diff options
-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 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 |