From: Greg Kroah-Hartman Date: Thu, 1 Aug 2013 03:42:33 +0000 (+0800) Subject: 3.0-stable patches X-Git-Tag: v3.0.89~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=52a765f8ea4286cd2319c1be639ec8a78c6a386b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: drm-radeon-fix-combios-tables-on-older-cards.patch drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch --- diff --git a/queue-3.0/drm-radeon-fix-combios-tables-on-older-cards.patch b/queue-3.0/drm-radeon-fix-combios-tables-on-older-cards.patch new file mode 100644 index 00000000000..5212794f517 --- /dev/null +++ b/queue-3.0/drm-radeon-fix-combios-tables-on-older-cards.patch @@ -0,0 +1,291 @@ +From cef1d00cd56f600121ad121875655ad410a001b8 Mon Sep 17 00:00:00 2001 +From: Mark Kettenis +Date: Sun, 21 Jul 2013 16:44:09 -0400 +Subject: drm/radeon: fix combios tables on older cards + +From: Mark Kettenis + +commit cef1d00cd56f600121ad121875655ad410a001b8 upstream. + +Noticed that my old Radeon 7500 hung after printing + + drm: GPU not posted. posting now... + +when it wasn't selected as the primary card the BIOS. Some digging +revealed that it was hanging in combios_parse_mmio_table() while +parsing the ASIC INIT 3 table. Looking at the BIOS ROM for the card, +it becomes obvious that there is no ASIC INIT 3 table in the BIOS. +The code is just processing random garbage. No surprise it hangs! + +Why do I say that there is no ASIC INIT 3 table is the BIOS? This +table is found through the MISC INFO table. The MISC INFO table can +be found at offset 0x5e in the COMBIOS header. But the header is +smaller than that. The COMBIOS header starts at offset 0x126. The +standard PCI Data Structure (the bit that starts with 'PCIR') lives at +offset 0x180. That means that the COMBIOS header can not be larger +than 0x5a bytes and therefore cannot contain a MISC INFO table. + +I looked at a dozen or so BIOS images, some my own, some downloaded from: + + + +It is fairly obvious that the size of the COMBIOS header can be found +at offset 0x6 of the header. Not sure if it is a 16-bit number or +just an 8-bit number, but that doesn't really matter since the tables +seems to be always smaller than 256 bytes. + +So I think combios_get_table_offset() should check if the requested +table is present. This can be done by checking the offset against the +size of the header. See the diff below. The diff is against the WIP +OpenBSD codebase that roughly corresponds to Linux 3.8.13 at this +point. But I don't think this bit of the code changed much since +then. + +For what it is worth: + +Signed-off-by: Mark Kettenis +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_combios.c | 145 +++++++++----------------------- + 1 file changed, 41 insertions(+), 104 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -147,7 +147,7 @@ static uint16_t combios_get_table_offset + enum radeon_combios_table_offset table) + { + struct radeon_device *rdev = dev->dev_private; +- int rev; ++ int rev, size; + uint16_t offset = 0, check_offset; + + if (!rdev->bios) +@@ -156,174 +156,106 @@ static uint16_t combios_get_table_offset + switch (table) { + /* absolute offset tables */ + case COMBIOS_ASIC_INIT_1_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0xc); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0xc; + break; + case COMBIOS_BIOS_SUPPORT_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x14); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x14; + break; + case COMBIOS_DAC_PROGRAMMING_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2a; + break; + case COMBIOS_MAX_COLOR_DEPTH_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2c; + break; + case COMBIOS_CRTC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x2e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x2e; + break; + case COMBIOS_PLL_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x30); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x30; + break; + case COMBIOS_TV_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x32); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x32; + break; + case COMBIOS_DFP_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x34); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x34; + break; + case COMBIOS_HW_CONFIG_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x36); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x36; + break; + case COMBIOS_MULTIMEDIA_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x38); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x38; + break; + case COMBIOS_TV_STD_PATCH_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x3e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x3e; + break; + case COMBIOS_LCD_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x40); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x40; + break; + case COMBIOS_MOBILE_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x42); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x42; + break; + case COMBIOS_PLL_INIT_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x46); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x46; + break; + case COMBIOS_MEM_CONFIG_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x48); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x48; + break; + case COMBIOS_SAVE_MASK_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4a; + break; + case COMBIOS_HARDCODED_EDID_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4c; + break; + case COMBIOS_ASIC_INIT_2_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x4e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x4e; + break; + case COMBIOS_CONNECTOR_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x50); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x50; + break; + case COMBIOS_DYN_CLK_1_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x52); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x52; + break; + case COMBIOS_RESERVED_MEM_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x54); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x54; + break; + case COMBIOS_EXT_TMDS_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x58); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x58; + break; + case COMBIOS_MEM_CLK_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5a; + break; + case COMBIOS_EXT_DAC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5c; + break; + case COMBIOS_MISC_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x5e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x5e; + break; + case COMBIOS_CRT_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x60); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x60; + break; + case COMBIOS_INTEGRATED_SYSTEM_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x62); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x62; + break; + case COMBIOS_COMPONENT_VIDEO_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x64); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x64; + break; + case COMBIOS_FAN_SPEED_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x66); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x66; + break; + case COMBIOS_OVERDRIVE_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x68); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x68; + break; + case COMBIOS_OEM_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6a); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6a; + break; + case COMBIOS_DYN_CLK_2_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6c); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6c; + break; + case COMBIOS_POWER_CONNECTOR_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x6e); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x6e; + break; + case COMBIOS_I2C_INFO_TABLE: +- check_offset = RBIOS16(rdev->bios_header_start + 0x70); +- if (check_offset) +- offset = check_offset; ++ check_offset = 0x70; + break; + /* relative offset tables */ + case COMBIOS_ASIC_INIT_3_TABLE: /* offset from misc info */ +@@ -439,11 +371,16 @@ static uint16_t combios_get_table_offset + } + break; + default: ++ check_offset = 0; + break; + } + +- return offset; ++ size = RBIOS8(rdev->bios_header_start + 0x6); ++ /* check absolute offset tables */ ++ if (table < COMBIOS_ASIC_INIT_3_TABLE && check_offset && check_offset < size) ++ offset = RBIOS16(rdev->bios_header_start + check_offset); + ++ return offset; + } + + bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) diff --git a/queue-3.0/drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch b/queue-3.0/drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch new file mode 100644 index 00000000000..dc524d7d510 --- /dev/null +++ b/queue-3.0/drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch @@ -0,0 +1,34 @@ +From 03ed8cf9b28d886c64c7e705c7bb1a365fd8fb95 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Fri, 19 Jul 2013 17:44:43 -0400 +Subject: drm/radeon: improve dac adjust heuristics for legacy pdac + +From: Alex Deucher + +commit 03ed8cf9b28d886c64c7e705c7bb1a365fd8fb95 upstream. + +Hopefully avoid more quirks in the future due to bogus +vbios dac data. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_combios.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_combios.c ++++ b/drivers/gpu/drm/radeon/radeon_combios.c +@@ -890,8 +890,10 @@ struct radeon_encoder_primary_dac *radeo + dac = RBIOS8(dac_info + 0x3) & 0xf; + p_dac->ps2_pdac_adj = (bg << 8) | (dac); + } +- /* if the values are all zeros, use the table */ +- if (p_dac->ps2_pdac_adj) ++ /* if the values are zeros, use the table */ ++ if ((dac == 0) || (bg == 0)) ++ found = 0; ++ else + found = 1; + } + diff --git a/queue-3.0/series b/queue-3.0/series index 87ccad84941..acbae698d3b 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -12,3 +12,5 @@ staging-comedi-comedi_cancel-ioctl-should-wake-up-read-write.patch libata-make-it-clear-that-sata_inic162x-is-experimental.patch powerpc-modules-module-crc-relocation-fix-causes-perf-issues.patch acpi-memhotplug-fix-a-stale-pointer-in-error-path.patch +drm-radeon-fix-combios-tables-on-older-cards.patch +drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch