xf86-video-intel: src/i830_crt.c src/i830_hdmi.c

Zhenyu Wang zhen at kemper.freedesktop.org
Fri Sep 19 00:28:11 PDT 2008


 src/i830_crt.c  |   45 ++++++++++++++++++++++++++++++++++++++++++++-
 src/i830_hdmi.c |   10 +++++++++-
 2 files changed, 53 insertions(+), 2 deletions(-)

New commits:
commit 2f93cfbc7e96acc32efb5e1ca49b817a81cba6e3
Author: Zhenyu Wang <zhenyu.z.wang at intel.com>
Date:   Fri Sep 19 15:20:55 2008 +0800

    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.

diff --git a/src/i830_crt.c b/src/i830_crt.c
index 8274c0c..5812e2b 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 d56eec9..44e5c05 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


More information about the xorg-commit mailing list