All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jonathan Neuschäfer" <j.neuschaefer@gmx.net>
To: linux-spi@vger.kernel.org, openbmc@lists.ozlabs.org
Cc: "Rob Herring" <robh+dt@kernel.org>,
	"Krzysztof Kozlowski" <krzysztof.kozlowski+dt@linaro.org>,
	"Jonathan Neuschäfer" <j.neuschaefer@gmx.net>,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Mark Brown" <broonie@kernel.org>
Subject: [PATCH v2 3/3] spi: wpcm-fiu: Add direct map support
Date: Thu, 24 Nov 2022 20:14:00 +0100	[thread overview]
Message-ID: <20221124191400.287918-4-j.neuschaefer@gmx.net> (raw)
In-Reply-To: <20221124191400.287918-1-j.neuschaefer@gmx.net>

Besides software controlled SPI transfers (UMA, "user mode access"), FIU
also supports a 16 MiB mapping window per attached flash chip.

This patch implements direct mapped read access, to speed up flash reads.


Without direct mapping:

	# time dd if=/dev/mtd0ro of=dump bs=1M
	16+0 records in
	16+0 records out
	real    1m 47.74s
	user    0m 0.00s
	sys     1m 47.75s


With direct mapping:

	# time dd if=/dev/mtd0ro of=dump bs=1M
	16+0 records in
	16+0 records out
	real    0m 30.81s
	user    0m 0.00s
	sys     0m 30.81s

Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
---

v2:
- Fix a few nits from the kernel test robot
- Fix check for fiu->memory mapping error

v1:
- https://lore.kernel.org/lkml/20221105185911.1547847-9-j.neuschaefer@gmx.net/
---
 drivers/spi/spi-wpcm-fiu.c | 64 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
index e525fe074f883..ab33710d50ac8 100644
--- a/drivers/spi/spi-wpcm-fiu.c
+++ b/drivers/spi/spi-wpcm-fiu.c
@@ -51,10 +51,16 @@
  */
 #define UMA_WAIT_ITERATIONS 100

+/* The memory-mapped view of flash is 16 MiB long */
+#define MAX_MEMORY_SIZE_PER_CS	(16 << 20)
+#define MAX_MEMORY_SIZE_TOTAL	(4 * MAX_MEMORY_SIZE_PER_CS)
+
 struct wpcm_fiu_spi {
 	struct device *dev;
 	struct clk *clk;
 	void __iomem *regs;
+	void __iomem *memory;
+	size_t memory_size;
 	struct regmap *shm_regmap;
 };

@@ -367,14 +373,64 @@ static int wpcm_fiu_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 	return 0;
 }

+static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+	struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller);
+	int cs = desc->mem->spi->chip_select;
+
+	if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
+		return -ENOTSUPP;
+
+	/*
+	 * Unfortunately, FIU only supports a 16 MiB direct mapping window (per
+	 * attached flash chip), but the SPI MEM core doesn't support partial
+	 * direct mappings. This means that we can't support direct mapping on
+	 * flashes that are bigger than 16 MiB.
+	 */
+	if (desc->info.offset + desc->info.length > MAX_MEMORY_SIZE_PER_CS)
+		return -ENOTSUPP;
+
+	/* Don't read past the memory window */
+	if (cs * MAX_MEMORY_SIZE_PER_CS + desc->info.offset + desc->info.length > fiu->memory_size)
+		return -ENOTSUPP;
+
+	return 0;
+}
+
+static ssize_t wpcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf)
+{
+	struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller);
+	int cs = desc->mem->spi->chip_select;
+
+	if (offs >= MAX_MEMORY_SIZE_PER_CS)
+		return -ENOTSUPP;
+
+	offs += cs * MAX_MEMORY_SIZE_PER_CS;
+
+	if (!fiu->memory || offs >= fiu->memory_size)
+		return -ENOTSUPP;
+
+	len = min_t(size_t, len, fiu->memory_size - offs);
+	memcpy_fromio(buf, fiu->memory + offs, len);
+
+	return len;
+}
+
 static const struct spi_controller_mem_ops wpcm_fiu_mem_ops = {
 	.adjust_op_size = wpcm_fiu_adjust_op_size,
 	.supports_op = wpcm_fiu_supports_op,
 	.exec_op = wpcm_fiu_exec_op,
+	.dirmap_create = wpcm_fiu_dirmap_create,
+	.dirmap_read = wpcm_fiu_direct_read,
 };

 static void wpcm_fiu_hw_init(struct wpcm_fiu_spi *fiu)
 {
+	/* Configure memory-mapped flash access */
+	writeb(FIU_BURST_CFG_R16, fiu->regs + FIU_BURST_BFG);
+	writeb(MAX_MEMORY_SIZE_TOTAL / (512 << 10), fiu->regs + FIU_CFG);
+	writeb(MAX_MEMORY_SIZE_PER_CS / (512 << 10) | BIT(6), fiu->regs + FIU_SPI_FL_CFG);
+
 	/* Deassert all manually asserted chip selects */
 	writeb(0x0f, fiu->regs + FIU_UMA_ECTS);
 }
