xf86-video-ati: Branch 'agd5f-superpatch'

Alex Deucher agd5f at kemper.freedesktop.org
Sat Sep 16 19:26:22 EEST 2006


 src/radeon.h          |  108 +++----
 src/radeon_display.c  |  719 +++++++++++++++++++++++++++++++-------------------
 src/radeon_driver.c   |  204 +++++++-------
 src/radeon_mergedfb.c |   28 +
 src/radeon_reg.h      |   64 ++++
 5 files changed, 702 insertions(+), 421 deletions(-)

New commits:
diff-tree a4545f40ca68797dfd7d93b4da72e5d195f5333f (from 8ac0d1dd86b6497d5d517af1f3dceb20aac5ee2b)
Author: Alex Deucher <alex at samba.(none)>
Date:   Sat Sep 16 12:24:33 2006 -0400

    Update to my latest code (also includes some of Henry's fixes)

diff --git a/src/radeon.h b/src/radeon.h
index 9274f82..089e3f8 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -86,59 +86,6 @@
 #define MIN(a,b) ((a)>(b)?(b):(a))
 #endif
 
-/* ------- mergedfb support ------------- */
-		/* Psuedo Xinerama support */
-#define NEED_REPLIES  		/* ? */
-#define EXTENSION_PROC_ARGS void *
-#include "extnsionst.h"  	/* required */
-#include <X11/extensions/panoramiXproto.h>  	/* required */
-#define RADEON_XINERAMA_MAJOR_VERSION  1
-#define RADEON_XINERAMA_MINOR_VERSION  1
-
-
-/* Relative merge position */
-typedef enum {
-   radeonLeftOf,
-   radeonRightOf,
-   radeonAbove,
-   radeonBelow,
-   radeonClone
-} RADEONScrn2Rel;
-
-typedef struct _region {
-    int x0,x1,y0,y1;
-} region;
-
-/* ------------------------------------- */
-
-#define RADEON_DEBUG            1 /* Turn off debugging output               */
-#define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
-#define RADEON_TIMEOUT    2000000 /* Fall out of wait loops after this count */
-
-/* Buffer are aligned on 4096 byte boundaries */
-#define RADEON_BUFFER_ALIGN 0x00000fff
-#define RADEON_VBIOS_SIZE 0x00010000
-#define RADEON_USE_RMX 0x80000000 /* mode flag for using RMX
-				   * Need to comfirm this is not used
-				   * for something else.
-				   */
-
-#if RADEON_DEBUG
-#define RADEONTRACE(x)						\
-do {									\
-    ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex);		\
-    ErrorF x;								\
-} while(0)
-#else
-#define RADEONTRACE(x) do { } while(0)
-#endif
-
-
-/* Other macros */
-#define RADEON_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
-#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
-#define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
-
 typedef enum {
     OPTION_NOACCEL,
     OPTION_SW_CURSOR,
@@ -208,6 +155,60 @@ typedef enum {
     OPTION_REVERSE_DISPLAY
 } RADEONOpts;
 
+/* ------- mergedfb support ------------- */
+		/* Psuedo Xinerama support */
+#define NEED_REPLIES  		/* ? */
+#define EXTENSION_PROC_ARGS void *
+#include "extnsionst.h"  	/* required */
+#include <X11/extensions/panoramiXproto.h>  	/* required */
+#define RADEON_XINERAMA_MAJOR_VERSION  1
+#define RADEON_XINERAMA_MINOR_VERSION  1
+
+
+/* Relative merge position */
+typedef enum {
+   radeonLeftOf,
+   radeonRightOf,
+   radeonAbove,
+   radeonBelow,
+   radeonClone
+} RADEONScrn2Rel;
+
+typedef struct _region {
+    int x0,x1,y0,y1;
+} region;
+
+/* ------------------------------------- */
+
+#define RADEON_DEBUG            1 /* Turn off debugging output               */
+#define RADEON_IDLE_RETRY      16 /* Fall out of idle loops after this count */
+#define RADEON_TIMEOUT    2000000 /* Fall out of wait loops after this count */
+
+/* Buffer are aligned on 4096 byte boundaries */
+#define RADEON_BUFFER_ALIGN 0x00000fff
+#define RADEON_VBIOS_SIZE 0x00010000
+#define RADEON_USE_RMX 0x80000000 /* mode flag for using RMX
+				   * Need to comfirm this is not used
+				   * for something else.
+				   */
+
+#if RADEON_DEBUG
+#define RADEONTRACE(x)						\
+do {									\
+    ErrorF("(**) %s(%d): ", RADEON_NAME, pScrn->scrnIndex);		\
+    ErrorF x;								\
+} while(0)
+#else
+#define RADEONTRACE(x) do { } while(0)
+#endif
+
+
+/* Other macros */
+#define RADEON_ARRAY_SIZE(x)  (sizeof(x)/sizeof(x[0]))
+#define RADEON_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1))
+#define RADEONPTR(pScrn)      ((RADEONInfoPtr)(pScrn)->driverPrivate)
+
+
 typedef struct {
 				/* Common registers */
     CARD32            ovr_clr;
@@ -875,6 +876,7 @@ extern Bool        RADEONGetLVDSInfoFrom
 extern Bool        RADEONGetTMDSInfoFromBIOS (ScrnInfoPtr pScrn);
 extern Bool        RADEONGetHardCodedEDIDFromBIOS (ScrnInfoPtr pScrn);
 
+extern xf86MonPtr  RADEONProbeDDC(ScrnInfoPtr pScrn, int indx);
 extern void        RADEONInitDispBandwidth(ScrnInfoPtr pScrn);
 extern Bool        RADEONI2cInit(ScrnInfoPtr pScrn);
 extern void        RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag);
diff --git a/src/radeon_display.c b/src/radeon_display.c
index 252f2f5..57e7bc2 100644
--- a/src/radeon_display.c
+++ b/src/radeon_display.c
@@ -160,6 +160,8 @@ static const CARD32 default_tvdac_adj [C
     0x00780000,   /* rv350 */
     0x00780000,   /* rv380 */
     0x01080000,   /* r420 */
+    0x01080000,   /* rv410 */ /* FIXME: just values from r420 used... */
+    0x00780000,   /* rs400 */ /* FIXME: just values from rv380 used... */
 };
 
 static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
@@ -209,6 +211,7 @@ Bool RADEONI2cInit(ScrnInfoPtr pScrn)
     return TRUE;
 }
 
+#if 1
 void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
 {
     MonPtr      mon = pScrn->monitor;
@@ -297,275 +300,411 @@ void RADEONSetSyncRangeFromEdid(ScrnInfo
     }
 }
 
