summaryrefslogtreecommitdiff
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
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.
-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 1ef0ff4..b24c481 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 c2b749a..35c6cbe 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 d79e7ad..3bbda49 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;