M: Abdellatif El Khlifi <abdellatif.elkhlifi@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
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@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
--------------------------------
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@arm.com>
--- /dev/null
+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>;
+ };
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
# Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
obj-y += nvmxip-uclass.o nvmxip.o
+obj-$(CONFIG_NVMXIP_QSPI) += nvmxip_qspi.o
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
+ *
+ * Authors:
+ * Abdellatif El Khlifi <abdellatif.elkhlifi@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),
+};