rpms/xorg-x11/devel xorg-x11-6.8.2-radeon-display-bandwidth-calc-fix.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-fix-crtc2-offset-cntl.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-fix-divider-select.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-fix-mergedfb-bios-dividers.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-fix-one-mode-ddc.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-fix-pll-probing.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-lvds-probe-pll.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-no-vga.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-pll-errata-workarounds.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-pll2-tmds-no-odd-value.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-release-i2c-lines.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-reverse-ddc-option.patch, NONE, 1.1.2.1 xorg-x11-6.8.2-radeon-surface-cntl-dual-head.patch, NONE, 1.1.2.1 xorg-x11.spec, 1.193, 1.193.2.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed May 4 08:45:21 UTC 2005


Author: dwmw2

Update of /cvs/dist/rpms/xorg-x11/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv21254

Modified Files:
      Tag: private-fc4-radeon-branch
	xorg-x11.spec 
Added Files:
      Tag: private-fc4-radeon-branch
	xorg-x11-6.8.2-radeon-display-bandwidth-calc-fix.patch 
	xorg-x11-6.8.2-radeon-fix-crtc2-offset-cntl.patch 
	xorg-x11-6.8.2-radeon-fix-divider-select.patch 
	xorg-x11-6.8.2-radeon-fix-mergedfb-bios-dividers.patch 
	xorg-x11-6.8.2-radeon-fix-one-mode-ddc.patch 
	xorg-x11-6.8.2-radeon-fix-pll-probing.patch 
	xorg-x11-6.8.2-radeon-lvds-probe-pll.patch 
	xorg-x11-6.8.2-radeon-no-vga.patch 
	xorg-x11-6.8.2-radeon-pll-errata-workarounds.patch 
	xorg-x11-6.8.2-radeon-pll2-tmds-no-odd-value.patch 
	xorg-x11-6.8.2-radeon-release-i2c-lines.patch 
	xorg-x11-6.8.2-radeon-reverse-ddc-option.patch 
	xorg-x11-6.8.2-radeon-surface-cntl-dual-head.patch 
Log Message:
Ben's radeon patches

xorg-x11-6.8.2-radeon-display-bandwidth-calc-fix.patch:
 radeon_driver.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

--- NEW FILE xorg-x11-6.8.2-radeon-display-bandwidth-calc-fix.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:08.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:12.000000000 +1000
@@ -6104,7 +6104,7 @@
 	*/
 	temp = INREG(RADEON_MEM_CNTL);
 	data = (R300_MEM_NUM_CHANNELS_MASK & temp);
-	if (data == 2) {
+	if (data == 1) {
 	    if (R300_MEM_USE_CD_CH_ONLY & temp) {
 		temp  = INREG(R300_MC_IND_INDEX);
 		temp &= ~R300_MC_IND_ADDR_MASK;

xorg-x11-6.8.2-radeon-fix-crtc2-offset-cntl.patch:
 radeon_driver.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletion(-)

--- NEW FILE xorg-x11-6.8.2-radeon-fix-crtc2-offset-cntl.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:16.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:19.000000000 +1000
@@ -6491,8 +6491,12 @@
 				      ? RADEON_CRTC2_V_SYNC_POL
 				      : 0));
 
+    /* This version of the driver doesn't do tiling, make sure it is disabled
+     * as the BIOS may have enabled it. 0 is a sane value for CRTC2_OFFSET_CNTL
+     * based on the documentation
+     */
     save->crtc2_offset      = 0;
-    save->crtc2_offset_cntl = INREG(RADEON_CRTC2_OFFSET_CNTL);
+    save->crtc2_offset_cntl = 0;
     /* this should be right */
     if (info->MergedFB) {
     save->crtc2_pitch  = (((info->CRT2pScrn->displayWidth * pScrn->bitsPerPixel) +

xorg-x11-6.8.2-radeon-fix-divider-select.patch:
 radeon_driver.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-fix-divider-select.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:40:48.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:41:44.000000000 +1000
@@ -5453,8 +5453,13 @@
            By doing this we can avoid the blanking problem with some panels.
         */
         if ((restore->ppll_ref_div == (INPLL(pScrn, RADEON_PPLL_REF_DIV) & RADEON_PPLL_REF_DIV_MASK)) &&
-	    (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) & (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK))))
-            return;
+	    (restore->ppll_div_3 == (INPLL(pScrn, RADEON_PPLL_DIV_3) & 
+				     (RADEON_PPLL_POST3_DIV_MASK | RADEON_PPLL_FB3_DIV_MASK)))) {
+	    OUTREGP(RADEON_CLOCK_CNTL_INDEX,
+		    RADEON_PLL_DIV_SEL,
+		    ~(RADEON_PLL_DIV_SEL));
+	    return;
+	}
     }
 
     OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,

xorg-x11-6.8.2-radeon-fix-mergedfb-bios-dividers.patch:
 radeon_driver.c |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-fix-mergedfb-bios-dividers.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:50:52.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:50:58.000000000 +1000
@@ -6857,8 +6857,8 @@
 }
 
 /* Define PLL registers for requested video mode */
-static void RADEONInitPLLRegisters(RADEONSavePtr save, RADEONPLLPtr pll,
-				   double dot_clock)
+static void RADEONInitPLLRegisters(RADEONInfoPtr info, RADEONSavePtr save,
+                                  RADEONPLLPtr pll, double dot_clock)
 {
     unsigned long  freq = dot_clock * 100;
 
@@ -6882,6 +6882,13 @@
 	{  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;
 
@@ -7051,7 +7058,7 @@
             return FALSE;
         dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT1)->Clock / 1000.0;
         if (dot_clock) {
-            RADEONInitPLLRegisters(save, &info->pll, dot_clock);
+            RADEONInitPLLRegisters(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;
@@ -7066,13 +7073,7 @@
 	    return FALSE;
 	dot_clock = mode->Clock/1000.0;
 	if (dot_clock) {
-            if (info->UseBiosDividers) {
-                save->ppll_ref_div = info->RefDivider;
-                save->ppll_div_3   = info->FeedbackDivider | (info->PostDivider << 16);
-                save->htotal_cntl  = 0;
-            }
-            else
-		RADEONInitPLLRegisters(save, &info->pll, dot_clock);
+           RADEONInitPLLRegisters(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;

xorg-x11-6.8.2-radeon-fix-one-mode-ddc.patch:
 radeon_driver.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-fix-one-mode-ddc.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-14 15:26:08.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-14 15:26:56.000000000 +1000
@@ -3614,7 +3614,7 @@
 		}
 	    }
 
- 	    if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
+ 	    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.
@@ -3879,7 +3879,7 @@
 		}
 	    }
 
-	    if ((modesFound <= 1) || (user_modes_found < user_modes_asked)) {
+	    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.

xorg-x11-6.8.2-radeon-fix-pll-probing.patch:
 radeon_driver.c |  154 +++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 124 insertions(+), 30 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-fix-pll-probing.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:19.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:22.000000000 +1000
@@ -1186,41 +1186,59 @@
     return(bConnected ? MT_CRT : MT_NONE);
 }
 
-#if defined(__powerpc__)
 static Bool RADEONProbePLLParameters(ScrnInfoPtr pScrn)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
     RADEONPLLPtr  pll  = &info->pll;
     unsigned char *RADEONMMIO = info->MMIO;
     unsigned char ppll_div_sel;
-    unsigned Nx, M;
+    unsigned mpll_fb_div, spll_fb_div, M;
     unsigned xclk, tmp, ref_div;
     int hTotal, vTotal, num, denom, m, n;
-    float hz, vclk, xtal;
+    float hz, prev_xtal, vclk, xtal, mpll, spll;
     long start_secs, start_usecs, stop_secs, stop_usecs, total_usecs;
-    int i;
-
-    for(i=0; i<1000000; i++)
-	if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)
+    long to1_secs, to1_usecs, to2_secs, to2_usecs;
+    unsigned int f1, f2, f3;
+    int tries = 0;
+
+    prev_xtal = 0;
+ again:
+    xtal = 0;
+    if (++tries > 10)
+           goto failed;
+
+    xf86getsecs(&to1_secs, &to1_usecs);
+    f1 = INREG(RADEON_CRTC_CRNT_FRAME);
+    for (;;) {
+       f2 = INREG(RADEON_CRTC_CRNT_FRAME);
+       if (f1 != f2)
 	    break;
-
+       xf86getsecs(&to2_secs, &to2_usecs);
+       if ((to2_secs - to1_secs) > 1) {
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Clock not counting...\n");
+           goto failed;
+       }
+    }
     xf86getsecs(&start_secs, &start_usecs);
