[Intel-gfx] [PATCH 1/2]initialize sdvo lvds output

Ma Ling ling.ma at intel.com
Fri Mar 13 07:15:52 CET 2009


set sdvo lvds output and fetch fixed mode for sdvo as soon as possible.

Signed-off-by: Ma Ling <ling.ma at intel.com>
---
 src/i830_sdvo.c |   88 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 254b866..76f21d3 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -90,6 +90,10 @@ struct i830_sdvo_priv {
      * This is set if we treat the device as HDMI, instead of DVI.
      */
     Bool is_hdmi;
+    /**
+     * This is set if we detect output of sdvo device as LVDS.
+     */
+    Bool is_lvds;
 
     /**
      * Returned SDTV resolutions allowed for the current format, if the
@@ -1531,6 +1535,67 @@ i830_sdvo_check_hdmi_encode (xf86OutputPtr output)
 	return FALSE;
 }
 
+/* This function will try to fetch lvds fixed mode from sdvo device*/
+static Bool i830_sdvo_fetch_fixed_mode(xf86OutputPtr  output)
+{
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    I830Ptr                 pI830 = I830PTR(output->scrn);
+    DisplayModePtr          modes, scan;
+    xf86CrtcPtr             crtc;
+    uint32_t                sdvox;
+    uint32_t                pipe;
+    int                     output_device;
+    Bool                    ret = TRUE;
+
+    output_device = ((struct i830_sdvo_priv *)
+                    (intel_output->dev_priv))->output_device;
+
+    /* Attempt to get the fixed panel mode from DDC.
+     * Assume that the preferred,mode is the right one.
+     * Mode list is arranged in priority order,
+     * so first ones are preferred.
+     */
+    modes = i830_ddc_get_modes(output);
+    for (scan = modes; scan != NULL; scan = scan->next) {
+        if (scan->type & M_T_PREFERRED) {
+            /* Pull our chosen mode out
+             * and make it the fixed mode.
+             */
+            if (modes == scan)
+                modes = modes->next;
+            if (scan->prev != NULL)
+                scan->prev = scan->next;
+            if (scan->next != NULL)
+                scan->next = scan->prev;
+            pI830->lvds_fixed_mode = scan;
+            goto end;
+        }
+    }
+
+    /* If we *still* don't have a mode, try checking if the panel is already
+     * turned on.  If so, assume that whatever is currently programmed is the
+     * correct mode.
+     */
+    sdvox = INREG(output_device);
+    pipe = (sdvox & SDVO_PIPE_B_SELECT) ? 1 : 0;
+    crtc = XF86_CRTC_CONFIG_PTR(output->scrn)->crtc[pipe];
+
+    if ((sdvox & SDVO_ENABLE) &&
+        (pI830->lvds_fixed_mode = i830_crtc_mode_get(output->scrn, crtc))) {
+        pI830->lvds_fixed_mode->type |= M_T_PREFERRED;
+        goto end;
+    }
+
+    /* failed to find fixed mode*/
+    ret = FALSE;
+end:
+    /* Delete the mode list we allocated */
+    while (modes != NULL)
+        xf86DeleteMode(&modes, modes);
+
+    return ret;
+}
+
 static void i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv);
 
 static Bool
@@ -1549,6 +1614,7 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
     /* clear up privates */
     dev_priv->is_tv = FALSE;
     intel_output->needs_tv_clock = FALSE;
+    dev_priv->is_lvds = FALSE;
 
     if (flag & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
     {
@@ -1581,14 +1647,14 @@ i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag)
 	dev_priv->controlled_output = SDVO_OUTPUT_RGB1;
 	output->subpixel_order = SubPixelHorizontalRGB;
 	name_prefix="VGA";
-    } else if (flag & SDVO_OUTPUT_LVDS0) {
-	dev_priv->controlled_output = SDVO_OUTPUT_LVDS0;
-	output->subpixel_order = SubPixelHorizontalRGB;
-	name_prefix="LVDS";
-    } else if (flag & SDVO_OUTPUT_LVDS1) {
-	dev_priv->controlled_output = SDVO_OUTPUT_LVDS1;
-	output->subpixel_order = SubPixelHorizontalRGB;
-	name_prefix="LVDS";
+    } else if (flag & (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) {
+        if (flag & SDVO_OUTPUT_LVDS0)
+            dev_priv->controlled_output = SDVO_OUTPUT_LVDS0;
+        else
+            dev_priv->controlled_output = SDVO_OUTPUT_LVDS1;
+        output->subpixel_order = SubPixelHorizontalRGB;
+        name_prefix="LVDS";
+        dev_priv->is_lvds = TRUE;
     } else {
 	unsigned char	bytes[2];
 
@@ -1697,6 +1763,11 @@ i830_sdvo_detect(xf86OutputPtr output)
 	    dev_priv->attached_output = response;
 	}
     }
+    /* if sdvo lvds is available, must get fixed mode */
+    if (dev_priv->is_lvds == TRUE &&
+        i830_sdvo_fetch_fixed_mode(output) == FALSE) {
+	 return XF86OutputStatusDisconnected;
+    }
 
     if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
     {
@@ -1990,7 +2061,6 @@ i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv)
     dev_priv->ddc_bus = 1 << num_bits;
 }
 
-
 Bool
 i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 {
-- 
1.5.4.4






More information about the Intel-gfx mailing list