summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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