Hi, On 8/1/2025 10:07 AM, FUKAUMI Naoki wrote: > Hi Jonas, > > Are there any remaining issues with this patch series?
If I remember correctly there was some remarks from Kever that we should implement core blocking for decoders etc. With the DT decoder node-names not being "correct" and me not getting any confirmation on the Linux ML this got put on hold / low-priority for me. I think the latest decoder nodes proposed on Linux ML from a few weeks ago are now correct, so I should be able to pick this up again and send a v2, will take a closer look later this weekend after re-spinning some of my other series. Regards, Jonas > > Best regards, > > -- > FUKAUMI Naoki > Radxa Computer (Shenzhen) Co., Ltd. > > On 12/11/24 07:23, Jonas Karlman wrote: >> The RK3582 SoC is a variant of the RK3588S with some IP blocks disabled. >> What blocks are disabled/non-working is indicated by ip-state in OTP. >> >> This add initial support for RK3582 by using ft_system_setup() to mark >> any cpu and/or gpu node with status=fail as indicated by ip-state. >> >> This apply same policy as vendor U-Boot for RK3582, i.e. two big cpu >> cores and the gpu is always failed/disabled. >> >> Enable Kconfig option OF_SYSTEM_SETUP in board defconfig to make use of >> the required DT fixups for RK3582 board variants. >> >> Signed-off-by: Jonas Karlman <jo...@kwiboo.se> >> --- >> arch/arm/mach-rockchip/rk3588/rk3588.c | 128 +++++++++++++++++++++++++ >> 1 file changed, 128 insertions(+) >> >> diff --git a/arch/arm/mach-rockchip/rk3588/rk3588.c >> b/arch/arm/mach-rockchip/rk3588/rk3588.c >> index c1dce3ee3703..06e6318312b2 100644 >> --- a/arch/arm/mach-rockchip/rk3588/rk3588.c >> +++ b/arch/arm/mach-rockchip/rk3588/rk3588.c >> @@ -7,6 +7,7 @@ >> #define LOG_CATEGORY LOGC_ARCH >> >> #include <dm.h> >> +#include <fdt_support.h> >> #include <misc.h> >> #include <spl.h> >> #include <asm/armv8/mmu.h> >> @@ -185,6 +186,12 @@ int arch_cpu_init(void) >> >> #define RK3588_OTP_CPU_CODE_OFFSET 0x02 >> #define RK3588_OTP_SPECIFICATION_OFFSET 0x06 >> +#define RK3588_OTP_IP_STATE_OFFSET 0x1d >> + >> +#define BAD_CPU_CLUSTER0 GENMASK(3, 0) >> +#define BAD_CPU_CLUSTER1 GENMASK(5, 4) >> +#define BAD_CPU_CLUSTER2 GENMASK(7, 6) >> +#define BAD_GPU GENMASK(4, 1) >> >> int checkboard(void) >> { >> @@ -230,3 +237,124 @@ int checkboard(void) >> >> return 0; >> } >> + >> +#ifdef CONFIG_OF_SYSTEM_SETUP >> +static int fdt_path_del_node(void *fdt, const char *path) >> +{ >> + int nodeoffset; >> + >> + nodeoffset = fdt_path_offset(fdt, path); >> + if (nodeoffset < 0) >> + return nodeoffset; >> + >> + return fdt_del_node(fdt, nodeoffset); >> +} >> + >> +static int fdt_path_set_name(void *fdt, const char *path, const char *name) >> +{ >> + int nodeoffset; >> + >> + nodeoffset = fdt_path_offset(fdt, path); >> + if (nodeoffset < 0) >> + return nodeoffset; >> + >> + return fdt_set_name(fdt, nodeoffset, name); >> +} >> + >> +int ft_system_setup(void *blob, struct bd_info *bd) >> +{ >> + static const char * const cpu_node_names[] = { >> + "cpu@0", "cpu@100", "cpu@200", "cpu@300", >> + "cpu@400", "cpu@500", "cpu@600", "cpu@700", >> + }; >> + u8 cpu_code[2], ip_state[3]; >> + int parent, node, i, ret; >> + struct udevice *dev; >> + >> + if (!IS_ENABLED(CONFIG_ROCKCHIP_OTP) || !CONFIG_IS_ENABLED(MISC)) >> + return -ENOSYS; >> + >> + ret = uclass_get_device_by_driver(UCLASS_MISC, >> + DM_DRIVER_GET(rockchip_otp), &dev); >> + if (ret) { >> + log_debug("Could not find otp device, ret=%d\n", ret); >> + return ret; >> + } >> + >> + /* cpu-code: SoC model, e.g. 0x35 0x82 or 0x35 0x88 */ >> + ret = misc_read(dev, RK3588_OTP_CPU_CODE_OFFSET, cpu_code, 2); >> + if (ret < 0) { >> + log_debug("Could not read cpu-code, ret=%d\n", ret); >> + return ret; >> + } >> + >> + log_debug("cpu-code: %02x %02x\n", cpu_code[0], cpu_code[1]); >> + >> + /* skip on rk3588 */ >> + if (cpu_code[0] == 0x35 && cpu_code[1] == 0x88) >> + return 0; >> + >> + ret = misc_read(dev, RK3588_OTP_IP_STATE_OFFSET, &ip_state, 3); >> + if (ret < 0) { >> + log_debug("Could not read ip-state, ret=%d\n", ret); >> + return ret; >> + } >> + >> + log_debug("ip-state: %02x %02x %02x\n", >> + ip_state[0], ip_state[1], ip_state[2]); >> + >> + if (cpu_code[0] == 0x35 && cpu_code[1] == 0x82) { >> + /* policy: always disable gpu */ >> + ip_state[1] |= BAD_GPU; >> + >> + /* policy: always disable one big core cluster */ >> + if (!(ip_state[0] & (BAD_CPU_CLUSTER1 | BAD_CPU_CLUSTER2))) >> + ip_state[0] |= BAD_CPU_CLUSTER2; >> + } >> + >> + if (ip_state[0] & BAD_CPU_CLUSTER1) { >> + /* fail entire cluster when one or more core is bad */ >> + ip_state[0] |= BAD_CPU_CLUSTER1; >> + fdt_path_del_node(blob, "/cpus/cpu-map/cluster1"); >> + } >> + >> + if (ip_state[0] & BAD_CPU_CLUSTER2) { >> + /* fail entire cluster when one or more core is bad */ >> + ip_state[0] |= BAD_CPU_CLUSTER2; >> + fdt_path_del_node(blob, "/cpus/cpu-map/cluster2"); >> + } else if (ip_state[0] & BAD_CPU_CLUSTER1) { >> + /* cluster nodes must be named in a continuous series */ >> + fdt_path_set_name(blob, "/cpus/cpu-map/cluster2", "cluster1"); >> + } >> + >> + /* gpu: ip_state[1]: bit1~4 */ >> + if (ip_state[1] & BAD_GPU) { >> + log_debug("fail gpu\n"); >> + fdt_status_fail_by_pathf(blob, "/gpu@fb000000"); >> + } >> + >> + parent = fdt_path_offset(blob, "/cpus"); >> + if (parent < 0) { >> + log_debug("Could not find /cpus, parent=%d\n", parent); >> + return 0; >> + } >> + >> + /* cpu: ip_state[0]: bit0~7 */ >> + for (i = 0; i < 8; i++) { >> + /* fail any bad cpu core */ >> + if (!(ip_state[0] & BIT(i))) >> + continue; >> + >> + node = fdt_subnode_offset(blob, parent, cpu_node_names[i]); >> + if (node >= 0) { >> + log_debug("fail cpu %s\n", cpu_node_names[i]); >> + fdt_status_fail(blob, node); >> + } else { >> + log_debug("Could not find %s, node=%d\n", >> + cpu_node_names[i], node); >> + } >> + } >> + >> + return 0; >> +} >> +#endif > >