All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] spi-ti-qspi: Handle vmalloc'd buffers
@ 2017-04-11 11:52 ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, linux-omap, Vignesh R

First patch, adds can_dma() like interface for spi_flash_read()
interface,
this will enable controller drivers to selectively use DMA based on
buffer type, alignment, size or other limitations.
Second patch implements bounce buffer support for ti-qspi driver to
handle buffers that are not DMA'able, like vmalloc'd buffers that belong
to LPAE region. This is required to work with UBIFS.

Vignesh R (2):
  spi: Add can_dma like interface for spi_flash_read
  spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble

 drivers/spi/spi-ti-qspi.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----
 drivers/spi/spi.c         |  2 +-
 include/linux/spi/spi.h   |  4 +++
 3 files changed, 64 insertions(+), 8 deletions(-)

-- 
2.11.0

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

* [PATCH v2 0/2] spi-ti-qspi: Handle vmalloc'd buffers
@ 2017-04-11 11:52 ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, linux-omap, Vignesh R

First patch, adds can_dma() like interface for spi_flash_read()
interface,
this will enable controller drivers to selectively use DMA based on
buffer type, alignment, size or other limitations.
Second patch implements bounce buffer support for ti-qspi driver to
handle buffers that are not DMA'able, like vmalloc'd buffers that belong
to LPAE region. This is required to work with UBIFS.

Vignesh R (2):
  spi: Add can_dma like interface for spi_flash_read
  spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble

 drivers/spi/spi-ti-qspi.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----
 drivers/spi/spi.c         |  2 +-
 include/linux/spi/spi.h   |  4 +++
 3 files changed, 64 insertions(+), 8 deletions(-)

-- 
2.11.0

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

* [PATCH v2 1/2] spi: Add can_dma like interface for spi_flash_read
@ 2017-04-11 11:52   ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, linux-omap, Vignesh R

Add an interface analogous to ->can_dma() for spi_flash_read()
interface. This will enable SPI controller drivers to inform SPI core
when not to do DMA mappings.

Signed-off-by: Vignesh R <vigneshr@ti.com>
---

