This patchset adds DT bindings and a driver for the Flash Interface Unit
(FIU), the SPI flash controller in the Nuvoton WPCM450 BMC SoC. It
supports four chip selects, and direct (memory-mapped) access to 16 MiB
per chip. Larger flash chips can be accessed by software-defined SPI
transfers.
The existing NPCM7xx FIU driver is sufficitently incompatible with the
WPCM450 FIU that I decided to write a new driver.
Changelog for v2:
- Dropped the patches which have been applied in the meantime, leaving
only three out of eight
- Changed the binding to require both items in the reg property, because
there is no need to keep the second item optional, suggested by
Krzysztof Kozlowski
- Various other cleanups suggested by Krzysztof Kozlowski and the kernel
test robot
Jonathan
Jonathan Neuschäfer (3):
dt-bindings: spi: Add Nuvoton WPCM450 Flash Interface Unit (FIU)
spi: wpcm-fiu: Add driver for Nuvoton WPCM450 Flash Interface Unit
(FIU)
spi: wpcm-fiu: Add direct map support
.../bindings/spi/nuvoton,wpcm450-fiu.yaml | 66 +++
drivers/spi/Kconfig | 11 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-wpcm-fiu.c | 508 ++++++++++++++++++
4 files changed, 586 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml
create mode 100644 drivers/spi/spi-wpcm-fiu.c
--
2.35.1
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 <[email protected]>
---
v2:
- Fix a few nits from the kernel test robot
- Fix check for fiu->memory mapping error
v1:
- https://lore.kernel.org/lkml/[email protected]/
---
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
The Flash Interface Unit (FIU) is the SPI flash controller in the
Nuvoton WPCM450 BMC SoC. It supports four chip selects, and direct
(memory-mapped) access to 16 MiB per chip. Larger flash chips can be
accessed by software-defined SPI transfers.
The FIU in newer NPCM7xx SoCs is not compatible with the WPCM450 FIU.
Signed-off-by: Jonathan Neuschäfer <[email protected]>
---
v2:
- A few cleanups suggested by Krzysztof Kozlowski
- Simplify binding by making second reg item mandatory
v1:
- https://lore.kernel.org/lkml/[email protected]/
---
.../bindings/spi/nuvoton,wpcm450-fiu.yaml | 66 +++++++++++++++++++
1 file changed, 66 insertions(+)
create mode 100644 Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml
diff --git a/Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml b/Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml
new file mode 100644
index 0000000000000..ef94803e75d90
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/nuvoton,wpcm450-fiu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Nuvoton WPCM450 Flash Interface Unit (FIU)
+
+maintainers:
+ - Jonathan Neuschäfer <[email protected]>
+
+allOf:
+ - $ref: /schemas/spi/spi-controller.yaml#
+
+properties:
+ compatible:
+ const: nuvoton,wpcm450-fiu
+
+ reg:
+ items:
+ - description: FIU registers
+ - description: Memory-mapped flash contents
+
+ reg-names:
+ items:
+ - const: control
+ - const: memory
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ nuvoton,shm:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: a phandle to the SHM block (see ../arm/nuvoton,shm.yaml)
+
+required:
+ - compatible
+ - reg
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/nuvoton,wpcm450-clk.h>
+ spi@c8000000 {
+ compatible = "nuvoton,wpcm450-fiu";
+ reg = <0xc8000000 0x1000>, <0xc0000000 0x4000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "control", "memory";
+ clocks = <&clk WPCM450_CLK_FIU>;
+ nuvoton,shm = <&shm>;
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ };
+ };
+
+ shm: syscon@c8001000 {
+ compatible = "nuvoton,wpcm450-shm", "syscon";
+ reg = <0xc8001000 0x1000>;
+ };
--
2.35.1
On 24/11/2022 20:13, Jonathan Neuschäfer wrote:
> The Flash Interface Unit (FIU) is the SPI flash controller in the
> Nuvoton WPCM450 BMC SoC. It supports four chip selects, and direct
> (memory-mapped) access to 16 MiB per chip. Larger flash chips can be
> accessed by software-defined SPI transfers.
>
> The FIU in newer NPCM7xx SoCs is not compatible with the WPCM450 FIU.
>
> Signed-off-by: Jonathan Neuschäfer <[email protected]>
> ---
>
Reviewed-by: Krzysztof Kozlowski <[email protected]>
Best regards,
Krzysztof
On Thu, Nov 24, 2022 at 08:13:58PM +0100, Jonathan Neusch?fer wrote:
> The Flash Interface Unit (FIU) is the SPI flash controller in the
> Nuvoton WPCM450 BMC SoC. It supports four chip selects, and direct
> (memory-mapped) access to 16 MiB per chip. Larger flash chips can be
> accessed by software-defined SPI transfers.
You didn't send me the cover letter for this series. As documented in
submitting-patches.rst please send things to the maintainers for the
code you would like to change. The normal kernel workflow is that
people apply patches from their inboxes, if they aren't copied they are
likely to not see the patch at all and it is much more difficult to
apply patches.
On Fri, Nov 25, 2022 at 01:13:29PM +0000, Mark Brown wrote:
> On Thu, Nov 24, 2022 at 08:13:58PM +0100, Jonathan Neuschäfer wrote:
> > The Flash Interface Unit (FIU) is the SPI flash controller in the
> > Nuvoton WPCM450 BMC SoC. It supports four chip selects, and direct
> > (memory-mapped) access to 16 MiB per chip. Larger flash chips can be
> > accessed by software-defined SPI transfers.
>
> You didn't send me the cover letter for this series. As documented in
> submitting-patches.rst please send things to the maintainers for the
> code you would like to change. The normal kernel workflow is that
> people apply patches from their inboxes, if they aren't copied they are
> likely to not see the patch at all and it is much more difficult to
> apply patches.
Ah, sorry. I wrongly associated you with a different subsystem (I think
MFD), which became irrelevant for this iteration of the patchset,
rather than SPI.
Here's the relevant/new part of the cover letter, for your convenience:
Changelog for v2:
- Dropped the patches which have been applied in the meantime, leaving
only three out of eight
- Changed the binding to require both items in the reg property, because
there is no need to keep the second item optional, suggested by
Krzysztof Kozlowski
- Various other cleanups suggested by Krzysztof Kozlowski and the kernel
test robot
Jonathan
On Thu, 24 Nov 2022 20:13:58 +0100, Jonathan Neuschäfer wrote:
> The Flash Interface Unit (FIU) is the SPI flash controller in the
> Nuvoton WPCM450 BMC SoC. It supports four chip selects, and direct
> (memory-mapped) access to 16 MiB per chip. Larger flash chips can be
> accessed by software-defined SPI transfers.
>
> The FIU in newer NPCM7xx SoCs is not compatible with the WPCM450 FIU.
>
> Signed-off-by: Jonathan Neuschäfer <[email protected]>
> ---
>
> v2:
> - A few cleanups suggested by Krzysztof Kozlowski
> - Simplify binding by making second reg item mandatory
>
> v1:
> - https://lore.kernel.org/lkml/[email protected]/
> ---
> .../bindings/spi/nuvoton,wpcm450-fiu.yaml | 66 +++++++++++++++++++
> 1 file changed, 66 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dts:18:18: fatal error: dt-bindings/clock/nuvoton,wpcm450-clk.h: No such file or directory
18 | #include <dt-bindings/clock/nuvoton,wpcm450-clk.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:406: Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dtb] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1492: dt_binding_check] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/[email protected]
This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command.
On Sat, Nov 26, 2022 at 04:25:36PM -0600, Rob Herring wrote:
>
> On Thu, 24 Nov 2022 20:13:58 +0100, Jonathan Neusch?fer wrote:
> > The Flash Interface Unit (FIU) is the SPI flash controller in the
> > Nuvoton WPCM450 BMC SoC. It supports four chip selects, and direct
> > (memory-mapped) access to 16 MiB per chip. Larger flash chips can be
> > accessed by software-defined SPI transfers.
> >
> > The FIU in newer NPCM7xx SoCs is not compatible with the WPCM450 FIU.
> >
> > Signed-off-by: Jonathan Neusch?fer <[email protected]>
> > ---
> >
> > v2:
> > - A few cleanups suggested by Krzysztof Kozlowski
> > - Simplify binding by making second reg item mandatory
> >
> > v1:
> > - https://lore.kernel.org/lkml/[email protected]/
> > ---
> > .../bindings/spi/nuvoton,wpcm450-fiu.yaml | 66 +++++++++++++++++++
> > 1 file changed, 66 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.yaml
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dts:18:18: fatal error: dt-bindings/clock/nuvoton,wpcm450-clk.h: No such file or directory
> 18 | #include <dt-bindings/clock/nuvoton,wpcm450-clk.h>
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> compilation terminated.
> make[1]: *** [scripts/Makefile.lib:406: Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dtb] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1492: dt_binding_check] Error 2
FWIW this seems to now be in linux-next as dd71cd4dd6c9 ("spi: Add Nuvoton
WPCM450 Flash Interface Unit (FIU) bindings") & is breaking
dt_binding_check.
Thanks,
Conor.
On Mon, Nov 28, 2022 at 11:05:31AM +0000, Conor Dooley wrote:
> On Sat, Nov 26, 2022 at 04:25:36PM -0600, Rob Herring wrote:
[...]
> > dtschema/dtc warnings/errors:
> > Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dts:18:18: fatal error: dt-bindings/clock/nuvoton,wpcm450-clk.h: No such file or directory
> > 18 | #include <dt-bindings/clock/nuvoton,wpcm450-clk.h>
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > compilation terminated.
> > make[1]: *** [scripts/Makefile.lib:406: Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dtb] Error 1
> > make[1]: *** Waiting for unfinished jobs....
> > make: *** [Makefile:1492: dt_binding_check] Error 2
>
> FWIW this seems to now be in linux-next as dd71cd4dd6c9 ("spi: Add Nuvoton
> WPCM450 Flash Interface Unit (FIU) bindings") & is breaking
> dt_binding_check.
Ah, sorry about that. It should resolve itself once nuvoton,wpcm450-clk
binding gets merged, but I don't see a definite timeframe for that, yet.
Alternatively, I can send a patch to simplify the example in the FIU
binding.
Jonathan
On Mon, Nov 28, 2022 at 02:58:57PM +0100, Jonathan Neusch?fer wrote:
> On Mon, Nov 28, 2022 at 11:05:31AM +0000, Conor Dooley wrote:
> > On Sat, Nov 26, 2022 at 04:25:36PM -0600, Rob Herring wrote:
> [...]
> > > dtschema/dtc warnings/errors:
> > > Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dts:18:18: fatal error: dt-bindings/clock/nuvoton,wpcm450-clk.h: No such file or directory
> > > 18 | #include <dt-bindings/clock/nuvoton,wpcm450-clk.h>
> > > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > > compilation terminated.
> > > make[1]: *** [scripts/Makefile.lib:406: Documentation/devicetree/bindings/spi/nuvoton,wpcm450-fiu.example.dtb] Error 1
> > > make[1]: *** Waiting for unfinished jobs....
> > > make: *** [Makefile:1492: dt_binding_check] Error 2
> >
> > FWIW this seems to now be in linux-next as dd71cd4dd6c9 ("spi: Add Nuvoton
> > WPCM450 Flash Interface Unit (FIU) bindings") & is breaking
> > dt_binding_check.
>
> Ah, sorry about that. It should resolve itself once nuvoton,wpcm450-clk
> binding gets merged, but I don't see a definite timeframe for that, yet.
>
> Alternatively, I can send a patch to simplify the example in the FIU
> binding.
Without being a Responsible Adult^TM for either SPI or DT, my preference
would be for simplifying the binding so that if your clk stuff doesn't
land for 6.2 the binding checks still work.
On Mon, Nov 28, 2022 at 02:09:37PM +0000, Conor Dooley wrote:
> Without being a Responsible Adult^TM for either SPI or DT, my preference
> would be for simplifying the binding so that if your clk stuff doesn't
> land for 6.2 the binding checks still work.
Yes, please simplify the example.