* [PATCHv2 0/2] dma: mv_xor: big endian support
@ 2013-07-29 15:42 Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 1/2] mv_xor: use {readl, writel}_relaxed instead of __raw_{readl, writel} Thomas Petazzoni
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Thomas Petazzoni @ 2013-07-29 15:42 UTC (permalink / raw)
To: linux-arm-kernel
Vinod, Dan,
This small set of patches adds support for big endian operation in the
DMA mv_xor driver. It has been tested in both little-endian and
big-endian modes on the Armada XP GP board.
If possible, I'd like those to be merged for 3.12.
Changes since v1:
* Use readl_relaxed() and writel_relaxed() instead of readl/writel
when converting from raw_readl/raw_writel, since they preserve the
same barrier behavior. Suggested by Russell King.
Thanks!
Thomas
Thomas Petazzoni (2):
mv_xor: use {readl,writel}_relaxed instead of __raw_{readl,writel}
mv_xor: support big endian systems using descriptor swap feature
drivers/dma/mv_xor.c | 47 +++++++++++++++++++++++++++--------------------
drivers/dma/mv_xor.h | 28 +++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 21 deletions(-)
--
1.8.1.2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2 1/2] mv_xor: use {readl, writel}_relaxed instead of __raw_{readl, writel}
2013-07-29 15:42 [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
@ 2013-07-29 15:42 ` Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 2/2] mv_xor: support big endian systems using descriptor swap feature Thomas Petazzoni
2013-08-15 16:00 ` [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2 siblings, 0 replies; 8+ messages in thread
From: Thomas Petazzoni @ 2013-07-29 15:42 UTC (permalink / raw)
To: linux-arm-kernel
In order to support big-endian execution, the mv_xor driver is changed
to use the readl_relaxed() and writel_relaxed() accessors that
properly convert from the CPU endianess to the device endianess (which
in the case of Marvell XOR hardware is always little-endian).
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/dma/mv_xor.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 200f1a3..c026b27 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -114,25 +114,25 @@ static void mv_desc_set_src_addr(struct mv_xor_desc_slot *desc,
static u32 mv_chan_get_current_desc(struct mv_xor_chan *chan)
{
- return __raw_readl(XOR_CURR_DESC(chan));
+ return readl_relaxed(XOR_CURR_DESC(chan));
}
static void mv_chan_set_next_descriptor(struct mv_xor_chan *chan,
u32 next_desc_addr)
{
- __raw_writel(next_desc_addr, XOR_NEXT_DESC(chan));
+ writel_relaxed(next_desc_addr, XOR_NEXT_DESC(chan));
}
static void mv_chan_unmask_interrupts(struct mv_xor_chan *chan)
{
- u32 val = __raw_readl(XOR_INTR_MASK(chan));
+ u32 val = readl_relaxed(XOR_INTR_MASK(chan));
val |= XOR_INTR_MASK_VALUE << (chan->idx * 16);
- __raw_writel(val, XOR_INTR_MASK(chan));
+ writel_relaxed(val, XOR_INTR_MASK(chan));
}
static u32 mv_chan_get_intr_cause(struct mv_xor_chan *chan)
{
- u32 intr_cause = __raw_readl(XOR_INTR_CAUSE(chan));
+ u32 intr_cause = readl_relaxed(XOR_INTR_CAUSE(chan));
intr_cause = (intr_cause >> (chan->idx * 16)) & 0xFFFF;
return intr_cause;
}
@@ -149,13 +149,13 @@ static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan)
{
u32 val = ~(1 << (chan->idx * 16));
dev_dbg(mv_chan_to_devp(chan), "%s, val 0x%08x\n", __func__, val);
- __raw_writel(val, XOR_INTR_CAUSE(chan));
+ writel_relaxed(val, XOR_INTR_CAUSE(chan));
}
static void mv_xor_device_clear_err_status(struct mv_xor_chan *chan)
{
u32 val = 0xFFFF0000 >> (chan->idx * 16);
- __raw_writel(val, XOR_INTR_CAUSE(chan));
+ writel_relaxed(val, XOR_INTR_CAUSE(chan));
}
static int mv_can_chain(struct mv_xor_desc_slot *desc)
@@ -173,7 +173,7 @@ static void mv_set_mode(struct mv_xor_chan *chan,
enum dma_transaction_type type)
{
u32 op_mode;
- u32 config = __raw_readl(XOR_CONFIG(chan));
+ u32 config = readl_relaxed(XOR_CONFIG(chan));
switch (type) {
case DMA_XOR:
@@ -192,7 +192,7 @@ static void mv_set_mode(struct mv_xor_chan *chan,
config &= ~0x7;
config |= op_mode;
- __raw_writel(config, XOR_CONFIG(chan));
+ writel_relaxed(config, XOR_CONFIG(chan));
chan->current_type = type;
}
@@ -201,14 +201,14 @@ static void mv_chan_activate(struct mv_xor_chan *chan)
u32 activation;
dev_dbg(mv_chan_to_devp(chan), " activate chan.\n");
- activation = __raw_readl(XOR_ACTIVATION(chan));
+ activation = readl_relaxed(XOR_ACTIVATION(chan));
activation |= 0x1;
- __raw_writel(activation, XOR_ACTIVATION(chan));
+ writel_relaxed(activation, XOR_ACTIVATION(chan));
}
static char mv_chan_is_busy(struct mv_xor_chan *chan)
{
- u32 state = __raw_readl(XOR_ACTIVATION(chan));
+ u32 state = readl_relaxed(XOR_ACTIVATION(chan));
state = (state >> 4) & 0x3;
@@ -755,22 +755,22 @@ static void mv_dump_xor_regs(struct mv_xor_chan *chan)
{
u32 val;
- val = __raw_readl(XOR_CONFIG(chan));
+ val = readl_relaxed(XOR_CONFIG(chan));
dev_err(mv_chan_to_devp(chan), "config 0x%08x\n", val);
- val = __raw_readl(XOR_ACTIVATION(chan));
+ val = readl_relaxed(XOR_ACTIVATION(chan));
dev_err(mv_chan_to_devp(chan), "activation 0x%08x\n", val);
- val = __raw_readl(XOR_INTR_CAUSE(chan));
+ val = readl_relaxed(XOR_INTR_CAUSE(chan));
dev_err(mv_chan_to_devp(chan), "intr cause 0x%08x\n", val);
- val = __raw_readl(XOR_INTR_MASK(chan));
+ val = readl_relaxed(XOR_INTR_MASK(chan));
dev_err(mv_chan_to_devp(chan), "intr mask 0x%08x\n", val);
- val = __raw_readl(XOR_ERROR_CAUSE(chan));
+ val = readl_relaxed(XOR_ERROR_CAUSE(chan));
dev_err(mv_chan_to_devp(chan), "error cause 0x%08x\n", val);
- val = __raw_readl(XOR_ERROR_ADDR(chan));
+ val = readl_relaxed(XOR_ERROR_ADDR(chan));
dev_err(mv_chan_to_devp(chan), "error addr 0x%08x\n", val);
}
--
1.8.1.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCHv2 2/2] mv_xor: support big endian systems using descriptor swap feature
2013-07-29 15:42 [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 1/2] mv_xor: use {readl, writel}_relaxed instead of __raw_{readl, writel} Thomas Petazzoni
@ 2013-07-29 15:42 ` Thomas Petazzoni
2013-08-15 16:00 ` [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2 siblings, 0 replies; 8+ messages in thread
From: Thomas Petazzoni @ 2013-07-29 15:42 UTC (permalink / raw)
To: linux-arm-kernel
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>
---
drivers/dma/mv_xor.c | 11 +++++++++--
drivers/dma/mv_xor.h | 28 +++++++++++++++++++++++++++-
2 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index c026b27..d332b9e 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;
}
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index c619359..06b067f 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -29,8 +29,10 @@
#define MV_XOR_THRESHOLD 1
#define MV_XOR_MAX_CHANNELS 2
+/* Values for the XOR_CONFIG register */
#define XOR_OPERATION_MODE_XOR 0
#define XOR_OPERATION_MODE_MEMCPY 2
+#define XOR_DESCRIPTOR_SWAP BIT(14)
#define XOR_CURR_DESC(chan) (chan->mmr_base + 0x210 + (chan->idx * 4))
#define XOR_NEXT_DESC(chan) (chan->mmr_base + 0x200 + (chan->idx * 4))
@@ -143,7 +145,16 @@ struct mv_xor_desc_slot {
#endif
};
-/* This structure describes XOR descriptor size 64bytes */
+/*
+ * This structure describes XOR descriptor size 64bytes. The
+ * mv_phy_src_idx() macro must be used when indexing the values of the
+ * phy_src_addr[] array. This is due to the fact that the 'descriptor
+ * swap' feature, used on big endian systems, swaps descriptors data
+ * within blocks of 8 bytes. So two consecutive values of the
+ * phy_src_addr[] array are actually swapped in big-endian, which
+ * explains the different mv_phy_src_idx() implementation.
+ */
+#if defined(__LITTLE_ENDIAN)
struct mv_xor_desc {
u32 status; /* descriptor execution status */
u32 crc32_result; /* result of CRC-32 calculation */
@@ -155,6 +166,21 @@ struct mv_xor_desc {
u32 reserved0;
u32 reserved1;
};
+#define mv_phy_src_idx(src_idx) (src_idx)
+#else
+struct mv_xor_desc {
+ u32 crc32_result; /* result of CRC-32 calculation */
+ u32 status; /* descriptor execution status */
+ u32 phy_next_desc; /* next descriptor address pointer */
+ u32 desc_command; /* type of operation to be carried out */
+ u32 phy_dest_addr; /* destination block address */
+ u32 byte_count; /* size of src/dst blocks in bytes */
+ u32 phy_src_addr[8]; /* source block addresses */
+ u32 reserved1;
+ u32 reserved0;
+};
+#define mv_phy_src_idx(src_idx) (src_idx ^ 1)
+#endif
#define to_mv_sw_desc(addr_hw_desc) \
container_of(addr_hw_desc, struct mv_xor_desc_slot, hw_desc)
--
1.8.1.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCHv2 0/2] dma: mv_xor: big endian support
2013-07-29 15:42 [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 1/2] mv_xor: use {readl, writel}_relaxed instead of __raw_{readl, writel} Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 2/2] mv_xor: support big endian systems using descriptor swap feature Thomas Petazzoni
@ 2013-08-15 16:00 ` Thomas Petazzoni
2013-08-15 16:08 ` Jason Cooper
2013-08-19 4:22 ` Vinod Koul
2 siblings, 2 replies; 8+ messages in thread
From: Thomas Petazzoni @ 2013-08-15 16:00 UTC (permalink / raw)
To: linux-arm-kernel
Vinod, Dan,
I've sent the below two patches about three weeks ago, and they haven't
received any comments. They are relatively simple, so would it be
possible to queue them for 3.12 ?
Jason, Andrew, Gregory, as the Marvell EBU maintainers, it would be
great if you could give your Acked-by and/or Tested-by on those patches.
Thanks!
Thomas
On Mon, 29 Jul 2013 17:42:12 +0200, Thomas Petazzoni wrote:
> Vinod, Dan,
>
> This small set of patches adds support for big endian operation in the
> DMA mv_xor driver. It has been tested in both little-endian and
> big-endian modes on the Armada XP GP board.
>
> If possible, I'd like those to be merged for 3.12.
>
> Changes since v1:
> * Use readl_relaxed() and writel_relaxed() instead of readl/writel
> when converting from raw_readl/raw_writel, since they preserve the
> same barrier behavior. Suggested by Russell King.
>
> Thanks!
>
> Thomas
>
> Thomas Petazzoni (2):
> mv_xor: use {readl,writel}_relaxed instead of __raw_{readl,writel}
> mv_xor: support big endian systems using descriptor swap feature
>
> drivers/dma/mv_xor.c | 47 +++++++++++++++++++++++++++--------------------
> drivers/dma/mv_xor.h | 28 +++++++++++++++++++++++++++-
> 2 files changed, 54 insertions(+), 21 deletions(-)
>
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2 0/2] dma: mv_xor: big endian support
2013-08-15 16:00 ` [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
@ 2013-08-15 16:08 ` Jason Cooper
2013-08-19 4:22 ` Vinod Koul
1 sibling, 0 replies; 8+ messages in thread
From: Jason Cooper @ 2013-08-15 16:08 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Aug 15, 2013 at 06:00:44PM +0200, Thomas Petazzoni wrote:
> Jason, Andrew, Gregory, as the Marvell EBU maintainers, it would be
> great if you could give your Acked-by and/or Tested-by on those patches.
Ahh, yes. I thought these had been accepted. If you're waiting for us,
Acked-by: Jason Cooper <jason@lakedaemon.net>
thx,
Jason.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2 0/2] dma: mv_xor: big endian support
2013-08-15 16:00 ` [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2013-08-15 16:08 ` Jason Cooper
@ 2013-08-19 4:22 ` Vinod Koul
2013-08-19 8:33 ` Dan Williams
1 sibling, 1 reply; 8+ messages in thread
From: Vinod Koul @ 2013-08-19 4:22 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Aug 15, 2013 at 06:00:44PM +0200, Thomas Petazzoni wrote:
> Vinod, Dan,
>
> I've sent the below two patches about three weeks ago, and they haven't
> received any comments. They are relatively simple, so would it be
> possible to queue them for 3.12 ?
>
> Jason, Andrew, Gregory, as the Marvell EBU maintainers, it would be
> great if you could give your Acked-by and/or Tested-by on those patches.
>
> Thanks!
>
> Thomas
>
> On Mon, 29 Jul 2013 17:42:12 +0200, Thomas Petazzoni wrote:
> > Vinod, Dan,
> >
> > This small set of patches adds support for big endian operation in the
> > DMA mv_xor driver. It has been tested in both little-endian and
> > big-endian modes on the Armada XP GP board.
> >
> > If possible, I'd like those to be merged for 3.12.
These look fine to me.
Dan let me know if you okay with me to carry these
~Vinod
> >
> > Changes since v1:
> > * Use readl_relaxed() and writel_relaxed() instead of readl/writel
> > when converting from raw_readl/raw_writel, since they preserve the
> > same barrier behavior. Suggested by Russell King.
> >
> > Thanks!
> >
> > Thomas
> >
> > Thomas Petazzoni (2):
> > mv_xor: use {readl,writel}_relaxed instead of __raw_{readl,writel}
> > mv_xor: support big endian systems using descriptor swap feature
> >
> > drivers/dma/mv_xor.c | 47 +++++++++++++++++++++++++++--------------------
> > drivers/dma/mv_xor.h | 28 +++++++++++++++++++++++++++-
> > 2 files changed, 54 insertions(+), 21 deletions(-)
> >
>
>
>
> --
> Thomas Petazzoni, Free Electrons
> Kernel, drivers, real-time and embedded Linux
> development, consulting, training and support.
> http://free-electrons.com
--
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2 0/2] dma: mv_xor: big endian support
2013-08-19 4:22 ` Vinod Koul
@ 2013-08-19 8:33 ` Dan Williams
2013-08-19 9:42 ` Thomas Petazzoni
0 siblings, 1 reply; 8+ messages in thread
From: Dan Williams @ 2013-08-19 8:33 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, Aug 18, 2013 at 9:22 PM, Vinod Koul <vinod.koul@intel.com> wrote:
> On Thu, Aug 15, 2013 at 06:00:44PM +0200, Thomas Petazzoni wrote:
>> Vinod, Dan,
>>
>> I've sent the below two patches about three weeks ago, and they haven't
>> received any comments. They are relatively simple, so would it be
>> possible to queue them for 3.12 ?
>>
>> Jason, Andrew, Gregory, as the Marvell EBU maintainers, it would be
>> great if you could give your Acked-by and/or Tested-by on those patches.
>>
>> Thanks!
>>
>> Thomas
>>
>> On Mon, 29 Jul 2013 17:42:12 +0200, Thomas Petazzoni wrote:
>> > Vinod, Dan,
>> >
>> > This small set of patches adds support for big endian operation in the
>> > DMA mv_xor driver. It has been tested in both little-endian and
>> > big-endian modes on the Armada XP GP board.
>> >
>> > If possible, I'd like those to be merged for 3.12.
> These look fine to me.
>
> Dan let me know if you okay with me to carry these
I'm dusting off the tree for a few other patches. I'll apply them.
--
Dan
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCHv2 0/2] dma: mv_xor: big endian support
2013-08-19 8:33 ` Dan Williams
@ 2013-08-19 9:42 ` Thomas Petazzoni
0 siblings, 0 replies; 8+ messages in thread
From: Thomas Petazzoni @ 2013-08-19 9:42 UTC (permalink / raw)
To: linux-arm-kernel
Dear Dan Williams,
On Mon, 19 Aug 2013 01:33:26 -0700, Dan Williams wrote:
> >> > Vinod, Dan,
> >> >
> >> > This small set of patches adds support for big endian operation in the
> >> > DMA mv_xor driver. It has been tested in both little-endian and
> >> > big-endian modes on the Armada XP GP board.
> >> >
> >> > If possible, I'd like those to be merged for 3.12.
> > These look fine to me.
> >
> > Dan let me know if you okay with me to carry these
>
> I'm dusting off the tree for a few other patches. I'll apply them.
Great, thanks!
Thomas
--
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-08-19 9:42 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-29 15:42 [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 1/2] mv_xor: use {readl, writel}_relaxed instead of __raw_{readl, writel} Thomas Petazzoni
2013-07-29 15:42 ` [PATCHv2 2/2] mv_xor: support big endian systems using descriptor swap feature Thomas Petazzoni
2013-08-15 16:00 ` [PATCHv2 0/2] dma: mv_xor: big endian support Thomas Petazzoni
2013-08-15 16:08 ` Jason Cooper
2013-08-19 4:22 ` Vinod Koul
2013-08-19 8:33 ` Dan Williams
2013-08-19 9:42 ` Thomas Petazzoni
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).