Linux-SPI Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/3]  spi: stm32-qspi: Fix and update
@ 2021-04-19 12:15 patrice.chotard
  2021-04-19 12:15 ` [PATCH 1/3] spi: stm32-qspi: fix pm_runtime usage_count counter patrice.chotard
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: patrice.chotard @ 2021-04-19 12:15 UTC (permalink / raw)
  To: Mark Brown, Alexandre Torgue
  Cc: linux-spi, linux-stm32, linux-arm-kernel, linux-kernel,
	christophe.kerello, patrice.chotard

From: Patrice Chotard <patrice.chotard@foss.st.com>

Christophe Kerello (1):
  spi: stm32-qspi: fix pm_runtime usage_count counter

Patrice Chotard (2):
  spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer
  spi: stm32-qspi: Add dirmap support

 drivers/spi/spi-stm32-qspi.c | 106 +++++++++++++++++++++++++++--------
 1 file changed, 84 insertions(+), 22 deletions(-)

-- 
2.17.1


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

* [PATCH 1/3] spi: stm32-qspi: fix pm_runtime usage_count counter
  2021-04-19 12:15 [PATCH 0/3] spi: stm32-qspi: Fix and update patrice.chotard
@ 2021-04-19 12:15 ` patrice.chotard
  2021-04-19 12:15 ` [PATCH 2/3] spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer patrice.chotard
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: patrice.chotard @ 2021-04-19 12:15 UTC (permalink / raw)
  To: Mark Brown, Alexandre Torgue
  Cc: linux-spi, linux-stm32, linux-arm-kernel, linux-kernel,
	christophe.kerello, patrice.chotard, stable

From: Christophe Kerello <christophe.kerello@foss.st.com>

pm_runtime usage_count counter is not well managed.
pm_runtime_put_autosuspend callback drops the usage_counter but this
one has never been increased. Add pm_runtime_get_sync callback to bump up
the usage counter. It is also needed to use pm_runtime_force_suspend and
pm_runtime_force_resume APIs to handle properly the clock.

Fixes: 9d282c17b023 ("spi: stm32-qspi: Add pm_runtime support")
Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
Cc: stable@vger.kernel.org
---
 drivers/spi/spi-stm32-qspi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 947e6b9dc9f4..2786470a5201 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -727,21 +727,31 @@ static int __maybe_unused stm32_qspi_suspend(struct device *dev)
 {
 	pinctrl_pm_select_sleep_state(dev);
 
-	return 0;
+	return pm_runtime_force_suspend(dev);
 }
 
 static int __maybe_unused stm32_qspi_resume(struct device *dev)
 {
 	struct stm32_qspi *qspi = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pm_runtime_force_resume(dev);
+	if (ret < 0)
+		return ret;
 
 	pinctrl_pm_select_default_state(dev);
-	clk_prepare_enable(qspi->clk);
+
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev);
+		return ret;
+	}
 
 	writel_relaxed(qspi->cr_reg, qspi->io_base + QSPI_CR);
 	writel_relaxed(qspi->dcr_reg, qspi->io_base + QSPI_DCR);
 
-	pm_runtime_mark_last_busy(qspi->dev);
-	pm_runtime_put_autosuspend(qspi->dev);
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
 
 	return 0;
 }
-- 
2.17.1


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

* [PATCH 2/3] spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer
  2021-04-19 12:15 [PATCH 0/3] spi: stm32-qspi: Fix and update patrice.chotard
  2021-04-19 12:15 ` [PATCH 1/3] spi: stm32-qspi: fix pm_runtime usage_count counter patrice.chotard
