[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xserver-xorg-video-ati: Changes to 'upstream-experimental'



 configure.ac          |    2 
 src/radeon_bios.c     |    5 +
 src/radeon_display.c  |   65 +++++++++++++++--------
 src/radeon_driver.c   |  137 ++++++++++++++++++++++++++++++--------------------
 src/radeon_mergedfb.c |   53 ++++++++++++++-----
 src/radeon_modes.c    |   82 ++++++++++++-----------------
 src/radeon_probe.h    |    3 -
 src/radeon_reg.h      |    2 
 8 files changed, 209 insertions(+), 140 deletions(-)

New commits:
commit 09bfc8ed000f95ede5b73f2bad69edc1a4d9bac6
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Sun May 20 18:06:22 2007 -0400

    update to 6.6.192 for rc release

diff --git a/configure.ac b/configure.ac
index ddfa7c8..8b29d8d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@
 
 AC_PREREQ(2.57)
 AC_INIT([xf86-video-ati],
-        6.6.191,
+        6.6.192,
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
         xf86-video-ati)
 

commit 764cb73e8dec4040cdd418d249fc504399fca3ee
Author: Alex Deucher <alex@t41p.hsd1.va.comcast.net>
Date:   Sun May 20 17:26:26 2007 -0400

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

diff --git a/src/radeon_display.c b/src/radeon_display.c
index f3b86e6..fb345a9 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -2135,7 +2135,9 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
     RADEONEntPtr pRADEONEnt   = RADEONEntPriv(pScrn);
     RADEONConnector *pPort;
 
-    if (!pRADEONEnt->HasSecondary || (info->IsSwitching  && !info->IsSecondary)) {
+    if (!pRADEONEnt->HasSecondary ||
+	(pRADEONEnt->HasSecondary && !info->IsSwitching) ||
+	(info->IsSwitching && (!info->IsSecondary))) {
 	pPort = RADEONGetCrtcConnector(pScrn, 1);
 	if (pPort)
 	    RADEONUnblankSet(pScrn, pPort);
@@ -2158,7 +2160,8 @@ void RADEONUnblank(ScrnInfoPtr pScrn)
       }
     }
 
-    if (info->IsSwitching && info->IsSecondary) {
+    if ((pRADEONEnt->HasSecondary && !info->IsSwitching) ||
+	(info->IsSwitching && info->IsSecondary)) {
 	pPort = RADEONGetCrtcConnector(pScrn, 2);
 	if (pPort)
 	    RADEONUnblankSet(pScrn, pPort);
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index b9cce22..933265f 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2971,7 +2971,9 @@ static Bool RADEONPreInitControllers(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10
 
     RADEONGetBIOSInfo(pScrn, pInt10);
 
-    RADEONSetupConnectors(pScrn);
+    if (!info->IsSecondary) {
+	RADEONSetupConnectors(pScrn);
+    }
     RADEONMapControllers(pScrn);
 
     RADEONGetClockInfo(pScrn);

commit a3ee42207aab77d93655a82fdcb32be38268b85f
Author: Dave Airlie <airlied@linux.ie>
Date:   Wed Apr 25 09:52:22 2007 +1000

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

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index fa143cb..abbc160 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -215,8 +215,13 @@ RADEONCopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest,
       * extension to allow selecting among a number of modes whose merged result
       * looks identical but consists of different modes for CRT1 and CRT2
       */
-    mode->VRefresh = (float)((i->Clock * 1000.0 / i->HTotal / i->VTotal) * 100 +
-	(j->Clock * 1000.0 / j->HTotal / j->VTotal));
+    {
+	float ref1, ref2;
+	ref1 = ((float)i->Clock * 100.0 / i->HTotal / i->VTotal) * 50.0;
+	ref2 = ((float)j->Clock * 100.0 / j->HTotal / j->VTotal) / 2.0;
+
+        mode->VRefresh = (float) ref1 + ref2;
+    }
 
     mode->Clock = (int)(mode->VRefresh * 0.001 * mode->HTotal * mode->VTotal);
 

commit 3828237200fc16d4d32664fb8358950c213d4897
Author: Dave Airlie <airlied@nx6125b.(none)>
Date:   Sun Apr 22 11:36:00 2007 +1000

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

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

commit c81ed9bd7b37c9d02141d10f6c7bad3d0c57032f
Author: Dave Airlie <airlied@linux.ie>
Date:   Sat Apr 21 18:58:40 2007 +1000

    radeon: fix build on older server

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 3d147e2..1a63971 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -186,9 +186,11 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
 	    new->status     = MODE_OK;
 #ifdef M_T_PREFERRED
 	    if (PREFERRED_TIMING_MODE(ddc->features.msc))
-	      new->type     = M_T_PREFERRED;
+	      new->type     |= M_T_PREFERRED;
 #endif
+#ifdef M_T_DRIVER
 	      new->type     |= M_T_DRIVER;
+#endif
 
 	    switch (d_timings->misc) {
 	    case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;

commit 406eec71116a58d42288a7f1c809a92d5bda7350
Author: Dave Airlie <airlied@linux.ie>
Date:   Sat Apr 21 18:56:28 2007 +1000

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

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index bcc0882..b9cce22 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2036,8 +2036,8 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
     if (info->IsDellServer)
 	info->ddc_mode = TRUE;
     /* IBM Lewis server have troubles using the on-chip RMX mode */
-    if (info->ChipFamily == CHIP_FAMILY_RV100 && !info->HasCRTC2 && pRADEONEnt->PortInfo[0]->MonInfo) {
-	struct vendor *ven = &pRADEONEnt->PortInfo[0].MonInfo->vendor;
+    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2 && pRADEONEnt->PortInfo[0]->MonInfo) {
+	struct vendor *ven = &pRADEONEnt->PortInfo[0]->MonInfo->vendor;
 	if (ven && ven->prod_id == 0x029a && ven->serial == 0x01010101)
 	    info->ddc_mode = TRUE;
     }

commit ad119960095b4b64f4c6793f65950c9967ce4989
Author: Matthias Hopf <mhopf@suse.de>
Date:   Thu Apr 19 11:54:46 2007 +0200

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

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

commit 16ef77df4ebaf5ea13baa82972aaf98e71ac32ee
Author: Matthias Hopf <mhopf@suse.de>
Date:   Wed Apr 18 17:36:15 2007 +0200

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

diff --git a/src/radeon_display.c b/src/radeon_display.c
index ac05648..57e752e 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -755,13 +755,11 @@ static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn)
 		info->VSyncWidth = d_timings->v_sync_width;
 		info->VBlank     = d_timings->v_blanking;
                 info->Flags      = (d_timings->interlaced ? V_INTERLACE : 0);
-                if (d_timings->sync == 3) {
-                   switch (d_timings->misc) {
-                   case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break;
-                   case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break;
-                   case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break;
-                   case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break;
-                   }
+                switch (d_timings->misc) {
+                case 0: info->Flags |= V_NHSYNC | V_NVSYNC; break;
+                case 1: info->Flags |= V_PHSYNC | V_NVSYNC; break;
+                case 2: info->Flags |= V_NHSYNC | V_PVSYNC; break;
+                case 3: info->Flags |= V_PHSYNC | V_PVSYNC; break;
                 }
                 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel infos found from DDC detailed: %dx%d\n",
                            info->PanelXRes, info->PanelYRes);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 6b8577e..3d147e2 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -190,13 +190,11 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
 #endif
 	      new->type     |= M_T_DRIVER;
 
-	    if (d_timings->sync == 3) {
-		switch (d_timings->misc) {
-		case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
-		case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
-		case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
-		case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
-		}
+	    switch (d_timings->misc) {
+	    case 0: new->Flags |= V_NHSYNC | V_NVSYNC; break;
+	    case 1: new->Flags |= V_PHSYNC | V_NVSYNC; break;
+	    case 2: new->Flags |= V_NHSYNC | V_PVSYNC; break;
+	    case 3: new->Flags |= V_PHSYNC | V_PVSYNC; break;
 	    }
 	    count++;
 

commit 0abce69f0d826a7ca1a41d963cd4730b6e01c145
Author: Matthias Hopf <mhopf@suse.de>
Date:   Wed Apr 18 17:32:52 2007 +0200

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

diff --git a/src/radeon_display.c b/src/radeon_display.c
index d661c17..ac05648 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -776,7 +776,7 @@ static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn)
     for (j = 0; j < 8; j++) {
 	if ((info->PanelXRes < ddc->timings2[j].hsize) &&
 	    (info->PanelYRes < ddc->timings2[j].vsize)) {
-	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+	    for (p = pScrn->monitor->Modes; p; p = p->next) {
 		if ((ddc->timings2[j].hsize == p->HDisplay) &&
 		    (ddc->timings2[j].vsize == p->VDisplay)) {
 		    float  refresh =
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 372b2ed..6b8577e 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -212,7 +212,7 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
     for (j = 0; j < 8; j++) {
         if (ddc->timings2[j].hsize == 0 || ddc->timings2[j].vsize == 0)
                continue;
-	for (p = pScrn->monitor->Modes; p && p->next; p = p->next) {
+	for (p = pScrn->monitor->Modes; p; p = p->next) {
 	    /* Ignore all double scan modes */
 	    if (p->Flags & V_DBLSCAN)
 		continue;
@@ -248,7 +248,7 @@ static DisplayModePtr RADEONDDCModes(ScrnInfoPtr pScrn, xf86MonPtr ddc)
     tmp = (ddc->timings1.t1 << 8) | ddc->timings1.t2;
     for (j = 0; j < 16; j++) {
 	if (tmp & (1 << j)) {
-	    for (p = pScrn->monitor->Modes; p && p->next; p = p->next) {
+	    for (p = pScrn->monitor->Modes; p; p = p->next) {
 		/* Ignore all double scan modes */
 		if (p->Flags & V_DBLSCAN)
 		    continue;
@@ -560,7 +560,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
     }
 
     /* add in all default vesa modes smaller than panel size, used for randr*/
-    for (p = pScrn->monitor->Modes; p && p->next; p = p->next->next) {
+    for (p = pScrn->monitor->Modes; p; p = p->next) {
 	if ((p->HDisplay <= info->PanelXRes) && (p->VDisplay <= info->PanelYRes)) {
 	    tmp = first;
 	    while (tmp) {

commit aea801cf9a5ce519a53d6fffd9a3a2e526ec79ea
Author: Matthias Hopf <mhopf@suse.de>
Date:   Fri Apr 13 16:16:05 2007 +0200

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

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index c4bda8a..0f9e2d6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2328,7 +2328,11 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 		
 	    }
 	}
+	else
+	    info->MergedFB = FALSE;
     }
+    else
+	info->MergedFB = FALSE;
 
     if (info->MergedFB) {
        /* If no virtual dimension was given by the user,

commit 07ddffb32e6293c77b32c94b87ec468caef3d6f5
Author: Matthias Hopf <mhopf@suse.de>
Date:   Wed Apr 11 14:36:51 2007 +0200

    Fixed typo in mode list generation.

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 5c91cd3..fa143cb 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -389,7 +389,7 @@ RADEONGenerateModeListFromLargestModes(ScrnInfoPtr pScrn,
     if(srel != radeonClone) {
        if(mode3 && mode4 && !info->NonRect) {
 	  mode1 = mode3;
-	  mode2 = mode2;
+	  mode2 = mode4;
        }
     }
 

commit 4effa67ea75736a31b9e78a7b35acf74b067c43e
Author: Dave Airlie <airlied@linux.ie>
Date:   Mon Apr 9 22:08:31 2007 +1000

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

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

commit 6b25a4c48796e022a093f3072574ffe9709ecaf4
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Wed Apr 4 10:47:29 2007 +0200

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

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 6a7745e..5c91cd3 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -536,12 +536,33 @@ RADEONGenerateModeList(ScrnInfoPtr pScrn, char* str,
            DisplayModePtr p, q, result = NULL;
 
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-                "Clone mode, list all common modes\n");
-           for (p = i; p->next != i; p = p->next)
-                for (q = j; q->next != j; q = q->next)
-                   if ((p->HDisplay == q->HDisplay) &&
-                        (p->VDisplay == q->VDisplay))
-                        result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+                      "Clone mode, linking all nearest modes\n");
+
+           p = i;
+           q = j;
+
+           result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+
+           while (p->next != i || q->next != j) {
+              DisplayModePtr next_p = p;
+
+              if (q->next == j || (p->next != i &&
+                                   (p->HDisplay > q->HDisplay ||
+                                    (p->HDisplay == q->HDisplay &&
+                                     p->VDisplay >= q->VDisplay))))
+                 next_p = p->next;
+
+              if (p->next == i || (q->next != j &&
+                                   (q->HDisplay > p->HDisplay ||
+                                    (q->HDisplay == p->HDisplay &&
+                                     q->VDisplay >= p->VDisplay))))
+                 q = q->next;
+
+              p = next_p;
+
+              result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+           }
+
            return result;
         } else {
            xf86DrvMsg(pScrn->scrnIndex, X_INFO,

commit 3c892f163ec1fa9be6e733aab091c9b718f41efc
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Wed Apr 4 09:52:37 2007 +0200

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

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 535d047..372b2ed 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -373,15 +373,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 			    if (p == ddcModes) ddcModes = p->next;
 
 			    /* Add to used modes */
-			    if (last) {
-				last->next = p;
-				p->prev = last;
-			    } else {
-				first = p;
-				p->prev = NULL;
-			    }
-			    p->next = NULL;
-			    last = p;
+			    RADEONSortModes(&p, &first, &last);
 
 			    break;
 			}
@@ -402,15 +394,7 @@ int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
 		    if (p == ddcModes) ddcModes = p->next;
 
 		    /* Add to used modes */
-		    if (last) {
-			last->next = p;
-			p->prev = last;
-		    } else {
-			first = p;
-			p->prev = NULL;
-		    }
-		    p->next = NULL;
-		    last = p;
+		    RADEONSortModes(&p, &first, &last);
 		}
 	    }
 
@@ -558,12 +542,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
 
 	new->type      |= M_T_USERDEF;
 
-	new->next       = NULL;
-	new->prev       = last;
-
-	if (last) last->next = new;
-	last = new;
-	if (!first) first = new;
+	RADEONSortModes(&new, &first, &last);
 
 	pScrn->display->virtualX =
 	    pScrn->virtualX = MAX(pScrn->virtualX, width);
@@ -609,12 +588,7 @@ int RADEONValidateFPModes(ScrnInfoPtr pScrn, char **ppModeName)
 
 		new->type      |= M_T_DEFAULT;
 
-		new->next       = NULL;
-		new->prev       = last;
-
-		if (last) last->next = new;
-		last = new;
-		if (!first) first = new;
+		RADEONSortModes(&new, &first, &last);
 	    }
 	}
     }

commit 3a8190ccc79969925257e7b980b78d79053d208d
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Wed Apr 4 09:47:07 2007 +0200

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

diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 820ba4b..6a7745e 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -581,8 +581,10 @@ RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
   	               info->CRT1XOffs = info->CRT2XOffs = 0;
   	               maxh -= (info->CRT1XOffs + info->CRT2XOffs);
   	}
-  	pScrn->virtualX = maxh;
-  	pScrn->displayWidth = maxh;
+	if (maxh > pScrn->virtualX)
+	    pScrn->virtualX = maxh;
+	if (maxh > pScrn->displayWidth)
+	    pScrn->displayWidth = maxh;
   	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "width", maxh);
     } else {
   	if(maxh < pScrn->display->virtualX) {
@@ -592,7 +594,8 @@ RADEONRecalcDefaultVirtualSize(ScrnInfoPtr pScrn)
     }
 
     if(!(pScrn->display->virtualY)) {
-        pScrn->virtualY = maxv;
+	if (maxv > pScrn->virtualY)
+	    pScrn->virtualY = maxv;
 	xf86DrvMsg(pScrn->scrnIndex, X_PROBED, str, "height", maxv);
     } else {
 	if(maxv < pScrn->display->virtualY) {

commit 9b1e97284ce185d358ca756a235d2cee346fa53f
Author: Henry Zhao <henryz@localhost.localdomain>
Date:   Sat Mar 31 23:01:52 2007 -0800

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

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

commit 9c2dcd19be8fc2cc29e637d1e9748e66196e3900
Author: Henry Zhao <henryz@localhost.localdomain>
Date:   Sat Mar 31 20:10:03 2007 -0800

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

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 0e68d7d..7fd802a 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2125,7 +2125,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
      * 'stretched' from their native mode.
      */
     if (info->DisplayType == MT_CRT && !info->ddc_mode) {
-
+	xf86SetDDCproperties(pScrn, pScrn->monitor->DDC);
 	modesFound =
 	    xf86ValidateModes(pScrn,
 			      pScrn->monitor->Modes,
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 70bf184..09b8aaf 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -675,7 +675,7 @@ int RADEONValidateMergeModes(ScrnInfoPtr pScrn1)
      * 'stretched' from their native mode.
      */
     if (info->MergeType == MT_CRT && !info->ddc_mode) {
- 
+	xf86SetDDCproperties(pScrn, pScrn->monitor->DDC); 
 	modesFound =
 	    xf86ValidateModes(pScrn,
 			      pScrn->monitor->Modes,

commit 1acd6d6fa42acec07fb11aeb189f492ddb021cb4
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Fri Mar 30 11:06:10 2007 +0200

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

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 57d8826..0e68d7d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -2247,7 +2247,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 	    /* If we have 2 screens from the config file, we don't need
 	     * to do clone thing, let each screen handles one head.
 	     */
-	    if (!pRADEONEnt->HasSecondary) {
+	    if (info->MergedFB) {
 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 			   "Validating CRTC2 modes for MergedFB ------------ \n");
 
@@ -2273,7 +2273,7 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
 
 
     if (pRADEONEnt->HasCRTC2) {
-	if(pRADEONEnt->Controller[1]->binding == 1) {
+	if(pRADEONEnt->Controller[1]->binding == 1 && info->MergedFB) {
 	    
 	    xf86SetCrtcForModes(info->CRT2pScrn, INTERLACE_HALVE_V);
 	    

commit 1a71106c0e4fe5f650239dc694163fdf52d33663
Author: Michel Dänzer <michel@tungstengraphics.com>
Date:   Tue Mar 27 10:13:21 2007 +0200

    radeon: Fix typo.

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 2cd4c7b..57d8826 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6336,7 +6336,7 @@ static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
     if (crtc1 && (crtc_mask & 1)) {
     	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
 	   crtc1->name,
-	   crtc1->clock,
+	   crtc1->Clock/1000.0,
 
 	   crtc1->HDisplay,
 	   crtc1->HSyncStart,

commit f87e57d4d773a019d1cc8a10425c57480430f6a4
Author: Dave Airlie <airlied@linux.ie>
Date:   Tue Mar 27 18:08:54 2007 +1000

    radeon: fix up crtc debug dereference problem

diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1bd6884..2cd4c7b 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -6333,9 +6333,10 @@ static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
     ScrnInfoPtr    pScrn0    = NULL;
 
 #if RADEON_DEBUG
-    ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
+    if (crtc1 && (crtc_mask & 1)) {
+    	ErrorF("%-12.12s %7.2f  %4d %4d %4d %4d  %4d %4d %4d %4d (%d,%d)",
 	   crtc1->name,
-	   dot_clock,
+	   crtc1->clock,
 
 	   crtc1->HDisplay,
 	   crtc1->HSyncStart,
@@ -6348,40 +6349,44 @@ static Bool RADEONInit2(ScrnInfoPtr pScrn, DisplayModePtr crtc1,
 	   crtc1->VTotal,
 	   pScrn->depth,
 	   pScrn->bitsPerPixel);
-    if (crtc1->Flags & V_DBLSCAN)   ErrorF(" D");
-    if (crtc1->Flags & V_CSYNC)     ErrorF(" C");
-    if (crtc1->Flags & V_INTERLACE) ErrorF(" I");
-    if (crtc1->Flags & V_PHSYNC)    ErrorF(" +H");
-    if (crtc1->Flags & V_NHSYNC)    ErrorF(" -H");
-    if (crtc1->Flags & V_PVSYNC)    ErrorF(" +V");
-    if (crtc1->Flags & V_NVSYNC)    ErrorF(" -V");
-    ErrorF("\n");



Reply to: