Naming a fixed SCSI device number cannot express "use the currently activated boot LU". Offer the boot W-LU as an alternative source, so that flipping bBootLunEn between boot LU A and boot LU B moves U-Boot along with it and the SPL needs no reconfiguration.
Signed-off-by: Alexey Charkov <[email protected]> --- common/spl/Kconfig | 30 +++++++++++++++++++++++++++++- common/spl/spl_ufs.c | 18 ++++++++++++++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index d1e3c365ac9a..093bf55e6017 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1634,9 +1634,37 @@ config SPL_UFS_SUPPORT use of UFS devices such as hard drives and flash drivers for loading U-Boot. +choice + prompt "Source of the U-Boot image on UFS" + depends on SPL_UFS_SUPPORT + default SPL_UFS_RAW_U_BOOT_USE_DEVNUM + help + Pick how the SPL decides which UFS logical unit holds U-Boot. Either + name a logical unit outright, or let the device point at one of its + boot logical units through the boot well known logical unit. + +config SPL_UFS_RAW_U_BOOT_USE_DEVNUM + bool "A fixed SCSI device number" + help + Load U-Boot from the logical unit that shows up at a known SCSI device + number once the SPL has scanned the bus. + +config SPL_UFS_RAW_U_BOOT_USE_BOOT_WLUN + bool "The UFS boot well known logical unit" + help + Load U-Boot through the boot W-LU, which the device maps onto whichever + logical unit bBootLunEn currently selects (boot LU A or boot LU B). This + follows an A/B switch made by the device itself, so the SPL does not have + to know which of the two is active. + + Booting has to be enabled on the device (bBootLunEn is not 0), otherwise + the boot W-LU does not answer and the SPL will not find it. + +endchoice + 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 + depends on SPL_UFS_RAW_U_BOOT_USE_DEVNUM default 0 help UFS devices are usually configured with multiple LUNs, which present diff --git a/common/spl/spl_ufs.c b/common/spl/spl_ufs.c index cef1843f40f3..393736c7dc7c 100644 --- a/common/spl/spl_ufs.c +++ b/common/spl/spl_ufs.c @@ -8,6 +8,7 @@ #include <scsi.h> #include <errno.h> #include <image.h> +#include <ufs.h> #include <linux/compiler.h> #include <log.h> @@ -24,16 +25,25 @@ 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; + int devnum = config_opt_enabled(CONFIG_SPL_UFS_RAW_U_BOOT_USE_DEVNUM, + CONFIG_SPL_UFS_RAW_U_BOOT_DEVNUM, -1); 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; + if (CONFIG_IS_ENABLED(UFS_RAW_U_BOOT_USE_BOOT_WLUN)) { + /* A UFS controller only ever has a single target */ + if (scsi_get_blk_by_lun(0, UFS_UPIU_BOOT_WLUN, &bd)) { + puts("spl_ufs_load_image: UFS boot LU not found\n"); + return -ENODEV; + } + } else { + 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); -- 2.54.0
