Move output connection detection to a per-output method.
This will be used by RandR, and should let us clean up some of the initial display configuration, hopefully. Also, analog hotplug-based detection is now enabled on G965.
This commit is contained in:
parent
9fd719fce2
commit
68cef9f4e0
11
src/i830.h
11
src/i830.h
|
|
@ -207,6 +207,12 @@ struct _I830DVODriver {
|
|||
|
||||
extern const char *i830_output_type_names[];
|
||||
|
||||
enum detect_status {
|
||||
OUTPUT_STATUS_CONNECTED,
|
||||
OUTPUT_STATUS_DISCONNECTED,
|
||||
OUTPUT_STATUS_UNKNOWN
|
||||
};
|
||||
|
||||
struct _I830OutputRec {
|
||||
int type;
|
||||
int pipe;
|
||||
|
|
@ -258,6 +264,11 @@ struct _I830OutputRec {
|
|||
void (*post_set_mode)(ScrnInfoPtr pScrn, I830OutputPtr output,
|
||||
DisplayModePtr pMode);
|
||||
|
||||
/**
|
||||
* Probe for a connected output, and return detect_status.
|
||||
*/
|
||||
enum detect_status (*detect)(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
|
||||
xf86MonPtr MonInfo;
|
||||
I2CBusPtr pI2CBus;
|
||||
I2CBusPtr pDDCBus;
|
||||
|
|
|
|||
162
src/i830_crt.c
162
src/i830_crt.c
|
|
@ -112,6 +112,167 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
OUTREG(ADPA, adpa);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
|
||||
*
|
||||
* Only for I945G/GM.
|
||||
*
|
||||
* \return TRUE if CRT is connected.
|
||||
* \return FALSE if CRT is disconnected.
|
||||
*/
|
||||
static Bool
|
||||
i830_crt_detect_hotplug(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 temp;
|
||||
const int timeout_ms = 1000;
|
||||
int starttime, curtime;
|
||||
|
||||
temp = INREG(PORT_HOTPLUG_EN);
|
||||
|
||||
OUTREG(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
|
||||
|
||||
for (curtime = starttime = GetTimeInMillis();
|
||||
(curtime - starttime) < timeout_ms; curtime = GetTimeInMillis())
|
||||
{
|
||||
if ((INREG(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
|
||||
CRT_HOTPLUG_MONITOR_COLOR)
|
||||
{
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects CRT presence by checking for load.
|
||||
*
|
||||
* Requires that the current pipe's DPLL is active. This will cause flicker
|
||||
* on the CRT, so it should not be used while the display is being used. Only
|
||||
* color (not monochrome) displays are detected.
|
||||
*
|
||||
* \return TRUE if CRT is connected.
|
||||
* \return FALSE if CRT is disconnected.
|
||||
*/
|
||||
static Bool
|
||||
i830_crt_detect_load(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 adpa, pipeconf;
|
||||
CARD8 st00;
|
||||
int pipeconf_reg, bclrpat_reg, dpll_reg;
|
||||
int pipe;
|
||||
|
||||
pipe = pI830->pipe;
|
||||
if (pipe == 0) {
|
||||
bclrpat_reg = BCLRPAT_A;
|
||||
pipeconf_reg = PIPEACONF;
|
||||
dpll_reg = DPLL_A;
|
||||
} else {
|
||||
bclrpat_reg = BCLRPAT_B;
|
||||
pipeconf_reg = PIPEBCONF;
|
||||
dpll_reg = DPLL_B;
|
||||
}
|
||||
|
||||
/* Don't try this if the DPLL isn't running. */
|
||||
if (!(INREG(dpll_reg) & DPLL_VCO_ENABLE))
|
||||
return FALSE;
|
||||
|
||||
adpa = INREG(ADPA);
|
||||
|
||||
/* Enable CRT output if disabled. */
|
||||
if (!(adpa & ADPA_DAC_ENABLE)) {
|
||||
OUTREG(ADPA, adpa | ADPA_DAC_ENABLE |
|
||||
((pipe == 1) ? ADPA_PIPE_B_SELECT : 0));
|
||||
}
|
||||
|
||||
/* Set the border color to red, green. Maybe we should save/restore this
|
||||
* reg.
|
||||
*/
|
||||
OUTREG(bclrpat_reg, 0x00500050);
|
||||
|
||||
/* Force the border color through the active region */
|
||||
pipeconf = INREG(pipeconf_reg);
|
||||
OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
|
||||
|
||||
/* Read the ST00 VGA status register */
|
||||
st00 = pI830->readStandard(pI830, 0x3c2);
|
||||
|
||||
/* Restore previous settings */
|
||||
OUTREG(pipeconf_reg, pipeconf);
|
||||
OUTREG(ADPA, adpa);
|
||||
|
||||
if (st00 & (1 << 4))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects CRT presence by probing for a response on the DDC address.
|
||||
*
|
||||
* This takes approximately 5ms in testing on an i915GM, with CRT connected or
|
||||
* not.
|
||||
*
|
||||
* \return TRUE if the CRT is connected and responded to DDC.
|
||||
* \return FALSE if no DDC response was detected.
|
||||
*/
|
||||
static Bool
|
||||
i830_crt_detect_ddc(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
struct _I830OutputRec *output;
|
||||
|
||||
output = &pI830->output[0];
|
||||
/* CRT should always be at 0, but check anyway */
|
||||
if (output->type != I830_OUTPUT_ANALOG)
|
||||
return FALSE;
|
||||
|
||||
return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to detect CRT presence through any method available.
|
||||
*
|
||||
* @param allow_disturb enables detection methods that may cause flickering
|
||||
* on active displays.
|
||||
*/
|
||||
static enum detect_status
|
||||
i830_crt_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830)) {
|
||||
if (i830_crt_detect_hotplug(pScrn))
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
else
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
if (i830_crt_detect_ddc(pScrn))
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
|
||||
/* Use the load-detect method if we're not currently outputting to the CRT,
|
||||
* or we don't care.
|
||||
*
|
||||
* Actually, the method is unreliable currently. We need to not share a
|
||||
* pipe, as it seems having other outputs on that pipe will result in a
|
||||
* false positive.
|
||||
*/
|
||||
if (0) {
|
||||
if (i830_crt_detect_load(pScrn))
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
else
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
void
|
||||
i830_crt_init(ScrnInfoPtr pScrn)
|
||||
{
|
||||
|
|
@ -124,6 +285,7 @@ i830_crt_init(ScrnInfoPtr pScrn)
|
|||
pI830->output[pI830->num_outputs].mode_valid = i830_crt_mode_valid;
|
||||
pI830->output[pI830->num_outputs].pre_set_mode = i830_crt_pre_set_mode;
|
||||
pI830->output[pI830->num_outputs].post_set_mode = i830_crt_post_set_mode;
|
||||
pI830->output[pI830->num_outputs].detect = i830_crt_detect;
|
||||
|
||||
/* Set up the DDC bus. */
|
||||
I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
|
||||
|
|
|
|||
|
|
@ -831,150 +831,3 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
|
|||
pI830->output[i].pipe == 0 ? 'A' : 'B');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence.
|
||||
*
|
||||
* Only for I945G/GM.
|
||||
*/
|
||||
static Bool
|
||||
i830HotplugDetectCRT(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 temp;
|
||||
const int timeout_ms = 1000;
|
||||
int starttime, curtime;
|
||||
|
||||
temp = INREG(PORT_HOTPLUG_EN);
|
||||
|
||||
OUTREG(PORT_HOTPLUG_EN, temp | CRT_HOTPLUG_FORCE_DETECT | (1 << 5));
|
||||
|
||||
for (curtime = starttime = GetTimeInMillis();
|
||||
(curtime - starttime) < timeout_ms; curtime = GetTimeInMillis())
|
||||
{
|
||||
if ((INREG(PORT_HOTPLUG_EN) & CRT_HOTPLUG_FORCE_DETECT) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
|
||||
CRT_HOTPLUG_MONITOR_COLOR)
|
||||
{
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects CRT presence by checking for load.
|
||||
*
|
||||
* Requires that the current pipe's DPLL is active. This will cause flicker
|
||||
* on the CRT, so it should not be used while the display is being used. Only
|
||||
* color (not monochrome) displays are detected.
|
||||
*/
|
||||
static Bool
|
||||
i830LoadDetectCRT(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 adpa, pipeconf;
|
||||
CARD8 st00;
|
||||
int pipeconf_reg, bclrpat_reg, dpll_reg;
|
||||
int pipe;
|
||||
|
||||
pipe = pI830->pipe;
|
||||
if (pipe == 0) {
|
||||
bclrpat_reg = BCLRPAT_A;
|
||||
pipeconf_reg = PIPEACONF;
|
||||
dpll_reg = DPLL_A;
|
||||
} else {
|
||||
bclrpat_reg = BCLRPAT_B;
|
||||
pipeconf_reg = PIPEBCONF;
|
||||
dpll_reg = DPLL_B;
|
||||
}
|
||||
|
||||
/* Don't try this if the DPLL isn't running. */
|
||||
if (!(INREG(dpll_reg) & DPLL_VCO_ENABLE))
|
||||
return FALSE;
|
||||
|
||||
adpa = INREG(ADPA);
|
||||
|
||||
/* Enable CRT output if disabled. */
|
||||
if (!(adpa & ADPA_DAC_ENABLE)) {
|
||||
OUTREG(ADPA, adpa | ADPA_DAC_ENABLE |
|
||||
((pipe == 1) ? ADPA_PIPE_B_SELECT : 0));
|
||||
}
|
||||
|
||||
/* Set the border color to red, green. Maybe we should save/restore this
|
||||
* reg.
|
||||
*/
|
||||
OUTREG(bclrpat_reg, 0x00500050);
|
||||
|
||||
/* Force the border color through the active region */
|
||||
pipeconf = INREG(pipeconf_reg);
|
||||
OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
|
||||
|
||||
/* Read the ST00 VGA status register */
|
||||
st00 = pI830->readStandard(pI830, 0x3c2);
|
||||
|
||||
/* Restore previous settings */
|
||||
OUTREG(pipeconf_reg, pipeconf);
|
||||
OUTREG(ADPA, adpa);
|
||||
|
||||
if (st00 & (1 << 4))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects CRT presence by probing for a response on the DDC address.
|
||||
*
|
||||
* This takes approximately 5ms in testing on an i915GM, with CRT connected or
|
||||
* not.
|
||||
*/
|
||||
static Bool
|
||||
i830DDCDetectCRT(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
struct _I830OutputRec *output;
|
||||
|
||||
output = &pI830->output[0];
|
||||
/* CRT should always be at 0, but check anyway */
|
||||
if (output->type != I830_OUTPUT_ANALOG)
|
||||
return FALSE;
|
||||
|
||||
return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to detect CRT presence through any method available.
|
||||
*
|
||||
* @param allow_disturb enables detection methods that may cause flickering
|
||||
* on active displays.
|
||||
*/
|
||||
Bool
|
||||
i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
Bool found_ddc;
|
||||
|
||||
if (IS_I945G(pI830) || IS_I945GM(pI830))
|
||||
return i830HotplugDetectCRT(pScrn);
|
||||
|
||||
found_ddc = i830DDCDetectCRT(pScrn);
|
||||
if (found_ddc)
|
||||
return TRUE;
|
||||
|
||||
/* Use the load-detect method if we're not currently outputting to the CRT,
|
||||
* or we don't care.
|
||||
*
|
||||
* Actually, the method is unreliable currently. We need to not share a
|
||||
* pipe, as it seems having other outputs on that pipe will result in a
|
||||
* false positive.
|
||||
*/
|
||||
if (0 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
|
||||
return i830LoadDetectCRT(pScrn);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
Bool i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe);
|
||||
void i830DisableUnusedFunctions(ScrnInfoPtr pScrn);
|
||||
Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
|
||||
Bool i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb);
|
||||
void i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y);
|
||||
void i830WaitForVblank(ScrnInfoPtr pScrn);
|
||||
void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
|
||||
|
|
|
|||
|
|
@ -1439,28 +1439,36 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
pI830->operatingDevices = (pI830->MonType2 << 8) | pI830->MonType1;
|
||||
pI830->specifiedMonitor = TRUE;
|
||||
} else if (I830IsPrimary(pScrn)) {
|
||||
/* Choose a default set of outputs to use based on what we've detected. */
|
||||
if (i830DetectCRT(pScrn, TRUE)) {
|
||||
pI830->MonType1 |= PIPE_CRT;
|
||||
}
|
||||
|
||||
/* Check for attached SDVO outputs. Assume that they're flat panels for
|
||||
* now. Though really, it's just a name at the moment, since we don't
|
||||
* treat different SDVO outputs differently. Also, check for LVDS and
|
||||
* set it to the right pipe if available.
|
||||
/* Choose a default set of outputs to use based on what we've detected.
|
||||
*
|
||||
* Assume that SDVO outputs are flat panels for now. It's just a name
|
||||
* at the moment, since we don't treat different SDVO outputs
|
||||
* differently.
|
||||
*/
|
||||
for (i = 0; i < pI830->num_outputs; i++) {
|
||||
if (pI830->output[i].type == I830_OUTPUT_LVDS)
|
||||
pI830->MonType2 |= PIPE_LFP;
|
||||
pI830->MonType2 = PIPE_LFP;
|
||||
|
||||
if (pI830->output[i].type == I830_OUTPUT_SDVO) {
|
||||
if (!i830_sdvo_detect_displays(pScrn, &pI830->output[i]))
|
||||
if (pI830->output[i].type == I830_OUTPUT_SDVO ||
|
||||
pI830->output[i].type == I830_OUTPUT_ANALOG)
|
||||
{
|
||||
int pipetype;
|
||||
|
||||
if (pI830->output[i].detect(pScrn, &pI830->output[i]) ==
|
||||
OUTPUT_STATUS_DISCONNECTED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pI830->output[i].type == I830_OUTPUT_SDVO)
|
||||
pipetype = PIPE_DFP;
|
||||
else
|
||||
pipetype = PIPE_CRT;
|
||||
|
||||
if (pI830->MonType1 == PIPE_NONE)
|
||||
pI830->MonType1 |= PIPE_DFP;
|
||||
pI830->MonType1 |= pipetype;
|
||||
else if (pI830->MonType2 == PIPE_NONE)
|
||||
pI830->MonType2 |= PIPE_DFP;
|
||||
pI830->MonType2 |= pipetype;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3891,22 +3899,23 @@ i830MonitorDetectDebugger(ScrnInfoPtr pScrn)
|
|||
if (!pScrn->vtSema)
|
||||
return 1000;
|
||||
|
||||
start = GetTimeInMillis();
|
||||
found_crt = i830DetectCRT(pScrn, FALSE);
|
||||
finish = GetTimeInMillis();
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected CRT as %s in %dms\n",
|
||||
found_crt ? "connected" : "disconnected", finish - start);
|
||||
|
||||
for (i = 0; i < pI830->num_outputs; i++) {
|
||||
Bool found_sdvo = TRUE;
|
||||
enum output_status ret;
|
||||
char *result;
|
||||
|
||||
if (pI830->output[i].type != I830_OUTPUT_SDVO)
|
||||
continue;
|
||||
start = GetTimeInMillis();
|
||||
found_sdvo = i830_sdvo_detect_displays(pScrn, &pI830->output[i]);
|
||||
ret = pI830->output[i].detect(pScrn, &pI830->output[i]);
|
||||
finish = GetTimeInMillis();
|
||||
|
||||
if (ret == OUTPUT_STATUS_CONNECTED)
|
||||
result = "connected";
|
||||
else if (ret == OUTPUT_STATUS_DISCONNECTED)
|
||||
result = "disconnected";
|
||||
else
|
||||
result = "unknown";
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Detected SDVO as %s in %dms\n",
|
||||
found_sdvo ? "connected" : "disconnected", finish - start);
|
||||
result, finish - start);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -144,6 +144,17 @@ i830_dvo_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
OUTREG(DVOC, dvo);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the output connection on our DVO device.
|
||||
*
|
||||
* Unimplemented.
|
||||
*/
|
||||
static enum detect_status
|
||||
i830_dvo_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
|
||||
struct _I830DVODriver **retdrv)
|
||||
|
|
@ -189,6 +200,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
|
|||
pI830->output[i].mode_valid = i830_dvo_mode_valid;
|
||||
pI830->output[i].pre_set_mode = i830_dvo_pre_set_mode;
|
||||
pI830->output[i].post_set_mode = i830_dvo_post_set_mode;
|
||||
pI830->output[i].detect = i830_dvo_detect;
|
||||
|
||||
/* Set up the I2C and DDC buses */
|
||||
ret = I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E");
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "xf86.h"
|
||||
#include "i830.h"
|
||||
#include "i830_bios.h"
|
||||
|
||||
/**
|
||||
* Sets the power state for the panel.
|
||||
|
|
@ -176,6 +177,18 @@ i830_lvds_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
i830SetLVDSPanelPower(pScrn, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the LVDS connection.
|
||||
*
|
||||
* This always returns OUTPUT_STATUS_CONNECTED. This output should only have
|
||||
* been set up if the LVDS was actually connected anyway.
|
||||
*/
|
||||
static enum detect_status
|
||||
i830_lvds_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
}
|
||||
|
||||
void
|
||||
i830_lvds_init(ScrnInfoPtr pScrn)
|
||||
{
|
||||
|
|
@ -221,6 +234,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
|
|||
pI830->output[pI830->num_outputs].mode_valid = i830_lvds_mode_valid;
|
||||
pI830->output[pI830->num_outputs].pre_set_mode = i830_lvds_pre_set_mode;
|
||||
pI830->output[pI830->num_outputs].post_set_mode = i830_lvds_post_set_mode;
|
||||
pI830->output[pI830->num_outputs].detect = i830_lvds_detect;
|
||||
|
||||
/* Set up the LVDS DDC channel. Most panels won't support it, but it can
|
||||
* be useful if available.
|
||||
|
|
|
|||
|
|
@ -803,17 +803,18 @@ I830ReprobePipeModeList(ScrnInfoPtr pScrn, int pipe)
|
|||
* is plugged in, then assume that it is.
|
||||
*/
|
||||
if (pI830->pipeMon[pipe] == NULL) {
|
||||
enum detect_status detect;
|
||||
|
||||
detect = pI830->output[output_index].detect(pScrn,
|
||||
&pI830->output[output_index]);
|
||||
|
||||
switch (pI830->output[output_index].type) {
|
||||
case I830_OUTPUT_SDVO:
|
||||
if (i830_sdvo_detect_displays(pScrn, &pI830->output[output_index]))
|
||||
if (detect == OUTPUT_STATUS_CONNECTED)
|
||||
pI830->pipeMon[pipe] = i830GetConfiguredMonitor(pScrn);
|
||||
break;
|
||||
case I830_OUTPUT_ANALOG:
|
||||
/* Do a disruptive detect if necessary, since we want to be sure we
|
||||
* know if a monitor is attached, and this detect process should be
|
||||
* infrequent.
|
||||
*/
|
||||
if (i830DetectCRT(pScrn, TRUE)) {
|
||||
if (detect == OUTPUT_STATUS_CONNECTED) {
|
||||
/* if (pipe == pI830->pipe)
|
||||
pI830->pipeMon[pipe] = i830GetConfiguredMonitor(pScrn);
|
||||
else */
|
||||
|
|
|
|||
|
|
@ -904,8 +904,8 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
|
|||
*
|
||||
* Takes 14ms on average on my i945G.
|
||||
*/
|
||||
Bool
|
||||
i830_sdvo_detect_displays(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static enum detect_status
|
||||
i830_sdvo_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
CARD8 response[2];
|
||||
CARD8 status;
|
||||
|
|
@ -914,9 +914,12 @@ i830_sdvo_detect_displays(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
status = i830_sdvo_read_response(output, &response, 2);
|
||||
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return FALSE;
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
|
||||
return (response[0] != 0 || response[1] != 0);
|
||||
if (response[0] != 0 || response[1] != 0)
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
else
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -936,6 +939,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
output->mode_valid = i830_sdvo_mode_valid;
|
||||
output->pre_set_mode = i830_sdvo_pre_set_mode;
|
||||
output->post_set_mode = i830_sdvo_post_set_mode;
|
||||
output->detect = i830_sdvo_detect;
|
||||
|
||||
/* While it's the same bus, we just initialize a new copy to avoid trouble
|
||||
* with tracking refcounting ourselves, since the XFree86 DDX bits don't.
|
||||
|
|
|
|||
|
|
@ -31,8 +31,5 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device);
|
|||
int
|
||||
i830_sdvo_get_pixel_multiplier(DisplayModePtr pMode);
|
||||
|
||||
Bool
|
||||
i830_sdvo_detect_displays(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
|
||||
void
|
||||
i830_sdvo_dump(ScrnInfoPtr pScrn);
|
||||
|
|
|
|||
|
|
@ -405,6 +405,18 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
|
|||
OUTREG(TV_CTL, tv_ctl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the TV connection.
|
||||
*
|
||||
* Currently this always returns OUTPUT_STATUS_UNKNOWN, as we need to be sure
|
||||
* we have a pipe programmed in order to probe the TV.
|
||||
*/
|
||||
static enum detect_status
|
||||
i830_tv_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
void
|
||||
i830_tv_init(ScrnInfoPtr pScrn)
|
||||
{
|
||||
|
|
@ -425,6 +437,7 @@ i830_tv_init(ScrnInfoPtr pScrn)
|
|||
pI830->output[pI830->num_outputs].mode_valid = i830_tv_mode_valid;
|
||||
pI830->output[pI830->num_outputs].pre_set_mode = i830_tv_pre_set_mode;
|
||||
pI830->output[pI830->num_outputs].post_set_mode = i830_tv_post_set_mode;
|
||||
pI830->output[pI830->num_outputs].detect = i830_tv_detect;
|
||||
|
||||
pI830->num_outputs++;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue