[openwrt/openwrt] uboot-rockchip: add support for Rockchip RK3582

LEDE Commits lede-commits at lists.infradead.org
Sun Sep 7 05:41:38 PDT 2025


hauke pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/547626764bca4321b4aaf5108c7c416d9e472387

commit 547626764bca4321b4aaf5108c7c416d9e472387
Author: FUKAUMI Naoki <naoki at radxa.com>
AuthorDate: Mon Aug 25 15:32:10 2025 +0000

    uboot-rockchip: add support for Rockchip RK3582
    
    Import patches from
     https://patchwork.ozlabs.org/project/uboot/list/?series=468562
    
    Apply patch 3/3 partially due to conflicts.
    
    Signed-off-by: FUKAUMI Naoki <naoki at radxa.com>
    Link: https://github.com/openwrt/openwrt/pull/19867
    Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
 .../110-rockchip-Add-initial-RK3582-support.patch  | 245 +++++++++++++++++++++
 ...-rk3588-generic-Enable-support-for-RK3582.patch |  72 ++++++
 ...3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch |  32 +++
 3 files changed, 349 insertions(+)

diff --git a/package/boot/uboot-rockchip/patches/110-rockchip-Add-initial-RK3582-support.patch b/package/boot/uboot-rockchip/patches/110-rockchip-Add-initial-RK3582-support.patch
new file mode 100644
index 0000000000..a2b576863b
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/110-rockchip-Add-initial-RK3582-support.patch
@@ -0,0 +1,245 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas at kwiboo.se>
+Date: Sun, 10 Aug 2025 22:26:29 +0000
+Subject: rockchip: Add initial RK3582 support
+
+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 vdec/venc 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 one vdec/venc core 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 <jonas at kwiboo.se>
+
+--- 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>
+@@ -192,6 +193,15 @@ 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 FAIL_CPU_CLUSTER0		GENMASK(3, 0)
++#define FAIL_CPU_CLUSTER1		GENMASK(5, 4)
++#define FAIL_CPU_CLUSTER2		GENMASK(7, 6)
++#define FAIL_RKVDEC0			BIT(6)
++#define FAIL_RKVDEC1			BIT(7)
++#define FAIL_RKVENC0			BIT(0)
++#define FAIL_RKVENC1			BIT(2)
+ 
+ int checkboard(void)
+ {
+@@ -237,3 +247,199 @@ int checkboard(void)
+ 
+ 	return 0;
+ }
++
++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);
++}
++
++/*
++ * RK3582 is a variant of the RK3588S with some IP blocks disabled. What blocks
++ * are disabled/non-working is indicated by ip-state in OTP. ft_system_setup()
++ * is used to mark any cpu and/or vdec/venc node with status=fail as indicated
++ * by ip-state. Apply same policy as vendor U-Boot for RK3582, i.e. two big cpu
++ * cores and one vdec/venc core is always failed. Enable OF_SYSTEM_SETUP to make
++ * use of the required DT fixups for RK3582 board variants.
++ */
++int ft_system_setup(void *blob, struct bd_info *bd)
++{
++	static const char * const cpu_node_names[] = {
++		"cpu at 0", "cpu at 100", "cpu at 200", "cpu at 300",
++		"cpu at 400", "cpu at 500", "cpu at 600", "cpu at 700",
++	};
++	int parent, node, i, comp_len, len, ret;
++	bool cluster1_removed = false;
++	u8 cpu_code[2], ip_state[3];
++	struct udevice *dev;
++	char soc_comp[16];
++	const char *comp;
++	void *data;
++
++	if (!IS_ENABLED(CONFIG_OF_SYSTEM_SETUP))
++		return 0;
++
++	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]);
++
++	/* only fail cores on rk3582/rk3583 */
++	if (!(cpu_code[0] == 0x35 && cpu_code[1] == 0x82) &&
++	    !(cpu_code[0] == 0x35 && cpu_code[1] == 0x83))
++		return 0;
++
++	ret = misc_read(dev, RK3588_OTP_IP_STATE_OFFSET, &ip_state, 3);
++	if (ret < 0) {
++		log_err("Could not read ip-state, ret=%d\n", ret);
++		return ret;
++	}
++
++	log_debug("ip-state: %02x %02x %02x (otp)\n",
++		  ip_state[0], ip_state[1], ip_state[2]);
++
++	/* policy: fail entire big core cluster when one or more core is bad */
++	if (ip_state[0] & FAIL_CPU_CLUSTER1)
++		ip_state[0] |= FAIL_CPU_CLUSTER1;
++	if (ip_state[0] & FAIL_CPU_CLUSTER2)
++		ip_state[0] |= FAIL_CPU_CLUSTER2;
++
++	/* policy: always fail one big core cluster on rk3582/rk3583 */
++	if (!(ip_state[0] & (FAIL_CPU_CLUSTER1 | FAIL_CPU_CLUSTER2)))
++		ip_state[0] |= FAIL_CPU_CLUSTER2;
++
++	/* policy: always fail one rkvdec core on rk3582/rk3583 */
++	if (!(ip_state[1] & (FAIL_RKVDEC0 | FAIL_RKVDEC1)))
++		ip_state[1] |= FAIL_RKVDEC1;
++
++	/* policy: always fail one rkvenc core on rk3582/rk3583 */
++	if (!(ip_state[2] & (FAIL_RKVENC0 | FAIL_RKVENC1)))
++		ip_state[2] |= FAIL_RKVENC1;
++
++	log_debug("ip-state: %02x %02x %02x (policy)\n",
++		  ip_state[0], ip_state[1], ip_state[2]);
++
++	/* cpu cluster1: ip_state[0]: bit4~5 */
++	if ((ip_state[0] & FAIL_CPU_CLUSTER1) == FAIL_CPU_CLUSTER1) {
++		log_debug("remove cpu-map cluster1\n");
++		fdt_path_del_node(blob, "/cpus/cpu-map/cluster1");
++		cluster1_removed = true;
++	}
++
++	/* cpu cluster2: ip_state[0]: bit6~7 */
++	if ((ip_state[0] & FAIL_CPU_CLUSTER2) == FAIL_CPU_CLUSTER2) {
++		log_debug("remove cpu-map cluster2\n");
++		fdt_path_del_node(blob, "/cpus/cpu-map/cluster2");
++	} else if (cluster1_removed) {
++		/* cluster nodes must be named in a continuous series */
++		log_debug("rename cpu-map cluster2\n");
++		fdt_path_set_name(blob, "/cpus/cpu-map/cluster2", "cluster1");
++	}
++
++	/* rkvdec: ip_state[1]: bit6,7 */
++	if (ip_state[1] & FAIL_RKVDEC0) {
++		log_debug("fail rkvdec0\n");
++		fdt_status_fail_by_pathf(blob, "/video-codec at fdc38100");
++		fdt_status_fail_by_pathf(blob, "/iommu at fdc38700");
++	}
++	if (ip_state[1] & FAIL_RKVDEC1) {
++		log_debug("fail rkvdec1\n");
++		fdt_status_fail_by_pathf(blob, "/video-codec at fdc40100");
++		fdt_status_fail_by_pathf(blob, "/iommu at fdc40700");
++	}
++
++	/* rkvenc: ip_state[2]: bit0,2 */
++	if (ip_state[2] & FAIL_RKVENC0) {
++		log_debug("fail rkvenc0\n");
++		fdt_status_fail_by_pathf(blob, "/video-codec at fdbd0000");
++		fdt_status_fail_by_pathf(blob, "/iommu at fdbdf000");
++	}
++	if (ip_state[2] & FAIL_RKVENC1) {
++		log_debug("fail rkvenc1\n");
++		fdt_status_fail_by_pathf(blob, "/video-codec at fdbe0000");
++		fdt_status_fail_by_pathf(blob, "/iommu at fdbef000");
++	}
++
++	parent = fdt_path_offset(blob, "/cpus");
++	if (parent < 0) {
++		log_err("Could not find /cpus, parent=%d\n", parent);
++		return parent;
++	}
++
++	/* 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_err("Could not find %s, node=%d\n",
++				cpu_node_names[i], node);
++			return node;
++		}
++	}
++
++	node = fdt_path_offset(blob, "/");
++	if (node < 0) {
++		log_err("Could not find /, node=%d\n", node);
++		return node;
++	}
++
++	snprintf(soc_comp, sizeof(soc_comp), "rockchip,rk35%x", cpu_code[1]);
++
++	for (i = 0, comp_len = 0;
++	     (comp = fdt_stringlist_get(blob, node, "compatible", i, &len));
++	     i++) {
++		/* stop at soc compatible */
++		if (!strcmp(comp, soc_comp) ||
++		    !strcmp(comp, "rockchip,rk3588s") ||
++		    !strcmp(comp, "rockchip,rk3588"))
++			break;
++
++		log_debug("compatible[%d]: %s\n", i, comp);
++		comp_len += len + 1;
++	}
++
++	/* truncate to only include board compatible */
++	fdt_setprop_placeholder(blob, node, "compatible", comp_len, &data);
++
++	/* append soc compatible */
++	fdt_appendprop_string(blob, node, "compatible", soc_comp);
++	fdt_appendprop_string(blob, node, "compatible", "rockchip,rk3588s");
++
++	return 0;
++}
diff --git a/package/boot/uboot-rockchip/patches/111-rockchip-rk3588-generic-Enable-support-for-RK3582.patch b/package/boot/uboot-rockchip/patches/111-rockchip-rk3588-generic-Enable-support-for-RK3582.patch
new file mode 100644
index 0000000000..c20d6ca40c
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/111-rockchip-rk3588-generic-Enable-support-for-RK3582.patch
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas at kwiboo.se>
+Date: Sun, 10 Aug 2025 22:26:30 +0000
+Subject: rockchip: rk3588-generic: Enable support for RK3582
+
+Add Kconfig option OF_SYSTEM_SETUP=y to support booting boards with a
+RK3582 SoC. CPU and GPU cores are failed based on ip-state and policy.
+
+Tested on a ROCK 5C Lite v1.1:
+
+  cpu-code: 35 82
+  ip-state: 10 00 00 (otp)
+  ip-state: 30 80 04 (policy)
+  remove cpu-map cluster1
+  rename cpu-map cluster2
+  fail rkvdec1
+  fail rkvenc1
+  fail cpu cpu at 400
+  fail cpu cpu at 500
+
+and on a Radxa E52C:
+
+  cpu-code: 35 82
+  ip-state: 00 04 00 (otp)
+  ip-state: c0 84 04 (policy)
+  remove cpu-map cluster2
+  fail rkvdec1
+  fail rkvenc1
+  fail cpu cpu at 600
+  fail cpu cpu at 700
+
+Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
+
+--- a/arch/arm/dts/rk3588-generic.dts
++++ b/arch/arm/dts/rk3588-generic.dts
+@@ -1,13 +1,13 @@
+ // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ /*
+- * Minimal generic DT for RK3588S/RK3588 with eMMC, SD-card and USB OTG enabled
++ * Minimal generic DT for RK3582/RK3588S/RK3588 with eMMC, SD-card and USB OTG enabled
+  */
+ 
+ /dts-v1/;
+ #include "rk3588s.dtsi"
+ 
+ / {
+-	model = "Generic RK3588S/RK3588";
++	model = "Generic RK3582/RK3588S/RK3588";
+ 	compatible = "rockchip,rk3588";
+ 
+ 	aliases {
+--- a/configs/generic-rk3588_defconfig
++++ b/configs/generic-rk3588_defconfig
+@@ -16,6 +16,7 @@ CONFIG_SPL_FIT_SIGNATURE=y
+ CONFIG_SPL_LOAD_FIT=y
+ # CONFIG_BOOTMETH_VBE is not set
+ CONFIG_LEGACY_IMAGE_FORMAT=y
++CONFIG_OF_SYSTEM_SETUP=y
+ CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-generic.dtb"
+ # CONFIG_DISPLAY_CPUINFO is not set
+ CONFIG_SPL_MAX_SIZE=0x40000
+--- a/doc/board/rockchip/rockchip.rst
++++ b/doc/board/rockchip/rockchip.rst
+@@ -145,7 +145,7 @@ List of mainline supported Rockchip boar
+      - FriendlyElec NanoPC-T6 (nanopc-t6-rk3588)
+      - FriendlyElec NanoPi R6C (nanopi-r6c-rk3588s)
+      - FriendlyElec NanoPi R6S (nanopi-r6s-rk3588s)
+-     - Generic RK3588S/RK3588 (generic-rk3588)
++     - Generic RK3582/RK3588S/RK3588 (generic-rk3588)
+      - Hardkernel ODROID-M2 (odroid-m2-rk3588s)
+      - Indiedroid Nova (nova-rk3588s)
+      - Khadas Edge2 (khadas-edge2-rk3588s)
diff --git a/package/boot/uboot-rockchip/patches/112-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch b/package/boot/uboot-rockchip/patches/112-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch
new file mode 100644
index 0000000000..a69f9d87ef
--- /dev/null
+++ b/package/boot/uboot-rockchip/patches/112-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch
@@ -0,0 +1,32 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <jonas at kwiboo.se>
+Date: Sun, 10 Aug 2025 22:26:31 +0000
+Subject: rockchip: rk3588s-rock-5c: Add support for ROCK 5C Lite variant
+
+Add Kconfig option OF_SYSTEM_SETUP=y to support booting ROCK 5C Lite
+boards with a RK3582 SoC. CPU and GPU cores are failed based on ip-state
+and policy.
+
+Tested on a ROCK 5C Lite v1.1:
+
+  cpu-code: 35 82
+  ip-state: 00 80 00 (otp)
+  ip-state: c0 80 04 (policy)
+  remove cpu-map cluster2
+  fail rkvdec1
+  fail rkvenc1
+  fail cpu cpu at 600
+  fail cpu cpu at 700
+
+Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
+
+--- a/configs/rock-5c-rk3588s_defconfig
++++ b/configs/rock-5c-rk3588s_defconfig
+@@ -18,6 +18,7 @@ CONFIG_FIT_VERBOSE=y
+ CONFIG_SPL_FIT_SIGNATURE=y
+ CONFIG_SPL_LOAD_FIT=y
+ CONFIG_LEGACY_IMAGE_FORMAT=y
++CONFIG_OF_SYSTEM_SETUP=y
+ CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-rock-5c.dtb"
+ # CONFIG_DISPLAY_CPUINFO is not set
+ CONFIG_SPL_MAX_SIZE=0x40000




More information about the lede-commits mailing list