[Intel-gfx] [PATCH 1/2]i830_sdvo.c:initialize sdvo lvds output

Ma Ling ling.ma at intel.com
Mon Feb 23 06:20:38 CET 2009


set sdvo lvds output and fetch fixed mode for output.

---
 src/i830_sdvo.c |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 88 insertions(+), 6 deletions(-)

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 0750166..ff5d570 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -82,6 +82,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
@@ -1749,6 +1753,75 @@ i830_sdvo_get_digital_encoding_mode(xf86OutputPtr output)
     return TRUE;
 }
 
+/* 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;
+	}
+    }
+
+    /* Get the LVDS fixed mode out of the BIOS.  We should support LVDS with
+     * the BIOS being unavailable or broken, but lack the configuration options
+     * for now.
+     */
+    if (pI830->lvds_fixed_mode)
+	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;
+}
+
 Bool
 i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 {
@@ -1904,14 +1977,17 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
 	dev_priv->controlled_output = SDVO_OUTPUT_RGB1;
         output->subpixel_order = SubPixelHorizontalRGB;
 	name_prefix="VGA";
-    } else if (dev_priv->caps.output_flags & SDVO_OUTPUT_LVDS0) {
-	dev_priv->controlled_output = SDVO_OUTPUT_LVDS0;
-        output->subpixel_order = SubPixelHorizontalRGB;
-	name_prefix="LVDS";
-    } else if (dev_priv->caps.output_flags & SDVO_OUTPUT_LVDS1) {
-	dev_priv->controlled_output = SDVO_OUTPUT_LVDS1;
+    }
+    else if (dev_priv->caps.output_flags &
+	    (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) {
+
+	if (dev_priv->caps.output_flags & 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
     {
@@ -1935,6 +2011,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
     }
 
     i830_sdvo_select_ddc_bus(dev_priv);
+    /* failed to fetch lvds fixed modes for sdvo device */
+    if (dev_priv->is_lvds == TRUE && i830_sdvo_fetch_fixed_mode(output) == FALSE) {
+	xf86OutputDestroy (output);
+	return FALSE;
+    }
++
 
     /* Set the input timing to the screen. Assume always input 0. */
     i830_sdvo_set_target_input(output, TRUE, FALSE);
-- 
1.5.4.4






More information about the Intel-gfx mailing list