linux-mtd.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support
@ 2020-09-24  8:12 Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 1/4] mtd: hyperbus: Provide per device private pointer Vignesh Raghavendra
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Vignesh Raghavendra @ 2020-09-24  8:12 UTC (permalink / raw)
  To: Vignesh Raghavendra
  Cc: Peter Ujfalusi, Richard Weinberger, linux-mtd, linux-kernel,
	Miquel Raynal

This series add DMA support for reading data from HyperBus memory
devices for TI's AM654/J721e SoCs

With DMA there is ~5x improvement in read througput.

v2:
Fix DMAengine APIs usage issues pointed out by Peter.

Vignesh Raghavendra (4):
  mtd: hyperbus: Provide per device private pointer
  mtd: hyperbus: hbmc-am654: Fix direct mapping setup flash access
  mtd: hyperbus: hbmc-am654: Drop pm_runtime* calls from probe
  mtd: hyperbus: hbmc-am654: Add DMA support for reads

 drivers/mtd/hyperbus/hbmc-am654.c | 144 ++++++++++++++++++++++++++----
 include/linux/mtd/hyperbus.h      |   2 +
 2 files changed, 130 insertions(+), 16 deletions(-)

-- 
2.28.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/4] mtd: hyperbus: Provide per device private pointer
  2020-09-24  8:12 [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
@ 2020-09-24  8:12 ` Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 2/4] mtd: hyperbus: hbmc-am654: Fix direct mapping setup flash access Vignesh Raghavendra
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Vignesh Raghavendra @ 2020-09-24  8:12 UTC (permalink / raw)
  To: Vignesh Raghavendra
  Cc: Peter Ujfalusi, Richard Weinberger, linux-mtd, linux-kernel,
	Miquel Raynal

Provide per device private pointer that can be used by controller
drivers to store device specific private data.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 include/linux/mtd/hyperbus.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/mtd/hyperbus.h b/include/linux/mtd/hyperbus.h
index 2129f7d3b6eb..d8cb1aec826d 100644
--- a/include/linux/mtd/hyperbus.h
+++ b/include/linux/mtd/hyperbus.h
@@ -20,6 +20,7 @@ enum hyperbus_memtype {
  * @mtd: pointer to MTD struct
  * @ctlr: pointer to HyperBus controller struct
  * @memtype: type of memory device: HyperFlash or HyperRAM
+ * @priv: pointer to controller specific per device private data
  */
 
 struct hyperbus_device {
@@ -28,6 +29,7 @@ struct hyperbus_device {
 	struct mtd_info *mtd;
 	struct hyperbus_ctlr *ctlr;
 	enum hyperbus_memtype memtype;
+	void *priv;
 };
 
 /**
-- 
2.28.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/4] mtd: hyperbus: hbmc-am654: Fix direct mapping setup flash access
  2020-09-24  8:12 [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 1/4] mtd: hyperbus: Provide per device private pointer Vignesh Raghavendra
@ 2020-09-24  8:12 ` Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 3/4] mtd: hyperbus: hbmc-am654: Drop pm_runtime* calls from probe Vignesh Raghavendra
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Vignesh Raghavendra @ 2020-09-24  8:12 UTC (permalink / raw)
  To: Vignesh Raghavendra
  Cc: Peter Ujfalusi, Richard Weinberger, linux-mtd, linux-kernel,
	Miquel Raynal

Setting up of direct mapping should be done with flash node's IO
address space and not with controller's IO region.

Fixes: b6fe8bc67d2d3 ("mtd: hyperbus: move direct mapping setup to AM654 HBMC driver")
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/hyperbus/hbmc-am654.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c
index e0e33f6bf513..1e70ecfffa39 100644
--- a/drivers/mtd/hyperbus/hbmc-am654.c
+++ b/drivers/mtd/hyperbus/hbmc-am654.c
@@ -70,7 +70,8 @@ static int am654_hbmc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	ret = of_address_to_resource(np, 0, &res);
+	priv->hbdev.np = of_get_next_child(np, NULL);
+	ret = of_address_to_resource(priv->hbdev.np, 0, &res);
 	if (ret)
 		return ret;
 
@@ -103,7 +104,6 @@ static int am654_hbmc_probe(struct platform_device *pdev)
 	priv->ctlr.dev = dev;
 	priv->ctlr.ops = &am654_hbmc_ops;
 	priv->hbdev.ctlr = &priv->ctlr;
-	priv->hbdev.np = of_get_next_child(dev->of_node, NULL);
 	ret = hyperbus_register_device(&priv->hbdev);
 	if (ret) {
 		dev_err(dev, "failed to register controller\n");
-- 
2.28.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/4] mtd: hyperbus: hbmc-am654: Drop pm_runtime* calls from probe
  2020-09-24  8:12 [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 1/4] mtd: hyperbus: Provide per device private pointer Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 2/4] mtd: hyperbus: hbmc-am654: Fix direct mapping setup flash access Vignesh Raghavendra
@ 2020-09-24  8:12 ` Vignesh Raghavendra
  2020-09-24  8:12 ` [PATCH v2 4/4] mtd: hyperbus: hbmc-am654: Add DMA support for reads Vignesh Raghavendra
  2020-09-30  8:27 ` [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
  4 siblings, 0 replies; 6+ messages in thread
From: Vignesh Raghavendra @ 2020-09-24  8:12 UTC (permalink / raw)
  To: Vignesh Raghavendra
  Cc: Peter Ujfalusi, Richard Weinberger, linux-mtd, linux-kernel,
	Miquel Raynal

Recent genpd changes for K3 platform ensure device is ON before driver
probe is called. Therefore, drop redundant pm_runtime_* calls from
driver to simplify the code.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/hyperbus/hbmc-am654.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c
index 1e70ecfffa39..b6a2400fcaa9 100644
--- a/drivers/mtd/hyperbus/hbmc-am654.c
+++ b/drivers/mtd/hyperbus/hbmc-am654.c
@@ -13,7 +13,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
 #include <linux/types.h>
 
 #define AM654_HBMC_CALIB_COUNT 25
@@ -89,13 +88,6 @@ static int am654_hbmc_probe(struct platform_device *pdev)
 		priv->mux_ctrl = control;
 	}
 
-	pm_runtime_enable(dev);
-	ret = pm_runtime_get_sync(dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(dev);
-		goto disable_pm;
-	}
-
 	priv->hbdev.map.size = resource_size(&res);
 	priv->hbdev.map.virt = devm_ioremap_resource(dev, &res);
 	if (IS_ERR(priv->hbdev.map.virt))
@@ -107,13 +99,11 @@ static int am654_hbmc_probe(struct platform_device *pdev)
 	ret = hyperbus_register_device(&priv->hbdev);
 	if (ret) {
 		dev_err(dev, "failed to register controller\n");
-		pm_runtime_put_sync(&pdev->dev);
-		goto disable_pm;
+		goto disable_mux;
 	}
 
 	return 0;
-disable_pm:
-	pm_runtime_disable(dev);
+disable_mux:
 	if (priv->mux_ctrl)
 		mux_control_deselect(priv->mux_ctrl);
 	return ret;
@@ -127,8 +117,6 @@ static int am654_hbmc_remove(struct platform_device *pdev)
 	ret = hyperbus_unregister_device(&priv->hbdev);
 	if (priv->mux_ctrl)
 		mux_control_deselect(priv->mux_ctrl);
-	pm_runtime_put_sync(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
 
 	return ret;
 }
-- 
2.28.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/4] mtd: hyperbus: hbmc-am654: Add DMA support for reads
  2020-09-24  8:12 [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
                   ` (2 preceding siblings ...)
  2020-09-24  8:12 ` [PATCH v2 3/4] mtd: hyperbus: hbmc-am654: Drop pm_runtime* calls from probe Vignesh Raghavendra
@ 2020-09-24  8:12 ` Vignesh Raghavendra
  2020-09-30  8:27 ` [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
  4 siblings, 0 replies; 6+ messages in thread
From: Vignesh Raghavendra @ 2020-09-24  8:12 UTC (permalink / raw)
  To: Vignesh Raghavendra
  Cc: Peter Ujfalusi, Richard Weinberger, linux-mtd, linux-kernel,
	Miquel Raynal

AM654 HyperBus controller provides MMIO interface to read data from
flash. So add DMA memcpy support for reading data over MMIO interface.
This provides 5x improvement in throughput and reduces CPU usage as
well.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/mtd/hyperbus/hbmc-am654.c | 126 +++++++++++++++++++++++++++++-
 1 file changed, 125 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/hyperbus/hbmc-am654.c b/drivers/mtd/hyperbus/hbmc-am654.c
index b6a2400fcaa9..a3439b791eeb 100644
--- a/drivers/mtd/hyperbus/hbmc-am654.c
+++ b/drivers/mtd/hyperbus/hbmc-am654.c
@@ -3,6 +3,10 @@
 // Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com/
 // Author: Vignesh Raghavendra <vigneshr@ti.com>
 
+#include <linux/completion.h>
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -13,10 +17,18 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/sched/task_stack.h>
 #include <linux/types.h>
 
 #define AM654_HBMC_CALIB_COUNT 25
 
+struct am654_hbmc_device_priv {
+	struct completion rx_dma_complete;
+	phys_addr_t device_base;
+	struct hyperbus_ctlr *ctlr;
+	struct dma_chan *rx_chan;
+};
+
 struct am654_hbmc_priv {
 	struct hyperbus_ctlr ctlr;
 	struct hyperbus_device hbdev;
@@ -51,13 +63,103 @@ static int am654_hbmc_calibrate(struct hyperbus_device *hbdev)
 	return ret;
 }
 
+static void am654_hbmc_dma_callback(void *param)
+{
+	struct am654_hbmc_device_priv *priv = param;
+
+	complete(&priv->rx_dma_complete);
+}
+
+static int am654_hbmc_dma_read(struct am654_hbmc_device_priv *priv, void *to,
+			       unsigned long from, ssize_t len)
+
+{
+	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+	struct dma_chan *rx_chan = priv->rx_chan;
+	struct dma_async_tx_descriptor *tx;
+	dma_addr_t dma_dst, dma_src;
+	dma_cookie_t cookie;
+	int ret;
+
+	if (!priv->rx_chan || !virt_addr_valid(to) || object_is_on_stack(to))
+		return -EINVAL;
+
+	dma_dst = dma_map_single(rx_chan->device->dev, to, len, DMA_FROM_DEVICE);
+	if (dma_mapping_error(rx_chan->device->dev, dma_dst)) {
+		dev_dbg(priv->ctlr->dev, "DMA mapping failed\n");
+		return -EIO;
+	}
+
+	dma_src = priv->device_base + from;
+	tx = dmaengine_prep_dma_memcpy(rx_chan, dma_dst, dma_src, len, flags);
+	if (!tx) {
+		dev_err(priv->ctlr->dev, "device_prep_dma_memcpy error\n");
+		ret = -EIO;
+		goto unmap_dma;
+	}
+
+	reinit_completion(&priv->rx_dma_complete);
+	tx->callback = am654_hbmc_dma_callback;
+	tx->callback_param = priv;
+	cookie = dmaengine_submit(tx);
+
+	ret = dma_submit_error(cookie);
+	if (ret) {
+		dev_err(priv->ctlr->dev, "dma_submit_error %d\n", cookie);
+		goto unmap_dma;
+	}
+
+	dma_async_issue_pending(rx_chan);
+	if (!wait_for_completion_timeout(&priv->rx_dma_complete,  msecs_to_jiffies(len + 1000))) {
+		dmaengine_terminate_sync(rx_chan);
+		dev_err(priv->ctlr->dev, "DMA wait_for_completion_timeout\n");
+		ret = -ETIMEDOUT;
+	}
+
+unmap_dma:
+	dma_unmap_single(rx_chan->device->dev, dma_dst, len, DMA_FROM_DEVICE);
+	return ret;
+}
+
+static void am654_hbmc_read(struct hyperbus_device *hbdev, void *to,
+			    unsigned long from, ssize_t len)
+{
+	struct am654_hbmc_device_priv *priv = hbdev->priv;
+
+	if (len < SZ_1K || am654_hbmc_dma_read(priv, to, from, len))
+		memcpy_fromio(to, hbdev->map.virt + from, len);
+}
+
 static const struct hyperbus_ops am654_hbmc_ops = {
 	.calibrate = am654_hbmc_calibrate,
+	.copy_from = am654_hbmc_read,
 };
 
+static int am654_hbmc_request_mmap_dma(struct am654_hbmc_device_priv *priv)
+{
+	struct dma_chan *rx_chan;
+	dma_cap_mask_t mask;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
+
+	rx_chan = dma_request_chan_by_mask(&mask);
+	if (IS_ERR(rx_chan)) {
+		if (PTR_ERR(rx_chan) == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_dbg(priv->ctlr->dev, "No DMA channel available\n");
+		return 0;
+	}
+	priv->rx_chan = rx_chan;
+	init_completion(&priv->rx_dma_complete);
+
+	return 0;
+}
+
 static int am654_hbmc_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct am654_hbmc_device_priv *dev_priv;
 	struct device *dev = &pdev->dev;
 	struct am654_hbmc_priv *priv;
 	struct resource res;
@@ -96,13 +198,31 @@ static int am654_hbmc_probe(struct platform_device *pdev)
 	priv->ctlr.dev = dev;
 	priv->ctlr.ops = &am654_hbmc_ops;
 	priv->hbdev.ctlr = &priv->ctlr;
+
+	dev_priv = devm_kzalloc(dev, sizeof(*dev_priv), GFP_KERNEL);
+	if (!dev_priv) {
+		ret = -ENOMEM;
+		goto disable_mux;
+	}
+
+	priv->hbdev.priv = dev_priv;
+	dev_priv->device_base = res.start;
+	dev_priv->ctlr = &priv->ctlr;
+
+	ret = am654_hbmc_request_mmap_dma(dev_priv);
+	if (ret)
+		goto disable_mux;
+
 	ret = hyperbus_register_device(&priv->hbdev);
 	if (ret) {
 		dev_err(dev, "failed to register controller\n");
-		goto disable_mux;
+		goto release_dma;
 	}
 
 	return 0;
+release_dma:
+	if (dev_priv->rx_chan)
+		dma_release_channel(dev_priv->rx_chan);
 disable_mux:
 	if (priv->mux_ctrl)
 		mux_control_deselect(priv->mux_ctrl);
@@ -112,12 +232,16 @@ static int am654_hbmc_probe(struct platform_device *pdev)
 static int am654_hbmc_remove(struct platform_device *pdev)
 {
 	struct am654_hbmc_priv *priv = platform_get_drvdata(pdev);
+	struct am654_hbmc_device_priv *dev_priv = priv->hbdev.priv;
 	int ret;
 
 	ret = hyperbus_unregister_device(&priv->hbdev);
 	if (priv->mux_ctrl)
 		mux_control_deselect(priv->mux_ctrl);
 
+	if (dev_priv->rx_chan)
+		dma_release_channel(dev_priv->rx_chan);
+
 	return ret;
 }
 
-- 
2.28.0


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support
  2020-09-24  8:12 [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
                   ` (3 preceding siblings ...)
  2020-09-24  8:12 ` [PATCH v2 4/4] mtd: hyperbus: hbmc-am654: Add DMA support for reads Vignesh Raghavendra
@ 2020-09-30  8:27 ` Vignesh Raghavendra
  4 siblings, 0 replies; 6+ messages in thread
