summaryrefslogtreecommitdiff
path: root/drivers/dma/mv_xor.c
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2013-07-29 19:42:14 +0400
committerDan Williams <djbw@fb.com>2013-08-23 09:57:37 +0400
commite03bc654f85604bcd5304debb597f398d1d03778 (patch)
tree380052c9f15b3b01034dac678acc1b3fcf21bf37 /drivers/dma/mv_xor.c
parent5733c38ae3473115ac7df3fe19bd2502149d8c51 (diff)
downloadlinux-e03bc654f85604bcd5304debb597f398d1d03778.tar.xz
mv_xor: support big endian systems using descriptor swap feature
The mv_xor driver had never been used in a big-endian context, and therefore was not using the hardware features to support such an execution environment. The hardware provides a "descriptor swap" bit that automatically swaps the bytes of the DMA descriptors, within blocks of 8 bytes. This requires a different DMA descriptor layout on big-endian systems, as well as enabling this "descriptor swap" bit. This mechanism is exactly identical to the one already used in the mv643xx_eth network driver and the mvneta network driver. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Signed-off-by: Dan Williams <djbw@fb.com>
Diffstat (limited to 'drivers/dma/mv_xor.c')
-rw-r--r--drivers/dma/mv_xor.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index c026b27f76e1..d332b9e3f9ce 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -64,7 +64,7 @@ static u32 mv_desc_get_src_addr(struct mv_xor_desc_slot *desc,
int src_idx)
{
struct mv_xor_desc *hw_desc = desc->hw_desc;
- return hw_desc->phy_src_addr[src_idx];
+ return hw_desc->phy_src_addr[mv_phy_src_idx(src_idx)];
}
@@ -107,7 +107,7 @@ static void mv_desc_set_src_addr(struct mv_xor_desc_slot *desc,
int index, dma_addr_t addr)
{
struct mv_xor_desc *hw_desc = desc->hw_desc;
- hw_desc->phy_src_addr[index] = addr;
+ hw_desc->phy_src_addr[mv_phy_src_idx(index)] = addr;
if (desc->type == DMA_XOR)
hw_desc->desc_command |= (1 << index);
}
@@ -192,6 +192,13 @@ static void mv_set_mode(struct mv_xor_chan *chan,
config &= ~0x7;
config |= op_mode;
+
+#if defined(__BIG_ENDIAN)
+ config |= XOR_DESCRIPTOR_SWAP;
+#else
+ config &= ~XOR_DESCRIPTOR_SWAP;
+#endif
+
writel_relaxed(config, XOR_CONFIG(chan));
chan->current_type = type;
}