v2: No changes.

 drivers/spi/spi.c       | 2 +-
 include/linux/spi/spi.h | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index f699ea530b88..57b64d2128e5 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2854,7 +2854,7 @@ int spi_flash_read(struct spi_device *spi,
 
 	mutex_lock(&master->bus_lock_mutex);
 	mutex_lock(&master->io_mutex);
-	if (master->dma_rx) {
+	if (master->dma_rx && master->spi_flash_can_dma(spi, msg)) {
 		rx_dev = master->dma_rx->device->dev;
 		ret = spi_map_buf(master, rx_dev, &msg->rx_sg,
 				  msg->buf, msg->len,
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 805878d61a8f..935bd2854ff1 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -376,6 +376,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @unprepare_message: undo any work done by prepare_message().
  * @spi_flash_read: to support spi-controller hardwares that provide
  *                  accelerated interface to read from flash devices.
+ * @spi_flash_can_dma: analogous to can_dma() interface, but for
+ *		       controllers implementing spi_flash_read.
  * @flash_read_supported: spi device supports flash read
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *	number. Any individual value may be -ENOENT for CS lines that
@@ -539,6 +541,8 @@ struct spi_master {
 				 struct spi_message *message);
 	int (*spi_flash_read)(struct  spi_device *spi,
 			      struct spi_flash_read_message *msg);
+	bool (*spi_flash_can_dma)(struct spi_device *spi,
+				  struct spi_flash_read_message *msg);
 	bool (*flash_read_supported)(struct spi_device *spi);
 
 	/*
-- 
2.11.0

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

* [PATCH v2 1/2] spi: Add can_dma like interface for spi_flash_read
@ 2017-04-11 11:52   ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Vignesh R

Add an interface analogous to ->can_dma() for spi_flash_read()
interface. This will enable SPI controller drivers to inform SPI core
when not to do DMA mappings.

Signed-off-by: Vignesh R <vigneshr-l0cyMroinI0@public.gmane.org>
---

v2: No changes.

 drivers/spi/spi.c       | 2 +-
 include/linux/spi/spi.h | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index f699ea530b88..57b64d2128e5 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2854,7 +2854,7 @@ int spi_flash_read(struct spi_device *spi,
 
 	mutex_lock(&master->bus_lock_mutex);
 	mutex_lock(&master->io_mutex);
-	if (master->dma_rx) {
+	if (master->dma_rx && master->spi_flash_can_dma(spi, msg)) {
 		rx_dev = master->dma_rx->device->dev;
 		ret = spi_map_buf(master, rx_dev, &msg->rx_sg,
 				  msg->buf, msg->len,
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 805878d61a8f..935bd2854ff1 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -376,6 +376,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @unprepare_message: undo any work done by prepare_message().
  * @spi_flash_read: to support spi-controller hardwares that provide
  *                  accelerated interface to read from flash devices.
+ * @spi_flash_can_dma: analogous to can_dma() interface, but for
+ *		       controllers implementing spi_flash_read.
  * @flash_read_supported: spi device supports flash read
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *	number. Any individual value may be -ENOENT for CS lines that
@@ -539,6 +541,8 @@ struct spi_master {
 				 struct spi_message *message);
 	int (*spi_flash_read)(struct  spi_device *spi,
 			      struct spi_flash_read_message *msg);
+	bool (*spi_flash_can_dma)(struct spi_device *spi,
+				  struct spi_flash_read_message *msg);
 	bool (*flash_read_supported)(struct spi_device *spi);
 
 	/*
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 1/2] spi: Add can_dma like interface for spi_flash_read
@ 2017-04-11 11:52   ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Vignesh R

Add an interface analogous to ->can_dma() for spi_flash_read()
interface. This will enable SPI controller drivers to inform SPI core
when not to do DMA mappings.

Signed-off-by: Vignesh R <vigneshr-l0cyMroinI0@public.gmane.org>
---

v2: No changes.

 drivers/spi/spi.c       | 2 +-
 include/linux/spi/spi.h | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index f699ea530b88..57b64d2128e5 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2854,7 +2854,7 @@ int spi_flash_read(struct spi_device *spi,
 
 	mutex_lock(&master->bus_lock_mutex);
 	mutex_lock(&master->io_mutex);
-	if (master->dma_rx) {
+	if (master->dma_rx && master->spi_flash_can_dma(spi, msg)) {
 		rx_dev = master->dma_rx->device->dev;
 		ret = spi_map_buf(master, rx_dev, &msg->rx_sg,
 				  msg->buf, msg->len,
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 805878d61a8f..935bd2854ff1 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -376,6 +376,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @unprepare_message: undo any work done by prepare_message().
  * @spi_flash_read: to support spi-controller hardwares that provide
  *                  accelerated interface to read from flash devices.
+ * @spi_flash_can_dma: analogous to can_dma() interface, but for
+ *		       controllers implementing spi_flash_read.
  * @flash_read_supported: spi device supports flash read
  * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
  *	number. Any individual value may be -ENOENT for CS lines that
@@ -539,6 +541,8 @@ struct spi_master {
 				 struct spi_message *message);
 	int (*spi_flash_read)(struct  spi_device *spi,
 			      struct spi_flash_read_message *msg);
+	bool (*spi_flash_can_dma)(struct spi_device *spi,
+				  struct spi_flash_read_message *msg);
 	bool (*flash_read_supported)(struct spi_device *spi);
 
 	/*
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
  2017-04-11 11:52 ` Vignesh R
@ 2017-04-11 11:52   ` Vignesh R
  -1 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, linux-omap, Vignesh R

Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
can potentially be in memory region above 32bit addressable region(ie
buffers belonging to memory region backed by LPAE) of DMA, implement
spi_flash_can_dma() interface to inform SPI core not to map such
buffers.
When buffers are not mapped for DMA, then use a pre allocated bounce
buffer(64K = typical flash erase sector size) to read from flash and
then do a copy to actual destination buffer. This is approach is much
faster than using memcpy using CPU and also reduces CPU load.

With this patch, UBIFS read speed is ~18MB/s and CPU utilization <20% on
DRA74 Rev H EVM. Performance degradation is negligible when compared
with non bounce buffer case while using UBIFS.

Signed-off-by: Vignesh R <vigneshr@ti.com>
---

v2: Fix compiler warnings and sparse warnings reported by Kbuild bot.

 drivers/spi/spi-ti-qspi.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 7b39bc204a30..c24d9b45a27c 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -33,6 +33,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/sizes.h>
 
 #include <linux/spi/spi.h>
 
@@ -57,6 +58,8 @@ struct ti_qspi {
 	struct ti_qspi_regs     ctx_reg;
 
 	dma_addr_t		mmap_phys_base;
+	dma_addr_t		rx_bb_dma_addr;
+	void			*rx_bb_addr;
 	struct dma_chan		*rx_chan;
 
 	u32 spi_max_frequency;
@@ -126,6 +129,8 @@ struct ti_qspi {
 #define QSPI_SETUP_ADDR_SHIFT		8
 #define QSPI_SETUP_DUMMY_SHIFT		10
 
+#define QSPI_DMA_BUFFER_SIZE            SZ_64K
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
 		unsigned long reg)
 {
@@ -429,6 +434,35 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst,
 	return 0;
 }
 
+static int ti_qspi_dma_bounce_buffer(struct ti_qspi *qspi,
+				     struct spi_flash_read_message *msg)
+{
+	size_t readsize = msg->len;
+	void *to = msg->buf;
+	dma_addr_t dma_src = qspi->mmap_phys_base + msg->from;
+	int ret = 0;
+
+	/*
+	 * Use bounce buffer as FS like jffs2, ubifs may pass
+	 * buffers that does not belong to kernel lowmem region.
+	 */
+	while (readsize != 0) {
+		size_t xfer_len = min_t(size_t, QSPI_DMA_BUFFER_SIZE,
+					readsize);
+
+		ret = ti_qspi_dma_xfer(qspi, qspi->rx_bb_dma_addr,
+				       dma_src, xfer_len);
+		if (ret != 0)
+			return ret;
+		memcpy(to, qspi->rx_bb_addr, xfer_len);
+		readsize -= xfer_len;
+		dma_src += xfer_len;
+		to += xfer_len;
+	}
+
+	return ret;
+}
+
 static int ti_qspi_dma_xfer_sg(struct ti_qspi *qspi, struct sg_table rx_sg,
 			       loff_t from)
 {
@@ -496,6 +530,12 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi,
 		      QSPI_SPI_SETUP_REG(spi->chip_select));
 }
 
+static bool ti_qspi_spi_flash_can_dma(struct spi_device *spi,
+				      struct spi_flash_read_message *msg)
+{
+	return virt_addr_valid(msg->buf);
+}
+
 static int ti_qspi_spi_flash_read(struct spi_device *spi,
 				  struct spi_flash_read_message *msg)
 {
@@ -509,15 +549,12 @@ static int ti_qspi_spi_flash_read(struct spi_device *spi,
 	ti_qspi_setup_mmap_read(spi, msg);
 
 	if (qspi->rx_chan) {
-		if (msg->cur_msg_mapped) {
+		if (msg->cur_msg_mapped)
 			ret = ti_qspi_dma_xfer_sg(qspi, msg->rx_sg, msg->from);
-			if (ret)
-				goto err_unlock;
-		} else {
-			dev_err(qspi->dev, "Invalid address for DMA\n");
-			ret = -EIO;
+		else
+			ret = ti_qspi_dma_bounce_buffer(qspi, msg);
+		if (ret)
 			goto err_unlock;
-		}
 	} else {
 		memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
 	}
@@ -723,6 +760,17 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		ret = 0;
 		goto no_dma;
 	}
+	qspi->rx_bb_addr = dma_alloc_coherent(qspi->dev,
+					      QSPI_DMA_BUFFER_SIZE,
+					      &qspi->rx_bb_dma_addr,
+					      GFP_KERNEL | GFP_DMA);
+	if (!qspi->rx_bb_addr) {
+		dev_err(qspi->dev,
+			"dma_alloc_coherent failed, using PIO mode\n");
+		dma_release_channel(qspi->rx_chan);
+		goto no_dma;
+	}
+	master->spi_flash_can_dma = ti_qspi_spi_flash_can_dma;
 	master->dma_rx = qspi->rx_chan;
 	init_completion(&qspi->transfer_complete);
 	if (res_mmap)
@@ -763,6 +811,10 @@ static int ti_qspi_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	if (qspi->rx_bb_addr)
+		dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE,
+				  qspi->rx_bb_addr,
+				  qspi->rx_bb_dma_addr);
 	if (qspi->rx_chan)
 		dma_release_channel(qspi->rx_chan);
 
-- 
2.11.0

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

* [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-04-11 11:52   ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-11 11:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, linux-omap, Vignesh R

Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
can potentially be in memory region above 32bit addressable region(ie
buffers belonging to memory region backed by LPAE) of DMA, implement
spi_flash_can_dma() interface to inform SPI core not to map such
buffers.
When buffers are not mapped for DMA, then use a pre allocated bounce
buffer(64K = typical flash erase sector size) to read from flash and
then do a copy to actual destination buffer. This is approach is much
faster than using memcpy using CPU and also reduces CPU load.

With this patch, UBIFS read speed is ~18MB/s and CPU utilization <20% on
DRA74 Rev H EVM. Performance degradation is negligible when compared
with non bounce buffer case while using UBIFS.

Signed-off-by: Vignesh R <vigneshr@ti.com>
---

v2: Fix compiler warnings and sparse warnings reported by Kbuild bot.

 drivers/spi/spi-ti-qspi.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 7b39bc204a30..c24d9b45a27c 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -33,6 +33,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/sizes.h>
 
 #include <linux/spi/spi.h>
 
@@ -57,6 +58,8 @@ struct ti_qspi {
 	struct ti_qspi_regs     ctx_reg;
 
 	dma_addr_t		mmap_phys_base;
+	dma_addr_t		rx_bb_dma_addr;
+	void			*rx_bb_addr;
 	struct dma_chan		*rx_chan;
 
 	u32 spi_max_frequency;
@@ -126,6 +129,8 @@ struct ti_qspi {
 #define QSPI_SETUP_ADDR_SHIFT		8
 #define QSPI_SETUP_DUMMY_SHIFT		10
 
+#define QSPI_DMA_BUFFER_SIZE            SZ_64K
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
 		unsigned long reg)
 {
@@ -429,6 +434,35 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst,
 	return 0;
 }
 
+static int ti_qspi_dma_bounce_buffer(struct ti_qspi *qspi,
+				     struct spi_flash_read_message *msg)
+{
+	size_t readsize = msg->len;
+	void *to = msg->buf;
+	dma_addr_t dma_src = qspi->mmap_phys_base + msg->from;
+	int ret = 0;
+
+	/*
+	 * Use bounce buffer as FS like jffs2, ubifs may pass
+	 * buffers that does not belong to kernel lowmem region.
+	 */
+	while (readsize != 0) {
+		size_t xfer_len = min_t(size_t, QSPI_DMA_BUFFER_SIZE,
+					readsize);
+
+		ret = ti_qspi_dma_xfer(qspi, qspi->rx_bb_dma_addr,
+				       dma_src, xfer_len);
+		if (ret != 0)
+			return ret;
+		memcpy(to, qspi->rx_bb_addr, xfer_len);
+		readsize -= xfer_len;
+		dma_src += xfer_len;
+		to += xfer_len;
+	}
+
+	return ret;
+}
+
 static int ti_qspi_dma_xfer_sg(struct ti_qspi *qspi, struct sg_table rx_sg,
 			       loff_t from)
 {
@@ -496,6 +530,12 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi,
 		      QSPI_SPI_SETUP_REG(spi->chip_select));
 }
 
+static bool ti_qspi_spi_flash_can_dma(struct spi_device *spi,
+				      struct spi_flash_read_message *msg)
+{
+	return virt_addr_valid(msg->buf);
+}
+
 static int ti_qspi_spi_flash_read(struct spi_device *spi,
 				  struct spi_flash_read_message *msg)
 {
@@ -509,15 +549,12 @@ static int ti_qspi_spi_flash_read(struct spi_device *spi,
 	ti_qspi_setup_mmap_read(spi, msg);
 
 	if (qspi->rx_chan) {
-		if (msg->cur_msg_mapped) {
+		if (msg->cur_msg_mapped)
 			ret = ti_qspi_dma_xfer_sg(qspi, msg->rx_sg, msg->from);
-			if (ret)
-				goto err_unlock;
-		} else {
-			dev_err(qspi->dev, "Invalid address for DMA\n");
-			ret = -EIO;
+		else
+			ret = ti_qspi_dma_bounce_buffer(qspi, msg);
+		if (ret)
 			goto err_unlock;
-		}
 	} else {
 		memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
 	}
@@ -723,6 +760,17 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		ret = 0;
 		goto no_dma;
 	}
+	qspi->rx_bb_addr = dma_alloc_coherent(qspi->dev,
+					      QSPI_DMA_BUFFER_SIZE,
+					      &qspi->rx_bb_dma_addr,
+					      GFP_KERNEL | GFP_DMA);
+	if (!qspi->rx_bb_addr) {
+		dev_err(qspi->dev,
+			"dma_alloc_coherent failed, using PIO mode\n");
+		dma_release_channel(qspi->rx_chan);
+		goto no_dma;
+	}
+	master->spi_flash_can_dma = ti_qspi_spi_flash_can_dma;
 	master->dma_rx = qspi->rx_chan;
 	init_completion(&qspi->transfer_complete);
 	if (res_mmap)
@@ -763,6 +811,10 @@ static int ti_qspi_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	if (qspi->rx_bb_addr)
+		dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE,
+				  qspi->rx_bb_addr,
+				  qspi->rx_bb_dma_addr);
 	if (qspi->rx_chan)
 		dma_release_channel(qspi->rx_chan);
 
-- 
2.11.0

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
  2017-04-11 11:52   ` Vignesh R
  (?)
@ 2017-04-21 17:06   ` Mark Brown
  2017-04-25 12:18       ` Vignesh R
  -1 siblings, 1 reply; 18+ messages in thread
From: Mark Brown @ 2017-04-21 17:06 UTC (permalink / raw)
  To: Vignesh R; +Cc: linux-spi, linux-kernel, linux-omap

[-- Attachment #1: Type: text/plain, Size: 741 bytes --]

On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
> can potentially be in memory region above 32bit addressable region(ie
> buffers belonging to memory region backed by LPAE) of DMA, implement
> spi_flash_can_dma() interface to inform SPI core not to map such
> buffers.

I'll apply this since it fixes bugs for your systems but it feels like
something that we should be moving further into the core since LPAE
isn't specific to your devices.  We should ideally have something
(possibly in the DMA mapping code even) which does the remapping without
the driver needing to know about it.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Applied "spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble" to the spi tree
  2017-04-11 11:52   ` Vignesh R
@ 2017-04-21 17:28     ` Mark Brown
  -1 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2017-04-21 17:28 UTC (permalink / raw)
  To: Vignesh R
  Cc: Mark Brown, Mark Brown, linux-spi, linux-kernel, linux-omap, linux-spi

The patch

   spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From c687c46e9e4527c4b4d82bc3cca58c1b08bcfb83 Mon Sep 17 00:00:00 2001
From: Vignesh R <vigneshr@ti.com>
Date: Tue, 11 Apr 2017 17:22:25 +0530
Subject: [PATCH] spi: spi-ti-qspi: Use bounce buffer if read buffer is not
 DMA'ble

Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
can potentially be in memory region above 32bit addressable region(ie
buffers belonging to memory region backed by LPAE) of DMA, implement
spi_flash_can_dma() interface to inform SPI core not to map such
buffers.
When buffers are not mapped for DMA, then use a pre allocated bounce
buffer(64K = typical flash erase sector size) to read from flash and
then do a copy to actual destination buffer. This is approach is much
faster than using memcpy using CPU and also reduces CPU load.

With this patch, UBIFS read speed is ~18MB/s and CPU utilization <20% on
DRA74 Rev H EVM. Performance degradation is negligible when compared
with non bounce buffer case while using UBIFS.

Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-ti-qspi.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 804914ebfd9d..23a06148b8ae 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -33,6 +33,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/sizes.h>
 
 #include <linux/spi/spi.h>
 
@@ -57,6 +58,8 @@ struct ti_qspi {
 	struct ti_qspi_regs     ctx_reg;
 
 	dma_addr_t		mmap_phys_base;
+	dma_addr_t		rx_bb_dma_addr;
+	void			*rx_bb_addr;
 	struct dma_chan		*rx_chan;
 
 	u32 spi_max_frequency;
@@ -126,6 +129,8 @@ struct ti_qspi {
 #define QSPI_SETUP_ADDR_SHIFT		8
 #define QSPI_SETUP_DUMMY_SHIFT		10
 
+#define QSPI_DMA_BUFFER_SIZE            SZ_64K
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
 		unsigned long reg)
 {
@@ -429,6 +434,35 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst,
 	return 0;
 }
 
+static int ti_qspi_dma_bounce_buffer(struct ti_qspi *qspi,
+				     struct spi_flash_read_message *msg)
+{
+	size_t readsize = msg->len;
+	void *to = msg->buf;
+	dma_addr_t dma_src = qspi->mmap_phys_base + msg->from;
+	int ret = 0;
+
+	/*
+	 * Use bounce buffer as FS like jffs2, ubifs may pass
+	 * buffers that does not belong to kernel lowmem region.
+	 */
+	while (readsize != 0) {
+		size_t xfer_len = min_t(size_t, QSPI_DMA_BUFFER_SIZE,
+					readsize);
+
+		ret = ti_qspi_dma_xfer(qspi, qspi->rx_bb_dma_addr,
+				       dma_src, xfer_len);
+		if (ret != 0)
+			return ret;
+		memcpy(to, qspi->rx_bb_addr, xfer_len);
+		readsize -= xfer_len;
+		dma_src += xfer_len;
+		to += xfer_len;
+	}
+
+	return ret;
+}
+
 static int ti_qspi_dma_xfer_sg(struct ti_qspi *qspi, struct sg_table rx_sg,
 			       loff_t from)
 {
@@ -496,6 +530,12 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi,
 		      QSPI_SPI_SETUP_REG(spi->chip_select));
 }
 
+static bool ti_qspi_spi_flash_can_dma(struct spi_device *spi,
+				      struct spi_flash_read_message *msg)
+{
+	return virt_addr_valid(msg->buf);
+}
+
 static int ti_qspi_spi_flash_read(struct spi_device *spi,
 				  struct spi_flash_read_message *msg)
 {
@@ -509,15 +549,12 @@ static int ti_qspi_spi_flash_read(struct spi_device *spi,
 	ti_qspi_setup_mmap_read(spi, msg);
 
 	if (qspi->rx_chan) {
-		if (msg->cur_msg_mapped) {
+		if (msg->cur_msg_mapped)
 			ret = ti_qspi_dma_xfer_sg(qspi, msg->rx_sg, msg->from);
-			if (ret)
-				goto err_unlock;
-		} else {
-			dev_err(qspi->dev, "Invalid address for DMA\n");
-			ret = -EIO;
+		else
+			ret = ti_qspi_dma_bounce_buffer(qspi, msg);
+		if (ret)
 			goto err_unlock;
-		}
 	} else {
 		memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
 	}
@@ -718,6 +755,17 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		ret = 0;
 		goto no_dma;
 	}
+	qspi->rx_bb_addr = dma_alloc_coherent(qspi->dev,
+					      QSPI_DMA_BUFFER_SIZE,
+					      &qspi->rx_bb_dma_addr,
+					      GFP_KERNEL | GFP_DMA);
+	if (!qspi->rx_bb_addr) {
+		dev_err(qspi->dev,
+			"dma_alloc_coherent failed, using PIO mode\n");
+		dma_release_channel(qspi->rx_chan);
+		goto no_dma;
+	}
+	master->spi_flash_can_dma = ti_qspi_spi_flash_can_dma;
 	master->dma_rx = qspi->rx_chan;
 	init_completion(&qspi->transfer_complete);
 	if (res_mmap)
@@ -757,6 +805,10 @@ static int ti_qspi_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	if (qspi->rx_bb_addr)
+		dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE,
+				  qspi->rx_bb_addr,
+				  qspi->rx_bb_dma_addr);
 	if (qspi->rx_chan)
 		dma_release_channel(qspi->rx_chan);
 
-- 
2.11.0

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

* Applied "spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble" to the spi tree
@ 2017-04-21 17:28     ` Mark Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2017-04-21 17:28 UTC (permalink / raw)
  To: Vignesh R; +Cc: Mark Brown

The patch

   spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble

has been applied to the spi tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From c687c46e9e4527c4b4d82bc3cca58c1b08bcfb83 Mon Sep 17 00:00:00 2001
From: Vignesh R <vigneshr@ti.com>
Date: Tue, 11 Apr 2017 17:22:25 +0530
Subject: [PATCH] spi: spi-ti-qspi: Use bounce buffer if read buffer is not
 DMA'ble

Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
can potentially be in memory region above 32bit addressable region(ie
buffers belonging to memory region backed by LPAE) of DMA, implement
spi_flash_can_dma() interface to inform SPI core not to map such
buffers.
When buffers are not mapped for DMA, then use a pre allocated bounce
buffer(64K = typical flash erase sector size) to read from flash and
then do a copy to actual destination buffer. This is approach is much
faster than using memcpy using CPU and also reduces CPU load.

With this patch, UBIFS read speed is ~18MB/s and CPU utilization <20% on
DRA74 Rev H EVM. Performance degradation is negligible when compared
with non bounce buffer case while using UBIFS.

Signed-off-by: Vignesh R <vigneshr@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-ti-qspi.c | 66 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index 804914ebfd9d..23a06148b8ae 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -33,6 +33,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
+#include <linux/sizes.h>
 
 #include <linux/spi/spi.h>
 
@@ -57,6 +58,8 @@ struct ti_qspi {
 	struct ti_qspi_regs     ctx_reg;
 
 	dma_addr_t		mmap_phys_base;
+	dma_addr_t		rx_bb_dma_addr;
+	void			*rx_bb_addr;
 	struct dma_chan		*rx_chan;
 
 	u32 spi_max_frequency;
@@ -126,6 +129,8 @@ struct ti_qspi {
 #define QSPI_SETUP_ADDR_SHIFT		8
 #define QSPI_SETUP_DUMMY_SHIFT		10
 
+#define QSPI_DMA_BUFFER_SIZE            SZ_64K
+
 static inline unsigned long ti_qspi_read(struct ti_qspi *qspi,
 		unsigned long reg)
 {
@@ -429,6 +434,35 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst,
 	return 0;
 }
 
+static int ti_qspi_dma_bounce_buffer(struct ti_qspi *qspi,
+				     struct spi_flash_read_message *msg)
+{
+	size_t readsize = msg->len;
+	void *to = msg->buf;
+	dma_addr_t dma_src = qspi->mmap_phys_base + msg->from;
+	int ret = 0;
+
+	/*
+	 * Use bounce buffer as FS like jffs2, ubifs may pass
+	 * buffers that does not belong to kernel lowmem region.
+	 */
+	while (readsize != 0) {
+		size_t xfer_len = min_t(size_t, QSPI_DMA_BUFFER_SIZE,
+					readsize);
+
+		ret = ti_qspi_dma_xfer(qspi, qspi->rx_bb_dma_addr,
+				       dma_src, xfer_len);
+		if (ret != 0)
+			return ret;
+		memcpy(to, qspi->rx_bb_addr, xfer_len);
+		readsize -= xfer_len;
+		dma_src += xfer_len;
+		to += xfer_len;
+	}
+
+	return ret;
+}
+
 static int ti_qspi_dma_xfer_sg(struct ti_qspi *qspi, struct sg_table rx_sg,
 			       loff_t from)
 {
@@ -496,6 +530,12 @@ static void ti_qspi_setup_mmap_read(struct spi_device *spi,
 		      QSPI_SPI_SETUP_REG(spi->chip_select));
 }
 
+static bool ti_qspi_spi_flash_can_dma(struct spi_device *spi,
+				      struct spi_flash_read_message *msg)
+{
+	return virt_addr_valid(msg->buf);
+}
+
 static int ti_qspi_spi_flash_read(struct spi_device *spi,
 				  struct spi_flash_read_message *msg)
 {
@@ -509,15 +549,12 @@ static int ti_qspi_spi_flash_read(struct spi_device *spi,
 	ti_qspi_setup_mmap_read(spi, msg);
 
 	if (qspi->rx_chan) {
-		if (msg->cur_msg_mapped) {
+		if (msg->cur_msg_mapped)
 			ret = ti_qspi_dma_xfer_sg(qspi, msg->rx_sg, msg->from);
-			if (ret)
-				goto err_unlock;
-		} else {
-			dev_err(qspi->dev, "Invalid address for DMA\n");
-			ret = -EIO;
+		else
+			ret = ti_qspi_dma_bounce_buffer(qspi, msg);
+		if (ret)
 			goto err_unlock;
-		}
 	} else {
 		memcpy_fromio(msg->buf, qspi->mmap_base + msg->from, msg->len);
 	}
@@ -718,6 +755,17 @@ static int ti_qspi_probe(struct platform_device *pdev)
 		ret = 0;
 		goto no_dma;
 	}
+	qspi->rx_bb_addr = dma_alloc_coherent(qspi->dev,
+					      QSPI_DMA_BUFFER_SIZE,
+					      &qspi->rx_bb_dma_addr,
+					      GFP_KERNEL | GFP_DMA);
+	if (!qspi->rx_bb_addr) {
+		dev_err(qspi->dev,
+			"dma_alloc_coherent failed, using PIO mode\n");
+		dma_release_channel(qspi->rx_chan);
+		goto no_dma;
+	}
+	master->spi_flash_can_dma = ti_qspi_spi_flash_can_dma;
 	master->dma_rx = qspi->rx_chan;
 	init_completion(&qspi->transfer_complete);
 	if (res_mmap)
@@ -757,6 +805,10 @@ static int ti_qspi_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	if (qspi->rx_bb_addr)
+		dma_free_coherent(qspi->dev, QSPI_DMA_BUFFER_SIZE,
+				  qspi->rx_bb_addr,
+				  qspi->rx_bb_dma_addr);
 	if (qspi->rx_chan)
 		dma_release_channel(qspi->rx_chan);
 
-- 
2.11.0

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-04-25 12:18       ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-25 12:18 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-spi, linux-kernel, linux-omap



On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>> can potentially be in memory region above 32bit addressable region(ie
>> buffers belonging to memory region backed by LPAE) of DMA, implement
>> spi_flash_can_dma() interface to inform SPI core not to map such
>> buffers.
> 
> I'll apply this since it fixes bugs for your systems but it feels like
> something that we should be moving further into the core since LPAE
> isn't specific to your devices.  We should ideally have something
> (possibly in the DMA mapping code even) which does the remapping without
> the driver needing to know about it.
> 

I agree, there is a need to have generic remapping code. Also, I guess,
once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
have to worry much about vmalloc'd buffers.

-- 
Regards
Vignesh

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-04-25 12:18       ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-25 12:18 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA



On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>> can potentially be in memory region above 32bit addressable region(ie
>> buffers belonging to memory region backed by LPAE) of DMA, implement
>> spi_flash_can_dma() interface to inform SPI core not to map such
>> buffers.
> 
> I'll apply this since it fixes bugs for your systems but it feels like
> something that we should be moving further into the core since LPAE
> isn't specific to your devices.  We should ideally have something
> (possibly in the DMA mapping code even) which does the remapping without
> the driver needing to know about it.
> 

I agree, there is a need to have generic remapping code. Also, I guess,
once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
have to worry much about vmalloc'd buffers.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-04-25 12:18       ` Vignesh R
  0 siblings, 0 replies; 18+ messages in thread
From: Vignesh R @ 2017-04-25 12:18 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA



On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>> can potentially be in memory region above 32bit addressable region(ie
>> buffers belonging to memory region backed by LPAE) of DMA, implement
>> spi_flash_can_dma() interface to inform SPI core not to map such
>> buffers.
> 
> I'll apply this since it fixes bugs for your systems but it feels like
> something that we should be moving further into the core since LPAE
> isn't specific to your devices.  We should ideally have something
> (possibly in the DMA mapping code even) which does the remapping without
> the driver needing to know about it.
> 

I agree, there is a need to have generic remapping code. Also, I guess,
once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
have to worry much about vmalloc'd buffers.

-- 
Regards
Vignesh
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-06-16 15:54         ` Cyrille Pitchen
  0 siblings, 0 replies; 18+ messages in thread
From: Cyrille Pitchen @ 2017-06-16 15:54 UTC (permalink / raw)
  To: Vignesh R, Mark Brown
  Cc: linux-spi, linux-kernel, linux-omap, Richard Weinberger, Boris BREZILLON

Hi all,

+ Richard and Boris as MTD maintainers

Le 25/04/2017 à 14:18, Vignesh R a écrit :
> 
> 
> On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
>> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>>> can potentially be in memory region above 32bit addressable region(ie
>>> buffers belonging to memory region backed by LPAE) of DMA, implement
>>> spi_flash_can_dma() interface to inform SPI core not to map such
>>> buffers.
>>
>> I'll apply this since it fixes bugs for your systems but it feels like
>> something that we should be moving further into the core since LPAE
>> isn't specific to your devices.  We should ideally have something
>> (possibly in the DMA mapping code even) which does the remapping without
>> the driver needing to know about it.
>>
> 
> I agree, there is a need to have generic remapping code. Also, I guess,
> once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
> have to worry much about vmalloc'd buffers.
> 

I've just discussed with Richard and Boris and AFAIK, nothing is planned
at the UBIFS side to replace vmalloc'd buffers by kmalloc'd buffers.
There are reasons for using vmalloc() but Richard can explain better
than me :)

Also, depending on the cache model used by Atmel SoCs, the spi-atmel.c
driver may suffer from the same issue too: using spi_map_buf() hence
mapping vmalloc'ed buffers for DMA usage will be OK with ARM Cortex A5
(PIPT data cache, so no cache aliasing issue at all) hence with SAMA5
series but is not OK for some older cores like ARM926 (VIVT data cache)
hence the SAM9 series.

So to fix the spi-atmel.c driver when used with SAM9 SoCs, we are
thinking about sending a first patch to simply disable the use of DMA
transfers on SAM9 SoCs in case of vmalloc'ed buffers and use CPU
transfers instead.
The code will be left unchanged for SAMA5 SoCs so there would be no
performance loss on those SoCs.
It won't be optimal on SAM9 SoCs but at least it would work.

Then in a new series, if nobody has started to work on this topic yet,
we could propose a generic solution using a bounce buffer at the SPI
core level. however we first need to think how we could do this.

Best regards,

Cyrille

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-06-16 15:54         ` Cyrille Pitchen
  0 siblings, 0 replies; 18+ messages in thread
From: Cyrille Pitchen @ 2017-06-16 15:54 UTC (permalink / raw)
  To: Vignesh R, Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Richard Weinberger,
	Boris BREZILLON

Hi all,

+ Richard and Boris as MTD maintainers

Le 25/04/2017 à 14:18, Vignesh R a écrit :
> 
> 
> On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
>> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>>> can potentially be in memory region above 32bit addressable region(ie
>>> buffers belonging to memory region backed by LPAE) of DMA, implement
>>> spi_flash_can_dma() interface to inform SPI core not to map such
>>> buffers.
>>
>> I'll apply this since it fixes bugs for your systems but it feels like
>> something that we should be moving further into the core since LPAE
>> isn't specific to your devices.  We should ideally have something
>> (possibly in the DMA mapping code even) which does the remapping without
>> the driver needing to know about it.
>>
> 
> I agree, there is a need to have generic remapping code. Also, I guess,
> once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
> have to worry much about vmalloc'd buffers.
> 

I've just discussed with Richard and Boris and AFAIK, nothing is planned
at the UBIFS side to replace vmalloc'd buffers by kmalloc'd buffers.
There are reasons for using vmalloc() but Richard can explain better
than me :)

Also, depending on the cache model used by Atmel SoCs, the spi-atmel.c
driver may suffer from the same issue too: using spi_map_buf() hence
mapping vmalloc'ed buffers for DMA usage will be OK with ARM Cortex A5
(PIPT data cache, so no cache aliasing issue at all) hence with SAMA5
series but is not OK for some older cores like ARM926 (VIVT data cache)
hence the SAM9 series.

So to fix the spi-atmel.c driver when used with SAM9 SoCs, we are
thinking about sending a first patch to simply disable the use of DMA
transfers on SAM9 SoCs in case of vmalloc'ed buffers and use CPU
transfers instead.
The code will be left unchanged for SAMA5 SoCs so there would be no
performance loss on those SoCs.
It won't be optimal on SAM9 SoCs but at least it would work.

Then in a new series, if nobody has started to work on this topic yet,
we could propose a generic solution using a bounce buffer at the SPI
core level. however we first need to think how we could do this.

Best regards,

Cyrille
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
@ 2017-06-16 15:54         ` Cyrille Pitchen
  0 siblings, 0 replies; 18+ messages in thread
From: Cyrille Pitchen @ 2017-06-16 15:54 UTC (permalink / raw)
  To: Vignesh R, Mark Brown
  Cc: linux-spi-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, Richard Weinberger,
	Boris BREZILLON

Hi all,

+ Richard and Boris as MTD maintainers

Le 25/04/2017 à 14:18, Vignesh R a écrit :
> 
> 
> On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
>> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>>> can potentially be in memory region above 32bit addressable region(ie
>>> buffers belonging to memory region backed by LPAE) of DMA, implement
>>> spi_flash_can_dma() interface to inform SPI core not to map such
>>> buffers.
>>
>> I'll apply this since it fixes bugs for your systems but it feels like
>> something that we should be moving further into the core since LPAE
>> isn't specific to your devices.  We should ideally have something
>> (possibly in the DMA mapping code even) which does the remapping without
>> the driver needing to know about it.
>>
> 
> I agree, there is a need to have generic remapping code. Also, I guess,
> once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
> have to worry much about vmalloc'd buffers.
> 

I've just discussed with Richard and Boris and AFAIK, nothing is planned
at the UBIFS side to replace vmalloc'd buffers by kmalloc'd buffers.
There are reasons for using vmalloc() but Richard can explain better
than me :)

Also, depending on the cache model used by Atmel SoCs, the spi-atmel.c
driver may suffer from the same issue too: using spi_map_buf() hence
mapping vmalloc'ed buffers for DMA usage will be OK with ARM Cortex A5
(PIPT data cache, so no cache aliasing issue at all) hence with SAMA5
series but is not OK for some older cores like ARM926 (VIVT data cache)
hence the SAM9 series.

So to fix the spi-atmel.c driver when used with SAM9 SoCs, we are
thinking about sending a first patch to simply disable the use of DMA
transfers on SAM9 SoCs in case of vmalloc'ed buffers and use CPU
transfers instead.
The code will be left unchanged for SAMA5 SoCs so there would be no
performance loss on those SoCs.
It won't be optimal on SAM9 SoCs but at least it would work.

Then in a new series, if nobody has started to work on this topic yet,
we could propose a generic solution using a bounce buffer at the SPI
core level. however we first need to think how we could do this.

Best regards,

Cyrille
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
  2017-06-16 15:54         ` Cyrille Pitchen
  (?)
  (?)
@ 2017-06-20  9:45         ` Vignesh R
  2017-06-23 12:12           ` Mark Brown
  -1 siblings, 1 reply; 18+ messages in thread
From: Vignesh R @ 2017-06-20  9:45 UTC (permalink / raw)
  To: Cyrille Pitchen, Mark Brown
  Cc: linux-spi, linux-kernel, linux-omap, Richard Weinberger, Boris BREZILLON

Hi,

On Friday 16 June 2017 09:24 PM, Cyrille Pitchen wrote:
> Hi all,
> 
> + Richard and Boris as MTD maintainers
> 
> Le 25/04/2017 à 14:18, Vignesh R a écrit :
>>
>>
>> On Friday 21 April 2017 10:36 PM, Mark Brown wrote:
>>> On Tue, Apr 11, 2017 at 05:22:25PM +0530, Vignesh R wrote:
>>>> Flash filesystems like JFFS2, UBIFS and MTD block layer can provide
>>>> vmalloc'd or kmap'd buffers that cannot be mapped using dma_map_sg() and
>>>> can potentially be in memory region above 32bit addressable region(ie
>>>> buffers belonging to memory region backed by LPAE) of DMA, implement
>>>> spi_flash_can_dma() interface to inform SPI core not to map such
>>>> buffers.
>>>
>>> I'll apply this since it fixes bugs for your systems but it feels like
>>> something that we should be moving further into the core since LPAE
>>> isn't specific to your devices.  We should ideally have something
>>> (possibly in the DMA mapping code even) which does the remapping without
>>> the driver needing to know about it.
>>>
>>
>> I agree, there is a need to have generic remapping code. Also, I guess,
>> once UBIFS is moved to use kmalloc'd buffers SPI flash devices will not
>> have to worry much about vmalloc'd buffers.
>>
> 
> I've just discussed with Richard and Boris and AFAIK, nothing is planned
> at the UBIFS side to replace vmalloc'd buffers by kmalloc'd buffers.
> There are reasons for using vmalloc() but Richard can explain better
> than me :)
> 
> Also, depending on the cache model used by Atmel SoCs, the spi-atmel.c
> driver may suffer from the same issue too: using spi_map_buf() hence
> mapping vmalloc'ed buffers for DMA usage will be OK with ARM Cortex A5
> (PIPT data cache, so no cache aliasing issue at all) hence with SAMA5
> series but is not OK for some older cores like ARM926 (VIVT data cache)
> hence the SAM9 series.
> 
> So to fix the spi-atmel.c driver when used with SAM9 SoCs, we are
> thinking about sending a first patch to simply disable the use of DMA
> transfers on SAM9 SoCs in case of vmalloc'ed buffers and use CPU
> transfers instead.
> The code will be left unchanged for SAMA5 SoCs so there would be no
> performance loss on those SoCs.
> It won't be optimal on SAM9 SoCs but at least it would work.
> 
> Then in a new series, if nobody has started to work on this topic yet,
> we could propose a generic solution using a bounce buffer at the SPI
> core level. however we first need to think how we could do this.
> 

One of the questions that was hovering around when this issue was
discussed last time around was where should the code to detect whether
or not to use bounce buffer reside? Some extension to generic DMA APIs
or SPI drivers or somewhere else?

-- 
Regards
Vignesh

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

* Re: [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble
  2017-06-20  9:45         ` Vignesh R
@ 2017-06-23 12:12           ` Mark Brown
  0 siblings, 0 replies; 18+ messages in thread
From: Mark Brown @ 2017-06-23 12:12 UTC (permalink / raw)
  To: Vignesh R
  Cc: Cyrille Pitchen, linux-spi, linux-kernel, linux-omap,
	Richard Weinberger, Boris BREZILLON

[-- Attachment #1: Type: text/plain, Size: 702 bytes --]

On Tue, Jun 20, 2017 at 03:15:34PM +0530, Vignesh R wrote:
> On Friday 16 June 2017 09:24 PM, Cyrille Pitchen wrote:

> > Then in a new series, if nobody has started to work on this topic yet,
> > we could propose a generic solution using a bounce buffer at the SPI
> > core level. however we first need to think how we could do this.

> One of the questions that was hovering around when this issue was
> discussed last time around was where should the code to detect whether
> or not to use bounce buffer reside? Some extension to generic DMA APIs
> or SPI drivers or somewhere else?

It seems like it's a generic DMA thing - presumably it's going to be an
issue for other devices as well sometimes.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

end of thread, other threads:[~2017-06-23 12:12 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-11 11:52 [PATCH v2 0/2] spi-ti-qspi: Handle vmalloc'd buffers Vignesh R
2017-04-11 11:52 ` Vignesh R
2017-04-11 11:52 ` [PATCH v2 1/2] spi: Add can_dma like interface for spi_flash_read Vignesh R
2017-04-11 11:52   ` Vignesh R
2017-04-11 11:52   ` Vignesh R
2017-04-11 11:52 ` [PATCH v2 2/2] spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble Vignesh R
2017-04-11 11:52   ` Vignesh R
2017-04-21 17:06   ` Mark Brown
2017-04-25 12:18     ` Vignesh R
2017-04-25 12:18       ` Vignesh R
2017-04-25 12:18       ` Vignesh R
2017-06-16 15:54       ` Cyrille Pitchen
2017-06-16 15:54         ` Cyrille Pitchen
2017-06-16 15:54         ` Cyrille Pitchen
2017-06-20  9:45         ` Vignesh R
2017-06-23 12:12           ` Mark Brown
2017-04-21 17:28   ` Applied "spi: spi-ti-qspi: Use bounce buffer if read buffer is not DMA'ble" to the spi tree Mark Brown
2017-04-21 17:28     ` Mark Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.