xf86-video-ati: Branch 'master' - 5 commits
Alex Deucher
agd5f at kemper.freedesktop.org
Fri Dec 21 13:35:48 PST 2007
src/Makefile.am | 3
src/legacy_crtc.c | 1847 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/legacy_output.c | 1736 +++++++++++++++++++++++++++++++++++++++++++++++
src/radeon.h | 5
src/radeon_accel.c | 337 +++++++++
src/radeon_crtc.c | 916 +------------------------
src/radeon_display.c | 878 ------------------------
src/radeon_driver.c | 1461 ----------------------------------------
src/radeon_output.c | 1252 +---------------------------------
src/radeon_tv.c | 395 ++++++++++
10 files changed, 4426 insertions(+), 4404 deletions(-)
New commits:
commit 8c761afdcb9baf1649b93449692fb9ab67bc2c80
Author: Alex Deucher <alex at botch2.(none)>
Date: Fri Dec 21 16:24:49 2007 -0500
RADEON: more re-org
move save/restore routines into legacy_crtc/output
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
index f1bf9be..4a7071a 100644
--- a/src/legacy_crtc.c
+++ b/src/legacy_crtc.c
@@ -53,6 +53,585 @@
#include "sarea.h"
#endif
+/* Write common registers */
+void
+RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (info->IsSecondary)
+ return;
+
+ OUTREG(RADEON_OVR_CLR, restore->ovr_clr);
+ OUTREG(RADEON_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right);
+ OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom);
+ OUTREG(RADEON_OV0_SCALE_CNTL, restore->ov0_scale_cntl);
+ OUTREG(RADEON_SUBPIC_CNTL, restore->subpic_cntl);
+ OUTREG(RADEON_VIPH_CONTROL, restore->viph_control);
+ OUTREG(RADEON_I2C_CNTL_1, restore->i2c_cntl_1);
+ OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl);
+ OUTREG(RADEON_CAP0_TRIG_CNTL, restore->cap0_trig_cntl);
+ OUTREG(RADEON_CAP1_TRIG_CNTL, restore->cap1_trig_cntl);
+ OUTREG(RADEON_BUS_CNTL, restore->bus_cntl);
+ OUTREG(RADEON_SURFACE_CNTL, restore->surface_cntl);
+
+ /* Workaround for the VT switching problem in dual-head mode. This
+ * problem only occurs on RV style chips, typically when a FP and
+ * CRT are connected.
+ */
+ if (pRADEONEnt->HasCRTC2 &&
+ info->ChipFamily != CHIP_FAMILY_R200 &&
+ !IS_R300_VARIANT) {
+ CARD32 tmp;
+
+ tmp = INREG(RADEON_DAC_CNTL2);
+ OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
+ usleep(100000);
+ }
+}
+
+
+/* Write CRTC registers */
+void
+RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Programming CRTC1, offset: 0x%08x\n",
+ (unsigned)restore->crtc_offset);
+
+ /* We prevent the CRTC from hitting the memory controller until
+ * fully programmed
+ */
+ OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl |
+ RADEON_CRTC_DISP_REQ_EN_B);
+
+ OUTREGP(RADEON_CRTC_EXT_CNTL,
+ restore->crtc_ext_cntl,
+ RADEON_CRTC_VSYNC_DIS |
+ RADEON_CRTC_HSYNC_DIS |
+ RADEON_CRTC_DISPLAY_DIS);
+
+ OUTREG(RADEON_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp);
+ OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
+ OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp);
+ OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid);
+
+ OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid);
+ OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid);
+ OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
+ OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
+
+ if (IS_R300_VARIANT)
+ OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0);
+ OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
+ OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset);
+
+ OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch);
+ OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);
+ OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl);
+
+ if (info->IsDellServer) {
+ OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+ OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+ OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+ }
+
+ OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl);
+}
+
+/* Write CRTC2 registers */
+void
+RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ /* CARD32 crtc2_gen_cntl;*/
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Programming CRTC2, offset: 0x%08x\n",
+ (unsigned)restore->crtc2_offset);
+
+ /* We prevent the CRTC from hitting the memory controller until
+ * fully programmed
+ */
+ OUTREG(RADEON_CRTC2_GEN_CNTL,
+ restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
+ RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
+ RADEON_CRTC2_DISP_REQ_EN_B);
+
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, restore->crtc2_v_total_disp);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid);
+
+ OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp_h2_sync_strt_wid);
+ OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp_v2_sync_strt_wid);
+
+ if (IS_R300_VARIANT)
+ OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0);
+ OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
+ OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset);
+
+ OUTREG(RADEON_CRTC2_PITCH, restore->crtc2_pitch);
+ OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl);
+
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
+ OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
+ OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
+ OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
+ }
+ OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
+
+}
+
+static void
+RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
+{
+ int i = 0;
+
+ /* FIXME: Certain revisions of R300 can't recover here. Not sure of
+ the cause yet, but this workaround will mask the problem for now.
+ Other chips usually will pass at the very first test, so the
+ workaround shouldn't have any effect on them. */
+ for (i = 0;
+ (i < 10000 &&
+ INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
+ i++);
+}
+
+static void
+RADEONPLLWriteUpdate(ScrnInfoPtr pScrn)
+{
+ while (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
+
+ OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+ RADEON_PPLL_ATOMIC_UPDATE_W,
+ ~(RADEON_PPLL_ATOMIC_UPDATE_W));
+}
+
+static void
+RADEONPLL2WaitForReadUpdateComplete(ScrnInfoPtr pScrn)
+{
+ int i = 0;
+
+ /* FIXME: Certain revisions of R300 can't recover here. Not sure of
+ the cause yet, but this workaround will mask the problem for now.
+ Other chips usually will pass at the very first test, so the
+ workaround shouldn't have any effect on them. */
+ for (i = 0;
+ (i < 10000 &&
+ INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
+ i++);
+}
+
+static void
+RADEONPLL2WriteUpdate(ScrnInfoPtr pScrn)
+{
+ while (INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
+
+ OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
+ RADEON_P2PLL_ATOMIC_UPDATE_W,
+ ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
+}
+
+static CARD8
+RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
+ CARD16 fb_div)
+{
+ unsigned vcoFreq;
+
+ if (!ref_div)
+ return 1;
+
+ vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
+
+ /*
+ * This is horribly crude: the VCO frequency range is divided into
+ * 3 parts, each part having a fixed PLL gain value.
+ */
+ if (vcoFreq >= 30000)
+ /*
+ * [300..max] MHz : 7
+ */
+ return 7;
+ else if (vcoFreq >= 18000)
+ /*
+ * [180..300) MHz : 4
+ */
+ return 4;
+ else
+ /*
+ * [0..180) MHz : 1
+ */
+ return 1;
+}
+
+/* Write PLL registers */
+void
+RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD8 pllGain;
+
+#if defined(__powerpc__)
+ /* apparently restoring the pll causes a hang??? */
+ if (info->MacModel == RADEON_MAC_IBOOK)
+ return;
+#endif
+
+ pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+ restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
+
+ if (info->IsMobility) {
+ /* A temporal workaround for the occational blanking on certain laptop panels.
+ This appears to related to the PLL divider registers (fail to lock?).
+ It occurs even when all dividers are the same with their old settings.
+ In this case we really don't need to fiddle with PLL registers.
+ By doing this we can avoid the blanking problem with some panels.
+ */
+ if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
+ (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) &
+ (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
+ OUTREGP(RADEON_CLOCK_CNTL_INDEX,
+ RADEON_PLL_DIV_SEL,
+ ~(RADEON_PLL_DIV_SEL));
+ RADEONPllErrataAfterIndex(info);
+ return;
+ }
+ }
+
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+ RADEON_VCLK_SRC_SEL_CPUCLK,
+ ~(RADEON_VCLK_SRC_SEL_MASK));
+
+ OUTPLLP(pScrn,
+ RADEON_PPLL_CNTL,
+ RADEON_PPLL_RESET
+ | RADEON_PPLL_ATOMIC_UPDATE_EN
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+ | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
+ ~(RADEON_PPLL_RESET
+ | RADEON_PPLL_ATOMIC_UPDATE_EN
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+ | RADEON_PPLL_PVG_MASK));
+
+ OUTREGP(RADEON_CLOCK_CNTL_INDEX,
+ RADEON_PLL_DIV_SEL,
+ ~(RADEON_PLL_DIV_SEL));
+ RADEONPllErrataAfterIndex(info);
+
+ if (IS_R300_VARIANT ||
+ (info->ChipFamily == CHIP_FAMILY_RS300) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400)) {
+ if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
+ /* When restoring console mode, use saved PPLL_REF_DIV
+ * setting.
+ */
+ OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+ restore->ppll_ref_div,
+ 0);
+ } else {
+ /* R300 uses ref_div_acc field as real ref divider */
+ OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+ (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
+ ~R300_PPLL_REF_DIV_ACC_MASK);
+ }
+ } else {
+ OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
+ restore->ppll_ref_div,
+ ~RADEON_PPLL_REF_DIV_MASK);
+ }
+
+ OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
+ restore->ppll_div_3,
+ ~RADEON_PPLL_FB3_DIV_MASK);
+
+ OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
+ restore->ppll_div_3,
+ ~RADEON_PPLL_POST3_DIV_MASK);
+
+ RADEONPLLWriteUpdate(pScrn);
+ RADEONPLLWaitForReadUpdateComplete(pScrn);
+
+ OUTPLL(pScrn, RADEON_HTOTAL_CNTL, restore->htotal_cntl);
+
+ OUTPLLP(pScrn, RADEON_PPLL_CNTL,
+ 0,
+ ~(RADEON_PPLL_RESET
+ | RADEON_PPLL_SLEEP
+ | RADEON_PPLL_ATOMIC_UPDATE_EN
+ | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+ restore->ppll_ref_div,
+ restore->ppll_div_3,
+ (unsigned)restore->htotal_cntl,
+ INPLL(pScrn, RADEON_PPLL_CNTL));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote: rd=%d, fd=%d, pd=%d\n",
+ restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+ (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
+
+ usleep(50000); /* Let the clock to lock */
+
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+ RADEON_VCLK_SRC_SEL_PPLLCLK,
+ ~(RADEON_VCLK_SRC_SEL_MASK));
+
+ /*OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);*/
+
+ ErrorF("finished PLL1\n");
+
+}
+
+/* Write PLL2 registers */
+void
+RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD8 pllGain;
+
+ pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+ restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+ restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
+
+
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+ RADEON_PIX2CLK_SRC_SEL_CPUCLK,
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+
+ OUTPLLP(pScrn,
+ RADEON_P2PLL_CNTL,
+ RADEON_P2PLL_RESET
+ | RADEON_P2PLL_ATOMIC_UPDATE_EN
+ | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
+ ~(RADEON_P2PLL_RESET
+ | RADEON_P2PLL_ATOMIC_UPDATE_EN
+ | RADEON_P2PLL_PVG_MASK));
+
+
+ OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
+ restore->p2pll_ref_div,
+ ~RADEON_P2PLL_REF_DIV_MASK);
+
+ OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
+ restore->p2pll_div_0,
+ ~RADEON_P2PLL_FB0_DIV_MASK);
+
+ OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
+ restore->p2pll_div_0,
+ ~RADEON_P2PLL_POST0_DIV_MASK);
+
+ RADEONPLL2WriteUpdate(pScrn);
+ RADEONPLL2WaitForReadUpdateComplete(pScrn);
+
+ OUTPLL(pScrn, RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
+
+ OUTPLLP(pScrn, RADEON_P2PLL_CNTL,
+ 0,
+ ~(RADEON_P2PLL_RESET
+ | RADEON_P2PLL_SLEEP
+ | RADEON_P2PLL_ATOMIC_UPDATE_EN));
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+ (unsigned)restore->p2pll_ref_div,
+ (unsigned)restore->p2pll_div_0,
+ (unsigned)restore->htotal_cntl2,
+ INPLL(pScrn, RADEON_P2PLL_CNTL));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Wrote2: rd=%u, fd=%u, pd=%u\n",
+ (unsigned)restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+ (unsigned)restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
+ (unsigned)((restore->p2pll_div_0 &
+ RADEON_P2PLL_POST0_DIV_MASK) >>16));
+
+ usleep(5000); /* Let the clock to lock */
+
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+
+ ErrorF("finished PLL2\n");
+
+}
+
+/* Read common registers */
+void
+RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->ovr_clr = INREG(RADEON_OVR_CLR);
+ save->ovr_wid_left_right = INREG(RADEON_OVR_WID_LEFT_RIGHT);
+ save->ovr_wid_top_bottom = INREG(RADEON_OVR_WID_TOP_BOTTOM);
+ save->ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL);
+ save->subpic_cntl = INREG(RADEON_SUBPIC_CNTL);
+ save->viph_control = INREG(RADEON_VIPH_CONTROL);
+ save->i2c_cntl_1 = INREG(RADEON_I2C_CNTL_1);
+ save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
+ save->cap0_trig_cntl = INREG(RADEON_CAP0_TRIG_CNTL);
+ save->cap1_trig_cntl = INREG(RADEON_CAP1_TRIG_CNTL);
+ save->bus_cntl = INREG(RADEON_BUS_CNTL);
+ save->surface_cntl = INREG(RADEON_SURFACE_CNTL);
+ save->grph_buffer_cntl = INREG(RADEON_GRPH_BUFFER_CNTL);
+ save->grph2_buffer_cntl = INREG(RADEON_GRPH2_BUFFER_CNTL);
+}
+
+void
+RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH);
+ save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH);
+ save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH);
+}
+
+/* Read CRTC registers */
+void
+RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
+ save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+ save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP);
+ save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
+ save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP);
+ save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID);
+
+ save->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID);
+ save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID);
+ save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP);
+ save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP);
+
+ save->crtc_offset = INREG(RADEON_CRTC_OFFSET);
+ save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
+ save->crtc_pitch = INREG(RADEON_CRTC_PITCH);
+ save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL);
+ save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL);
+
+ if (IS_R300_VARIANT)
+ save->crtc_tile_x0_y0 = INREG(R300_CRTC_TILE_X0_Y0);
+
+ if (info->IsDellServer) {
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
+ save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG);
+ save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ }
+
+ /* track if the crtc is enabled for text restore */
+ if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS)
+ info->crtc_on = FALSE;
+ else
+ info->crtc_on = TRUE;
+
+}
+
+/* Read CRTC2 registers */
+void
+RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ save->crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+ save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ save->crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+ save->crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+ save->crtc2_offset = INREG(RADEON_CRTC2_OFFSET);
+ save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
+ save->crtc2_pitch = INREG(RADEON_CRTC2_PITCH);
+
+ if (IS_R300_VARIANT)
+ save->crtc2_tile_x0_y0 = INREG(R300_CRTC2_TILE_X0_Y0);
+
+ save->fp_h2_sync_strt_wid = INREG (RADEON_FP_H2_SYNC_STRT_WID);
+ save->fp_v2_sync_strt_wid = INREG (RADEON_FP_V2_SYNC_STRT_WID);
+
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30);
+ save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34);
+ save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
+ save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c);
+ }
+
+ save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL);
+
+ /* track if the crtc is enabled for text restore */
+ if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS)
+ info->crtc2_on = FALSE;
+ else
+ info->crtc2_on = TRUE;
+
+}
+
+/* Read PLL registers */
+void
+RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
+ save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3);
+ save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL);
+ save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: 0x%08x 0x%08x 0x%08x\n",
+ save->ppll_ref_div,
+ save->ppll_div_3,
+ (unsigned)save->htotal_cntl);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: rd=%d, fd=%d, pd=%d\n",
+ save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+ save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+ (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
+}
+
+/* Read PLL registers */
+void
+RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ save->p2pll_ref_div = INPLL(pScrn, RADEON_P2PLL_REF_DIV);
+ save->p2pll_div_0 = INPLL(pScrn, RADEON_P2PLL_DIV_0);
+ save->htotal_cntl2 = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
+ save->pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: 0x%08x 0x%08x 0x%08x\n",
+ (unsigned)save->p2pll_ref_div,
+ (unsigned)save->p2pll_div_0,
+ (unsigned)save->htotal_cntl2);
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Read: rd=%u, fd=%u, pd=%u\n",
+ (unsigned)(save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK),
+ (unsigned)(save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK),
+ (unsigned)((save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK)
+ >> 16));
+}
void
legacy_crtc_dpms(xf86CrtcPtr crtc, int mode)
diff --git a/src/legacy_output.c b/src/legacy_output.c
index 6f55ae2..799aa2e 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -53,6 +53,165 @@ static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color
static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
+void
+RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+ RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (IS_R300_VARIANT)
+ OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
+
+ OUTREGP(RADEON_DAC_CNTL,
+ restore->dac_cntl,
+ RADEON_DAC_RANGE_CNTL |
+ RADEON_DAC_BLANKING);
+
+ OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+
+ if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
+ (info->ChipFamily != CHIP_FAMILY_R200))
+ OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+
+ if ((info->ChipFamily == CHIP_FAMILY_R200) ||
+ IS_R300_VARIANT) {
+ OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
+ } else {
+ OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+ }
+
+ OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
+
+ /* R200 DAC connected via DVO */
+ if (info->ChipFamily == CHIP_FAMILY_R200)
+ OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
+}
+
+
+/* Write TMDS registers */
+void
+RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TMDS_PLL_CNTL, restore->tmds_pll_cntl);
+ OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
+ OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl);
+
+ /* old AIW Radeon has some BIOS initialization problem
+ * with display buffer underflow, only occurs to DFP
+ */
+ if (!pRADEONEnt->HasCRTC2)
+ OUTREG(RADEON_GRPH_BUFFER_CNTL,
+ INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
+
+}
+
+/* Write FP2 registers */
+void
+RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
+
+}
+
+/* Write RMX registers */
+void
+RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch);
+ OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch);
+
+}
+
+/* Write LVDS registers */
+void
+RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (info->IsMobility) {
+ OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
+ OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl);
+
+ if (info->ChipFamily == CHIP_FAMILY_RV410) {
+ OUTREG(RADEON_CLOCK_CNTL_INDEX, 0);
+ }
+ }
+
+}
+
+void
+RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH);
+ CARD32 bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH);
+
+ OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
+ bios_5_scratch &= 0xF;
+ bios_5_scratch |= (restore->bios_5_scratch & ~0xF);
+ OUTREG(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
+ if (restore->bios_6_scratch & 0x40000000)
+ bios_6_scratch |= 0x40000000;
+ else
+ bios_6_scratch &= ~0x40000000;
+ OUTREG(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
+
+}
+
+void
+RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->dac_cntl = INREG(RADEON_DAC_CNTL);
+ save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+ save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
+ save->disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG);
+ save->dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+ save->gpiopad_a = INREG(RADEON_GPIOPAD_A);
+
+}
+
+/* Read flat panel registers */
+void
+RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ save->fp_gen_cntl = INREG(RADEON_FP_GEN_CNTL);
+ save->fp2_gen_cntl = INREG (RADEON_FP2_GEN_CNTL);
+ save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
+ save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
+ save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL);
+ save->lvds_pll_cntl = INREG(RADEON_LVDS_PLL_CNTL);
+ save->tmds_pll_cntl = INREG(RADEON_TMDS_PLL_CNTL);
+ save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL);
+
+ if (info->ChipFamily == CHIP_FAMILY_RV280) {
+ /* bit 22 of TMDS_PLL_CNTL is read-back inverted */
+ save->tmds_pll_cntl ^= (1 << 22);
+ }
+}
+
Bool
RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch)
diff --git a/src/radeon.h b/src/radeon.h
index 47e1b89..5c15888 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -902,8 +902,6 @@ extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
DisplayModePtr mode, BOOL IsPrimary);
extern void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
-extern void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore);
-extern void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore);
#ifdef XF86DRI
#ifdef USE_XAA
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 7b9cd85..1662e04 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -125,11 +125,9 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
#endif
-DisplayModePtr
+extern DisplayModePtr
RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
-static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
- unsigned nWaitLoops, unsigned cntThreshold);
static const OptionInfoRec RADEONOptions[] = {
{ OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE },
@@ -3910,820 +3908,6 @@ static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
#endif
-/* Write common registers */
-void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- if (info->IsSecondary)
- return;
-
- OUTREG(RADEON_OVR_CLR, restore->ovr_clr);
- OUTREG(RADEON_OVR_WID_LEFT_RIGHT, restore->ovr_wid_left_right);
- OUTREG(RADEON_OVR_WID_TOP_BOTTOM, restore->ovr_wid_top_bottom);
- OUTREG(RADEON_OV0_SCALE_CNTL, restore->ov0_scale_cntl);
- OUTREG(RADEON_SUBPIC_CNTL, restore->subpic_cntl);
- OUTREG(RADEON_VIPH_CONTROL, restore->viph_control);
- OUTREG(RADEON_I2C_CNTL_1, restore->i2c_cntl_1);
- OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl);
- OUTREG(RADEON_CAP0_TRIG_CNTL, restore->cap0_trig_cntl);
- OUTREG(RADEON_CAP1_TRIG_CNTL, restore->cap1_trig_cntl);
- OUTREG(RADEON_BUS_CNTL, restore->bus_cntl);
- OUTREG(RADEON_SURFACE_CNTL, restore->surface_cntl);
-
- /* Workaround for the VT switching problem in dual-head mode. This
- * problem only occurs on RV style chips, typically when a FP and
- * CRT are connected.
- */
- if (pRADEONEnt->HasCRTC2 &&
- info->ChipFamily != CHIP_FAMILY_R200 &&
- !IS_R300_VARIANT) {
- CARD32 tmp;
-
- tmp = INREG(RADEON_DAC_CNTL2);
- OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
- usleep(100000);
- }
-}
-
-void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- if (IS_R300_VARIANT)
- OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
-
- OUTREGP(RADEON_DAC_CNTL,
- restore->dac_cntl,
- RADEON_DAC_RANGE_CNTL |
- RADEON_DAC_BLANKING);
-
- OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
-
- if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
- (info->ChipFamily != CHIP_FAMILY_R200))
- OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-
- OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
-
- if ((info->ChipFamily == CHIP_FAMILY_R200) ||
- IS_R300_VARIANT) {
- OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
- } else {
- OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
- }
-
- OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
-
- /* R200 DAC connected via DVO */
- if (info->ChipFamily == CHIP_FAMILY_R200)
- OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
-}
-
-/* Write CRTC registers */
-void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Programming CRTC1, offset: 0x%08x\n",
- (unsigned)restore->crtc_offset);
-
- /* We prevent the CRTC from hitting the memory controller until
- * fully programmed
- */
- OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl |
- RADEON_CRTC_DISP_REQ_EN_B);
-
- OUTREGP(RADEON_CRTC_EXT_CNTL,
- restore->crtc_ext_cntl,
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS |
- RADEON_CRTC_DISPLAY_DIS);
-
- OUTREG(RADEON_CRTC_H_TOTAL_DISP, restore->crtc_h_total_disp);
- OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
- OUTREG(RADEON_CRTC_V_TOTAL_DISP, restore->crtc_v_total_disp);
- OUTREG(RADEON_CRTC_V_SYNC_STRT_WID, restore->crtc_v_sync_strt_wid);
-
- OUTREG(RADEON_FP_H_SYNC_STRT_WID, restore->fp_h_sync_strt_wid);
- OUTREG(RADEON_FP_V_SYNC_STRT_WID, restore->fp_v_sync_strt_wid);
- OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
- OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
-
- if (IS_R300_VARIANT)
- OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0);
- OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
- OUTREG(RADEON_CRTC_OFFSET, restore->crtc_offset);
-
- OUTREG(RADEON_CRTC_PITCH, restore->crtc_pitch);
- OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);
- OUTREG(RADEON_CRTC_MORE_CNTL, restore->crtc_more_cntl);
-
- if (info->IsDellServer) {
- OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
- OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
- OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
- OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
- }
-
- OUTREG(RADEON_CRTC_GEN_CNTL, restore->crtc_gen_cntl);
-}
-
-/* Write CRTC2 registers */
-void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- /* CARD32 crtc2_gen_cntl;*/
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Programming CRTC2, offset: 0x%08x\n",
- (unsigned)restore->crtc2_offset);
-
- /* We prevent the CRTC from hitting the memory controller until
- * fully programmed
- */
- OUTREG(RADEON_CRTC2_GEN_CNTL,
- restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
- RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
- RADEON_CRTC2_DISP_REQ_EN_B);
-
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, restore->crtc2_h_total_disp);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, restore->crtc2_v_total_disp);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, restore->crtc2_v_sync_strt_wid);
-
- OUTREG(RADEON_FP_H2_SYNC_STRT_WID, restore->fp_h2_sync_strt_wid);
- OUTREG(RADEON_FP_V2_SYNC_STRT_WID, restore->fp_v2_sync_strt_wid);
-
- if (IS_R300_VARIANT)
- OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0);
- OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
- OUTREG(RADEON_CRTC2_OFFSET, restore->crtc2_offset);
-
- OUTREG(RADEON_CRTC2_PITCH, restore->crtc2_pitch);
- OUTREG(RADEON_DISP2_MERGE_CNTL, restore->disp2_merge_cntl);
-
- if (info->ChipFamily == CHIP_FAMILY_RS400) {
- OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
- OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
- OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
- OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
- }
- OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
-
-}
-
-/* Write TMDS registers */
-void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- OUTREG(RADEON_TMDS_PLL_CNTL, restore->tmds_pll_cntl);
- OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
- OUTREG(RADEON_FP_GEN_CNTL, restore->fp_gen_cntl);
-
- /* old AIW Radeon has some BIOS initialization problem
- * with display buffer underflow, only occurs to DFP
- */
- if (!pRADEONEnt->HasCRTC2)
- OUTREG(RADEON_GRPH_BUFFER_CNTL,
- INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
-
-}
-
-/* Write FP2 registers */
-void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
-
-}
-
-/* Write RMX registers */
-void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- OUTREG(RADEON_FP_HORZ_STRETCH, restore->fp_horz_stretch);
- OUTREG(RADEON_FP_VERT_STRETCH, restore->fp_vert_stretch);
-
-}
-
-/* Write LVDS registers */
-void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- if (info->IsMobility) {
- OUTREG(RADEON_LVDS_GEN_CNTL, restore->lvds_gen_cntl);
- OUTREG(RADEON_LVDS_PLL_CNTL, restore->lvds_pll_cntl);
-
- if (info->ChipFamily == CHIP_FAMILY_RV410) {
- OUTREG(RADEON_CLOCK_CNTL_INDEX, 0);
- }
- }
-
-}
-
-void RADEONRestoreBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH);
- CARD32 bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH);
-
- OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
- bios_5_scratch &= 0xF;
- bios_5_scratch |= (restore->bios_5_scratch & ~0xF);
- OUTREG(RADEON_BIOS_5_SCRATCH, bios_5_scratch);
- if (restore->bios_6_scratch & 0x40000000)
- bios_6_scratch |= 0x40000000;
- else
- bios_6_scratch &= ~0x40000000;
- OUTREG(RADEON_BIOS_6_SCRATCH, bios_6_scratch);
-
-}
-
-/* Write to TV FIFO RAM */
-static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
- CARD32 value)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 tmp;
- int i = 0;
-
- OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
-
- OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
- OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
-
- do {
- tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
- if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
- break;
- i++;
- }
- while (i < 10000);
- /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
-
- OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
-}
-
-/* Read from TV FIFO RAM */
-static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 tmp;
- int i = 0;
-
- OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
- OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
-
- do {
- tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
- if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
- break;
- i++;
- }
- while (i < 10000);
- /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
-
- OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
-
- return INREG(RADEON_TV_HOST_READ_DATA);
-}
-
-/* Get FIFO addresses of horizontal & vertical code timing tables from
- * settings of uv_adr register.
- */
-static CARD16 RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
-{
- CARD16 hTable;
-
- switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
- case 0:
- hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
- break;
- case 1:
- hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
- break;
- case 2:
- hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
- break;
- default:
- /* Of course, this should never happen */
- hTable = 0;
- break;
- }
- return hTable;
-}
-
-static CARD16 RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
-{
- CARD16 vTable;
-
- switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
- case 0:
- vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
- break;
- case 1:
- vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
- break;
- case 2:
- vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
- break;
- default:
- /* Of course, this should never happen */
- vTable = 0;
- break;
- }
- return vTable;
-}
-
-/* Restore horizontal/vertical timing code tables */
-void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD16 hTable;
- CARD16 vTable;
- CARD32 tmp;
- unsigned i;
-
- OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
- hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
- vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
-
- for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
- tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
- RADEONWriteTVFIFO(pScrn, hTable, tmp);
- if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
- break;
- }
-
- for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
- tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
- RADEONWriteTVFIFO(pScrn, vTable, tmp);
- if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
- break;
- }
-}
-
-/* restore TV PLLs */
-static void RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
- OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
-
- RADEONWaitPLLLock(pScrn, 200, 800, 135);
-
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
-
- RADEONWaitPLLLock(pScrn, 300, 160, 27);
- RADEONWaitPLLLock(pScrn, 200, 800, 135);
-
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
-
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
- OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
-}
-
-/* Restore TV horizontal/vertical settings */
-static void RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
-
- OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
- OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
- OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
-
- OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
- OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
-
- OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
-
- OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
- OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
-
- OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
- OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
- OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
-}
-
-/* restore TV RESTART registers */
-void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
- OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
- OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
-}
-
-/* restore tv standard & output muxes */
-static void RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
-
- OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
-
- OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
- OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
-
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
-
- OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
-}
-
-/* Restore TV out regs */
-void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- ErrorF("Entering Restore TV\n");
-
- OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
- | RADEON_TV_ASYNC_RST
- | RADEON_CRT_ASYNC_RST
- | RADEON_TV_FIFO_ASYNC_RST));
-
- /* Temporarily turn the TV DAC off */
- OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
- | RADEON_TV_DAC_BGSLEEP
- | RADEON_TV_DAC_RDACPD
- | RADEON_TV_DAC_GDACPD
- | RADEON_TV_DAC_BDACPD));
-
- ErrorF("Restore TV PLL\n");
- RADEONRestoreTVPLLRegisters(pScrn, restore);
-
- ErrorF("Restore TVHV\n");
- RADEONRestoreTVHVRegisters(pScrn, restore);
-
- OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
- | RADEON_TV_ASYNC_RST
- | RADEON_CRT_ASYNC_RST));
-
- ErrorF("Restore TV Restarts\n");
- RADEONRestoreTVRestarts(pScrn, restore);
-
- ErrorF("Restore Timing Tables\n");
- RADEONRestoreTVTimingTables(pScrn, restore);
-
-
- OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
- | RADEON_TV_ASYNC_RST));
-
- ErrorF("Restore TV standard\n");
- RADEONRestoreTVOutputStd(pScrn, restore);
-
- OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
-
- OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
- OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
-
- OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-
- ErrorF("Leaving Restore TV\n");
-}
-
-static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
-{
- int i = 0;
-
- /* FIXME: Certain revisions of R300 can't recover here. Not sure of
- the cause yet, but this workaround will mask the problem for now.
- Other chips usually will pass at the very first test, so the
- workaround shouldn't have any effect on them. */
- for (i = 0;
- (i < 10000 &&
- INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
- i++);
-}
-
-static void RADEONPLLWriteUpdate(ScrnInfoPtr pScrn)
-{
- while (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_ATOMIC_UPDATE_R);
-
- OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
- RADEON_PPLL_ATOMIC_UPDATE_W,
- ~(RADEON_PPLL_ATOMIC_UPDATE_W));
-}
-
-static void RADEONPLL2WaitForReadUpdateComplete(ScrnInfoPtr pScrn)
-{
- int i = 0;
-
- /* FIXME: Certain revisions of R300 can't recover here. Not sure of
- the cause yet, but this workaround will mask the problem for now.
- Other chips usually will pass at the very first test, so the
- workaround shouldn't have any effect on them. */
- for (i = 0;
- (i < 10000 &&
- INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
- i++);
-}
-
-static void RADEONPLL2WriteUpdate(ScrnInfoPtr pScrn)
-{
- while (INPLL(pScrn, RADEON_P2PLL_REF_DIV) & RADEON_P2PLL_ATOMIC_UPDATE_R);
-
- OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
- RADEON_P2PLL_ATOMIC_UPDATE_W,
- ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
-}
-
-static CARD8 RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
- CARD16 fb_div)
-{
- unsigned vcoFreq;
-
- if (!ref_div)
- return 1;
-
- vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
-
- /*
- * This is horribly crude: the VCO frequency range is divided into
- * 3 parts, each part having a fixed PLL gain value.
- */
- if (vcoFreq >= 30000)
- /*
- * [300..max] MHz : 7
- */
- return 7;
- else if (vcoFreq >= 18000)
- /*
- * [180..300) MHz : 4
- */
- return 4;
- else
- /*
- * [0..180) MHz : 1
- */
- return 1;
-}
-
-/* Wait for PLLs to lock */
-static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
- unsigned nWaitLoops, unsigned cntThreshold)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 savePLLTest;
- unsigned i;
- unsigned j;
-
- OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
-
- savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
-
- OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
-
- /* XXX: these should probably be OUTPLL to avoid various PLL errata */
-
- OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
-
- for (i = 0; i < nTests; i++) {
- OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
-
- for (j = 0; j < nWaitLoops; j++)
- if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
- break;
- }
-
- OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
-
- OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
-}
-
-/* Write PLL registers */
-void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD8 pllGain;
-
-#if defined(__powerpc__)
- /* apparently restoring the pll causes a hang??? */
- if (info->MacModel == RADEON_MAC_IBOOK)
- return;
-#endif
-
- pllGain = RADEONComputePLLGain(info->pll.reference_freq,
- restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
- restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
-
- if (info->IsMobility) {
- /* A temporal workaround for the occational blanking on certain laptop panels.
- This appears to related to the PLL divider registers (fail to lock?).
- It occurs even when all dividers are the same with their old settings.
- In this case we really don't need to fiddle with PLL registers.
- By doing this we can avoid the blanking problem with some panels.
- */
- if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
- (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) &
- (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
- OUTREGP(RADEON_CLOCK_CNTL_INDEX,
- RADEON_PLL_DIV_SEL,
- ~(RADEON_PLL_DIV_SEL));
- RADEONPllErrataAfterIndex(info);
- return;
- }
- }
-
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
- RADEON_VCLK_SRC_SEL_CPUCLK,
- ~(RADEON_VCLK_SRC_SEL_MASK));
-
- OUTPLLP(pScrn,
- RADEON_PPLL_CNTL,
- RADEON_PPLL_RESET
- | RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
- | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
- ~(RADEON_PPLL_RESET
- | RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
- | RADEON_PPLL_PVG_MASK));
-
- OUTREGP(RADEON_CLOCK_CNTL_INDEX,
- RADEON_PLL_DIV_SEL,
- ~(RADEON_PLL_DIV_SEL));
- RADEONPllErrataAfterIndex(info);
-
- if (IS_R300_VARIANT ||
- (info->ChipFamily == CHIP_FAMILY_RS300) ||
- (info->ChipFamily == CHIP_FAMILY_RS400)) {
- if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
- /* When restoring console mode, use saved PPLL_REF_DIV
- * setting.
- */
- OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
- restore->ppll_ref_div,
- 0);
- } else {
- /* R300 uses ref_div_acc field as real ref divider */
- OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
- (restore->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT),
- ~R300_PPLL_REF_DIV_ACC_MASK);
- }
- } else {
- OUTPLLP(pScrn, RADEON_PPLL_REF_DIV,
- restore->ppll_ref_div,
- ~RADEON_PPLL_REF_DIV_MASK);
- }
-
- OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
- restore->ppll_div_3,
- ~RADEON_PPLL_FB3_DIV_MASK);
-
- OUTPLLP(pScrn, RADEON_PPLL_DIV_3,
- restore->ppll_div_3,
- ~RADEON_PPLL_POST3_DIV_MASK);
-
- RADEONPLLWriteUpdate(pScrn);
- RADEONPLLWaitForReadUpdateComplete(pScrn);
-
- OUTPLL(pScrn, RADEON_HTOTAL_CNTL, restore->htotal_cntl);
-
- OUTPLLP(pScrn, RADEON_PPLL_CNTL,
- 0,
- ~(RADEON_PPLL_RESET
- | RADEON_PPLL_SLEEP
- | RADEON_PPLL_ATOMIC_UPDATE_EN
- | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
- restore->ppll_ref_div,
- restore->ppll_div_3,
- (unsigned)restore->htotal_cntl,
- INPLL(pScrn, RADEON_PPLL_CNTL));
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Wrote: rd=%d, fd=%d, pd=%d\n",
- restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
- restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
- (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
-
- usleep(50000); /* Let the clock to lock */
-
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
- RADEON_VCLK_SRC_SEL_PPLLCLK,
- ~(RADEON_VCLK_SRC_SEL_MASK));
-
- /*OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);*/
-
- ErrorF("finished PLL1\n");
-
-}
-
-
-/* Write PLL2 registers */
-void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
- RADEONSavePtr restore)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD8 pllGain;
-
- pllGain = RADEONComputePLLGain(info->pll.reference_freq,
- restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
- restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
-
-
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
- RADEON_PIX2CLK_SRC_SEL_CPUCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
- OUTPLLP(pScrn,
- RADEON_P2PLL_CNTL,
- RADEON_P2PLL_RESET
- | RADEON_P2PLL_ATOMIC_UPDATE_EN
- | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
- ~(RADEON_P2PLL_RESET
- | RADEON_P2PLL_ATOMIC_UPDATE_EN
- | RADEON_P2PLL_PVG_MASK));
-
-
- OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
- restore->p2pll_ref_div,
- ~RADEON_P2PLL_REF_DIV_MASK);
-
- OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
- restore->p2pll_div_0,
- ~RADEON_P2PLL_FB0_DIV_MASK);
-
- OUTPLLP(pScrn, RADEON_P2PLL_DIV_0,
- restore->p2pll_div_0,
- ~RADEON_P2PLL_POST0_DIV_MASK);
-
- RADEONPLL2WriteUpdate(pScrn);
- RADEONPLL2WaitForReadUpdateComplete(pScrn);
-
- OUTPLL(pScrn, RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
-
- OUTPLLP(pScrn, RADEON_P2PLL_CNTL,
- 0,
- ~(RADEON_P2PLL_RESET
- | RADEON_P2PLL_SLEEP
- | RADEON_P2PLL_ATOMIC_UPDATE_EN));
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
- (unsigned)restore->p2pll_ref_div,
- (unsigned)restore->p2pll_div_0,
- (unsigned)restore->htotal_cntl2,
- INPLL(pScrn, RADEON_P2PLL_CNTL));
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Wrote2: rd=%u, fd=%u, pd=%u\n",
- (unsigned)restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
- (unsigned)restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
- (unsigned)((restore->p2pll_div_0 &
- RADEON_P2PLL_POST0_DIV_MASK) >>16));
-
- usleep(5000); /* Let the clock to lock */
-
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
- RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
- ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
-
- ErrorF("finished PLL2\n");
-
-}
-
-
/* restore original surface info (for fb console). */
static void RADEONRestoreSurfaces(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
@@ -4922,289 +4106,6 @@ static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
}
-/* Read common registers */
-static void RADEONSaveCommonRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- save->ovr_clr = INREG(RADEON_OVR_CLR);
- save->ovr_wid_left_right = INREG(RADEON_OVR_WID_LEFT_RIGHT);
- save->ovr_wid_top_bottom = INREG(RADEON_OVR_WID_TOP_BOTTOM);
- save->ov0_scale_cntl = INREG(RADEON_OV0_SCALE_CNTL);
- save->subpic_cntl = INREG(RADEON_SUBPIC_CNTL);
- save->viph_control = INREG(RADEON_VIPH_CONTROL);
- save->i2c_cntl_1 = INREG(RADEON_I2C_CNTL_1);
- save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
- save->cap0_trig_cntl = INREG(RADEON_CAP0_TRIG_CNTL);
- save->cap1_trig_cntl = INREG(RADEON_CAP1_TRIG_CNTL);
- save->bus_cntl = INREG(RADEON_BUS_CNTL);
- save->surface_cntl = INREG(RADEON_SURFACE_CNTL);
- save->grph_buffer_cntl = INREG(RADEON_GRPH_BUFFER_CNTL);
- save->grph2_buffer_cntl = INREG(RADEON_GRPH2_BUFFER_CNTL);
-}
-
-/* Read CRTC registers */
-static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- save->crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
- save->crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
- save->crtc_h_total_disp = INREG(RADEON_CRTC_H_TOTAL_DISP);
- save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
- save->crtc_v_total_disp = INREG(RADEON_CRTC_V_TOTAL_DISP);
- save->crtc_v_sync_strt_wid = INREG(RADEON_CRTC_V_SYNC_STRT_WID);
-
- save->fp_h_sync_strt_wid = INREG(RADEON_FP_H_SYNC_STRT_WID);
- save->fp_v_sync_strt_wid = INREG(RADEON_FP_V_SYNC_STRT_WID);
- save->fp_crtc_h_total_disp = INREG(RADEON_FP_CRTC_H_TOTAL_DISP);
- save->fp_crtc_v_total_disp = INREG(RADEON_FP_CRTC_V_TOTAL_DISP);
-
- save->crtc_offset = INREG(RADEON_CRTC_OFFSET);
- save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
- save->crtc_pitch = INREG(RADEON_CRTC_PITCH);
- save->disp_merge_cntl = INREG(RADEON_DISP_MERGE_CNTL);
- save->crtc_more_cntl = INREG(RADEON_CRTC_MORE_CNTL);
-
- if (IS_R300_VARIANT)
- save->crtc_tile_x0_y0 = INREG(R300_CRTC_TILE_X0_Y0);
-
- if (info->IsDellServer) {
- save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
- save->disp_hw_debug = INREG (RADEON_DISP_HW_DEBUG);
- save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
- }
-
- /* track if the crtc is enabled for text restore */
- if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS)
- info->crtc_on = FALSE;
- else
- info->crtc_on = TRUE;
-
-}
-
-/* Read DAC registers */
-static void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- save->dac_cntl = INREG(RADEON_DAC_CNTL);
- save->dac2_cntl = INREG(RADEON_DAC_CNTL2);
- save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- save->disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
- save->disp_tv_out_cntl = INREG(RADEON_DISP_TV_OUT_CNTL);
- save->disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG);
- save->dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
- save->gpiopad_a = INREG(RADEON_GPIOPAD_A);
-
-}
-
-static void RADEONSaveBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- save->bios_4_scratch = INREG(RADEON_BIOS_4_SCRATCH);
- save->bios_5_scratch = INREG(RADEON_BIOS_5_SCRATCH);
- save->bios_6_scratch = INREG(RADEON_BIOS_6_SCRATCH);
-}
-
-/* Read flat panel registers */
-static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- save->fp_gen_cntl = INREG(RADEON_FP_GEN_CNTL);
- save->fp2_gen_cntl = INREG (RADEON_FP2_GEN_CNTL);
- save->fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
- save->fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
- save->lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL);
- save->lvds_pll_cntl = INREG(RADEON_LVDS_PLL_CNTL);
- save->tmds_pll_cntl = INREG(RADEON_TMDS_PLL_CNTL);
- save->tmds_transmitter_cntl= INREG(RADEON_TMDS_TRANSMITTER_CNTL);
-
- if (info->ChipFamily == CHIP_FAMILY_RV280) {
- /* bit 22 of TMDS_PLL_CNTL is read-back inverted */
- save->tmds_pll_cntl ^= (1 << 22);
- }
-}
-
-/* Read CRTC2 registers */
-static void RADEONSaveCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- save->crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
- save->crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
- save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
- save->crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
- save->crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
- save->crtc2_offset = INREG(RADEON_CRTC2_OFFSET);
- save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
- save->crtc2_pitch = INREG(RADEON_CRTC2_PITCH);
-
- if (IS_R300_VARIANT)
- save->crtc2_tile_x0_y0 = INREG(R300_CRTC2_TILE_X0_Y0);
-
- save->fp_h2_sync_strt_wid = INREG (RADEON_FP_H2_SYNC_STRT_WID);
- save->fp_v2_sync_strt_wid = INREG (RADEON_FP_V2_SYNC_STRT_WID);
-
- if (info->ChipFamily == CHIP_FAMILY_RS400) {
- save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30);
- save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34);
- save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
- save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c);
- }
-
- save->disp2_merge_cntl = INREG(RADEON_DISP2_MERGE_CNTL);
-
- /* track if the crtc is enabled for text restore */
- if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS)
- info->crtc2_on = FALSE;
- else
- info->crtc2_on = TRUE;
-
-}
-
-/* Save horizontal/vertical timing code tables */
-static void RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD16 hTable;
- CARD16 vTable;
- CARD32 tmp;
- unsigned i;
-
- save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
- hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
- vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
-
- /*
- * Reset FIFO arbiter in order to be able to access FIFO RAM
- */
-
- OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
- | RADEON_CRT_ASYNC_RST
- | RADEON_RESTART_PHASE_FIX
- | RADEON_CRT_FIFO_CE_EN
- | RADEON_TV_FIFO_CE_EN
- | RADEON_TV_ON));
-
- /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
-
- ErrorF("saveTimingTables: reading timing tables\n");
-
- for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
- tmp = RADEONReadTVFIFO(pScrn, hTable--);
- save->h_code_timing[ i ] = (CARD16)((tmp >> 14) & 0x3fff);
- save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
-
- if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
- break;
- }
-
- for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
- tmp = RADEONReadTVFIFO(pScrn, vTable++);
- save->v_code_timing[ i ] = (CARD16)(tmp & 0x3fff);
- save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
-
- if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
- break;
- }
-}
-
-/* read TV regs */
-static void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- ErrorF("Entering TV Save\n");
-
- save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
- save->tv_frestart = INREG(RADEON_TV_FRESTART);
- save->tv_hrestart = INREG(RADEON_TV_HRESTART);
- save->tv_vrestart = INREG(RADEON_TV_VRESTART);
- save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
- save->tv_hdisp = INREG(RADEON_TV_HDISP);
- save->tv_hstart = INREG(RADEON_TV_HSTART);
- save->tv_htotal = INREG(RADEON_TV_HTOTAL);
- save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
- save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
- save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
- save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
- save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
- save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
- save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
- save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
- save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
- save->tv_vdisp = INREG(RADEON_TV_VDISP);
- save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
- save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
- save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
- save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
- save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
- save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
- save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
-
- save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
- save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1);
-
- ErrorF("Save TV timing tables\n");
-
- RADEONSaveTVTimingTables(pScrn, save);
-
- ErrorF("TV Save done\n");
-}
-
-/* Read PLL registers */
-static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
- save->ppll_div_3 = INPLL(pScrn, RADEON_PPLL_DIV_3);
- save->htotal_cntl = INPLL(pScrn, RADEON_HTOTAL_CNTL);
- save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Read: 0x%08x 0x%08x 0x%08x\n",
- save->ppll_ref_div,
- save->ppll_div_3,
- (unsigned)save->htotal_cntl);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Read: rd=%d, fd=%d, pd=%d\n",
- save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
- save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
- (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
-}
-
-/* Read PLL registers */
-static void RADEONSavePLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- save->p2pll_ref_div = INPLL(pScrn, RADEON_P2PLL_REF_DIV);
- save->p2pll_div_0 = INPLL(pScrn, RADEON_P2PLL_DIV_0);
- save->htotal_cntl2 = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
- save->pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Read: 0x%08x 0x%08x 0x%08x\n",
- (unsigned)save->p2pll_ref_div,
- (unsigned)save->p2pll_div_0,
- (unsigned)save->htotal_cntl2);
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "Read: rd=%u, fd=%u, pd=%u\n",
- (unsigned)(save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK),
- (unsigned)(save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK),
- (unsigned)((save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK)
- >> 16));
-}
#if 0
/* Read palette data */
@@ -5228,7 +4129,8 @@ static void RADEONSavePalette(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
#endif
-void avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
+void
+avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
@@ -5382,7 +4284,8 @@ void avivo_save(ScrnInfoPtr pScrn, RADEONSavePtr save)
}
-void avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+void
+avivo_restore(ScrnInfoPtr pScrn, RADEONSavePtr restore)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 5e9a9c8..9959295 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -180,6 +180,401 @@ static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
+static void
+RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+ unsigned nWaitLoops, unsigned cntThreshold)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 savePLLTest;
+ unsigned i;
+ unsigned j;
+
+ OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
+
+ savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
+
+ OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
+
+ /* XXX: these should probably be OUTPLL to avoid various PLL errata */
+
+ OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
+
+ for (i = 0; i < nTests; i++) {
+ OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
+
+ for (j = 0; j < nWaitLoops; j++)
+ if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
+ break;
+ }
+
+ OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
+
+ OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
+}
+
+/* Write to TV FIFO RAM */
+static void
+RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
+ CARD32 value)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp;
+ int i = 0;
+
+ OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
+
+ do {
+ tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
+ break;
+ i++;
+ }
+ while (i < 10000);
+ /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+}
+
+/* Read from TV FIFO RAM */
+static CARD32
+RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp;
+ int i = 0;
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
+
+ do {
+ tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+ if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
+ break;
+ i++;
+ }
+ while (i < 10000);
+ /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
+
+ OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+
+ return INREG(RADEON_TV_HOST_READ_DATA);
+}
+
+/* Get FIFO addresses of horizontal & vertical code timing tables from
+ * settings of uv_adr register.
+ */
+static CARD16
+RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
+{
+ CARD16 hTable;
+
+ switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
+ case 0:
+ hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
+ break;
+ case 1:
+ hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
+ break;
+ case 2:
+ hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
+ break;
+ default:
+ /* Of course, this should never happen */
+ hTable = 0;
+ break;
+ }
+ return hTable;
+}
+
+static CARD16
+RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
+{
+ CARD16 vTable;
+
+ switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
+ case 0:
+ vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
+ break;
+ case 1:
+ vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
+ break;
+ case 2:
+ vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
+ break;
+ default:
+ /* Of course, this should never happen */
+ vTable = 0;
+ break;
+ }
+ return vTable;
+}
+
+/* Restore horizontal/vertical timing code tables */
+static void
+RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 hTable;
+ CARD16 vTable;
+ CARD32 tmp;
+ unsigned i;
+
+ OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
+ hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
+ vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
+ tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
+ RADEONWriteTVFIFO(pScrn, hTable, tmp);
+ if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
+ tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
+ RADEONWriteTVFIFO(pScrn, vTable, tmp);
+ if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
+ break;
+ }
+}
+
+/* restore TV PLLs */
+static void
+RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+ OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
+
+ RADEONWaitPLLLock(pScrn, 200, 800, 135);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
+
+ RADEONWaitPLLLock(pScrn, 300, 160, 27);
+ RADEONWaitPLLLock(pScrn, 200, 800, 135);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
+ OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
+}
+
+/* Restore TV horizontal/vertical settings */
+static void
+RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
+
+ OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
+ OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
+ OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
+
+ OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
+ OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
+
+ OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
+
+ OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
+ OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+
+ OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
+ OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
+ OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
+}
+
+/* restore TV RESTART registers */
+static void
+RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
+ OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
+ OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
+}
+
+/* restore tv standard & output muxes */
+static void
+RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
+
+ OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+ OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
+ OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
+
+ OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
+}
+
+/* Restore TV out regs */
+void
+RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ ErrorF("Entering Restore TV\n");
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_TV_FIFO_ASYNC_RST));
+
+ /* Temporarily turn the TV DAC off */
+ OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
+ | RADEON_TV_DAC_BGSLEEP
+ | RADEON_TV_DAC_RDACPD
+ | RADEON_TV_DAC_GDACPD
+ | RADEON_TV_DAC_BDACPD));
+
+ ErrorF("Restore TV PLL\n");
+ RADEONRestoreTVPLLRegisters(pScrn, restore);
+
+ ErrorF("Restore TVHV\n");
+ RADEONRestoreTVHVRegisters(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST));
+
+ ErrorF("Restore TV Restarts\n");
+ RADEONRestoreTVRestarts(pScrn, restore);
+
+ ErrorF("Restore Timing Tables\n");
+ RADEONRestoreTVTimingTables(pScrn, restore);
+
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+ | RADEON_TV_ASYNC_RST));
+
+ ErrorF("Restore TV standard\n");
+ RADEONRestoreTVOutputStd(pScrn, restore);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+
+ OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
+ OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
+
+ OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+ ErrorF("Leaving Restore TV\n");
+}
+
+/* Save horizontal/vertical timing code tables */
+static void
+RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD16 hTable;
+ CARD16 vTable;
+ CARD32 tmp;
+ unsigned i;
+
+ save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
+ hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
+ vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
+
+ /*
+ * Reset FIFO arbiter in order to be able to access FIFO RAM
+ */
+
+ OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+ | RADEON_CRT_ASYNC_RST
+ | RADEON_RESTART_PHASE_FIX
+ | RADEON_CRT_FIFO_CE_EN
+ | RADEON_TV_FIFO_CE_EN
+ | RADEON_TV_ON));
+
+ /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
+
+ ErrorF("saveTimingTables: reading timing tables\n");
+
+ for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
+ tmp = RADEONReadTVFIFO(pScrn, hTable--);
+ save->h_code_timing[ i ] = (CARD16)((tmp >> 14) & 0x3fff);
+ save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
+
+ if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
+ break;
+ }
+
+ for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
+ tmp = RADEONReadTVFIFO(pScrn, vTable++);
+ save->v_code_timing[ i ] = (CARD16)(tmp & 0x3fff);
+ save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
+
+ if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
+ break;
+ }
+}
+
+/* read TV regs */
+void
+RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ ErrorF("Entering TV Save\n");
+
+ save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
+ save->tv_frestart = INREG(RADEON_TV_FRESTART);
+ save->tv_hrestart = INREG(RADEON_TV_HRESTART);
+ save->tv_vrestart = INREG(RADEON_TV_VRESTART);
+ save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
+ save->tv_hdisp = INREG(RADEON_TV_HDISP);
+ save->tv_hstart = INREG(RADEON_TV_HSTART);
+ save->tv_htotal = INREG(RADEON_TV_HTOTAL);
+ save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
+ save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+ save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
+ save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
+ save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
+ save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+ save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
+ save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
+ save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
+ save->tv_vdisp = INREG(RADEON_TV_VDISP);
+ save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
+ save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
+ save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
+ save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
+ save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
+ save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
+ save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
+
+ save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
+ save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1);
+
+ ErrorF("Save TV timing tables\n");
+
+ RADEONSaveTVTimingTables(pScrn, save);
+
+ ErrorF("TV Save done\n");
+}
+
+
/* Compute F,V,H restarts from default restart position and hPos & vPos
* Return TRUE when code timing table was changed
*/
commit 910773d3a6c717f9d4762ea7b9ee6c3ae061781e
Author: Alex Deucher <alex at botch2.(none)>
Date: Fri Dec 21 15:53:15 2007 -0500
RADEON: more re-org. move XAA Mem init to radeon_accel.c
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 5bf03f5..8b2f167 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -915,3 +915,340 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn)
info->XInited3D = TRUE;
}
+#ifdef USE_XAA
+#ifdef XF86DRI
+Bool
+RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int cpp = info->CurrentLayout.pixel_bytes;
+ int depthCpp = (info->depthBits - 8) / 4;
+ int width_bytes = pScrn->displayWidth * cpp;
+ int bufferSize;
+ int depthSize;
+ int l;
+ int scanlines;
+ int texsizerequest;
+ BoxRec MemBox;
+ FBAreaPtr fbarea;
+
+ info->frontOffset = 0;
+ info->frontPitch = pScrn->displayWidth;
+ info->backPitch = pScrn->displayWidth;
+
+ /* make sure we use 16 line alignment for tiling (8 might be enough).
+ * Might need that for non-XF86DRI too?
+ */
+ if (info->allowColorTiling) {
+ bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes
+ + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
+ } else {
+ bufferSize = (pScrn->virtualY * width_bytes
+ + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
+ }
+
+ /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels,
+ * which is always the case if color tiling is used due to color pitch
+ * but not necessarily otherwise, and its height a multiple of 16 lines.
+ */
+ info->depthPitch = (pScrn->displayWidth + 31) & ~31;
+ depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch
+ * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
+
+ switch (info->CPMode) {
+ case RADEON_DEFAULT_CP_PIO_MODE:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n");
+ break;
+ case RADEON_DEFAULT_CP_BM_MODE:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n");
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n");
+ break;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB GART aperture\n", info->gartSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for the ring buffer\n", info->ringSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for vertex/indirect buffers\n", info->bufSize);
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB for GART textures\n", info->gartTexSize);
+
+ /* Try for front, back, depth, and three framebuffers worth of
+ * pixmap cache. Should be enough for a fullscreen background
+ * image plus some leftovers.
+ * If the FBTexPercent option was used, try to achieve that percentage instead,
+ * but still have at least one pixmap buffer (get problems with xvideo/render
+ * otherwise probably), and never reserve more than 3 offscreen buffers as it's
+ * probably useless for XAA.
+ */
+ if (info->textureSize >= 0) {
+ texsizerequest = ((int)info->FbMapSize - 2 * bufferSize - depthSize
+ - 2 * width_bytes - 16384 - info->FbSecureSize)
+ /* first divide, then multiply or we'll get an overflow (been there...) */
+ / 100 * info->textureSize;
+ }
+ else {
+ texsizerequest = (int)info->FbMapSize / 2;
+ }
+ info->textureSize = info->FbMapSize - info->FbSecureSize - 5 * bufferSize - depthSize;
+
+ /* If that gives us less than the requested memory, let's
+ * be greedy and grab some more. Sorry, I care more about 3D
+ * performance than playing nicely, and you'll get around a full
+ * framebuffer's worth of pixmap cache anyway.
+ */
+ if (info->textureSize < texsizerequest) {
+ info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize;
+ }
+ if (info->textureSize < texsizerequest) {
+ info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize;
+ }
+
+ /* If there's still no space for textures, try without pixmap cache, but
+ * never use the reserved space, the space hw cursor and PCIGART table might
+ * use.
+ */
+ if (info->textureSize < 0) {
+ info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize
+ - 2 * width_bytes - 16384 - info->FbSecureSize;
+ }
+
+ /* Check to see if there is more room available after the 8192nd
+ * scanline for textures
+ */
+ /* FIXME: what's this good for? condition is pretty much impossible to meet */
+ if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize
+ > info->textureSize) {
+ info->textureSize =
+ info->FbMapSize - 8192*width_bytes - bufferSize - depthSize;
+ }
+
+ /* If backbuffer is disabled, don't allocate memory for it */
+ if (info->noBackBuffer) {
+ info->textureSize += bufferSize;
+ }
+
+ /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer!
+ At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned,
+ otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee
+ it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor
+ area otherwise).
+ This might cause some space at the end of the video memory to be unused, since it
+ can't be used (?) due to that log_tex_granularity thing???
+ Could use different copyscreentoscreen function for the pageflip copies
+ (which would use different src and dst offsets) to avoid this. */
+ if (info->allowColorTiling && !info->noBackBuffer) {
+ info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize +
+ width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16);
+ }
+ if (info->textureSize > 0) {
+ l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
+ if (l < RADEON_LOG_TEX_GRANULARITY)
+ l = RADEON_LOG_TEX_GRANULARITY;
+ /* Round the texture size up to the nearest whole number of
+ * texture regions. Again, be greedy about this, don't
+ * round down.
+ */
+ info->log2TexGran = l;
+ info->textureSize = (info->textureSize >> l) << l;
+ } else {
+ info->textureSize = 0;
+ }
+
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256x32bpp textures.
+ */
+ if (info->textureSize < 512 * 1024) {
+ info->textureOffset = 0;
+ info->textureSize = 0;
+ }
+
+ if (info->allowColorTiling && !info->noBackBuffer) {
+ info->textureOffset = ((info->FbMapSize - info->textureSize) /
+ (width_bytes * 16)) * (width_bytes * 16);
+ }
+ else {
+ /* Reserve space for textures */
+ info->textureOffset = ((info->FbMapSize - info->textureSize +
+ RADEON_BUFFER_ALIGN) &
+ ~(CARD32)RADEON_BUFFER_ALIGN);
+ }
+
+ /* Reserve space for the shared depth
+ * buffer.
+ */
+ info->depthOffset = ((info->textureOffset - depthSize +
+ RADEON_BUFFER_ALIGN) &
+ ~(CARD32)RADEON_BUFFER_ALIGN);
+
+ /* Reserve space for the shared back buffer */
+ if (info->noBackBuffer) {
+ info->backOffset = info->depthOffset;
+ } else {
+ info->backOffset = ((info->depthOffset - bufferSize +
+ RADEON_BUFFER_ALIGN) &
+ ~(CARD32)RADEON_BUFFER_ALIGN);
+ }
+
+ info->backY = info->backOffset / width_bytes;
+ info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp;
+
+ scanlines = (info->FbMapSize-info->FbSecureSize) / width_bytes;
+ if (scanlines > 8191)
+ scanlines = 8191;
+
+ MemBox.x1 = 0;
+ MemBox.y1 = 0;
+ MemBox.x2 = pScrn->displayWidth;
+ MemBox.y2 = scanlines;
+
+ if (!xf86InitFBManager(pScreen, &MemBox)) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Memory manager initialization to "
+ "(%d,%d) (%d,%d) failed\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+ return FALSE;
+ } else {
+ int width, height;
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Memory manager initialized to (%d,%d) (%d,%d)\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+ /* why oh why can't we just request modes which are guaranteed to be 16 lines
+ aligned... sigh */
+ if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->displayWidth,
+ info->allowColorTiling ?
+ ((pScrn->virtualY + 15) & ~15)
+ - pScrn->virtualY + 2 : 2,
+ 0, NULL, NULL,
+ NULL))) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved area from (%d,%d) to (%d,%d)\n",
+ fbarea->box.x1, fbarea->box.y1,
+ fbarea->box.x2, fbarea->box.y2);
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
+ }
+
+ RADEONDRIAllocatePCIGARTTable(pScreen);
+
+ if (xf86QueryLargestOffscreenArea(pScreen, &width,
+ &height, 0, 0, 0)) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height);
+
+ /* Lines in offscreen area needed for depth buffer and
+ * textures
+ */
+ info->depthTexLines = (scanlines
+ - info->depthOffset / width_bytes);
+ info->backLines = (scanlines
+ - info->backOffset / width_bytes
+ - info->depthTexLines);
+ info->backArea = NULL;
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Unable to determine largest offscreen area "
+ "available\n");
+ return FALSE;
+ }
+ }
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use front buffer at offset 0x%x\n",
+ info->frontOffset);
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use back buffer at offset 0x%x\n",
+ info->backOffset);
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use depth buffer at offset 0x%x\n",
+ info->depthOffset);
+ if (info->cardType==CARD_PCIE)
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use %d kb for PCI GART table at offset 0x%x\n",
+ info->pciGartSize/1024, (unsigned)info->pciGartOffset);
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use %d kb for textures at offset 0x%x\n",
+ info->textureSize/1024, info->textureOffset);
+
+ info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
+ ((info->frontOffset + info->fbLocation) >> 10));
+
+ info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
+ ((info->backOffset + info->fbLocation) >> 10));
+
+ info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) |
+ ((info->depthOffset + info->fbLocation) >> 10));
+ return TRUE;
+}
+#endif /* XF86DRI */
+
+Bool
+RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ BoxRec MemBox;
+ int y2;
+
+ int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+
+ MemBox.x1 = 0;
+ MemBox.y1 = 0;
+ MemBox.x2 = pScrn->displayWidth;
+ y2 = info->FbMapSize / width_bytes;
+ if (y2 >= 32768)
+ y2 = 32767; /* because MemBox.y2 is signed short */
+ MemBox.y2 = y2;
+
+ /* The acceleration engine uses 14 bit
+ * signed coordinates, so we can't have any
+ * drawable caches beyond this region.
+ */
+ if (MemBox.y2 > 8191)
+ MemBox.y2 = 8191;
+
+ if (!xf86InitFBManager(pScreen, &MemBox)) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Memory manager initialization to "
+ "(%d,%d) (%d,%d) failed\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+ return FALSE;
+ } else {
+ int width, height;
+ FBAreaPtr fbarea;
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Memory manager initialized to (%d,%d) (%d,%d)\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
+ if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->displayWidth,
+ info->allowColorTiling ?
+ ((pScrn->virtualY + 15) & ~15)
+ - pScrn->virtualY + 2 : 2,
+ 0, NULL, NULL,
+ NULL))) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Reserved area from (%d,%d) to (%d,%d)\n",
+ fbarea->box.x1, fbarea->box.y1,
+ fbarea->box.x2, fbarea->box.y2);
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
+ }
+ if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
+ 0, 0, 0)) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height);
+ }
+ return TRUE;
+ }
+}
+#endif /* USE_XAA */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 85cfe88..7b9cd85 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2955,11 +2955,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
goto fail;
}
- /* Free the video bios (if applicable) */
- //if (info->VBIOS) {
- //xfree(info->VBIOS);
- //info->VBIOS = NULL;
- //}
/* Free int10 info */
if (pInt10)
@@ -3108,343 +3103,6 @@ static void RADEONBlockHandler(int i, pointer blockData,
#endif
}
-
-#ifdef USE_XAA
-#ifdef XF86DRI
-Bool RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int cpp = info->CurrentLayout.pixel_bytes;
- int depthCpp = (info->depthBits - 8) / 4;
- int width_bytes = pScrn->displayWidth * cpp;
- int bufferSize;
- int depthSize;
- int l;
- int scanlines;
- int texsizerequest;
- BoxRec MemBox;
- FBAreaPtr fbarea;
-
- info->frontOffset = 0;
- info->frontPitch = pScrn->displayWidth;
- info->backPitch = pScrn->displayWidth;
-
- /* make sure we use 16 line alignment for tiling (8 might be enough).
- * Might need that for non-XF86DRI too?
- */
- if (info->allowColorTiling) {
- bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes
- + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
- } else {
- bufferSize = (pScrn->virtualY * width_bytes
- + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
- }
-
- /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels,
- * which is always the case if color tiling is used due to color pitch
- * but not necessarily otherwise, and its height a multiple of 16 lines.
- */
- info->depthPitch = (pScrn->displayWidth + 31) & ~31;
- depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch
- * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
-
- switch (info->CPMode) {
- case RADEON_DEFAULT_CP_PIO_MODE:
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n");
- break;
- case RADEON_DEFAULT_CP_BM_MODE:
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n");
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n");
- break;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d MB GART aperture\n", info->gartSize);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d MB for the ring buffer\n", info->ringSize);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d MB for vertex/indirect buffers\n", info->bufSize);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d MB for GART textures\n", info->gartTexSize);
-
- /* Try for front, back, depth, and three framebuffers worth of
- * pixmap cache. Should be enough for a fullscreen background
- * image plus some leftovers.
- * If the FBTexPercent option was used, try to achieve that percentage instead,
- * but still have at least one pixmap buffer (get problems with xvideo/render
- * otherwise probably), and never reserve more than 3 offscreen buffers as it's
- * probably useless for XAA.
- */
- if (info->textureSize >= 0) {
- texsizerequest = ((int)info->FbMapSize - 2 * bufferSize - depthSize
- - 2 * width_bytes - 16384 - info->FbSecureSize)
- /* first divide, then multiply or we'll get an overflow (been there...) */
- / 100 * info->textureSize;
- }
- else {
- texsizerequest = (int)info->FbMapSize / 2;
- }
- info->textureSize = info->FbMapSize - info->FbSecureSize - 5 * bufferSize - depthSize;
-
- /* If that gives us less than the requested memory, let's
- * be greedy and grab some more. Sorry, I care more about 3D
- * performance than playing nicely, and you'll get around a full
- * framebuffer's worth of pixmap cache anyway.
- */
- if (info->textureSize < texsizerequest) {
- info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize;
- }
- if (info->textureSize < texsizerequest) {
- info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize;
- }
-
- /* If there's still no space for textures, try without pixmap cache, but
- * never use the reserved space, the space hw cursor and PCIGART table might
- * use.
- */
- if (info->textureSize < 0) {
- info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize
- - 2 * width_bytes - 16384 - info->FbSecureSize;
- }
-
- /* Check to see if there is more room available after the 8192nd
- * scanline for textures
- */
- /* FIXME: what's this good for? condition is pretty much impossible to meet */
- if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize
- > info->textureSize) {
- info->textureSize =
- info->FbMapSize - 8192*width_bytes - bufferSize - depthSize;
- }
-
- /* If backbuffer is disabled, don't allocate memory for it */
- if (info->noBackBuffer) {
- info->textureSize += bufferSize;
- }
-
- /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer!
- At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned,
- otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee
- it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor
- area otherwise).
- This might cause some space at the end of the video memory to be unused, since it
- can't be used (?) due to that log_tex_granularity thing???
- Could use different copyscreentoscreen function for the pageflip copies
- (which would use different src and dst offsets) to avoid this. */
- if (info->allowColorTiling && !info->noBackBuffer) {
- info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize +
- width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16);
- }
- if (info->textureSize > 0) {
- l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
- if (l < RADEON_LOG_TEX_GRANULARITY)
- l = RADEON_LOG_TEX_GRANULARITY;
- /* Round the texture size up to the nearest whole number of
- * texture regions. Again, be greedy about this, don't
- * round down.
- */
- info->log2TexGran = l;
- info->textureSize = (info->textureSize >> l) << l;
- } else {
- info->textureSize = 0;
- }
-
- /* Set a minimum usable local texture heap size. This will fit
- * two 256x256x32bpp textures.
- */
- if (info->textureSize < 512 * 1024) {
- info->textureOffset = 0;
- info->textureSize = 0;
- }
-
- if (info->allowColorTiling && !info->noBackBuffer) {
- info->textureOffset = ((info->FbMapSize - info->textureSize) /
- (width_bytes * 16)) * (width_bytes * 16);
- }
- else {
- /* Reserve space for textures */
- info->textureOffset = ((info->FbMapSize - info->textureSize +
- RADEON_BUFFER_ALIGN) &
- ~(CARD32)RADEON_BUFFER_ALIGN);
- }
-
- /* Reserve space for the shared depth
- * buffer.
- */
- info->depthOffset = ((info->textureOffset - depthSize +
- RADEON_BUFFER_ALIGN) &
- ~(CARD32)RADEON_BUFFER_ALIGN);
-
- /* Reserve space for the shared back buffer */
- if (info->noBackBuffer) {
- info->backOffset = info->depthOffset;
- } else {
- info->backOffset = ((info->depthOffset - bufferSize +
- RADEON_BUFFER_ALIGN) &
- ~(CARD32)RADEON_BUFFER_ALIGN);
- }
-
- info->backY = info->backOffset / width_bytes;
- info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp;
-
- scanlines = (info->FbMapSize-info->FbSecureSize) / width_bytes;
- if (scanlines > 8191)
- scanlines = 8191;
-
- MemBox.x1 = 0;
- MemBox.y1 = 0;
- MemBox.x2 = pScrn->displayWidth;
- MemBox.y2 = scanlines;
-
- if (!xf86InitFBManager(pScreen, &MemBox)) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Memory manager initialization to "
- "(%d,%d) (%d,%d) failed\n",
- MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
- return FALSE;
- } else {
- int width, height;
-
- xf86DrvMsg(scrnIndex, X_INFO,
- "Memory manager initialized to (%d,%d) (%d,%d)\n",
- MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
- /* why oh why can't we just request modes which are guaranteed to be 16 lines
- aligned... sigh */
- if ((fbarea = xf86AllocateOffscreenArea(pScreen,
- pScrn->displayWidth,
- info->allowColorTiling ?
- ((pScrn->virtualY + 15) & ~15)
- - pScrn->virtualY + 2 : 2,
- 0, NULL, NULL,
- NULL))) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Reserved area from (%d,%d) to (%d,%d)\n",
- fbarea->box.x1, fbarea->box.y1,
- fbarea->box.x2, fbarea->box.y2);
- } else {
- xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
- }
-
- RADEONDRIAllocatePCIGARTTable(pScreen);
-
- if (xf86QueryLargestOffscreenArea(pScreen, &width,
- &height, 0, 0, 0)) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Largest offscreen area available: %d x %d\n",
- width, height);
-
- /* Lines in offscreen area needed for depth buffer and
- * textures
- */
- info->depthTexLines = (scanlines
- - info->depthOffset / width_bytes);
- info->backLines = (scanlines
- - info->backOffset / width_bytes
- - info->depthTexLines);
- info->backArea = NULL;
- } else {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Unable to determine largest offscreen area "
- "available\n");
- return FALSE;
- }
- }
-
- xf86DrvMsg(scrnIndex, X_INFO,
- "Will use front buffer at offset 0x%x\n",
- info->frontOffset);
-
- xf86DrvMsg(scrnIndex, X_INFO,
- "Will use back buffer at offset 0x%x\n",
- info->backOffset);
- xf86DrvMsg(scrnIndex, X_INFO,
- "Will use depth buffer at offset 0x%x\n",
- info->depthOffset);
- if (info->cardType==CARD_PCIE)
- xf86DrvMsg(scrnIndex, X_INFO,
- "Will use %d kb for PCI GART table at offset 0x%x\n",
- info->pciGartSize/1024, (unsigned)info->pciGartOffset);
- xf86DrvMsg(scrnIndex, X_INFO,
- "Will use %d kb for textures at offset 0x%x\n",
- info->textureSize/1024, info->textureOffset);
-
- info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
- ((info->frontOffset + info->fbLocation) >> 10));
-
- info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
- ((info->backOffset + info->fbLocation) >> 10));
-
- info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) |
- ((info->depthOffset + info->fbLocation) >> 10));
- return TRUE;
-}
-#endif /* XF86DRI */
-
-Bool RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RADEONInfoPtr info = RADEONPTR(pScrn);
- BoxRec MemBox;
- int y2;
-
- int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
-
- MemBox.x1 = 0;
- MemBox.y1 = 0;
- MemBox.x2 = pScrn->displayWidth;
- y2 = info->FbMapSize / width_bytes;
- if (y2 >= 32768)
- y2 = 32767; /* because MemBox.y2 is signed short */
- MemBox.y2 = y2;
-
- /* The acceleration engine uses 14 bit
- * signed coordinates, so we can't have any
- * drawable caches beyond this region.
- */
- if (MemBox.y2 > 8191)
- MemBox.y2 = 8191;
-
- if (!xf86InitFBManager(pScreen, &MemBox)) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "Memory manager initialization to "
- "(%d,%d) (%d,%d) failed\n",
- MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
- return FALSE;
- } else {
- int width, height;
- FBAreaPtr fbarea;
-
- xf86DrvMsg(scrnIndex, X_INFO,
- "Memory manager initialized to (%d,%d) (%d,%d)\n",
- MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2);
- if ((fbarea = xf86AllocateOffscreenArea(pScreen,
- pScrn->displayWidth,
- info->allowColorTiling ?
- ((pScrn->virtualY + 15) & ~15)
- - pScrn->virtualY + 2 : 2,
- 0, NULL, NULL,
- NULL))) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Reserved area from (%d,%d) to (%d,%d)\n",
- fbarea->box.x1, fbarea->box.y1,
- fbarea->box.x2, fbarea->box.y2);
- } else {
- xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n");
- }
- if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
- 0, 0, 0)) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Largest offscreen area available: %d x %d\n",
- width, height);
- }
- return TRUE;
- }
-}
-#endif /* USE_XAA */
-
static void
RADEONPointerMoved(int index, int x, int y)
{
commit 0631a23bd103f9b74e525da2c41304eab60c6f17
Author: Alex Deucher <alex at botch2.(none)>
Date: Fri Dec 21 15:40:18 2007 -0500
RADEON: fix rn50 reversion from last merge
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e65e446..85cfe88 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1222,18 +1222,6 @@ static void RADEONGetClockInfo(ScrnInfoPtr pScrn)
info->mclk = 200.00;
}
- if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
- /* Avoid RN50 corruption due to memory bandwidth starvation.
- * 18 is an empirical value based on the databook and Windows driver.
- *
- * Empirical value changed to 24 to raise pixel clock limit and
- * allow higher resolution modes on capable monitors
- */
- pll->pll_out_max = min(pll->pll_out_max,
- 24 * info->mclk * 100 / pScrn->bitsPerPixel *
- info->RamWidth / 16);
- }
-
/* card limits for computing PLLs */
if (IS_AVIVO_VARIANT) {
pll->min_post_div = 2;
commit 5b917797a13c6caa80028d1842a284598e874288
Author: Alex Deucher <alex at botch2.(none)>
Date: Fri Dec 21 15:30:20 2007 -0500
RADEON: remove no longer used radeon_display.c
diff --git a/src/radeon_display.c b/src/radeon_display.c
deleted file mode 100644
index 1c529cf..0000000
--- a/src/radeon_display.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
- * VA Linux Systems Inc., Fremont, California.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
- * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <stdio.h>
-
-/* X and server generic header files */
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "vgaHW.h"
-#include "xf86Modes.h"
-
-/* Driver data structures */
-#include "radeon.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
-#include "radeon_probe.h"
-#include "radeon_version.h"
-
-extern int getRADEONEntityIndex(void);
-
-
-void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
-{
- MonPtr mon = pScrn->monitor;
- xf86MonPtr ddc = mon->DDC;
- int i;
-
- if (flag) { /* HSync */
- for (i = 0; i < 4; i++) {
- if (ddc->det_mon[i].type == DS_RANGES) {
- mon->nHsync = 1;
- mon->hsync[0].lo = ddc->det_mon[i].section.ranges.min_h;
- mon->hsync[0].hi = ddc->det_mon[i].section.ranges.max_h;
- return;
- }
- }
- /* If no sync ranges detected in detailed timing table, let's
- * try to derive them from supported VESA modes. Are we doing
- * too much here!!!? */
- i = 0;
- if (ddc->timings1.t1 & 0x02) { /* 800x600 at 56 */
- mon->hsync[i].lo = mon->hsync[i].hi = 35.2;
- i++;
- }
- if (ddc->timings1.t1 & 0x04) { /* 640x480 at 75 */
- mon->hsync[i].lo = mon->hsync[i].hi = 37.5;
- i++;
- }
- if ((ddc->timings1.t1 & 0x08) || (ddc->timings1.t1 & 0x01)) {
- mon->hsync[i].lo = mon->hsync[i].hi = 37.9;
- i++;
- }
- if (ddc->timings1.t2 & 0x40) {
- mon->hsync[i].lo = mon->hsync[i].hi = 46.9;
- i++;
- }
- if ((ddc->timings1.t2 & 0x80) || (ddc->timings1.t2 & 0x08)) {
- mon->hsync[i].lo = mon->hsync[i].hi = 48.1;
- i++;
- }
- if (ddc->timings1.t2 & 0x04) {
- mon->hsync[i].lo = mon->hsync[i].hi = 56.5;
- i++;
- }
- if (ddc->timings1.t2 & 0x02) {
- mon->hsync[i].lo = mon->hsync[i].hi = 60.0;
- i++;
- }
- if (ddc->timings1.t2 & 0x01) {
- mon->hsync[i].lo = mon->hsync[i].hi = 64.0;
- i++;
- }
- mon->nHsync = i;
- } else { /* Vrefresh */
- for (i = 0; i < 4; i++) {
- if (ddc->det_mon[i].type == DS_RANGES) {
- mon->nVrefresh = 1;
- mon->vrefresh[0].lo = ddc->det_mon[i].section.ranges.min_v;
- mon->vrefresh[0].hi = ddc->det_mon[i].section.ranges.max_v;
- return;
- }
- }
-
- i = 0;
- if (ddc->timings1.t1 & 0x02) { /* 800x600 at 56 */
- mon->vrefresh[i].lo = mon->vrefresh[i].hi = 56;
- i++;
- }
- if ((ddc->timings1.t1 & 0x01) || (ddc->timings1.t2 & 0x08)) {
- mon->vrefresh[i].lo = mon->vrefresh[i].hi = 60;
- i++;
- }
- if (ddc->timings1.t2 & 0x04) {
- mon->vrefresh[i].lo = mon->vrefresh[i].hi = 70;
- i++;
- }
- if ((ddc->timings1.t1 & 0x08) || (ddc->timings1.t2 & 0x80)) {
- mon->vrefresh[i].lo = mon->vrefresh[i].hi = 72;
- i++;
- }
- if ((ddc->timings1.t1 & 0x04) || (ddc->timings1.t2 & 0x40) ||
- (ddc->timings1.t2 & 0x02) || (ddc->timings1.t2 & 0x01)) {
- mon->vrefresh[i].lo = mon->vrefresh[i].hi = 75;
- i++;
- }
- mon->nVrefresh = i;
- }
-}
commit bf14aa5f88fc3b4e69d71db5b23248b8bb2018d0
Author: Alex Deucher <alex at botch2.(none)>
Date: Fri Dec 21 15:29:47 2007 -0500
RADEON: re-org legacy crtc/output code into separate files
diff --git a/src/Makefile.am b/src/Makefile.am
index 3e0352b..7b25e4b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -116,7 +116,8 @@ radeon_drv_ladir = @moduledir@/drivers
radeon_drv_la_SOURCES = \
radeon_accel.c radeon_cursor.c radeon_dga.c \
radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
- radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
+ radeon_vip.c radeon_misc.c radeon_probe.c \
+ legacy_crtc.c legacy_output.c \
radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
$(RADEON_ATOMBIOS_SOURCES) radeon_atombios.c radeon_atomwrapper.c \
$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES) atombios_output.c atombios_crtc.c
diff --git a/src/legacy_crtc.c b/src/legacy_crtc.c
new file mode 100644
index 0000000..f1bf9be
--- /dev/null
+++ b/src/legacy_crtc.c
@@ -0,0 +1,1268 @@
+/*
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ * VA Linux Systems Inc., Fremont, California.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "radeon_dri.h"
+#include "radeon_sarea.h"
+#include "sarea.h"
+#endif
+
+
+void
+legacy_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+ int mask;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
+
+
+ switch(mode) {
+ case DPMSModeOn:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+ }
+ break;
+ case DPMSModeStandby:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
+ }
+ break;
+ case DPMSModeSuspend:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
+ }
+ break;
+ case DPMSModeOff:
+ if (radeon_crtc->crtc_id) {
+ OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+ } else {
+ OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B);
+ OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+ }
+ break;
+ }
+
+ if (mode != DPMSModeOff)
+ radeon_crtc_load_lut(crtc);
+}
+
+
+/* Define common registers for requested video mode */
+static void
+RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
+{
+ save->ovr_clr = 0;
+ save->ovr_wid_left_right = 0;
+ save->ovr_wid_top_bottom = 0;
+ save->ov0_scale_cntl = 0;
+ save->subpic_cntl = 0;
+ save->viph_control = 0;
+ save->i2c_cntl_1 = 0;
+ save->rbbm_soft_reset = 0;
+ save->cap0_trig_cntl = 0;
+ save->cap1_trig_cntl = 0;
+ save->bus_cntl = info->BusCntl;
+ /*
+ * If bursts are enabled, turn on discards
+ * Radeon doesn't have write bursts
+ */
+ if (save->bus_cntl & (RADEON_BUS_READ_BURST))
+ save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
+}
+
+static void
+RADEONInitSurfaceCntl(xf86CrtcPtr crtc, RADEONSavePtr save)
+{
+ save->surface_cntl = 0;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ /* We must set both apertures as they can be both used to map the entire
+ * video memory. -BenH.
+ */
+ switch (crtc->scrn->bitsPerPixel) {
+ case 16:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
+ break;
+
+ case 32:
+ save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
+ save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
+ break;
+ }
+#endif
+
+}
+
+
+static Bool
+RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
+ int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int Base;
+#ifdef XF86DRI
+ RADEONSAREAPrivPtr pSAREAPriv;
+ XF86DRISAREAPtr pSAREA;
+#endif
+
+ save->crtc_offset = pScrn->fbOffset;
+#ifdef XF86DRI
+ if (info->allowPageFlip)
+ save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+ else
+#endif
+ save->crtc_offset_cntl = 0;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT)
+ save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
+ }
+ else {
+ if (IS_R300_VARIANT)
+ save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+ }
+
+ Base = pScrn->fbOffset;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT) {
+ /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+ * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
+ * Makes tiling MUCH easier.
+ */
+ save->crtc_tile_x0_y0 = x | (y << 16);
+ Base &= ~0x7ff;
+ } else {
+ /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+ drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+ flickering when scrolling vertically in a virtual screen, possibly because crtc will
+ pick up the new offset value at the end of each scanline, but the new offset_cntl value
+ only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+ OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+ /*save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;*/
+#if 0
+ /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+ if (!info->have3DWindows)
+#endif
+ save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+ int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+ /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+ int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+ Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+ save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
+ }
+ }
+ else {
+ int offset = y * info->CurrentLayout.displayWidth + x;
+ switch (info->CurrentLayout.pixel_code) {
+ case 15:
+ case 16: offset *= 2; break;
+ case 24: offset *= 3; break;
+ case 32: offset *= 4; break;
+ }
+ Base += offset;
+ }
+
+ if (crtc->rotatedData != NULL) {
+ Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
+ }
+
+ Base &= ~7; /* 3 lower bits are always 0 */
+
+
+#ifdef XF86DRI
+ if (info->directRenderingInited) {
+ /* note cannot use pScrn->pScreen since this is unitialized when called from
+ RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+ *** pageflipping!
+ ***/
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ /* can't get at sarea in a semi-sane way? */
+ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+ pSAREA->frame.x = (Base / info->CurrentLayout.pixel_bytes)
+ % info->CurrentLayout.displayWidth;
+ pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
+ / info->CurrentLayout.displayWidth;
+ pSAREA->frame.width = pScrn->frameX1 - x + 1;
+ pSAREA->frame.height = pScrn->frameY1 - y + 1;
+
+ if (pSAREAPriv->pfCurrentPage == 1) {
+ Base += info->backOffset - info->frontOffset;
+ }
+ }
+#endif
+ save->crtc_offset = Base;
+
+ return TRUE;
+
+}
+
+/* Define CRTC registers for requested video mode */
+static Bool
+RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int vsync_wid;
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; break;
+ case 8: format = 2; break;
+ case 15: format = 3; break; /* 555 */
+ case 16: format = 4; break; /* 565 */
+ case 24: format = 5; break; /* RGB */
+ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n",
+ info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+
+ /*save->bios_4_scratch = info->SavedReg->bios_4_scratch;*/
+ save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
+ | RADEON_CRTC_EN
+ | (format << 8)
+ | ((mode->Flags & V_DBLSCAN)
+ ? RADEON_CRTC_DBL_SCAN_EN
+ : 0)
+ | ((mode->Flags & V_CSYNC)
+ ? RADEON_CRTC_CSYNC_EN
+ : 0)
+ | ((mode->Flags & V_INTERLACE)
+ ? RADEON_CRTC_INTERLACE_EN
+ : 0));
+
+ save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
+ RADEON_CRTC_VSYNC_DIS |
+ RADEON_CRTC_HSYNC_DIS |
+ RADEON_CRTC_DISPLAY_DIS);
+
+ save->disp_merge_cntl = info->SavedReg->disp_merge_cntl;
+ save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+
+ save->crtc_more_cntl = 0;
+ if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+ (info->ChipFamily == CHIP_FAMILY_RS200)) {
+ /* This is to workaround the asic bug for RMX, some versions
+ of BIOS dosen't have this register initialized correctly.
+ */
+ save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
+ }
+
+ save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+ | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
+ << 16));
+
+ hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+ if (!hsync_wid) hsync_wid = 1;
+ hsync_start = mode->CrtcHSyncStart - 8;
+
+ save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
+ | ((hsync_wid & 0x3f) << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? RADEON_CRTC_H_SYNC_POL
+ : 0));
+
+ /* This works for double scan mode. */
+ save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+
+ vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ if (!vsync_wid) vsync_wid = 1;
+
+ save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+ | ((vsync_wid & 0x1f) << 16)
+ | ((mode->Flags & V_NVSYNC)
+ ? RADEON_CRTC_V_SYNC_POL
+ : 0));
+
+ save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
+ ((pScrn->bitsPerPixel * 8) -1)) /
+ (pScrn->bitsPerPixel * 8));
+ save->crtc_pitch |= save->crtc_pitch << 16;
+
+ save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+ save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
+ save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+ save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+
+ if (info->IsDellServer) {
+ save->dac2_cntl = info->SavedReg->dac2_cntl;
+ save->tv_dac_cntl = info->SavedReg->tv_dac_cntl;
+ save->crtc2_gen_cntl = info->SavedReg->crtc2_gen_cntl;
+ save->disp_hw_debug = info->SavedReg->disp_hw_debug;
+
+ save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+ save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+
+ /* For CRT on DAC2, don't turn it on if BIOS didn't
+ enable it, even it's detected.
+ */
+ save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+ save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
+ save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
+ }
+
+ return TRUE;
+}
+
+
+static Bool
+RADEONInitCrtc2Base(xf86CrtcPtr crtc, RADEONSavePtr save,
+ int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int Base;
+#ifdef XF86DRI
+ RADEONSAREAPrivPtr pSAREAPriv;
+ XF86DRISAREAPtr pSAREA;
+#endif
+
+ /* It seems all fancy options apart from pflip can be safely disabled
+ */
+ save->crtc2_offset = pScrn->fbOffset;
+#ifdef XF86DRI
+ if (info->allowPageFlip)
+ save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+ else
+#endif
+ save->crtc2_offset_cntl = 0;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT)
+ save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
+ }
+ else {
+ if (IS_R300_VARIANT)
+ save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+ R300_CRTC_MICRO_TILE_BUFFER_DIS |
+ R300_CRTC_MACRO_TILE_EN);
+ else
+ save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
+ }
+
+ Base = pScrn->fbOffset;
+
+ if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
+ if (IS_R300_VARIANT) {
+ /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
+ * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
+ * Makes tiling MUCH easier.
+ */
+ save->crtc2_tile_x0_y0 = x | (y << 16);
+ Base &= ~0x7ff;
+ } else {
+ /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
+ drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
+ flickering when scrolling vertically in a virtual screen, possibly because crtc will
+ pick up the new offset value at the end of each scanline, but the new offset_cntl value
+ only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
+ OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
+ /*save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;*/
+#if 0
+ /* try to get rid of flickering when scrolling at least for 2d */
+#ifdef XF86DRI
+ if (!info->have3DWindows)
+#endif
+ save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+ int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
+ /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
+ int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
+ Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
+ save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
+ }
+ }
+ else {
+ int offset = y * info->CurrentLayout.displayWidth + x;
+ switch (info->CurrentLayout.pixel_code) {
+ case 15:
+ case 16: offset *= 2; break;
+ case 24: offset *= 3; break;
+ case 32: offset *= 4; break;
+ }
+ Base += offset;
+ }
+
+ if (crtc->rotatedData != NULL) {
+ Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
+ }
+
+ Base &= ~7; /* 3 lower bits are always 0 */
+
+#ifdef XF86DRI
+ if (info->directRenderingInited) {
+ /* note cannot use pScrn->pScreen since this is unitialized when called from
+ RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
+ /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
+ *** pageflipping!
+ ***/
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ /* can't get at sarea in a semi-sane way? */
+ pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
+
+ pSAREAPriv->crtc2_base = Base;
+
+ if (pSAREAPriv->pfCurrentPage == 1) {
+ Base += info->backOffset - info->frontOffset;
+ }
+ }
+#endif
+ save->crtc2_offset = Base;
+
+ return TRUE;
+}
+
+
+/* Define CRTC2 registers for requested video mode */
+static Bool
+RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int format;
+ int hsync_start;
+ int hsync_wid;
+ int vsync_wid;
+
+ switch (info->CurrentLayout.pixel_code) {
+ case 4: format = 1; break;
+ case 8: format = 2; break;
+ case 15: format = 3; break; /* 555 */
+ case 16: format = 4; break; /* 565 */
+ case 24: format = 5; break; /* RGB */
+ case 32: format = 6; break; /* xRGB */
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unsupported pixel depth (%d)\n",
+ info->CurrentLayout.bitsPerPixel);
+ return FALSE;
+ }
+
+ save->crtc2_h_total_disp =
+ ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
+ | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
+
+ hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
+ if (!hsync_wid) hsync_wid = 1;
+ hsync_start = mode->CrtcHSyncStart - 8;
+
+ save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
+ | ((hsync_wid & 0x3f) << 16)
+ | ((mode->Flags & V_NHSYNC)
+ ? RADEON_CRTC_H_SYNC_POL
+ : 0));
+
+ /* This works for double scan mode. */
+ save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
+ | ((mode->CrtcVDisplay - 1) << 16));
+
+ vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
+ if (!vsync_wid) vsync_wid = 1;
+
+ save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+ | ((vsync_wid & 0x1f) << 16)
+ | ((mode->Flags & V_NVSYNC)
+ ? RADEON_CRTC2_V_SYNC_POL
+ : 0));
+
+ save->crtc2_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
+ ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
+ save->crtc2_pitch |= save->crtc2_pitch << 16;
+
+ /* check to see if TV DAC is enabled for another crtc and keep it enabled */
+ if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
+ save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
+ else
+ save->crtc2_gen_cntl = 0;
+
+ save->crtc2_gen_cntl |= (RADEON_CRTC2_EN
+ | (format << 8)
+ | RADEON_CRTC2_VSYNC_DIS
+ | RADEON_CRTC2_HSYNC_DIS
+ | RADEON_CRTC2_DISP_DIS
+ | ((mode->Flags & V_DBLSCAN)
+ ? RADEON_CRTC2_DBL_SCAN_EN
+ : 0)
+ | ((mode->Flags & V_CSYNC)
+ ? RADEON_CRTC2_CSYNC_EN
+ : 0)
+ | ((mode->Flags & V_INTERLACE)
+ ? RADEON_CRTC2_INTERLACE_EN
+ : 0));
+
+ save->disp2_merge_cntl = info->SavedReg->disp2_merge_cntl;
+ save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
+
+ save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
+ save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
+
+ if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
+ save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
+ save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
+ save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
+ }
+
+ return TRUE;
+}
+
+
+/* Define PLL registers for requested video mode */
+static void
+RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ RADEONPLLPtr pll, DisplayModePtr mode,
+ int flags)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD32 feedback_div = 0;
+ CARD32 reference_div = 0;
+ CARD32 post_divider = 0;
+ CARD32 freq = 0;
+
+ struct {
+ int divider;
+ int bitvalue;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 16, 5 }, /* VCLK_SRC/16 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+
+
+ if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
+ save->ppll_ref_div = info->RefDivider;
+ save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
+ save->htotal_cntl = 0;
+ return;
+ }
+
+ RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ if (post_div->divider == post_divider)
+ break;
+ }
+
+ if (!post_div->divider) {
+ save->pll_output_freq = freq;
+ post_div = &post_divs[0];
+ }
+
+ save->dot_clock_freq = freq;
+ save->feedback_div = feedback_div;
+ save->reference_div = reference_div;
+ save->post_div = post_divider;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
+ (unsigned)save->dot_clock_freq,
+ (unsigned)save->pll_output_freq,
+ save->feedback_div,
+ save->reference_div,
+ save->post_div);
+
+ save->ppll_ref_div = save->reference_div;
+
+#if defined(__powerpc__)
+ /* apparently programming this otherwise causes a hang??? */
+ if (info->MacModel == RADEON_MAC_IBOOK)
+ save->ppll_div_3 = 0x000600ad;
+ else
+#endif
+ save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
+
+ save->htotal_cntl = mode->HTotal & 0x7;
+
+ save->vclk_ecp_cntl = (info->SavedReg->vclk_ecp_cntl &
+ ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
+}
+
+/* Define PLL2 registers for requested video mode */
+static void
+RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ RADEONPLLPtr pll, DisplayModePtr mode,
+ int flags)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ CARD32 feedback_div = 0;
+ CARD32 reference_div = 0;
+ CARD32 post_divider = 0;
+ CARD32 freq = 0;
+
+ struct {
+ int divider;
+ int bitvalue;
+ } *post_div, post_divs[] = {
+ /* From RAGE 128 VR/RAGE 128 GL Register
+ * Reference Manual (Technical Reference
+ * Manual P/N RRG-G04100-C Rev. 0.04), page
+ * 3-17 (PLL_DIV_[3:0]).
+ */
+ { 1, 0 }, /* VCLK_SRC */
+ { 2, 1 }, /* VCLK_SRC/2 */
+ { 4, 2 }, /* VCLK_SRC/4 */
+ { 8, 3 }, /* VCLK_SRC/8 */
+ { 3, 4 }, /* VCLK_SRC/3 */
+ { 6, 6 }, /* VCLK_SRC/6 */
+ { 12, 7 }, /* VCLK_SRC/12 */
+ { 0, 0 }
+ };
+
+ if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
+ save->p2pll_ref_div = info->RefDivider;
+ save->p2pll_div_0 = info->FeedbackDivider | (info->PostDivider << 16);
+ save->htotal_cntl2 = 0;
+ return;
+ }
+
+ RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ if (post_div->divider == post_divider)
+ break;
+ }
+
+ if (!post_div->divider) {
+ save->pll_output_freq_2 = freq;
+ post_div = &post_divs[0];
+ }
+
+ save->dot_clock_freq_2 = freq;
+ save->feedback_div_2 = feedback_div;
+ save->reference_div_2 = reference_div;
+ save->post_div_2 = post_divider;
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
+ (unsigned)save->dot_clock_freq_2,
+ (unsigned)save->pll_output_freq_2,
+ save->feedback_div_2,
+ save->reference_div_2,
+ save->post_div_2);
+
+ save->p2pll_ref_div = save->reference_div_2;
+
+ save->p2pll_div_0 = (save->feedback_div_2 |
+ (post_div->bitvalue << 16));
+
+ save->htotal_cntl2 = mode->HTotal & 0x7;
+
+ save->pixclks_cntl = ((info->SavedReg->pixclks_cntl &
+ ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+ RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
+}
+
+static void
+RADEONInitBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ /* tell the bios not to muck with the hardware on events */
+ save->bios_4_scratch = 0x4; /* 0x4 needed for backlight */
+ save->bios_5_scratch = (info->SavedReg->bios_5_scratch & 0xff) | 0xff00; /* bits 0-3 keep backlight level */
+ save->bios_6_scratch = info->SavedReg->bios_6_scratch | 0x40000000;
+
+}
+
+static void
+radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+ /* pixclks_cntl controls tv clock routing */
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+}
+
+/* Calculate display buffer watermark to prevent buffer underflow */
+static void
+RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
+{
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ CARD32 temp, data, mem_trcd, mem_trp, mem_tras, mem_trbs=0;
+ float mem_tcas;
+ int k1, c;
+ CARD32 MemTrcdExtMemCntl[4] = {1, 2, 3, 4};
+ CARD32 MemTrpExtMemCntl[4] = {1, 2, 3, 4};
+ CARD32 MemTrasExtMemCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+
+ CARD32 MemTrcdMemTimingCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+ CARD32 MemTrpMemTimingCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+ CARD32 MemTrasMemTimingCntl[16] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+
+ float MemTcas[8] = {0, 1, 2, 3, 0, 1.5, 2.5, 0};
+ float MemTcas2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+ float MemTrbs[8] = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5};
+
+ float mem_bw, peak_disp_bw;
+ float min_mem_eff = 0.8;
+ float sclk_eff, sclk_delay;
+ float mc_latency_mclk, mc_latency_sclk, cur_latency_mclk, cur_latency_sclk;
+ float disp_latency, disp_latency_overhead, disp_drain_rate, disp_drain_rate2;
+ float pix_clk, pix_clk2; /* in MHz */
+ int cur_size = 16; /* in octawords */
+ int critical_point, critical_point2;
+ int stop_req, max_stop_req;
+ float read_return_rate, time_disp1_drop_priority;
+
+ /*
+ * Set display0/1 priority up on r3/4xx in the memory controller for
+ * high res modes if the user specifies HIGH for displaypriority
+ * option.
+ */
+ if ((info->DispPriority == 2) && IS_R300_VARIANT) {
+ CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
+ if (pRADEONEnt->pCrtc[1]->enabled) {
+ mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
+ } else {
+ mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
+ }
+ OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
+ }
+
+
+ /* R420 and RV410 family not supported yet */
+ if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return;
+
+ /*
+ * Determine if there is enough bandwidth for current display mode
+ */
+ mem_bw = info->mclk * (info->RamWidth / 8) * (info->IsDDR ? 2 : 1);
+
+ pix_clk = mode1->Clock/1000.0;
+ if (mode2)
+ pix_clk2 = mode2->Clock/1000.0;
+ else
+ pix_clk2 = 0;
+
+ peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
+ if (pixel_bytes2)
+ peak_disp_bw += (pix_clk2 * pixel_bytes2);
+
+ if (peak_disp_bw >= mem_bw * min_mem_eff) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "You may not have enough display bandwidth for current mode\n"
+ "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
+ }
+
+ /* CRTC1
+ Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
+ GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
+ */
+ stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16;
+
+ /* setup Max GRPH_STOP_REQ default value */
+ if (IS_RV100_VARIANT)
+ max_stop_req = 0x5c;
+ else
+ max_stop_req = 0x7c;
+ if (stop_req > max_stop_req)
+ stop_req = max_stop_req;
+
+ /* Get values from the EXT_MEM_CNTL register...converting its contents. */
+ temp = INREG(RADEON_MEM_TIMING_CNTL);
+ if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
+ mem_trcd = MemTrcdExtMemCntl[(temp & 0x0c) >> 2];
+ mem_trp = MemTrpExtMemCntl[ (temp & 0x03) >> 0];
+ mem_tras = MemTrasExtMemCntl[(temp & 0x70) >> 4];
+ } else { /* RV200 and later */
+ mem_trcd = MemTrcdMemTimingCntl[(temp & 0x07) >> 0];
+ mem_trp = MemTrpMemTimingCntl[ (temp & 0x700) >> 8];
+ mem_tras = MemTrasMemTimingCntl[(temp & 0xf000) >> 12];
+ }
+
+ /* Get values from the MEM_SDRAM_MODE_REG register...converting its */
+ temp = INREG(RADEON_MEM_SDRAM_MODE_REG);
+ data = (temp & (7<<20)) >> 20;
+ if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
+ mem_tcas = MemTcas [data];
+ } else {
+ mem_tcas = MemTcas2 [data];
+ }
+
+ if (IS_R300_VARIANT) {
+
+ /* on the R300, Tcas is included in Trbs.
+ */
+ temp = INREG(RADEON_MEM_CNTL);
+ data = (R300_MEM_NUM_CHANNELS_MASK & temp);
+ if (data == 1) {
+ if (R300_MEM_USE_CD_CH_ONLY & temp) {
+ temp = INREG(R300_MC_IND_INDEX);
+ temp &= ~R300_MC_IND_ADDR_MASK;
+ temp |= R300_MC_READ_CNTL_CD_mcind;
+ OUTREG(R300_MC_IND_INDEX, temp);
+ temp = INREG(R300_MC_IND_DATA);
+ data = (R300_MEM_RBS_POSITION_C_MASK & temp);
+ } else {
+ temp = INREG(R300_MC_READ_CNTL_AB);
+ data = (R300_MEM_RBS_POSITION_A_MASK & temp);
+ }
+ } else {
+ temp = INREG(R300_MC_READ_CNTL_AB);
+ data = (R300_MEM_RBS_POSITION_A_MASK & temp);
+ }
+
+ mem_trbs = MemTrbs[data];
+ mem_tcas += mem_trbs;
+ }
+
+ if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
+ /* DDR64 SCLK_EFF = SCLK for analysis */
+ sclk_eff = info->sclk;
+ } else {
+#ifdef XF86DRI
+ if (info->directRenderingEnabled)
+ sclk_eff = info->sclk - (info->agpMode * 50.0 / 3.0);
+ else
+#endif
+ sclk_eff = info->sclk;
+ }
+
+ /* Find the memory controller latency for the display client.
+ */
+ if (IS_R300_VARIANT) {
+ /*not enough for R350 ???*/
+ /*
+ if (!mode2) sclk_delay = 150;
+ else {
+ if (info->RamWidth == 256) sclk_delay = 87;
+ else sclk_delay = 97;
+ }
+ */
+ sclk_delay = 250;
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_RV100) ||
+ info->IsIGP) {
+ if (info->IsDDR) sclk_delay = 41;
+ else sclk_delay = 33;
+ } else {
+ if (info->RamWidth == 128) sclk_delay = 57;
+ else sclk_delay = 41;
+ }
+ }
+
+ mc_latency_sclk = sclk_delay / sclk_eff;
+
+ if (info->IsDDR) {
+ if (info->RamWidth == 32) {
+ k1 = 40;
+ c = 3;
+ } else {
+ k1 = 20;
+ c = 1;
+ }
+ } else {
+ k1 = 40;
+ c = 3;
+ }
+ mc_latency_mclk = ((2.0*mem_trcd + mem_tcas*c + 4.0*mem_tras + 4.0*mem_trp + k1) /
+ info->mclk) + (4.0 / sclk_eff);
+
+ /*
+ HW cursor time assuming worst case of full size colour cursor.
+ */
+ cur_latency_mclk = (mem_trp + MAX(mem_tras, (mem_trcd + 2*(cur_size - (info->IsDDR+1))))) / info->mclk;
+ cur_latency_sclk = cur_size / sclk_eff;
+
+ /*
+ Find the total latency for the display data.
+ */
+ disp_latency_overhead = 8.0 / info->sclk;
+ mc_latency_mclk = mc_latency_mclk + disp_latency_overhead + cur_latency_mclk;
+ mc_latency_sclk = mc_latency_sclk + disp_latency_overhead + cur_latency_sclk;
+ disp_latency = MAX(mc_latency_mclk, mc_latency_sclk);
+
+ /*
+ Find the drain rate of the display buffer.
+ */
+ disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
+ if (pixel_bytes2)
+ disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
+ else
+ disp_drain_rate2 = 0;
+
+ /*
+ Find the critical point of the display buffer.
+ */
+ critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5);
+
+ /* ???? */
+ /*
+ temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
+ if (critical_point < temp) critical_point = temp;
+ */
+ if (info->DispPriority == 2) {
+ critical_point = 0;
+ }
+
+ /*
+ The critical point should never be above max_stop_req-4. Setting
+ GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
+ */
+ if (max_stop_req - critical_point < 4) critical_point = 0;
+
+ if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) {
+ /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
+ critical_point = 0x10;
+ }
+
+ temp = info->SavedReg->grph_buffer_cntl;
+ temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
+ temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
+ temp &= ~(RADEON_GRPH_START_REQ_MASK);
+ if ((info->ChipFamily == CHIP_FAMILY_R350) &&
+ (stop_req > 0x15)) {
+ stop_req -= 0x10;
+ }
+ temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
+
+ temp |= RADEON_GRPH_BUFFER_SIZE;
+ temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
+ RADEON_GRPH_CRITICAL_AT_SOF |
+ RADEON_GRPH_STOP_CNTL);
+ /*
+ Write the result into the register.
+ */
+ OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
+ (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "GRPH_BUFFER_CNTL from %x to %x\n",
+ (unsigned int)info->SavedReg->grph_buffer_cntl,
+ (unsigned int)INREG(RADEON_GRPH_BUFFER_CNTL));
+
+ if (mode2) {
+ stop_req = mode2->HDisplay * pixel_bytes2 / 16;
+
+ if (stop_req > max_stop_req) stop_req = max_stop_req;
+
+ temp = info->SavedReg->grph2_buffer_cntl;
+ temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
+ temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
+ temp &= ~(RADEON_GRPH_START_REQ_MASK);
+ if ((info->ChipFamily == CHIP_FAMILY_R350) &&
+ (stop_req > 0x15)) {
+ stop_req -= 0x10;
+ }
+ temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
+ temp |= RADEON_GRPH_BUFFER_SIZE;
+ temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
+ RADEON_GRPH_CRITICAL_AT_SOF |
+ RADEON_GRPH_STOP_CNTL);
+
+ if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
+ (info->ChipFamily == CHIP_FAMILY_RS200))
+ critical_point2 = 0;
+ else {
+ read_return_rate = MIN(info->sclk, info->mclk*(info->RamWidth*(info->IsDDR+1)/128));
+ time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate);
+
+ critical_point2 = (CARD32)((disp_latency + time_disp1_drop_priority +
+ disp_latency) * disp_drain_rate2 + 0.5);
+
+ if (info->DispPriority == 2) {
+ critical_point2 = 0;
+ }
+
+ if (max_stop_req - critical_point2 < 4) critical_point2 = 0;
+
+ }
+
+ if (critical_point2 == 0 && info->ChipFamily == CHIP_FAMILY_R300) {
+ /* some R300 cards have problem with this set to 0 */
+ critical_point2 = 0x10;
+ }
+
+ OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
+ (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
+
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "GRPH2_BUFFER_CNTL from %x to %x\n",
+ (unsigned int)info->SavedReg->grph2_buffer_cntl,
+ (unsigned int)INREG(RADEON_GRPH2_BUFFER_CNTL));
+ }
+}
+
+void
+RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ DisplayModePtr mode1, mode2;
+ int pixel_bytes2 = 0;
+
+ if (info->IsPrimary || info->IsSecondary)
+ mode1 = &xf86_config->crtc[0]->mode;
+ else
+ mode1 = info->CurrentLayout.mode;
+ mode2 = NULL;
+ pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+
+ if (xf86_config->num_crtc == 2) {
+ pixel_bytes2 = 0;
+ mode2 = NULL;
+
+ if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
+ pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+ mode1 = &xf86_config->crtc[0]->mode;
+ mode2 = &xf86_config->crtc[1]->mode;
+ } else if (xf86_config->crtc[0]->enabled) {
+ mode1 = &xf86_config->crtc[0]->mode;
+ } else if (xf86_config->crtc[1]->enabled) {
+ mode1 = &xf86_config->crtc[1]->mode;
+ } else
+ return;
+ } else {
+ if (xf86_config->crtc[0]->enabled)
+ mode1 = &xf86_config->crtc[0]->mode;
+ else
+ return;
+ }
+
+ RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
+}
+
+void
+legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode, int x, int y)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ Bool tilingOld = info->tilingEnabled;
+ int i = 0;
+ double dot_clock = 0;
+ int pll_flags = RADEON_PLL_LEGACY;
+ Bool update_tv_routing = FALSE;
+
+
+ if (info->allowColorTiling) {
+ info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+#ifdef XF86DRI
+ if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
+ RADEONSAREAPrivPtr pSAREAPriv;
+ if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed changing tiling status\n");
+ /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+ pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
+ info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
+ }
+#endif
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (output->crtc == crtc) {
+ if (radeon_output->MonType != MT_CRT)
+ pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
+ if (radeon_output->MonType == MT_LCD)
+ pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
+ }
+ }
+
+ if (info->IsMobility)
+ RADEONInitBIOSRegisters(pScrn, info->ModeReg);
+
+ ErrorF("init memmap\n");
+ RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
+ ErrorF("init common\n");
+ RADEONInitCommonRegisters(info->ModeReg, info);
+
+ RADEONInitSurfaceCntl(crtc, info->ModeReg);
+
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ ErrorF("init crtc1\n");
+ RADEONInitCrtcRegisters(crtc, info->ModeReg, adjusted_mode);
+ RADEONInitCrtcBase(crtc, info->ModeReg, x, y);
+ dot_clock = adjusted_mode->Clock / 1000.0;
+ if (dot_clock) {
+ ErrorF("init pll1\n");
+ RADEONInitPLLRegisters(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
+ } else {
+ info->ModeReg->ppll_ref_div = info->SavedReg->ppll_ref_div;
+ info->ModeReg->ppll_div_3 = info->SavedReg->ppll_div_3;
+ info->ModeReg->htotal_cntl = info->SavedReg->htotal_cntl;
+ }
+ break;
+ case 1:
+ ErrorF("init crtc2\n");
+ RADEONInitCrtc2Registers(crtc, info->ModeReg, adjusted_mode);
+ RADEONInitCrtc2Base(crtc, info->ModeReg, x, y);
+ dot_clock = adjusted_mode->Clock / 1000.0;
+ if (dot_clock) {
+ ErrorF("init pll2\n");
+ RADEONInitPLL2Registers(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
+ }
+ break;
+ }
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (output->crtc == crtc) {
+ if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ RADEONAdjustCrtcRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+ RADEONAdjustPLLRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+ update_tv_routing = TRUE;
+ break;
+ case 1:
+ RADEONAdjustCrtc2RegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+ RADEONAdjustPLL2RegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
+ break;
+ }
+ }
+ }
+ }
+
+ if (info->IsMobility)
+ RADEONRestoreBIOSRegisters(pScrn, info->ModeReg);
+
+ ErrorF("restore memmap\n");
+ RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
+ ErrorF("restore common\n");
+ RADEONRestoreCommonRegisters(pScrn, info->ModeReg);
+
+ switch (radeon_crtc->crtc_id) {
+ case 0:
+ ErrorF("restore crtc1\n");
+ RADEONRestoreCrtcRegisters(pScrn, info->ModeReg);
+ ErrorF("restore pll1\n");
+ RADEONRestorePLLRegisters(pScrn, info->ModeReg);
+ break;
+ case 1:
+ ErrorF("restore crtc2\n");
+ RADEONRestoreCrtc2Registers(pScrn, info->ModeReg);
+ ErrorF("restore pll2\n");
+ RADEONRestorePLL2Registers(pScrn, info->ModeReg);
+ break;
+ }
+
+ /* pixclks_cntl handles tv-out clock routing */
+ if (update_tv_routing)
+ radeon_update_tv_routing(pScrn, info->ModeReg);
+
+ if (info->DispPriority)
+ RADEONInitDispBandwidth(pScrn);
+
+ if (info->tilingEnabled != tilingOld) {
+ /* need to redraw front buffer, I guess this can be considered a hack ? */
+ /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+ if (pScrn->pScreen)
+ xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+ RADEONChangeSurfaces(pScrn);
+ if (pScrn->pScreen)
+ xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+ /* xf86SetRootClip would do, but can't access that here */
+ }
+
+ /* reset ecp_div for Xv */
+ info->ecp_div = -1;
+
+}
+
diff --git a/src/legacy_output.c b/src/legacy_output.c
new file mode 100644
index 0000000..6f55ae2
--- /dev/null
+++ b/src/legacy_output.c
@@ -0,0 +1,1577 @@
+/*
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ * VA Linux Systems Inc., Fremont, California.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_tv.h"
+#include "radeon_atombios.h"
+
+static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
+static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
+
+
+Bool
+RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch)
+{
+ if (!xf86I2CReadByte(dvo, addr, ch)) {
+ xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
+ "Unable to read from %s Slave %d.\n",
+ dvo->pI2CBus->BusName, dvo->SlaveAddr);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+Bool
+RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch)
+{
+ if (!xf86I2CWriteByte(dvo, addr, ch)) {
+ xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
+ "Unable to write to %s Slave %d.\n",
+ dvo->pI2CBus->BusName, dvo->SlaveAddr);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+I2CDevPtr
+RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ I2CDevPtr dvo;
+
+ dvo = xcalloc(1, sizeof(I2CDevRec));
+ if (dvo == NULL)
+ return NULL;
+
+ dvo->DevName = "RADEON DVO Controller";
+ dvo->SlaveAddr = addr;
+ dvo->pI2CBus = b;
+ dvo->StartTimeout = b->StartTimeout;
+ dvo->BitTimeout = b->BitTimeout;
+ dvo->AcknTimeout = b->AcknTimeout;
+ dvo->ByteTimeout = b->ByteTimeout;
+
+ if (xf86I2CDevInit(dvo)) {
+ return dvo;
+ }
+
+ xfree(dvo);
+ return NULL;
+}
+
+static void
+RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (!radeon_output->DVOChip)
+ return;
+
+ OUTREG(radeon_output->dvo_i2c_reg, INREG(radeon_output->dvo_i2c_reg) &
+ (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
+
+ if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
+ if (radeon_output->DVOChip) {
+ switch(info->ext_tmds_chip) {
+ case RADEON_SIL_164:
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
+ break;
+#if 0
+ /* needs work see bug 10418 */
+ case RADEON_SIL_1178:
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32);
+ RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ }
+}
+
+#if 0
+static RADEONMonitorType
+RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ int bConnected = 0;
+
+ /* the monitor either wasn't connected or it is a non-DDC CRT.
+ * try to probe it
+ */
+ if(IsCrtDac) {
+ unsigned long ulOrigVCLK_ECP_CNTL;
+ unsigned long ulOrigDAC_CNTL;
+ unsigned long ulOrigDAC_MACRO_CNTL;
+ unsigned long ulOrigDAC_EXT_CNTL;
+ unsigned long ulOrigCRTC_EXT_CNTL;
+ unsigned long ulData;
+ unsigned long ulMask;
+
+ ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+ ulData = ulOrigVCLK_ECP_CNTL;
+ ulData &= ~(RADEON_PIXCLK_ALWAYS_ONb
+ | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ ulMask = ~(RADEON_PIXCLK_ALWAYS_ONb
+ |RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+ ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
+ ulData = ulOrigCRTC_EXT_CNTL;
+ ulData |= RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
+
+ ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
+ ulData = ulOrigDAC_EXT_CNTL;
+ ulData &= ~RADEON_DAC_FORCE_DATA_MASK;
+ ulData |= (RADEON_DAC_FORCE_BLANK_OFF_EN
+ |RADEON_DAC_FORCE_DATA_EN
+ |RADEON_DAC_FORCE_DATA_SEL_MASK);
+ if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
+ (info->ChipFamily == CHIP_FAMILY_RV280))
+ ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, ulData);
+
+ /* turn on power so testing can go through */
+ ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
+ ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
+ OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
+
+ ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+ ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+ /* Enable comparators and set DAC range to PS2 (VGA) output level */
+ ulData = ulOrigDAC_CNTL;
+ ulData |= RADEON_DAC_CMP_EN;
+ ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
+ ulData |= 0x2;
+ OUTREG(RADEON_DAC_CNTL, ulData);
+
+ /* Settle down */
+ usleep(10000);
+
+ /* Read comparators */
+ ulData = INREG(RADEON_DAC_CNTL);
+ bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
+
+ /* Restore things */
+ ulData = ulOrigVCLK_ECP_CNTL;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL );
+ OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
+ OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
+
+ if (!bConnected) {
+ /* Power DAC down if CRT is not connected */
+ ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+ ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+ ulData = INREG(RADEON_DAC_CNTL);
+ ulData |= RADEON_DAC_PDWN;
+ OUTREG(RADEON_DAC_CNTL, ulData);
+ }
+ } else { /* TV DAC */
+
+ /* This doesn't seem to work reliably (maybe worse on some OEM cards),
+ for now we always return false. If one wants to connected a
+ non-DDC monitor on the DVI port when CRT port is also connected,
+ he will need to explicitly tell the driver in the config file
+ with Option MonitorLayout.
+ */
+ bConnected = FALSE;
+
+#if 0
+ if (info->ChipFamily == CHIP_FAMILY_R200) {
+ unsigned long ulOrigGPIO_MONID;
+ unsigned long ulOrigFP2_GEN_CNTL;
+ unsigned long ulOrigDISP_OUTPUT_CNTL;
+ unsigned long ulOrigCRTC2_GEN_CNTL;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
+ unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
+ unsigned long ulOrigCRTC2_H_TOTAL_DISP;
+ unsigned long ulOrigCRTC2_V_TOTAL_DISP;
+ unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
+ unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
+ unsigned long ulData, i;
+
+ ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
+ ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
+ ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
+ ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
+ ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+ ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+ ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+ ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+ ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+ ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+
+ ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+ ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+ ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ ulData = INREG(RADEON_GPIO_MONID);
+ ulData &= ~RADEON_GPIO_A_0;
+ OUTREG(RADEON_GPIO_MONID, ulData);
+
+ OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+ for (i = 0; i < 200; i++) {
+ ulData = INREG(RADEON_GPIO_MONID);
+ bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
+ if (!bConnected) break;
+
+ usleep(1000);
+ }
+
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
+ OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
+ OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
+ } else {
+ unsigned long ulOrigPIXCLKSDATA;
+ unsigned long ulOrigTV_MASTER_CNTL;
+ unsigned long ulOrigTV_DAC_CNTL;
+ unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
+ unsigned long ulOrigDAC_CNTL2;
+ unsigned long ulData;
+ unsigned long ulMask;
+
+ ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulData &= ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ ulMask = ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
+ ulData = ulOrigTV_MASTER_CNTL;
+ ulData &= ~RADEON_TVCLK_ALWAYS_ONb;
+ OUTREG(RADEON_TV_MASTER_CNTL, ulData);
+
+ ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
+ ulData = ulOrigDAC_CNTL2;
+ ulData &= ~RADEON_DAC2_DAC2_CLK_SEL;
+ OUTREG(RADEON_DAC_CNTL2, ulData);
+
+ ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
+
+ ulData = 0x00880213;
+ OUTREG(RADEON_TV_DAC_CNTL, ulData);
+
+ ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+ ulData = (RADEON_Y_RED_EN
+ | RADEON_C_GRN_EN
+ | RADEON_CMP_BLU_EN
+ | RADEON_RED_MX_FORCE_DAC_DATA
+ | RADEON_GRN_MX_FORCE_DAC_DATA
+ | RADEON_BLU_MX_FORCE_DAC_DATA);
+ if (IS_R300_VARIANT)
+ ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+ else
+ ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
+
+ usleep(10000);
+
+ ulData = INREG(RADEON_TV_DAC_CNTL);
+ bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
+ OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
+ OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
+ }
+#endif
+ return MT_UNKNOWN;
+ }
+
+ return(bConnected ? MT_CRT : MT_NONE);
+}
+#endif
+
+RADEONMonitorType
+legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ RADEONMonitorType found = MT_NONE;
+
+ if (OUTPUT_IS_TV) {
+ if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
+ if (radeon_output->type == OUTPUT_STV)
+ radeon_output->MonType = MT_STV;
+ else
+ radeon_output->MonType = MT_CTV;
+ } else {
+ if (info->InternalTVOut) {
+ if (radeon_output->load_detection)
+ radeon_output->MonType = radeon_detect_tv(pScrn);
+ else
+ radeon_output->MonType = MT_NONE;
+ }
+ }
+ } else {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ if (radeon_output->load_detection)
+ found = radeon_detect_primary_dac(pScrn, TRUE);
+ } else if (radeon_output->DACType == DAC_TVDAC) {
+ if (radeon_output->load_detection) {
+ if (info->ChipFamily == CHIP_FAMILY_R200)
+ found = radeon_detect_ext_dac(pScrn);
+ else
+ found = radeon_detect_tv_dac(pScrn, TRUE);
+ } else
+ found = MT_NONE;
+ }
+ }
+
+ return found;
+}
+
+/*
+ * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
+ *
+ */
+static void
+RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+
+ if (IsPrimaryDAC) {
+ CARD32 dac_cntl;
+ CARD32 dac_macro_cntl = 0;
+ dac_cntl = INREG(RADEON_DAC_CNTL);
+ dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+ if (IsOn) {
+ dac_cntl &= ~RADEON_DAC_PDWN;
+ dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
+ RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ } else {
+ dac_cntl |= RADEON_DAC_PDWN;
+ dac_macro_cntl |= (RADEON_DAC_PDWN_R |
+ RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+ }
+ OUTREG(RADEON_DAC_CNTL, dac_cntl);
+ OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+ } else {
+ CARD32 tv_dac_cntl;
+ CARD32 fp2_gen_cntl;
+
+ switch(info->ChipFamily)
+ {
+ case CHIP_FAMILY_R420:
+ case CHIP_FAMILY_RV410:
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ if (IsOn) {
+ tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_BDACPD |
+ RADEON_TV_DAC_BGSLEEP);
+ } else {
+ tv_dac_cntl |= (R420_TV_DAC_RDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_BDACPD |
+ RADEON_TV_DAC_BGSLEEP);
+ }
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+ break;
+ case CHIP_FAMILY_R200:
+ fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
+ if (IsOn) {
+ fp2_gen_cntl |= RADEON_FP2_DVO_EN;
+ } else {
+ fp2_gen_cntl &= ~RADEON_FP2_DVO_EN;
+ }
+ OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+ break;
+
+ default:
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ if (IsOn) {
+ tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD |
+ RADEON_TV_DAC_BDACPD |
+ RADEON_TV_DAC_BGSLEEP);
+ } else {
+ tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD |
+ RADEON_TV_DAC_BDACPD |
+ RADEON_TV_DAC_BGSLEEP);
+ }
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+ break;
+ }
+ }
+}
+
+/* This is to be used enable/disable displays dynamically */
+static void
+RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONSavePtr save = info->ModeReg;
+ unsigned char * RADEONMMIO = info->MMIO;
+ unsigned long tmp;
+ RADEONOutputPrivatePtr radeon_output;
+ int tv_dac_change = 0, o;
+ radeon_output = output->driver_private;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+ for (o = 0; o < xf86_config->num_output; o++) {
+ if (output == xf86_config->output[o]) {
+ break;
+ }
+ }
+
+ if (bEnable) {
+ ErrorF("enable montype: %d\n", radeon_output->MonType);
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ info->output_crt1 |= (1 << o);
+ tmp = INREG(RADEON_CRTC_EXT_CNTL);
+ tmp |= RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+ save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+ } else if (radeon_output->DACType == DAC_TVDAC) {
+ info->output_crt2 |= (1 << o);
+ if (info->ChipFamily == CHIP_FAMILY_R200) {
+ tmp = INREG(RADEON_FP2_GEN_CNTL);
+ tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+ save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ } else {
+ tmp = INREG(RADEON_CRTC2_GEN_CNTL);
+ tmp |= RADEON_CRTC2_CRT2_ON;
+ OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+ save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
+ }
+ tv_dac_change = 1;
+ }
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->TMDSType == TMDS_INT) {
+ info->output_dfp1 |= (1 << o);
+ tmp = INREG(RADEON_FP_GEN_CNTL);
+ tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ OUTREG(RADEON_FP_GEN_CNTL, tmp);
+ save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ } else if (radeon_output->TMDSType == TMDS_EXT) {
+ info->output_dfp2 |= (1 << o);
+ tmp = INREG(RADEON_FP2_GEN_CNTL);
+ tmp &= ~RADEON_FP2_BLANK_EN;
+ tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+ save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
+ }
+ } else if (radeon_output->MonType == MT_LCD) {
+ info->output_lcd1 |= (1 << o);
+ tmp = INREG(RADEON_LVDS_GEN_CNTL);
+ tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+ tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
+ usleep (radeon_output->PanelPwrDly * 1000);
+ OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+ save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+ save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
+ } else if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+ info->output_tv1 |= (1 << o);
+ tmp = INREG(RADEON_TV_MASTER_CNTL);
+ tmp |= RADEON_TV_ON;
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+ tv_dac_change = 2;
+ radeon_output->tv_on = TRUE;
+ }
+ } else {
+ ErrorF("disable montype: %d\n", radeon_output->MonType);
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ info->output_crt1 &= ~(1 << o);
+ if (!info->output_crt1) {
+ tmp = INREG(RADEON_CRTC_EXT_CNTL);
+ tmp &= ~RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+ save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+ }
+ } else if (radeon_output->DACType == DAC_TVDAC) {
+ info->output_crt2 &= ~(1 << o);
+ tv_dac_change = 1;
+ if (!info->output_crt2) {
+ if (info->ChipFamily == CHIP_FAMILY_R200) {
+ tmp = INREG(RADEON_FP2_GEN_CNTL);
+ tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+ save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ } else {
+ tmp = INREG(RADEON_CRTC2_GEN_CNTL);
+ tmp &= ~RADEON_CRTC2_CRT2_ON;
+ OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+ save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
+ }
+ }
+ }
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->TMDSType == TMDS_INT) {
+ info->output_dfp1 &= ~(1 << o);
+ if (!info->output_dfp1) {
+ tmp = INREG(RADEON_FP_GEN_CNTL);
+ tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ OUTREG(RADEON_FP_GEN_CNTL, tmp);
+ save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ }
+ } else if (radeon_output->TMDSType == TMDS_EXT) {
+ info->output_dfp2 &= ~(1 << o);
+ if (!info->output_dfp2) {
+ tmp = INREG(RADEON_FP2_GEN_CNTL);
+ tmp |= RADEON_FP2_BLANK_EN;
+ tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+ save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
+ }
+ }
+ } else if (radeon_output->MonType == MT_LCD) {
+ info->output_lcd1 &= ~(1 << o);
+ if (!info->output_lcd1) {
+ unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ if (info->IsMobility || info->IsIGP) {
+ /* Asic bug, when turning off LVDS_ON, we have to make sure
+ RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+ */
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+ }
+ tmp = INREG(RADEON_LVDS_GEN_CNTL);
+ tmp |= RADEON_LVDS_DISPLAY_DIS;
+ tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+ OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+ save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+ save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+ if (info->IsMobility || info->IsIGP) {
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ }
+ }
+ } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+ info->output_tv1 &= ~(1 << o);
+ tv_dac_change = 2;
+ if (!info->output_tv1) {
+ tmp = INREG(RADEON_TV_MASTER_CNTL);
+ tmp &= ~RADEON_TV_ON;
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+ radeon_output->tv_on = FALSE;
+ }
+ }
+ }
+
+ if (tv_dac_change) {
+ if (bEnable)
+ info->tv_dac_enable_mask |= tv_dac_change;
+ else
+ info->tv_dac_enable_mask &= ~tv_dac_change;
+
+ if (bEnable && info->tv_dac_enable_mask)
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+ else if (!bEnable && info->tv_dac_enable_mask == 0)
+ RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+
+ }
+}
+
+void
+legacy_output_dpms(xf86OutputPtr output, int mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ switch(mode) {
+ case DPMSModeOn:
+ RADEONEnableDisplay(output, TRUE);
+ break;
+ case DPMSModeOff:
+ case DPMSModeSuspend:
+ case DPMSModeStandby:
+ RADEONEnableDisplay(output, FALSE);
+ break;
+ }
+}
+
+static void
+RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int i;
+ CARD32 tmp = info->SavedReg->tmds_pll_cntl & 0xfffff;
+
+ for (i=0; i<4; i++) {
+ if (radeon_output->tmds_pll[i].freq == 0) break;
+ if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
+ tmp = radeon_output->tmds_pll[i].value ;
+ break;
+ }
+ }
+
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
+ if (tmp & 0xfff00000)
+ save->tmds_pll_cntl = tmp;
+ else {
+ save->tmds_pll_cntl = info->SavedReg->tmds_pll_cntl & 0xfff00000;
+ save->tmds_pll_cntl |= tmp;
+ }
+ } else save->tmds_pll_cntl = tmp;
+
+ save->tmds_transmitter_cntl = info->SavedReg->tmds_transmitter_cntl &
+ ~(RADEON_TMDS_TRANSMITTER_PLLRST);
+
+ if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
+ save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
+ else /* weird, RV chips got this bit reversed? */
+ save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
+
+ save->fp_gen_cntl = info->SavedReg->fp_gen_cntl |
+ (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
+ RADEON_FP_CRTC_DONT_SHADOW_HEND );
+
+ save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+
+ if (pScrn->rgbBits == 8)
+ save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
+ else
+ save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
+
+
+ if (IsPrimary) {
+ if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+ save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+ if (mode->Flags & RADEON_USE_RMX)
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
+ else
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
+ } else
+ save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
+ } else {
+ if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
+ save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
+ save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
+ } else
+ save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
+ }
+
+}
+
+static void
+RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+
+ if (pScrn->rgbBits == 8)
+ save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl |
+ RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
+ else
+ save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
+ ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
+
+ save->fp2_gen_cntl &= ~(RADEON_FP2_ON |
+ RADEON_FP2_DVO_EN |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+
+
+ /* XXX: these may be oem specific */
+ if (IS_R300_VARIANT) {
+ save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
+#if 0
+ if (mode->Clock > 165000)
+ save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;
+#endif
+ }
+
+ if (IsPrimary) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
+ if (mode->Flags & RADEON_USE_RMX)
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
+ } else {
+ save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
+ }
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+ } else {
+ save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
+ }
+ }
+
+}
+
+static void
+RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ save->lvds_pll_cntl = (info->SavedReg->lvds_pll_cntl |
+ RADEON_LVDS_PLL_EN);
+
+ save->lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
+
+ save->lvds_gen_cntl = info->SavedReg->lvds_gen_cntl;
+ save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+ save->lvds_gen_cntl &= ~(RADEON_LVDS_ON |
+ RADEON_LVDS_BLON |
+ RADEON_LVDS_EN |
+ RADEON_LVDS_RST_FM);
+
+ if (IS_R300_VARIANT)
+ save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
+
+ if (IsPrimary) {
+ if (IS_R300_VARIANT) {
+ if (mode->Flags & RADEON_USE_RMX)
+ save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
+ } else
+ save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
+ } else {
+ if (IS_R300_VARIANT) {
+ save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
+ } else
+ save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
+ }
+
+}
+
+static void
+RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ int xres = mode->HDisplay;
+ int yres = mode->VDisplay;
+ float Hratio, Vratio;
+
+ save->fp_vert_stretch = info->SavedReg->fp_vert_stretch &
+ RADEON_VERT_STRETCH_RESERVED;
+ save->fp_horz_stretch = info->SavedReg->fp_horz_stretch &
+ (RADEON_HORZ_FP_LOOP_STRETCH |
+ RADEON_HORZ_AUTO_RATIO_INC);
+
+ if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
+ return;
+
+ if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
+ Hratio = 1.0;
+ Vratio = 1.0;
+ } else {
+ if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
+ if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
+
+ Hratio = (float)xres/(float)radeon_output->PanelXRes;
+ Vratio = (float)yres/(float)radeon_output->PanelYRes;
+ }
+
+ if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
+ save->fp_horz_stretch |= ((xres/8-1)<<16);
+ } else {
+ save->fp_horz_stretch |= ((((unsigned long)
+ (Hratio * RADEON_HORZ_STRETCH_RATIO_MAX)) &
+ RADEON_HORZ_STRETCH_RATIO_MASK) |
+ RADEON_HORZ_STRETCH_BLEND |
+ RADEON_HORZ_STRETCH_ENABLE |
+ ((radeon_output->PanelXRes/8-1)<<16));
+ }
+
+ if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
+ save->fp_vert_stretch |= ((yres-1)<<12);
+ } else {
+ save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) &
+ RADEON_VERT_STRETCH_RATIO_MASK) |
+ RADEON_VERT_STRETCH_ENABLE |
+ RADEON_VERT_STRETCH_BLEND |
+ ((radeon_output->PanelYRes-1)<<12));
+ }
+
+}
+
+static void
+RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ if (IsPrimary) {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+ ~RADEON_DISP_DAC_SOURCE_MASK;
+ } else {
+ save->dac2_cntl = info->SavedReg->dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
+ }
+ } else {
+ if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+ ~RADEON_DISP_DAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
+ } else {
+ save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
+ }
+ }
+ save->dac_cntl = (RADEON_DAC_MASK_ALL
+ | RADEON_DAC_VGA_ADR_EN
+ | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
+
+ save->dac_macro_cntl = info->SavedReg->dac_macro_cntl;
+}
+
+static void
+RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (info->ChipFamily == CHIP_FAMILY_R420 ||
+ info->ChipFamily == CHIP_FAMILY_RV410) {
+ save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
+ ~(RADEON_TV_DAC_STD_MASK |
+ RADEON_TV_DAC_BGADJ_MASK |
+ R420_TV_DAC_DACADJ_MASK |
+ R420_TV_DAC_RDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_GDACPD |
+ R420_TV_DAC_TVENABLE);
+ } else {
+ save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
+ ~(RADEON_TV_DAC_STD_MASK |
+ RADEON_TV_DAC_BGADJ_MASK |
+ RADEON_TV_DAC_DACADJ_MASK |
+ RADEON_TV_DAC_RDACPD |
+ RADEON_TV_DAC_GDACPD |
+ RADEON_TV_DAC_GDACPD);
+ }
+
+ save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_DAC_STD_PS2 |
+ radeon_output->tv_dac_adj);
+
+}
+
+static void
+RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
+ DisplayModePtr mode, BOOL IsPrimary)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+
+ /*0x0028023;*/
+ RADEONInitTvDacCntl(output, save);
+
+ if (IS_R300_VARIANT)
+ save->gpiopad_a = info->SavedReg->gpiopad_a | 1;
+
+ save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+
+ if (IsPrimary) {
+ if (IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+ ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
+ } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+ save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
+ ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ } else {
+ save->disp_hw_debug = info->SavedReg->disp_hw_debug | RADEON_CRT2_DISP1_SEL;
+ }
+ } else {
+ if (IS_R300_VARIANT) {
+ save->disp_output_cntl = info->SavedReg->disp_output_cntl &
+ ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ } else if (info->ChipFamily == CHIP_FAMILY_R200) {
+ save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
+ ~(R200_FP2_SOURCE_SEL_MASK |
+ RADEON_FP2_DVO_RATE_SEL_SDR);
+ save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
+ } else {
+ save->disp_hw_debug = info->SavedReg->disp_hw_debug &
+ ~RADEON_CRT2_DISP1_SEL;
+ }
+ }
+}
+
+static void
+RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+ DisplayModePtr mode, xf86OutputPtr output,
+ int crtc_num)
+{
+ Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ if (crtc_num == 0)
+ RADEONInitRMXRegisters(output, save, mode);
+
+ if (radeon_output->MonType == MT_CRT) {
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ RADEONInitDACRegisters(output, save, mode, IsPrimary);
+ } else {
+ RADEONInitDAC2Registers(output, save, mode, IsPrimary);
+ }
+ } else if (radeon_output->MonType == MT_LCD) {
+ RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
+ } else if (radeon_output->MonType == MT_DFP) {
+ if (radeon_output->TMDSType == TMDS_INT) {
+ RADEONInitFPRegisters(output, save, mode, IsPrimary);
+ } else {
+ RADEONInitFP2Registers(output, save, mode, IsPrimary);
+ }
+ } else if (radeon_output->MonType == MT_STV ||
+ radeon_output->MonType == MT_CTV) {
+ RADEONInitTVRegisters(output, save, mode, IsPrimary);
+ }
+}
+
+void
+legacy_output_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+ DisplayModePtr adjusted_mode)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+ xf86CrtcPtr crtc = output->crtc;
+ RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+ RADEONInitOutputRegisters(pScrn, info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
+
+ if (radeon_crtc->crtc_id == 0)
+ RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
+
+ switch(radeon_output->MonType) {
+ case MT_LCD:
+ ErrorF("restore LVDS\n");
+ RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
+ break;
+ case MT_DFP:
+ if (radeon_output->TMDSType == TMDS_INT) {
+ ErrorF("restore FP\n");
+ RADEONRestoreFPRegisters(pScrn, info->ModeReg);
+ } else {
+ ErrorF("restore FP2\n");
+ if (info->IsAtomBios)
+ atombios_external_tmds_setup(output, mode);
+ else
+ RADEONRestoreDVOChip(pScrn, output);
+ RADEONRestoreFP2Registers(pScrn, info->ModeReg);
+ }
+ break;
+ case MT_STV:
+ case MT_CTV:
+ ErrorF("restore tv\n");
+ RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+ RADEONRestoreTVRegisters(pScrn, info->ModeReg);
+ break;
+ default:
+ ErrorF("restore dac\n");
+ RADEONRestoreDACRegisters(pScrn, info->ModeReg);
+ }
+
+}
+
+/* the following functions are based on the load detection code
+ * in the beos radeon driver by Thomas Kurschel and the existing
+ * load detection code in this driver.
+ */
+static RADEONMonitorType
+radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 vclk_ecp_cntl, crtc_ext_cntl;
+ CARD32 dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+ crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ dac_cntl = INREG(RADEON_DAC_CNTL);
+ dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+
+ tmp = vclk_ecp_cntl &
+ ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+
+ tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+
+ tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
+ RADEON_DAC_FORCE_DATA_EN;
+
+ if (color)
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+ else
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+ if (IS_R300_VARIANT)
+ tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+ tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
+ tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
+ OUTREG(RADEON_DAC_CNTL, tmp);
+
+ tmp &= ~(RADEON_DAC_PDWN_R |
+ RADEON_DAC_PDWN_G |
+ RADEON_DAC_PDWN_B);
+
+ OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
+
+ usleep(2000);
+
+ if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
+ found = MT_CRT;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Found %s CRT connected to primary DAC\n",
+ color ? "color" : "bw");
+ }
+
+ /* restore the regs we used */
+ OUTREG(RADEON_DAC_CNTL, dac_cntl);
+ OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+ OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
+
+ return found;
+}
+
+static RADEONMonitorType
+radeon_detect_ext_dac(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+ CARD32 disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
+ CARD32 disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
+ CARD32 tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+ CARD32 crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+ RADEONMonitorType found = MT_NONE;
+ int connected = 0;
+ int i = 0;
+
+ /* save the regs we need */
+ gpio_monid = INREG(RADEON_GPIO_MONID);
+ fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
+ disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+ disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+ disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+ disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+ disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+ disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+ crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+ crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+ crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+ crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+ tmp = INREG(RADEON_GPIO_MONID);
+ tmp &= ~RADEON_GPIO_A_0;
+ OUTREG(RADEON_GPIO_MONID, tmp);
+
+ OUTREG(RADEON_FP2_GEN_CNTL,
+ RADEON_FP2_ON |
+ RADEON_FP2_PANEL_FORMAT |
+ R200_FP2_SOURCE_SEL_TRANS_UNIT |
+ RADEON_FP2_DVO_EN |
+ R200_FP2_DVO_RATE_SEL_SDR);
+
+ OUTREG(RADEON_DISP_OUTPUT_CNTL,
+ RADEON_DISP_DAC_SOURCE_RMX |
+ RADEON_DISP_TRANS_MATRIX_GRAPHICS);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL,
+ RADEON_CRTC2_EN |
+ RADEON_CRTC2_DISP_REQ_EN_B);
+
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+ for (i = 0; i < 200; i++) {
+ tmp = INREG(RADEON_GPIO_MONID);
+ if (tmp & RADEON_GPIO_Y_0)
+ connected = 1;
+ else
+ connected = 0;
+
+ if (!connected)
+ break;
+
+ usleep(1000);
+ }
+
+ if (connected)
+ found = MT_CRT;
+
+ /* restore the regs we used */
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+ OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+ OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+ OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+ OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+ OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+ OUTREG(RADEON_GPIO_MONID, gpio_monid);
+
+ return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+ CARD32 disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
+ disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
+ disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+
+ tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
+ | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+
+ if (IS_R300_VARIANT) {
+ OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
+ }
+
+ tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
+ tmp |= RADEON_CRTC2_CRT2_ON |
+ (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+
+ if (IS_R300_VARIANT) {
+ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+ } else {
+ tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
+ OUTREG(RADEON_DISP_HW_DEBUG, tmp);
+ }
+
+ tmp = RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN |
+ RADEON_TV_DAC_STD_PS2;
+
+ OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+ tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
+ RADEON_DAC2_FORCE_DATA_EN;
+
+ if (color)
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+ else
+ tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+ if (IS_R300_VARIANT)
+ tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+ else
+ tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+ tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
+ OUTREG(RADEON_DAC_CNTL2, tmp);
+
+ usleep(10000);
+
+ if (IS_R300_VARIANT) {
+ if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
+ found = MT_CRT;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Found %s CRT connected to TV DAC\n",
+ color ? "color" : "bw");
+ }
+ } else {
+ if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
+ found = MT_CRT;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Found %s CRT connected to TV DAC\n",
+ color ? "color" : "bw");
+ }
+ }
+
+ /* restore regs we used */
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+
+ if (IS_R300_VARIANT) {
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
+ } else {
+ OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+ }
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
+
+ return found;
+}
+
+static RADEONMonitorType
+r300_detect_tv(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
+ CARD32 gpiopad_a, disp_output_cntl;
+ RADEONMonitorType found = MT_NONE;
+
+ /* save the regs we need */
+ gpiopad_a = INREG(RADEON_GPIOPAD_A);
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+ crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+ dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+
+ OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
+
+ OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
+
+ OUTREG(RADEON_CRTC2_GEN_CNTL,
+ RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
+
+ tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+ tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+
+ OUTREG(RADEON_DAC_EXT_CNTL,
+ RADEON_DAC2_FORCE_BLANK_OFF_EN |
+ RADEON_DAC2_FORCE_DATA_EN |
+ RADEON_DAC_FORCE_DATA_SEL_RGB |
+ (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
+
+ OUTREG(RADEON_TV_DAC_CNTL,
+ RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+ (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+ INREG(RADEON_TV_DAC_CNTL);
+
+ usleep(4000);
+
+ OUTREG(RADEON_TV_DAC_CNTL,
+ RADEON_TV_DAC_NBLANK |
+ RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN |
+ RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+ (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+ INREG(RADEON_TV_DAC_CNTL);
+
+ usleep(6000);
+
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
+ found = MT_STV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "S-Video TV connection detected\n");
+ } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
+ found = MT_CTV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Composite TV connection detected\n" );
+ }
+
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
+ OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+ OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+ OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+ OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+
+ return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv(ScrnInfoPtr pScrn)
+{
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char *RADEONMMIO = info->MMIO;
+ CARD32 tmp, dac_cntl2, tv_master_cntl;
+ CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
+ RADEONMonitorType found = MT_NONE;
+
+ if (IS_R300_VARIANT)
+ return r300_detect_tv(pScrn);
+
+ /* save the regs we need */
+ dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+ tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+ tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+ config_cntl = INREG(RADEON_CONFIG_CNTL);
+ tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+ tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
+ OUTREG(RADEON_DAC_CNTL2, tmp);
+
+ tmp = tv_master_cntl | RADEON_TV_ON;
+ tmp &= ~(RADEON_TV_ASYNC_RST |
+ RADEON_RESTART_PHASE_FIX |
+ RADEON_CRT_FIFO_CE_EN |
+ RADEON_TV_FIFO_CE_EN |
+ RADEON_RE_SYNC_NOW_SEL_MASK);
+ tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
+
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+
+ tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
+ RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
+ (8 << RADEON_TV_DAC_BGADJ_SHIFT);
+
+ if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
+ tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
+ else
+ tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
+
+ OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+ tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
+ RADEON_RED_MX_FORCE_DAC_DATA |
+ RADEON_GRN_MX_FORCE_DAC_DATA |
+ RADEON_BLU_MX_FORCE_DAC_DATA |
+ (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
+
+ usleep(3000);
+
+ tmp = INREG(RADEON_TV_DAC_CNTL);
+ if (tmp & RADEON_TV_DAC_GDACDET) {
+ found = MT_STV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "S-Video TV connection detected\n");
+ } else if (tmp & RADEON_TV_DAC_BDACDET) {
+ found = MT_CTV;
+ xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+ "Composite TV connection detected\n" );
+ }
+
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
+ OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+ OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+ OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+
+ return found;
+}
+
+/* disable all ouputs before enabling the ones we want */
+void
+RADEONDisableDisplays(ScrnInfoPtr pScrn) {
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ unsigned char * RADEONMMIO = info->MMIO;
+ unsigned long tmp, tmpPixclksCntl;
+
+
+ /* primary DAC */
+ tmp = INREG(RADEON_CRTC_EXT_CNTL);
+ tmp &= ~RADEON_CRTC_CRT_ON;
+ OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+ RADEONDacPowerSet(pScrn, FALSE, TRUE);
+
+ /* Secondary DAC */
+ if (info->ChipFamily == CHIP_FAMILY_R200) {
+ tmp = INREG(RADEON_FP2_GEN_CNTL);
+ tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+ } else {
+ tmp = INREG(RADEON_CRTC2_GEN_CNTL);
+ tmp &= ~RADEON_CRTC2_CRT2_ON;
+ OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+ }
+ RADEONDacPowerSet(pScrn, FALSE, FALSE);
+
+ /* turn off tv-out */
+ if (info->InternalTVOut) {
+ tmp = INREG(RADEON_TV_MASTER_CNTL);
+ tmp &= ~RADEON_TV_ON;
+ OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+ }
+
+ /* FP 1 */
+ tmp = INREG(RADEON_FP_GEN_CNTL);
+ tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
+ OUTREG(RADEON_FP_GEN_CNTL, tmp);
+
+ /* FP 2 */
+ tmp = INREG(RADEON_FP2_GEN_CNTL);
+ tmp |= RADEON_FP2_BLANK_EN;
+ tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
+ OUTREG(RADEON_FP2_GEN_CNTL, tmp);
+
+ /* LVDS */
+ if (info->IsMobility) {
+ tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+ if (info->IsMobility || info->IsIGP) {
+ /* Asic bug, when turning off LVDS_ON, we have to make sure
+ RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+ */
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+ }
+ tmp = INREG(RADEON_LVDS_GEN_CNTL);
+ tmp |= RADEON_LVDS_DISPLAY_DIS;
+ tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
+ OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+ if (info->IsMobility || info->IsIGP) {
+ OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+ }
+ }
+
+}
diff --git a/src/radeon.h b/src/radeon.h
index 7f4d001..47e1b89 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -842,13 +842,10 @@ extern void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,
RADEONInfoPtr info);
extern void RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
extern Bool RADEONI2cInit(ScrnInfoPtr pScrn);
-extern void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
extern Bool RADEONSetupConnectors(ScrnInfoPtr pScrn);
extern void RADEONPrintPortMap(ScrnInfoPtr pScrn);
-extern void RADEONEnableDisplay(xf86OutputPtr pPort, BOOL bEnable);
extern void RADEONDisableDisplays(ScrnInfoPtr pScrn);
extern void RADEONGetPanelInfo(ScrnInfoPtr pScrn);
-extern void RADEONGetTVDacAdjInfo(xf86OutputPtr output);
extern void RADEONUnblank(ScrnInfoPtr pScrn);
extern void RADEONUnblank(ScrnInfoPtr pScrn);
extern void RADEONBlank(ScrnInfoPtr pScrn);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 8e66518..9034cf5 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -53,68 +53,27 @@
#include "sarea.h"
#endif
-void radeon_crtc_load_lut(xf86CrtcPtr crtc);
-
extern void atombios_crtc_mode_set(xf86CrtcPtr crtc,
DisplayModePtr mode,
DisplayModePtr adjusted_mode,
int x, int y);
+extern void legacy_crtc_mode_set(xf86CrtcPtr crtc,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode,
+ int x, int y);
extern void atombios_crtc_dpms(xf86CrtcPtr crtc, int mode);
+extern void legacy_crtc_dpms(xf86CrtcPtr crtc, int mode);
static void
radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
- int mask;
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
+ RADEONInfoPtr info = RADEONPTR(crtc->scrn);
if (IS_AVIVO_VARIANT) {
atombios_crtc_dpms(crtc, mode);
- return;
- }
-
- mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
-
-
- switch(mode) {
- case DPMSModeOn:
- if (radeon_crtc->crtc_id) {
- OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
- } else {
- OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
- OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
- }
- break;
- case DPMSModeStandby:
- if (radeon_crtc->crtc_id) {
- OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
- } else {
- OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
- OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
- }
- break;
- case DPMSModeSuspend:
- if (radeon_crtc->crtc_id) {
- OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
- } else {
- OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
- OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
- }
- break;
- case DPMSModeOff:
- if (radeon_crtc->crtc_id) {
- OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
- } else {
- OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B);
- OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
- }
- break;
+ } else {
+ legacy_crtc_dpms(crtc, mode);
}
-
- if (mode != DPMSModeOff)
- radeon_crtc_load_lut(crtc);
}
static Bool
@@ -133,491 +92,6 @@ radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
radeon_crtc_dpms(crtc, DPMSModeOff);
}
-/* Define common registers for requested video mode */
-static void
-RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
-{
- save->ovr_clr = 0;
- save->ovr_wid_left_right = 0;
- save->ovr_wid_top_bottom = 0;
- save->ov0_scale_cntl = 0;
- save->subpic_cntl = 0;
- save->viph_control = 0;
- save->i2c_cntl_1 = 0;
- save->rbbm_soft_reset = 0;
- save->cap0_trig_cntl = 0;
- save->cap1_trig_cntl = 0;
- save->bus_cntl = info->BusCntl;
- /*
- * If bursts are enabled, turn on discards
- * Radeon doesn't have write bursts
- */
- if (save->bus_cntl & (RADEON_BUS_READ_BURST))
- save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
-}
-
-static void
-RADEONInitSurfaceCntl(xf86CrtcPtr crtc, RADEONSavePtr save)
-{
- save->surface_cntl = 0;
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
- /* We must set both apertures as they can be both used to map the entire
- * video memory. -BenH.
- */
- switch (crtc->scrn->bitsPerPixel) {
- case 16:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_16BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_16BPP;
- break;
-
- case 32:
- save->surface_cntl |= RADEON_NONSURF_AP0_SWP_32BPP;
- save->surface_cntl |= RADEON_NONSURF_AP1_SWP_32BPP;
- break;
- }
-#endif
-
-}
-
-Bool
-RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
- int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int Base;
-#ifdef XF86DRI
- RADEONSAREAPrivPtr pSAREAPriv;
- XF86DRISAREAPtr pSAREA;
-#endif
-
- save->crtc_offset = pScrn->fbOffset;
-#ifdef XF86DRI
- if (info->allowPageFlip)
- save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
- else
-#endif
- save->crtc_offset_cntl = 0;
-
- if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
- if (IS_R300_VARIANT)
- save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc_offset_cntl |= RADEON_CRTC_TILE_EN;
- }
- else {
- if (IS_R300_VARIANT)
- save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
- }
-
- Base = pScrn->fbOffset;
-
- if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
- if (IS_R300_VARIANT) {
- /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
- * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
- * Makes tiling MUCH easier.
- */
- save->crtc_tile_x0_y0 = x | (y << 16);
- Base &= ~0x7ff;
- } else {
- /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
- drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
- flickering when scrolling vertically in a virtual screen, possibly because crtc will
- pick up the new offset value at the end of each scanline, but the new offset_cntl value
- only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
- OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
- /*save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL) & ~0xf;*/
-#if 0
- /* try to get rid of flickering when scrolling at least for 2d */
-#ifdef XF86DRI
- if (!info->have3DWindows)
-#endif
- save->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-
- int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
- /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
- int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
- Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
- save->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
- }
- }
- else {
- int offset = y * info->CurrentLayout.displayWidth + x;
- switch (info->CurrentLayout.pixel_code) {
- case 15:
- case 16: offset *= 2; break;
- case 24: offset *= 3; break;
- case 32: offset *= 4; break;
- }
- Base += offset;
- }
-
- if (crtc->rotatedData != NULL) {
- Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
- }
-
- Base &= ~7; /* 3 lower bits are always 0 */
-
-
-#ifdef XF86DRI
- if (info->directRenderingInited) {
- /* note cannot use pScrn->pScreen since this is unitialized when called from
- RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
- /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
- *** pageflipping!
- ***/
- pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
- /* can't get at sarea in a semi-sane way? */
- pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
-
- pSAREA->frame.x = (Base / info->CurrentLayout.pixel_bytes)
- % info->CurrentLayout.displayWidth;
- pSAREA->frame.y = (Base / info->CurrentLayout.pixel_bytes)
- / info->CurrentLayout.displayWidth;
- pSAREA->frame.width = pScrn->frameX1 - x + 1;
- pSAREA->frame.height = pScrn->frameY1 - y + 1;
-
- if (pSAREAPriv->pfCurrentPage == 1) {
- Base += info->backOffset - info->frontOffset;
- }
- }
-#endif
- save->crtc_offset = Base;
-
- return TRUE;
-
-}
-
-/* Define CRTC registers for requested video mode */
-Bool
-RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
- DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int format;
- int hsync_start;
- int hsync_wid;
- int vsync_wid;
-
- switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; break;
- case 8: format = 2; break;
- case 15: format = 3; break; /* 555 */
- case 16: format = 4; break; /* 565 */
- case 24: format = 5; break; /* RGB */
- case 32: format = 6; break; /* xRGB */
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unsupported pixel depth (%d)\n",
- info->CurrentLayout.bitsPerPixel);
- return FALSE;
- }
-
- /*save->bios_4_scratch = info->SavedReg->bios_4_scratch;*/
- save->crtc_gen_cntl = (RADEON_CRTC_EXT_DISP_EN
- | RADEON_CRTC_EN
- | (format << 8)
- | ((mode->Flags & V_DBLSCAN)
- ? RADEON_CRTC_DBL_SCAN_EN
- : 0)
- | ((mode->Flags & V_CSYNC)
- ? RADEON_CRTC_CSYNC_EN
- : 0)
- | ((mode->Flags & V_INTERLACE)
- ? RADEON_CRTC_INTERLACE_EN
- : 0));
-
- save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
- RADEON_CRTC_VSYNC_DIS |
- RADEON_CRTC_HSYNC_DIS |
- RADEON_CRTC_DISPLAY_DIS);
-
- save->disp_merge_cntl = info->SavedReg->disp_merge_cntl;
- save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
-
- save->crtc_more_cntl = 0;
- if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200)) {
- /* This is to workaround the asic bug for RMX, some versions
- of BIOS dosen't have this register initialized correctly.
- */
- save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
- }
-
- save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
- | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
- << 16));
-
- hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
- if (!hsync_wid) hsync_wid = 1;
- hsync_start = mode->CrtcHSyncStart - 8;
-
- save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
- | ((hsync_wid & 0x3f) << 16)
- | ((mode->Flags & V_NHSYNC)
- ? RADEON_CRTC_H_SYNC_POL
- : 0));
-
- /* This works for double scan mode. */
- save->crtc_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
- | ((mode->CrtcVDisplay - 1) << 16));
-
- vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
- if (!vsync_wid) vsync_wid = 1;
-
- save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
- | ((vsync_wid & 0x1f) << 16)
- | ((mode->Flags & V_NVSYNC)
- ? RADEON_CRTC_V_SYNC_POL
- : 0));
-
- save->crtc_pitch = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
- ((pScrn->bitsPerPixel * 8) -1)) /
- (pScrn->bitsPerPixel * 8));
- save->crtc_pitch |= save->crtc_pitch << 16;
-
- save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
- save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
- save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
- save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
-
- if (info->IsDellServer) {
- save->dac2_cntl = info->SavedReg->dac2_cntl;
- save->tv_dac_cntl = info->SavedReg->tv_dac_cntl;
- save->crtc2_gen_cntl = info->SavedReg->crtc2_gen_cntl;
- save->disp_hw_debug = info->SavedReg->disp_hw_debug;
-
- save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
- save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
-
- /* For CRT on DAC2, don't turn it on if BIOS didn't
- enable it, even it's detected.
- */
- save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
- save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
- save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
- }
-
- return TRUE;
-}
-
-Bool
-RADEONInitCrtc2Base(xf86CrtcPtr crtc, RADEONSavePtr save,
- int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int Base;
-#ifdef XF86DRI
- RADEONSAREAPrivPtr pSAREAPriv;
- XF86DRISAREAPtr pSAREA;
-#endif
-
- /* It seems all fancy options apart from pflip can be safely disabled
- */
- save->crtc2_offset = pScrn->fbOffset;
-#ifdef XF86DRI
- if (info->allowPageFlip)
- save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
- else
-#endif
- save->crtc2_offset_cntl = 0;
-
- if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
- if (IS_R300_VARIANT)
- save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
- }
- else {
- if (IS_R300_VARIANT)
- save->crtc2_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
- R300_CRTC_MICRO_TILE_BUFFER_DIS |
- R300_CRTC_MACRO_TILE_EN);
- else
- save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
- }
-
- Base = pScrn->fbOffset;
-
- if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
- if (IS_R300_VARIANT) {
- /* On r300/r400 when tiling is enabled crtc_offset is set to the address of
- * the surface. the x/y offsets are handled by the X_Y tile reg for each crtc
- * Makes tiling MUCH easier.
- */
- save->crtc2_tile_x0_y0 = x | (y << 16);
- Base &= ~0x7ff;
- } else {
- /* note we cannot really simply use the info->ModeReg.crtc_offset_cntl value, since the
- drm might have set FLIP_CNTL since we wrote that. Unfortunately FLIP_CNTL causes
- flickering when scrolling vertically in a virtual screen, possibly because crtc will
- pick up the new offset value at the end of each scanline, but the new offset_cntl value
- only after a vsync. We'd probably need to wait (in drm) for vsync and only then update
- OFFSET and OFFSET_CNTL, if the y coord has changed. Seems hard to fix. */
- /*save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL) & ~0xf;*/
-#if 0
- /* try to get rid of flickering when scrolling at least for 2d */
-#ifdef XF86DRI
- if (!info->have3DWindows)
-#endif
- save->crtc2_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-
- int byteshift = info->CurrentLayout.bitsPerPixel >> 4;
- /* crtc uses 256(bytes)x8 "half-tile" start addresses? */
- int tile_addr = (((y >> 3) * info->CurrentLayout.displayWidth + x) >> (8 - byteshift)) << 11;
- Base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
- save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
- }
- }
- else {
- int offset = y * info->CurrentLayout.displayWidth + x;
- switch (info->CurrentLayout.pixel_code) {
- case 15:
- case 16: offset *= 2; break;
- case 24: offset *= 3; break;
- case 32: offset *= 4; break;
- }
- Base += offset;
- }
-
- if (crtc->rotatedData != NULL) {
- Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
- }
-
- Base &= ~7; /* 3 lower bits are always 0 */
-
-#ifdef XF86DRI
- if (info->directRenderingInited) {
- /* note cannot use pScrn->pScreen since this is unitialized when called from
- RADEONScreenInit, and we need to call from there to get mergedfb + pageflip working */
- /*** NOTE: r3/4xx will need sarea and drm pageflip updates to handle the xytile regs for
- *** pageflipping!
- ***/
- pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
- /* can't get at sarea in a semi-sane way? */
- pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
-
- pSAREAPriv->crtc2_base = Base;
-
- if (pSAREAPriv->pfCurrentPage == 1) {
- Base += info->backOffset - info->frontOffset;
- }
- }
-#endif
- save->crtc2_offset = Base;
-
- return TRUE;
-}
-
-/* Define CRTC2 registers for requested video mode */
-Bool
-RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
- DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- int format;
- int hsync_start;
- int hsync_wid;
- int vsync_wid;
-
- switch (info->CurrentLayout.pixel_code) {
- case 4: format = 1; break;
- case 8: format = 2; break;
- case 15: format = 3; break; /* 555 */
- case 16: format = 4; break; /* 565 */
- case 24: format = 5; break; /* RGB */
- case 32: format = 6; break; /* xRGB */
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unsupported pixel depth (%d)\n",
- info->CurrentLayout.bitsPerPixel);
- return FALSE;
- }
-
- save->crtc2_h_total_disp =
- ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
- | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff) << 16));
-
- hsync_wid = (mode->CrtcHSyncEnd - mode->CrtcHSyncStart) / 8;
- if (!hsync_wid) hsync_wid = 1;
- hsync_start = mode->CrtcHSyncStart - 8;
-
- save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
- | ((hsync_wid & 0x3f) << 16)
- | ((mode->Flags & V_NHSYNC)
- ? RADEON_CRTC_H_SYNC_POL
- : 0));
-
- /* This works for double scan mode. */
- save->crtc2_v_total_disp = (((mode->CrtcVTotal - 1) & 0xffff)
- | ((mode->CrtcVDisplay - 1) << 16));
-
- vsync_wid = mode->CrtcVSyncEnd - mode->CrtcVSyncStart;
- if (!vsync_wid) vsync_wid = 1;
-
- save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
- | ((vsync_wid & 0x1f) << 16)
- | ((mode->Flags & V_NVSYNC)
- ? RADEON_CRTC2_V_SYNC_POL
- : 0));
-
- save->crtc2_pitch = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
- ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
- save->crtc2_pitch |= save->crtc2_pitch << 16;
-
- /* check to see if TV DAC is enabled for another crtc and keep it enabled */
- if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
- save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
- else
- save->crtc2_gen_cntl = 0;
-
- save->crtc2_gen_cntl |= (RADEON_CRTC2_EN
- | (format << 8)
- | RADEON_CRTC2_VSYNC_DIS
- | RADEON_CRTC2_HSYNC_DIS
- | RADEON_CRTC2_DISP_DIS
- | ((mode->Flags & V_DBLSCAN)
- ? RADEON_CRTC2_DBL_SCAN_EN
- : 0)
- | ((mode->Flags & V_CSYNC)
- ? RADEON_CRTC2_CSYNC_EN
- : 0)
- | ((mode->Flags & V_INTERLACE)
- ? RADEON_CRTC2_INTERLACE_EN
- : 0));
-
- save->disp2_merge_cntl = info->SavedReg->disp2_merge_cntl;
- save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
-
- save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
- save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
-
- if (info->ChipFamily == CHIP_FAMILY_RS400) {
- save->rs480_unk_e30 = 0x105DC1CC; /* because I'm worth it */
- save->rs480_unk_e34 = 0x2749D000; /* AMD really should */
- save->rs480_unk_e38 = 0x29ca71dc; /* release docs */
- save->rs480_unk_e3c = 0x28FBC3AC; /* this is so a trade secret */
- }
-
- return TRUE;
-}
-
-
static CARD32 RADEONDiv(CARD64 n, CARD32 d)
{
return (n + (d / 2)) / d;
@@ -716,333 +190,6 @@ RADEONComputePLL(RADEONPLLPtr pll,
}
-/* Define PLL registers for requested video mode */
-static void
-RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- RADEONPLLPtr pll, DisplayModePtr mode,
- int flags)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD32 feedback_div = 0;
- CARD32 reference_div = 0;
- CARD32 post_divider = 0;
- CARD32 freq = 0;
-
- struct {
- int divider;
- int bitvalue;
- } *post_div, post_divs[] = {
- /* From RAGE 128 VR/RAGE 128 GL Register
- * Reference Manual (Technical Reference
- * Manual P/N RRG-G04100-C Rev. 0.04), page
- * 3-17 (PLL_DIV_[3:0]).
- */
- { 1, 0 }, /* VCLK_SRC */
- { 2, 1 }, /* VCLK_SRC/2 */
- { 4, 2 }, /* VCLK_SRC/4 */
- { 8, 3 }, /* VCLK_SRC/8 */
- { 3, 4 }, /* VCLK_SRC/3 */
- { 16, 5 }, /* VCLK_SRC/16 */
- { 6, 6 }, /* VCLK_SRC/6 */
- { 12, 7 }, /* VCLK_SRC/12 */
- { 0, 0 }
- };
-
-
- if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
- save->ppll_ref_div = info->RefDivider;
- save->ppll_div_3 = info->FeedbackDivider | (info->PostDivider << 16);
- save->htotal_cntl = 0;
- return;
- }
-
- RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
-
- for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
- if (post_div->divider == post_divider)
- break;
- }
-
- if (!post_div->divider) {
- save->pll_output_freq = freq;
- post_div = &post_divs[0];
- }
-
- save->dot_clock_freq = freq;
- save->feedback_div = feedback_div;
- save->reference_div = reference_div;
- save->post_div = post_divider;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
- (unsigned)save->dot_clock_freq,
- (unsigned)save->pll_output_freq,
- save->feedback_div,
- save->reference_div,
- save->post_div);
-
- save->ppll_ref_div = save->reference_div;
-
-#if defined(__powerpc__)
- /* apparently programming this otherwise causes a hang??? */
- if (info->MacModel == RADEON_MAC_IBOOK)
- save->ppll_div_3 = 0x000600ad;
- else
-#endif
- save->ppll_div_3 = (save->feedback_div | (post_div->bitvalue << 16));
-
- save->htotal_cntl = mode->HTotal & 0x7;
-
- save->vclk_ecp_cntl = (info->SavedReg->vclk_ecp_cntl &
- ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
-}
-
-/* Define PLL2 registers for requested video mode */
-static void
-RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
- RADEONPLLPtr pll, DisplayModePtr mode,
- int flags)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- CARD32 feedback_div = 0;
- CARD32 reference_div = 0;
- CARD32 post_divider = 0;
- CARD32 freq = 0;
-
- struct {
- int divider;
- int bitvalue;
- } *post_div, post_divs[] = {
- /* From RAGE 128 VR/RAGE 128 GL Register
- * Reference Manual (Technical Reference
- * Manual P/N RRG-G04100-C Rev. 0.04), page
- * 3-17 (PLL_DIV_[3:0]).
- */
- { 1, 0 }, /* VCLK_SRC */
- { 2, 1 }, /* VCLK_SRC/2 */
- { 4, 2 }, /* VCLK_SRC/4 */
- { 8, 3 }, /* VCLK_SRC/8 */
- { 3, 4 }, /* VCLK_SRC/3 */
- { 6, 6 }, /* VCLK_SRC/6 */
- { 12, 7 }, /* VCLK_SRC/12 */
- { 0, 0 }
- };
-
- if ((flags & RADEON_PLL_USE_BIOS_DIVS) && info->UseBiosDividers) {
- save->p2pll_ref_div = info->RefDivider;
- save->p2pll_div_0 = info->FeedbackDivider | (info->PostDivider << 16);
- save->htotal_cntl2 = 0;
- return;
- }
-
- RADEONComputePLL(pll, mode->Clock, &freq, &feedback_div, &reference_div, &post_divider, flags);
-
- for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
- if (post_div->divider == post_divider)
- break;
- }
-
- if (!post_div->divider) {
- save->pll_output_freq_2 = freq;
- post_div = &post_divs[0];
- }
-
- save->dot_clock_freq_2 = freq;
- save->feedback_div_2 = feedback_div;
- save->reference_div_2 = reference_div;
- save->post_div_2 = post_divider;
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "dc=%u, of=%u, fd=%d, rd=%d, pd=%d\n",
- (unsigned)save->dot_clock_freq_2,
- (unsigned)save->pll_output_freq_2,
- save->feedback_div_2,
- save->reference_div_2,
- save->post_div_2);
-
- save->p2pll_ref_div = save->reference_div_2;
-
- save->p2pll_div_0 = (save->feedback_div_2 |
- (post_div->bitvalue << 16));
-
- save->htotal_cntl2 = mode->HTotal & 0x7;
-
- save->pixclks_cntl = ((info->SavedReg->pixclks_cntl &
- ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
- RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
-}
-
-static void
-RADEONInitBIOSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- /* tell the bios not to muck with the hardware on events */
- save->bios_4_scratch = 0x4; /* 0x4 needed for backlight */
- save->bios_5_scratch = (info->SavedReg->bios_5_scratch & 0xff) | 0xff00; /* bits 0-3 keep backlight level */
- save->bios_6_scratch = info->SavedReg->bios_6_scratch | 0x40000000;
-
-}
-
-static void
-radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
- /* pixclks_cntl controls tv clock routing */
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
-}
-
-static void
-legacy_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
- DisplayModePtr adjusted_mode, int x, int y)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- Bool tilingOld = info->tilingEnabled;
- int i = 0;
- double dot_clock = 0;
- int pll_flags = RADEON_PLL_LEGACY;
- Bool update_tv_routing = FALSE;
-
-
- if (info->allowColorTiling) {
- info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
-#ifdef XF86DRI
- if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
- RADEONSAREAPrivPtr pSAREAPriv;
- if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed changing tiling status\n");
- /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
- pSAREAPriv = DRIGetSAREAPrivate(screenInfo.screens[pScrn->scrnIndex]);
- info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
- }
-#endif
- }
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (output->crtc == crtc) {
- if (radeon_output->MonType != MT_CRT)
- pll_flags |= RADEON_PLL_NO_ODD_POST_DIV;
- if (radeon_output->MonType == MT_LCD)
- pll_flags |= (RADEON_PLL_USE_BIOS_DIVS | RADEON_PLL_USE_REF_DIV);
- }
- }
-
- if (info->IsMobility)
- RADEONInitBIOSRegisters(pScrn, info->ModeReg);
-
- ErrorF("init memmap\n");
- RADEONInitMemMapRegisters(pScrn, info->ModeReg, info);
- ErrorF("init common\n");
- RADEONInitCommonRegisters(info->ModeReg, info);
-
- RADEONInitSurfaceCntl(crtc, info->ModeReg);
-
- switch (radeon_crtc->crtc_id) {
- case 0:
- ErrorF("init crtc1\n");
- RADEONInitCrtcRegisters(crtc, info->ModeReg, adjusted_mode);
- RADEONInitCrtcBase(crtc, info->ModeReg, x, y);
- dot_clock = adjusted_mode->Clock / 1000.0;
- if (dot_clock) {
- ErrorF("init pll1\n");
- RADEONInitPLLRegisters(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
- } else {
- info->ModeReg->ppll_ref_div = info->SavedReg->ppll_ref_div;
- info->ModeReg->ppll_div_3 = info->SavedReg->ppll_div_3;
- info->ModeReg->htotal_cntl = info->SavedReg->htotal_cntl;
- }
- break;
- case 1:
- ErrorF("init crtc2\n");
- RADEONInitCrtc2Registers(crtc, info->ModeReg, adjusted_mode);
- RADEONInitCrtc2Base(crtc, info->ModeReg, x, y);
- dot_clock = adjusted_mode->Clock / 1000.0;
- if (dot_clock) {
- ErrorF("init pll2\n");
- RADEONInitPLL2Registers(pScrn, info->ModeReg, &info->pll, adjusted_mode, pll_flags);
- }
- break;
- }
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (output->crtc == crtc) {
- if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
- switch (radeon_crtc->crtc_id) {
- case 0:
- RADEONAdjustCrtcRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
- RADEONAdjustPLLRegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
- update_tv_routing = TRUE;
- break;
- case 1:
- RADEONAdjustCrtc2RegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
- RADEONAdjustPLL2RegistersForTV(pScrn, info->ModeReg, adjusted_mode, output);
- break;
- }
- }
- }
- }
-
- if (info->IsMobility)
- RADEONRestoreBIOSRegisters(pScrn, info->ModeReg);
-
- ErrorF("restore memmap\n");
- RADEONRestoreMemMapRegisters(pScrn, info->ModeReg);
- ErrorF("restore common\n");
- RADEONRestoreCommonRegisters(pScrn, info->ModeReg);
-
- switch (radeon_crtc->crtc_id) {
- case 0:
- ErrorF("restore crtc1\n");
- RADEONRestoreCrtcRegisters(pScrn, info->ModeReg);
- ErrorF("restore pll1\n");
- /*if (info->IsAtomBios)
- atombios_crtc_set_pll(crtc, adjusted_mode);
- else*/
- RADEONRestorePLLRegisters(pScrn, info->ModeReg);
- break;
- case 1:
- ErrorF("restore crtc2\n");
- RADEONRestoreCrtc2Registers(pScrn, info->ModeReg);
- ErrorF("restore pll2\n");
- /*if (info->IsAtomBios)
- atombios_crtc_set_pll(crtc, adjusted_mode);
- else*/
- RADEONRestorePLL2Registers(pScrn, info->ModeReg);
- break;
- }
-
- /* pixclks_cntl handles tv-out clock routing */
- if (update_tv_routing)
- radeon_update_tv_routing(pScrn, info->ModeReg);
-
- if (info->DispPriority)
- RADEONInitDispBandwidth(pScrn);
-
- if (info->tilingEnabled != tilingOld) {
- /* need to redraw front buffer, I guess this can be considered a hack ? */
- /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
- if (pScrn->pScreen)
- xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
- RADEONChangeSurfaces(pScrn);
- if (pScrn->pScreen)
- xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
- /* xf86SetRootClip would do, but can't access that here */
- }
-
- /* reset ecp_div for Xv */
- info->ecp_div = -1;
-
-}
-
static void
radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode, int x, int y)
@@ -1066,7 +213,8 @@ radeon_crtc_mode_commit(xf86CrtcPtr crtc)
radeon_crtc_dpms(crtc, DPMSModeOn);
}
-void radeon_crtc_load_lut(xf86CrtcPtr crtc)
+void
+radeon_crtc_load_lut(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
@@ -1499,3 +647,47 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
return pMode;
}
+void
+RADEONBlank(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output;
+ xf86CrtcPtr crtc;
+ int o, c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ crtc = xf86_config->crtc[c];
+ for (o = 0; o < xf86_config->num_output; o++) {
+ output = xf86_config->output[o];
+ if (output->crtc != crtc)
+ continue;
+
+ output->funcs->dpms(output, DPMSModeOff);
+ }
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+ }
+}
+
+void
+RADEONUnblank(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output;
+ xf86CrtcPtr crtc;
+ int o, c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ crtc = xf86_config->crtc[c];
+ if(!crtc->enabled)
+ continue;
+ crtc->funcs->dpms(crtc, DPMSModeOn);
+ for (o = 0; o < xf86_config->num_output; o++) {
+ output = xf86_config->output[o];
+ if (output->crtc != crtc)
+ continue;
+
+ output->funcs->dpms(output, DPMSModeOn);
+ }
+ }
+}
+
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 2043f24..1c529cf 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -48,27 +48,6 @@
extern int getRADEONEntityIndex(void);
-static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
-{
- 0x00000000, /* unknown */
- 0x00000000, /* legacy */
- 0x00000000, /* r100 */
- 0x00280000, /* rv100 */
- 0x00000000, /* rs100 */
- 0x00880000, /* rv200 */
- 0x00000000, /* rs200 */
- 0x00000000, /* r200 */
- 0x00770000, /* rv250 */
- 0x00290000, /* rs300 */
- 0x00560000, /* rv280 */
- 0x00780000, /* r300 */
- 0x00770000, /* r350 */
- 0x00780000, /* rv350 */
- 0x00780000, /* rv380 */
- 0x01080000, /* r420 */
- 0x01080000, /* rv410 */ /* FIXME: just values from r420 used... */
- 0x00780000, /* rs400 */ /* FIXME: just values from rv380 used... */
-};
void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
{
@@ -157,722 +136,3 @@ void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
mon->nVrefresh = i;
}
}
-
-void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- /* Todo: get this setting from BIOS */
- radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
- if (info->IsMobility) { /* some mobility chips may different */
- if (info->ChipFamily == CHIP_FAMILY_RV250)
- radeon_output->tv_dac_adj = 0x00880000;
- }
-}
-
-/*
- * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
- *
- */
-static void RADEONDacPowerSet(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- if (IsPrimaryDAC) {
- CARD32 dac_cntl;
- CARD32 dac_macro_cntl = 0;
- dac_cntl = INREG(RADEON_DAC_CNTL);
- dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
- if (IsOn) {
- dac_cntl &= ~RADEON_DAC_PDWN;
- dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
- RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- } else {
- dac_cntl |= RADEON_DAC_PDWN;
- dac_macro_cntl |= (RADEON_DAC_PDWN_R |
- RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- }
- OUTREG(RADEON_DAC_CNTL, dac_cntl);
- OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
- } else {
- CARD32 tv_dac_cntl;
- CARD32 fp2_gen_cntl;
-
- switch(info->ChipFamily)
- {
- case CHIP_FAMILY_R420:
- case CHIP_FAMILY_RV410:
- tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- if (IsOn) {
- tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_BDACPD |
- RADEON_TV_DAC_BGSLEEP);
- } else {
- tv_dac_cntl |= (R420_TV_DAC_RDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_BDACPD |
- RADEON_TV_DAC_BGSLEEP);
- }
- OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
- break;
- case CHIP_FAMILY_R200:
- fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
- if (IsOn) {
- fp2_gen_cntl |= RADEON_FP2_DVO_EN;
- } else {
- fp2_gen_cntl &= ~RADEON_FP2_DVO_EN;
- }
- OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
- break;
-
- default:
- tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- if (IsOn) {
- tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
- RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_BDACPD |
- RADEON_TV_DAC_BGSLEEP);
- } else {
- tv_dac_cntl |= (RADEON_TV_DAC_RDACPD |
- RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_BDACPD |
- RADEON_TV_DAC_BGSLEEP);
- }
- OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
- break;
- }
- }
-}
-
-/* disable all ouputs before enabling the ones we want */
-void RADEONDisableDisplays(ScrnInfoPtr pScrn) {
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char * RADEONMMIO = info->MMIO;
- unsigned long tmp, tmpPixclksCntl;
-
-
- /* primary DAC */
- tmp = INREG(RADEON_CRTC_EXT_CNTL);
- tmp &= ~RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
- RADEONDacPowerSet(pScrn, FALSE, TRUE);
-
- /* Secondary DAC */
- if (info->ChipFamily == CHIP_FAMILY_R200) {
- tmp = INREG(RADEON_FP2_GEN_CNTL);
- tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- OUTREG(RADEON_FP2_GEN_CNTL, tmp);
- } else {
- tmp = INREG(RADEON_CRTC2_GEN_CNTL);
- tmp &= ~RADEON_CRTC2_CRT2_ON;
- OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
- }
- RADEONDacPowerSet(pScrn, FALSE, FALSE);
-
- /* turn off tv-out */
- if (info->InternalTVOut) {
- tmp = INREG(RADEON_TV_MASTER_CNTL);
- tmp &= ~RADEON_TV_ON;
- OUTREG(RADEON_TV_MASTER_CNTL, tmp);
- }
-
- /* FP 1 */
- tmp = INREG(RADEON_FP_GEN_CNTL);
- tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- OUTREG(RADEON_FP_GEN_CNTL, tmp);
-
- /* FP 2 */
- tmp = INREG(RADEON_FP2_GEN_CNTL);
- tmp |= RADEON_FP2_BLANK_EN;
- tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- OUTREG(RADEON_FP2_GEN_CNTL, tmp);
-
- /* LVDS */
- if (info->IsMobility) {
- tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- if (info->IsMobility || info->IsIGP) {
- /* Asic bug, when turning off LVDS_ON, we have to make sure
- RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
- */
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
- }
- tmp = INREG(RADEON_LVDS_GEN_CNTL);
- tmp |= RADEON_LVDS_DISPLAY_DIS;
- tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
- OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
- if (info->IsMobility || info->IsIGP) {
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
- }
- }
-
-}
-
-/* This is to be used enable/disable displays dynamically */
-void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONSavePtr save = info->ModeReg;
- unsigned char * RADEONMMIO = info->MMIO;
- unsigned long tmp;
- RADEONOutputPrivatePtr radeon_output;
- int tv_dac_change = 0, o;
- radeon_output = output->driver_private;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-
- for (o = 0; o < xf86_config->num_output; o++) {
- if (output == xf86_config->output[o]) {
- break;
- }
- }
-
- if (bEnable) {
- ErrorF("enable montype: %d\n", radeon_output->MonType);
- if (radeon_output->MonType == MT_CRT) {
- if (radeon_output->DACType == DAC_PRIMARY) {
- info->output_crt1 |= (1 << o);
- tmp = INREG(RADEON_CRTC_EXT_CNTL);
- tmp |= RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
- save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
- RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
- } else if (radeon_output->DACType == DAC_TVDAC) {
- info->output_crt2 |= (1 << o);
- if (info->ChipFamily == CHIP_FAMILY_R200) {
- tmp = INREG(RADEON_FP2_GEN_CNTL);
- tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- OUTREG(RADEON_FP2_GEN_CNTL, tmp);
- save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- } else {
- tmp = INREG(RADEON_CRTC2_GEN_CNTL);
- tmp |= RADEON_CRTC2_CRT2_ON;
- OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
- save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
- }
- tv_dac_change = 1;
- }
- } else if (radeon_output->MonType == MT_DFP) {
- if (radeon_output->TMDSType == TMDS_INT) {
- info->output_dfp1 |= (1 << o);
- tmp = INREG(RADEON_FP_GEN_CNTL);
- tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- OUTREG(RADEON_FP_GEN_CNTL, tmp);
- save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- } else if (radeon_output->TMDSType == TMDS_EXT) {
- info->output_dfp2 |= (1 << o);
- tmp = INREG(RADEON_FP2_GEN_CNTL);
- tmp &= ~RADEON_FP2_BLANK_EN;
- tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- OUTREG(RADEON_FP2_GEN_CNTL, tmp);
- save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- save->fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN;
- }
- } else if (radeon_output->MonType == MT_LCD) {
- info->output_lcd1 |= (1 << o);
- tmp = INREG(RADEON_LVDS_GEN_CNTL);
- tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
- tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
- usleep (radeon_output->PanelPwrDly * 1000);
- OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
- save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
- save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
- } else if (radeon_output->MonType == MT_STV ||
- radeon_output->MonType == MT_CTV) {
- info->output_tv1 |= (1 << o);
- tmp = INREG(RADEON_TV_MASTER_CNTL);
- tmp |= RADEON_TV_ON;
- OUTREG(RADEON_TV_MASTER_CNTL, tmp);
- tv_dac_change = 2;
- radeon_output->tv_on = TRUE;
- }
- } else {
- ErrorF("disable montype: %d\n", radeon_output->MonType);
- if (radeon_output->MonType == MT_CRT) {
- if (radeon_output->DACType == DAC_PRIMARY) {
- info->output_crt1 &= ~(1 << o);
- if (!info->output_crt1) {
- tmp = INREG(RADEON_CRTC_EXT_CNTL);
- tmp &= ~RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
- save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
- RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
- }
- } else if (radeon_output->DACType == DAC_TVDAC) {
- info->output_crt2 &= ~(1 << o);
- tv_dac_change = 1;
- if (!info->output_crt2) {
- if (info->ChipFamily == CHIP_FAMILY_R200) {
- tmp = INREG(RADEON_FP2_GEN_CNTL);
- tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- OUTREG(RADEON_FP2_GEN_CNTL, tmp);
- save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- } else {
- tmp = INREG(RADEON_CRTC2_GEN_CNTL);
- tmp &= ~RADEON_CRTC2_CRT2_ON;
- OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
- save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
- }
- }
- }
- } else if (radeon_output->MonType == MT_DFP) {
- if (radeon_output->TMDSType == TMDS_INT) {
- info->output_dfp1 &= ~(1 << o);
- if (!info->output_dfp1) {
- tmp = INREG(RADEON_FP_GEN_CNTL);
- tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- OUTREG(RADEON_FP_GEN_CNTL, tmp);
- save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
- }
- } else if (radeon_output->TMDSType == TMDS_EXT) {
- info->output_dfp2 &= ~(1 << o);
- if (!info->output_dfp2) {
- tmp = INREG(RADEON_FP2_GEN_CNTL);
- tmp |= RADEON_FP2_BLANK_EN;
- tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- OUTREG(RADEON_FP2_GEN_CNTL, tmp);
- save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
- save->fp2_gen_cntl |= RADEON_FP2_BLANK_EN;
- }
- }
- } else if (radeon_output->MonType == MT_LCD) {
- info->output_lcd1 &= ~(1 << o);
- if (!info->output_lcd1) {
- unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- if (info->IsMobility || info->IsIGP) {
- /* Asic bug, when turning off LVDS_ON, we have to make sure
- RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
- */
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
- }
- tmp = INREG(RADEON_LVDS_GEN_CNTL);
- tmp |= RADEON_LVDS_DISPLAY_DIS;
- tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
- OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
- save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
- save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN);
- if (info->IsMobility || info->IsIGP) {
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
- }
- }
- } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
- info->output_tv1 &= ~(1 << o);
- tv_dac_change = 2;
- if (!info->output_tv1) {
- tmp = INREG(RADEON_TV_MASTER_CNTL);
- tmp &= ~RADEON_TV_ON;
- OUTREG(RADEON_TV_MASTER_CNTL, tmp);
- radeon_output->tv_on = FALSE;
- }
- }
- }
-
- if (tv_dac_change) {
- if (bEnable)
- info->tv_dac_enable_mask |= tv_dac_change;
- else
- info->tv_dac_enable_mask &= ~tv_dac_change;
-
- if (bEnable && info->tv_dac_enable_mask)
- RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
- else if (!bEnable && info->tv_dac_enable_mask == 0)
- RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-
- }
-}
-
-/* Calculate display buffer watermark to prevent buffer underflow */
-void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
-{
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
-
- CARD32 temp, data, mem_trcd, mem_trp, mem_tras, mem_trbs=0;
- float mem_tcas;
- int k1, c;
- CARD32 MemTrcdExtMemCntl[4] = {1, 2, 3, 4};
- CARD32 MemTrpExtMemCntl[4] = {1, 2, 3, 4};
- CARD32 MemTrasExtMemCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8};
-
- CARD32 MemTrcdMemTimingCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8};
- CARD32 MemTrpMemTimingCntl[8] = {1, 2, 3, 4, 5, 6, 7, 8};
- CARD32 MemTrasMemTimingCntl[16] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
-
- float MemTcas[8] = {0, 1, 2, 3, 0, 1.5, 2.5, 0};
- float MemTcas2[8] = {0, 1, 2, 3, 4, 5, 6, 7};
- float MemTrbs[8] = {1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5};
-
- float mem_bw, peak_disp_bw;
- float min_mem_eff = 0.8;
- float sclk_eff, sclk_delay;
- float mc_latency_mclk, mc_latency_sclk, cur_latency_mclk, cur_latency_sclk;
- float disp_latency, disp_latency_overhead, disp_drain_rate, disp_drain_rate2;
- float pix_clk, pix_clk2; /* in MHz */
- int cur_size = 16; /* in octawords */
- int critical_point, critical_point2;
- int stop_req, max_stop_req;
- float read_return_rate, time_disp1_drop_priority;
-
- /*
- * Set display0/1 priority up on r3/4xx in the memory controller for
- * high res modes if the user specifies HIGH for displaypriority
- * option.
- */
- if ((info->DispPriority == 2) && IS_R300_VARIANT) {
- CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
- if (pRADEONEnt->pCrtc[1]->enabled) {
- mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
- } else {
- mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
- }
- OUTREG(R300_MC_INIT_MISC_LAT_TIMER, mc_init_misc_lat_timer);
- }
-
-
- /* R420 and RV410 family not supported yet */
- if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return;
-
- /*
- * Determine if there is enough bandwidth for current display mode
- */
- mem_bw = info->mclk * (info->RamWidth / 8) * (info->IsDDR ? 2 : 1);
-
- pix_clk = mode1->Clock/1000.0;
- if (mode2)
- pix_clk2 = mode2->Clock/1000.0;
- else
- pix_clk2 = 0;
-
- peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
- if (pixel_bytes2)
- peak_disp_bw += (pix_clk2 * pixel_bytes2);
-
- if (peak_disp_bw >= mem_bw * min_mem_eff) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "You may not have enough display bandwidth for current mode\n"
- "If you have flickering problem, try to lower resolution, refresh rate, or color depth\n");
- }
-
- /* CRTC1
- Set GRPH_BUFFER_CNTL register using h/w defined optimal values.
- GRPH_STOP_REQ <= MIN[ 0x7C, (CRTC_H_DISP + 1) * (bit depth) / 0x10 ]
- */
- stop_req = mode1->HDisplay * info->CurrentLayout.pixel_bytes / 16;
-
- /* setup Max GRPH_STOP_REQ default value */
- if (IS_RV100_VARIANT)
- max_stop_req = 0x5c;
- else
- max_stop_req = 0x7c;
- if (stop_req > max_stop_req)
- stop_req = max_stop_req;
-
- /* Get values from the EXT_MEM_CNTL register...converting its contents. */
- temp = INREG(RADEON_MEM_TIMING_CNTL);
- if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
- mem_trcd = MemTrcdExtMemCntl[(temp & 0x0c) >> 2];
- mem_trp = MemTrpExtMemCntl[ (temp & 0x03) >> 0];
- mem_tras = MemTrasExtMemCntl[(temp & 0x70) >> 4];
- } else { /* RV200 and later */
- mem_trcd = MemTrcdMemTimingCntl[(temp & 0x07) >> 0];
- mem_trp = MemTrpMemTimingCntl[ (temp & 0x700) >> 8];
- mem_tras = MemTrasMemTimingCntl[(temp & 0xf000) >> 12];
- }
-
- /* Get values from the MEM_SDRAM_MODE_REG register...converting its */
- temp = INREG(RADEON_MEM_SDRAM_MODE_REG);
- data = (temp & (7<<20)) >> 20;
- if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
- mem_tcas = MemTcas [data];
- } else {
- mem_tcas = MemTcas2 [data];
- }
-
- if (IS_R300_VARIANT) {
-
- /* on the R300, Tcas is included in Trbs.
- */
- temp = INREG(RADEON_MEM_CNTL);
- data = (R300_MEM_NUM_CHANNELS_MASK & temp);
- if (data == 1) {
- if (R300_MEM_USE_CD_CH_ONLY & temp) {
- temp = INREG(R300_MC_IND_INDEX);
- temp &= ~R300_MC_IND_ADDR_MASK;
- temp |= R300_MC_READ_CNTL_CD_mcind;
- OUTREG(R300_MC_IND_INDEX, temp);
- temp = INREG(R300_MC_IND_DATA);
- data = (R300_MEM_RBS_POSITION_C_MASK & temp);
- } else {
- temp = INREG(R300_MC_READ_CNTL_AB);
- data = (R300_MEM_RBS_POSITION_A_MASK & temp);
- }
- } else {
- temp = INREG(R300_MC_READ_CNTL_AB);
- data = (R300_MEM_RBS_POSITION_A_MASK & temp);
- }
-
- mem_trbs = MemTrbs[data];
- mem_tcas += mem_trbs;
- }
-
- if ((info->ChipFamily == CHIP_FAMILY_RV100) || info->IsIGP) { /* RV100, M6, IGPs */
- /* DDR64 SCLK_EFF = SCLK for analysis */
- sclk_eff = info->sclk;
- } else {
-#ifdef XF86DRI
- if (info->directRenderingEnabled)
- sclk_eff = info->sclk - (info->agpMode * 50.0 / 3.0);
- else
-#endif
- sclk_eff = info->sclk;
- }
-
- /* Find the memory controller latency for the display client.
- */
- if (IS_R300_VARIANT) {
- /*not enough for R350 ???*/
- /*
- if (!mode2) sclk_delay = 150;
- else {
- if (info->RamWidth == 256) sclk_delay = 87;
- else sclk_delay = 97;
- }
- */
- sclk_delay = 250;
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_RV100) ||
- info->IsIGP) {
- if (info->IsDDR) sclk_delay = 41;
- else sclk_delay = 33;
- } else {
- if (info->RamWidth == 128) sclk_delay = 57;
- else sclk_delay = 41;
- }
- }
-
- mc_latency_sclk = sclk_delay / sclk_eff;
-
- if (info->IsDDR) {
- if (info->RamWidth == 32) {
- k1 = 40;
- c = 3;
- } else {
- k1 = 20;
- c = 1;
- }
- } else {
- k1 = 40;
- c = 3;
- }
- mc_latency_mclk = ((2.0*mem_trcd + mem_tcas*c + 4.0*mem_tras + 4.0*mem_trp + k1) /
- info->mclk) + (4.0 / sclk_eff);
-
- /*
- HW cursor time assuming worst case of full size colour cursor.
- */
- cur_latency_mclk = (mem_trp + MAX(mem_tras, (mem_trcd + 2*(cur_size - (info->IsDDR+1))))) / info->mclk;
- cur_latency_sclk = cur_size / sclk_eff;
-
- /*
- Find the total latency for the display data.
- */
- disp_latency_overhead = 8.0 / info->sclk;
- mc_latency_mclk = mc_latency_mclk + disp_latency_overhead + cur_latency_mclk;
- mc_latency_sclk = mc_latency_sclk + disp_latency_overhead + cur_latency_sclk;
- disp_latency = MAX(mc_latency_mclk, mc_latency_sclk);
-
- /*
- Find the drain rate of the display buffer.
- */
- disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
- if (pixel_bytes2)
- disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
- else
- disp_drain_rate2 = 0;
-
- /*
- Find the critical point of the display buffer.
- */
- critical_point= (CARD32)(disp_drain_rate * disp_latency + 0.5);
-
- /* ???? */
- /*
- temp = (info->SavedReg.grph_buffer_cntl & RADEON_GRPH_CRITICAL_POINT_MASK) >> RADEON_GRPH_CRITICAL_POINT_SHIFT;
- if (critical_point < temp) critical_point = temp;
- */
- if (info->DispPriority == 2) {
- critical_point = 0;
- }
-
- /*
- The critical point should never be above max_stop_req-4. Setting
- GRPH_CRITICAL_CNTL = 0 will thus force high priority all the time.
- */
- if (max_stop_req - critical_point < 4) critical_point = 0;
-
- if (critical_point == 0 && mode2 && info->ChipFamily == CHIP_FAMILY_R300) {
- /* some R300 cards have problem with this set to 0, when CRTC2 is enabled.*/
- critical_point = 0x10;
- }
-
- temp = info->SavedReg->grph_buffer_cntl;
- temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
- temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
- temp &= ~(RADEON_GRPH_START_REQ_MASK);
- if ((info->ChipFamily == CHIP_FAMILY_R350) &&
- (stop_req > 0x15)) {
- stop_req -= 0x10;
- }
- temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
-
- temp |= RADEON_GRPH_BUFFER_SIZE;
- temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
- RADEON_GRPH_CRITICAL_AT_SOF |
- RADEON_GRPH_STOP_CNTL);
- /*
- Write the result into the register.
- */
- OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
- (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "GRPH_BUFFER_CNTL from %x to %x\n",
- (unsigned int)info->SavedReg->grph_buffer_cntl,
- (unsigned int)INREG(RADEON_GRPH_BUFFER_CNTL));
-
- if (mode2) {
- stop_req = mode2->HDisplay * pixel_bytes2 / 16;
-
- if (stop_req > max_stop_req) stop_req = max_stop_req;
-
- temp = info->SavedReg->grph2_buffer_cntl;
- temp &= ~(RADEON_GRPH_STOP_REQ_MASK);
- temp |= (stop_req << RADEON_GRPH_STOP_REQ_SHIFT);
- temp &= ~(RADEON_GRPH_START_REQ_MASK);
- if ((info->ChipFamily == CHIP_FAMILY_R350) &&
- (stop_req > 0x15)) {
- stop_req -= 0x10;
- }
- temp |= (stop_req << RADEON_GRPH_START_REQ_SHIFT);
- temp |= RADEON_GRPH_BUFFER_SIZE;
- temp &= ~(RADEON_GRPH_CRITICAL_CNTL |
- RADEON_GRPH_CRITICAL_AT_SOF |
- RADEON_GRPH_STOP_CNTL);
-
- if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
- (info->ChipFamily == CHIP_FAMILY_RS200))
- critical_point2 = 0;
- else {
- read_return_rate = MIN(info->sclk, info->mclk*(info->RamWidth*(info->IsDDR+1)/128));
- time_disp1_drop_priority = critical_point / (read_return_rate - disp_drain_rate);
-
- critical_point2 = (CARD32)((disp_latency + time_disp1_drop_priority +
- disp_latency) * disp_drain_rate2 + 0.5);
-
- if (info->DispPriority == 2) {
- critical_point2 = 0;
- }
-
- if (max_stop_req - critical_point2 < 4) critical_point2 = 0;
-
- }
-
- if (critical_point2 == 0 && info->ChipFamily == CHIP_FAMILY_R300) {
- /* some R300 cards have problem with this set to 0 */
- critical_point2 = 0x10;
- }
-
- OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
- (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
-
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
- "GRPH2_BUFFER_CNTL from %x to %x\n",
- (unsigned int)info->SavedReg->grph2_buffer_cntl,
- (unsigned int)INREG(RADEON_GRPH2_BUFFER_CNTL));
- }
-}
-
-void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- DisplayModePtr mode1, mode2;
- int pixel_bytes2 = 0;
-
- if (info->IsPrimary || info->IsSecondary)
- mode1 = &xf86_config->crtc[0]->mode;
- else
- mode1 = info->CurrentLayout.mode;
- mode2 = NULL;
- pixel_bytes2 = info->CurrentLayout.pixel_bytes;
-
- if (xf86_config->num_crtc == 2) {
- pixel_bytes2 = 0;
- mode2 = NULL;
-
- if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
- pixel_bytes2 = info->CurrentLayout.pixel_bytes;
- mode1 = &xf86_config->crtc[0]->mode;
- mode2 = &xf86_config->crtc[1]->mode;
- } else if (xf86_config->crtc[0]->enabled) {
- mode1 = &xf86_config->crtc[0]->mode;
- } else if (xf86_config->crtc[1]->enabled) {
- mode1 = &xf86_config->crtc[1]->mode;
- } else
- return;
- } else {
- if (xf86_config->crtc[0]->enabled)
- mode1 = &xf86_config->crtc[0]->mode;
- else
- return;
- }
-
- RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
-}
-
-void RADEONBlank(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86OutputPtr output;
- xf86CrtcPtr crtc;
- int o, c;
-
- for (c = 0; c < xf86_config->num_crtc; c++) {
- crtc = xf86_config->crtc[c];
- for (o = 0; o < xf86_config->num_output; o++) {
- output = xf86_config->output[o];
- if (output->crtc != crtc)
- continue;
-
- output->funcs->dpms(output, DPMSModeOff);
- }
- crtc->funcs->dpms(crtc, DPMSModeOff);
- }
-}
-
-void RADEONUnblank(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86OutputPtr output;
- xf86CrtcPtr crtc;
- int o, c;
-
- for (c = 0; c < xf86_config->num_crtc; c++) {
- crtc = xf86_config->crtc[c];
- if(!crtc->enabled)
- continue;
- crtc->funcs->dpms(crtc, DPMSModeOn);
- for (o = 0; o < xf86_config->num_output; o++) {
- output = xf86_config->output[o];
- if (output->crtc != crtc)
- continue;
-
- output->funcs->dpms(output, DPMSModeOn);
- }
- }
-}
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 30a73ab..2346932 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -136,12 +136,31 @@ static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
{{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
};
+static const CARD32 default_tvdac_adj [CHIP_FAMILY_LAST] =
+{
+ 0x00000000, /* unknown */
+ 0x00000000, /* legacy */
+ 0x00000000, /* r100 */
+ 0x00280000, /* rv100 */
+ 0x00000000, /* rs100 */
+ 0x00880000, /* rv200 */
+ 0x00000000, /* rs200 */
+ 0x00000000, /* r200 */
+ 0x00770000, /* rv250 */
+ 0x00290000, /* rs300 */
+ 0x00560000, /* rv280 */
+ 0x00780000, /* r300 */
+ 0x00770000, /* r350 */
+ 0x00780000, /* rv350 */
+ 0x00780000, /* rv380 */
+ 0x01080000, /* r420 */
+ 0x01080000, /* rv410 */ /* FIXME: just values from r420 used... */
+ 0x00780000, /* rs400 */ /* FIXME: just values from rv380 used... */
+};
+
+
static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
static void RADEONUpdatePanelSize(xf86OutputPtr output);
-static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
-static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
-static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
-static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
#define AVIVO_I2C_DISABLE 0
#define AVIVO_I2C_ENABLE 1
@@ -150,102 +169,15 @@ static Bool AVIVOI2CDoLock(ScrnInfoPtr pScrn, int lock_state, int gpio);
extern void atombios_output_mode_set(xf86OutputPtr output,
DisplayModePtr mode,
DisplayModePtr adjusted_mode);
+extern void legacy_output_mode_set(xf86OutputPtr output,
+ DisplayModePtr mode,
+ DisplayModePtr adjusted_mode);
extern void atombios_output_dpms(xf86OutputPtr output, int mode);
+extern void legacy_output_dpms(xf86OutputPtr output, int mode);
extern RADEONMonitorType atombios_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output);
+extern RADEONMonitorType legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output);
extern int atombios_external_tmds_setup(xf86OutputPtr output, DisplayModePtr mode);
-Bool
-RADEONDVOReadByte(I2CDevPtr dvo, int addr, CARD8 *ch)
-{
- if (!xf86I2CReadByte(dvo, addr, ch)) {
- xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
- "Unable to read from %s Slave %d.\n",
- dvo->pI2CBus->BusName, dvo->SlaveAddr);
- return FALSE;
- }
- return TRUE;
-}
-
-Bool
-RADEONDVOWriteByte(I2CDevPtr dvo, int addr, CARD8 ch)
-{
- if (!xf86I2CWriteByte(dvo, addr, ch)) {
- xf86DrvMsg(dvo->pI2CBus->scrnIndex, X_ERROR,
- "Unable to write to %s Slave %d.\n",
- dvo->pI2CBus->BusName, dvo->SlaveAddr);
- return FALSE;
- }
- return TRUE;
-}
-
-static I2CDevPtr
-RADEONDVODeviceInit(I2CBusPtr b, I2CSlaveAddr addr)
-{
- I2CDevPtr dvo;
-
- dvo = xcalloc(1, sizeof(I2CDevRec));
- if (dvo == NULL)
- return NULL;
-
- dvo->DevName = "RADEON DVO Controller";
- dvo->SlaveAddr = addr;
- dvo->pI2CBus = b;
- dvo->StartTimeout = b->StartTimeout;
- dvo->BitTimeout = b->BitTimeout;
- dvo->AcknTimeout = b->AcknTimeout;
- dvo->ByteTimeout = b->ByteTimeout;
-
- if (xf86I2CDevInit(dvo)) {
- return dvo;
- }
-
- xfree(dvo);
- return NULL;
-}
-
-void
-RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (!radeon_output->DVOChip)
- return;
-
- OUTREG(radeon_output->dvo_i2c_reg, INREG(radeon_output->dvo_i2c_reg) &
- (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
-
- if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
- if (radeon_output->DVOChip) {
- switch(info->ext_tmds_chip) {
- case RADEON_SIL_164:
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x30);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x00);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x90);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0x89);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x3b);
- break;
-#if 0
- /* needs work see bug 10418 */
- case RADEON_SIL_1178:
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x44);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0f, 0x4c);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0e, 0x01);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0a, 0x80);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x09, 0x30);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0c, 0xc9);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x0d, 0x70);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x32);
- RADEONDVOWriteByte(radeon_output->DVOChip, 0x08, 0x33);
- break;
-#endif
- default:
- break;
- }
- }
- }
-}
void RADEONPrintPortMap(ScrnInfoPtr pScrn)
{
@@ -404,291 +336,6 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
return MonType;
}
-#if 0
-static RADEONMonitorType
-RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- int bConnected = 0;
-
- /* the monitor either wasn't connected or it is a non-DDC CRT.
- * try to probe it
- */
- if(IsCrtDac) {
- unsigned long ulOrigVCLK_ECP_CNTL;
- unsigned long ulOrigDAC_CNTL;
- unsigned long ulOrigDAC_MACRO_CNTL;
- unsigned long ulOrigDAC_EXT_CNTL;
- unsigned long ulOrigCRTC_EXT_CNTL;
- unsigned long ulData;
- unsigned long ulMask;
-
- ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
- ulData = ulOrigVCLK_ECP_CNTL;
- ulData &= ~(RADEON_PIXCLK_ALWAYS_ONb
- | RADEON_PIXCLK_DAC_ALWAYS_ONb);
- ulMask = ~(RADEON_PIXCLK_ALWAYS_ONb
- |RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
- ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
- ulData = ulOrigCRTC_EXT_CNTL;
- ulData |= RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
-
- ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
- ulData = ulOrigDAC_EXT_CNTL;
- ulData &= ~RADEON_DAC_FORCE_DATA_MASK;
- ulData |= (RADEON_DAC_FORCE_BLANK_OFF_EN
- |RADEON_DAC_FORCE_DATA_EN
- |RADEON_DAC_FORCE_DATA_SEL_MASK);
- if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
- (info->ChipFamily == CHIP_FAMILY_RV280))
- ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
- else
- ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
-
- OUTREG(RADEON_DAC_EXT_CNTL, ulData);
-
- /* turn on power so testing can go through */
- ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
- ulOrigDAC_CNTL &= ~RADEON_DAC_PDWN;
- OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL);
-
- ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
- ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
- /* Enable comparators and set DAC range to PS2 (VGA) output level */
- ulData = ulOrigDAC_CNTL;
- ulData |= RADEON_DAC_CMP_EN;
- ulData &= ~RADEON_DAC_RANGE_CNTL_MASK;
- ulData |= 0x2;
- OUTREG(RADEON_DAC_CNTL, ulData);
-
- /* Settle down */
- usleep(10000);
-
- /* Read comparators */
- ulData = INREG(RADEON_DAC_CNTL);
- bConnected = (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
-
- /* Restore things */
- ulData = ulOrigVCLK_ECP_CNTL;
- ulMask = 0xFFFFFFFFL;
- OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
- OUTREG(RADEON_DAC_CNTL, ulOrigDAC_CNTL );
- OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL );
- OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
-
- if (!bConnected) {
- /* Power DAC down if CRT is not connected */
- ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
- ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
- OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
-
- ulData = INREG(RADEON_DAC_CNTL);
- ulData |= RADEON_DAC_PDWN;
- OUTREG(RADEON_DAC_CNTL, ulData);
- }
- } else { /* TV DAC */
-
- /* This doesn't seem to work reliably (maybe worse on some OEM cards),
- for now we always return false. If one wants to connected a
- non-DDC monitor on the DVI port when CRT port is also connected,
- he will need to explicitly tell the driver in the config file
- with Option MonitorLayout.
- */
- bConnected = FALSE;
-
-#if 0
- if (info->ChipFamily == CHIP_FAMILY_R200) {
- unsigned long ulOrigGPIO_MONID;
- unsigned long ulOrigFP2_GEN_CNTL;
- unsigned long ulOrigDISP_OUTPUT_CNTL;
- unsigned long ulOrigCRTC2_GEN_CNTL;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
- unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
- unsigned long ulOrigCRTC2_H_TOTAL_DISP;
- unsigned long ulOrigCRTC2_V_TOTAL_DISP;
- unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
- unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
- unsigned long ulData, i;
-
- ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
- ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
- ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
- ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
- ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
- ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
- ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
- ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
- ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
- ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
-
- ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
- ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
- ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
- ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
- ulData = INREG(RADEON_GPIO_MONID);
- ulData &= ~RADEON_GPIO_A_0;
- OUTREG(RADEON_GPIO_MONID, ulData);
-
- OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
-
- OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
-
- OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
-
- for (i = 0; i < 200; i++) {
- ulData = INREG(RADEON_GPIO_MONID);
- bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
- if (!bConnected) break;
-
- usleep(1000);
- }
-
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
- OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
- OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
- OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
- OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
- } else {
- unsigned long ulOrigPIXCLKSDATA;
- unsigned long ulOrigTV_MASTER_CNTL;
- unsigned long ulOrigTV_DAC_CNTL;
- unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
- unsigned long ulOrigDAC_CNTL2;
- unsigned long ulData;
- unsigned long ulMask;
-
- ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-
- ulData = ulOrigPIXCLKSDATA;
- ulData &= ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- ulMask = ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
- ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
- ulData = ulOrigTV_MASTER_CNTL;
- ulData &= ~RADEON_TVCLK_ALWAYS_ONb;
- OUTREG(RADEON_TV_MASTER_CNTL, ulData);
-
- ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
- ulData = ulOrigDAC_CNTL2;
- ulData &= ~RADEON_DAC2_DAC2_CLK_SEL;
- OUTREG(RADEON_DAC_CNTL2, ulData);
-
- ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
-
- ulData = 0x00880213;
- OUTREG(RADEON_TV_DAC_CNTL, ulData);
-
- ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-
- ulData = (RADEON_Y_RED_EN
- | RADEON_C_GRN_EN
- | RADEON_CMP_BLU_EN
- | RADEON_RED_MX_FORCE_DAC_DATA
- | RADEON_GRN_MX_FORCE_DAC_DATA
- | RADEON_BLU_MX_FORCE_DAC_DATA);
- if (IS_R300_VARIANT)
- ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
- else
- ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
-
- usleep(10000);
-
- ulData = INREG(RADEON_TV_DAC_CNTL);
- bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
-
- ulData = ulOrigPIXCLKSDATA;
- ulMask = 0xFFFFFFFFL;
- OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
- OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
- OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
- OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
- }
-#endif
- return MT_UNKNOWN;
- }
-
- return(bConnected ? MT_CRT : MT_NONE);
-}
-#endif
-
-static RADEONMonitorType
-legacy_dac_detect(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- RADEONMonitorType found = MT_NONE;
-
- if (OUTPUT_IS_TV) {
- if (xf86ReturnOptValBool(info->Options, OPTION_FORCE_TVOUT, FALSE)) {
- if (radeon_output->type == OUTPUT_STV)
- radeon_output->MonType = MT_STV;
- else
- radeon_output->MonType = MT_CTV;
- } else {
- if (info->InternalTVOut) {
- if (radeon_output->load_detection)
- radeon_output->MonType = radeon_detect_tv(pScrn);
- else
- radeon_output->MonType = MT_NONE;
- }
- }
- } else {
- if (radeon_output->DACType == DAC_PRIMARY) {
- if (radeon_output->load_detection)
- found = radeon_detect_primary_dac(pScrn, TRUE);
- } else if (radeon_output->DACType == DAC_TVDAC) {
- if (radeon_output->load_detection) {
- if (info->ChipFamily == CHIP_FAMILY_R200)
- found = radeon_detect_ext_dac(pScrn);
- else
- found = radeon_detect_tv_dac(pScrn, TRUE);
- } else
- found = MT_NONE;
- }
- }
-
- return found;
-}
/* Primary Head (DVI or Laptop Int. panel)*/
/* A ddc capable display connected on DVI port */
@@ -818,23 +465,12 @@ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr
static void
radeon_dpms(xf86OutputPtr output, int mode)
{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONInfoPtr info = RADEONPTR(output->scrn);
if (IS_AVIVO_VARIANT) {
atombios_output_dpms(output, mode);
- return;
- }
-
- switch(mode) {
- case DPMSModeOn:
- RADEONEnableDisplay(output, TRUE);
- break;
- case DPMSModeOff:
- case DPMSModeSuspend:
- case DPMSModeStandby:
- RADEONEnableDisplay(output, FALSE);
- break;
+ } else {
+ legacy_output_dpms(output, mode);
}
}
@@ -941,402 +577,16 @@ radeon_mode_prepare(xf86OutputPtr output)
{
}
-static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- int i;
- CARD32 tmp = info->SavedReg->tmds_pll_cntl & 0xfffff;
-
- for (i=0; i<4; i++) {
- if (radeon_output->tmds_pll[i].freq == 0) break;
- if ((CARD32)(mode->Clock/10) < radeon_output->tmds_pll[i].freq) {
- tmp = radeon_output->tmds_pll[i].value ;
- break;
- }
- }
-
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RV280)) {
- if (tmp & 0xfff00000)
- save->tmds_pll_cntl = tmp;
- else {
- save->tmds_pll_cntl = info->SavedReg->tmds_pll_cntl & 0xfff00000;
- save->tmds_pll_cntl |= tmp;
- }
- } else save->tmds_pll_cntl = tmp;
-
- save->tmds_transmitter_cntl = info->SavedReg->tmds_transmitter_cntl &
- ~(RADEON_TMDS_TRANSMITTER_PLLRST);
-
- if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_R200) || !pRADEONEnt->HasCRTC2)
- save->tmds_transmitter_cntl &= ~(RADEON_TMDS_TRANSMITTER_PLLEN);
- else /* weird, RV chips got this bit reversed? */
- save->tmds_transmitter_cntl |= (RADEON_TMDS_TRANSMITTER_PLLEN);
-
- save->fp_gen_cntl = info->SavedReg->fp_gen_cntl |
- (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
- RADEON_FP_CRTC_DONT_SHADOW_HEND );
-
- save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-
- if (pScrn->rgbBits == 8)
- save->fp_gen_cntl |= RADEON_FP_PANEL_FORMAT; /* 24 bit format */
- else
- save->fp_gen_cntl &= ~RADEON_FP_PANEL_FORMAT;/* 18 bit format */
-
-
- if (IsPrimary) {
- if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
- save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
- if (mode->Flags & RADEON_USE_RMX)
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_RMX;
- else
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC1;
- } else
- save->fp_gen_cntl |= RADEON_FP_SEL_CRTC1;
- } else {
- if ((IS_R300_VARIANT) || (info->ChipFamily == CHIP_FAMILY_R200)) {
- save->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
- save->fp_gen_cntl |= R200_FP_SOURCE_SEL_CRTC2;
- } else
- save->fp_gen_cntl |= RADEON_FP_SEL_CRTC2;
- }
-
-}
-
-static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
-
- if (pScrn->rgbBits == 8)
- save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl |
- RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
- else
- save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
- ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
-
- save->fp2_gen_cntl &= ~(RADEON_FP2_ON |
- RADEON_FP2_DVO_EN |
- RADEON_FP2_DVO_RATE_SEL_SDR);
-
-
- /* XXX: these may be oem specific */
- if (IS_R300_VARIANT) {
- save->fp2_gen_cntl |= RADEON_FP2_PAD_FLOP_EN | R300_FP2_DVO_CLOCK_MODE_SINGLE;
-#if 0
- if (mode->Clock > 165000)
- save->fp2_gen_cntl |= R300_FP2_DVO_DUAL_CHANNEL_EN;
-#endif
- }
-
- if (IsPrimary) {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
- if (mode->Flags & RADEON_USE_RMX)
- save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_RMX;
- } else {
- save->fp2_gen_cntl &= ~RADEON_FP2_SRC_SEL_CRTC2;
- }
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->fp2_gen_cntl &= ~R200_FP2_SOURCE_SEL_MASK;
- save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
- } else {
- save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
- }
- }
-
-}
-
-static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- save->lvds_pll_cntl = (info->SavedReg->lvds_pll_cntl |
- RADEON_LVDS_PLL_EN);
-
- save->lvds_pll_cntl &= ~RADEON_LVDS_PLL_RESET;
-
- save->lvds_gen_cntl = info->SavedReg->lvds_gen_cntl;
- save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
- save->lvds_gen_cntl &= ~(RADEON_LVDS_ON |
- RADEON_LVDS_BLON |
- RADEON_LVDS_EN |
- RADEON_LVDS_RST_FM);
-
- if (IS_R300_VARIANT)
- save->lvds_pll_cntl &= ~(R300_LVDS_SRC_SEL_MASK);
-
- if (IsPrimary) {
- if (IS_R300_VARIANT) {
- if (mode->Flags & RADEON_USE_RMX)
- save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_RMX;
- } else
- save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
- } else {
- if (IS_R300_VARIANT) {
- save->lvds_pll_cntl |= R300_LVDS_SRC_SEL_CRTC2;
- } else
- save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
- }
-
-}
-
-static void RADEONInitRMXRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- int xres = mode->HDisplay;
- int yres = mode->VDisplay;
- float Hratio, Vratio;
-
- save->fp_vert_stretch = info->SavedReg->fp_vert_stretch &
- RADEON_VERT_STRETCH_RESERVED;
- save->fp_horz_stretch = info->SavedReg->fp_horz_stretch &
- (RADEON_HORZ_FP_LOOP_STRETCH |
- RADEON_HORZ_AUTO_RATIO_INC);
-
- if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
- return;
-
- if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
- Hratio = 1.0;
- Vratio = 1.0;
- } else {
- if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
- if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
-
- Hratio = (float)xres/(float)radeon_output->PanelXRes;
- Vratio = (float)yres/(float)radeon_output->PanelYRes;
- }
-
- if (Hratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
- save->fp_horz_stretch |= ((xres/8-1)<<16);
- } else {
- save->fp_horz_stretch |= ((((unsigned long)
- (Hratio * RADEON_HORZ_STRETCH_RATIO_MAX)) &
- RADEON_HORZ_STRETCH_RATIO_MASK) |
- RADEON_HORZ_STRETCH_BLEND |
- RADEON_HORZ_STRETCH_ENABLE |
- ((radeon_output->PanelXRes/8-1)<<16));
- }
-
- if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
- save->fp_vert_stretch |= ((yres-1)<<12);
- } else {
- save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) &
- RADEON_VERT_STRETCH_RATIO_MASK) |
- RADEON_VERT_STRETCH_ENABLE |
- RADEON_VERT_STRETCH_BLEND |
- ((radeon_output->PanelYRes-1)<<12));
- }
-
-}
-
-static void RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- if (IsPrimary) {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg->disp_output_cntl &
- ~RADEON_DISP_DAC_SOURCE_MASK;
- } else {
- save->dac2_cntl = info->SavedReg->dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
- }
- } else {
- if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg->disp_output_cntl &
- ~RADEON_DISP_DAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_DAC_SOURCE_CRTC2;
- } else {
- save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
- }
- }
- save->dac_cntl = (RADEON_DAC_MASK_ALL
- | RADEON_DAC_VGA_ADR_EN
- | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
-
- save->dac_macro_cntl = info->SavedReg->dac_macro_cntl;
-}
-
-static void
-RADEONInitTvDacCntl(xf86OutputPtr output, RADEONSavePtr save)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (info->ChipFamily == CHIP_FAMILY_R420 ||
- info->ChipFamily == CHIP_FAMILY_RV410) {
- save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
- ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- R420_TV_DAC_DACADJ_MASK |
- R420_TV_DAC_RDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_GDACPD |
- R420_TV_DAC_TVENABLE);
- } else {
- save->tv_dac_cntl = info->SavedReg->tv_dac_cntl &
- ~(RADEON_TV_DAC_STD_MASK |
- RADEON_TV_DAC_BGADJ_MASK |
- RADEON_TV_DAC_DACADJ_MASK |
- RADEON_TV_DAC_RDACPD |
- RADEON_TV_DAC_GDACPD |
- RADEON_TV_DAC_GDACPD);
- }
-
- save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_DAC_STD_PS2 |
- radeon_output->tv_dac_adj);
-
-}
-
-static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
- DisplayModePtr mode, BOOL IsPrimary)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
-
- /*0x0028023;*/
- RADEONInitTvDacCntl(output, save);
-
- if (IS_R300_VARIANT)
- save->gpiopad_a = info->SavedReg->gpiopad_a | 1;
-
- save->dac2_cntl = info->SavedReg->dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
-
- if (IsPrimary) {
- if (IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg->disp_output_cntl &
- ~RADEON_DISP_TVDAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC;
- } else if (info->ChipFamily == CHIP_FAMILY_R200) {
- save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
- ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- } else {
- save->disp_hw_debug = info->SavedReg->disp_hw_debug | RADEON_CRT2_DISP1_SEL;
- }
- } else {
- if (IS_R300_VARIANT) {
- save->disp_output_cntl = info->SavedReg->disp_output_cntl &
- ~RADEON_DISP_TVDAC_SOURCE_MASK;
- save->disp_output_cntl |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
- } else if (info->ChipFamily == CHIP_FAMILY_R200) {
- save->fp2_gen_cntl = info->SavedReg->fp2_gen_cntl &
- ~(R200_FP2_SOURCE_SEL_MASK |
- RADEON_FP2_DVO_RATE_SEL_SDR);
- save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
- } else {
- save->disp_hw_debug = info->SavedReg->disp_hw_debug &
- ~RADEON_CRT2_DISP1_SEL;
- }
- }
-}
-
-static void
-RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
- DisplayModePtr mode, xf86OutputPtr output,
- int crtc_num)
-{
- Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
- if (crtc_num == 0)
- RADEONInitRMXRegisters(output, save, mode);
-
- if (radeon_output->MonType == MT_CRT) {
- if (radeon_output->DACType == DAC_PRIMARY) {
- RADEONInitDACRegisters(output, save, mode, IsPrimary);
- } else {
- RADEONInitDAC2Registers(output, save, mode, IsPrimary);
- }
- } else if (radeon_output->MonType == MT_LCD) {
- RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
- } else if (radeon_output->MonType == MT_DFP) {
- if (radeon_output->TMDSType == TMDS_INT) {
- RADEONInitFPRegisters(output, save, mode, IsPrimary);
- } else {
- RADEONInitFP2Registers(output, save, mode, IsPrimary);
- }
- } else if (radeon_output->MonType == MT_STV ||
- radeon_output->MonType == MT_CTV) {
- RADEONInitTVRegisters(output, save, mode, IsPrimary);
- }
-}
-
-static void
-legacy_mode_set(xf86OutputPtr output, DisplayModePtr mode,
- DisplayModePtr adjusted_mode)
-{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
- RADEONOutputPrivatePtr radeon_output = output->driver_private;
- xf86CrtcPtr crtc = output->crtc;
- RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-
- RADEONInitOutputRegisters(pScrn, info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
-
- if (radeon_crtc->crtc_id == 0)
- RADEONRestoreRMXRegisters(pScrn, info->ModeReg);
-
- switch(radeon_output->MonType) {
- case MT_LCD:
- ErrorF("restore LVDS\n");
- RADEONRestoreLVDSRegisters(pScrn, info->ModeReg);
- break;
- case MT_DFP:
- if (radeon_output->TMDSType == TMDS_INT) {
- ErrorF("restore FP\n");
- RADEONRestoreFPRegisters(pScrn, info->ModeReg);
- } else {
- ErrorF("restore FP2\n");
- if (info->IsAtomBios)
- atombios_external_tmds_setup(output, mode);
- else
- RADEONRestoreDVOChip(pScrn, output);
- RADEONRestoreFP2Registers(pScrn, info->ModeReg);
- }
- break;
- case MT_STV:
- case MT_CTV:
- ErrorF("restore tv\n");
- RADEONRestoreDACRegisters(pScrn, info->ModeReg);
- RADEONRestoreTVRegisters(pScrn, info->ModeReg);
- break;
- default:
- ErrorF("restore dac\n");
- RADEONRestoreDACRegisters(pScrn, info->ModeReg);
- }
-
-}
-
static void
radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
- DisplayModePtr adjusted_mode)
+ DisplayModePtr adjusted_mode)
{
- ScrnInfoPtr pScrn = output->scrn;
- RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONInfoPtr info = RADEONPTR(output->scrn);
if (IS_AVIVO_VARIANT)
atombios_output_mode_set(output, mode, adjusted_mode);
else
- legacy_mode_set(output, mode, adjusted_mode);
+ legacy_output_mode_set(output, mode, adjusted_mode);
}
@@ -1346,423 +596,6 @@ radeon_mode_commit(xf86OutputPtr output)
radeon_dpms(output, DPMSModeOn);
}
-/* the following functions are based on the load detection code
- * in the beos radeon driver by Thomas Kurschel and the existing
- * load detection code in this driver.
- */
-static RADEONMonitorType
-radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 vclk_ecp_cntl, crtc_ext_cntl;
- CARD32 dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
- RADEONMonitorType found = MT_NONE;
-
- /* save the regs we need */
- vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
- crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
- dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
- dac_cntl = INREG(RADEON_DAC_CNTL);
- dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
-
- tmp = vclk_ecp_cntl &
- ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
- OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
-
- tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
- OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
-
- tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
- RADEON_DAC_FORCE_DATA_EN;
-
- if (color)
- tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
- else
- tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
-
- if (IS_R300_VARIANT)
- tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
- else
- tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
-
- OUTREG(RADEON_DAC_EXT_CNTL, tmp);
-
- tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
- tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
- OUTREG(RADEON_DAC_CNTL, tmp);
-
- tmp &= ~(RADEON_DAC_PDWN_R |
- RADEON_DAC_PDWN_G |
- RADEON_DAC_PDWN_B);
-
- OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
-
- usleep(2000);
-
- if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
- found = MT_CRT;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "Found %s CRT connected to primary DAC\n",
- color ? "color" : "bw");
- }
-
- /* restore the regs we used */
- OUTREG(RADEON_DAC_CNTL, dac_cntl);
- OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
- OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
- OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
- OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
-
- return found;
-}
-
-static RADEONMonitorType
-radeon_detect_ext_dac(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
- CARD32 disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
- CARD32 disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
- CARD32 tmp, crtc2_h_total_disp, crtc2_v_total_disp;
- CARD32 crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
- RADEONMonitorType found = MT_NONE;
- int connected = 0;
- int i = 0;
-
- /* save the regs we need */
- gpio_monid = INREG(RADEON_GPIO_MONID);
- fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
- disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
- crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
- disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
- disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
- disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
- disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
- disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
- disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
- crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
- crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
- crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
- crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
- tmp = INREG(RADEON_GPIO_MONID);
- tmp &= ~RADEON_GPIO_A_0;
- OUTREG(RADEON_GPIO_MONID, tmp);
-
- OUTREG(RADEON_FP2_GEN_CNTL,
- RADEON_FP2_ON |
- RADEON_FP2_PANEL_FORMAT |
- R200_FP2_SOURCE_SEL_TRANS_UNIT |
- RADEON_FP2_DVO_EN |
- R200_FP2_DVO_RATE_SEL_SDR);
-
- OUTREG(RADEON_DISP_OUTPUT_CNTL,
- RADEON_DISP_DAC_SOURCE_RMX |
- RADEON_DISP_TRANS_MATRIX_GRAPHICS);
-
- OUTREG(RADEON_CRTC2_GEN_CNTL,
- RADEON_CRTC2_EN |
- RADEON_CRTC2_DISP_REQ_EN_B);
-
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
-
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
-
- for (i = 0; i < 200; i++) {
- tmp = INREG(RADEON_GPIO_MONID);
- if (tmp & RADEON_GPIO_Y_0)
- connected = 1;
- else
- connected = 0;
-
- if (!connected)
- break;
-
- usleep(1000);
- }
-
- if (connected)
- found = MT_CRT;
-
- /* restore the regs we used */
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
- OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
- OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
- OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
- OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
- OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
- OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
- OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
- OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
- OUTREG(RADEON_GPIO_MONID, gpio_monid);
-
- return found;
-}
-
-static RADEONMonitorType
-radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
- CARD32 disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
- RADEONMonitorType found = MT_NONE;
-
- /* save the regs we need */
- pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
- gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
- disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
- disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
- crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
- tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
- dac_cntl2 = INREG(RADEON_DAC_CNTL2);
-
- tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
- | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
- if (IS_R300_VARIANT) {
- OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
- }
-
- tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
- tmp |= RADEON_CRTC2_CRT2_ON |
- (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
-
- OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
-
- if (IS_R300_VARIANT) {
- tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
- tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
- OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
- } else {
- tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
- OUTREG(RADEON_DISP_HW_DEBUG, tmp);
- }
-
- tmp = RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_MONITOR_DETECT_EN |
- RADEON_TV_DAC_STD_PS2;
-
- OUTREG(RADEON_TV_DAC_CNTL, tmp);
-
- tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
- RADEON_DAC2_FORCE_DATA_EN;
-
- if (color)
- tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
- else
- tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
-
- if (IS_R300_VARIANT)
- tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
- else
- tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
-
- OUTREG(RADEON_DAC_EXT_CNTL, tmp);
-
- tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
- OUTREG(RADEON_DAC_CNTL2, tmp);
-
- usleep(10000);
-
- if (IS_R300_VARIANT) {
- if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
- found = MT_CRT;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "Found %s CRT connected to TV DAC\n",
- color ? "color" : "bw");
- }
- } else {
- if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
- found = MT_CRT;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "Found %s CRT connected to TV DAC\n",
- color ? "color" : "bw");
- }
- }
-
- /* restore regs we used */
- OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
- OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
- OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
- OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
-
- if (IS_R300_VARIANT) {
- OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
- OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
- } else {
- OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
- }
- OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
-
- return found;
-}
-
-static RADEONMonitorType
-r300_detect_tv(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
- CARD32 gpiopad_a, disp_output_cntl;
- RADEONMonitorType found = MT_NONE;
-
- /* save the regs we need */
- gpiopad_a = INREG(RADEON_GPIOPAD_A);
- dac_cntl2 = INREG(RADEON_DAC_CNTL2);
- crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
- dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
- tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
-
- OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
-
- OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
-
- OUTREG(RADEON_CRTC2_GEN_CNTL,
- RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
-
- tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
- tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
- OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
-
- OUTREG(RADEON_DAC_EXT_CNTL,
- RADEON_DAC2_FORCE_BLANK_OFF_EN |
- RADEON_DAC2_FORCE_DATA_EN |
- RADEON_DAC_FORCE_DATA_SEL_RGB |
- (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
-
- OUTREG(RADEON_TV_DAC_CNTL,
- RADEON_TV_DAC_STD_NTSC |
- (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
- (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
-
- INREG(RADEON_TV_DAC_CNTL);
-
- usleep(4000);
-
- OUTREG(RADEON_TV_DAC_CNTL,
- RADEON_TV_DAC_NBLANK |
- RADEON_TV_DAC_NHOLD |
- RADEON_TV_MONITOR_DETECT_EN |
- RADEON_TV_DAC_STD_NTSC |
- (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
- (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
-
- INREG(RADEON_TV_DAC_CNTL);
-
- usleep(6000);
-
- tmp = INREG(RADEON_TV_DAC_CNTL);
- if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
- found = MT_STV;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "S-Video TV connection detected\n");
- } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
- found = MT_CTV;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "Composite TV connection detected\n" );
- }
-
- OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
- OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
- OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
- OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
- OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
- OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
-
- return found;
-}
-
-static RADEONMonitorType
-radeon_detect_tv(ScrnInfoPtr pScrn)
-{
- RADEONInfoPtr info = RADEONPTR(pScrn);
- unsigned char *RADEONMMIO = info->MMIO;
- CARD32 tmp, dac_cntl2, tv_master_cntl;
- CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
- RADEONMonitorType found = MT_NONE;
-
- if (IS_R300_VARIANT)
- return r300_detect_tv(pScrn);
-
- /* save the regs we need */
- dac_cntl2 = INREG(RADEON_DAC_CNTL2);
- tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
- tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
- config_cntl = INREG(RADEON_CONFIG_CNTL);
- tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-
- tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
- OUTREG(RADEON_DAC_CNTL2, tmp);
-
- tmp = tv_master_cntl | RADEON_TV_ON;
- tmp &= ~(RADEON_TV_ASYNC_RST |
- RADEON_RESTART_PHASE_FIX |
- RADEON_CRT_FIFO_CE_EN |
- RADEON_TV_FIFO_CE_EN |
- RADEON_RE_SYNC_NOW_SEL_MASK);
- tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
-
- OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-
- tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
- RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
- (8 << RADEON_TV_DAC_BGADJ_SHIFT);
-
- if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
- tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
- else
- tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
-
- OUTREG(RADEON_TV_DAC_CNTL, tmp);
-
- tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
- RADEON_RED_MX_FORCE_DAC_DATA |
- RADEON_GRN_MX_FORCE_DAC_DATA |
- RADEON_BLU_MX_FORCE_DAC_DATA |
- (0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
-
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
-
- usleep(3000);
-
- tmp = INREG(RADEON_TV_DAC_CNTL);
- if (tmp & RADEON_TV_DAC_GDACDET) {
- found = MT_STV;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "S-Video TV connection detected\n");
- } else if (tmp & RADEON_TV_DAC_BDACDET) {
- found = MT_CTV;
- xf86DrvMsg (pScrn->scrnIndex, X_INFO,
- "Composite TV connection detected\n" );
- }
-
- OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
- OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
- OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
- OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
-
- return found;
-}
-
static xf86OutputStatus
radeon_detect(xf86OutputPtr output)
{
@@ -1851,7 +684,7 @@ radeon_get_modes(xf86OutputPtr output)
static void
radeon_destroy (xf86OutputPtr output)
{
- if(output->driver_private)
+ if (output->driver_private)
xfree(output->driver_private);
}
@@ -2813,6 +1646,21 @@ RADEONGetTVInfo(xf86OutputPtr output)
}
+static void
+RADEONGetTVDacAdjInfo(xf86OutputPtr output)
+{
+ ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+ /* Todo: get this setting from BIOS */
+ radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
+ if (info->IsMobility) { /* some mobility chips may different */
+ if (info->ChipFamily == CHIP_FAMILY_RV250)
+ radeon_output->tv_dac_adj = 0x00880000;
+ }
+}
+
void RADEONInitConnector(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
More information about the xorg-commit
mailing list