From a5a1055d64ab4fa16bfb03a412ae6c4fe69ff65d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 27 Aug 2007 22:42:22 -0400 Subject: RADEON: make tmds pll an output attribute sometimes the bios tmds plls are busted for certain monitors. sometimes the dirver tables are. Let the user pick at run time. --- src/radeon_bios.c | 17 ------------- src/radeon_output.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++---- src/radeon_probe.h | 7 ++++++ 3 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src/radeon_bios.c b/src/radeon_bios.c index 1ef0ff48..b24c4817 100644 --- a/src/radeon_bios.c +++ b/src/radeon_bios.c @@ -879,23 +879,6 @@ Bool RADEONGetTMDSInfoFromBIOS (xf86OutputPtr output) } return TRUE; } - - /* revision 4 has some problem as it appears in RV280, - comment it off for now, use default instead */ - /* - else if (RADEON_BIOS8(tmp) == 4) { - int stride = 0; - n = RADEON_BIOS8(tmp + 5) + 1; - if (n > 4) n = 4; - for (i=0; itmds_pll[i].value = RADEON_BIOS32(tmp+stride+0x08); - radeon_output->tmds_pll[i].freq = RADEON_BIOS16(tmp+stride+0x10); - if (i == 0) stride += 10; - else stride += 6; - } - return TRUE; - } - */ } } return FALSE; diff --git a/src/radeon_output.c b/src/radeon_output.c index c2b749ae..35c6cbe4 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -152,6 +152,7 @@ static RADEONMonitorType radeon_detect_tv(ScrnInfoPtr pScrn); static RADEONMonitorType radeon_detect_primary_dac(ScrnInfoPtr pScrn, Bool color); static RADEONMonitorType radeon_detect_tv_dac(ScrnInfoPtr pScrn, Bool color); static RADEONMonitorType radeon_detect_ext_dac(ScrnInfoPtr pScrn); +static void RADEONGetTMDSInfoFromTable(xf86OutputPtr output); void RADEONPrintPortMap(ScrnInfoPtr pScrn) { @@ -1009,6 +1010,15 @@ radeon_mode_set(xf86OutputPtr output, DisplayModePtr mode, xf86CrtcPtr crtc = output->crtc; RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private; + if (radeon_output->type == OUTPUT_DVI && + radeon_output->TMDSType == TMDS_INT) { + if (radeon_output->tmds_pll_table == TMDS_PLL_BIOS) { + if (!RADEONGetTMDSInfoFromBIOS(output)) + RADEONGetTMDSInfoFromTable(output); + } else + RADEONGetTMDSInfoFromTable(output); + } + RADEONInitOutputRegisters(pScrn, &info->ModeReg, adjusted_mode, output, radeon_crtc->crtc_id); if (radeon_crtc->crtc_id == 0) @@ -1564,6 +1574,7 @@ radeon_set_backlight_level(xf86OutputPtr output, int level) } static Atom backlight_atom; +static Atom tmds_pll_atom; static Atom rmx_atom; static Atom monitor_type_atom; static Atom tv_hsize_atom; @@ -1606,6 +1617,32 @@ radeon_create_resources(xf86OutputPtr output) } } + if (radeon_output->type == OUTPUT_DVI && + radeon_output->TMDSType == TMDS_INT) { + tmds_pll_atom = MAKE_ATOM("tmds_pll"); + + err = RRConfigureOutputProperty(output->randr_output, tmds_pll_atom, + FALSE, FALSE, FALSE, 0, NULL); + if (err != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "RRConfigureOutputProperty error, %d\n", err); + } + /* Set the current value of the property */ +#if defined(__powerpc__) + s = "driver"; +#else + s = "bios"; +#endif + err = RRChangeOutputProperty(output->randr_output, tmds_pll_atom, + XA_STRING, 8, PropModeReplace, strlen(s), (pointer)s, + FALSE, FALSE); + if (err != 0) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "RRChangeOutputProperty error, %d\n", err); + } + + } + /* RMX control - fullscreen, centered, keep ratio */ /* actually more of a crtc property as only crtc1 has rmx */ if (radeon_output->type == OUTPUT_LVDS || @@ -1785,6 +1822,19 @@ radeon_set_property(xf86OutputPtr output, Atom property, } else { return FALSE; } + } else if (property == tmds_pll_atom) { + const char *s; + if (value->type != XA_STRING || value->format != 8) + return FALSE; + s = (char*)value->data; + if (value->size == strlen("bios") && !strncmp("bios", s, strlen("bios"))) { + radeon_output->tmds_pll_table = TMDS_PLL_BIOS; + return TRUE; + } else if (value->size == strlen("driver") && !strncmp("driver", s, strlen("driver"))) { + radeon_output->tmds_pll_table = TMDS_PLL_DRIVER; + return TRUE; + } + return FALSE; } else if (property == monitor_type_atom) { const char *s; if (value->type != XA_STRING || value->format != 8) @@ -2256,13 +2306,25 @@ RADEONGetLVDSInfo (xf86OutputPtr output) } static void -RADEONGetTMDSInfo(xf86OutputPtr output) +RADEONGetTMDSInfoFromTable(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; RADEONInfoPtr info = RADEONPTR(pScrn); RADEONOutputPrivatePtr radeon_output = output->driver_private; int i; + for (i=0; i<4; i++) { + radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value; + radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq; + } +} + +static void +RADEONGetTMDSInfo(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + int i; + for (i=0; i<4; i++) { radeon_output->tmds_pll[i].value = 0; radeon_output->tmds_pll[i].freq = 0; @@ -2270,10 +2332,8 @@ RADEONGetTMDSInfo(xf86OutputPtr output) if (RADEONGetTMDSInfoFromBIOS(output)) return; - for (i=0; i<4; i++) { - radeon_output->tmds_pll[i].value = default_tmds_pll[info->ChipFamily][i].value; - radeon_output->tmds_pll[i].freq = default_tmds_pll[info->ChipFamily][i].freq; - } + RADEONGetTMDSInfoFromTable(output); + } static void diff --git a/src/radeon_probe.h b/src/radeon_probe.h index d79e7ad6..3bbda49e 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -122,6 +122,12 @@ typedef enum DVI_ANALOG } RADEONDviType; +typedef enum +{ + TMDS_PLL_BIOS, + TMDS_PLL_DRIVER +} RADEONTMDSPllType; + typedef struct { CARD32 freq; CARD32 value; @@ -196,6 +202,7 @@ typedef struct _RADEONOutputPrivateRec { int PanelPwrDly; int DotClock; RADEONTMDSPll tmds_pll[4]; + RADEONTMDSPllType tmds_pll_table; /* TV out */ TVStd default_tvStd; TVStd tvStd; -- cgit v1.2.3