xf86-video-ati: Branch 'randr-1.2'

Michel Daenzer daenzer at kemper.freedesktop.org
Wed May 30 11:26:52 PDT 2007


 src/radeon.h         |   22 +
 src/radeon_bios.c    |    2 
 src/radeon_crtc.c    |  635 +++++++++++++++++++++++++++++++-
 src/radeon_cursor.c  |   52 --
 src/radeon_display.c |  677 ----------------------------------
 src/radeon_driver.c  |  926 ----------------------------------------------
 src/radeon_modes.c   |    6 
 src/radeon_output.c  | 1007 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/radeon_video.c   |    1 
 9 files changed, 1643 insertions(+), 1685 deletions(-)

New commits:
diff-tree 0e0946e0aa2527794e07473199e851bbfbc47cb1 (from 31c1be420d5277dd15505bd73e6144827a0580cd)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Wed May 30 18:56:53 2007 +0200

    radeon: Lots of warning fixes.
    
    Move code where it's used, remove unused variables, etc.

diff --git a/src/radeon.h b/src/radeon.h
index eb4902b..62faee0 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -816,6 +816,26 @@ extern Bool        RADEONGetLVDSInfoFrom
 extern Bool        RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
 
+extern void        RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+						RADEONSavePtr restore);
+extern void        RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+						RADEONSavePtr restore);
+extern void        RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+					      RADEONSavePtr restore);
+extern void        RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+					     RADEONSavePtr restore);
+extern void        RADEONRestoreFPRegisters(ScrnInfoPtr pScrn,
+					    RADEONSavePtr restore);
+extern void        RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+					     RADEONSavePtr restore);
+extern void        RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+					       RADEONSavePtr restore);
+extern void        RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+					      RADEONSavePtr restore);
+
+extern void        RADEONInitMemMapRegisters(ScrnInfoPtr pScrn,
+					     RADEONSavePtr save,
+					     RADEONInfoPtr info);
 extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
 extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
 extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
@@ -859,6 +879,8 @@ void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
 void
 RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
+void
+RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox);
 
 #ifdef XF86DRI
 #ifdef USE_XAA
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 8d5c0ec..76b0a72 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -44,7 +44,6 @@
 int RADEONBIOSApplyConnectorQuirks(ScrnInfoPtr pScrn, int connector_found)
 {
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
     /* quirk for compaq nx6125 - the bios lies about the VGA DDC */
     if (info->PciInfo->subsysVendor == PCI_VENDOR_HP) {
@@ -145,7 +144,6 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn
 Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int i = 0, j, tmp, tmp0=0, tmp1=0;
 
     if(!info->VBIOS) return FALSE;
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 0e1d82e..79ab578 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -47,6 +47,13 @@
 #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 radeon_crtc_load_lut(xf86CrtcPtr crtc);
 
 static void
@@ -113,6 +120,619 @@ radeon_crtc_mode_prepare(xf86CrtcPtr crt
     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;
+}
+
+/* Define CRTC registers for requested video mode */
+static Bool
+RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
+			DisplayModePtr mode, int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    //RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int    format;
+    int    hsync_start;
+    int    hsync_wid;
+    int    vsync_wid;
+    int    Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
+
+    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->surface_cntl = 0;
+    save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
+    save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
+
+#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 (pScrn->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
+
+    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;
+    if (hsync_wid > 0x3f) hsync_wid = 0x3f;
+    hsync_start = mode->CrtcHSyncStart - 8;
+
+    save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
+				  | (hsync_wid << 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;
+    if (vsync_wid > 0x1f) vsync_wid = 0x1f;
+
+    save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+				  | (vsync_wid << 16)
+				  | ((mode->Flags & V_NVSYNC)
+				     ? RADEON_CRTC_V_SYNC_POL
+				     : 0));
+
+    save->crtc_offset      = pScrn->fbOffset;
+    if (info->allowPageFlip)
+	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+
+    if (info->tilingEnabled) {
+       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;
+    }
+
+    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;
+
+    Base = pScrn->fbOffset;
+
+    if (info->tilingEnabled) {
+        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;
+    }
+
+    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;
+
+
+    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;
+}
+
+/* Define CRTC2 registers for requested video mode */
+static Bool
+RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
+			 DisplayModePtr mode, int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    //RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int    format;
+    int    hsync_start;
+    int    hsync_wid;
+    int    vsync_wid;
+    int    Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
+
+    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;
+    if (hsync_wid > 0x3f) hsync_wid = 0x3f;
+    hsync_start = mode->CrtcHSyncStart - 8;
+
+    save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
+				   | (hsync_wid << 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;
+    if (vsync_wid > 0x1f) vsync_wid = 0x1f;
+
+    save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
+				   | (vsync_wid << 16)
+				   | ((mode->Flags & V_NVSYNC)
+				      ? RADEON_CRTC2_V_SYNC_POL
+				      : 0));
+
+    /* It seems all fancy options apart from pflip can be safely disabled
+     */
+    save->crtc2_offset      = pScrn->fbOffset;
+    if (info->allowPageFlip)
+	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+
+    if (info->tilingEnabled) {
+       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;
+    }
+
+    save->crtc2_pitch  = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) +
+			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
+    save->crtc2_pitch |= save->crtc2_pitch << 16;
+
+    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;
+
+    Base = pScrn->fbOffset;
+
+    if (info->tilingEnabled) {
+        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;
+    }
+
+    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;
+
+    /* We must set SURFACE_CNTL properly on the second screen too */
+    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 (pScrn->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
+ 
+    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;
+}
+
+
+/* Compute n/d with rounding */
+static int RADEONDiv(int n, int d)
+{
+    return (n + (d / 2)) / d;
+}
+
+/* Define PLL registers for requested video mode */
+static void
+RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
+		       RADEONSavePtr save, RADEONPLLPtr pll,
+		       double dot_clock)
+{
+    unsigned long  freq = dot_clock * 100;
+
+    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 (info->UseBiosDividers) {
+       save->ppll_ref_div = info->RefDivider;
+       save->ppll_div_3   = info->FeedbackDivider | (info->PostDivider << 16);
+       save->htotal_cntl  = 0;
+       return;
+    }
+
+    if (freq > pll->max_pll_freq)      freq = pll->max_pll_freq;
+    if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
+
+    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+	save->pll_output_freq = post_div->divider * freq;
+
+	if (save->pll_output_freq >= pll->min_pll_freq
+	    && save->pll_output_freq <= pll->max_pll_freq) break;
+    }
+
+    if (!post_div->divider) {
+	save->pll_output_freq = freq;
+	post_div = &post_divs[0];
+    }
+
+    save->dot_clock_freq = freq;
+    save->feedback_div   = RADEONDiv(pll->reference_div
+				     * save->pll_output_freq,
+				     pll->reference_freq);
+    save->post_div       = post_div->divider;
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "dc=%ld, of=%ld, fd=%d, pd=%d\n",
+		   save->dot_clock_freq,
+		   save->pll_output_freq,
+		   save->feedback_div,
+		   save->post_div);
+
+    save->ppll_ref_div   = pll->reference_div;
+    save->ppll_div_3     = (save->feedback_div | (post_div->bitvalue << 16));
+    save->htotal_cntl    = 0;
+
+    save->vclk_cntl = (info->SavedReg.vclk_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, double dot_clock,
+			int no_odd_postdiv)
+{
+    RADEONInfoPtr  info      = RADEONPTR(pScrn);
+    unsigned long  freq = dot_clock * 100;
+
+    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 (freq > pll->max_pll_freq)      freq = pll->max_pll_freq;
+    if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
+
+    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+       /* Odd post divider value don't work properly on the second digital
+        * output
+        */
+       if (no_odd_postdiv && (post_div->divider & 1))
+           continue;
+	save->pll_output_freq_2 = post_div->divider * freq;
+	if (save->pll_output_freq_2 >= pll->min_pll_freq
+	    && save->pll_output_freq_2 <= pll->max_pll_freq) 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   = RADEONDiv(pll->reference_div
+				       * save->pll_output_freq_2,
+				       pll->reference_freq);
+    save->post_div_2       = post_div->divider;
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "dc=%ld, of=%ld, fd=%d, pd=%d\n",
+		   save->dot_clock_freq_2,
+		   save->pll_output_freq_2,
+		   save->feedback_div_2,
+		   save->post_div_2);
+
+    save->p2pll_ref_div    = pll->reference_div;
+    save->p2pll_div_0      = (save->feedback_div_2 |
+			      (post_div->bitvalue << 16));
+    save->htotal_cntl2     = 0;
+
+    save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
+			   ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+			  RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
+
+}
+
 static void
 radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode, int x, int y)
