Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bab1c6a authored by Robert Jarzmik's avatar Robert Jarzmik
Browse files

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: e87ffbdf ("dmaengine: pxa_dma: fix the no-requestor case")
Signed-off-by: default avatarRobert Jarzmik <robert.jarzmik@free.fr>
Acked-by: default avatarVinod Koul <vinod.koul@intel.com>
parent 72b195cb
Loading
Loading
Loading
Loading
+28 −11
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ struct pxad_chan {
struct pxad_device {
	struct dma_device		slave;
	int				nr_chans;
	int				nr_requestors;
	void __iomem			*base;
	struct pxad_phy			*phys;
	spinlock_t			phy_lock;	/* Phy association */
@@ -473,7 +474,7 @@ static void pxad_free_phy(struct pxad_chan *chan)
		return;

	/* clear the channel mapping in DRCMR */
	if (chan->drcmr <= DRCMR_CHLNUM) {
	if (chan->drcmr <= pdev->nr_requestors) {
		reg = pxad_drcmr(chan->drcmr);
		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)
{
	struct pxad_device *pdev;
	u32 reg, dalgn;

	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__,
		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);
		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;
	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
	struct pxad_device *pdev = to_pxad_dev(chan->vc.chan.device);

	*dcmd = 0;
	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_src = dev_addr;
		*dcmd |= PXA_DCMD_INCTRGADDR;
		if (chan->drcmr <= DRCMR_CHLNUM)
		if (chan->drcmr <= pdev->nr_requestors)
			*dcmd |= PXA_DCMD_FLOWSRC;
	}
	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_dst = dev_addr;
		*dcmd |= PXA_DCMD_INCSRCADDR;
		if (chan->drcmr <= DRCMR_CHLNUM)
		if (chan->drcmr <= pdev->nr_requestors)
			*dcmd |= PXA_DCMD_FLOWTRG;
	}
	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,
			    struct pxad_device *pdev,
			    unsigned int nr_phy_chans)
			    unsigned int nr_phy_chans,
			    unsigned int nr_requestors)
{
	int ret;
	unsigned int i;
	struct pxad_chan *c;

	pdev->nr_chans = nr_phy_chans;
	pdev->nr_requestors = nr_requestors;
	INIT_LIST_HEAD(&pdev->slave.channels);
	pdev->slave.device_alloc_chan_resources = pxad_alloc_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;
	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
	struct resource *iores;
	int ret, dma_channels = 0;
	int ret, dma_channels = 0, nb_requestors = 0;
	const enum dma_slave_buswidth widths =
		DMA_SLAVE_BUSWIDTH_1_BYTE   | DMA_SLAVE_BUSWIDTH_2_BYTES |
		DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -1393,13 +1399,23 @@ static int pxad_probe(struct platform_device *op)
		return PTR_ERR(pdev->base);

	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",
				     &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;
	else
		nb_requestors = pdata->nb_requestors;
	} else {
		dma_channels = 32;	/* default 32 channel */
	}

	dma_cap_set(DMA_SLAVE, 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.dev = &op->dev;
	ret = pxad_init_dmadev(op, pdev, dma_channels);
	ret = pxad_init_dmadev(op, pdev, dma_channels, nb_requestors);
	if (ret) {
		dev_err(pdev->slave.dev, "unable to register\n");
		return ret;
@@ -1436,7 +1452,8 @@ static int pxad_probe(struct platform_device *op)

	platform_set_drvdata(op, 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;
}