From f90d7f9882001029b5238c75b8c3f56ee605ed72 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 24 Mar 2023 14:25:29 +0100 Subject: ARM: dts: rk356x: Add DMC controller node There's currently no DMC controller node in the upstream dtsi file. Add one until it's there. Signed-off-by: Sascha Hauer --- arch/arm/dts/rk356x.dtsi | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/rk356x.dtsi b/arch/arm/dts/rk356x.dtsi index 6a9cd14d2d..4de2404b50 100644 --- a/arch/arm/dts/rk356x.dtsi +++ b/arch/arm/dts/rk356x.dtsi @@ -6,4 +6,9 @@ barebox,bootsource-mmc1 = &sdmmc0; barebox,bootsource-mmc2 = &sdmmc1; }; + + dmc: memory-controller { + compatible = "rockchip,rk3568-dmc"; + rockchip,pmu = <&pmugrf>; + }; }; -- cgit v1.2.1 From bc9baa7ac71c4a8e75d000317d85d6bf6a85a8e4 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Thu, 5 Jan 2023 08:34:40 +0100 Subject: ARM: Rockchip: implement memory read out from controller Add a driver to read out the amount of memory from the DDR controller. The decoding of the registers has been taken from U-Boot. Currently supported are the RK3399 and the RK3568, but decoding should work on other Rockchip SoCs as well. Signed-off-by: Ahmad Fatoum Signed-off-by: Sascha Hauer --- arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/dmc.c | 219 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 arch/arm/mach-rockchip/dmc.c (limited to 'arch') diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 2529af7c7e..f6c575854e 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_ARCH_RK3188) += rk3188.o obj-$(CONFIG_ARCH_RK3288) += rk3288.o obj-pbl-$(CONFIG_ARCH_RK3568) += rk3568.o obj-$(CONFIG_ARCH_ROCKCHIP_V8) += bootm.o +obj-pbl-$(CONFIG_ARCH_ROCKCHIP_V8) += dmc.o obj-$(CONFIG_BAREBOX_UPDATE) += bbu.o diff --git a/arch/arm/mach-rockchip/dmc.c b/arch/arm/mach-rockchip/dmc.c new file mode 100644 index 0000000000..dd60db5830 --- /dev/null +++ b/arch/arm/mach-rockchip/dmc.c @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Rockchip Electronics Co., Ltd. + */ + +#define pr_fmt(fmt) "rockchip-dmc: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RK3399_PMUGRF_OS_REG2 0x308 +#define RK3399_PMUGRF_OS_REG3 0x30C + +#define RK3568_PMUGRF_OS_REG2 0x208 +#define RK3568_PMUGRF_OS_REG3 0x20c + +#define RK3399_INT_REG_START 0xf0000000 +#define RK3568_INT_REG_START RK3399_INT_REG_START + +struct rockchip_dmc_drvdata { + unsigned int os_reg2; + unsigned int os_reg3; + resource_size_t internal_registers_start; +}; + +static resource_size_t rockchip_sdram_size(u32 sys_reg2, u32 sys_reg3) +{ + u32 rank, cs0_col, bk, cs0_row, cs1_row, bw, row_3_4; + resource_size_t chipsize_mb, size_mb = 0; + u32 ch; + u32 cs1_col; + u32 bg = 0; + u32 dbw, dram_type; + u32 ch_num = 1 + FIELD_GET(SYS_REG_NUM_CH, sys_reg2); + u32 version = FIELD_GET(SYS_REG_VERSION, sys_reg3); + + pr_debug("%s(reg2=%x, reg3=%x)\n", __func__, sys_reg2, sys_reg3); + + dram_type = FIELD_GET(SYS_REG_DDRTYPE, sys_reg2); + + if (version >= 3) + dram_type |= FIELD_GET(SYS_REG_EXTEND_DDRTYPE, sys_reg3) << 3; + + for (ch = 0; ch < ch_num; ch++) { + rank = 1 + (sys_reg2 >> SYS_REG_RANK_SHIFT(ch) & SYS_REG_RANK_MASK); + cs0_col = 9 + (sys_reg2 >> SYS_REG_COL_SHIFT(ch) & SYS_REG_COL_MASK); + cs1_col = cs0_col; + + bk = 3 - ((sys_reg2 >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK); + + cs0_row = sys_reg2 >> SYS_REG_CS0_ROW_SHIFT(ch) & SYS_REG_CS0_ROW_MASK; + cs1_row = sys_reg2 >> SYS_REG_CS1_ROW_SHIFT(ch) & SYS_REG_CS1_ROW_MASK; + + if (version >= 2) { + cs1_col = 9 + (sys_reg3 >> SYS_REG_CS1_COL_SHIFT(ch) & + SYS_REG_CS1_COL_MASK); + + cs0_row |= (sys_reg3 >> SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) & + SYS_REG_EXTEND_CS0_ROW_MASK) << 2; + + if (cs0_row == 7) + cs0_row = 12; + else + cs0_row += 13; + + cs1_row |= (sys_reg3 >> SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) & + SYS_REG_EXTEND_CS1_ROW_MASK) << 2; + + if (cs1_row == 7) + cs1_row = 12; + else + cs1_row += 13; + } else { + cs0_row += 13; + cs1_row += 13; + } + + bw = (2 >> ((sys_reg2 >> SYS_REG_BW_SHIFT(ch)) & SYS_REG_BW_MASK)); + row_3_4 = sys_reg2 >> SYS_REG_ROW_3_4_SHIFT(ch) & SYS_REG_ROW_3_4_MASK; + + if (dram_type == DDR4) { + dbw = (sys_reg2 >> SYS_REG_DBW_SHIFT(ch)) & SYS_REG_DBW_MASK; + bg = (dbw == 2) ? 2 : 1; + } + + chipsize_mb = (1 << (cs0_row + cs0_col + bk + bg + bw - 20)); + + if (rank > 1) + chipsize_mb += chipsize_mb >> ((cs0_row - cs1_row) + + (cs0_col - cs1_col)); + if (row_3_4) + chipsize_mb = chipsize_mb * 3 / 4; + + size_mb += chipsize_mb; + + if (rank > 1) + pr_debug("rank %d cs0_col %d cs1_col %d bk %d cs0_row %d " + "cs1_row %d bw %d row_3_4 %d\n", + rank, cs0_col, cs1_col, bk, cs0_row, + cs1_row, bw, row_3_4); + else + pr_debug("rank %d cs0_col %d bk %d cs0_row %d " + "bw %d row_3_4 %d\n", + rank, cs0_col, bk, cs0_row, + bw, row_3_4); + } + + return (resource_size_t)size_mb << 20; +} + +resource_size_t rk3399_ram0_size(void) +{ + void __iomem *pmugrf = IOMEM(RK3399_PMUGRF_BASE); + u32 sys_reg2, sys_reg3; + resource_size_t size; + + sys_reg2 = readl(pmugrf + RK3399_PMUGRF_OS_REG2); + sys_reg3 = readl(pmugrf + RK3399_PMUGRF_OS_REG3); + + size = rockchip_sdram_size(sys_reg2, sys_reg3); + size = min_t(resource_size_t, RK3399_INT_REG_START, size); + + pr_debug("%s() = %llu\n", __func__, (u64)size); + + return size; +} + +resource_size_t rk3568_ram0_size(void) +{ + void __iomem *pmugrf = IOMEM(RK3568_PMUGRF_BASE); + u32 sys_reg2, sys_reg3; + resource_size_t size; + + sys_reg2 = readl(pmugrf + RK3568_PMUGRF_OS_REG2); + sys_reg3 = readl(pmugrf + RK3568_PMUGRF_OS_REG3); + + size = rockchip_sdram_size(sys_reg2, sys_reg3); + size = min_t(resource_size_t, RK3568_INT_REG_START, size); + + pr_debug("%s() = %llu\n", __func__, (u64)size); + + return size; +} + +static int rockchip_dmc_probe(struct device *dev) +{ + const struct rockchip_dmc_drvdata *drvdata; + resource_size_t membase, memsize; + struct regmap *regmap; + u32 sys_reg2, sys_reg3; + + regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu"); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + drvdata = device_get_match_data(dev); + if (!drvdata) + return -ENOENT; + + regmap_read(regmap, drvdata->os_reg2, &sys_reg2); + regmap_read(regmap, drvdata->os_reg3, &sys_reg3); + + memsize = rockchip_sdram_size(sys_reg2, sys_reg3); + + dev_info(dev, "Detected memory size: %pa\n", &memsize); + + /* lowest 10M are shaved off for secure world firmware */ + membase = 0xa00000; + + /* ram0, from 0xa00000 up to SoC internal register space start */ + arm_add_mem_device("ram0", membase, + min_t(resource_size_t, drvdata->internal_registers_start, memsize) - membase); + + /* ram1, remaining RAM beyond 32bit space */ + if (memsize > SZ_4G) + arm_add_mem_device("ram1", SZ_4G, memsize - SZ_4G); + + return 0; +} + +static const struct rockchip_dmc_drvdata rk3399_drvdata = { + .os_reg2 = RK3399_PMUGRF_OS_REG2, + .os_reg3 = RK3399_PMUGRF_OS_REG3, + .internal_registers_start = RK3399_INT_REG_START, +}; + +static const struct rockchip_dmc_drvdata rk3568_drvdata = { + .os_reg2 = RK3568_PMUGRF_OS_REG2, + .os_reg3 = RK3568_PMUGRF_OS_REG3, + .internal_registers_start = RK3568_INT_REG_START, +}; + +static struct of_device_id rockchip_dmc_dt_ids[] = { + { + .compatible = "rockchip,rk3399-dmc", + .data = &rk3399_drvdata, + }, + { + .compatible = "rockchip,rk3568-dmc", + .data = &rk3568_drvdata, + }, + { /* sentinel */ } +}; + +static struct driver rockchip_dmc_driver = { + .name = "rockchip-dmc", + .probe = rockchip_dmc_probe, + .of_compatible = rockchip_dmc_dt_ids, +}; +mem_platform_driver(rockchip_dmc_driver); -- cgit v1.2.1 From 1a6cab4f07b45fd1bca5d62ea37c00d26e70cde7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 23 Mar 2023 20:03:48 +0100 Subject: ARM: Rockchip: Add rk3568 specific barebox entry function Add a rk3568 specific barebox entry function to simplify board code. Signed-off-by: Sascha Hauer --- arch/arm/mach-rockchip/atf.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c index 93025faf68..9735cb8ef3 100644 --- a/arch/arm/mach-rockchip/atf.c +++ b/arch/arm/mach-rockchip/atf.c @@ -5,6 +5,9 @@ #include #include #include +#include +#include +#include static unsigned long load_elf64_image_phdr(const void *elf) { @@ -69,3 +72,19 @@ void rk3568_atf_load_bl31(void *fdt) { rockchip_atf_load_bl31(RK3568, rk3568_bl31_bin, rk3568_op_tee_bin, fdt); } + +void __noreturn rk3568_barebox_entry(void *fdt) +{ + unsigned long membase, memsize; + + membase = RK3568_DRAM_BOTTOM; + memsize = rk3568_ram0_size() - RK3568_DRAM_BOTTOM; + + if (current_el() == 3) { + rk3568_lowlevel_init(); + rk3568_atf_load_bl31(fdt); + /* not reached when CONFIG_ARCH_ROCKCHIP_ATF */ + } + + barebox_arm_entry(membase, memsize, fdt); +} -- cgit v1.2.1 From 4a26017f6dd70c6b0c0fd11d527291058c85cea5 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 23 Mar 2023 20:08:42 +0100 Subject: ARM: Rockchip: rk3568: use rk3568_barebox_entry() There is a rk3568 specific entry function for barebox now, switch the existing boards over to use it. Signed-off-by: Sascha Hauer --- arch/arm/boards/pine64-quartz64/lowlevel.c | 26 ++++------------------ arch/arm/boards/radxa-rock3/lowlevel.c | 25 ++++----------------- .../boards/rockchip-rk3568-bpi-r2pro/lowlevel.c | 25 +++------------------ arch/arm/boards/rockchip-rk3568-evb/lowlevel.c | 26 +++------------------- 4 files changed, 14 insertions(+), 88 deletions(-) (limited to 'arch') diff --git a/arch/arm/boards/pine64-quartz64/lowlevel.c b/arch/arm/boards/pine64-quartz64/lowlevel.c index 1e63c0e698..7723d47860 100644 --- a/arch/arm/boards/pine64-quartz64/lowlevel.c +++ b/arch/arm/boards/pine64-quartz64/lowlevel.c @@ -1,35 +1,17 @@ // SPDX-License-Identifier: GPL-2.0-only + #include -#include -#include #include #include #include #include -#include extern char __dtb_rk3566_quartz64_a_start[]; -static noinline void start_quartz64(void) -{ - void *fdt = __dtb_rk3566_quartz64_a_start; - - if (current_el() == 3) { - rk3568_lowlevel_init(); - rk3568_atf_load_bl31(fdt); - /* not reached */ - } - - barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, - fdt); -} - ENTRY_FUNCTION(start_quartz64a, r0, r1, r2) { - /* - * Image execution starts at 0x0, but this is used for ATF and - * OP-TEE later, so move away from here. - */ + putc_ll('>'); + if (current_el() == 3) relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS); else @@ -37,5 +19,5 @@ ENTRY_FUNCTION(start_quartz64a, r0, r1, r2) setup_c(); - start_quartz64(); + rk3568_barebox_entry(__dtb_rk3566_quartz64_a_start); } diff --git a/arch/arm/boards/radxa-rock3/lowlevel.c b/arch/arm/boards/radxa-rock3/lowlevel.c index a8226749d4..ec407404b9 100644 --- a/arch/arm/boards/radxa-rock3/lowlevel.c +++ b/arch/arm/boards/radxa-rock3/lowlevel.c @@ -1,19 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only + #include -#include -#include #include #include #include #include -#include extern char __dtb_rk3568_rock_3a_start[]; -static noinline void rk3568_start(void) +ENTRY_FUNCTION(start_rock3a, r0, r1, r2) { - void *fdt = __dtb_rk3568_rock_3a_start; - /* * Enable vccio4 1.8V and vccio6 1.8V * Needed for GMAC to work. @@ -24,21 +20,8 @@ static noinline void rk3568_start(void) */ writel(RK_SETBITS(0x50), 0xfdc20140); - if (current_el() == 3) { - rk3568_lowlevel_init(); - rk3568_atf_load_bl31(fdt); - /* not reached */ - } - - barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, fdt); -} + putc_ll('>'); -ENTRY_FUNCTION(start_rock3a, r0, r1, r2) -{ - /* - * Image execution starts at 0x0, but this is used for ATF and - * OP-TEE later, so move away from here. - */ if (current_el() == 3) relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS); else @@ -46,5 +29,5 @@ ENTRY_FUNCTION(start_rock3a, r0, r1, r2) setup_c(); - rk3568_start(); + rk3568_barebox_entry(__dtb_rk3568_rock_3a_start); } diff --git a/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c b/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c index 23bacc91d9..12c2445287 100644 --- a/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c +++ b/arch/arm/boards/rockchip-rk3568-bpi-r2pro/lowlevel.c @@ -1,8 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include -#include -#include #include #include #include @@ -11,9 +9,9 @@ extern char __dtb_rk3568_bpi_r2_pro_start[]; -static noinline void rk3568_start(void) +ENTRY_FUNCTION(start_rk3568_bpi_r2pro, r0, r1, r2) { - void *fdt; + putc_ll('>'); /* * set iodomain vccio6 to 1.8V needed for GMAC1 to work. @@ -28,23 +26,6 @@ static noinline void rk3568_start(void) //clear bit 6 for 3v3 as it was set to 1v8 writel(RK_CLRBITS(BIT(6)), PMU_GRF_IO_VSEL1); - fdt = __dtb_rk3568_bpi_r2_pro_start; - - if (current_el() == 3) { - rk3568_lowlevel_init(); - rk3568_atf_load_bl31(fdt); - /* not reached */ - } - - barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, fdt); -} - -ENTRY_FUNCTION(start_rk3568_bpi_r2pro, r0, r1, r2) -{ - /* - * Image execution starts at 0x0, but this is used for ATF and - * OP-TEE later, so move away from here. - */ if (current_el() == 3) relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS); else @@ -52,5 +33,5 @@ ENTRY_FUNCTION(start_rk3568_bpi_r2pro, r0, r1, r2) setup_c(); - rk3568_start(); + rk3568_barebox_entry(__dtb_rk3568_bpi_r2_pro_start); } diff --git a/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c b/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c index 8720e6d9ae..d5ae70049e 100644 --- a/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c +++ b/arch/arm/boards/rockchip-rk3568-evb/lowlevel.c @@ -1,20 +1,15 @@ // SPDX-License-Identifier: GPL-2.0-only #include -#include -#include #include #include #include #include -#include extern char __dtb_rk3568_evb1_v10_start[]; -static noinline void rk3568_start(void) +ENTRY_FUNCTION(start_rk3568_evb, r0, r1, r2) { - void *fdt; - /* * Enable vccio4 1.8V and vccio6 1.8V * Needed for GMAC to work. @@ -25,23 +20,8 @@ static noinline void rk3568_start(void) */ writel(RK_SETBITS(0x50), 0xfdc20140); - fdt = __dtb_rk3568_evb1_v10_start; - - if (current_el() == 3) { - rk3568_lowlevel_init(); - rk3568_atf_load_bl31(fdt); - /* not reached */ - } - - barebox_arm_entry(RK3568_DRAM_BOTTOM, 0x80000000 - RK3568_DRAM_BOTTOM, fdt); -} + putc_ll('>'); -ENTRY_FUNCTION(start_rk3568_evb, r0, r1, r2) -{ - /* - * Image execution starts at 0x0, but this is used for ATF and - * OP-TEE later, so move away from here. - */ if (current_el() == 3) relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS); else @@ -49,5 +29,5 @@ ENTRY_FUNCTION(start_rk3568_evb, r0, r1, r2) setup_c(); - rk3568_start(); + rk3568_barebox_entry(__dtb_rk3568_evb1_v10_start); } -- cgit v1.2.1 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 ++--------------------- 4 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 arch/arm/mach-rockchip/bootrom.c (limited to 'arch') 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; } -- cgit v1.2.1 From dad8498490d40594d0c8d4566057406bf2d9963a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 28 Mar 2023 09:35:24 +0200 Subject: ARM: Rockchip: Do not pass device tree to TF-A The downstream TF-A doesn't cope with our device tree when CONFIG_OF_OVERLAY_LIVE is enabled, supposedly because it is too big for some reason. Otherwise it doesn't have any visible effect if we pass a device tree or not, except that the TF-A fills in the ethernet MAC address into the device tree. The upstream TF-A doesn't use the device tree at all. Pass NULL for now until we have a good reason to pass a real device tree. Signed-off-by: Sascha Hauer --- arch/arm/mach-rockchip/atf.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c index f3fb50b990..d1431cc526 100644 --- a/arch/arm/mach-rockchip/atf.c +++ b/arch/arm/mach-rockchip/atf.c @@ -85,7 +85,19 @@ 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); + + /* + * The downstream TF-A doesn't cope with our device tree when + * CONFIG_OF_OVERLAY_LIVE is enabled, supposedly because it is + * too big for some reason. Otherwise it doesn't have any visible + * effect if we pass a device tree or not, except that the TF-A + * fills in the ethernet MAC address into the device tree. + * The upstream TF-A doesn't use the device tree at all. + * + * Pass NULL for now until we have a good reason to pass a real + * device tree. + */ + rk3568_atf_load_bl31(NULL); /* not reached when CONFIG_ARCH_ROCKCHIP_ATF */ } -- cgit v1.2.1 From 7bf493b1a646e1ee2e88cc7d41b462a6714eafee Mon Sep 17 00:00:00 2001 From: Rouven Czerwinski Date: Thu, 30 Mar 2023 18:11:01 +0200 Subject: arm: rockchip: add support for CM3 on IO board Working: - RKBIN DDR training (rk3566_ddr_1056MHz_v1.13.bin) - RKBIN TF-A (v1.34) from RKBIN - Environment storage - DHCP, ping and link detection Signed-off-by: Rouven Czerwinski Link: https://lore.barebox.org/20230330161101.58529-1-r.czerwinski@pengutronix.de Signed-off-by: Sascha Hauer --- arch/arm/boards/Makefile | 1 + arch/arm/boards/radxa-cm3/.gitignore | 1 + arch/arm/boards/radxa-cm3/Makefile | 3 ++ arch/arm/boards/radxa-cm3/board.c | 56 ++++++++++++++++++++++++++++++++++++ arch/arm/boards/radxa-cm3/lowlevel.c | 32 +++++++++++++++++++++ arch/arm/dts/Makefile | 1 + arch/arm/dts/rk3566-cm3-io.dts | 50 ++++++++++++++++++++++++++++++++ arch/arm/mach-rockchip/Kconfig | 6 ++++ 8 files changed, 150 insertions(+) create mode 100644 arch/arm/boards/radxa-cm3/.gitignore create mode 100644 arch/arm/boards/radxa-cm3/Makefile create mode 100644 arch/arm/boards/radxa-cm3/board.c create mode 100644 arch/arm/boards/radxa-cm3/lowlevel.c create mode 100644 arch/arm/dts/rk3566-cm3-io.dts (limited to 'arch') diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 37b1650e63..b204c257f6 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -190,3 +190,4 @@ obj-$(CONFIG_MACH_RK3568_BPI_R2PRO) += rockchip-rk3568-bpi-r2pro/ obj-$(CONFIG_MACH_PINE64_QUARTZ64) += pine64-quartz64/ obj-$(CONFIG_MACH_RADXA_ROCK3) += radxa-rock3/ obj-$(CONFIG_MACH_VARISCITE_DT8MCUSTOMBOARD_IMX8MP) += variscite-dt8mcustomboard-imx8mp/ +obj-$(CONFIG_MACH_RADXA_CM3) += radxa-cm3/ diff --git a/arch/arm/boards/radxa-cm3/.gitignore b/arch/arm/boards/radxa-cm3/.gitignore new file mode 100644 index 0000000000..f458f794b5 --- /dev/null +++ b/arch/arm/boards/radxa-cm3/.gitignore @@ -0,0 +1 @@ +sdram-init.bin diff --git a/arch/arm/boards/radxa-cm3/Makefile b/arch/arm/boards/radxa-cm3/Makefile new file mode 100644 index 0000000000..b37b6c870b --- /dev/null +++ b/arch/arm/boards/radxa-cm3/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-y += board.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/radxa-cm3/board.c b/arch/arm/boards/radxa-cm3/board.c new file mode 100644 index 0000000000..14b6784179 --- /dev/null +++ b/arch/arm/boards/radxa-cm3/board.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include + +struct cm3_model { + const char *name; + const char *shortname; +}; + +static int cm3_probe(struct device *dev) +{ + enum bootsource bootsource = bootsource_get(); + int instance = bootsource_get_instance(); + const struct cm3_model *model; + + model = device_get_match_data(dev); + + barebox_set_model(model->name); + barebox_set_hostname(model->shortname); + + if (bootsource == BOOTSOURCE_MMC && instance == 1) + of_device_enable_path("/chosen/environment-sd"); + else + of_device_enable_path("/chosen/environment-emmc"); + + rk3568_bbu_mmc_register("emmc", BBU_HANDLER_FLAG_DEFAULT, + "/dev/mmc0"); + rk3568_bbu_mmc_register("sd", 0, "/dev/mmc1"); + + return 0; +} + +static const struct cm3_model cm3_io = { + .name = "Radxa CM3 on IO Board", + .shortname = "cm3-io", +}; + +static const struct of_device_id cm3_of_match[] = { + { + .compatible = "radxa,cm3-io", + .data = &cm3_io, + }, + { /* sentinel */ }, +}; + +static struct driver cm3_io_board_driver = { + .name = "board-cm3-io", + .probe = cm3_probe, + .of_compatible = cm3_of_match, +}; +coredevice_platform_driver(cm3_io_board_driver); + +BAREBOX_DEEP_PROBE_ENABLE(cm3_of_match); diff --git a/arch/arm/boards/radxa-cm3/lowlevel.c b/arch/arm/boards/radxa-cm3/lowlevel.c new file mode 100644 index 0000000000..e1b453f21f --- /dev/null +++ b/arch/arm/boards/radxa-cm3/lowlevel.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include +#include +#include + +extern char __dtb_rk3566_cm3_io_start[]; + +ENTRY_FUNCTION(start_radxa_cm3_io, r0, r1, r2) +{ + /* + * Enable vccio4 1.8V and vccio6 1.8V + * Needed for GMAC to work. + * FIXME: This is done by the io-domain driver as well, but there + * currently is no mechanism to make sure the driver gets probed + * before its consumers. Remove this setup once this issue is + * resolved. + */ + writel(RK_SETBITS(0x50), 0xfdc20140); + + putc_ll('>'); + + if (current_el() == 3) + relocate_to_adr_full(RK3568_BAREBOX_LOAD_ADDRESS); + else + relocate_to_current_adr(); + + setup_c(); + + rk3568_barebox_entry(__dtb_rk3566_cm3_io_start); +} diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 0a7cceb461..220e1617e3 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -109,6 +109,7 @@ lwl-$(CONFIG_MACH_PROTONIC_STM32MP1) += \ stm32mp151-prtt1s.dtb.o lwl-$(CONFIG_MACH_RADXA_ROCK) += rk3188-radxarock.dtb.o lwl-$(CONFIG_MACH_RADXA_ROCK3) += rk3568-rock-3a.dtb.o +lwl-$(CONFIG_MACH_RADXA_CM3) += rk3566-cm3-io.dtb.o lwl-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += rk3288-phycore-som.dtb.o lwl-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o lwl-$(CONFIG_MACH_RK3568_EVB) += rk3568-evb1-v10.dtb.o diff --git a/arch/arm/dts/rk3566-cm3-io.dts b/arch/arm/dts/rk3566-cm3-io.dts new file mode 100644 index 0000000000..39cef5e797 --- /dev/null +++ b/arch/arm/dts/rk3566-cm3-io.dts @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include +#include "rk356x.dtsi" + +/ { + chosen: chosen { + environment-sd { + compatible = "barebox,environment"; + device-path = &environment_sd; + status = "disabled"; + }; + + environment-emmc { + compatible = "barebox,environment"; + device-path = &environment_emmc; + status = "disabled"; + }; + }; +}; + +&sdhci { + no-sd; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <2>; + #size-cells = <2>; + + environment_emmc: partition@408000 { + label = "barebox-environment"; + reg = <0x0 0x408000 0x0 0x8000>; + }; + }; +}; + +&sdmmc0 { + partitions { + compatible = "fixed-partitions"; + #address-cells = <2>; + #size-cells = <2>; + + environment_sd: partition@408000 { + label = "barebox-environment"; + reg = <0x0 0x408000 0x0 0x8000>; + }; + }; +}; diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index 4ac75ab947..c087783b18 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -86,6 +86,12 @@ config MACH_RADXA_ROCK3 help Say Y here if you are using a Radxa ROCK3 +config MACH_RADXA_CM3 + select ARCH_RK3568 + bool "Radxa CM3" + help + Say Y here if you are using a Radxa CM3 + comment "select board features:" config ARCH_ROCKCHIP_ATF -- cgit v1.2.1