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 <neil.armstrong@linaro.org>
Signed-off-by: Alexey Charkov <alchark@gmail.com>
Link: https://patch.msgid.link/20260120-rk3576-ufs-v5-1-0edb61b301b7@gmail.com
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
This commit is contained in:
Alexey Charkov
2026-01-20 22:09:02 +04:00
committed by Neil Armstrong
parent d908dd98de
commit c664b4d5f3
8 changed files with 87 additions and 0 deletions

View File

@@ -1893,6 +1893,7 @@ M: Neil Armstrong <neil.armstrong@linaro.org>
M: Bhupesh Sharma <bhupesh.linux@gmail.com>
M: Neha Malcom Francis <n-francis@ti.com>
S: Maintained
F: common/spl/spl_ufs.c
F: drivers/ufs/
UPL

View File

@@ -30,6 +30,7 @@ enum {
BOOT_DEVICE_XIP,
BOOT_DEVICE_BOOTROM,
BOOT_DEVICE_SMH,
BOOT_DEVICE_UFS,
BOOT_DEVICE_NONE
};
#endif

View File

@@ -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

View File

@@ -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

49
common/spl/spl_ufs.c Normal file
View File

@@ -0,0 +1,49 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2025 Alexey Charkov <alchark@gmail.com>
*/
#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);

View File

@@ -73,6 +73,7 @@ obj-$(CONFIG_SPL_USB_HOST) += usb/host/
obj-$(CONFIG_SPL_SATA) += ata/ scsi/
obj-$(CONFIG_SPL_LEGACY_BLOCK) += block/
obj-$(CONFIG_SPL_THERMAL) += thermal/
obj-$(CONFIG_SPL_UFS_SUPPORT) += scsi/ ufs/
endif
endif

View File

@@ -16,4 +16,7 @@ ifdef CONFIG_XPL_BUILD
ifdef CONFIG_SPL_SATA
obj-$(CONFIG_SCSI) += scsi.o scsi-uclass.o
endif
ifdef CONFIG_SPL_UFS_SUPPORT
obj-$(CONFIG_SCSI) += scsi.o scsi-uclass.o
endif
endif

View File

@@ -147,6 +147,7 @@ else
obj-$(CONFIG_$(PHASE_)SPRINTF) += vsprintf.o
endif
obj-$(CONFIG_$(PHASE_)STRTO) += strto.o
obj-$(CONFIG_$(PHASE_)UFS_SUPPORT) += charset.o
else
# Main U-Boot always uses the full printf support
obj-y += vsprintf.o strto.o