[Intel-gfx] [PATCH] SDVO: use attached display flags for output setup

Zhenyu Wang zhenyu.z.wang at intel.com
Wed Dec 10 04:38:18 CET 2008


SDVO encoder's capability flag can't be used to
determine what current output type is, driver may
initialize wrong output type for this, e.g chrontel
7021 claims both RGB and TV capability, but real
output depends on board vendor.

This one trys to use GET_ATTACHED_DISPLAYS command
to setup output according with current config. Tested
on one 915G board with chrontel 7021 showed correct
detect result.
---
 src/i830_sdvo.c |   68 ++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 16 deletions(-)

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 256d16d..f15cb04 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -66,6 +66,11 @@ struct i830_sdvo_priv {
      */
     struct i830_sdvo_caps caps;
 
+    /**
+     * SDVO devices currently attached by i830_sdvo_get_attached_display()
+     */
+    uint16_t attached_output;
+
     /** Pixel clock limitations reported by the SDVO device, in kHz */
     int pixel_clock_min, pixel_clock_max;
 
@@ -1450,6 +1455,18 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
     }
 }
 
+static Bool
+i830_sdvo_get_attached_display (xf86OutputPtr output, uint16_t* response)
+{
+    uint8_t status;
+
+    i830_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+    status = i830_sdvo_read_response(output, response, 2);
+    if (status != SDVO_CMD_STATUS_SUCCESS)
+	return FALSE;
+    return TRUE;
+}
+
 /**
  * Asks the SDVO device if any displays are currently connected.
  *
@@ -1462,16 +1479,12 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
 static xf86OutputStatus
 i830_sdvo_detect(xf86OutputPtr output)
 {
-    uint8_t response[2];
-    uint8_t status;
+    uint16_t response;
 
-    i830_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
-    status = i830_sdvo_read_response(output, &response, 2);
-
-    if (status != SDVO_CMD_STATUS_SUCCESS)
+    if (i830_sdvo_get_attached_display(output, &response) == FALSE)
 	return XF86OutputStatusUnknown;
 
-    if (response[0] != 0 || response[1] != 0)
+    if (response != 0)
 	return XF86OutputStatusConnected;
     else
 	return XF86OutputStatusDisconnected;
@@ -1753,6 +1766,7 @@ i830_sdvo_get_digital_encoding_mode(xf86OutputPtr output)
 Bool
 i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 {
+    I830Ptr		    pI830 = I830PTR(pScrn);
     xf86OutputPtr	    output;
     I830OutputPrivatePtr    intel_output;
     struct i830_sdvo_priv   *dev_priv;
@@ -1866,11 +1880,32 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     intel_output->pDDCBus = ddcbus;
     intel_output->dev_priv = dev_priv;
 
-    i830_sdvo_get_capabilities(output, &dev_priv->caps);
+    if (i830_sdvo_get_capabilities(output, &dev_priv->caps) == FALSE ||
+	    dev_priv->caps.output_flags == 0)
+    {
+	xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING,
+		"SDVO%c can't get encoder capability\n",
+		output_device == SDVOB ? 'B' : 'C');
+	xf86OutputDestroy (output);
+	return FALSE;
+    }
+
+    if (i830_sdvo_get_attached_display (output, &dev_priv->attached_output)
+	    == FALSE) {
+	xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING,
+		"SDVO%c can't get attached displays\n",
+		output_device == SDVOB ? 'B' : 'C');
+	xf86OutputDestroy (output);
+	return FALSE;
+    } else if (pI830->debug_modes)
+	xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO,
+		"SDVO%c attached display 0x%x\n",
+		output_device == SDVOB ? 'B' : 'C',
+		dev_priv->attached_output);
 
-    if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
+    if (dev_priv->attached_output & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
     {
-	if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
+	if (dev_priv->attached_output & SDVO_OUTPUT_TMDS0)
 	    dev_priv->controlled_output = SDVO_OUTPUT_TMDS0;
 	else
 	    dev_priv->controlled_output = SDVO_OUTPUT_TMDS1;
@@ -1886,7 +1921,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 	    name_prefix = "HDMI";
 	}
     }
-    else if (dev_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
+    else if (dev_priv->attached_output & SDVO_OUTPUT_SVID0)
     {
 	dev_priv->controlled_output = SDVO_OUTPUT_SVID0;
         output->subpixel_order = SubPixelHorizontalRGB; /* XXX */
@@ -1894,13 +1929,13 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 	dev_priv->is_tv = TRUE;
 	intel_output->needs_tv_clock = TRUE;
     }
-    else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
+    else if (dev_priv->attached_output & SDVO_OUTPUT_RGB0)
     {
 	dev_priv->controlled_output = SDVO_OUTPUT_RGB0;
         output->subpixel_order = SubPixelHorizontalRGB;
 	name_prefix="VGA";
     }
-    else if (dev_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
+    else if (dev_priv->attached_output & SDVO_OUTPUT_RGB1)
     {
 	dev_priv->controlled_output = SDVO_OUTPUT_RGB1;
         output->subpixel_order = SubPixelHorizontalRGB;
@@ -1911,7 +1946,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 	unsigned char	bytes[2];
 
 	dev_priv->controlled_output = 0;
-	memcpy (bytes, &dev_priv->caps.output_flags, 2);
+	memcpy (bytes, &dev_priv->attached_output, 2);
 	xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING,
 		   "%s: Unknown SDVO output type (0x%02x%02x)\n",
 		   SDVO_NAME(dev_priv),
@@ -1936,11 +1971,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 					  &dev_priv->pixel_clock_max);
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "%s: device VID/DID: %02X:%02X.%02X, "
+	       "%s: device VID/DID: %02X:%02X.%02X cap: 0x%x "
 	       "clock range %.1fMHz - %.1fMHz\n",
 	       SDVO_NAME(dev_priv),
 	       dev_priv->caps.vendor_id, dev_priv->caps.device_id,
 	       dev_priv->caps.device_rev_id,
+	       dev_priv->caps.output_flags,
 	       dev_priv->pixel_clock_min / 1000.0,
 	       dev_priv->pixel_clock_max / 1000.0);
 
@@ -1950,7 +1986,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 	       dev_priv->caps.sdvo_input_count >= 2 ? "s" : "");
 
 #define REPORT_OUTPUT_FLAG(flag, name) do {				\
-    if (dev_priv->caps.output_flags & flag) {				\
+    if (dev_priv->attached_output & flag) {				\
 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: %s output reported\n", \
 		   SDVO_NAME(dev_priv), name);				\
     }									\
-- 
1.5.6.5




More information about the Intel-gfx mailing list