-
-    for(i=0; i<1000000; i++)
-	if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0)
-	    break;
-
-    for(i=0; i<1000000; i++)
-	if (((INREG(RADEON_CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0)
+    for(;;) {
+       f3 = INREG(RADEON_CRTC_CRNT_FRAME);
+       if (f3 != f2)
 	    break;
-
+       xf86getsecs(&to2_secs, &to2_usecs);
+       if ((to2_secs - start_secs) > 1)
+           goto failed;
+    }
     xf86getsecs(&stop_secs, &stop_usecs);
 
+    if ((stop_secs - start_secs) != 0)
+           goto again;
     total_usecs = abs(stop_usecs - start_usecs);
-    hz = 1000000/total_usecs;
+    if (total_usecs == 0)
+           goto again;
+    hz = 1000000.0/(float)total_usecs;
 
-    hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;
-    vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0x3ff) + 1);
+    hTotal = ((INREG(RADEON_CRTC_H_TOTAL_DISP) & 0x3ff) + 1) * 8;
+    vTotal = ((INREG(RADEON_CRTC_V_TOTAL_DISP) & 0xfff) + 1);
     vclk = (float)(hTotal * (float)(vTotal * hz));
 
     switch((INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x30000) >> 16) {
@@ -1243,8 +1261,7 @@
         break;
      }
 
-    OUTREG(RADEON_CLOCK_CNTL_INDEX, 1);
-    ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_DATA + 1) & 0x3;
+    ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
 
     n = (INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
     m = (INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff);
@@ -1282,23 +1299,93 @@
     else if ((xtal > 29400000) && (xtal < 29600000))
         xtal = 2950;
     else
-	return FALSE;
+       goto again;
+ failed:
+    if (xtal == 0) {
+       xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Failed to probe xtal value ! "
+                  "Using default 27Mhz\n");
+       xtal = 2700;
+    } else {
+       if (prev_xtal == 0) {
+           prev_xtal = xtal;
+           tries = 0;
+           goto again;
+       } else if (prev_xtal != xtal) {
+           prev_xtal = 0;
+           goto again;
+       }
+    }
 
     tmp = INPLL(pScrn, RADEON_X_MPLL_REF_FB_DIV);
     ref_div = INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff;
 
-    Nx = (tmp & 0xff00) >> 8;
+    /* Some sanity check based on the BIOS code .... */
+    if (ref_div < 2) {
+       CARD32 tmp;
+       tmp = INPLL(pScrn, RADEON_PPLL_REF_DIV);
+       if (IS_R300_VARIANT || (info->ChipFamily == CHIP_FAMILY_RS300))
+           ref_div = (tmp & R300_PPLL_REF_DIV_ACC_MASK) >>
+                   R300_PPLL_REF_DIV_ACC_SHIFT;
+       else
+           ref_div = tmp & RADEON_PPLL_REF_DIV_MASK;
+       if (ref_div < 2)
+           ref_div = 12;
+    }
+
+    /* Calculate "base" xclk straight from MPLL, though that isn't
+     * really useful (hopefully). This isn't called XCLK anymore on
+     * radeon's...
+     */
+    mpll_fb_div = (tmp & 0xff00) >> 8;
+    spll_fb_div = (tmp & 0xff0000) >> 16;
     M = (tmp & 0xff);
-    xclk = RADEONDiv((2 * Nx * xtal), (2 * M));
+    xclk = RADEONDiv((2 * mpll_fb_div * xtal), (M));
+
+    /*
+     * Calculate MCLK based on MCLK-A
+     */
+    mpll = (2.0 * (float)mpll_fb_div * (xtal / 100.0)) / (float)M;
+    spll = (2.0 * (float)spll_fb_div * (xtal / 100.0)) / (float)M;
+
+    tmp = INPLL(pScrn, RADEON_MCLK_CNTL) & 0x7;
+    switch(tmp) {
+    case 1: info->mclk = mpll; break;
+    case 2: info->mclk = mpll / 2.0; break;
+    case 3: info->mclk = mpll / 4.0; break;
+    case 4: info->mclk = mpll / 8.0; break;
+    case 7: info->mclk = spll; break;
+    default:
+           info->mclk = 200.00;
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported MCLKA source"
+                      " setting %d, can't probe MCLK value !\n", tmp);
+    }
+
+    /*
+     * Calculate SCLK
+     */
+    tmp = INPLL(pScrn, RADEON_SCLK_CNTL) & 0x7;
+    switch(tmp) {
+    case 1: info->sclk = spll; break;
+    case 2: info->sclk = spll / 2.0; break;
+    case 3: info->sclk = spll / 4.0; break;
+    case 4: info->sclk = spll / 8.0; break;
+    case 7: info->sclk = mpll;
+    default:
+           info->sclk = 200.00;
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unsupported SCLK source"
+                      " setting %d, can't probe SCLK value !\n", tmp);
+    }
 
     /* we're done, hopefully these are sane values */
     pll->reference_div = ref_div;
     pll->xclk = xclk;
     pll->reference_freq = xtal;
 
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Probed PLL values: xtal: %f Mhz, "
+              "sclk: %f Mhz, mclk: %f Mhz\n", xtal/100.0, info->sclk, info->mclk);
+
     return TRUE;
 }
-#endif
 
 static void RADEONGetPanelInfoFromReg (ScrnInfoPtr pScrn)
 {
@@ -1450,17 +1537,24 @@
 	xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
 		    "Video BIOS not detected, using default clock settings!\n");
 
-#if defined(__powerpc__)
-	if (RADEONProbePLLParameters(pScrn)) return;
-#endif
+       /* Default min/max PLL values */
+       if (info->ChipFamily == CHIP_FAMILY_R420) {
+           pll->min_pll_freq = 20000;
+           pll->max_pll_freq = 50000;
+       } else {
+           pll->min_pll_freq = 12500;
+           pll->max_pll_freq = 35000;
+       }
+
+       if (RADEONProbePLLParameters(pScrn))
+            return;
+
 	if (info->IsIGP)
 	    pll->reference_freq = 1432;
 	else
 	    pll->reference_freq = 2700;
 
 	pll->reference_div = 12;
-	pll->min_pll_freq = 12500;
-	pll->max_pll_freq = 35000;
 	pll->xclk = 10300;
 
         info->sclk = 200.00;

xorg-x11-6.8.2-radeon-lvds-probe-pll.patch:
 radeon.man      |   10 ++++
 radeon_driver.c |  118 ++++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 91 insertions(+), 37 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-lvds-probe-pll.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:02:39.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:11:48.000000000 +1000
