From 4a6f536e4248e2bdc853250e7b9cbd1badb7cfe6 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Sun, 25 Dec 2022 22:20:04 +0100 Subject: ARM: Rockchip: make bootsource logic generic to all SoCs Decoding of the bootsource from the register value can be shared across multiple Rockchip SoCs. Move the code to a common place to allow for that. At least with some TF-A versions the IRAM where the bootsource is stored cannot not be accessed in normal mode, so read it out before we start the TF-A. For this the scratch space is used. Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- arch/arm/mach-rockchip/Makefile | 2 +- arch/arm/mach-rockchip/atf.c | 3 +++ arch/arm/mach-rockchip/bootrom.c | 51 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-rockchip/rk3568.c | 29 ++--------------------- include/bootsource.h | 1 + include/mach/rockchip/bootrom.h | 32 +++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 arch/arm/mach-rockchip/bootrom.c create mode 100644 include/mach/rockchip/bootrom.h diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index f6c575854e..04d75ce287 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only -obj-y += rockchip.o +obj-y += rockchip.o bootrom.o pbl-$(CONFIG_ARCH_ROCKCHIP_ATF) += atf.o obj-$(CONFIG_ARCH_RK3188) += rk3188.o obj-$(CONFIG_ARCH_RK3288) += rk3288.o diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c index 9735cb8ef3..f3fb50b990 100644 --- a/arch/arm/mach-rockchip/atf.c +++ b/arch/arm/mach-rockchip/atf.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include static unsigned long load_elf64_image_phdr(const void *elf) { @@ -82,6 +84,7 @@ void __noreturn rk3568_barebox_entry(void *fdt) if (current_el() == 3) { rk3568_lowlevel_init(); + rockchip_store_bootrom_iram(membase, memsize, IOMEM(RK3568_IRAM_BASE)); rk3568_atf_load_bl31(fdt); /* not reached when CONFIG_ARCH_ROCKCHIP_ATF */ } diff --git a/arch/arm/mach-rockchip/bootrom.c b/arch/arm/mach-rockchip/bootrom.c new file mode 100644 index 0000000000..cdd0536cda --- /dev/null +++ b/arch/arm/mach-rockchip/bootrom.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include +#include +#include + +#define BROM_BOOTSOURCE_ID 0x10 +#define BROM_BOOTSOURCE_SLOT 0x14 +#define BROM_BOOTSOURCE_SLOT_ACTIVE GENMASK(12, 10) + +static const void __iomem *rk_iram; + +int rockchip_bootsource_get_active_slot(void) +{ + if (!rk_iram) + return -EINVAL; + + return FIELD_GET(BROM_BOOTSOURCE_SLOT_ACTIVE, + readl(IOMEM(rk_iram) + BROM_BOOTSOURCE_SLOT)); +} + +struct rk_bootsource { + enum bootsource src; + int instance; +}; + +static struct rk_bootsource bootdev_map[] = { + [0x1] = { .src = BOOTSOURCE_NAND, .instance = 0 }, + [0x2] = { .src = BOOTSOURCE_MMC, .instance = 0 }, + [0x3] = { .src = BOOTSOURCE_SPI_NOR, .instance = 0 }, + [0x4] = { .src = BOOTSOURCE_SPI_NAND, .instance = 0 }, + [0x5] = { .src = BOOTSOURCE_MMC, .instance = 1 }, + [0xa] = { .src = BOOTSOURCE_USB, .instance = 0 }, +}; + +void rockchip_parse_bootrom_iram(const void *iram) +{ + u32 v; + + rk_iram = iram; + + v = readl(iram + BROM_BOOTSOURCE_ID); + + if (v >= ARRAY_SIZE(bootdev_map)) + return; + + bootsource_set(bootdev_map[v].src, bootdev_map[v].instance); +} diff --git a/arch/arm/mach-rockchip/rk3568.c b/arch/arm/mach-rockchip/rk3568.c index 39bd4772a6..c0453ea0c4 100644 --- a/arch/arm/mach-rockchip/rk3568.c +++ b/arch/arm/mach-rockchip/rk3568.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -137,35 +138,9 @@ void rk3568_lowlevel_init(void) qos_priority_init(); } -struct rk_bootsource { - enum bootsource src; - int instance; -}; - -static struct rk_bootsource bootdev_map[] = { - [0x1] = { .src = BOOTSOURCE_NAND, .instance = 0 }, - [0x2] = { .src = BOOTSOURCE_MMC, .instance = 0 }, - [0x3] = { .src = BOOTSOURCE_SPI_NOR, .instance = 0 }, - [0x4] = { .src = BOOTSOURCE_SPI_NAND, .instance = 0 }, - [0x5] = { .src = BOOTSOURCE_MMC, .instance = 1 }, - [0xa] = { .src = BOOTSOURCE_USB, .instance = 0 }, -}; - -static void rk3568_bootsource(void) -{ - u32 v; - - v = readl(RK3568_IRAM_BASE + 0x10); - - if (v >= ARRAY_SIZE(bootdev_map)) - return; - - bootsource_set(bootdev_map[v].src, bootdev_map[v].instance); -} - int rk3568_init(void) { - rk3568_bootsource(); + rockchip_parse_bootrom_iram(rockchip_scratch_space()); return 0; } diff --git a/include/bootsource.h b/include/bootsource.h index 05935b64a7..f2ab3a2ad4 100644 --- a/include/bootsource.h +++ b/include/bootsource.h @@ -26,6 +26,7 @@ enum bootsource { #define BOOTSOURCE_INSTANCE_UNKNOWN -1 enum bootsource bootsource_get(void); +enum bootsource bootsource_get_device(void); int bootsource_get_instance(void); void bootsource_set_alias_name(const char *name); char *bootsource_get_alias_name(void); diff --git a/include/mach/rockchip/bootrom.h b/include/mach/rockchip/bootrom.h new file mode 100644 index 0000000000..96eb147ae4 --- /dev/null +++ b/include/mach/rockchip/bootrom.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __MACH_ROCKCHIP_BOOTROM_H +#define __MACH_ROCKCHIP_BOOTROM_H + +#include +#include +#include + +struct rockchip_scratch_space { + u32 irom[16]; +}; + +static inline void rockchip_store_bootrom_iram(ulong membase, + ulong memsize, + const void *iram) +{ + void *dst = (void *)__arm_mem_scratch(membase + memsize); + memcpy(dst, iram, sizeof(struct rockchip_scratch_space)); +} + +static inline const struct rockchip_scratch_space *rockchip_scratch_space(void) +{ + return arm_mem_scratch_get(); +} + +void rockchip_parse_bootrom_iram(const void *iram); + +int rockchip_bootsource_get_active_slot(void); + + +#endif -- cgit v1.2.1