@@ -121,7 +741,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONMonitorType montype;
+    RADEONMonitorType montype = MT_NONE;
     int i = 0;
     double         dot_clock = 0;
 
@@ -198,7 +818,6 @@ radeon_crtc_mode_commit(xf86CrtcPtr crtc
 void radeon_crtc_load_lut(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -219,10 +838,7 @@ static void
 radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, 
 		      CARD16 *blue, int size)
 {
-    ScrnInfoPtr pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
     int i;
 
     for (i = 0; i < 256; i++) {
@@ -239,9 +855,8 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr		pScrn = crtc->scrn;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
-#ifdef XF86DRI
-    Bool           CPStarted   = info->CPStarted;
 
+#ifdef XF86DRI
     if (info->CPStarted && pScrn->pScreen) {
 	DRILock(pScrn->pScreen, 0);
 	if (info->accelOn)
@@ -322,7 +937,7 @@ radeon_crtc_shadow_allocate (xf86CrtcPtr
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     unsigned long rotate_pitch;
     unsigned long rotate_offset;
-    int align = KB(4), size;
+    int align = 4096, size;
     int cpp = pScrn->bitsPerPixel / 8;
 
     rotate_pitch = pScrn->displayWidth * cpp;
@@ -382,7 +997,6 @@ static PixmapPtr
 radeon_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
     unsigned long rotate_pitch;
     PixmapPtr rotate_pixmap;
     int cpp = pScrn->bitsPerPixel / 8;
@@ -599,8 +1213,7 @@ RADEONChooseOverlayCRTC(ScrnInfoPtr pScr
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     int c;
-    int highx = 0, highy = 0;
-    int crtc_num;
+    int crtc_num = 0;
 
     for (c = 0; c < xf86_config->num_crtc; c++)
     {
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index b3f7691..98f4560 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -59,14 +59,6 @@
 				/* X and server generic header files */
 #include "xf86.h"
 
-/* Mono ARGB cursor colours (premultiplied). */
-static CARD32 mono_cursor_color[] = {
-	0x00000000, /* White, fully transparent. */
-	0x00000000, /* Black, fully transparent. */
-	0xffffffff, /* White, fully opaque. */
-	0xff000000, /* Black, fully opaque. */
-};
-
 #define CURSOR_WIDTH	64
 #define CURSOR_HEIGHT	64
 
@@ -131,44 +123,6 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crt
 
 }
 
-/* Set cursor foreground and background colors */
-static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    CARD32        *pixels     = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
-    int            pixel, i;
-    CURSOR_SWAPPING_DECL_MMIO
-
-    RADEONCTRACE(("RADEONSetCursorColors\n"));
-
-#ifdef ARGB_CURSOR
-    /* Don't recolour cursors set with SetCursorARGB. */
-    if (info->cursor_argb)
-       return;
-#endif
-
-    fg |= 0xff000000;
-    bg |= 0xff000000;
-
-    /* Don't recolour the image if we don't have to. */
-    if (fg == info->cursor_fg && bg == info->cursor_bg)
-       return;
-
-    CURSOR_SWAPPING_START();
-
-    /* Note: We assume that the pixels are either fully opaque or fully
-     * transparent, so we won't premultiply them, and we can just
-     * check for non-zero pixel values; those are either fg or bg
-     */
-    for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++)
-       if ((pixel = *pixels))
-           *pixels = (pixel == info->cursor_fg) ? fg : bg;
-
-    CURSOR_SWAPPING_END();
-    info->cursor_fg = fg;
-    info->cursor_bg = bg;
-}
-
 void
 radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 {
@@ -262,14 +216,13 @@ void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    int crtc_id = radeon_crtc->crtc_id;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
+#if 0
     int            x, y, w, h;
     CARD32	  *i;
+#endif
 
     RADEONCTRACE(("RADEONLoadCursorARGB\n"));
 
@@ -313,7 +266,6 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
 {
     ScrnInfoPtr        pScrn   = xf86Screens[pScreen->myNum];
     RADEONInfoPtr      info    = RADEONPTR(pScrn);
-    xf86CursorInfoPtr  cursor;
     int                width;
     int		       width_bytes;
     int                height;
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 0442b9a..18d8a01 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -49,28 +49,6 @@
 
 extern int getRADEONEntityIndex(void);
 
-static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
-{
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_LEGACY*/
-    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RADEON*/
-    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV100*/
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS100*/
-    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV200*/
-    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS200*/
-    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_R200*/
-    {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV250*/
-    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS300*/
-    {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R300*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R350*/
-    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV350*/
-    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV380*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R420*/
-    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
-    {{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 */
@@ -93,68 +71,6 @@ static const CARD32 default_tvdac_adj [C
     0x00780000,   /* rs400 */ /* FIXME: just values from rv380 used... */
 };
 
-static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
-{
-    ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned long  val;
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    /* Get the result */
-
-    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) { 
-        val = INREG(b->DriverPrivate.uval+4);
-        *Clock = (val & (1<<13)) != 0;
-        *data  = (val & (1<<12)) != 0;
-    } else {
-        val = INREG(b->DriverPrivate.uval);
-        *Clock = (val & RADEON_GPIO_Y_1) != 0;
-        *data  = (val & RADEON_GPIO_Y_0) != 0;
-    }
-}
-
-static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
-{
-    ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned long  val;
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
-        val |= (Clock ? 0:(1<<13));
-        val |= (data ? 0:(1<<12));
-        OUTREG(b->DriverPrivate.uval, val);
-    } else {
-        val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
-        val |= (Clock ? 0:RADEON_GPIO_EN_1);
-        val |= (data ? 0:RADEON_GPIO_EN_0);
-        OUTREG(b->DriverPrivate.uval, val);
-   }
-    /* read back to improve reliability on some cards. */
-    val = INREG(b->DriverPrivate.uval);
-}
-
-Bool RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
-{
-    I2CBusPtr pI2CBus;
-
-    pI2CBus = xf86CreateI2CBusRec();
-    if (!pI2CBus) return FALSE;
-
-    pI2CBus->BusName    = name;
-    pI2CBus->scrnIndex  = pScrn->scrnIndex;
-    pI2CBus->I2CPutBits = RADEONI2CPutBits;
-    pI2CBus->I2CGetBits = RADEONI2CGetBits;
-    pI2CBus->AcknTimeout = 5;
-    pI2CBus->DriverPrivate.uval = i2c_reg;
-
-    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
-
-    *bus_ptr = pI2CBus;
-    return TRUE;
-}
-
 void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
 {
     MonPtr      mon = pScrn->monitor;
@@ -243,590 +159,6 @@ void RADEONSetSyncRangeFromEdid(ScrnInfo
     }
 }
 
-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);
-}
-
-
-RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    unsigned long DDCReg;
-    RADEONMonitorType MonType = MT_NONE;
-    xf86MonPtr* MonInfo = &output->MonInfo;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONDDCType DDCType = radeon_output->DDCType;
-    int i, j;
-
-    DDCReg = radeon_output->DDCReg;
-
-    /* Read and output monitor info using DDC2 over I2C bus */
-    if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK)) {
-	OUTREG(DDCReg, INREG(DDCReg) &
-	       (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
-
-	/* For some old monitors (like Compaq Presario FP500), we need
-	 * following process to initialize/stop DDC
-	 */
-	OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
-	for (j = 0; j < 3; j++) {
-	    OUTREG(DDCReg,
-		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
-	    usleep(13000);
-
-	    OUTREG(DDCReg,
-		   INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
-	    for (i = 0; i < 10; i++) {
-		usleep(15000);
-		if (INREG(DDCReg) & RADEON_GPIO_Y_1)
-		    break;
-	    }
-	    if (i == 10) continue;
-
-	    usleep(15000);
-
-	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
-	    usleep(15000);
-
-	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
-	    usleep(15000);
-	    OUTREG(DDCReg,
-		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
-	    usleep(15000);
-	    *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
-
-	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
-	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
-	    usleep(15000);
-	    OUTREG(DDCReg,
-		   INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
-	    for (i = 0; i < 5; i++) {
-		usleep(15000);
-		if (INREG(DDCReg) & RADEON_GPIO_Y_1)
-		    break;
-	    }
-	    usleep(15000);
-	    OUTREG(DDCReg,
-		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
-	    usleep(15000);
-
-	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
-	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
-	    usleep(15000);
-	    if(*MonInfo)  break;
-	}
-    } else if (radeon_output->pI2CBus && info->ddc2 && DDCReg == RADEON_LCD_GPIO_MASK) {
-         *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
-    } else {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
-	MonType = MT_NONE;
-    }
-
-    OUTREG(DDCReg, INREG(DDCReg) &
-	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
-
-    if (*MonInfo) {
-	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
-	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
-	    MonType = MT_LCD;
-	} else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		 (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) {
-	    MonType = MT_DFP;
-	} else if ((*MonInfo)->rawData[0x14] & 0x80) {	/* if it's digital */
-	    MonType = MT_DFP;
-	} else {
-	    MonType = MT_CRT;
-	}
-    } else MonType = MT_NONE;
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
-
-    return MonType;
-}
-
-void RADEONGetPanelInfoFromReg (xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
-    CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
-
-    radeon_output->PanelPwrDly = 200;
-    if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
-	radeon_output->PanelYRes = (fp_vert_stretch>>12) + 1;
-    } else {
-	radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
-    }
-    if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
-	radeon_output->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
-    } else {
-	radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
-    }
-    
-    if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
-	radeon_output->PanelXRes = 640;
-	radeon_output->PanelYRes = 480;
-    }
-
-    // move this to crtc function
-    if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
-           CARD32 ppll_div_sel, ppll_val;
-
-           ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
-	   RADEONPllErrataAfterIndex(info);
-	   ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
-           if ((ppll_val & 0x000707ff) == 0x1bb)
-		   goto noprobe;
-	   info->FeedbackDivider = ppll_val & 0x7ff;
-	   info->PostDivider = (ppll_val >> 16) & 0x7;
-	   info->RefDivider = info->pll.reference_div;
-	   info->UseBiosDividers = TRUE;
-
-           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                      "Existing panel PLL dividers will be used.\n");
-    }
- noprobe:
-
-    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-	       "Panel size %dx%d is derived, this may not be correct.\n"
-		   "If not, use PanelSize option to overwrite this setting\n",
-	       radeon_output->PanelXRes, radeon_output->PanelYRes);
-}
-
-
-/* BIOS may not have right panel size, we search through all supported
- * DDC modes looking for the maximum panel size.
- */
-void RADEONUpdatePanelSize(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int             j;
-    /* XXX: fixme */
-    xf86MonPtr      ddc  = pScrn->monitor->DDC;
-    DisplayModePtr  p;
-
-    // crtc should handle?
-    if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
-       return;
-
-    /* Go thru detailed timing table first */
-    for (j = 0; j < 4; j++) {
-	if (ddc->det_mon[j].type == 0) {
-	    struct detailed_timings *d_timings =
-		&ddc->det_mon[j].section.d_timings;
-           int match = 0;
-
-           /* If we didn't get a panel clock or guessed one, try to match the
-            * mode with the panel size. We do that because we _need_ a panel
-            * clock, or ValidateFPModes will fail, even when UseBiosDividers
-            * is set.
-            */
-           if (radeon_output->DotClock == 0 &&
-               radeon_output->PanelXRes == d_timings->h_active &&
-               radeon_output->PanelYRes == d_timings->v_active)
-               match = 1;
-
-           /* If we don't have a BIOS provided panel data with fixed dividers,
-            * check for a larger panel size
-            */
-	    if (radeon_output->PanelXRes < d_timings->h_active &&
-               radeon_output->PanelYRes < d_timings->v_active &&
-               !info->UseBiosDividers)
-               match = 1;
-
-             if (match) {
-		radeon_output->PanelXRes  = d_timings->h_active;
-		radeon_output->PanelYRes  = d_timings->v_active;
-		radeon_output->DotClock   = d_timings->clock / 1000;
-		radeon_output->HOverPlus  = d_timings->h_sync_off;
-		radeon_output->HSyncWidth = d_timings->h_sync_width;
-		radeon_output->HBlank     = d_timings->h_blanking;
-		radeon_output->VOverPlus  = d_timings->v_sync_off;
-		radeon_output->VSyncWidth = d_timings->v_sync_width;
-		radeon_output->VBlank     = d_timings->v_blanking;
-                radeon_output->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-                switch (d_timings->misc) {
-                case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break;
-                case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break;
-                case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break;
-                case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break;
-                }
-                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
-                           radeon_output->PanelXRes, radeon_output->PanelYRes);
-	    }
-	}
-    }
-
-    if (info->UseBiosDividers && radeon_output->DotClock != 0)
-       return;
-
-    /* Search thru standard VESA modes from EDID */
-    for (j = 0; j < 8; j++) {
-	if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) &&
-	    (radeon_output->PanelYRes < ddc->timings2[j].vsize)) {
-	    for (p = pScrn->monitor->Modes; p; p = p->next) {
-		if ((ddc->timings2[j].hsize == p->HDisplay) &&
-		    (ddc->timings2[j].vsize == p->VDisplay)) {
-		    float  refresh =
-			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
-		    if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
-			/* Is this good enough? */
-			radeon_output->PanelXRes  = ddc->timings2[j].hsize;
-			radeon_output->PanelYRes  = ddc->timings2[j].vsize;
-			radeon_output->HBlank     = p->HTotal - p->HDisplay;
-			radeon_output->HOverPlus  = p->HSyncStart - p->HDisplay;
-			radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart;
-			radeon_output->VBlank     = p->VTotal - p->VDisplay;
-			radeon_output->VOverPlus  = p->VSyncStart - p->VDisplay;
-			radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart;
-			radeon_output->DotClock   = p->Clock;
-                        radeon_output->Flags      = p->Flags;
-                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
-                                   radeon_output->PanelXRes, radeon_output->PanelYRes);
-		    }
-		}
-	    }
-	}
-    }
-}
-
-Bool RADEONGetLVDSInfo (xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    char* s;
-
-    if (!RADEONGetLVDSInfoFromBIOS(output))
-	RADEONGetPanelInfoFromReg(output);
-
-    if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
-	radeon_output->PanelPwrDly = 200;
-	if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
-	    RADEONGetPanelInfoFromReg(output);
-	}
-    }
-
-    /* The panel size we collected from BIOS may not be the
-     * maximum size supported by the panel.  If not, we update
-     * it now.  These will be used if no matching mode can be
-     * found from EDID data.
-     */
-    RADEONUpdatePanelSize(output);
-
-    if (radeon_output->DotClock == 0) {
-	RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-	DisplayModePtr  tmp_mode = NULL;
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "No valid timing info from BIOS.\n");
-	/* No timing information for the native mode,
-	   use whatever specified in the Modeline.
-	   If no Modeline specified, we'll just pick
-	   the VESA mode at 60Hz refresh rate which
-	   is likely to be the best for a flat panel.
-	*/
-	tmp_mode = pScrn->monitor->Modes;
-	while(tmp_mode) {
-	    if ((tmp_mode->HDisplay == radeon_output->PanelXRes) &&
-		(tmp_mode->VDisplay == radeon_output->PanelYRes)) {
-		    
-		float  refresh =
-		    (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
-		if ((abs(60.0 - refresh) < 1.0) ||
-		    (tmp_mode->type == 0)) {
-		    radeon_output->HBlank     = tmp_mode->HTotal - tmp_mode->HDisplay;
-		    radeon_output->HOverPlus  = tmp_mode->HSyncStart - tmp_mode->HDisplay;
-		    radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
-		    radeon_output->VBlank     = tmp_mode->VTotal - tmp_mode->VDisplay;
-		    radeon_output->VOverPlus  = tmp_mode->VSyncStart - tmp_mode->VDisplay;
-		    radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
-		    radeon_output->DotClock   = tmp_mode->Clock;
-		    radeon_output->Flags = 0;
-		    break;
-		}
-	    }
-	    tmp_mode = tmp_mode->next;
-	}
-	if ((radeon_output->DotClock == 0) && !output->MonInfo) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Panel size is not correctly detected.\n"
-		       "Please try to use PanelSize option for correct settings.\n");
-	    return FALSE;
-	}
-    }
-
-    return TRUE;
-}
-
-void RADEONGetTMDSInfo(xf86OutputPtr output)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int i;
-
-    for (i=0; i<4; i++) {
-        radeon_output->tmds_pll[i].value = 0;
-        radeon_output->tmds_pll[i].freq = 0;
-    }
-
-    if (RADEONGetTMDSInfoFromBIOS(output)) return;
-
-    for (i=0; i<4; i++) {
-        radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
-        radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
-    }
-}
-
 void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
