From 2f93cfbc7e96acc32efb5e1ca49b817a81cba6e3 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Fri, 19 Sep 2008 15:20:55 +0800 Subject: Fix output detection for DVI-I For CRT this trys to probe all possible port for EDID and detects got confirmed by EDID's d/a type bit. For HDMI/DVI, also using EDID d/a type bit to ensure it should handle the connect or not. --- src/i830_crt.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/i830_hdmi.c | 10 +++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/i830_crt.c b/src/i830_crt.c index 8274c0cc..5812e2b7 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -410,6 +410,49 @@ i830_crt_get_crtc(xf86OutputPtr output) } #endif +static xf86MonPtr +i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + xf86MonPtr edid_mon = NULL; + + /* Set up the DDC bus. */ + if (gpio_reg != GPIOA) + I830I2CInit(output->scrn, &intel_output->pDDCBus, gpio_reg, gpio_str); + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + + if (!edid_mon || DIGITAL(edid_mon->features.input_type)) { + xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); + if (edid_mon) { + xfree(edid_mon); + edid_mon = NULL; + } + } + return edid_mon; +} + +static DisplayModePtr +i830_crt_get_modes (xf86OutputPtr output) +{ + DisplayModePtr modes; + xf86MonPtr edid_mon = NULL; + + /* Try to probe normal CRT port, and also digital port for output + in DVI-I mode. */ + if ((edid_mon = i830_get_edid(output, GPIOA, "CRTDDC_A"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOD, "CRTDDC_D"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOE, "CRTDDC_E"))) + goto found; +found: + xf86OutputSetEDID (output, edid_mon); + + modes = xf86OutputGetEDIDModes (output); + return modes; +} + static const xf86OutputFuncsRec i830_crt_output_funcs = { .dpms = i830_crt_dpms, .save = i830_crt_save, @@ -420,7 +463,7 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = { .mode_set = i830_crt_mode_set, .commit = i830_output_commit, .detect = i830_crt_detect, - .get_modes = i830_ddc_get_modes, + .get_modes = i830_crt_get_modes, .destroy = i830_crt_destroy, #ifdef RANDR_GET_CRTC_INTERFACE .get_crtc = i830_crt_get_crtc, diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c index d56eec90..44e5c056 100644 --- a/src/i830_hdmi.c +++ b/src/i830_hdmi.c @@ -139,6 +139,8 @@ i830_hdmi_detect(xf86OutputPtr output) struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; I830Ptr pI830 = I830PTR(pScrn); uint32_t temp, bit; + xf86OutputStatus status; + xf86MonPtr edid_mon; /* For G4X, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. * Failure to do so will result in spurious interrupts being @@ -171,9 +173,15 @@ i830_hdmi_detect(xf86OutputPtr output) } if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0) - return XF86OutputStatusConnected; + status = XF86OutputStatusConnected; else return XF86OutputStatusDisconnected; + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + if (!edid_mon || !DIGITAL(edid_mon->features.input_type)) + status = XF86OutputStatusDisconnected; + xfree(edid_mon); + return status; } static void -- cgit v1.2.3