@@ -118,6 +118,7 @@
 static void RADEONGetMergedFBOptions(ScrnInfoPtr pScrn);
 static int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
+static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn);
 
 /* psuedo xinerama support */
 
@@ -166,6 +167,7 @@
     OPTION_SHOWCACHE,
     OPTION_VGA_ACCESS,
     OPTION_REVERSE_DDC,
+    OPTION_LVDS_PROBE_PLL,
     OPTION_DYNAMIC_CLOCKS
 } RADEONOpts;
 
@@ -213,6 +215,7 @@
     { OPTION_DYNAMIC_CLOCKS, "DynamicClocks",    OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_VGA_ACCESS,     "VGAAccess",        OPTV_BOOLEAN, {0}, TRUE  },
     { OPTION_REVERSE_DDC,    "ReverseDDC",       OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_LVDS_PROBE_PLL, "LVDSProbePLL",     OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
@@ -1412,7 +1415,25 @@
 	info->PanelXRes = 640;
 	info->PanelYRes = 480;
     }
-    
+
+    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",
@@ -1426,17 +1447,24 @@
     if (!RADEONGetLVDSInfoFromBIOS(pScrn))
         RADEONGetPanelInfoFromReg(pScrn);
 
+    /* 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);
+
+    /* 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.
+     */
     if (info->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 == info->PanelXRes) &&
@@ -1507,6 +1535,8 @@
             RADEONGetTMDSInfo(pScrn);
             if (!pScrn->monitor->DDC)
                 RADEONGetHardCodedEDIDFromBIOS(pScrn);
+            else if (!info->IsSecondary)
+               RADEONUpdatePanelSize(pScrn);
         }
     }
 }
@@ -2705,16 +2735,35 @@
     xf86MonPtr      ddc  = pScrn->monitor->DDC;
     DisplayModePtr  p;
 
+    if (info->UseBiosDividers && info->DotClock != 0)
+       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;
-	    if (info->PanelXRes <= d_timings->h_active &&
-		info->PanelYRes <= d_timings->v_active) {
+           int match = 0;
 
-		if (info->DotClock) continue; /* Timings already inited */
+           /* 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 (info->DotClock == 0 &&
+               info->PanelXRes == d_timings->h_active &&
+               info->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)
+               match = 1;
+
+             if (match) {
 		info->PanelXRes  = d_timings->h_active;
 		info->PanelYRes  = d_timings->v_active;
 		info->DotClock   = d_timings->clock / 1000;
@@ -2724,10 +2773,24 @@
 		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);
+                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;
+                   }
+                }
+                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
+                           info->PanelXRes, info->PanelYRes);
 	    }
 	}
     }
 
+    if (info->UseBiosDividers && info->DotClock != 0)
+       return;
+
     /* Search thru standard VESA modes from EDID */
     for (j = 0; j < 8; j++) {
 	if ((info->PanelXRes < ddc->timings2[j].hsize) &&
@@ -2749,26 +2812,14 @@
 			info->VOverPlus  = p->VSyncStart - p->VDisplay;
 			info->VSyncWidth = p->VSyncEnd - p->VSyncStart;
 			info->DotClock   = p->Clock;
-			info->Flags      =
-			    (ddc->det_mon[j].section.d_timings.interlaced
-			     ? V_INTERLACE
-			     : 0);
-			if (ddc->det_mon[j].section.d_timings.sync == 3) {
-			    switch (ddc->det_mon[j].section.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;
-			    }
-			}
+                        info->Flags      = p->Flags;
+                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC VESA/EDID: %dx%d\n",
+                                   info->PanelXRes, info->PanelYRes);
 		    }
 		}
 	    }
 	}
     }
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel size found from DDC: %dx%d\n",
-	       info->PanelXRes, info->PanelYRes);
 }
 
 /* This function will sort all modes according to their resolution.
@@ -2889,6 +2940,8 @@
 
     /* 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) &&
@@ -2978,19 +3031,10 @@
     pScrn->virtualX = pScrn1->display->virtualX;
     pScrn->virtualY = pScrn1->display->virtualY;
 
-    if (pScrn->monitor->DDC && !info->UseBiosDividers) {
+    if (pScrn->monitor->DDC) {
 	int  maxVirtX = pScrn->virtualX;
 	int  maxVirtY = pScrn->virtualY;
 
-	if ((DisplayType != MT_CRT) && (!info->IsSecondary) && (!crtc2)) {
-	    /* 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);
-	}
-
 	/* Collect all of the DDC modes */
 	first = last = ddcModes = RADEONDDCModes(pScrn);
 
@@ -3682,7 +3726,8 @@
 		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
 			   "Invalid PanelSize value: %s\n", s);
 	    }
-	}
+        } else
+            RADEONGetPanelInfo(pScrn);
     }
 
     if (pScrn->monitor->DDC) {
@@ -4361,7 +4406,6 @@
     RADEONGetBIOSInfo(pScrn, pInt10);
     if (!RADEONQueryConnectedMonitors(pScrn))    goto fail;
     RADEONGetClockInfo(pScrn);
-    RADEONGetPanelInfo(pScrn);
 
     /* collect MergedFB options */
     /* only parse mergedfb options on the primary head. 
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.man
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.man	2005-04-12 16:03:23.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.man	2005-04-12 16:12:36.000000000 +1000
@@ -512,6 +512,16 @@
 typically needed on the Radeon 9600 cards bundled with Apple G5s. The
 default is
 .B off.
+.TP
+.BI "Option \*qLVDSProbePLL\*q \*q" boolean \*q
+When BIOS panel informations aren't available (like on PowerBooks), it
+may still be necessary to use the firmware provided PLL values for the
+panel or flickering will happen. This option will force probing of
+the current value programmed in the chip when X is launched in that
+case.  This is only useful for LVDS panels (laptop internal panels).
+The default is
+.B on.
+.TP
 
 .SH SEE ALSO
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)

xorg-x11-6.8.2-radeon-no-vga.patch:
 radeon.h        |    2 +
 radeon.man      |   11 +++++
 radeon_driver.c |  112 ++++++++++++++++++++++++++++++++++++--------------------
 3 files changed, 85 insertions(+), 40 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-no-vga.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2004-12-17 11:13:18.000000000 +1100
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:50:29.000000000 +1000
@@ -164,6 +164,7 @@
     OPTION_SUBPIXEL_ORDER,
 #endif
     OPTION_SHOWCACHE,
+    OPTION_VGA_ACCESS,
     OPTION_DYNAMIC_CLOCKS
 } RADEONOpts;
 
@@ -209,6 +210,7 @@
 #endif
     { OPTION_SHOWCACHE,      "ShowCache",        OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DYNAMIC_CLOCKS, "DynamicClocks",    OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_VGA_ACCESS,     "VGAAccess",        OPTV_BOOLEAN, {0}, TRUE  },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
@@ -4143,14 +4145,6 @@
 	return TRUE;
     }
 
-    if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE;
-    xf86LoaderReqSymLists(vgahwSymbols, NULL);
-    if (!vgaHWGetHWRec(pScrn)) {
-	RADEONFreeRec(pScrn);
-	goto fail2;
-    }
-
-    vgaHWGetIOBase(VGAHWPTR(pScrn));
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "PCI bus %d card %d func %d\n",
@@ -4179,6 +4173,32 @@
     memcpy(info->Options, RADEONOptions, sizeof(RADEONOptions));
     xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
 
+    /* By default, don't do VGA IOs on ppc */
+#ifdef __powerpc__
+    info->VGAAccess = FALSE;
+#else
+    info->VGAAccess = TRUE;
+#endif
+
+    xf86GetOptValBool(info->Options, OPTION_VGA_ACCESS, &info->VGAAccess);
+    if (info->VGAAccess) {
+       if (!xf86LoadSubModule(pScrn, "vgahw"))
+           info->VGAAccess = FALSE;
+        else {
+           xf86LoaderReqSymLists(vgahwSymbols, NULL);
+            if (!vgaHWGetHWRec(pScrn))
+               info->VGAAccess = FALSE;
+       }
+       if (!info->VGAAccess)
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Loading VGA module failed,"
+                      " trying to run without it\n");
+    } else
+           xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VGAAccess option set to FALSE,"
+                      " VGA module load skipped\n");
+    if (info->VGAAccess)
+        vgaHWGetIOBase(VGAHWPTR(pScrn));
+
+
     if (!RADEONPreInitWeight(pScrn))
 	goto fail;
 
@@ -4293,7 +4313,8 @@
     if (pInt10)
 	xf86FreeInt10(pInt10);
 
-    vgaHWFreeHWRec(pScrn);
+    if (info->VGAAccess)
+           vgaHWFreeHWRec(pScrn);
 
  fail2:
     if(info->MMIO) RADEONUnmapMMIO(pScrn);
@@ -5731,7 +5752,6 @@
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  save       = &info->SavedReg;
-    vgaHWPtr       hwp        = VGAHWPTR(pScrn);
 
     RADEONTRACE(("RADEONSave\n"));
     if (info->FBDev) {
@@ -5740,19 +5760,23 @@
     }
 
     if (!info->IsSecondary) {
-	vgaHWUnlock(hwp);
+        if (info->VGAAccess) {
+           vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+            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
-	 */
-	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
-	vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS); /* Save mode
-						       * & fonts & cmap
-						       */
+           /* Save mode * & fonts & cmap */
+           vgaHWSave(pScrn, &hwp->SavedReg, VGA_SR_MODE | VGA_SR_FONTS);
 #endif
-	vgaHWLock(hwp);
+           vgaHWLock(hwp);
+       }
 	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);
@@ -5768,7 +5792,6 @@
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONSavePtr  restore    = &info->SavedReg;
-    vgaHWPtr       hwp        = VGAHWPTR(pScrn);
 
     RADEONTRACE(("RADEONRestore\n"));
 
@@ -5810,27 +5833,36 @@
     usleep(100000);
 #endif
 
-    if (!info->IsSecondary) {
-	vgaHWUnlock(hwp);
+    if (info->VGAAccess) {
+       vgaHWPtr hwp = VGAHWPTR(pScrn);
+        if (!info->IsSecondary) {
+            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;
-	vgaHWPtr      hwp0;
-
-	pScrn0 = pRADEONEnt->pPrimaryScrn;
-	hwp0   = VGAHWPTR(pScrn0);
-	vgaHWUnlock(hwp0);
-	vgaHWRestore(pScrn0, &hwp0->SavedReg, VGA_SR_MODE | VGA_SR_FONTS );
-	vgaHWLock(hwp0);
+           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);
+           }
+       }
     }
     RADEONUnblank(pScrn);
 
@@ -7349,7 +7381,7 @@
        }
     }
 
-    if (xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
+    if (info->VGAAccess && xf86LoaderCheckSymbol("vgaHWFreeHWRec"))
 	vgaHWFreeHWRec(pScrn);
     RADEONFreeRec(pScrn);
 }
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.man
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.man	2004-09-04 09:26:19.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.man	2005-04-12 14:37:58.000000000 +1000
@@ -494,6 +494,17 @@
 with this enabled.  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
+shouldn't be if the console is using radeonfb or some other graphic
+mode driver. Some platforms like PowerPC have issues with those, and they aren't
+necessary unless you have a real text mode in console. The default is
+.B off
+on PowerPC and
+.B on
+on other architectures.
+.TP
 
 .SH SEE ALSO
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h	2005-01-25 14:20:12.000000000 +1100
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.h	2005-04-12 14:37:58.000000000 +1000
@@ -596,6 +596,8 @@
 
     /* special handlings for DELL triple-head server */
     Bool		IsDellServer; 
+
+    Bool		VGAAccess;
 } RADEONInfoRec, *RADEONInfoPtr;
 
 

xorg-x11-6.8.2-radeon-pll-errata-workarounds.patch:
 radeon.h        |   16 +++++
 radeon_accel.c  |    6 +-
 radeon_driver.c |  157 +++++++++++++++++++++++++++++++++++++-------------------
 radeon_macros.h |   10 ---
 radeon_video.c  |    9 +--
 5 files changed, 132 insertions(+), 66 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-pll-errata-workarounds.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:42:38.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:45:43.000000000 +1000
@@ -691,24 +691,49 @@
     return TRUE;
 }
 
-/* This function is required to workaround a hardware bug in some (all?)
- * revisions of the R300.  This workaround should be called after every
- * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
- * may not be correct.
- */
-void R300CGWorkaround(ScrnInfoPtr pScrn) {
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+void RADEONPllErrataAfterIndex(RADEONInfoPtr info)
+{
     unsigned char *RADEONMMIO = info->MMIO;
-    CARD32         save, tmp;
+	
+    if (!(info->ChipErrata & CHIP_ERRATA_PLL_DUMMYREADS))
+	return;
 
-    save = INREG(RADEON_CLOCK_CNTL_INDEX);
-    tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
-    OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);
-    tmp = INREG(RADEON_CLOCK_CNTL_DATA);
-    OUTREG(RADEON_CLOCK_CNTL_INDEX, save);
+    /* This workaround is necessary on rv200 and RS200 or PLL
+     * reads may return garbage (among others...)
+     */
+    (void)INREG(RADEON_CLOCK_CNTL_DATA);
+    (void)INREG(RADEON_CRTC_GEN_CNTL);
 }
 
-/* Read PLL information */
+void RADEONPllErrataAfterData(RADEONInfoPtr info)
+{
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    /* This workarounds is necessary on RV100, RS100 and RS200 chips
+     * or the chip could hang on a subsequent access
+     */
+    if (info->ChipErrata & CHIP_ERRATA_PLL_DELAY) {
+	/* we can't deal with posted writes here ... */
+	usleep(5000);
+    }
+
+    /* This function is required to workaround a hardware bug in some (all?)
+     * revisions of the R300.  This workaround should be called after every
+     * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
+     * may not be correct.
+     */
+    if (info->ChipErrata & CHIP_ERRATA_R300_CG) {
+	CARD32         save, tmp;
+
+	save = INREG(RADEON_CLOCK_CNTL_INDEX);
+	tmp = save & ~(0x3f | RADEON_PLL_WR_EN);
+	OUTREG(RADEON_CLOCK_CNTL_INDEX, tmp);
+	tmp = INREG(RADEON_CLOCK_CNTL_DATA);
+	OUTREG(RADEON_CLOCK_CNTL_INDEX, save);
+    }
+}
+
+/* Read PLL register */
 unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
@@ -716,12 +741,27 @@
     CARD32         data;
 
     OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
+    RADEONPllErrataAfterIndex(info);
     data = INREG(RADEON_CLOCK_CNTL_DATA);
-    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+    RADEONPllErrataAfterData(info);
 
     return data;
 }
 
+/* Write PLL information */
+void RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, CARD32 data)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+
+    OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) |
+				      RADEON_PLL_WR_EN));
+    RADEONPllErrataAfterIndex(info);
+    OUTREG(RADEON_CLOCK_CNTL_DATA, data);
+    RADEONPllErrataAfterData(info);
+}
+
+
 #if 0
 /* Read PAL information (only used for debugging) */
 static int RADEONINPAL(int idx)