@@ -1400,11 +732,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
 void RADEONInitDispBandwidth(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     DisplayModePtr mode1, mode2;
-    RADEONInfoPtr info2 = NULL;
-    xf86CrtcPtr crtc;
     int pixel_bytes2 = 0;
 
     mode1 = info->CurrentLayout.mode;
@@ -1432,10 +761,7 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
 
 void RADEONBlank(ScrnInfoPtr pScrn)
 {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     xf86OutputPtr output;
     xf86CrtcPtr crtc;
     int o, c;
@@ -1455,10 +781,7 @@ void RADEONBlank(ScrnInfoPtr pScrn)
 
 void RADEONUnblank(ScrnInfoPtr pScrn)
 {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     xf86OutputPtr output;
     xf86CrtcPtr crtc;
     int o, c;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b399736..925b8ee 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -93,6 +93,7 @@
 #include "xf86_ansic.h"		/* For xf86getsecs() */
 #include "xf86_OSproc.h"
 #include "xf86RAC.h"
+#include "xf86RandR12.h"
 #include "xf86Resources.h"
 #include "xf86cmap.h"
 #include "vbe.h"
@@ -429,6 +430,7 @@ struct RADEONInt10Save {
 static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
 static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
 
+#if 0
 static Bool
 RADEONCreateScreenResources (ScreenPtr pScreen)
 {
@@ -444,6 +446,7 @@ RADEONCreateScreenResources (ScreenPtr p
 
   return TRUE;
 }
+#endif
 
 RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
 {
@@ -538,8 +541,6 @@ static Bool RADEONGetRec(ScrnInfoPtr pSc
 /* Free our private RADEONInfoRec */
 static void RADEONFreeRec(ScrnInfoPtr pScrn)
 {
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-
     if (!pScrn || !pScrn->driverPrivate) return;
     xfree(pScrn->driverPrivate);
     pScrn->driverPrivate = NULL;
@@ -2488,7 +2489,6 @@ static Bool RADEONPreInitXv(ScrnInfoPtr 
 
 static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 {
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     int i;
 
@@ -2827,7 +2827,6 @@ fail:
            vgaHWFreeHWRec(pScrn);
 #endif
 
- fail2:
     if(info->MMIO) RADEONUnmapMMIO(pScrn);
     info->MMIO = NULL;
 
@@ -2842,11 +2841,9 @@ static void RADEONLoadPalette(ScrnInfoPt
 			      int *indices, LOCO *colors, VisualPtr pVisual)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int            i;
     int            index, j;
-    unsigned char  r, g, b;
     CARD16 lut_r[256], lut_g[256], lut_b[256];
     int c;
 
@@ -4032,7 +4029,6 @@ void RADEONRestoreCommonRegisters(ScrnIn
 	info->ChipFamily != CHIP_FAMILY_R200 &&
 	!IS_R300_VARIANT) {
 	CARD32        tmp;
-        RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
 	tmp = INREG(RADEON_DAC_CNTL2);
 	OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
@@ -4622,7 +4618,6 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
 void
 RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
 {
-    RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86CrtcPtr crtc = pRADEONEnt->pCrtc[crtc_num];
@@ -4640,11 +4635,7 @@ RADEONEnableOutputs(ScrnInfoPtr pScrn, i
 /* Write out state to define a new video mode */
 void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
-    RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    RADEONCrtcPrivatePtr pCRTC1 = pRADEONEnt->Controller[0];
-    RADEONCrtcPrivatePtr pCRTC2 = pRADEONEnt->Controller[1];
-    xf86OutputPtr output;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONRestoreMode(%p)\n", restore);
@@ -4924,8 +4915,6 @@ static void RADEONSavePalette(ScrnInfoPt
 /* Save state that defines current video mode */
 static void RADEONSaveMode(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
-
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONSaveMode(%p)\n", save);
 
@@ -5070,914 +5059,6 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 #endif
 }
 
-/* Define common registers for requested video mode */
-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;
-}
-
-/* XXX: fix me */
-static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    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);
-    }
-    /* FIXME: doesn't make sense, this just replaces the previous value... */
-    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
-			 RADEON_TV_DAC_NHOLD |
-			  RADEON_TV_DAC_STD_PS2);
-			  //			 info->tv_dac_adj);
-}
-
-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);
-
-    if (IsPrimary) {
-        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->fp2_gen_cntl   &= ~(R200_FP2_SOURCE_SEL_MASK | 
-                                      RADEON_FP2_DVO_EN |
-                                      RADEON_FP2_DVO_RATE_SEL_SDR);
-	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 | 
-                                      RADEON_FP2_DVO_RATE_SEL_SDR);
-            }
-    } else {
-        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->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->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR);
-            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_gen_cntl = info->SavedReg.lvds_gen_cntl;
-    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-    save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
-
-    if (IsPrimary)
-	save->lvds_gen_cntl &= ~RADEON_LVDS_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;
-
-    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;
-    }
-
-	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 (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 +
-				     0.5)) & 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 +
-						0.5)) & 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));
-}
-
-static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
-				  DisplayModePtr mode, BOOL IsPrimary)
-{
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    /*0x0028023;*/
-    RADEONInitTvDacCntl(pScrn, save);
-
-    if (IsPrimary) {
-	/*save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl | RADEON_CRTC2_CRT2_ON;*/
-        save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
-        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);
-            /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
-				    (RADEON_FP2_ON |
-				     RADEON_FP2_BLANK_EN |
-				     RADEON_FP2_DVO_EN);*/
-	} else {
-            save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
-        }
-    } else {
-            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
-        if (IS_R300_VARIANT) {
-            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
-            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 /*|
-				   RADEON_FP2_BLANK_EN |
-                                   RADEON_FP2_ON |
-                                   RADEON_FP2_DVO_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;*/
-        } else {
-            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
-            save->disp_hw_debug = info->SavedReg.disp_hw_debug &
-					~RADEON_CRT2_DISP1_SEL;
-        }
-    }
-}
-
-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 (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) {
-	if (crtc_num == 0)
-	    RADEONInitRMXRegisters(output, save, mode);
-	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
-    } else if (radeon_output->MonType == MT_DFP) {
-	if (crtc_num == 0)
-	    RADEONInitRMXRegisters(output, save, mode);
-	if (radeon_output->TMDSType == TMDS_INT) {
-	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
-	} else {
-	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
-	}
-    }
-}
-
-/* Define CRTC registers for requested video mode */
-Bool RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
-				  DisplayModePtr mode, int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    //RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    int    format;
-    int    hsync_start;
-    int    hsync_wid;
-    int    vsync_wid;
-    int i, Base;
-#ifdef XF86DRI
-    RADEONSAREAPrivPtr pSAREAPriv;
-    XF86DRISAREAPtr pSAREA;
-#endif
-
-    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->surface_cntl = 0;
-    save->disp_merge_cntl = info->SavedReg.disp_merge_cntl;
-    save->disp_merge_cntl &= ~RADEON_DISP_RGB_OFFSET_EN;
-
-#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 (pScrn->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
-
-    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;
-    if (hsync_wid > 0x3f) hsync_wid = 0x3f;
-    hsync_start = mode->CrtcHSyncStart - 8;
-
-    save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
-				  | (hsync_wid << 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;
-    if (vsync_wid > 0x1f) vsync_wid = 0x1f;
-
-    save->crtc_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
-				  | (vsync_wid << 16)
-				  | ((mode->Flags & V_NVSYNC)
-				     ? RADEON_CRTC_V_SYNC_POL
-				     : 0));
-
-    save->crtc_offset      = pScrn->fbOffset;
-    if (info->tilingEnabled) {
-       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;
-    }
-
-    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;
-
-    Base = pScrn->fbOffset;
-
-    if (info->tilingEnabled) {
-        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;
-    }
-
-    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;
-
-
-    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;
-}
-
-/* Define CRTC2 registers for requested video mode */
-Bool RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
-				     DisplayModePtr mode, int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    //RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    int    format;
-    int    hsync_start;
-    int    hsync_wid;
-    int    vsync_wid;
-    int i, Base;
-#ifdef XF86DRI
-    RADEONSAREAPrivPtr pSAREAPriv;
-    XF86DRISAREAPtr pSAREA;
-#endif
-
-    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;
-    if (hsync_wid > 0x3f) hsync_wid = 0x3f;
-    hsync_start = mode->CrtcHSyncStart - 8;
-
-    save->crtc2_h_sync_strt_wid = ((hsync_start & 0x1fff)
-				   | (hsync_wid << 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;
-    if (vsync_wid > 0x1f) vsync_wid = 0x1f;
-
-    save->crtc2_v_sync_strt_wid = (((mode->CrtcVSyncStart - 1) & 0xfff)
-				   | (vsync_wid << 16)
-				   | ((mode->Flags & V_NVSYNC)
-				      ? RADEON_CRTC2_V_SYNC_POL
-				      : 0));
-
-    /* It seems all fancy options apart from pflip can be safely disabled
-     */
-    save->crtc2_offset      = pScrn->fbOffset;
-    save->crtc2_offset_cntl &= RADEON_CRTC_OFFSET_FLIP_CNTL;
-    if (info->tilingEnabled) {
-       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;
-    }
-
-    save->crtc2_pitch  = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) +
-			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
-    save->crtc2_pitch |= save->crtc2_pitch << 16;
-
-    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;
-
-    Base = pScrn->fbOffset;
-
-    if (info->tilingEnabled) {
-        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;
-    }
-
-    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;
-
-    /* We must set SURFACE_CNTL properly on the second screen too */
-    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 (pScrn->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
- 
-    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 */
-void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
-				   RADEONSavePtr save, RADEONPLLPtr pll,
-				   double dot_clock)
-{
-    unsigned long  freq = dot_clock * 100;
-
-    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 (info->UseBiosDividers) {
-       save->ppll_ref_div = info->RefDivider;
-       save->ppll_div_3   = info->FeedbackDivider | (info->PostDivider << 16);
-       save->htotal_cntl  = 0;
-       return;
-    }
-
-    if (freq > pll->max_pll_freq)      freq = pll->max_pll_freq;
-    if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
-
-    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
-	save->pll_output_freq = post_div->divider * freq;
-
-	if (save->pll_output_freq >= pll->min_pll_freq
-	    && save->pll_output_freq <= pll->max_pll_freq) break;
-    }
-
-    if (!post_div->divider) {
-	save->pll_output_freq = freq;
-	post_div = &post_divs[0];
-    }
-
-    save->dot_clock_freq = freq;
-    save->feedback_div   = RADEONDiv(pll->reference_div
-				     * save->pll_output_freq,
-				     pll->reference_freq);
-    save->post_div       = post_div->divider;
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "dc=%ld, of=%ld, fd=%d, pd=%d\n",
-		   save->dot_clock_freq,
-		   save->pll_output_freq,
-		   save->feedback_div,
-		   save->post_div);
-
-    save->ppll_ref_div   = pll->reference_div;
-    save->ppll_div_3     = (save->feedback_div | (post_div->bitvalue << 16));
-    save->htotal_cntl    = 0;
-
-    save->vclk_cntl = (info->SavedReg.vclk_cntl &
-	    ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
-
-}
-
-/* Define PLL2 registers for requested video mode */
-void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
-				    RADEONPLLPtr pll, double dot_clock,
-				    int no_odd_postdiv)
-{
-    RADEONInfoPtr  info      = RADEONPTR(pScrn);
-    unsigned long  freq = dot_clock * 100;
-
-    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 (freq > pll->max_pll_freq)      freq = pll->max_pll_freq;
-    if (freq * 12 < pll->min_pll_freq) freq = pll->min_pll_freq / 12;
-
-    for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
-       /* Odd post divider value don't work properly on the second digital
-        * output
-        */
-       if (no_odd_postdiv && (post_div->divider & 1))
-           continue;
-	save->pll_output_freq_2 = post_div->divider * freq;
-	if (save->pll_output_freq_2 >= pll->min_pll_freq
-	    && save->pll_output_freq_2 <= pll->max_pll_freq) 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   = RADEONDiv(pll->reference_div
-				       * save->pll_output_freq_2,
-				       pll->reference_freq);
-    save->post_div_2       = post_div->divider;
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "dc=%ld, of=%ld, fd=%d, pd=%d\n",
-		   save->dot_clock_freq_2,
-		   save->pll_output_freq_2,
-		   save->feedback_div_2,
-		   save->post_div_2);
-
-    save->p2pll_ref_div    = pll->reference_div;
-    save->p2pll_div_0      = (save->feedback_div_2 |
-			      (post_div->bitvalue << 16));
-    save->htotal_cntl2     = 0;
-
-    save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
-			   ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
-			  RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
-
-}
-
 #if 0
 /* Define initial palette for requested video mode.  This doesn't do
  * anything for XFree86 4.0.
@@ -6327,7 +5408,6 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 	for (i = 0; i < xf86_config->num_crtc; i++)
 	{
 	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
-	    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 	    /* Mark that we'll need to re-set the mode for sure */
 	    memset(&crtc->mode, 0, sizeof(crtc->mode));
 	    if (!crtc->desiredMode.CrtcHDisplay) {
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index bc069ea..a7503a5 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -82,7 +82,6 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
 static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr  new   = NULL;
     char            stmp[32];
@@ -130,7 +129,6 @@ static DisplayModePtr RADEONFPNativeMode
 int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList)
 {
     ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr  last       = NULL;
     DisplayModePtr  new        = NULL;
@@ -265,12 +263,8 @@ DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr mode;
-    DisplayModePtr test;
     xf86MonPtr		    edid_mon;
     DisplayModePtr	    modes = NULL;
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 8ac43b2..99b6544 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -124,13 +124,33 @@ const char *OutputType[10] = {
     "Composite",
 };
 
+static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
+{
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_LEGACY*/
+    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RADEON*/
+    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV100*/
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS100*/
+    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV200*/
+    {{12000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS200*/
+    {{15000, 0xa1b}, {0xffffffff, 0xa3f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_R200*/
+    {{15500, 0x81b}, {0xffffffff, 0x83f}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV250*/
+    {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_RS300*/
+    {{13000, 0x400f4}, {15000, 0x400f7}, {0xffffffff, 0x40111}, {0, 0}}, /*CHIP_FAMILY_RV280*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R300*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R350*/
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV350*/
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RV380*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_R420*/
+    {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}},		/*CHIP_FAMILY_RV410*/ /* FIXME: just values from r420 used... */
+    {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}},	/*CHIP_FAMILY_RS400*/ /* FIXME: just values from rv380 used... */
+};
+
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
 
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONOutputPrivatePtr radeon_output;
     xf86OutputPtr output;
@@ -155,13 +175,356 @@ void RADEONPrintPortMap(ScrnInfoPtr pScr
 
 }
 
+static RADEONMonitorType
+RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    unsigned long DDCReg;
+    RADEONMonitorType MonType = MT_NONE;
+    xf86MonPtr* MonInfo = &output->MonInfo;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONDDCType DDCType = radeon_output->DDCType;
+    int i, j;
+
+    DDCReg = radeon_output->DDCReg;
+
+    /* Read and output monitor info using DDC2 over I2C bus */
+    if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK)) {
+	OUTREG(DDCReg, INREG(DDCReg) &
+	       (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
+
+	/* For some old monitors (like Compaq Presario FP500), we need
+	 * following process to initialize/stop DDC
+	 */
+	OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+	for (j = 0; j < 3; j++) {
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+	    usleep(13000);
+
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+	    for (i = 0; i < 10; i++) {
+		usleep(15000);
+		if (INREG(DDCReg) & RADEON_GPIO_Y_1)
+		    break;
+	    }
+	    if (i == 10) continue;
+
+	    usleep(15000);
+
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+	    usleep(15000);
+
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+	    usleep(15000);
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+	    usleep(15000);
+	    *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+	    usleep(15000);
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
+	    for (i = 0; i < 5; i++) {
+		usleep(15000);
+		if (INREG(DDCReg) & RADEON_GPIO_Y_1)
+		    break;
+	    }
+	    usleep(15000);
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
+	    usleep(15000);
+
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
+	    usleep(15000);
+	    if(*MonInfo)  break;
+	}
+    } else if (radeon_output->pI2CBus && info->ddc2 && DDCReg == RADEON_LCD_GPIO_MASK) {
+         *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
+    } else {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
+	MonType = MT_NONE;
+    }
+
+    OUTREG(DDCReg, INREG(DDCReg) &
+	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+
+    if (*MonInfo) {
+	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
+	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
+	    MonType = MT_LCD;
+	} else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+		 (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D)) {
+	    MonType = MT_DFP;
+	} else if ((*MonInfo)->rawData[0x14] & 0x80) {	/* if it's digital */
+	    MonType = MT_DFP;
+	} else {
+	    MonType = MT_CRT;
+	}
+    } else MonType = MT_NONE;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
+
+    return MonType;
+}
+
+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);
+}
+
 /* Primary Head (DVI or Laptop Int. panel)*/
 /* A ddc capable display connected on DVI port */
 /* Secondary Head (mostly VGA, can be DVI on some OEM boards)*/
 void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     
     if (radeon_output->MonType == MT_UNKNOWN) {
@@ -212,8 +575,6 @@ static RADEONMonitorType RADEONPortCheck
 static void
 radeon_dpms(xf86OutputPtr output, int mode)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
-
     switch(mode) {
     case DPMSModeOn:
 	RADEONEnableDisplay(output, TRUE);
@@ -241,10 +602,7 @@ radeon_restore(xf86OutputPtr restore)
 static int
 radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    DisplayModePtr m;
 
     if (radeon_output->type != OUTPUT_LVDS)
 	return MODE_OK;
@@ -293,6 +651,317 @@ 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);
+
+    if (IsPrimary) {
+        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+            save->fp2_gen_cntl   &= ~(R200_FP2_SOURCE_SEL_MASK | 
+                                      RADEON_FP2_DVO_EN |
+                                      RADEON_FP2_DVO_RATE_SEL_SDR);
+	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 | 
+                                      RADEON_FP2_DVO_RATE_SEL_SDR);
+            }
+    } else {
+        if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
+            save->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->fp2_gen_cntl &= ~(RADEON_FP2_DVO_RATE_SEL_SDR);
+            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_gen_cntl = info->SavedReg.lvds_gen_cntl;
+    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
+    save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+
+    if (IsPrimary)
+	save->lvds_gen_cntl &= ~RADEON_LVDS_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;
+
+    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;
+    }
+
+	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 (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 +
+				     0.5)) & 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 +
+						0.5)) & 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));
+}
+
+/* XXX: fix me */
+static void
+RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    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);
+    }
+    /* FIXME: doesn't make sense, this just replaces the previous value... */
+    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
+			 RADEON_TV_DAC_NHOLD |
+			  RADEON_TV_DAC_STD_PS2);
+			  //			 info->tv_dac_adj);
+}
+
+static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
+				  DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+
+    /*0x0028023;*/
+    RADEONInitTvDacCntl(pScrn, save);
+
+    if (IsPrimary) {
+	/*save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl | RADEON_CRTC2_CRT2_ON;*/
+        save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+        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);
+            /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
+				    (RADEON_FP2_ON |
+				     RADEON_FP2_BLANK_EN |
+				     RADEON_FP2_DVO_EN);*/
+	} else {
+            save->disp_hw_debug = info->SavedReg.disp_hw_debug | RADEON_CRT2_DISP1_SEL;
+        }
+    } else {
+            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+        if (IS_R300_VARIANT) {
+            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+            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 /*|
+				   RADEON_FP2_BLANK_EN |
+                                   RADEON_FP2_ON |
+                                   RADEON_FP2_DVO_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;*/
+        } else {
+            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+            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 (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) {
+	if (crtc_num == 0)
+	    RADEONInitRMXRegisters(output, save, mode);
+	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
+    } else if (radeon_output->MonType == MT_DFP) {
+	if (crtc_num == 0)
+	    RADEONInitRMXRegisters(output, save, mode);
+	if (radeon_output->TMDSType == TMDS_INT) {
+	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
+	} else {
+	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
+	}
+    }
+}
+
 static void
 radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		  DisplayModePtr adjusted_mode)