@ 2021-04-19 12:15 ` patrice.chotard
  2021-04-19 12:15 ` [PATCH 3/3] spi: stm32-qspi: Add dirmap support patrice.chotard
  2021-04-19 17:33 ` [PATCH 0/3] spi: stm32-qspi: Fix and update Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: patrice.chotard @ 2021-04-19 12:15 UTC (permalink / raw)
  To: Mark Brown, Alexandre Torgue
  Cc: linux-spi, linux-stm32, linux-arm-kernel, linux-kernel,
	christophe.kerello, patrice.chotard

From: Patrice Chotard <patrice.chotard@foss.st.com>

In order to optimize accesses to spi flashes, trigger a DMA only
if more than 4 bytes has to be transferred.

DMA transfer preparation's cost becomes negligible above 4 bytes to
transfer. Below this threshold, indirect transfer give more throughput.

mtd_speedtest shows that page write throughtput increases :
  - from 779 to 853 KiB/s (~9.5%) with s25fl512s SPI-NOR.
  - from 5283 to 5666 KiB/s (~7.25%) with Micron SPI-NAND.

Signed-off-by: Christophe Kerello <christophe.kerello@foss.st.com>
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
---
 drivers/spi/spi-stm32-qspi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 2786470a5201..6e74d6bed54c 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -269,8 +269,9 @@ static int stm32_qspi_tx(struct stm32_qspi *qspi, const struct spi_mem_op *op)
 
 	if (qspi->fmode == CCR_FMODE_MM)
 		return stm32_qspi_tx_mm(qspi, op);
-	else if ((op->data.dir == SPI_MEM_DATA_IN && qspi->dma_chrx) ||
-		 (op->data.dir == SPI_MEM_DATA_OUT && qspi->dma_chtx))
+	else if (((op->data.dir == SPI_MEM_DATA_IN && qspi->dma_chrx) ||
+		 (op->data.dir == SPI_MEM_DATA_OUT && qspi->dma_chtx)) &&
+		  op->data.nbytes > 4)
 		if (!stm32_qspi_tx_dma(qspi, op))
 			return 0;
 
-- 
2.17.1


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

* [PATCH 3/3] spi: stm32-qspi: Add dirmap support
  2021-04-19 12:15 [PATCH 0/3] spi: stm32-qspi: Fix and update patrice.chotard
  2021-04-19 12:15 ` [PATCH 1/3] spi: stm32-qspi: fix pm_runtime usage_count counter patrice.chotard
  2021-04-19 12:15 ` [PATCH 2/3] spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer patrice.chotard
@ 2021-04-19 12:15 ` patrice.chotard
  2021-04-19 17:33 ` [PATCH 0/3] spi: stm32-qspi: Fix and update Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: patrice.chotard @ 2021-04-19 12:15 UTC (permalink / raw)
  To: Mark Brown, Alexandre Torgue
  Cc: linux-spi, linux-stm32, linux-arm-kernel, linux-kernel,
	christophe.kerello, patrice.chotard

From: Patrice Chotard <patrice.chotard@foss.st.com>

Add stm32_qspi_dirmap_read() and stm32_qspi_dirmap_create()
to get dirmap support.

Update the exec_op callback which doens't allow anymore memory map
access. Memory map access are only available through the dirmap_read
callback.

Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
---
 drivers/spi/spi-stm32-qspi.c | 83 +++++++++++++++++++++++++++++-------
 1 file changed, 67 insertions(+), 16 deletions(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 6e74d6bed54c..e2a99f054551 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -331,7 +331,7 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
 {
 	struct stm32_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
 	struct stm32_qspi_flash *flash = &qspi->flash[mem->spi->chip_select];
-	u32 ccr, cr, addr_max;
+	u32 ccr, cr;
 	int timeout, err = 0;
 
 	dev_dbg(qspi->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
@@ -343,18 +343,6 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
 	if (err)
 		goto abort;
 
-	addr_max = op->addr.val + op->data.nbytes + 1;
-
-	if (op->data.dir == SPI_MEM_DATA_IN) {
-		if (addr_max < qspi->mm_size &&
-		    op->addr.buswidth)
-			qspi->fmode = CCR_FMODE_MM;
-		else
-			qspi->fmode = CCR_FMODE_INDR;
-	} else {
-		qspi->fmode = CCR_FMODE_INDW;
-	}
-
 	cr = readl_relaxed(qspi->io_base + QSPI_CR);
 	cr &= ~CR_PRESC_MASK & ~CR_FSEL;
 	cr |= FIELD_PREP(CR_PRESC_MASK, flash->presc);
@@ -364,8 +352,6 @@ static int stm32_qspi_send(struct spi_mem *mem, const struct spi_mem_op *op)
 	if (op->data.nbytes)
 		writel_relaxed(op->data.nbytes - 1,
 			       qspi->io_base + QSPI_DLR);
-	else
-		qspi->fmode = CCR_FMODE_INDW;
 
 	ccr = qspi->fmode;
 	ccr |= FIELD_PREP(CCR_INST_MASK, op->cmd.opcode);
@@ -441,6 +427,11 @@ static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 	}
 
 	mutex_lock(&qspi->lock);
+	if (op->data.dir == SPI_MEM_DATA_IN && op->data.nbytes)
+		qspi->fmode = CCR_FMODE_INDR;
+	else
+		qspi->fmode = CCR_FMODE_INDW;
+
 	ret = stm32_qspi_send(mem, op);
 	mutex_unlock(&qspi->lock);
 
@@ -450,6 +441,64 @@ static int stm32_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 	return ret;
 }
 
+static int stm32_qspi_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+	struct stm32_qspi *qspi = spi_controller_get_devdata(desc->mem->spi->master);
+
+	if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT)
+		return -EOPNOTSUPP;
+
+	/* should never happen, as mm_base == null is an error probe exit condition */
+	if (!qspi->mm_base && desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN)
+		return -EOPNOTSUPP;
+
+	if (!qspi->mm_size)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+static ssize_t stm32_qspi_dirmap_read(struct spi_mem_dirmap_desc *desc,
+				      u64 offs, size_t len, void *buf)
+{
+	struct stm32_qspi *qspi = spi_controller_get_devdata(desc->mem->spi->master);
+	struct spi_mem_op op;
+	u32 addr_max;
+	int ret;
+
+	ret = pm_runtime_get_sync(qspi->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(qspi->dev);
+		return ret;
+	}
+
+	mutex_lock(&qspi->lock);
+	/* make a local copy of desc op_tmpl and complete dirmap rdesc
+	 * spi_mem_op template with offs, len and *buf in  order to get
+	 * all needed transfer information into struct spi_mem_op
+	 */
+	memcpy(&op, &desc->info.op_tmpl, sizeof(struct spi_mem_op));
+	dev_dbg(qspi->dev, "%s len = 0x%x offs = 0x%llx buf = 0x%p\n", __func__, len, offs, buf);
+
+	op.data.nbytes = len;
+	op.addr.val = desc->info.offset + offs;
+	op.data.buf.in = buf;
+
+	addr_max = op.addr.val + op.data.nbytes + 1;
+	if (addr_max < qspi->mm_size && op.addr.buswidth)
+		qspi->fmode = CCR_FMODE_MM;
+	else
+		qspi->fmode = CCR_FMODE_INDR;
+
+	ret = stm32_qspi_send(desc->mem, &op);
+	mutex_unlock(&qspi->lock);
+
+	pm_runtime_mark_last_busy(qspi->dev);
+	pm_runtime_put_autosuspend(qspi->dev);
+
+	return ret ?: len;
+}
+
 static int stm32_qspi_setup(struct spi_device *spi)
 {
 	struct spi_controller *ctrl = spi->master;
@@ -555,7 +604,9 @@ static void stm32_qspi_dma_free(struct stm32_qspi *qspi)
  * to check supported mode.
  */
 static const struct spi_controller_mem_ops stm32_qspi_mem_ops = {
-	.exec_op = stm32_qspi_exec_op,
+	.exec_op	= stm32_qspi_exec_op,
+	.dirmap_create	= stm32_qspi_dirmap_create,
+	.dirmap_read	= stm32_qspi_dirmap_read,
 };
 
 static int stm32_qspi_probe(struct platform_device *pdev)
-- 
2.17.1


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

* Re: [PATCH 0/3] spi: stm32-qspi: Fix and update
  2021-04-19 12:15 [PATCH 0/3] spi: stm32-qspi: Fix and update patrice.chotard
                   ` (2 preceding siblings ...)
  2021-04-19 12:15 ` [PATCH 3/3] spi: stm32-qspi: Add dirmap support patrice.chotard
@ 2021-04-19 17:33 ` Mark Brown
  3 siblings, 0 replies; 5+ messages in thread
