summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorAlexey Charkov <[email protected]>2026-01-20 22:09:02 +0400
committerNeil Armstrong <[email protected]>2026-03-12 09:30:44 +0100
commitc664b4d5f30a704003b97823a5ad6361cb16fbe8 (patch)
tree166fe6f013e4e1f25b503ef69132ebc8752e2582 /common
parentd908dd98de5c335a213d882746d033158db02cce (diff)
spl: Make UFS available for SPL builds
Add minimal infrastructure to build SPL images with support for UFS storage devices. This also pulls in SCSI support and charset functions, which are dependencies of the UFS code. With this, only a fixed offset is supported for loading the next image, which should be specified in CONFIG_SPL_UFS_RAW_U_BOOT_SECTOR as the number of 4096-byte sectors into the UFS block device. Reviewed-by: Neil Armstrong <[email protected]> Signed-off-by: Alexey Charkov <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Neil Armstrong <[email protected]>
Diffstat (limited to 'common')
-rw-r--r--common/spl/Kconfig30
-rw-r--r--common/spl/Makefile1
-rw-r--r--common/spl/spl_ufs.c49
3 files changed, 80 insertions, 0 deletions
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 996c9b8db4f..dafc0cb91bd 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1613,6 +1613,36 @@ config SPL_THERMAL
automatic power-off when the temperature gets too high or low. Other
devices may be discrete but connected on a suitable bus.
+config SPL_UFS_SUPPORT
+ bool "Support loading from UFS"
+ depends on UFS
+ select SPL_LOAD_BLOCK
+ help
+ Enable support for UFS in SPL. This allows
+ use of UFS devices such as hard drives and flash drivers for
+ loading U-Boot.
+
+config SPL_UFS_RAW_U_BOOT_DEVNUM
+ int "SCSI device number of the UFS device to load U-Boot from"
+ depends on SPL_UFS_SUPPORT
+ default 0
+ help
+ UFS devices are usually configured with multiple LUNs, which present
+ themselves as sequentially numbered SCSI devices. Usually one would
+ get a default LUN 0 taking up most of the space on the device, with
+ a number of smaller LUNs following it. This option controls which of
+ them the SPL will attempt to load U-Boot from. Note that this is the
+ SCSI device number, which might differ from the UFS LUN if you have
+ multiple SCSI devices attached and recognized by the SPL.
+
+config SPL_UFS_RAW_U_BOOT_SECTOR
+ hex "Address on the UFS to load U-Boot from"
+ depends on SPL_UFS_SUPPORT
+ default 0x800 if ARCH_ROCKCHIP
+ help
+ Address on the block device to load U-Boot from.
+ Units: UFS sectors (1 sector = 4096 bytes).
+
config SPL_WATCHDOG
bool "Support watchdog drivers"
imply SPL_WDT if !HW_WATCHDOG
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 4c9482bd309..e18f3cf0948 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_$(PHASE_)DFU) += spl_dfu.o
obj-$(CONFIG_$(PHASE_)SPI_LOAD) += spl_spi.o
obj-$(CONFIG_$(PHASE_)RAM_SUPPORT) += spl_ram.o
obj-$(CONFIG_$(PHASE_)USB_SDP_SUPPORT) += spl_sdp.o
+obj-$(CONFIG_$(PHASE_)UFS_SUPPORT) += spl_ufs.o
endif
obj-$(CONFIG_$(PHASE_)UPL) += spl_upl.o
diff --git a/common/spl/spl_ufs.c b/common/spl/spl_ufs.c
new file mode 100644
index 00000000000..cef1843f40f
--- /dev/null
+++ b/common/spl/spl_ufs.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2025 Alexey Charkov <[email protected]>
+ */
+
+#include <spl.h>
+#include <spl_load.h>
+#include <scsi.h>
+#include <errno.h>
+#include <image.h>
+#include <linux/compiler.h>
+#include <log.h>
+
+static ulong spl_ufs_load_read(struct spl_load_info *load, ulong off, ulong size, void *buf)
+{
+ struct blk_desc *bd = load->priv;
+ lbaint_t sector = off >> bd->log2blksz;
+ lbaint_t count = size >> bd->log2blksz;
+
+ return blk_dread(bd, sector, count, buf) << bd->log2blksz;
+}
+
+static int spl_ufs_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ unsigned long sector = CONFIG_SPL_UFS_RAW_U_BOOT_SECTOR;
+ int devnum = CONFIG_SPL_UFS_RAW_U_BOOT_DEVNUM;
+ struct spl_load_info load;
+ struct blk_desc *bd;
+ int err;
+
+ /* try to recognize storage devices immediately */
+ scsi_scan(false);
+ bd = blk_get_devnum_by_uclass_id(UCLASS_SCSI, devnum);
+ if (!bd)
+ return -ENODEV;
+
+ spl_load_init(&load, spl_ufs_load_read, bd, bd->blksz);
+ err = spl_load(spl_image, bootdev, &load, 0, sector << bd->log2blksz);
+ if (err) {
+ puts("spl_ufs_load_image: ufs block read error\n");
+ log_debug("(error=%d)\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+SPL_LOAD_IMAGE_METHOD("UFS", 0, BOOT_DEVICE_UFS, spl_ufs_load_image);