From: Vignesh Raghavendra @ 2020-09-30  8:27 UTC (permalink / raw)
  To: Vignesh Raghavendra
  Cc: Peter Ujfalusi, Richard Weinberger, linux-mtd, linux-kernel,
	Miquel Raynal

On Thu, 24 Sep 2020 13:42:10 +0530, Vignesh Raghavendra wrote:
> This series add DMA support for reading data from HyperBus memory
> devices for TI's AM654/J721e SoCs
> 
> With DMA there is ~5x improvement in read througput.
> 
> v2:
> Fix DMAengine APIs usage issues pointed out by Peter.
> 
> [...]

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git cfi/next, thanks!
[1/4] mtd: hyperbus: Provide per device private pointer
      https://git.kernel.org/mtd/c/714fb2fbe7
[2/4] mtd: hyperbus: hbmc-am654: Fix direct mapping setup flash access
      https://git.kernel.org/mtd/c/aca31ce968
[3/4] mtd: hyperbus: hbmc-am654: Drop pm_runtime* calls from probe
      https://git.kernel.org/mtd/c/992df3bb35
[4/4] mtd: hyperbus: hbmc-am654: Add DMA support for reads
      https://git.kernel.org/mtd/c/00c9cf49a6

--
Regards
Vignesh


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2020-09-30  8:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-24  8:12 [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra
2020-09-24  8:12 ` [PATCH v2 1/4] mtd: hyperbus: Provide per device private pointer Vignesh Raghavendra
2020-09-24  8:12 ` [PATCH v2 2/4] mtd: hyperbus: hbmc-am654: Fix direct mapping setup flash access Vignesh Raghavendra
2020-09-24  8:12 ` [PATCH v2 3/4] mtd: hyperbus: hbmc-am654: Drop pm_runtime* calls from probe Vignesh Raghavendra
2020-09-24  8:12 ` [PATCH v2 4/4] mtd: hyperbus: hbmc-am654: Add DMA support for reads Vignesh Raghavendra
2020-09-30  8:27 ` [PATCH v2 0/4] mtd: hyperbus: hbmc-am654: Add DMA support Vignesh Raghavendra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).