@@ -1267,6 +1307,7 @@
      }
 
     ppll_div_sel = INREG8(RADEON_CLOCK_CNTL_INDEX + 1) & 0x3;
+    RADEONPllErrataAfterIndex(info);
 
     n = (INPLL(pScrn, RADEON_PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
     m = (INPLL(pScrn, RADEON_PPLL_REF_DIV) & 0x3ff);
@@ -2536,10 +2577,22 @@
 	info1->MergedFB = FALSE;
     }
 
-    info->R300CGWorkaround =
-	(info->ChipFamily == CHIP_FAMILY_R300 &&
-	 (INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
-	 == RADEON_CFG_ATI_REV_A11);
+    /* Check chip errata */
+    info->ChipErrata = 0;
+
+    if (info->ChipFamily == CHIP_FAMILY_R300 &&
+	(INREG(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK)
+	== RADEON_CFG_ATI_REV_A11)
+	    info->ChipErrata |= CHIP_ERRATA_R300_CG;
+
+    if (info->ChipFamily == CHIP_FAMILY_RV200 ||
+	info->ChipFamily == CHIP_FAMILY_RS200)
+	    info->ChipErrata |= CHIP_ERRATA_PLL_DUMMYREADS;
+
+    if (info->ChipFamily == CHIP_FAMILY_RV100 ||
+	info->ChipFamily == CHIP_FAMILY_RS100 ||
+	info->ChipFamily == CHIP_FAMILY_RS200)
+	    info->ChipErrata |= CHIP_ERRATA_PLL_DELAY;
 
     info->MemCntl            = INREG(RADEON_SDRAM_MODE_REG);
     info->BusCntl            = INREG(RADEON_BUS_CNTL);
@@ -5380,7 +5433,7 @@
 
 	if (info->IsMobility || info->IsIGP) {
 	    if (!(restore->lvds_gen_cntl & RADEON_LVDS_ON)) {
-		OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 	    }
 	}
     }
@@ -5458,6 +5511,7 @@
 	    OUTREGP(RADEON_CLOCK_CNTL_INDEX,
 		    RADEON_PLL_DIV_SEL,
 		    ~(RADEON_PLL_DIV_SEL));
+	    RADEONPllErrataAfterIndex(info);
 	    return;
 	}
     }
@@ -5478,6 +5532,7 @@
     OUTREGP(RADEON_CLOCK_CNTL_INDEX,
 	    RADEON_PLL_DIV_SEL,
 	    ~(RADEON_PLL_DIV_SEL));
+    RADEONPllErrataAfterIndex(info);
 
     if (IS_R300_VARIANT ||
 	(info->ChipFamily == CHIP_FAMILY_RS300)) {
@@ -5511,7 +5566,7 @@
     RADEONPLLWriteUpdate(pScrn);
     RADEONPLLWaitForReadUpdateComplete(pScrn);
 
-    OUTPLL(RADEON_HTOTAL_CNTL, restore->htotal_cntl);
+    OUTPLL(pScrn, RADEON_HTOTAL_CNTL, restore->htotal_cntl);
 
     OUTPLLP(pScrn, RADEON_PPLL_CNTL,
 	    0,
@@ -5573,7 +5628,7 @@
     RADEONPLL2WriteUpdate(pScrn);
     RADEONPLL2WaitForReadUpdateComplete(pScrn);
 
-    OUTPLL(RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
+    OUTPLL(pScrn, RADEON_HTOTAL2_CNTL, restore->htotal_cntl2);
 
     OUTPLLP(pScrn, RADEON_P2PLL_CNTL,
 	    0,
@@ -5933,7 +5988,7 @@
 	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);
-	if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+	RADEONPllErrataAfterIndex(info);
     }
 
     RADEONSaveMode(pScrn, save);
@@ -5960,7 +6015,7 @@
     RADEONBlank(pScrn);
 
     OUTREG(RADEON_CLOCK_CNTL_INDEX, restore->clock_cntl_index);
-    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+    RADEONPllErrataAfterIndex(info);
     OUTREG(RADEON_RBBM_SOFT_RESET,  restore->rbbm_soft_reset);
     OUTREG(RADEON_DP_DATATYPE,      restore->dp_datatype);
     OUTREG(RADEON_GRPH_BUFFER_CNTL, restore->grph_buffer_cntl);
@@ -7791,7 +7846,7 @@
 			     ~(RADEON_LVDS_BLON | RADEON_LVDS_ON));
 
 		    if (info->IsMobility || info->IsIGP) {
-			OUTPLL(RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
+			OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmpPixclksCntl);
 		    }
 		} else if (info->DisplayType == MT_CRT) {
 		    if ((pRADEONEnt->HasSecondary) || info->MergedFB) {
@@ -8012,14 +8067,14 @@
 			RADEON_SCLK_FORCE_RE   | RADEON_SCLK_FORCE_PB  |
 			RADEON_SCLK_FORCE_TAM  | RADEON_SCLK_FORCE_TDM |
                         RADEON_SCLK_FORCE_RB);
-                OUTPLL(RADEON_SCLK_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
             } else if (info->ChipFamily == CHIP_FAMILY_RV350) {
                 /* for RV350/M10, no delays are required. */
                 tmp = INPLL(pScrn, R300_SCLK_CNTL2);
                 tmp |= (R300_SCLK_FORCE_TCL |
                         R300_SCLK_FORCE_GA  |
 			R300_SCLK_FORCE_CBA);
-                OUTPLL(R300_SCLK_CNTL2, tmp);
+                OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
 
                 tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
                 tmp |= (RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP      |
@@ -8030,11 +8085,11 @@
 			R300_SCLK_FORCE_PX      | R300_SCLK_FORCE_TX        |
 			R300_SCLK_FORCE_US      | RADEON_SCLK_FORCE_TV_SCLK |
                         R300_SCLK_FORCE_SU      | RADEON_SCLK_FORCE_OV0);
-                OUTPLL(RADEON_SCLK_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
 
                 tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
                 tmp |= RADEON_SCLK_MORE_FORCEON;
-                OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
 
                 tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
                 tmp |= (RADEON_FORCEON_MCLKA |
@@ -8042,13 +8097,13 @@
                         RADEON_FORCEON_YCLKA |
 			RADEON_FORCEON_YCLKB |
                         RADEON_FORCEON_MC);
-                OUTPLL(RADEON_MCLK_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
 
                 tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
                 tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb  | 
                          RADEON_PIXCLK_DAC_ALWAYS_ONb | 
 			 R300_DISP_DAC_PIXCLK_DAC_BLANK_OFF); 
-                OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
 
                 tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
                 tmp &= ~(RADEON_PIX2CLK_ALWAYS_ONb         | 
@@ -8065,7 +8120,7 @@
 			 R300_P2G2CLK_ALWAYS_ONb            | 
 			 R300_P2G2CLK_ALWAYS_ONb           | 
 			 R300_DISP_DAC_PIXCLK_DAC2_BLANK_OFF); 
-                OUTPLL(RADEON_PIXCLKS_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
             }  else {
                 tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
                 tmp |= (RADEON_SCLK_FORCE_CP | RADEON_SCLK_FORCE_E2);
@@ -8102,7 +8157,7 @@
                     tmp |= ( R300_SCLK_FORCE_TCL |
 			     R300_SCLK_FORCE_GA  |
 			     R300_SCLK_FORCE_CBA);
-                    OUTPLL(R300_SCLK_CNTL2, tmp);
+                    OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
 		    usleep(16000);
 		}
 
@@ -8119,7 +8174,7 @@
 		    (info->ChipFamily == CHIP_FAMILY_RV280)) {
                     tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
 		    tmp |= RADEON_SCLK_MORE_FORCEON;
-                    OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+                    OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
 		    usleep(16000);
 		}
 
@@ -8138,7 +8193,7 @@
                 tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
                 tmp &= ~(RADEON_PIXCLK_ALWAYS_ONb  |
 			 RADEON_PIXCLK_DAC_ALWAYS_ONb); 
-                OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
 	    }
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Disabled\n");
             break;
@@ -8154,7 +8209,7 @@
 			 RADEON_SCLK_FORCE_IDCT | RADEON_SCLK_FORCE_RE   |
 			 RADEON_SCLK_FORCE_PB   | RADEON_SCLK_FORCE_TAM  |
 			 RADEON_SCLK_FORCE_TDM);
