xf86-video-intel: 4 commits - src/i810_reg.h src/i830_bios.c src/i830_bios.h src/i830_crt.c src/i830.h src/i830_sdvo.c

Zhenyu Wang zhen at kemper.freedesktop.org
Tue Jun 2 18:53:28 PDT 2009


 src/i810_reg.h  |    1 
 src/i830.h      |    1 
 src/i830_bios.c |   89 ++++++++++++++++++++++++++++++++++++++++----------------
 src/i830_bios.h |   17 ++++++++++
 src/i830_crt.c  |    7 ++--
 src/i830_sdvo.c |   60 ++++++++++++++++++++++++++++---------
 6 files changed, 133 insertions(+), 42 deletions(-)

New commits:
commit ea0b00e675281b2914450992501566122f9affe0
Author: Ma Ling <ling.ma at intel.com>
Date:   Mon Jun 1 17:13:53 2009 +0800

    Provide mode line from VBT to xorg.
    
    If sdvo get modes function can't find modes from EDID,
    transmit sdvo lvds modes from VBT to xorg.
    
    Signed-off-by: Ma Ling <ling.ma at intel.com>

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index a4c9120..cfba482 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -91,6 +91,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
@@ -1550,6 +1554,31 @@ i830_sdvo_check_hdmi_encode (xf86OutputPtr output)
 	return FALSE;
 }
 
+/* This function will try to fetch native modes for sdvo lvds output*/
+static DisplayModePtr i830_sdvo_lvds_fetch_modes(xf86OutputPtr  output)
+{
+    I830Ptr                 pI830 = I830PTR(output->scrn);
+    DisplayModePtr          modes;
+
+    /*
+     * Attempt to get the mode list from DDC.
+     * Assume that the preferred modes are
+     * arranged in priority order,
+     */
+    modes = i830_ddc_get_modes(output);
+    if (modes != NULL)
+        goto end;
+
+    if (pI830->sdvo_lvds_fixed_mode != NULL)
+        modes = xf86DuplicateModes(output->scrn, pI830->sdvo_lvds_fixed_mode);
+
+end:
+    /* Guarantee the the first preferred mode is chosen by xserver */
+    if (modes != NULL)
+        modes->type |= (M_T_DRIVER | M_T_PREFERRED);
+    return modes;
+}
+
 static void i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv);
 
 static Bool
@@ -1568,6 +1597,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))
     {
@@ -1608,14 +1638,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];
 
@@ -1746,11 +1776,15 @@ i830_sdvo_get_ddc_modes(xf86OutputPtr output)
     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     DisplayModePtr modes = NULL;
     xf86OutputPtr crt;
-    I830OutputPrivatePtr intel_output;
+    I830OutputPrivatePtr intel_output =output->driver_private;
     xf86MonPtr edid_mon = NULL;
-    struct i830_sdvo_priv *dev_priv;
+    struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
+
+    if (dev_priv->is_lvds)
+        modes = i830_sdvo_lvds_fetch_modes(output);
+    else
+        modes = i830_ddc_get_modes(output);
 
-    modes = i830_ddc_get_modes(output);
     if (modes != NULL)
 	goto check_hdmi;
 
@@ -1774,9 +1808,6 @@ i830_sdvo_get_ddc_modes(xf86OutputPtr output)
 
 check_hdmi:
     /* Check if HDMI encode, setup it and set the flag for HDMI audio */
