dmaengine: pxa_dma: fix the maximum requestor line
The current number of requestor lines is limited to 31. This was an
error of a previous commit, as this number is platform dependent, and is
actually :
- for pxa25x: 40 requestor lines
- for pxa27x: 75 requestor lines
- for pxa3xx: 100 requestor lines
The previous testing did not reveal the faulty constant as on pxa[23]xx
platforms, only camera, MSL and USB are above requestor 32, and in these
only the camera has a driver using dma.
Fixes: e87ffbdf06
("dmaengine: pxa_dma: fix the no-requestor case")
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
Acked-by: Vinod Koul <vinod.koul@intel.com>
This commit is contained in:
@@ -122,6 +122,7 @@ struct pxad_chan {
|
|||||||
struct pxad_device {
|
struct pxad_device {
|
||||||
struct dma_device slave;
|
struct dma_device slave;
|
||||||
int nr_chans;
|
int nr_chans;
|
||||||
|
int nr_requestors;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct pxad_phy *phys;
|
struct pxad_phy *phys;
|
||||||
spinlock_t phy_lock; /* Phy association */
|
spinlock_t phy_lock; /* Phy association */
|
||||||
@@ -473,7 +474,7 @@ static void pxad_free_phy(struct pxad_chan *chan)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* clear the channel mapping in DRCMR */
|
/* clear the channel mapping in DRCMR */
|
||||||
if (chan->drcmr <= DRCMR_CHLNUM) {
|
if (chan->drcmr <= pdev->nr_requestors) {
|
||||||
reg = pxad_drcmr(chan->drcmr);
|
reg = pxad_drcmr(chan->drcmr);
|
||||||
writel_relaxed(0, chan->phy->base + reg);
|
writel_relaxed(0, chan->phy->base + reg);
|
||||||
}
|
}
|
||||||
@@ -509,6 +510,7 @@ static bool is_running_chan_misaligned(struct pxad_chan *chan)
|
|||||||
|
|
||||||
static void phy_enable(struct pxad_phy *phy, bool misaligned)
|
static void phy_enable(struct pxad_phy *phy, bool misaligned)
|
||||||
{
|
{
|
||||||
|
struct pxad_device *pdev;
|
||||||
u32 reg, dalgn;
|
u32 reg, dalgn;
|
||||||
|
|
||||||
if (!phy->vchan)
|
if (!phy->vchan)
|
||||||
@@ -518,7 +520,8 @@ static void phy_enable(struct pxad_phy *phy, bool misaligned)
|
|||||||
"%s(); phy=%p(%d) misaligned=%d\n", __func__,
|
"%s(); phy=%p(%d) misaligned=%d\n", __func__,
|
||||||
phy, phy->idx, misaligned);
|
phy, phy->idx, misaligned);
|
||||||
|
|
||||||
if (phy->vchan->drcmr <= DRCMR_CHLNUM) {
|
pdev = to_pxad_dev(phy->vchan->vc.chan.device);
|
||||||
|
if (phy->vchan->drcmr <= pdev->nr_requestors) {
|
||||||
reg = pxad_drcmr(phy->vchan->drcmr);
|
reg = pxad_drcmr(phy->vchan->drcmr);
|
||||||
writel_relaxed(DRCMR_MAPVLD | phy->idx, phy->base + reg);
|
writel_relaxed(DRCMR_MAPVLD | phy->idx, phy->base + reg);
|
||||||
}
|
}
|
||||||
@@ -908,6 +911,7 @@ static void pxad_get_config(struct pxad_chan *chan,
|
|||||||
{
|
{
|
||||||
u32 maxburst = 0, dev_addr = 0;
|
u32 maxburst = 0, dev_addr = 0;
|
||||||
enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
|
enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
|
||||||
|
struct pxad_device *pdev = to_pxad_dev(chan->vc.chan.device);
|
||||||
|
|
||||||
*dcmd = 0;
|
*dcmd = 0;
|
||||||
if (dir == DMA_DEV_TO_MEM) {
|
if (dir == DMA_DEV_TO_MEM) {
|
||||||
@@ -916,7 +920,7 @@ static void pxad_get_config(struct pxad_chan *chan,
|
|||||||
dev_addr = chan->cfg.src_addr;
|
dev_addr = chan->cfg.src_addr;
|
||||||
*dev_src = dev_addr;
|
*dev_src = dev_addr;
|
||||||
*dcmd |= PXA_DCMD_INCTRGADDR;
|
*dcmd |= PXA_DCMD_INCTRGADDR;
|
||||||
if (chan->drcmr <= DRCMR_CHLNUM)
|
if (chan->drcmr <= pdev->nr_requestors)
|
||||||
*dcmd |= PXA_DCMD_FLOWSRC;
|
*dcmd |= PXA_DCMD_FLOWSRC;
|
||||||
}
|
}
|
||||||
if (dir == DMA_MEM_TO_DEV) {
|
if (dir == DMA_MEM_TO_DEV) {
|
||||||
@@ -925,7 +929,7 @@ static void pxad_get_config(struct pxad_chan *chan,
|
|||||||
dev_addr = chan->cfg.dst_addr;
|
dev_addr = chan->cfg.dst_addr;
|
||||||
*dev_dst = dev_addr;
|
*dev_dst = dev_addr;
|
||||||
*dcmd |= PXA_DCMD_INCSRCADDR;
|
*dcmd |= PXA_DCMD_INCSRCADDR;
|
||||||
if (chan->drcmr <= DRCMR_CHLNUM)
|
if (chan->drcmr <= pdev->nr_requestors)
|
||||||
*dcmd |= PXA_DCMD_FLOWTRG;
|
*dcmd |= PXA_DCMD_FLOWTRG;
|
||||||
}
|
}
|
||||||
if (dir == DMA_MEM_TO_MEM)
|
if (dir == DMA_MEM_TO_MEM)
|
||||||
@@ -1335,13 +1339,15 @@ static struct dma_chan *pxad_dma_xlate(struct of_phandle_args *dma_spec,
|
|||||||
|
|
||||||
static int pxad_init_dmadev(struct platform_device *op,
|
static int pxad_init_dmadev(struct platform_device *op,
|
||||||
struct pxad_device *pdev,
|
struct pxad_device *pdev,
|
||||||
unsigned int nr_phy_chans)
|
unsigned int nr_phy_chans,
|
||||||
|
unsigned int nr_requestors)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct pxad_chan *c;
|
struct pxad_chan *c;
|
||||||
|
|
||||||
pdev->nr_chans = nr_phy_chans;
|
pdev->nr_chans = nr_phy_chans;
|
||||||
|
pdev->nr_requestors = nr_requestors;
|
||||||
INIT_LIST_HEAD(&pdev->slave.channels);
|
INIT_LIST_HEAD(&pdev->slave.channels);
|
||||||
pdev->slave.device_alloc_chan_resources = pxad_alloc_chan_resources;
|
pdev->slave.device_alloc_chan_resources = pxad_alloc_chan_resources;
|
||||||
pdev->slave.device_free_chan_resources = pxad_free_chan_resources;
|
pdev->slave.device_free_chan_resources = pxad_free_chan_resources;
|
||||||
@@ -1376,7 +1382,7 @@ static int pxad_probe(struct platform_device *op)
|
|||||||
const struct of_device_id *of_id;
|
const struct of_device_id *of_id;
|
||||||
struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
|
struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
|
||||||
struct resource *iores;
|
struct resource *iores;
|
||||||
int ret, dma_channels = 0;
|
int ret, dma_channels = 0, nb_requestors = 0;
|
||||||
const enum dma_slave_buswidth widths =
|
const enum dma_slave_buswidth widths =
|
||||||
DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES |
|
DMA_SLAVE_BUSWIDTH_1_BYTE | DMA_SLAVE_BUSWIDTH_2_BYTES |
|
||||||
DMA_SLAVE_BUSWIDTH_4_BYTES;
|
DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||||
@@ -1393,13 +1399,23 @@ static int pxad_probe(struct platform_device *op)
|
|||||||
return PTR_ERR(pdev->base);
|
return PTR_ERR(pdev->base);
|
||||||
|
|
||||||
of_id = of_match_device(pxad_dt_ids, &op->dev);
|
of_id = of_match_device(pxad_dt_ids, &op->dev);
|
||||||
if (of_id)
|
if (of_id) {
|
||||||
of_property_read_u32(op->dev.of_node, "#dma-channels",
|
of_property_read_u32(op->dev.of_node, "#dma-channels",
|
||||||
&dma_channels);
|
&dma_channels);
|
||||||
else if (pdata && pdata->dma_channels)
|
ret = of_property_read_u32(op->dev.of_node, "#dma-requests",
|
||||||
|
&nb_requestors);
|
||||||
|
if (ret) {
|
||||||
|
dev_warn(pdev->slave.dev,
|
||||||
|
"#dma-requests set to default 32 as missing in OF: %d",
|
||||||
|
ret);
|
||||||
|
nb_requestors = 32;
|
||||||
|
};
|
||||||
|
} else if (pdata && pdata->dma_channels) {
|
||||||
dma_channels = pdata->dma_channels;
|
dma_channels = pdata->dma_channels;
|
||||||
else
|
nb_requestors = pdata->nb_requestors;
|
||||||
|
} else {
|
||||||
dma_channels = 32; /* default 32 channel */
|
dma_channels = 32; /* default 32 channel */
|
||||||
|
}
|
||||||
|
|
||||||
dma_cap_set(DMA_SLAVE, pdev->slave.cap_mask);
|
dma_cap_set(DMA_SLAVE, pdev->slave.cap_mask);
|
||||||
dma_cap_set(DMA_MEMCPY, pdev->slave.cap_mask);
|
dma_cap_set(DMA_MEMCPY, pdev->slave.cap_mask);
|
||||||
@@ -1417,7 +1433,7 @@ static int pxad_probe(struct platform_device *op)
|
|||||||
pdev->slave.descriptor_reuse = true;
|
pdev->slave.descriptor_reuse = true;
|
||||||
|
|
||||||
pdev->slave.dev = &op->dev;
|
pdev->slave.dev = &op->dev;
|
||||||
ret = pxad_init_dmadev(op, pdev, dma_channels);
|
ret = pxad_init_dmadev(op, pdev, dma_channels, nb_requestors);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(pdev->slave.dev, "unable to register\n");
|
dev_err(pdev->slave.dev, "unable to register\n");
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1436,7 +1452,8 @@ static int pxad_probe(struct platform_device *op)
|
|||||||
|
|
||||||
platform_set_drvdata(op, pdev);
|
platform_set_drvdata(op, pdev);
|
||||||
pxad_init_debugfs(pdev);
|
pxad_init_debugfs(pdev);
|
||||||
dev_info(pdev->slave.dev, "initialized %d channels\n", dma_channels);
|
dev_info(pdev->slave.dev, "initialized %d channels on %d requestors\n",
|
||||||
|
dma_channels, nb_requestors);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user