* [PATCH] dmaengine: sun6i: Fix memcpy operation
@ 2014-11-11 18:35 Maxime Ripard
2014-11-12 9:25 ` Vinod Koul
0 siblings, 1 reply; 3+ messages in thread
From: Maxime Ripard @ 2014-11-11 18:35 UTC (permalink / raw)
To: Vinod Koul, dmaengine; +Cc: linux-kernel, Chen-Yu Tsai, Maxime Ripard, stable
The prep_memcpy call was not setting any meaningful burst and width because it
was relying on the dma_slave_config was not set already.
Rework the needed conversion functions, and hardcode the width and burst to
use.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Cc: stable@vger.kernel.org
---
Hi Vinod,
This is a fix aimed at 3.18.
Thanks!
Maxime
drivers/dma/sun6i-dma.c | 61 ++++++++++++++++++++++++-------------------------
1 file changed, 30 insertions(+), 31 deletions(-)
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 3aa10b328254..91292f5513ff 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -230,30 +230,25 @@ static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev,
readl(pchan->base + DMA_CHAN_CUR_PARA));
}
-static inline int convert_burst(u32 maxburst, u8 *burst)
+static inline s8 convert_burst(u32 maxburst)
{
switch (maxburst) {
case 1:
- *burst = 0;
- break;
+ return 0;
case 8:
- *burst = 2;
- break;
+ return 2;
default:
return -EINVAL;
}
-
- return 0;
}
-static inline int convert_buswidth(enum dma_slave_buswidth addr_width, u8 *width)
+static inline s8 convert_buswidth(enum dma_slave_buswidth addr_width)
{
if ((addr_width < DMA_SLAVE_BUSWIDTH_1_BYTE) ||
(addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
return -EINVAL;
- *width = addr_width >> 1;
- return 0;
+ return addr_width >> 1;
}
static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev,
@@ -284,26 +279,25 @@ static inline int sun6i_dma_cfg_lli(struct sun6i_dma_lli *lli,
struct dma_slave_config *config)
{
u8 src_width, dst_width, src_burst, dst_burst;
- int ret;
if (!config)
return -EINVAL;
- ret = convert_burst(config->src_maxburst, &src_burst);
- if (ret)
- return ret;
+ src_burst = convert_burst(config->src_maxburst);
+ if (src_burst)
+ return src_burst;
- ret = convert_burst(config->dst_maxburst, &dst_burst);
- if (ret)
- return ret;
+ dst_burst = convert_burst(config->dst_maxburst);
+ if (dst_burst)
+ return dst_burst;
- ret = convert_buswidth(config->src_addr_width, &src_width);
- if (ret)
- return ret;
+ src_width = convert_buswidth(config->src_addr_width);
+ if (src_width)
+ return src_width;
- ret = convert_buswidth(config->dst_addr_width, &dst_width);
- if (ret)
- return ret;
+ dst_width = convert_buswidth(config->dst_addr_width);
+ if (dst_width)
+ return dst_width;
lli->cfg = DMA_CHAN_CFG_SRC_BURST(src_burst) |
DMA_CHAN_CFG_SRC_WIDTH(src_width) |
@@ -542,11 +536,10 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
{
struct sun6i_dma_dev *sdev = to_sun6i_dma_dev(chan->device);
struct sun6i_vchan *vchan = to_sun6i_vchan(chan);
- struct dma_slave_config *sconfig = &vchan->cfg;
struct sun6i_dma_lli *v_lli;
struct sun6i_desc *txd;
dma_addr_t p_lli;
- int ret;
+ s8 burst, width;
dev_dbg(chan2dev(chan),
"%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n",
@@ -565,14 +558,21 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
goto err_txd_free;
}
- ret = sun6i_dma_cfg_lli(v_lli, src, dest, len, sconfig);
- if (ret)
- goto err_dma_free;
+ v_lli->src = src;
+ v_lli->dst = dest;
+ v_lli->len = len;
+ v_lli->para = NORMAL_WAIT;
+ burst = convert_burst(8);
+ width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
v_lli->cfg |= DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) |
DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) |
DMA_CHAN_CFG_DST_LINEAR_MODE |
- DMA_CHAN_CFG_SRC_LINEAR_MODE;
+ DMA_CHAN_CFG_SRC_LINEAR_MODE |
+ DMA_CHAN_CFG_SRC_BURST(burst) |
+ DMA_CHAN_CFG_SRC_WIDTH(width) |
+ DMA_CHAN_CFG_DST_BURST(burst) |
+ DMA_CHAN_CFG_DST_WIDTH(width);
sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
@@ -580,8 +580,6 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
-err_dma_free:
- dma_pool_free(sdev->pool, v_lli, p_lli);
err_txd_free:
kfree(txd);
return NULL;
@@ -915,6 +913,7 @@ static int sun6i_dma_probe(struct platform_device *pdev)
sdc->slave.device_prep_dma_memcpy = sun6i_dma_prep_dma_memcpy;
sdc->slave.device_control = sun6i_dma_control;
sdc->slave.chancnt = NR_MAX_VCHANS;
+ sdc->slave.copy_align = 4;
sdc->slave.dev = &pdev->dev;
--
2.1.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] dmaengine: sun6i: Fix memcpy operation
2014-11-11 18:35 [PATCH] dmaengine: sun6i: Fix memcpy operation Maxime Ripard
@ 2014-11-12 9:25 ` Vinod Koul
2014-11-12 9:39 ` Maxime Ripard
0 siblings, 1 reply; 3+ messages in thread
From: Vinod Koul @ 2014-11-12 9:25 UTC (permalink / raw)
To: Maxime Ripard; +Cc: dmaengine, linux-kernel, Chen-Yu Tsai, stable
On Tue, Nov 11, 2014 at 07:35:52PM +0100, Maxime Ripard wrote:
> The prep_memcpy call was not setting any meaningful burst and width because it
> was relying on the dma_slave_config was not set already.
>
> Rework the needed conversion functions, and hardcode the width and burst to
> use.
>
Applied, thanks.
For memcpy, reying on dma_slave-config wasnt the right idea to start with.
Memcoy is supposed to work even without that
Thanks
--
~Vinod
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] dmaengine: sun6i: Fix memcpy operation
2014-11-12 9:25 ` Vinod Koul
@ 2014-11-12 9:39 ` Maxime Ripard
0 siblings, 0 replies; 3+ messages in thread
From: Maxime Ripard @ 2014-11-12 9:39 UTC (permalink / raw)
To: Vinod Koul; +Cc: dmaengine, linux-kernel, Chen-Yu Tsai, stable
[-- Attachment #1: Type: text/plain, Size: 703 bytes --]
On Wed, Nov 12, 2014 at 02:55:06PM +0530, Vinod Koul wrote:
> On Tue, Nov 11, 2014 at 07:35:52PM +0100, Maxime Ripard wrote:
> > The prep_memcpy call was not setting any meaningful burst and width because it
> > was relying on the dma_slave_config was not set already.
> >
> > Rework the needed conversion functions, and hardcode the width and burst to
> > use.
> >
>
> Applied, thanks.
>
> For memcpy, reying on dma_slave-config wasnt the right idea to start with.
> Memcoy is supposed to work even without that
Yeah, I learned that the "hard" way :)
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-11-12 9:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-11 18:35 [PATCH] dmaengine: sun6i: Fix memcpy operation Maxime Ripard
2014-11-12 9:25 ` Vinod Koul
2014-11-12 9:39 ` Maxime Ripard
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).