From f37af2760ea92cec3fbdcfceb6df7be57a618165 Mon Sep 17 00:00:00 2001 From: Abdellatif El Khlifi Date: Mon, 17 Apr 2023 10:11:52 +0100 Subject: drivers/mtd/nvmxip: introduce NVM XIP block storage emulation add block storage emulation for NVM XIP flash devices Some paltforms such as Corstone-1000 need to see NVM XIP raw flash as a block storage device with read only capability. Here NVM flash devices are devices with addressable memory (e.g: QSPI NOR flash). The implementation is generic and can be used by different platforms. Two drivers are provided as follows. nvmxip-blk : a generic block driver allowing to read from the XIP flash nvmxip Uclass driver : When a device is described in the DT and associated with UCLASS_NVMXIP, the Uclass creates a block device and binds it with the nvmxip-blk. Platforms can use multiple NVM XIP devices at the same time by defining a DT node for each one of them. Signed-off-by: Abdellatif El Khlifi --- doc/develop/driver-model/index.rst | 1 + doc/develop/driver-model/nvmxip.rst | 48 +++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 doc/develop/driver-model/nvmxip.rst (limited to 'doc/develop') diff --git a/doc/develop/driver-model/index.rst b/doc/develop/driver-model/index.rst index 7366ef818c5..8e12bbd9366 100644 --- a/doc/develop/driver-model/index.rst +++ b/doc/develop/driver-model/index.rst @@ -20,6 +20,7 @@ subsystems livetree migration nvme + nvmxip of-plat pci-info pmic-framework diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst new file mode 100644 index 00000000000..fe087b13d22 --- /dev/null +++ b/doc/develop/driver-model/nvmxip.rst @@ -0,0 +1,48 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +NVM XIP Block Storage Emulation Driver +======================================= + +Summary +------- + +Non-Volatile Memory devices with addressable memory (e.g: QSPI NOR flash) could +be used for block storage needs (e.g: parsing a GPT layout in a raw QSPI NOR flash). + +The NVMXIP Uclass provides this functionality and can be used for any 64-bit platform. + +The NVMXIP Uclass provides the following drivers: + + nvmxip-blk block driver: + + A generic block driver allowing to read from the XIP flash. + The driver belongs to UCLASS_BLK. + The driver implemented by drivers/mtd/nvmxip/nvmxip.c + + nvmxip Uclass driver: + + When a device is described in the DT and associated with UCLASS_NVMXIP, + 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. + +Supported hardware +-------------------------------- + +Any 64-bit plaform. + +Configuration +---------------------- + +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. + This option provides the block storage driver nvmxip-blk which + handles the read operation. This driver is HW agnostic and can support + multiple flash devices at the same time. + +Contributors +------------ + * Abdellatif El Khlifi -- cgit v1.3.1 From 9e115ace358d9ed79844b27b06b3a0e8b23d49da Mon Sep 17 00:00:00 2001 From: Abdellatif El Khlifi Date: Mon, 17 Apr 2023 10:11:53 +0100 Subject: drivers/mtd/nvmxip: introduce QSPI XIP driver add nvmxip_qspi driver under UCLASS_NVMXIP The device associated with this driver is the parent of the blk# 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 --- MAINTAINERS | 1 + doc/develop/driver-model/nvmxip.rst | 45 +++++++++++++++- doc/device-tree-bindings/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 (limited to 'doc/develop') diff --git a/MAINTAINERS b/MAINTAINERS index fe87b39939f..fd155ca8788 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1208,6 +1208,7 @@ NVMXIP M: Abdellatif El Khlifi 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 fe087b13d22..09afdbcccf5 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# 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@08000000 + blk 3 [ + ] nvmxip-blk | `-- nvmxip-qspi1@08000000.blk#1 + nvmxip 1 [ + ] nvmxip_qspi |-- nvmxip-qspi2@08200000 + blk 4 [ + ] nvmxip-blk | `-- nvmxip-qspi2@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 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 00000000000..cc60e9efdcd --- /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@08000000 { + compatible = "nvmxip,qspi"; + reg = <0x0 0x08000000 0x0 0x00200000>; + lba_shift = <9>; + lba = <4096>; + }; + + nvmxip-qspi2@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 ef53fc3c790..3ef71050264 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 07890982c7e..54eacc102e6 100644 --- a/drivers/mtd/nvmxip/Makefile +++ b/drivers/mtd/nvmxip/Makefile @@ -5,3 +5,4 @@ # Abdellatif El Khlifi 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 00000000000..7221fd1cb46 --- /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 + * + * Authors: + * Abdellatif El Khlifi + */ + +#include +#include +#include +#include +#include "nvmxip.h" + +#include +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), +}; -- cgit v1.3.1 From cc89b7cf419223a746ab3cfc5741a19cd40ebabe Mon Sep 17 00:00:00 2001 From: Abdellatif El Khlifi Date: Mon, 17 Apr 2023 10:11:55 +0100 Subject: sandbox64: add support for NVMXIP QSPI enable NVMXIP QSPI for sandbox 64-bit Adding two NVM XIP QSPI storage devices. Signed-off-by: Abdellatif El Khlifi Reviewed-by: Simon Glass --- arch/sandbox/dts/sandbox64.dts | 13 +++++++++++++ arch/sandbox/dts/test.dts | 14 ++++++++++++++ configs/sandbox64_defconfig | 1 + doc/develop/driver-model/nvmxip.rst | 2 +- doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt | 6 +++--- drivers/mtd/nvmxip/nvmxip-uclass.c | 7 +++++++ 6 files changed, 39 insertions(+), 4 deletions(-) (limited to 'doc/develop') diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts index f21fc181f37..195365580a7 100644 --- a/arch/sandbox/dts/sandbox64.dts +++ b/arch/sandbox/dts/sandbox64.dts @@ -89,6 +89,19 @@ cs-gpios = <0>, <&gpio_a 0>; }; + nvmxip-qspi1@08000000 { + compatible = "nvmxip,qspi"; + reg = /bits/ 64 <0x08000000 0x00200000>; + lba_shift = <9>; + lba = <4096>; + }; + + nvmxip-qspi2@08200000 { + compatible = "nvmxip,qspi"; + reg = /bits/ 64 <0x08200000 0x00100000>; + lba_shift = <9>; + lba = <2048>; + }; }; #include "sandbox.dtsi" diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 7c1ee71cb7c..bcdea0b8e7b 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1802,6 +1802,20 @@ compatible = "u-boot,fwu-mdata-gpt"; fwu-mdata-store = <&mmc0>; }; + + nvmxip-qspi1@08000000 { + compatible = "nvmxip,qspi"; + reg = <0x08000000 0x00200000>; + lba_shift = <9>; + lba = <4096>; + }; + + nvmxip-qspi2@08200000 { + compatible = "nvmxip,qspi"; + reg = <0x08200000 0x00100000>; + lba_shift = <9>; + lba = <2048>; + }; }; #include "sandbox_pmic.dtsi" diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index af2c56ad4c6..bb877b6a587 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -260,3 +260,4 @@ CONFIG_FWU_MULTI_BANK_UPDATE=y CONFIG_UNIT_TEST=y CONFIG_UT_TIME=y CONFIG_UT_DM=y +CONFIG_NVMXIP_QSPI=y diff --git a/doc/develop/driver-model/nvmxip.rst b/doc/develop/driver-model/nvmxip.rst index 09afdbcccf5..e85dc220b9c 100644 --- a/doc/develop/driver-model/nvmxip.rst +++ b/doc/develop/driver-model/nvmxip.rst @@ -56,7 +56,7 @@ The implementation is generic and can be used by different platforms. Supported hardware -------------------------------- -Any 64-bit plaform. +Any plaform supporting readq(). Configuration ---------------------- diff --git a/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt index cc60e9efdcd..882728d5413 100644 --- a/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt +++ b/doc/device-tree-bindings/nvmxip/nvmxip_qspi.txt @@ -16,7 +16,7 @@ If a platform has its own driver, please provide your own compatible string. 2) - reg = <0x0 0x08000000 0x0 0x00200000>; + reg = /bits/ 64 <0x08000000 0x00200000>; The start address and size of the flash device. The values give here are an example (when the cell size is 2). @@ -43,14 +43,14 @@ Example of multiple flash devices nvmxip-qspi1@08000000 { compatible = "nvmxip,qspi"; - reg = <0x0 0x08000000 0x0 0x00200000>; + reg = /bits/ 64 <0x08000000 0x00200000>; lba_shift = <9>; lba = <4096>; }; nvmxip-qspi2@08200000 { compatible = "nvmxip,qspi"; - reg = <0x0 0x08200000 0x0 0x00100000>; + reg = /bits/ 64 <0x08200000 0x00100000>; lba_shift = <9>; lba = <2048>; }; diff --git a/drivers/mtd/nvmxip/nvmxip-uclass.c b/drivers/mtd/nvmxip/nvmxip-uclass.c index 9f96041e3d8..6d8eb177b50 100644 --- a/drivers/mtd/nvmxip/nvmxip-uclass.c +++ b/drivers/mtd/nvmxip/nvmxip-uclass.c @@ -9,6 +9,9 @@ #include #include #include +#if CONFIG_IS_ENABLED(SANDBOX64) +#include +#endif #include #include "nvmxip.h" @@ -36,6 +39,10 @@ static int nvmxip_post_bind(struct udevice *udev) char bdev_name[NVMXIP_BLKDEV_NAME_SZ + 1]; int devnum; +#if CONFIG_IS_ENABLED(SANDBOX64) + sandbox_set_enable_memio(true); +#endif + devnum = uclass_id_count(UCLASS_NVMXIP); snprintf(bdev_name, NVMXIP_BLKDEV_NAME_SZ, "blk#%d", devnum); -- cgit v1.3.1