-                OUTPLL (RADEON_SCLK_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
 	    } else if ((info->ChipFamily == CHIP_FAMILY_R300) ||
 		       (info->ChipFamily == CHIP_FAMILY_R350) ||
 		       (info->ChipFamily == CHIP_FAMILY_RV350)) {
@@ -8166,7 +8221,7 @@
 		    tmp |=  (R300_SCLK_TCL_MAX_DYN_STOP_LAT |
 			     R300_SCLK_GA_MAX_DYN_STOP_LAT  |
 			     R300_SCLK_CBA_MAX_DYN_STOP_LAT);
-		    OUTPLL(R300_SCLK_CNTL2, tmp);
+		    OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
 
 		    tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
 		    tmp &= ~(RADEON_SCLK_FORCE_DISP2 | RADEON_SCLK_FORCE_CP      |
@@ -8178,17 +8233,17 @@
 			     R300_SCLK_FORCE_US      | RADEON_SCLK_FORCE_TV_SCLK |
 			     R300_SCLK_FORCE_SU      | RADEON_SCLK_FORCE_OV0);
 		    tmp |=  RADEON_DYN_STOP_LAT_MASK;
-		    OUTPLL(RADEON_SCLK_CNTL, tmp);
+		    OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
 
 		    tmp = INPLL(pScrn, RADEON_SCLK_MORE_CNTL);
 		    tmp &= ~RADEON_SCLK_MORE_FORCEON;
 		    tmp |=  RADEON_SCLK_MORE_MAX_DYN_STOP_LAT;
-		    OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+		    OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
 
 		    tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
 		    tmp |= (RADEON_PIXCLK_ALWAYS_ONb |
 			    RADEON_PIXCLK_DAC_ALWAYS_ONb);   
-		    OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+		    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
 
 		    tmp = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
 		    tmp |= (RADEON_PIX2CLK_ALWAYS_ONb         |
@@ -8204,12 +8259,12 @@
 			    R300_PIXCLK_TVO_ALWAYS_ONb        |
 			    R300_P2G2CLK_ALWAYS_ONb           |
 			    R300_P2G2CLK_ALWAYS_ONb);
-		    OUTPLL(RADEON_PIXCLKS_CNTL, tmp);
+		    OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
 
 		    tmp = INPLL(pScrn, RADEON_MCLK_MISC);
 		    tmp |= (RADEON_MC_MCLK_DYN_ENABLE |
 			    RADEON_IO_MCLK_DYN_ENABLE);
-		    OUTPLL(RADEON_MCLK_MISC, tmp);
+		    OUTPLL(pScrn, RADEON_MCLK_MISC, tmp);
 
 		    tmp = INPLL(pScrn, RADEON_MCLK_CNTL);
 		    tmp |= (RADEON_FORCEON_MCLKA |
@@ -8238,19 +8293,19 @@
 			}
 		    }
 
-		    OUTPLL(RADEON_MCLK_CNTL, tmp);
+		    OUTPLL(pScrn, RADEON_MCLK_CNTL, tmp);
 		} else {
 		    tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
 		    tmp &= ~(R300_SCLK_FORCE_VAP);
 		    tmp |= RADEON_SCLK_FORCE_CP;
-		    OUTPLL(RADEON_SCLK_CNTL, tmp);
+		    OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
 		    usleep(15000);
 
 		    tmp = INPLL(pScrn, R300_SCLK_CNTL2);
 		    tmp &= ~(R300_SCLK_FORCE_TCL |
 			     R300_SCLK_FORCE_GA  |
 			     R300_SCLK_FORCE_CBA);
-		    OUTPLL(R300_SCLK_CNTL2, tmp);
+		    OUTPLL(pScrn, R300_SCLK_CNTL2, tmp);
 		}
 	    } else {
                 tmp = INPLL(pScrn, RADEON_CLK_PWRMGT_CNTL);
@@ -8261,12 +8316,12 @@
 
                 tmp |= (RADEON_ENGIN_DYNCLK_MODE |
 			(0x01 << RADEON_ACTIVE_HILO_LAT_SHIFT));
-                OUTPLL(RADEON_CLK_PWRMGT_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_CLK_PWRMGT_CNTL, tmp);
 		usleep(15000);
 
                 tmp = INPLL(pScrn, RADEON_CLK_PIN_CNTL);
                 tmp |= RADEON_SCLK_DYN_START_CNTL; 
-                OUTPLL(RADEON_CLK_PIN_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_CLK_PIN_CNTL, tmp);
 		usleep(15000);
 
 		/* When DRI is enabled, setting DYN_STOP_LAT to zero can cause some R200 
@@ -8287,7 +8342,7 @@
                     tmp |= RADEON_SCLK_FORCE_VIP;
                 }
 
-                OUTPLL(RADEON_SCLK_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_SCLK_CNTL, tmp);
 
 		if ((info->ChipFamily == CHIP_FAMILY_RV200) ||
 		    (info->ChipFamily == CHIP_FAMILY_RV250) ||
@@ -8302,7 +8357,7 @@
 			 RADEON_CFG_ATI_REV_A13)) {
                         tmp |= RADEON_SCLK_MORE_FORCEON;
 		    }
-                    OUTPLL(RADEON_SCLK_MORE_CNTL, tmp);
+                    OUTPLL(pScrn, RADEON_SCLK_MORE_CNTL, tmp);
 		    usleep(15000);
                 }
 
@@ -8327,14 +8382,14 @@
 			 RADEON_PIXCLK_LVDS_ALWAYS_ONb     |
 			 RADEON_PIXCLK_TMDS_ALWAYS_ONb);
 
-		OUTPLL(RADEON_PIXCLKS_CNTL, tmp);
+		OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
 		usleep(15000);
 
 		tmp = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
 		tmp |= (RADEON_PIXCLK_ALWAYS_ONb  |
 		        RADEON_PIXCLK_DAC_ALWAYS_ONb); 
 
-                OUTPLL(RADEON_VCLK_ECP_CNTL, tmp);
+                OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, tmp);
 		usleep(15000);
             }    
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dynamic Clock Scaling Enabled\n");
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.h
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.h	2005-04-12 16:40:48.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.h	2005-04-12 16:42:39.000000000 +1000
@@ -273,6 +273,16 @@
         (info->ChipFamily == CHIP_FAMILY_RV380) ||  \
         (info->ChipFamily == CHIP_FAMILY_R420))
 
+/*
+ * Errata workarounds
+ */
+typedef enum {
+       CHIP_ERRATA_R300_CG             = 0x00000001,
+       CHIP_ERRATA_PLL_DUMMYREADS      = 0x00000002,
+       CHIP_ERRATA_PLL_DELAY           = 0x00000004
+} RADEONErrata;
+
+
 
 typedef struct {
     CARD32 freq;
@@ -285,6 +295,7 @@
     PCITAG            PciTag;
     int               Chipset;
     RADEONChipFamily  ChipFamily;
+    RADEONErrata      ChipErrata;
 
     Bool              FBDev;
 
@@ -623,6 +634,8 @@
 extern void        RADEONEngineRestore(ScrnInfoPtr pScrn);
 
 extern unsigned    RADEONINPLL(ScrnInfoPtr pScrn, int addr);
+extern void        RADEONOUTPLL(ScrnInfoPtr pScrn, int addr, CARD32 data);
+
 extern void        RADEONWaitForVerticalSync(ScrnInfoPtr pScrn);
 extern void        RADEONWaitForVerticalSync2(ScrnInfoPtr pScrn);
 
@@ -640,6 +653,9 @@
 extern void        RADEONResetVideo(ScrnInfoPtr pScrn);
 extern void        R300CGWorkaround(ScrnInfoPtr pScrn);
 
+extern void        RADEONPllErrataAfterIndex(RADEONInfoPtr info);
+extern void        RADEONPllErrataAfterData(RADEONInfoPtr info);
+
 #ifdef XF86DRI
 extern void        RADEONAccelInitCP(ScreenPtr pScreen, XAAInfoRecPtr a);
 extern Bool        RADEONDRIScreenInit(ScreenPtr pScreen);
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_macros.h
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_macros.h	2005-04-12 16:40:48.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_macros.h	2005-04-12 16:42:39.000000000 +1000
@@ -84,19 +84,14 @@
 
 #define INPLL(pScrn, addr) RADEONINPLL(pScrn, addr)
 
-#define OUTPLL(addr, val)						\
-do {									\
-    OUTREG8(RADEON_CLOCK_CNTL_INDEX, (((addr) & 0x3f) |			\
-				      RADEON_PLL_WR_EN));		\
-    OUTREG(RADEON_CLOCK_CNTL_DATA, val);				\
-} while (0)
+#define OUTPLL(pScrn, addr, val) RADEONOUTPLL(pScrn, addr, val)
 
 #define OUTPLLP(pScrn, addr, val, mask)					\
 do {									\
     CARD32 tmp_ = INPLL(pScrn, addr);					\
     tmp_ &= (mask);							\
     tmp_ |= (val);							\
-    OUTPLL(addr, tmp_);							\
+    OUTPLL(pScrn, addr, tmp_);						\
 } while (0)
 
 #define OUTPAL_START(idx)						\
@@ -138,5 +133,4 @@
     }									\
 } while (0)
 