+#else
+
+void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
+{
+    MonPtr monitor = pScrn->monitor;
+    xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
+    int i, j;
+    float hmin = 1e6, hmax = 0.0, vmin = 1e6, vmax = 0.0;
+    float h, v;
+    struct std_timings *t;
+    struct detailed_timings *dt;
+    struct monitor_ranges *mon_range = NULL;
+    int numTimings = 0;
+    range hsync[MAX_HSYNC];
+    range vrefresh[MAX_VREFRESH];
+
+    numTimings = 0;
+
+    if (flag) { /* Hsync */
+	for (i = 0; i < DET_TIMINGS; i++) {
+	    switch (DDC->det_mon[i].type) {
+	    case DS_RANGES:
+		mon_range = &DDC->det_mon[i].section.ranges;
+		hsync[numTimings].lo = mon_range->min_h;
+		hsync[numTimings].hi = mon_range->max_h;
+		numTimings++;
+		break;
+
+	    case DS_STD_TIMINGS:
+		t = DDC->det_mon[i].section.std_t;
+		for (j = 0; j < 5; j++) {
+		    if (t[j].hsize > 256) { /* sanity check */
+			h = t[j].refresh * 1.07 * t[j].vsize / 1000.0;
+			if (h < hmin)
+			    hmin = h;
+			if (h > hmax)
+			    hmax = h;
+		    }
+		}
+		break;
+
+	    case DT:
+		dt = &DDC->det_mon[i].section.d_timings;
+		if (dt->clock > 15000000) { /* sanity check */
+		    h = (float)dt->clock / (dt->h_active + dt->h_blanking);
+		    h /= 1000.0;
+		    if (h < hmin)
+			hmin = h;
+		    if (h > hmax)
+			hmax = h;
+		}
+		break;
+	    }
+
+	    if (numTimings > MAX_HSYNC)
+		break;
+	}
+
+	if (numTimings == 0) {
+	    t = DDC->timings2;
+	    for (i = 0; i < STD_TIMINGS; i++) {
+		if (t[i].hsize > 256) { /* sanity check */
+		    h = t[i].refresh * 1.07 * t[i].vsize / 1000.0;
+		    if (h < hmin)
+			hmin = h;
+		    if (h > hmax)
+			hmax = h;
+		}
+	    }
+
+	    if (hmax > 0.0) {
+		hsync[numTimings].lo = hmin;
+		hsync[numTimings].hi = hmax;
+		numTimings++;
+	    }
+	}
+
+	if (numTimings > 0) {
+	    monitor->nHsync = numTimings;
+	    for (i = 0; i < numTimings; i++) {
+	    	monitor->hsync[i].lo = hsync[i].lo;
+	    	monitor->hsync[i].hi = hsync[i].hi;
+	    }
+	} else {
+	    pScrn->monitor->hsync[0].lo = 28;
+            pScrn->monitor->hsync[0].hi = 60;
+            monitor->nHsync = 1;
+	}
+
+    } else {  /* Vrefresh */
+	for (i = 0; i < DET_TIMINGS; i++) {
+	    switch (DDC->det_mon[i].type) {
+	    case DS_RANGES:
+		mon_range = &DDC->det_mon[i].section.ranges;
+		vrefresh[numTimings].lo = mon_range->min_v;
+		vrefresh[numTimings].hi = mon_range->max_v;
+		numTimings++;
+		break;
+
+	    case DS_STD_TIMINGS:
+		t = DDC->det_mon[i].section.std_t;
+		for (j = 0; j < 5; j++) {
+		    if (t[j].hsize > 256) { /* sanity check */
+			if (t[j].refresh < vmin)
+			    vmin = t[i].refresh;
+			if (t[j].refresh > vmax)
+			    vmax = t[i].refresh;
+		    }
+		}
+		break;
+
+	    case DT:
+		dt = &DDC->det_mon[i].section.d_timings;
+		if (dt->clock > 15000000) { /* sanity check */
+		    h = (float)dt->clock / (dt->h_active + dt->h_blanking);
+		    v = h / (dt->v_active + dt->v_blanking);
+		    if (dt->interlaced) 
+			v /= 2.0;
+
+		    if (v < vmin)
+			vmin = v;
+		    if (v > vmax)
+			vmax = v;
+		}
+		break;
+	    }
+
+	    if (numTimings > MAX_HSYNC)
+		break;
+	}
+
+	if (numTimings == 0) {
+	    t = DDC->timings2;
+	    for (i = 0; i < STD_TIMINGS; i++) {
+		if (t[i].hsize > 256) { /* sanity check */
+		    if (t[i].refresh < vmin)
+			vmin = t[i].refresh;
+		    if (t[i].refresh > vmax)
+			vmax = t[i].refresh;
+		}
+	    }
+
+	    if (vmax > 0.0) {
+		vrefresh[numTimings].lo = vmin;
+		vrefresh[numTimings].hi = vmax;
+		numTimings++;
+	    }
+	}
+
+	if (numTimings > 0) {
+	    monitor->nVrefresh = numTimings;
+	    for (i = 0; i < numTimings; i++) {
+		monitor->vrefresh[i].lo = vrefresh[i].lo;
+		monitor->vrefresh[i].hi = vrefresh[i].hi;
+	    }
+	 } else {
+	    pScrn->monitor->vrefresh[0].lo = 43;
+            pScrn->monitor->vrefresh[0].hi = 72;
+            monitor->nVrefresh = 1;
+	}
+    }
+}
+#endif
+
 static RADEONMonitorType
-RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsPrimaryDac)
+RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac)
 {
     RADEONInfoPtr info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
-    int	          bConnected = 0;
+    int		  bConnected = 0;
 
-    /* the monitor either wasn't connected or it is a non-DDC monitor.
-      we need to try to detect connectedness another way....
-    */
-    if(IsPrimaryDac) 
-    {
-        unsigned long ulOrigVCLK_ECP_CNTL;
-        unsigned long ulOrigDAC_CNTL;
-        unsigned long ulOrigDAC_EXT_CNTL;
-        unsigned long ulOrigCRTC_EXT_CNTL;
-        unsigned long ulOrigDAC_CNTL2;
-        unsigned long ulData;
-        unsigned long ulMask;
-
-	ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
-	OUTREG(RADEON_DAC_CNTL2, 2);
-
-        ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
-
-        ulData              = ulOrigVCLK_ECP_CNTL;
-        ulData             &= ~(RADEON_PIXCLK_ALWAYS_ONb
-                                | RADEON_PIXCLK_DAC_ALWAYS_ONb);
-        ulMask              = ~(RADEON_PIXCLK_ALWAYS_ONb
-                                |RADEON_PIXCLK_DAC_ALWAYS_ONb);
-        OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
-        ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
-        ulData              = ulOrigCRTC_EXT_CNTL;
-        ulData             |= RADEON_CRTC_CRT_ON;
-        OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
-   
-        ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
-        ulData             = ulOrigDAC_EXT_CNTL;
-        ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;
-        ulData            |=  (RADEON_DAC_FORCE_BLANK_OFF_EN
-                               |RADEON_DAC_FORCE_DATA_EN
-                               |RADEON_DAC_FORCE_DATA_SEL_MASK);
-        if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
-            (info->ChipFamily == CHIP_FAMILY_RV280))
-            ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
-        else
-            ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
-
-        OUTREG(RADEON_DAC_EXT_CNTL, ulData);
-
-        ulOrigDAC_CNTL     = INREG(RADEON_DAC_CNTL);
-        ulData             = ulOrigDAC_CNTL;
-        ulData            |= RADEON_DAC_CMP_EN;
-        ulData            &= ~(RADEON_DAC_RANGE_CNTL_MASK
-                               | RADEON_DAC_PDWN);
-        ulData            |= 0x2;
-        OUTREG(RADEON_DAC_CNTL, ulData);
-
-        usleep(1000);
-
-        ulData     = INREG(RADEON_DAC_CNTL);
-        bConnected =  (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
-  
-        ulData    = ulOrigVCLK_ECP_CNTL;
-        ulMask    = 0xFFFFFFFFL;
-        OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
-
-        OUTREG(RADEON_DAC_CNTL,      ulOrigDAC_CNTL     );
-        OUTREG(RADEON_DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
-        OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
-	OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
-    }
-    else
-    {
-        if (info->ChipFamily == CHIP_FAMILY_R200)
-        {
-#if 0
-            unsigned long ulOrigGPIO_MONID;
-            unsigned long ulOrigFP2_GEN_CNTL;
-            unsigned long ulOrigDISP_OUTPUT_CNTL;
-            unsigned long ulOrigCRTC2_GEN_CNTL;
-            unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
-            unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
-            unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
-            unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
-            unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
-            unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
-            unsigned long ulOrigCRTC2_H_TOTAL_DISP;
-            unsigned long ulOrigCRTC2_V_TOTAL_DISP;
-            unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
-            unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
-            unsigned long ulData, i;
-#endif
+    /* the monitor either wasn't connected or it is a non-DDC CRT.
+     * try to probe it
+     */
+    if(IsCrtDac) {
+	unsigned long ulOrigVCLK_ECP_CNTL;
+	unsigned long ulOrigDAC_CNTL;
+	unsigned long ulOrigDAC_MACRO_CNTL;
+	unsigned long ulOrigDAC_EXT_CNTL;
+	unsigned long ulOrigCRTC_EXT_CNTL;
+	unsigned long ulData;
+	unsigned long ulMask;
+
+	ulOrigVCLK_ECP_CNTL = INPLL(pScrn, RADEON_VCLK_ECP_CNTL);
+
+	ulData              = ulOrigVCLK_ECP_CNTL;
+	ulData             &= ~(RADEON_PIXCLK_ALWAYS_ONb
+				| RADEON_PIXCLK_DAC_ALWAYS_ONb);
+	ulMask              = ~(RADEON_PIXCLK_ALWAYS_ONb
+				|RADEON_PIXCLK_DAC_ALWAYS_ONb);
+	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+	ulOrigCRTC_EXT_CNTL = INREG(RADEON_CRTC_EXT_CNTL);
+	ulData              = ulOrigCRTC_EXT_CNTL;
+	ulData             |= RADEON_CRTC_CRT_ON;
+	OUTREG(RADEON_CRTC_EXT_CNTL, ulData);
+
+	ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
+	ulData             = ulOrigDAC_EXT_CNTL;
+	ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;
+	ulData            |=  (RADEON_DAC_FORCE_BLANK_OFF_EN
+			       |RADEON_DAC_FORCE_DATA_EN
+			       |RADEON_DAC_FORCE_DATA_SEL_MASK);
+	if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
+	    (info->ChipFamily == CHIP_FAMILY_RV280))
+	    ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
+	else
+	    ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
 
-/* This doesn't work on some cards, we always return false 
-   for now, If one wants to connected a non-DDC monitor on 
-   the DVI port, he has to specify it explicitly in
-   the config file with Option MonitorLayout.
-*/
-            return MT_NONE; /* **** code ends here ***** */
+	OUTREG(RADEON_DAC_EXT_CNTL, ulData);
 
-#if 0
-            ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
-            ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
-            ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
-            ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
-            ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
-            ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
-            ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
-            ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
-            ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
-            ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
-
-            ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
-            ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
-            ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
-            ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
-
-            ulData     = INREG(RADEON_GPIO_MONID);
-            ulData    &= ~RADEON_GPIO_A_0;
-            OUTREG(RADEON_GPIO_MONID, ulData);
-
-            OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
-
-            OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
-
-            OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
-            OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
-            OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
-            OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
-            OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+	ulOrigDAC_CNTL     = INREG(RADEON_DAC_CNTL);
 
-            for (i = 0; i < 200; i++)
-            {
-                ulData     = INREG(RADEON_GPIO_MONID);
-                bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
-                if (!bConnected) break;
-    
-                usleep(1000);
-            }
+	if (ulOrigDAC_CNTL & RADEON_DAC_PDWN) {
+	    /* turn on power so testing can go through */
+	    ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+	    ulOrigDAC_MACRO_CNTL &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+		RADEON_DAC_PDWN_B);
+	    OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+	}
+
+	ulData             = ulOrigDAC_CNTL;
+	ulData            |= RADEON_DAC_CMP_EN;
+	ulData            &= ~(RADEON_DAC_RANGE_CNTL_MASK
+			       | RADEON_DAC_PDWN);
+	ulData            |= 0x2;
+
+	OUTREG(RADEON_DAC_CNTL, ulData);
+
+	usleep(10000);
+
+	ulData     = INREG(RADEON_DAC_CNTL);
+	bConnected =  (RADEON_DAC_CMP_OUTPUT & ulData)?1:0;
+
+	ulData    = ulOrigVCLK_ECP_CNTL;
+	ulMask    = 0xFFFFFFFFL;
+	OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL, ulData, ulMask);
+
+	OUTREG(RADEON_DAC_CNTL,      ulOrigDAC_CNTL     );
+	OUTREG(RADEON_DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
+	OUTREG(RADEON_CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
+
+	if (!bConnected) {
+	    /* Power DAC down if CRT is not connected */
+            ulOrigDAC_MACRO_CNTL = INREG(RADEON_DAC_MACRO_CNTL);
+            ulOrigDAC_MACRO_CNTL |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G |
+	    	RADEON_DAC_PDWN_B);
+            OUTREG(RADEON_DAC_MACRO_CNTL, ulOrigDAC_MACRO_CNTL);
+
+	    ulData     = INREG(RADEON_DAC_CNTL);
+	    ulData     |= RADEON_DAC_PDWN ;
+	    OUTREG(RADEON_DAC_CNTL, ulData);
+    	}
+    } else { /* TV DAC */
+
+        /* This doesn't seem to work reliably (maybe worse on some OEM cards),
+           for now we always return false. If one wants to connected a
+           non-DDC monitor on the DVI port when CRT port is also connected,
+           he will need to explicitly tell the driver in the config file
+           with Option MonitorLayout.
+        */
+        bConnected = FALSE;
 
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
-            OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
-            OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
-            OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
-            OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
-            OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
-            OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
-            OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
-            OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
-            OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
-#endif
-        }
-        else
-        {
-            unsigned long ulOrigPIXCLKSDATA;
-            unsigned long ulOrigTV_MASTER_CNTL;
-            unsigned long ulOrigTV_DAC_CNTL;
-            unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
-            unsigned long ulOrigDAC_CNTL2;
-            unsigned long ulOrigCRTC2_GEN_CNTL;
-            unsigned long ulOrigDISP_OUTPUT_CNTL;
-            unsigned long ulOrigDAC_EXT_CNTL;
-            unsigned long ulData;
-            unsigned long ulMask;
-            int i;
-
-            ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
-
-            ulData            = ulOrigPIXCLKSDATA;
-            ulData           &= ~(RADEON_PIX2CLK_ALWAYS_ONb
-                                  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
-            ulMask            = ~(RADEON_PIX2CLK_ALWAYS_ONb
-                              | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
-            OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-
-            ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
-            ulData               = ulOrigTV_MASTER_CNTL;
-            ulData              &= ~RADEON_TVCLK_ALWAYS_ONb;
-            OUTREG(RADEON_TV_MASTER_CNTL, ulData);
-
-            ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
-            ulData          = ulOrigDAC_CNTL2; 
-            ulData          |= RADEON_DAC2_DAC2_CLK_SEL;
-            OUTREG(RADEON_DAC_CNTL2, ulData);
-        
-            ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
-            ulData          = ulOrigDISP_OUTPUT_CNTL & ~0xc;
-            OUTREG(RADEON_DISP_OUTPUT_CNTL, ulData);
-
-            ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
-            ulData          = ulOrigCRTC2_GEN_CNTL | RADEON_CRTC2_CRT2_ON;
-            OUTREG(RADEON_CRTC2_GEN_CNTL, ulData);
-
-            ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
-            ulData  =  (RADEON_Y_RED_EN
-                        | RADEON_C_GRN_EN
-                        | RADEON_CMP_BLU_EN
-                        | RADEON_RED_MX_FORCE_DAC_DATA
-                        | RADEON_GRN_MX_FORCE_DAC_DATA
-                        | RADEON_BLU_MX_FORCE_DAC_DATA);
+#if 0
+	if (info->ChipFamily == CHIP_FAMILY_R200) {
+	    unsigned long ulOrigGPIO_MONID;
+	    unsigned long ulOrigFP2_GEN_CNTL;
+	    unsigned long ulOrigDISP_OUTPUT_CNTL;
+	    unsigned long ulOrigCRTC2_GEN_CNTL;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_A;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_B;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_C;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_D;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_E;
+	    unsigned long ulOrigDISP_LIN_TRANS_GRPH_F;
+	    unsigned long ulOrigCRTC2_H_TOTAL_DISP;
+	    unsigned long ulOrigCRTC2_V_TOTAL_DISP;
+	    unsigned long ulOrigCRTC2_H_SYNC_STRT_WID;
+	    unsigned long ulOrigCRTC2_V_SYNC_STRT_WID;
+	    unsigned long ulData, i;
+
+	    ulOrigGPIO_MONID = INREG(RADEON_GPIO_MONID);
+	    ulOrigFP2_GEN_CNTL = INREG(RADEON_FP2_GEN_CNTL);
+	    ulOrigDISP_OUTPUT_CNTL = INREG(RADEON_DISP_OUTPUT_CNTL);
+	    ulOrigCRTC2_GEN_CNTL = INREG(RADEON_CRTC2_GEN_CNTL);
+	    ulOrigDISP_LIN_TRANS_GRPH_A = INREG(RADEON_DISP_LIN_TRANS_GRPH_A);
+	    ulOrigDISP_LIN_TRANS_GRPH_B = INREG(RADEON_DISP_LIN_TRANS_GRPH_B);
+	    ulOrigDISP_LIN_TRANS_GRPH_C = INREG(RADEON_DISP_LIN_TRANS_GRPH_C);
+	    ulOrigDISP_LIN_TRANS_GRPH_D = INREG(RADEON_DISP_LIN_TRANS_GRPH_D);
+	    ulOrigDISP_LIN_TRANS_GRPH_E = INREG(RADEON_DISP_LIN_TRANS_GRPH_E);
+	    ulOrigDISP_LIN_TRANS_GRPH_F = INREG(RADEON_DISP_LIN_TRANS_GRPH_F);
+
+	    ulOrigCRTC2_H_TOTAL_DISP = INREG(RADEON_CRTC2_H_TOTAL_DISP);
+	    ulOrigCRTC2_V_TOTAL_DISP = INREG(RADEON_CRTC2_V_TOTAL_DISP);
+	    ulOrigCRTC2_H_SYNC_STRT_WID = INREG(RADEON_CRTC2_H_SYNC_STRT_WID);
+	    ulOrigCRTC2_V_SYNC_STRT_WID = INREG(RADEON_CRTC2_V_SYNC_STRT_WID);
+
+	    ulData     = INREG(RADEON_GPIO_MONID);
+	    ulData    &= ~RADEON_GPIO_A_0;
+	    OUTREG(RADEON_GPIO_MONID, ulData);
+
+	    OUTREG(RADEON_FP2_GEN_CNTL, 0x0a000c0c);
+
+	    OUTREG(RADEON_DISP_OUTPUT_CNTL, 0x00000012);
+
+	    OUTREG(RADEON_CRTC2_GEN_CNTL, 0x06000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, 0x00000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, 0x000003f0);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, 0x00000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, 0x000003f0);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, 0x00000000);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, 0x000003f0);
+	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, 0x01000008);
+	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, 0x00000800);
+	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, 0x00080001);
+	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, 0x00000080);
+
+	    for (i = 0; i < 200; i++) {
+		ulData     = INREG(RADEON_GPIO_MONID);
+		bConnected = (ulData & RADEON_GPIO_Y_0)?1:0;
+		if (!bConnected) break;
+
+		usleep(1000);
+	    }
+
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_A, ulOrigDISP_LIN_TRANS_GRPH_A);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_B, ulOrigDISP_LIN_TRANS_GRPH_B);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_C, ulOrigDISP_LIN_TRANS_GRPH_C);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_D, ulOrigDISP_LIN_TRANS_GRPH_D);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_E, ulOrigDISP_LIN_TRANS_GRPH_E);
+	    OUTREG(RADEON_DISP_LIN_TRANS_GRPH_F, ulOrigDISP_LIN_TRANS_GRPH_F);
+	    OUTREG(RADEON_CRTC2_H_TOTAL_DISP, ulOrigCRTC2_H_TOTAL_DISP);
+	    OUTREG(RADEON_CRTC2_V_TOTAL_DISP, ulOrigCRTC2_V_TOTAL_DISP);
+	    OUTREG(RADEON_CRTC2_H_SYNC_STRT_WID, ulOrigCRTC2_H_SYNC_STRT_WID);
+	    OUTREG(RADEON_CRTC2_V_SYNC_STRT_WID, ulOrigCRTC2_V_SYNC_STRT_WID);
+	    OUTREG(RADEON_CRTC2_GEN_CNTL, ulOrigCRTC2_GEN_CNTL);
+	    OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
+	    OUTREG(RADEON_FP2_GEN_CNTL, ulOrigFP2_GEN_CNTL);
+	    OUTREG(RADEON_GPIO_MONID, ulOrigGPIO_MONID);
+        } else {
+	    unsigned long ulOrigPIXCLKSDATA;
+	    unsigned long ulOrigTV_MASTER_CNTL;
+	    unsigned long ulOrigTV_DAC_CNTL;
+	    unsigned long ulOrigTV_PRE_DAC_MUX_CNTL;
+	    unsigned long ulOrigDAC_CNTL2;
+	    unsigned long ulData;
+	    unsigned long ulMask;
+
+	    ulOrigPIXCLKSDATA = INPLL(pScrn, RADEON_PIXCLKS_CNTL);
+
+	    ulData            = ulOrigPIXCLKSDATA;
+	    ulData           &= ~(RADEON_PIX2CLK_ALWAYS_ONb
+				  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+	    ulMask            = ~(RADEON_PIX2CLK_ALWAYS_ONb
+			  | RADEON_PIX2CLK_DAC_ALWAYS_ONb);
+	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+	    ulOrigTV_MASTER_CNTL = INREG(RADEON_TV_MASTER_CNTL);
+	    ulData               = ulOrigTV_MASTER_CNTL;
+	    ulData              &= ~RADEON_TVCLK_ALWAYS_ONb;
+	    OUTREG(RADEON_TV_MASTER_CNTL, ulData);
+
+	    ulOrigDAC_CNTL2 = INREG(RADEON_DAC_CNTL2);
+	    ulData          = ulOrigDAC_CNTL2;
+	    ulData          &= ~RADEON_DAC2_DAC2_CLK_SEL;
+	    OUTREG(RADEON_DAC_CNTL2, ulData);
+
+	    ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
+
+	    ulData  = 0x00880213;
+	    OUTREG(RADEON_TV_DAC_CNTL, ulData);
+
+	    ulOrigTV_PRE_DAC_MUX_CNTL = INREG(RADEON_TV_PRE_DAC_MUX_CNTL);
+
+	    ulData  =  (RADEON_Y_RED_EN
+			| RADEON_C_GRN_EN
+			| RADEON_CMP_BLU_EN
+			| RADEON_RED_MX_FORCE_DAC_DATA
+			| RADEON_GRN_MX_FORCE_DAC_DATA
+			| RADEON_BLU_MX_FORCE_DAC_DATA);
             if (IS_R300_VARIANT)
-                ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
-            else
-                ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
-            OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
-
-            ulOrigTV_DAC_CNTL = INREG(RADEON_TV_DAC_CNTL);
-
-            ulData  = 0x00880213;
-            OUTREG(RADEON_TV_DAC_CNTL, ulData);
-            usleep(50000);
-
-            ulOrigDAC_EXT_CNTL = INREG(RADEON_DAC_EXT_CNTL);
-            ulData             = ulOrigDAC_EXT_CNTL;
-            ulData            &= ~RADEON_DAC_FORCE_DATA_MASK;
-            ulData            |=  (3 | RADEON_DAC_FORCE_DATA_SEL_MASK);
-            if ((info->ChipFamily == CHIP_FAMILY_RV250) ||
-                (info->ChipFamily == CHIP_FAMILY_RV280))
-                ulData |= (0x01b6 << RADEON_DAC_FORCE_DATA_SHIFT);
-            else
-                ulData |= (0x01ac << RADEON_DAC_FORCE_DATA_SHIFT);
-            OUTREG(RADEON_DAC_EXT_CNTL, ulData);
+		ulData |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+	    else
+		ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
 
-            usleep(1000);
+	    usleep(10000);
 
-            ulData     = INREG(RADEON_TV_DAC_CNTL);
-            bConnected = (ulData & RADEON_TV_DAC_CMPOUT) ? 1:0;
-#if 1
-            for (i = 0; i < 4; i++) {
-                ulData  = 0x00880203;
-                OUTREG(RADEON_TV_DAC_CNTL, ulData);
-                while(INREG(RADEON_TV_DAC_CNTL) & (1<<5)); 
-                ulData  = 0x00880213;
-                OUTREG(RADEON_TV_DAC_CNTL, ulData);
-                usleep(5000);
-                ulData     = INREG(RADEON_TV_DAC_CNTL);
-                bConnected = (ulData & RADEON_TV_DAC_CMPOUT) ? 1:0;
-                if (!bConnected) break;
-            }
-#endif            
-            ulData    = ulOrigPIXCLKSDATA;
-            ulMask    = 0xFFFFFFFFL;
-            OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
-        
-            OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
-            OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
-            OUTREG(RADEON_DAC_EXT_CNTL, ulOrigDAC_EXT_CNTL);
-            OUTREG(RADEON_DISP_OUTPUT_CNTL, ulOrigDISP_OUTPUT_CNTL);
-            OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
-            OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
-        }
-    }
+	    ulData     = INREG(RADEON_TV_DAC_CNTL);
+	    bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
 
