summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2009-06-22 11:11:06 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-22 11:13:30 -0700
commit15af8ea6ab6998bbab9f4eeda227565c409da229 (patch)
tree36c2814e0e19b49876fc7a49420d3b599d10a727
parent534e73ad4f234a04755917f2bf17ba821c27eb52 (diff)
downloadxorg-driver-xf86-video-intel-15af8ea6ab6998bbab9f4eeda227565c409da229.tar.gz
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 <jbarnes@virtuousgeek.org>
-rw-r--r--src/bios_reader/bios_reader.c18
-rw-r--r--src/i830_bios.c17
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;