@@ -404,6 +460,14 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
 	if (IS_ERR(fiu->clk))
 		return PTR_ERR(fiu->clk);

+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+	fiu->memory = devm_ioremap_resource(dev, res);
+	fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+	if (IS_ERR(fiu->memory)) {
+		dev_err(dev, "Failed to map flash memory window\n");
+		return PTR_ERR(fiu->memory);
+	}
+
 	fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");

 	wpcm_fiu_hw_init(fiu);
--
2.35.1


WARNING: multiple messages have this Message-ID (diff)
From: "Jonathan Neuschäfer" <j.neuschaefer@gmx.net>
To: linux-spi@vger.kernel.org, openbmc@lists.ozlabs.org
Cc: devicetree@vger.kernel.org,
	"Jonathan Neuschäfer" <j.neuschaefer@gmx.net>,
	"Rob Herring" <robh+dt@kernel.org>,
	linux-kernel@vger.kernel.org, "Mark Brown" <broonie@kernel.org>,
	"Krzysztof Kozlowski" <krzysztof.kozlowski+dt@linaro.org>
Subject: [PATCH v2 3/3] spi: wpcm-fiu: Add direct map support
Date: Thu, 24 Nov 2022 20:14:00 +0100	[thread overview]
Message-ID: <20221124191400.287918-4-j.neuschaefer@gmx.net> (raw)
In-Reply-To: <20221124191400.287918-1-j.neuschaefer@gmx.net>

Besides software controlled SPI transfers (UMA, "user mode access"), FIU
also supports a 16 MiB mapping window per attached flash chip.

This patch implements direct mapped read access, to speed up flash reads.


Without direct mapping:

	# time dd if=/dev/mtd0ro of=dump bs=1M
	16+0 records in
	16+0 records out
	real    1m 47.74s
	user    0m 0.00s
	sys     1m 47.75s


With direct mapping:

	# time dd if=/dev/mtd0ro of=dump bs=1M
	16+0 records in
	16+0 records out
	real    0m 30.81s
	user    0m 0.00s
	sys     0m 30.81s

Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
---

v2:
- Fix a few nits from the kernel test robot
- Fix check for fiu->memory mapping error

v1:
- https://lore.kernel.org/lkml/20221105185911.1547847-9-j.neuschaefer@gmx.net/
---
 drivers/spi/spi-wpcm-fiu.c | 64 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c
index e525fe074f883..ab33710d50ac8 100644
--- a/drivers/spi/spi-wpcm-fiu.c
+++ b/drivers/spi/spi-wpcm-fiu.c
@@ -51,10 +51,16 @@
  */
 #define UMA_WAIT_ITERATIONS 100

+/* The memory-mapped view of flash is 16 MiB long */
+#define MAX_MEMORY_SIZE_PER_CS	(16 << 20)
+#define MAX_MEMORY_SIZE_TOTAL	(4 * MAX_MEMORY_SIZE_PER_CS)
+
 struct wpcm_fiu_spi {
 	struct device *dev;
 	struct clk *clk;
 	void __iomem *regs;
+	void __iomem *memory;
+	size_t memory_size;
 	struct regmap *shm_regmap;
 };

@@ -367,14 +373,64 @@ static int wpcm_fiu_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
 	return 0;
 }

