[109/251] drm/radeon: fix endian issues with DP handling (v3)

2013-09-10 Thread Steven Rostedt
3.6.11.9-rc1 stable review patch.
If anyone has any objections, please let me know.

--

From: Alex Deucher 

[ Upstream commit 34be8c9af7b8728465963740fc11136ae90dfc36 ]

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 
Cc: sta...@vger.kernel.org
Signed-off-by: Steven Rostedt 
---
 drivers/gpu/drm/radeon/atombios_dp.c |   43 ++
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_dp.c 
b/drivers/gpu/drm/radeon/atombios_dp.c
index 3623b98..a0b5e1e 100644
--- 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 radeon_i2c_chan 
*chan,
 
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 radeon_i2c_chan 
*chan,
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;
 }
-- 
1.7.10.4


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[109/251] drm/radeon: fix endian issues with DP handling (v3)

2013-09-10 Thread Steven Rostedt
3.6.11.9-rc1 stable review patch.
If anyone has any objections, please let me know.

--

From: Alex Deucher alexander.deuc...@amd.com

[ Upstream commit 34be8c9af7b8728465963740fc11136ae90dfc36 ]

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.deuc...@amd.com
Cc: Dong He hedongh...@gmail.com
Cc: sta...@vger.kernel.org
Signed-off-by: Steven Rostedt rost...@goodmis.org
---
 drivers/gpu/drm/radeon/atombios_dp.c |   43 ++
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_dp.c 
b/drivers/gpu/drm/radeon/atombios_dp.c
index 3623b98..a0b5e1e 100644
--- 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 radeon_i2c_chan 
*chan,
 
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 radeon_i2c_chan 
*chan,
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;
 }
-- 
1.7.10.4


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/