-    return (bConnected ? MT_CRT : MT_NONE);
+	    ulData    = ulOrigPIXCLKSDATA;
+	    ulMask    = 0xFFFFFFFFL;
+	    OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+	    OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
+	    OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
+	    OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
+	    OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
+	}
+#endif
+    }
+    return(bConnected ? MT_CRT : MT_NONE);
 }
 
-
 static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, RADEONConnector* port)
 {
     RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -574,6 +713,8 @@ static RADEONMonitorType RADEONDisplayDD
     RADEONMonitorType MonType = MT_NONE;
     xf86MonPtr* MonInfo = &port->MonInfo;
     int i, j;
+    RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
+    int vbeProbe = FALSE;
 
     DDCReg = info->DDCReg;
     switch(DDCType)
@@ -588,13 +729,13 @@ static RADEONMonitorType RADEONDisplayDD
 	info->DDCReg = RADEON_GPIO_VGA_DDC;
 	break;
     case DDC_CRT2:
-	if ((info->ChipFamily == CHIP_FAMILY_R200) ||
-	    IS_R300_VARIANT) return MT_NONE;
 	info->DDCReg = RADEON_GPIO_CRT2_DDC;
 	break;
     default:
 	info->DDCReg = DDCReg;
+	/* Fall through, can still try ... 
 	return MT_NONE;
+	*/
     }
 
     /* Read and output monitor info using DDC2 over I2C bus */
