summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Deucher <alex@botch2.(none)>2007-08-27 22:42:22 -0400
committerAlex Deucher <alex@botch2.(none)>2007-08-27 22:42:22 -0400
commita5a1055d64ab4fa16bfb03a412ae6c4fe69ff65d (patch)
tree8bdc0c15a1a62a9cdff9fc33c3d7a0757d35873d /src
parenta12e4aa01bf1c5723c3c791ff9bdc26eef21d5ea (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/radeon_bios.c17
-rw-r--r--src/radeon_output.c70
-rw-r--r--src/radeon_probe.h7
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; i<n; i++) {
- radeon_output->tmds_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,7 +2306,7 @@ RADEONGetLVDSInfo (xf86OutputPtr output)
}
static void
-RADEONGetTMDSInfo(xf86OutputPtr output)
+RADEONGetTMDSInfoFromTable(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
RADEONInfoPtr info = RADEONPTR(pScrn);
@@ -2264,16 +2314,26 @@ RADEONGetTMDSInfo(xf86OutputPtr output)
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;
}
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;