From: Mark Brown @ 2021-04-19 17:33 UTC (permalink / raw)
  To: Alexandre Torgue, patrice.chotard
  Cc: Mark Brown, christophe.kerello, linux-arm-kernel, linux-spi,
	linux-kernel, linux-stm32

On Mon, 19 Apr 2021 14:15:38 +0200, patrice.chotard@foss.st.com wrote:
> Christophe Kerello (1):
>   spi: stm32-qspi: fix pm_runtime usage_count counter
> 
> Patrice Chotard (2):
>   spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer
>   spi: stm32-qspi: Add dirmap support
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/3] spi: stm32-qspi: fix pm_runtime usage_count counter
      commit: 102e9d1936569d43f55dd1ea89be355ad207143c
[2/3] spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer
      commit: f3530f26f8e9869e6e8c3370cf6f61330774fe2b
[3/3] spi: stm32-qspi: Add dirmap support
      commit: 18674dee3cd651279eb3d9ba789fe483ddfe1137

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

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

end of thread, back to index

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-19 12:15 [PATCH 0/3] spi: stm32-qspi: Fix and update patrice.chotard
2021-04-19 12:15 ` [PATCH 1/3] spi: stm32-qspi: fix pm_runtime usage_count counter patrice.chotard
2021-04-19 12:15 ` [PATCH 2/3] spi: stm32-qspi: Trigger DMA only if more than 4 bytes to transfer patrice.chotard
2021-04-19 12:15 ` [PATCH 3/3] spi: stm32-qspi: Add dirmap support patrice.chotard
2021-04-19 17:33 ` [PATCH 0/3] spi: stm32-qspi: Fix and update Mark Brown

Linux-SPI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-spi/0 linux-spi/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-spi linux-spi/ https://lore.kernel.org/linux-spi \
		linux-spi@vger.kernel.org
	public-inbox-index linux-spi

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-spi


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git