@@ -618,7 +759,7 @@ static RADEONMonitorType RADEONDisplayDD
 		if (INREG(info->DDCReg) & RADEON_GPIO_Y_1)
 		    break;
 	    }
-	    if (i == 3) continue;
+	    if (i == 10) continue;
 
 	    usleep(15000);
 
@@ -657,21 +798,58 @@ static RADEONMonitorType RADEONDisplayDD
 	MonType = MT_NONE;
     }
 
-    OUTREG(info->DDCReg, INREG(info->DDCReg) & ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+    OUTREG(info->DDCReg, INREG(info->DDCReg) &
+	   ~(RADEON_GPIO_EN_0 | RADEON_GPIO_EN_1));
+
+    if ((!*MonInfo) && ((port == &pRADEONEnt->PortInfo[0]) ||
+	(RADEONCrtIsPhysicallyConnected(pScrn, !(pRADEONEnt->PortInfo[1].DACType)) 
+	== MT_CRT))) {
+	vbeProbe = TRUE;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE DDC probing on port %d ::: \n", 
+	    (port == &pRADEONEnt->PortInfo[0])? 1:2);
+	*MonInfo = RADEONProbeDDC(pScrn, info->pEnt->index);
+    }
 
     if (*MonInfo) {
 	if ((*MonInfo)->rawData[0x14] & 0x80) {
-	    if (port->TMDSType == TMDS_EXT) MonType = MT_DFP;
-	    else {
-	      if ((INREG(RADEON_FP_GEN_CNTL) & (1<<7)) || !info->IsMobility) MonType = MT_DFP;
-	      else MonType = MT_LCD;
+	    /* Note some laptops have a DVI output that uses internal TMDS,
+	     * when its DVI is enabled by hotkey, LVDS panel is not used.
+	     * In this case, the laptop is configured as DVI+VGA as a normal 
+	     * desktop card.
+	     * Also for laptop, when X starts with lid closed (no DVI connection)
+	     * both LDVS and TMDS are disable, we still need to treat it as a LVDS panel.
+	     */
+	    if (vbeProbe && 
+		(RADEONCrtIsPhysicallyConnected(pScrn, !(port->DACType)) == MT_CRT)) {
+	    	    MonType = MT_NONE;
+	    	    *MonInfo = NULL;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VBE probed DDC info nullified on port %d :::\n", (port == &pRADEONEnt->PortInfo[0])? 1:2);
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CRT physically connected but digital device indicated in DDC\n");
+	    } else {
+		if (port->TMDSType == TMDS_EXT) MonType = MT_DFP;
+	    	else {
+		    if ((INREG(RADEON_FP_GEN_CNTL) & RADEON_FP_EN_TMDS) || !info->IsMobility)
+		    	MonType = MT_DFP;
+		    else 
+		    	MonType = MT_LCD;
+		}
 	    }
-	} else MonType = MT_CRT;
+	} else  {
+	    	if ((RADEONCrtIsPhysicallyConnected(pScrn, 
+		    !(pRADEONEnt->PortInfo[1].DACType)) == MT_CRT) && vbeProbe && 
+		    (info->HasCRTC2) && (port == &pRADEONEnt->PortInfo[0])) {
+	    	    MonType = MT_NONE;
+	    	    *MonInfo = NULL;
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DDC info nullified on port 1 :::\n");
+		    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Analog device indicated in DDC but port 2 CRT physically connected\n");
+		} else
+	    	    MonType = MT_CRT;
+	}
     } else MonType = MT_NONE;
 
     info->DDCReg = DDCReg;
 
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO, 
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 	       "DDC Type: %d, Detected Type: %d\n", DDCType, MonType);
 
     return MonType;
@@ -962,7 +1140,9 @@ static void RADEONQueryConnectedDisplays
     pRADEONEnt->Controller[0].IsActive = FALSE;
     pRADEONEnt->Controller[1].IsActive = FALSE;
 
-    if (!RADEONGetConnectorInfoFromBIOS(pScrn)) {
+    if (!RADEONGetConnectorInfoFromBIOS(pScrn) ||
+        ((pRADEONEnt->PortInfo[0].DDCType == 0) &&
+        (pRADEONEnt->PortInfo[1].DDCType == 0))) {
 	/* Below is the most common setting, but may not be true */
         pRADEONEnt->PortInfo[0].MonType = MT_UNKNOWN;
         pRADEONEnt->PortInfo[0].MonInfo = NULL;
@@ -1107,6 +1287,7 @@ static void RADEONQueryConnectedDisplays
 
         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 
                    "MonitorLayout Option: \n\tMonitor1--Type %s, Monitor2--Type %s\n\n", s1, s2);
+
 #if 0
         if (pRADEONEnt->PortInfo[1].MonType == MT_CRT) {
                 pRADEONEnt->PortInfo[1].DACType = DAC_PRIMARY;
@@ -1120,6 +1301,7 @@ static void RADEONQueryConnectedDisplays
                 pRADEONEnt->PortInfo[0].MonInfo = NULL;
         }
 #endif
+
         /* some thinkpads and powerbooks use lvds and internal tmds 
 	 * at the same time.  --AGD
 	 */
@@ -1387,6 +1569,7 @@ static void RADEONDacPowerSet(ScrnInfoPt
 	switch(info->ChipFamily)
 	{
 	case CHIP_FAMILY_R420:
+	case CHIP_FAMILY_RV410:
 	    tv_dac_cntl = INREG(RADEON_TV_DAC_CNTL);
 	    if (IsOn) {
 		tv_dac_cntl &= ~(R420_TV_DAC_RDACPD |
@@ -1815,7 +1998,7 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
 				     (critical_point << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
 
     RADEONTRACE(("GRPH_BUFFER_CNTL from %x to %x\n",
-	       info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL)));
+		 (unsigned int)info->SavedReg.grph_buffer_cntl, INREG(RADEON_GRPH_BUFFER_CNTL)));
 
     if (mode2) {
 	stop_req = mode2->HDisplay * info2->CurrentLayout.pixel_bytes / 16;
@@ -1863,9 +2046,9 @@ void RADEONInitDispBandwidth(ScrnInfoPtr
 					  (critical_point2 << RADEON_GRPH_CRITICAL_POINT_SHIFT)));
 
 	RADEONTRACE(("GRPH2_BUFFER_CNTL from %x to %x\n",
-		     info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL)));
+		     (unsigned int)info->SavedReg.grph2_buffer_cntl, INREG(RADEON_GRPH2_BUFFER_CNTL)));
     }
-}   
+}
 
 /* Blank screen. */
 void RADEONBlank (ScrnInfoPtr pScrn)
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index e6ccf61..220778d 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -112,13 +112,6 @@
 #include "atipciids.h"
 #include "radeon_chipset.h"
 
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-#ifndef MIN
-#define MIN(a,b) ((a)>(b)?(b):(a))
-#endif
-
 				/* Forward definitions for driver functions */
 static Bool RADEONCloseScreen(int scrnIndex, ScreenPtr pScreen);
 static Bool RADEONSaveScreen(ScreenPtr pScreen, int mode);
