diff --git a/src/i830.h b/src/i830.h index 207d4ec..5dfaf11 100644 --- a/src/i830.h +++ b/src/i830.h @@ -917,6 +917,7 @@ extern const int I830CopyROP[16]; #define QUIRK_PFIT_SAFE 0x00000040 #define QUIRK_IGNORE_CRT 0x00000080 #define QUIRK_BROKEN_ACPI_LID 0x00000100 +#define QUIRK_USE_LVDS_LFP_DATA 0x00000200 extern void i830_fixup_devices(ScrnInfoPtr); /** diff --git a/src/i830_bios.c b/src/i830_bios.c index 7c51f38..9e1a1ff 100644 --- a/src/i830_bios.c +++ b/src/i830_bios.c @@ -85,7 +85,6 @@ static void parse_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; DisplayModePtr fixed_mode; unsigned char *timing_ptr; @@ -101,13 +100,25 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb) if (lvds_options->panel_type == 0xff) return; - lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); - if (!lvds_lfp_data_ptrs) - return; + if (pI830->quirk_flag & QUIRK_USE_LVDS_LFP_DATA) { + struct bdb_lvds_lfp_data *lvds_lfp_data; + + lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA); + if (!lvds_lfp_data) + return; + + timing_ptr = (unsigned char *)&lvds_lfp_data->data[lvds_options->panel_type].dvo_timing; + } else { + struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; - timing_offset = - lvds_lfp_data_ptrs->ptr[lvds_options->panel_type].dvo_timing_offset; - timing_ptr = (unsigned char *)bdb + timing_offset; + 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; + } if (pI830->skip_panel_detect) return; diff --git a/src/i830_quirks.c b/src/i830_quirks.c index 81ea3c2..5dc1117 100644 --- a/src/i830_quirks.c +++ b/src/i830_quirks.c @@ -260,6 +260,15 @@ static void quirk_broken_acpi_lid (I830Ptr pI830) pI830->quirk_flag |= QUIRK_BROKEN_ACPI_LID; } +/* + * On some machines, LVP_DATA_PTRS have the wrong offsets, so + * use the LFP_DATA array in that case + */ +static void quirk_use_lvds_data (I830Ptr pI830) +{ + pI830->quirk_flag |= QUIRK_USE_LVDS_LFP_DATA; +} + /* keep this list sorted by OEM, then by chip ID */ static i830_quirk i830_quirk_list[] = { /* Aopen mini pc */ @@ -394,6 +403,9 @@ static i830_quirk i830_quirk_list[] = { /* #19529: iBase MB890 board */ { PCI_CHIP_I855_GM, 0x8086, 0x3582, quirk_ibase_lvds }, + /* #19460: Nuzhdin's laptop has funky VBT LFP data */ + { PCI_CHIP_I915_GM, SUBSYS_ANY, SUBSYS_ANY, quirk_use_lvds_data }, + { 0, 0, 0, NULL }, };