summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@samba.(none)>2006-09-16 12:24:33 -0400
committerAlex Deucher <alex@samba.(none)>2006-09-16 12:24:33 -0400
commita4545f40ca68797dfd7d93b4da72e5d195f5333f (patch)
treec4f654bb02c37d98ad8632ebf09f0b846e215fb0
parent8ac0d1dd86b6497d5d517af1f3dceb20aac5ee2b (diff)
Update to my latest code (also includes some of Henry's fixes)agd5f-superpatch
-rw-r--r--src/radeon.h108
-rw-r--r--src/radeon_display.c723
-rw-r--r--src/radeon_driver.c204
-rw-r--r--src/radeon_mergedfb.c28
-rw-r--r--src/radeon_reg.h64
5 files changed, 704 insertions, 423 deletions
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 RADEONGetLVDSInfoFromBIOS (ScrnInfoPtr pScrn);
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 [CHIP_FAMILY_LAST] =
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,274 +300,410 @@ void RADEONSetSyncRangeFromEdid(ScrnInfoPtr pScrn, int flag)
}
}
+#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);
+
+ OUTREG(RADEON_DAC_EXT_CNTL, ulData);
+
+ ulOrigDAC_CNTL = INREG(RADEON_DAC_CNTL);
-/* 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 ***** */
+ 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;
#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);
-
- 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 (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);
-#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);
+ 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);
-
- usleep(1000);
-
- 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 |= 0x180 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+ else
+ ulData |= 0x1f5 << RADEON_TV_FORCE_DAC_DATA_SHIFT;
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulData);
- return (bConnected ? MT_CRT : MT_NONE);
-}
+ usleep(10000);
+ ulData = INREG(RADEON_TV_DAC_CNTL);
+ bConnected = (ulData & RADEON_TV_DAC_CMPOUT)?1:0;
+
+ ulData = ulOrigPIXCLKSDATA;
+ ulMask = 0xFFFFFFFFL;
+ OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL, ulData, ulMask);
+
+ OUTREG(RADEON_TV_MASTER_CNTL, ulOrigTV_MASTER_CNTL);
+ OUTREG(RADEON_DAC_CNTL2, ulOrigDAC_CNTL2);
+ OUTREG(RADEON_TV_DAC_CNTL, ulOrigTV_DAC_CNTL);
+ OUTREG(RADEON_TV_PRE_DAC_MUX_CNTL, ulOrigTV_PRE_DAC_MUX_CNTL);
+ }
+#endif
+ }
+ return(bConnected ? MT_CRT : MT_NONE);
+}
static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCType DDCType, RADEONConnector* port)
{
@@ -574,6 +713,8 @@ static RADEONMonitorType RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT
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 RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT
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 RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT
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 RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, RADEONDDCT
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(ScrnInfoPtr pScrn)
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(ScrnInfoPtr pScrn)
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(ScrnInfoPtr pScrn)
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(ScrnInfoPtr pScrn, Bool IsOn, Bool IsPrimaryDAC)
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 pScrn)
(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 pScrn)
(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(ScrnInfoPtr pScrn);
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(ScrnInfoPtr pScrn)
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(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) &&
@@ -2707,6 +2706,9 @@ static Bool RADEONPreInitModes(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
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(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
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(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
} 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(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10)
}
}
+ /* 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(ScrnInfoPtr pScrn, xf86Int10InfoPtr pInt10
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 pScrn, int flags)
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 pScrn, int flags)
}
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(ScrnInfoPtr pScrn, int numColors,
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(ScrnInfoPtr pScrn, int numColors,
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(ScrnInfoPtr pScrn, int numColors,
}
}
- 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(ScrnInfoPtr pScrn,
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(ScrnInfoPtr pScrn,
OUTPLLP(pScrn, RADEON_VCLK_ECP_CNTL,
RADEON_VCLK_SRC_SEL_PPLLCLK,
~(RADEON_VCLK_SRC_SEL_MASK));
-
}
@@ -5590,7 +5581,6 @@ static void RADEONRestorePLL2Registers(ScrnInfoPtr pScrn,
OUTPLLP(pScrn, RADEON_PIXCLKS_CNTL,
RADEON_PIX2CLK_SRC_SEL_P2PLLCLK,
~(RADEON_PIX2CLK_SRC_SEL_MASK));
-
}
@@ -5777,6 +5767,32 @@ void RADEONChangeSurfaces(ScrnInfoPtr pScrn)
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(ScrnInfoPtr pScrn, RADEONSavePtr restore)
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(ScrnInfoPtr pScrn, RADEONSavePtr save)
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(ScrnInfoPtr pScrn, RADEONSavePtr save)
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(ScrnInfoPtr pScrn, RADEONSavePtr save)
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(RADEONSavePtr save, RADEONInfoPtr info)
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(ScrnInfoPtr pScrn, RADEONSavePtr save)
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 pScrn, RADEONSavePtr save,
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(ScrnInfoPtr pScrn, RADEONSavePtr save,
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(ScrnInfoPtr pScrn, RADEONInfoPtr info,
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(ScrnInfoPtr pScrn, RADEONSavePtr save,
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(ScrnInfoPtr pScrn, RADEONSavePtr save,
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, DisplayModePtr dest,
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, char* str,
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