summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMa Ling <ling.ma@intel.com>2009-06-01 17:13:22 +0800
committerZhenyu Wang <zhenyu.z.wang@intel.com>2009-06-03 09:49:29 +0800
commit9e7ee50bea5f65003f1d70cc06d8c1ace1282548 (patch)
tree56ab8551d7c2d0d20e910c323fa464cc299e3153 /src
parent88f766be008008d76c150e3ac16f09d4ecbb6d53 (diff)
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@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_bios.c89
-rw-r--r--src/i830_bios.h17
3 files changed, 83 insertions, 24 deletions
diff --git a/src/i830.h b/src/i830.h
index 88542864..2d9e9058 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 73c097ad..9c1f1017 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 78af830c..1f1f1aa2 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