summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch455
1 files changed, 455 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch
new file mode 100644
index 0000000000..721ee15665
--- /dev/null
+++ b/meta-arm/meta-arm-bsp/recipes-bsp/u-boot/u-boot/corstone1000/0027-drivers-mtd-nvmxip-introduce-NVM-XIP-block-storage-e.patch
@@ -0,0 +1,455 @@
+From c7567aaf75a66e204d492a8f6e2a3b4bfb8a7e45 Mon Sep 17 00:00:00 2001
+From: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
+Date: Fri, 14 Apr 2023 13:23:25 +0100
+Subject: [PATCH 27/42] 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 <abdellatif.elkhlifi@arm.com>
+Upstream-Status: Backport [https://github.com/u-boot/u-boot/commit/c9c2c95d4cd27fe0cd41fe13a863899d268f973c]
+---
+ MAINTAINERS | 6 ++
+ doc/develop/driver-model/index.rst | 1 +
+ doc/develop/driver-model/nvmxip.rst | 48 +++++++++++
+ drivers/block/blk-uclass.c | 1 +
+ drivers/mtd/Kconfig | 2 +
+ drivers/mtd/Makefile | 1 +
+ drivers/mtd/nvmxip/Kconfig | 13 +++
+ drivers/mtd/nvmxip/Makefile | 7 ++
+ drivers/mtd/nvmxip/nvmxip-uclass.c | 67 ++++++++++++++++
+ drivers/mtd/nvmxip/nvmxip.c | 119 ++++++++++++++++++++++++++++
+ drivers/mtd/nvmxip/nvmxip.h | 32 ++++++++
+ include/dm/uclass-id.h | 1 +
+ 12 files changed, 298 insertions(+)
+ create mode 100644 doc/develop/driver-model/nvmxip.rst
+ create mode 100644 drivers/mtd/nvmxip/Kconfig
+ create mode 100644 drivers/mtd/nvmxip/Makefile
+ create mode 100644 drivers/mtd/nvmxip/nvmxip-uclass.c
+ create mode 100644 drivers/mtd/nvmxip/nvmxip.c
+ create mode 100644 drivers/mtd/nvmxip/nvmxip.h
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index a2f60a3b93..1dbfab5f43 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1202,6 +1202,12 @@ F: cmd/nvme.c
+ F: include/nvme.h
+ F: doc/develop/driver-model/nvme.rst
+
++NVMXIP
++M: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
++S: Maintained
++F: doc/develop/driver-model/nvmxip.rst
++F: drivers/mtd/nvmxip/
++
+ NVMEM
+ M: Sean Anderson <seanga2@gmail.com>
+ S: Maintained
+diff --git a/doc/develop/driver-model/index.rst b/doc/develop/driver-model/index.rst
+index 7366ef818c..8e12bbd936 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 0000000000..fe087b13d2
+--- /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 <abdellatif.elkhlifi@arm.com>
+diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
+index c69fc4d518..e8ab576c32 100644
+--- a/drivers/block/blk-uclass.c
++++ b/drivers/block/blk-uclass.c
+@@ -28,6 +28,7 @@ static struct {
+ { UCLASS_AHCI, "sata" },
+ { UCLASS_HOST, "host" },
+ { UCLASS_NVME, "nvme" },
++ { UCLASS_NVMXIP, "nvmxip" },
+ { UCLASS_EFI_MEDIA, "efi" },
+ { UCLASS_EFI_LOADER, "efiloader" },
+ { UCLASS_VIRTIO, "virtio" },
+diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
+index fcdb450f77..0537ac64e3 100644
+--- a/drivers/mtd/Kconfig
++++ b/drivers/mtd/Kconfig
+@@ -224,4 +224,6 @@ source "drivers/mtd/spi/Kconfig"
+
+ source "drivers/mtd/ubi/Kconfig"
+
++source "drivers/mtd/nvmxip/Kconfig"
++
+ endmenu
+diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
+index 3a78590aaa..c638980ea2 100644
+--- a/drivers/mtd/Makefile
++++ b/drivers/mtd/Makefile
+@@ -25,6 +25,7 @@ obj-y += nand/
+ obj-y += onenand/
+ obj-y += spi/
+ obj-$(CONFIG_MTD_UBI) += ubi/
++obj-$(CONFIG_NVMXIP) += nvmxip/
+
+ #SPL/TPL build
+ else
+diff --git a/drivers/mtd/nvmxip/Kconfig b/drivers/mtd/nvmxip/Kconfig
+new file mode 100644
+index 0000000000..ef53fc3c79
+--- /dev/null
++++ b/drivers/mtd/nvmxip/Kconfig
+@@ -0,0 +1,13 @@
++# 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>
++
++config NVMXIP
++ bool "NVM XIP devices support"
++ select BLK
++ help
++ 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.
+diff --git a/drivers/mtd/nvmxip/Makefile b/drivers/mtd/nvmxip/Makefile
+new file mode 100644
+index 0000000000..07890982c7
+--- /dev/null
++++ b/drivers/mtd/nvmxip/Makefile
+@@ -0,0 +1,7 @@
++# 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>
++
++obj-y += nvmxip-uclass.o nvmxip.o
+diff --git a/drivers/mtd/nvmxip/nvmxip-uclass.c b/drivers/mtd/nvmxip/nvmxip-uclass.c
+new file mode 100644
+index 0000000000..9f96041e3d
+--- /dev/null
++++ b/drivers/mtd/nvmxip/nvmxip-uclass.c
+@@ -0,0 +1,67 @@
++// 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 <log.h>
++#include <linux/bitops.h>
++#include "nvmxip.h"
++
++/* LBA Macros */
++
++#define DEFAULT_LBA_SHIFT 10 /* 1024 bytes per block */
++#define DEFAULT_LBA_COUNT 1024 /* block count */
++
++#define DEFAULT_LBA_SZ BIT(DEFAULT_LBA_SHIFT)
++
++/**
++ * nvmxip_post_bind() - post binding treatments
++ * @dev: the NVMXIP device
++ *
++ * Create and probe a child block device.
++ *
++ * Return:
++ *
++ * 0 on success. Otherwise, failure
++ */
++static int nvmxip_post_bind(struct udevice *udev)
++{
++ int ret;
++ struct udevice *bdev = NULL;
++ char bdev_name[NVMXIP_BLKDEV_NAME_SZ + 1];
++ int devnum;
++
++ devnum = uclass_id_count(UCLASS_NVMXIP);
++ snprintf(bdev_name, NVMXIP_BLKDEV_NAME_SZ, "blk#%d", devnum);
++
++ ret = blk_create_devicef(udev, NVMXIP_BLKDRV_NAME, bdev_name, UCLASS_NVMXIP,
++ devnum, DEFAULT_LBA_SZ,
++ DEFAULT_LBA_COUNT, &bdev);
++ if (ret) {
++ log_err("[%s]: failure during creation of the block device %s, error %d\n",
++ udev->name, bdev_name, ret);
++ return ret;
++ }
++
++ ret = blk_probe_or_unbind(bdev);
++ if (ret) {
++ log_err("[%s]: failure during probing the block device %s, error %d\n",
++ udev->name, bdev_name, ret);
++ return ret;
++ }
++
++ log_info("[%s]: the block device %s ready for use\n", udev->name, bdev_name);
++
++ return 0;
++}
++
++UCLASS_DRIVER(nvmxip) = {
++ .name = "nvmxip",
++ .id = UCLASS_NVMXIP,
++ .post_bind = nvmxip_post_bind,
++};
+diff --git a/drivers/mtd/nvmxip/nvmxip.c b/drivers/mtd/nvmxip/nvmxip.c
+new file mode 100644
+index 0000000000..a359e3b482
+--- /dev/null
++++ b/drivers/mtd/nvmxip/nvmxip.c
+@@ -0,0 +1,119 @@
++// 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 <log.h>
++#include <mapmem.h>
++#include <asm/io.h>
++#include <linux/bitops.h>
++#include <linux/errno.h>
++#include "nvmxip.h"
++
++/**
++ * nvmxip_mmio_rawread() - read from the XIP flash
++ * @address: address of the data
++ * @value: pointer to where storing the value read
++ *
++ * Read raw data from the XIP flash.
++ *
++ * Return:
++ *
++ * Always return 0.
++ */
++static int nvmxip_mmio_rawread(const phys_addr_t address, u64 *value)
++{
++ *value = readq(address);
++ return 0;
++}
++
++/**
++ * nvmxip_blk_read() - block device read operation
++ * @dev: the block device
++ * @blknr: first block number to read from
++ * @blkcnt: number of blocks to read
++ * @buffer: destination buffer
++ *
++ * Read data from the block storage device.
++ *
++ * Return:
++ *
++ * number of blocks read on success. Otherwise, failure
++ */
++static ulong nvmxip_blk_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
++{
++ struct nvmxip_plat *plat = dev_get_plat(dev->parent);
++ struct blk_desc *desc = dev_get_uclass_plat(dev);
++ /* number of the u64 words to read */
++ u32 qwords = (blkcnt * desc->blksz) / sizeof(u64);
++ /* physical address of the first block to read */
++ phys_addr_t blkaddr = plat->phys_base + blknr * desc->blksz;
++ u64 *virt_blkaddr;
++ u64 *pdst = buffer;
++ uint qdata_idx;
++
++ if (!pdst)
++ return -EINVAL;
++
++ log_debug("[%s]: reading from blknr: %lu , blkcnt: %lu\n", dev->name, blknr, blkcnt);
++
++ virt_blkaddr = map_sysmem(blkaddr, 0);
++
++ /* assumption: the data is virtually contiguous */
++
++ for (qdata_idx = 0 ; qdata_idx < qwords ; qdata_idx++)
++ nvmxip_mmio_rawread((phys_addr_t)(virt_blkaddr + qdata_idx), pdst++);
++
++ log_debug("[%s]: src[0]: 0x%llx , dst[0]: 0x%llx , src[-1]: 0x%llx , dst[-1]: 0x%llx\n",
++ dev->name,
++ *virt_blkaddr,
++ *(u64 *)buffer,
++ *(u64 *)((u8 *)virt_blkaddr + desc->blksz * blkcnt - sizeof(u64)),
++ *(u64 *)((u8 *)buffer + desc->blksz * blkcnt - sizeof(u64)));
++
++ unmap_sysmem(virt_blkaddr);
++
++ return blkcnt;
++}
++
++/**
++ * nvmxip_blk_probe() - block storage device probe
++ * @dev: the block storage device
++ *
++ * Initialize the block storage descriptor.
++ *
++ * Return:
++ *
++ * Always return 0.
++ */
++static int nvmxip_blk_probe(struct udevice *dev)
++{
++ struct nvmxip_plat *plat = dev_get_plat(dev->parent);
++ struct blk_desc *desc = dev_get_uclass_plat(dev);
++
++ desc->lba = plat->lba;
++ desc->log2blksz = plat->lba_shift;
++ desc->blksz = BIT(plat->lba_shift);
++ desc->bdev = dev;
++
++ log_debug("[%s]: block storage layout\n lbas: %lu , log2blksz: %d, blksz: %lu\n",
++ dev->name, desc->lba, desc->log2blksz, desc->blksz);
++
++ return 0;
++}
++
++static const struct blk_ops nvmxip_blk_ops = {
++ .read = nvmxip_blk_read,
++};
++
++U_BOOT_DRIVER(nvmxip_blk) = {
++ .name = NVMXIP_BLKDRV_NAME,
++ .id = UCLASS_BLK,
++ .probe = nvmxip_blk_probe,
++ .ops = &nvmxip_blk_ops,
++};
+diff --git a/drivers/mtd/nvmxip/nvmxip.h b/drivers/mtd/nvmxip/nvmxip.h
+new file mode 100644
+index 0000000000..f4ef37725d
+--- /dev/null
++++ b/drivers/mtd/nvmxip/nvmxip.h
+@@ -0,0 +1,32 @@
++/* 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>
++ */
++
++#ifndef __DRIVER_NVMXIP_H__
++#define __DRIVER_NVMXIP_H__
++
++#include <blk.h>
++
++#define NVMXIP_BLKDRV_NAME "nvmxip-blk"
++#define NVMXIP_BLKDEV_NAME_SZ 20
++
++/**
++ * struct nvmxip_plat - the NVMXIP driver plat
++ *
++ * @phys_base: NVM XIP device base address
++ * @lba_shift: block size shift count
++ * @lba: number of blocks
++ *
++ * The NVMXIP information read from the DT.
++ */
++struct nvmxip_plat {
++ phys_addr_t phys_base;
++ u32 lba_shift;
++ lbaint_t lba;
++};
++
++#endif /* __DRIVER_NVMXIP_H__ */
+diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
+index fa08a66ac8..f3564a49d9 100644
+--- a/include/dm/uclass-id.h
++++ b/include/dm/uclass-id.h
+@@ -92,6 +92,7 @@ enum uclass_id {
+ UCLASS_NOP, /* No-op devices */
+ UCLASS_NORTHBRIDGE, /* Intel Northbridge / SDRAM controller */
+ UCLASS_NVME, /* NVM Express device */
++ UCLASS_NVMXIP, /* NVM XIP devices */
+ UCLASS_P2SB, /* (x86) Primary-to-Sideband Bus */
+ UCLASS_PANEL, /* Display panel, such as an LCD */
+ UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
+--
+2.25.1
+