@@ -130,8 +123,10 @@ static void RADEONGetMergedFBOptions(Scr
 static int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
 static void RADEONSetDynamicClock(ScrnInfoPtr pScrn, int mode);
 static void RADEONForceSomeClocks(ScrnInfoPtr pScrn);
-static void RADEONUpdatePanelSize(ScrnInfoPtr pScrn);
 static void RADEONSaveMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
+xf86MonPtr RADEONProbeDDC(ScrnInfoPtr pScrn, int indx);
+static RADEONMonitorType RADEONCrtIsPhysicallyConnected(ScrnInfoPtr pScrn, int IsCrtDac);
+  
 
 #ifdef XF86DRI
 static void RADEONAdjustMemMapRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save);
@@ -1110,9 +1105,12 @@ static void RADEONGetClockInfo(ScrnInfoP
     if (info->ChipFamily == CHIP_FAMILY_RV100 && !info->HasCRTC2) {
         /* Avoid RN50 corruption due to memory bandwidth starvation.
          * 18 is an empirical value based on the databook and Windows driver.
-        */
+         *
+         * Empirical value changed to 24 to raise pixel clock limit and
+         * allow higher resolution modes on capable monitors.
+         */
         pll->max_pll_freq = min(pll->max_pll_freq,
-                               18 * info->mclk * 100 / pScrn->bitsPerPixel *
+                               24 * info->mclk * 100 / pScrn->bitsPerPixel *
                                info->RamWidth / 16);
     }
 
@@ -2000,7 +1998,8 @@ static void RADEONSortModes(DisplayModeP
 
     p = *last;
     while (p) {
-	if ((((*new)->HDisplay < p->HDisplay) &&
+	if (((*new)->HDisplay < p->HDisplay) ||
+	    (((*new)->HDisplay == p->HDisplay) &&
 	     ((*new)->VDisplay < p->VDisplay)) ||
 	    (((*new)->HDisplay == p->HDisplay) &&
 	     ((*new)->VDisplay == p->VDisplay) &&
@@ -2707,6 +2706,9 @@ static Bool RADEONPreInitModes(ScrnInfoP
     int            modesFound;
     RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
     char           *s;
+    DisplayModePtr	first = NULL;
+    DisplayModePtr 	last = NULL;
+    DisplayModePtr 	start, mp;
 
     /* This option has two purposes:
      *
@@ -2763,7 +2765,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 		   "No DDC data available, DDCMode option is dismissed\n");
     }
-
+#if 0
     if ((info->DisplayType == MT_DFP) ||
 	(info->DisplayType == MT_LCD)) {
 	if ((s = xf86GetOptValString(info->Options, OPTION_PANEL_SIZE))) {
@@ -2817,6 +2819,7 @@ static Bool RADEONPreInitModes(ScrnInfoP
         } else
             RADEONGetPanelInfo(pScrn);
     }
+#endif
 
     if (pScrn->monitor->DDC) {
         /* If we still don't know sync range yet, let's try EDID.
@@ -2986,6 +2989,35 @@ static Bool RADEONPreInitModes(ScrnInfoP
 	}
     }
 
+    /* Sort the modes, retain the first */
+    if (pScrn->modes && (start = pScrn->modes->next)) {
+       /* Copy modelist into a new sorted modelist */
+       for (mp = start; mp != pScrn->modes; mp = mp->next) {
+           DisplayModePtr 	new = NULL;
+
+           new = xnfcalloc(1, sizeof (DisplayModeRec));
+           memcpy(new, mp, sizeof (DisplayModeRec));
+           new->name = strdup(mp->name);
+           RADEONSortModes(&new, &first, &last);
+       }
+
+       if (last && first) {
+           /* Clean up the old modelist */
+           start->prev = pScrn->modes->prev;
+           if (start->prev)
+               start->prev->next = start;
+           while (start) 
+               xf86DeleteMode(&start, start);
+
+           /* Switch to the new sorted modelist */
+           pScrn->modes->next = first;
+           pScrn->modes->prev = last;
+           first->prev = pScrn->modes;
+           last->next = pScrn->modes;
+
+       }
+    }
+
     pScrn->currentMode = pScrn->modes;
     if(info->MergedFB) {
        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -3560,15 +3592,18 @@ static Bool RADEONPreInitControllers(Scr
     return TRUE;
 }
 
-static void
+xf86MonPtr
 RADEONProbeDDC(ScrnInfoPtr pScrn, int indx)
 {
     vbeInfoPtr  pVbe;
+    xf86MonPtr monitor;
 
     if (xf86LoadSubModule(pScrn, "vbe")) {
 	pVbe = VBEInit(NULL,indx);
-	ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
-    }
+	monitor = vbeDoEDID(pVbe, NULL);
+	return (monitor);
+    } else
+	return (NULL);
 }
 
 _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr pScrn, int flags)
@@ -3588,7 +3623,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
 
     info               = RADEONPTR(pScrn);
     info->IsSecondary  = FALSE;
-    info->IsPrimary    = FALSE;
+    info->IsPrimary     = FALSE;
     info->MergedFB     = FALSE;
     info->IsSwitching  = FALSE;
     info->MMIO         = NULL;
@@ -3659,7 +3694,7 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     }
 
     if (flags & PROBE_DETECT) {
-	RADEONProbeDDC(pScrn, info->pEnt->index);
+	ConfiguredMonitor = RADEONProbeDDC(pScrn, info->pEnt->index);
 	RADEONPostInt10Check(pScrn, int10_save);
 	if(info->MMIO) RADEONUnmapMMIO(pScrn);
 	return TRUE;
@@ -3960,7 +3995,6 @@ static void RADEONLoadPalette(ScrnInfoPt
     int            i;
     int            idx, j;
     unsigned char  r, g, b;
-    CARD32 tmp = 0;
 
 #ifdef XF86DRI
     if (info->CPStarted && pScrn->pScreen) DRILock(pScrn->pScreen, 0);
@@ -3969,13 +4003,6 @@ static void RADEONLoadPalette(ScrnInfoPt
     if (info->accelOn && pScrn->pScreen)
         RADEON_SYNC(info, pScrn);
 
-    if (info->HasCRTC2) {
-	tmp = INPLL (pScrn, RADEON_PIXCLKS_CNTL);
-	OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL, 
-		 RADEON_PIX2CLK_SRC_SEL_CPUCLK,
-		 ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-    }
-
     if (info->FBDev) {
 	fbdevHWLoadPalette(pScrn, numColors, indices, colors, pVisual);
     } else {
@@ -4084,47 +4111,11 @@ static void RADEONLoadPalette(ScrnInfoPt
 	}
     }
 
-    if (info->HasCRTC2)
-	OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
 #ifdef XF86DRI
     if (info->CPStarted && pScrn->pScreen) DRIUnlock(pScrn->pScreen);
 #endif
 }
 
-#if 1
-/* Write palette data */
-static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
-{
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    unsigned char *RADEONMMIO = info->MMIO;
-    int            i;
-    CARD32 tmp = 0;
-
-    if (info->HasCRTC2) {
-	tmp = INPLL (pScrn, RADEON_PIXCLKS_CNTL);
-	OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL, 
-		 RADEON_PIX2CLK_SRC_SEL_CPUCLK,
-		 ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
-	PAL_SELECT(1);
-	OUTPAL_START(0);
-	for (i = 0; i < 256; i++) {
-	    OUTPAL_NEXT_CARD32(restore->palette2[i]);
-	}
-    }
-
-    PAL_SELECT(0);
-    OUTPAL_START(0);
-    for (i = 0; i < 256; i++) {
-	OUTPAL_NEXT_CARD32(restore->palette[i]);
-    }
-
-    if (info->HasCRTC2)
-	OUTREG(RADEON_PIXCLKS_CNTL, tmp);
-}
-#endif
-
 static void RADEONBlockHandler(int i, pointer blockData,
 			       pointer pTimeout, pointer pReadmask)
 {
@@ -5324,6 +5315,7 @@ static void RADEONRestoreCrtc2Registers(
 
     OUTREG(RADEON_DAC_CNTL2, restore->dac2_cntl);
 
+    /*OUTREG(RADEON_TV_DAC_CNTL, 0x00280203);*/
     if ((info->ChipFamily != CHIP_FAMILY_RADEON) &&
 	(info->ChipFamily != CHIP_FAMILY_R200)) 
 	OUTREG (RADEON_TV_DAC_CNTL, restore->tv_dac_cntl);
@@ -5529,7 +5521,6 @@ static void RADEONRestorePLLRegisters(Sc
     OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
 	    RADEON_VCLK_SRC_SEL_PPLLCLK,
 	    ~(RADEON_VCLK_SRC_SEL_MASK));
-
 }
 
 
@@ -5590,7 +5581,6 @@ static void RADEONRestorePLL2Registers(S
     OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
 	    RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
 	    ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
 }
 
 
@@ -5777,6 +5767,32 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
     RADEONSaveSurfaces(pScrn, &info->ModeReg);
 }
 
+#if 0
+/* Write palette data */
+static void RADEONRestorePalette(ScrnInfoPtr pScrn, RADEONSavePtr restore)
+{
+    RADEONInfoPtr  info       = RADEONPTR(pScrn);
+    unsigned char *RADEONMMIO = info->MMIO;
+    int            i;
+
+    if (!restore->palette_valid) return;
+
+    PAL_SELECT(1);
+    OUTPAL_START(0);
+    for (i = 0; i < 256; i++) {
+	RADEONWaitForFifo(pScrn, 32); /* delay */
+	OUTPAL_NEXT_CARD32(restore->palette2[i]);
+    }
+
+    PAL_SELECT(0);
+    OUTPAL_START(0);
+    for (i = 0; i < 256; i++) {
+	RADEONWaitForFifo(pScrn, 32); /* delay */
+	OUTPAL_NEXT_CARD32(restore->palette[i]);
+    }
+}
+#endif
+
 /* Write out state to define a new video mode */
 static void RADEONRestoreMode(ScrnInfoPtr pScrn, RADEONSavePtr restore)
 {
@@ -5787,6 +5803,16 @@ static void RADEONRestoreMode(ScrnInfoPt
 
     RADEONTRACE(("RADEONRestoreMode(%p)\n", restore));
 
+    /* For Non-dual head card, we don't have private field in the Entity */
+    if (!info->HasCRTC2) {
+	RADEONRestoreMemMapRegisters(pScrn, restore);
+	RADEONRestoreCommonRegisters(pScrn, restore);
+	RADEONRestoreCrtcRegisters(pScrn, restore);
+	RADEONRestoreFPRegisters(pScrn, restore);
+	RADEONRestorePLLRegisters(pScrn, restore);
+	return;
+    }
+
     /* When changing mode with Dual-head card, care must be taken for
      * the special order in setting registers. CRTC2 has to be set
      * before changing CRTC_EXT register.  In the dual-head setup, X
@@ -5911,7 +5937,6 @@ static void RADEONSaveCrtcRegisters(Scrn
     save->crtc_gen_cntl        = INREG(RADEON_CRTC_GEN_CNTL);
     save->crtc_ext_cntl        = INREG(RADEON_CRTC_EXT_CNTL);
     save->dac_cntl             = INREG(RADEON_DAC_CNTL);
-    save->tv_dac_cntl          = INREG(RADEON_TV_DAC_CNTL);
     save->crtc_h_total_disp    = INREG(RADEON_CRTC_H_TOTAL_DISP);
     save->crtc_h_sync_strt_wid = INREG(RADEON_CRTC_H_SYNC_STRT_WID);
     save->crtc_v_total_disp    = INREG(RADEON_CRTC_V_TOTAL_DISP);
@@ -5967,6 +5992,7 @@ static void RADEONSaveCrtc2Registers(Scr
     unsigned char *RADEONMMIO = info->MMIO;
 
     save->dac2_cntl             = INREG(RADEON_DAC_CNTL2);
+    save->tv_dac_cntl           = INREG(RADEON_TV_DAC_CNTL);
     save->disp_output_cntl      = INREG(RADEON_DISP_OUTPUT_CNTL);
     save->disp_tv_out_cntl      = INREG(RADEON_DISP_TV_OUT_CNTL);
     save->disp_hw_debug         = INREG (RADEON_DISP_HW_DEBUG);
@@ -6030,26 +6056,17 @@ static void RADEONSavePalette(ScrnInfoPt
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     unsigned char *RADEONMMIO = info->MMIO;
     int            i;
-    CARD32 tmp = 0;
-
-    if (info->HasCRTC2) {
-	tmp = INPLL (pScrn, RADEON_PIXCLKS_CNTL);
-	OUTPLLP (pScrn, RADEON_PIXCLKS_CNTL, 
-		 RADEON_PIX2CLK_SRC_SEL_CPUCLK,
-		 ~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
-	PAL_SELECT(1);
-	INPAL_START(0);
-	for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
-    }
 
+#ifdef ENABLE_FLAT_PANEL
+    /* Select palette 0 (main CRTC) if using FP-enabled chip */
+ /* if (info->Port1 == MT_DFP) PAL_SELECT(1); */
+#endif
+    PAL_SELECT(1);
+    INPAL_START(0);
+    for (i = 0; i < 256; i++) save->palette2[i] = INPAL_NEXT();
     PAL_SELECT(0);
     INPAL_START(0);
     for (i = 0; i < 256; i++) save->palette[i] = INPAL_NEXT();
-
-    if (info->HasCRTC2)
-	OUTPLL(pScrn, RADEON_PIXCLKS_CNTL, tmp);
-
     save->palette_valid = TRUE;
 }
 
@@ -6239,7 +6256,8 @@ static void RADEONInitCommonRegisters(RA
 static void RADEONInitTvDacCntl(ScrnInfoPtr pScrn, RADEONSavePtr save)
 {
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
-    if (info->ChipFamily == CHIP_FAMILY_R420) {
+    if (info->ChipFamily == CHIP_FAMILY_R420 ||
+	info->ChipFamily == CHIP_FAMILY_RV410) {
 	save->tv_dac_cntl &= ~(RADEON_TV_DAC_STD_MASK |
 			       RADEON_TV_DAC_BGADJ_MASK |
 			       R420_TV_DAC_DACADJ_MASK |
@@ -6259,7 +6277,7 @@ static void RADEONInitTvDacCntl(ScrnInfo
 			 RADEON_TV_DAC_NHOLD |
 			 RADEON_TV_DAC_STD_PS2 |
 			 info->tv_dac_adj);
-}
+}   
 
 static void RADEONInitFPRegisters(ScrnInfoPtr pScrn, RADEONSavePtr save,
 				  DisplayModePtr mode, BOOL IsPrimary)
@@ -6564,10 +6582,6 @@ Bool RADEONInitCrtcRegisters(ScrnInfoPtr
     save->crtc_pitch  = ((pScrn->displayWidth * pScrn->bitsPerPixel) +
 			 ((pScrn->bitsPerPixel * 8) -1)) / (pScrn->bitsPerPixel * 8);
     save->crtc_pitch |= save->crtc_pitch << 16;
-    
-    save->vclk_cntl = (info->SavedReg.vclk_cntl &
-	    ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
-
 
     /* Set following registers for all cases first, if a DFP/LCD is connected on
        internal TMDS/LVDS port, they will be set by RADEONInitFPRegister
@@ -6862,13 +6876,7 @@ Bool RADEONInitCrtc2Registers(ScrnInfoPt
 	    else
 		save->fp2_gen_cntl &= ~RADEON_FP2_PANEL_FORMAT;/* 18 bit format, */
         }
-    } 
-
-
-    save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
-			   ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
-			  RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
-
+    }
 
     /* We must set SURFACE_CNTL properly on the second screen too */
     save->surface_cntl = 0;
@@ -6956,6 +6964,10 @@ static void RADEONInitPLLRegisters(ScrnI
     save->ppll_ref_div   = pll->reference_div;
     save->ppll_div_3     = (save->feedback_div | (post_div->bitvalue << 16));
     save->htotal_cntl    = 0;
+
+    save->vclk_cntl = (info->SavedReg.vclk_cntl &
+	    ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK;
+
 }
 
 /* Define PLL2 registers for requested video mode */
@@ -6963,6 +6975,7 @@ static void RADEONInitPLL2Registers(Scrn
 				    RADEONPLLPtr pll, double dot_clock,
 				    int no_odd_postdiv)
 {
+    RADEONInfoPtr  info      = RADEONPTR(pScrn);
     unsigned long  freq = dot_clock * 100;
 
     struct {
@@ -7019,6 +7032,11 @@ static void RADEONInitPLL2Registers(Scrn
     save->p2pll_div_0      = (save->feedback_div_2 |
 			      (post_div->bitvalue << 16));
     save->htotal_cntl2     = 0;
+
+    save->pixclks_cntl = ((info->SavedReg.pixclks_cntl &
+			   ~(RADEON_PIX2CLK_SRC_SEL_MASK)) |
+			  RADEON_PIX2CLK_SRC_SEL_P2PLLCLK);
+
 }
 
 #if 0
diff --git a/src/radeon_mergedfb.c b/src/radeon_mergedfb.c
index 313dda2..f78c8bb 100644
--- a/src/radeon_mergedfb.c
+++ b/src/radeon_mergedfb.c
@@ -212,6 +212,12 @@ RADEONCopyModeNLink(ScrnInfoPtr pScrn, D
     mode->VSyncEnd += dy;
     mode->VTotal += dy;
 
+    /* This is needed for not generating negative refesh rates in xrandr with the
+       faked DotClock below
+     */
+    if (!(mode->VRefresh))
+        mode->VRefresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;
+
      /* Provide a sophisticated fake DotClock in order to trick the vidmode
       * extension to allow selecting among a number of modes whose merged result
       * looks identical but consists of different modes for CRT1 and CRT2
@@ -531,14 +537,26 @@ RADEONGenerateModeList(ScrnInfoPtr pScrn
    if(str != NULL) {
       return(RADEONGenerateModeListFromMetaModes(pScrn, str, i, j, srel));
    } else {
-      xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	"No MetaModes given, linking %s modes by default\n",
-	(srel == radeonClone) ? "largest common" :
-	   (info->NonRect ?
+	if (srel == radeonClone ) {
+      	   DisplayModePtr p, q, result = NULL;
+
+      	   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"Clone mode, list all common modes\n");
+	   for (p = i; p->next != i; p = p->next)
+		for (q = j; q->next != j; q = q->next)
+		   if ((p->HDisplay == q->HDisplay) &&
+			(p->VDisplay == q->VDisplay))
+		   	result = RADEONCopyModeNLink(pScrn, result, p, q, srel);
+	   return result;
+	} else {
+      	   xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		"No MetaModes given, linking %s modes by default\n",
+	   	(info->NonRect ?
 		(((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest" :  "tallest")
 		:
 		(((srel == radeonLeftOf) || (srel == radeonRightOf)) ? "widest common" :  "tallest common")) );
-      return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel));
+           return(RADEONGenerateModeListFromLargestModes(pScrn, i, j, srel));
+	}
    }
 }
 
diff --git a/src/radeon_reg.h b/src/radeon_reg.h
index 317699b..d873a96 100644
--- a/src/radeon_reg.h
+++ b/src/radeon_reg.h
@@ -3040,15 +3040,75 @@
 #define RADEON_SS_SHININESS                      60
 
 #define RADEON_TV_MASTER_CNTL                    0x0800
+#       define RADEON_TV_ASYNC_RST               (1 <<  0)
+#       define RADEON_CRT_ASYNC_RST              (1 <<  1)
+#       define RADEON_RESTART_PHASE_FIX          (1 <<  3)
+#       define RADEON_CRT_FIFO_CE_EN             (1 <<  9)
+#       define RADEON_TV_FIFO_CE_EN              (1 << 10)
 #       define RADEON_TVCLK_ALWAYS_ONb           (1 << 30)
-#define RADEON_TV_DAC_CNTL                       0x088c
-#       define RADEON_TV_DAC_CMPOUT              (1 << 5)
 #define RADEON_TV_PRE_DAC_MUX_CNTL               0x0888
 #       define RADEON_Y_RED_EN                   (1 << 0)
 #       define RADEON_C_GRN_EN                   (1 << 1)
 #       define RADEON_CMP_BLU_EN                 (1 << 2)
+#       define RADEON_DAC_DITHER_EN              (1 << 3)
 #       define RADEON_RED_MX_FORCE_DAC_DATA      (6 << 4)
 #       define RADEON_GRN_MX_FORCE_DAC_DATA      (6 << 8)
 #       define RADEON_BLU_MX_FORCE_DAC_DATA      (6 << 12)
 #       define RADEON_TV_FORCE_DAC_DATA_SHIFT    16
+#define RADEON_TV_RGB_CNTL                           0x0804
+#       define RADEON_SWITCH_TO_BLUE		  (1 <<  4)
+#       define RADEON_RGB_DITHER_EN		  (1 <<  5)
+#       define RADEON_RGB_SRC_SEL_MASK		  (3 <<  8)
+#       define RADEON_RGB_SRC_SEL_CRTC1		  (0 <<  8)
+#       define RADEON_RGB_SRC_SEL_RMX		  (1 <<  8)
+#       define RADEON_RGB_SRC_SEL_CRTC2		  (2 <<  8)
+#       define RADEON_RGB_CONVERT_BY_PASS	  (1 << 10)
+#define RADEON_TV_SYNC_CNTL                          0x0808
+#define RADEON_TV_HTOTAL                             0x080c
+#define RADEON_TV_HDISP                              0x0810
+#define RADEON_TV_HSTART                             0x0818
+#define RADEON_TV_HCOUNT                             0x081C
+#define RADEON_TV_VTOTAL                             0x0820
+#define RADEON_TV_VDISP                              0x0824
+#define RADEON_TV_VCOUNT                             0x0828
+#define RADEON_TV_FTOTAL                             0x082c
+#define RADEON_TV_FCOUNT                             0x0830
+#define RADEON_TV_FRESTART                           0x0834
+#define RADEON_TV_HRESTART                           0x0838
+#define RADEON_TV_VRESTART                           0x083c
+#define RADEON_TV_HOST_READ_DATA                     0x0840
+#define RADEON_TV_HOST_WRITE_DATA                    0x0844
+#define RADEON_TV_HOST_RD_WT_CNTL                    0x0848
+#define RADEON_TV_VSCALER_CNTL1                      0x084c
+#       define RADEON_RESTART_FIELD              (1 << 29) /* restart on field 0 */
+#       define RADEON_Y_DEL_W_SIG_SHIFT          26
+#define RADEON_TV_TIMING_CNTL                        0x0850
+#define RADEON_TV_VSCALER_CNTL2                      0x0854
+#       define RADEON_DITHER_MODE                (1 <<  0)
+#       define RADEON_Y_OUTPUT_DITHER_EN         (1 <<  1)
+#       define RADEON_UV_OUTPUT_DITHER_EN        (1 <<  2)
+#       define RADEON_UV_TO_BUF_DITHER_EN        (1 <<  3)
+#define RADEON_TV_Y_FALL_CNTL                        0x0858
+#       define RADEON_Y_FALL_PING_PONG           (1 << 16)
+#define RADEON_TV_Y_RISE_CNTL                        0x085c
+#       define RADEON_Y_RISE_PING_PONG           (1 << 16)
+#define RADEON_TV_Y_SAW_TOOTH_CNTL                   0x0860
+#define RADEON_TV_UPSAMP_AND_GAIN_CNTL               0x0864
+#define RADEON_TV_GAIN_LIMIT_SETTINGS                0x0868
+#define RADEON_TV_LINEAR_GAIN_SETTINGS               0x086c
+#define RADEON_TV_MODULATOR_CNTL1                    0x0870
+#       define RADEON_ALT_PHASE_EN               (1 <<  6)
+#       define RADEON_SYNC_TIP_LEVEL             (1 <<  7)
+#define RADEON_TV_MODULATOR_CNTL2                    0x0874
+#define RADEON_TV_CRC_CNTL                           0x0890
+#define RADEON_TV_UV_ADR                             0x08ac
+#define RADEON_TV_PLL_FINE_CNTL			     0x0020	/* PLL */
+#define RADEON_TV_PLL_CNTL                           0x0021	/* PLL */
+#       define RADEON_TV_SLIP_EN                 (1 << 23)
+#       define RADEON_TV_DTO_EN                  (1 << 28)
+#define RADEON_TV_PLL_CNTL1                          0x0022	/* PLL */
+#       define RADEON_TVPLL_TEST_DIS             (1 << 31)
+#       define RADEON_TVCLK_SRC_SEL_TVPLL        (1 << 30)
+#       define RADEON_TVPLL_SLEEP                (1 <<  3)
+#       define RADEON_TVPLL_REFCLK_SEL           (1 <<  4)
 #endif



More information about the xorg-commit mailing list