diff options
author | Ma Ling <ling.ma@intel.com> | 2009-06-01 17:13:22 +0800 |
---|---|---|
committer | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2009-06-03 09:49:29 +0800 |
commit | 9e7ee50bea5f65003f1d70cc06d8c1ace1282548 (patch) | |
tree | 56ab8551d7c2d0d20e910c323fa464cc299e3153 /src | |
parent | 88f766be008008d76c150e3ac16f09d4ecbb6d53 (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.h | 1 | ||||
-rw-r--r-- | src/i830_bios.c | 89 | ||||
-rw-r--r-- | src/i830_bios.h | 17 |
3 files changed, 83 insertions, 24 deletions
@@ -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 |