summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@botch2.(none)>2007-08-27 23:44:13 -0400
committerAlex Deucher <alex@botch2.(none)>2007-08-27 23:44:13 -0400
commit42839fb5a8584196e7b18375bff6c426ed0347d9 (patch)
tree90ecc6e2c985a8576b19d8b856401aa2df73426f
parenta5a1055d64ab4fa16bfb03a412ae6c4fe69ff65d (diff)
RADEON: make load detection an output attribute for analog outputs
Since TV/VGA/DVI-I can share the TV DAC, we often get false detection of all inputs that share that DAC. Make load detection an output attribute. Enabled by default on primary dac and on cards where tv dac is (usually) dedicated to tv (non-IGP mobilities).
-rw-r--r--src/radeon_modes.c60
-rw-r--r--src/radeon_output.c83
-rw-r--r--src/radeon_probe.h1
3 files changed, 104 insertions, 40 deletions
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index a5e1cc4d..687e3888 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -289,47 +289,47 @@ RADEONProbeOutputModes(xf86OutputPtr output)
#endif
ErrorF("in RADEONProbeOutputModes\n");
-
- if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
- edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
- xf86OutputSetEDID (output, edid_mon);
+ if (output->status == XF86OutputStatusConnected) {
+ if (radeon_output->type == OUTPUT_DVI || radeon_output->type == OUTPUT_VGA) {
+ edid_mon = xf86OutputGetEDID (output, radeon_output->pI2CBus);
+ xf86OutputSetEDID (output, edid_mon);
- modes = xf86OutputGetEDIDModes (output);
- return modes;
- }
- if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
- modes = RADEONTVModes(output);
- return modes;
- }
- if (radeon_output->type == OUTPUT_LVDS) {
- /* okay we got DDC info */
- if (output->MonInfo) {
- /* Debug info for now, at least */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
- xf86PrintEDID(output->MonInfo);
+ modes = xf86OutputGetEDIDModes (output);
+ return modes;
+ }
+ if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
+ modes = RADEONTVModes(output);
+ return modes;
+ }
+ if (radeon_output->type == OUTPUT_LVDS) {
+ /* okay we got DDC info */
+ if (output->MonInfo) {
+ /* Debug info for now, at least */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %d\n", radeon_output->num);
+ xf86PrintEDID(output->MonInfo);
- modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
+ modes = xf86DDCGetModes(pScrn->scrnIndex, output->MonInfo);
- for (mode = modes; mode != NULL; mode = mode->next) {
- if (mode->Flags & V_DBLSCAN) {
- if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
- mode->status = MODE_CLOCK_RANGE;
+ for (mode = modes; mode != NULL; mode = mode->next) {
+ if (mode->Flags & V_DBLSCAN) {
+ if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
+ mode->status = MODE_CLOCK_RANGE;
+ }
}
- }
- xf86PruneInvalidModes(pScrn, &modes, TRUE);
+ xf86PruneInvalidModes(pScrn, &modes, TRUE);
- /* do some physcial size stuff */
- }
+ /* do some physcial size stuff */
+ }
- if (modes == NULL) {
- RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+ if (modes == NULL) {
+ RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+ }
}
}
if (modes) {
xf86ValidateModesUserConfig(pScrn, modes);
- xf86PruneInvalidModes(pScrn, &modes,
- FALSE);
+ xf86PruneInvalidModes(pScrn, &modes, FALSE);
}
return modes;
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 35c6cbe4..78f451ed 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -536,21 +536,29 @@ void RADEONConnectorFindMonitor(ScrnInfoPtr pScrn, xf86OutputPtr output)
if (radeon_output->MonType == MT_UNKNOWN) {
if (radeon_output->type == OUTPUT_STV || radeon_output->type == OUTPUT_CTV) {
- if (info->InternalTVOut)
- radeon_output->MonType = radeon_detect_tv(pScrn);
+ if (info->InternalTVOut) {
+ if (radeon_output->load_detection)
+ radeon_output->MonType = radeon_detect_tv(pScrn);
+ else
+ radeon_output->MonType = MT_NONE;
+ }
} else {
radeon_output->MonType = RADEONDisplayDDCConnected(pScrn, output);
if (!radeon_output->MonType) {
if (radeon_output->type == OUTPUT_LVDS || radeon_output->type == OUTPUT_DVI)
radeon_output->MonType = RADEONPortCheckNonDDC(pScrn, output);
if (!radeon_output->MonType) {
- if (radeon_output->DACType == DAC_PRIMARY)
- radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
- else if (radeon_output->DACType == DAC_TVDAC) {
- if (info->ChipFamily == CHIP_FAMILY_R200)
- radeon_output->MonType = radeon_detect_ext_dac(pScrn);
- else
- radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
+ if (radeon_output->DACType == DAC_PRIMARY) {
+ if (radeon_output->load_detection)
+ radeon_output->MonType = radeon_detect_primary_dac(pScrn, TRUE);
+ } else if (radeon_output->DACType == DAC_TVDAC) {
+ if (radeon_output->load_detection) {
+ if (info->ChipFamily == CHIP_FAMILY_R200)
+ radeon_output->MonType = radeon_detect_ext_dac(pScrn);
+ else
+ radeon_output->MonType = radeon_detect_tv_dac(pScrn, TRUE);
+ } else
+ radeon_output->MonType = MT_NONE;
}
}
}
@@ -1577,6 +1585,7 @@ static Atom backlight_atom;
static Atom tmds_pll_atom;
static Atom rmx_atom;
static Atom monitor_type_atom;
+static Atom load_detection_atom;
static Atom tv_hsize_atom;
static Atom tv_hpos_atom;
static Atom tv_vpos_atom;
@@ -1617,6 +1626,37 @@ radeon_create_resources(xf86OutputPtr output)
}
}
+ if (radeon_output->DACType == DAC_PRIMARY ||
+ radeon_output->DACType == DAC_TVDAC) {
+ load_detection_atom = MAKE_ATOM("load_detection");
+
+ range[0] = 0; /* off */
+ range[1] = 1; /* on */
+ err = RRConfigureOutputProperty(output->randr_output, load_detection_atom,
+ FALSE, TRUE, FALSE, 2, range);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRConfigureOutputProperty error, %d\n", err);
+ }
+
+ if (radeon_output->DACType == DAC_PRIMARY)
+ data = 1; /* primary dac, only drives vga */
+ else if (radeon_output->DACType == DAC_TVDAC &&
+ info->IsMobility &&
+ !info->IsIGP)
+ data = 1; /* laptops with tv only on tvdac */
+ else
+ data = 0; /* shared tvdac between vga/dvi/tv */
+
+ err = RRChangeOutputProperty(output->randr_output, load_detection_atom,
+ XA_INTEGER, 32, PropModeReplace, 1, &data,
+ FALSE, TRUE);
+ if (err != 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "RRChangeOutputProperty error, %d\n", err);
+ }
+ }
+
if (radeon_output->type == OUTPUT_DVI &&
radeon_output->TMDSType == TMDS_INT) {
tmds_pll_atom = MAKE_ATOM("tmds_pll");
@@ -1803,6 +1843,19 @@ radeon_set_property(xf86OutputPtr output, Atom property,
radeon_set_backlight_level(output, val);
+ } else if (property == load_detection_atom) {
+ if (value->type != XA_INTEGER ||
+ value->format != 32 ||
+ value->size != 1) {
+ return FALSE;
+ }
+
+ val = *(INT32 *)value->data;
+ if (val < 0 || val > 1)
+ return FALSE;
+
+ radeon_output->load_detection = val;
+
} else if (property == rmx_atom) {
xf86CrtcPtr crtc = output->crtc;
RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
@@ -2358,6 +2411,7 @@ RADEONGetTVInfo(xf86OutputPtr output)
void RADEONInitConnector(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
+ RADEONInfoPtr info = RADEONPTR(pScrn);
RADEONOutputPrivatePtr radeon_output = output->driver_private;
int DDCReg = 0;
char* name = (char*) DDCTypeName[radeon_output->DDCType];
@@ -2370,7 +2424,16 @@ void RADEONInitConnector(xf86OutputPtr output)
case DDC_LCD : DDCReg = RADEON_LCD_GPIO_MASK; break;
default: break;
}
-
+
+ if (radeon_output->DACType == DAC_PRIMARY)
+ radeon_output->load_detection = 1; /* primary dac, only drives vga */
+ else if (radeon_output->DACType == DAC_TVDAC &&
+ info->IsMobility &&
+ !info->IsIGP)
+ radeon_output->load_detection = 1; /* laptops with tv only on tvdac */
+ else
+ radeon_output->load_detection = 0; /* shared tvdac between vga/dvi/tv */
+
if (DDCReg) {
radeon_output->DDCReg = DDCReg;
RADEONI2CInit(pScrn, &radeon_output->pI2CBus, DDCReg, name);
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 3bbda49e..947bf88f 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -211,6 +211,7 @@ typedef struct _RADEONOutputPrivateRec {
int hSize;
float TVRefClk;
int SupportedTVStds;
+ int load_detection;
} RADEONOutputPrivateRec, *RADEONOutputPrivatePtr;
#define RADEON_MAX_CRTC 2