+static int wpcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+	struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller);
+	int cs = desc->mem->spi->chip_select;
+
+	if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN)
+		return -ENOTSUPP;
+
+	/*
+	 * Unfortunately, FIU only supports a 16 MiB direct mapping window (per
+	 * attached flash chip), but the SPI MEM core doesn't support partial
+	 * direct mappings. This means that we can't support direct mapping on
+	 * flashes that are bigger than 16 MiB.
+	 */
+	if (desc->info.offset + desc->info.length > MAX_MEMORY_SIZE_PER_CS)
+		return -ENOTSUPP;
+
+	/* Don't read past the memory window */
+	if (cs * MAX_MEMORY_SIZE_PER_CS + desc->info.offset + desc->info.length > fiu->memory_size)
+		return -ENOTSUPP;
+
+	return 0;
+}
+
+static ssize_t wpcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf)
+{
+	struct wpcm_fiu_spi *fiu = spi_controller_get_devdata(desc->mem->spi->controller);
+	int cs = desc->mem->spi->chip_select;
+
+	if (offs >= MAX_MEMORY_SIZE_PER_CS)
+		return -ENOTSUPP;
+
+	offs += cs * MAX_MEMORY_SIZE_PER_CS;
+
+	if (!fiu->memory || offs >= fiu->memory_size)
+		return -ENOTSUPP;
+
+	len = min_t(size_t, len, fiu->memory_size - offs);
+	memcpy_fromio(buf, fiu->memory + offs, len);
+
+	return len;
+}
+
 static const struct spi_controller_mem_ops wpcm_fiu_mem_ops = {
 	.adjust_op_size = wpcm_fiu_adjust_op_size,
 	.supports_op = wpcm_fiu_supports_op,
 	.exec_op = wpcm_fiu_exec_op,
+	.dirmap_create = wpcm_fiu_dirmap_create,
+	.dirmap_read = wpcm_fiu_direct_read,
 };

 static void wpcm_fiu_hw_init(struct wpcm_fiu_spi *fiu)
 {
+	/* Configure memory-mapped flash access */
+	writeb(FIU_BURST_CFG_R16, fiu->regs + FIU_BURST_BFG);
+	writeb(MAX_MEMORY_SIZE_TOTAL / (512 << 10), fiu->regs + FIU_CFG);
+	writeb(MAX_MEMORY_SIZE_PER_CS / (512 << 10) | BIT(6), fiu->regs + FIU_SPI_FL_CFG);
+
 	/* Deassert all manually asserted chip selects */
 	writeb(0x0f, fiu->regs + FIU_UMA_ECTS);
 }
@@ -404,6 +460,14 @@ static int wpcm_fiu_probe(struct platform_device *pdev)
 	if (IS_ERR(fiu->clk))
 		return PTR_ERR(fiu->clk);

+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
+	fiu->memory = devm_ioremap_resource(dev, res);
+	fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL);
+	if (IS_ERR(fiu->memory)) {
+		dev_err(dev, "Failed to map flash memory window\n");
+		return PTR_ERR(fiu->memory);
+	}
+
 	fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm");

 	wpcm_fiu_hw_init(fiu);
--
2.35.1


  parent reply	other threads:[~2022-11-24 19:14 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-24 19:13 [PATCH v2 0/3] Nuvoton WPCM450 FIU SPI flash controller Jonathan Neuschäfer
2022-11-24 19:13 ` Jonathan Neuschäfer
2022-11-24 19:13 ` [PATCH v2 1/3] dt-bindings: spi: Add Nuvoton WPCM450 Flash Interface Unit (FIU) Jonathan Neuschäfer
2022-11-24 19:13   ` Jonathan Neuschäfer
2022-11-25  8:33   ` Krzysztof Kozlowski
2022-11-25 13:13   ` Mark Brown
2022-11-25 13:13     ` Mark Brown
2022-11-25 14:33     ` Jonathan Neuschäfer
2022-11-25 14:33       ` Jonathan Neuschäfer
2022-11-26 22:25   ` Rob Herring
2022-11-26 22:25     ` Rob Herring
2022-11-28 11:05     ` Conor Dooley
2022-11-28 11:05       ` Conor Dooley
2022-11-28 13:58       ` Jonathan Neuschäfer
2022-11-28 13:58         ` Jonathan Neuschäfer
2022-11-28 14:09         ` Conor Dooley
2022-11-28 14:09           ` Conor Dooley
2022-11-28 17:57           ` Mark Brown
2022-11-28 17:57             ` Mark Brown
2022-11-24 19:13 ` [PATCH v2 2/3] spi: wpcm-fiu: Add driver for " Jonathan Neuschäfer
2022-11-24 19:13   ` Jonathan Neuschäfer
2022-11-25 13:04   ` Mark Brown
2022-11-25 13:04     ` Mark Brown
2022-11-25 16:33     ` Jonathan Neuschäfer
2022-11-25 16:33       ` Jonathan Neuschäfer
2022-11-25 16:48       ` Mark Brown
2022-11-25 16:48         ` Mark Brown
2022-11-24 19:14 ` Jonathan Neuschäfer [this message]
2022-11-24 19:14   ` [PATCH v2 3/3] spi: wpcm-fiu: Add direct map support Jonathan Neuschäfer
2022-11-25 14:59 ` [PATCH v2 0/3] Nuvoton WPCM450 FIU SPI flash controller Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221124191400.287918-4-j.neuschaefer@gmx.net \
    --to=j.neuschaefer@gmx.net \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=openbmc@lists.ozlabs.org \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.