Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 297537
b: refs/heads/master
c: 359291a
h: refs/heads/master
i:
  297535: 255e619
v: v3
  • Loading branch information
Javier Martin authored and Vinod Koul committed Mar 26, 2012
1 parent 9625c77 commit 0ff44f9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 64 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bdc0c7534c80c479b2336aed3e4016f4743f4853
refs/heads/master: 359291a1a095a8a402405cd9c4bab46684e7bcfe
98 changes: 35 additions & 63 deletions trunk/drivers/dma/imx-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ struct imxdma_channel_internal {

int in_use;

u32 ccr_from_device;
u32 ccr_to_device;

struct timer_list watchdog;

int hw_chaining;
Expand Down Expand Up @@ -182,6 +179,8 @@ struct imxdma_channel {
enum dma_status status;
int dma_request;
struct scatterlist *sg_list;
u32 ccr_from_device;
u32 ccr_to_device;
};

struct imxdma_engine {
Expand Down Expand Up @@ -313,58 +312,6 @@ static void imxdma_disable_hw(struct imxdma_channel *imxdmac)
local_irq_restore(flags);
}

static int
imxdma_setup_sg_hw(struct imxdma_desc *d,
struct scatterlist *sg, unsigned int sgcount,
unsigned int dma_length, unsigned int dev_addr,
enum dma_transfer_direction direction)
{
struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
int channel = imxdmac->channel;

if (imxdmac->internal.in_use)
return -EBUSY;

imxdmac->internal.sg = sg;
imxdmac->internal.resbytes = dma_length;

if (!sg || !sgcount) {
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg empty sg list\n",
channel);
return -EINVAL;
}

if (!sg->length) {
printk(KERN_ERR "imxdma%d: imx_dma_setup_sg zero length\n",
channel);
return -EINVAL;
}

if (direction == DMA_DEV_TO_MEM) {
pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
"dev_addr=0x%08x for read\n",
channel, __func__, sg, sgcount, dma_length, dev_addr);

imx_dmav1_writel(dev_addr, DMA_SAR(channel));
imx_dmav1_writel(imxdmac->internal.ccr_from_device, DMA_CCR(channel));
} else if (direction == DMA_MEM_TO_DEV) {
pr_debug("imxdma%d: %s sg=%p sgcount=%d total length=%d "
"dev_addr=0x%08x for write\n",
channel, __func__, sg, sgcount, dma_length, dev_addr);

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_sg bad dmamode\n",
channel);
return -EINVAL;
}

imxdma_sg_next(d, sg);

return 0;
}

static void imxdma_watchdog(unsigned long data)
{
struct imxdma_channel *imxdmac = (struct imxdma_channel *)data;
Expand Down Expand Up @@ -526,7 +473,6 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
{
struct imxdma_channel *imxdmac = to_imxdma_chan(d->desc.chan);
struct imxdma_engine *imxdma = imxdmac->imxdma;
int ret;

/* Configure and enable */
switch (d->type) {
Expand All @@ -548,10 +494,37 @@ static int imxdma_xfer_desc(struct imxdma_desc *d)
/* Cyclic transfer is the same as slave_sg with special sg configuration. */
case IMXDMA_DESC_CYCLIC:
case IMXDMA_DESC_SLAVE_SG:
ret = imxdma_setup_sg_hw(d, d->sg, d->sgcount, d->len,
imxdmac->per_address, d->direction);
if (ret < 0)
return ret;
imxdmac->internal.sg = d->sg;
imxdmac->internal.resbytes = d->len;

if (d->direction == DMA_DEV_TO_MEM) {
imx_dmav1_writel(imxdmac->per_address,
DMA_SAR(imxdmac->channel));
imx_dmav1_writel(imxdmac->ccr_from_device,
DMA_CCR(imxdmac->channel));

dev_dbg(imxdma->dev, "%s channel: %d sg=%p sgcount=%d "
"total length=%d dev_addr=0x%08x (dev2mem)\n",
__func__, imxdmac->channel, d->sg, d->sgcount,
d->len, imxdmac->per_address);
} else if (d->direction == DMA_MEM_TO_DEV) {
imx_dmav1_writel(imxdmac->per_address,
DMA_DAR(imxdmac->channel));
imx_dmav1_writel(imxdmac->ccr_to_device,
DMA_CCR(imxdmac->channel));

dev_dbg(imxdma->dev, "%s channel: %d sg=%p sgcount=%d "
"total length=%d dev_addr=0x%08x (mem2dev)\n",
__func__, imxdmac->channel, d->sg, d->sgcount,
d->len, imxdmac->per_address);
} else {
dev_err(imxdma->dev, "%s channel: %d bad dma mode\n",
__func__, imxdmac->channel);
return -EINVAL;
}

imxdma_sg_next(d, d->sg);

break;
default:
return -EINVAL;
Expand Down Expand Up @@ -641,11 +614,10 @@ static int imxdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
imxdmac->internal.hw_chaining = 1;
if (!imxdma_hw_chain(&imxdmac->internal))
return -EINVAL;
imxdmac->internal.ccr_from_device =
(mode | IMX_DMA_TYPE_FIFO) |
imxdmac->ccr_from_device = (mode | IMX_DMA_TYPE_FIFO) |
((IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) << 2) |
CCR_REN;
imxdmac->internal.ccr_to_device =
imxdmac->ccr_to_device =
(IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR) |
((mode | IMX_DMA_TYPE_FIFO) << 2) | CCR_REN;
imx_dmav1_writel(imxdmac->dma_request,
Expand Down

0 comments on commit 0ff44f9

Please sign in to comment.