From: Greg Kroah-Hartman Date: Thu, 1 Aug 2013 03:42:54 +0000 (+0800) Subject: 3.4-stable patches X-Git-Tag: v3.0.89~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e3322acc7f6fa6765dc813ed0746d4820acab8b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: drm-radeon-fix-combios-tables-on-older-cards.patch drm-radeon-fix-endian-issues-with-dp-handling-v3.patch drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch --- diff --git a/queue-3.4/drm-radeon-fix-combios-tables-on-older-cards.patch b/queue-3.4/drm-radeon-fix-combios-tables-on-older-cards.patch new file mode 100644 index 00000000000..5212794f517 --- /dev/null +++ b/queue-3.4/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.4/drm-radeon-fix-endian-issues-with-dp-handling-v3.patch b/queue-3.4/drm-radeon-fix-endian-issues-with-dp-handling-v3.patch new file mode 100644 index 00000000000..572cf7427b7 --- /dev/null +++ b/queue-3.4/drm-radeon-fix-endian-issues-with-dp-handling-v3.patch @@ -0,0 +1,90 @@ +From 34be8c9af7b8728465963740fc11136ae90dfc36 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Thu, 18 Jul 2013 11:13:53 -0400 +Subject: drm/radeon: fix endian issues with DP handling (v3) + +From: Alex Deucher + +commit 34be8c9af7b8728465963740fc11136ae90dfc36 upstream. + +The atom interpreter expects data in LE format, so +swap the message buffer as apprioriate. + +v2: properly handle non-dw aligned byte counts. +v3: properly handle remainder + +Signed-off-by: Alex Deucher +Cc: Dong He +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_dp.c | 43 +++++++++++++++++++++++++++++++---- + 1 file changed, 39 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_dp.c ++++ b/drivers/gpu/drm/radeon/atombios_dp.c +@@ -45,6 +45,41 @@ static char *pre_emph_names[] = { + }; + + /***** radeon AUX functions *****/ ++ ++/* Atom needs data in little endian format ++ * so swap as appropriate when copying data to ++ * or from atom. Note that atom operates on ++ * dw units. ++ */ ++static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) ++{ ++#ifdef __BIG_ENDIAN ++ u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ ++ u32 *dst32, *src32; ++ int i; ++ ++ memcpy(src_tmp, src, num_bytes); ++ src32 = (u32 *)src_tmp; ++ dst32 = (u32 *)dst_tmp; ++ if (to_le) { ++ for (i = 0; i < ((num_bytes + 3) / 4); i++) ++ dst32[i] = cpu_to_le32(src32[i]); ++ memcpy(dst, dst_tmp, num_bytes); ++ } else { ++ u8 dws = num_bytes & ~3; ++ for (i = 0; i < ((num_bytes + 3) / 4); i++) ++ dst32[i] = le32_to_cpu(src32[i]); ++ memcpy(dst, dst_tmp, dws); ++ if (num_bytes % 4) { ++ for (i = 0; i < (num_bytes % 4); i++) ++ dst[dws+i] = dst_tmp[dws+i]; ++ } ++ } ++#else ++ memcpy(dst, src, num_bytes); ++#endif ++} ++ + union aux_channel_transaction { + PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1; + PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2; +@@ -66,10 +101,10 @@ static int radeon_process_aux_ch(struct + + base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1); + +- memcpy(base, send, send_bytes); ++ radeon_copy_swap(base, send, send_bytes, true); + +- args.v1.lpAuxRequest = 0 + 4; +- args.v1.lpDataOut = 16 + 4; ++ args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4)); ++ args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4)); + args.v1.ucDataOutLen = 0; + args.v1.ucChannelID = chan->rec.i2c_id; + args.v1.ucDelay = delay / 10; +@@ -103,7 +138,7 @@ static int radeon_process_aux_ch(struct + recv_bytes = recv_size; + + if (recv && recv_size) +- memcpy(recv, base + 16, recv_bytes); ++ radeon_copy_swap(recv, base + 16, recv_bytes, false); + + return recv_bytes; + } diff --git a/queue-3.4/drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch b/queue-3.4/drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch new file mode 100644 index 00000000000..dc524d7d510 --- /dev/null +++ b/queue-3.4/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.4/series b/queue-3.4/series index c28a0e78d41..bfcf4362488 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -22,3 +22,6 @@ 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 dm-verity-fix-inability-to-use-a-few-specific-devices-sizes.patch +drm-radeon-fix-endian-issues-with-dp-handling-v3.patch +drm-radeon-fix-combios-tables-on-older-cards.patch +drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch