[Intel-gfx] [PATCH 1/2 V3] Fetch mode line from VBT, then keep it.

Ma Ling ling.ma at intel.com
Mon Jun 1 11:13:22 CEST 2009


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>
---
 src/i830.h      |    1 +
 src/i830_bios.c |   89 ++++++++++++++++++++++++++++++++++++++++---------------
 src/i830_bios.h |   17 ++++++++++
 3 files changed, 83 insertions(+), 24 deletions(-)

diff --git a/src/i830.h b/src/i830.h
index 60dc146..f69f81f 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
-- 
1.5.4.4






More information about the Intel-gfx mailing list