[PATCH 0/4] Fix pxa dma requestor lines

STALE3820d

7 messages, 3 authors, 2016-02-15 · open the first message on its own page

[PATCH 0/4] Fix pxa dma requestor lines

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: 2016-02-11 21:23:46

This serie aims at fixing a bug which arose in the pxa_dma driver, which needs
to know the number of requestor lines which are connected to the DMA IP.

The current implementation of pxa_dma is limited to 32 lines, which pxa27x has
75 lines and pxa3xx has 100 of them. As a consequence, DMA clients with a
requestor greater that 32 are not working, namely the pxa_camera driver.

The proposed fix by Vinod is to make the driver aware of the number of lines,
which is done by this patchset.

I'd like to have this reviewed and then taken through the PXA tree. For this
I'll need :
 - Rob/Grant/Kumar/Ian ack on patch 1/4
 - Haojian's ack on patch 2/4
 - Vinod's ack on patch 4/4

Thanks in advance.

--
Robert

Robert Jarzmik (4):
  dma: mmp_pdma: Add the #requestors DT property documentation
  dmaengine: mmp-pdma: add number of requestors
  ARM: pxa: add the number of DMA requestor lines
  dmaengine: pxa_dma: fix the maximum requestor line

 Documentation/devicetree/bindings/dma/mmp-dma.txt |  2 ++
 arch/arm/boot/dts/pxa27x.dtsi                     |  1 +
 arch/arm/boot/dts/pxa3xx.dtsi                     |  1 +
 arch/arm/mach-pxa/devices.c                       |  3 ++-
 arch/arm/mach-pxa/pxa25x.c                        |  2 +-
 arch/arm/mach-pxa/pxa27x.c                        |  2 +-
 arch/arm/mach-pxa/pxa3xx.c                        |  2 +-
 arch/arm/plat-pxa/include/plat/dma.h              |  2 +-
 drivers/dma/pxa_dma.c                             | 33 +++++++++++++++--------
 include/linux/platform_data/mmp_dma.h             |  1 +
 10 files changed, 33 insertions(+), 16 deletions(-)

-- 
2.1.4

[PATCH 2/4] dmaengine: mmp-pdma: add number of requestors

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: 2016-02-11 21:23:43

The DMA chip has a fixed number of requestor lines used for flow
control. This number is platform dependent. The pxa_dma dma driver will
use this value to activate or not the flow control.

There won't be any impact on mmp_pdma driver.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 include/linux/platform_data/mmp_dma.h | 1 +
 1 file changed, 1 insertion(+)
diff --git a/include/linux/platform_data/mmp_dma.h b/include/linux/platform_data/mmp_dma.h
index 2a330ec9e2af..d1397c8ed94e 100644
--- a/include/linux/platform_data/mmp_dma.h
+++ b/include/linux/platform_data/mmp_dma.h
@@ -14,6 +14,7 @@
 
 struct mmp_dma_platdata {
 	int dma_channels;
+	int nb_requestors;
 };
 
 #endif /* MMP_DMA_H */
-- 
2.1.4

[PATCH 1/4] dma: mmp_pdma: Add the #requestors DT property documentation

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: 2016-02-11 21:23:45

For pxa based platforms, the number of requestor lines should be
specified, so that the driver can check if the flow control should be
activated (when a requestor line is asked for) or not.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 Documentation/devicetree/bindings/dma/mmp-dma.txt | 2 ++
 1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/dma/mmp-dma.txt b/Documentation/devicetree/bindings/dma/mmp-dma.txt
index 7a802f64e5bd..716b70338a15 100644
--- a/Documentation/devicetree/bindings/dma/mmp-dma.txt
+++ b/Documentation/devicetree/bindings/dma/mmp-dma.txt
@@ -12,6 +12,8 @@ Required properties:
 Optional properties:
 - #dma-channels: Number of DMA channels supported by the controller (defaults
   to 32 when not specified)
+- #requestors: Number of DMA requestor lines supported by the controller
+  (defaults to 0 when not specified)
 
 "marvell,pdma-1.0"
 Used platforms: pxa25x, pxa27x, pxa3xx, pxa93x, pxa168, pxa910, pxa688.
-- 
2.1.4

Re: [PATCH 1/4] dma: mmp_pdma: Add the #requestors DT property documentation

From: Arnd Bergmann <arnd@arndb.de>
Date: 2016-02-11 22:00:44

On Thursday 11 February 2016 22:23:15 Robert Jarzmik wrote:
quoted hunk
@@ -12,6 +12,8 @@ Required properties:
 Optional properties:
 - #dma-channels: Number of DMA channels supported by the controller (defaults
   to 32 when not specified)
+- #requestors: Number of DMA requestor lines supported by the controller
+  (defaults to 0 when not specified)
 
Most other ones use "#dma-requests" as the property name here, I think it makes
sense to stay with that convention.

	Arnd

[PATCH 4/4] dmaengine: pxa_dma: fix the maximum requestor line

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: 2016-02-11 21:24:30

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: e87ffbdf0697 ("dmaengine: pxa_dma: fix the no-requestor case")
Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 drivers/dma/pxa_dma.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
index ca6c088edc8a..bc51d6271373 100644
--- a/drivers/dma/pxa_dma.c
+++ b/drivers/dma/pxa_dma.c
@@ -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);
 	}
@@ -914,6 +917,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) {
@@ -922,7 +926,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) {
@@ -931,7 +935,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)
@@ -1341,13 +1345,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;
@@ -1382,7 +1388,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;
@@ -1399,13 +1405,17 @@ 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)
+		of_property_read_u32(op->dev.of_node, "#requestors",
+				     &nb_requestors);
+	} 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);
@@ -1423,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;
@@ -1442,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;
 }
 
