diff options
author | Alex Deucher <alex@botch2.(none)> | 2007-08-27 23:44:13 -0400 |
---|---|---|
committer | Alex Deucher <alex@botch2.(none)> | 2007-08-27 23:44:13 -0400 |
commit | 42839fb5a8584196e7b18375bff6c426ed0347d9 (patch) | |
tree | 90ecc6e2c985a8576b19d8b856401aa2df73426f | |
parent | a5a1055d64ab4fa16bfb03a412ae6c4fe69ff65d (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.c | 60 | ||||
-rw-r--r-- | src/radeon_output.c | 83 | ||||
-rw-r--r-- | src/radeon_probe.h | 1 |
3 files changed, 104 insertions, 40 deletions
diff --git a/src/radeon_modes.c b/src/radeon_modes.c index a5e1cc4..687e388 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 35c6cbe..78f451e 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 3bbda49..947bf88 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 |