提交 2efc3449 编写于 作者: J Javier Martin 提交者: Vinod Koul

dmaengine: imx-dma: remove dma_mode member of internal structure.

dmaengine now provides 'enum dma_transfer_direction' to properly
specify DMA transfer direction. For this reason, DMA_MODE_* defines
are replaced by this new type and therefore dma_mode member becomes
redundant.
Signed-off-by: NJavier Martin <javier.martin@vista-silicon.com>
Acked-by: NSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: NVinod Koul <vinod.koul@linux.intel.com>
上级 232e3c2c
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
#define IMXDMA_MAX_CHAN_DESCRIPTORS 16 #define IMXDMA_MAX_CHAN_DESCRIPTORS 16
#define IMX_DMA_CHANNELS 16 #define IMX_DMA_CHANNELS 16
#define DMA_MODE_READ 0
#define DMA_MODE_WRITE 1
#define DMA_MODE_MASK 1
#define IMX_DMA_LENGTH_LOOP ((unsigned int)-1) #define IMX_DMA_LENGTH_LOOP ((unsigned int)-1)
#define IMX_DMA_MEMSIZE_32 (0 << 4) #define IMX_DMA_MEMSIZE_32 (0 << 4)
#define IMX_DMA_MEMSIZE_8 (1 << 4) #define IMX_DMA_MEMSIZE_8 (1 << 4)
...@@ -133,7 +129,6 @@ enum imxdma_prep_type { ...@@ -133,7 +129,6 @@ enum imxdma_prep_type {
*/ */
struct imxdma_channel_internal { struct imxdma_channel_internal {
unsigned int dma_mode;
struct scatterlist *sg; struct scatterlist *sg;
unsigned int resbytes; unsigned int resbytes;
...@@ -154,7 +149,7 @@ struct imxdma_desc { ...@@ -154,7 +149,7 @@ struct imxdma_desc {
dma_addr_t src; dma_addr_t src;
dma_addr_t dest; dma_addr_t dest;
size_t len; size_t len;
unsigned int dmamode; enum dma_transfer_direction direction;
enum imxdma_prep_type type; enum imxdma_prep_type type;
/* For memcpy and interleaved */ /* For memcpy and interleaved */
unsigned int config_port; unsigned int config_port;
...@@ -239,8 +234,9 @@ static int imxdma_hw_chain(struct imxdma_channel_internal *imxdma) ...@@ -239,8 +234,9 @@ static int imxdma_hw_chain(struct imxdma_channel_internal *imxdma)
/* /*
* imxdma_sg_next - prepare next chunk for scatter-gather DMA emulation * imxdma_sg_next - prepare next chunk for scatter-gather DMA emulation
*/ */
static inline int imxdma_sg_next(struct imxdma_channel *imxdmac, struct scatterlist *sg) static inline int imxdma_sg_next(struct imxdma_desc *d, struct scatterlist *sg)
{ {
struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
struct imxdma_channel_internal *imxdma = &imxdmac->internal; struct imxdma_channel_internal *imxdma = &imxdmac->internal;
unsigned long now; unsigned long now;
...@@ -248,7 +244,7 @@ static inline int imxdma_sg_next(struct imxdma_channel *imxdmac, struct scatterl ...@@ -248,7 +244,7 @@ static inline int imxdma_sg_next(struct imxdma_channel *imxdmac, struct scatterl
if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP) if (imxdma->resbytes != IMX_DMA_LENGTH_LOOP)
imxdma->resbytes -= now; imxdma->resbytes -= now;
if ((imxdma->dma_mode & DMA_MODE_MASK) == DMA_MODE_READ) if (d->direction == DMA_DEV_TO_MEM)
imx_dmav1_writel(sg->dma_address, DMA_DAR(imxdmac->channel)); imx_dmav1_writel(sg->dma_address, DMA_DAR(imxdmac->channel));
else else
imx_dmav1_writel(sg->dma_address, DMA_SAR(imxdmac->channel)); imx_dmav1_writel(sg->dma_address, DMA_SAR(imxdmac->channel));
...@@ -265,14 +261,12 @@ static inline int imxdma_sg_next(struct imxdma_channel *imxdmac, struct scatterl ...@@ -265,14 +261,12 @@ static inline int imxdma_sg_next(struct imxdma_channel *imxdmac, struct scatterl
} }
static int static int
imxdma_setup_single_hw(struct imxdma_channel *imxdmac, dma_addr_t dma_address, imxdma_setup_mem2mem_hw(struct imxdma_channel *imxdmac, dma_addr_t dma_address,
unsigned int dma_length, unsigned int dev_addr, unsigned int dma_length, unsigned int dev_addr)
unsigned int dmamode)
{ {
int channel = imxdmac->channel; int channel = imxdmac->channel;
imxdmac->internal.sg = NULL; imxdmac->internal.sg = NULL;
imxdmac->internal.dma_mode = dmamode;
if (!dma_address) { if (!dma_address) {
printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n", printk(KERN_ERR "imxdma%d: imx_dma_setup_single null address\n",
...@@ -286,38 +280,24 @@ imxdma_setup_single_hw(struct imxdma_channel *imxdmac, dma_addr_t dma_address, ...@@ -286,38 +280,24 @@ imxdma_setup_single_hw(struct imxdma_channel *imxdmac, dma_addr_t dma_address,
return -EINVAL; return -EINVAL;
} }
if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d " "dev_addr=0x%08x for write\n",
"dev_addr=0x%08x for read\n", channel, __func__, (unsigned int)dma_address,
channel, __func__, (unsigned int)dma_address, dma_length, dev_addr);
dma_length, dev_addr);
imx_dmav1_writel(dev_addr, DMA_SAR(channel)); imx_dmav1_writel(dma_address, DMA_SAR(channel));
imx_dmav1_writel(dma_address, DMA_DAR(channel)); imx_dmav1_writel(dev_addr, DMA_DAR(channel));
imx_dmav1_writel(imxdmac->internal.ccr_from_device, DMA_CCR(channel)); imx_dmav1_writel(imxdmac->internal.ccr_to_device,
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { DMA_CCR(channel));
pr_debug("imxdma%d: %s dma_addressg=0x%08x dma_length=%d "
"dev_addr=0x%08x for write\n",
channel, __func__, (unsigned int)dma_address,
dma_length, dev_addr);
imx_dmav1_writel(dma_address, DMA_SAR(channel));
imx_dmav1_writel(dev_addr, DMA_DAR(channel));
imx_dmav1_writel(imxdmac->internal.ccr_to_device,
DMA_CCR(channel));
} else {
printk(KERN_ERR "imxdma%d: imx_dma_setup_single bad dmamode\n",
channel);
return -EINVAL;
}
imx_dmav1_writel(dma_length, DMA_CNTR(channel)); imx_dmav1_writel(dma_length, DMA_CNTR(channel));
return 0; return 0;
} }
static void imxdma_enable_hw(struct imxdma_channel *imxdmac) static void imxdma_enable_hw(struct imxdma_desc *d)
{ {
struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
int channel = imxdmac->channel; int channel = imxdmac->channel;
unsigned long flags; unsigned long flags;
...@@ -338,7 +318,7 @@ static void imxdma_enable_hw(struct imxdma_channel *imxdmac) ...@@ -338,7 +318,7 @@ static void imxdma_enable_hw(struct imxdma_channel *imxdmac)
imxdmac->internal.sg = sg_next(imxdmac->internal.sg); imxdmac->internal.sg = sg_next(imxdmac->internal.sg);
if (imxdmac->internal.sg) { if (imxdmac->internal.sg) {
u32 tmp; u32 tmp;
imxdma_sg_next(imxdmac, imxdmac->internal.sg); imxdma_sg_next(d, imxdmac->internal.sg);
tmp = imx_dmav1_readl(DMA_CCR(channel)); tmp = imx_dmav1_readl(DMA_CCR(channel));
imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT, imx_dmav1_writel(tmp | CCR_RPT | CCR_ACRPT,
DMA_CCR(channel)); DMA_CCR(channel));
...@@ -395,18 +375,18 @@ imxdma_config_channel_hw(struct imxdma_channel *imxdmac, unsigned int config_por ...@@ -395,18 +375,18 @@ imxdma_config_channel_hw(struct imxdma_channel *imxdmac, unsigned int config_por
} }
static int static int
imxdma_setup_sg_hw(struct imxdma_channel *imxdmac, imxdma_setup_sg_hw(struct imxdma_desc *d,
struct scatterlist *sg, unsigned int sgcount, struct scatterlist *sg, unsigned int sgcount,
unsigned int dma_length, unsigned int dev_addr, unsigned int dma_length, unsigned int dev_addr,
unsigned int dmamode) enum dma_transfer_direction direction)
{ {
struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
int channel = imxdmac->channel; int channel = imxdmac->channel;
if (imxdmac->internal.in_use) if (imxdmac->internal.in_use)
return -EBUSY; return -EBUSY;
imxdmac->internal.sg = sg; imxdmac->internal.sg = sg;
imxdmac->internal.dma_mode = dmamode;
imxdmac->internal.resbytes = dma_length; imxdmac->internal.resbytes = dma_length;
if (!sg || !sgcount) { if (!sg || !sgcount) {
...@@ -421,14 +401,14 @@ imxdma_setup_sg_hw(struct imxdma_channel *imxdmac, ...@@ -421,14 +401,14 @@ imxdma_setup_sg_hw(struct imxdma_channel *imxdmac,
return -EINVAL; return -EINVAL;
} }
if ((dmamode & DMA_MODE_MASK) == DMA_MODE_READ) { if (direction == DMA_DEV_TO_MEM) {
pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d " pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
"dev_addr=0x%08x for read\n", "dev_addr=0x%08x for read\n",
channel, __func__, sg, sgcount, dma_length, dev_addr); channel, __func__, sg, sgcount, dma_length, dev_addr);
imx_dmav1_writel(dev_addr, DMA_SAR(channel)); imx_dmav1_writel(dev_addr, DMA_SAR(channel));
imx_dmav1_writel(imxdmac->internal.ccr_from_device, DMA_CCR(channel)); imx_dmav1_writel(imxdmac->internal.ccr_from_device, DMA_CCR(channel));
} else if ((dmamode & DMA_MODE_MASK) == DMA_MODE_WRITE) { } else if (direction == DMA_MEM_TO_DEV) {
pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d " pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
"dev_addr=0x%08x for write\n", "dev_addr=0x%08x for write\n",
channel, __func__, sg, sgcount, dma_length, dev_addr); channel, __func__, sg, sgcount, dma_length, dev_addr);
...@@ -441,7 +421,7 @@ imxdma_setup_sg_hw(struct imxdma_channel *imxdmac, ...@@ -441,7 +421,7 @@ imxdma_setup_sg_hw(struct imxdma_channel *imxdmac,
return -EINVAL; return -EINVAL;
} }
imxdma_sg_next(imxdmac, sg); imxdma_sg_next(d, sg);
return 0; return 0;
} }
...@@ -519,13 +499,26 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac) ...@@ -519,13 +499,26 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
{ {
struct imxdma_channel_internal *imxdma = &imxdmac->internal; struct imxdma_channel_internal *imxdma = &imxdmac->internal;
int chno = imxdmac->channel; int chno = imxdmac->channel;
struct imxdma_desc *desc;
if (imxdma->sg) { if (imxdma->sg) {
u32 tmp; u32 tmp;
imxdma->sg = sg_next(imxdma->sg); imxdma->sg = sg_next(imxdma->sg);
if (imxdma->sg) { if (imxdma->sg) {
imxdma_sg_next(imxdmac, imxdma->sg);
spin_lock(&imxdmac->lock);
if (list_empty(&imxdmac->ld_active)) {
spin_unlock(&imxdmac->lock);
goto out;
}
desc = list_first_entry(&imxdmac->ld_active,
struct imxdma_desc,
node);
spin_unlock(&imxdmac->lock);
imxdma_sg_next(desc, imxdma->sg);
tmp = imx_dmav1_readl(DMA_CCR(chno)); tmp = imx_dmav1_readl(DMA_CCR(chno));
...@@ -558,6 +551,7 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac) ...@@ -558,6 +551,7 @@ static void dma_irq_handle_channel(struct imxdma_channel *imxdmac)
} }
} }
out:
imx_dmav1_writel(0, DMA_CCR(chno)); imx_dmav1_writel(0, DMA_CCR(chno));
imxdma->in_use = 0; imxdma->in_use = 0;
/* Tasklet irq */ /* Tasklet irq */
...@@ -601,8 +595,7 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) ...@@ -601,8 +595,7 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
d->config_port, d->config_mem, 0, 0); d->config_port, d->config_mem, 0, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = imxdma_setup_single_hw(imxdmac, d->src, ret = imxdma_setup_mem2mem_hw(imxdmac, d->src, d->len, d->dest);
d->len, d->dest, d->dmamode);
if (ret < 0) if (ret < 0)
return ret; return ret;
break; break;
...@@ -610,19 +603,15 @@ static int imxdma_xfer_desc(struct imxdma_desc *d) ...@@ -610,19 +603,15 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
/* Cyclic transfer is the same as slave_sg with special sg configuration. */ /* Cyclic transfer is the same as slave_sg with special sg configuration. */
case IMXDMA_DESC_CYCLIC: case IMXDMA_DESC_CYCLIC:
case IMXDMA_DESC_SLAVE_SG: case IMXDMA_DESC_SLAVE_SG:
if (d->dmamode == DMA_MODE_READ) ret = imxdma_setup_sg_hw(d, d->sg, d->sgcount, d->len,
ret = imxdma_setup_sg_hw(imxdmac, d->sg, imxdmac->per_address, d->direction);
d->sgcount, d->len, d->src, d->dmamode);
else
ret = imxdma_setup_sg_hw(imxdmac, d->sg,
d->sgcount, d->len, d->dest, d->dmamode);
if (ret < 0) if (ret < 0)
return ret; return ret;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
imxdma_enable_hw(imxdmac); imxdma_enable_hw(d);
return 0; return 0;
} }
...@@ -839,11 +828,10 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg( ...@@ -839,11 +828,10 @@ static struct dma_async_tx_descriptor *imxdma_prep_slave_sg(
desc->sg = sgl; desc->sg = sgl;
desc->sgcount = sg_len; desc->sgcount = sg_len;
desc->len = dma_length; desc->len = dma_length;
desc->direction = direction;
if (direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) {
desc->dmamode = DMA_MODE_READ;
desc->src = imxdmac->per_address; desc->src = imxdmac->per_address;
} else { } else {
desc->dmamode = DMA_MODE_WRITE;
desc->dest = imxdmac->per_address; desc->dest = imxdmac->per_address;
} }
desc->desc.callback = NULL; desc->desc.callback = NULL;
...@@ -900,11 +888,10 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( ...@@ -900,11 +888,10 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
desc->sg = imxdmac->sg_list; desc->sg = imxdmac->sg_list;
desc->sgcount = periods; desc->sgcount = periods;
desc->len = IMX_DMA_LENGTH_LOOP; desc->len = IMX_DMA_LENGTH_LOOP;
desc->direction = direction;
if (direction == DMA_DEV_TO_MEM) { if (direction == DMA_DEV_TO_MEM) {
desc->dmamode = DMA_MODE_READ;
desc->src = imxdmac->per_address; desc->src = imxdmac->per_address;
} else { } else {
desc->dmamode = DMA_MODE_WRITE;
desc->dest = imxdmac->per_address; desc->dest = imxdmac->per_address;
} }
desc->desc.callback = NULL; desc->desc.callback = NULL;
...@@ -934,7 +921,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_memcpy( ...@@ -934,7 +921,7 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_memcpy(
desc->src = src; desc->src = src;
desc->dest = dest; desc->dest = dest;
desc->len = len; desc->len = len;
desc->dmamode = DMA_MODE_WRITE; desc->direction = DMA_MEM_TO_MEM;
desc->config_port = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR; desc->config_port = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR;
desc->config_mem = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR; desc->config_mem = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR;
desc->desc.callback = NULL; desc->desc.callback = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册