-
 #endif
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c	2005-04-12 14:37:58.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_video.c	2005-04-12 16:47:51.000000000 +1000
@@ -877,8 +877,8 @@
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Dotclock is %g Mhz, setting ecp_div to %d\n", info->ModeReg.dot_clock_freq/100.0, pPriv->ecp_div);
 #endif
 
-    OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) &
-				  0xfffffCff) | (pPriv->ecp_div << 8));
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) &
+					 0xfffffCff) | (pPriv->ecp_div << 8));
 
     /* I suspect we may need a usleep after writing to the PLL.  if you play a video too soon
        after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey 
@@ -890,7 +890,8 @@
 	(info->ChipFamily == CHIP_FAMILY_RS300)) {
         /* Force the overlay clock on for integrated chips
 	 */
-        OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
+        OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
+	       (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
     }
 
     info->adaptor = adapt;
@@ -1312,7 +1313,7 @@
     else
 	ecp_div = 1;
 
-    OUTPLL(RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
+    OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL, (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) & 0xfffffCff) | (ecp_div << 8));
 
     /* I suspect we may need a usleep after writing to the PLL.  if you play a video too soon
        after switching crtcs in mergedfb clone mode you get a temporary one pixel line of colorkey 
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c	2005-04-12 15:57:37.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c	2005-04-12 16:46:29.000000000 +1000
@@ -171,7 +171,7 @@
     RADEONEngineFlush(pScrn);
 
     clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
-    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+    RADEONPllErrataAfterIndex(info);
 
 #if 0 /* taken care of by new PM code */
     /* Some ASICs have bugs with dynamic-on feature, which are
@@ -249,8 +249,8 @@
 	OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
 
     OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
-    OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
-    if (info->R300CGWorkaround) R300CGWorkaround(pScrn);
+    RADEONPllErrataAfterIndex(info);
+    OUTPLL(pScrn, RADEON_MCLK_CNTL, mclk_cntl);
 }
 
 /* Restore the acceleration hardware to its previous state */

xorg-x11-6.8.2-radeon-pll2-tmds-no-odd-value.patch:
 radeon_driver.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-pll2-tmds-no-odd-value.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:57:59.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:59:59.000000000 +1000
