From a4545f40ca68797dfd7d93b4da72e5d195f5333f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sat, 16 Sep 2006 12:24:33 -0400 Subject: Update to my latest code (also includes some of Henry's fixes) --- src/radeon.h | 108 ++++---- src/radeon_display.c | 723 +++++++++++++++++++++++++++++++------------------- src/radeon_driver.c | 204 +++++++------- src/radeon_mergedfb.c | 28 +- src/radeon_reg.h | 64 ++++- 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 /* 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 /* 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 -- cgit v1.2.3