-- 
2.1.4

Re: [PATCH 4/4] dmaengine: pxa_dma: fix the maximum requestor line

From: Vinod Koul <hidden>
Date: 2016-02-15 16:31:39

On Thu, Feb 11, 2016 at 10:23:18PM +0100, Robert Jarzmik wrote:
quoted hunk
@@ -1399,13 +1405,17 @@ 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)
+		of_property_read_u32(op->dev.of_node, "#requestors",
+				     &nb_requestors);
I think we should check the return value here. This might be err in case
when we have older DT on platform, but still should work with default in
that case
+	} else if (pdata && pdata->dma_channels) {
 		dma_channels = pdata->dma_channels;
-	else
+		nb_requestors = pdata->nb_requestors;
+	} else {
 		dma_channels = 32;	/* default 32 channel */
+	}
-- 
~Vinod

[PATCH 3/4] ARM: pxa: add the number of DMA requestor lines

From: Robert Jarzmik <robert.jarzmik@free.fr>
Date: 2016-02-11 21:31:14

Declare the number of DMA requestor lines per platform :
 - for pxa25x: 40 requestor lines
 - for pxa27x: 75 requestor lines
 - for pxa3xx: 100 requestor lines

This information will be used to activate the DMA flow control or not.

Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
---
 arch/arm/boot/dts/pxa27x.dtsi        | 1 +
 arch/arm/boot/dts/pxa3xx.dtsi        | 1 +
 arch/arm/mach-pxa/devices.c          | 3 ++-
 arch/arm/mach-pxa/pxa25x.c           | 2 +-
 arch/arm/mach-pxa/pxa27x.c           | 2 +-
 arch/arm/mach-pxa/pxa3xx.c           | 2 +-
 arch/arm/plat-pxa/include/plat/dma.h | 2 +-
 7 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/pxa27x.dtsi b/arch/arm/boot/dts/pxa27x.dtsi
index ef366b204c89..1f5bdfd8f9e0 100644
--- a/arch/arm/boot/dts/pxa27x.dtsi
+++ b/arch/arm/boot/dts/pxa27x.dtsi
@@ -13,6 +13,7 @@
 			interrupts = <25>;
 			#dma-channels = <32>;
 			#dma-cells = <2>;
+			#requestors = <75>;
 			status = "okay";
 		};
 
diff --git a/arch/arm/boot/dts/pxa3xx.dtsi b/arch/arm/boot/dts/pxa3xx.dtsi
index cf6998a0804d..d10d932d1d2b 100644
--- a/arch/arm/boot/dts/pxa3xx.dtsi
+++ b/arch/arm/boot/dts/pxa3xx.dtsi
@@ -12,6 +12,7 @@
 			interrupts = <25>;
 			#dma-channels = <32>;
 			#dma-cells = <2>;
+			#requestors = <100>;
 			status = "okay";
 		};
 
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 6e12c162506f..d9ff6e4dd854 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -1233,6 +1233,7 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info)
 
 static struct mmp_dma_platdata pxa_dma_pdata = {
 	.dma_channels	= 0,
+	.nb_requestors	= 0,
 };
 
 static struct resource pxa_dma_resource[] = {
@@ -1261,7 +1262,7 @@ static struct platform_device pxa2xx_pxa_dma = {
 	.resource	= pxa_dma_resource,
 };
 
-void __init pxa2xx_set_dmac_info(int nb_channels)
+void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors)
 {
 	pxa_dma_pdata.dma_channels = nb_channels;
 	pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata);
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index a177bf45feef..823504f48f80 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -206,7 +206,7 @@ static int __init pxa25x_init(void)
 		register_syscore_ops(&pxa_irq_syscore_ops);
 		register_syscore_ops(&pxa2xx_mfp_syscore_ops);
 
-		pxa2xx_set_dmac_info(16);
+		pxa2xx_set_dmac_info(16, 40);
 		pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info);
 		ret = platform_add_devices(pxa25x_devices,
 					   ARRAY_SIZE(pxa25x_devices));
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index 73e96270dc53..d84239c89639 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -310,7 +310,7 @@ static int __init pxa27x_init(void)
 		if (!of_have_populated_dt()) {
 			pxa_register_device(&pxa27x_device_gpio,
 					    &pxa27x_gpio_info);
-			pxa2xx_set_dmac_info(32);
+			pxa2xx_set_dmac_info(32, 75);
 			ret = platform_add_devices(devices,
 						   ARRAY_SIZE(devices));
 		}
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index a1c4c888f246..fb0adb669124 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -450,7 +450,7 @@ static int __init pxa3xx_init(void)
 		if (of_have_populated_dt())
 			return 0;
 
-		pxa2xx_set_dmac_info(32);
+		pxa2xx_set_dmac_info(32, 100);
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 		if (ret)
 			return ret;
diff --git a/arch/arm/plat-pxa/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h
index 28848b344e2d..ceba3e4184fc 100644
--- a/arch/arm/plat-pxa/include/plat/dma.h
+++ b/arch/arm/plat-pxa/include/plat/dma.h
@@ -95,6 +95,6 @@ static inline int pxad_toggle_reserved_channel(int legacy_channel)
 }
 #endif
 
-extern void __init pxa2xx_set_dmac_info(int nb_channels);
+extern void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors);
 
 #endif /* __PLAT_DMA_H */
-- 
2.1.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help