[PATCH v2 2/7] drivers/mtd/nvmxip: introduce QSPI XIP driver

Abdellatif El Khlifi abdellatif.elkhlifi at arm.com
Mon Apr 17 11:11:53 CEST 2023


add nvmxip_qspi driver under UCLASS_NVMXIP

The device associated with this driver is the parent of the blk#<id> device
nvmxip_qspi can be reused by other platforms. If the platform
has custom settings to apply before using the flash, then the platform
can provide its own parent driver belonging to UCLASS_NVMXIP and reuse
nvmxip-blk driver. The custom driver can be implemented like nvmxip_qspi in
addition to the platform custom settings.

Platforms can use multiple NVM XIP devices at the same time by defining a
DT node for each one of them.

For more details please refer to doc/develop/driver-model/nvmxip_qspi.rst

Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi at arm.com>
---
 MAINTAINERS                                   |  1 +
 doc/develop/driver-model/nvmxip.rst           | 45 +++++++++++-
 .../nvmxip/nvmxip_qspi.txt                    | 56 +++++++++++++++
 drivers/mtd/nvmxip/Kconfig                    |  6 ++
 drivers/mtd/nvmxip/Makefile                   |  1 +
 drivers/mtd/nvmxip/nvmxip_qspi.c              | 70 +++++++++++++++++++
 6 files changed, 178 insertions(+), 1 deletion(-)
 create mode 100644 doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
 create mode 100644 drivers/mtd/nvmxip/nvmxip_qspi.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 39f143e60b..77acce79c5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1206,6 +1206,7 @@ NVMXIP
 M:	Abdellatif El Khlifi <abdellatif.elkhlifi at arm.com>
 S:	Maintained
 F:	doc/develop/driver-model/nvmxip.rst
+F:	doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
 F:	drivers/mtd/nvmxip/
 
 NVMEM
diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst
index fe087b13d2..09afdbcccf 100644
--- a/doc/develop/driver-model/nvmxip.rst
+++ b/doc/develop/driver-model/nvmxip.rst
@@ -25,7 +25,33 @@ The NVMXIP Uclass provides the following drivers:
         the Uclass creates a block device and binds it with the nvmxip-blk.
 	The Uclass driver implemented by drivers/mtd/nvmxip/nvmxip-uclass.c
 
-    The implementation is generic and can be used by different platforms.
+      nvmxip_qspi driver :
+
+        The driver probed with the DT and is the parent of the blk#<id> device.
+        nvmxip_qspi can be reused by other platforms. If the platform
+        has custom settings to apply before using the flash, then the platform
+        can provide its own parent driver belonging to UCLASS_NVMXIP and reuse
+        nvmxip-blk. The custom driver can be implemented like nvmxip_qspi in
+        addition to the platform custom settings.
+	The nvmxip_qspi driver belongs to UCLASS_NVMXIP.
+	The driver implemented by drivers/mtd/nvmxip/nvmxip_qspi.c
+
+	For example, if we have two NVMXIP devices described in the DT
+	The devices hierarchy is as follows:
+
+::
+
+   => dm tree
+
+        Class     Index  Probed  Driver                Name
+    -----------------------------------------------------------
+    ...
+     nvmxip        0  [ + ]   nvmxip_qspi           |-- nvmxip-qspi1 at 08000000
+     blk           3  [ + ]   nvmxip-blk                    |   `-- nvmxip-qspi1 at 08000000.blk#1
+     nvmxip        1  [ + ]   nvmxip_qspi           |-- nvmxip-qspi2 at 08200000
+     blk           4  [ + ]   nvmxip-blk                    |   `-- nvmxip-qspi2 at 08200000.blk#2
+
+The implementation is generic and can be used by different platforms.
 
 Supported hardware
 --------------------------------
@@ -43,6 +69,23 @@ config NVMXIP
 	  handles the read operation. This driver is HW agnostic and can support
 	  multiple flash devices at the same time.
 
+config NVMXIP_QSPI
+	  This option allows the emulation of a block storage device on top of a QSPI XIP flash.
+	  Any platform that needs to emulate one or multiple QSPI XIP flash devices can turn this
+	  option on to enable the functionality. NVMXIP config is selected automatically.
+	  Platforms that need to add custom treatments before accessing to the flash, can
+	  write their own driver (same as nvmxip_qspi in addition to the custom settings).
+
+Device Tree nodes
+--------------------
+
+Multiple QSPI XIP flash devices can be used at the same time by describing them through DT
+nodes.
+
+Please refer to the documentation of the DT binding at:
+
+doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
+
 Contributors
 ------------
    * Abdellatif El Khlifi <abdellatif.elkhlifi at arm.com>
