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

Alex Deucher agd5f at kemper.freedesktop.org
Fri May 11 09:07:42 PDT 2007


 src/radeon.h         |   22 --
 src/radeon_bios.c    |  124 ++++++-----
 src/radeon_display.c |  553 +++++++++++++++++++++++++++++++++++++++------------
 src/radeon_driver.c  |   93 ++++----
 src/radeon_modes.c   |   84 ++++---
 src/radeon_probe.h   |   23 ++
 src/radeon_video.c   |   34 ---
 7 files changed, 632 insertions(+), 301 deletions(-)

New commits:
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));


More information about the xorg-commit mailing list