-    intel_output = output->driver_private;
-    dev_priv = intel_output->dev_priv;
-
     if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1))
     {
 	if (!i830_sdvo_check_hdmi_encode(output)) {
@@ -2105,7 +2136,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)
 {
commit 9e7ee50bea5f65003f1d70cc06d8c1ace1282548
Author: Ma Ling <ling.ma at intel.com>
Date:   Mon Jun 1 17:13:22 2009 +0800

    Fetch mode line from VBT, then keep it.
    
    Parse SDVO LVDS option section, then according to panel type
    fetch fixed mode line from SDVO LVDS DTDS section .
    
    Signed-off-by: Ma Ling <ling.ma at intel.com>

diff --git a/src/i830.h b/src/i830.h
index 8854286..2d9e905 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -498,6 +498,7 @@ typedef struct _I830Rec {
    int lvds_ssc_freq; /* in MHz */
    Bool lvds_dither;
    DisplayModePtr lvds_fixed_mode;
+   DisplayModePtr sdvo_lvds_fixed_mode;
    Bool skip_panel_detect;
    Bool integrated_lvds; /* LVDS config from driver feature BDB */
 
diff --git a/src/i830_bios.c b/src/i830_bios.c
index 73c097a..9c1f101 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -73,6 +73,36 @@ find_section(struct bdb_header *bdb, int section_id)
     return NULL;
 }
 
+static void
+fill_detail_timing_data(DisplayModePtr fixed_mode, unsigned char *timing_ptr)
+{
+    fixed_mode->HDisplay   = _H_ACTIVE(timing_ptr);
+    fixed_mode->VDisplay   = _V_ACTIVE(timing_ptr);
+    fixed_mode->HSyncStart = fixed_mode->HDisplay +
+        _H_SYNC_OFF(timing_ptr);
+    fixed_mode->HSyncEnd   = fixed_mode->HSyncStart +
+        _H_SYNC_WIDTH(timing_ptr);
+    fixed_mode->HTotal     = fixed_mode->HDisplay +
+        _H_BLANK(timing_ptr);
+    fixed_mode->VSyncStart = fixed_mode->VDisplay +
+        _V_SYNC_OFF(timing_ptr);
+    fixed_mode->VSyncEnd   = fixed_mode->VSyncStart +
+        _V_SYNC_WIDTH(timing_ptr);
+    fixed_mode->VTotal     = fixed_mode->VDisplay +
+        _V_BLANK(timing_ptr);
+    fixed_mode->Clock      = _PIXEL_CLOCK(timing_ptr) / 1000;
+    fixed_mode->type       = M_T_PREFERRED;
+
+    /* Some VBTs have bogus h/vtotal values */
+    if (fixed_mode->HSyncEnd > fixed_mode->HTotal)
+        fixed_mode->HTotal = fixed_mode->HSyncEnd + 1;
+    if (fixed_mode->VSyncEnd > fixed_mode->VTotal)
+        fixed_mode->VTotal = fixed_mode->VSyncEnd + 1;
+
+    xf86SetModeDefaultName(fixed_mode);
+
+}
+
 /**
  * Returns the BIOS's fixed panel mode.
  *
@@ -82,7 +112,7 @@ find_section(struct bdb_header *bdb, int section_id)
  * detecting the panel mode is preferable.
  */
 static void
-parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
+parse_integrated_panel_data(I830Ptr pI830, struct bdb_header *bdb)
 {
     struct bdb_lvds_options *lvds_options;
     struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
@@ -118,32 +148,43 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
     /* Since lvds_bdb_2_fp_edid_dtd is just an EDID detailed timing
      * block, pull the contents out using EDID macros.
      */
-    fixed_mode->HDisplay   = _H_ACTIVE(timing_ptr);
-    fixed_mode->VDisplay   = _V_ACTIVE(timing_ptr);
-    fixed_mode->HSyncStart = fixed_mode->HDisplay +
-	_H_SYNC_OFF(timing_ptr);
-    fixed_mode->HSyncEnd   = fixed_mode->HSyncStart +
-	_H_SYNC_WIDTH(timing_ptr);
-    fixed_mode->HTotal     = fixed_mode->HDisplay +
-	_H_BLANK(timing_ptr);
-    fixed_mode->VSyncStart = fixed_mode->VDisplay +
-	_V_SYNC_OFF(timing_ptr);
-    fixed_mode->VSyncEnd   = fixed_mode->VSyncStart +
-	_V_SYNC_WIDTH(timing_ptr);
-    fixed_mode->VTotal     = fixed_mode->VDisplay +
-	_V_BLANK(timing_ptr);
-    fixed_mode->Clock      = _PIXEL_CLOCK(timing_ptr) / 1000;
-    fixed_mode->type       = M_T_PREFERRED;
+    fill_detail_timing_data(fixed_mode, timing_ptr);
+    pI830->lvds_fixed_mode = fixed_mode;
+}
 
-    /* Some VBTs have bogus h/vtotal values */
-    if (fixed_mode->HSyncEnd > fixed_mode->HTotal)
-	fixed_mode->HTotal = fixed_mode->HSyncEnd + 1;
-    if (fixed_mode->VSyncEnd > fixed_mode->VTotal)
-	fixed_mode->VTotal = fixed_mode->VSyncEnd + 1;
+static void
+parse_sdvo_panel_data(I830Ptr pI830, struct bdb_header *bdb)
+{
+    DisplayModePtr fixed_mode;
+    struct bdb_sdvo_lvds_options *sdvo_lvds_options;
+    unsigned char *timing_ptr;
 
-    xf86SetModeDefaultName(fixed_mode);
+    pI830->sdvo_lvds_fixed_mode = NULL;
 
-    pI830->lvds_fixed_mode = fixed_mode;
+    sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);
+    if (sdvo_lvds_options == NULL)
+        return;
+
+    timing_ptr = find_section(bdb, BDB_SDVO_PANEL_DTDS);
+    if (timing_ptr == NULL)
+        return;
+
+    fixed_mode = xnfalloc(sizeof(DisplayModeRec));
+    if (fixed_mode == NULL)
+        return;
+
+    memset(fixed_mode, 0, sizeof(*fixed_mode));
+    fill_detail_timing_data(fixed_mode, timing_ptr +
+                        (sdvo_lvds_options->panel_type * DET_TIMING_INFO_LEN));
+    pI830->sdvo_lvds_fixed_mode = fixed_mode;
+
+}
+
+static void
+parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
+{
+    parse_integrated_panel_data(pI830, bdb);
+    parse_sdvo_panel_data(pI830, bdb);
 }
 
 static void
diff --git a/src/i830_bios.h b/src/i830_bios.h
index 78af830..1f1f1aa 100644
--- a/src/i830_bios.h
+++ b/src/i830_bios.h
@@ -436,6 +436,23 @@ struct bdb_driver_feature {
     uint8_t	legacy_crt_max_refresh;
 } __attribute__((packed));
 
+struct bdb_sdvo_lvds_options {
+    uint8_t     panel_backlight;
+    uint8_t     h40_set_panel_type;
+    uint8_t     panel_type;
+    uint8_t     ssc_clk_freq;
+    uint16_t    als_low_trip;
+    uint16_t    als_high_trip;
+    uint8_t     sclalarcoeff_tab_row_num;
+    uint8_t     sclalarcoeff_tab_row_size;
+    uint8_t     coefficient[8];
+    uint8_t     panel_misc_bits_1;
+    uint8_t     panel_misc_bits_2;
+    uint8_t     panel_misc_bits_3;
+    uint8_t     panel_misc_bits_4;
+} __attribute__((packed));
+
+
 #ifndef REG_DUMPER
 int i830_bios_init(ScrnInfoPtr pScrn);
 #endif
commit 88f766be008008d76c150e3ac16f09d4ecbb6d53
Author: Ma Ling <ling.ma at intel.com>
Date:   Fri May 15 15:22:11 2009 +0800

    Wait doubled regis to be stable for load pipe detection
    
    We have two approaches for VGA detections: hot plug detection for 945G onwards
    and load pipe detection for Pre-945G. load pipe detection will get one free
    pipe ,and set border color as red and blue, then check CRT status by
    swf register. Because pipe registers in hires mode are double buffered,
    once set force border bit in pipeconf register, we have to wait for
    a vblank until it is effective, otherwise result is unstable.
    
    It fixed freedesktop bug #20463
    
    Signed-off-by: Ma Ling <ling.ma at intel.com>

diff --git a/src/i830_crt.c b/src/i830_crt.c
index eced5e8..536d63d 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -286,7 +286,8 @@ i830_crt_detect_load (xf86CrtcPtr	    crtc,
     {
 	uint32_t	pipeconf = INREG(pipeconf_reg);
 	OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER);
-	
+        /* Wait for next Vblank to substitue border color for Color info */
+        i830WaitForVblank (pScrn);
 	st00 = pI830->readStandard (pI830, 0x3c2);
 	present = (st00 & (1 << 4)) != 0;
 	OUTREG(pipeconf_reg, pipeconf);
commit 6a635be5ea2b2df9d6b9a8006325244394038474
Author: Ma Ling <ling.ma at intel.com>
Date:   Fri May 15 14:01:18 2009 +0800

    Set activation periods as 64 cdclk sync up with KMS
    
    We use force CRT detect trigger bit(1 << 3) to detect VGA in hot plug mode,
    which triggers a CRT hotplug/unplug detection cycle independent of the
    interrupt enable bit(1 << 9), so keep bit 9.
    And although spec says CRT_HOTPLUG_ACTIVATION_PERIOD_64(1 << 8) is only useful
    for mobile platform, it is also required to detect vga on G4x platform correctly.
    Tested the patch on G45/G43/Q45 platforms with no regressions
    
    It fixed freedesktop.org bug #21120 and part of bug #21210.
    
    Signed-off-by: Ma Ling <ling.ma at intel.com>

diff --git a/src/i810_reg.h b/src/i810_reg.h
index cb33784..db542aa 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1262,6 +1262,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 # define CRT_HOTPLUG_DETECT_VOLTAGE_325MV	(0 << 2)
 # define CRT_HOTPLUG_DETECT_VOLTAGE_475MV	(1 << 2)
 # define CRT_HOTPLUG_MASK			(0x3fc)	/* Bits 9-2 */
+# define CRT_FORCE_HOTPLUG_MASK                 0xfffffe1f
 
 #define PORT_HOTPLUG_STAT	0x61114
 # define HDMIB_HOTPLUG_INT_STATUS		(1 << 29)
diff --git a/src/i830_crt.c b/src/i830_crt.c
index d8e4a76..eced5e8 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -185,7 +185,7 @@ i830_crt_detect_hotplug(xf86OutputPtr output)
 
     hotplug_en = INREG(PORT_HOTPLUG_EN);
 
-    hotplug_en &= ~CRT_HOTPLUG_MASK;
+    hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
 
     /* This starts the detection sequence */
     hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
@@ -193,7 +193,7 @@ i830_crt_detect_hotplug(xf86OutputPtr output)
     /* GM45 requires a longer activation period to reliably
      * detect CRT
      */
-    if (IS_GM45(pI830))
+    if (IS_G4X(pI830))
 	hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64;
 
     /* Use the default voltage value */


More information about the xorg-commit mailing list