|
@@ -272,13 +272,13 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
|
|
|
|
|
|
bool pl330_filter(struct dma_chan *chan, void *param)
|
|
|
{
|
|
|
- struct dma_pl330_peri *peri;
|
|
|
+ u8 *peri_id;
|
|
|
|
|
|
if (chan->device->dev->driver != &pl330_driver.drv)
|
|
|
return false;
|
|
|
|
|
|
- peri = chan->private;
|
|
|
- return peri->peri_id == (unsigned)param;
|
|
|
+ peri_id = chan->private;
|
|
|
+ return *peri_id == (unsigned)param;
|
|
|
}
|
|
|
EXPORT_SYMBOL(pl330_filter);
|
|
|
|
|
@@ -512,7 +512,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
|
|
|
static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
|
|
|
{
|
|
|
struct dma_pl330_dmac *pdmac = pch->dmac;
|
|
|
- struct dma_pl330_peri *peri = pch->chan.private;
|
|
|
+ u8 *peri_id = pch->chan.private;
|
|
|
struct dma_pl330_desc *desc;
|
|
|
|
|
|
/* Pluck one desc from the pool of DMAC */
|
|
@@ -537,13 +537,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
|
|
|
desc->txd.cookie = 0;
|
|
|
async_tx_ack(&desc->txd);
|
|
|
|
|
|
- if (peri) {
|
|
|
- desc->req.rqtype = peri->rqtype;
|
|
|
- desc->req.peri = pch->chan.chan_id;
|
|
|
- } else {
|
|
|
- desc->req.rqtype = MEMTOMEM;
|
|
|
- desc->req.peri = 0;
|
|
|
- }
|
|
|
+ desc->req.peri = peri_id ? pch->chan.chan_id : 0;
|
|
|
|
|
|
dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
|
|
|
|
|
@@ -630,12 +624,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
|
|
|
case DMA_TO_DEVICE:
|
|
|
desc->rqcfg.src_inc = 1;
|
|
|
desc->rqcfg.dst_inc = 0;
|
|
|
+ desc->req.rqtype = MEMTODEV;
|
|
|
src = dma_addr;
|
|
|
dst = pch->fifo_addr;
|
|
|
break;
|
|
|
case DMA_FROM_DEVICE:
|
|
|
desc->rqcfg.src_inc = 0;
|
|
|
desc->rqcfg.dst_inc = 1;
|
|
|
+ desc->req.rqtype = DEVTOMEM;
|
|
|
src = pch->fifo_addr;
|
|
|
dst = dma_addr;
|
|
|
break;
|
|
@@ -661,16 +657,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
|
|
|
{
|
|
|
struct dma_pl330_desc *desc;
|
|
|
struct dma_pl330_chan *pch = to_pchan(chan);
|
|
|
- struct dma_pl330_peri *peri = chan->private;
|
|
|
struct pl330_info *pi;
|
|
|
int burst;
|
|
|
|
|
|
if (unlikely(!pch || !len))
|
|
|
return NULL;
|
|
|
|
|
|
- if (peri && peri->rqtype != MEMTOMEM)
|
|
|
- return NULL;
|
|
|
-
|
|
|
pi = &pch->dmac->pif;
|
|
|
|
|
|
desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
|
|
@@ -679,6 +671,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
|
|
|
|
|
|
desc->rqcfg.src_inc = 1;
|
|
|
desc->rqcfg.dst_inc = 1;
|
|
|
+ desc->req.rqtype = MEMTOMEM;
|
|
|
|
|
|
/* Select max possible burst size */
|
|
|
burst = pi->pcfg.data_bus_width / 8;
|
|
@@ -707,24 +700,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
|
|
{
|
|
|
struct dma_pl330_desc *first, *desc = NULL;
|
|
|
struct dma_pl330_chan *pch = to_pchan(chan);
|
|
|
- struct dma_pl330_peri *peri = chan->private;
|
|
|
struct scatterlist *sg;
|
|
|
unsigned long flags;
|
|
|
int i;
|
|
|
dma_addr_t addr;
|
|
|
|
|
|
- if (unlikely(!pch || !sgl || !sg_len || !peri))
|
|
|
- return NULL;
|
|
|
-
|
|
|
- /* Make sure the direction is consistent */
|
|
|
- if ((direction == DMA_TO_DEVICE &&
|
|
|
- peri->rqtype != MEMTODEV) ||
|
|
|
- (direction == DMA_FROM_DEVICE &&
|
|
|
- peri->rqtype != DEVTOMEM)) {
|
|
|
- dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
|
|
|
- __func__, __LINE__);
|
|
|
+ if (unlikely(!pch || !sgl || !sg_len))
|
|
|
return NULL;
|
|
|
- }
|
|
|
|
|
|
addr = pch->fifo_addr;
|
|
|
|
|
@@ -765,11 +747,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
|
|
|
if (direction == DMA_TO_DEVICE) {
|
|
|
desc->rqcfg.src_inc = 1;
|
|
|
desc->rqcfg.dst_inc = 0;
|
|
|
+ desc->req.rqtype = MEMTODEV;
|
|
|
fill_px(&desc->px,
|
|
|
addr, sg_dma_address(sg), sg_dma_len(sg));
|
|
|
} else {
|
|
|
desc->rqcfg.src_inc = 0;
|
|
|
desc->rqcfg.dst_inc = 1;
|
|
|
+ desc->req.rqtype = DEVTOMEM;
|
|
|
fill_px(&desc->px,
|
|
|
sg_dma_address(sg), addr, sg_dma_len(sg));
|
|
|
}
|
|
@@ -876,28 +860,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
|
|
|
|
|
|
for (i = 0; i < num_chan; i++) {
|
|
|
pch = &pdmac->peripherals[i];
|
|
|
- if (pdat) {
|
|
|
- struct dma_pl330_peri *peri = &pdat->peri[i];
|
|
|
-
|
|
|
- switch (peri->rqtype) {
|
|
|
- case MEMTOMEM:
|
|
|
- dma_cap_set(DMA_MEMCPY, pd->cap_mask);
|
|
|
- break;
|
|
|
- case MEMTODEV:
|
|
|
- case DEVTOMEM:
|
|
|
- dma_cap_set(DMA_SLAVE, pd->cap_mask);
|
|
|
- dma_cap_set(DMA_CYCLIC, pd->cap_mask);
|
|
|
- break;
|
|
|
- default:
|
|
|
- dev_err(&adev->dev, "DEVTODEV Not Supported\n");
|
|
|
- continue;
|
|
|
- }
|
|
|
- pch->chan.private = peri;
|
|
|
- } else {
|
|
|
- dma_cap_set(DMA_MEMCPY, pd->cap_mask);
|
|
|
- pch->chan.private = NULL;
|
|
|
- }
|
|
|
-
|
|
|
+ pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
|
|
|
INIT_LIST_HEAD(&pch->work_list);
|
|
|
spin_lock_init(&pch->lock);
|
|
|
pch->pl330_chid = NULL;
|
|
@@ -909,6 +872,10 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
|
|
|
}
|
|
|
|
|
|
pd->dev = &adev->dev;
|
|
|
+ if (pdat)
|
|
|
+ pd->cap_mask = pdat->cap_mask;
|
|
|
+ else
|
|
|
+ dma_cap_set(DMA_MEMCPY, pd->cap_mask);
|
|
|
|
|
|
pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
|
|
|
pd->device_free_chan_resources = pl330_free_chan_resources;
|