]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Aug 2013 03:42:54 +0000 (11:42 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Aug 2013 03:42:54 +0000 (11:42 +0800)
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

queue-3.4/drm-radeon-fix-combios-tables-on-older-cards.patch [new file with mode: 0644]
queue-3.4/drm-radeon-fix-endian-issues-with-dp-handling-v3.patch [new file with mode: 0644]
queue-3.4/drm-radeon-improve-dac-adjust-heuristics-for-legacy-pdac.patch [new file with mode: 0644]
queue-3.4/series

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 (file)
index 0000000..5212794
--- /dev/null
@@ -0,0 +1,291 @@
+From cef1d00cd56f600121ad121875655ad410a001b8 Mon Sep 17 00:00:00 2001
+From: Mark Kettenis <kettenis@openbsd.org>
+Date: Sun, 21 Jul 2013 16:44:09 -0400
+Subject: drm/radeon: fix combios tables on older cards
+
+From: Mark Kettenis <kettenis@openbsd.org>
+
+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:
+
+    <http://www.techpowerup.com/vgabios/index.php?manufacturer=ATI&page=1>
+
+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 <kettenis@openbsd.org>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..572cf74
--- /dev/null
@@ -0,0 +1,90 @@
+From 34be8c9af7b8728465963740fc11136ae90dfc36 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Thu, 18 Jul 2013 11:13:53 -0400
+Subject: drm/radeon: fix endian issues with DP handling (v3)
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+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 <alexander.deucher@amd.com>
+Cc: Dong He <hedonghust@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..dc524d7
--- /dev/null
@@ -0,0 +1,34 @@
+From 03ed8cf9b28d886c64c7e705c7bb1a365fd8fb95 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Fri, 19 Jul 2013 17:44:43 -0400
+Subject: drm/radeon: improve dac adjust heuristics for legacy pdac
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 03ed8cf9b28d886c64c7e705c7bb1a365fd8fb95 upstream.
+
+Hopefully avoid more quirks in the future due to bogus
+vbios dac data.
+
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+       }
index c28a0e78d41ea1775df604fff80c310cd3da1ca0..bfcf43624889061c5f679ff97c6bbe472ca72dc3 100644 (file)
@@ -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