This adds basic support for the Rockchip rk3568 SoC. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> Link: https://lore.barebox.org/20210615141641.31577-8-s.hauer@xxxxxxxxxxxxxx Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- arch/arm/Kconfig | 3 - arch/arm/mach-rockchip/Kconfig | 18 ++ arch/arm/mach-rockchip/Makefile | 4 +- arch/arm/mach-rockchip/atf.c | 62 ++++++ arch/arm/mach-rockchip/include/mach/atf.h | 18 ++ arch/arm/mach-rockchip/include/mach/bbu.h | 14 ++ .../arm/mach-rockchip/include/mach/debug_ll.h | 8 + .../mach-rockchip/include/mach/rk3568-regs.h | 18 ++ .../arm/mach-rockchip/include/mach/rockchip.h | 11 ++ arch/arm/mach-rockchip/rk3568.c | 176 ++++++++++++++++++ arch/arm/mach-rockchip/rockchip.c | 2 + common/Kconfig | 10 +- firmware/Makefile | 3 +- include/bootsource.h | 1 + 14 files changed, 342 insertions(+), 6 deletions(-) create mode 100644 arch/arm/mach-rockchip/atf.c create mode 100644 arch/arm/mach-rockchip/include/mach/atf.h create mode 100644 arch/arm/mach-rockchip/include/mach/bbu.h create mode 100644 arch/arm/mach-rockchip/include/mach/rk3568-regs.h create mode 100644 arch/arm/mach-rockchip/rk3568.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 6f28e1ec10..0740039309 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -145,8 +145,6 @@ config ARCH_PXA config ARCH_ROCKCHIP bool "Rockchip RX3xxx" - select CPU_V7 - select ARM_SMP_TWD select COMMON_CLK select CLKDEV_LOOKUP select COMMON_CLK_OF_PROVIDER @@ -156,7 +154,6 @@ config ARCH_ROCKCHIP select OFTREE select HAVE_PBL_MULTI_IMAGES select HAS_DEBUG_LL - select ARCH_HAS_L2X0 config ARCH_SOCFPGA bool "Altera SOCFPGA" diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 65bcbcac96..b4c8573c6e 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -13,11 +13,23 @@ config RK_TIMER config ARCH_RK3188 bool + select CPU_V7 + select ARM_SMP_TWD + select ARCH_HAS_L2X0 config ARCH_RK3288 bool + select CPU_V7 + select ARM_SMP_TWD + select ARCH_HAS_L2X0 select CLOCKSOURCE_ROCKCHIP +config ARCH_RK3568 + bool + select CPU_V8 + select ARM_ATF + select SYS_SUPPORTS_64BIT_KERNEL + comment "select Rockchip boards:" config MACH_RADXA_ROCK @@ -34,3 +46,9 @@ config MACH_PHYTEC_SOM_RK3288 Say Y here if you are using a RK3288 based Phytecs SOM endmenu + +config ARCH_RK3568_OPTEE + bool "Build OP-TEE binary into barebox" + help + With this option enabled the RK3568 OP-TEE binary is compiled + into barebox and started along with the BL31 trusted firmware. diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 0188d0252f..b7bab1fb73 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1,3 +1,5 @@ -obj-y += rockchip.o +obj-y += rockchip.o atf.o +pbl-y += atf.o obj-$(CONFIG_ARCH_RK3188) += rk3188.o obj-$(CONFIG_ARCH_RK3288) += rk3288.o +obj-pbl-$(CONFIG_ARCH_RK3568) += rk3568.o diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c new file mode 100644 index 0000000000..3c4c9d1c8a --- /dev/null +++ b/arch/arm/mach-rockchip/atf.c @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include <common.h> +#include <firmware.h> +#include <asm/system.h> +#include <mach/atf.h> +#include <elf.h> +#include <asm/atf_common.h> + +static unsigned long load_elf64_image_phdr(const void *elf) +{ + const Elf64_Ehdr *ehdr; /* Elf header structure pointer */ + const Elf64_Phdr *phdr; /* Program header structure pointer */ + int i; + + ehdr = elf; + phdr = elf + ehdr->e_phoff; + + /* Load each program header */ + for (i = 0; i < ehdr->e_phnum; ++i) { + void *dst = (void *)(ulong)phdr->p_paddr; + const void *src = elf + phdr->p_offset; + + pr_debug("Loading phdr %i to 0x%p (%lu bytes)\n", + i, dst, (ulong)phdr->p_filesz); + if (phdr->p_filesz) + memcpy(dst, src, phdr->p_filesz); + if (phdr->p_filesz != phdr->p_memsz) + memset(dst + phdr->p_filesz, 0x00, + phdr->p_memsz - phdr->p_filesz); + ++phdr; + } + + return ehdr->e_entry; +} + +void rk3568_atf_load_bl31(void *fdt) +{ + const void *bl31_elf, *optee; + unsigned long bl31; + size_t bl31_elf_size, optee_size; + uintptr_t optee_load_address = 0; + + get_builtin_firmware(rk3568_bl31_bin, &bl31_elf, &bl31_elf_size); + + bl31 = load_elf64_image_phdr(bl31_elf); + + if (IS_ENABLED(CONFIG_ARCH_RK3568_OPTEE)) { + optee_load_address = RK3568_OPTEE_LOAD_ADDRESS; + + get_builtin_firmware(rk3568_op_tee_bin, &optee, &optee_size); + + memcpy((void *)optee_load_address, optee, optee_size); + } + + /* Setup an initial stack for EL2 */ + asm volatile("msr sp_el2, %0" : : + "r" (RK3568_BAREBOX_LOAD_ADDRESS - 16) : + "cc"); + + bl31_entry(bl31, optee_load_address, + RK3568_BAREBOX_LOAD_ADDRESS, (uintptr_t)fdt); +} diff --git a/arch/arm/mach-rockchip/include/mach/atf.h b/arch/arm/mach-rockchip/include/mach/atf.h new file mode 100644 index 0000000000..337a8261c8 --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/atf.h @@ -0,0 +1,18 @@ +#ifndef __MACH_ATF_H +#define __MACH_ATF_H + +/* First usable DRAM address. Lower mem is used for ATF and OP-TEE */ +#define RK3568_DRAM_BOTTOM 0xa00000 + +/* OP-TEE expects to be loaded here */ +#define RK3568_OPTEE_LOAD_ADDRESS 0x200000 + +/* + * board lowlevel code should relocate barebox here. This is where + * OP-TEE jumps to after initialization. + */ +#define RK3568_BAREBOX_LOAD_ADDRESS (RK3568_DRAM_BOTTOM + 1024*1024) + +void rk3568_atf_load_bl31(void *fdt); + +#endif /* __MACH_ATF_H */ diff --git a/arch/arm/mach-rockchip/include/mach/bbu.h b/arch/arm/mach-rockchip/include/mach/bbu.h new file mode 100644 index 0000000000..e61e0615e2 --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/bbu.h @@ -0,0 +1,14 @@ +#ifndef __MACH_ROCKCHIP_BBU_H +#define __MACH_ROCKCHIP_BBU_H + +#include <bbu.h> + +static inline int rk3568_bbu_mmc_register(const char *name, unsigned long flags, + const char *devicefile) +{ + return bbu_register_std_file_update(name, flags, + devicefile, filetype_rockchip_rkns_image); + +} + +# endif /* __MACH_ROCKCHIP_BBU_H */ diff --git a/arch/arm/mach-rockchip/include/mach/debug_ll.h b/arch/arm/mach-rockchip/include/mach/debug_ll.h index 7806aab8bb..af6257a674 100644 --- a/arch/arm/mach-rockchip/include/mach/debug_ll.h +++ b/arch/arm/mach-rockchip/include/mach/debug_ll.h @@ -5,6 +5,7 @@ #include <io.h> #include <mach/rk3188-regs.h> #include <mach/rk3288-regs.h> +#include <mach/rk3568-regs.h> #ifdef CONFIG_DEBUG_LL @@ -22,6 +23,13 @@ #define serial_out(a, v) writel(v, a) #define serial_in(a) readl(a) +#elif defined CONFIG_DEBUG_ROCKCHIP_RK3568_UART + +#define UART_CLOCK 24000000 +#define RK_DEBUG_SOC RK3568 +#define serial_out(a, v) writel(v, a) +#define serial_in(a) readl(a) + #endif #define __RK_UART_BASE(soc, num) soc##_UART##num##_BASE diff --git a/arch/arm/mach-rockchip/include/mach/rk3568-regs.h b/arch/arm/mach-rockchip/include/mach/rk3568-regs.h new file mode 100644 index 0000000000..bb2ca7bd90 --- /dev/null +++ b/arch/arm/mach-rockchip/include/mach/rk3568-regs.h @@ -0,0 +1,18 @@ +#ifndef __MACH_RK3568_REGS_H +#define __MACH_RK3568_REGS_H + +/* UART */ +#define RK3568_UART0_BASE 0xfdd50000 +#define RK3568_UART1_BASE 0xfe650000 +#define RK3568_UART2_BASE 0xfe660000 +#define RK3568_UART3_BASE 0xfe670000 +#define RK3568_UART4_BASE 0xfe680000 +#define RK3568_UART5_BASE 0xfe690000 +#define RK3568_UART6_BASE 0xfe6a0000 +#define RK3568_UART7_BASE 0xfe6b0000 +#define RK3568_UART8_BASE 0xfe6c0000 +#define RK3568_UART9_BASE 0xfe6d0000 + +#define RK3568_IRAM_BASE 0xfdcc0000 + +#endif /* __MACH_RK3568_REGS_H */ diff --git a/arch/arm/mach-rockchip/include/mach/rockchip.h b/arch/arm/mach-rockchip/include/mach/rockchip.h index 8d37c67d4f..722b73d6f8 100644 --- a/arch/arm/mach-rockchip/include/mach/rockchip.h +++ b/arch/arm/mach-rockchip/include/mach/rockchip.h @@ -19,4 +19,15 @@ static inline int rk3288_init(void) } #endif +#ifdef CONFIG_ARCH_RK3568 +int rk3568_init(void); +#else +static inline int rk3568_init(void) +{ + return -ENOTSUPP; +} +#endif + +int rk3568_lowlevel_init(void); + #endif /* __MACH_ROCKCHIP_H */ diff --git a/arch/arm/mach-rockchip/rk3568.c b/arch/arm/mach-rockchip/rk3568.c new file mode 100644 index 0000000000..fcf3cb7053 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3568.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0+ +#include <common.h> +#include <io.h> +#include <bootsource.h> +#include <mach/rk3568-regs.h> +#include <mach/rockchip.h> + +#define GRF_BASE 0xfdc60000 +#define GRF_GPIO1B_DS_2 0x218 +#define GRF_GPIO1B_DS_3 0x21c +#define GRF_GPIO1C_DS_0 0x220 +#define GRF_GPIO1C_DS_1 0x224 +#define GRF_GPIO1C_DS_2 0x228 +#define GRF_GPIO1C_DS_3 0x22c +#define GRF_GPIO1D_DS_0 0x230 +#define GRF_GPIO1D_DS_1 0x234 +#define GRF_SOC_CON4 0x510 +#define EDP_PHY_GRF_BASE 0xfdcb0000 +#define EDP_PHY_GRF_CON0 (EDP_PHY_GRF_BASE + 0x00) +#define EDP_PHY_GRF_CON10 (EDP_PHY_GRF_BASE + 0x28) +#define PMU_BASE_ADDR 0xfdd90000 +#define PMU_NOC_AUTO_CON0 0x70 +#define PMU_NOC_AUTO_CON1 0x74 +#define CRU_BASE 0xfdd20000 +#define CRU_SOFTRST_CON26 0x468 +#define CRU_SOFTRST_CON28 0x470 +#define SGRF_BASE 0xFDD18000 +#define SGRF_SOC_CON3 0xC +#define SGRF_SOC_CON4 0x10 +#define PMUGRF_SOC_CON15 0xfdc20100 +#define CPU_GRF_BASE 0xfdc30000 +#define GRF_CORE_PVTPLL_CON0 0x10 +#define USBPHY_U3_GRF 0xfdca0000 +#define USBPHY_U3_GRF_CON1 (USBPHY_U3_GRF + 0x04) +#define USBPHY_U2_GRF 0xfdca8000 +#define USBPHY_U2_GRF_CON0 (USBPHY_U2_GRF + 0x00) +#define USBPHY_U2_GRF_CON1 (USBPHY_U2_GRF + 0x04) + +#define PMU_PWR_GATE_SFTCON 0xA0 +#define PMU_PWR_DWN_ST 0x98 +#define PMU_BUS_IDLE_SFTCON0 0x50 +#define PMU_BUS_IDLE_ST 0x68 +#define PMU_BUS_IDLE_ACK 0x60 + +#define EBC_PRIORITY_REG 0xfe158008 + +static void qos_priority_init(void) +{ + u32 delay; + + /* enable all pd except npu and gpu */ + writel(0xffff0000 & ~(BIT(0 + 16) | BIT(1 + 16)), + PMU_BASE_ADDR + PMU_PWR_GATE_SFTCON); + delay = 1000; + do { + udelay(1); + delay--; + if (delay == 0) { + printf("Fail to set domain."); + hang(); + } + } while (readl(PMU_BASE_ADDR + PMU_PWR_DWN_ST) & ~(BIT(0) | BIT(1))); + + /* release all idle request except npu and gpu */ + writel(0xffff0000 & ~(BIT(1 + 16) | BIT(2 + 16)), + PMU_BASE_ADDR + PMU_BUS_IDLE_SFTCON0); + + delay = 1000; + /* wait ack status */ + do { + udelay(1); + delay--; + if (delay == 0) { + printf("Fail to get ack on domain.\n"); + hang(); + } + } while (readl(PMU_BASE_ADDR + PMU_BUS_IDLE_ACK) & ~(BIT(1) | BIT(2))); + + delay = 1000; + /* wait idle status */ + do { + udelay(1); + delay--; + if (delay == 0) { + printf("Fail to set idle on domain.\n"); + hang(); + } + } while (readl(PMU_BASE_ADDR + PMU_BUS_IDLE_ST) & ~(BIT(1) | BIT(2))); + + writel(0x303, EBC_PRIORITY_REG); +} + +int rk3568_lowlevel_init(void) +{ + /* + * When perform idle operation, corresponding clock can + * be opened or gated automatically. + */ + writel(0xffffffff, PMU_BASE_ADDR + PMU_NOC_AUTO_CON0); + writel(0x000f000f, PMU_BASE_ADDR + PMU_NOC_AUTO_CON1); + + /* Set the emmc sdmmc0 to secure */ + writel(((0x3 << 11 | 0x1 << 4) << 16), SGRF_BASE + SGRF_SOC_CON4); + /* set the emmc ds to level 2 */ + writel(0x3f3f0707, GRF_BASE + GRF_GPIO1B_DS_2); + writel(0x3f3f0707, GRF_BASE + GRF_GPIO1B_DS_3); + writel(0x3f3f0707, GRF_BASE + GRF_GPIO1C_DS_0); + writel(0x3f3f0707, GRF_BASE + GRF_GPIO1C_DS_1); + writel(0x3f3f0707, GRF_BASE + GRF_GPIO1C_DS_2); + writel(0x3f3f0707, GRF_BASE + GRF_GPIO1C_DS_3); + + /* Set the fspi to secure */ + writel(((0x1 << 14) << 16) | (0x0 << 14), SGRF_BASE + SGRF_SOC_CON3); + + /* Disable eDP phy by default */ + writel(0x00070007, EDP_PHY_GRF_CON10); + writel(0x0ff10ff1, EDP_PHY_GRF_CON0); + + /* Set core pvtpll ring length */ + writel(0x00ff002b, CPU_GRF_BASE + GRF_CORE_PVTPLL_CON0); + + /* + * Assert reset the pipephy0, pipephy1 and pipephy2, + * and de-assert reset them in Kernel combphy driver. + */ + writel(0x02a002a0, CRU_BASE + CRU_SOFTRST_CON28); + + /* + * Set USB 2.0 PHY0 port1 and PHY1 port0 and port1 + * enter suspend mode to to save power. And USB 2.0 + * PHY0 port0 for OTG interface still in normal mode. + */ + writel(0x01ff01d1, USBPHY_U3_GRF_CON1); + writel(0x01ff01d1, USBPHY_U2_GRF_CON0); + writel(0x01ff01d1, USBPHY_U2_GRF_CON1); + + qos_priority_init(); + + return 0; +} + +struct rk_bootsource { + enum bootsource src; + int instance; +}; + +static struct rk_bootsource bootdev_map[] = { + { .src = BOOTSOURCE_UNKNOWN, .instance = 0 }, + { .src = BOOTSOURCE_NAND, .instance = 0 }, + { .src = BOOTSOURCE_MMC, .instance = 0 }, + { .src = BOOTSOURCE_SPI_NOR, .instance = 0 }, + { .src = BOOTSOURCE_SPI_NAND, .instance = 0 }, + { .src = BOOTSOURCE_MMC, .instance = 1 }, +}; + +static enum bootsource rk3568_bootsource(void) +{ + u32 v; + + v = readl(RK3568_IRAM_BASE + 0x10); + + if (v >= ARRAY_SIZE(bootdev_map)) + return BOOTSOURCE_UNKNOWN; + + bootsource_set(bootdev_map[v].src); + bootsource_set_instance(bootdev_map[v].instance); + + return bootdev_map[v].src; +} + +int rk3568_init(void) +{ + rk3568_bootsource(); + + return 0; +} diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index b0fbb49457..f0b2484c68 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -9,6 +9,8 @@ static int rockchip_init(void) rk3188_init(); else if (of_machine_is_compatible("rockchip,rk3288")) rk3288_init(); + else if (of_machine_is_compatible("rockchip,rk3568")) + rk3568_init(); else pr_err("Unknown rockchip SoC\n"); diff --git a/common/Kconfig b/common/Kconfig index 8b8f80bbb3..273186c5fa 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1331,6 +1331,13 @@ config DEBUG_ROCKCHIP_RK3288_UART Say Y here if you want kernel low-level debugging support on RK3288. +config DEBUG_ROCKCHIP_RK3568_UART + bool "RK3568 Debug UART" + depends on ARCH_RK3568 + help + Say Y here if you want kernel low-level debugging support + on RK3568. + config DEBUG_SOCFPGA_UART0 bool "Use SOCFPGA UART0 for low-level debug" depends on ARCH_SOCFPGA @@ -1417,7 +1424,8 @@ config DEBUG_OMAP_UART_PORT config DEBUG_ROCKCHIP_UART_PORT int "RK3xxx UART debug port" if DEBUG_ROCKCHIP_RK3188_UART || \ - DEBUG_ROCKCHIP_RK3288_UART + DEBUG_ROCKCHIP_RK3288_UART || \ + DEBUG_ROCKCHIP_RK3568_UART default 2 depends on ARCH_ROCKCHIP help diff --git a/firmware/Makefile b/firmware/Makefile index 3a38c40079..00bdedfc6b 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -9,7 +9,8 @@ firmware-$(CONFIG_FIRMWARE_IMX_LPDDR4_PMU_TRAIN) += \ firmware-$(CONFIG_FIRMWARE_IMX8MM_ATF) += imx8mm-bl31.bin firmware-$(CONFIG_FIRMWARE_IMX8MP_ATF) += imx8mp-bl31.bin firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx8mq-bl31.bin - +firmware-$(CONFIG_ARCH_RK3568) += rk3568-bl31.bin +firmware-$(CONFIG_ARCH_RK3568_OPTEE) += rk3568-op-tee.bin firmware-$(CONFIG_DRIVER_NET_FSL_FMAN) += fsl_fman_ucode_ls1046_r1.0_106_4_18.bin firmware-$(CONFIG_ARCH_LAYERSCAPE_PPA) += ppa-ls1046a.bin diff --git a/include/bootsource.h b/include/bootsource.h index 32295ddd96..646b0e91c1 100644 --- a/include/bootsource.h +++ b/include/bootsource.h @@ -12,6 +12,7 @@ enum bootsource { BOOTSOURCE_SPI, BOOTSOURCE_SPI_EEPROM, BOOTSOURCE_SPI_NOR, + BOOTSOURCE_SPI_NAND, BOOTSOURCE_SERIAL, BOOTSOURCE_ONENAND, BOOTSOURCE_HD, -- 2.29.2 _______________________________________________ barebox mailing list barebox@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox