aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_dp.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-08-19 09:24:13 +1000
committerDave Airlie <airlied@redhat.com>2013-08-19 09:24:13 +1000
commit1dda8d02acbba80444a98e71d9d419232c109e94 (patch)
treef32a7234a7855dc8040a82b5db2236c0e2d76a25 /drivers/gpu/drm/radeon/atombios_dp.c
parentdrm/tilcdc fixup mode to workaround sync for tda998x (diff)
parentMerge branch 'drm/next/du' of git://linuxtv.org/pinchartl/fbdev into drm-rcar-stable (diff)
downloadlinux-dev-1dda8d02acbba80444a98e71d9d419232c109e94.tar.xz
linux-dev-1dda8d02acbba80444a98e71d9d419232c109e94.zip
Merge remote-tracking branch 'pfdo/drm-rcar-for-v3.12' into drm-next
Merge the rcar stable branch that is being shared with the arm-soc tree. Signed-off-by: Dave Airlie <airlied@redhat.com> * pfdo/drm-rcar-for-v3.12: (220 commits) drm/rcar-du: Add FBDEV emulation support drm/rcar-du: Add internal LVDS encoder support drm/rcar-du: Configure RGB output routing to DPAD0 drm/rcar-du: Rework output routing support drm/rcar-du: Add support for DEFR8 register drm/rcar-du: Add support for multiple groups drm/rcar-du: Fix buffer pitch alignment for R8A7790 DU drm/rcar-du: Add support for the R8A7790 DU drm/rcar-du: Move output routing configuration to group drm/rcar-du: Remove register definitions for the second channel drm/rcar-du: Use dynamic number of CRTCs instead of CRTCs array size drm/rcar-du: Introduce CRTCs groups drm/rcar-du: Rename rcar_du_plane_(init|register) to rcar_du_planes_* drm/rcar-du: Create rcar_du_planes structure drm/rcar-du: Rename platform data fields to match what they describe drm/rcar-du: Merge LVDS and VGA encoder code drm/rcar-du: Split VGA encoder and connector drm/rcar-du: Split LVDS encoder and connector drm/rcar-du: Clarify comment regarding plane Y source coordinate drm/rcar-du: Support per-CRTC clock and IRQ ... Conflicts: drivers/gpu/drm/i915/i915_dma.c drivers/gpu/drm/i915/intel_pm.c drivers/gpu/drm/qxl/qxl_release.c
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_dp.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c43
1 files changed, 39 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index c239739736db..3569d89b9e41 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -44,6 +44,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;
@@ -65,10 +100,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;
@@ -102,7 +137,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;
}