xf86-video-ati: Branch 'pci-rework' - 330 commits

George Sapountzis gsap7 at kemper.freedesktop.org
Tue Aug 28 06:05:48 PDT 2007


 .gitignore               |    1 
 configure.ac             |    8 
 man/ati.man              |    4 
 man/radeon.man           |  252 --
 src/Makefile.am          |   22 
 src/ati.c                |  601 ++++++-
 src/ati.h                |   72 
 src/atiadjust.c          |    2 
 src/atichip.c            |  508 -----
 src/atichip.h            |   71 
 src/aticonfig.c          |    2 
 src/aticonsole.c         |    8 
 src/atidri.c             |   11 
 src/atifillin.c          |   47 
 src/atifillin.h          |   41 
 src/atimach64probe.c     |   80 
 src/atimach64probe.h     |    3 
 src/atimach64xv.c        |    3 
 src/atimodule.c          |   40 
 src/atipreinit.c         |    6 
 src/atiprobe.c           |    1 
 src/atiscreen.c          |    2 
 src/ativalid.c           |    2 
 src/local_xf86Rename.h   |   23 
 src/r128_dri.c           |    4 
 src/r128_driver.c        |   36 
 src/r128_probe.c         |   33 
 src/r128_probe.h         |    2 
 src/radeon.h             |  337 ++-
 src/radeon_accel.c       |   38 
 src/radeon_accelfuncs.c  |   10 
 src/radeon_bios.c        | 1030 ++++++++++--
 src/radeon_common.h      |    7 
 src/radeon_commonfuncs.c |   14 
 src/radeon_crtc.c        | 1317 +++++++++++++++
 src/radeon_cursor.c      |  346 +---
 src/radeon_display.c     | 1873 +--------------------
 src/radeon_dri.c         |  204 +-
 src/radeon_driver.c      | 4022 +++++++++++++++--------------------------------
 src/radeon_exa.c         |   17 
 src/radeon_exa_funcs.c   |   23 
 src/radeon_mergedfb.c    | 2089 ------------------------
 src/radeon_mergedfb.h    |  121 -
 src/radeon_modes.c       |  679 +------
 src/radeon_output.c      | 2756 ++++++++++++++++++++++++++++++++
 src/radeon_probe.c       |   33 
 src/radeon_probe.h       |  134 +
 src/radeon_reg.h         |  180 +-
 src/radeon_tv.c          |  759 ++++++++
 src/radeon_tv.h          |   56 
 src/radeon_version.h     |    2 
 src/radeon_video.c       |  407 ++--
 src/radeon_video.h       |    6 
 src/theatre.c            |   15 
 src/theatre200.c         |   19 
 src/theatre_detect.c     |   15 
 56 files changed, 9261 insertions(+), 9133 deletions(-)

New commits:
diff-tree 7b38d9a1209f87255e5bb0aefe46a363ce4fb6ef (from parents)
Merge: 2e3d43af1e5077cc61dd8668551a6291368d9ed2 673f799729824f4439dd5f681f75dd5aab50947f
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Tue Aug 28 16:01:12 2007 +0300

    Merge branch 'master' into pci-rework
    
    Conflicts:
    
    	src/ati.c

diff --cc src/ati.c
index 803ac0b,423fd95..3f6cc0c
@@@ -57,10 -57,8 +57,10 @@@
  #include "config.h"
  #endif
  
 +#include "atipcirename.h"
 +
  #include "ati.h"
- #include "atichip.h"
+ #include "atimodule.h"
  #include "ativersion.h"
  #include "atimach64probe.h"
  
@@@ -99,20 -98,30 +100,30 @@@
      int       flags
  )
  {
-     pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo();
-     Bool        ProbeSuccess = FALSE;
+     pciVideoPtr pVideo;
+     pciVideoPtr *xf86PciVideoInfo;
      Bool        DoMach64 = FALSE;
      Bool        DoRage128 = FALSE, DoRadeon = FALSE;
-     int         i;
      ATIChipType Chip;
  
-     if (!(flags & PROBE_DETECT))
+     xf86PciVideoInfo = xf86GetPciVideoInfo();
+ 
+     if (xf86PciVideoInfo == NULL)
+         return FALSE;
+ 
+     while ((pVideo = *xf86PciVideoInfo++) != NULL)
      {
-         if (xf86MatchDevice(ATI_NAME, NULL) > 0)
 -        if ((pVideo->vendor != PCI_VENDOR_ATI) ||
 -            (pVideo->chipType == PCI_CHIP_MACH32))
++        if ((PCI_DEV_VENDOR_ID(pVideo) != PCI_VENDOR_ATI) ||
++            (PCI_DEV_DEVICE_ID(pVideo) == PCI_CHIP_MACH32))
+             continue;
+ 
+         /* Check for Rage128's, Radeon's and later adapters */
 -        Chip = ATIChipID(pVideo->chipType, pVideo->chipRev);
++        Chip = ATIChipID(PCI_DEV_DEVICE_ID(pVideo), PCI_DEV_REVISION(pVideo));
+         if (Chip <= ATI_CHIP_Mach64)
              DoMach64 = TRUE;
-         if (xf86MatchDevice(R128_NAME, NULL) > 0)
+         else if (Chip <= ATI_CHIP_Rage128)
              DoRage128 = TRUE;
-         if (xf86MatchDevice(RADEON_NAME, NULL) > 0)
+         else if (Chip <= ATI_CHIP_Radeon)
              DoRadeon = TRUE;
      }
  
diff-tree 673f799729824f4439dd5f681f75dd5aab50947f (from ad6f7ad1b2ccae0bc0a416b9b0ca22709c9d5199)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Tue Aug 28 00:42:30 2007 -0400

    RADEON: Update tv attributes immediately

diff --git a/src/radeon_display.c b/src/radeon_display.c
index ed45d79..fa80e10 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -373,6 +373,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
 	    tmp |= RADEON_TV_ON;
 	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
             tv_dac_change = 2;
+	    radeon_output->tv_on = TRUE;
 	}
     } else {
 	ErrorF("disable montype: %d\n", radeon_output->MonType);
@@ -431,6 +432,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
 	    tmp &= ~RADEON_TV_ON;
 	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
             tv_dac_change = 2;
+	    radeon_output->tv_on = FALSE;
 	}
     }
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 3003ead..4df2597 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1695,7 +1695,7 @@ radeon_create_resources(xf86OutputPtr ou
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the property */
-	s = "fill";
+	s = "full";
 	err = RRChangeOutputProperty(output->randr_output, rmx_atom,
 				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
 				     FALSE, FALSE);
@@ -1935,7 +1935,8 @@ radeon_set_property(xf86OutputPtr output
 	    return FALSE;
 
 	radeon_output->hSize = val;
-	/*RADEONUpdateHVPosition(output, NULL);*/
+	if (radeon_output->tv_on)
+	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 	return TRUE;
     } else if (property == tv_hpos_atom) {
 	if (value->type != XA_INTEGER ||
@@ -1949,7 +1950,8 @@ radeon_set_property(xf86OutputPtr output
 	    return FALSE;
 
 	radeon_output->hPos = val;
-	/*RADEONUpdateHVPosition(output, NULL);*/
+	if (radeon_output->tv_on)
+	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 	return TRUE;
     } else if (property == tv_vpos_atom) {
 	if (value->type != XA_INTEGER ||
@@ -1963,7 +1965,8 @@ radeon_set_property(xf86OutputPtr output
 	    return FALSE;
 
 	radeon_output->vPos = val;
-	/*RADEONUpdateHVPosition(output, NULL);*/
+	if (radeon_output->tv_on)
+	    RADEONUpdateHVPosition(output, &output->crtc->mode);
 	return TRUE;
     } else if (property == tv_std_atom) {
 	const char *s;
@@ -2471,6 +2474,7 @@ void RADEONInitConnector(xf86OutputPtr o
     }
 
     if (radeon_output->DACType == DAC_TVDAC) {
+	radeon_output->tv_on = FALSE;
 	RADEONGetTVDacAdjInfo(output);
     }
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 947bf88..b6ef59d 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -211,6 +211,7 @@ typedef struct _RADEONOutputPrivateRec {
     int               hSize;
     float             TVRefClk;
     int               SupportedTVStds;
+    Bool              tv_on;
     int               load_detection;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
diff-tree ad6f7ad1b2ccae0bc0a416b9b0ca22709c9d5199 (from 17e0f9e6cbfdb115034d327bd34d46339fd632b7)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Tue Aug 28 00:08:41 2007 -0400

    RADEON: remove the "default" tv_standard option

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 6bd0d95..3003ead 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1806,7 +1806,27 @@ radeon_create_resources(xf86OutputPtr ou
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the backlight property */
-	s = "default";
+	switch (radeon_output->default_tvStd) {
+	case TV_STD_PAL:
+	    s = "pal";
+	    break;
+	case TV_STD_PAL_M:
+	    s = "pal-m";
+	    break;
+	case TV_STD_PAL_60:
+	    s = "pal-60";
+	    break;
+	case TV_STD_NTSC_J:
+	    s = "ntsc-j";
+	    break;
+	case TV_STD_SCART_PAL:
+	    s = "scart-pal";
+	    break;
+	case TV_STD_NTSC:
+	default:
+	    s = "ntsc";
+	    break;
+	}
 	err = RRChangeOutputProperty(output->randr_output, tv_std_atom,
 				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
 				     FALSE, FALSE);
diff-tree 17e0f9e6cbfdb115034d327bd34d46339fd632b7 (from 42839fb5a8584196e7b18375bff6c426ed0347d9)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Mon Aug 27 23:59:03 2007 -0400

    RADEON: enable load detection for tvdac if output count for tvdac < 2

diff --git a/src/radeon.h b/src/radeon.h
index 53fb5f7..fa2bccd 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -799,6 +799,7 @@ typedef struct {
     Bool              crtc2_on;
 
     Bool              InternalTVOut;
+    int               tvdac_use_count;
 
     Rotation rotation;
     void (*PointerMoved)(int, int, int);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 78f451e..6bd0d95 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1637,14 +1637,13 @@ radeon_create_resources(xf86OutputPtr ou
 	if (err != 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRConfigureOutputProperty error, %d\n", err);
-	}
+	}	
 
 	if (radeon_output->DACType == DAC_PRIMARY)
 	    data = 1; /* primary dac, only drives vga */
 	else if (radeon_output->DACType == DAC_TVDAC &&
-		 info->IsMobility &&
-		 !info->IsIGP)
-	    data = 1; /* laptops with tv only on tvdac */
+		 info->tvdac_use_count < 2)
+	    data = 1; /* only one output with tvdac */
 	else
 	    data = 0; /* shared tvdac between vga/dvi/tv */
 
@@ -2428,9 +2427,8 @@ void RADEONInitConnector(xf86OutputPtr o
     if (radeon_output->DACType == DAC_PRIMARY)
 	radeon_output->load_detection = 1; /* primary dac, only drives vga */
     else if (radeon_output->DACType == DAC_TVDAC &&
-	     info->IsMobility &&
-	     !info->IsIGP)
-	radeon_output->load_detection = 1; /* laptops with tv only on tvdac */
+	     info->tvdac_use_count < 2)
+	radeon_output->load_detection = 1; /* only one output with tvdac */
     else
 	radeon_output->load_detection = 0; /* shared tvdac between vga/dvi/tv */
 
@@ -2617,8 +2615,12 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	}
     }
 
+    info->tvdac_use_count = 0;
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
+	    if (info->BiosConnector[i].DACType == DAC_TVDAC)
+		info->tvdac_use_count++;
+
 	    if (info->IsAtomBios) {
 		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
 		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
diff-tree 42839fb5a8584196e7b18375bff6c426ed0347d9 (from a5a1055d64ab4fa16bfb03a412ae6c4fe69ff65d)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Mon Aug 27 23:44:13 2007 -0400

    RADEON: make load detection an output attribute for analog outputs
    
    Since TV/VGA/DVI-I can share the TV DAC, we often get false detection
    of all inputs that share that DAC.  Make load detection an output
    attribute.  Enabled by default on primary dac and on cards where
    tv dac is (usually) dedicated to tv (non-IGP mobilities).

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index a5e1cc4..687e388 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -289,47 +289,47 @@ RADEONProbeOutputModes(xf86OutputPtr out
 #endif
     ErrorF("in RADEONProbeOutputModes\n");
 
-
-    if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
-	edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
-	xf86OutputSetEDID (output, edid_mon);
+    if (output->status == XF86OutputStatusConnected) {
+	if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
+	    edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
+	    xf86OutputSetEDID (output, edid_mon);
       
-	modes = xf86OutputGetEDIDModes (output);
-	return modes;
-    }
-    if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
-	modes = RADEONTVModes(output);
-	return modes;
-    }
-    if (radeon_output->type == OUTPUT_LVDS) {
-	/* okay we got DDC info */
-	if (output->MonInfo) {
-	    /* Debug info for now, at least */
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
-	    xf86PrintEDID(output->MonInfo);
+	    modes = xf86OutputGetEDIDModes (output);
+	    return modes;
+	}
+	if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+	    modes = RADEONTVModes(output);
+	    return modes;
+	}
+	if (radeon_output->type == OUTPUT_LVDS) {
+	    /* okay we got DDC info */
+	    if (output->MonInfo) {
+		/* Debug info for now, at least */
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
+		xf86PrintEDID(output->MonInfo);
 	
-	    modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
+		modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
 	
-	    for (mode = modes; mode != NULL; mode = mode->next) {
-		if (mode->Flags & V_DBLSCAN) {
-		    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
-			mode->status = MODE_CLOCK_RANGE;
+		for (mode = modes; mode != NULL; mode = mode->next) {
+		    if (mode->Flags & V_DBLSCAN) {
+			if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+			    mode->status = MODE_CLOCK_RANGE;
+		    }
 		}
-	    }
-	    xf86PruneInvalidModes(pScrn, &modes, TRUE);
+		xf86PruneInvalidModes(pScrn, &modes, TRUE);
 	
-	    /* do some physcial size stuff */
-	}
+		/* do some physcial size stuff */
+	    }
       
-	if (modes == NULL) {
-	    RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+	    if (modes == NULL) {
+		RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+	    }
 	}
     }
     
     if (modes) {
 	xf86ValidateModesUserConfig(pScrn, modes);
-	xf86PruneInvalidModes(pScrn, &modes,
-			      FALSE);
+	xf86PruneInvalidModes(pScrn, &modes, FALSE);
     }
 
     return modes;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 35c6cbe..78f451e 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -536,21 +536,29 @@ void RADEONConnectorFindMonitor(ScrnInfo
 
     if (radeon_output->MonType == MT_UNKNOWN) {
 	if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
-	    if (info->InternalTVOut)
-		radeon_output->MonType = radeon_detect_tv(pScrn);
+	    if (info->InternalTVOut) {
+		if (radeon_output->load_detection)
+		    radeon_output->MonType = radeon_detect_tv(pScrn);
+		else
+		    radeon_output->MonType = MT_NONE;
+	    }
 	} else {
 	    radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output);
 	    if (!radeon_output->MonType) {
 		if (radeon_output->type == OUTPUT_LVDS || radeon_output->type == OUTPUT_DVI)
 		    radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output);
 		if (!radeon_output->MonType) {
-		    if (radeon_output->DACType == DAC_PRIMARY)
-			radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
-		    else if (radeon_output->DACType == DAC_TVDAC) {
-			if (info->ChipFamily == CHIP_FAMILY_R200)
-			    radeon_output->MonType = radeon_detect_ext_dac(pScrn);
-			else
-			    radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
+		    if (radeon_output->DACType == DAC_PRIMARY) {
+			if (radeon_output->load_detection)
+			    radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
+		    } else if (radeon_output->DACType == DAC_TVDAC) {
+			if (radeon_output->load_detection) {
+			    if (info->ChipFamily == CHIP_FAMILY_R200)
+				radeon_output->MonType = radeon_detect_ext_dac(pScrn);
+			    else
+				radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
+			} else
+			    radeon_output->MonType = MT_NONE;
 		    }
 		}
 	    }
@@ -1577,6 +1585,7 @@ static Atom backlight_atom;
 static Atom tmds_pll_atom;
 static Atom rmx_atom;
 static Atom monitor_type_atom;
+static Atom load_detection_atom;
 static Atom tv_hsize_atom;
 static Atom tv_hpos_atom;
 static Atom tv_vpos_atom;
@@ -1617,6 +1626,37 @@ radeon_create_resources(xf86OutputPtr ou
 	}
     }
 
+    if (radeon_output->DACType == DAC_PRIMARY ||
+	radeon_output->DACType == DAC_TVDAC) {
+	load_detection_atom = MAKE_ATOM("load_detection");
+
+	range[0] = 0; /* off */
+	range[1] = 1; /* on */
+	err = RRConfigureOutputProperty(output->randr_output, load_detection_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+
+	if (radeon_output->DACType == DAC_PRIMARY)
+	    data = 1; /* primary dac, only drives vga */
+	else if (radeon_output->DACType == DAC_TVDAC &&
+		 info->IsMobility &&
+		 !info->IsIGP)
+	    data = 1; /* laptops with tv only on tvdac */
+	else
+	    data = 0; /* shared tvdac between vga/dvi/tv */
+
+	err = RRChangeOutputProperty(output->randr_output, load_detection_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
     if (radeon_output->type == OUTPUT_DVI &&
 	radeon_output->TMDSType == TMDS_INT) {
 	tmds_pll_atom = MAKE_ATOM("tmds_pll");
@@ -1803,6 +1843,19 @@ radeon_set_property(xf86OutputPtr output
 
 	radeon_set_backlight_level(output, val);
 
+    } else if (property == load_detection_atom) {
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < 0 || val > 1)
+	    return FALSE;
+
+	radeon_output->load_detection = val;
+
     } else if (property == rmx_atom) {
 	xf86CrtcPtr	crtc = output->crtc;
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
@@ -2358,6 +2411,7 @@ RADEONGetTVInfo(xf86OutputPtr output)
 void RADEONInitConnector(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int DDCReg = 0;
     char* name = (char*) DDCTypeName[radeon_output->DDCType];
@@ -2370,7 +2424,16 @@ void RADEONInitConnector(xf86OutputPtr o
     case DDC_LCD  : DDCReg = RADEON_LCD_GPIO_MASK; break;
     default: break;
     }
-    
+
+    if (radeon_output->DACType == DAC_PRIMARY)
+	radeon_output->load_detection = 1; /* primary dac, only drives vga */
+    else if (radeon_output->DACType == DAC_TVDAC &&
+	     info->IsMobility &&
+	     !info->IsIGP)
+	radeon_output->load_detection = 1; /* laptops with tv only on tvdac */
+    else
+	radeon_output->load_detection = 0; /* shared tvdac between vga/dvi/tv */
+
     if (DDCReg) {
 	radeon_output->DDCReg = DDCReg;
 	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 3bbda49..947bf88 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -211,6 +211,7 @@ typedef struct _RADEONOutputPrivateRec {
     int               hSize;
     float             TVRefClk;
     int               SupportedTVStds;
+    int               load_detection;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 #define RADEON_MAX_CRTC 2
diff-tree a5a1055d64ab4fa16bfb03a412ae6c4fe69ff65d (from a12e4aa01bf1c5723c3c791ff9bdc26eef21d5ea)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Mon Aug 27 22:42:22 2007 -0400

    RADEON: make tmds pll an output attribute
    
    sometimes the bios tmds plls are busted for certain
    monitors. sometimes the dirver tables are.  Let the user
    pick at run time.

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 1ef0ff4..b24c481 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -879,23 +879,6 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86Outp
 		}
 		return TRUE;
 	    }
-
-	    /* revision 4 has some problem as it appears in RV280, 
-	       comment it off for now, use default instead */ 
-	    /*    
-		  else if (RADEON_BIOS8(tmp) == 4) {
-		  int stride = 0;
-		  n = RADEON_BIOS8(tmp + 5) + 1;
-		  if (n > 4) n = 4;
-		  for (i=0; i<n; i++) {
-		  radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
-		  radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
-		  if (i == 0) stride += 10;
-		  else stride += 6;
-		  }
-		  return TRUE;
-		  }
-	    */  
 	}
     }
     return FALSE;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index c2b749a..35c6cbe 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -152,6 +152,7 @@ static RADEONMonitorType radeon_detect_t
 static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
 static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
 static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
+static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output);
 
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
@@ -1009,6 +1010,15 @@ radeon_mode_set(xf86OutputPtr output, Di
     xf86CrtcPtr	crtc = output->crtc;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
+    if (radeon_output->type == OUTPUT_DVI &&
+	radeon_output->TMDSType == TMDS_INT) {
+	if (radeon_output->tmds_pll_table == TMDS_PLL_BIOS) {
+	    if (!RADEONGetTMDSInfoFromBIOS(output))
+		RADEONGetTMDSInfoFromTable(output);
+	} else
+	    RADEONGetTMDSInfoFromTable(output);
+    }
+
     RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
 
     if (radeon_crtc->crtc_id == 0)
@@ -1564,6 +1574,7 @@ radeon_set_backlight_level(xf86OutputPtr
 }
 
 static Atom backlight_atom;
+static Atom tmds_pll_atom;
 static Atom rmx_atom;
 static Atom monitor_type_atom;
 static Atom tv_hsize_atom;
@@ -1606,6 +1617,32 @@ radeon_create_resources(xf86OutputPtr ou
 	}
     }
 
+    if (radeon_output->type == OUTPUT_DVI &&
+	radeon_output->TMDSType == TMDS_INT) {
+	tmds_pll_atom = MAKE_ATOM("tmds_pll");
+
+	err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom,
+					FALSE, FALSE, FALSE, 0, NULL);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	/* Set the current value of the property */
+#if defined(__powerpc__)
+	s = "driver";
+#else
+	s = "bios";
+#endif
+	err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom,
+				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+				     FALSE, FALSE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+
+    }
+
     /* RMX control - fullscreen, centered, keep ratio */
     /* actually more of a crtc property as only crtc1 has rmx */
     if (radeon_output->type == OUTPUT_LVDS ||
@@ -1785,6 +1822,19 @@ radeon_set_property(xf86OutputPtr output
 	} else {
 	    return FALSE;
 	}
+    } else if (property == tmds_pll_atom) {
+	const char *s;
+	if (value->type != XA_STRING || value->format != 8)
+	    return FALSE;
+	s = (char*)value->data;
+	if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) {
+	    radeon_output->tmds_pll_table = TMDS_PLL_BIOS;
+	    return TRUE;
+	} else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) {
+	    radeon_output->tmds_pll_table = TMDS_PLL_DRIVER;
+	    return TRUE;
+	}
+	return FALSE;
     } else if (property == monitor_type_atom) {
 	const char *s;
 	if (value->type != XA_STRING || value->format != 8)
@@ -2256,7 +2306,7 @@ RADEONGetLVDSInfo (xf86OutputPtr output)
 }
 
 static void
-RADEONGetTMDSInfo(xf86OutputPtr output)
+RADEONGetTMDSInfoFromTable(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -2264,16 +2314,26 @@ RADEONGetTMDSInfo(xf86OutputPtr output)
     int i;
 
     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;
+    }
+}
+
+static void
+RADEONGetTMDSInfo(xf86OutputPtr output)
+{
+    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;
-    }
+    RADEONGetTMDSInfoFromTable(output);
+
 }
 
 static void
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index d79e7ad..3bbda49 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -122,6 +122,12 @@ typedef enum
     DVI_ANALOG
 } RADEONDviType;
 
+typedef enum
+{
+    TMDS_PLL_BIOS,
+    TMDS_PLL_DRIVER
+} RADEONTMDSPllType;
+
 typedef struct {
     CARD32 freq;
     CARD32 value;
@@ -196,6 +202,7 @@ typedef struct _RADEONOutputPrivateRec {
     int               PanelPwrDly;
     int               DotClock;
     RADEONTMDSPll     tmds_pll[4];
+    RADEONTMDSPllType tmds_pll_table;
     /* TV out */
     TVStd             default_tvStd;
     TVStd             tvStd;
diff-tree a12e4aa01bf1c5723c3c791ff9bdc26eef21d5ea (from d43596e5f5d7c60f96b57bc3e743a9b40eb7109d)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sun Aug 26 18:51:29 2007 -0400

    Bump for new release

diff --git a/configure.ac b/configure.ac
index cdc6377..0c413c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-ati],
-        6.7.191,
+        6.7.192,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-ati)
 
diff-tree d43596e5f5d7c60f96b57bc3e743a9b40eb7109d (from 47eb3327c258bb0cfd9a1d5677624b9988a39057)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sun Aug 26 18:07:50 2007 -0400

    RADEON: Fix rotation.  works now

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 026cd8a..e976e2c 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -188,7 +188,7 @@ RADEONInitCrtcBase(xf86CrtcPtr crtc, RAD
 #endif
 	save->crtc_offset_cntl = 0;
 
-    if (info->tilingEnabled) {
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
        if (IS_R300_VARIANT)
           save->crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
 				     R300_CRTC_MICRO_TILE_BUFFER_DIS |
@@ -207,7 +207,7 @@ RADEONInitCrtcBase(xf86CrtcPtr crtc, RAD
 
     Base = pScrn->fbOffset;
 
-    if (info->tilingEnabled) {
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
         if (IS_R300_VARIANT) {
 	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
 	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
@@ -249,6 +249,10 @@ RADEONInitCrtcBase(xf86CrtcPtr crtc, RAD
        Base += offset;
     }
 
+    if (crtc->rotatedData != NULL) {
+	Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
+    }
+
     Base &= ~7;                 /* 3 lower bits are always 0 */
 
 
@@ -419,7 +423,7 @@ RADEONInitCrtc2Base(xf86CrtcPtr crtc, RA
 #endif
 	save->crtc2_offset_cntl = 0;
 
-    if (info->tilingEnabled) {
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
        if (IS_R300_VARIANT)
           save->crtc2_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
 				      R300_CRTC_MICRO_TILE_BUFFER_DIS |
@@ -438,7 +442,7 @@ RADEONInitCrtc2Base(xf86CrtcPtr crtc, RA
 
     Base = pScrn->fbOffset;
 
-    if (info->tilingEnabled) {
+    if (info->tilingEnabled && (crtc->rotatedData == NULL)) {
         if (IS_R300_VARIANT) {
 	/* On r300/r400 when tiling is enabled crtc_offset is set to the address of
 	 * the surface.  the x/y offsets are handled by the X_Y tile reg for each crtc
@@ -480,6 +484,10 @@ RADEONInitCrtc2Base(xf86CrtcPtr crtc, RA
        Base += offset;
     }
 
+    if (crtc->rotatedData != NULL) {
+	Base = pScrn->fbOffset + (char *)crtc->rotatedData - (char *)info->FB;
+    }
+
     Base &= ~7;                 /* 3 lower bits are always 0 */
 
 #ifdef XF86DRI
@@ -560,7 +568,7 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
 				      ? RADEON_CRTC2_V_SYNC_POL
 				      : 0));
 
-    save->crtc2_pitch  = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) +
+    save->crtc2_pitch  = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
 			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
     save->crtc2_pitch |= save->crtc2_pitch << 16;
 
diff-tree 47eb3327c258bb0cfd9a1d5677624b9988a39057 (from f36720377737210c985b196d9a988efdd767f1c7)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sun Aug 26 15:43:22 2007 -0400

    RADEON: minor tweak to tv out

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index c5917bc..3a26a0a 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -343,7 +343,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
 	                       | RADEON_SYNC_TIP_LEVEL
 	                       | RADEON_YFLT_EN
 	                       | RADEON_UVFLT_EN
-	                       | (2 << RADEON_CY_FILT_BLEND_SHIFT);
+	                       | (6 << RADEON_CY_FILT_BLEND_SHIFT);
 
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J) {
diff-tree f36720377737210c985b196d9a988efdd767f1c7 (from f2b13f1457bf860b075310d3962254be0ed7bea3)
Author: Alex Deucher <alex at samba.(none)>
Date:   Sun Aug 26 14:13:06 2007 -0400

    RADEON: fix depth 16 palette for real this time

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 6a4116d..026cd8a 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -103,7 +103,7 @@ radeon_crtc_dpms(xf86CrtcPtr crtc, int m
     }
   
     if (mode != DPMSModeOff)
-	radeon_crtc_load_lut(crtc);  
+	radeon_crtc_load_lut(crtc);
 }
 
 static Bool
@@ -911,21 +911,8 @@ void radeon_crtc_load_lut(xf86CrtcPtr cr
 
     PAL_SELECT(radeon_crtc->crtc_id);
 
-    if (pScrn->depth == 15) {
-	for (i = 0; i < 32; i++) {
-	    OUTPAL(i * 8, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
-	}
-    } else if (pScrn->depth == 16) {
-	for (i = 0; i < 64; i++) {
-	    OUTPAL(i * 4, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
-	    if (i <= 31) {
-		OUTPAL(i * 8, radeon_crtc->lut_r[i + 64], radeon_crtc->lut_g[i + 64], radeon_crtc->lut_b[i + 64]);
-	    }
-	}
-    } else {
-	for (i = 0; i < 256; i++) {
-	    OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
-	}
+    for (i = 0; i < 256; i++) {
+	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
     }
 
 }
@@ -937,17 +924,19 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
 {
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     ScrnInfoPtr		pScrn = crtc->scrn;
-    int i;
+    int i, j;
 
     if (pScrn->depth == 16) {
 	for (i = 0; i < 64; i++) {
-	    radeon_crtc->lut_r[i] = red[i/2] >> 8;
-	    radeon_crtc->lut_g[i] = green[i] >> 8;
-	    radeon_crtc->lut_b[i] = blue[i/2] >> 8;
 	    if (i <= 31) {
-		radeon_crtc->lut_r[i + 64] = red[i] >> 8;
-		radeon_crtc->lut_g[i + 64] = green[(i * 2) + 1] >> 8;
-		radeon_crtc->lut_b[i + 64] = blue[i] >> 8;
+		for (j = 0; j < 8; j++) {
+		    radeon_crtc->lut_r[i * 8 + j] = red[i] >> 8;
+		    radeon_crtc->lut_b[i * 8 + j] = blue[i] >> 8;
+		}
+	    }
+
+	    for (j = 0; j < 4; j++) {
+		radeon_crtc->lut_g[i * 4 + j] = green[i] >> 8;
 	    }
 	}
     } else {
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e445b9e..158e1e4 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2856,7 +2856,7 @@ static void RADEONLoadPalette(ScrnInfoPt
 	  case 16:
 	      for (i = 0; i < numColors; i++) {
 		  index = indices[i];
-		  
+
 		  if (i <= 31) {
 		      for (j = 0; j < 8; j++) {
 			  lut_r[index * 8 + j] = colors[index].red << 8;
@@ -2874,7 +2874,7 @@ static void RADEONLoadPalette(ScrnInfoPt
 		  lut_r[index] = colors[index].red << 8;
 		  lut_g[index] = colors[index].green << 8;
 		  lut_b[index] = colors[index].blue << 8;
-	      } 
+	      }
 	      break;
 	  }
 
diff-tree f2b13f1457bf860b075310d3962254be0ed7bea3 (from 5d044b9f74c7aa7e12f2822896fed881e2ca9d19)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sun Aug 26 13:27:19 2007 -0400

    RADEON: Only update pixclks_cntl when updating tv routing
    
    No need to re-set all of the pll2 stuff

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index d42e482..6a4116d 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -752,6 +752,13 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScr
 }
 
 static void
+radeon_update_tv_routing(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    /* pixclks_cntl controls tv clock routing */
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
+}
+
+static void
 radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode, int x, int y)
 {
@@ -867,7 +874,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 
     /* pixclks_cntl handles tv-out clock routing */
     if (update_tv_routing)
-	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
+	radeon_update_tv_routing(pScrn, &info->ModeReg);
 
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
diff-tree 5d044b9f74c7aa7e12f2822896fed881e2ca9d19 (from 3fd2d22a02812d5f86cdc1c9503f48362b0c362b)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sat Aug 25 21:03:08 2007 -0400

    RADEON: fix crtc clipping for Xv

diff --git a/src/radeon_video.c b/src/radeon_video.c
index 5cbe9fc..271f7fe 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1562,7 +1562,7 @@ RADEONSetupImageVideo(ScreenPtr pScreen)
 	return NULL;
 
     adapt->type = XvWindowMask | XvInputMask | XvImageMask;
-    adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+    adapt->flags = VIDEO_OVERLAID_IMAGES /*| VIDEO_CLIP_TO_VIEWPORT*/;
     adapt->name = "ATI Radeon Video Overlay";
     adapt->nEncodings = 1;
     adapt->pEncodings = &DummyEncoding;
@@ -3330,8 +3330,8 @@ RADEONInitOffscreenImages(ScreenPtr pScr
 	return;
 
     offscreenImages[0].image = &Images[0];
-    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES |
-			       VIDEO_CLIP_TO_VIEWPORT;
+    offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES /*|
+			       VIDEO_CLIP_TO_VIEWPORT*/;
     offscreenImages[0].alloc_surface = RADEONAllocateSurface;
     offscreenImages[0].free_surface = RADEONFreeSurface;
     offscreenImages[0].display = RADEONDisplaySurface;
diff-tree 3fd2d22a02812d5f86cdc1c9503f48362b0c362b (from 3469e1aa08792890fa6a5c72da52a1992a0b382c)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Sat Aug 25 17:37:35 2007 -0400

    RADEON: remove fbdev option
    
    FBDev support is currently broken, and it not really compatible
    with randr

diff --git a/man/radeon.man b/man/radeon.man
index 8423cc9..88665bf 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -150,14 +150,6 @@ affects the "true" overlay via xv, it wo
 .br
 The default value is either 1536 (for most chips) or 1920.
 .TP
-.BI "Option \*qUseFBDev\*q \*q" boolean \*q
-Enable or disable use of an OS\-specific framebuffer device interface
-(which is not supported on all OSs).  MergedFB does not work when this
-option is in use.  See fbdevhw(__drivermansuffix__) for further information. 
-.br
-The default is
-.B off.
-.TP
 .BI "Option \*qAGPMode\*q \*q" integer \*q
 Set AGP data transfer rate.
 (used only when DRI is enabled)
diff --git a/src/radeon.h b/src/radeon.h
index 6f880b8..53fb5f7 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -123,7 +123,6 @@ typedef enum {
 #endif
     OPTION_DDC_MODE,
     OPTION_IGNORE_EDID,
-    OPTION_FBDEV,
     OPTION_DISP_PRIORITY,
     OPTION_PANEL_SIZE,
     OPTION_MIN_DOTCLOCK,
@@ -437,8 +436,6 @@ typedef struct {
     RADEONChipFamily  ChipFamily;
     RADEONErrata      ChipErrata;
 
-    Bool              FBDev;
-
     unsigned long     LinearAddr;       /* Frame buffer physical address     */
     unsigned long     MMIOAddr;         /* MMIO region physical address      */
     unsigned long     BIOSAddr;         /* BIOS physical address             */
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 3ee7760..d42e482 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -36,7 +36,6 @@
 /* X and server generic header files */
 #include "xf86.h"
 #include "xf86_OSproc.h"
-#include "fbdevhw.h"
 #include "vgaHW.h"
 #include "xf86Modes.h"
 
diff --git a/src/radeon_display.c b/src/radeon_display.c
index ed20409..ed45d79 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -36,7 +36,6 @@
 /* X and server generic header files */
 #include "xf86.h"
 #include "xf86_OSproc.h"
-#include "fbdevhw.h"
 #include "vgaHW.h"
 #include "xf86Modes.h"
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a111e0d..e445b9e 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -98,11 +98,10 @@
 #include "xf86cmap.h"
 #include "vbe.h"
 
-				/* fbdevhw * vgaHW definitions */
+				/* vgaHW definitions */
 #ifdef WITH_VGAHW
 #include "vgaHW.h"
 #endif
-#include "fbdevhw.h"
 
 #define DPMS_SERVER
 #include <X11/extensions/dpms.h>
@@ -159,7 +158,6 @@ static const OptionInfoRec RADEONOptions
 #endif
     { OPTION_DDC_MODE,       "DDCMode",          OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_IGNORE_EDID,    "IgnoreEDID",       OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_FBDEV,          "UseFBDev",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DISP_PRIORITY,  "DisplayPriority",  OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_PANEL_SIZE,     "PanelSize",        OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_MIN_DOTCLOCK,   "ForceMinDotClock", OPTV_FREQ,    {0}, FALSE },
@@ -208,34 +206,6 @@ static const char *vgahwSymbols[] = {
 };
 #endif
 
-static const char *fbdevHWSymbols[] = {
-    "fbdevHWInit",
-    "fbdevHWUseBuildinMode",
-
-    "fbdevHWGetVidmem",
-
-    "fbdevHWDPMSSet",
-
-    /* colormap */
-    "fbdevHWLoadPalette",
-    /* ScrnInfo hooks */
-    "fbdevHWAdjustFrame",
-    "fbdevHWEnterVT",
-    "fbdevHWLeaveVT",
-    "fbdevHWModeInit",
-    "fbdevHWRestore",
-    "fbdevHWSave",
-    "fbdevHWSwitchMode",
-    "fbdevHWValidModeWeak",
-
-    "fbdevHWMapMMIO",
-    "fbdevHWMapVidmem",
-    "fbdevHWUnmapMMIO",
-    "fbdevHWUnmapVidmem",
-
-    NULL
-};
-
 static const char *ddcSymbols[] = {
     "xf86PrintEDID",
     "xf86DoEDID_DDC1",
@@ -396,7 +366,6 @@ void RADEONLoaderRefSymLists(void)
 			  drmSymbols,
 			  driSymbols,
 #endif
-			  fbdevHWSymbols,
 			  vbeSymbols,
 			  int10Symbols,
 			  i2cSymbols,
@@ -553,15 +522,11 @@ static Bool RADEONMapMMIO(ScrnInfoPtr pS
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-    if (info->FBDev) {
-	info->MMIO = fbdevHWMapMMIO(pScrn);
-    } else {
-	info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
-				   VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
-				   info->PciTag,
-				   info->MMIOAddr,
-				   info->MMIOSize);
-    }
+    info->MMIO = xf86MapPciMem(pScrn->scrnIndex,
+			       VIDMEM_MMIO | VIDMEM_READSIDEEFFECT,
+			       info->PciTag,
+			       info->MMIOAddr,
+			       info->MMIOSize);
 
     if (!info->MMIO) return FALSE;
     return TRUE;
@@ -574,11 +539,8 @@ static Bool RADEONUnmapMMIO(ScrnInfoPtr 
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-    if (info->FBDev)
-	fbdevHWUnmapMMIO(pScrn);
-    else {
-	xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
-    }
+    xf86UnMapVidMem(pScrn->scrnIndex, info->MMIO, info->MMIOSize);
+
     info->MMIO = NULL;
     return TRUE;
 }
@@ -588,17 +550,13 @@ static Bool RADEONMapFB(ScrnInfoPtr pScr
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-    if (info->FBDev) {
-	info->FB = fbdevHWMapVidmem(pScrn);
-    } else {
-	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
-	info->FB = xf86MapPciMem(pScrn->scrnIndex,
-				 VIDMEM_FRAMEBUFFER,
-				 info->PciTag,
-				 info->LinearAddr,
-				 info->FbMapSize);
-    }
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
+    info->FB = xf86MapPciMem(pScrn->scrnIndex,
+			     VIDMEM_FRAMEBUFFER,
+			     info->PciTag,
+			     info->LinearAddr,
+			     info->FbMapSize);
 
     if (!info->FB) return FALSE;
     return TRUE;
@@ -609,10 +567,7 @@ static Bool RADEONUnmapFB(ScrnInfoPtr pS
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-    if (info->FBDev)
-	fbdevHWUnmapVidmem(pScrn);
-    else
-	xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
+    xf86UnMapVidMem(pScrn->scrnIndex, info->FB, info->FbMapSize);
     info->FB = NULL;
     return TRUE;
 }
@@ -1211,8 +1166,7 @@ static void RADEONInitMemoryMap(ScrnInfo
     }
 #endif
 
-    /* We won't try to change MC_FB_LOCATION when using fbdev */
-    if (!info->FBDev) {
+    {
 	if (info->IsIGP)
 	    info->mc_fb_location = INREG(RADEON_NB_TOM);
 	else
@@ -1380,9 +1334,7 @@ static Bool RADEONPreInitVRAM(ScrnInfoPt
     MessageType    from = X_PROBED;
     CARD32         accessible, bar_size;
 
-    if (info->FBDev)
-	pScrn->videoRam      = fbdevHWGetVidmem(pScrn) / 1024;
-    else if ((info->IsIGP)) {
+    if ((info->IsIGP)) {
         CARD32 tom = INREG(RADEON_NB_TOM);
 
 	pScrn->videoRam = (((tom >> 16) -
@@ -2293,12 +2245,7 @@ static void RADEONPreInitColorTiling(Scr
     }
 #endif /* XF86DRI */
 
-    if ((info->allowColorTiling) && (info->FBDev)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "Color tiling not supported with UseFBDev option\n");
-	info->allowColorTiling = FALSE;
-    }
-    else if (info->allowColorTiling) {
+    if (info->allowColorTiling) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling enabled by default\n");
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling disabled\n");
@@ -2715,30 +2662,8 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 	"X server will %skeep DPI constant for all screen sizes\n",
 	info->constantDPI ? "" : "not ");
 
-    if (xf86ReturnOptValBool(info->Options, OPTION_FBDEV, FALSE)) {
-	/* check for Linux framebuffer device */
-
-	if (xf86LoadSubModule(pScrn, "fbdevhw")) {
-	    xf86LoaderReqSymLists(fbdevHWSymbols, NULL);
-
-	    if (fbdevHWInit(pScrn, info->PciInfo, NULL)) {
-		pScrn->ValidMode     = fbdevHWValidModeWeak();
-		info->FBDev = TRUE;
-		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-			   "Using framebuffer device\n");
-	    } else {
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			   "fbdevHWInit failed, not using framebuffer device\n");
-	    }
-	} else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Couldn't load fbdevhw module, not using framebuffer device\n");
-	}
-    }
-
-    if (!info->FBDev)
-	if (!RADEONPreInitInt10(pScrn, &pInt10))
-	    goto fail;
+    if (!RADEONPreInitInt10(pScrn, &pInt10))
+	goto fail;
 
     RADEONPostInt10Check(pScrn, int10_save);
 
@@ -2906,9 +2831,7 @@ static void RADEONLoadPalette(ScrnInfoPt
     if (info->accelOn && pScrn->pScreen)
         RADEON_SYNC(info, pScrn);
 
-    if (info->FBDev) {
-	fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual);
-    } else {
+    {
 
       for (c = 0; c < xf86_config->num_crtc; c++) {
 	  xf86CrtcPtr crtc = xf86_config->crtc[c];
@@ -3365,6 +3288,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int            hasDRI = 0;
+    int i;
 #ifdef RENDER
     int            subPixelOrder = SubPixelUnknown;
     char*          s;
@@ -3465,11 +3389,11 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     /* empty the surfaces */
     unsigned char *RADEONMMIO = info->MMIO;
-    unsigned int i;
-    for (i = 0; i < 8; i++) {
-	OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0);
-	OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0);
-	OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0);
+    unsigned int j;
+    for (j = 0; j < 8; j++) {
+	OUTREG(RADEON_SURFACE0_INFO + 16 * j, 0);
+	OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * j, 0);
+	OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * j, 0);
     }
 
 #ifdef XF86DRI
@@ -3642,35 +3566,22 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 #endif
 
     pScrn->vtSema = TRUE;
-    if (info->FBDev) {
-	unsigned char *RADEONMMIO = info->MMIO;
 
-	if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) return FALSE;
-	pScrn->displayWidth = fbdevHWGetLineLength(pScrn)
-		/ info->CurrentLayout.pixel_bytes;
-	RADEONSaveMemMapRegisters(pScrn, &info->ModeReg);
-	info->fbLocation = (info->ModeReg.mc_fb_location & 0xffff) << 16;
-	info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
-	info->ModeReg.surface_cntl &= ~RADEON_SURF_TRANSLATION_DIS;
-    } else {
-	int i;
-	for (i = 0; i < xf86_config->num_crtc; i++)
-	{
-	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+	xf86CrtcPtr	crtc = xf86_config->crtc[i];
 	    
-	    /* Mark that we'll need to re-set the mode for sure */
-	    memset(&crtc->mode, 0, sizeof(crtc->mode));
-	    if (!crtc->desiredMode.CrtcHDisplay) {
-		crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
-		crtc->desiredRotation = RR_Rotate_0;
-		crtc->desiredX = 0;
-		crtc->desiredY = 0;
-	    }
+	/* Mark that we'll need to re-set the mode for sure */
+	memset(&crtc->mode, 0, sizeof(crtc->mode));
+	if (!crtc->desiredMode.CrtcHDisplay) {
+	    crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
+	    crtc->desiredRotation = RR_Rotate_0;
+	    crtc->desiredX = 0;
+	    crtc->desiredY = 0;
+	}
 
-	    if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
-		return FALSE;
+	if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
+	    return FALSE;
 
-	}
     }
 
     RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
@@ -4090,32 +4001,6 @@ void RADEONRestoreCommonRegisters(ScrnIn
     }
 }
 
-/* Write miscellaneous registers which might have been destroyed by an fbdevHW
- * call
- */
-static void RADEONRestoreFBDevRegisters(ScrnInfoPtr pScrn,
-					 RADEONSavePtr restore)
-{
-#ifdef XF86DRI
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    /* Restore register for vertical blank interrupts */
-    if (info->irq) {
-	OUTREG(RADEON_GEN_INT_CNTL, restore->gen_int_cntl);
-    }
-
-    /* Restore registers for page flipping */
-    if (info->allowPageFlip) {
-	OUTREG(RADEON_CRTC_OFFSET_CNTL, restore->crtc_offset_cntl);
-	if (pRADEONEnt->HasCRTC2) {
-	    OUTREG(RADEON_CRTC2_OFFSET_CNTL, restore->crtc2_offset_cntl);
-	}
-    }
-#endif
-}
-
 void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
 				       RADEONSavePtr restore)
 {
@@ -5079,29 +4964,6 @@ static void RADEONSaveCommonRegisters(Sc
     save->grph2_buffer_cntl  = INREG(RADEON_GRPH2_BUFFER_CNTL);
 }
 
-/* Read miscellaneous registers which might be destroyed by an fbdevHW call */
-static void RADEONSaveFBDevRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
-{
-#ifdef XF86DRI
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-
-    /* Save register for vertical blank interrupts */
-    if (info->irq) {
-	save->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
-    }
-
-    /* Save registers for page flipping */
-    if (info->allowPageFlip) {
-	save->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
-	if (pRADEONEnt->HasCRTC2) {
-	    save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
-	}
-    }
-#endif
-}
-
 /* Read CRTC registers */
 static void RADEONSaveCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
@@ -5411,13 +5273,6 @@ static void RADEONSave(ScrnInfoPtr pScrn
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONSave\n");
 
-    if (info->FBDev) {
-	RADEONSaveMemMapRegisters(pScrn, save);
-	fbdevHWSave(pScrn);
-	return;
-    }
-
-
 #ifdef WITH_VGAHW
     if (info->VGAAccess) {
 	vgaHWPtr hwp = VGAHWPTR(pScrn);
@@ -5464,10 +5319,6 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     OUTREG(RADEON_RBBM_GUICNTL, RADEON_HOST_DATA_SWAP_NONE);
 #endif
 
-    if (info->FBDev) {
-	fbdevHWRestore(pScrn);
-	return;
-    }
     RADEONBlank(pScrn);
 
     OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
@@ -5635,17 +5486,7 @@ Bool RADEONSwitchMode(int scrnIndex, Dis
     if (info->accelOn)
         RADEON_SYNC(info, pScrn);
 
-    if (info->FBDev) {
-	RADEONSaveFBDevRegisters(pScrn, &info->ModeReg);
-
-	ret = fbdevHWSwitchMode(scrnIndex, mode, flags);
-	pScrn->displayWidth = fbdevHWGetLineLength(pScrn)
-		/ info->CurrentLayout.pixel_bytes;
-
-	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
-    } else {
-	ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
-    }
+    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
 
     if (info->tilingEnabled != tilingOld) {
 	/* need to redraw front buffer, I guess this can be considered a hack ? */
@@ -5841,14 +5682,10 @@ void RADEONAdjustFrame(int scrnIndex, in
         RADEON_SYNC(info, pScrn);
 
     if (crtc && crtc->enabled) {
-	if (info->FBDev) {
-	    fbdevHWAdjustFrame(scrnIndex, crtc->desiredX + x, crtc->desiredY + y, flags);
-	} else {
-	    if (crtc == pRADEONEnt->pCrtc[0])
-		RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
-	    else
-		RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, TRUE);
-	}
+	if (crtc == pRADEONEnt->pCrtc[0])
+	    RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
+	else
+	    RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, TRUE);
 	crtc->x = output->initial_x + x;
 	crtc->y = output->initial_y + y;
     }
@@ -5868,11 +5705,12 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONEnterVT\n");
 
-    if (!info->FBDev && (INREG(RADEON_CONFIG_MEMSIZE) == 0)) { /* Softboot V_BIOS */
+    if ((INREG(RADEON_CONFIG_MEMSIZE)) == 0) { /* Softboot V_BIOS */
        xf86Int10InfoPtr pInt;
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "zero MEMSIZE, probably at D3cold. Re-POSTing via int10.\n");
@@ -5887,34 +5725,22 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     /* Makes sure the engine is idle before doing anything */
     RADEONWaitForIdleMMIO(pScrn);
 
-    if (info->FBDev) {
-	unsigned char *RADEONMMIO = info->MMIO;
-	if (!fbdevHWEnterVT(scrnIndex,flags)) return FALSE;
-	info->PaletteSavedOnVT = FALSE;
-	info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
-
-	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
-    } else {
-	int i;
-
-	pScrn->vtSema = TRUE;
-	for (i = 0; i < xf86_config->num_crtc; i++)
-	{
-	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
-	    /* Mark that we'll need to re-set the mode for sure */
-	    memset(&crtc->mode, 0, sizeof(crtc->mode));
-	    if (!crtc->desiredMode.CrtcHDisplay) {
-		crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
-		crtc->desiredRotation = RR_Rotate_0;
-		crtc->desiredX = 0;
-		crtc->desiredY = 0;
-	    }
+    pScrn->vtSema = TRUE;
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+	xf86CrtcPtr	crtc = xf86_config->crtc[i];
+	/* Mark that we'll need to re-set the mode for sure */
+	memset(&crtc->mode, 0, sizeof(crtc->mode));
+	if (!crtc->desiredMode.CrtcHDisplay) {
+	    crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
+	    crtc->desiredRotation = RR_Rotate_0;
+	    crtc->desiredX = 0;
+	    crtc->desiredY = 0;
+	}
 
-	    if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
-				    crtc->desiredX, crtc->desiredY))
-		return FALSE;
+	if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
+			      crtc->desiredX, crtc->desiredY))
+	    return FALSE;
 
-	}
     }
 
     RADEONRestoreSurfaces(pScrn, &info->ModeReg);
@@ -5960,7 +5786,6 @@ void RADEONLeaveVT(int scrnIndex, int fl
 {
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
-    RADEONSavePtr  save  = &info->ModeReg;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONLeaveVT\n");
@@ -5992,15 +5817,6 @@ void RADEONLeaveVT(int scrnIndex, int fl
     }
 #endif
 
-    if (info->FBDev) {
-	RADEONSavePalette(pScrn, save);
-	info->PaletteSavedOnVT = TRUE;
-
-	RADEONSaveFBDevRegisters(pScrn, &info->ModeReg);
-
-	fbdevHWLeaveVT(scrnIndex,flags);
-    }
-
     RADEONRestore(pScrn);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 1f38b3b..c2b749a 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -36,7 +36,6 @@
 /* X and server generic header files */
 #include "xf86.h"
 #include "xf86_OSproc.h"
-#include "fbdevhw.h"
 #include "vgaHW.h"
 #include "xf86Modes.h"
 
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index bc2905a..c5917bc 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -13,7 +13,6 @@
 /* X and server generic header files */
 #include "xf86.h"
 #include "xf86_OSproc.h"
-#include "fbdevhw.h"
 #include "vgaHW.h"
 #include "xf86Modes.h"
 
diff-tree 3469e1aa08792890fa6a5c72da52a1992a0b382c (from 71f650d1bc432514516f7ac64a5e8a54c5227881)
Author: Alex Deucher <alex at botch2.(none)>
Date:   Fri Aug 24 20:42:13 2007 -0400

    RADEON: add extra green data in depth 16
    
    Apparently some radeons need this?

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 6211b02..3ee7760 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -912,6 +912,9 @@ void radeon_crtc_load_lut(xf86CrtcPtr cr
     } else if (pScrn->depth == 16) {
 	for (i = 0; i < 64; i++) {
 	    OUTPAL(i * 4, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+	    if (i <= 31) {
+		OUTPAL(i * 8, radeon_crtc->lut_r[i + 64], radeon_crtc->lut_g[i + 64], radeon_crtc->lut_b[i + 64]);
+	    }
 	}
     } else {
 	for (i = 0; i < 256; i++) {
@@ -935,6 +938,11 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
 	    radeon_crtc->lut_r[i] = red[i/2] >> 8;
 	    radeon_crtc->lut_g[i] = green[i] >> 8;
 	    radeon_crtc->lut_b[i] = blue[i/2] >> 8;
+	    if (i <= 31) {
+		radeon_crtc->lut_r[i + 64] = red[i] >> 8;
+		radeon_crtc->lut_g[i + 64] = green[(i * 2) + 1] >> 8;
+		radeon_crtc->lut_b[i + 64] = blue[i] >> 8;
+	    }
 	}
     } else {
 	for (i = 0; i < 256; i++) {
diff-tree 71f650d1bc432514516f7ac64a5e8a54c5227881 (from d7230939f523610c57f92bdfc72966bdbc6f1070)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Fri Aug 24 09:21:39 2007 +0200

    Require xorg-server >= 1.3 for RandR 1.2.

diff --git a/configure.ac b/configure.ac
index b178224..cdc6377 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,7 +71,7 @@ XORG_DRIVER_CHECK_EXT(XF86MISC, xf86misc
 XORG_DRIVER_CHECK_EXT(DPMSExtension, xextproto)
 
 # Checks for pkg-config packages
-PKG_CHECK_MODULES(XORG, [xorg-server xproto fontsproto $REQUIRED_MODULES])
+PKG_CHECK_MODULES(XORG, [xorg-server >= 1.3 xproto fontsproto $REQUIRED_MODULES])
 sdkdir=$(pkg-config --variable=sdkdir xorg-server)
 
 # Checks for libraries.
diff-tree d7230939f523610c57f92bdfc72966bdbc6f1070 (from 91c45fedfd155a153dcd2c3f3e30986bfbd44e6f)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Fri Aug 24 09:21:14 2007 +0200

    64 bit warning fixes.
    
    For printf vs. CARD32, use %u or %x and and a cast to unsigned.

diff --git a/src/atidri.c b/src/atidri.c
index d4fbead..07adda7 100644
--- a/src/atidri.c
+++ b/src/atidri.c
@@ -1269,9 +1269,10 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen
       ErrorF( "[dri] Data does not fit in SAREA\n" );
       return FALSE;
    }
-   xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %d+%d: %d\n",
-	       sizeof(XF86DRISAREARec), sizeof(ATISAREAPrivRec),
-	       sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec) );
+   xf86DrvMsg( pScreenInfo->scrnIndex, X_INFO, "[drm] SAREA %u+%u: %u\n",
+	       (unsigned)sizeof(XF86DRISAREARec),
+	       (unsigned)sizeof(ATISAREAPrivRec),
+	       (unsigned)(sizeof(XF86DRISAREARec) + sizeof(ATISAREAPrivRec)) );
    pDRIInfo->SAREASize = SAREA_MAX;
 
    pATIDRI = (ATIDRIPtr) xnfcalloc( sizeof(ATIDRIRec), 1 );
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 7dcb5d5..1ef0ff4 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -653,8 +653,11 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInf
 	    if (info->sclk == 0) info->sclk = 200;
 	    if (info->mclk == 0) info->mclk = 200;
 		
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_pll: %ld, max_pll: %ld, xclk: %d, sclk: %f, mclk: %f\n",
-		       pll->reference_freq, pll->min_pll_freq, pll->max_pll_freq, pll->xclk, info->sclk, info->mclk);
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ref_freq: %d, min_pll: %u, "
+		       "max_pll: %u, xclk: %d, sclk: %f, mclk: %f\n",
+		       pll->reference_freq, (unsigned)pll->min_pll_freq,
+		       (unsigned)pll->max_pll_freq, pll->xclk, info->sclk,
+		       info->mclk);
 
 	} else {
 	    pll_info_block = RADEON_BIOS16 (info->ROMHeaderStart + 0x30);
@@ -839,8 +842,9 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86Outp
 					   ((RADEON_BIOS8(tmp+i*6+9) & 0xf)<<12) |
 					   ((RADEON_BIOS8(tmp+i*6+11) & 0xf)<<16));
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-			   "TMDS PLL from BIOS: %ld %lx\n", 
-			   radeon_output->tmds_pll[i].freq, radeon_output->tmds_pll[i].value);
+			   "TMDS PLL from BIOS: %u %x\n", 
+			   (unsigned)radeon_output->tmds_pll[i].freq,
+			   (unsigned)radeon_output->tmds_pll[i].value);
 		       
 		if (maxfreq == radeon_output->tmds_pll[i].freq) {
 		    radeon_output->tmds_pll[i].freq = 0xffffffff;
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 1b9b2fb..6211b02 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -666,9 +666,9 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn
     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,
+		   "dc=%u, of=%u, fd=%d, pd=%d\n",
+		   (unsigned)save->dot_clock_freq,
+		   (unsigned)save->pll_output_freq,
 		   save->feedback_div,
 		   save->post_div);
 
@@ -735,9 +735,9 @@ RADEONInitPLL2Registers(ScrnInfoPtr pScr
     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,
+		   "dc=%u, of=%u, fd=%d, pd=%d\n",
+		   (unsigned)save->dot_clock_freq_2,
+		   (unsigned)save->pll_output_freq_2,
 		   save->feedback_div_2,
 		   save->post_div_2);
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c6c7845..a111e0d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1051,10 +1051,11 @@ static void RADEONGetClockInfo(ScrnInfoP
     }
 
     xf86DrvMsg (pScrn->scrnIndex, X_INFO,
-		"PLL parameters: rf=%d rd=%d min=%ld max=%ld; xclk=%d\n",
+		"PLL parameters: rf=%d rd=%d min=%d max=%d; xclk=%d\n",
 		pll->reference_freq,
 		pll->reference_div,
-		pll->min_pll_freq, pll->max_pll_freq, pll->xclk);
+		(unsigned)pll->min_pll_freq, (unsigned)pll->max_pll_freq,
+		pll->xclk);
 
     /* (Some?) Radeon BIOSes seem too lie about their minimum dot
      * clocks.  Allow users to override the detected minimum dot clock
@@ -1182,7 +1183,7 @@ static void RADEONInitMemoryMap(ScrnInfo
 {
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    unsigned long mem_size;
+    CARD32 mem_size;
     CARD32 aper_size;
 
     /* Default to existing values */
@@ -1254,11 +1255,12 @@ static void RADEONInitMemoryMap(ScrnInfo
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "RADEONInitMemoryMap() : \n");
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "  mem_size         : 0x%08lx\n", mem_size);
+	       "  mem_size         : 0x%08x\n", (unsigned)mem_size);
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "  MC_FB_LOCATION   : 0x%08lx\n", info->mc_fb_location);
+	       "  MC_FB_LOCATION   : 0x%08x\n", (unsigned)info->mc_fb_location);
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "  MC_AGP_LOCATION  : 0x%08lx\n", info->mc_agp_location);
+	       "  MC_AGP_LOCATION  : 0x%08x\n",
+	       (unsigned)info->mc_agp_location);
 }
 
 static void RADEONGetVRamType(ScrnInfoPtr pScrn)
@@ -1321,8 +1323,8 @@ static CARD32 RADEONGetAccessibleVRAM(Sc
     if (info->directRenderingEnabled &&
 	info->pKernelDRMVersion->version_minor < 23) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "[dri] limiting video memory to one aperture of %ldK\n",
-		   aper_size);
+		   "[dri] limiting video memory to one aperture of %uK\n",
+		   (unsigned)aper_size);
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		   "[dri] detected radeon kernel module version 1.%d but"
 		   " 1.23 or newer is required for full memory mapping.\n",
@@ -1409,8 +1411,8 @@ static Bool RADEONPreInitVRAM(ScrnInfoPt
 	accessible = bar_size;
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Detected total video RAM=%dK, accessible=%ldK (PCI BAR=%ldK)\n",
-	       pScrn->videoRam, accessible, bar_size);
+	       "Detected total video RAM=%dK, accessible=%uK (PCI BAR=%uK)\n",
+	       pScrn->videoRam, (unsigned)accessible, (unsigned)bar_size);
     if (pScrn->videoRam > accessible)
 	pScrn->videoRam = accessible;
 
@@ -3248,8 +3250,8 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex
 	       info->depthOffset);
     if (info->cardType==CARD_PCIE)
     	xf86DrvMsg(scrnIndex, X_INFO,
-	           "Will use %d kb for PCI GART table at offset 0x%lx\n",
-		   info->pciGartSize/1024, info->pciGartOffset);
+	           "Will use %d kb for PCI GART table at offset 0x%x\n",
+		   info->pciGartSize/1024, (unsigned)info->pciGartOffset);
     xf86DrvMsg(scrnIndex, X_INFO,
 	       "Will use %d kb for textures at offset 0x%x\n",
 	       info->textureSize/1024, info->textureOffset);
@@ -3772,9 +3774,9 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 		int  width, height;
 
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			   "Using hardware cursor (scanline %ld)\n",
-			   info->cursor_offset / pScrn->displayWidth
-			   / info->CurrentLayout.pixel_bytes);
+			   "Using hardware cursor (scanline %u)\n",
+			   (unsigned)(info->cursor_offset / pScrn->displayWidth
+				      / info->CurrentLayout.pixel_bytes));
 		if (xf86QueryLargestOffscreenArea(pScreen, &width, &height,
 					      0, 0, 0)) {
 		    xf86DrvMsg(scrnIndex, X_INFO,
@@ -3852,9 +3854,11 @@ void RADEONRestoreMemMapRegisters(ScrnIn
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "RADEONRestoreMemMapRegisters() : \n");
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "  MC_FB_LOCATION   : 0x%08lx\n", restore->mc_fb_location);
+	       "  MC_FB_LOCATION   : 0x%08x\n",
+	       (unsigned)restore->mc_fb_location);
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "  MC_AGP_LOCATION  : 0x%08lx\n", restore->mc_agp_location);
+	       "  MC_AGP_LOCATION  : 0x%08x\n",
+	       (unsigned)restore->mc_agp_location);
 
     /* Write memory mapping registers only if their value change
      * since we must ensure no access is done while they are
@@ -4007,11 +4011,11 @@ static void RADEONAdjustMemMapRegisters(
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "DRI init changed memory map, adjusting ...\n");
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "  MC_FB_LOCATION  was: 0x%08lx is: 0x%08lx\n",
-		       info->mc_fb_location, fb);
+		       "  MC_FB_LOCATION  was: 0x%08x is: 0x%08x\n",
+		       (unsigned)info->mc_fb_location, (unsigned)fb);
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "  MC_AGP_LOCATION was: 0x%08lx is: 0x%08lx\n",
-		       info->mc_agp_location, agp);
+		       "  MC_AGP_LOCATION was: 0x%08x is: 0x%08x\n",
+		       (unsigned)info->mc_agp_location, (unsigned)agp);
 	    info->mc_fb_location = fb;
 	    info->mc_agp_location = agp;
 	    info->fbLocation = (save->mc_fb_location & 0xffff) << 16;
@@ -4156,8 +4160,8 @@ void RADEONRestoreCrtcRegisters(ScrnInfo
     unsigned char *RADEONMMIO = info->MMIO;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Programming CRTC1, offset: 0x%08lx\n",
-		   restore->crtc_offset);
+		   "Programming CRTC1, offset: 0x%08x\n",
+		   (unsigned)restore->crtc_offset);
 
     /* We prevent the CRTC from hitting the memory controller until
      * fully programmed
@@ -4209,8 +4213,8 @@ void RADEONRestoreCrtc2Registers(ScrnInf
     /*    CARD32	   crtc2_gen_cntl;*/
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Programming CRTC2, offset: 0x%08lx\n",
-		   restore->crtc2_offset);
+		   "Programming CRTC2, offset: 0x%08x\n",
+		   (unsigned)restore->crtc2_offset);
 
     /* We prevent the CRTC from hitting the memory controller until
      * fully programmed
@@ -4762,10 +4766,10 @@ void RADEONRestorePLLRegisters(ScrnInfoP
 	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote: 0x%08x 0x%08x 0x%08lx (0x%08x)\n",
+		   "Wrote: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
 		   restore->ppll_ref_div,
 		   restore->ppll_div_3,
-		   restore->htotal_cntl,
+		   (unsigned)restore->htotal_cntl,
 		   INPLL(pScrn, RADEON_PPLL_CNTL));
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Wrote: rd=%d, fd=%d, pd=%d\n",
@@ -4835,16 +4839,17 @@ void RADEONRestorePLL2Registers(ScrnInfo
 	      | RADEON_P2PLL_ATOMIC_UPDATE_EN));
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote2: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n",
-		   restore->p2pll_ref_div,
-		   restore->p2pll_div_0,
-		   restore->htotal_cntl2,
+		   "Wrote2: 0x%08x 0x%08x 0x%08x (0x%08x)\n",
+		   (unsigned)restore->p2pll_ref_div,
+		   (unsigned)restore->p2pll_div_0,
+		   (unsigned)restore->htotal_cntl2,
 		   INPLL(pScrn, RADEON_P2PLL_CNTL));
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote2: rd=%ld, fd=%ld, pd=%ld\n",
-		   restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
-		   restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
-		   (restore->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >>16);
+		   "Wrote2: rd=%u, fd=%u, pd=%u\n",
+		   (unsigned)restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+		   (unsigned)restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
+		   (unsigned)((restore->p2pll_div_0 &
+			       RADEON_P2PLL_POST0_DIV_MASK) >>16));
 
     usleep(5000); /* Let the clock to lock */
 
@@ -5320,10 +5325,10 @@ static void RADEONSavePLLRegisters(ScrnI
     save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: 0x%08x 0x%08x 0x%08lx\n",
+		   "Read: 0x%08x 0x%08x 0x%08x\n",
 		   save->ppll_ref_div,
 		   save->ppll_div_3,
-		   save->htotal_cntl);
+		   (unsigned)save->htotal_cntl);
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Read: rd=%d, fd=%d, pd=%d\n",
 		   save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
@@ -5340,15 +5345,16 @@ static void RADEONSavePLL2Registers(Scrn
     save->pixclks_cntl  = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: 0x%08lx 0x%08lx 0x%08lx\n",
-		   save->p2pll_ref_div,
-		   save->p2pll_div_0,
-		   save->htotal_cntl2);
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Read: rd=%ld, fd=%ld, pd=%ld\n",
-		   save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
-		   save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
-		   (save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >> 16);
+		   "Read: 0x%08x 0x%08x 0x%08x\n",
+		   (unsigned)save->p2pll_ref_div,
+		   (unsigned)save->p2pll_div_0,
+		   (unsigned)save->htotal_cntl2);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: rd=%u, fd=%u, pd=%u\n",
+		   (unsigned)(save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK),
+		   (unsigned)(save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK),
+		   (unsigned)((save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK)
+			      >> 16));
 }
 
 /* Read palette data */
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 7231c1e..5cbe9fc 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1325,21 +1325,21 @@ static void RADEONSetupTheatre(ScrnInfoP
                                    } else {
                                    t->wComp0Connector=RT_COMP1;
                                    }
-                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %ld\n", t->wComp0Connector);
+                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Composite connector is port %u\n", (unsigned)t->wComp0Connector);
                                   break;
                         case 3:  if(a & 0x4){
                                    t->wSVideo0Connector=RT_YCR_COMP4;
                                    } else {
                                    t->wSVideo0Connector=RT_YCF_COMP4;
                                    }
-                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %ld\n", t->wSVideo0Connector);
+                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "SVideo connector is port %u\n", (unsigned)t->wSVideo0Connector);
                                    break;
                         default:
                                 break;
                         }
                 }
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%ld, composite=%ld, svideo=%ld\n",
-    	     t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector);
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rage Theatre: Connectors (detected): tuner=%u, composite=%u, svideo=%u\n",
+    	     (unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
         
          }
 
@@ -1347,8 +1347,8 @@ static void RADEONSetupTheatre(ScrnInfoP
     if(info->RageTheatreCompositePort>=0)t->wComp0Connector=info->RageTheatreCompositePort;
     if(info->RageTheatreSVideoPort>=0)t->wSVideo0Connector=info->RageTheatreSVideoPort;
         
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%ld, composite=%ld, svideo=%ld\n",
-    	t->wTunerConnector, t->wComp0Connector, t->wSVideo0Connector);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RageTheatre: Connectors (using): tuner=%u, composite=%u, svideo=%u\n",
+    	(unsigned)t->wTunerConnector, (unsigned)t->wComp0Connector, (unsigned)t->wSVideo0Connector);
 
     switch((info->RageTheatreCrystal>=0)?info->RageTheatreCrystal:pll->reference_freq){
                 case 2700:
@@ -1881,7 +1881,8 @@ RADEONSetPortAttribute(ScrnInfoPtr  pScr
    else if(attribute == xvAdjustment) 
    {
   	pPriv->adjustment=value;
-        xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %ld\n", pPriv->adjustment);
+        xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Setting pPriv->adjustment to %u\n",
+		   (unsigned)pPriv->adjustment);
   	if(pPriv->tda9885!=0){
 		pPriv->tda9885->top_adjustment=value;
 		RADEON_TDA9885_SetEncoding(pPriv);
diff --git a/src/theatre.c b/src/theatre.c
index 0a635fa..a5aadfb 100644
--- a/src/theatre.c
+++ b/src/theatre.c
@@ -1796,7 +1796,9 @@ void RT_SetConnector (TheatrePtr t, CARD
     	counter++;
 	}
     dwTempContrast = ReadRT_fld (fld_LP_CONTRAST);
-    if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: timeout waiting for line count (%ld)\n", ReadRT_fld (fld_VS_LINE_COUNT));
+    if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+				 "Rage Theatre: timeout waiting for line count (%u)\n",
+				 (unsigned)ReadRT_fld (fld_VS_LINE_COUNT));
 
 
     WriteRT_fld (fld_LP_CONTRAST, 0x0);
@@ -1851,7 +1853,9 @@ void RT_SetConnector (TheatrePtr t, CARD
     	counter++;
 	}
     WriteRT_fld (fld_LP_CONTRAST, dwTempContrast);
-    if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "Rage Theatre: timeout waiting for line count (%ld)\n", ReadRT_fld (fld_VS_LINE_COUNT));
+    if(counter>=10000)xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+				 "Rage Theatre: timeout waiting for line count (%u)\n",
+				 (unsigned)ReadRT_fld (fld_VS_LINE_COUNT));
 
 
 
@@ -1942,7 +1946,8 @@ void DumpRageTheatreRegs(TheatrePtr t)
     for(i=0;i<0x900;i+=4)
     {
        RT_regr(i, &data);
-       xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register 0x%04x is equal to 0x%08lx\n", i, data);
+       xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+		  "register 0x%04x is equal to 0x%08x\n", i, (unsigned)data);
     }   
 
 }
@@ -2147,7 +2152,9 @@ void DumpRageTheatreRegsByName(TheatrePt
 
     for(i=0; rt_reg_list[i].name!=NULL;i++){
         RT_regr(rt_reg_list[i].addr, &data);
-        xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register (0x%04lx) %s is equal to 0x%08lx\n", rt_reg_list[i].addr, rt_reg_list[i].name, data);
+        xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+		   "register (0x%04lx) %s is equal to 0x%08x\n",
+		   rt_reg_list[i].addr, rt_reg_list[i].name, (unsigned)data);
     	}
 
 }
diff --git a/src/theatre200.c b/src/theatre200.c
index ff86395..672f01e 100644
--- a/src/theatre200.c
+++ b/src/theatre200.c
@@ -1799,10 +1799,12 @@ void RT_SetConnector (TheatrePtr t, CARD
 	t->wConnector = wConnector;
 
 	theatre_read(t, VIP_GPIO_CNTL, &data);
-	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %lx\n", data);
+	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %x\n",
+		   (unsigned)data);
 
 	theatre_read(t, VIP_GPIO_INOUT, &data);
-	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %lx\n", data);
+	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %x\n",
+		   (unsigned)data);
 	
 	switch (wConnector)
 	{
@@ -1851,10 +1853,12 @@ void RT_SetConnector (TheatrePtr t, CARD
 	}
 
 	theatre_read(t, VIP_GPIO_CNTL, &data);
-	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %lx\n", data);
+	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_CNTL: %x\n",
+		   (unsigned)data);
 
 	theatre_read(t, VIP_GPIO_INOUT, &data);
-	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %lx\n", data);
+	xf86DrvMsg(t->VIP->scrnIndex,X_INFO,"VIP_GPIO_INOUT: %x\n",
+		   (unsigned)data);
 
 
 	dsp_configure_i2s_port(t, 0, 0, 0);
@@ -2007,7 +2011,8 @@ void DumpRageTheatreRegs(TheatrePtr t)
     for(i=0;i<0x900;i+=4)
     {
        RT_regr(i, &data);
-       xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register 0x%04x is equal to 0x%08lx\n", i, data);
+       xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+		  "register 0x%04x is equal to 0x%08x\n", i, (unsigned)data);
     }   
 
 }
@@ -2212,7 +2217,9 @@ void DumpRageTheatreRegsByName(TheatrePt
 
     for(i=0; rt_reg_list[i].name!=NULL;i++){
         RT_regr(rt_reg_list[i].addr, &data);
-        xf86DrvMsg(t->VIP->scrnIndex, X_INFO, "register (0x%04lx) %s is equal to 0x%08lx\n", rt_reg_list[i].addr, rt_reg_list[i].name, data);
+        xf86DrvMsg(t->VIP->scrnIndex, X_INFO,
+		   "register (0x%04lx) %s is equal to 0x%08x\n",
+		   rt_reg_list[i].addr, rt_reg_list[i].name, (unsigned)data);
     	}
 
 }
diff --git a/src/theatre_detect.c b/src/theatre_detect.c
index e754832..8770911 100644
--- a/src/theatre_detect.c
+++ b/src/theatre_detect.c
@@ -67,7 +67,7 @@ static Bool theatre_write(TheatrePtr t,C
 TheatrePtr DetectTheatre(GENERIC_BUS_Ptr b)
 {
    TheatrePtr t;  
-   CARD32 i;
+   int i;
    CARD32 val;
    char s[20];
    
@@ -88,7 +88,9 @@ TheatrePtr DetectTheatre(GENERIC_BUS_Ptr
    {
 	if(b->read(b, ((i & 0x03)<<14) | VIP_VIP_VENDOR_DEVICE_ID, 4, (CARD8 *)&val))
         {
-	  if(val)xf86DrvMsg(b->scrnIndex, X_INFO, "Device %ld on VIP bus ids as 0x%08lx\n",i,val);
+	  if(val)xf86DrvMsg(b->scrnIndex, X_INFO,
+			    "Device %d on VIP bus ids as 0x%08x\n", i,
+			    (unsigned)val);
 	  if(t->theatre_num>=0)continue; /* already found one instance */
 	  switch(val){
 	  	case RT100_ATI_ID:
@@ -101,10 +103,12 @@ TheatrePtr DetectTheatre(GENERIC_BUS_Ptr
 		   break;
                 }
 	} else {
-	  xf86DrvMsg(b->scrnIndex, X_INFO, "No response from device %ld on VIP bus\n",i);	
+	  xf86DrvMsg(b->scrnIndex, X_INFO, "No response from device %d on VIP bus\n",i);	
 	}
    }
-   if(t->theatre_num>=0)xf86DrvMsg(b->scrnIndex, X_INFO, "Detected Rage Theatre as device %d on VIP bus with id 0x%08lx\n",t->theatre_num,t->theatre_id);
+   if(t->theatre_num>=0)xf86DrvMsg(b->scrnIndex, X_INFO,
+				   "Detected Rage Theatre as device %d on VIP bus with id 0x%08x\n",
+				   t->theatre_num, (unsigned)t->theatre_id);
 
    if(t->theatre_num < 0)
    {
@@ -113,7 +117,8 @@ TheatrePtr DetectTheatre(GENERIC_BUS_Ptr
    }
 
    RT_regr(VIP_VIP_REVISION_ID, &val);
-   xf86DrvMsg(b->scrnIndex, X_INFO, "Detected Rage Theatre revision %8.8lX\n", val);
+   xf86DrvMsg(b->scrnIndex, X_INFO, "Detected Rage Theatre revision %8.8X\n",
+	      (unsigned)val);
 
 #if 0
 DumpRageTheatreRegsByName(t);
diff-tree 91c45fedfd155a153dcd2c3f3e30986bfbd44e6f (from 056ca6bb5adf974290693b55de6cd6880d2132d1)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Fri Aug 24 15:05:01 2007 +1000

    radeon: don't disable dac if either tv or vga is using it
    
    On my rs480 I had to vt switch to get hotplug VGA working due to the tv-out
    code turning off the dac when the vga code was actually using it.

diff --git a/src/radeon.h b/src/radeon.h
index 29e7da4..6f880b8 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -791,6 +791,7 @@ typedef struct {
     int                MaxLines;
 
     CARD32            tv_dac_adj;
+    CARD32            tv_dac_enable_mask;
 
     Bool want_vblank_interrupts;
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
diff --git a/src/radeon_display.c b/src/radeon_display.c
index c51fb5d..ed20409 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -322,6 +322,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
     unsigned char * RADEONMMIO = info->MMIO;
     unsigned long tmp;
     RADEONOutputPrivatePtr radeon_output;
+    int tv_dac_change = 0;
     radeon_output = output->driver_private;
 
     if (bEnable) {
@@ -332,6 +333,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
                 tmp |= RADEON_CRTC_CRT_ON;                    
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
+                RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
             } else if (radeon_output->DACType == DAC_TVDAC) {
                 if (info->ChipFamily == CHIP_FAMILY_R200) {
                     tmp = INREG(RADEON_FP2_GEN_CNTL);
@@ -344,8 +346,8 @@ void RADEONEnableDisplay(xf86OutputPtr o
                     OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
                     save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
                 }
+                tv_dac_change = 1;
             }
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
         } else if (radeon_output->MonType == MT_DFP) {
             if (radeon_output->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
@@ -371,7 +373,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
 	    tmp = INREG(RADEON_TV_MASTER_CNTL);
 	    tmp |= RADEON_TV_ON;
 	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+            tv_dac_change = 2;
 	}
     } else {
 	ErrorF("disable montype: %d\n", radeon_output->MonType);
@@ -381,6 +383,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
                 tmp &= ~RADEON_CRTC_CRT_ON;
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
+                RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
             } else if (radeon_output->DACType == DAC_TVDAC) {
                 if (info->ChipFamily == CHIP_FAMILY_R200) {
                     tmp = INREG(RADEON_FP2_GEN_CNTL);
@@ -393,8 +396,8 @@ void RADEONEnableDisplay(xf86OutputPtr o
                     OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
                     save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
                 }
+                tv_dac_change = 1;
             }
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
         } else if (radeon_output->MonType == MT_DFP) {
             if (radeon_output->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
@@ -428,9 +431,22 @@ void RADEONEnableDisplay(xf86OutputPtr o
 	    tmp = INREG(RADEON_TV_MASTER_CNTL);
 	    tmp &= ~RADEON_TV_ON;
 	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
-	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+            tv_dac_change = 2;
 	}
     }
+
+    if (tv_dac_change) {
+	if (bEnable)
+		info->tv_dac_enable_mask |= tv_dac_change;
+	else
+		info->tv_dac_enable_mask &= ~tv_dac_change;
+
+	if (bEnable && info->tv_dac_enable_mask)
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+	else if (!bEnable && info->tv_dac_enable_mask == 0)
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+
+    }
 }
 
 /* Calculate display buffer watermark to prevent buffer underflow */
diff-tree 056ca6bb5adf974290693b55de6cd6880d2132d1 (from 13fd53286bdda2c55683bdb5f63e7d345f6c63ef)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Aug 23 20:19:47 2007 -0400

    RADEON: NONE to None to match other port info

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 90a2c92..1f38b3b 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -77,7 +77,7 @@ const char *TMDSTypeName[4] = {
 };
 
 const char *DDCTypeName[6] = {
-  "NONE",
+  "None",
   "MONID",
   "DVI_DDC",
   "VGA_DDC",
diff-tree 13fd53286bdda2c55683bdb5f63e7d345f6c63ef (from 53bad86ca48a9b6529c1f0989ee568d9d48841c6)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Aug 23 20:17:51 2007 -0400

    RADEON: set (hopefully) reasonable default max desktop sizes
    
    Based on the amount of vram.  We really need ttm...

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 469e7bc..c6c7845 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2772,9 +2772,26 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 		crtc_max_Y = 8192;
 	}
     } else {
-	crtc_max_X = 1600;
-	crtc_max_Y = 1200;
+	if (pScrn->videoRam < 16384) {
+	    crtc_max_X = 1600;
+	    crtc_max_Y = 1200;
+	} else if (pScrn->videoRam <= 32768) {
+	    crtc_max_X = 2048;
+	    crtc_max_Y = 1200;
+	} else if (pScrn->videoRam > 32768) {
+	    if (IS_R300_VARIANT) {
+		crtc_max_X = 2560;
+		crtc_max_Y = 2048;
+	    } else {
+		crtc_max_X = 2048;
+		crtc_max_Y = 2048;
+	    }
+	}
     }
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Max desktop size set to %dx%d\n",
+	       crtc_max_X, crtc_max_Y);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "For a larger or smaller max desktop size, add a Virtual line to your xorg.conf\n");
 
     /*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/
     xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
diff-tree 53bad86ca48a9b6529c1f0989ee568d9d48841c6 (from 4712dedea225e9e07177aebda2ffc6290d1f53c7)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Aug 23 19:24:59 2007 -0400

    RADEON: clean up the logic in crtc_mode_set()

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 434034c..1b9b2fb 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -759,22 +759,21 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     ScrnInfoPtr pScrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    xf86OutputPtr output;
-    RADEONOutputPrivatePtr radeon_output;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONMonitorType montype = MT_NONE;
     Bool           tilingOld   = info->tilingEnabled;
     int i = 0;
     double         dot_clock = 0;
+    Bool no_odd_post_div = FALSE;
+    Bool update_tv_routing = FALSE;
 
 
     if (info->allowColorTiling) {
-        info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
-#ifdef XF86DRI	
+	info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+#ifdef XF86DRI
 	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
 	    RADEONSAREAPrivPtr pSAREAPriv;
 	  if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
-  	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			 "[drm] failed changing tiling status\n");
 	    pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
 	    info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
@@ -783,11 +782,12 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     }
 
     for (i = 0; i < xf86_config->num_output; i++) {
-	output = xf86_config->output[i];
-	radeon_output = output->driver_private;
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
 	if (output->crtc == crtc) {
-	    montype = radeon_output->MonType;
+	    if (radeon_output->MonType != MT_CRT)
+		no_odd_post_div = TRUE;
 	}
     }
 
@@ -820,28 +820,36 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll2\n");
-	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, montype != MT_CRT);
+	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, no_odd_post_div);
         }
 	break;
     }
 
-    if (montype == MT_STV || montype == MT_CTV) {
-	switch (radeon_crtc->crtc_id) {
-	case 0:
-	    RADEONAdjustCrtcRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-	    RADEONAdjustPLLRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-	    break;
-	case 1:
-	    RADEONAdjustCrtc2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-	    RADEONAdjustPLL2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
-	    break;
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+	if (output->crtc == crtc) {
+	    if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+		switch (radeon_crtc->crtc_id) {
+		case 0:
+		    RADEONAdjustCrtcRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+		    RADEONAdjustPLLRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+		    update_tv_routing = TRUE;
+		    break;
+		case 1:
+		    RADEONAdjustCrtc2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+		    RADEONAdjustPLL2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+		    break;
+		}
+	    }
 	}
     }
 
     ErrorF("restore memmap\n");
     RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
     ErrorF("restore common\n");
-    RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);    
+    RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);
 
     switch (radeon_crtc->crtc_id) {
     case 0:
@@ -859,7 +867,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     }
 
     /* pixclks_cntl handles tv-out clock routing */
-    if (montype == MT_STV || montype == MT_CTV)
+    if (update_tv_routing)
 	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
 
     if (info->DispPriority)
diff-tree 4712dedea225e9e07177aebda2ffc6290d1f53c7 (from b0f170c5f736ecba1a5899d602c4173fe9b9b1fa)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Aug 23 18:51:34 2007 -0400

    RADEON: Always assume LVDS is connected
    
    Not all bioses seem to set the right scratch bits.  If we have
    LVDS (via bios table or otherwise) assume it's connected.

diff --git a/src/radeon_output.c b/src/radeon_output.c
index b9e01a1..90a2c92 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -580,7 +580,6 @@ static RADEONMonitorType RADEONPortCheck
 
 
     if (radeon_output->type == OUTPUT_LVDS) {
-	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
 	    MonType =  MT_LCD;
     } else if (radeon_output->type == OUTPUT_DVI) {
 	if (radeon_output->TMDSType == TMDS_INT) {
diff-tree b0f170c5f736ecba1a5899d602c4173fe9b9b1fa (from ac54c0e4360099697755d14b1030def73d8235b0)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 12:55:40 2007 +0200

    radeon: Remove unnecessary #include <time.h>.

diff --git a/src/radeon.h b/src/radeon.h
index 8babf39..29e7da4 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -39,8 +39,7 @@
 
 #include <stdlib.h>		/* For abs() */
 #include <unistd.h>		/* For usleep() */
-#include <sys/time.h>		/* For
-#include <time.h>		 * gettimeofday() */
+#include <sys/time.h>		/* For gettimeofday() */
 
 #include "xf86str.h"
 #include "compiler.h"
diff-tree ac54c0e4360099697755d14b1030def73d8235b0 (from de26e406f52b3b13f03eee2b8023924ec6406f0a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Wed Aug 22 14:33:59 2007 +0200

    radeon: Warning fixes.

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 975fc07..7dcb5d5 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -619,8 +619,7 @@ Bool RADEONGetTVInfoFromBIOS (xf86Output
 		ErrorF("\n");
 
 		return TRUE;
-	    } else
-		return FALSE;
+	    }
 	}
     }
     return FALSE;
@@ -1077,7 +1076,7 @@ RADEONRestoreBIOSRegBlock(ScrnInfoPtr pS
 	case RADEON_TABLE_FLAG_WRITE_INDEXED:
 	    val = RADEON_BIOS32(offset);
 	    ErrorF("WRITE INDEXED: 0x%x 0x%x\n",
-		   index, val);
+		   index, (unsigned)val);
 	    OUTREG(RADEON_MM_INDEX, index);
 	    OUTREG(RADEON_MM_DATA, val);
 	    offset += 4;
@@ -1085,7 +1084,7 @@ RADEONRestoreBIOSRegBlock(ScrnInfoPtr pS
 
 	case RADEON_TABLE_FLAG_WRITE_DIRECT:
 	    val = RADEON_BIOS32(offset);
-	    ErrorF("WRITE DIRECT: 0x%x 0x%x\n", index, val);
+	    ErrorF("WRITE DIRECT: 0x%x 0x%x\n", index, (unsigned)val);
 	    OUTREG(index, val);
 	    offset += 4;
 	    break;
@@ -1096,7 +1095,7 @@ RADEONRestoreBIOSRegBlock(ScrnInfoPtr pS
 	    ormask = RADEON_BIOS32(offset);
 	    offset += 4;
 	    ErrorF("MASK INDEXED: 0x%x 0x%x 0x%x\n",
-		   index, andmask, ormask);
+		   index, (unsigned)andmask, (unsigned)ormask);
 	    OUTREG(RADEON_MM_INDEX, index);
 	    val = INREG(RADEON_MM_DATA);
 	    val = (val & andmask) | ormask;
@@ -1109,7 +1108,7 @@ RADEONRestoreBIOSRegBlock(ScrnInfoPtr pS
 	    ormask = RADEON_BIOS32(offset);
 	    offset += 4;
 	    ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n",
-		   index, andmask, ormask);
+		   index, (unsigned)andmask, (unsigned)ormask);
 	    val = INREG(index);
 	    val = (val & andmask) | ormask;
 	    OUTREG(index, val);
@@ -1198,7 +1197,7 @@ RADEONRestoreBIOSMemBlock(ScrnInfoPtr pS
 	    offset += 2;
 
 	    ErrorF("INDEX RADEON_MEM_SDRAM_MODE_REG %x %x\n",
-		   RADEON_SDRAM_MODE_MASK, ormask);
+		   RADEON_SDRAM_MODE_MASK, (unsigned)ormask);
 
 	    /* can this use direct access? */
 	    OUTREG(RADEON_MM_INDEX, RADEON_MEM_SDRAM_MODE_REG);
@@ -1209,7 +1208,7 @@ RADEONRestoreBIOSMemBlock(ScrnInfoPtr pS
 	    ormask = (CARD32)index << 24;
 
 	    ErrorF("INDEX RADEON_MEM_SDRAM_MODE_REG %x %x\n",
-		   RADEON_B3MEM_RESET_MASK, ormask);
+		   RADEON_B3MEM_RESET_MASK, (unsigned)ormask);
 
             /* can this use direct access? */
             OUTREG(RADEON_MM_INDEX, RADEON_MEM_SDRAM_MODE_REG);
@@ -1224,7 +1223,6 @@ static void
 RADEONRestoreBIOSPllBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     CARD16 offset = table_offset;
     CARD8  index, shift;
     CARD32 andmask, ormask, val, clk_pwrmgt_cntl;
@@ -1298,7 +1296,7 @@ RADEONRestoreBIOSPllBlock(ScrnInfoPtr pS
 	    offset++;
 
 	    ErrorF("PLL_MASK_BYTE 0x%x 0x%x 0x%x 0x%x\n", 
-		   index, shift, andmask, ormask);
+		   index, shift, (unsigned)andmask, (unsigned)ormask);
 	    val = INPLL(pScrn, index);
 	    val = (val & andmask) | ormask;
 	    OUTPLL(pScrn, index, val);
@@ -1306,7 +1304,7 @@ RADEONRestoreBIOSPllBlock(ScrnInfoPtr pS
 
 	case RADEON_PLL_FLAG_WRITE:
 	    val = RADEON_BIOS32(offset);
-	    ErrorF("PLL_WRITE 0x%x 0x%x\n", index, val);
+	    ErrorF("PLL_WRITE 0x%x 0x%x\n", index, (unsigned)val);
 	    OUTPLL(pScrn, index, val);
 	    offset += 4;
 	    break;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 940bb01..b9e01a1 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -654,8 +654,6 @@ static Bool
 radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) {
@@ -1229,12 +1227,9 @@ radeon_detect_tv_dac(ScrnInfoPtr pScrn, 
 
     /* save the regs we need */
     pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-    if (IS_R300_VARIANT) {
-	gpiopad_a = INREG(RADEON_GPIOPAD_A);
-	disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
-    } else {
-	disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG);
-    }
+    gpiopad_a = IS_R300_VARIANT ? INREG(RADEON_GPIOPAD_A) : 0;
+    disp_output_cntl = IS_R300_VARIANT ? INREG(RADEON_DISP_OUTPUT_CNTL) : 0;
+    disp_hw_debug = !IS_R300_VARIANT ? INREG(RADEON_DISP_HW_DEBUG) : 0;
     crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
     tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
     dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
@@ -2286,10 +2281,7 @@ RADEONGetTMDSInfo(xf86OutputPtr output)
 static void
 RADEONGetTVInfo(xf86OutputPtr output)
 {
-    ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int i;
 
     radeon_output->hPos = 0;
     radeon_output->vPos = 0;
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 522f7ed..bc2905a 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -187,9 +187,7 @@ static long SLOPE_limit[5] = { 6, 5, 4, 
 static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
 				 DisplayModePtr mode)
 {
-    ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
     int restart;
     unsigned hTotal;
     unsigned vTotal;
@@ -274,7 +272,8 @@ static Bool RADEONInitTVRestarts(xf86Out
     save->tv_frestart = restart % fTotal;
 
     ErrorF("computeRestarts: F/H/V=%u,%u,%u\n",
-	   save->tv_frestart , save->tv_vrestart , save->tv_hrestart);
+	   (unsigned)save->tv_frestart, (unsigned)save->tv_vrestart,
+	   (unsigned)save->tv_hrestart);
 
     /* Compute H_INC from hSize */
     if (radeon_output->tvStd == TV_STD_NTSC ||
@@ -570,7 +569,6 @@ void RADEONUpdateHVPosition(xf86OutputPt
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     Bool reloadTable;
     RADEONSavePtr restore = &info->ModeReg;
 
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 15e2101..7231c1e 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2587,20 +2587,19 @@ RADEONDisplayVideo(
 	y_mult = 2;
     }
 
+    v_inc = (src_h << v_inc_shift) / drw_h;
+
     for (i = 0; i < xf86_config->num_output; i++) {
 	output = xf86_config->output[i];
 	if (output->crtc == crtc) {
 	    radeon_output = output->driver_private;
+	    if (radeon_output->Flags & RADEON_USE_RMX)
+		v_inc = ((src_h * mode->CrtcVDisplay /
+			  radeon_output->PanelYRes) << v_inc_shift) / drw_h;
 	    break;
 	}
     }
 
-    if (radeon_output->Flags & RADEON_USE_RMX) {
-	v_inc = ((src_h * mode->CrtcVDisplay / radeon_output->PanelYRes) << v_inc_shift) / drw_h;
-    } else {
-	v_inc = (src_h << v_inc_shift) / drw_h;
-    }
-
     h_inc = (1 << (12 + ecp_div));
 
     step_by_y = 1;
@@ -2860,7 +2859,6 @@ RADEONPutImage(
   DrawablePtr pDraw
 ){
    RADEONInfoPtr info = RADEONPTR(pScrn);
-   xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
    INT32 xa, xb, ya, yb;
    unsigned char *dst_start;
@@ -3259,7 +3257,6 @@ RADEONDisplaySurface(
 ){
     OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
     ScrnInfoPtr pScrn = surface->pScrn;
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
 
@@ -3362,7 +3359,6 @@ RADEONPutVideo(
 ){
    RADEONInfoPtr info = RADEONPTR(pScrn);
    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
-   xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;
    INT32 xa, xb, ya, yb, top;
    unsigned int pitch, new_size, alloc_size;
@@ -3376,7 +3372,6 @@ RADEONPutVideo(
    int mult;
    int vbi_line_width, vbi_start, vbi_end;
    xf86CrtcPtr crtc;
-   RADEONCrtcPrivatePtr radeon_crtc;
 
     RADEON_SYNC(info, pScrn);
    /*
diff-tree de26e406f52b3b13f03eee2b8023924ec6406f0a (from c66e5de26ae93caa368213f3cce139aacec955d2)
Author: Alon Ziv <alonz at nolaviz.org>
Date:   Mon Jul 30 22:47:59 2007 +0300

    radeon: Sane handling of timeouts in WaitForVerticalSync(2).
    
    RADEONWaitForVerticalSync() and RADEONWaitForVerticalSync2() need to wait
    for a timeout specified in milliseconds; looping around usleep() causes
    the timeout to be unnecessarily long, as the OS may sleep longer than
    requested (on Linux the minimum actual sleep value may be several ms).
    
    The new logic uses gettimeofday() in the loop to see when the (absolute)
    timeout has arrived.
    
    Signed-off-by: Alon Ziv <alonz at nolaviz.org>

diff --git a/src/radeon.h b/src/radeon.h
index bf1444c..8babf39 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -39,6 +39,8 @@
 
 #include <stdlib.h>		/* For abs() */
 #include <unistd.h>		/* For usleep() */
+#include <sys/time.h>		/* For
+#include <time.h>		 * gettimeofday() */
 
 #include "xf86str.h"
 #include "compiler.h"
@@ -159,6 +161,8 @@ typedef enum {
 #define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
 #define RADEON_TIMEOUT    2000000 /* Fall out of wait loops after this count */
 
+#define RADEON_VSYNC_TIMEOUT	20000 /* Maximum wait for VSYNC (in usecs) */
+
 /* Buffer are aligned on 4096 byte boundaries */
 #define RADEON_BUFFER_ALIGN 0x00000fff
 #define RADEON_VBIOS_SIZE 0x00010000
@@ -1224,4 +1228,21 @@ static __inline__ void RADEON_SYNC(RADEO
 #endif
 }
 
+static __inline__ void radeon_init_timeout(struct timeval *endtime,
+    unsigned int timeout)
+{
+    gettimeofday(endtime, NULL);
+    endtime->tv_usec += timeout;
+    endtime->tv_sec += endtime->tv_usec / 1000000;
+    endtime->tv_usec %= 1000000;
+}
+
+static __inline__ int radeon_timedout(const struct timeval *endtime)
+{
+    struct timeval now;
+    gettimeofday(&now, NULL);
+    return now.tv_sec == endtime->tv_sec ?
+        now.tv_usec > endtime->tv_usec : now.tv_sec > endtime->tv_sec;
+}
+
 #endif /* _RADEON_H_ */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 87f1405..469e7bc 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -724,7 +724,7 @@ void RADEONWaitForVerticalSync(ScrnInfoP
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32         crtc_gen_cntl;
-    int            i;
+    struct timeval timeout;
 
     crtc_gen_cntl = INREG(RADEON_CRTC_GEN_CNTL);
     if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) ||
@@ -735,10 +735,10 @@ void RADEONWaitForVerticalSync(ScrnInfoP
     OUTREG(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR);
 
     /* Wait for it to go back up */
-    for (i = 0; i < RADEON_TIMEOUT/1000; i++) {
-	if (INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) break;
-	usleep(1);
-    }
+    radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT);
+    while (!(INREG(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_SAVE) &&
+        !radeon_timedout(&timeout))
+	usleep(100);
 }
 
 /* Wait for vertical sync on secondary CRTC */
@@ -747,7 +747,7 @@ void RADEONWaitForVerticalSync2(ScrnInfo
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32         crtc2_gen_cntl;
-    int            i;
+    struct timeval timeout;
  
     crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
     if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) ||
@@ -758,10 +758,10 @@ void RADEONWaitForVerticalSync2(ScrnInfo
     OUTREG(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR);
 
     /* Wait for it to go back up */
-    for (i = 0; i < RADEON_TIMEOUT/1000; i++) {
-	if (INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) break;
-	usleep(1);
-    }
+    radeon_init_timeout(&timeout, RADEON_VSYNC_TIMEOUT);
+    while (!(INREG(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_SAVE) &&
+        !radeon_timedout(&timeout))
+	usleep(100);
 }
 
 
diff-tree c66e5de26ae93caa368213f3cce139aacec955d2 (from 633c1fff10a3be4c9f48c1995e330d60bf6abbb2)
Author: Sascha Sommer <saschasommer at freenet.de>
Date:   Thu Aug 23 12:11:51 2007 +0200

    radeon: Round down RMX stretch ratios.
    
    Fixes issues with RMX scaling, see
    https://bugs.freedesktop.org/show_bug.cgi?id=8983 .

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 9650a39..940bb01 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -848,21 +848,22 @@ static void RADEONInitRMXRegisters(xf86O
     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));
+	save->fp_horz_stretch |= ((((unsigned long)
+				    (Hratio * RADEON_HORZ_STRETCH_RATIO_MAX)) &
+				   RADEON_HORZ_STRETCH_RATIO_MASK) |
+				  RADEON_HORZ_STRETCH_BLEND |
+				  RADEON_HORZ_STRETCH_ENABLE |
+				  ((radeon_output->PanelXRes/8-1)<<16));
     }
 
     if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
 	save->fp_vert_stretch |= ((yres-1)<<12);
     } else {
-	save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX +
-						0.5)) & RADEON_VERT_STRETCH_RATIO_MASK) |
-				      RADEON_VERT_STRETCH_ENABLE |
-				      RADEON_VERT_STRETCH_BLEND |
-				      ((radeon_output->PanelYRes-1)<<12));
+	save->fp_vert_stretch |= ((((unsigned long)(Vratio * RADEON_VERT_STRETCH_RATIO_MAX)) &
+				   RADEON_VERT_STRETCH_RATIO_MASK) |
+				  RADEON_VERT_STRETCH_ENABLE |
+				  RADEON_VERT_STRETCH_BLEND |
+				  ((radeon_output->PanelYRes-1)<<12));
     }
 
 }
diff-tree 633c1fff10a3be4c9f48c1995e330d60bf6abbb2 (from 4f8010ce22043c0f8d60c0f49d270ce98c9d2466)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 12:11:41 2007 +0200

    radeon: Sync pages when enabling page flipping with EXA as well.
    
    Exclude the DRI window(s) though to avoid scribbling over 3D rendering.

diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 0ad0f7f..24018e8 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -69,7 +69,7 @@ static void RADEONDRITransitionMultiToSi
 static void RADEONDRITransitionSingleToMulti3d(ScreenPtr pScreen);
 
 #ifdef DAMAGE
-static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg);
 
 #if (DRIINFO_MAJOR_VERSION > 5 ||		\
      (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
@@ -406,16 +406,7 @@ static void RADEONLeaveServer(ScreenPtr 
 	int nrects = pDamageReg ? REGION_NUM_RECTS(pDamageReg) : 0;
 
 	if (nrects) {
-	    RegionRec region;
-
-	    REGION_NULL(pScreen, &region);
-	    REGION_SUBTRACT(pScreen, &region, pDamageReg, &info->driRegion);
-
-	    nrects = REGION_NUM_RECTS(&region);
-
-	    if (nrects) {
-		RADEONDRIRefreshArea(pScrn, nrects, REGION_RECTS(&region));
-	    }
+	    RADEONDRIRefreshArea(pScrn, pDamageReg);
 	}
     }
 #endif
@@ -1871,15 +1862,17 @@ void RADEONDRICloseScreen(ScreenPtr pScr
  */
 
 
-static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
+static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, RegionPtr pReg)
 {
     RADEONInfoPtr       info       = RADEONPTR(pScrn);
-    int                 i;
+    int                 i, num;
     ScreenPtr           pScreen    = pScrn->pScreen;
     RADEONSAREAPrivPtr  pSAREAPriv = DRIGetSAREAPrivate(pScreen);
 #ifdef USE_EXA
     PixmapPtr           pPix = pScreen->GetScreenPixmap(pScreen);
 #endif
+    RegionRec region;
+    BoxPtr pbox;
 
     if (!info->directRenderingInited || !info->CPStarted)
 	return;
@@ -1890,6 +1883,17 @@ static void RADEONDRIRefreshArea(ScrnInf
     if (!pSAREAPriv->pfAllowPageFlip && pSAREAPriv->pfCurrentPage == 0)
 	return;
 
+    REGION_NULL(pScreen, &region);
+    REGION_SUBTRACT(pScreen, &region, pReg, &info->driRegion);
+
+    num = REGION_NUM_RECTS(&region);
+
+    if (!num) {
+	goto out;
+    }
+
+    pbox = REGION_RECTS(&region);
+
     /* pretty much a hack. */
 
 #ifdef USE_EXA
@@ -1910,7 +1914,7 @@ static void RADEONDRIRefreshArea(ScrnInf
     if (!info->useEXA) {
 	/* Make sure accel has been properly inited */
 	if (info->accel == NULL || info->accel->SetupForScreenToScreenCopy == NULL)
-	    return;
+	    goto out;
 	if (info->tilingEnabled)
 	    info->dst_pitch_offset |= RADEON_DST_TILE_MACRO;
 	(*info->accel->SetupForScreenToScreenCopy)(pScrn,
@@ -1946,6 +1950,8 @@ static void RADEONDRIRefreshArea(ScrnInf
     info->dst_pitch_offset &= ~RADEON_DST_TILE_MACRO;
 #endif
 
+out:
+    REGION_NULL(pScreen, &region);
     DamageEmpty(info->pDamage);
 }
 
@@ -1959,16 +1965,13 @@ static void RADEONEnablePageFlip(ScreenP
 
     if (info->allowPageFlip) {
 	RADEONSAREAPrivPtr pSAREAPriv = DRIGetSAREAPrivate(pScreen);
+	BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1,
+		       .y2 = pScrn->virtualY - 1 };
+	RegionPtr pReg = REGION_CREATE(pScreen, &box, 1);
 
 	pSAREAPriv->pfAllowPageFlip = 1;
-
-#ifdef USE_XAA
-	if (!info->useEXA) {
-	    BoxRec box = { .x1 = 0, .y1 = 0, .x2 = pScrn->virtualX - 1,
-			   .y2 = pScrn->virtualY - 1 };
-	    RADEONDRIRefreshArea(pScrn, 1, &box);
-	}
-#endif
+	RADEONDRIRefreshArea(pScrn, pReg);
+	REGION_DESTROY(pScreen, pReg);
     }
 #endif
 }
diff-tree 4f8010ce22043c0f8d60c0f49d270ce98c9d2466 (from 7b527054a7c81d1d1dbc79d41b9e53064dab68cb)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 12:11:12 2007 +0200

    radeon: Don't synchronize DRI windows between pages when possible.

diff --git a/src/radeon.h b/src/radeon.h
index 1a91cfd..bf1444c 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -605,6 +605,7 @@ typedef struct {
     Bool              allowPageFlip;    /* Enable 3d page flipping */
 #ifdef DAMAGE
     DamagePtr         pDamage;
+    RegionRec         driRegion;
 #endif
     Bool              have3DWindows;    /* Are there any 3d clients? */
 
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index f057bdf..0ad0f7f 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -70,6 +70,11 @@ static void RADEONDRITransitionSingleToM
 
 #ifdef DAMAGE
 static void RADEONDRIRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
+
+#if (DRIINFO_MAJOR_VERSION > 5 ||		\
+     (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 1))
+static void RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num);
+#endif
 #endif
 
 /* Initialize the visual configs that are supported by the hardware.
@@ -401,7 +406,16 @@ static void RADEONLeaveServer(ScreenPtr 
 	int nrects = pDamageReg ? REGION_NUM_RECTS(pDamageReg) : 0;
 
 	if (nrects) {
-	    RADEONDRIRefreshArea(pScrn, nrects, REGION_RECTS(pDamageReg));
+	    RegionRec region;
+
+	    REGION_NULL(pScreen, &region);
+	    REGION_SUBTRACT(pScreen, &region, pDamageReg, &info->driRegion);
+
+	    nrects = REGION_NUM_RECTS(&region);
+
+	    if (nrects) {
+		RADEONDRIRefreshArea(pScrn, nrects, REGION_RECTS(&region));
+	    }
 	}
     }
 #endif
@@ -1490,6 +1504,11 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre
     pDRIInfo->TransitionTo3d = RADEONDRITransitionTo3d;
     pDRIInfo->TransitionSingleToMulti3D = RADEONDRITransitionSingleToMulti3d;
     pDRIInfo->TransitionMultiToSingle3D = RADEONDRITransitionMultiToSingle3d;
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 ||	\
+			(DRIINFO_MAJOR_VERSION == 5 &&	\
+			 DRIINFO_MINOR_VERSION >= 1))
+    pDRIInfo->ClipNotify     = RADEONDRIClipNotify;
+#endif
 
     pDRIInfo->createDummyCtx     = TRUE;
     pDRIInfo->createDummyCtxPriv = FALSE;
@@ -1753,7 +1772,11 @@ void RADEONDRICloseScreen(ScreenPtr pScr
 
      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		    "RADEONDRICloseScreen\n");
-    
+
+#ifdef DAMAGE
+     REGION_UNINIT(pScreen, &info->driRegion);
+#endif
+
      if (info->irq) {
 	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
 	drmCtlUninstHandler(info->drmFD);
@@ -2101,6 +2124,33 @@ static void RADEONDRITransitionTo2d(Scre
 	xf86ForceHWCursor (pScreen, FALSE);
 }
 
+#if defined(DAMAGE) && (DRIINFO_MAJOR_VERSION > 5 ||	\
+			(DRIINFO_MAJOR_VERSION == 5 &&	\
+			 DRIINFO_MINOR_VERSION >= 1))
+static void
+RADEONDRIClipNotify(ScreenPtr pScreen, WindowPtr *ppWin, int num)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+
+    REGION_UNINIT(pScreen, &info->driRegion);
+    REGION_NULL(pScreen, &info->driRegion);
+
+    if (num > 0) {
+	int i;
+
+	for (i = 0; i < num; i++) {
+	    WindowPtr pWin = ppWin[i];
+
+	    if (pWin) {
+		REGION_UNION(pScreen, &info->driRegion, &pWin->clipList,
+			     &info->driRegion);
+	    }
+	}
+    }
+}
+#endif
+
 void RADEONDRIAllocatePCIGARTTable(ScreenPtr pScreen)
 {
     ScrnInfoPtr        pScrn   = xf86Screens[pScreen->myNum];
diff-tree 7b527054a7c81d1d1dbc79d41b9e53064dab68cb (from d7ba9f001c0ab645984526afd0e64d1c6a6d654a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 12:10:33 2007 +0200

    radeon: Restore memmap registers even if only AGP location changed.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1d5cc36..87f1405 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3982,13 +3982,11 @@ static void RADEONAdjustMemMapRegisters(
     RADEONInfoPtr  info   = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 fb, agp;
-    int fb_loc_changed;
 
     fb = INREG(RADEON_MC_FB_LOCATION);
     agp = INREG(RADEON_MC_AGP_LOCATION);
-    fb_loc_changed = (fb != info->mc_fb_location);
 
-    if (fb_loc_changed || agp != info->mc_agp_location) {
+    if (fb != info->mc_fb_location || agp != info->mc_agp_location) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "DRI init changed memory map, adjusting ...\n");
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -4007,9 +4005,8 @@ static void RADEONAdjustMemMapRegisters(
 
 	    RADEONInitMemMapRegisters(pScrn, save, info);
 
-	    /* If MC_FB_LOCATION was changed, adjust the various offsets */
-	    if (fb_loc_changed)
-		    RADEONRestoreMemMapRegisters(pScrn, save);
+	    /* Adjust the various offsets */
+	    RADEONRestoreMemMapRegisters(pScrn, save);
     }
 
 #ifdef USE_EXA
diff-tree d7ba9f001c0ab645984526afd0e64d1c6a6d654a (from 8c7c22e22b6076abc80e4e1aaa8d1f4cf2f3ed14)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 11:39:54 2007 +0200

    radeon: Change a test to info->IsIGP from several IGP families.

diff --git a/src/radeon_video.c b/src/radeon_video.c
index 73c9efc..15e2101 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1437,9 +1437,7 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
         info->ecp_div = 1;
     ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
 
-    if ((info->ChipFamily == CHIP_FAMILY_RS100) || 
-	(info->ChipFamily == CHIP_FAMILY_RS200) ||
-	(info->ChipFamily == CHIP_FAMILY_RS300)) {
+    if (info->IsIGP) {
         /* Force the overlay clock on for integrated chips
 	 */
         ecp |= (1<<18);
diff-tree 8c7c22e22b6076abc80e4e1aaa8d1f4cf2f3ed14 (from 92fa7cc00688d7bfc1fb72e645ac30c6d92669c6)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 11:38:17 2007 +0200

    radeon: Wait for pending overlay flip to finish before emitting new one.

diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 9eae40d..af62a69 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -1094,6 +1094,7 @@
 #       define  RADEON_REG_LD_CTL_VBLANK_DURING_LOCK   0x00000002L
 #       define  RADEON_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L
 #       define  RADEON_REG_LD_CTL_LOCK_READBACK        0x00000008L
+#       define  RADEON_REG_LD_CTL_FLIP_READBACK        0x00000010L
 #define RADEON_OV0_SCALE_CNTL               0x0420
 #       define  RADEON_SCALER_HORZ_PICK_NEAREST    0x00000004L
 #       define  RADEON_SCALER_VERT_PICK_NEAREST    0x00000008L
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 7b85108..73c9efc 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2966,8 +2966,14 @@ RADEONPutImage(
 
    offset = (pPriv->video_offset) + (top * dstPitch);
 
-   if(pPriv->doubleBuffer)
+   if(pPriv->doubleBuffer) {
+	unsigned char *RADEONMMIO = info->MMIO;
+
+	/* Wait for last flip to take effect */
+	while(!(INREG(RADEON_OV0_REG_LOAD_CNTL) & RADEON_REG_LD_CTL_FLIP_READBACK));
+
 	offset += pPriv->currentBuffer * new_size;
+   }
 
    dst_start = info->FB + offset;
 
diff-tree 92fa7cc00688d7bfc1fb72e645ac30c6d92669c6 (from 5cb20c2dc5eca9d7d7d78e9924ea1b90076e7253)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Thu Aug 23 11:38:16 2007 +0200

    radeon: Don't call RADEONDRIRefreshArea when the damaged region is empty.

diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 7949c5b..f057bdf 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -398,10 +398,10 @@ static void RADEONLeaveServer(ScreenPtr 
 #ifdef DAMAGE
     if (info->pDamage) {
 	RegionPtr pDamageReg = DamageRegion(info->pDamage);
+	int nrects = pDamageReg ? REGION_NUM_RECTS(pDamageReg) : 0;
 
-	if (pDamageReg) {
-	    RADEONDRIRefreshArea(pScrn, REGION_NUM_RECTS(pDamageReg),
-				 REGION_RECTS(pDamageReg));
+	if (nrects) {
+	    RADEONDRIRefreshArea(pScrn, nrects, REGION_RECTS(pDamageReg));
 	}
     }
 #endif
diff-tree 5cb20c2dc5eca9d7d7d78e9924ea1b90076e7253 (from 9d6261c024c697a211da4b6300420153eb72a264)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Aug 23 18:46:41 2007 +1000

    radeon: bug 11899 + debian 435040 - test for usefbdev before calling int10
    (cherry picked from commit 3334c247540b113f9c4a5ce1879d8648a45a959a)

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1f4d0c2..1d5cc36 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5852,7 +5852,7 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONEnterVT\n");
 
-    if (INREG(RADEON_CONFIG_MEMSIZE) == 0) { /* Softboot V_BIOS */
+    if (!info->FBDev && (INREG(RADEON_CONFIG_MEMSIZE) == 0)) { /* Softboot V_BIOS */
        xf86Int10InfoPtr pInt;
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "zero MEMSIZE, probably at D3cold. Re-POSTing via int10.\n");
diff-tree 9d6261c024c697a211da4b6300420153eb72a264 (from 7bc1f862bc5f992f213143fbafef52459ba7db4a)
Author: Roland Bär <roland at verifysoft.de>
Date:   Thu Aug 23 18:33:34 2007 +1000

    radeon: bug 11860 fix some mem leaks

diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index d7ff643..c697f65 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -303,6 +303,7 @@ RADEONProbe(DriverPtr drv, int flags)
 		foundScreen          = TRUE;
 	    }
 
+            xfree(pEnt);
 	    pEnt = xf86GetEntityInfo(usedChips[i]);
 
             /* create a RADEONEntity for all chips, even with
diff-tree 7bc1f862bc5f992f213143fbafef52459ba7db4a (from 9d38c8aa1a7d6fb1af41ee8abdb4a95f94843538)
Author: Roland Bär <roland at verifysoft.de>
Date:   Thu Aug 23 18:37:35 2007 +1000

    radeon: bug 11861 - dead code removal in radeon_video.c
    (cherry picked from commit 8e3a6f83016cd8c4cfd43ceee4cbf0a8dc018b2a)

diff --git a/src/radeon_video.c b/src/radeon_video.c
index a38931c..7b85108 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -3444,7 +3444,8 @@ RADEONPutVideo(
    id = FOURCC_YUY2;
    
    top = ya>>16;
-
+#if 0
+   /* setting the ID above makes this useful - needs revisiting */
    switch(id) {
    case FOURCC_YV12:
    case FOURCC_I420:
@@ -3462,6 +3463,10 @@ RADEONPutVideo(
         srcPitch = (width<<1);
         break;
    }
+#else
+   dstPitch = ((width<<1) + 15) & ~15;
+   srcPitch = (width<<1);
+#endif
 
    new_size = dstPitch * height;
    new_size = new_size + 0x1f; /* for aligning */
diff-tree 9d38c8aa1a7d6fb1af41ee8abdb4a95f94843538 (from e4c8969b48a6c8dcc4e7f9852479d24a0204fc0d)
Author: Dave Airlie <airlied at clockmaker.usersys.redhat.com>
Date:   Thu Aug 23 20:10:24 2007 +1000

    radeon: cleanup some warnings

diff --git a/src/radeon.h b/src/radeon.h
index 6128345..1a91cfd 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -960,6 +960,10 @@ extern void RADEONAdjustPLL2RegistersFor
 extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
                                   DisplayModePtr mode, BOOL IsPrimary);
 
+extern void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+extern void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore);
+
 #ifdef XF86DRI
 #ifdef USE_XAA
 extern void        RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 9d8946f..975fc07 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -623,6 +623,7 @@ Bool RADEONGetTVInfoFromBIOS (xf86Output
 		return FALSE;
 	}
     }
+    return FALSE;
 }
 
 /* Read PLL parameters from BIOS block.  Default to typical values if there
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0dc8d56..1f4d0c2 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4256,7 +4256,6 @@ void RADEONRestoreFPRegisters(ScrnInfoPt
 void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
     OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
@@ -4267,7 +4266,6 @@ void RADEONRestoreFP2Registers(ScrnInfoP
 void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
     OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
@@ -4390,7 +4388,7 @@ static CARD16 RADEONGetVTimingTablesAddr
 }
 
 /* Restore horizontal/vertical timing code tables */
-static void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -4466,7 +4464,7 @@ static void RADEONRestoreTVHVRegisters(S
 }
 
 /* restore TV RESTART registers */
-static void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -5259,7 +5257,6 @@ static void RADEONSaveTVRegisters(ScrnIn
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    unsigned i;
 
     ErrorF("Entering TV Save\n");
 
diff-tree e4c8969b48a6c8dcc4e7f9852479d24a0204fc0d (from 81a8093f2ffdce59d4e8a44f65f3d5c771fd6425)
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Aug 23 19:56:21 2007 +1000

    updated release numbering for randr 1.2

diff --git a/configure.ac b/configure.ac
index 441e723..b178224 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-ati],
-        6.6.193,
+        6.7.191,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-ati)
 
diff-tree 81a8093f2ffdce59d4e8a44f65f3d5c771fd6425 (from parents)
Merge: c08e6ec9e7ac06caee53689b0ec50ef6a7a0ba37 53a67e31904bec9a3aa1bd24de8034dcafea1d2a
Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Aug 23 19:51:47 2007 +1000

    Merge remote branch 'origin/randr-1.2'

diff-tree c08e6ec9e7ac06caee53689b0ec50ef6a7a0ba37 (from parents)
Merge: 5793e8753d11432bf95c7c6dd80c811e16aba058 a0d0fcd3bab765b4db25e04884fd8a342abb9c66
Author: Dave Airlie <airlied at clockmaker.usersys.redhat.com>
Date:   Thu Aug 23 19:42:19 2007 +1000

    Merge branch 'master' into randr-merge
    
    Conflicts:
    
    	src/radeon.h
    	src/radeon_bios.c
    	src/radeon_display.c
    	src/radeon_dri.c
    	src/radeon_driver.c
    	src/radeon_modes.c
    	src/radeon_probe.h
    	src/radeon_video.c

diff --cc src/radeon.h
index a8f72fc,b19b017..aee4c3e
@@@ -907,14 -897,13 +906,15 @@@
  extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
  extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
  extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
 -extern void        RADEONSetupConnectors(ScrnInfoPtr pScrn);
 -extern Bool        RADEONMapControllers(ScrnInfoPtr pScrn);
 -extern void        RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable);
 +extern Bool        RADEONSetupConnectors(ScrnInfoPtr pScrn);
 +extern void        RADEONPrintPortMap(ScrnInfoPtr pScrn);
 +extern void        RADEONEnableDisplay(xf86OutputPtr pPort, BOOL bEnable);
  extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
  extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
 -extern void        RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn);
 -extern void        RADEONBlank(ScrnInfoPtr pScrn, Bool Blank);
 +extern void        RADEONGetTVDacAdjInfo(xf86OutputPtr output);
 +extern void        RADEONUnblank(ScrnInfoPtr pScrn);
++extern void        RADEONUnblank(ScrnInfoPtr pScrn);
 +extern void        RADEONBlank(ScrnInfoPtr pScrn);
  extern void        RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
  						   int PowerManagementMode,
  						   int flags);
diff --cc src/radeon_driver.c
index ae34cf3,74323c9..f338d16
@@@ -5567,8 -6566,10 +5567,10 @@@
      if (unblank) SetTimeSinceLastInputEvent();
  
      if ((pScrn != NULL) && pScrn->vtSema) {
- 	if (unblank)  RADEONUnblank(pScrn);
- 	else          RADEONBlank(pScrn);
+ 	if (unblank)
 -	    RADEONBlank(pScrn, FALSE);
++	    RADEONUnblank(pScrn);
+ 	else
 -	    RADEONBlank(pScrn, TRUE);
++	    RADEONBlank(pScrn);
      }
      return TRUE;
  }
diff-tree 53a67e31904bec9a3aa1bd24de8034dcafea1d2a (from e9719e8e02eef46717ae9b4d8c7998466dac30cb)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 21 21:20:41 2007 -0400

    RADEON: Fix color problem on pre-R3xx chips tv-out

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 1f61250..522f7ed 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -620,7 +620,6 @@ void RADEONAdjustCrtcRegistersForTV(Scrn
     save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
 	((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
 
-    save->disp_merge_cntl |= RADEON_DISP_RGB_OFFSET_EN;
 }
 
 void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
@@ -705,7 +704,6 @@ void RADEONAdjustCrtc2RegistersForTV(Scr
     save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
 	((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
 
-    save->disp2_merge_cntl |= RADEON_DISP2_RGB_OFFSET_EN;
 }
 
 void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
diff-tree e9719e8e02eef46717ae9b4d8c7998466dac30cb (from 36c22a49580d86a6518b67f31a78bd53d39491af)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 21 21:17:20 2007 -0400

    RADEON: more tv out fixes and clean up

diff --git a/src/radeon.h b/src/radeon.h
index a778cb8..bf60ab6 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -330,6 +330,7 @@ typedef struct {
     CARD32 	      tv_data_delay_b;
     CARD32 	      tv_dac_cntl;
     CARD32 	      tv_pll_cntl;
+    CARD32 	      tv_pll_cntl1;
     CARD32	      tv_pll_fine_cntl;
     CARD32 	      tv_modulator_cntl1;
     CARD32 	      tv_modulator_cntl2;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c822937..57bb0bb 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4403,15 +4403,6 @@ static void RADEONRestoreTVTimingTables(
     hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
     vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
 
-    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
-				   | RADEON_CRT_ASYNC_RST
-				   | RADEON_RESTART_PHASE_FIX
-				   | RADEON_CRT_FIFO_CE_EN
-				   | RADEON_TV_FIFO_CE_EN
-				   | RADEON_TV_ON));
-
-    /*OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);*/
-
     for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
 	tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
 	RADEONWriteTVFIFO(pScrn, hTable, tmp);
@@ -4511,12 +4502,9 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
 
     ErrorF("Entering Restore TV\n");
 
-    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
-
     OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
 				   | RADEON_TV_ASYNC_RST
 				   | RADEON_CRT_ASYNC_RST
-				   | RADEON_RESTART_PHASE_FIX
 				   | RADEON_TV_FIFO_ASYNC_RST));
 
     /* Temporarily turn the TV DAC off */
@@ -4534,8 +4522,7 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
 
     OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
 				   | RADEON_TV_ASYNC_RST
-				   | RADEON_CRT_ASYNC_RST
-				   | RADEON_RESTART_PHASE_FIX));
+				   | RADEON_CRT_ASYNC_RST));
 
     ErrorF("Restore TV Restarts\n");
     RADEONRestoreTVRestarts(pScrn, restore);
@@ -4545,8 +4532,7 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
   
 
     OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
-				   | RADEON_TV_ASYNC_RST
-				   | RADEON_RESTART_PHASE_FIX));
+				   | RADEON_TV_ASYNC_RST));
 
     ErrorF("Restore TV standard\n");
     RADEONRestoreTVOutputStd(pScrn, restore);
@@ -5305,6 +5291,7 @@ static void RADEONSaveTVRegisters(ScrnIn
     save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
 
     save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
+    save->tv_pll_cntl1 = INPLL(pScrn, RADEON_TV_PLL_CNTL1);
 
     ErrorF("Save TV timing tables\n");
 
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 4e4d874..9eae40d 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3141,6 +3141,8 @@
 #       define RADEON_RGB_SRC_SEL_RMX		  (1 <<  8)
 #       define RADEON_RGB_SRC_SEL_CRTC2		  (2 <<  8)
 #       define RADEON_RGB_CONVERT_BY_PASS	  (1 << 10)
+#       define RADEON_UVRAM_READ_MARGIN_SHIFT	  16
+#       define RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT	  20
 #	define RADEON_TVOUT_SCALE_EN 		  (1 << 26)
 #define RADEON_TV_SYNC_CNTL                          0x0808
 #       define RADEON_SYNC_OE                     (1 <<  0)
@@ -3211,6 +3213,9 @@
 #	define RADEON_SLEW_RATE_LIMIT		 (1 << 23)
 #       define RADEON_CY_FILT_BLEND_SHIFT        28
 #define RADEON_TV_MODULATOR_CNTL2                    0x0874
+#       define RADEON_TV_U_BURST_LEVEL_MASK     0x1ff
+#       define RADEON_TV_V_BURST_LEVEL_MASK     0x1ff
+#       define RADEON_TV_V_BURST_LEVEL_SHIFT    16
 #define RADEON_TV_CRC_CNTL                           0x0890
 #define RADEON_TV_UV_ADR                             0x08ac
 #	define RADEON_MAX_UV_ADR_MASK		 0x000000ff
@@ -3242,6 +3247,10 @@
 #       define RADEON_TVPLL_RESET                (1 <<  1)
 #       define RADEON_TVPLL_SLEEP                (1 <<  3)
 #       define RADEON_TVPLL_REFCLK_SEL           (1 <<  4)
+#       define RADEON_TVPCP_SHIFT                8
+#       define RADEON_TVPCP_MASK                 (7 << 8)
+#       define RADEON_TVPVG_SHIFT                11
+#       define RADEON_TVPVG_MASK                 (7 << 11)
 #       define RADEON_TVPDC_SHIFT                14
 #       define RADEON_TVPDC_MASK                 (3 << 14)
 #       define RADEON_TVPLL_TEST_DIS             (1 << 31)
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 73bf34d..1f61250 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -205,8 +205,7 @@ static Bool RADEONInitTVRestarts(xf86Out
     /* FIXME: need to revisit this when we add more modes */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_PAL_M)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -257,7 +256,7 @@ static Bool RADEONInitTVRestarts(xf86Out
      */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M||
+	radeon_output->tvStd == TV_STD_PAL_M ||
 	radeon_output->tvStd == TV_STD_PAL_60)
 	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
     else
@@ -280,8 +279,7 @@ static Bool RADEONInitTVRestarts(xf86Out
     /* Compute H_INC from hSize */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M ||
-	radeon_output->tvStd == TV_STD_PAL_60)
+	radeon_output->tvStd == TV_STD_PAL_M)
 	hInc = (CARD16)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
 			(radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
     else
@@ -314,8 +312,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
     /* FIXME: need to revisit this when we add more modes */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+	radeon_output->tvStd == TV_STD_PAL_M)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -332,10 +329,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
     save->tv_linear_gain_settings = (0x100 << RADEON_UV_GAIN_SHIFT) |
 	                            (0x100 << RADEON_Y_GAIN_SHIFT);
 
-    save->tv_master_cntl = (RADEON_RESTART_PHASE_FIX
-			    | RADEON_VIN_ASYNC_RST
-			    | RADEON_AUD_ASYNC_RST
-			    | RADEON_DVS_ASYNC_RST
+    save->tv_master_cntl = (RADEON_VIN_ASYNC_RST
 			    | RADEON_CRT_FIFO_CE_EN
 			    | RADEON_TV_FIFO_CE_EN
 			    | RADEON_TV_ON);
@@ -343,24 +337,32 @@ void RADEONInitTVRegisters(xf86OutputPtr
     if (!IS_R300_VARIANT)
 	save->tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
 
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J)
+	save->tv_master_cntl |= RADEON_RESTART_PHASE_FIX;
+
     save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
 	                       | RADEON_SYNC_TIP_LEVEL
 	                       | RADEON_YFLT_EN
 	                       | RADEON_UVFLT_EN
-	                       | (0x3b << RADEON_BLANK_LEVEL_SHIFT)
-	                       | (0x6 << RADEON_CY_FILT_BLEND_SHIFT);
+	                       | (2 << RADEON_CY_FILT_BLEND_SHIFT);
 
     if (radeon_output->tvStd == TV_STD_NTSC ||
-	radeon_output->tvStd == TV_STD_NTSC_J ||
-	radeon_output->tvStd == TV_STD_PAL_M ||
-	radeon_output->tvStd == TV_STD_PAL_60 ||
-	radeon_output->tvStd == TV_STD_SCART_PAL) {
-	save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT);
-	save->tv_modulator_cntl2 = 0x00000191;
+	radeon_output->tvStd == TV_STD_NTSC_J) {
+	save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT)
+	                            | (0x3b << RADEON_BLANK_LEVEL_SHIFT);
+	save->tv_modulator_cntl2 = (-111 & RADEON_TV_U_BURST_LEVEL_MASK) |
+	    ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
+    } else if (radeon_output->tvStd == TV_STD_SCART_PAL) {
+	save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN;
+	save->tv_modulator_cntl2 = (0 & RADEON_TV_U_BURST_LEVEL_MASK) |
+	    ((0 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
     } else {
 	save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
-	                            | (0x3b << RADEON_SET_UP_LEVEL_SHIFT);
-	save->tv_modulator_cntl2 = 0x003e01b2;
+	                            | (0x3b << RADEON_SET_UP_LEVEL_SHIFT)
+	                            | (0x3b << RADEON_BLANK_LEVEL_SHIFT);
+	save->tv_modulator_cntl2 = (-78 & RADEON_TV_U_BURST_LEVEL_MASK) |
+	    ((62 & RADEON_TV_V_BURST_LEVEL_MASK) << RADEON_TV_V_BURST_LEVEL_SHIFT);
     }
 
     save->pll_test_cntl = 0;
@@ -370,8 +372,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
 				 | RADEON_CMP_BLU_EN
 				 | RADEON_DAC_DITHER_EN);
 
-    save->tv_rgb_cntl = (RADEON_RGB_DITHER_EN | RADEON_TVOUT_SCALE_EN
-			 | (0x0b << 16) | (0x07 << 20));
+    save->tv_rgb_cntl = (RADEON_RGB_DITHER_EN
+			 | RADEON_TVOUT_SCALE_EN
+			 | (0x0b << RADEON_UVRAM_READ_MARGIN_SHIFT)
+			 | (0x07 << RADEON_FIFORAM_FFMACRO_READ_MARGIN_SHIFT));
 
     if (IsPrimary) {
 	if (radeon_output->Flags & RADEON_USE_RMX)
@@ -445,9 +449,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
     save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | (8 << 16) | (6 << 20);
 
     if (radeon_output->tvStd == TV_STD_NTSC ||
-        radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_NTSC_J)
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
     else
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
@@ -468,9 +470,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
 #endif
 
     if (radeon_output->tvStd == TV_STD_NTSC ||
-        radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_NTSC_J)
 	save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
 	    (((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
 	    ((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
@@ -483,6 +483,12 @@ void RADEONInitTVRegisters(xf86OutputPtr
 	    (((PAL_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
 	    ((PAL_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
 
+    save->tv_pll_cntl1 =  (((4 & RADEON_TVPCP_MASK)<< RADEON_TVPCP_SHIFT) |
+			   ((4 & RADEON_TVPVG_MASK) << RADEON_TVPVG_SHIFT) |
+			   ((1 & RADEON_TVPDC_MASK)<< RADEON_TVPDC_SHIFT) |
+			   RADEON_TVCLK_SRC_SEL_TVPLL |
+			   RADEON_TVPLL_TEST_DIS);
+
     save->tv_upsamp_and_gain_cntl = RADEON_YUPSAMP_EN | RADEON_UVUPSAMP_EN;
 
     save->tv_uv_adr = 0xc8;
@@ -595,8 +601,7 @@ void RADEONAdjustCrtcRegistersForTV(Scrn
     /* FIXME: need to revisit this when we add more modes */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_PAL_M)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -628,8 +633,7 @@ void RADEONAdjustPLLRegistersForTV(ScrnI
     /* FIXME: need to revisit this when we add more modes */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_PAL_M)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -682,8 +686,7 @@ void RADEONAdjustCrtc2RegistersForTV(Scr
     /* FIXME: need to revisit this when we add more modes */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_PAL_M)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -715,8 +718,7 @@ void RADEONAdjustPLL2RegistersForTV(Scrn
     /* FIXME: need to revisit this when we add more modes */
     if (radeon_output->tvStd == TV_STD_NTSC ||
 	radeon_output->tvStd == TV_STD_NTSC_J ||
-        radeon_output->tvStd == TV_STD_PAL_M ||
-        radeon_output->tvStd == TV_STD_PAL_60)
+        radeon_output->tvStd == TV_STD_PAL_M)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
diff-tree 36c22a49580d86a6518b67f31a78bd53d39491af (from 9470bd67731059f26859ed5f0bea3ade09e2c80c)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 21 20:28:39 2007 -0400

    RADEON: fix tv-out on R3xx
    
    R3xx apparently needs the tv clock forced on.

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 8dbe974..73bf34d 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -338,9 +338,11 @@ void RADEONInitTVRegisters(xf86OutputPtr
 			    | RADEON_DVS_ASYNC_RST
 			    | RADEON_CRT_FIFO_CE_EN
 			    | RADEON_TV_FIFO_CE_EN
-			    | RADEON_TVCLK_ALWAYS_ONb
 			    | RADEON_TV_ON);
 
+    if (!IS_R300_VARIANT)
+	save->tv_master_cntl |= RADEON_TVCLK_ALWAYS_ONb;
+
     save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
 	                       | RADEON_SYNC_TIP_LEVEL
 	                       | RADEON_YFLT_EN
diff-tree 9470bd67731059f26859ed5f0bea3ade09e2c80c (from b275febdb0918e8cebdffbb433b0eeb3ff4d3746)
Author: Alex Deucher <alex at botch2.com>
Date:   Mon Aug 20 20:54:06 2007 -0400

    RADEON: Add DefaultConnectorTable option
    
    This option skips the parsing the BIOS connector table
    and falls back to chip specific defaults.
    Also remove man page section for the now gone bioshotkeys
    option.

diff --git a/man/radeon.man b/man/radeon.man
index fcb6d73..63bbb9b 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -363,13 +363,6 @@ life by reducing power usage.  Some user
 with this enabled.  The default is
 .B off.
 .TP
-.BI "Option \*qBIOSHotkeys\*q \*q" boolean \*q
-Enable BIOS hotkey output switching. This allows the BIOS to toggle outputs
-using hotkeys (e.g., fn-f7, etc.).  Since the driver does not support ACPI, 
-there is no way to validate modes on an output switch and the BIOS can 
-potentially change things behind the driver's back.  The default is
-.B off.
-.TP
 .BI "Option \*qVGAAccess\*q \*q" boolean \*q
 Tell the driver if it can do legacy VGA IOs to the card. This is
 necessary for properly resuming consoles when in VGA text mode, but
@@ -406,6 +399,12 @@ for RN50/ES1000 and
 .B on 
 for others.
 .TP
+.BI "Option \*qDefaultConnectorTable\*q \*q" boolean \*q
+Enable this option to skip the BIOS connector table parsing and use the
+driver defaults for each chip.  
+The default is
+.B off 
+.TP
 
 .SH SEE ALSO
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
diff --git a/src/radeon.h b/src/radeon.h
index 4f7f60e..a778cb8 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -151,7 +151,8 @@ typedef enum {
     OPTION_ACCELMETHOD,
     OPTION_CONSTANTDPI,
     OPTION_CONNECTORTABLE,
-    OPTION_DRI
+    OPTION_DRI,
+    OPTION_DEFAULT_CONNECTOR_TABLE
 } RADEONOpts;
 
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ae34cf3..c822937 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -188,6 +188,7 @@ static const OptionInfoRec RADEONOptions
     { OPTION_CONSTANTDPI,    "ConstantDPI",	 OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DRI,            "DRI",       	 OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_CONNECTORTABLE, "ConnectorTable",   OPTV_STRING,  {0}, FALSE },
+    { OPTION_DEFAULT_CONNECTOR_TABLE, "DefaultConnectorTable", OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 73e44f3..9650a39 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2344,34 +2344,29 @@ void RADEONInitConnector(xf86OutputPtr o
 
 }
 
-/*
- * initialise the static data sos we don't have to re-do at randr change */
-Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
+static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    xf86OutputPtr output;
-    char *optstr;
-    int i = 0;
-    int num_vga = 0;
-    int num_dvi = 0;
 
-    /* We first get the information about all connectors from BIOS.
-     * This is how the card is phyiscally wired up.
-     * The information should be correct even on a OEM card.
-     * If not, we may have problem -- need to use MonitorLayout option.
-     */
-    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	info->BiosConnector[i].valid = FALSE;
-	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
-	info->BiosConnector[i].DACType = DAC_UNKNOWN;
-	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
-	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
-    }
+    if (info->IsMobility) {
+	/* Below is the most common setting, but may not be true */
+	if (info->IsIGP) {
+	    info->BiosConnector[0].DDCType = DDC_LCD;
+	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
+	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+	    info->BiosConnector[0].valid = TRUE;
 
-    if (!RADEONGetConnectorInfoFromBIOS(pScrn)) {
-	if (info->IsMobility) {
-	    /* Below is the most common setting, but may not be true */
+	    /* IGP only has TVDAC */
+	    if (info->ChipFamily == CHIP_FAMILY_RS400)
+		info->BiosConnector[1].DDCType = DDC_CRT2;
+	    else
+		info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].DACType = DAC_TVDAC;
+	    info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	    info->BiosConnector[1].valid = TRUE;
+	} else {
 #if defined(__powerpc__)
 	    info->BiosConnector[0].DDCType = DDC_DVI;
 #else
@@ -2387,9 +2382,28 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[1].TMDSType = TMDS_EXT;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
 	    info->BiosConnector[1].valid = TRUE;
+	}
+    } else {
+	/* Below is the most common setting, but may not be true */
+	if (info->IsIGP) {
+	    if (info->ChipFamily == CHIP_FAMILY_RS400)
+		info->BiosConnector[0].DDCType = DDC_CRT2;
+	    else
+		info->BiosConnector[0].DDCType = DDC_VGA;
+	    info->BiosConnector[0].DACType = DAC_TVDAC;
+	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_CRT;
+	    info->BiosConnector[0].valid = TRUE;
 
+	    /* not sure what a good default DDCType for DVI on 
+	     * IGP desktop chips is
+	     */
+	    info->BiosConnector[1].DDCType = DDC_MONID; /* DDC_DVI? */
+	    info->BiosConnector[1].DACType = DAC_UNKNOWN;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
+	    info->BiosConnector[1].valid = TRUE;
 	} else {
-	    /* Below is the most common setting, but may not be true */
 	    info->BiosConnector[0].DDCType = DDC_DVI;
 	    info->BiosConnector[0].DACType = DAC_TVDAC;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
@@ -2402,35 +2416,68 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
 	    info->BiosConnector[1].valid = TRUE;
 	}
+    }
 
-	if (info->InternalTVOut) {
-	    info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
-	    info->BiosConnector[2].DACType = DAC_TVDAC;
-	    info->BiosConnector[2].TMDSType = TMDS_NONE;
-	    info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
-	    info->BiosConnector[2].valid = TRUE;
-	}
+    if (info->InternalTVOut) {
+	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
+	info->BiosConnector[2].DACType = DAC_TVDAC;
+	info->BiosConnector[2].TMDSType = TMDS_NONE;
+	info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[2].valid = TRUE;
+    }
+
+    /* Some cards have the DDC lines swapped and we have no way to
+     * detect it yet (Mac cards)
+     */
+    if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
+	info->BiosConnector[0].DDCType = DDC_VGA;
+	info->BiosConnector[1].DDCType = DDC_DVI;
+    }
+
+}
+
+/*
+ * initialise the static data sos we don't have to re-do at randr change */
+Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    xf86OutputPtr output;
+    char *optstr;
+    int i = 0;
+    int num_vga = 0;
+    int num_dvi = 0;
 
-       /* Some cards have the DDC lines swapped and we have no way to
-        * detect it yet (Mac cards)
-        */
-       if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-           info->BiosConnector[0].DDCType = DDC_VGA;
-           info->BiosConnector[1].DDCType = DDC_DVI;
-        }
+    /* We first get the information about all connectors from BIOS.
+     * This is how the card is phyiscally wired up.
+     * The information should be correct even on a OEM card.
+     */
+    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	info->BiosConnector[i].valid = FALSE;
+	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[i].DACType = DAC_UNKNOWN;
+	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
+    }
+
+    if (xf86ReturnOptValBool(info->Options, OPTION_DEFAULT_CONNECTOR_TABLE, FALSE)) {
+	RADEONSetupGenericConnectors(pScrn);
+    } else {
+	if (!RADEONGetConnectorInfoFromBIOS(pScrn))
+	    RADEONSetupGenericConnectors(pScrn);
     }
 
     if (info->HasSingleDAC) {
         /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
-        if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
-            info->BiosConnector[0].DACType = DAC_TVDAC;
-            info->BiosConnector[1].DACType = DAC_NONE;
-        } else {
-            info->BiosConnector[1].DACType = DAC_TVDAC;
-            info->BiosConnector[0].DACType = DAC_NONE;
-        }
+	for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT)
+		info->BiosConnector[i].DACType = DAC_TVDAC;
+	}
     } else if (!pRADEONEnt->HasCRTC2) {
-        info->BiosConnector[0].DACType = DAC_PRIMARY;
+	for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	    if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT)
+		info->BiosConnector[i].DACType = DAC_PRIMARY;
+	}
     }
 
     /* parse connector table option */
diff-tree a0d0fcd3bab765b4db25e04884fd8a342abb9c66 (from d0895f67e327bb268fd59fcfd8fc22678d804f57)
Author: iLisa Wu <liswu at ati.com>
Date:   Mon Aug 20 15:44:07 2007 +0200

    Fix crash with no valid mode in xorg.conf's modelist and empty Virtual
    
    If the resolution defined in xorg.conf failed to find a matching mode in the
    supported modelist, and no virtual desktop dimensions are defined the xorg.conf
    either, virtual X and Y dimension will be set to 0 which will cause Xserver
    crash.
    
    (Novell bugzilla #296856, closed)

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 1a63971..e1635e0 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -299,6 +299,8 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
     DisplayModePtr  first      = NULL;
     DisplayModePtr  ddcModes   = NULL;
     int             count      = 0;
+    int             maxXRes    = 0;
+    int             maxYRes    = 0;
     int             i, width, height;
     ScrnInfoPtr pScrn = pScrn1;
 
@@ -334,13 +336,13 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 		p->Flags     |= RADEON_USE_RMX;
 	    }
 
-	    maxVirtX = MAX(maxVirtX, p->HDisplay);
-	    maxVirtY = MAX(maxVirtY, p->VDisplay);
+	    maxXRes = maxVirtX = MAX(maxVirtX, p->HDisplay);
+	    maxYRes = maxVirtY = MAX(maxVirtY, p->VDisplay);
 	    count++;
 
 	    last = p;
 	}
-
+    
 	/* Match up modes that are specified in the XF86Config file */
 	if (ppModeName[0]) {
 	    DisplayModePtr  next;
@@ -378,9 +380,21 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 			    break;
 			}
 		    }
+		    if (!p) {
+			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+				   " %dx%d is not supported by the device\n",
+				   width, height);
+		    }
 		}
 	    }
-
+	    /* just for sanity check, if maxVirtX and maxVirtY are not
+	     * specified, set max resolution that panel support for the max
+	     * virtual dimensions */
+	    if ((!maxVirtX) || (!maxVirtY)) {
+		maxVirtX = maxXRes;
+		maxVirtY = maxYRes;
+	    }
+	    
 	    /*
 	     * Add remaining DDC modes if they're smaller than the user
 	     * specified modes
diff-tree b275febdb0918e8cebdffbb433b0eeb3ff4d3746 (from a90d675832ddb02c81ace010ccbf02619b70edac)
Author: Alex Deucher <alex at samba.(none)>
Date:   Sun Aug 19 20:55:32 2007 -0400

    RADEON: turn off TVCLK when blanking tv encoder

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 4334016..ec0cdd9 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -368,6 +368,9 @@ void RADEONEnableDisplay(xf86OutputPtr o
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } else if (radeon_output->MonType == MT_STV ||
 		   radeon_output->MonType == MT_CTV) {
+	    tmp = INREG(RADEON_TV_MASTER_CNTL);
+	    tmp |= RADEON_TV_ON;
+	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
 	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
 	}
     } else {
@@ -422,6 +425,9 @@ void RADEONEnableDisplay(xf86OutputPtr o
 		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 	    }
         } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+	    tmp = INREG(RADEON_TV_MASTER_CNTL);
+	    tmp &= ~RADEON_TV_ON;
+	    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
 	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
 	}
     }
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index db5288a..8dbe974 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -338,6 +338,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
 			    | RADEON_DVS_ASYNC_RST
 			    | RADEON_CRT_FIFO_CE_EN
 			    | RADEON_TV_FIFO_CE_EN
+			    | RADEON_TVCLK_ALWAYS_ONb
 			    | RADEON_TV_ON);
 
     save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
diff-tree a90d675832ddb02c81ace010ccbf02619b70edac (from 5793e8753d11432bf95c7c6dd80c811e16aba058)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 16 21:55:14 2007 -0400

    RADEON: fix Xv clipping and overlay sourcing
    
    - Basically just copied from the intel driver.  I'm planning to push
    this to the server soon, but add it now to get things working
    and to provide compat for older servers.
    
    - Overlay crtc source control attribute now called XV_CRTC
    The old attribute XV_SWITCHCRT has been removed.  If anyone cares,
    we can add it back as an alias to XV_CRTC
    XV_CRTC: -1 auto, 0 crtc0, 1 crtc1

diff --git a/src/radeon.h b/src/radeon.h
index a8f72fc..4f7f60e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -460,7 +460,6 @@ typedef struct {
     Bool              IsMobility;       /* Mobile chips for laptops */
     Bool              IsIGP;            /* IGP chips */
     Bool              HasSingleDAC;     /* only TVDAC on chip */
-    Bool              OverlayOnCRTC2;
     Bool              ddc_mode;         /* Validate mode by matching exactly
 					 * the modes supported in DDC data
 					 */
@@ -948,8 +947,6 @@ void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
 void
 RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
-void
-RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox);
 
 extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
 					   DisplayModePtr mode, xf86OutputPtr output);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 8e71330..434034c 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -1296,28 +1296,3 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr cr
     return pMode;
 }
 
-void
-RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
-{
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int c;
-    int crtc_num = 0;
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-    {
-        xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-	if (!crtc->enabled)
-	    continue;
-
-	if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y))
-	    crtc_num = c;
-    }
-
-    if (crtc_num == 1)
-        info->OverlayOnCRTC2 = TRUE;
-    else
-        info->OverlayOnCRTC2 = FALSE;
-}
-
diff --git a/src/radeon_video.c b/src/radeon_video.c
index dbf66da..a38931c 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -106,7 +106,7 @@ static Atom xvBrightness, xvColorKey, xv
 static Atom xvRedIntensity, xvGreenIntensity, xvBlueIntensity;
 static Atom xvContrast, xvHue, xvColor, xvAutopaintColorkey, xvSetDefaults;
 static Atom xvGamma, xvColorspace;
-static Atom xvSwitchCRT;
+static Atom xvCRTC;
 static Atom xvEncoding, xvFrequency, xvVolume, xvMute,
 	     xvDecBrightness, xvDecContrast, xvDecHue, xvDecColor, xvDecSaturation,
 	     xvTunerStatus, xvSAP, xvOverlayDeinterlacingMethod,
@@ -119,6 +119,114 @@ static Atom xvOvAlpha, xvGrAlpha, xvAlph
 #define GET_PORT_PRIVATE(pScrn) \
    (RADEONPortPrivPtr)((RADEONPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
 
+static void
+radeon_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
+{
+    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+
+    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
+
+static void
+radeon_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
+    if (crtc->enabled) {
+	crtc_box->x1 = crtc->x;
+	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
+	crtc_box->y1 = crtc->y;
+	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
+    } else
+	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+radeon_box_area(BoxPtr box)
+{
+    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
+}
+
+static xf86CrtcPtr
+radeon_covering_crtc(ScrnInfoPtr pScrn,
+		     BoxPtr	box,
+		     xf86CrtcPtr desired,
+		     BoxPtr	crtc_box_ret)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcPtr		crtc, best_crtc;
+    int			coverage, best_coverage;
+    int			c;
+    BoxRec		crtc_box, cover_box;
+
+    best_crtc = NULL;
+    best_coverage = 0;
+    crtc_box_ret->x1 = 0;
+    crtc_box_ret->x2 = 0;
+    crtc_box_ret->y1 = 0;
+    crtc_box_ret->y2 = 0;
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+	radeon_crtc_box(crtc, &crtc_box);
+	radeon_box_intersect(&cover_box, &crtc_box, box);
+	coverage = radeon_box_area(&cover_box);
+	if (coverage && crtc == desired) {
+	    *crtc_box_ret = crtc_box;
+	    return crtc;
+	} else if (coverage > best_coverage) {
+	    *crtc_box_ret = crtc_box;
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
+    return best_crtc;
+}
+
+static Bool
+radeon_clip_video_helper(ScrnInfoPtr pScrn,
+			 xf86CrtcPtr *crtc_ret,
+			 xf86CrtcPtr desired_crtc,
+			 BoxPtr      dst,
+			 INT32	    *xa,
+			 INT32	    *xb,
+			 INT32	    *ya,
+			 INT32	    *yb,
+			 RegionPtr   reg,
+			 INT32	    width,
+			 INT32	    height)
+{
+    Bool	ret;
+    RegionRec	crtc_region_local;
+    RegionPtr	crtc_region = reg;
+    
+    /*
+     * For overlay video, compute the relevant CRTC and
+     * clip video to that
+     */
+    if (crtc_ret) {
+	BoxRec		crtc_box;
+	xf86CrtcPtr	crtc = radeon_covering_crtc(pScrn, dst,
+						    desired_crtc,
+						    &crtc_box);
+
+	if (crtc) {
+	    REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
+	    crtc_region = &crtc_region_local;
+	    REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
+	}
+	*crtc_ret = crtc;
+    }
+
+    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, 
+				crtc_region, width, height);
+
+    if (crtc_region != reg)
+	REGION_UNINIT (pScreen, &crtc_region_local);
+
+    return ret;
+}
 
 #ifdef USE_EXA
 static void
@@ -226,7 +334,7 @@ static XF86AttributeRec Attributes[NUM_A
    {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
    {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
    {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
-   {XvSettable | XvGettable,     0,    1, "XV_SWITCHCRT"},
+   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
    {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
    {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
 };
@@ -257,7 +365,7 @@ static XF86AttributeRec Attributes[NUM_D
    {XvSettable | XvGettable, -1000, 1000, "XV_RED_INTENSITY"},
    {XvSettable | XvGettable, -1000, 1000, "XV_GREEN_INTENSITY"},
    {XvSettable | XvGettable, -1000, 1000, "XV_BLUE_INTENSITY"},
-   {XvSettable | XvGettable,     0,    1, "XV_SWITCHCRT"},
+   {XvSettable | XvGettable,     -1,    1, "XV_CRTC"},
    {XvSettable | XvGettable,   100, 10000, "XV_GAMMA"},
    {XvSettable | XvGettable,     0,    1, "XV_COLORSPACE"},
    
@@ -1082,7 +1190,7 @@ RADEONResetVideo(ScrnInfoPtr pScrn)
 
     xvAutopaintColorkey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
     xvSetDefaults       = MAKE_ATOM("XV_SET_DEFAULTS");
-    xvSwitchCRT         = MAKE_ATOM("XV_SWITCHCRT");
+    xvCRTC              = MAKE_ATOM("XV_CRTC");
 
     xvOvAlpha	      = MAKE_ATOM("XV_OVERLAY_ALPHA");
     xvGrAlpha	      = MAKE_ATOM("XV_GRAPHICS_ALPHA");
@@ -1295,11 +1403,8 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
     pPriv->currentBuffer = 0;
     pPriv->autopaint_colorkey = TRUE;
     pPriv->gamma = 1000;
-    if (info->OverlayOnCRTC2)
-	pPriv->crt2 = TRUE;
-    else
-	pPriv->crt2 = FALSE;
-	
+    pPriv->desired_crtc = NULL;
+
     pPriv->ov_alpha = 255;
     pPriv->gr_alpha = 255;
     pPriv->alpha_mode = 0;
@@ -1324,24 +1429,14 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
      * 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
      * for higher clocks, sure makes life nicer
      */
+    dot_clock = info->ModeReg.dot_clock_freq;
 
-    /* Figure out which head we are on */
-    if (info->OverlayOnCRTC2)
-	dot_clock = info->ModeReg.dot_clock_freq_2;
-    else
-	dot_clock = info->ModeReg.dot_clock_freq;
-
-    if(dot_clock < 17500)
+    if (dot_clock < 17500)
         info->ecp_div = 0;
     else
         info->ecp_div = 1;
     ecp = (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (info->ecp_div << 8);
 
-#if 0
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, info->ecp_div);
-#endif
-
-
     if ((info->ChipFamily == CHIP_FAMILY_RS100) || 
 	(info->ChipFamily == CHIP_FAMILY_RS200) ||
 	(info->ChipFamily == CHIP_FAMILY_RS300)) {
@@ -1353,7 +1448,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
     OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, ecp);
 
 
-
     /* Decide on tuner type */
     if((info->tunerType<0) && (info->MM_TABLE_valid)) {
         pPriv->tuner_type = info->MM_TABLE.tuner_type;
@@ -1657,14 +1751,15 @@ RADEONSetPortAttribute(ScrnInfoPtr  pScr
 	RADEONSetColorKey (pScrn, pPriv->colorKey);
 	REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
     } 
-    else if(attribute == xvSwitchCRT) 
+    else if(attribute == xvCRTC) 
     {
-	pPriv->crt2 = ClipValue (value, 0, 1);
-	pPriv->crt2 = value;
-	if (pPriv->crt2)
-	    info->OverlayOnCRTC2 = TRUE;
+	xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	if ((value < -1) || (value > xf86_config->num_crtc))
+	    return BadValue;
+	if (value < 0)
+	    pPriv->desired_crtc = NULL;
 	else
-	    info->OverlayOnCRTC2 = FALSE; 
+	    pPriv->desired_crtc = xf86_config->crtc[value];
     }
     else if(attribute == xvOvAlpha) 
     {
@@ -1854,8 +1949,16 @@ RADEONGetPortAttribute(ScrnInfoPtr  pScr
 	*value = pPriv->doubleBuffer ? 1 : 0;
     else if(attribute == xvColorKey)
 	*value = pPriv->colorKey;
-    else if(attribute == xvSwitchCRT)
-	*value = pPriv->crt2 ? 1 : 0;
+    else if(attribute == xvCRTC) {
+	int		c;
+	xf86CrtcConfigPtr	xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	for (c = 0; c < xf86_config->num_crtc; c++)
+	    if (xf86_config->crtc[c] == pPriv->desired_crtc)
+		break;
+	if (c == xf86_config->num_crtc)
+	    c = -1;
+	*value = c;
+    }
     else if(attribute == xvOvAlpha)
 	*value = pPriv->ov_alpha;
     else if(attribute == xvGrAlpha)
@@ -2388,7 +2491,8 @@ RADEONFreeMemory(
 static void
 RADEONDisplayVideo(
     ScrnInfoPtr pScrn,
-    RADEONPortPrivPtr pPriv, 
+    xf86CrtcPtr crtc,
+    RADEONPortPrivPtr pPriv,
     int id,
     int offset1, int offset2,
     int offset3, int offset4,
@@ -2425,10 +2529,10 @@ RADEONDisplayVideo(
     int predownscale=0;
     int src_w_d;
     int leftuv = 0;
-    xf86CrtcPtr crtc;
     DisplayModePtr mode;
     RADEONOutputPrivatePtr radeon_output;
     xf86OutputPtr output;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
     is_rgb=0; is_planar=0;
     switch(id){
@@ -2451,7 +2555,7 @@ RADEONDisplayVideo(
        workarounds for chip erratas */
 
     /* Figure out which head we are on for dot clock */
-    if (info->OverlayOnCRTC2)
+    if (radeon_crtc->crtc_id == 1)
         dot_clock = info->ModeReg.dot_clock_freq_2;
     else
         dot_clock = info->ModeReg.dot_clock_freq;
@@ -2476,11 +2580,6 @@ RADEONDisplayVideo(
     v_inc_shift = 20;
     y_mult = 1;
 
-    if (info->OverlayOnCRTC2)
-	crtc = xf86_config->crtc[1];
-    else
-	crtc = xf86_config->crtc[0];
-
     mode = &crtc->mode;
 
     if (mode->Flags & V_INTERLACE)
@@ -2494,6 +2593,7 @@ RADEONDisplayVideo(
 	output = xf86_config->output[i];
 	if (output->crtc == crtc) {
 	    radeon_output = output->driver_private;
+	    break;
 	}
     }
 
@@ -2653,7 +2753,7 @@ RADEONDisplayVideo(
      * rendering for the second head.
      */
 
-    if (info->OverlayOnCRTC2) {
+    if (radeon_crtc->crtc_id == 1) {
         x_off = 0;
         OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
                                       ((dstBox->y1*y_mult) << 16)));
@@ -2731,6 +2831,7 @@ RADEONDisplayVideo(
 			| ((info->ChipFamily >= CHIP_FAMILY_R200) ? RADEON_SCALER_TEMPORAL_DEINT : 0);
 		break;
     }
+
     OUTREG(RADEON_OV0_SCALE_CNTL, scale_cntl);
     OUTREG(RADEON_OV0_REG_LOAD_CNTL, 0);
 }
@@ -2804,16 +2905,10 @@ RADEONPutImage(
    dstBox.y1 = drw_y;
    dstBox.y2 = drw_y + drw_h;
 
-   RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
-   if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,
-			     clipBoxes, width, height))
-	return Success;
-
-   if (info->OverlayOnCRTC2)
-     crtc = xf86_config->crtc[1];
-   else
-     crtc = xf86_config->crtc[0];
+   if (!radeon_clip_video_helper(pScrn, &crtc, pPriv->desired_crtc,
+				 &dstBox, &xa, &xb, &ya, &yb,
+				 clipBoxes, width, height))
+       return Success;
 
    dstBox.x1 -= crtc->x;
    dstBox.x2 -= crtc->x;
@@ -2942,7 +3037,7 @@ RADEONPutImage(
 
     /* FIXME: someone should look at these offsets, I don't think it makes sense how
               they are handled throughout the source. */
-    RADEONDisplayVideo(pScrn, pPriv, id, offset, offset + d2line, offset + d3line,
+    RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset, offset + d2line, offset + d3line,
 		     offset, offset + d2line, offset + d3line, width, height, dstPitch,
 		     xa, xb, ya, &dstBox, src_w, src_h, drw_w, drw_h, METHOD_BOB);
 
@@ -3183,17 +3278,11 @@ RADEONDisplaySurface(
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    RADEONChooseOverlayCRTC(pScrn, &dstBox);
-
-    if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, 
-			       surface->width, surface->height))
-	return Success;
+    if (!radeon_clip_video_helper(pScrn, &crtc, portPriv->desired_crtc,
+				  &dstBox, &xa, &xb, &ya, &yb, clipBoxes,
+				  surface->width, surface->height))
+        return Success;
 
-    if (info->OverlayOnCRTC2)
-        crtc = xf86_config->crtc[1];
-    else
-        crtc = xf86_config->crtc[0];
-    
     dstBox.x1 -= crtc->x;
     dstBox.x2 -= crtc->x;
     dstBox.y1 -= crtc->y;
@@ -3203,7 +3292,7 @@ RADEONDisplaySurface(
     /* this isn't needed */
     RADEONResetVideo(pScrn);
 #endif
-    RADEONDisplayVideo(pScrn, portPriv, surface->id,
+    RADEONDisplayVideo(pScrn, crtc, portPriv, surface->id,
 		       surface->offsets[0], surface->offsets[0],
 		       surface->offsets[0], surface->offsets[0],
 		       surface->offsets[0], surface->offsets[0],
@@ -3283,6 +3372,7 @@ RADEONPutVideo(
    int mult;
    int vbi_line_width, vbi_start, vbi_end;
    xf86CrtcPtr crtc;
+   RADEONCrtcPrivatePtr radeon_crtc;
 
     RADEON_SYNC(info, pScrn);
    /*
@@ -3320,19 +3410,14 @@ RADEONPutVideo(
 
    vbi_line_width = 798*2;
    if(width<=640)
-	   vbi_line_width = 0x640; /* 1600 actually */
-	   else
-	   vbi_line_width = 2000; /* might need adjustment */
-
-   RADEONChooseOverlayCRTC(pScrn, &dstBox);
-        
-   if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
-        return Success;
-
-   if (info->OverlayOnCRTC2)
-     crtc = xf86_config->crtc[1];
+       vbi_line_width = 0x640; /* 1600 actually */
    else
-     crtc = xf86_config->crtc[0];
+       vbi_line_width = 2000; /* might need adjustment */
+
+   if (!radeon_clip_video_helper(pScrn, &crtc, pPriv->desired_crtc,
+				 &dstBox, &xa, &xb, &ya, &yb,
+				 clipBoxes, width, height))
+       return Success;
 
    dstBox.x1 -= crtc->x;
    dstBox.x2 -= crtc->x;
@@ -3487,7 +3572,7 @@ RADEONPutVideo(
 	    RADEONFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes);
    }
 
-   RADEONDisplayVideo(pScrn, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch,
+   RADEONDisplayVideo(pScrn, crtc, pPriv, id, offset1+top*srcPitch, offset2+top*srcPitch,
 		offset3+top*srcPitch, offset4+top*srcPitch, offset1+top*srcPitch,
 		offset2+top*srcPitch, width, height, dstPitch*mult/2,
                      xa, xb, ya, &dstBox, src_w, src_h*mult/2, drw_w, drw_h, pPriv->overlay_deinterlacing_method);
diff --git a/src/radeon_video.h b/src/radeon_video.h
index b6d5d2d..072f40e 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -11,6 +11,8 @@
 #include "generic_bus.h"
 #include "theatre.h"
 
+#include "xf86Crtc.h"
+
 /* Xvideo port struct */
 typedef struct {
    CARD32	 transform_index;
@@ -40,7 +42,7 @@ typedef struct {
    CARD8         tuner_type;
    MSP3430Ptr    msp3430;
    TDA9885Ptr    tda9885;
-	UDA1380Ptr	  uda1380;
+    UDA1380Ptr	  uda1380;
 
    /* VIP bus and devices */
    GENERIC_BUS_Ptr  VIP;
@@ -77,7 +79,7 @@ typedef struct {
    Time          offTime;
    Time          freeTime;
    Bool          autopaint_colorkey;
-   Bool		 crt2; /* 0=CRT1, 1=CRT2 */
+   xf86CrtcPtr   desired_crtc;
 
 #ifdef USE_EXA
    int              size;
diff-tree 5793e8753d11432bf95c7c6dd80c811e16aba058 (from 6f011aaabaf18d66ffc255ad76aaf938b2396302)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Aug 15 19:26:36 2007 -0400

    RADEON: Remove RADEONRestoreMode()
    
    Since we no longer use it to write modes all it did
    was restore some of the regs for a console restore.
    Just move the relevant bits into RADEONRestore() and
    remove it.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 09464c1..ae34cf3 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -113,7 +113,6 @@
 
 
 				/* Forward definitions for driver functions */
-void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore);
 static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
 static void RADEONSave(ScrnInfoPtr pScrn);
@@ -5041,50 +5040,6 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
-/* Write out state to define a new video mode */
-void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info     = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
-    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "RADEONRestoreMode(%p)\n", restore);
-
-    /* When changing mode with Dual-head card, care must be taken for
-     * the special order in setting registers. CRTC2 has to be set
-     * before changing CRTC_EXT register.  In the dual-head setup, X
-     * server calls this routine twice with primary and secondary pScrn
-     * pointers respectively. The calls can come with different
-     * order. Regardless the order of X server issuing the calls, we
-     * have to ensure we set registers in the right order!!!  Otherwise
-     * we may get a blank screen.
-     *
-     * We always restore MemMap first, the saverec should be up to date
-     * in all cases
-     */
-    RADEONRestoreMemMapRegisters(pScrn, restore);
-    RADEONRestoreCommonRegisters(pScrn, restore);
-
-    if (pRADEONEnt->HasCRTC2) {
-	RADEONRestoreCrtc2Registers(pScrn, restore);
-	RADEONRestorePLL2Registers(pScrn, restore);
-    }
-
-    RADEONRestoreCrtcRegisters(pScrn, restore);
-    RADEONRestorePLLRegisters(pScrn, restore);
-    RADEONRestoreRMXRegisters(pScrn, restore);
-    RADEONRestoreFPRegisters(pScrn, restore);
-    RADEONRestoreFP2Registers(pScrn, restore);
-    RADEONRestoreLVDSRegisters(pScrn, restore);
-
-    if (info->InternalTVOut)
-	RADEONRestoreTVRegisters(pScrn, restore);
-
-#if 0
-    RADEONRestorePalette(pScrn, &info->SavedReg);
-#endif
-}
-
 /* Read memory map */
 static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
@@ -5490,6 +5445,7 @@ static void RADEONSave(ScrnInfoPtr pScrn
 void RADEONRestore(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  restore    = &info->SavedReg;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -5525,7 +5481,24 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 	OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
 #endif
 
-    RADEONRestoreMode(pScrn, restore);
+    RADEONRestoreMemMapRegisters(pScrn, restore);
+    RADEONRestoreCommonRegisters(pScrn, restore);
+
+    if (pRADEONEnt->HasCRTC2) {
+	RADEONRestoreCrtc2Registers(pScrn, restore);
+	RADEONRestorePLL2Registers(pScrn, restore);
+    }
+
+    RADEONRestoreCrtcRegisters(pScrn, restore);
+    RADEONRestorePLLRegisters(pScrn, restore);
+    RADEONRestoreRMXRegisters(pScrn, restore);
+    RADEONRestoreFPRegisters(pScrn, restore);
+    RADEONRestoreFP2Registers(pScrn, restore);
+    RADEONRestoreLVDSRegisters(pScrn, restore);
+
+    if (info->InternalTVOut)
+	RADEONRestoreTVRegisters(pScrn, restore);
+
     RADEONRestoreSurfaces(pScrn, restore);
 
 #if 1
diff-tree 6f011aaabaf18d66ffc255ad76aaf938b2396302 (from c8dad98abb042c6abbbee18f9ae4db72084bc513)
Author: Lisa Wu <Lisa.Wu at amd.com>
Date:   Wed Aug 15 19:17:51 2007 -0400

    RADEON: fix console restore on r3xx and r4xx
    
    When restoring the console we need to:
    1) we need to restore DAC registers after all other registers are
     restored and CRTCs are enabled.
    2) we need to enable CRTC2 registers before CRTC1 registers

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c1f0c3c..09464c1 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5076,7 +5076,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     RADEONRestoreFPRegisters(pScrn, restore);
     RADEONRestoreFP2Registers(pScrn, restore);
     RADEONRestoreLVDSRegisters(pScrn, restore);
-    RADEONRestoreDACRegisters(pScrn, restore);
+
     if (info->InternalTVOut)
 	RADEONRestoreTVRegisters(pScrn, restore);
 
@@ -5553,21 +5553,19 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     }
 #endif
 
-    /*RADEONUnblank(pScrn);*/
-    /* R4xx hangs when unblanking, but seems to restore fine without it. 
-     * This will probably cause problems with non-VGA consoles.
-     */
-    if (!info->IsAtomBios) {
-	/* need to make sure we don't enable a crtc by accident or we may get a hang */
-	if (info->crtc_on) {
-	    crtc = xf86_config->crtc[0];
-	    crtc->funcs->dpms(crtc, DPMSModeOn);
-	}
-	if (info->crtc2_on) {
-	    crtc = xf86_config->crtc[1];
-	    crtc->funcs->dpms(crtc, DPMSModeOn);
-	}
+    /* need to make sure we don't enable a crtc by accident or we may get a hang */
+    if (info->crtc2_on) {
+	crtc = xf86_config->crtc[1];
+	crtc->funcs->dpms(crtc, DPMSModeOn);
+    }
+    if (info->crtc_on) {
+	crtc = xf86_config->crtc[0];
+	crtc->funcs->dpms(crtc, DPMSModeOn);
     }
+    /* to restore console mode, DAC registers should be set after every other registers are set,
+     * otherwise,we may get blank screen 
+     */
+    RADEONRestoreDACRegisters(pScrn, restore);
 
 #if 0
     RADEONWaitForVerticalSync(pScrn);
diff-tree c8dad98abb042c6abbbee18f9ae4db72084bc513 (from f8cd74435f0072dbf5f6e83d67d2d5e1f4e82c91)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed Aug 15 00:55:24 2007 -0400

    RADEON: make sure crtc routing is correct in r300_detect_tv()
    
    Also remove some unused variable

diff --git a/src/radeon_output.c b/src/radeon_output.c
index d8d411a..73e44f3 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1328,7 +1328,7 @@ r300_detect_tv(ScrnInfoPtr pScrn)
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
-    CARD32 gpiopad_a;
+    CARD32 gpiopad_a, disp_output_cntl;
     RADEONMonitorType found = MT_NONE;
 
     /* save the regs we need */
@@ -1337,6 +1337,7 @@ r300_detect_tv(ScrnInfoPtr pScrn)
     crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
     dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
     tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
 
     OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
 
@@ -1345,6 +1346,10 @@ r300_detect_tv(ScrnInfoPtr pScrn)
     OUTREG(RADEON_CRTC2_GEN_CNTL,
 	   RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
 
+    tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+    tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+
     OUTREG(RADEON_DAC_EXT_CNTL,
 	   RADEON_DAC2_FORCE_BLANK_OFF_EN |
 	   RADEON_DAC2_FORCE_DATA_EN |
@@ -1386,6 +1391,7 @@ r300_detect_tv(ScrnInfoPtr pScrn)
     OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
     OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
     OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
     OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
     OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
 
@@ -1397,7 +1403,7 @@ radeon_detect_tv(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD32 tmp, dac_cntl2, crtc_ext_cntl, crtc2_gen_cntl, tv_master_cntl;
+    CARD32 tmp, dac_cntl2, tv_master_cntl;
     CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
     RADEONMonitorType found = MT_NONE;
 
@@ -1406,7 +1412,6 @@ radeon_detect_tv(ScrnInfoPtr pScrn)
 
     /* save the regs we need */
     dac_cntl2 = INREG(RADEON_DAC_CNTL2);
-    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
     tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
     tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
     config_cntl = INREG(RADEON_CONFIG_CNTL);
@@ -1460,7 +1465,6 @@ radeon_detect_tv(ScrnInfoPtr pScrn)
     OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
     OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
     OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
-    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
     OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
 
     return found;
diff-tree f8cd74435f0072dbf5f6e83d67d2d5e1f4e82c91 (from 6f398cd07ea734dd66a8eac71b629e59123d75b8)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 14 23:50:57 2007 -0400

    RADEON: minor cleanup

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 7f8f406..d8d411a 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -940,8 +940,9 @@ static void RADEONInitDAC2Registers(xf86
     if (IS_R300_VARIANT)
 	save->gpiopad_a = info->SavedReg.gpiopad_a | 1;
 
+    save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
+
     if (IsPrimary) {
-        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;
@@ -954,9 +955,7 @@ static void RADEONInitDAC2Registers(xf86
             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;
@@ -966,7 +965,6 @@ static void RADEONInitDAC2Registers(xf86
 				    RADEON_FP2_DVO_RATE_SEL_SDR);
             save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
         } 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;
         }
diff-tree 6f398cd07ea734dd66a8eac71b629e59123d75b8 (from 366a1d4c240ac93622caff97b652696db99bf2e6)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 14 23:42:32 2007 -0400

    RADEON: Implement improved tv load detection for r300
    
    The previous implementation resulted in false positives
    on occasion.  This method works much more reliably.
    Based on beos code by Thomas Kurschel

diff --git a/src/radeon_output.c b/src/radeon_output.c
index fdf85a9..7f8f406 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1325,6 +1325,76 @@ radeon_detect_tv_dac(ScrnInfoPtr pScrn, 
 }
 
 static RADEONMonitorType
+r300_detect_tv(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp, dac_cntl2, crtc2_gen_cntl, dac_ext_cntl, tv_dac_cntl;
+    CARD32 gpiopad_a;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    gpiopad_a = INREG(RADEON_GPIOPAD_A);
+    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+
+    OUTREGP(RADEON_GPIOPAD_A, 0, ~1 );
+
+    OUTREG(RADEON_DAC_CNTL2, RADEON_DAC2_DAC2_CLK_SEL );
+
+    OUTREG(RADEON_CRTC2_GEN_CNTL,
+	   RADEON_CRTC2_CRT2_ON | RADEON_CRTC2_VSYNC_TRISTAT );
+
+    OUTREG(RADEON_DAC_EXT_CNTL,
+	   RADEON_DAC2_FORCE_BLANK_OFF_EN |
+	   RADEON_DAC2_FORCE_DATA_EN |
+	   RADEON_DAC_FORCE_DATA_SEL_RGB |
+	   (0xec << RADEON_DAC_FORCE_DATA_SHIFT ));
+
+    OUTREG(RADEON_TV_DAC_CNTL,
+	   RADEON_TV_DAC_STD_NTSC |
+	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+    INREG(RADEON_TV_DAC_CNTL);
+
+    usleep(4000);
+
+    OUTREG(RADEON_TV_DAC_CNTL,
+	   RADEON_TV_DAC_NBLANK |
+	   RADEON_TV_DAC_NHOLD |
+	   RADEON_TV_MONITOR_DETECT_EN |
+	   RADEON_TV_DAC_STD_NTSC |
+	   (8 << RADEON_TV_DAC_BGADJ_SHIFT) |
+	   (6 << RADEON_TV_DAC_DACADJ_SHIFT ));
+
+    INREG(RADEON_TV_DAC_CNTL);
+
+    usleep(6000);
+
+    tmp = INREG(RADEON_TV_DAC_CNTL);
+    if ( (tmp & RADEON_TV_DAC_GDACDET) != 0 ) {
+	found = MT_STV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "S-Video TV connection detected\n");
+    } else if ( (tmp & RADEON_TV_DAC_BDACDET) != 0 ) {
+	found = MT_CTV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "Composite TV connection detected\n" );
+    }
+
+    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl );
+    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+    OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1);
+
+    return found;
+}
+
+static RADEONMonitorType
 radeon_detect_tv(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -1333,6 +1403,9 @@ radeon_detect_tv(ScrnInfoPtr pScrn)
     CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
     RADEONMonitorType found = MT_NONE;
 
+    if (IS_R300_VARIANT)
+	return r300_detect_tv(pScrn);
+
     /* save the regs we need */
     dac_cntl2 = INREG(RADEON_DAC_CNTL2);
     crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
diff-tree 366a1d4c240ac93622caff97b652696db99bf2e6 (from 5b4a04c23e3f1ec2490418b111f417c16463c709)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 14 23:25:37 2007 -0400

    RADEON: Turn off tv encoder in disableoutputs()

diff --git a/src/radeon_display.c b/src/radeon_display.c
index da2b82f..4334016 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -276,6 +276,13 @@ void RADEONDisableDisplays(ScrnInfoPtr p
     }
     RADEONDacPowerSet(pScrn, FALSE, FALSE);
 
+    /* turn off tv-out */
+    if (info->InternalTVOut) {
+	tmp = INREG(RADEON_TV_MASTER_CNTL);
+	tmp &= ~RADEON_TV_ON;
+	OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+    }
+
     /* FP 1 */
     tmp = INREG(RADEON_FP_GEN_CNTL);
     tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
@@ -333,7 +340,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
                     save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
                 } else {
                     tmp = INREG(RADEON_CRTC2_GEN_CNTL);
-                    tmp |= RADEON_CRTC2_CRT2_ON;  
+                    tmp |= RADEON_CRTC2_CRT2_ON;
                     OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
                     save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
                 }
@@ -368,7 +375,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
         if (radeon_output->MonType == MT_CRT) {
             if (radeon_output->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
-                tmp &= ~RADEON_CRTC_CRT_ON;       
+                tmp &= ~RADEON_CRTC_CRT_ON;
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
             } else if (radeon_output->DACType == DAC_TVDAC) {
diff-tree 5b4a04c23e3f1ec2490418b111f417c16463c709 (from db2a828b2f21b92cd654b309d137204334975b89)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 14 23:11:52 2007 -0400

    RADEON: Make sure RMX is always programmed for crtc1
    
    If the RMX registers are left as programmed by the bios
    this can lead to a blank screen when crtc1 is feeding a
    DAC.  Fix found and reported by Lisa Wu <liswu at ati.com>
    Fixes bug 11985

diff --git a/src/radeon_output.c b/src/radeon_output.c
index c2598dc..fdf85a9 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -825,6 +825,15 @@ static void RADEONInitRMXRegisters(xf86O
     int    yres = mode->VDisplay;
     float  Hratio, Vratio;
 
+    save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
+	                    RADEON_VERT_STRETCH_RESERVED;
+    save->fp_horz_stretch = info->SavedReg.fp_horz_stretch &
+	                    (RADEON_HORZ_FP_LOOP_STRETCH |
+	                     RADEON_HORZ_AUTO_RATIO_INC);
+
+    if (radeon_output->MonType != MT_LCD && radeon_output->MonType != MT_DFP)
+	return;
+
     if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
 	Hratio = 1.0;
 	Vratio = 1.0;
@@ -836,12 +845,6 @@ static void RADEONInitRMXRegisters(xf86O
 	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 {
@@ -978,6 +981,9 @@ RADEONInitOutputRegisters(ScrnInfoPtr pS
     Bool IsPrimary = crtc_num == 0 ? TRUE : FALSE;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
+    if (crtc_num == 0)
+	RADEONInitRMXRegisters(output, save, mode);
+
     if (radeon_output->MonType == MT_CRT) {
 	if (radeon_output->DACType == DAC_PRIMARY) {
 	    RADEONInitDACRegisters(output, save, mode, IsPrimary);
@@ -985,12 +991,8 @@ RADEONInitOutputRegisters(ScrnInfoPtr pS
 	    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 {
@@ -1014,16 +1016,15 @@ radeon_mode_set(xf86OutputPtr output, Di
 
     RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
 
+    if (radeon_crtc->crtc_id == 0)
+	RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
+
     switch(radeon_output->MonType) {
     case MT_LCD:
 	ErrorF("restore LVDS\n");
-	if (radeon_crtc->crtc_id == 0)
-	    RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
 	RADEONRestoreLVDSRegisters(pScrn, &info->ModeReg);
 	break;
     case MT_DFP:
-	if (radeon_crtc->crtc_id == 0)
-	    RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
 	if (radeon_output->TMDSType == TMDS_INT) {
 	    ErrorF("restore FP\n");
 	    RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
diff-tree db2a828b2f21b92cd654b309d137204334975b89 (from 6fc3ddbbb6fbbee1f6076c776e5b46c0c772b6d4)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Aug 14 22:47:29 2007 -0400

    RADEON: Add load detection
    
    Based on the beos driver by Thomas Kurschel and the
    existing load detection code in this driver.

diff --git a/src/radeon_output.c b/src/radeon_output.c
index d86fbbd..c2598dc 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -149,6 +149,10 @@ static const RADEONTMDSPll default_tmds_
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
 static void RADEONUpdatePanelSize(xf86OutputPtr output);
+static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn);
+static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color);
+static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn);
 
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
@@ -275,6 +279,7 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pS
     return MonType;
 }
 
+#if 0
 static RADEONMonitorType
 RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
 {
@@ -519,6 +524,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoP
 
     return(bConnected ? MT_CRT : MT_NONE);
 }
+#endif
 
 /* Primary Head (DVI or Laptop Int. panel)*/
 /* A ddc capable display connected on DVI port */
@@ -527,12 +533,28 @@ void RADEONConnectorFindMonitor(ScrnInfo
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    
+
     if (radeon_output->MonType == MT_UNKNOWN) {
-	if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output)));
-	else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
-	else if (radeon_output->DACType == DAC_PRIMARY) 
-	    radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
+	if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+	    if (info->InternalTVOut)
+		radeon_output->MonType = radeon_detect_tv(pScrn);
+	} else {
+	    radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output);
+	    if (!radeon_output->MonType) {
+		if (radeon_output->type == OUTPUT_LVDS || radeon_output->type == OUTPUT_DVI)
+		    radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output);
+		if (!radeon_output->MonType) {
+		    if (radeon_output->DACType == DAC_PRIMARY)
+			radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
+		    else if (radeon_output->DACType == DAC_TVDAC) {
+			if (info->ChipFamily == CHIP_FAMILY_R200)
+			    radeon_output->MonType = radeon_detect_ext_dac(pScrn);
+			else
+			    radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
+		    }
+		}
+	    }
+	}
     }
 
     /* update panel info for RMX */
@@ -1029,6 +1051,349 @@ radeon_mode_commit(xf86OutputPtr output)
     RADEONEnableDisplay(output, TRUE);
 }
 
+/* the following functions are based on the load detection code
+ * in the beos radeon driver by Thomas Kurschel and the existing
+ * load detection code in this driver.
+ */
+static RADEONMonitorType
+radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 vclk_ecp_cntl, crtc_ext_cntl;
+    CARD32 dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+    dac_cntl = INREG(RADEON_DAC_CNTL);
+    dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+
+    tmp = vclk_ecp_cntl &
+	~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb);
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
+
+    tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON;
+    OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
+
+    tmp = RADEON_DAC_FORCE_BLANK_OFF_EN |
+	RADEON_DAC_FORCE_DATA_EN;
+
+    if (color)
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+    else
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+    if (IS_R300_VARIANT)
+	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+    else
+	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+    tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN);
+    tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN;
+    OUTREG(RADEON_DAC_CNTL, tmp);
+
+    tmp &= ~(RADEON_DAC_PDWN_R |
+	     RADEON_DAC_PDWN_G |
+	     RADEON_DAC_PDWN_B);
+
+    OUTREG(RADEON_DAC_MACRO_CNTL, tmp);
+
+    usleep(2000);
+
+    if (INREG(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) {
+	found = MT_CRT;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "Found %s CRT connected to primary DAC\n",
+		    color ? "color" : "bw");
+    }
+
+    /* restore the regs we used */
+    OUTREG(RADEON_DAC_CNTL, dac_cntl);
+    OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl);
+
+    return found;
+}
+
+static RADEONMonitorType
+radeon_detect_ext_dac(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 gpio_monid, fp2_gen_cntl, disp_output_cntl, crtc2_gen_cntl;
+    CARD32 disp_lin_trans_grph_a, disp_lin_trans_grph_b, disp_lin_trans_grph_c;
+    CARD32 disp_lin_trans_grph_d, disp_lin_trans_grph_e, disp_lin_trans_grph_f;
+    CARD32 tmp, crtc2_h_total_disp, crtc2_v_total_disp;
+    CARD32 crtc2_h_sync_strt_wid, crtc2_v_sync_strt_wid;
+    RADEONMonitorType found = MT_NONE;
+    int connected = 0;
+    int i = 0;
+
+    /* save the regs we need */
+    gpio_monid = INREG(RADEON_GPIO_MONID);
+    fp2_gen_cntl = INREG(RADEON_FP2_GEN_CNTL);
+    disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+    disp_lin_trans_grph_a = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+    disp_lin_trans_grph_b = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+    disp_lin_trans_grph_c = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+    disp_lin_trans_grph_d = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+    disp_lin_trans_grph_e = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+    disp_lin_trans_grph_f = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+    crtc2_h_total_disp = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+    crtc2_v_total_disp = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+    crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+    crtc2_v_sync_strt_wid = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+    tmp = INREG(RADEON_GPIO_MONID);
+    tmp &= ~RADEON_GPIO_A_0;
+    OUTREG(RADEON_GPIO_MONID, tmp);
+
+    OUTREG(RADEON_FP2_GEN_CNTL,
+	   RADEON_FP2_ON |
+	   RADEON_FP2_PANEL_FORMAT |
+	   R200_FP2_SOURCE_SEL_TRANS_UNIT |
+	   RADEON_FP2_DVO_EN |
+	   R200_FP2_DVO_RATE_SEL_SDR);
+
+    OUTREG(RADEON_DISP_OUTPUT_CNTL,
+	   RADEON_DISP_DAC_SOURCE_RMX |
+	   RADEON_DISP_TRANS_MATRIX_GRAPHICS);
+
+    OUTREG(RADEON_CRTC2_GEN_CNTL,
+	   RADEON_CRTC2_EN |
+	   RADEON_CRTC2_DISP_REQ_EN_B);
+
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+
+    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+    for (i = 0; i < 200; i++) {
+	tmp = INREG(RADEON_GPIO_MONID);
+	if (tmp & RADEON_GPIO_Y_0)
+	    connected = 1;
+	else
+	    connected = 0;
+
+	if (!connected)
+	    break;
+
+	usleep(1000);
+    }
+
+    if (connected)
+	found = MT_CRT;
+
+    /* restore the regs we used */
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, disp_lin_trans_grph_a);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, disp_lin_trans_grph_b);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, disp_lin_trans_grph_c);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, disp_lin_trans_grph_d);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, disp_lin_trans_grph_e);
+    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, disp_lin_trans_grph_f);
+    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, crtc2_h_total_disp);
+    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, crtc2_v_total_disp);
+    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, crtc2_h_sync_strt_wid);
+    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, crtc2_v_sync_strt_wid);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+    OUTREG(RADEON_FP2_GEN_CNTL, fp2_gen_cntl);
+    OUTREG(RADEON_GPIO_MONID, gpio_monid);
+
+    return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl;
+    CARD32 disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    pixclks_cntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+    if (IS_R300_VARIANT) {
+	gpiopad_a = INREG(RADEON_GPIOPAD_A);
+	disp_output_cntl = INREG(RADEON_DISP_OUTPUT_CNTL);
+    } else {
+	disp_hw_debug = INREG(RADEON_DISP_HW_DEBUG);
+    }
+    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL);
+    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    dac_ext_cntl = INREG(RADEON_DAC_EXT_CNTL);
+    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+
+    tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb
+			   | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
+
+    if (IS_R300_VARIANT) {
+	OUTREGP(RADEON_GPIOPAD_A, 1, ~1 );
+    }
+
+    tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK;
+    tmp |= RADEON_CRTC2_CRT2_ON |
+	(2 << RADEON_CRTC2_PIX_WIDTH_SHIFT);
+
+    OUTREG(RADEON_CRTC2_GEN_CNTL, tmp);
+
+    if (IS_R300_VARIANT) {
+	tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK;
+	tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2;
+	OUTREG(RADEON_DISP_OUTPUT_CNTL, tmp);
+    } else {
+	tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL;
+	OUTREG(RADEON_DISP_HW_DEBUG, tmp);
+    }
+
+    tmp = RADEON_TV_DAC_NBLANK |
+	RADEON_TV_DAC_NHOLD |
+	RADEON_TV_MONITOR_DETECT_EN |
+	RADEON_TV_DAC_STD_PS2;
+
+    OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+    tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN |
+	RADEON_DAC2_FORCE_DATA_EN;
+
+    if (color)
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB;
+    else
+	tmp |= RADEON_DAC_FORCE_DATA_SEL_G;
+
+    if (IS_R300_VARIANT)
+	tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+    else
+	tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT);
+
+    OUTREG(RADEON_DAC_EXT_CNTL, tmp);
+
+    tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN;
+    OUTREG(RADEON_DAC_CNTL2, tmp);
+
+    usleep(10000);
+
+    if (IS_R300_VARIANT) {
+	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) {
+	    found = MT_CRT;
+	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+			"Found %s CRT connected to TV DAC\n",
+			color ? "color" : "bw");
+	}
+    } else {
+	if (INREG(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) {
+	    found = MT_CRT;
+	    xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+			"Found %s CRT connected to TV DAC\n",
+			color ? "color" : "bw");
+	}
+    }
+
+    /* restore regs we used */
+    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+    OUTREG(RADEON_DAC_EXT_CNTL, dac_ext_cntl);
+    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+
+    if (IS_R300_VARIANT) {
+	OUTREG(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl);
+	OUTREGP(RADEON_GPIOPAD_A, gpiopad_a, ~1 );
+    } else {
+	OUTREG(RADEON_DISP_HW_DEBUG, disp_hw_debug);
+    }
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, pixclks_cntl);
+
+    return found;
+}
+
+static RADEONMonitorType
+radeon_detect_tv(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp, dac_cntl2, crtc_ext_cntl, crtc2_gen_cntl, tv_master_cntl;
+    CARD32 tv_dac_cntl, tv_pre_dac_mux_cntl, config_cntl;
+    RADEONMonitorType found = MT_NONE;
+
+    /* save the regs we need */
+    dac_cntl2 = INREG(RADEON_DAC_CNTL2);
+    crtc_ext_cntl = INREG(RADEON_CRTC_EXT_CNTL);
+    tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    config_cntl = INREG(RADEON_CONFIG_CNTL);
+    tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+    tmp = dac_cntl2 & ~RADEON_DAC2_DAC2_CLK_SEL;
+    OUTREG(RADEON_DAC_CNTL2, tmp);
+
+    tmp = tv_master_cntl | RADEON_TV_ON;
+    tmp &= ~(RADEON_TV_ASYNC_RST |
+	     RADEON_RESTART_PHASE_FIX |
+	     RADEON_CRT_FIFO_CE_EN |
+	     RADEON_TV_FIFO_CE_EN |
+	     RADEON_RE_SYNC_NOW_SEL_MASK);
+    tmp |= RADEON_TV_FIFO_ASYNC_RST | RADEON_CRT_ASYNC_RST;
+
+    OUTREG(RADEON_TV_MASTER_CNTL, tmp);
+
+    tmp = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD |
+	RADEON_TV_MONITOR_DETECT_EN | RADEON_TV_DAC_STD_NTSC |
+	(8 << RADEON_TV_DAC_BGADJ_SHIFT);
+
+    if (config_cntl & RADEON_CFG_ATI_REV_ID_MASK)
+	tmp |= (4 << RADEON_TV_DAC_DACADJ_SHIFT);
+    else
+	tmp |= (8 << RADEON_TV_DAC_DACADJ_SHIFT);
+
+    OUTREG(RADEON_TV_DAC_CNTL, tmp);
+
+    tmp = RADEON_C_GRN_EN | RADEON_CMP_BLU_EN |
+	RADEON_RED_MX_FORCE_DAC_DATA |
+	RADEON_GRN_MX_FORCE_DAC_DATA |
+	RADEON_BLU_MX_FORCE_DAC_DATA |
+	(0x109 << RADEON_TV_FORCE_DAC_DATA_SHIFT);
+
+    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tmp);
+
+    usleep(3000);
+
+    tmp = INREG(RADEON_TV_DAC_CNTL);
+    if (tmp & RADEON_TV_DAC_GDACDET) {
+	found = MT_STV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "S-Video TV connection detected\n");
+    } else if (tmp & RADEON_TV_DAC_BDACDET) {
+	found = MT_CTV;
+	xf86DrvMsg (pScrn->scrnIndex, X_INFO,
+		    "Composite TV connection detected\n" );
+    }
+
+    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, tv_pre_dac_mux_cntl);
+    OUTREG(RADEON_TV_DAC_CNTL, tv_dac_cntl);
+    OUTREG(RADEON_TV_MASTER_CNTL, tv_master_cntl);
+    OUTREG(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl);
+    OUTREG(RADEON_DAC_CNTL2, dac_cntl2);
+
+    return found;
+}
+
 static xf86OutputStatus
 radeon_detect(xf86OutputPtr output)
 {
@@ -1037,15 +1402,8 @@ radeon_detect(xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     Bool connected = TRUE;
 
-    /* assume tv is disconnected for now */
-    if (radeon_output->type == OUTPUT_STV) {
-	radeon_output->MonType = MT_NONE;
-    } else if (radeon_output->type == OUTPUT_CTV) {
-	radeon_output->MonType = MT_NONE;
-    } else {
-	radeon_output->MonType = MT_UNKNOWN;
-	RADEONConnectorFindMonitor(pScrn, output);
-    }
+    radeon_output->MonType = MT_UNKNOWN;
+    RADEONConnectorFindMonitor(pScrn, output);
 
     /* force montype based on output property */
     if (radeon_output->type == OUTPUT_DVI) {
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index db2057a..4e4d874 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -325,6 +325,8 @@
 #       define RADEON_CRTC2_HSYNC_TRISTAT   (1 <<  5)
 #       define RADEON_CRTC2_VSYNC_TRISTAT   (1 <<  6)
 #       define RADEON_CRTC2_CRT2_ON         (1 <<  7)
+#       define RADEON_CRTC2_PIX_WIDTH_SHIFT 8
+#       define RADEON_CRTC2_PIX_WIDTH_MASK  (0xf << 8)
 #       define RADEON_CRTC2_ICON_EN         (1 << 15)
 #       define RADEON_CRTC2_CUR_EN          (1 << 16)
 #       define RADEON_CRTC2_CUR_MODE_MASK   (7 << 20)
@@ -335,8 +337,8 @@
 #       define RADEON_CRTC2_HSYNC_DIS       (1 << 28)
 #       define RADEON_CRTC2_VSYNC_DIS       (1 << 29)
 #define RADEON_CRTC_MORE_CNTL               0x27c
-#       define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)   
-#       define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)   
+#       define RADEON_CRTC_H_CUTOFF_ACTIVE_EN (1<<4)
+#       define RADEON_CRTC_V_CUTOFF_ACTIVE_EN (1<<5)
 #define RADEON_CRTC_GUI_TRIG_VLINE          0x0218
 #define RADEON_CRTC_H_SYNC_STRT_WID         0x0204
 #       define RADEON_CRTC_H_SYNC_STRT_PIX        (0x07  <<  0)
@@ -457,6 +459,7 @@
 
 #define RADEON_DAC_CNTL                     0x0058
 #       define RADEON_DAC_RANGE_CNTL        (3 <<  0)
+#       define RADEON_DAC_RANGE_CNTL_PS2    (2 <<  0)
 #       define RADEON_DAC_RANGE_CNTL_MASK   0x03
 #       define RADEON_DAC_BLANKING          (1 <<  2)
 #       define RADEON_DAC_CMP_EN            (1 <<  3)
@@ -471,10 +474,21 @@
 #       define RADEON_DAC2_DAC_CLK_SEL      (1 <<  0)
 #       define RADEON_DAC2_DAC2_CLK_SEL     (1 <<  1)
 #       define RADEON_DAC2_PALETTE_ACC_CTL  (1 <<  5)
+#       define RADEON_DAC2_CMP_EN           (1 <<  7)
+#       define RADEON_DAC2_CMP_OUT_R        (1 <<  8)
+#       define RADEON_DAC2_CMP_OUT_G        (1 <<  9)
+#       define RADEON_DAC2_CMP_OUT_B        (1 << 10)
+#       define RADEON_DAC2_CMP_OUTPUT       (1 << 11)
 #define RADEON_DAC_EXT_CNTL                 0x0280
-#       define RADEON_DAC_FORCE_BLANK_OFF_EN (1 << 4)
-#       define RADEON_DAC_FORCE_DATA_EN      (1 << 5)
+#       define RADEON_DAC2_FORCE_BLANK_OFF_EN (1 << 0)
+#       define RADEON_DAC2_FORCE_DATA_EN      (1 << 1)
+#       define RADEON_DAC_FORCE_BLANK_OFF_EN  (1 << 4)
+#       define RADEON_DAC_FORCE_DATA_EN       (1 << 5)
 #       define RADEON_DAC_FORCE_DATA_SEL_MASK (3 << 6)
+#       define RADEON_DAC_FORCE_DATA_SEL_R    (0 << 6)
+#       define RADEON_DAC_FORCE_DATA_SEL_G    (1 << 6)
+#       define RADEON_DAC_FORCE_DATA_SEL_B    (2 << 6)
+#       define RADEON_DAC_FORCE_DATA_SEL_RGB  (3 << 6)
 #       define RADEON_DAC_FORCE_DATA_MASK   0x0003ff00
 #       define RADEON_DAC_FORCE_DATA_SHIFT  8
 #define RADEON_DAC_MACRO_CNTL               0x0d04
@@ -494,10 +508,15 @@
 #       define RADEON_TV_DAC_STD_RS343      (3 <<  8)
 #       define RADEON_TV_DAC_BGSLEEP        (1 <<  6)
 #       define RADEON_TV_DAC_BGADJ_MASK     (0xf <<  16)
+#       define RADEON_TV_DAC_BGADJ_SHIFT    16
 #       define RADEON_TV_DAC_DACADJ_MASK    (0xf <<  20)
+#       define RADEON_TV_DAC_DACADJ_SHIFT   20
 #       define RADEON_TV_DAC_RDACPD         (1 <<  24)
 #       define RADEON_TV_DAC_GDACPD         (1 <<  25)
 #       define RADEON_TV_DAC_BDACPD         (1 <<  26)
+#       define RADEON_TV_DAC_RDACDET        (1 << 29)
+#       define RADEON_TV_DAC_GDACDET        (1 << 30)
+#       define RADEON_TV_DAC_BDACDET        (1 << 31)
 #       define R420_TV_DAC_DACADJ_MASK      (0x1f <<  20)
 #       define R420_TV_DAC_RDACPD           (1 <<  25)
 #       define R420_TV_DAC_GDACPD           (1 <<  26)
@@ -509,10 +528,18 @@
 #       define RADEON_DISP_DAC_SOURCE_MASK  0x03
 #       define RADEON_DISP_DAC2_SOURCE_MASK  0x0c
 #       define RADEON_DISP_DAC_SOURCE_CRTC2 0x01
+#       define RADEON_DISP_DAC_SOURCE_RMX   0x02
+#       define RADEON_DISP_DAC_SOURCE_LTU   0x03
 #       define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04
 #       define RADEON_DISP_TVDAC_SOURCE_MASK  (0x03 << 2)
 #       define RADEON_DISP_TVDAC_SOURCE_CRTC  0x0
 #       define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01 << 2)
+#       define RADEON_DISP_TVDAC_SOURCE_RMX   (0x02 << 2)
+#       define RADEON_DISP_TVDAC_SOURCE_LTU   (0x03 << 2)
+#       define RADEON_DISP_TRANS_MATRIX_MASK  (0x03 << 4)
+#       define RADEON_DISP_TRANS_MATRIX_ALPHA_MSB (0x00 << 4)
+#       define RADEON_DISP_TRANS_MATRIX_GRAPHICS  (0x01 << 4)
+#       define RADEON_DISP_TRANS_MATRIX_VIDEO     (0x02 << 4)
 #       define RADEON_DISP_TV_SOURCE_CRTC   (1 << 16) /* crtc1 or crtc2 */
 #       define RADEON_DISP_TV_SOURCE_LTU    (0 << 16) /* linear transform unit */
 #define RADEON_DISP_TV_OUT_CNTL             0x0d6c
@@ -756,6 +783,7 @@
 #       define R200_FP2_SOURCE_SEL_CRTC1       (0 <<  10)
 #       define R200_FP2_SOURCE_SEL_CRTC2       (1 << 10)
 #       define R200_FP2_SOURCE_SEL_RMX         (2 << 10)
+#       define R200_FP2_SOURCE_SEL_TRANS_UNIT  (3 << 10)
 #       define RADEON_FP2_SRC_SEL_MASK         (3 << 13)
 #       define RADEON_FP2_SRC_SEL_CRTC2        (1 << 13)
 #       define RADEON_FP2_FP_POL               (1 << 16)
@@ -767,6 +795,7 @@
 #       define RADEON_FP2_CRC_READ_EN          (1 << 24)
 #       define RADEON_FP2_DVO_EN               (1 << 25)
 #       define RADEON_FP2_DVO_RATE_SEL_SDR     (1 << 26)
+#       define R200_FP2_DVO_RATE_SEL_SDR       (1 << 27)
 #define RADEON_FP_H_SYNC_STRT_WID           0x02c4
 #define RADEON_FP_H2_SYNC_STRT_WID          0x03c4
 #define RADEON_FP_HORZ_STRETCH              0x028c
@@ -923,6 +952,7 @@
 #define RADEON_MDGPIO_A_REG                 0x01ac
 #define RADEON_MDGPIO_EN_REG                0x01b0
 #define RADEON_MDGPIO_MASK                  0x0198
+#define RADEON_GPIOPAD_A		    0x019c
 #define RADEON_MDGPIO_Y_REG                 0x01b4
 #define RADEON_MEM_ADDR_CONFIG              0x0148
 #define RADEON_MEM_BASE                     0x0f10 /* PCI */
@@ -3091,6 +3121,7 @@
 #	define RADEON_DVS_ASYNC_RST		 (1 <<  7)
 #       define RADEON_CRT_FIFO_CE_EN             (1 <<  9)
 #       define RADEON_TV_FIFO_CE_EN              (1 << 10)
+#       define RADEON_RE_SYNC_NOW_SEL_MASK       (3 << 14)
 #       define RADEON_TVCLK_ALWAYS_ONb           (1 << 30)
 #	define RADEON_TV_ON			 (1 << 31)
 #define RADEON_TV_PRE_DAC_MUX_CNTL               0x0888
@@ -3215,7 +3246,6 @@
 #       define RADEON_TVPDC_MASK                 (3 << 14)
 #       define RADEON_TVPLL_TEST_DIS             (1 << 31)
 #       define RADEON_TVCLK_SRC_SEL_TVPLL        (1 << 30)
-#define RADEON_GPIOPAD_A			     0x019c
 
 #define RADEON_RS480_UNK_e30			0xe30
 #define RADEON_RS480_UNK_e34			0xe34
diff-tree 6fc3ddbbb6fbbee1f6076c776e5b46c0c772b6d4 (from b7738d2ef82e1759adf78e5db1291f8739b4166f)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 12 12:00:20 2007 -0400

    RADEON: order the VGA and DVI ports correctly

diff --git a/src/radeon_output.c b/src/radeon_output.c
index b570b7f..d86fbbd 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -2079,17 +2079,17 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
 		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
 		    if (num_dvi > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
 			num_dvi--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
 		    }
 		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
 		    if (num_vga > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
 			num_vga--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
 		    }
 		} else
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
@@ -2097,17 +2097,17 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
 		     (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
 		    if (num_dvi > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
 			num_dvi--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
 		    }
 		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
 		    if (num_vga > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
 			num_vga--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
 		    }
 		} else
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
diff-tree b7738d2ef82e1759adf78e5db1291f8739b4166f (from c01000bc684f6a23a38a52f0808182cefaa686bb)
Author: Alex Deucher <alex at botch2.com>
Date:   Sat Aug 11 17:50:42 2007 -0400

    RADEON: fix connector setup when there's no bios tables

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 2d7f195..9d8946f 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -227,6 +227,8 @@ static Bool RADEONGetLegacyConnectorInfo
     RADEONInfoPtr info = RADEONPTR (pScrn);
     int offset, i, entry, tmp, tmp0, tmp1;
 
+    if (!info->VBIOS) return FALSE;
+
     offset = RADEON_BIOS16(info->ROMHeaderStart + 0x50);
     if (offset) {
 	for (i = 0; i < 4; i++) {
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 440d39f..b570b7f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1946,11 +1946,13 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
 	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+	    info->BiosConnector[0].valid = TRUE;
 
 	    info->BiosConnector[1].DDCType = DDC_VGA;
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_EXT;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	    info->BiosConnector[1].valid = TRUE;
 
 	} else {
 	    /* Below is the most common setting, but may not be true */
@@ -1958,11 +1960,13 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[0].DACType = DAC_TVDAC;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
+	    info->BiosConnector[0].valid = TRUE;
 
 	    info->BiosConnector[1].DDCType = DDC_VGA;
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_EXT;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	    info->BiosConnector[1].valid = TRUE;
 	}
 
 	if (info->InternalTVOut) {
@@ -1970,6 +1974,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[2].DACType = DAC_TVDAC;
 	    info->BiosConnector[2].TMDSType = TMDS_NONE;
 	    info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	    info->BiosConnector[2].valid = TRUE;
 	}
 
        /* Some cards have the DDC lines swapped and we have no way to
diff-tree d0895f67e327bb268fd59fcfd8fc22678d804f57 (from 1de52d91ff3a04b9b587b858e1e5be40d3a7fd0a)
Author: Luc Verhaegen <libv at skynet.be>
Date:   Thu Aug 9 12:11:40 2007 +0200

    AGPFastWrite risk reduction.
    
    Actively warn the user in the log about the effects of AGPFastWrite and
    sanitise AGPFastWrite handling while we're here.

diff --git a/src/radeon.h b/src/radeon.h
index 5f3f4ab..b19b017 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -611,7 +611,6 @@ typedef struct {
     unsigned long     gartOffset;
     unsigned char     *AGP;             /* Map */
     int               agpMode;
-    int               agpFastWrite;
 
     CARD32            pciCommand;
 
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 11f7140..315b204 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -748,28 +748,6 @@ static Bool RADEONSetAgpMode(RADEONInfoP
 
     xf86DrvMsg(pScreen->myNum, from, "Using AGP %dx\n", info->agpMode);
 
-    info->agpFastWrite = 0; // Always off by default as it sucks
-
-    from = xf86GetOptValInteger(info->Options, OPTION_AGP_FW,
-				&info->agpFastWrite) ? X_CONFIG : X_DEFAULT;
-
-    if (info->agpFastWrite &&
-	(vendor == PCI_VENDOR_AMD) &&
-	(device == PCI_CHIP_AMD761)) {
-
-	/* Disable fast write for AMD 761 chipset, since they cause
-	 * lockups when enabled.
-	 */
-	info->agpFastWrite = FALSE;
-	from = X_DEFAULT;
-	xf86DrvMsg(pScreen->myNum, X_WARNING,
-		   "[agp] Not enabling Fast Writes on AMD 761 chipset to avoid "
-		   "lockups");
-    }
-
-    xf86DrvMsg(pScreen->myNum, from, "AGP Fast Writes %sabled\n",
-	       info->agpFastWrite ? "en" : "dis");
-
     mode &= ~RADEON_AGP_MODE_MASK;
     if (is_v3) {
 	/* only set one mode bit for AGPv3 */
@@ -788,8 +766,26 @@ static Bool RADEONSetAgpMode(RADEONInfoP
 	}
     }
 
-    if (info->agpFastWrite) mode |= RADEON_AGP_FW_MODE;
-    else mode &= ~RADEON_AGP_FW_MODE;
+    /* AGP Fast Writes.
+     * TODO: take into account that certain agp modes don't support fast
+     * writes at all */
+    mode &= ~RADEON_AGP_FW_MODE; /* Disable per default */
+    if (xf86ReturnOptValBool(info->Options, OPTION_AGP_FW, FALSE)) {
+	xf86DrvMsg(pScreen->myNum, X_WARNING,
+		   "WARNING: Using the AGPFastWrite option is not recommended.\n");
+	xf86Msg(X_NONE, "\tThis option does not provide much of a noticable speed"
+		" boost, while it\n\twill probably hard lock your machine."
+		" All bets are off!\n");
+
+	/* Black list some host/AGP bridges. */
+	if ((vendor == PCI_VENDOR_AMD) && (device == PCI_CHIP_AMD761))
+	    xf86DrvMsg(pScreen->myNum, X_PROBED, "Ignoring AGPFastWrite option "
+		       "for the AMD 761 northbridge.\n");
+	else {
+	    xf86DrvMsg(pScreen->myNum, X_CONFIG, "Enabling AGP Fast Writes.\n");
+	    mode |= RADEON_AGP_FW_MODE;
+	}
+    } /* Don't mention this otherwise, so that people don't get funny ideas */
 
     xf86DrvMsg(pScreen->myNum, X_INFO,
 	       "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
diff-tree c01000bc684f6a23a38a52f0808182cefaa686bb (from 5c3f49e651c36f3bd14fa29359e24825d8f7f77f)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Aug 8 00:07:16 2007 -0400

    RADEON: fix typo in comment

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index cf67400..8e71330 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -565,7 +565,7 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
 			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
     save->crtc2_pitch |= save->crtc2_pitch << 16;
 
-    /* check to see if TV_DAC is enabled for another output and keep it enabled */
+    /* check to see if TV DAC is enabled for another crtc and keep it enabled */
     if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
 	save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
     else
diff-tree 5c3f49e651c36f3bd14fa29359e24825d8f7f77f (from 08fe7ad00fba523775e95b5e6295fe23a5119d60)
Author: Lisa Wu <liswu at ati.com>
Date:   Wed Aug 8 00:05:47 2007 -0400

    RADEON: make sure RADEON_CRTC2_CRT2_ON bit state is properly accounted for
    
    - when the TV DAC is used for crtc1 make sure to keep this bit set when
    initializing crtc2.
    - fixes bug 11894

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index cbb50d8..cf67400 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -565,20 +565,26 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
 			  ((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));
+    /* check to see if TV_DAC is enabled for another output and keep it enabled */
+    if (save->crtc2_gen_cntl & RADEON_CRTC2_CRT2_ON)
+	save->crtc2_gen_cntl = RADEON_CRTC2_CRT2_ON;
+    else
+	save->crtc2_gen_cntl = 0;
+
+    save->crtc2_gen_cntl |= (RADEON_CRTC2_EN
+			     | (format << 8)
+			     | RADEON_CRTC2_VSYNC_DIS
+			     | RADEON_CRTC2_HSYNC_DIS
+			     | RADEON_CRTC2_DISP_DIS
+			     | ((mode->Flags & V_DBLSCAN)
+				? RADEON_CRTC2_DBL_SCAN_EN
+				: 0)
+			     | ((mode->Flags & V_CSYNC)
+				? RADEON_CRTC2_CSYNC_EN
+				: 0)
+			     | ((mode->Flags & V_INTERLACE)
+				? RADEON_CRTC2_INTERLACE_EN
+				: 0));
 
     save->disp2_merge_cntl = info->SavedReg.disp2_merge_cntl;
     save->disp2_merge_cntl &= ~(RADEON_DISP2_RGB_OFFSET_EN);
diff-tree 08fe7ad00fba523775e95b5e6295fe23a5119d60 (from f56b90a60393ed187c0e39e149b2a3a32331ea52)
Author: Alex Deucher <alex at botch2.com>
Date:   Tue Aug 7 23:16:05 2007 -0400

    RADEON: fix ConnectorTable option after connector table re-work
    
    We may want to add the possiblity of more connectors to this option

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 7a26d43..440d39f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1998,6 +1998,11 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE);
 
     if (optstr) {
+	for (i = 2; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	    info->BiosConnector[i].valid = FALSE;
+	}
+	info->BiosConnector[0].valid = TRUE;
+	info->BiosConnector[1].valid = TRUE;
 	if (sscanf(optstr, "%u,%d,%d,%u,%u,%d,%d,%u",
 		   &info->BiosConnector[0].DDCType,
 		   &info->BiosConnector[0].DACType,
@@ -2012,7 +2017,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	}
     }
 
-    for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
 	    if (info->IsAtomBios) {
 		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
diff-tree f56b90a60393ed187c0e39e149b2a3a32331ea52 (from a88a0e77eec514325b4d07bf7be9fb04e6f8e244)
Author: Alex Deucher <alex at botch2.com>
Date:   Tue Aug 7 23:08:02 2007 -0400

    RADEON: Make sure the default TV standard is supported

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 9e167b5..2d7f195 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -587,6 +587,7 @@ Bool RADEONGetTVInfoFromBIOS (xf86Output
 		else if (refclk == 3)
 		    radeon_output->TVRefClk = 27.000000000;
 
+		radeon_output->SupportedTVStds = radeon_output->default_tvStd;
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
 		stds = RADEON_BIOS8(offset + 10) & 0x1f;
 		if (stds & TV_STD_NTSC) {
diff-tree a88a0e77eec514325b4d07bf7be9fb04e6f8e244 (from 3752808d6c08a9727370ef8d79088e787791e131)
Author: Alex Deucher <alex at botch2.com>
Date:   Tue Aug 7 00:43:20 2007 -0400

    RADEON: minor fix to legacy bios connector table

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 696fee4..9e167b5 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -239,11 +239,8 @@ static Bool RADEONGetLegacyConnectorInfo
 	    tmp = RADEON_BIOS16(entry);
 	    info->BiosConnector[i].ConnectorType = (tmp >> 12) & 0xf;
 	    info->BiosConnector[i].DDCType = (tmp >> 8) & 0xf;
-	    info->BiosConnector[i].DACType = tmp & 0x3;
-	    if (tmp & 0x10)
-		info->BiosConnector[i].TMDSType = TMDS_EXT;
-	    else
-		info->BiosConnector[i].TMDSType = TMDS_INT;
+	    info->BiosConnector[i].DACType = tmp & 0x1;
+	    info->BiosConnector[i].TMDSType = tmp & 0x10;
 
 	}
     } else {
diff-tree 3752808d6c08a9727370ef8d79088e787791e131 (from b4ec3e436afb5bc99ec755cbd96eee9a1ec492a5)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 16:13:39 2007 -0400

    RADEON: Always set MonType in radeon_detect()
    
    - Always set the the MonType in radeon detect even if no
    monitor is detected so users can still force disconnected
    outputs on.  For DVI-I users will have to set the
    dvi_monitor_type attribute to force digital or analog,
    everything else should just work.

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 1bbc73e..7a26d43 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1035,13 +1035,12 @@ radeon_detect(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    Bool connected = TRUE;
 
-    /* assume tv is connected for now */
+    /* assume tv is disconnected for now */
     if (radeon_output->type == OUTPUT_STV) {
-	/*radeon_output->MonType = MT_STV;*/
 	radeon_output->MonType = MT_NONE;
     } else if (radeon_output->type == OUTPUT_CTV) {
-	/*radeon_output->MonType = MT_CTV;*/
 	radeon_output->MonType = MT_NONE;
     } else {
 	radeon_output->MonType = MT_UNKNOWN;
@@ -1050,25 +1049,36 @@ radeon_detect(xf86OutputPtr output)
 
     /* force montype based on output property */
     if (radeon_output->type == OUTPUT_DVI) {
+	if (radeon_output->MonType == MT_NONE)
+	    connected = FALSE;
 	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
 	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
-	    if (radeon_output->MonType > MT_NONE) {
-		if (radeon_output->DVIType == DVI_ANALOG)
-		    radeon_output->MonType = MT_CRT;
-		else if (radeon_output->DVIType == DVI_DIGITAL)
-		    radeon_output->MonType = MT_DFP;
-	    }
+	    if (radeon_output->DVIType == DVI_ANALOG)
+		radeon_output->MonType = MT_CRT;
+	    else if (radeon_output->DVIType == DVI_DIGITAL)
+		radeon_output->MonType = MT_DFP;
 	}
     }
 
+    /* set montype so users can force outputs on even if detection fails */
+    if (radeon_output->MonType == MT_NONE) {
+	connected = FALSE;
+	if (radeon_output->type == OUTPUT_LVDS)
+	    radeon_output->MonType = MT_LCD;
+	else if (radeon_output->type == OUTPUT_VGA)
+            radeon_output->MonType = MT_CRT;
+	else if (radeon_output->type == OUTPUT_STV)
+            radeon_output->MonType = MT_STV;
+	else if (radeon_output->type == OUTPUT_CTV)
+            radeon_output->MonType = MT_CTV;
+	else if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+		 (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D))
+	    radeon_output->MonType = MT_DFP;
+    }
 
     if (radeon_output->MonType == MT_UNKNOWN) {
         output->subpixel_order = SubPixelUnknown;
 	return XF86OutputStatusUnknown;
-    }
-    else if (radeon_output->MonType == MT_NONE) {
-        output->subpixel_order = SubPixelUnknown;
-	return XF86OutputStatusDisconnected;
     } else {
 
       switch(radeon_output->MonType) {
@@ -1080,8 +1090,11 @@ radeon_detect(xf86OutputPtr output)
 	  output->subpixel_order = SubPixelNone;
 	  break;
       }
-      
-      return XF86OutputStatusConnected;
+
+      if (connected)
+	  return XF86OutputStatusConnected;
+      else
+	  return XF86OutputStatusDisconnected;
     }
 
 }
diff-tree b4ec3e436afb5bc99ec755cbd96eee9a1ec492a5 (from 1fc2a1120e7c05938e2bd72d3c7837ecff8bc9da)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 15:37:04 2007 -0400

    RADEON: add tv out properties

diff --git a/src/radeon.h b/src/radeon.h
index 432ee89..a8f72fc 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -926,6 +926,7 @@ extern int RADEONValidateDDCModes(ScrnIn
 				  RADEONMonitorType DisplayType, int crtc2);
 extern int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
+extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
 
 DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output);
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 4556552..696fee4 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -550,34 +550,35 @@ Bool RADEONGetTVInfoFromBIOS (xf86Output
 	    if (RADEON_BIOS8(offset + 6) == 'T') {
 		switch (RADEON_BIOS8(offset + 7) & 0xf) {
 		case 1:
-		    radeon_output->tvStd = TV_STD_NTSC;
+		    radeon_output->default_tvStd = TV_STD_NTSC;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
 		    break;
 		case 2:
-		    radeon_output->tvStd = TV_STD_PAL;
+		    radeon_output->default_tvStd = TV_STD_PAL;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
 		    break;
 		case 3:
-		    radeon_output->tvStd = TV_STD_PAL_M;
+		    radeon_output->default_tvStd = TV_STD_PAL_M;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
 		    break;
 		case 4:
-		    radeon_output->tvStd = TV_STD_PAL_60;
+		    radeon_output->default_tvStd = TV_STD_PAL_60;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
 		    break;
 		case 5:
-		    radeon_output->tvStd = TV_STD_NTSC_J;
+		    radeon_output->default_tvStd = TV_STD_NTSC_J;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
 		    break;
 		case 6:
-		    radeon_output->tvStd = TV_STD_SCART_PAL;
+		    radeon_output->default_tvStd = TV_STD_SCART_PAL;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n");
 		    break;
 		default:
-		    radeon_output->tvStd = TV_STD_NTSC;
+		    radeon_output->default_tvStd = TV_STD_NTSC;
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n");
 		    break;
 		}
+		radeon_output->tvStd = radeon_output->default_tvStd;
 
 		refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3;
 		if (refclk == 0)
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 8a35556..1bbc73e 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1125,6 +1125,10 @@ radeon_set_backlight_level(xf86OutputPtr
 static Atom backlight_atom;
 static Atom rmx_atom;
 static Atom monitor_type_atom;
+static Atom tv_hsize_atom;
+static Atom tv_hpos_atom;
+static Atom tv_vpos_atom;
+static Atom tv_std_atom;
 #define RADEON_MAX_BACKLIGHT_LEVEL 255
 
 static void
@@ -1188,7 +1192,7 @@ radeon_create_resources(xf86OutputPtr ou
     if (radeon_output->type == OUTPUT_DVI) {
 	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
 	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
-	    monitor_type_atom = MAKE_ATOM("monitor_type");
+	    monitor_type_atom = MAKE_ATOM("dvi_monitor_type");
 
 	    err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
 					    FALSE, FALSE, FALSE, 0, NULL);
@@ -1197,7 +1201,6 @@ radeon_create_resources(xf86OutputPtr ou
 			   "RRConfigureOutputProperty error, %d\n", err);
 	    }
 	    /* Set the current value of the backlight property */
-	    radeon_output->DVIType = DVI_AUTO;
 	    s = "auto";
 	    err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
 					 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
@@ -1209,6 +1212,92 @@ radeon_create_resources(xf86OutputPtr ou
 	}
     }
 
+    if (radeon_output->type == OUTPUT_STV ||
+	radeon_output->type == OUTPUT_CTV) {
+	tv_hsize_atom = MAKE_ATOM("tv_horizontal_size");
+
+	range[0] = -MAX_H_SIZE;
+	range[1] = MAX_H_SIZE;
+	err = RRConfigureOutputProperty(output->randr_output, tv_hsize_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	data = 0;
+	err = RRChangeOutputProperty(output->randr_output, tv_hsize_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
+    if (radeon_output->type == OUTPUT_STV ||
+	radeon_output->type == OUTPUT_CTV) {
+	tv_hpos_atom = MAKE_ATOM("tv_horizontal_position");
+
+	range[0] = -MAX_H_POSITION;
+	range[1] = MAX_H_POSITION;
+	err = RRConfigureOutputProperty(output->randr_output, tv_hpos_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	data = 0;
+	err = RRChangeOutputProperty(output->randr_output, tv_hpos_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
+    if (radeon_output->type == OUTPUT_STV ||
+	radeon_output->type == OUTPUT_CTV) {
+	tv_vpos_atom = MAKE_ATOM("tv_vertical_position");
+
+	range[0] = -MAX_V_POSITION;
+	range[1] = MAX_V_POSITION;
+	err = RRConfigureOutputProperty(output->randr_output, tv_vpos_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	data = 0;
+	err = RRChangeOutputProperty(output->randr_output, tv_vpos_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
+    if (radeon_output->type == OUTPUT_STV ||
+	radeon_output->type == OUTPUT_CTV) {
+	tv_std_atom = MAKE_ATOM("tv_standard");
+
+	err = RRConfigureOutputProperty(output->randr_output, tv_std_atom,
+					FALSE, FALSE, FALSE, 0, NULL);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	/* Set the current value of the backlight property */
+	s = "default";
+	err = RRChangeOutputProperty(output->randr_output, tv_std_atom,
+				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+				     FALSE, FALSE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
 }
 
 static Bool
@@ -1271,6 +1360,100 @@ radeon_set_property(xf86OutputPtr output
 	    return TRUE;
 	}
 	return FALSE;
+    } else if (property == tv_hsize_atom) {
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < -MAX_H_SIZE || val > MAX_H_SIZE)
+	    return FALSE;
+
+	radeon_output->hSize = val;
+	/*RADEONUpdateHVPosition(output, NULL);*/
+	return TRUE;
+    } else if (property == tv_hpos_atom) {
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
+	    return FALSE;
+
+	radeon_output->hPos = val;
+	/*RADEONUpdateHVPosition(output, NULL);*/
+	return TRUE;
+    } else if (property == tv_vpos_atom) {
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < -MAX_H_POSITION || val > MAX_H_POSITION)
+	    return FALSE;
+
+	radeon_output->vPos = val;
+	/*RADEONUpdateHVPosition(output, NULL);*/
+	return TRUE;
+    } else if (property == tv_std_atom) {
+	const char *s;
+	if (value->type != XA_STRING || value->format != 8)
+	    return FALSE;
+	s = (char*)value->data;
+	if (value->size == strlen("default") && !strncmp("default", s, strlen("default"))) {
+	    radeon_output->tvStd = radeon_output->default_tvStd;
+	    return TRUE;
+	} else if (value->size == strlen("ntsc") && !strncmp("ntsc", s, strlen("ntsc"))) {
+	    if (radeon_output->SupportedTVStds & TV_STD_NTSC) {
+		radeon_output->tvStd = TV_STD_NTSC;
+		return TRUE;
+	    } else {
+		return FALSE;
+	    }
+	} else if (value->size == strlen("pal") && !strncmp("pal", s, strlen("pal"))) {
+	    if (radeon_output->SupportedTVStds & TV_STD_PAL) {
+		radeon_output->tvStd = TV_STD_PAL;
+		return TRUE;
+	    } else {
+		return FALSE;
+	    }
+	} else if (value->size == strlen("pal-m") && !strncmp("pal-m", s, strlen("pal-m"))) {
+	    if (radeon_output->SupportedTVStds & TV_STD_PAL_M) {
+		radeon_output->tvStd = TV_STD_PAL_M;
+		return TRUE;
+	    } else {
+		return FALSE;
+	    }
+	} else if (value->size == strlen("pal-60") && !strncmp("pal-60", s, strlen("pal-60"))) {
+	    if (radeon_output->SupportedTVStds & TV_STD_PAL_60) {
+		radeon_output->tvStd = TV_STD_PAL_60;
+		return TRUE;
+	    } else {
+		return FALSE;
+	    }
+	} else if (value->size == strlen("ntsc-j") && !strncmp("ntsc-j", s, strlen("ntsc-j"))) {
+	    if (radeon_output->SupportedTVStds & TV_STD_NTSC_J) {
+		radeon_output->tvStd = TV_STD_NTSC_J;
+		return TRUE;
+	    } else {
+		return FALSE;
+	    }
+	} else if (value->size == strlen("scart-pal") && !strncmp("scart-pal", s, strlen("scart-pal"))) {
+	    if (radeon_output->SupportedTVStds & TV_STD_SCART_PAL) {
+		radeon_output->tvStd = TV_STD_SCART_PAL;
+		return TRUE;
+	    } else {
+		return FALSE;
+	    }
+	}
+	return FALSE;
     }
 
     return TRUE;
@@ -1667,6 +1850,7 @@ RADEONGetTVInfo(xf86OutputPtr output)
     if (RADEONGetTVInfoFromBIOS(output)) return;
 
     /* set some reasonable defaults */
+    radeon_output->default_tvStd = TV_STD_NTSC;
     radeon_output->tvStd = TV_STD_NTSC;
     radeon_output->TVRefClk = 27.000000000;
     radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 27b78cc..d79e7ad 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -197,6 +197,7 @@ typedef struct _RADEONOutputPrivateRec {
     int               DotClock;
     RADEONTMDSPll     tmds_pll[4];
     /* TV out */
+    TVStd             default_tvStd;
     TVStd             tvStd;
     int               hPos;
     int               vPos;
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 3c12dfd..db5288a 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -556,7 +556,7 @@ void RADEONInitTVRegisters(xf86OutputPtr
 
 
 /* Set hw registers for a new h/v position & h size */
-static void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode)
+void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
diff-tree 1fc2a1120e7c05938e2bd72d3c7837ecff8bc9da (from 7d8eb3751d74bd8a1fb9fa2d2fcb9c4c895f6ba4)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 14:41:57 2007 -0400

    RADEON: switch DVI-I monitor type attribute to string

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 9ac7d43..8a35556 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1188,22 +1188,20 @@ radeon_create_resources(xf86OutputPtr ou
     if (radeon_output->type == OUTPUT_DVI) {
 	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
 	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
-	    monitor_type_atom = MAKE_ATOM("MONITORTYPE");
+	    monitor_type_atom = MAKE_ATOM("monitor_type");
 
-	    range[0] = DVI_AUTO;
-	    range[1] = DVI_ANALOG;
 	    err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
-					    FALSE, TRUE, FALSE, 2, range);
+					    FALSE, FALSE, FALSE, 0, NULL);
 	    if (err != 0) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "RRConfigureOutputProperty error, %d\n", err);
 	    }
 	    /* Set the current value of the backlight property */
 	    radeon_output->DVIType = DVI_AUTO;
-	    data = DVI_AUTO;
+	    s = "auto";
 	    err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
-					 XA_INTEGER, 32, PropModeReplace, 1, &data,
-					 FALSE, TRUE);
+					 XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+					 FALSE, FALSE);
 	    if (err != 0) {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "RRChangeOutputProperty error, %d\n", err);
@@ -1258,17 +1256,21 @@ radeon_set_property(xf86OutputPtr output
 	    return FALSE;
 	}
     } else if (property == monitor_type_atom) {
-	if (value->type != XA_INTEGER ||
-	    value->format != 32 ||
-	    value->size != 1) {
+	const char *s;
+	if (value->type != XA_STRING || value->format != 8)
 	    return FALSE;
+	s = (char*)value->data;
+	if (value->size == strlen("auto") && !strncmp("auto", s, strlen("auto"))) {
+	    radeon_output->DVIType = DVI_AUTO;
+	    return TRUE;
+	} else if (value->size == strlen("analog") && !strncmp("analog", s, strlen("analog"))) {
+	    radeon_output->DVIType = DVI_ANALOG;
+	    return TRUE;
+	} else if (value->size == strlen("digital") && !strncmp("digital", s, strlen("digital"))) {
+	    radeon_output->DVIType = DVI_DIGITAL;
+	    return TRUE;
 	}
-
-	val = *(INT32 *)value->data;
-	if (val < DVI_AUTO || val > DVI_ANALOG)
-	    return FALSE;
-
-	radeon_output->DVIType = val;
+	return FALSE;
     }
 
     return TRUE;
diff-tree 7d8eb3751d74bd8a1fb9fa2d2fcb9c4c895f6ba4 (from e71bb88bc9052af8866fb6945dbc06dbb0e6d1c0)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 14:31:18 2007 -0400

    RADEON: make backlight attribute lower case

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 31d8881..9ac7d43 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1139,7 +1139,7 @@ radeon_create_resources(xf86OutputPtr ou
 
     /* backlight control */
     if (radeon_output->type == OUTPUT_LVDS) {
-	backlight_atom = MAKE_ATOM("BACKLIGHT");
+	backlight_atom = MAKE_ATOM("backlight");
 
 	range[0] = 0;
 	range[1] = RADEON_MAX_BACKLIGHT_LEVEL;
diff-tree e71bb88bc9052af8866fb6945dbc06dbb0e6d1c0 (from 284323135ec04635dfa9cabd5790a35b953abca2)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 14:26:15 2007 -0400

    RADEON: switch RMX attribute to string type
    
    Still not actually hooked up.

diff --git a/src/radeon_output.c b/src/radeon_output.c
index a759452..31d8881 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1135,6 +1135,7 @@ radeon_create_resources(xf86OutputPtr ou
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     INT32 range[2];
     int data, err;
+    const char *s;
 
     /* backlight control */
     if (radeon_output->type == OUTPUT_LVDS) {
@@ -1161,23 +1162,22 @@ radeon_create_resources(xf86OutputPtr ou
     }
 
     /* RMX control - fullscreen, centered, keep ratio */
+    /* actually more of a crtc property as only crtc1 has rmx */
     if (radeon_output->type == OUTPUT_LVDS ||
 	radeon_output->type == OUTPUT_DVI) {
-	rmx_atom = MAKE_ATOM("PANELSCALER");
+	rmx_atom = MAKE_ATOM("scaler");
 
-	range[0] = 0;
-	range[1] = 2;
 	err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
-					FALSE, TRUE, FALSE, 2, range);
+					FALSE, FALSE, FALSE, 0, NULL);
 	if (err != 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the property */
-	data = 0;
+	s = "fill";
 	err = RRChangeOutputProperty(output->randr_output, rmx_atom,
-				     XA_INTEGER, 32, PropModeReplace, 1, &data,
-				     FALSE, TRUE);
+				     XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s,
+				     FALSE, FALSE);
 	if (err != 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRChangeOutputProperty error, %d\n", err);
@@ -1239,7 +1239,24 @@ radeon_set_property(xf86OutputPtr output
 	radeon_set_backlight_level(output, val);
 
     } else if (property == rmx_atom) {
-	return TRUE;
+	xf86CrtcPtr	crtc = output->crtc;
+	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+	if (radeon_crtc->crtc_id == 0) {
+	    const char *s;
+	    if (value->type != XA_STRING || value->format != 8)
+		return FALSE;
+	    s = (char*)value->data;
+	    if (value->size == strlen("full") && !strncmp("full", s, strlen("full"))) {
+		return TRUE;
+	    } else if (value->size == strlen("aspect") && !strncmp("aspect", s, strlen("aspect"))) {
+		return TRUE;
+	    } else if (value->size == strlen("center") && !strncmp("center", s, strlen("center"))) {
+		return TRUE;
+	    }
+	    return FALSE;
+	} else {
+	    return FALSE;
+	}
     } else if (property == monitor_type_atom) {
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
diff-tree 284323135ec04635dfa9cabd5790a35b953abca2 (from d1abdad167aa24ac970c69422435df443c82ebd6)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 04:35:24 2007 -0400

    RADEON: typo

diff --git a/src/radeon_output.c b/src/radeon_output.c
index f65507a..a759452 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1858,7 +1858,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		    } else {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
 		    }
-		} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) {
+		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
 		    if (num_vga > 1) {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
 			num_vga--;
@@ -1876,7 +1876,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		    } else {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
 		    }
-		} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
+		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
 		    if (num_vga > 1) {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
 			num_vga--;
diff-tree d1abdad167aa24ac970c69422435df443c82ebd6 (from 0cca25d8d6a0cb0d29b68e6cd9c699d1390aede1)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 03:45:02 2007 -0400

    RADEON: fixes
    
    - fix output ordering
    - set tv-out to return un-connected for now in radeon_detect()

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index fe1d091..4556552 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -200,13 +200,13 @@ static Bool RADEONGetATOMConnectorInfoFr
 
     /* DVI-I ports have 2 entries: one for analog, one for digital.  combine them */
     if (info->BiosConnector[0].valid && info->BiosConnector[7].valid) {
-	info->BiosConnector[0].TMDSType = info->BiosConnector[7].TMDSType;
-	info->BiosConnector[7].valid = FALSE;
+	info->BiosConnector[7].DACType = info->BiosConnector[0].DACType;
+	info->BiosConnector[0].valid = FALSE;
     }
 
     if (info->BiosConnector[4].valid && info->BiosConnector[3].valid) {
-	info->BiosConnector[4].TMDSType = info->BiosConnector[3].TMDSType;
-	info->BiosConnector[3].valid = FALSE;
+	info->BiosConnector[3].DACType = info->BiosConnector[4].DACType;
+	info->BiosConnector[4].valid = FALSE;
     }
 
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 0cd1183..f65507a 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1038,9 +1038,11 @@ radeon_detect(xf86OutputPtr output)
 
     /* assume tv is connected for now */
     if (radeon_output->type == OUTPUT_STV) {
-	radeon_output->MonType = MT_STV;
+	/*radeon_output->MonType = MT_STV;*/
+	radeon_output->MonType = MT_NONE;
     } else if (radeon_output->type == OUTPUT_CTV) {
-	radeon_output->MonType = MT_CTV;
+	/*radeon_output->MonType = MT_CTV;*/
+	radeon_output->MonType = MT_NONE;
     } else {
 	radeon_output->MonType = MT_UNKNOWN;
 	RADEONConnectorFindMonitor(pScrn, output);
@@ -1851,17 +1853,17 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
 		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
 		    if (num_dvi > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
 			num_dvi--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
 		    }
 		} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) {
 		    if (num_vga > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
 			num_vga--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
 		    }
 		} else
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
@@ -1869,17 +1871,17 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
 		     (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
 		    if (num_dvi > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
 			num_dvi--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
 		    }
 		} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
 		    if (num_vga > 1) {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
 			num_vga--;
 		    } else {
-			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
 		    }
 		} else
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
diff-tree 0cca25d8d6a0cb0d29b68e6cd9c699d1390aede1 (from ba5496ae7973786802962bf649dd91c219531749)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 03:19:24 2007 -0400

    RADEON: Fix DVI-I support in ATOM bios connector table parsing

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index b79fea7..fe1d091 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -198,6 +198,18 @@ static Bool RADEONGetATOMConnectorInfoFr
 	return FALSE;
     }
 
+    /* DVI-I ports have 2 entries: one for analog, one for digital.  combine them */
+    if (info->BiosConnector[0].valid && info->BiosConnector[7].valid) {
+	info->BiosConnector[0].TMDSType = info->BiosConnector[7].TMDSType;
+	info->BiosConnector[7].valid = FALSE;
+    }
+
+    if (info->BiosConnector[4].valid && info->BiosConnector[3].valid) {
+	info->BiosConnector[4].TMDSType = info->BiosConnector[3].TMDSType;
+	info->BiosConnector[3].valid = FALSE;
+    }
+
+
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
diff-tree ba5496ae7973786802962bf649dd91c219531749 (from 2ec22783ddf4c522df9e5fd1b2003854486d7a2b)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 02:27:32 2007 -0400

    RADEON: refactor output init to handle multiple DVI or VGA
    
    - refactor output init to handle multiple DVI or VGA with the new
    bios table parsing

diff --git a/src/radeon_output.c b/src/radeon_output.c
index d0225aa..0cd1183 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1701,7 +1701,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     xf86OutputPtr output;
     char *optstr;
     int i = 0;
-
+    int num_vga = 0;
+    int num_dvi = 0;
 
     /* We first get the information about all connectors from BIOS.
      * This is how the card is phyiscally wired up.
@@ -1795,6 +1796,27 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
+	    if (info->IsAtomBios) {
+		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
+		    num_dvi++;
+		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_VGA_ATOM) {
+		    num_vga++;
+		}
+	    } else {
+		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
+		    num_dvi++;
+		} else if (info->BiosConnector[i].ConnectorType == CONNECTOR_CRT) {
+		    num_vga++;
+		}
+	    }
+	}
+    }
+
+    for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	if (info->BiosConnector[i].valid) {
 	    RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
 	    if (!radeon_output) {
 		return FALSE;
@@ -1825,39 +1847,40 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    }
 	    RADEONSetOutputType(pScrn, radeon_output);
 	    if (info->IsAtomBios) {
-		if (((info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		     (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
-		     (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_A_ATOM)) &&
-		    ((info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-		     (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
-		     (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_A_ATOM))) {
-		    if (i > 0)
+		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+		    (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_A_ATOM)) {
+		    if (num_dvi > 1) {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
-		    else
+			num_dvi--;
+		    } else {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
-		} else if ((info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) &&
-			   (info->BiosConnector[1].ConnectorType == CONNECTOR_VGA_ATOM)) {
-		    if (i > 0)
+		    }
+		} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) {
+		    if (num_vga > 1) {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
-		    else
+			num_vga--;
+		    } else {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+		    }
 		} else
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
 	    } else {
-		if (((info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D) ||
-		     (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_I)) &&
-		    ((info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_D) ||
-		     (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_I))) {
-		    if (i > 0)
+		if ((info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_D) ||
+		     (info->BiosConnector[i].ConnectorType == CONNECTOR_DVI_I)) {
+		    if (num_dvi > 1) {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
-		    else
+			num_dvi--;
+		    } else {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
-		} else if ((info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) &&
-			   (info->BiosConnector[1].ConnectorType == CONNECTOR_CRT)) {
-		    if (i > 0)
+		    }
+		} else if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
+		    if (num_vga > 1) {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
-		    else
+			num_vga--;
+		    } else {
 			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+		    }
 		} else
 		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
 	    }
diff-tree 2ec22783ddf4c522df9e5fd1b2003854486d7a2b (from cc8e1d95f1b90a259beea4e8cc4d7e29af660919)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 01:39:35 2007 -0400

    RADEON: attempt to do the right thing for standards other than PAL or NTSC

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index ec355e2..3c12dfd 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -203,7 +203,10 @@ static Bool RADEONInitTVRestarts(xf86Out
     const TVModeConstants *constPtr;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -211,7 +214,10 @@ static Bool RADEONInitTVRestarts(xf86Out
     hTotal = constPtr->horTotal;
     vTotal = constPtr->verTotal;
     
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	fTotal = NTSC_TV_VFTOTAL + 1;
     else
 	fTotal = PAL_TV_VFTOTAL + 1;
@@ -219,7 +225,9 @@ static Bool RADEONInitTVRestarts(xf86Out
     /* Adjust positions 1&2 in hor. code timing table */
     hOffset = radeon_output->hPos * H_POS_UNIT;
 
-    if (radeon_output->tvStd == TV_STD_NTSC) {
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M) {
 	p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
 	p2 = hor_timing_NTSC[ H_TABLE_POS2 ];
     } else {
@@ -247,7 +255,10 @@ static Bool RADEONInitTVRestarts(xf86Out
      * Convert vPos TV lines to n. of CRTC pixels
      * Be verrrrry careful when mixing signed & unsigned values in C..
      */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M||
+	radeon_output->tvStd == TV_STD_PAL_60)
 	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
     else
 	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
@@ -267,7 +278,10 @@ static Bool RADEONInitTVRestarts(xf86Out
 	   save->tv_frestart , save->tv_vrestart , save->tv_hrestart);
 
     /* Compute H_INC from hSize */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M ||
+	radeon_output->tvStd == TV_STD_PAL_60)
 	hInc = (CARD16)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
 			(radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
     else
@@ -298,7 +312,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
 
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -330,16 +347,18 @@ void RADEONInitTVRegisters(xf86OutputPtr
 	                       | (0x3b << RADEON_BLANK_LEVEL_SHIFT)
 	                       | (0x6 << RADEON_CY_FILT_BLEND_SHIFT);
 
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M ||
+	radeon_output->tvStd == TV_STD_PAL_60 ||
+	radeon_output->tvStd == TV_STD_SCART_PAL) {
 	save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT);
-    else
+	save->tv_modulator_cntl2 = 0x00000191;
+    } else {
 	save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
 	                            | (0x3b << RADEON_SET_UP_LEVEL_SHIFT);
-
-    if (radeon_output->tvStd == TV_STD_NTSC)
-	save->tv_modulator_cntl2 = 0x00000191;
-    else
 	save->tv_modulator_cntl2 = 0x003e01b2;
+    }
 
     save->pll_test_cntl = 0;
 
@@ -364,7 +383,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
 
     save->tv_sync_size = constPtr->horResolution + 8;
 
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M ||
+	radeon_output->tvStd == TV_STD_PAL_60)
 	vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
     else
 	vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
@@ -378,7 +400,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
     else
 	save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
 
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+        radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	flicker_removal =
 	    (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5;
     else
@@ -416,12 +441,16 @@ void RADEONInitTVRegisters(xf86OutputPtr
 
     save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | (8 << 16) | (6 << 20);
 
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+        radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
     else
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
 
 #if 0
+    /* needs fixes for r4xx */
     save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
 	                 | RADEON_TV_DAC_BDACPD);
 
@@ -435,7 +464,10 @@ void RADEONInitTVRegisters(xf86OutputPtr
     }
 #endif
 
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+        radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
 	    (((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
 	    ((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
@@ -454,18 +486,30 @@ void RADEONInitTVRegisters(xf86OutputPtr
 
     save->tv_vdisp = constPtr->verResolution - 1;
 
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+        radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	save->tv_ftotal = NTSC_TV_VFTOTAL;
     else
 	save->tv_ftotal = PAL_TV_VFTOTAL;
 
     save->tv_vtotal = constPtr->verTotal - 1;
 
-    if (radeon_output->tvStd == TV_STD_NTSC) {
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M) {
 	hor_timing = hor_timing_NTSC;
-	vert_timing = vert_timing_NTSC;
     } else {
 	hor_timing = hor_timing_PAL;
+    }
+
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+	radeon_output->tvStd == TV_STD_PAL_M ||
+	radeon_output->tvStd == TV_STD_PAL_60) {
+	vert_timing = vert_timing_NTSC;
+    } else {
 	vert_timing = vert_timing_PAL;
     }
 
@@ -546,7 +590,10 @@ void RADEONAdjustCrtcRegistersForTV(Scrn
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -576,7 +623,10 @@ void RADEONAdjustPLLRegistersForTV(ScrnI
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -627,7 +677,10 @@ void RADEONAdjustCrtc2RegistersForTV(Scr
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
@@ -657,7 +710,10 @@ void RADEONAdjustPLL2RegistersForTV(Scrn
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     /* FIXME: need to revisit this when we add more modes */
-    if (radeon_output->tvStd == TV_STD_NTSC)
+    if (radeon_output->tvStd == TV_STD_NTSC ||
+	radeon_output->tvStd == TV_STD_NTSC_J ||
+        radeon_output->tvStd == TV_STD_PAL_M ||
+        radeon_output->tvStd == TV_STD_PAL_60)
 	constPtr = &availableTVModes[0];
     else
 	constPtr = &availableTVModes[1];
diff-tree cc8e1d95f1b90a259beea4e8cc4d7e29af660919 (from b61a49f2a5401560f85e11bcdd005287433cad12)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Aug 5 01:14:36 2007 -0400

    RADEON: Major rework of BIOS table parsing
    
    - greatly simplify ATOM and legacy connector table parsing
    - use bios tables to detect LVDS and TV outputs
    - add support for TV table parsing (legacy only)

diff --git a/src/radeon.h b/src/radeon.h
index 7792f31..432ee89 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -875,6 +875,7 @@ extern Bool        RADEONGetConnectorInf
 extern Bool        RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn);
 extern Bool        RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool        RADEONGetTVInfoFromBIOS (xf86OutputPtr output);
 extern Bool        RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
 
 extern void        RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 26019ba..b79fea7 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -141,6 +141,175 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn
     return TRUE;
 }
 
+static Bool RADEONGetATOMConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    int offset, i, tmp, tmp0, crtc, portinfo, gpio;
+
+    if (!info->VBIOS) return FALSE;
+
+    offset = RADEON_BIOS16(info->MasterDataStart + 22);
+
+    if (offset) {
+	tmp = RADEON_BIOS16(offset + 4);
+	for (i = 0; i < 8; i++) {
+	    if (tmp & (1 << i)) {
+		info->BiosConnector[i].valid = TRUE;
+		portinfo = RADEON_BIOS16(offset + 6 + i * 2);
+		info->BiosConnector[i].DACType = (portinfo & 0xf) - 1;
+		info->BiosConnector[i].ConnectorType = (portinfo >> 4) & 0xf;
+		crtc = (portinfo >> 8) & 0xf;
+		tmp0 = RADEON_BIOS16(info->MasterDataStart + 24);
+		gpio = RADEON_BIOS16(tmp0 + 4 + 27 * crtc) * 4;
+		switch(gpio) {
+		case RADEON_GPIO_MONID:
+		    info->BiosConnector[i].DDCType = DDC_MONID;
+		    break;
+		case RADEON_GPIO_DVI_DDC:
+		    info->BiosConnector[i].DDCType = DDC_DVI;
+		    break;
+		case RADEON_GPIO_VGA_DDC:
+		    info->BiosConnector[i].DDCType = DDC_VGA;
+		    break;
+		case RADEON_GPIO_CRT2_DDC:
+		    info->BiosConnector[i].DDCType = DDC_CRT2;
+		    break;
+		case RADEON_LCD_GPIO_MASK:
+		    info->BiosConnector[i].DDCType = DDC_LCD;
+		    break;
+		default:
+		    info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+		    break;
+		}
+
+		if (i == 3)
+		    info->BiosConnector[i].TMDSType = TMDS_INT;
+		else if (i == 7)
+		    info->BiosConnector[i].TMDSType = TMDS_EXT;
+		else
+		    info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+
+	    } else {
+		info->BiosConnector[i].valid = FALSE;
+	    }
+	}   
+    } else {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
+	return FALSE;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	if (info->BiosConnector[i].valid) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+		       i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
+	}
+    }
+
+    return TRUE;
+}
+
+static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    int offset, i, entry, tmp, tmp0, tmp1;
+
+    offset = RADEON_BIOS16(info->ROMHeaderStart + 0x50);
+    if (offset) {
+	for (i = 0; i < 4; i++) {
+	    entry = offset + 2 + i*2;
+
+	    if (!RADEON_BIOS16(entry)) {
+		break;
+	    }
+	    info->BiosConnector[i].valid = TRUE;
+	    tmp = RADEON_BIOS16(entry);
+	    info->BiosConnector[i].ConnectorType = (tmp >> 12) & 0xf;
+	    info->BiosConnector[i].DDCType = (tmp >> 8) & 0xf;
+	    info->BiosConnector[i].DACType = tmp & 0x3;
+	    if (tmp & 0x10)
+		info->BiosConnector[i].TMDSType = TMDS_EXT;
+	    else
+		info->BiosConnector[i].TMDSType = TMDS_INT;
+
+	}
+    } else {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Connector Info Table found!\n");
+	return FALSE;
+    }
+
+    /* check LVDS table */
+    if (info->IsMobility) {
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x40);
+	if (offset) {
+	    info->BiosConnector[4].valid = TRUE;
+	    info->BiosConnector[4].ConnectorType = CONNECTOR_PROPRIETARY;
+	    info->BiosConnector[4].DACType = DAC_NONE;
+	    info->BiosConnector[4].TMDSType = TMDS_NONE;
+
+	    tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
+	    if (tmp) {
+		tmp0 = RADEON_BIOS16(tmp + 0x15);
+		if (tmp0) {
+		    tmp1 = RADEON_BIOS8(tmp0+2) & 0x07;
+		    if (tmp1) {	    
+			info->BiosConnector[4].DDCType	= tmp1;      
+			if (info->BiosConnector[4].DDCType > DDC_LCD) {
+			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+				       "Unknown DDCType %d found\n",
+				       info->BiosConnector[4].DDCType);
+			    info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+			}
+			xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
+		    }
+		}
+	    } else {
+		info->BiosConnector[4].DDCType = DDC_NONE_DETECTED;
+	    }
+	}
+    }
+
+    /* check TV table */
+    if (info->InternalTVOut) {
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+	if (offset) {
+	    if (RADEON_BIOS8(offset + 6) == 'T') {
+		info->BiosConnector[5].valid = TRUE;
+		/* assume s-video for now */
+		info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
+		info->BiosConnector[5].DACType = DAC_TVDAC;
+		info->BiosConnector[5].TMDSType = TMDS_NONE;
+		info->BiosConnector[5].DDCType = DDC_NONE_DETECTED;
+	    }
+	}
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
+    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	if (info->BiosConnector[i].valid) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+		       i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
+	}
+    }
+
+    return TRUE;
+}
+
+Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+
+    if(!info->VBIOS) return FALSE;
+
+    if (info->IsAtomBios)
+	return RADEONGetATOMConnectorInfoFromBIOS(pScrn);
+    else
+	return RADEONGetLegacyConnectorInfoFromBIOS(pScrn);
+}
+
+#if 0
 Bool RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
@@ -350,6 +519,98 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
     }
     return TRUE;
 }
+#endif
+
+Bool RADEONGetTVInfoFromBIOS (xf86OutputPtr output) {
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int offset, refclk, stds;
+
+    if (!info->VBIOS) return FALSE;
+
+    if (info->IsAtomBios) {
+	/* no idea where TV table is on ATOM bios */
+	return FALSE;
+    } else {
+	offset = RADEON_BIOS16(info->ROMHeaderStart + 0x32);
+	if (offset) {
+	    if (RADEON_BIOS8(offset + 6) == 'T') {
+		switch (RADEON_BIOS8(offset + 7) & 0xf) {
+		case 1:
+		    radeon_output->tvStd = TV_STD_NTSC;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC\n");
+		    break;
+		case 2:
+		    radeon_output->tvStd = TV_STD_PAL;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL\n");
+		    break;
+		case 3:
+		    radeon_output->tvStd = TV_STD_PAL_M;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-M\n");
+		    break;
+		case 4:
+		    radeon_output->tvStd = TV_STD_PAL_60;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: PAL-60\n");
+		    break;
+		case 5:
+		    radeon_output->tvStd = TV_STD_NTSC_J;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: NTSC-J\n");
+		    break;
+		case 6:
+		    radeon_output->tvStd = TV_STD_SCART_PAL;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Default TV standard: SCART-PAL\n");
+		    break;
+		default:
+		    radeon_output->tvStd = TV_STD_NTSC;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Unknown TV standard; defaulting to NTSC\n");
+		    break;
+		}
+
+		refclk = (RADEON_BIOS8(offset + 9) >> 2) & 0x3;
+		if (refclk == 0)
+		    radeon_output->TVRefClk = 29.498928713; /* MHz */
+		else if (refclk == 1)
+		    radeon_output->TVRefClk = 28.636360000;
+		else if (refclk == 2)
+		    radeon_output->TVRefClk = 14.318180000;
+		else if (refclk == 3)
+		    radeon_output->TVRefClk = 27.000000000;
+
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standards supported by chip: ");
+		stds = RADEON_BIOS8(offset + 10) & 0x1f;
+		if (stds & TV_STD_NTSC) {
+		    radeon_output->SupportedTVStds |= TV_STD_NTSC;
+		    ErrorF("NTSC ");
+		}
+		if (stds & TV_STD_PAL) {
+		    radeon_output->SupportedTVStds |= TV_STD_PAL;
+		    ErrorF("PAL ");
+		}
+		if (stds & TV_STD_PAL_M) {
+		    radeon_output->SupportedTVStds |= TV_STD_PAL_M;
+		    ErrorF("PAL-M ");
+		}
+		if (stds & TV_STD_PAL_60) {
+		    radeon_output->SupportedTVStds |= TV_STD_PAL_60;
+		    ErrorF("PAL-60 ");
+		}
+		if (stds & TV_STD_NTSC_J) {
+		    radeon_output->SupportedTVStds |= TV_STD_NTSC_J;
+		    ErrorF("NTSC-J ");
+		}
+		if (stds & TV_STD_SCART_PAL) {
+		    radeon_output->SupportedTVStds |= TV_STD_SCART_PAL;
+		    ErrorF("SCART-PAL");
+		}
+		ErrorF("\n");
+
+		return TRUE;
+	    } else
+		return FALSE;
+	}
+    }
+}
 
 /* Read PLL parameters from BIOS block.  Default to typical values if there
    is no BIOS. */
diff --git a/src/radeon_output.c b/src/radeon_output.c
index fa6fb4f..d0225aa 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -611,6 +611,7 @@ radeon_mode_valid(xf86OutputPtr output, 
 
     if (radeon_output->type == OUTPUT_STV ||
 	radeon_output->type == OUTPUT_CTV) {
+	/* FIXME: Update when more modes are added */
 	if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
 	    return MODE_OK;
 	else
@@ -1630,6 +1631,27 @@ RADEONGetTMDSInfo(xf86OutputPtr output)
     }
 }
 
+static void
+RADEONGetTVInfo(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int i;
+
+    radeon_output->hPos = 0;
+    radeon_output->vPos = 0;
+    radeon_output->hSize = 0;
+
+    if (RADEONGetTVInfoFromBIOS(output)) return;
+
+    /* set some reasonable defaults */
+    radeon_output->tvStd = TV_STD_NTSC;
+    radeon_output->TVRefClk = 27.000000000;
+    radeon_output->SupportedTVStds = TV_STD_NTSC | TV_STD_PAL;
+
+}
+
 void RADEONInitConnector(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
@@ -1657,12 +1679,11 @@ void RADEONInitConnector(xf86OutputPtr o
 
     if (radeon_output->type == OUTPUT_DVI) {
 	RADEONGetTMDSInfo(output);
+    }
 
-	// FIXME -- this should be done in detect or getmodes
-	/*if (i == 0)
-	  RADEONGetHardCodedEDIDFromBIOS(output);*/
-
-	/*RADEONUpdatePanelSize(output);*/
+    if (radeon_output->type == OUTPUT_STV ||
+	radeon_output->type == OUTPUT_CTV) {
+	RADEONGetTVInfo(output);
     }
 
     if (radeon_output->DACType == DAC_TVDAC) {
@@ -1688,15 +1709,14 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
      * If not, we may have problem -- need to use MonitorLayout option.
      */
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	info->BiosConnector[i].valid = FALSE;
 	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
 	info->BiosConnector[i].DACType = DAC_UNKNOWN;
 	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
 	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
     }
 
-    if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
-        ((info->BiosConnector[0].DDCType == 0) &&
-        (info->BiosConnector[1].DDCType == 0))) {
+    if (!RADEONGetConnectorInfoFromBIOS(pScrn)) {
 	if (info->IsMobility) {
 	    /* Below is the most common setting, but may not be true */
 #if defined(__powerpc__)
@@ -1712,6 +1732,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_EXT;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+
 	} else {
 	    /* Below is the most common setting, but may not be true */
 	    info->BiosConnector[0].DDCType = DDC_DVI;
@@ -1725,6 +1746,13 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
 	}
 
+	if (info->InternalTVOut) {
+	    info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
+	    info->BiosConnector[2].DACType = DAC_TVDAC;
+	    info->BiosConnector[2].TMDSType = TMDS_NONE;
+	    info->BiosConnector[2].DDCType = DDC_NONE_DETECTED;
+	}
+
        /* Some cards have the DDC lines swapped and we have no way to
         * detect it yet (Mac cards)
         */
@@ -1766,7 +1794,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     }
 
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	if (info->BiosConnector[i].ConnectorType != CONNECTOR_NONE) {
+	if (info->BiosConnector[i].valid) {
 	    RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
 	    if (!radeon_output) {
 		return FALSE;
@@ -1851,98 +1879,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	}
     }
 
-    /* if it's a mobility make sure we have a LVDS port */
-    if (info->IsMobility) {
-	if (info->IsAtomBios) {
-	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_LVDS_ATOM &&
-		info->BiosConnector[1].ConnectorType != CONNECTOR_LVDS_ATOM) {
-		/* add LVDS port */
-		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-		if (!radeon_output) {
-		    return FALSE;
-		}
-		radeon_output->MonType = MT_UNKNOWN;
-		radeon_output->DDCType = DDC_LCD;
-		radeon_output->DACType = DAC_NONE;
-		radeon_output->TMDSType = TMDS_NONE;
-		radeon_output->ConnectorType = CONNECTOR_LVDS_ATOM;
-		RADEONSetOutputType(pScrn, radeon_output);
-		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-		if (!output) {
-		    return FALSE;
-		}
-		output->driver_private = radeon_output;
-		output->possible_crtcs = 1;
-		output->possible_clones = 0;
-
-		RADEONInitConnector(output);
-
-	    }
-	} else {
-	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_PROPRIETARY &&
-		info->BiosConnector[1].ConnectorType != CONNECTOR_PROPRIETARY) {
-		/* add LVDS port */
-		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-		if (!radeon_output) {
-		    return FALSE;
-		}
-		radeon_output->MonType = MT_UNKNOWN;
-		radeon_output->DDCType = DDC_LCD;
-		radeon_output->DACType = DAC_NONE;
-		radeon_output->TMDSType = TMDS_NONE;
-		radeon_output->ConnectorType = CONNECTOR_PROPRIETARY;
-		RADEONSetOutputType(pScrn, radeon_output);
-		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-		if (!output) {
-		    return FALSE;
-		}
-		output->driver_private = radeon_output;
-		output->possible_crtcs = 1;
-		output->possible_clones = 0;
-
-		RADEONInitConnector(output);
-	    }
-	}
-    }
-
-    /* add TV out */
-#if 0
-    if (info->InternalTVOut) {
-	/* need to check the bios tables to see if we really have tv out and what type we have */
-	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-	if (!radeon_output) {
-	    return FALSE;
-	}
-	/* hard code type for now */
-	radeon_output->MonType = MT_STV;
-	radeon_output->DDCType = DDC_NONE_DETECTED;
-	radeon_output->DACType = DAC_TVDAC;
-	radeon_output->TMDSType = TMDS_NONE;
-
-	/* hard code type for now */
-	if (info->IsAtomBios)
-	    radeon_output->ConnectorType = CONNECTOR_STV_ATOM;
-	else
-	    radeon_output->ConnectorType = CONNECTOR_STV;
-
-	radeon_output->tvStd = TV_STD_NTSC;
-	radeon_output->hPos = 0;
-	radeon_output->vPos = 0;
-	radeon_output->hSize = 0;
-
-	RADEONSetOutputType(pScrn, radeon_output);
-	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-	if (!output) {
-	    return FALSE;
-	}
-	output->driver_private = radeon_output;
-	output->possible_crtcs = 1 | 2;
-	output->possible_clones = 0;
-
-	RADEONInitConnector(output);
-    }
-#endif
-
     return TRUE;
 }
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index f0df341..27b78cc 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -140,13 +140,12 @@ typedef enum
 /* standards */
 typedef enum
 {
-    TV_STD_NTSC,
-    TV_STD_PAL,
-    TV_STD_PAL_M,
-    TV_STD_PAL_60,
-    TV_STD_NTSC_J,
-    TV_STD_PAL_CN,
-    TV_STD_PAL_N
+    TV_STD_NTSC      = 1,
+    TV_STD_PAL       = 2,
+    TV_STD_PAL_M     = 4,
+    TV_STD_PAL_60    = 8,
+    TV_STD_NTSC_J    = 16,
+    TV_STD_SCART_PAL = 32,
 } TVStd;
 
 typedef struct _RADEONCrtcPrivateRec {
@@ -167,6 +166,7 @@ typedef struct {
     RADEONDacType DACType;
     RADEONTmdsType TMDSType;
     RADEONConnectorType ConnectorType;
+    Bool valid;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -201,10 +201,12 @@ typedef struct _RADEONOutputPrivateRec {
     int               hPos;
     int               vPos;
     int               hSize;
+    float             TVRefClk;
+    int               SupportedTVStds;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 #define RADEON_MAX_CRTC 2
-#define RADEON_MAX_BIOS_CONNECTOR 2
+#define RADEON_MAX_BIOS_CONNECTOR 8
 
 typedef struct
 {
diff-tree 1de52d91ff3a04b9b587b858e1e5be40d3a7fd0a (from 371001c0433db1d17e468f3ea99ea57f922145a3)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Aug 4 17:58:58 2007 +1000

    update configure.ac for 6.6.193 release

diff --git a/configure.ac b/configure.ac
index f444afb..441e723 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-ati],
-        6.6.192,
+        6.6.193,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-ati)
 
diff-tree 371001c0433db1d17e468f3ea99ea57f922145a3 (from 90946c53d7a4b23d03270ad6da0450759a11de3d)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Aug 4 17:51:19 2007 +1000

    radeon: remove unused variables

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 95e669d..02f5960 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2071,7 +2071,6 @@ RADEONCRTC2Blank(RADEONInfoPtr info, Boo
 void RADEONBlank(ScrnInfoPtr pScrn, Bool Blank)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
 
     if (!pRADEONEnt->HasSecondary ||
@@ -2223,7 +2222,6 @@ RADEONDisplayPowerManagementSet(ScrnInfo
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *pPort;
 
     if (!pScrn->vtSema)
 	return;
diff-tree 90946c53d7a4b23d03270ad6da0450759a11de3d (from e30a145934df8f6a7f71290d6c75e4239f9d52f7)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Aug 4 17:51:06 2007 +1000

    ati: add -Wall for gcc
    
    As per luc's "suggestion" in Novell bug.
    
    This may generate warnings on 64-bit until we get rid of CARD32

diff --git a/configure.ac b/configure.ac
index 8b29d8d..f444afb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,6 +39,10 @@ AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 AC_PROG_CC
 
+if test "x$GCC" = "xyes"; then
+	CFLAGS="$CFLAGS -Wall"
+fi
+
 AH_TOP([#include "xorg-server.h"])
 
 AC_ARG_WITH(xorg-module-dir,
diff-tree e30a145934df8f6a7f71290d6c75e4239f9d52f7 (from a156db5e8b037ed12a448f70045453baf9d0c504)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Aug 4 17:44:46 2007 +1000

    radeon: cleanup some pieces of the dpms/blank register programming

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 0bf7271..95e669d 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2020,33 +2020,26 @@ RADEONOutputsBlank(ScrnInfoPtr pScrn, RA
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 val;
 
     switch(pPort->MonType) {
     case MT_LCD:
-	if (Blank)
-	    OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS);
-	else
-	    OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS);
+	val = (Blank == TRUE) ? RADEON_LVDS_DISPLAY_DIS : 0;
+	OUTREGP(RADEON_LVDS_GEN_CNTL, val, ~RADEON_LVDS_DISPLAY_DIS);
         break;
     case MT_CRT:
 	if ((info->ChipFamily == CHIP_FAMILY_R200) && (pPort->DACType == DAC_TVDAC)) {
-	    if (Blank)
-		OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-	    else
-		OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
+	    val = (Blank == TRUE) ? RADEON_FP2_BLANK_EN : 0;
+	    OUTREGP(RADEON_FP2_GEN_CNTL, val, ~RADEON_FP2_BLANK_EN);
 	}
         break;
     case MT_DFP:
 	if (pPort->TMDSType == TMDS_EXT) {
-	    if (Blank)
-		OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-	    else
-		OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
+	    val = Blank ? RADEON_FP2_BLANK_EN : 0;
+	    OUTREGP(RADEON_FP2_GEN_CNTL, val, ~RADEON_FP2_BLANK_EN);
 	} else {
-	    if (Blank)
-		OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN);
-	    else
-		OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN);
+	    val = Blank ? RADEON_FP_BLANK_EN : 0;
+	    OUTREGP(RADEON_FP_GEN_CNTL, val, ~RADEON_FP_BLANK_EN);
 	}
         break;
     case MT_NONE:
@@ -2059,28 +2052,19 @@ static void
 RADEONCRTC1Blank(RADEONInfoPtr info, Bool Blank)
 {
     unsigned char *RADEONMMIO = info->MMIO;
-    
-    if (Blank)
-	OUTREGP(RADEON_CRTC_EXT_CNTL,
-		RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS,
-		~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS));
-    else
-	OUTREGP(RADEON_CRTC_EXT_CNTL, 0,
-		~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS));
+    CARD32 val = (Blank == TRUE) ? (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS) : 0;
+
+    OUTREGP(RADEON_CRTC_EXT_CNTL, val,
+	    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS));
 }
 
 static void
 RADEONCRTC2Blank(RADEONInfoPtr info, Bool Blank)
 {
     unsigned char *RADEONMMIO = info->MMIO;
-    
-    if (Blank)
-	OUTREGP(RADEON_CRTC2_GEN_CNTL,
-		RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS,
-		~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
-    else
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
-		~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+    CARD32 val = (Blank == TRUE) ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : 0;
+    OUTREGP(RADEON_CRTC2_GEN_CNTL, val,
+	    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
 }
 
 /* Blank screen */
@@ -2178,63 +2162,58 @@ void
 RADEONCRTC1DPMS(RADEONInfoPtr info, int Mode)
 {
     unsigned char *RADEONMMIO = info->MMIO;
-
+    CARD32 val;
     switch (Mode) {
 	case DPMSModeOn:
 	    /* Screen: On; HSync: On, VSync: On */
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, 0,
-		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    val = 0;
 	    break;
 	case DPMSModeStandby:
 	    /* Screen: Off; HSync: Off, VSync: On */
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS),
-		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    val = (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS);
 	    break;
 	case DPMSModeSuspend:
 	    /* Screen: Off; HSync: On, VSync: Off */
-	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS),
-		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    val = (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS);
 	    break;
 	case DPMSModeOff:
 	default:
 	    /* Screen: Off; HSync: Off, VSync: Off */
-	    OUTREGP(RADEON_CRTC_EXT_CNTL,
-		    (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS),
-		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    val = (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
 	    break;
     }
+    OUTREGP(RADEON_CRTC_EXT_CNTL, val,
+	    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+
 }
 
 void
 RADEONCRTC2DPMS(RADEONInfoPtr info, int Mode)
 {
     unsigned char *RADEONMMIO = info->MMIO;
-    
+    CARD32 val;
     switch (Mode) {
 	case DPMSModeOn:
 	    /* Screen: On; HSync: On, VSync: On */
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
-		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    val = 0;
 	    break;
 	case DPMSModeStandby:
 	    /* Screen: Off; HSync: Off, VSync: On */
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
-		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    val = (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS);
 	    break;
 	case DPMSModeSuspend:
 	    /* Screen: Off; HSync: On, VSync: Off */
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
-		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    val = (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS);
 	    break;
 	case DPMSModeOff:
 	default:
 	    /* Screen: Off; HSync: Off, VSync: Off */
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL,
-		    (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS),
-		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    val = (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS);
 	    break;
 	    
     }
+    OUTREGP(RADEON_CRTC2_GEN_CNTL, val,
+	    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));    
 }
 
 
diff-tree a156db5e8b037ed12a448f70045453baf9d0c504 (from 165a07cbbfcd94e3d1fac434b8fada8d29428a09)
Author: Luc Verhaegen <libv at skynet.be>
Date:   Sat Aug 4 17:37:18 2007 +1000

    Clean up PortInfo to CRTC mapping
    
    Also sanitise blanking and DPMS functions
    
    Fixes from Novell Bug 264720, and fd.o 10772

diff --git a/src/radeon.h b/src/radeon.h
index a22e481..5f3f4ab 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -904,14 +904,12 @@ extern void        RADEONEnableDisplay(S
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
 extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
 extern void        RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn);
-extern void        RADEONUnblank(ScrnInfoPtr pScrn);
-extern void        RADEONBlank(ScrnInfoPtr pScrn);
+extern void        RADEONBlank(ScrnInfoPtr pScrn, Bool Blank);
 extern void        RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
 						   int PowerManagementMode,
 						   int flags);
 extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn);
 extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
-extern RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num);
 extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 				  RADEONMonitorType DisplayType, int crtc2);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 6ae8862..0bf7271 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -941,6 +941,16 @@ void RADEONGetTVDacAdjInfo(ScrnInfoPtr p
     }
 }
 
+static void
+RADEONConnectorReverse(RADEONEntPtr pRADEONEnt)
+{
+    RADEONConnector *connector;
+
+    connector = pRADEONEnt->PortInfo[0];
+    pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
+    pRADEONEnt->PortInfo[1] = connector;
+}
+
 /*
  * initialise the static data sos we don't have to re-do at randr change */
 void RADEONSetupConnectors(ScrnInfoPtr pScrn)
@@ -998,12 +1008,9 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     }
 
     /* always make TMDS_INT port first*/
-    if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) {
-        RADEONConnector *connector;
-        connector = pRADEONEnt->PortInfo[0];
-        pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
-        pRADEONEnt->PortInfo[1] = connector;
-    } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT &&
+    if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT)
+	RADEONConnectorReverse(pRADEONEnt);
+    else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT &&
                 pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) {
         /* no TMDS_INT port, make primary DAC port first */
 	/* On my Inspiron 8600 both internal and external ports are
@@ -1011,10 +1018,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	   swap when the first port is not DAC_PRIMARY */
         if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) &&  (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) &&
 	     (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) {
-            RADEONConnector *connector;
-            connector = pRADEONEnt->PortInfo[0];
-            pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
-            pRADEONEnt->PortInfo[1] = connector;
+	    RADEONConnectorReverse(pRADEONEnt);
         }
     }
 
@@ -1269,10 +1273,7 @@ static void RADEONQueryConnectedDisplays
 	    pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN;
 	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
 	    pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_NONE;
-	    
-	    pRADEONEnt->PortInfo[0]->crtc_num = 1;
-	    pRADEONEnt->PortInfo[1]->crtc_num = 2;
-	    
+
 	    return;
 	}
 	
@@ -1307,16 +1308,12 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     Bool head_reversed = FALSE;
-    RADEONConnector *connector;
 
     info->MergeType = MT_NONE;
 
     if (!info->IsSecondary) {
       RADEONQueryConnectedDisplays(pScrn);
 
-      pRADEONEnt->PortInfo[0]->crtc_num = 1;
-      pRADEONEnt->PortInfo[1]->crtc_num = 2;
-
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		 "Port1:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
 		 MonTypeName[pRADEONEnt->PortInfo[0]->MonType+1], 
@@ -1341,8 +1338,8 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 	if (pRADEONEnt->PortInfo[0]->MonType == MT_NONE) {
 	    if (pRADEONEnt->PortInfo[1]->MonType != MT_NONE) {
 		/* Only one detected on secondary, let it to be primary */
-		pRADEONEnt->PortInfo[0]->crtc_num = 2;
-		pRADEONEnt->PortInfo[1]->crtc_num = 1;
+		if (!head_reversed)
+		    RADEONConnectorReverse(pRADEONEnt);
 		head_reversed = TRUE;
 	    } else {
 		/* None detected, Default to a CRT connected */
@@ -1354,10 +1351,10 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 	    (pRADEONEnt->PortInfo[1]->MonType == MT_CRT)) {
 	    if (!(INREG(RADEON_LVDS_GEN_CNTL) & RADEON_LVDS_ON)) {
 		/* LCD is switched off, don't turn it on, otherwise it may casue lockup due to SS issue. */
-		pRADEONEnt->PortInfo[0]->crtc_num = 2;
-		pRADEONEnt->PortInfo[1]->crtc_num = 1;
-		pRADEONEnt->PortInfo[0]->MonType = MT_NONE;
+		if (!head_reversed)
+		    RADEONConnectorReverse(pRADEONEnt);
 		head_reversed = TRUE;
+		pRADEONEnt->PortInfo[0]->MonType = MT_NONE;
 		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "LCD is switched off, only CRT will be used\n");
 	    }
 	}
@@ -1371,8 +1368,8 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 		    */
 		    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Reverse Display cannot be used for mobility chip\n");
 		} else {
-		    pRADEONEnt->PortInfo[0]->crtc_num = 2;
-		    pRADEONEnt->PortInfo[1]->crtc_num = 1;
+		    if (!head_reversed)
+			RADEONConnectorReverse(pRADEONEnt);
 		    head_reversed = TRUE;
 		    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Primary and Secondary mapping is reversed\n");
 		}
@@ -1386,46 +1383,33 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 
     if(pRADEONEnt->HasCRTC2) {
 	if(info->IsSecondary) {
-	    connector = RADEONGetCrtcConnector(pScrn, 2);
   	    pRADEONEnt->Controller[1]->binding = 2;
-	    if (connector) {
-		info->DisplayType = connector->MonType;
-		pScrn->monitor->DDC = connector->MonInfo;
-	    }
+	    info->DisplayType = pRADEONEnt->PortInfo[1]->MonType;
+	    pScrn->monitor->DDC = pRADEONEnt->PortInfo[1]->MonInfo;
 	} else {
-	    connector = RADEONGetCrtcConnector(pScrn, 1);
   	    pRADEONEnt->Controller[0]->binding = 1;
-	    if (connector) {
-		info->DisplayType = connector->MonType; 
-		pScrn->monitor->DDC = connector->MonInfo;
-	    }
+	    info->DisplayType = pRADEONEnt->PortInfo[0]->MonType;
+	    pScrn->monitor->DDC = pRADEONEnt->PortInfo[0]->MonInfo;
 	}
-	
+
 	if(!pRADEONEnt->HasSecondary) {
-	    connector = RADEONGetCrtcConnector(pScrn, 2);
-	    if (connector)
-		info->MergeType = connector->MonType;
+	    info->MergeType = pRADEONEnt->PortInfo[1]->MonType;
 	    if (info->MergeType)
   	    	pRADEONEnt->Controller[1]->binding = 1;
-	} 
+	}
     } else {
-	connector = RADEONGetCrtcConnector(pScrn, 1);
-	if (connector) {
-	    if (connector->MonType == MT_NONE) 
-		connector->MonType = MT_CRT;
-	    info->DisplayType = connector->MonType; 
-	    pScrn->monitor->DDC = connector->MonInfo;
-	}
-	connector = RADEONGetCrtcConnector(pScrn, 2);
-	if (connector)
-	    connector->MonType = MT_NONE;
+	if (pRADEONEnt->PortInfo[0]->MonType == MT_NONE)
+	    pRADEONEnt->PortInfo[0]->MonType = MT_CRT;
+	info->DisplayType = pRADEONEnt->PortInfo[0]->MonType;
+	pScrn->monitor->DDC = pRADEONEnt->PortInfo[0]->MonInfo;
+
+	pRADEONEnt->PortInfo[1]->MonType = MT_NONE;
 	pRADEONEnt->Controller[1]->binding = 1;
     }
 
     if (!info->IsSecondary) {
-	connector = RADEONGetCrtcConnector(pScrn, 2);
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head:   Port%d ---- \n", head_reversed?2:1);
-	if (connector->MonType != MT_NONE)
+	if (pRADEONEnt->PortInfo[1]->MonType != MT_NONE)
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2);
  	else
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
@@ -2031,259 +2015,247 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
     RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2);
 }
 
-static void RADEONBlankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+static void
+RADEONOutputsBlank(ScrnInfoPtr pScrn, RADEONConnector *pPort, Bool Blank)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
     switch(pPort->MonType) {
     case MT_LCD:
-        OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS);
+	if (Blank)
+	    OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS);
+	else
+	    OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS);
         break;
-
     case MT_CRT:
-       if ((info->ChipFamily == CHIP_FAMILY_R200) && 
- 	  (pPort->DACType == DAC_TVDAC))
-	    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-      
+	if ((info->ChipFamily == CHIP_FAMILY_R200) && (pPort->DACType == DAC_TVDAC)) {
+	    if (Blank)
+		OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
+	    else
+		OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
+	}
         break;
     case MT_DFP:
-        if (pPort->TMDSType == TMDS_EXT)
-  	    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-        else
-	    OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN);
-      
+	if (pPort->TMDSType == TMDS_EXT) {
+	    if (Blank)
+		OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
+	    else
+		OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
+	} else {
+	    if (Blank)
+		OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN);
+	    else
+		OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN);
+	}
         break;
     case MT_NONE:
     default:
         break;
-    }   
+    }
+}
+ 
+static void
+RADEONCRTC1Blank(RADEONInfoPtr info, Bool Blank)
+{
+    unsigned char *RADEONMMIO = info->MMIO;
+    
+    if (Blank)
+	OUTREGP(RADEON_CRTC_EXT_CNTL,
+		RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS,
+		~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS));
+    else
+	OUTREGP(RADEON_CRTC_EXT_CNTL, 0,
+		~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_HSYNC_DIS));
+}
+
+static void
+RADEONCRTC2Blank(RADEONInfoPtr info, Bool Blank)
+{
+    unsigned char *RADEONMMIO = info->MMIO;
+    
+    if (Blank)
+	OUTREGP(RADEON_CRTC2_GEN_CNTL,
+		RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS,
+		~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+    else
+	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
+		~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
 }
 
 /* Blank screen */
-void RADEONBlank(ScrnInfoPtr pScrn)
+void RADEONBlank(ScrnInfoPtr pScrn, Bool Blank)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *pPort;
 
     if (!pRADEONEnt->HasSecondary ||
 	(pRADEONEnt->HasSecondary && !info->IsSwitching) ||
 	(info->IsSwitching && (!info->IsSecondary))) {
-        pPort = RADEONGetCrtcConnector(pScrn, 1);
-	if (pPort)
-	  RADEONBlankSet(pScrn, pPort);
-	OUTREGP (RADEON_CRTC_EXT_CNTL,
-		 RADEON_CRTC_DISPLAY_DIS |
-		 RADEON_CRTC_VSYNC_DIS |
-		 RADEON_CRTC_HSYNC_DIS,
-		 ~(RADEON_CRTC_DISPLAY_DIS |
-		   RADEON_CRTC_VSYNC_DIS | 
-		   RADEON_CRTC_HSYNC_DIS));
-
-	if (!pRADEONEnt->HasCRTC2) return;
+ 
+	RADEONOutputsBlank(pScrn, pRADEONEnt->PortInfo[0], Blank);
+	RADEONCRTC1Blank(info, Blank);
+ 
+	if (!pRADEONEnt->HasCRTC2)
+	    return;
 
 	if (pRADEONEnt->Controller[1]->binding == 1) {
-	    pPort = RADEONGetCrtcConnector(pScrn, 2);
-	    if (pPort)
-		RADEONBlankSet(pScrn, pPort);
-	    OUTREGP (RADEON_CRTC2_GEN_CNTL,
-		     RADEON_CRTC2_DISP_DIS |
-		     RADEON_CRTC2_VSYNC_DIS |
-		     RADEON_CRTC2_HSYNC_DIS,
-		     ~(RADEON_CRTC2_DISP_DIS |
-		       RADEON_CRTC2_VSYNC_DIS | 
-		       RADEON_CRTC2_HSYNC_DIS));
+	    RADEONOutputsBlank(pScrn, pRADEONEnt->PortInfo[1], Blank);
+	    RADEONCRTC2Blank(info, Blank);
 	}
     }
 
     if ((pRADEONEnt->HasSecondary && !info->IsSwitching) ||
 	(info->IsSwitching && info->IsSecondary)) {
-	pPort = RADEONGetCrtcConnector(pScrn, 2);
-	if (pPort)
-	    RADEONBlankSet(pScrn, pPort);
-	OUTREGP (RADEON_CRTC2_GEN_CNTL,
-		 RADEON_CRTC2_DISP_DIS |
-		 RADEON_CRTC2_VSYNC_DIS |
-		 RADEON_CRTC2_HSYNC_DIS,
-		 ~(RADEON_CRTC2_DISP_DIS |
-		   RADEON_CRTC2_VSYNC_DIS | 
-		   RADEON_CRTC2_HSYNC_DIS));
+	RADEONOutputsBlank(pScrn, pRADEONEnt->PortInfo[1], Blank);
+	RADEONCRTC2Blank(info, Blank);
     }
 }
 
-static void RADEONUnblankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+
+static void
+RADEONOutputsDPMS(ScrnInfoPtr pScrn, RADEONConnector *pPort, int Mode)
 {
-    RADEONInfoPtr info = RADEONPTR (pScrn);
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    switch(pPort->MonType) {
+    RADEONMonitorType MonType;
+    RADEONTmdsType TmdsType;
+    RADEONDacType DacType;
+  
+    MonType = pPort->MonType;
+    TmdsType = pPort->TMDSType;
+    DacType = pPort->DACType;
+    
+    switch (MonType) {
     case MT_LCD:
-        OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS);
-        break;
-    case MT_CRT:
-        if ((info->ChipFamily == CHIP_FAMILY_R200) &&
-	  (pPort->DACType == DAC_TVDAC))
-	      OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
-        break;
+	if (Mode == DPMSModeOn) {
+	    OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON);
+	    usleep (info->PanelPwrDly * 1000);
+	    OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON);
+	} else {
+	    unsigned int tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+	    
+	    /* Asic bug, when turning off LVDS_ON, we have to make sure
+	       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off */
+	    if (info->IsMobility || info->IsIGP)
+		OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+	    OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~(RADEON_LVDS_BLON | RADEON_LVDS_ON));
+	    if (info->IsMobility || info->IsIGP)
+		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+	}
+	break;
     case MT_DFP:
-        if (pPort->TMDSType == TMDS_EXT)
-	    OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
-        else
-	    OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN);
-        break;
-    case MT_NONE:
+	if (Mode == DPMSModeOn) {
+	    if (TmdsType == TMDS_EXT) {
+		OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
+		OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON);
+		if (info->ChipFamily >= CHIP_FAMILY_R200)
+		    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, ~RADEON_FP2_DVO_EN);
+	    } else
+		OUTREGP(RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN),
+			~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
+	} else {
+	    if (TmdsType == TMDS_EXT) {
+		OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
+		OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON);
+		if (info->ChipFamily >= CHIP_FAMILY_R200) {
+		    OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN);
+		}
+	    } else
+		OUTREGP(RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
+	}
+	break;
+    case MT_CRT:
     default:
-        break;
+	RADEONDacPowerSet(pScrn, (Mode == DPMSModeOn), (DacType == DAC_PRIMARY));
+	break;
     }
 }
 
-/* Unblank screen */
-void RADEONUnblank(ScrnInfoPtr pScrn)
+void
+RADEONCRTC1DPMS(RADEONInfoPtr info, int Mode)
 {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *pPort;
-
-    if (!pRADEONEnt->HasSecondary ||
-	(pRADEONEnt->HasSecondary && !info->IsSwitching) ||
-	(info->IsSwitching && (!info->IsSecondary))) {
-	pPort = RADEONGetCrtcConnector(pScrn, 1);
-	if (pPort)
-	    RADEONUnblankSet(pScrn, pPort);
-      OUTREGP(RADEON_CRTC_EXT_CNTL,
-	      0,
-	      ~(RADEON_CRTC_DISPLAY_DIS |
-		RADEON_CRTC_VSYNC_DIS |
-		RADEON_CRTC_HSYNC_DIS));
-
-      if (!pRADEONEnt->HasCRTC2) return;
-
-      if (pRADEONEnt->Controller[1]->binding == 1) {
-	pPort = RADEONGetCrtcConnector(pScrn, 2);
-	if (pPort)
-	    RADEONUnblankSet(pScrn, pPort);
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
-		~(RADEON_CRTC2_DISP_DIS |
-		  RADEON_CRTC2_VSYNC_DIS |
-		  RADEON_CRTC2_HSYNC_DIS));
-      }
-    }
 
-    if ((pRADEONEnt->HasSecondary && !info->IsSwitching) ||
-	(info->IsSwitching && info->IsSecondary)) {
-	pPort = RADEONGetCrtcConnector(pScrn, 2);
-	if (pPort)
-	    RADEONUnblankSet(pScrn, pPort);
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
-		~(RADEON_CRTC2_DISP_DIS |
-		  RADEON_CRTC2_VSYNC_DIS |
-		  RADEON_CRTC2_HSYNC_DIS));
+    switch (Mode) {
+	case DPMSModeOn:
+	    /* Screen: On; HSync: On, VSync: On */
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, 0,
+		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    break;
+	case DPMSModeStandby:
+	    /* Screen: Off; HSync: Off, VSync: On */
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS),
+		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    break;
+	case DPMSModeSuspend:
+	    /* Screen: Off; HSync: On, VSync: Off */
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS),
+		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    break;
+	case DPMSModeOff:
+	default:
+	    /* Screen: Off; HSync: Off, VSync: Off */
+	    OUTREGP(RADEON_CRTC_EXT_CNTL,
+		    (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS),
+		    ~(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS));
+	    break;
     }
 }
 
-static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort)
-{
-  RADEONInfoPtr  info       = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
-  RADEONMonitorType MonType;
-  RADEONTmdsType TmdsType;
-  RADEONDacType DacType;
-
-  MonType = pPort->MonType;
-  TmdsType = pPort->TMDSType;
-  DacType = pPort->DACType;
-
-  switch(MonType) {
-  case MT_LCD:
-    OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON);
-    usleep (info->PanelPwrDly * 1000);
-    OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON);
-    break;
-  case MT_DFP:
-    if (TmdsType == TMDS_EXT) {
-      OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
-      OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON);
-      if (info->ChipFamily >= CHIP_FAMILY_R200) {
-	OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, 
-		 ~RADEON_FP2_DVO_EN);
-      }
-    } else
-      OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN),
-	       ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
-    break;
-  case MT_CRT:
-  default:
-    RADEONDacPowerSet(pScrn, TRUE, (DacType == DAC_PRIMARY));
-    break;
-  }
-}
-
-static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+void
+RADEONCRTC2DPMS(RADEONInfoPtr info, int Mode)
 {
-  RADEONInfoPtr  info       = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
-  RADEONMonitorType MonType;
-  RADEONTmdsType TmdsType;
-  RADEONDacType DacType;
-  unsigned long tmpPixclksCntl;
-
-  MonType = pPort->MonType;
-  TmdsType = pPort->TMDSType;
-  DacType = pPort->DACType;
-
-  switch(MonType) {
-  case MT_LCD:
-    tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-    if (info->IsMobility || info->IsIGP) {
-      /* Asic bug, when turning off LVDS_ON, we have to make sure
-	 RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-      */
-      OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-    }
-    OUTREGP (RADEON_LVDS_GEN_CNTL, 0,
-	     ~(RADEON_LVDS_BLON | RADEON_LVDS_ON));
-    if (info->IsMobility || info->IsIGP) {
-      OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
-    }
-    break;
-  case MT_DFP:
-    if (TmdsType == TMDS_EXT) {
-      OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-      OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON);
-      if (info->ChipFamily >= CHIP_FAMILY_R200) {
-	OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN);
-      }
-    } else
-      OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
-    break;
-  case MT_CRT:
-  default:
-    RADEONDacPowerSet(pScrn, FALSE, (DacType == DAC_PRIMARY));
-    break;
-  }
+    unsigned char *RADEONMMIO = info->MMIO;
+    
+    switch (Mode) {
+	case DPMSModeOn:
+	    /* Screen: On; HSync: On, VSync: On */
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
+		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    break;
+	case DPMSModeStandby:
+	    /* Screen: Off; HSync: Off, VSync: On */
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
+		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    break;
+	case DPMSModeSuspend:
+	    /* Screen: Off; HSync: On, VSync: Off */
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
+		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    break;
+	case DPMSModeOff:
+	default:
+	    /* Screen: Off; HSync: Off, VSync: Off */
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL,
+		    (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS),
+		    ~(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS));
+	    break;
+	    
+    }
 }
 
 
 /* Sets VESA Display Power Management Signaling (DPMS) Mode */
-void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
-					    int PowerManagementMode,
-					    int flags)
+void
+RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     RADEONConnector *pPort;
-    if (!pScrn->vtSema) return;
+
+    if (!pScrn->vtSema)
+	return;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONDisplayPowerManagementSet(%d,0x%x)\n",
 		   PowerManagementMode, flags);
 
 #ifdef XF86DRI
-    if (info->CPStarted) DRILock(pScrn->pScreen, 0);
+    if (info->CPStarted)
+	DRILock(pScrn->pScreen, 0);
 #endif
 
     if (info->accelOn)
@@ -2292,92 +2264,23 @@ void RADEONDisplayPowerManagementSet(Scr
     if (info->FBDev) {
 	fbdevHWDPMSSet(pScrn, PowerManagementMode, flags);
     } else {
-	int             mask1     = (RADEON_CRTC_DISPLAY_DIS |
-				     RADEON_CRTC_HSYNC_DIS |
-				     RADEON_CRTC_VSYNC_DIS);
-	int             mask2     = (RADEON_CRTC2_DISP_DIS |
-				     RADEON_CRTC2_VSYNC_DIS |
-				     RADEON_CRTC2_HSYNC_DIS);
-
-	switch (PowerManagementMode) {
-	case DPMSModeOn:
-	    /* Screen: On; HSync: On, VSync: On */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask1);
-	    }
-	    break;
-
-	case DPMSModeStandby:
-	    /* Screen: Off; HSync: Off, VSync: On */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
-			~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			    (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
-			    ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL,
-			(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS),
-			~mask1);
-	    }
-	    break;
-
-	case DPMSModeSuspend:
-	    /* Screen: Off; HSync: On, VSync: Off */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
-			~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			    (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
-			    ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL,
-			(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS),
-			~mask1);
-	    }
-	    break;
-
-	case DPMSModeOff:
-	    /* Screen: Off; HSync: Off, VSync: Off */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL, mask1, ~mask1);
-	    }
-	    break;
-	}
+	if (info->IsSecondary) {
+	    RADEONCRTC2DPMS(info, PowerManagementMode);
+	    RADEONOutputsDPMS(pScrn, pRADEONEnt->PortInfo[1], PowerManagementMode);
+	} else {
+	    RADEONCRTC1DPMS(info, PowerManagementMode);
+	    RADEONOutputsDPMS(pScrn, pRADEONEnt->PortInfo[0], PowerManagementMode);
 
-	if (PowerManagementMode == DPMSModeOn) {
-  	    pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
-   	    RADEONDPMSSetOn(pScrn, pPort);
 	    if (pRADEONEnt->Controller[1]->binding == 1) {
-	      pPort = RADEONGetCrtcConnector(pScrn, 2);
-	      RADEONDPMSSetOn(pScrn, pPort);
+		RADEONCRTC2DPMS(info, PowerManagementMode);
+		RADEONOutputsDPMS(pScrn, pRADEONEnt->PortInfo[1], PowerManagementMode);
 	    }
-	} else if ((PowerManagementMode == DPMSModeOff) ||
-		   (PowerManagementMode == DPMSModeSuspend) ||
-		   (PowerManagementMode == DPMSModeStandby)) {
-	    pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
-	    RADEONDPMSSetOff(pScrn, pPort);
-	    if (pRADEONEnt->Controller[1]->binding == 1) {
-	        pPort = RADEONGetCrtcConnector(pScrn, 2);	        
-	        RADEONDPMSSetOff(pScrn, pPort);
-	    }
-        }
+	}
     }
 
 #ifdef XF86DRI
-    if (info->CPStarted) DRIUnlock(pScrn->pScreen);
+    if (info->CPStarted)
+	DRIUnlock(pScrn->pScreen);
 #endif
 }
 
@@ -2405,28 +2308,21 @@ Bool RADEONAllocateControllers(ScrnInfoP
 Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    int i;
 
     if (pRADEONEnt->PortInfo[0])
         return TRUE;
-    
-    /* for now always allocate max connectors */
-    for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
-      pRADEONEnt->PortInfo[i] = xcalloc(sizeof(RADEONConnector), 1);
-      if (!pRADEONEnt->PortInfo[i])
+
+    /* for now always allocate both connectors */
+    pRADEONEnt->PortInfo[0] = xcalloc(sizeof(RADEONConnector), 1);
+    if (!pRADEONEnt->PortInfo[0])
+	return FALSE;
+
+    pRADEONEnt->PortInfo[1] = xcalloc(sizeof(RADEONConnector), 1);
+    if (!pRADEONEnt->PortInfo[1]) {
+	xfree(pRADEONEnt->PortInfo[0]);
 	return FALSE;
     }
 
     return TRUE;
 }
 
-RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
-{
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
-    if (pRADEONEnt->PortInfo[0]->crtc_num == crtc_num)
-      return pRADEONEnt->PortInfo[0];
-    else if (pRADEONEnt->PortInfo[1]->crtc_num == crtc_num)
-      return pRADEONEnt->PortInfo[1];
-    return NULL;
-}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 5c20b0e..74323c9 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2034,9 +2034,8 @@ static Bool RADEONPreInitModes(ScrnInfoP
 	xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE);
 
     /* don't use RMX if we have a dual-tmds panels */
-    if ((connector = RADEONGetCrtcConnector(pScrn, 2)))
-	if (connector->MonType == MT_DFP)
-	    info->ddc_mode = TRUE;
+    if (pRADEONEnt->PortInfo[1]->MonType == MT_DFP)
+	info->ddc_mode = TRUE;
     /* don't use RMX if we are Dell Server */  
     if (info->IsDellServer)
 	info->ddc_mode = TRUE;
@@ -5176,11 +5175,8 @@ static void RADEONRestoreMode(ScrnInfoPt
 	    RADEONRestoreCrtc2Registers(pScrn, restore);
 	    RADEONRestorePLL2Registers(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
-	    pPort = RADEONGetCrtcConnector(pScrn, 2);
-	    if (pPort) {
-		RADEONEnableDisplay(pScrn, pPort, TRUE);
-		pCRTC2->IsActive = TRUE;
-	    }
+	    RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE);
+	    pCRTC2->IsActive = TRUE;
 	} else {
 	    RADEONRestoreMemMapRegisters(pScrn, restore);
 	    RADEONRestoreCommonRegisters(pScrn, restore);
@@ -5192,17 +5188,11 @@ static void RADEONRestoreMode(ScrnInfoPt
             RADEONRestoreCrtcRegisters(pScrn, restore);
             RADEONRestorePLLRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
-	    pPort = RADEONGetCrtcConnector(pScrn, 1);
-	    if (pPort) {
-		RADEONEnableDisplay(pScrn, pPort, TRUE);
-		pCRTC1->IsActive = TRUE;
-	    }
+	    RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[0], TRUE);
+	    pCRTC1->IsActive = TRUE;
 	    if (pCRTC2->binding == 1) {
-		pPort = RADEONGetCrtcConnector(pScrn, 2);
-		if (pPort) {
-		    RADEONEnableDisplay(pScrn, pPort, TRUE);
-		    pCRTC2->IsActive = TRUE;
-		}
+		RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE);
+		pCRTC2->IsActive = TRUE;
 	    }
 	}
     } else {
@@ -5216,17 +5206,11 @@ static void RADEONRestoreMode(ScrnInfoPt
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
-	pPort = RADEONGetCrtcConnector(pScrn, 1);
-	if (pPort) {
-	    RADEONEnableDisplay(pScrn, pPort, TRUE);
-	    pCRTC1->IsActive = TRUE;
-	}
-	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    pPort = RADEONGetCrtcConnector(pScrn, 2);
-	    if (pPort) {
-		RADEONEnableDisplay(pScrn, pPort, TRUE);
-		pCRTC2->IsActive = TRUE;
-	    }
+	RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[0], TRUE);
+	pCRTC1->IsActive = TRUE;
+	if (pCRTC2->binding == 1) {
+	    RADEONEnableDisplay(pScrn, pRADEONEnt->PortInfo[1], TRUE);
+	    pCRTC2->IsActive = TRUE;
 	}
     }
 
@@ -5538,7 +5522,7 @@ static void RADEONRestore(ScrnInfoPtr pS
 	fbdevHWRestore(pScrn);
 	return;
     }
-    RADEONBlank(pScrn);
+    RADEONBlank(pScrn, TRUE);
 
     OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
     RADEONPllErrataAfterIndex(info);
@@ -5602,7 +5586,7 @@ static void RADEONRestore(ScrnInfoPtr pS
        }
     }
 #endif
-    RADEONUnblank(pScrn);
+    RADEONBlank(pScrn, FALSE);
 
 #if 0
     RADEONWaitForVerticalSync(pScrn);
@@ -5910,10 +5894,8 @@ static void RADEONInitDAC2Registers(Scrn
     }
 }
 
-static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, int crtc_num)
+static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, Bool IsPrimary)
 {
-    Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE;
-
     if (pPort->MonType == MT_CRT) {
 	if (pPort->DACType == DAC_PRIMARY) {
 	    RADEONInitDACRegisters(pScrn, save, mode, IsPrimary);
@@ -5921,11 +5903,11 @@ static void RADEONInitOutputRegisters(Sc
 	    RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary);
 	}
     } else if (pPort->MonType == MT_LCD) {
-	if (crtc_num == 1)
+	if (IsPrimary)
 	    RADEONInitRMXRegisters(pScrn, save, mode);
 	RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary);
     } else if (pPort->MonType == MT_DFP) {
-	if (crtc_num == 1)
+	if (IsPrimary)
 	    RADEONInitRMXRegisters(pScrn, save, mode);
 	if (pPort->TMDSType == TMDS_INT) {
 	    RADEONInitFPRegisters(pScrn, save, mode, IsPrimary);
@@ -6095,11 +6077,7 @@ static Bool RADEONInitCrtcRegisters(Scrn
     }
 
     /* get the output connected to this CRTC */
-    if (pRADEONEnt->PortInfo[0]->crtc_num == 1) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 1);
-    } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 1);
-    }
+    RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], TRUE);
 
     if (info->IsDellServer) {
 	save->dac2_cntl = info->SavedReg.dac2_cntl;
@@ -6230,12 +6208,8 @@ static Bool RADEONInitCrtc2Registers(Scr
     save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
 
     /* get the output connected to this CRTC */
-    if (pRADEONEnt->PortInfo[0]->crtc_num == 2) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 2);
-    } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 2);
-    }
-
+    RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], FALSE);
+    
     /* We must set SURFACE_CNTL properly on the second screen too */
     save->surface_cntl = 0;
 #if X_BYTE_ORDER == X_BIG_ENDIAN
@@ -6568,9 +6542,9 @@ static Bool RADEONModeInit(ScrnInfoPtr p
     if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE;
 
     pScrn->vtSema = TRUE;
-    RADEONBlank(pScrn);
+    RADEONBlank(pScrn, TRUE);
     RADEONRestoreMode(pScrn, &info->ModeReg);
-    RADEONUnblank(pScrn);
+    RADEONBlank(pScrn, FALSE);
 
     info->CurrentLayout.mode = mode;
 
@@ -6592,8 +6566,10 @@ static Bool RADEONSaveScreen(ScreenPtr p
     if (unblank) SetTimeSinceLastInputEvent();
 
     if ((pScrn != NULL) && pScrn->vtSema) {
-	if (unblank)  RADEONUnblank(pScrn);
-	else          RADEONBlank(pScrn);
+	if (unblank)
+	    RADEONBlank(pScrn, FALSE);
+	else
+	    RADEONBlank(pScrn, TRUE);
     }
     return TRUE;
 }
@@ -7152,7 +7128,7 @@ static void
 RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
-    RADEONConnector *connector;
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     char        *strptr;
     char	*default_hsync = "28-33";
     char	*default_vrefresh = "43-72";
@@ -7182,12 +7158,10 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 	info->MergedFB = FALSE;
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
         "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n");
-    } else if ((connector = RADEONGetCrtcConnector(pScrn, 2))) {
-	if (!connector->MonInfo) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n");
-	    default_range = TRUE;
-	}
+    } else if (!pRADEONEnt->PortInfo[1]->MonInfo) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n");
+	default_range = TRUE;
     }
 
     if (xf86GetOptValBool(info->Options, OPTION_MERGEDFB, &val)) {
@@ -7352,8 +7326,7 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 
 	  /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */
 
-	  connector = RADEONGetCrtcConnector(pScrn, 2);
-	  info->CRT2pScrn->monitor->DDC = connector ? connector->MonInfo : NULL;
+	  info->CRT2pScrn->monitor->DDC = pRADEONEnt->PortInfo[1]->MonInfo;
 
           if (default_range) {
              RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, default_hsync, MAX_HSYNC);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index dc30e2e..dfec12f 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -119,9 +119,6 @@ typedef struct
     RADEONConnectorType ConnectorType;
     RADEONMonitorType MonType;
     xf86MonPtr MonInfo;
-
-    /* one connector can be bound to one CRTC */
-    int crtc_num;
 } RADEONConnector;
 
 
diff-tree b61a49f2a5401560f85e11bcdd005287433cad12 (from 288fa627274cb399059262d4f8bd844fc220a042)
Author: Alex Deucher <alex at botch2.com>
Date:   Fri Aug 3 19:27:59 2007 -0400

    RADEON: Change indexing of TV constants table in preparation for standard re-work

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index b802234..ec355e2 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -202,7 +202,11 @@ static Bool RADEONInitTVRestarts(xf86Out
     CARD16 hInc;
     const TVModeConstants *constPtr;
 
-    constPtr = &availableTVModes[radeon_output->tvStd];
+    /* FIXME: need to revisit this when we add more modes */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	constPtr = &availableTVModes[0];
+    else
+	constPtr = &availableTVModes[1];
 
     hTotal = constPtr->horTotal;
     vTotal = constPtr->verTotal;
@@ -292,7 +296,12 @@ void RADEONInitTVRegisters(xf86OutputPtr
     const CARD16 *hor_timing;
     const CARD16 *vert_timing;
 
-    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    /* FIXME: need to revisit this when we add more modes */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	constPtr = &availableTVModes[0];
+    else
+	constPtr = &availableTVModes[1];
 
     save->tv_crc_cntl = 0;
 
@@ -536,7 +545,11 @@ void RADEONAdjustCrtcRegistersForTV(Scrn
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    constPtr = &availableTVModes[radeon_output->tvStd];
+    /* FIXME: need to revisit this when we add more modes */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	constPtr = &availableTVModes[0];
+    else
+	constPtr = &availableTVModes[1];
 
     save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
 	(((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
@@ -562,7 +575,11 @@ void RADEONAdjustPLLRegistersForTV(ScrnI
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    constPtr = &availableTVModes[radeon_output->tvStd];
+    /* FIXME: need to revisit this when we add more modes */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	constPtr = &availableTVModes[0];
+    else
+	constPtr = &availableTVModes[1];
 
     save->htotal_cntl = (constPtr->horTotal & 0x7 /*0xf*/) | RADEON_HTOT_CNTL_VGA_EN;
 
@@ -609,7 +626,11 @@ void RADEONAdjustCrtc2RegistersForTV(Scr
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    constPtr = &availableTVModes[radeon_output->tvStd];
+    /* FIXME: need to revisit this when we add more modes */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	constPtr = &availableTVModes[0];
+    else
+	constPtr = &availableTVModes[1];
 
     save->crtc2_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
 	(((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
@@ -635,7 +656,11 @@ void RADEONAdjustPLL2RegistersForTV(Scrn
     const TVModeConstants *constPtr;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    constPtr = &availableTVModes[radeon_output->tvStd];
+    /* FIXME: need to revisit this when we add more modes */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	constPtr = &availableTVModes[0];
+    else
+	constPtr = &availableTVModes[1];
 
     save->htotal_cntl2 = (constPtr->horTotal & 0x7); /* 0xf */
 
diff-tree 288fa627274cb399059262d4f8bd844fc220a042 (from b66a1bc7994b33d349c1519761e431959311c85f)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 2 02:37:16 2007 -0400

    RADEON: avoid a divide by 0 and only save tv out regs if the chip has them

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a7f5831..c1f0c3c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4612,6 +4612,9 @@ static CARD8 RADEONComputePLLGain(CARD16
 {
     unsigned vcoFreq;
 
+    if (!ref_div)
+	return 1;
+
     vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
 
     /*
@@ -5417,6 +5420,8 @@ 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);
 
@@ -5428,7 +5433,8 @@ static void RADEONSaveMode(ScrnInfoPtr p
     RADEONSaveDACRegisters(pScrn, save);
     RADEONSaveCrtc2Registers(pScrn, save);
     RADEONSavePLL2Registers(pScrn, save);
-    RADEONSaveTVRegisters(pScrn, save);
+    if (info->InternalTVOut)
+	RADEONSaveTVRegisters(pScrn, save);
     /*RADEONSavePalette(pScrn, save);*/
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
diff-tree b66a1bc7994b33d349c1519761e431959311c85f (from d86592c8d5ce45d81d8a726c263e870e94fbcf11)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 2 02:11:20 2007 -0400

    RADEON: fix tv-out enable/disable

diff --git a/src/radeon_display.c b/src/radeon_display.c
index bca0ac1..da2b82f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -317,9 +317,8 @@ void RADEONEnableDisplay(xf86OutputPtr o
     RADEONOutputPrivatePtr radeon_output;
     radeon_output = output->driver_private;
 
-    ErrorF("enable montype: %d\n", radeon_output->MonType);
-
     if (bEnable) {
+	ErrorF("enable montype: %d\n", radeon_output->MonType);
         if (radeon_output->MonType == MT_CRT) {
             if (radeon_output->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
@@ -362,20 +361,11 @@ void RADEONEnableDisplay(xf86OutputPtr o
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } else if (radeon_output->MonType == MT_STV ||
 		   radeon_output->MonType == MT_CTV) {
-#if 1
-	    /* TV_MASTER_CNTL ??? */
-
-	    /* XXX: FIXME: STV vs CTV and DACPD bits */
-	    tmp = INREG(RADEON_TV_DAC_CNTL);
-	    tmp |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
-	    tmp &= ~RADEON_TV_DAC_BGSLEEP;
-	    OUTREG(RADEON_TV_DAC_CNTL, tmp);
-	    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
-	    save->tv_dac_cntl &= ~RADEON_TV_DAC_BGSLEEP;
-#endif
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
 	}
     } else {
-        if (radeon_output->MonType == MT_CRT || radeon_output->MonType == NONE) {
+	ErrorF("disable montype: %d\n", radeon_output->MonType);
+        if (radeon_output->MonType == MT_CRT) {
             if (radeon_output->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
                 tmp &= ~RADEON_CRTC_CRT_ON;       
@@ -395,9 +385,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
                 }
             }
 	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
-        }
-
-        if (radeon_output->MonType == MT_DFP || radeon_output->MonType == NONE) {
+        } else if (radeon_output->MonType == MT_DFP) {
             if (radeon_output->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
                 tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
@@ -409,10 +397,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
                 OUTREG(RADEON_FP2_GEN_CNTL, tmp);
                 save->fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
             }
-        }
-
-        if (radeon_output->MonType == MT_LCD || 
-            (radeon_output->MonType == NONE && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
+        } else if (radeon_output->MonType == MT_LCD) {
 	    unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 	    if (info->IsMobility || info->IsIGP) {
 	    /* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -429,21 +414,8 @@ void RADEONEnableDisplay(xf86OutputPtr o
 	    if (info->IsMobility || info->IsIGP) {
 		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 	    }
-        }
-
-	if (radeon_output->MonType == MT_STV ||
-	    radeon_output->MonType == MT_CTV) {
-#if 1
-
-	    /* TV_MASTER_CNTL ??? */
-
-	    tmp = INREG(RADEON_TV_DAC_CNTL);
-	    tmp &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
-	    tmp |= RADEON_TV_DAC_BGSLEEP;
-	    OUTREG(RADEON_TV_DAC_CNTL, tmp);
-	    save->tv_dac_cntl &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
-	    save->tv_dac_cntl |= RADEON_TV_DAC_BGSLEEP;
-#endif
+        } else if (radeon_output->MonType == MT_STV || radeon_output->MonType == MT_CTV) {
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
 	}
     }
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 64abf80..a7f5831 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4541,7 +4541,6 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
     RADEONRestoreTVRestarts(pScrn, restore);
   
     ErrorF("Restore Timing Tables\n");
-
     RADEONRestoreTVTimingTables(pScrn, restore);
   
 
@@ -4554,12 +4553,9 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
 
     OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
 
-    /*OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);*/
-
     OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
     OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
 
-    /* XXX: taken care of in EnableDisplay() */
     OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
 
     ErrorF("Leaving Restore TV\n");
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 38fbcd0..b802234 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -405,17 +405,14 @@ void RADEONInitTVRegisters(xf86OutputPtr
     tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
     save->tv_timing_cntl = tmp;
 
-    /* XXX: taken care of in enabledisplay() */
-    save->tv_dac_cntl = /*RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
-			  |*/ (8 << 16) | (6 << 20);
+    save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD | (8 << 16) | (6 << 20);
 
     if (radeon_output->tvStd == TV_STD_NTSC)
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
     else
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
 
-#if 1
-    /* XXX: taken care of in enabledisplay() */
+#if 0
     save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
 	                 | RADEON_TV_DAC_BDACPD);
 
diff-tree d86592c8d5ce45d81d8a726c263e870e94fbcf11 (from 971feb34843225030fff05b3f9d3801534fbf2d4)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 2 00:50:51 2007 -0400

    RADEON: add missing break

diff --git a/src/radeon_output.c b/src/radeon_output.c
index d3bb344..fa6fb4f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -997,6 +997,7 @@ radeon_mode_set(xf86OutputPtr output, Di
 	if (radeon_crtc->crtc_id == 0)
 	    RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
 	RADEONRestoreLVDSRegisters(pScrn, &info->ModeReg);
+	break;
     case MT_DFP:
 	if (radeon_crtc->crtc_id == 0)
 	    RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
diff-tree 971feb34843225030fff05b3f9d3801534fbf2d4 (from 98d7e00437bea78e03180eb30ff30de3455d9d1a)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 2 00:50:04 2007 -0400

    RADEON: move tv dac enable to enabledisplay()

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 059dfca..bca0ac1 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -362,18 +362,16 @@ void RADEONEnableDisplay(xf86OutputPtr o
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } else if (radeon_output->MonType == MT_STV ||
 		   radeon_output->MonType == MT_CTV) {
-#if 0
+#if 1
 	    /* TV_MASTER_CNTL ??? */
 
 	    /* XXX: FIXME: STV vs CTV and DACPD bits */
 	    tmp = INREG(RADEON_TV_DAC_CNTL);
-	    tmp |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
-	    tmp &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
-		     | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+	    tmp |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+	    tmp &= ~RADEON_TV_DAC_BGSLEEP;
 	    OUTREG(RADEON_TV_DAC_CNTL, tmp);
-	    save->tv_dac_cntl |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
-	    save->tv_dac_cntl &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
-				   | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+	    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+	    save->tv_dac_cntl &= ~RADEON_TV_DAC_BGSLEEP;
 #endif
 	}
     } else {
@@ -435,15 +433,16 @@ void RADEONEnableDisplay(xf86OutputPtr o
 
 	if (radeon_output->MonType == MT_STV ||
 	    radeon_output->MonType == MT_CTV) {
+#if 1
 
 	    /* TV_MASTER_CNTL ??? */
-#if 0
+
 	    tmp = INREG(RADEON_TV_DAC_CNTL);
-	    tmp &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
-	    tmp |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+	    tmp &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+	    tmp |= RADEON_TV_DAC_BGSLEEP;
 	    OUTREG(RADEON_TV_DAC_CNTL, tmp);
-	    save->tv_dac_cntl &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
-	    save->tv_dac_cntl |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+	    save->tv_dac_cntl &= ~(RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD);
+	    save->tv_dac_cntl |= RADEON_TV_DAC_BGSLEEP;
 #endif
 	}
     }
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index e4e6763..38fbcd0 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -406,8 +406,8 @@ void RADEONInitTVRegisters(xf86OutputPtr
     save->tv_timing_cntl = tmp;
 
     /* XXX: taken care of in enabledisplay() */
-    save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
-	                | (8 << 16) | (6 << 20);
+    save->tv_dac_cntl = /*RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
+			  |*/ (8 << 16) | (6 << 20);
 
     if (radeon_output->tvStd == TV_STD_NTSC)
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
diff-tree 98d7e00437bea78e03180eb30ff30de3455d9d1a (from 5c549c1d42f7bbc556942af13aff2661fae856f2)
Author: Alex Deucher <alex at botch2.com>
Date:   Thu Aug 2 00:20:50 2007 -0400

    RADEON: limit tv modes to the only one we can program at the moment

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 2790ddf..d3bb344 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -609,6 +609,14 @@ radeon_mode_valid(xf86OutputPtr output, 
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
+    if (radeon_output->type == OUTPUT_STV ||
+	radeon_output->type == OUTPUT_CTV) {
+	if (pMode->HDisplay == 800 && pMode->VDisplay == 600)
+	    return MODE_OK;
+	else
+	    return MODE_CLOCK_RANGE;
+    }
+
     if (radeon_output->type != OUTPUT_LVDS)
 	return MODE_OK;
 
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 001d013..e4e6763 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -141,7 +141,7 @@ static const CARD16 vert_timing_PAL[] =
  **********************************************************************/
 static const TVModeConstants availableTVModes[] =
 {
-    { 
+    {
 	800,                /* horResolution */
 	600,                /* verResolution */
 	TV_STD_NTSC,        /* standard */
@@ -156,7 +156,7 @@ static const TVModeConstants availableTV
 	4,                  /* crtcPLL_postDiv */
 	1022,               /* pixToTV */
     },
-    { 
+    {
 	800,               /* horResolution */
 	600,               /* verResolution */
 	TV_STD_PAL,        /* standard */
diff-tree 5c549c1d42f7bbc556942af13aff2661fae856f2 (from b03978028fd975eb6946503d3a56a49c5a67f339)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Aug 1 23:45:07 2007 -0400

    RADEON: remove unused elements

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index b700b1e..001d013 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -46,11 +46,8 @@ typedef struct
     unsigned defRestart;
     CARD16 crtcPLL_N;
     CARD8  crtcPLL_M;
-    Bool   crtcPLL_divBy2;
-    CARD8  crtcPLL_byteClkDiv;
     CARD8  crtcPLL_postDiv;
     unsigned pixToTV;
-    CARD8  byteClkDelay;
 } TVModeConstants;
 
 static const CARD16 hor_timing_NTSC[] =
@@ -156,11 +153,8 @@ static const TVModeConstants availableTV
 	625592,             /* defRestart */
 	592,                /* crtcPLL_N */
 	91,                 /* crtcPLL_M */
-	TRUE,               /* crtcPLL_divBy2 */
-	0,                  /* crtcPLL_byteClkDiv */
 	4,                  /* crtcPLL_postDiv */
 	1022,               /* pixToTV */
-	1,                  /* byteClkDelay */
     },
     { 
 	800,               /* horResolution */
@@ -174,11 +168,8 @@ static const TVModeConstants availableTV
 	696700,            /* defRestart */
 	1382,              /* crtcPLL_N */
 	231,               /* crtcPLL_M */
-	TRUE,              /* crtcPLL_divBy2 */
-	0,                 /* crtcPLL_byteClkDiv */
 	4,                 /* crtcPLL_postDiv */
 	759,               /* pixToTV */
-	1,                 /* byteClkDelay */
     }
 };
 
diff-tree b03978028fd975eb6946503d3a56a49c5a67f339 (from cf54222f1fa37366b2c2b39c82f8afc02f32e63c)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Aug 1 22:39:16 2007 -0400

    RADEON: convert hard coded tv out values to calculations

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 7c5bef4..64abf80 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4311,7 +4311,7 @@ static void RADEONWriteTVFIFO(ScrnInfoPt
 	    break;
 	i++;
     }
-    while (i < 100000);
+    while (i < 10000);
     /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
 
     OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
@@ -4334,7 +4334,7 @@ static CARD32 RADEONReadTVFIFO(ScrnInfoP
 	    break;
 	i++;
     }
-    while (i < 100000);
+    while (i < 10000);
     /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
 
     OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
@@ -4353,15 +4353,12 @@ static CARD16 RADEONGetHTimingTablesAddr
     case 0:
 	hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
 	break;
-
     case 1:
 	hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
 	break;
-
     case 2:
 	hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
 	break;
-
     default:
 	/* Of course, this should never happen */
 	hTable = 0;
@@ -4378,15 +4375,12 @@ static CARD16 RADEONGetVTimingTablesAddr
     case 0:
 	vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
 	break;
-
     case 1:
 	vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
 	break;
-
     case 2:
 	vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
 	break;
-
     default:
 	/* Of course, this should never happen */
 	vTable = 0;
@@ -5359,7 +5353,7 @@ static void RADEONSaveTVRegisters(ScrnIn
 
     ErrorF("Save TV timing tables\n");
 
-    RADEONSaveTimingTables(pScrn, save);
+    RADEONSaveTVTimingTables(pScrn, save);
 
     ErrorF("TV Save done\n");
 }
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 2a9daf3..b700b1e 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -44,25 +44,16 @@ typedef struct
     CARD16 horSyncStart;
     CARD16 verSyncStart;
     unsigned defRestart;
-    CARD32 vScalerCntl1;
-    CARD32 yRiseCntl;
-    CARD32 ySawtoothCntl;
     CARD16 crtcPLL_N;
     CARD8  crtcPLL_M;
     Bool   crtcPLL_divBy2;
     CARD8  crtcPLL_byteClkDiv;
     CARD8  crtcPLL_postDiv;
-    Bool   use888RGB; /* False: RGB data is 565 packed (2 bytes/pixel) */
-                      /* True : RGB data is 888 packed (3 bytes/pixel) */
     unsigned pixToTV;
     CARD8  byteClkDelay;
-    CARD32 tvoDataDelayA;
-    CARD32 tvoDataDelayB;
-    const CARD16 *horTimingTable;
-    const CARD16 *verTimingTable;
 } TVModeConstants;
 
-static const CARD16 horTimingNTSC_BIOS[] =
+static const CARD16 hor_timing_NTSC[] =
 {
     0x0007,
     0x003f,
@@ -84,7 +75,7 @@ static const CARD16 horTimingNTSC_BIOS[]
     0
 };
 
-static const CARD16 verTimingNTSC_BIOS[] =
+static const CARD16 vert_timing_NTSC[] =
 {
     0x2001,
     0x200d,
@@ -102,7 +93,7 @@ static const CARD16 verTimingNTSC_BIOS[]
     0
 };
 
-static const CARD16 horTimingPAL_BIOS[] =
+static const CARD16 hor_timing_PAL[] =
 {
     0x0007,
     0x0058,
@@ -124,7 +115,7 @@ static const CARD16 horTimingPAL_BIOS[] 
     0
 };
 
-static const CARD16 verTimingPAL_BIOS[] =
+static const CARD16 vert_timing_PAL[] =
 {
     0x2001,
     0x200c,
@@ -163,21 +154,13 @@ static const TVModeConstants availableTV
 	824,                /* horSyncStart */
 	632,                /* verSyncStart */
 	625592,             /* defRestart */
-	0x0900b46b,         /* vScalerCntl1 */
-	0x00012c00,         /* yRiseCntl */
-	0x10002d1a,         /* ySawtoothCntl */
 	592,                /* crtcPLL_N */
 	91,                 /* crtcPLL_M */
 	TRUE,               /* crtcPLL_divBy2 */
 	0,                  /* crtcPLL_byteClkDiv */
 	4,                  /* crtcPLL_postDiv */
-	FALSE,              /* use888RGB */
 	1022,               /* pixToTV */
 	1,                  /* byteClkDelay */
-	0x0a0b0907,         /* tvoDataDelayA */
-	0x060a090a,         /* tvoDataDelayB */
-	horTimingNTSC_BIOS, /* horTimingTable */
-	verTimingNTSC_BIOS  /* verTimingTable */
     },
     { 
 	800,               /* horResolution */
@@ -189,26 +172,23 @@ static const TVModeConstants availableTV
 	824,               /* horSyncStart */
 	669,               /* verSyncStart */
 	696700,            /* defRestart */
-	0x09009097,        /* vScalerCntl1 */
-	0x000007da,        /* yRiseCntl */
-	0x10002426,        /* ySawtoothCntl */
 	1382,              /* crtcPLL_N */
 	231,               /* crtcPLL_M */
 	TRUE,              /* crtcPLL_divBy2 */
 	0,                 /* crtcPLL_byteClkDiv */
 	4,                 /* crtcPLL_postDiv */
-	FALSE,             /* use888RGB */
 	759,               /* pixToTV */
 	1,                 /* byteClkDelay */
-	0x0a0b0907,        /* tvoDataDelayA */
-	0x060a090a,        /* tvoDataDelayB */
-	horTimingPAL_BIOS, /* horTimingTable */
-	verTimingPAL_BIOS  /* verTimingTable */
     }
 };
 
 #define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 0 ]))
 
+static long YCOEF_value[5] = { 2, 2, 0, 4, 0 };
+static long YCOEF_EN_value[5] = { 1, 1, 0, 1, 0 };
+static long SLOPE_value[5] = { 1, 2, 2, 4, 8 };
+static long SLOPE_limit[5] = { 6, 5, 4, 3, 2 };
+
 
 /* Compute F,V,H restarts from default restart position and hPos & vPos
  * Return TRUE when code timing table was changed
@@ -241,13 +221,17 @@ static Bool RADEONInitTVRestarts(xf86Out
     else
 	fTotal = PAL_TV_VFTOTAL + 1;
 
-    /*
-     * Adjust positions 1&2 in hor. code timing table
-     */
+    /* Adjust positions 1&2 in hor. code timing table */
     hOffset = radeon_output->hPos * H_POS_UNIT;
 
-    p1 = constPtr->horTimingTable[ H_TABLE_POS1 ];
-    p2 = constPtr->horTimingTable[ H_TABLE_POS2 ];
+    if (radeon_output->tvStd == TV_STD_NTSC) {
+	p1 = hor_timing_NTSC[ H_TABLE_POS1 ];
+	p2 = hor_timing_NTSC[ H_TABLE_POS2 ];
+    } else {
+	p1 = hor_timing_PAL[ H_TABLE_POS1 ];
+	p2 = hor_timing_PAL[ H_TABLE_POS2 ];
+    }
+
 
     p1 = (CARD16)((int)p1 + hOffset);
     p2 = (CARD16)((int)p2 - hOffset);
@@ -311,8 +295,11 @@ void RADEONInitTVRegisters(xf86OutputPtr
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     unsigned i;
+    unsigned long vert_space, flicker_removal;
     CARD32 tmp;
     const TVModeConstants *constPtr;
+    const CARD16 *hor_timing;
+    const CARD16 *vert_timing;
 
     constPtr = &availableTVModes[radeon_output->tvStd];
 
@@ -361,7 +348,8 @@ void RADEONInitTVRegisters(xf86OutputPtr
 				 | RADEON_CMP_BLU_EN
 				 | RADEON_DAC_DITHER_EN);
 
-    save->tv_rgb_cntl = 0x007b0004;
+    save->tv_rgb_cntl = (RADEON_RGB_DITHER_EN | RADEON_TVOUT_SCALE_EN
+			 | (0x0b << 16) | (0x07 << 20));
 
     if (IsPrimary) {
 	if (radeon_output->Flags & RADEON_USE_RMX)
@@ -375,14 +363,59 @@ void RADEONInitTVRegisters(xf86OutputPtr
     save->tv_sync_cntl = RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE;
 
     save->tv_sync_size = constPtr->horResolution + 8;
-  
-    tmp = (constPtr->vScalerCntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	vert_space = constPtr->verTotal * 2 * 10000 / NTSC_TV_LINES_PER_FRAME;
+    else
+	vert_space = constPtr->verTotal * 2 * 10000 / PAL_TV_LINES_PER_FRAME;
+
+    save->tv_vscaler_cntl1 = RADEON_Y_W_EN;
+    save->tv_vscaler_cntl1 =
+	(save->tv_vscaler_cntl1 & 0xe3ff0000) | (vert_space * (1 << FRAC_BITS) / 10000);
+    save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
+    if (constPtr->horResolution == 1024)
+	save->tv_vscaler_cntl1 |= (4 << RADEON_Y_DEL_W_SIG_SHIFT);
+    else
+	save->tv_vscaler_cntl1 |= (2 << RADEON_Y_DEL_W_SIG_SHIFT);
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	flicker_removal =
+	    (float) constPtr->verTotal * 2.0 / NTSC_TV_LINES_PER_FRAME + 0.5;
+    else
+	flicker_removal =
+	    (float) constPtr->verTotal * 2.0 / PAL_TV_LINES_PER_FRAME + 0.5;
+
+    if (flicker_removal < 3)
+	flicker_removal = 3;
+    for (i = 0; i < 6; ++i) {
+	if (flicker_removal == SLOPE_limit[i])
+	    break;
+    }
+    save->tv_y_saw_tooth_cntl =
+	(vert_space * SLOPE_value[i] * (1 << (FRAC_BITS - 1)) + 5001) / 10000 / 8
+	| ((SLOPE_value[i] * (1 << (FRAC_BITS - 1)) / 8) << 16);
+    save->tv_y_fall_cntl =
+	(YCOEF_EN_value[i] << 17) | ((YCOEF_value[i] * (1 << 8) / 8) << 24) |
+	RADEON_Y_FALL_PING_PONG | (272 * SLOPE_value[i] / 8) * (1 << (FRAC_BITS - 1)) /
+	1024;
+    save->tv_y_rise_cntl =
+	RADEON_Y_RISE_PING_PONG
+	| (flicker_removal * 1024 - 272) * SLOPE_value[i] / 8 * (1 << (FRAC_BITS - 1)) / 1024;
+
+    save->tv_vscaler_cntl2 = ((save->tv_vscaler_cntl2 & 0x00fffff0)
+			      | (0x10 << 24)
+			      | RADEON_DITHER_MODE 
+			      | RADEON_Y_OUTPUT_DITHER_EN
+			      | RADEON_UV_OUTPUT_DITHER_EN
+			      | RADEON_UV_TO_BUF_DITHER_EN);
+
+    tmp = (save->tv_vscaler_cntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
     tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
     tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
     save->tv_timing_cntl = tmp;
 
+    /* XXX: taken care of in enabledisplay() */
     save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
-	                | RADEON_TV_MONITOR_DETECT_EN
 	                | (8 << 16) | (6 << 20);
 
     if (radeon_output->tvStd == TV_STD_NTSC)
@@ -390,15 +423,16 @@ void RADEONInitTVRegisters(xf86OutputPtr
     else
 	save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
 
-#if 0
+#if 1
+    /* XXX: taken care of in enabledisplay() */
     save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
 	                 | RADEON_TV_DAC_BDACPD);
 
-    if (MonType == MT_CTV) {
+    if (radeon_output->MonType == MT_CTV) {
 	save->tv_dac_cntl &= ~RADEON_TV_DAC_BDACPD;
     }
 
-    if (MonType == MT_STV) {
+    if (radeon_output->MonType == MT_STV) {
 	save->tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
 			       RADEON_TV_DAC_GDACPD);
     }
@@ -428,26 +462,23 @@ void RADEONInitTVRegisters(xf86OutputPtr
     else
 	save->tv_ftotal = PAL_TV_VFTOTAL;
 
-    save->tv_vscaler_cntl1 = constPtr->vScalerCntl1;
-    save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
-
-    save->tv_vscaler_cntl2 = 0x10000000;
-
     save->tv_vtotal = constPtr->verTotal - 1;
 
-    save->tv_y_fall_cntl = RADEON_Y_FALL_PING_PONG | RADEON_Y_COEF_EN;
-    save->tv_y_fall_cntl |= 0x80000400;
-
-    save->tv_y_rise_cntl = constPtr->yRiseCntl;
-    save->tv_y_saw_tooth_cntl = constPtr->ySawtoothCntl;
+    if (radeon_output->tvStd == TV_STD_NTSC) {
+	hor_timing = hor_timing_NTSC;
+	vert_timing = vert_timing_NTSC;
+    } else {
+	hor_timing = hor_timing_PAL;
+	vert_timing = vert_timing_PAL;
+    }
 
     for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
-	if ((save->h_code_timing[ i ] = constPtr->horTimingTable[ i ]) == 0)
+	if ((save->h_code_timing[ i ] = hor_timing[ i ]) == 0)
 	    break;
     }
 
     for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
-	if ((save->v_code_timing[ i ] = constPtr->verTimingTable[ i ]) == 0)
+	if ((save->v_code_timing[ i ] = vert_timing[ i ]) == 0)
 	    break;
     }
 
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
index 829efba..5c8c8c9 100644
--- a/src/radeon_tv.h
+++ b/src/radeon_tv.h
@@ -49,3 +49,8 @@
 #define PAL_TV_LINES_PER_FRAME 625
 #define PAL_TV_ZERO_H_SIZE 473200
 #define PAL_TV_H_SIZE_UNIT 9360
+
+
+#define VERT_LEAD_IN_LINES 2
+#define FRAC_BITS 0xe
+#define FRAC_MASK 0x3fff
diff-tree cf54222f1fa37366b2c2b39c82f8afc02f32e63c (from 22d460d3ad991223aa1fbd7e5edeb45e36c65dc0)
Author: Alex Deucher <alex at botch2.com>
Date:   Tue Jul 31 02:01:49 2007 -0400

    RADEON: more fixes...

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 20d43ff..7c5bef4 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4409,14 +4409,14 @@ static void RADEONRestoreTVTimingTables(
     hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
     vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
 
-    /*    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
 				   | RADEON_CRT_ASYNC_RST
 				   | RADEON_RESTART_PHASE_FIX
 				   | RADEON_CRT_FIFO_CE_EN
 				   | RADEON_TV_FIFO_CE_EN
-				   | RADEON_TV_ON));*/
+				   | RADEON_TV_ON));
 
-    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
+    /*OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);*/
 
     for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
 	tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
@@ -4509,20 +4509,6 @@ static void RADEONRestoreTVOutputStd(Scr
     OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
 }
 
-/* Test if tv output would be enabled with a given value in TV_DAC_CNTL */
-static Bool RADEONTVIsOn(CARD32 tv_dac_cntl)
-{
-    /* XXX: Fixme for STV vs. CTV */
-    if (tv_dac_cntl & RADEON_TV_DAC_BGSLEEP)
-	return FALSE;
-    else if ((tv_dac_cntl &
-	      (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD)) ==
-	     (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD))
-	return FALSE;
-    else
-	return TRUE;
-}
-
 /* Restore TV out regs */
 void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
@@ -4562,9 +4548,7 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
   
     ErrorF("Restore Timing Tables\n");
 
-    /* Timing tables are only restored when tv output is active */
-    if (RADEONTVIsOn(restore->tv_dac_cntl))
-	RADEONRestoreTVTimingTables(pScrn, restore);
+    RADEONRestoreTVTimingTables(pScrn, restore);
   
 
     OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
@@ -5304,7 +5288,15 @@ static void RADEONSaveTVTimingTables(Scr
     /*
      * Reset FIFO arbiter in order to be able to access FIFO RAM
      */
-    OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST
+				   | RADEON_RESTART_PHASE_FIX
+				   | RADEON_CRT_FIFO_CE_EN
+				   | RADEON_TV_FIFO_CE_EN
+				   | RADEON_TV_ON));
+
+    /*OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);*/
 
     ErrorF("saveTimingTables: reading timing tables\n");
 
@@ -5364,14 +5356,10 @@ static void RADEONSaveTVRegisters(ScrnIn
     save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
 
     save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
-      
-    /*
-     * Read H/V code timing tables (current tables only are saved)
-     * This step is skipped when tv output is disabled in current RT state
-     * (see RADEONRestoreTVRegisters)
-     */
-    if (RADEONTVIsOn(save->tv_dac_cntl))
-	RADEONSaveTimingTables(pScrn, save);
+
+    ErrorF("Save TV timing tables\n");
+
+    RADEONSaveTimingTables(pScrn, save);
 
     ErrorF("TV Save done\n");
 }
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index a0e680b..2a9daf3 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -456,8 +456,6 @@ void RADEONInitTVRegisters(xf86OutputPtr
      */
     RADEONInitTVRestarts(output, save, mode);
 
-    /*save->hw_debug = 0x00000200;*/
-
     save->dac_cntl &= ~RADEON_DAC_TVO_EN;
 
     if (IS_R300_VARIANT)
diff-tree 22d460d3ad991223aa1fbd7e5edeb45e36c65dc0 (from 4822a2b837334f408f962646ab5ea4f8b0335ac9)
Author: Alex Deucher <alex at botch2.com>
Date:   Tue Jul 31 01:28:05 2007 -0400

    RADEON: fix name of tv output

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 9c11bf6..2790ddf 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1297,9 +1297,9 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
 	case CONNECTOR_DVI_D:
 	    output = OUTPUT_DVI; break;
 	case CONNECTOR_CTV:
-	    output = OUTPUT_STV; break;
-	case CONNECTOR_STV:
 	    output = OUTPUT_CTV; break;
+	case CONNECTOR_STV:
+	    output = OUTPUT_STV; break;
 	case CONNECTOR_NONE:
 	case CONNECTOR_UNSUPPORTED:
 	default:
diff-tree 4822a2b837334f408f962646ab5ea4f8b0335ac9 (from fe494c9db2995bb8ce7a028ecf9626e0cb0cf506)
Author: Alex Deucher <alex at botch2.com>
Date:   Tue Jul 31 01:18:40 2007 -0400

    RADEON: tv-out fixes.  works now.  tested on rv350.
    
    VT siwtch is busted, and xrandr doesn't play nice yet.
    uncomment code in radeon_output.c to test.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 74711ce..20d43ff 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4298,7 +4298,7 @@ static void RADEONWriteTVFIFO(ScrnInfoPt
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 tmp;
-
+    int i = 0;
 
     OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
 
@@ -4307,26 +4307,35 @@ static void RADEONWriteTVFIFO(ScrnInfoPt
 
     do {
 	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+	if ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0)
+	    break;
+	i++;
     }
-    while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);
+    while (i < 100000);
+    /*while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);*/
 
     OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
 }
 
-/* Read from RT FIFO RAM */
+/* Read from TV FIFO RAM */
 static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 tmp;
+    int i = 0;
   
     OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
     OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
 
     do {
 	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
-    } 
-    while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);
+	if ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0)
+	    break;
+	i++;
+    }
+    while (i < 100000);
+    /*while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);*/
 
     OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
 
@@ -4400,12 +4409,14 @@ static void RADEONRestoreTVTimingTables(
     hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
     vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
 
-    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+    /*    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
 				   | RADEON_CRT_ASYNC_RST
 				   | RADEON_RESTART_PHASE_FIX
 				   | RADEON_CRT_FIFO_CE_EN
 				   | RADEON_TV_FIFO_CE_EN
-				   | RADEON_TV_ON));
+				   | RADEON_TV_ON));*/
+
+    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
 
     for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
 	tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
@@ -4416,7 +4427,7 @@ static void RADEONRestoreTVTimingTables(
 
     for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
 	tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
-	RADEONWriteFIFO(pScrn, vTable, tmp);
+	RADEONWriteTVFIFO(pScrn, vTable, tmp);
 	if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
 	    break;
     }
@@ -4553,7 +4564,7 @@ void RADEONRestoreTVRegisters(ScrnInfoPt
 
     /* Timing tables are only restored when tv output is active */
     if (RADEONTVIsOn(restore->tv_dac_cntl))
-	RADEONRestoreTimingTables(pScrn, restore);
+	RADEONRestoreTVTimingTables(pScrn, restore);
   
 
     OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
diff --git a/src/radeon_output.c b/src/radeon_output.c
index d0a12dd..9c11bf6 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1025,9 +1025,16 @@ radeon_detect(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    
-    radeon_output->MonType = MT_UNKNOWN;
-    RADEONConnectorFindMonitor(pScrn, output);
+
+    /* assume tv is connected for now */
+    if (radeon_output->type == OUTPUT_STV) {
+	radeon_output->MonType = MT_STV;
+    } else if (radeon_output->type == OUTPUT_CTV) {
+	radeon_output->MonType = MT_CTV;
+    } else {
+	radeon_output->MonType = MT_UNKNOWN;
+	RADEONConnectorFindMonitor(pScrn, output);
+    }
 
     /* force montype based on output property */
     if (radeon_output->type == OUTPUT_DVI) {
@@ -1888,6 +1895,45 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    }
 	}
     }
+
+    /* add TV out */
+#if 0
+    if (info->InternalTVOut) {
+	/* need to check the bios tables to see if we really have tv out and what type we have */
+	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+	if (!radeon_output) {
+	    return FALSE;
+	}
+	/* hard code type for now */
+	radeon_output->MonType = MT_STV;
+	radeon_output->DDCType = DDC_NONE_DETECTED;
+	radeon_output->DACType = DAC_TVDAC;
+	radeon_output->TMDSType = TMDS_NONE;
+
+	/* hard code type for now */
+	if (info->IsAtomBios)
+	    radeon_output->ConnectorType = CONNECTOR_STV_ATOM;
+	else
+	    radeon_output->ConnectorType = CONNECTOR_STV;
+
+	radeon_output->tvStd = TV_STD_NTSC;
+	radeon_output->hPos = 0;
+	radeon_output->vPos = 0;
+	radeon_output->hSize = 0;
+
+	RADEONSetOutputType(pScrn, radeon_output);
+	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	if (!output) {
+	    return FALSE;
+	}
+	output->driver_private = radeon_output;
+	output->possible_crtcs = 1 | 2;
+	output->possible_clones = 0;
+
+	RADEONInitConnector(output);
+    }
+#endif
+
     return TRUE;
 }
 
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 5acc4ff..a0e680b 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -333,7 +333,8 @@ void RADEONInitTVRegisters(xf86OutputPtr
 			    | RADEON_AUD_ASYNC_RST
 			    | RADEON_DVS_ASYNC_RST
 			    | RADEON_CRT_FIFO_CE_EN
-			    | RADEON_TV_FIFO_CE_EN);
+			    | RADEON_TV_FIFO_CE_EN
+			    | RADEON_TV_ON);
 
     save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
 	                       | RADEON_SYNC_TIP_LEVEL
diff-tree fe494c9db2995bb8ce7a028ecf9626e0cb0cf506 (from 6b9b7a7bdc290d07de9b226691ec8025af8db896)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Jul 29 15:26:34 2007 -0400

    RADEON: add info about tv out code and authorship

diff --git a/src/radeon_tv.c b/src/radeon_tv.c
index 1d0b2c6..5acc4ff 100644
--- a/src/radeon_tv.c
+++ b/src/radeon_tv.c
@@ -1,3 +1,7 @@
+/*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi at lycos.com>
+ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
index 179b87b..829efba 100644
--- a/src/radeon_tv.h
+++ b/src/radeon_tv.h
@@ -1,4 +1,9 @@
 /*
+ * Integrated TV out support based on the GATOS code by
+ * Federico Ulivi <fulivi at lycos.com>
+ */
+
+/*
  * Maximum length of horizontal/vertical code timing tables for state storage
  */
 #define MAX_H_CODE_TIMING_LEN 32
diff-tree 6b9b7a7bdc290d07de9b226691ec8025af8db896 (from 8d043db1817d94edeb72ab208dfea60026715d48)
Author: Alex Deucher <alex at botch2.com>
Date:   Sun Jul 29 15:23:14 2007 -0400

    RADEON: Initial pass at integrated tv out support
    
    Based on the GATOS tv-out support by Federico Ulivi <fulivi at lycos.com>
    and information from ati with substantial rework by myself.
    
    Code is not actually hooked up yet.

diff --git a/src/Makefile.am b/src/Makefile.am
index 24665a4..709b98c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,7 +80,7 @@ radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
-	radeon_crtc.c radeon_output.c radeon_modes.c \
+	radeon_crtc.c radeon_output.c radeon_modes.c radeon_tv.c \
 	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
@@ -181,6 +181,7 @@ EXTRA_DIST = \
 	radeon_sarea.h \
 	radeon_version.h \
 	radeon_video.h \
+	radeon_tv.h \
 	theatre200.h \
 	theatre_detect.h \
 	theatre.h \
diff --git a/src/radeon.h b/src/radeon.h
index 96c4632..7792f31 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -65,6 +65,8 @@
 #include "xf86xv.h"
 
 #include "radeon_probe.h"
+#include "radeon_tv.h"
+
 				/* DRI support */
 #ifdef XF86DRI
 #define _XF86DRI_SERVER_
@@ -300,12 +302,54 @@ typedef struct {
     CARD32            palette[256];
     CARD32            palette2[256];
 
-    CARD32            tv_dac_cntl;
-
     CARD32            rs480_unk_e30;
     CARD32            rs480_unk_e34;
     CARD32            rs480_unk_e38;
     CARD32            rs480_unk_e3c;
+
+    /* TV out registers */
+    CARD32 	      tv_master_cntl;
+    CARD32 	      tv_htotal;
+    CARD32 	      tv_hsize;
+    CARD32 	      tv_hdisp;
+    CARD32 	      tv_hstart;
+    CARD32 	      tv_vtotal;
+    CARD32 	      tv_vdisp;
+    CARD32 	      tv_timing_cntl;
+    CARD32 	      tv_vscaler_cntl1;
+    CARD32 	      tv_vscaler_cntl2;
+    CARD32 	      tv_sync_size;
+    CARD32 	      tv_vrestart;
+    CARD32 	      tv_hrestart;
+    CARD32 	      tv_frestart;
+    CARD32 	      tv_ftotal;
+    CARD32 	      tv_clock_sel_cntl;
+    CARD32 	      tv_clkout_cntl;
+    CARD32 	      tv_data_delay_a;
+    CARD32 	      tv_data_delay_b;
+    CARD32 	      tv_dac_cntl;
+    CARD32 	      tv_pll_cntl;
+    CARD32	      tv_pll_fine_cntl;
+    CARD32 	      tv_modulator_cntl1;
+    CARD32 	      tv_modulator_cntl2;
+    CARD32 	      tv_frame_lock_cntl;
+    CARD32 	      tv_pre_dac_mux_cntl;
+    CARD32 	      tv_rgb_cntl;
+    CARD32 	      tv_y_saw_tooth_cntl;
+    CARD32 	      tv_y_rise_cntl;
+    CARD32 	      tv_y_fall_cntl;
+    CARD32 	      tv_uv_adr;
+    CARD32	      tv_upsamp_and_gain_cntl;
+    CARD32	      tv_gain_limit_settings;
+    CARD32	      tv_linear_gain_settings;
+    CARD32	      tv_crc_cntl;
+    CARD32            tv_sync_cntl;
+    CARD32	      gpiopad_a;
+    CARD32            pll_test_cntl;
+
+    CARD16	      h_code_timing[MAX_H_CODE_TIMING_LEN];
+    CARD16	      v_code_timing[MAX_V_CODE_TIMING_LEN];
+
 } RADEONSaveRec, *RADEONSavePtr;
 
 typedef struct {
@@ -752,6 +796,8 @@ typedef struct {
     Bool              crtc_on;
     Bool              crtc2_on;
 
+    Bool              InternalTVOut;
+
     Rotation rotation;
     void (*PointerMoved)(int, int, int);
     CreateScreenResourcesProcPtr CreateScreenResources;
@@ -903,6 +949,17 @@ RADEONEnableOutputs(ScrnInfoPtr pScrn, i
 void
 RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox);
 
+extern void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+					   DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+					  DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+					   DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+					  DisplayModePtr mode, xf86OutputPtr output);
+extern void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
+                                  DisplayModePtr mode, BOOL IsPrimary);
+
 #ifdef XF86DRI
 #ifdef USE_XAA
 extern void        RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 3518c9c..cbb50d8 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -753,6 +753,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     ScrnInfoPtr pScrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    xf86OutputPtr output;
+    RADEONOutputPrivatePtr radeon_output;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONMonitorType montype = MT_NONE;
     Bool           tilingOld   = info->tilingEnabled;
@@ -775,8 +777,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     }
 
     for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+	output = xf86_config->output[i];
+	radeon_output = output->driver_private;
 
 	if (output->crtc == crtc) {
 	    montype = radeon_output->MonType;
@@ -816,7 +818,20 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
         }
 	break;
     }
-    
+
+    if (montype == MT_STV || montype == MT_CTV) {
+	switch (radeon_crtc->crtc_id) {
+	case 0:
+	    RADEONAdjustCrtcRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+	    RADEONAdjustPLLRegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+	    break;
+	case 1:
+	    RADEONAdjustCrtc2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+	    RADEONAdjustPLL2RegistersForTV(pScrn, &info->ModeReg, adjusted_mode, output);
+	    break;
+	}
+    }
+
     ErrorF("restore memmap\n");
     RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
     ErrorF("restore common\n");
@@ -837,6 +852,10 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	break;
     }
 
+    /* pixclks_cntl handles tv-out clock routing */
+    if (montype == MT_STV || montype == MT_CTV)
+	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
+
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
 
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 79fb352..059dfca 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -360,12 +360,27 @@ void RADEONEnableDisplay(xf86OutputPtr o
             OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
             save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
-        } 
+        } else if (radeon_output->MonType == MT_STV ||
+		   radeon_output->MonType == MT_CTV) {
+#if 0
+	    /* TV_MASTER_CNTL ??? */
+
+	    /* XXX: FIXME: STV vs CTV and DACPD bits */
+	    tmp = INREG(RADEON_TV_DAC_CNTL);
+	    tmp |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+	    tmp &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
+		     | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+	    OUTREG(RADEON_TV_DAC_CNTL, tmp);
+	    save->tv_dac_cntl |= (TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+	    save->tv_dac_cntl &= ~(TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD
+				   | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+#endif
+	}
     } else {
         if (radeon_output->MonType == MT_CRT || radeon_output->MonType == NONE) {
             if (radeon_output->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
-                tmp &= ~RADEON_CRTC_CRT_ON;                    
+                tmp &= ~RADEON_CRTC_CRT_ON;       
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
             } else if (radeon_output->DACType == DAC_TVDAC) {
@@ -417,6 +432,20 @@ void RADEONEnableDisplay(xf86OutputPtr o
 		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 	    }
         }
+
+	if (radeon_output->MonType == MT_STV ||
+	    radeon_output->MonType == MT_CTV) {
+
+	    /* TV_MASTER_CNTL ??? */
+#if 0
+	    tmp = INREG(RADEON_TV_DAC_CNTL);
+	    tmp &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+	    tmp |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+	    OUTREG(RADEON_TV_DAC_CNTL, tmp);
+	    save->tv_dac_cntl &= ~(TV_DAC_CNTL_NBLANK | TV_DAC_CNTL_NHOLD);
+	    save->tv_dac_cntl |= (TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD | TV_DAC_CNTL_BDACPD);
+#endif
+	}
     }
 }
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e9a0954..74711ce 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -128,9 +128,9 @@ static void RADEONAdjustMemMapRegisters(
 
 DisplayModePtr
 RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
-/* psuedo xinerama support */
 
-extern Bool 		RADEONnoPanoramiXExtension;
+static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+                              unsigned nWaitLoops, unsigned cntThreshold);
 
 static const OptionInfoRec RADEONOptions[] = {
     { OPTION_NOACCEL,        "NoAccel",          OPTV_BOOLEAN, {0}, FALSE },
@@ -1497,6 +1497,7 @@ static Bool RADEONPreInitChipType(ScrnIn
     info->IsIGP = FALSE;
     info->IsDellServer = FALSE;
     info->HasSingleDAC = FALSE;
+    info->InternalTVOut = TRUE;
     switch (info->Chipset) {
     case PCI_CHIP_RADEON_LY:
     case PCI_CHIP_RADEON_LZ:
@@ -1556,6 +1557,7 @@ static Bool RADEONPreInitChipType(ScrnIn
     case PCI_CHIP_R200_QL:
     case PCI_CHIP_R200_QM:
 	info->ChipFamily = CHIP_FAMILY_R200;
+	info->InternalTVOut = FALSE;
 	break;
 
     case PCI_CHIP_RADEON_LW:
@@ -1738,6 +1740,7 @@ static Bool RADEONPreInitChipType(ScrnIn
 	/* Original Radeon/7200 */
 	info->ChipFamily = CHIP_FAMILY_RADEON;
 	pRADEONEnt->HasCRTC2 = FALSE;
+	info->InternalTVOut = FALSE;
     }
 
 
@@ -4101,6 +4104,9 @@ void RADEONRestoreDACRegisters(ScrnInfoP
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
+    if (IS_R300_VARIANT)
+	OUTREGP(RADEON_GPIOPAD_A, restore->gpiopad_a, ~1);
+
     OUTREGP(RADEON_DAC_CNTL,
 	    restore->dac_cntl,
 	    RADEON_DAC_RANGE_CNTL |
@@ -4108,14 +4114,14 @@ void RADEONRestoreDACRegisters(ScrnInfoP
 
     OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
 
-    //OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
     if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
     	(info->ChipFamily != CHIP_FAMILY_R200)) 
     OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
 
+    OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+
     if ((info->ChipFamily == CHIP_FAMILY_R200) ||
 	IS_R300_VARIANT) {
-	OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
 	OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
     } else {
 	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
@@ -4273,7 +4279,6 @@ void RADEONRestoreRMXRegisters(ScrnInfoP
 void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
     if (info->IsMobility) {
@@ -4286,6 +4291,291 @@ void RADEONRestoreLVDSRegisters(ScrnInfo
 
 }
 
+/* Write to TV FIFO RAM */
+static void RADEONWriteTVFIFO(ScrnInfoPtr pScrn, CARD16 addr,
+			      CARD32 value)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp;
+
+
+    OUTREG(RADEON_TV_HOST_WRITE_DATA, value);
+
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_WT);
+
+    do {
+	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+    }
+    while ((tmp & RADEON_HOST_FIFO_WT_ACK) == 0);
+
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+}
+
+/* Read from RT FIFO RAM */
+static CARD32 RADEONReadTVFIFO(ScrnInfoPtr pScrn, CARD16 addr)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 tmp;
+  
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr);
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, addr | RADEON_HOST_FIFO_RD);
+
+    do {
+	tmp = INREG(RADEON_TV_HOST_RD_WT_CNTL);
+    } 
+    while ((tmp & RADEON_HOST_FIFO_RD_ACK) == 0);
+
+    OUTREG(RADEON_TV_HOST_RD_WT_CNTL, 0);
+
+    return INREG(RADEON_TV_HOST_READ_DATA);
+}
+
+/* Get FIFO addresses of horizontal & vertical code timing tables from
+ * settings of uv_adr register. 
+ */
+static CARD16 RADEONGetHTimingTablesAddr(CARD32 tv_uv_adr)
+{
+    CARD16 hTable;
+
+    switch ((tv_uv_adr & RADEON_HCODE_TABLE_SEL_MASK) >> RADEON_HCODE_TABLE_SEL_SHIFT) {
+    case 0:
+	hTable = RADEON_TV_MAX_FIFO_ADDR_INTERNAL;
+	break;
+
+    case 1:
+	hTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2;
+	break;
+
+    case 2:
+	hTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2;
+	break;
+
+    default:
+	/* Of course, this should never happen */
+	hTable = 0;
+	break;
+    }
+    return hTable;
+}
+
+static CARD16 RADEONGetVTimingTablesAddr(CARD32 tv_uv_adr)
+{
+    CARD16 vTable;
+
+    switch ((tv_uv_adr & RADEON_VCODE_TABLE_SEL_MASK) >> RADEON_VCODE_TABLE_SEL_SHIFT) {
+    case 0:
+	vTable = ((tv_uv_adr & RADEON_MAX_UV_ADR_MASK) >> RADEON_MAX_UV_ADR_SHIFT) * 2 + 1;
+	break;
+
+    case 1:
+	vTable = ((tv_uv_adr & RADEON_TABLE1_BOT_ADR_MASK) >> RADEON_TABLE1_BOT_ADR_SHIFT) * 2 + 1;
+	break;
+
+    case 2:
+	vTable = ((tv_uv_adr & RADEON_TABLE3_TOP_ADR_MASK) >> RADEON_TABLE3_TOP_ADR_SHIFT) * 2 + 1;
+	break;
+
+    default:
+	/* Of course, this should never happen */
+	vTable = 0;
+	break;
+    }
+    return vTable;
+}
+
+/* Restore horizontal/vertical timing code tables */
+static void RADEONRestoreTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 hTable;
+    CARD16 vTable;
+    CARD32 tmp;
+    unsigned i;
+
+    OUTREG(RADEON_TV_UV_ADR, restore->tv_uv_adr);
+    hTable = RADEONGetHTimingTablesAddr(restore->tv_uv_adr);
+    vTable = RADEONGetVTimingTablesAddr(restore->tv_uv_adr);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST
+				   | RADEON_RESTART_PHASE_FIX
+				   | RADEON_CRT_FIFO_CE_EN
+				   | RADEON_TV_FIFO_CE_EN
+				   | RADEON_TV_ON));
+
+    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2, hTable--) {
+	tmp = ((CARD32)restore->h_code_timing[ i ] << 14) | ((CARD32)restore->h_code_timing[ i + 1 ]);
+	RADEONWriteTVFIFO(pScrn, hTable, tmp);
+	if (restore->h_code_timing[ i ] == 0 || restore->h_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+
+    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2, vTable++) {
+	tmp = ((CARD32)restore->v_code_timing[ i + 1 ] << 14) | ((CARD32)restore->v_code_timing[ i ]);
+	RADEONWriteFIFO(pScrn, vTable, tmp);
+	if (restore->v_code_timing[ i ] == 0 || restore->v_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+}
+
+/* restore TV PLLs */
+static void RADEONRestoreTVPLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+    OUTPLL(pScrn, RADEON_TV_PLL_CNTL, restore->tv_pll_cntl);
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVPLL_RESET, ~RADEON_TVPLL_RESET);
+
+    RADEONWaitPLLLock(pScrn, 200, 800, 135);
+  
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_RESET);
+
+    RADEONWaitPLLLock(pScrn, 300, 160, 27);
+    RADEONWaitPLLLock(pScrn, 200, 800, 135);
+  
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~0xf);
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, RADEON_TVCLK_SRC_SEL_TVPLL, ~RADEON_TVCLK_SRC_SEL_TVPLL);
+  
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, (1 << RADEON_TVPDC_SHIFT), ~RADEON_TVPDC_MASK);
+    OUTPLLP(pScrn, RADEON_TV_PLL_CNTL1, 0, ~RADEON_TVPLL_SLEEP);
+}
+
+/* Restore TV horizontal/vertical settings */
+static void RADEONRestoreTVHVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TV_RGB_CNTL, restore->tv_rgb_cntl);
+
+    OUTREG(RADEON_TV_HTOTAL, restore->tv_htotal);
+    OUTREG(RADEON_TV_HDISP, restore->tv_hdisp);
+    OUTREG(RADEON_TV_HSTART, restore->tv_hstart);
+
+    OUTREG(RADEON_TV_VTOTAL, restore->tv_vtotal);
+    OUTREG(RADEON_TV_VDISP, restore->tv_vdisp);
+
+    OUTREG(RADEON_TV_FTOTAL, restore->tv_ftotal);
+
+    OUTREG(RADEON_TV_VSCALER_CNTL1, restore->tv_vscaler_cntl1);
+    OUTREG(RADEON_TV_VSCALER_CNTL2, restore->tv_vscaler_cntl2);
+
+    OUTREG(RADEON_TV_Y_FALL_CNTL, restore->tv_y_fall_cntl);
+    OUTREG(RADEON_TV_Y_RISE_CNTL, restore->tv_y_rise_cntl);
+    OUTREG(RADEON_TV_Y_SAW_TOOTH_CNTL, restore->tv_y_saw_tooth_cntl);
+}
+
+/* restore TV RESTART registers */
+static void RADEONRestoreTVRestarts(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TV_FRESTART, restore->tv_frestart);
+    OUTREG(RADEON_TV_HRESTART, restore->tv_hrestart);
+    OUTREG(RADEON_TV_VRESTART, restore->tv_vrestart);
+}
+
+/* restore tv standard & output muxes */
+static void RADEONRestoreTVOutputStd(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_TV_SYNC_CNTL, restore->tv_sync_cntl);
+  
+    OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+    OUTREG(RADEON_TV_MODULATOR_CNTL1, restore->tv_modulator_cntl1);
+    OUTREG(RADEON_TV_MODULATOR_CNTL2, restore->tv_modulator_cntl2);
+ 
+    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, restore->tv_pre_dac_mux_cntl);
+
+    OUTREG(RADEON_TV_CRC_CNTL, restore->tv_crc_cntl);
+}
+
+/* Test if tv output would be enabled with a given value in TV_DAC_CNTL */
+static Bool RADEONTVIsOn(CARD32 tv_dac_cntl)
+{
+    /* XXX: Fixme for STV vs. CTV */
+    if (tv_dac_cntl & RADEON_TV_DAC_BGSLEEP)
+	return FALSE;
+    else if ((tv_dac_cntl &
+	      (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD)) ==
+	     (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD | RADEON_TV_DAC_BDACPD))
+	return FALSE;
+    else
+	return TRUE;
+}
+
+/* Restore TV out regs */
+void RADEONRestoreTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    ErrorF("Entering Restore TV\n");
+
+    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl | RADEON_TV_ON);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+				   | RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST
+				   | RADEON_RESTART_PHASE_FIX
+				   | RADEON_TV_FIFO_ASYNC_RST));
+
+    /* Temporarily turn the TV DAC off */
+    OUTREG(RADEON_TV_DAC_CNTL, ((restore->tv_dac_cntl & ~RADEON_TV_DAC_NBLANK)
+				| RADEON_TV_DAC_BGSLEEP
+				| RADEON_TV_DAC_RDACPD
+				| RADEON_TV_DAC_GDACPD
+				| RADEON_TV_DAC_BDACPD));
+
+    ErrorF("Restore TV PLL\n");
+    RADEONRestoreTVPLLRegisters(pScrn, restore);
+
+    ErrorF("Restore TVHV\n");
+    RADEONRestoreTVHVRegisters(pScrn, restore);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+				   | RADEON_TV_ASYNC_RST
+				   | RADEON_CRT_ASYNC_RST
+				   | RADEON_RESTART_PHASE_FIX));
+
+    ErrorF("Restore TV Restarts\n");
+    RADEONRestoreTVRestarts(pScrn, restore);
+  
+    ErrorF("Restore Timing Tables\n");
+
+    /* Timing tables are only restored when tv output is active */
+    if (RADEONTVIsOn(restore->tv_dac_cntl))
+	RADEONRestoreTimingTables(pScrn, restore);
+  
+
+    OUTREG(RADEON_TV_MASTER_CNTL, (restore->tv_master_cntl
+				   | RADEON_TV_ASYNC_RST
+				   | RADEON_RESTART_PHASE_FIX));
+
+    ErrorF("Restore TV standard\n");
+    RADEONRestoreTVOutputStd(pScrn, restore);
+
+    OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+
+    /*OUTREG(RADEON_DISP_MERGE_CNTL, restore->disp_merge_cntl);*/
+
+    OUTREG(RADEON_TV_GAIN_LIMIT_SETTINGS, restore->tv_gain_limit_settings);
+    OUTREG(RADEON_TV_LINEAR_GAIN_SETTINGS, restore->tv_linear_gain_settings);
+
+    /* XXX: taken care of in EnableDisplay() */
+    OUTREG(RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+    ErrorF("Leaving Restore TV\n");
+}
+
 static void RADEONPLLWaitForReadUpdateComplete(ScrnInfoPtr pScrn)
 {
     int i = 0;
@@ -4360,6 +4650,39 @@ static CARD8 RADEONComputePLLGain(CARD16
         return 1;
 }
 
+/* Wait for PLLs to lock */
+static void RADEONWaitPLLLock(ScrnInfoPtr pScrn, unsigned nTests,
+			      unsigned nWaitLoops, unsigned cntThreshold)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD32 savePLLTest;
+    unsigned i;
+    unsigned j;
+
+    OUTREG(RADEON_TEST_DEBUG_MUX, (INREG(RADEON_TEST_DEBUG_MUX) & 0xffff60ff) | 0x100);
+
+    savePLLTest = INPLL(pScrn, RADEON_PLL_TEST_CNTL);
+
+    OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest & ~RADEON_PLL_MASK_READ_B);
+
+    /* XXX: these should probably be OUTPLL to avoid various PLL errata */
+
+    OUTREG8(RADEON_CLOCK_CNTL_INDEX, RADEON_PLL_TEST_CNTL);
+
+    for (i = 0; i < nTests; i++) {
+	OUTREG8(RADEON_CLOCK_CNTL_DATA + 3, 0);
+      
+	for (j = 0; j < nWaitLoops; j++)
+	    if (INREG8(RADEON_CLOCK_CNTL_DATA + 3) >= cntThreshold)
+		break;
+    }
+
+    OUTPLL(pScrn, RADEON_PLL_TEST_CNTL, savePLLTest);
+
+    OUTREG(RADEON_TEST_DEBUG_MUX, INREG(RADEON_TEST_DEBUG_MUX) & 0xffffe0ff);
+}
+
 /* Write PLL registers */
 void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
 			       RADEONSavePtr restore)
@@ -4733,6 +5056,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
 /* Write out state to define a new video mode */
 void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
+    RADEONInfoPtr  info     = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
@@ -4765,6 +5089,8 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     RADEONRestoreFP2Registers(pScrn, restore);
     RADEONRestoreLVDSRegisters(pScrn, restore);
     RADEONRestoreDACRegisters(pScrn, restore);
+    if (info->InternalTVOut)
+	RADEONRestoreTVRegisters(pScrn, restore);
 
 #if 0
     RADEONRestorePalette(pScrn, &info->SavedReg);
@@ -4884,6 +5210,8 @@ static void RADEONSaveDACRegisters(ScrnI
     save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
     save->disp_hw_debug         = INREG(RADEON_DISP_HW_DEBUG);
     save->dac_macro_cntl        = INREG(RADEON_DAC_MACRO_CNTL);
+    save->gpiopad_a             = INREG(RADEON_GPIOPAD_A);
+
 }
 
 /* Read flat panel registers */
@@ -4948,6 +5276,95 @@ static void RADEONSaveCrtc2Registers(Scr
 
 }
 
+/* Save horizontal/vertical timing code tables */
+static void RADEONSaveTVTimingTables(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 hTable;
+    CARD16 vTable;
+    CARD32 tmp;
+    unsigned i;
+
+    save->tv_uv_adr = INREG(RADEON_TV_UV_ADR);
+    hTable = RADEONGetHTimingTablesAddr(save->tv_uv_adr);
+    vTable = RADEONGetVTimingTablesAddr(save->tv_uv_adr);
+
+    /*
+     * Reset FIFO arbiter in order to be able to access FIFO RAM
+     */
+    OUTREG(RADEON_TV_MASTER_CNTL, save->tv_master_cntl | RADEON_TV_ON);
+
+    ErrorF("saveTimingTables: reading timing tables\n");
+
+    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i += 2) {
+	tmp = RADEONReadTVFIFO(pScrn, hTable--);
+	save->h_code_timing[ i     ] = (CARD16)((tmp >> 14) & 0x3fff);
+	save->h_code_timing[ i + 1 ] = (CARD16)(tmp & 0x3fff);
+
+	if (save->h_code_timing[ i ] == 0 || save->h_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+
+    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i += 2) {
+	tmp = RADEONReadTVFIFO(pScrn, vTable++);
+	save->v_code_timing[ i     ] = (CARD16)(tmp & 0x3fff);
+	save->v_code_timing[ i + 1 ] = (CARD16)((tmp >> 14) & 0x3fff);
+
+	if (save->v_code_timing[ i ] == 0 || save->v_code_timing[ i + 1 ] == 0)
+	    break;
+    }
+}
+
+/* read TV regs */
+static void RADEONSaveTVRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    unsigned i;
+
+    ErrorF("Entering TV Save\n");
+
+    save->tv_crc_cntl = INREG(RADEON_TV_CRC_CNTL);
+    save->tv_frestart = INREG(RADEON_TV_FRESTART);
+    save->tv_hrestart = INREG(RADEON_TV_HRESTART);
+    save->tv_vrestart = INREG(RADEON_TV_VRESTART);
+    save->tv_gain_limit_settings = INREG(RADEON_TV_GAIN_LIMIT_SETTINGS);
+    save->tv_hdisp = INREG(RADEON_TV_HDISP);
+    save->tv_hstart = INREG(RADEON_TV_HSTART);
+    save->tv_htotal = INREG(RADEON_TV_HTOTAL);
+    save->tv_linear_gain_settings = INREG(RADEON_TV_LINEAR_GAIN_SETTINGS);
+    save->tv_master_cntl = INREG(RADEON_TV_MASTER_CNTL);
+    save->tv_rgb_cntl = INREG(RADEON_TV_RGB_CNTL);
+    save->tv_modulator_cntl1 = INREG(RADEON_TV_MODULATOR_CNTL1);
+    save->tv_modulator_cntl2 = INREG(RADEON_TV_MODULATOR_CNTL2);
+    save->tv_pre_dac_mux_cntl = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+    save->tv_sync_cntl = INREG(RADEON_TV_SYNC_CNTL);
+    save->tv_timing_cntl = INREG(RADEON_TV_TIMING_CNTL);
+    save->tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
+    save->tv_upsamp_and_gain_cntl = INREG(RADEON_TV_UPSAMP_AND_GAIN_CNTL);
+    save->tv_vdisp = INREG(RADEON_TV_VDISP);
+    save->tv_ftotal = INREG(RADEON_TV_FTOTAL);
+    save->tv_vscaler_cntl1 = INREG(RADEON_TV_VSCALER_CNTL1);
+    save->tv_vscaler_cntl2 = INREG(RADEON_TV_VSCALER_CNTL2);
+    save->tv_vtotal = INREG(RADEON_TV_VTOTAL);
+    save->tv_y_fall_cntl = INREG(RADEON_TV_Y_FALL_CNTL);
+    save->tv_y_rise_cntl = INREG(RADEON_TV_Y_RISE_CNTL);
+    save->tv_y_saw_tooth_cntl = INREG(RADEON_TV_Y_SAW_TOOTH_CNTL);
+
+    save->tv_pll_cntl = INPLL(pScrn, RADEON_TV_PLL_CNTL);
+      
+    /*
+     * Read H/V code timing tables (current tables only are saved)
+     * This step is skipped when tv output is disabled in current RT state
+     * (see RADEONRestoreTVRegisters)
+     */
+    if (RADEONTVIsOn(save->tv_dac_cntl))
+	RADEONSaveTimingTables(pScrn, save);
+
+    ErrorF("TV Save done\n");
+}
+
 /* Read PLL registers */
 static void RADEONSavePLLRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
@@ -5016,12 +5433,13 @@ static void RADEONSaveMode(ScrnInfoPtr p
 
     RADEONSaveMemMapRegisters(pScrn, save);
     RADEONSaveCommonRegisters(pScrn, save);
-    RADEONSavePLLRegisters (pScrn, save);
-    RADEONSaveCrtcRegisters (pScrn, save);
-    RADEONSaveFPRegisters (pScrn, save);
-    RADEONSaveDACRegisters (pScrn, save);
-    RADEONSaveCrtc2Registers (pScrn, save);
-    RADEONSavePLL2Registers (pScrn, save);
+    RADEONSavePLLRegisters(pScrn, save);
+    RADEONSaveCrtcRegisters(pScrn, save);
+    RADEONSaveFPRegisters(pScrn, save);
+    RADEONSaveDACRegisters(pScrn, save);
+    RADEONSaveCrtc2Registers(pScrn, save);
+    RADEONSavePLL2Registers(pScrn, save);
+    RADEONSaveTVRegisters(pScrn, save);
     /*RADEONSavePalette(pScrn, save);*/
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 66d8a7f..a5e1cc4 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -78,6 +78,17 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
 
 }
 
+static DisplayModePtr RADEONTVModes(xf86OutputPtr output)
+{
+    DisplayModePtr new  = NULL;
+
+    /* just a place holder */    
+    new = xf86CVTMode(800, 600, 60.00, FALSE, FALSE);
+    new->type = M_T_DRIVER | M_T_PREFERRED;
+
+    return new;
+}
+
 /* This is used only when no mode is specified for FP and no ddc is
  * available.  We force it to native mode, if possible.
  */
@@ -286,6 +297,10 @@ RADEONProbeOutputModes(xf86OutputPtr out
 	modes = xf86OutputGetEDIDModes (output);
 	return modes;
     }
+    if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+	modes = RADEONTVModes(output);
+	return modes;
+    }
     if (radeon_output->type == OUTPUT_LVDS) {
 	/* okay we got DDC info */
 	if (output->MonInfo) {
diff --git a/src/radeon_output.c b/src/radeon_output.c
index e431bf5..d0a12dd 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -46,6 +46,7 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
+#include "radeon_tv.h"
 
 
 const char *MonTypeName[7] = {
@@ -890,7 +891,7 @@ RADEONInitTvDacCntl(ScrnInfoPtr pScrn, R
     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,
@@ -902,6 +903,9 @@ static void RADEONInitDAC2Registers(xf86
     /*0x0028023;*/
     RADEONInitTvDacCntl(pScrn, save);
 
+    if (IS_R300_VARIANT)
+	save->gpiopad_a = info->SavedReg.gpiopad_a | 1;
+
     if (IsPrimary) {
         save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
         if (IS_R300_VARIANT) {
@@ -961,6 +965,9 @@ RADEONInitOutputRegisters(ScrnInfoPtr pS
 	} else {
 	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
 	}
+    } else if (radeon_output->MonType == MT_STV ||
+	       radeon_output->MonType == MT_CTV) {
+	RADEONInitTVRegisters(output, save, mode, IsPrimary);
     }
 }
 
@@ -993,6 +1000,12 @@ radeon_mode_set(xf86OutputPtr output, Di
 	    RADEONRestoreFP2Registers(pScrn, &info->ModeReg);
 	}
 	break;
+    case MT_STV:
+    case MT_CTV:
+	ErrorF("restore tv\n");
+	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+	RADEONRestoreTVRegisters(pScrn, &info->ModeReg);
+	break;
     default:
 	ErrorF("restore dac\n");
 	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
@@ -1041,8 +1054,12 @@ radeon_detect(xf86OutputPtr output)
 
       switch(radeon_output->MonType) {
       case MT_LCD:
-      case MT_DFP: output->subpixel_order = SubPixelHorizontalRGB; break;
-      default: output->subpixel_order = SubPixelNone; break;
+      case MT_DFP:
+	  output->subpixel_order = SubPixelHorizontalRGB;
+	  break;
+      default:
+	  output->subpixel_order = SubPixelNone;
+	  break;
       }
       
       return XF86OutputStatusConnected;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 0dceca9..f0df341 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -137,6 +137,18 @@ typedef enum
     OUTPUT_CTV,
 } RADEONOutputType;
 
+/* standards */
+typedef enum
+{
+    TV_STD_NTSC,
+    TV_STD_PAL,
+    TV_STD_PAL_M,
+    TV_STD_PAL_60,
+    TV_STD_NTSC_J,
+    TV_STD_PAL_CN,
+    TV_STD_PAL_N
+} TVStd;
+
 typedef struct _RADEONCrtcPrivateRec {
 #ifdef USE_XAA
     FBLinearPtr rotate_mem_xaa;
@@ -184,6 +196,11 @@ typedef struct _RADEONOutputPrivateRec {
     int               PanelPwrDly;
     int               DotClock;
     RADEONTMDSPll     tmds_pll[4];
+    /* TV out */
+    TVStd             tvStd;
+    int               hPos;
+    int               vPos;
+    int               hSize;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 #define RADEON_MAX_CRTC 2
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 5fdda45..db2057a 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -467,6 +467,7 @@
 #       define RADEON_DAC_PDWN              (1 << 15)
 #       define RADEON_DAC_MASK_ALL          (0xff << 24)
 #define RADEON_DAC_CNTL2                    0x007c
+#       define RADEON_DAC2_TV_CLK_SEL       (0 <<  1)
 #       define RADEON_DAC2_DAC_CLK_SEL      (1 <<  0)
 #       define RADEON_DAC2_DAC2_CLK_SEL     (1 <<  1)
 #       define RADEON_DAC2_PALETTE_ACC_CTL  (1 <<  5)
@@ -486,9 +487,11 @@
 #       define RADEON_TV_DAC_PEDESTAL       (1 <<  2)
 #       define RADEON_TV_MONITOR_DETECT_EN  (1 <<  4)
 #       define RADEON_TV_DAC_CMPOUT         (1 <<  5)
+#       define RADEON_TV_DAC_STD_MASK       (3 <<  8)
+#       define RADEON_TV_DAC_STD_PAL        (0 <<  8)
 #       define RADEON_TV_DAC_STD_NTSC       (1 <<  8)
-#       define RADEON_TV_DAC_STD_MASK       0x0300
-#       define RADEON_TV_DAC_STD_PS2        0x0200
+#       define RADEON_TV_DAC_STD_PS2        (2 <<  8)
+#       define RADEON_TV_DAC_STD_RS343      (3 <<  8)
 #       define RADEON_TV_DAC_BGSLEEP        (1 <<  6)
 #       define RADEON_TV_DAC_BGADJ_MASK     (0xf <<  16)
 #       define RADEON_TV_DAC_DACADJ_MASK    (0xf <<  20)
@@ -507,9 +510,9 @@
 #       define RADEON_DISP_DAC2_SOURCE_MASK  0x0c
 #       define RADEON_DISP_DAC_SOURCE_CRTC2 0x01
 #       define RADEON_DISP_DAC2_SOURCE_CRTC2 0x04
-#       define RADEON_DISP_TVDAC_SOURCE_MASK  (0x03<<2)
+#       define RADEON_DISP_TVDAC_SOURCE_MASK  (0x03 << 2)
 #       define RADEON_DISP_TVDAC_SOURCE_CRTC  0x0
-#       define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01<<2)
+#       define RADEON_DISP_TVDAC_SOURCE_CRTC2 (0x01 << 2)
 #       define RADEON_DISP_TV_SOURCE_CRTC   (1 << 16) /* crtc1 or crtc2 */
 #       define RADEON_DISP_TV_SOURCE_LTU    (0 << 16) /* linear transform unit */
 #define RADEON_DISP_TV_OUT_CNTL             0x0d6c
@@ -537,12 +540,12 @@
 #       define RADEON_DISP_ALPHA_MODE_KEY   0
 #       define RADEON_DISP_ALPHA_MODE_PER_PIXEL 1
 #       define RADEON_DISP_ALPHA_MODE_GLOBAL 2
-#       define RADEON_DISP_RGB_OFFSET_EN    (1<<8)
+#       define RADEON_DISP_RGB_OFFSET_EN    (1 << 8)
 #       define RADEON_DISP_GRPH_ALPHA_MASK  (0xff << 16)
 #       define RADEON_DISP_OV0_ALPHA_MASK   (0xff << 24)
 #	define RADEON_DISP_LIN_TRANS_BYPASS (0x01 << 9)
 #define RADEON_DISP2_MERGE_CNTL		    0x0d68
-#       define RADEON_DISP2_RGB_OFFSET_EN   (1<<8)
+#       define RADEON_DISP2_RGB_OFFSET_EN   (1 << 8)
 #define RADEON_DISP_LIN_TRANS_GRPH_A        0x0d80
 #define RADEON_DISP_LIN_TRANS_GRPH_B        0x0d84
 #define RADEON_DISP_LIN_TRANS_GRPH_C        0x0d88
@@ -844,6 +847,7 @@
 #       define RADEON_HDP_SOFT_RESET        (1 << 26)
 #       define RADEON_HDP_APER_CNTL         (1 << 23)
 #define RADEON_HTOTAL_CNTL                  0x0009 /* PLL */
+#       define RADEON_HTOT_CNTL_VGA_EN      (1 << 28)
 #define RADEON_HTOTAL2_CNTL                 0x002e /* PLL */
 
        /* Multimedia I2C bus */
@@ -1267,6 +1271,7 @@
 #       define R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF (1 << 23)
 #define RADEON_PLANE_3D_MASK_C              0x1d44
 #define RADEON_PLL_TEST_CNTL                0x0013 /* PLL */
+#       define RADEON_PLL_MASK_READ_B          (1 << 9)
 #define RADEON_PMI_CAP_ID                   0x0f5c /* PCI */
 #define RADEON_PMI_DATA                     0x0f63 /* PCI */
 #define RADEON_PMI_NXT_CAP_PTR              0x0f5d /* PCI */
@@ -3080,9 +3085,14 @@
 #       define RADEON_TV_ASYNC_RST               (1 <<  0)
 #       define RADEON_CRT_ASYNC_RST              (1 <<  1)
 #       define RADEON_RESTART_PHASE_FIX          (1 <<  3)
+#	define RADEON_TV_FIFO_ASYNC_RST		 (1 <<  4)
+#	define RADEON_VIN_ASYNC_RST		 (1 <<  5)
+#	define RADEON_AUD_ASYNC_RST		 (1 <<  6)
+#	define RADEON_DVS_ASYNC_RST		 (1 <<  7)
 #       define RADEON_CRT_FIFO_CE_EN             (1 <<  9)
 #       define RADEON_TV_FIFO_CE_EN              (1 << 10)
 #       define RADEON_TVCLK_ALWAYS_ONb           (1 << 30)
+#	define RADEON_TV_ON			 (1 << 31)
 #define RADEON_TV_PRE_DAC_MUX_CNTL               0x0888
 #       define RADEON_Y_RED_EN                   (1 << 0)
 #       define RADEON_C_GRN_EN                   (1 << 1)
@@ -3100,7 +3110,14 @@
 #       define RADEON_RGB_SRC_SEL_RMX		  (1 <<  8)
 #       define RADEON_RGB_SRC_SEL_CRTC2		  (2 <<  8)
 #       define RADEON_RGB_CONVERT_BY_PASS	  (1 << 10)
+#	define RADEON_TVOUT_SCALE_EN 		  (1 << 26)
 #define RADEON_TV_SYNC_CNTL                          0x0808
+#       define RADEON_SYNC_OE                     (1 <<  0)
+#       define RADEON_SYNC_OUT                    (1 <<  1)
+#       define RADEON_SYNC_IN                     (1 <<  2)
+#       define RADEON_SYNC_PUB                    (1 <<  3)
+#       define RADEON_SYNC_PD                     (1 <<  4)
+#       define RADEON_TV_SYNC_IO_DRIVE            (1 <<  5)
 #define RADEON_TV_HTOTAL                             0x080c
 #define RADEON_TV_HDISP                              0x0810
 #define RADEON_TV_HSTART                             0x0818
@@ -3116,10 +3133,23 @@
 #define RADEON_TV_HOST_READ_DATA                     0x0840
 #define RADEON_TV_HOST_WRITE_DATA                    0x0844
 #define RADEON_TV_HOST_RD_WT_CNTL                    0x0848
+#	define RADEON_HOST_FIFO_RD		 (1 << 12)
+#	define RADEON_HOST_FIFO_RD_ACK		 (1 << 13)
+#	define RADEON_HOST_FIFO_WT		 (1 << 14)
+#	define RADEON_HOST_FIFO_WT_ACK		 (1 << 15)
 #define RADEON_TV_VSCALER_CNTL1                      0x084c
+#       define RADEON_UV_INC_MASK                0xffff
+#       define RADEON_UV_INC_SHIFT               0
+#       define RADEON_Y_W_EN			 (1 << 24)
 #       define RADEON_RESTART_FIELD              (1 << 29) /* restart on field 0 */
 #       define RADEON_Y_DEL_W_SIG_SHIFT          26
 #define RADEON_TV_TIMING_CNTL                        0x0850
+#       define RADEON_H_INC_MASK                 0xfff
+#       define RADEON_H_INC_SHIFT                0
+#       define RADEON_REQ_Y_FIRST                (1 << 19)
+#       define RADEON_FORCE_BURST_ALWAYS         (1 << 21)
+#       define RADEON_UV_POST_SCALE_BYPASS       (1 << 23)
+#       define RADEON_UV_OUTPUT_POST_SCALE_SHIFT 24
 #define RADEON_TV_VSCALER_CNTL2                      0x0854
 #       define RADEON_DITHER_MODE                (1 <<  0)
 #       define RADEON_Y_OUTPUT_DITHER_EN         (1 <<  1)
@@ -3127,27 +3157,65 @@
 #       define RADEON_UV_TO_BUF_DITHER_EN        (1 <<  3)
 #define RADEON_TV_Y_FALL_CNTL                        0x0858
 #       define RADEON_Y_FALL_PING_PONG           (1 << 16)
+#       define RADEON_Y_COEF_EN                  (1 << 17)
 #define RADEON_TV_Y_RISE_CNTL                        0x085c
 #       define RADEON_Y_RISE_PING_PONG           (1 << 16)
 #define RADEON_TV_Y_SAW_TOOTH_CNTL                   0x0860
 #define RADEON_TV_UPSAMP_AND_GAIN_CNTL               0x0864
+#	define RADEON_YUPSAMP_EN		 (1 <<  0)
+#	define RADEON_UVUPSAMP_EN		 (1 <<  2)
 #define RADEON_TV_GAIN_LIMIT_SETTINGS                0x0868
+#       define RADEON_Y_GAIN_LIMIT_SHIFT         0
+#       define RADEON_UV_GAIN_LIMIT_SHIFT        16
 #define RADEON_TV_LINEAR_GAIN_SETTINGS               0x086c
+#       define RADEON_Y_GAIN_SHIFT               0
+#       define RADEON_UV_GAIN_SHIFT              16
 #define RADEON_TV_MODULATOR_CNTL1                    0x0870
+#	define RADEON_YFLT_EN			 (1 <<  2)
+#	define RADEON_UVFLT_EN			 (1 <<  3)
 #       define RADEON_ALT_PHASE_EN               (1 <<  6)
 #       define RADEON_SYNC_TIP_LEVEL             (1 <<  7)
+#       define RADEON_BLANK_LEVEL_SHIFT          8
+#       define RADEON_SET_UP_LEVEL_SHIFT         16
+#	define RADEON_SLEW_RATE_LIMIT		 (1 << 23)
+#       define RADEON_CY_FILT_BLEND_SHIFT        28
 #define RADEON_TV_MODULATOR_CNTL2                    0x0874
 #define RADEON_TV_CRC_CNTL                           0x0890
 #define RADEON_TV_UV_ADR                             0x08ac
+#	define RADEON_MAX_UV_ADR_MASK		 0x000000ff
+#	define RADEON_MAX_UV_ADR_SHIFT		 0
+#	define RADEON_TABLE1_BOT_ADR_MASK	 0x0000ff00
+#	define RADEON_TABLE1_BOT_ADR_SHIFT	 8
+#	define RADEON_TABLE3_TOP_ADR_MASK	 0x00ff0000
+#	define RADEON_TABLE3_TOP_ADR_SHIFT	 16
+#	define RADEON_HCODE_TABLE_SEL_MASK	 0x06000000
+#	define RADEON_HCODE_TABLE_SEL_SHIFT	 25
+#	define RADEON_VCODE_TABLE_SEL_MASK	 0x18000000
+#	define RADEON_VCODE_TABLE_SEL_SHIFT	 27
+#	define RADEON_TV_MAX_FIFO_ADDR		 0x1a7
+#	define RADEON_TV_MAX_FIFO_ADDR_INTERNAL	 0x1ff
 #define RADEON_TV_PLL_FINE_CNTL			     0x0020	/* PLL */
 #define RADEON_TV_PLL_CNTL                           0x0021	/* PLL */
+#       define RADEON_TV_M0LO_MASK               0xff
+#       define RADEON_TV_M0HI_MASK               0x3
+#       define RADEON_TV_M0HI_SHIFT              18
+#       define RADEON_TV_N0LO_MASK               0xff
+#       define RADEON_TV_N0LO_SHIFT              8
+#       define RADEON_TV_N0HI_MASK               0x3
+#       define RADEON_TV_N0HI_SHIFT              21
+#       define RADEON_TV_P_MASK                  0xf
+#       define RADEON_TV_P_SHIFT                 24
 #       define RADEON_TV_SLIP_EN                 (1 << 23)
 #       define RADEON_TV_DTO_EN                  (1 << 28)
 #define RADEON_TV_PLL_CNTL1                          0x0022	/* PLL */
-#       define RADEON_TVPLL_TEST_DIS             (1 << 31)
-#       define RADEON_TVCLK_SRC_SEL_TVPLL        (1 << 30)
+#       define RADEON_TVPLL_RESET                (1 <<  1)
 #       define RADEON_TVPLL_SLEEP                (1 <<  3)
 #       define RADEON_TVPLL_REFCLK_SEL           (1 <<  4)
+#       define RADEON_TVPDC_SHIFT                14
+#       define RADEON_TVPDC_MASK                 (3 << 14)
+#       define RADEON_TVPLL_TEST_DIS             (1 << 31)
+#       define RADEON_TVCLK_SRC_SEL_TVPLL        (1 << 30)
+#define RADEON_GPIOPAD_A			     0x019c
 
 #define RADEON_RS480_UNK_e30			0xe30
 #define RADEON_RS480_UNK_e34			0xe34
diff --git a/src/radeon_tv.c b/src/radeon_tv.c
new file mode 100644
index 0000000..1d0b2c6
--- /dev/null
+++ b/src/radeon_tv.c
@@ -0,0 +1,656 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "fbdevhw.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_tv.h"
+
+/**********************************************************************
+ *
+ * ModeConstants
+ *
+ * Storage of constants related to a single video mode
+ *
+ **********************************************************************/
+
+typedef struct
+{
+    CARD16 horResolution;
+    CARD16 verResolution;
+    TVStd  standard;
+    CARD16 horTotal;
+    CARD16 verTotal;
+    CARD16 horStart;
+    CARD16 horSyncStart;
+    CARD16 verSyncStart;
+    unsigned defRestart;
+    CARD32 vScalerCntl1;
+    CARD32 yRiseCntl;
+    CARD32 ySawtoothCntl;
+    CARD16 crtcPLL_N;
+    CARD8  crtcPLL_M;
+    Bool   crtcPLL_divBy2;
+    CARD8  crtcPLL_byteClkDiv;
+    CARD8  crtcPLL_postDiv;
+    Bool   use888RGB; /* False: RGB data is 565 packed (2 bytes/pixel) */
+                      /* True : RGB data is 888 packed (3 bytes/pixel) */
+    unsigned pixToTV;
+    CARD8  byteClkDelay;
+    CARD32 tvoDataDelayA;
+    CARD32 tvoDataDelayB;
+    const CARD16 *horTimingTable;
+    const CARD16 *verTimingTable;
+} TVModeConstants;
+
+static const CARD16 horTimingNTSC_BIOS[] =
+{
+    0x0007,
+    0x003f,
+    0x0263,
+    0x0a24,
+    0x2a6b,
+    0x0a36,
+    0x126d, /* H_TABLE_POS1 */
+    0x1bfe,
+    0x1a8f, /* H_TABLE_POS2 */
+    0x1ec7,
+    0x3863,
+    0x1bfe,
+    0x1bfe,
+    0x1a2a,
+    0x1e95,
+    0x0e31,
+    0x201b,
+    0
+};
+
+static const CARD16 verTimingNTSC_BIOS[] =
+{
+    0x2001,
+    0x200d,
+    0x1006,
+    0x0c06,
+    0x1006,
+    0x1818,
+    0x21e3,
+    0x1006,
+    0x0c06,
+    0x1006,
+    0x1817,
+    0x21d4,
+    0x0002,
+    0
+};
+
+static const CARD16 horTimingPAL_BIOS[] =
+{
+    0x0007,
+    0x0058,
+    0x027c,
+    0x0a31,
+    0x2a77,
+    0x0a95,
+    0x124f, /* H_TABLE_POS1 */
+    0x1bfe,
+    0x1b22, /* H_TABLE_POS2 */
+    0x1ef9,
+    0x387c,
+    0x1bfe,
+    0x1bfe,
+    0x1b31,
+    0x1eb5,
+    0x0e43,
+    0x201b,
+    0
+};
+
+static const CARD16 verTimingPAL_BIOS[] =
+{
+    0x2001,
+    0x200c,
+    0x1005,
+    0x0c05,
+    0x1005,
+    0x1401,
+    0x1821,
+    0x2240,
+    0x1005,
+    0x0c05,
+    0x1005,
+    0x1401,
+    0x1822,
+    0x2230,
+    0x0002,
+    0
+};
+
+/**********************************************************************
+ *
+ * availableModes
+ *
+ * Table of all allowed modes for tv output
+ *
+ **********************************************************************/
+static const TVModeConstants availableTVModes[] =
+{
+    { 
+	800,                /* horResolution */
+	600,                /* verResolution */
+	TV_STD_NTSC,        /* standard */
+	990,                /* horTotal */
+	740,                /* verTotal */
+	813,                /* horStart */
+	824,                /* horSyncStart */
+	632,                /* verSyncStart */
+	625592,             /* defRestart */
+	0x0900b46b,         /* vScalerCntl1 */
+	0x00012c00,         /* yRiseCntl */
+	0x10002d1a,         /* ySawtoothCntl */
+	592,                /* crtcPLL_N */
+	91,                 /* crtcPLL_M */
+	TRUE,               /* crtcPLL_divBy2 */
+	0,                  /* crtcPLL_byteClkDiv */
+	4,                  /* crtcPLL_postDiv */
+	FALSE,              /* use888RGB */
+	1022,               /* pixToTV */
+	1,                  /* byteClkDelay */
+	0x0a0b0907,         /* tvoDataDelayA */
+	0x060a090a,         /* tvoDataDelayB */
+	horTimingNTSC_BIOS, /* horTimingTable */
+	verTimingNTSC_BIOS  /* verTimingTable */
+    },
+    { 
+	800,               /* horResolution */
+	600,               /* verResolution */
+	TV_STD_PAL,        /* standard */
+	1144,              /* horTotal */
+	706,               /* verTotal */
+	812,               /* horStart */
+	824,               /* horSyncStart */
+	669,               /* verSyncStart */
+	696700,            /* defRestart */
+	0x09009097,        /* vScalerCntl1 */
+	0x000007da,        /* yRiseCntl */
+	0x10002426,        /* ySawtoothCntl */
+	1382,              /* crtcPLL_N */
+	231,               /* crtcPLL_M */
+	TRUE,              /* crtcPLL_divBy2 */
+	0,                 /* crtcPLL_byteClkDiv */
+	4,                 /* crtcPLL_postDiv */
+	FALSE,             /* use888RGB */
+	759,               /* pixToTV */
+	1,                 /* byteClkDelay */
+	0x0a0b0907,        /* tvoDataDelayA */
+	0x060a090a,        /* tvoDataDelayB */
+	horTimingPAL_BIOS, /* horTimingTable */
+	verTimingPAL_BIOS  /* verTimingTable */
+    }
+};
+
+#define N_AVAILABLE_MODES (sizeof(availableModes) / sizeof(availableModes[ 0 ]))
+
+
+/* Compute F,V,H restarts from default restart position and hPos & vPos
+ * Return TRUE when code timing table was changed
+ */
+static Bool RADEONInitTVRestarts(xf86OutputPtr output, RADEONSavePtr save,
+				 DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    int restart;
+    unsigned hTotal;
+    unsigned vTotal;
+    unsigned fTotal;
+    int vOffset;
+    int hOffset;
+    CARD16 p1;
+    CARD16 p2;
+    Bool hChanged;
+    CARD16 hInc;
+    const TVModeConstants *constPtr;
+
+    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    hTotal = constPtr->horTotal;
+    vTotal = constPtr->verTotal;
+    
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	fTotal = NTSC_TV_VFTOTAL + 1;
+    else
+	fTotal = PAL_TV_VFTOTAL + 1;
+
+    /*
+     * Adjust positions 1&2 in hor. code timing table
+     */
+    hOffset = radeon_output->hPos * H_POS_UNIT;
+
+    p1 = constPtr->horTimingTable[ H_TABLE_POS1 ];
+    p2 = constPtr->horTimingTable[ H_TABLE_POS2 ];
+
+    p1 = (CARD16)((int)p1 + hOffset);
+    p2 = (CARD16)((int)p2 - hOffset);
+
+    hChanged = (p1 != save->h_code_timing[ H_TABLE_POS1 ] || 
+		p2 != save->h_code_timing[ H_TABLE_POS2 ]);
+
+    save->h_code_timing[ H_TABLE_POS1 ] = p1;
+    save->h_code_timing[ H_TABLE_POS2 ] = p2;
+
+    /* Convert hOffset from n. of TV clock periods to n. of CRTC clock periods (CRTC pixels) */
+    hOffset = (hOffset * (int)(constPtr->pixToTV)) / 1000;
+
+    /* Adjust restart */
+    restart = constPtr->defRestart;
+ 
+    /*
+     * Convert vPos TV lines to n. of CRTC pixels
+     * Be verrrrry careful when mixing signed & unsigned values in C..
+     */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(NTSC_TV_LINES_PER_FRAME);
+    else
+	vOffset = ((int)(vTotal * hTotal) * 2 * radeon_output->vPos) / (int)(PAL_TV_LINES_PER_FRAME);
+
+    restart -= vOffset + hOffset;
+
+    ErrorF("computeRestarts: def = %u, h = %d, v = %d, p1=%04x, p2=%04x, restart = %d\n",
+	   constPtr->defRestart , radeon_output->hPos , radeon_output->vPos , p1 , p2 , restart);
+
+    save->tv_hrestart = restart % hTotal;
+    restart /= hTotal;
+    save->tv_vrestart = restart % vTotal;
+    restart /= vTotal;
+    save->tv_frestart = restart % fTotal;
+
+    ErrorF("computeRestarts: F/H/V=%u,%u,%u\n",
+	   save->tv_frestart , save->tv_vrestart , save->tv_hrestart);
+
+    /* Compute H_INC from hSize */
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	hInc = (CARD16)((int)(constPtr->horResolution * 4096 * NTSC_TV_CLOCK_T) /
+			(radeon_output->hSize * (int)(NTSC_TV_H_SIZE_UNIT) + (int)(NTSC_TV_ZERO_H_SIZE)));
+    else
+	hInc = (CARD16)((int)(constPtr->horResolution * 4096 * PAL_TV_CLOCK_T) /
+			(radeon_output->hSize * (int)(PAL_TV_H_SIZE_UNIT) + (int)(PAL_TV_ZERO_H_SIZE)));
+
+    save->tv_timing_cntl = (save->tv_timing_cntl & ~RADEON_H_INC_MASK) |
+	((CARD32)hInc << RADEON_H_INC_SHIFT);
+
+    ErrorF("computeRestarts: hSize=%d,hInc=%u\n" , radeon_output->hSize , hInc);
+
+    return hChanged;
+}
+
+/* intit TV-out regs */
+void RADEONInitTVRegisters(xf86OutputPtr output, RADEONSavePtr save,
+                                  DisplayModePtr mode, BOOL IsPrimary)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    unsigned i;
+    CARD32 tmp;
+    const TVModeConstants *constPtr;
+
+    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    save->tv_crc_cntl = 0;
+
+    save->tv_gain_limit_settings = (0x17f << RADEON_UV_GAIN_LIMIT_SHIFT) | 
+	                           (0x5ff << RADEON_Y_GAIN_LIMIT_SHIFT);
+
+    save->tv_hdisp = constPtr->horResolution - 1;
+    save->tv_hstart = constPtr->horStart;
+    save->tv_htotal = constPtr->horTotal - 1;
+
+    save->tv_linear_gain_settings = (0x100 << RADEON_UV_GAIN_SHIFT) |
+	                            (0x100 << RADEON_Y_GAIN_SHIFT);
+
+    save->tv_master_cntl = (RADEON_RESTART_PHASE_FIX
+			    | RADEON_VIN_ASYNC_RST
+			    | RADEON_AUD_ASYNC_RST
+			    | RADEON_DVS_ASYNC_RST
+			    | RADEON_CRT_FIFO_CE_EN
+			    | RADEON_TV_FIFO_CE_EN);
+
+    save->tv_modulator_cntl1 = RADEON_SLEW_RATE_LIMIT
+	                       | RADEON_SYNC_TIP_LEVEL
+	                       | RADEON_YFLT_EN
+	                       | RADEON_UVFLT_EN
+	                       | (0x3b << RADEON_BLANK_LEVEL_SHIFT)
+	                       | (0x6 << RADEON_CY_FILT_BLEND_SHIFT);
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	save->tv_modulator_cntl1 |= (0x46 << RADEON_SET_UP_LEVEL_SHIFT);
+    else
+	save->tv_modulator_cntl1 |= RADEON_ALT_PHASE_EN
+	                            | (0x3b << RADEON_SET_UP_LEVEL_SHIFT);
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	save->tv_modulator_cntl2 = 0x00000191;
+    else
+	save->tv_modulator_cntl2 = 0x003e01b2;
+
+    save->pll_test_cntl = 0;
+
+    save->tv_pre_dac_mux_cntl = (RADEON_Y_RED_EN
+				 | RADEON_C_GRN_EN
+				 | RADEON_CMP_BLU_EN
+				 | RADEON_DAC_DITHER_EN);
+
+    save->tv_rgb_cntl = 0x007b0004;
+
+    if (IsPrimary) {
+	if (radeon_output->Flags & RADEON_USE_RMX)
+	    save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_RMX;
+	else
+	    save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC1;
+    } else {
+	save->tv_rgb_cntl |= RADEON_RGB_SRC_SEL_CRTC2;
+    }
+
+    save->tv_sync_cntl = RADEON_SYNC_PUB | RADEON_TV_SYNC_IO_DRIVE;
+
+    save->tv_sync_size = constPtr->horResolution + 8;
+  
+    tmp = (constPtr->vScalerCntl1 >> RADEON_UV_INC_SHIFT) & RADEON_UV_INC_MASK;
+    tmp = ((16384 * 256 * 10) / tmp + 5) / 10;
+    tmp = (tmp << RADEON_UV_OUTPUT_POST_SCALE_SHIFT) | 0x000b0000;
+    save->tv_timing_cntl = tmp;
+
+    save->tv_dac_cntl = RADEON_TV_DAC_NBLANK | RADEON_TV_DAC_NHOLD
+	                | RADEON_TV_MONITOR_DETECT_EN
+	                | (8 << 16) | (6 << 20);
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	save->tv_dac_cntl |= RADEON_TV_DAC_STD_NTSC;
+    else
+	save->tv_dac_cntl |= RADEON_TV_DAC_STD_PAL;
+
+#if 0
+    save->tv_dac_cntl |= (RADEON_TV_DAC_RDACPD | RADEON_TV_DAC_GDACPD
+	                 | RADEON_TV_DAC_BDACPD);
+
+    if (MonType == MT_CTV) {
+	save->tv_dac_cntl &= ~RADEON_TV_DAC_BDACPD;
+    }
+
+    if (MonType == MT_STV) {
+	save->tv_dac_cntl &= ~(RADEON_TV_DAC_RDACPD |
+			       RADEON_TV_DAC_GDACPD);
+    }
+#endif
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	save->tv_pll_cntl = (NTSC_TV_PLL_M & RADEON_TV_M0LO_MASK) |
+	    (((NTSC_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+	    ((NTSC_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+	    (((NTSC_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+	    ((NTSC_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+    else
+	save->tv_pll_cntl = (PAL_TV_PLL_M & RADEON_TV_M0LO_MASK) |
+	    (((PAL_TV_PLL_M >> 8) & RADEON_TV_M0HI_MASK) << RADEON_TV_M0HI_SHIFT) |
+	    ((PAL_TV_PLL_N & RADEON_TV_N0LO_MASK) << RADEON_TV_N0LO_SHIFT) |
+	    (((PAL_TV_PLL_N >> 8) & RADEON_TV_N0HI_MASK) << RADEON_TV_N0HI_SHIFT) |
+	    ((PAL_TV_PLL_P & RADEON_TV_P_MASK) << RADEON_TV_P_SHIFT);
+
+    save->tv_upsamp_and_gain_cntl = RADEON_YUPSAMP_EN | RADEON_UVUPSAMP_EN;
+
+    save->tv_uv_adr = 0xc8;
+
+    save->tv_vdisp = constPtr->verResolution - 1;
+
+    if (radeon_output->tvStd == TV_STD_NTSC)
+	save->tv_ftotal = NTSC_TV_VFTOTAL;
+    else
+	save->tv_ftotal = PAL_TV_VFTOTAL;
+
+    save->tv_vscaler_cntl1 = constPtr->vScalerCntl1;
+    save->tv_vscaler_cntl1 |= RADEON_RESTART_FIELD;
+
+    save->tv_vscaler_cntl2 = 0x10000000;
+
+    save->tv_vtotal = constPtr->verTotal - 1;
+
+    save->tv_y_fall_cntl = RADEON_Y_FALL_PING_PONG | RADEON_Y_COEF_EN;
+    save->tv_y_fall_cntl |= 0x80000400;
+
+    save->tv_y_rise_cntl = constPtr->yRiseCntl;
+    save->tv_y_saw_tooth_cntl = constPtr->ySawtoothCntl;
+
+    for (i = 0; i < MAX_H_CODE_TIMING_LEN; i++) {
+	if ((save->h_code_timing[ i ] = constPtr->horTimingTable[ i ]) == 0)
+	    break;
+    }
+
+    for (i = 0; i < MAX_V_CODE_TIMING_LEN; i++) {
+	if ((save->v_code_timing[ i ] = constPtr->verTimingTable[ i ]) == 0)
+	    break;
+    }
+
+    /*
+     * This must be called AFTER loading timing tables as they are modified by this function
+     */
+    RADEONInitTVRestarts(output, save, mode);
+
+    /*save->hw_debug = 0x00000200;*/
+
+    save->dac_cntl &= ~RADEON_DAC_TVO_EN;
+
+    if (IS_R300_VARIANT)
+        save->gpiopad_a = info->SavedReg.gpiopad_a & ~1;
+
+    if (IsPrimary) {
+	save->disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+	save->disp_output_cntl |= (RADEON_DISP_TVDAC_SOURCE_CRTC
+				   | RADEON_DISP_TV_SOURCE_CRTC);
+    	if (info->ChipFamily >= CHIP_FAMILY_R200) {
+	    save->disp_tv_out_cntl &= ~RADEON_DISP_TV_PATH_SRC_CRTC2;
+    	} else {
+            save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+    	}
+    } else {
+	save->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK;
+	save->disp_output_cntl |= RADEON_DISP_TV_SOURCE_CRTC;
+
+    	if (info->ChipFamily >= CHIP_FAMILY_R200) {
+	    save->disp_tv_out_cntl |= RADEON_DISP_TV_PATH_SRC_CRTC2;
+    	} else {
+            save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
+    	}
+    }
+}
+
+
+/* Set hw registers for a new h/v position & h size */
+static void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    Bool reloadTable;
+    RADEONSavePtr restore = &info->ModeReg;
+
+    reloadTable = RADEONInitTVRestarts(output, restore, mode);
+
+    RADEONRestoreTVRestarts(pScrn, restore);
+
+    OUTREG(RADEON_TV_TIMING_CNTL, restore->tv_timing_cntl);
+
+    if (reloadTable) {
+	 OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl
+		                       | RADEON_TV_ASYNC_RST
+		                       | RADEON_CRT_ASYNC_RST
+		                       | RADEON_RESTART_PHASE_FIX);
+
+	RADEONRestoreTVTimingTables(pScrn, restore);
+
+	OUTREG(RADEON_TV_MASTER_CNTL, restore->tv_master_cntl);
+    }
+}
+
+void RADEONAdjustCrtcRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+				    DisplayModePtr mode, xf86OutputPtr output)
+{
+    const TVModeConstants *constPtr;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    save->crtc_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+	(((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+    save->crtc_h_sync_strt_wid = (save->crtc_h_sync_strt_wid 
+				  & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) |
+	(((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+	(constPtr->horSyncStart & 7);
+
+    save->crtc_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+	((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+    save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
+	((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+
+    save->disp_merge_cntl |= RADEON_DISP_RGB_OFFSET_EN;
+}
+
+void RADEONAdjustPLLRegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+				   DisplayModePtr mode, xf86OutputPtr output)
+{
+    unsigned postDiv;
+    const TVModeConstants *constPtr;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    save->htotal_cntl = (constPtr->horTotal & 0x7 /*0xf*/) | RADEON_HTOT_CNTL_VGA_EN;
+
+    save->ppll_ref_div = constPtr->crtcPLL_M;
+
+    switch (constPtr->crtcPLL_postDiv) {
+    case 1:
+	postDiv = 0;
+	break;
+    case 2:
+	postDiv = 1;
+	break;
+    case 3:
+	postDiv = 4;
+	break;
+    case 4:
+	postDiv = 2;
+	break;
+    case 6:
+	postDiv = 6;
+	break;
+    case 8:
+	postDiv = 3;
+	break;
+    case 12:
+	postDiv = 7;
+	break;
+    case 16:
+    default:
+	postDiv = 5;
+	break;
+    }
+
+    save->ppll_div_3 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16);
+
+    save->pixclks_cntl &= ~(RADEON_PIX2CLK_SRC_SEL_MASK | RADEON_PIXCLK_TV_SRC_SEL);
+    save->pixclks_cntl |= RADEON_PIX2CLK_SRC_SEL_P2PLLCLK;
+
+}
+
+void RADEONAdjustCrtc2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+				     DisplayModePtr mode, xf86OutputPtr output)
+{
+    const TVModeConstants *constPtr;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    save->crtc2_h_total_disp = (((constPtr->horResolution / 8) - 1) << RADEON_CRTC_H_DISP_SHIFT) |
+	(((constPtr->horTotal / 8) - 1) << RADEON_CRTC_H_TOTAL_SHIFT);
+
+    save->crtc2_h_sync_strt_wid = (save->crtc2_h_sync_strt_wid 
+				  & ~(RADEON_CRTC_H_SYNC_STRT_PIX | RADEON_CRTC_H_SYNC_STRT_CHAR)) |
+	(((constPtr->horSyncStart / 8) - 1) << RADEON_CRTC_H_SYNC_STRT_CHAR_SHIFT) |
+	(constPtr->horSyncStart & 7);
+
+    save->crtc2_v_total_disp = ((constPtr->verResolution - 1) << RADEON_CRTC_V_DISP_SHIFT) |
+	((constPtr->verTotal - 1) << RADEON_CRTC_V_TOTAL_SHIFT);
+
+    save->crtc_v_sync_strt_wid = (save->crtc_v_sync_strt_wid & ~RADEON_CRTC_V_SYNC_STRT) |
+	((constPtr->verSyncStart - 1) << RADEON_CRTC_V_SYNC_STRT_SHIFT);
+
+    save->disp2_merge_cntl |= RADEON_DISP2_RGB_OFFSET_EN;
+}
+
+void RADEONAdjustPLL2RegistersForTV(ScrnInfoPtr pScrn, RADEONSavePtr save,
+				    DisplayModePtr mode, xf86OutputPtr output)
+{
+    unsigned postDiv;
+    const TVModeConstants *constPtr;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    constPtr = &availableTVModes[radeon_output->tvStd];
+
+    save->htotal_cntl2 = (constPtr->horTotal & 0x7); /* 0xf */
+
+    save->p2pll_ref_div = constPtr->crtcPLL_M;
+
+    switch (constPtr->crtcPLL_postDiv) {
+    case 1:
+	postDiv = 0;
+	break;
+    case 2:
+	postDiv = 1;
+	break;
+    case 3:
+	postDiv = 4;
+	break;
+    case 4:
+	postDiv = 2;
+	break;
+    case 6:
+	postDiv = 6;
+	break;
+    case 8:
+	postDiv = 3;
+	break;
+    case 12:
+	postDiv = 7;
+	break;
+    case 16:
+    default:
+	postDiv = 5;
+	break;
+    }
+
+    save->p2pll_div_0 = (constPtr->crtcPLL_N & 0x7ff) | (postDiv << 16);
+
+    save->pixclks_cntl &= ~RADEON_PIX2CLK_SRC_SEL_MASK;
+    save->pixclks_cntl |= (RADEON_PIX2CLK_SRC_SEL_P2PLLCLK
+			   | RADEON_PIXCLK_TV_SRC_SEL);
+
+}
diff --git a/src/radeon_tv.h b/src/radeon_tv.h
new file mode 100644
index 0000000..179b87b
--- /dev/null
+++ b/src/radeon_tv.h
@@ -0,0 +1,46 @@
+/*
+ * Maximum length of horizontal/vertical code timing tables for state storage
+ */
+#define MAX_H_CODE_TIMING_LEN 32
+#define MAX_V_CODE_TIMING_LEN 32
+
+/*
+ * Limits of h/v positions (hPos & vPos)
+ */
+#define MAX_H_POSITION 5 /* Range: [-5..5], negative is on the left, 0 is default, positive is on the right */
+#define MAX_V_POSITION 5 /* Range: [-5..5], negative is up, 0 is default, positive is down */
+
+/*
+ * Unit for hPos (in TV clock periods)
+ */
+#define H_POS_UNIT 10
+
+/*
+ * Indexes in h. code timing table for horizontal line position adjustment
+ */
+#define H_TABLE_POS1 6
+#define H_TABLE_POS2 8
+
+/*
+ * Limits of hor. size (hSize)
+ */
+#define MAX_H_SIZE 5 /* Range: [-5..5], negative is smaller, positive is larger */
+
+/* tv standard constants */
+#define NTSC_TV_PLL_M 22
+#define NTSC_TV_PLL_N 175
+#define NTSC_TV_PLL_P 5
+#define NTSC_TV_CLOCK_T 233
+#define NTSC_TV_VFTOTAL 1
+#define NTSC_TV_LINES_PER_FRAME 525
+#define NTSC_TV_ZERO_H_SIZE 479166
+#define NTSC_TV_H_SIZE_UNIT 9478
+
+#define PAL_TV_PLL_M 113
+#define PAL_TV_PLL_N 668
+#define PAL_TV_PLL_P 3
+#define PAL_TV_CLOCK_T 188
+#define PAL_TV_VFTOTAL 3
+#define PAL_TV_LINES_PER_FRAME 625
+#define PAL_TV_ZERO_H_SIZE 473200
+#define PAL_TV_H_SIZE_UNIT 9360
diff-tree 8d043db1817d94edeb72ab208dfea60026715d48 (from 62f06d89da3f7160d5e4df8d7ce6fe1a94e9d07c)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Jul 25 20:37:58 2007 -0400

    RADEON: Compute PLL VCO gain

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d82e912..e9a0954 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4332,12 +4332,45 @@ static void RADEONPLL2WriteUpdate(ScrnIn
 	    ~(RADEON_P2PLL_ATOMIC_UPDATE_W));
 }
 
+static CARD8 RADEONComputePLLGain(CARD16 reference_freq, CARD16 ref_div,
+				  CARD16 fb_div)
+{
+    unsigned vcoFreq;
+
+    vcoFreq = ((unsigned)reference_freq * fb_div) / ref_div;
+
+    /*
+     * This is horribly crude: the VCO frequency range is divided into
+     * 3 parts, each part having a fixed PLL gain value.
+     */
+    if (vcoFreq >= 30000)
+	/*
+	 * [300..max] MHz : 7
+	 */
+	return 7;
+    else if (vcoFreq >= 18000)
+	/*
+	 * [180..300) MHz : 4
+	 */
+        return 4;
+    else
+	/*
+	 * [0..180) MHz : 1
+	 */
+        return 1;
+}
+
 /* Write PLL registers */
 void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
-				      RADEONSavePtr restore)
+			       RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    CARD8 pllGain;
+
+    pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+				   restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+				   restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK);
 
     if (info->IsMobility) {
         /* A temporal workaround for the occational blanking on certain laptop panels.
@@ -4365,10 +4398,12 @@ void RADEONRestorePLLRegisters(ScrnInfoP
 	    RADEON_PPLL_CNTL,
 	    RADEON_PPLL_RESET
 	    | RADEON_PPLL_ATOMIC_UPDATE_EN
-	    | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN,
+	    | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+	    | ((CARD32)pllGain << RADEON_PPLL_PVG_SHIFT),
 	    ~(RADEON_PPLL_RESET
 	      | RADEON_PPLL_ATOMIC_UPDATE_EN
-	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
+	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN
+	      | RADEON_PPLL_PVG_MASK));
 
     OUTREGP(RADEON_CLOCK_CNTL_INDEX,
 	    RADEON_PLL_DIV_SEL,
@@ -4443,8 +4478,16 @@ void RADEONRestorePLLRegisters(ScrnInfoP
 
 /* Write PLL2 registers */
 void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
-				       RADEONSavePtr restore)
+				RADEONSavePtr restore)
 {
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    CARD8 pllGain;
+
+    pllGain = RADEONComputePLLGain(info->pll.reference_freq,
+                                   restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+                                   restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK);
+
+
     OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
 	    RADEON_PIX2CLK_SRC_SEL_CPUCLK,
 	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
@@ -4452,9 +4495,11 @@ void RADEONRestorePLL2Registers(ScrnInfo
     OUTPLLP(pScrn,
 	    RADEON_P2PLL_CNTL,
 	    RADEON_P2PLL_RESET
-	    | RADEON_P2PLL_ATOMIC_UPDATE_EN,
+	    | RADEON_P2PLL_ATOMIC_UPDATE_EN
+	    | ((CARD32)pllGain << RADEON_P2PLL_PVG_SHIFT),
 	    ~(RADEON_P2PLL_RESET
-	      | RADEON_P2PLL_ATOMIC_UPDATE_EN));
+	      | RADEON_P2PLL_ATOMIC_UPDATE_EN
+	      | RADEON_P2PLL_PVG_MASK));
 
 
     OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 9423bca..5fdda45 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -1225,6 +1225,8 @@
 #define RADEON_P2PLL_CNTL                   0x002a /* P2PLL */
 #       define RADEON_P2PLL_RESET                (1 <<  0)
 #       define RADEON_P2PLL_SLEEP                (1 <<  1)
+#       define RADEON_P2PLL_PVG_MASK             (7 << 11)
+#       define RADEON_P2PLL_PVG_SHIFT            11
 #       define RADEON_P2PLL_ATOMIC_UPDATE_EN     (1 << 16)
 #       define RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
 #       define RADEON_P2PLL_ATOMIC_UPDATE_VSYNC  (1 << 18)
@@ -1274,6 +1276,8 @@
 #define RADEON_PPLL_CNTL                    0x0002 /* PLL */
 #       define RADEON_PPLL_RESET                (1 <<  0)
 #       define RADEON_PPLL_SLEEP                (1 <<  1)
+#       define RADEON_PPLL_PVG_MASK             (7 << 11)
+#       define RADEON_PPLL_PVG_SHIFT            11
 #       define RADEON_PPLL_ATOMIC_UPDATE_EN     (1 << 16)
 #       define RADEON_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17)
 #       define RADEON_PPLL_ATOMIC_UPDATE_VSYNC  (1 << 18)
diff-tree 62f06d89da3f7160d5e4df8d7ce6fe1a94e9d07c (from 9cc3ab8320162f371bba15dc131f23c5de2013fc)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Jul 25 20:22:25 2007 -0400

    RADEON: write out saved vclk and pixclk values

diff --git a/src/radeon.h b/src/radeon.h
index c759b75..96c4632 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -281,7 +281,7 @@ typedef struct {
     unsigned          ppll_ref_div;
     unsigned          ppll_div_3;
     CARD32            htotal_cntl;
-    CARD32            vclk_cntl;
+    CARD32            vclk_ecp_cntl;
 
 				/* Computed values for PLL2 */
     CARD32            dot_clock_freq_2;
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 5bd2338..3518c9c 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -670,7 +670,7 @@ RADEONInitPLLRegisters(ScrnInfoPtr pScrn
     save->ppll_div_3     = (save->feedback_div | (post_div->bitvalue << 16));
     save->htotal_cntl    = 0;
 
-    save->vclk_cntl = (info->SavedReg.vclk_cntl &
+    save->vclk_ecp_cntl = (info->SavedReg.vclk_ecp_cntl &
 	    ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
 
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 36e14ff..d82e912 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4431,9 +4431,10 @@ void RADEONRestorePLLRegisters(ScrnInfoP
 
     usleep(50000); /* Let the clock to lock */
 
-    OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
+    /* OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
 	    RADEON_VCLK_SRC_SEL_PPLLCLK,
-	    ~(RADEON_VCLK_SRC_SEL_MASK));
+	    ~(RADEON_VCLK_SRC_SEL_MASK));*/
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, restore->vclk_ecp_cntl);
 
     ErrorF("finished PLL1\n");
 
@@ -4493,9 +4494,10 @@ void RADEONRestorePLL2Registers(ScrnInfo
 
     usleep(5000); /* Let the clock to lock */
 
-    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
+    /*OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
 	    RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
-	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));*/
+    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, restore->pixclks_cntl);
 
     ErrorF("finished PLL2\n");
 
@@ -4907,7 +4909,7 @@ static void RADEONSavePLLRegisters(ScrnI
     save->ppll_ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV);
     save->ppll_div_3   = INPLL(pScrn, RADEON_PPLL_DIV_3);
     save->htotal_cntl  = INPLL(pScrn, RADEON_HTOTAL_CNTL);
-    save->vclk_cntl    = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+    save->vclk_ecp_cntl = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "Read: 0x%08x 0x%08x 0x%08lx\n",
diff-tree 165a07cbbfcd94e3d1fac434b8fada8d29428a09 (from 18b00b47a483e7854727e99126808ddf361e7a4a)
Author: Brice Goglin <Brice.Goglin at ens-lyon.org>
Date:   Wed Jul 25 19:01:02 2007 +0200

    Minor fixes in the manpages
    
    - ati.man
      . add references to radeon and r128 manpages in SEE ALSO
        (Xavier Bestel in Debian bug #386001).
      . remove the manpage suffix from atimisc reference in the text
        since there is no such manpage for now.
    - radeon.man
      . typo in "specifying" (reported by A. Costa in Debian bug #432059).
      . replace a non-ascii character with the corresponding groff escape
        sequence so that it works whatever the locale (Julien Cristau).

diff --git a/man/ati.man b/man/ati.man
index bc33610..c6c7d01 100644
--- a/man/ati.man
+++ b/man/ati.man
@@ -17,7 +17,7 @@ ati \- ATI video driver
 is an __xservername__ wrapper driver for ATI video cards.  It autodetects
 whether your hardware has a Radeon, Rage 128, or Mach64 or earlier class of
 chipset, and loads the radeon(__drivermansuffix__),
-r128(__drivermansuffix__), or atimisc(__drivermansuffix__) driver as
+r128(__drivermansuffix__), or atimisc driver as
 appropriate.
 .SH SUPPORTED HARDWARE
 The
@@ -29,6 +29,6 @@ Please refer to __xconfigfile__(__filema
 details, and the specific card driver for driver configuration details.
 driver.
 .SH "SEE ALSO"
-__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
+__xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__), r128(__drivermansuffix__), radeon(__drivermansuffix__)
 .SH AUTHORS
 See the individual driver pages for authors.
diff --git a/man/radeon.man b/man/radeon.man
index 447dcbe..35b4929 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -535,7 +535,7 @@ remainder of video RAM is reserved for E
 results in all offscreen video RAM being reserved for EXA and only GART memory
 being available for OpenGL textures. This may improve EXA performance, but
 beware that it may cause problems with OpenGL drivers from Mesa versions older
-than 6.4. With XAA, specifiying lower percentage than what gets reserved without
+than 6.4. With XAA, specifying lower percentage than what gets reserved without
 this option has no effect, but the driver tries to increase the video RAM
 reserved for textures to the amount specified roughly.
 Default:
@@ -644,7 +644,7 @@ Kevin E. Martin          \fIkem at freedesk
 Alan Hourihane           \fIalanh at fairlite.demon.co.uk\fP
 Marc Aurele La France    \fItsi at xfree86.org\fP
 Benjamin Herrenschmidt   \fIbenh at kernel.crashing.org\fP
-Michel Dänzer            \fImichel at tungstengraphics.com\fP
+Michel D\(:anzer            \fImichel at tungstengraphics.com\fP
 Alex Deucher             \fIalexdeucher at gmail.com\fP
 Bogdan D.                \fIbogdand at users.sourceforge.net\fP
 Eric Anholt              \fIeric at anholt.net\fP
diff-tree 9cc3ab8320162f371bba15dc131f23c5de2013fc (from 193d58b0ea9de3e326017e50b88e2f3726854506)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Jul 25 02:24:14 2007 -0400

    RADEON: hack around console restore hang on r4xx
    
    r4xx seems to hang when unblanking the crtc(s) when
    restoring the console.  This needs to be investigated
    further.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 71e24ba..36e14ff 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5093,15 +5093,20 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     }
 #endif
 
-    /* need to make sure we don't enable a crtc by accident or we may get a hang */
     /*RADEONUnblank(pScrn);*/
-    if (info->crtc_on) {
-	crtc = xf86_config->crtc[0];
-	crtc->funcs->dpms(crtc, DPMSModeOn);
-    }
-    if (info->crtc2_on) {
-	crtc = xf86_config->crtc[1];
-	crtc->funcs->dpms(crtc, DPMSModeOn);
+    /* R4xx hangs when unblanking, but seems to restore fine without it. 
+     * This will probably cause problems with non-VGA consoles.
+     */
+    if (!info->IsAtomBios) {
+	/* need to make sure we don't enable a crtc by accident or we may get a hang */
+	if (info->crtc_on) {
+	    crtc = xf86_config->crtc[0];
+	    crtc->funcs->dpms(crtc, DPMSModeOn);
+	}
+	if (info->crtc2_on) {
+	    crtc = xf86_config->crtc[1];
+	    crtc->funcs->dpms(crtc, DPMSModeOn);
+	}
     }
 
 #if 0
diff-tree 193d58b0ea9de3e326017e50b88e2f3726854506 (from 262e32bd9ea4123b116362b33b5798753b2568fe)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Jul 25 01:27:58 2007 -0400

    RADEON: fix randr on r4xx
    
    Seems the way we parse the ATOM connector table results
    in reversed connectors.

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 10ef99f..26019ba 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -145,6 +145,7 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     int i = 0, j, tmp, tmp0=0, tmp1=0;
+    RADEONBIOSConnector tempConnector;
 
     if(!info->VBIOS) return FALSE;
 
@@ -225,6 +226,12 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 		    }
 		}
 	    }
+
+	    /* R4xx seem to get the connector table backwards */
+	    tempConnector = info->BiosConnector[0];
+	    info->BiosConnector[0] = info->BiosConnector[1];
+	    info->BiosConnector[1] = tempConnector;
+
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
 	    for (i=0; i<2; i++) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
diff-tree 262e32bd9ea4123b116362b33b5798753b2568fe (from 7b3e22e96cfc98621bd20fa76317e6d8f7242165)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jul 19 23:48:57 2007 -0400

    RADEON: fix palette when depth != 24

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index de060fb..5bd2338 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -872,23 +872,43 @@ void radeon_crtc_load_lut(xf86CrtcPtr cr
 
     PAL_SELECT(radeon_crtc->crtc_id);
 
-    for (i = 0; i < 256; i++) {
-	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+    if (pScrn->depth == 15) {
+	for (i = 0; i < 32; i++) {
+	    OUTPAL(i * 8, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+	}
+    } else if (pScrn->depth == 16) {
+	for (i = 0; i < 64; i++) {
+	    OUTPAL(i * 4, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+	}
+    } else {
+	for (i = 0; i < 256; i++) {
+	    OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+	}
     }
+
 }
 
 
 static void
-radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, 
+radeon_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green,
 		      CARD16 *blue, int size)
 {
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    ScrnInfoPtr		pScrn = crtc->scrn;
     int i;
 
-    for (i = 0; i < 256; i++) {
-	radeon_crtc->lut_r[i] = red[i] >> 8;
-	radeon_crtc->lut_g[i] = green[i] >> 8;
-	radeon_crtc->lut_b[i] = blue[i] >> 8;
+    if (pScrn->depth == 16) {
+	for (i = 0; i < 64; i++) {
+	    radeon_crtc->lut_r[i] = red[i/2] >> 8;
+	    radeon_crtc->lut_g[i] = green[i] >> 8;
+	    radeon_crtc->lut_b[i] = blue[i/2] >> 8;
+	}
+    } else {
+	for (i = 0; i < 256; i++) {
+	    radeon_crtc->lut_r[i] = red[i] >> 8;
+	    radeon_crtc->lut_g[i] = green[i] >> 8;
+	    radeon_crtc->lut_b[i] = blue[i] >> 8;
+	}
     }
 
     radeon_crtc_load_lut(crtc);
diff-tree 18b00b47a483e7854727e99126808ddf361e7a4a (from 882fe7631586b0a7919f808588a2ea4fb555f7e8)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jul 19 19:01:42 2007 -0400

    R128: don't clip modes to panel on laptops when only using the CRT port
    
    fixes bug 5832

diff --git a/src/r128_driver.c b/src/r128_driver.c
index b03bd42..6e26a6e 100644
--- a/src/r128_driver.c
+++ b/src/r128_driver.c
@@ -4257,6 +4257,9 @@ ModeStatus R128ValidMode(int scrnIndex, 
     ScrnInfoPtr   pScrn = xf86Screens[scrnIndex];
     R128InfoPtr   info  = R128PTR(pScrn);
 
+    if (info->BIOSDisplay == R128_BIOS_DISPLAY_CRT)
+	return MODE_OK;
+
     if(info->isDFP) {
         if(info->PanelXRes < mode->CrtcHDisplay ||
            info->PanelYRes < mode->CrtcVDisplay)
diff-tree 882fe7631586b0a7919f808588a2ea4fb555f7e8 (from ac9cbaf32176cf144bc694ac879e7c9e2920f762)
Author: Brice Goglin <brice.goglin at ens-lyon.org>
Date:   Thu Jul 19 18:44:27 2007 -0400

    MACH64: avoid crash in Xv code
    
    fixes bug 11054

diff --git a/src/atimach64xv.c b/src/atimach64xv.c
index 997fa69..67becec 100644
--- a/src/atimach64xv.c
+++ b/src/atimach64xv.c
@@ -979,6 +979,9 @@ ATIMach64PutImage
     if (pATI->ActiveSurface)
         return Success;
 
+    if (DstH < 16)
+	return Success;
+
     if (!ATIMach64ClipVideo(pScreenInfo, pATI, ImageID,
                             SrcX, SrcY, SrcW, SrcH,
                             DstX, DstY, &DstW, &DstH,
diff-tree 7b3e22e96cfc98621bd20fa76317e6d8f7242165 (from 2a35ccfb8ffee9f0ef6f8d4f0eeb80a471543caa)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jul 5 20:37:10 2007 -0400

    RADEON: set default values for crtc_offset_cntls

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 578da56..de060fb 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -185,8 +185,9 @@ RADEONInitCrtcBase(xf86CrtcPtr crtc, RAD
 #ifdef XF86DRI
     if (info->allowPageFlip)
 	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+    else
 #endif
-
+	save->crtc_offset_cntl = 0;
 
     if (info->tilingEnabled) {
        if (IS_R300_VARIANT)
@@ -415,7 +416,9 @@ RADEONInitCrtc2Base(xf86CrtcPtr crtc, RA
 #ifdef XF86DRI
     if (info->allowPageFlip)
 	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+    else
 #endif
+	save->crtc2_offset_cntl = 0;
 
     if (info->tilingEnabled) {
        if (IS_R300_VARIANT)
diff-tree 2a35ccfb8ffee9f0ef6f8d4f0eeb80a471543caa (from bdcae622100c81a4d9a53938542b64908bacd195)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jul 5 20:04:04 2007 -0400

    RADEON: Fix tiling on r1xx and r2xx
    
    spotted by Andrew Randrianasulu <randrik at mail.ru>
    fixes bug 11357

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index e1196b3..578da56 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -175,7 +175,6 @@ RADEONInitCrtcBase(xf86CrtcPtr crtc, RAD
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     int    Base;
 #ifdef XF86DRI
     RADEONSAREAPrivPtr pSAREAPriv;
@@ -223,7 +222,7 @@ RADEONInitCrtcBase(xf86CrtcPtr crtc, RAD
 		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;
+	     /*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
@@ -404,7 +403,6 @@ RADEONInitCrtc2Base(xf86CrtcPtr crtc, RA
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
     int    Base;
 #ifdef XF86DRI
     RADEONSAREAPrivPtr pSAREAPriv;
@@ -453,7 +451,7 @@ RADEONInitCrtc2Base(xf86CrtcPtr crtc, RA
 		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;
+	     /*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
diff-tree ac9cbaf32176cf144bc694ac879e7c9e2920f762 (from 5b5b90c2cea7e36895354f5872acd3fc769653f9)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jul 2 10:06:02 2007 +0200

    radeon: Fully zero-initialize info->CRT2pScrn->monitor.
    
    This prevents modes from getting rejected due to the uninitialized maxPixClock
    value.
    
    Fixes http://bugs.freedesktop.org/show_bug.cgi?id=9816 .

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 4e1868d..5c20b0e 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -7323,7 +7323,7 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 
     if(info->MergedFB) {
           /* fill in monitor */
-       info->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
+       info->CRT2pScrn->monitor = xcalloc(1, sizeof(MonRec));
        if(info->CRT2pScrn->monitor) {
           DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
           memcpy(info->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
diff-tree bdcae622100c81a4d9a53938542b64908bacd195 (from 21be0d3a1f4700572c6425800596785d6850626f)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri Jun 29 01:15:57 2007 -0400

    RADEON: save crtc on/off state for console restore
    
    - prevents a possible hang if console is only using 1 crtc

diff --git a/src/radeon.h b/src/radeon.h
index c8b18b0..c759b75 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -748,6 +748,10 @@ typedef struct {
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
     RADEONBIOSInitTable BiosTable;
 
+    /* save crtc state for console restore */
+    Bool              crtc_on;
+    Bool              crtc2_on;
+
     Rotation rotation;
     void (*PointerMoved)(int, int, int);
     CreateScreenResourcesProcPtr CreateScreenResources;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c555869..71e24ba 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3375,6 +3375,9 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     info->PaletteSavedOnVT = FALSE;
 
+    info->crtc_on = FALSE;
+    info->crtc2_on = FALSE;
+
     RADEONSave(pScrn);
 
     RADEONDisableDisplays(pScrn);
@@ -4812,6 +4815,13 @@ static void RADEONSaveCrtcRegisters(Scrn
 	save->disp_hw_debug    = INREG (RADEON_DISP_HW_DEBUG);
 	save->crtc2_gen_cntl   = INREG(RADEON_CRTC2_GEN_CNTL);
     }
+
+    /* track if the crtc is enabled for text restore */
+    if (save->crtc_ext_cntl & RADEON_CRTC_DISPLAY_DIS)
+	info->crtc_on = FALSE;
+    else
+	info->crtc_on = TRUE;
+
 }
 
 /* Read DAC registers */
@@ -4882,6 +4892,13 @@ static void RADEONSaveCrtc2Registers(Scr
     }
     
     save->disp2_merge_cntl      = INREG(RADEON_DISP2_MERGE_CNTL);
+
+    /* track if the crtc is enabled for text restore */
+    if (save->crtc2_gen_cntl & RADEON_CRTC2_DISP_DIS)
+	info->crtc2_on = FALSE;
+    else
+	info->crtc2_on = TRUE;
+
 }
 
 /* Read PLL registers */
@@ -5015,6 +5032,8 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  restore    = &info->SavedReg;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcPtr crtc;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONRestore\n");
@@ -5073,19 +5092,18 @@ void RADEONRestore(ScrnInfoPtr pScrn)
        vgaHWLock(hwp);
     }
 #endif
-#if 0
-    {
-        xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-	int i;
-	for (i = 0; i <= xf86_config->num_crtc; i++) {
-		if (i == 0)
-			xf86_config->crtc[i]->enabled = 1;
-		else
-			xf86_config->crtc[i]->enabled = 0;
-    	}
+
+    /* need to make sure we don't enable a crtc by accident or we may get a hang */
+    /*RADEONUnblank(pScrn);*/
+    if (info->crtc_on) {
+	crtc = xf86_config->crtc[0];
+	crtc->funcs->dpms(crtc, DPMSModeOn);
+    }
+    if (info->crtc2_on) {
+	crtc = xf86_config->crtc[1];
+	crtc->funcs->dpms(crtc, DPMSModeOn);
     }
-#endif
-    RADEONUnblank(pScrn);
+
 #if 0
     RADEONWaitForVerticalSync(pScrn);
 #endif
diff-tree 21be0d3a1f4700572c6425800596785d6850626f (from d9bf28b55d98fea2d285c9c46362aaf2175d0a46)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri Jun 29 00:38:50 2007 -0400

    RADEON: simplify console restore
    
    - still need to track crtcs for blank/unblank when restoring text console

diff --git a/src/radeon.h b/src/radeon.h
index a3aa074..c8b18b0 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -238,7 +238,7 @@ typedef struct {
 
 				/* CRTC2 registers */
     CARD32            crtc2_gen_cntl;
-
+    CARD32            dac_macro_cntl;
     CARD32            dac2_cntl;
     CARD32            disp_output_cntl;
     CARD32            disp_tv_out_cntl;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 655e8ee..c555869 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4118,6 +4118,8 @@ void RADEONRestoreDACRegisters(ScrnInfoP
 	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
     }
 
+    OUTREG(RADEON_DAC_MACRO_CNTL, restore->dac_macro_cntl);
+
     /* R200 DAC connected via DVO */
     if (info->ChipFamily == CHIP_FAMILY_R200)
 	OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
@@ -4678,23 +4680,6 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
-void
-RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
-{
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    xf86CrtcPtr crtc = pRADEONEnt->pCrtc[crtc_num];
-    int i;
-
-    /* get the output connected to this CRTC */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc) {
-	    RADEONEnableDisplay(output, TRUE);
-	}
-    }
-}
-
 /* Write out state to define a new video mode */
 void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
@@ -4703,25 +4688,6 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONRestoreMode(%p)\n", restore);
 
-    /* For Non-dual head card, we don't have private field in the Entity */
-    if (!pRADEONEnt->HasCRTC2) {
-	RADEONRestoreMemMapRegisters(pScrn, restore);
-	RADEONRestoreCommonRegisters(pScrn, restore);
-	RADEONRestoreCrtcRegisters(pScrn, restore);
-	RADEONRestoreRMXRegisters(pScrn, restore);
-	RADEONRestoreFPRegisters(pScrn, restore);
-	RADEONRestoreFP2Registers(pScrn, restore);
-	RADEONRestoreLVDSRegisters(pScrn, restore);
-	RADEONRestoreDACRegisters(pScrn, restore);
-	RADEONRestorePLLRegisters(pScrn, restore);
-	return;
-    }
-
-    /* Disable all outputs at initial mode set.  the ones we want will
-       get set by RADEONEnableDisplay()
-     */
-    RADEONDisableDisplays(pScrn);
-
     /* When changing mode with Dual-head card, care must be taken for
      * the special order in setting registers. CRTC2 has to be set
      * before changing CRTC_EXT register.  In the dual-head setup, X
@@ -4736,8 +4702,11 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
      */
     RADEONRestoreMemMapRegisters(pScrn, restore);
     RADEONRestoreCommonRegisters(pScrn, restore);
-    RADEONRestoreCrtc2Registers(pScrn, restore);
-    RADEONRestorePLL2Registers(pScrn, restore);
+
+    if (pRADEONEnt->HasCRTC2) {
+	RADEONRestoreCrtc2Registers(pScrn, restore);
+	RADEONRestorePLL2Registers(pScrn, restore);
+    }
 
     RADEONRestoreCrtcRegisters(pScrn, restore);
     RADEONRestorePLLRegisters(pScrn, restore);
@@ -4747,9 +4716,6 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     RADEONRestoreLVDSRegisters(pScrn, restore);
     RADEONRestoreDACRegisters(pScrn, restore);
 
-    RADEONEnableOutputs(pScrn, 0);
-    RADEONEnableOutputs(pScrn, 1);
-
 #if 0
     RADEONRestorePalette(pScrn, &info->SavedReg);
 #endif
@@ -4860,7 +4826,7 @@ static void RADEONSaveDACRegisters(ScrnI
     save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
     save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
     save->disp_hw_debug         = INREG(RADEON_DISP_HW_DEBUG);
-
+    save->dac_macro_cntl        = INREG(RADEON_DAC_MACRO_CNTL);
 }
 
 /* Read flat panel registers */
@@ -4881,9 +4847,6 @@ static void RADEONSaveFPRegisters(ScrnIn
     save->bios_5_scratch       = INREG(RADEON_BIOS_5_SCRATCH);
     save->bios_6_scratch       = INREG(RADEON_BIOS_6_SCRATCH);
 
-    save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
-    save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
-
     if (info->ChipFamily == CHIP_FAMILY_RV280) {
 	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
 	save->tmds_pll_cntl ^= (1 << 22);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 5585345..e431bf5 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -857,6 +857,8 @@ static void RADEONInitDACRegisters(xf86O
     save->dac_cntl = (RADEON_DAC_MASK_ALL
 		      | RADEON_DAC_VGA_ADR_EN
 		      | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
+
+    save->dac_macro_cntl = info->SavedReg.dac_macro_cntl;
 }
 
 /* XXX: fix me */
diff-tree d9bf28b55d98fea2d285c9c46362aaf2175d0a46 (from 9f193985627be8e6ea1418a424e825ddbc4957b2)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jun 28 23:52:28 2007 -0400

    RADEON: factor out surface_cntl init into one function

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index df75bc3..e1196b3 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -143,6 +143,32 @@ RADEONInitCommonRegisters(RADEONSavePtr 
 	save->bus_cntl |= RADEON_BUS_RD_DISCARD_EN;
 }
 
+static void
+RADEONInitSurfaceCntl(xf86CrtcPtr crtc, RADEONSavePtr save)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+
+    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
+
+}
+
 static Bool
 RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
 		   int x, int y)
@@ -301,27 +327,9 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 			    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)) {
@@ -577,25 +585,6 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
     save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
     save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
 
-    /* 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 */
@@ -798,6 +787,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     ErrorF("init common\n");
     RADEONInitCommonRegisters(&info->ModeReg, info);
 
+    RADEONInitSurfaceCntl(crtc, &info->ModeReg);
+
     switch (radeon_crtc->crtc_id) {
     case 0:
 	ErrorF("init crtc1\n");
diff-tree 9f193985627be8e6ea1418a424e825ddbc4957b2 (from 0f361e9e80a29d287fa42436c32c657e3c102539)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jun 28 23:43:13 2007 -0400

    RADEON: move crtc base setups to new functions

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index d7eadd8..df75bc3 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -143,25 +143,131 @@ RADEONInitCommonRegisters(RADEONSavePtr 
 	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)
+RADEONInitCrtcBase(xf86CrtcPtr crtc, RADEONSavePtr save,
+		   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
 
+    save->crtc_offset      = pScrn->fbOffset;
+#ifdef XF86DRI
+    if (info->allowPageFlip)
+	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
+
+
+    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;
+    }
+
+    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;
+
+    return TRUE;
+
+}
+
+/* Define CRTC registers for requested video mode */
+static Bool
+RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
+			DisplayModePtr mode)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int    format;
+    int    hsync_start;
+    int    hsync_wid;
+    int    vsync_wid;
+
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
     case 8:  format = 2; break;
@@ -254,39 +360,74 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 				     ? RADEON_CRTC_V_SYNC_POL
 				     : 0));
 
-    save->crtc_offset      = pScrn->fbOffset;
+    save->crtc_pitch  = (((pScrn->displayWidth * pScrn->bitsPerPixel) +
+			  ((pScrn->bitsPerPixel * 8) -1)) /
+			 (pScrn->bitsPerPixel * 8));
+    save->crtc_pitch |= save->crtc_pitch << 16;
+    
+    save->fp_h_sync_strt_wid = save->crtc_h_sync_strt_wid;
+    save->fp_v_sync_strt_wid = save->crtc_v_sync_strt_wid;
+    save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
+    save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
+
+    if (info->IsDellServer) {
+	save->dac2_cntl = info->SavedReg.dac2_cntl;
+	save->tv_dac_cntl = info->SavedReg.tv_dac_cntl;
+	save->crtc2_gen_cntl = info->SavedReg.crtc2_gen_cntl;
+	save->disp_hw_debug = info->SavedReg.disp_hw_debug;
+
+	save->dac2_cntl &= ~RADEON_DAC2_DAC_CLK_SEL;
+	save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+
+	/* For CRT on DAC2, don't turn it on if BIOS didn't
+	   enable it, even it's detected.
+	*/
+	save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+	save->tv_dac_cntl &= ~((1<<2) | (3<<8) | (7<<24) | (0xff<<16));
+	save->tv_dac_cntl |= (0x03 | (2<<8) | (0x58<<16));
+    }
+
+    return TRUE;
+}
+
+static Bool
+RADEONInitCrtc2Base(xf86CrtcPtr crtc, RADEONSavePtr save,
+		    int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int    Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
+
+    /* It seems all fancy options apart from pflip can be safely disabled
+     */
+    save->crtc2_offset      = pScrn->fbOffset;
 #ifdef XF86DRI
     if (info->allowPageFlip)
-	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
 #endif
 
     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);
+          save->crtc2_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->crtc2_offset_cntl |= RADEON_CRTC_TILE_EN;
     }
     else {
        if (IS_R300_VARIANT)
-          save->crtc_offset_cntl &= ~(R300_CRTC_X_Y_MODE_EN |
+          save->crtc2_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->crtc2_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) {
@@ -295,7 +436,7 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 	 * 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);
+             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
@@ -304,20 +445,20 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 		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;
+	     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->crtc_offset_cntl &= ~RADEON_CRTC_OFFSET_FLIP_CNTL;
+		 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->crtc_offset_cntl = save->crtc_offset_cntl | (y % 16);
+             save->crtc2_offset_cntl = save->crtc_offset_cntl | (y % 16);
          }
     }
     else {
@@ -333,7 +474,6 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 
     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
@@ -345,37 +485,14 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 	/* 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;
+	pSAREAPriv->crtc2_base = Base;
 
 	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));
-    }
+    save->crtc2_offset = Base;
 
     return TRUE;
 }
@@ -383,21 +500,14 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 /* Define CRTC2 registers for requested video mode */
 static Bool
 RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
-			 DisplayModePtr mode, int x, int y)
+			 DisplayModePtr mode)
 {
     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;
@@ -442,31 +552,6 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
 				      ? RADEON_CRTC2_V_SYNC_POL
 				      : 0));
 
-    /* It seems all fancy options apart from pflip can be safely disabled
-     */
-    save->crtc2_offset      = pScrn->fbOffset;
-#ifdef XF86DRI
-    if (info->allowPageFlip)
-	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
-#endif
-
-    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;
@@ -492,72 +577,6 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
     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
@@ -782,7 +801,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     switch (radeon_crtc->crtc_id) {
     case 0:
 	ErrorF("init crtc1\n");
-	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode, x, y);
+	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode);
+	RADEONInitCrtcBase(crtc, &info->ModeReg, x, y);
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll1\n");
@@ -795,7 +815,8 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	break;
     case 1:
 	ErrorF("init crtc2\n");
-        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode, x, y);
+        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode);
+	RADEONInitCrtc2Base(crtc, &info->ModeReg, x, y);
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll2\n");
diff-tree 0f361e9e80a29d287fa42436c32c657e3c102539 (from 1d4630067d293d26284d5fe230debef3913ec6cf)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jun 28 23:08:07 2007 -0400

    RADEON: fix corruption after 3D apps run

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 048175b..655e8ee 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2540,7 +2540,7 @@ RADEONCRTCResize(ScrnInfoPtr scrn, int w
 {
     scrn->virtualX = width;
     scrn->virtualY = height;
-    RADEONSetPitch(scrn);
+    /* RADEONSetPitch(scrn); */
     return TRUE;
 }
 
@@ -2792,7 +2792,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     ErrorF("after xf86InitialConfiguration\n");
 
-   RADEONSetPitch(pScrn);
+    RADEONSetPitch(pScrn);
 
    /* Set display resolution */
    xf86SetDpi(pScrn, 0, 0);
diff-tree 1d4630067d293d26284d5fe230debef3913ec6cf (from 2754d1ba01fc3367019487e0c0f59d74c950aaa7)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jun 28 22:24:04 2007 -0400

    RADEON: set info->CurrentLayout.displayWidth in RADEONSetPitch()

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 42565e4..048175b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2810,8 +2810,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     if (!RADEONPreInitXv(pScrn))                 goto fail;
 
-   info->CurrentLayout.displayWidth = pScrn->displayWidth;
-
     if (!xf86RandR12PreInit (pScrn))
     {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 6952dd5..66d8a7f 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -74,6 +74,8 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
 	break;
     }
     pScrn->displayWidth = dummy;
+    info->CurrentLayout.displayWidth = pScrn->displayWidth;
+
 }
 
 /* This is used only when no mode is specified for FP and no ddc is
diff-tree 2754d1ba01fc3367019487e0c0f59d74c950aaa7 (from 7901bcafa92dccd319ddb5de4627d806a39f15f9)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jun 28 22:15:22 2007 -0400

    RADEON: Switch cursor back to memcpy()

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index e59d2b3..f19f2bc 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -219,8 +219,6 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
-    int            x, y, w, h;
-    CARD32	  *i;
 
     RADEONCTRACE(("RADEONLoadCursorARGB\n"));
 
@@ -228,14 +226,7 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt
 
     CURSOR_SWAPPING_START();
 
-    w = CURSOR_WIDTH;
-    h = CURSOR_HEIGHT;
-    for (y = 0; y < h; y++) {
-	i = image;
-	image += w;
-	for (x = 0; x < w; x++)
-	    *d++ = *i++;
-    }
+    memcpy (d, image, CURSOR_HEIGHT * CURSOR_WIDTH * 4);
 
     CURSOR_SWAPPING_END ();
 }
diff-tree 7901bcafa92dccd319ddb5de4627d806a39f15f9 (from 6a3599d6155d073a3116c4b13bdf04b44bb9e087)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 25 18:39:14 2007 -0400

    RADEON: make sure we unblank in RADEONRestore()
    
    reported by Andrew Randrianasulu (bugs 11357, 11146)

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ea235c1..42565e4 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5123,8 +5123,8 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 			xf86_config->crtc[i]->enabled = 0;
     	}
     }
-    RADEONUnblank(pScrn);
 #endif
+    RADEONUnblank(pScrn);
 #if 0
     RADEONWaitForVerticalSync(pScrn);
 #endif
diff-tree 6a3599d6155d073a3116c4b13bdf04b44bb9e087 (from 771c37fcac8104b894120cc3fc0154b31b0318d1)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 25 18:20:54 2007 -0400

    RADEON: make sure we set the stride properly

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index bee23f0..ea235c1 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2540,6 +2540,7 @@ RADEONCRTCResize(ScrnInfoPtr scrn, int w
 {
     scrn->virtualX = width;
     scrn->virtualY = height;
+    RADEONSetPitch(scrn);
     return TRUE;
 }
 
@@ -2791,7 +2792,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     ErrorF("after xf86InitialConfiguration\n");
 
-   pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+   RADEONSetPitch(pScrn);
 
    /* Set display resolution */
    xf86SetDpi(pScrn, 0, 0);
diff-tree 771c37fcac8104b894120cc3fc0154b31b0318d1 (from 01bd5eb713500d3e3d4351865d460c8d1e476454)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 25 17:53:26 2007 -0400

    RADEON: attempt to fix cursor on big endian (only tested on x86)

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 98f4560..e59d2b3 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -219,10 +219,8 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt
     RADEONInfoPtr  info       = RADEONPTR(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"));
 
@@ -230,30 +228,14 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt
 
     CURSOR_SWAPPING_START();
 
-
-    memcpy (d, image, CURSOR_HEIGHT * CURSOR_WIDTH * 4);
-#if 0
-    w = pCurs->bits->width;
-    if (w > CURSOR_WIDTH)
-	w = CURSOR_WIDTH;
-    h = pCurs->bits->height;
-    if (h > CURSOR_HEIGHT)
-	h = CURSOR_HEIGHT;
-    for (y = 0; y < h; y++)
-    {
+    w = CURSOR_WIDTH;
+    h = CURSOR_HEIGHT;
+    for (y = 0; y < h; y++) {
 	i = image;
-	image += pCurs->bits->width;
+	image += w;
 	for (x = 0; x < w; x++)
 	    *d++ = *i++;
-	/* pad to the right with transparent */
-	for (; x < CURSOR_WIDTH; x++)
-	    *d++ = 0;
     }
-    /* pad below with transparent */
-    for (; y < CURSOR_HEIGHT; y++)
-	for (x = 0; x < CURSOR_WIDTH; x++)
-	    *d++ = 0;
-#endif
 
     CURSOR_SWAPPING_END ();
 }
diff-tree 5b5b90c2cea7e36895354f5872acd3fc769653f9 (from 92e65d5e0d6817ff4c9a08020a0a9b3a8c3c98b0)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 25 16:27:54 2007 -0400

    RADEON: fix possible segfault on mobility chips with MM tables
    
    spotted by Stefan Buehler

diff --git a/src/radeon_video.c b/src/radeon_video.c
index 390df89..2f8bec5 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1189,17 +1189,11 @@ static void RADEONSetupTheatre(ScrnInfoP
 
     /* Go and find Rage Theatre, if it exists */
     
-    switch(info->Chipset){
-    	case PCI_CHIP_RADEON_LY:
-	case PCI_CHIP_RADEON_LZ:
-	        xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M6, not scanning for Rage Theatre\n");
-		break;
-	case PCI_CHIP_RADEON_LW:
-	        xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M7, not scanning for Rage Theatre\n");
-		break;
-	default:
-	    pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
-	}
+    if (info->IsMobility)
+	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
+    else
+	pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
+
 
     if(pPriv->theatre==NULL)return;
     
diff-tree 01bd5eb713500d3e3d4351865d460c8d1e476454 (from 52cc1dc1491559a9055f3ba6dd54064bb382ad86)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 25 16:16:18 2007 -0400

    RADEON: fix possible segfault on mobility chips with MM tables
    
    reported by Stefan Buehler

diff --git a/src/radeon_video.c b/src/radeon_video.c
index 95db9ef..dbf66da 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1188,17 +1188,10 @@ static void RADEONSetupTheatre(ScrnInfoP
 
     /* Go and find Rage Theatre, if it exists */
     
-    switch(info->Chipset){
-    	case PCI_CHIP_RADEON_LY:
-	case PCI_CHIP_RADEON_LZ:
-	        xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M6, not scanning for Rage Theatre\n");
-		break;
-	case PCI_CHIP_RADEON_LW:
-	        xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility M7, not scanning for Rage Theatre\n");
-		break;
-	default:
-	    pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
-	}
+    if (info->IsMobility)
+	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Detected Radeon Mobility, not scanning for Rage Theatre\n");
+    else
+	pPriv->theatre=xf86_DetectTheatre(pPriv->VIP);
 
     if(pPriv->theatre==NULL)return;
     
diff-tree 52cc1dc1491559a9055f3ba6dd54064bb382ad86 (from 3bb46c03fddd3bd79bdab887366aeeced0290a3a)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 25 15:49:19 2007 -0400

    RADEON: tiling and FB size fixes
    
    - fix tiling on older radeons
    - allow the user to specify FB size using Virtual line in config
    Current default is 1600x1200
    - reset ecp_div for Xv in randr crtc mode set

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index bee05e2..d7eadd8 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -746,9 +746,25 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONMonitorType montype = MT_NONE;
+    Bool           tilingOld   = info->tilingEnabled;
     int i = 0;
     double         dot_clock = 0;
 
+
+    if (info->allowColorTiling) {
+        info->tilingEnabled = (adjusted_mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
+#ifdef XF86DRI	
+	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
+	    RADEONSAREAPrivPtr pSAREAPriv;
+	  if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_SWITCH_TILING, (info->tilingEnabled ? 1 : 0)) < 0)
+  	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			 "[drm] failed changing tiling status\n");
+	    pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
+	    info->tilingEnabled = pSAREAPriv->tiling_enabled ? TRUE : FALSE;
+	}
+#endif
+    }
+
     for (i = 0; i < xf86_config->num_output; i++) {
 	xf86OutputPtr output = xf86_config->output[i];
 	RADEONOutputPrivatePtr radeon_output = output->driver_private;
@@ -811,6 +827,17 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
 
+    if (info->tilingEnabled != tilingOld) {
+	/* need to redraw front buffer, I guess this can be considered a hack ? */
+	xf86EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+	RADEONChangeSurfaces(pScrn);
+	xf86EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+	/* xf86SetRootClip would do, but can't access that here */
+    }
+
+    /* reset ecp_div for Xv */
+    info->ecp_div = -1;
+
 }
 
 static void
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 7434936..bee23f0 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2261,6 +2261,7 @@ static void RADEONPreInitColorTiling(Scr
     info->allowColorTiling = xf86ReturnOptValBool(info->Options,
 				        OPTION_COLOR_TILING, TRUE);
     if (IS_R300_VARIANT) {
+	/* this may be 4096 on r4xx -- need to double check */
 	info->MaxSurfaceWidth = 3968; /* one would have thought 4096...*/
 	info->MaxLines = 4096;
     } else {
@@ -2554,6 +2555,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     void *int10_save = NULL;
     const char *s;
     MessageType from;
+    int crtc_max_X, crtc_max_Y;
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONPreInit\n");
@@ -2750,8 +2752,28 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     RADEONPreInitColorTiling(pScrn);
 
-    xf86CrtcSetSizeRange (pScrn, 320, 200, 2708, 1200);//nfo->MaxSurfaceWidth, info->MaxLines);
+    /* we really need an FB manager... */
+    if (pScrn->display->virtualX) {
+	crtc_max_X = pScrn->display->virtualX;
+	crtc_max_Y = pScrn->display->virtualY;
+	if (info->allowColorTiling) {
+	    if (crtc_max_X > info->MaxSurfaceWidth)
+		crtc_max_X = info->MaxSurfaceWidth;
+	    if (crtc_max_Y > info->MaxLines)
+		crtc_max_Y = info->MaxLines;
+	} else {
+	    if (crtc_max_X > 8192)
+		crtc_max_X = 8192;
+	    if (crtc_max_Y > 8192)
+		crtc_max_Y = 8192;
+	}
+    } else {
+	crtc_max_X = 1600;
+	crtc_max_Y = 1200;
+    }
 
+    /*xf86CrtcSetSizeRange (pScrn, 320, 200, info->MaxSurfaceWidth, info->MaxLines);*/
+    xf86CrtcSetSizeRange (pScrn, 320, 200, crtc_max_X, crtc_max_Y);
 
     RADEONPreInitDDC(pScrn);
 
diff-tree 3bb46c03fddd3bd79bdab887366aeeced0290a3a (from b9fac5695bf8f123b391e3b162c4865258a685dd)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri Jun 22 01:12:38 2007 -0400

    RADEON: bump crtc max to 1200 so 1600x1200 will work out of the box
    
    - a better fix will be forthcoming...

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 08157d1..7434936 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2750,7 +2750,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     RADEONPreInitColorTiling(pScrn);
 
-    xf86CrtcSetSizeRange (pScrn, 320, 200, 2708, 1152);//nfo->MaxSurfaceWidth, info->MaxLines);
+    xf86CrtcSetSizeRange (pScrn, 320, 200, 2708, 1200);//nfo->MaxSurfaceWidth, info->MaxLines);
 
 
     RADEONPreInitDDC(pScrn);
diff-tree b9fac5695bf8f123b391e3b162c4865258a685dd (from ec1fd2c388ec2c4033644776ee8588405a3d25f1)
Author: Andrew Randrianasulu <randrik at mail.ru>
Date:   Fri Jun 22 01:01:14 2007 -0400

    RADEON: Fix VT switch hangs
    
    - re-order DRI resume functions in EnterVT()
    - fixes bug 11287

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 8f6ff2b..08157d1 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5482,10 +5482,10 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     	}
 
 	/* get the DRI back into shape after resume */
+	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
 	RADEONDRIResume(pScrn->pScreen);
 	RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
 
-	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
     }
 #endif
     /* this will get XVideo going again, but only if XVideo was initialised
diff-tree 92e65d5e0d6817ff4c9a08020a0a9b3a8c3c98b0 (from b72ff160f908bf3aa9f64705377e92d80360a4f7)
Author: Andrew Randrianasulu <randrik at mail.ru>
Date:   Fri Jun 22 00:55:00 2007 -0400

    RADEON: Fix VT switch hangs
    
    - reorder RADEONDRISetVBlankInterrupt() and RADEONDRIResume()
    - see bug 11287

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index caa478e..4e1868d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6931,10 +6931,9 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     	}
 
 	/* get the DRI back into shape after resume */
+	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
 	RADEONDRIResume(pScrn->pScreen);
 	RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
-
-	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
     }
 #endif
     /* this will get XVideo going again, but only if XVideo was initialised
diff-tree ec1fd2c388ec2c4033644776ee8588405a3d25f1 (from 0f5a92667281ca3f80218bc67d4031125a5e4793)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 19 00:39:59 2007 -0400

    RADEON: Split FP reg restore to only touch regs relevant to the output
    
    - only restore output specific regs
    - restore fp2_gen_cntl on R200 DAC restore as R200 DAC2 is connected via
    DVO

diff --git a/src/radeon.h b/src/radeon.h
index f1b2fa3..a3aa074 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -837,6 +837,12 @@ extern void        RADEONRestoreDACRegis
 					     RADEONSavePtr restore);
 extern void        RADEONRestoreFPRegisters(ScrnInfoPtr pScrn,
 					    RADEONSavePtr restore);
+extern void        RADEONRestoreFP2Registers(ScrnInfoPtr pScrn,
+					     RADEONSavePtr restore);
+extern void        RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn,
+					      RADEONSavePtr restore);
+extern void        RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn,
+					     RADEONSavePtr restore);
 extern void        RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
 					     RADEONSavePtr restore);
 extern void        RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1fd71fc..8f6ff2b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4097,6 +4097,9 @@ void RADEONRestoreDACRegisters(ScrnInfoP
 	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
     }
 
+    /* R200 DAC connected via DVO */
+    if (info->ChipFamily == CHIP_FAMILY_R200)
+	OUTREG(RADEON_FP2_GEN_CNTL, restore->fp2_gen_cntl);
 }
 
 /* Write CRTC registers */
@@ -4197,7 +4200,7 @@ void RADEONRestoreCrtc2Registers(ScrnInf
 
 }
 
-/* Write flat panel registers */
+/* Write TMDS registers */
 void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -4206,10 +4209,7 @@ void RADEONRestoreFPRegisters(ScrnInfoPt
 
     OUTREG(RADEON_TMDS_PLL_CNTL,        restore->tmds_pll_cntl);
     OUTREG(RADEON_TMDS_TRANSMITTER_CNTL,restore->tmds_transmitter_cntl);
-    OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
-    OUTREG(RADEON_FP_VERT_STRETCH,      restore->fp_vert_stretch);
     OUTREG(RADEON_FP_GEN_CNTL,          restore->fp_gen_cntl);
-    OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
 
     /* old AIW Radeon has some BIOS initialization problem
      * with display buffer underflow, only occurs to DFP
@@ -4218,8 +4218,41 @@ void RADEONRestoreFPRegisters(ScrnInfoPt
 	OUTREG(RADEON_GRPH_BUFFER_CNTL,
 	       INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
 
+}
+
+/* Write FP2 registers */
+void RADEONRestoreFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
+
+}
+
+/* Write RMX registers */
+void RADEONRestoreRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
+    OUTREG(RADEON_FP_VERT_STRETCH,      restore->fp_vert_stretch);
+
+}
+
+/* Write LVDS registers */
+void RADEONRestoreLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
     if (info->IsMobility) {
 	OUTREG(RADEON_LVDS_GEN_CNTL,  restore->lvds_gen_cntl);
+	/*OUTREG(RADEON_LVDS_PLL_CNTL,  restore->lvds_pll_cntl);*/  
 	OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
 	OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch);
 	OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch);
@@ -4654,7 +4687,10 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreMemMapRegisters(pScrn, restore);
 	RADEONRestoreCommonRegisters(pScrn, restore);
 	RADEONRestoreCrtcRegisters(pScrn, restore);
+	RADEONRestoreRMXRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
+	RADEONRestoreFP2Registers(pScrn, restore);
+	RADEONRestoreLVDSRegisters(pScrn, restore);
 	RADEONRestoreDACRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	return;
@@ -4684,7 +4720,10 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 
     RADEONRestoreCrtcRegisters(pScrn, restore);
     RADEONRestorePLLRegisters(pScrn, restore);
+    RADEONRestoreRMXRegisters(pScrn, restore);
     RADEONRestoreFPRegisters(pScrn, restore);
+    RADEONRestoreFP2Registers(pScrn, restore);
+    RADEONRestoreLVDSRegisters(pScrn, restore);
     RADEONRestoreDACRegisters(pScrn, restore);
 
     RADEONEnableOutputs(pScrn, 0);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 5c4a166..5585345 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -770,9 +770,11 @@ static void RADEONInitLVDSRegisters(xf86
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
 
+    save->lvds_pll_cntl = info->SavedReg.lvds_pll_cntl;
+
     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);
+    save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+    save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
 
     if (IsPrimary)
 	save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
@@ -862,6 +864,7 @@ 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 &
@@ -973,9 +976,20 @@ radeon_mode_set(xf86OutputPtr output, Di
 
     switch(radeon_output->MonType) {
     case MT_LCD:
+	ErrorF("restore LVDS\n");
+	if (radeon_crtc->crtc_id == 0)
+	    RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
+	RADEONRestoreLVDSRegisters(pScrn, &info->ModeReg);
     case MT_DFP:
-	ErrorF("restore FP\n");
-	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+	if (radeon_crtc->crtc_id == 0)
+	    RADEONRestoreRMXRegisters(pScrn, &info->ModeReg);
+	if (radeon_output->TMDSType == TMDS_INT) {
+	    ErrorF("restore FP\n");
+	    RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+	} else {
+	    ErrorF("restore FP2\n");
+	    RADEONRestoreFP2Registers(pScrn, &info->ModeReg);
+	}
 	break;
     default:
 	ErrorF("restore dac\n");
diff-tree 0f5a92667281ca3f80218bc67d4031125a5e4793 (from 5868af53204e8fc210735e68e891e15085285629)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 18 23:35:21 2007 -0400

    RADEON: only touch LVDS on mobility chips

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7f280be..79fb352 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -287,19 +287,21 @@ void RADEONDisableDisplays(ScrnInfoPtr p
     OUTREG(RADEON_FP2_GEN_CNTL, tmp);
 
     /* LVDS */
-    tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-    if (info->IsMobility || info->IsIGP) {
-	/* Asic bug, when turning off LVDS_ON, we have to make sure
-	   RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-	 */
-	OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-    }
-    tmp = INREG(RADEON_LVDS_GEN_CNTL);
-    tmp |= RADEON_LVDS_DISPLAY_DIS;
-    tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
-    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-    if (info->IsMobility || info->IsIGP) {
-	OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+    if (info->IsMobility) {
+	tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+	if (info->IsMobility || info->IsIGP) {
+	    /* Asic bug, when turning off LVDS_ON, we have to make sure
+	       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+	    */
+	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+	}
+	tmp = INREG(RADEON_LVDS_GEN_CNTL);
+	tmp |= RADEON_LVDS_DISPLAY_DIS;
+	tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
+	OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+	if (info->IsMobility || info->IsIGP) {
+	    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+	}
     }
 
 }
diff-tree b72ff160f908bf3aa9f64705377e92d80360a4f7 (from 80313621ffa8c409ae63fc1b28c15fc4abdc3a7b)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 18 21:51:45 2007 -0400

    RADEON: only touch LVDS on mobility chips

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 0889582..6ae8862 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1561,19 +1561,21 @@ void RADEONDisableDisplays(ScrnInfoPtr p
     OUTREG(RADEON_FP2_GEN_CNTL, tmp);
 
     /* LVDS */
-    tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-    if (info->IsMobility || info->IsIGP) {
-	/* Asic bug, when turning off LVDS_ON, we have to make sure
-	   RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-	 */
-	OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-    }
-    tmp = INREG(RADEON_LVDS_GEN_CNTL);
-    tmp |= RADEON_LVDS_DISPLAY_DIS;
-    tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
-    OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-    if (info->IsMobility || info->IsIGP) {
-	OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+    if (info->IsMobility) {
+	tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+	if (info->IsMobility || info->IsIGP) {
+	    /* Asic bug, when turning off LVDS_ON, we have to make sure
+	       RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
+	    */
+	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
+	}
+	tmp = INREG(RADEON_LVDS_GEN_CNTL);
+	tmp |= RADEON_LVDS_DISPLAY_DIS;
+	tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
+	OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+	if (info->IsMobility || info->IsIGP) {
+	    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+	}
     }
 
 }
diff-tree 80313621ffa8c409ae63fc1b28c15fc4abdc3a7b (from f19a6f7ee5bf4ec632e7813359f167599c08e823)
Author: Henry Zhao <henryz at localhost.localdomain>
Date:   Fri Jun 15 17:00:05 2007 -0700

    Update CRT2pScrn->monitor->Last to reflect the
    last mode of CRT2pScrn. See bug 11278.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 071411b..caa478e 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -7349,6 +7349,7 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 	         currentm = newm;
 	         tempm = tempm->next;
 	  }
+	  info->CRT2pScrn->monitor->Last = currentm;
 
 	  /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */
 
diff-tree 5868af53204e8fc210735e68e891e15085285629 (from 4f2a1ba9c2fc20042d67132f986a86a9783a245e)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 12 23:53:48 2007 -0400

    RADEON: yet another LVDS...

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1064fda..1fd71fc 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4821,8 +4821,8 @@ static void RADEONSaveFPRegisters(ScrnIn
     save->bios_5_scratch       = INREG(RADEON_BIOS_5_SCRATCH);
     save->bios_6_scratch       = INREG(RADEON_BIOS_6_SCRATCH);
 
-    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-    save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+    save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+    save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
 
     if (info->ChipFamily == CHIP_FAMILY_RV280) {
 	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
diff-tree f19a6f7ee5bf4ec632e7813359f167599c08e823 (from 44748a826b52924a6e050215d8d62755e0ac7fb2)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 12 23:44:41 2007 -0400

    RADEON: additional LVDS off fix (missed in previous commit)

diff --git a/src/radeon_display.c b/src/radeon_display.c
index b2eaf09..0889582 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1569,8 +1569,8 @@ void RADEONDisableDisplays(ScrnInfoPtr p
 	OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
     }
     tmp = INREG(RADEON_LVDS_GEN_CNTL);
-    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-    tmp &= ~(RADEON_LVDS_BLON);
+    tmp |= RADEON_LVDS_DISPLAY_DIS;
+    tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
     OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
     if (info->IsMobility || info->IsIGP) {
 	OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
diff-tree 4f2a1ba9c2fc20042d67132f986a86a9783a245e (from 9fc416ce08cc5d74faa7b184e80ce43ed2f4fbee)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 12 23:41:24 2007 -0400

    RADEON: additional LVDS off fix (missed in previous commit)

diff --git a/src/radeon_display.c b/src/radeon_display.c
index f170406..7f280be 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -295,8 +295,8 @@ void RADEONDisableDisplays(ScrnInfoPtr p
 	OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
     }
     tmp = INREG(RADEON_LVDS_GEN_CNTL);
-    tmp |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-    tmp &= ~(RADEON_LVDS_BLON);
+    tmp |= RADEON_LVDS_DISPLAY_DIS;
+    tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
     OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
     if (info->IsMobility || info->IsIGP) {
 	OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
diff-tree 9fc416ce08cc5d74faa7b184e80ce43ed2f4fbee (from c4045cbc5e6975520efef422ce9df2a7d99a7ff4)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Jun 12 23:35:09 2007 -0400

    radeon: Fix panel size detection from registers with stretched mode programmed.

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 25d6c66..5c4a166 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1344,12 +1344,14 @@ RADEONGetPanelInfoFromReg (xf86OutputPtr
 
     radeon_output->PanelPwrDly = 200;
     if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
-	radeon_output->PanelYRes = (fp_vert_stretch>>12) + 1;
+	radeon_output->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
+				    RADEON_VERT_PANEL_SHIFT) + 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;
+	radeon_output->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
+				     RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
     } else {
 	radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
     }
diff-tree c4045cbc5e6975520efef422ce9df2a7d99a7ff4 (from 090888d3baf61a70640d28e99afdce20952cdea0)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 12 23:32:18 2007 -0400

    RADEON: make sure to clear RADEON_LVDS_ON when turning LVDS off
    
    - fixes bug 3483

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 18d8a01..f170406 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -406,11 +406,11 @@ void RADEONEnableDisplay(xf86OutputPtr o
 		OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
 	    }
             tmp = INREG(RADEON_LVDS_GEN_CNTL);
-            tmp |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-            tmp &= ~(RADEON_LVDS_BLON);
+            tmp |= RADEON_LVDS_DISPLAY_DIS;
+            tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
             OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-            save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-            save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+            save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+            save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
 	    if (info->IsMobility || info->IsIGP) {
 		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 	    }
diff-tree 090888d3baf61a70640d28e99afdce20952cdea0 (from 9dd9f09a9021653e5590d27bd7aa0e7af85416ad)
Author: Tormod Volden <bugzi06.fdo.tormod at xoxy.net>
Date:   Tue Jun 12 23:30:18 2007 -0400

    RADEON: limit PanelPwrDly to 2000 ms on ATOM bios as per legacy bios
    
    - fixes bug 11238

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index f55d161..10ef99f 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -415,6 +415,9 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86Outp
 	    radeon_output->VSyncWidth = RADEON_BIOS16(tmp+20);
 	    radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+40);
 
+	    if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
+		radeon_output->PanelPwrDly = 2000;
+
 	    radeon_output->Flags = 0;
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
 		       "LVDS Info:\n"
diff-tree 44748a826b52924a6e050215d8d62755e0ac7fb2 (from c292fc64499ff4cc135c07deda99cf4169f8fef4)
Author: Tormod Volden <bugzi06.fdo.tormod at xoxy.net>
Date:   Tue Jun 12 23:23:49 2007 -0400

    RADEON: limit PanelPwrDly to 2000 ms on ATOM bios as per legacy bios
    
    - fixes bug 11238

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index e62fb25..fefa6ff 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -432,6 +432,9 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfo
 	    info->VSyncWidth = RADEON_BIOS16(tmp+20);
 	    info->PanelPwrDly = RADEON_BIOS16(tmp+40);
 
+	    if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0)
+		info->PanelPwrDly = 2000;
+
 	    info->Flags = 0;
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
 		       "LVDS Info:\n"
diff-tree c292fc64499ff4cc135c07deda99cf4169f8fef4 (from c6a3286d6f6ddda89115d98d45665dadd78bf41d)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 12 23:20:18 2007 -0400

    RADEON: make sure RADEON_LVDS_ON is cleared when turning LVDS off
    
    - fixes bug 3483

diff --git a/src/radeon_display.c b/src/radeon_display.c
index acb4d30..b2eaf09 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1675,11 +1675,11 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
 		OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
 	    }
             tmp = INREG(RADEON_LVDS_GEN_CNTL);
-            tmp |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-            tmp &= ~(RADEON_LVDS_BLON);
+            tmp |= RADEON_LVDS_DISPLAY_DIS;
+            tmp &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
             OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-            save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
-            save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+            save->lvds_gen_cntl |= RADEON_LVDS_DISPLAY_DIS;
+            save->lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON);
 	    if (info->IsMobility || info->IsIGP) {
 		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 	    }
diff-tree c6a3286d6f6ddda89115d98d45665dadd78bf41d (from 7a6b3c0f77c69019268f585c51c3dcbcc99014d4)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:39:38 2007 +0200

    radeon: Fix panel size detection from registers with stretched mode programmed.

diff --git a/src/radeon_display.c b/src/radeon_display.c
index d501cdc..acb4d30 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -684,12 +684,14 @@ static void RADEONGetPanelInfoFromReg (S
 
     info->PanelPwrDly = 200;
     if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
-	info->PanelYRes = (fp_vert_stretch>>12) + 1;
+	info->PanelYRes = ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >>
+			   RADEON_VERT_PANEL_SHIFT) + 1;
     } else {
 	info->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
     }
     if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
-	info->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
+	info->PanelXRes = (((fp_horz_stretch & RADEON_HORZ_PANEL_SIZE) >>
+			    RADEON_HORZ_PANEL_SHIFT) + 1) * 8;
     } else {
 	info->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
     }
diff-tree 7a6b3c0f77c69019268f585c51c3dcbcc99014d4 (from f31fd9ce598841c505a0b5ed32bf124f49fea332)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:39:38 2007 +0200

    radeon: Don't loop indefinitely if no mode matches detected panel size.

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 90fdc54..d501cdc 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -863,8 +863,12 @@ static Bool RADEONGetLVDSInfo (ScrnInfoP
 		    info->Flags = 0;
 		    break;
 		}
-		tmp_mode = tmp_mode->next;
 	    }
+
+	    tmp_mode = tmp_mode->next;
+
+	    if (tmp_mode == pScrn->monitor->Modes)
+		break;
 	}
 	if ((info->DotClock == 0) && !pRADEONEnt->PortInfo[0]->MonInfo) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff-tree f31fd9ce598841c505a0b5ed32bf124f49fea332 (from 2d40fa55e8d7a1cfb204d66ca4a4d95a3b13d5b5)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon Jun 11 09:39:38 2007 +0200

    radeon: Fix some more ErrorFs when setting mode.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 91af1ec..071411b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6430,7 +6430,7 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
 
     if (crtc1 && (crtc_mask & 1)) {
     	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+		       "%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)%s%s%s%s%s%s%s\n",
 		       crtc1->name,
 		       crtc1->Clock/1000.0,
 
@@ -6444,19 +6444,18 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
 		       crtc1->VSyncEnd,
 		       crtc1->VTotal,
 		       pScrn->depth,
-		       pScrn->bitsPerPixel);
-    	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    	ErrorF("\n");
+		       pScrn->bitsPerPixel,
+		       (crtc1->Flags & V_DBLSCAN) ? " D" : "",
+		       (crtc1->Flags & V_CSYNC) ? " C" : "",
+		       (crtc1->Flags & V_INTERLACE) ? " I" : "",
+		       (crtc1->Flags & V_PHSYNC) ? " +H" : "",
+		       (crtc1->Flags & V_NHSYNC) ? " -H" : "",
+		       (crtc1->Flags & V_PVSYNC) ? " +V" : "",
+		       (crtc1->Flags & V_NVSYNC) ? " -V" : "");
     }
     if (crtc2 && (crtc_mask & 2)) {
         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		       "%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+		       "%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)%s%s%s%s%s%s%s\n",
 		       crtc2->name,
 		       crtc2->Clock/1000.0,
 
@@ -6470,15 +6469,14 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
 		       crtc2->CrtcVSyncEnd,
 		       crtc2->CrtcVTotal,
 		       pScrn->depth,
-		       pScrn->bitsPerPixel);
-        if (crtc2->Flags & V_DBLSCAN)   ErrorF(" D");
-        if (crtc2->Flags & V_CSYNC)     ErrorF(" C");
-        if (crtc2->Flags & V_INTERLACE) ErrorF(" I");
-        if (crtc2->Flags & V_PHSYNC)    ErrorF(" +H");
-        if (crtc2->Flags & V_NHSYNC)    ErrorF(" -H");
-        if (crtc2->Flags & V_PVSYNC)    ErrorF(" +V");
-        if (crtc2->Flags & V_NVSYNC)    ErrorF(" -V");
-    	ErrorF("\n");
+		       pScrn->bitsPerPixel,
+		       (crtc2->Flags & V_DBLSCAN) ? " D" : "",
+		       (crtc2->Flags & V_CSYNC) ? " C" : "",
+		       (crtc2->Flags & V_INTERLACE) ? " I" : "",
+		       (crtc2->Flags & V_PHSYNC) ? " +H" : "",
+		       (crtc2->Flags & V_NHSYNC) ? " -H" : "",
+		       (crtc2->Flags & V_PVSYNC) ? " +V" : "",
+		       (crtc2->Flags & V_NVSYNC) ? " -V" : "");
     }
 
     if (crtc1 && (crtc_mask & 1))
diff-tree 9dd9f09a9021653e5590d27bd7aa0e7af85416ad (from 9ad311eeb0ac2b70a862dbb9de278154ba9142ec)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu Jun 7 15:32:31 2007 -0400

    RADEON: fix some issues with bios table init code
    
    - fix some issues with bios table init code
    - re-org preinit to better handle bios table init of cards

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 543ccb9..f55d161 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -712,7 +712,7 @@ RADEONGetBIOSInitTableOffsets(ScrnInfoPt
 		    RADEONValidateBIOSOffset(pScrn, info->BiosTable.mem_config_offset);
 	    }
 	    if (info->BiosTable.mem_config_offset) {
-		info->BiosTable.mem_reset_offset = RADEON_BIOS16(info->BiosTable.mem_config_offset);
+		info->BiosTable.mem_reset_offset = info->BiosTable.mem_config_offset;
 		if (info->BiosTable.mem_reset_offset) {
 		    while (RADEON_BIOS8(info->BiosTable.mem_reset_offset))
 			info->BiosTable.mem_reset_offset++;
@@ -721,14 +721,14 @@ RADEONGetBIOSInitTableOffsets(ScrnInfoPt
 		}
 	    }
 	    if (info->BiosTable.mem_config_offset) {
-		info->BiosTable.short_mem_offset = RADEON_BIOS16(info->BiosTable.mem_config_offset);
+		info->BiosTable.short_mem_offset = info->BiosTable.mem_config_offset;
 		if ((info->BiosTable.short_mem_offset != 0) &&
 		    (RADEON_BIOS8(info->BiosTable.short_mem_offset - 2) <= 64))
 		    info->BiosTable.short_mem_offset +=
 			RADEON_BIOS8(info->BiosTable.short_mem_offset - 3);
 	    }
 	    if (info->BiosTable.rr2_offset) {
-		info->BiosTable.rr3_offset = RADEON_BIOS16(info->BiosTable.rr2_offset);
+		info->BiosTable.rr3_offset = info->BiosTable.rr2_offset;
 		if (info->BiosTable.rr3_offset) {
 		    while ((val = RADEON_BIOS8(info->BiosTable.rr3_offset + 1)) != 0) {
 			if (val & 0x40)
@@ -743,7 +743,7 @@ RADEONGetBIOSInitTableOffsets(ScrnInfoPt
 	    }
 
 	    if (info->BiosTable.rr3_offset) {
-		info->BiosTable.rr4_offset = RADEON_BIOS16(info->BiosTable.rr3_offset);
+		info->BiosTable.rr4_offset = info->BiosTable.rr3_offset;
 		if (info->BiosTable.rr4_offset) {
 		    while ((val = RADEON_BIOS8(info->BiosTable.rr4_offset + 1)) != 0) {
 			if (val & 0x40)
@@ -853,15 +853,15 @@ RADEONRestoreBIOSRegBlock(ScrnInfoPtr pS
 	    case RADEON_TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE:
 		count = RADEON_BIOS16(offset);
 		ErrorF("SCOMMAND_WAIT_MEM_PWRUP_COMPLETE %d\n", count);
+		/* may need to take into account how many memory channels
+		 * each card has
+		 */
+		if (IS_R300_VARIANT)
+		    channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
+		else
+		    channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
 		while (count--) {
 		    /* XXX: may need indexed access */
-		    /* may need to take into account how many memory channels
-		     * each card has
-		     */
-		    if (IS_R300_VARIANT)
-			channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
-		    else
-			channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
 		    if ((INREG(RADEON_MEM_STR_CNTL) &
 			 channel_complete_mask) ==
 		        channel_complete_mask)
@@ -894,15 +894,15 @@ RADEONRestoreBIOSMemBlock(ScrnInfoPtr pS
 	if (index == 0x0f) {
 	    count = 20000;
 	    ErrorF("MEM_WAIT_MEM_PWRUP_COMPLETE %d\n", count);
+	    /* may need to take into account how many memory channels
+	     * each card has
+	     */
+	    if (IS_R300_VARIANT)
+		channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
+	    else
+		channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
 	    while (count--) {
 		/* XXX: may need indexed access */
-		/* may need to take into account how many memory channels
-		 * each card has
-		 */
-		if (IS_R300_VARIANT)
-		    channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
-		else
-		    channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
 		if ((INREG(RADEON_MEM_STR_CNTL) &
 		     channel_complete_mask) ==
 		    channel_complete_mask)
@@ -948,7 +948,7 @@ RADEONRestoreBIOSPllBlock(ScrnInfoPtr pS
     if (offset == 0)
 	return;
 
-    while ((index = BIOS8(offset)) != 0) {
+    while ((index = RADEON_BIOS8(offset)) != 0) {
 	offset++;
 
 	switch (index & RADEON_PLL_FLAG_MASK) {
@@ -959,8 +959,8 @@ RADEONRestoreBIOSPllBlock(ScrnInfoPtr pS
 		usleep(150);
 		break;
 	    case RADEON_PLL_WAIT_5MS:
-		usleep(5000);
 		ErrorF("delay: 5 ms\n");
+		usleep(5000);
 		break;
 
 	    case RADEON_PLL_WAIT_MC_BUSY_MASK:
@@ -1001,15 +1001,15 @@ RADEONRestoreBIOSPllBlock(ScrnInfoPtr pS
 	    break;
 	    
 	case RADEON_PLL_FLAG_MASK_BYTE:
-	    shift = BIOS8(offset) * 8;
+	    shift = RADEON_BIOS8(offset) * 8;
 	    offset++;
 
 	    andmask =
-		(((CARD32)BIOS8(offset)) << shift) |
+		(((CARD32)RADEON_BIOS8(offset)) << shift) |
 		~((CARD32)0xff << shift);
 	    offset++;
 
-	    ormask = ((CARD32)BIOS8(offset)) << shift;
+	    ormask = ((CARD32)RADEON_BIOS8(offset)) << shift;
 	    offset++;
 
 	    ErrorF("PLL_MASK_BYTE 0x%x 0x%x 0x%x 0x%x\n", 
@@ -1041,32 +1041,32 @@ RADEONPostCardFromBIOSTables(ScrnInfoPtr
 	    return FALSE;
 	} else {
 	    if (info->BiosTable.rr1_offset) {
-		ErrorF("rr1 restore\n");
+		ErrorF("rr1 restore, 0x%x\n", info->BiosTable.rr1_offset);
 		RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr1_offset);
 	    }
 	    if (info->BiosTable.revision < 0x09) {
 		if (info->BiosTable.pll_offset) {
-		    ErrorF("pll restore\n");
+		    ErrorF("pll restore, 0x%x\n", info->BiosTable.pll_offset);
 		    RADEONRestoreBIOSPllBlock(pScrn, info->BiosTable.pll_offset);
 		}
 		if (info->BiosTable.rr2_offset) {
-		    ErrorF("rr2 restore\n");
+		    ErrorF("rr2 restore, 0x%x\n", info->BiosTable.rr2_offset);
 		    RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr2_offset);
 		}
 		if (info->BiosTable.rr4_offset) {
-		    ErrorF("rr4 restore\n");
+		    ErrorF("rr4 restore, 0x%x\n", info->BiosTable.rr4_offset);
 		    RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr4_offset);
 		}
 		if (info->BiosTable.mem_reset_offset) {
-		    ErrorF("mem reset restore\n");
+		    ErrorF("mem reset restore, 0x%x\n", info->BiosTable.mem_reset_offset);
 		    RADEONRestoreBIOSMemBlock(pScrn, info->BiosTable.mem_reset_offset);
 		}
 		if (info->BiosTable.rr3_offset) {
-		    ErrorF("rr3 restore\n");
+		    ErrorF("rr3 restore, 0x%x\n", info->BiosTable.rr3_offset);
 		    RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr3_offset);
 		}
 		if (info->BiosTable.dyn_clk_offset) {
-		    ErrorF("dyn_clk restore\n");
+		    ErrorF("dyn_clk restore, 0x%x\n", info->BiosTable.dyn_clk_offset);
 		    RADEONRestoreBIOSPllBlock(pScrn, info->BiosTable.dyn_clk_offset);
 		}
 	    }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 7d48650..1064fda 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2487,7 +2487,16 @@ static Bool RADEONPreInitXv(ScrnInfoPtr 
     return TRUE;
 }
 
-static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
+static void RADEONPreInitBIOS(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
+{
+    RADEONGetBIOSInfo(pScrn, pInt10);
+#if 0
+    RADEONGetBIOSInitTableOffsets(pScrn);
+    RADEONPostCardFromBIOSTables(pScrn);
+#endif
+}
+
+static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn)
 {
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     int i;
@@ -2495,8 +2504,6 @@ static Bool RADEONPreInitControllers(Scr
     if (!RADEONAllocateControllers(pScrn))
 	return FALSE;
 
-    RADEONGetBIOSInfo(pScrn, pInt10);
-
     RADEONGetClockInfo(pScrn);
 
     if (!RADEONSetupConnectors(pScrn)) {
@@ -2730,6 +2737,8 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     if (!RADEONPreInitChipType(pScrn))
 	goto fail;
 
+    RADEONPreInitBIOS(pScrn, pInt10);
+
 #ifdef XF86DRI
     /* PreInit DRI first of all since we need that for getting a proper
      * memory map
@@ -2746,7 +2755,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     RADEONPreInitDDC(pScrn);
 
-    if (!RADEONPreInitControllers(pScrn, pInt10))
+    if (!RADEONPreInitControllers(pScrn))
        goto fail;
 
 
diff-tree 9ad311eeb0ac2b70a862dbb9de278154ba9142ec (from 2527f2b69aa7dffa3ba4359c45955e3185bdf0e6)
Author: Tilman Sauerbeck <tilman at code-monkey.de>
Date:   Thu Jun 7 11:03:02 2007 +0200

    Fixed 'make dist'.

diff --git a/src/Makefile.am b/src/Makefile.am
index bdc2979..24665a4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -181,8 +181,6 @@ EXTRA_DIST = \
 	radeon_sarea.h \
 	radeon_version.h \
 	radeon_video.h \
-	radeon_xf86Modes.h \
-	radeon_xf86Crtc.h \
 	theatre200.h \
 	theatre_detect.h \
 	theatre.h \
diff-tree 2527f2b69aa7dffa3ba4359c45955e3185bdf0e6 (from e67d1420bf65055ecb6fdfe6b1b1f53aae83854a)
Author: Alex Deucher <alex at botch2.com>
Date:   Wed Jun 6 00:08:45 2007 -0400

    RADEON: implement support for posting cards based on x86 bios tables (untested)
    
    This is based on the netbsd radeonfb driver by Garrett D'Amore.
    The code is not hooked up yet, but should allow you to post cards
    without needing to execute bios code.  This should be useful on
    non-x86 platforms, for posting secndary cards, and for suspend/resume.
    Works on legacy bioses only (no ATOM support).

diff --git a/src/radeon.h b/src/radeon.h
index 260c413..f1b2fa3 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -174,6 +174,18 @@ typedef enum {
 #define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
 #define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
 
+typedef struct {
+    int    revision;
+    CARD16 rr1_offset;
+    CARD16 rr2_offset;
+    CARD16 dyn_clk_offset;
+    CARD16 pll_offset;
+    CARD16 mem_config_offset;
+    CARD16 mem_reset_offset;
+    CARD16 short_mem_offset;
+    CARD16 rr3_offset;
+    CARD16 rr4_offset;
+} RADEONBIOSInitTable;
 
 typedef struct {
 				/* Common registers */
@@ -734,6 +746,7 @@ typedef struct {
 
     Bool want_vblank_interrupts;
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
+    RADEONBIOSInitTable BiosTable;
 
     Rotation rotation;
     void (*PointerMoved)(int, int, int);
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 76b0a72..543ccb9 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -612,3 +612,465 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86Outp
     }
     return FALSE;
 }
+
+/* support for init from bios tables
+ *
+ * Based heavily on the netbsd radeonfb driver
+ * Written by Garrett D'Amore
+ * Copyright (c) 2006 Itronix Inc.
+ *
+ */
+
+/* bios table defines */
+
+#define RADEON_TABLE_ENTRY_FLAG_MASK    0xe000
+#define RADEON_TABLE_ENTRY_INDEX_MASK   0x1fff
+#define RADEON_TABLE_ENTRY_COMMAND_MASK 0x00ff
+
+#define RADEON_TABLE_FLAG_WRITE_INDEXED 0x0000
+#define RADEON_TABLE_FLAG_WRITE_DIRECT  0x2000
+#define RADEON_TABLE_FLAG_MASK_INDEXED  0x4000
+#define RADEON_TABLE_FLAG_MASK_DIRECT   0x6000
+#define RADEON_TABLE_FLAG_DELAY         0x8000
+#define RADEON_TABLE_FLAG_SCOMMAND      0xa000
+
+#define RADEON_TABLE_SCOMMAND_WAIT_MC_BUSY_MASK       0x03
+#define RADEON_TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE 0x08
+
+#define RADEON_PLL_FLAG_MASK      0xc0
+#define RADEON_PLL_INDEX_MASK     0x3f
+
+#define RADEON_PLL_FLAG_WRITE     0x00
+#define RADEON_PLL_FLAG_MASK_BYTE 0x40
+#define RADEON_PLL_FLAG_WAIT      0x80
+
+#define RADEON_PLL_WAIT_150MKS                    1
+#define RADEON_PLL_WAIT_5MS                       2
+#define RADEON_PLL_WAIT_MC_BUSY_MASK              3
+#define RADEON_PLL_WAIT_DLL_READY_MASK            4
+#define RADEON_PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24 5
+
+static CARD16
+RADEONValidateBIOSOffset(ScrnInfoPtr pScrn, CARD16 offset)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    CARD8 revision = RADEON_BIOS8(offset - 1);
+
+    if (revision > 0x10) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "Bad revision %d for BIOS table\n", revision);
+        return 0;
+    }
+
+    if (offset < 0x60) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                   "Bad offset 0x%x for BIOS Table\n", offset);
+        return 0;
+    }
+
+    return offset;
+}
+
+Bool
+RADEONGetBIOSInitTableOffsets(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    CARD8 val;
+
+    if (!info->VBIOS) {
+	return FALSE;
+    } else {
+	if (info->IsAtomBios) {
+	    return FALSE;
+	} else {
+	    info->BiosTable.revision = RADEON_BIOS8(info->ROMHeaderStart + 4);
+	    info->BiosTable.rr1_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x0c);
+	    if (info->BiosTable.rr1_offset) {
+		info->BiosTable.rr1_offset =
+		    RADEONValidateBIOSOffset(pScrn, info->BiosTable.rr1_offset);
+	    }
+	    if (info->BiosTable.revision > 0x09)
+		return TRUE;
+	    info->BiosTable.rr2_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x4e);
+	    if (info->BiosTable.rr2_offset) {
+		info->BiosTable.rr2_offset =
+		    RADEONValidateBIOSOffset(pScrn, info->BiosTable.rr2_offset);
+	    }
+	    info->BiosTable.dyn_clk_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x52);
+	    if (info->BiosTable.dyn_clk_offset) {
+		info->BiosTable.dyn_clk_offset =
+		    RADEONValidateBIOSOffset(pScrn, info->BiosTable.dyn_clk_offset);
+	    }
+	    info->BiosTable.pll_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x46);
+	    if (info->BiosTable.pll_offset) {
+		info->BiosTable.pll_offset =
+		    RADEONValidateBIOSOffset(pScrn, info->BiosTable.pll_offset);
+	    }
+	    info->BiosTable.mem_config_offset = RADEON_BIOS16(info->ROMHeaderStart + 0x48);
+	    if (info->BiosTable.mem_config_offset) {
+		info->BiosTable.mem_config_offset =
+		    RADEONValidateBIOSOffset(pScrn, info->BiosTable.mem_config_offset);
+	    }
+	    if (info->BiosTable.mem_config_offset) {
+		info->BiosTable.mem_reset_offset = RADEON_BIOS16(info->BiosTable.mem_config_offset);
+		if (info->BiosTable.mem_reset_offset) {
+		    while (RADEON_BIOS8(info->BiosTable.mem_reset_offset))
+			info->BiosTable.mem_reset_offset++;
+		    info->BiosTable.mem_reset_offset++;
+		    info->BiosTable.mem_reset_offset += 2;
+		}
+	    }
+	    if (info->BiosTable.mem_config_offset) {
+		info->BiosTable.short_mem_offset = RADEON_BIOS16(info->BiosTable.mem_config_offset);
+		if ((info->BiosTable.short_mem_offset != 0) &&
+		    (RADEON_BIOS8(info->BiosTable.short_mem_offset - 2) <= 64))
+		    info->BiosTable.short_mem_offset +=
+			RADEON_BIOS8(info->BiosTable.short_mem_offset - 3);
+	    }
+	    if (info->BiosTable.rr2_offset) {
+		info->BiosTable.rr3_offset = RADEON_BIOS16(info->BiosTable.rr2_offset);
+		if (info->BiosTable.rr3_offset) {
+		    while ((val = RADEON_BIOS8(info->BiosTable.rr3_offset + 1)) != 0) {
+			if (val & 0x40)
+			    info->BiosTable.rr3_offset += 10;
+			else if (val & 0x80)
+			    info->BiosTable.rr3_offset += 4;
+			else
+			    info->BiosTable.rr3_offset += 6;
+		    }
+		    info->BiosTable.rr3_offset += 2;
+		}
+	    }
+
+	    if (info->BiosTable.rr3_offset) {
+		info->BiosTable.rr4_offset = RADEON_BIOS16(info->BiosTable.rr3_offset);
+		if (info->BiosTable.rr4_offset) {
+		    while ((val = RADEON_BIOS8(info->BiosTable.rr4_offset + 1)) != 0) {
+			if (val & 0x40)
+			    info->BiosTable.rr4_offset += 10;
+			else if (val & 0x80)
+			    info->BiosTable.rr4_offset += 4;
+			else
+			    info->BiosTable.rr4_offset += 6;
+		    }
+		    info->BiosTable.rr4_offset += 2;
+		}
+	    }
+
+	    if (info->BiosTable.rr3_offset + 1 == info->BiosTable.pll_offset) {
+		info->BiosTable.rr3_offset = 0;
+		info->BiosTable.rr4_offset = 0;
+	    }
+
+	    return TRUE;
+
+	}
+    }
+}
+
+static void
+RADEONRestoreBIOSRegBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 offset = table_offset;
+    CARD16 value, flag, index, count;
+    CARD32 andmask, ormask, val, channel_complete_mask;
+    CARD8  command;
+
+    if (offset == 0)
+	return;
+
+    while ((value = RADEON_BIOS16(offset)) != 0) {
+	flag = value & RADEON_TABLE_ENTRY_FLAG_MASK;
+	index = value & RADEON_TABLE_ENTRY_INDEX_MASK;
+	command = value & RADEON_TABLE_ENTRY_COMMAND_MASK;
+
+	offset += 2;
+
+	switch (flag) {
+	case RADEON_TABLE_FLAG_WRITE_INDEXED:
+	    val = RADEON_BIOS32(offset);
+	    ErrorF("WRITE INDEXED: 0x%x 0x%x\n",
+		   index, val);
+	    OUTREG(RADEON_MM_INDEX, index);
+	    OUTREG(RADEON_MM_DATA, val);
+	    offset += 4;
+	    break;
+
+	case RADEON_TABLE_FLAG_WRITE_DIRECT:
+	    val = RADEON_BIOS32(offset);
+	    ErrorF("WRITE DIRECT: 0x%x 0x%x\n", index, val);
+	    OUTREG(index, val);
+	    offset += 4;
+	    break;
+
+	case RADEON_TABLE_FLAG_MASK_INDEXED:
+	    andmask = RADEON_BIOS32(offset);
+	    offset += 4;
+	    ormask = RADEON_BIOS32(offset);
+	    offset += 4;
+	    ErrorF("MASK INDEXED: 0x%x 0x%x 0x%x\n",
+		   index, andmask, ormask);
+	    OUTREG(RADEON_MM_INDEX, index);
+	    val = INREG(RADEON_MM_DATA);
+	    val = (val & andmask) | ormask;
+	    OUTREG(RADEON_MM_DATA, val);
+	    break;
+
+	case RADEON_TABLE_FLAG_MASK_DIRECT:
+	    andmask = RADEON_BIOS32(offset);
+	    offset += 4;
+	    ormask = RADEON_BIOS32(offset);
+	    offset += 4;
+	    ErrorF("MASK DIRECT: 0x%x 0x%x 0x%x\n",
+		   index, andmask, ormask);
+	    val = INREG(index);
+	    val = (val & andmask) | ormask;
+	    OUTREG(index, val);
+	    break;
+
+	case RADEON_TABLE_FLAG_DELAY:
+	    count = RADEON_BIOS16(offset);
+	    ErrorF("delay: %d\n", count);
+	    usleep(count);
+	    offset += 2;
+	    break;
+
+	case RADEON_TABLE_FLAG_SCOMMAND:
+	    ErrorF("SCOMMAND 0x%x\n", command); 
+	    switch (command) {
+	    case RADEON_TABLE_SCOMMAND_WAIT_MC_BUSY_MASK:
+		count = RADEON_BIOS16(offset);
+		ErrorF("SCOMMAND_WAIT_MC_BUSY_MASK %d\n", count);
+		while (count--) {
+		    if (!(INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL) &
+			  RADEON_MC_BUSY))
+			break;
+		}
+		break;
+
+	    case RADEON_TABLE_SCOMMAND_WAIT_MEM_PWRUP_COMPLETE:
+		count = RADEON_BIOS16(offset);
+		ErrorF("SCOMMAND_WAIT_MEM_PWRUP_COMPLETE %d\n", count);
+		while (count--) {
+		    /* XXX: may need indexed access */
+		    /* may need to take into account how many memory channels
+		     * each card has
+		     */
+		    if (IS_R300_VARIANT)
+			channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
+		    else
+			channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
+		    if ((INREG(RADEON_MEM_STR_CNTL) &
+			 channel_complete_mask) ==
+		        channel_complete_mask)
+			break;
+		}
+		break;
+
+	    }
+	    offset += 2;
+	    break;
+	}
+    }
+}
+
+static void
+RADEONRestoreBIOSMemBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 offset = table_offset;
+    CARD16 count;
+    CARD32 ormask, val, channel_complete_mask;
+    CARD8  index;
+
+    if (offset == 0)
+	return;
+
+    while ((index = RADEON_BIOS8(offset)) != 0xff) {
+	offset++;
+	if (index == 0x0f) {
+	    count = 20000;
+	    ErrorF("MEM_WAIT_MEM_PWRUP_COMPLETE %d\n", count);
+	    while (count--) {
+		/* XXX: may need indexed access */
+		/* may need to take into account how many memory channels
+		 * each card has
+		 */
+		if (IS_R300_VARIANT)
+		    channel_complete_mask = R300_MEM_PWRUP_COMPLETE;
+		else
+		    channel_complete_mask = RADEON_MEM_PWRUP_COMPLETE;
+		if ((INREG(RADEON_MEM_STR_CNTL) &
+		     channel_complete_mask) ==
+		    channel_complete_mask)
+		    break;
+	    }
+	} else {
+	    ormask = RADEON_BIOS16(offset);
+	    offset += 2;
+
+	    ErrorF("INDEX RADEON_MEM_SDRAM_MODE_REG %x %x\n",
+		   RADEON_SDRAM_MODE_MASK, ormask);
+
+	    /* can this use direct access? */
+	    OUTREG(RADEON_MM_INDEX, RADEON_MEM_SDRAM_MODE_REG);
+	    val = INREG(RADEON_MM_DATA);
+	    val = (val & RADEON_SDRAM_MODE_MASK) | ormask;
+	    OUTREG(RADEON_MM_DATA, val);
+
+	    ormask = (CARD32)index << 24;
+
+	    ErrorF("INDEX RADEON_MEM_SDRAM_MODE_REG %x %x\n",
+		   RADEON_B3MEM_RESET_MASK, ormask);
+
+            /* can this use direct access? */
+            OUTREG(RADEON_MM_INDEX, RADEON_MEM_SDRAM_MODE_REG);
+            val = INREG(RADEON_MM_DATA);
+            val = (val & RADEON_B3MEM_RESET_MASK) | ormask;
+            OUTREG(RADEON_MM_DATA, val);
+	}
+    }
+}
+
+static void
+RADEONRestoreBIOSPllBlock(ScrnInfoPtr pScrn, CARD16 table_offset)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    CARD16 offset = table_offset;
+    CARD8  index, shift;
+    CARD32 andmask, ormask, val, clk_pwrmgt_cntl;
+    CARD16 count;
+
+    if (offset == 0)
+	return;
+
+    while ((index = BIOS8(offset)) != 0) {
+	offset++;
+
+	switch (index & RADEON_PLL_FLAG_MASK) {
+	case RADEON_PLL_FLAG_WAIT:
+	    switch (index & RADEON_PLL_INDEX_MASK) {
+	    case RADEON_PLL_WAIT_150MKS:
+		ErrorF("delay: 150 us\n");
+		usleep(150);
+		break;
+	    case RADEON_PLL_WAIT_5MS:
+		usleep(5000);
+		ErrorF("delay: 5 ms\n");
+		break;
+
+	    case RADEON_PLL_WAIT_MC_BUSY_MASK:
+		count = 1000;
+		ErrorF("PLL_WAIT_MC_BUSY_MASK %d\n", count);
+		while (count--) {
+		    if (!(INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL) &
+			  RADEON_MC_BUSY))
+			break;
+		}
+		break;
+
+	    case RADEON_PLL_WAIT_DLL_READY_MASK:
+		count = 1000;
+		ErrorF("PLL_WAIT_DLL_READY_MASK %d\n", count);
+		while (count--) {
+		    if (INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL) &
+			RADEON_DLL_READY)
+			break;
+		}
+		break;
+
+	    case RADEON_PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24:
+		ErrorF("PLL_WAIT_CHK_SET_CLK_PWRMGT_CNTL24\n");
+		clk_pwrmgt_cntl = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL);
+		if (clk_pwrmgt_cntl & RADEON_CG_NO1_DEBUG_0) {
+		    val = INPLL(pScrn, RADEON_MCLK_CNTL);
+		    /* is this right? */
+		    val = (val & 0xFFFF0000) | 0x1111; /* seems like we should clear these... */
+		    OUTPLL(pScrn, RADEON_MCLK_CNTL, val);
+		    usleep(10000);
+		    OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL,
+			   clk_pwrmgt_cntl & ~RADEON_CG_NO1_DEBUG_0);
+		    usleep(10000);
+		}
+		break;
+	    }
+	    break;
+	    
+	case RADEON_PLL_FLAG_MASK_BYTE:
+	    shift = BIOS8(offset) * 8;
+	    offset++;
+
+	    andmask =
+		(((CARD32)BIOS8(offset)) << shift) |
+		~((CARD32)0xff << shift);
+	    offset++;
+
+	    ormask = ((CARD32)BIOS8(offset)) << shift;
+	    offset++;
+
+	    ErrorF("PLL_MASK_BYTE 0x%x 0x%x 0x%x 0x%x\n", 
+		   index, shift, andmask, ormask);
+	    val = INPLL(pScrn, index);
+	    val = (val & andmask) | ormask;
+	    OUTPLL(pScrn, index, val);
+	    break;
+
+	case RADEON_PLL_FLAG_WRITE:
+	    val = RADEON_BIOS32(offset);
+	    ErrorF("PLL_WRITE 0x%x 0x%x\n", index, val);
+	    OUTPLL(pScrn, index, val);
+	    offset += 4;
+	    break;
+	}
+    }
+}
+
+Bool
+RADEONPostCardFromBIOSTables(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+
+    if (!info->VBIOS) {
+	return FALSE;
+    } else {
+	if (info->IsAtomBios) {
+	    return FALSE;
+	} else {
+	    if (info->BiosTable.rr1_offset) {
+		ErrorF("rr1 restore\n");
+		RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr1_offset);
+	    }
+	    if (info->BiosTable.revision < 0x09) {
+		if (info->BiosTable.pll_offset) {
+		    ErrorF("pll restore\n");
+		    RADEONRestoreBIOSPllBlock(pScrn, info->BiosTable.pll_offset);
+		}
+		if (info->BiosTable.rr2_offset) {
+		    ErrorF("rr2 restore\n");
+		    RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr2_offset);
+		}
+		if (info->BiosTable.rr4_offset) {
+		    ErrorF("rr4 restore\n");
+		    RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr4_offset);
+		}
+		if (info->BiosTable.mem_reset_offset) {
+		    ErrorF("mem reset restore\n");
+		    RADEONRestoreBIOSMemBlock(pScrn, info->BiosTable.mem_reset_offset);
+		}
+		if (info->BiosTable.rr3_offset) {
+		    ErrorF("rr3 restore\n");
+		    RADEONRestoreBIOSRegBlock(pScrn, info->BiosTable.rr3_offset);
+		}
+		if (info->BiosTable.dyn_clk_offset) {
+		    ErrorF("dyn_clk restore\n");
+		    RADEONRestoreBIOSPllBlock(pScrn, info->BiosTable.dyn_clk_offset);
+		}
+	    }
+	}
+    }
+    return TRUE;
+}
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 72470a6..9423bca 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -231,7 +231,13 @@
 #       define RADEON_ACTIVE_HILO_LAT_MASK  (3 << 13)
 #       define RADEON_ACTIVE_HILO_LAT_SHIFT 13
 #       define RADEON_DISP_DYN_STOP_LAT_MASK (1 << 12)
+#       define RADEON_MC_BUSY               (1 << 16)
+#       define RADEON_DLL_READY             (1 << 19)
+#       define RADEON_CG_NO1_DEBUG_0        (1 << 24)
+#       define RADEON_CG_NO1_DEBUG_MASK     (0x1f << 24)
 #       define RADEON_DYN_STOP_MODE_MASK    (7 << 21)
+#       define RADEON_TVPLL_PWRMGT_OFF      (1 << 30)
+#       define RADEON_TVCLK_TURNOFF         (1 << 31)
 #define RADEON_PLL_PWRMGT_CNTL              0x0015
 #       define RADEON_TCL_BYPASS_DISABLE    (1 << 20)
 #define RADEON_CLR_CMP_CLR_3D               0x1a24
@@ -889,9 +895,6 @@
 #define RADEON_MAX_LATENCY                  0x0f3f /* PCI */
 #define RADEON_MC_AGP_LOCATION              0x014c
 #define RADEON_MC_FB_LOCATION               0x0148
-#define RADEON_MC_STATUS                    0x0150
-#       define RADEON_MC_IDLE               (1 << 2)
-#       define R300_MC_IDLE                 (1 << 4)
 #define RADEON_DISPLAY_BASE_ADDR            0x23c
 #define RADEON_DISPLAY2_BASE_ADDR           0x33c
 #define RADEON_OV0_BASE_ADDR                0x43c
@@ -907,8 +910,8 @@
 #       define R300_DISABLE_MC_MCLKA        (1 << 21)
 #       define R300_DISABLE_MC_MCLKB        (1 << 21)
 #define RADEON_MCLK_MISC                    0x001f /* PLL */
-#       define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1<<12)
-#       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1<<13)
+#       define RADEON_MC_MCLK_MAX_DYN_STOP_LAT (1 << 12)
+#       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1 << 13)
 #       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
 #       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 15)
 #define RADEON_LCD_GPIO_MASK                0x01a0
@@ -921,15 +924,26 @@
 #define RADEON_MEM_BASE                     0x0f10 /* PCI */
 #define RADEON_MEM_CNTL                     0x0140
 #       define RADEON_MEM_NUM_CHANNELS_MASK 0x01
-#       define RADEON_MEM_USE_B_CH_ONLY     (1<<1)
-#       define RV100_HALF_MODE              (1<<3)
+#       define RADEON_MEM_USE_B_CH_ONLY     (1 <<  1)
+#       define RV100_HALF_MODE              (1 <<  3)
 #       define R300_MEM_NUM_CHANNELS_MASK   0x03
-#       define R300_MEM_USE_CD_CH_ONLY      (1<<2)
+#       define R300_MEM_USE_CD_CH_ONLY      (1 <<  2)
 #define RADEON_MEM_TIMING_CNTL              0x0144 /* EXT_MEM_CNTL */
 #define RADEON_MEM_INIT_LAT_TIMER           0x0154
 #define RADEON_MEM_INTF_CNTL                0x014c
 #define RADEON_MEM_SDRAM_MODE_REG           0x0158
+#       define RADEON_SDRAM_MODE_MASK       0xffff0000
+#       define RADEON_B3MEM_RESET_MASK      0x6fffffff
 #define RADEON_MEM_STR_CNTL                 0x0150
+#       define RADEON_MEM_PWRUP_COMPL_A     (1 <<  0)
+#       define RADEON_MEM_PWRUP_COMPL_B     (1 <<  1)
+#       define R300_MEM_PWRUP_COMPL_C       (1 <<  2)
+#       define R300_MEM_PWRUP_COMPL_D       (1 <<  3)
+#       define RADEON_MEM_PWRUP_COMPLETE    0x03
+#       define R300_MEM_PWRUP_COMPLETE      0x0f
+#define RADEON_MC_STATUS                    0x0150
+#       define RADEON_MC_IDLE               (1 << 2)
+#       define R300_MC_IDLE                 (1 << 4)
 #define RADEON_MEM_VGA_RP_SEL               0x003c
 #define RADEON_MEM_VGA_WP_SEL               0x0038
 #define RADEON_MIN_GRANT                    0x0f3e /* PCI */
diff-tree e67d1420bf65055ecb6fdfe6b1b1f53aae83854a (from 7886405308e3288d5c86b6f2c7dbfa8ff865139c)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue Jun 5 22:31:50 2007 -0400

    RADEON: fixup RADEONDisplayVideo() to better handle the crtc being used

diff --git a/src/radeon.h b/src/radeon.h
index 750d5c6..260c413 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -411,9 +411,6 @@ typedef struct {
     Bool              R300CGWorkaround;
 
 				/* EDID or BIOS values for FPs */
-    int               PanelXRes;
-    int               PanelYRes;
-
     int               RefDivider;
     int               FeedbackDivider;
     int               PostDivider;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index c3548dd..25d6c66 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -643,11 +643,10 @@ radeon_mode_fixup(xf86OutputPtr output, 
 	    adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
 	    adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
 	    adjusted_mode->Clock          = radeon_output->DotClock;
-	    adjusted_mode->Flags          = radeon_output->Flags | RADEON_USE_RMX;
-	    /* FIXME: do this properly in radeon_video.c */
-	    info->PanelYRes = radeon_output->PanelYRes;
-	    info->PanelXRes = radeon_output->PanelXRes;
-	}
+	    radeon_output->Flags |= RADEON_USE_RMX;
+	    adjusted_mode->Flags          = radeon_output->Flags;
+	} else
+	    radeon_output->Flags &= ~RADEON_USE_RMX;
 
     }
 
diff --git a/src/radeon_video.c b/src/radeon_video.c
index d389e11..95db9ef 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2409,6 +2409,7 @@ RADEONDisplayVideo(
     int deinterlacing_method
 ){
     RADEONInfoPtr info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 v_inc, h_inc, h_inc_uv, step_by_y, step_by_uv, tmp;
     double h_inc_d;
@@ -2431,6 +2432,10 @@ RADEONDisplayVideo(
     int predownscale=0;
     int src_w_d;
     int leftuv = 0;
+    xf86CrtcPtr crtc;
+    DisplayModePtr mode;
+    RADEONOutputPrivatePtr radeon_output;
+    xf86OutputPtr output;
 
     is_rgb=0; is_planar=0;
     switch(id){
@@ -2478,15 +2483,29 @@ RADEONDisplayVideo(
     v_inc_shift = 20;
     y_mult = 1;
 
-    if (pScrn->currentMode->Flags & V_INTERLACE)
+    if (info->OverlayOnCRTC2)
+	crtc = xf86_config->crtc[1];
+    else
+	crtc = xf86_config->crtc[0];
+
+    mode = &crtc->mode;
+
+    if (mode->Flags & V_INTERLACE)
 	v_inc_shift++;
-    if (pScrn->currentMode->Flags & V_DBLSCAN) {
+    if (mode->Flags & V_DBLSCAN) {
 	v_inc_shift--;
 	y_mult = 2;
     }
-    // FIXME
-    if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
-	v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+	output = xf86_config->output[i];
+	if (output->crtc == crtc) {
+	    radeon_output = output->driver_private;
+	}
+    }
+
+    if (radeon_output->Flags & RADEON_USE_RMX) {
+	v_inc = ((src_h * mode->CrtcVDisplay / radeon_output->PanelYRes) << v_inc_shift) / drw_h;
     } else {
 	v_inc = (src_h << v_inc_shift) / drw_h;
     }
@@ -2624,6 +2643,15 @@ RADEONDisplayVideo(
 	x_off = 0;
 
     /* needed to make the overlay work on crtc1 in leftof and above modes */
+    /* XXX: may need to adjust x_off/y_off for dualhead like mergedfb -- need to test */
+    /*
+    if (srel == radeonLeftOf) {
+	x_off -= mode->CrtcHDisplay;
+    }
+    if (srel == radeonAbove) {
+	y_off -= mode->CrtcVDisplay;
+    }
+    */
 
     /* Put the hardware overlay on CRTC2:
      *
diff-tree 7886405308e3288d5c86b6f2c7dbfa8ff865139c (from f54ad565a69deb52547fd04e123f56fc1294cd0a)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 4 21:16:56 2007 -0400

    RADEON: fix indenting

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 2f5674f..c3548dd 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -158,20 +158,19 @@ void RADEONPrintPortMap(ScrnInfoPtr pScr
     int o;
 
     for (o = 0; o < xf86_config->num_output; o++) {
-      output = xf86_config->output[o];
-      radeon_output = output->driver_private;
-
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		 "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
-	  o,
-	  MonTypeName[radeon_output->MonType+1],
-	  info->IsAtomBios ? 
-	  ConnectorTypeNameATOM[radeon_output->ConnectorType]:
-	  ConnectorTypeName[radeon_output->ConnectorType],
-	  DACTypeName[radeon_output->DACType+1],
-	  TMDSTypeName[radeon_output->TMDSType+1],
-	  DDCTypeName[radeon_output->DDCType]);
+	output = xf86_config->output[o];
+	radeon_output = output->driver_private;
 
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
+		   "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
+		   o,
+		   MonTypeName[radeon_output->MonType+1],
+		   info->IsAtomBios ? 
+		   ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+		   ConnectorTypeName[radeon_output->ConnectorType],
+		   DACTypeName[radeon_output->DACType+1],
+		   TMDSTypeName[radeon_output->TMDSType+1],
+		   DDCTypeName[radeon_output->DDCType]);
     }
 
 }
diff-tree f54ad565a69deb52547fd04e123f56fc1294cd0a (from 687879bff716ad01f9f158860deb8ba770faab99)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 4 21:13:16 2007 -0400

    RADEON: no need to go through all the crtcs, we've got what we need

diff --git a/src/radeon_output.c b/src/radeon_output.c
index b13fd29..2f5674f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -967,18 +967,11 @@ radeon_mode_set(xf86OutputPtr output, Di
 {
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int i;
+    xf86CrtcPtr	crtc = output->crtc;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
-    /* get the outputs connected to this CRTC */
-    for (i = 0; i < xf86_config->num_crtc; i++) {
-	xf86CrtcPtr	crtc = xf86_config->crtc[i];
-	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-	if (output->crtc == crtc) {
-	    RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
-	}
-    }
+    RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
 
     switch(radeon_output->MonType) {
     case MT_LCD:
diff-tree 687879bff716ad01f9f158860deb8ba770faab99 (from e6161e472ff266f69547704a61040228a8704b06)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 4 21:08:40 2007 -0400

    RADEON: add support for RMX on DVI, make sure RMX is only enabled on crtc1

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 3e2881f..b13fd29 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -147,6 +147,7 @@ static const RADEONTMDSPll default_tmds_
 };
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
+static void RADEONUpdatePanelSize(xf86OutputPtr output);
 
 void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
@@ -528,19 +529,23 @@ void RADEONConnectorFindMonitor(ScrnInfo
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     
     if (radeon_output->MonType == MT_UNKNOWN) {
-      if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output)));
-      else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
-      else if (radeon_output->DACType == DAC_PRIMARY) 
-	  radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
+	if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output)));
+	else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
+	else if (radeon_output->DACType == DAC_PRIMARY) 
+	    radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
     }
 
+    /* update panel info for RMX */
+    if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
+	RADEONUpdatePanelSize(output);
+
     if (output->MonInfo) {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
-		 info->IsAtomBios ?
-		 ConnectorTypeNameATOM[radeon_output->ConnectorType]:
-		 ConnectorTypeName[radeon_output->ConnectorType]
-		 );
-      xf86PrintEDID( output->MonInfo );
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
+		   info->IsAtomBios ?
+		   ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+		   ConnectorTypeName[radeon_output->ConnectorType]
+		   );
+	xf86PrintEDID( output->MonInfo );
     }
 }
 
@@ -622,25 +627,29 @@ radeon_mode_fixup(xf86OutputPtr output, 
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    if (radeon_output->type != OUTPUT_LVDS)
-	return TRUE;
+    if (radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP) {
+	xf86CrtcPtr crtc = output->crtc;
+	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+	if ((mode->HDisplay < radeon_output->PanelXRes ||
+	     mode->VDisplay < radeon_output->PanelYRes) &&
+	    radeon_crtc->crtc_id == 0)
+	    adjusted_mode->Flags |= RADEON_USE_RMX;
+
+	if (adjusted_mode->Flags & RADEON_USE_RMX) {
+	    adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
+	    adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
+	    adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+	    adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
+	    adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
+	    adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+	    adjusted_mode->Clock          = radeon_output->DotClock;
+	    adjusted_mode->Flags          = radeon_output->Flags | RADEON_USE_RMX;
+	    /* FIXME: do this properly in radeon_video.c */
+	    info->PanelYRes = radeon_output->PanelYRes;
+	    info->PanelXRes = radeon_output->PanelXRes;
+	}
 
-    if (mode->HDisplay < radeon_output->PanelXRes ||
-	mode->VDisplay < radeon_output->PanelYRes)
-	adjusted_mode->Flags |= RADEON_USE_RMX;
-
-    if (adjusted_mode->Flags & RADEON_USE_RMX) {
-	adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
-	adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
-	adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-	adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
-	adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
-	adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
-	adjusted_mode->Clock          = radeon_output->DotClock;
-	adjusted_mode->Flags          = radeon_output->Flags | RADEON_USE_RMX;
-	/* save these for Xv with RMX */
-	info->PanelYRes = radeon_output->PanelYRes;
-	info->PanelXRes = radeon_output->PanelXRes;
     }
 
     return TRUE;
@@ -1121,7 +1130,7 @@ radeon_create_resources(xf86OutputPtr ou
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
-	/* Set the current value of the backlight property */
+	/* Set the current value of the property */
 	data = 0;
 	err = RRChangeOutputProperty(output->randr_output, rmx_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &data,
@@ -1395,7 +1404,8 @@ RADEONUpdatePanelSize(xf86OutputPtr outp
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int             j;
     /* XXX: fixme */
-    xf86MonPtr      ddc  = pScrn->monitor->DDC;
+    //xf86MonPtr      ddc  = pScrn->monitor->DDC;
+    xf86MonPtr ddc = output->MonInfo;
     DisplayModePtr  p;
 
     // crtc should handle?
diff-tree e6161e472ff266f69547704a61040228a8704b06 (from be0ce38232ea4f5679c5829ab663939144c6e617)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 4 20:32:55 2007 -0400

    RADEON: remove some cruft

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 8060b4c..3e2881f 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -891,7 +891,6 @@ static void RADEONInitDAC2Registers(xf86
     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 &
@@ -901,10 +900,6 @@ static void RADEONInitDAC2Registers(xf86
 	    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;
         }
@@ -919,12 +914,7 @@ static void RADEONInitDAC2Registers(xf86
 	    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;*/
+            save->fp2_gen_cntl |= R200_FP2_SOURCE_SEL_CRTC2;
         } else {
             save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC2_CLK_SEL;
             save->disp_hw_debug = info->SavedReg.disp_hw_debug &
diff-tree be0ce38232ea4f5679c5829ab663939144c6e617 (from 8ec617f6493dd0aea5d11f92e3d58c3feef8c8fd)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon Jun 4 20:22:15 2007 -0400

    RADEON: number the outputs if there are more than one of the same

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 99b6544..8060b4c 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -1754,7 +1754,44 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		    radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
 	    }
 	    RADEONSetOutputType(pScrn, radeon_output);
-	    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	    if (info->IsAtomBios) {
+		if (((info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+		     (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+		     (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_A_ATOM)) &&
+		    ((info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+		     (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+		     (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_A_ATOM))) {
+		    if (i > 0)
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+		    else
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+		} else if ((info->BiosConnector[0].ConnectorType == CONNECTOR_VGA_ATOM) &&
+			   (info->BiosConnector[1].ConnectorType == CONNECTOR_VGA_ATOM)) {
+		    if (i > 0)
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+		    else
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+		} else
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	    } else {
+		if (((info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D) ||
+		     (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_I)) &&
+		    ((info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_D) ||
+		     (info->BiosConnector[1].ConnectorType == CONNECTOR_DVI_I))) {
+		    if (i > 0)
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-1");
+		    else
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "DVI-0");
+		} else if ((info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) &&
+			   (info->BiosConnector[1].ConnectorType == CONNECTOR_CRT)) {
+		    if (i > 0)
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-1");
+		    else
+			output = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA-0");
+		} else
+		    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	    }
+
 	    if (!output) {
 		return FALSE;
 	    }
diff-tree 8ec617f6493dd0aea5d11f92e3d58c3feef8c8fd (from 73d8e3ec8536b4777490b7ba457566f02233811f)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jun 3 17:32:43 2007 +1000

    radeon: disable irqs at server start until 3D app starts

diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 97ed357..1b17e2e 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1679,6 +1679,9 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr
     info->DRICloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = RADEONDRIDoCloseScreen;
 
+    /* disable vblank at startup */
+    RADEONDRISetVBlankInterrupt (pScrn, FALSE);
+
     return TRUE;
 }
 
@@ -1756,6 +1759,7 @@ void RADEONDRICloseScreen(ScreenPtr pScr
 		    "RADEONDRICloseScreen\n");
     
      if (info->irq) {
+	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
 	drmCtlUninstHandler(info->drmFD);
 	info->irq = 0;
 	info->ModeReg.gen_int_cntl = 0;
diff-tree 2d40fa55e8d7a1cfb204d66ca4a4d95a3b13d5b5 (from dcb64a4d3947e5a9fbda4b72e29a5b6102370f07)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jun 3 17:32:43 2007 +1000

    radeon: disable irqs at server start until 3D app starts

diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 63c35b4..11f7140 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1675,6 +1675,9 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr
     info->DRICloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = RADEONDRIDoCloseScreen;
 
+    /* disable vblank at startup */
+    RADEONDRISetVBlankInterrupt (pScrn, FALSE);
+
     return TRUE;
 }
 
@@ -1752,6 +1755,7 @@ void RADEONDRICloseScreen(ScreenPtr pScr
 		    "RADEONDRICloseScreen\n");
     
      if (info->irq) {
+	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
 	drmCtlUninstHandler(info->drmFD);
 	info->irq = 0;
 	info->ModeReg.gen_int_cntl = 0;
diff-tree dcb64a4d3947e5a9fbda4b72e29a5b6102370f07 (from 4c61c0ee91a2ffeefce30972a584486f1df1d1ae)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jun 3 17:10:49 2007 +1000

    radeon: disable vbl interrupts when no 3d is running on a new enough drm

diff --git a/src/radeon.h b/src/radeon.h
index 88402df..a22e481 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -818,6 +818,7 @@ typedef struct {
 
     CARD32            tv_dac_adj;
 
+    Bool want_vblank_interrupts;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 #define RADEONWaitForFifo(pScrn, entries)				\
@@ -935,6 +936,7 @@ extern drmBufPtr   RADEONCPGetBuffer(Scr
 extern void        RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
 extern void        RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
 extern int         RADEONCPStop(ScrnInfoPtr pScrn,  RADEONInfoPtr info);
+extern Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on);
 
 extern void        RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst,
 					CARD32 pitch, int cpp,
diff --git a/src/radeon_common.h b/src/radeon_common.h
index 3f2c6ab..467addf 100644
--- a/src/radeon_common.h
+++ b/src/radeon_common.h
@@ -420,6 +420,8 @@ typedef union {
 #define RADEON_PARAM_SAREA_HANDLE          9
 #define RADEON_PARAM_GART_TEX_HANDLE       10
 #define RADEON_PARAM_SCRATCH_OFFSET        11
+#define RADEON_PARAM_CARD_TYPE             12
+#define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 
 typedef struct drm_radeon_getparam {
 	int param;
@@ -473,7 +475,7 @@ typedef struct drm_radeon_set_param {
 #define RADEON_SETPARAM_PCIGART_LOCATION 3
 #define RADEON_SETPARAM_NEW_MEMMAP 4
 #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5
-
+#define RADEON_SETPARAM_VBLANK_CRTC 6           /* VBLANK CRTC */
 /* 1.14: Clients can allocate/free a surface
  */
 typedef struct drm_radeon_surface_alloc {
@@ -486,4 +488,7 @@ typedef struct drm_radeon_surface_free {
 	unsigned int address;
 } drmRadeonSurfaceFree;
 
+#define	DRM_RADEON_VBLANK_CRTC1 	1
+#define	DRM_RADEON_VBLANK_CRTC2 	2
+
 #endif
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 39393f5..63c35b4 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1352,6 +1352,25 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pSc
     return TRUE;
 }
 
+Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
+{
+    RADEONInfoPtr  info    = RADEONPTR(pScrn);
+    int value = 0;
+
+    if (info->directRenderingEnabled && info->pKernelDRMVersion->version_minor >= 28) {
+	/* we could do something with mergedfb here I'm sure */
+        if (on)
+	        value = DRM_RADEON_VBLANK_CRTC1;
+
+	if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_VBLANK_CRTC, value)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEON Vblank Crtc Setup Failed %d\n", value);
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+
 /* Initialize the screen-specific data structures for the DRI and the
  * Radeon.  This is the main entry point to the device-specific
  * initialization code.  It calls device-independent DRI functions to
@@ -2029,6 +2048,9 @@ static void RADEONDRITransitionTo3d(Scre
 
     RADEONChangeSurfaces(pScrn);
     RADEONEnablePageFlip(pScreen);
+    
+    info->want_vblank_interrupts = TRUE;
+    RADEONDRISetVBlankInterrupt(pScrn, TRUE);
 
     if (info->cursor)
 	xf86ForceHWCursor (pScreen, TRUE);
@@ -2068,6 +2090,9 @@ static void RADEONDRITransitionTo2d(Scre
 
     RADEONChangeSurfaces(pScrn);
 
+    info->want_vblank_interrupts = FALSE;
+    RADEONDRISetVBlankInterrupt(pScrn, FALSE);
+
     if (info->cursor)
 	xf86ForceHWCursor (pScreen, FALSE);
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 25921ad..91af1ec 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6935,6 +6935,8 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 	/* get the DRI back into shape after resume */
 	RADEONDRIResume(pScrn->pScreen);
 	RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
+
+	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
     }
 #endif
     /* this will get XVideo going again, but only if XVideo was initialised
@@ -6970,6 +6972,8 @@ void RADEONLeaveVT(int scrnIndex, int fl
 		   "RADEONLeaveVT\n");
 #ifdef XF86DRI
     if (RADEONPTR(pScrn)->directRenderingInited) {
+
+	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
 	DRILock(pScrn->pScreen, 0);
 	RADEONCP_STOP(pScrn, info);
 
diff-tree 73d8e3ec8536b4777490b7ba457566f02233811f (from 63f0d4ed0a98830ecbe18c6e4174689111a59b68)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jun 3 17:07:59 2007 +1000

    randr-1.2 increase dri minor version for mesa to know we can do vbl on both

diff --git a/src/radeon_version.h b/src/radeon_version.h
index a1b2459..ccc1367 100644
--- a/src/radeon_version.h
+++ b/src/radeon_version.h
@@ -41,7 +41,7 @@
 
 #define RADEON_VERSION_MAJOR 4
 #define RADEON_VERSION_MAJOR_TILED 5
-#define RADEON_VERSION_MINOR 2
+#define RADEON_VERSION_MINOR 3
 #define RADEON_VERSION_PATCH 0
 
 #ifndef RADEON_VERSION_EXTRA
diff-tree 63f0d4ed0a98830ecbe18c6e4174689111a59b68 (from d7775c1b38b5bdc439a27ec2c3c3a03a5b24cf57)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jun 3 16:49:14 2007 +1000

    randr-1.2: add support for vblank on both heads
    
    Also disable vbl when 3D isn't running

diff --git a/src/radeon.h b/src/radeon.h
index 62faee0..750d5c6 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -735,6 +735,7 @@ typedef struct {
 
     CARD32            tv_dac_adj;
 
+    Bool want_vblank_interrupts;
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
 
     Rotation rotation;
@@ -899,6 +900,7 @@ extern drmBufPtr   RADEONCPGetBuffer(Scr
 extern void        RADEONCPFlushIndirect(ScrnInfoPtr pScrn, int discard);
 extern void        RADEONCPReleaseIndirect(ScrnInfoPtr pScrn);
 extern int         RADEONCPStop(ScrnInfoPtr pScrn,  RADEONInfoPtr info);
+extern Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on);
 
 extern void        RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst,
 					CARD32 pitch, int cpp,
diff --git a/src/radeon_common.h b/src/radeon_common.h
index 3f2c6ab..467addf 100644
--- a/src/radeon_common.h
+++ b/src/radeon_common.h
@@ -420,6 +420,8 @@ typedef union {
 #define RADEON_PARAM_SAREA_HANDLE          9
 #define RADEON_PARAM_GART_TEX_HANDLE       10
 #define RADEON_PARAM_SCRATCH_OFFSET        11
+#define RADEON_PARAM_CARD_TYPE             12
+#define RADEON_PARAM_VBLANK_CRTC           13   /* VBLANK CRTC */
 
 typedef struct drm_radeon_getparam {
 	int param;
@@ -473,7 +475,7 @@ typedef struct drm_radeon_set_param {
 #define RADEON_SETPARAM_PCIGART_LOCATION 3
 #define RADEON_SETPARAM_NEW_MEMMAP 4
 #define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5
-
+#define RADEON_SETPARAM_VBLANK_CRTC 6           /* VBLANK CRTC */
 /* 1.14: Clients can allocate/free a surface
  */
 typedef struct drm_radeon_surface_alloc {
@@ -486,4 +488,7 @@ typedef struct drm_radeon_surface_free {
 	unsigned int address;
 } drmRadeonSurfaceFree;
 
+#define	DRM_RADEON_VBLANK_CRTC1 	1
+#define	DRM_RADEON_VBLANK_CRTC2 	2
+
 #endif
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 39393f5..97ed357 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1352,6 +1352,29 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pSc
     return TRUE;
 }
 
+Bool RADEONDRISetVBlankInterrupt(ScrnInfoPtr pScrn, Bool on)
+{
+    RADEONInfoPtr  info    = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int value = 0;
+
+    if (info->directRenderingEnabled && info->pKernelDRMVersion->version_minor >= 28) {
+        if (on) {
+  	    if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
+	        value = DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2;
+	    else
+	        value = DRM_RADEON_VBLANK_CRTC1;
+	}
+
+	if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_VBLANK_CRTC, value)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RADEON Vblank Crtc Setup Failed %d\n", value);
+	    return FALSE;
+	}
+    }
+    return TRUE;
+}
+
+
 /* Initialize the screen-specific data structures for the DRI and the
  * Radeon.  This is the main entry point to the device-specific
  * initialization code.  It calls device-independent DRI functions to
@@ -2029,6 +2052,9 @@ static void RADEONDRITransitionTo3d(Scre
 
     RADEONChangeSurfaces(pScrn);
     RADEONEnablePageFlip(pScreen);
+    
+    info->want_vblank_interrupts = TRUE;
+    RADEONDRISetVBlankInterrupt(pScrn, TRUE);
 
     if (info->cursor)
 	xf86ForceHWCursor (pScreen, TRUE);
@@ -2068,6 +2094,9 @@ static void RADEONDRITransitionTo2d(Scre
 
     RADEONChangeSurfaces(pScrn);
 
+    info->want_vblank_interrupts = FALSE;
+    RADEONDRISetVBlankInterrupt(pScrn, FALSE);
+
     if (info->cursor)
 	xf86ForceHWCursor (pScreen, FALSE);
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1c433e2..7d48650 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5436,6 +5436,8 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 	/* get the DRI back into shape after resume */
 	RADEONDRIResume(pScrn->pScreen);
 	RADEONAdjustMemMapRegisters(pScrn, &info->ModeReg);
+
+	RADEONDRISetVBlankInterrupt (pScrn, TRUE);
     }
 #endif
     /* this will get XVideo going again, but only if XVideo was initialised
@@ -5471,6 +5473,8 @@ void RADEONLeaveVT(int scrnIndex, int fl
 		   "RADEONLeaveVT\n");
 #ifdef XF86DRI
     if (RADEONPTR(pScrn)->directRenderingInited) {
+
+	RADEONDRISetVBlankInterrupt (pScrn, FALSE);
 	DRILock(pScrn->pScreen, 0);
 	RADEONCP_STOP(pScrn, info);
 
diff-tree d7775c1b38b5bdc439a27ec2c3c3a03a5b24cf57 (from 5a9516fe4f17854acd4fbf3a8eadf5139081dbd4)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jun 3 12:46:31 2007 +1000

    randr-1.2: make native mode preferred
    
    If we have a native mode from the BIOS make it preferred mode

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index a7503a5..6952dd5 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -107,7 +107,7 @@ static DisplayModePtr RADEONFPNativeMode
 
 	new->Clock      = radeon_output->DotClock;
 	new->Flags      = 0;
-	new->type       = M_T_USERDEF;
+	new->type       = M_T_USERDEF | M_T_PREFERRED;
 
 	new->next       = NULL;
 	new->prev       = NULL;
diff-tree 5a9516fe4f17854acd4fbf3a8eadf5139081dbd4 (from 802804461ebdca9a951e7e562ec68fd08d8eae01)
Author: Paul TBBle Hampson <Paul.Hampson at pobox.com>
Date:   Sat Jun 2 14:28:18 2007 -0400

    RADEONProbePLLParameters sets pll->reference_div, and
    RADEONGetPanelInfoFromReg uses it.
    
    This ensures that the former is called before the latter.
    (this should fix randr on ppc)

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 925b8ee..1c433e2 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2497,14 +2497,14 @@ static Bool RADEONPreInitControllers(Scr
 
     RADEONGetBIOSInfo(pScrn, pInt10);
 
+    RADEONGetClockInfo(pScrn);
+
     if (!RADEONSetupConnectors(pScrn)) {
 	return FALSE;
     }
       
     RADEONPrintPortMap(pScrn);
 
-    RADEONGetClockInfo(pScrn);
-
     for (i = 0; i < config->num_output; i++) 
     {
       xf86OutputPtr	      output = config->output[i];
diff-tree 802804461ebdca9a951e7e562ec68fd08d8eae01 (from 0e0946e0aa2527794e07473199e851bbfbc47cb1)
Author: Matthieu Herrb <matthieu at deville.herrb.com>
Date:   Thu May 31 22:23:57 2007 -0600

    Fix build whithout XF86DRI

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 79ab578..bee05e2 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -255,8 +255,10 @@ RADEONInitCrtcRegisters(xf86CrtcPtr crtc
 				     : 0));
 
     save->crtc_offset      = pScrn->fbOffset;
+#ifdef XF86DRI
     if (info->allowPageFlip)
 	save->crtc_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
 
     if (info->tilingEnabled) {
        if (IS_R300_VARIANT)
@@ -443,8 +445,10 @@ RADEONInitCrtc2Registers(xf86CrtcPtr crt
     /* It seems all fancy options apart from pflip can be safely disabled
      */
     save->crtc2_offset      = pScrn->fbOffset;
+#ifdef XF86DRI
     if (info->allowPageFlip)
 	save->crtc2_offset_cntl = RADEON_CRTC_OFFSET_FLIP_CNTL;
+#endif
 
     if (info->tilingEnabled) {
        if (IS_R300_VARIANT)
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;
diff-tree 31c1be420d5277dd15505bd73e6144827a0580cd (from 7fc02657c4d740941fbda5a8823cf45de3eca3f8)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Wed May 30 17:49:01 2007 +1000

    remove these syncs, at least on rs480 it doesn't break
    
    probably requires testing on other r300 based cards, with the syncs in
    we hang when moving the cursor into the second CRTC.

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 6746615..b3f7691 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -106,8 +106,6 @@ radeon_crtc_show_cursor (xf86CrtcPtr crt
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     unsigned char     *RADEONMMIO = info->MMIO;
 
-    RADEON_SYNC(info, pScrn);
-
     if (crtc_id == 0) 
 	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN | 2 << 20, 
 		~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
@@ -125,8 +123,6 @@ radeon_crtc_hide_cursor (xf86CrtcPtr crt
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     unsigned char     *RADEONMMIO = info->MMIO;
 
-    RADEON_SYNC(info, pScrn);
-
     if (crtc_id == 0)
 	OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
     else if (crtc_id == 1)
diff-tree 7fc02657c4d740941fbda5a8823cf45de3eca3f8 (from parents)
Merge: 800bf53279e2c2bf854682bbfd6fa16d03afed00 4c61c0ee91a2ffeefce30972a584486f1df1d1ae
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Wed May 30 17:27:22 2007 +1000

    Merge branch 'origin' into randr-1.2-test
    
    Conflicts:
    
    	src/radeon_cursor.c
    	src/radeon_display.c
    	src/radeon_driver.c

diff --cc src/radeon.h
index d75b154,88402df..eb4902b
@@@ -152,8 -161,31 +152,7 @@@
      OPTION_DRI
  } RADEONOpts;
  
 -/* ------- mergedfb support ------------- */
 -		/* Psuedo Xinerama support */
 -#define NEED_REPLIES  		/* ? */
 -#define EXTENSION_PROC_ARGS void *
 -#include "extnsionst.h"  	/* required */
 -#include <X11/extensions/panoramiXproto.h>  	/* required */
 -#define RADEON_XINERAMA_MAJOR_VERSION  1
 -#define RADEON_XINERAMA_MINOR_VERSION  1
 -
 -
 -/* Relative merge position */
 -typedef enum {
 -   radeonLeftOf,
 -   radeonRightOf,
 -   radeonAbove,
 -   radeonBelow,
 -   radeonClone
 -} RADEONScrn2Rel;
 -
 -typedef struct _region {
 -    int x0,x1,y0,y1;
 -} region;
 -
 -/* ------------------------------------- */
  
- #define RADEON_DEBUG            1 /* Turn off debugging output               */
  #define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
  #define RADEON_TIMEOUT    2000000 /* Fall out of wait loops after this count */
  
@@@ -165,18 -197,8 +164,10 @@@
  				   * for something else.
  				   */
  
- #if RADEON_DEBUG
- #define RADEONTRACE(x)						\
- do {									\
-     ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex);		\
-     ErrorF x;								\
- } while(0)
- #else
- #define RADEONTRACE(x) do { } while(0)
- #endif
+ #define RADEON_LOGLEVEL_DEBUG 4
  
 +/* for Xv, outputs */
 +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
  
  /* Other macros */
  #define RADEON_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
diff --cc src/radeon_bios.c
index 25cd1a8,e62fb25..8d5c0ec
@@@ -40,6 -41,21 +41,21 @@@
  #include "radeon_probe.h"
  #include "vbe.h"
  
+ 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) {
+       if (info->PciInfo->subsysCard == 0x308b) {
 -	if (pRADEONEnt->PortInfo[1]->DDCType == DDC_CRT2)
 -	  pRADEONEnt->PortInfo[1]->DDCType        = DDC_MONID;
++	if (info->BiosConnector[1].DDCType == DDC_CRT2)
++	  info->BiosConnector[1].DDCType = DDC_MONID;
+       }
+     }
+     return connector_found;
+ }
+ 
  /* Read the Video BIOS block and the FP registers (if applicable). */
  Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
  {
diff --cc src/radeon_cursor.c
index 68771f8,ec80dd8..6746615
@@@ -103,41 -98,6 +97,43 @@@
  
  #endif
  
 +void
 +radeon_crtc_show_cursor (xf86CrtcPtr crtc)
 +{
 +    ScrnInfoPtr pScrn = crtc->scrn;
 +    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 +    int crtc_id = radeon_crtc->crtc_id;
 +    RADEONInfoPtr      info       = RADEONPTR(pScrn);
 +    unsigned char     *RADEONMMIO = info->MMIO;
 +
++    RADEON_SYNC(info, pScrn);
++
 +    if (crtc_id == 0) 
- 	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
- 		~RADEON_CRTC_CUR_EN);
++	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN | 2 << 20, 
++		~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
 +    else if (crtc_id == 1)
- 	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
- 		~RADEON_CRTC2_CUR_EN);
- 
- 
++	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN | 2 << 20,
++		~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_CUR_MODE_MASK));
 +}
 +
 +void
 +radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
 +{
 +    ScrnInfoPtr pScrn = crtc->scrn;
 +    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 +    int crtc_id = radeon_crtc->crtc_id;
 +    RADEONInfoPtr      info       = RADEONPTR(pScrn);
 +    unsigned char     *RADEONMMIO = info->MMIO;
 +
++    RADEON_SYNC(info, pScrn);
++
 +    if (crtc_id == 0)
 +	OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
 +    else if (crtc_id == 1)
 +	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
 +
 +
 +}
  
  /* Set cursor foreground and background colors */
  static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
@@@ -277,23 -293,14 +273,11 @@@
      unsigned char *RADEONMMIO = info->MMIO;
      CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
      int            x, y, w, h;
-     CARD32         save1      = 0;
-     CARD32         save2      = 0;
 -    CARD32	  *image = pCurs->bits->argb;
      CARD32	  *i;
  
      RADEONCTRACE(("RADEONLoadCursorARGB\n"));
  
-     if (crtc_id == 0) {
- 	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
- 	save1 |= (CARD32) (2 << 20);
- 	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
-     } else if (crtc_id == 1) {
- 	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
- 	save2 |= (CARD32) (2 << 20);
- 	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-     }
- 
 -#ifdef ARGB_CURSOR
      info->cursor_argb = TRUE;
 -#endif
  
      CURSOR_SWAPPING_START();
  
@@@ -320,15 -324,8 +304,9 @@@
      for (; y < CURSOR_HEIGHT; y++)
  	for (x = 0; x < CURSOR_WIDTH; x++)
  	    *d++ = 0;
 +#endif
  
      CURSOR_SWAPPING_END ();
- 
-     if (crtc_id == 0) {
- 	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-     } else if (crtc_id == 1) {
- 	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-     }
  }
  
  #endif
diff --cc src/radeon_display.c
index 3bbf371,90fdc54..0442b9a
@@@ -1340,11 -1941,13 +1340,13 @@@
      OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
  				     (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
  
-     RADEONTRACE(("GRPH_BUFFER_CNTL from %x to %x\n",
- 		 (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL)));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "GRPH_BUFFER_CNTL from %x to %x\n",
+ 		   (unsigned int)info->SavedReg.grph_buffer_cntl,
+ 		   INREG(RADEON_GRPH_BUFFER_CNTL));
  
      if (mode2) {
 -	stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16;
 +	stop_req = mode2->HDisplay * pixel_bytes2 / 16;
  
  	if (stop_req > max_stop_req) stop_req = max_stop_req;
  
diff --cc src/radeon_driver.c
index 42d1899,25921ad..b399736
@@@ -3331,6 -3816,7 +3338,7 @@@
  #ifdef XF86DRI
      pScrn->fbOffset    = info->frontOffset;
  #endif
 -    if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
++
      if (!RADEONMapMem(pScrn)) return FALSE;
  
  #ifdef XF86DRI
@@@ -3429,8 -3925,11 +3437,9 @@@
  #endif
  
      /* Initial setup of surfaces */
-     RADEONTRACE(("Setting up initial surfaces\n"));
 -    if (!info->IsSecondary) {
 -	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 -		       "Setting up initial surfaces\n");
 -	RADEONChangeSurfaces(pScrn);
 -    }
++    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
++                   "Setting up initial surfaces\n");
 +    RADEONChangeSurfaces(pScrn);
  
  				/* Memory manager setup */
  
@@@ -3612,10 -4105,11 +3623,11 @@@
  
      RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
  
 -    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 +    //    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
  
      /* Backing store setup */
-     RADEONTRACE(("Initializing backing store\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "Initializing backing store\n");
      miInitializeBackingStore(pScreen);
      xf86SetBackingStore(pScreen);
  
@@@ -3664,8 -4159,15 +3677,10 @@@
  #endif
  
      /* Make sure surfaces are allright since DRI setup may have changed them */
-     RADEONTRACE(("Setting up final surfaces\n"));
 -    if (!info->IsSecondary) {
 -	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 -		       "Setting up final surfaces\n");
 -	RADEONChangeSurfaces(pScrn);
 -    }
++    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
++                   "Setting up final surfaces\n");
+ 
 -    if(info->MergedFB)
 -	/* need this here to fix up sarea values */
 -	RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 +    RADEONChangeSurfaces(pScrn);
  
      /* Enable aceleration */
      if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
@@@ -3685,10 -4188,12 +3701,12 @@@
      }
  
      /* Init DPMS */
-     RADEONTRACE(("Initializing DPMS\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "Initializing DPMS\n");
 -    xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
 +    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
  
-     RADEONTRACE(("Initializing Cursor\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "Initializing Cursor\n");
  
      /* Set Silken Mouse */
      xf86SetSilkenMouse(pScreen);
@@@ -3725,16 -4230,45 +3743,16 @@@
  	xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n");
      }
  
- 
- 
 -    /* Colormap setup */
 -    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 -		   "Initializing color map\n");
 -    if (!miCreateDefColormap(pScreen)) return FALSE;
 -    if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
 -			     RADEONLoadPalette, NULL,
 -			     CMAP_PALETTED_TRUECOLOR
 -#if 0 /* This option messes up text mode! (eich at suse.de) */
 -			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
 -#endif
 -			     | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
 -
 -    /* DGA setup */
 +    /* DGA setup */
-     RADEONTRACE(("Initializing DGA\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "Initializing DGA\n");
      RADEONDGAInit(pScreen);
  
 -    /* Wrap some funcs for MergedFB */
 -    if(info->MergedFB) {
 -       info->PointerMoved = pScrn->PointerMoved;
 -       pScrn->PointerMoved = RADEONMergePointerMoved;
 -       /* Psuedo xinerama */
 -       if(info->UseRADEONXinerama) {
 -          RADEONnoPanoramiXExtension = FALSE;
 -          RADEONXineramaExtensionInit(pScrn);
 -       } else {
 -	  info->MouseRestrictions = FALSE;
 -       }
 -    }
 -
      /* Init Xv */
-     RADEONTRACE(("Initializing Xv\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "Initializing Xv\n");
      RADEONInitVideo(pScreen);
  
 -    if(info->MergedFB)
 -	/* need this here to fix up sarea values */
 -	RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 -
      /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
      /* Wrap CloseScreen */
      info->CloseScreen    = pScreen->CloseScreen;
@@@ -3743,24 -4277,6 +3761,25 @@@
      info->BlockHandler = pScreen->BlockHandler;
      pScreen->BlockHandler = RADEONBlockHandler;
  
 +   if (!xf86CrtcScreenInit (pScreen))
 +       return FALSE;
 +
 +    /* Wrap pointer motion to flip touch screen around */
 +    info->PointerMoved = pScrn->PointerMoved;
 +    pScrn->PointerMoved = RADEONPointerMoved;
 +
 +    /* Colormap setup */
-     RADEONTRACE(("Initializing color map\n"));
++    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
++                   "Initializing color map\n");
 +    if (!miCreateDefColormap(pScreen)) return FALSE;
 +    if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
 +			     RADEONLoadPalette, NULL,
 +			     CMAP_PALETTED_TRUECOLOR
 +#if 0 /* This option messes up text mode! (eich at suse.de) */
 +			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
 +#endif
 +			     | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
 +
      /* Note unused options */
      if (serverGeneration == 1)
  	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@@ -4124,11 -4626,18 +4152,12 @@@
  {
      RADEONInfoPtr  info       = RADEONPTR(pScrn);
      unsigned char *RADEONMMIO = info->MMIO;
 -    CARD32	   crtc2_gen_cntl;
 +    /*    CARD32	   crtc2_gen_cntl;*/
  
-     RADEONTRACE(("Programming CRTC2, offset: 0x%08lx\n",
- 		 restore->crtc2_offset));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "Programming CRTC2, offset: 0x%08lx\n",
+ 		   restore->crtc2_offset);
  
 -    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) &
 -	    (RADEON_CRTC2_VSYNC_DIS |
 -	     RADEON_CRTC2_HSYNC_DIS |
 -	     RADEON_CRTC2_DISP_DIS);
 -    crtc2_gen_cntl |= restore->crtc2_gen_cntl;
 -
      /* We prevent the CRTC from hitting the memory controller until
       * fully programmed
       */
@@@ -4153,7 -4672,13 +4182,13 @@@
      OUTREG(RADEON_CRTC2_PITCH,           restore->crtc2_pitch);
      OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
  
+     if (info->ChipFamily == CHIP_FAMILY_RS400) {
+ 	OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
+ 	OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
+ 	OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
+ 	OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
+     }
 -    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
 +    OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
  
  }
  
@@@ -4605,10 -5134,12 +4642,12 @@@
  {
      RADEONInfoPtr      info = RADEONPTR(pScrn);
      RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 -    RADEONController* pCRTC1 = pRADEONEnt->Controller[0];
 -    RADEONController* pCRTC2 = pRADEONEnt->Controller[1];
 -    RADEONConnector *pPort;
 +    RADEONCrtcPrivatePtr pCRTC1 = pRADEONEnt->Controller[0];
 +    RADEONCrtcPrivatePtr pCRTC2 = pRADEONEnt->Controller[1];
 +    xf86OutputPtr output;
-     RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
+ 
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "RADEONRestoreMode(%p)\n", restore);
  
      /* For Non-dual head card, we don't have private field in the Entity */
      if (!pRADEONEnt->HasCRTC2) {
@@@ -4876,19 -5449,27 +4926,21 @@@
  {
      RADEONInfoPtr  info = RADEONPTR(pScrn);
  
-     RADEONTRACE(("RADEONSaveMode(%p)\n", save));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "RADEONSaveMode(%p)\n", save);
  
 -    if (info->IsSecondary) {
 -        RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
 -        RADEONInfoPtr info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
 -        memcpy(&info->SavedReg, &info0->SavedReg, sizeof(RADEONSaveRec));
 -    } else {
 -        RADEONSaveMemMapRegisters(pScrn, save);
 -        RADEONSaveCommonRegisters(pScrn, save);
 -        RADEONSavePLLRegisters (pScrn, save);
 -        RADEONSaveCrtcRegisters (pScrn, save);
 -        RADEONSaveFPRegisters (pScrn, save);
 -        RADEONSaveCrtc2Registers (pScrn, save);
 -        RADEONSavePLL2Registers (pScrn, save);
 -	/*RADEONSavePalette(pScrn, save);*/
 -	/*memcpy(&info->ModeReg, &info->SavedReg, sizeof(RADEONSaveRec));*/
 -    }
 +    RADEONSaveMemMapRegisters(pScrn, save);
 +    RADEONSaveCommonRegisters(pScrn, save);
 +    RADEONSavePLLRegisters (pScrn, save);
 +    RADEONSaveCrtcRegisters (pScrn, save);
 +    RADEONSaveFPRegisters (pScrn, save);
 +    RADEONSaveDACRegisters (pScrn, save);
 +    RADEONSaveCrtc2Registers (pScrn, save);
 +    RADEONSavePLL2Registers (pScrn, save);
 +    /*RADEONSavePalette(pScrn, save);*/
  
-     RADEONTRACE(("RADEONSaveMode returns %p\n", save));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "RADEONSaveMode returns %p\n", save);
  }
  
  /* Save everything needed to restore the original VC state */
@@@ -5061,19 -5655,17 +5116,19 @@@
  			       RADEON_TV_DAC_GDACPD);
      }
      /* FIXME: doesn't make sense, this just replaces the previous value... */
-     save->tv_dac_cntl = (RADEON_TV_DAC_NBLANK |
+     save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
  			 RADEON_TV_DAC_NHOLD |
- 			 RADEON_TV_DAC_STD_PS2 |
- 			 info->tv_dac_adj);
+ 			  RADEON_TV_DAC_STD_PS2);
+ 			  //			 info->tv_dac_adj);
  }
  
 -static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
 +static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
  				  DisplayModePtr mode, BOOL IsPrimary)
  {
 +    ScrnInfoPtr pScrn = output->scrn;
      RADEONInfoPtr  info       = RADEONPTR(pScrn);
 -    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 +    RADEONEntPtr  pRADEONEnt = RADEONEntPriv(pScrn);
 +    RADEONOutputPrivatePtr radeon_output = output->driver_private;
      int i;
      CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
  
@@@ -5976,10 -6635,21 +6041,11 @@@
      }
  #endif
  
-     RADEONTRACE(("RADEONSwitchMode() !n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "RADEONSwitchMode() !n");
  
      if (info->allowColorTiling) {
 -	if (info->MergedFB) {
 -	    if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags &
 -		(V_DBLSCAN | V_INTERLACE)) ||
 -		(((RADEONMergedDisplayModePtr)mode->Private)->CRT2->Flags &
 -		(V_DBLSCAN | V_INTERLACE)))
 -		info->tilingEnabled = FALSE;
 -	    else info->tilingEnabled = TRUE;
 -	}
 -	else {
 -            info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
 -	}
 +        info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
  #ifdef XF86DRI	
  	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
  	    RADEONSAREAPrivPtr pSAREAPriv;
@@@ -6226,9 -6893,9 +6293,10 @@@
      ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
      RADEONInfoPtr  info  = RADEONPTR(pScrn);
      unsigned char *RADEONMMIO = info->MMIO;
 +    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
  
-     RADEONTRACE(("RADEONEnterVT\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ 		   "RADEONEnterVT\n");
  
      if (INREG(RADEON_CONFIG_MEMSIZE) == 0) { /* Softboot V_BIOS */
         xf86Int10InfoPtr pInt;
diff-tree 800bf53279e2c2bf854682bbfd6fa16d03afed00 (from c2637a01f9aca4032262c66ade305f5fe2c54294)
Author: Matthieu Herrb <matthieu at deville.herrb.com>
Date:   Tue May 29 23:31:13 2007 -0600

    Fix build without XF86DRI

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 070daaf..0e1d82e 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -239,9 +239,9 @@ 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)
@@ -365,8 +365,10 @@ radeon_crtc_shadow_allocate (xf86CrtcPtr
 		       "Couldn't allocate shadow memory for rotated CRTC\n");
 	    return NULL;
 	}
+#ifdef XF86DRI
 	rotate_offset = info->frontOffset +
 	    radeon_crtc->rotate_mem_xaa->offset * cpp;
+#endif
     }
 #endif /* USE_XAA */
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c57e13e..42d1899 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3315,14 +3315,22 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     char*          s;
 #endif
 
+
+#ifdef XF86DRI
     RADEONTRACE(("RADEONScreenInit %lx %ld %d\n",
 		 pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset));
+#else
+    RADEONTRACE(("RADEONScreenInit %lx %ld\n",
+		 pScrn->memPhysBase, pScrn->fbOffset));
+#endif
 
     info->accelOn      = FALSE;
 #ifdef USE_XAA
     info->accel        = NULL;
 #endif
+#ifdef XF86DRI
     pScrn->fbOffset    = info->frontOffset;
+#endif
     if (!RADEONMapMem(pScrn)) return FALSE;
 
 #ifdef XF86DRI
@@ -3497,6 +3505,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     /* Setup DRI after visuals have been established, but before fbScreenInit is
      * called.  fbScreenInit will eventually call the driver's InitGLXVisuals
      * call back. */
+#ifdef XF86DRI
     if (info->directRenderingEnabled) {
 	/* FIXME: When we move to dynamic allocation of back and depth
 	 * buffers, we will want to revisit the following check for 3
@@ -3520,7 +3529,6 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 	}
     }
 
-#if defined(XF86DRI)
     /* Tell DRI about new memory map */
     if (info->directRenderingEnabled && info->newMemoryMap) {
         if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
diff-tree 4c61c0ee91a2ffeefce30972a584486f1df1d1ae (from 5337e7bd0069a3f2c4ab22b21a19471427ad3d81)
Author: Matthieu Herrb <matthieu at deville.herrb.com>
Date:   Tue May 29 21:35:35 2007 -0600

    Fix build without XF86DRI

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 5eca577..25921ad 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3799,15 +3799,23 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     char*          s;
 #endif
 
+#ifdef XF86DRI
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
 		   "RADEONScreenInit %lx %ld %d\n",
 		   pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset);
+#else
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONScreenInit %lx %ld\n",
+		   pScrn->memPhysBase, pScrn->fbOffset);
+#endif
 
     info->accelOn      = FALSE;
 #ifdef USE_XAA
     info->accel        = NULL;
 #endif
+#ifdef XF86DRI
     pScrn->fbOffset    = info->frontOffset;
+#endif
     if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
     if (!RADEONMapMem(pScrn)) return FALSE;
 
@@ -3997,6 +4005,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     /* Setup DRI after visuals have been established, but before fbScreenInit is
      * called.  fbScreenInit will eventually call the driver's InitGLXVisuals
      * call back. */
+#ifdef XF86DRI
     if (info->directRenderingEnabled) {
 	/* FIXME: When we move to dynamic allocation of back and depth
 	 * buffers, we will want to revisit the following check for 3
@@ -4020,7 +4029,6 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 	}
     }
 
-#if defined(XF86DRI)
     /* Tell DRI about new memory map */
     if (info->directRenderingEnabled && info->newMemoryMap) {
         if (RADEONDRISetParam(pScrn, RADEON_SETPARAM_NEW_MEMMAP, 1) < 0) {
diff-tree 5337e7bd0069a3f2c4ab22b21a19471427ad3d81 (from bff809dc8ed07ac39e9b576a87916486a5e37156)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Wed May 30 08:10:44 2007 +1000

    radeon: add bios quirk for nx6125 monid

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index dd3d0a7..e62fb25 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -34,12 +34,28 @@
 #include "xf86.h"
 #include "xf86_OSproc.h"
 
+#include "xf86PciInfo.h"
 #include "radeon.h"
 #include "radeon_reg.h"
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "vbe.h"
 
+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) {
+      if (info->PciInfo->subsysCard == 0x308b) {
+	if (pRADEONEnt->PortInfo[1]->DDCType == DDC_CRT2)
+	  pRADEONEnt->PortInfo[1]->DDCType        = DDC_MONID;
+      }
+    }
+    return connector_found;
+}
+
 /* Read the Video BIOS block and the FP registers (if applicable). */
 Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 {
@@ -313,6 +329,8 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 	    connector_found = 1;
 	}
 
+	connector_found = RADEONBIOSApplyConnectorQuirks(pScrn, connector_found);
+	
 	if (connector_found == 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No connector found in Connector Info Table.\n");
 	} else {
diff-tree bff809dc8ed07ac39e9b576a87916486a5e37156 (from 104105fee5c3945d3f210e6a4cb73ab492c61543)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Wed May 30 08:02:26 2007 +1000

    rs480: more unknown regs
    
    Hardcode the values from a working fglrx run, this works for me now
    
    I've no idea what it might do for anyone else

diff --git a/src/radeon.h b/src/radeon.h
index 3e79c1b..88402df 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -318,7 +318,10 @@ typedef struct {
 
     CARD32            tv_dac_cntl;
 
+    CARD32            rs480_unk_e30;
+    CARD32            rs480_unk_e34;
     CARD32            rs480_unk_e38;
+    CARD32            rs480_unk_e3c;
 } RADEONSaveRec, *RADEONSavePtr;
 
 typedef struct {
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a3d8a03..5eca577 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4665,7 +4665,10 @@ static void RADEONRestoreCrtc2Registers(
     OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
 
     if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	OUTREG(RADEON_RS480_UNK_e30, restore->rs480_unk_e30);
+	OUTREG(RADEON_RS480_UNK_e34, restore->rs480_unk_e34);
 	OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
+	OUTREG(RADEON_RS480_UNK_e3c, restore->rs480_unk_e3c);
     }
     OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
 
@@ -5363,8 +5366,12 @@ static void RADEONSaveCrtc2Registers(Scr
     save->fp_h2_sync_strt_wid   = INREG (RADEON_FP_H2_SYNC_STRT_WID);
     save->fp_v2_sync_strt_wid   = INREG (RADEON_FP_V2_SYNC_STRT_WID);
 
-    if (info->ChipFamily == CHIP_FAMILY_RS400)
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->rs480_unk_e30 = INREG(RADEON_RS480_UNK_e30);
+	save->rs480_unk_e34 = INREG(RADEON_RS480_UNK_e34);
 	save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
+	save->rs480_unk_e3c = INREG(RADEON_RS480_UNK_e3c);
+    }
     
     save->disp2_merge_cntl      = INREG(RADEON_DISP2_MERGE_CNTL);
 }
@@ -6241,8 +6248,10 @@ static Bool RADEONInitCrtc2Registers(Scr
 #endif
  
     if (info->ChipFamily == CHIP_FAMILY_RS400) {
-	save->rs480_unk_e38 = info->SavedReg.rs480_unk_e38 & ~(0x300);
-	save->rs480_unk_e38 |= 0x100;
+	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;
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 476c56b..01bcec8 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3127,5 +3127,9 @@
 #       define RADEON_TVPLL_SLEEP                (1 <<  3)
 #       define RADEON_TVPLL_REFCLK_SEL           (1 <<  4)
 
+#define RADEON_RS480_UNK_e30			0xe30
+#define RADEON_RS480_UNK_e34			0xe34
 #define RADEON_RS480_UNK_e38			0xe38
+#define RADEON_RS480_UNK_e3c			0xe3c
+
 #endif
diff-tree 104105fee5c3945d3f210e6a4cb73ab492c61543 (from 5aa603bcabbb077dec169c48438c2e2ebe1195d7)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Tue May 29 19:09:33 2007 +1000

    rs480: make second crtc work with magic number in magic register.
    
    I've no idea why or what this does.

diff --git a/src/radeon.h b/src/radeon.h
index 3ea44f3..3e79c1b 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -318,6 +318,7 @@ typedef struct {
 
     CARD32            tv_dac_cntl;
 
+    CARD32            rs480_unk_e38;
 } RADEONSaveRec, *RADEONSavePtr;
 
 typedef struct {
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b0e4037..a3d8a03 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4664,6 +4664,9 @@ static void RADEONRestoreCrtc2Registers(
     OUTREG(RADEON_CRTC2_PITCH,           restore->crtc2_pitch);
     OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	OUTREG(RADEON_RS480_UNK_e38, restore->rs480_unk_e38);
+    }
     OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
 
 }
@@ -4858,11 +4861,10 @@ static void RADEONRestorePLL2Registers(S
     OUTPLLP(pScrn,
 	    RADEON_P2PLL_CNTL,
 	    RADEON_P2PLL_RESET
-	    | RADEON_P2PLL_ATOMIC_UPDATE_EN
-	    | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN,
+	    | RADEON_P2PLL_ATOMIC_UPDATE_EN,
 	    ~(RADEON_P2PLL_RESET
-	      | RADEON_P2PLL_ATOMIC_UPDATE_EN
-	      | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN));
+	      | RADEON_P2PLL_ATOMIC_UPDATE_EN));
+
 
     OUTPLLP(pScrn, RADEON_P2PLL_REF_DIV,
 	    restore->p2pll_ref_div,
@@ -4885,17 +4887,16 @@ static void RADEONRestorePLL2Registers(S
 	    0,
 	    ~(RADEON_P2PLL_RESET
 	      | RADEON_P2PLL_SLEEP
-	      | RADEON_P2PLL_ATOMIC_UPDATE_EN
-	      | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN));
+	      | RADEON_P2PLL_ATOMIC_UPDATE_EN));
 
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n",
+		   "Wrote2: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n",
 		   restore->p2pll_ref_div,
 		   restore->p2pll_div_0,
 		   restore->htotal_cntl2,
 		   INPLL(pScrn, RADEON_P2PLL_CNTL));
     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
-		   "Wrote: rd=%ld, fd=%ld, pd=%ld\n",
+		   "Wrote2: rd=%ld, fd=%ld, pd=%ld\n",
 		   restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
 		   restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
 		   (restore->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >>16);
@@ -5362,6 +5363,9 @@ static void RADEONSaveCrtc2Registers(Scr
     save->fp_h2_sync_strt_wid   = INREG (RADEON_FP_H2_SYNC_STRT_WID);
     save->fp_v2_sync_strt_wid   = INREG (RADEON_FP_V2_SYNC_STRT_WID);
 
+    if (info->ChipFamily == CHIP_FAMILY_RS400)
+	save->rs480_unk_e38 = INREG(RADEON_RS480_UNK_e38);
+    
     save->disp2_merge_cntl      = INREG(RADEON_DISP2_MERGE_CNTL);
 }
 
@@ -5636,10 +5640,10 @@ static void RADEONInitTvDacCntl(ScrnInfo
 			       RADEON_TV_DAC_GDACPD);
     }
     /* FIXME: doesn't make sense, this just replaces the previous value... */
-    save->tv_dac_cntl = (RADEON_TV_DAC_NBLANK |
+    save->tv_dac_cntl |= (RADEON_TV_DAC_NBLANK |
 			 RADEON_TV_DAC_NHOLD |
-			 RADEON_TV_DAC_STD_PS2 |
-			 info->tv_dac_adj);
+			  RADEON_TV_DAC_STD_PS2);
+			  //			 info->tv_dac_adj);
 }
 
 static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
@@ -6236,6 +6240,11 @@ static Bool RADEONInitCrtc2Registers(Scr
     }
 #endif
  
+    if (info->ChipFamily == CHIP_FAMILY_RS400) {
+	save->rs480_unk_e38 = info->SavedReg.rs480_unk_e38 & ~(0x300);
+	save->rs480_unk_e38 |= 0x100;
+    }
+
     return TRUE;
 }
 
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 81acd46..476c56b 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3126,4 +3126,6 @@
 #       define RADEON_TVCLK_SRC_SEL_TVPLL        (1 << 30)
 #       define RADEON_TVPLL_SLEEP                (1 <<  3)
 #       define RADEON_TVPLL_REFCLK_SEL           (1 <<  4)
+
+#define RADEON_RS480_UNK_e38			0xe38
 #endif
diff-tree 5aa603bcabbb077dec169c48438c2e2ebe1195d7 (from c52322354fe64725733842b3356798c50e7735d5)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Tue May 29 07:23:24 2007 +1000

    rs480: only has single dac

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a812195..b0e4037 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1720,7 +1720,7 @@ static Bool RADEONPreInitChipType(ScrnIn
     case PCI_CHIP_RS482_5974:
 	info->ChipFamily = CHIP_FAMILY_RS400;
 	info->IsIGP = TRUE;
-	/*info->HasSingleDAC = TRUE;*/ /* ??? */
+	info->HasSingleDAC = TRUE;
         break;
 
     case PCI_CHIP_RV410_564A:
diff-tree c52322354fe64725733842b3356798c50e7735d5 (from parents)
Merge: dd6a966e862b774a8e8b9e1a085309219673efad 975da595f032c145ad74079ff8edeaead779dc7b
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Tue May 29 07:21:48 2007 +1000

    Merge branch 'origin'

diff-tree c2637a01f9aca4032262c66ade305f5fe2c54294 (from bbb769c4107bfcae682e46d026e54cbfb67d62cd)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 18:26:35 2007 -0400

    RADEON: remove some dead code from the last commit

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 473aa30..c57e13e 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3735,18 +3735,6 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     info->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = RADEONBlockHandler;
 
-#if 0
-    /* Rotation */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
-    xf86DisableRandR(); /* Disable built-in RandR extension */
-
-    xf86RandR12Init (pScreen);
-    xf86RandR12SetRotations (pScreen, RR_Rotate_0);
-
-    info->CreateScreenResources = pScreen->CreateScreenResources;
-    pScreen->CreateScreenResources = RADEONCreateScreenResources;
-#endif
-
    if (!xf86CrtcScreenInit (pScreen))
        return FALSE;
 
diff-tree bbb769c4107bfcae682e46d026e54cbfb67d62cd (from a69f90be9384244744fabfa76469ede9cd26ac98)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 18:25:06 2007 -0400

    RADEON: more rotation work (still not there)
    
    - once again borrowed heavily from intel

diff --git a/src/radeon.h b/src/radeon.h
index fcbae2a..d75b154 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -725,10 +725,7 @@ typedef struct {
     /* X itself has the 3D context */
     Bool              XInited3D;
 
-  DisplayModePtr currentMode, savedCurrentMode;
-    /* merged fb stuff, also covers clone modes */
-    void        	(*PointerMoved)(int index, int x, int y);
-    Bool		NoVirtual;
+    DisplayModePtr currentMode, savedCurrentMode;
 
     int			constantDPI; /* -1 = auto, 0 = off, 1 = on */
     int			RADEONDPIVX, RADEONDPIVY;
@@ -745,6 +742,8 @@ typedef struct {
 
     RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
 
+    Rotation rotation;
+    void (*PointerMoved)(int, int, int);
     CreateScreenResourcesProcPtr CreateScreenResources;
 } RADEONInfoRec, *RADEONInfoPtr;
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index be1427b..473aa30 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3275,6 +3275,33 @@ Bool RADEONSetupMemXAA(int scrnIndex, Sc
 }
 #endif /* USE_XAA */
 
+static void
+RADEONPointerMoved(int index, int x, int y)
+{
+    ScrnInfoPtr pScrn = xf86Screens[index];
+    RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    int newX = x, newY = y;
+
+    switch (info->rotation) {
+    case RR_Rotate_0:
+	break;
+    case RR_Rotate_90:
+	newX = y;
+	newY = pScrn->pScreen->width - x - 1;
+	break;
+    case RR_Rotate_180:
+	newX = pScrn->pScreen->width - x - 1;
+	newY = pScrn->pScreen->height - y - 1;
+	break;
+    case RR_Rotate_270:
+	newX = pScrn->pScreen->height - y - 1;
+	newY = x;
+	break;
+    }
+
+    (*info->PointerMoved)(index, newX, newY);
+}
+
 /* Called at the start of each server generation. */
 Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
                                 int argc, char **argv)
@@ -3708,6 +3735,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     info->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = RADEONBlockHandler;
 
+#if 0
     /* Rotation */
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
     xf86DisableRandR(); /* Disable built-in RandR extension */
@@ -3717,6 +3745,14 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     info->CreateScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = RADEONCreateScreenResources;
+#endif
+
+   if (!xf86CrtcScreenInit (pScreen))
+       return FALSE;
+
+    /* Wrap pointer motion to flip touch screen around */
+    info->PointerMoved = pScrn->PointerMoved;
+    pScrn->PointerMoved = RADEONPointerMoved;
 
     /* Colormap setup */
     RADEONTRACE(("Initializing color map\n"));
diff-tree a69f90be9384244744fabfa76469ede9cd26ac98 (from 3b619d88a65a5801c85d120f2d39704194433f10)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 17:54:48 2007 -0400

    RADEON: first pass at rotation (not working yet)
    
    - based heavily on intel

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 621d811..070daaf 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -270,6 +270,167 @@ radeon_crtc_unlock(xf86CrtcPtr crtc)
         RADEON_SYNC(info, pScrn);
 }
 
+#ifdef USE_XAA
+/**
+ * Allocates memory from the XF86 linear allocator, but also purges
+ * memory if possible to cause the allocation to succeed.
+ */
+static FBLinearPtr
+radeon_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
+				 int granularity,
+				 MoveLinearCallbackProcPtr moveCB,
+				 RemoveLinearCallbackProcPtr removeCB,
+				 pointer privData)
+{
+    FBLinearPtr linear;
+    int max_size;
+
+    linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+					 removeCB, privData);
+    if (linear != NULL)
+	return linear;
+
+    /* The above allocation didn't succeed, so purge unlocked stuff and try
+     * again.
+     */
+    xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
+				    PRIORITY_EXTREME);
+
+    if (max_size < length)
+	return NULL;
+
+    xf86PurgeUnlockedOffscreenAreas(pScreen);
+
+    linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+					 removeCB, privData);
+
+    return linear;
+}
+#endif
+
+/**
+ * Allocates memory for a locked-in-framebuffer shadow of the given
+ * width and height for this CRTC's rotated shadow framebuffer.
+ */
+ 
+static void *
+radeon_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    ScreenPtr pScreen = pScrn->pScreen;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    unsigned long rotate_pitch;
+    unsigned long rotate_offset;
+    int align = KB(4), size;
+    int cpp = pScrn->bitsPerPixel / 8;
+
+    rotate_pitch = pScrn->displayWidth * cpp;
+    size = rotate_pitch * height;
+
+#ifdef USE_EXA
+    /* We could get close to what we want here by just creating a pixmap like
+     * normal, but we have to lock it down in framebuffer, and there is no
+     * setter for offscreen area locking in EXA currently.  So, we just
+     * allocate offscreen memory and fake up a pixmap header for it.
+     */
+    if (info->useEXA) {
+	assert(radeon_crtc->rotate_mem_exa == NULL);
+
+	radeon_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align,
+						       TRUE, NULL, NULL);
+	if (radeon_crtc->rotate_mem_exa == NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Couldn't allocate shadow memory for rotated CRTC\n");
+	    return NULL;
+	}
+	rotate_offset = radeon_crtc->rotate_mem_exa->offset;
+    }
+#endif /* USE_EXA */
+#ifdef USE_XAA
+    if (!info->useEXA) {
+	/* The XFree86 linear allocator operates in units of screen pixels,
+	 * sadly.
+	 */
+	size = (size + cpp - 1) / cpp;
+	align = (align + cpp - 1) / cpp;
+
+	assert(radeon_crtc->rotate_mem_xaa == NULL);
+
+	radeon_crtc->rotate_mem_xaa =
+	    radeon_xf86AllocateOffscreenLinear(pScreen, size, align,
+					       NULL, NULL, NULL);
+	if (radeon_crtc->rotate_mem_xaa == NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Couldn't allocate shadow memory for rotated CRTC\n");
+	    return NULL;
+	}
+	rotate_offset = info->frontOffset +
+	    radeon_crtc->rotate_mem_xaa->offset * cpp;
+    }
+#endif /* USE_XAA */
+
+    return info->FB + rotate_offset;
+}
+    
+/**
+ * Creates a pixmap for this CRTC's rotated shadow framebuffer.
+ */
+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;
+
+    if (!data)
+	data = radeon_crtc_shadow_allocate(crtc, width, height);
+    
+    rotate_pitch = pScrn->displayWidth * cpp;
+
+    rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
+					   width, height,
+					   pScrn->depth,
+					   pScrn->bitsPerPixel,
+					   rotate_pitch,
+					   data);
+
+    if (rotate_pixmap == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		   "Couldn't allocate shadow pixmap for rotated CRTC\n");
+    }
+
+    return rotate_pixmap;
+}
+
+static void
+radeon_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+    if (rotate_pixmap)
+	FreeScratchPixmapHeader(rotate_pixmap);
+    
+    if (data) {
+#ifdef USE_EXA
+	if (info->useEXA && radeon_crtc->rotate_mem_exa != NULL) {
+	    exaOffscreenFree(pScrn->pScreen, radeon_crtc->rotate_mem_exa);
+	    radeon_crtc->rotate_mem_exa = NULL;
+	}
+#endif /* USE_EXA */
+#ifdef USE_XAA
+	if (!info->useEXA) {
+	    xf86FreeOffscreenLinear(radeon_crtc->rotate_mem_xaa);
+	    radeon_crtc->rotate_mem_xaa = NULL;
+	}
+#endif /* USE_XAA */
+    }
+}
+
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
     .dpms = radeon_crtc_dpms,
     .save = NULL, /* XXX */
@@ -281,6 +442,9 @@ static const xf86CrtcFuncsRec radeon_crt
     .gamma_set = radeon_crtc_gamma_set,
     .lock = radeon_crtc_lock,
     .unlock = radeon_crtc_unlock,
+    .shadow_create = radeon_crtc_shadow_create,
+    .shadow_allocate = radeon_crtc_shadow_allocate,
+    .shadow_destroy = radeon_crtc_shadow_destroy,
     .set_cursor_colors = radeon_crtc_set_cursor_colors,
     .set_cursor_position = radeon_crtc_set_cursor_position,
     .show_cursor = radeon_crtc_show_cursor,
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index cccf783..0dceca9 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -45,6 +45,13 @@
 
 #include "xf86Crtc.h"
 
+#ifdef USE_EXA
+#include "exa.h"
+#endif
+#ifdef USE_XAA
+#include "xaa.h"
+#endif
+
 typedef enum
 {
     DDC_NONE_DETECTED,
@@ -131,6 +138,12 @@ typedef enum
 } RADEONOutputType;
 
 typedef struct _RADEONCrtcPrivateRec {
+#ifdef USE_XAA
+    FBLinearPtr rotate_mem_xaa;
+#endif
+#ifdef USE_EXA
+    ExaOffscreenArea *rotate_mem_exa;
+#endif
     int crtc_id;
     int binding;
     /* Lookup table values to be set when the CRTC is enabled */
diff-tree 3b619d88a65a5801c85d120f2d39704194433f10 (from 089ae4afd23322bf602d340c531c36a4c8b461ed)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 17:06:18 2007 -0400

    RADEON: clean up and add comment regarding clones

diff --git a/src/radeon_output.c b/src/radeon_output.c
index a5b3790..8ac43b2 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -787,7 +787,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    if (radeon_output->type != OUTPUT_LVDS)
 		output->possible_crtcs |= 2;
 
-	    output->possible_clones = 0 /*1|2*/;
+	    /* we can clone the DACs, and probably TV-out, 
+	       but I'm not sure it's worth the trouble */
+	    output->possible_clones = 0;
 
 	    RADEONInitConnector(output);
 	}
@@ -815,7 +817,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		}
 		output->driver_private = radeon_output;
 		output->possible_crtcs = 1;
-		output->possible_clones = 0 /*1|2*/;
+		output->possible_clones = 0;
 
 		RADEONInitConnector(output);
 
@@ -840,7 +842,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		}
 		output->driver_private = radeon_output;
 		output->possible_crtcs = 1;
-		output->possible_clones = 0 /*1|2*/;
+		output->possible_clones = 0;
 
 		RADEONInitConnector(output);
 	    }
diff-tree 089ae4afd23322bf602d340c531c36a4c8b461ed (from c4cef0c9481257a744ac99dfc7beb988ce51a8ee)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 15:49:11 2007 -0400

    RADEON: Switch SetOutputType() to use names rather than numbers

diff --git a/src/radeon_output.c b/src/radeon_output.c
index c65798d..a5b3790 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -569,32 +569,45 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     RADEONOutputType output;
+
     if (info->IsAtomBios) {
 	switch(radeon_output->ConnectorType) {
-	case 0: output = OUTPUT_NONE; break;
-	case 1: output = OUTPUT_VGA; break;
-	case 2:
-	case 3:
-	case 4: output = OUTPUT_DVI; break;
-	case 5: output = OUTPUT_STV; break;
-	case 6: output = OUTPUT_CTV; break;
-	case 7:
-	case 8: output = OUTPUT_LVDS; break;
-	case 9:
+	case CONNECTOR_VGA_ATOM:
+	    output = OUTPUT_VGA; break;
+	case CONNECTOR_DVI_I_ATOM:
+	case CONNECTOR_DVI_D_ATOM:
+	case CONNECTOR_DVI_A_ATOM:
+	    output = OUTPUT_DVI; break;
+	case CONNECTOR_STV_ATOM:
+	    output = OUTPUT_STV; break;
+	case CONNECTOR_CTV_ATOM:
+	    output = OUTPUT_CTV; break;
+	case CONNECTOR_LVDS_ATOM:
+	case CONNECTOR_DIGITAL_ATOM:
+	    output = OUTPUT_LVDS; break;
+	case CONNECTOR_NONE_ATOM:
+	case CONNECTOR_UNSUPPORTED_ATOM:
 	default:
 	    output = OUTPUT_NONE; break;
 	}
     }
     else {
 	switch(radeon_output->ConnectorType) {
-	case 0: output = OUTPUT_NONE; break;
-	case 1: output = OUTPUT_LVDS; break;
-	case 2: output = OUTPUT_VGA; break;
-	case 3:
-	case 4: output = OUTPUT_DVI; break;
-	case 5: output = OUTPUT_STV; break;
-	case 6: output = OUTPUT_CTV; break;
-	default: output = OUTPUT_NONE; break;
+	case CONNECTOR_PROPRIETARY:
+	    output = OUTPUT_LVDS; break;
+	case CONNECTOR_CRT:
+	    output = OUTPUT_VGA; break;
+	case CONNECTOR_DVI_I:
+	case CONNECTOR_DVI_D:
+	    output = OUTPUT_DVI; break;
+	case CONNECTOR_CTV:
+	    output = OUTPUT_STV; break;
+	case CONNECTOR_STV:
+	    output = OUTPUT_CTV; break;
+	case CONNECTOR_NONE:
+	case CONNECTOR_UNSUPPORTED:
+	default:
+	    output = OUTPUT_NONE; break;
 	}
     }
     radeon_output->type = output;
diff-tree c4cef0c9481257a744ac99dfc7beb988ce51a8ee (from 899c62e987d5c7524817ba85675e39a8a28e0232)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 13:12:37 2007 -0400

    RADEON: make sure we have the lock when SYNCing

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index e8a676a..621d811 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -241,17 +241,16 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     Bool           CPStarted   = info->CPStarted;
 
-    if (info->accelOn)
-        RADEON_SYNC(info, pScrn);
-
 #ifdef XF86DRI
     if (info->CPStarted && pScrn->pScreen) {
 	DRILock(pScrn->pScreen, 0);
+	if (info->accelOn)
+	    RADEON_SYNC(info, pScrn);
 	return TRUE;
-    } else {
-	return FALSE;
     }
 #endif
+    if (info->accelOn)
+        RADEON_SYNC(info, pScrn);
 
     return FALSE;
 
diff-tree 899c62e987d5c7524817ba85675e39a8a28e0232 (from 18857184ffa6847815d349c020b003f8401e36ee)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 12:54:01 2007 -0400

    RADEON: Make sure LVDS and FP2 routing info gets written

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 6409a6b..be1427b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4097,12 +4097,6 @@ void RADEONRestoreCrtc2Registers(ScrnInf
     RADEONTRACE(("Programming CRTC2, offset: 0x%08lx\n",
 		 restore->crtc2_offset));
 
-    /*    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) &
-	    (RADEON_CRTC2_VSYNC_DIS |
-	     RADEON_CRTC2_HSYNC_DIS |
-	     RADEON_CRTC2_DISP_DIS);
-	     crtc2_gen_cntl |= restore->crtc2_gen_cntl;*/
-
     /* We prevent the CRTC from hitting the memory controller until
      * fully programmed
      */
@@ -4143,6 +4137,7 @@ void RADEONRestoreFPRegisters(ScrnInfoPt
     OUTREG(RADEON_FP_HORZ_STRETCH,      restore->fp_horz_stretch);
     OUTREG(RADEON_FP_VERT_STRETCH,      restore->fp_vert_stretch);
     OUTREG(RADEON_FP_GEN_CNTL,          restore->fp_gen_cntl);
+    OUTREG(RADEON_FP2_GEN_CNTL,         restore->fp2_gen_cntl);
 
     /* old AIW Radeon has some BIOS initialization problem
      * with display buffer underflow, only occurs to DFP
@@ -4152,6 +4147,7 @@ void RADEONRestoreFPRegisters(ScrnInfoPt
 	       INREG(RADEON_GRPH_BUFFER_CNTL) & ~0x7f0000);
 
     if (info->IsMobility) {
+	OUTREG(RADEON_LVDS_GEN_CNTL,  restore->lvds_gen_cntl);
 	OUTREG(RADEON_BIOS_4_SCRATCH, restore->bios_4_scratch);
 	OUTREG(RADEON_BIOS_5_SCRATCH, restore->bios_5_scratch);
 	OUTREG(RADEON_BIOS_6_SCRATCH, restore->bios_6_scratch);
@@ -4754,6 +4750,9 @@ static void RADEONSaveFPRegisters(ScrnIn
     save->bios_5_scratch       = INREG(RADEON_BIOS_5_SCRATCH);
     save->bios_6_scratch       = INREG(RADEON_BIOS_6_SCRATCH);
 
+    save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_DISPLAY_DIS);
+    save->lvds_gen_cntl &= ~(RADEON_LVDS_BLON);
+
     if (info->ChipFamily == CHIP_FAMILY_RV280) {
 	/* bit 22 of TMDS_PLL_CNTL is read-back inverted */
 	save->tmds_pll_cntl ^= (1 << 22);
@@ -5075,6 +5074,8 @@ static void RADEONInitFPRegisters(xf86Ou
 			 (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
@@ -5114,6 +5115,8 @@ static void RADEONInitFP2Registers(xf86O
 	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 | 
@@ -5125,25 +5128,14 @@ static void RADEONInitFP2Registers(xf86O
             save->fp2_gen_cntl   &= ~(RADEON_FP2_SRC_SEL_CRTC2 | 
                                       RADEON_FP2_DVO_RATE_SEL_SDR);
             }
-        /*save->fp2_gen_cntl   |= ( RADEON_FP2_ON |
-				    RADEON_FP2_BLANK_EN |
-                                    RADEON_FP2_DVO_EN);*/
     } 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 /*| 
-                                   RADEON_FP2_PANEL_FORMAT |
-				   RADEON_FP2_BLANK_EN |
-                                   RADEON_FP2_ON |
-                                   RADEON_FP2_DVO_EN*/);
+            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 /*| 
-                                   RADEON_FP2_PANEL_FORMAT |
-				   RADEON_FP2_BLANK_EN |
-                                   RADEON_FP2_ON |
-                                   RADEON_FP2_DVO_EN*/);
+            save->fp2_gen_cntl |= RADEON_FP2_SRC_SEL_CRTC2;
         }
     }
 
@@ -5155,12 +5147,14 @@ static void RADEONInitLVDSRegisters(xf86
     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 = info->SavedReg.lvds_gen_cntl &
-				~RADEON_LVDS_SEL_CRTC2;
+	save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
     else
-	save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl |
-				RADEON_LVDS_SEL_CRTC2;
+	save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
 
 }
 
diff-tree 18857184ffa6847815d349c020b003f8401e36ee (from 3a61453efb4f04492cef823b6dd1273b55c6a785)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 12:27:00 2007 -0400

    RADEON: fix handling of DRI lock

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 638bdd0..e8a676a 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -241,13 +241,20 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     Bool           CPStarted   = info->CPStarted;
 
+    if (info->accelOn)
+        RADEON_SYNC(info, pScrn);
+
 #ifdef XF86DRI
-    if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
+    if (info->CPStarted && pScrn->pScreen) {
+	DRILock(pScrn->pScreen, 0);
+	return TRUE;
+    } else {
+	return FALSE;
+    }
 #endif
 
-    if (info->accelOn)
-        RADEON_SYNC(info, pScrn);
     return FALSE;
+
 }
 
 static void
diff-tree 3a61453efb4f04492cef823b6dd1273b55c6a785 (from ceec3f62257bafe4771e75d3c4f1d2a517d7acf8)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sat May 26 01:38:09 2007 -0400

    RADEON: implement backlight control for LVDS
    
    This code is currently disabled as I'm not sure which
    laptops actually use this method for backlight control.
    My laptop seems to use another method as adjusting the
    backlight level doesn't seem to touch LVDS_GEN_CNTL.
    Maybe just macs?

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 0ea6d65..c65798d 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -391,9 +391,32 @@ radeon_destroy (xf86OutputPtr output)
         xfree(output->driver_private);
 }
 
+static void
+radeon_set_backlight_level(xf86OutputPtr output, int level)
+{
+    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;
+    lvds_gen_cntl |= (level << RADEON_LVDS_BL_MOD_LEVEL_SHIFT) & RADEON_LVDS_BL_MOD_LEVEL_MASK;
+    //usleep (radeon_output->PanelPwrDly * 1000);
+    OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+    lvds_gen_cntl &= ~RADEON_LVDS_BL_MOD_EN;
+    //usleep (radeon_output->PanelPwrDly * 1000);
+    OUTREG(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl);
+#endif
+}
+
 static Atom backlight_atom;
 static Atom rmx_atom;
 static Atom monitor_type_atom;
+#define RADEON_MAX_BACKLIGHT_LEVEL 255
 
 static void
 radeon_create_resources(xf86OutputPtr output)
@@ -409,7 +432,7 @@ radeon_create_resources(xf86OutputPtr ou
 	backlight_atom = MAKE_ATOM("BACKLIGHT");
 
 	range[0] = 0;
-	range[1] = 255; // i830_lvds_get_max_backlight(pScrn);
+	range[1] = RADEON_MAX_BACKLIGHT_LEVEL;
 	err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
 					FALSE, TRUE, FALSE, 2, range);
 	if (err != 0) {
@@ -417,7 +440,8 @@ radeon_create_resources(xf86OutputPtr ou
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the backlight property */
-	data = 127; //pI830->backlight_duty_cycle;
+	//data = (info->SavedReg.lvds_gen_cntl & RADEON_LVDS_BL_MOD_LEVEL_MASK) >> RADEON_LVDS_BL_MOD_LEVEL_SHIFT;
+	data = RADEON_MAX_BACKLIGHT_LEVEL;
 	err = RRChangeOutputProperty(output->randr_output, backlight_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &data,
 				     FALSE, TRUE);
@@ -433,7 +457,7 @@ radeon_create_resources(xf86OutputPtr ou
 	rmx_atom = MAKE_ATOM("PANELSCALER");
 
 	range[0] = 0;
-	range[1] = 2; // i830_lvds_get_max_backlight(pScrn);
+	range[1] = 2;
 	err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
 					FALSE, TRUE, FALSE, 2, range);
 	if (err != 0) {
@@ -441,7 +465,7 @@ radeon_create_resources(xf86OutputPtr ou
 		       "RRConfigureOutputProperty error, %d\n", err);
 	}
 	/* Set the current value of the backlight property */
-	data = 0; //pI830->backlight_duty_cycle;
+	data = 0;
 	err = RRChangeOutputProperty(output->randr_output, rmx_atom,
 				     XA_INTEGER, 32, PropModeReplace, 1, &data,
 				     FALSE, TRUE);
@@ -490,11 +514,25 @@ radeon_set_property(xf86OutputPtr output
 
 
     if (property == backlight_atom) {
-	return TRUE;
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < 0 || val > RADEON_MAX_BACKLIGHT_LEVEL)
+	    return FALSE;
+
+#if defined(__powerpc__)
+	val = RADEON_MAX_BACKLIGHT_LEVEL - val;
+#endif
+
+	radeon_set_backlight_level(output, val);
+
     } else if (property == rmx_atom) {
 	return TRUE;
     } else if (property == monitor_type_atom) {
-
 	if (value->type != XA_INTEGER ||
 	    value->format != 32 ||
 	    value->size != 1) {
@@ -732,6 +770,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    }
 	    output->driver_private = radeon_output;
 	    output->possible_crtcs = 1;
+	    /* crtc2 can drive LVDS, it just doesn't have RMX */
 	    if (radeon_output->type != OUTPUT_LVDS)
 		output->possible_crtcs |= 2;
 
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index b8bff78..892e8d0 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -876,6 +876,9 @@
 #       define RADEON_LVDS_PANEL_TYPE       (1   <<  2)
 #       define RADEON_LVDS_PANEL_FORMAT     (1   <<  3)
 #       define RADEON_LVDS_EN               (1   <<  7)
+#       define RADEON_LVDS_BL_MOD_LEVEL_SHIFT 8
+#       define RADEON_LVDS_BL_MOD_LEVEL_MASK (0xff << 8)
+#       define RADEON_LVDS_BL_MOD_EN        (1   << 16)
 #       define RADEON_LVDS_DIGON            (1   << 18)
 #       define RADEON_LVDS_BLON             (1   << 19)
 #       define RADEON_LVDS_SEL_CRTC2        (1   << 23)
diff-tree ceec3f62257bafe4771e75d3c4f1d2a517d7acf8 (from e3e9c608651e7cbb9851489274815f47d2a8dbbb)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 25 23:29:51 2007 -0400

    RADEON: implement auto/analog/digital output property for DVI-I (untested)

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 4e2fa0c..0ea6d65 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -335,11 +335,27 @@ static xf86OutputStatus
 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;
     RADEONConnectorFindMonitor(pScrn, output);
+
+    /* force montype based on output property */
+    if (radeon_output->type == OUTPUT_DVI) {
+	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
+	    if (radeon_output->MonType > MT_NONE) {
+		if (radeon_output->DVIType == DVI_ANALOG)
+		    radeon_output->MonType = MT_CRT;
+		else if (radeon_output->DVIType == DVI_DIGITAL)
+		    radeon_output->MonType = MT_DFP;
+	    }
+	}
+    }
+
+
     if (radeon_output->MonType == MT_UNKNOWN) {
         output->subpixel_order = SubPixelUnknown;
 	return XF86OutputStatusUnknown;
@@ -383,6 +399,7 @@ static void
 radeon_create_resources(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     INT32 range[2];
     int data, err;
@@ -434,27 +451,30 @@ radeon_create_resources(xf86OutputPtr ou
 	}
     }
 
-    /* force analog/digital for DVI-I ports */
-    /* FIXME: make sure this is DVI-I */
+    /* force auto/analog/digital for DVI-I ports */
     if (radeon_output->type == OUTPUT_DVI) {
-	monitor_type_atom = MAKE_ATOM("MONITORTYPE");
-
-	range[0] = 0;
-	range[1] = 1; // i830_lvds_get_max_backlight(pScrn);
-	err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
-					FALSE, TRUE, FALSE, 2, range);
-	if (err != 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "RRConfigureOutputProperty error, %d\n", err);
-	}
-	/* Set the current value of the backlight property */
-	data = 0; //pI830->backlight_duty_cycle;
-	err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
-				     XA_INTEGER, 32, PropModeReplace, 1, &data,
-				     FALSE, TRUE);
-	if (err != 0) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "RRChangeOutputProperty error, %d\n", err);
+	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I_ATOM) ||
+	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_I)) {
+	    monitor_type_atom = MAKE_ATOM("MONITORTYPE");
+
+	    range[0] = DVI_AUTO;
+	    range[1] = DVI_ANALOG;
+	    err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
+					    FALSE, TRUE, FALSE, 2, range);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRConfigureOutputProperty error, %d\n", err);
+	    }
+	    /* Set the current value of the backlight property */
+	    radeon_output->DVIType = DVI_AUTO;
+	    data = DVI_AUTO;
+	    err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
+					 XA_INTEGER, 32, PropModeReplace, 1, &data,
+					 FALSE, TRUE);
+	    if (err != 0) {
+		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			   "RRChangeOutputProperty error, %d\n", err);
+	    }
 	}
     }
 
@@ -465,13 +485,27 @@ radeon_set_property(xf86OutputPtr output
 		       RRPropertyValuePtr value)
 {
     ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    INT32 val;
+
 
     if (property == backlight_atom) {
 	return TRUE;
     } else if (property == rmx_atom) {
 	return TRUE;
     } else if (property == monitor_type_atom) {
-	return TRUE;
+
+	if (value->type != XA_INTEGER ||
+	    value->format != 32 ||
+	    value->size != 1) {
+	    return FALSE;
+	}
+
+	val = *(INT32 *)value->data;
+	if (val < DVI_AUTO || val > DVI_ANALOG)
+	    return FALSE;
+
+	radeon_output->DVIType = val;
     }
 
     return TRUE;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 6887388..cccf783 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -108,6 +108,13 @@ typedef enum
     TMDS_NONE    = 2
 } RADEONTmdsType;
 
+typedef enum
+{
+    DVI_AUTO,
+    DVI_DIGITAL,
+    DVI_ANALOG
+} RADEONDviType;
+
 typedef struct {
     CARD32 freq;
     CARD32 value;
@@ -143,6 +150,7 @@ typedef struct _RADEONOutputPrivateRec {
     void *dev_priv;
     RADEONDDCType DDCType;
     RADEONDacType DACType;
+    RADEONDviType DVIType;
     RADEONTmdsType TMDSType;
     RADEONConnectorType ConnectorType;
     RADEONMonitorType MonType;
diff-tree e3e9c608651e7cbb9851489274815f47d2a8dbbb (from a7d2c9c0f6155c4e65a2e73f3832c0d8ca7af5fc)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 25 19:26:24 2007 -0400

    RADEON: more clean of last commits

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 0577a05..4e2fa0c 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -192,12 +192,14 @@ static RADEONMonitorType RADEONPortCheck
     if (radeon_output->type == OUTPUT_LVDS) {
 	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
 	    MonType =  MT_LCD;
-    } else if (radeon_output->TMDSType == TMDS_INT) {
-	if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
-	    MonType = MT_DFP;
-    } else if (radeon_output->TMDSType == TMDS_EXT) {
-	if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
-	    MonType = MT_DFP;
+    } else if (radeon_output->type == OUTPUT_DVI) {
+	if (radeon_output->TMDSType == TMDS_INT) {
+	    if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
+		MonType = MT_DFP;
+	} else if (radeon_output->TMDSType == TMDS_EXT) {
+	    if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
+		MonType = MT_DFP;
+	}
     }
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff-tree a7d2c9c0f6155c4e65a2e73f3832c0d8ca7af5fc (from e50ca35ce2ea79dadb38ce14e459eed836452ff7)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 25 19:09:11 2007 -0400

    RADEON: fixup last commit and add support for ext TMDS detect

diff --git a/src/radeon_output.c b/src/radeon_output.c
index e823120..0577a05 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -192,9 +192,12 @@ static RADEONMonitorType RADEONPortCheck
     if (radeon_output->type == OUTPUT_LVDS) {
 	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
 	    MonType =  MT_LCD;
-    } else if (radeon_output->type == OUTPUT_DVI) {
+    } else if (radeon_output->TMDSType == TMDS_INT) {
 	if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
 	    MonType = MT_DFP;
+    } else if (radeon_output->TMDSType == TMDS_EXT) {
+	if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_DETECT_SENSE)
+	    MonType = MT_DFP;
     }
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 0d5e586..b8bff78 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -742,6 +742,7 @@
 #       define RADEON_FP2_BLANK_EN             (1 <<  1)
 #       define RADEON_FP2_ON                   (1 <<  2)
 #       define RADEON_FP2_PANEL_FORMAT         (1 <<  3)
+#       define RADEON_FP2_DETECT_SENSE         (1 <<  8)
 #       define R200_FP2_SOURCE_SEL_MASK        (3 << 10)
 #       define R200_FP2_SOURCE_SEL_CRTC1       (0 <<  10)
 #       define R200_FP2_SOURCE_SEL_CRTC2       (1 << 10)
diff-tree e50ca35ce2ea79dadb38ce14e459eed836452ff7 (from abb9b57e7b4162ab6c21fd1e809d24f13f7e1ea1)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 25 18:56:32 2007 -0400

    RADEON: clean up non-DDC probe, add detect for DVI

diff --git a/src/radeon_output.c b/src/radeon_output.c
index e45690b..e823120 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -189,15 +189,12 @@ static RADEONMonitorType RADEONPortCheck
     RADEONMonitorType MonType = MT_NONE;
 
 
-    if (info->IsMobility) {
-        if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
-	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
-	     if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
-	         MonType =  MT_LCD;
-        }
-	/* non-DDC TMDS panel connected through DVO */
-	if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_ON)
-	  MonType = MT_DFP;
+    if (radeon_output->type == OUTPUT_LVDS) {
+	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
+	    MonType =  MT_LCD;
+    } else if (radeon_output->type == OUTPUT_DVI) {
+	if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_DETECT_SENSE)
+	    MonType = MT_DFP;
     }
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff-tree abb9b57e7b4162ab6c21fd1e809d24f13f7e1ea1 (from 679236defd28bea8874004377436347950ff7bec)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 23 21:37:58 2007 -0400

    RADEON: clean up some logic

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 76affcb..3bbf371 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -568,14 +568,17 @@ RADEONMonitorType RADEONDisplayDDCConnec
 	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
 
     if (*MonInfo) {
-	/* if it's digital */
-	if ((*MonInfo)->rawData[0x14] & 0x80) {
-	    if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
-		radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)
-		MonType = MT_LCD;
-	    else
-		MonType = MT_DFP;
-	} else MonType = MT_CRT;
+	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,
diff --git a/src/radeon_output.c b/src/radeon_output.c
index ce743c5..e45690b 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -191,7 +191,7 @@ static RADEONMonitorType RADEONPortCheck
 
     if (info->IsMobility) {
         if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
-	     radeon_output->ConnectorType == CONNECTOR_PROPRIETARY) {
+	    (!info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
 	     if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
 	         MonType =  MT_LCD;
         }
diff-tree 679236defd28bea8874004377436347950ff7bec (from e38cad5633c974467f6417051eda8d487ac3686e)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 23 21:18:40 2007 -0400

    RADEON: add output properties (not functional yet)

diff --git a/src/radeon.h b/src/radeon.h
index 75dd234..fcbae2a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -78,6 +78,7 @@
 #endif
 
 #include "xf86Crtc.h"
+#include "X11/Xatom.h"
 
 				/* Render support */
 #ifdef RENDER
@@ -174,6 +175,8 @@ do {									\
 #define RADEONTRACE(x) do { } while(0)
 #endif
 
+/* for Xv, outputs */
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
 
 /* Other macros */
 #define RADEON_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index c24be8f..638bdd0 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -279,7 +279,6 @@ static const xf86CrtcFuncsRec radeon_crt
     .set_cursor_position = radeon_crtc_set_cursor_position,
     .show_cursor = radeon_crtc_show_cursor,
     .hide_cursor = radeon_crtc_hide_cursor,
-/*    .load_cursor_image = i830_crtc_load_cursor_image, */
     .load_cursor_argb = radeon_crtc_load_cursor_argb,
     .destroy = NULL, /* XXX */
 };
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 7fb5fb7..ce743c5 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -373,7 +373,110 @@ radeon_destroy (xf86OutputPtr output)
         xfree(output->driver_private);
 }
 
+static Atom backlight_atom;
+static Atom rmx_atom;
+static Atom monitor_type_atom;
+
+static void
+radeon_create_resources(xf86OutputPtr output)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    INT32 range[2];
+    int data, err;
+
+    /* backlight control */
+    if (radeon_output->type == OUTPUT_LVDS) {
+	backlight_atom = MAKE_ATOM("BACKLIGHT");
+
+	range[0] = 0;
+	range[1] = 255; // i830_lvds_get_max_backlight(pScrn);
+	err = RRConfigureOutputProperty(output->randr_output, backlight_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	/* Set the current value of the backlight property */
+	data = 127; //pI830->backlight_duty_cycle;
+	err = RRChangeOutputProperty(output->randr_output, backlight_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
+    /* RMX control - fullscreen, centered, keep ratio */
+    if (radeon_output->type == OUTPUT_LVDS ||
+	radeon_output->type == OUTPUT_DVI) {
+	rmx_atom = MAKE_ATOM("PANELSCALER");
+
+	range[0] = 0;
+	range[1] = 2; // i830_lvds_get_max_backlight(pScrn);
+	err = RRConfigureOutputProperty(output->randr_output, rmx_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	/* Set the current value of the backlight property */
+	data = 0; //pI830->backlight_duty_cycle;
+	err = RRChangeOutputProperty(output->randr_output, rmx_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
+    /* force analog/digital for DVI-I ports */
+    /* FIXME: make sure this is DVI-I */
+    if (radeon_output->type == OUTPUT_DVI) {
+	monitor_type_atom = MAKE_ATOM("MONITORTYPE");
+
+	range[0] = 0;
+	range[1] = 1; // i830_lvds_get_max_backlight(pScrn);
+	err = RRConfigureOutputProperty(output->randr_output, monitor_type_atom,
+					FALSE, TRUE, FALSE, 2, range);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRConfigureOutputProperty error, %d\n", err);
+	}
+	/* Set the current value of the backlight property */
+	data = 0; //pI830->backlight_duty_cycle;
+	err = RRChangeOutputProperty(output->randr_output, monitor_type_atom,
+				     XA_INTEGER, 32, PropModeReplace, 1, &data,
+				     FALSE, TRUE);
+	if (err != 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "RRChangeOutputProperty error, %d\n", err);
+	}
+    }
+
+}
+
+static Bool
+radeon_set_property(xf86OutputPtr output, Atom property,
+		       RRPropertyValuePtr value)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+
+    if (property == backlight_atom) {
+	return TRUE;
+    } else if (property == rmx_atom) {
+	return TRUE;
+    } else if (property == monitor_type_atom) {
+	return TRUE;
+    }
+
+    return TRUE;
+}
+
 static const xf86OutputFuncsRec radeon_output_funcs = {
+    .create_resources = radeon_create_resources,
     .dpms = radeon_dpms,
     .save = radeon_save,
     .restore = radeon_restore,
@@ -384,6 +487,7 @@ static const xf86OutputFuncsRec radeon_o
     .commit = radeon_mode_commit,
     .detect = radeon_detect,
     .get_modes = radeon_get_modes,
+    .set_property = radeon_set_property,
     .destroy = radeon_destroy
 };
 
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 6d085cc..5510d7b 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -99,7 +99,7 @@ static void RADEON_TDA9885_SetEncoding(R
 static void RADEON_FI1236_SetEncoding(RADEONPortPrivPtr pPriv);
 
 
-#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
 #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
 
 static Atom xvBrightness, xvColorKey, xvSaturation, xvDoubleBuffer;
diff-tree 975da595f032c145ad74079ff8edeaead779dc7b (from 8275151baac22c34149cef0b7d922771d24abc3e)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue May 22 10:56:47 2007 +0200

    radeon: Provide new DRI texOffsetStart hook when available with EXA.

diff --git a/src/radeon.h b/src/radeon.h
index 8c399cd..3ea44f3 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -851,6 +851,7 @@ extern Bool        RADEONAccelInit(Scree
 extern Bool        RADEONSetupMemEXA (ScreenPtr pScreen);
 extern Bool        RADEONDrawInitMMIO(ScreenPtr pScreen);
 #ifdef XF86DRI
+extern unsigned long long RADEONTexOffsetStart(PixmapPtr pPix);
 extern Bool        RADEONGetDatatypeBpp(int bpp, CARD32 *type);
 extern Bool        RADEONGetPixmapOffsetPitch(PixmapPtr pPix,
 					      CARD32 *pitch_offset);
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 24e31ab..39393f5 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1475,6 +1475,22 @@ Bool RADEONDRIScreenInit(ScreenPtr pScre
     pDRIInfo->createDummyCtx     = TRUE;
     pDRIInfo->createDummyCtxPriv = FALSE;
 
+#ifdef USE_EXA
+    if (info->useEXA) {
+#if DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3
+       int major, minor, patch;
+
+       DRIQueryVersion(&major, &minor, &patch);
+
+       if (minor >= 3)
+#endif
+#if DRIINFO_MAJOR_VERSION > 5 || \
+    (DRIINFO_MAJOR_VERSION == 5 && DRIINFO_MINOR_VERSION >= 3)
+	  pDRIInfo->texOffsetStart = RADEONTexOffsetStart;
+#endif
+    }
+#endif
+
     if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR,
 		   "[dri] DRIScreenInit failed.  Disabling DRI.\n");
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index f9bcace..d074f08 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -496,3 +496,20 @@ Bool RADEONSetupMemEXA (ScreenPtr pScree
 
     return TRUE;
 }
+
+#ifdef XF86DRI
+
+#ifndef ExaOffscreenMarkUsed
+extern void ExaOffscreenMarkUsed(PixmapPtr);
+#endif
+
+unsigned long long
+RADEONTexOffsetStart(PixmapPtr pPix)
+{
+    exaMoveInPixmap(pPix);
+    ExaOffscreenMarkUsed(pPix);
+
+    return RADEONPTR(xf86Screens[pPix->drawable.pScreen->myNum])->fbLocation +
+	exaGetPixmapOffset(pPix);
+}
+#endif
diff-tree e38cad5633c974467f6417051eda8d487ac3686e (from aed193a47a939451d9a6d05b02653b1d73e1d523)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue May 22 00:09:46 2007 -0400

    RADEON: Only add valid connectors

diff --git a/src/radeon_output.c b/src/radeon_output.c
index c2bebf0..7fb5fb7 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -556,47 +556,49 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     }
 
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-	if (!radeon_output) {
-	    return FALSE;
-	}
-	radeon_output->MonType = MT_UNKNOWN;
-	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
-	radeon_output->DDCType = info->BiosConnector[i].DDCType;
-	if (info->IsAtomBios) {
-	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM)
-		radeon_output->DACType = DAC_NONE;
-	    else
-		radeon_output->DACType = info->BiosConnector[i].DACType;
+	if (info->BiosConnector[i].ConnectorType != CONNECTOR_NONE) {
+	    RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+	    if (!radeon_output) {
+		return FALSE;
+	    }
+	    radeon_output->MonType = MT_UNKNOWN;
+	    radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
+	    radeon_output->DDCType = info->BiosConnector[i].DDCType;
+	    if (info->IsAtomBios) {
+		if (radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM)
+		    radeon_output->DACType = DAC_NONE;
+		else
+		    radeon_output->DACType = info->BiosConnector[i].DACType;
+
+		if (radeon_output->ConnectorType == CONNECTOR_VGA_ATOM)
+		    radeon_output->TMDSType = TMDS_NONE;
+		else
+		    radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	    } else {
+		if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
+		    radeon_output->DACType = DAC_NONE;
+		else
+		    radeon_output->DACType = info->BiosConnector[i].DACType;
+
+		if (radeon_output->ConnectorType == CONNECTOR_CRT)
+		    radeon_output->TMDSType = TMDS_NONE;
+		else
+		    radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	    }
+	    RADEONSetOutputType(pScrn, radeon_output);
+	    output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	    if (!output) {
+		return FALSE;
+	    }
+	    output->driver_private = radeon_output;
+	    output->possible_crtcs = 1;
+	    if (radeon_output->type != OUTPUT_LVDS)
+		output->possible_crtcs |= 2;
 
-	    if (radeon_output->ConnectorType == CONNECTOR_VGA_ATOM)
-		radeon_output->TMDSType = TMDS_NONE;
-	    else
-		radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
-	} else {
-	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
-		radeon_output->DACType = DAC_NONE;
-	    else
-		radeon_output->DACType = info->BiosConnector[i].DACType;
+	    output->possible_clones = 0 /*1|2*/;
 
-	    if (radeon_output->ConnectorType == CONNECTOR_CRT)
-		radeon_output->TMDSType = TMDS_NONE;
-	    else
-		radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	    RADEONInitConnector(output);
 	}
-	RADEONSetOutputType(pScrn, radeon_output);
-	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-	if (!output) {
-	    return FALSE;
-	}
-	output->driver_private = radeon_output;
-	output->possible_crtcs = 1;
-	if (radeon_output->type != OUTPUT_LVDS)
- 	    output->possible_crtcs |= 2;
-
-	output->possible_clones = 0 /*1|2*/;
-
-	RADEONInitConnector(output);
     }
 
     /* if it's a mobility make sure we have a LVDS port */
diff-tree 8275151baac22c34149cef0b7d922771d24abc3e (from 137e3fc1899078af0f72303ab0a4e6cf35804a7b)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon May 21 10:25:48 2007 +0200

    radeon: HW cursor cleanup.
    
    Don't needlessly turn the HW cursor on/off in RADEONLoadCursor*().
    
    Besides cleaning up the code, this semms to avoid some HW cursor related 3D
    lockups, see https://bugs.freedesktop.org/show_bug.cgi?id=10815 . My best
    guess is that this is because the engine is now always idled before touching
    the CRTC registers.

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index a45198a..ec80dd8 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -71,8 +71,6 @@ static CARD32 mono_cursor_color[] = {
 #define CURSOR_WIDTH	64
 #define CURSOR_HEIGHT	64
 
-#define COMMON_CURSOR_SWAPPING_START()	 RADEON_SYNC(info, pScrn)
-
 /*
  * The cursor bits are always 32bpp.  On MSBFirst buses,
  * configure byte swapping to swap 32 bit units when writing
@@ -84,7 +82,6 @@ static CARD32 mono_cursor_color[] = {
 #define CURSOR_SWAPPING_DECL_MMIO   unsigned char *RADEONMMIO = info->MMIO;
 #define CURSOR_SWAPPING_START() \
   do { \
-    COMMON_CURSOR_SWAPPING_START(); \
     OUTREG(RADEON_SURFACE_CNTL, \
 	   (info->ModeReg.surface_cntl | \
 	     RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP) & \
@@ -96,10 +93,7 @@ static CARD32 mono_cursor_color[] = {
 #else
 
 #define CURSOR_SWAPPING_DECL_MMIO
-#define CURSOR_SWAPPING_START() \
-  do { \
-    COMMON_CURSOR_SWAPPING_START(); \
-  } while (0)
+#define CURSOR_SWAPPING_START()
 #define CURSOR_SWAPPING_END()
 
 #endif
@@ -205,25 +199,11 @@ static void RADEONLoadCursorImage(ScrnIn
     unsigned char *RADEONMMIO = info->MMIO;
     CARD8         *s          = (CARD8 *)(pointer)image;
     CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
-    CARD32         save1      = 0;
-    CARD32         save2      = 0;
     CARD8	   chunk;
     CARD32         i, j;
 
     RADEONCTRACE(("RADEONLoadCursorImage (at %x)\n", info->cursor_offset));
 
-    if (!info->IsSecondary) {
-	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save1 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
-    }
-
-    if (info->IsSecondary || info->MergedFB) {
-	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save2 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-    }
-
 #ifdef ARGB_CURSOR
     info->cursor_argb = FALSE;
 #endif
@@ -237,23 +217,18 @@ static void RADEONLoadCursorImage(ScrnIn
      * (which actually bit swaps the image) to make the bits LSBFirst
      */
     CURSOR_SWAPPING_START();
+
 #define ARGB_PER_CHUNK	(8 * sizeof (chunk) / 2)
     for (i = 0; i < (CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK); i++) {
         chunk = *s++;
 	for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2)
 	    *d++ = mono_cursor_color[chunk & 3];
     }
+
     CURSOR_SWAPPING_END();
 
     info->cursor_bg = mono_cursor_color[2];
     info->cursor_fg = mono_cursor_color[3];
-
-    if (!info->IsSecondary)
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-
-    if (info->IsSecondary || info->MergedFB)
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-
 }
 
 /* Hide hardware cursor. */
@@ -264,6 +239,8 @@ static void RADEONHideCursor(ScrnInfoPtr
 
     RADEONCTRACE(("RADEONHideCursor\n"));
 
+    RADEON_SYNC(info, pScrn);
+
     if (info->IsSecondary || info->MergedFB)
 	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
 
@@ -279,13 +256,15 @@ static void RADEONShowCursor(ScrnInfoPtr
 
     RADEONCTRACE(("RADEONShowCursor\n"));
 
+    RADEON_SYNC(info, pScrn);
+
     if (info->IsSecondary || info->MergedFB)
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
-		~RADEON_CRTC2_CUR_EN);
+	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN | 2 << 20,
+		~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_CUR_MODE_MASK));
 
     if (!info->IsSecondary)
-	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
-		~RADEON_CRTC_CUR_EN);
+	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN | 2 << 20,
+		~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
 }
 
 /* Determine if hardware cursor is in use. */
@@ -314,25 +293,11 @@ static void RADEONLoadCursorARGB (ScrnIn
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
     int            x, y, w, h;
-    CARD32         save1      = 0;
-    CARD32         save2      = 0;
     CARD32	  *image = pCurs->bits->argb;
     CARD32	  *i;
 
     RADEONCTRACE(("RADEONLoadCursorARGB\n"));
 
-    if (!info->IsSecondary) {
-	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save1 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
-    }
-
-    if (info->IsSecondary || info->MergedFB) {
-	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save2 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-    }
-
 #ifdef ARGB_CURSOR
     info->cursor_argb = TRUE;
 #endif
@@ -361,13 +326,6 @@ static void RADEONLoadCursorARGB (ScrnIn
 	    *d++ = 0;
 
     CURSOR_SWAPPING_END ();
-
-    if (!info->IsSecondary)
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-
-    if (info->IsSecondary || info->MergedFB)
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-
 }
 
 #endif
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 0d5e586..81acd46 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -308,7 +308,7 @@
 #       define RADEON_CRTC_CSYNC_EN         (1 <<  4)
 #       define RADEON_CRTC_ICON_EN          (1 << 15)
 #       define RADEON_CRTC_CUR_EN           (1 << 16)
-#       define RADEON_CRTC_CUR_MODE_MASK    (7 << 17)
+#       define RADEON_CRTC_CUR_MODE_MASK    (7 << 20)
 #       define RADEON_CRTC_EXT_DISP_EN      (1 << 24)
 #       define RADEON_CRTC_EN               (1 << 25)
 #       define RADEON_CRTC_DISP_REQ_EN_B    (1 << 26)
diff-tree 137e3fc1899078af0f72303ab0a4e6cf35804a7b (from 09bfc8ed000f95ede5b73f2bad69edc1a4d9bac6)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Mon May 21 10:25:48 2007 +0200

    radeon: Suppress debugging output by default.
    
    It can be enabled at runtime by increasing the log verbosity level.
    
    Also change the prefix from (**) to (II) to make grepping the log file for
    defaults overridden by xorg.conf more useful again.
    
    Turn some MC related debugging output into normal informational output as it's
    useful for recognizing corner cases that can cause stability issues.

diff --git a/src/radeon.h b/src/radeon.h
index ce2fe19..8c399cd 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -186,7 +186,6 @@ typedef struct _region {
 
 /* ------------------------------------- */
 
-#define RADEON_DEBUG            1 /* Turn off debugging output               */
 #define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
 #define RADEON_TIMEOUT    2000000 /* Fall out of wait loops after this count */
 
@@ -198,15 +197,7 @@ typedef struct _region {
 				   * for something else.
 				   */
 
-#if RADEON_DEBUG
-#define RADEONTRACE(x)						\
-do {									\
-    ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex);		\
-    ErrorF x;								\
-} while(0)
-#else
-#define RADEONTRACE(x) do { } while(0)
-#endif
+#define RADEON_LOGLEVEL_DEBUG 4
 
 
 /* Other macros */
diff --git a/src/radeon_accel.c b/src/radeon_accel.c
index 41859c4..b739988 100644
--- a/src/radeon_accel.c
+++ b/src/radeon_accel.c
@@ -134,9 +134,10 @@ void RADEONWaitForFifoFunction(ScrnInfoP
 		INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
 	    if (info->fifo_slots >= entries) return;
 	}
-	RADEONTRACE(("FIFO timed out: %u entries, stat=0x%08x\n",
-		     INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
-		     INREG(RADEON_RBBM_STATUS)));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "FIFO timed out: %u entries, stat=0x%08x\n",
+		       INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+		       INREG(RADEON_RBBM_STATUS));
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "FIFO timed out, resetting engine...\n");
 	RADEONEngineReset(pScrn);
@@ -165,8 +166,9 @@ void RADEONEngineFlush(ScrnInfoPtr pScrn
 	    break;
     }
     if (i == RADEON_TIMEOUT) {
-	RADEONTRACE(("DC flush timeout: %x\n",
-		    INREG(RADEON_RB3D_DSTCACHE_CTLSTAT)));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "DC flush timeout: %x\n",
+		       INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
     }
 }
 
@@ -296,9 +298,10 @@ void RADEONEngineRestore(ScrnInfoPtr pSc
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    RADEONTRACE(("EngineRestore (%d/%d)\n",
-		 info->CurrentLayout.pixel_code,
-		 info->CurrentLayout.bitsPerPixel));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "EngineRestore (%d/%d)\n",
+		   info->CurrentLayout.pixel_code,
+		   info->CurrentLayout.bitsPerPixel);
 
     /* Setup engine location. This shouldn't be necessary since we
      * set them appropriately before any accel ops, but let's avoid
@@ -347,9 +350,10 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    RADEONTRACE(("EngineInit (%d/%d)\n",
-		 info->CurrentLayout.pixel_code,
-		 info->CurrentLayout.bitsPerPixel));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "EngineInit (%d/%d)\n",
+		   info->CurrentLayout.pixel_code,
+		   info->CurrentLayout.bitsPerPixel);
 
     OUTREG(RADEON_RB3D_CNTL, 0);
 
@@ -362,15 +366,17 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
     case 24: info->datatype = 5; break;
     case 32: info->datatype = 6; break;
     default:
-	RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n",
-		     info->CurrentLayout.depth,
-		     info->CurrentLayout.bitsPerPixel,
-		     info->CurrentLayout.pixel_code));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Unknown depth/bpp = %d/%d (code = %d)\n",
+		       info->CurrentLayout.depth,
+		       info->CurrentLayout.bitsPerPixel,
+		       info->CurrentLayout.pixel_code);
     }
     info->pitch = ((info->CurrentLayout.displayWidth / 8) *
 		   (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1));
 
-    RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Pitch for acceleration = %d\n", info->pitch);
 
     info->dp_gui_master_cntl =
 	((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c
index 70f7ddc..6a999af 100644
--- a/src/radeon_commonfuncs.c
+++ b/src/radeon_commonfuncs.c
@@ -156,9 +156,10 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnIn
 #endif
 
 #if 0
-    RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n",
-		     INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
-		     INREG(RADEON_RBBM_STATUS)));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "WaitForIdle (entering): %d entries, stat=0x%08x\n",
+		   INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+		   INREG(RADEON_RBBM_STATUS));
 #endif
 
     /* Wait for the engine to go idle */
@@ -171,9 +172,10 @@ void FUNC_NAME(RADEONWaitForIdle)(ScrnIn
 		return;
 	    }
 	}
-	RADEONTRACE(("Idle timed out: %u entries, stat=0x%08x\n",
-		     INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
-		     INREG(RADEON_RBBM_STATUS)));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Idle timed out: %u entries, stat=0x%08x\n",
+		       INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+		       INREG(RADEON_RBBM_STATUS));
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Idle timed out, resetting engine...\n");
 	RADEONEngineReset(pScrn);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index fb345a9..90fdc54 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1941,8 +1941,10 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
     OUTREG(RADEON_GRPH_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
 				     (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
 
-    RADEONTRACE(("GRPH_BUFFER_CNTL from %x to %x\n",
-		 (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL)));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "GRPH_BUFFER_CNTL from %x to %x\n",
+		   (unsigned int)info->SavedReg.grph_buffer_cntl,
+		   INREG(RADEON_GRPH_BUFFER_CNTL));
 
     if (mode2) {
 	stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16;
@@ -1989,8 +1991,10 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
 	OUTREG(RADEON_GRPH2_BUFFER_CNTL, ((temp & ~RADEON_GRPH_CRITICAL_POINT_MASK) |
 					  (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
 
-	RADEONTRACE(("GRPH2_BUFFER_CNTL from %x to %x\n",
-		     (unsigned int)info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL)));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "GRPH2_BUFFER_CNTL from %x to %x\n",
+		       (unsigned int)info->SavedReg.grph2_buffer_cntl,
+		       INREG(RADEON_GRPH2_BUFFER_CNTL));
     }
 }
 
@@ -2266,7 +2270,9 @@ void RADEONDisplayPowerManagementSet(Scr
     RADEONConnector *pPort;
     if (!pScrn->vtSema) return;
 
-    RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONDisplayPowerManagementSet(%d,0x%x)\n",
+		   PowerManagementMode, flags);
 
 #ifdef XF86DRI
     if (info->CPStarted) DRILock(pScrn->pScreen, 0);
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index b09a8cf..24e31ab 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1690,7 +1690,8 @@ void RADEONDRIStop(ScreenPtr pScreen)
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     RING_LOCALS;
 
-    RADEONTRACE(("RADEONDRIStop\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONDRIStop\n");
 
     /* Stop the CP */
     if (info->directRenderingInited) {
@@ -1712,7 +1713,8 @@ void RADEONDRICloseScreen(ScreenPtr pScr
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     drmRadeonInit  drmInfo;
 
-     RADEONTRACE(("RADEONDRICloseScreen\n"));
+     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		    "RADEONDRICloseScreen\n");
     
      if (info->irq) {
 	drmCtlUninstHandler(info->drmFD);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 933265f..a812195 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -626,7 +626,8 @@ static Bool RADEONMapFB(ScrnInfoPtr pScr
     if (info->FBDev) {
 	info->FB = fbdevHWMapVidmem(pScrn);
     } else {
-	RADEONTRACE(("Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Map: 0x%08lx, 0x%08lx\n", info->LinearAddr, info->FbMapSize);
 	info->FB = xf86MapPciMem(pScrn->scrnIndex,
 				 VIDMEM_FRAMEBUFFER,
 				 info->PciTag,
@@ -1285,10 +1286,14 @@ static void RADEONInitMemoryMap(ScrnInfo
      */
     info->mc_agp_location = 0xffffffc0;
 
-    RADEONTRACE(("RADEONInitMemoryMap() : \n"));
-    RADEONTRACE(("  mem_size         : 0x%08lx\n", mem_size));
-    RADEONTRACE(("  MC_FB_LOCATION   : 0x%08lx\n", info->mc_fb_location));
-    RADEONTRACE(("  MC_AGP_LOCATION  : 0x%08lx\n", info->mc_agp_location));
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "RADEONInitMemoryMap() : \n");
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "  mem_size         : 0x%08lx\n", mem_size);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "  MC_FB_LOCATION   : 0x%08lx\n", info->mc_fb_location);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "  MC_AGP_LOCATION  : 0x%08lx\n", info->mc_agp_location);
 }
 
 static void RADEONGetVRamType(ScrnInfoPtr pScrn)
@@ -3002,7 +3007,8 @@ Bool RADEONPreInit(ScrnInfoPtr pScrn, in
     const char *s;
     MessageType from;
 
-    RADEONTRACE(("RADEONPreInit\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONPreInit\n");
     if (pScrn->numEntities != 1) return FALSE;
 
     if (!RADEONGetRec(pScrn)) return FALSE;
@@ -3793,8 +3799,9 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     char*          s;
 #endif
 
-    RADEONTRACE(("RADEONScreenInit %lx %ld %d\n",
-		 pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONScreenInit %lx %ld %d\n",
+		   pScrn->memPhysBase, pScrn->fbOffset, info->frontOffset);
 
     info->accelOn      = FALSE;
 #ifdef USE_XAA
@@ -3911,13 +3918,15 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     /* Initial setup of surfaces */
     if (!info->IsSecondary) {
-	RADEONTRACE(("Setting up initial surfaces\n"));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Setting up initial surfaces\n");
 	RADEONChangeSurfaces(pScrn);
     }
 
 				/* Memory manager setup */
 
-    RADEONTRACE(("Setting up accel memmap\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Setting up accel memmap\n");
 
 #ifdef USE_EXA
     if (info->useEXA) {
@@ -4022,7 +4031,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 	}
     }
 #endif
-    RADEONTRACE(("Initializing fb layer\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing fb layer\n");
 
     /* Init fb layer */
     if (!fbScreenInit(pScreen, info->FB + pScrn->fbOffset,
@@ -4090,7 +4100,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
     /* Backing store setup */
-    RADEONTRACE(("Initializing backing store\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing backing store\n");
     miInitializeBackingStore(pScreen);
     xf86SetBackingStore(pScreen);
 
@@ -4110,7 +4121,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
       }
     }
     if (info->directRenderingEnabled) {
-        RADEONTRACE(("DRI Finishing init !\n"));
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "DRI Finishing init !\n");
 	info->directRenderingEnabled = RADEONDRIFinishScreenInit(pScreen);
     }
     if (info->directRenderingEnabled) {
@@ -4140,7 +4152,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     /* Make sure surfaces are allright since DRI setup may have changed them */
     if (!info->IsSecondary) {
-	RADEONTRACE(("Setting up final surfaces\n"));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Setting up final surfaces\n");
 	RADEONChangeSurfaces(pScrn);
     }
 
@@ -4150,7 +4163,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     /* Enable aceleration */
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
-	 RADEONTRACE(("Initializing Acceleration\n"));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "Initializing Acceleration\n");
 	if (RADEONAccelInit(pScreen)) {
 	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
 	    info->accelOn = TRUE;
@@ -4166,10 +4180,12 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     }
 
     /* Init DPMS */
-    RADEONTRACE(("Initializing DPMS\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing DPMS\n");
     xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
 
-    RADEONTRACE(("Initializing Cursor\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing Cursor\n");
 
     /* Set Silken Mouse */
     xf86SetSilkenMouse(pScreen);
@@ -4207,7 +4223,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     }
 
     /* Colormap setup */
-    RADEONTRACE(("Initializing color map\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing color map\n");
     if (!miCreateDefColormap(pScreen)) return FALSE;
     if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
 			     RADEONLoadPalette, NULL,
@@ -4218,7 +4235,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 			     | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
 
     /* DGA setup */
-    RADEONTRACE(("Initializing DGA\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing DGA\n");
     RADEONDGAInit(pScreen);
 
     /* Wrap some funcs for MergedFB */
@@ -4235,7 +4253,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     }
 
     /* Init Xv */
-    RADEONTRACE(("Initializing Xv\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Initializing Xv\n");
     RADEONInitVideo(pScreen);
 
     if(info->MergedFB)
@@ -4254,7 +4273,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     if (serverGeneration == 1)
 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
-    RADEONTRACE(("RADEONScreenInit finished\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONScreenInit finished\n");
 
     return TRUE;
 }
@@ -4268,9 +4288,12 @@ static void RADEONRestoreMemMapRegisters
     unsigned char *RADEONMMIO = info->MMIO;
     int timeout;
 
-    RADEONTRACE(("RADEONRestoreMemMapRegisters() : \n"));
-    RADEONTRACE(("  MC_FB_LOCATION   : 0x%08lx\n", restore->mc_fb_location));
-    RADEONTRACE(("  MC_AGP_LOCATION  : 0x%08lx\n", restore->mc_agp_location));
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "RADEONRestoreMemMapRegisters() : \n");
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "  MC_FB_LOCATION   : 0x%08lx\n", restore->mc_fb_location);
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "  MC_AGP_LOCATION  : 0x%08lx\n", restore->mc_agp_location);
 
     /* Write memory mapping registers only if their value change
      * since we must ensure no access is done while they are
@@ -4281,7 +4304,8 @@ static void RADEONRestoreMemMapRegisters
 	CARD32 crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl=0, ov0_scale_cntl;
 	CARD32 old_mc_status, status_idle;
 
-	RADEONTRACE(("  Map Changed ! Applying ...\n"));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "  Map Changed ! Applying ...\n");
 
 	/* Make sure engine is idle. We assume the CCE is stopped
 	 * at this point
@@ -4354,7 +4378,8 @@ static void RADEONRestoreMemMapRegisters
 	/* Make sure map fully reached the chip */
 	(void)INREG(RADEON_MC_FB_LOCATION);
 
-	RADEONTRACE(("  Map applied, resetting engine ...\n"));
+	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "  Map applied, resetting engine ...\n");
 
 	/* Reset the engine and HDP */
 	RADEONEngineReset(pScrn);
@@ -4391,7 +4416,8 @@ static void RADEONRestoreMemMapRegisters
 	}
     }
 
-    RADEONTRACE(("Updating display base addresses...\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Updating display base addresses...\n");
 
     OUTREG(RADEON_DISPLAY_BASE_ADDR, restore->display_base_addr);
     if (pRADEONEnt->HasCRTC2)
@@ -4402,7 +4428,8 @@ static void RADEONRestoreMemMapRegisters
     /* More paranoia delays, wait 100ms */
     usleep(100000);
 
-    RADEONTRACE(("Memory map updated.\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Memory map updated.\n");
  }
 
 #ifdef XF86DRI
@@ -4538,8 +4565,9 @@ static void RADEONRestoreCrtcRegisters(S
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    RADEONTRACE(("Programming CRTC1, offset: 0x%08lx\n",
-		 restore->crtc_offset));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Programming CRTC1, offset: 0x%08lx\n",
+		   restore->crtc_offset);
 
     /* We prevent the CRTC from hitting the memory controller until
      * fully programmed
@@ -4592,8 +4620,9 @@ static void RADEONRestoreCrtc2Registers(
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32	   crtc2_gen_cntl;
 
-    RADEONTRACE(("Programming CRTC2, offset: 0x%08lx\n",
-		 restore->crtc2_offset));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Programming CRTC2, offset: 0x%08lx\n",
+		   restore->crtc2_offset);
 
     crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) &
 	    (RADEON_CRTC2_VSYNC_DIS |
@@ -4798,15 +4827,17 @@ static void RADEONRestorePLLRegisters(Sc
 	      | RADEON_PPLL_ATOMIC_UPDATE_EN
 	      | RADEON_PPLL_VGA_ATOMIC_UPDATE_EN));
 
-    RADEONTRACE(("Wrote: 0x%08x 0x%08x 0x%08lx (0x%08x)\n",
-	       restore->ppll_ref_div,
-	       restore->ppll_div_3,
-	       restore->htotal_cntl,
-	       INPLL(pScrn, RADEON_PPLL_CNTL)));
-    RADEONTRACE(("Wrote: rd=%d, fd=%d, pd=%d\n",
-	       restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
-	       restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
-	       (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote: 0x%08x 0x%08x 0x%08lx (0x%08x)\n",
+		   restore->ppll_ref_div,
+		   restore->ppll_div_3,
+		   restore->htotal_cntl,
+		   INPLL(pScrn, RADEON_PPLL_CNTL));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote: rd=%d, fd=%d, pd=%d\n",
+		   restore->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+		   restore->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+		   (restore->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
 
     usleep(50000); /* Let the clock to lock */
 
@@ -4857,15 +4888,17 @@ static void RADEONRestorePLL2Registers(S
 	      | RADEON_P2PLL_ATOMIC_UPDATE_EN
 	      | RADEON_P2PLL_VGA_ATOMIC_UPDATE_EN));
 
-    RADEONTRACE(("Wrote: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n",
-	       restore->p2pll_ref_div,
-	       restore->p2pll_div_0,
-	       restore->htotal_cntl2,
-	       INPLL(pScrn, RADEON_P2PLL_CNTL)));
-    RADEONTRACE(("Wrote: rd=%ld, fd=%ld, pd=%ld\n",
-	       restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
-	       restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
-	       (restore->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >>16));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote: 0x%08lx 0x%08lx 0x%08lx (0x%08x)\n",
+		   restore->p2pll_ref_div,
+		   restore->p2pll_div_0,
+		   restore->htotal_cntl2,
+		   INPLL(pScrn, RADEON_P2PLL_CNTL));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Wrote: rd=%ld, fd=%ld, pd=%ld\n",
+		   restore->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+		   restore->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
+		   (restore->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >>16);
 
     usleep(5000); /* Let the clock to lock */
 
@@ -5092,7 +5125,9 @@ static void RADEONRestoreMode(ScrnInfoPt
     RADEONController* pCRTC1 = pRADEONEnt->Controller[0];
     RADEONController* pCRTC2 = pRADEONEnt->Controller[1];
     RADEONConnector *pPort;
-    RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONRestoreMode(%p)\n", restore);
 
     /* For Non-dual head card, we don't have private field in the Entity */
     if (!pRADEONEnt->HasCRTC2) {
@@ -5338,14 +5373,16 @@ static void RADEONSavePLLRegisters(ScrnI
     save->htotal_cntl  = INPLL(pScrn, RADEON_HTOTAL_CNTL);
     save->vclk_cntl    = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
 
-    RADEONTRACE(("Read: 0x%08x 0x%08x 0x%08lx\n",
-		 save->ppll_ref_div,
-		 save->ppll_div_3,
-		 save->htotal_cntl));
-    RADEONTRACE(("Read: rd=%d, fd=%d, pd=%d\n",
-		 save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
-		 save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
-		 (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: 0x%08x 0x%08x 0x%08lx\n",
+		   save->ppll_ref_div,
+		   save->ppll_div_3,
+		   save->htotal_cntl);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: rd=%d, fd=%d, pd=%d\n",
+		   save->ppll_ref_div & RADEON_PPLL_REF_DIV_MASK,
+		   save->ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK,
+		   (save->ppll_div_3 & RADEON_PPLL_POST3_DIV_MASK) >> 16);
 }
 
 /* Read PLL registers */
@@ -5356,14 +5393,16 @@ static void RADEONSavePLL2Registers(Scrn
     save->htotal_cntl2  = INPLL(pScrn, RADEON_HTOTAL2_CNTL);
     save->pixclks_cntl  = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 
-    RADEONTRACE(("Read: 0x%08lx 0x%08lx 0x%08lx\n",
-		 save->p2pll_ref_div,
-		 save->p2pll_div_0,
-		 save->htotal_cntl2));
-    RADEONTRACE(("Read: rd=%ld, fd=%ld, pd=%ld\n",
-		 save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
-		 save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
-		 (save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >> 16));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: 0x%08lx 0x%08lx 0x%08lx\n",
+		   save->p2pll_ref_div,
+		   save->p2pll_div_0,
+		   save->htotal_cntl2);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Read: rd=%ld, fd=%ld, pd=%ld\n",
+		   save->p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK,
+		   save->p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK,
+		   (save->p2pll_div_0 & RADEON_P2PLL_POST0_DIV_MASK) >> 16);
 }
 
 /* Read palette data */
@@ -5391,7 +5430,8 @@ static void RADEONSaveMode(ScrnInfoPtr p
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-    RADEONTRACE(("RADEONSaveMode(%p)\n", save));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONSaveMode(%p)\n", save);
 
     if (info->IsSecondary) {
         RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
@@ -5409,7 +5449,8 @@ static void RADEONSaveMode(ScrnInfoPtr p
 	/*memcpy(&info->ModeReg, &info->SavedReg, sizeof(RADEONSaveRec));*/
     }
 
-    RADEONTRACE(("RADEONSaveMode returns %p\n", save));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONSaveMode returns %p\n", save);
 }
 
 /* Save everything needed to restore the original VC state */
@@ -5419,7 +5460,9 @@ static void RADEONSave(ScrnInfoPtr pScrn
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  save       = &info->SavedReg;
 
-    RADEONTRACE(("RADEONSave\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONSave\n");
+
     if (info->FBDev) {
 	RADEONSaveMemMapRegisters(pScrn, save);
 	fbdevHWSave(pScrn);
@@ -5464,7 +5507,8 @@ static void RADEONRestore(ScrnInfoPtr pS
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  restore    = &info->SavedReg;
 
-    RADEONTRACE(("RADEONRestore\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONRestore\n");
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
     RADEONWaitForFifo(pScrn, 1);
@@ -6251,11 +6295,12 @@ static void RADEONInitPLLRegisters(ScrnI
 				     pll->reference_freq);
     save->post_div       = post_div->divider;
 
-    RADEONTRACE(("dc=%ld, of=%ld, fd=%d, pd=%d\n",
-	       save->dot_clock_freq,
-	       save->pll_output_freq,
-	       save->feedback_div,
-	       save->post_div));
+    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));
@@ -6318,11 +6363,12 @@ static void RADEONInitPLL2Registers(Scrn
 				       pll->reference_freq);
     save->post_div_2       = post_div->divider;
 
-    RADEONTRACE(("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));
+    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 |
@@ -6356,23 +6402,23 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
     RADEONInfoPtr  info0     = NULL;
     ScrnInfoPtr    pScrn0    = NULL;
 
-#if RADEON_DEBUG
     if (crtc1 && (crtc_mask & 1)) {
-    	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc1->name,
-	   crtc1->Clock/1000.0,
-
-	   crtc1->HDisplay,
-	   crtc1->HSyncStart,
-	   crtc1->HSyncEnd,
-	   crtc1->HTotal,
-
-	   crtc1->VDisplay,
-	   crtc1->VSyncStart,
-	   crtc1->VSyncEnd,
-	   crtc1->VTotal,
-	   pScrn->depth,
-	   pScrn->bitsPerPixel);
+    	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+		       crtc1->name,
+		       crtc1->Clock/1000.0,
+
+		       crtc1->HDisplay,
+		       crtc1->HSyncStart,
+		       crtc1->HSyncEnd,
+		       crtc1->HTotal,
+
+		       crtc1->VDisplay,
+		       crtc1->VSyncStart,
+		       crtc1->VSyncEnd,
+		       crtc1->VTotal,
+		       pScrn->depth,
+		       pScrn->bitsPerPixel);
     	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
     	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
     	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
@@ -6383,21 +6429,22 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
     	ErrorF("\n");
     }
     if (crtc2 && (crtc_mask & 2)) {
-        ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc2->name,
-	   crtc2->Clock/1000.0,
-
-	   crtc2->CrtcHDisplay,
-	   crtc2->CrtcHSyncStart,
-	   crtc2->CrtcHSyncEnd,
-	   crtc2->CrtcHTotal,
-
-	   crtc2->CrtcVDisplay,
-	   crtc2->CrtcVSyncStart,
-	   crtc2->CrtcVSyncEnd,
-	   crtc2->CrtcVTotal,
-	   pScrn->depth,
-	   pScrn->bitsPerPixel);
+        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		       "%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+		       crtc2->name,
+		       crtc2->Clock/1000.0,
+
+		       crtc2->CrtcHDisplay,
+		       crtc2->CrtcHSyncStart,
+		       crtc2->CrtcHSyncEnd,
+		       crtc2->CrtcHTotal,
+
+		       crtc2->CrtcVDisplay,
+		       crtc2->CrtcVSyncStart,
+		       crtc2->CrtcVSyncEnd,
+		       crtc2->CrtcVTotal,
+		       pScrn->depth,
+		       pScrn->bitsPerPixel);
         if (crtc2->Flags & V_DBLSCAN)   ErrorF(" D");
         if (crtc2->Flags & V_CSYNC)     ErrorF(" C");
         if (crtc2->Flags & V_INTERLACE) ErrorF(" I");
@@ -6407,7 +6454,6 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
         if (crtc2->Flags & V_NVSYNC)    ErrorF(" -V");
     	ErrorF("\n");
     }
-#endif
 
     if (crtc1 && (crtc_mask & 1))
         info->Flags = crtc1->Flags;
@@ -6467,7 +6513,8 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
 	return FALSE;
     }
 
-    RADEONTRACE(("RADEONInit returns %p\n", save));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONInit returns %p\n", save);
     return TRUE;
 }
 
@@ -6491,7 +6538,8 @@ static Bool RADEONModeInit(ScrnInfoPtr p
 {
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-    RADEONTRACE(("RADEONModeInit()\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONModeInit()\n");
 
     if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE;
 
@@ -6513,7 +6561,8 @@ static Bool RADEONSaveScreen(ScreenPtr p
     ScrnInfoPtr  pScrn = xf86Screens[pScreen->myNum];
     Bool         unblank;
 
-    RADEONTRACE(("RADEONSaveScreen(%d)\n", mode));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONSaveScreen(%d)\n", mode);
 
     unblank = xf86IsUnblank(mode);
     if (unblank) SetTimeSinceLastInputEvent();
@@ -6560,7 +6609,8 @@ Bool RADEONSwitchMode(int scrnIndex, Dis
     }
 #endif
 
-    RADEONTRACE(("RADEONSwitchMode() !n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONSwitchMode() !n");
 
     if (info->allowColorTiling) {
 	if (info->MergedFB) {
@@ -6678,7 +6728,8 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 #endif
 
 #if 0 /* Verbose */
-    RADEONTRACE(("RADEONDoAdjustFrame(%d,%d,%d)\n", x, y, clone));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONDoAdjustFrame(%d,%d,%d)\n", x, y, clone);
 #endif
 
     if (info->showCache && y) {
@@ -6817,7 +6868,8 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    RADEONTRACE(("RADEONEnterVT\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONEnterVT\n");
 
     if (INREG(RADEON_CONFIG_MEMSIZE) == 0) { /* Softboot V_BIOS */
        xf86Int10InfoPtr pInt;
@@ -6888,7 +6940,8 @@ void RADEONLeaveVT(int scrnIndex, int fl
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     RADEONSavePtr  save  = &info->ModeReg;
 
-    RADEONTRACE(("RADEONLeaveVT\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONLeaveVT\n");
 #ifdef XF86DRI
     if (RADEONPTR(pScrn)->directRenderingInited) {
 	DRILock(pScrn->pScreen, 0);
@@ -6926,7 +6979,8 @@ void RADEONLeaveVT(int scrnIndex, int fl
 
     RADEONRestore(pScrn);
 
-    RADEONTRACE(("Ok, leaving now...\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Ok, leaving now...\n");
 }
 
 /* Called at the end of each server generation.  Restore the original
@@ -6938,7 +6992,8 @@ static Bool RADEONCloseScreen(int scrnIn
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
 
-    RADEONTRACE(("RADEONCloseScreen\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONCloseScreen\n");
 
     /* Mark acceleration as stopped or we might try to access the engine at
      * wrong times, especially if we had DRI, after DRI has been stopped
@@ -6971,7 +7026,8 @@ static Bool RADEONCloseScreen(int scrnIn
 	RADEONRestore(pScrn);
     }
 
-    RADEONTRACE(("Disposing accel...\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Disposing accel...\n");
 #ifdef USE_EXA
     if (info->exa) {
 	exaDriverFini(pScreen);
@@ -6991,14 +7047,17 @@ static Bool RADEONCloseScreen(int scrnIn
     }
 #endif /* USE_XAA */
 
-    RADEONTRACE(("Disposing cusor info\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Disposing cusor info\n");
     if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
     info->cursor = NULL;
 
-    RADEONTRACE(("Disposing DGA\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Disposing DGA\n");
     if (info->DGAModes) xfree(info->DGAModes);
     info->DGAModes = NULL;
-    RADEONTRACE(("Unmapping memory\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "Unmapping memory\n");
     RADEONUnmapMem(pScrn);
 
     pScrn->vtSema = FALSE;
@@ -7015,7 +7074,8 @@ void RADEONFreeScreen(int scrnIndex, int
     ScrnInfoPtr  pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     
-    RADEONTRACE(("RADEONFreeScreen\n"));
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+		   "RADEONFreeScreen\n");
 
     /* when server quits at PreInit, we don't need do this anymore*/
     if (!info) return;
diff-tree aed193a47a939451d9a6d05b02653b1d73e1d523 (from 870c8043068a0f44b53d1148371b2cc1e3970a7b)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 20 21:13:59 2007 -0400

    RADEON: fix crtc1 (un)blanking code after last commit
    
    - crtc1 MC control is on CRTC_GEN_CNTL
    - fix indenting

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 5d7237c..c24be8f 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -52,48 +52,52 @@ void radeon_crtc_load_lut(xf86CrtcPtr cr
 static void
 radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
-  int mask;
-  ScrnInfoPtr pScrn = crtc->scrn;
-  RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-  RADEONInfoPtr info = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
+    int mask;
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
     
-  mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_DISP_REQ_EN_B);
+    mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
 
 
-  switch(mode) {
-  case DPMSModeOn:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
-    }
-    break;
-  case DPMSModeStandby:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
-    }
-    break;
-  case DPMSModeSuspend:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
-    }
-    break;
-  case DPMSModeOff:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+    switch(mode) {
+    case DPMSModeOn:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+	}
+	break;
+    case DPMSModeStandby:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
+	}
+	break;
+    case DPMSModeSuspend:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
+	}
+	break;
+    case DPMSModeOff:
+	if (radeon_crtc->crtc_id) {
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+	} else {
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_DISP_REQ_EN_B, ~RADEON_CRTC_DISP_REQ_EN_B);
+	    OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+	}
+	break;
     }
-    break;
-  }
   
-  if (mode != DPMSModeOff)
-    radeon_crtc_load_lut(crtc);  
+    if (mode != DPMSModeOff)
+	radeon_crtc_load_lut(crtc);  
 }
 
 static Bool
diff-tree 870c8043068a0f44b53d1148371b2cc1e3970a7b (from 9a147fef8e0e2ede2a0008c4ecfbd9b00c8dc5f6)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 20 21:03:10 2007 -0400

    RADEON: several updates
    
    - move output init from InitCrtc() functions to the output mode_set()
    - take the crtc off the MC when blanking
    - move EnableDisplay() to output commit()
    - clean up some dead code
    - don't enable dacs in initcrtc() functions, this is taken care of in EnableDisplay()

diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
index 1047dcf..5d7237c 100644
--- a/src/radeon_crtc.c
+++ b/src/radeon_crtc.c
@@ -58,7 +58,7 @@ radeon_crtc_dpms(xf86CrtcPtr crtc, int m
   RADEONInfoPtr info = RADEONPTR(pScrn);
   unsigned char *RADEONMMIO = info->MMIO;
     
-  mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
+  mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_REQ_EN_B) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS | RADEON_CRTC_DISP_REQ_EN_B);
 
 
   switch(mode) {
@@ -129,7 +129,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	    montype = radeon_output->MonType;
 	}
     }
-    
+
     ErrorF("init memmap\n");
     RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info);
     ErrorF("init common\n");
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 91bb7b1..6409a6b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5292,10 +5292,11 @@ static void RADEONInitDAC2Registers(xf86
     }
 }
 
-static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr output, int crtc_num)
+void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr output, int crtc_num)
 {
-    Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE;
+    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);
@@ -5303,11 +5304,11 @@ static void RADEONInitOutputRegisters(Sc
 	    RADEONInitDAC2Registers(output, save, mode, IsPrimary);
 	}
     } else if (radeon_output->MonType == MT_LCD) {
-	if (crtc_num == 1)
+	if (crtc_num == 0)
 	    RADEONInitRMXRegisters(output, save, mode);
 	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
     } else if (radeon_output->MonType == MT_DFP) {
-	if (crtc_num == 1)
+	if (crtc_num == 0)
 	    RADEONInitRMXRegisters(output, save, mode);
 	if (radeon_output->TMDSType == TMDS_INT) {
 	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
@@ -5366,7 +5367,6 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
 			      : 0));
 
     save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
-			    RADEON_CRTC_CRT_ON |
 			    RADEON_CRTC_VSYNC_DIS |
 			    RADEON_CRTC_HSYNC_DIS |
 			    RADEON_CRTC_DISPLAY_DIS);
@@ -5458,15 +5458,6 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
     save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
     save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
 
-
-    /* get the output connected to this CRTC */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc) {
-	    RADEONInitOutputRegisters(pScrn, save, mode, output, 1);
-	}
-    }
-
     Base = pScrn->fbOffset;
 
     if (info->tilingEnabled) {
@@ -5649,7 +5640,6 @@ Bool RADEONInitCrtc2Registers(xf86CrtcPt
     save->crtc2_pitch |= save->crtc2_pitch << 16;
 
     save->crtc2_gen_cntl = (RADEON_CRTC2_EN
-			    | RADEON_CRTC2_CRT2_ON
 			    | (format << 8)
 			    | RADEON_CRTC2_VSYNC_DIS
 			    | RADEON_CRTC2_HSYNC_DIS
@@ -5670,14 +5660,6 @@ Bool RADEONInitCrtc2Registers(xf86CrtcPt
     save->fp_h2_sync_strt_wid = save->crtc2_h_sync_strt_wid;
     save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
 
-    /* get the output connected to this CRTC */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc) {
-	    RADEONInitOutputRegisters(pScrn, save, mode, output, 2);
-	}
-    }
-
     Base = pScrn->fbOffset;
 
     if (info->tilingEnabled) {
diff --git a/src/radeon_output.c b/src/radeon_output.c
index a52b1fc..c2bebf0 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -215,13 +215,11 @@ radeon_dpms(xf86OutputPtr output, int mo
     switch(mode) {
     case DPMSModeOn:
 	RADEONEnableDisplay(output, TRUE);
-	/*      RADEONDPMSSetOn(output);*/
 	break;
     case DPMSModeOff:
     case DPMSModeSuspend:
     case DPMSModeStandby:
 	RADEONEnableDisplay(output, FALSE);
-	/*RADEONDPMSSetOff(output);*/
 	break;
     }
 }
@@ -299,7 +297,18 @@ radeon_mode_set(xf86OutputPtr output, Di
 {
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int i;
+
+    /* get the outputs connected to this CRTC */
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+	xf86CrtcPtr	crtc = xf86_config->crtc[i];
+	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+	if (output->crtc == crtc) {
+	    RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id);
+	}
+    }
 
     switch(radeon_output->MonType) {
     case MT_LCD:
@@ -312,12 +321,12 @@ radeon_mode_set(xf86OutputPtr output, Di
 	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
     }
 
-    RADEONEnableDisplay(output, TRUE);
 }
 
 static void
 radeon_mode_commit(xf86OutputPtr output)
 {
+    RADEONEnableDisplay(output, TRUE);
 }
 
 static xf86OutputStatus
diff-tree 09bfc8ed000f95ede5b73f2bad69edc1a4d9bac6 (from 764cb73e8dec4040cdd418d249fc504399fca3ee)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 20 18:06:22 2007 -0400

    update to 6.6.192 for rc release

diff --git a/configure.ac b/configure.ac
index ddfa7c8..8b29d8d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-ati],
-        6.6.191,
+        6.6.192,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-ati)
 
diff-tree 764cb73e8dec4040cdd418d249fc504399fca3ee (from a3ee42207aab77d93655a82fdcb32be38268b85f)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 20 17:26:26 2007 -0400

    Fix regular/"xinerama"/zaphod dualhead mode
    
    - logic in RADEONUnblank() was wrong
    - Calling RADEONSetupConnectors() on second instance screwed up the port info
    - still seem to be HW cursor issues with zaphod mode

diff --git a/src/radeon_display.c b/src/radeon_display.c
index f3b86e6..fb345a9 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2135,7 +2135,9 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     RADEONConnector *pPort;
 
-    if (!pRADEONEnt->HasSecondary || (info->IsSwitching  && !info->IsSecondary)) {
+    if (!pRADEONEnt->HasSecondary ||
+	(pRADEONEnt->HasSecondary && !info->IsSwitching) ||
+	(info->IsSwitching && (!info->IsSecondary))) {
 	pPort = RADEONGetCrtcConnector(pScrn, 1);
 	if (pPort)
 	    RADEONUnblankSet(pScrn, pPort);
@@ -2158,7 +2160,8 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
       }
     }
 
-    if (info->IsSwitching && info->IsSecondary) {
+    if ((pRADEONEnt->HasSecondary && !info->IsSwitching) ||
+	(info->IsSwitching && info->IsSecondary)) {
 	pPort = RADEONGetCrtcConnector(pScrn, 2);
 	if (pPort)
 	    RADEONUnblankSet(pScrn, pPort);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b9cce22..933265f 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2971,7 +2971,9 @@ static Bool RADEONPreInitControllers(Scr
 
     RADEONGetBIOSInfo(pScrn, pInt10);
 
-    RADEONSetupConnectors(pScrn);
+    if (!info->IsSecondary) {
+	RADEONSetupConnectors(pScrn);
+    }
     RADEONMapControllers(pScrn);
 
     RADEONGetClockInfo(pScrn);
diff-tree 9a147fef8e0e2ede2a0008c4ecfbd9b00c8dc5f6 (from bbd6faff4c6acb48970d774375c8a61861405f96)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 18 23:45:11 2007 -0400

    RADEON: if connector is VGA set TMDS to none

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 3247b74..a52b1fc 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -553,14 +553,28 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	}
 	radeon_output->MonType = MT_UNKNOWN;
 	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
-	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-	    radeon_output->ConnectorType == CONNECTOR_DVI_D)
-	    radeon_output->DACType = DAC_NONE;
-	else
-	    radeon_output->DACType = info->BiosConnector[i].DACType;
 	radeon_output->DDCType = info->BiosConnector[i].DDCType;
-	radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	if (info->IsAtomBios) {
+	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM)
+		radeon_output->DACType = DAC_NONE;
+	    else
+		radeon_output->DACType = info->BiosConnector[i].DACType;
+
+	    if (radeon_output->ConnectorType == CONNECTOR_VGA_ATOM)
+		radeon_output->TMDSType = TMDS_NONE;
+	    else
+		radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	} else {
+	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
+		radeon_output->DACType = DAC_NONE;
+	    else
+		radeon_output->DACType = info->BiosConnector[i].DACType;
 
+	    if (radeon_output->ConnectorType == CONNECTOR_CRT)
+		radeon_output->TMDSType = TMDS_NONE;
+	    else
+		radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	}
 	RADEONSetOutputType(pScrn, radeon_output);
 	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
 	if (!output) {
diff-tree bbd6faff4c6acb48970d774375c8a61861405f96 (from 7940ec364f3cbf02ba64b92c74cbaad4555baf38)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 18 23:30:19 2007 -0400

    RADEON: Change default LVDS i2c line for powerpc

diff --git a/src/radeon_output.c b/src/radeon_output.c
index 924c3e0..3247b74 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -482,7 +482,11 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
         (info->BiosConnector[1].DDCType == 0))) {
 	if (info->IsMobility) {
 	    /* Below is the most common setting, but may not be true */
+#if defined(__powerpc__)
+	    info->BiosConnector[0].DDCType = DDC_DVI;
+#else
 	    info->BiosConnector[0].DDCType = DDC_LCD;
+#endif
 	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
 	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
diff-tree 7940ec364f3cbf02ba64b92c74cbaad4555baf38 (from f71bfde7352ef858c1041037d7dc77c237e315a4)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 18 00:23:08 2007 -0400

    RADEON: cleanup

diff --git a/src/radeon.h b/src/radeon.h
index fde7f79..75dd234 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -402,7 +402,6 @@ typedef struct {
     unsigned long     FbMapSize;        /* Size of frame buffer, in bytes    */
     unsigned long     FbSecureSize;     /* Size of secured fb area at end of
                                            framebuffer */
-    /*int               Flags;*/            /* Saved copy of mode flags          */
 
     Bool              IsMobility;       /* Mobile chips for laptops */
     Bool              IsIGP;            /* IGP chips */
@@ -416,17 +415,7 @@ typedef struct {
 				/* EDID or BIOS values for FPs */
     int               PanelXRes;
     int               PanelYRes;
-#if 0
-    int               HOverPlus;
-    int               HSyncWidth;
-    int               HBlank;
-    int               VOverPlus;
-    int               VSyncWidth;
-    int               VBlank;
-    int               PanelPwrDly;
-    int               DotClock;
-#endif
-    // move these to crtc priv rec
+
     int               RefDivider;
     int               FeedbackDivider;
     int               PostDivider;
@@ -437,7 +426,7 @@ typedef struct {
     Bool              ddc2;
 
     RADEONPLLRec      pll;
-    /*RADEONTMDSPll     tmds_pll[4];*/
+
     int               RamWidth;
     float	      sclk;		/* in MHz */
     float	      mclk;		/* in MHz */
diff-tree f71bfde7352ef858c1041037d7dc77c237e315a4 (from f711e266d6927dec648f6ff26f15c6f48643f78c)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 18 00:12:03 2007 -0400

    RADEON: more cleanup

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b2d28a5..91bb7b1 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5458,19 +5458,6 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
     save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
     save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
 
-#if 0
-    /* Set following registers for all cases first, if a DFP/LCD is connected on
-       internal TMDS/LVDS port, they will be set by RADEONInitFPRegister
-    */
-    if (!info->IsSwitching) {
-	save->fp_gen_cntl = 0;
-	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);
-    }
-#endif
 
     /* get the output connected to this CRTC */
     for (i = 0; i < xf86_config->num_output; i++) {
diff-tree f711e266d6927dec648f6ff26f15c6f48643f78c (from bfc1c372d7475b7fa6bffb8a79dec1dc2f11ec59)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu May 17 23:59:07 2007 -0400

    RADEON: turn off all outputs in screeninit().  We'll turn on the ones we want later

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ba736ca..b2d28a5 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3307,6 +3307,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     RADEONSave(pScrn);
 
+    RADEONDisableDisplays(pScrn);
+
     if (info->IsMobility) {
         if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
 	    RADEONSetDynamicClock(pScrn, 1);
diff-tree bfc1c372d7475b7fa6bffb8a79dec1dc2f11ec59 (from c60b3bc9e3e7463bdb42e2478be8cc3f22c63c68)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu May 17 23:45:29 2007 -0400

    RADEON: More cleanup

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index f63eec7..25cd1a8 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -272,31 +272,6 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 	}
 
 	if (info->IsMobility) {
-#if 0
-	    /* For the cases where only one VGA connector is found, 
-	       we assume LVDS is not listed in the connector table, 
-	       add it in here as the first port.
-	    */
-	    if ((connector_found < 3) && (info->BiosConnector[tmp1]->ConnectorType == CONNECTOR_CRT)) {
-		if (connector_found == 1) {
-		    memcpy (&info->BiosConnector[1], &info->BiosConnector[0], 
-			    sizeof (info->BiosConnector));
-		}
-		info->BiosConnector[0].DACType = DAC_TVDAC;
-		info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
-		info->BiosConnector[0].DDCType = DDC_NONE_DETECTED;
-		info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
-
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "LVDS port is not in connector table, added in.\n");
-		if (connector_found == 0) connector_found = 1;
-		else connector_found = 3;
-	    }
-
-	    /* some bioses seem to list the LVDS port as DVI hack around that here */
-	    if (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D) {
-		info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
-	    }
-#endif
 	    if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) {
 	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
 		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d561fa0..ba736ca 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1661,7 +1661,7 @@ static Bool RADEONPreInitChipType(ScrnIn
     case PCI_CHIP_RS482_5974:
 	info->ChipFamily = CHIP_FAMILY_RS400;
 	info->IsIGP = TRUE;
-	/*info->HasSingleDAC = TRUE;*/ /* ??? */
+	info->HasSingleDAC = TRUE; /* ??? */
         break;
 
     case PCI_CHIP_RV410_564A:
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 3052c36..924c3e0 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -181,17 +181,6 @@ void RADEONConnectorFindMonitor(ScrnInfo
     }
 }
 
-static void RADEONSwapOutputs(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONBIOSConnector tmp;
-    
-    tmp = info->BiosConnector[0];
-    info->BiosConnector[0] = info->BiosConnector[1];
-    info->BiosConnector[1] = tmp;
-    
-}
-
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
@@ -524,29 +513,14 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
         }
     }
 
-    /* always make TMDS_INT port first*/
-    if (info->BiosConnector[1].TMDSType == TMDS_INT) {
-	RADEONSwapOutputs(pScrn);
-    } else if ((info->BiosConnector[0].TMDSType != TMDS_INT &&
-                info->BiosConnector[1].TMDSType != TMDS_INT)) {
-        /* no TMDS_INT port, make primary DAC port first */
-	/* On my Inspiron 8600 both internal and external ports are
-	   marked DAC_PRIMARY in BIOS. So be extra careful - only
-	   swap when the first port is not DAC_PRIMARY */
-        if ((!(info->BiosConnector[0].ConnectorType == CONNECTOR_PROPRIETARY)) &&  (info->BiosConnector[1].DACType == DAC_PRIMARY) &&
-	     (info->BiosConnector[0].DACType != DAC_PRIMARY)) {
-	    RADEONSwapOutputs(pScrn);
-        }
-    }
-
     if (info->HasSingleDAC) {
         /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
         if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
             info->BiosConnector[0].DACType = DAC_TVDAC;
-            info->BiosConnector[1].DACType = DAC_PRIMARY;
+            info->BiosConnector[1].DACType = DAC_NONE;
         } else {
             info->BiosConnector[1].DACType = DAC_TVDAC;
-            info->BiosConnector[0].DACType = DAC_PRIMARY;
+            info->BiosConnector[0].DACType = DAC_NONE;
         }
     } else if (!pRADEONEnt->HasCRTC2) {
         info->BiosConnector[0].DACType = DAC_PRIMARY;
@@ -563,7 +537,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		   &info->BiosConnector[1].DACType,
 		   &info->BiosConnector[1].TMDSType,
 		   &info->BiosConnector[1].ConnectorType) != 8) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid ConnectorTable option: %s\n", optstr);
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid ConnectorTable option: %s\n", optstr);
+	    return FALSE;
 	}
     }
 
diff-tree c60b3bc9e3e7463bdb42e2478be8cc3f22c63c68 (from 11289f8206cab1a94bd64a3938cf9af50f19497e)
Author: Paul TBBle Hampson <Paul.Hampson at pobox.com>
Date:   Thu May 17 23:26:54 2007 -0400

    Fix for infinite loop in RADEONGetLVDSInfo

diff --git a/src/radeon_display.c b/src/radeon_display.c
index f0a24ab..76affcb 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -790,8 +790,8 @@ Bool RADEONGetLVDSInfo (xf86OutputPtr ou
 		    radeon_output->Flags = 0;
 		    break;
 		}
-		tmp_mode = tmp_mode->next;
 	    }
+	    tmp_mode = tmp_mode->next;
 	}
 	if ((radeon_output->DotClock == 0) && !output->MonInfo) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
diff-tree 11289f8206cab1a94bd64a3938cf9af50f19497e (from fba1a11e287ebf04cf311645d31299896bad7283)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue May 15 00:48:31 2007 -0400

    RADEON: remove some debugging code

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 85a4844..f0a24ab 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -980,7 +980,7 @@ void RADEONEnableDisplay(xf86OutputPtr o
     RADEONOutputPrivatePtr radeon_output;
     radeon_output = output->driver_private;
 
-    ErrorF("montype: %d\n", radeon_output->MonType);
+    ErrorF("enable montype: %d\n", radeon_output->MonType);
 
     if (bEnable) {
         if (radeon_output->MonType == MT_CRT) {
@@ -1017,12 +1017,10 @@ void RADEONEnableDisplay(xf86OutputPtr o
             }
         } else if (radeon_output->MonType == MT_LCD) {
             tmp = INREG(RADEON_LVDS_GEN_CNTL);
-	    ErrorF("read in LVDS reg\n");
             tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
 	    usleep (radeon_output->PanelPwrDly * 1000);
             OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
-	    ErrorF("wrote out LVDS reg\n");
             save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } 
diff-tree fba1a11e287ebf04cf311645d31299896bad7283 (from 9ed00e959fcdab2739a7e64ca1e303a6faf28f15)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue May 15 00:44:29 2007 -0400

    RADEON: Move DAC regs to their own Save() function

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 32f51d6..d561fa0 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4692,7 +4692,6 @@ static void RADEONSaveCrtcRegisters(Scrn
 
     save->crtc_gen_cntl        = INREG(RADEON_CRTC_GEN_CNTL);
     save->crtc_ext_cntl        = INREG(RADEON_CRTC_EXT_CNTL);
-    save->dac_cntl             = INREG(RADEON_DAC_CNTL);
     save->crtc_h_total_disp    = INREG(RADEON_CRTC_H_TOTAL_DISP);
     save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
     save->crtc_v_total_disp    = INREG(RADEON_CRTC_V_TOTAL_DISP);
@@ -4720,6 +4719,21 @@ static void RADEONSaveCrtcRegisters(Scrn
     }
 }
 
+/* Read DAC registers */
+static void RADEONSaveDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    save->dac_cntl              = INREG(RADEON_DAC_CNTL);
+    save->dac2_cntl             = INREG(RADEON_DAC_CNTL2);
+    save->tv_dac_cntl           = INREG(RADEON_TV_DAC_CNTL);
+    save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
+    save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
+    save->disp_hw_debug         = INREG(RADEON_DISP_HW_DEBUG);
+
+}
+
 /* Read flat panel registers */
 static void RADEONSaveFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
@@ -4750,12 +4764,6 @@ static void RADEONSaveCrtc2Registers(Scr
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
 
-    save->dac2_cntl             = INREG(RADEON_DAC_CNTL2);
-    save->tv_dac_cntl           = INREG(RADEON_TV_DAC_CNTL);
-    save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
-    save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
-    save->disp_hw_debug         = INREG (RADEON_DISP_HW_DEBUG);
-
     save->crtc2_gen_cntl        = INREG(RADEON_CRTC2_GEN_CNTL);
     save->crtc2_h_total_disp    = INREG(RADEON_CRTC2_H_TOTAL_DISP);
     save->crtc2_h_sync_strt_wid = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
@@ -4842,6 +4850,7 @@ static void RADEONSaveMode(ScrnInfoPtr p
     RADEONSavePLLRegisters (pScrn, save);
     RADEONSaveCrtcRegisters (pScrn, save);
     RADEONSaveFPRegisters (pScrn, save);
+    RADEONSaveDACRegisters (pScrn, save);
     RADEONSaveCrtc2Registers (pScrn, save);
     RADEONSavePLL2Registers (pScrn, save);
     /*RADEONSavePalette(pScrn, save);*/
diff-tree 9ed00e959fcdab2739a7e64ca1e303a6faf28f15 (from 5106c8fe5f74865cac8b00937739a4efde9fc254)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue May 15 00:36:05 2007 -0400

    RADEON: Lots of small fixes
    
    - remove extra crtc2_base set
    - remove some debugging code
    - clean up RestoreMode()
    - make sure a DDC reg gets assigned for LCD_DDC
    - make sure we adjust the right frame in AdjustFrame()
    - rename RADEONMapControllers() to RADEONPrintPortMap() to
    reflect what it actually does now
    - make i2c bus name match the DDC port
    - remove or comment out un-needed code

diff --git a/src/radeon.h b/src/radeon.h
index e0b4b9b..fde7f79 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -833,7 +833,7 @@ extern void        RADEONInitDispBandwid
 extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
 extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
 extern Bool        RADEONSetupConnectors(ScrnInfoPtr pScrn);
-extern Bool        RADEONMapControllers(ScrnInfoPtr pScrn);
+extern void        RADEONPrintPortMap(ScrnInfoPtr pScrn);
 extern void        RADEONEnableDisplay(xf86OutputPtr pPort, BOOL bEnable);
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
 extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 6e08f24..f63eec7 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -408,8 +408,6 @@ Bool RADEONGetLVDSInfoFromBIOS (xf86Outp
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     unsigned long tmp, i;
 
-    ErrorF("grabbing LVDS from bios");
-
     if (!info->VBIOS) return FALSE;
 
     if (info->IsAtomBios) {
@@ -551,8 +549,6 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86Outp
     CARD32 tmp, maxfreq;
     int i, n;
 
-    ErrorF("grabbing LVDS from bios");
-
     if (!info->VBIOS) return FALSE;
 
     if (info->IsAtomBios) {
diff --git a/src/radeon_display.c b/src/radeon_display.c
index c3167bc..85a4844 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -742,8 +742,6 @@ Bool RADEONGetLVDSInfo (xf86OutputPtr ou
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     char* s;
 
-    ErrorF("LVDS get info");
-
     if (!RADEONGetLVDSInfoFromBIOS(output))
 	RADEONGetPanelInfoFromReg(output);
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c82c6ba..32f51d6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -116,8 +116,6 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
 static void RADEONSave(ScrnInfoPtr pScrn);
-//static void RADEONRestore(ScrnInfoPtr pScrn);
-//static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
 static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
 static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
@@ -2498,7 +2496,7 @@ static Bool RADEONPreInitControllers(Scr
 	return FALSE;
     }
       
-    RADEONMapControllers(pScrn);
+    RADEONPrintPortMap(pScrn);
 
     RADEONGetClockInfo(pScrn);
 
@@ -3577,7 +3575,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
 
-    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+    //    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
     /* Backing store setup */
     RADEONTRACE(("Initializing backing store\n"));
@@ -4612,10 +4610,8 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
      */
     RADEONRestoreMemMapRegisters(pScrn, restore);
     RADEONRestoreCommonRegisters(pScrn, restore);
-    if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	RADEONRestoreCrtc2Registers(pScrn, restore);
-	RADEONRestorePLL2Registers(pScrn, restore);
-    }
+    RADEONRestoreCrtc2Registers(pScrn, restore);
+    RADEONRestorePLL2Registers(pScrn, restore);
 
     RADEONRestoreCrtcRegisters(pScrn, restore);
     RADEONRestorePLLRegisters(pScrn, restore);
@@ -4623,10 +4619,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     RADEONRestoreDACRegisters(pScrn, restore);
 
     RADEONEnableOutputs(pScrn, 0);
-
-    if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	RADEONEnableOutputs(pScrn, 1);
-    }
+    RADEONEnableOutputs(pScrn, 1);
 
 #if 0
     RADEONRestorePalette(pScrn, &info->SavedReg);
@@ -5732,7 +5725,6 @@ Bool RADEONInitCrtc2Registers(xf86CrtcPt
     }
 
     Base &= ~7;                 /* 3 lower bits are always 0 */
-    save->crtc2_offset = Base;
 
 #ifdef XF86DRI
     if (info->directRenderingInited) {
@@ -6189,6 +6181,7 @@ void RADEONAdjustFrame(int scrnIndex, in
 {
     ScrnInfoPtr    pScrn      = xf86Screens[scrnIndex];
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86OutputPtr  output = config->output[config->compat_output];
     xf86CrtcPtr	crtc = output->crtc;
@@ -6204,7 +6197,10 @@ void RADEONAdjustFrame(int scrnIndex, in
 	if (info->FBDev) {
 	    fbdevHWAdjustFrame(scrnIndex, crtc->desiredX + x, crtc->desiredY + y, flags);
 	} else {
-	    RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
+	    if (crtc == pRADEONEnt->pCrtc[0])
+		RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
+	    else
+		RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, TRUE);
 	}
 	crtc->x = output->initial_x + x;
 	crtc->y = output->initial_y + y;
@@ -6258,7 +6254,6 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 	{
 	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
 	    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-	    radeon_crtc->binding = 1;
 	    /* 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_output.c b/src/radeon_output.c
index e9e1aea..3052c36 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -126,7 +126,7 @@ const char *OutputType[10] = {
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
 
-Bool RADEONMapControllers(ScrnInfoPtr pScrn)
+void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
@@ -136,9 +136,6 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     xf86OutputPtr output;
     int o;
 
-    pRADEONEnt->Controller[0]->binding = 1;
-    pRADEONEnt->Controller[1]->binding = 1;
-
     for (o = 0; o < xf86_config->num_output; o++) {
       output = xf86_config->output[o];
       radeon_output = output->driver_private;
@@ -156,7 +153,6 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 
     }
 
-    return TRUE;
 }
 
 /* Primary Head (DVI or Laptop Int. panel)*/
@@ -433,13 +429,14 @@ void RADEONInitConnector(xf86OutputPtr o
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int DDCReg = 0;
-    char* name = OutputType[radeon_output->type];
+    char* name = (char*) DDCTypeName[radeon_output->DDCType];
 
     switch(radeon_output->DDCType) {
     case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
     case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
-    case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
-    case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+    case DDC_VGA  : DDCReg = RADEON_GPIO_VGA_DDC; break;
+    case DDC_CRT2 : DDCReg = RADEON_GPIO_CRT2_DDC; break;
+    case DDC_LCD  : DDCReg = RADEON_LCD_GPIO_MASK; break;
     default: break;
     }
     
@@ -455,7 +452,7 @@ void RADEONInitConnector(xf86OutputPtr o
     if (radeon_output->type == OUTPUT_DVI) {
 	RADEONGetTMDSInfo(output);
 
-	// FIXME
+	// FIXME -- this should be done in detect or getmodes
 	/*if (i == 0)
 	  RADEONGetHardCodedEDIDFromBIOS(output);*/
 
diff-tree 5106c8fe5f74865cac8b00937739a4efde9fc254 (from 224a73e41e9be344d5644203e7ebd5a3a8272604)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 21:48:26 2007 -0400

    RADEON: Further cleanup

diff --git a/src/radeon.h b/src/radeon.h
index 2a2a672..e0b4b9b 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -407,9 +407,6 @@ typedef struct {
     Bool              IsMobility;       /* Mobile chips for laptops */
     Bool              IsIGP;            /* IGP chips */
     Bool              HasSingleDAC;     /* only TVDAC on chip */
-    Bool              IsSecondary;      /* Second Screen                     */
-    Bool	      IsPrimary;        /* Primary Screen */
-    Bool              IsSwitching;      /* Flag for switching mode           */
     Bool              OverlayOnCRTC2;
     Bool              ddc_mode;         /* Validate mode by matching exactly
 					 * the modes supported in DDC data
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b2b23bc..c82c6ba 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2551,7 +2551,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     if (!RADEONGetRec(pScrn)) return FALSE;
 
     info               = RADEONPTR(pScrn);
-    info->IsSwitching  = FALSE;
     info->MMIO         = NULL;
 
     info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
@@ -3971,7 +3970,6 @@ void RADEONRestoreCommonRegisters(ScrnIn
      * CRT are connected.
      */
     if (pRADEONEnt->HasCRTC2 &&
-	!info->IsSwitching &&
 	info->ChipFamily != CHIP_FAMILY_R200 &&
 	!IS_R300_VARIANT) {
 	CARD32        tmp;
@@ -4598,8 +4596,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     /* Disable all outputs at initial mode set.  the ones we want will
        get set by RADEONEnableDisplay()
      */
-    if (!info->IsSwitching)
-        RADEONDisableDisplays(pScrn);
+    RADEONDisableDisplays(pScrn);
 
     /* When changing mode with Dual-head card, care must be taken for
      * the special order in setting registers. CRTC2 has to be set
@@ -4613,40 +4610,22 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
      * We always restore MemMap first, the saverec should be up to date
      * in all cases
      */
-    if (info->IsSwitching) {
-	RADEONRestoreMemMapRegisters(pScrn, restore);
-	RADEONRestoreCommonRegisters(pScrn, restore);
-	if (pCRTC2->binding == 1) {
-	    RADEONRestoreCrtc2Registers(pScrn, restore);
-	    RADEONRestorePLL2Registers(pScrn, restore);
-	}
+    RADEONRestoreMemMapRegisters(pScrn, restore);
+    RADEONRestoreCommonRegisters(pScrn, restore);
+    if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
+	RADEONRestoreCrtc2Registers(pScrn, restore);
+	RADEONRestorePLL2Registers(pScrn, restore);
+    }
+
+    RADEONRestoreCrtcRegisters(pScrn, restore);
+    RADEONRestorePLLRegisters(pScrn, restore);
+    RADEONRestoreFPRegisters(pScrn, restore);
+    RADEONRestoreDACRegisters(pScrn, restore);
 
-	RADEONRestoreCrtcRegisters(pScrn, restore);
-	RADEONRestorePLLRegisters(pScrn, restore);
-	RADEONRestoreFPRegisters(pScrn, restore);
-	RADEONRestoreDACRegisters(pScrn, restore);
-	RADEONEnableOutputs(pScrn, 0);
-	if (pCRTC2->binding == 1) {
-	    RADEONEnableOutputs(pScrn, 1);
-	}
-    } else {
-	RADEONRestoreMemMapRegisters(pScrn, restore);
-	RADEONRestoreCommonRegisters(pScrn, restore);
-	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    RADEONRestoreCrtc2Registers(pScrn, restore);
-	    RADEONRestorePLL2Registers(pScrn, restore);
-	}
-
-	RADEONRestoreCrtcRegisters(pScrn, restore);
-	RADEONRestorePLLRegisters(pScrn, restore);
-	RADEONRestoreFPRegisters(pScrn, restore);
-	RADEONRestoreDACRegisters(pScrn, restore);
-
-	RADEONEnableOutputs(pScrn, 0);
+    RADEONEnableOutputs(pScrn, 0);
 
-	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    RADEONEnableOutputs(pScrn, 1);
-	}
+    if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
+	RADEONEnableOutputs(pScrn, 1);
     }
 
 #if 0
@@ -5475,6 +5454,7 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
     save->fp_crtc_h_total_disp = save->crtc_h_total_disp;
     save->fp_crtc_v_total_disp = save->crtc_v_total_disp;
 
+#if 0
     /* Set following registers for all cases first, if a DFP/LCD is connected on
        internal TMDS/LVDS port, they will be set by RADEONInitFPRegister
     */
@@ -5486,6 +5466,7 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
 				  (RADEON_HORZ_FP_LOOP_STRETCH |
 				  RADEON_HORZ_AUTO_RATIO_INC);
     }
+#endif
 
     /* get the output connected to this CRTC */
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -6025,9 +6006,7 @@ Bool RADEONSwitchMode(int scrnIndex, Dis
 
 	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
     } else {
-	info->IsSwitching = TRUE;
 	ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
-	info->IsSwitching = FALSE;
     }
 
     if (info->tilingEnabled != tilingOld) {
diff-tree 224a73e41e9be344d5644203e7ebd5a3a8272604 (from 9c2f20a83a5fed14225f4c3ebcd8ca41e9d4bd48)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 21:41:59 2007 -0400

    RADEON: remove remnants of "old" multi-head support
    
    The old screen based multi-head code is broken at this point
    and I have no intention of fixing it, so to clean things up
    I've removed it.

diff --git a/src/radeon_display.c b/src/radeon_display.c
index c5caf9c..c3167bc 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1404,22 +1404,10 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
     xf86CrtcPtr crtc;
     int pixel_bytes2 = 0;
 
-    if (pRADEONEnt->pSecondaryScrn) {
-	if (info->IsSecondary) return;
-	info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn);
-    } else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info;
-
     mode1 = info->CurrentLayout.mode;
-    if ((pRADEONEnt->HasSecondary) && info2) {
-	mode2 = info2->CurrentLayout.mode;
-    } else {
-	mode2 = NULL;
-    }
+    mode2 = NULL;
+    pixel_bytes2 = info->CurrentLayout.pixel_bytes;
 
-    if (info2) 
-      pixel_bytes2 = info2->CurrentLayout.pixel_bytes;
-    
-    
     if (xf86_config->num_crtc == 2) {
       pixel_bytes2 = 0;
       mode2 = NULL;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index dbbf91f..b2b23bc 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1427,23 +1427,6 @@ static Bool RADEONPreInitVRAM(ScrnInfoPt
     xf86DrvMsg(pScrn->scrnIndex, from,
 	       "Mapped VideoRAM: %d kByte (%d bit %s SDRAM)\n", pScrn->videoRam, info->RamWidth, info->IsDDR?"DDR":"SDR");
 
-    /* FIXME: For now, split FB into two equal sections. This should
-     * be able to be adjusted by user with a config option. */
-    if (info->IsPrimary) {
-        pScrn->videoRam /= 2;
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		"Using %dk of videoram for primary head\n",
-		pScrn->videoRam);
-    }
-
-    if (info->IsSecondary) {  
-        pScrn->videoRam /= 2;
-        info->LinearAddr += pScrn->videoRam * 1024;
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		"Using %dk of videoram for secondary head\n",
-		pScrn->videoRam);
-    }
-
     pScrn->videoRam  &= ~1023;
     info->FbMapSize  = pScrn->videoRam * 1024;
 
@@ -2078,18 +2061,6 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr
     info->pLibDRMVersion = NULL;
     info->pKernelDRMVersion = NULL;
 
-    if (xf86IsEntityShared(info->pEnt->index)) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "Direct Rendering Disabled -- "
-		   "Dual-head configuration is not working with "
-		   "DRI at present.\n"
-		   "Please use the radeon randr 1.2 support option if you "
-		   "want Dual-head with DRI.\n");
-	return FALSE;
-    }
-    if (info->IsSecondary)
-        return FALSE;
-
     if (info->Chipset == PCI_CHIP_RN50_515E ||
 	info->Chipset == PCI_CHIP_RN50_5969) {
     	if (xf86ReturnOptValBool(info->Options, OPTION_DRI, FALSE)) {
@@ -2312,14 +2283,7 @@ static void RADEONPreInitColorTiling(Scr
     }
 #endif /* XF86DRI */
 
-    if ((info->allowColorTiling) && (info->IsSecondary)) {
-	/* can't have tiling on the 2nd head (as long as it can't use drm).
-	 * We'd never get the surface save/restore (vt switching) right...
-	 */
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Color tiling disabled for 2nd head\n");
-	info->allowColorTiling = FALSE;
-    }
-    else if ((info->allowColorTiling) && (info->FBDev)) {
+    if ((info->allowColorTiling) && (info->FBDev)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		   "Color tiling not supported with UseFBDev option\n");
 	info->allowColorTiling = FALSE;
@@ -2525,11 +2489,8 @@ static Bool RADEONPreInitControllers(Scr
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     int i;
 
-    if (!info->IsSecondary) {
-      
-      if (!RADEONAllocateControllers(pScrn))
-	  return FALSE;
-    }
+    if (!RADEONAllocateControllers(pScrn))
+	return FALSE;
 
     RADEONGetBIOSInfo(pScrn, pInt10);
 
@@ -2590,8 +2551,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     if (!RADEONGetRec(pScrn)) return FALSE;
 
     info               = RADEONPTR(pScrn);
-    info->IsSecondary  = FALSE;
-    info->IsPrimary     = FALSE;
     info->IsSwitching  = FALSE;
     info->MMIO         = NULL;
 
@@ -2636,30 +2595,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     RADEONPreInt10Save(pScrn, &int10_save);
 #endif
 
-    if (xf86IsEntityShared(info->pEnt->index)) {
-	if (xf86IsPrimInitDone(info->pEnt->index)) {
-
-	    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
-	    info->IsSecondary = TRUE;
-	    if (!pRADEONEnt->HasSecondary) {
-		xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-			   "Only one monitor detected, Second screen "
-			   "will NOT be created\n");
-		goto fail2;
-	    }
-	    pRADEONEnt->pSecondaryScrn = pScrn;
-	} else {
-	    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
-	    info->IsPrimary = TRUE;
-
-	    xf86SetPrimInitDone(info->pEnt->index);
-
-	    pRADEONEnt->pPrimaryScrn        = pScrn;
-	}
-    }
-
     if (flags & PROBE_DETECT) {
 	RADEONProbeDDC(pScrn, info->pEnt->index);
 	RADEONPostInt10Check(pScrn, int10_save);
@@ -2874,10 +2809,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
 fail:
 				/* Pre-init failed. */
-    if (info->IsSecondary) {
-        RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-	pRADEONEnt->HasSecondary = FALSE;
-    }
 				/* Free the video bios (if applicable) */
     if (info->VBIOS) {
 	xfree(info->VBIOS);
@@ -3368,7 +3299,6 @@ Bool RADEONScreenInit(int scrnIndex, Scr
     info->accel        = NULL;
 #endif
     pScrn->fbOffset    = info->frontOffset;
-    if (info->IsSecondary) pScrn->fbOffset = pScrn->videoRam * 1024;
     if (!RADEONMapMem(pScrn)) return FALSE;
 
 #ifdef XF86DRI
@@ -3380,7 +3310,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 
     RADEONSave(pScrn);
 
-    if ((!info->IsSecondary) && info->IsMobility) {
+    if (info->IsMobility) {
         if (xf86ReturnOptValBool(info->Options, OPTION_DYNAMIC_CLOCKS, FALSE)) {
 	    RADEONSetDynamicClock(pScrn, 1);
         } else {
@@ -3388,8 +3318,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
         }
     }
 
-    if ((!info->IsSecondary) && (IS_R300_VARIANT || IS_RV100_VARIANT))
-      RADEONForceSomeClocks(pScrn);
+    if (IS_R300_VARIANT || IS_RV100_VARIANT)
+	RADEONForceSomeClocks(pScrn);
 
     if (info->allowColorTiling && (pScrn->virtualX > info->MaxSurfaceWidth)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -3439,15 +3369,13 @@ Bool RADEONScreenInit(int scrnIndex, Scr
      */
     RADEONInitMemoryMap(pScrn);
 
-    if (!info->IsSecondary) {
-	/* empty the surfaces */
-	unsigned char *RADEONMMIO = info->MMIO;
-	unsigned int i;
-	for (i = 0; i < 8; i++) {
-	    OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0);
-	    OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0);
-	    OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0);
-	}
+    /* empty the surfaces */
+    unsigned char *RADEONMMIO = info->MMIO;
+    unsigned int i;
+    for (i = 0; i < 8; i++) {
+	OUTREG(RADEON_SURFACE0_INFO + 16 * i, 0);
+	OUTREG(RADEON_SURFACE0_LOWER_BOUND + 16 * i, 0);
+	OUTREG(RADEON_SURFACE0_UPPER_BOUND + 16 * i, 0);
     }
 
 #ifdef XF86DRI
@@ -3467,10 +3395,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 #endif
 
     /* Initial setup of surfaces */
-    if (!info->IsSecondary) {
-	RADEONTRACE(("Setting up initial surfaces\n"));
-	RADEONChangeSurfaces(pScrn);
-    }
+    RADEONTRACE(("Setting up initial surfaces\n"));
+    RADEONChangeSurfaces(pScrn);
 
 				/* Memory manager setup */
 
@@ -3704,10 +3630,8 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 #endif
 
     /* Make sure surfaces are allright since DRI setup may have changed them */
-    if (!info->IsSecondary) {
-	RADEONTRACE(("Setting up final surfaces\n"));
-	RADEONChangeSurfaces(pScrn);
-    }
+    RADEONTRACE(("Setting up final surfaces\n"));
+    RADEONChangeSurfaces(pScrn);
 
     /* Enable aceleration */
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
@@ -4614,27 +4538,24 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
 	unsigned int surf_info = swap_pattern;
 	unsigned char *RADEONMMIO = info->MMIO;
 	/* we don't need anything like WaitForFifo, no? */
-	if (!info->IsSecondary) {
-	    if (info->tilingEnabled) {
-		if (IS_R300_VARIANT)
-		   surf_info |= (width_bytes / 8) | color_pattern;
-		else
-		   surf_info |= (width_bytes / 16) | color_pattern;
-	    }
-	    OUTREG(RADEON_SURFACE0_INFO, surf_info);
-	    OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0);
-	    OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1);
+	if (info->tilingEnabled) {
+	    if (IS_R300_VARIANT)
+		surf_info |= (width_bytes / 8) | color_pattern;
+	    else
+		surf_info |= (width_bytes / 16) | color_pattern;
+	}
+	OUTREG(RADEON_SURFACE0_INFO, surf_info);
+	OUTREG(RADEON_SURFACE0_LOWER_BOUND, 0);
+	OUTREG(RADEON_SURFACE0_UPPER_BOUND, bufferSize - 1);
 /*	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		"surface0 set to %x, LB 0x%x UB 0x%x\n",
 		surf_info, 0, bufferSize - 1024);*/
-	}
     }
 
     /* Update surface images */
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
-// hack, but it's going away soon
 void
 RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
 {
@@ -4677,7 +4598,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     /* Disable all outputs at initial mode set.  the ones we want will
        get set by RADEONEnableDisplay()
      */
-    if (!info->IsSwitching && !info->IsSecondary)
+    if (!info->IsSwitching)
         RADEONDisableDisplays(pScrn);
 
     /* When changing mode with Dual-head card, care must be taken for
@@ -4693,30 +4614,20 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
      * in all cases
      */
     if (info->IsSwitching) {
-	if (info->IsSecondary) {
-	    RADEONRestoreMemMapRegisters(pScrn, restore);
-	    RADEONRestoreCommonRegisters(pScrn, restore);
+	RADEONRestoreMemMapRegisters(pScrn, restore);
+	RADEONRestoreCommonRegisters(pScrn, restore);
+	if (pCRTC2->binding == 1) {
 	    RADEONRestoreCrtc2Registers(pScrn, restore);
 	    RADEONRestorePLL2Registers(pScrn, restore);
-	    RADEONRestoreFPRegisters(pScrn, restore);
-	    RADEONRestoreDACRegisters(pScrn, restore);
-	    RADEONEnableOutputs(pScrn, 1);
-	} else {
-	    RADEONRestoreMemMapRegisters(pScrn, restore);
-	    RADEONRestoreCommonRegisters(pScrn, restore);
-	    if (pCRTC2->binding == 1) {
-		RADEONRestoreCrtc2Registers(pScrn, restore);
-		RADEONRestorePLL2Registers(pScrn, restore);
-	    }
+	}
 
-            RADEONRestoreCrtcRegisters(pScrn, restore);
-            RADEONRestorePLLRegisters(pScrn, restore);
-	    RADEONRestoreFPRegisters(pScrn, restore);
-	    RADEONRestoreDACRegisters(pScrn, restore);
-	    RADEONEnableOutputs(pScrn, 0);
-	    if (pCRTC2->binding == 1) {
-	      RADEONEnableOutputs(pScrn, 1);
-	    }
+	RADEONRestoreCrtcRegisters(pScrn, restore);
+	RADEONRestorePLLRegisters(pScrn, restore);
+	RADEONRestoreFPRegisters(pScrn, restore);
+	RADEONRestoreDACRegisters(pScrn, restore);
+	RADEONEnableOutputs(pScrn, 0);
+	if (pCRTC2->binding == 1) {
+	    RADEONEnableOutputs(pScrn, 1);
 	}
     } else {
 	RADEONRestoreMemMapRegisters(pScrn, restore);
@@ -4730,19 +4641,14 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestorePLLRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
 	RADEONRestoreDACRegisters(pScrn, restore);
-	ErrorF("finished FP restore\n");
 
 	RADEONEnableOutputs(pScrn, 0);
-	ErrorF("enable output1 done\n");
 
 	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
 	    RADEONEnableOutputs(pScrn, 1);
-	    ErrorF("enable output2 done\n");
 	}
     }
 
-    ErrorF("finished modeset\n");
-
 #if 0
     RADEONRestorePalette(pScrn, &info->SavedReg);
 #endif
@@ -4959,21 +4865,14 @@ static void RADEONSaveMode(ScrnInfoPtr p
 
     RADEONTRACE(("RADEONSaveMode(%p)\n", save));
 
-    if (info->IsSecondary) {
-        RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-        RADEONInfoPtr info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
-        memcpy(&info->SavedReg, &info0->SavedReg, sizeof(RADEONSaveRec));
-    } else {
-        RADEONSaveMemMapRegisters(pScrn, save);
-        RADEONSaveCommonRegisters(pScrn, save);
-        RADEONSavePLLRegisters (pScrn, save);
-        RADEONSaveCrtcRegisters (pScrn, save);
-        RADEONSaveFPRegisters (pScrn, save);
-        RADEONSaveCrtc2Registers (pScrn, save);
-        RADEONSavePLL2Registers (pScrn, save);
-	/*RADEONSavePalette(pScrn, save);*/
-	/*memcpy(&info->ModeReg, &info->SavedReg, sizeof(RADEONSaveRec));*/
-    }
+    RADEONSaveMemMapRegisters(pScrn, save);
+    RADEONSaveCommonRegisters(pScrn, save);
+    RADEONSavePLLRegisters (pScrn, save);
+    RADEONSaveCrtcRegisters (pScrn, save);
+    RADEONSaveFPRegisters (pScrn, save);
+    RADEONSaveCrtc2Registers (pScrn, save);
+    RADEONSavePLL2Registers (pScrn, save);
+    /*RADEONSavePalette(pScrn, save);*/
 
     RADEONTRACE(("RADEONSaveMode returns %p\n", save));
 }
@@ -4992,35 +4891,33 @@ static void RADEONSave(ScrnInfoPtr pScrn
 	return;
     }
 
-    if (!info->IsSecondary) {
+
 #ifdef WITH_VGAHW
-        if (info->VGAAccess) {
-           vgaHWPtr hwp = VGAHWPTR(pScrn);
+    if (info->VGAAccess) {
+	vgaHWPtr hwp = VGAHWPTR(pScrn);
 
-            vgaHWUnlock(hwp);
+	vgaHWUnlock(hwp);
 # if defined(__powerpc__)
-           /* temporary hack to prevent crashing on PowerMacs when trying to
-            * read VGA fonts and colormap, will find a better solution
-            * in the future. TODO: Check if there's actually some VGA stuff
-            * setup in the card at all !!
-            */
-           vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
+	/* temporary hack to prevent crashing on PowerMacs when trying to
+	 * read VGA fonts and colormap, will find a better solution
+	 * in the future. TODO: Check if there's actually some VGA stuff
+	 * setup in the card at all !!
+	 */
+	vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE); /* Save mode only */
 # else
-           /* Save mode * & fonts & cmap */
-           vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
+	/* Save mode * & fonts & cmap */
+	vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
 # endif
-           vgaHWLock(hwp);
-       }
-#endif
-	save->dp_datatype      = INREG(RADEON_DP_DATATYPE);
-	save->rbbm_soft_reset  = INREG(RADEON_RBBM_SOFT_RESET);
-	save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
-	RADEONPllErrataAfterIndex(info);
+	vgaHWLock(hwp);
     }
+#endif
+    save->dp_datatype      = INREG(RADEON_DP_DATATYPE);
+    save->rbbm_soft_reset  = INREG(RADEON_RBBM_SOFT_RESET);
+    save->clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
+    RADEONPllErrataAfterIndex(info);
 
     RADEONSaveMode(pScrn, save);
-    if (!info->IsSecondary)
-	RADEONSaveSurfaces(pScrn, save);
+    RADEONSaveSurfaces(pScrn, save);
 }
 
 /* Restore the original (text) mode */
@@ -5060,8 +4957,7 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 #endif
 
     RADEONRestoreMode(pScrn, restore);
-    if (!info->IsSecondary)
-	RADEONRestoreSurfaces(pScrn, restore);
+    RADEONRestoreSurfaces(pScrn, restore);
 
 #if 1
     /* Temp fix to "solve" VT switch problems.  When switching VTs on
@@ -5075,34 +4971,16 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 #ifdef WITH_VGAHW
     if (info->VGAAccess) {
        vgaHWPtr hwp = VGAHWPTR(pScrn);
-        if (!info->IsSecondary) {
-            vgaHWUnlock(hwp);
+       vgaHWUnlock(hwp);
 # if defined(__powerpc__)
-           /* Temporary hack to prevent crashing on PowerMacs when trying to
-            * write VGA fonts, will find a better solution in the future
-            */
-           vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
+       /* Temporary hack to prevent crashing on PowerMacs when trying to
+	* write VGA fonts, will find a better solution in the future
+	*/
+       vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE );
 # else
-           vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
+       vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
 # endif
-           vgaHWLock(hwp);
-        } else {
-            RADEONEntPtr  pRADEONEnt = RADEONEntPriv(pScrn);
-           ScrnInfoPtr   pScrn0 = pRADEONEnt->pPrimaryScrn;
-            RADEONInfoPtr info0 = RADEONPTR(pScrn0);
-           vgaHWPtr      hwp0;
-
-           if (info0->VGAAccess) {
-               hwp0 = VGAHWPTR(pScrn0);
-               vgaHWUnlock(hwp0);
-#if defined(__powerpc__)
-               vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE);
-#else
-               vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
-#endif
-               vgaHWLock(hwp0);
-           }
-       }
+       vgaHWLock(hwp);
     }
 #endif
 #if 0
@@ -6244,7 +6122,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
      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. */
-    if (crtc2 || info->IsSecondary) {
+    if (crtc2) {
 	reg = RADEON_CRTC2_OFFSET;
 	regcntl = RADEON_CRTC2_OFFSET_CNTL;
 	xytilereg = R300_CRTC2_TILE_X0_Y0;
@@ -6301,7 +6179,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 	/* can't get at sarea in a semi-sane way? */
 	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
 
-	if (crtc2 || info->IsSecondary) {
+	if (crtc2) {
 	    pSAREAPriv->crtc2_base = Base;
 	}
 	else {
@@ -6401,7 +6279,7 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 	{
 	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
 	    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-	    radeon_crtc->binding = info->IsSecondary ? 2 : 1;
+	    radeon_crtc->binding = 1;
 	    /* Mark that we'll need to re-set the mode for sure */
 	    memset(&crtc->mode, 0, sizeof(crtc->mode));
 	    if (!crtc->desiredMode.CrtcHDisplay) {
@@ -6418,8 +6296,7 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 	}
     }
 
-    if (!info->IsSecondary)
-	RADEONRestoreSurfaces(pScrn, &info->ModeReg);
+    RADEONRestoreSurfaces(pScrn, &info->ModeReg);
 #ifdef XF86DRI
     if (info->directRenderingEnabled) {
     	if (info->cardType == CARD_PCIE && info->pKernelDRMVersion->version_minor >= 19 && info->FbSecureSize)
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 818a2dd..6887388 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -179,9 +179,6 @@ typedef struct
     Bool IsSecondaryRestored;
     Bool RestorePrimary;
 
-    ScrnInfoPtr pSecondaryScrn;
-    ScrnInfoPtr pPrimaryScrn;
-
     Bool ReversedDAC;	  /* TVDAC used as primary dac */
     Bool ReversedTMDS;    /* DDC_DVI is used for external TMDS */
     xf86CrtcPtr pCrtc[RADEON_MAX_CRTC];
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 97724eb..6d085cc 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1333,7 +1333,7 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
      */
 
     /* Figure out which head we are on */
-    if ((info->OverlayOnCRTC2) || info->IsSecondary)
+    if (info->OverlayOnCRTC2)
 	dot_clock = info->ModeReg.dot_clock_freq_2;
     else
 	dot_clock = info->ModeReg.dot_clock_freq;
@@ -2454,7 +2454,7 @@ RADEONDisplayVideo(
        workarounds for chip erratas */
 
     /* Figure out which head we are on for dot clock */
-    if (info->OverlayOnCRTC2 || info->IsSecondary)
+    if (info->OverlayOnCRTC2)
         dot_clock = info->ModeReg.dot_clock_freq_2;
     else
         dot_clock = info->ModeReg.dot_clock_freq;
@@ -2575,14 +2575,6 @@ RADEONDisplayVideo(
 	offset5 += ((left >> 16) & ~7) << 1;
 	offset6 += ((left >> 16) & ~7) << 1;
     }
-    if (info->IsSecondary) {
-	offset1 += info->FbMapSize;
-	offset2 += info->FbMapSize;
-	offset3 += info->FbMapSize;
-	offset4 += info->FbMapSize;
-	offset5 += info->FbMapSize;
-	offset6 += info->FbMapSize;
-    }
 
     tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3);
     p1_h_accum_init = ((tmp <<  4) & 0x000f8000) |
@@ -2641,7 +2633,7 @@ RADEONDisplayVideo(
      * rendering for the second head.
      */
 
-    if (info->OverlayOnCRTC2 || info->IsSecondary) {
+    if (info->OverlayOnCRTC2) {
         x_off = 0;
         OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
                                       ((dstBox->y1*y_mult) << 16)));
diff-tree 9c2f20a83a5fed14225f4c3ebcd8ca41e9d4bd48 (from e187321ab8dd58d2b2fe92c062d070ba4820a2bf)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 21:13:23 2007 -0400

    RADEON: additional cleanups

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ceea69d..dbbf91f 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2536,7 +2536,6 @@ static Bool RADEONPreInitControllers(Scr
     if (!RADEONSetupConnectors(pScrn)) {
 	return FALSE;
     }
-
       
     RADEONMapControllers(pScrn);
 
@@ -5295,7 +5294,6 @@ static void RADEONInitLVDSRegisters(xf86
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
 
-/* XXX saved but never used??? */
     if (IsPrimary)
 	save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl &
 				~RADEON_LVDS_SEL_CRTC2;
@@ -6150,7 +6148,7 @@ Bool RADEONSwitchMode(int scrnIndex, Dis
 	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
     } else {
 	info->IsSwitching = TRUE;
-	ret = TRUE; //RADEONModeInit(xf86Screens[scrnIndex], mode);
+	ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
 	info->IsSwitching = FALSE;
     }
 
@@ -6327,16 +6325,16 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 	OUTREG(regcntl, crtcoffsetcntl);
     }
 
-    if (crtc2)
-	OUTREG(reg, Base);
-    else
-	OUTREG(reg, Base);
+    OUTREG(reg, Base);
 }
 
 void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
 {
     ScrnInfoPtr    pScrn      = xf86Screens[scrnIndex];
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86OutputPtr  output = config->output[config->compat_output];
+    xf86CrtcPtr	crtc = output->crtc;
 
 #ifdef XF86DRI
     if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
@@ -6345,12 +6343,17 @@ void RADEONAdjustFrame(int scrnIndex, in
     if (info->accelOn)
         RADEON_SYNC(info, pScrn);
 
-    if (info->FBDev) {
-	fbdevHWAdjustFrame(scrnIndex, x, y, flags);
-    } else {
-	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
+    if (crtc && crtc->enabled) {
+	if (info->FBDev) {
+	    fbdevHWAdjustFrame(scrnIndex, crtc->desiredX + x, crtc->desiredY + y, flags);
+	} else {
+	    RADEONDoAdjustFrame(pScrn, crtc->desiredX + x, crtc->desiredY + y, FALSE);
+	}
+	crtc->x = output->initial_x + x;
+	crtc->y = output->initial_y + y;
     }
 
+
 #ifdef XF86DRI
 	if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
 #endif
diff-tree e187321ab8dd58d2b2fe92c062d070ba4820a2bf (from e60a7bcaf5611ad4706b1d1442ce4cae49145f42)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 19:49:10 2007 -0400

    RADEON: add new ConnectorTable option and re-add PanelSize option

diff --git a/src/radeon.h b/src/radeon.h
index 7922f1a..2a2a672 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -147,6 +147,7 @@ typedef enum {
     OPTION_LVDS_PROBE_PLL,
     OPTION_ACCELMETHOD,
     OPTION_CONSTANTDPI,
+    OPTION_CONNECTORTABLE,
     OPTION_DRI
 } RADEONOpts;
 
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 737b170..c5caf9c 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -740,11 +740,20 @@ Bool RADEONGetLVDSInfo (xf86OutputPtr ou
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    char* s;
 
     ErrorF("LVDS get info");
 
     if (!RADEONGetLVDSInfoFromBIOS(output))
-        RADEONGetPanelInfoFromReg(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
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 8626b89..ceea69d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -189,6 +189,7 @@ static const OptionInfoRec RADEONOptions
     { OPTION_ACCELMETHOD,    "AccelMethod",      OPTV_STRING,  {0}, FALSE },
     { OPTION_CONSTANTDPI,    "ConstantDPI",	 OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DRI,            "DRI",       	 OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_CONNECTORTABLE, "ConnectorTable",   OPTV_STRING,  {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 18ef16d..e9e1aea 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -68,10 +68,11 @@ const RADEONMonitorType MonTypeID[7] = {
   MT_STV,     /* STV -> STV */
 };
 
-const char *TMDSTypeName[3] = {
-  "NONE",
+const char *TMDSTypeName[4] = {
+  "Unknown",
   "Internal",
-  "External"
+  "External",
+  "None"
 };
 
 const char *DDCTypeName[6] = {
@@ -83,15 +84,16 @@ const char *DDCTypeName[6] = {
   "LCD_DDC"
 };
 
-const char *DACTypeName[3] = {
+const char *DACTypeName[4] = {
   "Unknown",
   "Primary",
   "TVDAC/ExtDAC",
+  "None"
 };
 
 const char *ConnectorTypeName[8] = {
   "None",
-  "Proprietary",
+  "Proprietary/LVDS",
   "VGA",
   "DVI-I",
   "DVI-D",
@@ -473,7 +475,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     xf86OutputPtr output;
-    const char *s;
+    char *optstr;
     int i = 0, second = 0, max_mt = 5;
 
 
@@ -553,6 +555,21 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
         info->BiosConnector[0].DACType = DAC_PRIMARY;
     }
 
+    /* parse connector table option */
+    if (optstr = (char *)xf86GetOptValString(info->Options, OPTION_CONNECTORTABLE)) {
+	if (sscanf(optstr, "%d,%d,%d,%d,%d,%d,%d,%d",
+		   &info->BiosConnector[0].DDCType,
+		   &info->BiosConnector[0].DACType,
+		   &info->BiosConnector[0].TMDSType,
+		   &info->BiosConnector[0].ConnectorType,
+		   &info->BiosConnector[1].DDCType,
+		   &info->BiosConnector[1].DACType,
+		   &info->BiosConnector[1].TMDSType,
+		   &info->BiosConnector[1].ConnectorType) != 8) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid ConnectorTable option: %s\n", optstr);
+	}
+    }
+
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
 	if (!radeon_output) {
@@ -562,7 +579,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
 	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
 	    radeon_output->ConnectorType == CONNECTOR_DVI_D)
-	    radeon_output->DACType = DAC_UNKNOWN;
+	    radeon_output->DACType = DAC_NONE;
 	else
 	    radeon_output->DACType = info->BiosConnector[i].DACType;
 	radeon_output->DDCType = info->BiosConnector[i].DDCType;
@@ -595,8 +612,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		}
 		radeon_output->MonType = MT_UNKNOWN;
 		radeon_output->DDCType = DDC_LCD;
-		radeon_output->DACType = DAC_UNKNOWN;
-		radeon_output->TMDSType = TMDS_UNKNOWN;
+		radeon_output->DACType = DAC_NONE;
+		radeon_output->TMDSType = TMDS_NONE;
 		radeon_output->ConnectorType = CONNECTOR_LVDS_ATOM;
 		RADEONSetOutputType(pScrn, radeon_output);
 		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
@@ -620,8 +637,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 		}
 		radeon_output->MonType = MT_UNKNOWN;
 		radeon_output->DDCType = DDC_LCD;
-		radeon_output->DACType = DAC_UNKNOWN;
-		radeon_output->TMDSType = TMDS_UNKNOWN;
+		radeon_output->DACType = DAC_NONE;
+		radeon_output->TMDSType = TMDS_NONE;
 		radeon_output->ConnectorType = CONNECTOR_PROPRIETARY;
 		RADEONSetOutputType(pScrn, radeon_output);
 		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 2bb5b27..818a2dd 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -96,14 +96,16 @@ typedef enum
 {
     DAC_UNKNOWN = -1,
     DAC_PRIMARY = 0,
-    DAC_TVDAC   = 1
+    DAC_TVDAC   = 1,
+    DAC_NONE    = 2
 } RADEONDacType;
 
 typedef enum
 {
     TMDS_UNKNOWN = -1,
     TMDS_INT     = 0,
-    TMDS_EXT     = 1
+    TMDS_EXT     = 1,
+    TMDS_NONE    = 2
 } RADEONTmdsType;
 
 typedef struct {
diff-tree e60a7bcaf5611ad4706b1d1442ce4cae49145f42 (from 51caa5dccc4a2e14d1b41bb7868ad20468dd4cfe)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 18:14:29 2007 -0400

    RADEON: remove mergedfb, etc. cruft from man page

diff --git a/man/radeon.man b/man/radeon.man
index 447dcbe..fcb6d73 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -223,227 +223,6 @@ HIGH   \-\- Force to the highest priorit
 The default value is
 .B AUTO.
 .TP
-.BI "Option \*qMonitorLayout\*q \*q" string \*q
-.br
-This option is used to overwrite the detected monitor types.
-This is only required when driver makes a false detection.
-The possible monitor types are:
-.br
-NONE   \-\- Not connected
-.br
-CRT    \-\- Analog CRT monitor
-.br
-TMDS   \-\- Desktop flat panel
-.br 
-LVDS   \-\- Laptop flat panel
-.br
-This option can be used in following format:
-.br
-Option "MonitorLayout" "[type on primary], [type on secondary]"
-.br
-For example, Option "MonitorLayout" "CRT, TMDS"
-
-Primary/Secondary head for dual\-head cards:
-.br
-(when only one port is used, it will be treated as the primary regardless)
-.br
-.B Primary head:
-.br
-DVI port on DVI+VGA cards
-.br
-LCD output on laptops
-.br 
-Internal TMDS port on DVI+DVI cards
-.br 
-.B Secondary head:
-.br
-VGA port on DVI+VGA cards
-.br
-VGA port on laptops
-.br
-External TMDS port on DVI+DVI cards
-
-The default value is
-.B undefined.
-.TP 
-.BI "Option \*qMergedFB\*q \*q" boolean \*q
-This enables merged framebuffer mode.  In this mode you have a single 
-shared framebuffer with two viewports looking into it.  It is similar
-to Xinerama, but has some advantages.  It is faster than Xinerama, the
-DRI works on both heads, and it supports clone modes.  
-.br
-Merged framebuffer mode provides two linked viewports looking into a
-single large shared framebuffer.  The size of the framebuffer is 
-determined by the
-.B Virtual
-keyword defined on the
-.B Screen
-section of your __xconfigfile__ file.  It works just like regular virtual
-desktop except you have two viewports looking into it instead of one.
-.br
-For example, if you wanted a desktop composed of two 1024x768 viewports
-looking into a single desktop you would create a virtual desktop of 
-2048x768 (left/right) or 1024x1536 (above/below), e.g.,
-.br
-.B Virtual 2048 768
-or
-.B Virtual 1024 1536
-.br
-The virtual desktop can be larger than larger than the size of the viewports
-looking into it.  In this case the linked viewports will scroll around in the 
-virtual desktop.  Viewports with different sizes are also supported (e.g., one
-that is 1024x768 and one that is 640x480).  In this case the smaller viewport
-will scroll relative to the larger one such that none of the virtual desktop 
-is inaccessible.  If you do not define a virtual desktop the driver will create
-one based on the orientation of the heads and size of the largest defined mode in 
-the display section that is supported on each head.
-.br
-The relation of the viewports in specified by the
-.B CRT2Position
-Option.  The options are
-.B Clone
-,
-.B LeftOf
-,
-.B RightOf
-,
-.B Above
-, and
-.B Below.  
-MergedFB is enabled by default if a monitor is detected on each output.  If 
-no position is given it defaults to clone mode (the old clone options are now 
-deprecated, also, the option OverlayOnCRTC2 has been replaced by the Xv 
-attribute XV_SWITCHCRT; the overlay can be switched to CRT1 or CRT2 on the fly 
-in clone mode).
-.br
-The maximum framebuffer size that the 2D acceleration engine can handle is 
-8192x8192.  The maximum framebuffer size that the 3D engine can handle is 
-2048x2048.
-.br
-.B Note:
-Page flipping does not work well in certain configurations with MergedFB.  If you 
-see rendering errors or other strange behavior, disable page flipping. Also MergedFB
-is not compatible with the 
-.B UseFBDev 
-option.
-.br
-The default value is
-.B undefined.
-.TP 
-.BI "Option \*qCRT2HSync\*q \*q" "string" \*q
-Set the horizontal sync range for the secondary  monitor. 
-It is not required if a DDC\-capable monitor is connected.
-.br
-For example, Option "CRT2HSync" "30.0-86.0"
-.br
-The default value is
-.B undefined.
-.TP 
-.BI "Option \*qCRT2VRefresh\*q \*q" "string" \*q
-Set the vertical refresh range for the secondary monitor.
-It is not required if a DDC\-capable monitor is connected.
-.br
-For example, Option "CRT2VRefresh" "50.0-120.0"
-.br
-The default value is
-.B undefined.
-.TP
-.BI "Option \*qCRT2Position\*q \*q" "string" \*q
-Set the relationship of CRT2 relative to CRT1. Valid options are: 
-.B Clone
-,
-.B LeftOf
-,
-.B RightOf
-,
-.B Above
-, and
-.B Below
-.
-.br
-For example, Option "CRT2Position" "RightOf"
-.br
-This option also supports an offset.  This is most useful when
-.B MergedNonRectangular 
-is enabled.  For example if you want CRT2 to be offset 100 pixels down from 
-the start of CRT1, you'd type:
-.br
-Option "CRT2Position" "LeftOf 100"
-.br
-The offset is vertical for LeftOf and RightOf and horizontal for Above and 
-Below.  Offsets can be positive or negative.
-.br
-The default value is
-.B Clone.
-.TP
-.BI "Option \*qMetaModes\*q \*q" "string" \*q
-MetaModes are mode combinations for CRT1 and CRT2.  If you are using merged
-frame buffer mode and want to change modes (CTRL-ALT-+/-), these define which
-modes will be switched to on CRT1 and CRT2.  The MetaModes are defined as 
-CRT1Mode-CRT2Mode (800x600-1024x768).  Modes listed individually (800x600) 
-define clone modes, that way you can mix clone modes with non-clone modes. 
-Also some programs require "standard" modes.  If you want to add clone modes 
-of different refreshes or sizes to the mix, they are defined as CRT1Mode+CRT2Mode 
-(800x600+1024x768).
-.br
-Note:  Any mode you use in the MetaModes must be defined in the
-.B Screen 
-section of your __xconfigfile__ file.  Modes not defined there will be ignored when
-the MetaModes are parsed since the driver uses them to make sure the monitors can 
-handle those modes.  If you do not define a MetaMode the driver will create
-one based on the orientation of the heads and size of the largest defined mode in 
-the display section that is supported on each head.
-.br
-.B Modes "1024x768" "800x600" "640x480"
-.br
-For example, Option "MetaModes" "1024x768-1024x768 800x600-1024x768 640x480-800x600 800x600"
-.br
-The default value is
-.B undefined.
-.TP
-.BI "Option \*qMergedXinerama\*q \*q" boolean \*q
-Since merged framebuffer mode does not use Xinerama, apps are not able to intelligently
-place windows.  Merged framebuffer mode provides its own pseudo-Xinerama.  This allows
-Xinerama compliant applications to place windows appropriately.  There are some caveats.
-Since merged framebuffer mode is able to change relative screen sizes and orientations on
-the fly, as well has having overlapping viewports, pseudo-Xinerama, might not always 
-provide the right hints.  Also many Xinerama compliant applications only query Xinerama
-once at startup; if the information changes, they may not be aware of the change.  If
-you are already using Xinerama (e.g., a single head card and a dualhead card providing
-three heads), pseudo-Xinerama will be disabled.
-.br
-This option allows you turn off the driver provided pseudo-Xinerama extension.
-.br
-The default value is
-.B TRUE.
-.TP 
-.BI "Option \*qMergedXineramaCRT2IsScreen0\*q \*q" boolean \*q
-By default the pseudo-Xinerama provided by the driver makes the left-most or bottom
-head Xinerama screen 0.  Certain Xinerama-aware applications do special things with 
-screen 0.  To change that behavior, use this option.
-.br
-The default value is
-.B undefined.
-.TP
-.BI "Option \*qMergedDPI\*q \*q" "string" \*q
-The driver will attempt to figure out an appropriate DPI based on the DDC information
-and the orientation of the heads when in merged framebuffer mode.  If this value does 
-not suit you, you can manually set the DPI using this option.
-.br
-For example, Option "MergedDPI" "100 100"
-.br
-The default value is
-.B undefined.
-.TP
-.BI "Option \*qMergedNonRectangular\*q \*q" boolean \*q
-If you are using MergedFB with two modes of different sizes, turn this option on to 
-keep the smaller head from scrolling within the larger virtual desktop and to keep 
-the mouse from moving into that area.  Applications that are not Xinerama aware can 
-potentially end up stranded in this area.
-.br
-The default value is
-.B FALSE.
-.TP
 .BI "Option \*qColorTiling\*q \*q" "boolean" \*q
 Frame buffer can be addressed either in linear or tiled mode. Tiled mode can provide
 significant performance benefits with 3D applications, for 2D it shouldn't matter
@@ -478,12 +257,6 @@ For example, Option "PanelSize" "1400x10
 .br
 The default value is
 .B none.
-.TP 
-.BI "Option \*qPanelOff\*q \*q" boolean \*q
-Disable panel output.
-.br
-The default value is
-.B off.
 .TP
 .BI "Option \*qEnablePageFlip\*q \*q" boolean \*q
 Enable page flipping for 3D acceleration. This will increase performance
diff --git a/src/radeon.h b/src/radeon.h
index f8d9c65..7922f1a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -117,7 +117,6 @@ typedef enum {
     OPTION_ACCEL_DFS,
 #endif
 #endif
-    OPTION_PANEL_OFF,
     OPTION_DDC_MODE,
     OPTION_IGNORE_EDID,
     OPTION_FBDEV,
diff-tree 51caa5dccc4a2e14d1b41bb7868ad20468dd4cfe (from c5da9d4040cb08598d171d20f84d3f6c20a033e0)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 18:10:02 2007 -0400

    RADEON: remove old mergedfb and dualhead options that are no longer used

diff --git a/src/radeon.h b/src/radeon.h
index 762376a..f8d9c65 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -119,19 +119,8 @@ typedef enum {
 #endif
     OPTION_PANEL_OFF,
     OPTION_DDC_MODE,
-    OPTION_MONITOR_LAYOUT,
     OPTION_IGNORE_EDID,
     OPTION_FBDEV,
-    OPTION_MERGEDFB,
-    OPTION_CRT2HSYNC,
-    OPTION_CRT2VREFRESH,
-    OPTION_CRT2POS,
-    OPTION_METAMODES,
-    OPTION_MERGEDDPI,
-    OPTION_RADEONXINERAMA,
-    OPTION_CRT2ISSCRN0,
-    OPTION_MERGEDFBNONRECT,
-    OPTION_MERGEDFBMOUSER,
     OPTION_DISP_PRIORITY,
     OPTION_PANEL_SIZE,
     OPTION_MIN_DOTCLOCK,
@@ -159,7 +148,6 @@ typedef enum {
     OPTION_LVDS_PROBE_PLL,
     OPTION_ACCELMETHOD,
     OPTION_CONSTANTDPI,
-    OPTION_REVERSE_DISPLAY,
     OPTION_DRI
 } RADEONOpts;
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index adc635d..8626b89 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -160,7 +160,6 @@ static const OptionInfoRec RADEONOptions
 #endif
 #endif
     { OPTION_DDC_MODE,       "DDCMode",          OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_MONITOR_LAYOUT, "MonitorLayout",    OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_IGNORE_EDID,    "IgnoreEDID",       OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_FBDEV,          "UseFBDev",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DISP_PRIORITY,  "DisplayPriority",  OPTV_ANYSTR,  {0}, FALSE },
@@ -189,7 +188,6 @@ static const OptionInfoRec RADEONOptions
     { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL",     OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_ACCELMETHOD,    "AccelMethod",      OPTV_STRING,  {0}, FALSE },
     { OPTION_CONSTANTDPI,    "ConstantDPI",	 OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_REVERSE_DISPLAY,"ReverseDisplay",   OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DRI,            "DRI",       	 OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
diff-tree c5da9d4040cb08598d171d20f84d3f6c20a033e0 (from e776fa9ecc53d63f916a5447a76fb2bb3b824167)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 18:05:38 2007 -0400

    RADEON: remove more dead code

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 8ce1912..737b170 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1478,92 +1478,3 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     }
 }
 
-#if 0
-static void RADEONDPMSSetOn(xf86OutputPtr output)
-{
-  ScrnInfoPtr pScrn = output->scrn;
-  RADEONInfoPtr  info       = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
-  RADEONMonitorType MonType;
-  RADEONTmdsType TmdsType;
-  RADEONDacType DacType;
-  RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-  MonType = radeon_output->MonType;
-  TmdsType = radeon_output->TMDSType;
-  DacType = radeon_output->DACType;
-
-  ErrorF("radeon_dpms_on %d %d %d\n", radeon_output->num, MonType, DacType);
-
-  switch(MonType) {
-  case MT_LCD:
-    OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON);
-    usleep (radeon_output->PanelPwrDly * 1000);
-    OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON);
-    break;
-  case MT_DFP:
-    if (TmdsType == TMDS_EXT) {
-      OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
-      OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_ON, ~RADEON_FP2_ON);
-      if (info->ChipFamily >= CHIP_FAMILY_R200) {
-	OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_DVO_EN, 
-		 ~RADEON_FP2_DVO_EN);
-      }
-    } else
-      OUTREGP (RADEON_FP_GEN_CNTL, (RADEON_FP_FPON | RADEON_FP_TMDS_EN),
-	       ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
-    break;
-  case MT_CRT:
-  default:
-    RADEONDacPowerSet(pScrn, TRUE, (DacType == DAC_PRIMARY));
-    break;
-  }
-}
-
-static void RADEONDPMSSetOff(xf86OutputPtr output)
-{
-  ScrnInfoPtr pScrn = output->scrn;
-  RADEONInfoPtr  info       = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
-  RADEONMonitorType MonType;
-  RADEONTmdsType TmdsType;
-  RADEONDacType DacType;
-  unsigned long tmpPixclksCntl;
-  RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-  MonType = radeon_output->MonType;
-  TmdsType = radeon_output->TMDSType;
-  DacType = radeon_output->DACType;
-
-  switch(MonType) {
-  case MT_LCD:
-    tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-    if (info->IsMobility || info->IsIGP) {
-      /* Asic bug, when turning off LVDS_ON, we have to make sure
-	 RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
-      */
-      OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, 0, ~RADEON_PIXCLK_LVDS_ALWAYS_ONb);
-    }
-    OUTREGP (RADEON_LVDS_GEN_CNTL, 0,
-	     ~(RADEON_LVDS_BLON | RADEON_LVDS_ON));
-    if (info->IsMobility || info->IsIGP) {
-      OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
-    }
-    break;
-  case MT_DFP:
-    if (TmdsType == TMDS_EXT) {
-      OUTREGP (RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-      OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_ON);
-      if (info->ChipFamily >= CHIP_FAMILY_R200) {
-	OUTREGP (RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_DVO_EN);
-      }
-    } else
-      OUTREGP (RADEON_FP_GEN_CNTL, 0, ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN));
-    break;
-  case MT_CRT:
-  default:
-    RADEONDacPowerSet(pScrn, FALSE, (DacType == DAC_PRIMARY));
-    break;
-  }
-}
-#endif
diff-tree e776fa9ecc53d63f916a5447a76fb2bb3b824167 (from 58ce388452b7bc790c438d75c9cf4a0f69f0d7b2)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 15:43:39 2007 -0400

    RADEON: re-org randr code
    
    - move crtc stuff to radeon_crtc.c
    - move output stuff to radeon_output.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 55a0f2a..bdc2979 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -80,7 +80,8 @@ radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
-	radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	radeon_crtc.c radeon_output.c radeon_modes.c \
+	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
diff --git a/src/radeon_crtc.c b/src/radeon_crtc.c
new file mode 100644
index 0000000..1047dcf
--- /dev/null
+++ b/src/radeon_crtc.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ *                VA Linux Systems Inc., Fremont, California.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "fbdevhw.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+
+void radeon_crtc_load_lut(xf86CrtcPtr crtc);
+
+static void
+radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+  int mask;
+  ScrnInfoPtr pScrn = crtc->scrn;
+  RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+  RADEONInfoPtr info = RADEONPTR(pScrn);
+  unsigned char *RADEONMMIO = info->MMIO;
+    
+  mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
+
+
+  switch(mode) {
+  case DPMSModeOn:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+    }
+    break;
+  case DPMSModeStandby:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
+    }
+    break;
+  case DPMSModeSuspend:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
+    }
+    break;
+  case DPMSModeOff:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+    }
+    break;
+  }
+  
+  if (mode != DPMSModeOff)
+    radeon_crtc_load_lut(crtc);  
+}
+
+static Bool
+radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
+		     DisplayModePtr adjusted_mode)
+{
+    return TRUE;
+}
+
+static void
+radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
+{
+    radeon_crtc_dpms(crtc, DPMSModeOff);
+}
+
+static void
+radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
+		     DisplayModePtr adjusted_mode, int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONMonitorType montype;
+    int i = 0;
+    double         dot_clock = 0;
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+	if (output->crtc == crtc) {
+	    montype = radeon_output->MonType;
+	}
+    }
+    
+    ErrorF("init memmap\n");
+    RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info);
+    ErrorF("init common\n");
+    RADEONInitCommonRegisters(&info->ModeReg, info);
+
+    switch (radeon_crtc->crtc_id) {
+    case 0:
+	ErrorF("init crtc1\n");
+	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode, x, y);
+        dot_clock = adjusted_mode->Clock / 1000.0;
+        if (dot_clock) {
+	    ErrorF("init pll1\n");
+	    RADEONInitPLLRegisters(pScrn, info, &info->ModeReg, &info->pll, dot_clock);
+        } else {
+            info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
+            info->ModeReg.ppll_div_3   = info->SavedReg.ppll_div_3;
+            info->ModeReg.htotal_cntl  = info->SavedReg.htotal_cntl;
+        }
+	break;
+    case 1:
+	ErrorF("init crtc2\n");
+        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode, x, y);
+        dot_clock = adjusted_mode->Clock / 1000.0;
+        if (dot_clock) {
+	    ErrorF("init pll2\n");
+	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, montype != MT_CRT);
+        }
+	break;
+    }
+    
+    ErrorF("restore memmap\n");
+    RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
+    ErrorF("restore common\n");
+    RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);    
+
+    switch (radeon_crtc->crtc_id) {
+    case 0:
+	ErrorF("restore crtc1\n");
+	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
+	ErrorF("restore pll1\n");
+	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
+	break;
+    case 1:
+	ErrorF("restore crtc2\n");
+	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
+	ErrorF("restore pll2\n");
+	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
+	break;
+    }
+
+    if (info->DispPriority)
+        RADEONInitDispBandwidth(pScrn);
+
+}
+
+static void
+radeon_crtc_mode_commit(xf86CrtcPtr crtc)
+{
+    radeon_crtc_dpms(crtc, DPMSModeOn);
+}
+
+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;
+    int i;
+
+    if (!crtc->enabled)
+	return;
+
+    PAL_SELECT(radeon_crtc->crtc_id);
+
+    for (i = 0; i < 256; i++) {
+	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+    }
+}
+
+
+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++) {
+	radeon_crtc->lut_r[i] = red[i] >> 8;
+	radeon_crtc->lut_g[i] = green[i] >> 8;
+	radeon_crtc->lut_b[i] = blue[i] >> 8;
+    }
+
+    radeon_crtc_load_lut(crtc);
+}
+
+static Bool
+radeon_crtc_lock(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    Bool           CPStarted   = info->CPStarted;
+
+#ifdef XF86DRI
+    if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
+#endif
+
+    if (info->accelOn)
+        RADEON_SYNC(info, pScrn);
+    return FALSE;
+}
+
+static void
+radeon_crtc_unlock(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+
+#ifdef XF86DRI
+	if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
+#endif
+
+    if (info->accelOn)
+        RADEON_SYNC(info, pScrn);
+}
+
+static const xf86CrtcFuncsRec radeon_crtc_funcs = {
+    .dpms = radeon_crtc_dpms,
+    .save = NULL, /* XXX */
+    .restore = NULL, /* XXX */
+    .mode_fixup = radeon_crtc_mode_fixup,
+    .prepare = radeon_crtc_mode_prepare,
+    .mode_set = radeon_crtc_mode_set,
+    .commit = radeon_crtc_mode_commit,
+    .gamma_set = radeon_crtc_gamma_set,
+    .lock = radeon_crtc_lock,
+    .unlock = radeon_crtc_unlock,
+    .set_cursor_colors = radeon_crtc_set_cursor_colors,
+    .set_cursor_position = radeon_crtc_set_cursor_position,
+    .show_cursor = radeon_crtc_show_cursor,
+    .hide_cursor = radeon_crtc_hide_cursor,
+/*    .load_cursor_image = i830_crtc_load_cursor_image, */
+    .load_cursor_argb = radeon_crtc_load_cursor_argb,
+    .destroy = NULL, /* XXX */
+};
+
+Bool RADEONAllocateControllers(ScrnInfoPtr pScrn)
+{
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+
+    if (pRADEONEnt->Controller[0])
+      return TRUE;
+
+    pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+    if (!pRADEONEnt->pCrtc[0])
+      return FALSE;
+
+    pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+    if (!pRADEONEnt->Controller[0])
+        return FALSE;
+
+    pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
+    pRADEONEnt->Controller[0]->crtc_id = 0;
+
+    if (!pRADEONEnt->HasCRTC2)
+	return TRUE;
+
+    pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+    if (!pRADEONEnt->pCrtc[1])
+      return FALSE;
+
+    pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
+    if (!pRADEONEnt->Controller[1])
+    {
+	xfree(pRADEONEnt->Controller[0]);
+	return FALSE;
+    }
+
+    pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
+    pRADEONEnt->Controller[1]->crtc_id = 1;
+    return TRUE;
+}
+
+/**
+ * In the current world order, there are lists of modes per output, which may
+ * or may not include the mode that was asked to be set by XFree86's mode
+ * selection.  Find the closest one, in the following preference order:
+ *
+ * - Equality
+ * - Closer in size to the requested mode, but no larger
+ * - Closer in refresh rate to the requested mode.
+ */
+DisplayModePtr
+RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
+{
+    ScrnInfoPtr	pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    DisplayModePtr pBest = NULL, pScan = NULL;
+    int i;
+
+    /* Assume that there's only one output connected to the given CRTC. */
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr  output = xf86_config->output[i];
+	if (output->crtc == crtc && output->probed_modes != NULL)
+	{
+	    pScan = output->probed_modes;
+	    break;
+	}
+    }
+
+    /* If the pipe doesn't have any detected modes, just let the system try to
+     * spam the desired mode in.
+     */
+    if (pScan == NULL) {
+	RADEONCrtcPrivatePtr  radeon_crtc = crtc->driver_private;
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "No crtc mode list for crtc %d,"
+		   "continuing with desired mode\n", radeon_crtc->crtc_id);
+	return pMode;
+    }
+
+    for (; pScan != NULL; pScan = pScan->next) {
+	assert(pScan->VRefresh != 0.0);
+
+	/* If there's an exact match, we're done. */
+	if (xf86ModesEqual(pScan, pMode)) {
+	    pBest = pMode;
+	    break;
+	}
+
+	/* Reject if it's larger than the desired mode. */
+	if (pScan->HDisplay > pMode->HDisplay ||
+	    pScan->VDisplay > pMode->VDisplay)
+	{
+	    continue;
+	}
+
+	if (pBest == NULL) {
+	    pBest = pScan;
+	    continue;
+	}
+
+	/* Find if it's closer to the right size than the current best
+	 * option.
+	 */
+	if ((pScan->HDisplay > pBest->HDisplay &&
+	     pScan->VDisplay >= pBest->VDisplay) ||
+	    (pScan->HDisplay >= pBest->HDisplay &&
+	     pScan->VDisplay > pBest->VDisplay))
+	{
+	    pBest = pScan;
+	    continue;
+	}
+
+	/* Find if it's still closer to the right refresh than the current
+	 * best resolution.
+	 */
+	if (pScan->HDisplay == pBest->HDisplay &&
+	    pScan->VDisplay == pBest->VDisplay &&
+	    (fabs(pScan->VRefresh - pMode->VRefresh) <
+	     fabs(pBest->VRefresh - pMode->VRefresh))) {
+	    pBest = pScan;
+	}
+    }
+
+    if (pBest == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "No suitable mode found to program for the pipe.\n"
+		   "	continuing with desired mode %dx%d@%.1f\n",
+		   pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
+    } else if (!xf86ModesEqual(pBest, pMode)) {
+      RADEONCrtcPrivatePtr  radeon_crtc = crtc->driver_private;
+      int		    crtc = radeon_crtc->crtc_id;
+      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 "
+		   "mode %dx%d@%.1f\n", crtc,
+		   pBest->HDisplay, pBest->VDisplay, pBest->VRefresh,
+		   pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
+	pMode = pBest;
+    }
+    return pMode;
+}
+
+void
+RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
+{
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int c;
+    int highx = 0, highy = 0;
+    int crtc_num;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+        xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (!crtc->enabled)
+	    continue;
+
+	if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y))
+	    crtc_num = c;
+    }
+
+    if (crtc_num == 1)
+        info->OverlayOnCRTC2 = TRUE;
+    else
+        info->OverlayOnCRTC2 = FALSE;
+}
+
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7ec6c6b..8ce1912 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -47,85 +47,8 @@
 #include "radeon_probe.h"
 #include "radeon_version.h"
 
-void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output);
-void radeon_crtc_load_lut(xf86CrtcPtr crtc);
 extern int getRADEONEntityIndex(void);
 
-const char *MonTypeName[7] = {
-  "AUTO",
-  "NONE",
-  "CRT",
-  "LVDS",
-  "TMDS",
-  "CTV",
-  "STV"
-};
-
-const RADEONMonitorType MonTypeID[7] = {
-  MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */
-  MT_NONE,    /* NONE -> NONE */
-  MT_CRT,     /* CRT -> CRT */
-  MT_LCD,     /* Laptop LCDs are driven via LVDS port */
-  MT_DFP,     /* DFPs are driven via TMDS */
-  MT_CTV,     /* CTV -> CTV */
-  MT_STV,     /* STV -> STV */
-};
-
-const char *TMDSTypeName[3] = {
-  "NONE",
-  "Internal",
-  "External"
-};
-
-const char *DDCTypeName[6] = {
-  "NONE",
-  "MONID",
-  "DVI_DDC",
-  "VGA_DDC",
-  "CRT2_DDC",
-  "LCD_DDC"
-};
-
-const char *DACTypeName[3] = {
-  "Unknown",
-  "Primary",
-  "TVDAC/ExtDAC",
-};
-
-const char *ConnectorTypeName[8] = {
-  "None",
-  "Proprietary",
-  "VGA",
-  "DVI-I",
-  "DVI-D",
-  "CTV",
-  "STV",
-  "Unsupported"
-};
-
-const char *ConnectorTypeNameATOM[10] = {
-  "None",
-  "VGA",
-  "DVI-I",
-  "DVI-D",
-  "DVI-A",
-  "STV",
-  "CTV",
-  "LVDS",
-  "Digital",
-  "Unsupported"
-};
-
-const char *OutputType[10] = {
-    "None",
-    "VGA",
-    "DVI",
-    "LVDS",
-    "S-video",
-    "Composite",
-};
-
-
 static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
 {
     {{0, 0}, {0, 0}, {0, 0}, {0, 0}},				/*CHIP_FAMILY_UNKNOW*/
@@ -320,7 +243,7 @@ void RADEONSetSyncRangeFromEdid(ScrnInfo
     }
 }
 
-static RADEONMonitorType
+RADEONMonitorType
 RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
@@ -566,7 +489,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoP
 }
 
 
-static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
+RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -661,7 +584,7 @@ static RADEONMonitorType RADEONDisplayDD
     return MonType;
 }
 
-static void RADEONGetPanelInfoFromReg (xf86OutputPtr output)
+void RADEONGetPanelInfoFromReg (xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -716,7 +639,7 @@ static void RADEONGetPanelInfoFromReg (x
 /* 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)
+void RADEONUpdatePanelSize(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -812,7 +735,7 @@ static void RADEONUpdatePanelSize(xf86Ou
     }
 }
 
-static Bool RADEONGetLVDSInfo (xf86OutputPtr output)
+Bool RADEONGetLVDSInfo (xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -874,7 +797,7 @@ static Bool RADEONGetLVDSInfo (xf86Outpu
     return TRUE;
 }
 
-static void RADEONGetTMDSInfo(xf86OutputPtr output)
+void RADEONGetTMDSInfo(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -908,102 +831,6 @@ void RADEONGetTVDacAdjInfo(xf86OutputPtr
     }
 }
 
-static void RADEONSwapOutputs(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONBIOSConnector tmp;
-    
-    tmp = info->BiosConnector[0];
-    info->BiosConnector[0] = info->BiosConnector[1];
-    info->BiosConnector[1] = tmp;
-    
-}
-
-static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    RADEONMonitorType MonType = MT_NONE;
-
-
-    if (info->IsMobility) {
-        if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
-	     radeon_output->ConnectorType == CONNECTOR_PROPRIETARY) {
-	     if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
-	         MonType =  MT_LCD;
-        }
-	/* non-DDC TMDS panel connected through DVO */
-	if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_ON)
-	  MonType = MT_DFP;
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Detected Monitor Type: %d\n", MonType);
-
-    return MonType;
-
-}
-
-/* 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) {
-      if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output)));
-      else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
-      else if (radeon_output->DACType == DAC_PRIMARY) 
-	  radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
-    }
-
-    if (output->MonInfo) {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
-		 info->IsAtomBios ?
-		 ConnectorTypeNameATOM[radeon_output->ConnectorType]:
-		 ConnectorTypeName[radeon_output->ConnectorType]
-		 );
-      xf86PrintEDID( output->MonInfo );
-    }
-}
-
-Bool RADEONMapControllers(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;
-    int o;
-
-    pRADEONEnt->Controller[0]->binding = 1;
-    pRADEONEnt->Controller[1]->binding = 1;
-
-    for (o = 0; o < xf86_config->num_output; o++) {
-      output = xf86_config->output[o];
-      radeon_output = output->driver_private;
-
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		 "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
-	  o,
-	  MonTypeName[radeon_output->MonType+1],
-	  info->IsAtomBios ? 
-	  ConnectorTypeNameATOM[radeon_output->ConnectorType]:
-	  ConnectorTypeName[radeon_output->ConnectorType],
-	  DACTypeName[radeon_output->DACType+1],
-	  TMDSTypeName[radeon_output->TMDSType+1],
-	  DDCTypeName[radeon_output->DDCType]);
-
-    }
-
-    return TRUE;
-}
-
 /*
  * Powering done DAC, needed for DPMS problem with ViewSonic P817 (or its variant).
  *
@@ -1651,6 +1478,7 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     }
 }
 
+#if 0
 static void RADEONDPMSSetOn(xf86OutputPtr output)
 {
   ScrnInfoPtr pScrn = output->scrn;
@@ -1738,818 +1566,4 @@ static void RADEONDPMSSetOff(xf86OutputP
     break;
   }
 }
-
-
-static void
-radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
-  int mask;
-  ScrnInfoPtr pScrn = crtc->scrn;
-  RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-  RADEONInfoPtr info = RADEONPTR(pScrn);
-  unsigned char *RADEONMMIO = info->MMIO;
-    
-  mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
-
-
-  switch(mode) {
-  case DPMSModeOn:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
-    }
-    break;
-  case DPMSModeStandby:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
-    }
-    break;
-  case DPMSModeSuspend:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
-    }
-    break;
-  case DPMSModeOff:
-    if (radeon_crtc->crtc_id) {
-      OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
-    } else {
-      OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
-    }
-    break;
-  }
-  
-  if (mode != DPMSModeOff)
-    radeon_crtc_load_lut(crtc);  
-}
-
-static Bool
-radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
-		     DisplayModePtr adjusted_mode)
-{
-    return TRUE;
-}
-
-static void
-radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
-{
-    radeon_crtc_dpms(crtc, DPMSModeOff);
-}
-
-static void
-radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
-		     DisplayModePtr adjusted_mode, int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONMonitorType montype;
-    int i = 0;
-    double         dot_clock = 0;
-
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-	if (output->crtc == crtc) {
-	    montype = radeon_output->MonType;
-	}
-    }
-    
-    ErrorF("init memmap\n");
-    RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info);
-    ErrorF("init common\n");
-    RADEONInitCommonRegisters(&info->ModeReg, info);
-
-    switch (radeon_crtc->crtc_id) {
-    case 0:
-	ErrorF("init crtc1\n");
-	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode, x, y);
-        dot_clock = adjusted_mode->Clock / 1000.0;
-        if (dot_clock) {
-	    ErrorF("init pll1\n");
-	    RADEONInitPLLRegisters(pScrn, info, &info->ModeReg, &info->pll, dot_clock);
-        } else {
-            info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
-            info->ModeReg.ppll_div_3   = info->SavedReg.ppll_div_3;
-            info->ModeReg.htotal_cntl  = info->SavedReg.htotal_cntl;
-        }
-	break;
-    case 1:
-	ErrorF("init crtc2\n");
-        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode, x, y);
-        dot_clock = adjusted_mode->Clock / 1000.0;
-        if (dot_clock) {
-	    ErrorF("init pll2\n");
-	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, montype != MT_CRT);
-        }
-	break;
-    }
-    
-    ErrorF("restore memmap\n");
-    RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
-    ErrorF("restore common\n");
-    RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);    
-
-    switch (radeon_crtc->crtc_id) {
-    case 0:
-	ErrorF("restore crtc1\n");
-	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore pll1\n");
-	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
-	break;
-    case 1:
-	ErrorF("restore crtc2\n");
-	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
-	ErrorF("restore pll2\n");
-	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
-	break;
-    }
-
-    if (info->DispPriority)
-        RADEONInitDispBandwidth(pScrn);
-
-}
-
-static void
-radeon_crtc_mode_commit(xf86CrtcPtr crtc)
-{
-    radeon_crtc_dpms(crtc, DPMSModeOn);
-}
-
-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;
-    int i;
-
-    if (!crtc->enabled)
-	return;
-
-    PAL_SELECT(radeon_crtc->crtc_id);
-
-    for (i = 0; i < 256; i++) {
-	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
-    }
-}
-
-
-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++) {
-	radeon_crtc->lut_r[i] = red[i] >> 8;
-	radeon_crtc->lut_g[i] = green[i] >> 8;
-	radeon_crtc->lut_b[i] = blue[i] >> 8;
-    }
-
-    radeon_crtc_load_lut(crtc);
-}
-
-static Bool
-radeon_crtc_lock(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr		pScrn = crtc->scrn;
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
-    Bool           CPStarted   = info->CPStarted;
-
-#ifdef XF86DRI
-    if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
 #endif
-
-    if (info->accelOn)
-        RADEON_SYNC(info, pScrn);
-    return FALSE;
-}
-
-static void
-radeon_crtc_unlock(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr		pScrn = crtc->scrn;
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
-
-#ifdef XF86DRI
-	if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
-#endif
-
-    if (info->accelOn)
-        RADEON_SYNC(info, pScrn);
-}
-
-static const xf86CrtcFuncsRec radeon_crtc_funcs = {
-    .dpms = radeon_crtc_dpms,
-    .save = NULL, /* XXX */
-    .restore = NULL, /* XXX */
-    .mode_fixup = radeon_crtc_mode_fixup,
-    .prepare = radeon_crtc_mode_prepare,
-    .mode_set = radeon_crtc_mode_set,
-    .commit = radeon_crtc_mode_commit,
-    .gamma_set = radeon_crtc_gamma_set,
-    .lock = radeon_crtc_lock,
-    .unlock = radeon_crtc_unlock,
-    .set_cursor_colors = radeon_crtc_set_cursor_colors,
-    .set_cursor_position = radeon_crtc_set_cursor_position,
-    .show_cursor = radeon_crtc_show_cursor,
-    .hide_cursor = radeon_crtc_hide_cursor,
-/*    .load_cursor_image = i830_crtc_load_cursor_image, */
-    .load_cursor_argb = radeon_crtc_load_cursor_argb,
-    .destroy = NULL, /* XXX */
-};
-
-static void
-radeon_dpms(xf86OutputPtr output, int mode)
-{
-    ScrnInfoPtr	pScrn = output->scrn;
-
-    switch(mode) {
-    case DPMSModeOn:
-	RADEONEnableDisplay(output, TRUE);
-	/*      RADEONDPMSSetOn(output);*/
-	break;
-    case DPMSModeOff:
-    case DPMSModeSuspend:
-    case DPMSModeStandby:
-	RADEONEnableDisplay(output, FALSE);
-	/*RADEONDPMSSetOff(output);*/
-	break;
-    }
-}
-
-static void
-radeon_save(xf86OutputPtr output)
-{
-
-}
-
-static void
-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;
-
-    if (pMode->HDisplay > radeon_output->PanelXRes ||
-	pMode->VDisplay > radeon_output->PanelYRes)
-	return MODE_PANEL;
-
-    return MODE_OK;
-}
-
-static Bool
-radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
-		    DisplayModePtr adjusted_mode)
-{
-    ScrnInfoPtr	pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    if (radeon_output->type != OUTPUT_LVDS)
-	return TRUE;
-
-    if (mode->HDisplay < radeon_output->PanelXRes ||
-	mode->VDisplay < radeon_output->PanelYRes)
-	adjusted_mode->Flags |= RADEON_USE_RMX;
-
-    if (adjusted_mode->Flags & RADEON_USE_RMX) {
-	adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
-	adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
-	adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-	adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
-	adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
-	adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
-	adjusted_mode->Clock          = radeon_output->DotClock;
-	adjusted_mode->Flags          = radeon_output->Flags | RADEON_USE_RMX;
-	/* save these for Xv with RMX */
-	info->PanelYRes = radeon_output->PanelYRes;
-	info->PanelXRes = radeon_output->PanelXRes;
-    }
-
-    return TRUE;
-}
-
-static void
-radeon_mode_prepare(xf86OutputPtr output)
-{
-}
-
-static void
-radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
-		  DisplayModePtr adjusted_mode)
-{
-    ScrnInfoPtr	    pScrn = output->scrn;
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    switch(radeon_output->MonType) {
-    case MT_LCD:
-    case MT_DFP:
-	ErrorF("restore FP\n");
-	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
-	break;
-    default:
-	ErrorF("restore dac\n");
-	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
-    }
-
-    RADEONEnableDisplay(output, TRUE);
-}
-
-static void
-radeon_mode_commit(xf86OutputPtr output)
-{
-}
-
-static xf86OutputStatus
-radeon_detect(xf86OutputPtr output)
-{
-    ScrnInfoPtr	    pScrn = output->scrn;
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    
-    radeon_output->MonType = MT_UNKNOWN;
-    RADEONConnectorFindMonitor(pScrn, output);
-    if (radeon_output->MonType == MT_UNKNOWN) {
-        output->subpixel_order = SubPixelUnknown;
-	return XF86OutputStatusUnknown;
-    }
-    else if (radeon_output->MonType == MT_NONE) {
-        output->subpixel_order = SubPixelUnknown;
-	return XF86OutputStatusDisconnected;
-    } else {
-
-      switch(radeon_output->MonType) {
-      case MT_LCD:
-      case MT_DFP: output->subpixel_order = SubPixelHorizontalRGB; break;
-      default: output->subpixel_order = SubPixelNone; break;
-      }
-      
-      return XF86OutputStatusConnected;
-    }
-
-}
-
-static DisplayModePtr
-radeon_get_modes(xf86OutputPtr output)
-{
-  DisplayModePtr modes;
-  modes = RADEONProbeOutputModes(output);
-  return modes;
-}
-
-static void
-radeon_destroy (xf86OutputPtr output)
-{
-    if(output->driver_private)
-        xfree(output->driver_private);
-}
-
-static const xf86OutputFuncsRec radeon_output_funcs = {
-    .dpms = radeon_dpms,
-    .save = radeon_save,
-    .restore = radeon_restore,
-    .mode_valid = radeon_mode_valid,
-    .mode_fixup = radeon_mode_fixup,
-    .prepare = radeon_mode_prepare,
-    .mode_set = radeon_mode_set,
-    .commit = radeon_mode_commit,
-    .detect = radeon_detect,
-    .get_modes = radeon_get_modes,
-    .destroy = radeon_destroy
-};
-
-Bool RADEONAllocateControllers(ScrnInfoPtr pScrn)
-{
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-
-    if (pRADEONEnt->Controller[0])
-      return TRUE;
-
-    pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
-    if (!pRADEONEnt->pCrtc[0])
-      return FALSE;
-
-    pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
-    if (!pRADEONEnt->Controller[0])
-        return FALSE;
-
-    pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
-    pRADEONEnt->Controller[0]->crtc_id = 0;
-
-    if (!pRADEONEnt->HasCRTC2)
-	return TRUE;
-
-    pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
-    if (!pRADEONEnt->pCrtc[1])
-      return FALSE;
-
-    pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
-    if (!pRADEONEnt->Controller[1])
-    {
-	xfree(pRADEONEnt->Controller[0]);
-	return FALSE;
-    }
-
-    pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
-    pRADEONEnt->Controller[1]->crtc_id = 1;
-    return TRUE;
-}
-
-void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
-{
-    RADEONInfoPtr info = RADEONPTR (pScrn);
-    RADEONOutputType output;
-    if (info->IsAtomBios) {
-	switch(radeon_output->ConnectorType) {
-	case 0: output = OUTPUT_NONE; break;
-	case 1: output = OUTPUT_VGA; break;
-	case 2:
-	case 3:
-	case 4: output = OUTPUT_DVI; break;
-	case 5: output = OUTPUT_STV; break;
-	case 6: output = OUTPUT_CTV; break;
-	case 7:
-	case 8: output = OUTPUT_LVDS; break;
-	case 9:
-	default:
-	    output = OUTPUT_NONE; break;
-	}
-    }
-    else {
-	switch(radeon_output->ConnectorType) {
-	case 0: output = OUTPUT_NONE; break;
-	case 1: output = OUTPUT_LVDS; break;
-	case 2: output = OUTPUT_VGA; break;
-	case 3:
-	case 4: output = OUTPUT_DVI; break;
-	case 5: output = OUTPUT_STV; break;
-	case 6: output = OUTPUT_CTV; break;
-	default: output = OUTPUT_NONE; break;
-	}
-    }
-    radeon_output->type = output;
-}
-
-void RADEONInitConnector(xf86OutputPtr output)
-{
-    ScrnInfoPtr	    pScrn = output->scrn;
-    RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    int DDCReg = 0;
-    char* name = OutputType[radeon_output->type];
-
-    switch(radeon_output->DDCType) {
-    case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
-    case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
-    case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
-    case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
-    default: break;
-    }
-    
-    if (DDCReg) {
-	radeon_output->DDCReg = DDCReg;
-	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
-    }
-
-    if (radeon_output->type == OUTPUT_LVDS) {
-	RADEONGetLVDSInfo(output);
-    }
-
-    if (radeon_output->type == OUTPUT_DVI) {
-	RADEONGetTMDSInfo(output);
-
-	// FIXME
-	/*if (i == 0)
-	  RADEONGetHardCodedEDIDFromBIOS(output);*/
-
-	/*RADEONUpdatePanelSize(output);*/
-    }
-
-    if (radeon_output->DACType == DAC_TVDAC) {
-	RADEONGetTVDacAdjInfo(output);
-    }
-
-}
-
-/*
- * initialise the static data sos we don't have to re-do at randr change */
-Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    xf86OutputPtr output;
-    const char *s;
-    int i = 0, second = 0, max_mt = 5;
-
-
-    /* We first get the information about all connectors from BIOS.
-     * This is how the card is phyiscally wired up.
-     * The information should be correct even on a OEM card.
-     * If not, we may have problem -- need to use MonitorLayout option.
-     */
-    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
-	info->BiosConnector[i].DACType = DAC_UNKNOWN;
-	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
-	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
-    }
-
-    if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
-        ((info->BiosConnector[0].DDCType == 0) &&
-        (info->BiosConnector[1].DDCType == 0))) {
-	if (info->IsMobility) {
-	    /* Below is the most common setting, but may not be true */
-	    info->BiosConnector[0].DDCType = DDC_LCD;
-	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
-	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
-	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
-
-	    info->BiosConnector[1].DDCType = DDC_VGA;
-	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_EXT;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
-	} else {
-	    /* Below is the most common setting, but may not be true */
-	    info->BiosConnector[0].DDCType = DDC_DVI;
-	    info->BiosConnector[0].DACType = DAC_TVDAC;
-	    info->BiosConnector[0].TMDSType = TMDS_INT;
-	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
-
-	    info->BiosConnector[1].DDCType = DDC_VGA;
-	    info->BiosConnector[1].DACType = DAC_PRIMARY;
-	    info->BiosConnector[1].TMDSType = TMDS_EXT;
-	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
-	}
-
-       /* Some cards have the DDC lines swapped and we have no way to
-        * detect it yet (Mac cards)
-        */
-       if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-           info->BiosConnector[0].DDCType = DDC_VGA;
-           info->BiosConnector[1].DDCType = DDC_DVI;
-        }
-    }
-
-    /* always make TMDS_INT port first*/
-    if (info->BiosConnector[1].TMDSType == TMDS_INT) {
-	RADEONSwapOutputs(pScrn);
-    } else if ((info->BiosConnector[0].TMDSType != TMDS_INT &&
-                info->BiosConnector[1].TMDSType != TMDS_INT)) {
-        /* no TMDS_INT port, make primary DAC port first */
-	/* On my Inspiron 8600 both internal and external ports are
-	   marked DAC_PRIMARY in BIOS. So be extra careful - only
-	   swap when the first port is not DAC_PRIMARY */
-        if ((!(info->BiosConnector[0].ConnectorType == CONNECTOR_PROPRIETARY)) &&  (info->BiosConnector[1].DACType == DAC_PRIMARY) &&
-	     (info->BiosConnector[0].DACType != DAC_PRIMARY)) {
-	    RADEONSwapOutputs(pScrn);
-        }
-    }
-
-    if (info->HasSingleDAC) {
-        /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
-        if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
-            info->BiosConnector[0].DACType = DAC_TVDAC;
-            info->BiosConnector[1].DACType = DAC_PRIMARY;
-        } else {
-            info->BiosConnector[1].DACType = DAC_TVDAC;
-            info->BiosConnector[0].DACType = DAC_PRIMARY;
-        }
-    } else if (!pRADEONEnt->HasCRTC2) {
-        info->BiosConnector[0].DACType = DAC_PRIMARY;
-    }
-
-    for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
-	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-	if (!radeon_output) {
-	    return FALSE;
-	}
-	radeon_output->MonType = MT_UNKNOWN;
-	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
-	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
-	    radeon_output->ConnectorType == CONNECTOR_DVI_D)
-	    radeon_output->DACType = DAC_UNKNOWN;
-	else
-	    radeon_output->DACType = info->BiosConnector[i].DACType;
-	radeon_output->DDCType = info->BiosConnector[i].DDCType;
-	radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
-
-	RADEONSetOutputType(pScrn, radeon_output);
-	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-	if (!output) {
-	    return FALSE;
-	}
-	output->driver_private = radeon_output;
-	output->possible_crtcs = 1;
-	if (radeon_output->type != OUTPUT_LVDS)
- 	    output->possible_crtcs |= 2;
-
-	output->possible_clones = 0 /*1|2*/;
-
-	RADEONInitConnector(output);
-    }
-
-    /* if it's a mobility make sure we have a LVDS port */
-    if (info->IsMobility) {
-	if (info->IsAtomBios) {
-	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_LVDS_ATOM &&
-		info->BiosConnector[1].ConnectorType != CONNECTOR_LVDS_ATOM) {
-		/* add LVDS port */
-		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-		if (!radeon_output) {
-		    return FALSE;
-		}
-		radeon_output->MonType = MT_UNKNOWN;
-		radeon_output->DDCType = DDC_LCD;
-		radeon_output->DACType = DAC_UNKNOWN;
-		radeon_output->TMDSType = TMDS_UNKNOWN;
-		radeon_output->ConnectorType = CONNECTOR_LVDS_ATOM;
-		RADEONSetOutputType(pScrn, radeon_output);
-		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-		if (!output) {
-		    return FALSE;
-		}
-		output->driver_private = radeon_output;
-		output->possible_crtcs = 1;
-		output->possible_clones = 0 /*1|2*/;
-
-		RADEONInitConnector(output);
-
-	    }
-	} else {
-	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_PROPRIETARY &&
-		info->BiosConnector[1].ConnectorType != CONNECTOR_PROPRIETARY) {
-		/* add LVDS port */
-		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-		if (!radeon_output) {
-		    return FALSE;
-		}
-		radeon_output->MonType = MT_UNKNOWN;
-		radeon_output->DDCType = DDC_LCD;
-		radeon_output->DACType = DAC_UNKNOWN;
-		radeon_output->TMDSType = TMDS_UNKNOWN;
-		radeon_output->ConnectorType = CONNECTOR_PROPRIETARY;
-		RADEONSetOutputType(pScrn, radeon_output);
-		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
-		if (!output) {
-		    return FALSE;
-		}
-		output->driver_private = radeon_output;
-		output->possible_crtcs = 1;
-		output->possible_clones = 0 /*1|2*/;
-
-		RADEONInitConnector(output);
-	    }
-	}
-    }
-    return TRUE;
-}
-
-/**
- * In the current world order, there are lists of modes per output, which may
- * or may not include the mode that was asked to be set by XFree86's mode
- * selection.  Find the closest one, in the following preference order:
- *
- * - Equality
- * - Closer in size to the requested mode, but no larger
- * - Closer in refresh rate to the requested mode.
- */
-DisplayModePtr
-RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
-{
-    ScrnInfoPtr	pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    DisplayModePtr pBest = NULL, pScan = NULL;
-    int i;
-
-    /* Assume that there's only one output connected to the given CRTC. */
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr  output = xf86_config->output[i];
-	if (output->crtc == crtc && output->probed_modes != NULL)
-	{
-	    pScan = output->probed_modes;
-	    break;
-	}
-    }
-
-    /* If the pipe doesn't have any detected modes, just let the system try to
-     * spam the desired mode in.
-     */
-    if (pScan == NULL) {
-	RADEONCrtcPrivatePtr  radeon_crtc = crtc->driver_private;
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "No crtc mode list for crtc %d,"
-		   "continuing with desired mode\n", radeon_crtc->crtc_id);
-	return pMode;
-    }
-
-    for (; pScan != NULL; pScan = pScan->next) {
-	assert(pScan->VRefresh != 0.0);
-
-	/* If there's an exact match, we're done. */
-	if (xf86ModesEqual(pScan, pMode)) {
-	    pBest = pMode;
-	    break;
-	}
-
-	/* Reject if it's larger than the desired mode. */
-	if (pScan->HDisplay > pMode->HDisplay ||
-	    pScan->VDisplay > pMode->VDisplay)
-	{
-	    continue;
-	}
-
-	if (pBest == NULL) {
-	    pBest = pScan;
-	    continue;
-	}
-
-	/* Find if it's closer to the right size than the current best
-	 * option.
-	 */
-	if ((pScan->HDisplay > pBest->HDisplay &&
-	     pScan->VDisplay >= pBest->VDisplay) ||
-	    (pScan->HDisplay >= pBest->HDisplay &&
-	     pScan->VDisplay > pBest->VDisplay))
-	{
-	    pBest = pScan;
-	    continue;
-	}
-
-	/* Find if it's still closer to the right refresh than the current
-	 * best resolution.
-	 */
-	if (pScan->HDisplay == pBest->HDisplay &&
-	    pScan->VDisplay == pBest->VDisplay &&
-	    (fabs(pScan->VRefresh - pMode->VRefresh) <
-	     fabs(pBest->VRefresh - pMode->VRefresh))) {
-	    pBest = pScan;
-	}
-    }
-
-    if (pBest == NULL) {
-	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "No suitable mode found to program for the pipe.\n"
-		   "	continuing with desired mode %dx%d@%.1f\n",
-		   pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
-    } else if (!xf86ModesEqual(pBest, pMode)) {
-      RADEONCrtcPrivatePtr  radeon_crtc = crtc->driver_private;
-      int		    crtc = radeon_crtc->crtc_id;
-      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		   "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 "
-		   "mode %dx%d@%.1f\n", crtc,
-		   pBest->HDisplay, pBest->VDisplay, pBest->VRefresh,
-		   pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
-	pMode = pBest;
-    }
-    return pMode;
-}
-
-void
-RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
-{
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int c;
-    int highx = 0, highy = 0;
-    int crtc_num;
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-    {
-        xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-	if (!crtc->enabled)
-	    continue;
-
-	if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y))
-	    crtc_num = c;
-    }
-
-    if (crtc_num == 1)
-        info->OverlayOnCRTC2 = TRUE;
-    else
-        info->OverlayOnCRTC2 = FALSE;
-}
diff --git a/src/radeon_output.c b/src/radeon_output.c
new file mode 100644
index 0000000..18ef16d
--- /dev/null
+++ b/src/radeon_output.c
@@ -0,0 +1,641 @@
+/*
+ * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
+ *                VA Linux Systems Inc., Fremont, California.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "fbdevhw.h"
+#include "vgaHW.h"
+#include "xf86Modes.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+
+
+const char *MonTypeName[7] = {
+  "AUTO",
+  "NONE",
+  "CRT",
+  "LVDS",
+  "TMDS",
+  "CTV",
+  "STV"
+};
+
+const RADEONMonitorType MonTypeID[7] = {
+  MT_UNKNOWN, /* this is just a dummy value for AUTO DETECTION */
+  MT_NONE,    /* NONE -> NONE */
+  MT_CRT,     /* CRT -> CRT */
+  MT_LCD,     /* Laptop LCDs are driven via LVDS port */
+  MT_DFP,     /* DFPs are driven via TMDS */
+  MT_CTV,     /* CTV -> CTV */
+  MT_STV,     /* STV -> STV */
+};
+
+const char *TMDSTypeName[3] = {
+  "NONE",
+  "Internal",
+  "External"
+};
+
+const char *DDCTypeName[6] = {
+  "NONE",
+  "MONID",
+  "DVI_DDC",
+  "VGA_DDC",
+  "CRT2_DDC",
+  "LCD_DDC"
+};
+
+const char *DACTypeName[3] = {
+  "Unknown",
+  "Primary",
+  "TVDAC/ExtDAC",
+};
+
+const char *ConnectorTypeName[8] = {
+  "None",
+  "Proprietary",
+  "VGA",
+  "DVI-I",
+  "DVI-D",
+  "CTV",
+  "STV",
+  "Unsupported"
+};
+
+const char *ConnectorTypeNameATOM[10] = {
+  "None",
+  "VGA",
+  "DVI-I",
+  "DVI-D",
+  "DVI-A",
+  "STV",
+  "CTV",
+  "LVDS",
+  "Digital",
+  "Unsupported"
+};
+
+const char *OutputType[10] = {
+    "None",
+    "VGA",
+    "DVI",
+    "LVDS",
+    "S-video",
+    "Composite",
+};
+
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output);
+
+Bool RADEONMapControllers(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;
+    int o;
+
+    pRADEONEnt->Controller[0]->binding = 1;
+    pRADEONEnt->Controller[1]->binding = 1;
+
+    for (o = 0; o < xf86_config->num_output; o++) {
+      output = xf86_config->output[o];
+      radeon_output = output->driver_private;
+
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
+		 "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
+	  o,
+	  MonTypeName[radeon_output->MonType+1],
+	  info->IsAtomBios ? 
+	  ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+	  ConnectorTypeName[radeon_output->ConnectorType],
+	  DACTypeName[radeon_output->DACType+1],
+	  TMDSTypeName[radeon_output->TMDSType+1],
+	  DDCTypeName[radeon_output->DDCType]);
+
+    }
+
+    return TRUE;
+}
+
+/* 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) {
+      if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output)));
+      else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
+      else if (radeon_output->DACType == DAC_PRIMARY) 
+	  radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
+    }
+
+    if (output->MonInfo) {
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
+		 info->IsAtomBios ?
+		 ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+		 ConnectorTypeName[radeon_output->ConnectorType]
+		 );
+      xf86PrintEDID( output->MonInfo );
+    }
+}
+
+static void RADEONSwapOutputs(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONBIOSConnector tmp;
+    
+    tmp = info->BiosConnector[0];
+    info->BiosConnector[0] = info->BiosConnector[1];
+    info->BiosConnector[1] = tmp;
+    
+}
+
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONMonitorType MonType = MT_NONE;
+
+
+    if (info->IsMobility) {
+        if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
+	     radeon_output->ConnectorType == CONNECTOR_PROPRIETARY) {
+	     if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
+	         MonType =  MT_LCD;
+        }
+	/* non-DDC TMDS panel connected through DVO */
+	if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_ON)
+	  MonType = MT_DFP;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Detected Monitor Type: %d\n", MonType);
+
+    return MonType;
+
+}
+
+static void
+radeon_dpms(xf86OutputPtr output, int mode)
+{
+    ScrnInfoPtr	pScrn = output->scrn;
+
+    switch(mode) {
+    case DPMSModeOn:
+	RADEONEnableDisplay(output, TRUE);
+	/*      RADEONDPMSSetOn(output);*/
+	break;
+    case DPMSModeOff:
+    case DPMSModeSuspend:
+    case DPMSModeStandby:
+	RADEONEnableDisplay(output, FALSE);
+	/*RADEONDPMSSetOff(output);*/
+	break;
+    }
+}
+
+static void
+radeon_save(xf86OutputPtr output)
+{
+
+}
+
+static void
+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;
+
+    if (pMode->HDisplay > radeon_output->PanelXRes ||
+	pMode->VDisplay > radeon_output->PanelYRes)
+	return MODE_PANEL;
+
+    return MODE_OK;
+}
+
+static Bool
+radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+		    DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr	pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (radeon_output->type != OUTPUT_LVDS)
+	return TRUE;
+
+    if (mode->HDisplay < radeon_output->PanelXRes ||
+	mode->VDisplay < radeon_output->PanelYRes)
+	adjusted_mode->Flags |= RADEON_USE_RMX;
+
+    if (adjusted_mode->Flags & RADEON_USE_RMX) {
+	adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
+	adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
+	adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+	adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
+	adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
+	adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+	adjusted_mode->Clock          = radeon_output->DotClock;
+	adjusted_mode->Flags          = radeon_output->Flags | RADEON_USE_RMX;
+	/* save these for Xv with RMX */
+	info->PanelYRes = radeon_output->PanelYRes;
+	info->PanelXRes = radeon_output->PanelXRes;
+    }
+
+    return TRUE;
+}
+
+static void
+radeon_mode_prepare(xf86OutputPtr output)
+{
+}
+
+static void
+radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+		  DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    switch(radeon_output->MonType) {
+    case MT_LCD:
+    case MT_DFP:
+	ErrorF("restore FP\n");
+	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+	break;
+    default:
+	ErrorF("restore dac\n");
+	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+    }
+
+    RADEONEnableDisplay(output, TRUE);
+}
+
+static void
+radeon_mode_commit(xf86OutputPtr output)
+{
+}
+
+static xf86OutputStatus
+radeon_detect(xf86OutputPtr output)
+{
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    
+    radeon_output->MonType = MT_UNKNOWN;
+    RADEONConnectorFindMonitor(pScrn, output);
+    if (radeon_output->MonType == MT_UNKNOWN) {
+        output->subpixel_order = SubPixelUnknown;
+	return XF86OutputStatusUnknown;
+    }
+    else if (radeon_output->MonType == MT_NONE) {
+        output->subpixel_order = SubPixelUnknown;
+	return XF86OutputStatusDisconnected;
+    } else {
+
+      switch(radeon_output->MonType) {
+      case MT_LCD:
+      case MT_DFP: output->subpixel_order = SubPixelHorizontalRGB; break;
+      default: output->subpixel_order = SubPixelNone; break;
+      }
+      
+      return XF86OutputStatusConnected;
+    }
+
+}
+
+static DisplayModePtr
+radeon_get_modes(xf86OutputPtr output)
+{
+  DisplayModePtr modes;
+  modes = RADEONProbeOutputModes(output);
+  return modes;
+}
+
+static void
+radeon_destroy (xf86OutputPtr output)
+{
+    if(output->driver_private)
+        xfree(output->driver_private);
+}
+
+static const xf86OutputFuncsRec radeon_output_funcs = {
+    .dpms = radeon_dpms,
+    .save = radeon_save,
+    .restore = radeon_restore,
+    .mode_valid = radeon_mode_valid,
+    .mode_fixup = radeon_mode_fixup,
+    .prepare = radeon_mode_prepare,
+    .mode_set = radeon_mode_set,
+    .commit = radeon_mode_commit,
+    .detect = radeon_detect,
+    .get_modes = radeon_get_modes,
+    .destroy = radeon_destroy
+};
+
+void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    RADEONOutputType output;
+    if (info->IsAtomBios) {
+	switch(radeon_output->ConnectorType) {
+	case 0: output = OUTPUT_NONE; break;
+	case 1: output = OUTPUT_VGA; break;
+	case 2:
+	case 3:
+	case 4: output = OUTPUT_DVI; break;
+	case 5: output = OUTPUT_STV; break;
+	case 6: output = OUTPUT_CTV; break;
+	case 7:
+	case 8: output = OUTPUT_LVDS; break;
+	case 9:
+	default:
+	    output = OUTPUT_NONE; break;
+	}
+    }
+    else {
+	switch(radeon_output->ConnectorType) {
+	case 0: output = OUTPUT_NONE; break;
+	case 1: output = OUTPUT_LVDS; break;
+	case 2: output = OUTPUT_VGA; break;
+	case 3:
+	case 4: output = OUTPUT_DVI; break;
+	case 5: output = OUTPUT_STV; break;
+	case 6: output = OUTPUT_CTV; break;
+	default: output = OUTPUT_NONE; break;
+	}
+    }
+    radeon_output->type = output;
+}
+
+void RADEONInitConnector(xf86OutputPtr output)
+{
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int DDCReg = 0;
+    char* name = OutputType[radeon_output->type];
+
+    switch(radeon_output->DDCType) {
+    case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+    case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
+    case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
+    case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+    default: break;
+    }
+    
+    if (DDCReg) {
+	radeon_output->DDCReg = DDCReg;
+	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
+    }
+
+    if (radeon_output->type == OUTPUT_LVDS) {
+	RADEONGetLVDSInfo(output);
+    }
+
+    if (radeon_output->type == OUTPUT_DVI) {
+	RADEONGetTMDSInfo(output);
+
+	// FIXME
+	/*if (i == 0)
+	  RADEONGetHardCodedEDIDFromBIOS(output);*/
+
+	/*RADEONUpdatePanelSize(output);*/
+    }
+
+    if (radeon_output->DACType == DAC_TVDAC) {
+	RADEONGetTVDacAdjInfo(output);
+    }
+
+}
+
+/*
+ * initialise the static data sos we don't have to re-do at randr change */
+Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    xf86OutputPtr output;
+    const char *s;
+    int i = 0, second = 0, max_mt = 5;
+
+
+    /* We first get the information about all connectors from BIOS.
+     * This is how the card is phyiscally wired up.
+     * The information should be correct even on a OEM card.
+     * If not, we may have problem -- need to use MonitorLayout option.
+     */
+    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[i].DACType = DAC_UNKNOWN;
+	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
+    }
+
+    if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
+        ((info->BiosConnector[0].DDCType == 0) &&
+        (info->BiosConnector[1].DDCType == 0))) {
+	if (info->IsMobility) {
+	    /* Below is the most common setting, but may not be true */
+	    info->BiosConnector[0].DDCType = DDC_LCD;
+	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
+	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+
+	    info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].DACType = DAC_PRIMARY;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	} else {
+	    /* Below is the most common setting, but may not be true */
+	    info->BiosConnector[0].DDCType = DDC_DVI;
+	    info->BiosConnector[0].DACType = DAC_TVDAC;
+	    info->BiosConnector[0].TMDSType = TMDS_INT;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
+
+	    info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].DACType = DAC_PRIMARY;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	}
+
+       /* Some cards have the DDC lines swapped and we have no way to
+        * detect it yet (Mac cards)
+        */
+       if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
+           info->BiosConnector[0].DDCType = DDC_VGA;
+           info->BiosConnector[1].DDCType = DDC_DVI;
+        }
+    }
+
+    /* always make TMDS_INT port first*/
+    if (info->BiosConnector[1].TMDSType == TMDS_INT) {
+	RADEONSwapOutputs(pScrn);
+    } else if ((info->BiosConnector[0].TMDSType != TMDS_INT &&
+                info->BiosConnector[1].TMDSType != TMDS_INT)) {
+        /* no TMDS_INT port, make primary DAC port first */
+	/* On my Inspiron 8600 both internal and external ports are
+	   marked DAC_PRIMARY in BIOS. So be extra careful - only
+	   swap when the first port is not DAC_PRIMARY */
+        if ((!(info->BiosConnector[0].ConnectorType == CONNECTOR_PROPRIETARY)) &&  (info->BiosConnector[1].DACType == DAC_PRIMARY) &&
+	     (info->BiosConnector[0].DACType != DAC_PRIMARY)) {
+	    RADEONSwapOutputs(pScrn);
+        }
+    }
+
+    if (info->HasSingleDAC) {
+        /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
+        if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
+            info->BiosConnector[0].DACType = DAC_TVDAC;
+            info->BiosConnector[1].DACType = DAC_PRIMARY;
+        } else {
+            info->BiosConnector[1].DACType = DAC_TVDAC;
+            info->BiosConnector[0].DACType = DAC_PRIMARY;
+        }
+    } else if (!pRADEONEnt->HasCRTC2) {
+        info->BiosConnector[0].DACType = DAC_PRIMARY;
+    }
+
+    for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+	if (!radeon_output) {
+	    return FALSE;
+	}
+	radeon_output->MonType = MT_UNKNOWN;
+	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
+	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+	    radeon_output->ConnectorType == CONNECTOR_DVI_D)
+	    radeon_output->DACType = DAC_UNKNOWN;
+	else
+	    radeon_output->DACType = info->BiosConnector[i].DACType;
+	radeon_output->DDCType = info->BiosConnector[i].DDCType;
+	radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+
+	RADEONSetOutputType(pScrn, radeon_output);
+	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	if (!output) {
+	    return FALSE;
+	}
+	output->driver_private = radeon_output;
+	output->possible_crtcs = 1;
+	if (radeon_output->type != OUTPUT_LVDS)
+ 	    output->possible_crtcs |= 2;
+
+	output->possible_clones = 0 /*1|2*/;
+
+	RADEONInitConnector(output);
+    }
+
+    /* if it's a mobility make sure we have a LVDS port */
+    if (info->IsMobility) {
+	if (info->IsAtomBios) {
+	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_LVDS_ATOM &&
+		info->BiosConnector[1].ConnectorType != CONNECTOR_LVDS_ATOM) {
+		/* add LVDS port */
+		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+		if (!radeon_output) {
+		    return FALSE;
+		}
+		radeon_output->MonType = MT_UNKNOWN;
+		radeon_output->DDCType = DDC_LCD;
+		radeon_output->DACType = DAC_UNKNOWN;
+		radeon_output->TMDSType = TMDS_UNKNOWN;
+		radeon_output->ConnectorType = CONNECTOR_LVDS_ATOM;
+		RADEONSetOutputType(pScrn, radeon_output);
+		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+		if (!output) {
+		    return FALSE;
+		}
+		output->driver_private = radeon_output;
+		output->possible_crtcs = 1;
+		output->possible_clones = 0 /*1|2*/;
+
+		RADEONInitConnector(output);
+
+	    }
+	} else {
+	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_PROPRIETARY &&
+		info->BiosConnector[1].ConnectorType != CONNECTOR_PROPRIETARY) {
+		/* add LVDS port */
+		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+		if (!radeon_output) {
+		    return FALSE;
+		}
+		radeon_output->MonType = MT_UNKNOWN;
+		radeon_output->DDCType = DDC_LCD;
+		radeon_output->DACType = DAC_UNKNOWN;
+		radeon_output->TMDSType = TMDS_UNKNOWN;
+		radeon_output->ConnectorType = CONNECTOR_PROPRIETARY;
+		RADEONSetOutputType(pScrn, radeon_output);
+		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+		if (!output) {
+		    return FALSE;
+		}
+		output->driver_private = radeon_output;
+		output->possible_crtcs = 1;
+		output->possible_clones = 0 /*1|2*/;
+
+		RADEONInitConnector(output);
+	    }
+	}
+    }
+    return TRUE;
+}
+
diff-tree 58ce388452b7bc790c438d75c9cf4a0f69f0d7b2 (from 66e8e6c8348d007930730e90295588efe8108844)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 15:05:01 2007 -0400

    RADEON: Remove dead code

diff --git a/src/radeon_display.c b/src/radeon_display.c
index cafcb0e..7ec6c6b 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -894,22 +894,6 @@ static void RADEONGetTMDSInfo(xf86Output
     }
 }
 
-#if 0
-void RADEONGetPanelInfo (ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info     = RADEONPTR(pScrn);
-    char* s;
-
-    if((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
-        info->PanelPwrDly = 200;
-        if (sscanf (s, "%dx%d", &info->PanelXRes, &info->PanelYRes) != 2) {
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
-            RADEONGetPanelInfoFromReg(output);
-        }
-    } 
-}
-#endif
-
 void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
 {
     ScrnInfoPtr pScrn = output->scrn;
@@ -987,105 +971,6 @@ void RADEONConnectorFindMonitor(ScrnInfo
     }
 }
 
-#if 0
-void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn)
-{
-
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    const char *s;
-    Bool ignore_edid = FALSE;
-
-    /* IgnoreEDID option is different from the NoDDCxx options used by DDC module
-     * When IgnoreEDID is used, monitor detection will still use DDC
-     * detection, but all EDID data will not be used in mode validation.
-     * You can use this option when you have a DDC monitor but want specify your own
-     * monitor timing parameters by using HSync, VRefresh and Modeline,
-     */
-    if (xf86GetOptValBool(info->Options, OPTION_IGNORE_EDID, &ignore_edid)) {
-        if (ignore_edid)
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "IgnoreEDID is specified, EDID data will be ignored\n");
-    }
-
-    if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
-        if (!ignore_edid) {
-            if ((pRADEONEnt->PortInfo[0]->MonType > MT_NONE) &&
-                (pRADEONEnt->PortInfo[0]->MonType < MT_STV))
-		RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[0]->DDCType,
-					  pRADEONEnt->pOutput[0]);
-            if ((pRADEONEnt->PortInfo[1]->MonType > MT_NONE) &&
-                (pRADEONEnt->PortInfo[1]->MonType < MT_STV))
-		RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[1]->DDCType,
-					  pRADEONEnt->pOutput[1]);
-        }
-    }
-    else {
-      /* force monitor redetection */
-      pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
-      pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
-    }
-      
-    
-    if (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN || pRADEONEnt->PortInfo[1]->MonType == MT_UNKNOWN) {
-	
-        if ((!pRADEONEnt->HasCRTC2) && (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN)) {
-	    if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI,
-									     pRADEONEnt->pOutput[0])));
-	    else if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_VGA,
-										  pRADEONEnt->pOutput[0])));
-	    else if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_CRT2,
-										  pRADEONEnt->pOutput[0])));
-	    else
-		pRADEONEnt->PortInfo[0]->MonType = MT_CRT;
-	    
-	    if (!ignore_edid) {
-		if (pRADEONEnt->pOutput[0]->MonInfo) {
-		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n");
-		    xf86PrintEDID(pRADEONEnt->pOutput[0]->MonInfo );
-		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n");
-		}
-	    }
-	    
-	    pRADEONEnt->PortInfo[1]->MonType = MT_NONE;
-	    pRADEONEnt->pOutput[1]->MonInfo = NULL;
-	    pRADEONEnt->PortInfo[1]->DDCType = DDC_NONE_DETECTED;
-	    pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN;
-	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
-	    pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_NONE;
-	    
-	    pRADEONEnt->PortInfo[0]->crtc_num = 1;
-	    pRADEONEnt->PortInfo[1]->crtc_num = 2;
-	    
-	    return;
-	}
-	
-	RADEONConnectorFindMonitor(pScrn, pRADEONEnt->pOutput[0]);
-	RADEONConnectorFindMonitor(pScrn, pRADEONEnt->pOutput[1]);
-	
-    }
-
-    if(ignore_edid) {
-        pRADEONEnt->pOutput[0]->MonInfo = NULL;
-        pRADEONEnt->pOutput[1]->MonInfo = NULL;
-    } else {
-        if (pRADEONEnt->pOutput[0]->MonInfo) {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 1st port ----------------------\n");
-            xf86PrintEDID( pRADEONEnt->pOutput[0]->MonInfo );
-        }
-
-        if (pRADEONEnt->pOutput[1]->MonInfo) {
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 2nd port -----------------------\n");
-            xf86PrintEDID( pRADEONEnt->pOutput[1]->MonInfo );
-        }
-    }
-    
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "\n");
-
-    return;
-}
-#endif
-
 Bool RADEONMapControllers(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
@@ -1116,115 +1001,6 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 
     }
 
-#if 0
-    if (!info->IsSecondary) {
-      pRADEONEnt->PortInfo[0]->crtc_num = 1;
-      pRADEONEnt->PortInfo[1]->crtc_num = 2;
-
-
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		 "Port2:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
-		 MonTypeName[pRADEONEnt->PortInfo[1]->MonType+1], 
-		 info->IsAtomBios ? 
-		 ConnectorTypeNameATOM[pRADEONEnt->PortInfo[1]->ConnectorType]:
-		 ConnectorTypeName[pRADEONEnt->PortInfo[1]->ConnectorType],
-		 DACTypeName[pRADEONEnt->PortInfo[1]->DACType+1],
-		 TMDSTypeName[pRADEONEnt->PortInfo[1]->TMDSType+1],
-		 		 DDCTypeName[pRADEONEnt->PortInfo[1]->DDCType]);
-
-	/* no display detected on primary port*/
-	if (pRADEONEnt->PortInfo[0]->MonType == MT_NONE) {
-	    if (pRADEONEnt->PortInfo[1]->MonType != MT_NONE) {
-		/* Only one detected on secondary, let it to be primary */
-		pRADEONEnt->PortInfo[0]->crtc_num = 2;
-		pRADEONEnt->PortInfo[1]->crtc_num = 1;
-		head_reversed = TRUE;
-	    } else {
-		/* None detected, Default to a CRT connected */
-		pRADEONEnt->PortInfo[0]->MonType = MT_CRT;
-	    }
-	}
-
-	if ((pRADEONEnt->PortInfo[0]->MonType == MT_LCD) &&
-	    (pRADEONEnt->PortInfo[1]->MonType == MT_CRT)) {
-	    if (!(INREG(RADEON_LVDS_GEN_CNTL) & RADEON_LVDS_ON)) {
-		/* LCD is switched off, don't turn it on, otherwise it may casue lockup due to SS issue. */
-		pRADEONEnt->PortInfo[0]->crtc_num = 2;
-		pRADEONEnt->PortInfo[1]->crtc_num = 1;
-		pRADEONEnt->PortInfo[0]->MonType = MT_NONE;
-		head_reversed = TRUE;
-		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "LCD is switched off, only CRT will be used\n");
-	    }
-	}
-
-	if ((pRADEONEnt->PortInfo[0]->MonType != MT_NONE) &&
-	    (pRADEONEnt->PortInfo[1]->MonType != MT_NONE)) {
-	  if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DISPLAY, FALSE)) {
-		if (info->IsMobility) {
-		    /* Don't reverse display for mobility chips, as only CRTC1 path has RMX which
-		       will be required by many LCD panels
-		    */
-		    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Reverse Display cannot be used for mobility chip\n");
-		} else {
-		    pRADEONEnt->PortInfo[0]->crtc_num = 2;
-		    pRADEONEnt->PortInfo[1]->crtc_num = 1;
-		    head_reversed = TRUE;
-		    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Primary and Secondary mapping is reversed\n");
-		}
-	    }
-	}
-
-	if (pRADEONEnt->HasSecondary && pRADEONEnt->PortInfo[1]->MonType == MT_NONE) {
-	    pRADEONEnt->HasSecondary = FALSE;
-	}
-    }
-
-    if(pRADEONEnt->HasCRTC2) {
-	if(info->IsSecondary) {
-	    output = RADEONGetCrtcConnector(pScrn, 2);
-	    radeon_output = output->driver_private;
-  	    pRADEONEnt->Controller[1]->binding = 2;
-	    if (output) {
-		pScrn->monitor->DDC = output->MonInfo;
-	    }
-	} else {
-	    output = RADEONGetCrtcConnector(pScrn, 1);
-	    radeon_output = output->driver_private;
-  	    pRADEONEnt->Controller[0]->binding = 1;
-	    if (output) {
-		pScrn->monitor->DDC = output->MonInfo;
-	    }
-	}
-	
-	if(!pRADEONEnt->HasSecondary) {
-	  pRADEONEnt->Controller[1]->binding = 1;
-	} 
-    } else {
-	output = RADEONGetCrtcConnector(pScrn, 1);
-	radeon_output = output->driver_private;
-	if (output) {
-	    if (radeon_output->MonType == MT_NONE) 
-		radeon_output->MonType = MT_CRT;
-	    pScrn->monitor->DDC = output->MonInfo;
-	}
-	output = RADEONGetCrtcConnector(pScrn, 2);
-	radeon_output = output->driver_private;
-	if (output)
-	    radeon_output->MonType = MT_NONE;
-	pRADEONEnt->Controller[1]->binding = 1;
-    }
-
-    if (!info->IsSecondary) {
-	output = RADEONGetCrtcConnector(pScrn, 2);
-	radeon_output = output->driver_private;
-        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head:   Port%d ---- \n", head_reversed?2:1);
-	if (radeon_output->MonType != MT_NONE)
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2);
- 	else
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
-    }
-#endif
-
     return TRUE;
 }
 
@@ -2403,36 +2179,6 @@ Bool RADEONAllocateControllers(ScrnInfoP
     return TRUE;
 }
 
-#if 0
-Bool RADEONAllocatePortInfo(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr      info = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    int num_connectors;
-    int i;
-
-    if (pRADEONEnt->PortInfo[0])
-	return TRUE;
-
-    /* when we support TV, this should be incremented */
-    if (info->IsMobility) {
-      /* DVI on docks */
-      info->max_connectors = 3;
-    } else {
-      info->max_connectors = 2;
-    }
-
-    /* for now always allocate max connectors */
-    for (i = 0 ; i < info->max_connectors; i++) {
-
-	pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-	if (!pRADEONEnt->PortInfo[i])
-	    return FALSE;
-    }
-    return TRUE;
-}
-#endif
-
 void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
@@ -2594,137 +2340,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     } else if (!pRADEONEnt->HasCRTC2) {
         info->BiosConnector[0].DACType = DAC_PRIMARY;
     }
-#if 0
-    /*
-     * MonitorLayout option takes a string for two monitors connected in following format:
-     * Option "MonitorLayout" "primary-port-display, secondary-port-display"
-     * primary and secondary port displays can have one of following:
-     *    NONE, CRT, LVDS, TMDS
-     * With this option, driver will bring up monitors as specified,
-     * not using auto-detection routines to probe monitors.
-     *
-     * This option can be used when the false monitor detection occurs.
-     *
-     * This option can also be used to disable one connected display.
-     * For example, if you have a laptop connected to an external CRT
-     * and you want to disable the internal LCD panel, you can specify
-     * Option "MonitorLayout" "NONE, CRT"
-     *
-     * This option can also used to disable Clone mode. One there is only
-     * one monitor is specified, clone mode will be turned off automatically
-     * even you have two monitors connected.
-     *
-     * Another usage of this option is you want to config the server
-     * to start up with a certain monitor arrangement even one monitor
-     * is not plugged in when server starts.
-     * For example, you can config your laptop with 
-     * Option "MonitorLayout" "LVDS, CRT"
-     * Option "CloneHSync" "40-150"
-     * Option "CloneVRefresh" "60-120"
-     * With these options, you can connect in your CRT monitor later
-     * after the X server has started.
-     */
-    if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
-        char s1[5], s2[5];
-        i = 0;
-        /* When using user specified monitor types, we will not do DDC detection
-         *
-         */
-        do {
-            switch(*s) {
-            case ',':
-                s1[i] = '\0';
-                i = 0;
-                second = 1;
-                break;
-            case ' ':
-            case '\t':
-            case '\n':
-            case '\r':
-                break;
-            default:
-                if (second)
-                    s2[i] = *s;
-                else
-                    s1[i] = *s;
-                i++;
-                break;
-            }
-            if (i > 4) i = 4;
-        } while(*s++);
-        s2[i] = '\0';
-
-        for (i = 0; i < max_mt; i++)
-        {
-            if (strcmp(s1, MonTypeName[i]) == 0) 
-            {
-                pRADEONEnt->PortInfo[0]->MonType = MonTypeID[i];
-                break;
-            }
-        }
-        if (i ==  max_mt)
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-                       "Invalid Monitor type specified for 1st port \n"); 
-
-        for (i = 0; i < max_mt; i++)
-        {
-            if (strcmp(s2, MonTypeName[i]) == 0) 
-            {
-                pRADEONEnt->PortInfo[1]->MonType = MonTypeID[i];
-                break;
-            }
-
-        }
-        if (i ==  max_mt)
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-                       "Invalid Monitor type specified for 2nd port \n"); 
-
-	if (i ==  max_mt)
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Invalid Monitor type specified for 2nd port \n");
-
-	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-		   "MonitorLayout Option: \n\tMonitor1--Type %s, Monitor2--Type %s\n\n", s1, s2);
-#if 0
-	if (pRADEONEnt->PortInfo[1]->MonType == MT_CRT) {
-	    pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
-	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
-	    pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
-	    pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
-	    pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	    pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
-	    pRADEONEnt->PortInfo[0]->ConnectorType = pRADEONEnt->PortInfo[0]->MonType+1;
-	    pRADEONEnt->PortInfo[0]->MonInfo = NULL;
-        }
-#endif
-
-        /* some thinkpads and powerbooks use lvds and internal tmds 
-	 * at the same time.  --AGD
-	 */
-	if ((pRADEONEnt->PortInfo[0]->MonType  == MT_LCD) &&
-	    (pRADEONEnt->PortInfo[1]->MonType == MT_DFP)) {
-	    pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
-	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
-            pRADEONEnt->PortInfo[1]->TMDSType = TMDS_INT;
-            pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I;
-            pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	}
-    }
-
-    if (info->IsMobility) {
-        pRADEONEnt->PortInfo[2]->DDCType = DDC_DVI;
-        pRADEONEnt->PortInfo[2]->TMDSType = TMDS_INT;
-        pRADEONEnt->PortInfo[2]->ConnectorType = CONNECTOR_DVI_D;
-        pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	if (pRADEONEnt->PortInfo[0]->DDCType == DDC_DVI) {
-	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
-	}
-	if (pRADEONEnt->PortInfo[0]->TMDSType == TMDS_INT) {
-	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	}
-    }
-#endif
 
     for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
@@ -2812,52 +2427,6 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
     return TRUE;
 }
 
-#if 0
-Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr      info = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    int i;
-
-    if (pRADEONEnt->pOutput[0])
-        return TRUE;
-
-    /* for now always allocate max connectors */
-    for (i = 0 ; i < info->max_connectors; i++) {
-
-	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
-	if (!pRADEONEnt->pOutput[i])
-	    return FALSE;
-	
-	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
-	pRADEONEnt->PortInfo[i]->num = i;
-
-	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
-	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
- 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
-
-	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
-    }
-
-    return TRUE;
-}
-#endif
-
-#if 0
-xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
-{
-    RADEONInfoPtr      info = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    int i;
-
-    for (i = 0; i < info->max_connectors; i++) {
-        if (pRADEONEnt->PortInfo[i]->crtc_num == crtc_num)
-	    return pRADEONEnt->pOutput[i];
-    }
-    return NULL;
-}
-#endif
-
 /**
  * In the current world order, there are lists of modes per output, which may
  * or may not include the mode that was asked to be set by XFree86's mode
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0616b32..adc635d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6070,179 +6070,6 @@ static void RADEONInitPalette(RADEONSave
 }
 #endif
 
-#if 0
-/* Define registers for a requested video mode */
-Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
-		 DisplayModePtr crtc2, int crtc_mask,
-		 RADEONSavePtr save, RADEONMonitorType montype)
-{
-    RADEONInfoPtr  info      = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    double         dot_clock = 0;
-    RADEONInfoPtr  info0     = NULL;
-    ScrnInfoPtr    pScrn0    = NULL;
-
-    if (crtc_mask & 1)
-      xf86PrintModeline(pScrn->scrnIndex, crtc1);
-    if (crtc_mask & 2)
-      xf86PrintModeline(pScrn->scrnIndex, crtc2);
-
-#if RADEON_DEBUG
-    if (crtc1 && (crtc_mask & 1)) {
-    	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc1->name,
-	   crtc1->Clock/1000.0,
-
-	   crtc1->HDisplay,
-	   crtc1->HSyncStart,
-	   crtc1->HSyncEnd,
-	   crtc1->HTotal,
-
-	   crtc1->VDisplay,
-	   crtc1->VSyncStart,
-	   crtc1->VSyncEnd,
-	   crtc1->VTotal,
-	   pScrn->depth,
-	   pScrn->bitsPerPixel);
-    	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    	ErrorF("\n");
-    }
-    if (crtc2 && (crtc_mask & 2)) {
-        ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc2->name,
-	   crtc2->Clock/1000.0,
-
-	   crtc2->CrtcHDisplay,
-	   crtc2->CrtcHSyncStart,
-	   crtc2->CrtcHSyncEnd,
-	   crtc2->CrtcHTotal,
-
-	   crtc2->CrtcVDisplay,
-	   crtc2->CrtcVSyncStart,
-	   crtc2->CrtcVSyncEnd,
-	   crtc2->CrtcVTotal,
-	   pScrn->depth,
-	   pScrn->bitsPerPixel);
-        if (crtc2->Flags & V_DBLSCAN)   ErrorF(" D");
-        if (crtc2->Flags & V_CSYNC)     ErrorF(" C");
-        if (crtc2->Flags & V_INTERLACE) ErrorF(" I");
-        if (crtc2->Flags & V_PHSYNC)    ErrorF(" +H");
-        if (crtc2->Flags & V_NHSYNC)    ErrorF(" -H");
-        if (crtc2->Flags & V_PVSYNC)    ErrorF(" +V");
-        if (crtc2->Flags & V_NVSYNC)    ErrorF(" -V");
-    	ErrorF("\n");
-    }
-#endif
-
-    /*    if (crtc1 && (crtc_mask & 1))
-	  info->Flags = crtc1->Flags;*/
-
-    RADEONInitMemMapRegisters(pScrn, save, info);
-    RADEONInitCommonRegisters(save, info);
-
-    switch(crtc_mask) {
-    case 1:
-	if (!RADEONInitCrtcRegisters(pScrn, save, crtc1, info))
-	    return FALSE;
-	dot_clock = crtc1->Clock/1000.0;
-	if (dot_clock) {
-		RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock);
-	} else {
-	    save->ppll_ref_div = info->SavedReg.ppll_ref_div;
-	    save->ppll_div_3   = info->SavedReg.ppll_div_3;
-	    save->htotal_cntl  = info->SavedReg.htotal_cntl;
-	}
-	if (pRADEONEnt->HasSecondary) {
-	    pScrn0 = pRADEONEnt->pSecondaryScrn;
-	    info0 = RADEONPTR(pScrn0);
-	    /* carry over to secondary screen */
-	    memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));	
-	}
-
-	/* Not used for now: */
-	/* if (!info->PaletteSavedOnVT) RADEONInitPalette(save); */
-	break;
-    case 2:
-	if (pRADEONEnt->HasSecondary) {
-	    pScrn0 = pRADEONEnt->pPrimaryScrn;
-	    info0 = RADEONPTR(pScrn0);
-	} else {
-	    pScrn0 = pScrn;
-	    info0 = info;
-	}
-	dot_clock = crtc2->Clock/1000.0;
-	if (!RADEONInitCrtc2Registers(pScrn, save, crtc2, info))
-	    return FALSE;
-	RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, montype != MT_CRT);
-	/* Make sure primary has the same copy */
-	if (pRADEONEnt->HasSecondary)
-	  memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));
-	break;
-    case 3:
-       if (!RADEONInitCrtcRegisters(pScrn, save, 
-				    crtc1, info))
-            return FALSE;
-        dot_clock = crtc1->Clock / 1000.0;
-        if (dot_clock) {
-		RADEONInitPLLRegisters(pScrn, info, save, &info->pll, dot_clock);
-        } else {
-            save->ppll_ref_div = info->SavedReg.ppll_ref_div;
-            save->ppll_div_3   = info->SavedReg.ppll_div_3;
-            save->htotal_cntl  = info->SavedReg.htotal_cntl;
-        }
-        RADEONInitCrtc2Registers(pScrn, save, crtc2, info);
-        dot_clock = crtc2->Clock / 1000.0;
-        RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, montype != MT_CRT);
-	break;
-    default:
-	return FALSE;
-    }
-
-    RADEONTRACE(("RADEONInit2 %d returns %p\n", crtc_mask, save));
-    return TRUE;
-}
-
-static Bool RADEONInit(ScrnInfoPtr pScrn, DisplayModePtr mode,
-		       RADEONSavePtr save)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-
-    if (info->IsSecondary) {
-        return RADEONInit2(pScrn, NULL, mode, 2, save, 0);
-    } else {
-        return RADEONInit2(pScrn, mode, NULL, 1, save, 0);
-    }
-}
-
-/* Initialize a new mode */
-static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
-
-    RADEONTRACE(("RADEONModeInit()\n"));
-
-    if (!RADEONInit(pScrn, mode, &info->ModeReg)) return FALSE;
-
-    pScrn->vtSema = TRUE;
-    RADEONBlank(pScrn);
-    RADEONRestoreMode(pScrn, &info->ModeReg);
-    RADEONUnblank(pScrn);
-
-    info->CurrentLayout.mode = mode;
-
-    if (info->DispPriority)
-	RADEONInitDispBandwidth(pScrn);
-
-    return TRUE;
-}
-#endif
-
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode)
 {
     ScrnInfoPtr  pScrn = xf86Screens[pScreen->myNum];
@@ -6588,9 +6415,6 @@ Bool RADEONEnterVT(int scrnIndex, int fl
 
 	}
     }
-#if 0
-      if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
-#endif
 
     if (!info->IsSecondary)
 	RADEONRestoreSurfaces(pScrn, &info->ModeReg);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 3e18b05..2bb5b27 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -126,10 +126,6 @@ typedef struct _RADEONCrtcPrivateRec {
     int binding;
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
-    int               RefDivider;
-    int               FeedbackDivider;
-    int               PostDivider;
-    Bool              UseBiosDividers;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct {
diff-tree 66e8e6c8348d007930730e90295588efe8108844 (from 1c16c2ce9c5b02b03d23da965127d82eea4c4039)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 14:25:03 2007 -0400

    RADEON: several fixes
    
    - give better DDC names
    - disable DAC if connector is DVI-D
    - fix indentation in ProbeDDCModes()

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 779e8ab..cafcb0e 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2473,7 +2473,7 @@ void RADEONInitConnector(xf86OutputPtr o
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int DDCReg = 0;
-    char* name = "DDC Bus";//OutputType[radeon_output->type];
+    char* name = OutputType[radeon_output->type];
 
     switch(radeon_output->DDCType) {
     case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
@@ -2732,10 +2732,15 @@ Bool RADEONSetupConnectors(ScrnInfoPtr p
 	    return FALSE;
 	}
 	radeon_output->MonType = MT_UNKNOWN;
+	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
+	if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_DVI_D_ATOM) ||
+	    radeon_output->ConnectorType == CONNECTOR_DVI_D)
+	    radeon_output->DACType = DAC_UNKNOWN;
+	else
+	    radeon_output->DACType = info->BiosConnector[i].DACType;
 	radeon_output->DDCType = info->BiosConnector[i].DDCType;
-	radeon_output->DACType = info->BiosConnector[i].DACType;
 	radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
-	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
+
 	RADEONSetOutputType(pScrn, radeon_output);
 	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
 	if (!output) {
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 4555856..bc069ea 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -284,45 +284,43 @@ RADEONProbeOutputModes(xf86OutputPtr out
 
 
     if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
-      edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
-      xf86OutputSetEDID (output, edid_mon);
+	edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
+	xf86OutputSetEDID (output, edid_mon);
       
-      modes = xf86OutputGetEDIDModes (output);
-      return modes;
+	modes = xf86OutputGetEDIDModes (output);
+	return modes;
     }
     if (radeon_output->type == OUTPUT_LVDS) {
-      /* okay we got DDC info */
-      if (output->MonInfo) {
-	/* Debug info for now, at least */
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
-	xf86PrintEDID(output->MonInfo);
+	/* okay we got DDC info */
+	if (output->MonInfo) {
+	    /* Debug info for now, at least */
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
+	    xf86PrintEDID(output->MonInfo);
 	
-	modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
+	    modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
 	
-	for (mode = modes; mode != NULL; mode = mode->next) {
-	  if (mode->Flags & V_DBLSCAN) {
-	    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
-	    mode->status = MODE_CLOCK_RANGE;
-	  }
-	}
-	xf86PruneInvalidModes(pScrn, &modes, TRUE);
+	    for (mode = modes; mode != NULL; mode = mode->next) {
+		if (mode->Flags & V_DBLSCAN) {
+		    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+			mode->status = MODE_CLOCK_RANGE;
+		}
+	    }
+	    xf86PruneInvalidModes(pScrn, &modes, TRUE);
 	
-	/* do some physcial size stuff */
-      }
-      
+	    /* do some physcial size stuff */
+	}
       
-      if (modes == NULL) {
-	MonRec fixed_mon;
-
-	RADEONValidateFPModes(output, pScrn->display->modes, &modes);
-      }
+	if (modes == NULL) {
+	    RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+	}
     }
     
     if (modes) {
-      xf86ValidateModesUserConfig(pScrn, modes);
-      xf86PruneInvalidModes(pScrn, &modes,
-				  FALSE);
+	xf86ValidateModesUserConfig(pScrn, modes);
+	xf86PruneInvalidModes(pScrn, &modes,
+			      FALSE);
     }
+
     return modes;
 }
 
diff-tree 1c16c2ce9c5b02b03d23da965127d82eea4c4039 (from 7c66e903368f77ecc4d3bd1c9f08d2adbd85e83c)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 13:54:04 2007 -0400

    RADEON: fix VT switch

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 8e8f7a2..0616b32 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4643,7 +4643,7 @@ RADEONEnableOutputs(ScrnInfoPtr pScrn, i
     RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    xf86CrtcPtr crtc = pRADEONEnt->pCrtc[0];
+    xf86CrtcPtr crtc = pRADEONEnt->pCrtc[crtc_num];
     int i;
 
     /* get the output connected to this CRTC */
@@ -4702,7 +4702,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    RADEONRestorePLL2Registers(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
 	    RADEONRestoreDACRegisters(pScrn, restore);
-	    RADEONEnableOutputs(pScrn, 2);
+	    RADEONEnableOutputs(pScrn, 1);
 	} else {
 	    RADEONRestoreMemMapRegisters(pScrn, restore);
 	    RADEONRestoreCommonRegisters(pScrn, restore);
@@ -4715,9 +4715,9 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
             RADEONRestorePLLRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
 	    RADEONRestoreDACRegisters(pScrn, restore);
-	    RADEONEnableOutputs(pScrn, 1);
+	    RADEONEnableOutputs(pScrn, 0);
 	    if (pCRTC2->binding == 1) {
-	      RADEONEnableOutputs(pScrn, 2);
+	      RADEONEnableOutputs(pScrn, 1);
 	    }
 	}
     } else {
@@ -4734,11 +4734,11 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreDACRegisters(pScrn, restore);
 	ErrorF("finished FP restore\n");
 
-	RADEONEnableOutputs(pScrn, 1);
+	RADEONEnableOutputs(pScrn, 0);
 	ErrorF("enable output1 done\n");
 
 	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    RADEONEnableOutputs(pScrn, 2);
+	    RADEONEnableOutputs(pScrn, 1);
 	    ErrorF("enable output2 done\n");
 	}
     }
diff-tree 7c66e903368f77ecc4d3bd1c9f08d2adbd85e83c (from aec078eb0740651fba8ec602e8239bd679efc8ad)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 13:37:59 2007 -0400

    RADEON: move crtc offset handling into init/save/restore functions

diff --git a/src/radeon.h b/src/radeon.h
index 8c3b700..762376a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -240,6 +240,7 @@ typedef struct {
     CARD32            disp_merge_cntl;
     CARD32            grph_buffer_cntl;
     CARD32            crtc_more_cntl;
+    CARD32            crtc_tile_x0_y0;
 
 				/* CRTC2 registers */
     CARD32            crtc2_gen_cntl;
@@ -257,6 +258,8 @@ typedef struct {
     CARD32            crtc2_offset;
     CARD32            crtc2_offset_cntl;
     CARD32            crtc2_pitch;
+    CARD32            crtc2_tile_x0_y0;
+
 				/* Flat panel registers */
     CARD32            fp_crtc_h_total_disp;
     CARD32            fp_crtc_v_total_disp;
@@ -784,7 +787,7 @@ extern void        RADEONWaitForIdleCP(S
 #endif
 
 extern void        RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y,
-				       int clone);
+				       Bool clone);
 
 extern void        RADEONEngineReset(ScrnInfoPtr pScrn);
 extern void        RADEONEngineFlush(ScrnInfoPtr pScrn);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index f64b6f6..779e8ab 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2042,7 +2042,6 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 
 	if (output->crtc == crtc) {
 	    montype = radeon_output->MonType;
-	    radeon_output->crtc_num = radeon_crtc->crtc_id + 1;
 	}
     }
     
@@ -2054,7 +2053,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     switch (radeon_crtc->crtc_id) {
     case 0:
 	ErrorF("init crtc1\n");
-	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode, info);
+	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode, x, y);
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll1\n");
@@ -2067,7 +2066,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	break;
     case 1:
 	ErrorF("init crtc2\n");
-        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode, info);
+        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode, x, y);
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll2\n");
@@ -2083,16 +2082,12 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 
     switch (radeon_crtc->crtc_id) {
     case 0:
-	ErrorF("adjustframe 1\n");
-	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
 	ErrorF("restore crtc1\n");
 	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
 	ErrorF("restore pll1\n");
 	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
 	break;
     case 1:
-	ErrorF("adjustframe 2\n");
-	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
 	ErrorF("restore crtc2\n");
 	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
 	ErrorF("restore pll2\n");
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index edc59bb..8e8f7a2 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4147,8 +4147,11 @@ void RADEONRestoreCrtcRegisters(ScrnInfo
     OUTREG(RADEON_FP_CRTC_H_TOTAL_DISP, restore->fp_crtc_h_total_disp);
     OUTREG(RADEON_FP_CRTC_V_TOTAL_DISP, restore->fp_crtc_v_total_disp);
 
-    OUTREG(RADEON_CRTC_OFFSET,          restore->crtc_offset);
+    if (IS_R300_VARIANT)
+	OUTREG(R300_CRTC_TILE_X0_Y0, restore->crtc_tile_x0_y0);
     OUTREG(RADEON_CRTC_OFFSET_CNTL,     restore->crtc_offset_cntl);
+    OUTREG(RADEON_CRTC_OFFSET,          restore->crtc_offset);
+
     OUTREG(RADEON_CRTC_PITCH,           restore->crtc_pitch);
     OUTREG(RADEON_DISP_MERGE_CNTL,      restore->disp_merge_cntl);
     OUTREG(RADEON_CRTC_MORE_CNTL,       restore->crtc_more_cntl);
@@ -4196,8 +4199,11 @@ void RADEONRestoreCrtc2Registers(ScrnInf
     OUTREG(RADEON_FP_H2_SYNC_STRT_WID,   restore->fp_h2_sync_strt_wid);
     OUTREG(RADEON_FP_V2_SYNC_STRT_WID,   restore->fp_v2_sync_strt_wid);
 
-    OUTREG(RADEON_CRTC2_OFFSET,          restore->crtc2_offset);
+    if (IS_R300_VARIANT)
+	OUTREG(R300_CRTC2_TILE_X0_Y0, restore->crtc2_tile_x0_y0);
     OUTREG(RADEON_CRTC2_OFFSET_CNTL,     restore->crtc2_offset_cntl);
+    OUTREG(RADEON_CRTC2_OFFSET,          restore->crtc2_offset);
+
     OUTREG(RADEON_CRTC2_PITCH,           restore->crtc2_pitch);
     OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
 
@@ -4827,6 +4833,9 @@ static void RADEONSaveCrtcRegisters(Scrn
     save->disp_merge_cntl      = INREG(RADEON_DISP_MERGE_CNTL);
     save->crtc_more_cntl       = INREG(RADEON_CRTC_MORE_CNTL);
 
+    if (IS_R300_VARIANT)
+	save->crtc_tile_x0_y0 =  INREG(R300_CRTC_TILE_X0_Y0);
+
     if (info->IsDellServer) {
 	save->tv_dac_cntl      = INREG(RADEON_TV_DAC_CNTL);
 	save->dac2_cntl        = INREG(RADEON_DAC_CNTL2);
@@ -4880,6 +4889,9 @@ static void RADEONSaveCrtc2Registers(Scr
     save->crtc2_offset_cntl     = INREG(RADEON_CRTC2_OFFSET_CNTL);
     save->crtc2_pitch           = INREG(RADEON_CRTC2_PITCH);
 
+    if (IS_R300_VARIANT)
+	save->crtc2_tile_x0_y0 =  INREG(R300_CRTC2_TILE_X0_Y0);
+
     save->fp_h2_sync_strt_wid   = INREG (RADEON_FP_H2_SYNC_STRT_WID);
     save->fp_v2_sync_strt_wid   = INREG (RADEON_FP_V2_SYNC_STRT_WID);
 
@@ -5449,18 +5461,23 @@ static void RADEONInitOutputRegisters(Sc
 
 /* Define CRTC registers for requested video mode */
 Bool RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
-				  DisplayModePtr mode, RADEONInfoPtr info)
+				  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);
+    //RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
     int    format;
     int    hsync_start;
     int    hsync_wid;
     int    vsync_wid;
-    int i;
-
+    int i, Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
 
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
@@ -5603,6 +5620,79 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
 	}
     }
 
+    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;
@@ -5625,17 +5715,23 @@ Bool RADEONInitCrtcRegisters(xf86CrtcPtr
 
 /* Define CRTC2 registers for requested video mode */
 Bool RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
-				     DisplayModePtr mode, RADEONInfoPtr info)
+				     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);
+    //RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
     int    format;
     int    hsync_start;
     int    hsync_wid;
     int    vsync_wid;
-    int i;
+    int i, Base;
+#ifdef XF86DRI
+    RADEONSAREAPrivPtr pSAREAPriv;
+    XF86DRISAREAPtr pSAREA;
+#endif
 
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
@@ -5735,6 +5831,73 @@ Bool RADEONInitCrtc2Registers(xf86CrtcPt
 	}
     }
 
+    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 */
+    save->crtc2_offset = Base;
+
+#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
@@ -6226,11 +6389,11 @@ ModeStatus RADEONValidMode(int scrnIndex
 /* Adjust viewport into virtual desktop such that (0,0) in viewport
  * space is (x,y) in virtual space.
  */
-void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int clone)
+void RADEONDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, Bool crtc2)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    int            Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
+    int            Base, reg, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
 #ifdef XF86DRI
     RADEONSAREAPrivPtr pSAREAPriv;
     XF86DRISAREAPtr pSAREA;
@@ -6257,10 +6420,12 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
      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. */
-    if (clone || info->IsSecondary) {
+    if (crtc2 || info->IsSecondary) {
+	reg = RADEON_CRTC2_OFFSET;
 	regcntl = RADEON_CRTC2_OFFSET_CNTL;
 	xytilereg = R300_CRTC2_TILE_X0_Y0;
     } else {
+	reg = RADEON_CRTC_OFFSET;
 	regcntl = RADEON_CRTC_OFFSET_CNTL;
 	xytilereg = R300_CRTC_TILE_X0_Y0;
     }
@@ -6312,7 +6477,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 	/* can't get at sarea in a semi-sane way? */
 	pSAREA = (void *)((char*)pSAREAPriv - sizeof(XF86DRISAREARec));
 
-	if (clone || info->IsSecondary) {
+	if (crtc2 || info->IsSecondary) {
 	    pSAREAPriv->crtc2_base = Base;
 	}
 	else {
@@ -6331,15 +6496,15 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 #endif
 
     if (IS_R300_VARIANT) {
-        OUTREG(xytilereg, crtcxytile);
+	OUTREG(xytilereg, crtcxytile);
     } else {
-        OUTREG(regcntl, crtcoffsetcntl);
+	OUTREG(regcntl, crtcoffsetcntl);
     }
 
-    if (clone)
-        info->ModeReg.crtc2_offset = Base;
+    if (crtc2)
+	OUTREG(reg, Base);
     else
-        info->ModeReg.crtc_offset = Base;
+	OUTREG(reg, Base);
 }
 
 void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
@@ -6457,7 +6622,7 @@ Bool RADEONEnterVT(int scrnIndex, int fl
     }
 #endif
 
-    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+    //    pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
     return TRUE;
 }
diff-tree aec078eb0740651fba8ec602e8239bd679efc8ad (from 0550c37ecc434b8075fb3c367d100ff27625bb64)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 11:57:57 2007 -0400

    RADEON: fix up DDCConnected()

diff --git a/src/radeon_display.c b/src/radeon_display.c
index cf1d1fe..f64b6f6 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -566,7 +566,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoP
 }
 
 
-static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr output)
+static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -574,9 +574,9 @@ static RADEONMonitorType RADEONDisplayDD
     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 */
@@ -645,21 +645,13 @@ static RADEONMonitorType RADEONDisplayDD
 	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
 
     if (*MonInfo) {
+	/* if it's digital */
 	if ((*MonInfo)->rawData[0x14] & 0x80) {
-	    /* Note some laptops have a DVI output that uses internal TMDS,
-	     * when its DVI is enabled by hotkey, LVDS panel is not used.
-	     * In this case, the laptop is configured as DVI+VGA as a normal 
-	     * desktop card.
-	     * Also for laptop, when X starts with lid closed (no DVI connection)
-	     * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
-	     */
-	    if (radeon_output->TMDSType == TMDS_EXT) MonType = MT_DFP;
-	    else {
-		if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS)
-		    MonType = MT_DFP;
-		else
-		    MonType = MT_LCD;
-	    }
+	    if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
+		radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)
+		MonType = MT_LCD;
+	    else
+		MonType = MT_DFP;
 	} else MonType = MT_CRT;
     } else MonType = MT_NONE;
 
@@ -979,9 +971,7 @@ void RADEONConnectorFindMonitor(ScrnInfo
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     
     if (radeon_output->MonType == MT_UNKNOWN) {
-      if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn,
-						     radeon_output->DDCType,
-						     output)));
+      if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output)));
       else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
       else if (radeon_output->DACType == DAC_PRIMARY) 
 	  radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
diff-tree 0550c37ecc434b8075fb3c367d100ff27625bb64 (from 117220527de9fd3158f600645bcfcaf46847f45f)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 11:44:50 2007 -0400

    RADEON: don't need to pass pScrn to EnableDisplay()

diff --git a/src/radeon.h b/src/radeon.h
index 4f674ed..8c3b700 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -846,7 +846,7 @@ extern Bool        RADEONI2cInit(ScrnInf
 extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
 extern Bool        RADEONSetupConnectors(ScrnInfoPtr pScrn);
 extern Bool        RADEONMapControllers(ScrnInfoPtr pScrn);
-extern void        RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable);
+extern void        RADEONEnableDisplay(xf86OutputPtr pPort, BOOL bEnable);
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
 extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
 extern void        RADEONGetTVDacAdjInfo(xf86OutputPtr output);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 897db27..cf1d1fe 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1370,8 +1370,9 @@ void RADEONDisableDisplays(ScrnInfoPtr p
 }
 
 /* This is to be used enable/disable displays dynamically */
-void RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr output, BOOL bEnable)
+void RADEONEnableDisplay(xf86OutputPtr output, BOOL bEnable)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONSavePtr save = &info->ModeReg;
     unsigned char * RADEONMMIO = info->MMIO;
@@ -2216,13 +2217,13 @@ radeon_dpms(xf86OutputPtr output, int mo
 
     switch(mode) {
     case DPMSModeOn:
-	RADEONEnableDisplay(pScrn, output, TRUE);
+	RADEONEnableDisplay(output, TRUE);
 	/*      RADEONDPMSSetOn(output);*/
 	break;
     case DPMSModeOff:
     case DPMSModeSuspend:
     case DPMSModeStandby:
-	RADEONEnableDisplay(pScrn, output, FALSE);
+	RADEONEnableDisplay(output, FALSE);
 	/*RADEONDPMSSetOff(output);*/
 	break;
     }
@@ -2314,7 +2315,7 @@ radeon_mode_set(xf86OutputPtr output, Di
 	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
     }
 
-    RADEONEnableDisplay(pScrn, output, TRUE);
+    RADEONEnableDisplay(output, TRUE);
 }
 
 static void
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a261d0d..edc59bb 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4644,7 +4644,7 @@ RADEONEnableOutputs(ScrnInfoPtr pScrn, i
     for (i = 0; i < xf86_config->num_output; i++) {
 	xf86OutputPtr output = xf86_config->output[i];
 	if (output->crtc == crtc) {
-	    RADEONEnableDisplay(pScrn, output, TRUE);
+	    RADEONEnableDisplay(output, TRUE);
 	}
     }
 }
diff-tree 117220527de9fd3158f600645bcfcaf46847f45f (from 7e5c29961ac2a9e9dbe5d6d2d73d11cd018d62b5)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun May 13 11:37:35 2007 -0400

    RADEON: remove hardcoded output limit and PortInfo stuff

diff --git a/src/radeon.h b/src/radeon.h
index e58747a..4f674ed 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -763,7 +763,7 @@ typedef struct {
 
     CARD32            tv_dac_adj;
 
-  int               max_connectors;
+    RADEONBIOSConnector BiosConnector[RADEON_MAX_BIOS_CONNECTOR];
 
     CreateScreenResourcesProcPtr CreateScreenResources;
 } RADEONInfoRec, *RADEONInfoPtr;
@@ -844,7 +844,7 @@ extern Bool        RADEONGetHardCodedEDI
 extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
 extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
 extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
-extern void        RADEONSetupConnectors(ScrnInfoPtr pScrn);
+extern Bool        RADEONSetupConnectors(ScrnInfoPtr pScrn);
 extern Bool        RADEONMapControllers(ScrnInfoPtr pScrn);
 extern void        RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable);
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 4b3ec56..6e08f24 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -148,49 +148,49 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 			    /* sharing same port with id[0] */
 			    if (((portinfo>>8) & 0xf) == id[0]) {
 				if (i == 3) 
-				    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
+				    info->BiosConnector[0].TMDSType = TMDS_INT;
 				else if (i == 7)
-				    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_EXT;
+				    info->BiosConnector[0].TMDSType = TMDS_EXT;
 
-				if (pRADEONEnt->PortInfo[0]->DACType == DAC_UNKNOWN)
-				    pRADEONEnt->PortInfo[0]->DACType = (portinfo & 0xf) - 1;
+				if (info->BiosConnector[0].DACType == DAC_UNKNOWN)
+				    info->BiosConnector[0].DACType = (portinfo & 0xf) - 1;
 				continue;
 			    }
 			}
 
 			id[crtc] = (portinfo>>8) & 0xf; 
-			pRADEONEnt->PortInfo[crtc]->DACType = (portinfo & 0xf) - 1;
-			pRADEONEnt->PortInfo[crtc]->ConnectorType = (portinfo>>4) & 0xf;
+			info->BiosConnector[crtc].DACType = (portinfo & 0xf) - 1;
+			info->BiosConnector[crtc].ConnectorType = (portinfo>>4) & 0xf;
 			if (i == 3) 
-			    pRADEONEnt->PortInfo[crtc]->TMDSType = TMDS_INT;
+			    info->BiosConnector[crtc].TMDSType = TMDS_INT;
 			else if (i == 7)
-			    pRADEONEnt->PortInfo[crtc]->TMDSType = TMDS_EXT;
+			    info->BiosConnector[crtc].TMDSType = TMDS_EXT;
 			
 			if((tmp0 = RADEON_BIOS16 (info->MasterDataStart + 24)) && id[crtc]) {
 			    switch (RADEON_BIOS16 (tmp0 + 4 + 27 * id[crtc]) * 4) 
 			    {
 			    case RADEON_GPIO_MONID:
-				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_MONID;
+				info->BiosConnector[crtc].DDCType = DDC_MONID;
 				break;
 			    case RADEON_GPIO_DVI_DDC:
-				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_DVI;
+				info->BiosConnector[crtc].DDCType = DDC_DVI;
 				break;
 			    case RADEON_GPIO_VGA_DDC:
-				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_VGA;
+				info->BiosConnector[crtc].DDCType = DDC_VGA;
 				break;
 			    case RADEON_GPIO_CRT2_DDC:
-				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_CRT2;
+				info->BiosConnector[crtc].DDCType = DDC_CRT2;
 				break;
 			    case RADEON_LCD_GPIO_MASK:
-				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_LCD;
+				info->BiosConnector[crtc].DDCType = DDC_LCD;
 				break;
 			    default:
-				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_NONE_DETECTED;
+				info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED;
 				break;
 			    }
 
 			} else {
-			    pRADEONEnt->PortInfo[crtc]->DDCType = DDC_NONE_DETECTED;
+			    info->BiosConnector[crtc].DDCType = DDC_NONE_DETECTED;
 			}
 			crtc++;
 		    } else {
@@ -200,22 +200,22 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 			for (j=0; j<2; j++) {
 			    if (((portinfo>>8) & 0xf) == id[j]) {
 				if (i == 3) 
-				    pRADEONEnt->PortInfo[j]->TMDSType = TMDS_INT;
+				    info->BiosConnector[j].TMDSType = TMDS_INT;
 				else if (i == 7)
-				    pRADEONEnt->PortInfo[j]->TMDSType = TMDS_EXT;
+				    info->BiosConnector[j].TMDSType = TMDS_EXT;
 
-				if (pRADEONEnt->PortInfo[j]->DACType == DAC_UNKNOWN)
-				    pRADEONEnt->PortInfo[j]->DACType = (portinfo & 0xf) - 1;
+				if (info->BiosConnector[j].DACType == DAC_UNKNOWN)
+				    info->BiosConnector[j].DACType = (portinfo & 0xf) - 1;
 			    }
 			}
 		    }
 		}
 	    }
-
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Bios Connector table: \n");
 	    for (i=0; i<2; i++) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-			   i, pRADEONEnt->PortInfo[i]->DDCType, pRADEONEnt->PortInfo[i]->DACType,
-			   pRADEONEnt->PortInfo[i]->TMDSType, pRADEONEnt->PortInfo[i]->ConnectorType);
+			   i, info->BiosConnector[i].DDCType, info->BiosConnector[i].DACType,
+			   info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
 	    }	    
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No Device Info Table found!\n");
@@ -242,25 +242,27 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 		tmp0 = RADEON_BIOS16(tmp + i*2);
 		if (((tmp0 >> 12) & 0x0f) == 0) continue;     /* no connector */
 		if (connector_found > 0) {
-		    if (pRADEONEnt->PortInfo[tmp1]->DDCType == ((tmp0 >> 8) & 0x0f))
+		    if (info->BiosConnector[tmp1].DDCType == ((tmp0 >> 8) & 0x0f))
 			continue;                             /* same connector */
 		}
 
 		/* internal DDC_DVI port will get assigned to PortInfo[0], or if there is no DDC_DVI (like in some IGPs). */
 		tmp1 = ((((tmp0 >> 8) & 0xf) == DDC_DVI) || (tmp1 == 1)) ? 0 : 1; /* determine port info index */
 		
-		pRADEONEnt->PortInfo[tmp1]->DDCType        = (tmp0 >> 8) & 0x0f;
-		if (pRADEONEnt->PortInfo[tmp1]->DDCType > DDC_CRT2) pRADEONEnt->PortInfo[tmp1]->DDCType = DDC_NONE_DETECTED;
-		pRADEONEnt->PortInfo[tmp1]->DACType        = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;
-		pRADEONEnt->PortInfo[tmp1]->ConnectorType  = (tmp0 >> 12) & 0x0f;
-		if (pRADEONEnt->PortInfo[tmp1]->ConnectorType > CONNECTOR_UNSUPPORTED) pRADEONEnt->PortInfo[tmp1]->ConnectorType = CONNECTOR_UNSUPPORTED;
-		pRADEONEnt->PortInfo[tmp1]->TMDSType       = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT;
+		info->BiosConnector[tmp1].DDCType        = (tmp0 >> 8) & 0x0f;
+		if (info->BiosConnector[tmp1].DDCType > DDC_CRT2)
+		    info->BiosConnector[tmp1].DDCType = DDC_NONE_DETECTED;
+		info->BiosConnector[tmp1].DACType        = (tmp0 & 0x01) ? DAC_TVDAC : DAC_PRIMARY;
+		info->BiosConnector[tmp1].ConnectorType  = (tmp0 >> 12) & 0x0f;
+		if (info->BiosConnector[tmp1].ConnectorType > CONNECTOR_UNSUPPORTED)
+		    info->BiosConnector[tmp1].ConnectorType = CONNECTOR_UNSUPPORTED;
+		info->BiosConnector[tmp1].TMDSType       = ((tmp0 >> 4) & 0x01) ? TMDS_EXT : TMDS_INT;
 
 		/* some sanity checks */
-		if (((pRADEONEnt->PortInfo[tmp1]->ConnectorType != CONNECTOR_DVI_D) &&
-		     (pRADEONEnt->PortInfo[tmp1]->ConnectorType != CONNECTOR_DVI_I)) &&
-		    pRADEONEnt->PortInfo[tmp1]->TMDSType == TMDS_INT)
-		    pRADEONEnt->PortInfo[tmp1]->TMDSType = TMDS_UNKNOWN;
+		if (((info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_D) &&
+		     (info->BiosConnector[tmp1].ConnectorType != CONNECTOR_DVI_I)) &&
+		    info->BiosConnector[tmp1].TMDSType == TMDS_INT)
+		    info->BiosConnector[tmp1].TMDSType = TMDS_UNKNOWN;
 		
 		connector_found += (tmp1 + 1);
 	    }
@@ -270,19 +272,20 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 	}
 
 	if (info->IsMobility) {
+#if 0
 	    /* For the cases where only one VGA connector is found, 
 	       we assume LVDS is not listed in the connector table, 
 	       add it in here as the first port.
 	    */
-	    if ((connector_found < 3) && (pRADEONEnt->PortInfo[tmp1]->ConnectorType == CONNECTOR_CRT)) {
+	    if ((connector_found < 3) && (info->BiosConnector[tmp1]->ConnectorType == CONNECTOR_CRT)) {
 		if (connector_found == 1) {
-		    memcpy (&pRADEONEnt->PortInfo[1], &pRADEONEnt->PortInfo[0], 
-			    sizeof (pRADEONEnt->PortInfo[0]));
+		    memcpy (&info->BiosConnector[1], &info->BiosConnector[0], 
+			    sizeof (info->BiosConnector));
 		}
-		pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-		pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-		pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
-		pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_PROPRIETARY;
+		info->BiosConnector[0].DACType = DAC_TVDAC;
+		info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+		info->BiosConnector[0].DDCType = DDC_NONE_DETECTED;
+		info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
 
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "LVDS port is not in connector table, added in.\n");
 		if (connector_found == 0) connector_found = 1;
@@ -290,54 +293,54 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 	    }
 
 	    /* some bioses seem to list the LVDS port as DVI hack around that here */
-	    if (pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_DVI_D) {
-		pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_PROPRIETARY;
+	    if (info->BiosConnector[0].ConnectorType == CONNECTOR_DVI_D) {
+		info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
 	    }
-
+#endif
 	    if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) {
 	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
 		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    
-			pRADEONEnt->PortInfo[0]->DDCType	= tmp1;      
-			if (pRADEONEnt->PortInfo[0]->DDCType > DDC_LCD) {
+			info->BiosConnector[0].DDCType	= tmp1;      
+			if (info->BiosConnector[0].DDCType > DDC_LCD) {
 			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 				       "Unknown DDCType %d found\n",
-				       pRADEONEnt->PortInfo[0]->DDCType);
-			    pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
+				       info->BiosConnector[0].DDCType);
+			    info->BiosConnector[0].DDCType = DDC_NONE_DETECTED;
 			}
 			xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "LCD DDC Info Table found!\n");
 		    }
 		}
 	    } 
 	} else if (connector_found == 2) {
-	    memcpy (&pRADEONEnt->PortInfo[0], &pRADEONEnt->PortInfo[1], 
-		    sizeof (pRADEONEnt->PortInfo[0]));	
-	    pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN;
-	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
-	    pRADEONEnt->PortInfo[1]->DDCType = DDC_NONE_DETECTED;
-	    pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_NONE;
+	    memcpy (&info->BiosConnector[0], &info->BiosConnector[1], 
+		    sizeof (info->BiosConnector[0]));	
+	    info->BiosConnector[1].DACType = DAC_UNKNOWN;
+	    info->BiosConnector[1].TMDSType = TMDS_UNKNOWN;
+	    info->BiosConnector[1].DDCType = DDC_NONE_DETECTED;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_NONE;
 	    connector_found = 1;
 	}
 
 	if (connector_found == 0) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No connector found in Connector Info Table.\n");
 	} else {
-	    xf86DrvMsg(0, X_INFO, "Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       pRADEONEnt->PortInfo[0]->DDCType, pRADEONEnt->PortInfo[0]->DACType,
-		       pRADEONEnt->PortInfo[0]->TMDSType, pRADEONEnt->PortInfo[0]->ConnectorType);
+	    xf86DrvMsg(0, X_INFO, "Bios Connector0: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+		       info->BiosConnector[0].DDCType, info->BiosConnector[0].DACType,
+		       info->BiosConnector[0].TMDSType, info->BiosConnector[0].ConnectorType);
 	}
 	if (connector_found == 3) {
-	    xf86DrvMsg(0, X_INFO, "Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       pRADEONEnt->PortInfo[1]->DDCType, pRADEONEnt->PortInfo[1]->DACType,
-		       pRADEONEnt->PortInfo[1]->TMDSType, pRADEONEnt->PortInfo[1]->ConnectorType);
+	    xf86DrvMsg(0, X_INFO, "Bios Connector1: DDCType-%d, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
+		       info->BiosConnector[1].DDCType, info->BiosConnector[1].DACType,
+		       info->BiosConnector[1].TMDSType, info->BiosConnector[1].ConnectorType);
 	}
 
 #if 0
 /* External TMDS Table, not used now */
         if ((tmp0 = RADEON_BIOS16(info->ROMHeaderStart + 0x58))) {
 
-            //pRADEONEnt->PortInfo[1]->DDCType = (RADEON_BIOS8(tmp0 + 7) & 0x07);
-            //pRADEONEnt->PortInfo[1]->ConnectorType  = CONNECTOR_DVI_I;
-            //pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
+            //info->BiosConnector[1].DDCType = (RADEON_BIOS8(tmp0 + 7) & 0x07);
+            //info->BiosConnector[1].ConnectorType  = CONNECTOR_DVI_I;
+            //info->BiosConnector[1].TMDSType = TMDS_EXT;
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "External TMDS found.\n");
 
         } else {
diff --git a/src/radeon_display.c b/src/radeon_display.c
index c77ff64..897db27 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -871,7 +871,7 @@ static Bool RADEONGetLVDSInfo (xf86Outpu
 		tmp_mode = tmp_mode->next;
 	    }
 	}
-	if ((radeon_output->DotClock == 0) && !pRADEONEnt->pOutput[0]->MonInfo) {
+	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");
@@ -934,283 +934,14 @@ void RADEONGetTVDacAdjInfo(xf86OutputPtr
 
 static void RADEONSwapOutputs(ScrnInfoPtr pScrn)
 {
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    xf86OutputPtr connector;
-    RADEONOutputPrivatePtr conn_priv;
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONBIOSConnector tmp;
     
-    connector = pRADEONEnt->pOutput[0];
-    pRADEONEnt->pOutput[0] = pRADEONEnt->pOutput[1];
-    pRADEONEnt->pOutput[1] = connector;
+    tmp = info->BiosConnector[0];
+    info->BiosConnector[0] = info->BiosConnector[1];
+    info->BiosConnector[1] = tmp;
     
-    conn_priv = pRADEONEnt->PortInfo[0];
-    pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
-    pRADEONEnt->PortInfo[1] = conn_priv;
 }
-#if 0
-/*
- * initialise the static data sos we don't have to re-do at randr change */
-void RADEONSetupConnectors(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    xf86OutputPtr output;
-    const char *s;
-    int i = 0, second = 0, max_mt = 5;
-
-    /* We first get the information about all connectors from BIOS.
-     * This is how the card is phyiscally wired up.
-     * The information should be correct even on a OEM card.
-     * If not, we may have problem -- need to use MonitorLayout option.
-     */
-    for (i = 0; i < info->max_connectors; i++) {
-	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
-	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->ConnectorType = CONNECTOR_NONE;
-    }
-
-    if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
-        ((pRADEONEnt->PortInfo[0]->DDCType == 0) &&
-        (pRADEONEnt->PortInfo[1]->DDCType == 0))) {
-	/* Below is the most common setting, but may not be true */
-	pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI;
-	pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-	pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
-	pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I;
-
-	pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
-	pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
-	pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
-	pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
-
-
-       /* Some cards have the DDC lines swapped and we have no way to
-        * detect it yet (Mac cards)
-        */
-       if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-           pRADEONEnt->PortInfo[0]->DDCType = DDC_VGA;
-           pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
-        }
-    }
-
-    /* always make TMDS_INT port first*/
-    if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) {
-	RADEONSwapOutputs(pScrn);
-    } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT &&
-                pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) {
-        /* no TMDS_INT port, make primary DAC port first */
-	/* On my Inspiron 8600 both internal and external ports are
-	   marked DAC_PRIMARY in BIOS. So be extra careful - only
-	   swap when the first port is not DAC_PRIMARY */
-        if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) &&  (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) &&
-	     (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) {
-	    RADEONSwapOutputs(pScrn);
-        }
-    }
-
-    if (info->HasSingleDAC) {
-        /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
-        if (pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_CRT) {
-            pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-            pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
-        } else {
-            pRADEONEnt->PortInfo[1]->DACType = DAC_TVDAC;
-            pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
-        }
-    } else if (!pRADEONEnt->HasCRTC2) {
-        pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
-    }
-
-    /*
-     * MonitorLayout option takes a string for two monitors connected in following format:
-     * Option "MonitorLayout" "primary-port-display, secondary-port-display"
-     * primary and secondary port displays can have one of following:
-     *    NONE, CRT, LVDS, TMDS
-     * With this option, driver will bring up monitors as specified,
-     * not using auto-detection routines to probe monitors.
-     *
-     * This option can be used when the false monitor detection occurs.
-     *
-     * This option can also be used to disable one connected display.
-     * For example, if you have a laptop connected to an external CRT
-     * and you want to disable the internal LCD panel, you can specify
-     * Option "MonitorLayout" "NONE, CRT"
-     *
-     * This option can also used to disable Clone mode. One there is only
-     * one monitor is specified, clone mode will be turned off automatically
-     * even you have two monitors connected.
-     *
-     * Another usage of this option is you want to config the server
-     * to start up with a certain monitor arrangement even one monitor
-     * is not plugged in when server starts.
-     * For example, you can config your laptop with 
-     * Option "MonitorLayout" "LVDS, CRT"
-     * Option "CloneHSync" "40-150"
-     * Option "CloneVRefresh" "60-120"
-     * With these options, you can connect in your CRT monitor later
-     * after the X server has started.
-     */
-    if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
-        char s1[5], s2[5];
-        i = 0;
-        /* When using user specified monitor types, we will not do DDC detection
-         *
-         */
-        do {
-            switch(*s) {
-            case ',':
-                s1[i] = '\0';
-                i = 0;
-                second = 1;
-                break;
-            case ' ':
-            case '\t':
-            case '\n':
-            case '\r':
-                break;
-            default:
-                if (second)
-                    s2[i] = *s;
-                else
-                    s1[i] = *s;
-                i++;
-                break;
-            }
-            if (i > 4) i = 4;
-        } while(*s++);
-        s2[i] = '\0';
-
-        for (i = 0; i < max_mt; i++)
-        {
-            if (strcmp(s1, MonTypeName[i]) == 0) 
-            {
-                pRADEONEnt->PortInfo[0]->MonType = MonTypeID[i];
-                break;
-            }
-        }
-        if (i ==  max_mt)
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-                       "Invalid Monitor type specified for 1st port \n"); 
-
-        for (i = 0; i < max_mt; i++)
-        {
-            if (strcmp(s2, MonTypeName[i]) == 0) 
-            {
-                pRADEONEnt->PortInfo[1]->MonType = MonTypeID[i];
-                break;
-            }
-
-        }
-        if (i ==  max_mt)
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
-                       "Invalid Monitor type specified for 2nd port \n"); 
-
-	if (i ==  max_mt)
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Invalid Monitor type specified for 2nd port \n");
-
-	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-		   "MonitorLayout Option: \n\tMonitor1--Type %s, Monitor2--Type %s\n\n", s1, s2);
-#if 0
-	if (pRADEONEnt->PortInfo[1]->MonType == MT_CRT) {
-	    pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
-	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
-	    pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
-	    pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
-	    pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	    pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
-	    pRADEONEnt->PortInfo[0]->ConnectorType = pRADEONEnt->PortInfo[0]->MonType+1;
-	    pRADEONEnt->PortInfo[0]->MonInfo = NULL;
-        }
-#endif
-
-        /* some thinkpads and powerbooks use lvds and internal tmds 
-	 * at the same time.  --AGD
-	 */
-	if ((pRADEONEnt->PortInfo[0]->MonType  == MT_LCD) &&
-	    (pRADEONEnt->PortInfo[1]->MonType == MT_DFP)) {
-	    pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
-	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
-            pRADEONEnt->PortInfo[1]->TMDSType = TMDS_INT;
-            pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I;
-            pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	}
-    }
-
-#if 1
-    if (info->IsMobility) {
-        pRADEONEnt->PortInfo[2]->DDCType = DDC_DVI;
-        pRADEONEnt->PortInfo[2]->TMDSType = TMDS_INT;
-        pRADEONEnt->PortInfo[2]->ConnectorType = CONNECTOR_DVI_D;
-        pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	if (pRADEONEnt->PortInfo[0]->DDCType == DDC_DVI) {
-	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
-	}
-	if (pRADEONEnt->PortInfo[0]->TMDSType == TMDS_INT) {
-	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
-	}
-    }
-#endif
-
-    //    for (i = 0; i < xf86_config->num_output; i++) {
-    for (i = 0 ; i < info->max_connectors; i++) {
-	RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
-
-	int DDCReg = 0;
-	char *names[] = { "DDC1", "DDC2", "DDC3" };
-
-	RADEONSetOutputType(pScrn, radeon_output);
-
-	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
-	if (!pRADEONEnt->pOutput[i])
-	    return FALSE;
-	
-	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
-	pRADEONEnt->PortInfo[i]->num = i;
-
-	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
-	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
- 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
-
-	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
-
-	switch(radeon_output->DDCType) {
-	case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
-	case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
-	case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
-	case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
-	default: break;
-	}
-
-	if (DDCReg) {
-	    radeon_output->DDCReg = DDCReg;
-	    RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
-	}
-
-	if (radeon_output->type == OUTPUT_LVDS) {
-	    RADEONGetLVDSInfo(output);
-	}
-
-	if (radeon_output->type == OUTPUT_DVI) {
-	    RADEONGetTMDSInfo(output);
-
-	    if (i == 0)
-		RADEONGetHardCodedEDIDFromBIOS(output);
-
-	    /*RADEONUpdatePanelSize(output);*/
-	}
-
-	if (radeon_output->DACType == DAC_TVDAC) {
-	    RADEONGetTVDacAdjInfo(output);
-	}
-    }
-}
-#endif
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
@@ -1266,6 +997,7 @@ void RADEONConnectorFindMonitor(ScrnInfo
     }
 }
 
+#if 0
 void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn)
 {
 
@@ -1362,6 +1094,7 @@ void RADEONQueryConnectedDisplays(ScrnIn
 
     return;
 }
+#endif
 
 Bool RADEONMapControllers(ScrnInfoPtr pScrn)
 {
@@ -2330,7 +2063,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     switch (radeon_crtc->crtc_id) {
     case 0:
 	ErrorF("init crtc1\n");
-	RADEONInitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
+	RADEONInitCrtcRegisters(crtc, &info->ModeReg, adjusted_mode, info);
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll1\n");
@@ -2343,7 +2076,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	break;
     case 1:
 	ErrorF("init crtc2\n");
-        RADEONInitCrtc2Registers(pScrn, &info->ModeReg, adjusted_mode, info);
+        RADEONInitCrtc2Registers(crtc, &info->ModeReg, adjusted_mode, info);
         dot_clock = adjusted_mode->Clock / 1000.0;
         if (dot_clock) {
 	    ErrorF("init pll2\n");
@@ -2684,6 +2417,7 @@ Bool RADEONAllocateControllers(ScrnInfoP
     return TRUE;
 }
 
+#if 0
 Bool RADEONAllocatePortInfo(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr      info = RADEONPTR(pScrn);
@@ -2711,6 +2445,7 @@ Bool RADEONAllocatePortInfo(ScrnInfoPtr 
     }
     return TRUE;
 }
+#endif
 
 void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
 {
@@ -2747,113 +2482,133 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
     radeon_output->type = output;
 }
 
-Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
+void RADEONInitConnector(xf86OutputPtr output)
 {
-    RADEONInfoPtr      info = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    int i;
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    int DDCReg = 0;
+    char* name = "DDC Bus";//OutputType[radeon_output->type];
 
-    if (pRADEONEnt->pOutput[0])
-        return TRUE;
+    switch(radeon_output->DDCType) {
+    case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+    case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
+    case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
+    case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+    default: break;
+    }
+    
+    if (DDCReg) {
+	radeon_output->DDCReg = DDCReg;
+	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
+    }
 
-    /* for now always allocate max connectors */
-    for (i = 0 ; i < info->max_connectors; i++) {
+    if (radeon_output->type == OUTPUT_LVDS) {
+	RADEONGetLVDSInfo(output);
+    }
 
-	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
-	if (!pRADEONEnt->pOutput[i])
-	    return FALSE;
-	
-	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
-	pRADEONEnt->PortInfo[i]->num = i;
+    if (radeon_output->type == OUTPUT_DVI) {
+	RADEONGetTMDSInfo(output);
 
-	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
-	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
- 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
+	// FIXME
+	/*if (i == 0)
+	  RADEONGetHardCodedEDIDFromBIOS(output);*/
 
-	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
+	/*RADEONUpdatePanelSize(output);*/
+    }
+
+    if (radeon_output->DACType == DAC_TVDAC) {
+	RADEONGetTVDacAdjInfo(output);
     }
 
-    return TRUE;
 }
 
 /*
  * initialise the static data sos we don't have to re-do at randr change */
-void RADEONSetupConnectors(ScrnInfoPtr pScrn)
+Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     xf86OutputPtr output;
     const char *s;
     int i = 0, second = 0, max_mt = 5;
 
+
     /* We first get the information about all connectors from BIOS.
      * This is how the card is phyiscally wired up.
      * The information should be correct even on a OEM card.
      * If not, we may have problem -- need to use MonitorLayout option.
      */
-    for (i = 0; i < info->max_connectors; i++) {
-	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
-	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->ConnectorType = CONNECTOR_NONE;
+    for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	info->BiosConnector[i].DDCType = DDC_NONE_DETECTED;
+	info->BiosConnector[i].DACType = DAC_UNKNOWN;
+	info->BiosConnector[i].TMDSType = TMDS_UNKNOWN;
+	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
     }
 
     if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
-        ((pRADEONEnt->PortInfo[0]->DDCType == 0) &&
-        (pRADEONEnt->PortInfo[1]->DDCType == 0))) {
-	/* Below is the most common setting, but may not be true */
-	pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI;
-	pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-	pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
-	pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I;
-
-	pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
-	pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
-	pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
-	pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
-
+        ((info->BiosConnector[0].DDCType == 0) &&
+        (info->BiosConnector[1].DDCType == 0))) {
+	if (info->IsMobility) {
+	    /* Below is the most common setting, but may not be true */
+	    info->BiosConnector[0].DDCType = DDC_LCD;
+	    info->BiosConnector[0].DACType = DAC_UNKNOWN;
+	    info->BiosConnector[0].TMDSType = TMDS_UNKNOWN;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_PROPRIETARY;
+
+	    info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].DACType = DAC_PRIMARY;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	} else {
+	    /* Below is the most common setting, but may not be true */
+	    info->BiosConnector[0].DDCType = DDC_DVI;
+	    info->BiosConnector[0].DACType = DAC_TVDAC;
+	    info->BiosConnector[0].TMDSType = TMDS_INT;
+	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
+
+	    info->BiosConnector[1].DDCType = DDC_VGA;
+	    info->BiosConnector[1].DACType = DAC_PRIMARY;
+	    info->BiosConnector[1].TMDSType = TMDS_EXT;
+	    info->BiosConnector[1].ConnectorType = CONNECTOR_CRT;
+	}
 
        /* Some cards have the DDC lines swapped and we have no way to
         * detect it yet (Mac cards)
         */
        if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-           pRADEONEnt->PortInfo[0]->DDCType = DDC_VGA;
-           pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
+           info->BiosConnector[0].DDCType = DDC_VGA;
+           info->BiosConnector[1].DDCType = DDC_DVI;
         }
     }
 
     /* always make TMDS_INT port first*/
-    if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) {
+    if (info->BiosConnector[1].TMDSType == TMDS_INT) {
 	RADEONSwapOutputs(pScrn);
-    } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT &&
-                pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) {
+    } else if ((info->BiosConnector[0].TMDSType != TMDS_INT &&
+                info->BiosConnector[1].TMDSType != TMDS_INT)) {
         /* no TMDS_INT port, make primary DAC port first */
 	/* On my Inspiron 8600 both internal and external ports are
 	   marked DAC_PRIMARY in BIOS. So be extra careful - only
 	   swap when the first port is not DAC_PRIMARY */
-        if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) &&  (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) &&
-	     (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) {
+        if ((!(info->BiosConnector[0].ConnectorType == CONNECTOR_PROPRIETARY)) &&  (info->BiosConnector[1].DACType == DAC_PRIMARY) &&
+	     (info->BiosConnector[0].DACType != DAC_PRIMARY)) {
 	    RADEONSwapOutputs(pScrn);
         }
     }
 
     if (info->HasSingleDAC) {
         /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
-        if (pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_CRT) {
-            pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
-            pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
+        if (info->BiosConnector[0].ConnectorType == CONNECTOR_CRT) {
+            info->BiosConnector[0].DACType = DAC_TVDAC;
+            info->BiosConnector[1].DACType = DAC_PRIMARY;
         } else {
-            pRADEONEnt->PortInfo[1]->DACType = DAC_TVDAC;
-            pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
+            info->BiosConnector[1].DACType = DAC_TVDAC;
+            info->BiosConnector[0].DACType = DAC_PRIMARY;
         }
     } else if (!pRADEONEnt->HasCRTC2) {
-        pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
+        info->BiosConnector[0].DACType = DAC_PRIMARY;
     }
-
+#if 0
     /*
      * MonitorLayout option takes a string for two monitors connected in following format:
      * Option "MonitorLayout" "primary-port-display, secondary-port-display"
@@ -2971,7 +2726,6 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	}
     }
 
-#if 1
     if (info->IsMobility) {
         pRADEONEnt->PortInfo[2]->DDCType = DDC_DVI;
         pRADEONEnt->PortInfo[2]->TMDSType = TMDS_INT;
@@ -2986,61 +2740,117 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     }
 #endif
 
-    //    for (i = 0; i < xf86_config->num_output; i++) {
-    for (i = 0 ; i < info->max_connectors; i++) {
-	RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
-
-	int DDCReg = 0;
-	char *names[] = { "DDC1", "DDC2", "DDC3" };
-
+    for (i = 0 ; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
+	RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+	if (!radeon_output) {
+	    return FALSE;
+	}
+	radeon_output->MonType = MT_UNKNOWN;
+	radeon_output->DDCType = info->BiosConnector[i].DDCType;
+	radeon_output->DACType = info->BiosConnector[i].DACType;
+	radeon_output->TMDSType = info->BiosConnector[i].TMDSType;
+	radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
 	RADEONSetOutputType(pScrn, radeon_output);
+	output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+	if (!output) {
+	    return FALSE;
+	}
+	output->driver_private = radeon_output;
+	output->possible_crtcs = 1;
+	if (radeon_output->type != OUTPUT_LVDS)
+ 	    output->possible_crtcs |= 2;
 
-	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
-	/*if (!pRADEONEnt->pOutput[i])
-	  return FALSE;*/
-	
-	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
-	pRADEONEnt->PortInfo[i]->num = i;
+	output->possible_clones = 0 /*1|2*/;
 
-	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
-	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
- 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
+	RADEONInitConnector(output);
+    }
 
-	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
+    /* if it's a mobility make sure we have a LVDS port */
+    if (info->IsMobility) {
+	if (info->IsAtomBios) {
+	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_LVDS_ATOM &&
+		info->BiosConnector[1].ConnectorType != CONNECTOR_LVDS_ATOM) {
+		/* add LVDS port */
+		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+		if (!radeon_output) {
+		    return FALSE;
+		}
+		radeon_output->MonType = MT_UNKNOWN;
+		radeon_output->DDCType = DDC_LCD;
+		radeon_output->DACType = DAC_UNKNOWN;
+		radeon_output->TMDSType = TMDS_UNKNOWN;
+		radeon_output->ConnectorType = CONNECTOR_LVDS_ATOM;
+		RADEONSetOutputType(pScrn, radeon_output);
+		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+		if (!output) {
+		    return FALSE;
+		}
+		output->driver_private = radeon_output;
+		output->possible_crtcs = 1;
+		output->possible_clones = 0 /*1|2*/;
 
-	output = pRADEONEnt->pOutput[i];
+		RADEONInitConnector(output);
 
-	switch(radeon_output->DDCType) {
-	case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
-	case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
-	case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
-	case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
-	default: break;
-	}
+	    }
+	} else {
+	    if (info->BiosConnector[0].ConnectorType != CONNECTOR_PROPRIETARY &&
+		info->BiosConnector[1].ConnectorType != CONNECTOR_PROPRIETARY) {
+		/* add LVDS port */
+		RADEONOutputPrivatePtr radeon_output = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+		if (!radeon_output) {
+		    return FALSE;
+		}
+		radeon_output->MonType = MT_UNKNOWN;
+		radeon_output->DDCType = DDC_LCD;
+		radeon_output->DACType = DAC_UNKNOWN;
+		radeon_output->TMDSType = TMDS_UNKNOWN;
+		radeon_output->ConnectorType = CONNECTOR_PROPRIETARY;
+		RADEONSetOutputType(pScrn, radeon_output);
+		output = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[radeon_output->type]);
+		if (!output) {
+		    return FALSE;
+		}
+		output->driver_private = radeon_output;
+		output->possible_crtcs = 1;
+		output->possible_clones = 0 /*1|2*/;
 
-	if (DDCReg) {
-	    radeon_output->DDCReg = DDCReg;
-	    RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
+		RADEONInitConnector(output);
+	    }
 	}
+    }
+    return TRUE;
+}
 
-	if (radeon_output->type == OUTPUT_LVDS) {
-	    RADEONGetLVDSInfo(output);
-	}
+#if 0
+Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr      info = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    int i;
+
+    if (pRADEONEnt->pOutput[0])
+        return TRUE;
 
-	if (radeon_output->type == OUTPUT_DVI) {
-	    RADEONGetTMDSInfo(output);
+    /* for now always allocate max connectors */
+    for (i = 0 ; i < info->max_connectors; i++) {
 
-	    if (i == 0)
-		RADEONGetHardCodedEDIDFromBIOS(output);
+	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
+	if (!pRADEONEnt->pOutput[i])
+	    return FALSE;
+	
+	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
+	pRADEONEnt->PortInfo[i]->num = i;
 
-	    /*RADEONUpdatePanelSize(output);*/
-	}
+	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
+	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
+ 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
 
-	if (radeon_output->DACType == DAC_TVDAC) {
-	    RADEONGetTVDacAdjInfo(output);
-	}
+	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
     }
+
+    return TRUE;
 }
+#endif
 
 #if 0
 xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d5cd60e..a261d0d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -117,7 +117,7 @@ static Bool RADEONCloseScreen(int scrnIn
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
 static void RADEONSave(ScrnInfoPtr pScrn);
 //static void RADEONRestore(ScrnInfoPtr pScrn);
-static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
+//static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
 static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
 static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
@@ -2528,28 +2528,20 @@ static Bool RADEONPreInitControllers(Scr
 
     if (!info->IsSecondary) {
       
-      if (!RADEONAllocatePortInfo(pScrn))
-	return FALSE;
-
       if (!RADEONAllocateControllers(pScrn))
 	  return FALSE;
     }
 
-    /*    if (!info->IsSecondary) {
-      if (!RADEONAllocateConnectors(pScrn))
-	return FALSE;
-	}*/
-
     RADEONGetBIOSInfo(pScrn, pInt10);
 
-    RADEONSetupConnectors(pScrn);
+    if (!RADEONSetupConnectors(pScrn)) {
+	return FALSE;
+    }
 
       
     RADEONMapControllers(pScrn);
 
     RADEONGetClockInfo(pScrn);
-    /*    RADEONGetPanelInfo(pScrn);
-	  RADEONGetTVDacAdjInfo(pScrn);*/
 
     for (i = 0; i < config->num_output; i++) 
     {
@@ -4638,21 +4630,23 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
+// hack, but it's going away soon
 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[0];
     int i;
-    xf86OutputPtr output;
 
-    for (i = 0; i < info->max_connectors; i++) {
-        if (pRADEONEnt->PortInfo[i]->crtc_num == crtc_num) {
-	    output = pRADEONEnt->pOutput[i];
-            RADEONEnableDisplay(pScrn, output, TRUE);
-        }
+    /* get the output connected to this CRTC */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc) {
+	    RADEONEnableDisplay(pScrn, output, TRUE);
+	}
     }
-
 }
 
 /* Write out state to define a new video mode */
@@ -4702,7 +4696,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    RADEONRestorePLL2Registers(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
 	    RADEONRestoreDACRegisters(pScrn, restore);
-	    RADEONEnableOuputs(pScrn, 2);
+	    RADEONEnableOutputs(pScrn, 2);
 	} else {
 	    RADEONRestoreMemMapRegisters(pScrn, restore);
 	    RADEONRestoreCommonRegisters(pScrn, restore);
@@ -4715,9 +4709,9 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
             RADEONRestorePLLRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
 	    RADEONRestoreDACRegisters(pScrn, restore);
-	    RADEONEnableOuputs(pScrn, 1);
+	    RADEONEnableOutputs(pScrn, 1);
 	    if (pCRTC2->binding == 1) {
-	      RADEONEnableOuputs(pScrn, 2);
+	      RADEONEnableOutputs(pScrn, 2);
 	    }
 	}
     } else {
@@ -5454,15 +5448,18 @@ static void RADEONInitOutputRegisters(Sc
 }
 
 /* Define CRTC registers for requested video mode */
-Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+Bool RADEONInitCrtcRegisters(xf86CrtcPtr crtc, RADEONSavePtr save,
 				  DisplayModePtr mode, RADEONInfoPtr info)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     int    format;
     int    hsync_start;
     int    hsync_wid;
     int    vsync_wid;
     int i;
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
 
 
     switch (info->CurrentLayout.pixel_code) {
@@ -5599,19 +5596,12 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr
     }
 
     /* get the output connected to this CRTC */
-    for (i = 0; i < info->max_connectors; i++) {
-      if (pRADEONEnt->PortInfo[i]->crtc_num == 1) {
-	ErrorF("init output for crtc1\n");
-        RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 1);
-      }
-    }
-#if 0
-    if (pRADEONEnt->PortInfo[0]->crtc_num == 1) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 1);
-    } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 1);
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc) {
+	    RADEONInitOutputRegisters(pScrn, save, mode, output, 1);
+	}
     }
-#endif
 
     if (info->IsDellServer) {
 	save->dac2_cntl = info->SavedReg.dac2_cntl;
@@ -5634,19 +5624,18 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr
 }
 
 /* Define CRTC2 registers for requested video mode */
-Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+Bool RADEONInitCrtc2Registers(xf86CrtcPtr crtc, RADEONSavePtr save,
 				     DisplayModePtr mode, RADEONInfoPtr info)
 {
+    ScrnInfoPtr pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     int    format;
     int    hsync_start;
     int    hsync_wid;
     int    vsync_wid;
     int i;
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONInfoPtr info0 = NULL;
-
-    if (info->IsSecondary)
-	info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
 
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
@@ -5739,19 +5728,12 @@ Bool RADEONInitCrtc2Registers(ScrnInfoPt
     save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
 
     /* get the output connected to this CRTC */
-    for (i = 0; i < info->max_connectors; i++) {
-      if (pRADEONEnt->PortInfo[i]->crtc_num == 2) {
-	ErrorF("init output for crtc2\n");
-        RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 2);
-      }
-    }
-#if 0
-    if (pRADEONEnt->PortInfo[0]->crtc_num == 2) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 2);
-    } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 2);
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc) {
+	    RADEONInitOutputRegisters(pScrn, save, mode, output, 2);
+	}
     }
-#endif
 
     /* We must set SURFACE_CNTL properly on the second screen too */
     save->surface_cntl = 0;
@@ -5925,6 +5907,7 @@ static void RADEONInitPalette(RADEONSave
 }
 #endif
 
+#if 0
 /* Define registers for a requested video mode */
 Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
 		 DisplayModePtr crtc2, int crtc_mask,
@@ -6095,6 +6078,7 @@ static Bool RADEONModeInit(ScrnInfoPtr p
 
     return TRUE;
 }
+#endif
 
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode)
 {
@@ -6177,7 +6161,7 @@ Bool RADEONSwitchMode(int scrnIndex, Dis
 	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
     } else {
 	info->IsSwitching = TRUE;
-	ret = RADEONModeInit(xf86Screens[scrnIndex], mode);
+	ret = TRUE; //RADEONModeInit(xf86Screens[scrnIndex], mode);
 	info->IsSwitching = FALSE;
     }
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 9a4a52d..3e18b05 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -132,6 +132,13 @@ typedef struct _RADEONCrtcPrivateRec {
     Bool              UseBiosDividers;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
+typedef struct {
+    RADEONDDCType DDCType;
+    RADEONDacType DACType;
+    RADEONTmdsType TMDSType;
+    RADEONConnectorType ConnectorType;
+} RADEONBIOSConnector;
+
 typedef struct _RADEONOutputPrivateRec {
     int num;
     RADEONOutputType type;
@@ -160,8 +167,8 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONTMDSPll     tmds_pll[4];
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
-#define RADEON_MAX_CONNECTOR 3 /* actually 4: DVI/VGA, DVI on docks, TV, LVDS */
 #define RADEON_MAX_CRTC 2
+#define RADEON_MAX_BIOS_CONNECTOR 2
 
 typedef struct
 {
@@ -179,9 +186,6 @@ typedef struct
 
     Bool ReversedDAC;	  /* TVDAC used as primary dac */
     Bool ReversedTMDS;    /* DDC_DVI is used for external TMDS */
-    xf86OutputPtr pOutput[RADEON_MAX_CONNECTOR];
-    RADEONOutputPrivatePtr PortInfo[RADEON_MAX_CONNECTOR];
-
     xf86CrtcPtr pCrtc[RADEON_MAX_CRTC];
     RADEONCrtcPrivatePtr Controller[RADEON_MAX_CRTC];
 
diff-tree 7e5c29961ac2a9e9dbe5d6d2d73d11cd018d62b5 (from ab5603edd8fc3ef0560bdfb6a6d9c6af2a49d1e5)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 11 18:00:40 2007 +0200

    RADEON: Fix RMX after the last commit

diff --git a/src/radeon.h b/src/radeon.h
index 24d9878..e58747a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -426,8 +426,9 @@ typedef struct {
     Bool              R300CGWorkaround;
 
 				/* EDID or BIOS values for FPs */
-    /*    int               PanelXRes;
+    int               PanelXRes;
     int               PanelYRes;
+#if 0
     int               HOverPlus;
     int               HSyncWidth;
     int               HBlank;
@@ -436,7 +437,8 @@ typedef struct {
     int               VBlank;
     int               PanelPwrDly;
     int               DotClock;
-    */
+#endif
+    // move these to crtc priv rec
     int               RefDivider;
     int               FeedbackDivider;
     int               PostDivider;
diff --git a/src/radeon_display.c b/src/radeon_display.c
index f7a307b..c77ff64 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -695,6 +695,7 @@ static void RADEONGetPanelInfoFromReg (x
 	radeon_output->PanelYRes = 480;
     }
 
+    // move this to crtc function
     if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
            CARD32 ppll_div_sel, ppll_val;
 
@@ -703,10 +704,10 @@ static void RADEONGetPanelInfoFromReg (x
 	   ppll_val = INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel);
            if ((ppll_val & 0x000707ff) == 0x1bb)
 		   goto noprobe;
-	   radeon_output->FeedbackDivider = ppll_val & 0x7ff;
-	   radeon_output->PostDivider = (ppll_val >> 16) & 0x7;
-	   radeon_output->RefDivider = info->pll.reference_div;
-	   radeon_output->UseBiosDividers = TRUE;
+	   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");
@@ -733,7 +734,8 @@ static void RADEONUpdatePanelSize(xf86Ou
     xf86MonPtr      ddc  = pScrn->monitor->DDC;
     DisplayModePtr  p;
 
-    if ((radeon_output->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
+    // crtc should handle?
+    if ((info->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
        return;
 
     /* Go thru detailed timing table first */
@@ -758,7 +760,7 @@ static void RADEONUpdatePanelSize(xf86Ou
             */
 	    if (radeon_output->PanelXRes < d_timings->h_active &&
                radeon_output->PanelYRes < d_timings->v_active &&
-               !radeon_output->UseBiosDividers)
+               !info->UseBiosDividers)
                match = 1;
 
              if (match) {
@@ -784,7 +786,7 @@ static void RADEONUpdatePanelSize(xf86Ou
 	}
     }
 
-    if (radeon_output->UseBiosDividers && radeon_output->DotClock != 0)
+    if (info->UseBiosDividers && radeon_output->DotClock != 0)
        return;
 
     /* Search thru standard VESA modes from EDID */
@@ -2538,6 +2540,20 @@ radeon_mode_fixup(xf86OutputPtr output, 
 	mode->VDisplay < radeon_output->PanelYRes)
 	adjusted_mode->Flags |= RADEON_USE_RMX;
 
+    if (adjusted_mode->Flags & RADEON_USE_RMX) {
+	adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
+	adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
+	adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+	adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
+	adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
+	adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+	adjusted_mode->Clock          = radeon_output->DotClock;
+	adjusted_mode->Flags          = radeon_output->Flags | RADEON_USE_RMX;
+	/* save these for Xv with RMX */
+	info->PanelYRes = radeon_output->PanelYRes;
+	info->PanelXRes = radeon_output->PanelXRes;
+    }
+
     return TRUE;
 }
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 6f3ee7a..d5cd60e 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5529,21 +5529,6 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr
         save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
     }
 
-    // fix me, move to output
-    /*
-    if (mode->Flags & RADEON_USE_RMX) {
-      mode->CrtcHTotal     = mode->CrtcHDisplay + info->HBlank;
-      mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlus;
-      mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + info->HSyncWidth;
-      mode->CrtcVTotal     = mode->CrtcVDisplay + info->VBlank;
-      mode->CrtcVSyncStart = mode->CrtcVDisplay + info->VOverPlus;
-      mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + info->VSyncWidth;
-      mode->Clock          = info->DotClock;
-      mode->Flags          = info->Flags | RADEON_USE_RMX;
-    }
-    */
-
-
     save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
 			       | ((((mode->CrtcHDisplay / 8) - 1) & 0x1ff)
 				  << 16));
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index d2f9299..9a4a52d 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -126,6 +126,10 @@ typedef struct _RADEONCrtcPrivateRec {
     int binding;
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
+    int               RefDivider;
+    int               FeedbackDivider;
+    int               PostDivider;
+    Bool              UseBiosDividers;
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -153,10 +157,6 @@ typedef struct _RADEONOutputPrivateRec {
     int               Flags;            /* Saved copy of mode flags          */
     int               PanelPwrDly;
     int               DotClock;
-    int               RefDivider;
-    int               FeedbackDivider;
-    int               PostDivider;
-    Bool              UseBiosDividers;
     RADEONTMDSPll     tmds_pll[4];
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
diff --git a/src/radeon_video.c b/src/radeon_video.c
index a91cb36..97724eb 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2479,33 +2479,17 @@ RADEONDisplayVideo(
     v_inc_shift = 20;
     y_mult = 1;
 
-    /* TODO NO IDEA WHAT THIS IS ABOUT */
-    if (0) {//info->MergedFB) {
-	if (overlay_mode->Flags & V_INTERLACE)
-	    v_inc_shift++;
-    	if (overlay_mode->Flags & V_DBLSCAN) {
-	    v_inc_shift--;
-	    y_mult = 2;
-	}
-	// FIXME
-	/*    	if (overlay_mode->Flags & RADEON_USE_RMX) {
-	    v_inc = ((src_h * overlay_mode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
-	    } else {*/
-	    v_inc = (src_h << v_inc_shift) / drw_h;
-	    /*}*/
+    if (pScrn->currentMode->Flags & V_INTERLACE)
+	v_inc_shift++;
+    if (pScrn->currentMode->Flags & V_DBLSCAN) {
+	v_inc_shift--;
+	y_mult = 2;
+    }
+    // FIXME
+    if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
+	v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
     } else {
-	if (pScrn->currentMode->Flags & V_INTERLACE)
-	    v_inc_shift++;
-    	if (pScrn->currentMode->Flags & V_DBLSCAN) {
-	    v_inc_shift--;
-	    y_mult = 2;
-	}
-	// FIXME
-	/*    	if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
-	    v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
-	    } else {*/
-	    v_inc = (src_h << v_inc_shift) / drw_h;
-	    /*}*/
+	v_inc = (src_h << v_inc_shift) / drw_h;
     }
 
     h_inc = (1 << (12 + ecp_div));
diff-tree ab5603edd8fc3ef0560bdfb6a6d9c6af2a49d1e5 (from 94eb0681de0641e490f06486468617a727fefe86)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 11 17:34:35 2007 +0200

    RADEON: Move LVDS, TMDS, DAC properties to the output rec

diff --git a/src/radeon.h b/src/radeon.h
index 98ca96b..24d9878 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -380,11 +380,6 @@ typedef enum {
 } RADEONCardType;
 
 typedef struct {
-    CARD32 freq;
-    CARD32 value;
-}RADEONTMDSPll;
-
-typedef struct {
     EntityInfoPtr     pEnt;
     pciVideoPtr       PciInfo;
     PCITAG            PciTag;
@@ -416,7 +411,7 @@ typedef struct {
     unsigned long     FbMapSize;        /* Size of frame buffer, in bytes    */
     unsigned long     FbSecureSize;     /* Size of secured fb area at end of
                                            framebuffer */
-    int               Flags;            /* Saved copy of mode flags          */
+    /*int               Flags;*/            /* Saved copy of mode flags          */
 
     Bool              IsMobility;       /* Mobile chips for laptops */
     Bool              IsIGP;            /* IGP chips */
@@ -431,7 +426,7 @@ typedef struct {
     Bool              R300CGWorkaround;
 
 				/* EDID or BIOS values for FPs */
-    int               PanelXRes;
+    /*    int               PanelXRes;
     int               PanelYRes;
     int               HOverPlus;
     int               HSyncWidth;
@@ -441,6 +436,7 @@ typedef struct {
     int               VBlank;
     int               PanelPwrDly;
     int               DotClock;
+    */
     int               RefDivider;
     int               FeedbackDivider;
     int               PostDivider;
@@ -451,7 +447,7 @@ typedef struct {
     Bool              ddc2;
 
     RADEONPLLRec      pll;
-    RADEONTMDSPll     tmds_pll[4];
+    /*RADEONTMDSPll     tmds_pll[4];*/
     int               RamWidth;
     float	      sclk;		/* in MHz */
     float	      mclk;		/* in MHz */
@@ -839,9 +835,9 @@ extern void        RADEONPllErrataAfterD
 extern Bool        RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10);
 extern Bool        RADEONGetConnectorInfoFromBIOS (ScrnInfoPtr pScrn);
 extern Bool        RADEONGetClockInfoFromBIOS (ScrnInfoPtr pScrn);
-extern Bool        RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn);
-extern Bool        RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn);
-extern Bool        RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn);
+extern Bool        RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool        RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output);
+extern Bool        RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output);
 
 extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
 extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
@@ -851,7 +847,7 @@ extern Bool        RADEONMapControllers(
 extern void        RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable);
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
 extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
-extern void        RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn);
+extern void        RADEONGetTVDacAdjInfo(xf86OutputPtr output);
 extern void        RADEONUnblank(ScrnInfoPtr pScrn);
 extern void        RADEONBlank(ScrnInfoPtr pScrn);
 extern void        RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
@@ -863,7 +859,7 @@ extern xf86OutputPtr RADEONGetCrtcConnec
 extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 				  RADEONMonitorType DisplayType, int crtc2);
-extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList);
+extern int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 
 DisplayModePtr
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 76e0819..4b3ec56 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -398,36 +398,40 @@ Bool RADEONGetClockInfoFromBIOS (ScrnInf
     return TRUE;
 }
 
-Bool RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn)
+Bool RADEONGetLVDSInfoFromBIOS (xf86OutputPtr output)
 {
-    RADEONInfoPtr info     = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     unsigned long tmp, i;
 
+    ErrorF("grabbing LVDS from bios");
+
     if (!info->VBIOS) return FALSE;
 
     if (info->IsAtomBios) {
 	if((tmp = RADEON_BIOS16 (info->MasterDataStart + 16))) {
 
-	    info->PanelXRes = RADEON_BIOS16(tmp+6);
-	    info->PanelYRes = RADEON_BIOS16(tmp+10);
-	    info->DotClock   = RADEON_BIOS16(tmp+4)*10;
-	    info->HBlank     = RADEON_BIOS16(tmp+8);
-	    info->HOverPlus  = RADEON_BIOS16(tmp+14);
-	    info->HSyncWidth = RADEON_BIOS16(tmp+16);
-	    info->VBlank     = RADEON_BIOS16(tmp+12);
-	    info->VOverPlus  = RADEON_BIOS16(tmp+18);
-	    info->VSyncWidth = RADEON_BIOS16(tmp+20);
-	    info->PanelPwrDly = RADEON_BIOS16(tmp+40);
+	    radeon_output->PanelXRes = RADEON_BIOS16(tmp+6);
+	    radeon_output->PanelYRes = RADEON_BIOS16(tmp+10);
+	    radeon_output->DotClock   = RADEON_BIOS16(tmp+4)*10;
+	    radeon_output->HBlank     = RADEON_BIOS16(tmp+8);
+	    radeon_output->HOverPlus  = RADEON_BIOS16(tmp+14);
+	    radeon_output->HSyncWidth = RADEON_BIOS16(tmp+16);
+	    radeon_output->VBlank     = RADEON_BIOS16(tmp+12);
+	    radeon_output->VOverPlus  = RADEON_BIOS16(tmp+18);
+	    radeon_output->VSyncWidth = RADEON_BIOS16(tmp+20);
+	    radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+40);
 
-	    info->Flags = 0;
+	    radeon_output->Flags = 0;
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
 		       "LVDS Info:\n"
 		       "XRes: %d, YRes: %d, DotClock: %d\n"
 		       "HBlank: %d, HOverPlus: %d, HSyncWidth: %d\n"
 		       "VBlank: %d, VOverPlus: %d, VSyncWidth: %d\n",
-		       info->PanelXRes, info->PanelYRes, info->DotClock,
-		       info->HBlank,info->HOverPlus, info->HSyncWidth,
-		       info->VBlank, info->VOverPlus, info->VSyncWidth);
+		       radeon_output->PanelXRes, radeon_output->PanelYRes, radeon_output->DotClock,
+		       radeon_output->HBlank, radeon_output->HOverPlus, radeon_output->HSyncWidth,
+		       radeon_output->VBlank, radeon_output->VOverPlus, radeon_output->VSyncWidth);
 	} else {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "No LVDS Info Table found in BIOS!\n");
@@ -452,14 +456,14 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfo
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		       "Panel ID string: %s\n", stmp);
 
-	    info->PanelXRes = RADEON_BIOS16(tmp+25);
-	    info->PanelYRes = RADEON_BIOS16(tmp+27);
+	    radeon_output->PanelXRes = RADEON_BIOS16(tmp+25);
+	    radeon_output->PanelYRes = RADEON_BIOS16(tmp+27);
 	    xf86DrvMsg(0, X_INFO, "Panel Size from BIOS: %dx%d\n",
-		       info->PanelXRes, info->PanelYRes);
+		       radeon_output->PanelXRes, radeon_output->PanelYRes);
 	
-	    info->PanelPwrDly = RADEON_BIOS16(tmp+44);
-	    if (info->PanelPwrDly > 2000 || info->PanelPwrDly < 0)
-		info->PanelPwrDly = 2000;
+	    radeon_output->PanelPwrDly = RADEON_BIOS16(tmp+44);
+	    if (radeon_output->PanelPwrDly > 2000 || radeon_output->PanelPwrDly < 0)
+		radeon_output->PanelPwrDly = 2000;
 
 	    /* some panels only work well with certain divider combinations.
 	     */
@@ -480,20 +484,20 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfo
 	    for (i = 0; i < 32; i++) {
 		tmp0 = RADEON_BIOS16(tmp+64+i*2);
 		if (tmp0 == 0) break;
-		if ((RADEON_BIOS16(tmp0) == info->PanelXRes) &&
-		    (RADEON_BIOS16(tmp0+2) == info->PanelYRes)) {
-		    info->HBlank     = (RADEON_BIOS16(tmp0+17) -
+		if ((RADEON_BIOS16(tmp0) == radeon_output->PanelXRes) &&
+		    (RADEON_BIOS16(tmp0+2) == radeon_output->PanelYRes)) {
+		    radeon_output->HBlank     = (RADEON_BIOS16(tmp0+17) -
 					RADEON_BIOS16(tmp0+19)) * 8;
-		    info->HOverPlus  = (RADEON_BIOS16(tmp0+21) -
+		    radeon_output->HOverPlus  = (RADEON_BIOS16(tmp0+21) -
 					RADEON_BIOS16(tmp0+19) - 1) * 8;
-		    info->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
-		    info->VBlank     = (RADEON_BIOS16(tmp0+24) -
+		    radeon_output->HSyncWidth = RADEON_BIOS8(tmp0+23) * 8;
+		    radeon_output->VBlank     = (RADEON_BIOS16(tmp0+24) -
 					RADEON_BIOS16(tmp0+26));
-		    info->VOverPlus  = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
+		    radeon_output->VOverPlus  = ((RADEON_BIOS16(tmp0+28) & 0x7ff) -
 					RADEON_BIOS16(tmp0+26));
-		    info->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
-		    info->DotClock   = RADEON_BIOS16(tmp0+9) * 10;
-		    info->Flags = 0;
+		    radeon_output->VSyncWidth = ((RADEON_BIOS16(tmp0+28) & 0xf800) >> 11);
+		    radeon_output->DotClock   = RADEON_BIOS16(tmp0+9) * 10;
+		    radeon_output->Flags = 0;
 		}
 	    }
 	}
@@ -501,9 +505,11 @@ Bool RADEONGetLVDSInfoFromBIOS (ScrnInfo
     return TRUE;
 }
 
-Bool RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn)
+Bool RADEONGetHardCodedEDIDFromBIOS (xf86OutputPtr output)
 {
-    RADEONInfoPtr info     = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     unsigned long tmp;
     char EDID[256];
 
@@ -519,27 +525,31 @@ Bool RADEONGetHardCodedEDIDFromBIOS (Scr
 
 	memcpy(EDID, (char*)(info->VBIOS + tmp), 256);
 
-	info->DotClock = (*(CARD16*)(EDID+54)) * 10;
-	info->PanelXRes = (*(CARD8*)(EDID+56)) + ((*(CARD8*)(EDID+58))>>4)*256;
-	info->HBlank = (*(CARD8*)(EDID+57)) + ((*(CARD8*)(EDID+58)) & 0xf)*256;
-	info->HOverPlus = (*(CARD8*)(EDID+62)) + ((*(CARD8*)(EDID+65)>>6)*256);
-	info->HSyncWidth = (*(CARD8*)(EDID+63)) + (((*(CARD8*)(EDID+65)>>4) & 3)*256);
-	info->PanelYRes = (*(CARD8*)(EDID+59)) + ((*(CARD8*)(EDID+61))>>4)*256;
-	info->VBlank = ((*(CARD8*)(EDID+60)) + ((*(CARD8*)(EDID+61)) & 0xf)*256);
-	info->VOverPlus = (((*(CARD8*)(EDID+64))>>4) + (((*(CARD8*)(EDID+65)>>2) & 3)*16));
-	info->VSyncWidth = (((*(CARD8*)(EDID+64)) & 0xf) + ((*(CARD8*)(EDID+65)) & 3)*256);
-	info->Flags      = V_NHSYNC | V_NVSYNC; /**(CARD8*)(EDID+71);*/
+	radeon_output->DotClock = (*(CARD16*)(EDID+54)) * 10;
+	radeon_output->PanelXRes = (*(CARD8*)(EDID+56)) + ((*(CARD8*)(EDID+58))>>4)*256;
+	radeon_output->HBlank = (*(CARD8*)(EDID+57)) + ((*(CARD8*)(EDID+58)) & 0xf)*256;
+	radeon_output->HOverPlus = (*(CARD8*)(EDID+62)) + ((*(CARD8*)(EDID+65)>>6)*256);
+	radeon_output->HSyncWidth = (*(CARD8*)(EDID+63)) + (((*(CARD8*)(EDID+65)>>4) & 3)*256);
+	radeon_output->PanelYRes = (*(CARD8*)(EDID+59)) + ((*(CARD8*)(EDID+61))>>4)*256;
+	radeon_output->VBlank = ((*(CARD8*)(EDID+60)) + ((*(CARD8*)(EDID+61)) & 0xf)*256);
+	radeon_output->VOverPlus = (((*(CARD8*)(EDID+64))>>4) + (((*(CARD8*)(EDID+65)>>2) & 3)*16));
+	radeon_output->VSyncWidth = (((*(CARD8*)(EDID+64)) & 0xf) + ((*(CARD8*)(EDID+65)) & 3)*256);
+	radeon_output->Flags      = V_NHSYNC | V_NVSYNC; /**(CARD8*)(EDID+71);*/
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardcoded EDID data will be used for TMDS panel\n");
     }
     return TRUE;
 }
 
-Bool RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn)
+Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output)
 {
-    RADEONInfoPtr info     = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     CARD32 tmp, maxfreq;
     int i, n;
 
+    ErrorF("grabbing LVDS from bios");
+
     if (!info->VBIOS) return FALSE;
 
     if (info->IsAtomBios) {
@@ -548,18 +558,18 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfo
 	    maxfreq = RADEON_BIOS16(tmp+4);
 	    
 	    for (i=0; i<4; i++) {
-		info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
+		radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*6+6);
 		/* This assumes each field in TMDS_PLL has 6 bit as in R300/R420 */
-		info->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
+		radeon_output->tmds_pll[i].value = ((RADEON_BIOS8(tmp+i*6+8) & 0x3f) |
 					   ((RADEON_BIOS8(tmp+i*6+10) & 0x3f)<<6) |
 					   ((RADEON_BIOS8(tmp+i*6+9) & 0xf)<<12) |
 					   ((RADEON_BIOS8(tmp+i*6+11) & 0xf)<<16));
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 			   "TMDS PLL from BIOS: %ld %lx\n", 
-			   info->tmds_pll[i].freq, info->tmds_pll[i].value);
+			   radeon_output->tmds_pll[i].freq, radeon_output->tmds_pll[i].value);
 		       
-		if (maxfreq == info->tmds_pll[i].freq) {
-		    info->tmds_pll[i].freq = 0xffffffff;
+		if (maxfreq == radeon_output->tmds_pll[i].freq) {
+		    radeon_output->tmds_pll[i].freq = 0xffffffff;
 		    break;
 		}
 	    }
@@ -575,8 +585,8 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfo
 		n = RADEON_BIOS8(tmp + 5) + 1;
 		if (n > 4) n = 4;
 		for (i=0; i<n; i++) {
-		    info->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
-		    info->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
+		    radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+i*10+0x08);
+		    radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+i*10+0x10);
 		}
 		return TRUE;
 	    } else if (RADEON_BIOS8(tmp) == 4) {
@@ -584,8 +594,8 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfo
 		n = RADEON_BIOS8(tmp + 5) + 1;
 		if (n > 4) n = 4;
 		for (i=0; i<n; i++) {
-		    info->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
-		    info->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
+		    radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
+		    radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
 		    if (i == 0) stride += 10;
 		    else stride += 6;
 		}
@@ -600,8 +610,8 @@ Bool RADEONGetTMDSInfoFromBIOS (ScrnInfo
 		  n = RADEON_BIOS8(tmp + 5) + 1;
 		  if (n > 4) n = 4;
 		  for (i=0; i<n; i++) {
-		  info->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
-		  info->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
+		  radeon_output->tmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08);
+		  radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10);
 		  if (i == 0) stride += 10;
 		  else stride += 6;
 		  }
diff --git a/src/radeon_display.c b/src/radeon_display.c
index cebb2e6..f7a307b 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -669,28 +669,30 @@ static RADEONMonitorType RADEONDisplayDD
     return MonType;
 }
 
-static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn)
+static void RADEONGetPanelInfoFromReg (xf86OutputPtr output)
 {
-    RADEONInfoPtr info     = RADEONPTR(pScrn);
+    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);
 
-    info->PanelPwrDly = 200;
+    radeon_output->PanelPwrDly = 200;
     if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) {
-	info->PanelYRes = (fp_vert_stretch>>12) + 1;
+	radeon_output->PanelYRes = (fp_vert_stretch>>12) + 1;
     } else {
-	info->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
+	radeon_output->PanelYRes = (INREG(RADEON_CRTC_V_TOTAL_DISP)>>16) + 1;
     }
     if (fp_horz_stretch & RADEON_HORZ_STRETCH_ENABLE) {
-	info->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
+	radeon_output->PanelXRes = ((fp_horz_stretch>>16) + 1) * 8;
     } else {
-	info->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
+	radeon_output->PanelXRes = ((INREG(RADEON_CRTC_H_TOTAL_DISP)>>16) + 1) * 8;
     }
     
-    if ((info->PanelXRes < 640) || (info->PanelYRes < 480)) {
-	info->PanelXRes = 640;
-	info->PanelYRes = 480;
+    if ((radeon_output->PanelXRes < 640) || (radeon_output->PanelYRes < 480)) {
+	radeon_output->PanelXRes = 640;
+	radeon_output->PanelYRes = 480;
     }
 
     if (xf86ReturnOptValBool(info->Options, OPTION_LVDS_PROBE_PLL, TRUE)) {
@@ -701,10 +703,10 @@ static void RADEONGetPanelInfoFromReg (S
 	   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;
+	   radeon_output->FeedbackDivider = ppll_val & 0x7ff;
+	   radeon_output->PostDivider = (ppll_val >> 16) & 0x7;
+	   radeon_output->RefDivider = info->pll.reference_div;
+	   radeon_output->UseBiosDividers = TRUE;
 
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
                       "Existing panel PLL dividers will be used.\n");
@@ -714,21 +716,24 @@ static void RADEONGetPanelInfoFromReg (S
     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",
-	       info->PanelXRes, info->PanelYRes);
+	       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(ScrnInfoPtr pScrn)
+static void RADEONUpdatePanelSize(xf86OutputPtr output)
 {
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int             j;
-    RADEONInfoPtr   info = RADEONPTR (pScrn);
+    /* XXX: fixme */
     xf86MonPtr      ddc  = pScrn->monitor->DDC;
     DisplayModePtr  p;
 
-    if ((info->UseBiosDividers && info->DotClock != 0) || (ddc == NULL))
+    if ((radeon_output->UseBiosDividers && radeon_output->DotClock != 0) || (ddc == NULL))
        return;
 
     /* Go thru detailed timing table first */
@@ -743,49 +748,49 @@ static void RADEONUpdatePanelSize(ScrnIn
             * clock, or ValidateFPModes will fail, even when UseBiosDividers
             * is set.
             */
-           if (info->DotClock == 0 &&
-               info->PanelXRes == d_timings->h_active &&
-               info->PanelYRes == d_timings->v_active)
+           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 (info->PanelXRes < d_timings->h_active &&
-               info->PanelYRes < d_timings->v_active &&
-               !info->UseBiosDividers)
+	    if (radeon_output->PanelXRes < d_timings->h_active &&
+               radeon_output->PanelYRes < d_timings->v_active &&
+               !radeon_output->UseBiosDividers)
                match = 1;
 
              if (match) {
-		info->PanelXRes  = d_timings->h_active;
-		info->PanelYRes  = d_timings->v_active;
-		info->DotClock   = d_timings->clock / 1000;
-		info->HOverPlus  = d_timings->h_sync_off;
-		info->HSyncWidth = d_timings->h_sync_width;
-		info->HBlank     = d_timings->h_blanking;
-		info->VOverPlus  = d_timings->v_sync_off;
-		info->VSyncWidth = d_timings->v_sync_width;
-		info->VBlank     = d_timings->v_blanking;
-                info->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
+		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: info->Flags |= V_NHSYNC | V_NVSYNC; break;
-                case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break;
-                case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break;
-                case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break;
+                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",
-                           info->PanelXRes, info->PanelYRes);
+                           radeon_output->PanelXRes, radeon_output->PanelYRes);
 	    }
 	}
     }
 
-    if (info->UseBiosDividers && info->DotClock != 0)
+    if (radeon_output->UseBiosDividers && radeon_output->DotClock != 0)
        return;
 
     /* Search thru standard VESA modes from EDID */
     for (j = 0; j < 8; j++) {
-	if ((info->PanelXRes < ddc->timings2[j].hsize) &&
-	    (info->PanelYRes < ddc->timings2[j].vsize)) {
+	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)) {
@@ -794,18 +799,18 @@ static void RADEONUpdatePanelSize(ScrnIn
 
 		    if (abs((float)ddc->timings2[j].refresh - refresh) < 1.0) {
 			/* Is this good enough? */
-			info->PanelXRes  = ddc->timings2[j].hsize;
-			info->PanelYRes  = ddc->timings2[j].vsize;
-			info->HBlank     = p->HTotal - p->HDisplay;
-			info->HOverPlus  = p->HSyncStart - p->HDisplay;
-			info->HSyncWidth = p->HSyncEnd - p->HSyncStart;
-			info->VBlank     = p->VTotal - p->VDisplay;
-			info->VOverPlus  = p->VSyncStart - p->VDisplay;
-			info->VSyncWidth = p->VSyncEnd - p->VSyncStart;
-			info->DotClock   = p->Clock;
-                        info->Flags      = p->Flags;
+			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",
-                                   info->PanelXRes, info->PanelYRes);
+                                   radeon_output->PanelXRes, radeon_output->PanelYRes);
 		    }
 		}
 	    }
@@ -813,21 +818,25 @@ static void RADEONUpdatePanelSize(ScrnIn
     }
 }
 
-static Bool RADEONGetLVDSInfo (ScrnInfoPtr pScrn)
+static Bool RADEONGetLVDSInfo (xf86OutputPtr output)
 {
-    RADEONInfoPtr info     = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-    if (!RADEONGetLVDSInfoFromBIOS(pScrn))
-        RADEONGetPanelInfoFromReg(pScrn);
+    ErrorF("LVDS get info");
+
+    if (!RADEONGetLVDSInfoFromBIOS(output))
+        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(pScrn);
+    RADEONUpdatePanelSize(output);
 
-    if (info->DotClock == 0) {
+    if (radeon_output->DotClock == 0) {
 	RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
 	DisplayModePtr  tmp_mode = NULL;
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -840,27 +849,27 @@ static Bool RADEONGetLVDSInfo (ScrnInfoP
 	*/
 	tmp_mode = pScrn->monitor->Modes;
 	while(tmp_mode) {
-	    if ((tmp_mode->HDisplay == info->PanelXRes) &&
-		(tmp_mode->VDisplay == info->PanelYRes)) {
+	    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)) {
-		    info->HBlank     = tmp_mode->HTotal - tmp_mode->HDisplay;
-		    info->HOverPlus  = tmp_mode->HSyncStart - tmp_mode->HDisplay;
-		    info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
-		    info->VBlank     = tmp_mode->VTotal - tmp_mode->VDisplay;
-		    info->VOverPlus  = tmp_mode->VSyncStart - tmp_mode->VDisplay;
-		    info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
-		    info->DotClock   = tmp_mode->Clock;
-		    info->Flags = 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 ((info->DotClock == 0) && !pRADEONEnt->pOutput[0]->MonInfo) {
+	if ((radeon_output->DotClock == 0) && !pRADEONEnt->pOutput[0]->MonInfo) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Panel size is not correctly detected.\n"
 		       "Please try to use PanelSize option for correct settings.\n");
@@ -871,24 +880,27 @@ static Bool RADEONGetLVDSInfo (ScrnInfoP
     return TRUE;
 }
 
-static void RADEONGetTMDSInfo(ScrnInfoPtr pScrn)
+static void RADEONGetTMDSInfo(xf86OutputPtr output)
 {
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i;
 
     for (i=0; i<4; i++) {
-        info->tmds_pll[i].value = 0;
-        info->tmds_pll[i].freq = 0;
+        radeon_output->tmds_pll[i].value = 0;
+        radeon_output->tmds_pll[i].freq = 0;
     }
 
-    if (RADEONGetTMDSInfoFromBIOS(pScrn)) return;
+    if (RADEONGetTMDSInfoFromBIOS(output)) return;
 
     for (i=0; i<4; i++) {
-        info->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value;
-        info->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq;
+        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;
     }
 }
 
+#if 0
 void RADEONGetPanelInfo (ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info     = RADEONPTR(pScrn);
@@ -898,20 +910,23 @@ void RADEONGetPanelInfo (ScrnInfoPtr pSc
         info->PanelPwrDly = 200;
         if (sscanf (s, "%dx%d", &info->PanelXRes, &info->PanelYRes) != 2) {
             xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
-            RADEONGetPanelInfoFromReg(pScrn);
+            RADEONGetPanelInfoFromReg(output);
         }
     } 
 }
+#endif
 
-void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn)
+void RADEONGetTVDacAdjInfo(xf86OutputPtr output)
 {
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     
     /* Todo: get this setting from BIOS */
-    info->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
+    radeon_output->tv_dac_adj = default_tvdac_adj[info->ChipFamily];
     if (info->IsMobility) { /* some mobility chips may different */
 	if (info->ChipFamily == CHIP_FAMILY_RV250)
-	    info->tv_dac_adj = 0x00880000;
+	    radeon_output->tv_dac_adj = 0x00880000;
     }
 }
 
@@ -929,12 +944,15 @@ static void RADEONSwapOutputs(ScrnInfoPt
     pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
     pRADEONEnt->PortInfo[1] = conn_priv;
 }
+#if 0
 /*
  * initialise the static data sos we don't have to re-do at randr change */
 void RADEONSetupConnectors(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86OutputPtr output;
     const char *s;
     int i = 0, second = 0, max_mt = 5;
 
@@ -1137,45 +1155,60 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     }
 #endif
 
-    for (i = 0; i < info->max_connectors; i++) {
-      RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
+    //    for (i = 0; i < xf86_config->num_output; i++) {
+    for (i = 0 ; i < info->max_connectors; i++) {
+	RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
 
-      int DDCReg = 0;
-      char *names[] = { "DDC1", "DDC2", "DDC3" };
+	int DDCReg = 0;
+	char *names[] = { "DDC1", "DDC2", "DDC3" };
 
-      RADEONSetOutputType(pScrn, radeon_output);
-      switch(radeon_output->DDCType) {
-      case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
-      case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
-      case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
-      case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
-      default: break;
-      }
-      
-      if (DDCReg) {
-	radeon_output->DDCReg = DDCReg;
-	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
-      }
+	RADEONSetOutputType(pScrn, radeon_output);
 
-      if (radeon_output->type == OUTPUT_LVDS) {
-	RADEONGetLVDSInfo(pScrn);
-      }
+	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
+	if (!pRADEONEnt->pOutput[i])
+	    return FALSE;
+	
+	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
+	pRADEONEnt->PortInfo[i]->num = i;
 
-      if (radeon_output->type == OUTPUT_DVI) {
-	RADEONGetTMDSInfo(pScrn);
+	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
+	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
+ 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
 
-	if (i == 0)
-		RADEONGetHardCodedEDIDFromBIOS(pScrn);
+	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
 
-	/*RADEONUpdatePanelSize(pScrn);*/
+	switch(radeon_output->DDCType) {
+	case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+	case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
+	case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
+	case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+	default: break;
+	}
 
-      }
+	if (DDCReg) {
+	    radeon_output->DDCReg = DDCReg;
+	    RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
+	}
 
+	if (radeon_output->type == OUTPUT_LVDS) {
+	    RADEONGetLVDSInfo(output);
+	}
 
-    }
+	if (radeon_output->type == OUTPUT_DVI) {
+	    RADEONGetTMDSInfo(output);
 
-    
+	    if (i == 0)
+		RADEONGetHardCodedEDIDFromBIOS(output);
+
+	    /*RADEONUpdatePanelSize(output);*/
+	}
+
+	if (radeon_output->DACType == DAC_TVDAC) {
+	    RADEONGetTVDacAdjInfo(output);
+	}
+    }
 }
+#endif
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
@@ -1651,7 +1684,7 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
 	    ErrorF("read in LVDS reg\n");
             tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
-	    usleep (info->PanelPwrDly * 1000);
+	    usleep (radeon_output->PanelPwrDly * 1000);
             OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
 	    ErrorF("wrote out LVDS reg\n");
             save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
@@ -2135,7 +2168,7 @@ static void RADEONDPMSSetOn(xf86OutputPt
   switch(MonType) {
   case MT_LCD:
     OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON);
-    usleep (info->PanelPwrDly * 1000);
+    usleep (radeon_output->PanelPwrDly * 1000);
     OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_ON, ~RADEON_LVDS_ON);
     break;
   case MT_DFP:
@@ -2278,14 +2311,13 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     double         dot_clock = 0;
 
     for (i = 0; i < xf86_config->num_output; i++) {
-      xf86OutputPtr output = xf86_config->output[i];
-      RADEONOutputPrivatePtr radeon_output = output->driver_private;
+	xf86OutputPtr output = xf86_config->output[i];
+	RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-      if (output->crtc == crtc) {
-	montype = radeon_output->MonType;
-	radeon_output->crtc_num = radeon_crtc->crtc_id + 1;
-	ErrorF("using crtc: %d on output %s montype: %d\n", radeon_output->crtc_num, OutputType[radeon_output->type], montype);
-      }
+	if (output->crtc == crtc) {
+	    montype = radeon_output->MonType;
+	    radeon_output->crtc_num = radeon_crtc->crtc_id + 1;
+	}
     }
     
     ErrorF("init memmap\n");
@@ -2307,7 +2339,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
             info->ModeReg.htotal_cntl  = info->SavedReg.htotal_cntl;
         }
 	break;
-    case 1: 
+    case 1:
 	ErrorF("init crtc2\n");
         RADEONInitCrtc2Registers(pScrn, &info->ModeReg, adjusted_mode, info);
         dot_clock = adjusted_mode->Clock / 1000.0;
@@ -2484,8 +2516,8 @@ radeon_mode_valid(xf86OutputPtr output, 
     if (radeon_output->type != OUTPUT_LVDS)
 	return MODE_OK;
 
-    if (pMode->HDisplay > info->PanelXRes ||
-	pMode->VDisplay > info->PanelYRes)
+    if (pMode->HDisplay > radeon_output->PanelXRes ||
+	pMode->VDisplay > radeon_output->PanelYRes)
 	return MODE_PANEL;
 
     return MODE_OK;
@@ -2502,8 +2534,8 @@ radeon_mode_fixup(xf86OutputPtr output, 
     if (radeon_output->type != OUTPUT_LVDS)
 	return TRUE;
 
-    if (mode->HDisplay < info->PanelXRes ||
-	mode->VDisplay < info->PanelYRes)
+    if (mode->HDisplay < radeon_output->PanelXRes ||
+	mode->VDisplay < radeon_output->PanelYRes)
 	adjusted_mode->Flags |= RADEON_USE_RMX;
 
     return TRUE;
@@ -2707,7 +2739,7 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 
     if (pRADEONEnt->pOutput[0])
         return TRUE;
-    
+
     /* for now always allocate max connectors */
     for (i = 0 ; i < info->max_connectors; i++) {
 
@@ -2728,6 +2760,271 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
     return TRUE;
 }
 
+/*
+ * initialise the static data sos we don't have to re-do at randr change */
+void RADEONSetupConnectors(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86OutputPtr output;
+    const char *s;
+    int i = 0, second = 0, max_mt = 5;
+
+    /* We first get the information about all connectors from BIOS.
+     * This is how the card is phyiscally wired up.
+     * The information should be correct even on a OEM card.
+     * If not, we may have problem -- need to use MonitorLayout option.
+     */
+    for (i = 0; i < info->max_connectors; i++) {
+	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
+	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
+	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
+	pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN;
+	pRADEONEnt->PortInfo[i]->ConnectorType = CONNECTOR_NONE;
+    }
+
+    if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
+        ((pRADEONEnt->PortInfo[0]->DDCType == 0) &&
+        (pRADEONEnt->PortInfo[1]->DDCType == 0))) {
+	/* Below is the most common setting, but may not be true */
+	pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
+	pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI;
+	pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
+	pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
+	pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I;
+
+	pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
+	pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
+	pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
+	pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
+	pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
+
+
+       /* Some cards have the DDC lines swapped and we have no way to
+        * detect it yet (Mac cards)
+        */
+       if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
+           pRADEONEnt->PortInfo[0]->DDCType = DDC_VGA;
+           pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
+        }
+    }
+
+    /* always make TMDS_INT port first*/
+    if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) {
+	RADEONSwapOutputs(pScrn);
+    } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT &&
+                pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) {
+        /* no TMDS_INT port, make primary DAC port first */
+	/* On my Inspiron 8600 both internal and external ports are
+	   marked DAC_PRIMARY in BIOS. So be extra careful - only
+	   swap when the first port is not DAC_PRIMARY */
+        if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) &&  (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) &&
+	     (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) {
+	    RADEONSwapOutputs(pScrn);
+        }
+    }
+
+    if (info->HasSingleDAC) {
+        /* For RS300/RS350/RS400 chips, there is no primary DAC. Force VGA port to use TVDAC*/
+        if (pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_CRT) {
+            pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
+            pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
+        } else {
+            pRADEONEnt->PortInfo[1]->DACType = DAC_TVDAC;
+            pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
+        }
+    } else if (!pRADEONEnt->HasCRTC2) {
+        pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
+    }
+
+    /*
+     * MonitorLayout option takes a string for two monitors connected in following format:
+     * Option "MonitorLayout" "primary-port-display, secondary-port-display"
+     * primary and secondary port displays can have one of following:
+     *    NONE, CRT, LVDS, TMDS
+     * With this option, driver will bring up monitors as specified,
+     * not using auto-detection routines to probe monitors.
+     *
+     * This option can be used when the false monitor detection occurs.
+     *
+     * This option can also be used to disable one connected display.
+     * For example, if you have a laptop connected to an external CRT
+     * and you want to disable the internal LCD panel, you can specify
+     * Option "MonitorLayout" "NONE, CRT"
+     *
+     * This option can also used to disable Clone mode. One there is only
+     * one monitor is specified, clone mode will be turned off automatically
+     * even you have two monitors connected.
+     *
+     * Another usage of this option is you want to config the server
+     * to start up with a certain monitor arrangement even one monitor
+     * is not plugged in when server starts.
+     * For example, you can config your laptop with 
+     * Option "MonitorLayout" "LVDS, CRT"
+     * Option "CloneHSync" "40-150"
+     * Option "CloneVRefresh" "60-120"
+     * With these options, you can connect in your CRT monitor later
+     * after the X server has started.
+     */
+    if ((s = xf86GetOptValString(info->Options, OPTION_MONITOR_LAYOUT))) {
+        char s1[5], s2[5];
+        i = 0;
+        /* When using user specified monitor types, we will not do DDC detection
+         *
+         */
+        do {
+            switch(*s) {
+            case ',':
+                s1[i] = '\0';
+                i = 0;
+                second = 1;
+                break;
+            case ' ':
+            case '\t':
+            case '\n':
+            case '\r':
+                break;
+            default:
+                if (second)
+                    s2[i] = *s;
+                else
+                    s1[i] = *s;
+                i++;
+                break;
+            }
+            if (i > 4) i = 4;
+        } while(*s++);
+        s2[i] = '\0';
+
+        for (i = 0; i < max_mt; i++)
+        {
+            if (strcmp(s1, MonTypeName[i]) == 0) 
+            {
+                pRADEONEnt->PortInfo[0]->MonType = MonTypeID[i];
+                break;
+            }
+        }
+        if (i ==  max_mt)
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
+                       "Invalid Monitor type specified for 1st port \n"); 
+
+        for (i = 0; i < max_mt; i++)
+        {
+            if (strcmp(s2, MonTypeName[i]) == 0) 
+            {
+                pRADEONEnt->PortInfo[1]->MonType = MonTypeID[i];
+                break;
+            }
+
+        }
+        if (i ==  max_mt)
+            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
+                       "Invalid Monitor type specified for 2nd port \n"); 
+
+	if (i ==  max_mt)
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Invalid Monitor type specified for 2nd port \n");
+
+	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+		   "MonitorLayout Option: \n\tMonitor1--Type %s, Monitor2--Type %s\n\n", s1, s2);
+#if 0
+	if (pRADEONEnt->PortInfo[1]->MonType == MT_CRT) {
+	    pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
+	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
+	    pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
+	    pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_CRT;
+	    pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
+	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
+	    pRADEONEnt->PortInfo[0]->DDCType = DDC_NONE_DETECTED;
+	    pRADEONEnt->PortInfo[0]->ConnectorType = pRADEONEnt->PortInfo[0]->MonType+1;
+	    pRADEONEnt->PortInfo[0]->MonInfo = NULL;
+        }
+#endif
+
+        /* some thinkpads and powerbooks use lvds and internal tmds 
+	 * at the same time.  --AGD
+	 */
+	if ((pRADEONEnt->PortInfo[0]->MonType  == MT_LCD) &&
+	    (pRADEONEnt->PortInfo[1]->MonType == MT_DFP)) {
+	    pRADEONEnt->PortInfo[1]->DDCType = DDC_DVI;
+	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
+            pRADEONEnt->PortInfo[1]->TMDSType = TMDS_INT;
+            pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I;
+            pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
+	}
+    }
+
+#if 1
+    if (info->IsMobility) {
+        pRADEONEnt->PortInfo[2]->DDCType = DDC_DVI;
+        pRADEONEnt->PortInfo[2]->TMDSType = TMDS_INT;
+        pRADEONEnt->PortInfo[2]->ConnectorType = CONNECTOR_DVI_D;
+        pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
+	if (pRADEONEnt->PortInfo[0]->DDCType == DDC_DVI) {
+	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
+	}
+	if (pRADEONEnt->PortInfo[0]->TMDSType == TMDS_INT) {
+	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
+	}
+    }
+#endif
+
+    //    for (i = 0; i < xf86_config->num_output; i++) {
+    for (i = 0 ; i < info->max_connectors; i++) {
+	RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
+
+	int DDCReg = 0;
+	char *names[] = { "DDC1", "DDC2", "DDC3" };
+
+	RADEONSetOutputType(pScrn, radeon_output);
+
+	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
+	/*if (!pRADEONEnt->pOutput[i])
+	  return FALSE;*/
+	
+	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
+	pRADEONEnt->PortInfo[i]->num = i;
+
+	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
+	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
+ 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
+
+	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
+
+	output = pRADEONEnt->pOutput[i];
+
+	switch(radeon_output->DDCType) {
+	case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+	case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
+	case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
+	case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+	default: break;
+	}
+
+	if (DDCReg) {
+	    radeon_output->DDCReg = DDCReg;
+	    RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
+	}
+
+	if (radeon_output->type == OUTPUT_LVDS) {
+	    RADEONGetLVDSInfo(output);
+	}
+
+	if (radeon_output->type == OUTPUT_DVI) {
+	    RADEONGetTMDSInfo(output);
+
+	    if (i == 0)
+		RADEONGetHardCodedEDIDFromBIOS(output);
+
+	    /*RADEONUpdatePanelSize(output);*/
+	}
+
+	if (radeon_output->DACType == DAC_TVDAC) {
+	    RADEONGetTVDacAdjInfo(output);
+	}
+    }
+}
 
 #if 0
 xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 2afe4dc..6f3ee7a 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2532,23 +2532,24 @@ static Bool RADEONPreInitControllers(Scr
 	return FALSE;
 
       if (!RADEONAllocateControllers(pScrn))
-	return FALSE;
+	  return FALSE;
     }
 
+    /*    if (!info->IsSecondary) {
+      if (!RADEONAllocateConnectors(pScrn))
+	return FALSE;
+	}*/
+
     RADEONGetBIOSInfo(pScrn, pInt10);
 
     RADEONSetupConnectors(pScrn);
 
-    if (!info->IsSecondary) {
-      if (!RADEONAllocateConnectors(pScrn))
-	return FALSE;
-    }
       
     RADEONMapControllers(pScrn);
 
     RADEONGetClockInfo(pScrn);
-    RADEONGetPanelInfo(pScrn);
-    RADEONGetTVDacAdjInfo(pScrn);
+    /*    RADEONGetPanelInfo(pScrn);
+	  RADEONGetTVDacAdjInfo(pScrn);*/
 
     for (i = 0; i < config->num_output; i++) 
     {
@@ -5170,18 +5171,20 @@ static void RADEONInitTvDacCntl(ScrnInfo
 			 info->tv_dac_adj);
 }
 
-static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+static void RADEONInitFPRegisters(xf86OutputPtr output, RADEONSavePtr save,
 				  DisplayModePtr mode, BOOL IsPrimary)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(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 (info->tmds_pll[i].freq == 0) break;
-	if ((CARD32)(mode->Clock/10) < info->tmds_pll[i].freq) {
-	    tmp = info->tmds_pll[i].value ;
+	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;
 	}
     }
@@ -5232,10 +5235,12 @@ static void RADEONInitFPRegisters(ScrnIn
 
 }
 
-static void RADEONInitFP2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+static void RADEONInitFP2Registers(xf86OutputPtr output, RADEONSavePtr save,
 				   DisplayModePtr mode, BOOL IsPrimary)
 {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+
 
     if (pScrn->rgbBits == 8) 
 	save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
@@ -5279,10 +5284,12 @@ static void RADEONInitFP2Registers(ScrnI
 
 }
 
-static void RADEONInitLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+static void RADEONInitLVDSRegisters(xf86OutputPtr output, RADEONSavePtr save,
 				    DisplayModePtr mode, BOOL IsPrimary)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
+
 /* XXX saved but never used??? */
     if (IsPrimary)
 	save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl &
@@ -5293,24 +5300,25 @@ static void RADEONInitLVDSRegisters(Scrn
 
 }
 
-static void RADEONInitRMXRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+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 (info->PanelXRes == 0 || info->PanelYRes == 0) {
+    if (radeon_output->PanelXRes == 0 || radeon_output->PanelYRes == 0) {
 	Hratio = 1.0;
 	Vratio = 1.0;
     } else {
-	if (xres > info->PanelXRes) xres = info->PanelXRes;
-	if (yres > info->PanelYRes) yres = info->PanelYRes;
+	if (xres > radeon_output->PanelXRes) xres = radeon_output->PanelXRes;
+	if (yres > radeon_output->PanelYRes) yres = radeon_output->PanelYRes;
 	    
-	Hratio = (float)xres/(float)info->PanelXRes;
-	Vratio = (float)yres/(float)info->PanelYRes;
+	Hratio = (float)xres/(float)radeon_output->PanelXRes;
+	Vratio = (float)yres/(float)radeon_output->PanelYRes;
     }
 
 	save->fp_vert_stretch = info->SavedReg.fp_vert_stretch &
@@ -5326,7 +5334,7 @@ static void RADEONInitRMXRegisters(ScrnI
 				     0.5)) & RADEON_HORZ_STRETCH_RATIO_MASK) |
 				    RADEON_HORZ_STRETCH_BLEND |
 				    RADEON_HORZ_STRETCH_ENABLE |
-				    ((info->PanelXRes/8-1)<<16));
+				    ((radeon_output->PanelXRes/8-1)<<16));
     }
 
     if (Vratio == 1.0 || !(mode->Flags & RADEON_USE_RMX)) {
@@ -5336,14 +5344,15 @@ static void RADEONInitRMXRegisters(ScrnI
 						0.5)) & RADEON_VERT_STRETCH_RATIO_MASK) |
 				      RADEON_VERT_STRETCH_ENABLE |
 				      RADEON_VERT_STRETCH_BLEND |
-				      ((info->PanelYRes-1)<<12));
+				      ((radeon_output->PanelYRes-1)<<12));
     }
 
 }
 
-static void RADEONInitDACRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+static void RADEONInitDACRegisters(xf86OutputPtr output, RADEONSavePtr save,
 				  DisplayModePtr mode, BOOL IsPrimary)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
 
     if (IsPrimary) {
@@ -5367,9 +5376,10 @@ static void RADEONInitDACRegisters(ScrnI
 		      | (info->dac6bits ? 0 : RADEON_DAC_8BIT_EN));
 }
 
-static void RADEONInitDAC2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+static void RADEONInitDAC2Registers(xf86OutputPtr output, RADEONSavePtr save,
 				  DisplayModePtr mode, BOOL IsPrimary)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
 
     /*0x0028023;*/
@@ -5424,21 +5434,21 @@ static void RADEONInitOutputRegisters(Sc
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     if (radeon_output->MonType == MT_CRT) {
 	if (radeon_output->DACType == DAC_PRIMARY) {
-	    RADEONInitDACRegisters(pScrn, save, mode, IsPrimary);
+	    RADEONInitDACRegisters(output, save, mode, IsPrimary);
 	} else {
-	    RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary);
+	    RADEONInitDAC2Registers(output, save, mode, IsPrimary);
 	}
     } else if (radeon_output->MonType == MT_LCD) {
 	if (crtc_num == 1)
-	    RADEONInitRMXRegisters(pScrn, save, mode);
-	RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary);
+	    RADEONInitRMXRegisters(output, save, mode);
+	RADEONInitLVDSRegisters(output, save, mode, IsPrimary);
     } else if (radeon_output->MonType == MT_DFP) {
 	if (crtc_num == 1)
-	    RADEONInitRMXRegisters(pScrn, save, mode);
+	    RADEONInitRMXRegisters(output, save, mode);
 	if (radeon_output->TMDSType == TMDS_INT) {
-	    RADEONInitFPRegisters(pScrn, save, mode, IsPrimary);
+	    RADEONInitFPRegisters(output, save, mode, IsPrimary);
 	} else {
-	    RADEONInitFP2Registers(pScrn, save, mode, IsPrimary);
+	    RADEONInitFP2Registers(output, save, mode, IsPrimary);
 	}
     }
 }
@@ -5519,6 +5529,8 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr
         save->crtc_more_cntl |= RADEON_CRTC_H_CUTOFF_ACTIVE_EN;
     }
 
+    // fix me, move to output
+    /*
     if (mode->Flags & RADEON_USE_RMX) {
       mode->CrtcHTotal     = mode->CrtcHDisplay + info->HBlank;
       mode->CrtcHSyncStart = mode->CrtcHDisplay + info->HOverPlus;
@@ -5529,7 +5541,7 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr
       mode->Clock          = info->DotClock;
       mode->Flags          = info->Flags | RADEON_USE_RMX;
     }
-
+    */
 
 
     save->crtc_h_total_disp = ((((mode->CrtcHTotal / 8) - 1) & 0x3ff)
@@ -5997,8 +6009,8 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
     }
 #endif
 
-    if (crtc1 && (crtc_mask & 1))
-        info->Flags = crtc1->Flags;
+    /*    if (crtc1 && (crtc_mask & 1))
+	  info->Flags = crtc1->Flags;*/
 
     RADEONInitMemMapRegisters(pScrn, save, info);
     RADEONInitCommonRegisters(save, info);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 46680e3..4555856 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -79,32 +79,34 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
 /* This is used only when no mode is specified for FP and no ddc is
  * available.  We force it to native mode, if possible.
  */
-static DisplayModePtr RADEONFPNativeMode(ScrnInfoPtr pScrn)
+static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
 {
-    RADEONInfoPtr   info  = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr  new   = NULL;
     char            stmp[32];
 
-    if (info->PanelXRes != 0 &&
-	info->PanelYRes != 0 &&
-	info->DotClock != 0) {
+    if (radeon_output->PanelXRes != 0 &&
+	radeon_output->PanelYRes != 0 &&
+	radeon_output->DotClock != 0) {
 
 	/* Add native panel size */
 	new             = xnfcalloc(1, sizeof (DisplayModeRec));
-	sprintf(stmp, "%dx%d", info->PanelXRes, info->PanelYRes);
+	sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes);
 	new->name       = xnfalloc(strlen(stmp) + 1);
 	strcpy(new->name, stmp);
-	new->HDisplay   = info->PanelXRes;
-	new->VDisplay   = info->PanelYRes;
+	new->HDisplay   = radeon_output->PanelXRes;
+	new->VDisplay   = radeon_output->PanelYRes;
 
-	new->HTotal     = new->HDisplay + info->HBlank;
-	new->HSyncStart = new->HDisplay + info->HOverPlus;
-	new->HSyncEnd   = new->HSyncStart + info->HSyncWidth;
-	new->VTotal     = new->VDisplay + info->VBlank;
-	new->VSyncStart = new->VDisplay + info->VOverPlus;
-	new->VSyncEnd   = new->VSyncStart + info->VSyncWidth;
+	new->HTotal     = new->HDisplay + radeon_output->HBlank;
+	new->HSyncStart = new->HDisplay + radeon_output->HOverPlus;
+	new->HSyncEnd   = new->HSyncStart + radeon_output->HSyncWidth;
+	new->VTotal     = new->VDisplay + radeon_output->VBlank;
+	new->VSyncStart = new->VDisplay + radeon_output->VOverPlus;
+	new->VSyncEnd   = new->VSyncStart + radeon_output->VSyncWidth;
 
-	new->Clock      = info->DotClock;
+	new->Clock      = radeon_output->DotClock;
 	new->Flags      = 0;
 	new->type       = M_T_USERDEF;
 
@@ -112,9 +114,9 @@ static DisplayModePtr RADEONFPNativeMode
 	new->prev       = NULL;
 
 	pScrn->display->virtualX =
-	    pScrn->virtualX = MAX(pScrn->virtualX, info->PanelXRes);
+	    pScrn->virtualX = MAX(pScrn->virtualX, radeon_output->PanelXRes);
 	pScrn->display->virtualY =
-	    pScrn->virtualY = MAX(pScrn->virtualY, info->PanelYRes);
+	    pScrn->virtualY = MAX(pScrn->virtualY, radeon_output->PanelYRes);
 
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "No valid mode specified, force to native mode\n");
@@ -125,9 +127,11 @@ static DisplayModePtr RADEONFPNativeMode
 
 /* FP mode initialization routine for using on-chip RMX to scale
  */
-int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList)
+int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList)
 {
-    RADEONInfoPtr   info       = RADEONPTR(pScrn);
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr  last       = NULL;
     DisplayModePtr  new        = NULL;
     DisplayModePtr  first      = NULL;
@@ -150,13 +154,13 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 	 * need the internal RMX unit in the video chips (and there is
 	 * only one per card), this will only apply to the primary head.
 	 */
-	if (width < 320 || width > info->PanelXRes ||
-	    height < 200 || height > info->PanelYRes) {
+	if (width < 320 || width > radeon_output->PanelXRes ||
+	    height < 200 || height > radeon_output->PanelYRes) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "Mode %s is out of range.\n", ppModeName[i]);
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "Valid modes must be between 320x200-%dx%d\n",
-		       info->PanelXRes, info->PanelYRes);
+		       radeon_output->PanelXRes, radeon_output->PanelYRes);
 	    continue;
 	}
 
@@ -169,17 +173,17 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 	/* These values are effective values after expansion They are
 	 * not really used to set CRTC registers.
 	 */
-	new->HTotal     = info->PanelXRes + info->HBlank;
-	new->HSyncStart = info->PanelXRes + info->HOverPlus;
-	new->HSyncEnd   = new->HSyncStart + info->HSyncWidth;
-	new->VTotal     = info->PanelYRes + info->VBlank;
-	new->VSyncStart = info->PanelYRes + info->VOverPlus;
-	new->VSyncEnd   = new->VSyncStart + info->VSyncWidth;
-	new->Clock      = info->DotClock;
+	new->HTotal     = radeon_output->PanelXRes + radeon_output->HBlank;
+	new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+	new->HSyncEnd   = new->HSyncStart + radeon_output->HSyncWidth;
+	new->VTotal     = radeon_output->PanelYRes + radeon_output->VBlank;
+	new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+	new->VSyncEnd   = new->VSyncStart + radeon_output->VSyncWidth;
+	new->Clock      = radeon_output->DotClock;
 	new->Flags     |= RADEON_USE_RMX;
 
 #ifdef M_T_PREFERRED
-	if (width == info->PanelXRes && height == info->PanelYRes)
+	if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes)
 	  new->type |= M_T_PREFERRED;
 #endif
 
@@ -203,13 +207,13 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 
     /* If all else fails, add the native mode */
     if (!count) {
-	first = last = RADEONFPNativeMode(pScrn);
+	first = last = RADEONFPNativeMode(output);
 	if (first) count = 1;
     }
 
     /* add in all default vesa modes smaller than panel size, used for randr*/
     for (p = *modeList; p && p->next; p = p->next->next) {
-	if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) {
+	if ((p->HDisplay <= radeon_output->PanelXRes) && (p->VDisplay <= radeon_output->PanelYRes)) {
 	    tmp = first;
 	    while (tmp) {
 		if ((p->HDisplay == tmp->HDisplay) && (p->VDisplay == tmp->VDisplay)) break;
@@ -225,13 +229,13 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 		/* These values are effective values after expansion They are
 		 * not really used to set CRTC registers.
 		 */
-		new->HTotal     = info->PanelXRes + info->HBlank;
-		new->HSyncStart = info->PanelXRes + info->HOverPlus;
-		new->HSyncEnd   = new->HSyncStart + info->HSyncWidth;
-		new->VTotal     = info->PanelYRes + info->VBlank;
-		new->VSyncStart = info->PanelYRes + info->VOverPlus;
-		new->VSyncEnd   = new->VSyncStart + info->VSyncWidth;
-		new->Clock      = info->DotClock;
+		new->HTotal     = radeon_output->PanelXRes + radeon_output->HBlank;
+		new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+		new->HSyncEnd   = new->HSyncStart + radeon_output->HSyncWidth;
+		new->VTotal     = radeon_output->PanelYRes + radeon_output->VBlank;
+		new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+		new->VSyncEnd   = new->VSyncStart + radeon_output->VSyncWidth;
+		new->Clock      = radeon_output->DotClock;
 		new->Flags     |= RADEON_USE_RMX;
 
 		new->type      |= M_T_DEFAULT;
@@ -310,7 +314,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
       if (modes == NULL) {
 	MonRec fixed_mon;
 
-	RADEONValidateFPModes(pScrn, pScrn->display->modes, &modes);
+	RADEONValidateFPModes(output, pScrn->display->modes, &modes);
       }
     }
     
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 541a910..d2f9299 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -106,6 +106,11 @@ typedef enum
     TMDS_EXT     = 1
 } RADEONTmdsType;
 
+typedef struct {
+    CARD32 freq;
+    CARD32 value;
+}RADEONTMDSPll;
+
 typedef enum
 {
     OUTPUT_NONE,
@@ -135,6 +140,24 @@ typedef struct _RADEONOutputPrivateRec {
     int crtc_num;
     int DDCReg;
     I2CBusPtr         pI2CBus;
+    CARD32            tv_dac_adj;
+    /* panel stuff */
+    int               PanelXRes;
+    int               PanelYRes;
+    int               HOverPlus;
+    int               HSyncWidth;
+    int               HBlank;
+    int               VOverPlus;
+    int               VSyncWidth;
+    int               VBlank;
+    int               Flags;            /* Saved copy of mode flags          */
+    int               PanelPwrDly;
+    int               DotClock;
+    int               RefDivider;
+    int               FeedbackDivider;
+    int               PostDivider;
+    Bool              UseBiosDividers;
+    RADEONTMDSPll     tmds_pll[4];
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 #define RADEON_MAX_CONNECTOR 3 /* actually 4: DVI/VGA, DVI on docks, TV, LVDS */
diff --git a/src/radeon_video.c b/src/radeon_video.c
index d080982..a91cb36 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2487,11 +2487,12 @@ RADEONDisplayVideo(
 	    v_inc_shift--;
 	    y_mult = 2;
 	}
-    	if (overlay_mode->Flags & RADEON_USE_RMX) {
+	// FIXME
+	/*    	if (overlay_mode->Flags & RADEON_USE_RMX) {
 	    v_inc = ((src_h * overlay_mode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
-    	} else {
+	    } else {*/
 	    v_inc = (src_h << v_inc_shift) / drw_h;
-    	}
+	    /*}*/
     } else {
 	if (pScrn->currentMode->Flags & V_INTERLACE)
 	    v_inc_shift++;
@@ -2499,11 +2500,12 @@ RADEONDisplayVideo(
 	    v_inc_shift--;
 	    y_mult = 2;
 	}
-    	if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
+	// FIXME
+	/*    	if (pScrn->currentMode->Flags & RADEON_USE_RMX) {
 	    v_inc = ((src_h * pScrn->currentMode->CrtcVDisplay / info->PanelYRes) << v_inc_shift) / drw_h;
-    	} else {
+	    } else {*/
 	    v_inc = (src_h << v_inc_shift) / drw_h;
-    	}
+	    /*}*/
     }
 
     h_inc = (1 << (12 + ecp_div));
diff-tree 94eb0681de0641e490f06486468617a727fefe86 (from 673ede5578d5d9caf2adf0445fe1e684b034eea5)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 11 14:39:48 2007 +0200

    RADEON: switch output dpms to use RADEONEnableDisplay()

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 66cc307..cebb2e6 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1714,7 +1714,6 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
 	    }
         }
     }
-    ErrorF("finished output enable\n");
 }
 
 /* Calculate display buffer watermark to prevent buffer underflow */
@@ -2217,10 +2216,6 @@ radeon_crtc_dpms(xf86CrtcPtr crtc, int m
     
   mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
 
-  if (radeon_crtc->crtc_id)
-      ErrorF("crtc2 mode: %d", mode);
-  else
-      ErrorF("crtc1 mode: %d", mode);
 
   switch(mode) {
   case DPMSModeOn:
@@ -2334,34 +2329,21 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
 	ErrorF("restore crtc1\n");
 	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
-	/*	ErrorF("restore FP1\n");
-	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore dac\n");
-	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore pll1\n");*/
+	ErrorF("restore pll1\n");
 	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
-	/*	ErrorF("enable 1\n");
-		RADEONEnableOutputs(pScrn, 1);*/
 	break;
     case 1:
 	ErrorF("adjustframe 2\n");
 	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
 	ErrorF("restore crtc2\n");
 	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
-	/*	ErrorF("restore fp2\n");
-	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore dac2\n");
-	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);*/
 	ErrorF("restore pll2\n");
 	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
-	/*	ErrorF("enable 2\n");
-		RADEONEnableOutputs(pScrn, 2);*/
 	break;
     }
 
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
-    ErrorF("bandwidth set\n");
 
 }
 
@@ -2463,15 +2445,19 @@ static const xf86CrtcFuncsRec radeon_crt
 static void
 radeon_dpms(xf86OutputPtr output, int mode)
 {
+    ScrnInfoPtr	pScrn = output->scrn;
+
     switch(mode) {
     case DPMSModeOn:
-      RADEONDPMSSetOn(output);
-      break;
+	RADEONEnableDisplay(pScrn, output, TRUE);
+	/*      RADEONDPMSSetOn(output);*/
+	break;
     case DPMSModeOff:
     case DPMSModeSuspend:
     case DPMSModeStandby:
-      RADEONDPMSSetOff(output);
-      break;
+	RADEONEnableDisplay(pScrn, output, FALSE);
+	/*RADEONDPMSSetOff(output);*/
+	break;
     }
 }
 
diff-tree 673ede5578d5d9caf2adf0445fe1e684b034eea5 (from 0070a7d787adaae99f7bc2659be4b0f49f439db5)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 11 14:28:17 2007 +0200

    RADEON: re-arrange output mode setting

diff --git a/src/radeon_display.c b/src/radeon_display.c
index c9699ca..66cc307 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2311,7 +2311,6 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
             info->ModeReg.ppll_div_3   = info->SavedReg.ppll_div_3;
             info->ModeReg.htotal_cntl  = info->SavedReg.htotal_cntl;
         }
-	/*RADEONInit2(pScrn, adjusted_mode, NULL, 1, &info->ModeReg, montype);*/
 	break;
     case 1: 
 	ErrorF("init crtc2\n");
@@ -2321,7 +2320,6 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	    ErrorF("init pll2\n");
 	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, montype != MT_CRT);
         }
-	/*RADEONInit2(pScrn, NULL, adjusted_mode, 2, &info->ModeReg, montype);*/
 	break;
     }
     
@@ -2336,28 +2334,28 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
 	ErrorF("restore crtc1\n");
 	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore FP1\n");
+	/*	ErrorF("restore FP1\n");
 	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
 	ErrorF("restore dac\n");
 	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
-	ErrorF("restore pll1\n");
+	ErrorF("restore pll1\n");*/
 	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
-	ErrorF("enable 1\n");
-	RADEONEnableOutputs(pScrn, 1);
+	/*	ErrorF("enable 1\n");
+		RADEONEnableOutputs(pScrn, 1);*/
 	break;
     case 1:
 	ErrorF("adjustframe 2\n");
 	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
 	ErrorF("restore crtc2\n");
 	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
-	ErrorF("restore fp2\n");
+	/*	ErrorF("restore fp2\n");
 	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
 	ErrorF("restore dac2\n");
-	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);*/
 	ErrorF("restore pll2\n");
 	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
-	ErrorF("enable 2\n");
-	RADEONEnableOutputs(pScrn, 2);
+	/*	ErrorF("enable 2\n");
+		RADEONEnableOutputs(pScrn, 2);*/
 	break;
     }
 
@@ -2535,10 +2533,21 @@ radeon_mode_set(xf86OutputPtr output, Di
 		  DisplayModePtr adjusted_mode)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    
-    //    RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], );
+
+    switch(radeon_output->MonType) {
+    case MT_LCD:
+    case MT_DFP:
+	ErrorF("restore FP\n");
+	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+	break;
+    default:
+	ErrorF("restore dac\n");
+	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+    }
+
+    RADEONEnableDisplay(pScrn, output, TRUE);
 }
 
 static void
diff-tree 0070a7d787adaae99f7bc2659be4b0f49f439db5 (from bba456232ac9a6218aa7fbd504d6093fa72860cf)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Fri May 11 13:06:15 2007 +0200

    RADEON: more re-org
    
    - move crtc mode setting around
    - add dri lock/unlock to crtc lock/unlock calls

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 3c75149..c9699ca 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2267,6 +2267,7 @@ radeon_crtc_mode_fixup(xf86CrtcPtr crtc,
 static void
 radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
 {
+    radeon_crtc_dpms(crtc, DPMSModeOff);
 }
 
 static void
@@ -2323,9 +2324,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	/*RADEONInit2(pScrn, NULL, adjusted_mode, 2, &info->ModeReg, montype);*/
 	break;
     }
-
-    radeon_crtc_dpms(crtc, DPMSModeOff);
-
+    
     ErrorF("restore memmap\n");
     RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
     ErrorF("restore common\n");
@@ -2362,21 +2361,16 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 	break;
     }
 
-
-    /*    RADEONRestoreMode(pScrn, &info->ModeReg);*/
-
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
     ErrorF("bandwidth set\n");
-    /*RADEONUnblank(pScrn);*/
-    radeon_crtc_dpms(crtc, DPMSModeOn);
 
-    ErrorF("unblank\n");
 }
 
 static void
 radeon_crtc_mode_commit(xf86CrtcPtr crtc)
 {
+    radeon_crtc_dpms(crtc, DPMSModeOn);
 }
 
 void radeon_crtc_load_lut(xf86CrtcPtr crtc)
@@ -2425,6 +2419,10 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
     RADEONInfoPtr  info = RADEONPTR(pScrn);
     Bool           CPStarted   = info->CPStarted;
 
+#ifdef XF86DRI
+    if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
+#endif
+
     if (info->accelOn)
         RADEON_SYNC(info, pScrn);
     return FALSE;
@@ -2436,6 +2434,10 @@ radeon_crtc_unlock(xf86CrtcPtr crtc)
     ScrnInfoPtr		pScrn = crtc->scrn;
     RADEONInfoPtr  info = RADEONPTR(pScrn);
 
+#ifdef XF86DRI
+	if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
+#endif
+
     if (info->accelOn)
         RADEON_SYNC(info, pScrn);
 }
diff-tree bba456232ac9a6218aa7fbd504d6093fa72860cf (from 1779a12a947401e5c6bcf784b47e9b3c80d37204)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu May 10 15:33:51 2007 +0200

    RADEON: fix VT switch

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ab67f49..2afe4dc 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4670,6 +4670,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreCommonRegisters(pScrn, restore);
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
+	RADEONRestoreDACRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	return;
     }
@@ -4699,6 +4700,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    RADEONRestoreCrtc2Registers(pScrn, restore);
 	    RADEONRestorePLL2Registers(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
+	    RADEONRestoreDACRegisters(pScrn, restore);
 	    RADEONEnableOuputs(pScrn, 2);
 	} else {
 	    RADEONRestoreMemMapRegisters(pScrn, restore);
@@ -4711,6 +4713,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
             RADEONRestoreCrtcRegisters(pScrn, restore);
             RADEONRestorePLLRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
+	    RADEONRestoreDACRegisters(pScrn, restore);
 	    RADEONEnableOuputs(pScrn, 1);
 	    if (pCRTC2->binding == 1) {
 	      RADEONEnableOuputs(pScrn, 2);
@@ -4727,6 +4730,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
+	RADEONRestoreDACRegisters(pScrn, restore);
 	ErrorF("finished FP restore\n");
 
 	RADEONEnableOutputs(pScrn, 1);
diff-tree 1779a12a947401e5c6bcf784b47e9b3c80d37204 (from 0cb23277666db3b30438c6f88840d861e04df414)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Thu May 10 06:22:35 2007 -0700

    Add cscope files to .gitignore

diff --git a/.gitignore b/.gitignore
index 42ddc0a..ddc5574 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ r128.4x
 radeon.4
 radeon.4x
 stamp-h1
+*cscope*
diff-tree 0cb23277666db3b30438c6f88840d861e04df414 (from 33c370b1d8350945f80ac12097d3e91243a400f2)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Thu May 10 15:20:56 2007 +0200

    RADEON: randr driver re-org checkpoint
    
    - split the mode setting per-crtc
    - reduce start up flicker

diff --git a/src/radeon.h b/src/radeon.h
index 6afed66..98ca96b 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -884,6 +884,8 @@ void
 radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
 void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
+void
+RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num);
 
 #ifdef XF86DRI
 #ifdef USE_XAA
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7fb2b77..3c75149 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2217,6 +2217,11 @@ radeon_crtc_dpms(xf86CrtcPtr crtc, int m
     
   mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
 
+  if (radeon_crtc->crtc_id)
+      ErrorF("crtc2 mode: %d", mode);
+  else
+      ErrorF("crtc1 mode: %d", mode);
+
   switch(mode) {
   case DPMSModeOn:
     if (radeon_crtc->crtc_id) {
@@ -2274,6 +2279,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONMonitorType montype;
     int i = 0;
+    double         dot_clock = 0;
 
     for (i = 0; i < xf86_config->num_output; i++) {
       xf86OutputPtr output = xf86_config->output[i];
@@ -2286,30 +2292,85 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
       }
     }
     
+    ErrorF("init memmap\n");
+    RADEONInitMemMapRegisters(pScrn, &info->ModeReg, info);
+    ErrorF("init common\n");
+    RADEONInitCommonRegisters(&info->ModeReg, info);
+
     switch (radeon_crtc->crtc_id) {
-    case 0: 
-      RADEONInit2(pScrn, adjusted_mode, NULL, 1, &info->ModeReg, montype);
-      break;
+    case 0:
+	ErrorF("init crtc1\n");
+	RADEONInitCrtcRegisters(pScrn, &info->ModeReg, adjusted_mode, info);
+        dot_clock = adjusted_mode->Clock / 1000.0;
+        if (dot_clock) {
+	    ErrorF("init pll1\n");
+	    RADEONInitPLLRegisters(pScrn, info, &info->ModeReg, &info->pll, dot_clock);
+        } else {
+            info->ModeReg.ppll_ref_div = info->SavedReg.ppll_ref_div;
+            info->ModeReg.ppll_div_3   = info->SavedReg.ppll_div_3;
+            info->ModeReg.htotal_cntl  = info->SavedReg.htotal_cntl;
+        }
+	/*RADEONInit2(pScrn, adjusted_mode, NULL, 1, &info->ModeReg, montype);*/
+	break;
     case 1: 
-      RADEONInit2(pScrn, NULL, adjusted_mode, 2, &info->ModeReg, montype);
-      break;
-    }
+	ErrorF("init crtc2\n");
+        RADEONInitCrtc2Registers(pScrn, &info->ModeReg, adjusted_mode, info);
+        dot_clock = adjusted_mode->Clock / 1000.0;
+        if (dot_clock) {
+	    ErrorF("init pll2\n");
+	    RADEONInitPLL2Registers(pScrn, &info->ModeReg, &info->pll, dot_clock, montype != MT_CRT);
+        }
+	/*RADEONInit2(pScrn, NULL, adjusted_mode, 2, &info->ModeReg, montype);*/
+	break;
+    }
+
+    radeon_crtc_dpms(crtc, DPMSModeOff);
+
+    ErrorF("restore memmap\n");
+    RADEONRestoreMemMapRegisters(pScrn, &info->ModeReg);
+    ErrorF("restore common\n");
+    RADEONRestoreCommonRegisters(pScrn, &info->ModeReg);    
 
-    RADEONBlank(pScrn);
-    if (radeon_crtc->crtc_id == 0)
+    switch (radeon_crtc->crtc_id) {
+    case 0:
+	ErrorF("adjustframe 1\n");
 	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
-    else if (radeon_crtc->crtc_id == 1)
+	ErrorF("restore crtc1\n");
+	RADEONRestoreCrtcRegisters(pScrn, &info->ModeReg);
+	ErrorF("restore FP1\n");
+	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+	ErrorF("restore dac\n");
+	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+	ErrorF("restore pll1\n");
+	RADEONRestorePLLRegisters(pScrn, &info->ModeReg);
+	ErrorF("enable 1\n");
+	RADEONEnableOutputs(pScrn, 1);
+	break;
+    case 1:
+	ErrorF("adjustframe 2\n");
 	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
-    RADEONRestoreMode(pScrn, &info->ModeReg);
+	ErrorF("restore crtc2\n");
+	RADEONRestoreCrtc2Registers(pScrn, &info->ModeReg);
+	ErrorF("restore fp2\n");
+	RADEONRestoreFPRegisters(pScrn, &info->ModeReg);
+	ErrorF("restore dac2\n");
+	RADEONRestoreDACRegisters(pScrn, &info->ModeReg);
+	ErrorF("restore pll2\n");
+	RADEONRestorePLL2Registers(pScrn, &info->ModeReg);
+	ErrorF("enable 2\n");
+	RADEONEnableOutputs(pScrn, 2);
+	break;
+    }
 
-    ErrorF("mode restored\n");
 
-    ErrorF("frame adjusted\n");
+    /*    RADEONRestoreMode(pScrn, &info->ModeReg);*/
 
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
     ErrorF("bandwidth set\n");
-    RADEONUnblank(pScrn);
+    /*RADEONUnblank(pScrn);*/
+    radeon_crtc_dpms(crtc, DPMSModeOn);
+
     ErrorF("unblank\n");
 }
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1e94c58..ab67f49 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1169,7 +1169,7 @@ static Bool RADEONPreInitWeight(ScrnInfo
     return TRUE;
 }
 
-static void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+void RADEONInitMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
 				      RADEONInfoPtr info)
 {
     save->mc_fb_location = info->mc_fb_location;
@@ -3825,7 +3825,7 @@ Bool RADEONScreenInit(int scrnIndex, Scr
 }
 
 /* Write memory mapping registers */
-static void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
+void RADEONRestoreMemMapRegisters(ScrnInfoPtr pScrn,
 					 RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -4031,7 +4031,7 @@ static void RADEONAdjustMemMapRegisters(
 #endif
 
 /* Write common registers */
-static void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
+void RADEONRestoreCommonRegisters(ScrnInfoPtr pScrn,
 					 RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -4094,8 +4094,36 @@ static void RADEONRestoreFBDevRegisters(
 #endif
 }
 
+void RADEONRestoreDACRegisters(ScrnInfoPtr pScrn,
+				       RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREGP(RADEON_DAC_CNTL,
+	    restore->dac_cntl,
+	    RADEON_DAC_RANGE_CNTL |
+	    RADEON_DAC_BLANKING);
+
+    OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
+
+    //OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
+    if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
+    	(info->ChipFamily != CHIP_FAMILY_R200)) 
+    OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
+
+    if ((info->ChipFamily == CHIP_FAMILY_R200) ||
+	IS_R300_VARIANT) {
+	OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
+	OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
+    } else {
+	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
+    }
+
+}
+
 /* Write CRTC registers */
-static void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
+void RADEONRestoreCrtcRegisters(ScrnInfoPtr pScrn,
 				       RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -4116,11 +4144,6 @@ static void RADEONRestoreCrtcRegisters(S
 	    RADEON_CRTC_HSYNC_DIS |
 	    RADEON_CRTC_DISPLAY_DIS);
 
-    OUTREGP(RADEON_DAC_CNTL,
-	    restore->dac_cntl,
-	    RADEON_DAC_RANGE_CNTL |
-	    RADEON_DAC_BLANKING);
-
     OUTREG(RADEON_CRTC_H_TOTAL_DISP,    restore->crtc_h_total_disp);
     OUTREG(RADEON_CRTC_H_SYNC_STRT_WID, restore->crtc_h_sync_strt_wid);
     OUTREG(RADEON_CRTC_V_TOTAL_DISP,    restore->crtc_v_total_disp);
@@ -4148,42 +4171,29 @@ static void RADEONRestoreCrtcRegisters(S
 }
 
 /* Write CRTC2 registers */
-static void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
+void RADEONRestoreCrtc2Registers(ScrnInfoPtr pScrn,
 					RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD32	   crtc2_gen_cntl;
+    /*    CARD32	   crtc2_gen_cntl;*/
 
     RADEONTRACE(("Programming CRTC2, offset: 0x%08lx\n",
 		 restore->crtc2_offset));
 
-    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) &
+    /*    crtc2_gen_cntl = INREG(RADEON_CRTC2_GEN_CNTL) &
 	    (RADEON_CRTC2_VSYNC_DIS |
 	     RADEON_CRTC2_HSYNC_DIS |
 	     RADEON_CRTC2_DISP_DIS);
-    crtc2_gen_cntl |= restore->crtc2_gen_cntl;
+	     crtc2_gen_cntl |= restore->crtc2_gen_cntl;*/
 
     /* We prevent the CRTC from hitting the memory controller until
      * fully programmed
      */
     OUTREG(RADEON_CRTC2_GEN_CNTL,
-	   crtc2_gen_cntl | RADEON_CRTC2_DISP_REQ_EN_B);
-
-    OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
-
-    //OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);
-    if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
-    	(info->ChipFamily != CHIP_FAMILY_R200)) 
-    OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
-
-    if ((info->ChipFamily == CHIP_FAMILY_R200) ||
-	IS_R300_VARIANT) {
-	OUTREG(RADEON_DISP_OUTPUT_CNTL, restore->disp_output_cntl);
-	OUTREG(RADEON_DISP_TV_OUT_CNTL, restore->disp_tv_out_cntl);
-    } else {
-	OUTREG(RADEON_DISP_HW_DEBUG, restore->disp_hw_debug);
-    }
+	   restore->crtc2_gen_cntl | RADEON_CRTC2_VSYNC_DIS |
+	   RADEON_CRTC2_HSYNC_DIS | RADEON_CRTC2_DISP_DIS |
+	   RADEON_CRTC2_DISP_REQ_EN_B);
 
     OUTREG(RADEON_CRTC2_H_TOTAL_DISP,    restore->crtc2_h_total_disp);
     OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, restore->crtc2_h_sync_strt_wid);
@@ -4198,12 +4208,12 @@ static void RADEONRestoreCrtc2Registers(
     OUTREG(RADEON_CRTC2_PITCH,           restore->crtc2_pitch);
     OUTREG(RADEON_DISP2_MERGE_CNTL,      restore->disp2_merge_cntl);
 
-    OUTREG(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, restore->crtc2_gen_cntl);
 
 }
 
 /* Write flat panel registers */
-static void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+void RADEONRestoreFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -4277,7 +4287,7 @@ static void RADEONPLL2WriteUpdate(ScrnIn
 }
 
 /* Write PLL registers */
-static void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
+void RADEONRestorePLLRegisters(ScrnInfoPtr pScrn,
 				      RADEONSavePtr restore)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -4383,7 +4393,7 @@ static void RADEONRestorePLLRegisters(Sc
 
 
 /* Write PLL2 registers */
-static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
+void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
 				       RADEONSavePtr restore)
 {
     OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
@@ -4627,7 +4637,7 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
-static void
+void
 RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
 {
     RADEONInfoPtr      info = RADEONPTR(pScrn);
@@ -5105,7 +5115,7 @@ void RADEONRestore(ScrnInfoPtr pScrn)
 }
 
 /* Define common registers for requested video mode */
-static void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
+void RADEONInitCommonRegisters(RADEONSavePtr save, RADEONInfoPtr info)
 {
     save->ovr_clr            = 0;
     save->ovr_wid_left_right = 0;
@@ -5430,7 +5440,7 @@ static void RADEONInitOutputRegisters(Sc
 }
 
 /* Define CRTC registers for requested video mode */
-static Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
+Bool RADEONInitCrtcRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
 				  DisplayModePtr mode, RADEONInfoPtr info)
 {
     int    format;
@@ -5623,7 +5633,7 @@ static Bool RADEONInitCrtcRegisters(Scrn
 }
 
 /* Define CRTC2 registers for requested video mode */
-static Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+Bool RADEONInitCrtc2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
 				     DisplayModePtr mode, RADEONInfoPtr info)
 {
     int    format;
@@ -5766,7 +5776,7 @@ static Bool RADEONInitCrtc2Registers(Scr
 
 
 /* Define PLL registers for requested video mode */
-static void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
+void RADEONInitPLLRegisters(ScrnInfoPtr pScrn, RADEONInfoPtr info,
 				   RADEONSavePtr save, RADEONPLLPtr pll,
 				   double dot_clock)
 {
@@ -5836,7 +5846,7 @@ static void RADEONInitPLLRegisters(ScrnI
 }
 
 /* Define PLL2 registers for requested video mode */
-static void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
+void RADEONInitPLL2Registers(ScrnInfoPtr pScrn, RADEONSavePtr save,
 				    RADEONPLLPtr pll, double dot_clock,
 				    int no_odd_postdiv)
 {
diff-tree 33c370b1d8350945f80ac12097d3e91243a400f2 (from 6263248a0044777a352e4ee7380b4b8f9afd091b)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Wed May 9 16:16:39 2007 -0700

    RADEON:
      - fix an ugly modesetting bug:  if we happened to set the mode on
        CRTC1 before CRTC2, CRTC2's RestoreMode function would clobber
        CRTC1's CRTC_OFFSET register since we never updated
        ModeReg.crtc_offset...  so make AdjustFrame use ModeReg and pull
        the call to it up before RestoreMode, seems to work ok here.

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 9a3a87f..7fb2b77 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2296,14 +2296,13 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     }
 
     RADEONBlank(pScrn);
-    RADEONRestoreMode(pScrn, &info->ModeReg);
-
-    ErrorF("mode restored\n");
-
     if (radeon_crtc->crtc_id == 0)
 	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
     else if (radeon_crtc->crtc_id == 1)
 	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
+    RADEONRestoreMode(pScrn, &info->ModeReg);
+
+    ErrorF("mode restored\n");
 
     ErrorF("frame adjusted\n");
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index df644d8..1e94c58 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6235,7 +6235,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    int            reg, Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
+    int            Base, regcntl, crtcoffsetcntl, xytilereg, crtcxytile = 0;
 #ifdef XF86DRI
     RADEONSAREAPrivPtr pSAREAPriv;
     XF86DRISAREAPtr pSAREA;
@@ -6263,11 +6263,9 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
      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. */
     if (clone || info->IsSecondary) {
-        reg = RADEON_CRTC2_OFFSET;
 	regcntl = RADEON_CRTC2_OFFSET_CNTL;
 	xytilereg = R300_CRTC2_TILE_X0_Y0;
     } else {
-        reg = RADEON_CRTC_OFFSET;
 	regcntl = RADEON_CRTC_OFFSET_CNTL;
 	xytilereg = R300_CRTC_TILE_X0_Y0;
     }
@@ -6337,14 +6335,16 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
     }
 #endif
 
-    OUTREG(reg, Base);
-
     if (IS_R300_VARIANT) {
         OUTREG(xytilereg, crtcxytile);
     } else {
         OUTREG(regcntl, crtcoffsetcntl);
     }
 
+    if (clone)
+        info->ModeReg.crtc2_offset = Base;
+    else
+        info->ModeReg.crtc_offset = Base;
 }
 
 void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
diff-tree 6263248a0044777a352e4ee7380b4b8f9afd091b (from d2497009e395800fbde5777465f3087a54b94418)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Wed May 9 14:52:00 2007 -0700

    RADEON:
      - use fixup_mode hook to set RADEON_USE_RMX flag so panel scaling
        works
      - use valid_mode hook to prune invalid default modes from list
      - use adjusted_mode in crtc_mode_set (using adjusted_mode from
        fixup hook)

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 1039209..9a3a87f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2288,10 +2288,10 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     
     switch (radeon_crtc->crtc_id) {
     case 0: 
-      RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg, montype);
+      RADEONInit2(pScrn, adjusted_mode, NULL, 1, &info->ModeReg, montype);
       break;
     case 1: 
-      RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg, montype);
+      RADEONInit2(pScrn, NULL, adjusted_mode, 2, &info->ModeReg, montype);
       break;
     }
 
@@ -2430,6 +2430,18 @@ 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;
+
+    if (pMode->HDisplay > info->PanelXRes ||
+	pMode->VDisplay > info->PanelYRes)
+	return MODE_PANEL;
+
     return MODE_OK;
 }
 
@@ -2437,8 +2449,18 @@ static Bool
 radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
 		    DisplayModePtr adjusted_mode)
 {
-    return TRUE;
+    ScrnInfoPtr	pScrn = output->scrn;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+    if (radeon_output->type != OUTPUT_LVDS)
+	return TRUE;
+
+    if (mode->HDisplay < info->PanelXRes ||
+	mode->VDisplay < info->PanelYRes)
+	adjusted_mode->Flags |= RADEON_USE_RMX;
 
+    return TRUE;
 }
 
 static void
diff-tree d2497009e395800fbde5777465f3087a54b94418 (from 4488f0737d5268168eab41440b7a3b5732efb15e)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 9 22:23:45 2007 +0200

    randr checkpoint
    
    - server still hangs if you start with external monitor connected
    - RMX not working
    - more than 2 outputs now possible (untested)

diff --git a/src/radeon.h b/src/radeon.h
index 671c87e..6afed66 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -765,6 +765,8 @@ typedef struct {
 
     CARD32            tv_dac_adj;
 
+  int               max_connectors;
+
     CreateScreenResourcesProcPtr CreateScreenResources;
 } RADEONInfoRec, *RADEONInfoPtr;
 
diff --git a/src/radeon_display.c b/src/radeon_display.c
index e379099..1039209 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -655,16 +655,16 @@ static RADEONMonitorType RADEONDisplayDD
 	     */
 	    if (radeon_output->TMDSType == TMDS_EXT) MonType = MT_DFP;
 	    else {
-		if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility)
+		if (INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS)
 		    MonType = MT_DFP;
-		else 
+		else
 		    MonType = MT_LCD;
 	    }
 	} else MonType = MT_CRT;
     } else MonType = MT_NONE;
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "DDC Type: %d, Detected Type: %d\n", DDCType, MonType);
+	       "DDC Type: %d, Detected Monitor Type: %d\n", DDCType, MonType);
 
     return MonType;
 }
@@ -943,7 +943,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
      * The information should be correct even on a OEM card.
      * If not, we may have problem -- need to use MonitorLayout option.
      */
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+    for (i = 0; i < info->max_connectors; i++) {
 	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
 	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
 	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
@@ -1122,11 +1122,26 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	}
     }
 
-    for (i = 0; i < 2; i++) {
+#if 1
+    if (info->IsMobility) {
+        pRADEONEnt->PortInfo[2]->DDCType = DDC_DVI;
+        pRADEONEnt->PortInfo[2]->TMDSType = TMDS_INT;
+        pRADEONEnt->PortInfo[2]->ConnectorType = CONNECTOR_DVI_D;
+        pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
+	if (pRADEONEnt->PortInfo[0]->DDCType == DDC_DVI) {
+	    pRADEONEnt->PortInfo[0]->DDCType = DDC_MONID;
+	}
+	if (pRADEONEnt->PortInfo[0]->TMDSType == TMDS_INT) {
+	    pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
+	}
+    }
+#endif
+
+    for (i = 0; i < info->max_connectors; i++) {
       RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
 
       int DDCReg = 0;
-      char *names[] = { "DDC1", "DDC2" };
+      char *names[] = { "DDC1", "DDC2", "DDC3" };
 
       RADEONSetOutputType(pScrn, radeon_output);
       switch(radeon_output->DDCType) {
@@ -1152,7 +1167,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	if (i == 0)
 		RADEONGetHardCodedEDIDFromBIOS(pScrn);
 
-	RADEONUpdatePanelSize(pScrn);
+	/*RADEONUpdatePanelSize(pScrn);*/
 
       }
 
@@ -1167,24 +1182,25 @@ static RADEONMonitorType RADEONPortCheck
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    RADEONMonitorType MonType = MT_NONE;
+
 
     if (info->IsMobility) {
-      switch(radeon_output->num) {
-      case 0:
-	/* non-DDC laptop panel connected on primary */
-	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
-	  return MT_LCD;
-	break;
-      case 1:
+        if ((info->IsAtomBios && radeon_output->ConnectorType == CONNECTOR_LVDS_ATOM) ||
+	     radeon_output->ConnectorType == CONNECTOR_PROPRIETARY) {
+	     if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
+	         MonType =  MT_LCD;
+        }
 	/* non-DDC TMDS panel connected through DVO */
 	if (INREG(RADEON_FP2_GEN_CNTL) & RADEON_FP2_ON)
-	  return MT_DFP;
-	break;
-      default:
-	break;
-      }
+	  MonType = MT_DFP;
     }
-    return MT_NONE;
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Detected Monitor Type: %d\n", MonType);
+
+    return MonType;
+
 }
 
 /* Primary Head (DVI or Laptop Int. panel)*/
@@ -1201,8 +1217,8 @@ void RADEONConnectorFindMonitor(ScrnInfo
 						     radeon_output->DDCType,
 						     output)));
       else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
-      else
-	radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
+      else if (radeon_output->DACType == DAC_PRIMARY) 
+	  radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
     }
 
     if (output->MonInfo) {
@@ -1322,6 +1338,8 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     xf86OutputPtr output;
     int o;
 
+    pRADEONEnt->Controller[0]->binding = 1;
+    pRADEONEnt->Controller[1]->binding = 1;
 
     for (o = 0; o < xf86_config->num_output; o++) {
       output = xf86_config->output[o];
@@ -1477,7 +1495,6 @@ static void RADEONDacPowerSet(ScrnInfoPt
 			       RADEON_DAC_PDWN_G |
 			       RADEON_DAC_PDWN_B);
 	}
-	ErrorF("Setting IsOn %d DAC CNTL %08X and DAC MACRO_CNTL %08X\n", IsOn, dac_cntl, dac_macro_cntl);
 	OUTREG(RADEON_DAC_CNTL, dac_cntl);
 	OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
     } else {
@@ -1594,6 +1611,8 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
     RADEONOutputPrivatePtr radeon_output;
     radeon_output = output->driver_private;
 
+    ErrorF("montype: %d\n", radeon_output->MonType);
+
     if (bEnable) {
         if (radeon_output->MonType == MT_CRT) {
             if (radeon_output->DACType == DAC_PRIMARY) {
@@ -1629,10 +1648,12 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
             }
         } else if (radeon_output->MonType == MT_LCD) {
             tmp = INREG(RADEON_LVDS_GEN_CNTL);
+	    ErrorF("read in LVDS reg\n");
             tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
 	    usleep (info->PanelPwrDly * 1000);
             OUTREG(RADEON_LVDS_GEN_CNTL, tmp);
+	    ErrorF("wrote out LVDS reg\n");
             save->lvds_gen_cntl |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } 
@@ -1693,6 +1714,7 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
 	    }
         }
     }
+    ErrorF("finished output enable\n");
 }
 
 /* Calculate display buffer watermark to prevent buffer underflow */
@@ -2260,6 +2282,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
       if (output->crtc == crtc) {
 	montype = radeon_output->MonType;
 	radeon_output->crtc_num = radeon_crtc->crtc_id + 1;
+	ErrorF("using crtc: %d on output %s montype: %d\n", radeon_output->crtc_num, OutputType[radeon_output->type], montype);
       }
     }
     
@@ -2275,14 +2298,20 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     RADEONBlank(pScrn);
     RADEONRestoreMode(pScrn, &info->ModeReg);
 
+    ErrorF("mode restored\n");
+
     if (radeon_crtc->crtc_id == 0)
 	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
     else if (radeon_crtc->crtc_id == 1)
 	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
 
+    ErrorF("frame adjusted\n");
+
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
+    ErrorF("bandwidth set\n");
     RADEONUnblank(pScrn);
+    ErrorF("unblank\n");
 }
 
 static void
@@ -2530,6 +2559,7 @@ Bool RADEONAllocateControllers(ScrnInfoP
 
 Bool RADEONAllocatePortInfo(ScrnInfoPtr pScrn)
 {
+    RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int num_connectors;
     int i;
@@ -2537,8 +2567,16 @@ Bool RADEONAllocatePortInfo(ScrnInfoPtr 
     if (pRADEONEnt->PortInfo[0])
 	return TRUE;
 
+    /* when we support TV, this should be incremented */
+    if (info->IsMobility) {
+      /* DVI on docks */
+      info->max_connectors = 3;
+    } else {
+      info->max_connectors = 2;
+    }
+
     /* for now always allocate max connectors */
-    for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
+    for (i = 0 ; i < info->max_connectors; i++) {
 
 	pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
 	if (!pRADEONEnt->PortInfo[i])
@@ -2584,6 +2622,7 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
 
 Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
 {
+    RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int i;
 
@@ -2591,7 +2630,7 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
         return TRUE;
     
     /* for now always allocate max connectors */
-    for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
+    for (i = 0 ; i < info->max_connectors; i++) {
 
 	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
 	if (!pRADEONEnt->pOutput[i])
@@ -2604,7 +2643,7 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
  	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
 
-	pRADEONEnt->pOutput[i]->possible_clones = 1|2;
+	pRADEONEnt->pOutput[i]->possible_clones = 0 /*1|2*/;
     }
 
     return TRUE;
@@ -2614,10 +2653,11 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 #if 0
 xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
 {
+    RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int i;
 
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+    for (i = 0; i < info->max_connectors; i++) {
         if (pRADEONEnt->PortInfo[i]->crtc_num == crtc_num)
 	    return pRADEONEnt->pOutput[i];
     }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0624ae6..df644d8 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2555,7 +2555,9 @@ static Bool RADEONPreInitControllers(Scr
       xf86OutputPtr	      output = config->output[i];
       
       output->status = (*output->funcs->detect) (output);
+      ErrorF("finished output detect: %d\n", i);
     }
+    ErrorF("finished all detect\n");
     return TRUE;
 }
 
@@ -2819,12 +2821,16 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
        goto fail;
 
 
+    ErrorF("before xf86InitialConfiguration\n");
+
     if (!xf86InitialConfiguration (pScrn, FALSE))
    {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
       goto fail;
    }
 
+    ErrorF("after xf86InitialConfiguration\n");
+
    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
 
    /* Set display resolution */
@@ -4370,6 +4376,9 @@ static void RADEONRestorePLLRegisters(Sc
     OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
 	    RADEON_VCLK_SRC_SEL_PPLLCLK,
 	    ~(RADEON_VCLK_SRC_SEL_MASK));
+
+    ErrorF("finished PLL1\n");
+
 }
 
 
@@ -4429,6 +4438,9 @@ static void RADEONRestorePLL2Registers(S
     OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
 	    RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
 	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
+
+    ErrorF("finished PLL2\n");
+
 }
 
 
@@ -4616,13 +4628,14 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
 }
 
 static void
-RADEONEnableOuputs(ScrnInfoPtr pScrn, int crtc_num)
+RADEONEnableOutputs(ScrnInfoPtr pScrn, int crtc_num)
 {
+    RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int i;
     xf86OutputPtr output;
 
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+    for (i = 0; i < info->max_connectors; i++) {
         if (pRADEONEnt->PortInfo[i]->crtc_num == crtc_num) {
 	    output = pRADEONEnt->pOutput[i];
             RADEONEnableDisplay(pScrn, output, TRUE);
@@ -4655,7 +4668,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
        get set by RADEONEnableDisplay()
      */
     if (!info->IsSwitching && !info->IsSecondary)
-	RADEONDisableDisplays(pScrn);
+        RADEONDisableDisplays(pScrn);
 
     /* When changing mode with Dual-head card, care must be taken for
      * the special order in setting registers. CRTC2 has to be set
@@ -4704,14 +4717,19 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
+	ErrorF("finished FP restore\n");
 
-	RADEONEnableOuputs(pScrn, 1);
+	RADEONEnableOutputs(pScrn, 1);
+	ErrorF("enable output1 done\n");
 
 	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    RADEONEnableOuputs(pScrn, 2);
+	    RADEONEnableOutputs(pScrn, 2);
+	    ErrorF("enable output2 done\n");
 	}
     }
 
+    ErrorF("finished modeset\n");
+
 #if 0
     RADEONRestorePalette(pScrn, &info->SavedReg);
 #endif
@@ -5570,9 +5588,11 @@ static Bool RADEONInitCrtcRegisters(Scrn
     }
 
     /* get the output connected to this CRTC */
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-      if (pRADEONEnt->PortInfo[i]->crtc_num == 1)
+    for (i = 0; i < info->max_connectors; i++) {
+      if (pRADEONEnt->PortInfo[i]->crtc_num == 1) {
+	ErrorF("init output for crtc1\n");
         RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 1);
+      }
     }
 #if 0
     if (pRADEONEnt->PortInfo[0]->crtc_num == 1) {
@@ -5708,9 +5728,11 @@ static Bool RADEONInitCrtc2Registers(Scr
     save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
 
     /* get the output connected to this CRTC */
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-      if (pRADEONEnt->PortInfo[i]->crtc_num == 2)
-        RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 1);
+    for (i = 0; i < info->max_connectors; i++) {
+      if (pRADEONEnt->PortInfo[i]->crtc_num == 2) {
+	ErrorF("init output for crtc2\n");
+        RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 2);
+      }
     }
 #if 0
     if (pRADEONEnt->PortInfo[0]->crtc_num == 2) {
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 4d7251f..46680e3 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -270,10 +270,14 @@ RADEONProbeOutputModes(xf86OutputPtr out
     xf86MonPtr		    edid_mon;
     DisplayModePtr	    modes = NULL;
 
+#if 0
     /* force reprobe */
     radeon_output->MonType = MT_UNKNOWN;
 	
     RADEONConnectorFindMonitor(pScrn, output);
+#endif
+    ErrorF("in RADEONProbeOutputModes\n");
+
 
     if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
       edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index cbe9e74..541a910 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -137,7 +137,7 @@ typedef struct _RADEONOutputPrivateRec {
     I2CBusPtr         pI2CBus;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
-#define RADEON_MAX_CONNECTOR 2
+#define RADEON_MAX_CONNECTOR 3 /* actually 4: DVI/VGA, DVI on docks, TV, LVDS */
 #define RADEON_MAX_CRTC 2
 
 typedef struct
diff-tree 4488f0737d5268168eab41440b7a3b5732efb15e (from 4d992386e2ab9d8c50f0484445564325dfb42930)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 9 16:41:13 2007 +0200

    more randr re-work
    
    - remove RADEONQueryConnectedDisplays(); randr takes care of this now
    - print edid after randr detection

diff --git a/src/radeon_display.c b/src/radeon_display.c
index e79895f..e379099 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1192,6 +1192,7 @@ static RADEONMonitorType RADEONPortCheck
 /* 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;
     
@@ -1203,6 +1204,15 @@ void RADEONConnectorFindMonitor(ScrnInfo
       else
 	radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
     }
+
+    if (output->MonInfo) {
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on connector: %s ----------------------\n",
+		 info->IsAtomBios ?
+		 ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+		 ConnectorTypeName[radeon_output->ConnectorType]
+		 );
+      xf86PrintEDID( output->MonInfo );
+    }
 }
 
 void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn)
@@ -1312,10 +1322,7 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     xf86OutputPtr output;
     int o;
 
-    /*
-      pRADEONEnt->PortInfo[0]->crtc_num = 1;
-      pRADEONEnt->PortInfo[1]->crtc_num = 2;
-    */
+
     for (o = 0; o < xf86_config->num_output; o++) {
       output = xf86_config->output[o];
       radeon_output = output->driver_private;
@@ -2604,7 +2611,7 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 }
 
 
-
+#if 0
 xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -2616,7 +2623,7 @@ xf86OutputPtr RADEONGetCrtcConnector(Scr
     }
     return NULL;
 }
-
+#endif
 
 /**
  * In the current world order, there are lists of modes per output, which may
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e16c183..0624ae6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2543,10 +2543,6 @@ static Bool RADEONPreInitControllers(Scr
       if (!RADEONAllocateConnectors(pScrn))
 	return FALSE;
     }
-
-    if (!info->IsSecondary) {
-      RADEONQueryConnectedDisplays(pScrn);
-    }
       
     RADEONMapControllers(pScrn);
 
diff-tree 4d992386e2ab9d8c50f0484445564325dfb42930 (from 2618cf2aa8ed76411b943eb90c95869814c2f151)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 9 16:12:21 2007 +0200

    enable all outputs on each crtc on mode restore

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d05d9f7..e16c183 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4619,6 +4619,22 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
+static void
+RADEONEnableOuputs(ScrnInfoPtr pScrn, int crtc_num)
+{
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    int i;
+    xf86OutputPtr output;
+
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+        if (pRADEONEnt->PortInfo[i]->crtc_num == crtc_num) {
+	    output = pRADEONEnt->pOutput[i];
+            RADEONEnableDisplay(pScrn, output, TRUE);
+        }
+    }
+
+}
+
 /* Write out state to define a new video mode */
 void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
@@ -4664,10 +4680,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    RADEONRestoreCrtc2Registers(pScrn, restore);
 	    RADEONRestorePLL2Registers(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
-	    output = RADEONGetCrtcConnector(pScrn, 2);
-	    if (output) {
-		RADEONEnableDisplay(pScrn, output, TRUE);
-	    }
+	    RADEONEnableOuputs(pScrn, 2);
 	} else {
 	    RADEONRestoreMemMapRegisters(pScrn, restore);
 	    RADEONRestoreCommonRegisters(pScrn, restore);
@@ -4679,15 +4692,9 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
             RADEONRestoreCrtcRegisters(pScrn, restore);
             RADEONRestorePLLRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
-	    output = RADEONGetCrtcConnector(pScrn, 1);
-	    if (output) {
-		RADEONEnableDisplay(pScrn, output, TRUE);
-	    }
+	    RADEONEnableOuputs(pScrn, 1);
 	    if (pCRTC2->binding == 1) {
-		output = RADEONGetCrtcConnector(pScrn, 2);
-		if (output) {
-		    RADEONEnableDisplay(pScrn, output, TRUE);
-		}
+	      RADEONEnableOuputs(pScrn, 2);
 	    }
 	}
     } else {
@@ -4701,15 +4708,11 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
-	output = RADEONGetCrtcConnector(pScrn, 1);
-	if (output) {
-	    RADEONEnableDisplay(pScrn, output, TRUE);
-	}
+
+	RADEONEnableOuputs(pScrn, 1);
+
 	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    output = RADEONGetCrtcConnector(pScrn, 2);
-	    if (output) {
-		RADEONEnableDisplay(pScrn, output, TRUE);
-	    }
+	    RADEONEnableOuputs(pScrn, 2);
 	}
     }
 
diff-tree 2618cf2aa8ed76411b943eb90c95869814c2f151 (from 61b9e79cbeee6f735a4c82ec8a802aee85d8b890)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 9 15:48:40 2007 +0200

    More re-org to allow more than 2 outputs
    
    - Move radeon output crtc map into crtc_set_mode
    - in modeinit, set up all outputs attached to crtc

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7d31a52..e79895f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1312,9 +1312,10 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     xf86OutputPtr output;
     int o;
 
+    /*
       pRADEONEnt->PortInfo[0]->crtc_num = 1;
       pRADEONEnt->PortInfo[1]->crtc_num = 2;
-
+    */
     for (o = 0; o < xf86_config->num_output; o++) {
       output = xf86_config->output[o];
       radeon_output = output->driver_private;
@@ -2251,6 +2252,7 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 
       if (output->crtc == crtc) {
 	montype = radeon_output->MonType;
+	radeon_output->crtc_num = radeon_crtc->crtc_id + 1;
       }
     }
     
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1875244..d05d9f7 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5420,8 +5420,9 @@ static Bool RADEONInitCrtcRegisters(Scrn
     int    hsync_start;
     int    hsync_wid;
     int    vsync_wid;
+    int i;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    xf86OutputPtr connector;
+
 
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
@@ -5570,11 +5571,17 @@ static Bool RADEONInitCrtcRegisters(Scrn
     }
 
     /* get the output connected to this CRTC */
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+      if (pRADEONEnt->PortInfo[i]->crtc_num == 1)
+        RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 1);
+    }
+#if 0
     if (pRADEONEnt->PortInfo[0]->crtc_num == 1) {
 	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 1);
     } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) {
 	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 1);
     }
+#endif
 
     if (info->IsDellServer) {
 	save->dac2_cntl = info->SavedReg.dac2_cntl;
@@ -5604,9 +5611,10 @@ static Bool RADEONInitCrtc2Registers(Scr
     int    hsync_start;
     int    hsync_wid;
     int    vsync_wid;
-
+    int i;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     RADEONInfoPtr info0 = NULL;
+
     if (info->IsSecondary)
 	info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
 
@@ -5701,11 +5709,17 @@ static Bool RADEONInitCrtc2Registers(Scr
     save->fp_v2_sync_strt_wid = save->crtc2_v_sync_strt_wid;
 
     /* get the output connected to this CRTC */
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+      if (pRADEONEnt->PortInfo[i]->crtc_num == 2)
+        RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[i], 1);
+    }
+#if 0
     if (pRADEONEnt->PortInfo[0]->crtc_num == 2) {
 	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 2);
     } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) {
 	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 2);
     }
+#endif
 
     /* We must set SURFACE_CNTL properly on the second screen too */
     save->surface_cntl = 0;
diff-tree 61b9e79cbeee6f735a4c82ec8a802aee85d8b890 (from 6a724dd798c1a7b461672993c02be83a7bccded6)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 9 15:11:23 2007 +0200

    start to clean up MapControllers

diff --git a/src/radeon_display.c b/src/radeon_display.c
index c0750eb..7d31a52 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1307,23 +1307,36 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    Bool head_reversed = FALSE;
-    xf86OutputPtr output;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONOutputPrivatePtr radeon_output;
+    xf86OutputPtr output;
+    int o;
 
-    if (!info->IsSecondary) {
       pRADEONEnt->PortInfo[0]->crtc_num = 1;
       pRADEONEnt->PortInfo[1]->crtc_num = 2;
 
+    for (o = 0; o < xf86_config->num_output; o++) {
+      output = xf86_config->output[o];
+      radeon_output = output->driver_private;
+
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
-		 "Port1:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
-		 MonTypeName[pRADEONEnt->PortInfo[0]->MonType+1], 
-		 info->IsAtomBios ? 
-		 ConnectorTypeNameATOM[pRADEONEnt->PortInfo[0]->ConnectorType]:
-		 ConnectorTypeName[pRADEONEnt->PortInfo[0]->ConnectorType],
-		 DACTypeName[pRADEONEnt->PortInfo[0]->DACType+1],
-		 TMDSTypeName[pRADEONEnt->PortInfo[0]->TMDSType+1],
-		 DDCTypeName[pRADEONEnt->PortInfo[0]->DDCType]);
+		 "Port%d:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
+	  o,
+	  MonTypeName[radeon_output->MonType+1],
+	  info->IsAtomBios ? 
+	  ConnectorTypeNameATOM[radeon_output->ConnectorType]:
+	  ConnectorTypeName[radeon_output->ConnectorType],
+	  DACTypeName[radeon_output->DACType+1],
+	  TMDSTypeName[radeon_output->TMDSType+1],
+	  DDCTypeName[radeon_output->DDCType]);
+
+    }
+
+#if 0
+    if (!info->IsSecondary) {
+      pRADEONEnt->PortInfo[0]->crtc_num = 1;
+      pRADEONEnt->PortInfo[1]->crtc_num = 2;
+
 
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		 "Port2:\n Monitor   -- %s\n Connector -- %s\n DAC Type  -- %s\n TMDS Type -- %s\n DDC Type  -- %s\n", 
@@ -1426,7 +1439,7 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
  	else
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
     }
-
+#endif
 
     return TRUE;
 }
diff-tree 6a724dd798c1a7b461672993c02be83a7bccded6 (from 03860fed24b4f76cc7f1f4210ec8f8040fa04777)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Wed May 9 14:48:17 2007 +0200

    minor cleanup

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 5c84591..c0750eb 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -943,7 +943,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
      * The information should be correct even on a OEM card.
      * If not, we may have problem -- need to use MonitorLayout option.
      */
-    for (i = 0; i < 2; i++) {
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
 	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
 	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
 	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
@@ -2571,7 +2571,6 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
     /* for now always allocate max connectors */
     for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
 
-
 	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
 	if (!pRADEONEnt->pOutput[i])
 	    return FALSE;
@@ -2579,11 +2578,11 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
 	pRADEONEnt->PortInfo[i]->num = i;
 
-	pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0);
+	pRADEONEnt->pOutput[i]->possible_crtcs = 1;
 	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
- 	    pRADEONEnt->pOutput[i]->possible_crtcs |= (1<<1);
+ 	    pRADEONEnt->pOutput[i]->possible_crtcs |= 2;
 
-	pRADEONEnt->pOutput[i]->possible_clones = 0;
+	pRADEONEnt->pOutput[i]->possible_clones = 1|2;
     }
 
     return TRUE;
@@ -2594,11 +2593,12 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    int i;
 
-    if (pRADEONEnt->PortInfo[0]->crtc_num == crtc_num)
-      return pRADEONEnt->pOutput[0];
-    else if (pRADEONEnt->PortInfo[1]->crtc_num == crtc_num)
-      return pRADEONEnt->pOutput[1];
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+        if (pRADEONEnt->PortInfo[i]->crtc_num == crtc_num)
+	    return pRADEONEnt->pOutput[i];
+    }
     return NULL;
 }
 
diff-tree 03860fed24b4f76cc7f1f4210ec8f8040fa04777 (from 76670f665ebec7cdf40a04bf9379cb3ad4417507)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue May 8 19:27:48 2007 +0200

    remove some old mergedfb cruft

diff --git a/src/radeon.h b/src/radeon.h
index 47a3bd9..671c87e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -163,30 +163,6 @@ typedef enum {
     OPTION_DRI
 } RADEONOpts;
 
-/* ------- mergedfb support ------------- */
-		/* Psuedo Xinerama support */
-#define NEED_REPLIES  		/* ? */
-#define EXTENSION_PROC_ARGS void *
-#include "extnsionst.h"  	/* required */
-#include <X11/extensions/panoramiXproto.h>  	/* required */
-#define RADEON_XINERAMA_MAJOR_VERSION  1
-#define RADEON_XINERAMA_MINOR_VERSION  1
-
-
-/* Relative merge position */
-typedef enum {
-   radeonLeftOf,
-   radeonRightOf,
-   radeonAbove,
-   radeonBelow,
-   radeonClone
-} RADEONScrn2Rel;
-
-typedef struct _region {
-    int x0,x1,y0,y1;
-} region;
-
-/* ------------------------------------- */
 
 #define RADEON_DEBUG            1 /* Turn off debugging output               */
 #define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
diff-tree 76670f665ebec7cdf40a04bf9379cb3ad4417507 (from parents)
Merge: 83f81ed5e3c33c94c80500316c37a7cbfc51f41f a3ee42207aab77d93655a82fdcb32be38268b85f
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Tue May 8 18:41:25 2007 +0200

    Merge branch 'master' into randr-1.2 and fix conflicts

diff --cc src/Makefile.am
index b2361f1,84642f7..55a0f2a
@@@ -79,10 -77,10 +77,10 @@@
  radeon_drv_la_LDFLAGS = -module -avoid-version
  radeon_drv_ladir = @moduledir@/drivers
  radeon_drv_la_SOURCES = \
 -	radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
 +	radeon_accel.c radeon_cursor.c radeon_dga.c \
  	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
- 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
- 	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+ 	radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
+ 	radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
  
  theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
  theatre_detect_drv_la_LDFLAGS = -module -avoid-version
diff --cc src/radeon_display.c
index f0015ae,f3b86e6..5c84591
@@@ -177,10 -167,16 +178,16 @@@
      unsigned char *RADEONMMIO = info->MMIO;
  
      /* Get the result */
-     val = INREG(b->DriverPrivate.uval);
  
-     *Clock = (val & RADEON_GPIO_Y_1) != 0;
-     *data  = (val & RADEON_GPIO_Y_0) != 0;
 -    if (info->DDCReg == RADEON_LCD_GPIO_MASK) { 
 -        val = INREG(info->DDCReg+4);
++    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(info->DDCReg);
++        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)
@@@ -190,32 -186,35 +197,38 @@@
      unsigned long  val;
      unsigned char *RADEONMMIO = info->MMIO;
  
-     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);
- 
 -    if (info->DDCReg == RADEON_LCD_GPIO_MASK) {
 -        val = INREG(info->DDCReg) & (CARD32)~((1<<12) | (1<<13));
++    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(info->DDCReg, val);
++        OUTREG(b->DriverPrivate.uval, val);
+     } else {
 -        val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
++        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(info->DDCReg, val);
++        OUTREG(b->DriverPrivate.uval, val);
+    }
      /* read back to improve reliability on some cards. */
 -    val = INREG(info->DDCReg);
 +    val = INREG(b->DriverPrivate.uval);
  }
  
 -Bool RADEONI2cInit(ScrnInfoPtr pScrn)
 +Bool RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
  {
 -    RADEONInfoPtr  info = RADEONPTR(pScrn);
 +    I2CBusPtr pI2CBus;
  
 -    info->pI2CBus = xf86CreateI2CBusRec();
 -    if (!info->pI2CBus) return FALSE;
 +    pI2CBus = xf86CreateI2CBusRec();
 +    if (!pI2CBus) return FALSE;
  
 -    info->pI2CBus->BusName    = "DDC";
 -    info->pI2CBus->scrnIndex  = pScrn->scrnIndex;
 -    info->pI2CBus->I2CPutBits = RADEONI2CPutBits;
 -    info->pI2CBus->I2CGetBits = RADEONI2CGetBits;
 -    info->pI2CBus->AcknTimeout = 5;
 +    pI2CBus->BusName    = name;
 +    pI2CBus->scrnIndex  = pScrn->scrnIndex;
 +    pI2CBus->I2CPutBits = RADEONI2CPutBits;
 +    pI2CBus->I2CGetBits = RADEONI2CGetBits;
 +    pI2CBus->AcknTimeout = 5;
 +    pI2CBus->DriverPrivate.uval = i2c_reg;
  
 -    if (!xf86I2CBusInit(info->pI2CBus)) return FALSE;
 +    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
 +
 +    *bus_ptr = pI2CBus;
      return TRUE;
  }
  
@@@ -559,16 -557,35 +572,16 @@@
      unsigned char *RADEONMMIO = info->MMIO;
      unsigned long DDCReg;
      RADEONMonitorType MonType = MT_NONE;
 -    xf86MonPtr* MonInfo = &port->MonInfo;
 +    xf86MonPtr* MonInfo = &output->MonInfo;
 +    RADEONOutputPrivatePtr radeon_output = output->driver_private;
      int i, j;
  
 -    DDCReg = info->DDCReg;
 -    switch(DDCType)
 -    {
 -    case DDC_MONID:
 -	info->DDCReg = RADEON_GPIO_MONID;
 -	break;
 -    case DDC_DVI:
 -	info->DDCReg = RADEON_GPIO_DVI_DDC;
 -	break;
 -    case DDC_VGA:
 -	info->DDCReg = RADEON_GPIO_VGA_DDC;
 -	break;
 -    case DDC_CRT2:
 -	info->DDCReg = RADEON_GPIO_CRT2_DDC;
 -	break;
 -    case DDC_LCD:
 -	info->DDCReg = RADEON_LCD_GPIO_MASK;
 -	break;
 -    default:
 -	info->DDCReg = DDCReg;
 -	return MT_NONE;
 -    }
++
 +    DDCReg = radeon_output->DDCReg;
  
      /* Read and output monitor info using DDC2 over I2C bus */
-     if (radeon_output->pI2CBus && info->ddc2) {
- 
 -    if (info->pI2CBus && info->ddc2 && (info->DDCReg != RADEON_LCD_GPIO_MASK)) {
 -	OUTREG(info->DDCReg, INREG(info->DDCReg) &
++    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
@@@ -612,15 -629,17 +625,17 @@@
  		    break;
  	    }
  	    usleep(15000);
 -	    OUTREG(info->DDCReg,
 -		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
 +	    OUTREG(DDCReg,
 +		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
  	    usleep(15000);
  
 -	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
 -	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
 +	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
 +	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
  	    usleep(15000);
- 	    if(*MonInfo) break;
+ 	    if(*MonInfo)  break;
  	}
 -    } else if (info->pI2CBus && info->ddc2 && info->DDCReg == RADEON_LCD_GPIO_MASK) {
 -         *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);
++    } 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;
diff --cc src/radeon_driver.c
index 712ec3b,b9cce22..1875244
@@@ -2662,11 -3100,6 +2694,11 @@@
      pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
      pScrn->monitor     = pScrn->confScreen->monitor;
  
 +   /* Allocate an xf86CrtcConfig */
 +    xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
-    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
++    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 +
 +
      if (!RADEONPreInitVisual(pScrn))
  	goto fail;
  
@@@ -5870,11 -6354,62 +5890,67 @@@
      RADEONInfoPtr  info0     = NULL;
      ScrnInfoPtr    pScrn0    = NULL;
  
 +    if (crtc_mask & 1)
 +      xf86PrintModeline(pScrn->scrnIndex, crtc1);
 +    if (crtc_mask & 2)
 +      xf86PrintModeline(pScrn->scrnIndex, crtc2);
 +
+ #if RADEON_DEBUG
+     if (crtc1 && (crtc_mask & 1)) {
+     	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+ 	   crtc1->name,
+ 	   crtc1->Clock/1000.0,
+ 
+ 	   crtc1->HDisplay,
+ 	   crtc1->HSyncStart,
+ 	   crtc1->HSyncEnd,
+ 	   crtc1->HTotal,
+ 
+ 	   crtc1->VDisplay,
+ 	   crtc1->VSyncStart,
+ 	   crtc1->VSyncEnd,
+ 	   crtc1->VTotal,
+ 	   pScrn->depth,
+ 	   pScrn->bitsPerPixel);
+     	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
+     	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
+     	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
+     	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
+     	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
+     	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
+     	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
+     	ErrorF("\n");
+     }
+     if (crtc2 && (crtc_mask & 2)) {
+         ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+ 	   crtc2->name,
+ 	   crtc2->Clock/1000.0,
+ 
+ 	   crtc2->CrtcHDisplay,
+ 	   crtc2->CrtcHSyncStart,
+ 	   crtc2->CrtcHSyncEnd,
+ 	   crtc2->CrtcHTotal,
+ 
+ 	   crtc2->CrtcVDisplay,
+ 	   crtc2->CrtcVSyncStart,
+ 	   crtc2->CrtcVSyncEnd,
+ 	   crtc2->CrtcVTotal,
+ 	   pScrn->depth,
+ 	   pScrn->bitsPerPixel);
+         if (crtc2->Flags & V_DBLSCAN)   ErrorF(" D");
+         if (crtc2->Flags & V_CSYNC)     ErrorF(" C");
+         if (crtc2->Flags & V_INTERLACE) ErrorF(" I");
+         if (crtc2->Flags & V_PHSYNC)    ErrorF(" +H");
+         if (crtc2->Flags & V_NHSYNC)    ErrorF(" -H");
+         if (crtc2->Flags & V_PVSYNC)    ErrorF(" +V");
+         if (crtc2->Flags & V_NVSYNC)    ErrorF(" -V");
+     	ErrorF("\n");
+     }
+ #endif
+ 
+     if (crtc1 && (crtc_mask & 1))
+         info->Flags = crtc1->Flags;
+ 
      RADEONInitMemMapRegisters(pScrn, save, info);
      RADEONInitCommonRegisters(save, info);
  
diff --cc src/radeon_modes.c
index 064b1ae,1a63971..4d7251f
@@@ -76,7 -144,295 +76,6 @@@
      pScrn->displayWidth = dummy;
  }
  
- 
 -/* When no mode provided in config file, this will add all modes supported in
 - * DDC date the pScrn->modes list
 - */
 -static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
 -{
 -    DisplayModePtr  p;
 -    DisplayModePtr  last  = NULL;
 -    DisplayModePtr  new   = NULL;
 -    DisplayModePtr  first = NULL;
 -    int             count = 0;
 -    int             j, tmp;
 -    char            stmp[32];
 -
 -    /* 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;
 -
 -	    if (d_timings->h_active == 0 || d_timings->v_active == 0) break;
 -
 -	    new = xnfcalloc(1, sizeof (DisplayModeRec));
 -	    memset(new, 0, sizeof (DisplayModeRec));
 -
 -	    new->HDisplay   = d_timings->h_active;
 -	    new->VDisplay   = d_timings->v_active;
 -
 -	    sprintf(stmp, "%dx%d", new->HDisplay, new->VDisplay);
 -	    new->name       = xnfalloc(strlen(stmp) + 1);
 -	    strcpy(new->name, stmp);
 -
 -	    new->HTotal     = new->HDisplay + d_timings->h_blanking;
 -	    new->HSyncStart = new->HDisplay + d_timings->h_sync_off;
 -	    new->HSyncEnd   = new->HSyncStart + d_timings->h_sync_width;
 -	    new->VTotal     = new->VDisplay + d_timings->v_blanking;
 -	    new->VSyncStart = new->VDisplay + d_timings->v_sync_off;
 -	    new->VSyncEnd   = new->VSyncStart + d_timings->v_sync_width;
 -	    new->Clock      = d_timings->clock / 1000;
 -	    new->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
 -	    new->status     = MODE_OK;
 -#ifdef M_T_PREFERRED
 -	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
 -	      new->type     |= M_T_PREFERRED;
 -#endif
 -#ifdef M_T_DRIVER
 -	      new->type     |= M_T_DRIVER;
 -#endif
 -
 -	    switch (d_timings->misc) {
 -	    case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
 -	    case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
 -	    case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
 -	    case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
 -	    }
 -	    count++;
 -
 -	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -		       "Valid Mode from Detailed timing table: %s\n",
 -		       new->name);
 -
 -	    RADEONSortModes(&new, &first, &last);
 -	}
 -    }
 -
 -    /* Search thru standard VESA modes from EDID */
 -    for (j = 0; j < 8; j++) {
 -        if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
 -               continue;
 -	for (p = pScrn->monitor->Modes; p; p = p->next) {
 -	    /* Ignore all double scan modes */
 -	    if (p->Flags & V_DBLSCAN)
 -		continue;
 -	    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? */
 -		    new = xnfcalloc(1, sizeof (DisplayModeRec));
 -		    memcpy(new, p, sizeof(DisplayModeRec));
 -		    new->name = xnfalloc(strlen(p->name) + 1);
 -		    strcpy(new->name, p->name);
 -		    new->status = MODE_OK;
 -		    if ((new->type != M_T_USERDEF) && (new->type))
 -		    	new->type   = M_T_DEFAULT;
 -
 -		    count++;
 -
 -		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -			       "Valid Mode from standard timing table: %s\n",
 -			       new->name);
 -
 -		    RADEONSortModes(&new, &first, &last);
 -		    break;
 -		}
 -	    }
 -	}
 -    }
 -
 -    /* Search thru established modes from EDID */
 -    tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
 -    for (j = 0; j < 16; j++) {
 -	if (tmp & (1 << j)) {
 -	    for (p = pScrn->monitor->Modes; p; p = p->next) {
 -		/* Ignore all double scan modes */
 -		if (p->Flags & V_DBLSCAN)
 -		    continue;
 -		if ((est_timings[j].hsize == p->HDisplay) &&
 -		    (est_timings[j].vsize == p->VDisplay)) {
 -		    float  refresh =
 -			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
 -
 -		    if (abs((float)est_timings[j].refresh - refresh) < 1.0) {
 -			/* Is this good enough? */
 -			new = xnfcalloc(1, sizeof (DisplayModeRec));
 -			memcpy(new, p, sizeof(DisplayModeRec));
 -			new->name = xnfalloc(strlen(p->name) + 1);
 -			strcpy(new->name, p->name);
 -			new->status = MODE_OK;
 -		    	if ((new->type != M_T_USERDEF) && (new->type))
 -		    	    new->type   = M_T_DEFAULT;
 -
 -			count++;
 -
 -			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -				   "Valid Mode from established timing "
 -				   "table: %s\n", new->name);
 -
 -			RADEONSortModes(&new, &first, &last);
 -			break;
 -		    }
 -		}
 -	    }
 -	}
 -    }
 -
 -    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	       "Total of %d mode(s) found.\n", count);
 -
 -    return first;
 -}
 -
 -/* XFree86's xf86ValidateModes routine doesn't work well with DDC modes,
 - * so here is our own validation routine.
 - */
 -int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 -			   RADEONMonitorType DisplayType, int crtc2)
 -{
 -    RADEONInfoPtr   info       = RADEONPTR(pScrn1);
 -    DisplayModePtr  p;
 -    DisplayModePtr  last       = NULL;
 -    DisplayModePtr  first      = NULL;
 -    DisplayModePtr  ddcModes   = NULL;
 -    int             count      = 0;
 -    int             i, width, height;
 -    ScrnInfoPtr pScrn = pScrn1;
 -
 -    if (crtc2)
 -	pScrn = info->CRT2pScrn;
 -
 -    pScrn->virtualX = pScrn1->display->virtualX;
 -    pScrn->virtualY = pScrn1->display->virtualY;
 -
 -    if (pScrn->monitor->DDC) {
 -	int  maxVirtX = pScrn->virtualX;
 -	int  maxVirtY = pScrn->virtualY;
 -
 -	/* Collect all of the DDC modes */
 -	first = last = ddcModes = RADEONDDCModes(pScrn, pScrn->monitor->DDC);
 -
 -	for (p = ddcModes; p; p = p->next) {
 -
 -	    /* If primary head is a flat panel, use RMX by default */
 -	    if ((!info->IsSecondary && DisplayType != MT_CRT) &&
 -		(!info->ddc_mode) && (!crtc2)) {
 -		/* These values are effective values after expansion.
 -		 * They are not really used to set CRTC registers.
 -		 */
 -		p->HTotal     = info->PanelXRes + info->HBlank;
 -		p->HSyncStart = info->PanelXRes + info->HOverPlus;
 -		p->HSyncEnd   = p->HSyncStart + info->HSyncWidth;
 -		p->VTotal     = info->PanelYRes + info->VBlank;
 -		p->VSyncStart = info->PanelYRes + info->VOverPlus;
 -		p->VSyncEnd   = p->VSyncStart + info->VSyncWidth;
 -		p->Clock      = info->DotClock;
 -
 -		p->Flags     |= RADEON_USE_RMX;
 -	    }
 -
 -	    maxVirtX = MAX(maxVirtX, p->HDisplay);
 -	    maxVirtY = MAX(maxVirtY, p->VDisplay);
 -	    count++;
 -
 -	    last = p;
 -	}
 -
 -	/* Match up modes that are specified in the XF86Config file */
 -	if (ppModeName[0]) {
 -	    DisplayModePtr  next;
 -
 -	    /* Reset the max virtual dimensions */
 -	    maxVirtX = pScrn->virtualX;
 -	    maxVirtY = pScrn->virtualY;
 -
 -	    /* Reset list */
 -	    first = last = NULL;
 -
 -	    for (i = 0; ppModeName[i]; i++) {
 -		/* FIXME: Use HDisplay and VDisplay instead of mode string */
 -		if (sscanf(ppModeName[i], "%dx%d", &width, &height) == 2) {
 -		    for (p = ddcModes; p; p = next) {
 -			next = p->next;
 -
 -			if (p->HDisplay == width && p->VDisplay == height) {
 -			    /* We found a DDC mode that matches the one
 -                               requested in the XF86Config file */
 -			    p->type |= M_T_USERDEF;
 -
 -			    /* Update  the max virtual setttings */
 -			    maxVirtX = MAX(maxVirtX, width);
 -			    maxVirtY = MAX(maxVirtY, height);
 -
 -			    /* Unhook from DDC modes */
 -			    if (p->prev) p->prev->next = p->next;
 -			    if (p->next) p->next->prev = p->prev;
 -			    if (p == ddcModes) ddcModes = p->next;
 -
 -			    /* Add to used modes */
 -			    RADEONSortModes(&p, &first, &last);
 -
 -			    break;
 -			}
 -		    }
 -		}
 -	    }
 -
 -	    /*
 -	     * Add remaining DDC modes if they're smaller than the user
 -	     * specified modes
 -	     */
 -	    for (p = ddcModes; p; p = next) {
 -		next = p->next;
 -		if (p->HDisplay <= maxVirtX && p->VDisplay <= maxVirtY) {
 -		    /* Unhook from DDC modes */
 -		    if (p->prev) p->prev->next = p->next;
 -		    if (p->next) p->next->prev = p->prev;
 -		    if (p == ddcModes) ddcModes = p->next;
 -
 -		    /* Add to used modes */
 -		    RADEONSortModes(&p, &first, &last);
 -		}
 -	    }
 -
 -	    /* Delete unused modes */
 -	    while (ddcModes)
 -		xf86DeleteMode(&ddcModes, ddcModes);
 -	} else {
 -	    /*
 -	     * No modes were configured, so we make the DDC modes
 -	     * available for the user to cycle through.
 -	     */
 -	    for (p = ddcModes; p; p = p->next)
 -		p->type |= M_T_USERDEF;
 -	}
 -
 -        if (crtc2) {
 -            pScrn->virtualX = maxVirtX;
 -            pScrn->virtualY = maxVirtY;
 -	} else {
 -	    pScrn->virtualX = pScrn->display->virtualX = maxVirtX;
 -	    pScrn->virtualY = pScrn->display->virtualY = maxVirtY;
 -	}
 -    }
 -
 -    /* Close the doubly-linked mode list, if we found any usable modes */
 -    if (last) {
 -	last->next   = first;
 -	first->prev  = last;
 -	pScrn->modes = first;
 -	RADEONSetPitch(pScrn);
 -    }
 -
 -    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 -	       "Total number of valid DDC mode(s) found: %d\n", count);
 -
 -    return count;
 -}
 -
  /* This is used only when no mode is specified for FP and no ddc is
   * available.  We force it to native mode, if possible.
   */
@@@ -186,12 -542,7 +185,12 @@@
  
  	new->type      |= M_T_USERDEF;
  
 -	RADEONSortModes(&new, &first, &last);
 +	new->next       = NULL;
 +	new->prev       = last;
 +
 +	if (last) last->next = new;
 +	last = new;
- 	if (!first) first = new;
++        if (!first) first = new;
  
  	pScrn->display->virtualX =
  	    pScrn->virtualX = MAX(pScrn->virtualX, width);
@@@ -237,12 -588,7 +236,9 @@@
  
  		new->type      |= M_T_DEFAULT;
  
- 		new->next       = NULL;
- 		new->prev       = last;
- 
 -		RADEONSortModes(&new, &first, &last);
 +		if (last) last->next = new;
- 		last = new;
++	        last = new;
 +		if (!first) first = new;
  	    }
  	}
      }
@@@ -261,64 -607,164 +257,64 @@@
      return count;
  }
  
 -
 -int RADEONValidateMergeModes(ScrnInfoPtr pScrn1)
 +DisplayModePtr
 +RADEONProbeOutputModes(xf86OutputPtr output)
  {
 -    RADEONInfoPtr   info             = RADEONPTR(pScrn1);
 -    ClockRangePtr   clockRanges;
 -    int             modesFound;
 -    ScrnInfoPtr pScrn = info->CRT2pScrn;
 -
 -    /* fill in pScrn2 */
 -    pScrn->videoRam = pScrn1->videoRam;
 -    pScrn->depth = pScrn1->depth;
 -    pScrn->numClocks = pScrn1->numClocks;
 -    pScrn->progClock = pScrn1->progClock;
 -    pScrn->fbFormat = pScrn1->fbFormat;
 -    pScrn->videoRam = pScrn1->videoRam;
 -    pScrn->maxHValue = pScrn1->maxHValue;
 -    pScrn->maxVValue = pScrn1->maxVValue;
 -    pScrn->xInc = pScrn1->xInc;
 -
 -    if (info->NoVirtual) {
 -	pScrn1->display->virtualX = 0;
 -        pScrn1->display->virtualY = 0;
 +    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;
 +
 +    /* force reprobe */
 +    radeon_output->MonType = MT_UNKNOWN;
 +	
 +    RADEONConnectorFindMonitor(pScrn, output);
 +
 +    if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
 +      edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
 +      xf86OutputSetEDID (output, edid_mon);
 +      
 +      modes = xf86OutputGetEDIDModes (output);
 +      return modes;
 +    }
 +    if (radeon_output->type == OUTPUT_LVDS) {
 +      /* okay we got DDC info */
 +      if (output->MonInfo) {
 +	/* Debug info for now, at least */
 +	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
 +	xf86PrintEDID(output->MonInfo);
 +	
 +	modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
 +	
 +	for (mode = modes; mode != NULL; mode = mode->next) {
 +	  if (mode->Flags & V_DBLSCAN) {
 +	    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
 +	    mode->status = MODE_CLOCK_RANGE;
 +	  }
 +	}
 +	xf86PruneInvalidModes(pScrn, &modes, TRUE);
 +	
 +	/* do some physcial size stuff */
 +      }
 +      
 +      
 +      if (modes == NULL) {
 +	MonRec fixed_mon;
- 	
++
 +	RADEONValidateFPModes(pScrn, pScrn->display->modes, &modes);
 +      }
 +    }
 +    
 +    if (modes) {
 +      xf86ValidateModesUserConfig(pScrn, modes);
 +      xf86PruneInvalidModes(pScrn, &modes,
 +				  FALSE);
      }
 -
 -    if (pScrn->monitor->DDC) {
 -        /* If we still don't know sync range yet, let's try EDID.
 -         *
 -         * Note that, since we can have dual heads, Xconfigurator
 -         * may not be able to probe both monitors correctly through
 -         * vbe probe function (RADEONProbeDDC). Here we provide an
 -         * additional way to auto-detect sync ranges if they haven't
 -         * been added to XF86Config manually.
 -         */
 -        if (pScrn->monitor->nHsync <= 0)
 -            RADEONSetSyncRangeFromEdid(pScrn, 1);
 -        if (pScrn->monitor->nVrefresh <= 0)
 -            RADEONSetSyncRangeFromEdid(pScrn, 0);
 -    }
 -
 -    /* Get mode information */
 -    pScrn->progClock               = TRUE;
 -    clockRanges                    = xnfcalloc(sizeof(*clockRanges), 1);
 -    clockRanges->next              = NULL;
 -    clockRanges->minClock          = info->pll.min_pll_freq;
 -    clockRanges->maxClock          = info->pll.max_pll_freq * 10;
 -    clockRanges->clockIndex        = -1;
 -    clockRanges->interlaceAllowed  = (info->MergeType == MT_CRT);
 -    clockRanges->doubleScanAllowed = (info->MergeType == MT_CRT);
 -
 -    /* We'll use our own mode validation routine for DFP/LCD, since
 -     * xf86ValidateModes does not work correctly with the DFP/LCD modes
 -     * 'stretched' from their native mode.
 -     */
 -    if (info->MergeType == MT_CRT && !info->ddc_mode) {
 -	xf86SetDDCproperties(pScrn, pScrn->monitor->DDC); 
 -	modesFound =
 -	    xf86ValidateModes(pScrn,
 -			      pScrn->monitor->Modes,
 -			      pScrn1->display->modes,
 -			      clockRanges,
 -			      NULL,                  /* linePitches */
 -			      8 * 64,                /* minPitch */
 -			      8 * 1024,              /* maxPitch */
 -			      info->allowColorTiling ? 2048 :
 -			          64 * pScrn1->bitsPerPixel, /* pitchInc */
 -			      128,                   /* minHeight */
 -			      info->MaxLines,        /* maxHeight */
 -			      pScrn1->display->virtualX ? pScrn1->virtualX : 0,
 -			      pScrn1->display->virtualY ? pScrn1->virtualY : 0,
 -			      info->FbMapSize,
 -			      LOOKUP_BEST_REFRESH);
 -
 -	if (modesFound == -1) return 0;
 -
 -	xf86PruneDriverModes(pScrn);
 -	if (!modesFound || !pScrn->modes) {
 -	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
 -	    return 0;
 -	}
 -
 -    } else {
 -	/* First, free any allocated modes during configuration, since
 -	 * we don't need them
 -	 */
 -	while (pScrn->modes)
 -	    xf86DeleteMode(&pScrn->modes, pScrn->modes);
 -	while (pScrn->modePool)
 -	    xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
 -
 -	/* Next try to add DDC modes */
 -	modesFound = RADEONValidateDDCModes(pScrn, pScrn1->display->modes,
 -					    info->MergeType, 1);
 -
 -	/* If that fails and we're connect to a flat panel, then try to
 -         * add the flat panel modes
 -	 */
 -	if (info->MergeType != MT_CRT) {
 -	    
 -	    /* some panels have DDC, but don't have internal scaler.
 -	     * in this case, we need to validate additional modes
 -	     * by using on-chip RMX.
 -	     */
 -	    int user_modes_asked = 0, user_modes_found = 0, i;
 -	    DisplayModePtr  tmp_mode = pScrn->modes;
 -	    while (pScrn1->display->modes[user_modes_asked]) user_modes_asked++;	    
 -	    if (tmp_mode) {
 -		for (i = 0; i < modesFound; i++) {
 -		    if (tmp_mode->type & M_T_USERDEF) user_modes_found++;
 -		    tmp_mode = tmp_mode->next;
 -		}
 -	    }
 -
 - 	    if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
 -		/* when panel size is not valid, try to validate 
 -		 * mode using xf86ValidateModes routine
 -		 * This can happen when DDC is disabled.
 -		 */
 -		/* if (info->PanelXRes < 320 || info->PanelYRes < 200) */
 -		    modesFound =
 -			xf86ValidateModes(pScrn,
 -					  pScrn->monitor->Modes,
 -					  pScrn1->display->modes,
 -					  clockRanges,
 -					  NULL,                  /* linePitches */
 -					  8 * 64,                /* minPitch */
 -					  8 * 1024,              /* maxPitch */
 -					  info->allowColorTiling ? 2048 :
 -					      64 * pScrn1->bitsPerPixel, /* pitchInc */
 -					  128,                   /* minHeight */
 -					  info->MaxLines,        /* maxHeight */
 -					  pScrn1->display->virtualX,
 -					  pScrn1->display->virtualY,
 -					  info->FbMapSize,
 -					  LOOKUP_BEST_REFRESH);
 -
 -	    } 
 -        }
 -
 -	/* Setup the screen's clockRanges for the VidMode extension */
 -	if (!pScrn->clockRanges) {
 -	    pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1);
 -	    memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges));
 -	    pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH;
 -	}
 -
 -	/* Fail if we still don't have any valid modes */
 -	if (modesFound < 1) {
 -	    if (info->MergeType == MT_CRT) {
 -		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -			   "No valid DDC modes found for this CRT\n");
 -		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -			   "Try turning off the \"DDCMode\" option\n");
 -	    } else {
 -		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 -			   "No valid mode found for this DFP/LCD\n");
 -	    }
 -	    return 0;
 -	}
 -    }
 -    return modesFound;
 +    return modes;
  }
 +
diff-tree 83f81ed5e3c33c94c80500316c37a7cbfc51f41f (from 5fc21cd34436919300018d8d4850fc67db284eb3)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon May 7 22:54:16 2007 +0200

    RADEON: Fix cursor handling for randr

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index f6c116c..68771f8 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -185,49 +185,27 @@ radeon_crtc_set_cursor_position (xf86Crt
     int crtc_id = radeon_crtc->crtc_id;
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     unsigned char     *RADEONMMIO = info->MMIO;
-    int temp;
-    int oldx = x, oldy = y;
-    int hotspotx = 0, hotspoty = 0;
-    int c;
-    int xorigin, yorigin;
-    int		       stride     = 256;
-    int thisx, thisy;
-
-    oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
-    oldy += pScrn->frameY0;
-
-    x = oldx;
-    y = oldy;
-
+    int xorigin = 0, yorigin = 0;
+    int stride = 256;
     DisplayModePtr mode = &crtc->mode;
-    thisx = x - crtc->x;
-    thisy = y - crtc->y;
-
-    if (thisx >= mode->HDisplay ||
-	thisy >= mode->VDisplay) 
-    {
-	thisx = 0;
-	thisy = 0;
-    }
 
-    temp = 0;
-    xorigin = 0;
-    yorigin = 0;
-    if (thisx < 0) xorigin = -thisx+1;
-    if (thisy < 0) yorigin = -thisy+1;
-#if 0
-    if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
-    if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
-#endif
-    temp |= (xorigin ? 0 : thisx) << 16;
-    temp |= (yorigin ? 0 : thisy);
+    if (x < 0)                        xorigin = -x+1;
+    if (y < 0)                        yorigin = -y+1;
+    if (xorigin >= CURSOR_WIDTH)  xorigin = CURSOR_WIDTH - 1;
+    if (yorigin >= CURSOR_HEIGHT) yorigin = CURSOR_HEIGHT - 1;
+
+    if (mode->Flags & V_INTERLACE)
+	y /= 2;
+    else if (mode->Flags & V_DBLSCAN)
+	y *= 2;
 
     if (crtc_id == 0) {
 	OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
 					   | (xorigin << 16)
 					   | yorigin));
-	OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK |
-					   temp));
+	OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
+					   | ((xorigin ? 0 : x) << 16)
+					   | (yorigin ? 0 : y)));
 	RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
 			info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
 	OUTREG(RADEON_CUR_OFFSET,
@@ -236,8 +214,9 @@ radeon_crtc_set_cursor_position (xf86Crt
 	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
 					    | (xorigin << 16)
 					    | yorigin));
-	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK |
-					    temp));
+	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
+					   | ((xorigin ? 0 : x) << 16)
+					   | (yorigin ? 0 : y)));
 	RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
 			info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
 	OUTREG(RADEON_CUR2_OFFSET,
@@ -285,119 +264,7 @@ radeon_crtc_set_cursor_colors (xf86CrtcP
     info->cursor_bg = bg;
 }
 
-/* Copy cursor image from `image' to video memory.  RADEONSetCursorPosition
- * will be called after this, so we can ignore xorigin and yorigin.
- */
-static void RADEONLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *image)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    CARD8         *s          = (CARD8 *)(pointer)image;
-    CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
-    CARD32         save1      = 0;
-    CARD32         save2      = 0;
-    CARD8	   chunk;
-    CARD32         i, j;
-
-    RADEONCTRACE(("RADEONLoadCursorImage (at %x)\n", info->cursor_offset));
-
-
-    if (!info->IsSecondary) {
-	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save1 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
-
-	if (pRADEONEnt->HasCRTC2) {
-	    save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
-	    save2 |= (CARD32) (2 << 20);
-	    OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-	}
-    }
-
-    if (info->IsSecondary) {
-	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save2 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-    }
-
-#ifdef ARGB_CURSOR
-    info->cursor_argb = FALSE;
-#endif
-
-    /*
-     * Convert the bitmap to ARGB32.
-     *
-     * HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 always places
-     * source in the low bit of the pair and mask in the high bit,
-     * and MSBFirst machines set HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
-     * (which actually bit swaps the image) to make the bits LSBFirst
-     */
-    CURSOR_SWAPPING_START();
-#define ARGB_PER_CHUNK	(8 * sizeof (chunk) / 2)
-    for (i = 0; i < (CURSOR_WIDTH * CURSOR_HEIGHT / ARGB_PER_CHUNK); i++) {
-        chunk = *s++;
-	for (j = 0; j < ARGB_PER_CHUNK; j++, chunk >>= 2)
-	    *d++ = mono_cursor_color[chunk & 3];
-    }
-    CURSOR_SWAPPING_END();
-
-    info->cursor_bg = mono_cursor_color[2];
-    info->cursor_fg = mono_cursor_color[3];
-
-    if (!info->IsSecondary)
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-
-    OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-
-}
-
-/* Hide hardware cursor. */
-static void RADEONHideCursor(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int c;
-    RADEONCTRACE(("RADEONHideCursor\n"));
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-        RADEONCrtcCursor(xf86_config->crtc[c], TRUE);
-}
-
-/* Show hardware cursor. */
-static void RADEONShowCursor(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int c;
-
-    RADEONCTRACE(("RADEONShowCursor\n"));
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-        RADEONCrtcCursor(xf86_config->crtc[c], FALSE);
-}
-
-/* Determine if hardware cursor is in use. */
-static Bool RADEONUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
-{
-    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
-    RADEONInfoPtr  info  = RADEONPTR(pScrn);
-
-    return info->cursor ? TRUE : FALSE;
-}
-
 #ifdef ARGB_CURSOR
-#include "cursorstr.h"
-
-static Bool RADEONUseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
-{
-    if (RADEONUseHWCursor(pScreen, pCurs) &&
-	pCurs->bits->height <= CURSOR_HEIGHT && pCurs->bits->width <= CURSOR_WIDTH)
-	return TRUE;
-    return FALSE;
-}
 
 void
 radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
@@ -426,9 +293,7 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt
 	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
     }
 
-#ifdef ARGB_CURSOR
     info->cursor_argb = TRUE;
-#endif
 
     CURSOR_SWAPPING_START();
 
@@ -466,74 +331,6 @@ radeon_crtc_load_cursor_argb (xf86CrtcPt
     }
 }
 
-static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
-    int            x, y, w, h;
-    CARD32         save1      = 0;
-    CARD32         save2      = 0;
-    CARD32	  *image = pCurs->bits->argb;
-    CARD32	  *i;
-
-    RADEONCTRACE(("RADEONLoadCursorARGB\n"));
-
-    if (!info->IsSecondary) {
-	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save1 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
-
-	if (pRADEONEnt->HasCRTC2) {
-	    save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
-	    save2 |= (CARD32) (2 << 20);
-	    OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-	}
-    }
-
-    if (info->IsSecondary) {
-	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
-	save2 |= (CARD32) (2 << 20);
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
-    }
-
-#ifdef ARGB_CURSOR
-    info->cursor_argb = TRUE;
-#endif
-
-    CURSOR_SWAPPING_START();
-
-    w = pCurs->bits->width;
-    if (w > CURSOR_WIDTH)
-	w = CURSOR_WIDTH;
-    h = pCurs->bits->height;
-    if (h > CURSOR_HEIGHT)
-	h = CURSOR_HEIGHT;
-    for (y = 0; y < h; y++)
-    {
-	i = image;
-	image += pCurs->bits->width;
-	for (x = 0; x < w; x++)
-	    *d++ = *i++;
-	/* pad to the right with transparent */
-	for (; x < CURSOR_WIDTH; x++)
-	    *d++ = 0;
-    }
-    /* pad below with transparent */
-    for (; y < CURSOR_HEIGHT; y++)
-	for (x = 0; x < CURSOR_WIDTH; x++)
-	    *d++ = 0;
-
-    CURSOR_SWAPPING_END ();
-
-    if (!info->IsSecondary)
-	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
-
-    OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
-
-}
-
 #endif
 
 
diff-tree 5fc21cd34436919300018d8d4850fc67db284eb3 (from 99b3df154317f0209618e532282a3e7ad091c00f)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Mon May 7 13:31:20 2007 -0700

    - fix randr 1.2 on pre-RV350 chips by enabling DAC_MACRO_CNTL writes
    - set dac_cntl on non-primary crtcs
    - set XCRT_CNT_EN in CRTC_EXT_CNTL just because
    - fix warnings in calls to xf86PrintModeline (wants screen index not
      pScrnInfo)

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7a8f94f..f0015ae 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1431,8 +1431,7 @@ static void RADEONDacPowerSet(ScrnInfoPt
 	CARD32 dac_cntl;
 	CARD32 dac_macro_cntl = 0;
 	dac_cntl = INREG(RADEON_DAC_CNTL);
-	if ((!info->IsMobility) || (info->ChipFamily >= CHIP_FAMILY_RV350)) 
-	    dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
+	dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
 	if (IsOn) {
 	    dac_cntl &= ~RADEON_DAC_PDWN;
 	    dac_macro_cntl &= ~(RADEON_DAC_PDWN_R |
@@ -1446,8 +1445,7 @@ static void RADEONDacPowerSet(ScrnInfoPt
 	}
 	ErrorF("Setting IsOn %d DAC CNTL %08X and DAC MACRO_CNTL %08X\n", IsOn, dac_cntl, dac_macro_cntl);
 	OUTREG(RADEON_DAC_CNTL, dac_cntl);
-	if ((!info->IsMobility) || (info->ChipFamily >= CHIP_FAMILY_RV350)) 
-	    OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
+	OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
     } else {
 	CARD32 tv_dac_cntl;
 	CARD32 fp2_gen_cntl;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a580583..712ec3b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5302,10 +5302,6 @@ static void RADEONInitDACRegisters(ScrnI
         } 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));
-
     } else {
         if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
             save->disp_output_cntl = info->SavedReg.disp_output_cntl &
@@ -5315,6 +5311,9 @@ static void RADEONInitDACRegisters(ScrnI
             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(ScrnInfoPtr pScrn, RADEONSavePtr save,
@@ -5432,7 +5431,8 @@ static Bool RADEONInitCrtcRegisters(Scrn
 			      ? RADEON_CRTC_INTERLACE_EN
 			      : 0));
 
-    save->crtc_ext_cntl |= (RADEON_CRTC_CRT_ON |
+    save->crtc_ext_cntl |= (RADEON_XCRT_CNT_EN|
+			    RADEON_CRTC_CRT_ON |
 			    RADEON_CRTC_VSYNC_DIS |
 			    RADEON_CRTC_HSYNC_DIS |
 			    RADEON_CRTC_DISPLAY_DIS);
@@ -5871,9 +5871,9 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
     ScrnInfoPtr    pScrn0    = NULL;
 
     if (crtc_mask & 1)
-      xf86PrintModeline(pScrn, crtc1);
+      xf86PrintModeline(pScrn->scrnIndex, crtc1);
     if (crtc_mask & 2)
-      xf86PrintModeline(pScrn, crtc2);
+      xf86PrintModeline(pScrn->scrnIndex, crtc2);
 
     RADEONInitMemMapRegisters(pScrn, save, info);
     RADEONInitCommonRegisters(save, info);
diff-tree 99b3df154317f0209618e532282a3e7ad091c00f (from 2a1cd107a593630001799d6cd9e72c64222553b2)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Mon May 7 19:02:35 2007 +0200

    RADEON - update randr cursor handling, LVDS setup fix
    
    - quick fix for the cursor handling to update to the latest
    server bits
    - make sure connector type is CONNECTOR_PROPRIETARY for LVDS.

diff --git a/src/radeon.h b/src/radeon.h
index 383a1c7..0eb6169 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -889,6 +889,19 @@ extern Bool RADEONInit2(ScrnInfoPtr pScr
 			DisplayModePtr crtc2, int crtc_mask,
 			RADEONSavePtr save, RADEONMonitorType montype);
 
+void
+radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
+void
+radeon_crtc_show_cursor (xf86CrtcPtr crtc);
+void
+radeon_crtc_hide_cursor (xf86CrtcPtr crtc);
+void
+radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
+void
+radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg);
+void
+radeon_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image);
+
 #ifdef XF86DRI
 #ifdef USE_XAA
 extern void        RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 1d4c9bb..fa316a6 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -286,6 +286,11 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 		else connector_found = 3;
 	    }
 
+	    /* some bioses seem to list the LVDS port as DVI hack around that here */
+	    if (pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_DVI_D) {
+		pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_PROPRIETARY;
+	    }
+
 	    if ((tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42))) {
 	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
 		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 6d61b07..f6c116c 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -103,43 +103,41 @@ static CARD32 mono_cursor_color[] = {
 
 #endif
 
-static void
-RADEONCrtcCursor(xf86CrtcPtr crtc,  Bool force)
+void
+radeon_crtc_show_cursor (xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
     int crtc_id = radeon_crtc->crtc_id;
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    Bool		show;
     unsigned char     *RADEONMMIO = info->MMIO;
-    CARD32 save1 = 0, save2 = 0;
 
-    if (!crtc->enabled && !crtc->cursorShown)
-      return;
+    if (crtc_id == 0) 
+	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
+		~RADEON_CRTC_CUR_EN);
+    else if (crtc_id == 1)
+	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
+		~RADEON_CRTC2_CUR_EN);
 
-    
-    show = crtc->cursorInRange && crtc->enabled;
-    if (show && (force || !crtc->cursorShown))
-    {
-	if (crtc_id == 0) 
-	    OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
-		    ~RADEON_CRTC_CUR_EN);
-	else if (crtc_id == 1)
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
-		    ~RADEON_CRTC2_CUR_EN);
-	crtc->cursorShown = TRUE;
-    } else if (!show && (force || crtc->cursorShown)) {
-
-	if (crtc_id == 0)
-	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
-	else if (crtc_id == 1)
-	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
 
-	crtc->cursorShown = FALSE;
-    }
-    
-}    
+}
+
+void
+radeon_crtc_hide_cursor (xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    int crtc_id = radeon_crtc->crtc_id;
+    RADEONInfoPtr      info       = RADEONPTR(pScrn);
+    unsigned char     *RADEONMMIO = info->MMIO;
+
+    if (crtc_id == 0)
+	OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
+    else if (crtc_id == 1)
+	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
+
+
+}
 
 /* Set cursor foreground and background colors */
 static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
@@ -179,20 +177,21 @@ static void RADEONSetCursorColors(ScrnIn
     info->cursor_bg = bg;
 }
 
-static void
-RADEONRandrSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+void
+radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 {
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    int crtc_id = radeon_crtc->crtc_id;
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     unsigned char     *RADEONMMIO = info->MMIO;
-    xf86CursorInfoPtr  cursor     = info->cursor;
-    Bool inrange;
     int temp;
     int oldx = x, oldy = y;
     int hotspotx = 0, hotspoty = 0;
     int c;
     int xorigin, yorigin;
     int		       stride     = 256;
+    int thisx, thisy;
 
     oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
     oldy += pScrn->frameY0;
@@ -200,70 +199,90 @@ RADEONRandrSetCursorPosition(ScrnInfoPtr
     x = oldx;
     y = oldy;
 
-    for (c = 0 ; c < xf86_config->num_crtc; c++) {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-	DisplayModePtr mode = &crtc->mode;
-	int thisx = x - crtc->x;
-	int thisy = y - crtc->y;
-	
-	if (!crtc->enabled && !crtc->cursorShown)
-	    continue;
-
-	/*
-	 * There is a screen display problem when the cursor position is set
-	 * wholely outside of the viewport.  We trap that here, turning the
-	 * cursor off when that happens, and back on when it comes back into
-	 * the viewport.
-	 */
-	inrange = TRUE;
-	if (thisx >= mode->HDisplay ||
-	    thisy >= mode->VDisplay ||
-	    thisx <= -cursor->MaxWidth || thisy <= -cursor->MaxHeight) 
-	{
-	    inrange = FALSE;
-	    thisx = 0;
-	    thisy = 0;
-	}
+    DisplayModePtr mode = &crtc->mode;
+    thisx = x - crtc->x;
+    thisy = y - crtc->y;
 
-	temp = 0;
-	xorigin = 0;
-	yorigin = 0;
-	if (thisx < 0) xorigin = -thisx+1;
-	if (thisy < 0) yorigin = -thisy+1;
-	if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
-	if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
-
-	temp |= (xorigin ? 0 : thisx) << 16;
-	temp |= (yorigin ? 0 : thisy);
-
-	if (c == 0) {
-	    OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
-					       | (xorigin << 16)
-					       | yorigin));
-	    OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK |
-					       temp));
-	    RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
-			  info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
-	    OUTREG(RADEON_CUR_OFFSET,
-		   info->cursor_offset + pScrn->fbOffset + yorigin * stride);
-	}
-	if (c == 1) {
-	    OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
-						| (xorigin << 16)
-						| yorigin));
-	    OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK |
-						temp));
-	    RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
-			  info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
-	    OUTREG(RADEON_CUR2_OFFSET,
-		   info->cursor_offset + pScrn->fbOffset + yorigin * stride);
-	}
-	crtc->cursorInRange = inrange;
+    if (thisx >= mode->HDisplay ||
+	thisy >= mode->VDisplay) 
+    {
+	thisx = 0;
+	thisy = 0;
+    }
+
+    temp = 0;
+    xorigin = 0;
+    yorigin = 0;
+    if (thisx < 0) xorigin = -thisx+1;
+    if (thisy < 0) yorigin = -thisy+1;
+#if 0
+    if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
+    if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
+#endif
+    temp |= (xorigin ? 0 : thisx) << 16;
+    temp |= (yorigin ? 0 : thisy);
 
-	RADEONCrtcCursor(crtc, FALSE);
+    if (crtc_id == 0) {
+	OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
+					   | (xorigin << 16)
+					   | yorigin));
+	OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK |
+					   temp));
+	RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+			info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	OUTREG(RADEON_CUR_OFFSET,
+		info->cursor_offset + pScrn->fbOffset + yorigin * stride);
+    } else if (crtc_id == 1) {
+	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
+					    | (xorigin << 16)
+					    | yorigin));
+	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK |
+					    temp));
+	RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+			info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	OUTREG(RADEON_CUR2_OFFSET,
+		info->cursor_offset + pScrn->fbOffset + yorigin * stride);
     }
 
+}
 
+void
+radeon_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    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;
 }
 
 /* Copy cursor image from `image' to video memory.  RADEONSetCursorPosition
@@ -380,6 +399,73 @@ static Bool RADEONUseHWCursorARGB (Scree
     return FALSE;
 }
 
+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);
+    int            x, y, w, h;
+    CARD32         save1      = 0;
+    CARD32         save2      = 0;
+    CARD32	  *i;
+
+    RADEONCTRACE(("RADEONLoadCursorARGB\n"));
+
+    if (crtc_id == 0) {
+	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
+	save1 |= (CARD32) (2 << 20);
+	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
+    } else if (crtc_id == 1) {
+	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
+	save2 |= (CARD32) (2 << 20);
+	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
+    }
+
+#ifdef ARGB_CURSOR
+    info->cursor_argb = TRUE;
+#endif
+
+    CURSOR_SWAPPING_START();
+
+
+    memcpy (d, image, CURSOR_HEIGHT * CURSOR_WIDTH * 4);
+#if 0
+    w = pCurs->bits->width;
+    if (w > CURSOR_WIDTH)
+	w = CURSOR_WIDTH;
+    h = pCurs->bits->height;
+    if (h > CURSOR_HEIGHT)
+	h = CURSOR_HEIGHT;
+    for (y = 0; y < h; y++)
+    {
+	i = image;
+	image += pCurs->bits->width;
+	for (x = 0; x < w; x++)
+	    *d++ = *i++;
+	/* pad to the right with transparent */
+	for (; x < CURSOR_WIDTH; x++)
+	    *d++ = 0;
+    }
+    /* pad below with transparent */
+    for (; y < CURSOR_HEIGHT; y++)
+	for (x = 0; x < CURSOR_WIDTH; x++)
+	    *d++ = 0;
+#endif
+
+    CURSOR_SWAPPING_END ();
+
+    if (crtc_id == 0) {
+	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
+    } else if (crtc_id == 1) {
+	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
+    }
+}
+
 static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -462,33 +548,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
     int                height;
     int                size_bytes;
 
-    if (!(cursor = info->cursor = xf86CreateCursorInfoRec())) return FALSE;
-
-    cursor->MaxWidth          = CURSOR_WIDTH;
-    cursor->MaxHeight         = CURSOR_HEIGHT;
-    cursor->Flags             = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP
-				 | HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-				 /* this is a lie --
-				  * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
-				  * actually inverts the bit order, so
-				  * this switches to LSBFIRST
-				  */
-				 | HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
-#endif
-				 | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1);
 
-    cursor->SetCursorColors   = RADEONSetCursorColors;
-    cursor->SetCursorPosition = RADEONRandrSetCursorPosition;
-    cursor->LoadCursorImage   = RADEONLoadCursorImage;
-    cursor->HideCursor        = RADEONHideCursor;
-    cursor->ShowCursor        = RADEONShowCursor;
-    cursor->UseHWCursor       = RADEONUseHWCursor;
-
-#ifdef ARGB_CURSOR
-    cursor->UseHWCursorARGB   = RADEONUseHWCursorARGB;
-    cursor->LoadCursorARGB    = RADEONLoadCursorARGB;
-#endif
     size_bytes                = CURSOR_WIDTH * 4 * CURSOR_HEIGHT;
     width                     = pScrn->displayWidth;
     width_bytes		      = width * (pScrn->bitsPerPixel / 8);
@@ -518,5 +578,17 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
     }
 #endif
 
-    return xf86InitCursor(pScreen, cursor);
+    return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
+			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+				 /* this is a lie --
+				  * HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
+				  * actually inverts the bit order, so
+				  * this switches to LSBFIRST
+				  */
+			       HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+#endif
+			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
+			       HARDWARE_CURSOR_ARGB));
 }
diff --git a/src/radeon_display.c b/src/radeon_display.c
index f6f2410..7a8f94f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2241,6 +2241,12 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 
     RADEONBlank(pScrn);
     RADEONRestoreMode(pScrn, &info->ModeReg);
+
+    if (radeon_crtc->crtc_id == 0)
+	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
+    else if (radeon_crtc->crtc_id == 1)
+	RADEONDoAdjustFrame(pScrn, x, y, TRUE);
+
     if (info->DispPriority)
         RADEONInitDispBandwidth(pScrn);
     RADEONUnblank(pScrn);
@@ -2323,6 +2329,12 @@ static const xf86CrtcFuncsRec radeon_crt
     .gamma_set = radeon_crtc_gamma_set,
     .lock = radeon_crtc_lock,
     .unlock = radeon_crtc_unlock,
+    .set_cursor_colors = radeon_crtc_set_cursor_colors,
+    .set_cursor_position = radeon_crtc_set_cursor_position,
+    .show_cursor = radeon_crtc_show_cursor,
+    .hide_cursor = radeon_crtc_hide_cursor,
+/*    .load_cursor_image = i830_crtc_load_cursor_image, */
+    .load_cursor_argb = radeon_crtc_load_cursor_argb,
     .destroy = NULL, /* XXX */
 };
 
diff-tree a3ee42207aab77d93655a82fdcb32be38268b85f (from 3828237200fc16d4d32664fb8358950c213d4897)
Author: Dave Airlie <airlied at linux.ie>
Date:   Wed Apr 25 09:52:22 2007 +1000

    radeon: another attempt at fixing the mergedfb refresh rate
    
    This attempts to keep it inside the 32-bit limit when multiplying things out
    later in the randr tree.
    
    Let me know if I screwed this up..

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index fa143cb..abbc160 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -215,8 +215,13 @@ RADEONCopyModeNLink(ScrnInfoPtr pScrn, D
       * extension to allow selecting among a number of modes whose merged result
       * looks identical but consists of different modes for CRT1 and CRT2
       */
-    mode->VRefresh = (float)((i->Clock * 1000.0 / i->HTotal / i->VTotal) * 100 +
-	(j->Clock * 1000.0 / j->HTotal / j->VTotal));
+    {
+	float ref1, ref2;
+	ref1 = ((float)i->Clock * 100.0 / i->HTotal / i->VTotal) * 50.0;
+	ref2 = ((float)j->Clock * 100.0 / j->HTotal / j->VTotal) / 2.0;
+
+        mode->VRefresh = (float) ref1 + ref2;
+    }
 
     mode->Clock = (int)(mode->VRefresh * 0.001 * mode->HTotal * mode->VTotal);
 
diff-tree 3828237200fc16d4d32664fb8358950c213d4897 (from c81ed9bd7b37c9d02141d10f6c7bad3d0c57032f)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Sun Apr 22 11:36:00 2007 +1000

    radeon: add support for DDC on some laptop chipsets
    
    I noticed fglrx has DDC for the panel in the rs480 laptop, however radeon
    didn't pick it up, so I valgrinded fglrx and spotted 0x1a0/0x1a4 accesses
    I actually noticed this before from the BIOS but never figured it out.
    
    So now I get DDC from the LCD on this laptop.

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 1d4c9bb..dd3d0a7 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -181,6 +181,9 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 			    case RADEON_GPIO_CRT2_DDC:
 				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_CRT2;
 				break;
+			    case RADEON_LCD_GPIO_MASK:
+				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_LCD;
+				break;
 			    default:
 				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_NONE_DETECTED;
 				break;
@@ -290,7 +293,7 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
 		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    
 			pRADEONEnt->PortInfo[0]->DDCType	= tmp1;      
-			if (pRADEONEnt->PortInfo[0]->DDCType > DDC_CRT2) {
+			if (pRADEONEnt->PortInfo[0]->DDCType > DDC_LCD) {
 			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 				       "Unknown DDCType %d found\n",
 				       pRADEONEnt->PortInfo[0]->DDCType);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 57e752e..f3b86e6 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -75,12 +75,13 @@ const char *TMDSTypeName[3] = {
   "External"
 };
 
-const char *DDCTypeName[5] = {
+const char *DDCTypeName[6] = {
   "NONE",
   "MONID",
   "DVI_DDC",
   "VGA_DDC",
-  "CRT2_DDC"
+  "CRT2_DDC",
+  "LCD_DDC"
 };
 
 const char *DACTypeName[3] = {
@@ -166,10 +167,16 @@ static void RADEONI2CGetBits(I2CBusPtr b
     unsigned char *RADEONMMIO = info->MMIO;
 
     /* Get the result */
-    val = INREG(info->DDCReg);
 
-    *Clock = (val & RADEON_GPIO_Y_1) != 0;
-    *data  = (val & RADEON_GPIO_Y_0) != 0;
+    if (info->DDCReg == RADEON_LCD_GPIO_MASK) { 
+        val = INREG(info->DDCReg+4);
+        *Clock = (val & (1<<13)) != 0;
+        *data  = (val & (1<<12)) != 0;
+    } else {
+        val = INREG(info->DDCReg);
+        *Clock = (val & RADEON_GPIO_Y_1) != 0;
+        *data  = (val & RADEON_GPIO_Y_0) != 0;
+    }
 }
 
 static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
@@ -179,11 +186,17 @@ static void RADEONI2CPutBits(I2CBusPtr b
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
 
-    val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
-    val |= (Clock ? 0:RADEON_GPIO_EN_1);
-    val |= (data ? 0:RADEON_GPIO_EN_0);
-    OUTREG(info->DDCReg, val);
-
+    if (info->DDCReg == RADEON_LCD_GPIO_MASK) {
+        val = INREG(info->DDCReg) & (CARD32)~((1<<12) | (1<<13));
+        val |= (Clock ? 0:(1<<13));
+        val |= (data ? 0:(1<<12));
+        OUTREG(info->DDCReg, val);
+    } else {
+        val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
+        val |= (Clock ? 0:RADEON_GPIO_EN_1);
+        val |= (data ? 0:RADEON_GPIO_EN_0);
+        OUTREG(info->DDCReg, val);
+   }
     /* read back to improve reliability on some cards. */
     val = INREG(info->DDCReg);
 }
@@ -562,13 +575,16 @@ static RADEONMonitorType RADEONDisplayDD
     case DDC_CRT2:
 	info->DDCReg = RADEON_GPIO_CRT2_DDC;
 	break;
+    case DDC_LCD:
+	info->DDCReg = RADEON_LCD_GPIO_MASK;
+	break;
     default:
 	info->DDCReg = DDCReg;
 	return MT_NONE;
     }
 
     /* Read and output monitor info using DDC2 over I2C bus */
-    if (info->pI2CBus && info->ddc2) {
+    if (info->pI2CBus && info->ddc2 && (info->DDCReg != RADEON_LCD_GPIO_MASK)) {
 	OUTREG(info->DDCReg, INREG(info->DDCReg) &
 	       (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
 
@@ -620,15 +636,17 @@ static RADEONMonitorType RADEONDisplayDD
 	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
 	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
 	    usleep(15000);
-	    if(*MonInfo) break;
+	    if(*MonInfo)  break;
 	}
+    } else if (info->pI2CBus && info->ddc2 && info->DDCReg == RADEON_LCD_GPIO_MASK) {
+         *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
 	MonType = MT_NONE;
     }
 
     OUTREG(info->DDCReg, INREG(info->DDCReg) &
-	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+        ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
 
     if (*MonInfo) {
 	if ((*MonInfo)->rawData[0x14] & 0x80) {
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index f446516..dc30e2e 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -48,7 +48,8 @@ typedef enum
     DDC_MONID,
     DDC_DVI,
     DDC_VGA,
-    DDC_CRT2
+    DDC_CRT2,
+    DDC_LCD,
 } RADEONDDCType;
 
 typedef enum
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index b50fcf0..0d5e586 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -907,6 +907,8 @@
 #       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1<<13)
 #       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
 #       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 15)
+#define RADEON_LCD_GPIO_MASK                0x01a0
+#define RADEON_LCD_GPIO_Y_REG               0x01a4
 #define RADEON_MDGPIO_A_REG                 0x01ac
 #define RADEON_MDGPIO_EN_REG                0x01b0
 #define RADEON_MDGPIO_MASK                  0x0198
diff-tree dd6a966e862b774a8e8b9e1a085309219673efad (from c81ed9bd7b37c9d02141d10f6c7bad3d0c57032f)
Author: Dave Airlie <airlied at nx6125b.(none)>
Date:   Sun Apr 22 11:36:00 2007 +1000

    radeon: add support for DDC on some laptop chipsets
    
    I noticed fglrx has DDC for the panel in the rs480 laptop, however radeon
    didn't pick it up, so I valgrinded fglrx and spotted 0x1a0/0x1a4 accesses
    I actually noticed this before from the BIOS but never figured it out.
    
    So now I get DDC from the LCD on this laptop.

diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 1d4c9bb..dd3d0a7 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -181,6 +181,9 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 			    case RADEON_GPIO_CRT2_DDC:
 				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_CRT2;
 				break;
+			    case RADEON_LCD_GPIO_MASK:
+				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_LCD;
+				break;
 			    default:
 				pRADEONEnt->PortInfo[crtc]->DDCType = DDC_NONE_DETECTED;
 				break;
@@ -290,7 +293,7 @@ Bool RADEONGetConnectorInfoFromBIOS (Scr
 	        if ((tmp0 = RADEON_BIOS16(tmp + 0x15))) {
 		    if ((tmp1 = RADEON_BIOS8(tmp0+2) & 0x07)) {	    
 			pRADEONEnt->PortInfo[0]->DDCType	= tmp1;      
-			if (pRADEONEnt->PortInfo[0]->DDCType > DDC_CRT2) {
+			if (pRADEONEnt->PortInfo[0]->DDCType > DDC_LCD) {
 			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 				       "Unknown DDCType %d found\n",
 				       pRADEONEnt->PortInfo[0]->DDCType);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 57e752e..f3b86e6 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -75,12 +75,13 @@ const char *TMDSTypeName[3] = {
   "External"
 };
 
-const char *DDCTypeName[5] = {
+const char *DDCTypeName[6] = {
   "NONE",
   "MONID",
   "DVI_DDC",
   "VGA_DDC",
-  "CRT2_DDC"
+  "CRT2_DDC",
+  "LCD_DDC"
 };
 
 const char *DACTypeName[3] = {
@@ -166,10 +167,16 @@ static void RADEONI2CGetBits(I2CBusPtr b
     unsigned char *RADEONMMIO = info->MMIO;
 
     /* Get the result */
-    val = INREG(info->DDCReg);
 
-    *Clock = (val & RADEON_GPIO_Y_1) != 0;
-    *data  = (val & RADEON_GPIO_Y_0) != 0;
+    if (info->DDCReg == RADEON_LCD_GPIO_MASK) { 
+        val = INREG(info->DDCReg+4);
+        *Clock = (val & (1<<13)) != 0;
+        *data  = (val & (1<<12)) != 0;
+    } else {
+        val = INREG(info->DDCReg);
+        *Clock = (val & RADEON_GPIO_Y_1) != 0;
+        *data  = (val & RADEON_GPIO_Y_0) != 0;
+    }
 }
 
 static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
@@ -179,11 +186,17 @@ static void RADEONI2CPutBits(I2CBusPtr b
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
 
-    val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
-    val |= (Clock ? 0:RADEON_GPIO_EN_1);
-    val |= (data ? 0:RADEON_GPIO_EN_0);
-    OUTREG(info->DDCReg, val);
-
+    if (info->DDCReg == RADEON_LCD_GPIO_MASK) {
+        val = INREG(info->DDCReg) & (CARD32)~((1<<12) | (1<<13));
+        val |= (Clock ? 0:(1<<13));
+        val |= (data ? 0:(1<<12));
+        OUTREG(info->DDCReg, val);
+    } else {
+        val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
+        val |= (Clock ? 0:RADEON_GPIO_EN_1);
+        val |= (data ? 0:RADEON_GPIO_EN_0);
+        OUTREG(info->DDCReg, val);
+   }
     /* read back to improve reliability on some cards. */
     val = INREG(info->DDCReg);
 }
@@ -562,13 +575,16 @@ static RADEONMonitorType RADEONDisplayDD
     case DDC_CRT2:
 	info->DDCReg = RADEON_GPIO_CRT2_DDC;
 	break;
+    case DDC_LCD:
+	info->DDCReg = RADEON_LCD_GPIO_MASK;
+	break;
     default:
 	info->DDCReg = DDCReg;
 	return MT_NONE;
     }
 
     /* Read and output monitor info using DDC2 over I2C bus */
-    if (info->pI2CBus && info->ddc2) {
+    if (info->pI2CBus && info->ddc2 && (info->DDCReg != RADEON_LCD_GPIO_MASK)) {
 	OUTREG(info->DDCReg, INREG(info->DDCReg) &
 	       (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
 
@@ -620,15 +636,17 @@ static RADEONMonitorType RADEONDisplayDD
 	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
 	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
 	    usleep(15000);
-	    if(*MonInfo) break;
+	    if(*MonInfo)  break;
 	}
+    } else if (info->pI2CBus && info->ddc2 && info->DDCReg == RADEON_LCD_GPIO_MASK) {
+         *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);
     } else {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DDC2/I2C is not properly initialized\n");
 	MonType = MT_NONE;
     }
 
     OUTREG(info->DDCReg, INREG(info->DDCReg) &
-	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+        ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
 
     if (*MonInfo) {
 	if ((*MonInfo)->rawData[0x14] & 0x80) {
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index f446516..dc30e2e 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -48,7 +48,8 @@ typedef enum
     DDC_MONID,
     DDC_DVI,
     DDC_VGA,
-    DDC_CRT2
+    DDC_CRT2,
+    DDC_LCD,
 } RADEONDDCType;
 
 typedef enum
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index b50fcf0..0d5e586 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -907,6 +907,8 @@
 #       define RADEON_IO_MCLK_MAX_DYN_STOP_LAT (1<<13)
 #       define RADEON_MC_MCLK_DYN_ENABLE    (1 << 14)
 #       define RADEON_IO_MCLK_DYN_ENABLE    (1 << 15)
+#define RADEON_LCD_GPIO_MASK                0x01a0
+#define RADEON_LCD_GPIO_Y_REG               0x01a4
 #define RADEON_MDGPIO_A_REG                 0x01ac
 #define RADEON_MDGPIO_EN_REG                0x01b0
 #define RADEON_MDGPIO_MASK                  0x0198
diff-tree c81ed9bd7b37c9d02141d10f6c7bad3d0c57032f (from 406eec71116a58d42288a7f1c809a92d5bda7350)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Apr 21 18:58:40 2007 +1000

    radeon: fix build on older server

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 3d147e2..1a63971 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -186,9 +186,11 @@ static DisplayModePtr RADEONDDCModes(Scr
 	    new->status     = MODE_OK;
 #ifdef M_T_PREFERRED
 	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
-	      new->type     = M_T_PREFERRED;
+	      new->type     |= M_T_PREFERRED;
 #endif
+#ifdef M_T_DRIVER
 	      new->type     |= M_T_DRIVER;
+#endif
 
 	    switch (d_timings->misc) {
 	    case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
diff-tree 406eec71116a58d42288a7f1c809a92d5bda7350 (from ad119960095b4b64f4c6793f65950c9967ce4989)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Apr 21 18:56:28 2007 +1000

    radeon: fix build since patches for IBM don't actually build

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index bcc0882..b9cce22 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2036,8 +2036,8 @@ static Bool RADEONPreInitModes(ScrnInfoP
     if (info->IsDellServer)
 	info->ddc_mode = TRUE;
     /* IBM Lewis server have troubles using the on-chip RMX mode */
-    if (info->ChipFamily == CHIP_FAMILY_RV100 && !info->HasCRTC2 && pRADEONEnt->PortInfo[0]->MonInfo) {
-	struct vendor *ven = &pRADEONEnt->PortInfo[0].MonInfo->vendor;
+    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2 && pRADEONEnt->PortInfo[0]->MonInfo) {
+	struct vendor *ven = &pRADEONEnt->PortInfo[0]->MonInfo->vendor;
 	if (ven && ven->prod_id == 0x029a && ven->serial == 0x01010101)
 	    info->ddc_mode = TRUE;
     }
diff-tree ad119960095b4b64f4c6793f65950c9967ce4989 (from 16ef77df4ebaf5ea13baa82972aaf98e71ac32ee)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Apr 19 11:54:46 2007 +0200

    Disable RMX for IBM Lewis server.
    
    Due to the hardware layout RMX ddc_mode has to be set.
    If ddc_mode is set, RADEONValdiateFPModes() shouldn't be called.
    Bugzilla #10620 (3).

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0f9e2d6..bcc0882 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2029,15 +2029,19 @@ static Bool RADEONPreInitModes(ScrnInfoP
 	xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE);
 
     /* don't use RMX if we have a dual-tmds panels */
-    
     if ((connector = RADEONGetCrtcConnector(pScrn, 2)))
 	if (connector->MonType == MT_DFP)
 	    info->ddc_mode = TRUE;
     /* don't use RMX if we are Dell Server */  
     if (info->IsDellServer)
-    {
 	info->ddc_mode = TRUE;
+    /* IBM Lewis server have troubles using the on-chip RMX mode */
+    if (info->ChipFamily == CHIP_FAMILY_RV100 && !info->HasCRTC2 && pRADEONEnt->PortInfo[0]->MonInfo) {
+	struct vendor *ven = &pRADEONEnt->PortInfo[0].MonInfo->vendor;
+	if (ven && ven->prod_id == 0x029a && ven->serial == 0x01010101)
+	    info->ddc_mode = TRUE;
     }
+
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "Validating modes on %s head ---------\n",
 	       info->IsSecondary ? "Secondary" : "Primary");
@@ -2219,7 +2223,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 					  pScrn->display->virtualY,
 					  info->FbMapSize,
 					  LOOKUP_BEST_REFRESH);
-		else if (!info->IsSecondary)
+		else if (!info->IsSecondary && !info->ddc_mode)
 		    modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes);
 	    }
         }
diff-tree 16ef77df4ebaf5ea13baa82972aaf98e71ac32ee (from 0abce69f0d826a7ca1a41d963cd4730b6e01c145)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Wed Apr 18 17:36:15 2007 +0200

    Set sync polarity restriction flags even for non-"digital separate" monitors.
    
    According to Lisa Wu, this is correct regarding the VESA EEDID standard.
    Bugzilla #10620 (2), original patch by Lisa Wu @ATI

diff --git a/src/radeon_display.c b/src/radeon_display.c
index ac05648..57e752e 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -755,13 +755,11 @@ static void RADEONUpdatePanelSize(ScrnIn
 		info->VSyncWidth = d_timings->v_sync_width;
 		info->VBlank     = d_timings->v_blanking;
                 info->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-                if (d_timings->sync == 3) {
-                   switch (d_timings->misc) {
-                   case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break;
-                   case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break;
-                   case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break;
-                   case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break;
-                   }
+                switch (d_timings->misc) {
+                case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break;
+                case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break;
+                case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break;
+                case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break;
                 }
                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
                            info->PanelXRes, info->PanelYRes);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 6b8577e..3d147e2 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -190,13 +190,11 @@ static DisplayModePtr RADEONDDCModes(Scr
 #endif
 	      new->type     |= M_T_DRIVER;
 
-	    if (d_timings->sync == 3) {
-		switch (d_timings->misc) {
-		case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
-		case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
-		case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
-		case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
-		}
+	    switch (d_timings->misc) {
+	    case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
+	    case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
+	    case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
+	    case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
 	    }
 	    count++;
 
diff-tree 0abce69f0d826a7ca1a41d963cd4730b6e01c145 (from aea801cf9a5ce519a53d6fffd9a3a2e526ec79ea)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Wed Apr 18 17:32:52 2007 +0200

    Fix inconsistent use of Mode lists.
    
    Some scans used to only check every second entry, some stopped at the entry
    before the last entry.
    Bugzilla #10620 (1), original patch by Lisa Wu @ATI

diff --git a/src/radeon_display.c b/src/radeon_display.c
index d661c17..ac05648 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -776,7 +776,7 @@ static void RADEONUpdatePanelSize(ScrnIn
     for (j = 0; j < 8; j++) {
 	if ((info->PanelXRes < ddc->timings2[j].hsize) &&
 	    (info->PanelYRes < ddc->timings2[j].vsize)) {
-	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+	    for (p = pScrn->monitor->Modes; p; p = p->next) {
 		if ((ddc->timings2[j].hsize == p->HDisplay) &&
 		    (ddc->timings2[j].vsize == p->VDisplay)) {
 		    float  refresh =
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 372b2ed..6b8577e 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -212,7 +212,7 @@ static DisplayModePtr RADEONDDCModes(Scr
     for (j = 0; j < 8; j++) {
         if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
                continue;
-	for (p = pScrn->monitor->Modes; p && p->next; p = p->next) {
+	for (p = pScrn->monitor->Modes; p; p = p->next) {
 	    /* Ignore all double scan modes */
 	    if (p->Flags & V_DBLSCAN)
 		continue;
@@ -248,7 +248,7 @@ static DisplayModePtr RADEONDDCModes(Scr
     tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
     for (j = 0; j < 16; j++) {
 	if (tmp & (1 << j)) {
-	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next) {
+	    for (p = pScrn->monitor->Modes; p; p = p->next) {
 		/* Ignore all double scan modes */
 		if (p->Flags & V_DBLSCAN)
 		    continue;
@@ -560,7 +560,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
     }
 
     /* add in all default vesa modes smaller than panel size, used for randr*/
-    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+    for (p = pScrn->monitor->Modes; p; p = p->next) {
 	if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) {
 	    tmp = first;
 	    while (tmp) {
diff-tree aea801cf9a5ce519a53d6fffd9a3a2e526ec79ea (from 07ddffb32e6293c77b32c94b87ec468caef3d6f5)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Fri Apr 13 16:16:05 2007 +0200

    Fix crash if MergedFB and secondary head not found
    
    If the secondary head isn't found (Monitor unplugged etc.) but MergedFB
    is configured, the driver segfaults because it tries to access the mode
    list private structures, which are not filled in.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c4bda8a..0f9e2d6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2328,7 +2328,11 @@ static Bool RADEONPreInitModes(ScrnInfoP
 		
 	    }
 	}
+	else
+	    info->MergedFB = FALSE;
     }
+    else
+	info->MergedFB = FALSE;
 
     if (info->MergedFB) {
        /* If no virtual dimension was given by the user,
diff-tree 07ddffb32e6293c77b32c94b87ec468caef3d6f5 (from 4effa67ea75736a31b9e78a7b35acf74b067c43e)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Wed Apr 11 14:36:51 2007 +0200

    Fixed typo in mode list generation.

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 5c91cd3..fa143cb 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -389,7 +389,7 @@ RADEONGenerateModeListFromLargestModes(S
     if(srel != radeonClone) {
        if(mode3 && mode4 && !info->NonRect) {
 	  mode1 = mode3;
-	  mode2 = mode2;
+	  mode2 = mode4;
        }
     }
 
diff-tree 4effa67ea75736a31b9e78a7b35acf74b067c43e (from 6b25a4c48796e022a093f3072574ffe9709ecaf4)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Apr 9 22:08:31 2007 +1000

    radeon: add support for enabling direct rendering on RS480
    
    Thanks to Matthew Garrett and Ubuntu for the hw loan to get this working.
    
    Still no 3D driver support but at least you should get CP acceleration for
    2D now.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 7fd802a..c4bda8a 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -953,7 +953,8 @@ static Bool RADEONProbePLLParameters(Scr
     if (ref_div < 2) {
        CARD32 tmp;
        tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
-       if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS300))
+       if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS300)
+			   || (info->ChipFamily == CHIP_FAMILY_RS400))
            ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >>
                    R300_PPLL_REF_DIV_ACC_SHIFT;
        else
@@ -1033,7 +1034,8 @@ static void RADEONGetClockInfo(ScrnInfoP
 	    CARD32 tmp;
 	    tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
 	    if (IS_R300_VARIANT ||
-		(info->ChipFamily == CHIP_FAMILY_RS300)) {
+		(info->ChipFamily == CHIP_FAMILY_RS300) ||
+		(info->ChipFamily == CHIP_FAMILY_RS400)) {
 		pll->reference_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >> R300_PPLL_REF_DIV_ACC_SHIFT;
 	    } else {
 		pll->reference_div = tmp & RADEON_PPLL_REF_DIV_MASK;
@@ -1903,10 +1905,15 @@ static Bool RADEONPreInitChipType(ScrnIn
 	}
     }
 
+
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
 	       (info->cardType==CARD_PCI) ? "PCI" :
 		(info->cardType==CARD_PCIE) ? "PCIE" : "AGP");
 
+    /* treat PCIE IGP cards as PCI */
+    if (info->cardType == CARD_PCIE && info->IsIGP)
+		info->cardType = CARD_PCI;
+
     if ((s = xf86GetOptValString(info->Options, OPTION_BUS_TYPE))) {
 	if (strcmp(s, "AGP") == 0) {
 	    info->cardType = CARD_AGP;
@@ -2526,18 +2533,6 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr
 	}
     }
 
-    if (info->Chipset == PCI_CHIP_RS400_5A41 ||
-	info->Chipset == PCI_CHIP_RS400_5A42 ||
-	info->Chipset == PCI_CHIP_RC410_5A61 ||
-	info->Chipset == PCI_CHIP_RC410_5A62 ||
-	info->Chipset == PCI_CHIP_RS480_5954 ||
-	info->Chipset == PCI_CHIP_RS480_5955 ||
-	info->Chipset == PCI_CHIP_RS482_5974 ||
-	info->Chipset == PCI_CHIP_RS482_5975) {
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Direct rendering broken on XPRESS 200 and 200M\n");
-	return FALSE;
-    }
 
     if (!xf86ReturnOptValBool(info->Options, OPTION_DRI, TRUE)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -2564,6 +2559,24 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr
 	       info->pKernelDRMVersion->version_minor,
 	       info->pKernelDRMVersion->version_patchlevel);
 
+    if (info->Chipset == PCI_CHIP_RS400_5A41 ||
+	info->Chipset == PCI_CHIP_RS400_5A42 ||
+	info->Chipset == PCI_CHIP_RC410_5A61 ||
+	info->Chipset == PCI_CHIP_RC410_5A62 ||
+	info->Chipset == PCI_CHIP_RS480_5954 ||
+	info->Chipset == PCI_CHIP_RS480_5955 ||
+	info->Chipset == PCI_CHIP_RS482_5974 ||
+	info->Chipset == PCI_CHIP_RS482_5975) {
+
+	if (info->pKernelDRMVersion->version_minor < 27) {
+ 	     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			"Direct rendering broken on XPRESS 200 and 200M with DRI less than 1.27\n");
+	     return FALSE;
+	}
+ 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	"Direct rendering experimental on RS400/Xpress 200 enabled\n");
+    }
+
     if (xf86ReturnOptValBool(info->Options, OPTION_CP_PIO, FALSE)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Forcing CP into PIO mode\n");
 	info->CPMode = RADEON_DEFAULT_CP_PIO_MODE;
@@ -4734,7 +4747,8 @@ static void RADEONRestorePLLRegisters(Sc
     RADEONPllErrataAfterIndex(info);
 
     if (IS_R300_VARIANT ||
-	(info->ChipFamily == CHIP_FAMILY_RS300)) {
+	(info->ChipFamily == CHIP_FAMILY_RS300) ||
+	(info->ChipFamily == CHIP_FAMILY_RS400)) {
 	if (restore->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
 	    /* When restoring console mode, use saved PPLL_REF_DIV
 	     * setting.
diff-tree 6b25a4c48796e022a093f3072574ffe9709ecaf4 (from 3c892f163ec1fa9be6e733aab091c9b718f41efc)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Wed Apr 4 10:47:29 2007 +0200

    radeon: Link nearest modes by default for clone mode.
    
    This makes sure all modes of both CRTCs will be available by default with
    MergedFB.

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 6a7745e..5c91cd3 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -536,12 +536,33 @@ RADEONGenerateModeList(ScrnInfoPtr pScrn
            DisplayModePtr p, q, result = NULL;
 
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                "Clone mode, list all common modes\n");
-           for (p = i; p->next != i; p = p->next)
-                for (q = j; q->next != j; q = q->next)
-                   if ((p->HDisplay == q->HDisplay) &&
-                        (p->VDisplay == q->VDisplay))
-                        result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+                      "Clone mode, linking all nearest modes\n");
+
+           p = i;
+           q = j;
+
+           result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+
+           while (p->next != i || q->next != j) {
+              DisplayModePtr next_p = p;
+
+              if (q->next == j || (p->next != i &&
+                                   (p->HDisplay > q->HDisplay ||
+                                    (p->HDisplay == q->HDisplay &&
+                                     p->VDisplay >= q->VDisplay))))
+                 next_p = p->next;
+
+              if (p->next == i || (q->next != j &&
+                                   (q->HDisplay > p->HDisplay ||
+                                    (q->HDisplay == p->HDisplay &&
+                                     q->VDisplay >= p->VDisplay))))
+                 q = q->next;
+
+              p = next_p;
+
+              result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+           }
+
            return result;
         } else {
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff-tree 3c892f163ec1fa9be6e733aab091c9b718f41efc (from 3a8190ccc79969925257e7b980b78d79053d208d)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Wed Apr 4 09:52:37 2007 +0200

    radeon: Always sort modes when adding to list.
    
    This makes sure mode lists will always be sorted from larger to smaller.

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 535d047..372b2ed 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -373,15 +373,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 			    if (p == ddcModes) ddcModes = p->next;
 
 			    /* Add to used modes */
-			    if (last) {
-				last->next = p;
-				p->prev = last;
-			    } else {
-				first = p;
-				p->prev = NULL;
-			    }
-			    p->next = NULL;
-			    last = p;
+			    RADEONSortModes(&p, &first, &last);
 
 			    break;
 			}
@@ -402,15 +394,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 		    if (p == ddcModes) ddcModes = p->next;
 
 		    /* Add to used modes */
-		    if (last) {
-			last->next = p;
-			p->prev = last;
-		    } else {
-			first = p;
-			p->prev = NULL;
-		    }
-		    p->next = NULL;
-		    last = p;
+		    RADEONSortModes(&p, &first, &last);
 		}
 	    }
 
@@ -558,12 +542,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 
 	new->type      |= M_T_USERDEF;
 
-	new->next       = NULL;
-	new->prev       = last;
-
-	if (last) last->next = new;
-	last = new;
-	if (!first) first = new;
+	RADEONSortModes(&new, &first, &last);
 
 	pScrn->display->virtualX =
 	    pScrn->virtualX = MAX(pScrn->virtualX, width);
@@ -609,12 +588,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 
 		new->type      |= M_T_DEFAULT;
 
-		new->next       = NULL;
-		new->prev       = last;
-
-		if (last) last->next = new;
-		last = new;
-		if (!first) first = new;
+		RADEONSortModes(&new, &first, &last);
 	    }
 	}
     }
diff-tree 3a8190ccc79969925257e7b980b78d79053d208d (from 9b1e97284ce185d358ca756a235d2cee346fa53f)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Wed Apr 4 09:47:07 2007 +0200

    radeon: Don't shrink virtual size based on secondary modes.

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 820ba4b..6a7745e 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -581,8 +581,10 @@ RADEONRecalcDefaultVirtualSize(ScrnInfoP
   	               info->CRT1XOffs = info->CRT2XOffs = 0;
   	               maxh -= (info->CRT1XOffs + info->CRT2XOffs);
   	}
-  	pScrn->virtualX = maxh;
-  	pScrn->displayWidth = maxh;
+	if (maxh > pScrn->virtualX)
+	    pScrn->virtualX = maxh;
+	if (maxh > pScrn->displayWidth)
+	    pScrn->displayWidth = maxh;
   	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
     } else {
   	if(maxh < pScrn->display->virtualX) {
@@ -592,7 +594,8 @@ RADEONRecalcDefaultVirtualSize(ScrnInfoP
     }
 
     if(!(pScrn->display->virtualY)) {
-        pScrn->virtualY = maxv;
+	if (maxv > pScrn->virtualY)
+	    pScrn->virtualY = maxv;
 	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
     } else {
 	if(maxv < pScrn->display->virtualY) {
diff-tree 9b1e97284ce185d358ca756a235d2cee346fa53f (from 9c2dcd19be8fc2cc29e637d1e9748e66196e3900)
Author: Henry Zhao <henryz at localhost.localdomain>
Date:   Sat Mar 31 23:01:52 2007 -0800

    10205: Radeon driver's own mode validation code does not work properly

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 09b8aaf..535d047 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -86,10 +86,16 @@ static void RADEONSortModes(DisplayModeP
 
     p = *last;
     while (p) {
-	if ((((*new)->HDisplay < p->HDisplay) &&
+	if (((*new)->HDisplay < p->HDisplay) ||
+	    (((*new)->HDisplay == p->HDisplay) &&
 	     ((*new)->VDisplay < p->VDisplay)) ||
 	    (((*new)->HDisplay == p->HDisplay) &&
 	     ((*new)->VDisplay == p->VDisplay) &&
+	     ((*new)->type < p->type) && 
+	     !(((*new)->type == M_T_USERDEF) || (!(*new)->type))) ||
+	    (((*new)->HDisplay == p->HDisplay) &&
+	     ((*new)->VDisplay == p->VDisplay) &&
+	     ((*new)->type == p->type) && 
 	     ((*new)->Clock < p->Clock))) {
 
 	    if (p->next) p->next->prev = *new;
@@ -181,9 +187,8 @@ static DisplayModePtr RADEONDDCModes(Scr
 #ifdef M_T_PREFERRED
 	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
 	      new->type     = M_T_PREFERRED;
-	    else
 #endif
-	      new->type     = M_T_DEFAULT;
+	      new->type     |= M_T_DRIVER;
 
 	    if (d_timings->sync == 3) {
 		switch (d_timings->misc) {
@@ -207,8 +212,10 @@ static DisplayModePtr RADEONDDCModes(Scr
     for (j = 0; j < 8; j++) {
         if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
                continue;
-	for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+	for (p = pScrn->monitor->Modes; p && p->next; p = p->next) {
 	    /* Ignore all double scan modes */
+	    if (p->Flags & V_DBLSCAN)
+		continue;
 	    if ((ddc->timings2[j].hsize == p->HDisplay) &&
 		(ddc->timings2[j].vsize == p->VDisplay)) {
 		float  refresh =
@@ -221,7 +228,8 @@ static DisplayModePtr RADEONDDCModes(Scr
 		    new->name = xnfalloc(strlen(p->name) + 1);
 		    strcpy(new->name, p->name);
 		    new->status = MODE_OK;
-		    new->type   = M_T_DEFAULT;
+		    if ((new->type != M_T_USERDEF) && (new->type))
+		    	new->type   = M_T_DEFAULT;
 
 		    count++;
 
@@ -240,7 +248,10 @@ static DisplayModePtr RADEONDDCModes(Scr
     tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
     for (j = 0; j < 16; j++) {
 	if (tmp & (1 << j)) {
-	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next) {
+		/* Ignore all double scan modes */
+		if (p->Flags & V_DBLSCAN)
+		    continue;
 		if ((est_timings[j].hsize == p->HDisplay) &&
 		    (est_timings[j].vsize == p->VDisplay)) {
 		    float  refresh =
@@ -253,7 +264,8 @@ static DisplayModePtr RADEONDDCModes(Scr
 			new->name = xnfalloc(strlen(p->name) + 1);
 			strcpy(new->name, p->name);
 			new->status = MODE_OK;
-			new->type   = M_T_DEFAULT;
+		    	if ((new->type != M_T_USERDEF) && (new->type))
+		    	    new->type   = M_T_DEFAULT;
 
 			count++;
 
diff-tree 9c2dcd19be8fc2cc29e637d1e9748e66196e3900 (from 1acd6d6fa42acec07fb11aeb189f492ddb021cb4)
Author: Henry Zhao <henryz at localhost.localdomain>
Date:   Sat Mar 31 20:10:03 2007 -0800

    9337: EDID modes do not participate in validation for CRT monitor

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0e68d7d..7fd802a 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2125,7 +2125,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
      * 'stretched' from their native mode.
      */
     if (info->DisplayType == MT_CRT && !info->ddc_mode) {
-
+	xf86SetDDCproperties(pScrn, pScrn->monitor->DDC);
 	modesFound =
 	    xf86ValidateModes(pScrn,
 			      pScrn->monitor->Modes,
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 70bf184..09b8aaf 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -675,7 +675,7 @@ int RADEONValidateMergeModes(ScrnInfoPtr
      * 'stretched' from their native mode.
      */
     if (info->MergeType == MT_CRT && !info->ddc_mode) {
- 
+	xf86SetDDCproperties(pScrn, pScrn->monitor->DDC); 
 	modesFound =
 	    xf86ValidateModes(pScrn,
 			      pScrn->monitor->Modes,
diff-tree 1acd6d6fa42acec07fb11aeb189f492ddb021cb4 (from 1a71106c0e4fe5f650239dc694163fdf52d33663)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Fri Mar 30 11:06:10 2007 +0200

    radeon: Guard some MergedFB specific code with info->MergedFB tests.
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=10442 .

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 57d8826..0e68d7d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2247,7 +2247,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 	    /* If we have 2 screens from the config file, we don't need
 	     * to do clone thing, let each screen handles one head.
 	     */
-	    if (!pRADEONEnt->HasSecondary) {
+	    if (info->MergedFB) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "Validating CRTC2 modes for MergedFB ------------ \n");
 
@@ -2273,7 +2273,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 
 
     if (pRADEONEnt->HasCRTC2) {
-	if(pRADEONEnt->Controller[1]->binding == 1) {
+	if(pRADEONEnt->Controller[1]->binding == 1 && info->MergedFB) {
 	    
 	    xf86SetCrtcForModes(info->CRT2pScrn, INTERLACE_HALVE_V);
 	    
diff-tree 1a71106c0e4fe5f650239dc694163fdf52d33663 (from f87e57d4d773a019d1cc8a10425c57480430f6a4)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 27 10:13:21 2007 +0200

    radeon: Fix typo.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 2cd4c7b..57d8826 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6336,7 +6336,7 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
     if (crtc1 && (crtc_mask & 1)) {
     	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
 	   crtc1->name,
-	   crtc1->clock,
+	   crtc1->Clock/1000.0,
 
 	   crtc1->HDisplay,
 	   crtc1->HSyncStart,
diff-tree f87e57d4d773a019d1cc8a10425c57480430f6a4 (from 66b4a571a4e7960da6807d3f30955aa08e89ccc6)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Mar 27 18:08:54 2007 +1000

    radeon: fix up crtc debug dereference problem

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1bd6884..2cd4c7b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6333,9 +6333,10 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
     ScrnInfoPtr    pScrn0    = NULL;
 
 #if RADEON_DEBUG
-    ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+    if (crtc1 && (crtc_mask & 1)) {
+    	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
 	   crtc1->name,
-	   dot_clock,
+	   crtc1->clock,
 
 	   crtc1->HDisplay,
 	   crtc1->HSyncStart,
@@ -6348,40 +6349,44 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
 	   crtc1->VTotal,
 	   pScrn->depth,
 	   pScrn->bitsPerPixel);
-    if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    ErrorF("\n");
-    ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc1->name,
-	   crtc1->Clock/1000.0,
-
-	   crtc1->CrtcHDisplay,
-	   crtc1->CrtcHSyncStart,
-	   crtc1->CrtcHSyncEnd,
-	   crtc1->CrtcHTotal,
-
-	   crtc1->CrtcVDisplay,
-	   crtc1->CrtcVSyncStart,
-	   crtc1->CrtcVSyncEnd,
-	   crtc1->CrtcVTotal,
+    	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
+    	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
+    	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
+    	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
+    	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
+    	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
+    	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
+    	ErrorF("\n");
+    }
+    if (crtc2 && (crtc_mask & 2)) {
+        ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+	   crtc2->name,
+	   crtc2->Clock/1000.0,
+
+	   crtc2->CrtcHDisplay,
+	   crtc2->CrtcHSyncStart,
+	   crtc2->CrtcHSyncEnd,
+	   crtc2->CrtcHTotal,
+
+	   crtc2->CrtcVDisplay,
+	   crtc2->CrtcVSyncStart,
+	   crtc2->CrtcVSyncEnd,
+	   crtc2->CrtcVTotal,
 	   pScrn->depth,
 	   pScrn->bitsPerPixel);
-    if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    ErrorF("\n");
+        if (crtc2->Flags & V_DBLSCAN)   ErrorF(" D");
+        if (crtc2->Flags & V_CSYNC)     ErrorF(" C");
+        if (crtc2->Flags & V_INTERLACE) ErrorF(" I");
+        if (crtc2->Flags & V_PHSYNC)    ErrorF(" +H");
+        if (crtc2->Flags & V_NHSYNC)    ErrorF(" -H");
+        if (crtc2->Flags & V_PVSYNC)    ErrorF(" +V");
+        if (crtc2->Flags & V_NVSYNC)    ErrorF(" -V");
+    	ErrorF("\n");
+    }
 #endif
 
-    info->Flags = crtc1->Flags;
+    if (crtc1 && (crtc_mask & 1))
+        info->Flags = crtc1->Flags;
 
     RADEONInitMemMapRegisters(pScrn, save, info);
     RADEONInitCommonRegisters(save, info);
diff-tree 66b4a571a4e7960da6807d3f30955aa08e89ccc6 (from fca30a6b581cb6c1466ab1bc316df8fed5d82b60)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Mar 27 17:00:37 2007 +1000

    update number to 6.6.191 for rc release

diff --git a/configure.ac b/configure.ac
index 16b93e1..ddfa7c8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-ati],
-        6.6.99,
+        6.6.191,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-ati)
 
diff-tree fca30a6b581cb6c1466ab1bc316df8fed5d82b60 (from 97d8d1ed10d069343f2b3172ba64ca421821a602)
Author: Alex Deucher <alex at botch2.com>
Date:   Mon Mar 26 23:26:51 2007 -0400

    fix NULL dereference
    
    when IsSecondary is true, crtc1 is NULL
    Noticed by Sverre Froyen.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 28580a5..1bd6884 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6328,7 +6328,7 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
 {
     RADEONInfoPtr  info      = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    double         dot_clock = crtc1->Clock/1000.0;
+    double         dot_clock;
     RADEONInfoPtr  info0     = NULL;
     ScrnInfoPtr    pScrn0    = NULL;
 
@@ -6358,7 +6358,7 @@ static Bool RADEONInit2(ScrnInfoPtr pScr
     ErrorF("\n");
     ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
 	   crtc1->name,
-	   dot_clock,
+	   crtc1->Clock/1000.0,
 
 	   crtc1->CrtcHDisplay,
 	   crtc1->CrtcHSyncStart,
diff-tree 97d8d1ed10d069343f2b3172ba64ca421821a602 (from aa8f5b02ebc9be60df48722588261627d6a457e8)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sat Mar 24 20:02:12 2007 +0200

    Move atichip.c from ati to atimisc.

diff --git a/src/Makefile.am b/src/Makefile.am
index 1da3740..84642f7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,13 +51,13 @@ ati_drv_la_LTLIBRARIES = ati_drv.la
 ati_drv_la_LDFLAGS = -module -avoid-version
 ati_drv_ladir = @moduledir@/drivers
 ati_drv_la_SOURCES = \
-	ati.c atichip.c atimodule.c
+	ati.c atimodule.c
 
 atimisc_drv_la_LTLIBRARIES = atimisc_drv.la
 atimisc_drv_la_LDFLAGS = -module -avoid-version
 atimisc_drv_ladir = @moduledir@/drivers
 atimisc_drv_la_SOURCES = \
-	atibus.c atiprobe.c atividmem.c \
+	atibus.c atichip.c atiprobe.c atividmem.c \
 	atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.c \
 	atidac.c atidecoder.c atidsp.c atii2c.c \
 	atilock.c atimach64.c atimach64accel.c atimach64cursor.c \
diff --git a/src/ati.c b/src/ati.c
index 4ef53e3..423fd95 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -58,15 +58,12 @@
 #endif
 
 #include "ati.h"
-#include "atichip.h"
 #include "atimodule.h"
 #include "ativersion.h"
 #include "atimach64probe.h"
 
 #include "radeon_probe.h"
-#include "radeon_version.h"
 #include "r128_probe.h"
-#include "r128_version.h"
 
 /*
  * ATIIdentify --
@@ -236,3 +233,469 @@ _X_EXPORT DriverRec ATI =
     NULL,
     0
 };
+
+/*
+ * Chip-related definitions.
+ */
+const char *ATIChipNames[] =
+{
+    "Unknown",
+    "ATI 88800GX-C",
+    "ATI 88800GX-D",
+    "ATI 88800GX-E",
+    "ATI 88800GX-F",
+    "ATI 88800GX",
+    "ATI 88800CX",
+    "ATI 264CT",
+    "ATI 264ET",
+    "ATI 264VT",
+    "ATI 3D Rage",
+    "ATI 264VT-B",
+    "ATI 3D Rage II",
+    "ATI 264VT3",
+    "ATI 3D Rage II+DVD",
+    "ATI 3D Rage LT",
+    "ATI 264VT4",
+    "ATI 3D Rage IIc",
+    "ATI 3D Rage Pro",
+    "ATI 3D Rage LT Pro",
+    "ATI 3D Rage XL or XC",
+    "ATI 3D Rage Mobility",
+    "ATI unknown Mach64",
+    "ATI Rage 128 GL",
+    "ATI Rage 128 VR",
+    "ATI Rage 128 Pro GL",
+    "ATI Rage 128 Pro VR",
+    "ATI Rage 128 Pro ULTRA",
+    "ATI Rage 128 Mobility M3",
+    "ATI Rage 128 Mobility M4",
+    "ATI unknown Rage 128"
+    "ATI Radeon 7200",
+    "ATI Radeon 7000 (VE)",
+    "ATI Radeon Mobility M6",
+    "ATI Radeon IGP320",
+    "ATI Radeon IGP330/340/350",
+    "ATI Radeon 7000 IGP",
+    "ATI Radeon 7500",
+    "ATI Radeon Mobility M7",
+    "ATI Radeon 8500/9100",
+    "ATI Radeon 9000",
+    "ATI Radeon Mobility M9",
+    "ATI Radeon 9100 IGP",
+    "ATI Radeon 9200 IGP",
+    "ATI Radeon 9200",
+    "ATI Radeon Mobility M9+",
+    "ATI Radeon 9700/9500",
+    "ATI Radeon 9600/9550",
+    "ATI Radeon 9800",
+    "ATI Radeon 9800XT",
+    "ATI Radeon X300/X550/M22",
+    "ATI Radeon X600/X550/M24",
+    "ATI Radeon X800/M18 AGP",
+    "ATI Radeon X800/M28 PCIE",
+    "ATI Radeon X800XL PCIE",
+    "ATI Radeon X850 PCIE",
+    "ATI Radeon X850 AGP",
+    "ATI Radeon X700",
+    "ATI Xpress 200"
+    "ATI unknown Radeon",
+    "ATI Rage HDTV"
+};
+
+#include "atichip.h"
+
+/*
+ * ATIChipID --
+ *
+ * This returns the ATI_CHIP_* value (generally) associated with a particular
+ * ChipID/ChipRev combination.
+ */
+ATIChipType
+ATIChipID
+(
+    const CARD16 ChipID,
+    const CARD8  ChipRev
+)
+{
+    switch (ChipID)
+    {
+        case OldChipID('G', 'X'):  case NewChipID('G', 'X'):
+            switch (ChipRev)
+            {
+                case 0x00U:
+                    return ATI_CHIP_88800GXC;
+
+                case 0x01U:
+                    return ATI_CHIP_88800GXD;
+
+                case 0x02U:
+                    return ATI_CHIP_88800GXE;
+
+                case 0x03U:
+                    return ATI_CHIP_88800GXF;
+
+                default:
+                    return ATI_CHIP_88800GX;
+            }
+
+        case OldChipID('C', 'X'):  case NewChipID('C', 'X'):
+            return ATI_CHIP_88800CX;
+
+        case OldChipID('C', 'T'):  case NewChipID('C', 'T'):
+            return ATI_CHIP_264CT;
+
+        case OldChipID('E', 'T'):  case NewChipID('E', 'T'):
+            return ATI_CHIP_264ET;
+
+        case OldChipID('V', 'T'):  case NewChipID('V', 'T'):
+            /* For simplicity, ignore ChipID discrepancy that can occur here */
+            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
+                return ATI_CHIP_264VT;
+            return ATI_CHIP_264VTB;
+
+        case OldChipID('G', 'T'):  case NewChipID('G', 'T'):
+            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
+                return ATI_CHIP_264GT;
+            return ATI_CHIP_264GTB;
+
+        case OldChipID('V', 'U'):  case NewChipID('V', 'U'):
+            return ATI_CHIP_264VT3;
+
+        case OldChipID('G', 'U'):  case NewChipID('G', 'U'):
+            return ATI_CHIP_264GTDVD;
+
+        case OldChipID('L', 'G'):  case NewChipID('L', 'G'):
+            return ATI_CHIP_264LT;
+
+        case OldChipID('V', 'V'):  case NewChipID('V', 'V'):
+            return ATI_CHIP_264VT4;
+
+        case OldChipID('G', 'V'):  case NewChipID('G', 'V'):
+        case OldChipID('G', 'W'):  case NewChipID('G', 'W'):
+        case OldChipID('G', 'Y'):  case NewChipID('G', 'Y'):
+        case OldChipID('G', 'Z'):  case NewChipID('G', 'Z'):
+            return ATI_CHIP_264GT2C;
+
+        case OldChipID('G', 'B'):  case NewChipID('G', 'B'):
+        case OldChipID('G', 'D'):  case NewChipID('G', 'D'):
+        case OldChipID('G', 'I'):  case NewChipID('G', 'I'):
+        case OldChipID('G', 'P'):  case NewChipID('G', 'P'):
+        case OldChipID('G', 'Q'):  case NewChipID('G', 'Q'):
+            return ATI_CHIP_264GTPRO;
+
+        case OldChipID('L', 'B'):  case NewChipID('L', 'B'):
+        case OldChipID('L', 'D'):  case NewChipID('L', 'D'):
+        case OldChipID('L', 'I'):  case NewChipID('L', 'I'):
+        case OldChipID('L', 'P'):  case NewChipID('L', 'P'):
+        case OldChipID('L', 'Q'):  case NewChipID('L', 'Q'):
+            return ATI_CHIP_264LTPRO;
+
+        case OldChipID('G', 'L'):  case NewChipID('G', 'L'):
+        case OldChipID('G', 'M'):  case NewChipID('G', 'M'):
+        case OldChipID('G', 'N'):  case NewChipID('G', 'N'):
+        case OldChipID('G', 'O'):  case NewChipID('G', 'O'):
+        case OldChipID('G', 'R'):  case NewChipID('G', 'R'):
+        case OldChipID('G', 'S'):  case NewChipID('G', 'S'):
+            return ATI_CHIP_264XL;
+
+        case OldChipID('L', 'M'):  case NewChipID('L', 'M'):
+        case OldChipID('L', 'N'):  case NewChipID('L', 'N'):
+        case OldChipID('L', 'R'):  case NewChipID('L', 'R'):
+        case OldChipID('L', 'S'):  case NewChipID('L', 'S'):
+            return ATI_CHIP_MOBILITY;
+
+        case NewChipID('R', 'E'):
+        case NewChipID('R', 'F'):
+        case NewChipID('R', 'G'):
+        case NewChipID('S', 'K'):
+        case NewChipID('S', 'L'):
+        case NewChipID('S', 'M'):
+        /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */
+        case NewChipID('S', 'N'):
+            return ATI_CHIP_RAGE128GL;
+
+        case NewChipID('R', 'K'):
+        case NewChipID('R', 'L'):
+        /*
+         * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR
+         * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only.
+         * I'm stuffing them here for now until this can be clarified as ATI
+         * documentation doesn't mention their details. <mharris at redhat.com>
+         */
+        case NewChipID('S', 'E'):
+        case NewChipID('S', 'F'):
+        case NewChipID('S', 'G'):
+        case NewChipID('S', 'H'):
+            return ATI_CHIP_RAGE128VR;
+
+     /* case NewChipID('S', 'H'): */
+     /* case NewChipID('S', 'K'): */
+     /* case NewChipID('S', 'L'): */
+     /* case NewChipID('S', 'N'): */
+     /*     return ATI_CHIP_RAGE128_4X; */
+
+        case NewChipID('P', 'A'):
+        case NewChipID('P', 'B'):
+        case NewChipID('P', 'C'):
+        case NewChipID('P', 'D'):
+        case NewChipID('P', 'E'):
+        case NewChipID('P', 'F'):
+            return ATI_CHIP_RAGE128PROGL;
+
+        case NewChipID('P', 'G'):
+        case NewChipID('P', 'H'):
+        case NewChipID('P', 'I'):
+        case NewChipID('P', 'J'):
+        case NewChipID('P', 'K'):
+        case NewChipID('P', 'L'):
+        case NewChipID('P', 'M'):
+        case NewChipID('P', 'N'):
+        case NewChipID('P', 'O'):
+        case NewChipID('P', 'P'):
+        case NewChipID('P', 'Q'):
+        case NewChipID('P', 'R'):
+        case NewChipID('P', 'S'):
+        case NewChipID('P', 'T'):
+        case NewChipID('P', 'U'):
+        case NewChipID('P', 'V'):
+        case NewChipID('P', 'W'):
+        case NewChipID('P', 'X'):
+            return ATI_CHIP_RAGE128PROVR;
+
+        case NewChipID('T', 'F'):
+        case NewChipID('T', 'L'):
+        case NewChipID('T', 'R'):
+        case NewChipID('T', 'S'):
+        case NewChipID('T', 'T'):
+        case NewChipID('T', 'U'):
+            return ATI_CHIP_RAGE128PROULTRA;
+
+        case NewChipID('L', 'E'):
+        case NewChipID('L', 'F'):
+        /*
+         * "LK" and "LL" are not in any ATI documentation I can find
+         * - mharris
+         */
+        case NewChipID('L', 'K'):
+        case NewChipID('L', 'L'):
+            return ATI_CHIP_RAGE128MOBILITY3;
+
+        case NewChipID('M', 'F'):
+        case NewChipID('M', 'L'):
+            return ATI_CHIP_RAGE128MOBILITY4;
+
+        case NewChipID('Q', 'D'):
+        case NewChipID('Q', 'E'):
+        case NewChipID('Q', 'F'):
+        case NewChipID('Q', 'G'):
+            return ATI_CHIP_RADEON;
+
+        case NewChipID('Q', 'Y'):
+        case NewChipID('Q', 'Z'):
+        case NewChipID('Q', '^'):
+            return ATI_CHIP_RADEONVE;
+
+        case NewChipID('L', 'Y'):
+        case NewChipID('L', 'Z'):
+            return ATI_CHIP_RADEONMOBILITY6;
+
+        case NewChipID('A', '6'):
+        case NewChipID('C', '6'):
+             return ATI_CHIP_RS100;
+
+        case NewChipID('A', '7'):
+        case NewChipID('C', '7'):
+             return ATI_CHIP_RS200;
+
+        case NewChipID('D', '7'):
+        case NewChipID('B', '7'):
+             return ATI_CHIP_RS250;
+
+        case NewChipID('L', 'W'):
+        case NewChipID('L', 'X'):
+            return ATI_CHIP_RADEONMOBILITY7;
+
+        case NewChipID('Q', 'H'):
+        case NewChipID('Q', 'I'):
+        case NewChipID('Q', 'J'):
+        case NewChipID('Q', 'K'):
+        case NewChipID('Q', 'L'):
+        case NewChipID('Q', 'M'):
+        case NewChipID('Q', 'N'):
+        case NewChipID('Q', 'O'):
+        case NewChipID('Q', 'h'):
+        case NewChipID('Q', 'i'):
+        case NewChipID('Q', 'j'):
+        case NewChipID('Q', 'k'):
+        case NewChipID('Q', 'l'):
+        case NewChipID('B', 'B'):
+            return ATI_CHIP_R200;
+
+        case NewChipID('Q', 'W'):
+        case NewChipID('Q', 'X'):
+            return ATI_CHIP_RV200;
+
+        case NewChipID('I', 'f'):
+        case NewChipID('I', 'g'):
+            return ATI_CHIP_RV250;
+
+        case NewChipID('L', 'd'):
+        case NewChipID('L', 'f'):
+        case NewChipID('L', 'g'):
+            return ATI_CHIP_RADEONMOBILITY9;
+
+        case NewChipID('X', '4'):
+        case NewChipID('X', '5'):
+             return ATI_CHIP_RS300;
+
+        case NewChipID('x', '4'):
+        case NewChipID('x', '5'):
+             return ATI_CHIP_RS350;
+
+        case NewChipID('Y', '\''):
+        case NewChipID('Y', 'a'):
+        case NewChipID('Y', 'b'):
+        case NewChipID('Y', 'd'):
+        case NewChipID('Y', 'e'):
+            return ATI_CHIP_RV280;
+
+        case NewChipID('\\', 'a'):
+        case NewChipID('\\', 'c'):
+            return ATI_CHIP_RADEONMOBILITY9PLUS;
+
+        case NewChipID('A', 'D'):
+        case NewChipID('A', 'E'):
+        case NewChipID('A', 'F'):
+        case NewChipID('A', 'G'):
+        case NewChipID('N', 'D'):
+        case NewChipID('N', 'E'):
+        case NewChipID('N', 'F'):
+        case NewChipID('N', 'G'):
+            return ATI_CHIP_R300;
+
+        case NewChipID('A', 'H'):
+        case NewChipID('A', 'I'):
+        case NewChipID('A', 'J'):
+        case NewChipID('A', 'K'):
+        case NewChipID('N', 'H'):
+        case NewChipID('N', 'I'):
+        case NewChipID('N', 'K'):
+            return ATI_CHIP_R350;
+
+        case NewChipID('A', 'P'):
+        case NewChipID('A', 'Q'):
+        case NewChipID('A', 'R'):
+        case NewChipID('A', 'S'):
+        case NewChipID('A', 'T'):
+        case NewChipID('A', 'U'):
+        case NewChipID('A', 'V'):
+        case NewChipID('N', 'P'):
+        case NewChipID('N', 'Q'):
+        case NewChipID('N', 'R'):
+        case NewChipID('N', 'S'):
+        case NewChipID('N', 'T'):
+        case NewChipID('N', 'V'):
+            return ATI_CHIP_RV350;
+
+        case NewChipID('N', 'J'):
+            return ATI_CHIP_R360;
+
+        case NewChipID('[', '\''):
+        case NewChipID('[', 'b'):
+        case NewChipID('[', 'c'):
+        case NewChipID('[', 'd'):
+        case NewChipID('[', 'e'):
+        case NewChipID('T', '\''):
+        case NewChipID('T', 'b'):
+        case NewChipID('T', 'd'):
+	    return ATI_CHIP_RV370;
+
+        case NewChipID('>', 'P'):
+        case NewChipID('>', 'T'):
+        case NewChipID('1', 'P'):
+        case NewChipID('1', 'R'):
+        case NewChipID('1', 'T'):
+	    return ATI_CHIP_RV380;
+
+        case NewChipID('J', 'H'):
+        case NewChipID('J', 'I'):
+        case NewChipID('J', 'J'):
+        case NewChipID('J', 'K'):
+        case NewChipID('J', 'L'):
+        case NewChipID('J', 'M'):
+        case NewChipID('J', 'N'):
+        case NewChipID('J', 'O'):
+        case NewChipID('J', 'P'):
+        case NewChipID('J', 'T'):
+	    return ATI_CHIP_R420;
+
+        case NewChipID('U', 'H'):
+        case NewChipID('U', 'I'):
+        case NewChipID('U', 'J'):
+        case NewChipID('U', 'K'):
+        case NewChipID('U', 'P'):
+        case NewChipID('U', 'Q'):
+        case NewChipID('U', 'R'):
+        case NewChipID('U', 'T'):
+        case NewChipID(']', 'W'):
+        /* those are m28, not 100% certain they are r423 could
+	   be r480 but not r430 as their pci id names indicate... */
+        case NewChipID(']', 'H'):
+        case NewChipID(']', 'I'):
+        case NewChipID(']', 'J'):
+	    return ATI_CHIP_R423;
+
+        case NewChipID('U', 'L'):
+        case NewChipID('U', 'M'):
+        case NewChipID('U', 'N'):
+        case NewChipID('U', 'O'):
+	    return ATI_CHIP_R430;
+
+        case NewChipID(']', 'L'):
+        case NewChipID(']', 'M'):
+        case NewChipID(']', 'N'):
+        case NewChipID(']', 'O'):
+        case NewChipID(']', 'P'):
+        case NewChipID(']', 'R'):
+	    return ATI_CHIP_R480;
+
+        case NewChipID('K', 'I'):
+        case NewChipID('K', 'J'):
+        case NewChipID('K', 'K'):
+        case NewChipID('K', 'L'):
+	    return ATI_CHIP_R481;
+
+        case NewChipID('^', 'H'):
+        case NewChipID('^', 'J'):
+        case NewChipID('^', 'K'):
+        case NewChipID('^', 'L'):
+        case NewChipID('^', 'M'):
+        case NewChipID('^', 'O'):
+        case NewChipID('V', 'J'):
+        case NewChipID('V', 'K'):
+        case NewChipID('V', 'O'):
+        case NewChipID('V', 'R'):
+        case NewChipID('V', 'S'):
+	    return ATI_CHIP_RV410;
+
+        case NewChipID('Z', 'A'):
+        case NewChipID('Z', 'B'):
+        case NewChipID('Z', 'a'):
+        case NewChipID('Z', 'b'):
+        case NewChipID('Y', 'T'):
+        case NewChipID('Y', 'U'):
+        case NewChipID('Y', 't'):
+        case NewChipID('Y', 'u'):
+	    return ATI_CHIP_RS400;
+
+        case NewChipID('H', 'D'):
+            return ATI_CHIP_HDTV;
+
+        default:
+            /*
+             * Treat anything else as an unknown Radeon.  Please keep the above
+             * up-to-date however, as it serves as a central chip list.
+             */
+            return ATI_CHIP_Radeon;
+    }
+}
diff --git a/src/ati.h b/src/ati.h
index fbb8521..48ab1cd 100644
--- a/src/ati.h
+++ b/src/ati.h
@@ -33,4 +33,76 @@
 
 extern DriverRec ATI;
 
+/*
+ * Chip-related definitions.
+ */
+typedef enum
+{
+    ATI_CHIP_NONE = 0,
+    ATI_CHIP_88800GXC,          /* Mach64 */
+    ATI_CHIP_88800GXD,          /* Mach64 */
+    ATI_CHIP_88800GXE,          /* Mach64 */
+    ATI_CHIP_88800GXF,          /* Mach64 */
+    ATI_CHIP_88800GX,           /* Mach64 */
+    ATI_CHIP_88800CX,           /* Mach64 */
+    ATI_CHIP_264CT,             /* Mach64 */
+    ATI_CHIP_264ET,             /* Mach64 */
+    ATI_CHIP_264VT,             /* Mach64 */
+    ATI_CHIP_264GT,             /* Mach64 */
+    ATI_CHIP_264VTB,            /* Mach64 */
+    ATI_CHIP_264GTB,            /* Mach64 */
+    ATI_CHIP_264VT3,            /* Mach64 */
+    ATI_CHIP_264GTDVD,          /* Mach64 */
+    ATI_CHIP_264LT,             /* Mach64 */
+    ATI_CHIP_264VT4,            /* Mach64 */
+    ATI_CHIP_264GT2C,           /* Mach64 */
+    ATI_CHIP_264GTPRO,          /* Mach64 */
+    ATI_CHIP_264LTPRO,          /* Mach64 */
+    ATI_CHIP_264XL,             /* Mach64 */
+    ATI_CHIP_MOBILITY,          /* Mach64 */
+    ATI_CHIP_Mach64,            /* Last among Mach64's */
+    ATI_CHIP_RAGE128GL,         /* Rage128 */
+    ATI_CHIP_RAGE128VR,         /* Rage128 */
+    ATI_CHIP_RAGE128PROGL,      /* Rage128 */
+    ATI_CHIP_RAGE128PROVR,      /* Rage128 */
+    ATI_CHIP_RAGE128PROULTRA,   /* Rage128 */
+    ATI_CHIP_RAGE128MOBILITY3,  /* Rage128 */
+    ATI_CHIP_RAGE128MOBILITY4,  /* Rage128 */
+    ATI_CHIP_Rage128,           /* Last among Rage128's */
+    ATI_CHIP_RADEON,            /* Radeon */
+    ATI_CHIP_RADEONVE,          /* Radeon VE */
+    ATI_CHIP_RADEONMOBILITY6,   /* Radeon M6 */
+    ATI_CHIP_RS100,             /* IGP320 */
+    ATI_CHIP_RS200,             /* IGP340 */
+    ATI_CHIP_RS250,             /* Radoen 7000 IGP */
+    ATI_CHIP_RV200,             /* RV200 */
+    ATI_CHIP_RADEONMOBILITY7,   /* Radeon M7 */
+    ATI_CHIP_R200,              /* R200 */
+    ATI_CHIP_RV250,             /* RV250 */
+    ATI_CHIP_RADEONMOBILITY9,   /* Radeon M9 */
+    ATI_CHIP_RS300,             /* Radoen 9100 IGP */
+    ATI_CHIP_RS350,             /* Radoen 9200 IGP */
+    ATI_CHIP_RV280,             /* RV250 */
+    ATI_CHIP_RADEONMOBILITY9PLUS,   /* Radeon M9+ */
+    ATI_CHIP_R300,              /* R300 */
+    ATI_CHIP_RV350,             /* RV350/M10/M11 */
+    ATI_CHIP_R350,              /* R350 */
+    ATI_CHIP_R360,              /* R360 */
+    ATI_CHIP_RV370,             /* RV370/M22 */
+    ATI_CHIP_RV380,             /* RV380/M24 */
+    ATI_CHIP_R420,              /* R420/M18 */
+    ATI_CHIP_R423,              /* R423/M28? */
+    ATI_CHIP_R430,              /* R430 */
+    ATI_CHIP_R480,              /* R480/M28? */
+    ATI_CHIP_R481,              /* R481 */
+    ATI_CHIP_RV410,             /* RV410, M26 */
+    ATI_CHIP_RS400,             /* RS400, RS410, RS480, RS482, ... */
+    ATI_CHIP_Radeon,            /* Last among Radeon's */
+    ATI_CHIP_HDTV               /* HDTV */
+} ATIChipType;
+
+extern const char *ATIChipNames[];
+
+extern ATIChipType ATIChipID(const CARD16, const CARD8);
+
 #endif /* ___ATI_H___ */
diff --git a/src/atichip.c b/src/atichip.c
index 6ef423b..5f8a221 100644
--- a/src/atichip.c
+++ b/src/atichip.c
@@ -30,74 +30,6 @@
 #include "atimach64io.h"
 #include "ativersion.h"
 
-/*
- * Chip-related definitions.
- */
-const char *ATIChipNames[] =
-{
-    "Unknown",
-    "ATI 88800GX-C",
-    "ATI 88800GX-D",
-    "ATI 88800GX-E",
-    "ATI 88800GX-F",
-    "ATI 88800GX",
-    "ATI 88800CX",
-    "ATI 264CT",
-    "ATI 264ET",
-    "ATI 264VT",
-    "ATI 3D Rage",
-    "ATI 264VT-B",
-    "ATI 3D Rage II",
-    "ATI 264VT3",
-    "ATI 3D Rage II+DVD",
-    "ATI 3D Rage LT",
-    "ATI 264VT4",
-    "ATI 3D Rage IIc",
-    "ATI 3D Rage Pro",
-    "ATI 3D Rage LT Pro",
-    "ATI 3D Rage XL or XC",
-    "ATI 3D Rage Mobility",
-    "ATI unknown Mach64",
-    "ATI Rage 128 GL",
-    "ATI Rage 128 VR",
-    "ATI Rage 128 Pro GL",
-    "ATI Rage 128 Pro VR",
-    "ATI Rage 128 Pro ULTRA",
-    "ATI Rage 128 Mobility M3",
-    "ATI Rage 128 Mobility M4",
-    "ATI unknown Rage 128"
-    "ATI Radeon 7200",
-    "ATI Radeon 7000 (VE)",
-    "ATI Radeon Mobility M6",
-    "ATI Radeon IGP320",
-    "ATI Radeon IGP330/340/350",
-    "ATI Radeon 7000 IGP",
-    "ATI Radeon 7500",
-    "ATI Radeon Mobility M7",
-    "ATI Radeon 8500/9100",
-    "ATI Radeon 9000",
-    "ATI Radeon Mobility M9",
-    "ATI Radeon 9100 IGP",
-    "ATI Radeon 9200 IGP",
-    "ATI Radeon 9200",
-    "ATI Radeon Mobility M9+",
-    "ATI Radeon 9700/9500",
-    "ATI Radeon 9600/9550",
-    "ATI Radeon 9800",
-    "ATI Radeon 9800XT",
-    "ATI Radeon X300/X550/M22",
-    "ATI Radeon X600/X550/M24",
-    "ATI Radeon X800/M18 AGP",
-    "ATI Radeon X800/M28 PCIE",
-    "ATI Radeon X800XL PCIE",
-    "ATI Radeon X850 PCIE",
-    "ATI Radeon X850 AGP",
-    "ATI Radeon X700",
-    "ATI Xpress 200"
-    "ATI unknown Radeon",
-    "ATI Rage HDTV"
-};
-
 const char *ATIFoundryNames[] =
     { "SGS", "NEC", "KCS", "UMC", "TSMC", "5", "6", "UMC" };
 
@@ -337,399 +269,3 @@ ATIMach64ChipID
             break;
     }
 }
-
-/*
- * ATIChipID --
- *
- * This returns the ATI_CHIP_* value (generally) associated with a particular
- * ChipID/ChipRev combination.
- */
-ATIChipType
-ATIChipID
-(
-    const CARD16 ChipID,
-    const CARD8  ChipRev
-)
-{
-    switch (ChipID)
-    {
-        case OldChipID('G', 'X'):  case NewChipID('G', 'X'):
-            switch (ChipRev)
-            {
-                case 0x00U:
-                    return ATI_CHIP_88800GXC;
-
-                case 0x01U:
-                    return ATI_CHIP_88800GXD;
-
-                case 0x02U:
-                    return ATI_CHIP_88800GXE;
-
-                case 0x03U:
-                    return ATI_CHIP_88800GXF;
-
-                default:
-                    return ATI_CHIP_88800GX;
-            }
-
-        case OldChipID('C', 'X'):  case NewChipID('C', 'X'):
-            return ATI_CHIP_88800CX;
-
-        case OldChipID('C', 'T'):  case NewChipID('C', 'T'):
-            return ATI_CHIP_264CT;
-
-        case OldChipID('E', 'T'):  case NewChipID('E', 'T'):
-            return ATI_CHIP_264ET;
-
-        case OldChipID('V', 'T'):  case NewChipID('V', 'T'):
-            /* For simplicity, ignore ChipID discrepancy that can occur here */
-            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
-                return ATI_CHIP_264VT;
-            return ATI_CHIP_264VTB;
-
-        case OldChipID('G', 'T'):  case NewChipID('G', 'T'):
-            if (!(ChipRev & GetBits(CFG_CHIP_VERSION, CFG_CHIP_REV)))
-                return ATI_CHIP_264GT;
-            return ATI_CHIP_264GTB;
-
-        case OldChipID('V', 'U'):  case NewChipID('V', 'U'):
-            return ATI_CHIP_264VT3;
-
-        case OldChipID('G', 'U'):  case NewChipID('G', 'U'):
-            return ATI_CHIP_264GTDVD;
-
-        case OldChipID('L', 'G'):  case NewChipID('L', 'G'):
-            return ATI_CHIP_264LT;
-
-        case OldChipID('V', 'V'):  case NewChipID('V', 'V'):
-            return ATI_CHIP_264VT4;
-
-        case OldChipID('G', 'V'):  case NewChipID('G', 'V'):
-        case OldChipID('G', 'W'):  case NewChipID('G', 'W'):
-        case OldChipID('G', 'Y'):  case NewChipID('G', 'Y'):
-        case OldChipID('G', 'Z'):  case NewChipID('G', 'Z'):
-            return ATI_CHIP_264GT2C;
-
-        case OldChipID('G', 'B'):  case NewChipID('G', 'B'):
-        case OldChipID('G', 'D'):  case NewChipID('G', 'D'):
-        case OldChipID('G', 'I'):  case NewChipID('G', 'I'):
-        case OldChipID('G', 'P'):  case NewChipID('G', 'P'):
-        case OldChipID('G', 'Q'):  case NewChipID('G', 'Q'):
-            return ATI_CHIP_264GTPRO;
-
-        case OldChipID('L', 'B'):  case NewChipID('L', 'B'):
-        case OldChipID('L', 'D'):  case NewChipID('L', 'D'):
-        case OldChipID('L', 'I'):  case NewChipID('L', 'I'):
-        case OldChipID('L', 'P'):  case NewChipID('L', 'P'):
-        case OldChipID('L', 'Q'):  case NewChipID('L', 'Q'):
-            return ATI_CHIP_264LTPRO;
-
-        case OldChipID('G', 'L'):  case NewChipID('G', 'L'):
-        case OldChipID('G', 'M'):  case NewChipID('G', 'M'):
-        case OldChipID('G', 'N'):  case NewChipID('G', 'N'):
-        case OldChipID('G', 'O'):  case NewChipID('G', 'O'):
-        case OldChipID('G', 'R'):  case NewChipID('G', 'R'):
-        case OldChipID('G', 'S'):  case NewChipID('G', 'S'):
-            return ATI_CHIP_264XL;
-
-        case OldChipID('L', 'M'):  case NewChipID('L', 'M'):
-        case OldChipID('L', 'N'):  case NewChipID('L', 'N'):
-        case OldChipID('L', 'R'):  case NewChipID('L', 'R'):
-        case OldChipID('L', 'S'):  case NewChipID('L', 'S'):
-            return ATI_CHIP_MOBILITY;
-
-        case NewChipID('R', 'E'):
-        case NewChipID('R', 'F'):
-        case NewChipID('R', 'G'):
-        case NewChipID('S', 'K'):
-        case NewChipID('S', 'L'):
-        case NewChipID('S', 'M'):
-        /* "SN" is listed as ATI_CHIP_RAGE128_4X in ATI docs */
-        case NewChipID('S', 'N'):
-            return ATI_CHIP_RAGE128GL;
-
-        case NewChipID('R', 'K'):
-        case NewChipID('R', 'L'):
-        /*
-         * ATI documentation lists SE/SF/SG under both ATI_CHIP_RAGE128VR
-         * and ATI_CHIP_RAGE128_4X, and lists SH/SK/SL under Rage 128 4X only.
-         * I'm stuffing them here for now until this can be clarified as ATI
-         * documentation doesn't mention their details. <mharris at redhat.com>
-         */
-        case NewChipID('S', 'E'):
-        case NewChipID('S', 'F'):
-        case NewChipID('S', 'G'):
-        case NewChipID('S', 'H'):
-            return ATI_CHIP_RAGE128VR;
-
-     /* case NewChipID('S', 'H'): */
-     /* case NewChipID('S', 'K'): */
-     /* case NewChipID('S', 'L'): */
-     /* case NewChipID('S', 'N'): */
-     /*     return ATI_CHIP_RAGE128_4X; */
-
-        case NewChipID('P', 'A'):
-        case NewChipID('P', 'B'):
-        case NewChipID('P', 'C'):
-        case NewChipID('P', 'D'):
-        case NewChipID('P', 'E'):
-        case NewChipID('P', 'F'):
-            return ATI_CHIP_RAGE128PROGL;
-
-        case NewChipID('P', 'G'):
-        case NewChipID('P', 'H'):
-        case NewChipID('P', 'I'):
-        case NewChipID('P', 'J'):
-        case NewChipID('P', 'K'):
-        case NewChipID('P', 'L'):
-        case NewChipID('P', 'M'):
-        case NewChipID('P', 'N'):
-        case NewChipID('P', 'O'):
-        case NewChipID('P', 'P'):
-        case NewChipID('P', 'Q'):
-        case NewChipID('P', 'R'):
-        case NewChipID('P', 'S'):
-        case NewChipID('P', 'T'):
-        case NewChipID('P', 'U'):
-        case NewChipID('P', 'V'):
-        case NewChipID('P', 'W'):
-        case NewChipID('P', 'X'):
-            return ATI_CHIP_RAGE128PROVR;
-
-        case NewChipID('T', 'F'):
-        case NewChipID('T', 'L'):
-        case NewChipID('T', 'R'):
-        case NewChipID('T', 'S'):
-        case NewChipID('T', 'T'):
-        case NewChipID('T', 'U'):
-            return ATI_CHIP_RAGE128PROULTRA;
-
-        case NewChipID('L', 'E'):
-        case NewChipID('L', 'F'):
-        /*
-         * "LK" and "LL" are not in any ATI documentation I can find
-         * - mharris
-         */
-        case NewChipID('L', 'K'):
-        case NewChipID('L', 'L'):
-            return ATI_CHIP_RAGE128MOBILITY3;
-
-        case NewChipID('M', 'F'):
-        case NewChipID('M', 'L'):
-            return ATI_CHIP_RAGE128MOBILITY4;
-
-        case NewChipID('Q', 'D'):
-        case NewChipID('Q', 'E'):
-        case NewChipID('Q', 'F'):
-        case NewChipID('Q', 'G'):
-            return ATI_CHIP_RADEON;
-
-        case NewChipID('Q', 'Y'):
-        case NewChipID('Q', 'Z'):
-        case NewChipID('Q', '^'):
-            return ATI_CHIP_RADEONVE;
-
-        case NewChipID('L', 'Y'):
-        case NewChipID('L', 'Z'):
-            return ATI_CHIP_RADEONMOBILITY6;
-
-        case NewChipID('A', '6'):
-        case NewChipID('C', '6'):
-             return ATI_CHIP_RS100;
-
-        case NewChipID('A', '7'):
-        case NewChipID('C', '7'):
-             return ATI_CHIP_RS200;
-
-        case NewChipID('D', '7'):
-        case NewChipID('B', '7'):
-             return ATI_CHIP_RS250;
-
-        case NewChipID('L', 'W'):
-        case NewChipID('L', 'X'):
-            return ATI_CHIP_RADEONMOBILITY7;
-
-        case NewChipID('Q', 'H'):
-        case NewChipID('Q', 'I'):
-        case NewChipID('Q', 'J'):
-        case NewChipID('Q', 'K'):
-        case NewChipID('Q', 'L'):
-        case NewChipID('Q', 'M'):
-        case NewChipID('Q', 'N'):
-        case NewChipID('Q', 'O'):
-        case NewChipID('Q', 'h'):
-        case NewChipID('Q', 'i'):
-        case NewChipID('Q', 'j'):
-        case NewChipID('Q', 'k'):
-        case NewChipID('Q', 'l'):
-        case NewChipID('B', 'B'):
-            return ATI_CHIP_R200;
-
-        case NewChipID('Q', 'W'):
-        case NewChipID('Q', 'X'):
-            return ATI_CHIP_RV200;
-
-        case NewChipID('I', 'f'):
-        case NewChipID('I', 'g'):
-            return ATI_CHIP_RV250;
-
-        case NewChipID('L', 'd'):
-        case NewChipID('L', 'f'):
-        case NewChipID('L', 'g'):
-            return ATI_CHIP_RADEONMOBILITY9;
-
-        case NewChipID('X', '4'):
-        case NewChipID('X', '5'):
-             return ATI_CHIP_RS300;
-
-        case NewChipID('x', '4'):
-        case NewChipID('x', '5'):
-             return ATI_CHIP_RS350;
-
-        case NewChipID('Y', '\''):
-        case NewChipID('Y', 'a'):
-        case NewChipID('Y', 'b'):
-        case NewChipID('Y', 'd'):
-        case NewChipID('Y', 'e'):
-            return ATI_CHIP_RV280;
-
-        case NewChipID('\\', 'a'):
-        case NewChipID('\\', 'c'):
-            return ATI_CHIP_RADEONMOBILITY9PLUS;
-
-        case NewChipID('A', 'D'):
-        case NewChipID('A', 'E'):
-        case NewChipID('A', 'F'):
-        case NewChipID('A', 'G'):
-        case NewChipID('N', 'D'):
-        case NewChipID('N', 'E'):
-        case NewChipID('N', 'F'):
-        case NewChipID('N', 'G'):
-            return ATI_CHIP_R300;
-
-        case NewChipID('A', 'H'):
-        case NewChipID('A', 'I'):
-        case NewChipID('A', 'J'):
-        case NewChipID('A', 'K'):
-        case NewChipID('N', 'H'):
-        case NewChipID('N', 'I'):
-        case NewChipID('N', 'K'):
-            return ATI_CHIP_R350;
-
-        case NewChipID('A', 'P'):
-        case NewChipID('A', 'Q'):
-        case NewChipID('A', 'R'):
-        case NewChipID('A', 'S'):
-        case NewChipID('A', 'T'):
-        case NewChipID('A', 'U'):
-        case NewChipID('A', 'V'):
-        case NewChipID('N', 'P'):
-        case NewChipID('N', 'Q'):
-        case NewChipID('N', 'R'):
-        case NewChipID('N', 'S'):
-        case NewChipID('N', 'T'):
-        case NewChipID('N', 'V'):
-            return ATI_CHIP_RV350;
-
-        case NewChipID('N', 'J'):
-            return ATI_CHIP_R360;
-
-        case NewChipID('[', '\''):
-        case NewChipID('[', 'b'):
-        case NewChipID('[', 'c'):
-        case NewChipID('[', 'd'):
-        case NewChipID('[', 'e'):
-        case NewChipID('T', '\''):
-        case NewChipID('T', 'b'):
-        case NewChipID('T', 'd'):
-	    return ATI_CHIP_RV370;
-
-        case NewChipID('>', 'P'):
-        case NewChipID('>', 'T'):
-        case NewChipID('1', 'P'):
-        case NewChipID('1', 'R'):
-        case NewChipID('1', 'T'):
-	    return ATI_CHIP_RV380;
-
-        case NewChipID('J', 'H'):
-        case NewChipID('J', 'I'):
-        case NewChipID('J', 'J'):
-        case NewChipID('J', 'K'):
-        case NewChipID('J', 'L'):
-        case NewChipID('J', 'M'):
-        case NewChipID('J', 'N'):
-        case NewChipID('J', 'O'):
-        case NewChipID('J', 'P'):
-        case NewChipID('J', 'T'):
-	    return ATI_CHIP_R420;
-
-        case NewChipID('U', 'H'):
-        case NewChipID('U', 'I'):
-        case NewChipID('U', 'J'):
-        case NewChipID('U', 'K'):
-        case NewChipID('U', 'P'):
-        case NewChipID('U', 'Q'):
-        case NewChipID('U', 'R'):
-        case NewChipID('U', 'T'):
-        case NewChipID(']', 'W'):
-        /* those are m28, not 100% certain they are r423 could
-	   be r480 but not r430 as their pci id names indicate... */
-        case NewChipID(']', 'H'):
-        case NewChipID(']', 'I'):
-        case NewChipID(']', 'J'):
-	    return ATI_CHIP_R423;
-
-        case NewChipID('U', 'L'):
-        case NewChipID('U', 'M'):
-        case NewChipID('U', 'N'):
-        case NewChipID('U', 'O'):
-	    return ATI_CHIP_R430;
-
-        case NewChipID(']', 'L'):
-        case NewChipID(']', 'M'):
-        case NewChipID(']', 'N'):
-        case NewChipID(']', 'O'):
-        case NewChipID(']', 'P'):
-        case NewChipID(']', 'R'):
-	    return ATI_CHIP_R480;
-
-        case NewChipID('K', 'I'):
-        case NewChipID('K', 'J'):
-        case NewChipID('K', 'K'):
-        case NewChipID('K', 'L'):
-	    return ATI_CHIP_R481;
-
-        case NewChipID('^', 'H'):
-        case NewChipID('^', 'J'):
-        case NewChipID('^', 'K'):
-        case NewChipID('^', 'L'):
-        case NewChipID('^', 'M'):
-        case NewChipID('^', 'O'):
-        case NewChipID('V', 'J'):
-        case NewChipID('V', 'K'):
-        case NewChipID('V', 'O'):
-        case NewChipID('V', 'R'):
-        case NewChipID('V', 'S'):
-	    return ATI_CHIP_RV410;
-
-        case NewChipID('Z', 'A'):
-        case NewChipID('Z', 'B'):
-        case NewChipID('Z', 'a'):
-        case NewChipID('Z', 'b'):
-        case NewChipID('Y', 'T'):
-        case NewChipID('Y', 'U'):
-        case NewChipID('Y', 't'):
-        case NewChipID('Y', 'u'):
-	    return ATI_CHIP_RS400;
-
-        case NewChipID('H', 'D'):
-            return ATI_CHIP_HDTV;
-
-        default:
-            /*
-             * Treat anything else as an unknown Radeon.  Please keep the above
-             * up-to-date however, as it serves as a central chip list.
-             */
-            return ATI_CHIP_Radeon;
-    }
-}
diff --git a/src/atichip.h b/src/atichip.h
index 733c7b1..44cd188 100644
--- a/src/atichip.h
+++ b/src/atichip.h
@@ -29,76 +29,6 @@
 #include <X11/Xmd.h>
 
 /*
- * Chip-related definitions.
- */
-typedef enum
-{
-    ATI_CHIP_NONE = 0,
-    ATI_CHIP_88800GXC,          /* Mach64 */
-    ATI_CHIP_88800GXD,          /* Mach64 */
-    ATI_CHIP_88800GXE,          /* Mach64 */
-    ATI_CHIP_88800GXF,          /* Mach64 */
-    ATI_CHIP_88800GX,           /* Mach64 */
-    ATI_CHIP_88800CX,           /* Mach64 */
-    ATI_CHIP_264CT,             /* Mach64 */
-    ATI_CHIP_264ET,             /* Mach64 */
-    ATI_CHIP_264VT,             /* Mach64 */
-    ATI_CHIP_264GT,             /* Mach64 */
-    ATI_CHIP_264VTB,            /* Mach64 */
-    ATI_CHIP_264GTB,            /* Mach64 */
-    ATI_CHIP_264VT3,            /* Mach64 */
-    ATI_CHIP_264GTDVD,          /* Mach64 */
-    ATI_CHIP_264LT,             /* Mach64 */
-    ATI_CHIP_264VT4,            /* Mach64 */
-    ATI_CHIP_264GT2C,           /* Mach64 */
-    ATI_CHIP_264GTPRO,          /* Mach64 */
-    ATI_CHIP_264LTPRO,          /* Mach64 */
-    ATI_CHIP_264XL,             /* Mach64 */
-    ATI_CHIP_MOBILITY,          /* Mach64 */
-    ATI_CHIP_Mach64,            /* Last among Mach64's */
-    ATI_CHIP_RAGE128GL,         /* Rage128 */
-    ATI_CHIP_RAGE128VR,         /* Rage128 */
-    ATI_CHIP_RAGE128PROGL,      /* Rage128 */
-    ATI_CHIP_RAGE128PROVR,      /* Rage128 */
-    ATI_CHIP_RAGE128PROULTRA,   /* Rage128 */
-    ATI_CHIP_RAGE128MOBILITY3,  /* Rage128 */
-    ATI_CHIP_RAGE128MOBILITY4,  /* Rage128 */
-    ATI_CHIP_Rage128,           /* Last among Rage128's */
-    ATI_CHIP_RADEON,            /* Radeon */
-    ATI_CHIP_RADEONVE,          /* Radeon VE */
-    ATI_CHIP_RADEONMOBILITY6,   /* Radeon M6 */
-    ATI_CHIP_RS100,             /* IGP320 */
-    ATI_CHIP_RS200,             /* IGP340 */
-    ATI_CHIP_RS250,             /* Radoen 7000 IGP */
-    ATI_CHIP_RV200,             /* RV200 */
-    ATI_CHIP_RADEONMOBILITY7,   /* Radeon M7 */
-    ATI_CHIP_R200,              /* R200 */
-    ATI_CHIP_RV250,             /* RV250 */
-    ATI_CHIP_RADEONMOBILITY9,   /* Radeon M9 */
-    ATI_CHIP_RS300,             /* Radoen 9100 IGP */
-    ATI_CHIP_RS350,             /* Radoen 9200 IGP */
-    ATI_CHIP_RV280,             /* RV250 */
-    ATI_CHIP_RADEONMOBILITY9PLUS,   /* Radeon M9+ */
-    ATI_CHIP_R300,              /* R300 */
-    ATI_CHIP_RV350,             /* RV350/M10/M11 */
-    ATI_CHIP_R350,              /* R350 */
-    ATI_CHIP_R360,              /* R360 */
-    ATI_CHIP_RV370,             /* RV370/M22 */
-    ATI_CHIP_RV380,             /* RV380/M24 */
-    ATI_CHIP_R420,              /* R420/M18 */
-    ATI_CHIP_R423,              /* R423/M28? */
-    ATI_CHIP_R430,              /* R430 */
-    ATI_CHIP_R480,              /* R480/M28? */
-    ATI_CHIP_R481,              /* R481 */
-    ATI_CHIP_RV410,             /* RV410, M26 */
-    ATI_CHIP_RS400,             /* RS400, RS410, RS480, RS482, ... */
-    ATI_CHIP_Radeon,            /* Last among Radeon's */
-    ATI_CHIP_HDTV               /* HDTV */
-} ATIChipType;
-
-extern const char *ATIChipNames[];
-
-/*
  * Foundry codes for 264xT's.
  */
 typedef enum
@@ -116,7 +46,6 @@ typedef enum
 extern const char *ATIFoundryNames[];
 
 extern void        ATIMach64ChipID(ATIPtr, const CARD16);
-extern ATIChipType ATIChipID(const CARD16, const CARD8);
 
 #define OldChipID(_1, _0) \
     (SetBits(_0 - 'A', CHIP_CODE_0) | SetBits(_1 - 'A', CHIP_CODE_1))
diff-tree aa8f5b02ebc9be60df48722588261627d6a457e8 (from 39e896a1e688ea2d2d21f88c1c5d34c5810aac1c)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sat Mar 24 19:53:02 2007 +0200

    [mach64] Use Mach64Chipsets[] instead of ATIChipNames[].
    
    atimisc is PCI-only now, we can get the chip name with xf86TokenToString().

diff --git a/src/atimach64probe.c b/src/atimach64probe.c
index 043cad9..c5330cc 100644
--- a/src/atimach64probe.c
+++ b/src/atimach64probe.c
@@ -38,7 +38,7 @@
 #include "atiadjust.h"
 #include "ativalid.h"
 
-static SymTabRec
+SymTabRec
 Mach64Chipsets[] = {
     {ATI_CHIP_88800GXC, "ATI 88800GX-C"},
     {ATI_CHIP_88800GXD, "ATI 88800GX-D"},
diff --git a/src/atimach64probe.h b/src/atimach64probe.h
index fa9e713..65ced98 100644
--- a/src/atimach64probe.h
+++ b/src/atimach64probe.h
@@ -25,6 +25,8 @@
 
 #include "xf86str.h"
 
+extern SymTabRec             Mach64Chipsets[];
+
 extern const OptionInfoRec * Mach64AvailableOptions(int, int);
 extern void                  Mach64Identify(int);
 extern Bool                  Mach64Probe(DriverPtr, int);
diff --git a/src/atipreinit.c b/src/atipreinit.c
index 7f0c4b2..d960e88 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -41,6 +41,7 @@
 #include "atimach64.h"
 #include "atimach64accel.h"
 #include "atimach64io.h"
+#include "atimach64probe.h"
 #include "atimode.h"
 #include "atioption.h"
 #include "atipreinit.h"
@@ -982,7 +983,8 @@ ATIPreInit
 
     /* Report what was found */
     xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED,
-        "%s graphics controller detected.\n", ATIChipNames[pATI->Chip]);
+        "%s graphics controller detected.\n",
+        xf86TokenToString(Mach64Chipsets, pATI->Chip));
 
     {
         Message = Buffer + snprintf(Buffer, SizeOf(Buffer), "Chip type %04X",
diff-tree 39e896a1e688ea2d2d21f88c1c5d34c5810aac1c (from f046a910ca117279fbabc6281b2e23439ec9ea4e)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Sat Mar 24 19:47:18 2007 +0200

    [mach64] Set pATI->ChipRevision correctly, instead of overriding.
    
    There is no need to override pATI->ChipRevision for GX/CX, as it is only
    reported with a printf.

diff --git a/src/atichip.c b/src/atichip.c
index ddc7e0a..6ef423b 100644
--- a/src/atichip.c
+++ b/src/atichip.c
@@ -115,18 +115,18 @@ ATIMach64ChipID
 )
 {
     pATI->config_chip_id = inr(CONFIG_CHIP_ID);
-    pATI->ChipType       = GetBits(pATI->config_chip_id, 0xFFFFU);
+    pATI->ChipType       = GetBits(pATI->config_chip_id, CFG_CHIP_TYPE);
     pATI->ChipClass      = GetBits(pATI->config_chip_id, CFG_CHIP_CLASS);
-    pATI->ChipRevision   = GetBits(pATI->config_chip_id, CFG_CHIP_REV);
+    pATI->ChipRev        = GetBits(pATI->config_chip_id, CFG_CHIP_REV);
     pATI->ChipVersion    = GetBits(pATI->config_chip_id, CFG_CHIP_VERSION);
     pATI->ChipFoundry    = GetBits(pATI->config_chip_id, CFG_CHIP_FOUNDRY);
-    pATI->ChipRev        = pATI->ChipRevision;
+    pATI->ChipRevision   = GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
     switch (pATI->ChipType)
     {
         case OldChipID('G', 'X'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'X'):
-            switch (pATI->ChipRevision)
+            switch (pATI->ChipRev)
             {
                 case 0x00U:
                     pATI->Chip = ATI_CHIP_88800GXC;
@@ -159,8 +159,6 @@ ATIMach64ChipID
         case OldChipID('C', 'T'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('C', 'T'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264CT;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -168,8 +166,6 @@ ATIMach64ChipID
         case OldChipID('E', 'T'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('E', 'T'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264ET;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -177,8 +173,6 @@ ATIMach64ChipID
         case OldChipID('V', 'T'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('V', 'T'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264VT;
             pATI->BusType = ATI_BUS_PCI;
             /* Some early GT's are detected as VT's */
@@ -199,8 +193,6 @@ ATIMach64ChipID
         case OldChipID('G', 'T'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'T'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->BusType = ATI_BUS_PCI;
             if (!pATI->ChipVersion)
                 pATI->Chip = ATI_CHIP_264GT;
@@ -211,8 +203,6 @@ ATIMach64ChipID
         case OldChipID('V', 'U'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('V', 'U'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264VT3;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -220,8 +210,6 @@ ATIMach64ChipID
         case OldChipID('G', 'U'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'U'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264GTDVD;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -229,8 +217,6 @@ ATIMach64ChipID
         case OldChipID('L', 'G'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('L', 'G'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264LT;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -238,8 +224,6 @@ ATIMach64ChipID
         case OldChipID('V', 'V'):
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('V', 'V'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264VT4;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -249,8 +233,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'V'):
         case NewChipID('G', 'Y'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264GT2C;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -260,8 +242,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'W'):
         case NewChipID('G', 'Z'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264GT2C;
             pATI->BusType = ATI_BUS_AGP;
             break;
@@ -273,8 +253,6 @@ ATIMach64ChipID
         case NewChipID('G', 'I'):
         case NewChipID('G', 'P'):
         case NewChipID('G', 'Q'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264GTPRO;
             pATI->BusType = ATI_BUS_PCI;
             break;
@@ -284,8 +262,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'B'):
         case NewChipID('G', 'D'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264GTPRO;
             pATI->BusType = ATI_BUS_AGP;
             break;
@@ -297,8 +273,6 @@ ATIMach64ChipID
         case NewChipID('L', 'I'):
         case NewChipID('L', 'P'):
         case NewChipID('L', 'Q'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264LTPRO;
             pATI->BusType = ATI_BUS_PCI;
             pATI->LCDVBlendFIFOSize = 800;
@@ -309,8 +283,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('L', 'B'):
         case NewChipID('L', 'D'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264LTPRO;
             pATI->BusType = ATI_BUS_AGP;
             pATI->LCDVBlendFIFOSize = 800;
@@ -325,8 +297,6 @@ ATIMach64ChipID
         case NewChipID('G', 'O'):
         case NewChipID('G', 'R'):
         case NewChipID('G', 'S'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264XL;
             pATI->BusType = ATI_BUS_PCI;
             pATI->LCDVBlendFIFOSize = 1024;
@@ -337,8 +307,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('G', 'M'):
         case NewChipID('G', 'N'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_264XL;
             pATI->BusType = ATI_BUS_AGP;
             pATI->LCDVBlendFIFOSize = 1024;
@@ -349,8 +317,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('L', 'R'):
         case NewChipID('L', 'S'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_MOBILITY;
             pATI->BusType = ATI_BUS_PCI;
             pATI->LCDVBlendFIFOSize = 1024;
@@ -361,8 +327,6 @@ ATIMach64ChipID
             pATI->ChipType = OldToNewChipID(pATI->ChipType);
         case NewChipID('L', 'M'):
         case NewChipID('L', 'N'):
-            pATI->ChipRevision =
-                GetBits(pATI->config_chip_id, CFG_CHIP_REVISION);
             pATI->Chip = ATI_CHIP_MOBILITY;
             pATI->BusType = ATI_BUS_AGP;
             pATI->LCDVBlendFIFOSize = 1024;
diff-tree f046a910ca117279fbabc6281b2e23439ec9ea4e (from 9cd175d9cd4ed710fccb303664c77519ecaf1e21)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Mar 23 22:19:17 2007 +0200

    Drop probing by driver name from "Device" section.
    
    atimisc is PCI-only now, so we only need to scan the PCI space.

diff --git a/src/ati.c b/src/ati.c
index fa7d9e8..4ef53e3 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -101,46 +101,33 @@ ATIProbe
     int       flags
 )
 {
-    pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo();
+    pciVideoPtr pVideo;
+    pciVideoPtr *xf86PciVideoInfo;
     Bool        DoMach64 = FALSE;
     Bool        DoRage128 = FALSE, DoRadeon = FALSE;
-    int         i;
     ATIChipType Chip;
 
-    if (!(flags & PROBE_DETECT))
+    xf86PciVideoInfo = xf86GetPciVideoInfo();
+
+    if (xf86PciVideoInfo == NULL)
+        return FALSE;
+
+    while ((pVideo = *xf86PciVideoInfo++) != NULL)
     {
-        if (xf86MatchDevice(ATI_NAME, NULL) > 0)
+        if ((pVideo->vendor != PCI_VENDOR_ATI) ||
+            (pVideo->chipType == PCI_CHIP_MACH32))
+            continue;
+
+        /* Check for Rage128's, Radeon's and later adapters */
+        Chip = ATIChipID(pVideo->chipType, pVideo->chipRev);
+        if (Chip <= ATI_CHIP_Mach64)
             DoMach64 = TRUE;
-        if (xf86MatchDevice(R128_NAME, NULL) > 0)
+        else if (Chip <= ATI_CHIP_Rage128)
             DoRage128 = TRUE;
-        if (xf86MatchDevice(RADEON_NAME, NULL) > 0)
+        else if (Chip <= ATI_CHIP_Radeon)
             DoRadeon = TRUE;
     }
 
-    if (xf86PciVideoInfo)
-    {
-        for (i = 0;  (pVideo = xf86PciVideoInfo[i++]);  )
-        {
-            if ((pVideo->vendor != PCI_VENDOR_ATI) ||
-                (pVideo->chipType == PCI_CHIP_MACH32))
-                continue;
-
-            /* Check for Rage128's, Radeon's and later adapters */
-            Chip = ATIChipID(pVideo->chipType, pVideo->chipRev);
-            if (Chip > ATI_CHIP_Mach64)
-            {
-                if (Chip <= ATI_CHIP_Rage128)
-                    DoRage128 = TRUE;
-                else if (Chip <= ATI_CHIP_Radeon)
-                    DoRadeon = TRUE;
-
-                continue;
-            }
-
-            DoMach64 = TRUE;
-        }
-    }
-
     /* Call Radeon driver probe */
     if (DoRadeon)
     {
diff-tree 9cd175d9cd4ed710fccb303664c77519ecaf1e21 (from d7a8cd0e476034796fc38e25a28cd28d05ea4a13)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Mar 23 22:12:48 2007 +0200

    Fold FillIn() back to Probe().

diff --git a/src/Makefile.am b/src/Makefile.am
index 197c486..1da3740 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -59,7 +59,7 @@ atimisc_drv_ladir = @moduledir@/drivers
 atimisc_drv_la_SOURCES = \
 	atibus.c atiprobe.c atividmem.c \
 	atiadjust.c atiaudio.c aticlock.c aticonfig.c aticonsole.c \
-	atidac.c atidecoder.c atidsp.c atifillin.c atii2c.c \
+	atidac.c atidecoder.c atidsp.c atii2c.c \
 	atilock.c atimach64.c atimach64accel.c atimach64cursor.c \
 	atimach64i2c.c atimach64io.c atimach64xv.c atimode.c atipreinit.c \
 	atiprint.c atirgb514.c atiscreen.c atituner.c atiutil.c ativalid.c \
@@ -123,7 +123,6 @@ EXTRA_DIST = \
 	atidri.h \
 	atidripriv.h \
 	atidsp.h \
-	atifillin.h \
 	ati.h \
 	atii2c.h \
 	atiload.h \
diff --git a/src/atifillin.c b/src/atifillin.c
deleted file mode 100644
index 41d4964..0000000
--- a/src/atifillin.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2004 Adam Jackson.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * atifillin.c: fill in a ScrnInfoPtr with the relevant information for
- * atimisc.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "atifillin.h"
-
-void ATIFillInScreenInfo(ScrnInfoPtr pScreenInfo)
-{
-    pScreenInfo->driverVersion = ATI_VERSION_CURRENT;
-    pScreenInfo->driverName    = ATI_DRIVER_NAME;
-    pScreenInfo->name          = ATI_NAME;
-    pScreenInfo->PreInit       = ATIPreInit;
-    pScreenInfo->ScreenInit    = ATIScreenInit;
-    pScreenInfo->SwitchMode    = ATISwitchMode;
-    pScreenInfo->AdjustFrame   = ATIAdjustFrame;
-    pScreenInfo->EnterVT       = ATIEnterVT;
-    pScreenInfo->LeaveVT       = ATILeaveVT;
-    pScreenInfo->FreeScreen    = ATIFreeScreen;
-    pScreenInfo->ValidMode     = ATIValidMode;
-}
diff --git a/src/atifillin.h b/src/atifillin.h
deleted file mode 100644
index 7d5e54d..0000000
--- a/src/atifillin.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2004 Adam Jackson.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * atifillin.h: header for atifillin.c.
- */
-
-#ifndef ATI_FILLIN_H
-#define ATI_FILLIN_H
-
-/* include headers corresponding to fields touched by ATIFillInScreenInfo() */
-
-#include "ativersion.h"
-#include "atipreinit.h"
-#include "atiscreen.h"
-#include "aticonsole.h"
-#include "atiadjust.h"
-#include "ativalid.h"
-
-extern void ATIFillInScreenInfo(ScrnInfoPtr);
-
-#endif
diff --git a/src/atimach64probe.c b/src/atimach64probe.c
index cff8bfb..043cad9 100644
--- a/src/atimach64probe.c
+++ b/src/atimach64probe.c
@@ -26,13 +26,18 @@
 
 #include "ati.h"
 #include "atichip.h"
-#include "atifillin.h"
-#include "atimodule.h"
 #include "atimach64io.h"
 #include "atimach64probe.h"
 #include "atioption.h"
 #include "ativersion.h"
 
+/* include headers corresponding to ScrnInfoPtr fields */
+#include "atipreinit.h"
+#include "atiscreen.h"
+#include "aticonsole.h"
+#include "atiadjust.h"
+#include "ativalid.h"
+
 static SymTabRec
 Mach64Chipsets[] = {
     {ATI_CHIP_88800GXC, "ATI 88800GX-C"},
@@ -135,16 +140,16 @@ Mach64Identify
 _X_EXPORT Bool
 Mach64Probe(DriverPtr pDriver, int flags)
 {
-    GDevPtr  *devSections;
-    int  *usedChips;
-    int  numDevSections;
-    int  numUsed;
-    Bool  ProbeSuccess = FALSE;
+    GDevPtr *devSections;
+    int     *usedChips;
+    int     numDevSections;
+    int     numUsed;
+    Bool    ProbeSuccess = FALSE;
 
-    if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0)
+    if (xf86GetPciVideoInfo() == NULL)
         return FALSE;
 
-    if (xf86GetPciVideoInfo() == NULL)
+    if ((numDevSections = xf86MatchDevice(ATI_DRIVER_NAME, &devSections)) <= 0)
         return FALSE;
 
     numUsed = xf86MatchPciInstances(ATI_DRIVER_NAME, PCI_VENDOR_ATI,
@@ -163,8 +168,6 @@ Mach64Probe(DriverPtr pDriver, int flags
 
         for (i = 0; i < numUsed; i++) {
             ScrnInfoPtr pScrn;
-            EntityInfoPtr pEnt;
-            pciVideoPtr pVideo;
 
             pScrn = xf86ConfigPciEntity(NULL, 0, usedChips[i], Mach64PciChipsets,
                                         0, 0, 0, 0, NULL);
@@ -172,16 +175,24 @@ Mach64Probe(DriverPtr pDriver, int flags
             if (!pScrn)
                 continue;
 
-            pEnt = xf86GetEntityInfo(usedChips[i]);
-            pVideo = xf86GetPciInfoForEntity(usedChips[i]);
-
-            ATIFillInScreenInfo(pScrn);
-
-            pScrn->Probe = Mach64Probe;
+            pScrn->driverVersion = ATI_VERSION_CURRENT;
+            pScrn->driverName    = ATI_DRIVER_NAME;
+            pScrn->name          = ATI_NAME;
+            pScrn->Probe         = Mach64Probe;
+            pScrn->PreInit       = ATIPreInit;
+            pScrn->ScreenInit    = ATIScreenInit;
+            pScrn->SwitchMode    = ATISwitchMode;
+            pScrn->AdjustFrame   = ATIAdjustFrame;
+            pScrn->EnterVT       = ATIEnterVT;
+            pScrn->LeaveVT       = ATILeaveVT;
+            pScrn->FreeScreen    = ATIFreeScreen;
+            pScrn->ValidMode     = ATIValidMode;
 
             ProbeSuccess = TRUE;
         }
     }
 
+    xfree(usedChips);
+
     return ProbeSuccess;
 }
diff --git a/src/atiprobe.c b/src/atiprobe.c
index 4a70f81..5f22032 100644
--- a/src/atiprobe.c
+++ b/src/atiprobe.c
@@ -31,7 +31,6 @@
 #include "atibus.h"
 #include "atichip.h"
 #include "atimach64io.h"
-#include "atimodule.h"
 #include "atiprobe.h"
 #include "ativersion.h"
 #include "atividmem.h"
diff --git a/src/r128_driver.c b/src/r128_driver.c
index 01276e0..b03bd42 100644
--- a/src/r128_driver.c
+++ b/src/r128_driver.c
@@ -4605,18 +4605,3 @@ static int r128_set_backlight_enable(Scr
 
 	return 0;
 }
-
-void R128FillInScreenInfo(ScrnInfoPtr pScrn)
-{
-	pScrn->driverVersion = R128_VERSION_CURRENT;
-	pScrn->driverName    = R128_DRIVER_NAME;
-	pScrn->name          = R128_NAME;
-	pScrn->PreInit       = R128PreInit;
-	pScrn->ScreenInit    = R128ScreenInit;
-	pScrn->SwitchMode    = R128SwitchMode;
-	pScrn->AdjustFrame   = R128AdjustFrame;
-	pScrn->EnterVT       = R128EnterVT;
-	pScrn->LeaveVT       = R128LeaveVT;
-	pScrn->FreeScreen    = R128FreeScreen;
-	pScrn->ValidMode     = R128ValidMode;
-}
diff --git a/src/r128_probe.c b/src/r128_probe.c
index 836f1d0..81ff663 100644
--- a/src/r128_probe.c
+++ b/src/r128_probe.c
@@ -41,7 +41,6 @@
  * Modified by Marc Aurele La France <tsi at xfree86.org> for ATI driver merge.
  */
 
-#include "atimodule.h"
 #include "ativersion.h"
 
 #include "r128_probe.h"
@@ -194,8 +193,18 @@ R128Probe(DriverPtr drv, int flags)
         if((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
              R128PciChipsets, 0, 0, 0, 0, 0)))
 	{
+	    pScrn->driverVersion = R128_VERSION_CURRENT;
+	    pScrn->driverName    = R128_DRIVER_NAME;
+	    pScrn->name          = R128_NAME;
 	    pScrn->Probe         = R128Probe;
-	    R128FillInScreenInfo(pScrn);
+	    pScrn->PreInit       = R128PreInit;
+	    pScrn->ScreenInit    = R128ScreenInit;
+	    pScrn->SwitchMode    = R128SwitchMode;
+	    pScrn->AdjustFrame   = R128AdjustFrame;
+	    pScrn->EnterVT       = R128EnterVT;
+	    pScrn->LeaveVT       = R128LeaveVT;
+	    pScrn->FreeScreen    = R128FreeScreen;
+	    pScrn->ValidMode     = R128ValidMode;
 
 	    foundScreen          = TRUE;
 
diff --git a/src/r128_probe.h b/src/r128_probe.h
index 9150296..180e52a 100644
--- a/src/r128_probe.h
+++ b/src/r128_probe.h
@@ -73,6 +73,4 @@ extern ModeStatus            R128ValidMo
 
 extern const OptionInfoRec * R128OptionsWeak(void);
 
-extern void                  R128FillInScreenInfo(ScrnInfoPtr);
-
 #endif /* _R128_PROBE_H_ */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0a79483..28580a5 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -7619,21 +7619,3 @@ static void RADEONSetDynamicClock(ScrnIn
 	    break;
     }
 }
-
-void RADEONFillInScreenInfo(ScrnInfoPtr pScrn)
-{
-    pScrn->driverVersion = RADEON_VERSION_CURRENT;
-    pScrn->driverName    = RADEON_DRIVER_NAME;
-    pScrn->name          = RADEON_NAME;
-    pScrn->PreInit       = RADEONPreInit;
-    pScrn->ScreenInit    = RADEONScreenInit;
-    pScrn->SwitchMode    = RADEONSwitchMode;
-#ifdef X_XF86MiscPassMessage
-    pScrn->HandleMessage = RADEONHandleMessage;
-#endif
-    pScrn->AdjustFrame   = RADEONAdjustFrame;
-    pScrn->EnterVT       = RADEONEnterVT;
-    pScrn->LeaveVT       = RADEONLeaveVT;
-    pScrn->FreeScreen    = RADEONFreeScreen;
-    pScrn->ValidMode     = RADEONValidMode;
-}
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index 4ff11ea..d7ff643 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -40,7 +40,6 @@
  * Modified by Marc Aurele La France <tsi at xfree86.org> for ATI driver merge.
  */
 
-#include "atimodule.h"
 #include "ativersion.h"
 
 #include "radeon_probe.h"
@@ -285,8 +284,22 @@ RADEONProbe(DriverPtr drv, int flags)
 	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
 					     RADEONPciChipsets, 0, 0, 0,
 					     0, 0))) {
+		pScrn->driverVersion = RADEON_VERSION_CURRENT;
+		pScrn->driverName    = RADEON_DRIVER_NAME;
+		pScrn->name          = RADEON_NAME;
 		pScrn->Probe         = RADEONProbe;
-		RADEONFillInScreenInfo(pScrn);
+		pScrn->PreInit       = RADEONPreInit;
+		pScrn->ScreenInit    = RADEONScreenInit;
+		pScrn->SwitchMode    = RADEONSwitchMode;
+#ifdef X_XF86MiscPassMessage
+		pScrn->HandleMessage = RADEONHandleMessage;
+#endif
+		pScrn->AdjustFrame   = RADEONAdjustFrame;
+		pScrn->EnterVT       = RADEONEnterVT;
+		pScrn->LeaveVT       = RADEONLeaveVT;
+		pScrn->FreeScreen    = RADEONFreeScreen;
+		pScrn->ValidMode     = RADEONValidMode;
+
 		foundScreen          = TRUE;
 	    }
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index b651e7d..f446516 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -172,6 +172,4 @@ extern ModeStatus           RADEONValidM
 
 extern const OptionInfoRec *RADEONOptionsWeak(void);
 
-extern void                 RADEONFillInScreenInfo(ScrnInfoPtr);
-
 #endif /* _RADEON_PROBE_H_ */
diff-tree d7a8cd0e476034796fc38e25a28cd28d05ea4a13 (from 58626d8b78f26f0d9c480033d3c3a12e541342b1)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Mar 23 22:10:03 2007 +0200

    Drop now unneeded _X_EXPORT's.

diff --git a/src/atiadjust.c b/src/atiadjust.c
index f01fee6..267186f 100644
--- a/src/atiadjust.c
+++ b/src/atiadjust.c
@@ -82,7 +82,7 @@ ATIAdjustPreInit
  * displayed location in video memory.  This is used to implement the virtual
  * window.
  */
-_X_EXPORT void
+void
 ATIAdjustFrame
 (
     int scrnIndex,
diff --git a/src/aticonfig.c b/src/aticonfig.c
index a4ceddf..1e119e0 100644
--- a/src/aticonfig.c
+++ b/src/aticonfig.c
@@ -234,7 +234,7 @@ static const OptionInfoRec ATIPublicOpti
 
 static const unsigned long ATIPublicOptionSize = SizeOf(ATIPublicOptions);
 
-_X_EXPORT const OptionInfoRec *
+const OptionInfoRec *
 ATIOptionsWeak(void) { return ATIPublicOptions; }
 
 /*
diff --git a/src/aticonsole.c b/src/aticonsole.c
index 6d0c662..bd5ec9c 100644
--- a/src/aticonsole.c
+++ b/src/aticonsole.c
@@ -628,7 +628,7 @@ ATILeaveGraphics
  *
  * This function switches to another graphics video state.
  */
-_X_EXPORT Bool
+Bool
 ATISwitchMode
 (
     int            iScreen,
@@ -681,7 +681,7 @@ ATISwitchMode
  *
  * This function sets the server's virtual console to a graphics video state.
  */
-_X_EXPORT Bool
+Bool
 ATIEnterVT
 (
     int iScreen,
@@ -751,7 +751,7 @@ ATIEnterVT
  * This function restores the server's virtual console to its state on server
  * entry.
  */
-_X_EXPORT void
+void
 ATILeaveVT
 (
     int iScreen,
@@ -780,7 +780,7 @@ ATILeaveVT
  *
  * This function frees all driver data related to a screen.
  */
-_X_EXPORT void
+void
 ATIFreeScreen
 (
     int iScreen,
diff --git a/src/atifillin.c b/src/atifillin.c
index dcbcb3c..41d4964 100644
--- a/src/atifillin.c
+++ b/src/atifillin.c
@@ -31,7 +31,7 @@
 
 #include "atifillin.h"
 
-_X_EXPORT void ATIFillInScreenInfo(ScrnInfoPtr pScreenInfo)
+void ATIFillInScreenInfo(ScrnInfoPtr pScreenInfo)
 {
     pScreenInfo->driverVersion = ATI_VERSION_CURRENT;
     pScreenInfo->driverName    = ATI_DRIVER_NAME;
diff --git a/src/atipreinit.c b/src/atipreinit.c
index 8f80824..7f0c4b2 100644
--- a/src/atipreinit.c
+++ b/src/atipreinit.c
@@ -146,7 +146,7 @@ ATIPrintNoiseIfRequested
  * This function is only called once per screen at the start of the first
  * server generation.
  */
-_X_EXPORT Bool
+Bool
 ATIPreInit
 (
     ScrnInfoPtr pScreenInfo,
diff --git a/src/atiscreen.c b/src/atiscreen.c
index 58b0bda..bc57934 100644
--- a/src/atiscreen.c
+++ b/src/atiscreen.c
@@ -349,7 +349,7 @@ ATIMach64SetupMemXAA
  *
  * This function is called by DIX to initialise the screen.
  */
-_X_EXPORT Bool
+Bool
 ATIScreenInit
 (
     int       iScreen,
diff --git a/src/ativalid.c b/src/ativalid.c
index 8a92e82..51cf5ae 100644
--- a/src/ativalid.c
+++ b/src/ativalid.c
@@ -35,7 +35,7 @@
  *
  * This checks for hardware-related limits on mode timings.
  */
-_X_EXPORT ModeStatus
+ModeStatus
 ATIValidMode
 (
     int iScreen,
diff --git a/src/r128_driver.c b/src/r128_driver.c
index 81c9015..01276e0 100644
--- a/src/r128_driver.c
+++ b/src/r128_driver.c
@@ -182,7 +182,7 @@ static const OptionInfoRec R128Options[]
   { -1,                  NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
-_X_EXPORT const OptionInfoRec *R128OptionsWeak(void) { return R128Options; }
+const OptionInfoRec *R128OptionsWeak(void) { return R128Options; }
 
 R128RAMRec R128RAM[] = {        /* Memory Specifications
 				   From RAGE 128 Software Development
@@ -2044,7 +2044,7 @@ R128ProbeDDC(ScrnInfoPtr pScrn, int indx
 }
 
 /* R128PreInit is called once at server startup. */
-_X_EXPORT Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
+Bool R128PreInit(ScrnInfoPtr pScrn, int flags)
 {
     R128InfoPtr      info;
     xf86Int10InfoPtr pInt10 = NULL;
@@ -2334,7 +2334,7 @@ R128BlockHandler(int i, pointer blockDat
 }
 
 /* Called at the start of each server generation. */
-_X_EXPORT Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
+Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen,
                               int argc, char **argv)
 {
     ScrnInfoPtr pScrn  = xf86Screens[pScreen->myNum];
@@ -4238,7 +4238,7 @@ static Bool R128SaveScreen(ScreenPtr pSc
  * The workaround is to switch the mode, then switch to another VT, then
  * switch back. --AGD
  */
-_X_EXPORT Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+Bool R128SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 {
     ScrnInfoPtr   pScrn       = xf86Screens[scrnIndex];
     R128InfoPtr info        = R128PTR(pScrn);
@@ -4251,7 +4251,7 @@ _X_EXPORT Bool R128SwitchMode(int scrnIn
 }
 
 /* Used to disallow modes that are not supported by the hardware. */
-_X_EXPORT ModeStatus R128ValidMode(int scrnIndex, DisplayModePtr mode,
+ModeStatus R128ValidMode(int scrnIndex, DisplayModePtr mode,
                                    Bool verbose, int flags)
 {
     ScrnInfoPtr   pScrn = xf86Screens[scrnIndex];
@@ -4327,7 +4327,7 @@ _X_EXPORT ModeStatus R128ValidMode(int s
 
 /* Adjust viewport into virtual desktop such that (0,0) in viewport space
    is (x,y) in virtual space. */
-_X_EXPORT void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
+void R128AdjustFrame(int scrnIndex, int x, int y, int flags)
 {
     ScrnInfoPtr   pScrn     = xf86Screens[scrnIndex];
     R128InfoPtr   info      = R128PTR(pScrn);
@@ -4363,7 +4363,7 @@ _X_EXPORT void R128AdjustFrame(int scrnI
 
 /* Called when VT switching back to the X server.  Reinitialize the video
    mode. */
-_X_EXPORT Bool R128EnterVT(int scrnIndex, int flags)
+Bool R128EnterVT(int scrnIndex, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     R128InfoPtr info  = R128PTR(pScrn);
@@ -4396,7 +4396,7 @@ _X_EXPORT Bool R128EnterVT(int scrnIndex
 
 /* Called when VT switching away from the X server.  Restore the original
    text mode. */
-_X_EXPORT void R128LeaveVT(int scrnIndex, int flags)
+void R128LeaveVT(int scrnIndex, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     R128InfoPtr info  = R128PTR(pScrn);
@@ -4466,7 +4466,7 @@ static Bool R128CloseScreen(int scrnInde
     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
 }
 
-_X_EXPORT void R128FreeScreen(int scrnIndex, int flags)
+void R128FreeScreen(int scrnIndex, int flags)
 {
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     R128InfoPtr   info      = R128PTR(pScrn);
@@ -4606,7 +4606,7 @@ static int r128_set_backlight_enable(Scr
 	return 0;
 }
 
-_X_EXPORT void R128FillInScreenInfo(ScrnInfoPtr pScrn)
+void R128FillInScreenInfo(ScrnInfoPtr pScrn)
 {
 	pScrn->driverVersion = R128_VERSION_CURRENT;
 	pScrn->driverName    = R128_DRIVER_NAME;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 9ed0d6c..0a79483 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -203,7 +203,7 @@ static const OptionInfoRec RADEONOptions
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
-_X_EXPORT const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
+const OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions; }
 
 #ifdef WITH_VGAHW
 static const char *vgahwSymbols[] = {
@@ -2971,7 +2971,7 @@ RADEONProbeDDC(ScrnInfoPtr pScrn, int in
     }
 }
 
-_X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
+Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 {
     RADEONInfoPtr     info;
     xf86Int10InfoPtr  pInt10 = NULL;
@@ -3759,7 +3759,7 @@ Bool RADEONSetupMemXAA(int scrnIndex, Sc
 #endif /* USE_XAA */
 
 /* Called at the start of each server generation. */
-_X_EXPORT Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
+Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen,
                                 int argc, char **argv)
 {
     ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
@@ -6516,7 +6516,7 @@ RADEONResetDPI(ScrnInfoPtr pScrn, Bool f
     }
 }
 
-_X_EXPORT Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+Bool RADEONSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 {
     ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
     RADEONInfoPtr  info        = RADEONPTR(pScrn);
@@ -6610,7 +6610,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrn
 }
 
 #ifdef X_XF86MiscPassMessage
-_X_EXPORT Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
+Bool RADEONHandleMessage(int scrnIndex, const char* msgtype,
                                    const char* msgval, char** retmsg)
 {
     ErrorF("RADEONHandleMessage(%d, \"%s\", \"%s\", retmsg)\n", scrnIndex,
@@ -6621,7 +6621,7 @@ _X_EXPORT Bool RADEONHandleMessage(int s
 #endif
 
 /* Used to disallow modes that are not supported by the hardware */
-_X_EXPORT ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode,
+ModeStatus RADEONValidMode(int scrnIndex, DisplayModePtr mode,
                                      Bool verbose, int flag)
 {
     /* There are problems with double scan mode at high clocks
@@ -6754,7 +6754,7 @@ void RADEONDoAdjustFrame(ScrnInfoPtr pSc
 
 }
 
-_X_EXPORT void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
+void RADEONAdjustFrame(int scrnIndex, int x, int y, int flags)
 {
     ScrnInfoPtr    pScrn      = xf86Screens[scrnIndex];
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -6782,7 +6782,7 @@ _X_EXPORT void RADEONAdjustFrame(int scr
 /* Called when VT switching back to the X server.  Reinitialize the
  * video mode.
  */
-_X_EXPORT Bool RADEONEnterVT(int scrnIndex, int flags)
+Bool RADEONEnterVT(int scrnIndex, int flags)
 {
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
@@ -6853,7 +6853,7 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 /* Called when VT switching away from the X server.  Restore the
  * original text mode.
  */
-_X_EXPORT void RADEONLeaveVT(int scrnIndex, int flags)
+void RADEONLeaveVT(int scrnIndex, int flags)
 {
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
@@ -6981,7 +6981,7 @@ static Bool RADEONCloseScreen(int scrnIn
     return (*pScreen->CloseScreen)(scrnIndex, pScreen);
 }
 
-_X_EXPORT void RADEONFreeScreen(int scrnIndex, int flags)
+void RADEONFreeScreen(int scrnIndex, int flags)
 {
     ScrnInfoPtr  pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
@@ -7620,7 +7620,7 @@ static void RADEONSetDynamicClock(ScrnIn
     }
 }
 
-_X_EXPORT void RADEONFillInScreenInfo(ScrnInfoPtr pScrn)
+void RADEONFillInScreenInfo(ScrnInfoPtr pScrn)
 {
     pScrn->driverVersion = RADEON_VERSION_CURRENT;
     pScrn->driverName    = RADEON_DRIVER_NAME;
diff-tree 58626d8b78f26f0d9c480033d3c3a12e541342b1 (from 166c760a86165330175023e07c4b2bd6891633c5)
Author: George Sapountzis <gsap7 at yahoo.gr>
Date:   Fri Mar 23 21:30:19 2007 +0200

    Move {atimach64,r128,radeon}_probe.c from ati to subdrivers.
    
    Subdrivers are now loaded from the wrapper Probe function rather than at screen
    creation time.
    
    The wrapper Identify callback only prints chip families now, chip lists are
    printed when a subdriver is loaded. This also avoids duplication of subdriver
    Identify callbacks.
    
    Unknown radeons should still get a list of known radeon and then probe fails...
    
    Probe for atimisc last to avoid needless loading in most cases (r128, radeon).

diff --git a/src/Makefile.am b/src/Makefile.am
index 5c1bee6..197c486 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,8 +51,7 @@ ati_drv_la_LTLIBRARIES = ati_drv.la
 ati_drv_la_LDFLAGS = -module -avoid-version
 ati_drv_ladir = @moduledir@/drivers
 ati_drv_la_SOURCES = \
-	ati.c atichip.c atimodule.c atimach64probe.c \
-	radeon_probe.c r128_probe.c
+	ati.c atichip.c atimodule.c
 
 atimisc_drv_la_LTLIBRARIES = atimisc_drv.la
 atimisc_drv_la_LDFLAGS = -module -avoid-version
@@ -64,15 +63,15 @@ atimisc_drv_la_SOURCES = \
 	atilock.c atimach64.c atimach64accel.c atimach64cursor.c \
 	atimach64i2c.c atimach64io.c atimach64xv.c atimode.c atipreinit.c \
 	atiprint.c atirgb514.c atiscreen.c atituner.c atiutil.c ativalid.c \
-	atiload.c atimisc.c $(ATIMISC_DRI_SRCS) $(ATIMISC_DGA_SOURCES) \
-	$(ATIMISC_CPIO_SOURCES) $(ATIMISC_EXA_SOURCES)
+	atiload.c atimisc.c atimach64probe.c $(ATIMISC_CPIO_SOURCES) \
+	$(ATIMISC_DGA_SOURCES) $(ATIMISC_DRI_SRCS) $(ATIMISC_EXA_SOURCES)
 
 r128_drv_la_LTLIBRARIES = r128_drv.la
 r128_drv_la_LDFLAGS = -module -avoid-version
 r128_drv_ladir = @moduledir@/drivers
 r128_drv_la_SOURCES = \
 	r128_accel.c r128_cursor.c r128_dga.c r128_driver.c \
-	r128_video.c r128_misc.c $(R128_DRI_SRCS)
+	r128_video.c r128_misc.c r128_probe.c $(R128_DRI_SRCS)
 
 radeon_drv_la_LTLIBRARIES = radeon_drv.la
 radeon_drv_la_LDFLAGS = -module -avoid-version
@@ -80,7 +79,8 @@ radeon_drv_ladir = @moduledir@/drivers
 radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
-	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	radeon_vip.c radeon_misc.c radeon_probe.c radeon_display.c \
+	radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
diff --git a/src/ati.c b/src/ati.c
index e7a5aee..fa7d9e8 100644
--- a/src/ati.c
+++ b/src/ati.c
@@ -59,6 +59,7 @@
 
 #include "ati.h"
 #include "atichip.h"
+#include "atimodule.h"
 #include "ativersion.h"
 #include "atimach64probe.h"
 
@@ -78,10 +79,13 @@ ATIIdentify
     int flags
 )
 {
+    /*
+     * Only print chip families here, chip lists are printed when a subdriver
+     * is loaded.
+     */
     xf86Msg(X_INFO, "%s: %s\n", ATI_NAME,
-            "ATI driver (version " ATI_VERSION_NAME ") for chipset: mach64");
-    R128Identify(flags);
-    RADEONIdentify(flags);
+            "ATI driver wrapper (version " ATI_VERSION_NAME ") for chipsets: "
+            "mach64, rage128, radeon");
 }
 
 /*
@@ -98,7 +102,6 @@ ATIProbe
 )
 {
     pciVideoPtr pVideo, *xf86PciVideoInfo = xf86GetPciVideoInfo();
-    Bool        ProbeSuccess = FALSE;
     Bool        DoMach64 = FALSE;
     Bool        DoRage128 = FALSE, DoRadeon = FALSE;
     int         i;
@@ -138,19 +141,73 @@ ATIProbe
         }
     }
 
-    /* Call Mach64 driver probe */
-    if (DoMach64 && Mach64Probe(pDriver, flags))
-        ProbeSuccess = TRUE;
+    /* Call Radeon driver probe */
+    if (DoRadeon)
+    {
+        pointer radeon = xf86LoadDrvSubModule(pDriver, "radeon");
+
+        if (!radeon)
+        {
+            xf86Msg(X_ERROR,
+                ATI_NAME ":  Failed to load \"radeon\" module.\n");
+            return FALSE;
+        }
+
+        xf86LoaderReqSymLists(RADEONSymbols, NULL);
+
+        RADEONIdentify(flags);
+
+        if (RADEONProbe(pDriver, flags))
+            return TRUE;
+
+        xf86UnloadSubModule(radeon);
+    }
 
     /* Call Rage 128 driver probe */
-    if (DoRage128 && R128Probe(pDriver, flags))
-        ProbeSuccess = TRUE;
+    if (DoRage128)
+    {
+        pointer r128 = xf86LoadDrvSubModule(pDriver, "r128");
 
-    /* Call Radeon driver probe */
-    if (DoRadeon && RADEONProbe(pDriver, flags))
-        ProbeSuccess = TRUE;
+        if (!r128)
+        {
+            xf86Msg(X_ERROR,
+                ATI_NAME ":  Failed to load \"r128\" module.\n");
+            return FALSE;
+        }
+
+        xf86LoaderReqSymLists(R128Symbols, NULL);
 
-    return ProbeSuccess;
+        R128Identify(flags);
+
+        if (R128Probe(pDriver, flags))
+            return TRUE;
+
+        xf86UnloadSubModule(r128);
+    }
+
+    /* Call Mach64 driver probe */
+    if (DoMach64)
+    {
+        pointer atimisc = xf86LoadDrvSubModule(pDriver, "atimisc");
+
+        if (!atimisc)
+        {
+            xf86Msg(X_ERROR,
+                ATI_NAME ":  Failed to load \"atimisc\" module.\n");
+            return FALSE;
+        }
+
+        xf86LoaderReqSymLists(ATISymbols, NULL);
+
+        Mach64Identify(flags);
+
+        if (Mach64Probe(pDriver, flags))
+            return TRUE;
+
+        xf86UnloadSubModule(atimisc);
+    }
+
+    return FALSE;
 }
 
 /*
@@ -158,22 +215,27 @@ ATIProbe
  *
  * Return recognised options that are intended for public consumption.
  */
-const OptionInfoRec *
+static const OptionInfoRec *
 ATIAvailableOptions
 (
     int ChipId,
     int BusId
 )
 {
-    const OptionInfoRec *pOptions;
+    CARD16      ChipType = ChipId & 0xffff;
+    ATIChipType Chip;
 
-    if ((pOptions = R128AvailableOptions(ChipId, BusId)))
-        return pOptions;
+    /* Probe should have loaded the appropriate subdriver by this point */
 
-    if ((pOptions = RADEONAvailableOptions(ChipId, BusId)))
-        return pOptions;
+    Chip = ATIChipID(ChipType, 0x0); /* chip revision is don't care */
+    if (Chip <= ATI_CHIP_Mach64)
+        return Mach64AvailableOptions(ChipId, BusId);
+    else if (Chip <= ATI_CHIP_Rage128)
+        return R128AvailableOptions(ChipId, BusId);
+    else if (Chip <= ATI_CHIP_Radeon)
+        return RADEONAvailableOptions(ChipId, BusId);
 
-    return Mach64AvailableOptions(ChipId, BusId);
+    return NULL;
 }
 
 /* The root of all evil... */
diff --git a/src/atimach64probe.c b/src/atimach64probe.c
index 47340a5..cff8bfb 100644
--- a/src/atimach64probe.c
+++ b/src/atimach64probe.c
@@ -101,7 +101,7 @@ Mach64PciChipsets[] = {
     {-1, -1, RES_UNDEFINED}
 };
 
-const OptionInfoRec *
+_X_EXPORT const OptionInfoRec *
 Mach64AvailableOptions(int chipid, int busid)
 {
     /*
@@ -112,12 +112,27 @@ Mach64AvailableOptions(int chipid, int b
 }
 
 /*
+ * Mach64Identify --
+ *
+ * Print the driver's list of chipset names.
+ */
+_X_EXPORT void
+Mach64Identify
+(
+    int flags
+)
+{
+    xf86Msg(X_INFO, "%s: %s\n", ATI_NAME,
+            "Driver for ATI Mach64 chipsets");
+}
+
+/*
  * Mach64Probe --
  *
  * This function is called once, at the start of the first server generation to
  * do a minimal probe for supported hardware.
  */
-Bool
+_X_EXPORT Bool
 Mach64Probe(DriverPtr pDriver, int flags)
 {
     GDevPtr  *devSections;
@@ -160,20 +175,6 @@ Mach64Probe(DriverPtr pDriver, int flags
             pEnt = xf86GetEntityInfo(usedChips[i]);
             pVideo = xf86GetPciInfoForEntity(usedChips[i]);
 
-#ifdef XFree86LOADER
-
-            if (!xf86LoadSubModule(pScrn, "atimisc"))
-            {
-                xf86Msg(X_ERROR,
-                    ATI_NAME ":  Failed to load \"atimisc\" module.\n");
-                xf86DeleteScreen(pScrn->scrnIndex, 0);
-                continue;
-            }
-
-            xf86LoaderReqSymLists(ATISymbols, NULL);
-
-#endif
-
             ATIFillInScreenInfo(pScrn);
 
             pScrn->Probe = Mach64Probe;
diff --git a/src/atimach64probe.h b/src/atimach64probe.h
index 4e474ca..fa9e713 100644
--- a/src/atimach64probe.h
+++ b/src/atimach64probe.h
@@ -26,6 +26,7 @@
 #include "xf86str.h"
 
 extern const OptionInfoRec * Mach64AvailableOptions(int, int);
+extern void                  Mach64Identify(int);
 extern Bool                  Mach64Probe(DriverPtr, int);
 
 #endif /* ___ATIMACH64PROBE_H___ */
diff --git a/src/atimodule.c b/src/atimodule.c
index 05456e7..6aa9a2e 100644
--- a/src/atimodule.c
+++ b/src/atimodule.c
@@ -34,47 +34,25 @@
 
 const char *ATISymbols[] =
 {
-    "ATIPreInit",
-    "ATIScreenInit",
-    "ATISwitchMode",
-    "ATIAdjustFrame",
-    "ATIEnterVT",
-    "ATILeaveVT",
-    "ATIFreeScreen",
-    "ATIValidMode",
-    "ATIOptionsWeak",
-    "ATIFillInScreenInfo",
+    "Mach64Identify",
+    "Mach64Probe",
+    "Mach64AvailableOptions",
     NULL
 };
 
 const char *R128Symbols[] =
 {
-    "R128PreInit",
-    "R128ScreenInit",
-    "R128SwitchMode",
-    "R128AdjustFrame",
-    "R128EnterVT",
-    "R128LeaveVT",
-    "R128FreeScreen",
-    "R128ValidMode",
-    "R128OptionsWeak",
-    "R128FillInScreenInfo",
+    "R128Identify",
+    "R128Probe",
+    "R128AvailableOptions",
     NULL
 };
 
 const char *RADEONSymbols[] =
 {
-    "RADEONPreInit",
-    "RADEONScreenInit",
-    "RADEONSwitchMode",
-    "RADEONAdjustFrame",
-    "RADEONEnterVT",
-    "RADEONLeaveVT",
-    "RADEONFreeScreen",
-    "RADEONValidMode",
-    "RADEONOptionsWeak",
-    "RADEONHandleMessage",
-    "RADEONFillInScreenInfo",
+    "RADEONIdentify",
+    "RADEONProbe",
+    "RADEONAvailableOptions",
     NULL
 };
 
diff --git a/src/r128_probe.c b/src/r128_probe.c
index 96e7897..836f1d0 100644
--- a/src/r128_probe.c
+++ b/src/r128_probe.c
@@ -107,7 +107,7 @@ PciChipsets R128PciChipsets[] = {
 int gR128EntityIndex = -1;
 
 /* Return the options for supported chipset 'n'; NULL otherwise */
-const OptionInfoRec *
+_X_EXPORT const OptionInfoRec *
 R128AvailableOptions(int chipid, int busid)
 {
     int i;
@@ -126,7 +126,7 @@ R128AvailableOptions(int chipid, int bus
 }
 
 /* Return the string name for supported chipset 'n'; NULL otherwise. */
-void
+_X_EXPORT void
 R128Identify(int flags)
 {
     xf86PrintChipsets(R128_NAME,
@@ -135,7 +135,7 @@ R128Identify(int flags)
 }
 
 /* Return TRUE if chipset is present; FALSE otherwise. */
-Bool
+_X_EXPORT Bool
 R128Probe(DriverPtr drv, int flags)
 {
     int           numUsed;
@@ -194,20 +194,6 @@ R128Probe(DriverPtr drv, int flags)
         if((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
              R128PciChipsets, 0, 0, 0, 0, 0)))
 	{
-
-#ifdef XFree86LOADER
-
-	    if (!xf86LoadSubModule(pScrn, "r128")) {
-		xf86Msg(X_ERROR,
-		    R128_NAME ":  Failed to load \"r128\" module.\n");
-		xf86DeleteScreen(pScrn->scrnIndex, 0);
-		continue;
-	    }
-
-	    xf86LoaderReqSymLists(R128Symbols, NULL);
-
-#endif
-
 	    pScrn->Probe         = R128Probe;
 	    R128FillInScreenInfo(pScrn);
 
diff --git a/src/radeon_probe.c b/src/radeon_probe.c
index 98b35aa..4ff11ea 100644
--- a/src/radeon_probe.c
+++ b/src/radeon_probe.c
@@ -200,7 +200,7 @@ PciChipsets RADEONPciChipsets[] = {
 int gRADEONEntityIndex = -1;
 
 /* Return the options for supported chipset 'n'; NULL otherwise */
-const OptionInfoRec *
+_X_EXPORT const OptionInfoRec *
 RADEONAvailableOptions(int chipid, int busid)
 {
     int  i;
@@ -219,7 +219,7 @@ RADEONAvailableOptions(int chipid, int b
 }
 
 /* Return the string name for supported chipset 'n'; NULL otherwise. */
-void
+_X_EXPORT void
 RADEONIdentify(int flags)
 {
     xf86PrintChipsets(RADEON_NAME,
@@ -228,7 +228,7 @@ RADEONIdentify(int flags)
 }
 
 /* Return TRUE if chipset is present; FALSE otherwise. */
-Bool
+_X_EXPORT Bool
 RADEONProbe(DriverPtr drv, int flags)
 {
     int      numUsed;
@@ -285,17 +285,6 @@ RADEONProbe(DriverPtr drv, int flags)
 	    if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i],
 					     RADEONPciChipsets, 0, 0, 0,
 					     0, 0))) {
-#ifdef XFree86LOADER
-		if (!xf86LoadSubModule(pScrn, "radeon")) {
-		    xf86Msg(X_ERROR, RADEON_NAME
-			    ":  Failed to load \"radeon\" module.\n");
-		    xf86DeleteScreen(pScrn->scrnIndex, 0);
-		    continue;
-		}
-
-		xf86LoaderReqSymLists(RADEONSymbols, NULL);
-#endif
-
 		pScrn->Probe         = RADEONProbe;
 		RADEONFillInScreenInfo(pScrn);
 		foundScreen          = TRUE;
diff-tree 166c760a86165330175023e07c4b2bd6891633c5 (from 1bdd376dbd57de8925244f0808f974d6d8cff39d)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 20 09:16:02 2007 +0100

    Fix advertised minimum minor version of the DRI module.
    
    We don't automatically require bumped minor versions.

diff --git a/src/atidri.c b/src/atidri.c
index 83cb25f..d4fbead 100644
--- a/src/atidri.c
+++ b/src/atidri.c
@@ -1197,13 +1197,13 @@ Bool ATIDRIScreenInit( ScreenPtr pScreen
 
    /* Check the DRI version */
    DRIQueryVersion( &major, &minor, &patch );
-   if ( major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION ) {
+   if ( major != DRIINFO_MAJOR_VERSION || minor < 0 ) {
       xf86DrvMsg( pScreen->myNum, X_ERROR,
 		  "[dri] ATIDRIScreenInit failed because of a version mismatch.\n"
 		  "[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
 		  "[dri] Disabling the DRI.\n",
 		  major, minor, patch,
-                  DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION );
+                  DRIINFO_MAJOR_VERSION, 0 );
       return FALSE;
    }
 
diff --git a/src/r128_dri.c b/src/r128_dri.c
index 21a13c1..fc91421 100644
--- a/src/r128_dri.c
+++ b/src/r128_dri.c
@@ -988,13 +988,13 @@ Bool R128DRIScreenInit(ScreenPtr pScreen
 
     /* Check the DRI version */
     DRIQueryVersion(&major, &minor, &patch);
-    if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+    if (major != DRIINFO_MAJOR_VERSION || minor < 0) {
 	xf86DrvMsg(pScreen->myNum, X_ERROR,
 		"[dri] R128DRIScreenInit failed because of a version mismatch.\n"
 		"[dri] libdri version is %d.%d.%d but version %d.%d.x is needed.\n"
 		"[dri] Disabling the DRI.\n",
 		major, minor, patch,
-                DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+                DRIINFO_MAJOR_VERSION, 0);
 	return FALSE;
     }
 
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 7ebf958..b09a8cf 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -1244,7 +1244,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pSc
 
     /* Check the DRI version */
     DRIQueryVersion(&major, &minor, &patch);
-    if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION) {
+    if (major != DRIINFO_MAJOR_VERSION || minor < 0) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "[dri] RADEONDRIGetVersion failed because of a version "
 		   "mismatch.\n"
@@ -1252,7 +1252,7 @@ Bool RADEONDRIGetVersion(ScrnInfoPtr pSc
 		   "needed.\n"
 		   "[dri] Disabling DRI.\n",
 		   major, minor, patch,
-                   DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
+                   DRIINFO_MAJOR_VERSION, 0);
 	return FALSE;
     }
 
diff-tree 1bdd376dbd57de8925244f0808f974d6d8cff39d (from 3cfa3a5c8daf03aaad6fc30d275709f6eb717d29)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 20 09:14:39 2007 +0100

    radeon: Only sync to hardware when really necessary with EXA.
    
    In particular, don't sync again after accelerated DownloadFromScreen, which
    syncs implicitly. This avoids calling into the kernel when it's not necessary,
    which can be relevant in some situations.

diff --git a/src/radeon.h b/src/radeon.h
index 8d0115e..ce2fe19 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -497,6 +497,8 @@ typedef struct {
 
 #ifdef USE_EXA
     ExaDriverPtr      exa;
+    int               exaSyncMarker;
+    int               exaMarkerSynced;
     int               engineMode;
 #define EXA_ENGINEMODE_UNKNOWN 0
 #define EXA_ENGINEMODE_2D      1
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 0d847d1..c356de7 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -59,14 +59,30 @@
 
 #include "exa.h"
 
+static int
+FUNC_NAME(RADEONMarkSync)(ScreenPtr pScreen)
+{
+    RINFO_FROM_SCREEN(pScreen);
+
+    TRACE;
+
+    return ++info->exaSyncMarker;
+}
+
 static void
 FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
 {
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+
     TRACE;
 
-    FUNC_NAME(RADEONWaitForIdle)(xf86Screens[pScreen->myNum]);
+    if (info->exaMarkerSynced != marker) {
+	FUNC_NAME(RADEONWaitForIdle)(pScrn);
+	info->exaMarkerSynced = marker;
+    }
 
-    RADEONPTR(xf86Screens[pScreen->myNum])->engineMode = EXA_ENGINEMODE_UNKNOWN;
+    RADEONPTR(pScrn)->engineMode = EXA_ENGINEMODE_UNKNOWN;
 }
 
 static Bool
@@ -444,6 +460,8 @@ FUNC_NAME(RADEONDownloadFromScreen)(Pixm
 	drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,
 			    &indirect, sizeof(drmRadeonIndirect));
 
+	info->exaMarkerSynced = info->exaSyncMarker;
+
 	return TRUE;
     }
 #endif
@@ -504,6 +522,7 @@ Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr
     info->exa->Copy = FUNC_NAME(RADEONCopy);
     info->exa->DoneCopy = FUNC_NAME(RADEONDoneCopy);
 
+    info->exa->MarkSync = FUNC_NAME(RADEONMarkSync);
     info->exa->WaitMarker = FUNC_NAME(RADEONSync);
     info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen);
     info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);
diff-tree 3cfa3a5c8daf03aaad6fc30d275709f6eb717d29 (from e174d8df8c801fad95e5f79cff69187c200bee6e)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 20 09:13:24 2007 +0100

    radeon: Unify code to release the CP.

diff --git a/src/radeon.h b/src/radeon.h
index 5bb005b..8d0115e 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -964,6 +964,16 @@ do {									\
     info->CPStarted = TRUE;                                             \
 } while (0)
 
+#define RADEONCP_RELEASE(pScrn, info)					\
+do {									\
+    if (info->CPInUse) {						\
+	RADEON_PURGE_CACHE();						\
+	RADEON_WAIT_UNTIL_IDLE();					\
+	RADEONCPReleaseIndirect(pScrn);					\
+	info->CPInUse = FALSE;						\
+    }									\
+} while (0)
+
 #define RADEONCP_STOP(pScrn, info)					\
 do {									\
     int _ret;								\
@@ -1128,14 +1138,6 @@ do {									\
     ADVANCE_RING();							\
 } while (0)
 
-#define RADEON_FLUSH_CACHE()						\
-do {									\
-    BEGIN_RING(2);							\
-    OUT_RING(CP_PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0));		\
-    OUT_RING(RADEON_RB3D_DC_FLUSH);					\
-    ADVANCE_RING();							\
-} while (0)
-
 #define RADEON_PURGE_CACHE()						\
 do {									\
     BEGIN_RING(2);							\
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index ee6192e..7ebf958 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -409,13 +409,7 @@ static void RADEONLeaveServer(ScreenPtr 
     /* The CP is always running, but if we've generated any CP commands
      * we must flush them to the kernel module now.
      */
-    if (info->CPInUse) {
-	RADEON_FLUSH_CACHE();
-	RADEON_WAIT_UNTIL_IDLE();
-	RADEONCPReleaseIndirect(pScrn);
-
-	info->CPInUse = FALSE;
-    }
+    RADEONCP_RELEASE(pScrn, info);
 
 #ifdef USE_EXA
     info->engineMode = EXA_ENGINEMODE_UNKNOWN;
@@ -1703,13 +1697,7 @@ void RADEONDRIStop(ScreenPtr pScreen)
 	/* If we've generated any CP commands, we must flush them to the
 	 * kernel module now.
 	 */
-	if (info->CPInUse) {
-	    RADEON_FLUSH_CACHE();
-	    RADEON_WAIT_UNTIL_IDLE();
-	    RADEONCPReleaseIndirect(pScrn);
-
-	    info->CPInUse = FALSE;
-	}
+	RADEONCP_RELEASE(pScrn, info);
 	RADEONCP_STOP(pScrn, info);
     }
     info->directRenderingInited = FALSE;
diff-tree e174d8df8c801fad95e5f79cff69187c200bee6e (from 113fb4b61e709a9b54fc2ef73efce06011e771c1)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 20 09:12:51 2007 +0100

    radeon: Minor BlockHandler cleanups.
    
    Don't flush indirect buffer in BlockHandler; it's done in LeaveServer.
    
    Also set the EXA engine mode to unknown only at the end.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 4842542..9ed0d6c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3404,14 +3404,6 @@ static void RADEONBlockHandler(int i, po
     ScrnInfoPtr    pScrn   = xf86Screens[i];
     RADEONInfoPtr  info    = RADEONPTR(pScrn);
 
-#ifdef XF86DRI
-    if (info->directRenderingInited) {
-	FLUSH_RING();
-    }
-#endif
-#ifdef USE_EXA
-    info->engineMode = EXA_ENGINEMODE_UNKNOWN;
-#endif
     pScreen->BlockHandler = info->BlockHandler;
     (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
     pScreen->BlockHandler = RADEONBlockHandler;
@@ -3423,6 +3415,10 @@ static void RADEONBlockHandler(int i, po
     if(info->RenderCallback)
 	(*info->RenderCallback)(pScrn);
 #endif
+
+#ifdef USE_EXA
+    info->engineMode = EXA_ENGINEMODE_UNKNOWN;
+#endif
 }
 
 
diff-tree 113fb4b61e709a9b54fc2ef73efce06011e771c1 (from 4651d00b183cb498879d605c4b93cd3a0c63cb33)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 20 09:12:09 2007 +0100

    radeon: Disable CP line acceleration on RV280s.
    
    There have been several reports of stability issues with things like the
    xscreensaver hack hypercube.

diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c
index 784b074..212131f 100644
--- a/src/radeon_accelfuncs.c
+++ b/src/radeon_accelfuncs.c
@@ -1204,8 +1204,14 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pSc
        hardware accel two point lines */
     miSetZeroLineBias(pScreen, (OCTANT5 | OCTANT6 | OCTANT7 | OCTANT8));
 
-    a->SubsequentSolidTwoPointLine
-	= FUNC_NAME(RADEONSubsequentSolidTwoPointLine);
+#ifdef ACCEL_CP
+    /* RV280s lock up with this using the CP for reasons to be determined.
+     * See https://bugs.freedesktop.org/show_bug.cgi?id=5986 .
+     */
+    if (info->ChipFamily != CHIP_FAMILY_RV280)
+#endif
+	a->SubsequentSolidTwoPointLine
+	    = FUNC_NAME(RADEONSubsequentSolidTwoPointLine);
 
     /* Disabled on RV200 and newer because it does not pass XTest */
     if (info->ChipFamily < CHIP_FAMILY_RV200) {
diff-tree 4651d00b183cb498879d605c4b93cd3a0c63cb33 (from 2d2fb54ba370c1df9ef5102e83c17a7ff5c55403)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Tue Mar 20 09:10:19 2007 +0100

    radeon: Make sure 3D clients will re-upload textures to video RAM after LeaveVT.
    
    Walk the SAREA texList and bump the age of every active object, so their owners
    will consider them kicked out when they grab the HW lock next time.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ca0b201..4842542 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6874,6 +6874,19 @@ _X_EXPORT void RADEONLeaveVT(int scrnInd
             /* we need to backup the PCIE GART TABLE from fb memory */
             memcpy(info->pciGartBackup, (info->FB + info->pciGartOffset), info->pciGartSize);
         }
+
+	/* Make sure 3D clients will re-upload textures to video RAM */
+	if (info->textureSize) {
+	    RADEONSAREAPrivPtr pSAREAPriv =
+		(RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScrn->pScreen);
+	    drmTextureRegionPtr list = pSAREAPriv->texList[0];
+	    int age = ++pSAREAPriv->texAge[0], i = 0;
+
+	    do {
+		list[i].age = age;
+		i = list[i].next;
+	    } while (i != 0);
+	}
     }
 #endif
 
diff-tree 2a1cd107a593630001799d6cd9e72c64222553b2 (from 703c6fc0142ffc600285c13fe6dafecf988c0a1d)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Tue Mar 6 14:35:50 2007 -0800

    Add prepare/commit hooks to output and crtc func table

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 685431f..f6f2410 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2206,6 +2206,11 @@ radeon_crtc_mode_fixup(xf86CrtcPtr crtc,
 }
 
 static void
+radeon_crtc_mode_prepare(xf86CrtcPtr crtc)
+{
+}
+
+static void
 radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
 		     DisplayModePtr adjusted_mode, int x, int y)
 {
@@ -2241,6 +2246,11 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     RADEONUnblank(pScrn);
 }
 
+static void
+radeon_crtc_mode_commit(xf86CrtcPtr crtc)
+{
+}
+
 void radeon_crtc_load_lut(xf86CrtcPtr crtc)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
@@ -2307,7 +2317,9 @@ static const xf86CrtcFuncsRec radeon_crt
     .save = NULL, /* XXX */
     .restore = NULL, /* XXX */
     .mode_fixup = radeon_crtc_mode_fixup,
+    .prepare = radeon_crtc_mode_prepare,
     .mode_set = radeon_crtc_mode_set,
+    .commit = radeon_crtc_mode_commit,
     .gamma_set = radeon_crtc_gamma_set,
     .lock = radeon_crtc_lock,
     .unlock = radeon_crtc_unlock,
@@ -2356,6 +2368,11 @@ radeon_mode_fixup(xf86OutputPtr output, 
 }
 
 static void
+radeon_mode_prepare(xf86OutputPtr output)
+{
+}
+
+static void
 radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		  DisplayModePtr adjusted_mode)
 {
@@ -2366,6 +2383,11 @@ radeon_mode_set(xf86OutputPtr output, Di
     //    RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], );
 }
 
+static void
+radeon_mode_commit(xf86OutputPtr output)
+{
+}
+
 static xf86OutputStatus
 radeon_detect(xf86OutputPtr output)
 {
@@ -2416,7 +2438,9 @@ static const xf86OutputFuncsRec radeon_o
     .restore = radeon_restore,
     .mode_valid = radeon_mode_valid,
     .mode_fixup = radeon_mode_fixup,
+    .prepare = radeon_mode_prepare,
     .mode_set = radeon_mode_set,
+    .commit = radeon_mode_commit,
     .detect = radeon_detect,
     .get_modes = radeon_get_modes,
     .destroy = radeon_destroy
diff-tree 703c6fc0142ffc600285c13fe6dafecf988c0a1d (from 58ee31d015cf8bec0edca62a46faec0b3505be8c)
Author: Jesse Barnes <jbarnes at jbarnes-mobile.amr.corp.intel.com>
Date:   Tue Mar 6 10:12:42 2007 -0800

    Update for new CRTC resize hooks.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 8de9eef..a580583 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2542,6 +2542,18 @@ RADEONProbeDDC(ScrnInfoPtr pScrn, int in
     }
 }
 
+static Bool
+RADEONCRTCResize(ScrnInfoPtr scrn, int width, int height)
+{
+    scrn->virtualX = width;
+    scrn->virtualY = height;
+    return TRUE;
+}
+
+static const xf86CrtcConfigFuncsRec RADEONCRTCResizeFuncs = {
+    RADEONCRTCResize
+};
+
 _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 {
     xf86CrtcConfigPtr   xf86_config;
@@ -2651,7 +2663,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     pScrn->monitor     = pScrn->confScreen->monitor;
 
    /* Allocate an xf86CrtcConfig */
-   xf86CrtcConfigInit (pScrn);
+    xf86CrtcConfigInit (pScrn, &RADEONCRTCResizeFuncs);
    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
 
@@ -2779,7 +2791,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
        goto fail;
 
 
-   if (!xf86InitialConfiguration (pScrn))
+    if (!xf86InitialConfiguration (pScrn, FALSE))
    {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
       goto fail;
diff-tree 58ee31d015cf8bec0edca62a46faec0b3505be8c (from 3cfe94d5438961b869766dacbcd13fde8b770ca2)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Feb 25 23:29:09 2007 +1100

    fix typo

diff --git a/src/radeon_display.c b/src/radeon_display.c
index e9890d9..685431f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1137,7 +1137,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	RADEONGetTMDSInfo(pScrn);
 
 	if (i == 0)
-		RADEONGetHardCodedEDIDFromBios(pScrn);
+		RADEONGetHardCodedEDIDFromBIOS(pScrn);
 
 	RADEONUpdatePanelSize(pScrn);
 
diff-tree 3cfe94d5438961b869766dacbcd13fde8b770ca2 (from parents)
Merge: 31c018ca4a18ce426b29006f103f56eee7f985fa 3b43788c45f51ad2d3e8e64383c412f4ddd97207
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Feb 25 23:27:19 2007 +1100

    Merge branch 'radeon-randrv12-v4'
    
    Conflicts:
    
    	src/radeon_display.c
    	src/radeon_driver.c

diff --cc src/radeon_display.c
index d661c17,4995893..e9890d9
@@@ -1136,17 -1107,57 +1107,56 @@@
              pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I;
              pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
  	}
+     }
+ 
+     for (i = 0; i < 2; i++) {
+       RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
+ 
+       int DDCReg = 0;
+       char *names[] = { "DDC1", "DDC2" };
+ 
+       RADEONSetOutputType(pScrn, radeon_output);
+       switch(radeon_output->DDCType) {
+       case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+       case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
+       case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
+       case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+       default: break;
+       }
+       
+       if (DDCReg) {
+ 	radeon_output->DDCReg = DDCReg;
+ 	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
+       }
+ 
+       if (radeon_output->type == OUTPUT_LVDS) {
+ 	RADEONGetLVDSInfo(pScrn);
+       }
+ 
+       if (radeon_output->type == OUTPUT_DVI) {
+ 	RADEONGetTMDSInfo(pScrn);
+ 
+ 	if (i == 0)
+ 		RADEONGetHardCodedEDIDFromBios(pScrn);
+ 
+ 	RADEONUpdatePanelSize(pScrn);
+ 
+       }
+ 
  
      }
+ 
+     
  }
  
- static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, int connector)
+ static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
  {
      RADEONInfoPtr info       = RADEONPTR(pScrn);
 -    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
      unsigned char *RADEONMMIO = info->MMIO;
+     RADEONOutputPrivatePtr radeon_output = output->driver_private;
  
      if (info->IsMobility) {
-       switch(connector) {
+       switch(radeon_output->num) {
        case 0:
  	/* non-DDC laptop panel connected on primary */
  	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
@@@ -1167,18 -1178,19 +1177,18 @@@
  /* 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, int connector)
+ void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
  {
 -    RADEONInfoPtr info       = RADEONPTR(pScrn);
      RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-     RADEONConnector *pPort = pRADEONEnt->PortInfo[connector];
+     RADEONOutputPrivatePtr radeon_output = output->driver_private;
      
-     if (pPort->MonType == MT_UNKNOWN) {
-       if ((pPort->MonType = RADEONDisplayDDCConnected(pScrn,
- 						     pPort->DDCType,
- 						     pPort)));
-       else if((pPort->MonType = RADEONPortCheckNonDDC(pScrn, connector)));
+     if (radeon_output->MonType == MT_UNKNOWN) {
+       if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn,
+ 						     radeon_output->DDCType,
+ 						     output)));
+       else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
        else
- 	pPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pPort->DACType));
+ 	radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
      }
  }
  
@@@ -2153,9 -2066,11 +2063,10 @@@
      }
  }
  
- static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+ static void RADEONDPMSSetOn(xf86OutputPtr output)
  {
+   ScrnInfoPtr pScrn = output->scrn;
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
 -  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;
    RADEONMonitorType MonType;
    RADEONTmdsType TmdsType;
@@@ -2190,9 -2108,11 +2104,10 @@@
    }
  }
  
- static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+ static void RADEONDPMSSetOff(xf86OutputPtr output)
  {
+   ScrnInfoPtr pScrn = output->scrn;
    RADEONInfoPtr  info       = RADEONPTR(pScrn);
 -  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;
    RADEONMonitorType MonType;
    RADEONTmdsType TmdsType;
@@@ -2375,6 -2472,60 +2466,59 @@@
      int i;
  
      if (pRADEONEnt->PortInfo[0])
+ 	return TRUE;
+ 
+     /* for now always allocate max connectors */
+     for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
+ 
+ 	pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+ 	if (!pRADEONEnt->PortInfo[i])
+ 	    return FALSE;
+     }
+     return TRUE;
+ }
+ 
+ void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
+ {
+     RADEONInfoPtr info = RADEONPTR (pScrn);
+     RADEONOutputType output;
+     if (info->IsAtomBios) {
+ 	switch(radeon_output->ConnectorType) {
+ 	case 0: output = OUTPUT_NONE; break;
+ 	case 1: output = OUTPUT_VGA; break;
+ 	case 2:
+ 	case 3:
+ 	case 4: output = OUTPUT_DVI; break;
+ 	case 5: output = OUTPUT_STV; break;
+ 	case 6: output = OUTPUT_CTV; break;
+ 	case 7:
+ 	case 8: output = OUTPUT_LVDS; break;
+ 	case 9:
+ 	default:
+ 	    output = OUTPUT_NONE; break;
+ 	}
+     }
+     else {
+ 	switch(radeon_output->ConnectorType) {
+ 	case 0: output = OUTPUT_NONE; break;
+ 	case 1: output = OUTPUT_LVDS; break;
+ 	case 2: output = OUTPUT_VGA; break;
+ 	case 3:
+ 	case 4: output = OUTPUT_DVI; break;
+ 	case 5: output = OUTPUT_STV; break;
+ 	case 6: output = OUTPUT_CTV; break;
+ 	default: output = OUTPUT_NONE; break;
+ 	}
+     }
+     radeon_output->type = output;
+ }
+ 
+ Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
+ {
+     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 -    int num_connectors;
+     int i;
+ 
+     if (pRADEONEnt->pOutput[0])
          return TRUE;
      
      /* for now always allocate max connectors */
diff --cc src/radeon_video.c
index 390df89,ed4cbfb..d080982
@@@ -2448,14 -2440,15 +2447,14 @@@
              break;
          default:
  	    break;
 -        }
 -
 -    /* Unlike older Mach64 chips, RADEON has only two ECP settings: 0 for PIXCLK < 175Mhz, and 1 (divide by 2)
 -       for higher clocks, sure makes life nicer
 +    }
  
 -       Here we need to find ecp_div again, as the user may have switched resolutions */
 +    /* Here we need to find ecp_div again, as the user may have switched resolutions
 +       but only call OUTPLL/INPLL if needed since it may cause a 10ms delay due to
 +       workarounds for chip erratas */
  
      /* Figure out which head we are on for dot clock */
-     if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
+     if (info->OverlayOnCRTC2 || info->IsSecondary)
          dot_clock = info->ModeReg.dot_clock_freq_2;
      else
          dot_clock = info->ModeReg.dot_clock_freq;
diff-tree 3b43788c45f51ad2d3e8e64383c412f4ddd97207 (from 24c6fa7cfac5602ba9e6e2f331bcac52fab258e5)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Feb 25 23:17:31 2007 +1100

    cleanup radeon code against master server

diff --git a/src/Makefile.am b/src/Makefile.am
index 4d0d1a9..078f318 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,7 +82,7 @@ radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
-	radeon_randr.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
diff --git a/src/radeon.h b/src/radeon.h
index 36372c8..e4b8d3f 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -880,6 +880,8 @@ extern int RADEONValidateDDCModes(ScrnIn
 extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 
+DisplayModePtr
+RADEONProbeOutputModes(xf86OutputPtr output);
 extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
 			DisplayModePtr crtc2, int crtc_mask,
 			RADEONSavePtr save, RADEONMonitorType montype);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index d83c68b..4995893 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -47,7 +47,7 @@
 #include "radeon_probe.h"
 #include "radeon_version.h"
 
-
+void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output);
 void radeon_crtc_load_lut(xf86CrtcPtr crtc);
 extern int getRADEONEntityIndex(void);
 
@@ -2238,6 +2238,12 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
       RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg, montype);
       break;
     }
+
+    RADEONBlank(pScrn);
+    RADEONRestoreMode(pScrn, &info->ModeReg);
+    if (info->DispPriority)
+        RADEONInitDispBandwidth(pScrn);
+    RADEONUnblank(pScrn);
 }
 
 void radeon_crtc_load_lut(xf86CrtcPtr crtc)
@@ -2282,19 +2288,23 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
 static Bool
 radeon_crtc_lock(xf86CrtcPtr crtc)
 {
-  ScrnInfoPtr		pScrn = crtc->scrn;
-  RADEONInfoPtr  info = RADEONPTR(pScrn);
-  Bool           CPStarted   = info->CPStarted;
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    Bool           CPStarted   = info->CPStarted;
 
+    if (info->accelOn)
+        RADEON_SYNC(info, pScrn);
     return FALSE;
 }
 
 static void
 radeon_crtc_unlock(xf86CrtcPtr crtc)
 {
-  ScrnInfoPtr		pScrn = crtc->scrn;
-  RADEONInfoPtr  info = RADEONPTR(pScrn);
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
 
+    if (info->accelOn)
+        RADEON_SYNC(info, pScrn);
 }
 
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
@@ -2553,135 +2563,6 @@ xf86OutputPtr RADEONGetCrtcConnector(Scr
 }
 
 
-void
-RADEONCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    RADEONCrtcPrivatePtr	radeon_crtc = crtc->driver_private;
-    int crtc_id = radeon_crtc->crtc_id;
-    unsigned long Start;
-    
-    RADEONDoAdjustFrame(pScrn, x, y, crtc_id);
-
-    crtc->x = x;
-    crtc->y = y;
-}
-
-Bool
-RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-		  int x, int y)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);  
-    DisplayModePtr adjusted_mode;
-    Bool		didLock = FALSE;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    int i , ret;
-    DisplayModeRec	saved_mode;
-    int 		saved_x, saved_y;
-    Rotation 		saved_rotation;
-    /* XXX: mode */
-
-    adjusted_mode = xf86DuplicateMode(mode);
-    
-    crtc->enabled = xf86CrtcInUse (crtc);
-
-    if (!crtc->enabled) {
-      return TRUE;
-    }
-
-    didLock = crtc->funcs->lock (crtc);
-
-    saved_mode = crtc->mode;
-    saved_x = crtc->x;
-    saved_y = crtc->y;
-    saved_rotation = crtc->rotation;
-
-    /* Update crtc values up front so the driver can rely on them for mode
-     * setting.
-     */
-    crtc->mode = *mode;
-    crtc->x = x;
-    crtc->y = y;
-    crtc->rotation = rotation;
-
-    /* Pass our mode to the outputs and the CRTC to give them a chance to
-     * adjust it according to limitations or output properties, and also
-     * a chance to reject the mode entirely.
-     */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
-	    ret = FALSE;
-	    goto done;
-	}
-    }
-
-    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
-	ret = FALSE;
-	goto done;
-    }
-
-    if (!xf86CrtcRotate (crtc, mode, rotation)) {
-	goto done;
-    }
-
-#if 0
-    /* Disable the outputs and CRTCs before setting the mode. */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	/* Disable the output as the first thing we do. */
-	output->funcs->dpms(output, DPMSModeOff);
-    }
-
-    crtc->funcs->dpms(crtc, DPMSModeOff);
-#endif
-
-    /* Set up the DPLL and any output state that needs to adjust or depend
-     * on the DPLL.
-     */
-    crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->mode_set(output, mode, adjusted_mode);
-    }
-
-#if 0
-    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
-    crtc->funcs->dpms(crtc, DPMSModeOn);
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->dpms(output, DPMSModeOn);
-    }
-#endif
-    
-    /* XXX free adjustedmode */
-    ret = TRUE;
-
- done:
-    if (!ret) {
-	crtc->x = saved_x;
-	crtc->y = saved_y;
-	crtc->rotation = saved_rotation;
-	crtc->mode = saved_mode;
-    }
-
-    if (didLock)
-	crtc->funcs->unlock (crtc);
-
-    return ret;
-}
-
 /**
  * In the current world order, there are lists of modes per output, which may
  * or may not include the mode that was asked to be set by XFree86's mode
@@ -2784,33 +2665,6 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr cr
 }
 
 void
-RADEONDisableUnusedFunctions(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int o, c;
-
-    for (o = 0; o < xf86_config->num_output; o++)
-    {
-	xf86OutputPtr output = xf86_config->output[o];
-
-	if (output->crtc == NULL) {
-		radeon_dpms(output, DPMSModeOff);
-	}
-    }
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-    {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-	if (!crtc->enabled) {
-		memset(&crtc->mode, 0, sizeof(crtc->mode));
-		radeon_crtc_dpms(crtc, DPMSModeOff);
-	}
-    }
-
-
-}
-
-void
 RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
 {
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0e2ec00..3f4ee4c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3634,15 +3634,10 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 		crtc->desiredY = 0;
 	    }
 
-	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
+	    if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
 		return FALSE;
 
 	}
-	RADEONBlank(pScrn);
-	RADEONRestoreMode(pScrn, &info->ModeReg);
-	RADEONUnblank(pScrn);
-
-	//if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
     }
 
     RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
@@ -6326,17 +6321,11 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 		crtc->desiredY = 0;
 	    }
 
-	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
+	    if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
 				    crtc->desiredX, crtc->desiredY))
 		return FALSE;
 
 	}
-	RADEONBlank(pScrn);
-	RADEONRestoreMode(pScrn, &info->ModeReg);
-	RADEONUnblank(pScrn);
-
-	if (info->DispPriority)
- 	    RADEONInitDispBandwidth(pScrn);
     }
 #if 0
       if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
deleted file mode 100644
index 679831f..0000000
--- a/src/radeon_randr.c
+++ /dev/null
@@ -1,965 +0,0 @@
-/*
- * Copyright 2006 Dave Airlie
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <stdio.h>
-
-/* X and server generic header files */
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "fbdevhw.h"
-#include "vgaHW.h"
-
-#include "randrstr.h"
-
-/* Driver data structures */
-#include "radeon.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
-#include "radeon_probe.h"
-#include "radeon_version.h"
-
-typedef struct _xf86RandR12Info {
-    int				    virtualX;
-    int				    virtualY;
-    int				    mmWidth;
-    int				    mmHeight;
-    int				    maxX;
-    int				    maxY;
-    Rotation			    rotation; /* current mode */
-    Rotation                        supported_rotations; /* driver supported */
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-#ifdef RANDR_12_INTERFACE
-static Bool xf86RandR12Init12 (ScreenPtr pScreen);
-static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
-#endif
-
- 
-static int	    xf86RandR12Index;
-static int	    xf86RandR12Generation;
-
-#define XF86RANDRINFO(p) \
-	((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
-
-static int
-xf86RandR12ModeRefresh (DisplayModePtr mode)
-{
-    if (mode->VRefresh)
-	return (int) (mode->VRefresh + 0.5);
-    else
-	return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-static Bool
-xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
-    RRScreenSizePtr	    pSize;
-    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
-    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
-    DisplayModePtr	    mode;
-    int			    refresh0 = 60;
-    int			    maxX = 0, maxY = 0;
-
-    *rotations = randrp->supported_rotations;
-
-    if (randrp->virtualX == -1 || randrp->virtualY == -1)
-    {
-	randrp->virtualX = scrp->virtualX;
-	randrp->virtualY = scrp->virtualY;
-    }
-
-    /* Re-probe the outputs for new monitors or modes */
-    xf86ProbeOutputModes (scrp, 0, 0);
-    xf86SetScrnInfoModes (scrp);
-
-    for (mode = scrp->modes; ; mode = mode->next)
-    {
-	int refresh = xf86RandR12ModeRefresh (mode);
-	if (randrp->maxX == 0 || randrp->maxY == 0)
-	{
-		if (maxX < mode->HDisplay)
-			maxX = mode->HDisplay;
-		if (maxY < mode->VDisplay)
-			maxY = mode->VDisplay;
-	}
-	if (mode == scrp->modes)
-	    refresh0 = refresh;
-	pSize = RRRegisterSize (pScreen,
-				mode->HDisplay, mode->VDisplay,
-				randrp->mmWidth, randrp->mmHeight);
-	if (!pSize)
-	    return FALSE;
-	RRRegisterRate (pScreen, pSize, refresh);
-
-	if (xf86ModesEqual(mode, scrp->currentMode) &&
-	    mode->HDisplay == scrp->virtualX &&
-	    mode->VDisplay == scrp->virtualY)
-	{
-	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
-	}
-	if (mode->next == scrp->modes)
-	    break;
-    }
-
-    if (randrp->maxX == 0 || randrp->maxY == 0)
-    {
-	randrp->maxX = maxX;
-	randrp->maxY = maxY;
-    }
-
-    if (scrp->currentMode->HDisplay != randrp->virtualX ||
-	scrp->currentMode->VDisplay != randrp->virtualY)
-    {
-	pSize = RRRegisterSize (pScreen,
-				randrp->virtualX, randrp->virtualY,
-				randrp->mmWidth,
-				randrp->mmHeight);
-	if (!pSize)
-	    return FALSE;
-	RRRegisterRate (pScreen, pSize, refresh0);
-	if (scrp->virtualX == randrp->virtualX &&
-	    scrp->virtualY == randrp->virtualY)
-	{
-	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
-	}
-    }
-
-    return TRUE;
-}
-
-static Bool
-xf86RandR12SetMode (ScreenPtr	    pScreen,
-		  DisplayModePtr    mode,
-		  Bool		    useVirtual,
-		  int		    mmWidth,
-		  int		    mmHeight)
-{
-    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-    int			oldWidth = pScreen->width;
-    int			oldHeight = pScreen->height;
-    int			oldmmWidth = pScreen->mmWidth;
-    int			oldmmHeight = pScreen->mmHeight;
-    WindowPtr		pRoot = WindowTable[pScreen->myNum];
-    DisplayModePtr      currentMode = NULL;
-    Bool 		ret = TRUE;
-    PixmapPtr 		pspix = NULL;
-
-    if (pRoot)
-	(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-    if (useVirtual)
-    {
-	scrp->virtualX = randrp->virtualX;
-	scrp->virtualY = randrp->virtualY;
-    }
-    else
-    {
-	scrp->virtualX = mode->HDisplay;
-	scrp->virtualY = mode->VDisplay;
-    }
-
-    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
-    {
-	/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
-	pScreen->width = scrp->virtualY;
-	pScreen->height = scrp->virtualX;
-	pScreen->mmWidth = mmHeight;
-	pScreen->mmHeight = mmWidth;
-    }
-    else
-    {
-	pScreen->width = scrp->virtualX;
-	pScreen->height = scrp->virtualY;
-	pScreen->mmWidth = mmWidth;
-	pScreen->mmHeight = mmHeight;
-    }
-    if (scrp->currentMode == mode) {
-        /* Save current mode */
-        currentMode = scrp->currentMode;
-        /* Reset, just so we ensure the drivers SwitchMode is called */
-        scrp->currentMode = NULL;
-    }
-    /*
-     * We know that if the driver failed to SwitchMode to the rotated
-     * version, then it should revert back to it's prior mode.
-     */
-    if (!xf86SwitchMode (pScreen, mode))
-    {
-        ret = FALSE;
-	scrp->virtualX = pScreen->width = oldWidth;
-	scrp->virtualY = pScreen->height = oldHeight;
-	pScreen->mmWidth = oldmmWidth;
-	pScreen->mmHeight = oldmmHeight;
-        scrp->currentMode = currentMode;
-    }
-    /*
-     * Get the new Screen pixmap ptr as SwitchMode might have called
-     * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
-     * Unfortunately.
-     */
-    pspix = (*pScreen->GetScreenPixmap) (pScreen);
-    if (pspix->devPrivate.ptr)
-       scrp->pixmapPrivate = pspix->devPrivate;
-
-    /*
-     * Make sure the layout is correct
-     */
-    xf86ReconfigureLayout();
-
-    /*
-     * Make sure the whole screen is visible
-     */
-    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
-    xf86SetViewport (pScreen, 0, 0);
-    if (pRoot)
-	(*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-    return ret;
-}
-
-Bool
-xf86RandR12SetConfig (ScreenPtr		pScreen,
-		    Rotation		rotation,
-		    int			rate,
-		    RRScreenSizePtr	pSize)
-{
-    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-    DisplayModePtr	mode;
-    int			px, py;
-    Bool		useVirtual = FALSE;
-    int			maxX = 0, maxY = 0;
-    Rotation		oldRotation = randrp->rotation;
-
-    randrp->rotation = rotation;
-
-    if (randrp->virtualX == -1 || randrp->virtualY == -1)
-    {
-	randrp->virtualX = scrp->virtualX;
-	randrp->virtualY = scrp->virtualY;
-    }
-
-    miPointerPosition (&px, &py);
-    for (mode = scrp->modes; ; mode = mode->next)
-    {
-	if (randrp->maxX == 0 || randrp->maxY == 0)
-	{
-		if (maxX < mode->HDisplay)
-			maxX = mode->HDisplay;
-		if (maxY < mode->VDisplay)
-			maxY = mode->VDisplay;
-	}
-	if (mode->HDisplay == pSize->width &&
-	    mode->VDisplay == pSize->height &&
-	    (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
-	    break;
-	if (mode->next == scrp->modes)
-	{
-	    if (pSize->width == randrp->virtualX &&
-		pSize->height == randrp->virtualY)
-	    {
-		mode = scrp->modes;
-		useVirtual = TRUE;
-		break;
-	    }
-    	    if (randrp->maxX == 0 || randrp->maxY == 0)
-    	    {
-		randrp->maxX = maxX;
-		randrp->maxY = maxY;
-    	    }
-	    return FALSE;
-	}
-    }
-
-    if (randrp->maxX == 0 || randrp->maxY == 0)
-    {
-	randrp->maxX = maxX;
-	randrp->maxY = maxY;
-    }
-
-    if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
-			   pSize->mmHeight)) {
-        randrp->rotation = oldRotation;
-	return FALSE;
-    }
-
-    /*
-     * Move the cursor back where it belongs; SwitchMode repositions it
-     */
-    if (pScreen == miPointerCurrentScreen ())
-    {
-        px = (px >= pScreen->width ? (pScreen->width - 1) : px);
-        py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
-	xf86SetViewport(pScreen, px, py);
-
-	(*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
-    }
-
-    return TRUE;
-}
-
-static Bool
-xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
-			CARD16		width,
-			CARD16		height,
-			CARD32		mmWidth,
-			CARD32		mmHeight)
-{
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-    ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
-    WindowPtr		pRoot = WindowTable[pScreen->myNum];
-    Bool 		ret = TRUE;
-
-    if (randrp->virtualX == -1 || randrp->virtualY == -1)
-    {
-	randrp->virtualX = pScrn->virtualX;
-	randrp->virtualY = pScrn->virtualY;
-    }
-    if (pRoot)
-	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-    pScrn->virtualX = width;
-    pScrn->virtualY = height;
-
-    pScreen->width = pScrn->virtualX;
-    pScreen->height = pScrn->virtualY;
-    pScreen->mmWidth = mmWidth;
-    pScreen->mmHeight = mmHeight;
-
-    xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
-    xf86SetViewport (pScreen, 0, 0);
-    if (pRoot)
-	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-#if RANDR_12_INTERFACE
-    if (WindowTable[pScreen->myNum])
-	RRScreenSizeNotify (pScreen);
-#endif
-    return ret;
-}
-
-Rotation
-xf86RandR12GetRotation(ScreenPtr pScreen)
-{
-    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
-
-    return randrp->rotation;
-}
-
-Bool
-xf86RandR12CreateScreenResources (ScreenPtr pScreen)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-    int			c;
-    int			width, height;
-    int			mmWidth, mmHeight;
-#ifdef PANORAMIX
-    /* XXX disable RandR when using Xinerama */
-    if (!noPanoramiXExtension)
-	return TRUE;
-#endif
-
-    /*
-     * Compute size of screen
-     */
-    width = 0; height = 0;
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr crtc = config->crtc[c];
-	int	    crtc_width = crtc->x + crtc->mode.HDisplay;
-	int	    crtc_height = crtc->y + crtc->mode.VDisplay;
-	
-	if (crtc->enabled && crtc_width > width)
-	    width = crtc_width;
-	if (crtc->enabled && crtc_height > height)
-	    height = crtc_height;
-    }
-    
-    if (width && height)
-    {
-	/*
-	 * Compute physical size of screen
-	 */
-	if (monitorResolution) 
-	{
-	    mmWidth = width * 25.4 / monitorResolution;
-	    mmHeight = height * 25.4 / monitorResolution;
-	}
-	else
-	{
-	    mmWidth = pScreen->mmWidth;
-	    mmHeight = pScreen->mmHeight;
-	}
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Setting screen physical size to %d x %d\n",
-		   mmWidth, mmHeight);
-	xf86RandR12ScreenSetSize (pScreen,
-				  width,
-				  height,
-				  mmWidth,
-				  mmHeight);
-    }
-
-    if (randrp->virtualX == -1 || randrp->virtualY == -1)
-    {
-	randrp->virtualX = pScrn->virtualX;
-	randrp->virtualY = pScrn->virtualY;
-    }
-#if RANDR_12_INTERFACE
-    if (xf86RandR12CreateScreenResources12 (pScreen))
-	return TRUE;
-#endif
-    return TRUE;
-}
-
-
-Bool
-xf86RandR12Init (ScreenPtr pScreen)
-{
-    rrScrPrivPtr	rp;
-    XF86RandRInfoPtr	randrp;
-
-#ifdef PANORAMIX
-    /* XXX disable RandR when using Xinerama */
-    if (!noPanoramiXExtension)
-	return TRUE;
-#endif
-    if (xf86RandR12Generation != serverGeneration)
-    {
-	xf86RandR12Index = AllocateScreenPrivateIndex();
-	xf86RandR12Generation = serverGeneration;
-    }
-
-    randrp = xalloc (sizeof (XF86RandRInfoRec));
-    if (!randrp)
-	return FALSE;
-
-    if (!RRScreenInit(pScreen))
-    {
-	xfree (randrp);
-	return FALSE;
-    }
-    rp = rrGetScrPriv(pScreen);
-    rp->rrGetInfo = xf86RandR12GetInfo;
-    rp->rrSetConfig = xf86RandR12SetConfig;
-
-    randrp->virtualX = -1;
-    randrp->virtualY = -1;
-    randrp->mmWidth = pScreen->mmWidth;
-    randrp->mmHeight = pScreen->mmHeight;
-
-    randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
-    randrp->supported_rotations = RR_Rotate_0;
-
-    randrp->maxX = randrp->maxY = 0;
-
-    pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
-
-#if RANDR_12_INTERFACE
-    if (!xf86RandR12Init12 (pScreen))
-	return FALSE;
-#endif
-    return TRUE;
-}
-
-void
-xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
-{
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-
-    randrp->supported_rotations = rotations;
-}
-
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
-    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
-    if (xf86RandR12Generation != serverGeneration ||
-	XF86RANDRINFO(pScreen)->virtualX == -1)
-    {
-	*x = pScrn->virtualX;
-	*y = pScrn->virtualY;
-    } else {
-	XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
-	*x = randrp->virtualX;
-	*y = randrp->virtualY;
-    }
-}
-
-#if RANDR_12_INTERFACE
-static Bool
-xf86RandR12CrtcNotify (RRCrtcPtr	randr_crtc)
-{
-    ScreenPtr		pScreen = randr_crtc->pScreen;
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RRModePtr		randr_mode = NULL;
-    int			x;
-    int			y;
-    Rotation		rotation;
-    int			numOutputs;
-    RROutputPtr		*randr_outputs;
-    RROutputPtr		randr_output;
-    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
-    xf86OutputPtr	output;
-    int			i, j;
-    DisplayModePtr	curMode = &crtc->mode;
-    Bool		ret;
-
-    randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
-    if (!randr_outputs)
-	return FALSE;
-    x = crtc->x;
-    y = crtc->y;
-    rotation = RR_Rotate_0;
-    numOutputs = 0;
-    randr_mode = NULL;
-    for (i = 0; i < config->num_output; i++)
-    {
-	output = config->output[i];
-	if (output->crtc == crtc)
-	{
-	    randr_output = output->randr_output;
-	    randr_outputs[numOutputs++] = randr_output;
-	    /*
-	     * We make copies of modes, so pointer equality 
-	     * isn't sufficient
-	     */
-	    for (j = 0; j < randr_output->numModes; j++)
-	    {
-		DisplayModePtr	outMode = randr_output->modes[j]->devPrivate;
-		if (xf86ModesEqual(curMode, outMode))
-		{
-		    randr_mode = randr_output->modes[j];
-		    break;
-		}
-	    }
-	}
-    }
-    ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
-			rotation, numOutputs, randr_outputs);
-    DEALLOCATE_LOCAL(randr_outputs);
-    return ret;
-}
-
-static Bool
-xf86RandR12CrtcSet (ScreenPtr	pScreen,
-		  RRCrtcPtr	randr_crtc,
-		  RRModePtr	randr_mode,
-		  int		x,
-		  int		y,
-		  Rotation	rotation,
-		  int		num_randr_outputs,
-		  RROutputPtr	*randr_outputs)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
-    DisplayModePtr	mode = randr_mode ? randr_mode->devPrivate : NULL;
-    Bool		changed = FALSE;
-    int			o, ro;
-    xf86CrtcPtr		*save_crtcs;
-    Bool save_enabled = crtc->enabled;
-    int ret;
-    
-    save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
-    if ((mode != NULL) != crtc->enabled)
-    changed = TRUE;
-    else if (mode && !xf86ModesEqual (&crtc->mode, mode))
-	changed = TRUE;
-    
-    if (x != crtc->x || y != crtc->y)
-	changed = TRUE;
-    
-    for (o = 0; o < config->num_output; o++) {
-	xf86OutputPtr  output = config->output[o];
-	xf86CrtcPtr new_crtc;
-	
-	save_crtcs[o] = output->crtc;
-	
-	if (output->crtc == crtc)
-	    new_crtc = NULL;
-	else
-	    new_crtc = output->crtc;
-	
-	for (ro = 0; ro < num_randr_outputs; ro++)
-	    if (output->randr_output == randr_outputs[ro]) {
-		new_crtc = crtc;
-		break;
-	    }
-	if (new_crtc != output->crtc) {
-	    changed = TRUE;
-	    output->crtc = new_crtc;
-	}
-    }
-    
-    /* got to set the modes in here */
-    if (changed) {
-	RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-	RADEONInfoPtr  info = RADEONPTR(pScrn);
-	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
-	crtc->enabled = mode != NULL;
-
-#if 0//def XF86DRI
-	if (info->CPStarted) {
-	  DRILock(pScrn->pScreen, 0);
-	  RADEONCP_STOP(pScrn, info);
-	}
-#endif	
-	if (info->accelOn)
-	    RADEON_SYNC(info, pScrn);
-
-	radeon_crtc->binding = info->IsSecondary ? 2 : 1;
-	if (mode) {
-  	    info->IsSwitching = TRUE;
-	    if (!RADEONCrtcSetMode (crtc, mode, rotation, x, y))
-	    {
-		crtc->enabled = save_enabled;
-		for (o = 0; o < config->num_output; o++)
-		{
-		    xf86OutputPtr	output = config->output[o];
-		    output->crtc = save_crtcs[o];
-		}
-		DEALLOCATE_LOCAL(save_crtcs);
-		return FALSE;
-	    }
-	    crtc->desiredMode = *mode;
-	    crtc->desiredRotation = rotation;
-	    crtc->desiredX = x;
-	    crtc->desiredY = y;
-
-	    RADEONDisableUnusedFunctions(pScrn);
-	    RADEONBlank(pScrn);
-	    RADEONRestoreMode(pScrn, &info->ModeReg);
-	    RADEONUnblank(pScrn);
-	    info->IsSwitching = FALSE;
-	}
-	if (info->DispPriority)
-	  RADEONInitDispBandwidth(pScrn);
-
-	if (info->accelOn) {
-	  RADEON_SYNC(info, pScrn);
-//	  RADEONEngineRestore(pScrn);
-	}
-
-#if 0 //ef XF86DRI
-	if (info->CPStarted) {
-	  RADEONCP_START(pScrn, info);
-	  DRIUnlock(pScrn->pScreen);
-	}
-#endif
-    }
-    if (changed && mode)
-	RADEONCrtcSetBase(crtc, x, y);
-    DEALLOCATE_LOCAL(save_crtcs);
-    return xf86RandR12CrtcNotify (randr_crtc);
-}
-
-
-static Bool
-xf86RandR12CrtcSetGamma (ScreenPtr    pScreen,
-			 RRCrtcPtr    randr_crtc)
-{
-    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
-
-    if (crtc->funcs->gamma_set == NULL)
-	return FALSE;
-
-    crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen,
-			   randr_crtc->gammaBlue, randr_crtc->gammaSize);
-
-    return TRUE;
-}
-
-static Bool
-xf86RandR12OutputSetProperty (ScreenPtr pScreen,
-                              RROutputPtr randr_output,
-                              Atom property,
-                              RRPropertyValuePtr value)
-{
-    xf86OutputPtr output = randr_output->devPrivate;
-
-    /* If we don't have any property handler, then we don't care what the
-     * user is setting properties to.
-     */
-    if (output->funcs->set_property == NULL)
-        return TRUE;
-
-    return output->funcs->set_property(output, property, value);
-}
-
-/**
- * Given a list of xf86 modes and a RandR Output object, construct
- * RandR modes and assign them to the output
- */
-static Bool
-xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
-{
-    DisplayModePtr  mode;
-    RRModePtr	    *rrmodes = NULL;
-    int		    nmode = 0;
-    int		    npreferred = 0;
-    Bool	    ret = TRUE;
-    int		    pref;
-
-    for (mode = modes; mode; mode = mode->next)
-	nmode++;
-
-    if (nmode) {
-	rrmodes = xalloc (nmode * sizeof (RRModePtr));
-	
-	if (!rrmodes)
-	    return FALSE;
-	nmode = 0;
-
-	for (pref = 1; pref >= 0; pref--) {
-	    for (mode = modes; mode; mode = mode->next) {
-		if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
-		    xRRModeInfo		modeInfo;
-		    RRModePtr		rrmode;
-		    
-		    modeInfo.nameLength = strlen (mode->name);
-		    modeInfo.width = mode->HDisplay;
-		    modeInfo.dotClock = mode->Clock * 1000;
-		    modeInfo.hSyncStart = mode->HSyncStart;
-		    modeInfo.hSyncEnd = mode->HSyncEnd;
-		    modeInfo.hTotal = mode->HTotal;
-		    modeInfo.hSkew = mode->HSkew;
-
-		    modeInfo.height = mode->VDisplay;
-		    modeInfo.vSyncStart = mode->VSyncStart;
-		    modeInfo.vSyncEnd = mode->VSyncEnd;
-		    modeInfo.vTotal = mode->VTotal;
-		    modeInfo.modeFlags = mode->Flags;
-
-		    rrmode = RRModeGet (&modeInfo, mode->name);
-		    if (rrmode) {
-			rrmode->devPrivate = mode;
-			rrmodes[nmode++] = rrmode;
-			npreferred += pref;
-		    }
-		}
-	    }
-	}
-    }
-    
-    ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
-    xfree (rrmodes);
-    return ret;
-}
-
-/*
- * Mirror the current mode configuration to RandR
- */
-static Bool
-xf86RandR12SetInfo12 (ScreenPtr pScreen)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    RROutputPtr		*clones;
-    RRCrtcPtr		*crtcs;
-    int			ncrtc;
-    int			o, c, l;
-    RRCrtcPtr		randr_crtc;
-    int			nclone;
-    
-    clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
-    crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr));
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-	
-	ncrtc = 0;
-	for (c = 0; c < config->num_crtc; c++)
-	    if (output->possible_crtcs & (1 << c))
-		crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
-
-	if (output->crtc)
-	    randr_crtc = output->crtc->randr_crtc;
-	else
-	    randr_crtc = NULL;
-
-	if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
-	{
-	    DEALLOCATE_LOCAL (crtcs);
-	    DEALLOCATE_LOCAL (clones);
-	    return FALSE;
-	}
-
-	RROutputSetCrtc (output->randr_output, randr_crtc);
-	RROutputSetPhysicalSize(output->randr_output, 
-				output->mm_width,
-				output->mm_height);
-	xf86RROutputSetModes (output->randr_output, output->probed_modes);
-
-	switch (output->status) {
-	case XF86OutputStatusConnected:
-	    RROutputSetConnection (output->randr_output, RR_Connected);
-	    break;
-	case XF86OutputStatusDisconnected:
-	    RROutputSetConnection (output->randr_output, RR_Disconnected);
-	    break;
-	case XF86OutputStatusUnknown:
-	    RROutputSetConnection (output->randr_output, RR_UnknownConnection);
-	    break;
-	}
-
-	RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
-
-	/*
-	 * Valid clones
-	 */
-	nclone = 0;
-	for (l = 0; l < config->num_output; l++)
-	{
-	    xf86OutputPtr	    clone = config->output[l];
-	    
-	    if (l != o && (output->possible_clones & (1 << l)))
-		clones[nclone++] = clone->randr_output;
-	}
-	if (!RROutputSetClones (output->randr_output, clones, nclone))
-	{
-	    DEALLOCATE_LOCAL (crtcs);
-	    DEALLOCATE_LOCAL (clones);
-	    return FALSE;
-	}
-    }
-    DEALLOCATE_LOCAL (crtcs);
-    DEALLOCATE_LOCAL (clones);
-    return TRUE;
-}
-
-/*
- * Query the hardware for the current state, then mirror
- * that to RandR
- */
-static Bool
-xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-
-    xf86ProbeOutputModes (pScrn, 0, 0);
-    xf86SetScrnInfoModes (pScrn);
-
-    return xf86RandR12SetInfo12 (pScreen);
-}
-
-static Bool
-xf86RandR12CreateObjects12 (ScreenPtr pScreen)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			c;
-    int			o;
-    
-    if (!RRInit ())
-	return FALSE;
-
-    /*
-     * Configure crtcs
-     */
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr    crtc = config->crtc[c];
-	
-	crtc->randr_crtc = RRCrtcCreate (crtc);
-	RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
-	RRCrtcGammaSetSize (crtc->randr_crtc, 256);
-    }
-    /*
-     * Configure outputs
-     */
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->randr_output = RROutputCreate (output->name, 
-					       strlen (output->name),
-					       output);
-	RROutputAttachScreen (output->randr_output, pScreen);
-    }
-    return TRUE;
-}
-
-static Bool
-xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
-{
-    int			c;
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-    for (c = 0; c < config->num_crtc; c++)
-	xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-    
-    
-    RRScreenSetSizeRange (pScreen, 320, 240,
-			  randrp->virtualX, randrp->virtualY);
-    return TRUE;
-}
-
-static void
-xf86RandR12PointerMoved (int scrnIndex, int x, int y)
-{
-}
-
-static Bool
-xf86RandR12Init12 (ScreenPtr pScreen)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    rrScrPrivPtr	rp = rrGetScrPriv(pScreen);
-
-    rp->rrGetInfo = xf86RandR12GetInfo12;
-    rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
-    rp->rrCrtcSet = xf86RandR12CrtcSet;
-    rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
-    rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
-    rp->rrSetConfig = NULL;
-    pScrn->PointerMoved = xf86RandR12PointerMoved;
-    if (!xf86RandR12CreateObjects12 (pScreen))
-	return FALSE;
-
-    /*
-     * Configure output modes
-     */
-    if (!xf86RandR12SetInfo12 (pScreen))
-	return FALSE;
-    return TRUE;
-}
-
-#endif
-
-Bool
-xf86RandR12PreInit (ScrnInfoPtr pScrn)
-{
-    return TRUE;
-}
diff-tree 24c6fa7cfac5602ba9e6e2f331bcac52fab258e5 (from 63248f0b4308a4487cda3aa22daa36e3e0d38d14)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Feb 25 21:43:54 2007 +1100

    make radeon randr build against master server

diff --git a/src/Makefile.am b/src/Makefile.am
index ae2b002..4d0d1a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,9 +82,7 @@ radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
-	radeon_xf86Crtc.c radeon_xf86Modes.c radeon_randr.c \
-	radeon_edid_modes.c radeon_xf86cvt.c radeon_xf86Rotate.c \
-	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	radeon_randr.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
diff --git a/src/radeon.h b/src/radeon.h
index 83bec69..36372c8 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -77,7 +77,7 @@
 #endif
 #endif
 
-#include "radeon_xf86Crtc.h"
+#include "xf86Crtc.h"
 
 				/* Render support */
 #ifdef RENDER
diff --git a/src/radeon_display.c b/src/radeon_display.c
index f3d54a9..d83c68b 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -38,6 +38,7 @@
 #include "xf86_OSproc.h"
 #include "fbdevhw.h"
 #include "vgaHW.h"
+#include "xf86Modes.h"
 
 /* Driver data structures */
 #include "radeon.h"
@@ -45,7 +46,6 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
-#include "radeon_xf86Modes.h"
 
 
 void radeon_crtc_load_lut(xf86CrtcPtr crtc);
diff --git a/src/radeon_edid_modes.c b/src/radeon_edid_modes.c
deleted file mode 100644
index 747b75f..0000000
--- a/src/radeon_edid_modes.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * @file This is a copy of edid_modes.c from the X Server, for compatibility
- * with old X Servers.
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86DDC.h"
-#include "radeon_xf86Modes.h"
-#include "xf86Priv.h"
-#include <string.h>
-#include <math.h>
-
-
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-
-/*
- * Quirks to work around broken EDID data from various monitors.
- */
-
-typedef enum {
-    DDC_QUIRK_NONE = 0,
-    /* Force detailed sync polarity to -h +v */
-    DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0,
-    /* First detailed mode is bogus, prefer largest mode at 60hz */
-    DDC_QUIRK_PREFER_LARGE_60 = 1 << 1,
-} ddc_quirk_t;
-
-static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
-{
-    /* Belinea 1924S1W */
-    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
-	DDC->vendor.prod_id == 1932)
-	return TRUE;
-    /* Belinea 10 20 30W */
-    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
-	DDC->vendor.prod_id == 2007)
-	return TRUE;
-    
-    return FALSE;
-}
-
-static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
-{
-    /* Belinea 10 15 55 */
-    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
-	DDC->vendor.prod_id == 1516)
-	return TRUE;
-    
-    return FALSE;
-}
-
-typedef struct {
-    Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
-    ddc_quirk_t	quirk;
-    char	*description;
-} ddc_quirk_map_t;
-
-static const ddc_quirk_map_t ddc_quirks[] = {
-    { 
-	quirk_dt_sync_hm_vp,	DDC_QUIRK_DT_SYNC_HM_VP,
-	"Set detailed timing sync polarity to -h +v"
-    },
-    {
-	quirk_prefer_large_60,   DDC_QUIRK_PREFER_LARGE_60,
-	"Detailed timing is not preferred, use largest mode at 60Hz"
-    },
-    { 
-	NULL,		DDC_QUIRK_NONE,
-	"No known quirks"
-    },
-};
-
-/*
- * TODO:
- *  - for those with access to the VESA DMT standard; review please.
- */
-#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
-#define MODESUFFIX   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-DisplayModeRec DDCEstablishedModes[17] = {
-    { MODEPREFIX("800x600"),    40000,  800,  840,  968, 1056, 0,  600,  601,  605,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 60Hz */
-    { MODEPREFIX("800x600"),    36000,  800,  824,  896, 1024, 0,  600,  601,  603,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 56Hz */
-    { MODEPREFIX("640x480"),    31500,  640,  656,  720,  840, 0,  480,  481,  484,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 75Hz */
-    { MODEPREFIX("640x480"),    31500,  640,  664,  704,  832, 0,  480,  489,  491,  520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 72Hz */
-    { MODEPREFIX("640x480"),    30240,  640,  704,  768,  864, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 67Hz */
-    { MODEPREFIX("640x480"),    25200,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 60Hz */
-    { MODEPREFIX("720x400"),    35500,  720,  738,  846,  900, 0,  400,  421,  423,  449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400 at 88Hz */
-    { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400 at 70Hz */
-    { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024 at 75Hz */
-    { MODEPREFIX("1024x768"),   78800, 1024, 1040, 1136, 1312, 0,  768,  769,  772,  800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768 at 75Hz */
-    { MODEPREFIX("1024x768"),   75000, 1024, 1048, 1184, 1328, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 70Hz */
-    { MODEPREFIX("1024x768"),   65000, 1024, 1048, 1184, 1344, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 60Hz */
-    { MODEPREFIX("1024x768"),   44900, 1024, 1032, 1208, 1264, 0,  768,  768,  776,  817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768 at 43Hz */
-    { MODEPREFIX("832x624"),    57284,  832,  864,  928, 1152, 0,  624,  625,  628,  667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624 at 75Hz */
-    { MODEPREFIX("800x600"),    49500,  800,  816,  896, 1056, 0,  600,  601,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 75Hz */
-    { MODEPREFIX("800x600"),    50000,  800,  856,  976, 1040, 0,  600,  637,  643,  666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 72Hz */
-    { MODEPREFIX("1152x864"),  108000, 1152, 1216, 1344, 1600, 0,  864,  865,  868,  900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864 at 75Hz */
-};
-
-static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
-			ddc_quirk_t quirks)
-{
-    DisplayModePtr Modes = NULL, Mode = NULL;
-    CARD32 bits = (timing->t1) | (timing->t2 << 8) |
-        ((timing->t_manu & 0x80) << 9);
-    int i;
-
-    for (i = 0; i < 17; i++) {
-        if (bits & (0x01 << i)) {
-            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
-            Modes = xf86ModesAdd(Modes, Mode);
-        }
-    }
-
-    return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
-			   ddc_quirk_t quirks)
-{
-    DisplayModePtr Modes = NULL, Mode = NULL;
-    int i;
-
-    for (i = 0; i < STD_TIMINGS; i++) {
-        if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
-            Mode =  xf86CVTMode(timing[i].hsize, timing[i].vsize,
-                                timing[i].refresh, FALSE, FALSE);
-	    Mode->type = M_T_DRIVER;
-            Modes = xf86ModesAdd(Modes, Mode);
-        }
-    }
-
-    return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
-			  int preferred, ddc_quirk_t quirks)
-{
-    DisplayModePtr Mode;
-
-    /* We don't do stereo */
-    if (timing->stereo) {
-        xf86DrvMsg(scrnIndex, X_INFO,
-		   "%s: Ignoring: We don't handle stereo.\n", __func__);
-        return NULL;
-    }
-
-    /* We only do seperate sync currently */
-    if (timing->sync != 0x03) {
-         xf86DrvMsg(scrnIndex, X_INFO,
-		    "%s: %dx%d Warning: We only handle seperate"
-                    " sync.\n", __func__, timing->h_active, timing->v_active);
-    }
-
-    Mode = xnfalloc(sizeof(DisplayModeRec));
-    memset(Mode, 0, sizeof(DisplayModeRec));
-
-    Mode->type = M_T_DRIVER;
-    if (preferred)
-	Mode->type |= M_T_PREFERRED;
-
-    Mode->Clock = timing->clock / 1000.0;
-
-    Mode->HDisplay = timing->h_active;
-    Mode->HSyncStart = timing->h_active + timing->h_sync_off;
-    Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
-    Mode->HTotal = timing->h_active + timing->h_blanking;
-
-    Mode->VDisplay = timing->v_active;
-    Mode->VSyncStart = timing->v_active + timing->v_sync_off;
-    Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
-    Mode->VTotal = timing->v_active + timing->v_blanking;
-
-    xf86SetModeDefaultName(Mode);
-
-    /* We ignore h/v_size and h/v_border for now. */
-
-    if (timing->interlaced)
-        Mode->Flags |= V_INTERLACE;
-
-    if (quirks & DDC_QUIRK_DT_SYNC_HM_VP)
-	Mode->Flags |= V_NHSYNC | V_PVSYNC;
-    else
-    {
-	if (timing->misc & 0x02)
-	    Mode->Flags |= V_PHSYNC;
-	else
-	    Mode->Flags |= V_NHSYNC;
-    
-	if (timing->misc & 0x01)
-	    Mode->Flags |= V_PVSYNC;
-	else
-	    Mode->Flags |= V_NVSYNC;
-    }
-
-    return Mode;
-}
-
-DisplayModePtr
-xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
-{
-    int preferred, i;
-    DisplayModePtr  Modes = NULL, Mode;
-    ddc_quirk_t	    quirks;
-
-    xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
-		DDC->vendor.name, DDC->vendor.prod_id);
-    quirks = DDC_QUIRK_NONE;
-    for (i = 0; ddc_quirks[i].detect; i++)
-	if (ddc_quirks[i].detect (scrnIndex, DDC))
-	{
-	    xf86DrvMsg (scrnIndex, X_INFO, "    EDID quirk: %s\n",
-			ddc_quirks[i].description);
-	    quirks |= ddc_quirks[i].quirk;
-	}
-    
-    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
-	preferred = 0;
-
-    for (i = 0; i < DET_TIMINGS; i++) {
-	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
-
-        switch (det_mon->type) {
-        case DT:
-            Mode = DDCModeFromDetailedTiming(scrnIndex,
-                                             &det_mon->section.d_timings,
-					     preferred,
-					     quirks);
-	    preferred = 0;
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        case DS_STD_TIMINGS:
-            Mode = DDCModesFromStandardTiming(scrnIndex,
-					      det_mon->section.std_t,
-					      quirks);
-            Modes = xf86ModesAdd(Modes, Mode);
-            break;
-        default:
-            break;
-        }
-    }
-
-    /* Add established timings */
-    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    /* Add standard timings */
-    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks);
-    Modes = xf86ModesAdd(Modes, Mode);
-
-    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
-    {
-	DisplayModePtr	best = Modes;
-	for (Mode = Modes; Mode; Mode = Mode->next)
-	{
-	    if (Mode == best) continue;
-	    if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
-	    {
-		best = Mode;
-		continue;
-	    }
-	    if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
-	    {
-		double	mode_refresh = xf86ModeVRefresh (Mode);
-		double	best_refresh = xf86ModeVRefresh (best);
-		double	mode_dist = fabs(mode_refresh - 60.0);
-		double	best_dist = fabs(best_refresh - 60.0);
-		if (mode_dist < best_dist)
-		{
-		    best = Mode;
-		    continue;
-		}
-	    }
-	}
-	if (best)
-	    best->type |= M_T_PREFERRED;
-    }
-    return Modes;
-}
-
-#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 74e52cb..064b1ae 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -50,7 +50,7 @@
 
 #include "radeon_version.h"
 
-#include "radeon_xf86Modes.h"
+#include "xf86Modes.h"
 				/* DDC support */
 #include "xf86DDC.h"
 #include <randrstr.h>
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 66210a4..c783460 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -43,7 +43,7 @@
 #define _XF86MISC_SERVER_
 #include <X11/extensions/xf86misc.h>
 
-#include "radeon_xf86Crtc.h"
+#include "xf86Crtc.h"
 
 typedef enum
 {
diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
deleted file mode 100644
index 7e4ae39..0000000
--- a/src/radeon_xf86Crtc.c
+++ /dev/null
@@ -1,1560 +0,0 @@
-/*
- * $Id: $
- *
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-//#include "i.h"
-#include "radeon_xf86Crtc.h"
-#include "radeon_xf86Modes.h"
-#include "X11/extensions/render.h"
-
-#define DPMS_SERVER
-#include "X11/extensions/dpms.h"
-#include "X11/Xatom.h"
-
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-int xf86CrtcConfigPrivateIndex = -1;
-
-void
-xf86CrtcConfigInit (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr	config;
-    
-    if (xf86CrtcConfigPrivateIndex == -1)
-	xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
-    config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
-    scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
-}
- 
-void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
-		      int minWidth, int minHeight,
-		      int maxWidth, int maxHeight)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-
-    config->minWidth = minWidth;
-    config->minHeight = minHeight;
-    config->maxWidth = maxWidth;
-    config->maxHeight = maxHeight;
-}
-
-/*
- * Crtc functions
- */
-xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr		scrn,
-		const xf86CrtcFuncsRec	*funcs)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr		crtc, *crtcs;
-
-    crtc = xcalloc (sizeof (xf86CrtcRec), 1);
-    if (!crtc)
-	return NULL;
-    crtc->scrn = scrn;
-    crtc->funcs = funcs;
-#ifdef RANDR_12_INTERFACE
-    crtc->randr_crtc = NULL;
-#endif
-    crtc->rotation = RR_Rotate_0;
-    crtc->desiredRotation = RR_Rotate_0;
-    if (xf86_config->crtc)
-	crtcs = xrealloc (xf86_config->crtc,
-			  (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
-    else
-	crtcs = xalloc ((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
-    if (!crtcs)
-    {
-	xfree (crtc);
-	return NULL;
-    }
-    xf86_config->crtc = crtcs;
-    xf86_config->crtc[xf86_config->num_crtc++] = crtc;
-    return crtc;
-}
-
-void
-xf86CrtcDestroy (xf86CrtcPtr crtc)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-    int			c;
-    
-    (*crtc->funcs->destroy) (crtc);
-    for (c = 0; c < xf86_config->num_crtc; c++)
-	if (xf86_config->crtc[c] == crtc)
-	{
-	    memmove (&xf86_config->crtc[c],
-		     &xf86_config->crtc[c+1],
-		     xf86_config->num_crtc - (c + 1));
-	    xf86_config->num_crtc--;
-	    break;
-	}
-    xfree (crtc);
-}
-
-
-/**
- * Return whether any outputs are connected to the specified pipe
- */
-
-Bool
-xf86CrtcInUse (xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr		pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			o;
-    
-    for (o = 0; o < xf86_config->num_output; o++)
-	if (xf86_config->output[o]->crtc == crtc)
-	    return TRUE;
-    return FALSE;
-}
-
-/**
- * Sets the given video mode on the given crtc
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-		 int x, int y)
-{
-    ScrnInfoPtr		scrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-    Bool		ret = FALSE;
-    Bool		didLock = FALSE;
-    DisplayModePtr	adjusted_mode;
-    DisplayModeRec	saved_mode;
-    int			saved_x, saved_y;
-    Rotation		saved_rotation;
-
-    adjusted_mode = xf86DuplicateMode(mode);
-
-    crtc->enabled = xf86CrtcInUse (crtc);
-    
-    if (!crtc->enabled)
-    {
-	/* XXX disable crtc? */
-	return TRUE;
-    }
-
-    didLock = crtc->funcs->lock (crtc);
-
-    saved_mode = crtc->mode;
-    saved_x = crtc->x;
-    saved_y = crtc->y;
-    saved_rotation = crtc->rotation;
-    /* Update crtc values up front so the driver can rely on them for mode
-     * setting.
-     */
-    crtc->mode = *mode;
-    crtc->x = x;
-    crtc->y = y;
-    crtc->rotation = rotation;
-
-    /* XXX short-circuit changes to base location only */
-    
-    /* Pass our mode to the outputs and the CRTC to give them a chance to
-     * adjust it according to limitations or output properties, and also
-     * a chance to reject the mode entirely.
-     */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
-	    goto done;
-	}
-    }
-
-    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
-	goto done;
-    }
-
-    if (!xf86CrtcRotate (crtc, mode, rotation)) {
-	goto done;
-    }
-
-    /* Disable the outputs and CRTCs before setting the mode. */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	/* Disable the output as the first thing we do. */
-	output->funcs->dpms(output, DPMSModeOff);
-    }
-
-    crtc->funcs->dpms(crtc, DPMSModeOff);
-
-    /* Set up the DPLL and any output state that needs to adjust or depend
-     * on the DPLL.
-     */
-    crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->mode_set(output, mode, adjusted_mode);
-    }
-
-    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
-    crtc->funcs->dpms(crtc, DPMSModeOn);
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->dpms(output, DPMSModeOn);
-    }
-
-    /* XXX free adjustedmode */
-    ret = TRUE;
-done:
-    if (!ret) {
-	crtc->x = saved_x;
-	crtc->y = saved_y;
-	crtc->rotation = saved_rotation;
-	crtc->mode = saved_mode;
-    }
-
-    if (didLock)
-	crtc->funcs->unlock (crtc);
-
-    return ret;
-}
-
-/*
- * Output functions
- */
-
-extern XF86ConfigPtr xf86configptr;
-
-typedef enum {
-    OPTION_PREFERRED_MODE,
-    OPTION_POSITION,
-    OPTION_BELOW,
-    OPTION_RIGHT_OF,
-    OPTION_ABOVE,
-    OPTION_LEFT_OF,
-    OPTION_ENABLE,
-    OPTION_DISABLE,
-    OPTION_MIN_CLOCK,
-    OPTION_MAX_CLOCK,
-} OutputOpts;
-
-static OptionInfoRec xf86OutputOptions[] = {
-    {OPTION_PREFERRED_MODE, "PreferredMode",	OPTV_STRING,  {0}, FALSE },
-    {OPTION_POSITION,	    "Position",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_BELOW,	    "Below",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_RIGHT_OF,	    "RightOf",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_ABOVE,	    "Above",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_LEFT_OF,	    "LeftOf",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_ENABLE,	    "Enable",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_DISABLE,	    "Disable",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_MIN_CLOCK,	    "MinClock",		OPTV_FREQ,    {0}, FALSE },
-    {OPTION_MAX_CLOCK,	    "MaxClock",		OPTV_FREQ,    {0}, FALSE },
-    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
-};
-
-static void
-xf86OutputSetMonitor (xf86OutputPtr output)
-{
-    char    *option_name;
-    static const char monitor_prefix[] = "monitor-";
-    char    *monitor;
-
-    if (output->options)
-	xfree (output->options);
-
-    output->options = xnfalloc (sizeof (xf86OutputOptions));
-    memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
-    
-    option_name = xnfalloc (strlen (monitor_prefix) +
-			    strlen (output->name) + 1);
-    strcpy (option_name, monitor_prefix);
-    strcat (option_name, output->name);
-    monitor = xf86findOptionValue (output->scrn->options, option_name);
-    if (!monitor)
-	monitor = output->name;
-    else
-	xf86MarkOptionUsedByName (output->scrn->options, option_name);
-    xfree (option_name);
-    output->conf_monitor = xf86findMonitor (monitor,
-					    xf86configptr->conf_monitor_lst);
-    if (output->conf_monitor)
-	xf86ProcessOptions (output->scrn->scrnIndex,
-			    output->conf_monitor->mon_option_lst,
-			    output->options);
-}
-
-static Bool
-xf86OutputEnabled (xf86OutputPtr    output)
-{
-    /* Check to see if this output was disabled in the config file */
-    if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
-	xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
-    {
-	return FALSE;
-    }
-    return TRUE;
-}
-
-xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr		    scrn,
-		  const xf86OutputFuncsRec *funcs,
-		  const char		    *name)
-{
-    xf86OutputPtr	output, *outputs;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			len = strlen (name);
-
-    output = xcalloc (sizeof (xf86OutputRec) + len + 1, 1);
-    if (!output)
-	return NULL;
-    output->scrn = scrn;
-    output->funcs = funcs;
-    output->name = (char *) (output + 1);
-    output->subpixel_order = SubPixelUnknown;
-    strcpy (output->name, name);
-#ifdef RANDR_12_INTERFACE
-    output->randr_output = NULL;
-#endif
-    xf86OutputSetMonitor (output);
-    
-    if (xf86_config->output)
-	outputs = xrealloc (xf86_config->output,
-			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
-    else
-	outputs = xalloc ((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
-    if (!outputs)
-    {
-	xfree (output);
-	return NULL;
-    }
-    
-    xf86_config->output = outputs;
-    xf86_config->output[xf86_config->num_output++] = output;
-    
-    return output;
-}
-
-Bool
-xf86OutputRename (xf86OutputPtr output, const char *name)
-{
-    int	    len = strlen(name);
-    char    *newname = xalloc (len + 1);
-    
-    if (!newname)
-	return FALSE;	/* so sorry... */
-    
-    strcpy (newname, name);
-    if (output->name != (char *) (output + 1))
-	xfree (output->name);
-    output->name = newname;
-    xf86OutputSetMonitor (output);
-    return TRUE;
-}
-
-void
-xf86OutputDestroy (xf86OutputPtr output)
-{
-    ScrnInfoPtr		scrn = output->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    
-    (*output->funcs->destroy) (output);
-    while (output->probed_modes)
-	xf86DeleteMode (&output->probed_modes, output->probed_modes);
-    for (o = 0; o < xf86_config->num_output; o++)
-	if (xf86_config->output[o] == output)
-	{
-	    memmove (&xf86_config->output[o],
-		     &xf86_config->output[o+1],
-		     xf86_config->num_output - (o + 1));
-	    xf86_config->num_output--;
-	    break;
-	}
-    if (output->name != (char *) (output + 1))
-	xfree (output->name);
-    xfree (output);
-}
-
-static DisplayModePtr
-xf86DefaultMode (xf86OutputPtr output, int width, int height)
-{
-    DisplayModePtr  target_mode = NULL;
-    DisplayModePtr  mode;
-    int		    target_diff = 0;
-    int		    target_preferred = 0;
-    int		    mm_height;
-    
-    mm_height = output->mm_height;
-    if (!mm_height)
-	mm_height = 203;	/* 768 pixels at 96dpi */
-    /*
-     * Pick a mode closest to 96dpi 
-     */
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	int	    dpi;
-	int	    preferred = (mode->type & M_T_PREFERRED) != 0;
-	int	    diff;
-
-	if (mode->HDisplay > width || mode->VDisplay > height) continue;
-	dpi = (mode->HDisplay * 254) / (mm_height * 10);
-	diff = dpi - 96;
-	diff = diff < 0 ? -diff : diff;
-	if (target_mode == NULL || (preferred > target_preferred) ||
-	    (preferred == target_preferred && diff < target_diff))
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	    target_preferred = preferred;
-	}
-    }
-    return target_mode;
-}
-
-static DisplayModePtr
-xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match,
-		 int width, int height)
-{
-    DisplayModePtr  target_mode = NULL;
-    DisplayModePtr  mode;
-    int		    target_diff = 0;
-    
-    /*
-     * Pick a mode closest to the specified mode
-     */
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	int	    dx, dy;
-	int	    diff;
-
-	if (mode->HDisplay > width || mode->VDisplay > height) continue;
-	
-	/* exact matches are preferred */
-	if (xf86ModesEqual (mode, match))
-	    return mode;
-	
-	dx = match->HDisplay - mode->HDisplay;
-	dy = match->VDisplay - mode->VDisplay;
-	diff = dx * dx + dy * dy;
-	if (target_mode == NULL || diff < target_diff)
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	}
-    }
-    return target_mode;
-}
-
-static Bool
-xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
-{
-    DisplayModePtr  mode;
-
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	if (mode->HDisplay > width || mode->VDisplay > height) continue;
-	if (mode->type & M_T_PREFERRED)
-	    return TRUE;
-    }
-    return FALSE;
-}
-
-static int
-xf86PickCrtcs (ScrnInfoPtr	scrn,
-	       xf86CrtcPtr	*best_crtcs,
-	       DisplayModePtr	*modes,
-	       int		n,
-	       int		width,
-	       int		height)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int		    c, o, l;
-    xf86OutputPtr   output;
-    xf86CrtcPtr	    crtc;
-    xf86CrtcPtr	    *crtcs;
-    xf86CrtcPtr	    best_crtc;
-    int		    best_score;
-    int		    score;
-    int		    my_score;
-    
-    if (n == config->num_output)
-	return 0;
-    output = config->output[n];
-    
-    /*
-     * Compute score with this output disabled
-     */
-    best_crtcs[n] = NULL;
-    best_crtc = NULL;
-    best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
-    if (modes[n] == NULL)
-	return best_score;
-    
-    crtcs = xalloc (config->num_output * sizeof (xf86CrtcPtr));
-    if (!crtcs)
-	return best_score;
-
-    my_score = 1;
-    /* Score outputs that are known to be connected higher */
-    if (output->status == XF86OutputStatusConnected)
-	my_score++;
-    /* Score outputs with preferred modes higher */
-    if (xf86OutputHasPreferredMode (output, width, height))
-	my_score++;
-    /*
-     * Select a crtc for this output and
-     * then attempt to configure the remaining
-     * outputs
-     */
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	if ((output->possible_crtcs & (1 << c)) == 0)
-	    continue;
-	
-	crtc = config->crtc[c];
-	/*
-	 * Check to see if some other output is
-	 * using this crtc
-	 */
-	for (o = 0; o < n; o++)
-	    if (best_crtcs[o] == crtc)
-		break;
-	if (o < n)
-	{
-	    /*
-	     * If the two outputs desire the same mode,
-	     * see if they can be cloned
-	     */
-	    if (xf86ModesEqual (modes[o], modes[n]) &&
-		config->output[o]->initial_x == config->output[n]->initial_x &&
-		config->output[o]->initial_y == config->output[n]->initial_y)
-	    {
-		for (l = 0; l < config->num_output; l++)
-		    if (output->possible_clones & (1 << l))
-			break;
-		if (l == config->num_output)
-		    continue;		/* nope, try next CRTC */
-	    }
-	    else
-		continue;		/* different modes, can't clone */
-	}
-	crtcs[n] = crtc;
-	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
-	score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
-	if (score > best_score)
-	{
-	    best_crtc = crtc;
-	    best_score = score;
-	    memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
-	}
-    }
-    xfree (crtcs);
-    return best_score;
-}
-
-
-/*
- * Compute the virtual size necessary to place all of the available
- * crtcs in the specified configuration and also large enough to
- * resize any crtc to the largest available mode
- */
-
-static void
-xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int	    width = 0, height = 0;
-    int	    o;
-    int	    c;
-    int	    s;
-
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	int	    crtc_width = 0, crtc_height = 0;
-	xf86CrtcPtr crtc = config->crtc[c];
-
-	if (crtc->enabled)
-	{
-	    crtc_width = crtc->x + crtc->desiredMode.HDisplay;
-	    crtc_height = crtc->y + crtc->desiredMode.VDisplay;
-	}
-	for (o = 0; o < config->num_output; o++) 
-	{
-	    xf86OutputPtr   output = config->output[o];
-
-	    for (s = 0; s < config->num_crtc; s++)
-		if (output->possible_crtcs & (1 << s))
-		{
-		    DisplayModePtr  mode;
-		    for (mode = output->probed_modes; mode; mode = mode->next)
-		    {
-			if (mode->HDisplay > crtc_width)
-			    crtc_width = mode->HDisplay;
-			if (mode->VDisplay > crtc_height)
-			    crtc_height = mode->VDisplay;
-		    }
-		}
-	}
-	if (crtc_width > width)
-	    width = crtc_width;
-	if (crtc_height > height)
-	    height = crtc_height;
-    }
-    if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
-    if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
-    if (config->minWidth && width < config->minWidth) width = config->minWidth;
-    if (config->minHeight && height < config->minHeight) height = config->minHeight;
-    *widthp = width;
-    *heightp = height;
-}
-
-#define POSITION_UNSET	-100000
-
-static Bool
-xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    int			min_x, min_y;
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->initial_x = output->initial_y = POSITION_UNSET;
-    }
-    
-    /*
-     * Loop until all outputs are set
-     */
-    for (;;)
-    {
-	Bool	any_set = FALSE;
-	Bool	keep_going = FALSE;
-
-	for (o = 0; o < config->num_output; o++)	
-	{
-	    static const OutputOpts	relations[] = {
-		OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
-	    };
-	    xf86OutputPtr   output = config->output[o];
-	    xf86OutputPtr   relative;
-	    char	    *relative_name;
-	    char	    *position;
-	    OutputOpts	    relation;
-	    int		    r;
-
-	    if (output->initial_x != POSITION_UNSET)
-		continue;
-	    position = xf86GetOptValString (output->options,
-					    OPTION_POSITION);
-	    /*
-	     * Absolute position wins
-	     */
-	    if (position)
-	    {
-		int		    x, y;
-		if (sscanf (position, "%d %d", &x, &y) == 2)
-		{
-		    output->initial_x = x;
-		    output->initial_y = y;
-		}
-		else
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Output %s position not of form \"x y\"\n",
-				output->name);
-		    output->initial_x = output->initial_y = 0;
-		}
-		any_set = TRUE;
-		continue;
-	    }
-	    /*
-	     * Next comes relative positions
-	     */
-	    relation = 0;
-	    relative_name = NULL;
-	    for (r = 0; r < 4; r++)
-	    {
-		relation = relations[r];
-		relative_name = xf86GetOptValString (output->options,
-						     relation);
-		if (relative_name)
-		    break;
-	    }
-	    if (relative_name)
-	    {
-		int or;
-		relative = NULL;
-		for (or = 0; or < config->num_output; or++)
-		{
-		    xf86OutputPtr	out_rel = config->output[or];
-		    XF86ConfMonitorPtr	rel_mon = out_rel->conf_monitor;
-		    char		*name;
-
-		    if (rel_mon)
-			name = rel_mon->mon_identifier;
-		    else
-			name = out_rel->name;
-		    if (!strcmp (relative_name, name))
-		    {
-			relative = config->output[or];
-			break;
-		    }
-		}
-		if (!relative)
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Cannot position output %s relative to unknown output %s\n",
-				output->name, relative_name);
-		    output->initial_x = 0;
-		    output->initial_y = 0;
-		    any_set = TRUE;
-		    continue;
-		}
-		if (relative->initial_x == POSITION_UNSET)
-		{
-		    keep_going = TRUE;
-		    continue;
-		}
-		output->initial_x = relative->initial_x;
-		output->initial_y = relative->initial_y;
-		switch (relation) {
-		case OPTION_BELOW:
-		    output->initial_y += modes[or]->VDisplay;
-		    break;
-		case OPTION_RIGHT_OF:
-		    output->initial_x += modes[or]->HDisplay;
-		    break;
-		case OPTION_ABOVE:
-		    output->initial_y -= modes[o]->VDisplay;
-		    break;
-		case OPTION_LEFT_OF:
-		    output->initial_x -= modes[o]->HDisplay;
-		    break;
-		default:
-		    break;
-		}
-		any_set = TRUE;
-		continue;
-	    }
-	    
-	    /* Nothing set, just stick them at 0,0 */
-	    output->initial_x = 0;
-	    output->initial_y = 0;
-	    any_set = TRUE;
-	}
-	if (!keep_going)
-	    break;
-	if (!any_set) 
-	{
-	    for (o = 0; o < config->num_output; o++)
-	    {
-		xf86OutputPtr   output = config->output[o];
-		if (output->initial_x == POSITION_UNSET)
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Output position loop. Moving %s to 0,0\n",
-				output->name);
-		    output->initial_x = output->initial_y = 0;
-		    break;
-		}
-	    }
-	}
-    }
-
-    /*
-     * normalize positions
-     */
-    min_x = 1000000;
-    min_y = 1000000;
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	if (output->initial_x < min_x)
-	    min_x = output->initial_x;
-	if (output->initial_y < min_y)
-	    min_y = output->initial_y;
-    }
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->initial_x -= min_x;
-	output->initial_y -= min_y;
-    }
-    return TRUE;
-}
-
-/*
- * XXX walk the monitor mode list and prune out duplicates that
- * are inserted by xf86DDCMonitorSet. In an ideal world, that
- * function would do this work by itself.
- */
-
-static void
-xf86PruneDuplicateMonitorModes (MonPtr Monitor)
-{
-    DisplayModePtr  master, clone, next;
-
-    for (master = Monitor->Modes; 
-	 master && master != Monitor->Last; 
-	 master = master->next)
-    {
-	for (clone = master->next; clone && clone != Monitor->Modes; clone = next)
-	{
-	    next = clone->next;
-	    if (xf86ModesEqual (master, clone))
-	    {
-		if (Monitor->Last == clone)
-		    Monitor->Last = clone->prev;
-		xf86DeleteMode (&Monitor->Modes, clone);
-	    }
-	}
-    }
-}
-
-/** Return - 0 + if a should be earlier, same or later than b in list
- */
-static int
-i830xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
-{
-    int	diff;
-
-    diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
-    if (diff)
-	return diff;
-    diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
-    if (diff)
-	return diff;
-    diff = b->Clock - a->Clock;
-    return diff;
-}
-
-/**
- * Insertion sort input in-place and return the resulting head
- */
-static DisplayModePtr
-i830xf86SortModes (DisplayModePtr input)
-{
-    DisplayModePtr  output = NULL, i, o, n, *op, prev;
-
-    /* sort by preferred status and pixel area */
-    while (input)
-    {
-	i = input;
-	input = input->next;
-	for (op = &output; (o = *op); op = &o->next)
-	    if (i830xf86ModeCompare (o, i) > 0)
-		break;
-	i->next = *op;
-	*op = i;
-    }
-    /* prune identical modes */
-    for (o = output; o && (n = o->next); o = n)
-    {
-	if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
-	{
-	    o->next = n->next;
-	    xfree (n->name);
-	    xfree (n);
-	    n = o;
-	}
-    }
-    /* hook up backward links */
-    prev = NULL;
-    for (o = output; o; o = o->next)
-    {
-	o->prev = prev;
-	prev = o;
-    }
-    return output;
-}
-
-#define DEBUG_REPROBE 1
-
-void
-xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-
-    if (maxX == 0 || maxY == 0)
-	xf86RandR12GetOriginalVirtualSize (scrn, &maxX, &maxY);
-
-    /* Elide duplicate modes before defaulting code uses them */
-    xf86PruneDuplicateMonitorModes (scrn->monitor);
-    
-    /* Probe the list of modes for each output. */
-    for (o = 0; o < config->num_output; o++) 
-    {
-	xf86OutputPtr	    output = config->output[o];
-	DisplayModePtr	    mode;
-	DisplayModePtr	    config_modes = NULL, output_modes, default_modes;
-	char		    *preferred_mode;
-	xf86MonPtr	    edid_monitor;
-	XF86ConfMonitorPtr  conf_monitor;
-	MonRec		    mon_rec;
-	int		    min_clock = 0;
-	int		    max_clock = 0;
-	double		    clock;
-	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
-	
-	while (output->probed_modes != NULL)
-	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
-
-	/*
-	 * Check connection status
-	 */
-	output->status = (*output->funcs->detect)(output);
-
-	if (output->status == XF86OutputStatusDisconnected)
-	    continue;
-
-	memset (&mon_rec, '\0', sizeof (mon_rec));
-	
-	conf_monitor = output->conf_monitor;
-	
-	if (conf_monitor)
-	{
-	    int	i;
-	    
-	    for (i = 0; i < conf_monitor->mon_n_hsync; i++)
-	    {
-		mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
-		mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
-		mon_rec.nHsync++;
-		sync_source = sync_config;
-	    }
-	    for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
-	    {
-		mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
-		mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
-		mon_rec.nVrefresh++;
-		sync_source = sync_config;
-	    }
-	    config_modes = xf86GetMonitorModes (scrn, conf_monitor);
-	}
-	
-	output_modes = (*output->funcs->get_modes) (output);
-	
-	edid_monitor = output->MonInfo;
-	
-	if (edid_monitor)
-	{
-	    int			    i;
-	    Bool		    set_hsync = mon_rec.nHsync == 0;
-	    Bool		    set_vrefresh = mon_rec.nVrefresh == 0;
-
-	    for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
-	    {
-		if (edid_monitor->det_mon[i].type == DS_RANGES)
-		{
-		    struct monitor_ranges   *ranges = &edid_monitor->det_mon[i].section.ranges;
-		    if (set_hsync && ranges->max_h)
-		    {
-			mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h;
-			mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h;
-			mon_rec.nHsync++;
-			if (sync_source == sync_default)
-			    sync_source = sync_edid;
-		    }
-		    if (set_vrefresh && ranges->max_v)
-		    {
-			mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v;
-			mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v;
-			mon_rec.nVrefresh++;
-			if (sync_source == sync_default)
-			    sync_source = sync_edid;
-		    }
-		    if (ranges->max_clock > max_clock)
-			max_clock = ranges->max_clock;
-		}
-	    }
-	}
-
-	if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
-			       OPTUNITS_KHZ, &clock))
-	    min_clock = (int) clock;
-	if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
-			       OPTUNITS_KHZ, &clock))
-	    max_clock = (int) clock;
-
-	/*
-	 * These limits will end up setting a 1024x768 at 60Hz mode by default,
-	 * which seems like a fairly good mode to use when nothing else is
-	 * specified
-	 */
-	if (mon_rec.nHsync == 0)
-	{
-	    mon_rec.hsync[0].lo = 31.0;
-	    mon_rec.hsync[0].hi = 55.0;
-	    mon_rec.nHsync = 1;
-	}
-	if (mon_rec.nVrefresh == 0)
-	{
-	    mon_rec.vrefresh[0].lo = 58.0;
-	    mon_rec.vrefresh[0].hi = 62.0;
-	    mon_rec.nVrefresh = 1;
-	}
-	default_modes = xf86GetDefaultModes (output->interlaceAllowed,
-					     output->doubleScanAllowed);
-	
-	if (sync_source == sync_config)
-	{
-	    /* 
-	     * Check output and config modes against sync range from config file
-	     */
-	    xf86ValidateModesSync (scrn, output_modes, &mon_rec);
-	    xf86ValidateModesSync (scrn, config_modes, &mon_rec);
-	}
-	/*
-	 * Check default modes against sync range
-	 */
-        xf86ValidateModesSync (scrn, default_modes, &mon_rec);
-	/*
-	 * Check default modes against monitor max clock
-	 */
-	if (max_clock)
-	    xf86ValidateModesClocks(scrn, default_modes,
-				    &min_clock, &max_clock, 1);
-	
-	output->probed_modes = NULL;
-	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
-	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
-	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
-	
-	/*
-	 * Check all modes against max size
-	 */
-	if (maxX && maxY)
-	    xf86ValidateModesSize (scrn, output->probed_modes,
-				       maxX, maxY, 0);
-	 
-	/*
-	 * Check all modes against output
-	 */
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next) 
-	    if (mode->status == MODE_OK)
-		mode->status = (*output->funcs->mode_valid)(output, mode);
-	
-	xf86PruneInvalidModes(scrn, &output->probed_modes, TRUE);
-	
-	output->probed_modes = i830xf86SortModes (output->probed_modes);
-	
-	/* Check for a configured preference for a particular mode */
-	preferred_mode = xf86GetOptValString (output->options,
-					      OPTION_PREFERRED_MODE);
-
-	if (preferred_mode)
-	{
-	    for (mode = output->probed_modes; mode; mode = mode->next)
-	    {
-		if (!strcmp (preferred_mode, mode->name))
-		{
-		    if (mode != output->probed_modes)
-		    {
-			if (mode->prev)
-			    mode->prev->next = mode->next;
-			if (mode->next)
-			    mode->next->prev = mode->prev;
-			mode->next = output->probed_modes;
-			output->probed_modes->prev = mode;
-			mode->prev = NULL;
-			output->probed_modes = mode;
-		    }
-		    mode->type |= M_T_PREFERRED;
-		    break;
-		}
-	    }
-	}
-	
-#ifdef DEBUG_REPROBE
-	if (output->probed_modes != NULL) {
-	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		       "Printing probed modes for output %s\n",
-		       output->name);
-	} else {
-	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
-		       "No remaining probed modes for output %s\n",
-		       output->name);
-	}
-#endif
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
-	{
-	    /* The code to choose the best mode per pipe later on will require
-	     * VRefresh to be set.
-	     */
-	    mode->VRefresh = xf86ModeVRefresh(mode);
-	    xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
-#ifdef DEBUG_REPROBE
-	    xf86PrintModeline(scrn->scrnIndex, mode);
-#endif
-	}
-    }
-}
-
-
-/**
- * Copy one of the output mode lists to the ScrnInfo record
- */
-
-/* XXX where does this function belong? Here? */
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
-
-void
-xf86SetScrnInfoModes (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86OutputPtr	output;
-    xf86CrtcPtr		crtc;
-    DisplayModePtr	last, mode;
-
-    output = config->output[config->compat_output];
-    if (!output->crtc)
-    {
-	int o;
-
-	output = NULL;
-	for (o = 0; o < config->num_output; o++)
-	    if (config->output[o]->crtc)
-	    {
-		config->compat_output = o;
-		output = config->output[o];
-		break;
-	    }
-	/* no outputs are active, punt and leave things as they are */
-	if (!output)
-	    return;
-    }
-    crtc = output->crtc;
-
-    /* Clear any existing modes from scrn->modes */
-    while (scrn->modes != NULL)
-	xf86DeleteMode(&scrn->modes, scrn->modes);
-
-    /* Set scrn->modes to the mode list for the 'compat' output */
-    scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
-
-    for (mode = scrn->modes; mode; mode = mode->next)
-	if (xf86ModesEqual (mode, &crtc->desiredMode))
-	    break;
-
-    if (scrn->modes != NULL) {
-	/* For some reason, scrn->modes is circular, unlike the other mode
-	 * lists.  How great is that?
-	 */
-	for (last = scrn->modes; last && last->next; last = last->next)
-	    ;
-	last->next = scrn->modes;
-	scrn->modes->prev = last;
-	if (mode) {
-	    while (scrn->modes != mode)
-		scrn->modes = scrn->modes->next;
-	}
-    }
-    scrn->currentMode = scrn->modes;
-}
-
-/**
- * Construct default screen configuration
- *
- * Given auto-detected (and, eventually, configured) values,
- * construct a usable configuration for the system
- */
-
-Bool
-xf86InitialConfiguration (ScrnInfoPtr	    scrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o, c;
-    DisplayModePtr	target_mode = NULL;
-    xf86CrtcPtr		*crtcs;
-    DisplayModePtr	*modes;
-    Bool		*enabled;
-    int			width;
-    int			height;
-
-    if (scrn->display->virtualX)
-	width = scrn->display->virtualX;
-    else
-	width = config->maxWidth;
-    if (scrn->display->virtualY)
-	height = scrn->display->virtualY;
-    else
-	height = config->maxHeight;
-
-    xf86ProbeOutputModes (scrn, width, height);
-
-    crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
-    modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
-    enabled = xnfcalloc (config->num_output, sizeof (Bool));
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-	
-	modes[o] = NULL;
-	enabled[o] = (xf86OutputEnabled (output) &&
-		      output->status != XF86OutputStatusDisconnected);
-    }
-    
-    /*
-     * Let outputs with preferred modes drive screen size
-     */
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-
-	if (enabled[o] &&
-	    xf86OutputHasPreferredMode (output, width, height))
-	{
-	    target_mode = xf86DefaultMode (output, width, height);
-	    if (target_mode)
-	    {
-		modes[o] = target_mode;
-		config->compat_output = o;
-		break;
-	    }
-	}
-    }
-    if (!target_mode)
-    {
-	for (o = 0; o < config->num_output; o++)
-	{
-	    xf86OutputPtr output = config->output[o];
-	    if (enabled[o])
-	    {
-		target_mode = xf86DefaultMode (output, width, height);
-		if (target_mode)
-		{
-		    modes[o] = target_mode;
-		    config->compat_output = o;
-		    break;
-		}
-	    }
-	}
-    }
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-	
-	if (enabled[o] && !modes[o])
-	    modes[o] = xf86ClosestMode (output, target_mode, width, height);
-    }
-
-    /*
-     * Set the position of each output
-     */
-    if (!xf86InitialOutputPositions (scrn, modes))
-    {
-	xfree (crtcs);
-	xfree (modes);
-	return FALSE;
-    }
-	
-    /*
-     * Assign CRTCs to fit output configuration
-     */
-    if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
-    {
-	xfree (crtcs);
-	xfree (modes);
-	return FALSE;
-    }
-    
-    /* XXX override xf86 common frame computation code */
-    
-    scrn->display->frameX0 = 0;
-    scrn->display->frameY0 = 0;
-    
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr	crtc = config->crtc[c];
-
-	crtc->enabled = FALSE;
-	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
-    }
-    
-    /*
-     * Set initial configuration
-     */
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-	DisplayModePtr	mode = modes[o];
-        xf86CrtcPtr	crtc = crtcs[o];
-
-	if (mode && crtc)
-	{
-	    crtc->desiredMode = *mode;
-	    crtc->enabled = TRUE;
-	    crtc->x = output->initial_x;
-	    crtc->y = output->initial_y;
-	    output->crtc = crtc;
-	}
-    }
-    
-    if (scrn->display->virtualX == 0)
-    {
-	/*
-	 * Expand virtual size to cover potential mode switches
-	 */
-	xf86DefaultScreenLimits (scrn, &width, &height);
-    
-	scrn->display->virtualX = width;
-	scrn->display->virtualY = height;
-    }
-
-    if (width > scrn->virtualX)
-	scrn->virtualX = width;
-    if (height > scrn->virtualY)
-	scrn->virtualY = height;
-    
-    /* Mirror output modes to scrn mode list */
-    xf86SetScrnInfoModes (scrn);
-    
-    xfree (crtcs);
-    xfree (modes);
-    return TRUE;
-}
-
-/**
- * Set the DPMS power mode of all outputs and CRTCs.
- *
- * If the new mode is off, it will turn off outputs and then CRTCs.
- * Otherwise, it will affect CRTCs before outputs.
- */
-void
-xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-
-    if (!scrn->vtSema)
-	return;
-
-    if (mode == DPMSModeOff) {
-	for (i = 0; i < config->num_output; i++) {
-	    xf86OutputPtr output = config->output[i];
-	    if (output->crtc != NULL)
-		(*output->funcs->dpms) (output, mode);
-	}
-    }
-
-    for (i = 0; i < config->num_crtc; i++) {
-	xf86CrtcPtr crtc = config->crtc[i];
-	if (crtc->enabled)
-	    (*crtc->funcs->dpms) (crtc, mode);
-    }
-
-    if (mode != DPMSModeOff) {
-	for (i = 0; i < config->num_output; i++) {
-	    xf86OutputPtr output = config->output[i];
-	    if (output->crtc != NULL)
-		(*output->funcs->dpms) (output, mode);
-	}
-    }
-}
-
-/**
- * Implement the screensaver by just calling down into the driver DPMS hooks.
- *
- * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
- * the outputs will still get disabled (blanked).
- */
-Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
-    if (xf86IsUnblank(mode))
-	xf86DPMSSet(pScrn, DPMSModeOn, 0);
-    else
-	xf86DPMSSet(pScrn, DPMSModeOff, 0);
-
-    return TRUE;
-}
-
-/**
- * Disable all inactive crtcs and outputs
- */
-void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			o, c;
-
-    for (o = 0; o < xf86_config->num_output; o++) 
-    {
-	xf86OutputPtr  output = xf86_config->output[o];
-	if (!output->crtc) 
-	    (*output->funcs->dpms)(output, DPMSModeOff);
-    }
-
-    for (c = 0; c < xf86_config->num_crtc; c++) 
-    {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-	if (!crtc->enabled) 
-	{
-	    crtc->funcs->dpms(crtc, DPMSModeOff);
-	    memset(&crtc->mode, 0, sizeof(crtc->mode));
-	}
-    }
-}
-
-#ifdef RANDR_12_INTERFACE
-
-#define EDID_ATOM_NAME		"EDID_DATA"
-
-/**
- * Set the RandR EDID property
- */
-static void
-xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
-{
-    Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
-
-    /* This may get called before the RandR resources have been created */
-    if (output->randr_output == NULL)
-	return;
-
-    if (data_len != 0) {
-	RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
-			       PropModeReplace, data_len, data, FALSE);
-    } else {
-	RRDeleteOutputProperty(output->randr_output, edid_atom);
-    }
-}
-
-#endif
-
-/**
- * Set the EDID information for the specified output
- */
-void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
-{
-    ScrnInfoPtr		scrn = output->scrn;
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-#ifdef RANDR_12_INTERFACE
-    int			size;
-#endif
-    
-    if (output->MonInfo != NULL)
-	xfree(output->MonInfo);
-    
-    output->MonInfo = edid_mon;
-
-    /* Debug info for now, at least */
-    xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
-    xf86PrintEDID(edid_mon);
-    
-    /* Set the DDC properties for the 'compat' output */
-    if (output == config->output[config->compat_output])
-        xf86SetDDCproperties(scrn, edid_mon);
-
-#ifdef RANDR_12_INTERFACE
-    /* Set the RandR output properties */
-    size = 0;
-    if (edid_mon)
-    {
-	if (edid_mon->ver.version == 1)
-	    size = 128;
-	else if (edid_mon->ver.version == 2)
-	    size = 256;
-    }
-    xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
-#endif
-
-    if (edid_mon)
-    {
-	/* Pull out a phyiscal size from a detailed timing if available. */
-	for (i = 0; i < 4; i++) {
-	    if (edid_mon->det_mon[i].type == DT &&
-		edid_mon->det_mon[i].section.d_timings.h_size != 0 &&
-		edid_mon->det_mon[i].section.d_timings.v_size != 0)
-	    {
-		output->mm_width = edid_mon->det_mon[i].section.d_timings.h_size;
-		output->mm_height = edid_mon->det_mon[i].section.d_timings.v_size;
-		break;
-	    }
-	}
-    
-	/* if no mm size is available from a detailed timing, check the max size field */
-	if ((!output->mm_width || !output->mm_height) &&
-	    (edid_mon->features.hsize && edid_mon->features.vsize))
-	{
-	    output->mm_width = edid_mon->features.hsize * 10;
-	    output->mm_height = edid_mon->features.vsize * 10;
-	}
-    }
-}
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output)
-{
-    ScrnInfoPtr	scrn = output->scrn;
-    xf86MonPtr	edid_mon = output->MonInfo;
-
-    if (!edid_mon)
-	return NULL;
-    return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
-}
-
-xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
-{
-    ScrnInfoPtr	scrn = output->scrn;
-
-    return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
-}
diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h
deleted file mode 100644
index 67950da..0000000
--- a/src/radeon_xf86Crtc.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-#ifndef _XF86CRTC_H_
-#define _XF86CRTC_H_
-
-#include <edid.h>
-#include "randrstr.h"
-#include "radeon_xf86Modes.h"
-#include "xf86Parser.h"
-#include "damage.h"
-
-/* Compat definitions for older X Servers. */
-#ifndef M_T_PREFERRED
-#define M_T_PREFERRED	0x08
-#endif
-#ifndef M_T_DRIVER
-#define M_T_DRIVER	0x40
-#endif
-
-typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
-typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
-
-typedef enum _xf86OutputStatus {
-   XF86OutputStatusConnected,
-   XF86OutputStatusDisconnected,
-   XF86OutputStatusUnknown,
-} xf86OutputStatus;
-
-typedef struct _xf86CrtcFuncs {
-   /**
-    * Turns the crtc on/off, or sets intermediate power levels if available.
-    *
-    * Unsupported intermediate modes drop to the lower power setting.  If the
-    * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
-    * be safe to call mode_set.
-    */
-   void
-    (*dpms)(xf86CrtcPtr		crtc,
-	    int		    	mode);
-
-   /**
-    * Saves the crtc's state for restoration on VT switch.
-    */
-   void
-    (*save)(xf86CrtcPtr		crtc);
-
-   /**
-    * Restore's the crtc's state at VT switch.
-    */
-   void
-    (*restore)(xf86CrtcPtr	crtc);
-
-    /**
-     * Lock CRTC prior to mode setting, mostly for DRI.
-     * Returns whether unlock is needed
-     */
-    Bool
-    (*lock) (xf86CrtcPtr crtc);
-    
-    /**
-     * Unlock CRTC after mode setting, mostly for DRI
-     */
-    void
-    (*unlock) (xf86CrtcPtr crtc);
-    
-    /**
-     * Callback to adjust the mode to be set in the CRTC.
-     *
-     * This allows a CRTC to adjust the clock or even the entire set of
-     * timings, which is used for panels with fixed timings or for
-     * buses with clock limitations.
-     */
-    Bool
-    (*mode_fixup)(xf86CrtcPtr crtc,
-		  DisplayModePtr mode,
-		  DisplayModePtr adjusted_mode);
-
-    /**
-     * Callback for setting up a video mode after fixups have been made.
-     */
-    void
-    (*mode_set)(xf86CrtcPtr crtc,
-		DisplayModePtr mode,
-		DisplayModePtr adjusted_mode,
-		int x, int y);
-
-    /* Set the color ramps for the CRTC to the given values. */
-    void
-    (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
-		 int size);
-
-    /**
-     * Create shadow pixmap for rotation support
-     */
-    PixmapPtr
-    (*shadow_create) (xf86CrtcPtr crtc, int width, int height);
-    
-    /**
-     * Destroy shadow pixmap
-     */
-    void
-    (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap);
-
-    /**
-     * Clean up driver-specific bits of the crtc
-     */
-    void
-    (*destroy) (xf86CrtcPtr	crtc);
-} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
-
-struct _xf86Crtc {
-    /**
-     * Associated ScrnInfo
-     */
-    ScrnInfoPtr	    scrn;
-    
-    /**
-     * Active state of this CRTC
-     *
-     * Set when this CRTC is driving one or more outputs 
-     */
-    Bool	    enabled;
-    
-    /** Track whether cursor is within CRTC range  */
-    Bool	    cursorInRange;
-    
-    /** Track state of cursor associated with this CRTC */
-    Bool	    cursorShown;
-    
-    /**
-     * Active mode
-     *
-     * This reflects the mode as set in the CRTC currently
-     * It will be cleared when the VT is not active or
-     * during server startup
-     */
-    DisplayModeRec  mode;
-    Rotation	    rotation;
-    PixmapPtr	    rotatedPixmap;
-    /**
-     * Position on screen
-     *
-     * Locates this CRTC within the frame buffer
-     */
-    int		    x, y;
-    
-    /**
-     * Desired mode
-     *
-     * This is set to the requested mode, independent of
-     * whether the VT is active. In particular, it receives
-     * the startup configured mode and saves the active mode
-     * on VT switch.
-     */
-    DisplayModeRec  desiredMode;
-    Rotation	    desiredRotation;
-    int		    desiredX, desiredY;
-    
-    /** crtc-specific functions */
-    const xf86CrtcFuncsRec *funcs;
-
-    /**
-     * Driver private
-     *
-     * Holds driver-private information
-     */
-    void	    *driver_private;
-
-#ifdef RANDR_12_INTERFACE
-    /**
-     * RandR crtc
-     *
-     * When RandR 1.2 is available, this
-     * points at the associated crtc object
-     */
-    RRCrtcPtr	    randr_crtc;
-#else
-    void	    *randr_crtc;
-#endif
-};
-
-typedef struct _xf86OutputFuncs {
-    /**
-     * Called to allow the output a chance to create properties after the
-     * RandR objects have been created.
-     */
-    void
-    (*create_resources)(xf86OutputPtr output);
-
-    /**
-     * Turns the output on/off, or sets intermediate power levels if available.
-     *
-     * Unsupported intermediate modes drop to the lower power setting.  If the
-     * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
-     * disabled afterwards.
-     */
-    void
-    (*dpms)(xf86OutputPtr	output,
-	    int			mode);
-
-    /**
-     * Saves the output's state for restoration on VT switch.
-     */
-    void
-    (*save)(xf86OutputPtr	output);
-
-    /**
-     * Restore's the output's state at VT switch.
-     */
-    void
-    (*restore)(xf86OutputPtr	output);
-
-    /**
-     * Callback for testing a video mode for a given output.
-     *
-     * This function should only check for cases where a mode can't be supported
-     * on the output specifically, and not represent generic CRTC limitations.
-     *
-     * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
-     */
-    int
-    (*mode_valid)(xf86OutputPtr	    output,
-		  DisplayModePtr    pMode);
-
-    /**
-     * Callback to adjust the mode to be set in the CRTC.
-     *
-     * This allows an output to adjust the clock or even the entire set of
-     * timings, which is used for panels with fixed timings or for
-     * buses with clock limitations.
-     */
-    Bool
-    (*mode_fixup)(xf86OutputPtr output,
-		  DisplayModePtr mode,
-		  DisplayModePtr adjusted_mode);
-
-    /**
-     * Callback for setting up a video mode after fixups have been made.
-     *
-     * This is only called while the output is disabled.  The dpms callback
-     * must be all that's necessary for the output, to turn the output on
-     * after this function is called.
-     */
-    void
-    (*mode_set)(xf86OutputPtr  output,
-		DisplayModePtr mode,
-		DisplayModePtr adjusted_mode);
-
-    /**
-     * Probe for a connected output, and return detect_status.
-     */
-    xf86OutputStatus
-    (*detect)(xf86OutputPtr	    output);
-
-    /**
-     * Query the device for the modes it provides.
-     *
-     * This function may also update MonInfo, mm_width, and mm_height.
-     *
-     * \return singly-linked list of modes or NULL if no modes found.
-     */
-    DisplayModePtr
-    (*get_modes)(xf86OutputPtr	    output);
-
-#ifdef RANDR_12_INTERFACE
-    /**
-     * Callback when an output's property has changed.
-     */
-    Bool
-    (*set_property)(xf86OutputPtr output,
-		    Atom property,
-		    RRPropertyValuePtr value);
-#endif
-    /**
-     * Clean up driver-specific bits of the output
-     */
-    void
-    (*destroy) (xf86OutputPtr	    output);
-} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
-
-struct _xf86Output {
-    /**
-     * Associated ScrnInfo
-     */
-    ScrnInfoPtr		scrn;
-
-    /**
-     * Currently connected crtc (if any)
-     *
-     * If this output is not in use, this field will be NULL.
-     */
-    xf86CrtcPtr		crtc;
-
-    /**
-     * Possible CRTCs for this output as a mask of crtc indices
-     */
-    CARD32		possible_crtcs;
-
-    /**
-     * Possible outputs to share the same CRTC as a mask of output indices
-     */
-    CARD32		possible_clones;
-    
-    /**
-     * Whether this output can support interlaced modes
-     */
-    Bool		interlaceAllowed;
-
-    /**
-     * Whether this output can support double scan modes
-     */
-    Bool		doubleScanAllowed;
-
-    /**
-     * List of available modes on this output.
-     *
-     * This should be the list from get_modes(), plus perhaps additional
-     * compatible modes added later.
-     */
-    DisplayModePtr	probed_modes;
-
-    /**
-     * Options parsed from the related monitor section
-     */
-    OptionInfoPtr	options;
-    
-    /**
-     * Configured monitor section
-     */
-    XF86ConfMonitorPtr  conf_monitor;
-    
-    /**
-     * Desired initial position
-     */
-    int			initial_x, initial_y;
-
-    /**
-     * Current connection status
-     *
-     * This indicates whether a monitor is known to be connected
-     * to this output or not, or whether there is no way to tell
-     */
-    xf86OutputStatus	status;
-
-    /** EDID monitor information */
-    xf86MonPtr		MonInfo;
-
-    /** subpixel order */
-    int			subpixel_order;
-
-    /** Physical size of the currently attached output device. */
-    int			mm_width, mm_height;
-
-    /** Output name */
-    char		*name;
-
-    /** output-specific functions */
-    const xf86OutputFuncsRec *funcs;
-
-    /** driver private information */
-    void		*driver_private;
-    
-#ifdef RANDR_12_INTERFACE
-    /**
-     * RandR 1.2 output structure.
-     *
-     * When RandR 1.2 is available, this points at the associated
-     * RandR output structure and is created when this output is created
-     */
-    RROutputPtr		randr_output;
-#else
-    void		*randr_output;
-#endif
-};
-
-typedef struct _xf86CrtcConfig {
-    int			num_output;
-    xf86OutputPtr	*output;
-    /**
-     * compat_output is used whenever we deal
-     * with legacy code that only understands a single
-     * output. pScrn->modes will be loaded from this output,
-     * adjust frame will whack this output, etc.
-     */
-    int			compat_output;
-
-    int			num_crtc;
-    xf86CrtcPtr		*crtc;
-
-    int			minWidth, minHeight;
-    int			maxWidth, maxHeight;
-    
-    /* For crtc-based rotation */
-    DamagePtr   rotationDamage;
-
-    /* DGA */
-    unsigned int dga_flags;
-
-} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
-
-extern int xf86CrtcConfigPrivateIndex;
-
-#define XF86_CRTC_CONFIG_PTR(p)	((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
-
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-void
-xf86CrtcConfigInit (ScrnInfoPtr		scrn);
-
-void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
-		      int minWidth, int minHeight,
-		      int maxWidth, int maxHeight);
-
-/*
- * Crtc functions
- */
-xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr		scrn,
-		const xf86CrtcFuncsRec	*funcs);
-
-void
-xf86CrtcDestroy (xf86CrtcPtr		crtc);
-
-
-/**
- * Allocate a crtc for the specified output
- *
- * Find a currently unused CRTC which is suitable for
- * the specified output
- */
-
-xf86CrtcPtr 
-xf86AllocCrtc (xf86OutputPtr		output);
-
-/**
- * Free a crtc
- *
- * Mark the crtc as unused by any outputs
- */
-
-void
-xf86FreeCrtc (xf86CrtcPtr		crtc);
-
-/**
- * Sets the given video mode on the given crtc
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-		 int x, int y);
-
-/*
- * Assign crtc rotation during mode set
- */
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
-
-/**
- * Return whether any output is assigned to the crtc
- */
-Bool
-xf86CrtcInUse (xf86CrtcPtr crtc);
-
-/*
- * Output functions
- */
-xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr		scrn,
-		      const xf86OutputFuncsRec *funcs,
-		      const char	*name);
-
-Bool
-xf86OutputRename (xf86OutputPtr output, const char *name);
-
-void
-xf86OutputDestroy (xf86OutputPtr	output);
-
-void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
-
-void
-xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
-
-Bool
-xf86InitialConfiguration (ScrnInfoPtr pScrn);
-
-void
-xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
-    
-Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode);
-
-void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
-
-/**
- * Set the EDID information for the specified output
- */
-void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output);
-
-xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
-
-#endif /* _XF86CRTC_H_ */
diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c
deleted file mode 100644
index ce9151b..0000000
--- a/src/radeon_xf86Modes.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/* -*- c-basic-offset: 4 -*- */
-/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.10 2006/03/07 16:00:57 libv Exp $ */
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "radeon.h"
-#include "radeon_xf86Modes.h"
-#include "xf86Priv.h"
-
-extern XF86ConfigPtr xf86configptr;
-
-/**
- * @file this file contains symbols from xf86Mode.c and friends that are static
- * there but we still want to use.  We need to come up with better API here.
- */
-
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-/**
- * Calculates the horizontal sync rate of a mode.
- *
- * Exact copy of xf86Mode.c's.
- */
-double
-xf86ModeHSync(DisplayModePtr mode)
-{
-    double hsync = 0.0;
-    
-    if (mode->HSync > 0.0)
-	    hsync = mode->HSync;
-    else if (mode->HTotal > 0)
-	    hsync = (float)mode->Clock / (float)mode->HTotal;
-
-    return hsync;
-}
-
-/**
- * Calculates the vertical refresh rate of a mode.
- *
- * Exact copy of xf86Mode.c's.
- */
-double
-xf86ModeVRefresh(DisplayModePtr mode)
-{
-    double refresh = 0.0;
-
-    if (mode->VRefresh > 0.0)
-	refresh = mode->VRefresh;
-    else if (mode->HTotal > 0 && mode->VTotal > 0) {
-	refresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;
-	if (mode->Flags & V_INTERLACE)
-	    refresh *= 2.0;
-	if (mode->Flags & V_DBLSCAN)
-	    refresh /= 2.0;
-	if (mode->VScan > 1)
-	    refresh /= (float)(mode->VScan);
-    }
-    return refresh;
-}
-
-/** Sets a default mode name of <width>x<height> on a mode. */
-void
-xf86SetModeDefaultName(DisplayModePtr mode)
-{
-    if (mode->name != NULL)
-	xfree(mode->name);
-
-    mode->name = XNFprintf("%dx%d", mode->HDisplay, mode->VDisplay);
-}
-
-/*
- * xf86SetModeCrtc
- *
- * Initialises the Crtc parameters for a mode.  The initialisation includes
- * adjustments for interlaced and double scan modes.
- *
- * Exact copy of xf86Mode.c's.
- */
-void
-xf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
-{
-    if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN))
-	return;
-
-    p->CrtcHDisplay             = p->HDisplay;
-    p->CrtcHSyncStart           = p->HSyncStart;
-    p->CrtcHSyncEnd             = p->HSyncEnd;
-    p->CrtcHTotal               = p->HTotal;
-    p->CrtcHSkew                = p->HSkew;
-    p->CrtcVDisplay             = p->VDisplay;
-    p->CrtcVSyncStart           = p->VSyncStart;
-    p->CrtcVSyncEnd             = p->VSyncEnd;
-    p->CrtcVTotal               = p->VTotal;
-    if (p->Flags & V_INTERLACE) {
-	if (adjustFlags & INTERLACE_HALVE_V) {
-	    p->CrtcVDisplay         /= 2;
-	    p->CrtcVSyncStart       /= 2;
-	    p->CrtcVSyncEnd         /= 2;
-	    p->CrtcVTotal           /= 2;
-	}
-	/* Force interlaced modes to have an odd VTotal */
-	/* maybe we should only do this when INTERLACE_HALVE_V is set? */
-	p->CrtcVTotal |= 1;
-    }
-
-    if (p->Flags & V_DBLSCAN) {
-        p->CrtcVDisplay         *= 2;
-        p->CrtcVSyncStart       *= 2;
-        p->CrtcVSyncEnd         *= 2;
-        p->CrtcVTotal           *= 2;
-    }
-    if (p->VScan > 1) {
-        p->CrtcVDisplay         *= p->VScan;
-        p->CrtcVSyncStart       *= p->VScan;
-        p->CrtcVSyncEnd         *= p->VScan;
-        p->CrtcVTotal           *= p->VScan;
-    }
-    p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
-    p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
-    p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
-    p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
-
-    p->CrtcHAdjusted = FALSE;
-    p->CrtcVAdjusted = FALSE;
-}
-
-/**
- * Allocates and returns a copy of pMode, including pointers within pMode.
- */
-DisplayModePtr
-xf86DuplicateMode(DisplayModePtr pMode)
-{
-    DisplayModePtr pNew;
-
-    pNew = xnfalloc(sizeof(DisplayModeRec));
-    *pNew = *pMode;
-    pNew->next = NULL;
-    pNew->prev = NULL;
-    if (pNew->name == NULL) {
-	xf86SetModeDefaultName(pMode);
-    } else {
-	pNew->name = xnfstrdup(pMode->name);
-    }
-
-    return pNew;
-}
-
-/**
- * Duplicates every mode in the given list and returns a pointer to the first
- * mode.
- *
- * \param modeList doubly-linked mode list
- */
-DisplayModePtr
-xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
-    DisplayModePtr first = NULL, last = NULL;
-    DisplayModePtr mode;
-
-    for (mode = modeList; mode != NULL; mode = mode->next) {
-	DisplayModePtr new;
-
-	new = xf86DuplicateMode(mode);
-
-	/* Insert pNew into modeList */
-	if (last) {
-	    last->next = new;
-	    new->prev = last;
-	} else {
-	    first = new;
-	    new->prev = NULL;
-	}
-	new->next = NULL;
-	last = new;
-    }
-
-    return first;
-}
-
-/**
- * Returns true if the given modes should program to the same timings.
- *
- * This doesn't use Crtc values, as it might be used on ModeRecs without the
- * Crtc values set.  So, it's assumed that the other numbers are enough.
- *
- * This isn't in xf86Modes.c, but it might deserve to be there.
- */
-Bool
-xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2)
-{
-     if (pMode1->Clock == pMode2->Clock &&
-	 pMode1->HDisplay == pMode2->HDisplay &&
-	 pMode1->HSyncStart == pMode2->HSyncStart &&
-	 pMode1->HSyncEnd == pMode2->HSyncEnd &&
-	 pMode1->HTotal == pMode2->HTotal &&
-	 pMode1->HSkew == pMode2->HSkew &&
-	 pMode1->VDisplay == pMode2->VDisplay &&
-	 pMode1->VSyncStart == pMode2->VSyncStart &&
-	 pMode1->VSyncEnd == pMode2->VSyncEnd &&
-	 pMode1->VTotal == pMode2->VTotal &&
-	 pMode1->VScan == pMode2->VScan &&
-	 pMode1->Flags == pMode2->Flags)
-     {
-	return TRUE;
-     } else {
-	return FALSE;
-     }
-}
-
-/* exact copy of xf86Mode.c */
-static void
-add(char **p, char *new)
-{
-    *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2);
-    strcat(*p, " ");
-    strcat(*p, new);
-}
-
-/**
- * Print out a modeline.
- *
- * Convenient VRefresh printing was added, though, compared to xf86Mode.c
- */
-void
-xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
-{
-    char tmp[256];
-    char *flags = xnfcalloc(1, 1);
-
-    if (mode->HSkew) { 
-	snprintf(tmp, 256, "hskew %i", mode->HSkew); 
-	add(&flags, tmp);
-    }
-    if (mode->VScan) { 
-	snprintf(tmp, 256, "vscan %i", mode->VScan); 
-	add(&flags, tmp);
-    }
-    if (mode->Flags & V_INTERLACE) add(&flags, "interlace");
-    if (mode->Flags & V_CSYNC) add(&flags, "composite");
-    if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan");
-    if (mode->Flags & V_BCAST) add(&flags, "bcast");
-    if (mode->Flags & V_PHSYNC) add(&flags, "+hsync");
-    if (mode->Flags & V_NHSYNC) add(&flags, "-hsync");
-    if (mode->Flags & V_PVSYNC) add(&flags, "+vsync");
-    if (mode->Flags & V_NVSYNC) add(&flags, "-vsync");
-    if (mode->Flags & V_PCSYNC) add(&flags, "+csync");
-    if (mode->Flags & V_NCSYNC) add(&flags, "-csync");
-#if 0
-    if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2");
-#endif
-    xf86DrvMsg(scrnIndex, X_INFO,
-		   "Modeline \"%s\"x%.01f  %6.2f  %i %i %i %i  %i %i %i %i%s "
-		   "(%.01f kHz)\n",
-		   mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
-		   mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
-		   mode->VDisplay, mode->VSyncStart, mode->VSyncEnd,
-		   mode->VTotal, flags, xf86ModeHSync(mode));
-    xfree(flags);
-}
-#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
-
-/**
- * Marks as bad any modes with unsupported flags.
- *
- * \param modeList doubly-linked or circular list of modes.
- * \param flags flags supported by the driver.
- *
- * \bug only V_INTERLACE and V_DBLSCAN are supported.  Is that enough?
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			    int flags)
-{
-    DisplayModePtr mode;
-
-    for (mode = modeList; mode != NULL; mode = mode->next) {
-	if (mode->Flags & V_INTERLACE && !(flags & V_INTERLACE))
-	    mode->status = MODE_NO_INTERLACE;
-	if (mode->Flags & V_DBLSCAN && !(flags & V_DBLSCAN))
-	    mode->status = MODE_NO_DBLESCAN;
-    }
-}
-
-/**
- * Marks as bad any modes extending beyond the given max X, Y, or pitch.
- *
- * \param modeList doubly-linked or circular list of modes.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			  int maxX, int maxY, int maxPitch)
-{
-    DisplayModePtr mode;
-
-    for (mode = modeList; mode != NULL; mode = mode->next) {
-	if (maxPitch > 0 && mode->HDisplay > maxPitch)
-	    mode->status = MODE_BAD_WIDTH;
-
-	if (maxX > 0 && mode->HDisplay > maxX)
-	    mode->status = MODE_VIRTUAL_X;
-
-	if (maxY > 0 && mode->VDisplay > maxY)
-	    mode->status = MODE_VIRTUAL_Y;
-
-	if (mode->next == modeList)
-	    break;
-    }
-}
-
-/**
- * Marks as bad any modes that aren't supported by the given monitor's
- * hsync and vrefresh ranges.
- *
- * \param modeList doubly-linked or circular list of modes.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			  MonPtr mon)
-{
-    DisplayModePtr mode;
-
-    for (mode = modeList; mode != NULL; mode = mode->next) {
-	Bool bad;
-	int i;
-
-	bad = TRUE;
-	for (i = 0; i < mon->nHsync; i++) {
-	    if (xf86ModeHSync(mode) >= mon->hsync[i].lo &&
-		xf86ModeHSync(mode) <= mon->hsync[i].hi)
-	    {
-		bad = FALSE;
-	    }
-	}
-	if (bad)
-	    mode->status = MODE_HSYNC;
-
-	bad = TRUE;
-	for (i = 0; i < mon->nVrefresh; i++) {
-	    if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
-		xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
-	    {
-		bad = FALSE;
-	    }
-	}
-	if (bad)
-	    mode->status = MODE_VSYNC;
-
-	if (mode->next == modeList)
-	    break;
-    }
-}
-
-/**
- * Marks as bad any modes extending beyond outside of the given clock ranges.
- *
- * \param modeList doubly-linked or circular list of modes.
- * \param min pointer to minimums of clock ranges
- * \param max pointer to maximums of clock ranges
- * \param n_ranges number of ranges.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			    int *min, int *max, int n_ranges)
-{
-    DisplayModePtr mode;
-    int i;
-
-    for (mode = modeList; mode != NULL; mode = mode->next) {
-	Bool good = FALSE;
-	for (i = 0; i < n_ranges; i++) {
-	    if (mode->Clock >= min[i] && mode->Clock <= max[i]) {
-		good = TRUE;
-		break;
-	    }
-	}
-	if (!good)
-	    mode->status = MODE_CLOCK_RANGE;
-    }
-}
-
-/**
- * If the user has specified a set of mode names to use, mark as bad any modes
- * not listed.
- *
- * The user mode names specified are prefixes to names of modes, so "1024x768"
- * will match modes named "1024x768", "1024x768x75", "1024x768-good", but
- * "1024x768x75" would only match "1024x768x75" from that list.
- *
- * MODE_BAD is used as the rejection flag, for lack of a better flag.
- *
- * \param modeList doubly-linked or circular list of modes.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
-    DisplayModePtr mode;
-
-    if (pScrn->display->modes[0] == NULL)
-	return;
-
-    for (mode = modeList; mode != NULL; mode = mode->next) {
-	int i;
-	Bool good = FALSE;
-
-	for (i = 0; pScrn->display->modes[i] != NULL; i++) {
-	    if (strncmp(pScrn->display->modes[i], mode->name,
-			strlen(pScrn->display->modes[i])) == 0) {
-		good = TRUE;
-		break;
-	    }
-	}
-	if (!good)
-	    mode->status = MODE_BAD;
-    }
-}
-
-
-/**
- * Frees any modes from the list with a status other than MODE_OK.
- *
- * \param modeList pointer to a doubly-linked or circular list of modes.
- * \param verbose determines whether the reason for mode invalidation is
- *	  printed.
- *
- * This is not in xf86Modes.c, but would be part of the proposed new API.
- */
-void
-xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
-			  Bool verbose)
-{
-    DisplayModePtr mode;
-
-    for (mode = *modeList; mode != NULL;) {
-	DisplayModePtr next = mode->next, first = *modeList;
-
-	if (mode->status != MODE_OK) {
-	    if (verbose) {
-		char *type = "";
-		if (mode->type & M_T_BUILTIN)
-		    type = "built-in ";
-		else if (mode->type & M_T_DEFAULT)
-		    type = "default ";
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			   "Not using %smode \"%s\" (%s)\n", type, mode->name,
-			   xf86ModeStatusToString(mode->status));
-	    }
-	    xf86DeleteMode(modeList, mode);
-	}
-
-	if (next == first)
-	    break;
-	mode = next;
-    }
-}
-
-/**
- * Adds the new mode into the mode list, and returns the new list
- *
- * \param modes doubly-linked mode list.
- */
-DisplayModePtr
-xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
-{
-    if (modes == NULL)
-	return new;
-
-    if (new) {
-	DisplayModePtr mode = modes;
-
-	while (mode->next)
-	    mode = mode->next;
-
-	mode->next = new;
-	new->prev = mode;
-    }
-
-    return modes;
-}
-
-/**
- * Build a mode list from a list of config file modes
- */
-static DisplayModePtr
-xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
-{
-    DisplayModePtr  head = NULL, prev = NULL, mode;
-    
-    for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
-    {
-        mode = xcalloc(1, sizeof(DisplayModeRec));
-	if (!mode)
-	    continue;
-        mode->name       = xstrdup(conf_mode->ml_identifier);
-	if (!mode->name)
-	{
-	    xfree (mode);
-	    continue;
-	}
-	mode->type       = 0;
-        mode->Clock      = conf_mode->ml_clock;
-        mode->HDisplay   = conf_mode->ml_hdisplay;
-        mode->HSyncStart = conf_mode->ml_hsyncstart;
-        mode->HSyncEnd   = conf_mode->ml_hsyncend;
-        mode->HTotal     = conf_mode->ml_htotal;
-        mode->VDisplay   = conf_mode->ml_vdisplay;
-        mode->VSyncStart = conf_mode->ml_vsyncstart;
-        mode->VSyncEnd   = conf_mode->ml_vsyncend;
-        mode->VTotal     = conf_mode->ml_vtotal;
-        mode->Flags      = conf_mode->ml_flags;
-        mode->HSkew      = conf_mode->ml_hskew;
-        mode->VScan      = conf_mode->ml_vscan;
-
-        mode->prev = prev;
-	mode->next = NULL;
-	if (prev)
-	    prev->next = mode;
-	else
-	    head = mode;
-	prev = mode;
-    }
-    return head;
-}
-
-/**
- * Build a mode list from a monitor configuration
- */
-DisplayModePtr
-xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
-{
-    DisplayModePtr	    modes = NULL;
-    XF86ConfModesLinkPtr    modes_link;
-    
-    if (!conf_monitor)
-	return NULL;
-
-    /*
-     * first we collect the mode lines from the UseModes directive
-     */
-    for (modes_link = conf_monitor->mon_modes_sect_lst; 
-	 modes_link; 
-	 modes_link = modes_link->list.next)
-    {
-	/* If this modes link hasn't been resolved, go look it up now */
-	if (!modes_link->ml_modes)
-	    modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str, 
-						  xf86configptr->conf_modes_lst);
-	if (modes_link->ml_modes)
-	    modes = xf86ModesAdd (modes,
-				  xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
-    }
-
-    return xf86ModesAdd (modes,
-			 xf86GetConfigModes (conf_monitor->mon_modeline_lst));
-}
-
-/**
- * Build a mode list containing all of the default modes
- */
-DisplayModePtr
-xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
-{
-    DisplayModePtr  head = NULL, prev = NULL, mode;
-    int		    i;
-
-    for (i = 0; xf86DefaultModes[i].name != NULL; i++)
-    {
-	DisplayModePtr	defMode = &xf86DefaultModes[i];
-	
-	if (!interlaceAllowed && (defMode->Flags & V_INTERLACE))
-	    continue;
-	if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN))
-	    continue;
-
-	mode = xalloc(sizeof(DisplayModeRec));
-	if (!mode)
-	    continue;
-        memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec));
-        mode->name = xstrdup(xf86DefaultModes[i].name);
-        if (!mode->name)
-	{
-	    xfree (mode);
-	    continue;
-	}
-        mode->prev = prev;
-	mode->next = NULL;
-	if (prev)
-	    prev->next = mode;
-	else
-	    head = mode;
-	prev = mode;
-    }
-    return head;
-}
diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h
deleted file mode 100644
index 6668f44..0000000
--- a/src/radeon_xf86Modes.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- *    Eric Anholt <eric at anholt.net>
- *
- */
-
-#ifndef _RADEON_XF86MODES_H_
-#define _RADEON_XF86MODES_H_
-#include "xorgVersion.h"
-#include "xf86Parser.h"
-#include "radeon_xf86Rename.h"
-
-double xf86ModeHSync(DisplayModePtr mode);
-double xf86ModeVRefresh(DisplayModePtr mode);
-DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode);
-DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn,
-				       DisplayModePtr modeList);
-void xf86SetModeDefaultName(DisplayModePtr mode);
-void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
-void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
-DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
-
-DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
-DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
-			   Bool Reduced, Bool Interlaced);
-
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-		       int flags);
-
-void
-xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			int *min, int *max, int n_ranges);
-
-void
-xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-		      int maxX, int maxY, int maxPitch);
-
-void
-xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-		      MonPtr mon);
-
-void
-xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
-		      Bool verbose);
-
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-		       int flags);
-
-void
-xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
-
-DisplayModePtr
-xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
-
-DisplayModePtr
-xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
-
-#endif
diff --git a/src/radeon_xf86Rename.h b/src/radeon_xf86Rename.h
deleted file mode 100644
index cf8de62..0000000
--- a/src/radeon_xf86Rename.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifndef _XF86RENAME_H_
-#define _XF86RENAME_H_
-
-#include "local_xf86Rename.h"
-
-#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit)
-#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex)
-#define xf86CrtcCreate XF86NAME(xf86CrtcCreate)
-#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy)
-#define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
-#define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
-#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
-#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
-#define xf86CVTMode XF86NAME(xf86CVTMode)
-#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions)
-#define xf86DPMSSet XF86NAME(xf86DPMSSet)
-#define xf86DuplicateMode XF86NAME(xf86DuplicateMode)
-#define xf86DuplicateModes XF86NAME(xf86DuplicateModes)
-#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes)
-#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes)
-#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration)
-#define xf86ModeHSync XF86NAME(xf86ModeHSync)
-#define xf86ModesAdd XF86NAME(xf86ModesAdd)
-#define xf86ModesEqual XF86NAME(xf86ModesEqual)
-#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh)
-#define xf86OutputCreate XF86NAME(xf86OutputCreate)
-#define xf86OutputDestroy XF86NAME(xf86OutputDestroy)
-#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID)
-#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes)
-#define xf86OutputRename XF86NAME(xf86OutputRename)
-#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID)
-#define xf86PrintModeline XF86NAME(xf86PrintModeline)
-#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes)
-#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes)
-#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc)
-#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName)
-#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes)
-#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks)
-#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags)
-#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize)
-#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync)
-#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig)
-
-#endif /* _XF86RENAME_H_ */
diff --git a/src/radeon_xf86Rotate.c b/src/radeon_xf86Rotate.c
deleted file mode 100644
index 102b508..0000000
--- a/src/radeon_xf86Rotate.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-/*#include "i830.h" */
-#include "radeon_xf86Crtc.h"
-#include "radeon_xf86Modes.h"
-//#include "i830_randr.h"
-#include "X11/extensions/render.h"
-#define DPMS_SERVER
-#include "X11/extensions/dpms.h"
-#include "X11/Xatom.h"
-
-static int
-mode_height (DisplayModePtr mode, Rotation rotation)
-{
-    switch (rotation & 0xf) {
-    case RR_Rotate_0:
-    case RR_Rotate_180:
-	return mode->VDisplay;
-    case RR_Rotate_90:
-    case RR_Rotate_270:
-	return mode->HDisplay;
-    default:
-	return 0;
-    }
-}
-
-static int
-mode_width (DisplayModePtr mode, Rotation rotation)
-{
-    switch (rotation & 0xf) {
-    case RR_Rotate_0:
-    case RR_Rotate_180:
-	return mode->HDisplay;
-    case RR_Rotate_90:
-    case RR_Rotate_270:
-	return mode->VDisplay;
-    default:
-	return 0;
-    }
-}
-
-/* borrowed from composite extension, move to Render and publish? */
-
-static VisualPtr
-compGetWindowVisual (WindowPtr pWin)
-{
-    ScreenPtr	    pScreen = pWin->drawable.pScreen;
-    VisualID	    vid = wVisual (pWin);
-    int		    i;
-
-    for (i = 0; i < pScreen->numVisuals; i++)
-	if (pScreen->visuals[i].vid == vid)
-	    return &pScreen->visuals[i];
-    return 0;
-}
-
-static PictFormatPtr
-compWindowFormat (WindowPtr pWin)
-{
-    ScreenPtr	pScreen = pWin->drawable.pScreen;
-    
-    return PictureMatchVisual (pScreen, pWin->drawable.depth,
-			       compGetWindowVisual (pWin));
-}
-
-static void
-xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation,
-	       int dest_width, int dest_height)
-{
-    switch (rotation & 0xf) {
-    default:
-    case RR_Rotate_0:
-	*dst = *src;
-	break;
-    case RR_Rotate_90:
-	dst->x1 = src->y1;
-	dst->y1 = dest_height - src->x2;
-	dst->x2 = src->y2;
-	dst->y2 = dest_height - src->x1;
-	break;
-    case RR_Rotate_180:
-	dst->x1 = dest_width - src->x2;
-	dst->y1 = dest_height - src->y2;
-	dst->x2 = dest_width - src->x1;
-	dst->y2 = dest_height - src->y1;
-	break;
-    case RR_Rotate_270:
-	dst->x1 = dest_width - src->y2;
-	dst->y1 = src->x1;
-	dst->y2 = src->x2;
-	dst->x2 = dest_width - src->y1;
-	break;
-    }
-    if (rotation & RR_Reflect_X) {
-	int x1 = dst->x1;
-	dst->x1 = dest_width - dst->x2;
-	dst->x2 = dest_width - x1;
-    }
-    if (rotation & RR_Reflect_Y) {
-	int y1 = dst->y1;
-	dst->y1 = dest_height - dst->y2;
-	dst->y2 = dest_height - y1;
-    }
-}
-
-static void
-xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
-{
-    ScrnInfoPtr		scrn = crtc->scrn;
-    ScreenPtr		screen = scrn->pScreen;
-    WindowPtr		root = WindowTable[screen->myNum];
-    PixmapPtr		dst_pixmap = crtc->rotatedPixmap;
-    PictFormatPtr	format = compWindowFormat (WindowTable[screen->myNum]);
-    int			error;
-    PicturePtr		src, dst;
-    PictTransform	transform;
-    int			n = REGION_NUM_RECTS(region);
-    BoxPtr		b = REGION_RECTS(region);
-    XID			include_inferiors = IncludeInferiors;
-    
-    src = CreatePicture (None,
-			 &root->drawable,
-			 format,
-			 CPSubwindowMode,
-			 &include_inferiors,
-			 serverClient,
-			 &error);
-    if (!src) {
-	ErrorF("couldn't create src pict\n");
-	return;
-    }
-    dst = CreatePicture (None,
-			 &dst_pixmap->drawable,
-			 format,
-			 0L,
-			 NULL,
-			 serverClient,
-			 &error);
-    if (!dst) {
-	ErrorF("couldn't create src pict\n");
-	return;
-    }
-
-    memset (&transform, '\0', sizeof (transform));
-    transform.matrix[2][2] = IntToxFixed(1);
-    transform.matrix[0][2] = IntToxFixed(crtc->x);
-    transform.matrix[1][2] = IntToxFixed(crtc->y);
-    switch (crtc->rotation & 0xf) {
-    default:
-    case RR_Rotate_0:
-	transform.matrix[0][0] = IntToxFixed(1);
-	transform.matrix[1][1] = IntToxFixed(1);
-	break;
-    case RR_Rotate_90:
-	transform.matrix[0][1] = IntToxFixed(-1);
-	transform.matrix[1][0] = IntToxFixed(1);
-	transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay);
-	break;
-    case RR_Rotate_180:
-	transform.matrix[0][0] = IntToxFixed(-1);
-	transform.matrix[1][1] = IntToxFixed(-1);
-	transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay);
-	transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
-	break;
-    case RR_Rotate_270:
-	transform.matrix[0][1] = IntToxFixed(1);
-	transform.matrix[1][0] = IntToxFixed(-1);
-	transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
-	break;
-    }
-
-    /* handle reflection */
-    if (crtc->rotation & RR_Reflect_X)
-    {
-	/* XXX figure this out */
-    }
-    if (crtc->rotation & RR_Reflect_Y)
-    {
-	/* XXX figure this out too */
-    }
-
-    error = SetPictureTransform (src, &transform);
-    if (error) {
-	ErrorF("Couldn't set transform\n");
-	return;
-    }
-
-    while (n--)
-    {
-	BoxRec	dst_box;
-
-	xf86RotateBox (&dst_box, b, crtc->rotation,
-		       crtc->mode.HDisplay, crtc->mode.VDisplay);
-	CompositePicture (PictOpSrc,
-			  src, NULL, dst,
-			  dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
-			  dst_box.x2 - dst_box.x1,
-			  dst_box.y2 - dst_box.y1);
-	b++;
-    }
-    FreePicture (src, None);
-    FreePicture (dst, None);
-}
-
-static void
-xf86RotateRedisplay(ScreenPtr pScreen)
-{
-    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    DamagePtr		damage = xf86_config->rotationDamage;
-    RegionPtr		region;
-
-    if (!damage)
-	return;
-    region = DamageRegion(damage);
-    if (REGION_NOTEMPTY(pScreen, region)) 
-    {
-	int		    c;
-	
-	for (c = 0; c < xf86_config->num_crtc; c++)
-	{
-	    xf86CrtcPtr	    crtc = xf86_config->crtc[c];
-
-	    if (crtc->rotation != RR_Rotate_0)
-	    {
-		BoxRec	    box;
-		RegionRec   crtc_damage;
-
-		/* compute portion of damage that overlaps crtc */
-		box.x1 = crtc->x;
-		box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation);
-		box.y1 = crtc->y;
-		box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation);
-		REGION_INIT(pScreen, &crtc_damage, &box, 1);
-		REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
-		
-		/* update damaged region */
-		if (REGION_NOTEMPTY(pScreen, &crtc_damage))
-    		    xf86RotateCrtcRedisplay (crtc, &crtc_damage);
-		
-		REGION_UNINIT (pScreen, &crtc_damage);
-	    }
-	}
-	DamageEmpty(damage);
-    }
-}
-
-static void
-xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
-{
-    ScreenPtr pScreen = (ScreenPtr) data;
-
-    xf86RotateRedisplay(pScreen);
-}
-
-static void
-xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
-{
-}
-
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
-{
-    ScrnInfoPtr		pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    ScreenPtr		pScreen = pScrn->pScreen;
-    
-    if (rotation == RR_Rotate_0)
-    {
-	/* Free memory from rotation */
-	if (crtc->rotatedPixmap)
-	{
-	    crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap);
-	    crtc->rotatedPixmap = NULL;
-	}
-
-	if (xf86_config->rotationDamage)
-	{
-	    /* Free damage structure */
-	    DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
-			      xf86_config->rotationDamage);
-	    DamageDestroy (xf86_config->rotationDamage);
-	    xf86_config->rotationDamage = NULL;
-	    /* Free block/wakeup handler */
-	    RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
-					  xf86RotateWakeupHandler,
-					  (pointer) pScreen);
-	}
-    }
-    else
-    {
-	/* 
-	 * these are the size of the shadow pixmap, which
-	 * matches the mode, not the pre-rotated copy in the
-	 * frame buffer
-	 */
-	int	    width = mode->HDisplay;
-	int	    height = mode->VDisplay;
-	PixmapPtr   shadow = crtc->rotatedPixmap;
-	int	    old_width = shadow ? shadow->drawable.width : 0;
-	int	    old_height = shadow ? shadow->drawable.height : 0;
-	BoxRec	    damage_box;
-	RegionRec   damage_region;
-	
-	/* Allocate memory for rotation */
-	if (old_width != width || old_height != height)
-	{
-	    if (shadow)
-	    {
-		crtc->funcs->shadow_destroy (crtc, shadow);
-		crtc->rotatedPixmap = NULL;
-	    }
-	    shadow = crtc->funcs->shadow_create (crtc, width, height);
-	    if (!shadow)
-		goto bail1;
-	    crtc->rotatedPixmap = shadow;
-	}
-	
-	if (!xf86_config->rotationDamage)
-	{
-	    /* Create damage structure */
-	    xf86_config->rotationDamage = DamageCreate (NULL, NULL,
-						DamageReportNone,
-						TRUE, pScreen, pScreen);
-	    if (!xf86_config->rotationDamage)
-		goto bail2;
-	    
-	    /* Hook damage to screen pixmap */
-	    DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
-			    xf86_config->rotationDamage);
-	    
-	    /* Assign block/wakeup handler */
-	    if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
-						 xf86RotateWakeupHandler,
-						 (pointer) pScreen))
-	    {
-		goto bail3;
-	    }
-	    damage_box.x1 = 0;
-	    damage_box.y1 = 0;
-	    damage_box.x2 = mode_width (mode, rotation);
-	    damage_box.y2 = mode_height (mode, rotation);
-	    REGION_INIT (pScreen, &damage_region, &damage_box, 1);
-	    DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
-				&damage_region);
-	    REGION_UNINIT (pScreen, &damage_region);
-	}
-	if (0)
-	{
-bail3:
-	    DamageDestroy (xf86_config->rotationDamage);
-	    xf86_config->rotationDamage = NULL;
-	    
-bail2:
-	    if (shadow)
-	    {
-		crtc->funcs->shadow_destroy (crtc, shadow);
-		crtc->rotatedPixmap = NULL;
-	    }
-bail1:
-	    if (old_width && old_height)
-		crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
-								  old_width,
-								  old_height);
-	    return FALSE;
-	}
-    }
-    
-    /* All done */
-    return TRUE;
-}
diff --git a/src/radeon_xf86cvt.c b/src/radeon_xf86cvt.c
deleted file mode 100644
index 9d8d025..0000000
--- a/src/radeon_xf86cvt.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright 2005-2006 Luc Verhaegen.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * @file This is a copy of xf86cvt.c from the X Server, for compatibility with
- * old servers (pre-1.2).
- */
-
-/*
- * The reason for having this function in a file of its own is
- * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
- * code is shared directly.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xf86.h"
-
-#include <string.h>
-#include "xf86DDC.h"
-#include "radeon_xf86Modes.h"
-#include "xf86Priv.h"
-
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-/*
- * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
- *
- * These calculations are stolen from the CVT calculation spreadsheet written
- * by Graham Loveridge. He seems to be claiming no copyright and there seems to
- * be no license attached to this. He apparently just wants to see his name
- * mentioned.
- *
- * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
- *
- * Comments and structure corresponds to the comments and structure of the xls.
- * This should ease importing of future changes to the standard (not very
- * likely though).
- *
- * About margins; i'm sure that they are to be the bit between HDisplay and
- * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and 
- * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
- * outside sync "margin" for some reason. Since we prefer seeing proper
- * blanking instead of the overscan colour, and since the Crtc* values will
- * probably get altered after us, we will disable margins altogether. With
- * these calculations, Margins will plainly expand H/VDisplay, and we don't
- * want that. -- libv
- *
- */
-_X_EXPORT DisplayModePtr
-xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
-	    Bool Interlaced)
-{
-    DisplayModeRec  *Mode = xnfalloc(sizeof(DisplayModeRec));
-
-    /* 1) top/bottom margin size (% of height) - default: 1.8 */
-#define CVT_MARGIN_PERCENTAGE 1.8    
-
-    /* 2) character cell horizontal granularity (pixels) - default 8 */
-#define CVT_H_GRANULARITY 8
-
-    /* 4) Minimum vertical porch (lines) - default 3 */
-#define CVT_MIN_V_PORCH 3
-
-    /* 4) Minimum number of vertical back porch lines - default 6 */
-#define CVT_MIN_V_BPORCH 6
-
-    /* Pixel Clock step (kHz) */
-#define CVT_CLOCK_STEP 250
-
-    Bool Margins = FALSE;
-    float  VFieldRate, HPeriod;
-    int  HDisplayRnd, HMargin;
-    int  VDisplayRnd, VMargin, VSync;
-    float  Interlace; /* Please rename this */
-
-    memset(Mode, 0, sizeof(DisplayModeRec));
-
-    /* CVT default is 60.0Hz */
-    if (!VRefresh)
-        VRefresh = 60.0;
-
-    /* 1. Required field rate */
-    if (Interlaced)
-        VFieldRate = VRefresh * 2;
-    else
-        VFieldRate = VRefresh;
-
-    /* 2. Horizontal pixels */
-    HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
-
-    /* 3. Determine left and right borders */
-    if (Margins) {
-        /* right margin is actually exactly the same as left */
-        HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
-        HMargin -= HMargin % CVT_H_GRANULARITY;
-    } else
-        HMargin = 0;
-
-    /* 4. Find total active pixels */
-    Mode->HDisplay = HDisplayRnd + 2*HMargin;
-
-    /* 5. Find number of lines per field */
-    if (Interlaced)
-        VDisplayRnd = VDisplay / 2;
-    else
-        VDisplayRnd = VDisplay;
-
-    /* 6. Find top and bottom margins */
-    /* nope. */
-    if (Margins)
-        /* top and bottom margins are equal again. */
-        VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
-    else
-        VMargin = 0;
-
-    Mode->VDisplay = VDisplay + 2*VMargin;
-
-    /* 7. Interlace */
-    if (Interlaced)
-        Interlace = 0.5;
-    else
-        Interlace = 0.0;
-
-    /* Determine VSync Width from aspect ratio */
-    if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
-        VSync = 4;
-    else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
-        VSync = 5;
-    else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
-        VSync = 6;
-    else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
-        VSync = 7;
-    else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
-        VSync = 7;
-    else /* Custom */
-        VSync = 10;
-
-    if (!Reduced) { /* simplified GTF calculation */
-
-        /* 4) Minimum time of vertical sync + back porch interval (µs) 
-         * default 550.0 */
-#define CVT_MIN_VSYNC_BP 550.0
-
-        /* 3) Nominal HSync width (% of line period) - default 8 */
-#define CVT_HSYNC_PERCENTAGE 8
-
-        float  HBlankPercentage;
-        int  VSyncAndBackPorch, VBackPorch;
-        int  HBlank;
-
-        /* 8. Estimated Horizontal period */
-        HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / 
-            (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
-
-        /* 9. Find number of lines in sync + backporch */
-        if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH))
-            VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
-        else
-            VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1;
-
-        /* 10. Find number of lines in back porch */
-        VBackPorch = VSyncAndBackPorch - VSync;
-
-        /* 11. Find total number of lines in vertical field */
-        Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
-            + CVT_MIN_V_PORCH;
-
-        /* 5) Definition of Horizontal blanking time limitation */
-        /* Gradient (%/kHz) - default 600 */
-#define CVT_M_FACTOR 600
-
-        /* Offset (%) - default 40 */
-#define CVT_C_FACTOR 40
-
-        /* Blanking time scaling factor - default 128 */
-#define CVT_K_FACTOR 128
-
-        /* Scaling factor weighting - default 20 */
-#define CVT_J_FACTOR 20
-
-#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
-#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
-        CVT_J_FACTOR
-
-        /* 12. Find ideal blanking duty cycle from formula */
-        HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0;
-
-        /* 13. Blanking time */
-        if (HBlankPercentage < 20)
-            HBlankPercentage = 20;
-
-        HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage);
-        HBlank -= HBlank % (2*CVT_H_GRANULARITY);
-        
-        /* 14. Find total number of pixels in a line. */
-        Mode->HTotal = Mode->HDisplay + HBlank;
-
-        /* Fill in HSync values */
-        Mode->HSyncEnd = Mode->HDisplay + HBlank / 2;
-
-        Mode->HSyncStart = Mode->HSyncEnd - 
-            (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100;
-        Mode->HSyncStart += CVT_H_GRANULARITY - 
-            Mode->HSyncStart % CVT_H_GRANULARITY;
-
-        /* Fill in VSync values */
-        Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH;
-        Mode->VSyncEnd = Mode->VSyncStart + VSync;
-
-    } else { /* Reduced blanking */
-        /* Minimum vertical blanking interval time (µs) - default 460 */
-#define CVT_RB_MIN_VBLANK 460.0
-
-        /* Fixed number of clocks for horizontal sync */
-#define CVT_RB_H_SYNC 32.0
-
-        /* Fixed number of clocks for horizontal blanking */
-#define CVT_RB_H_BLANK 160.0
-
-        /* Fixed number of lines for vertical front porch - default 3 */
-#define CVT_RB_VFPORCH 3
-
-        int  VBILines;
-
-        /* 8. Estimate Horizontal period. */
-        HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / 
-            (VDisplayRnd + 2*VMargin);
-
-        /* 9. Find number of lines in vertical blanking */
-        VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
-
-        /* 10. Check if vertical blanking is sufficient */
-        if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
-            VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
-        
-        /* 11. Find total number of lines in vertical field */
-        Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
-
-        /* 12. Find total number of pixels in a line */
-        Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK;
-
-        /* Fill in HSync values */
-        Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2;
-        Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC;
-
-        /* Fill in VSync values */
-        Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH;
-        Mode->VSyncEnd = Mode->VSyncStart + VSync;
-    }
-
-    /* 15/13. Find pixel clock frequency (kHz for xf86) */
-    Mode->Clock = Mode->HTotal * 1000.0 / HPeriod;
-    Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP;
-
-    /* 16/14. Find actual Horizontal Frequency (kHz) */
-    Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal);
-
-    /* 17/15. Find actual Field rate */
-    Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
-        ((float) (Mode->HTotal * Mode->VTotal));
-
-    /* 18/16. Find actual vertical frame frequency */
-    /* ignore - just set the mode flag for interlaced */
-    if (Interlaced)
-        Mode->VTotal *= 2;
-
-    {
-        char  Name[256];
-        Name[0] = 0;
-
-        snprintf(Name, 256, "%dx%d", HDisplay, VDisplay);
-
-        Mode->name = xnfalloc(strlen(Name) + 1);
-        memcpy(Mode->name, Name, strlen(Name) + 1);
-    }
-
-    if (Reduced)
-        Mode->Flags |= V_PHSYNC | V_NVSYNC;
-    else
-        Mode->Flags |= V_NHSYNC | V_PVSYNC;
-
-    if (Interlaced)
-        Mode->Flags |= V_INTERLACE;
-
-    return Mode;
-}
-#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
diff --git a/src/xf86Optrec.h b/src/xf86Optrec.h
deleted file mode 100644
index 183b857..0000000
--- a/src/xf86Optrec.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* 
- * 
- * Copyright (c) 1997  Metro Link Incorporated
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- * 
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- * 
- */
-/*
- * Copyright (c) 1997-2001 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-/* 
- * This file contains the Option Record that is passed between the Parser,
- * and Module setup procs.
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#ifndef _xf86Optrec_h_
-#define _xf86Optrec_h_
-#include <stdio.h>
-
-/* 
- * all records that need to be linked lists should contain a GenericList as
- * their first field.
- */
-typedef struct generic_list_rec
-{
-	void *next;
-}
-GenericListRec, *GenericListPtr, *glp;
-
-/*
- * All options are stored using this data type.
- */
-typedef struct
-{
-	GenericListRec list;
-	char *opt_name;
-	char *opt_val;
-	int opt_used;
-	char *opt_comment;
-}
-XF86OptionRec, *XF86OptionPtr;
-
-
-XF86OptionPtr xf86addNewOption(XF86OptionPtr head, char *name, char *val);
-XF86OptionPtr xf86optionListDup(XF86OptionPtr opt);
-void xf86optionListFree(XF86OptionPtr opt);
-char *xf86optionName(XF86OptionPtr opt);
-char *xf86optionValue(XF86OptionPtr opt);
-XF86OptionPtr xf86newOption(char *name, char *value);
-XF86OptionPtr xf86nextOption(XF86OptionPtr list);
-XF86OptionPtr xf86findOption(XF86OptionPtr list, const char *name);
-char *xf86findOptionValue(XF86OptionPtr list, const char *name);
-int xf86findOptionBoolean (XF86OptionPtr, const char *, int);
-XF86OptionPtr xf86optionListCreate(const char **options, int count, int used);
-XF86OptionPtr xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail);
-char *xf86configStrdup (const char *s);
-int xf86nameCompare (const char *s1, const char *s2);
-char *xf86uLongToString(unsigned long i);
-void xf86debugListOptions(XF86OptionPtr);
-XF86OptionPtr xf86parseOption(XF86OptionPtr head);
-void xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs);
-
-
-#endif /* _xf86Optrec_h_ */
diff --git a/src/xf86Parser.h b/src/xf86Parser.h
deleted file mode 100644
index a682927..0000000
--- a/src/xf86Parser.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/* 
- * 
- * Copyright (c) 1997  Metro Link Incorporated
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"), 
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- * 
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- * 
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- * 
- */
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-/* 
- * This file contains the external interfaces for the XFree86 configuration
- * file parser.
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#ifndef _xf86Parser_h_
-#define _xf86Parser_h_
-
-#include "xf86Optrec.h"
-
-#define HAVE_PARSER_DECLS
-
-typedef struct
-{
-	char *file_logfile;
-	char *file_rgbpath;
-	char *file_modulepath;
-	char *file_inputdevs;
-	char *file_fontpath;
-	char *file_comment;
-}
-XF86ConfFilesRec, *XF86ConfFilesPtr;
-
-/* Values for load_type */
-#define XF86_LOAD_MODULE	0
-#define XF86_LOAD_DRIVER	1
-
-typedef struct
-{
-	GenericListRec list;
-	int load_type;
-	char *load_name;
-	XF86OptionPtr load_opt;
-	char *load_comment;
-        int ignore;
-}
-XF86LoadRec, *XF86LoadPtr;
-
-typedef struct
-{
-	XF86LoadPtr mod_load_lst;
-	char *mod_comment;
-}
-XF86ConfModuleRec, *XF86ConfModulePtr;
-
-#define CONF_IMPLICIT_KEYBOARD	"Implicit Core Keyboard"
-
-#define CONF_IMPLICIT_POINTER	"Implicit Core Pointer"
-
-#define XF86CONF_PHSYNC    0x0001
-#define XF86CONF_NHSYNC    0x0002
-#define XF86CONF_PVSYNC    0x0004
-#define XF86CONF_NVSYNC    0x0008
-#define XF86CONF_INTERLACE 0x0010
-#define XF86CONF_DBLSCAN   0x0020
-#define XF86CONF_CSYNC     0x0040
-#define XF86CONF_PCSYNC    0x0080
-#define XF86CONF_NCSYNC    0x0100
-#define XF86CONF_HSKEW     0x0200	/* hskew provided */
-#define XF86CONF_BCAST     0x0400
-#define XF86CONF_CUSTOM    0x0800	/* timing numbers customized by editor */
-#define XF86CONF_VSCAN     0x1000
-
-typedef struct
-{
-	GenericListRec list;
-	char *ml_identifier;
-	int ml_clock;
-	int ml_hdisplay;
-	int ml_hsyncstart;
-	int ml_hsyncend;
-	int ml_htotal;
-	int ml_vdisplay;
-	int ml_vsyncstart;
-	int ml_vsyncend;
-	int ml_vtotal;
-	int ml_vscan;
-	int ml_flags;
-	int ml_hskew;
-	char *ml_comment;
-}
-XF86ConfModeLineRec, *XF86ConfModeLinePtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *vp_identifier;
-	XF86OptionPtr vp_option_lst;
-	char *vp_comment;
-}
-XF86ConfVideoPortRec, *XF86ConfVideoPortPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *va_identifier;
-	char *va_vendor;
-	char *va_board;
-	char *va_busid;
-	char *va_driver;
-	XF86OptionPtr va_option_lst;
-	XF86ConfVideoPortPtr va_port_lst;
-	char *va_fwdref;
-	char *va_comment;
-}
-XF86ConfVideoAdaptorRec, *XF86ConfVideoAdaptorPtr;
-
-#define CONF_MAX_HSYNC 8
-#define CONF_MAX_VREFRESH 8
-
-typedef struct
-{
-	float hi, lo;
-}
-parser_range;
-
-typedef struct
-{
-	int red, green, blue;
-}
-parser_rgb;
-
-typedef struct
-{
-	GenericListRec list;
-	char *modes_identifier;
-	XF86ConfModeLinePtr mon_modeline_lst;
-	char *modes_comment;
-}
-XF86ConfModesRec, *XF86ConfModesPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *ml_modes_str;
-	XF86ConfModesPtr ml_modes;
-}
-XF86ConfModesLinkRec, *XF86ConfModesLinkPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *mon_identifier;
-	char *mon_vendor;
-	char *mon_modelname;
-	int mon_width;				/* in mm */
-	int mon_height;				/* in mm */
-	XF86ConfModeLinePtr mon_modeline_lst;
-	int mon_n_hsync;
-	parser_range mon_hsync[CONF_MAX_HSYNC];
-	int mon_n_vrefresh;
-	parser_range mon_vrefresh[CONF_MAX_VREFRESH];
-	float mon_gamma_red;
-	float mon_gamma_green;
-	float mon_gamma_blue;
-	XF86OptionPtr mon_option_lst;
-	XF86ConfModesLinkPtr mon_modes_sect_lst;
-	char *mon_comment;
-}
-XF86ConfMonitorRec, *XF86ConfMonitorPtr;
-
-#define CONF_MAXDACSPEEDS 4
-#define CONF_MAXCLOCKS    128
-
-typedef struct
-{
-	GenericListRec list;
-	char *dev_identifier;
-	char *dev_vendor;
-	char *dev_board;
-	char *dev_chipset;
-	char *dev_busid;
-	char *dev_card;
-	char *dev_driver;
-	char *dev_ramdac;
-	int dev_dacSpeeds[CONF_MAXDACSPEEDS];
-	int dev_videoram;
-	int dev_textclockfreq;
-	unsigned long dev_bios_base;
-	unsigned long dev_mem_base;
-	unsigned long dev_io_base;
-	char *dev_clockchip;
-	int dev_clocks;
-	int dev_clock[CONF_MAXCLOCKS];
-	int dev_chipid;
-	int dev_chiprev;
-	int dev_irq;
-	int dev_screen;
-	XF86OptionPtr dev_option_lst;
-	char *dev_comment;
-}
-XF86ConfDeviceRec, *XF86ConfDevicePtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *mode_name;
-}
-XF86ModeRec, *XF86ModePtr;
-
-typedef struct
-{
-	GenericListRec list;
-	int disp_frameX0;
-	int disp_frameY0;
-	int disp_virtualX;
-	int disp_virtualY;
-	int disp_depth;
-	int disp_bpp;
-	char *disp_visual;
-	parser_rgb disp_weight;
-	parser_rgb disp_black;
-	parser_rgb disp_white;
-	XF86ModePtr disp_mode_lst;
-	XF86OptionPtr disp_option_lst;
-	char *disp_comment;
-}
-XF86ConfDisplayRec, *XF86ConfDisplayPtr;
-
-typedef struct
-{
-	XF86OptionPtr flg_option_lst;
-	char *flg_comment;
-}
-XF86ConfFlagsRec, *XF86ConfFlagsPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *al_adaptor_str;
-	XF86ConfVideoAdaptorPtr al_adaptor;
-}
-XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *scrn_identifier;
-	char *scrn_obso_driver;
-	int scrn_defaultdepth;
-	int scrn_defaultbpp;
-	int scrn_defaultfbbpp;
-	char *scrn_monitor_str;
-	XF86ConfMonitorPtr scrn_monitor;
-	char *scrn_device_str;
-	XF86ConfDevicePtr scrn_device;
-	XF86ConfAdaptorLinkPtr scrn_adaptor_lst;
-	XF86ConfDisplayPtr scrn_display_lst;
-	XF86OptionPtr scrn_option_lst;
-	char *scrn_comment;
-}
-XF86ConfScreenRec, *XF86ConfScreenPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *inp_identifier;
-	char *inp_driver;
-	XF86OptionPtr inp_option_lst;
-	char *inp_comment;
-}
-XF86ConfInputRec, *XF86ConfInputPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	XF86ConfInputPtr iref_inputdev;
-	char *iref_inputdev_str;
-	XF86OptionPtr iref_option_lst;
-}
-XF86ConfInputrefRec, *XF86ConfInputrefPtr;
-
-/* Values for adj_where */
-#define CONF_ADJ_OBSOLETE	-1
-#define CONF_ADJ_ABSOLUTE	0
-#define CONF_ADJ_RIGHTOF	1
-#define CONF_ADJ_LEFTOF		2
-#define CONF_ADJ_ABOVE		3
-#define CONF_ADJ_BELOW		4
-#define CONF_ADJ_RELATIVE	5
-
-typedef struct
-{
-	GenericListRec list;
-	int adj_scrnum;
-	XF86ConfScreenPtr adj_screen;
-	char *adj_screen_str;
-	XF86ConfScreenPtr adj_top;
-	char *adj_top_str;
-	XF86ConfScreenPtr adj_bottom;
-	char *adj_bottom_str;
-	XF86ConfScreenPtr adj_left;
-	char *adj_left_str;
-	XF86ConfScreenPtr adj_right;
-	char *adj_right_str;
-	int adj_where;
-	int adj_x;
-	int adj_y;
-	char *adj_refscreen;
-}
-XF86ConfAdjacencyRec, *XF86ConfAdjacencyPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *inactive_device_str;
-	XF86ConfDevicePtr inactive_device;
-}
-XF86ConfInactiveRec, *XF86ConfInactivePtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *lay_identifier;
-	XF86ConfAdjacencyPtr lay_adjacency_lst;
-	XF86ConfInactivePtr lay_inactive_lst;
-	XF86ConfInputrefPtr lay_input_lst;
-	XF86OptionPtr lay_option_lst;
-	char *lay_comment;
-}
-XF86ConfLayoutRec, *XF86ConfLayoutPtr;
-
-typedef struct 
-{ 
-	GenericListRec list; 
-	char *vs_name;
-	char *vs_identifier;
-	XF86OptionPtr vs_option_lst;
-	char *vs_comment;
-}
-XF86ConfVendSubRec, *XF86ConfVendSubPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	char *vnd_identifier;
-	XF86OptionPtr vnd_option_lst;
-	XF86ConfVendSubPtr vnd_sub_lst;
-	char *vnd_comment;
-}
-XF86ConfVendorRec, *XF86ConfVendorPtr;
-
-typedef struct
-{
-	GenericListRec list;
-	int buf_count;
-	int buf_size;
-	char *buf_flags;
-	char *buf_comment;
-}
-XF86ConfBuffersRec, *XF86ConfBuffersPtr;
-
-typedef struct
-{
-	char *dri_group_name;
-	int dri_group;
-	int dri_mode;
-	XF86ConfBuffersPtr dri_buffers_lst;
-	char *dri_comment;
-}
-XF86ConfDRIRec, *XF86ConfDRIPtr;
-
-typedef struct
-{
-	XF86OptionPtr ext_option_lst;
-	char *extensions_comment;
-}
-XF86ConfExtensionsRec, *XF86ConfExtensionsPtr;
-
-typedef struct
-{
-	XF86ConfFilesPtr conf_files;
-	XF86ConfModulePtr conf_modules;
-	XF86ConfFlagsPtr conf_flags;
-	XF86ConfVideoAdaptorPtr conf_videoadaptor_lst;
-	XF86ConfModesPtr conf_modes_lst;
-	XF86ConfMonitorPtr conf_monitor_lst;
-	XF86ConfDevicePtr conf_device_lst;
-	XF86ConfScreenPtr conf_screen_lst;
-	XF86ConfInputPtr conf_input_lst;
-	XF86ConfLayoutPtr conf_layout_lst;
-	XF86ConfVendorPtr conf_vendor_lst;
-	XF86ConfDRIPtr conf_dri;
-	XF86ConfExtensionsPtr conf_extensions;
-	char *conf_comment;
-}
-XF86ConfigRec, *XF86ConfigPtr;
-
-typedef struct
-{
-	int token;			/* id of the token */
-	char *name;			/* pointer to the LOWERCASED name */
-}
-xf86ConfigSymTabRec, *xf86ConfigSymTabPtr;
-
-/*
- * prototypes for public functions
- */
-extern const char *xf86openConfigFile (const char *, const char *,
-					const char *);
-extern void xf86setBuiltinConfig(const char *config[]);
-extern XF86ConfigPtr xf86readConfigFile (void);
-extern void xf86closeConfigFile (void);
-extern void xf86freeConfig (XF86ConfigPtr p);
-extern int xf86writeConfigFile (const char *, XF86ConfigPtr);
-XF86ConfDevicePtr xf86findDevice(const char *ident, XF86ConfDevicePtr p);
-XF86ConfLayoutPtr xf86findLayout(const char *name, XF86ConfLayoutPtr list);
-XF86ConfMonitorPtr xf86findMonitor(const char *ident, XF86ConfMonitorPtr p);
-XF86ConfModesPtr xf86findModes(const char *ident, XF86ConfModesPtr p);
-XF86ConfModeLinePtr xf86findModeLine(const char *ident, XF86ConfModeLinePtr p);
-XF86ConfScreenPtr xf86findScreen(const char *ident, XF86ConfScreenPtr p);
-XF86ConfInputPtr xf86findInput(const char *ident, XF86ConfInputPtr p);
-XF86ConfInputPtr xf86findInputByDriver(const char *driver, XF86ConfInputPtr p);
-XF86ConfVendorPtr xf86findVendor(const char *name, XF86ConfVendorPtr list);
-XF86ConfVideoAdaptorPtr xf86findVideoAdaptor(const char *ident,
-						XF86ConfVideoAdaptorPtr p);
-
-GenericListPtr xf86addListItem(GenericListPtr head, GenericListPtr c_new);
-int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2);
-
-int xf86pathIsAbsolute(const char *path);
-int xf86pathIsSafe(const char *path);
-char *xf86addComment(char *cur, char *add);
-
-#endif /* _xf86Parser_h_ */
diff-tree 63248f0b4308a4487cda3aa22daa36e3e0d38d14 (from 6a25f620d40cbb063de94aa6b5267296cd5a0670)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Feb 12 19:37:36 2007 +1100

    fix LVDS by moving bios reading around

diff --git a/src/radeon_display.c b/src/radeon_display.c
index fa76bac..f3d54a9 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1115,6 +1115,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
       int DDCReg = 0;
       char *names[] = { "DDC1", "DDC2" };
 
+      RADEONSetOutputType(pScrn, radeon_output);
       switch(radeon_output->DDCType) {
       case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
       case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
@@ -1135,7 +1136,8 @@ void RADEONSetupConnectors(ScrnInfoPtr p
       if (radeon_output->type == OUTPUT_DVI) {
 	RADEONGetTMDSInfo(pScrn);
 
-	RADEONGetHardCodedEDIDFromBios(pScrn);
+	if (i == 0)
+		RADEONGetHardCodedEDIDFromBios(pScrn);
 
 	RADEONUpdatePanelSize(pScrn);
 
@@ -2519,7 +2521,6 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
     /* for now always allocate max connectors */
     for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
 
-	RADEONSetOutputType(pScrn, pRADEONEnt->PortInfo[i]);
 
 	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
 	if (!pRADEONEnt->pOutput[i])
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 4ece51c..0e2ec00 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2424,17 +2424,6 @@ static Bool RADEONPreInitControllers(Scr
       
     RADEONMapControllers(pScrn);
 
-    info->HBlank     = 0;
-    info->HOverPlus  = 0;
-    info->HSyncWidth = 0;
-    info->VBlank     = 0;
-    info->VOverPlus  = 0;
-    info->VSyncWidth = 0;
-    info->DotClock   = 0;
-    info->UseBiosDividers = FALSE;
-
-    info->OverlayOnCRTC2 = FALSE;
-
     RADEONGetClockInfo(pScrn);
     RADEONGetPanelInfo(pScrn);
     RADEONGetTVDacAdjInfo(pScrn);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index b88ffb9..74e52cb 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -309,7 +309,6 @@ RADEONProbeOutputModes(xf86OutputPtr out
       
       if (modes == NULL) {
 	MonRec fixed_mon;
-	DisplayModePtr modes;
 	
 	RADEONValidateFPModes(pScrn, pScrn->display->modes, &modes);
       }
diff-tree 6a25f620d40cbb063de94aa6b5267296cd5a0670 (from 9234d8045c5fefbd1a781209409e55a13e3e5370)
Author: David Airlie <airlied at asimov.stargames.com.au>
Date:   Mon Feb 12 15:59:43 2007 +1100

    remove assignments to pOutput before it is created

diff --git a/src/radeon_display.c b/src/radeon_display.c
index c146785..fa76bac 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -932,7 +932,6 @@ void RADEONSetupConnectors(ScrnInfoPtr p
      */
     for (i = 0; i < 2; i++) {
 	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
-	pRADEONEnt->pOutput[i]->MonInfo = NULL;
 	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
 	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
 	pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN;
@@ -944,14 +943,12 @@ void RADEONSetupConnectors(ScrnInfoPtr p
         (pRADEONEnt->PortInfo[1]->DDCType == 0))) {
 	/* Below is the most common setting, but may not be true */
 	pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
-	pRADEONEnt->pOutput[0]->MonInfo = NULL;
 	pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI;
 	pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
 	pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
 	pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I;
 
 	pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
-	pRADEONEnt->pOutput[1]->MonInfo = NULL;
 	pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
 	pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
 	pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
diff-tree 9234d8045c5fefbd1a781209409e55a13e3e5370 (from d7317604c843e21c1df048a9253ed55a1957cccd)
Author: David Airlie <airlied at asimov.stargames.com.au>
Date:   Mon Feb 5 11:53:18 2007 +1100

    remove all the locking glxgears runs fine over screen changes without it

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 4f31cdb..c146785 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2277,7 +2277,6 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
 	radeon_crtc->lut_b[i] = blue[i] >> 8;
     }
 
-    ErrorF("Loading lut %d\n", radeon_crtc->crtc_id);
     radeon_crtc_load_lut(crtc);
 }
 
@@ -2287,14 +2286,7 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
   ScrnInfoPtr		pScrn = crtc->scrn;
   RADEONInfoPtr  info = RADEONPTR(pScrn);
   Bool           CPStarted   = info->CPStarted;
-  if (info->accelOn)
-    RADEON_SYNC(info, pScrn);
-#ifdef XF86DRI
-    if (info->CPStarted) {
-	DRILock(pScrn->pScreen, 0);
-	RADEONCP_STOP(pScrn, info);
-    }
-#endif
+
     return FALSE;
 }
 
@@ -2304,18 +2296,6 @@ radeon_crtc_unlock(xf86CrtcPtr crtc)
   ScrnInfoPtr		pScrn = crtc->scrn;
   RADEONInfoPtr  info = RADEONPTR(pScrn);
 
-  if (info->accelOn) {
-    RADEON_SYNC(info, pScrn);
-    RADEONEngineRestore(pScrn);
-    
-}
-#ifdef XF86DRI
-  if (info->CPStarted) {
-    RADEONCP_START(pScrn, info);
-    DRIUnlock(pScrn->pScreen);
-  }
-#endif
-
 }
 
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 925a01f..679831f 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -628,7 +628,13 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	RADEONInfoPtr  info = RADEONPTR(pScrn);
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 	crtc->enabled = mode != NULL;
-	
+
+#if 0//def XF86DRI
+	if (info->CPStarted) {
+	  DRILock(pScrn->pScreen, 0);
+	  RADEONCP_STOP(pScrn, info);
+	}
+#endif	
 	if (info->accelOn)
 	    RADEON_SYNC(info, pScrn);
 
@@ -659,7 +665,18 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	}
 	if (info->DispPriority)
 	  RADEONInitDispBandwidth(pScrn);
-    
+
+	if (info->accelOn) {
+	  RADEON_SYNC(info, pScrn);
+//	  RADEONEngineRestore(pScrn);
+	}
+
+#if 0 //ef XF86DRI
+	if (info->CPStarted) {
+	  RADEONCP_START(pScrn, info);
+	  DRIUnlock(pScrn->pScreen);
+	}
+#endif
     }
     if (changed && mode)
 	RADEONCrtcSetBase(crtc, x, y);
diff-tree d7317604c843e21c1df048a9253ed55a1957cccd (from 15c68ac19ff9971ae02cf52036ba36ddea1a6759)
Author: David Airlie <airlied at linux.ie>
Date:   Fri Feb 2 14:54:00 2007 +1100

    get rid of mergetype and displaytype from radeon.h

diff --git a/src/radeon.h b/src/radeon.h
index 204c1f2..83bec69 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -440,11 +440,6 @@ typedef struct {
                                            framebuffer */
     int               Flags;            /* Saved copy of mode flags          */
 
-				/* VE/M6 support */
-    RADEONMonitorType DisplayType;      /* Monitor connected on              */
-    RADEONDDCType     DDCType;
-    RADEONConnectorType ConnectorType;
-
     Bool              IsMobility;       /* Mobile chips for laptops */
     Bool              IsIGP;            /* IGP chips */
     Bool              HasSingleDAC;     /* only TVDAC on chip */
@@ -771,8 +766,6 @@ typedef struct {
 
   DisplayModePtr currentMode, savedCurrentMode;
     /* merged fb stuff, also covers clone modes */
-    Bool		MergedFB;
-    RADEONMonitorType   MergeType;
     void        	(*PointerMoved)(int index, int x, int y);
     Bool		NoVirtual;
 
diff --git a/src/radeon_display.c b/src/radeon_display.c
index b9d2bee..4f31cdb 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -887,21 +887,7 @@ void RADEONGetPanelInfo (ScrnInfoPtr pSc
             xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Invalid PanelSize option: %s\n", s);
             RADEONGetPanelInfoFromReg(pScrn);
         }
-    } else {
-
-        if(info->DisplayType == MT_LCD) {
-            RADEONGetLVDSInfo(pScrn);
-	    if (info->MergeType == MT_DFP) {
-		RADEONGetTMDSInfo(pScrn);
-	    }
-        } else if ((info->DisplayType == MT_DFP) || (info->MergeType == MT_DFP)) {
-            RADEONGetTMDSInfo(pScrn);
-            if (!pScrn->monitor->DDC)
-                RADEONGetHardCodedEDIDFromBIOS(pScrn);
-            else if (!info->IsSecondary)
-               RADEONUpdatePanelSize(pScrn);
-        }
-    }
+    } 
 }
 
 void RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn)
@@ -1127,10 +1113,12 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     }
 
     for (i = 0; i < 2; i++) {
+      RADEONOutputPrivatePtr radeon_output = pRADEONEnt->PortInfo[i];
+
       int DDCReg = 0;
       char *names[] = { "DDC1", "DDC2" };
 
-      switch(pRADEONEnt->PortInfo[i]->DDCType) {
+      switch(radeon_output->DDCType) {
       case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
       case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
       case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
@@ -1139,10 +1127,27 @@ void RADEONSetupConnectors(ScrnInfoPtr p
       }
       
       if (DDCReg) {
-	pRADEONEnt->PortInfo[i]->DDCReg = DDCReg;
-	RADEONI2CInit(pScrn, &pRADEONEnt->PortInfo[i]->pI2CBus, DDCReg, names[i]);
+	radeon_output->DDCReg = DDCReg;
+	RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, names[i]);
+      }
+
+      if (radeon_output->type == OUTPUT_LVDS) {
+	RADEONGetLVDSInfo(pScrn);
       }
+
+      if (radeon_output->type == OUTPUT_DVI) {
+	RADEONGetTMDSInfo(pScrn);
+
+	RADEONGetHardCodedEDIDFromBios(pScrn);
+
+	RADEONUpdatePanelSize(pScrn);
+
+      }
+
+
     }
+
+    
 }
 
 static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
@@ -1190,7 +1195,7 @@ void RADEONConnectorFindMonitor(ScrnInfo
     }
 }
 
-static void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn)
+void RADEONQueryConnectedDisplays(ScrnInfoPtr pScrn)
 {
 
     RADEONInfoPtr info       = RADEONPTR(pScrn);
@@ -1297,11 +1302,7 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     xf86OutputPtr output;
     RADEONOutputPrivatePtr radeon_output;
 
-    info->MergeType = MT_NONE;
-
     if (!info->IsSecondary) {
-      RADEONQueryConnectedDisplays(pScrn);
-
       pRADEONEnt->PortInfo[0]->crtc_num = 1;
       pRADEONEnt->PortInfo[1]->crtc_num = 2;
 
@@ -1378,7 +1379,6 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 	    radeon_output = output->driver_private;
   	    pRADEONEnt->Controller[1]->binding = 2;
 	    if (output) {
-		info->DisplayType = radeon_output->MonType;
 		pScrn->monitor->DDC = output->MonInfo;
 	    }
 	} else {
@@ -1386,18 +1386,12 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 	    radeon_output = output->driver_private;
   	    pRADEONEnt->Controller[0]->binding = 1;
 	    if (output) {
-		info->DisplayType = radeon_output->MonType; 
 		pScrn->monitor->DDC = output->MonInfo;
 	    }
 	}
 	
 	if(!pRADEONEnt->HasSecondary) {
-	    output = RADEONGetCrtcConnector(pScrn, 2);
-	    radeon_output = output->driver_private;
-	    if (output)
-		info->MergeType = radeon_output->MonType;
-	    if (info->MergeType)
-  	    	pRADEONEnt->Controller[1]->binding = 1;
+	  pRADEONEnt->Controller[1]->binding = 1;
 	} 
     } else {
 	output = RADEONGetCrtcConnector(pScrn, 1);
@@ -1405,7 +1399,6 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 	if (output) {
 	    if (radeon_output->MonType == MT_NONE) 
 		radeon_output->MonType = MT_CRT;
-	    info->DisplayType = radeon_output->MonType; 
 	    pScrn->monitor->DDC = output->MonInfo;
 	}
 	output = RADEONGetCrtcConnector(pScrn, 2);
@@ -1425,16 +1418,6 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
     }
 
-    info->HBlank     = 0;
-    info->HOverPlus  = 0;
-    info->HSyncWidth = 0;
-    info->VBlank     = 0;
-    info->VOverPlus  = 0;
-    info->VSyncWidth = 0;
-    info->DotClock   = 0;
-    info->UseBiosDividers = FALSE;
-
-    info->OverlayOnCRTC2 = FALSE;
 
     return TRUE;
 }
@@ -2236,13 +2219,24 @@ 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;
+    int i = 0;
+
+    for (i = 0; i < xf86_config->num_output; i++) {
+      xf86OutputPtr output = xf86_config->output[i];
+      RADEONOutputPrivatePtr radeon_output = output->driver_private;
+
+      if (output->crtc == crtc) {
+	montype = radeon_output->MonType;
+      }
+    }
     
     switch (radeon_crtc->crtc_id) {
     case 0: 
-      RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg, MT_CRT);
+      RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg, montype);
       break;
     case 1: 
-      RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg, MT_CRT);
+      RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg, montype);
       break;
     }
 }
@@ -2397,12 +2391,23 @@ radeon_detect(xf86OutputPtr output)
     
     radeon_output->MonType = MT_UNKNOWN;
     RADEONConnectorFindMonitor(pScrn, output);
-    if (radeon_output->MonType == MT_UNKNOWN)
+    if (radeon_output->MonType == MT_UNKNOWN) {
+        output->subpixel_order = SubPixelUnknown;
 	return XF86OutputStatusUnknown;
+    }
     else if (radeon_output->MonType == MT_NONE) {
+        output->subpixel_order = SubPixelUnknown;
 	return XF86OutputStatusDisconnected;
-    } else
-	return XF86OutputStatusConnected;
+    } else {
+
+      switch(radeon_output->MonType) {
+      case MT_LCD:
+      case MT_DFP: output->subpixel_order = SubPixelHorizontalRGB; break;
+      default: output->subpixel_order = SubPixelNone; break;
+      }
+      
+      return XF86OutputStatusConnected;
+    }
 
 }
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 5371c4c..4ece51c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1429,7 +1429,6 @@ static Bool RADEONPreInitVRAM(ScrnInfoPt
      * be able to be adjusted by user with a config option. */
     if (info->IsPrimary) {
         pScrn->videoRam /= 2;
-	info->MergedFB = FALSE;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
 		"Using %dk of videoram for primary head\n",
 		pScrn->videoRam);
@@ -2076,7 +2075,7 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr
 		   "Direct Rendering Disabled -- "
 		   "Dual-head configuration is not working with "
 		   "DRI at present.\n"
-		   "Please use the radeon MergedFB option if you "
+		   "Please use the radeon randr 1.2 support option if you "
 		   "want Dual-head with DRI.\n");
 	return FALSE;
     }
@@ -2419,8 +2418,23 @@ static Bool RADEONPreInitControllers(Scr
 	return FALSE;
     }
 
+    if (!info->IsSecondary) {
+      RADEONQueryConnectedDisplays(pScrn);
+    }
+      
     RADEONMapControllers(pScrn);
 
+    info->HBlank     = 0;
+    info->HOverPlus  = 0;
+    info->HSyncWidth = 0;
+    info->VBlank     = 0;
+    info->VOverPlus  = 0;
+    info->VSyncWidth = 0;
+    info->DotClock   = 0;
+    info->UseBiosDividers = FALSE;
+
+    info->OverlayOnCRTC2 = FALSE;
+
     RADEONGetClockInfo(pScrn);
     RADEONGetPanelInfo(pScrn);
     RADEONGetTVDacAdjInfo(pScrn);
@@ -2464,7 +2478,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     info               = RADEONPTR(pScrn);
     info->IsSecondary  = FALSE;
     info->IsPrimary     = FALSE;
-    info->MergedFB     = FALSE;
     info->IsSwitching  = FALSE;
     info->MMIO         = NULL;
 
@@ -3604,16 +3617,6 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
 	PictureSetSubpixelOrder (pScreen, subPixelOrder);
     } 
-
-    if (PictureGetSubpixelOrder (pScreen) == SubPixelUnknown) {
-	switch (info->DisplayType) {
-	case MT_NONE:	subPixelOrder = SubPixelUnknown; break;
-	case MT_LCD:	subPixelOrder = SubPixelHorizontalRGB; break;
-	case MT_DFP:	subPixelOrder = SubPixelHorizontalRGB; break;
-	default:	subPixelOrder = SubPixelNone; break;
-	}
-	PictureSetSubpixelOrder (pScreen, subPixelOrder);
-    }
 #endif
 
     pScrn->vtSema = TRUE;
@@ -4061,11 +4064,9 @@ static void RADEONRestoreCommonRegisters
 	CARD32        tmp;
         RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
-	if (pRADEONEnt->HasSecondary || info->MergedFB) {
-	    tmp = INREG(RADEON_DAC_CNTL2);
-	    OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
-	    usleep(100000);
-	}
+	tmp = INREG(RADEON_DAC_CNTL2);
+	OUTREG(RADEON_DAC_CNTL2, tmp & ~RADEON_DAC2_DAC_CLK_SEL);
+	usleep(100000);
     }
 }
 
@@ -5968,9 +5969,9 @@ static Bool RADEONInit(ScrnInfoPtr pScrn
     RADEONInfoPtr info = RADEONPTR(pScrn);
 
     if (info->IsSecondary) {
-        return RADEONInit2(pScrn, NULL, mode, 2, save, info->DisplayType);
+        return RADEONInit2(pScrn, NULL, mode, 2, save, 0);
     } else {
-        return RADEONInit2(pScrn, mode, NULL, 1, save, info->DisplayType);
+        return RADEONInit2(pScrn, mode, NULL, 1, save, 0);
     }
 }
 
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 93ea1eb..ed4cbfb 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1332,7 +1332,7 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
      */
 
     /* Figure out which head we are on */
-    if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
+    if ((info->OverlayOnCRTC2) || info->IsSecondary)
 	dot_clock = info->ModeReg.dot_clock_freq_2;
     else
 	dot_clock = info->ModeReg.dot_clock_freq;
@@ -2469,7 +2469,7 @@ RADEONDisplayVideo(
     y_mult = 1;
 
     /* TODO NO IDEA WHAT THIS IS ABOUT */
-    if (info->MergedFB) {
+    if (0) {//info->MergedFB) {
 	if (overlay_mode->Flags & V_INTERLACE)
 	    v_inc_shift++;
     	if (overlay_mode->Flags & V_DBLSCAN) {
diff-tree 15c68ac19ff9971ae02cf52036ba36ddea1a6759 (from 72ef23ef7dd159d827e8e122482a58928d532268)
Author: David Airlie <airlied at linux.ie>
Date:   Fri Feb 2 14:30:16 2007 +1100

    rename some variables to output from connector

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7f19f79..b9d2bee 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1294,7 +1294,7 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     Bool head_reversed = FALSE;
-    xf86OutputPtr connector;
+    xf86OutputPtr output;
     RADEONOutputPrivatePtr radeon_output;
 
     info->MergeType = MT_NONE;
@@ -1374,50 +1374,50 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
 
     if(pRADEONEnt->HasCRTC2) {
 	if(info->IsSecondary) {
-	    connector = RADEONGetCrtcConnector(pScrn, 2);
-	    radeon_output = connector->driver_private;
+	    output = RADEONGetCrtcConnector(pScrn, 2);
+	    radeon_output = output->driver_private;
   	    pRADEONEnt->Controller[1]->binding = 2;
-	    if (connector) {
+	    if (output) {
 		info->DisplayType = radeon_output->MonType;
-		pScrn->monitor->DDC = connector->MonInfo;
+		pScrn->monitor->DDC = output->MonInfo;
 	    }
 	} else {
-	    connector = RADEONGetCrtcConnector(pScrn, 1);
-	    radeon_output = connector->driver_private;
+	    output = RADEONGetCrtcConnector(pScrn, 1);
+	    radeon_output = output->driver_private;
   	    pRADEONEnt->Controller[0]->binding = 1;
-	    if (connector) {
+	    if (output) {
 		info->DisplayType = radeon_output->MonType; 
-		pScrn->monitor->DDC = connector->MonInfo;
+		pScrn->monitor->DDC = output->MonInfo;
 	    }
 	}
 	
 	if(!pRADEONEnt->HasSecondary) {
-	    connector = RADEONGetCrtcConnector(pScrn, 2);
-	    radeon_output = connector->driver_private;
-	    if (connector)
+	    output = RADEONGetCrtcConnector(pScrn, 2);
+	    radeon_output = output->driver_private;
+	    if (output)
 		info->MergeType = radeon_output->MonType;
 	    if (info->MergeType)
   	    	pRADEONEnt->Controller[1]->binding = 1;
 	} 
     } else {
-	connector = RADEONGetCrtcConnector(pScrn, 1);
-	radeon_output = connector->driver_private;
-	if (connector) {
+	output = RADEONGetCrtcConnector(pScrn, 1);
+	radeon_output = output->driver_private;
+	if (output) {
 	    if (radeon_output->MonType == MT_NONE) 
 		radeon_output->MonType = MT_CRT;
 	    info->DisplayType = radeon_output->MonType; 
-	    pScrn->monitor->DDC = connector->MonInfo;
+	    pScrn->monitor->DDC = output->MonInfo;
 	}
-	connector = RADEONGetCrtcConnector(pScrn, 2);
-	radeon_output = connector->driver_private;
-	if (connector)
+	output = RADEONGetCrtcConnector(pScrn, 2);
+	radeon_output = output->driver_private;
+	if (output)
 	    radeon_output->MonType = MT_NONE;
 	pRADEONEnt->Controller[1]->binding = 1;
     }
 
     if (!info->IsSecondary) {
-	connector = RADEONGetCrtcConnector(pScrn, 2);
-	radeon_output = connector->driver_private;
+	output = RADEONGetCrtcConnector(pScrn, 2);
+	radeon_output = output->driver_private;
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head:   Port%d ---- \n", head_reversed?2:1);
 	if (radeon_output->MonType != MT_NONE)
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2);
diff-tree 72ef23ef7dd159d827e8e122482a58928d532268 (from 96acf6b2b242454345cc4b9cfc7ca07e0b597b43)
Author: David Airlie <airlied at linux.ie>
Date:   Fri Feb 2 14:26:29 2007 +1100

    fixup mode probing a bit neater

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 813f277..7f19f79 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2409,8 +2409,9 @@ radeon_detect(xf86OutputPtr output)
 static DisplayModePtr
 radeon_get_modes(xf86OutputPtr output)
 {
-    RADEONProbeOutputModes(output);
-    return output->probed_modes;
+  DisplayModePtr modes;
+  modes = RADEONProbeOutputModes(output);
+  return modes;
 }
 
 static void
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index fb7727e..b88ffb9 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -261,7 +261,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
     return count;
 }
 
-void
+DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
@@ -272,7 +272,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
     DisplayModePtr mode;
     DisplayModePtr test;
     xf86MonPtr		    edid_mon;
-    DisplayModePtr	    modes;
+    DisplayModePtr	    modes = NULL;
 
     /* force reprobe */
     radeon_output->MonType = MT_UNKNOWN;
@@ -283,8 +283,8 @@ RADEONProbeOutputModes(xf86OutputPtr out
       edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
       xf86OutputSetEDID (output, edid_mon);
       
-      output->probed_modes = xf86OutputGetEDIDModes (output);
-      return;
+      modes = xf86OutputGetEDIDModes (output);
+      return modes;
     }
     if (radeon_output->type == OUTPUT_LVDS) {
       /* okay we got DDC info */
@@ -307,20 +307,20 @@ RADEONProbeOutputModes(xf86OutputPtr out
       }
       
       
-      if (output->probed_modes == NULL) {
+      if (modes == NULL) {
 	MonRec fixed_mon;
 	DisplayModePtr modes;
 	
-	RADEONValidateFPModes(pScrn, pScrn->display->modes, &output->probed_modes);
+	RADEONValidateFPModes(pScrn, pScrn->display->modes, &modes);
       }
     }
     
-    if (output->probed_modes) {
-      xf86ValidateModesUserConfig(pScrn,
-					output->probed_modes);
-      xf86PruneInvalidModes(pScrn, &output->probed_modes,
+    if (modes) {
+      xf86ValidateModesUserConfig(pScrn, modes);
+      xf86PruneInvalidModes(pScrn, &modes,
 				  FALSE);
     }
+    return modes;
 }
 
 
diff-tree 96acf6b2b242454345cc4b9cfc7ca07e0b597b43 (from 76bc53f9b153880730ab61dcd2b6e4e7717e4058)
Author: David Airlie <airlied at linux.ie>
Date:   Fri Feb 2 14:26:19 2007 +1100

    bring over setproperty from intel code

diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 23e4dad..925a01f 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -683,6 +683,23 @@ xf86RandR12CrtcSetGamma (ScreenPtr    pS
     return TRUE;
 }
 
+static Bool
+xf86RandR12OutputSetProperty (ScreenPtr pScreen,
+                              RROutputPtr randr_output,
+                              Atom property,
+                              RRPropertyValuePtr value)
+{
+    xf86OutputPtr output = randr_output->devPrivate;
+
+    /* If we don't have any property handler, then we don't care what the
+     * user is setting properties to.
+     */
+    if (output->funcs->set_property == NULL)
+        return TRUE;
+
+    return output->funcs->set_property(output, property, value);
+}
+
 /**
  * Given a list of xf86 modes and a RandR Output object, construct
  * RandR modes and assign them to the output
@@ -908,6 +925,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
     rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
     rp->rrCrtcSet = xf86RandR12CrtcSet;
     rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
+    rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
     rp->rrSetConfig = NULL;
     pScrn->PointerMoved = xf86RandR12PointerMoved;
     if (!xf86RandR12CreateObjects12 (pScreen))
diff-tree 76bc53f9b153880730ab61dcd2b6e4e7717e4058 (from 47fb9ce657f018177a35b449a4d716dc03be9327)
Author: David Airlie <airlied at linux.ie>
Date:   Fri Feb 2 14:15:03 2007 +1100

    move i2c buses into outputs

diff --git a/src/radeon.h b/src/radeon.h
index 211385d..204c1f2 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -476,8 +476,6 @@ typedef struct {
     Bool              ddc_bios;
     Bool              ddc1;
     Bool              ddc2;
-    I2CBusPtr         pI2CBus;
-    CARD32            DDCReg;
 
     RADEONPLLRec      pll;
     RADEONTMDSPll     tmds_pll[4];
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 07df70d..813f277 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -177,7 +177,7 @@ static void RADEONI2CGetBits(I2CBusPtr b
     unsigned char *RADEONMMIO = info->MMIO;
 
     /* Get the result */
-    val = INREG(info->DDCReg);
+    val = INREG(b->DriverPrivate.uval);
 
     *Clock = (val & RADEON_GPIO_Y_1) != 0;
     *data  = (val & RADEON_GPIO_Y_0) != 0;
@@ -190,29 +190,32 @@ static void RADEONI2CPutBits(I2CBusPtr b
     unsigned long  val;
     unsigned char *RADEONMMIO = info->MMIO;
 
-    val = INREG(info->DDCReg) & (CARD32)~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1);
+    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(info->DDCReg, val);
+    OUTREG(b->DriverPrivate.uval, val);
 
     /* read back to improve reliability on some cards. */
-    val = INREG(info->DDCReg);
+    val = INREG(b->DriverPrivate.uval);
 }
 
-Bool RADEONI2cInit(ScrnInfoPtr pScrn)
+Bool RADEONI2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
 {
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    I2CBusPtr pI2CBus;
+
+    pI2CBus = xf86CreateI2CBusRec();
+    if (!pI2CBus) return FALSE;
 
-    info->pI2CBus = xf86CreateI2CBusRec();
-    if (!info->pI2CBus) return FALSE;
+    pI2CBus->BusName    = name;
+    pI2CBus->scrnIndex  = pScrn->scrnIndex;
+    pI2CBus->I2CPutBits = RADEONI2CPutBits;
+    pI2CBus->I2CGetBits = RADEONI2CGetBits;
+    pI2CBus->AcknTimeout = 5;
+    pI2CBus->DriverPrivate.uval = i2c_reg;
 
-    info->pI2CBus->BusName    = "DDC";
-    info->pI2CBus->scrnIndex  = pScrn->scrnIndex;
-    info->pI2CBus->I2CPutBits = RADEONI2CPutBits;
-    info->pI2CBus->I2CGetBits = RADEONI2CGetBits;
-    info->pI2CBus->AcknTimeout = 5;
+    if (!xf86I2CBusInit(pI2CBus)) return FALSE;
 
-    if (!xf86I2CBusInit(info->pI2CBus)) return FALSE;
+    *bus_ptr = pI2CBus;
     return TRUE;
 }
 
@@ -550,88 +553,71 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoP
 }
 
 
-static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr port)
+static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr output)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     unsigned long DDCReg;
     RADEONMonitorType MonType = MT_NONE;
-    xf86MonPtr* MonInfo = &port->MonInfo;
-    RADEONOutputPrivatePtr radeon_output = port->driver_private;
+    xf86MonPtr* MonInfo = &output->MonInfo;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i, j;
 
-    DDCReg = info->DDCReg;
-    switch(DDCType)
-    {
-    case DDC_MONID:
-	info->DDCReg = RADEON_GPIO_MONID;
-	break;
-    case DDC_DVI:
-	info->DDCReg = RADEON_GPIO_DVI_DDC;
-	break;
-    case DDC_VGA:
-	info->DDCReg = RADEON_GPIO_VGA_DDC;
-	break;
-    case DDC_CRT2:
-	info->DDCReg = RADEON_GPIO_CRT2_DDC;
-	break;
-    default:
-	info->DDCReg = DDCReg;
-	return MT_NONE;
-    }
+    DDCReg = radeon_output->DDCReg;
 
     /* Read and output monitor info using DDC2 over I2C bus */
-    if (info->pI2CBus && info->ddc2) {
-	OUTREG(info->DDCReg, INREG(info->DDCReg) &
+    if (radeon_output->pI2CBus && info->ddc2) {
+
+	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(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));
+	OUTREG(DDCReg, INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
 	for (j = 0; j < 3; j++) {
-	    OUTREG(info->DDCReg,
-		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
 	    usleep(13000);
 
-	    OUTREG(info->DDCReg,
-		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
 	    for (i = 0; i < 10; i++) {
 		usleep(15000);
-		if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)
+		if (INREG(DDCReg) & RADEON_GPIO_Y_1)
 		    break;
 	    }
 	    if (i == 10) continue;
 
 	    usleep(15000);
 
-	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
 	    usleep(15000);
 
-	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
 	    usleep(15000);
-	    OUTREG(info->DDCReg,
-		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
 	    usleep(15000);
-	    *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, info->pI2CBus);
+	    *MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, radeon_output->pI2CBus);
 
-	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
-	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
 	    usleep(15000);
-	    OUTREG(info->DDCReg,
-		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_1));
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_1));
 	    for (i = 0; i < 5; i++) {
 		usleep(15000);
-		if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)
+		if (INREG(DDCReg) & RADEON_GPIO_Y_1)
 		    break;
 	    }
 	    usleep(15000);
-	    OUTREG(info->DDCReg,
-		   INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0));
+	    OUTREG(DDCReg,
+		   INREG(DDCReg) & ~(RADEON_GPIO_EN_0));
 	    usleep(15000);
 
-	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_1);
-	    OUTREG(info->DDCReg, INREG(info->DDCReg) | RADEON_GPIO_EN_0);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_1);
+	    OUTREG(DDCReg, INREG(DDCReg) | RADEON_GPIO_EN_0);
 	    usleep(15000);
 	    if(*MonInfo) break;
 	}
@@ -640,7 +626,7 @@ static RADEONMonitorType RADEONDisplayDD
 	MonType = MT_NONE;
     }
 
-    OUTREG(info->DDCReg, INREG(info->DDCReg) &
+    OUTREG(DDCReg, INREG(DDCReg) &
 	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
 
     if (*MonInfo) {
@@ -662,8 +648,6 @@ static RADEONMonitorType RADEONDisplayDD
 	} else MonType = MT_CRT;
     } else MonType = MT_NONE;
 
-    info->DDCReg = DDCReg;
-
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "DDC Type: %d, Detected Type: %d\n", DDCType, MonType);
 
@@ -1140,7 +1124,24 @@ void RADEONSetupConnectors(ScrnInfoPtr p
             pRADEONEnt->PortInfo[1]->ConnectorType = CONNECTOR_DVI_I;
             pRADEONEnt->PortInfo[0]->TMDSType = TMDS_UNKNOWN;
 	}
+    }
+
+    for (i = 0; i < 2; i++) {
+      int DDCReg = 0;
+      char *names[] = { "DDC1", "DDC2" };
 
+      switch(pRADEONEnt->PortInfo[i]->DDCType) {
+      case DDC_MONID: DDCReg = RADEON_GPIO_MONID; break;
+      case DDC_DVI  : DDCReg = RADEON_GPIO_DVI_DDC; break;
+      case DDC_VGA: DDCReg = RADEON_GPIO_VGA_DDC; break;
+      case DDC_CRT2: DDCReg = RADEON_GPIO_CRT2_DDC; break;
+      default: break;
+      }
+      
+      if (DDCReg) {
+	pRADEONEnt->PortInfo[i]->DDCReg = DDCReg;
+	RADEONI2CInit(pScrn, &pRADEONEnt->PortInfo[i]->pI2CBus, DDCReg, names[i]);
+      }
     }
 }
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 2706a0d..5371c4c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1922,9 +1922,7 @@ static void RADEONPreInitDDC(ScrnInfoPtr
     if (info->ddc2) {
 	if (xf86LoadSubModule(pScrn, "i2c")) {
 	    xf86LoaderReqSymLists(i2cSymbols,NULL);
-	    info->ddc2 = RADEONI2cInit(pScrn);
 	}
-	else info->ddc2 = FALSE;
     }
 }
 
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 16c2c30..fb7727e 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -269,65 +269,49 @@ RADEONProbeOutputModes(xf86OutputPtr out
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    DisplayModePtr ddc_modes, mode;
+    DisplayModePtr mode;
     DisplayModePtr test;
+    xf86MonPtr		    edid_mon;
+    DisplayModePtr	    modes;
 
     /* force reprobe */
     radeon_output->MonType = MT_UNKNOWN;
 	
     RADEONConnectorFindMonitor(pScrn, output);
-    
-    /* okay we got DDC info */
-    if (output->MonInfo) {
-      /* Debug info for now, at least */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
-      xf86PrintEDID(output->MonInfo);
-      
-      ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
+
+    if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
+      edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
+      xf86OutputSetEDID (output, edid_mon);
       
-      for (mode = ddc_modes; mode != NULL; mode = mode->next) {
-	if (mode->Flags & V_DBLSCAN) {
-	  if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+      output->probed_modes = xf86OutputGetEDIDModes (output);
+      return;
+    }
+    if (radeon_output->type == OUTPUT_LVDS) {
+      /* okay we got DDC info */
+      if (output->MonInfo) {
+	/* Debug info for now, at least */
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
+	xf86PrintEDID(output->MonInfo);
+	
+	modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
+	
+	for (mode = modes; mode != NULL; mode = mode->next) {
+	  if (mode->Flags & V_DBLSCAN) {
+	    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
 	    mode->status = MODE_CLOCK_RANGE;
+	  }
 	}
+	xf86PruneInvalidModes(pScrn, &modes, TRUE);
+	
+	/* do some physcial size stuff */
       }
-      xf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
       
-      /* do some physcial size stuff */
-    }
-    
-    
-    if (output->probed_modes == NULL) {
-      MonRec fixed_mon;
-      DisplayModePtr modes;
       
-      switch(radeon_output->MonType) {
-      case MT_CRT:
-      case MT_DFP:
-	
-	/* We've got a potentially-connected monitor that we can't DDC.  Return a
-	 * fixed set of VESA plus user modes for a presumed multisync monitor with
-	 * some reasonable limits.
-	 */
-	fixed_mon.nHsync = 1;
-	fixed_mon.hsync[0].lo = 31.0;
-	fixed_mon.hsync[0].hi = 100.0;
-	fixed_mon.nVrefresh = 1;
-	fixed_mon.vrefresh[0].lo = 50.0;
-	fixed_mon.vrefresh[0].hi = 70.0;
+      if (output->probed_modes == NULL) {
+	MonRec fixed_mon;
+	DisplayModePtr modes;
 	
-	modes = xf86DuplicateModes(pScrn, pScrn->monitor->Modes);
-	xf86ValidateModesSync(pScrn, modes, &fixed_mon);
-	xf86PruneInvalidModes(pScrn, &modes, TRUE);
-	/* fill out CRT of FP mode table */
-	output->probed_modes = modes;
-	break;
-	
-      case MT_LCD:
 	RADEONValidateFPModes(pScrn, pScrn->display->modes, &output->probed_modes);
-	break;
-      default:
-	break;
       }
     }
     
@@ -339,42 +323,4 @@ RADEONProbeOutputModes(xf86OutputPtr out
     }
 }
 
-/**
- * Takes the output mode lists and decides the default root window size
- * and framebuffer pitch.
- */
-void
-RADEON_set_default_screen_size(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    int maxX = -1, maxY = -1;
-    int i;
-
-    /* Set up a virtual size that will cover any clone mode we'd want to
-     * set for the currently-connected outputs.
-     */
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-	DisplayModePtr mode;
-
-	for (mode = pRADEONEnt->pOutput[i]->probed_modes; mode != NULL;
-	     mode = mode->next)
-	{
-	    if (mode->HDisplay > maxX)
-		maxX = mode->HDisplay;
-	    if (mode->VDisplay > maxY)
-		maxY = mode->VDisplay;
-	}
-    }
-    /* let the user specify a bigger virtual size if they like */
-    if (pScrn->display->virtualX > maxX)
-	maxX = pScrn->display->virtualX;
-    if (pScrn->display->virtualY > maxY)
-	maxY = pScrn->display->virtualY;
-    pScrn->virtualX = maxX;
-    pScrn->virtualY = maxY;
-    pScrn->displayWidth = (maxX + 63) & ~63;
-}
-
-
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index b62bcf6..66210a4 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -132,6 +132,8 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONConnectorType ConnectorType;
     RADEONMonitorType MonType;
     int crtc_num;
+    int DDCReg;
+    I2CBusPtr         pI2CBus;
 } RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 #define RADEON_MAX_CONNECTOR 2
diff-tree 47fb9ce657f018177a35b449a4d716dc03be9327 (from 720730b1b0de632488d3b9818210ec5e9c7f07ae)
Author: David Airlie <airlied at linux.ie>
Date:   Fri Feb 2 11:45:40 2007 +1100

    fixup callers to crtcsetmode fixes my cursors

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 0b13d49..07df70d 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2583,19 +2583,6 @@ RADEONCrtcSetBase(xf86CrtcPtr crtc, int 
 }
 
 Bool
-RADEONCrtcInUse(xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int	i;
-    
-    for (i = 0; i < xf86_config->num_output; i++)
-	if (xf86_config->output[i]->crtc == crtc)
-	    return TRUE;
-    return FALSE;
-}
-
-Bool
 RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
 		  int x, int y)
 {
@@ -2606,13 +2593,13 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     int i , ret;
     DisplayModeRec	saved_mode;
-    int saved_x, saved_y;
-    Rotation saved_rotation;
+    int 		saved_x, saved_y;
+    Rotation 		saved_rotation;
     /* XXX: mode */
 
     adjusted_mode = xf86DuplicateMode(mode);
     
-    crtc->enabled = RADEONCrtcInUse (crtc);
+    crtc->enabled = xf86CrtcInUse (crtc);
 
     if (!crtc->enabled) {
       return TRUE;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index f984b20..2706a0d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3644,7 +3644,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 		crtc->desiredY = 0;
 	    }
 
-	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE))
+	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, crtc->desiredX, crtc->desiredY))
 		return FALSE;
 
 	}
@@ -6338,7 +6338,8 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 		crtc->desiredY = 0;
 	    }
 
-	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE))
+	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
+				    crtc->desiredX, crtc->desiredY))
 		return FALSE;
 
 	}
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index d9683ec..23e4dad 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -635,7 +635,7 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	radeon_crtc->binding = info->IsSecondary ? 2 : 1;
 	if (mode) {
   	    info->IsSwitching = TRUE;
-	    if (!RADEONCrtcSetMode (crtc, mode, TRUE))
+	    if (!RADEONCrtcSetMode (crtc, mode, rotation, x, y))
 	    {
 		crtc->enabled = save_enabled;
 		for (o = 0; o < config->num_output; o++)
diff-tree 720730b1b0de632488d3b9818210ec5e9c7f07ae (from 6748732658850ea506f623a3622aa7135513ffd0)
Author: David Airlie <airlied at linux.ie>
Date:   Thu Feb 1 16:43:38 2007 +1100

    add locks for crtcs and some missing lines from intel update

diff --git a/src/radeon_display.c b/src/radeon_display.c
index a8df106..0b13d49 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2289,8 +2289,16 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
 static Bool
 radeon_crtc_lock(xf86CrtcPtr crtc)
 {
+  ScrnInfoPtr		pScrn = crtc->scrn;
+  RADEONInfoPtr  info = RADEONPTR(pScrn);
+  Bool           CPStarted   = info->CPStarted;
+  if (info->accelOn)
+    RADEON_SYNC(info, pScrn);
 #ifdef XF86DRI
-	/* TODO */
+    if (info->CPStarted) {
+	DRILock(pScrn->pScreen, 0);
+	RADEONCP_STOP(pScrn, info);
+    }
 #endif
     return FALSE;
 }
@@ -2298,8 +2306,19 @@ radeon_crtc_lock(xf86CrtcPtr crtc)
 static void
 radeon_crtc_unlock(xf86CrtcPtr crtc)
 {
+  ScrnInfoPtr		pScrn = crtc->scrn;
+  RADEONInfoPtr  info = RADEONPTR(pScrn);
+
+  if (info->accelOn) {
+    RADEON_SYNC(info, pScrn);
+    RADEONEngineRestore(pScrn);
+    
+}
 #ifdef XF86DRI
-	/* TODO */
+  if (info->CPStarted) {
+    RADEONCP_START(pScrn, info);
+    DRIUnlock(pScrn->pScreen);
+  }
 #endif
 
 }
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 97c9295..d9683ec 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -586,7 +586,6 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     xf86CrtcPtr		crtc = randr_crtc->devPrivate;
     DisplayModePtr	mode = randr_mode ? randr_mode->devPrivate : NULL;
     Bool		changed = FALSE;
-    Bool		pos_changed;
     int			o, ro;
     xf86CrtcPtr		*save_crtcs;
     Bool save_enabled = crtc->enabled;
@@ -598,9 +597,8 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     else if (mode && !xf86ModesEqual (&crtc->mode, mode))
 	changed = TRUE;
     
-    pos_changed = changed;
     if (x != crtc->x || y != crtc->y)
-	pos_changed = TRUE;
+	changed = TRUE;
     
     for (o = 0; o < config->num_output; o++) {
 	xf86OutputPtr  output = config->output[o];
@@ -649,6 +647,9 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 		return FALSE;
 	    }
 	    crtc->desiredMode = *mode;
+	    crtc->desiredRotation = rotation;
+	    crtc->desiredX = x;
+	    crtc->desiredY = y;
 
 	    RADEONDisableUnusedFunctions(pScrn);
 	    RADEONBlank(pScrn);
@@ -660,7 +661,7 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	  RADEONInitDispBandwidth(pScrn);
     
     }
-    if (pos_changed && mode)
+    if (changed && mode)
 	RADEONCrtcSetBase(crtc, x, y);
     DEALLOCATE_LOCAL(save_crtcs);
     return xf86RandR12CrtcNotify (randr_crtc);
diff-tree 6748732658850ea506f623a3622aa7135513ffd0 (from a77f08298dc7e097025e3f7f92e3665c0ef30095)
Author: David Airlie <airlied at linux.ie>
Date:   Thu Feb 1 16:26:31 2007 +1100

    update to latest intel codebase modulo using their mode set
    
    and it breaks my cursor

diff --git a/src/Makefile.am b/src/Makefile.am
index 0ec7c29..ae2b002 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,7 +83,7 @@ radeon_drv_la_SOURCES = \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
 	radeon_xf86Crtc.c radeon_xf86Modes.c radeon_randr.c \
-	radeon_edid_modes.c radeon_xf86cvt.c \
+	radeon_edid_modes.c radeon_xf86cvt.c radeon_xf86Rotate.c \
 	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
diff --git a/src/local_xf86Rename.h b/src/local_xf86Rename.h
new file mode 100644
index 0000000..5102170
--- /dev/null
+++ b/src/local_xf86Rename.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#define XF86NAME(x) radeon_##x
diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 8c3dcfa..6d61b07 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -202,7 +202,7 @@ RADEONRandrSetCursorPosition(ScrnInfoPtr
 
     for (c = 0 ; c < xf86_config->num_crtc; c++) {
 	xf86CrtcPtr crtc = xf86_config->crtc[c];
-	DisplayModePtr mode = &crtc->curMode;
+	DisplayModePtr mode = &crtc->mode;
 	int thisx = x - crtc->x;
 	int thisy = y - crtc->y;
 	
diff --git a/src/radeon_display.c b/src/radeon_display.c
index e769e15..a8df106 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -45,6 +45,7 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
+#include "radeon_xf86Modes.h"
 
 
 void radeon_crtc_load_lut(xf86CrtcPtr crtc);
@@ -2021,12 +2022,12 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
 
       if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
 	pixel_bytes2 = info->CurrentLayout.pixel_bytes;
-	mode1 = &xf86_config->crtc[0]->curMode;
-	mode2 = &xf86_config->crtc[1]->curMode;
+	mode1 = &xf86_config->crtc[0]->mode;
+	mode2 = &xf86_config->crtc[1]->mode;
       } else if (xf86_config->crtc[0]->enabled) {
-	mode1 = &xf86_config->crtc[0]->curMode;
+	mode1 = &xf86_config->crtc[0]->mode;
       } else if (xf86_config->crtc[1]->enabled) {
-	mode1 = &xf86_config->crtc[1]->curMode;
+	mode1 = &xf86_config->crtc[1]->mode;
       } else
 	return;
     }
@@ -2228,7 +2229,7 @@ radeon_crtc_mode_fixup(xf86CrtcPtr crtc,
 
 static void
 radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
-		   DisplayModePtr adjusted_mode)
+		     DisplayModePtr adjusted_mode, int x, int y)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@@ -2285,6 +2286,24 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
     radeon_crtc_load_lut(crtc);
 }
 
+static Bool
+radeon_crtc_lock(xf86CrtcPtr crtc)
+{
+#ifdef XF86DRI
+	/* TODO */
+#endif
+    return FALSE;
+}
+
+static void
+radeon_crtc_unlock(xf86CrtcPtr crtc)
+{
+#ifdef XF86DRI
+	/* TODO */
+#endif
+
+}
+
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
     .dpms = radeon_crtc_dpms,
     .save = NULL, /* XXX */
@@ -2292,6 +2311,8 @@ static const xf86CrtcFuncsRec radeon_crt
     .mode_fixup = radeon_crtc_mode_fixup,
     .mode_set = radeon_crtc_mode_set,
     .gamma_set = radeon_crtc_gamma_set,
+    .lock = radeon_crtc_lock,
+    .unlock = radeon_crtc_unlock,
     .destroy = NULL, /* XXX */
 };
 
@@ -2556,16 +2577,21 @@ RADEONCrtcInUse(xf86CrtcPtr crtc)
 }
 
 Bool
-RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
+RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+		  int x, int y)
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);  
     DisplayModePtr adjusted_mode;
+    Bool		didLock = FALSE;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     int i , ret;
-    /* XXX: curMode */
+    DisplayModeRec	saved_mode;
+    int saved_x, saved_y;
+    Rotation saved_rotation;
+    /* XXX: mode */
 
-    adjusted_mode = xf86DuplicateMode(pMode);
+    adjusted_mode = xf86DuplicateMode(mode);
     
     crtc->enabled = RADEONCrtcInUse (crtc);
 
@@ -2573,6 +2599,21 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
       return TRUE;
     }
 
+    didLock = crtc->funcs->lock (crtc);
+
+    saved_mode = crtc->mode;
+    saved_x = crtc->x;
+    saved_y = crtc->y;
+    saved_rotation = crtc->rotation;
+
+    /* Update crtc values up front so the driver can rely on them for mode
+     * setting.
+     */
+    crtc->mode = *mode;
+    crtc->x = x;
+    crtc->y = y;
+    crtc->rotation = rotation;
+
     /* Pass our mode to the outputs and the CRTC to give them a chance to
      * adjust it according to limitations or output properties, and also
      * a chance to reject the mode entirely.
@@ -2583,17 +2624,21 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
 	if (output->crtc != crtc)
 	    continue;
 
-	if (!output->funcs->mode_fixup(output, pMode, adjusted_mode)) {
+	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
 	    ret = FALSE;
 	    goto done;
 	}
     }
 
-    if (!crtc->funcs->mode_fixup(crtc, pMode, adjusted_mode)) {
+    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
 	ret = FALSE;
 	goto done;
     }
 
+    if (!xf86CrtcRotate (crtc, mode, rotation)) {
+	goto done;
+    }
+
 #if 0
     /* Disable the outputs and CRTCs before setting the mode. */
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -2612,11 +2657,11 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
     /* Set up the DPLL and any output state that needs to adjust or depend
      * on the DPLL.
      */
-    crtc->funcs->mode_set(crtc, pMode, adjusted_mode);
+    crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
     for (i = 0; i < xf86_config->num_output; i++) {
 	xf86OutputPtr output = xf86_config->output[i];
 	if (output->crtc == crtc)
-	    output->funcs->mode_set(output, pMode, adjusted_mode);
+	    output->funcs->mode_set(output, mode, adjusted_mode);
     }
 
 #if 0
@@ -2628,12 +2673,21 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
 	    output->funcs->dpms(output, DPMSModeOn);
     }
 #endif
-    crtc->curMode = *pMode;
     
     /* XXX free adjustedmode */
     ret = TRUE;
 
  done:
+    if (!ret) {
+	crtc->x = saved_x;
+	crtc->y = saved_y;
+	crtc->rotation = saved_rotation;
+	crtc->mode = saved_mode;
+    }
+
+    if (didLock)
+	crtc->funcs->unlock (crtc);
+
     return ret;
 }
 
@@ -2757,7 +2811,7 @@ RADEONDisableUnusedFunctions(ScrnInfoPtr
     {
 	xf86CrtcPtr crtc = xf86_config->crtc[c];
 	if (!crtc->enabled) {
-		memset(&crtc->curMode, 0, sizeof(crtc->curMode));
+		memset(&crtc->mode, 0, sizeof(crtc->mode));
 		radeon_crtc_dpms(crtc, DPMSModeOff);
 	}
     }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 44a7eb2..f984b20 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -112,6 +112,7 @@
 
 
 				/* Forward definitions for driver functions */
+void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore);
 static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
 static void RADEONSave(ScrnInfoPtr pScrn);
@@ -3635,10 +3636,14 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
 	    
 	    /* Mark that we'll need to re-set the mode for sure */
-	    memset(&crtc->curMode, 0, sizeof(crtc->curMode));
-	    if (!crtc->desiredMode.CrtcHDisplay)
+	    memset(&crtc->mode, 0, sizeof(crtc->mode));
+	    if (!crtc->desiredMode.CrtcHDisplay) {
 		crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
-	    
+		crtc->desiredRotation = RR_Rotate_0;
+		crtc->desiredX = 0;
+		crtc->desiredY = 0;
+	    }
+
 	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE))
 		return FALSE;
 
@@ -5423,8 +5428,6 @@ static Bool RADEONInitCrtcRegisters(Scrn
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     xf86OutputPtr connector;
 
-    pRADEONEnt->pCrtc[0]->curMode = *mode;
-
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
     case 8:  format = 2; break;
@@ -5611,8 +5614,6 @@ static Bool RADEONInitCrtc2Registers(Scr
     if (info->IsSecondary)
 	info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
 
-    pRADEONEnt->pCrtc[1]->curMode = *mode;
-
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
     case 8:  format = 2; break;
@@ -6329,10 +6330,14 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 	    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 	    radeon_crtc->binding = info->IsSecondary ? 2 : 1;
 	    /* Mark that we'll need to re-set the mode for sure */
-	    memset(&crtc->curMode, 0, sizeof(crtc->curMode));
-	    if (!crtc->desiredMode.CrtcHDisplay)
+	    memset(&crtc->mode, 0, sizeof(crtc->mode));
+	    if (!crtc->desiredMode.CrtcHDisplay) {
 		crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
-	    
+		crtc->desiredRotation = RR_Rotate_0;
+		crtc->desiredX = 0;
+		crtc->desiredY = 0;
+	    }
+
 	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE))
 		return FALSE;
 
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index ba14fe7..16c2c30 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -291,7 +291,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
 	    mode->status = MODE_CLOCK_RANGE;
 	}
       }
-      RADEONxf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
+      xf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
       
       /* do some physcial size stuff */
     }
@@ -316,9 +316,9 @@ RADEONProbeOutputModes(xf86OutputPtr out
 	fixed_mon.vrefresh[0].lo = 50.0;
 	fixed_mon.vrefresh[0].hi = 70.0;
 	
-	modes = RADEON_xf86DuplicateModes(pScrn, pScrn->monitor->Modes);
-	RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
-	RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
+	modes = xf86DuplicateModes(pScrn, pScrn->monitor->Modes);
+	xf86ValidateModesSync(pScrn, modes, &fixed_mon);
+	xf86PruneInvalidModes(pScrn, &modes, TRUE);
 	/* fill out CRT of FP mode table */
 	output->probed_modes = modes;
 	break;
@@ -332,9 +332,9 @@ RADEONProbeOutputModes(xf86OutputPtr out
     }
     
     if (output->probed_modes) {
-      RADEONxf86ValidateModesUserConfig(pScrn,
+      xf86ValidateModesUserConfig(pScrn,
 					output->probed_modes);
-      RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes,
+      xf86PruneInvalidModes(pScrn, &output->probed_modes,
 				  FALSE);
     }
 }
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 63b0080..97c9295 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -392,8 +392,8 @@ xf86RandR12CreateScreenResources (Screen
     for (c = 0; c < config->num_crtc; c++)
     {
 	xf86CrtcPtr crtc = config->crtc[c];
-	int	    crtc_width = crtc->x + crtc->curMode.HDisplay;
-	int	    crtc_height = crtc->y + crtc->curMode.VDisplay;
+	int	    crtc_width = crtc->x + crtc->mode.HDisplay;
+	int	    crtc_height = crtc->y + crtc->mode.VDisplay;
 	
 	if (crtc->enabled && crtc_width > width)
 	    width = crtc_width;
@@ -532,7 +532,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr	randr_c
     xf86CrtcPtr		crtc = randr_crtc->devPrivate;
     xf86OutputPtr	output;
     int			i, j;
-    DisplayModePtr	curMode = &crtc->curMode;
+    DisplayModePtr	curMode = &crtc->mode;
     Bool		ret;
 
     randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
@@ -595,7 +595,7 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
     if ((mode != NULL) != crtc->enabled)
     changed = TRUE;
-    else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
+    else if (mode && !xf86ModesEqual (&crtc->mode, mode))
 	changed = TRUE;
     
     pos_changed = changed;
diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
index df7b1bd..7e4ae39 100644
--- a/src/radeon_xf86Crtc.c
+++ b/src/radeon_xf86Crtc.c
@@ -89,6 +89,8 @@ xf86CrtcCreate (ScrnInfoPtr		scrn,
 #ifdef RANDR_12_INTERFACE
     crtc->randr_crtc = NULL;
 #endif
+    crtc->rotation = RR_Rotate_0;
+    crtc->desiredRotation = RR_Rotate_0;
     if (xf86_config->crtc)
 	crtcs = xrealloc (xf86_config->crtc,
 			  (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
@@ -123,6 +125,139 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
     xfree (crtc);
 }
 
+
+/**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+Bool
+xf86CrtcInUse (xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o;
+    
+    for (o = 0; o < xf86_config->num_output; o++)
+	if (xf86_config->output[o]->crtc == crtc)
+	    return TRUE;
+    return FALSE;
+}
+
+/**
+ * Sets the given video mode on the given crtc
+ */
+Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+		 int x, int y)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			i;
+    Bool		ret = FALSE;
+    Bool		didLock = FALSE;
+    DisplayModePtr	adjusted_mode;
+    DisplayModeRec	saved_mode;
+    int			saved_x, saved_y;
+    Rotation		saved_rotation;
+
+    adjusted_mode = xf86DuplicateMode(mode);
+
+    crtc->enabled = xf86CrtcInUse (crtc);
+    
+    if (!crtc->enabled)
+    {
+	/* XXX disable crtc? */
+	return TRUE;
+    }
+
+    didLock = crtc->funcs->lock (crtc);
+
+    saved_mode = crtc->mode;
+    saved_x = crtc->x;
+    saved_y = crtc->y;
+    saved_rotation = crtc->rotation;
+    /* Update crtc values up front so the driver can rely on them for mode
+     * setting.
+     */
+    crtc->mode = *mode;
+    crtc->x = x;
+    crtc->y = y;
+    crtc->rotation = rotation;
+
+    /* XXX short-circuit changes to base location only */
+    
+    /* Pass our mode to the outputs and the CRTC to give them a chance to
+     * adjust it according to limitations or output properties, and also
+     * a chance to reject the mode entirely.
+     */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+
+	if (output->crtc != crtc)
+	    continue;
+
+	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
+	    goto done;
+	}
+    }
+
+    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
+	goto done;
+    }
+
+    if (!xf86CrtcRotate (crtc, mode, rotation)) {
+	goto done;
+    }
+
+    /* Disable the outputs and CRTCs before setting the mode. */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+
+	if (output->crtc != crtc)
+	    continue;
+
+	/* Disable the output as the first thing we do. */
+	output->funcs->dpms(output, DPMSModeOff);
+    }
+
+    crtc->funcs->dpms(crtc, DPMSModeOff);
+
+    /* Set up the DPLL and any output state that needs to adjust or depend
+     * on the DPLL.
+     */
+    crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc)
+	    output->funcs->mode_set(output, mode, adjusted_mode);
+    }
+
+    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+    crtc->funcs->dpms(crtc, DPMSModeOn);
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc)
+	    output->funcs->dpms(output, DPMSModeOn);
+    }
+
+    /* XXX free adjustedmode */
+    ret = TRUE;
+done:
+    if (!ret) {
+	crtc->x = saved_x;
+	crtc->y = saved_y;
+	crtc->rotation = saved_rotation;
+	crtc->mode = saved_mode;
+    }
+
+    if (didLock)
+	crtc->funcs->unlock (crtc);
+
+    return ret;
+}
+
 /*
  * Output functions
  */
@@ -364,14 +499,14 @@ xf86OutputHasPreferredMode (xf86OutputPt
 }
 
 static int
-xf86PickCrtcs (ScrnInfoPtr	pScrn,
+xf86PickCrtcs (ScrnInfoPtr	scrn,
 	       xf86CrtcPtr	*best_crtcs,
 	       DisplayModePtr	*modes,
 	       int		n,
 	       int		width,
 	       int		height)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int		    c, o, l;
     xf86OutputPtr   output;
     xf86CrtcPtr	    crtc;
@@ -390,7 +525,7 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
      */
     best_crtcs[n] = NULL;
     best_crtc = NULL;
-    best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1, width, height);
+    best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
     if (modes[n] == NULL)
 	return best_score;
     
@@ -444,7 +579,7 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 	}
 	crtcs[n] = crtc;
 	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
-	score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
+	score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
 	if (score > best_score)
 	{
 	    best_crtc = crtc;
@@ -464,9 +599,9 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
  */
 
 static void
-xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
+xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int	    width = 0, height = 0;
     int	    o;
     int	    c;
@@ -515,9 +650,9 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
 #define POSITION_UNSET	-100000
 
 static Bool
-xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
+xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			o;
     int			min_x, min_y;
     
@@ -565,7 +700,7 @@ xf86InitialOutputPositions (ScrnInfoPtr 
 		}
 		else
 		{
-		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
 				"Output %s position not of form \"x y\"\n",
 				output->name);
 		    output->initial_x = output->initial_y = 0;
@@ -608,7 +743,7 @@ xf86InitialOutputPositions (ScrnInfoPtr 
 		}
 		if (!relative)
 		{
-		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
 				"Cannot position output %s relative to unknown output %s\n",
 				output->name, relative_name);
 		    output->initial_x = 0;
@@ -657,7 +792,7 @@ xf86InitialOutputPositions (ScrnInfoPtr 
 		xf86OutputPtr   output = config->output[o];
 		if (output->initial_x == POSITION_UNSET)
 		{
-		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
 				"Output position loop. Moving %s to 0,0\n",
 				output->name);
 		    output->initial_x = output->initial_y = 0;
@@ -780,16 +915,16 @@ i830xf86SortModes (DisplayModePtr input)
 #define DEBUG_REPROBE 1
 
 void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
+xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			o;
 
     if (maxX == 0 || maxY == 0)
-	xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY);
+	xf86RandR12GetOriginalVirtualSize (scrn, &maxX, &maxY);
 
     /* Elide duplicate modes before defaulting code uses them */
-    xf86PruneDuplicateMonitorModes (pScrn->monitor);
+    xf86PruneDuplicateMonitorModes (scrn->monitor);
     
     /* Probe the list of modes for each output. */
     for (o = 0; o < config->num_output; o++) 
@@ -839,7 +974,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 		mon_rec.nVrefresh++;
 		sync_source = sync_config;
 	    }
-	    config_modes = RADEONxf86GetMonitorModes (pScrn, conf_monitor);
+	    config_modes = xf86GetMonitorModes (scrn, conf_monitor);
 	}
 	
 	output_modes = (*output->funcs->get_modes) (output);
@@ -903,27 +1038,27 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	    mon_rec.vrefresh[0].hi = 62.0;
 	    mon_rec.nVrefresh = 1;
 	}
-	default_modes = RADEONxf86GetDefaultModes (output->interlaceAllowed,
-						 output->doubleScanAllowed);
+	default_modes = xf86GetDefaultModes (output->interlaceAllowed,
+					     output->doubleScanAllowed);
 	
 	if (sync_source == sync_config)
 	{
 	    /* 
 	     * Check output and config modes against sync range from config file
 	     */
-	    RADEONxf86ValidateModesSync (pScrn, output_modes, &mon_rec);
-	    RADEONxf86ValidateModesSync (pScrn, config_modes, &mon_rec);
+	    xf86ValidateModesSync (scrn, output_modes, &mon_rec);
+	    xf86ValidateModesSync (scrn, config_modes, &mon_rec);
 	}
 	/*
 	 * Check default modes against sync range
 	 */
-        RADEONxf86ValidateModesSync (pScrn, default_modes, &mon_rec);
+        xf86ValidateModesSync (scrn, default_modes, &mon_rec);
 	/*
 	 * Check default modes against monitor max clock
 	 */
 	if (max_clock)
-	    RADEONxf86ValidateModesClocks(pScrn, default_modes,
-					&min_clock, &max_clock, 1);
+	    xf86ValidateModesClocks(scrn, default_modes,
+				    &min_clock, &max_clock, 1);
 	
 	output->probed_modes = NULL;
 	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
@@ -934,7 +1069,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	 * Check all modes against max size
 	 */
 	if (maxX && maxY)
-	    RADEONxf86ValidateModesSize (pScrn, output->probed_modes,
+	    xf86ValidateModesSize (scrn, output->probed_modes,
 				       maxX, maxY, 0);
 	 
 	/*
@@ -944,7 +1079,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	    if (mode->status == MODE_OK)
 		mode->status = (*output->funcs->mode_valid)(output, mode);
 	
-	RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE);
+	xf86PruneInvalidModes(scrn, &output->probed_modes, TRUE);
 	
 	output->probed_modes = i830xf86SortModes (output->probed_modes);
 	
@@ -977,11 +1112,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	
 #ifdef DEBUG_REPROBE
 	if (output->probed_modes != NULL) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
 		       "Printing probed modes for output %s\n",
 		       output->name);
 	} else {
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	    xf86DrvMsg(scrn->scrnIndex, X_INFO,
 		       "No remaining probed modes for output %s\n",
 		       output->name);
 	}
@@ -995,7 +1130,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 	    xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
 
 #ifdef DEBUG_REPROBE
-	    xf86PrintModeline(pScrn->scrnIndex, mode);
+	    xf86PrintModeline(scrn->scrnIndex, mode);
 #endif
 	}
     }
@@ -1008,12 +1143,12 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 
 /* XXX where does this function belong? Here? */
 void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
 
 void
-xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
+xf86SetScrnInfoModes (ScrnInfoPtr scrn)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86OutputPtr	output;
     xf86CrtcPtr		crtc;
     DisplayModePtr	last, mode;
@@ -1037,31 +1172,31 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     }
     crtc = output->crtc;
 
-    /* Clear any existing modes from pScrn->modes */
-    while (pScrn->modes != NULL)
-	xf86DeleteMode(&pScrn->modes, pScrn->modes);
+    /* Clear any existing modes from scrn->modes */
+    while (scrn->modes != NULL)
+	xf86DeleteMode(&scrn->modes, scrn->modes);
 
-    /* Set pScrn->modes to the mode list for the 'compat' output */
-    pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
+    /* Set scrn->modes to the mode list for the 'compat' output */
+    scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
 
-    for (mode = pScrn->modes; mode; mode = mode->next)
+    for (mode = scrn->modes; mode; mode = mode->next)
 	if (xf86ModesEqual (mode, &crtc->desiredMode))
 	    break;
 
-    if (pScrn->modes != NULL) {
-	/* For some reason, pScrn->modes is circular, unlike the other mode
+    if (scrn->modes != NULL) {
+	/* For some reason, scrn->modes is circular, unlike the other mode
 	 * lists.  How great is that?
 	 */
-	for (last = pScrn->modes; last && last->next; last = last->next)
+	for (last = scrn->modes; last && last->next; last = last->next)
 	    ;
-	last->next = pScrn->modes;
-	pScrn->modes->prev = last;
+	last->next = scrn->modes;
+	scrn->modes->prev = last;
 	if (mode) {
-	    while (pScrn->modes != mode)
-		pScrn->modes = pScrn->modes->next;
+	    while (scrn->modes != mode)
+		scrn->modes = scrn->modes->next;
 	}
     }
-    pScrn->currentMode = pScrn->modes;
+    scrn->currentMode = scrn->modes;
 }
 
 /**
@@ -1072,9 +1207,9 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
  */
 
 Bool
-xf86InitialConfiguration (ScrnInfoPtr	    pScrn)
+xf86InitialConfiguration (ScrnInfoPtr	    scrn)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			o, c;
     DisplayModePtr	target_mode = NULL;
     xf86CrtcPtr		*crtcs;
@@ -1083,16 +1218,16 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     int			width;
     int			height;
 
-    if (pScrn->display->virtualX)
-	width = pScrn->display->virtualX;
+    if (scrn->display->virtualX)
+	width = scrn->display->virtualX;
     else
 	width = config->maxWidth;
-    if (pScrn->display->virtualY)
-	height = pScrn->display->virtualY;
+    if (scrn->display->virtualY)
+	height = scrn->display->virtualY;
     else
 	height = config->maxHeight;
 
-    xf86ProbeOutputModes (pScrn, width, height);
+    xf86ProbeOutputModes (scrn, width, height);
 
     crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
     modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
@@ -1154,7 +1289,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     /*
      * Set the position of each output
      */
-    if (!xf86InitialOutputPositions (pScrn, modes))
+    if (!xf86InitialOutputPositions (scrn, modes))
     {
 	xfree (crtcs);
 	xfree (modes);
@@ -1164,7 +1299,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     /*
      * Assign CRTCs to fit output configuration
      */
-    if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
+    if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
     {
 	xfree (crtcs);
 	xfree (modes);
@@ -1173,8 +1308,8 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     
     /* XXX override xf86 common frame computation code */
     
-    pScrn->display->frameX0 = 0;
-    pScrn->display->frameY0 = 0;
+    scrn->display->frameX0 = 0;
+    scrn->display->frameY0 = 0;
     
     for (c = 0; c < config->num_crtc; c++)
     {
@@ -1203,24 +1338,24 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	}
     }
     
-    if (pScrn->display->virtualX == 0)
+    if (scrn->display->virtualX == 0)
     {
 	/*
 	 * Expand virtual size to cover potential mode switches
 	 */
-	xf86DefaultScreenLimits (pScrn, &width, &height);
+	xf86DefaultScreenLimits (scrn, &width, &height);
     
-	pScrn->display->virtualX = width;
-	pScrn->display->virtualY = height;
+	scrn->display->virtualX = width;
+	scrn->display->virtualY = height;
     }
 
-    if (width > pScrn->virtualX)
-	pScrn->virtualX = width;
-    if (height > pScrn->virtualY)
-	pScrn->virtualY = height;
+    if (width > scrn->virtualX)
+	scrn->virtualX = width;
+    if (height > scrn->virtualY)
+	scrn->virtualY = height;
     
-    /* Mirror output modes to pScrn mode list */
-    xf86SetScrnInfoModes (pScrn);
+    /* Mirror output modes to scrn mode list */
+    xf86SetScrnInfoModes (scrn);
     
     xfree (crtcs);
     xfree (modes);
@@ -1234,11 +1369,14 @@ xf86InitialConfiguration (ScrnInfoPtr	  
  * Otherwise, it will affect CRTCs before outputs.
  */
 void
-xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
+xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
 {
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			i;
 
+    if (!scrn->vtSema)
+	return;
+
     if (mode == DPMSModeOff) {
 	for (i = 0; i < config->num_output; i++) {
 	    xf86OutputPtr output = config->output[i];
@@ -1262,6 +1400,53 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode,
     }
 }
 
+/**
+ * Implement the screensaver by just calling down into the driver DPMS hooks.
+ *
+ * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
+ * the outputs will still get disabled (blanked).
+ */
+Bool
+xf86SaveScreen(ScreenPtr pScreen, int mode)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+    if (xf86IsUnblank(mode))
+	xf86DPMSSet(pScrn, DPMSModeOn, 0);
+    else
+	xf86DPMSSet(pScrn, DPMSModeOff, 0);
+
+    return TRUE;
+}
+
+/**
+ * Disable all inactive crtcs and outputs
+ */
+void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o, c;
+
+    for (o = 0; o < xf86_config->num_output; o++) 
+    {
+	xf86OutputPtr  output = xf86_config->output[o];
+	if (!output->crtc) 
+	    (*output->funcs->dpms)(output, DPMSModeOff);
+    }
+
+    for (c = 0; c < xf86_config->num_crtc; c++) 
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (!crtc->enabled) 
+	{
+	    crtc->funcs->dpms(crtc, DPMSModeOff);
+	    memset(&crtc->mode, 0, sizeof(crtc->mode));
+	}
+    }
+}
+
 #ifdef RANDR_12_INTERFACE
 
 #define EDID_ATOM_NAME		"EDID_DATA"
@@ -1292,10 +1477,10 @@ xf86OutputSetEDIDProperty (xf86OutputPtr
  * Set the EDID information for the specified output
  */
 void
-i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
 {
-    ScrnInfoPtr		pScrn = output->scrn;
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    ScrnInfoPtr		scrn = output->scrn;
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
     int			i;
 #ifdef RANDR_12_INTERFACE
     int			size;
@@ -1307,12 +1492,12 @@ i830_xf86OutputSetEDID (xf86OutputPtr ou
     output->MonInfo = edid_mon;
 
     /* Debug info for now, at least */
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
+    xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
     xf86PrintEDID(edid_mon);
     
     /* Set the DDC properties for the 'compat' output */
     if (output == config->output[config->compat_output])
-        xf86SetDDCproperties(pScrn, edid_mon);
+        xf86SetDDCproperties(scrn, edid_mon);
 
 #ifdef RANDR_12_INTERFACE
     /* Set the RandR output properties */
@@ -1356,20 +1541,20 @@ i830_xf86OutputSetEDID (xf86OutputPtr ou
  * stored in 'output'
  */
 DisplayModePtr
-i830_xf86OutputGetEDIDModes (xf86OutputPtr output)
+xf86OutputGetEDIDModes (xf86OutputPtr output)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
+    ScrnInfoPtr	scrn = output->scrn;
     xf86MonPtr	edid_mon = output->MonInfo;
 
     if (!edid_mon)
 	return NULL;
-    return xf86DDCGetModes(pScrn->scrnIndex, edid_mon);
+    return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
 }
 
 xf86MonPtr
-i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
 {
-    ScrnInfoPtr	pScrn = output->scrn;
+    ScrnInfoPtr	scrn = output->scrn;
 
-    return xf86DoEDID_DDC2 (pScrn->scrnIndex, pDDCBus);
+    return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
 }
diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h
index 2f534f8..67950da 100644
--- a/src/radeon_xf86Crtc.h
+++ b/src/radeon_xf86Crtc.h
@@ -26,6 +26,7 @@
 #include "randrstr.h"
 #include "radeon_xf86Modes.h"
 #include "xf86Parser.h"
+#include "damage.h"
 
 /* Compat definitions for older X Servers. */
 #ifndef M_T_PREFERRED
@@ -68,7 +69,19 @@ typedef struct _xf86CrtcFuncs {
    void
     (*restore)(xf86CrtcPtr	crtc);
 
-
+    /**
+     * Lock CRTC prior to mode setting, mostly for DRI.
+     * Returns whether unlock is needed
+     */
+    Bool
+    (*lock) (xf86CrtcPtr crtc);
+    
+    /**
+     * Unlock CRTC after mode setting, mostly for DRI
+     */
+    void
+    (*unlock) (xf86CrtcPtr crtc);
+    
     /**
      * Callback to adjust the mode to be set in the CRTC.
      *
@@ -87,7 +100,8 @@ typedef struct _xf86CrtcFuncs {
     void
     (*mode_set)(xf86CrtcPtr crtc,
 		DisplayModePtr mode,
-		DisplayModePtr adjusted_mode);
+		DisplayModePtr adjusted_mode,
+		int x, int y);
 
     /* Set the color ramps for the CRTC to the given values. */
     void
@@ -95,6 +109,18 @@ typedef struct _xf86CrtcFuncs {
 		 int size);
 
     /**
+     * Create shadow pixmap for rotation support
+     */
+    PixmapPtr
+    (*shadow_create) (xf86CrtcPtr crtc, int width, int height);
+    
+    /**
+     * Destroy shadow pixmap
+     */
+    void
+    (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap);
+
+    /**
      * Clean up driver-specific bits of the crtc
      */
     void
@@ -114,13 +140,6 @@ struct _xf86Crtc {
      */
     Bool	    enabled;
     
-    /**
-     * Position on screen
-     *
-     * Locates this CRTC within the frame buffer
-     */
-    int		    x, y;
-    
     /** Track whether cursor is within CRTC range  */
     Bool	    cursorInRange;
     
@@ -134,7 +153,15 @@ struct _xf86Crtc {
      * It will be cleared when the VT is not active or
      * during server startup
      */
-    DisplayModeRec  curMode;
+    DisplayModeRec  mode;
+    Rotation	    rotation;
+    PixmapPtr	    rotatedPixmap;
+    /**
+     * Position on screen
+     *
+     * Locates this CRTC within the frame buffer
+     */
+    int		    x, y;
     
     /**
      * Desired mode
@@ -145,6 +172,8 @@ struct _xf86Crtc {
      * on VT switch.
      */
     DisplayModeRec  desiredMode;
+    Rotation	    desiredRotation;
+    int		    desiredX, desiredY;
     
     /** crtc-specific functions */
     const xf86CrtcFuncsRec *funcs;
@@ -171,6 +200,13 @@ struct _xf86Crtc {
 
 typedef struct _xf86OutputFuncs {
     /**
+     * Called to allow the output a chance to create properties after the
+     * RandR objects have been created.
+     */
+    void
+    (*create_resources)(xf86OutputPtr output);
+
+    /**
      * Turns the output on/off, or sets intermediate power levels if available.
      *
      * Unsupported intermediate modes drop to the lower power setting.  If the
@@ -245,6 +281,15 @@ typedef struct _xf86OutputFuncs {
     DisplayModePtr
     (*get_modes)(xf86OutputPtr	    output);
 
+#ifdef RANDR_12_INTERFACE
+    /**
+     * Callback when an output's property has changed.
+     */
+    Bool
+    (*set_property)(xf86OutputPtr output,
+		    Atom property,
+		    RRPropertyValuePtr value);
+#endif
     /**
      * Clean up driver-specific bits of the output
      */
@@ -363,6 +408,13 @@ typedef struct _xf86CrtcConfig {
 
     int			minWidth, minHeight;
     int			maxWidth, maxHeight;
+    
+    /* For crtc-based rotation */
+    DamagePtr   rotationDamage;
+
+    /* DGA */
+    unsigned int dga_flags;
+
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
 extern int xf86CrtcConfigPrivateIndex;
@@ -411,6 +463,25 @@ xf86AllocCrtc (xf86OutputPtr		output);
 void
 xf86FreeCrtc (xf86CrtcPtr		crtc);
 
+/**
+ * Sets the given video mode on the given crtc
+ */
+Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+		 int x, int y);
+
+/*
+ * Assign crtc rotation during mode set
+ */
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
+
+/**
+ * Return whether any output is assigned to the crtc
+ */
+Bool
+xf86CrtcInUse (xf86CrtcPtr crtc);
+
 /*
  * Output functions
  */
@@ -437,20 +508,26 @@ xf86InitialConfiguration (ScrnInfoPtr pS
 void
 xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
     
+Bool
+xf86SaveScreen(ScreenPtr pScreen, int mode);
+
+void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
+
 /**
  * Set the EDID information for the specified output
  */
 void
-i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
 
 /**
  * Return the list of modes supported by the EDID information
  * stored in 'output'
  */
 DisplayModePtr
-i830_xf86OutputGetEDIDModes (xf86OutputPtr output);
+xf86OutputGetEDIDModes (xf86OutputPtr output);
 
 xf86MonPtr
-i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
 
 #endif /* _XF86CRTC_H_ */
diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c
index fa7f97a..ce9151b 100644
--- a/src/radeon_xf86Modes.c
+++ b/src/radeon_xf86Modes.c
@@ -148,47 +148,13 @@ xf86SetModeCrtc(DisplayModePtr p, int ad
         p->CrtcVSyncEnd         *= p->VScan;
         p->CrtcVTotal           *= p->VScan;
     }
-    p->CrtcHAdjusted = FALSE;
-    p->CrtcVAdjusted = FALSE;
-
-    /*
-     * XXX
-     *
-     * The following is taken from VGA, but applies to other cores as well.
-     */
     p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
     p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
-    if ((p->CrtcVBlankEnd - p->CrtcVBlankStart) >= 127) {
-        /* 
-         * V Blanking size must be < 127.
-         * Moving blank start forward is safer than moving blank end
-         * back, since monitors clamp just AFTER the sync pulse (or in
-         * the sync pulse), but never before.
-         */
-        p->CrtcVBlankStart = p->CrtcVBlankEnd - 127;
-	/*
-	 * If VBlankStart is now > VSyncStart move VBlankStart
-	 * to VSyncStart using the maximum width that fits into
-	 * VTotal.
-	 */
-	if (p->CrtcVBlankStart > p->CrtcVSyncStart) {
-	    p->CrtcVBlankStart = p->CrtcVSyncStart;
-	    p->CrtcVBlankEnd = min(p->CrtcHBlankStart + 127, p->CrtcVTotal);
-	}
-    }
     p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
     p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
 
-    if ((p->CrtcHBlankEnd - p->CrtcHBlankStart) >= 63 * 8) {
-        /*
-         * H Blanking size must be < 63*8. Same remark as above.
-         */
-        p->CrtcHBlankStart = p->CrtcHBlankEnd - 63 * 8;
-	if (p->CrtcHBlankStart > p->CrtcHSyncStart) {
-	    p->CrtcHBlankStart = p->CrtcHSyncStart;
-	    p->CrtcHBlankEnd = min(p->CrtcHBlankStart + 63 * 8, p->CrtcHTotal);
-	}
-    }
+    p->CrtcHAdjusted = FALSE;
+    p->CrtcVAdjusted = FALSE;
 }
 
 /**
@@ -337,7 +303,7 @@ xf86PrintModeline(int scrnIndex,DisplayM
  * This is not in xf86Modes.c, but would be part of the proposed new API.
  */
 void
-RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
 			    int flags)
 {
     DisplayModePtr mode;
@@ -358,7 +324,7 @@ RADEONxf86ValidateModesFlags(ScrnInfoPtr
  * This is not in xf86Modes.c, but would be part of the proposed new API.
  */
 void
-RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
 			  int maxX, int maxY, int maxPitch)
 {
     DisplayModePtr mode;
@@ -387,7 +353,7 @@ RADEONxf86ValidateModesSize(ScrnInfoPtr 
  * This is not in xf86Modes.c, but would be part of the proposed new API.
  */
 void
-RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
 			  MonPtr mon)
 {
     DisplayModePtr mode;
@@ -434,7 +400,7 @@ RADEONxf86ValidateModesSync(ScrnInfoPtr 
  * This is not in xf86Modes.c, but would be part of the proposed new API.
  */
 void
-RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
 			    int *min, int *max, int n_ranges)
 {
     DisplayModePtr mode;
@@ -468,7 +434,7 @@ RADEONxf86ValidateModesClocks(ScrnInfoPt
  * This is not in xf86Modes.c, but would be part of the proposed new API.
  */
 void
-RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
 {
     DisplayModePtr mode;
 
@@ -502,7 +468,7 @@ RADEONxf86ValidateModesUserConfig(ScrnIn
  * This is not in xf86Modes.c, but would be part of the proposed new API.
  */
 void
-RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
 			  Bool verbose)
 {
     DisplayModePtr mode;
@@ -558,13 +524,13 @@ xf86ModesAdd(DisplayModePtr modes, Displ
  * Build a mode list from a list of config file modes
  */
 static DisplayModePtr
-RADEONxf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
+xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
 {
     DisplayModePtr  head = NULL, prev = NULL, mode;
     
     for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
     {
-        mode = xalloc(sizeof(DisplayModeRec));
+        mode = xcalloc(1, sizeof(DisplayModeRec));
 	if (!mode)
 	    continue;
         mode->name       = xstrdup(conf_mode->ml_identifier);
@@ -573,8 +539,6 @@ RADEONxf86GetConfigModes (XF86ConfModeLi
 	    xfree (mode);
 	    continue;
 	}
-	
-        memset(mode,'\0',sizeof(DisplayModeRec));
 	mode->type       = 0;
         mode->Clock      = conf_mode->ml_clock;
         mode->HDisplay   = conf_mode->ml_hdisplay;
@@ -600,12 +564,11 @@ RADEONxf86GetConfigModes (XF86ConfModeLi
     return head;
 }
 
-
 /**
  * Build a mode list from a monitor configuration
  */
 DisplayModePtr
-RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
+xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
 {
     DisplayModePtr	    modes = NULL;
     XF86ConfModesLinkPtr    modes_link;
@@ -626,18 +589,18 @@ RADEONxf86GetMonitorModes (ScrnInfoPtr p
 						  xf86configptr->conf_modes_lst);
 	if (modes_link->ml_modes)
 	    modes = xf86ModesAdd (modes,
-				  RADEONxf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
+				  xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
     }
 
     return xf86ModesAdd (modes,
-			 RADEONxf86GetConfigModes (conf_monitor->mon_modeline_lst));
+			 xf86GetConfigModes (conf_monitor->mon_modeline_lst));
 }
 
 /**
  * Build a mode list containing all of the default modes
  */
 DisplayModePtr
-RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
+xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
 {
     DisplayModePtr  head = NULL, prev = NULL, mode;
     int		    i;
diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h
index 8e23997..6668f44 100644
--- a/src/radeon_xf86Modes.h
+++ b/src/radeon_xf86Modes.h
@@ -29,67 +29,54 @@
 #define _RADEON_XF86MODES_H_
 #include "xorgVersion.h"
 #include "xf86Parser.h"
+#include "radeon_xf86Rename.h"
 
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-double RADEON_xf86ModeHSync(DisplayModePtr mode);
-double RADEON_xf86ModeVRefresh(DisplayModePtr mode);
-DisplayModePtr RADEON_xf86DuplicateMode(DisplayModePtr pMode);
-DisplayModePtr RADEON_xf86DuplicateModes(ScrnInfoPtr pScrn,
+double xf86ModeHSync(DisplayModePtr mode);
+double xf86ModeVRefresh(DisplayModePtr mode);
+DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode);
+DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn,
 				       DisplayModePtr modeList);
-void RADEON_xf86SetModeDefaultName(DisplayModePtr mode);
-void RADEON_xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-Bool RADEON_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
-void RADEON_xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
-DisplayModePtr RADEON_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
+void xf86SetModeDefaultName(DisplayModePtr mode);
+void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
+Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
+void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
+DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
 
-DisplayModePtr RADEON_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
-DisplayModePtr RADEON_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
-				Bool Reduced, Bool Interlaced);
-
-#define xf86ModeHSync RADEON_xf86ModeHSync
-#define xf86ModeVRefresh RADEON_xf86ModeVRefresh
-#define xf86DuplicateMode RADEON_xf86DuplicateMode
-#define xf86DuplicateModes RADEON_xf86DuplicateModes
-#define xf86SetModeDefaultName RADEON_xf86SetModeDefaultName
-#define xf86SetModeCrtc RADEON_xf86SetModeCrtc
-#define xf86ModesEqual RADEON_xf86ModesEqual
-#define xf86PrintModeline RADEON_xf86PrintModeline
-#define xf86ModesAdd RADEON_xf86ModesAdd
-#define xf86DDCGetModes RADEON_xf86DDCGetModes
-#define xf86CVTMode RADEON_xf86CVTMode
-#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
+DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
+DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
+			   Bool Reduced, Bool Interlaced);
 
 void
-RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			    int flags);
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+		       int flags);
 
 void
-RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			    int *min, int *max, int n_ranges);
+xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			int *min, int *max, int n_ranges);
 
 void
-RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			  int maxX, int maxY, int maxPitch);
+xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+		      int maxX, int maxY, int maxPitch);
 
 void
-RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			  MonPtr mon);
+xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+		      MonPtr mon);
 
 void
-RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
-			  Bool verbose);
+xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+		      Bool verbose);
 
 void
-RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
-			    int flags);
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+		       int flags);
 
 void
-RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
 
 DisplayModePtr
-RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
+xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
 
 DisplayModePtr
-RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
+xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
 
 #endif
diff --git a/src/radeon_xf86Rename.h b/src/radeon_xf86Rename.h
new file mode 100644
index 0000000..cf8de62
--- /dev/null
+++ b/src/radeon_xf86Rename.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _XF86RENAME_H_
+#define _XF86RENAME_H_
+
+#include "local_xf86Rename.h"
+
+#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit)
+#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex)
+#define xf86CrtcCreate XF86NAME(xf86CrtcCreate)
+#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy)
+#define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
+#define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
+#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
+#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
+#define xf86CVTMode XF86NAME(xf86CVTMode)
+#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions)
+#define xf86DPMSSet XF86NAME(xf86DPMSSet)
+#define xf86DuplicateMode XF86NAME(xf86DuplicateMode)
+#define xf86DuplicateModes XF86NAME(xf86DuplicateModes)
+#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes)
+#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes)
+#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration)
+#define xf86ModeHSync XF86NAME(xf86ModeHSync)
+#define xf86ModesAdd XF86NAME(xf86ModesAdd)
+#define xf86ModesEqual XF86NAME(xf86ModesEqual)
+#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh)
+#define xf86OutputCreate XF86NAME(xf86OutputCreate)
+#define xf86OutputDestroy XF86NAME(xf86OutputDestroy)
+#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID)
+#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes)
+#define xf86OutputRename XF86NAME(xf86OutputRename)
+#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID)
+#define xf86PrintModeline XF86NAME(xf86PrintModeline)
+#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes)
+#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes)
+#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc)
+#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName)
+#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes)
+#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks)
+#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags)
+#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize)
+#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync)
+#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig)
+
+#endif /* _XF86RENAME_H_ */
diff --git a/src/radeon_xf86Rotate.c b/src/radeon_xf86Rotate.c
new file mode 100644
index 0000000..102b508
--- /dev/null
+++ b/src/radeon_xf86Rotate.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+/*#include "i830.h" */
+#include "radeon_xf86Crtc.h"
+#include "radeon_xf86Modes.h"
+//#include "i830_randr.h"
+#include "X11/extensions/render.h"
+#define DPMS_SERVER
+#include "X11/extensions/dpms.h"
+#include "X11/Xatom.h"
+
+static int
+mode_height (DisplayModePtr mode, Rotation rotation)
+{
+    switch (rotation & 0xf) {
+    case RR_Rotate_0:
+    case RR_Rotate_180:
+	return mode->VDisplay;
+    case RR_Rotate_90:
+    case RR_Rotate_270:
+	return mode->HDisplay;
+    default:
+	return 0;
+    }
+}
+
+static int
+mode_width (DisplayModePtr mode, Rotation rotation)
+{
+    switch (rotation & 0xf) {
+    case RR_Rotate_0:
+    case RR_Rotate_180:
+	return mode->HDisplay;
+    case RR_Rotate_90:
+    case RR_Rotate_270:
+	return mode->VDisplay;
+    default:
+	return 0;
+    }
+}
+
+/* borrowed from composite extension, move to Render and publish? */
+
+static VisualPtr
+compGetWindowVisual (WindowPtr pWin)
+{
+    ScreenPtr	    pScreen = pWin->drawable.pScreen;
+    VisualID	    vid = wVisual (pWin);
+    int		    i;
+
+    for (i = 0; i < pScreen->numVisuals; i++)
+	if (pScreen->visuals[i].vid == vid)
+	    return &pScreen->visuals[i];
+    return 0;
+}
+
+static PictFormatPtr
+compWindowFormat (WindowPtr pWin)
+{
+    ScreenPtr	pScreen = pWin->drawable.pScreen;
+    
+    return PictureMatchVisual (pScreen, pWin->drawable.depth,
+			       compGetWindowVisual (pWin));
+}
+
+static void
+xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation,
+	       int dest_width, int dest_height)
+{
+    switch (rotation & 0xf) {
+    default:
+    case RR_Rotate_0:
+	*dst = *src;
+	break;
+    case RR_Rotate_90:
+	dst->x1 = src->y1;
+	dst->y1 = dest_height - src->x2;
+	dst->x2 = src->y2;
+	dst->y2 = dest_height - src->x1;
+	break;
+    case RR_Rotate_180:
+	dst->x1 = dest_width - src->x2;
+	dst->y1 = dest_height - src->y2;
+	dst->x2 = dest_width - src->x1;
+	dst->y2 = dest_height - src->y1;
+	break;
+    case RR_Rotate_270:
+	dst->x1 = dest_width - src->y2;
+	dst->y1 = src->x1;
+	dst->y2 = src->x2;
+	dst->x2 = dest_width - src->y1;
+	break;
+    }
+    if (rotation & RR_Reflect_X) {
+	int x1 = dst->x1;
+	dst->x1 = dest_width - dst->x2;
+	dst->x2 = dest_width - x1;
+    }
+    if (rotation & RR_Reflect_Y) {
+	int y1 = dst->y1;
+	dst->y1 = dest_height - dst->y2;
+	dst->y2 = dest_height - y1;
+    }
+}
+
+static void
+xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    ScreenPtr		screen = scrn->pScreen;
+    WindowPtr		root = WindowTable[screen->myNum];
+    PixmapPtr		dst_pixmap = crtc->rotatedPixmap;
+    PictFormatPtr	format = compWindowFormat (WindowTable[screen->myNum]);
+    int			error;
+    PicturePtr		src, dst;
+    PictTransform	transform;
+    int			n = REGION_NUM_RECTS(region);
+    BoxPtr		b = REGION_RECTS(region);
+    XID			include_inferiors = IncludeInferiors;
+    
+    src = CreatePicture (None,
+			 &root->drawable,
+			 format,
+			 CPSubwindowMode,
+			 &include_inferiors,
+			 serverClient,
+			 &error);
+    if (!src) {
+	ErrorF("couldn't create src pict\n");
+	return;
+    }
+    dst = CreatePicture (None,
+			 &dst_pixmap->drawable,
+			 format,
+			 0L,
+			 NULL,
+			 serverClient,
+			 &error);
+    if (!dst) {
+	ErrorF("couldn't create src pict\n");
+	return;
+    }
+
+    memset (&transform, '\0', sizeof (transform));
+    transform.matrix[2][2] = IntToxFixed(1);
+    transform.matrix[0][2] = IntToxFixed(crtc->x);
+    transform.matrix[1][2] = IntToxFixed(crtc->y);
+    switch (crtc->rotation & 0xf) {
+    default:
+    case RR_Rotate_0:
+	transform.matrix[0][0] = IntToxFixed(1);
+	transform.matrix[1][1] = IntToxFixed(1);
+	break;
+    case RR_Rotate_90:
+	transform.matrix[0][1] = IntToxFixed(-1);
+	transform.matrix[1][0] = IntToxFixed(1);
+	transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay);
+	break;
+    case RR_Rotate_180:
+	transform.matrix[0][0] = IntToxFixed(-1);
+	transform.matrix[1][1] = IntToxFixed(-1);
+	transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay);
+	transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
+	break;
+    case RR_Rotate_270:
+	transform.matrix[0][1] = IntToxFixed(1);
+	transform.matrix[1][0] = IntToxFixed(-1);
+	transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
+	break;
+    }
+
+    /* handle reflection */
+    if (crtc->rotation & RR_Reflect_X)
+    {
+	/* XXX figure this out */
+    }
+    if (crtc->rotation & RR_Reflect_Y)
+    {
+	/* XXX figure this out too */
+    }
+
+    error = SetPictureTransform (src, &transform);
+    if (error) {
+	ErrorF("Couldn't set transform\n");
+	return;
+    }
+
+    while (n--)
+    {
+	BoxRec	dst_box;
+
+	xf86RotateBox (&dst_box, b, crtc->rotation,
+		       crtc->mode.HDisplay, crtc->mode.VDisplay);
+	CompositePicture (PictOpSrc,
+			  src, NULL, dst,
+			  dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
+			  dst_box.x2 - dst_box.x1,
+			  dst_box.y2 - dst_box.y1);
+	b++;
+    }
+    FreePicture (src, None);
+    FreePicture (dst, None);
+}
+
+static void
+xf86RotateRedisplay(ScreenPtr pScreen)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    DamagePtr		damage = xf86_config->rotationDamage;
+    RegionPtr		region;
+
+    if (!damage)
+	return;
+    region = DamageRegion(damage);
+    if (REGION_NOTEMPTY(pScreen, region)) 
+    {
+	int		    c;
+	
+	for (c = 0; c < xf86_config->num_crtc; c++)
+	{
+	    xf86CrtcPtr	    crtc = xf86_config->crtc[c];
+
+	    if (crtc->rotation != RR_Rotate_0)
+	    {
+		BoxRec	    box;
+		RegionRec   crtc_damage;
+
+		/* compute portion of damage that overlaps crtc */
+		box.x1 = crtc->x;
+		box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation);
+		box.y1 = crtc->y;
+		box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation);
+		REGION_INIT(pScreen, &crtc_damage, &box, 1);
+		REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
+		
+		/* update damaged region */
+		if (REGION_NOTEMPTY(pScreen, &crtc_damage))
+    		    xf86RotateCrtcRedisplay (crtc, &crtc_damage);
+		
+		REGION_UNINIT (pScreen, &crtc_damage);
+	    }
+	}
+	DamageEmpty(damage);
+    }
+}
+
+static void
+xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
+{
+    ScreenPtr pScreen = (ScreenPtr) data;
+
+    xf86RotateRedisplay(pScreen);
+}
+
+static void
+xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
+{
+}
+
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+{
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    ScreenPtr		pScreen = pScrn->pScreen;
+    
+    if (rotation == RR_Rotate_0)
+    {
+	/* Free memory from rotation */
+	if (crtc->rotatedPixmap)
+	{
+	    crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap);
+	    crtc->rotatedPixmap = NULL;
+	}
+
+	if (xf86_config->rotationDamage)
+	{
+	    /* Free damage structure */
+	    DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+			      xf86_config->rotationDamage);
+	    DamageDestroy (xf86_config->rotationDamage);
+	    xf86_config->rotationDamage = NULL;
+	    /* Free block/wakeup handler */
+	    RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
+					  xf86RotateWakeupHandler,
+					  (pointer) pScreen);
+	}
+    }
+    else
+    {
+	/* 
+	 * these are the size of the shadow pixmap, which
+	 * matches the mode, not the pre-rotated copy in the
+	 * frame buffer
+	 */
+	int	    width = mode->HDisplay;
+	int	    height = mode->VDisplay;
+	PixmapPtr   shadow = crtc->rotatedPixmap;
+	int	    old_width = shadow ? shadow->drawable.width : 0;
+	int	    old_height = shadow ? shadow->drawable.height : 0;
+	BoxRec	    damage_box;
+	RegionRec   damage_region;
+	
+	/* Allocate memory for rotation */
+	if (old_width != width || old_height != height)
+	{
+	    if (shadow)
+	    {
+		crtc->funcs->shadow_destroy (crtc, shadow);
+		crtc->rotatedPixmap = NULL;
+	    }
+	    shadow = crtc->funcs->shadow_create (crtc, width, height);
+	    if (!shadow)
+		goto bail1;
+	    crtc->rotatedPixmap = shadow;
+	}
+	
+	if (!xf86_config->rotationDamage)
+	{
+	    /* Create damage structure */
+	    xf86_config->rotationDamage = DamageCreate (NULL, NULL,
+						DamageReportNone,
+						TRUE, pScreen, pScreen);
+	    if (!xf86_config->rotationDamage)
+		goto bail2;
+	    
+	    /* Hook damage to screen pixmap */
+	    DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+			    xf86_config->rotationDamage);
+	    
+	    /* Assign block/wakeup handler */
+	    if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
+						 xf86RotateWakeupHandler,
+						 (pointer) pScreen))
+	    {
+		goto bail3;
+	    }
+	    damage_box.x1 = 0;
+	    damage_box.y1 = 0;
+	    damage_box.x2 = mode_width (mode, rotation);
+	    damage_box.y2 = mode_height (mode, rotation);
+	    REGION_INIT (pScreen, &damage_region, &damage_box, 1);
+	    DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+				&damage_region);
+	    REGION_UNINIT (pScreen, &damage_region);
+	}
+	if (0)
+	{
+bail3:
+	    DamageDestroy (xf86_config->rotationDamage);
+	    xf86_config->rotationDamage = NULL;
+	    
+bail2:
+	    if (shadow)
+	    {
+		crtc->funcs->shadow_destroy (crtc, shadow);
+		crtc->rotatedPixmap = NULL;
+	    }
+bail1:
+	    if (old_width && old_height)
+		crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+								  old_width,
+								  old_height);
+	    return FALSE;
+	}
+    }
+    
+    /* All done */
+    return TRUE;
+}
diff-tree a77f08298dc7e097025e3f7f92e3665c0ef30095 (from fa12fe1cc90dd745f3eea35a07d4f3efd652e7b4)
Author: David Airlie <airlied at linux.ie>
Date:   Mon Jan 29 16:12:24 2007 +1100

    radeon: always reset cursor regs

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index ac6f358..8c3dcfa 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -444,8 +444,7 @@ static void RADEONLoadCursorARGB (ScrnIn
     if (!info->IsSecondary)
 	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
 
-    if (info->IsSecondary || info->MergedFB)
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
 
 }
 
diff-tree fa12fe1cc90dd745f3eea35a07d4f3efd652e7b4 (from 4d3649b84a3325043c38cece4499de0095cebd71)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jan 23 19:37:51 2007 +1100

    remove unused restore palette function

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 629fb9f..44a7eb2 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -4618,32 +4618,6 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
-#if 0
-/* Write palette data */
-static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    int            i;
-
-    if (!restore->palette_valid) return;
-
-    PAL_SELECT(1);
-    OUTPAL_START(0);
-    for (i = 0; i < 256; i++) {
-	RADEONWaitForFifo(pScrn, 32); /* delay */
-	OUTPAL_NEXT_CARD32(restore->palette2[i]);
-    }
-
-    PAL_SELECT(0);
-    OUTPAL_START(0);
-    for (i = 0; i < 256; i++) {
-	RADEONWaitForFifo(pScrn, 32); /* delay */
-	OUTPAL_NEXT_CARD32(restore->palette[i]);
-    }
-}
-#endif
-
 /* Write out state to define a new video mode */
 void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
diff-tree 4d3649b84a3325043c38cece4499de0095cebd71 (from 9149e763865598c307cbefc753ff6ebdeeaf32ae)
Author: Dave Airlie <airlied at linux.ie>
Date:   Tue Jan 23 19:37:21 2007 +1100

    remove isused and isactive

diff --git a/src/radeon_display.c b/src/radeon_display.c
index ad9ca3f..e769e15 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -952,7 +952,6 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     const char *s;
-    Bool ignore_edid = FALSE;
     int i = 0, second = 0, max_mt = 5;
 
     /* We first get the information about all connectors from BIOS.
@@ -968,10 +967,6 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN;
 	pRADEONEnt->PortInfo[i]->ConnectorType = CONNECTOR_NONE;
     }
-    pRADEONEnt->Controller[0]->IsUsed = FALSE;
-    pRADEONEnt->Controller[1]->IsUsed = FALSE;
-    pRADEONEnt->Controller[0]->IsActive = FALSE;
-    pRADEONEnt->Controller[1]->IsActive = FALSE;
 
     if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
         ((pRADEONEnt->PortInfo[0]->DDCType == 0) &&
@@ -1029,18 +1024,6 @@ void RADEONSetupConnectors(ScrnInfoPtr p
         pRADEONEnt->PortInfo[0]->DACType = DAC_PRIMARY;
     }
 
-    /* IgnoreEDID option is different from the NoDDCxx options used by DDC module
-     * When IgnoreEDID is used, monitor detection will still use DDC
-     * detection, but all EDID data will not be used in mode validation.
-     * You can use this option when you have a DDC monitor but want specify your own
-     * monitor timing parameters by using HSync, VRefresh and Modeline,
-     */
-    if (xf86GetOptValBool(info->Options, OPTION_IGNORE_EDID, &ignore_edid)) {
-        if (ignore_edid)
-            xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-                       "IgnoreEDID is specified, EDID data will be ignored\n");
-    }
-
     /*
      * MonitorLayout option takes a string for two monitors connected in following format:
      * Option "MonitorLayout" "primary-port-display, secondary-port-display"
@@ -1738,7 +1721,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
      */
     if ((info->DispPriority == 2) && IS_R300_VARIANT) {
         CARD32 mc_init_misc_lat_timer = INREG(R300_MC_INIT_MISC_LAT_TIMER);
-	if (pRADEONEnt->Controller[1]->IsActive) {
+	if (pRADEONEnt->pCrtc[1]->enabled) {
 	    mc_init_misc_lat_timer |= 0x1100; /* display 0 and 1 */
 	} else {
 	    mc_init_misc_lat_timer |= 0x0100; /* display 0 only */
@@ -2518,7 +2501,6 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 	if (!pRADEONEnt->pOutput[i])
 	    return FALSE;
 	
-	
 	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
 	pRADEONEnt->PortInfo[i]->num = i;
 
@@ -2528,7 +2510,6 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 
 	pRADEONEnt->pOutput[i]->possible_clones = 0;
     }
-    
 
     return TRUE;
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 9c4b509..629fb9f 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2401,6 +2401,7 @@ static Bool RADEONPreInitControllers(Scr
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     int i;
+
     if (!info->IsSecondary) {
       
       if (!RADEONAllocatePortInfo(pScrn))
@@ -4691,7 +4692,6 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    output = RADEONGetCrtcConnector(pScrn, 2);
 	    if (output) {
 		RADEONEnableDisplay(pScrn, output, TRUE);
-		pCRTC2->IsActive = TRUE;
 	    }
 	} else {
 	    RADEONRestoreMemMapRegisters(pScrn, restore);
@@ -4707,13 +4707,11 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    output = RADEONGetCrtcConnector(pScrn, 1);
 	    if (output) {
 		RADEONEnableDisplay(pScrn, output, TRUE);
-		pCRTC1->IsActive = TRUE;
 	    }
 	    if (pCRTC2->binding == 1) {
 		output = RADEONGetCrtcConnector(pScrn, 2);
 		if (output) {
 		    RADEONEnableDisplay(pScrn, output, TRUE);
-		    pCRTC2->IsActive = TRUE;
 		}
 	    }
 	}
@@ -4731,13 +4729,11 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	output = RADEONGetCrtcConnector(pScrn, 1);
 	if (output) {
 	    RADEONEnableDisplay(pScrn, output, TRUE);
-	    pCRTC1->IsActive = TRUE;
 	}
 	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
 	    output = RADEONGetCrtcConnector(pScrn, 2);
 	    if (output) {
 		RADEONEnableDisplay(pScrn, output, TRUE);
-		pCRTC2->IsActive = TRUE;
 	    }
 	}
     }
@@ -5453,8 +5449,6 @@ static Bool RADEONInitCrtcRegisters(Scrn
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     xf86OutputPtr connector;
 
-    pRADEONEnt->Controller[0]->IsUsed = TRUE;
-    pRADEONEnt->Controller[0]->IsActive = TRUE;
     pRADEONEnt->pCrtc[0]->curMode = *mode;
 
     switch (info->CurrentLayout.pixel_code) {
@@ -5643,8 +5637,6 @@ static Bool RADEONInitCrtc2Registers(Scr
     if (info->IsSecondary)
 	info0 = RADEONPTR(pRADEONEnt->pPrimaryScrn);
 
-    pRADEONEnt->Controller[1]->IsUsed = TRUE;
-    pRADEONEnt->Controller[1]->IsActive = TRUE;
     pRADEONEnt->pCrtc[1]->curMode = *mode;
 
     switch (info->CurrentLayout.pixel_code) {
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index acdd7d3..b62bcf6 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -118,8 +118,6 @@ typedef enum
 typedef struct _RADEONCrtcPrivateRec {
     int crtc_id;
     int binding;
-    Bool IsActive;
-    Bool IsUsed;
     /* Lookup table values to be set when the CRTC is enabled */
     CARD8 lut_r[256], lut_g[256], lut_b[256];
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
diff-tree 9149e763865598c307cbefc753ff6ebdeeaf32ae (from 2a13a3b641d9acf4f50472e1c8ba07633c3b78d6)
Author: David Airlie <airlied at asimov.stargames.com.au>
Date:   Tue Jan 23 15:20:11 2007 +1100

    radeon: fixup problem with cursor not going off
    
    Also fixup secondary dac detect to return unknown for now

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 79d4a23..ac6f358 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -114,11 +114,12 @@ RADEONCrtcCursor(xf86CrtcPtr crtc,  Bool
     Bool		show;
     unsigned char     *RADEONMMIO = info->MMIO;
     CARD32 save1 = 0, save2 = 0;
-    if (!crtc->enabled)
-	return;
+
+    if (!crtc->enabled && !crtc->cursorShown)
+      return;
 
     
-    show = crtc->cursorInRange;
+    show = crtc->cursorInRange && crtc->enabled;
     if (show && (force || !crtc->cursorShown))
     {
 	if (crtc_id == 0) 
@@ -205,7 +206,7 @@ RADEONRandrSetCursorPosition(ScrnInfoPtr
 	int thisx = x - crtc->x;
 	int thisy = y - crtc->y;
 	
-	if (!crtc->enabled)
+	if (!crtc->enabled && !crtc->cursorShown)
 	    continue;
 
 	/*
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 1c8d473..ad9ca3f 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -542,6 +542,7 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoP
 	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
 	}
 #endif
+	return MT_UNKNOWN;
     }
 
     return(bConnected ? MT_CRT : MT_NONE);
@@ -2297,6 +2298,7 @@ radeon_crtc_gamma_set(xf86CrtcPtr crtc, 
 	radeon_crtc->lut_b[i] = blue[i] >> 8;
     }
 
+    ErrorF("Loading lut %d\n", radeon_crtc->crtc_id);
     radeon_crtc_load_lut(crtc);
 }
 
@@ -2761,14 +2763,25 @@ RADEONDisableUnusedFunctions(ScrnInfoPtr
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int o, c;
 
+    for (o = 0; o < xf86_config->num_output; o++)
+    {
+	xf86OutputPtr output = xf86_config->output[o];
+
+	if (output->crtc == NULL) {
+		radeon_dpms(output, DPMSModeOff);
+	}
+    }
+
     for (c = 0; c < xf86_config->num_crtc; c++)
     {
 	xf86CrtcPtr crtc = xf86_config->crtc[c];
-	if (!crtc->enabled)
+	if (!crtc->enabled) {
 		memset(&crtc->curMode, 0, sizeof(crtc->curMode));
-
+		radeon_crtc_dpms(crtc, DPMSModeOff);
+	}
     }
 
+
 }
 
 void
diff-tree 2a13a3b641d9acf4f50472e1c8ba07633c3b78d6 (from cbd84bed13582e82f8b2e84aa152602474c09cd4)
Author: David Airlie <airlied at asimov.stargames.com.au>
Date:   Tue Jan 23 10:36:06 2007 +1100

    fixup init disp bandwidth
    
    This probably break old-style dualhead badly

diff --git a/src/radeon_display.c b/src/radeon_display.c
index afe6f94..1c8d473 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1699,8 +1699,7 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
 }
 
 /* Calculate display buffer watermark to prevent buffer underflow */
-void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, RADEONInfoPtr info2,
-			      DisplayModePtr mode1, DisplayModePtr mode2)
+void RADEONInitDispBandwidth2(ScrnInfoPtr pScrn, RADEONInfoPtr info, int pixel_bytes2, DisplayModePtr mode1, DisplayModePtr mode2)
 {
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -1750,11 +1749,6 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
     /* R420 and RV410 family not supported yet */
     if (info->ChipFamily == CHIP_FAMILY_R420 || info->ChipFamily == CHIP_FAMILY_RV410) return; 
 
-    if (pRADEONEnt->pSecondaryScrn) {
-	if (info->IsSecondary) return;
-	info2 = RADEONPTR(pRADEONEnt->pSecondaryScrn);
-    }  else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info;
-
     /*
      * Determine if there is enough bandwidth for current display mode
      */
@@ -1767,8 +1761,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
 	pix_clk2 = 0;
 
     peak_disp_bw = (pix_clk * info->CurrentLayout.pixel_bytes);
-    if (info2) 
-	peak_disp_bw +=	(pix_clk2 * info2->CurrentLayout.pixel_bytes);
+    if (pixel_bytes2)
+      peak_disp_bw += (pix_clk2 * pixel_bytes2);
 
     if (peak_disp_bw >= mem_bw * min_mem_eff) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 
@@ -1908,8 +1902,8 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
       Find the drain rate of the display buffer.
     */
     disp_drain_rate = pix_clk / (16.0/info->CurrentLayout.pixel_bytes);
-    if (info2)
-	disp_drain_rate2 = pix_clk2 / (16.0/info2->CurrentLayout.pixel_bytes);
+    if (pixel_bytes2)
+	disp_drain_rate2 = pix_clk2 / (16.0/pixel_bytes2);
     else
 	disp_drain_rate2 = 0;
 
@@ -1962,7 +1956,7 @@ void RADEONInitDispBandwidth2(ScrnInfoPt
 		 (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL)));
 
     if (mode2) {
-	stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16;
+	stop_req = mode2->HDisplay * pixel_bytes2 / 16;
 
 	if (stop_req > max_stop_req) stop_req = max_stop_req;
 
@@ -2015,8 +2009,11 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
 {
     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;
 
     if (pRADEONEnt->pSecondaryScrn) {
 	if (info->IsSecondary) return;
@@ -2030,7 +2027,27 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
 	mode2 = NULL;
     }
 
-    RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2);
+    if (info2) 
+      pixel_bytes2 = info2->CurrentLayout.pixel_bytes;
+    
+    
+    if (xf86_config->num_crtc == 2) {
+      pixel_bytes2 = 0;
+      mode2 = NULL;
+
+      if (xf86_config->crtc[1]->enabled && xf86_config->crtc[0]->enabled) {
+	pixel_bytes2 = info->CurrentLayout.pixel_bytes;
+	mode1 = &xf86_config->crtc[0]->curMode;
+	mode2 = &xf86_config->crtc[1]->curMode;
+      } else if (xf86_config->crtc[0]->enabled) {
+	mode1 = &xf86_config->crtc[0]->curMode;
+      } else if (xf86_config->crtc[1]->enabled) {
+	mode1 = &xf86_config->crtc[1]->curMode;
+      } else
+	return;
+    }
+
+    RADEONInitDispBandwidth2(pScrn, info, pixel_bytes2, mode1, mode2);
 }
 
 void RADEONBlank(ScrnInfoPtr pScrn)
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a935da0..9c4b509 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6374,6 +6374,9 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 	RADEONBlank(pScrn);
 	RADEONRestoreMode(pScrn, &info->ModeReg);
 	RADEONUnblank(pScrn);
+
+	if (info->DispPriority)
+ 	    RADEONInitDispBandwidth(pScrn);
     }
 #if 0
       if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 4e21a33..63b0080 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -656,8 +656,8 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	    RADEONUnblank(pScrn);
 	    info->IsSwitching = FALSE;
 	}
-	    //	    if (info->DispPriority)
-	    //		RADEONInitDispBandwidth(pScrn);
+	if (info->DispPriority)
+	  RADEONInitDispBandwidth(pScrn);
     
     }
     if (pos_changed && mode)
diff-tree cbd84bed13582e82f8b2e84aa152602474c09cd4 (from 6296882135b183425a219efb75374d3b172de370)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Jan 22 22:19:46 2007 +1100

    removed even more  mergedfb remains

diff --git a/src/radeon.h b/src/radeon.h
index c46a270..211385d 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -774,22 +774,12 @@ typedef struct {
   DisplayModePtr currentMode, savedCurrentMode;
     /* merged fb stuff, also covers clone modes */
     Bool		MergedFB;
-    RADEONScrn2Rel	CRT2Position;
-    char *		CRT2HSync;
-    char *		CRT2VRefresh;
-    char *		MetaModes;
-    ScrnInfoPtr		CRT2pScrn;
-    DisplayModePtr	CRT1Modes;
-    DisplayModePtr	CRT1CurrentMode;
     RADEONMonitorType   MergeType;
-    RADEONDDCType       MergeDDCType;
     void        	(*PointerMoved)(int index, int x, int y);
     Bool		NoVirtual;
 
     int			constantDPI; /* -1 = auto, 0 = off, 1 = on */
     int			RADEONDPIVX, RADEONDPIVY;
-    RADEONScrn2Rel	MergedDPISRel;
-    int			RADEONMergedDPIVX, RADEONMergedDPIVY, RADEONMergedDPIRot;
 
     /* special handlings for DELL triple-head server */
     Bool		IsDellServer; 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 101acf1..a935da0 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -539,46 +539,6 @@ static Bool RADEONGetRec(ScrnInfoPtr pSc
 static void RADEONFreeRec(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
-    if(info->CRT2HSync) xfree(info->CRT2HSync);
-    info->CRT2HSync = NULL;
-    if(info->CRT2VRefresh) xfree(info->CRT2VRefresh);
-    info->CRT2VRefresh = NULL;
-    if(info->MetaModes) xfree(info->MetaModes);
-    info->MetaModes = NULL;
-    if(info->CRT2pScrn) {
-       if(info->CRT2pScrn->modes) {
-          while(info->CRT2pScrn->modes)
-             xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes);
-       }
-       if(info->CRT2pScrn->monitor) {
-          if(info->CRT2pScrn->monitor->Modes) {
-	     while(info->CRT2pScrn->monitor->Modes)
-	        xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes);
-	  }
-	  if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC);
-          xfree(info->CRT2pScrn->monitor);
-       }
-       xfree(info->CRT2pScrn);
-       info->CRT2pScrn = NULL;
-    }
-    if(info->CRT1Modes) {
-       if(info->CRT1Modes != pScrn->modes) {
-          if(pScrn->modes) {
-             pScrn->currentMode = pScrn->modes;
-             do {
-                DisplayModePtr p = pScrn->currentMode->next;
-                if(pScrn->currentMode->Private)
-                   xfree(pScrn->currentMode->Private);
-                xfree(pScrn->currentMode);
-                pScrn->currentMode = p;
-             } while(pScrn->currentMode != pScrn->modes);
-          }
-          pScrn->currentMode = info->CRT1CurrentMode;
-          pScrn->modes = info->CRT1Modes;
-          info->CRT1CurrentMode = NULL;
-          info->CRT1Modes = NULL;
-       }
-    }
 
     if (!pScrn || !pScrn->driverPrivate) return;
     xfree(pScrn->driverPrivate);
@@ -6580,40 +6540,6 @@ _X_EXPORT void RADEONFreeScreen(int scrn
     /* when server quits at PreInit, we don't need do this anymore*/
     if (!info) return;
 
-    if(info->MergedFB) {
-       if(pScrn->modes) {
-          pScrn->currentMode = pScrn->modes;
-          do {
-            DisplayModePtr p = pScrn->currentMode->next;
-            if(pScrn->currentMode->Private)
-                xfree(pScrn->currentMode->Private);
-            xfree(pScrn->currentMode);
-            pScrn->currentMode = p;
-          } while(pScrn->currentMode != pScrn->modes);
-       }
-       pScrn->currentMode = info->CRT1CurrentMode;
-       pScrn->modes = info->CRT1Modes;
-       info->CRT1CurrentMode = NULL;
-       info->CRT1Modes = NULL;
-
-       if(info->CRT2pScrn) {
-          if(info->CRT2pScrn->modes) {
-             while(info->CRT2pScrn->modes)
-                xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes);
-          }
-          if(info->CRT2pScrn->monitor) {
-	     if(info->CRT2pScrn->monitor->Modes) {
-	        while(info->CRT2pScrn->monitor->Modes)
-		   xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes);
-	     }
-	     if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC);
-             xfree(info->CRT2pScrn->monitor);
-	  }
-          xfree(info->CRT2pScrn);
-          info->CRT2pScrn = NULL;
-       }
-    }
-
 #ifdef WITH_VGAHW
     if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
 	vgaHWFreeHWRec(pScrn);
diff-tree 6296882135b183425a219efb75374d3b172de370 (from 26e1bab2c7a4ad52710746265b3da495b54dab36)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Jan 22 22:14:48 2007 +1100

    remove more mergedfb relics

diff --git a/src/radeon.h b/src/radeon.h
index 4f77bd3..c46a270 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -784,16 +784,7 @@ typedef struct {
     RADEONMonitorType   MergeType;
     RADEONDDCType       MergeDDCType;
     void        	(*PointerMoved)(int index, int x, int y);
-    /* pseudo xinerama support for mergedfb */
-    ExtensionEntry 	*XineramaExtEntry;
-    int			RADEONXineramaVX, RADEONXineramaVY;
-    Bool		AtLeastOneNonClone;
-    int			MergedFBXDPI, MergedFBYDPI;
     Bool		NoVirtual;
-    int                 CRT1XOffs, CRT1YOffs, CRT2XOffs, CRT2YOffs;
-    int                 MBXNR1XMAX, MBXNR1YMAX, MBXNR2XMAX, MBXNR2YMAX;
-    Bool                NonRect, HaveNonRect, HaveOffsRegions, MouseRestrictions;
-    region              NonRectDead, OffDead1, OffDead2;
 
     int			constantDPI; /* -1 = auto, 0 = off, 1 = on */
     int			RADEONDPIVX, RADEONDPIVY;
diff-tree 26e1bab2c7a4ad52710746265b3da495b54dab36 (from 9008e1caa45e4a18e6f3289c7b17036730fe578a)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Jan 22 22:11:55 2007 +1100

    radeon: fixup some of the video code after randr
    
    This may not be complete, I need to test on dual-head system later

diff --git a/src/radeon.h b/src/radeon.h
index 4d3f96d..4f77bd3 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -781,19 +781,10 @@ typedef struct {
     ScrnInfoPtr		CRT2pScrn;
     DisplayModePtr	CRT1Modes;
     DisplayModePtr	CRT1CurrentMode;
-    int			CRT1frameX0;
-    int			CRT1frameY0;
-    int			CRT1frameX1;
-    int			CRT1frameY1;
     RADEONMonitorType   MergeType;
     RADEONDDCType       MergeDDCType;
     void        	(*PointerMoved)(int index, int x, int y);
     /* pseudo xinerama support for mergedfb */
-    int			maxCRT1_X1, maxCRT1_X2, maxCRT1_Y1, maxCRT1_Y2;
-    int			maxCRT2_X1, maxCRT2_X2, maxCRT2_Y1, maxCRT2_Y2;
-    int			maxClone_X1, maxClone_X2, maxClone_Y1, maxClone_Y2;
-    Bool		UseRADEONXinerama;
-    Bool		CRT2IsScrn0;
     ExtensionEntry 	*XineramaExtEntry;
     int			RADEONXineramaVX, RADEONXineramaVY;
     Bool		AtLeastOneNonClone;
diff --git a/src/radeon_display.c b/src/radeon_display.c
index a02167a..afe6f94 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2765,16 +2765,17 @@ RADEONChooseOverlayCRTC(ScrnInfoPtr pScr
 
     for (c = 0; c < xf86_config->num_crtc; c++)
     {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
+        xf86CrtcPtr crtc = xf86_config->crtc[c];
+
 	if (!crtc->enabled)
-	  continue;
+	    continue;
 
 	if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y))
-	  crtc_num = c;
+	    crtc_num = c;
     }
 
     if (crtc_num == 1)
-      info->OverlayOnCRTC2 = TRUE;
+        info->OverlayOnCRTC2 = TRUE;
     else
-      info->OverlayOnCRTC2 = FALSE;
+        info->OverlayOnCRTC2 = FALSE;
 }
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 9575592..93ea1eb 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2448,7 +2448,7 @@ RADEONDisplayVideo(
        Here we need to find ecp_div again, as the user may have switched resolutions */
 
     /* Figure out which head we are on for dot clock */
-    if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary)
+    if (info->OverlayOnCRTC2 || info->IsSecondary)
         dot_clock = info->ModeReg.dot_clock_freq_2;
     else
         dot_clock = info->ModeReg.dot_clock_freq;
@@ -2468,6 +2468,7 @@ RADEONDisplayVideo(
     v_inc_shift = 20;
     y_mult = 1;
 
+    /* TODO NO IDEA WHAT THIS IS ABOUT */
     if (info->MergedFB) {
 	if (overlay_mode->Flags & V_INTERLACE)
 	    v_inc_shift++;
@@ -2607,7 +2608,7 @@ RADEONDisplayVideo(
      * rendering for the second head.
      */
 
-    if ((info->MergedFB && info->OverlayOnCRTC2) || info->IsSecondary) {
+    if (info->OverlayOnCRTC2 || info->IsSecondary) {
         x_off = 0;
         OUTREG(RADEON_OV1_Y_X_START, ((dstBox->x1 + x_off) |
                                       ((dstBox->y1*y_mult) << 16)));
@@ -2710,6 +2711,7 @@ RADEONPutImage(
   DrawablePtr pDraw
 ){
    RADEONInfoPtr info = RADEONPTR(pScrn);
+   xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
    INT32 xa, xb, ya, yb;
    unsigned char *dst_start;
@@ -2718,6 +2720,7 @@ RADEONPutImage(
    int top, left, npixels, nlines, bpp;
    BoxRec dstBox;
    CARD32 tmp;
+   xf86CrtcPtr crtc;
 
    /*
     * s2offset, s3offset - byte offsets into U and V plane of the
@@ -2755,17 +2758,15 @@ RADEONPutImage(
 			     clipBoxes, width, height))
 	return Success;
 
-   if (info->MergedFB && info->OverlayOnCRTC2) {
-	dstBox.x1 -= info->CRT2pScrn->frameX0;
-	dstBox.x2 -= info->CRT2pScrn->frameX0;
-	dstBox.y1 -= info->CRT2pScrn->frameY0;
-	dstBox.y2 -= info->CRT2pScrn->frameY0;
-   } else {
-	dstBox.x1 -= pScrn->frameX0;
-	dstBox.x2 -= pScrn->frameX0;
-	dstBox.y1 -= pScrn->frameY0;
-	dstBox.y2 -= pScrn->frameY0;
-   }
+   if (info->OverlayOnCRTC2)
+     crtc = xf86_config->crtc[1];
+   else
+     crtc = xf86_config->crtc[0];
+
+   dstBox.x1 -= crtc->x;
+   dstBox.x2 -= crtc->x;
+   dstBox.y1 -= crtc->y;
+   dstBox.y2 -= crtc->y;
 
    bpp = pScrn->bitsPerPixel >> 3;
 
@@ -3089,12 +3090,13 @@ RADEONDisplaySurface(
 ){
     OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr;
     ScrnInfoPtr pScrn = surface->pScrn;
-
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONPortPrivPtr portPriv = info->adaptor->pPortPrivates[0].ptr;
 
     INT32 xa, ya, xb, yb;
     BoxRec dstBox;
+    xf86CrtcPtr crtc;
 
     if (src_w > (drw_w << 4))
 	drw_w = src_w >> 4;
@@ -3117,17 +3119,15 @@ RADEONDisplaySurface(
 			       surface->width, surface->height))
 	return Success;
 
-    if (info->MergedFB && info->OverlayOnCRTC2) {
-	dstBox.x1 -= info->CRT2pScrn->frameX0;
-	dstBox.x2 -= info->CRT2pScrn->frameX0;
-	dstBox.y1 -= info->CRT2pScrn->frameY0;
-	dstBox.y2 -= info->CRT2pScrn->frameY0;
-    } else {
-	dstBox.x1 -= pScrn->frameX0;
-	dstBox.x2 -= pScrn->frameX0;
-	dstBox.y1 -= pScrn->frameY0;
-	dstBox.y2 -= pScrn->frameY0;
-    }
+    if (info->OverlayOnCRTC2)
+        crtc = xf86_config->crtc[1];
+    else
+        crtc = xf86_config->crtc[0];
+    
+    dstBox.x1 -= crtc->x;
+    dstBox.x2 -= crtc->x;
+    dstBox.y1 -= crtc->y;
+    dstBox.y2 -= crtc->y;
 
 #if 0
     /* this isn't needed */
@@ -3198,6 +3198,7 @@ RADEONPutVideo(
 ){
    RADEONInfoPtr info = RADEONPTR(pScrn);
    RADEONPortPrivPtr pPriv = (RADEONPortPrivPtr)data;
+   xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
    unsigned char *RADEONMMIO = info->MMIO;
    INT32 xa, xb, ya, yb, top;
    unsigned int pitch, new_size, alloc_size;
@@ -3210,6 +3211,7 @@ RADEONPutVideo(
    int width, height;
    int mult;
    int vbi_line_width, vbi_start, vbi_end;
+   xf86CrtcPtr crtc;
 
     RADEON_SYNC(info, pScrn);
    /*
@@ -3256,17 +3258,15 @@ RADEONPutVideo(
    if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
         return Success;
 
-   if (info->MergedFB && info->OverlayOnCRTC2) {
-	dstBox.x1 -= info->CRT2pScrn->frameX0;
-	dstBox.x2 -= info->CRT2pScrn->frameX0;
-	dstBox.y1 -= info->CRT2pScrn->frameY0;
-	dstBox.y2 -= info->CRT2pScrn->frameY0;
-   } else {
-	dstBox.x1 -= pScrn->frameX0;
-	dstBox.x2 -= pScrn->frameX0;
-	dstBox.y1 -= pScrn->frameY0;
-	dstBox.y2 -= pScrn->frameY0;
-   }
+   if (info->OverlayOnCRTC2)
+     crtc = xf86_config->crtc[1];
+   else
+     crtc = xf86_config->crtc[0];
+
+   dstBox.x1 -= crtc->x;
+   dstBox.x2 -= crtc->x;
+   dstBox.y1 -= crtc->y;
+   dstBox.y2 -= crtc->y;
 
    bpp = pScrn->bitsPerPixel >> 3;
    pitch = bpp * pScrn->displayWidth;
diff-tree 9008e1caa45e4a18e6f3289c7b17036730fe578a (from e29a32d711553fcb4ca9928122ac285fe0b0c1a7)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Jan 22 21:16:47 2007 +1100

    remove unused merged code

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 6036f82..ba14fe7 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -261,168 +261,6 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
     return count;
 }
 
-
-int RADEONValidateMergeModes(ScrnInfoPtr pScrn1)
-{
-    RADEONInfoPtr   info             = RADEONPTR(pScrn1);
-    ClockRangePtr   clockRanges;
-    int             modesFound;
-    ScrnInfoPtr pScrn = info->CRT2pScrn;
-
-    /* fill in pScrn2 */
-    pScrn->videoRam = pScrn1->videoRam;
-    pScrn->depth = pScrn1->depth;
-    pScrn->numClocks = pScrn1->numClocks;
-    pScrn->progClock = pScrn1->progClock;
-    pScrn->fbFormat = pScrn1->fbFormat;
-    pScrn->videoRam = pScrn1->videoRam;
-    pScrn->maxHValue = pScrn1->maxHValue;
-    pScrn->maxVValue = pScrn1->maxVValue;
-    pScrn->xInc = pScrn1->xInc;
-
-    if (info->NoVirtual) {
-	pScrn1->display->virtualX = 0;
-        pScrn1->display->virtualY = 0;
-    }
-
-    if (pScrn->monitor->DDC) {
-        /* If we still don't know sync range yet, let's try EDID.
-         *
-         * Note that, since we can have dual heads, Xconfigurator
-         * may not be able to probe both monitors correctly through
-         * vbe probe function (RADEONProbeDDC). Here we provide an
-         * additional way to auto-detect sync ranges if they haven't
-         * been added to XF86Config manually.
-         */
-        if (pScrn->monitor->nHsync <= 0)
-            RADEONSetSyncRangeFromEdid(pScrn, 1);
-        if (pScrn->monitor->nVrefresh <= 0)
-            RADEONSetSyncRangeFromEdid(pScrn, 0);
-    }
-
-    /* Get mode information */
-    pScrn->progClock               = TRUE;
-    clockRanges                    = xnfcalloc(sizeof(*clockRanges), 1);
-    clockRanges->next              = NULL;
-    clockRanges->minClock          = info->pll.min_pll_freq;
-    clockRanges->maxClock          = info->pll.max_pll_freq * 10;
-    clockRanges->clockIndex        = -1;
-    clockRanges->interlaceAllowed  = (info->MergeType == MT_CRT);
-    clockRanges->doubleScanAllowed = (info->MergeType == MT_CRT);
-
-    /* We'll use our own mode validation routine for DFP/LCD, since
-     * xf86ValidateModes does not work correctly with the DFP/LCD modes
-     * 'stretched' from their native mode.
-     */
-    if (info->MergeType == MT_CRT && !info->ddc_mode) {
- 
-	modesFound =
-	    xf86ValidateModes(pScrn,
-			      pScrn->monitor->Modes,
-			      pScrn1->display->modes,
-			      clockRanges,
-			      NULL,                  /* linePitches */
-			      8 * 64,                /* minPitch */
-			      8 * 1024,              /* maxPitch */
-			      info->allowColorTiling ? 2048 :
-			          64 * pScrn1->bitsPerPixel, /* pitchInc */
-			      128,                   /* minHeight */
-			      info->MaxLines,        /* maxHeight */
-			      pScrn1->display->virtualX ? pScrn1->virtualX : 0,
-			      pScrn1->display->virtualY ? pScrn1->virtualY : 0,
-			      info->FbMapSize,
-			      LOOKUP_BEST_REFRESH);
-
-	if (modesFound == -1) return 0;
-
-	xf86PruneDriverModes(pScrn);
-	if (!modesFound || !pScrn->modes) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
-	    return 0;
-	}
-
-    } else {
-	/* First, free any allocated modes during configuration, since
-	 * we don't need them
-	 */
-	while (pScrn->modes)
-	    xf86DeleteMode(&pScrn->modes, pScrn->modes);
-	while (pScrn->modePool)
-	    xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
-	/* Next try to add DDC modes */
-	modesFound = RADEONValidateDDCModes(pScrn, pScrn1->display->modes,
-					    info->MergeType, 1);
-
-	/* If that fails and we're connect to a flat panel, then try to
-         * add the flat panel modes
-	 */
-	if (info->MergeType != MT_CRT) {
-	    
-	    /* some panels have DDC, but don't have internal scaler.
-	     * in this case, we need to validate additional modes
-	     * by using on-chip RMX.
-	     */
-	    int user_modes_asked = 0, user_modes_found = 0, i;
-	    DisplayModePtr  tmp_mode = pScrn->modes;
-	    while (pScrn1->display->modes[user_modes_asked]) user_modes_asked++;	    
-	    if (tmp_mode) {
-		for (i = 0; i < modesFound; i++) {
-		    if (tmp_mode->type & M_T_USERDEF) user_modes_found++;
-		    tmp_mode = tmp_mode->next;
-		}
-	    }
-
- 	    if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
-		/* when panel size is not valid, try to validate 
-		 * mode using xf86ValidateModes routine
-		 * This can happen when DDC is disabled.
-		 */
-		/* if (info->PanelXRes < 320 || info->PanelYRes < 200) */
-		    modesFound =
-			xf86ValidateModes(pScrn,
-					  pScrn->monitor->Modes,
-					  pScrn1->display->modes,
-					  clockRanges,
-					  NULL,                  /* linePitches */
-					  8 * 64,                /* minPitch */
-					  8 * 1024,              /* maxPitch */
-					  info->allowColorTiling ? 2048 :
-					      64 * pScrn1->bitsPerPixel, /* pitchInc */
-					  128,                   /* minHeight */
-					  info->MaxLines,        /* maxHeight */
-					  pScrn1->display->virtualX,
-					  pScrn1->display->virtualY,
-					  info->FbMapSize,
-					  LOOKUP_BEST_REFRESH);
-
-	    } 
-        }
-
-	/* Setup the screen's clockRanges for the VidMode extension */
-	if (!pScrn->clockRanges) {
-	    pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1);
-	    memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges));
-	    pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH;
-	}
-
-	/* Fail if we still don't have any valid modes */
-	if (modesFound < 1) {
-	    if (info->MergeType == MT_CRT) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "No valid DDC modes found for this CRT\n");
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Try turning off the \"DDCMode\" option\n");
-	    } else {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "No valid mode found for this DFP/LCD\n");
-	    }
-	    return 0;
-	}
-    }
-    return modesFound;
-}
-
 void
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
diff-tree e29a32d711553fcb4ca9928122ac285fe0b0c1a7 (from aa9d04ba94a3cd60b248231da517e2817591fc69)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Jan 22 21:09:53 2007 +1100

    add back overlay CRTC chooser this may not work yet

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 98faf4c..a02167a 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2753,3 +2753,28 @@ RADEONDisableUnusedFunctions(ScrnInfoPtr
     }
 
 }
+
+void
+RADEONChooseOverlayCRTC(ScrnInfoPtr pScrn, BoxPtr dstBox)
+{
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int c;
+    int highx = 0, highy = 0;
+    int crtc_num;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	if (!crtc->enabled)
+	  continue;
+
+	if ((dstBox->x1 >= crtc->x) && (dstBox->y1 >= crtc->y))
+	  crtc_num = c;
+    }
+
+    if (crtc_num == 1)
+      info->OverlayOnCRTC2 = TRUE;
+    else
+      info->OverlayOnCRTC2 = FALSE;
+}
diff --git a/src/radeon_video.c b/src/radeon_video.c
index f8f29af..9575592 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -2749,8 +2749,7 @@ RADEONPutImage(
    dstBox.y1 = drw_y;
    dstBox.y2 = drw_y + drw_h;
 
- //  if (info->MergedFB)
-//	RADEONChooseOverlayCRTC(pScrn, &dstBox);
+   RADEONChooseOverlayCRTC(pScrn, &dstBox);
 
    if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,
 			     clipBoxes, width, height))
@@ -3112,8 +3111,7 @@ RADEONDisplaySurface(
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    //if (info->MergedFB)
-     //   RADEONChooseOverlayCRTC(pScrn, &dstBox);
+    RADEONChooseOverlayCRTC(pScrn, &dstBox);
 
     if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, 
 			       surface->width, surface->height))
@@ -3253,8 +3251,7 @@ RADEONPutVideo(
 	   else
 	   vbi_line_width = 2000; /* might need adjustment */
 
-   //if (info->MergedFB)
-    //    RADEONChooseOverlayCRTC(pScrn, &dstBox);
+   RADEONChooseOverlayCRTC(pScrn, &dstBox);
         
    if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
         return Success;
diff-tree aa9d04ba94a3cd60b248231da517e2817591fc69 (from e8be0056e8ff666f63a294691661f5dab289203e)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jan 21 20:29:56 2007 +1100

    remove alot more mergedfb support

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index f220ca4..79d4a23 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -55,7 +55,6 @@
 #include "radeon_version.h"
 #include "radeon_reg.h"
 #include "radeon_macros.h"
-#include "radeon_mergedfb.h"
 
 				/* X and server generic header files */
 #include "xf86.h"
diff --git a/src/radeon_display.c b/src/radeon_display.c
index f80162d..98faf4c 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -45,7 +45,6 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
-#include "radeon_mergedfb.h"
 
 
 void radeon_crtc_load_lut(xf86CrtcPtr crtc);
@@ -2025,10 +2024,7 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
     } else if (pRADEONEnt->Controller[1]->binding == 1) info2 = info;
 
     mode1 = info->CurrentLayout.mode;
-    if (info->MergedFB) {
-	mode1 = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1;
-	mode2 = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
-    } else if ((pRADEONEnt->HasSecondary) && info2) {
+    if ((pRADEONEnt->HasSecondary) && info2) {
 	mode2 = info2->CurrentLayout.mode;
     } else {
 	mode2 = NULL;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c2b0418..101acf1 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -74,7 +74,6 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
-#include "radeon_mergedfb.h"
 
 #ifdef XF86DRI
 #define _XF86DRI_SERVER_
@@ -119,7 +118,6 @@ static void RADEONSave(ScrnInfoPtr pScrn
 //static void RADEONRestore(ScrnInfoPtr pScrn);
 static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
-static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn);
 static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
 static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
 static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
@@ -163,16 +161,6 @@ static const OptionInfoRec RADEONOptions
     { OPTION_MONITOR_LAYOUT, "MonitorLayout",    OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_IGNORE_EDID,    "IgnoreEDID",       OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_FBDEV,          "UseFBDev",         OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_MERGEDFB,	     "MergedFB",      	 OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_CRT2HSYNC,	     "CRT2HSync",        OPTV_ANYSTR,  {0}, FALSE },
-    { OPTION_CRT2VREFRESH,   "CRT2VRefresh",     OPTV_ANYSTR,  {0}, FALSE },
-    { OPTION_CRT2POS,        "CRT2Position",	 OPTV_ANYSTR,  {0}, FALSE },
-    { OPTION_METAMODES,      "MetaModes",        OPTV_ANYSTR,  {0}, FALSE },
-    { OPTION_MERGEDDPI,	     "MergedDPI", 	 OPTV_ANYSTR,  {0}, FALSE },
-    { OPTION_RADEONXINERAMA, "MergedXinerama", OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_CRT2ISSCRN0,    "MergedXineramaCRT2IsScreen0", OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_MERGEDFBNONRECT, "MergedNonRectangular", OPTV_BOOLEAN,   {0}, FALSE },
-    { OPTION_MERGEDFBMOUSER,  "MergedMouseRestriction", OPTV_BOOLEAN,   {0}, FALSE },
     { OPTION_DISP_PRIORITY,  "DisplayPriority",  OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_PANEL_SIZE,     "PanelSize",        OPTV_ANYSTR,  {0}, FALSE },
     { OPTION_MIN_DOTCLOCK,   "ForceMinDotClock", OPTV_FREQ,    {0}, FALSE },
@@ -1988,394 +1976,6 @@ static Bool RADEONPreInitGamma(ScrnInfoP
     return TRUE;
 }
 
-/* This is called by RADEONPreInit to validate modes and compute
- * parameters for all of the valid modes.
- */
-static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
-{
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
-    ClockRangePtr  clockRanges;
-    int            modesFound;
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    char           *s;
-    xf86OutputPtr connector;
-    /* This option has two purposes:
-     *
-     * 1. For CRT, if this option is on, xf86ValidateModes (to
-     *    LOOKUP_BEST_REFRESH) is not going to be used for mode
-     *    validation.  Instead, we'll validate modes by matching exactly
-     *    the modes supported from the DDC data.  This option can be
-     *    used (a) to enable non-standard modes listed in the Detailed
-     *    Timings block of EDID, like 2048x1536 (not included in
-     *    xf86DefModes), (b) to avoid unstable modes for some flat
-     *    panels working in analog mode (some modes validated by
-     *    xf86ValidateModes don't really work with these panels).
-     *
-     * 2. For DFP on primary head, with this option on, the validation
-     *    routine will try to use supported modes from DDC data first
-     *    before trying on-chip RMX streching.  By default, native mode
-     *    + RMX streching is used for all non-native modes, it appears
-     *    more reliable. Some non-native modes listed in the DDC data
-     *    may not work properly if they are used directly. This seems to
-     *    only happen to a few panels (haven't nailed this down yet, it
-     *    may related to the incorrect setting in TMDS_PLL_CNTL when
-     *    pixel clock is changed).  Use this option may give you better
-     *    refresh rate for some non-native modes.  The 2nd DVI port will
-     *    always use DDC modes directly (only have one on-chip RMX
-     *    unit).
-     *
-     * Note: This option will be dismissed if no DDC data is available.
-     */
-
-    if (info->MergedFB) {
-	if (!(pScrn->display->virtualX))
-	    info->NoVirtual = TRUE;
-	else
-	    info->NoVirtual = FALSE;
-    }
-
-    info->ddc_mode =
-	xf86ReturnOptValBool(info->Options, OPTION_DDC_MODE, FALSE);
-
-    /* don't use RMX if we have a dual-tmds panels */
-    
-    if ((connector = RADEONGetCrtcConnector(pScrn, 2))) {
-	RADEONOutputPrivatePtr radconnector = connector->driver_private;
-	if (radconnector->MonType == MT_DFP)
-	    info->ddc_mode = TRUE;
-    }
-    /* don't use RMX if we are Dell Server */  
-    if (info->IsDellServer)
-    {
-	info->ddc_mode = TRUE;
-    }
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Validating modes on %s head ---------\n",
-	       info->IsSecondary ? "Secondary" : "Primary");
-
-    if (!pRADEONEnt->pOutput[0]->MonInfo && !pRADEONEnt->pOutput[1]->MonInfo && info->ddc_mode) {
-	info->ddc_mode = FALSE;
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "No DDC data available, DDCMode option is dismissed\n");
-    }
-
-    if ((info->DisplayType == MT_DFP) ||
-	(info->DisplayType == MT_LCD)) {
-	if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
-	    int PanelX, PanelY;
-	    DisplayModePtr  tmp_mode         = NULL;
-	    if (sscanf(s, "%dx%d", &PanelX, &PanelY) == 2) {
-		info->PanelXRes = PanelX;
-		info->PanelYRes = PanelY;
-		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-			   "Panel size is forced to: %s\n", s);
-
-		/* We can't trust BIOS or DDC timings anymore, 
-		   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.
-		*/ 
-		info->ddc_mode = FALSE;
-		pScrn->monitor->DDC = NULL;
-		tmp_mode = pScrn->monitor->Modes;
-		while(tmp_mode) {
-		    if ((tmp_mode->HDisplay == PanelX) && 
-			(tmp_mode->VDisplay == PanelY)) {
-
-			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)) {
-			    info->HBlank     = tmp_mode->HTotal - tmp_mode->HDisplay;
-			    info->HOverPlus  = tmp_mode->HSyncStart - tmp_mode->HDisplay;
-			    info->HSyncWidth = tmp_mode->HSyncEnd - tmp_mode->HSyncStart;
-			    info->VBlank     = tmp_mode->VTotal - tmp_mode->VDisplay;
-			    info->VOverPlus  = tmp_mode->VSyncStart - tmp_mode->VDisplay;
-			    info->VSyncWidth = tmp_mode->VSyncEnd - tmp_mode->VSyncStart;
-			    info->DotClock   = tmp_mode->Clock;
-			    info->Flags = 0;
-			    break;
-			}
-		    }
-		    tmp_mode = tmp_mode->next;
-		}
-		if (info->DotClock == 0) {
-		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			       "No valid timing info for specified panel size.\n"
-			       "Please specify the Modeline for this panel\n");
-		    return FALSE;
-		}
-	    } else {
-		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
-			   "Invalid PanelSize value: %s\n", s);
-	    }
-        } else
-            RADEONGetPanelInfo(pScrn);
-    }
-
-    if (pScrn->monitor->DDC) {
-        /* If we still don't know sync range yet, let's try EDID.
-         *
-         * Note that, since we can have dual heads, Xconfigurator
-         * may not be able to probe both monitors correctly through
-         * vbe probe function (RADEONProbeDDC). Here we provide an
-         * additional way to auto-detect sync ranges if they haven't
-         * been added to XF86Config manually.
-         */
-        if (pScrn->monitor->nHsync <= 0)
-            RADEONSetSyncRangeFromEdid(pScrn, 1);
-        if (pScrn->monitor->nVrefresh <= 0)
-            RADEONSetSyncRangeFromEdid(pScrn, 0);
-    }
-
-    /* Get mode information */
-    pScrn->progClock               = TRUE;
-    clockRanges                    = xnfcalloc(sizeof(*clockRanges), 1);
-    clockRanges->next              = NULL;
-    clockRanges->minClock          = info->pll.min_pll_freq;
-    clockRanges->maxClock          = info->pll.max_pll_freq * 10;
-    clockRanges->clockIndex        = -1;
-    clockRanges->interlaceAllowed  = (info->DisplayType == MT_CRT);
-    clockRanges->doubleScanAllowed = (info->DisplayType == MT_CRT);
-
-    /* We'll use our own mode validation routine for DFP/LCD, since
-     * xf86ValidateModes does not work correctly with the DFP/LCD modes
-     * 'stretched' from their native mode.
-     */
-    if (info->DisplayType == MT_CRT && !info->ddc_mode) {
-
-	modesFound =
-	    xf86ValidateModes(pScrn,
-			      pScrn->monitor->Modes,
-			      pScrn->display->modes,
-			      clockRanges,
-			      NULL,                  /* linePitches */
-			      8 * 64,                /* minPitch */
-			      8 * 1024,              /* maxPitch */
-			      info->allowColorTiling ? 2048 :
-			          64 * pScrn->bitsPerPixel, /* pitchInc */
-			      128,                   /* minHeight */
-			      info->MaxLines,        /* maxHeight */
-			      pScrn->display->virtualX,
-			      pScrn->display->virtualY,
-			      info->FbMapSize,
-			      LOOKUP_BEST_REFRESH);
-
-	if (modesFound < 1 && info->FBDev) {
-	    fbdevHWUseBuildinMode(pScrn);
-	    pScrn->displayWidth = fbdevHWGetLineLength(pScrn)
-				/ info->CurrentLayout.pixel_bytes;
-	    modesFound = 1;
-	}
-
-	if (modesFound == -1) return FALSE;
-
-	xf86PruneDriverModes(pScrn);
-	if (!modesFound || !pScrn->modes) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
-	    return FALSE;
-	}
-
-    } else {
-	/* First, free any allocated modes during configuration, since
-	 * we don't need them
-	 */
-	while (pScrn->modes)
-	    xf86DeleteMode(&pScrn->modes, pScrn->modes);
-	while (pScrn->modePool)
-	    xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
-	/* Next try to add DDC modes */
-	modesFound = RADEONValidateDDCModes(pScrn, pScrn->display->modes,
-					    info->DisplayType, 0);
-
-	/* If that fails and we're connect to a flat panel, then try to
-         * add the flat panel modes
-	 */
-	if (info->DisplayType != MT_CRT) {
-
-	    /* some panels have DDC, but don't have internal scaler.
-	     * in this case, we need to validate additional modes
-	     * by using on-chip RMX.
-	     */
-	    int user_modes_asked = 0, user_modes_found = 0, i;
-	    DisplayModePtr  tmp_mode = pScrn->modes;
-	    while (pScrn->display->modes[user_modes_asked]) user_modes_asked++;
-	    if (tmp_mode) {
-		for (i = 0; i < modesFound; i++) {
-		    if (tmp_mode->type & M_T_USERDEF) user_modes_found++;
-		    tmp_mode = tmp_mode->next;
-		}
-	    }
-
-	    if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
-		/* when panel size is not valid, try to validate
-		 * mode using xf86ValidateModes routine
-		 * This can happen when DDC is disabled.
-		 */
-		if (info->PanelXRes < 320 || info->PanelYRes < 200)
-		    modesFound =
-			xf86ValidateModes(pScrn,
-					  pScrn->monitor->Modes,
-					  pScrn->display->modes,
-					  clockRanges,
-					  NULL,                  /* linePitches */
-					  8 * 64,                /* minPitch */
-					  8 * 1024,              /* maxPitch */
-					  info->allowColorTiling ? 2048 :
-					      64 * pScrn->bitsPerPixel, /* pitchInc */
-					  128,                   /* minHeight */
-					  info->MaxLines,        /* maxHeight */
-					  pScrn->display->virtualX,
-					  pScrn->display->virtualY,
-					  info->FbMapSize,
-					  LOOKUP_BEST_REFRESH);
-		else if (!info->IsSecondary)
-		  modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes, &pScrn->monitor->Modes);
-	    }
-        }
-
-	/* Setup the screen's clockRanges for the VidMode extension */
-	if (!pScrn->clockRanges) {
-	    pScrn->clockRanges = xnfcalloc(sizeof(*(pScrn->clockRanges)), 1);
-	    memcpy(pScrn->clockRanges, clockRanges, sizeof(*clockRanges));
-	    pScrn->clockRanges->strategy = LOOKUP_BEST_REFRESH;
-	}
-
-	/* Fail if we still don't have any valid modes */
-	if (modesFound < 1) {
-	    if (info->DisplayType == MT_CRT) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "No valid DDC modes found for this CRT\n");
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Try turning off the \"DDCMode\" option\n");
-	    } else {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "No valid mode found for this DFP/LCD\n");
-	    }
-	    return FALSE;
-	}
-    }
-
-    xf86SetCrtcForModes(pScrn, 0);
-
-    if (pRADEONEnt->HasCRTC2) {
-	if (pRADEONEnt->Controller[1]->binding == 1) {
-
-	    /* If we have 2 screens from the config file, we don't need
-	     * to do clone thing, let each screen handles one head.
-	     */
-	    if (!pRADEONEnt->HasSecondary) {
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			   "Validating CRTC2 modes for MergedFB ------------ \n");
-
-		modesFound = RADEONValidateMergeModes(pScrn);
-		if (modesFound < 1) {
-		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			       "No valid mode found for CRTC2, disabling MergedFB\n");
-		    info->MergedFB = FALSE;
-		}
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			   "Total of %d CRTC2 modes found for MergedFB------------ \n",
-			   modesFound);
-	    }
-	}
-    }
-
-    pScrn->currentMode = pScrn->modes;
-    if(info->MergedFB) {
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-       	   "Modes for CRT1: ********************\n");
-    }
-    xf86PrintModes(pScrn);
-
-    if(pRADEONEnt->Controller[1]->binding == 1) {
-
-       xf86SetCrtcForModes(info->CRT2pScrn, INTERLACE_HALVE_V);
-
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-           "Modes for CRT2: ********************\n");
-
-       xf86PrintModes(info->CRT2pScrn);
-
-       info->CRT1Modes = pScrn->modes;
-       info->CRT1CurrentMode = pScrn->currentMode;
-
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Generating MergedFB mode list\n");
-
-       if (info->NoVirtual) {
-           pScrn->display->virtualX = 0;
-           pScrn->display->virtualY = 0;
-       }
-       pScrn->modes = RADEONGenerateModeList(pScrn, info->MetaModes,
-	            	                  info->CRT1Modes, info->CRT2pScrn->modes,
-					  info->CRT2Position);
-
-       if(!pScrn->modes) {
-
-	  xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-	      "Failed to parse MetaModes or no modes found. MergeFB mode disabled.\n");
-	  if(info->CRT2pScrn) {
-	     if(info->CRT2pScrn->modes) {
-	        while(info->CRT2pScrn->modes)
-		   xf86DeleteMode(&info->CRT2pScrn->modes, info->CRT2pScrn->modes);
-	     }
-	     if(info->CRT2pScrn->monitor) {
-	        if(info->CRT2pScrn->monitor->Modes) {
-	           while(info->CRT2pScrn->monitor->Modes)
-		      xf86DeleteMode(&info->CRT2pScrn->monitor->Modes, info->CRT2pScrn->monitor->Modes);
-	        }
-		if(info->CRT2pScrn->monitor->DDC) xfree(info->CRT2pScrn->monitor->DDC);
-	        xfree(info->CRT2pScrn->monitor);
-	     }
-             xfree(info->CRT2pScrn);
-	     info->CRT2pScrn = NULL;
-	  }
-	  pScrn->modes = info->CRT1Modes;
-	  info->CRT1Modes = NULL;
-	  info->MergedFB = FALSE;
-
-       }
-    }
-
-    if (info->MergedFB) {
-       /* If no virtual dimension was given by the user,
-        * calculate a sane one now. Adapts pScrn->virtualX,
-	* pScrn->virtualY and pScrn->displayWidth.
-	*/
-       RADEONRecalcDefaultVirtualSize(pScrn);
-       info->CRT2pScrn->virtualX = pScrn->virtualX;
-       info->CRT2pScrn->virtualY = pScrn->virtualY;
-       RADEONSetPitch(pScrn);
-       RADEONSetPitch(info->CRT2pScrn);
-
-       pScrn->modes = pScrn->modes->next;  /* We get the last from GenerateModeList() */
-       pScrn->currentMode = pScrn->modes;
-
-       /* Update CurrentLayout */
-       info->CurrentLayout.mode = pScrn->currentMode;
-       info->CurrentLayout.displayWidth = pScrn->displayWidth;
-    }
-
-				/* Set DPI */
-    /* xf86SetDpi(pScrn, 0, 0); */
-
-    if (info->MergedFB) {
-	RADEONMergedFBSetDpi(pScrn, info->CRT2pScrn, info->CRT2Position);
-    } else {
-	xf86SetDpi(pScrn, 0, 0);
-        info->RADEONDPIVX = pScrn->virtualX;
-        info->RADEONDPIVY = pScrn->virtualY;
-    }
-
-			
-
-    info->CurrentLayout.displayWidth = pScrn->displayWidth;
-    info->CurrentLayout.mode = pScrn->currentMode;
-
-    return TRUE;
-}
-
 /* This is called by RADEONPreInit to initialize the hardware cursor */
 static Bool RADEONPreInitCursor(ScrnInfoPtr pScrn)
 {
@@ -3252,13 +2852,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     xf86LoaderReqSymLists(fbSymbols, NULL);
 
-    /* collect MergedFB options */
-    /* only parse mergedfb options on the primary head. 
-       Mergedfb is already disabled in xinerama/screen based
-       multihead */
-    if (!info->IsSecondary)
-	RADEONGetMergedFBOptions(pScrn);
-
     if (!RADEONPreInitGamma(pScrn))              goto fail;
 
     if (!RADEONPreInitCursor(pScrn))             goto fail;
@@ -3406,111 +2999,6 @@ static void RADEONLoadPalette(ScrnInfoPt
       crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
 #endif
       }
-#if 0
-	/* If the second monitor is connected, we also need to deal with
-	 * the secondary palette
-	 */
-	if (info->IsSecondary) j = 1;
-	else j = 0;
-
-	PAL_SELECT(j);
-
-	if (info->CurrentLayout.depth == 15) {
-	    /* 15bpp mode.  This sends 32 values. */
-	    for (i = 0; i < numColors; i++) {
-		idx = indices[i];
-		r   = colors[idx].red;
-		g   = colors[idx].green;
-		b   = colors[idx].blue;
-		OUTPAL(idx * 8, r, g, b);
-	    }
-	} else if (info->CurrentLayout.depth == 16) {
-	    /* 16bpp mode.  This sends 64 values.
-	     *
-	     * There are twice as many green values as there are values
-	     * for red and blue.  So, we take each red and blue pair,
-	     * and combine it with each of the two green values.
-	     */
-	    for (i = 0; i < numColors; i++) {
-		idx = indices[i];
-		r   = colors[idx / 2].red;
-		g   = colors[idx].green;
-		b   = colors[idx / 2].blue;
-		RADEONWaitForFifo(pScrn, 32); /* delay */
-		OUTPAL(idx * 4, r, g, b);
-
-		/* AH - Added to write extra green data - How come this isn't
-		 * needed on R128?  We didn't load the extra green data in the
-		 * other routine
-		 */
-		if (idx <= 31) {
-		    r   = colors[idx].red;
-		    g   = colors[(idx * 2) + 1].green;
-		    b   = colors[idx].blue;
-		    RADEONWaitForFifo(pScrn, 32); /* delay */
-		    OUTPAL(idx * 8, r, g, b);
-		}
-	    }
-	} else {
-	    /* 8bpp mode.  This sends 256 values. */
-	    for (i = 0; i < numColors; i++) {
-		idx = indices[i];
-		r   = colors[idx].red;
-		b   = colors[idx].blue;
-		g   = colors[idx].green;
-		RADEONWaitForFifo(pScrn, 32); /* delay */
-		OUTPAL(idx, r, g, b);
-	    }
-	}
-
-	if (info->MergedFB) {
-	    PAL_SELECT(1);
-	    if (info->CurrentLayout.depth == 15) {
-		/* 15bpp mode.  This sends 32 values. */
-		for (i = 0; i < numColors; i++) {
-		    idx = indices[i];
-		    r   = colors[idx].red;
-		    g   = colors[idx].green;
-		    b   = colors[idx].blue;
-		    OUTPAL(idx * 8, r, g, b);
-		}
-	    } else if (info->CurrentLayout.depth == 16) {
-		/* 16bpp mode.  This sends 64 values.
-		 *
-		 * There are twice as many green values as there are values
-		 * for red and blue.  So, we take each red and blue pair,
-		 * and combine it with each of the two green values.
-		 */
-		for (i = 0; i < numColors; i++) {
-		    idx = indices[i];
-		    r   = colors[idx / 2].red;
-		    g   = colors[idx].green;
-		    b   = colors[idx / 2].blue;
-		    OUTPAL(idx * 4, r, g, b);
-
-		    /* AH - Added to write extra green data - How come
-		     * this isn't needed on R128?  We didn't load the
-		     * extra green data in the other routine.
-		     */
-		    if (idx <= 31) {
-			r   = colors[idx].red;
-			g   = colors[(idx * 2) + 1].green;
-			b   = colors[idx].blue;
-			OUTPAL(idx * 8, r, g, b);
-		    }
-		}
-	    } else {
-		/* 8bpp mode.  This sends 256 values. */
-		for (i = 0; i < numColors; i++) {
-		    idx = indices[i];
-		    r   = colors[idx].red;
-		    b   = colors[idx].blue;
-		    g   = colors[idx].green;
-		    OUTPAL(idx, r, g, b);
-		}
-	    }
-	}
-#endif
     }
 
 #ifdef XF86DRI
@@ -3934,17 +3422,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 	info->allowColorTiling = FALSE;
     }
     if (info->allowColorTiling) {
-	if (info->MergedFB) {
-	    if ((((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT1->Flags &
-		(V_DBLSCAN | V_INTERLACE)) ||
-		(((RADEONMergedDisplayModePtr)pScrn->currentMode->Private)->CRT2->Flags &
-		(V_DBLSCAN | V_INTERLACE)))
-		info->tilingEnabled = FALSE;
-	    else info->tilingEnabled = TRUE;
-	}
-	else {
-            info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
-	}
+        info->tilingEnabled = (pScrn->currentMode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
     }
 
     /* Visual setup */
@@ -4275,10 +3753,6 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 	RADEONChangeSurfaces(pScrn);
     }
 
-    if(info->MergedFB)
-	/* need this here to fix up sarea values */
-	RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
     /* Enable aceleration */
     if (!xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE)) {
 	 RADEONTRACE(("Initializing Acceleration\n"));
@@ -4343,27 +3817,10 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     RADEONTRACE(("Initializing DGA\n"));
     RADEONDGAInit(pScreen);
 
-    /* Wrap some funcs for MergedFB */
-    if(info->MergedFB) {
-       info->PointerMoved = pScrn->PointerMoved;
-       pScrn->PointerMoved = RADEONMergePointerMoved;
-       /* Psuedo xinerama */
-       if(info->UseRADEONXinerama) {
-          RADEONnoPanoramiXExtension = FALSE;
-          RADEONXineramaExtensionInit(pScrn);
-       } else {
-	  info->MouseRestrictions = FALSE;
-       }
-    }
-
     /* Init Xv */
     RADEONTRACE(("Initializing Xv\n"));
     RADEONInitVideo(pScreen);
 
-    if(info->MergedFB)
-	/* need this here to fix up sarea values */
-	RADEONAdjustFrameMerged(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
     /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
     /* Wrap CloseScreen */
     info->CloseScreen    = pScreen->CloseScreen;
@@ -6587,9 +6044,6 @@ static Bool RADEONInit(ScrnInfoPtr pScrn
 
     if (info->IsSecondary) {
         return RADEONInit2(pScrn, NULL, mode, 2, save, info->DisplayType);
-    } else if (info->MergedFB) {
-        return RADEONInit2(pScrn, ((RADEONMergedDisplayModePtr)mode->Private)->CRT1,
-			   ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, 3, save, info->MergeType);
     } else {
         return RADEONInit2(pScrn, mode, NULL, 1, save, info->DisplayType);
     }
@@ -6672,17 +6126,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrn
     RADEONTRACE(("RADEONSwitchMode() !n"));
 
     if (info->allowColorTiling) {
-	if (info->MergedFB) {
-	    if ((((RADEONMergedDisplayModePtr)mode->Private)->CRT1->Flags &
-		(V_DBLSCAN | V_INTERLACE)) ||
-		(((RADEONMergedDisplayModePtr)mode->Private)->CRT2->Flags &
-		(V_DBLSCAN | V_INTERLACE)))
-		info->tilingEnabled = FALSE;
-	    else info->tilingEnabled = TRUE;
-	}
-	else {
-            info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
-	}
+        info->tilingEnabled = (mode->Flags & (V_DBLSCAN | V_INTERLACE)) ? FALSE : TRUE;
 #ifdef XF86DRI	
 	if (info->directRenderingEnabled && (info->tilingEnabled != tilingOld)) {
 	    RADEONSAREAPrivPtr pSAREAPriv;
@@ -6740,10 +6184,7 @@ _X_EXPORT Bool RADEONSwitchMode(int scrn
     /* Since RandR (indirectly) uses SwitchMode(), we need to
      * update our Xinerama info here, too, in case of resizing
      */
-    if (info->MergedFB) {
-        RADEONMergedFBResetDpi(pScrn, FALSE);
-        RADEONUpdateXineramaScreenInfo(pScrn);
-    } else if(info->constantDPI) {
+    if(info->constantDPI) {
        RADEONResetDPI(pScrn, FALSE);
     }
 
@@ -6907,9 +6348,7 @@ _X_EXPORT void RADEONAdjustFrame(int scr
     if (info->accelOn)
         RADEON_SYNC(info, pScrn);
 
-    if(info->MergedFB) {
-    	RADEONAdjustFrameMerged(scrnIndex, x, y, flags);
-    } else if (info->FBDev) {
+    if (info->FBDev) {
 	fbdevHWAdjustFrame(scrnIndex, x, y, flags);
     } else {
 	RADEONDoAdjustFrame(pScrn, x, y, FALSE);
@@ -7182,244 +6621,6 @@ _X_EXPORT void RADEONFreeScreen(int scrn
     RADEONFreeRec(pScrn);
 }
 
-static void
-RADEONGetMergedFBOptions(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr      info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    xf86OutputPtr pOutput;
-    char        *strptr;
-    char	*default_hsync = "28-33";
-    char	*default_vrefresh = "43-72";
-    Bool	val;
-    Bool	default_range = FALSE;
-    static const char *mybadparm = "\"%s\" is is not a valid parameter for option \"%s\"\n";
-
-    if (info->FBDev == TRUE) {
-	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-	    "MergedFB does not work with Option UseFBDev, MergedFB mode is disabled\n");
-	info->MergedFB = FALSE;
-	return;
-    }
-
-#if RANDR_12_INTERFACE
-    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-              "MergedFB does not work with Randr 1.2\n");
-    info->MergedFB = FALSE;
-    return;
-#endif
-
-
-			/* collect MergedFB options */
-    info->MergedFB = TRUE;
-    info->UseRADEONXinerama = TRUE;
-    info->CRT2IsScrn0 = FALSE;
-    info->CRT2Position = radeonClone;
-    info->MergedFBXDPI = info->MergedFBYDPI = 0;
-    info->CRT1XOffs = info->CRT1YOffs = info->CRT2XOffs = info->CRT2YOffs = 0;
-    info->NonRect = info->HaveNonRect = info->HaveOffsRegions = FALSE;
-    info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536;
-    info->MouseRestrictions = TRUE;
-
-    if (info->MergeType == MT_NONE) {
-	info->MergedFB = FALSE;
-        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-        "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n");
-    } else if ((pOutput = RADEONGetCrtcConnector(pScrn, 2))) {
-	if (!pOutput->MonInfo) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-		       "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n");
-	    default_range = TRUE;
-	}
-    }
-
-    if (xf86GetOptValBool(info->Options, OPTION_MERGEDFB, &val)) {
-        if (val) {
-	    info->MergedFB = TRUE;
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	    "MergedFB mode forced on.\n");
-        } else {
-	    info->MergedFB = FALSE;
-            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	    "MergedFB mode forced off.\n");
-        }
-    }
-
-    /* Do some MergedFB mode initialisation */
-    if(info->MergedFB) {
-       info->CRT2pScrn = xalloc(sizeof(ScrnInfoRec));
-       if(!info->CRT2pScrn) {
-          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-	  	"Failed to allocate memory for merged pScrn, MergedFB mode is disabled\n");
-	  info->MergedFB = FALSE;
-       } else {
-          memcpy(info->CRT2pScrn, pScrn, sizeof(ScrnInfoRec));
-       }
-    }
-    if(info->MergedFB) {
-	  int result, ival;
-	  Bool valid = FALSE;
-	  char *tempstr;
-	  strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2POS);
-	  if (strptr) {
-	      tempstr = xalloc(strlen(strptr) + 1);
-	      result = sscanf(strptr, "%s %d", tempstr, &ival);
-	  } else { 	      /* Not specified - default is "Clone" */
-	      tempstr = NULL;
-	      result = 0;
-	      info->CRT2Position = radeonClone;
-	      valid = TRUE;
-	  }
-	  if(result >= 1) {
-       	        if(!xf86NameCmp(tempstr,"LeftOf")) {
-                   info->CRT2Position = radeonLeftOf;
-		   valid = TRUE;
-		   if(result == 2) {
-		      if(ival < 0) info->CRT1YOffs = -ival;
-		      else info->CRT2YOffs = ival;
-		   }
-		   info->CRT2IsScrn0 = TRUE;
- 	        } else if(!xf86NameCmp(tempstr,"RightOf")) {
-                   info->CRT2Position = radeonRightOf;
-		   valid = TRUE;
-		   if(result == 2) {
-		      if(ival < 0) info->CRT1YOffs = -ival;
-		      else info->CRT2YOffs = ival;
-		   }
-		   info->CRT2IsScrn0 = FALSE;
-	        } else if(!xf86NameCmp(tempstr,"Above")) {
-                   info->CRT2Position = radeonAbove;
-		   valid = TRUE;
-		   if(result == 2) {
-		      if(ival < 0) info->CRT1XOffs = -ival;
-		      else info->CRT2XOffs = ival;
-		   }
-		   info->CRT2IsScrn0 = FALSE;
-	        } else if(!xf86NameCmp(tempstr,"Below")) {
-                   info->CRT2Position = radeonBelow;
-		   valid = TRUE;
-		   if(result == 2) {
-		      if(ival < 0) info->CRT1XOffs = -ival;
-		      else info->CRT2XOffs = ival;
-		   }
-		   info->CRT2IsScrn0 = TRUE;
-	        } else if(!xf86NameCmp(tempstr,"Clone")) {
-                   info->CRT2Position = radeonClone;
-		   if(result == 1) valid = TRUE;
-		   /*info->CRT2IsScrn0 = TRUE;*/
-	        } 
-	  }
-	  if(!valid) {
-	        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-	            "\"%s\" is not a valid parameter for Option \"CRT2Position\"\n", strptr);
-	    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	            "Valid parameters are \"RightOf\", \"LeftOf\", \"Above\", \"Below\", or \"Clone\"\n");
-		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	            "Except for \"Clone\", the parameter may be followed by an integer.\n");
-	  }
-	  xfree(tempstr);
-
-	  strptr = (char *)xf86GetOptValString(info->Options, OPTION_METAMODES);
-	  if(strptr) {
-	     info->MetaModes = xalloc(strlen(strptr) + 1);
-	     if(info->MetaModes) memcpy(info->MetaModes, strptr, strlen(strptr) + 1);
-	  }
-	  strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2HSYNC);
-	  if(strptr) {
-	      info->CRT2HSync = xalloc(strlen(strptr) + 1);
-	      if(info->CRT2HSync) memcpy(info->CRT2HSync, strptr, strlen(strptr) + 1);
-	  }
-	  strptr = (char *)xf86GetOptValString(info->Options, OPTION_CRT2VREFRESH);
-	  if(strptr) {
-	      info->CRT2VRefresh = xalloc(strlen(strptr) + 1);
-	      if(info->CRT2VRefresh) memcpy(info->CRT2VRefresh, strptr, strlen(strptr) + 1);
-	  }
-
-	if(xf86GetOptValBool(info->Options, OPTION_RADEONXINERAMA, &val)) {
-	    if (!val)
-		info->UseRADEONXinerama = FALSE;
-	}
-	if(info->UseRADEONXinerama) {
-	        if(xf86GetOptValBool(info->Options, OPTION_CRT2ISSCRN0, &val)) {
-		   if(val) info->CRT2IsScrn0 = TRUE;
-		   else    info->CRT2IsScrn0 = FALSE;
-		}
-                if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBNONRECT, &val)) {
-  	            info->NonRect = val ? TRUE : FALSE;
-  	        }
-  	        if(xf86GetOptValBool(info->Options, OPTION_MERGEDFBMOUSER, &val)) {
-  	            info->MouseRestrictions = val ? TRUE : FALSE;
-  	        }
-	}
-	strptr = (char *)xf86GetOptValString(info->Options, OPTION_MERGEDDPI);
-	if(strptr) {
-	    int val1 = 0, val2 = 0;
-	    sscanf(strptr, "%d %d", &val1, &val2);
-	    if(val1 && val2) {
-	        info->MergedFBXDPI = val1;
-		info->MergedFBYDPI = val2;
-	     } else {
-	        xf86DrvMsg(pScrn->scrnIndex, X_WARNING, mybadparm, strptr, "MergedDPI");
-	     }
- 	}
-    }
-
-    if(info->MergedFB) {
-          /* fill in monitor */
-       info->CRT2pScrn->monitor = xalloc(sizeof(MonRec));
-       if(info->CRT2pScrn->monitor) {
-          DisplayModePtr tempm = NULL, currentm = NULL, newm = NULL;
-          memcpy(info->CRT2pScrn->monitor, pScrn->monitor, sizeof(MonRec));
-          info->CRT2pScrn->monitor->DDC = NULL;
-	  info->CRT2pScrn->monitor->Modes = NULL;
-	  info->CRT2pScrn->monitor->id = "CRT2 Monitor";
-	  tempm = pScrn->monitor->Modes;
-	  while(tempm) {
-	         if(!(newm = xalloc(sizeof(DisplayModeRec)))) break;
-	         memcpy(newm, tempm, sizeof(DisplayModeRec));
-	         if(!(newm->name = xalloc(strlen(tempm->name) + 1))) {
-	            xfree(newm);
-		    break;
-	         }
-	         strcpy(newm->name, tempm->name);
-	         if(!info->CRT2pScrn->monitor->Modes) 
-		    info->CRT2pScrn->monitor->Modes = newm;
-	         if(currentm) {
-	            currentm->next = newm;
-		    newm->prev = currentm;
-	         }
-	         currentm = newm;
-	         tempm = tempm->next;
-	  }
-
-	  /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */
-	  if ((pOutput = RADEONGetCrtcConnector(pScrn, 2)))
-	      info->CRT2pScrn->monitor->DDC = pOutput->MonInfo;
-	  else
-	      info->CRT2pScrn->monitor->DDC = NULL;
-          if (default_range) {
-             RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, default_hsync, MAX_HSYNC);
-             RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, default_vrefresh, MAX_VREFRESH);
-          }
-          if(info->CRT2HSync) {
-             info->CRT2pScrn->monitor->nHsync =
-	    	RADEONStrToRanges(info->CRT2pScrn->monitor->hsync, info->CRT2HSync, MAX_HSYNC);
-          }
-          if(info->CRT2VRefresh) {
-             info->CRT2pScrn->monitor->nVrefresh =
-	    	RADEONStrToRanges(info->CRT2pScrn->monitor->vrefresh, info->CRT2VRefresh, MAX_VREFRESH);
-          }
-
-       } else {
-          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-	  	"Failed to allocate memory for CRT2 monitor, MergedFB mode disabled.\n");
-	  if(info->CRT2pScrn) xfree(info->CRT2pScrn);
-    	  info->CRT2pScrn = NULL;
-	  info->MergedFB = FALSE;
-       }
-    }
-}
-
 static void RADEONForceSomeClocks(ScrnInfoPtr pScrn)
 {
     /* It appears from r300 and rv100 may need some clocks forced-on */
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index b97b6bd..6036f82 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -55,15 +55,6 @@
 #include "xf86DDC.h"
 #include <randrstr.h>
 
-void
-RADEONGetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
-    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
-    *x = pScrn->virtualX;
-    *y = pScrn->virtualY;
-}
-
 void RADEONSetPitch (ScrnInfoPtr pScrn)
 {
     int  dummy = pScrn->virtualX;
@@ -85,167 +76,6 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
     pScrn->displayWidth = dummy;
 }
 
-/* XFree86's xf86ValidateModes routine doesn't work well with DDC modes,
- * so here is our own validation routine.
- */
-int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
-			   RADEONMonitorType DisplayType, int crtc2)
-{
-    RADEONInfoPtr   info       = RADEONPTR(pScrn1);
-    DisplayModePtr  p;
-    DisplayModePtr  last       = NULL;
-    DisplayModePtr  first      = NULL;
-    DisplayModePtr  ddcModes   = NULL;
-    int             count      = 0;
-    int             i, width, height;
-    ScrnInfoPtr pScrn = pScrn1;
-
-    if (crtc2)
-	pScrn = info->CRT2pScrn;
-
-    pScrn->virtualX = pScrn1->display->virtualX;
-    pScrn->virtualY = pScrn1->display->virtualY;
-
-    if (pScrn->monitor->DDC) {
-	int  maxVirtX = pScrn->virtualX;
-	int  maxVirtY = pScrn->virtualY;
-
-	/* Collect all of the DDC modes */
-	first = last = ddcModes = xf86DDCGetModes(pScrn->scrnIndex, pScrn->monitor->DDC);
-
-	for (p = ddcModes; p; p = p->next) {
-
-	    /* If primary head is a flat panel, use RMX by default */
-	    if ((!info->IsSecondary && DisplayType != MT_CRT) &&
-		(!info->ddc_mode) && (!crtc2)) {
-		/* These values are effective values after expansion.
-		 * They are not really used to set CRTC registers.
-		 */
-		p->HTotal     = info->PanelXRes + info->HBlank;
-		p->HSyncStart = info->PanelXRes + info->HOverPlus;
-		p->HSyncEnd   = p->HSyncStart + info->HSyncWidth;
-		p->VTotal     = info->PanelYRes + info->VBlank;
-		p->VSyncStart = info->PanelYRes + info->VOverPlus;
-		p->VSyncEnd   = p->VSyncStart + info->VSyncWidth;
-		p->Clock      = info->DotClock;
-
-		p->Flags     |= RADEON_USE_RMX;
-	    }
-
-	    maxVirtX = MAX(maxVirtX, p->HDisplay);
-	    maxVirtY = MAX(maxVirtY, p->VDisplay);
-	    count++;
-
-	    last = p;
-	}
-
-	/* Match up modes that are specified in the XF86Config file */
-	if (ppModeName[0]) {
-	    DisplayModePtr  next;
-
-	    /* Reset the max virtual dimensions */
-	    maxVirtX = pScrn->virtualX;
-	    maxVirtY = pScrn->virtualY;
-
-	    /* Reset list */
-	    first = last = NULL;
-
-	    for (i = 0; ppModeName[i]; i++) {
-		/* FIXME: Use HDisplay and VDisplay instead of mode string */
-		if (sscanf(ppModeName[i], "%dx%d", &width, &height) == 2) {
-		    for (p = ddcModes; p; p = next) {
-			next = p->next;
-
-			if (p->HDisplay == width && p->VDisplay == height) {
-			    /* We found a DDC mode that matches the one
-                               requested in the XF86Config file */
-			    p->type |= M_T_USERDEF;
-
-			    /* Update  the max virtual setttings */
-			    maxVirtX = MAX(maxVirtX, width);
-			    maxVirtY = MAX(maxVirtY, height);
-
-			    /* Unhook from DDC modes */
-			    if (p->prev) p->prev->next = p->next;
-			    if (p->next) p->next->prev = p->prev;
-			    if (p == ddcModes) ddcModes = p->next;
-
-			    /* Add to used modes */
-			    if (last) {
-				last->next = p;
-				p->prev = last;
-			    } else {
-				first = p;
-				p->prev = NULL;
-			    }
-			    p->next = NULL;
-			    last = p;
-
-			    break;
-			}
-		    }
-		}
-	    }
-
-	    /*
-	     * Add remaining DDC modes if they're smaller than the user
-	     * specified modes
-	     */
-	    for (p = ddcModes; p; p = next) {
-		next = p->next;
-		if (p->HDisplay <= maxVirtX && p->VDisplay <= maxVirtY) {
-		    /* Unhook from DDC modes */
-		    if (p->prev) p->prev->next = p->next;
-		    if (p->next) p->next->prev = p->prev;
-		    if (p == ddcModes) ddcModes = p->next;
-
-		    /* Add to used modes */
-		    if (last) {
-			last->next = p;
-			p->prev = last;
-		    } else {
-			first = p;
-			p->prev = NULL;
-		    }
-		    p->next = NULL;
-		    last = p;
-		}
-	    }
-
-	    /* Delete unused modes */
-	    while (ddcModes)
-		xf86DeleteMode(&ddcModes, ddcModes);
-	} else {
-	    /*
-	     * No modes were configured, so we make the DDC modes
-	     * available for the user to cycle through.
-	     */
-	    for (p = ddcModes; p; p = p->next)
-		p->type |= M_T_USERDEF;
-	}
-
-        if (crtc2) {
-            pScrn->virtualX = maxVirtX;
-            pScrn->virtualY = maxVirtY;
-	} else {
-	    pScrn->virtualX = pScrn->display->virtualX = maxVirtX;
-	    pScrn->virtualY = pScrn->display->virtualY = maxVirtY;
-	}
-    }
-
-    /* Close the doubly-linked mode list, if we found any usable modes */
-    if (last) {
-	last->next   = first;
-	first->prev  = last;
-	pScrn->modes = first;
-//	RADEONSetPitch(pScrn);
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Total number of valid DDC mode(s) found: %d\n", count);
-
-    return count;
-}
 
 /* This is used only when no mode is specified for FP and no ddc is
  * available.  We force it to native mode, if possible.
@@ -670,81 +500,6 @@ RADEONProbeOutputModes(xf86OutputPtr out
 				  FALSE);
     }
 }
-  
-
-/**
- * Constructs pScrn->modes from the output mode lists.
- *
- * Currently it only takes one output's mode list and stuffs it into the
- * XFree86 DDX mode list while trimming it for root window size.
- *
- * This should be obsoleted by RandR 1.2 hopefully.
- */
-void
-RADEON_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
-    RADEONInfoPtr info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    DisplayModePtr saved_mode, last;
-    int originalVirtualX, originalVirtualY;
-    int i;
-
-    /* Remove the current mode from the modelist if we're re-validating, so we
-     * can find a new mode to map ourselves to afterwards.
-     */
-    saved_mode = info->currentMode;
-    if (saved_mode != NULL) {
-	RADEONxf86DeleteModeFromList(&pScrn->modes, saved_mode);
-    }
-
-    /* Clear any existing modes from pScrn->modes */
-    while (pScrn->modes != NULL)
-	xf86DeleteMode(&pScrn->modes, pScrn->modes);
-
-    /* Set pScrn->modes to the mode list for an arbitrary output.
-     * pScrn->modes should only be used for XF86VidMode now, which we don't
-     * care about enough to make some sort of unioned list.
-     */
-    for (i = 0; i < config->num_output; i++) {
-        xf86OutputPtr output = config->output[i];
-	if (output->probed_modes != NULL) {
-	    pScrn->modes =
-		RADEON_xf86DuplicateModes(pScrn, output->probed_modes);
-	    break;
-	}
-    }
-
-    RADEONGetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
-
-    /* Disable modes in the XFree86 DDX list that are larger than the current
-     * virtual size.
-     */
-    RADEONxf86ValidateModesSize(pScrn, pScrn->modes,
-			      originalVirtualX, originalVirtualY,
-			      pScrn->displayWidth);
-
-    /* Strip out anything that we threw out for virtualX/Y. */
-    RADEONxf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
-
-    if (pScrn->modes == NULL) {
-	FatalError("No modes left for XFree86 DDX\n");
-    }
-
-    /* For some reason, pScrn->modes is circular, unlike the other mode lists.
-     * How great is that?
-     */
-    last = RADEONGetModeListTail(pScrn->modes);
-    last->next = pScrn->modes;
-    pScrn->modes->prev = last;
-
-    /* Save a pointer to the previous current mode.  We can't reset
-     * pScrn->currentmode, because we rely on xf86SwitchMode's shortcut not
-     * happening so we can hot-enable devices at SwitchMode.  We'll notice this
-     * case at SwitchMode and free the saved mode.
-     */
-    info->savedCurrentMode = saved_mode;
-}
 
 /**
  * Takes the output mode lists and decides the default root window size
@@ -785,14 +540,3 @@ RADEON_set_default_screen_size(ScrnInfoP
 
 
 
-int RADEONValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
-{
-  
-  if (first_time)
-    {
-      RADEON_set_default_screen_size(pScrn);
-    }
-
-  RADEON_set_xf86_modes_from_outputs(pScrn);
-  return 1;
-}
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index ac1d567..4e21a33 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -43,7 +43,6 @@
 #include "radeon_macros.h"
 #include "radeon_probe.h"
 #include "radeon_version.h"
-#include "radeon_mergedfb.h"
 
 typedef struct _xf86RandR12Info {
     int				    virtualX;
diff --git a/src/radeon_video.c b/src/radeon_video.c
index 6a910a1..f8f29af 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -12,7 +12,6 @@
 #include "radeon_reg.h"
 #include "radeon_macros.h"
 #include "radeon_probe.h"
-#include "radeon_mergedfb.h"
 #include "radeon_video.h"
 
 #include "xf86.h"
@@ -2470,10 +2469,6 @@ RADEONDisplayVideo(
     y_mult = 1;
 
     if (info->MergedFB) {
-        if (info->OverlayOnCRTC2)
-	    overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
-	else
-	    overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT1;
 	if (overlay_mode->Flags & V_INTERLACE)
 	    v_inc_shift++;
     	if (overlay_mode->Flags & V_DBLSCAN) {
@@ -2604,19 +2599,6 @@ RADEONDisplayVideo(
 	x_off = 0;
 
     /* needed to make the overlay work on crtc1 in leftof and above modes */
-    if (info->MergedFB) {
-	RADEONScrn2Rel srel =
-	    ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-	overlay_mode = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2;
-	if (srel == radeonLeftOf) {
-    	    x_off -= overlay_mode->CrtcHDisplay;
-	    /* y_off -= pScrn->frameY0; */
-	}
-	if (srel == radeonAbove) {
-    	    y_off -= overlay_mode->CrtcVDisplay;
-	    /* x_off -= pScrn->frameX0; */
-	}
-    }
 
     /* Put the hardware overlay on CRTC2:
      *
@@ -2767,8 +2749,8 @@ RADEONPutImage(
    dstBox.y1 = drw_y;
    dstBox.y2 = drw_y + drw_h;
 
-   if (info->MergedFB)
-	RADEONChooseOverlayCRTC(pScrn, &dstBox);
+ //  if (info->MergedFB)
+//	RADEONChooseOverlayCRTC(pScrn, &dstBox);
 
    if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb,
 			     clipBoxes, width, height))
@@ -3130,8 +3112,8 @@ RADEONDisplaySurface(
     dstBox.y1 = drw_y;
     dstBox.y2 = drw_y + drw_h;
 
-    if (info->MergedFB)
-        RADEONChooseOverlayCRTC(pScrn, &dstBox);
+    //if (info->MergedFB)
+     //   RADEONChooseOverlayCRTC(pScrn, &dstBox);
 
     if (!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, 
 			       surface->width, surface->height))
@@ -3271,8 +3253,8 @@ RADEONPutVideo(
 	   else
 	   vbi_line_width = 2000; /* might need adjustment */
 
-   if (info->MergedFB)
-        RADEONChooseOverlayCRTC(pScrn, &dstBox);
+   //if (info->MergedFB)
+    //    RADEONChooseOverlayCRTC(pScrn, &dstBox);
         
    if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, width, height))
         return Success;
diff-tree e8be0056e8ff666f63a294691661f5dab289203e (from a648050a3cc60f92b1ca0b3d707aadf93d076d91)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 18 16:41:25 2007 +1100

    remove mergedfb

diff --git a/src/Makefile.am b/src/Makefile.am
index 3851881..0ec7c29 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -79,7 +79,7 @@ radeon_drv_la_LTLIBRARIES = radeon_drv.l
 radeon_drv_la_LDFLAGS = -module -avoid-version
 radeon_drv_ladir = @moduledir@/drivers
 radeon_drv_la_SOURCES = \
-	radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
+	radeon_accel.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
 	radeon_xf86Crtc.c radeon_xf86Modes.c radeon_randr.c \
@@ -187,7 +187,6 @@ EXTRA_DIST = \
 	radeon_exa_funcs.c \
 	radeon.h \
 	radeon_macros.h \
-	radeon_mergedfb.h \
 	radeon_probe.h \
 	radeon_reg.h \
 	radeon_sarea.h \
diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
deleted file mode 100644
index 820ba4b..0000000
--- a/src/radeon_mergedfb.c
+++ /dev/null
@@ -1,2089 +0,0 @@
-/*
- * Copyright 2003 Alex Deucher.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT.  IN NO EVENT SHALL ALEX DEUCHER, OR ANY OTHER 
- * CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/*
- * Authors:
- *   Alex Deucher <agd5f at yahoo.com>
- *   Based, in large part, on the sis driver by Thomas Winischhofer.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Resources.h"
-#include "xf86_OSproc.h"
-#include "extnsionst.h"  	/* required */
-#include <X11/extensions/panoramiXproto.h>  	/* required */
-#include "dixstruct.h"
-#include "vbe.h"
-
-
-#include "radeon.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
-#include "radeon_mergedfb.h"
-
-/* psuedo xinerama support */
-static unsigned char 	RADEONXineramaReqCode = 0;
-int 			RADEONXineramaPixWidth = 0;
-int 			RADEONXineramaPixHeight = 0;
-int 			RADEONXineramaNumScreens = 0;
-RADEONXineramaData	*RADEONXineramadataPtr = NULL;
-static int 		RADEONXineramaGeneration;
-Bool 		RADEONnoPanoramiXExtension = TRUE;
-
-int RADEONProcXineramaQueryVersion(ClientPtr client);
-int RADEONProcXineramaGetState(ClientPtr client);
-int RADEONProcXineramaGetScreenCount(ClientPtr client);
-int RADEONProcXineramaGetScreenSize(ClientPtr client);
-int RADEONProcXineramaIsActive(ClientPtr client);
-int RADEONProcXineramaQueryScreens(ClientPtr client);
-int RADEONSProcXineramaDispatch(ClientPtr client);
-
-static void
-RADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y);
-
-/* mergedfb functions */
-/* Helper function for CRT2 monitor vrefresh/hsync options
- * (Taken from mga, sis drivers)
- */
-int
-RADEONStrToRanges(range *r, char *s, int max)
-{
-   float num = 0.0;
-   int rangenum = 0;
-   Bool gotdash = FALSE;
-   Bool nextdash = FALSE;
-   char* strnum = NULL;
-   do {
-     switch(*s) {
-     case '0':
-     case '1':
-     case '2':
-     case '3':
-     case '4':
-     case '5':
-     case '6':
-     case '7':
-     case '8':
-     case '9':
-     case '.':
-        if(strnum == NULL) {
-           strnum = s;
-           gotdash = nextdash;
-           nextdash = FALSE;
-        }
-        break;
-     case '-':
-     case ' ':
-     case 0:
-        if(strnum == NULL) break;
-	sscanf(strnum, "%f", &num);
-	strnum = NULL;
-        if(gotdash)
-           r[rangenum - 1].hi = num;
-        else {
-           r[rangenum].lo = num;
-           r[rangenum].hi = num;
-           rangenum++;
-        }
-        if(*s == '-') nextdash = (rangenum != 0);
-        else if(rangenum >= max) return rangenum;
-        break;
-     default :
-        return 0;
-     }
-   } while(*(s++) != 0);
-
-   return rangenum;
-}
-
-/* Copy and link two modes (i, j) for merged-fb mode
- * (Taken from mga, sis drivers)
- * Copys mode i, merges j to copy of i, links the result to dest, and returns it.
- * Links i and j in Private record.
- * If dest is NULL, return value is copy of i linked to itself.
- * For mergedfb auto-config, we only check the dimension
- * against virtualX/Y, if they were user-provided.
- */
-static DisplayModePtr
-RADEONCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
-                 DisplayModePtr i, DisplayModePtr j,
-		 RADEONScrn2Rel srel)
-{
-    DisplayModePtr mode;
-    int dx = 0,dy = 0;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    if(!((mode = xalloc(sizeof(DisplayModeRec))))) return dest;
-    memcpy(mode, i, sizeof(DisplayModeRec));
-    if(!((mode->Private = xalloc(sizeof(RADEONMergedDisplayModeRec))))) {
-       xfree(mode);
-       return dest;
-    }
-    ((RADEONMergedDisplayModePtr)mode->Private)->CRT1 = i;
-    ((RADEONMergedDisplayModePtr)mode->Private)->CRT2 = j;
-    ((RADEONMergedDisplayModePtr)mode->Private)->CRT2Position = srel;
-    mode->PrivSize = 0;
-
-    switch(srel) {
-    case radeonLeftOf:
-    case radeonRightOf:
-       if(!(pScrn->display->virtualX)) {
-          dx = i->HDisplay + j->HDisplay;
-       } else {
-          dx = min(pScrn->virtualX, i->HDisplay + j->HDisplay);
-       }
-       dx -= mode->HDisplay;
-       if(!(pScrn->display->virtualY)) {
-          dy = max(i->VDisplay, j->VDisplay);
-       } else {
-          dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
-       }
-       dy -= mode->VDisplay;
-       break;
-    case radeonAbove:
-    case radeonBelow:
-       if(!(pScrn->display->virtualY)) {
-          dy = i->VDisplay + j->VDisplay;
-       } else {
-          dy = min(pScrn->virtualY, i->VDisplay + j->VDisplay);
-       }
-       dy -= mode->VDisplay;
-       if(!(pScrn->display->virtualX)) {
-          dx = max(i->HDisplay, j->HDisplay);
-       } else {
-          dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
-       }
-       dx -= mode->HDisplay;
-       break;
-    case radeonClone:
-       if(!(pScrn->display->virtualX)) {
-          dx = max(i->HDisplay, j->HDisplay);
-       } else {
-          dx = min(pScrn->virtualX, max(i->HDisplay, j->HDisplay));
-       }
-       dx -= mode->HDisplay;
-       if(!(pScrn->display->virtualY)) {
-          dy = max(i->VDisplay, j->VDisplay);
-       } else {
-	  dy = min(pScrn->virtualY, max(i->VDisplay, j->VDisplay));
-       }
-       dy -= mode->VDisplay;
-       break;
-    }
-    mode->HDisplay += dx;
-    mode->HSyncStart += dx;
-    mode->HSyncEnd += dx;
-    mode->HTotal += dx;
-    mode->VDisplay += dy;
-    mode->VSyncStart += dy;
-    mode->VSyncEnd += dy;
-    mode->VTotal += dy;
-
-     /* Provide a fake VRefresh/DotClock in order to trick the vidmode
-      * extension to allow selecting among a number of modes whose merged result
-      * looks identical but consists of different modes for CRT1 and CRT2
-      */
-    mode->VRefresh = (float)((i->Clock * 1000.0 / i->HTotal / i->VTotal) * 100 +
-	(j->Clock * 1000.0 / j->HTotal / j->VTotal));
-
-    mode->Clock = (int)(mode->VRefresh * 0.001 * mode->HTotal * mode->VTotal);
-
-    if( ((mode->HDisplay * ((pScrn->bitsPerPixel + 7) / 8) * mode->VDisplay) > 
-	(pScrn->videoRam * 1024)) ||
-        (mode->HDisplay > 8191) ||
-	(mode->VDisplay > 8191) ) {
-
-       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-	        "Skipped \"%s\" (%dx%d), not enough video RAM or beyond hardware specs\n",
-		mode->name, mode->HDisplay, mode->VDisplay);
-       xfree(mode->Private);
-       xfree(mode);
-
-       return dest;
-    }
-
-    if(srel != radeonClone) {
-       info->AtLeastOneNonClone = TRUE;
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-    	"Merged \"%s\" (%dx%d) and \"%s\" (%dx%d) to %dx%d%s\n",
-	i->name, i->HDisplay, i->VDisplay, j->name, j->HDisplay, j->VDisplay,
-	mode->HDisplay, mode->VDisplay, (srel == radeonClone) ? " (Clone)" : "");
-
-    mode->next = mode;
-    mode->prev = mode;
-
-    if(dest) {
-        mode->next = dest->next; 	/* Insert node after "dest" */
-        dest->next->prev = mode;
-        mode->prev = dest;
-        dest->next = mode;
-    }
-
-    return mode;
-}
-
-/* Helper function to find a mode from a given name
- * (Taken from mga, sis drivers)
- */
-static DisplayModePtr
-RADEONGetModeFromName(char* str, DisplayModePtr i)
-{
-    DisplayModePtr c = i;
-    if(!i) return NULL;
-    do {
-       if(strcmp(str, c->name) == 0) return c;
-       c = c->next;
-    } while(c != i);
-    return NULL;
-}
-
-static DisplayModePtr
-RADEONFindWidestTallestMode(DisplayModePtr i, Bool tallest)
-{
-    DisplayModePtr c = i, d = NULL;
-    int max = 0;
-    if(!i) return NULL;
-    do {
-       if(tallest) {
-          if(c->VDisplay > max) {
-             max = c->VDisplay;
-	     d = c;
-          }
-       } else {
-          if(c->HDisplay > max) {
-             max = c->HDisplay;
-	     d = c;
-          }
-       }
-       c = c->next;
-    } while(c != i);
-    return d;
-}
-
-static void
-RADEONFindWidestTallestCommonMode(DisplayModePtr i, DisplayModePtr j, Bool tallest,
-				DisplayModePtr *a, DisplayModePtr *b)
-{
-    DisplayModePtr c = i, d;
-    int max = 0;
-    Bool foundone;
-
-    (*a) = (*b) = NULL;
-
-    if(!i || !j) return;
-
-    do {
-       d = j;
-       foundone = FALSE;
-       do {
-	  if( (c->HDisplay == d->HDisplay) &&
-	      (c->VDisplay == d->VDisplay) ) {
-	     foundone = TRUE;
-	     break;
-	  }
-	  d = d->next;
-       } while(d != j);
-       if(foundone) {
-	  if(tallest) {
-	     if(c->VDisplay > max) {
-		max = c->VDisplay;
-		(*a) = c;
-		(*b) = d;
-	     }
-	  } else {
-	     if(c->HDisplay > max) {
-		max = c->HDisplay;
-		(*a) = c;
-		(*b) = d;
-	     }
-	  }
-       }
-       c = c->next;
-    } while(c != i);
-}
-
-static DisplayModePtr
-RADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
-		    DisplayModePtr i, DisplayModePtr j,
-		    RADEONScrn2Rel srel)
-{
-
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    DisplayModePtr mode1 = NULL;
-    DisplayModePtr mode2 = NULL;
-    DisplayModePtr mode3 = NULL;
-    DisplayModePtr mode4 = NULL;
-    DisplayModePtr result = NULL;
-
-    info->AtLeastOneNonClone = FALSE;
-
-    /* Now build a default list of MetaModes.
-     * - Non-clone: If the user enabled NonRectangular, we use the
-     * largest mode for each CRT1 and CRT2. If not, we use the largest
-     * common mode for CRT1 and CRT2 (if available). Additionally, and
-     * regardless if the above, we produce a clone mode consisting of
-     * the largest common mode (if available) in order to use DGA.
-     * - Clone: If the (global) CRT2Position is Clone, we use the
-     * largest common mode if available, otherwise the first two modes
-     * in each list.
-     */
-
-    switch(srel) {
-    case radeonLeftOf:
-    case radeonRightOf:
-       mode1 = RADEONFindWidestTallestMode(i, FALSE);
-       mode2 = RADEONFindWidestTallestMode(j, FALSE);
-       RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
-       break;
-    case radeonAbove:
-    case radeonBelow:
-       mode1 = RADEONFindWidestTallestMode(i, TRUE);
-       mode2 = RADEONFindWidestTallestMode(j, TRUE);
-       RADEONFindWidestTallestCommonMode(i, j, TRUE, &mode3, &mode4);
-       break;
-    case radeonClone:
-       RADEONFindWidestTallestCommonMode(i, j, FALSE, &mode3, &mode4);
-       if(mode3 && mode4) {
-	  mode1 = mode3;
-	  mode2 = mode4;
-       } else {
-	  mode1 = i;
-	  mode2 = j;
-       }
-    }
-
-    if(srel != radeonClone) {
-       if(mode3 && mode4 && !info->NonRect) {
-	  mode1 = mode3;
-	  mode2 = mode2;
-       }
-    }
-
-    if(mode1 && mode2) {
-       result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, srel);
-    }
-
-    if(srel != radeonClone) {
-       if(mode3 && mode4) {
-	  result = RADEONCopyModeNLink(pScrn, result, mode3, mode4, radeonClone);
-       }
-    }
-    return result;
-}
-
-/* Generate the merged-fb mode modelist
- * (Taken from mga, sis drivers)
- */
-static DisplayModePtr
-RADEONGenerateModeListFromMetaModes(ScrnInfoPtr pScrn, char* str,
-		    DisplayModePtr i, DisplayModePtr j,
-		    RADEONScrn2Rel srel)
-{
-    char* strmode = str;
-    char modename[256];
-    Bool gotdash = FALSE;
-    char gotsep = 0;
-    RADEONScrn2Rel sr;
-    DisplayModePtr mode1 = NULL;
-    DisplayModePtr mode2 = NULL;
-    DisplayModePtr result = NULL;
-    int myslen;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-
-    info->AtLeastOneNonClone = FALSE;
-
-    do {
-        switch(*str) {
-        case 0:
-        case '-':
-	case '+':
-        case ' ':
-	case ',':
-	case ';':
-           if(strmode != str) {
-
-              myslen = str - strmode;
-              if(myslen > 255) myslen = 255;
-  	      strncpy(modename, strmode, myslen);
-  	      modename[myslen] = 0;
-
-              if(gotdash) {
-                 if(mode1 == NULL) {
-  	             xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-  	                        "Error parsing MetaModes parameter\n");
-  	             return NULL;
-  	         }
-                 mode2 = RADEONGetModeFromName(modename, j);
-                 if(!mode2) {
-                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                        "Mode \"%s\" is not a supported mode for CRT2\n", modename);
-                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                        "\t(Skipping metamode \"%s%c%s\")\n", mode1->name, gotsep, modename);
-                    mode1 = NULL;
-		    gotsep = 0;
-                 }
-              } else {
-                 mode1 = RADEONGetModeFromName(modename, i);
-                 if(!mode1) {
-                    char* tmps = str;
-                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                        "Mode \"%s\" is not a supported mode for CRT1\n", modename);
-                    while(*tmps == ' ' || *tmps == ';') tmps++;
-                    /* skip the next mode */
-  	            if(*tmps == '-' || *tmps == '+' || *tmps == ',') {
-                       tmps++;
-		       /* skip spaces */
-		       while(*tmps == ' ' || *tmps == ';') tmps++;
-		       /* skip modename */
-		       while(*tmps && *tmps != ' ' && *tmps != ';' && *tmps != '-' && *tmps != '+' && *tmps != ',') tmps++;
-  	               myslen = tmps - strmode;
-  	               if(myslen > 255) myslen = 255;
-  	               strncpy(modename,strmode,myslen);
-  	               modename[myslen] = 0;
-                       str = tmps-1;
-                    }
-                    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                        "\t(Skipping metamode \"%s\")\n", modename);
-                    mode1 = NULL;
-		    gotsep = 0;
-                 }
-              }
-              gotdash = FALSE;
-           }
-           strmode = str + 1;
-           gotdash |= (*str == '-' || *str == '+' || *str == ',');
-	   if (*str == '-' || *str == '+' || *str == ',')
-  	      gotsep = *str;
-
-           if(*str != 0) break;
-	   /* Fall through otherwise */
-
-        default:
-           if(!gotdash && mode1) {
-              sr = srel;
-	      if(gotsep == '+') sr = radeonClone;
-              if(!mode2) {
-                 mode2 = RADEONGetModeFromName(mode1->name, j);
-                 sr = radeonClone;
-              }
-              if(!mode2) {
-                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                     "Mode \"%s\" is not a supported mode for CRT2\n", mode1->name);
-                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                     "\t(Skipping metamode \"%s\")\n", modename);
-                 mode1 = NULL;
-              } else {
-                 result = RADEONCopyModeNLink(pScrn, result, mode1, mode2, sr);
-                 mode1 = NULL;
-                 mode2 = NULL;
-              }
-	      gotsep = 0;
-           }
-           break;
-
-        }
-
-    } while(*(str++) != 0);
-     
-    return result;
-}
-
-DisplayModePtr
-RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
-		    DisplayModePtr i, DisplayModePtr j,
-		    RADEONScrn2Rel srel)
-{
-    RADEONInfoPtr  info   = RADEONPTR(pScrn);
-
-   if(str != NULL) {
-      return(RADEONGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
-   } else {
-        if (srel == radeonClone ) {
-           DisplayModePtr p, q, result = NULL;
-
-           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                "Clone mode, list all common modes\n");
-           for (p = i; p->next != i; p = p->next)
-                for (q = j; q->next != j; q = q->next)
-                   if ((p->HDisplay == q->HDisplay) &&
-                        (p->VDisplay == q->VDisplay))
-                        result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
-           return result;
-        } else {
-           xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                "No MetaModes given, linking %s modes by default\n",
-                (info->NonRect ?
-		(((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest" :  "tallest")
-		:
-		(((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest common" :  "tallest common")) );
-           return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel));
-        }
-    }
-}
-
-void
-RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr  info   = RADEONPTR(pScrn);
-    DisplayModePtr mode, bmode;
-    int maxh, maxv;
-    static const char *str = "MergedFB: Virtual %s %d\n";
-    static const char *errstr = "Virtual %s to small for given CRT2Position offset\n";
-
-    mode = bmode = pScrn->modes;
-    maxh = maxv = 0;
-    do {
-        if(mode->HDisplay > maxh) maxh = mode->HDisplay;
-	if(mode->VDisplay > maxv) maxv = mode->VDisplay;
-        mode = mode->next;
-    } while(mode != bmode);
-    maxh += info->CRT1XOffs + info->CRT2XOffs;
-    maxv += info->CRT1YOffs + info->CRT2YOffs;
-
-    if(!(pScrn->display->virtualX)) {
-	if(maxh > 8191) {
-  	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-  	               "Virtual width with CRT2Position offset beyond hardware specs\n");
-  	               info->CRT1XOffs = info->CRT2XOffs = 0;
-  	               maxh -= (info->CRT1XOffs + info->CRT2XOffs);
-  	}
-  	pScrn->virtualX = maxh;
-  	pScrn->displayWidth = maxh;
-  	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
-    } else {
-  	if(maxh < pScrn->display->virtualX) {
-  	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "width");
-  	    info->CRT1XOffs = info->CRT2XOffs = 0;
-	}
-    }
-
-    if(!(pScrn->display->virtualY)) {
-        pScrn->virtualY = maxv;
-	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
-    } else {
-	if(maxv < pScrn->display->virtualY) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, errstr, "height");
-	    info->CRT1YOffs = info->CRT2YOffs = 0;
-	}
-    }
-}
-
-/* Pseudo-Xinerama extension for MergedFB mode */
-void
-RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1)
-{
-    RADEONInfoPtr  info   = RADEONPTR(pScrn1);
-    ScrnInfoPtr pScrn2 = NULL;
-    int crt1scrnnum = 0, crt2scrnnum = 1;
-    int x1=0, x2=0, y1=0, y2=0, h1=0, h2=0, w1=0, w2=0;
-    int realvirtX, realvirtY;
-    DisplayModePtr currentMode, firstMode;
-    Bool infochanged = FALSE;
-    Bool usenonrect = info->NonRect;
-    const char *rectxine = "\t... setting up rectangular Xinerama layout\n";
-
-    info->MBXNR1XMAX = info->MBXNR1YMAX = info->MBXNR2XMAX = info->MBXNR2YMAX = 65536;
-    info->HaveNonRect = info->HaveOffsRegions = FALSE;
-
-    if(!info->MergedFB) return;
-
-    if(RADEONnoPanoramiXExtension) return;
-
-    if(!RADEONXineramadataPtr) return;
-
-    if(info->CRT2IsScrn0) {
-       crt1scrnnum = 1;
-       crt2scrnnum = 0;
-    }
-
-    pScrn2 = info->CRT2pScrn;
-
-    /* Attention: Usage of RandR may lead into virtual X and Y values
-     * actually smaller than our MetaModes! To avoid this, we calculate
-     * the maxCRT fields here (and not somewhere else, like in CopyNLink)
-     */
-
-     /* "Real" virtual: Virtual without the Offset */
-    realvirtX = pScrn1->virtualX - info->CRT1XOffs - info->CRT2XOffs;
-    realvirtY = pScrn1->virtualY - info->CRT1YOffs - info->CRT2YOffs;
-
-    if((info->RADEONXineramaVX != pScrn1->virtualX) || (info->RADEONXineramaVY != pScrn1->virtualY)) {
-
-      if(!(pScrn1->modes)) {
-          xf86DrvMsg(pScrn1->scrnIndex, X_ERROR,
-       	     "Internal error: RADEONUpdateXineramaScreenInfo(): pScrn->modes is NULL\n");
-	  return;
-       }
-
-       info->maxCRT1_X1 = info->maxCRT1_X2 = 0;
-       info->maxCRT1_Y1 = info->maxCRT1_Y2 = 0;
-       info->maxCRT2_X1 = info->maxCRT2_X2 = 0;
-       info->maxCRT2_Y1 = info->maxCRT2_Y2 = 0;
-       info->maxClone_X1 = info->maxClone_X2 = 0;
-       info->maxClone_Y1 = info->maxClone_Y2 = 0;
-
-       currentMode = firstMode = pScrn1->modes;
-
-       do {
-
-          DisplayModePtr p = currentMode->next;
-          DisplayModePtr i = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT1;
-          DisplayModePtr j = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2;
-          RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)currentMode->Private)->CRT2Position;
-
-          if((currentMode->HDisplay <= realvirtX) && (currentMode->VDisplay <= realvirtY) &&
-	     (i->HDisplay <= realvirtX) && (j->HDisplay <= realvirtX) &&
-	     (i->VDisplay <= realvirtY) && (j->VDisplay <= realvirtY)) {
-
-	     if(srel != radeonClone) {
-		if(info->maxCRT1_X1 == i->HDisplay) {
-		   if(info->maxCRT1_X2 < j->HDisplay) {
-		      info->maxCRT1_X2 = j->HDisplay;   /* Widest CRT2 mode displayed with widest CRT1 mode */
-		   }
-		} else if(info->maxCRT1_X1 < i->HDisplay) {
-		   info->maxCRT1_X1 = i->HDisplay;      /* Widest CRT1 mode */
-		   info->maxCRT1_X2 = j->HDisplay;
-		}
-		if(info->maxCRT2_X2 == j->HDisplay) {
-		   if(info->maxCRT2_X1 < i->HDisplay) {
-		      info->maxCRT2_X1 = i->HDisplay;   /* Widest CRT1 mode displayed with widest CRT2 mode */
-		   }
-		} else if(info->maxCRT2_X2 < j->HDisplay) {
-		   info->maxCRT2_X2 = j->HDisplay;      /* Widest CRT2 mode */
-		   info->maxCRT2_X1 = i->HDisplay;
-		}
-		if(info->maxCRT1_Y1 == i->VDisplay) {   /* Same as above, but tallest instead of widest */
-		   if(info->maxCRT1_Y2 < j->VDisplay) {
-		      info->maxCRT1_Y2 = j->VDisplay;
-		   }
-		} else if(info->maxCRT1_Y1 < i->VDisplay) {
-		   info->maxCRT1_Y1 = i->VDisplay;
-		   info->maxCRT1_Y2 = j->VDisplay;
-		}
-		if(info->maxCRT2_Y2 == j->VDisplay) {
-		   if(info->maxCRT2_Y1 < i->VDisplay) {
-		      info->maxCRT2_Y1 = i->VDisplay;
-		   }
-		} else if(info->maxCRT2_Y2 < j->VDisplay) {
-		   info->maxCRT2_Y2 = j->VDisplay;
-		   info->maxCRT2_Y1 = i->VDisplay;
-		}
-	     } else {
-		if(info->maxClone_X1 < i->HDisplay) {
-		   info->maxClone_X1 = i->HDisplay;
-		}
-		if(info->maxClone_X2 < j->HDisplay) {
-		   info->maxClone_X2 = j->HDisplay;
-		}
-		if(info->maxClone_Y1 < i->VDisplay) {
-		   info->maxClone_Y1 = i->VDisplay;
-		}
-		if(info->maxClone_Y2 < j->VDisplay) {
-		   info->maxClone_Y2 = j->VDisplay;
-		}
-	     }
-	  }
-	  currentMode = p;
-
-       } while((currentMode) && (currentMode != firstMode));
-
-       info->RADEONXineramaVX = pScrn1->virtualX;
-       info->RADEONXineramaVY = pScrn1->virtualY;
-       infochanged = TRUE;
-
-    }
-
-    if((usenonrect) && (info->CRT2Position != radeonClone) && info->maxCRT1_X1) {
-     switch(info->CRT2Position) {
-       case radeonLeftOf:
-       case radeonRightOf:
-	  if((info->maxCRT1_Y1 != realvirtY) && (info->maxCRT2_Y2 != realvirtY)) {
-	     usenonrect = FALSE;
-	  }
-	  break;
-       case radeonAbove:
-       case radeonBelow:
-	  if((info->maxCRT1_X1 != realvirtX) && (info->maxCRT2_X2 != realvirtX)) {
-	     usenonrect = FALSE;
-	  }
-	  break;
-       case radeonClone:
-	  break;
-       }
-
-       if(infochanged && !usenonrect) {
-	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-			"Virtual screen size does not match maximum display modes...\n");
-	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
-
-       }
-    } else if(infochanged && usenonrect) {
-       usenonrect = FALSE;
-       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-		"Only clone modes available for this virtual screen size...\n");
-       xf86DrvMsg(pScrn1->scrnIndex, X_INFO, rectxine);
-    }
-
-    if(info->maxCRT1_X1) {		/* Means we have at least one non-clone mode */
-       switch(info->CRT2Position) {
-       case radeonLeftOf:
-	  x1 = min(info->maxCRT1_X2, pScrn1->virtualX - info->maxCRT1_X1);
-	  if(x1 < 0) x1 = 0;
-	  y1 = info->CRT1YOffs;
-	  w1 = pScrn1->virtualX - x1;
-	  h1 = realvirtY;
-	  if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) {
-	     h1 = info->MBXNR1YMAX = info->maxCRT1_Y1;
-	     info->NonRectDead.x0 = x1;
-	     info->NonRectDead.x1 = x1 + w1 - 1;
-	     info->NonRectDead.y0 = y1 + h1;
-	     info->NonRectDead.y1 = pScrn1->virtualY - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  x2 = 0;
-	  y2 = info->CRT2YOffs;
-	  w2 = max(info->maxCRT2_X2, pScrn1->virtualX - info->maxCRT2_X1);
-	  if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX;
-	  h2 = realvirtY;
-	  if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) {
-	     h2 = info->MBXNR2YMAX = info->maxCRT2_Y2;
-	     info->NonRectDead.x0 = x2;
-	     info->NonRectDead.x1 = x2 + w2 - 1;
-	     info->NonRectDead.y0 = y2 + h2;
-	     info->NonRectDead.y1 = pScrn1->virtualY - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  break;
-       case radeonRightOf:
-	  x1 = 0;
-	  y1 = info->CRT1YOffs;
-	  w1 = max(info->maxCRT1_X1, pScrn1->virtualX - info->maxCRT1_X2);
-	  if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX;
-	  h1 = realvirtY;
-	  if((usenonrect) && (info->maxCRT1_Y1 != realvirtY)) {
-	     h1 = info->MBXNR1YMAX = info->maxCRT1_Y1;
-	     info->NonRectDead.x0 = x1;
-	     info->NonRectDead.x1 = x1 + w1 - 1;
-	     info->NonRectDead.y0 = y1 + h1;
-	     info->NonRectDead.y1 = pScrn1->virtualY - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  x2 = min(info->maxCRT2_X1, pScrn1->virtualX - info->maxCRT2_X2);
-	  if(x2 < 0) x2 = 0;
-	  y2 = info->CRT2YOffs;
-	  w2 = pScrn1->virtualX - x2;
-	  h2 = realvirtY;
-	  if((usenonrect) && (info->maxCRT2_Y2 != realvirtY)) {
-	     h2 = info->MBXNR2YMAX = info->maxCRT2_Y2;
-	     info->NonRectDead.x0 = x2;
-	     info->NonRectDead.x1 = x2 + w2 - 1;
-	     info->NonRectDead.y0 = y2 + h2;
-	     info->NonRectDead.y1 = pScrn1->virtualY - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  break;
-       case radeonAbove:
-	  x1 = info->CRT1XOffs;
-	  y1 = min(info->maxCRT1_Y2, pScrn1->virtualY - info->maxCRT1_Y1);
-	  if(y1 < 0) y1 = 0;
-	  w1 = realvirtX;
-	  h1 = pScrn1->virtualY - y1;
-	  if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
-	     w1 = info->MBXNR1XMAX = info->maxCRT1_X1;
-	     info->NonRectDead.x0 = x1 + w1;
-	     info->NonRectDead.x1 = pScrn1->virtualX - 1;
-	     info->NonRectDead.y0 = y1;
-	     info->NonRectDead.y1 = y1 + h1 - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  x2 = info->CRT2XOffs;
-	  y2 = 0;
-	  w2 = realvirtX;
-	  h2 = max(info->maxCRT2_Y2, pScrn1->virtualY - info->maxCRT2_Y1);
-	  if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY;
-	  if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) {
-	     w2 = info->MBXNR2XMAX = info->maxCRT2_X2;
-	     info->NonRectDead.x0 = x2 + w2;
-	     info->NonRectDead.x1 = pScrn1->virtualX - 1;
-	     info->NonRectDead.y0 = y2;
-	     info->NonRectDead.y1 = y2 + h2 - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  break;
-       case radeonBelow:
-	  x1 = info->CRT1XOffs;
-	  y1 = 0;
-	  w1 = realvirtX;
-	  h1 = max(info->maxCRT1_Y1, pScrn1->virtualY - info->maxCRT1_Y2);
-	  if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY;
-	  if((usenonrect) && (info->maxCRT1_X1 != realvirtX)) {
-	     w1 = info->MBXNR1XMAX = info->maxCRT1_X1;
-	     info->NonRectDead.x0 = x1 + w1;
-	     info->NonRectDead.x1 = pScrn1->virtualX - 1;
-	     info->NonRectDead.y0 = y1;
-	     info->NonRectDead.y1 = y1 + h1 - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-	  x2 = info->CRT2XOffs;
-	  y2 = min(info->maxCRT2_Y1, pScrn1->virtualY - info->maxCRT2_Y2);
-	  if(y2 < 0) y2 = 0;
-	  w2 = realvirtX;
-	  h2 = pScrn1->virtualY - y2;
-	  if((usenonrect) && (info->maxCRT2_X2 != realvirtX)) {
-	     w2 = info->MBXNR2XMAX = info->maxCRT2_X2;
-	     info->NonRectDead.x0 = x2 + w2;
-	     info->NonRectDead.x1 = pScrn1->virtualX - 1;
-	     info->NonRectDead.y0 = y2;
-	     info->NonRectDead.y1 = y2 + h2 - 1;
-	     info->HaveNonRect = TRUE;
-	  }
-       default:
-	  break;
-       }
-
-       switch(info->CRT2Position) {
-       case radeonLeftOf:
-       case radeonRightOf:
-	  if(info->CRT1YOffs) {
-	     info->OffDead1.x0 = x1;
-	     info->OffDead1.x1 = x1 + w1 - 1;
-	     info->OffDead1.y0 = 0;
-	     info->OffDead1.y1 = y1 - 1;
-	     info->OffDead2.x0 = x2;
-	     info->OffDead2.x1 = x2 + w2 - 1;
-	     info->OffDead2.y0 = y2 + h2;
-	     info->OffDead2.y1 = pScrn1->virtualY - 1;
-	     info->HaveOffsRegions = TRUE;
-	  } else if(info->CRT2YOffs) {
-	     info->OffDead1.x0 = x2;
-	     info->OffDead1.x1 = x2 + w2 - 1;
-	     info->OffDead1.y0 = 0;
-	     info->OffDead1.y1 = y2 - 1;
-	     info->OffDead2.x0 = x1;
-	     info->OffDead2.x1 = x1 + w1 - 1;
-	     info->OffDead2.y0 = y1 + h1;
-	     info->OffDead2.y1 = pScrn1->virtualY - 1;
-	     info->HaveOffsRegions = TRUE;
-	  }
-	  break;
-       case radeonAbove:
-       case radeonBelow:
-	  if(info->CRT1XOffs) {
-	     info->OffDead1.x0 = x2 + w2;
-	     info->OffDead1.x1 = pScrn1->virtualX - 1;
-	     info->OffDead1.y0 = y2;
-	     info->OffDead1.y1 = y2 + h2 - 1;
-	     info->OffDead2.x0 = 0;
-	     info->OffDead2.x1 = x1 - 1;
-	     info->OffDead2.y0 = y1;
-	     info->OffDead2.y1 = y1 + h1 - 1;
-	     info->HaveOffsRegions = TRUE;
-	  } else if(info->CRT2XOffs) {
-	     info->OffDead1.x0 = x1 + w1;
-	     info->OffDead1.x1 = pScrn1->virtualX - 1;
-	     info->OffDead1.y0 = y1;
-	     info->OffDead1.y1 = y1 + h1 - 1;
-	     info->OffDead2.x0 = 0;
-	     info->OffDead2.x1 = x2 - 1;
-	     info->OffDead2.y0 = y2;
-	     info->OffDead2.y1 = y2 + h2 - 1;
-	     info->HaveOffsRegions = TRUE;
-	  }
-       default:
-	  break;
-       }
-
-    } else {	/* Only clone-modes left */
-
-       x1 = x2 = 0;
-       y1 = y2 = 0;
-       w1 = w2 = max(info->maxClone_X1, info->maxClone_X2);
-       h1 = h2 = max(info->maxClone_Y1, info->maxClone_Y2);
-
-    }
-
-    RADEONXineramadataPtr[crt1scrnnum].x = x1;
-    RADEONXineramadataPtr[crt1scrnnum].y = y1;
-    RADEONXineramadataPtr[crt1scrnnum].width = w1;
-    RADEONXineramadataPtr[crt1scrnnum].height = h1;
-    RADEONXineramadataPtr[crt2scrnnum].x = x2;
-    RADEONXineramadataPtr[crt2scrnnum].y = y2;
-    RADEONXineramadataPtr[crt2scrnnum].width = w2;
-    RADEONXineramadataPtr[crt2scrnnum].height = h2;
-
-    if(infochanged) {
-       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-	  "Pseudo-Xinerama: CRT1 (Screen %d) (%d,%d)-(%d,%d)\n",
-	  crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1);
-       xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-	  "Pseudo-Xinerama: CRT2 (Screen %d) (%d,%d)-(%d,%d)\n",
-	  crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1);
-       if(info->HaveNonRect) {
-	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-		"Pseudo-Xinerama: Inaccessible area (%d,%d)-(%d,%d)\n",
-		info->NonRectDead.x0, info->NonRectDead.y0,
-		info->NonRectDead.x1, info->NonRectDead.y1);
-       }
-       if(info->HaveOffsRegions) {
-	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-		"Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
-		info->OffDead1.x0, info->OffDead1.y0,
-		info->OffDead1.x1, info->OffDead1.y1);
-	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-		"Pseudo-Xinerama: Inaccessible offset area (%d,%d)-(%d,%d)\n",
-		info->OffDead2.x0, info->OffDead2.y0,
-		info->OffDead2.x1, info->OffDead2.y1);
-       }
-       if(info->HaveNonRect || info->HaveOffsRegions) {
-	  xf86DrvMsg(pScrn1->scrnIndex, X_INFO,
-		"Mouse restriction for inaccessible areas is %s\n",
-		info->MouseRestrictions ? "enabled" : "disabled");
-       }
-    }
-}
-/* Proc */
-
-int
-RADEONProcXineramaQueryVersion(ClientPtr client)
-{
-    xPanoramiXQueryVersionReply	  rep;
-    register int		  n;
-
-    REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.majorVersion = RADEON_XINERAMA_MAJOR_VERSION;
-    rep.minorVersion = RADEON_XINERAMA_MINOR_VERSION;
-    if(client->swapped) {
-        swaps(&rep.sequenceNumber, n);
-        swapl(&rep.length, n);
-        swaps(&rep.majorVersion, n);
-        swaps(&rep.minorVersion, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep);
-    return (client->noClientException);
-}
-
-int
-RADEONProcXineramaGetState(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetStateReq);
-    WindowPtr			pWin;
-    xPanoramiXGetStateReply	rep;
-    register int		n;
-
-    REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
-    pWin = LookupWindow(stuff->window, client);
-    if(!pWin) return BadWindow;
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.state = !RADEONnoPanoramiXExtension;
-    if(client->swapped) {
-       swaps (&rep.sequenceNumber, n);
-       swapl (&rep.length, n);
-       swaps (&rep.state, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep);
-    return client->noClientException;
-}
-
-int
-RADEONProcXineramaGetScreenCount(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetScreenCountReq);
-    WindowPtr				pWin;
-    xPanoramiXGetScreenCountReply	rep;
-    register int			n;
-
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
-    pWin = LookupWindow(stuff->window, client);
-    if(!pWin) return BadWindow;
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.ScreenCount = RADEONXineramaNumScreens;
-    if(client->swapped) {
-       swaps(&rep.sequenceNumber, n);
-       swapl(&rep.length, n);
-       swaps(&rep.ScreenCount, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
-    return client->noClientException;
-}
-
-int
-RADEONProcXineramaGetScreenSize(ClientPtr client)
-{
-    REQUEST(xPanoramiXGetScreenSizeReq);
-    WindowPtr				pWin;
-    xPanoramiXGetScreenSizeReply	rep;
-    register int			n;
-
-    REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
-    pWin = LookupWindow (stuff->window, client);
-    if(!pWin)  return BadWindow;
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.width  = RADEONXineramadataPtr[stuff->screen].width;
-    rep.height = RADEONXineramadataPtr[stuff->screen].height;
-    if(client->swapped) {
-       swaps(&rep.sequenceNumber, n);
-       swapl(&rep.length, n);
-       swaps(&rep.width, n);
-       swaps(&rep.height, n);
-    }
-    WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
-    return client->noClientException;
-}
-
-int
-RADEONProcXineramaIsActive(ClientPtr client)
-{
-    xXineramaIsActiveReply	rep;
-
-    REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.state = !RADEONnoPanoramiXExtension;
-    if(client->swapped) {
-	register int n;
-	swaps(&rep.sequenceNumber, n);
-	swapl(&rep.length, n);
-	swapl(&rep.state, n);
-    }
-    WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
-    return client->noClientException;
-}
-
-int
-RADEONProcXineramaQueryScreens(ClientPtr client)
-{
-    xXineramaQueryScreensReply	rep;
-
-    REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.number = (RADEONnoPanoramiXExtension) ? 0 : RADEONXineramaNumScreens;
-    rep.length = rep.number * sz_XineramaScreenInfo >> 2;
-    if(client->swapped) {
-       register int n;
-       swaps(&rep.sequenceNumber, n);
-       swapl(&rep.length, n);
-       swapl(&rep.number, n);
-    }
-    WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep);
-
-    if(!RADEONnoPanoramiXExtension) {
-       xXineramaScreenInfo scratch;
-       int i;
-
-       for(i = 0; i < RADEONXineramaNumScreens; i++) {
-	  scratch.x_org  = RADEONXineramadataPtr[i].x;
-	  scratch.y_org  = RADEONXineramadataPtr[i].y;
-	  scratch.width  = RADEONXineramadataPtr[i].width;
-	  scratch.height = RADEONXineramadataPtr[i].height;
-	  if(client->swapped) {
-	     register int n;
-	     swaps(&scratch.x_org, n);
-	     swaps(&scratch.y_org, n);
-	     swaps(&scratch.width, n);
-    	     swaps(&scratch.height, n);
-	  }
-	  WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch);
-       }
-    }
-
-    return client->noClientException;
-}
-
-static int
-RADEONProcXineramaDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data)
-    {
-	case X_PanoramiXQueryVersion:
-	     return RADEONProcXineramaQueryVersion(client);
-	case X_PanoramiXGetState:
-	     return RADEONProcXineramaGetState(client);
-	case X_PanoramiXGetScreenCount:
-	     return RADEONProcXineramaGetScreenCount(client);
-	case X_PanoramiXGetScreenSize:
-	     return RADEONProcXineramaGetScreenSize(client);
-	case X_XineramaIsActive:
-	     return RADEONProcXineramaIsActive(client);
-	case X_XineramaQueryScreens:
-	     return RADEONProcXineramaQueryScreens(client);
-    }
-    return BadRequest;
-}
-
-/* SProc */
-
-static int
-RADEONSProcXineramaQueryVersion (ClientPtr client)
-{
-	REQUEST(xPanoramiXQueryVersionReq);
-	register int n;
-	swaps(&stuff->length,n);
-	REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
-	return RADEONProcXineramaQueryVersion(client);
-}
-
-static int
-RADEONSProcXineramaGetState(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetStateReq);
-	register int n;
- 	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
-	return RADEONProcXineramaGetState(client);
-}
-
-static int
-RADEONSProcXineramaGetScreenCount(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetScreenCountReq);
-	register int n;
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
-	return RADEONProcXineramaGetScreenCount(client);
-}
-
-static int
-RADEONSProcXineramaGetScreenSize(ClientPtr client)
-{
-	REQUEST(xPanoramiXGetScreenSizeReq);
-	register int n;
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
-	return RADEONProcXineramaGetScreenSize(client);
-}
-
-static int
-RADEONSProcXineramaIsActive(ClientPtr client)
-{
-	REQUEST(xXineramaIsActiveReq);
-	register int n;
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-	return RADEONProcXineramaIsActive(client);
-}
-
-static int
-RADEONSProcXineramaQueryScreens(ClientPtr client)
-{
-	REQUEST(xXineramaQueryScreensReq);
-	register int n;
-	swaps (&stuff->length, n);
-	REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-	return RADEONProcXineramaQueryScreens(client);
-}
-
-int
-RADEONSProcXineramaDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-    switch (stuff->data) {
-	case X_PanoramiXQueryVersion:
-	     return RADEONSProcXineramaQueryVersion(client);
-	case X_PanoramiXGetState:
-	     return RADEONSProcXineramaGetState(client);
-	case X_PanoramiXGetScreenCount:
-	     return RADEONSProcXineramaGetScreenCount(client);
-	case X_PanoramiXGetScreenSize:
-	     return RADEONSProcXineramaGetScreenSize(client);
-	case X_XineramaIsActive:
-	     return RADEONSProcXineramaIsActive(client);
-	case X_XineramaQueryScreens:
-	     return RADEONSProcXineramaQueryScreens(client);
-    }
-    return BadRequest;
-}
-
-static void
-RADEONXineramaResetProc(ExtensionEntry* extEntry)
-{
-    if(RADEONXineramadataPtr) {
-       Xfree(RADEONXineramadataPtr);
-       RADEONXineramadataPtr = NULL;
-    }
-}
-
-void
-RADEONXineramaExtensionInit(ScrnInfoPtr pScrn)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    Bool	success = FALSE;
-
-    if(!(RADEONXineramadataPtr)) {
-
-       if(!info->MergedFB) {
-          RADEONnoPanoramiXExtension = TRUE;
-	  info->MouseRestrictions = FALSE;
-          return;
-       }
-
-#ifdef PANORAMIX
-       if(!noPanoramiXExtension) {
-          xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-       	     "Xinerama active, not initializing Radeon Pseudo-Xinerama\n");
-          RADEONnoPanoramiXExtension = TRUE;
-	  info->MouseRestrictions = FALSE;
-          return;
-       }
-#endif
-
-       if(RADEONnoPanoramiXExtension) {
-          xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-       	      "Radeon Pseudo-Xinerama disabled\n");
-	  info->MouseRestrictions = FALSE;
-          return;
-       }
-
-       if(info->CRT2Position == radeonClone) {
-          xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-       	     "Running MergedFB in Clone mode, Radeon Pseudo-Xinerama disabled\n");
-          RADEONnoPanoramiXExtension = TRUE;
-	  info->MouseRestrictions = FALSE;
-          return;
-       }
-
-       if(!(info->AtLeastOneNonClone)) {
-          xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-       	     "Only Clone modes defined, Radeon Pseudo-Xinerama disabled\n");
-          RADEONnoPanoramiXExtension = TRUE;
-	  info->MouseRestrictions = FALSE;
-          return;
-       }
-
-       RADEONXineramaNumScreens = 2;
-
-       while(RADEONXineramaGeneration != serverGeneration) {
-
-	  info->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
-					RADEONProcXineramaDispatch,
-					RADEONSProcXineramaDispatch,
-					RADEONXineramaResetProc,
-					StandardMinorOpcode);
-
-	  if(!info->XineramaExtEntry) break;
-
-	  RADEONXineramaReqCode = (unsigned char)info->XineramaExtEntry->base;
-
-	  if(!(RADEONXineramadataPtr = (RADEONXineramaData *)
-	        xcalloc(RADEONXineramaNumScreens, sizeof(RADEONXineramaData)))) break;
-
-	  RADEONXineramaGeneration = serverGeneration;
-	  success = TRUE;
-       }
-
-       if(!success) {
-          xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-	    	"Failed to initialize Radeon Pseudo-Xinerama extension\n");
-          RADEONnoPanoramiXExtension = TRUE;
-	  info->MouseRestrictions = FALSE;
-          return;
-       }
-
-       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-    	  "Initialized Radeon Pseudo-Xinerama extension\n");
-
-       info->RADEONXineramaVX = 0;
-       info->RADEONXineramaVY = 0;
-
-    }
-
-    RADEONUpdateXineramaScreenInfo(pScrn);
-
-}
-/* End of PseudoXinerama */
-
-static Bool
-InRegion(int x, int y, region r)
-{
-    return (r.x0 <= x) && (x <= r.x1) && (r.y0 <= y) && (y <= r.y1);
-}
-
-void
-RADEONMergePointerMoved(int scrnIndex, int x, int y)
-{
-  ScrnInfoPtr   pScrn1 = xf86Screens[scrnIndex];
-  RADEONInfoPtr info = RADEONPTR(pScrn1);
-  ScrnInfoPtr   pScrn2 = info->CRT2pScrn;
-  region 	out, in1, in2, f2, f1;
-  int 		deltax, deltay;
-  int           temp1, temp2;
-  int           old1x0, old1y0, old2x0, old2y0;
-  int		CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0;
-  int		HVirt = pScrn1->virtualX;
-  int		VVirt = pScrn1->virtualY;
-  int		sigstate;
-  Bool		doit = FALSE, HaveNonRect = FALSE, HaveOffsRegions = FALSE;
-  RADEONScrn2Rel   srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-
-  if(info->DGAactive) {
-     return;
-     /* DGA: There is no cursor and no panning while DGA is active. */
-     /* If it were, we would need to do: */
-     /* HVirt = info->CurrentLayout.displayWidth;
-        VVirt = info->CurrentLayout.displayHeight;
-        BOUND(x, info->CurrentLayout.DGAViewportX, HVirt);
-        BOUND(y, info->CurrentLayout.DGAViewportY, VVirt); */
-  } else {
-     CRT1XOffs = info->CRT1XOffs;
-     CRT1YOffs = info->CRT1YOffs;
-     CRT2XOffs = info->CRT2XOffs;
-     CRT2YOffs = info->CRT2YOffs;
-     HaveNonRect = info->HaveNonRect;
-     HaveOffsRegions = info->HaveOffsRegions;
-  }
-
-  /* Check if the pointer is inside our dead areas */
-  if((info->MouseRestrictions) && (srel != radeonClone) && !RADEONnoPanoramiXExtension) {
-     if(HaveNonRect) {
-	if(InRegion(x, y, info->NonRectDead)) {
-	   switch(srel) {
-	   case radeonLeftOf:
-	   case radeonRightOf: y = info->NonRectDead.y0 - 1;
-			    doit = TRUE;
-			    break;
-	   case radeonAbove:
-	   case radeonBelow:   x = info->NonRectDead.x0 - 1;
-			    doit = TRUE;
-	   default:	    break;
-	   }
-	}
-     }
-     if(HaveOffsRegions) {
-	if(InRegion(x, y, info->OffDead1)) {
-	   switch(srel) {
-	   case radeonLeftOf:
-	   case radeonRightOf: y = info->OffDead1.y1;
-			    doit = TRUE;
-			    break;
-	   case radeonAbove:
-	   case radeonBelow:   x = info->OffDead1.x1;
-			    doit = TRUE;
-	   default:	    break;
-	   }
-	} else if(InRegion(x, y, info->OffDead2)) {
-	   switch(srel) {
-	   case radeonLeftOf:
-	   case radeonRightOf: y = info->OffDead2.y0 - 1;
-			    doit = TRUE;
-			    break;
-	   case radeonAbove:
-	   case radeonBelow:   x = info->OffDead2.x0 - 1;
-			    doit = TRUE;
-	   default:	    break;
-	   }
-	}
-     }
-     if(doit) {
-	UpdateCurrentTime();
-	sigstate = xf86BlockSIGIO();
-	miPointerAbsoluteCursor(x, y, currentTime.milliseconds);
-	xf86UnblockSIGIO(sigstate);
-	return;
-     }
-  }
-
-  f1.x0 = old1x0 = info->CRT1frameX0;
-  f1.x1 = info->CRT1frameX1;
-  f1.y0 = old1y0 = info->CRT1frameY0;
-  f1.y1 = info->CRT1frameY1;
-  f2.x0 = old2x0 = pScrn2->frameX0;
-  f2.x1 = pScrn2->frameX1;
-  f2.y0 = old2y0 = pScrn2->frameY0;
-  f2.y1 = pScrn2->frameY1;
-
-  /* Define the outer region. Crossing this causes all frames to move */
-  out.x0 = pScrn1->frameX0;
-  out.x1 = pScrn1->frameX1;
-  out.y0 = pScrn1->frameY0;
-  out.y1 = pScrn1->frameY1;
-
-  /*
-   * Define the inner sliding window. Being outsize both frames but
-   * inside the outer clipping window will slide corresponding frame
-   */
-  in1 = out;
-  in2 = out;
-  switch(srel) {
-     case radeonLeftOf:
-        in1.x0 = f1.x0;
-        in2.x1 = f2.x1;
-        break;
-     case radeonRightOf:
-        in1.x1 = f1.x1;
-        in2.x0 = f2.x0;
-        break;
-     case radeonBelow:
-        in1.y1 = f1.y1;
-        in2.y0 = f2.y0;
-        break;
-     case radeonAbove:
-        in1.y0 = f1.y0;
-        in2.y1 = f2.y1;
-        break;
-     case radeonClone:
-        break;
-  }
-
-  deltay = 0;
-  deltax = 0;
-
-  if(InRegion(x, y, out)) {	/* inside outer region */
-
-     /* xf86DrvMsg(0, X_INFO, "1: %d %d | %d %d %d %d | %d %d %d %d\n",
-     	x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); */
-
-     if(InRegion(x, y, in1) && !InRegion(x, y, f1)) {
-        REBOUND(f1.x0, f1.x1, x);
-        REBOUND(f1.y0, f1.y1, y);
-        deltax = 1;
-	/* xf86DrvMsg(0, X_INFO, "2: %d %d | %d %d %d %d | %d %d %d %d\n",
-     		x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1); */
-     }
-     if(InRegion(x, y, in2) && !InRegion(x, y, f2)) {
-        REBOUND(f2.x0, f2.x1, x);
-        REBOUND(f2.y0, f2.y1, y);
-        deltax = 1;
-     }
-
-  } else {			/* outside outer region */
-
-     /* xf86DrvMsg(0, X_INFO, "3: %d %d | %d %d %d %d | %d %d %d %d\n",
-     	x, y, in1.x0, in1.x1, in1.y0, in1.y1, f1.x0, f1.x1, f1.y0, f1.y1);
-     xf86DrvMsg(0, X_INFO, "3-out: %d %d %d %d\n",
-     	out.x0, out.x1, out.y0, out.y1); */
-
-     if(out.x0 > x) {
-        deltax = x - out.x0;
-     }
-     if(out.x1 < x) {
-        deltax = x - out.x1;
-     }
-     if(deltax) {
-        pScrn1->frameX0 += deltax;
-        pScrn1->frameX1 += deltax;
-	f1.x0 += deltax;
-        f1.x1 += deltax;
-        f2.x0 += deltax;
-        f2.x1 += deltax;
-     }
-
-     if(out.y0 > y) {
-        deltay = y - out.y0;
-     }
-     if(out.y1 < y) {
-        deltay = y - out.y1;
-     }
-     if(deltay) {
-        pScrn1->frameY0 += deltay;
-        pScrn1->frameY1 += deltay;
-	f1.y0 += deltay;
-        f1.y1 += deltay;
-        f2.y0 += deltay;
-        f2.y1 += deltay;
-     }
-
-     switch(srel) {
-        case radeonLeftOf:
-	   if(x >= f1.x0) { REBOUND(f1.y0, f1.y1, y); }
-	   if(x <= f2.x1) { REBOUND(f2.y0, f2.y1, y); }
-           break;
-        case radeonRightOf:
-	   if(x <= f1.x1) { REBOUND(f1.y0, f1.y1, y); }
-	   if(x >= f2.x0) { REBOUND(f2.y0, f2.y1, y); }
-           break;
-        case radeonBelow:
-	   if(y <= f1.y1) { REBOUND(f1.x0, f1.x1, x); }
-	   if(y >= f2.y0) { REBOUND(f2.x0, f2.x1, x); }
-           break;
-        case radeonAbove:
-	   if(y >= f1.y0) { REBOUND(f1.x0, f1.x1, x); }
-	   if(y <= f2.y1) { REBOUND(f2.x0, f2.x1, x); }
-           break;
-        case radeonClone:
-           break;
-     }
-
-  }
-
-  if(deltax || deltay) {
-     info->CRT1frameX0 = f1.x0;
-     info->CRT1frameY0 = f1.y0;
-     pScrn2->frameX0 = f2.x0;
-     pScrn2->frameY0 = f2.y0;
-
-     switch(((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position) {
-	case radeonLeftOf:
-	case radeonRightOf:
-	    if(info->CRT1YOffs || info->CRT2YOffs || HaveNonRect) {
-		if(info->CRT1frameY0 != old1y0) {
-		    if(info->CRT1frameY0 < info->CRT1YOffs)
-  	                info->CRT1frameY0 = info->CRT1YOffs;
-  	            temp1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay;
-  	            /*temp2 = pScrn1->virtualY - info->CRT2YOffs;*/
-		    temp2 = min((VVirt - CRT2YOffs), (CRT1YOffs + info->MBXNR1YMAX));
-  	            if(temp1 > temp2)
-  	                info->CRT1frameY0 -= (temp1 - temp2);
-  	        }
-  	        if(pScrn2->frameY0 != old2y0) {
-  	            if(pScrn2->frameY0 < info->CRT2YOffs)
-  	                pScrn2->frameY0 = info->CRT2YOffs;
-  	            temp1 = pScrn2->frameY0   + CDMPTR->CRT2->VDisplay;
-  	            /*temp2 = pScrn1->virtualY - info->CRT1YOffs;*/
-		    temp2 = min((VVirt - CRT1YOffs), (CRT2YOffs + info->MBXNR2YMAX));
-  	            if(temp1 > temp2)
-  	                pScrn2->frameY0 -= (temp1 - temp2);
-  	        }
-  	    }
-	    break;
-	case radeonBelow:
-	case radeonAbove:
-	    if(info->CRT1XOffs || info->CRT2XOffs || HaveNonRect) {
-		if(info->CRT1frameX0 != old1x0) {
-		    if(info->CRT1frameX0 < info->CRT1XOffs)
-			info->CRT1frameX0 = info->CRT1XOffs;
-		    temp1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay;
-  	            /*temp2 = pScrn1->virtualX - info->CRT2XOffs;*/
-                    temp2 = min((HVirt - CRT2XOffs), (CRT1XOffs + info->MBXNR1XMAX));
-  	            if(temp1 > temp2)
-  	            	info->CRT1frameX0 -= (temp1 - temp2);
-  	        }
-  	        if(pScrn2->frameX0 != old2x0) {
-  	            if(pScrn2->frameX0 < info->CRT2XOffs)
-  	       		pScrn2->frameX0 = info->CRT2XOffs;
-  	            temp1 = pScrn2->frameX0   + CDMPTR->CRT2->HDisplay;
-  	            /*temp2 = pScrn1->virtualX - info->CRT1XOffs;*/
-		    temp2 = min((HVirt - CRT1XOffs), (CRT2XOffs + info->MBXNR2XMAX));
-  	            if(temp1 > temp2)
-  	            	pScrn2->frameX0 -= (temp1 - temp2);
-  	        }
-  	    }
-  	    break;
-  	    case radeonClone:
-  	    	break;
-     }
-
-     info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
-     info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
-     pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR->CRT2->HDisplay - 1;
-     pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR->CRT2->VDisplay - 1;
-#if 0
-     pScrn1->frameX1   = pScrn1->frameX0   + info->CurrentLayout.mode->HDisplay  - 1;
-     pScrn1->frameY1   = pScrn1->frameY0   + info->CurrentLayout.mode->VDisplay  - 1;
-#endif
-
-     RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
-     RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
-  }
-}
-
-static void
-RADEONAdjustFrameMergedHelper(int scrnIndex, int x, int y, int flags)
-{
-    ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
-    RADEONInfoPtr info = RADEONPTR(pScrn1);
-    ScrnInfoPtr pScrn2 = info->CRT2pScrn;
-    int VTotal = info->CurrentLayout.mode->VDisplay;
-    int HTotal = info->CurrentLayout.mode->HDisplay;
-    int VMax = VTotal;
-    int HMax = HTotal;
-    int HVirt = pScrn1->virtualX;
-    int VVirt = pScrn1->virtualY;
-    int x1 = x, x2 = x;
-    int y1 = y, y2 = y;
-    int CRT1XOffs = 0, CRT1YOffs = 0, CRT2XOffs = 0, CRT2YOffs = 0;
-    int MBXNR1XMAX = 65536, MBXNR1YMAX = 65536, MBXNR2XMAX = 65536, MBXNR2YMAX = 65536;
-
-    if(info->DGAactive) {
-       HVirt = info->CurrentLayout.displayWidth;
-       VVirt = info->CurrentLayout.displayHeight;
-    } else {
-       CRT1XOffs = info->CRT1XOffs;
-       CRT1YOffs = info->CRT1YOffs;
-       CRT2XOffs = info->CRT2XOffs;
-       CRT2YOffs = info->CRT2YOffs;
-       MBXNR1XMAX = info->MBXNR1XMAX;
-       MBXNR1YMAX = info->MBXNR1YMAX;
-       MBXNR2XMAX = info->MBXNR2XMAX;
-       MBXNR2YMAX = info->MBXNR2YMAX;
-    }
-
-
-    BOUND(x, 0, pScrn1->virtualX - HTotal);
-    BOUND(y, 0, pScrn1->virtualY - VTotal);
-    if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {
-#if 0
-	BOUND(x1, info->CRT1XOffs, pScrn1->virtualX - HTotal - info->CRT2XOffs);
-	BOUND(y1, info->CRT1YOffs, pScrn1->virtualY - VTotal - info->CRT2YOffs);
-	BOUND(x2, info->CRT2XOffs, pScrn1->virtualX - HTotal - info->CRT1XOffs);
-	BOUND(y2, info->CRT2YOffs, pScrn1->virtualY - VTotal - info->CRT1YOffs);
-#endif
-       BOUND(x1, CRT1XOffs, min(HVirt, MBXNR1XMAX + CRT1XOffs) - min(HTotal, MBXNR1XMAX) - CRT2XOffs);
-       BOUND(y1, CRT1YOffs, min(VVirt, MBXNR1YMAX + CRT1YOffs) - min(VTotal, MBXNR1YMAX) - CRT2YOffs);
-       BOUND(x2, CRT2XOffs, min(HVirt, MBXNR2XMAX + CRT2XOffs) - min(HTotal, MBXNR2XMAX) - CRT1XOffs);
-       BOUND(y2, CRT2YOffs, min(VVirt, MBXNR2YMAX + CRT2YOffs) - min(VTotal, MBXNR2YMAX) - CRT1YOffs);
-    }
-
-    switch(SDMPTR(pScrn1)->CRT2Position) {
-        case radeonLeftOf:
-            pScrn2->frameX0 = x2;
-            /*BOUND(pScrn2->frameY0,   y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/
-            BOUND(pScrn2->frameY0,   y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay);
-            info->CRT1frameX0 = x1 + CDMPTR->CRT2->HDisplay;
-            /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/
-            BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay);
-            break;
-        case radeonRightOf:
-            info->CRT1frameX0 = x1;
-            /*BOUND(info->CRT1frameY0, y1, y1 + VMax - CDMPTR->CRT1->VDisplay);*/
-            BOUND(info->CRT1frameY0, y1, y1 + min(VMax, MBXNR1YMAX) - CDMPTR->CRT1->VDisplay);
-            pScrn2->frameX0 = x2 + CDMPTR->CRT1->HDisplay;
-            /*BOUND(pScrn2->frameY0,   y2, y2 + VMax - CDMPTR->CRT2->VDisplay);*/
-            BOUND(pScrn2->frameY0,   y2, y2 + min(VMax, MBXNR2YMAX) - CDMPTR->CRT2->VDisplay);
-            break;
-        case radeonAbove:
-            /*BOUND(pScrn2->frameX0,   x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/
-            BOUND(pScrn2->frameX0,   x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay);
-            pScrn2->frameY0 = y2;
-            /*BOUND(info->CRT1frameX0, x1, x1  + HMax - CDMPTR->CRT1->HDisplay);*/
-            BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay);
-            info->CRT1frameY0 = y1 + CDMPTR->CRT2->VDisplay;
-            break;
-        case radeonBelow:
-            /*BOUND(info->CRT1frameX0, x1, x1 + HMax - CDMPTR->CRT1->HDisplay);*/
-            BOUND(info->CRT1frameX0, x1, x1 + min(HMax, MBXNR1XMAX) - CDMPTR->CRT1->HDisplay);
-            info->CRT1frameY0 = y1;
-            /*BOUND(pScrn2->frameX0,   x2, x2 + HMax - CDMPTR->CRT2->HDisplay);*/
-	    BOUND(pScrn2->frameX0,   x2, x2 + min(HMax, MBXNR2XMAX) - CDMPTR->CRT2->HDisplay);
-            pScrn2->frameY0 = y2 + CDMPTR->CRT1->VDisplay;
-            break;
-        case radeonClone:
-            BOUND(info->CRT1frameX0, x,  x + HMax - CDMPTR->CRT1->HDisplay);
-            BOUND(info->CRT1frameY0, y,  y + VMax - CDMPTR->CRT1->VDisplay);
-            BOUND(pScrn2->frameX0,   x,  x + HMax - CDMPTR->CRT2->HDisplay);
-            BOUND(pScrn2->frameY0,   y,  y + VMax - CDMPTR->CRT2->VDisplay);
-            break;
-    }
-
-    BOUND(info->CRT1frameX0, 0, pScrn1->virtualX - CDMPTR->CRT1->HDisplay);
-    BOUND(info->CRT1frameY0, 0, pScrn1->virtualY - CDMPTR->CRT1->VDisplay);
-    BOUND(pScrn2->frameX0,   0, pScrn1->virtualX - CDMPTR->CRT2->HDisplay);
-    BOUND(pScrn2->frameY0,   0, pScrn1->virtualY - CDMPTR->CRT2->VDisplay);
-    
-    pScrn1->frameX0 = x;
-    pScrn1->frameY0 = y;
-
-    info->CRT1frameX1 = info->CRT1frameX0 + CDMPTR->CRT1->HDisplay - 1;
-    info->CRT1frameY1 = info->CRT1frameY0 + CDMPTR->CRT1->VDisplay - 1;
-    pScrn2->frameX1   = pScrn2->frameX0   + CDMPTR->CRT2->HDisplay - 1;
-    pScrn2->frameY1   = pScrn2->frameY0   + CDMPTR->CRT2->VDisplay - 1;
-    pScrn1->frameX1   = pScrn1->frameX0   + info->CurrentLayout.mode->HDisplay  - 1;
-    pScrn1->frameY1   = pScrn1->frameY0   + info->CurrentLayout.mode->VDisplay  - 1;
-
-    if(SDMPTR(pScrn1)->CRT2Position != radeonClone) {
-       pScrn1->frameX1 += CRT1XOffs + CRT2XOffs;
-       pScrn1->frameY1 += CRT1YOffs + CRT2YOffs;
-    }
-
-/*
-    RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
-    RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
-*/
-}
-
-void
-RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags)
-{
-    ScrnInfoPtr pScrn1 = xf86Screens[scrnIndex];
-    RADEONInfoPtr info = RADEONPTR(pScrn1);
-    ScrnInfoPtr pScrn2 = info->CRT2pScrn;
-
-    RADEONAdjustFrameMergedHelper(scrnIndex, x, y, flags);
-    RADEONDoAdjustFrame(pScrn1, info->CRT1frameX0, info->CRT1frameY0, FALSE);
-    RADEONDoAdjustFrame(pScrn1, pScrn2->frameX0, pScrn2->frameY0, TRUE);
-}
-
-static void
-RADEONMergedFBCalcDPI(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel, Bool quiet)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn1);
-    MessageType from = X_DEFAULT;
-    xf86MonPtr DDC1 = (xf86MonPtr)(pScrn1->monitor->DDC);
-    xf86MonPtr DDC2 = (xf86MonPtr)(pScrn2->monitor->DDC);
-    int ddcWidthmm = 0, ddcHeightmm = 0;
-    const char *dsstr = "MergedFB: Display dimensions: %dx%d mm\n";
-
-    /* This sets the DPI for MergedFB mode. The problem is that
-     * this can never be exact, because the output devices may
-     * have different dimensions. This function tries to compromise
-     * through a few assumptions, and it just calculates an average
-     * DPI value for both monitors.
-     */
-
-    /* Copy user-given DisplaySize (which should regard BOTH monitors!) */
-    pScrn1->widthmm = pScrn1->monitor->widthmm;
-    pScrn1->heightmm = pScrn1->monitor->heightmm;
-
-    if(monitorResolution > 0) {
-
-       /* Set command line given values (overrules given options) */
-       pScrn1->xDpi = monitorResolution;
-       pScrn1->yDpi = monitorResolution;
-       from = X_CMDLINE;
-
-    } else if(info->MergedFBXDPI) {
-
-       /* Set option-wise given values (overrules DisplaySize config option) */
-       pScrn1->xDpi = info->MergedFBXDPI;
-       pScrn1->yDpi = info->MergedFBYDPI;
-       from = X_CONFIG;
-
-    } else if(pScrn1->widthmm > 0 || pScrn1->heightmm > 0) {
-
-       /* Set values calculated from given DisplaySize */
-       from = X_CONFIG;
-       if(pScrn1->widthmm > 0) {
-	  pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
-       }
-       if(pScrn1->heightmm > 0) {
-	  pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
-       }
-       if(!quiet) {
-          xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, pScrn1->widthmm, pScrn1->heightmm);
-       }
-
-    } else if(ddcWidthmm && ddcHeightmm) {
-
-       /* Set values from DDC-provided display size */
-
-       /* Get DDC display size; if only either CRT1 or CRT2 provided these,
-	* assume equal dimensions for both, otherwise add dimensions
-	*/
-       if( (DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) &&
-	   (DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0)) ) {
-	  ddcWidthmm = max(DDC1->features.hsize, DDC2->features.hsize) * 10;
-	  ddcHeightmm = max(DDC1->features.vsize, DDC2->features.vsize) * 10;
-	  switch(srel) {
-	  case radeonLeftOf:
-	  case radeonRightOf:
-	     ddcWidthmm = (DDC1->features.hsize + DDC2->features.hsize) * 10;
-	     break;
-	  case radeonAbove:
-	  case radeonBelow:
-	     ddcHeightmm = (DDC1->features.vsize + DDC2->features.vsize) * 10;
-	  default:
-	     break;
-	  }
-       } else if(DDC1 && (DDC1->features.hsize > 0 && DDC1->features.vsize > 0)) {
-	  ddcWidthmm = DDC1->features.hsize * 10;
-	  ddcHeightmm = DDC1->features.vsize * 10;
-	  switch(srel) {
-	  case radeonLeftOf:
-	  case radeonRightOf:
-	     ddcWidthmm *= 2;
-	     break;
-	  case radeonAbove:
-	  case radeonBelow:
-	     ddcHeightmm *= 2;
-	  default:
-	     break;
-          }
-       } else if(DDC2 && (DDC2->features.hsize > 0 && DDC2->features.vsize > 0) ) {
-	  ddcWidthmm = DDC2->features.hsize * 10;
-	  ddcHeightmm = DDC2->features.vsize * 10;
-	  switch(srel) {
-	  case radeonLeftOf:
-	  case radeonRightOf:
-	     ddcWidthmm *= 2;
-	     break;
-	  case radeonAbove:
-	  case radeonBelow:
-	     ddcHeightmm *= 2;
-	  default:
-	     break;
-	  }
-       }
-
-       from = X_PROBED;
-
-       if(!quiet) {
-          xf86DrvMsg(pScrn1->scrnIndex, from, dsstr, ddcWidthmm, ddcHeightmm);
-       }
-
-       pScrn1->widthmm = ddcWidthmm;
-       pScrn1->heightmm = ddcHeightmm;
-       if(pScrn1->widthmm > 0) {
-	  pScrn1->xDpi = (int)((double)pScrn1->virtualX * 25.4 / pScrn1->widthmm);
-       }
-       if(pScrn1->heightmm > 0) {
-	  pScrn1->yDpi = (int)((double)pScrn1->virtualY * 25.4 / pScrn1->heightmm);
-       }
-
-    } else {
-
-       pScrn1->xDpi = pScrn1->yDpi = DEFAULT_DPI;
-
-    }
-
-    /* Sanity check */
-    if(pScrn1->xDpi > 0 && pScrn1->yDpi <= 0)
-       pScrn1->yDpi = pScrn1->xDpi;
-    if(pScrn1->yDpi > 0 && pScrn1->xDpi <= 0)
-       pScrn1->xDpi = pScrn1->yDpi;
-
-    pScrn2->xDpi = pScrn1->xDpi;
-    pScrn2->yDpi = pScrn1->yDpi;
-
-    if(!quiet) {
-       xf86DrvMsg(pScrn1->scrnIndex, from, "MergedFB: DPI set to (%d, %d)\n",
-		pScrn1->xDpi, pScrn1->yDpi);
-    }
-}
-
-
-void
-RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel)
-{
-    RADEONInfoPtr      info       = RADEONPTR(pScrn1);
-
-    RADEONMergedFBCalcDPI(pScrn1, pScrn2, srel, FALSE);
-
-    info->MergedDPISRel = srel;
-    info->RADEONMergedDPIVX = pScrn1->virtualX;
-    info->RADEONMergedDPIVY = pScrn1->virtualY;
-
-}
-
-void
-RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force)
-{
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-    RADEONScrn2Rel srel = ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-
-    /* This does the same calculation for the DPI as
-     * the initial run. This means that an eventually
-     * given -dpi command line switch will lead to
-     * constant dpi values, regardless of the virtual
-     * screen size.
-     * I consider this consequent. If this is undesired,
-     * one should use the DisplaySize parameter in the
-     * config file instead of the command line switch.
-     * The DPI will be calculated then.
-     */
-
-    if(force						||
-       (info->MergedDPISRel != srel)			||
-       (info->RADEONMergedDPIVX != pScrn->virtualX)	||
-       (info->RADEONMergedDPIVY != pScrn->virtualY)
-						) {
-
-       RADEONMergedFBCalcDPI(pScrn, info->CRT2pScrn, srel, TRUE);
-
-       pScreen->mmWidth = (pScrn->virtualX * 254 + pScrn->xDpi * 5) / (pScrn->xDpi * 10);
-       pScreen->mmHeight = (pScrn->virtualY * 254 + pScrn->yDpi * 5) / (pScrn->yDpi * 10);
-
-       info->MergedDPISRel = srel;
-       info->RADEONMergedDPIVX = pScrn->virtualX;
-       info->RADEONMergedDPIVY = pScrn->virtualY;
-
-    }
-}
-
-/* radeon cursor helpers */
-static void
-RADEONChooseCursorCRTC(ScrnInfoPtr pScrn1, int x, int y)
-{
-    RADEONInfoPtr      info       = RADEONPTR(pScrn1);
-    unsigned char     *RADEONMMIO = info->MMIO;
-    RADEONScrn2Rel srel = 
-        ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-    ScrnInfoPtr pScrn2 = info->CRT2pScrn;
-    
-    if (srel == radeonClone) {
-	/* show cursor 2 */
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
-		~RADEON_CRTC2_CUR_EN);
-	/* show cursor 1 */
-	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
-		~RADEON_CRTC_CUR_EN);
-    }
-    else {
-	if (((x >= pScrn1->frameX0) && (x <= pScrn1->frameX1)) &&
-       	    ((y >= pScrn1->frameY0) && (y <= pScrn1->frameY1))) {
-		/* hide cursor 2 */
-		OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
-		/* show cursor 1 */
-		OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
-			~RADEON_CRTC_CUR_EN);
-	}
-	if (((x >= pScrn2->frameX0) && (x <= pScrn2->frameX1)) &&
-       	    ((y >= pScrn2->frameY0) && (y <= pScrn2->frameY1))) {
-		/* hide cursor 1 */
-		OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
-		/* show cursor 2 */
-		OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
-			~RADEON_CRTC2_CUR_EN);
-	}
-    }
-}
-
-void
-RADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y)
-{
-    RADEONInfoPtr      info       = RADEONPTR(pScrn);
-    unsigned char     *RADEONMMIO = info->MMIO;
-    xf86CursorInfoPtr  cursor     = info->cursor;
-    int                xorigin    = 0;
-    int                yorigin    = 0;
-    int		       stride     = 256;
-    ScrnInfoPtr    pScrn2 = info->CRT2pScrn;
-    DisplayModePtr mode1 = CDMPTR->CRT1;
-    DisplayModePtr mode2 = CDMPTR->CRT2;
-    int            x1, y1, x2, y2;
-    int                total_y1    = pScrn->frameY1 - pScrn->frameY0;
-    int                total_y2    = pScrn2->frameY1 - pScrn2->frameY0;
-
-    if (x < 0)                        xorigin = -x+1;
-    if (y < 0)                        yorigin = -y+1;
-    /* if (y > total_y)                  y       = total_y; */
-    if (xorigin >= cursor->MaxWidth)  xorigin = cursor->MaxWidth - 1;
-    if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
-
-    x += pScrn->frameX0;
-    y += pScrn->frameY0;
-
-    x1 = x - info->CRT1frameX0;
-    y1 = y - info->CRT1frameY0;
-
-    x2 = x - pScrn2->frameX0;
-    y2 = y - pScrn2->frameY0;
-
-    if (y1 > total_y1)
-	y1       = total_y1;
-    if (y2 > total_y2)                  
-	y2       = total_y2;
-
-    if(mode1->Flags & V_INTERLACE)
-	y1 /= 2;
-    else if(mode1->Flags & V_DBLSCAN)
-	y1 *= 2;
-
-    if(mode2->Flags & V_INTERLACE)
-	y2 /= 2;
-    else if(mode2->Flags & V_DBLSCAN)
-	y2 *= 2;
-
-    if (x < 0)
-	x = 0;
-    if (y < 0)
-	y = 0;
-
-    RADEONChooseCursorCRTC(pScrn, x, y);
-
-		/* cursor1 */
-    OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
-				   | (xorigin << 16)
-				   | yorigin));
-    OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
-				   | ((xorigin ? 0 : x1) << 16)
-				   | (yorigin ? 0 : y1)));
-    OUTREG(RADEON_CUR_OFFSET, info->cursor_offset + yorigin * stride);
-		/* cursor2 */
-    OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
-				    | (xorigin << 16)
-				    | yorigin));
-    OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
-				    | ((xorigin ? 0 : x2) << 16)
-				    | (yorigin ? 0 : y2)));
-    OUTREG(RADEON_CUR2_OFFSET, info->cursor_offset + yorigin * stride);
-}
-
-/* radeon Xv helpers */
-
-/* choose the crtc for the overlay for mergedfb based on the location
-   of the output window and the orientation of the crtcs */
-
-void
-RADEONChooseOverlayCRTC(
-    ScrnInfoPtr pScrn,
-    BoxPtr dstBox
-) {
-    RADEONInfoPtr info = RADEONPTR(pScrn);
-    RADEONScrn2Rel srel = 
-        ((RADEONMergedDisplayModePtr)info->CurrentLayout.mode->Private)->CRT2Position;
-
-    if (srel == radeonLeftOf) {
-        if (dstBox->x1 >= info->CRT2pScrn->frameX1)
-            info->OverlayOnCRTC2 = FALSE;
-        else
-            info->OverlayOnCRTC2 = TRUE;
-    }
-    if (srel == radeonRightOf) {
-        if (dstBox->x2 <= info->CRT2pScrn->frameX0)
-            info->OverlayOnCRTC2 = FALSE;
-        else
-            info->OverlayOnCRTC2 = TRUE;
-    }
-    if (srel == radeonAbove) {
-        if (dstBox->y1 >= info->CRT2pScrn->frameY1)
-            info->OverlayOnCRTC2 = FALSE;
-        else
-            info->OverlayOnCRTC2 = TRUE;
-    }
-    if (srel == radeonBelow) {
-	if (dstBox->y2 <= info->CRT2pScrn->frameY0)
-            info->OverlayOnCRTC2 = FALSE;
-        else
-            info->OverlayOnCRTC2 = TRUE;
-    }
-}
diff --git a/src/radeon_mergedfb.h b/src/radeon_mergedfb.h
deleted file mode 100644
index d9bcc03..0000000
--- a/src/radeon_mergedfb.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright 2003 Alex Deucher.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT.  IN NO EVENT SHALL ALEX DEUCHER, OR ANY OTHER
- * CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Authors:
- *   Alex Deucher <agd5f at yahoo.com>
- *
- */
-
-#ifndef _RADEON_MERGEDFB_H_
-#define _RADEON_MERGEDFB_H_
-
-#include "xf86.h"
-
-#include "radeon.h"
-
-#if 0
-		/* Psuedo Xinerama support */
-#define NEED_REPLIES  		/* ? */
-#define EXTENSION_PROC_ARGS void *
-#include "extnsionst.h"  	/* required */
-#include <X11/extensions/panoramiXproto.h>  	/* required */
-#define RADEON_XINERAMA_MAJOR_VERSION  1
-#define RADEON_XINERAMA_MINOR_VERSION  1
-
-/* needed for pseudo-xinerama by radeon_driver.c */
-Bool 		RADEONnoPanoramiXExtension = TRUE;
-
-/* Relative merge position */
-typedef enum {
-   radeonLeftOf,
-   radeonRightOf,
-   radeonAbove,
-   radeonBelow,
-   radeonClone
-} RADEONScrn2Rel;
-#endif
-
-#define SDMPTR(x) ((RADEONMergedDisplayModePtr)(x->currentMode->Private))
-#define CDMPTR    ((RADEONMergedDisplayModePtr)(info->CurrentLayout.mode->Private))
-
-#define BOUND(test,low,hi) { \
-    if(test < low) test = low; \
-    if(test > hi) test = hi; }
-
-#define REBOUND(low,hi,test) { \
-    if(test < low) { \
-        hi += test-low; \
-        low = test; } \
-    if(test > hi) { \
-        low += test-hi; \
-        hi = test; } }
-
-typedef struct _MergedDisplayModeRec {
-    DisplayModePtr CRT1;
-    DisplayModePtr CRT2;
-    RADEONScrn2Rel    CRT2Position;
-} RADEONMergedDisplayModeRec, *RADEONMergedDisplayModePtr;
-
-typedef struct _RADEONXineramaData {
-    int x;
-    int y;
-    int width;
-    int height;
-} RADEONXineramaData;
-
-/* needed by radeon_driver.c */
-extern void
-RADEONAdjustFrameMerged(int scrnIndex, int x, int y, int flags);
-extern void
-RADEONMergePointerMoved(int scrnIndex, int x, int y);
-extern DisplayModePtr
-RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
-		    DisplayModePtr i, DisplayModePtr j,
-		    RADEONScrn2Rel srel);
-extern int
-RADEONStrToRanges(range *r, char *s, int max);
-extern void
-RADEONXineramaExtensionInit(ScrnInfoPtr pScrn);
-extern void
-RADEONUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1);
-extern void
-RADEONMergedFBSetDpi(ScrnInfoPtr pScrn1, ScrnInfoPtr pScrn2, RADEONScrn2Rel srel);
-extern void
-RADEONMergedFBResetDpi(ScrnInfoPtr pScrn, Bool force);
-extern void
-RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn);
-
-/* needed by radeon_cursor.c */
-extern void
-RADEONSetCursorPositionMerged(ScrnInfoPtr pScrn, int x, int y);
-
-/* needed by radeon_video.c */
-extern void
-RADEONChooseOverlayCRTC(ScrnInfoPtr, BoxPtr);
-
-#endif /* _RADEON_MERGEDFB_H_ */
diff-tree a648050a3cc60f92b1ca0b3d707aadf93d076d91 (from d2ecfb507282726122bb8b0d17fd3637d0ae7d46)
Author: Dave Airlie <airlied at linux.ie>
Date:   Wed Jan 17 17:28:07 2007 +1100

    move some cursor code around for show/hide

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index 74289e4..f220ca4 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -266,60 +266,6 @@ RADEONRandrSetCursorPosition(ScrnInfoPtr
 
 }
 
-/* Set cursor position to (x,y) with offset into cursor bitmap at
- * (xorigin,yorigin)
- */
-static void RADEONSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
-{
-    RADEONInfoPtr      info       = RADEONPTR(pScrn);
-    unsigned char     *RADEONMMIO = info->MMIO;
-    xf86CursorInfoPtr  cursor     = info->cursor;
-    int                xorigin    = 0;
-    int                yorigin    = 0;
-    int                total_y    = pScrn->frameY1 - pScrn->frameY0;
-    int		       stride     = 256;
-
-    if(info->MergedFB) {
-       RADEONCTRACE(("RADEONSetCursorPositionMerged\n"));
-       RADEONSetCursorPositionMerged(pScrn, x, y);
-       return;
-    }
-
-    RADEONCTRACE(("RADEONSetCursorPosition\n"));
-
-    
-#if 0
-    if (x < 0)                        xorigin = -x+1;
-    if (y < 0)                        yorigin = -y+1;
-    if (y > total_y)                  y       = total_y;
-    if (info->Flags & V_DBLSCAN)      y       *= 2;
-    if (xorigin >= cursor->MaxWidth)  xorigin = cursor->MaxWidth - 1;
-    if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
-
-    if (!info->IsSecondary) {
-	OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
-					   | (xorigin << 16)
-					   | yorigin));
-	OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK
-					   | ((xorigin ? 0 : x) << 16)
-					   | (yorigin ? 0 : y)));
-	RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d\n",
-		     info->cursor_offset + pScrn->fbOffset, yorigin, stride));
-	OUTREG(RADEON_CUR_OFFSET,
-	       info->cursor_offset + pScrn->fbOffset + yorigin * stride);
-    } else {
-	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
-					    | (xorigin << 16)
-					    | yorigin));
-	OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK
-					    | ((xorigin ? 0 : x) << 16)
-					    | (yorigin ? 0 : y)));
-	OUTREG(RADEON_CUR2_OFFSET,
-	       info->cursor_offset + pScrn->fbOffset + yorigin * stride);
-    }
-#endif
-}
-
 /* Copy cursor image from `image' to video memory.  RADEONSetCursorPosition
  * will be called after this, so we can ignore xorigin and yorigin.
  */
@@ -337,6 +283,7 @@ static void RADEONLoadCursorImage(ScrnIn
 
     RADEONCTRACE(("RADEONLoadCursorImage (at %x)\n", info->cursor_offset));
 
+
     if (!info->IsSecondary) {
 	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
 	save1 |= (CARD32) (2 << 20);
@@ -382,8 +329,7 @@ static void RADEONLoadCursorImage(ScrnIn
     if (!info->IsSecondary)
 	OUTREG(RADEON_CRTC_GEN_CNTL, save1);
 
-    if (info->IsSecondary || info->MergedFB)
-	OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
+    OUTREG(RADEON_CRTC2_GEN_CNTL, save2);
 
 }
 
@@ -392,14 +338,12 @@ static void RADEONHideCursor(ScrnInfoPtr
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int c;
     RADEONCTRACE(("RADEONHideCursor\n"));
 
-    if (info->IsSecondary || info->MergedFB)
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
-
-    if (!info->IsSecondary)
-	OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
+    for (c = 0; c < xf86_config->num_crtc; c++)
+        RADEONCrtcCursor(xf86_config->crtc[c], TRUE);
 }
 
 /* Show hardware cursor. */
@@ -407,16 +351,13 @@ static void RADEONShowCursor(ScrnInfoPtr
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int c;
 
     RADEONCTRACE(("RADEONShowCursor\n"));
 
-    if (info->IsSecondary || info->MergedFB)
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
-		~RADEON_CRTC2_CUR_EN);
-
-    if (!info->IsSecondary)
-	OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
-		~RADEON_CRTC_CUR_EN);
+    for (c = 0; c < xf86_config->num_crtc; c++)
+        RADEONCrtcCursor(xf86_config->crtc[c], FALSE);
 }
 
 /* Determine if hardware cursor is in use. */
diff-tree d2ecfb507282726122bb8b0d17fd3637d0ae7d46 (from 369f7c85ceff983defb7657b80ec9cd3e5440b07)
Author: Dave Airlie <airlied at linux.ie>
Date:   Wed Jan 17 17:16:27 2007 +1100

    make dri work again

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 2306fda..c2b0418 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3227,7 +3227,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     RADEONPreInitColorTiling(pScrn);
 
-    xf86CrtcSetSizeRange (pScrn, 320, 200, 3072, 3072) ;//nfo->MaxSurfaceWidth, info->MaxLines);
+    xf86CrtcSetSizeRange (pScrn, 320, 200, 2708, 1152);//nfo->MaxSurfaceWidth, info->MaxLines);
 
 
     RADEONPreInitDDC(pScrn);
diff-tree 369f7c85ceff983defb7657b80ec9cd3e5440b07 (from bdb66a2042f02c4b57bd3c0181a00b39fcbdb232)
Author: Dave Airlie <airlied at linux.ie>
Date:   Wed Jan 17 11:14:09 2007 +1100

    comment out unblanking on VT switch

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 288ddba..2306fda 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5639,7 +5639,7 @@ void RADEONRestore(ScrnInfoPtr pScrn)
     if (!info->IsSecondary)
 	RADEONRestoreSurfaces(pScrn, restore);
 
-#if 0
+#if 1
     /* Temp fix to "solve" VT switch problems.  When switching VTs on
      * some systems, the console can either hang or the fonts can be
      * corrupted.  This hack solves the problem 99% of the time.  A
@@ -5681,8 +5681,19 @@ void RADEONRestore(ScrnInfoPtr pScrn)
        }
     }
 #endif
+#if 0
+    {
+        xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int i;
+	for (i = 0; i <= xf86_config->num_crtc; i++) {
+		if (i == 0)
+			xf86_config->crtc[i]->enabled = 1;
+		else
+			xf86_config->crtc[i]->enabled = 0;
+    	}
+    }
     RADEONUnblank(pScrn);
-
+#endif
 #if 0
     RADEONWaitForVerticalSync(pScrn);
 #endif
@@ -7037,7 +7048,6 @@ _X_EXPORT void RADEONLeaveVT(int scrnInd
     }
 
     RADEONRestore(pScrn);
-
     RADEONTRACE(("Ok, leaving now...\n"));
 }
 
diff-tree bdb66a2042f02c4b57bd3c0181a00b39fcbdb232 (from aa0e7337815d4daca4df0671768621330b759011)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jan 14 21:07:05 2007 +1100

    radeon: get randr-1.2 mode switching mostly working on my laptop
    
    The main change is to fix the dac macro + cntl register writes for rv350 and
    above, this still has a problem with resetting the same mode after connect
    disconnect cycle, need to talk to keithp

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 2654296..f80162d 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1467,7 +1467,7 @@ static void RADEONDacPowerSet(ScrnInfoPt
 	CARD32 dac_cntl;
 	CARD32 dac_macro_cntl = 0;
 	dac_cntl = INREG(RADEON_DAC_CNTL);
-	if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350)) 
+	if ((!info->IsMobility) || (info->ChipFamily >= CHIP_FAMILY_RV350)) 
 	    dac_macro_cntl = INREG(RADEON_DAC_MACRO_CNTL);
 	if (IsOn) {
 	    dac_cntl &= ~RADEON_DAC_PDWN;
@@ -1480,8 +1480,9 @@ static void RADEONDacPowerSet(ScrnInfoPt
 			       RADEON_DAC_PDWN_G |
 			       RADEON_DAC_PDWN_B);
 	}
+	ErrorF("Setting IsOn %d DAC CNTL %08X and DAC MACRO_CNTL %08X\n", IsOn, dac_cntl, dac_macro_cntl);
 	OUTREG(RADEON_DAC_CNTL, dac_cntl);
-	if ((!info->IsMobility) || (info->ChipFamily == CHIP_FAMILY_RV350)) 
+	if ((!info->IsMobility) || (info->ChipFamily >= CHIP_FAMILY_RV350)) 
 	    OUTREG(RADEON_DAC_MACRO_CNTL, dac_macro_cntl);
     } else {
 	CARD32 tv_dac_cntl;
@@ -2099,6 +2100,8 @@ static void RADEONDPMSSetOn(xf86OutputPt
   TmdsType = radeon_output->TMDSType;
   DacType = radeon_output->DACType;
 
+  ErrorF("radeon_dpms_on %d %d %d\n", radeon_output->num, MonType, DacType);
+
   switch(MonType) {
   case MT_LCD:
     OUTREGP (RADEON_LVDS_GEN_CNTL, RADEON_LVDS_BLON, ~RADEON_LVDS_BLON);
@@ -2173,118 +2176,6 @@ static void RADEONDPMSSetOff(xf86OutputP
 }
 
 
-/* Sets VESA Display Power Management Signaling (DPMS) Mode */
-void RADEONDisplayPowerManagementSet(ScrnInfoPtr pScrn,
-					    int PowerManagementMode,
-					    int flags)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    xf86OutputPtr output;
-    if (!pScrn->vtSema) return;
-
-    RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags));
-
-#ifdef XF86DRI
-    if (info->CPStarted) DRILock(pScrn->pScreen, 0);
-#endif
-
-    if (info->accelOn)
-        RADEON_SYNC(info, pScrn);
-
-    if (info->FBDev) {
-	fbdevHWDPMSSet(pScrn, PowerManagementMode, flags);
-    } else {
-	int             mask1     = (RADEON_CRTC_DISPLAY_DIS |
-				     RADEON_CRTC_HSYNC_DIS |
-				     RADEON_CRTC_VSYNC_DIS);
-	int             mask2     = (RADEON_CRTC2_DISP_DIS |
-				     RADEON_CRTC2_VSYNC_DIS |
-				     RADEON_CRTC2_HSYNC_DIS);
-
-	switch (PowerManagementMode) {
-	case DPMSModeOn:
-	    /* Screen: On; HSync: On, VSync: On */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask1);
-	    }
-	    break;
-
-	case DPMSModeStandby:
-	    /* Screen: Off; HSync: Off, VSync: On */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
-			~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			    (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS),
-			    ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL,
-			(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS),
-			~mask1);
-	    }
-	    break;
-
-	case DPMSModeSuspend:
-	    /* Screen: Off; HSync: On, VSync: Off */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			(RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
-			~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL,
-			    (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS),
-			    ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL,
-			(RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS),
-			~mask1);
-	    }
-	    break;
-
-	case DPMSModeOff:
-	    /* Screen: Off; HSync: Off, VSync: Off */
-	    if (info->IsSecondary)
-		OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2);
-	    else {
-		if (pRADEONEnt->Controller[1]->binding == 1)
-		    OUTREGP(RADEON_CRTC2_GEN_CNTL, mask2, ~mask2);
-		OUTREGP(RADEON_CRTC_EXT_CNTL, mask1, ~mask1);
-	    }
-	    break;
-	}
-
-	if (PowerManagementMode == DPMSModeOn) {
-  	    output = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
-   	    RADEONDPMSSetOn(output);
-	    if (pRADEONEnt->Controller[1]->binding == 1) {
-	      output = RADEONGetCrtcConnector(pScrn, 2);
-	      RADEONDPMSSetOn(output);
-	    }
-	} else if ((PowerManagementMode == DPMSModeOff) ||
-		   (PowerManagementMode == DPMSModeSuspend) ||
-		   (PowerManagementMode == DPMSModeStandby)) {
-	    output = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
-	    RADEONDPMSSetOff(output);
-	    if (pRADEONEnt->Controller[1]->binding == 1) {
-	        output = RADEONGetCrtcConnector(pScrn, 2);	        
-	        RADEONDPMSSetOff(output);
-	    }
-        }
-    }
-
-#ifdef XF86DRI
-    if (info->CPStarted) DRIUnlock(pScrn->pScreen);
-#endif
-}
-
 static void
 radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
@@ -2469,9 +2360,9 @@ radeon_detect(xf86OutputPtr output)
     RADEONConnectorFindMonitor(pScrn, output);
     if (radeon_output->MonType == MT_UNKNOWN)
 	return XF86OutputStatusUnknown;
-    else if (radeon_output->MonType == MT_NONE)
+    else if (radeon_output->MonType == MT_NONE) {
 	return XF86OutputStatusDisconnected;
-    else
+    } else
 	return XF86OutputStatusConnected;
 
 }
@@ -2850,3 +2741,19 @@ RADEONCrtcFindClosestMode(xf86CrtcPtr cr
     }
     return pMode;
 }
+
+void
+RADEONDisableUnusedFunctions(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int o, c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	if (!crtc->enabled)
+		memset(&crtc->curMode, 0, sizeof(crtc->curMode));
+
+    }
+
+}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 89df328..288ddba 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -7079,7 +7079,6 @@ static Bool RADEONCloseScreen(int scrnIn
 #endif /* USE_XAA */
 
     if (pScrn->vtSema) {
-	RADEONDisplayPowerManagementSet(pScrn, DPMSModeOn, 0);
 	RADEONRestore(pScrn);
     }
 
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 7bf10ae..ac1d567 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -651,7 +651,7 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	    }
 	    crtc->desiredMode = *mode;
 
-	
+	    RADEONDisableUnusedFunctions(pScrn);
 	    RADEONBlank(pScrn);
 	    RADEONRestoreMode(pScrn, &info->ModeReg);
 	    RADEONUnblank(pScrn);
diff-tree aa0e7337815d4daca4df0671768621330b759011 (from 9d37f23aea43b74a7ec640e6b03617c8392e2572)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jan 14 19:17:32 2007 +1100

    use more randr-ish names for variables

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 30c363c..2654296 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -556,7 +556,7 @@ static RADEONMonitorType RADEONDisplayDD
     unsigned long DDCReg;
     RADEONMonitorType MonType = MT_NONE;
     xf86MonPtr* MonInfo = &port->MonInfo;
-    RADEONOutputPrivatePtr pRPort = port->driver_private;
+    RADEONOutputPrivatePtr radeon_output = port->driver_private;
     int i, j;
 
     DDCReg = info->DDCReg;
@@ -651,7 +651,7 @@ static RADEONMonitorType RADEONDisplayDD
 	     * Also for laptop, when X starts with lid closed (no DVI connection)
 	     * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
 	     */
-	    if (pRPort->TMDSType == TMDS_EXT) MonType = MT_DFP;
+	    if (radeon_output->TMDSType == TMDS_EXT) MonType = MT_DFP;
 	    else {
 		if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility)
 		    MonType = MT_DFP;
@@ -1160,15 +1160,15 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     }
 }
 
-static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
     if (info->IsMobility) {
-      switch(pRPort->num) {
+      switch(radeon_output->num) {
       case 0:
 	/* non-DDC laptop panel connected on primary */
 	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
@@ -1189,19 +1189,19 @@ static RADEONMonitorType RADEONPortCheck
 /* 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 pPort)
+void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     
-    if (pRPort->MonType == MT_UNKNOWN) {
-      if ((pRPort->MonType = RADEONDisplayDDCConnected(pScrn,
-						     pRPort->DDCType,
-						     pPort)));
-      else if((pRPort->MonType = RADEONPortCheckNonDDC(pScrn, pPort)));
+    if (radeon_output->MonType == MT_UNKNOWN) {
+      if ((radeon_output->MonType = RADEONDisplayDDCConnected(pScrn,
+						     radeon_output->DDCType,
+						     output)));
+      else if((radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output)));
       else
-	pRPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRPort->DACType));
+	radeon_output->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(radeon_output->DACType));
     }
 }
 
@@ -1310,7 +1310,7 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     unsigned char *RADEONMMIO = info->MMIO;
     Bool head_reversed = FALSE;
     xf86OutputPtr connector;
-    RADEONOutputPrivatePtr pRPort;
+    RADEONOutputPrivatePtr radeon_output;
 
     info->MergeType = MT_NONE;
 
@@ -1390,51 +1390,51 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     if(pRADEONEnt->HasCRTC2) {
 	if(info->IsSecondary) {
 	    connector = RADEONGetCrtcConnector(pScrn, 2);
-	    pRPort = connector->driver_private;
+	    radeon_output = connector->driver_private;
   	    pRADEONEnt->Controller[1]->binding = 2;
 	    if (connector) {
-		info->DisplayType = pRPort->MonType;
+		info->DisplayType = radeon_output->MonType;
 		pScrn->monitor->DDC = connector->MonInfo;
 	    }
 	} else {
 	    connector = RADEONGetCrtcConnector(pScrn, 1);
-	    pRPort = connector->driver_private;
+	    radeon_output = connector->driver_private;
   	    pRADEONEnt->Controller[0]->binding = 1;
 	    if (connector) {
-		info->DisplayType = pRPort->MonType; 
+		info->DisplayType = radeon_output->MonType; 
 		pScrn->monitor->DDC = connector->MonInfo;
 	    }
 	}
 	
 	if(!pRADEONEnt->HasSecondary) {
 	    connector = RADEONGetCrtcConnector(pScrn, 2);
-	    pRPort = connector->driver_private;
+	    radeon_output = connector->driver_private;
 	    if (connector)
-		info->MergeType = pRPort->MonType;
+		info->MergeType = radeon_output->MonType;
 	    if (info->MergeType)
   	    	pRADEONEnt->Controller[1]->binding = 1;
 	} 
     } else {
 	connector = RADEONGetCrtcConnector(pScrn, 1);
-	pRPort = connector->driver_private;
+	radeon_output = connector->driver_private;
 	if (connector) {
-	    if (pRPort->MonType == MT_NONE) 
-		pRPort->MonType = MT_CRT;
-	    info->DisplayType = pRPort->MonType; 
+	    if (radeon_output->MonType == MT_NONE) 
+		radeon_output->MonType = MT_CRT;
+	    info->DisplayType = radeon_output->MonType; 
 	    pScrn->monitor->DDC = connector->MonInfo;
 	}
 	connector = RADEONGetCrtcConnector(pScrn, 2);
-	pRPort = connector->driver_private;
+	radeon_output = connector->driver_private;
 	if (connector)
-	    pRPort->MonType = MT_NONE;
+	    radeon_output->MonType = MT_NONE;
 	pRADEONEnt->Controller[1]->binding = 1;
     }
 
     if (!info->IsSecondary) {
 	connector = RADEONGetCrtcConnector(pScrn, 2);
-	pRPort = connector->driver_private;
+	radeon_output = connector->driver_private;
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head:   Port%d ---- \n", head_reversed?2:1);
-	if (pRPort->MonType != MT_NONE)
+	if (radeon_output->MonType != MT_NONE)
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2);
  	else
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
@@ -1588,23 +1588,23 @@ void RADEONDisableDisplays(ScrnInfoPtr p
 }
 
 /* This is to be used enable/disable displays dynamically */
-void RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable)
+void RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr output, BOOL bEnable)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONSavePtr save = &info->ModeReg;
     unsigned char * RADEONMMIO = info->MMIO;
     unsigned long tmp;
-    RADEONOutputPrivatePtr pRPort;
-    pRPort = pPort->driver_private;
+    RADEONOutputPrivatePtr radeon_output;
+    radeon_output = output->driver_private;
 
     if (bEnable) {
-        if (pRPort->MonType == MT_CRT) {
-            if (pRPort->DACType == DAC_PRIMARY) {
+        if (radeon_output->MonType == MT_CRT) {
+            if (radeon_output->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
                 tmp |= RADEON_CRTC_CRT_ON;                    
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
-            } else if (pRPort->DACType == DAC_TVDAC) {
+            } else if (radeon_output->DACType == DAC_TVDAC) {
                 if (info->ChipFamily == CHIP_FAMILY_R200) {
                     tmp = INREG(RADEON_FP2_GEN_CNTL);
                     tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -1617,20 +1617,20 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
                     save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
                 }
             }
-	    RADEONDacPowerSet(pScrn, bEnable, (pRPort->DACType == DAC_PRIMARY));
-        } else if (pRPort->MonType == MT_DFP) {
-            if (pRPort->TMDSType == TMDS_INT) {
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
+        } else if (radeon_output->MonType == MT_DFP) {
+            if (radeon_output->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
                 tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
                 OUTREG(RADEON_FP_GEN_CNTL, tmp);
                 save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-            } else if (pRPort->TMDSType == TMDS_EXT) {
+            } else if (radeon_output->TMDSType == TMDS_EXT) {
                 tmp = INREG(RADEON_FP2_GEN_CNTL);
                 tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
                 OUTREG(RADEON_FP2_GEN_CNTL, tmp);
                 save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
             }
-        } else if (pRPort->MonType == MT_LCD) {
+        } else if (radeon_output->MonType == MT_LCD) {
             tmp = INREG(RADEON_LVDS_GEN_CNTL);
             tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
@@ -1640,13 +1640,13 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } 
     } else {
-        if (pRPort->MonType == MT_CRT || pRPort->MonType == NONE) {
-            if (pRPort->DACType == DAC_PRIMARY) {
+        if (radeon_output->MonType == MT_CRT || radeon_output->MonType == NONE) {
+            if (radeon_output->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
                 tmp &= ~RADEON_CRTC_CRT_ON;                    
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
-            } else if (pRPort->DACType == DAC_TVDAC) {
+            } else if (radeon_output->DACType == DAC_TVDAC) {
                 if (info->ChipFamily == CHIP_FAMILY_R200) {
                     tmp = INREG(RADEON_FP2_GEN_CNTL);
                     tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -1659,16 +1659,16 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
                     save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
                 }
             }
-	    RADEONDacPowerSet(pScrn, bEnable, (pRPort->DACType == DAC_PRIMARY));
+	    RADEONDacPowerSet(pScrn, bEnable, (radeon_output->DACType == DAC_PRIMARY));
         }
 
-        if (pRPort->MonType == MT_DFP || pRPort->MonType == NONE) {
-            if (pRPort->TMDSType == TMDS_INT) {
+        if (radeon_output->MonType == MT_DFP || radeon_output->MonType == NONE) {
+            if (radeon_output->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
                 tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
                 OUTREG(RADEON_FP_GEN_CNTL, tmp);
                 save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-            } else if (pRPort->TMDSType == TMDS_EXT) {
+            } else if (radeon_output->TMDSType == TMDS_EXT) {
                 tmp = INREG(RADEON_FP2_GEN_CNTL);
                 tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
                 OUTREG(RADEON_FP2_GEN_CNTL, tmp);
@@ -1676,8 +1676,8 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
             }
         }
 
-        if (pRPort->MonType == MT_LCD || 
-            (pRPort->MonType == NONE && pRPort->ConnectorType == CONNECTOR_PROPRIETARY)) {
+        if (radeon_output->MonType == MT_LCD || 
+            (radeon_output->MonType == NONE && radeon_output->ConnectorType == CONNECTOR_PROPRIETARY)) {
 	    unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 	    if (info->IsMobility || info->IsIGP) {
 	    /* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -2084,19 +2084,20 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     }
 }
 
-static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
+static void RADEONDPMSSetOn(xf86OutputPtr output)
 {
+  ScrnInfoPtr pScrn = output->scrn;
   RADEONInfoPtr  info       = RADEONPTR(pScrn);
   RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
   unsigned char *RADEONMMIO = info->MMIO;
   RADEONMonitorType MonType;
   RADEONTmdsType TmdsType;
   RADEONDacType DacType;
-  RADEONOutputPrivatePtr pRPort = pPort->driver_private;
+  RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-  MonType = pRPort->MonType;
-  TmdsType = pRPort->TMDSType;
-  DacType = pRPort->DACType;
+  MonType = radeon_output->MonType;
+  TmdsType = radeon_output->TMDSType;
+  DacType = radeon_output->DACType;
 
   switch(MonType) {
   case MT_LCD:
@@ -2123,8 +2124,9 @@ static void RADEONDPMSSetOn(ScrnInfoPtr 
   }
 }
 
-static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
+static void RADEONDPMSSetOff(xf86OutputPtr output)
 {
+  ScrnInfoPtr pScrn = output->scrn;
   RADEONInfoPtr  info       = RADEONPTR(pScrn);
   RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
   unsigned char *RADEONMMIO = info->MMIO;
@@ -2132,11 +2134,11 @@ static void RADEONDPMSSetOff(ScrnInfoPtr
   RADEONTmdsType TmdsType;
   RADEONDacType DacType;
   unsigned long tmpPixclksCntl;
-  RADEONOutputPrivatePtr pRPort = pPort->driver_private;
+  RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
-  MonType = pRPort->MonType;
-  TmdsType = pRPort->TMDSType;
-  DacType = pRPort->DACType;
+  MonType = radeon_output->MonType;
+  TmdsType = radeon_output->TMDSType;
+  DacType = radeon_output->DACType;
 
   switch(MonType) {
   case MT_LCD:
@@ -2179,7 +2181,7 @@ void RADEONDisplayPowerManagementSet(Scr
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    xf86OutputPtr pPort;
+    xf86OutputPtr output;
     if (!pScrn->vtSema) return;
 
     RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags));
@@ -2260,20 +2262,20 @@ void RADEONDisplayPowerManagementSet(Scr
 	}
 
 	if (PowerManagementMode == DPMSModeOn) {
-  	    pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
-   	    RADEONDPMSSetOn(pScrn, pPort);
+  	    output = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
+   	    RADEONDPMSSetOn(output);
 	    if (pRADEONEnt->Controller[1]->binding == 1) {
-	      pPort = RADEONGetCrtcConnector(pScrn, 2);
-	      RADEONDPMSSetOn(pScrn, pPort);
+	      output = RADEONGetCrtcConnector(pScrn, 2);
+	      RADEONDPMSSetOn(output);
 	    }
 	} else if ((PowerManagementMode == DPMSModeOff) ||
 		   (PowerManagementMode == DPMSModeSuspend) ||
 		   (PowerManagementMode == DPMSModeStandby)) {
-	    pPort = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
-	    RADEONDPMSSetOff(pScrn, pPort);
+	    output = RADEONGetCrtcConnector(pScrn, info->IsSecondary ? 2 : 1);
+	    RADEONDPMSSetOff(output);
 	    if (pRADEONEnt->Controller[1]->binding == 1) {
-	        pPort = RADEONGetCrtcConnector(pScrn, 2);	        
-	        RADEONDPMSSetOff(pScrn, pPort);
+	        output = RADEONGetCrtcConnector(pScrn, 2);	        
+	        RADEONDPMSSetOff(output);
 	    }
         }
     }
@@ -2407,16 +2409,15 @@ static const xf86CrtcFuncsRec radeon_crt
 static void
 radeon_dpms(xf86OutputPtr output, int mode)
 {
-    ScrnInfoPtr	    pScrn = output->scrn;
-    
     switch(mode) {
     case DPMSModeOn:
-      RADEONDPMSSetOn(pScrn, output);
+      RADEONDPMSSetOn(output);
       break;
     case DPMSModeOff:
     case DPMSModeSuspend:
     case DPMSModeStandby:
-      RADEONDPMSSetOff(pScrn, output);
+      RADEONDPMSSetOff(output);
+      break;
     }
 }
 
@@ -2558,12 +2559,12 @@ Bool RADEONAllocatePortInfo(ScrnInfoPtr 
     return TRUE;
 }
 
-void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr pRPort)
+void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr radeon_output)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     RADEONOutputType output;
     if (info->IsAtomBios) {
-	switch(pRPort->ConnectorType) {
+	switch(radeon_output->ConnectorType) {
 	case 0: output = OUTPUT_NONE; break;
 	case 1: output = OUTPUT_VGA; break;
 	case 2:
@@ -2579,7 +2580,7 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
 	}
     }
     else {
-	switch(pRPort->ConnectorType) {
+	switch(radeon_output->ConnectorType) {
 	case 0: output = OUTPUT_NONE; break;
 	case 1: output = OUTPUT_LVDS; break;
 	case 2: output = OUTPUT_VGA; break;
@@ -2590,7 +2591,7 @@ void RADEONSetOutputType(ScrnInfoPtr pSc
 	default: output = OUTPUT_NONE; break;
 	}
     }
-    pRPort->type = output;
+    radeon_output->type = output;
 }
 
 Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index a68b140..89df328 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5233,7 +5233,7 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     RADEONCrtcPrivatePtr pCRTC1 = pRADEONEnt->Controller[0];
     RADEONCrtcPrivatePtr pCRTC2 = pRADEONEnt->Controller[1];
-    xf86OutputPtr pPort;
+    xf86OutputPtr output;
     RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
 
     /* For Non-dual head card, we don't have private field in the Entity */
@@ -5271,9 +5271,9 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	    RADEONRestoreCrtc2Registers(pScrn, restore);
 	    RADEONRestorePLL2Registers(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
-	    pPort = RADEONGetCrtcConnector(pScrn, 2);
-	    if (pPort) {
-		RADEONEnableDisplay(pScrn, pPort, TRUE);
+	    output = RADEONGetCrtcConnector(pScrn, 2);
+	    if (output) {
+		RADEONEnableDisplay(pScrn, output, TRUE);
 		pCRTC2->IsActive = TRUE;
 	    }
 	} else {
@@ -5287,15 +5287,15 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
             RADEONRestoreCrtcRegisters(pScrn, restore);
             RADEONRestorePLLRegisters(pScrn, restore);
 	    RADEONRestoreFPRegisters(pScrn, restore);
-	    pPort = RADEONGetCrtcConnector(pScrn, 1);
-	    if (pPort) {
-		RADEONEnableDisplay(pScrn, pPort, TRUE);
+	    output = RADEONGetCrtcConnector(pScrn, 1);
+	    if (output) {
+		RADEONEnableDisplay(pScrn, output, TRUE);
 		pCRTC1->IsActive = TRUE;
 	    }
 	    if (pCRTC2->binding == 1) {
-		pPort = RADEONGetCrtcConnector(pScrn, 2);
-		if (pPort) {
-		    RADEONEnableDisplay(pScrn, pPort, TRUE);
+		output = RADEONGetCrtcConnector(pScrn, 2);
+		if (output) {
+		    RADEONEnableDisplay(pScrn, output, TRUE);
 		    pCRTC2->IsActive = TRUE;
 		}
 	    }
@@ -5311,15 +5311,15 @@ void RADEONRestoreMode(ScrnInfoPtr pScrn
 	RADEONRestoreCrtcRegisters(pScrn, restore);
 	RADEONRestorePLLRegisters(pScrn, restore);
 	RADEONRestoreFPRegisters(pScrn, restore);
-	pPort = RADEONGetCrtcConnector(pScrn, 1);
-	if (pPort) {
-	    RADEONEnableDisplay(pScrn, pPort, TRUE);
+	output = RADEONGetCrtcConnector(pScrn, 1);
+	if (output) {
+	    RADEONEnableDisplay(pScrn, output, TRUE);
 	    pCRTC1->IsActive = TRUE;
 	}
 	if ((pCRTC2->binding == 1) || pRADEONEnt->HasSecondary) {
-	    pPort = RADEONGetCrtcConnector(pScrn, 2);
-	    if (pPort) {
-		RADEONEnableDisplay(pScrn, pPort, TRUE);
+	    output = RADEONGetCrtcConnector(pScrn, 2);
+	    if (output) {
+		RADEONEnableDisplay(pScrn, output, TRUE);
 		pCRTC2->IsActive = TRUE;
 	    }
 	}
@@ -5989,24 +5989,24 @@ static void RADEONInitDAC2Registers(Scrn
     }
 }
 
-static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr pPort, int crtc_num)
+static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr output, int crtc_num)
 {
     Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE;
-    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
-    if (pRPort->MonType == MT_CRT) {
-	if (pRPort->DACType == DAC_PRIMARY) {
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    if (radeon_output->MonType == MT_CRT) {
+	if (radeon_output->DACType == DAC_PRIMARY) {
 	    RADEONInitDACRegisters(pScrn, save, mode, IsPrimary);
 	} else {
 	    RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary);
 	}
-    } else if (pRPort->MonType == MT_LCD) {
+    } else if (radeon_output->MonType == MT_LCD) {
 	if (crtc_num == 1)
 	    RADEONInitRMXRegisters(pScrn, save, mode);
 	RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary);
-    } else if (pRPort->MonType == MT_DFP) {
+    } else if (radeon_output->MonType == MT_DFP) {
 	if (crtc_num == 1)
 	    RADEONInitRMXRegisters(pScrn, save, mode);
-	if (pRPort->TMDSType == TMDS_INT) {
+	if (radeon_output->TMDSType == TMDS_INT) {
 	    RADEONInitFPRegisters(pScrn, save, mode, IsPrimary);
 	} else {
 	    RADEONInitFP2Registers(pScrn, save, mode, IsPrimary);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 4c8cb35..b97b6bd 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -600,19 +600,19 @@ RADEONProbeOutputModes(xf86OutputPtr out
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    RADEONOutputPrivatePtr pRPort = output->driver_private;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
     DisplayModePtr ddc_modes, mode;
     DisplayModePtr test;
 
     /* force reprobe */
-    pRPort->MonType = MT_UNKNOWN;
+    radeon_output->MonType = MT_UNKNOWN;
 	
     RADEONConnectorFindMonitor(pScrn, output);
     
     /* okay we got DDC info */
     if (output->MonInfo) {
       /* Debug info for now, at least */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", pRPort->num);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
       xf86PrintEDID(output->MonInfo);
       
       ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
@@ -633,7 +633,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
       MonRec fixed_mon;
       DisplayModePtr modes;
       
-      switch(pRPort->MonType) {
+      switch(radeon_output->MonType) {
       case MT_CRT:
       case MT_DFP:
 	
diff-tree 9d37f23aea43b74a7ec640e6b03617c8392e2572 (from 6bd4fe42789c38e7e804826715214ce6badcca6a)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jan 14 19:10:11 2007 +1100

    radeon: move blank/unblank to use randr

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 0819e54..30c363c 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2036,158 +2036,51 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
     RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2);
 }
 
-static void RADEONBlankSet(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONOutputPrivatePtr pRPort;
-    pRPort = pPort->driver_private;
-
-    switch(pRPort->MonType) {
-    case MT_LCD:
-        OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS);
-        break;
-
-    case MT_CRT:
-       if ((info->ChipFamily == CHIP_FAMILY_R200) && 
- 	  (pRPort->DACType == DAC_TVDAC))
-	    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-      
-        break;
-    case MT_DFP:
-        if (pRPort->TMDSType == TMDS_EXT)
-  	    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
-        else
-	    OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN);
-      
-        break;
-    case MT_NONE:
-    default:
-        break;
-    }   
-}
-
-/* Blank screen */
 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 pPort;
+    xf86OutputPtr output;
+    xf86CrtcPtr crtc;
+    int o, c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+    	for (o = 0; o < xf86_config->num_output; o++) {
+	    output = xf86_config->output[o];
+	    if (output->crtc != crtc)
+		continue;
 
-    if (!pRADEONEnt->HasSecondary ||
-	(pRADEONEnt->HasSecondary && !info->IsSwitching) ||
-	(info->IsSwitching && (!info->IsSecondary))) {
-        pPort = RADEONGetCrtcConnector(pScrn, 1);
-	if (pPort)
-	    RADEONBlankSet(pScrn, pPort);
-	OUTREGP (RADEON_CRTC_EXT_CNTL,
-		 RADEON_CRTC_DISPLAY_DIS |
-		 RADEON_CRTC_VSYNC_DIS |
-		 RADEON_CRTC_HSYNC_DIS,
-		 ~(RADEON_CRTC_DISPLAY_DIS |
-		   RADEON_CRTC_VSYNC_DIS | 
-		   RADEON_CRTC_HSYNC_DIS));
-
-	if (!pRADEONEnt->HasCRTC2) return;
-
-	if (pRADEONEnt->Controller[1]->binding == 1) {
-	    pPort = RADEONGetCrtcConnector(pScrn, 2);
-	    if (pPort)
-		RADEONBlankSet(pScrn, pPort);
-	    OUTREGP (RADEON_CRTC2_GEN_CNTL,
-		     RADEON_CRTC2_DISP_DIS |
-		     RADEON_CRTC2_VSYNC_DIS |
-		     RADEON_CRTC2_HSYNC_DIS,
-		     ~(RADEON_CRTC2_DISP_DIS |
-		       RADEON_CRTC2_VSYNC_DIS | 
-		       RADEON_CRTC2_HSYNC_DIS));
+	    output->funcs->dpms(output, DPMSModeOff);
 	}
-    }
-
-    if ((pRADEONEnt->HasSecondary && !info->IsSwitching) ||
-	(info->IsSwitching && info->IsSecondary)) {
-	pPort = RADEONGetCrtcConnector(pScrn, 2);
-	if (pPort)
-	    RADEONBlankSet(pScrn, pPort);
-	OUTREGP (RADEON_CRTC2_GEN_CNTL,
-		 RADEON_CRTC2_DISP_DIS |
-		 RADEON_CRTC2_VSYNC_DIS |
-		 RADEON_CRTC2_HSYNC_DIS,
-		 ~(RADEON_CRTC2_DISP_DIS |
-		   RADEON_CRTC2_VSYNC_DIS | 
-		   RADEON_CRTC2_HSYNC_DIS));
-    }
-}
-
-static void RADEONUnblankSet(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
-{
-    RADEONInfoPtr info = RADEONPTR (pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
-
-    switch(pRPort->MonType) {
-    case MT_LCD:
-        OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS);
-        break;
-    case MT_CRT:
-        if ((info->ChipFamily == CHIP_FAMILY_R200) &&
-	  (pRPort->DACType == DAC_TVDAC))
-	      OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
-        break;
-    case MT_DFP:
-        if (pRPort->TMDSType == TMDS_EXT)
-	    OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
-        else
-	    OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN);
-        break;
-    case MT_NONE:
-    default:
-        break;
+	crtc->funcs->dpms(crtc, DPMSModeOff);
     }
 }
 
-/* Unblank screen */
 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 pPort;
-
-    if (!pRADEONEnt->HasSecondary || (info->IsSwitching  && !info->IsSecondary)) {
-	pPort = RADEONGetCrtcConnector(pScrn, 1);
-	if (pPort)
-	    RADEONUnblankSet(pScrn, pPort);
-	OUTREGP(RADEON_CRTC_EXT_CNTL,
-		0,
-		~(RADEON_CRTC_DISPLAY_DIS |
-		  RADEON_CRTC_VSYNC_DIS |
-		  RADEON_CRTC_HSYNC_DIS));
-
-      if (!pRADEONEnt->HasCRTC2) return;
-
-      if (pRADEONEnt->Controller[1]->binding == 1) {
-	pPort = RADEONGetCrtcConnector(pScrn, 2);
-	if (pPort)
-	    RADEONUnblankSet(pScrn, pPort);
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
-		~(RADEON_CRTC2_DISP_DIS |
-		  RADEON_CRTC2_VSYNC_DIS |
-		  RADEON_CRTC2_HSYNC_DIS));
-      }
-    }
+    xf86OutputPtr output;
+    xf86CrtcPtr crtc;
+    int o, c;
+
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+	if(!crtc->enabled)
+		continue;
+	crtc->funcs->dpms(crtc, DPMSModeOn);
+    	for (o = 0; o < xf86_config->num_output; o++) {
+	    output = xf86_config->output[o];
+	    if (output->crtc != crtc)
+		continue;
 
-    if (info->IsSwitching && info->IsSecondary) {
-	pPort = RADEONGetCrtcConnector(pScrn, 2);
-	if (pPort)
-	    RADEONUnblankSet(pScrn, pPort);
-	OUTREGP(RADEON_CRTC2_GEN_CNTL, 0,
-		~(RADEON_CRTC2_DISP_DIS |
-		  RADEON_CRTC2_VSYNC_DIS |
-		  RADEON_CRTC2_HSYNC_DIS));
+	    output->funcs->dpms(output, DPMSModeOn);
+	}
     }
 }
 
diff-tree 6bd4fe42789c38e7e804826715214ce6badcca6a (from 3949288ed26a91e180b178f4796f2f7e1bdc8ed6)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jan 14 18:38:59 2007 +1100

    disable dpms on/off as it was writing regs before we wanted to

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 15e25eb..0819e54 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2813,6 +2813,7 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
 	goto done;
     }
 
+#if 0
     /* Disable the outputs and CRTCs before setting the mode. */
     for (i = 0; i < xf86_config->num_output; i++) {
 	xf86OutputPtr output = xf86_config->output[i];
@@ -2825,6 +2826,7 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
     }
 
     crtc->funcs->dpms(crtc, DPMSModeOff);
+#endif
 
     /* Set up the DPLL and any output state that needs to adjust or depend
      * on the DPLL.
@@ -2836,6 +2838,7 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
 	    output->funcs->mode_set(output, pMode, adjusted_mode);
     }
 
+#if 0
     /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
     crtc->funcs->dpms(crtc, DPMSModeOn);
     for (i = 0; i < xf86_config->num_output; i++) {
@@ -2843,7 +2846,7 @@ RADEONCrtcSetMode(xf86CrtcPtr crtc, Disp
 	if (output->crtc == crtc)
 	    output->funcs->dpms(output, DPMSModeOn);
     }
-
+#endif
     crtc->curMode = *pMode;
     
     /* XXX free adjustedmode */
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d23fcd9..a68b140 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3222,13 +3222,14 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
      */
     info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
 #endif
-
-    xf86CrtcSetSizeRange (pScrn, 320, 200, 2048, 2048);
     if (!RADEONPreInitVRAM(pScrn))
 	goto fail;
 
     RADEONPreInitColorTiling(pScrn);
 
+    xf86CrtcSetSizeRange (pScrn, 320, 200, 3072, 3072) ;//nfo->MaxSurfaceWidth, info->MaxLines);
+
+
     RADEONPreInitDDC(pScrn);
 
     if (!RADEONPreInitControllers(pScrn, pInt10))
diff-tree 3949288ed26a91e180b178f4796f2f7e1bdc8ed6 (from 25b36a4c56422ad8e25a4a1c55055c2f062213ca)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Jan 14 16:26:39 2007 +1100

    radeon: destroy and fixup LVDS crtc

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 391922e..15e25eb 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2592,6 +2592,8 @@ radeon_get_modes(xf86OutputPtr output)
 static void
 radeon_destroy (xf86OutputPtr output)
 {
+    if(output->driver_private)
+        xfree(output->driver_private);
 }
 
 static const xf86OutputFuncsRec radeon_output_funcs = {
@@ -2719,8 +2721,12 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 	
 	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
 	pRADEONEnt->PortInfo[i]->num = i;
-	
-	pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0) | (1<<1);
+
+	pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0);
+	if (pRADEONEnt->PortInfo[i]->type != OUTPUT_LVDS)
+ 	    pRADEONEnt->pOutput[i]->possible_crtcs |= (1<<1);
+
+	pRADEONEnt->pOutput[i]->possible_clones = 0;
     }
     
 
diff-tree 25b36a4c56422ad8e25a4a1c55055c2f062213ca (from abe8791e4f9fa3e88273897b351387cd33822734)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Jan 5 16:13:16 2007 +1100

    minor randr1.2 fixups

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 8831377..391922e 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2557,6 +2557,11 @@ static void
 radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		  DisplayModePtr adjusted_mode)
 {
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    
+    //    RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], );
 }
 
 static xf86OutputStatus
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 755e1e9..d23fcd9 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6282,7 +6282,7 @@ static Bool RADEONInitCrtc2Registers(Scr
           save->crtc2_offset_cntl &= ~RADEON_CRTC_TILE_EN;
     }
 
-    save->crtc2_pitch  = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
+    save->crtc2_pitch  = ((info->CurrentLayout.displayWidth * pScrn->bitsPerPixel) +
 			  ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
     save->crtc2_pitch |= save->crtc2_pitch << 16;
 
@@ -6498,59 +6498,10 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
     RADEONInfoPtr  info0     = NULL;
     ScrnInfoPtr    pScrn0    = NULL;
 
-#if RADEON_DEBUG
-    if (crtc1) {
-	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	       crtc1->name,
-	       dot_clock,
-	       
-	       crtc1->HDisplay,
-	       crtc1->HSyncStart,
-	       crtc1->HSyncEnd,
-	       crtc1->HTotal,
-	       
-	       crtc1->VDisplay,
-	       crtc1->VSyncStart,
-	       crtc1->VSyncEnd,
-	       crtc1->VTotal,
-	       pScrn->depth,
-	       pScrn->bitsPerPixel);
-	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-	ErrorF("\n");
-	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	       crtc1->name,
-	       dot_clock,
-
-	       crtc1->CrtcHDisplay,
-	       crtc1->CrtcHSyncStart,
-	       crtc1->CrtcHSyncEnd,
-	       crtc1->CrtcHTotal,
-	       
-	       crtc1->CrtcVDisplay,
-	       crtc1->CrtcVSyncStart,
-	       crtc1->CrtcVSyncEnd,
-	       crtc1->CrtcVTotal,
-	       pScrn->depth,
-	       pScrn->bitsPerPixel);
-	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-	ErrorF("\n");
-	info->Flags = crtc1->Flags;
-    }
-#endif
-
-
+    if (crtc_mask & 1)
+      xf86PrintModeline(pScrn, crtc1);
+    if (crtc_mask & 2)
+      xf86PrintModeline(pScrn, crtc2);
 
     RADEONInitMemMapRegisters(pScrn, save, info);
     RADEONInitCommonRegisters(save, info);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index bad19b6..4c8cb35 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -238,7 +238,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 	last->next   = first;
 	first->prev  = last;
 	pScrn->modes = first;
-	RADEONSetPitch(pScrn);
+//	RADEONSetPitch(pScrn);
     }
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -422,7 +422,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 	last->next   = NULL; //first;
 	first->prev  = NULL; //last;
 	*modeList = first;
-	RADEONSetPitch(pScrn);
+	//RADEONSetPitch(pScrn);
     }
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index c6ec8a9..7bf10ae 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -637,7 +637,7 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 
 	radeon_crtc->binding = info->IsSecondary ? 2 : 1;
 	if (mode) {
-
+  	    info->IsSwitching = TRUE;
 	    if (!RADEONCrtcSetMode (crtc, mode, TRUE))
 	    {
 		crtc->enabled = save_enabled;
@@ -655,7 +655,7 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	    RADEONBlank(pScrn);
 	    RADEONRestoreMode(pScrn, &info->ModeReg);
 	    RADEONUnblank(pScrn);
-	
+	    info->IsSwitching = FALSE;
 	}
 	    //	    if (info->DispPriority)
 	    //		RADEONInitDispBandwidth(pScrn);
diff-tree abe8791e4f9fa3e88273897b351387cd33822734 (from 8a9c68c2234b91ed38555f892afdad30b9e4b455)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Jan 5 15:09:43 2007 +1100

    hook up DPMS through xf86

diff --git a/src/radeon_display.c b/src/radeon_display.c
index cf2e6ba..8831377 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -47,6 +47,8 @@
 #include "radeon_version.h"
 #include "radeon_mergedfb.h"
 
+
+void radeon_crtc_load_lut(xf86CrtcPtr crtc);
 extern int getRADEONEntityIndex(void);
 
 const char *MonTypeName[7] = {
@@ -2391,7 +2393,47 @@ void RADEONDisplayPowerManagementSet(Scr
 static void
 radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
 {
+  int mask;
+  ScrnInfoPtr pScrn = crtc->scrn;
+  RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+  RADEONInfoPtr info = RADEONPTR(pScrn);
+  unsigned char *RADEONMMIO = info->MMIO;
+    
+  mask = radeon_crtc->crtc_id ? (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS | RADEON_CRTC2_HSYNC_DIS) : (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS | RADEON_CRTC_VSYNC_DIS);
 
+  switch(mode) {
+  case DPMSModeOn:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, 0, ~mask);
+    }
+    break;
+  case DPMSModeStandby:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_HSYNC_DIS), ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_HSYNC_DIS), ~mask);
+    }
+    break;
+  case DPMSModeSuspend:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, (RADEON_CRTC2_DISP_DIS | RADEON_CRTC2_VSYNC_DIS), ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, (RADEON_CRTC_DISPLAY_DIS | RADEON_CRTC_VSYNC_DIS), ~mask);
+    }
+    break;
+  case DPMSModeOff:
+    if (radeon_crtc->crtc_id) {
+      OUTREGP(RADEON_CRTC2_GEN_CNTL, mask, ~mask);
+    } else {
+      OUTREGP(RADEON_CRTC_EXT_CNTL, mask, ~mask);
+    }
+    break;
+  }
+  
+  if (mode != DPMSModeOff)
+    radeon_crtc_load_lut(crtc);  
 }
 
 static Bool
@@ -2474,6 +2516,15 @@ radeon_dpms(xf86OutputPtr output, int mo
 {
     ScrnInfoPtr	    pScrn = output->scrn;
     
+    switch(mode) {
+    case DPMSModeOn:
+      RADEONDPMSSetOn(pScrn, output);
+      break;
+    case DPMSModeOff:
+    case DPMSModeSuspend:
+    case DPMSModeStandby:
+      RADEONDPMSSetOff(pScrn, output);
+    }
 }
 
 static void
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 6130235..755e1e9 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3266,6 +3266,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     if (!RADEONPreInitXv(pScrn))                 goto fail;
 
+   info->CurrentLayout.displayWidth = pScrn->displayWidth;
 
     if (!xf86RandR12PreInit (pScrn))
     {
@@ -4296,11 +4297,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 
     /* Init DPMS */
     RADEONTRACE(("Initializing DPMS\n"));
-#if 1
-    xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
-#else
     xf86DPMSInit(pScreen, xf86DPMSSet, 0);
-#endif
 
     RADEONTRACE(("Initializing Cursor\n"));
 
@@ -7001,7 +6998,8 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 	for (i = 0; i < xf86_config->num_crtc; i++)
 	{
 	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
-	    
+	    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+	    radeon_crtc->binding = info->IsSecondary ? 2 : 1;
 	    /* Mark that we'll need to re-set the mode for sure */
 	    memset(&crtc->curMode, 0, sizeof(crtc->curMode));
 	    if (!crtc->desiredMode.CrtcHDisplay)
diff-tree 8a9c68c2234b91ed38555f892afdad30b9e4b455 (from d6a2b8aeb5a97ee907fd45b574bc6e4ab4b3aede)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Jan 5 15:09:15 2007 +1100

    set binding for new heads

diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 29af262..c6ec8a9 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -629,12 +629,13 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
     if (changed) {
 	RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
 	RADEONInfoPtr  info = RADEONPTR(pScrn);
-	RADEONCrtcPrivatePtr pRcrtc;
+	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 	crtc->enabled = mode != NULL;
 	
 	if (info->accelOn)
 	    RADEON_SYNC(info, pScrn);
-	
+
+	radeon_crtc->binding = info->IsSecondary ? 2 : 1;
 	if (mode) {
 
 	    if (!RADEONCrtcSetMode (crtc, mode, TRUE))
diff-tree d6a2b8aeb5a97ee907fd45b574bc6e4ab4b3aede (from ef1d36e56dec1fec37cee2dfd9cb5bf8ce2c485c)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Jan 5 09:33:54 2007 +1100

    fix LUT

diff --git a/src/radeon.h b/src/radeon.h
index 04b51c4..4d3f96d 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -919,7 +919,7 @@ extern void RADEONSetPitch (ScrnInfoPtr 
 
 extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
 			DisplayModePtr crtc2, int crtc_mask,
-			RADEONSavePtr save);
+			RADEONSavePtr save, RADEONMonitorType montype);
 
 #ifdef XF86DRI
 #ifdef USE_XAA
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 44848ef..cf2e6ba 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2412,20 +2412,60 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
     
     switch (radeon_crtc->crtc_id) {
     case 0: 
-      RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg);
+      RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg, MT_CRT);
       break;
     case 1: 
-      RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg);
+      RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg, MT_CRT);
       break;
     }
 }
 
+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;
+    int i;
+
+    if (!crtc->enabled)
+	return;
+
+    PAL_SELECT(radeon_crtc->crtc_id);
+
+    for (i = 0; i < 256; i++) {
+	OUTPAL(i, radeon_crtc->lut_r[i], radeon_crtc->lut_g[i], radeon_crtc->lut_b[i]);
+    }
+}
+
+
+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++) {
+	radeon_crtc->lut_r[i] = red[i] >> 8;
+	radeon_crtc->lut_g[i] = green[i] >> 8;
+	radeon_crtc->lut_b[i] = blue[i] >> 8;
+    }
+
+    radeon_crtc_load_lut(crtc);
+}
+
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
     .dpms = radeon_crtc_dpms,
     .save = NULL, /* XXX */
     .restore = NULL, /* XXX */
     .mode_fixup = radeon_crtc_mode_fixup,
     .mode_set = radeon_crtc_mode_set,
+    .gamma_set = radeon_crtc_gamma_set,
     .destroy = NULL, /* XXX */
 };
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 3b1b004..6130235 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3334,9 +3334,12 @@ static void RADEONLoadPalette(ScrnInfoPt
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int            i;
-    int            idx, j;
+    int            index, j;
     unsigned char  r, g, b;
+    CARD16 lut_r[256], lut_g[256], lut_b[256];
+    int c;
 
 #ifdef XF86DRI
     if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
@@ -3348,6 +3351,60 @@ static void RADEONLoadPalette(ScrnInfoPt
     if (info->FBDev) {
 	fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual);
     } else {
+
+      for (c = 0; c < xf86_config->num_crtc; c++) {
+	  xf86CrtcPtr crtc = xf86_config->crtc[c];
+	  RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+
+	  for (i = 0 ; i < 256; i++) {
+	      lut_r[i] = radeon_crtc->lut_r[i] << 8;
+	      lut_g[i] = radeon_crtc->lut_g[i] << 8;
+	      lut_b[i] = radeon_crtc->lut_b[i] << 8;
+	  }
+
+	  switch (info->CurrentLayout.depth) {
+	  case 15:
+	      for (i = 0; i < numColors; i++) {
+		  index = indices[i];
+		  for (j = 0; j < 8; j++) {
+		      lut_r[index * 8 + j] = colors[index].red << 8;
+		      lut_g[index * 8 + j] = colors[index].green << 8;
+		      lut_b[index * 8 + j] = colors[index].blue << 8;
+		  }
+	      }
+	  case 16:
+	      for (i = 0; i < numColors; i++) {
+		  index = indices[i];
+		  
+		  if (i <= 31) {
+		      for (j = 0; j < 8; j++) {
+			  lut_r[index * 8 + j] = colors[index].red << 8;
+			  lut_b[index * 8 + j] = colors[index].blue << 8;
+		      }
+		  }
+		  
+		  for (j = 0; j < 4; j++) {
+		      lut_g[index * 4 + j] = colors[index].green << 8;
+		  }
+	      }
+	  default:
+	      for (i = 0; i < numColors; i++) {
+		  index = indices[i];
+		  lut_r[index] = colors[index].red << 8;
+		  lut_g[index] = colors[index].green << 8;
+		  lut_b[index] = colors[index].blue << 8;
+	      } 
+	      break;
+	  }
+
+	      /* Make the change through RandR */
+#ifdef RANDR_12_INTERFACE
+      RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
+#else
+      crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+#endif
+      }
+#if 0
 	/* If the second monitor is connected, we also need to deal with
 	 * the secondary palette
 	 */
@@ -3451,6 +3508,7 @@ static void RADEONLoadPalette(ScrnInfoPt
 		}
 	    }
 	}
+#endif
     }
 
 #ifdef XF86DRI
@@ -4118,6 +4176,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     }
 #endif
 
+    pScrn->vtSema = TRUE;
     if (info->FBDev) {
 	unsigned char *RADEONMMIO = info->MMIO;
 
@@ -4237,7 +4296,11 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 
     /* Init DPMS */
     RADEONTRACE(("Initializing DPMS\n"));
+#if 1
     xf86DPMSInit(pScreen, RADEONDisplayPowerManagementSet, 0);
+#else
+    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+#endif
 
     RADEONTRACE(("Initializing Cursor\n"));
 
@@ -4276,16 +4339,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 	xf86DrvMsg(scrnIndex, X_INFO, "Using software cursor\n");
     }
 
-    /* Colormap setup */
-    RADEONTRACE(("Initializing color map\n"));
-    if (!miCreateDefColormap(pScreen)) return FALSE;
-    if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
-			     RADEONLoadPalette, NULL,
-			     CMAP_PALETTED_TRUECOLOR
-#if 0 /* This option messes up text mode! (eich at suse.de) */
-			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
-#endif
-			     | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
+
 
     /* DGA setup */
     RADEONTRACE(("Initializing DGA\n"));
@@ -4330,6 +4384,17 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     info->CreateScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = RADEONCreateScreenResources;
 
+    /* Colormap setup */
+    RADEONTRACE(("Initializing color map\n"));
+    if (!miCreateDefColormap(pScreen)) return FALSE;
+    if (!xf86HandleColormaps(pScreen, 256, info->dac6bits ? 6 : 8,
+			     RADEONLoadPalette, NULL,
+			     CMAP_PALETTED_TRUECOLOR
+#if 0 /* This option messes up text mode! (eich at suse.de) */
+			     | CMAP_LOAD_EVEN_IF_OFFSCREEN
+#endif
+			     | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE;
+
     /* Note unused options */
     if (serverGeneration == 1)
 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -6428,7 +6493,7 @@ static void RADEONInitPalette(RADEONSave
 /* Define registers for a requested video mode */
 Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
 		 DisplayModePtr crtc2, int crtc_mask,
-		 RADEONSavePtr save)
+		 RADEONSavePtr save, RADEONMonitorType montype)
 {
     RADEONInfoPtr  info      = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
@@ -6526,7 +6591,7 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
 	dot_clock = crtc2->Clock/1000.0;
 	if (!RADEONInitCrtc2Registers(pScrn, save, crtc2, info))
 	    return FALSE;
-	RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->DisplayType != MT_CRT);
+	RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, montype != MT_CRT);
 	/* Make sure primary has the same copy */
 	if (pRADEONEnt->HasSecondary)
 	  memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));
@@ -6545,7 +6610,7 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
         }
         RADEONInitCrtc2Registers(pScrn, save, crtc2, info);
         dot_clock = crtc2->Clock / 1000.0;
-        RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->MergeType != MT_CRT);
+        RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, montype != MT_CRT);
 	break;
     default:
 	return FALSE;
@@ -6561,12 +6626,12 @@ static Bool RADEONInit(ScrnInfoPtr pScrn
     RADEONInfoPtr info = RADEONPTR(pScrn);
 
     if (info->IsSecondary) {
-        return RADEONInit2(pScrn, NULL, mode, 2, save);
+        return RADEONInit2(pScrn, NULL, mode, 2, save, info->DisplayType);
     } else if (info->MergedFB) {
         return RADEONInit2(pScrn, ((RADEONMergedDisplayModePtr)mode->Private)->CRT1,
-			   ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, 3, save);
+			   ((RADEONMergedDisplayModePtr)mode->Private)->CRT2, 3, save, info->MergeType);
     } else {
-        return RADEONInit2(pScrn, mode, NULL, 1, save);
+        return RADEONInit2(pScrn, mode, NULL, 1, save, info->DisplayType);
     }
 }
 
@@ -6931,6 +6996,8 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
     } else {
 	int i;
+
+	pScrn->vtSema = TRUE;
 	for (i = 0; i < xf86_config->num_crtc; i++)
 	{
 	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 817a40b..acdd7d3 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -120,6 +120,8 @@ typedef struct _RADEONCrtcPrivateRec {
     int binding;
     Bool IsActive;
     Bool IsUsed;
+    /* Lookup table values to be set when the CRTC is enabled */
+    CARD8 lut_r[256], lut_g[256], lut_b[256];
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct _RADEONOutputPrivateRec {
diff-tree ef1d36e56dec1fec37cee2dfd9cb5bf8ce2c485c (from 55aa832157bdebcba2d58896777942d108c352b0)
Author: Roland Scheidegger <sroland at tungstengraphics.com>
Date:   Wed Jan 3 15:56:23 2007 +0100

    fix uninitialized mode regs (bug 9495)
    
    Since the reorganization of the mode setting code, the mode registers relying
    on state already set (by bios) were not read, thus clearing out all bits the
    driver does not touch. At the very least, this could lead to completely
    nonfunctional to misbehaving dvi output (see bug 9495). Fix this by using the
    SavedReg values, which also makes it more obvious that those are bits which
    were not set by the driver previously, but come from register readback.
    (cherry picked from 9506f7015a1e442f4ca0bd3bfae555ec7e8a5f37 commit)

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 245f216..3b1b004 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5653,7 +5653,8 @@ static void RADEONInitTvDacCntl(ScrnInfo
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     if (info->ChipFamily == CHIP_FAMILY_R420 ||
 	info->ChipFamily == CHIP_FAMILY_RV410) {
-	save->tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
+	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 |
@@ -5661,13 +5662,15 @@ static void RADEONInitTvDacCntl(ScrnInfo
 			       R420_TV_DAC_GDACPD |
 			       R420_TV_DAC_TVENABLE);
     } else {
-	save->tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
+	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 |
@@ -5680,7 +5683,7 @@ static void RADEONInitFPRegisters(ScrnIn
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int i;
-    CARD32 tmp = save->tmds_pll_cntl & 0xfffff;
+    CARD32 tmp = info->SavedReg.tmds_pll_cntl & 0xfffff;
 
     for (i=0; i<4; i++) {
 	if (info->tmds_pll[i].freq == 0) break;
@@ -5694,19 +5697,21 @@ static void RADEONInitFPRegisters(ScrnIn
 	if (tmp & 0xfff00000)
 	    save->tmds_pll_cntl = tmp;
 	else {
-	    save->tmds_pll_cntl &= 0xfff00000;
+	    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 &= ~(RADEON_TMDS_TRANSMITTER_PLLRST);
+    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 |= (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
+    save->fp_gen_cntl = info->SavedReg.fp_gen_cntl |
+			 (RADEON_FP_CRTC_DONT_SHADOW_VPAR |
 			  RADEON_FP_CRTC_DONT_SHADOW_HEND );
 
     if (pScrn->rgbBits == 8)
@@ -5740,9 +5745,11 @@ static void RADEONInitFP2Registers(ScrnI
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
 
     if (pScrn->rgbBits == 8) 
-	save->fp2_gen_cntl |= RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
+	save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
+				RADEON_FP2_PANEL_FORMAT; /* 24 bit format, */
     else
-	save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
+	save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+				~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
 
     if (IsPrimary) {
         if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
@@ -5782,11 +5789,14 @@ static void RADEONInitFP2Registers(ScrnI
 static void RADEONInitLVDSRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
 				    DisplayModePtr mode, BOOL IsPrimary)
 {
-
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+/* XXX saved but never used??? */
     if (IsPrimary)
-	save->lvds_gen_cntl &= ~RADEON_LVDS_SEL_CRTC2;
+	save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl &
+				~RADEON_LVDS_SEL_CRTC2;
     else
-	save->lvds_gen_cntl |= RADEON_LVDS_SEL_CRTC2;
+	save->lvds_gen_cntl = info->SavedReg.lvds_gen_cntl |
+				RADEON_LVDS_SEL_CRTC2;
 
 }
 
@@ -5810,9 +5820,11 @@ static void RADEONInitRMXRegisters(ScrnI
 	Vratio = (float)yres/(float)info->PanelYRes;
     }
 
-    save->fp_vert_stretch &= RADEON_VERT_STRETCH_RESERVED;
-    save->fp_horz_stretch &= (RADEON_HORZ_FP_LOOP_STRETCH |
-			      RADEON_HORZ_AUTO_RATIO_INC);
+	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);
@@ -5843,9 +5855,10 @@ static void RADEONInitDACRegisters(ScrnI
 
     if (IsPrimary) {
 	if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK;
+            save->disp_output_cntl = info->SavedReg.disp_output_cntl &
+					~RADEON_DISP_DAC_SOURCE_MASK;
         } else {
-            save->dac2_cntl &= ~(RADEON_DAC2_DAC_CLK_SEL);
+            save->dac2_cntl = info->SavedReg.dac2_cntl & ~(RADEON_DAC2_DAC_CLK_SEL);
         }
         save->dac_cntl = (RADEON_DAC_MASK_ALL
 			  | RADEON_DAC_VGA_ADR_EN
@@ -5853,10 +5866,11 @@ static void RADEONInitDACRegisters(ScrnI
 
     } else {
         if ((info->ChipFamily == CHIP_FAMILY_R200) || IS_R300_VARIANT) {
-            save->disp_output_cntl &= ~RADEON_DISP_DAC_SOURCE_MASK;
+            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 |= RADEON_DAC2_DAC_CLK_SEL;
+            save->dac2_cntl = info->SavedReg.dac2_cntl | RADEON_DAC2_DAC_CLK_SEL;
         }
     }
 }
@@ -5870,27 +5884,33 @@ static void RADEONInitDAC2Registers(Scrn
     RADEONInitTvDacCntl(pScrn, save);
 
     if (IsPrimary) {
-	/*save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;*/
-        save->dac2_cntl |= RADEON_DAC2_DAC2_CLK_SEL;
+	/*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 &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+            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 &= ~(R200_FP2_SOURCE_SEL_MASK |
+	    save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl &
+				  ~(R200_FP2_SOURCE_SEL_MASK |
 				    RADEON_FP2_DVO_RATE_SEL_SDR);
-            /*save->fp2_gen_cntl |= (RADEON_FP2_ON |
+            /*save->fp2_gen_cntl = info->SavedReg.fp2_gen_cntl |
+				    (RADEON_FP2_ON |
 				     RADEON_FP2_BLANK_EN |
-                                     RADEON_FP2_DVO_EN);*/
+				     RADEON_FP2_DVO_EN);*/
 	} else {
-            save->disp_hw_debug |= RADEON_CRT2_DISP1_SEL;
+            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 |= RADEON_DAC2_DAC2_CLK_SEL;
-            save->disp_output_cntl &= ~RADEON_DISP_TVDAC_SOURCE_MASK;
+            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 &= ~(R200_FP2_SOURCE_SEL_MASK |
+	    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 |
@@ -5899,8 +5919,9 @@ static void RADEONInitDAC2Registers(Scrn
 	    /*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 |= RADEON_DAC2_DAC2_CLK_SEL;
-            save->disp_hw_debug &= ~RADEON_CRT2_DISP1_SEL;
+            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;
         }
     }
 }
@@ -6083,8 +6104,10 @@ static Bool RADEONInitCrtcRegisters(Scrn
     */
     if (!info->IsSwitching) {
 	save->fp_gen_cntl = 0;
-	save->fp_vert_stretch &= RADEON_VERT_STRETCH_RESERVED;
-	save->fp_horz_stretch &= (RADEON_HORZ_FP_LOOP_STRETCH |
+	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);
     }
 
diff-tree 55aa832157bdebcba2d58896777942d108c352b0 (from 4f8a7cafdc77e98dc44f9eced876560b1ee01117)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 17:57:31 2007 +1100

    fix cursor handling

diff --git a/src/radeon_cursor.c b/src/radeon_cursor.c
index a45198a..74289e4 100644
--- a/src/radeon_cursor.c
+++ b/src/radeon_cursor.c
@@ -31,7 +31,7 @@
 #endif
 
 #define RADEONCTRACE(x)
-/* #define RADEONCTRACE(x) RADEONTRACE(x)  */
+/*#define RADEONCTRACE(x) RADEONTRACE(x) */
 
 /*
  * Authors:
@@ -104,6 +104,42 @@ static CARD32 mono_cursor_color[] = {
 
 #endif
 
+static void
+RADEONCrtcCursor(xf86CrtcPtr crtc,  Bool force)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    int crtc_id = radeon_crtc->crtc_id;
+    RADEONInfoPtr      info       = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    Bool		show;
+    unsigned char     *RADEONMMIO = info->MMIO;
+    CARD32 save1 = 0, save2 = 0;
+    if (!crtc->enabled)
+	return;
+
+    
+    show = crtc->cursorInRange;
+    if (show && (force || !crtc->cursorShown))
+    {
+	if (crtc_id == 0) 
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, RADEON_CRTC_CUR_EN,
+		    ~RADEON_CRTC_CUR_EN);
+	else if (crtc_id == 1)
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, RADEON_CRTC2_CUR_EN,
+		    ~RADEON_CRTC2_CUR_EN);
+	crtc->cursorShown = TRUE;
+    } else if (!show && (force || crtc->cursorShown)) {
+
+	if (crtc_id == 0)
+	    OUTREGP(RADEON_CRTC_GEN_CNTL, 0, ~RADEON_CRTC_CUR_EN);
+	else if (crtc_id == 1)
+	    OUTREGP(RADEON_CRTC2_GEN_CNTL, 0, ~RADEON_CRTC2_CUR_EN);
+
+	crtc->cursorShown = FALSE;
+    }
+    
+}    
 
 /* Set cursor foreground and background colors */
 static void RADEONSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
@@ -143,6 +179,92 @@ static void RADEONSetCursorColors(ScrnIn
     info->cursor_bg = bg;
 }
 
+static void
+RADEONRandrSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONInfoPtr      info       = RADEONPTR(pScrn);
+    unsigned char     *RADEONMMIO = info->MMIO;
+    xf86CursorInfoPtr  cursor     = info->cursor;
+    Bool inrange;
+    int temp;
+    int oldx = x, oldy = y;
+    int hotspotx = 0, hotspoty = 0;
+    int c;
+    int xorigin, yorigin;
+    int		       stride     = 256;
+
+    oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
+    oldy += pScrn->frameY0;
+
+    x = oldx;
+    y = oldy;
+
+    for (c = 0 ; c < xf86_config->num_crtc; c++) {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	DisplayModePtr mode = &crtc->curMode;
+	int thisx = x - crtc->x;
+	int thisy = y - crtc->y;
+	
+	if (!crtc->enabled)
+	    continue;
+
+	/*
+	 * There is a screen display problem when the cursor position is set
+	 * wholely outside of the viewport.  We trap that here, turning the
+	 * cursor off when that happens, and back on when it comes back into
+	 * the viewport.
+	 */
+	inrange = TRUE;
+	if (thisx >= mode->HDisplay ||
+	    thisy >= mode->VDisplay ||
+	    thisx <= -cursor->MaxWidth || thisy <= -cursor->MaxHeight) 
+	{
+	    inrange = FALSE;
+	    thisx = 0;
+	    thisy = 0;
+	}
+
+	temp = 0;
+	xorigin = 0;
+	yorigin = 0;
+	if (thisx < 0) xorigin = -thisx+1;
+	if (thisy < 0) yorigin = -thisy+1;
+	if (xorigin >= cursor->MaxWidth) xorigin = cursor->MaxWidth - 1;
+	if (yorigin >= cursor->MaxHeight) yorigin = cursor->MaxHeight - 1;
+
+	temp |= (xorigin ? 0 : thisx) << 16;
+	temp |= (yorigin ? 0 : thisy);
+
+	if (c == 0) {
+	    OUTREG(RADEON_CUR_HORZ_VERT_OFF,  (RADEON_CUR_LOCK
+					       | (xorigin << 16)
+					       | yorigin));
+	    OUTREG(RADEON_CUR_HORZ_VERT_POSN, (RADEON_CUR_LOCK |
+					       temp));
+	    RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+			  info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	    OUTREG(RADEON_CUR_OFFSET,
+		   info->cursor_offset + pScrn->fbOffset + yorigin * stride);
+	}
+	if (c == 1) {
+	    OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
+						| (xorigin << 16)
+						| yorigin));
+	    OUTREG(RADEON_CUR2_HORZ_VERT_POSN, (RADEON_CUR2_LOCK |
+						temp));
+	    RADEONCTRACE(("cursor_offset2: 0x%x, yorigin: %d, stride: %d, temp %08X\n",
+			  info->cursor_offset + pScrn->fbOffset, yorigin, stride, temp));
+	    OUTREG(RADEON_CUR2_OFFSET,
+		   info->cursor_offset + pScrn->fbOffset + yorigin * stride);
+	}
+	crtc->cursorInRange = inrange;
+
+	RADEONCrtcCursor(crtc, FALSE);
+    }
+
+
+}
 
 /* Set cursor position to (x,y) with offset into cursor bitmap at
  * (xorigin,yorigin)
@@ -165,6 +287,8 @@ static void RADEONSetCursorPosition(Scrn
 
     RADEONCTRACE(("RADEONSetCursorPosition\n"));
 
+    
+#if 0
     if (x < 0)                        xorigin = -x+1;
     if (y < 0)                        yorigin = -y+1;
     if (y > total_y)                  y       = total_y;
@@ -182,7 +306,7 @@ static void RADEONSetCursorPosition(Scrn
 	RADEONCTRACE(("cursor_offset: 0x%x, yorigin: %d, stride: %d\n",
 		     info->cursor_offset + pScrn->fbOffset, yorigin, stride));
 	OUTREG(RADEON_CUR_OFFSET,
-		info->cursor_offset + pScrn->fbOffset + yorigin * stride);
+	       info->cursor_offset + pScrn->fbOffset + yorigin * stride);
     } else {
 	OUTREG(RADEON_CUR2_HORZ_VERT_OFF,  (RADEON_CUR2_LOCK
 					    | (xorigin << 16)
@@ -193,7 +317,7 @@ static void RADEONSetCursorPosition(Scrn
 	OUTREG(RADEON_CUR2_OFFSET,
 	       info->cursor_offset + pScrn->fbOffset + yorigin * stride);
     }
-
+#endif
 }
 
 /* Copy cursor image from `image' to video memory.  RADEONSetCursorPosition
@@ -203,6 +327,7 @@ static void RADEONLoadCursorImage(ScrnIn
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     CARD8         *s          = (CARD8 *)(pointer)image;
     CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
     CARD32         save1      = 0;
@@ -216,9 +341,15 @@ static void RADEONLoadCursorImage(ScrnIn
 	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
 	save1 |= (CARD32) (2 << 20);
 	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
+
+	if (pRADEONEnt->HasCRTC2) {
+	    save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
+	    save2 |= (CARD32) (2 << 20);
+	    OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
+	}
     }
 
-    if (info->IsSecondary || info->MergedFB) {
+    if (info->IsSecondary) {
 	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
 	save2 |= (CARD32) (2 << 20);
 	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
@@ -311,6 +442,7 @@ static Bool RADEONUseHWCursorARGB (Scree
 static void RADEONLoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32        *d          = (CARD32 *)(pointer)(info->FB + info->cursor_offset + pScrn->fbOffset);
     int            x, y, w, h;
@@ -325,9 +457,15 @@ static void RADEONLoadCursorARGB (ScrnIn
 	save1 = INREG(RADEON_CRTC_GEN_CNTL) & ~(CARD32) (3 << 20);
 	save1 |= (CARD32) (2 << 20);
 	OUTREG(RADEON_CRTC_GEN_CNTL, save1 & (CARD32)~RADEON_CRTC_CUR_EN);
+
+	if (pRADEONEnt->HasCRTC2) {
+	    save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
+	    save2 |= (CARD32) (2 << 20);
+	    OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
+	}
     }
 
-    if (info->IsSecondary || info->MergedFB) {
+    if (info->IsSecondary) {
 	save2 = INREG(RADEON_CRTC2_GEN_CNTL) & ~(CARD32) (3 << 20);
 	save2 |= (CARD32) (2 << 20);
 	OUTREG(RADEON_CRTC2_GEN_CNTL, save2 & (CARD32)~RADEON_CRTC2_CUR_EN);
@@ -401,7 +539,7 @@ Bool RADEONCursorInit(ScreenPtr pScreen)
 				 | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1);
 
     cursor->SetCursorColors   = RADEONSetCursorColors;
-    cursor->SetCursorPosition = RADEONSetCursorPosition;
+    cursor->SetCursorPosition = RADEONRandrSetCursorPosition;
     cursor->LoadCursorImage   = RADEONLoadCursorImage;
     cursor->HideCursor        = RADEONHideCursor;
     cursor->ShowCursor        = RADEONShowCursor;
diff-tree 4f8a7cafdc77e98dc44f9eced876560b1ee01117 (from 52f749c8a613ee316044abe82156ee270412ced8)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 16:23:39 2007 +1100

    hook up crtc modesetting

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7e8f76e..44848ef 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2079,7 +2079,7 @@ void RADEONBlank(ScrnInfoPtr pScrn)
 	(info->IsSwitching && (!info->IsSecondary))) {
         pPort = RADEONGetCrtcConnector(pScrn, 1);
 	if (pPort)
-	  RADEONBlankSet(pScrn, pPort);
+	    RADEONBlankSet(pScrn, pPort);
 	OUTREGP (RADEON_CRTC_EXT_CNTL,
 		 RADEON_CRTC_DISPLAY_DIS |
 		 RADEON_CRTC_VSYNC_DIS |
@@ -2159,11 +2159,11 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
 	pPort = RADEONGetCrtcConnector(pScrn, 1);
 	if (pPort)
 	    RADEONUnblankSet(pScrn, pPort);
-      OUTREGP(RADEON_CRTC_EXT_CNTL,
-	      0,
-	      ~(RADEON_CRTC_DISPLAY_DIS |
-		RADEON_CRTC_VSYNC_DIS |
-		RADEON_CRTC_HSYNC_DIS));
+	OUTREGP(RADEON_CRTC_EXT_CNTL,
+		0,
+		~(RADEON_CRTC_DISPLAY_DIS |
+		  RADEON_CRTC_VSYNC_DIS |
+		  RADEON_CRTC_HSYNC_DIS));
 
       if (!pRADEONEnt->HasCRTC2) return;
 
@@ -2407,6 +2407,17 @@ radeon_crtc_mode_set(xf86CrtcPtr crtc, D
 {
     ScrnInfoPtr pScrn = crtc->scrn;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    
+    switch (radeon_crtc->crtc_id) {
+    case 0: 
+      RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg);
+      break;
+    case 1: 
+      RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg);
+      break;
+    }
 }
 
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
@@ -2455,8 +2466,6 @@ static void
 radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
 		  DisplayModePtr adjusted_mode)
 {
-    
-
 }
 
 static xf86OutputStatus
@@ -2555,6 +2564,7 @@ Bool RADEONAllocatePortInfo(ScrnInfoPtr 
 	if (!pRADEONEnt->PortInfo[i])
 	    return FALSE;
     }
+    return TRUE;
 }
 
 void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr pRPort)
@@ -2633,3 +2643,211 @@ xf86OutputPtr RADEONGetCrtcConnector(Scr
       return pRADEONEnt->pOutput[1];
     return NULL;
 }
+
+
+void
+RADEONCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    RADEONCrtcPrivatePtr	radeon_crtc = crtc->driver_private;
+    int crtc_id = radeon_crtc->crtc_id;
+    unsigned long Start;
+    
+    RADEONDoAdjustFrame(pScrn, x, y, crtc_id);
+
+    crtc->x = x;
+    crtc->y = y;
+}
+
+Bool
+RADEONCrtcInUse(xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int	i;
+    
+    for (i = 0; i < xf86_config->num_output; i++)
+	if (xf86_config->output[i]->crtc == crtc)
+	    return TRUE;
+    return FALSE;
+}
+
+Bool
+RADEONCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);  
+    DisplayModePtr adjusted_mode;
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    int i , ret;
+    /* XXX: curMode */
+
+    adjusted_mode = xf86DuplicateMode(pMode);
+    
+    crtc->enabled = RADEONCrtcInUse (crtc);
+
+    if (!crtc->enabled) {
+      return TRUE;
+    }
+
+    /* Pass our mode to the outputs and the CRTC to give them a chance to
+     * adjust it according to limitations or output properties, and also
+     * a chance to reject the mode entirely.
+     */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+
+	if (output->crtc != crtc)
+	    continue;
+
+	if (!output->funcs->mode_fixup(output, pMode, adjusted_mode)) {
+	    ret = FALSE;
+	    goto done;
+	}
+    }
+
+    if (!crtc->funcs->mode_fixup(crtc, pMode, adjusted_mode)) {
+	ret = FALSE;
+	goto done;
+    }
+
+    /* Disable the outputs and CRTCs before setting the mode. */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+
+	if (output->crtc != crtc)
+	    continue;
+
+	/* Disable the output as the first thing we do. */
+	output->funcs->dpms(output, DPMSModeOff);
+    }
+
+    crtc->funcs->dpms(crtc, DPMSModeOff);
+
+    /* Set up the DPLL and any output state that needs to adjust or depend
+     * on the DPLL.
+     */
+    crtc->funcs->mode_set(crtc, pMode, adjusted_mode);
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc)
+	    output->funcs->mode_set(output, pMode, adjusted_mode);
+    }
+
+    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+    crtc->funcs->dpms(crtc, DPMSModeOn);
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc)
+	    output->funcs->dpms(output, DPMSModeOn);
+    }
+
+    crtc->curMode = *pMode;
+    
+    /* XXX free adjustedmode */
+    ret = TRUE;
+
+ done:
+    return ret;
+}
+
+/**
+ * In the current world order, there are lists of modes per output, which may
+ * or may not include the mode that was asked to be set by XFree86's mode
+ * selection.  Find the closest one, in the following preference order:
+ *
+ * - Equality
+ * - Closer in size to the requested mode, but no larger
+ * - Closer in refresh rate to the requested mode.
+ */
+DisplayModePtr
+RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
+{
+    ScrnInfoPtr	pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    DisplayModePtr pBest = NULL, pScan = NULL;
+    int i;
+
+    /* Assume that there's only one output connected to the given CRTC. */
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr  output = xf86_config->output[i];
+	if (output->crtc == crtc && output->probed_modes != NULL)
+	{
+	    pScan = output->probed_modes;
+	    break;
+	}
+    }
+
+    /* If the pipe doesn't have any detected modes, just let the system try to
+     * spam the desired mode in.
+     */
+    if (pScan == NULL) {
+	RADEONCrtcPrivatePtr  radeon_crtc = crtc->driver_private;
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "No crtc mode list for crtc %d,"
+		   "continuing with desired mode\n", radeon_crtc->crtc_id);
+	return pMode;
+    }
+
+    for (; pScan != NULL; pScan = pScan->next) {
+	assert(pScan->VRefresh != 0.0);
+
+	/* If there's an exact match, we're done. */
+	if (xf86ModesEqual(pScan, pMode)) {
+	    pBest = pMode;
+	    break;
+	}
+
+	/* Reject if it's larger than the desired mode. */
+	if (pScan->HDisplay > pMode->HDisplay ||
+	    pScan->VDisplay > pMode->VDisplay)
+	{
+	    continue;
+	}
+
+	if (pBest == NULL) {
+	    pBest = pScan;
+	    continue;
+	}
+
+	/* Find if it's closer to the right size than the current best
+	 * option.
+	 */
+	if ((pScan->HDisplay > pBest->HDisplay &&
+	     pScan->VDisplay >= pBest->VDisplay) ||
+	    (pScan->HDisplay >= pBest->HDisplay &&
+	     pScan->VDisplay > pBest->VDisplay))
+	{
+	    pBest = pScan;
+	    continue;
+	}
+
+	/* Find if it's still closer to the right refresh than the current
+	 * best resolution.
+	 */
+	if (pScan->HDisplay == pBest->HDisplay &&
+	    pScan->VDisplay == pBest->VDisplay &&
+	    (fabs(pScan->VRefresh - pMode->VRefresh) <
+	     fabs(pBest->VRefresh - pMode->VRefresh))) {
+	    pBest = pScan;
+	}
+    }
+
+    if (pBest == NULL) {
+	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "No suitable mode found to program for the pipe.\n"
+		   "	continuing with desired mode %dx%d@%.1f\n",
+		   pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
+    } else if (!xf86ModesEqual(pBest, pMode)) {
+      RADEONCrtcPrivatePtr  radeon_crtc = crtc->driver_private;
+      int		    crtc = radeon_crtc->crtc_id;
+      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		   "Choosing pipe %d's mode %dx%d@%.1f instead of xf86 "
+		   "mode %dx%d@%.1f\n", crtc,
+		   pBest->HDisplay, pBest->VDisplay, pBest->VRefresh,
+		   pMode->HDisplay, pMode->VDisplay, pMode->VRefresh);
+	pMode = pBest;
+    }
+    return pMode;
+}
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index d8eba3a..245f216 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -116,7 +116,7 @@
 static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
 static void RADEONSave(ScrnInfoPtr pScrn);
-static void RADEONRestore(ScrnInfoPtr pScrn);
+//static void RADEONRestore(ScrnInfoPtr pScrn);
 static Bool RADEONModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
 static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn);
@@ -128,6 +128,8 @@ static void RADEONSaveMemMapRegisters(Sc
 static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
 #endif
 
+DisplayModePtr
+RADEONCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
 /* psuedo xinerama support */
 
 extern Bool 		RADEONnoPanoramiXExtension;
@@ -3827,6 +3829,7 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 {
     ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     int            hasDRI = 0;
 #ifdef RENDER
     int            subPixelOrder = SubPixelUnknown;
@@ -4126,7 +4129,25 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 	info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
 	info->ModeReg.surface_cntl &= ~RADEON_SURF_TRANSLATION_DIS;
     } else {
-	if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
+	int i;
+	for (i = 0; i < xf86_config->num_crtc; i++)
+	{
+	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
+	    
+	    /* Mark that we'll need to re-set the mode for sure */
+	    memset(&crtc->curMode, 0, sizeof(crtc->curMode));
+	    if (!crtc->desiredMode.CrtcHDisplay)
+		crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
+	    
+	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE))
+		return FALSE;
+
+	}
+	RADEONBlank(pScrn);
+	RADEONRestoreMode(pScrn, &info->ModeReg);
+	RADEONUnblank(pScrn);
+
+	//if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
     }
 
     RADEONSaveScreen(pScreen, SCREEN_SAVER_ON);
@@ -5516,7 +5537,7 @@ static void RADEONSave(ScrnInfoPtr pScrn
 }
 
 /* Restore the original (text) mode */
-static void RADEONRestore(ScrnInfoPtr pScrn)
+void RADEONRestore(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
@@ -6388,60 +6409,63 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
 {
     RADEONInfoPtr  info      = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    double         dot_clock = crtc1->Clock/1000.0;
+    double         dot_clock = 0;
     RADEONInfoPtr  info0     = NULL;
     ScrnInfoPtr    pScrn0    = NULL;
 
 #if RADEON_DEBUG
-    ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc1->name,
-	   dot_clock,
-
-	   crtc1->HDisplay,
-	   crtc1->HSyncStart,
-	   crtc1->HSyncEnd,
-	   crtc1->HTotal,
-
-	   crtc1->VDisplay,
-	   crtc1->VSyncStart,
-	   crtc1->VSyncEnd,
-	   crtc1->VTotal,
-	   pScrn->depth,
-	   pScrn->bitsPerPixel);
-    if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    ErrorF("\n");
-    ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
-	   crtc1->name,
-	   dot_clock,
-
-	   crtc1->CrtcHDisplay,
-	   crtc1->CrtcHSyncStart,
-	   crtc1->CrtcHSyncEnd,
-	   crtc1->CrtcHTotal,
-
-	   crtc1->CrtcVDisplay,
-	   crtc1->CrtcVSyncStart,
-	   crtc1->CrtcVSyncEnd,
-	   crtc1->CrtcVTotal,
-	   pScrn->depth,
-	   pScrn->bitsPerPixel);
-    if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    ErrorF("\n");
+    if (crtc1) {
+	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+	       crtc1->name,
+	       dot_clock,
+	       
+	       crtc1->HDisplay,
+	       crtc1->HSyncStart,
+	       crtc1->HSyncEnd,
+	       crtc1->HTotal,
+	       
+	       crtc1->VDisplay,
+	       crtc1->VSyncStart,
+	       crtc1->VSyncEnd,
+	       crtc1->VTotal,
+	       pScrn->depth,
+	       pScrn->bitsPerPixel);
+	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
+	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
+	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
+	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
+	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
+	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
+	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
+	ErrorF("\n");
+	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+	       crtc1->name,
+	       dot_clock,
+
+	       crtc1->CrtcHDisplay,
+	       crtc1->CrtcHSyncStart,
+	       crtc1->CrtcHSyncEnd,
+	       crtc1->CrtcHTotal,
+	       
+	       crtc1->CrtcVDisplay,
+	       crtc1->CrtcVSyncStart,
+	       crtc1->CrtcVSyncEnd,
+	       crtc1->CrtcVTotal,
+	       pScrn->depth,
+	       pScrn->bitsPerPixel);
+	if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
+	if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
+	if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
+	if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
+	if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
+	if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
+	if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
+	ErrorF("\n");
+	info->Flags = crtc1->Flags;
+    }
 #endif
 
-    info->Flags = crtc1->Flags;
+
 
     RADEONInitMemMapRegisters(pScrn, save, info);
     RADEONInitCommonRegisters(save, info);
@@ -6469,14 +6493,20 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
 	/* if (!info->PaletteSavedOnVT) RADEONInitPalette(save); */
 	break;
     case 2:
-	pScrn0 = pRADEONEnt->pPrimaryScrn;
-	info0 = RADEONPTR(pScrn0);
+	if (pRADEONEnt->HasSecondary) {
+	    pScrn0 = pRADEONEnt->pPrimaryScrn;
+	    info0 = RADEONPTR(pScrn0);
+	} else {
+	    pScrn0 = pScrn;
+	    info0 = info;
+	}
 	dot_clock = crtc2->Clock/1000.0;
 	if (!RADEONInitCrtc2Registers(pScrn, save, crtc2, info))
 	    return FALSE;
 	RADEONInitPLL2Registers(pScrn, save, &info->pll, dot_clock, info->DisplayType != MT_CRT);
 	/* Make sure primary has the same copy */
-	memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));
+	if (pRADEONEnt->HasSecondary)
+	  memcpy(&info0->ModeReg, save, sizeof(RADEONSaveRec));
 	break;
     case 3:
        if (!RADEONInitCrtcRegisters(pScrn, save, 
@@ -6498,7 +6528,7 @@ Bool RADEONInit2(ScrnInfoPtr pScrn, Disp
 	return FALSE;
     }
 
-    RADEONTRACE(("RADEONInit returns %p\n", save));
+    RADEONTRACE(("RADEONInit2 %d returns %p\n", crtc_mask, save));
     return TRUE;
 }
 
@@ -6850,6 +6880,7 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
     ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
     RADEONTRACE(("RADEONEnterVT\n"));
 
@@ -6875,8 +6906,28 @@ _X_EXPORT Bool RADEONEnterVT(int scrnInd
 	info->ModeReg.surface_cntl = INREG(RADEON_SURFACE_CNTL);
 
 	RADEONRestoreFBDevRegisters(pScrn, &info->ModeReg);
-    } else
-	if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
+    } else {
+	int i;
+	for (i = 0; i < xf86_config->num_crtc; i++)
+	{
+	    xf86CrtcPtr	crtc = xf86_config->crtc[i];
+	    
+	    /* Mark that we'll need to re-set the mode for sure */
+	    memset(&crtc->curMode, 0, sizeof(crtc->curMode));
+	    if (!crtc->desiredMode.CrtcHDisplay)
+		crtc->desiredMode = *RADEONCrtcFindClosestMode (crtc, pScrn->currentMode);
+	    
+	    if (!RADEONCrtcSetMode (crtc, &crtc->desiredMode, TRUE))
+		return FALSE;
+
+	}
+	RADEONBlank(pScrn);
+	RADEONRestoreMode(pScrn, &info->ModeReg);
+	RADEONUnblank(pScrn);
+    }
+#if 0
+      if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE;
+#endif
 
     if (!info->IsSecondary)
 	RADEONRestoreSurfaces(pScrn, &info->ModeReg);
@@ -7293,7 +7344,7 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 	  }
 
 	  /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */
-	  if (pOutput = RADEONGetCrtcConnector(pScrn, 2))
+	  if ((pOutput = RADEONGetCrtcConnector(pScrn, 2)))
 	      info->CRT2pScrn->monitor->DDC = pOutput->MonInfo;
 	  else
 	      info->CRT2pScrn->monitor->DDC = NULL;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 977790c..817a40b 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -116,7 +116,6 @@ typedef enum
 } RADEONOutputType;
 
 typedef struct _RADEONCrtcPrivateRec {
-    int crtc;
     int crtc_id;
     int binding;
     Bool IsActive;
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index fef3667..29af262 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -636,31 +636,32 @@ xf86RandR12CrtcSet (ScreenPtr	pScreen,
 	    RADEON_SYNC(info, pScrn);
 	
 	if (mode) {
-	    if (pRcrtc->crtc_id == 0)
-		ret = RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg);
-	    else if (pRcrtc->crtc_id == 1)
-		ret = RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg);
-	    
-	    if (!ret) {
+
+	    if (!RADEONCrtcSetMode (crtc, mode, TRUE))
+	    {
 		crtc->enabled = save_enabled;
-		for (o = 0; o < config->num_output; o++) {
-		    xf86OutputPtr output = config->output[o];
+		for (o = 0; o < config->num_output; o++)
+		{
+		    xf86OutputPtr	output = config->output[o];
 		    output->crtc = save_crtcs[o];
 		}
 		DEALLOCATE_LOCAL(save_crtcs);
 		return FALSE;
 	    }
 	    crtc->desiredMode = *mode;
-	    
-	    pScrn->vtSema = TRUE;
+
+	
 	    RADEONBlank(pScrn);
 	    RADEONRestoreMode(pScrn, &info->ModeReg);
 	    RADEONUnblank(pScrn);
-	    
-	    if (info->DispPriority)
-		RADEONInitDispBandwidth(pScrn);
+	
 	}
+	    //	    if (info->DispPriority)
+	    //		RADEONInitDispBandwidth(pScrn);
+    
     }
+    if (pos_changed && mode)
+	RADEONCrtcSetBase(crtc, x, y);
     DEALLOCATE_LOCAL(save_crtcs);
     return xf86RandR12CrtcNotify (randr_crtc);
 }
diff-tree 52f749c8a613ee316044abe82156ee270412ced8 (from d7ff61c6822cbede7f5b59b411048d33dbae9ee4)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 16:23:26 2007 +1100

    fix typo

diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
index 7414d34..df7b1bd 100644
--- a/src/radeon_xf86Crtc.c
+++ b/src/radeon_xf86Crtc.c
@@ -839,7 +839,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn,
 		mon_rec.nVrefresh++;
 		sync_source = sync_config;
 	    }
-	    config_modes = i830xf86GetMonitorModes (pScrn, conf_monitor);
+	    config_modes = RADEONxf86GetMonitorModes (pScrn, conf_monitor);
 	}
 	
 	output_modes = (*output->funcs->get_modes) (output);
diff-tree d7ff61c6822cbede7f5b59b411048d33dbae9ee4 (from 50439d7e9f4f6f9933bacd59f8bb3e655a35dbc2)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 13:38:26 2007 +1100

    hook up detection of output

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 5e69def..7e8f76e 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2465,8 +2465,9 @@ radeon_detect(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-
-    //    RADEONConnectorFindMonitor(pScrn, id);
+    
+    radeon_output->MonType = MT_UNKNOWN;
+    RADEONConnectorFindMonitor(pScrn, output);
     if (radeon_output->MonType == MT_UNKNOWN)
 	return XF86OutputStatusUnknown;
     else if (radeon_output->MonType == MT_NONE)
diff-tree 50439d7e9f4f6f9933bacd59f8bb3e655a35dbc2 (from e067bfee92f2b0877108355619b2fb9188a9d15a)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 13:21:57 2007 +1100

    fixup some function calls

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 1953809..bad19b6 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -53,6 +53,7 @@
 #include "radeon_xf86Modes.h"
 				/* DDC support */
 #include "xf86DDC.h"
+#include <randrstr.h>
 
 void
 RADEONGetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
@@ -647,7 +648,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
 	fixed_mon.vrefresh[0].lo = 50.0;
 	fixed_mon.vrefresh[0].hi = 70.0;
 	
-	modes = RADEONxf86DuplicateModes(pScrn, pScrn->monitor->Modes);
+	modes = RADEON_xf86DuplicateModes(pScrn, pScrn->monitor->Modes);
 	RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
 	RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
 	/* fill out CRT of FP mode table */
@@ -709,7 +710,7 @@ RADEON_set_xf86_modes_from_outputs(ScrnI
         xf86OutputPtr output = config->output[i];
 	if (output->probed_modes != NULL) {
 	    pScrn->modes =
-		RADEONxf86DuplicateModes(pScrn, output->probed_modes);
+		RADEON_xf86DuplicateModes(pScrn, output->probed_modes);
 	    break;
 	}
     }
diff-tree e067bfee92f2b0877108355619b2fb9188a9d15a (from f1f34627ffbe2136ac3e023c01c0430412919ded)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 13:21:45 2007 +1100

    add more files for back compat

diff --git a/src/Makefile.am b/src/Makefile.am
index 788e4a9..3851881 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -83,6 +83,7 @@ radeon_drv_la_SOURCES = \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
 	radeon_xf86Crtc.c radeon_xf86Modes.c radeon_randr.c \
+	radeon_edid_modes.c radeon_xf86cvt.c \
 	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
diff --git a/src/radeon_edid_modes.c b/src/radeon_edid_modes.c
new file mode 100644
index 0000000..747b75f
--- /dev/null
+++ b/src/radeon_edid_modes.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2006 Luc Verhaegen.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file This is a copy of edid_modes.c from the X Server, for compatibility
+ * with old X Servers.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include <X11/Xatom.h>
+#include "property.h"
+#include "propertyst.h"
+#include "xf86DDC.h"
+#include "radeon_xf86Modes.h"
+#include "xf86Priv.h"
+#include <string.h>
+#include <math.h>
+
+
+#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
+
+/*
+ * Quirks to work around broken EDID data from various monitors.
+ */
+
+typedef enum {
+    DDC_QUIRK_NONE = 0,
+    /* Force detailed sync polarity to -h +v */
+    DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0,
+    /* First detailed mode is bogus, prefer largest mode at 60hz */
+    DDC_QUIRK_PREFER_LARGE_60 = 1 << 1,
+} ddc_quirk_t;
+
+static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Belinea 1924S1W */
+    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
+	DDC->vendor.prod_id == 1932)
+	return TRUE;
+    /* Belinea 10 20 30W */
+    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
+	DDC->vendor.prod_id == 2007)
+	return TRUE;
+    
+    return FALSE;
+}
+
+static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
+{
+    /* Belinea 10 15 55 */
+    if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
+	DDC->vendor.prod_id == 1516)
+	return TRUE;
+    
+    return FALSE;
+}
+
+typedef struct {
+    Bool	(*detect) (int scrnIndex, xf86MonPtr DDC);
+    ddc_quirk_t	quirk;
+    char	*description;
+} ddc_quirk_map_t;
+
+static const ddc_quirk_map_t ddc_quirks[] = {
+    { 
+	quirk_dt_sync_hm_vp,	DDC_QUIRK_DT_SYNC_HM_VP,
+	"Set detailed timing sync polarity to -h +v"
+    },
+    {
+	quirk_prefer_large_60,   DDC_QUIRK_PREFER_LARGE_60,
+	"Detailed timing is not preferred, use largest mode at 60Hz"
+    },
+    { 
+	NULL,		DDC_QUIRK_NONE,
+	"No known quirks"
+    },
+};
+
+/*
+ * TODO:
+ *  - for those with access to the VESA DMT standard; review please.
+ */
+#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
+#define MODESUFFIX   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
+
+DisplayModeRec DDCEstablishedModes[17] = {
+    { MODEPREFIX("800x600"),    40000,  800,  840,  968, 1056, 0,  600,  601,  605,  628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 60Hz */
+    { MODEPREFIX("800x600"),    36000,  800,  824,  896, 1024, 0,  600,  601,  603,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 56Hz */
+    { MODEPREFIX("640x480"),    31500,  640,  656,  720,  840, 0,  480,  481,  484,  500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 75Hz */
+    { MODEPREFIX("640x480"),    31500,  640,  664,  704,  832, 0,  480,  489,  491,  520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 72Hz */
+    { MODEPREFIX("640x480"),    30240,  640,  704,  768,  864, 0,  480,  483,  486,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 67Hz */
+    { MODEPREFIX("640x480"),    25200,  640,  656,  752,  800, 0,  480,  490,  492,  525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480 at 60Hz */
+    { MODEPREFIX("720x400"),    35500,  720,  738,  846,  900, 0,  400,  421,  423,  449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400 at 88Hz */
+    { MODEPREFIX("720x400"),    28320,  720,  738,  846,  900, 0,  400,  412,  414,  449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400 at 70Hz */
+    { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024 at 75Hz */
+    { MODEPREFIX("1024x768"),   78800, 1024, 1040, 1136, 1312, 0,  768,  769,  772,  800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768 at 75Hz */
+    { MODEPREFIX("1024x768"),   75000, 1024, 1048, 1184, 1328, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 70Hz */
+    { MODEPREFIX("1024x768"),   65000, 1024, 1048, 1184, 1344, 0,  768,  771,  777,  806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768 at 60Hz */
+    { MODEPREFIX("1024x768"),   44900, 1024, 1032, 1208, 1264, 0,  768,  768,  776,  817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768 at 43Hz */
+    { MODEPREFIX("832x624"),    57284,  832,  864,  928, 1152, 0,  624,  625,  628,  667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624 at 75Hz */
+    { MODEPREFIX("800x600"),    49500,  800,  816,  896, 1056, 0,  600,  601,  604,  625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 75Hz */
+    { MODEPREFIX("800x600"),    50000,  800,  856,  976, 1040, 0,  600,  637,  643,  666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600 at 72Hz */
+    { MODEPREFIX("1152x864"),  108000, 1152, 1216, 1344, 1600, 0,  864,  865,  868,  900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864 at 75Hz */
+};
+
+static DisplayModePtr
+DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
+			ddc_quirk_t quirks)
+{
+    DisplayModePtr Modes = NULL, Mode = NULL;
+    CARD32 bits = (timing->t1) | (timing->t2 << 8) |
+        ((timing->t_manu & 0x80) << 9);
+    int i;
+
+    for (i = 0; i < 17; i++) {
+        if (bits & (0x01 << i)) {
+            Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
+            Modes = xf86ModesAdd(Modes, Mode);
+        }
+    }
+
+    return Modes;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing,
+			   ddc_quirk_t quirks)
+{
+    DisplayModePtr Modes = NULL, Mode = NULL;
+    int i;
+
+    for (i = 0; i < STD_TIMINGS; i++) {
+        if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
+            Mode =  xf86CVTMode(timing[i].hsize, timing[i].vsize,
+                                timing[i].refresh, FALSE, FALSE);
+	    Mode->type = M_T_DRIVER;
+            Modes = xf86ModesAdd(Modes, Mode);
+        }
+    }
+
+    return Modes;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
+			  int preferred, ddc_quirk_t quirks)
+{
+    DisplayModePtr Mode;
+
+    /* We don't do stereo */
+    if (timing->stereo) {
+        xf86DrvMsg(scrnIndex, X_INFO,
+		   "%s: Ignoring: We don't handle stereo.\n", __func__);
+        return NULL;
+    }
+
+    /* We only do seperate sync currently */
+    if (timing->sync != 0x03) {
+         xf86DrvMsg(scrnIndex, X_INFO,
+		    "%s: %dx%d Warning: We only handle seperate"
+                    " sync.\n", __func__, timing->h_active, timing->v_active);
+    }
+
+    Mode = xnfalloc(sizeof(DisplayModeRec));
+    memset(Mode, 0, sizeof(DisplayModeRec));
+
+    Mode->type = M_T_DRIVER;
+    if (preferred)
+	Mode->type |= M_T_PREFERRED;
+
+    Mode->Clock = timing->clock / 1000.0;
+
+    Mode->HDisplay = timing->h_active;
+    Mode->HSyncStart = timing->h_active + timing->h_sync_off;
+    Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
+    Mode->HTotal = timing->h_active + timing->h_blanking;
+
+    Mode->VDisplay = timing->v_active;
+    Mode->VSyncStart = timing->v_active + timing->v_sync_off;
+    Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
+    Mode->VTotal = timing->v_active + timing->v_blanking;
+
+    xf86SetModeDefaultName(Mode);
+
+    /* We ignore h/v_size and h/v_border for now. */
+
+    if (timing->interlaced)
+        Mode->Flags |= V_INTERLACE;
+
+    if (quirks & DDC_QUIRK_DT_SYNC_HM_VP)
+	Mode->Flags |= V_NHSYNC | V_PVSYNC;
+    else
+    {
+	if (timing->misc & 0x02)
+	    Mode->Flags |= V_PHSYNC;
+	else
+	    Mode->Flags |= V_NHSYNC;
+    
+	if (timing->misc & 0x01)
+	    Mode->Flags |= V_PVSYNC;
+	else
+	    Mode->Flags |= V_NVSYNC;
+    }
+
+    return Mode;
+}
+
+DisplayModePtr
+xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
+{
+    int preferred, i;
+    DisplayModePtr  Modes = NULL, Mode;
+    ddc_quirk_t	    quirks;
+
+    xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
+		DDC->vendor.name, DDC->vendor.prod_id);
+    quirks = DDC_QUIRK_NONE;
+    for (i = 0; ddc_quirks[i].detect; i++)
+	if (ddc_quirks[i].detect (scrnIndex, DDC))
+	{
+	    xf86DrvMsg (scrnIndex, X_INFO, "    EDID quirk: %s\n",
+			ddc_quirks[i].description);
+	    quirks |= ddc_quirks[i].quirk;
+	}
+    
+    preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
+	preferred = 0;
+
+    for (i = 0; i < DET_TIMINGS; i++) {
+	struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
+
+        switch (det_mon->type) {
+        case DT:
+            Mode = DDCModeFromDetailedTiming(scrnIndex,
+                                             &det_mon->section.d_timings,
+					     preferred,
+					     quirks);
+	    preferred = 0;
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        case DS_STD_TIMINGS:
+            Mode = DDCModesFromStandardTiming(scrnIndex,
+					      det_mon->section.std_t,
+					      quirks);
+            Modes = xf86ModesAdd(Modes, Mode);
+            break;
+        default:
+            break;
+        }
+    }
+
+    /* Add established timings */
+    Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    /* Add standard timings */
+    Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks);
+    Modes = xf86ModesAdd(Modes, Mode);
+
+    if (quirks & DDC_QUIRK_PREFER_LARGE_60)
+    {
+	DisplayModePtr	best = Modes;
+	for (Mode = Modes; Mode; Mode = Mode->next)
+	{
+	    if (Mode == best) continue;
+	    if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
+	    {
+		best = Mode;
+		continue;
+	    }
+	    if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
+	    {
+		double	mode_refresh = xf86ModeVRefresh (Mode);
+		double	best_refresh = xf86ModeVRefresh (best);
+		double	mode_dist = fabs(mode_refresh - 60.0);
+		double	best_dist = fabs(best_refresh - 60.0);
+		if (mode_dist < best_dist)
+		{
+		    best = Mode;
+		    continue;
+		}
+	    }
+	}
+	if (best)
+	    best->type |= M_T_PREFERRED;
+    }
+    return Modes;
+}
+
+#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
diff --git a/src/radeon_xf86cvt.c b/src/radeon_xf86cvt.c
new file mode 100644
index 0000000..9d8d025
--- /dev/null
+++ b/src/radeon_xf86cvt.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2005-2006 Luc Verhaegen.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file This is a copy of xf86cvt.c from the X Server, for compatibility with
+ * old servers (pre-1.2).
+ */
+
+/*
+ * The reason for having this function in a file of its own is
+ * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode
+ * code is shared directly.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+
+#include <string.h>
+#include "xf86DDC.h"
+#include "radeon_xf86Modes.h"
+#include "xf86Priv.h"
+
+#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
+/*
+ * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
+ *
+ * These calculations are stolen from the CVT calculation spreadsheet written
+ * by Graham Loveridge. He seems to be claiming no copyright and there seems to
+ * be no license attached to this. He apparently just wants to see his name
+ * mentioned.
+ *
+ * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls
+ *
+ * Comments and structure corresponds to the comments and structure of the xls.
+ * This should ease importing of future changes to the standard (not very
+ * likely though).
+ *
+ * About margins; i'm sure that they are to be the bit between HDisplay and
+ * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and 
+ * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking
+ * outside sync "margin" for some reason. Since we prefer seeing proper
+ * blanking instead of the overscan colour, and since the Crtc* values will
+ * probably get altered after us, we will disable margins altogether. With
+ * these calculations, Margins will plainly expand H/VDisplay, and we don't
+ * want that. -- libv
+ *
+ */
+_X_EXPORT DisplayModePtr
+xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
+	    Bool Interlaced)
+{
+    DisplayModeRec  *Mode = xnfalloc(sizeof(DisplayModeRec));
+
+    /* 1) top/bottom margin size (% of height) - default: 1.8 */
+#define CVT_MARGIN_PERCENTAGE 1.8    
+
+    /* 2) character cell horizontal granularity (pixels) - default 8 */
+#define CVT_H_GRANULARITY 8
+
+    /* 4) Minimum vertical porch (lines) - default 3 */
+#define CVT_MIN_V_PORCH 3
+
+    /* 4) Minimum number of vertical back porch lines - default 6 */
+#define CVT_MIN_V_BPORCH 6
+
+    /* Pixel Clock step (kHz) */
+#define CVT_CLOCK_STEP 250
+
+    Bool Margins = FALSE;
+    float  VFieldRate, HPeriod;
+    int  HDisplayRnd, HMargin;
+    int  VDisplayRnd, VMargin, VSync;
+    float  Interlace; /* Please rename this */
+
+    memset(Mode, 0, sizeof(DisplayModeRec));
+
+    /* CVT default is 60.0Hz */
+    if (!VRefresh)
+        VRefresh = 60.0;
+
+    /* 1. Required field rate */
+    if (Interlaced)
+        VFieldRate = VRefresh * 2;
+    else
+        VFieldRate = VRefresh;
+
+    /* 2. Horizontal pixels */
+    HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY);
+
+    /* 3. Determine left and right borders */
+    if (Margins) {
+        /* right margin is actually exactly the same as left */
+        HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
+        HMargin -= HMargin % CVT_H_GRANULARITY;
+    } else
+        HMargin = 0;
+
+    /* 4. Find total active pixels */
+    Mode->HDisplay = HDisplayRnd + 2*HMargin;
+
+    /* 5. Find number of lines per field */
+    if (Interlaced)
+        VDisplayRnd = VDisplay / 2;
+    else
+        VDisplayRnd = VDisplay;
+
+    /* 6. Find top and bottom margins */
+    /* nope. */
+    if (Margins)
+        /* top and bottom margins are equal again. */
+        VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0);
+    else
+        VMargin = 0;
+
+    Mode->VDisplay = VDisplay + 2*VMargin;
+
+    /* 7. Interlace */
+    if (Interlaced)
+        Interlace = 0.5;
+    else
+        Interlace = 0.0;
+
+    /* Determine VSync Width from aspect ratio */
+    if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay))
+        VSync = 4;
+    else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay))
+        VSync = 5;
+    else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay))
+        VSync = 6;
+    else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay))
+        VSync = 7;
+    else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay))
+        VSync = 7;
+    else /* Custom */
+        VSync = 10;
+
+    if (!Reduced) { /* simplified GTF calculation */
+
+        /* 4) Minimum time of vertical sync + back porch interval (µs) 
+         * default 550.0 */
+#define CVT_MIN_VSYNC_BP 550.0
+
+        /* 3) Nominal HSync width (% of line period) - default 8 */
+#define CVT_HSYNC_PERCENTAGE 8
+
+        float  HBlankPercentage;
+        int  VSyncAndBackPorch, VBackPorch;
+        int  HBlank;
+
+        /* 8. Estimated Horizontal period */
+        HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / 
+            (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace);
+
+        /* 9. Find number of lines in sync + backporch */
+        if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH))
+            VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH;
+        else
+            VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1;
+
+        /* 10. Find number of lines in back porch */
+        VBackPorch = VSyncAndBackPorch - VSync;
+
+        /* 11. Find total number of lines in vertical field */
+        Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace
+            + CVT_MIN_V_PORCH;
+
+        /* 5) Definition of Horizontal blanking time limitation */
+        /* Gradient (%/kHz) - default 600 */
+#define CVT_M_FACTOR 600
+
+        /* Offset (%) - default 40 */
+#define CVT_C_FACTOR 40
+
+        /* Blanking time scaling factor - default 128 */
+#define CVT_K_FACTOR 128
+
+        /* Scaling factor weighting - default 20 */
+#define CVT_J_FACTOR 20
+
+#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256
+#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \
+        CVT_J_FACTOR
+
+        /* 12. Find ideal blanking duty cycle from formula */
+        HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0;
+
+        /* 13. Blanking time */
+        if (HBlankPercentage < 20)
+            HBlankPercentage = 20;
+
+        HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage);
+        HBlank -= HBlank % (2*CVT_H_GRANULARITY);
+        
+        /* 14. Find total number of pixels in a line. */
+        Mode->HTotal = Mode->HDisplay + HBlank;
+
+        /* Fill in HSync values */
+        Mode->HSyncEnd = Mode->HDisplay + HBlank / 2;
+
+        Mode->HSyncStart = Mode->HSyncEnd - 
+            (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100;
+        Mode->HSyncStart += CVT_H_GRANULARITY - 
+            Mode->HSyncStart % CVT_H_GRANULARITY;
+
+        /* Fill in VSync values */
+        Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH;
+        Mode->VSyncEnd = Mode->VSyncStart + VSync;
+
+    } else { /* Reduced blanking */
+        /* Minimum vertical blanking interval time (µs) - default 460 */
+#define CVT_RB_MIN_VBLANK 460.0
+
+        /* Fixed number of clocks for horizontal sync */
+#define CVT_RB_H_SYNC 32.0
+
+        /* Fixed number of clocks for horizontal blanking */
+#define CVT_RB_H_BLANK 160.0
+
+        /* Fixed number of lines for vertical front porch - default 3 */
+#define CVT_RB_VFPORCH 3
+
+        int  VBILines;
+
+        /* 8. Estimate Horizontal period. */
+        HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / 
+            (VDisplayRnd + 2*VMargin);
+
+        /* 9. Find number of lines in vertical blanking */
+        VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1;
+
+        /* 10. Check if vertical blanking is sufficient */
+        if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH))
+            VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH;
+        
+        /* 11. Find total number of lines in vertical field */
+        Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines;
+
+        /* 12. Find total number of pixels in a line */
+        Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK;
+
+        /* Fill in HSync values */
+        Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2;
+        Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC;
+
+        /* Fill in VSync values */
+        Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH;
+        Mode->VSyncEnd = Mode->VSyncStart + VSync;
+    }
+
+    /* 15/13. Find pixel clock frequency (kHz for xf86) */
+    Mode->Clock = Mode->HTotal * 1000.0 / HPeriod;
+    Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP;
+
+    /* 16/14. Find actual Horizontal Frequency (kHz) */
+    Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal);
+
+    /* 17/15. Find actual Field rate */
+    Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / 
+        ((float) (Mode->HTotal * Mode->VTotal));
+
+    /* 18/16. Find actual vertical frame frequency */
+    /* ignore - just set the mode flag for interlaced */
+    if (Interlaced)
+        Mode->VTotal *= 2;
+
+    {
+        char  Name[256];
+        Name[0] = 0;
+
+        snprintf(Name, 256, "%dx%d", HDisplay, VDisplay);
+
+        Mode->name = xnfalloc(strlen(Name) + 1);
+        memcpy(Mode->name, Name, strlen(Name) + 1);
+    }
+
+    if (Reduced)
+        Mode->Flags |= V_PHSYNC | V_NVSYNC;
+    else
+        Mode->Flags |= V_NHSYNC | V_PVSYNC;
+
+    if (Interlaced)
+        Mode->Flags |= V_INTERLACE;
+
+    return Mode;
+}
+#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
diff-tree f1f34627ffbe2136ac3e023c01c0430412919ded (from 249ec67c296b34d0c7c1d78602628d2f7ce6a045)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 12:50:03 2007 +1100

    make restore mode non-static

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ab9e9b7..d8eba3a 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -5143,7 +5143,7 @@ static void RADEONRestorePalette(ScrnInf
 #endif
 
 /* Write out state to define a new video mode */
-static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
     RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
diff-tree 249ec67c296b34d0c7c1d78602628d2f7ce6a045 (from a43c1d55f5f855d9e6ae939dd4eec1c607b6d514)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 12:43:03 2007 +1100

    more minor fixes to get radeon up to speed

diff --git a/src/radeon_display.c b/src/radeon_display.c
index dcf65f2..5e69def 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2465,15 +2465,15 @@ radeon_detect(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-#if 0
+
     //    RADEONConnectorFindMonitor(pScrn, id);
-    if (pRADEONEnt->PortInfo[id].MonType == MT_UNKNOWN)
+    if (radeon_output->MonType == MT_UNKNOWN)
 	return XF86OutputStatusUnknown;
-    else if (pRADEONEnt->PortInfo[id].MonType == MT_NONE)
+    else if (radeon_output->MonType == MT_NONE)
 	return XF86OutputStatusDisconnected;
     else
 	return XF86OutputStatusConnected;
-#endif
+
 }
 
 static DisplayModePtr
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index fb0fa80..ab9e9b7 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -449,7 +449,7 @@ RADEONCreateScreenResources (ScreenPtr p
    if (!(*pScreen->CreateScreenResources)(pScreen))
       return FALSE;
 
-   if (!RADEONRandRCreateScreenResources(pScreen))
+   if (!xf86RandR12CreateScreenResources(pScreen))
       return FALSE;
 
   return TRUE;
@@ -2850,12 +2850,13 @@ static Bool RADEONPreInitControllers(Scr
 
     RADEONGetBIOSInfo(pScrn, pInt10);
 
+    RADEONSetupConnectors(pScrn);
+
     if (!info->IsSecondary) {
       if (!RADEONAllocateConnectors(pScrn))
 	return FALSE;
     }
 
-    RADEONSetupConnectors(pScrn);
     RADEONMapControllers(pScrn);
 
     RADEONGetClockInfo(pScrn);
@@ -3220,7 +3221,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
 #endif
 
-    xf86CrtcSetSizeRange (pScrn, 320, 200, 16384, 2048);
+    xf86CrtcSetSizeRange (pScrn, 320, 200, 2048, 2048);
     if (!RADEONPreInitVRAM(pScrn))
 	goto fail;
 
diff-tree a43c1d55f5f855d9e6ae939dd4eec1c607b6d514 (from 87592ffb717da1f0a1767a38918d16d60953599c)
Author: Dave Airlie <airlied at linux.ie>
Date:   Thu Jan 4 12:29:51 2007 +1100

    bring radeon randr code inline with intel randr code

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 615525c..fb0fa80 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3267,14 +3267,12 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     if (!xf86RandR12PreInit (pScrn))
     {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
-      PreInitCleanup(pScrn);
-      return FALSE;
+      goto fail;
     }	
     
     if (pScrn->modes == NULL) {
       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
-      PreInitCleanup(pScrn);
-      return FALSE;
+      goto fail;
    }
 
     /* Free the video bios (if applicable) */
@@ -4303,9 +4301,9 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     /* Rotation */
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
     xf86DisableRandR(); /* Disable built-in RandR extension */
-    /* support all rotations */
+
     xf86RandR12Init (pScreen);
-    xf86RandR12SetRotations (pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
+    xf86RandR12SetRotations (pScreen, RR_Rotate_0);
 
     info->CreateScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = RADEONCreateScreenResources;
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index ce28e7b..fef3667 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -1,28 +1,24 @@
 /*
  * Copyright 2006 Dave Airlie
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
  *
- * All Rights Reserved.
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
  *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS AND/OR
- * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
  */
 
 
@@ -49,7 +45,7 @@
 #include "radeon_version.h"
 #include "radeon_mergedfb.h"
 
-typedef struct _radeonRandRInfo {
+typedef struct _xf86RandR12Info {
     int				    virtualX;
     int				    virtualY;
     int				    mmWidth;
@@ -69,27 +65,8 @@ static Bool xf86RandR12CreateScreenResou
 static int	    xf86RandR12Index;
 static int	    xf86RandR12Generation;
 
-#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[xf86RandR12Index].ptr)
-
-#if RANDR_12_INTERFACE
-
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
-    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
-    if (xf86RandR12Generation != serverGeneration ||
-	XF86RANDRINFO(pScreen)->virtualX == -1)
-    {
-	*x = pScrn->virtualX;
-	*y = pScrn->virtualY;
-    } else {
-	XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
-	*x = randrp->virtualX;
-	*y = randrp->virtualY;
-    }
-}
+#define XF86RANDRINFO(p) \
+	((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
 
 static int
 xf86RandR12ModeRefresh (DisplayModePtr mode)
@@ -119,7 +96,7 @@ xf86RandR12GetInfo (ScreenPtr pScreen, R
     }
 
     /* Re-probe the outputs for new monitors or modes */
-    xf86ProbeOutputModes (scrp);
+    xf86ProbeOutputModes (scrp, 0, 0);
     xf86SetScrnInfoModes (scrp);
 
     for (mode = scrp->modes; ; mode = mode->next)
@@ -348,20 +325,6 @@ xf86RandR12SetConfig (ScreenPtr		pScreen
     return TRUE;
 }
 
-Rotation
-xf86RandR12GetRotation(ScreenPtr pScreen)
-{
-    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
-
-    return randrp->rotation;
-}
-
-
-static void
-RADEONRandRPointerMoved (int scrnIndex, int x, int y)
-{
-}
-
 static Bool
 xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
 			CARD16		width,
@@ -389,15 +352,171 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScr
     pScreen->mmWidth = mmWidth;
     pScreen->mmHeight = mmHeight;
 
-    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+    xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
     xf86SetViewport (pScreen, 0, 0);
     if (pRoot)
 	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+#if RANDR_12_INTERFACE
     if (WindowTable[pScreen->myNum])
 	RRScreenSizeNotify (pScreen);
+#endif
     return ret;
 }
 
+Rotation
+xf86RandR12GetRotation(ScreenPtr pScreen)
+{
+    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
+
+    return randrp->rotation;
+}
+
+Bool
+xf86RandR12CreateScreenResources (ScreenPtr pScreen)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    int			c;
+    int			width, height;
+    int			mmWidth, mmHeight;
+#ifdef PANORAMIX
+    /* XXX disable RandR when using Xinerama */
+    if (!noPanoramiXExtension)
+	return TRUE;
+#endif
+
+    /*
+     * Compute size of screen
+     */
+    width = 0; height = 0;
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = config->crtc[c];
+	int	    crtc_width = crtc->x + crtc->curMode.HDisplay;
+	int	    crtc_height = crtc->y + crtc->curMode.VDisplay;
+	
+	if (crtc->enabled && crtc_width > width)
+	    width = crtc_width;
+	if (crtc->enabled && crtc_height > height)
+	    height = crtc_height;
+    }
+    
+    if (width && height)
+    {
+	/*
+	 * Compute physical size of screen
+	 */
+	if (monitorResolution) 
+	{
+	    mmWidth = width * 25.4 / monitorResolution;
+	    mmHeight = height * 25.4 / monitorResolution;
+	}
+	else
+	{
+	    mmWidth = pScreen->mmWidth;
+	    mmHeight = pScreen->mmHeight;
+	}
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Setting screen physical size to %d x %d\n",
+		   mmWidth, mmHeight);
+	xf86RandR12ScreenSetSize (pScreen,
+				  width,
+				  height,
+				  mmWidth,
+				  mmHeight);
+    }
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
+    {
+	randrp->virtualX = pScrn->virtualX;
+	randrp->virtualY = pScrn->virtualY;
+    }
+#if RANDR_12_INTERFACE
+    if (xf86RandR12CreateScreenResources12 (pScreen))
+	return TRUE;
+#endif
+    return TRUE;
+}
+
+
+Bool
+xf86RandR12Init (ScreenPtr pScreen)
+{
+    rrScrPrivPtr	rp;
+    XF86RandRInfoPtr	randrp;
+
+#ifdef PANORAMIX
+    /* XXX disable RandR when using Xinerama */
+    if (!noPanoramiXExtension)
+	return TRUE;
+#endif
+    if (xf86RandR12Generation != serverGeneration)
+    {
+	xf86RandR12Index = AllocateScreenPrivateIndex();
+	xf86RandR12Generation = serverGeneration;
+    }
+
+    randrp = xalloc (sizeof (XF86RandRInfoRec));
+    if (!randrp)
+	return FALSE;
+
+    if (!RRScreenInit(pScreen))
+    {
+	xfree (randrp);
+	return FALSE;
+    }
+    rp = rrGetScrPriv(pScreen);
+    rp->rrGetInfo = xf86RandR12GetInfo;
+    rp->rrSetConfig = xf86RandR12SetConfig;
+
+    randrp->virtualX = -1;
+    randrp->virtualY = -1;
+    randrp->mmWidth = pScreen->mmWidth;
+    randrp->mmHeight = pScreen->mmHeight;
+
+    randrp->rotation = RR_Rotate_0; /* initial rotated mode */
+
+    randrp->supported_rotations = RR_Rotate_0;
+
+    randrp->maxX = randrp->maxY = 0;
+
+    pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
+
+#if RANDR_12_INTERFACE
+    if (!xf86RandR12Init12 (pScreen))
+	return FALSE;
+#endif
+    return TRUE;
+}
+
+void
+xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
+{
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+
+    randrp->supported_rotations = rotations;
+}
+
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
+{
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+    if (xf86RandR12Generation != serverGeneration ||
+	XF86RANDRINFO(pScreen)->virtualX == -1)
+    {
+	*x = pScrn->virtualX;
+	*y = pScrn->virtualY;
+    } else {
+	XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+	*x = randrp->virtualX;
+	*y = randrp->virtualY;
+    }
+}
+
+#if RANDR_12_INTERFACE
 static Bool
 xf86RandR12CrtcNotify (RRCrtcPtr	randr_crtc)
 {
@@ -455,103 +574,111 @@ xf86RandR12CrtcNotify (RRCrtcPtr	randr_c
 
 static Bool
 xf86RandR12CrtcSet (ScreenPtr	pScreen,
-		    RRCrtcPtr	randr_crtc,
-		    RRModePtr	randr_mode,
-		    int		x,
-		    int		y,
-		    Rotation	rotation,
-		    int		num_randr_outputs,
-		    RROutputPtr	*randr_outputs)
-{
-  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-  xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-  xf86CrtcPtr crtc = randr_crtc->devPrivate;
-  DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
-  Bool changed = FALSE;
-  Bool pos_changed;
-  int o, ro;
-  xf86CrtcPtr		*save_crtcs;
-  Bool save_enabled = crtc->enabled;
-  int ret;
-
-  save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
-  if ((mode != NULL) != crtc->enabled)
-    changed = TRUE;
-  else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
+		  RRCrtcPtr	randr_crtc,
+		  RRModePtr	randr_mode,
+		  int		x,
+		  int		y,
+		  Rotation	rotation,
+		  int		num_randr_outputs,
+		  RROutputPtr	*randr_outputs)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
+    DisplayModePtr	mode = randr_mode ? randr_mode->devPrivate : NULL;
+    Bool		changed = FALSE;
+    Bool		pos_changed;
+    int			o, ro;
+    xf86CrtcPtr		*save_crtcs;
+    Bool save_enabled = crtc->enabled;
+    int ret;
+    
+    save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
+    if ((mode != NULL) != crtc->enabled)
     changed = TRUE;
-
-  pos_changed = changed;
-  if (x != crtc->x || y != crtc->y)
-    pos_changed = TRUE;
-
-  for (o = 0; o < config->num_output; o++) {
-    xf86OutputPtr  output = config->output[o];
-    xf86CrtcPtr new_crtc;
-
-    save_crtcs[o] = output->crtc;
-
-    if (output->crtc == crtc)
-      new_crtc = NULL;
-    else
-      new_crtc = output->crtc;
-
-    for (ro = 0; ro < num_randr_outputs; ro++)
-      if (output->randr_output == randr_outputs[ro]) {
-	new_crtc = crtc;
-	break;
-      }
-    if (new_crtc != output->crtc) {
-      changed = TRUE;
-      output->crtc = new_crtc;
-    }
-  }
-
-  /* got to set the modes in here */
-  if (changed) {
-    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONInfoPtr  info = RADEONPTR(pScrn);
-    RADEONCrtcPrivatePtr pRcrtc;
-    crtc->enabled = mode != NULL;
-
-    if (info->accelOn)
-      RADEON_SYNC(info, pScrn);
-
-    if (mode) {
-      if (pRcrtc->crtc_id == 0)
-	ret = RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg);
-      else if (pRcrtc->crtc_id == 1)
-	ret = RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg);
-      
-      if (!ret) {
-	crtc->enabled = save_enabled;
-	for (o = 0; o < config->num_output; o++) {
-	  xf86OutputPtr output = config->output[o];
-	  output->crtc = save_crtcs[o];
+    else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
+	changed = TRUE;
+    
+    pos_changed = changed;
+    if (x != crtc->x || y != crtc->y)
+	pos_changed = TRUE;
+    
+    for (o = 0; o < config->num_output; o++) {
+	xf86OutputPtr  output = config->output[o];
+	xf86CrtcPtr new_crtc;
+	
+	save_crtcs[o] = output->crtc;
+	
+	if (output->crtc == crtc)
+	    new_crtc = NULL;
+	else
+	    new_crtc = output->crtc;
+	
+	for (ro = 0; ro < num_randr_outputs; ro++)
+	    if (output->randr_output == randr_outputs[ro]) {
+		new_crtc = crtc;
+		break;
+	    }
+	if (new_crtc != output->crtc) {
+	    changed = TRUE;
+	    output->crtc = new_crtc;
 	}
-	DEALLOCATE_LOCAL(save_crtcs);
-	return FALSE;
-      }
-      crtc->desiredMode = *mode;
-      
-      pScrn->vtSema = TRUE;
-      RADEONBlank(pScrn);
-      RADEONRestoreMode(pScrn, &info->ModeReg);
-      RADEONUnblank(pScrn);
-      
-      if (info->DispPriority)
-	RADEONInitDispBandwidth(pScrn);
-    }
-  }
-  DEALLOCATE_LOCAL(save_crtcs);
-  return RADEONRandRCrtcNotify(randr_crtc);
+    }
+    
+    /* got to set the modes in here */
+    if (changed) {
+	RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+	RADEONInfoPtr  info = RADEONPTR(pScrn);
+	RADEONCrtcPrivatePtr pRcrtc;
+	crtc->enabled = mode != NULL;
+	
+	if (info->accelOn)
+	    RADEON_SYNC(info, pScrn);
+	
+	if (mode) {
+	    if (pRcrtc->crtc_id == 0)
+		ret = RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg);
+	    else if (pRcrtc->crtc_id == 1)
+		ret = RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg);
+	    
+	    if (!ret) {
+		crtc->enabled = save_enabled;
+		for (o = 0; o < config->num_output; o++) {
+		    xf86OutputPtr output = config->output[o];
+		    output->crtc = save_crtcs[o];
+		}
+		DEALLOCATE_LOCAL(save_crtcs);
+		return FALSE;
+	    }
+	    crtc->desiredMode = *mode;
+	    
+	    pScrn->vtSema = TRUE;
+	    RADEONBlank(pScrn);
+	    RADEONRestoreMode(pScrn, &info->ModeReg);
+	    RADEONUnblank(pScrn);
+	    
+	    if (info->DispPriority)
+		RADEONInitDispBandwidth(pScrn);
+	}
+    }
+    DEALLOCATE_LOCAL(save_crtcs);
+    return xf86RandR12CrtcNotify (randr_crtc);
 }
 
 
 static Bool
 xf86RandR12CrtcSetGamma (ScreenPtr    pScreen,
-		       RRCrtcPtr    crtc)
+			 RRCrtcPtr    randr_crtc)
 {
-    return FALSE;
+    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
+
+    if (crtc->funcs->gamma_set == NULL)
+	return FALSE;
+
+    crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen,
+			   randr_crtc->gammaBlue, randr_crtc->gammaSize);
+
+    return TRUE;
 }
 
 /**
@@ -599,8 +726,8 @@ xf86RROutputSetModes (RROutputPtr randr_
 		    modeInfo.modeFlags = mode->Flags;
 
 		    rrmode = RRModeGet (&modeInfo, mode->name);
-		    rrmode->devPrivate = mode;
 		    if (rrmode) {
+			rrmode->devPrivate = mode;
 			rrmodes[nmode++] = rrmode;
 			npreferred += pref;
 		    }
@@ -624,11 +751,11 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     RROutputPtr		*clones;
     RRCrtcPtr		*crtcs;
-    int ncrtc;
-    int o, c, l;
+    int			ncrtc;
+    int			o, c, l;
     RRCrtcPtr		randr_crtc;
-    int nclone;
-
+    int			nclone;
+    
     clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
     crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr));
     for (o = 0; o < config->num_output; o++)
@@ -658,7 +785,7 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
 				output->mm_height);
 	xf86RROutputSetModes (output->randr_output, output->probed_modes);
 
-	switch (output->status = (*output->funcs->detect)(output)) {
+	switch (output->status) {
 	case XF86OutputStatusConnected:
 	    RROutputSetConnection (output->randr_output, RR_Connected);
 	    break;
@@ -704,536 +831,94 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen,
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
 
-    xf86ProbeOutputModes (pScrn);
+    xf86ProbeOutputModes (pScrn, 0, 0);
     xf86SetScrnInfoModes (pScrn);
-    return RADEONRandRSetInfo12 (pScrn);
-}
-
-extern const char *ConnectorTypeName[], *ConnectorTypeNameATOM[];
 
-Bool
-RADEONRandRCreateScreenResources (ScreenPtr pScreen)
-{
-#if RANDR_12_INTERFACE
-    if (RADEONRandRCreateScreenResources12 (pScreen))
-      return TRUE;
-#endif
-    return FALSE;
+    return xf86RandR12SetInfo12 (pScreen);
 }
 
 static Bool
-xf86RandR12CreateObjects12(ScreenPtr pScreen)
-{
-  ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-  xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-  int c, o;
-
-  if (!RRInit())
-    return FALSE;
-
-
-  /*
-   * Configure crtcs
-   */
-  for (c = 0; c < config->num_crtc; c++)
-  {
-    xf86CrtcPtr    crtc = config->crtc[c];
-    
-    crtc->randr_crtc = RRCrtcCreate (crtc);
-    RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
-    RRCrtcGammaSetSize (crtc->randr_crtc, 256);
-  }
-
-  /*
-   * Configure outputs
-   */
-  for (o = 0; o < config->num_output; o++)
-  {
-    xf86OutputPtr	output = config->output[o];
-    
-    output->randr_output = RROutputCreate (output->name, 
-					   strlen (output->name),
-					   output);
-    RROutputAttachScreen (output->randr_output, pScreen);
-  } 
-
-  return TRUE;
-}
-
-static Bool
-xf86RandRCreateScreenResources12 (ScreenPtr pScreen)
+xf86RandR12CreateObjects12 (ScreenPtr pScreen)
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
-    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
     int			c;
-    int			width, height;
+    int			o;
+    
+    if (!RRInit ())
+	return FALSE;
 
     /*
-     * Compute width of screen
+     * Configure crtcs
      */
-    width = 0; height = 0;
     for (c = 0; c < config->num_crtc; c++)
     {
-	xf86CrtcPtr crtc = config->crtc[c];
-	int	    crtc_width = crtc->x + crtc->curMode.HDisplay;
-	int	    crtc_height = crtc->y + crtc->curMode.VDisplay;
+	xf86CrtcPtr    crtc = config->crtc[c];
 	
-	if (crtc->enabled && crtc_width > width)
-	    width = crtc_width;
-	if (crtc->enabled && crtc_height > height)
-	    height = crtc_height;
+	crtc->randr_crtc = RRCrtcCreate (crtc);
+	RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
+	RRCrtcGammaSetSize (crtc->randr_crtc, 256);
     }
-    
-    if (width && height)
+    /*
+     * Configure outputs
+     */
+    for (o = 0; o < config->num_output; o++)
     {
-	int mmWidth, mmHeight;
+	xf86OutputPtr	output = config->output[o];
 
-	mmWidth = pScreen->mmWidth;
-	mmHeight = pScreen->mmHeight;
-	if (width != pScreen->width)
-	    mmWidth = mmWidth * width / pScreen->width;
-	if (height != pScreen->height)
-	    mmHeight = mmHeight * height / pScreen->height;
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Setting screen physical size to %d x %d\n",
-		   mmWidth, mmHeight);
-	xf86RandR12ScreenSetSize (pScreen,
-				  width,
-				  height,
-				  mmWidth,
-				  mmHeight);
+	output->randr_output = RROutputCreate (output->name, 
+					       strlen (output->name),
+					       output);
+	RROutputAttachScreen (output->randr_output, pScreen);
     }
+    return TRUE;
+}
+
+static Bool
+xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
+{
+    int			c;
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
 
     for (c = 0; c < config->num_crtc; c++)
 	xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
     
-    if (randrp->virtualX == -1 || randrp->virtualY == -1)
-    {
-	randrp->virtualX = pScrn->virtualX;
-	randrp->virtualY = pScrn->virtualY;
-    }
     
     RRScreenSetSizeRange (pScreen, 320, 240,
 			  randrp->virtualX, randrp->virtualY);
     return TRUE;
 }
 
-Bool
-RADEONRandRInit (ScreenPtr    pScreen, int rotation)
+static void
+xf86RandR12PointerMoved (int scrnIndex, int x, int y)
 {
-    rrScrPrivPtr	rp;
-    XF86RandRInfoPtr	randrp;
-    
-#ifdef PANORAMIX
-    /* XXX disable RandR when using Xinerama */
-    if (!noPanoramiXExtension)
-	return TRUE;
-#endif
-    if (xf86RandR12Generation != serverGeneration)
-    {
-	xf86RandR12Index = AllocateScreenPrivateIndex();
-	xf86RandR12Generation = serverGeneration;
-    }
-    
-    randrp = xalloc (sizeof (XF86RandRInfoRec));
-    if (!randrp)
-	return FALSE;
-			
-    if (!RRScreenInit(pScreen))
-    {
-	xfree (randrp);
-	return FALSE;
-    }
-    rp = rrGetScrPriv(pScreen);
-    //    rp->rrGetInfo = RADEONRandRGetInfo;
-    //    rp->rrSetConfig = RADEONRandRSetConfig;
-
-    randrp->virtualX = -1;
-    randrp->virtualY = -1;
-    randrp->mmWidth = pScreen->mmWidth;
-    randrp->mmHeight = pScreen->mmHeight;
-    
-    randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
-    randrp->supported_rotations = rotation;
-
-    randrp->maxX = randrp->maxY = 0;
-
-    pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
-
-#if RANDR_12_INTERFACE
-    if (!RADEONRandRInit12 (pScreen))
-	return FALSE;
-#endif
-    return TRUE;
 }
 
-Bool
-RADEONRandRInit12(ScreenPtr pScreen)
+static Bool
+xf86RandR12Init12 (ScreenPtr pScreen)
 {
-  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-  rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    rrScrPrivPtr	rp = rrGetScrPriv(pScreen);
 
     rp->rrGetInfo = xf86RandR12GetInfo12;
     rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
     rp->rrCrtcSet = xf86RandR12CrtcSet;
     rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
-  rp->rrSetConfig = NULL;
-  //  memset (rp->modes, '\0', sizeof (rp->modes));
-  pScrn->PointerMoved = RADEONRandRPointerMoved;
-
-  if (!xf86RandR12CreateObjects12 (pScreen))
-    return FALSE;
-  /*
-   * Configure output modes
-   */
-  if (!xf86RandR12SetInfo12 (pScreen))
-    return FALSE;
-  return TRUE;
-}
-
-static RRModePtr
-RADEONRRDefaultMode (RROutputPtr output)
-{
-    RRModePtr   target_mode = NULL;
-    int		target_diff = 0;
-    int		mmHeight;
-    int		num_modes;
-    int		m;
-    
-    num_modes = output->numPreferred ? output->numPreferred : output->numModes;
-    mmHeight = output->mmHeight;
-    if (!mmHeight)
-	mmHeight = 203;	/* 768 pixels at 96dpi */
-    /*
-     * Pick a mode closest to 96dpi 
-     */
-    for (m = 0; m < num_modes; m++)
-    {
-	RRModePtr   mode = output->modes[m];
-	int	    dpi;
-	int	    diff;
-
-	dpi = (mode->mode.height * 254) / (mmHeight * 10);
-	diff = dpi - 96;
-	diff = diff < 0 ? -diff : diff;
-	if (target_mode == NULL || diff < target_diff)
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	}
-    }
-    return target_mode;
-}
-
-static RRModePtr
-RADEONClosestMode (RROutputPtr output, RRModePtr match)
-{
-    RRModePtr   target_mode = NULL;
-    int		target_diff = 0;
-    int		m;
-    
-    /*
-     * Pick a mode closest to the specified mode
-     */
-    for (m = 0; m < output->numModes; m++)
-    {
-	RRModePtr   mode = output->modes[m];
-	int	    dx, dy;
-	int	    diff;
-
-	/* exact matches are preferred */
-	if (mode == match)
-	    return mode;
-	
-	dx = match->mode.width - mode->mode.width;
-	dy = match->mode.height - mode->mode.height;
-	diff = dx * dx + dy * dy;
-	if (target_mode == NULL || diff < target_diff)
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	}
-    }
-    return target_mode;
-}
-
-static int
-RADEONRRPickCrtcs (RROutputPtr	*outputs,
-		 RRCrtcPtr	*best_crtcs,
-		 RRModePtr	*modes,
-		 int		num_outputs,
-		 int		n)
-{
-    int		c, o, l;
-    RROutputPtr	output;
-    RRCrtcPtr	crtc;
-    RRCrtcPtr	*crtcs;
-    RRCrtcPtr	best_crtc;
-    int		best_score;
-    int		score;
-    int		my_score;
-    
-    if (n == num_outputs)
-	return 0;
-    output = outputs[n];
-    
-    /*
-     * Compute score with this output disabled
-     */
-    best_crtcs[n] = NULL;
-    best_crtc = NULL;
-    best_score = RADEONRRPickCrtcs (outputs, best_crtcs, modes, num_outputs, n+1);
-    if (modes[n] == NULL)
-	return best_score;
-    
-    crtcs = xalloc (num_outputs * sizeof (RRCrtcPtr));
-    if (!crtcs)
-	return best_score;
-
-    my_score = 1;
-    /* Score outputs that are known to be connected higher */
-    if (output->connection == RR_Connected)
-	my_score++;
-    /* Score outputs with preferred modes higher */
-    if (output->numPreferred)
-	my_score++;
-    /*
-     * Select a crtc for this output and
-     * then attempt to configure the remaining
-     * outputs
-     */
-    for (c = 0; c < output->numCrtcs; c++)
-    {
-	crtc = output->crtcs[c];
-	/*
-	 * Check to see if some other output is
-	 * using this crtc
-	 */
-	for (o = 0; o < n; o++)
-	    if (best_crtcs[o] == crtc)
-		break;
-	if (o < n)
-	{
-	    /*
-	     * If the two outputs desire the same mode,
-	     * see if they can be cloned
-	     */
-	    if (modes[o] == modes[n])
-	    {
-		for (l = 0; l < output->numClones; l++)
-		    if (output->clones[l] == outputs[o])
-			break;
-		if (l == output->numClones)
-		    continue;		/* nope, try next CRTC */
-	    }
-	    else
-		continue;		/* different modes, can't clone */
-	}
-	crtcs[n] = crtc;
-	memcpy (crtcs, best_crtcs, n * sizeof (RRCrtcPtr));
-	score = my_score + RADEONRRPickCrtcs (outputs, crtcs, modes,
-					    num_outputs, n+1);
-	if (score >= best_score)
-	{
-	    best_crtc = crtc;
-	    best_score = score;
-	    memcpy (best_crtcs, crtcs, num_outputs * sizeof (RRCrtcPtr));
-	}
-    }
-    xfree (crtcs);
-    return best_score;
-}
-
-static Bool
-RADEONRRInitialConfiguration (RROutputPtr *outputs,
-			    RRCrtcPtr	*crtcs,
-			    RRModePtr	*modes,
-			    int		num_outputs)
-{
-    int		o;
-    RRModePtr	target_mode = NULL;
+    rp->rrSetConfig = NULL;
+    pScrn->PointerMoved = xf86RandR12PointerMoved;
+    if (!xf86RandR12CreateObjects12 (pScreen))
+	return FALSE;
 
-    for (o = 0; o < num_outputs; o++)
-	modes[o] = NULL;
-    
     /*
-     * Let outputs with preferred modes drive screen size
+     * Configure output modes
      */
-    for (o = 0; o < num_outputs; o++)
-    {
-	RROutputPtr output = outputs[o];
-
-	if (output->connection != RR_Disconnected && output->numPreferred)
-	{
-	    target_mode = RADEONRRDefaultMode (output);
-	    if (target_mode)
-	    {
-		modes[o] = target_mode;
-		break;
-	    }
-	}
-    }
-    if (!target_mode)
-    {
-	for (o = 0; o < num_outputs; o++)
-	{
-	    RROutputPtr output = outputs[o];
-	    if (output->connection != RR_Disconnected)
-	    {
-		target_mode = RADEONRRDefaultMode (output);
-		if (target_mode)
-		{
-		    modes[o] = target_mode;
-		    break;
-		}
-	    }
-	}
-    }
-    for (o = 0; o < num_outputs; o++)
-    {
-	RROutputPtr output = outputs[o];
-	
-	if (output->connection != RR_Disconnected && !modes[o])
-	    modes[o] = RADEONClosestMode (output, target_mode);
-    }
-
-    if (!RADEONRRPickCrtcs (outputs, crtcs, modes, num_outputs, 0))
+    if (!xf86RandR12SetInfo12 (pScreen))
 	return FALSE;
-    
     return TRUE;
 }
 
-/*
- * Compute the virtual size necessary to place all of the available
- * crtcs in a panorama configuration
- */
-
-static void
-RADEONRRDefaultScreenLimits (RROutputPtr *outputs, int num_outputs,
-			   RRCrtcPtr *crtcs, int num_crtc,
-			   int *widthp, int *heightp)
-{
-    int	    width = 0, height = 0;
-    int	    o;
-    int	    c;
-    int	    m;
-    int	    s;
-
-    for (c = 0; c < num_crtc; c++)
-    {
-	RRCrtcPtr   crtc = crtcs[c];
-	int	    crtc_width = 1600, crtc_height = 1200;
-
-	for (o = 0; o < num_outputs; o++) 
-	{
-	    RROutputPtr	output = outputs[o];
-
-	    for (s = 0; s < output->numCrtcs; s++)
-		if (output->crtcs[s] == crtc)
-		    break;
-	    if (s == output->numCrtcs)
-		continue;
-	    for (m = 0; m < output->numModes; m++)
-	    {
-		RRModePtr   mode = output->modes[m];
-		if (mode->mode.width > crtc_width)
-		    crtc_width = mode->mode.width;
-		if (mode->mode.height > crtc_width)
-		    crtc_height = mode->mode.height;
-	    }
-	}
-	width += crtc_width;
-	if (crtc_height > height)
-	    height = crtc_height;
-    }
-    *widthp = width;
-    *heightp = height;
-}
-
-#if 0
-Bool
-RADEONRandRPreInit(ScrnInfoPtr pScrn)
-{
-  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-#if RANDR_12_INTERFACE
-  RROutputPtr outputs[RADEON_MAX_CONNECTOR];
-  RRCrtcPtr output_crtcs[RADEON_MAX_CONNECTOR];
-  RRModePtr output_modes[RADEON_MAX_CONNECTOR];
-  RRCrtcPtr crtcs[RADEON_MAX_CRTC];
-#endif
-  int conn, crtc;
-  int o,c;
-  int width, height;
-
-  RADEONProbeOutputModes(pScrn);
-
-#if RANDR_12_INTERFACE
-  if (!xf86RandRCreateObjects12(pScrn))
-    return FALSE;
-
-  if (!RADEONRandRSetInfo12(pScrn))
-    return FALSE;
-  
-#endif
-    
-  /*
-   * With RandR info set up, let RandR choose
-   * the initial configuration
-   */
-  for (o = 0; o < RADEON_MAX_CONNECTOR; o++)
-    outputs[o] = pRADEONEnt->pOutput[o]->randr_output;
-  for (c = 0; c < RADEON_MAX_CRTC; c++)
-    crtcs[c] = pRADEONEnt->pCrtc[c]->randr_crtc;
-  
-  if (!RADEONRRInitialConfiguration (outputs, output_crtcs, output_modes,
-				     RADEON_MAX_CONNECTOR))
-	return FALSE;
-    
-  RADEONRRDefaultScreenLimits (outputs, RADEON_MAX_CONNECTOR,
-			       crtcs, RADEON_MAX_CRTC,
-			       &width, &height);
-    
-    if (width > pScrn->virtualX)
-      pScrn->virtualX = width;
-    if (height > pScrn->virtualY)
-      pScrn->virtualY = height;
-    
-    for (o = 0; o < RADEON_MAX_CONNECTOR; o++)
-    {
-	RRModePtr	randr_mode = output_modes[o];
-	DisplayModePtr	mode;
-	RRCrtcPtr	randr_crtc = output_crtcs[o];
-	int		pipe;
-	Bool		enabled;
-
-	if (randr_mode)
-	    mode = (DisplayModePtr) randr_mode->devPrivate;
-	else
-	    mode = NULL;
-	if (randr_crtc)
-	{
-	    pipe = (int) randr_crtc->devPrivate;
-	    enabled = TRUE;
-	}
-	else
-	{
-	    pipe = 0;
-	    enabled = FALSE;
-	}
-	//	if (mode)
-	//	    pRADEON->pipes[pipe].desiredMode = *mode;
-	//	pRADEON->output[o].pipe = pipe;
-	    //	pRADEON->output[o].enabled = enabled;
-    }
-
-  RADEON_set_xf86_modes_from_outputs(pScrn);
-  RADEON_set_default_screen_size(pScrn);
-    
-  return TRUE;
-}
-#endif
 #endif
 
 Bool
diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
index 76b03f5..7414d34 100644
--- a/src/radeon_xf86Crtc.c
+++ b/src/radeon_xf86Crtc.c
@@ -5,21 +5,21 @@
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
  *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -34,10 +34,12 @@
 #include "xf86DDC.h"
 //#include "i.h"
 #include "radeon_xf86Crtc.h"
+#include "radeon_xf86Modes.h"
 #include "X11/extensions/render.h"
 
 #define DPMS_SERVER
 #include "X11/extensions/dpms.h"
+#include "X11/Xatom.h"
 
 /*
  * Initialize xf86CrtcConfig structure
@@ -124,6 +126,79 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
 /*
  * Output functions
  */
+
+extern XF86ConfigPtr xf86configptr;
+
+typedef enum {
+    OPTION_PREFERRED_MODE,
+    OPTION_POSITION,
+    OPTION_BELOW,
+    OPTION_RIGHT_OF,
+    OPTION_ABOVE,
+    OPTION_LEFT_OF,
+    OPTION_ENABLE,
+    OPTION_DISABLE,
+    OPTION_MIN_CLOCK,
+    OPTION_MAX_CLOCK,
+} OutputOpts;
+
+static OptionInfoRec xf86OutputOptions[] = {
+    {OPTION_PREFERRED_MODE, "PreferredMode",	OPTV_STRING,  {0}, FALSE },
+    {OPTION_POSITION,	    "Position",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_BELOW,	    "Below",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_RIGHT_OF,	    "RightOf",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_ABOVE,	    "Above",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_LEFT_OF,	    "LeftOf",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_ENABLE,	    "Enable",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_DISABLE,	    "Disable",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_MIN_CLOCK,	    "MinClock",		OPTV_FREQ,    {0}, FALSE },
+    {OPTION_MAX_CLOCK,	    "MaxClock",		OPTV_FREQ,    {0}, FALSE },
+    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
+};
+
+static void
+xf86OutputSetMonitor (xf86OutputPtr output)
+{
+    char    *option_name;
+    static const char monitor_prefix[] = "monitor-";
+    char    *monitor;
+
+    if (output->options)
+	xfree (output->options);
+
+    output->options = xnfalloc (sizeof (xf86OutputOptions));
+    memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
+    
+    option_name = xnfalloc (strlen (monitor_prefix) +
+			    strlen (output->name) + 1);
+    strcpy (option_name, monitor_prefix);
+    strcat (option_name, output->name);
+    monitor = xf86findOptionValue (output->scrn->options, option_name);
+    if (!monitor)
+	monitor = output->name;
+    else
+	xf86MarkOptionUsedByName (output->scrn->options, option_name);
+    xfree (option_name);
+    output->conf_monitor = xf86findMonitor (monitor,
+					    xf86configptr->conf_monitor_lst);
+    if (output->conf_monitor)
+	xf86ProcessOptions (output->scrn->scrnIndex,
+			    output->conf_monitor->mon_option_lst,
+			    output->options);
+}
+
+static Bool
+xf86OutputEnabled (xf86OutputPtr    output)
+{
+    /* Check to see if this output was disabled in the config file */
+    if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
+	xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
+    {
+	return FALSE;
+    }
+    return TRUE;
+}
+
 xf86OutputPtr
 xf86OutputCreate (ScrnInfoPtr		    scrn,
 		  const xf86OutputFuncsRec *funcs,
@@ -144,6 +219,8 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
 #ifdef RANDR_12_INTERFACE
     output->randr_output = NULL;
 #endif
+    xf86OutputSetMonitor (output);
+    
     if (xf86_config->output)
 	outputs = xrealloc (xf86_config->output,
 			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
@@ -154,24 +231,28 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
 	xfree (output);
 	return NULL;
     }
+    
     xf86_config->output = outputs;
     xf86_config->output[xf86_config->num_output++] = output;
+    
     return output;
 }
 
-void
+Bool
 xf86OutputRename (xf86OutputPtr output, const char *name)
 {
     int	    len = strlen(name);
     char    *newname = xalloc (len + 1);
     
     if (!newname)
-	return;	/* so sorry... */
+	return FALSE;	/* so sorry... */
     
     strcpy (newname, name);
     if (output->name != (char *) (output + 1))
 	xfree (output->name);
     output->name = newname;
+    xf86OutputSetMonitor (output);
+    return TRUE;
 }
 
 void
@@ -348,7 +429,9 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 	     * If the two outputs desire the same mode,
 	     * see if they can be cloned
 	     */
-	    if (xf86ModesEqual (modes[o], modes[n]))
+	    if (xf86ModesEqual (modes[o], modes[n]) &&
+		config->output[o]->initial_x == config->output[n]->initial_x &&
+		config->output[o]->initial_y == config->output[n]->initial_y)
 	    {
 		for (l = 0; l < config->num_output; l++)
 		    if (output->possible_clones & (1 << l))
@@ -362,7 +445,7 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 	crtcs[n] = crtc;
 	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
 	score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
-	if (score >= best_score)
+	if (score > best_score)
 	{
 	    best_crtc = crtc;
 	    best_score = score;
@@ -376,7 +459,8 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 
 /*
  * Compute the virtual size necessary to place all of the available
- * crtcs in a panorama configuration
+ * crtcs in the specified configuration and also large enough to
+ * resize any crtc to the largest available mode
  */
 
 static void
@@ -391,7 +475,13 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
     for (c = 0; c < config->num_crtc; c++)
     {
 	int	    crtc_width = 0, crtc_height = 0;
+	xf86CrtcPtr crtc = config->crtc[c];
 
+	if (crtc->enabled)
+	{
+	    crtc_width = crtc->x + crtc->desiredMode.HDisplay;
+	    crtc_height = crtc->y + crtc->desiredMode.VDisplay;
+	}
 	for (o = 0; o < config->num_output; o++) 
 	{
 	    xf86OutputPtr   output = config->output[o];
@@ -409,7 +499,8 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
 		    }
 		}
 	}
-	width += crtc_width;
+	if (crtc_width > width)
+	    width = crtc_width;
 	if (crtc_height > height)
 	    height = crtc_height;
     }
@@ -421,6 +512,186 @@ xf86DefaultScreenLimits (ScrnInfoPtr pSc
     *heightp = height;
 }
 
+#define POSITION_UNSET	-100000
+
+static Bool
+xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o;
+    int			min_x, min_y;
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->initial_x = output->initial_y = POSITION_UNSET;
+    }
+    
+    /*
+     * Loop until all outputs are set
+     */
+    for (;;)
+    {
+	Bool	any_set = FALSE;
+	Bool	keep_going = FALSE;
+
+	for (o = 0; o < config->num_output; o++)	
+	{
+	    static const OutputOpts	relations[] = {
+		OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+	    };
+	    xf86OutputPtr   output = config->output[o];
+	    xf86OutputPtr   relative;
+	    char	    *relative_name;
+	    char	    *position;
+	    OutputOpts	    relation;
+	    int		    r;
+
+	    if (output->initial_x != POSITION_UNSET)
+		continue;
+	    position = xf86GetOptValString (output->options,
+					    OPTION_POSITION);
+	    /*
+	     * Absolute position wins
+	     */
+	    if (position)
+	    {
+		int		    x, y;
+		if (sscanf (position, "%d %d", &x, &y) == 2)
+		{
+		    output->initial_x = x;
+		    output->initial_y = y;
+		}
+		else
+		{
+		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+				"Output %s position not of form \"x y\"\n",
+				output->name);
+		    output->initial_x = output->initial_y = 0;
+		}
+		any_set = TRUE;
+		continue;
+	    }
+	    /*
+	     * Next comes relative positions
+	     */
+	    relation = 0;
+	    relative_name = NULL;
+	    for (r = 0; r < 4; r++)
+	    {
+		relation = relations[r];
+		relative_name = xf86GetOptValString (output->options,
+						     relation);
+		if (relative_name)
+		    break;
+	    }
+	    if (relative_name)
+	    {
+		int or;
+		relative = NULL;
+		for (or = 0; or < config->num_output; or++)
+		{
+		    xf86OutputPtr	out_rel = config->output[or];
+		    XF86ConfMonitorPtr	rel_mon = out_rel->conf_monitor;
+		    char		*name;
+
+		    if (rel_mon)
+			name = rel_mon->mon_identifier;
+		    else
+			name = out_rel->name;
+		    if (!strcmp (relative_name, name))
+		    {
+			relative = config->output[or];
+			break;
+		    }
+		}
+		if (!relative)
+		{
+		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+				"Cannot position output %s relative to unknown output %s\n",
+				output->name, relative_name);
+		    output->initial_x = 0;
+		    output->initial_y = 0;
+		    any_set = TRUE;
+		    continue;
+		}
+		if (relative->initial_x == POSITION_UNSET)
+		{
+		    keep_going = TRUE;
+		    continue;
+		}
+		output->initial_x = relative->initial_x;
+		output->initial_y = relative->initial_y;
+		switch (relation) {
+		case OPTION_BELOW:
+		    output->initial_y += modes[or]->VDisplay;
+		    break;
+		case OPTION_RIGHT_OF:
+		    output->initial_x += modes[or]->HDisplay;
+		    break;
+		case OPTION_ABOVE:
+		    output->initial_y -= modes[o]->VDisplay;
+		    break;
+		case OPTION_LEFT_OF:
+		    output->initial_x -= modes[o]->HDisplay;
+		    break;
+		default:
+		    break;
+		}
+		any_set = TRUE;
+		continue;
+	    }
+	    
+	    /* Nothing set, just stick them at 0,0 */
+	    output->initial_x = 0;
+	    output->initial_y = 0;
+	    any_set = TRUE;
+	}
+	if (!keep_going)
+	    break;
+	if (!any_set) 
+	{
+	    for (o = 0; o < config->num_output; o++)
+	    {
+		xf86OutputPtr   output = config->output[o];
+		if (output->initial_x == POSITION_UNSET)
+		{
+		    xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+				"Output position loop. Moving %s to 0,0\n",
+				output->name);
+		    output->initial_x = output->initial_y = 0;
+		    break;
+		}
+	    }
+	}
+    }
+
+    /*
+     * normalize positions
+     */
+    min_x = 1000000;
+    min_y = 1000000;
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	if (output->initial_x < min_x)
+	    min_x = output->initial_x;
+	if (output->initial_y < min_y)
+	    min_y = output->initial_y;
+    }
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->initial_x -= min_x;
+	output->initial_y -= min_y;
+    }
+    return TRUE;
+}
+
 /*
  * XXX walk the monitor mode list and prune out duplicates that
  * are inserted by xf86DDCMonitorSet. In an ideal world, that
@@ -440,39 +711,270 @@ xf86PruneDuplicateMonitorModes (MonPtr M
 	{
 	    next = clone->next;
 	    if (xf86ModesEqual (master, clone))
+	    {
+		if (Monitor->Last == clone)
+		    Monitor->Last = clone->prev;
 		xf86DeleteMode (&Monitor->Modes, clone);
+	    }
+	}
+    }
+}
+
+/** Return - 0 + if a should be earlier, same or later than b in list
+ */
+static int
+i830xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
+{
+    int	diff;
+
+    diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
+    if (diff)
+	return diff;
+    diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
+    if (diff)
+	return diff;
+    diff = b->Clock - a->Clock;
+    return diff;
+}
+
+/**
+ * Insertion sort input in-place and return the resulting head
+ */
+static DisplayModePtr
+i830xf86SortModes (DisplayModePtr input)
+{
+    DisplayModePtr  output = NULL, i, o, n, *op, prev;
+
+    /* sort by preferred status and pixel area */
+    while (input)
+    {
+	i = input;
+	input = input->next;
+	for (op = &output; (o = *op); op = &o->next)
+	    if (i830xf86ModeCompare (o, i) > 0)
+		break;
+	i->next = *op;
+	*op = i;
+    }
+    /* prune identical modes */
+    for (o = output; o && (n = o->next); o = n)
+    {
+	if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
+	{
+	    o->next = n->next;
+	    xfree (n->name);
+	    xfree (n);
+	    n = o;
 	}
     }
+    /* hook up backward links */
+    prev = NULL;
+    for (o = output; o; o = o->next)
+    {
+	o->prev = prev;
+	prev = o;
+    }
+    return output;
 }
 
+#define DEBUG_REPROBE 1
+
 void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn)
+xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
 {
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
-    Bool		properties_set = FALSE;
     int			o;
 
+    if (maxX == 0 || maxY == 0)
+	xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY);
+
     /* Elide duplicate modes before defaulting code uses them */
     xf86PruneDuplicateMonitorModes (pScrn->monitor);
     
     /* Probe the list of modes for each output. */
     for (o = 0; o < config->num_output; o++) 
     {
-	xf86OutputPtr  output = config->output[o];
-	DisplayModePtr mode;
-
+	xf86OutputPtr	    output = config->output[o];
+	DisplayModePtr	    mode;
+	DisplayModePtr	    config_modes = NULL, output_modes, default_modes;
+	char		    *preferred_mode;
+	xf86MonPtr	    edid_monitor;
+	XF86ConfMonitorPtr  conf_monitor;
+	MonRec		    mon_rec;
+	int		    min_clock = 0;
+	int		    max_clock = 0;
+	double		    clock;
+	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
+	
 	while (output->probed_modes != NULL)
 	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
 
-	output->probed_modes = (*output->funcs->get_modes) (output);
+	/*
+	 * Check connection status
+	 */
+	output->status = (*output->funcs->detect)(output);
+
+	if (output->status == XF86OutputStatusDisconnected)
+	    continue;
+
+	memset (&mon_rec, '\0', sizeof (mon_rec));
+	
+	conf_monitor = output->conf_monitor;
+	
+	if (conf_monitor)
+	{
+	    int	i;
+	    
+	    for (i = 0; i < conf_monitor->mon_n_hsync; i++)
+	    {
+		mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
+		mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
+		mon_rec.nHsync++;
+		sync_source = sync_config;
+	    }
+	    for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
+	    {
+		mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
+		mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
+		mon_rec.nVrefresh++;
+		sync_source = sync_config;
+	    }
+	    config_modes = i830xf86GetMonitorModes (pScrn, conf_monitor);
+	}
+	
+	output_modes = (*output->funcs->get_modes) (output);
+	
+	edid_monitor = output->MonInfo;
+	
+	if (edid_monitor)
+	{
+	    int			    i;
+	    Bool		    set_hsync = mon_rec.nHsync == 0;
+	    Bool		    set_vrefresh = mon_rec.nVrefresh == 0;
 
-	/* Set the DDC properties to whatever first output has DDC information.
+	    for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
+	    {
+		if (edid_monitor->det_mon[i].type == DS_RANGES)
+		{
+		    struct monitor_ranges   *ranges = &edid_monitor->det_mon[i].section.ranges;
+		    if (set_hsync && ranges->max_h)
+		    {
+			mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h;
+			mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h;
+			mon_rec.nHsync++;
+			if (sync_source == sync_default)
+			    sync_source = sync_edid;
+		    }
+		    if (set_vrefresh && ranges->max_v)
+		    {
+			mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v;
+			mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v;
+			mon_rec.nVrefresh++;
+			if (sync_source == sync_default)
+			    sync_source = sync_edid;
+		    }
+		    if (ranges->max_clock > max_clock)
+			max_clock = ranges->max_clock;
+		}
+	    }
+	}
+
+	if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
+			       OPTUNITS_KHZ, &clock))
+	    min_clock = (int) clock;
+	if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
+			       OPTUNITS_KHZ, &clock))
+	    max_clock = (int) clock;
+
+	/*
+	 * These limits will end up setting a 1024x768 at 60Hz mode by default,
+	 * which seems like a fairly good mode to use when nothing else is
+	 * specified
 	 */
-	if (output->MonInfo != NULL && !properties_set) {
-	    xf86SetDDCproperties(pScrn, output->MonInfo);
-	    properties_set = TRUE;
+	if (mon_rec.nHsync == 0)
+	{
+	    mon_rec.hsync[0].lo = 31.0;
+	    mon_rec.hsync[0].hi = 55.0;
+	    mon_rec.nHsync = 1;
+	}
+	if (mon_rec.nVrefresh == 0)
+	{
+	    mon_rec.vrefresh[0].lo = 58.0;
+	    mon_rec.vrefresh[0].hi = 62.0;
+	    mon_rec.nVrefresh = 1;
 	}
+	default_modes = RADEONxf86GetDefaultModes (output->interlaceAllowed,
+						 output->doubleScanAllowed);
+	
+	if (sync_source == sync_config)
+	{
+	    /* 
+	     * Check output and config modes against sync range from config file
+	     */
+	    RADEONxf86ValidateModesSync (pScrn, output_modes, &mon_rec);
+	    RADEONxf86ValidateModesSync (pScrn, config_modes, &mon_rec);
+	}
+	/*
+	 * Check default modes against sync range
+	 */
+        RADEONxf86ValidateModesSync (pScrn, default_modes, &mon_rec);
+	/*
+	 * Check default modes against monitor max clock
+	 */
+	if (max_clock)
+	    RADEONxf86ValidateModesClocks(pScrn, default_modes,
+					&min_clock, &max_clock, 1);
+	
+	output->probed_modes = NULL;
+	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
+	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
+	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
+	
+	/*
+	 * Check all modes against max size
+	 */
+	if (maxX && maxY)
+	    RADEONxf86ValidateModesSize (pScrn, output->probed_modes,
+				       maxX, maxY, 0);
+	 
+	/*
+	 * Check all modes against output
+	 */
+	for (mode = output->probed_modes; mode != NULL; mode = mode->next) 
+	    if (mode->status == MODE_OK)
+		mode->status = (*output->funcs->mode_valid)(output, mode);
+	
+	RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE);
+	
+	output->probed_modes = i830xf86SortModes (output->probed_modes);
+	
+	/* Check for a configured preference for a particular mode */
+	preferred_mode = xf86GetOptValString (output->options,
+					      OPTION_PREFERRED_MODE);
 
+	if (preferred_mode)
+	{
+	    for (mode = output->probed_modes; mode; mode = mode->next)
+	    {
+		if (!strcmp (preferred_mode, mode->name))
+		{
+		    if (mode != output->probed_modes)
+		    {
+			if (mode->prev)
+			    mode->prev->next = mode->next;
+			if (mode->next)
+			    mode->next->prev = mode->prev;
+			mode->next = output->probed_modes;
+			output->probed_modes->prev = mode;
+			mode->prev = NULL;
+			output->probed_modes = mode;
+		    }
+		    mode->type |= M_T_PREFERRED;
+		    break;
+		}
+	    }
+	}
+	
 #ifdef DEBUG_REPROBE
 	if (output->probed_modes != NULL) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -515,7 +1017,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     xf86OutputPtr	output;
     xf86CrtcPtr		crtc;
     DisplayModePtr	last, mode;
-    int			originalVirtualX, originalVirtualY;
 
     output = config->output[config->compat_output];
     if (!output->crtc)
@@ -543,31 +1044,23 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     /* Set pScrn->modes to the mode list for the 'compat' output */
     pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
 
-    xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
-
-    /* Disable modes in the XFree86 DDX list that are larger than the current
-     * virtual size.
-     */
-    RADEONxf86ValidateModesSize(pScrn, pScrn->modes,
-			      originalVirtualX, originalVirtualY,
-			      pScrn->displayWidth);
-
-    /* Strip out anything that we threw out for virtualX/Y. */
-    RADEONxf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
-
     for (mode = pScrn->modes; mode; mode = mode->next)
 	if (xf86ModesEqual (mode, &crtc->desiredMode))
 	    break;
-    
-    /* For some reason, pScrn->modes is circular, unlike the other mode lists.
-     * How great is that?
-     */
-    for (last = pScrn->modes; last && last->next; last = last->next);
-    last->next = pScrn->modes;
-    pScrn->modes->prev = last;
-    if (mode)
-	while (pScrn->modes != mode)
-	    pScrn->modes = pScrn->modes->next;
+
+    if (pScrn->modes != NULL) {
+	/* For some reason, pScrn->modes is circular, unlike the other mode
+	 * lists.  How great is that?
+	 */
+	for (last = pScrn->modes; last && last->next; last = last->next)
+	    ;
+	last->next = pScrn->modes;
+	pScrn->modes->prev = last;
+	if (mode) {
+	    while (pScrn->modes != mode)
+		pScrn->modes = pScrn->modes->next;
+	}
+    }
     pScrn->currentMode = pScrn->modes;
 }
 
@@ -586,35 +1079,33 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     DisplayModePtr	target_mode = NULL;
     xf86CrtcPtr		*crtcs;
     DisplayModePtr	*modes;
-    int			width, height;
-
-    xf86ProbeOutputModes (pScrn);
+    Bool		*enabled;
+    int			width;
+    int			height;
 
-    if (pScrn->display->virtualX == 0)
-    {
-	/*
-	 * Expand virtual size to cover potential mode switches
-	 */
-	xf86DefaultScreenLimits (pScrn, &width, &height);
-    
-	pScrn->display->virtualX = width;
-	pScrn->display->virtualY = height;
-    }
-    else
-    {
+    if (pScrn->display->virtualX)
 	width = pScrn->display->virtualX;
+    else
+	width = config->maxWidth;
+    if (pScrn->display->virtualY)
 	height = pScrn->display->virtualY;
-    }
-    if (width > pScrn->virtualX)
-	pScrn->virtualX = width;
-    if (height > pScrn->virtualY)
-	pScrn->virtualY = height;
-    
+    else
+	height = config->maxHeight;
+
+    xf86ProbeOutputModes (pScrn, width, height);
+
     crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
     modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
+    enabled = xnfcalloc (config->num_output, sizeof (Bool));
     
     for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr output = config->output[o];
+	
 	modes[o] = NULL;
+	enabled[o] = (xf86OutputEnabled (output) &&
+		      output->status != XF86OutputStatusDisconnected);
+    }
     
     /*
      * Let outputs with preferred modes drive screen size
@@ -623,7 +1114,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     {
 	xf86OutputPtr output = config->output[o];
 
-	if (output->status != XF86OutputStatusDisconnected &&
+	if (enabled[o] &&
 	    xf86OutputHasPreferredMode (output, width, height))
 	{
 	    target_mode = xf86DefaultMode (output, width, height);
@@ -640,7 +1131,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	for (o = 0; o < config->num_output; o++)
 	{
 	    xf86OutputPtr output = config->output[o];
-	    if (output->status != XF86OutputStatusDisconnected)
+	    if (enabled[o])
 	    {
 		target_mode = xf86DefaultMode (output, width, height);
 		if (target_mode)
@@ -656,10 +1147,23 @@ xf86InitialConfiguration (ScrnInfoPtr	  
     {
 	xf86OutputPtr output = config->output[o];
 	
-	if (output->status != XF86OutputStatusDisconnected && !modes[o])
+	if (enabled[o] && !modes[o])
 	    modes[o] = xf86ClosestMode (output, target_mode, width, height);
     }
 
+    /*
+     * Set the position of each output
+     */
+    if (!xf86InitialOutputPositions (pScrn, modes))
+    {
+	xfree (crtcs);
+	xfree (modes);
+	return FALSE;
+    }
+	
+    /*
+     * Assign CRTCs to fit output configuration
+     */
     if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
     {
 	xfree (crtcs);
@@ -679,7 +1183,7 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	crtc->enabled = FALSE;
 	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
     }
-	
+    
     /*
      * Set initial configuration
      */
@@ -693,13 +1197,28 @@ xf86InitialConfiguration (ScrnInfoPtr	  
 	{
 	    crtc->desiredMode = *mode;
 	    crtc->enabled = TRUE;
-	    crtc->x = 0;
-	    crtc->y = 0;
+	    crtc->x = output->initial_x;
+	    crtc->y = output->initial_y;
 	    output->crtc = crtc;
-	    /* XXX set position; for now, we clone */
 	}
     }
     
+    if (pScrn->display->virtualX == 0)
+    {
+	/*
+	 * Expand virtual size to cover potential mode switches
+	 */
+	xf86DefaultScreenLimits (pScrn, &width, &height);
+    
+	pScrn->display->virtualX = width;
+	pScrn->display->virtualY = height;
+    }
+
+    if (width > pScrn->virtualX)
+	pScrn->virtualX = width;
+    if (height > pScrn->virtualY)
+	pScrn->virtualY = height;
+    
     /* Mirror output modes to pScrn mode list */
     xf86SetScrnInfoModes (pScrn);
     
@@ -742,3 +1261,115 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode,
 	}
     }
 }
+
+#ifdef RANDR_12_INTERFACE
+
+#define EDID_ATOM_NAME		"EDID_DATA"
+
+/**
+ * Set the RandR EDID property
+ */
+static void
+xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
+{
+    Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
+
+    /* This may get called before the RandR resources have been created */
+    if (output->randr_output == NULL)
+	return;
+
+    if (data_len != 0) {
+	RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
+			       PropModeReplace, data_len, data, FALSE);
+    } else {
+	RRDeleteOutputProperty(output->randr_output, edid_atom);
+    }
+}
+
+#endif
+
+/**
+ * Set the EDID information for the specified output
+ */
+void
+i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
+{
+    ScrnInfoPtr		pScrn = output->scrn;
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			i;
+#ifdef RANDR_12_INTERFACE
+    int			size;
+#endif
+    
+    if (output->MonInfo != NULL)
+	xfree(output->MonInfo);
+    
+    output->MonInfo = edid_mon;
+
+    /* Debug info for now, at least */
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
+    xf86PrintEDID(edid_mon);
+    
+    /* Set the DDC properties for the 'compat' output */
+    if (output == config->output[config->compat_output])
+        xf86SetDDCproperties(pScrn, edid_mon);
+
+#ifdef RANDR_12_INTERFACE
+    /* Set the RandR output properties */
+    size = 0;
+    if (edid_mon)
+    {
+	if (edid_mon->ver.version == 1)
+	    size = 128;
+	else if (edid_mon->ver.version == 2)
+	    size = 256;
+    }
+    xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
+#endif
+
+    if (edid_mon)
+    {
+	/* Pull out a phyiscal size from a detailed timing if available. */
+	for (i = 0; i < 4; i++) {
+	    if (edid_mon->det_mon[i].type == DT &&
+		edid_mon->det_mon[i].section.d_timings.h_size != 0 &&
+		edid_mon->det_mon[i].section.d_timings.v_size != 0)
+	    {
+		output->mm_width = edid_mon->det_mon[i].section.d_timings.h_size;
+		output->mm_height = edid_mon->det_mon[i].section.d_timings.v_size;
+		break;
+	    }
+	}
+    
+	/* if no mm size is available from a detailed timing, check the max size field */
+	if ((!output->mm_width || !output->mm_height) &&
+	    (edid_mon->features.hsize && edid_mon->features.vsize))
+	{
+	    output->mm_width = edid_mon->features.hsize * 10;
+	    output->mm_height = edid_mon->features.vsize * 10;
+	}
+    }
+}
+
+/**
+ * Return the list of modes supported by the EDID information
+ * stored in 'output'
+ */
+DisplayModePtr
+i830_xf86OutputGetEDIDModes (xf86OutputPtr output)
+{
+    ScrnInfoPtr	pScrn = output->scrn;
+    xf86MonPtr	edid_mon = output->MonInfo;
+
+    if (!edid_mon)
+	return NULL;
+    return xf86DDCGetModes(pScrn->scrnIndex, edid_mon);
+}
+
+xf86MonPtr
+i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
+{
+    ScrnInfoPtr	pScrn = output->scrn;
+
+    return xf86DoEDID_DDC2 (pScrn->scrnIndex, pDDCBus);
+}
diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h
index 174647f..2f534f8 100644
--- a/src/radeon_xf86Crtc.h
+++ b/src/radeon_xf86Crtc.h
@@ -25,6 +25,15 @@
 #include <edid.h>
 #include "randrstr.h"
 #include "radeon_xf86Modes.h"
+#include "xf86Parser.h"
+
+/* Compat definitions for older X Servers. */
+#ifndef M_T_PREFERRED
+#define M_T_PREFERRED	0x08
+#endif
+#ifndef M_T_DRIVER
+#define M_T_DRIVER	0x40
+#endif
 
 typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
 typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
@@ -80,6 +89,11 @@ typedef struct _xf86CrtcFuncs {
 		DisplayModePtr mode,
 		DisplayModePtr adjusted_mode);
 
+    /* Set the color ramps for the CRTC to the given values. */
+    void
+    (*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
+		 int size);
+
     /**
      * Clean up driver-specific bits of the crtc
      */
@@ -260,6 +274,17 @@ struct _xf86Output {
      * Possible outputs to share the same CRTC as a mask of output indices
      */
     CARD32		possible_clones;
+    
+    /**
+     * Whether this output can support interlaced modes
+     */
+    Bool		interlaceAllowed;
+
+    /**
+     * Whether this output can support double scan modes
+     */
+    Bool		doubleScanAllowed;
+
     /**
      * List of available modes on this output.
      *
@@ -269,6 +294,21 @@ struct _xf86Output {
     DisplayModePtr	probed_modes;
 
     /**
+     * Options parsed from the related monitor section
+     */
+    OptionInfoPtr	options;
+    
+    /**
+     * Configured monitor section
+     */
+    XF86ConfMonitorPtr  conf_monitor;
+    
+    /**
+     * Desired initial position
+     */
+    int			initial_x, initial_y;
+
+    /**
      * Current connection status
      *
      * This indicates whether a monitor is known to be connected
@@ -379,14 +419,14 @@ xf86OutputCreate (ScrnInfoPtr		scrn,
 		      const xf86OutputFuncsRec *funcs,
 		      const char	*name);
 
-void
+Bool
 xf86OutputRename (xf86OutputPtr output, const char *name);
 
 void
 xf86OutputDestroy (xf86OutputPtr	output);
 
 void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn);
+xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
 
 void
 xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
@@ -396,5 +436,21 @@ xf86InitialConfiguration (ScrnInfoPtr pS
 
 void
 xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
+    
+/**
+ * Set the EDID information for the specified output
+ */
+void
+i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
+
+/**
+ * Return the list of modes supported by the EDID information
+ * stored in 'output'
+ */
+DisplayModePtr
+i830_xf86OutputGetEDIDModes (xf86OutputPtr output);
+
+xf86MonPtr
+i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
 
 #endif /* _XF86CRTC_H_ */
diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c
index e75ac79..fa7f97a 100644
--- a/src/radeon_xf86Modes.c
+++ b/src/radeon_xf86Modes.c
@@ -39,448 +39,23 @@
 #include "xf86.h"
 #include "radeon.h"
 #include "radeon_xf86Modes.h"
+#include "xf86Priv.h"
 
-
-#include <math.h>
-
-#define rint(x) floor(x)
-
-#define MARGIN_PERCENT    1.8   /* % of active vertical image                */
-#define CELL_GRAN         8.0   /* assumed character cell granularity        */
-#define MIN_PORCH         1     /* minimum front porch                       */
-#define V_SYNC_RQD        3     /* width of vsync in lines                   */
-#define H_SYNC_PERCENT    8.0   /* width of hsync as % of total line         */
-#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
-#define M                 600.0 /* blanking formula gradient                 */
-#define C                 40.0  /* blanking formula offset                   */
-#define K                 128.0 /* blanking formula scaling factor           */
-#define J                 20.0  /* blanking formula scaling factor           */
-
-/* C' and M' are part of the Blanking Duty Cycle computation */
-
-#define C_PRIME           (((C - J) * K/256.0) + J)
-#define M_PRIME           (K/256.0 * M)
-
-DisplayModePtr
-RADEONGetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins)
-{
-    float h_pixels_rnd;
-    float v_lines_rnd;
-    float v_field_rate_rqd;
-    float top_margin;
-    float bottom_margin;
-    float interlace;
-    float h_period_est;
-    float vsync_plus_bp;
-    float v_back_porch;
-    float total_v_lines;
-    float v_field_rate_est;
-    float h_period;
-    float v_field_rate;
-    float v_frame_rate;
-    float left_margin;
-    float right_margin;
-    float total_active_pixels;
-    float ideal_duty_cycle;
-    float h_blank;
-    float total_pixels;
-    float pixel_freq;
-    float h_freq;
-
-    float h_sync;
-    float h_front_porch;
-    float v_odd_front_porch_lines;
-    DisplayModePtr m;
-
-    m = xnfcalloc(sizeof(DisplayModeRec), 1);
-    
-    
-    /*  1. In order to give correct results, the number of horizontal
-     *  pixels requested is first processed to ensure that it is divisible
-     *  by the character size, by rounding it to the nearest character
-     *  cell boundary:
-     *
-     *  [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
-     */
-    
-    h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN;
-    
-    
-    /*  2. If interlace is requested, the number of vertical lines assumed
-     *  by the calculation must be halved, as the computation calculates
-     *  the number of vertical lines per field. In either case, the
-     *  number of lines is rounded to the nearest integer.
-     *   
-     *  [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
-     *                                     ROUND([V LINES],0))
-     */
-
-    v_lines_rnd = interlaced ?
-            rint((float) v_lines) / 2.0 :
-            rint((float) v_lines);
-    
-    /*  3. Find the frame rate required:
-     *
-     *  [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
-     *                                          [I/P FREQ RQD])
-     */
-
-    v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq);
-
-    /*  4. Find number of lines in Top margin:
-     *
-     *  [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
-     *          ROUND(([MARGIN%]/100*[V LINES RND]),0),
-     *          0)
-     */
-
-    top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0);
-
-    /*  5. Find number of lines in Bottom margin:
-     *
-     *  [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
-     *          ROUND(([MARGIN%]/100*[V LINES RND]),0),
-     *          0)
-     */
-
-    bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0);
-
-    /*  6. If interlace is required, then set variable [INTERLACE]=0.5:
-     *   
-     *  [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
-     */
-
-    interlace = interlaced ? 0.5 : 0.0;
-
-    /*  7. Estimate the Horizontal period
-     *
-     *  [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
-     *                    ([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
-     *                     [MIN PORCH RND]+[INTERLACE]) * 1000000
-     */
-
-    h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0))
-                    / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace)
-                    * 1000000.0);
-
-    /*  8. Find the number of lines in V sync + back porch:
-     *
-     *  [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
-     */
-
-    vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est);
-
-    /*  9. Find the number of lines in V back porch alone:
-     *
-     *  [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND]
-     *
-     *  XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]?
-     */
-    
-    v_back_porch = vsync_plus_bp - V_SYNC_RQD;
-    
-    /*  10. Find the total number of lines in Vertical field period:
-     *
-     *  [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] +
-     *                    [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] +
-     *                    [MIN PORCH RND]
-     */
-
-    total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp +
-        interlace + MIN_PORCH;
-    
-    /*  11. Estimate the Vertical field frequency:
-     *
-     *  [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
-     */
-
-    v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
-    
-    /*  12. Find the actual horizontal period:
-     *
-     *  [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
-     */
-
-    h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
-    
-    /*  13. Find the actual Vertical field frequency:
-     *
-     *  [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000
-     */
-
-    v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0;
-
-    /*  14. Find the Vertical frame frequency:
-     *
-     *  [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE]))
-     */
-
-    v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate;
-
-    /*  15. Find number of pixels in left margin:
-     *
-     *  [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
-     *          (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
-     *                   [CELL GRAN RND]),0)) * [CELL GRAN RND],
-     *          0))
-     */
-
-    left_margin = margins ?
-        rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
-        0.0;
-    
-    /*  16. Find number of pixels in right margin:
-     *
-     *  [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
-     *          (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
-     *                   [CELL GRAN RND]),0)) * [CELL GRAN RND],
-     *          0))
-     */
-    
-    right_margin = margins ?
-        rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
-        0.0;
-    
-    /*  17. Find total number of active pixels in image and left and right
-     *  margins:
-     *
-     *  [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] +
-     *                          [RIGHT MARGIN (PIXELS)]
-     */
-
-    total_active_pixels = h_pixels_rnd + left_margin + right_margin;
-    
-    /*  18. Find the ideal blanking duty cycle from the blanking duty cycle
-     *  equation:
-     *
-     *  [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
-     */
-
-    ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
-    
-    /*  19. Find the number of pixels in the blanking time to the nearest
-     *  double character cell:
-     *
-     *  [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
-     *                               [IDEAL DUTY CYCLE] /
-     *                               (100-[IDEAL DUTY CYCLE]) /
-     *                               (2*[CELL GRAN RND])), 0))
-     *                       * (2*[CELL GRAN RND])
-     */
-
-    h_blank = rint(total_active_pixels *
-                   ideal_duty_cycle /
-                   (100.0 - ideal_duty_cycle) /
-                   (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN);
-    
-    /*  20. Find total number of pixels:
-     *
-     *  [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
-     */
-
-    total_pixels = total_active_pixels + h_blank;
-    
-    /*  21. Find pixel clock frequency:
-     *
-     *  [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
-     */
-    
-    pixel_freq = total_pixels / h_period;
-    
-    /*  22. Find horizontal frequency:
-     *
-     *  [H FREQ] = 1000 / [H PERIOD]
-     */
-
-    h_freq = 1000.0 / h_period;
-    
-
-    /* Stage 1 computations are now complete; I should really pass
-       the results to another function and do the Stage 2
-       computations, but I only need a few more values so I'll just
-       append the computations here for now */
-
-    
-
-    /*  17. Find the number of pixels in the horizontal sync period:
-     *
-     *  [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
-     *                             [CELL GRAN RND]),0))*[CELL GRAN RND]
-     */
-
-    h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
-
-    /*  18. Find the number of pixels in the horizontal front porch period:
-     *
-     *  [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
-     */
-
-    h_front_porch = (h_blank / 2.0) - h_sync;
-
-    /*  36. Find the number of lines in the odd front porch period:
-     *
-     *  [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
-     */
-    
-    v_odd_front_porch_lines = MIN_PORCH + interlace;
-    
-    /* finally, pack the results in the DisplayMode struct */
-    
-    m->HDisplay  = (int) (h_pixels_rnd);
-    m->HSyncStart = (int) (h_pixels_rnd + h_front_porch);
-    m->HSyncEnd = (int) (h_pixels_rnd + h_front_porch + h_sync);
-    m->HTotal = (int) (total_pixels);
-
-    m->VDisplay  = (int) (v_lines_rnd);
-    m->VSyncStart = (int) (v_lines_rnd + v_odd_front_porch_lines);
-    m->VSyncEnd = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD);
-    m->VTotal = (int) (total_v_lines);
-
-    m->Clock   = (int)(pixel_freq * 1000);
-    m->SynthClock   = m->Clock;
-    m->HSync = h_freq;
-    m->VRefresh = v_frame_rate /* freq */;
-
-    RADEONxf86SetModeDefaultName(m);
-
-    return (m);
-}
-
-void
-RADEONPrintModes(ScrnInfoPtr scrp)
-{
-    DisplayModePtr p;
-    float hsync, refresh = 0;
-    char *desc, *desc2, *prefix, *uprefix;
-
-    if (scrp == NULL)
-	return;
-
-    xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
-	       "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
-	       scrp->displayWidth);
-    
-    p = scrp->modes;
-    if (p == NULL)
-	return;
-
-    do {
-	desc = desc2 = "";
-	if (p->HSync > 0.0)
-	    hsync = p->HSync;
-	else if (p->HTotal > 0)
-	    hsync = (float)p->Clock / (float)p->HTotal;
-	else
-	    hsync = 0.0;
-	if (p->VTotal > 0)
-	    refresh = hsync * 1000.0 / p->VTotal;
-	if (p->Flags & V_INTERLACE) {
-	    refresh *= 2.0;
-	    desc = " (I)";
-	}
-	if (p->Flags & V_DBLSCAN) {
-	    refresh /= 2.0;
-	    desc = " (D)";
-	}
-	if (p->VScan > 1) {
-	    refresh /= p->VScan;
-	    desc2 = " (VScan)";
-	}
-	if (p->VRefresh > 0.0)
-	    refresh = p->VRefresh;
-	if (p->type & M_T_BUILTIN)
-	    prefix = "Built-in mode";
-	else if (p->type & M_T_DEFAULT)
-	    prefix = "Default mode";
-	else
-	    prefix = "Mode";
-	if (p->type & M_T_USERDEF)
-	    uprefix = "*";
-	else
-	    uprefix = " ";
-	if (p->name)
-	    xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
-			   "%s%s \"%s\"\n", uprefix, prefix, p->name);
-	else
-	    xf86DrvMsg(scrp->scrnIndex, X_PROBED,
-			   "%s%s %dx%d (unnamed)\n",
-			   uprefix, prefix, p->HDisplay, p->VDisplay);
-	p = p->next;
-    } while (p != NULL && p != scrp->modes);
-}
-
-/* This function will sort all modes according to their resolution.
- * Highest resolution first.
- */
-void
-RADEONxf86SortModes(DisplayModePtr new, DisplayModePtr *first,
-	      DisplayModePtr *last)
-{
-    DisplayModePtr  p;
-
-    p = *last;
-    while (p) {
-	if (((new->HDisplay < p->HDisplay) &&
-	     (new->VDisplay < p->VDisplay)) ||
-	    ((new->HDisplay * new->VDisplay) < (p->HDisplay * p->VDisplay)) ||
-	    ((new->HDisplay == p->HDisplay) &&
-	     (new->VDisplay == p->VDisplay) &&
-	     (new->Clock < p->Clock))) {
-
-	    if (p->next) 
-		p->next->prev = new;
-	    new->prev = p;
-	    new->next = p->next;
-	    p->next = new;
-	    if (!(new->next))
-		*last = new;
-	    break;
-	}
-	if (!p->prev) {
-	    new->prev = NULL;
-	    new->next = p;
-	    p->prev = new;
-	    *first = new;
-	    break;
-	}
-	p = p->prev;
-    }
-
-    if (!*first) {
-	*first = new;
-	new->prev = NULL;
-	new->next = NULL;
-	*last = new;
-    }
-}
-
-DisplayModePtr
-RADEONGetModeListTail(DisplayModePtr pModeList)
-{
-    DisplayModePtr last;
-
-    if (pModeList == NULL)
-	return NULL;
-
-    for (last = pModeList; last->next != NULL; last = last->next)
-	;
-
-    return last;
-}
+extern XF86ConfigPtr xf86configptr;
 
 /**
  * @file this file contains symbols from xf86Mode.c and friends that are static
  * there but we still want to use.  We need to come up with better API here.
  */
 
-
+#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
 /**
  * Calculates the horizontal sync rate of a mode.
  *
  * Exact copy of xf86Mode.c's.
  */
 double
-RADEONxf86ModeHSync(DisplayModePtr mode)
+xf86ModeHSync(DisplayModePtr mode)
 {
     double hsync = 0.0;
     
@@ -498,7 +73,7 @@ RADEONxf86ModeHSync(DisplayModePtr mode)
  * Exact copy of xf86Mode.c's.
  */
 double
-RADEONxf86ModeVRefresh(DisplayModePtr mode)
+xf86ModeVRefresh(DisplayModePtr mode)
 {
     double refresh = 0.0;
 
@@ -516,14 +91,9 @@ RADEONxf86ModeVRefresh(DisplayModePtr mo
     return refresh;
 }
 
-/**
- * Sets a default mode name of <width>x<height>x<refresh> on a mode.
- *
- * The refresh rate doesn't contain decimals, as that's expected to be
- * unimportant from the user's perspective for non-custom modelines.
- */
+/** Sets a default mode name of <width>x<height> on a mode. */
 void
-RADEONxf86SetModeDefaultName(DisplayModePtr mode)
+xf86SetModeDefaultName(DisplayModePtr mode)
 {
     if (mode->name != NULL)
 	xfree(mode->name);
@@ -532,7 +102,7 @@ RADEONxf86SetModeDefaultName(DisplayMode
 }
 
 /*
- * RADEONxf86SetModeCrtc
+ * xf86SetModeCrtc
  *
  * Initialises the Crtc parameters for a mode.  The initialisation includes
  * adjustments for interlaced and double scan modes.
@@ -540,7 +110,7 @@ RADEONxf86SetModeDefaultName(DisplayMode
  * Exact copy of xf86Mode.c's.
  */
 void
-RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
+xf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
 {
     if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN))
 	return;
@@ -625,7 +195,7 @@ RADEONxf86SetModeCrtc(DisplayModePtr p, 
  * Allocates and returns a copy of pMode, including pointers within pMode.
  */
 DisplayModePtr
-RADEONxf86DuplicateMode(DisplayModePtr pMode)
+xf86DuplicateMode(DisplayModePtr pMode)
 {
     DisplayModePtr pNew;
 
@@ -634,7 +204,7 @@ RADEONxf86DuplicateMode(DisplayModePtr p
     pNew->next = NULL;
     pNew->prev = NULL;
     if (pNew->name == NULL) {
-	RADEONxf86SetModeDefaultName(pMode);
+	xf86SetModeDefaultName(pMode);
     } else {
 	pNew->name = xnfstrdup(pMode->name);
     }
@@ -649,7 +219,7 @@ RADEONxf86DuplicateMode(DisplayModePtr p
  * \param modeList doubly-linked mode list
  */
 DisplayModePtr
-RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
 {
     DisplayModePtr first = NULL, last = NULL;
     DisplayModePtr mode;
@@ -657,7 +227,7 @@ RADEONxf86DuplicateModes(ScrnInfoPtr pSc
     for (mode = modeList; mode != NULL; mode = mode->next) {
 	DisplayModePtr new;
 
-	new = RADEONxf86DuplicateMode(mode);
+	new = xf86DuplicateMode(mode);
 
 	/* Insert pNew into modeList */
 	if (last) {
@@ -683,7 +253,7 @@ RADEONxf86DuplicateModes(ScrnInfoPtr pSc
  * This isn't in xf86Modes.c, but it might deserve to be there.
  */
 Bool
-RADEONModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2)
+xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2)
 {
      if (pMode1->Clock == pMode2->Clock &&
 	 pMode1->HDisplay == pMode2->HDisplay &&
@@ -719,7 +289,7 @@ add(char **p, char *new)
  * Convenient VRefresh printing was added, though, compared to xf86Mode.c
  */
 void
-PrintModeline(int scrnIndex,DisplayModePtr mode)
+xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
 {
     char tmp[256];
     char *flags = xnfcalloc(1, 1);
@@ -751,9 +321,10 @@ PrintModeline(int scrnIndex,DisplayModeP
 		   mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
 		   mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
 		   mode->VDisplay, mode->VSyncStart, mode->VSyncEnd,
-		   mode->VTotal, flags, RADEONxf86ModeHSync(mode));
+		   mode->VTotal, flags, xf86ModeHSync(mode));
     xfree(flags);
 }
+#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
 
 /**
  * Marks as bad any modes with unsupported flags.
@@ -827,8 +398,8 @@ RADEONxf86ValidateModesSync(ScrnInfoPtr 
 
 	bad = TRUE;
 	for (i = 0; i < mon->nHsync; i++) {
-	    if (RADEONxf86ModeHSync(mode) >= mon->hsync[i].lo &&
-		RADEONxf86ModeHSync(mode) <= mon->hsync[i].hi)
+	    if (xf86ModeHSync(mode) >= mon->hsync[i].lo &&
+		xf86ModeHSync(mode) <= mon->hsync[i].hi)
 	    {
 		bad = FALSE;
 	    }
@@ -838,8 +409,8 @@ RADEONxf86ValidateModesSync(ScrnInfoPtr 
 
 	bad = TRUE;
 	for (i = 0; i < mon->nVrefresh; i++) {
-	    if (RADEONxf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
-		RADEONxf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
+	    if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
+		xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
 	    {
 		bad = FALSE;
 	    }
@@ -959,3 +530,144 @@ RADEONxf86PruneInvalidModes(ScrnInfoPtr 
     }
 }
 
+/**
+ * Adds the new mode into the mode list, and returns the new list
+ *
+ * \param modes doubly-linked mode list.
+ */
+DisplayModePtr
+xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
+{
+    if (modes == NULL)
+	return new;
+
+    if (new) {
+	DisplayModePtr mode = modes;
+
+	while (mode->next)
+	    mode = mode->next;
+
+	mode->next = new;
+	new->prev = mode;
+    }
+
+    return modes;
+}
+
+/**
+ * Build a mode list from a list of config file modes
+ */
+static DisplayModePtr
+RADEONxf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
+{
+    DisplayModePtr  head = NULL, prev = NULL, mode;
+    
+    for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
+    {
+        mode = xalloc(sizeof(DisplayModeRec));
+	if (!mode)
+	    continue;
+        mode->name       = xstrdup(conf_mode->ml_identifier);
+	if (!mode->name)
+	{
+	    xfree (mode);
+	    continue;
+	}
+	
+        memset(mode,'\0',sizeof(DisplayModeRec));
+	mode->type       = 0;
+        mode->Clock      = conf_mode->ml_clock;
+        mode->HDisplay   = conf_mode->ml_hdisplay;
+        mode->HSyncStart = conf_mode->ml_hsyncstart;
+        mode->HSyncEnd   = conf_mode->ml_hsyncend;
+        mode->HTotal     = conf_mode->ml_htotal;
+        mode->VDisplay   = conf_mode->ml_vdisplay;
+        mode->VSyncStart = conf_mode->ml_vsyncstart;
+        mode->VSyncEnd   = conf_mode->ml_vsyncend;
+        mode->VTotal     = conf_mode->ml_vtotal;
+        mode->Flags      = conf_mode->ml_flags;
+        mode->HSkew      = conf_mode->ml_hskew;
+        mode->VScan      = conf_mode->ml_vscan;
+
+        mode->prev = prev;
+	mode->next = NULL;
+	if (prev)
+	    prev->next = mode;
+	else
+	    head = mode;
+	prev = mode;
+    }
+    return head;
+}
+
+
+/**
+ * Build a mode list from a monitor configuration
+ */
+DisplayModePtr
+RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
+{
+    DisplayModePtr	    modes = NULL;
+    XF86ConfModesLinkPtr    modes_link;
+    
+    if (!conf_monitor)
+	return NULL;
+
+    /*
+     * first we collect the mode lines from the UseModes directive
+     */
+    for (modes_link = conf_monitor->mon_modes_sect_lst; 
+	 modes_link; 
+	 modes_link = modes_link->list.next)
+    {
+	/* If this modes link hasn't been resolved, go look it up now */
+	if (!modes_link->ml_modes)
+	    modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str, 
+						  xf86configptr->conf_modes_lst);
+	if (modes_link->ml_modes)
+	    modes = xf86ModesAdd (modes,
+				  RADEONxf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
+    }
+
+    return xf86ModesAdd (modes,
+			 RADEONxf86GetConfigModes (conf_monitor->mon_modeline_lst));
+}
+
+/**
+ * Build a mode list containing all of the default modes
+ */
+DisplayModePtr
+RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
+{
+    DisplayModePtr  head = NULL, prev = NULL, mode;
+    int		    i;
+
+    for (i = 0; xf86DefaultModes[i].name != NULL; i++)
+    {
+	DisplayModePtr	defMode = &xf86DefaultModes[i];
+	
+	if (!interlaceAllowed && (defMode->Flags & V_INTERLACE))
+	    continue;
+	if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN))
+	    continue;
+
+	mode = xalloc(sizeof(DisplayModeRec));
+	if (!mode)
+	    continue;
+        memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec));
+        mode->name = xstrdup(xf86DefaultModes[i].name);
+        if (!mode->name)
+	{
+	    xfree (mode);
+	    continue;
+	}
+        mode->prev = prev;
+	mode->next = NULL;
+	if (prev)
+	    prev->next = mode;
+	else
+	    head = mode;
+	prev = mode;
+    }
+    return head;
+}
diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h
index ddf3be8..8e23997 100644
--- a/src/radeon_xf86Modes.h
+++ b/src/radeon_xf86Modes.h
@@ -25,26 +25,39 @@
  *
  */
 
-double
-RADEONxf86ModeHSync(DisplayModePtr mode);
-
-double
-RADEONxf86ModeVRefresh(DisplayModePtr mode);
-
-DisplayModePtr
-RADEONxf86DuplicateMode(DisplayModePtr pMode);
-
-DisplayModePtr
-RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList);
-
-void
-RADEONxf86SetModeDefaultName(DisplayModePtr mode);
-
-void
-RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-
-Bool
-RADEONModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
+#ifndef _RADEON_XF86MODES_H_
+#define _RADEON_XF86MODES_H_
+#include "xorgVersion.h"
+#include "xf86Parser.h"
+
+#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
+double RADEON_xf86ModeHSync(DisplayModePtr mode);
+double RADEON_xf86ModeVRefresh(DisplayModePtr mode);
+DisplayModePtr RADEON_xf86DuplicateMode(DisplayModePtr pMode);
+DisplayModePtr RADEON_xf86DuplicateModes(ScrnInfoPtr pScrn,
+				       DisplayModePtr modeList);
+void RADEON_xf86SetModeDefaultName(DisplayModePtr mode);
+void RADEON_xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
+Bool RADEON_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
+void RADEON_xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
+DisplayModePtr RADEON_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
+
+DisplayModePtr RADEON_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
+DisplayModePtr RADEON_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
+				Bool Reduced, Bool Interlaced);
+
+#define xf86ModeHSync RADEON_xf86ModeHSync
+#define xf86ModeVRefresh RADEON_xf86ModeVRefresh
+#define xf86DuplicateMode RADEON_xf86DuplicateMode
+#define xf86DuplicateModes RADEON_xf86DuplicateModes
+#define xf86SetModeDefaultName RADEON_xf86SetModeDefaultName
+#define xf86SetModeCrtc RADEON_xf86SetModeCrtc
+#define xf86ModesEqual RADEON_xf86ModesEqual
+#define xf86PrintModeline RADEON_xf86PrintModeline
+#define xf86ModesAdd RADEON_xf86ModesAdd
+#define xf86DDCGetModes RADEON_xf86DDCGetModes
+#define xf86CVTMode RADEON_xf86CVTMode
+#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
 
 void
 RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
@@ -73,26 +86,10 @@ RADEONxf86ValidateModesFlags(ScrnInfoPtr
 void
 RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
 
-void
-PrintModeline(int scrnIndex,DisplayModePtr mode);
-
-extern DisplayModeRec RADEONxf86DefaultModes[];
-
-void
-RADEONPrintModes(ScrnInfoPtr scrp);
-
 DisplayModePtr
-RADEONGetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins);
-
-void
-RADEONxf86SortModes(DisplayModePtr new, DisplayModePtr *first,
-		    DisplayModePtr *last);
+RADEONxf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
 
 DisplayModePtr
-RADEONGetVESAEstablishedMode(ScrnInfoPtr pScrn, int i);
+RADEONxf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
 
-DisplayModePtr
-RADEONGetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc);
-
-DisplayModePtr
-RADEONGetModeListTail(DisplayModePtr pModeList);
+#endif
diff --git a/src/xf86Optrec.h b/src/xf86Optrec.h
new file mode 100644
index 0000000..183b857
--- /dev/null
+++ b/src/xf86Optrec.h
@@ -0,0 +1,112 @@
+/* 
+ * 
+ * Copyright (c) 1997  Metro Link Incorporated
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * 
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ * 
+ */
+/*
+ * Copyright (c) 1997-2001 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+
+/* 
+ * This file contains the Option Record that is passed between the Parser,
+ * and Module setup procs.
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifndef _xf86Optrec_h_
+#define _xf86Optrec_h_
+#include <stdio.h>
+
+/* 
+ * all records that need to be linked lists should contain a GenericList as
+ * their first field.
+ */
+typedef struct generic_list_rec
+{
+	void *next;
+}
+GenericListRec, *GenericListPtr, *glp;
+
+/*
+ * All options are stored using this data type.
+ */
+typedef struct
+{
+	GenericListRec list;
+	char *opt_name;
+	char *opt_val;
+	int opt_used;
+	char *opt_comment;
+}
+XF86OptionRec, *XF86OptionPtr;
+
+
+XF86OptionPtr xf86addNewOption(XF86OptionPtr head, char *name, char *val);
+XF86OptionPtr xf86optionListDup(XF86OptionPtr opt);
+void xf86optionListFree(XF86OptionPtr opt);
+char *xf86optionName(XF86OptionPtr opt);
+char *xf86optionValue(XF86OptionPtr opt);
+XF86OptionPtr xf86newOption(char *name, char *value);
+XF86OptionPtr xf86nextOption(XF86OptionPtr list);
+XF86OptionPtr xf86findOption(XF86OptionPtr list, const char *name);
+char *xf86findOptionValue(XF86OptionPtr list, const char *name);
+int xf86findOptionBoolean (XF86OptionPtr, const char *, int);
+XF86OptionPtr xf86optionListCreate(const char **options, int count, int used);
+XF86OptionPtr xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail);
+char *xf86configStrdup (const char *s);
+int xf86nameCompare (const char *s1, const char *s2);
+char *xf86uLongToString(unsigned long i);
+void xf86debugListOptions(XF86OptionPtr);
+XF86OptionPtr xf86parseOption(XF86OptionPtr head);
+void xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs);
+
+
+#endif /* _xf86Optrec_h_ */
diff --git a/src/xf86Parser.h b/src/xf86Parser.h
new file mode 100644
index 0000000..a682927
--- /dev/null
+++ b/src/xf86Parser.h
@@ -0,0 +1,483 @@
+/* 
+ * 
+ * Copyright (c) 1997  Metro Link Incorporated
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"), 
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ * 
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ * 
+ */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+
+/* 
+ * This file contains the external interfaces for the XFree86 configuration
+ * file parser.
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifndef _xf86Parser_h_
+#define _xf86Parser_h_
+
+#include "xf86Optrec.h"
+
+#define HAVE_PARSER_DECLS
+
+typedef struct
+{
+	char *file_logfile;
+	char *file_rgbpath;
+	char *file_modulepath;
+	char *file_inputdevs;
+	char *file_fontpath;
+	char *file_comment;
+}
+XF86ConfFilesRec, *XF86ConfFilesPtr;
+
+/* Values for load_type */
+#define XF86_LOAD_MODULE	0
+#define XF86_LOAD_DRIVER	1
+
+typedef struct
+{
+	GenericListRec list;
+	int load_type;
+	char *load_name;
+	XF86OptionPtr load_opt;
+	char *load_comment;
+        int ignore;
+}
+XF86LoadRec, *XF86LoadPtr;
+
+typedef struct
+{
+	XF86LoadPtr mod_load_lst;
+	char *mod_comment;
+}
+XF86ConfModuleRec, *XF86ConfModulePtr;
+
+#define CONF_IMPLICIT_KEYBOARD	"Implicit Core Keyboard"
+
+#define CONF_IMPLICIT_POINTER	"Implicit Core Pointer"
+
+#define XF86CONF_PHSYNC    0x0001
+#define XF86CONF_NHSYNC    0x0002
+#define XF86CONF_PVSYNC    0x0004
+#define XF86CONF_NVSYNC    0x0008
+#define XF86CONF_INTERLACE 0x0010
+#define XF86CONF_DBLSCAN   0x0020
+#define XF86CONF_CSYNC     0x0040
+#define XF86CONF_PCSYNC    0x0080
+#define XF86CONF_NCSYNC    0x0100
+#define XF86CONF_HSKEW     0x0200	/* hskew provided */
+#define XF86CONF_BCAST     0x0400
+#define XF86CONF_CUSTOM    0x0800	/* timing numbers customized by editor */
+#define XF86CONF_VSCAN     0x1000
+
+typedef struct
+{
+	GenericListRec list;
+	char *ml_identifier;
+	int ml_clock;
+	int ml_hdisplay;
+	int ml_hsyncstart;
+	int ml_hsyncend;
+	int ml_htotal;
+	int ml_vdisplay;
+	int ml_vsyncstart;
+	int ml_vsyncend;
+	int ml_vtotal;
+	int ml_vscan;
+	int ml_flags;
+	int ml_hskew;
+	char *ml_comment;
+}
+XF86ConfModeLineRec, *XF86ConfModeLinePtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *vp_identifier;
+	XF86OptionPtr vp_option_lst;
+	char *vp_comment;
+}
+XF86ConfVideoPortRec, *XF86ConfVideoPortPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *va_identifier;
+	char *va_vendor;
+	char *va_board;
+	char *va_busid;
+	char *va_driver;
+	XF86OptionPtr va_option_lst;
+	XF86ConfVideoPortPtr va_port_lst;
+	char *va_fwdref;
+	char *va_comment;
+}
+XF86ConfVideoAdaptorRec, *XF86ConfVideoAdaptorPtr;
+
+#define CONF_MAX_HSYNC 8
+#define CONF_MAX_VREFRESH 8
+
+typedef struct
+{
+	float hi, lo;
+}
+parser_range;
+
+typedef struct
+{
+	int red, green, blue;
+}
+parser_rgb;
+
+typedef struct
+{
+	GenericListRec list;
+	char *modes_identifier;
+	XF86ConfModeLinePtr mon_modeline_lst;
+	char *modes_comment;
+}
+XF86ConfModesRec, *XF86ConfModesPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *ml_modes_str;
+	XF86ConfModesPtr ml_modes;
+}
+XF86ConfModesLinkRec, *XF86ConfModesLinkPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *mon_identifier;
+	char *mon_vendor;
+	char *mon_modelname;
+	int mon_width;				/* in mm */
+	int mon_height;				/* in mm */
+	XF86ConfModeLinePtr mon_modeline_lst;
+	int mon_n_hsync;
+	parser_range mon_hsync[CONF_MAX_HSYNC];
+	int mon_n_vrefresh;
+	parser_range mon_vrefresh[CONF_MAX_VREFRESH];
+	float mon_gamma_red;
+	float mon_gamma_green;
+	float mon_gamma_blue;
+	XF86OptionPtr mon_option_lst;
+	XF86ConfModesLinkPtr mon_modes_sect_lst;
+	char *mon_comment;
+}
+XF86ConfMonitorRec, *XF86ConfMonitorPtr;
+
+#define CONF_MAXDACSPEEDS 4
+#define CONF_MAXCLOCKS    128
+
+typedef struct
+{
+	GenericListRec list;
+	char *dev_identifier;
+	char *dev_vendor;
+	char *dev_board;
+	char *dev_chipset;
+	char *dev_busid;
+	char *dev_card;
+	char *dev_driver;
+	char *dev_ramdac;
+	int dev_dacSpeeds[CONF_MAXDACSPEEDS];
+	int dev_videoram;
+	int dev_textclockfreq;
+	unsigned long dev_bios_base;
+	unsigned long dev_mem_base;
+	unsigned long dev_io_base;
+	char *dev_clockchip;
+	int dev_clocks;
+	int dev_clock[CONF_MAXCLOCKS];
+	int dev_chipid;
+	int dev_chiprev;
+	int dev_irq;
+	int dev_screen;
+	XF86OptionPtr dev_option_lst;
+	char *dev_comment;
+}
+XF86ConfDeviceRec, *XF86ConfDevicePtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *mode_name;
+}
+XF86ModeRec, *XF86ModePtr;
+
+typedef struct
+{
+	GenericListRec list;
+	int disp_frameX0;
+	int disp_frameY0;
+	int disp_virtualX;
+	int disp_virtualY;
+	int disp_depth;
+	int disp_bpp;
+	char *disp_visual;
+	parser_rgb disp_weight;
+	parser_rgb disp_black;
+	parser_rgb disp_white;
+	XF86ModePtr disp_mode_lst;
+	XF86OptionPtr disp_option_lst;
+	char *disp_comment;
+}
+XF86ConfDisplayRec, *XF86ConfDisplayPtr;
+
+typedef struct
+{
+	XF86OptionPtr flg_option_lst;
+	char *flg_comment;
+}
+XF86ConfFlagsRec, *XF86ConfFlagsPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *al_adaptor_str;
+	XF86ConfVideoAdaptorPtr al_adaptor;
+}
+XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *scrn_identifier;
+	char *scrn_obso_driver;
+	int scrn_defaultdepth;
+	int scrn_defaultbpp;
+	int scrn_defaultfbbpp;
+	char *scrn_monitor_str;
+	XF86ConfMonitorPtr scrn_monitor;
+	char *scrn_device_str;
+	XF86ConfDevicePtr scrn_device;
+	XF86ConfAdaptorLinkPtr scrn_adaptor_lst;
+	XF86ConfDisplayPtr scrn_display_lst;
+	XF86OptionPtr scrn_option_lst;
+	char *scrn_comment;
+}
+XF86ConfScreenRec, *XF86ConfScreenPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *inp_identifier;
+	char *inp_driver;
+	XF86OptionPtr inp_option_lst;
+	char *inp_comment;
+}
+XF86ConfInputRec, *XF86ConfInputPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	XF86ConfInputPtr iref_inputdev;
+	char *iref_inputdev_str;
+	XF86OptionPtr iref_option_lst;
+}
+XF86ConfInputrefRec, *XF86ConfInputrefPtr;
+
+/* Values for adj_where */
+#define CONF_ADJ_OBSOLETE	-1
+#define CONF_ADJ_ABSOLUTE	0
+#define CONF_ADJ_RIGHTOF	1
+#define CONF_ADJ_LEFTOF		2
+#define CONF_ADJ_ABOVE		3
+#define CONF_ADJ_BELOW		4
+#define CONF_ADJ_RELATIVE	5
+
+typedef struct
+{
+	GenericListRec list;
+	int adj_scrnum;
+	XF86ConfScreenPtr adj_screen;
+	char *adj_screen_str;
+	XF86ConfScreenPtr adj_top;
+	char *adj_top_str;
+	XF86ConfScreenPtr adj_bottom;
+	char *adj_bottom_str;
+	XF86ConfScreenPtr adj_left;
+	char *adj_left_str;
+	XF86ConfScreenPtr adj_right;
+	char *adj_right_str;
+	int adj_where;
+	int adj_x;
+	int adj_y;
+	char *adj_refscreen;
+}
+XF86ConfAdjacencyRec, *XF86ConfAdjacencyPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *inactive_device_str;
+	XF86ConfDevicePtr inactive_device;
+}
+XF86ConfInactiveRec, *XF86ConfInactivePtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *lay_identifier;
+	XF86ConfAdjacencyPtr lay_adjacency_lst;
+	XF86ConfInactivePtr lay_inactive_lst;
+	XF86ConfInputrefPtr lay_input_lst;
+	XF86OptionPtr lay_option_lst;
+	char *lay_comment;
+}
+XF86ConfLayoutRec, *XF86ConfLayoutPtr;
+
+typedef struct 
+{ 
+	GenericListRec list; 
+	char *vs_name;
+	char *vs_identifier;
+	XF86OptionPtr vs_option_lst;
+	char *vs_comment;
+}
+XF86ConfVendSubRec, *XF86ConfVendSubPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	char *vnd_identifier;
+	XF86OptionPtr vnd_option_lst;
+	XF86ConfVendSubPtr vnd_sub_lst;
+	char *vnd_comment;
+}
+XF86ConfVendorRec, *XF86ConfVendorPtr;
+
+typedef struct
+{
+	GenericListRec list;
+	int buf_count;
+	int buf_size;
+	char *buf_flags;
+	char *buf_comment;
+}
+XF86ConfBuffersRec, *XF86ConfBuffersPtr;
+
+typedef struct
+{
+	char *dri_group_name;
+	int dri_group;
+	int dri_mode;
+	XF86ConfBuffersPtr dri_buffers_lst;
+	char *dri_comment;
+}
+XF86ConfDRIRec, *XF86ConfDRIPtr;
+
+typedef struct
+{
+	XF86OptionPtr ext_option_lst;
+	char *extensions_comment;
+}
+XF86ConfExtensionsRec, *XF86ConfExtensionsPtr;
+
+typedef struct
+{
+	XF86ConfFilesPtr conf_files;
+	XF86ConfModulePtr conf_modules;
+	XF86ConfFlagsPtr conf_flags;
+	XF86ConfVideoAdaptorPtr conf_videoadaptor_lst;
+	XF86ConfModesPtr conf_modes_lst;
+	XF86ConfMonitorPtr conf_monitor_lst;
+	XF86ConfDevicePtr conf_device_lst;
+	XF86ConfScreenPtr conf_screen_lst;
+	XF86ConfInputPtr conf_input_lst;
+	XF86ConfLayoutPtr conf_layout_lst;
+	XF86ConfVendorPtr conf_vendor_lst;
+	XF86ConfDRIPtr conf_dri;
+	XF86ConfExtensionsPtr conf_extensions;
+	char *conf_comment;
+}
+XF86ConfigRec, *XF86ConfigPtr;
+
+typedef struct
+{
+	int token;			/* id of the token */
+	char *name;			/* pointer to the LOWERCASED name */
+}
+xf86ConfigSymTabRec, *xf86ConfigSymTabPtr;
+
+/*
+ * prototypes for public functions
+ */
+extern const char *xf86openConfigFile (const char *, const char *,
+					const char *);
+extern void xf86setBuiltinConfig(const char *config[]);
+extern XF86ConfigPtr xf86readConfigFile (void);
+extern void xf86closeConfigFile (void);
+extern void xf86freeConfig (XF86ConfigPtr p);
+extern int xf86writeConfigFile (const char *, XF86ConfigPtr);
+XF86ConfDevicePtr xf86findDevice(const char *ident, XF86ConfDevicePtr p);
+XF86ConfLayoutPtr xf86findLayout(const char *name, XF86ConfLayoutPtr list);
+XF86ConfMonitorPtr xf86findMonitor(const char *ident, XF86ConfMonitorPtr p);
+XF86ConfModesPtr xf86findModes(const char *ident, XF86ConfModesPtr p);
+XF86ConfModeLinePtr xf86findModeLine(const char *ident, XF86ConfModeLinePtr p);
+XF86ConfScreenPtr xf86findScreen(const char *ident, XF86ConfScreenPtr p);
+XF86ConfInputPtr xf86findInput(const char *ident, XF86ConfInputPtr p);
+XF86ConfInputPtr xf86findInputByDriver(const char *driver, XF86ConfInputPtr p);
+XF86ConfVendorPtr xf86findVendor(const char *name, XF86ConfVendorPtr list);
+XF86ConfVideoAdaptorPtr xf86findVideoAdaptor(const char *ident,
+						XF86ConfVideoAdaptorPtr p);
+
+GenericListPtr xf86addListItem(GenericListPtr head, GenericListPtr c_new);
+int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2);
+
+int xf86pathIsAbsolute(const char *path);
+int xf86pathIsSafe(const char *path);
+char *xf86addComment(char *cur, char *add);
+
+#endif /* _xf86Parser_h_ */
diff-tree 87592ffb717da1f0a1767a38918d16d60953599c (from 41cd50487bc85708a3f791dfa70bf85223d91a65)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 20:10:58 2006 +1100

    add setdpi call

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 942d2ad..615525c 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3240,6 +3240,9 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
    pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
 
+   /* Set display resolution */
+   xf86SetDpi(pScrn, 0, 0);
+
 	/* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
 
diff-tree 41cd50487bc85708a3f791dfa70bf85223d91a65 (from 555e0f988c571aa47bc62ec6d9612a71f1a1f59b)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 20:08:07 2006 +1100

    add displayWidth set

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b8810b4..942d2ad 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3238,6 +3238,8 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
       goto fail;
    }
 
+   pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
+
 	/* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
 
diff-tree 555e0f988c571aa47bc62ec6d9612a71f1a1f59b (from 3e2c72d7ac80ed874bcf2887a5253dac1c9bb02c)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 19:59:19 2006 +1100

    add randr pre init

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index f06edcc..b8810b4 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -3258,6 +3258,20 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     if (!RADEONPreInitXv(pScrn))                 goto fail;
 
+
+    if (!xf86RandR12PreInit (pScrn))
+    {
+      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
+      PreInitCleanup(pScrn);
+      return FALSE;
+    }	
+    
+    if (pScrn->modes == NULL) {
+      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
+      PreInitCleanup(pScrn);
+      return FALSE;
+   }
+
     /* Free the video bios (if applicable) */
     if (info->VBIOS) {
 	xfree(info->VBIOS);
diff-tree 3e2c72d7ac80ed874bcf2887a5253dac1c9bb02c (from 4356b031886e00b3ed5ac1dbceeadebd7fc29fc2)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 19:49:08 2006 +1100

    fixup even more remnants of old code

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 15b358f..1953809 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -611,7 +611,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
     /* okay we got DDC info */
     if (output->MonInfo) {
       /* Debug info for now, at least */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", output->num);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", pRPort->num);
       xf86PrintEDID(output->MonInfo);
       
       ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
@@ -786,8 +786,7 @@ RADEON_set_default_screen_size(ScrnInfoP
 
 int RADEONValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
 {
-  RADEONProbeOutputModes(pScrn);
-
+  
   if (first_time)
     {
       RADEON_set_default_screen_size(pScrn);
diff-tree 4356b031886e00b3ed5ac1dbceeadebd7fc29fc2 (from 17d39502a8dbea395051007aebffdf23644e9ee1)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 19:47:45 2006 +1100

    fix remnant of old code

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 50f0974..15b358f 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -600,7 +600,6 @@ RADEONProbeOutputModes(xf86OutputPtr out
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     RADEONOutputPrivatePtr pRPort = output->driver_private;
-    int i;
     DisplayModePtr ddc_modes, mode;
     DisplayModePtr test;
 
@@ -612,7 +611,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
     /* okay we got DDC info */
     if (output->MonInfo) {
       /* Debug info for now, at least */
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", output->num);
       xf86PrintEDID(output->MonInfo);
       
       ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
@@ -652,7 +651,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
 	RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
 	RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
 	/* fill out CRT of FP mode table */
-	pRADEONEnt->pOutput[i]->probed_modes = modes;
+	output->probed_modes = modes;
 	break;
 	
       case MT_LCD:
diff-tree 17d39502a8dbea395051007aebffdf23644e9ee1 (from bf0b364cbd8682f297e2d110ece1f72e7151340d)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 19:44:39 2006 +1100

    use getddcmodes properly

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 0b3a63a..50f0974 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -110,7 +110,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 	int  maxVirtY = pScrn->virtualY;
 
 	/* Collect all of the DDC modes */
-	first = last = ddcModes = xf86DDCGetModes(pScrn, pScrn->monitor->DDC);
+	first = last = ddcModes = xf86DDCGetModes(pScrn->scrnIndex, pScrn->monitor->DDC);
 
 	for (p = ddcModes; p; p = p->next) {
 
@@ -615,7 +615,7 @@ RADEONProbeOutputModes(xf86OutputPtr out
       xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
       xf86PrintEDID(output->MonInfo);
       
-      ddc_modes = RADEONGetDDCModes(pScrn, output->MonInfo);
+      ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
       
       for (mode = ddc_modes; mode != NULL; mode = mode->next) {
 	if (mode->Flags & V_DBLSCAN) {
diff-tree bf0b364cbd8682f297e2d110ece1f72e7151340d (from 4962a5430844114de864418d803f3182b90792ff)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 17:31:08 2006 +1100

    fix up output namings

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 7f17e45..dcf65f2 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -113,6 +113,15 @@ const char *ConnectorTypeNameATOM[10] = 
   "Unsupported"
 };
 
+const char *OutputType[10] = {
+    "None",
+    "VGA",
+    "DVI",
+    "LVDS",
+    "S-video",
+    "Composite",
+};
+
 
 static const RADEONTMDSPll default_tmds_pll[CHIP_FAMILY_LAST][4] =
 {
@@ -2529,33 +2538,84 @@ Bool RADEONAllocateControllers(ScrnInfoP
     return TRUE;
 }
 
-Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
+Bool RADEONAllocatePortInfo(ScrnInfoPtr pScrn)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     int num_connectors;
     int i;
 
     if (pRADEONEnt->PortInfo[0])
-        return TRUE;
-    
+	return TRUE;
+
     /* for now always allocate max connectors */
     for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
 
-      pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA");
-      if (!pRADEONEnt->pOutput[i])
-	return FALSE;
+	pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
+	if (!pRADEONEnt->PortInfo[i])
+	    return FALSE;
+    }
+}
 
-      pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
-      if (!pRADEONEnt->PortInfo[i])
-	return FALSE;
+void RADEONSetOutputType(ScrnInfoPtr pScrn, RADEONOutputPrivatePtr pRPort)
+{
+    RADEONInfoPtr info = RADEONPTR (pScrn);
+    RADEONOutputType output;
+    if (info->IsAtomBios) {
+	switch(pRPort->ConnectorType) {
+	case 0: output = OUTPUT_NONE; break;
+	case 1: output = OUTPUT_VGA; break;
+	case 2:
+	case 3:
+	case 4: output = OUTPUT_DVI; break;
+	case 5: output = OUTPUT_STV; break;
+	case 6: output = OUTPUT_CTV; break;
+	case 7:
+	case 8: output = OUTPUT_LVDS; break;
+	case 9:
+	default:
+	    output = OUTPUT_NONE; break;
+	}
+    }
+    else {
+	switch(pRPort->ConnectorType) {
+	case 0: output = OUTPUT_NONE; break;
+	case 1: output = OUTPUT_LVDS; break;
+	case 2: output = OUTPUT_VGA; break;
+	case 3:
+	case 4: output = OUTPUT_DVI; break;
+	case 5: output = OUTPUT_STV; break;
+	case 6: output = OUTPUT_CTV; break;
+	default: output = OUTPUT_NONE; break;
+	}
+    }
+    pRPort->type = output;
+}
 
-      pRADEONEnt->PortInfo[i]->type = OUTPUT_VGA;
-      pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
-      pRADEONEnt->PortInfo[i]->num = i;
+Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn)
+{
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    int num_connectors;
+    int i;
 
-      pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0) | (1<<1);
-    }
+    if (pRADEONEnt->pOutput[0])
+        return TRUE;
+    
+    /* for now always allocate max connectors */
+    for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
+
+	RADEONSetOutputType(pScrn, pRADEONEnt->PortInfo[i]);
 
+	pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, OutputType[pRADEONEnt->PortInfo[i]->type]);
+	if (!pRADEONEnt->pOutput[i])
+	    return FALSE;
+	
+	
+	pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
+	pRADEONEnt->PortInfo[i]->num = i;
+	
+	pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0) | (1<<1);
+    }
+    
 
     return TRUE;
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0aa594d..f06edcc 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2840,16 +2840,21 @@ static Bool RADEONPreInitControllers(Scr
     xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
     int i;
     if (!info->IsSecondary) {
-      if (!RADEONAllocateConnectors(pScrn))
+      
+      if (!RADEONAllocatePortInfo(pScrn))
 	return FALSE;
 
       if (!RADEONAllocateControllers(pScrn))
 	return FALSE;
-      
     }
 
     RADEONGetBIOSInfo(pScrn, pInt10);
 
+    if (!info->IsSecondary) {
+      if (!RADEONAllocateConnectors(pScrn))
+	return FALSE;
+    }
+
     RADEONSetupConnectors(pScrn);
     RADEONMapControllers(pScrn);
 
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 959d4dd..977790c 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -112,7 +112,7 @@ typedef enum
     OUTPUT_DVI,
     OUTPUT_LVDS,
     OUTPUT_STV,
-    OUTPUT_CTX,
+    OUTPUT_CTV,
 } RADEONOutputType;
 
 typedef struct _RADEONCrtcPrivateRec {
diff-tree 4962a5430844114de864418d803f3182b90792ff (from b47013f41249516ae82e22bd75caf573da2cc13c)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 17 16:58:07 2006 +1100

    remove some code that moved into server

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index e8e1476..0b3a63a 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -110,7 +110,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 	int  maxVirtY = pScrn->virtualY;
 
 	/* Collect all of the DDC modes */
-	first = last = ddcModes = RADEONGetDDCModes(pScrn, pScrn->monitor->DDC);
+	first = last = ddcModes = xf86DDCGetModes(pScrn, pScrn->monitor->DDC);
 
 	for (p = ddcModes; p; p = p->next) {
 
diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c
index 730169d..e75ac79 100644
--- a/src/radeon_xf86Modes.c
+++ b/src/radeon_xf86Modes.c
@@ -41,32 +41,6 @@
 #include "radeon_xf86Modes.h"
 
 
-/* Established timings from EDID standard */
-static struct
-{
-    int hsize;
-    int vsize;
-    int refresh;
-} est_timings[] = {
-    {1280, 1024, 75},
-    {1024, 768, 75},
-    {1024, 768, 70},
-    {1024, 768, 60},
-    {1024, 768, 87},
-    {832, 624, 75},
-    {800, 600, 75},
-    {800, 600, 72},
-    {800, 600, 60},
-    {800, 600, 56},
-    {640, 480, 75},
-    {640, 480, 72},
-    {640, 480, 67},
-    {640, 480, 60},
-    {720, 400, 88},
-    {720, 400, 70},
-};
-
-
 #include <math.h>
 
 #define rint(x) floor(x)
@@ -480,173 +454,6 @@ RADEONxf86SortModes(DisplayModePtr new, 
     }
 }
 
-/**
- * Gets a new pointer to a VESA established mode.
- *
- * \param i index into the VESA established modes table.
- */
-DisplayModePtr
-RADEONGetVESAEstablishedMode(ScrnInfoPtr pScrn, int i)
-{
-    DisplayModePtr pMode;
-
-    for (pMode = RADEONxf86DefaultModes; pMode->name != NULL; pMode++)
-    {
-	if (pMode->HDisplay == est_timings[i].hsize &&
-	    pMode->VDisplay == est_timings[i].vsize &&
-	    fabs(RADEONxf86ModeVRefresh(pMode) - est_timings[i].refresh) < 1.0)
-	{
-	    DisplayModePtr pNew = RADEONxf86DuplicateMode(pMode);
-	    RADEONxf86SetModeDefaultName(pNew);
-	    pNew->VRefresh = RADEONxf86ModeVRefresh(pMode);
-	    return pNew;
-	}
-    }
-    return NULL;
-}
-
-DisplayModePtr
-RADEONGetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
-{
-    DisplayModePtr  last  = NULL;
-    DisplayModePtr  new   = NULL;
-    DisplayModePtr  first = NULL;
-    int             count = 0;
-    int             j, tmp;
-
-    if (ddc == NULL)
-	return NULL;
-
-    /* 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;
-
-	    if (d_timings->h_active == 0 || d_timings->v_active == 0) break;
-
-	    new = xnfcalloc(1, sizeof (DisplayModeRec));
-	    memset(new, 0, sizeof (DisplayModeRec));
-
-	    new->HDisplay   = d_timings->h_active;
-	    new->VDisplay   = d_timings->v_active;
-
-	    new->HTotal     = new->HDisplay + d_timings->h_blanking;
-	    new->HSyncStart = new->HDisplay + d_timings->h_sync_off;
-	    new->HSyncEnd   = new->HSyncStart + d_timings->h_sync_width;
-	    new->VTotal     = new->VDisplay + d_timings->v_blanking;
-	    new->VSyncStart = new->VDisplay + d_timings->v_sync_off;
-	    new->VSyncEnd   = new->VSyncStart + d_timings->v_sync_width;
-	    new->Clock      = d_timings->clock / 1000;
-	    new->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-	    new->status     = MODE_OK;
-#ifdef M_T_PREFERRED
-	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
-		new->type   = M_T_PREFERRED;
-	    else
-		new->type   = M_T_DRIVER;
-#else
-	    new->type = M_T_USERDEF;
-#endif
-
-	    RADEONxf86SetModeDefaultName(new);
-
-	    if (d_timings->sync == 3) {
-		switch (d_timings->misc) {
-		case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
-		case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
-		case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
-		case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
-		}
-	    }
-	    count++;
-
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Valid Mode from Detailed timing table: %s (ht %d hss %d hse %d vt %d vss %d vse %d)\n",
-		       new->name,
-		       new->HTotal, new->HSyncStart, new->HSyncEnd,
-		       new->VTotal, new->VSyncStart, new->VSyncEnd);
-
-	    RADEONxf86SortModes(new, &first, &last);
-	}
-    }
-
-    /* Search thru standard VESA modes from EDID */
-    for (j = 0; j < 8; j++) {
-        if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
-               continue;
-#if 1
-	new = RADEONGetGTF(ddc->timings2[j].hsize, ddc->timings2[j].vsize,
-			 ddc->timings2[j].refresh, FALSE, FALSE);
-	new->status = MODE_OK;
-	new->type |= M_T_DEFAULT;
-
-	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		   "Valid Mode from standard timing table: %s\n",
-		   new->name);
-
-	RADEONxf86SortModes(new, &first, &last);
-#else
-	for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
-
-	    /* Ignore all double scan modes */
-	    if ((ddc->timings2[j].hsize == p->HDisplay) &&
-		(ddc->timings2[j].vsize == p->VDisplay)) {
-		float  refresh =
-		    (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-		float err = (float)ddc->timings2[j].refresh - refresh;
-
-		if (err < 0) err = -err;
-		if (err < 1.0) {
-		    /* Is this good enough? */
-		    new = xnfcalloc(1, sizeof (DisplayModeRec));
-		    memcpy(new, p, sizeof(DisplayModeRec));
-		    new->name = xnfalloc(strlen(p->name) + 1);
-		    strcpy(new->name, p->name);
-		    new->status = MODE_OK;
-		    new->type   = M_T_DEFAULT;
-
-		    count++;
-
-		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			       "Valid Mode from standard timing table: %s\n",
-			       new->name);
-
-		    RADEONxf86SortModes(new, &first, &last);
-		    break;
-		}
-	    }
-	}
-#endif
-    }
-
-    /* Search thru established modes from EDID */
-    tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
-    for (j = 0; j < 16; j++) {
-	if (tmp & (1 << j)) {
-	    new = RADEONGetVESAEstablishedMode(pScrn, j);
-	    if (new == NULL) {
-		ErrorF("Couldn't get established mode %d\n", j);
-		continue;
-	    }
-	    new->status = MODE_OK;
-	    new->type = M_T_DEFAULT;
-
-	    count++;
-
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid Mode from established "
-		       "timing table: %s\n", new->name);
-
-	    RADEONxf86SortModes(new, &first, &last);
-	}
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Total of %d DDC mode(s) found.\n", count);
-
-    return first;
-}
-
 DisplayModePtr
 RADEONGetModeListTail(DisplayModePtr pModeList)
 {
@@ -1152,111 +959,3 @@ RADEONxf86PruneInvalidModes(ScrnInfoPtr 
     }
 }
 
-#define MODEPREFIX(name) NULL, NULL, name, MODE_OK, M_T_DEFAULT
-#define MODESUFFIX       0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-/**
- * List of VESA established modes, taken from xf86DefaultModes but trimmed down.
- * (not trimming should be harmless).
- */
-DisplayModeRec RADEONxf86DefaultModes[] = {
-/* 640x350 @ 85Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("640x350"),31500, 640,672,736,832,0, 350,382,385,445,0, V_PHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x175"),15750, 320,336,368,416,0, 175,191,192,222,0, V_PHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x400 @ 85Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("640x400"),31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x200"),15750, 320,336,368,416,0, 200,200,202,222,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 720x400 @ 85Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("720x400"),35500, 720,756,828,936,0, 400,401,404,446,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("360x200"),17750, 360,378,414,468,0, 200,200,202,223,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("640x480"),31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x240"),15750, 320,332,352,416,0, 240,244,245,260,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */
-	{MODEPREFIX("640x480"),31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x240"),15750, 320,328,360,420,0, 240,240,242,250,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */
-	{MODEPREFIX("640x480"),36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("320x240"),18000, 320,348,376,416,0, 240,240,242,254,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */
-	{MODEPREFIX("800x600"),36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),18000, 400,412,448,512,0, 300,300,301,312,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */
-	{MODEPREFIX("800x600"),40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),20000, 400,420,484,528,0, 300,300,302,314,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */
-	{MODEPREFIX("800x600"),50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),25000, 400,428,488,520,0, 300,318,321,333,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */
-	{MODEPREFIX("800x600"),49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),24750, 400,408,448,528,0, 300,300,302,312,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */
-	{MODEPREFIX("800x600"),56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("400x300"),28150, 400,416,448,524,0, 300,300,302,315,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */
-	{MODEPREFIX("1024x768"),65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),32500, 512,524,592,672,0, 384,385,388,403,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */
-	{MODEPREFIX("1024x768"),75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),37500, 512,524,592,664,0, 384,385,388,403,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */
-	{MODEPREFIX("1024x768"),78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),39400, 512,520,568,656,0, 384,384,386,400,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */
-	{MODEPREFIX("1024x768"),94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("512x384"),47250, 512,536,584,688,0, 384,384,386,404,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */
-	{MODEPREFIX("1152x864"),108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("576x432"),54000, 576,608,672,800,0, 432,432,434,450,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x960 @ 60Hz (VESA) hsync: 60.0kHz */
-	{MODEPREFIX("1280x960"),108000, 1280,1376,1488,1800,0, 960,961,964,1000,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x480"),54000, 640,688,744,900,0, 480,480,482,500,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x960 @ 85Hz (VESA) hsync: 85.9kHz */
-	{MODEPREFIX("1280x960"),148500, 1280,1344,1504,1728,0, 960,961,964,1011,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x480"),74250, 640,672,752,864,0, 480,480,482,505,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz */
-	{MODEPREFIX("1280x1024"),108000, 1280,1328,1440,1688,0, 1024,1025,1028,1066,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x512"),54000, 640,664,720,844,0, 512,512,514,533,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz */
-	{MODEPREFIX("1280x1024"),135000, 1280,1296,1440,1688,0, 1024,1025,1028,1066,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x512"),67500, 640,648,720,844,0, 512,512,514,533,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz */
-	{MODEPREFIX("1280x1024"),157500, 1280,1344,1504,1728,0, 1024,1025,1028,1072,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("640x512"),78750, 640,672,752,864,0, 512,512,514,536,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz */
-	{MODEPREFIX("1600x1200"),162000, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),81000, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz */
-	{MODEPREFIX("1600x1200"),175500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),87750, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz */
-	{MODEPREFIX("1600x1200"),189000, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),94500, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz */
-	{MODEPREFIX("1600x1200"),202500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),101250, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz */
-	{MODEPREFIX("1600x1200"),229500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("800x600"),114750, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz */
-	{MODEPREFIX("1792x1344"),204800, 1792,1920,2120,2448,0, 1344,1345,1348,1394,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("896x672"),102400, 896,960,1060,1224,0, 672,672,674,697,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz */
-	{MODEPREFIX("1792x1344"),261000, 1792,1888,2104,2456,0, 1344,1345,1348,1417,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("896x672"),130500, 896,944,1052,1228,0, 672,672,674,708,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz */
-	{MODEPREFIX("1856x1392"),218300, 1856,1952,2176,2528,0, 1392,1393,1396,1439,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("928x696"),109150, 928,976,1088,1264,0, 696,696,698,719,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz */
-	{MODEPREFIX("1856x1392"),288000, 1856,1984,2208,2560,0, 1392,1393,1396,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("928x696"),144000, 928,992,1104,1280,0, 696,696,698,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz */
-	{MODEPREFIX("1920x1440"),234000, 1920,2048,2256,2600,0, 1440,1441,1444,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("960x720"),117000, 960,1024,1128,1300,0, 720,720,722,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-/* 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz */
-	{MODEPREFIX("1920x1440"),297000, 1920,2064,2288,2640,0, 1440,1441,1444,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
-	{MODEPREFIX("960x720"),148500, 960,1032,1144,1320,0, 720,720,722,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
-
-	/* Terminator */
-	{MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX}
-};
diff-tree b47013f41249516ae82e22bd75caf573da2cc13c (from 62a5e7565b66d7b7d65609c034f34b55bd266617)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sat Dec 16 12:02:37 2006 +1100

    hook up mode detect to new randr code

diff --git a/src/radeon_display.c b/src/radeon_display.c
index 260f5a1..7f17e45 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -1149,14 +1149,15 @@ void RADEONSetupConnectors(ScrnInfoPtr p
     }
 }
 
-static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, int connector)
+static RADEONMonitorType RADEONPortCheckNonDDC(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
+    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
 
     if (info->IsMobility) {
-      switch(connector) {
+      switch(pRPort->num) {
       case 0:
 	/* non-DDC laptop panel connected on primary */
 	if (INREG(RADEON_BIOS_4_SCRATCH) & 4)
@@ -1177,18 +1178,17 @@ static RADEONMonitorType RADEONPortCheck
 /* 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, int connector)
+void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    xf86OutputPtr pPort = pRADEONEnt->pOutput[connector];
     RADEONOutputPrivatePtr pRPort = pPort->driver_private;
     
     if (pRPort->MonType == MT_UNKNOWN) {
       if ((pRPort->MonType = RADEONDisplayDDCConnected(pScrn,
 						     pRPort->DDCType,
 						     pPort)));
-      else if((pRPort->MonType = RADEONPortCheckNonDDC(pScrn, connector)));
+      else if((pRPort->MonType = RADEONPortCheckNonDDC(pScrn, pPort)));
       else
 	pRPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRPort->DACType));
     }
@@ -1267,8 +1267,8 @@ static void RADEONQueryConnectedDisplays
 	    return;
 	}
 	
-	RADEONConnectorFindMonitor(pScrn, 0);
-	RADEONConnectorFindMonitor(pScrn, 1);
+	RADEONConnectorFindMonitor(pScrn, pRADEONEnt->pOutput[0]);
+	RADEONConnectorFindMonitor(pScrn, pRADEONEnt->pOutput[1]);
 	
     }
 
@@ -2470,7 +2470,8 @@ radeon_detect(xf86OutputPtr output)
 static DisplayModePtr
 radeon_get_modes(xf86OutputPtr output)
 {
-    
+    RADEONProbeOutputModes(output);
+    return output->probed_modes;
 }
 
 static void
@@ -2550,8 +2551,12 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
 
       pRADEONEnt->PortInfo[i]->type = OUTPUT_VGA;
       pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
+      pRADEONEnt->PortInfo[i]->num = i;
+
+      pRADEONEnt->pOutput[i]->possible_crtcs = (1<<0) | (1<<1);
     }
 
+
     return TRUE;
 }
 
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 639d39a..e8e1476 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -593,104 +593,81 @@ int RADEONValidateMergeModes(ScrnInfoPtr
 }
 
 void
-RADEONProbeOutputModes(ScrnInfoPtr pScrn)
+RADEONProbeOutputModes(xf86OutputPtr output)
 {
+    ScrnInfoPtr	    pScrn = output->scrn;
     xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr pRPort = output->driver_private;
     int i;
     DisplayModePtr ddc_modes, mode;
     DisplayModePtr test;
 
-    for (i = 0; i < config->num_output; i++) {
-        xf86OutputPtr output = config->output[i];
+    /* force reprobe */
+    pRPort->MonType = MT_UNKNOWN;
 	
-	test = output->probed_modes;
-	while(test != NULL) {
-	  xf86DeleteMode(&test, test);
-	}
-
-	output->probed_modes = test;
-
-	/* force reprobe */
-	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
+    RADEONConnectorFindMonitor(pScrn, output);
+    
+    /* okay we got DDC info */
+    if (output->MonInfo) {
+      /* Debug info for now, at least */
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
+      xf86PrintEDID(output->MonInfo);
+      
+      ddc_modes = RADEONGetDDCModes(pScrn, output->MonInfo);
+      
+      for (mode = ddc_modes; mode != NULL; mode = mode->next) {
+	if (mode->Flags & V_DBLSCAN) {
+	  if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+	    mode->status = MODE_CLOCK_RANGE;
+	}
+      }
+      RADEONxf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
+      
+      /* do some physcial size stuff */
+    }
+    
+    
+    if (output->probed_modes == NULL) {
+      MonRec fixed_mon;
+      DisplayModePtr modes;
+      
+      switch(pRPort->MonType) {
+      case MT_CRT:
+      case MT_DFP:
 	
-	RADEONConnectorFindMonitor(pScrn, i);
+	/* We've got a potentially-connected monitor that we can't DDC.  Return a
+	 * fixed set of VESA plus user modes for a presumed multisync monitor with
+	 * some reasonable limits.
+	 */
+	fixed_mon.nHsync = 1;
+	fixed_mon.hsync[0].lo = 31.0;
+	fixed_mon.hsync[0].hi = 100.0;
+	fixed_mon.nVrefresh = 1;
+	fixed_mon.vrefresh[0].lo = 50.0;
+	fixed_mon.vrefresh[0].hi = 70.0;
 	
-	/* okay we got DDC info */
-	if (output->MonInfo) {
-	    /* Debug info for now, at least */
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
-	    xf86PrintEDID(pRADEONEnt->pOutput[i]->MonInfo);
-
-	    ddc_modes = RADEONGetDDCModes(pScrn, pRADEONEnt->pOutput[i]->MonInfo);
-	    
-	    for (mode = ddc_modes; mode != NULL; mode = mode->next) {
-		if (mode->Flags & V_DBLSCAN) {
-		    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
-			mode->status = MODE_CLOCK_RANGE;
-		}
-	    }
-	    RADEONxf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
-
-	    /* do some physcial size stuff */
-	}
-	   
-
-	if (output->probed_modes == NULL) {
-  	    MonRec fixed_mon;
-	    DisplayModePtr modes;
-
-	    switch(pRADEONEnt->PortInfo[i]->MonType) {
-	    case MT_CRT:
-	    case MT_DFP:
-	      
-	            /* We've got a potentially-connected monitor that we can't DDC.  Return a
-		     * fixed set of VESA plus user modes for a presumed multisync monitor with
-		     * some reasonable limits.
-		     */
-	      fixed_mon.nHsync = 1;
-	      fixed_mon.hsync[0].lo = 31.0;
-	      fixed_mon.hsync[0].hi = 100.0;
-	      fixed_mon.nVrefresh = 1;
-	      fixed_mon.vrefresh[0].lo = 50.0;
-	      fixed_mon.vrefresh[0].hi = 70.0;
-	      
-	      modes = RADEONxf86DuplicateModes(pScrn, pScrn->monitor->Modes);
-	      RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
-	      RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
-	      /* fill out CRT of FP mode table */
-	      pRADEONEnt->pOutput[i]->probed_modes = modes;
-	      break;
-		
-	    case MT_LCD:
-	      RADEONValidateFPModes(pScrn, pScrn->display->modes, &pRADEONEnt->pOutput[i]->probed_modes);
-	      break;
-	    default:
-		break;
-	    }
-	}
-
-	if (output->probed_modes) {
-	  RADEONxf86ValidateModesUserConfig(pScrn,
-					    output->probed_modes);
-	  RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes,
-				      FALSE);
-	}
-
-
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
-	{
-	    /* The code to choose the best mode per pipe later on will require
-	     * VRefresh to be set.
-	     */
-	    mode->VRefresh = RADEONxf86ModeVRefresh(mode);
-	    RADEONxf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
-#ifdef DEBUG_REPROBE
-	    PrintModeline(pScrn->scrnIndex, mode);
-#endif
-	}
+	modes = RADEONxf86DuplicateModes(pScrn, pScrn->monitor->Modes);
+	RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
+	RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
+	/* fill out CRT of FP mode table */
+	pRADEONEnt->pOutput[i]->probed_modes = modes;
+	break;
+	
+      case MT_LCD:
+	RADEONValidateFPModes(pScrn, pScrn->display->modes, &output->probed_modes);
+	break;
+      default:
+	break;
+      }
+    }
+    
+    if (output->probed_modes) {
+      RADEONxf86ValidateModesUserConfig(pScrn,
+					output->probed_modes);
+      RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes,
+				  FALSE);
     }
 }
   
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index a717504..959d4dd 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -124,6 +124,7 @@ typedef struct _RADEONCrtcPrivateRec {
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct _RADEONOutputPrivateRec {
+    int num;
     RADEONOutputType type;
     void *dev_priv;
     RADEONDDCType DDCType;
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index baa9207..ce28e7b 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -66,12 +66,31 @@ static Bool xf86RandR12CreateScreenResou
 #endif
 
  
-static int	    RADEONRandRIndex;
-static int	    RADEONRandRGeneration;
+static int	    xf86RandR12Index;
+static int	    xf86RandR12Generation;
 
-#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[RADEONRandRIndex].ptr)
+#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[xf86RandR12Index].ptr)
 
 #if RANDR_12_INTERFACE
+
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
+{
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+    if (xf86RandR12Generation != serverGeneration ||
+	XF86RANDRINFO(pScreen)->virtualX == -1)
+    {
+	*x = pScrn->virtualX;
+	*y = pScrn->virtualY;
+    } else {
+	XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+	*x = randrp->virtualX;
+	*y = randrp->virtualY;
+    }
+}
+
 static int
 xf86RandR12ModeRefresh (DisplayModePtr mode)
 {
@@ -811,10 +830,10 @@ RADEONRandRInit (ScreenPtr    pScreen, i
     if (!noPanoramiXExtension)
 	return TRUE;
 #endif
-    if (RADEONRandRGeneration != serverGeneration)
+    if (xf86RandR12Generation != serverGeneration)
     {
-	RADEONRandRIndex = AllocateScreenPrivateIndex();
-	RADEONRandRGeneration = serverGeneration;
+	xf86RandR12Index = AllocateScreenPrivateIndex();
+	xf86RandR12Generation = serverGeneration;
     }
     
     randrp = xalloc (sizeof (XF86RandRInfoRec));
@@ -841,7 +860,7 @@ RADEONRandRInit (ScreenPtr    pScreen, i
 
     randrp->maxX = randrp->maxY = 0;
 
-    pScreen->devPrivates[RADEONRandRIndex].ptr = randrp;
+    pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
 
 #if RANDR_12_INTERFACE
     if (!RADEONRandRInit12 (pScreen))
diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
index 22f7ae4..76b03f5 100644
--- a/src/radeon_xf86Crtc.c
+++ b/src/radeon_xf86Crtc.c
@@ -548,12 +548,12 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
     /* Disable modes in the XFree86 DDX list that are larger than the current
      * virtual size.
      */
-    i830xf86ValidateModesSize(pScrn, pScrn->modes,
+    RADEONxf86ValidateModesSize(pScrn, pScrn->modes,
 			      originalVirtualX, originalVirtualY,
 			      pScrn->displayWidth);
 
     /* Strip out anything that we threw out for virtualX/Y. */
-    i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
+    RADEONxf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
 
     for (mode = pScrn->modes; mode; mode = mode->next)
 	if (xf86ModesEqual (mode, &crtc->desiredMode))
diff-tree 62a5e7565b66d7b7d65609c034f34b55bd266617 (from 29124400c7f193317d41d8cfd748371a239cfea1)
Author: Dave Airlie <airlied at linux.ie>
Date:   Fri Dec 15 19:48:42 2006 +1100

    bring over latest code from Intel git repo.
    
    this code doesn't work yet just realigns with intel work

diff --git a/src/radeon.h b/src/radeon.h
index 733b9c5..04b51c4 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -407,7 +407,6 @@ typedef struct {
 }RADEONTMDSPll;
 
 typedef struct {
-    xf86CrtcConfigRec xf86_config;
     EntityInfoPtr     pEnt;
     pciVideoPtr       PciInfo;
     PCITAG            PciTag;
diff --git a/src/radeon_display.c b/src/radeon_display.c
index f8db2ec..260f5a1 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2379,7 +2379,34 @@ void RADEONDisplayPowerManagementSet(Scr
 #endif
 }
 
+static void
+radeon_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+
+}
+
+static Bool
+radeon_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
+		     DisplayModePtr adjusted_mode)
+{
+    return TRUE;
+}
+
+static void
+radeon_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
+		   DisplayModePtr adjusted_mode)
+{
+    ScrnInfoPtr pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+}
+
 static const xf86CrtcFuncsRec radeon_crtc_funcs = {
+    .dpms = radeon_crtc_dpms,
+    .save = NULL, /* XXX */
+    .restore = NULL, /* XXX */
+    .mode_fixup = radeon_crtc_mode_fixup,
+    .mode_set = radeon_crtc_mode_set,
+    .destroy = NULL, /* XXX */
 };
 
 static void
@@ -2407,19 +2434,23 @@ radeon_mode_valid(xf86OutputPtr output, 
     return MODE_OK;
 }
 
-static void
-radeon_pre_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
+static Bool
+radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
+		    DisplayModePtr adjusted_mode)
 {
+    return TRUE;
 
 }
 
 static void
-radeon_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
+radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode,
+		  DisplayModePtr adjusted_mode)
 {
-}
+    
 
+}
 
-static enum detect_status
+static xf86OutputStatus
 radeon_detect(xf86OutputPtr output)
 {
     ScrnInfoPtr	    pScrn = output->scrn;
@@ -2428,11 +2459,11 @@ radeon_detect(xf86OutputPtr output)
 #if 0
     //    RADEONConnectorFindMonitor(pScrn, id);
     if (pRADEONEnt->PortInfo[id].MonType == MT_UNKNOWN)
-	return OUTPUT_STATUS_UNKNOWN;
+	return XF86OutputStatusUnknown;
     else if (pRADEONEnt->PortInfo[id].MonType == MT_NONE)
-	return OUTPUT_STATUS_DISCONNECTED;
+	return XF86OutputStatusDisconnected;
     else
-	return OUTPUT_STATUS_CONNECTED;
+	return XF86OutputStatusConnected;
 #endif
 }
 
@@ -2452,8 +2483,8 @@ static const xf86OutputFuncsRec radeon_o
     .save = radeon_save,
     .restore = radeon_restore,
     .mode_valid = radeon_mode_valid,
-    .pre_set_mode = radeon_pre_set_mode,
-    .post_set_mode = radeon_post_set_mode,
+    .mode_fixup = radeon_mode_fixup,
+    .mode_set = radeon_mode_set,
     .detect = radeon_detect,
     .get_modes = radeon_get_modes,
     .destroy = radeon_destroy
@@ -2471,7 +2502,7 @@ Bool RADEONAllocateControllers(ScrnInfoP
     if (!pRADEONEnt->pCrtc[0])
       return FALSE;
 
-    pRADEONEnt->Controller[0] = xnfcalloc(sizeof(xf86CrtcRec), 1);
+    pRADEONEnt->Controller[0] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
     if (!pRADEONEnt->Controller[0])
         return FALSE;
 
@@ -2485,7 +2516,7 @@ Bool RADEONAllocateControllers(ScrnInfoP
     if (!pRADEONEnt->pCrtc[1])
       return FALSE;
 
-    pRADEONEnt->Controller[1] = xnfcalloc(sizeof(xf86CrtcRec), 1);
+    pRADEONEnt->Controller[1] = xnfcalloc(sizeof(RADEONCrtcPrivateRec), 1);
     if (!pRADEONEnt->Controller[1])
     {
 	xfree(pRADEONEnt->Controller[0]);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index cf2af67..0aa594d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2837,7 +2837,8 @@ static Bool RADEONPreInitXv(ScrnInfoPtr 
 static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
-
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int i;
     if (!info->IsSecondary) {
       if (!RADEONAllocateConnectors(pScrn))
 	return FALSE;
@@ -2855,7 +2856,13 @@ static Bool RADEONPreInitControllers(Scr
     RADEONGetClockInfo(pScrn);
     RADEONGetPanelInfo(pScrn);
     RADEONGetTVDacAdjInfo(pScrn);
-    
+
+    for (i = 0; i < config->num_output; i++) 
+    {
+      xf86OutputPtr	      output = config->output[i];
+      
+      output->status = (*output->funcs->detect) (output);
+    }
     return TRUE;
 }
 
@@ -2872,6 +2879,7 @@ RADEONProbeDDC(ScrnInfoPtr pScrn, int in
 
 _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
 {
+    xf86CrtcConfigPtr   xf86_config;
     RADEONInfoPtr     info;
     xf86Int10InfoPtr  pInt10 = NULL;
     void *int10_save = NULL;
@@ -2980,6 +2988,11 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_VIEWPORT | RAC_CURSOR;
     pScrn->monitor     = pScrn->confScreen->monitor;
 
+   /* Allocate an xf86CrtcConfig */
+   xf86CrtcConfigInit (pScrn);
+   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+
     if (!RADEONPreInitVisual(pScrn))
 	goto fail;
 
@@ -3202,6 +3215,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     info->directRenderingEnabled = RADEONPreInitDRI(pScrn);
 #endif
 
+    xf86CrtcSetSizeRange (pScrn, 320, 200, 16384, 2048);
     if (!RADEONPreInitVRAM(pScrn))
 	goto fail;
 
@@ -3212,6 +3226,13 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     if (!RADEONPreInitControllers(pScrn, pInt10))
        goto fail;
 
+
+   if (!xf86InitialConfiguration (pScrn))
+   {
+      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
+      goto fail;
+   }
+
 	/* Get ScreenInit function */
     if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
 
@@ -3226,9 +3247,6 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     if (!RADEONPreInitGamma(pScrn))              goto fail;
 
-    if (!RADEONRandRPreInit(pScrn))
-	goto fail;
-
     if (!RADEONPreInitCursor(pScrn))             goto fail;
 
     if (!RADEONPreInitAccel(pScrn))              goto fail;
@@ -4262,7 +4280,8 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
     xf86DisableRandR(); /* Disable built-in RandR extension */
     /* support all rotations */
-    RADEONRandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for Radeon */
+    xf86RandR12Init (pScreen);
+    xf86RandR12SetRotations (pScreen, RR_Rotate_0); /* only 0 degrees for I965G */
 
     info->CreateScreenResources = pScreen->CreateScreenResources;
     pScreen->CreateScreenResources = RADEONCreateScreenResources;
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index bd11106..639d39a 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -595,14 +595,15 @@ int RADEONValidateMergeModes(ScrnInfoPtr
 void
 RADEONProbeOutputModes(ScrnInfoPtr pScrn)
 {
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     int i;
     DisplayModePtr ddc_modes, mode;
     DisplayModePtr test;
 
-    for (i = 0; i < info->xf86_config.num_output; i++) {
-        xf86OutputPtr output = info->xf86_config.output[i];
+    for (i = 0; i < config->num_output; i++) {
+        xf86OutputPtr output = config->output[i];
 	
 	test = output->probed_modes;
 	while(test != NULL) {
@@ -705,6 +706,7 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 void
 RADEON_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
 {
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR (pScrn);
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     DisplayModePtr saved_mode, last;
@@ -727,8 +729,8 @@ RADEON_set_xf86_modes_from_outputs(ScrnI
      * pScrn->modes should only be used for XF86VidMode now, which we don't
      * care about enough to make some sort of unioned list.
      */
-    for (i = 0; i < info->xf86_config.num_output; i++) {
-        xf86OutputPtr output = info->xf86_config.output[i];
+    for (i = 0; i < config->num_output; i++) {
+        xf86OutputPtr output = config->output[i];
 	if (output->probed_modes != NULL) {
 	    pScrn->modes =
 		RADEONxf86DuplicateModes(pScrn, output->probed_modes);
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index d3bd4c8..baa9207 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -61,8 +61,8 @@ typedef struct _radeonRandRInfo {
 } XF86RandRInfoRec, *XF86RandRInfoPtr;
 
 #ifdef RANDR_12_INTERFACE
-static Bool RADEONRandRInit12 (ScreenPtr pScreen);
-static Bool RADEONRandRCreateScreenResources12 (ScreenPtr pScreen);
+static Bool xf86RandR12Init12 (ScreenPtr pScreen);
+static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
 #endif
 
  
@@ -72,13 +72,279 @@ static int	    RADEONRandRGeneration;
 #define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[RADEONRandRIndex].ptr)
 
 #if RANDR_12_INTERFACE
+static int
+xf86RandR12ModeRefresh (DisplayModePtr mode)
+{
+    if (mode->VRefresh)
+	return (int) (mode->VRefresh + 0.5);
+    else
+	return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+static Bool
+xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+    RRScreenSizePtr	    pSize;
+    ScrnInfoPtr		    scrp = XF86SCRNINFO(pScreen);
+    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
+    DisplayModePtr	    mode;
+    int			    refresh0 = 60;
+    int			    maxX = 0, maxY = 0;
+
+    *rotations = randrp->supported_rotations;
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
+    {
+	randrp->virtualX = scrp->virtualX;
+	randrp->virtualY = scrp->virtualY;
+    }
+
+    /* Re-probe the outputs for new monitors or modes */
+    xf86ProbeOutputModes (scrp);
+    xf86SetScrnInfoModes (scrp);
+
+    for (mode = scrp->modes; ; mode = mode->next)
+    {
+	int refresh = xf86RandR12ModeRefresh (mode);
+	if (randrp->maxX == 0 || randrp->maxY == 0)
+	{
+		if (maxX < mode->HDisplay)
+			maxX = mode->HDisplay;
+		if (maxY < mode->VDisplay)
+			maxY = mode->VDisplay;
+	}
+	if (mode == scrp->modes)
+	    refresh0 = refresh;
+	pSize = RRRegisterSize (pScreen,
+				mode->HDisplay, mode->VDisplay,
+				randrp->mmWidth, randrp->mmHeight);
+	if (!pSize)
+	    return FALSE;
+	RRRegisterRate (pScreen, pSize, refresh);
+
+	if (xf86ModesEqual(mode, scrp->currentMode) &&
+	    mode->HDisplay == scrp->virtualX &&
+	    mode->VDisplay == scrp->virtualY)
+	{
+	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+	}
+	if (mode->next == scrp->modes)
+	    break;
+    }
+
+    if (randrp->maxX == 0 || randrp->maxY == 0)
+    {
+	randrp->maxX = maxX;
+	randrp->maxY = maxY;
+    }
+
+    if (scrp->currentMode->HDisplay != randrp->virtualX ||
+	scrp->currentMode->VDisplay != randrp->virtualY)
+    {
+	pSize = RRRegisterSize (pScreen,
+				randrp->virtualX, randrp->virtualY,
+				randrp->mmWidth,
+				randrp->mmHeight);
+	if (!pSize)
+	    return FALSE;
+	RRRegisterRate (pScreen, pSize, refresh0);
+	if (scrp->virtualX == randrp->virtualX &&
+	    scrp->virtualY == randrp->virtualY)
+	{
+	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
+	}
+    }
+
+    return TRUE;
+}
+
+static Bool
+xf86RandR12SetMode (ScreenPtr	    pScreen,
+		  DisplayModePtr    mode,
+		  Bool		    useVirtual,
+		  int		    mmWidth,
+		  int		    mmHeight)
+{
+    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    int			oldWidth = pScreen->width;
+    int			oldHeight = pScreen->height;
+    int			oldmmWidth = pScreen->mmWidth;
+    int			oldmmHeight = pScreen->mmHeight;
+    WindowPtr		pRoot = WindowTable[pScreen->myNum];
+    DisplayModePtr      currentMode = NULL;
+    Bool 		ret = TRUE;
+    PixmapPtr 		pspix = NULL;
+
+    if (pRoot)
+	(*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+    if (useVirtual)
+    {
+	scrp->virtualX = randrp->virtualX;
+	scrp->virtualY = randrp->virtualY;
+    }
+    else
+    {
+	scrp->virtualX = mode->HDisplay;
+	scrp->virtualY = mode->VDisplay;
+    }
+
+    if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+    {
+	/* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+	pScreen->width = scrp->virtualY;
+	pScreen->height = scrp->virtualX;
+	pScreen->mmWidth = mmHeight;
+	pScreen->mmHeight = mmWidth;
+    }
+    else
+    {
+	pScreen->width = scrp->virtualX;
+	pScreen->height = scrp->virtualY;
+	pScreen->mmWidth = mmWidth;
+	pScreen->mmHeight = mmHeight;
+    }
+    if (scrp->currentMode == mode) {
+        /* Save current mode */
+        currentMode = scrp->currentMode;
+        /* Reset, just so we ensure the drivers SwitchMode is called */
+        scrp->currentMode = NULL;
+    }
+    /*
+     * We know that if the driver failed to SwitchMode to the rotated
+     * version, then it should revert back to it's prior mode.
+     */
+    if (!xf86SwitchMode (pScreen, mode))
+    {
+        ret = FALSE;
+	scrp->virtualX = pScreen->width = oldWidth;
+	scrp->virtualY = pScreen->height = oldHeight;
+	pScreen->mmWidth = oldmmWidth;
+	pScreen->mmHeight = oldmmHeight;
+        scrp->currentMode = currentMode;
+    }
+    /*
+     * Get the new Screen pixmap ptr as SwitchMode might have called
+     * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
+     * Unfortunately.
+     */
+    pspix = (*pScreen->GetScreenPixmap) (pScreen);
+    if (pspix->devPrivate.ptr)
+       scrp->pixmapPrivate = pspix->devPrivate;
+
+    /*
+     * Make sure the layout is correct
+     */
+    xf86ReconfigureLayout();
+
+    /*
+     * Make sure the whole screen is visible
+     */
+    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+    xf86SetViewport (pScreen, 0, 0);
+    if (pRoot)
+	(*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+    return ret;
+}
+
+Bool
+xf86RandR12SetConfig (ScreenPtr		pScreen,
+		    Rotation		rotation,
+		    int			rate,
+		    RRScreenSizePtr	pSize)
+{
+    ScrnInfoPtr		scrp = XF86SCRNINFO(pScreen);
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    DisplayModePtr	mode;
+    int			px, py;
+    Bool		useVirtual = FALSE;
+    int			maxX = 0, maxY = 0;
+    Rotation		oldRotation = randrp->rotation;
+
+    randrp->rotation = rotation;
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
+    {
+	randrp->virtualX = scrp->virtualX;
+	randrp->virtualY = scrp->virtualY;
+    }
+
+    miPointerPosition (&px, &py);
+    for (mode = scrp->modes; ; mode = mode->next)
+    {
+	if (randrp->maxX == 0 || randrp->maxY == 0)
+	{
+		if (maxX < mode->HDisplay)
+			maxX = mode->HDisplay;
+		if (maxY < mode->VDisplay)
+			maxY = mode->VDisplay;
+	}
+	if (mode->HDisplay == pSize->width &&
+	    mode->VDisplay == pSize->height &&
+	    (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
+	    break;
+	if (mode->next == scrp->modes)
+	{
+	    if (pSize->width == randrp->virtualX &&
+		pSize->height == randrp->virtualY)
+	    {
+		mode = scrp->modes;
+		useVirtual = TRUE;
+		break;
+	    }
+    	    if (randrp->maxX == 0 || randrp->maxY == 0)
+    	    {
+		randrp->maxX = maxX;
+		randrp->maxY = maxY;
+    	    }
+	    return FALSE;
+	}
+    }
+
+    if (randrp->maxX == 0 || randrp->maxY == 0)
+    {
+	randrp->maxX = maxX;
+	randrp->maxY = maxY;
+    }
+
+    if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
+			   pSize->mmHeight)) {
+        randrp->rotation = oldRotation;
+	return FALSE;
+    }
+
+    /*
+     * Move the cursor back where it belongs; SwitchMode repositions it
+     */
+    if (pScreen == miPointerCurrentScreen ())
+    {
+        px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+        py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+	xf86SetViewport(pScreen, px, py);
+
+	(*pScreen->SetCursorPosition) (pScreen, px, py, FALSE);
+    }
+
+    return TRUE;
+}
+
+Rotation
+xf86RandR12GetRotation(ScreenPtr pScreen)
+{
+    XF86RandRInfoPtr	    randrp = XF86RANDRINFO(pScreen);
+
+    return randrp->rotation;
+}
+
+
 static void
 RADEONRandRPointerMoved (int scrnIndex, int x, int y)
 {
 }
 
 static Bool
-RADEONRandRScreenSetSize (ScreenPtr	pScreen,
+xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
 			CARD16		width,
 			CARD16		height,
 			CARD32		mmWidth,
@@ -89,7 +355,7 @@ RADEONRandRScreenSetSize (ScreenPtr	pScr
     WindowPtr		pRoot = WindowTable[pScreen->myNum];
     Bool 		ret = TRUE;
 
-    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
     {
 	randrp->virtualX = pScrn->virtualX;
 	randrp->virtualY = pScrn->virtualY;
@@ -103,7 +369,7 @@ RADEONRandRScreenSetSize (ScreenPtr	pScr
     pScreen->height = pScrn->virtualY;
     pScreen->mmWidth = mmWidth;
     pScreen->mmHeight = mmHeight;
-    
+
     xf86SetViewport (pScreen, pScreen->width, pScreen->height);
     xf86SetViewport (pScreen, 0, 0);
     if (pRoot)
@@ -114,79 +380,93 @@ RADEONRandRScreenSetSize (ScreenPtr	pScr
 }
 
 static Bool
-RADEONRandRCrtcNotify (RRCrtcPtr randr_crtc)
+xf86RandR12CrtcNotify (RRCrtcPtr	randr_crtc)
 {
-  ScreenPtr		pScreen = randr_crtc->pScreen;
-  XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-  ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-  RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-  RADEONInfoPtr info       = RADEONPTR(pScrn);
-  RRModePtr		randr_mode = NULL;
-  int x, y;
-  Rotation rotation;
-  int numOutputs;
-  RROutputPtr randr_outputs[RADEON_MAX_CRTC];
-  RROutputPtr randr_output;
-  xf86CrtcPtr crtc = randr_crtc->devPrivate;
-  xf86OutputPtr output;
-  int i, j;
-  DisplayModePtr	curMode = &crtc->curMode;
-
-  x = crtc->x;
-  y = crtc->y;
-  rotation = RR_Rotate_0;
-  numOutputs = 0;
-  randr_mode = NULL;
-
-  for (i = 0; i < info->xf86_config.num_output; i++) {
-    output = info->xf86_config.output[i];
-    if (output->crtc == crtc) {
-      
-      randr_output = output->randr_output;
-      randr_outputs[numOutputs++] = randr_output;
+    ScreenPtr		pScreen = randr_crtc->pScreen;
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RRModePtr		randr_mode = NULL;
+    int			x;
+    int			y;
+    Rotation		rotation;
+    int			numOutputs;
+    RROutputPtr		*randr_outputs;
+    RROutputPtr		randr_output;
+    xf86CrtcPtr		crtc = randr_crtc->devPrivate;
+    xf86OutputPtr	output;
+    int			i, j;
+    DisplayModePtr	curMode = &crtc->curMode;
+    Bool		ret;
 
-      for (j = 0; j < randr_output->numModes; j++) {
-	DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
-	if (xf86ModesEqual(curMode, outMode)) {
-	  randr_mode = randr_output->modes[j];
-	  break;
+    randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
+    if (!randr_outputs)
+	return FALSE;
+    x = crtc->x;
+    y = crtc->y;
+    rotation = RR_Rotate_0;
+    numOutputs = 0;
+    randr_mode = NULL;
+    for (i = 0; i < config->num_output; i++)
+    {
+	output = config->output[i];
+	if (output->crtc == crtc)
+	{
+	    randr_output = output->randr_output;
+	    randr_outputs[numOutputs++] = randr_output;
+	    /*
+	     * We make copies of modes, so pointer equality 
+	     * isn't sufficient
+	     */
+	    for (j = 0; j < randr_output->numModes; j++)
+	    {
+		DisplayModePtr	outMode = randr_output->modes[j]->devPrivate;
+		if (xf86ModesEqual(curMode, outMode))
+		{
+		    randr_mode = randr_output->modes[j];
+		    break;
+		}
+	    }
 	}
-      }
     }
-  }
-  
-  return RRCrtcNotify (randr_crtc, randr_mode, x, y, rotation, numOutputs, randr_outputs);
+    ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
+			rotation, numOutputs, randr_outputs);
+    DEALLOCATE_LOCAL(randr_outputs);
+    return ret;
 }
 
 static Bool
-RADEONRandRCrtcSet (ScreenPtr	pScreen,
-		  RRCrtcPtr	randr_crtc,
-		  RRModePtr	randr_mode,
-		  int		x,
-		  int		y,
-		  Rotation	rotation,
-		  int		num_randr_outputs,
-		  RROutputPtr	*randr_outputs)
+xf86RandR12CrtcSet (ScreenPtr	pScreen,
+		    RRCrtcPtr	randr_crtc,
+		    RRModePtr	randr_mode,
+		    int		x,
+		    int		y,
+		    Rotation	rotation,
+		    int		num_randr_outputs,
+		    RROutputPtr	*randr_outputs)
 {
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-  RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-  RADEONInfoPtr info       = RADEONPTR(pScrn);
+  xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
   xf86CrtcPtr crtc = randr_crtc->devPrivate;
-  RADEONCrtcPrivatePtr pRcrtc = crtc->driver_private;
   DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
   Bool changed = FALSE;
+  Bool pos_changed;
   int o, ro;
-  xf86CrtcPtr save_crtcs[RADEON_MAX_CONNECTOR];
+  xf86CrtcPtr		*save_crtcs;
   Bool save_enabled = crtc->enabled;
   int ret;
 
+  save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
   if ((mode != NULL) != crtc->enabled)
     changed = TRUE;
   else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
     changed = TRUE;
 
-  for (o = 0; o < info->xf86_config.num_output; o++) {
-    xf86OutputPtr output = info->xf86_config.output[o];
+  pos_changed = changed;
+  if (x != crtc->x || y != crtc->y)
+    pos_changed = TRUE;
+
+  for (o = 0; o < config->num_output; o++) {
+    xf86OutputPtr  output = config->output[o];
     xf86CrtcPtr new_crtc;
 
     save_crtcs[o] = output->crtc;
@@ -209,6 +489,9 @@ RADEONRandRCrtcSet (ScreenPtr	pScreen,
 
   /* got to set the modes in here */
   if (changed) {
+    RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    RADEONInfoPtr  info = RADEONPTR(pScrn);
+    RADEONCrtcPrivatePtr pRcrtc;
     crtc->enabled = mode != NULL;
 
     if (info->accelOn)
@@ -222,31 +505,31 @@ RADEONRandRCrtcSet (ScreenPtr	pScreen,
       
       if (!ret) {
 	crtc->enabled = save_enabled;
-	for (o = 0; o < info->xf86_config.num_output; o++) {
-	  xf86OutputPtr output = info->xf86_config.output[o];
+	for (o = 0; o < config->num_output; o++) {
+	  xf86OutputPtr output = config->output[o];
 	  output->crtc = save_crtcs[o];
 	}
+	DEALLOCATE_LOCAL(save_crtcs);
 	return FALSE;
       }
       crtc->desiredMode = *mode;
+      
+      pScrn->vtSema = TRUE;
+      RADEONBlank(pScrn);
+      RADEONRestoreMode(pScrn, &info->ModeReg);
+      RADEONUnblank(pScrn);
+      
+      if (info->DispPriority)
+	RADEONInitDispBandwidth(pScrn);
     }
   }
-
-  if (changed) {
-	pScrn->vtSema = TRUE;
-	RADEONBlank(pScrn);
-	RADEONRestoreMode(pScrn, &info->ModeReg);
-	RADEONUnblank(pScrn);
-	
-	if (info->DispPriority)
-		RADEONInitDispBandwidth(pScrn);
-  }
+  DEALLOCATE_LOCAL(save_crtcs);
   return RADEONRandRCrtcNotify(randr_crtc);
 }
 
 
 static Bool
-RADEONRandRCrtcSetGamma (ScreenPtr    pScreen,
+xf86RandR12CrtcSetGamma (ScreenPtr    pScreen,
 		       RRCrtcPtr    crtc)
 {
     return FALSE;
@@ -257,7 +540,7 @@ RADEONRandRCrtcSetGamma (ScreenPtr    pS
  * RandR modes and assign them to the output
  */
 static Bool
-RADEONxf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
+xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
 {
     DisplayModePtr  mode;
     RRModePtr	    *rrmodes = NULL;
@@ -316,63 +599,80 @@ RADEONxf86RROutputSetModes (RROutputPtr 
  * Mirror the current mode configuration to RandR
  */
 static Bool
-RADEONRandRSetInfo12 (ScrnInfoPtr pScrn)
+xf86RandR12SetInfo12 (ScreenPtr pScreen)
 {
-    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    RROutputPtr		clones[RADEON_MAX_CONNECTOR];
-    RRCrtcPtr		crtc;
-    int			nclone;
-    RRCrtcPtr		crtcs[RADEON_MAX_CRTC];
-    int			ncrtc;
-    DisplayModePtr	modes, mode;
-    xRRModeInfo		modeInfo;
-    RRModePtr		rrmode, *rrmodes;
-    int                 nmode, npreferred;
-    int i, j, p;
-    CARD32		possibleOptions = 0;
-    CARD32		currentOptions = 0;
-    int			connection;
-    int                 subpixel = SubPixelNone;
-    RRCrtcPtr		    randr_crtc;
-    xf86OutputPtr connector;
-    RADEONOutputPrivatePtr pRPort;
-
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-      ncrtc = 0;
-      crtc = NULL;
-      
-      connector = pRADEONEnt->pOutput[i];
-      pRPort = pRADEONEnt->PortInfo[i];
-
-      if (pRPort->MonType) {
-	crtc = pRADEONEnt->pCrtc[i]->randr_crtc;
-	crtcs[ncrtc++] = crtc;
-	randr_crtc = crtc;
-      } else
-	randr_crtc = NULL;
-      
-
-      if (!RROutputSetCrtcs(connector->randr_output, crtcs, ncrtc))
-	return FALSE;
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    RROutputPtr		*clones;
+    RRCrtcPtr		*crtcs;
+    int ncrtc;
+    int o, c, l;
+    RRCrtcPtr		randr_crtc;
+    int nclone;
+
+    clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
+    crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr));
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+	
+	ncrtc = 0;
+	for (c = 0; c < config->num_crtc; c++)
+	    if (output->possible_crtcs & (1 << c))
+		crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
 
-      RROutputSetCrtc(connector->randr_output, crtc);
+	if (output->crtc)
+	    randr_crtc = output->crtc->randr_crtc;
+	else
+	    randr_crtc = NULL;
 
-      nmode = 0;
-      npreferred = 0;
-      rrmodes = NULL;
-      
-      if (connector->probed_modes) {
-	RADEONxf86RROutputSetModes (connector->randr_output, connector->probed_modes);
-      }
+	if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
+	{
+	    DEALLOCATE_LOCAL (crtcs);
+	    DEALLOCATE_LOCAL (clones);
+	    return FALSE;
+	}
 
-      connection = RR_Disconnected;
-      if (pRPort->MonType > MT_NONE)
-	connection = RR_Connected;
+	RROutputSetCrtc (output->randr_output, randr_crtc);
+	RROutputSetPhysicalSize(output->randr_output, 
+				output->mm_width,
+				output->mm_height);
+	xf86RROutputSetModes (output->randr_output, output->probed_modes);
+
+	switch (output->status = (*output->funcs->detect)(output)) {
+	case XF86OutputStatusConnected:
+	    RROutputSetConnection (output->randr_output, RR_Connected);
+	    break;
+	case XF86OutputStatusDisconnected:
+	    RROutputSetConnection (output->randr_output, RR_Disconnected);
+	    break;
+	case XF86OutputStatusUnknown:
+	    RROutputSetConnection (output->randr_output, RR_UnknownConnection);
+	    break;
+	}
 
-      RROutputSetConnection(connector->randr_output, connection);
+	RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
 
-      RROutputSetSubpixelOrder(connector->randr_output, subpixel);
+	/*
+	 * Valid clones
+	 */
+	nclone = 0;
+	for (l = 0; l < config->num_output; l++)
+	{
+	    xf86OutputPtr	    clone = config->output[l];
+	    
+	    if (l != o && (output->possible_clones & (1 << l)))
+		clones[nclone++] = clone->randr_output;
+	}
+	if (!RROutputSetClones (output->randr_output, clones, nclone))
+	{
+	    DEALLOCATE_LOCAL (crtcs);
+	    DEALLOCATE_LOCAL (clones);
+	    return FALSE;
+	}
     }
+    DEALLOCATE_LOCAL (crtcs);
+    DEALLOCATE_LOCAL (clones);
     return TRUE;
 }
 
@@ -381,11 +681,12 @@ RADEONRandRSetInfo12 (ScrnInfoPtr pScrn)
  * that to RandR
  */
 static Bool
-RADEONRandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations)
+xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
 {
     ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
 
-    RADEONProbeOutputModes(pScrn);
+    xf86ProbeOutputModes (pScrn);
+    xf86SetScrnInfoModes (pScrn);
     return RADEONRandRSetInfo12 (pScrn);
 }
 
@@ -402,100 +703,101 @@ RADEONRandRCreateScreenResources (Screen
 }
 
 static Bool
-RADEONRandRCreateObjects12(ScrnInfoPtr pScrn)
+xf86RandR12CreateObjects12(ScreenPtr pScreen)
 {
-  int i;
-  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-  RADEONInfoPtr  info = RADEONPTR(pScrn);
+  ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+  xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+  int c, o;
 
   if (!RRInit())
     return FALSE;
 
+
   /*
-   * Create RandR resources, then probe them
+   * Configure crtcs
    */
-  for (i = 0; i < 2; i++)
+  for (c = 0; c < config->num_crtc; c++)
   {
-    RRCrtcPtr randr_crtc = RRCrtcCreate((void *)i);
-
-    if (!randr_crtc)
-      return FALSE;
-
-    RRCrtcGammaSetSize(randr_crtc, 256);
-    pRADEONEnt->pCrtc[i]->randr_crtc = randr_crtc;
+    xf86CrtcPtr    crtc = config->crtc[c];
+    
+    crtc->randr_crtc = RRCrtcCreate (crtc);
+    RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
+    RRCrtcGammaSetSize (crtc->randr_crtc, 256);
   }
 
-  for (i = 0; i < 2; i++)
+  /*
+   * Configure outputs
+   */
+  for (o = 0; o < config->num_output; o++)
   {
-    int output = pRADEONEnt->PortInfo[i]->ConnectorType;
-    const char *name = name = info->IsAtomBios ? ConnectorTypeNameATOM[output] : ConnectorTypeName[output];
-    RROutputPtr randr_output = RROutputCreate(name, strlen(name),
-					      (void *) i);
+    xf86OutputPtr	output = config->output[o];
     
-    if (!randr_output)
-      return FALSE;
+    output->randr_output = RROutputCreate (output->name, 
+					   strlen (output->name),
+					   output);
+    RROutputAttachScreen (output->randr_output, pScreen);
+  } 
 
-    pRADEONEnt->pOutput[i]->randr_output = randr_output;
-  }
   return TRUE;
 }
 
 static Bool
-RADEONRandRCreateScreenResources12 (ScreenPtr pScreen)
+xf86RandRCreateScreenResources12 (ScreenPtr pScreen)
 {
-  XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
-  ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
-  RADEONInfoPtr  info = RADEONPTR(pScrn);
-  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-  DisplayModePtr mode;
-  const char *name;
-  int i;
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(pScrn);
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    int			c;
+    int			width, height;
 
-  for (i = 0; i < 2; i++)
-  {
-    if (!RRCrtcAttachScreen(pRADEONEnt->pCrtc[i]->randr_crtc, pScreen))
-      return FALSE;
-  }
-  
-  for (i = 0; i < 2; i++) {
-    if (!RROutputAttachScreen(pRADEONEnt->pOutput[i]->randr_output, pScreen))
-      return FALSE;
-  }
+    /*
+     * Compute width of screen
+     */
+    width = 0; height = 0;
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = config->crtc[c];
+	int	    crtc_width = crtc->x + crtc->curMode.HDisplay;
+	int	    crtc_height = crtc->y + crtc->curMode.VDisplay;
+	
+	if (crtc->enabled && crtc_width > width)
+	    width = crtc_width;
+	if (crtc->enabled && crtc_height > height)
+	    height = crtc_height;
+    }
+    
+    if (width && height)
+    {
+	int mmWidth, mmHeight;
 
-  mode = pScrn->currentMode;
-  if (mode) {
-    int mmWidth, mmHeight;
-    
-    if (mode->HDisplay == pScreen->width &&
-	mode->VDisplay == pScreen->height)
-      {
-	mmWidth = pScrn->widthmm;
-	mmHeight = pScrn->heightmm;
-      } else {
-#define MMPERINCH 25.4
-	mmWidth = (double) mode->HDisplay / pScrn->xDpi * MMPERINCH;
-	mmHeight = (double) mode->VDisplay / pScrn->yDpi * MMPERINCH;
-    }
-    RADEONRandRScreenSetSize (pScreen,
-			    mode->HDisplay,
-			    mode->VDisplay,
-			    mmWidth,
-			    mmHeight);
-  }
+	mmWidth = pScreen->mmWidth;
+	mmHeight = pScreen->mmHeight;
+	if (width != pScreen->width)
+	    mmWidth = mmWidth * width / pScreen->width;
+	if (height != pScreen->height)
+	    mmHeight = mmHeight * height / pScreen->height;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Setting screen physical size to %d x %d\n",
+		   mmWidth, mmHeight);
+	xf86RandR12ScreenSetSize (pScreen,
+				  width,
+				  height,
+				  mmWidth,
+				  mmHeight);
+    }
 
-  for (i = 0; i < RADEON_MAX_CRTC; i++)
-    RADEONRandRCrtcNotify (pRADEONEnt->pCrtc[i]->randr_crtc);
+    for (c = 0; c < config->num_crtc; c++)
+	xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
     
-  if (randrp->virtualX == -1 || randrp->virtualY == -1)
-  {
-    randrp->virtualX = pScrn->virtualX;
-    randrp->virtualY = pScrn->virtualY;
-  }
-  
-  RRScreenSetSizeRange (pScreen, 320, 240,
-			randrp->virtualX, randrp->virtualY);
-  return TRUE;
-
+    if (randrp->virtualX == -1 || randrp->virtualY == -1)
+    {
+	randrp->virtualX = pScrn->virtualX;
+	randrp->virtualY = pScrn->virtualY;
+    }
+    
+    RRScreenSetSizeRange (pScreen, 320, 240,
+			  randrp->virtualX, randrp->virtualY);
+    return TRUE;
 }
 
 Bool
@@ -548,19 +850,27 @@ RADEONRandRInit (ScreenPtr    pScreen, i
     return TRUE;
 }
 
-static Bool
+Bool
 RADEONRandRInit12(ScreenPtr pScreen)
 {
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
   rrScrPrivPtr rp = rrGetScrPriv(pScreen);
 
-  rp->rrGetInfo = RADEONRandRGetInfo12;
-  rp->rrScreenSetSize = RADEONRandRScreenSetSize;
-  rp->rrCrtcSet = RADEONRandRCrtcSet;
-  rp->rrCrtcSetGamma = RADEONRandRCrtcSetGamma;
+    rp->rrGetInfo = xf86RandR12GetInfo12;
+    rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
+    rp->rrCrtcSet = xf86RandR12CrtcSet;
+    rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
   rp->rrSetConfig = NULL;
   //  memset (rp->modes, '\0', sizeof (rp->modes));
   pScrn->PointerMoved = RADEONRandRPointerMoved;
+
+  if (!xf86RandR12CreateObjects12 (pScreen))
+    return FALSE;
+  /*
+   * Configure output modes
+   */
+  if (!xf86RandR12SetInfo12 (pScreen))
+    return FALSE;
   return TRUE;
 }
 
@@ -823,7 +1133,7 @@ RADEONRRDefaultScreenLimits (RROutputPtr
     *heightp = height;
 }
 
-
+#if 0
 Bool
 RADEONRandRPreInit(ScrnInfoPtr pScrn)
 {
@@ -841,7 +1151,7 @@ RADEONRandRPreInit(ScrnInfoPtr pScrn)
   RADEONProbeOutputModes(pScrn);
 
 #if RANDR_12_INTERFACE
-  if (!RADEONRandRCreateObjects12(pScrn))
+  if (!xf86RandRCreateObjects12(pScrn))
     return FALSE;
 
   if (!RADEONRandRSetInfo12(pScrn))
@@ -905,3 +1215,10 @@ RADEONRandRPreInit(ScrnInfoPtr pScrn)
   return TRUE;
 }
 #endif
+#endif
+
+Bool
+xf86RandR12PreInit (ScrnInfoPtr pScrn)
+{
+    return TRUE;
+}
diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
index 41d6f86..22f7ae4 100644
--- a/src/radeon_xf86Crtc.c
+++ b/src/radeon_xf86Crtc.c
@@ -31,7 +31,43 @@
 #include <stdio.h>
 
 #include "xf86.h"
+#include "xf86DDC.h"
+//#include "i.h"
 #include "radeon_xf86Crtc.h"
+#include "X11/extensions/render.h"
+
+#define DPMS_SERVER
+#include "X11/extensions/dpms.h"
+
+/*
+ * Initialize xf86CrtcConfig structure
+ */
+
+int xf86CrtcConfigPrivateIndex = -1;
+
+void
+xf86CrtcConfigInit (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr	config;
+    
+    if (xf86CrtcConfigPrivateIndex == -1)
+	xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+    config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
+    scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
+}
+ 
+void
+xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
+		      int minWidth, int minHeight,
+		      int maxWidth, int maxHeight)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+
+    config->minWidth = minWidth;
+    config->minHeight = minHeight;
+    config->maxWidth = maxWidth;
+    config->maxHeight = maxHeight;
+}
 
 /*
  * Crtc functions
@@ -41,7 +77,7 @@ xf86CrtcCreate (ScrnInfoPtr		scrn,
 		const xf86CrtcFuncsRec	*funcs)
 {
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr		crtc;
+    xf86CrtcPtr		crtc, *crtcs;
 
     crtc = xcalloc (sizeof (xf86CrtcRec), 1);
     if (!crtc)
@@ -49,13 +85,19 @@ xf86CrtcCreate (ScrnInfoPtr		scrn,
     crtc->scrn = scrn;
     crtc->funcs = funcs;
 #ifdef RANDR_12_INTERFACE
-    crtc->randr_crtc = RRCrtcCreate (crtc);
-    if (!crtc->randr_crtc)
+    crtc->randr_crtc = NULL;
+#endif
+    if (xf86_config->crtc)
+	crtcs = xrealloc (xf86_config->crtc,
+			  (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
+    else
+	crtcs = xalloc ((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
+    if (!crtcs)
     {
 	xfree (crtc);
 	return NULL;
     }
-#endif
+    xf86_config->crtc = crtcs;
     xf86_config->crtc[xf86_config->num_crtc++] = crtc;
     return crtc;
 }
@@ -67,9 +109,6 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
     int			c;
     
     (*crtc->funcs->destroy) (crtc);
-#ifdef RANDR_12_INTERFACE
-    RRCrtcDestroy (crtc->randr_crtc);
-#endif
     for (c = 0; c < xf86_config->num_crtc; c++)
 	if (xf86_config->crtc[c] == crtc)
 	{
@@ -90,7 +129,7 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
 		  const xf86OutputFuncsRec *funcs,
 		  const char		    *name)
 {
-    xf86OutputPtr	output;
+    xf86OutputPtr	output, *outputs;
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
     int			len = strlen (name);
 
@@ -100,20 +139,42 @@ xf86OutputCreate (ScrnInfoPtr		    scrn,
     output->scrn = scrn;
     output->funcs = funcs;
     output->name = (char *) (output + 1);
+    output->subpixel_order = SubPixelUnknown;
     strcpy (output->name, name);
 #ifdef RANDR_12_INTERFACE
-    output->randr_output = RROutputCreate (name, strlen (name), output);
-    if (!output->randr_output)
+    output->randr_output = NULL;
+#endif
+    if (xf86_config->output)
+	outputs = xrealloc (xf86_config->output,
+			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
+    else
+	outputs = xalloc ((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
+    if (!outputs)
     {
 	xfree (output);
 	return NULL;
     }
-#endif
+    xf86_config->output = outputs;
     xf86_config->output[xf86_config->num_output++] = output;
     return output;
 }
 
 void
+xf86OutputRename (xf86OutputPtr output, const char *name)
+{
+    int	    len = strlen(name);
+    char    *newname = xalloc (len + 1);
+    
+    if (!newname)
+	return;	/* so sorry... */
+    
+    strcpy (newname, name);
+    if (output->name != (char *) (output + 1))
+	xfree (output->name);
+    output->name = newname;
+}
+
+void
 xf86OutputDestroy (xf86OutputPtr output)
 {
     ScrnInfoPtr		scrn = output->scrn;
@@ -121,9 +182,6 @@ xf86OutputDestroy (xf86OutputPtr output)
     int			o;
     
     (*output->funcs->destroy) (output);
-#ifdef RANDR_12_INTERFACE
-    RROutputDestroy (output->randr_output);
-#endif
     while (output->probed_modes)
 	xf86DeleteMode (&output->probed_modes, output->probed_modes);
     for (o = 0; o < xf86_config->num_output; o++)
@@ -135,6 +193,552 @@ xf86OutputDestroy (xf86OutputPtr output)
 	    xf86_config->num_output--;
 	    break;
 	}
+    if (output->name != (char *) (output + 1))
+	xfree (output->name);
     xfree (output);
 }
 
+static DisplayModePtr
+xf86DefaultMode (xf86OutputPtr output, int width, int height)
+{
+    DisplayModePtr  target_mode = NULL;
+    DisplayModePtr  mode;
+    int		    target_diff = 0;
+    int		    target_preferred = 0;
+    int		    mm_height;
+    
+    mm_height = output->mm_height;
+    if (!mm_height)
+	mm_height = 203;	/* 768 pixels at 96dpi */
+    /*
+     * Pick a mode closest to 96dpi 
+     */
+    for (mode = output->probed_modes; mode; mode = mode->next)
+    {
+	int	    dpi;
+	int	    preferred = (mode->type & M_T_PREFERRED) != 0;
+	int	    diff;
+
+	if (mode->HDisplay > width || mode->VDisplay > height) continue;
+	dpi = (mode->HDisplay * 254) / (mm_height * 10);
+	diff = dpi - 96;
+	diff = diff < 0 ? -diff : diff;
+	if (target_mode == NULL || (preferred > target_preferred) ||
+	    (preferred == target_preferred && diff < target_diff))
+	{
+	    target_mode = mode;
+	    target_diff = diff;
+	    target_preferred = preferred;
+	}
+    }
+    return target_mode;
+}
+
+static DisplayModePtr
+xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match,
+		 int width, int height)
+{
+    DisplayModePtr  target_mode = NULL;
+    DisplayModePtr  mode;
+    int		    target_diff = 0;
+    
+    /*
+     * Pick a mode closest to the specified mode
+     */
+    for (mode = output->probed_modes; mode; mode = mode->next)
+    {
+	int	    dx, dy;
+	int	    diff;
+
+	if (mode->HDisplay > width || mode->VDisplay > height) continue;
+	
+	/* exact matches are preferred */
+	if (xf86ModesEqual (mode, match))
+	    return mode;
+	
+	dx = match->HDisplay - mode->HDisplay;
+	dy = match->VDisplay - mode->VDisplay;
+	diff = dx * dx + dy * dy;
+	if (target_mode == NULL || diff < target_diff)
+	{
+	    target_mode = mode;
+	    target_diff = diff;
+	}
+    }
+    return target_mode;
+}
+
+static Bool
+xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
+{
+    DisplayModePtr  mode;
+
+    for (mode = output->probed_modes; mode; mode = mode->next)
+    {
+	if (mode->HDisplay > width || mode->VDisplay > height) continue;
+	if (mode->type & M_T_PREFERRED)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+static int
+xf86PickCrtcs (ScrnInfoPtr	pScrn,
+	       xf86CrtcPtr	*best_crtcs,
+	       DisplayModePtr	*modes,
+	       int		n,
+	       int		width,
+	       int		height)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int		    c, o, l;
+    xf86OutputPtr   output;
+    xf86CrtcPtr	    crtc;
+    xf86CrtcPtr	    *crtcs;
+    xf86CrtcPtr	    best_crtc;
+    int		    best_score;
+    int		    score;
+    int		    my_score;
+    
+    if (n == config->num_output)
+	return 0;
+    output = config->output[n];
+    
+    /*
+     * Compute score with this output disabled
+     */
+    best_crtcs[n] = NULL;
+    best_crtc = NULL;
+    best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1, width, height);
+    if (modes[n] == NULL)
+	return best_score;
+    
+    crtcs = xalloc (config->num_output * sizeof (xf86CrtcPtr));
+    if (!crtcs)
+	return best_score;
+
+    my_score = 1;
+    /* Score outputs that are known to be connected higher */
+    if (output->status == XF86OutputStatusConnected)
+	my_score++;
+    /* Score outputs with preferred modes higher */
+    if (xf86OutputHasPreferredMode (output, width, height))
+	my_score++;
+    /*
+     * Select a crtc for this output and
+     * then attempt to configure the remaining
+     * outputs
+     */
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	if ((output->possible_crtcs & (1 << c)) == 0)
+	    continue;
+	
+	crtc = config->crtc[c];
+	/*
+	 * Check to see if some other output is
+	 * using this crtc
+	 */
+	for (o = 0; o < n; o++)
+	    if (best_crtcs[o] == crtc)
+		break;
+	if (o < n)
+	{
+	    /*
+	     * If the two outputs desire the same mode,
+	     * see if they can be cloned
+	     */
+	    if (xf86ModesEqual (modes[o], modes[n]))
+	    {
+		for (l = 0; l < config->num_output; l++)
+		    if (output->possible_clones & (1 << l))
+			break;
+		if (l == config->num_output)
+		    continue;		/* nope, try next CRTC */
+	    }
+	    else
+		continue;		/* different modes, can't clone */
+	}
+	crtcs[n] = crtc;
+	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
+	score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
+	if (score >= best_score)
+	{
+	    best_crtc = crtc;
+	    best_score = score;
+	    memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
+	}
+    }
+    xfree (crtcs);
+    return best_score;
+}
+
+
+/*
+ * Compute the virtual size necessary to place all of the available
+ * crtcs in a panorama configuration
+ */
+
+static void
+xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int	    width = 0, height = 0;
+    int	    o;
+    int	    c;
+    int	    s;
+
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	int	    crtc_width = 0, crtc_height = 0;
+
+	for (o = 0; o < config->num_output; o++) 
+	{
+	    xf86OutputPtr   output = config->output[o];
+
+	    for (s = 0; s < config->num_crtc; s++)
+		if (output->possible_crtcs & (1 << s))
+		{
+		    DisplayModePtr  mode;
+		    for (mode = output->probed_modes; mode; mode = mode->next)
+		    {
+			if (mode->HDisplay > crtc_width)
+			    crtc_width = mode->HDisplay;
+			if (mode->VDisplay > crtc_height)
+			    crtc_height = mode->VDisplay;
+		    }
+		}
+	}
+	width += crtc_width;
+	if (crtc_height > height)
+	    height = crtc_height;
+    }
+    if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
+    if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
+    if (config->minWidth && width < config->minWidth) width = config->minWidth;
+    if (config->minHeight && height < config->minHeight) height = config->minHeight;
+    *widthp = width;
+    *heightp = height;
+}
+
+/*
+ * XXX walk the monitor mode list and prune out duplicates that
+ * are inserted by xf86DDCMonitorSet. In an ideal world, that
+ * function would do this work by itself.
+ */
+
+static void
+xf86PruneDuplicateMonitorModes (MonPtr Monitor)
+{
+    DisplayModePtr  master, clone, next;
+
+    for (master = Monitor->Modes; 
+	 master && master != Monitor->Last; 
+	 master = master->next)
+    {
+	for (clone = master->next; clone && clone != Monitor->Modes; clone = next)
+	{
+	    next = clone->next;
+	    if (xf86ModesEqual (master, clone))
+		xf86DeleteMode (&Monitor->Modes, clone);
+	}
+    }
+}
+
+void
+xf86ProbeOutputModes (ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    Bool		properties_set = FALSE;
+    int			o;
+
+    /* Elide duplicate modes before defaulting code uses them */
+    xf86PruneDuplicateMonitorModes (pScrn->monitor);
+    
+    /* Probe the list of modes for each output. */
+    for (o = 0; o < config->num_output; o++) 
+    {
+	xf86OutputPtr  output = config->output[o];
+	DisplayModePtr mode;
+
+	while (output->probed_modes != NULL)
+	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
+
+	output->probed_modes = (*output->funcs->get_modes) (output);
+
+	/* Set the DDC properties to whatever first output has DDC information.
+	 */
+	if (output->MonInfo != NULL && !properties_set) {
+	    xf86SetDDCproperties(pScrn, output->MonInfo);
+	    properties_set = TRUE;
+	}
+
+#ifdef DEBUG_REPROBE
+	if (output->probed_modes != NULL) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Printing probed modes for output %s\n",
+		       output->name);
+	} else {
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "No remaining probed modes for output %s\n",
+		       output->name);
+	}
+#endif
+	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
+	{
+	    /* The code to choose the best mode per pipe later on will require
+	     * VRefresh to be set.
+	     */
+	    mode->VRefresh = xf86ModeVRefresh(mode);
+	    xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+
+#ifdef DEBUG_REPROBE
+	    xf86PrintModeline(pScrn->scrnIndex, mode);
+#endif
+	}
+    }
+}
+
+
+/**
+ * Copy one of the output mode lists to the ScrnInfo record
+ */
+
+/* XXX where does this function belong? Here? */
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
+
+void
+xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86OutputPtr	output;
+    xf86CrtcPtr		crtc;
+    DisplayModePtr	last, mode;
+    int			originalVirtualX, originalVirtualY;
+
+    output = config->output[config->compat_output];
+    if (!output->crtc)
+    {
+	int o;
+
+	output = NULL;
+	for (o = 0; o < config->num_output; o++)
+	    if (config->output[o]->crtc)
+	    {
+		config->compat_output = o;
+		output = config->output[o];
+		break;
+	    }
+	/* no outputs are active, punt and leave things as they are */
+	if (!output)
+	    return;
+    }
+    crtc = output->crtc;
+
+    /* Clear any existing modes from pScrn->modes */
+    while (pScrn->modes != NULL)
+	xf86DeleteMode(&pScrn->modes, pScrn->modes);
+
+    /* Set pScrn->modes to the mode list for the 'compat' output */
+    pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
+
+    xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
+
+    /* Disable modes in the XFree86 DDX list that are larger than the current
+     * virtual size.
+     */
+    i830xf86ValidateModesSize(pScrn, pScrn->modes,
+			      originalVirtualX, originalVirtualY,
+			      pScrn->displayWidth);
+
+    /* Strip out anything that we threw out for virtualX/Y. */
+    i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
+
+    for (mode = pScrn->modes; mode; mode = mode->next)
+	if (xf86ModesEqual (mode, &crtc->desiredMode))
+	    break;
+    
+    /* For some reason, pScrn->modes is circular, unlike the other mode lists.
+     * How great is that?
+     */
+    for (last = pScrn->modes; last && last->next; last = last->next);
+    last->next = pScrn->modes;
+    pScrn->modes->prev = last;
+    if (mode)
+	while (pScrn->modes != mode)
+	    pScrn->modes = pScrn->modes->next;
+    pScrn->currentMode = pScrn->modes;
+}
+
+/**
+ * Construct default screen configuration
+ *
+ * Given auto-detected (and, eventually, configured) values,
+ * construct a usable configuration for the system
+ */
+
+Bool
+xf86InitialConfiguration (ScrnInfoPtr	    pScrn)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o, c;
+    DisplayModePtr	target_mode = NULL;
+    xf86CrtcPtr		*crtcs;
+    DisplayModePtr	*modes;
+    int			width, height;
+
+    xf86ProbeOutputModes (pScrn);
+
+    if (pScrn->display->virtualX == 0)
+    {
+	/*
+	 * Expand virtual size to cover potential mode switches
+	 */
+	xf86DefaultScreenLimits (pScrn, &width, &height);
+    
+	pScrn->display->virtualX = width;
+	pScrn->display->virtualY = height;
+    }
+    else
+    {
+	width = pScrn->display->virtualX;
+	height = pScrn->display->virtualY;
+    }
+    if (width > pScrn->virtualX)
+	pScrn->virtualX = width;
+    if (height > pScrn->virtualY)
+	pScrn->virtualY = height;
+    
+    crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
+    modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
+    
+    for (o = 0; o < config->num_output; o++)
+	modes[o] = NULL;
+    
+    /*
+     * Let outputs with preferred modes drive screen size
+     */
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr output = config->output[o];
+
+	if (output->status != XF86OutputStatusDisconnected &&
+	    xf86OutputHasPreferredMode (output, width, height))
+	{
+	    target_mode = xf86DefaultMode (output, width, height);
+	    if (target_mode)
+	    {
+		modes[o] = target_mode;
+		config->compat_output = o;
+		break;
+	    }
+	}
+    }
+    if (!target_mode)
+    {
+	for (o = 0; o < config->num_output; o++)
+	{
+	    xf86OutputPtr output = config->output[o];
+	    if (output->status != XF86OutputStatusDisconnected)
+	    {
+		target_mode = xf86DefaultMode (output, width, height);
+		if (target_mode)
+		{
+		    modes[o] = target_mode;
+		    config->compat_output = o;
+		    break;
+		}
+	    }
+	}
+    }
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr output = config->output[o];
+	
+	if (output->status != XF86OutputStatusDisconnected && !modes[o])
+	    modes[o] = xf86ClosestMode (output, target_mode, width, height);
+    }
+
+    if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
+    {
+	xfree (crtcs);
+	xfree (modes);
+	return FALSE;
+    }
+    
+    /* XXX override xf86 common frame computation code */
+    
+    pScrn->display->frameX0 = 0;
+    pScrn->display->frameY0 = 0;
+    
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr	crtc = config->crtc[c];
+
+	crtc->enabled = FALSE;
+	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
+    }
+	
+    /*
+     * Set initial configuration
+     */
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+	DisplayModePtr	mode = modes[o];
+        xf86CrtcPtr	crtc = crtcs[o];
+
+	if (mode && crtc)
+	{
+	    crtc->desiredMode = *mode;
+	    crtc->enabled = TRUE;
+	    crtc->x = 0;
+	    crtc->y = 0;
+	    output->crtc = crtc;
+	    /* XXX set position; for now, we clone */
+	}
+    }
+    
+    /* Mirror output modes to pScrn mode list */
+    xf86SetScrnInfoModes (pScrn);
+    
+    xfree (crtcs);
+    xfree (modes);
+    return TRUE;
+}
+
+/**
+ * Set the DPMS power mode of all outputs and CRTCs.
+ *
+ * If the new mode is off, it will turn off outputs and then CRTCs.
+ * Otherwise, it will affect CRTCs before outputs.
+ */
+void
+xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			i;
+
+    if (mode == DPMSModeOff) {
+	for (i = 0; i < config->num_output; i++) {
+	    xf86OutputPtr output = config->output[i];
+	    if (output->crtc != NULL)
+		(*output->funcs->dpms) (output, mode);
+	}
+    }
+
+    for (i = 0; i < config->num_crtc; i++) {
+	xf86CrtcPtr crtc = config->crtc[i];
+	if (crtc->enabled)
+	    (*crtc->funcs->dpms) (crtc, mode);
+    }
+
+    if (mode != DPMSModeOff) {
+	for (i = 0; i < config->num_output; i++) {
+	    xf86OutputPtr output = config->output[i];
+	    if (output->crtc != NULL)
+		(*output->funcs->dpms) (output, mode);
+	}
+    }
+}
diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h
index 36311d0..174647f 100644
--- a/src/radeon_xf86Crtc.h
+++ b/src/radeon_xf86Crtc.h
@@ -24,23 +24,24 @@
 
 #include <edid.h>
 #include "randrstr.h"
-//#include "xf86Modes.h"
-
-enum detect_status {
-   OUTPUT_STATUS_CONNECTED,
-   OUTPUT_STATUS_DISCONNECTED,
-   OUTPUT_STATUS_UNKNOWN
-};
+#include "radeon_xf86Modes.h"
 
 typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
+typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
+
+typedef enum _xf86OutputStatus {
+   XF86OutputStatusConnected,
+   XF86OutputStatusDisconnected,
+   XF86OutputStatusUnknown,
+} xf86OutputStatus;
 
 typedef struct _xf86CrtcFuncs {
    /**
     * Turns the crtc on/off, or sets intermediate power levels if available.
     *
     * Unsupported intermediate modes drop to the lower power setting.  If the
-    * mode is DPMSModeOff, the crtc must be disabled, as the DPLL may be
-    * disabled afterwards.
+    * mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
+    * be safe to call mode_set.
     */
    void
     (*dpms)(xf86CrtcPtr		crtc,
@@ -58,6 +59,27 @@ typedef struct _xf86CrtcFuncs {
    void
     (*restore)(xf86CrtcPtr	crtc);
 
+
+    /**
+     * Callback to adjust the mode to be set in the CRTC.
+     *
+     * This allows a CRTC to adjust the clock or even the entire set of
+     * timings, which is used for panels with fixed timings or for
+     * buses with clock limitations.
+     */
+    Bool
+    (*mode_fixup)(xf86CrtcPtr crtc,
+		  DisplayModePtr mode,
+		  DisplayModePtr adjusted_mode);
+
+    /**
+     * Callback for setting up a video mode after fixups have been made.
+     */
+    void
+    (*mode_set)(xf86CrtcPtr crtc,
+		DisplayModePtr mode,
+		DisplayModePtr adjusted_mode);
+
     /**
      * Clean up driver-specific bits of the crtc
      */
@@ -133,8 +155,6 @@ struct _xf86Crtc {
 #endif
 };
 
-typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
-
 typedef struct _xf86OutputFuncs {
     /**
      * Turns the output on/off, or sets intermediate power levels if available.
@@ -163,7 +183,7 @@ typedef struct _xf86OutputFuncs {
      * Callback for testing a video mode for a given output.
      *
      * This function should only check for cases where a mode can't be supported
-     * on the pipe specifically, and not represent generic CRTC limitations.
+     * on the output specifically, and not represent generic CRTC limitations.
      *
      * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
      */
@@ -172,27 +192,33 @@ typedef struct _xf86OutputFuncs {
 		  DisplayModePtr    pMode);
 
     /**
-     * Callback for setting up a video mode before any crtc/dpll changes.
+     * Callback to adjust the mode to be set in the CRTC.
      *
-     * \param pMode the mode that will be set, or NULL if the mode to be set is
-     * unknown (such as the restore path of VT switching).
+     * This allows an output to adjust the clock or even the entire set of
+     * timings, which is used for panels with fixed timings or for
+     * buses with clock limitations.
      */
-    void
-    (*pre_set_mode)(xf86OutputPtr   output,
-		    DisplayModePtr  pMode);
+    Bool
+    (*mode_fixup)(xf86OutputPtr output,
+		  DisplayModePtr mode,
+		  DisplayModePtr adjusted_mode);
 
     /**
-     * Callback for setting up a video mode after the DPLL update but before
-     * the plane is enabled.
+     * Callback for setting up a video mode after fixups have been made.
+     *
+     * This is only called while the output is disabled.  The dpms callback
+     * must be all that's necessary for the output, to turn the output on
+     * after this function is called.
      */
     void
-    (*post_set_mode)(xf86OutputPtr  output,
-		     DisplayModePtr pMode);
+    (*mode_set)(xf86OutputPtr  output,
+		DisplayModePtr mode,
+		DisplayModePtr adjusted_mode);
 
     /**
      * Probe for a connected output, and return detect_status.
      */
-    enum detect_status
+    xf86OutputStatus
     (*detect)(xf86OutputPtr	    output);
 
     /**
@@ -217,12 +243,23 @@ struct _xf86Output {
      * Associated ScrnInfo
      */
     ScrnInfoPtr		scrn;
+
     /**
      * Currently connected crtc (if any)
      *
      * If this output is not in use, this field will be NULL.
      */
     xf86CrtcPtr		crtc;
+
+    /**
+     * Possible CRTCs for this output as a mask of crtc indices
+     */
+    CARD32		possible_crtcs;
+
+    /**
+     * Possible outputs to share the same CRTC as a mask of output indices
+     */
+    CARD32		possible_clones;
     /**
      * List of available modes on this output.
      *
@@ -231,9 +268,20 @@ struct _xf86Output {
      */
     DisplayModePtr	probed_modes;
 
+    /**
+     * Current connection status
+     *
+     * This indicates whether a monitor is known to be connected
+     * to this output or not, or whether there is no way to tell
+     */
+    xf86OutputStatus	status;
+
     /** EDID monitor information */
     xf86MonPtr		MonInfo;
 
+    /** subpixel order */
+    int			subpixel_order;
+
     /** Physical size of the currently attached output device. */
     int			mm_width, mm_height;
 
@@ -259,18 +307,39 @@ struct _xf86Output {
 #endif
 };
 
-#define XF86_MAX_CRTC	4
-#define XF86_MAX_OUTPUT	16
-
 typedef struct _xf86CrtcConfig {
-   int			num_output;
-   xf86OutputPtr	output[XF86_MAX_OUTPUT];
-    
-   int			num_crtc;
-   xf86CrtcPtr		crtc[XF86_MAX_CRTC];
+    int			num_output;
+    xf86OutputPtr	*output;
+    /**
+     * compat_output is used whenever we deal
+     * with legacy code that only understands a single
+     * output. pScrn->modes will be loaded from this output,
+     * adjust frame will whack this output, etc.
+     */
+    int			compat_output;
+
+    int			num_crtc;
+    xf86CrtcPtr		*crtc;
+
+    int			minWidth, minHeight;
+    int			maxWidth, maxHeight;
 } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
 
-#define XF86_CRTC_CONFIG_PTR(p)	((xf86CrtcConfigPtr) ((p)->driverPrivate))
+extern int xf86CrtcConfigPrivateIndex;
+
+#define XF86_CRTC_CONFIG_PTR(p)	((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
+
+/*
+ * Initialize xf86CrtcConfig structure
+ */
+
+void
+xf86CrtcConfigInit (ScrnInfoPtr		scrn);
+
+void
+xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
+		      int minWidth, int minHeight,
+		      int maxWidth, int maxHeight);
 
 /*
  * Crtc functions
@@ -311,6 +380,21 @@ xf86OutputCreate (ScrnInfoPtr		scrn,
 		      const char	*name);
 
 void
+xf86OutputRename (xf86OutputPtr output, const char *name);
+
+void
 xf86OutputDestroy (xf86OutputPtr	output);
 
+void
+xf86ProbeOutputModes (ScrnInfoPtr pScrn);
+
+void
+xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
+
+Bool
+xf86InitialConfiguration (ScrnInfoPtr pScrn);
+
+void
+xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
+
 #endif /* _XF86CRTC_H_ */
diff-tree 29124400c7f193317d41d8cfd748371a239cfea1 (from 5d5fa1b86e5179b061f0db47fe0227d1b84c37f8)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 10 18:00:17 2006 +1100

    hook up randr crtc setting

diff --git a/src/radeon.h b/src/radeon.h
index e40905a..733b9c5 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -918,6 +918,9 @@ extern int RADEONValidateDDCModes(ScrnIn
 extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 
+extern Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
+			DisplayModePtr crtc2, int crtc_mask,
+			RADEONSavePtr save);
 
 #ifdef XF86DRI
 #ifdef USE_XAA
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 2521e31..f8db2ec 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2476,7 +2476,8 @@ Bool RADEONAllocateControllers(ScrnInfoP
         return FALSE;
 
     pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
-    
+    pRADEONEnt->Controller[0]->crtc_id = 0;
+
     if (!pRADEONEnt->HasCRTC2)
 	return TRUE;
 
@@ -2492,6 +2493,7 @@ Bool RADEONAllocateControllers(ScrnInfoP
     }
 
     pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
+    pRADEONEnt->Controller[1]->crtc_id = 1;
     return TRUE;
 }
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0724fe7..cf2af67 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6340,9 +6340,9 @@ static void RADEONInitPalette(RADEONSave
 #endif
 
 /* Define registers for a requested video mode */
-static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
-			DisplayModePtr crtc2, int crtc_mask,
-			RADEONSavePtr save)
+Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
+		 DisplayModePtr crtc2, int crtc_mask,
+		 RADEONSavePtr save)
 {
     RADEONInfoPtr  info      = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 6654afe..bd11106 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -601,21 +601,23 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
     DisplayModePtr ddc_modes, mode;
     DisplayModePtr test;
 
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-
-	test = pRADEONEnt->pOutput[i]->probed_modes;
+    for (i = 0; i < info->xf86_config.num_output; i++) {
+        xf86OutputPtr output = info->xf86_config.output[i];
+	
+	test = output->probed_modes;
 	while(test != NULL) {
 	  xf86DeleteMode(&test, test);
 	}
 
-	pRADEONEnt->pOutput[i]->probed_modes = test;
+	output->probed_modes = test;
+
 	/* force reprobe */
 	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
 	
 	RADEONConnectorFindMonitor(pScrn, i);
 	
 	/* okay we got DDC info */
-	if (pRADEONEnt->pOutput[i]->MonInfo) {
+	if (output->MonInfo) {
 	    /* Debug info for now, at least */
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
 	    xf86PrintEDID(pRADEONEnt->pOutput[i]->MonInfo);
@@ -634,7 +636,7 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 	}
 	   
 
-	if (pRADEONEnt->pOutput[i]->probed_modes == NULL) {
+	if (output->probed_modes == NULL) {
   	    MonRec fixed_mon;
 	    DisplayModePtr modes;
 
@@ -668,16 +670,15 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 	    }
 	}
 
-	if (pRADEONEnt->pOutput[i]->probed_modes) {
+	if (output->probed_modes) {
 	  RADEONxf86ValidateModesUserConfig(pScrn,
-					    pRADEONEnt->pOutput[i]->probed_modes);
-	  RADEONxf86PruneInvalidModes(pScrn, &pRADEONEnt->pOutput[i]->probed_modes,
+					    output->probed_modes);
+	  RADEONxf86PruneInvalidModes(pScrn, &output->probed_modes,
 				      FALSE);
 	}
 
 
-	for (mode = pRADEONEnt->pOutput[i]->probed_modes; mode != NULL;
-	     mode = mode->next)
+	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
 	{
 	    /* The code to choose the best mode per pipe later on will require
 	     * VRefresh to be set.
@@ -726,10 +727,11 @@ RADEON_set_xf86_modes_from_outputs(ScrnI
      * pScrn->modes should only be used for XF86VidMode now, which we don't
      * care about enough to make some sort of unioned list.
      */
-    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-	if (pRADEONEnt->pOutput[i]->probed_modes != NULL) {
+    for (i = 0; i < info->xf86_config.num_output; i++) {
+        xf86OutputPtr output = info->xf86_config.output[i];
+	if (output->probed_modes != NULL) {
 	    pScrn->modes =
-		RADEONxf86DuplicateModes(pScrn, pRADEONEnt->pOutput[i]->probed_modes);
+		RADEONxf86DuplicateModes(pScrn, output->probed_modes);
 	    break;
 	}
     }
@@ -750,12 +752,6 @@ RADEON_set_xf86_modes_from_outputs(ScrnI
 	FatalError("No modes left for XFree86 DDX\n");
     }
 
-    pScrn->currentMode = pScrn->modes;
-
-    xf86SetDpi(pScrn, 0, 0);
-    info->RADEONDPIVX = pScrn->virtualX;
-    info->RADEONDPIVY = pScrn->virtualY;
-
     /* For some reason, pScrn->modes is circular, unlike the other mode lists.
      * How great is that?
      */
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index fc09075..d3bd4c8 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -58,9 +58,6 @@ typedef struct _radeonRandRInfo {
     int				    maxY;
     Rotation			    rotation; /* current mode */
     Rotation                        supported_rotations; /* driver supported */
-#ifdef RANDR_12_INTERFACE
-    DisplayModePtr  		    modes[2];
-#endif
 } XF86RandRInfoRec, *XF86RandRInfoPtr;
 
 #ifdef RANDR_12_INTERFACE
@@ -117,49 +114,134 @@ RADEONRandRScreenSetSize (ScreenPtr	pScr
 }
 
 static Bool
-RADEONRandRCrtcNotify (RRCrtcPtr crtc)
+RADEONRandRCrtcNotify (RRCrtcPtr randr_crtc)
 {
-  ScreenPtr		pScreen = crtc->pScreen;
+  ScreenPtr		pScreen = randr_crtc->pScreen;
   XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
   ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
   RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-  RRModePtr		mode = NULL;
-  int i, j;
-  int numOutputs = 0;
+  RADEONInfoPtr info       = RADEONPTR(pScrn);
+  RRModePtr		randr_mode = NULL;
   int x, y;
-  int rotation = RR_Rotate_0;
-  RROutputPtr outputs[RADEON_MAX_CRTC];
-  RROutputPtr rrout;
-
-  for (i = 0; i<RADEON_MAX_CONNECTOR; i++) {
-    
-    rrout = pRADEONEnt->pOutput[i]->randr_output;
-
-    outputs[numOutputs++] = rrout;
-    for (j = 0; j<rrout->numModes; j++) {
-      DisplayModePtr outMode = rrout->modes[j]->devPrivate;
-      mode = rrout->modes[j];
+  Rotation rotation;
+  int numOutputs;
+  RROutputPtr randr_outputs[RADEON_MAX_CRTC];
+  RROutputPtr randr_output;
+  xf86CrtcPtr crtc = randr_crtc->devPrivate;
+  xf86OutputPtr output;
+  int i, j;
+  DisplayModePtr	curMode = &crtc->curMode;
+
+  x = crtc->x;
+  y = crtc->y;
+  rotation = RR_Rotate_0;
+  numOutputs = 0;
+  randr_mode = NULL;
+
+  for (i = 0; i < info->xf86_config.num_output; i++) {
+    output = info->xf86_config.output[i];
+    if (output->crtc == crtc) {
+      
+      randr_output = output->randr_output;
+      randr_outputs[numOutputs++] = randr_output;
+
+      for (j = 0; j < randr_output->numModes; j++) {
+	DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
+	if (xf86ModesEqual(curMode, outMode)) {
+	  randr_mode = randr_output->modes[j];
+	  break;
+	}
+      }
     }
   }
   
-  return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
+  return RRCrtcNotify (randr_crtc, randr_mode, x, y, rotation, numOutputs, randr_outputs);
 }
 
 static Bool
 RADEONRandRCrtcSet (ScreenPtr	pScreen,
-		  RRCrtcPtr	crtc,
-		  RRModePtr	mode,
+		  RRCrtcPtr	randr_crtc,
+		  RRModePtr	randr_mode,
 		  int		x,
 		  int		y,
 		  Rotation	rotation,
 		  int		num_randr_outputs,
 		  RROutputPtr	*randr_outputs)
 {
-  XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
   RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
- 
-  return RADEONRandRCrtcNotify(crtc);
+  RADEONInfoPtr info       = RADEONPTR(pScrn);
+  xf86CrtcPtr crtc = randr_crtc->devPrivate;
+  RADEONCrtcPrivatePtr pRcrtc = crtc->driver_private;
+  DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
+  Bool changed = FALSE;
+  int o, ro;
+  xf86CrtcPtr save_crtcs[RADEON_MAX_CONNECTOR];
+  Bool save_enabled = crtc->enabled;
+  int ret;
+
+  if ((mode != NULL) != crtc->enabled)
+    changed = TRUE;
+  else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
+    changed = TRUE;
+
+  for (o = 0; o < info->xf86_config.num_output; o++) {
+    xf86OutputPtr output = info->xf86_config.output[o];
+    xf86CrtcPtr new_crtc;
+
+    save_crtcs[o] = output->crtc;
+
+    if (output->crtc == crtc)
+      new_crtc = NULL;
+    else
+      new_crtc = output->crtc;
+
+    for (ro = 0; ro < num_randr_outputs; ro++)
+      if (output->randr_output == randr_outputs[ro]) {
+	new_crtc = crtc;
+	break;
+      }
+    if (new_crtc != output->crtc) {
+      changed = TRUE;
+      output->crtc = new_crtc;
+    }
+  }
+
+  /* got to set the modes in here */
+  if (changed) {
+    crtc->enabled = mode != NULL;
+
+    if (info->accelOn)
+      RADEON_SYNC(info, pScrn);
+
+    if (mode) {
+      if (pRcrtc->crtc_id == 0)
+	ret = RADEONInit2(pScrn, mode, NULL, 1, &info->ModeReg);
+      else if (pRcrtc->crtc_id == 1)
+	ret = RADEONInit2(pScrn, NULL, mode, 2, &info->ModeReg);
+      
+      if (!ret) {
+	crtc->enabled = save_enabled;
+	for (o = 0; o < info->xf86_config.num_output; o++) {
+	  xf86OutputPtr output = info->xf86_config.output[o];
+	  output->crtc = save_crtcs[o];
+	}
+	return FALSE;
+      }
+      crtc->desiredMode = *mode;
+    }
+  }
+
+  if (changed) {
+	pScrn->vtSema = TRUE;
+	RADEONBlank(pScrn);
+	RADEONRestoreMode(pScrn, &info->ModeReg);
+	RADEONUnblank(pScrn);
+	
+	if (info->DispPriority)
+		RADEONInitDispBandwidth(pScrn);
+  }
+  return RADEONRandRCrtcNotify(randr_crtc);
 }
 
 
diff-tree 5d5fa1b86e5179b061f0db47fe0227d1b84c37f8 (from 51d1cf19e71dd5de47f2c6467f4a1685eefd9e1e)
Author: Dave Airlie <airlied at linux.ie>
Date:   Mon Dec 4 18:53:33 2006 +1100

    update radeon driver to Intel driver xf86Crtc interfaces

diff --git a/src/Makefile.am b/src/Makefile.am
index 459a9ae..788e4a9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,7 +82,7 @@ radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
-	radeon_xf86Modes.c radeon_randr.c \
+	radeon_xf86Crtc.c radeon_xf86Modes.c radeon_randr.c \
 	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
@@ -193,6 +193,7 @@ EXTRA_DIST = \
 	radeon_version.h \
 	radeon_video.h \
 	radeon_xf86Modes.h \
+	radeon_xf86Crtc.h \
 	theatre200.h \
 	theatre_detect.h \
 	theatre.h \
diff --git a/src/radeon.h b/src/radeon.h
index f6a0227..e40905a 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -77,6 +77,8 @@
 #endif
 #endif
 
+#include "radeon_xf86Crtc.h"
+
 				/* Render support */
 #ifdef RENDER
 #include "picturestr.h"
@@ -405,6 +407,7 @@ typedef struct {
 }RADEONTMDSPll;
 
 typedef struct {
+    xf86CrtcConfigRec xf86_config;
     EntityInfoPtr     pEnt;
     pciVideoPtr       PciInfo;
     PCITAG            PciTag;
@@ -897,7 +900,7 @@ extern Bool        RADEONI2cInit(ScrnInf
 extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
 extern void        RADEONSetupConnectors(ScrnInfoPtr pScrn);
 extern Bool        RADEONMapControllers(ScrnInfoPtr pScrn);
-extern void        RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable);
+extern void        RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable);
 extern void        RADEONDisableDisplays(ScrnInfoPtr pScrn);
 extern void        RADEONGetPanelInfo(ScrnInfoPtr pScrn);
 extern void        RADEONGetTVDacAdjInfo(ScrnInfoPtr pScrn);
@@ -908,7 +911,7 @@ extern void        RADEONDisplayPowerMan
 						   int flags);
 extern Bool RADEONAllocateControllers(ScrnInfoPtr pScrn);
 extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
-extern RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num);
+extern xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num);
 extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 				  RADEONMonitorType DisplayType, int crtc2);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index a248428..2521e31 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -538,13 +538,14 @@ RADEONCrtIsPhysicallyConnected(ScrnInfoP
 }
 
 
-static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, RADEONConnector* port)
+static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, xf86OutputPtr port)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     unsigned long DDCReg;
     RADEONMonitorType MonType = MT_NONE;
     xf86MonPtr* MonInfo = &port->MonInfo;
+    RADEONOutputPrivatePtr pRPort = port->driver_private;
     int i, j;
 
     DDCReg = info->DDCReg;
@@ -639,7 +640,7 @@ static RADEONMonitorType RADEONDisplayDD
 	     * Also for laptop, when X starts with lid closed (no DVI connection)
 	     * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
 	     */
-	    if (port->TMDSType == TMDS_EXT) MonType = MT_DFP;
+	    if (pRPort->TMDSType == TMDS_EXT) MonType = MT_DFP;
 	    else {
 		if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility)
 		    MonType = MT_DFP;
@@ -850,7 +851,7 @@ static Bool RADEONGetLVDSInfo (ScrnInfoP
 		tmp_mode = tmp_mode->next;
 	    }
 	}
-	if ((info->DotClock == 0) && !pRADEONEnt->PortInfo[0]->MonInfo) {
+	if ((info->DotClock == 0) && !pRADEONEnt->pOutput[0]->MonInfo) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		       "Panel size is not correctly detected.\n"
 		       "Please try to use PanelSize option for correct settings.\n");
@@ -919,6 +920,20 @@ void RADEONGetTVDacAdjInfo(ScrnInfoPtr p
     }
 }
 
+static void RADEONSwapOutputs(ScrnInfoPtr pScrn)
+{
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    xf86OutputPtr connector;
+    RADEONOutputPrivatePtr conn_priv;
+    
+    connector = pRADEONEnt->pOutput[0];
+    pRADEONEnt->pOutput[0] = pRADEONEnt->pOutput[1];
+    pRADEONEnt->pOutput[1] = connector;
+    
+    conn_priv = pRADEONEnt->PortInfo[0];
+    pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
+    pRADEONEnt->PortInfo[1] = conn_priv;
+}
 /*
  * initialise the static data sos we don't have to re-do at randr change */
 void RADEONSetupConnectors(ScrnInfoPtr pScrn)
@@ -936,7 +951,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
      */
     for (i = 0; i < 2; i++) {
 	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[i]->MonInfo = NULL;
+	pRADEONEnt->pOutput[i]->MonInfo = NULL;
 	pRADEONEnt->PortInfo[i]->DDCType = DDC_NONE_DETECTED;
 	pRADEONEnt->PortInfo[i]->DACType = DAC_UNKNOWN;
 	pRADEONEnt->PortInfo[i]->TMDSType = TMDS_UNKNOWN;
@@ -952,14 +967,14 @@ void RADEONSetupConnectors(ScrnInfoPtr p
         (pRADEONEnt->PortInfo[1]->DDCType == 0))) {
 	/* Below is the most common setting, but may not be true */
 	pRADEONEnt->PortInfo[0]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[0]->MonInfo = NULL;
+	pRADEONEnt->pOutput[0]->MonInfo = NULL;
 	pRADEONEnt->PortInfo[0]->DDCType = DDC_DVI;
 	pRADEONEnt->PortInfo[0]->DACType = DAC_TVDAC;
 	pRADEONEnt->PortInfo[0]->TMDSType = TMDS_INT;
 	pRADEONEnt->PortInfo[0]->ConnectorType = CONNECTOR_DVI_I;
 
 	pRADEONEnt->PortInfo[1]->MonType = MT_UNKNOWN;
-	pRADEONEnt->PortInfo[1]->MonInfo = NULL;
+	pRADEONEnt->pOutput[1]->MonInfo = NULL;
 	pRADEONEnt->PortInfo[1]->DDCType = DDC_VGA;
 	pRADEONEnt->PortInfo[1]->DACType = DAC_PRIMARY;
 	pRADEONEnt->PortInfo[1]->TMDSType = TMDS_EXT;
@@ -977,10 +992,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 
     /* always make TMDS_INT port first*/
     if (pRADEONEnt->PortInfo[1]->TMDSType == TMDS_INT) {
-        RADEONConnector *connector;
-        connector = pRADEONEnt->PortInfo[0];
-        pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
-        pRADEONEnt->PortInfo[1] = connector;
+	RADEONSwapOutputs(pScrn);
     } else if ((pRADEONEnt->PortInfo[0]->TMDSType != TMDS_INT &&
                 pRADEONEnt->PortInfo[1]->TMDSType != TMDS_INT)) {
         /* no TMDS_INT port, make primary DAC port first */
@@ -989,10 +1001,7 @@ void RADEONSetupConnectors(ScrnInfoPtr p
 	   swap when the first port is not DAC_PRIMARY */
         if ((!(pRADEONEnt->PortInfo[0]->ConnectorType == CONNECTOR_PROPRIETARY)) &&  (pRADEONEnt->PortInfo[1]->DACType == DAC_PRIMARY) &&
 	     (pRADEONEnt->PortInfo[0]->DACType != DAC_PRIMARY)) {
-            RADEONConnector *connector;
-            connector = pRADEONEnt->PortInfo[0];
-            pRADEONEnt->PortInfo[0] = pRADEONEnt->PortInfo[1];
-            pRADEONEnt->PortInfo[1] = connector;
+	    RADEONSwapOutputs(pScrn);
         }
     }
 
@@ -1172,15 +1181,16 @@ void RADEONConnectorFindMonitor(ScrnInfo
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
-    RADEONConnector *pPort = pRADEONEnt->PortInfo[connector];
+    xf86OutputPtr pPort = pRADEONEnt->pOutput[connector];
+    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
     
-    if (pPort->MonType == MT_UNKNOWN) {
-      if ((pPort->MonType = RADEONDisplayDDCConnected(pScrn,
-						     pPort->DDCType,
+    if (pRPort->MonType == MT_UNKNOWN) {
+      if ((pRPort->MonType = RADEONDisplayDDCConnected(pScrn,
+						     pRPort->DDCType,
 						     pPort)));
-      else if((pPort->MonType = RADEONPortCheckNonDDC(pScrn, connector)));
+      else if((pRPort->MonType = RADEONPortCheckNonDDC(pScrn, connector)));
       else
-	pPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pPort->DACType));
+	pRPort->MonType = RADEONCrtIsPhysicallyConnected(pScrn, !(pRPort->DACType));
     }
 }
 
@@ -1210,11 +1220,11 @@ static void RADEONQueryConnectedDisplays
             if ((pRADEONEnt->PortInfo[0]->MonType > MT_NONE) &&
                 (pRADEONEnt->PortInfo[0]->MonType < MT_STV))
 		RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[0]->DDCType,
-					  pRADEONEnt->PortInfo[0]);
+					  pRADEONEnt->pOutput[0]);
             if ((pRADEONEnt->PortInfo[1]->MonType > MT_NONE) &&
                 (pRADEONEnt->PortInfo[1]->MonType < MT_STV))
 		RADEONDisplayDDCConnected(pScrn, pRADEONEnt->PortInfo[1]->DDCType,
-					  pRADEONEnt->PortInfo[1]);
+					  pRADEONEnt->pOutput[1]);
         }
     }
     else {
@@ -1228,24 +1238,24 @@ static void RADEONQueryConnectedDisplays
 	
         if ((!pRADEONEnt->HasCRTC2) && (pRADEONEnt->PortInfo[0]->MonType == MT_UNKNOWN)) {
 	    if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_DVI,
-									     pRADEONEnt->PortInfo[0])));
+									     pRADEONEnt->pOutput[0])));
 	    else if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_VGA,
-										  pRADEONEnt->PortInfo[0])));
+										  pRADEONEnt->pOutput[0])));
 	    else if((pRADEONEnt->PortInfo[0]->MonType = RADEONDisplayDDCConnected(pScrn, DDC_CRT2,
-										  pRADEONEnt->PortInfo[0])));
+										  pRADEONEnt->pOutput[0])));
 	    else
 		pRADEONEnt->PortInfo[0]->MonType = MT_CRT;
 	    
 	    if (!ignore_edid) {
-		if (pRADEONEnt->PortInfo[0]->MonInfo) {
+		if (pRADEONEnt->pOutput[0]->MonInfo) {
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Monitor1 EDID data ---------------------------\n");
-		    xf86PrintEDID(pRADEONEnt->PortInfo[0]->MonInfo );
+		    xf86PrintEDID(pRADEONEnt->pOutput[0]->MonInfo );
 		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of Monitor1 EDID data --------------------\n");
 		}
 	    }
 	    
 	    pRADEONEnt->PortInfo[1]->MonType = MT_NONE;
-	    pRADEONEnt->PortInfo[1]->MonInfo = NULL;
+	    pRADEONEnt->pOutput[1]->MonInfo = NULL;
 	    pRADEONEnt->PortInfo[1]->DDCType = DDC_NONE_DETECTED;
 	    pRADEONEnt->PortInfo[1]->DACType = DAC_UNKNOWN;
 	    pRADEONEnt->PortInfo[1]->TMDSType = TMDS_UNKNOWN;
@@ -1263,17 +1273,17 @@ static void RADEONQueryConnectedDisplays
     }
 
     if(ignore_edid) {
-        pRADEONEnt->PortInfo[0]->MonInfo = NULL;
-        pRADEONEnt->PortInfo[1]->MonInfo = NULL;
+        pRADEONEnt->pOutput[0]->MonInfo = NULL;
+        pRADEONEnt->pOutput[1]->MonInfo = NULL;
     } else {
-        if (pRADEONEnt->PortInfo[0]->MonInfo) {
+        if (pRADEONEnt->pOutput[0]->MonInfo) {
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 1st port ----------------------\n");
-            xf86PrintEDID( pRADEONEnt->PortInfo[0]->MonInfo );
+            xf86PrintEDID( pRADEONEnt->pOutput[0]->MonInfo );
         }
 
-        if (pRADEONEnt->PortInfo[1]->MonInfo) {
+        if (pRADEONEnt->pOutput[1]->MonInfo) {
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID data from the display on 2nd port -----------------------\n");
-            xf86PrintEDID( pRADEONEnt->PortInfo[1]->MonInfo );
+            xf86PrintEDID( pRADEONEnt->pOutput[1]->MonInfo );
         }
     }
     
@@ -1288,7 +1298,8 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     Bool head_reversed = FALSE;
-    RADEONConnector *connector;
+    xf86OutputPtr connector;
+    RADEONOutputPrivatePtr pRPort;
 
     info->MergeType = MT_NONE;
 
@@ -1368,45 +1379,51 @@ Bool RADEONMapControllers(ScrnInfoPtr pS
     if(pRADEONEnt->HasCRTC2) {
 	if(info->IsSecondary) {
 	    connector = RADEONGetCrtcConnector(pScrn, 2);
+	    pRPort = connector->driver_private;
   	    pRADEONEnt->Controller[1]->binding = 2;
 	    if (connector) {
-		info->DisplayType = connector->MonType;
+		info->DisplayType = pRPort->MonType;
 		pScrn->monitor->DDC = connector->MonInfo;
 	    }
 	} else {
 	    connector = RADEONGetCrtcConnector(pScrn, 1);
+	    pRPort = connector->driver_private;
   	    pRADEONEnt->Controller[0]->binding = 1;
 	    if (connector) {
-		info->DisplayType = connector->MonType; 
+		info->DisplayType = pRPort->MonType; 
 		pScrn->monitor->DDC = connector->MonInfo;
 	    }
 	}
 	
 	if(!pRADEONEnt->HasSecondary) {
 	    connector = RADEONGetCrtcConnector(pScrn, 2);
+	    pRPort = connector->driver_private;
 	    if (connector)
-		info->MergeType = connector->MonType;
+		info->MergeType = pRPort->MonType;
 	    if (info->MergeType)
   	    	pRADEONEnt->Controller[1]->binding = 1;
 	} 
     } else {
 	connector = RADEONGetCrtcConnector(pScrn, 1);
+	pRPort = connector->driver_private;
 	if (connector) {
-	    if (connector->MonType == MT_NONE) 
-		connector->MonType = MT_CRT;
-	    info->DisplayType = connector->MonType; 
+	    if (pRPort->MonType == MT_NONE) 
+		pRPort->MonType = MT_CRT;
+	    info->DisplayType = pRPort->MonType; 
 	    pScrn->monitor->DDC = connector->MonInfo;
 	}
 	connector = RADEONGetCrtcConnector(pScrn, 2);
+	pRPort = connector->driver_private;
 	if (connector)
-	    connector->MonType = MT_NONE;
+	    pRPort->MonType = MT_NONE;
 	pRADEONEnt->Controller[1]->binding = 1;
     }
 
     if (!info->IsSecondary) {
 	connector = RADEONGetCrtcConnector(pScrn, 2);
+	pRPort = connector->driver_private;
         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Primary Head:   Port%d ---- \n", head_reversed?2:1);
-	if (connector->MonType != MT_NONE)
+	if (pRPort->MonType != MT_NONE)
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Port%d ----\n", head_reversed?1:2);
  	else
             xf86DrvMsg(pScrn->scrnIndex, X_INFO, "---- Secondary Head: Not used ----\n");
@@ -1560,21 +1577,23 @@ void RADEONDisableDisplays(ScrnInfoPtr p
 }
 
 /* This is to be used enable/disable displays dynamically */
-void RADEONEnableDisplay(ScrnInfoPtr pScrn, RADEONConnector* pPort, BOOL bEnable)
+void RADEONEnableDisplay(ScrnInfoPtr pScrn, xf86OutputPtr pPort, BOOL bEnable)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONSavePtr save = &info->ModeReg;
     unsigned char * RADEONMMIO = info->MMIO;
     unsigned long tmp;
+    RADEONOutputPrivatePtr pRPort;
+    pRPort = pPort->driver_private;
 
     if (bEnable) {
-        if (pPort->MonType == MT_CRT) {
-            if (pPort->DACType == DAC_PRIMARY) {
+        if (pRPort->MonType == MT_CRT) {
+            if (pRPort->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
                 tmp |= RADEON_CRTC_CRT_ON;                    
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl |= RADEON_CRTC_CRT_ON;
-            } else if (pPort->DACType == DAC_TVDAC) {
+            } else if (pRPort->DACType == DAC_TVDAC) {
                 if (info->ChipFamily == CHIP_FAMILY_R200) {
                     tmp = INREG(RADEON_FP2_GEN_CNTL);
                     tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -1587,20 +1606,20 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
                     save->crtc2_gen_cntl |= RADEON_CRTC2_CRT2_ON;
                 }
             }
-	    RADEONDacPowerSet(pScrn, bEnable, (pPort->DACType == DAC_PRIMARY));
-        } else if (pPort->MonType == MT_DFP) {
-            if (pPort->TMDSType == TMDS_INT) {
+	    RADEONDacPowerSet(pScrn, bEnable, (pRPort->DACType == DAC_PRIMARY));
+        } else if (pRPort->MonType == MT_DFP) {
+            if (pRPort->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
                 tmp |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
                 OUTREG(RADEON_FP_GEN_CNTL, tmp);
                 save->fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-            } else if (pPort->TMDSType == TMDS_EXT) {
+            } else if (pRPort->TMDSType == TMDS_EXT) {
                 tmp = INREG(RADEON_FP2_GEN_CNTL);
                 tmp |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
                 OUTREG(RADEON_FP2_GEN_CNTL, tmp);
                 save->fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN);
             }
-        } else if (pPort->MonType == MT_LCD) {
+        } else if (pRPort->MonType == MT_LCD) {
             tmp = INREG(RADEON_LVDS_GEN_CNTL);
             tmp |= (RADEON_LVDS_ON | RADEON_LVDS_BLON);
             tmp &= ~(RADEON_LVDS_DISPLAY_DIS);
@@ -1610,13 +1629,13 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
             save->lvds_gen_cntl &= ~(RADEON_LVDS_DISPLAY_DIS);
         } 
     } else {
-        if (pPort->MonType == MT_CRT || pPort->MonType == NONE) {
-            if (pPort->DACType == DAC_PRIMARY) {
+        if (pRPort->MonType == MT_CRT || pRPort->MonType == NONE) {
+            if (pRPort->DACType == DAC_PRIMARY) {
                 tmp = INREG(RADEON_CRTC_EXT_CNTL);
                 tmp &= ~RADEON_CRTC_CRT_ON;                    
                 OUTREG(RADEON_CRTC_EXT_CNTL, tmp);
                 save->crtc_ext_cntl &= ~RADEON_CRTC_CRT_ON;
-            } else if (pPort->DACType == DAC_TVDAC) {
+            } else if (pRPort->DACType == DAC_TVDAC) {
                 if (info->ChipFamily == CHIP_FAMILY_R200) {
                     tmp = INREG(RADEON_FP2_GEN_CNTL);
                     tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
@@ -1629,16 +1648,16 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
                     save->crtc2_gen_cntl &= ~RADEON_CRTC2_CRT2_ON;
                 }
             }
-	    RADEONDacPowerSet(pScrn, bEnable, (pPort->DACType == DAC_PRIMARY));
+	    RADEONDacPowerSet(pScrn, bEnable, (pRPort->DACType == DAC_PRIMARY));
         }
 
-        if (pPort->MonType == MT_DFP || pPort->MonType == NONE) {
-            if (pPort->TMDSType == TMDS_INT) {
+        if (pRPort->MonType == MT_DFP || pRPort->MonType == NONE) {
+            if (pRPort->TMDSType == TMDS_INT) {
                 tmp = INREG(RADEON_FP_GEN_CNTL);
                 tmp &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
                 OUTREG(RADEON_FP_GEN_CNTL, tmp);
                 save->fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN);
-            } else if (pPort->TMDSType == TMDS_EXT) {
+            } else if (pRPort->TMDSType == TMDS_EXT) {
                 tmp = INREG(RADEON_FP2_GEN_CNTL);
                 tmp &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN);
                 OUTREG(RADEON_FP2_GEN_CNTL, tmp);
@@ -1646,8 +1665,8 @@ void RADEONEnableDisplay(ScrnInfoPtr pSc
             }
         }
 
-        if (pPort->MonType == MT_LCD || 
-            (pPort->MonType == NONE && pPort->ConnectorType == CONNECTOR_PROPRIETARY)) {
+        if (pRPort->MonType == MT_LCD || 
+            (pRPort->MonType == NONE && pRPort->ConnectorType == CONNECTOR_PROPRIETARY)) {
 	    unsigned long tmpPixclksCntl = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 	    if (info->IsMobility || info->IsIGP) {
 	    /* Asic bug, when turning off LVDS_ON, we have to make sure
@@ -2006,25 +2025,27 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
     RADEONInitDispBandwidth2(pScrn, info, info2, mode1, mode2);
 }
 
-static void RADEONBlankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+static void RADEONBlankSet(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr pRPort;
+    pRPort = pPort->driver_private;
 
-    switch(pPort->MonType) {
+    switch(pRPort->MonType) {
     case MT_LCD:
         OUTREGP(RADEON_LVDS_GEN_CNTL, RADEON_LVDS_DISPLAY_DIS, ~RADEON_LVDS_DISPLAY_DIS);
         break;
 
     case MT_CRT:
        if ((info->ChipFamily == CHIP_FAMILY_R200) && 
- 	  (pPort->DACType == DAC_TVDAC))
+ 	  (pRPort->DACType == DAC_TVDAC))
 	    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
       
         break;
     case MT_DFP:
-        if (pPort->TMDSType == TMDS_EXT)
+        if (pRPort->TMDSType == TMDS_EXT)
   	    OUTREGP(RADEON_FP2_GEN_CNTL, RADEON_FP2_BLANK_EN, ~RADEON_FP2_BLANK_EN);
         else
 	    OUTREGP(RADEON_FP_GEN_CNTL, RADEON_FP_BLANK_EN, ~RADEON_FP_BLANK_EN);
@@ -2042,7 +2063,7 @@ void RADEONBlank(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *pPort;
+    xf86OutputPtr pPort;
 
     if (!pRADEONEnt->HasSecondary ||
 	(pRADEONEnt->HasSecondary && !info->IsSwitching) ||
@@ -2089,23 +2110,24 @@ void RADEONBlank(ScrnInfoPtr pScrn)
     }
 }
 
-static void RADEONUnblankSet(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+static void RADEONUnblankSet(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
 
-    switch(pPort->MonType) {
+    switch(pRPort->MonType) {
     case MT_LCD:
         OUTREGP(RADEON_LVDS_GEN_CNTL, 0, ~RADEON_LVDS_DISPLAY_DIS);
         break;
     case MT_CRT:
         if ((info->ChipFamily == CHIP_FAMILY_R200) &&
-	  (pPort->DACType == DAC_TVDAC))
+	  (pRPort->DACType == DAC_TVDAC))
 	      OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
         break;
     case MT_DFP:
-        if (pPort->TMDSType == TMDS_EXT)
+        if (pRPort->TMDSType == TMDS_EXT)
 	    OUTREGP(RADEON_FP2_GEN_CNTL, 0, ~RADEON_FP2_BLANK_EN);
         else
 	    OUTREGP(RADEON_FP_GEN_CNTL, 0, ~RADEON_FP_BLANK_EN);
@@ -2122,7 +2144,7 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *pPort;
+    xf86OutputPtr pPort;
 
     if (!pRADEONEnt->HasSecondary || (info->IsSwitching  && !info->IsSecondary)) {
 	pPort = RADEONGetCrtcConnector(pScrn, 1);
@@ -2158,7 +2180,7 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     }
 }
 
-static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+static void RADEONDPMSSetOn(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
 {
   RADEONInfoPtr  info       = RADEONPTR(pScrn);
   RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
@@ -2166,10 +2188,11 @@ static void RADEONDPMSSetOn(ScrnInfoPtr 
   RADEONMonitorType MonType;
   RADEONTmdsType TmdsType;
   RADEONDacType DacType;
+  RADEONOutputPrivatePtr pRPort = pPort->driver_private;
 
-  MonType = pPort->MonType;
-  TmdsType = pPort->TMDSType;
-  DacType = pPort->DACType;
+  MonType = pRPort->MonType;
+  TmdsType = pRPort->TMDSType;
+  DacType = pRPort->DACType;
 
   switch(MonType) {
   case MT_LCD:
@@ -2196,7 +2219,7 @@ static void RADEONDPMSSetOn(ScrnInfoPtr 
   }
 }
 
-static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, RADEONConnector *pPort)
+static void RADEONDPMSSetOff(ScrnInfoPtr pScrn, xf86OutputPtr pPort)
 {
   RADEONInfoPtr  info       = RADEONPTR(pScrn);
   RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
@@ -2205,10 +2228,11 @@ static void RADEONDPMSSetOff(ScrnInfoPtr
   RADEONTmdsType TmdsType;
   RADEONDacType DacType;
   unsigned long tmpPixclksCntl;
+  RADEONOutputPrivatePtr pRPort = pPort->driver_private;
 
-  MonType = pPort->MonType;
-  TmdsType = pPort->TMDSType;
-  DacType = pPort->DACType;
+  MonType = pRPort->MonType;
+  TmdsType = pRPort->TMDSType;
+  DacType = pRPort->DACType;
 
   switch(MonType) {
   case MT_LCD:
@@ -2251,7 +2275,7 @@ void RADEONDisplayPowerManagementSet(Scr
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    RADEONConnector *pPort;
+    xf86OutputPtr pPort;
     if (!pScrn->vtSema) return;
 
     RADEONTRACE(("RADEONDisplayPowerManagementSet(%d,0x%x)\n", PowerManagementMode, flags));
@@ -2355,6 +2379,86 @@ void RADEONDisplayPowerManagementSet(Scr
 #endif
 }
 
+static const xf86CrtcFuncsRec radeon_crtc_funcs = {
+};
+
+static void
+radeon_dpms(xf86OutputPtr output, int mode)
+{
+    ScrnInfoPtr	    pScrn = output->scrn;
+    
+}
+
+static void
+radeon_save(xf86OutputPtr output)
+{
+
+}
+
+static void
+radeon_restore(xf86OutputPtr restore)
+{
+
+}
+
+static int
+radeon_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
+{
+    return MODE_OK;
+}
+
+static void
+radeon_pre_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
+{
+
+}
+
+static void
+radeon_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
+{
+}
+
+
+static enum detect_status
+radeon_detect(xf86OutputPtr output)
+{
+    ScrnInfoPtr	    pScrn = output->scrn;
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+#if 0
+    //    RADEONConnectorFindMonitor(pScrn, id);
+    if (pRADEONEnt->PortInfo[id].MonType == MT_UNKNOWN)
+	return OUTPUT_STATUS_UNKNOWN;
+    else if (pRADEONEnt->PortInfo[id].MonType == MT_NONE)
+	return OUTPUT_STATUS_DISCONNECTED;
+    else
+	return OUTPUT_STATUS_CONNECTED;
+#endif
+}
+
+static DisplayModePtr
+radeon_get_modes(xf86OutputPtr output)
+{
+    
+}
+
+static void
+radeon_destroy (xf86OutputPtr output)
+{
+}
+
+static const xf86OutputFuncsRec radeon_output_funcs = {
+    .dpms = radeon_dpms,
+    .save = radeon_save,
+    .restore = radeon_restore,
+    .mode_valid = radeon_mode_valid,
+    .pre_set_mode = radeon_pre_set_mode,
+    .post_set_mode = radeon_post_set_mode,
+    .detect = radeon_detect,
+    .get_modes = radeon_get_modes,
+    .destroy = radeon_destroy
+};
+
 Bool RADEONAllocateControllers(ScrnInfoPtr pScrn)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
@@ -2363,20 +2467,31 @@ Bool RADEONAllocateControllers(ScrnInfoP
     if (pRADEONEnt->Controller[0])
       return TRUE;
 
-    pRADEONEnt->Controller[0] = xcalloc(sizeof(RADEONController), 1);
+    pRADEONEnt->pCrtc[0] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+    if (!pRADEONEnt->pCrtc[0])
+      return FALSE;
+
+    pRADEONEnt->Controller[0] = xnfcalloc(sizeof(xf86CrtcRec), 1);
     if (!pRADEONEnt->Controller[0])
         return FALSE;
+
+    pRADEONEnt->pCrtc[0]->driver_private = pRADEONEnt->Controller[0];
     
     if (!pRADEONEnt->HasCRTC2)
 	return TRUE;
 
-    pRADEONEnt->Controller[1] = xcalloc(sizeof(RADEONController), 1);
+    pRADEONEnt->pCrtc[1] = xf86CrtcCreate(pScrn, &radeon_crtc_funcs);
+    if (!pRADEONEnt->pCrtc[1])
+      return FALSE;
+
+    pRADEONEnt->Controller[1] = xnfcalloc(sizeof(xf86CrtcRec), 1);
     if (!pRADEONEnt->Controller[1])
     {
 	xfree(pRADEONEnt->Controller[0]);
 	return FALSE;
     }
 
+    pRADEONEnt->pCrtc[1]->driver_private = pRADEONEnt->Controller[1];
     return TRUE;
 }
 
@@ -2391,21 +2506,31 @@ Bool RADEONAllocateConnectors(ScrnInfoPt
     
     /* for now always allocate max connectors */
     for (i = 0 ; i < RADEON_MAX_CONNECTOR; i++) {
-      pRADEONEnt->PortInfo[i] = xcalloc(sizeof(RADEONConnector), 1);
+
+      pRADEONEnt->pOutput[i] = xf86OutputCreate(pScrn, &radeon_output_funcs, "VGA");
+      if (!pRADEONEnt->pOutput[i])
+	return FALSE;
+
+      pRADEONEnt->PortInfo[i] = xnfcalloc(sizeof(RADEONOutputPrivateRec), 1);
       if (!pRADEONEnt->PortInfo[i])
 	return FALSE;
+
+      pRADEONEnt->PortInfo[i]->type = OUTPUT_VGA;
+      pRADEONEnt->pOutput[i]->driver_private = pRADEONEnt->PortInfo[i];
     }
 
     return TRUE;
 }
 
-RADEONConnector *RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
+
+
+xf86OutputPtr RADEONGetCrtcConnector(ScrnInfoPtr pScrn, int crtc_num)
 {
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
 
     if (pRADEONEnt->PortInfo[0]->crtc_num == crtc_num)
-      return pRADEONEnt->PortInfo[0];
+      return pRADEONEnt->pOutput[0];
     else if (pRADEONEnt->PortInfo[1]->crtc_num == crtc_num)
-      return pRADEONEnt->PortInfo[1];
+      return pRADEONEnt->pOutput[1];
     return NULL;
 }
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ccd0e1b..0724fe7 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -1996,7 +1996,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
     int            modesFound;
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     char           *s;
-    RADEONConnector *connector;
+    xf86OutputPtr connector;
     /* This option has two purposes:
      *
      * 1. For CRT, if this option is on, xf86ValidateModes (to
@@ -2037,9 +2037,11 @@ static Bool RADEONPreInitModes(ScrnInfoP
 
     /* don't use RMX if we have a dual-tmds panels */
     
-    if ((connector = RADEONGetCrtcConnector(pScrn, 2)))
-	if (connector->MonType == MT_DFP)
+    if ((connector = RADEONGetCrtcConnector(pScrn, 2))) {
+	RADEONOutputPrivatePtr radconnector = connector->driver_private;
+	if (radconnector->MonType == MT_DFP)
 	    info->ddc_mode = TRUE;
+    }
     /* don't use RMX if we are Dell Server */  
     if (info->IsDellServer)
     {
@@ -2049,7 +2051,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 	       "Validating modes on %s head ---------\n",
 	       info->IsSecondary ? "Secondary" : "Primary");
 
-    if (!pRADEONEnt->PortInfo[0]->MonInfo && !pRADEONEnt->PortInfo[1]->MonInfo && info->ddc_mode) {
+    if (!pRADEONEnt->pOutput[0]->MonInfo && !pRADEONEnt->pOutput[1]->MonInfo && info->ddc_mode) {
 	info->ddc_mode = FALSE;
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "No DDC data available, DDCMode option is dismissed\n");
@@ -5103,9 +5105,9 @@ static void RADEONRestoreMode(ScrnInfoPt
 {
     RADEONInfoPtr      info = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
-    RADEONController* pCRTC1 = pRADEONEnt->Controller[0];
-    RADEONController* pCRTC2 = pRADEONEnt->Controller[1];
-    RADEONConnector *pPort;
+    RADEONCrtcPrivatePtr pCRTC1 = pRADEONEnt->Controller[0];
+    RADEONCrtcPrivatePtr pCRTC2 = pRADEONEnt->Controller[1];
+    xf86OutputPtr pPort;
     RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
 
     /* For Non-dual head card, we don't have private field in the Entity */
@@ -5840,24 +5842,24 @@ static void RADEONInitDAC2Registers(Scrn
     }
 }
 
-static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, RADEONConnector *pPort, int crtc_num)
+static void RADEONInitOutputRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save, DisplayModePtr mode, xf86OutputPtr pPort, int crtc_num)
 {
     Bool IsPrimary = crtc_num == 1 ? TRUE : FALSE;
-
-    if (pPort->MonType == MT_CRT) {
-	if (pPort->DACType == DAC_PRIMARY) {
+    RADEONOutputPrivatePtr pRPort = pPort->driver_private;
+    if (pRPort->MonType == MT_CRT) {
+	if (pRPort->DACType == DAC_PRIMARY) {
 	    RADEONInitDACRegisters(pScrn, save, mode, IsPrimary);
 	} else {
 	    RADEONInitDAC2Registers(pScrn, save, mode, IsPrimary);
 	}
-    } else if (pPort->MonType == MT_LCD) {
+    } else if (pRPort->MonType == MT_LCD) {
 	if (crtc_num == 1)
 	    RADEONInitRMXRegisters(pScrn, save, mode);
 	RADEONInitLVDSRegisters(pScrn, save, mode, IsPrimary);
-    } else if (pPort->MonType == MT_DFP) {
+    } else if (pRPort->MonType == MT_DFP) {
 	if (crtc_num == 1)
 	    RADEONInitRMXRegisters(pScrn, save, mode);
-	if (pPort->TMDSType == TMDS_INT) {
+	if (pRPort->TMDSType == TMDS_INT) {
 	    RADEONInitFPRegisters(pScrn, save, mode, IsPrimary);
 	} else {
 	    RADEONInitFP2Registers(pScrn, save, mode, IsPrimary);
@@ -5874,11 +5876,11 @@ static Bool RADEONInitCrtcRegisters(Scrn
     int    hsync_wid;
     int    vsync_wid;
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *connector;
+    xf86OutputPtr connector;
 
     pRADEONEnt->Controller[0]->IsUsed = TRUE;
     pRADEONEnt->Controller[0]->IsActive = TRUE;
-    pRADEONEnt->Controller[0]->pCurMode = mode;
+    pRADEONEnt->pCrtc[0]->curMode = *mode;
 
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
@@ -6025,9 +6027,9 @@ static Bool RADEONInitCrtcRegisters(Scrn
 
     /* get the output connected to this CRTC */
     if (pRADEONEnt->PortInfo[0]->crtc_num == 1) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 1);
+	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 1);
     } else if (pRADEONEnt->PortInfo[1]->crtc_num == 1) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 1);
+	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 1);
     }
 
     if (info->IsDellServer) {
@@ -6066,7 +6068,7 @@ static Bool RADEONInitCrtc2Registers(Scr
 
     pRADEONEnt->Controller[1]->IsUsed = TRUE;
     pRADEONEnt->Controller[1]->IsActive = TRUE;
-    pRADEONEnt->Controller[1]->pCurMode = mode;
+    pRADEONEnt->pCrtc[1]->curMode = *mode;
 
     switch (info->CurrentLayout.pixel_code) {
     case 4:  format = 1; break;
@@ -6160,9 +6162,9 @@ static Bool RADEONInitCrtc2Registers(Scr
 
     /* get the output connected to this CRTC */
     if (pRADEONEnt->PortInfo[0]->crtc_num == 2) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[0], 2);
+	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[0], 2);
     } else if (pRADEONEnt->PortInfo[1]->crtc_num == 2) {
-	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->PortInfo[1], 2);
+	RADEONInitOutputRegisters(pScrn, save, mode, pRADEONEnt->pOutput[1], 2);
     }
 
     /* We must set SURFACE_CNTL properly on the second screen too */
@@ -7043,7 +7045,7 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 {
     RADEONInfoPtr      info       = RADEONPTR(pScrn);
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
-    RADEONConnector *connector;
+    xf86OutputPtr pOutput;
     char        *strptr;
     char	*default_hsync = "28-33";
     char	*default_vrefresh = "43-72";
@@ -7081,8 +7083,8 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 	info->MergedFB = FALSE;
         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
         "Failed to detect secondary monitor, MergedFB/Clone mode disabled\n");
-    } else if ((connector = RADEONGetCrtcConnector(pScrn, 2))) {
-	if (!connector->MonInfo) {
+    } else if ((pOutput = RADEONGetCrtcConnector(pScrn, 2))) {
+	if (!pOutput->MonInfo) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
 		       "Failed to detect secondary monitor DDC, default HSync and VRefresh used\n");
 	    default_range = TRUE;
@@ -7249,8 +7251,8 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 	  }
 
 	  /* xf86SetDDCproperties(info->CRT2pScrn, pRADEONEnt->MonInfo2); */
-	  if (connector = RADEONGetCrtcConnector(pScrn, 2))
-	      info->CRT2pScrn->monitor->DDC = connector->MonInfo;
+	  if (pOutput = RADEONGetCrtcConnector(pScrn, 2))
+	      info->CRT2pScrn->monitor->DDC = pOutput->MonInfo;
 	  else
 	      info->CRT2pScrn->monitor->DDC = NULL;
           if (default_range) {
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index c70f5e0..6654afe 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -603,24 +603,24 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 
     for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
 
-	test = pRADEONEnt->PortInfo[i]->probed_modes;
+	test = pRADEONEnt->pOutput[i]->probed_modes;
 	while(test != NULL) {
 	  xf86DeleteMode(&test, test);
 	}
 
-	pRADEONEnt->PortInfo[i]->probed_modes = test;
+	pRADEONEnt->pOutput[i]->probed_modes = test;
 	/* force reprobe */
 	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
 	
 	RADEONConnectorFindMonitor(pScrn, i);
 	
 	/* okay we got DDC info */
-	if (pRADEONEnt->PortInfo[i]->MonInfo) {
+	if (pRADEONEnt->pOutput[i]->MonInfo) {
 	    /* Debug info for now, at least */
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
-	    xf86PrintEDID(pRADEONEnt->PortInfo[i]->MonInfo);
+	    xf86PrintEDID(pRADEONEnt->pOutput[i]->MonInfo);
 
-	    ddc_modes = RADEONGetDDCModes(pScrn, pRADEONEnt->PortInfo[i]->MonInfo);
+	    ddc_modes = RADEONGetDDCModes(pScrn, pRADEONEnt->pOutput[i]->MonInfo);
 	    
 	    for (mode = ddc_modes; mode != NULL; mode = mode->next) {
 		if (mode->Flags & V_DBLSCAN) {
@@ -634,7 +634,7 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 	}
 	   
 
-	if (pRADEONEnt->PortInfo[i]->probed_modes == NULL) {
+	if (pRADEONEnt->pOutput[i]->probed_modes == NULL) {
   	    MonRec fixed_mon;
 	    DisplayModePtr modes;
 
@@ -657,26 +657,26 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 	      RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
 	      RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
 	      /* fill out CRT of FP mode table */
-	      pRADEONEnt->PortInfo[i]->probed_modes = modes;
+	      pRADEONEnt->pOutput[i]->probed_modes = modes;
 	      break;
 		
 	    case MT_LCD:
-	      RADEONValidateFPModes(pScrn, pScrn->display->modes, &pRADEONEnt->PortInfo[i]->probed_modes);
+	      RADEONValidateFPModes(pScrn, pScrn->display->modes, &pRADEONEnt->pOutput[i]->probed_modes);
 	      break;
 	    default:
 		break;
 	    }
 	}
 
-	if (pRADEONEnt->PortInfo[i]->probed_modes) {
+	if (pRADEONEnt->pOutput[i]->probed_modes) {
 	  RADEONxf86ValidateModesUserConfig(pScrn,
-					    pRADEONEnt->PortInfo[i]->probed_modes);
-	  RADEONxf86PruneInvalidModes(pScrn, &pRADEONEnt->PortInfo[i]->probed_modes,
+					    pRADEONEnt->pOutput[i]->probed_modes);
+	  RADEONxf86PruneInvalidModes(pScrn, &pRADEONEnt->pOutput[i]->probed_modes,
 				      FALSE);
 	}
 
 
-	for (mode = pRADEONEnt->PortInfo[i]->probed_modes; mode != NULL;
+	for (mode = pRADEONEnt->pOutput[i]->probed_modes; mode != NULL;
 	     mode = mode->next)
 	{
 	    /* The code to choose the best mode per pipe later on will require
@@ -727,9 +727,9 @@ RADEON_set_xf86_modes_from_outputs(ScrnI
      * care about enough to make some sort of unioned list.
      */
     for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
-	if (pRADEONEnt->PortInfo[i]->probed_modes != NULL) {
+	if (pRADEONEnt->pOutput[i]->probed_modes != NULL) {
 	    pScrn->modes =
-		RADEONxf86DuplicateModes(pScrn, pRADEONEnt->PortInfo[i]->probed_modes);
+		RADEONxf86DuplicateModes(pScrn, pRADEONEnt->pOutput[i]->probed_modes);
 	    break;
 	}
     }
@@ -789,7 +789,7 @@ RADEON_set_default_screen_size(ScrnInfoP
     for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
 	DisplayModePtr mode;
 
-	for (mode = pRADEONEnt->PortInfo[i]->probed_modes; mode != NULL;
+	for (mode = pRADEONEnt->pOutput[i]->probed_modes; mode != NULL;
 	     mode = mode->next)
 	{
 	    if (mode->HDisplay > maxX)
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index ebd4bab..a717504 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -43,8 +43,7 @@
 #define _XF86MISC_SERVER_
 #include <X11/extensions/xf86misc.h>
 
-#define RADEON_MAX_CRTC 2
-#define RADEON_MAX_CONNECTOR 2
+#include "radeon_xf86Crtc.h"
 
 typedef enum
 {
@@ -106,38 +105,34 @@ typedef enum
     TMDS_EXT     = 1
 } RADEONTmdsType;
 
-typedef struct
+typedef enum
 {
-    Bool IsUsed;
+    OUTPUT_NONE,
+    OUTPUT_VGA,
+    OUTPUT_DVI,
+    OUTPUT_LVDS,
+    OUTPUT_STV,
+    OUTPUT_CTX,
+} RADEONOutputType;
+
+typedef struct _RADEONCrtcPrivateRec {
+    int crtc;
+    int crtc_id;
+    int binding;
     Bool IsActive;
-    int binding; // which instance of the driver "owns" this controller
-    DisplayModePtr pCurMode;
-
-#ifdef RANDR_12_INTERFACE
-    RRCrtcPtr randr_crtc;
-#endif
-} RADEONController;
+    Bool IsUsed;
+} RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
-typedef struct
-{
+typedef struct _RADEONOutputPrivateRec {
+    RADEONOutputType type;
+    void *dev_priv;
     RADEONDDCType DDCType;
     RADEONDacType DACType;
     RADEONTmdsType TMDSType;
     RADEONConnectorType ConnectorType;
     RADEONMonitorType MonType;
-    xf86MonPtr MonInfo;
-
-    /* one connector can be bound to one CRTC */
     int crtc_num;
-
-    /* a list of probed modes on this connector */
-    DisplayModePtr probed_modes;
-#ifdef RANDR_12_INTERFACE
-    RROutputPtr randr_output;
-#endif
-} RADEONConnector;
-
-
+} RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
 
 #define RADEON_MAX_CONNECTOR 2
 #define RADEON_MAX_CRTC 2
@@ -158,8 +153,12 @@ typedef struct
 
     Bool ReversedDAC;	  /* TVDAC used as primary dac */
     Bool ReversedTMDS;    /* DDC_DVI is used for external TMDS */
-    RADEONConnector *PortInfo[RADEON_MAX_CONNECTOR];
-    RADEONController *Controller[RADEON_MAX_CRTC]; /* pointer to a controller */
+    xf86OutputPtr pOutput[RADEON_MAX_CONNECTOR];
+    RADEONOutputPrivatePtr PortInfo[RADEON_MAX_CONNECTOR];
+
+    xf86CrtcPtr pCrtc[RADEON_MAX_CRTC];
+    RADEONCrtcPrivatePtr Controller[RADEON_MAX_CRTC];
+
 } RADEONEntRec, *RADEONEntPtr;
 
 /* radeon_probe.c */
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
index 2fc012a..fc09075 100644
--- a/src/radeon_randr.c
+++ b/src/radeon_randr.c
@@ -133,7 +133,7 @@ RADEONRandRCrtcNotify (RRCrtcPtr crtc)
 
   for (i = 0; i<RADEON_MAX_CONNECTOR; i++) {
     
-    rrout = pRADEONEnt->PortInfo[i]->randr_output;
+    rrout = pRADEONEnt->pOutput[i]->randr_output;
 
     outputs[numOutputs++] = rrout;
     for (j = 0; j<rrout->numModes; j++) {
@@ -252,16 +252,18 @@ RADEONRandRSetInfo12 (ScrnInfoPtr pScrn)
     int			connection;
     int                 subpixel = SubPixelNone;
     RRCrtcPtr		    randr_crtc;
-    RADEONConnector *connector;
+    xf86OutputPtr connector;
+    RADEONOutputPrivatePtr pRPort;
 
     for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
       ncrtc = 0;
       crtc = NULL;
       
-      connector = pRADEONEnt->PortInfo[i];
+      connector = pRADEONEnt->pOutput[i];
+      pRPort = pRADEONEnt->PortInfo[i];
 
-      if (connector->MonType) {
-	crtc = pRADEONEnt->Controller[i]->randr_crtc;
+      if (pRPort->MonType) {
+	crtc = pRADEONEnt->pCrtc[i]->randr_crtc;
 	crtcs[ncrtc++] = crtc;
 	randr_crtc = crtc;
       } else
@@ -282,7 +284,7 @@ RADEONRandRSetInfo12 (ScrnInfoPtr pScrn)
       }
 
       connection = RR_Disconnected;
-      if (connector->MonType > MT_NONE)
+      if (pRPort->MonType > MT_NONE)
 	connection = RR_Connected;
 
       RROutputSetConnection(connector->randr_output, connection);
@@ -338,7 +340,7 @@ RADEONRandRCreateObjects12(ScrnInfoPtr p
       return FALSE;
 
     RRCrtcGammaSetSize(randr_crtc, 256);
-    pRADEONEnt->Controller[i]->randr_crtc = randr_crtc;
+    pRADEONEnt->pCrtc[i]->randr_crtc = randr_crtc;
   }
 
   for (i = 0; i < 2; i++)
@@ -351,7 +353,7 @@ RADEONRandRCreateObjects12(ScrnInfoPtr p
     if (!randr_output)
       return FALSE;
 
-    pRADEONEnt->PortInfo[i]->randr_output = randr_output;
+    pRADEONEnt->pOutput[i]->randr_output = randr_output;
   }
   return TRUE;
 }
@@ -369,12 +371,12 @@ RADEONRandRCreateScreenResources12 (Scre
 
   for (i = 0; i < 2; i++)
   {
-    if (!RRCrtcAttachScreen(pRADEONEnt->Controller[i]->randr_crtc, pScreen))
+    if (!RRCrtcAttachScreen(pRADEONEnt->pCrtc[i]->randr_crtc, pScreen))
       return FALSE;
   }
   
   for (i = 0; i < 2; i++) {
-    if (!RROutputAttachScreen(pRADEONEnt->PortInfo[i]->randr_output, pScreen))
+    if (!RROutputAttachScreen(pRADEONEnt->pOutput[i]->randr_output, pScreen))
       return FALSE;
   }
 
@@ -400,7 +402,7 @@ RADEONRandRCreateScreenResources12 (Scre
   }
 
   for (i = 0; i < RADEON_MAX_CRTC; i++)
-    RADEONRandRCrtcNotify (pRADEONEnt->Controller[i]->randr_crtc);
+    RADEONRandRCrtcNotify (pRADEONEnt->pCrtc[i]->randr_crtc);
     
   if (randrp->virtualX == -1 || randrp->virtualY == -1)
   {
@@ -770,9 +772,9 @@ RADEONRandRPreInit(ScrnInfoPtr pScrn)
    * the initial configuration
    */
   for (o = 0; o < RADEON_MAX_CONNECTOR; o++)
-    outputs[o] = pRADEONEnt->PortInfo[o]->randr_output;
+    outputs[o] = pRADEONEnt->pOutput[o]->randr_output;
   for (c = 0; c < RADEON_MAX_CRTC; c++)
-    crtcs[c] = pRADEONEnt->Controller[c]->randr_crtc;
+    crtcs[c] = pRADEONEnt->pCrtc[c]->randr_crtc;
   
   if (!RADEONRRInitialConfiguration (outputs, output_crtcs, output_modes,
 				     RADEON_MAX_CONNECTOR))
diff --git a/src/radeon_xf86Crtc.c b/src/radeon_xf86Crtc.c
new file mode 100644
index 0000000..41d6f86
--- /dev/null
+++ b/src/radeon_xf86Crtc.c
@@ -0,0 +1,140 @@
+/*
+ * $Id: $
+ *
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "radeon_xf86Crtc.h"
+
+/*
+ * Crtc functions
+ */
+xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr		scrn,
+		const xf86CrtcFuncsRec	*funcs)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CrtcPtr		crtc;
+
+    crtc = xcalloc (sizeof (xf86CrtcRec), 1);
+    if (!crtc)
+	return NULL;
+    crtc->scrn = scrn;
+    crtc->funcs = funcs;
+#ifdef RANDR_12_INTERFACE
+    crtc->randr_crtc = RRCrtcCreate (crtc);
+    if (!crtc->randr_crtc)
+    {
+	xfree (crtc);
+	return NULL;
+    }
+#endif
+    xf86_config->crtc[xf86_config->num_crtc++] = crtc;
+    return crtc;
+}
+
+void
+xf86CrtcDestroy (xf86CrtcPtr crtc)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+    int			c;
+    
+    (*crtc->funcs->destroy) (crtc);
+#ifdef RANDR_12_INTERFACE
+    RRCrtcDestroy (crtc->randr_crtc);
+#endif
+    for (c = 0; c < xf86_config->num_crtc; c++)
+	if (xf86_config->crtc[c] == crtc)
+	{
+	    memmove (&xf86_config->crtc[c],
+		     &xf86_config->crtc[c+1],
+		     xf86_config->num_crtc - (c + 1));
+	    xf86_config->num_crtc--;
+	    break;
+	}
+    xfree (crtc);
+}
+
+/*
+ * Output functions
+ */
+xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr		    scrn,
+		  const xf86OutputFuncsRec *funcs,
+		  const char		    *name)
+{
+    xf86OutputPtr	output;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			len = strlen (name);
+
+    output = xcalloc (sizeof (xf86OutputRec) + len + 1, 1);
+    if (!output)
+	return NULL;
+    output->scrn = scrn;
+    output->funcs = funcs;
+    output->name = (char *) (output + 1);
+    strcpy (output->name, name);
+#ifdef RANDR_12_INTERFACE
+    output->randr_output = RROutputCreate (name, strlen (name), output);
+    if (!output->randr_output)
+    {
+	xfree (output);
+	return NULL;
+    }
+#endif
+    xf86_config->output[xf86_config->num_output++] = output;
+    return output;
+}
+
+void
+xf86OutputDestroy (xf86OutputPtr output)
+{
+    ScrnInfoPtr		scrn = output->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+    
+    (*output->funcs->destroy) (output);
+#ifdef RANDR_12_INTERFACE
+    RROutputDestroy (output->randr_output);
+#endif
+    while (output->probed_modes)
+	xf86DeleteMode (&output->probed_modes, output->probed_modes);
+    for (o = 0; o < xf86_config->num_output; o++)
+	if (xf86_config->output[o] == output)
+	{
+	    memmove (&xf86_config->output[o],
+		     &xf86_config->output[o+1],
+		     xf86_config->num_output - (o + 1));
+	    xf86_config->num_output--;
+	    break;
+	}
+    xfree (output);
+}
+
diff --git a/src/radeon_xf86Crtc.h b/src/radeon_xf86Crtc.h
new file mode 100644
index 0000000..36311d0
--- /dev/null
+++ b/src/radeon_xf86Crtc.h
@@ -0,0 +1,316 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#ifndef _XF86CRTC_H_
+#define _XF86CRTC_H_
+
+#include <edid.h>
+#include "randrstr.h"
+//#include "xf86Modes.h"
+
+enum detect_status {
+   OUTPUT_STATUS_CONNECTED,
+   OUTPUT_STATUS_DISCONNECTED,
+   OUTPUT_STATUS_UNKNOWN
+};
+
+typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
+
+typedef struct _xf86CrtcFuncs {
+   /**
+    * Turns the crtc on/off, or sets intermediate power levels if available.
+    *
+    * Unsupported intermediate modes drop to the lower power setting.  If the
+    * mode is DPMSModeOff, the crtc must be disabled, as the DPLL may be
+    * disabled afterwards.
+    */
+   void
+    (*dpms)(xf86CrtcPtr		crtc,
+	    int		    	mode);
+
+   /**
+    * Saves the crtc's state for restoration on VT switch.
+    */
+   void
+    (*save)(xf86CrtcPtr		crtc);
+
+   /**
+    * Restore's the crtc's state at VT switch.
+    */
+   void
+    (*restore)(xf86CrtcPtr	crtc);
+
+    /**
+     * Clean up driver-specific bits of the crtc
+     */
+    void
+    (*destroy) (xf86CrtcPtr	crtc);
+} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
+
+struct _xf86Crtc {
+    /**
+     * Associated ScrnInfo
+     */
+    ScrnInfoPtr	    scrn;
+    
+    /**
+     * Active state of this CRTC
+     *
+     * Set when this CRTC is driving one or more outputs 
+     */
+    Bool	    enabled;
+    
+    /**
+     * Position on screen
+     *
+     * Locates this CRTC within the frame buffer
+     */
+    int		    x, y;
+    
+    /** Track whether cursor is within CRTC range  */
+    Bool	    cursorInRange;
+    
+    /** Track state of cursor associated with this CRTC */
+    Bool	    cursorShown;
+    
+    /**
+     * Active mode
+     *
+     * This reflects the mode as set in the CRTC currently
+     * It will be cleared when the VT is not active or
+     * during server startup
+     */
+    DisplayModeRec  curMode;
+    
+    /**
+     * Desired mode
+     *
+     * This is set to the requested mode, independent of
+     * whether the VT is active. In particular, it receives
+     * the startup configured mode and saves the active mode
+     * on VT switch.
+     */
+    DisplayModeRec  desiredMode;
+    
+    /** crtc-specific functions */
+    const xf86CrtcFuncsRec *funcs;
+
+    /**
+     * Driver private
+     *
+     * Holds driver-private information
+     */
+    void	    *driver_private;
+
+#ifdef RANDR_12_INTERFACE
+    /**
+     * RandR crtc
+     *
+     * When RandR 1.2 is available, this
+     * points at the associated crtc object
+     */
+    RRCrtcPtr	    randr_crtc;
+#else
+    void	    *randr_crtc;
+#endif
+};
+
+typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
+
+typedef struct _xf86OutputFuncs {
+    /**
+     * Turns the output on/off, or sets intermediate power levels if available.
+     *
+     * Unsupported intermediate modes drop to the lower power setting.  If the
+     * mode is DPMSModeOff, the output must be disabled, as the DPLL may be
+     * disabled afterwards.
+     */
+    void
+    (*dpms)(xf86OutputPtr	output,
+	    int			mode);
+
+    /**
+     * Saves the output's state for restoration on VT switch.
+     */
+    void
+    (*save)(xf86OutputPtr	output);
+
+    /**
+     * Restore's the output's state at VT switch.
+     */
+    void
+    (*restore)(xf86OutputPtr	output);
+
+    /**
+     * Callback for testing a video mode for a given output.
+     *
+     * This function should only check for cases where a mode can't be supported
+     * on the pipe specifically, and not represent generic CRTC limitations.
+     *
+     * \return MODE_OK if the mode is valid, or another MODE_* otherwise.
+     */
+    int
+    (*mode_valid)(xf86OutputPtr	    output,
+		  DisplayModePtr    pMode);
+
+    /**
+     * Callback for setting up a video mode before any crtc/dpll changes.
+     *
+     * \param pMode the mode that will be set, or NULL if the mode to be set is
+     * unknown (such as the restore path of VT switching).
+     */
+    void
+    (*pre_set_mode)(xf86OutputPtr   output,
+		    DisplayModePtr  pMode);
+
+    /**
+     * Callback for setting up a video mode after the DPLL update but before
+     * the plane is enabled.
+     */
+    void
+    (*post_set_mode)(xf86OutputPtr  output,
+		     DisplayModePtr pMode);
+
+    /**
+     * Probe for a connected output, and return detect_status.
+     */
+    enum detect_status
+    (*detect)(xf86OutputPtr	    output);
+
+    /**
+     * Query the device for the modes it provides.
+     *
+     * This function may also update MonInfo, mm_width, and mm_height.
+     *
+     * \return singly-linked list of modes or NULL if no modes found.
+     */
+    DisplayModePtr
+    (*get_modes)(xf86OutputPtr	    output);
+
+    /**
+     * Clean up driver-specific bits of the output
+     */
+    void
+    (*destroy) (xf86OutputPtr	    output);
+} xf86OutputFuncsRec, *xf86OutputFuncsPtr;
+
+struct _xf86Output {
+    /**
+     * Associated ScrnInfo
+     */
+    ScrnInfoPtr		scrn;
+    /**
+     * Currently connected crtc (if any)
+     *
+     * If this output is not in use, this field will be NULL.
+     */
+    xf86CrtcPtr		crtc;
+    /**
+     * List of available modes on this output.
+     *
+     * This should be the list from get_modes(), plus perhaps additional
+     * compatible modes added later.
+     */
+    DisplayModePtr	probed_modes;
+
+    /** EDID monitor information */
+    xf86MonPtr		MonInfo;
+
+    /** Physical size of the currently attached output device. */
+    int			mm_width, mm_height;
+
+    /** Output name */
+    char		*name;
+
+    /** output-specific functions */
+    const xf86OutputFuncsRec *funcs;
+
+    /** driver private information */
+    void		*driver_private;
+    
+#ifdef RANDR_12_INTERFACE
+    /**
+     * RandR 1.2 output structure.
+     *
+     * When RandR 1.2 is available, this points at the associated
+     * RandR output structure and is created when this output is created
+     */
+    RROutputPtr		randr_output;
+#else
+    void		*randr_output;
+#endif
+};
+
+#define XF86_MAX_CRTC	4
+#define XF86_MAX_OUTPUT	16
+
+typedef struct _xf86CrtcConfig {
+   int			num_output;
+   xf86OutputPtr	output[XF86_MAX_OUTPUT];
+    
+   int			num_crtc;
+   xf86CrtcPtr		crtc[XF86_MAX_CRTC];
+} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
+
+#define XF86_CRTC_CONFIG_PTR(p)	((xf86CrtcConfigPtr) ((p)->driverPrivate))
+
+/*
+ * Crtc functions
+ */
+xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr		scrn,
+		const xf86CrtcFuncsRec	*funcs);
+
+void
+xf86CrtcDestroy (xf86CrtcPtr		crtc);
+
+
+/**
+ * Allocate a crtc for the specified output
+ *
+ * Find a currently unused CRTC which is suitable for
+ * the specified output
+ */
+
+xf86CrtcPtr 
+xf86AllocCrtc (xf86OutputPtr		output);
+
+/**
+ * Free a crtc
+ *
+ * Mark the crtc as unused by any outputs
+ */
+
+void
+xf86FreeCrtc (xf86CrtcPtr		crtc);
+
+/*
+ * Output functions
+ */
+xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr		scrn,
+		      const xf86OutputFuncsRec *funcs,
+		      const char	*name);
+
+void
+xf86OutputDestroy (xf86OutputPtr	output);
+
+#endif /* _XF86CRTC_H_ */
diff-tree 51d1cf19e71dd5de47f2c6467f4a1685eefd9e1e (from eb17c9aed2144701ad7bd1042b2905446e4d708a)
Author: Dave Airlie <airlied at linux.ie>
Date:   Sun Dec 3 16:30:01 2006 +1100

    Add radeon randr 1.2 initial attempt at support
    
    This doesn't do a huge amount yet

diff --git a/src/Makefile.am b/src/Makefile.am
index e0ed9ed..459a9ae 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,7 +82,8 @@ radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
 	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
-	radeon_xf86Modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	radeon_xf86Modes.c radeon_randr.c \
+	$(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
diff --git a/src/radeon.h b/src/radeon.h
index 46eedbb..f6a0227 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -817,6 +817,7 @@ typedef struct {
 
     CARD32            tv_dac_adj;
 
+    CreateScreenResourcesProcPtr CreateScreenResources;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 #define RADEONWaitForFifo(pScrn, entries)				\
@@ -911,7 +912,7 @@ extern RADEONConnector *RADEONGetCrtcCon
 extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 				  RADEONMonitorType DisplayType, int crtc2);
-extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr modeList);
+extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 2dfcada..ccd0e1b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -439,6 +439,22 @@ struct RADEONInt10Save {
 static Bool RADEONMapMMIO(ScrnInfoPtr pScrn);
 static Bool RADEONUnmapMMIO(ScrnInfoPtr pScrn);
 
+static Bool
+RADEONCreateScreenResources (ScreenPtr pScreen)
+{
+   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+   RADEONInfoPtr  info   = RADEONPTR(pScrn);
+
+   pScreen->CreateScreenResources = info->CreateScreenResources;
+   if (!(*pScreen->CreateScreenResources)(pScreen))
+      return FALSE;
+
+   if (!RADEONRandRCreateScreenResources(pScreen))
+      return FALSE;
+
+  return TRUE;
+}
+
 RADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
 {
     DevUnion     *pPriv;
@@ -2211,7 +2227,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 					  info->FbMapSize,
 					  LOOKUP_BEST_REFRESH);
 		else if (!info->IsSecondary)
-		  modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes, pScrn->monitor->Modes);
+		  modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes, &pScrn->monitor->Modes);
 	    }
         }
 
@@ -3208,11 +3224,8 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     if (!RADEONPreInitGamma(pScrn))              goto fail;
 
-#if 0
-    if (!RADEONPreInitModes(pScrn, pInt10))      goto fail;
-#else
-    RADEONValidateXF86ModeList(pScrn, TRUE);
-#endif
+    if (!RADEONRandRPreInit(pScrn))
+	goto fail;
 
     if (!RADEONPreInitCursor(pScrn))             goto fail;
 
@@ -4243,6 +4256,15 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     info->BlockHandler = pScreen->BlockHandler;
     pScreen->BlockHandler = RADEONBlockHandler;
 
+    /* Rotation */
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "RandR enabled, ignore the following RandR disabled message.\n");
+    xf86DisableRandR(); /* Disable built-in RandR extension */
+    /* support all rotations */
+    RADEONRandRInit(pScreen, RR_Rotate_0); /* only 0 degrees for Radeon */
+
+    info->CreateScreenResources = pScreen->CreateScreenResources;
+    pScreen->CreateScreenResources = RADEONCreateScreenResources;
+
     /* Note unused options */
     if (serverGeneration == 1)
 	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -7036,6 +7058,14 @@ RADEONGetMergedFBOptions(ScrnInfoPtr pSc
 	return;
     }
 
+#if RANDR_12_INTERFACE
+    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+              "MergedFB does not work with Randr 1.2\n");
+    info->MergedFB = FALSE;
+    return;
+#endif
+
+
 			/* collect MergedFB options */
     info->MergedFB = TRUE;
     info->UseRADEONXinerama = TRUE;
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 694b2ed..c70f5e0 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -42,10 +42,12 @@
 
 #include "xf86.h"
 				/* Driver data structures */
+#include "randrstr.h"
+#include "radeon_probe.h"
 #include "radeon.h"
 #include "radeon_reg.h"
 #include "radeon_macros.h"
-#include "radeon_probe.h"
+
 #include "radeon_version.h"
 
 #include "radeon_xf86Modes.h"
@@ -293,7 +295,7 @@ static DisplayModePtr RADEONFPNativeMode
 
 /* FP mode initialization routine for using on-chip RMX to scale
  */
-int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr modeList)
+int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr *modeList)
 {
     RADEONInfoPtr   info       = RADEONPTR(pScrn);
     DisplayModePtr  last       = NULL;
@@ -376,7 +378,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
     }
 
     /* add in all default vesa modes smaller than panel size, used for randr*/
-    for (p = modeList; p && p->next; p = p->next->next) {
+    for (p = *modeList; p && p->next; p = p->next->next) {
 	if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) {
 	    tmp = first;
 	    while (tmp) {
@@ -416,9 +418,9 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
 
     /* Close the doubly-linked mode list, if we found any usable modes */
     if (last) {
-	last->next   = first;
-	first->prev  = last;
-	pScrn->modes = first;
+	last->next   = NULL; //first;
+	first->prev  = NULL; //last;
+	*modeList = first;
 	RADEONSetPitch(pScrn);
     }
 
@@ -597,14 +599,18 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
     int i;
     DisplayModePtr ddc_modes, mode;
-
+    DisplayModePtr test;
 
     for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
 
-	while(pRADEONEnt->PortInfo[i]->probed_modes != NULL) {
-	    xf86DeleteMode(&pRADEONEnt->PortInfo[i]->probed_modes,
-			   pRADEONEnt->PortInfo[i]->probed_modes);
+	test = pRADEONEnt->PortInfo[i]->probed_modes;
+	while(test != NULL) {
+	  xf86DeleteMode(&test, test);
 	}
+
+	pRADEONEnt->PortInfo[i]->probed_modes = test;
+	/* force reprobe */
+	pRADEONEnt->PortInfo[i]->MonType = MT_UNKNOWN;
 	
 	RADEONConnectorFindMonitor(pScrn, i);
 	
@@ -655,7 +661,7 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
 	      break;
 		
 	    case MT_LCD:
-	      RADEONValidateFPModes(pScrn, pScrn->display->modes, pRADEONEnt->PortInfo[i]->probed_modes);
+	      RADEONValidateFPModes(pScrn, pScrn->display->modes, &pRADEONEnt->PortInfo[i]->probed_modes);
 	      break;
 	    default:
 		break;
@@ -695,7 +701,7 @@ RADEONProbeOutputModes(ScrnInfoPtr pScrn
  *
  * This should be obsoleted by RandR 1.2 hopefully.
  */
-static void
+void
 RADEON_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
@@ -769,7 +775,7 @@ RADEON_set_xf86_modes_from_outputs(ScrnI
  * Takes the output mode lists and decides the default root window size
  * and framebuffer pitch.
  */
-static void
+void
 RADEON_set_default_screen_size(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 7ec5e65..ebd4bab 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -38,6 +38,7 @@
 
 #include "xf86str.h"
 #include "xf86DDC.h"
+#include "randrstr.h"
 
 #define _XF86MISC_SERVER_
 #include <X11/extensions/xf86misc.h>
@@ -111,6 +112,10 @@ typedef struct
     Bool IsActive;
     int binding; // which instance of the driver "owns" this controller
     DisplayModePtr pCurMode;
+
+#ifdef RANDR_12_INTERFACE
+    RRCrtcPtr randr_crtc;
+#endif
 } RADEONController;
 
 typedef struct
@@ -125,8 +130,11 @@ typedef struct
     /* one connector can be bound to one CRTC */
     int crtc_num;
 
-     /* a list of probed modes on this connector */
-     DisplayModePtr probed_modes;
+    /* a list of probed modes on this connector */
+    DisplayModePtr probed_modes;
+#ifdef RANDR_12_INTERFACE
+    RROutputPtr randr_output;
+#endif
 } RADEONConnector;
 
 
diff --git a/src/radeon_randr.c b/src/radeon_randr.c
new file mode 100644
index 0000000..2fc012a
--- /dev/null
+++ b/src/radeon_randr.c
@@ -0,0 +1,823 @@
+/*
+ * Copyright 2006 Dave Airlie
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS AND/OR
+ * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdio.h>
+
+/* X and server generic header files */
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "fbdevhw.h"
+#include "vgaHW.h"
+
+#include "randrstr.h"
+
+/* Driver data structures */
+#include "radeon.h"
+#include "radeon_reg.h"
+#include "radeon_macros.h"
+#include "radeon_probe.h"
+#include "radeon_version.h"
+#include "radeon_mergedfb.h"
+
+typedef struct _radeonRandRInfo {
+    int				    virtualX;
+    int				    virtualY;
+    int				    mmWidth;
+    int				    mmHeight;
+    int				    maxX;
+    int				    maxY;
+    Rotation			    rotation; /* current mode */
+    Rotation                        supported_rotations; /* driver supported */
+#ifdef RANDR_12_INTERFACE
+    DisplayModePtr  		    modes[2];
+#endif
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+#ifdef RANDR_12_INTERFACE
+static Bool RADEONRandRInit12 (ScreenPtr pScreen);
+static Bool RADEONRandRCreateScreenResources12 (ScreenPtr pScreen);
+#endif
+
+ 
+static int	    RADEONRandRIndex;
+static int	    RADEONRandRGeneration;
+
+#define XF86RANDRINFO(p)    ((XF86RandRInfoPtr) (p)->devPrivates[RADEONRandRIndex].ptr)
+
+#if RANDR_12_INTERFACE
+static void
+RADEONRandRPointerMoved (int scrnIndex, int x, int y)
+{
+}
+
+static Bool
+RADEONRandRScreenSetSize (ScreenPtr	pScreen,
+			CARD16		width,
+			CARD16		height,
+			CARD32		mmWidth,
+			CARD32		mmHeight)
+{
+    XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+    ScrnInfoPtr		pScrn = XF86SCRNINFO(pScreen);
+    WindowPtr		pRoot = WindowTable[pScreen->myNum];
+    Bool 		ret = TRUE;
+
+    if (randrp->virtualX == -1 || randrp->virtualY == -1) 
+    {
+	randrp->virtualX = pScrn->virtualX;
+	randrp->virtualY = pScrn->virtualY;
+    }
+    if (pRoot)
+	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+
+    pScreen->width = pScrn->virtualX;
+    pScreen->height = pScrn->virtualY;
+    pScreen->mmWidth = mmWidth;
+    pScreen->mmHeight = mmHeight;
+    
+    xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+    xf86SetViewport (pScreen, 0, 0);
+    if (pRoot)
+	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+    if (WindowTable[pScreen->myNum])
+	RRScreenSizeNotify (pScreen);
+    return ret;
+}
+
+static Bool
+RADEONRandRCrtcNotify (RRCrtcPtr crtc)
+{
+  ScreenPtr		pScreen = crtc->pScreen;
+  XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+  ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+  RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+  RRModePtr		mode = NULL;
+  int i, j;
+  int numOutputs = 0;
+  int x, y;
+  int rotation = RR_Rotate_0;
+  RROutputPtr outputs[RADEON_MAX_CRTC];
+  RROutputPtr rrout;
+
+  for (i = 0; i<RADEON_MAX_CONNECTOR; i++) {
+    
+    rrout = pRADEONEnt->PortInfo[i]->randr_output;
+
+    outputs[numOutputs++] = rrout;
+    for (j = 0; j<rrout->numModes; j++) {
+      DisplayModePtr outMode = rrout->modes[j]->devPrivate;
+      mode = rrout->modes[j];
+    }
+  }
+  
+  return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
+}
+
+static Bool
+RADEONRandRCrtcSet (ScreenPtr	pScreen,
+		  RRCrtcPtr	crtc,
+		  RRModePtr	mode,
+		  int		x,
+		  int		y,
+		  Rotation	rotation,
+		  int		num_randr_outputs,
+		  RROutputPtr	*randr_outputs)
+{
+  XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+  RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+ 
+  return RADEONRandRCrtcNotify(crtc);
+}
+
+
+static Bool
+RADEONRandRCrtcSetGamma (ScreenPtr    pScreen,
+		       RRCrtcPtr    crtc)
+{
+    return FALSE;
+}
+
+/**
+ * Given a list of xf86 modes and a RandR Output object, construct
+ * RandR modes and assign them to the output
+ */
+static Bool
+RADEONxf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
+{
+    DisplayModePtr  mode;
+    RRModePtr	    *rrmodes = NULL;
+    int		    nmode = 0;
+    int		    npreferred = 0;
+    Bool	    ret = TRUE;
+    int		    pref;
+
+    for (mode = modes; mode; mode = mode->next)
+	nmode++;
+
+    if (nmode) {
+	rrmodes = xalloc (nmode * sizeof (RRModePtr));
+	
+	if (!rrmodes)
+	    return FALSE;
+	nmode = 0;
+
+	for (pref = 1; pref >= 0; pref--) {
+	    for (mode = modes; mode; mode = mode->next) {
+		if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
+		    xRRModeInfo		modeInfo;
+		    RRModePtr		rrmode;
+		    
+		    modeInfo.nameLength = strlen (mode->name);
+		    modeInfo.width = mode->HDisplay;
+		    modeInfo.dotClock = mode->Clock * 1000;
+		    modeInfo.hSyncStart = mode->HSyncStart;
+		    modeInfo.hSyncEnd = mode->HSyncEnd;
+		    modeInfo.hTotal = mode->HTotal;
+		    modeInfo.hSkew = mode->HSkew;
+
+		    modeInfo.height = mode->VDisplay;
+		    modeInfo.vSyncStart = mode->VSyncStart;
+		    modeInfo.vSyncEnd = mode->VSyncEnd;
+		    modeInfo.vTotal = mode->VTotal;
+		    modeInfo.modeFlags = mode->Flags;
+
+		    rrmode = RRModeGet (&modeInfo, mode->name);
+		    rrmode->devPrivate = mode;
+		    if (rrmode) {
+			rrmodes[nmode++] = rrmode;
+			npreferred += pref;
+		    }
+		}
+	    }
+	}
+    }
+    
+    ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
+    xfree (rrmodes);
+    return ret;
+}
+
+/*
+ * Mirror the current mode configuration to RandR
+ */
+static Bool
+RADEONRandRSetInfo12 (ScrnInfoPtr pScrn)
+{
+    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
+    RROutputPtr		clones[RADEON_MAX_CONNECTOR];
+    RRCrtcPtr		crtc;
+    int			nclone;
+    RRCrtcPtr		crtcs[RADEON_MAX_CRTC];
+    int			ncrtc;
+    DisplayModePtr	modes, mode;
+    xRRModeInfo		modeInfo;
+    RRModePtr		rrmode, *rrmodes;
+    int                 nmode, npreferred;
+    int i, j, p;
+    CARD32		possibleOptions = 0;
+    CARD32		currentOptions = 0;
+    int			connection;
+    int                 subpixel = SubPixelNone;
+    RRCrtcPtr		    randr_crtc;
+    RADEONConnector *connector;
+
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+      ncrtc = 0;
+      crtc = NULL;
+      
+      connector = pRADEONEnt->PortInfo[i];
+
+      if (connector->MonType) {
+	crtc = pRADEONEnt->Controller[i]->randr_crtc;
+	crtcs[ncrtc++] = crtc;
+	randr_crtc = crtc;
+      } else
+	randr_crtc = NULL;
+      
+
+      if (!RROutputSetCrtcs(connector->randr_output, crtcs, ncrtc))
+	return FALSE;
+
+      RROutputSetCrtc(connector->randr_output, crtc);
+
+      nmode = 0;
+      npreferred = 0;
+      rrmodes = NULL;
+      
+      if (connector->probed_modes) {
+	RADEONxf86RROutputSetModes (connector->randr_output, connector->probed_modes);
+      }
+
+      connection = RR_Disconnected;
+      if (connector->MonType > MT_NONE)
+	connection = RR_Connected;
+
+      RROutputSetConnection(connector->randr_output, connection);
+
+      RROutputSetSubpixelOrder(connector->randr_output, subpixel);
+    }
+    return TRUE;
+}
+
+/*
+ * Query the hardware for the current state, then mirror
+ * that to RandR
+ */
+static Bool
+RADEONRandRGetInfo12 (ScreenPtr pScreen, Rotation *rotations)
+{
+    ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+
+    RADEONProbeOutputModes(pScrn);
+    return RADEONRandRSetInfo12 (pScrn);
+}
+
+extern const char *ConnectorTypeName[], *ConnectorTypeNameATOM[];
+
+Bool
+RADEONRandRCreateScreenResources (ScreenPtr pScreen)
+{
+#if RANDR_12_INTERFACE
+    if (RADEONRandRCreateScreenResources12 (pScreen))
+      return TRUE;
+#endif
+    return FALSE;
+}
+
+static Bool
+RADEONRandRCreateObjects12(ScrnInfoPtr pScrn)
+{
+  int i;
+  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+  RADEONInfoPtr  info = RADEONPTR(pScrn);
+
+  if (!RRInit())
+    return FALSE;
+
+  /*
+   * Create RandR resources, then probe them
+   */
+  for (i = 0; i < 2; i++)
+  {
+    RRCrtcPtr randr_crtc = RRCrtcCreate((void *)i);
+
+    if (!randr_crtc)
+      return FALSE;
+
+    RRCrtcGammaSetSize(randr_crtc, 256);
+    pRADEONEnt->Controller[i]->randr_crtc = randr_crtc;
+  }
+
+  for (i = 0; i < 2; i++)
+  {
+    int output = pRADEONEnt->PortInfo[i]->ConnectorType;
+    const char *name = name = info->IsAtomBios ? ConnectorTypeNameATOM[output] : ConnectorTypeName[output];
+    RROutputPtr randr_output = RROutputCreate(name, strlen(name),
+					      (void *) i);
+    
+    if (!randr_output)
+      return FALSE;
+
+    pRADEONEnt->PortInfo[i]->randr_output = randr_output;
+  }
+  return TRUE;
+}
+
+static Bool
+RADEONRandRCreateScreenResources12 (ScreenPtr pScreen)
+{
+  XF86RandRInfoPtr	randrp = XF86RANDRINFO(pScreen);
+  ScrnInfoPtr		pScrn = xf86Screens[pScreen->myNum];
+  RADEONInfoPtr  info = RADEONPTR(pScrn);
+  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+  DisplayModePtr mode;
+  const char *name;
+  int i;
+
+  for (i = 0; i < 2; i++)
+  {
+    if (!RRCrtcAttachScreen(pRADEONEnt->Controller[i]->randr_crtc, pScreen))
+      return FALSE;
+  }
+  
+  for (i = 0; i < 2; i++) {
+    if (!RROutputAttachScreen(pRADEONEnt->PortInfo[i]->randr_output, pScreen))
+      return FALSE;
+  }
+
+  mode = pScrn->currentMode;
+  if (mode) {
+    int mmWidth, mmHeight;
+    
+    if (mode->HDisplay == pScreen->width &&
+	mode->VDisplay == pScreen->height)
+      {
+	mmWidth = pScrn->widthmm;
+	mmHeight = pScrn->heightmm;
+      } else {
+#define MMPERINCH 25.4
+	mmWidth = (double) mode->HDisplay / pScrn->xDpi * MMPERINCH;
+	mmHeight = (double) mode->VDisplay / pScrn->yDpi * MMPERINCH;
+    }
+    RADEONRandRScreenSetSize (pScreen,
+			    mode->HDisplay,
+			    mode->VDisplay,
+			    mmWidth,
+			    mmHeight);
+  }
+
+  for (i = 0; i < RADEON_MAX_CRTC; i++)
+    RADEONRandRCrtcNotify (pRADEONEnt->Controller[i]->randr_crtc);
+    
+  if (randrp->virtualX == -1 || randrp->virtualY == -1)
+  {
+    randrp->virtualX = pScrn->virtualX;
+    randrp->virtualY = pScrn->virtualY;
+  }
+  
+  RRScreenSetSizeRange (pScreen, 320, 240,
+			randrp->virtualX, randrp->virtualY);
+  return TRUE;
+
+}
+
+Bool
+RADEONRandRInit (ScreenPtr    pScreen, int rotation)
+{
+    rrScrPrivPtr	rp;
+    XF86RandRInfoPtr	randrp;
+    
+#ifdef PANORAMIX
+    /* XXX disable RandR when using Xinerama */
+    if (!noPanoramiXExtension)
+	return TRUE;
+#endif
+    if (RADEONRandRGeneration != serverGeneration)
+    {
+	RADEONRandRIndex = AllocateScreenPrivateIndex();
+	RADEONRandRGeneration = serverGeneration;
+    }
+    
+    randrp = xalloc (sizeof (XF86RandRInfoRec));
+    if (!randrp)
+	return FALSE;
+			
+    if (!RRScreenInit(pScreen))
+    {
+	xfree (randrp);
+	return FALSE;
+    }
+    rp = rrGetScrPriv(pScreen);
+    //    rp->rrGetInfo = RADEONRandRGetInfo;
+    //    rp->rrSetConfig = RADEONRandRSetConfig;
+
+    randrp->virtualX = -1;
+    randrp->virtualY = -1;
+    randrp->mmWidth = pScreen->mmWidth;
+    randrp->mmHeight = pScreen->mmHeight;
+    
+    randrp->rotation = RR_Rotate_0; /* initial rotated mode */
+
+    randrp->supported_rotations = rotation;
+
+    randrp->maxX = randrp->maxY = 0;
+
+    pScreen->devPrivates[RADEONRandRIndex].ptr = randrp;
+
+#if RANDR_12_INTERFACE
+    if (!RADEONRandRInit12 (pScreen))
+	return FALSE;
+#endif
+    return TRUE;
+}
+
+static Bool
+RADEONRandRInit12(ScreenPtr pScreen)
+{
+  ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+  rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+
+  rp->rrGetInfo = RADEONRandRGetInfo12;
+  rp->rrScreenSetSize = RADEONRandRScreenSetSize;
+  rp->rrCrtcSet = RADEONRandRCrtcSet;
+  rp->rrCrtcSetGamma = RADEONRandRCrtcSetGamma;
+  rp->rrSetConfig = NULL;
+  //  memset (rp->modes, '\0', sizeof (rp->modes));
+  pScrn->PointerMoved = RADEONRandRPointerMoved;
+  return TRUE;
+}
+
+static RRModePtr
+RADEONRRDefaultMode (RROutputPtr output)
+{
+    RRModePtr   target_mode = NULL;
+    int		target_diff = 0;
+    int		mmHeight;
+    int		num_modes;
+    int		m;
+    
+    num_modes = output->numPreferred ? output->numPreferred : output->numModes;
+    mmHeight = output->mmHeight;
+    if (!mmHeight)
+	mmHeight = 203;	/* 768 pixels at 96dpi */
+    /*
+     * Pick a mode closest to 96dpi 
+     */
+    for (m = 0; m < num_modes; m++)
+    {
+	RRModePtr   mode = output->modes[m];
+	int	    dpi;
+	int	    diff;
+
+	dpi = (mode->mode.height * 254) / (mmHeight * 10);
+	diff = dpi - 96;
+	diff = diff < 0 ? -diff : diff;
+	if (target_mode == NULL || diff < target_diff)
+	{
+	    target_mode = mode;
+	    target_diff = diff;
+	}
+    }
+    return target_mode;
+}
+
+static RRModePtr
+RADEONClosestMode (RROutputPtr output, RRModePtr match)
+{
+    RRModePtr   target_mode = NULL;
+    int		target_diff = 0;
+    int		m;
+    
+    /*
+     * Pick a mode closest to the specified mode
+     */
+    for (m = 0; m < output->numModes; m++)
+    {
+	RRModePtr   mode = output->modes[m];
+	int	    dx, dy;
+	int	    diff;
+
+	/* exact matches are preferred */
+	if (mode == match)
+	    return mode;
+	
+	dx = match->mode.width - mode->mode.width;
+	dy = match->mode.height - mode->mode.height;
+	diff = dx * dx + dy * dy;
+	if (target_mode == NULL || diff < target_diff)
+	{
+	    target_mode = mode;
+	    target_diff = diff;
+	}
+    }
+    return target_mode;
+}
+
+static int
+RADEONRRPickCrtcs (RROutputPtr	*outputs,
+		 RRCrtcPtr	*best_crtcs,
+		 RRModePtr	*modes,
+		 int		num_outputs,
+		 int		n)
+{
+    int		c, o, l;
+    RROutputPtr	output;
+    RRCrtcPtr	crtc;
+    RRCrtcPtr	*crtcs;
+    RRCrtcPtr	best_crtc;
+    int		best_score;
+    int		score;
+    int		my_score;
+    
+    if (n == num_outputs)
+	return 0;
+    output = outputs[n];
+    
+    /*
+     * Compute score with this output disabled
+     */
+    best_crtcs[n] = NULL;
+    best_crtc = NULL;
+    best_score = RADEONRRPickCrtcs (outputs, best_crtcs, modes, num_outputs, n+1);
+    if (modes[n] == NULL)
+	return best_score;
+    
+    crtcs = xalloc (num_outputs * sizeof (RRCrtcPtr));
+    if (!crtcs)
+	return best_score;
+
+    my_score = 1;
+    /* Score outputs that are known to be connected higher */
+    if (output->connection == RR_Connected)
+	my_score++;
+    /* Score outputs with preferred modes higher */
+    if (output->numPreferred)
+	my_score++;
+    /*
+     * Select a crtc for this output and
+     * then attempt to configure the remaining
+     * outputs
+     */
+    for (c = 0; c < output->numCrtcs; c++)
+    {
+	crtc = output->crtcs[c];
+	/*
+	 * Check to see if some other output is
+	 * using this crtc
+	 */
+	for (o = 0; o < n; o++)
+	    if (best_crtcs[o] == crtc)
+		break;
+	if (o < n)
+	{
+	    /*
+	     * If the two outputs desire the same mode,
+	     * see if they can be cloned
+	     */
+	    if (modes[o] == modes[n])
+	    {
+		for (l = 0; l < output->numClones; l++)
+		    if (output->clones[l] == outputs[o])
+			break;
+		if (l == output->numClones)
+		    continue;		/* nope, try next CRTC */
+	    }
+	    else
+		continue;		/* different modes, can't clone */
+	}
+	crtcs[n] = crtc;
+	memcpy (crtcs, best_crtcs, n * sizeof (RRCrtcPtr));
+	score = my_score + RADEONRRPickCrtcs (outputs, crtcs, modes,
+					    num_outputs, n+1);
+	if (score >= best_score)
+	{
+	    best_crtc = crtc;
+	    best_score = score;
+	    memcpy (best_crtcs, crtcs, num_outputs * sizeof (RRCrtcPtr));
+	}
+    }
+    xfree (crtcs);
+    return best_score;
+}
+
+static Bool
+RADEONRRInitialConfiguration (RROutputPtr *outputs,
+			    RRCrtcPtr	*crtcs,
+			    RRModePtr	*modes,
+			    int		num_outputs)
+{
+    int		o;
+    RRModePtr	target_mode = NULL;
+
+    for (o = 0; o < num_outputs; o++)
+	modes[o] = NULL;
+    
+    /*
+     * Let outputs with preferred modes drive screen size
+     */
+    for (o = 0; o < num_outputs; o++)
+    {
+	RROutputPtr output = outputs[o];
+
+	if (output->connection != RR_Disconnected && output->numPreferred)
+	{
+	    target_mode = RADEONRRDefaultMode (output);
+	    if (target_mode)
+	    {
+		modes[o] = target_mode;
+		break;
+	    }
+	}
+    }
+    if (!target_mode)
+    {
+	for (o = 0; o < num_outputs; o++)
+	{
+	    RROutputPtr output = outputs[o];
+	    if (output->connection != RR_Disconnected)
+	    {
+		target_mode = RADEONRRDefaultMode (output);
+		if (target_mode)
+		{
+		    modes[o] = target_mode;
+		    break;
+		}
+	    }
+	}
+    }
+    for (o = 0; o < num_outputs; o++)
+    {
+	RROutputPtr output = outputs[o];
+	
+	if (output->connection != RR_Disconnected && !modes[o])
+	    modes[o] = RADEONClosestMode (output, target_mode);
+    }
+
+    if (!RADEONRRPickCrtcs (outputs, crtcs, modes, num_outputs, 0))
+	return FALSE;
+    
+    return TRUE;
+}
+
+/*
+ * Compute the virtual size necessary to place all of the available
+ * crtcs in a panorama configuration
+ */
+
+static void
+RADEONRRDefaultScreenLimits (RROutputPtr *outputs, int num_outputs,
+			   RRCrtcPtr *crtcs, int num_crtc,
+			   int *widthp, int *heightp)
+{
+    int	    width = 0, height = 0;
+    int	    o;
+    int	    c;
+    int	    m;
+    int	    s;
+
+    for (c = 0; c < num_crtc; c++)
+    {
+	RRCrtcPtr   crtc = crtcs[c];
+	int	    crtc_width = 1600, crtc_height = 1200;
+
+	for (o = 0; o < num_outputs; o++) 
+	{
+	    RROutputPtr	output = outputs[o];
+
+	    for (s = 0; s < output->numCrtcs; s++)
+		if (output->crtcs[s] == crtc)
+		    break;
+	    if (s == output->numCrtcs)
+		continue;
+	    for (m = 0; m < output->numModes; m++)
+	    {
+		RRModePtr   mode = output->modes[m];
+		if (mode->mode.width > crtc_width)
+		    crtc_width = mode->mode.width;
+		if (mode->mode.height > crtc_width)
+		    crtc_height = mode->mode.height;
+	    }
+	}
+	width += crtc_width;
+	if (crtc_height > height)
+	    height = crtc_height;
+    }
+    *widthp = width;
+    *heightp = height;
+}
+
+
+Bool
+RADEONRandRPreInit(ScrnInfoPtr pScrn)
+{
+  RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
+#if RANDR_12_INTERFACE
+  RROutputPtr outputs[RADEON_MAX_CONNECTOR];
+  RRCrtcPtr output_crtcs[RADEON_MAX_CONNECTOR];
+  RRModePtr output_modes[RADEON_MAX_CONNECTOR];
+  RRCrtcPtr crtcs[RADEON_MAX_CRTC];
+#endif
+  int conn, crtc;
+  int o,c;
+  int width, height;
+
+  RADEONProbeOutputModes(pScrn);
+
+#if RANDR_12_INTERFACE
+  if (!RADEONRandRCreateObjects12(pScrn))
+    return FALSE;
+
+  if (!RADEONRandRSetInfo12(pScrn))
+    return FALSE;
+  
+#endif
+    
+  /*
+   * With RandR info set up, let RandR choose
+   * the initial configuration
+   */
+  for (o = 0; o < RADEON_MAX_CONNECTOR; o++)
+    outputs[o] = pRADEONEnt->PortInfo[o]->randr_output;
+  for (c = 0; c < RADEON_MAX_CRTC; c++)
+    crtcs[c] = pRADEONEnt->Controller[c]->randr_crtc;
+  
+  if (!RADEONRRInitialConfiguration (outputs, output_crtcs, output_modes,
+				     RADEON_MAX_CONNECTOR))
+	return FALSE;
+    
+  RADEONRRDefaultScreenLimits (outputs, RADEON_MAX_CONNECTOR,
+			       crtcs, RADEON_MAX_CRTC,
+			       &width, &height);
+    
+    if (width > pScrn->virtualX)
+      pScrn->virtualX = width;
+    if (height > pScrn->virtualY)
+      pScrn->virtualY = height;
+    
+    for (o = 0; o < RADEON_MAX_CONNECTOR; o++)
+    {
+	RRModePtr	randr_mode = output_modes[o];
+	DisplayModePtr	mode;
+	RRCrtcPtr	randr_crtc = output_crtcs[o];
+	int		pipe;
+	Bool		enabled;
+
+	if (randr_mode)
+	    mode = (DisplayModePtr) randr_mode->devPrivate;
+	else
+	    mode = NULL;
+	if (randr_crtc)
+	{
+	    pipe = (int) randr_crtc->devPrivate;
+	    enabled = TRUE;
+	}
+	else
+	{
+	    pipe = 0;
+	    enabled = FALSE;
+	}
+	//	if (mode)
+	//	    pRADEON->pipes[pipe].desiredMode = *mode;
+	//	pRADEON->output[o].pipe = pipe;
+	    //	pRADEON->output[o].enabled = enabled;
+    }
+
+  RADEON_set_xf86_modes_from_outputs(pScrn);
+  RADEON_set_default_screen_size(pScrn);
+    
+  return TRUE;
+}
+#endif
diff-tree eb17c9aed2144701ad7bd1042b2905446e4d708a (from 941b5120916ebff69ec0ee4ca7a46105d5306e5d)
Author: airlied <airlied at optimus.localdomain>
Date:   Sat Nov 18 15:48:02 2006 +1100

    move radeon over to not using X's mode management like the intel driver.
    
    this builds and at least seems to pick a mode.. might be near to hooking
    up randr1.2 soon

diff --git a/src/radeon.h b/src/radeon.h
index d13beeb..46eedbb 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -769,6 +769,7 @@ typedef struct {
     /* X itself has the 3D context */
     Bool              XInited3D;
 
+  DisplayModePtr currentMode, savedCurrentMode;
     /* merged fb stuff, also covers clone modes */
     Bool		MergedFB;
     RADEONScrn2Rel	CRT2Position;
@@ -910,7 +911,7 @@ extern RADEONConnector *RADEONGetCrtcCon
 extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 				  RADEONMonitorType DisplayType, int crtc2);
-extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName);
+extern int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr modeList);
 extern void RADEONSetPitch (ScrnInfoPtr pScrn);
 
 
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0ba4427..2dfcada 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2211,7 +2211,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 					  info->FbMapSize,
 					  LOOKUP_BEST_REFRESH);
 		else if (!info->IsSecondary)
-		    modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes);
+		  modesFound = RADEONValidateFPModes(pScrn, pScrn->display->modes, pScrn->monitor->Modes);
 	    }
         }
 
@@ -2348,10 +2348,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
         info->RADEONDPIVY = pScrn->virtualY;
     }
 
-				/* Get ScreenInit function */
-    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
-
-    xf86LoaderReqSymLists(fbSymbols, NULL);
+			
 
     info->CurrentLayout.displayWidth = pScrn->displayWidth;
     info->CurrentLayout.mode = pScrn->currentMode;
@@ -3197,6 +3194,11 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     if (!RADEONPreInitControllers(pScrn, pInt10))
        goto fail;
 
+	/* Get ScreenInit function */
+    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
+
+    xf86LoaderReqSymLists(fbSymbols, NULL);
+
     /* collect MergedFB options */
     /* only parse mergedfb options on the primary head. 
        Mergedfb is already disabled in xinerama/screen based
@@ -3206,7 +3208,11 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     if (!RADEONPreInitGamma(pScrn))              goto fail;
 
+#if 0
     if (!RADEONPreInitModes(pScrn, pInt10))      goto fail;
+#else
+    RADEONValidateXF86ModeList(pScrn, TRUE);
+#endif
 
     if (!RADEONPreInitCursor(pScrn))             goto fail;
 
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 964ac5b..694b2ed 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -52,6 +52,15 @@
 				/* DDC support */
 #include "xf86DDC.h"
 
+void
+RADEONGetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
+{
+    ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+    *x = pScrn->virtualX;
+    *y = pScrn->virtualY;
+}
+
 void RADEONSetPitch (ScrnInfoPtr pScrn)
 {
     int  dummy = pScrn->virtualX;
@@ -284,7 +293,7 @@ static DisplayModePtr RADEONFPNativeMode
 
 /* FP mode initialization routine for using on-chip RMX to scale
  */
-int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
+int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName, DisplayModePtr modeList)
 {
     RADEONInfoPtr   info       = RADEONPTR(pScrn);
     DisplayModePtr  last       = NULL;
@@ -367,7 +376,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pS
     }
 
     /* add in all default vesa modes smaller than panel size, used for randr*/
-    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+    for (p = modeList; p && p->next; p = p->next->next) {
 	if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) {
 	    tmp = first;
 	    while (tmp) {
@@ -580,3 +589,230 @@ int RADEONValidateMergeModes(ScrnInfoPtr
     }
     return modesFound;
 }
+
+void
+RADEONProbeOutputModes(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    int i;
+    DisplayModePtr ddc_modes, mode;
+
+
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+
+	while(pRADEONEnt->PortInfo[i]->probed_modes != NULL) {
+	    xf86DeleteMode(&pRADEONEnt->PortInfo[i]->probed_modes,
+			   pRADEONEnt->PortInfo[i]->probed_modes);
+	}
+	
+	RADEONConnectorFindMonitor(pScrn, i);
+	
+	/* okay we got DDC info */
+	if (pRADEONEnt->PortInfo[i]->MonInfo) {
+	    /* Debug info for now, at least */
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", i);
+	    xf86PrintEDID(pRADEONEnt->PortInfo[i]->MonInfo);
+
+	    ddc_modes = RADEONGetDDCModes(pScrn, pRADEONEnt->PortInfo[i]->MonInfo);
+	    
+	    for (mode = ddc_modes; mode != NULL; mode = mode->next) {
+		if (mode->Flags & V_DBLSCAN) {
+		    if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+			mode->status = MODE_CLOCK_RANGE;
+		}
+	    }
+	    RADEONxf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
+
+	    /* do some physcial size stuff */
+	}
+	   
+
+	if (pRADEONEnt->PortInfo[i]->probed_modes == NULL) {
+  	    MonRec fixed_mon;
+	    DisplayModePtr modes;
+
+	    switch(pRADEONEnt->PortInfo[i]->MonType) {
+	    case MT_CRT:
+	    case MT_DFP:
+	      
+	            /* We've got a potentially-connected monitor that we can't DDC.  Return a
+		     * fixed set of VESA plus user modes for a presumed multisync monitor with
+		     * some reasonable limits.
+		     */
+	      fixed_mon.nHsync = 1;
+	      fixed_mon.hsync[0].lo = 31.0;
+	      fixed_mon.hsync[0].hi = 100.0;
+	      fixed_mon.nVrefresh = 1;
+	      fixed_mon.vrefresh[0].lo = 50.0;
+	      fixed_mon.vrefresh[0].hi = 70.0;
+	      
+	      modes = RADEONxf86DuplicateModes(pScrn, pScrn->monitor->Modes);
+	      RADEONxf86ValidateModesSync(pScrn, modes, &fixed_mon);
+	      RADEONxf86PruneInvalidModes(pScrn, &modes, TRUE);
+	      /* fill out CRT of FP mode table */
+	      pRADEONEnt->PortInfo[i]->probed_modes = modes;
+	      break;
+		
+	    case MT_LCD:
+	      RADEONValidateFPModes(pScrn, pScrn->display->modes, pRADEONEnt->PortInfo[i]->probed_modes);
+	      break;
+	    default:
+		break;
+	    }
+	}
+
+	if (pRADEONEnt->PortInfo[i]->probed_modes) {
+	  RADEONxf86ValidateModesUserConfig(pScrn,
+					    pRADEONEnt->PortInfo[i]->probed_modes);
+	  RADEONxf86PruneInvalidModes(pScrn, &pRADEONEnt->PortInfo[i]->probed_modes,
+				      FALSE);
+	}
+
+
+	for (mode = pRADEONEnt->PortInfo[i]->probed_modes; mode != NULL;
+	     mode = mode->next)
+	{
+	    /* The code to choose the best mode per pipe later on will require
+	     * VRefresh to be set.
+	     */
+	    mode->VRefresh = RADEONxf86ModeVRefresh(mode);
+	    RADEONxf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+
+#ifdef DEBUG_REPROBE
+	    PrintModeline(pScrn->scrnIndex, mode);
+#endif
+	}
+    }
+}
+  
+
+/**
+ * Constructs pScrn->modes from the output mode lists.
+ *
+ * Currently it only takes one output's mode list and stuffs it into the
+ * XFree86 DDX mode list while trimming it for root window size.
+ *
+ * This should be obsoleted by RandR 1.2 hopefully.
+ */
+static void
+RADEON_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    DisplayModePtr saved_mode, last;
+    int originalVirtualX, originalVirtualY;
+    int i;
+
+    /* Remove the current mode from the modelist if we're re-validating, so we
+     * can find a new mode to map ourselves to afterwards.
+     */
+    saved_mode = info->currentMode;
+    if (saved_mode != NULL) {
+	RADEONxf86DeleteModeFromList(&pScrn->modes, saved_mode);
+    }
+
+    /* Clear any existing modes from pScrn->modes */
+    while (pScrn->modes != NULL)
+	xf86DeleteMode(&pScrn->modes, pScrn->modes);
+
+    /* Set pScrn->modes to the mode list for an arbitrary output.
+     * pScrn->modes should only be used for XF86VidMode now, which we don't
+     * care about enough to make some sort of unioned list.
+     */
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+	if (pRADEONEnt->PortInfo[i]->probed_modes != NULL) {
+	    pScrn->modes =
+		RADEONxf86DuplicateModes(pScrn, pRADEONEnt->PortInfo[i]->probed_modes);
+	    break;
+	}
+    }
+
+    RADEONGetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
+
+    /* Disable modes in the XFree86 DDX list that are larger than the current
+     * virtual size.
+     */
+    RADEONxf86ValidateModesSize(pScrn, pScrn->modes,
+			      originalVirtualX, originalVirtualY,
+			      pScrn->displayWidth);
+
+    /* Strip out anything that we threw out for virtualX/Y. */
+    RADEONxf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
+
+    if (pScrn->modes == NULL) {
+	FatalError("No modes left for XFree86 DDX\n");
+    }
+
+    pScrn->currentMode = pScrn->modes;
+
+    xf86SetDpi(pScrn, 0, 0);
+    info->RADEONDPIVX = pScrn->virtualX;
+    info->RADEONDPIVY = pScrn->virtualY;
+
+    /* For some reason, pScrn->modes is circular, unlike the other mode lists.
+     * How great is that?
+     */
+    last = RADEONGetModeListTail(pScrn->modes);
+    last->next = pScrn->modes;
+    pScrn->modes->prev = last;
+
+    /* Save a pointer to the previous current mode.  We can't reset
+     * pScrn->currentmode, because we rely on xf86SwitchMode's shortcut not
+     * happening so we can hot-enable devices at SwitchMode.  We'll notice this
+     * case at SwitchMode and free the saved mode.
+     */
+    info->savedCurrentMode = saved_mode;
+}
+
+/**
+ * Takes the output mode lists and decides the default root window size
+ * and framebuffer pitch.
+ */
+static void
+RADEON_set_default_screen_size(ScrnInfoPtr pScrn)
+{
+    RADEONInfoPtr info       = RADEONPTR(pScrn);
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    int maxX = -1, maxY = -1;
+    int i;
+
+    /* Set up a virtual size that will cover any clone mode we'd want to
+     * set for the currently-connected outputs.
+     */
+    for (i = 0; i < RADEON_MAX_CONNECTOR; i++) {
+	DisplayModePtr mode;
+
+	for (mode = pRADEONEnt->PortInfo[i]->probed_modes; mode != NULL;
+	     mode = mode->next)
+	{
+	    if (mode->HDisplay > maxX)
+		maxX = mode->HDisplay;
+	    if (mode->VDisplay > maxY)
+		maxY = mode->VDisplay;
+	}
+    }
+    /* let the user specify a bigger virtual size if they like */
+    if (pScrn->display->virtualX > maxX)
+	maxX = pScrn->display->virtualX;
+    if (pScrn->display->virtualY > maxY)
+	maxY = pScrn->display->virtualY;
+    pScrn->virtualX = maxX;
+    pScrn->virtualY = maxY;
+    pScrn->displayWidth = (maxX + 63) & ~63;
+}
+
+
+
+int RADEONValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
+{
+  RADEONProbeOutputModes(pScrn);
+
+  if (first_time)
+    {
+      RADEON_set_default_screen_size(pScrn);
+    }
+
+  RADEON_set_xf86_modes_from_outputs(pScrn);
+  return 1;
+}
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index b651e7d..7ec5e65 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -42,6 +42,9 @@
 #define _XF86MISC_SERVER_
 #include <X11/extensions/xf86misc.h>
 
+#define RADEON_MAX_CRTC 2
+#define RADEON_MAX_CONNECTOR 2
+
 typedef enum
 {
     DDC_NONE_DETECTED,
@@ -121,6 +124,9 @@ typedef struct
 
     /* one connector can be bound to one CRTC */
     int crtc_num;
+
+     /* a list of probed modes on this connector */
+     DisplayModePtr probed_modes;
 } RADEONConnector;
 
 
diff-tree 941b5120916ebff69ec0ee4ca7a46105d5306e5d (from 608427283ea59cdfe3d85e1cf32719bc3809dc16)
Author: airlied <airlied at optimus.localdomain>
Date:   Sat Nov 18 10:41:12 2006 +1100

    make radeon modes use generic code

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 70bf184..964ac5b 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -48,75 +48,10 @@
 #include "radeon_probe.h"
 #include "radeon_version.h"
 
+#include "radeon_xf86Modes.h"
 				/* DDC support */
 #include "xf86DDC.h"
 
-/* Established timings from EDID standard */
-static struct
-{
-    int hsize;
-    int vsize;
-    int refresh;
-} est_timings[] = {
-    {1280, 1024, 75},
-    {1024, 768, 75},
-    {1024, 768, 70},
-    {1024, 768, 60},
-    {1024, 768, 87},
-    {832, 624, 75},
-    {800, 600, 75},
-    {800, 600, 72},
-    {800, 600, 60},
-    {800, 600, 56},
-    {640, 480, 75},
-    {640, 480, 72},
-    {640, 480, 67},
-    {640, 480, 60},
-    {720, 400, 88},
-    {720, 400, 70},
-};
-
-/* This function will sort all modes according to their resolution.
- * Highest resolution first.
- */
-static void RADEONSortModes(DisplayModePtr *new, DisplayModePtr *first,
-			    DisplayModePtr *last)
-{
-    DisplayModePtr  p;
-
-    p = *last;
-    while (p) {
-	if ((((*new)->HDisplay < p->HDisplay) &&
-	     ((*new)->VDisplay < p->VDisplay)) ||
-	    (((*new)->HDisplay == p->HDisplay) &&
-	     ((*new)->VDisplay == p->VDisplay) &&
-	     ((*new)->Clock < p->Clock))) {
-
-	    if (p->next) p->next->prev = *new;
-	    (*new)->prev = p;
-	    (*new)->next = p->next;
-	    p->next = *new;
-	    if (!((*new)->next)) *last = *new;
-	    break;
-	}
-	if (!p->prev) {
-	    (*new)->prev = NULL;
-	    (*new)->next = p;
-	    p->prev = *new;
-	    *first = *new;
-	    break;
-	}
-	p = p->prev;
-    }
-
-    if (!*first) {
-	*first = *new;
-	(*new)->prev = NULL;
-	(*new)->next = NULL;
-	*last = *new;
-    }
-}
-
 void RADEONSetPitch (ScrnInfoPtr pScrn)
 {
     int  dummy = pScrn->virtualX;
@@ -138,143 +73,6 @@ void RADEONSetPitch (ScrnInfoPtr pScrn)
     pScrn->displayWidth = dummy;
 }
 
-/* When no mode provided in config file, this will add all modes supported in
- * DDC date the pScrn->modes list
- */
-static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
-{
-    DisplayModePtr  p;
-    DisplayModePtr  last  = NULL;
-    DisplayModePtr  new   = NULL;
-    DisplayModePtr  first = NULL;
-    int             count = 0;
-    int             j, tmp;
-    char            stmp[32];
-
-    /* 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;
-
-	    if (d_timings->h_active == 0 || d_timings->v_active == 0) break;
-
-	    new = xnfcalloc(1, sizeof (DisplayModeRec));
-	    memset(new, 0, sizeof (DisplayModeRec));
-
-	    new->HDisplay   = d_timings->h_active;
-	    new->VDisplay   = d_timings->v_active;
-
-	    sprintf(stmp, "%dx%d", new->HDisplay, new->VDisplay);
-	    new->name       = xnfalloc(strlen(stmp) + 1);
-	    strcpy(new->name, stmp);
-
-	    new->HTotal     = new->HDisplay + d_timings->h_blanking;
-	    new->HSyncStart = new->HDisplay + d_timings->h_sync_off;
-	    new->HSyncEnd   = new->HSyncStart + d_timings->h_sync_width;
-	    new->VTotal     = new->VDisplay + d_timings->v_blanking;
-	    new->VSyncStart = new->VDisplay + d_timings->v_sync_off;
-	    new->VSyncEnd   = new->VSyncStart + d_timings->v_sync_width;
-	    new->Clock      = d_timings->clock / 1000;
-	    new->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-	    new->status     = MODE_OK;
-#ifdef M_T_PREFERRED
-	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
-	      new->type     = M_T_PREFERRED;
-	    else
-#endif
-	      new->type     = M_T_DEFAULT;
-
-	    if (d_timings->sync == 3) {
-		switch (d_timings->misc) {
-		case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
-		case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
-		case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
-		case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
-		}
-	    }
-	    count++;
-
-	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-		       "Valid Mode from Detailed timing table: %s\n",
-		       new->name);
-
-	    RADEONSortModes(&new, &first, &last);
-	}
-    }
-
-    /* Search thru standard VESA modes from EDID */
-    for (j = 0; j < 8; j++) {
-        if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
-               continue;
-	for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
-	    /* Ignore all double scan modes */
-	    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? */
-		    new = xnfcalloc(1, sizeof (DisplayModeRec));
-		    memcpy(new, p, sizeof(DisplayModeRec));
-		    new->name = xnfalloc(strlen(p->name) + 1);
-		    strcpy(new->name, p->name);
-		    new->status = MODE_OK;
-		    new->type   = M_T_DEFAULT;
-
-		    count++;
-
-		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-			       "Valid Mode from standard timing table: %s\n",
-			       new->name);
-
-		    RADEONSortModes(&new, &first, &last);
-		    break;
-		}
-	    }
-	}
-    }
-
-    /* Search thru established modes from EDID */
-    tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
-    for (j = 0; j < 16; j++) {
-	if (tmp & (1 << j)) {
-	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
-		if ((est_timings[j].hsize == p->HDisplay) &&
-		    (est_timings[j].vsize == p->VDisplay)) {
-		    float  refresh =
-			(float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
-
-		    if (abs((float)est_timings[j].refresh - refresh) < 1.0) {
-			/* Is this good enough? */
-			new = xnfcalloc(1, sizeof (DisplayModeRec));
-			memcpy(new, p, sizeof(DisplayModeRec));
-			new->name = xnfalloc(strlen(p->name) + 1);
-			strcpy(new->name, p->name);
-			new->status = MODE_OK;
-			new->type   = M_T_DEFAULT;
-
-			count++;
-
-			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-				   "Valid Mode from established timing "
-				   "table: %s\n", new->name);
-
-			RADEONSortModes(&new, &first, &last);
-			break;
-		    }
-		}
-	    }
-	}
-    }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "Total of %d mode(s) found.\n", count);
-
-    return first;
-}
-
 /* XFree86's xf86ValidateModes routine doesn't work well with DDC modes,
  * so here is our own validation routine.
  */
@@ -301,7 +99,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr p
 	int  maxVirtY = pScrn->virtualY;
 
 	/* Collect all of the DDC modes */
-	first = last = ddcModes = RADEONDDCModes(pScrn, pScrn->monitor->DDC);
+	first = last = ddcModes = RADEONGetDDCModes(pScrn, pScrn->monitor->DDC);
 
 	for (p = ddcModes; p; p = p->next) {
 
diff-tree 608427283ea59cdfe3d85e1cf32719bc3809dc16 (from d5b8cafc185b7d9fb909cb18a08615f81d89eaf8)
Author: airlied <airlied at optimus.localdomain>
Date:   Sat Nov 18 10:35:31 2006 +1100

    add more functions from i830 driver
    
    This adds more generic functions from the i830 driver to the radeon

diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c
index 1f8416e..730169d 100644
--- a/src/radeon_xf86Modes.c
+++ b/src/radeon_xf86Modes.c
@@ -40,6 +40,627 @@
 #include "radeon.h"
 #include "radeon_xf86Modes.h"
 
+
+/* Established timings from EDID standard */
+static struct
+{
+    int hsize;
+    int vsize;
+    int refresh;
+} est_timings[] = {
+    {1280, 1024, 75},
+    {1024, 768, 75},
+    {1024, 768, 70},
+    {1024, 768, 60},
+    {1024, 768, 87},
+    {832, 624, 75},
+    {800, 600, 75},
+    {800, 600, 72},
+    {800, 600, 60},
+    {800, 600, 56},
+    {640, 480, 75},
+    {640, 480, 72},
+    {640, 480, 67},
+    {640, 480, 60},
+    {720, 400, 88},
+    {720, 400, 70},
+};
+
+
+#include <math.h>
+
+#define rint(x) floor(x)
+
+#define MARGIN_PERCENT    1.8   /* % of active vertical image                */
+#define CELL_GRAN         8.0   /* assumed character cell granularity        */
+#define MIN_PORCH         1     /* minimum front porch                       */
+#define V_SYNC_RQD        3     /* width of vsync in lines                   */
+#define H_SYNC_PERCENT    8.0   /* width of hsync as % of total line         */
+#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */
+#define M                 600.0 /* blanking formula gradient                 */
+#define C                 40.0  /* blanking formula offset                   */
+#define K                 128.0 /* blanking formula scaling factor           */
+#define J                 20.0  /* blanking formula scaling factor           */
+
+/* C' and M' are part of the Blanking Duty Cycle computation */
+
+#define C_PRIME           (((C - J) * K/256.0) + J)
+#define M_PRIME           (K/256.0 * M)
+
+DisplayModePtr
+RADEONGetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins)
+{
+    float h_pixels_rnd;
+    float v_lines_rnd;
+    float v_field_rate_rqd;
+    float top_margin;
+    float bottom_margin;
+    float interlace;
+    float h_period_est;
+    float vsync_plus_bp;
+    float v_back_porch;
+    float total_v_lines;
+    float v_field_rate_est;
+    float h_period;
+    float v_field_rate;
+    float v_frame_rate;
+    float left_margin;
+    float right_margin;
+    float total_active_pixels;
+    float ideal_duty_cycle;
+    float h_blank;
+    float total_pixels;
+    float pixel_freq;
+    float h_freq;
+
+    float h_sync;
+    float h_front_porch;
+    float v_odd_front_porch_lines;
+    DisplayModePtr m;
+
+    m = xnfcalloc(sizeof(DisplayModeRec), 1);
+    
+    
+    /*  1. In order to give correct results, the number of horizontal
+     *  pixels requested is first processed to ensure that it is divisible
+     *  by the character size, by rounding it to the nearest character
+     *  cell boundary:
+     *
+     *  [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND])
+     */
+    
+    h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN;
+    
+    
+    /*  2. If interlace is requested, the number of vertical lines assumed
+     *  by the calculation must be halved, as the computation calculates
+     *  the number of vertical lines per field. In either case, the
+     *  number of lines is rounded to the nearest integer.
+     *   
+     *  [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0),
+     *                                     ROUND([V LINES],0))
+     */
+
+    v_lines_rnd = interlaced ?
+            rint((float) v_lines) / 2.0 :
+            rint((float) v_lines);
+    
+    /*  3. Find the frame rate required:
+     *
+     *  [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2,
+     *                                          [I/P FREQ RQD])
+     */
+
+    v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq);
+
+    /*  4. Find number of lines in Top margin:
+     *
+     *  [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
+     *          ROUND(([MARGIN%]/100*[V LINES RND]),0),
+     *          0)
+     */
+
+    top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0);
+
+    /*  5. Find number of lines in Bottom margin:
+     *
+     *  [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y",
+     *          ROUND(([MARGIN%]/100*[V LINES RND]),0),
+     *          0)
+     */
+
+    bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0);
+
+    /*  6. If interlace is required, then set variable [INTERLACE]=0.5:
+     *   
+     *  [INTERLACE]=(IF([INT RQD?]="y",0.5,0))
+     */
+
+    interlace = interlaced ? 0.5 : 0.0;
+
+    /*  7. Estimate the Horizontal period
+     *
+     *  [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) /
+     *                    ([V LINES RND] + (2*[TOP MARGIN (LINES)]) +
+     *                     [MIN PORCH RND]+[INTERLACE]) * 1000000
+     */
+
+    h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0))
+                    / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace)
+                    * 1000000.0);
+
+    /*  8. Find the number of lines in V sync + back porch:
+     *
+     *  [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0)
+     */
+
+    vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est);
+
+    /*  9. Find the number of lines in V back porch alone:
+     *
+     *  [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND]
+     *
+     *  XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]?
+     */
+    
+    v_back_porch = vsync_plus_bp - V_SYNC_RQD;
+    
+    /*  10. Find the total number of lines in Vertical field period:
+     *
+     *  [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] +
+     *                    [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] +
+     *                    [MIN PORCH RND]
+     */
+
+    total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp +
+        interlace + MIN_PORCH;
+    
+    /*  11. Estimate the Vertical field frequency:
+     *
+     *  [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000
+     */
+
+    v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0;
+    
+    /*  12. Find the actual horizontal period:
+     *
+     *  [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST])
+     */
+
+    h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est);
+    
+    /*  13. Find the actual Vertical field frequency:
+     *
+     *  [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000
+     */
+
+    v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0;
+
+    /*  14. Find the Vertical frame frequency:
+     *
+     *  [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE]))
+     */
+
+    v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate;
+
+    /*  15. Find number of pixels in left margin:
+     *
+     *  [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
+     *          (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
+     *                   [CELL GRAN RND]),0)) * [CELL GRAN RND],
+     *          0))
+     */
+
+    left_margin = margins ?
+        rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
+        0.0;
+    
+    /*  16. Find number of pixels in right margin:
+     *
+     *  [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y",
+     *          (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 /
+     *                   [CELL GRAN RND]),0)) * [CELL GRAN RND],
+     *          0))
+     */
+    
+    right_margin = margins ?
+        rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN :
+        0.0;
+    
+    /*  17. Find total number of active pixels in image and left and right
+     *  margins:
+     *
+     *  [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] +
+     *                          [RIGHT MARGIN (PIXELS)]
+     */
+
+    total_active_pixels = h_pixels_rnd + left_margin + right_margin;
+    
+    /*  18. Find the ideal blanking duty cycle from the blanking duty cycle
+     *  equation:
+     *
+     *  [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000)
+     */
+
+    ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0);
+    
+    /*  19. Find the number of pixels in the blanking time to the nearest
+     *  double character cell:
+     *
+     *  [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] *
+     *                               [IDEAL DUTY CYCLE] /
+     *                               (100-[IDEAL DUTY CYCLE]) /
+     *                               (2*[CELL GRAN RND])), 0))
+     *                       * (2*[CELL GRAN RND])
+     */
+
+    h_blank = rint(total_active_pixels *
+                   ideal_duty_cycle /
+                   (100.0 - ideal_duty_cycle) /
+                   (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN);
+    
+    /*  20. Find total number of pixels:
+     *
+     *  [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)]
+     */
+
+    total_pixels = total_active_pixels + h_blank;
+    
+    /*  21. Find pixel clock frequency:
+     *
+     *  [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD]
+     */
+    
+    pixel_freq = total_pixels / h_period;
+    
+    /*  22. Find horizontal frequency:
+     *
+     *  [H FREQ] = 1000 / [H PERIOD]
+     */
+
+    h_freq = 1000.0 / h_period;
+    
+
+    /* Stage 1 computations are now complete; I should really pass
+       the results to another function and do the Stage 2
+       computations, but I only need a few more values so I'll just
+       append the computations here for now */
+
+    
+
+    /*  17. Find the number of pixels in the horizontal sync period:
+     *
+     *  [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] /
+     *                             [CELL GRAN RND]),0))*[CELL GRAN RND]
+     */
+
+    h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN;
+
+    /*  18. Find the number of pixels in the horizontal front porch period:
+     *
+     *  [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)]
+     */
+
+    h_front_porch = (h_blank / 2.0) - h_sync;
+
+    /*  36. Find the number of lines in the odd front porch period:
+     *
+     *  [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE])
+     */
+    
+    v_odd_front_porch_lines = MIN_PORCH + interlace;
+    
+    /* finally, pack the results in the DisplayMode struct */
+    
+    m->HDisplay  = (int) (h_pixels_rnd);
+    m->HSyncStart = (int) (h_pixels_rnd + h_front_porch);
+    m->HSyncEnd = (int) (h_pixels_rnd + h_front_porch + h_sync);
+    m->HTotal = (int) (total_pixels);
+
+    m->VDisplay  = (int) (v_lines_rnd);
+    m->VSyncStart = (int) (v_lines_rnd + v_odd_front_porch_lines);
+    m->VSyncEnd = (int) (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD);
+    m->VTotal = (int) (total_v_lines);
+
+    m->Clock   = (int)(pixel_freq * 1000);
+    m->SynthClock   = m->Clock;
+    m->HSync = h_freq;
+    m->VRefresh = v_frame_rate /* freq */;
+
+    RADEONxf86SetModeDefaultName(m);
+
+    return (m);
+}
+
+void
+RADEONPrintModes(ScrnInfoPtr scrp)
+{
+    DisplayModePtr p;
+    float hsync, refresh = 0;
+    char *desc, *desc2, *prefix, *uprefix;
+
+    if (scrp == NULL)
+	return;
+
+    xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
+	       "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
+	       scrp->displayWidth);
+    
+    p = scrp->modes;
+    if (p == NULL)
+	return;
+
+    do {
+	desc = desc2 = "";
+	if (p->HSync > 0.0)
+	    hsync = p->HSync;
+	else if (p->HTotal > 0)
+	    hsync = (float)p->Clock / (float)p->HTotal;
+	else
+	    hsync = 0.0;
+	if (p->VTotal > 0)
+	    refresh = hsync * 1000.0 / p->VTotal;
+	if (p->Flags & V_INTERLACE) {
+	    refresh *= 2.0;
+	    desc = " (I)";
+	}
+	if (p->Flags & V_DBLSCAN) {
+	    refresh /= 2.0;
+	    desc = " (D)";
+	}
+	if (p->VScan > 1) {
+	    refresh /= p->VScan;
+	    desc2 = " (VScan)";
+	}
+	if (p->VRefresh > 0.0)
+	    refresh = p->VRefresh;
+	if (p->type & M_T_BUILTIN)
+	    prefix = "Built-in mode";
+	else if (p->type & M_T_DEFAULT)
+	    prefix = "Default mode";
+	else
+	    prefix = "Mode";
+	if (p->type & M_T_USERDEF)
+	    uprefix = "*";
+	else
+	    uprefix = " ";
+	if (p->name)
+	    xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+			   "%s%s \"%s\"\n", uprefix, prefix, p->name);
+	else
+	    xf86DrvMsg(scrp->scrnIndex, X_PROBED,
+			   "%s%s %dx%d (unnamed)\n",
+			   uprefix, prefix, p->HDisplay, p->VDisplay);
+	p = p->next;
+    } while (p != NULL && p != scrp->modes);
+}
+
+/* This function will sort all modes according to their resolution.
+ * Highest resolution first.
+ */
+void
+RADEONxf86SortModes(DisplayModePtr new, DisplayModePtr *first,
+	      DisplayModePtr *last)
+{
+    DisplayModePtr  p;
+
+    p = *last;
+    while (p) {
+	if (((new->HDisplay < p->HDisplay) &&
+	     (new->VDisplay < p->VDisplay)) ||
+	    ((new->HDisplay * new->VDisplay) < (p->HDisplay * p->VDisplay)) ||
+	    ((new->HDisplay == p->HDisplay) &&
+	     (new->VDisplay == p->VDisplay) &&
+	     (new->Clock < p->Clock))) {
+
+	    if (p->next) 
+		p->next->prev = new;
+	    new->prev = p;
+	    new->next = p->next;
+	    p->next = new;
+	    if (!(new->next))
+		*last = new;
+	    break;
+	}
+	if (!p->prev) {
+	    new->prev = NULL;
+	    new->next = p;
+	    p->prev = new;
+	    *first = new;
+	    break;
+	}
+	p = p->prev;
+    }
+
+    if (!*first) {
+	*first = new;
+	new->prev = NULL;
+	new->next = NULL;
+	*last = new;
+    }
+}
+
+/**
+ * Gets a new pointer to a VESA established mode.
+ *
+ * \param i index into the VESA established modes table.
+ */
+DisplayModePtr
+RADEONGetVESAEstablishedMode(ScrnInfoPtr pScrn, int i)
+{
+    DisplayModePtr pMode;
+
+    for (pMode = RADEONxf86DefaultModes; pMode->name != NULL; pMode++)
+    {
+	if (pMode->HDisplay == est_timings[i].hsize &&
+	    pMode->VDisplay == est_timings[i].vsize &&
+	    fabs(RADEONxf86ModeVRefresh(pMode) - est_timings[i].refresh) < 1.0)
+	{
+	    DisplayModePtr pNew = RADEONxf86DuplicateMode(pMode);
+	    RADEONxf86SetModeDefaultName(pNew);
+	    pNew->VRefresh = RADEONxf86ModeVRefresh(pMode);
+	    return pNew;
+	}
+    }
+    return NULL;
+}
+
+DisplayModePtr
+RADEONGetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
+{
+    DisplayModePtr  last  = NULL;
+    DisplayModePtr  new   = NULL;
+    DisplayModePtr  first = NULL;
+    int             count = 0;
+    int             j, tmp;
+
+    if (ddc == NULL)
+	return NULL;
+
+    /* 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;
+
+	    if (d_timings->h_active == 0 || d_timings->v_active == 0) break;
+
+	    new = xnfcalloc(1, sizeof (DisplayModeRec));
+	    memset(new, 0, sizeof (DisplayModeRec));
+
+	    new->HDisplay   = d_timings->h_active;
+	    new->VDisplay   = d_timings->v_active;
+
+	    new->HTotal     = new->HDisplay + d_timings->h_blanking;
+	    new->HSyncStart = new->HDisplay + d_timings->h_sync_off;
+	    new->HSyncEnd   = new->HSyncStart + d_timings->h_sync_width;
+	    new->VTotal     = new->VDisplay + d_timings->v_blanking;
+	    new->VSyncStart = new->VDisplay + d_timings->v_sync_off;
+	    new->VSyncEnd   = new->VSyncStart + d_timings->v_sync_width;
+	    new->Clock      = d_timings->clock / 1000;
+	    new->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
+	    new->status     = MODE_OK;
+#ifdef M_T_PREFERRED
+	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
+		new->type   = M_T_PREFERRED;
+	    else
+		new->type   = M_T_DRIVER;
+#else
+	    new->type = M_T_USERDEF;
+#endif
+
+	    RADEONxf86SetModeDefaultName(new);
+
+	    if (d_timings->sync == 3) {
+		switch (d_timings->misc) {
+		case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
+		case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
+		case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
+		case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
+		}
+	    }
+	    count++;
+
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "Valid Mode from Detailed timing table: %s (ht %d hss %d hse %d vt %d vss %d vse %d)\n",
+		       new->name,
+		       new->HTotal, new->HSyncStart, new->HSyncEnd,
+		       new->VTotal, new->VSyncStart, new->VSyncEnd);
+
+	    RADEONxf86SortModes(new, &first, &last);
+	}
+    }
+
+    /* Search thru standard VESA modes from EDID */
+    for (j = 0; j < 8; j++) {
+        if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
+               continue;
+#if 1
+	new = RADEONGetGTF(ddc->timings2[j].hsize, ddc->timings2[j].vsize,
+			 ddc->timings2[j].refresh, FALSE, FALSE);
+	new->status = MODE_OK;
+	new->type |= M_T_DEFAULT;
+
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Valid Mode from standard timing table: %s\n",
+		   new->name);
+
+	RADEONxf86SortModes(new, &first, &last);
+#else
+	for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+
+	    /* Ignore all double scan modes */
+	    if ((ddc->timings2[j].hsize == p->HDisplay) &&
+		(ddc->timings2[j].vsize == p->VDisplay)) {
+		float  refresh =
+		    (float)p->Clock * 1000.0 / p->HTotal / p->VTotal;
+		float err = (float)ddc->timings2[j].refresh - refresh;
+
+		if (err < 0) err = -err;
+		if (err < 1.0) {
+		    /* Is this good enough? */
+		    new = xnfcalloc(1, sizeof (DisplayModeRec));
+		    memcpy(new, p, sizeof(DisplayModeRec));
+		    new->name = xnfalloc(strlen(p->name) + 1);
+		    strcpy(new->name, p->name);
+		    new->status = MODE_OK;
+		    new->type   = M_T_DEFAULT;
+
+		    count++;
+
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			       "Valid Mode from standard timing table: %s\n",
+			       new->name);
+
+		    RADEONxf86SortModes(new, &first, &last);
+		    break;
+		}
+	    }
+	}
+#endif
+    }
+
+    /* Search thru established modes from EDID */
+    tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
+    for (j = 0; j < 16; j++) {
+	if (tmp & (1 << j)) {
+	    new = RADEONGetVESAEstablishedMode(pScrn, j);
+	    if (new == NULL) {
+		ErrorF("Couldn't get established mode %d\n", j);
+		continue;
+	    }
+	    new->status = MODE_OK;
+	    new->type = M_T_DEFAULT;
+
+	    count++;
+
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Valid Mode from established "
+		       "timing table: %s\n", new->name);
+
+	    RADEONxf86SortModes(new, &first, &last);
+	}
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Total of %d DDC mode(s) found.\n", count);
+
+    return first;
+}
+
+DisplayModePtr
+RADEONGetModeListTail(DisplayModePtr pModeList)
+{
+    DisplayModePtr last;
+
+    if (pModeList == NULL)
+	return NULL;
+
+    for (last = pModeList; last->next != NULL; last = last->next)
+	;
+
+    return last;
+}
+
 /**
  * @file this file contains symbols from xf86Mode.c and friends that are static
  * there but we still want to use.  We need to come up with better API here.
diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h
index a357a01..ddf3be8 100644
--- a/src/radeon_xf86Modes.h
+++ b/src/radeon_xf86Modes.h
@@ -77,3 +77,22 @@ void
 PrintModeline(int scrnIndex,DisplayModePtr mode);
 
 extern DisplayModeRec RADEONxf86DefaultModes[];
+
+void
+RADEONPrintModes(ScrnInfoPtr scrp);
+
+DisplayModePtr
+RADEONGetGTF(int h_pixels, int v_lines, float freq, int interlaced, int margins);
+
+void
+RADEONxf86SortModes(DisplayModePtr new, DisplayModePtr *first,
+		    DisplayModePtr *last);
+
+DisplayModePtr
+RADEONGetVESAEstablishedMode(ScrnInfoPtr pScrn, int i);
+
+DisplayModePtr
+RADEONGetDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc);
+
+DisplayModePtr
+RADEONGetModeListTail(DisplayModePtr pModeList);
diff-tree d5b8cafc185b7d9fb909cb18a08615f81d89eaf8 (from 9cfa82e1670ad85746926995972a535ddf03ee07)
Author: airlied <airlied at optimus.localdomain>
Date:   Sat Nov 18 10:22:38 2006 +1100

    add generic mode handling code from Intel driver

diff --git a/src/Makefile.am b/src/Makefile.am
index b1410f7..e0ed9ed 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,7 +81,8 @@ radeon_drv_ladir = @moduledir@/drivers
 radeon_drv_la_SOURCES = \
 	radeon_accel.c radeon_mergedfb.c radeon_cursor.c radeon_dga.c \
 	radeon_driver.c radeon_video.c radeon_bios.c radeon_mm_i2c.c \
-	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
+	radeon_vip.c radeon_misc.c radeon_display.c radeon_modes.c \
+	radeon_xf86Modes.c $(RADEON_DRI_SRCS) $(RADEON_EXA_SOURCES)
 
 theatre_detect_drv_la_LTLIBRARIES = theatre_detect_drv.la
 theatre_detect_drv_la_LDFLAGS = -module -avoid-version
@@ -190,6 +191,7 @@ EXTRA_DIST = \
 	radeon_sarea.h \
 	radeon_version.h \
 	radeon_video.h \
+	radeon_xf86Modes.h \
 	theatre200.h \
 	theatre_detect.h \
 	theatre.h \
diff --git a/src/radeon_xf86Modes.c b/src/radeon_xf86Modes.c
new file mode 100644
index 0000000..1f8416e
--- /dev/null
+++ b/src/radeon_xf86Modes.c
@@ -0,0 +1,641 @@
+/* -*- c-basic-offset: 4 -*- */
+/* $XdotOrg: xserver/xorg/hw/xfree86/common/xf86Mode.c,v 1.10 2006/03/07 16:00:57 libv Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Mode.c,v 1.69 2003/10/08 14:58:28 dawes Exp $ */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "radeon.h"
+#include "radeon_xf86Modes.h"
+
+/**
+ * @file this file contains symbols from xf86Mode.c and friends that are static
+ * there but we still want to use.  We need to come up with better API here.
+ */
+
+
+/**
+ * Calculates the horizontal sync rate of a mode.
+ *
+ * Exact copy of xf86Mode.c's.
+ */
+double
+RADEONxf86ModeHSync(DisplayModePtr mode)
+{
+    double hsync = 0.0;
+    
+    if (mode->HSync > 0.0)
+	    hsync = mode->HSync;
+    else if (mode->HTotal > 0)
+	    hsync = (float)mode->Clock / (float)mode->HTotal;
+
+    return hsync;
+}
+
+/**
+ * Calculates the vertical refresh rate of a mode.
+ *
+ * Exact copy of xf86Mode.c's.
+ */
+double
+RADEONxf86ModeVRefresh(DisplayModePtr mode)
+{
+    double refresh = 0.0;
+
+    if (mode->VRefresh > 0.0)
+	refresh = mode->VRefresh;
+    else if (mode->HTotal > 0 && mode->VTotal > 0) {
+	refresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;
+	if (mode->Flags & V_INTERLACE)
+	    refresh *= 2.0;
+	if (mode->Flags & V_DBLSCAN)
+	    refresh /= 2.0;
+	if (mode->VScan > 1)
+	    refresh /= (float)(mode->VScan);
+    }
+    return refresh;
+}
+
+/**
+ * Sets a default mode name of <width>x<height>x<refresh> on a mode.
+ *
+ * The refresh rate doesn't contain decimals, as that's expected to be
+ * unimportant from the user's perspective for non-custom modelines.
+ */
+void
+RADEONxf86SetModeDefaultName(DisplayModePtr mode)
+{
+    if (mode->name != NULL)
+	xfree(mode->name);
+
+    mode->name = XNFprintf("%dx%d", mode->HDisplay, mode->VDisplay);
+}
+
+/*
+ * RADEONxf86SetModeCrtc
+ *
+ * Initialises the Crtc parameters for a mode.  The initialisation includes
+ * adjustments for interlaced and double scan modes.
+ *
+ * Exact copy of xf86Mode.c's.
+ */
+void
+RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
+{
+    if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN))
+	return;
+
+    p->CrtcHDisplay             = p->HDisplay;
+    p->CrtcHSyncStart           = p->HSyncStart;
+    p->CrtcHSyncEnd             = p->HSyncEnd;
+    p->CrtcHTotal               = p->HTotal;
+    p->CrtcHSkew                = p->HSkew;
+    p->CrtcVDisplay             = p->VDisplay;
+    p->CrtcVSyncStart           = p->VSyncStart;
+    p->CrtcVSyncEnd             = p->VSyncEnd;
+    p->CrtcVTotal               = p->VTotal;
+    if (p->Flags & V_INTERLACE) {
+	if (adjustFlags & INTERLACE_HALVE_V) {
+	    p->CrtcVDisplay         /= 2;
+	    p->CrtcVSyncStart       /= 2;
+	    p->CrtcVSyncEnd         /= 2;
+	    p->CrtcVTotal           /= 2;
+	}
+	/* Force interlaced modes to have an odd VTotal */
+	/* maybe we should only do this when INTERLACE_HALVE_V is set? */
+	p->CrtcVTotal |= 1;
+    }
+
+    if (p->Flags & V_DBLSCAN) {
+        p->CrtcVDisplay         *= 2;
+        p->CrtcVSyncStart       *= 2;
+        p->CrtcVSyncEnd         *= 2;
+        p->CrtcVTotal           *= 2;
+    }
+    if (p->VScan > 1) {
+        p->CrtcVDisplay         *= p->VScan;
+        p->CrtcVSyncStart       *= p->VScan;
+        p->CrtcVSyncEnd         *= p->VScan;
+        p->CrtcVTotal           *= p->VScan;
+    }
+    p->CrtcHAdjusted = FALSE;
+    p->CrtcVAdjusted = FALSE;
+
+    /*
+     * XXX
+     *
+     * The following is taken from VGA, but applies to other cores as well.
+     */
+    p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
+    p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
+    if ((p->CrtcVBlankEnd - p->CrtcVBlankStart) >= 127) {
+        /* 
+         * V Blanking size must be < 127.
+         * Moving blank start forward is safer than moving blank end
+         * back, since monitors clamp just AFTER the sync pulse (or in
+         * the sync pulse), but never before.
+         */
+        p->CrtcVBlankStart = p->CrtcVBlankEnd - 127;
+	/*
+	 * If VBlankStart is now > VSyncStart move VBlankStart
+	 * to VSyncStart using the maximum width that fits into
+	 * VTotal.
+	 */
+	if (p->CrtcVBlankStart > p->CrtcVSyncStart) {
+	    p->CrtcVBlankStart = p->CrtcVSyncStart;
+	    p->CrtcVBlankEnd = min(p->CrtcHBlankStart + 127, p->CrtcVTotal);
+	}
+    }
+    p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
+    p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
+
+    if ((p->CrtcHBlankEnd - p->CrtcHBlankStart) >= 63 * 8) {
+        /*
+         * H Blanking size must be < 63*8. Same remark as above.
+         */
+        p->CrtcHBlankStart = p->CrtcHBlankEnd - 63 * 8;
+	if (p->CrtcHBlankStart > p->CrtcHSyncStart) {
+	    p->CrtcHBlankStart = p->CrtcHSyncStart;
+	    p->CrtcHBlankEnd = min(p->CrtcHBlankStart + 63 * 8, p->CrtcHTotal);
+	}
+    }
+}
+
+/**
+ * Allocates and returns a copy of pMode, including pointers within pMode.
+ */
+DisplayModePtr
+RADEONxf86DuplicateMode(DisplayModePtr pMode)
+{
+    DisplayModePtr pNew;
+
+    pNew = xnfalloc(sizeof(DisplayModeRec));
+    *pNew = *pMode;
+    pNew->next = NULL;
+    pNew->prev = NULL;
+    if (pNew->name == NULL) {
+	RADEONxf86SetModeDefaultName(pMode);
+    } else {
+	pNew->name = xnfstrdup(pMode->name);
+    }
+
+    return pNew;
+}
+
+/**
+ * Duplicates every mode in the given list and returns a pointer to the first
+ * mode.
+ *
+ * \param modeList doubly-linked mode list
+ */
+DisplayModePtr
+RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+{
+    DisplayModePtr first = NULL, last = NULL;
+    DisplayModePtr mode;
+
+    for (mode = modeList; mode != NULL; mode = mode->next) {
+	DisplayModePtr new;
+
+	new = RADEONxf86DuplicateMode(mode);
+
+	/* Insert pNew into modeList */
+	if (last) {
+	    last->next = new;
+	    new->prev = last;
+	} else {
+	    first = new;
+	    new->prev = NULL;
+	}
+	new->next = NULL;
+	last = new;
+    }
+
+    return first;
+}
+
+/**
+ * Returns true if the given modes should program to the same timings.
+ *
+ * This doesn't use Crtc values, as it might be used on ModeRecs without the
+ * Crtc values set.  So, it's assumed that the other numbers are enough.
+ *
+ * This isn't in xf86Modes.c, but it might deserve to be there.
+ */
+Bool
+RADEONModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2)
+{
+     if (pMode1->Clock == pMode2->Clock &&
+	 pMode1->HDisplay == pMode2->HDisplay &&
+	 pMode1->HSyncStart == pMode2->HSyncStart &&
+	 pMode1->HSyncEnd == pMode2->HSyncEnd &&
+	 pMode1->HTotal == pMode2->HTotal &&
+	 pMode1->HSkew == pMode2->HSkew &&
+	 pMode1->VDisplay == pMode2->VDisplay &&
+	 pMode1->VSyncStart == pMode2->VSyncStart &&
+	 pMode1->VSyncEnd == pMode2->VSyncEnd &&
+	 pMode1->VTotal == pMode2->VTotal &&
+	 pMode1->VScan == pMode2->VScan &&
+	 pMode1->Flags == pMode2->Flags)
+     {
+	return TRUE;
+     } else {
+	return FALSE;
+     }
+}
+
+/* exact copy of xf86Mode.c */
+static void
+add(char **p, char *new)
+{
+    *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2);
+    strcat(*p, " ");
+    strcat(*p, new);
+}
+
+/**
+ * Print out a modeline.
+ *
+ * Convenient VRefresh printing was added, though, compared to xf86Mode.c
+ */
+void
+PrintModeline(int scrnIndex,DisplayModePtr mode)
+{
+    char tmp[256];
+    char *flags = xnfcalloc(1, 1);
+
+    if (mode->HSkew) { 
+	snprintf(tmp, 256, "hskew %i", mode->HSkew); 
+	add(&flags, tmp);
+    }
+    if (mode->VScan) { 
+	snprintf(tmp, 256, "vscan %i", mode->VScan); 
+	add(&flags, tmp);
+    }
+    if (mode->Flags & V_INTERLACE) add(&flags, "interlace");
+    if (mode->Flags & V_CSYNC) add(&flags, "composite");
+    if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan");
+    if (mode->Flags & V_BCAST) add(&flags, "bcast");
+    if (mode->Flags & V_PHSYNC) add(&flags, "+hsync");
+    if (mode->Flags & V_NHSYNC) add(&flags, "-hsync");
+    if (mode->Flags & V_PVSYNC) add(&flags, "+vsync");
+    if (mode->Flags & V_NVSYNC) add(&flags, "-vsync");
+    if (mode->Flags & V_PCSYNC) add(&flags, "+csync");
+    if (mode->Flags & V_NCSYNC) add(&flags, "-csync");
+#if 0
+    if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2");
+#endif
+    xf86DrvMsg(scrnIndex, X_INFO,
+		   "Modeline \"%s\"x%.01f  %6.2f  %i %i %i %i  %i %i %i %i%s "
+		   "(%.01f kHz)\n",
+		   mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
+		   mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
+		   mode->VDisplay, mode->VSyncStart, mode->VSyncEnd,
+		   mode->VTotal, flags, RADEONxf86ModeHSync(mode));
+    xfree(flags);
+}
+
+/**
+ * Marks as bad any modes with unsupported flags.
+ *
+ * \param modeList doubly-linked or circular list of modes.
+ * \param flags flags supported by the driver.
+ *
+ * \bug only V_INTERLACE and V_DBLSCAN are supported.  Is that enough?
+ *
+ * This is not in xf86Modes.c, but would be part of the proposed new API.
+ */
+void
+RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			    int flags)
+{
+    DisplayModePtr mode;
+
+    for (mode = modeList; mode != NULL; mode = mode->next) {
+	if (mode->Flags & V_INTERLACE && !(flags & V_INTERLACE))
+	    mode->status = MODE_NO_INTERLACE;
+	if (mode->Flags & V_DBLSCAN && !(flags & V_DBLSCAN))
+	    mode->status = MODE_NO_DBLESCAN;
+    }
+}
+
+/**
+ * Marks as bad any modes extending beyond the given max X, Y, or pitch.
+ *
+ * \param modeList doubly-linked or circular list of modes.
+ *
+ * This is not in xf86Modes.c, but would be part of the proposed new API.
+ */
+void
+RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			  int maxX, int maxY, int maxPitch)
+{
+    DisplayModePtr mode;
+
+    for (mode = modeList; mode != NULL; mode = mode->next) {
+	if (maxPitch > 0 && mode->HDisplay > maxPitch)
+	    mode->status = MODE_BAD_WIDTH;
+
+	if (maxX > 0 && mode->HDisplay > maxX)
+	    mode->status = MODE_VIRTUAL_X;
+
+	if (maxY > 0 && mode->VDisplay > maxY)
+	    mode->status = MODE_VIRTUAL_Y;
+
+	if (mode->next == modeList)
+	    break;
+    }
+}
+
+/**
+ * Marks as bad any modes that aren't supported by the given monitor's
+ * hsync and vrefresh ranges.
+ *
+ * \param modeList doubly-linked or circular list of modes.
+ *
+ * This is not in xf86Modes.c, but would be part of the proposed new API.
+ */
+void
+RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			  MonPtr mon)
+{
+    DisplayModePtr mode;
+
+    for (mode = modeList; mode != NULL; mode = mode->next) {
+	Bool bad;
+	int i;
+
+	bad = TRUE;
+	for (i = 0; i < mon->nHsync; i++) {
+	    if (RADEONxf86ModeHSync(mode) >= mon->hsync[i].lo &&
+		RADEONxf86ModeHSync(mode) <= mon->hsync[i].hi)
+	    {
+		bad = FALSE;
+	    }
+	}
+	if (bad)
+	    mode->status = MODE_HSYNC;
+
+	bad = TRUE;
+	for (i = 0; i < mon->nVrefresh; i++) {
+	    if (RADEONxf86ModeVRefresh(mode) >= mon->vrefresh[i].lo &&
+		RADEONxf86ModeVRefresh(mode) <= mon->vrefresh[i].hi)
+	    {
+		bad = FALSE;
+	    }
+	}
+	if (bad)
+	    mode->status = MODE_VSYNC;
+
+	if (mode->next == modeList)
+	    break;
+    }
+}
+
+/**
+ * Marks as bad any modes extending beyond outside of the given clock ranges.
+ *
+ * \param modeList doubly-linked or circular list of modes.
+ * \param min pointer to minimums of clock ranges
+ * \param max pointer to maximums of clock ranges
+ * \param n_ranges number of ranges.
+ *
+ * This is not in xf86Modes.c, but would be part of the proposed new API.
+ */
+void
+RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			    int *min, int *max, int n_ranges)
+{
+    DisplayModePtr mode;
+    int i;
+
+    for (mode = modeList; mode != NULL; mode = mode->next) {
+	Bool good = FALSE;
+	for (i = 0; i < n_ranges; i++) {
+	    if (mode->Clock >= min[i] && mode->Clock <= max[i]) {
+		good = TRUE;
+		break;
+	    }
+	}
+	if (!good)
+	    mode->status = MODE_CLOCK_RANGE;
+    }
+}
+
+/**
+ * If the user has specified a set of mode names to use, mark as bad any modes
+ * not listed.
+ *
+ * The user mode names specified are prefixes to names of modes, so "1024x768"
+ * will match modes named "1024x768", "1024x768x75", "1024x768-good", but
+ * "1024x768x75" would only match "1024x768x75" from that list.
+ *
+ * MODE_BAD is used as the rejection flag, for lack of a better flag.
+ *
+ * \param modeList doubly-linked or circular list of modes.
+ *
+ * This is not in xf86Modes.c, but would be part of the proposed new API.
+ */
+void
+RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+{
+    DisplayModePtr mode;
+
+    if (pScrn->display->modes[0] == NULL)
+	return;
+
+    for (mode = modeList; mode != NULL; mode = mode->next) {
+	int i;
+	Bool good = FALSE;
+
+	for (i = 0; pScrn->display->modes[i] != NULL; i++) {
+	    if (strncmp(pScrn->display->modes[i], mode->name,
+			strlen(pScrn->display->modes[i])) == 0) {
+		good = TRUE;
+		break;
+	    }
+	}
+	if (!good)
+	    mode->status = MODE_BAD;
+    }
+}
+
+
+/**
+ * Frees any modes from the list with a status other than MODE_OK.
+ *
+ * \param modeList pointer to a doubly-linked or circular list of modes.
+ * \param verbose determines whether the reason for mode invalidation is
+ *	  printed.
+ *
+ * This is not in xf86Modes.c, but would be part of the proposed new API.
+ */
+void
+RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+			  Bool verbose)
+{
+    DisplayModePtr mode;
+
+    for (mode = *modeList; mode != NULL;) {
+	DisplayModePtr next = mode->next, first = *modeList;
+
+	if (mode->status != MODE_OK) {
+	    if (verbose) {
+		char *type = "";
+		if (mode->type & M_T_BUILTIN)
+		    type = "built-in ";
+		else if (mode->type & M_T_DEFAULT)
+		    type = "default ";
+		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+			   "Not using %smode \"%s\" (%s)\n", type, mode->name,
+			   xf86ModeStatusToString(mode->status));
+	    }
+	    xf86DeleteMode(modeList, mode);
+	}
+
+	if (next == first)
+	    break;
+	mode = next;
+    }
+}
+
+#define MODEPREFIX(name) NULL, NULL, name, MODE_OK, M_T_DEFAULT
+#define MODESUFFIX       0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
+
+/**
+ * List of VESA established modes, taken from xf86DefaultModes but trimmed down.
+ * (not trimming should be harmless).
+ */
+DisplayModeRec RADEONxf86DefaultModes[] = {
+/* 640x350 @ 85Hz (VESA) hsync: 37.9kHz */
+	{MODEPREFIX("640x350"),31500, 640,672,736,832,0, 350,382,385,445,0, V_PHSYNC | V_NVSYNC, MODESUFFIX},
+	{MODEPREFIX("320x175"),15750, 320,336,368,416,0, 175,191,192,222,0, V_PHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 640x400 @ 85Hz (VESA) hsync: 37.9kHz */
+	{MODEPREFIX("640x400"),31500, 640,672,736,832,0, 400,401,404,445,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("320x200"),15750, 320,336,368,416,0, 200,200,202,222,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 720x400 @ 85Hz (VESA) hsync: 37.9kHz */
+	{MODEPREFIX("720x400"),35500, 720,756,828,936,0, 400,401,404,446,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("360x200"),17750, 360,378,414,468,0, 200,200,202,223,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 640x480 @ 72Hz (VESA) hsync: 37.9kHz */
+	{MODEPREFIX("640x480"),31500, 640,664,704,832,0, 480,489,491,520,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
+	{MODEPREFIX("320x240"),15750, 320,332,352,416,0, 240,244,245,260,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 640x480 @ 75Hz (VESA) hsync: 37.5kHz */
+	{MODEPREFIX("640x480"),31500, 640,656,720,840,0, 480,481,484,500,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
+	{MODEPREFIX("320x240"),15750, 320,328,360,420,0, 240,240,242,250,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 640x480 @ 85Hz (VESA) hsync: 43.3kHz */
+	{MODEPREFIX("640x480"),36000, 640,696,752,832,0, 480,481,484,509,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
+	{MODEPREFIX("320x240"),18000, 320,348,376,416,0, 240,240,242,254,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 800x600 @ 56Hz (VESA) hsync: 35.2kHz */
+	{MODEPREFIX("800x600"),36000, 800,824,896,1024,0, 600,601,603,625,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("400x300"),18000, 400,412,448,512,0, 300,300,301,312,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 800x600 @ 60Hz (VESA) hsync: 37.9kHz */
+	{MODEPREFIX("800x600"),40000, 800,840,968,1056,0, 600,601,605,628,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("400x300"),20000, 400,420,484,528,0, 300,300,302,314,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 800x600 @ 72Hz (VESA) hsync: 48.1kHz */
+	{MODEPREFIX("800x600"),50000, 800,856,976,1040,0, 600,637,643,666,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("400x300"),25000, 400,428,488,520,0, 300,318,321,333,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 800x600 @ 75Hz (VESA) hsync: 46.9kHz */
+	{MODEPREFIX("800x600"),49500, 800,816,896,1056,0, 600,601,604,625,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("400x300"),24750, 400,408,448,528,0, 300,300,302,312,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 800x600 @ 85Hz (VESA) hsync: 53.7kHz */
+	{MODEPREFIX("800x600"),56300, 800,832,896,1048,0, 600,601,604,631,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("400x300"),28150, 400,416,448,524,0, 300,300,302,315,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1024x768 @ 60Hz (VESA) hsync: 48.4kHz */
+	{MODEPREFIX("1024x768"),65000, 1024,1048,1184,1344,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
+	{MODEPREFIX("512x384"),32500, 512,524,592,672,0, 384,385,388,403,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1024x768 @ 70Hz (VESA) hsync: 56.5kHz */
+	{MODEPREFIX("1024x768"),75000, 1024,1048,1184,1328,0, 768,771,777,806,0, V_NHSYNC | V_NVSYNC, MODESUFFIX},
+	{MODEPREFIX("512x384"),37500, 512,524,592,664,0, 384,385,388,403,0, V_NHSYNC | V_NVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1024x768 @ 75Hz (VESA) hsync: 60.0kHz */
+	{MODEPREFIX("1024x768"),78800, 1024,1040,1136,1312,0, 768,769,772,800,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("512x384"),39400, 512,520,568,656,0, 384,384,386,400,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1024x768 @ 85Hz (VESA) hsync: 68.7kHz */
+	{MODEPREFIX("1024x768"),94500, 1024,1072,1168,1376,0, 768,769,772,808,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("512x384"),47250, 512,536,584,688,0, 384,384,386,404,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1152x864 @ 75Hz (VESA) hsync: 67.5kHz */
+	{MODEPREFIX("1152x864"),108000, 1152,1216,1344,1600,0, 864,865,868,900,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("576x432"),54000, 576,608,672,800,0, 432,432,434,450,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1280x960 @ 60Hz (VESA) hsync: 60.0kHz */
+	{MODEPREFIX("1280x960"),108000, 1280,1376,1488,1800,0, 960,961,964,1000,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("640x480"),54000, 640,688,744,900,0, 480,480,482,500,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1280x960 @ 85Hz (VESA) hsync: 85.9kHz */
+	{MODEPREFIX("1280x960"),148500, 1280,1344,1504,1728,0, 960,961,964,1011,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("640x480"),74250, 640,672,752,864,0, 480,480,482,505,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz */
+	{MODEPREFIX("1280x1024"),108000, 1280,1328,1440,1688,0, 1024,1025,1028,1066,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("640x512"),54000, 640,664,720,844,0, 512,512,514,533,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz */
+	{MODEPREFIX("1280x1024"),135000, 1280,1296,1440,1688,0, 1024,1025,1028,1066,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("640x512"),67500, 640,648,720,844,0, 512,512,514,533,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz */
+	{MODEPREFIX("1280x1024"),157500, 1280,1344,1504,1728,0, 1024,1025,1028,1072,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("640x512"),78750, 640,672,752,864,0, 512,512,514,536,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz */
+	{MODEPREFIX("1600x1200"),162000, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("800x600"),81000, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz */
+	{MODEPREFIX("1600x1200"),175500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("800x600"),87750, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz */
+	{MODEPREFIX("1600x1200"),189000, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("800x600"),94500, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz */
+	{MODEPREFIX("1600x1200"),202500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("800x600"),101250, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz */
+	{MODEPREFIX("1600x1200"),229500, 1600,1664,1856,2160,0, 1200,1201,1204,1250,0, V_PHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("800x600"),114750, 800,832,928,1080,0, 600,600,602,625,0, V_PHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz */
+	{MODEPREFIX("1792x1344"),204800, 1792,1920,2120,2448,0, 1344,1345,1348,1394,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("896x672"),102400, 896,960,1060,1224,0, 672,672,674,697,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz */
+	{MODEPREFIX("1792x1344"),261000, 1792,1888,2104,2456,0, 1344,1345,1348,1417,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("896x672"),130500, 896,944,1052,1228,0, 672,672,674,708,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz */
+	{MODEPREFIX("1856x1392"),218300, 1856,1952,2176,2528,0, 1392,1393,1396,1439,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("928x696"),109150, 928,976,1088,1264,0, 696,696,698,719,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz */
+	{MODEPREFIX("1856x1392"),288000, 1856,1984,2208,2560,0, 1392,1393,1396,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("928x696"),144000, 928,992,1104,1280,0, 696,696,698,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz */
+	{MODEPREFIX("1920x1440"),234000, 1920,2048,2256,2600,0, 1440,1441,1444,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("960x720"),117000, 960,1024,1128,1300,0, 720,720,722,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+/* 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz */
+	{MODEPREFIX("1920x1440"),297000, 1920,2064,2288,2640,0, 1440,1441,1444,1500,0, V_NHSYNC | V_PVSYNC, MODESUFFIX},
+	{MODEPREFIX("960x720"),148500, 960,1032,1144,1320,0, 720,720,722,750,0, V_NHSYNC | V_PVSYNC | V_DBLSCAN, MODESUFFIX},
+
+	/* Terminator */
+	{MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODESUFFIX}
+};
diff --git a/src/radeon_xf86Modes.h b/src/radeon_xf86Modes.h
new file mode 100644
index 0000000..a357a01
--- /dev/null
+++ b/src/radeon_xf86Modes.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Eric Anholt <eric at anholt.net>
+ *
+ */
+
+double
+RADEONxf86ModeHSync(DisplayModePtr mode);
+
+double
+RADEONxf86ModeVRefresh(DisplayModePtr mode);
+
+DisplayModePtr
+RADEONxf86DuplicateMode(DisplayModePtr pMode);
+
+DisplayModePtr
+RADEONxf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+
+void
+RADEONxf86SetModeDefaultName(DisplayModePtr mode);
+
+void
+RADEONxf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
+
+Bool
+RADEONModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
+
+void
+RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			    int flags);
+
+void
+RADEONxf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			    int *min, int *max, int n_ranges);
+
+void
+RADEONxf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			  int maxX, int maxY, int maxPitch);
+
+void
+RADEONxf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			  MonPtr mon);
+
+void
+RADEONxf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+			  Bool verbose);
+
+void
+RADEONxf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+			    int flags);
+
+void
+RADEONxf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+
+void
+PrintModeline(int scrnIndex,DisplayModePtr mode);
+
+extern DisplayModeRec RADEONxf86DefaultModes[];


More information about the xorg-commit mailing list