From 15af8ea6ab6998bbab9f4eeda227565c409da229 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 22 Jun 2009 11:11:06 -0700 Subject: [PATCH] Fix LFP data block fetch Apparently the proper way to do this is to use the LFP data pointer block to figure out the LFP data block entry size, then use that plus the panel index to calculate an offset into the LFP data block array. Fixes fdo bug #19450. Signed-off-by: Jesse Barnes --- src/bios_reader/bios_reader.c | 18 +++++++++++++++--- src/i830_bios.c | 17 +++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c index 27ec7694..cdc20453 100644 --- a/src/bios_reader/bios_reader.c +++ b/src/bios_reader/bios_reader.c @@ -275,18 +275,30 @@ static void dump_lvds_options(void) static void dump_lvds_ptr_data(void) { struct bdb_block *block; + struct bdb_lvds_lfp_data *lvds_data; struct bdb_lvds_lfp_data_ptrs *ptrs; struct lvds_fp_timing *fp_timing; + struct bdb_lvds_lfp_data_entry *entry; + int lfp_data_size; block = find_section(BDB_LVDS_LFP_DATA_PTRS); if (!block) { printf("No LFP data pointers block\n"); return; } - ptrs = block->data; - fp_timing = (struct lvds_fp_timing *)((uint8_t *)bdb + - ptrs->ptr[panel_type].fp_timing_offset); + + block = find_section(BDB_LVDS_LFP_DATA); + if (!block) { + printf("No LVDS data block\n"); + return; + } + lvds_data = block->data; + + lfp_data_size = ptrs->ptr[1].fp_timing_offset - ptrs->ptr[0].fp_timing_offset; + entry = (struct bdb_lvds_lfp_data_entry *)((uint8_t *)lvds_data->data + + (lfp_data_size * panel_type)); + fp_timing = &entry->fp_timing; printf("LVDS timing pointer data:\n"); printf(" Number of entries: %d\n", ptrs->lvds_entries); diff --git a/src/i830_bios.c b/src/i830_bios.c index 2f129e97..62b9f5d9 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -118,9 +118,11 @@ 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; - int timing_offset; + struct bdb_lvds_lfp_data *lvds_data; + struct bdb_lvds_lfp_data_entry *entry; DisplayModePtr fixed_mode; unsigned char *timing_ptr; + int lfp_data_size; /* Defaults if we can't find VBT info */ pI830->lvds_dither = 0; @@ -133,13 +135,20 @@ parse_integrated_panel_data(I830Ptr pI830, struct bdb_header *bdb) if (lvds_options->panel_type == 0xff) return; + lvds_data = find_section(bdb, BDB_LVDS_LFP_DATA); + if (!lvds_data) { + return; + } + lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); if (!lvds_lfp_data_ptrs) return; - timing_offset = - lvds_lfp_data_ptrs->ptr[lvds_options->panel_type].dvo_timing_offset; - timing_ptr = (unsigned char *)bdb + timing_offset; + lfp_data_size = lvds_lfp_data_ptrs->ptr[1].fp_timing_offset - + lvds_lfp_data_ptrs->ptr[0].fp_timing_offset; + entry = (struct bdb_lvds_lfp_data_entry *)((uint8_t *)lvds_data->data + + (lfp_data_size * lvds_options->panel_type)); + timing_ptr = (unsigned char *)&entry->fp_timing; if (pI830->skip_panel_detect) return;