diff --git a/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
new file mode 100644
index 0000000000..cc60e9efdc
--- /dev/null
+++ b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt
@@ -0,0 +1,56 @@
+Specifying NVMXIP information for devices
+======================================
+
+QSPI XIP flash device nodes
+---------------------------
+
+Each flash device should have its own node.
+
+Each node must specify the following fields:
+
+1)
+		compatible = "nvmxip,qspi";
+
+This allows to bind the flash device with the nvmxip_qspi driver
+If a platform has its own driver, please provide your own compatible
+string.
+
+2)
+		reg = <0x0 0x08000000 0x0 0x00200000>;
+
+The start address and size of the flash device. The values give here are an
+example (when the cell size is 2).
+
+When cell size is 1, the reg field looks like this:
+
+		reg = <0x08000000 0x00200000>;
+
+3)
+
+		lba_shift = <9>;
+
+The number of bit shifts used to calculate the size in bytes of one block.
+In this example the block size is 1 << 9 = 2 ^ 9 = 512 bytes
+
+4)
+
+		lba = <4096>;
+
+The number of blocks.
+
+Example of multiple flash devices
+----------------------------------------------------
+
+	nvmxip-qspi1 at 08000000 {
+		compatible = "nvmxip,qspi";
+		reg = <0x0 0x08000000 0x0 0x00200000>;
+		lba_shift = <9>;
+		lba = <4096>;
+	};
+
+	nvmxip-qspi2 at 08200000 {
+		compatible = "nvmxip,qspi";
+		reg = <0x0 0x08200000 0x0 0x00100000>;
+		lba_shift = <9>;
+		lba = <2048>;
+	};
diff --git a/drivers/mtd/nvmxip/Kconfig b/drivers/mtd/nvmxip/Kconfig
index ef53fc3c79..3ef7105026 100644
--- a/drivers/mtd/nvmxip/Kconfig
+++ b/drivers/mtd/nvmxip/Kconfig
@@ -11,3 +11,9 @@ config NVMXIP
 	  This option allows the emulation of a block storage device
 	  on top of a direct access non volatile memory XIP flash devices.
 	  This support provides the read operation.
+
+config NVMXIP_QSPI
+	bool "QSPI XIP  support"
+	select NVMXIP
+	help
+	  This option allows the emulation of a block storage device on top of a QSPI XIP flash
diff --git a/drivers/mtd/nvmxip/Makefile b/drivers/mtd/nvmxip/Makefile
index 07890982c7..54eacc102e 100644
--- a/drivers/mtd/nvmxip/Makefile
+++ b/drivers/mtd/nvmxip/Makefile
@@ -5,3 +5,4 @@
 #   Abdellatif El Khlifi <abdellatif.elkhlifi at arm.com>
 
 obj-y += nvmxip-uclass.o nvmxip.o
+obj-$(CONFIG_NVMXIP_QSPI) += nvmxip_qspi.o
diff --git a/drivers/mtd/nvmxip/nvmxip_qspi.c b/drivers/mtd/nvmxip/nvmxip_qspi.c
new file mode 100644
index 0000000000..7221fd1cb4
--- /dev/null
+++ b/drivers/mtd/nvmxip/nvmxip_qspi.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office at arm.com>
+ *
+ * Authors:
+ *   Abdellatif El Khlifi <abdellatif.elkhlifi at arm.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdt_support.h>
+#include <linux/errno.h>
+#include "nvmxip.h"
+
+#include <asm/global_data.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+#define NVMXIP_QSPI_DRV_NAME "nvmxip_qspi"
+
+/**
+ * nvmxip_qspi_of_to_plat() -read from DT
+ * @dev:	the NVMXIP device
+ *
+ * Read from the DT the NVMXIP information.
+ *
+ * Return:
+ *
+ * 0 on success. Otherwise, failure
+ */
+static int nvmxip_qspi_of_to_plat(struct udevice *dev)
+{
+	struct nvmxip_plat *plat = dev_get_plat(dev);
+	int ret;
+
+	plat->phys_base = (phys_addr_t)dev_read_addr(dev);
+	if (plat->phys_base == FDT_ADDR_T_NONE) {
+		log_err("[%s]: can not get base address from device tree\n", dev->name);
+		return -EINVAL;
+	}
+
+	ret = dev_read_u32(dev, "lba_shift", &plat->lba_shift);
+	if (ret) {
+		log_err("[%s]: can not get lba_shift from device tree\n", dev->name);
+		return -EINVAL;
+	}
+
+	ret = dev_read_u32(dev, "lba", (u32 *)&plat->lba);
+	if (ret) {
+		log_err("[%s]: can not get lba from device tree\n", dev->name);
+		return -EINVAL;
+	}
+
+	log_debug("[%s]: XIP device base addr: 0x%llx , lba_shift: %d , lbas: %lu\n",
+		  dev->name, plat->phys_base, plat->lba_shift, plat->lba);
+
+	return 0;
+}
+
+static const struct udevice_id nvmxip_qspi_ids[] = {
+	{ .compatible = "nvmxip,qspi" },
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(nvmxip_qspi) = {
+	.name = NVMXIP_QSPI_DRV_NAME,
+	.id = UCLASS_NVMXIP,
+	.of_match = nvmxip_qspi_ids,
+	.of_to_plat = nvmxip_qspi_of_to_plat,
+	.plat_auto = sizeof(struct nvmxip_plat),
+};
-- 
2.25.1



More information about the U-Boot mailing list