@@ -6940,7 +6940,7 @@
 
 /* Define PLL2 registers for requested video mode */
 static void RADEONInitPLL2Registers(RADEONSavePtr save, RADEONPLLPtr pll,
-				    double dot_clock)
+				    double dot_clock, int no_odd_postdiv)
 {
     unsigned long  freq = dot_clock * 100;
 
@@ -6967,6 +6967,11 @@
     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;
@@ -7067,7 +7072,7 @@
     if (info->IsSecondary) {
 	if (!RADEONInitCrtc2Registers(pScrn, save, mode, info))
 	    return FALSE;
-	RADEONInitPLL2Registers(save, &info->pll, dot_clock);
+       RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->DisplayType != MT_CRT);
     } else if (info->MergedFB) {
         RADEONInitCommonRegisters(save, info);
         if (!RADEONInitCrtcRegisters(pScrn, save, 
@@ -7084,7 +7089,7 @@
         RADEONInitCrtc2Registers(pScrn, save, 
 			((RADEONMergedDisplayModePtr)mode->Private)->CRT2, info);
         dot_clock = (((RADEONMergedDisplayModePtr)mode->Private)->CRT2)->Clock / 1000.0;
-        RADEONInitPLL2Registers(save, &info->pll, dot_clock);
+        RADEONInitPLL2Registers(save, &info->pll, dot_clock, info->MergeType != MT_CRT);
     } else {
 	if (!RADEONInitCrtcRegisters(pScrn, save, mode, info))
 	    return FALSE;

xorg-x11-6.8.2-radeon-release-i2c-lines.patch:
 radeon_driver.c |    3 +++
 1 files changed, 3 insertions(+)

--- NEW FILE xorg-x11-6.8.2-radeon-release-i2c-lines.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:45:43.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:50:21.000000000 +1000
@@ -985,6 +985,9 @@
 	MonType = MT_NONE;
     }
 
+    OUTREG(info->DDCReg, INREG(info->DDCReg) &
+	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+
     if (*MonInfo) {
 	if ((*MonInfo)->rawData[0x14] & 0x80) {
 	    /* Note some laptops have a DVI output that uses internal TMDS,

xorg-x11-6.8.2-radeon-reverse-ddc-option.patch:
 radeon.man      |    7 +++++++
 radeon_driver.c |   10 ++++++++++
 2 files changed, 17 insertions(+)

--- NEW FILE xorg-x11-6.8.2-radeon-reverse-ddc-option.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:59:59.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 16:02:39.000000000 +1000
@@ -165,6 +165,7 @@
 #endif
     OPTION_SHOWCACHE,
     OPTION_VGA_ACCESS,
+    OPTION_REVERSE_DDC,
     OPTION_DYNAMIC_CLOCKS
 } RADEONOpts;
 
@@ -211,6 +212,7 @@
     { OPTION_SHOWCACHE,      "ShowCache",        OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DYNAMIC_CLOCKS, "DynamicClocks",    OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_VGA_ACCESS,     "VGAAccess",        OPTV_BOOLEAN, {0}, TRUE  },
+    { OPTION_REVERSE_DDC,    "ReverseDDC",       OPTV_BOOLEAN, {0}, FALSE },
     { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
 };
 
@@ -1706,6 +1708,14 @@
 	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*/
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.man
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon.man	2005-04-12 14:37:58.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon.man	2005-04-12 16:03:23.000000000 +1000
@@ -505,6 +505,13 @@
 .B on
 on other architectures.
 .TP
+.BI "Option \*qReverseDDC\*q \*q" boolean \*q
+When BIOS connector informations aren't available, use this option to
+reverse the mapping of the 2 main DDC ports. Use this if the X serve
+obviously detects the wrong display for each connector. This is
+typically needed on the Radeon 9600 cards bundled with Apple G5s. The
+default is
+.B off.
 
 .SH SEE ALSO
 __xservername__(__appmansuffix__), __xconfigfile__(__filemansuffix__), xorgconfig(__appmansuffix__), Xserver(__appmansuffix__), X(__miscmansuffix__)

xorg-x11-6.8.2-radeon-surface-cntl-dual-head.patch:
 radeon_accel.c  |    5 +----
 radeon_driver.c |   17 +++++++++++++++++
 2 files changed, 18 insertions(+), 4 deletions(-)

--- NEW FILE xorg-x11-6.8.2-radeon-surface-cntl-dual-head.patch ---
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:51:39.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c	2005-04-12 15:57:59.000000000 +1000
@@ -6632,6 +6632,23 @@
 
     }
 
+    /* We must set SURFACE_CNTL properly on the second screen too */
+    save->surface_cntl = 0;
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+    /* Alhought we current onlu use aperture 0, also setting aperture 1 should not harm -ReneR */
+    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
+
     RADEONTRACE(("Pitch = %d bytes (virtualX = %d, displayWidth = %d)\n",
 		 save->crtc2_pitch, pScrn->virtualX,
 		 info->CurrentLayout.displayWidth));
Index: xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c
===================================================================
--- xc-STABLE.orig/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c	2005-04-12 14:37:58.000000000 +1000
+++ xc-STABLE/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c	2005-04-12 15:57:37.000000000 +1000
@@ -291,10 +291,7 @@
     OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN);
 #endif
 
-    /* Restore SURFACE_CNTL - only the first head contains valid data -ReneR */
-    if (!info->IsSecondary) {
-	OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
-    }
+    OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
 
     RADEONWaitForFifo(pScrn, 1);
     OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX


Index: xorg-x11.spec
===================================================================
RCS file: /cvs/dist/rpms/xorg-x11/devel/xorg-x11.spec,v
retrieving revision 1.193
retrieving revision 1.193.2.1
diff -u -r1.193 -r1.193.2.1
--- xorg-x11.spec	30 Apr 2005 17:48:54 -0000	1.193
+++ xorg-x11.spec	4 May 2005 08:45:19 -0000	1.193.2.1
@@ -18,7 +18,7 @@
 
 Name: xorg-x11
 Version: 6.8.2
-Release: 30
+Release: 30.radeon.1
 #Release: 1.FC3.29
 
 %define build_mharris_mode	0
@@ -472,7 +472,23 @@
 # to the behavior we had pre-6.8.2.  It's not the right patch going
 # forward, but until the dynamic clocks code is fixed properly, let's
 # stick to something that works.
-Patch9335: xorg-x11-6.8.1-ati-radeon-dynamic-clocks-fix-2.patch
+# Patch9335: xorg-x11-6.8.1-ati-radeon-dynamic-clocks-fix-2.patch
+
+# Bah. Fix the radeon code properly... perhaps.
+# Patches from http://gate.crashing.org/~benh/xorg/
+Patch9400: xorg-x11-6.8.2-radeon-no-vga.patch
+Patch9401: xorg-x11-6.8.2-radeon-fix-crtc2-offset-cntl.patch
+Patch9402: xorg-x11-6.8.2-radeon-fix-pll-probing.patch
+Patch9403: xorg-x11-6.8.2-radeon-display-bandwidth-calc-fix.patch
+Patch9404: xorg-x11-6.8.2-radeon-fix-mergedfb-bios-dividers.patch
+Patch9405: xorg-x11-6.8.2-radeon-surface-cntl-dual-head.patch
+Patch9406: xorg-x11-6.8.2-radeon-pll2-tmds-no-odd-value.patch
+Patch9407: xorg-x11-6.8.2-radeon-reverse-ddc-option.patch
+Patch9408: xorg-x11-6.8.2-radeon-lvds-probe-pll.patch
+Patch9409: xorg-x11-6.8.2-radeon-fix-divider-select.patch
+Patch9410: xorg-x11-6.8.2-radeon-pll-errata-workarounds.patch
+Patch9411: xorg-x11-6.8.2-radeon-release-i2c-lines.patch
+Patch9412: xorg-x11-6.8.2-radeon-fix-one-mode-ddc.patch
 
 # EXPERIMENTAL PATCHES intended strictly for fedora-devel (FC4 currently).
 # Once a patch is determined to be safe to apply to other releases, it can
@@ -1148,7 +1164,24 @@
 %patch9333 -p0 -b .xpm-security-fix-CAN-2005-0605
 %patch9334 -p0 -b .xorg.conf.man-dont-refer-to-nonexisting-example
 
-%patch9335 -p0 -b .ati-radeon-dynamic-clocks-fix-2
+#%patch9335 -p0 -b .ati-radeon-dynamic-clocks-fix-2
+
+cd xc
+%patch9400 -p1 -b .radeon-no-vga
+%patch9401 -p1 -b .radeon-fix-crtc2-offset-cntl
+%patch9402 -p1 -b .radeon-fix-pll-probing
+%patch9403 -p1 -b .radeon-display-bandwidth-calc-fix
+%patch9404 -p1 -b .radeon-fix-mergedfb-bios-dividers
+%patch9405 -p1 -b .radeon-surface-cntl-dual-head
+%patch9406 -p1 -b .radeon-pll2-tmds-no-odd-value
+%patch9407 -p1 -b .radeon-reverse-ddc-option
+%patch9408 -p1 -b .radeon-lvds-probe-pll
+%patch9409 -p1 -b .radeon-fix-divider-select
+%patch9410 -p1 -b .radeon-pll-errata-workarounds
+# Also patch9500
+#%patch9411 -p1 -b .radeon-release-i2c-lines
+%patch9412 -p1 -b .radeon-fix-one-mode-ddc
+cd ..
 
 # EXPERIMENTAL PATCHES intended strictly for fedora-devel (FC4 currently)
 %if %{build_fc4}
@@ -3613,6 +3646,10 @@
 [ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT 
 
 %changelog
+* Wed May  4 2005 David Woodhouse <dwmw2 at redhat.com> 6.8.2-30.radeon.1
+- Disable ati-radeon-dynamic-clocks-fix-2.patch and add BenH's patches
+  to attempt to fix the problem (and others) properly.
+
 * Sat Apr 30 2005 Mike A. Harris <mharris at redhat.com> 6.8.2-30
 - Disabled xfs.init-fc4-startearly.patch as it breaks systems that /usr is
   on NFS. (FC4Blocker #156413)




More information about the fedora-cvs-commits mailing list