@@ -336,7 +1005,6 @@ radeon_detect(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     
     radeon_output->MonType = MT_UNKNOWN;
@@ -394,13 +1062,12 @@ radeon_destroy (xf86OutputPtr output)
 static void
 radeon_set_backlight_level(xf86OutputPtr output, int level)
 {
+#if 0
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     unsigned char * RADEONMMIO = info->MMIO;
     CARD32 lvds_gen_cntl;
 
-#if 0
     lvds_gen_cntl = INREG(RADEON_LVDS_GEN_CNTL);
     lvds_gen_cntl |= RADEON_LVDS_BL_MOD_EN;
     lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_LEVEL_MASK;
@@ -508,7 +1175,6 @@ static Bool
 radeon_set_property(xf86OutputPtr output, Atom property,
 		       RRPropertyValuePtr value)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     INT32 val;
 
@@ -613,6 +1279,315 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
     radeon_output->type = output;
 }
 
+static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
+{
+    ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned long  val;
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    /* Get the result */
+
+    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) { 
+        val = INREG(b->DriverPrivate.uval+4);
+        *Clock = (val & (1<<13)) != 0;
+        *data  = (val & (1<<12)) != 0;
+    } else {
+        val = INREG(b->DriverPrivate.uval);
+        *Clock = (val & RADEON_GPIO_Y_1) != 0;
+        *data  = (val & RADEON_GPIO_Y_0) != 0;
+    }
+}
+
+static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
+{
+    ScrnInfoPtr    pScrn      = xf86Screens[b->scrnIndex];
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned long  val;
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    if (b->DriverPrivate.uval == RADEON_LCD_GPIO_MASK) {
+        val = INREG(b->DriverPrivate.uval) & (CARD32)~((1<<12) | (1<<13));
+        val |= (Clock ? 0:(1<<13));
+        val |= (data ? 0:(1<<12));
+        OUTREG(b->DriverPrivate.uval, val);
+    } else {
+        val = INREG(b->DriverPrivate.uval) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
+        val |= (Clock ? 0:RADEON_GPIO_EN_1);
+        val |= (data ? 0:RADEON_GPIO_EN_0);
+        OUTREG(b->DriverPrivate.uval, val);
+   }
+    /* read back to improve reliability on some cards. */
+    val = INREG(b->DriverPrivate.uval);
+}
+
+static Bool
+RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
+{
+    I2CBusPtr pI2CBus;
+
+    pI2CBus = xf86CreateI2CBusRec();
+    if (!pI2CBus) return FALSE;
+
+    pI2CBus->BusName    = name;
+    pI2CBus->scrnIndex  = pScrn->scrnIndex;
+    pI2CBus->I2CPutBits = RADEONI2CPutBits;
+    pI2CBus->I2CGetBits = RADEONI2CGetBits;
+    pI2CBus->AcknTimeout = 5;
+    pI2CBus->DriverPrivate.uval = i2c_reg;
+
+    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
+
+    *bus_ptr = pI2CBus;
+    return TRUE;
+}
+
+static void
+RADEONGetPanelInfoFromReg (xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 fp_vert_stretch = INREG(RADEON_FP_VERT_STRETCH);
+    CARD32 fp_horz_stretch = INREG(RADEON_FP_HORZ_STRETCH);
+
+    radeon_output->PanelPwrDly = 200;
+    if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
+	radeon_output->PanelYRes = (fp_vert_stretch>>12) + 1;
+    } else {
+	radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
+    }
+    if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
+	radeon_output->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
+    } else {
+	radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
+    }
+    
+    if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
+	radeon_output->PanelXRes = 640;
+	radeon_output->PanelYRes = 480;
+    }
+
+    // move this to crtc function
+    if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
+           CARD32 ppll_div_sel, ppll_val;
+
+           ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
+	   RADEONPllErrataAfterIndex(info);
+	   ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
+           if ((ppll_val & 0x000707ff) == 0x1bb)
+		   goto noprobe;
+	   info->FeedbackDivider = ppll_val & 0x7ff;
+	   info->PostDivider = (ppll_val >> 16) & 0x7;
+	   info->RefDivider = info->pll.reference_div;
+	   info->UseBiosDividers = TRUE;
+
+           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                      "Existing panel PLL dividers will be used.\n");
+    }
+ noprobe:
+
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
+	       "Panel size %dx%d is derived, this may not be correct.\n"
+		   "If not, use PanelSize option to overwrite this setting\n",
+	       radeon_output->PanelXRes, radeon_output->PanelYRes);
+}
+
+/* BIOS may not have right panel size, we search through all supported
+ * DDC modes looking for the maximum panel size.
+ */
+static void
+RADEONUpdatePanelSize(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int             j;
+    /* XXX: fixme */
+    xf86MonPtr      ddc  = pScrn->monitor->DDC;
+    DisplayModePtr  p;
+
+    // crtc should handle?
+    if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
+       return;
+
+    /* Go thru detailed timing table first */
+    for (j = 0; j < 4; j++) {
+	if (ddc->det_mon[j].type == 0) {
+	    struct detailed_timings *d_timings =
+		&ddc->det_mon[j].section.d_timings;
+           int match = 0;
+
+           /* If we didn't get a panel clock or guessed one, try to match the
+            * mode with the panel size. We do that because we _need_ a panel
+            * clock, or ValidateFPModes will fail, even when UseBiosDividers
+            * is set.
+            */
+           if (radeon_output->DotClock == 0 &&
+               radeon_output->PanelXRes == d_timings->h_active &&
+               radeon_output->PanelYRes == d_timings->v_active)
+               match = 1;
+
+           /* If we don't have a BIOS provided panel data with fixed dividers,
+            * check for a larger panel size
+            */
+	    if (radeon_output->PanelXRes < d_timings->h_active &&
+               radeon_output->PanelYRes < d_timings->v_active &&
+               !info->UseBiosDividers)
+               match = 1;
+
+             if (match) {
+		radeon_output->PanelXRes  = d_timings->h_active;
+		radeon_output->PanelYRes  = d_timings->v_active;
+		radeon_output->DotClock   = d_timings->clock / 1000;
+		radeon_output->HOverPlus  = d_timings->h_sync_off;
+		radeon_output->HSyncWidth = d_timings->h_sync_width;
+		radeon_output->HBlank     = d_timings->h_blanking;
+		radeon_output->VOverPlus  = d_timings->v_sync_off;
+		radeon_output->VSyncWidth = d_timings->v_sync_width;
+		radeon_output->VBlank     = d_timings->v_blanking;
+                radeon_output->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
+                switch (d_timings->misc) {
+                case 0: radeon_output->Flags |= V_NHSYNC | V_NVSYNC; break;
+                case 1: radeon_output->Flags |= V_PHSYNC | V_NVSYNC; break;
+                case 2: radeon_output->Flags |= V_NHSYNC | V_PVSYNC; break;
+                case 3: radeon_output->Flags |= V_PHSYNC | V_PVSYNC; break;
+                }
+                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
+                           radeon_output->PanelXRes, radeon_output->PanelYRes);
+	    }
+	}
+    }
+
+    if (info->UseBiosDividers && radeon_output->DotClock != 0)
+       return;
+
+    /* Search thru standard VESA modes from EDID */
+    for (j = 0; j < 8; j++) {
+	if ((radeon_output->PanelXRes < ddc->timings2[j].hsize) &&
+	    (radeon_output->PanelYRes < ddc->timings2[j].vsize)) {
+	    for (p = pScrn->monitor->Modes; p; p = p->next) {
+		if ((ddc->timings2[j].hsize == p->HDisplay) &&
+		    (ddc->timings2[j].vsize == p->VDisplay)) {
+		    float  refresh =
+			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
+
+		    if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
+			/* Is this good enough? */
+			radeon_output->PanelXRes  = ddc->timings2[j].hsize;
+			radeon_output->PanelYRes  = ddc->timings2[j].vsize;
+			radeon_output->HBlank     = p->HTotal - p->HDisplay;
+			radeon_output->HOverPlus  = p->HSyncStart - p->HDisplay;
+			radeon_output->HSyncWidth = p->HSyncEnd - p->HSyncStart;
+			radeon_output->VBlank     = p->VTotal - p->VDisplay;
+			radeon_output->VOverPlus  = p->VSyncStart - p->VDisplay;
+			radeon_output->VSyncWidth = p->VSyncEnd - p->VSyncStart;
+			radeon_output->DotClock   = p->Clock;
+                        radeon_output->Flags      = p->Flags;
+                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
+                                   radeon_output->PanelXRes, radeon_output->PanelYRes);
+		    }
+		}
+	    }
+	}
+    }
+}
+
+static Bool
+RADEONGetLVDSInfo (xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    char* s;
+
+    if (!RADEONGetLVDSInfoFromBIOS(output))
+	RADEONGetPanelInfoFromReg(output);
+
+    if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
+	radeon_output->PanelPwrDly = 200;
+	if (sscanf (s, "%dx%d", &radeon_output->PanelXRes, &radeon_output->PanelYRes) != 2) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
+	    RADEONGetPanelInfoFromReg(output);
+	}
+    }
+
+    /* The panel size we collected from BIOS may not be the
+     * maximum size supported by the panel.  If not, we update
+     * it now.  These will be used if no matching mode can be
+     * found from EDID data.
+     */
+    RADEONUpdatePanelSize(output);
+
+    if (radeon_output->DotClock == 0) {
+	DisplayModePtr  tmp_mode = NULL;
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "No valid timing info from BIOS.\n");
+	/* No timing information for the native mode,
+	   use whatever specified in the Modeline.
+	   If no Modeline specified, we'll just pick
+	   the VESA mode at 60Hz refresh rate which
+	   is likely to be the best for a flat panel.
+	*/
+	tmp_mode = pScrn->monitor->Modes;
+	while(tmp_mode) {
+	    if ((tmp_mode->HDisplay == radeon_output->PanelXRes) &&
+		(tmp_mode->VDisplay == radeon_output->PanelYRes)) {
+		    
+		float  refresh =
+		    (float)tmp_mode->Clock * 1000.0 / tmp_mode->HTotal / tmp_mode->VTotal;
+		if ((abs(60.0 - refresh) < 1.0) ||
+		    (tmp_mode->type == 0)) {
+		    radeon_output->HBlank     = tmp_mode->HTotal - tmp_mode->HDisplay;
+		    radeon_output->HOverPlus  = tmp_mode->HSyncStart - tmp_mode->HDisplay;
+		    radeon_output->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
+		    radeon_output->VBlank     = tmp_mode->VTotal - tmp_mode->VDisplay;
+		    radeon_output->VOverPlus  = tmp_mode->VSyncStart - tmp_mode->VDisplay;
+		    radeon_output->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
+		    radeon_output->DotClock   = tmp_mode->Clock;
+		    radeon_output->Flags = 0;
+		    break;
+		}
+	    }
+
+	    tmp_mode = tmp_mode->next;
+
+	    if (tmp_mode == pScrn->monitor->Modes)
+		break;
+	}
+	if ((radeon_output->DotClock == 0) && !output->MonInfo) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Panel size is not correctly detected.\n"
+		       "Please try to use PanelSize option for correct settings.\n");
+	    return FALSE;
+	}
+    }
+
+    return TRUE;
+}
+
+static void
+RADEONGetTMDSInfo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int i;
+
+    for (i=0; i<4; i++) {
+        radeon_output->tmds_pll[i].value = 0;
+        radeon_output->tmds_pll[i].freq = 0;
+    }
+
+    if (RADEONGetTMDSInfoFromBIOS(output)) return;
+
+    for (i=0; i<4; i++) {
+        radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
+        radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+    }
+}
+
 void RADEONInitConnector(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
@@ -662,7 +1637,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     xf86OutputPtr output;
     char *optstr;
-    int i = 0, second = 0, max_mt = 5;
+    int i = 0;
 
 
     /* We first get the information about all connectors from BIOS.
@@ -731,8 +1706,10 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     }
 
     /* parse connector table option */
-    if (optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE)) {
-	if (sscanf(optstr, "%d,%d,%d,%d,%d,%d,%d,%d",
+    optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE);
+
+    if (optstr) {
+	if (sscanf(optstr, "%u,%d,%d,%u,%u,%d,%d,%u",
 		   &info->BiosConnector[0].DDCType,
 		   &info->BiosConnector[0].DACType,
 		   &info->BiosConnector[0].TMDSType,
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 5510d7b..d389e11 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2422,7 +2422,6 @@ RADEONDisplayVideo(
     int y_off;
     CARD32 scaler_src;
     CARD32 dot_clock;
-    DisplayModePtr overlay_mode;
     int is_rgb;
     int is_planar;
     int i;


More information about the xorg-commit mailing list