uboot-rockchip: backport RK3576 support
authorTianling Shen <[email protected]>
Sat, 13 Sep 2025 11:49:36 +0000 (19:49 +0800)
committerHauke Mehrtens <[email protected]>
Thu, 2 Oct 2025 20:42:35 +0000 (22:42 +0200)
Backport core support for RK3576 SoCs.

Signed-off-by: Tianling Shen <[email protected]>
Link: https://github.com/openwrt/openwrt/pull/20041
Signed-off-by: Hauke Mehrtens <[email protected]>
26 files changed:
package/boot/uboot-rockchip/patches/001-rockchip-rockchip-inno-usb2-Fix-Synchronous-Abort-on-usb.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/002-rng-rockchip_rng-Add-compatible-for-RK3576.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/003-rockchip-Add-default-USB_GADGET_PRODUCT_NUM-for-RK3576.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/004-board-rockchip-Add-minimal-generic-RK3576-board.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/005-rockchip-rk3576-Implement-to-print-SoC-variant.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/006-arm-dts-rockchip-Include-OTP-in-U-Boot-pre-reloc-phase-fo.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/007-usb-dwc3-generic-Use-combined-glue-and-ctrl-node-for-RK35.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/008-phy-rockchip-inno-usb2-Add-support-for-RK3576.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/009-phy-rockchip-usbdp-Add-support-for-RK3576.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/010-rockchip-clk-clk_rk3576-Add-dummy-CLK_REF_PCIEx_PHY.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/011-phy-rockchip-naneng-combphy-Add-support-for-RK3576.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/012-phy-rockchip-usbdp-Fix-Generic-PHY-reference-counting.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/013-phy-rockchip-naneng-combphy-Simplify-init-ops.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/014-phy-rockchip-naneng-combphy-Use-syscon_regmap_lookup_by_p.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/015-phy-rockchip-inno-usb2-Fix-improper-use-of-UCLASS_PHY.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/016-phy-rockchip-typec-Fix-improper-use-of-UCLASS_PHY.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/017-rockchip-rk3588-Disable-USB3OTG-U3-ports-early.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/018-rockchip-rk3576-Disable-USB3OTG0-U3-port-early.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/101-nanopc-t4-fix-memory-unstability.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/102-rockchip-Add-initial-RK3582-support.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/103-rockchip-rk3588-generic-Enable-support-for-RK3582.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/104-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch [new file with mode: 0644]
package/boot/uboot-rockchip/patches/105-nanopc-t4-fix-memory-unstability.patch [deleted file]
package/boot/uboot-rockchip/patches/110-rockchip-Add-initial-RK3582-support.patch [deleted file]
package/boot/uboot-rockchip/patches/111-rockchip-rk3588-generic-Enable-support-for-RK3582.patch [deleted file]
package/boot/uboot-rockchip/patches/112-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch [deleted file]

diff --git a/package/boot/uboot-rockchip/patches/001-rockchip-rockchip-inno-usb2-Fix-Synchronous-Abort-on-usb.patch b/package/boot/uboot-rockchip/patches/001-rockchip-rockchip-inno-usb2-Fix-Synchronous-Abort-on-usb.patch
new file mode 100644 (file)
index 0000000..347aaba
--- /dev/null
@@ -0,0 +1,73 @@
+From 1848a504379531eb726d29b355f9038d194e8430 Mon Sep 17 00:00:00 2001
+From: Alex Shumsky <[email protected]>
+Date: Thu, 3 Jul 2025 09:04:48 +0300
+Subject: [PATCH] rockchip: rockchip-inno-usb2: Fix Synchronous Abort on usb
+ start
+
+Fix NULL pointer dereference that happen when rockchip-inno-usb2 clock
+enabled before device probe. This early clock enable call happen in process
+of parent clock activation added in ac30d90f3367.
+
+Fixes: 229218373c22 ("phy: rockchip-inno-usb2: Add support for clkout_ctl_phy").
+Fixes: ac30d90f3367 ("clk: Ensure the parent clocks are enabled while reparenting")
+Co-authored-by: Jonas Karlman <[email protected]>
+Signed-off-by: Alex Shumsky <[email protected]>
+Reviewed-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -167,20 +167,27 @@ static struct phy_ops rockchip_usb2phy_o
+       .of_xlate = rockchip_usb2phy_of_xlate,
+ };
+-static void rockchip_usb2phy_clkout_ctl(struct clk *clk, struct regmap **base,
+-                                      const struct usb2phy_reg **clkout_ctl)
++static int rockchip_usb2phy_clkout_ctl(struct clk *clk, struct regmap **base,
++                                     const struct usb2phy_reg **clkout_ctl)
+ {
+       struct udevice *parent = dev_get_parent(clk->dev);
+       struct rockchip_usb2phy *priv = dev_get_priv(parent);
+       const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg;
+-      if (priv->phy_cfg->clkout_ctl_phy.enable) {
++      // phy_cfg can be NULL if this function called before probe (when parent
++      // clocks are enabled)
++      if (!phy_cfg)
++              return -EINVAL;
++
++      if (phy_cfg->clkout_ctl_phy.enable) {
+               *base = priv->phy_base;
+               *clkout_ctl = &phy_cfg->clkout_ctl_phy;
+       } else {
+               *base = priv->reg_base;
+               *clkout_ctl = &phy_cfg->clkout_ctl;
+       }
++
++      return 0;
+ }
+ /**
+@@ -206,7 +213,8 @@ int rockchip_usb2phy_clk_enable(struct c
+       const struct usb2phy_reg *clkout_ctl;
+       struct regmap *base;
+-      rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl);
++      if (rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl))
++              return -ENOSYS;
+       /* turn on 480m clk output if it is off */
+       if (!property_enabled(base, clkout_ctl)) {
+@@ -230,7 +238,8 @@ int rockchip_usb2phy_clk_disable(struct
+       const struct usb2phy_reg *clkout_ctl;
+       struct regmap *base;
+-      rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl);
++      if (rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl))
++              return -ENOSYS;
+       /* turn off 480m clk output */
+       property_enable(base, clkout_ctl, false);
diff --git a/package/boot/uboot-rockchip/patches/002-rng-rockchip_rng-Add-compatible-for-RK3576.patch b/package/boot/uboot-rockchip/patches/002-rng-rockchip_rng-Add-compatible-for-RK3576.patch
new file mode 100644 (file)
index 0000000..dbc9f1f
--- /dev/null
@@ -0,0 +1,38 @@
+From d079cdbc53026dca2c4209ee71c883de7fe0cc14 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:37 +0000
+Subject: [PATCH] rng: rockchip_rng: Add compatible for RK3576
+
+The RK3576 SoC contains a RKRNG block that can be used to generate
+random numbers using the rockchip_rng driver.
+
+Add compatible for RK3576 to support random numbers:
+
+  => rng list
+  RNG #0 - rng@2a410000
+
+  => rng
+  00000000: 36 dd ab 98 ec fb fe d1 cf 36 b3 e1 9b 3d 00 90  6........6...=..
+  00000010: f5 84 de 75 6b 27 48 9e 13 62 12 6c 50 ca 47 1a  ...uk'H..b.lP.G.
+  00000020: b3 4d fc 43 c5 b5 2d be 07 27 03 26 bb 69 61 2a  .M.C..-..'.&.ia*
+  00000030: 6f 70 01 83 4e ce 91 7a 5a 6c 7c 00 43 87 3e c5  op..N..zZl|.C.>.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/rng/rockchip_rng.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/rng/rockchip_rng.c
++++ b/drivers/rng/rockchip_rng.c
+@@ -394,6 +394,10 @@ static const struct udevice_id rockchip_
+               .data = (ulong)&rk_trngv1_soc_data,
+       },
+       {
++              .compatible = "rockchip,rk3576-rng",
++              .data = (ulong)&rkrng_soc_data,
++      },
++      {
+               .compatible = "rockchip,rkrng",
+               .data = (ulong)&rkrng_soc_data,
+       },
diff --git a/package/boot/uboot-rockchip/patches/003-rockchip-Add-default-USB_GADGET_PRODUCT_NUM-for-RK3576.patch b/package/boot/uboot-rockchip/patches/003-rockchip-Add-default-USB_GADGET_PRODUCT_NUM-for-RK3576.patch
new file mode 100644 (file)
index 0000000..6bebd2c
--- /dev/null
@@ -0,0 +1,25 @@
+From dd2c7df419ae8a5cc5f7ee0480218b0ae28d4926 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:38 +0000
+Subject: [PATCH] rockchip: Add default USB_GADGET_PRODUCT_NUM for RK3576
+
+Use 0x350e as the default USB Product ID for Rockchip RK3576, same PID
+being used by the BootROM when the device is in MASKROM mode.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Mattijs Korpershoek <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/usb/gadget/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/gadget/Kconfig
++++ b/drivers/usb/gadget/Kconfig
+@@ -86,6 +86,7 @@ config USB_GADGET_PRODUCT_NUM
+       default 0x350a if ROCKCHIP_RK3568
+       default 0x350b if ROCKCHIP_RK3588
+       default 0x350c if ROCKCHIP_RK3528
++      default 0x350e if ROCKCHIP_RK3576
+       default 0x0
+       help
+         Product ID of the USB device emulated, reported to the host device.
diff --git a/package/boot/uboot-rockchip/patches/004-board-rockchip-Add-minimal-generic-RK3576-board.patch b/package/boot/uboot-rockchip/patches/004-board-rockchip-Add-minimal-generic-RK3576-board.patch
new file mode 100644 (file)
index 0000000..f0a6055
--- /dev/null
@@ -0,0 +1,1029 @@
+From 108d9f11ea928a80976db80b5ff723ce8170ebe1 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:39 +0000
+Subject: [PATCH] board: rockchip: Add minimal generic RK3576 board
+
+Add a minimal generic RK3576 board that only have eMMC, SDMMC and USB
+OTG enabled. This defconfig can be used to boot from eMMC or SD-card on
+most RK3576 boards that follow reference board design.
+
+eMMC and SD-card boot tested on:
+- ArmSoM CM5
+- ArmSoM Sige5
+- FriendlyElec NanoPi M5
+- Luckfox Omni3576
+- Toybrick TB-RK3576D
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ arch/arm/dts/rk3576-generic-u-boot.dtsi   |  3 ++
+ arch/arm/dts/rk3576-generic.dts           | 63 +++++++++++++++++++++++
+ arch/arm/mach-rockchip/rk3576/MAINTAINERS |  5 ++
+ configs/generic-rk3576_defconfig          | 50 ++++++++++++++++++
+ doc/board/rockchip/rockchip.rst           |  1 +
+ 5 files changed, 122 insertions(+)
+ create mode 100644 arch/arm/dts/rk3576-generic-u-boot.dtsi
+ create mode 100644 arch/arm/dts/rk3576-generic.dts
+ create mode 100644 arch/arm/mach-rockchip/rk3576/MAINTAINERS
+ create mode 100644 configs/generic-rk3576_defconfig
+
+--- a/dts/upstream/include/dt-bindings/clock/rockchip,rk3576-cru.h
++++ b/dts/upstream/include/dt-bindings/clock/rockchip,rk3576-cru.h
+@@ -589,4 +589,19 @@
+ #define PCLK_EDP_S                    569
+ #define ACLK_KLAD                     570
++/* SCMI clocks, use these when changing clocks through SCMI */
++#define SCMI_ARMCLK_L                 10
++#define SCMI_ARMCLK_B                 11
++#define SCMI_CLK_GPU                  456
++
++/* IOC-controlled output clocks */
++#define CLK_SAI0_MCLKOUT_TO_IO                571
++#define CLK_SAI1_MCLKOUT_TO_IO                572
++#define CLK_SAI2_MCLKOUT_TO_IO                573
++#define CLK_SAI3_MCLKOUT_TO_IO                574
++#define CLK_SAI4_MCLKOUT_TO_IO                575
++#define CLK_SAI4_MCLKOUT_TO_IO                575
++#define CLK_FSPI0_TO_IO                       576
++#define CLK_FSPI1_TO_IO                       577
++
+ #endif
+--- a/dts/upstream/src/arm64/rockchip/rk3576.dtsi
++++ b/dts/upstream/src/arm64/rockchip/rk3576.dtsi
+@@ -111,7 +111,7 @@
+                       reg = <0x0>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <485>;
+-                      clocks = <&scmi_clk ARMCLK_L>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_L>;
+                       operating-points-v2 = <&cluster0_opp_table>;
+                       #cooling-cells = <2>;
+                       dynamic-power-coefficient = <120>;
+@@ -124,7 +124,7 @@
+                       reg = <0x1>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <485>;
+-                      clocks = <&scmi_clk ARMCLK_L>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_L>;
+                       operating-points-v2 = <&cluster0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+               };
+@@ -135,7 +135,7 @@
+                       reg = <0x2>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <485>;
+-                      clocks = <&scmi_clk ARMCLK_L>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_L>;
+                       operating-points-v2 = <&cluster0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+               };
+@@ -146,7 +146,7 @@
+                       reg = <0x3>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <485>;
+-                      clocks = <&scmi_clk ARMCLK_L>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_L>;
+                       operating-points-v2 = <&cluster0_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+               };
+@@ -157,7 +157,7 @@
+                       reg = <0x100>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
+-                      clocks = <&scmi_clk ARMCLK_B>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_B>;
+                       operating-points-v2 = <&cluster1_opp_table>;
+                       #cooling-cells = <2>;
+                       dynamic-power-coefficient = <320>;
+@@ -170,7 +170,7 @@
+                       reg = <0x101>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
+-                      clocks = <&scmi_clk ARMCLK_B>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_B>;
+                       operating-points-v2 = <&cluster1_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+               };
+@@ -181,7 +181,7 @@
+                       reg = <0x102>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
+-                      clocks = <&scmi_clk ARMCLK_B>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_B>;
+                       operating-points-v2 = <&cluster1_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+               };
+@@ -192,7 +192,7 @@
+                       reg = <0x103>;
+                       enable-method = "psci";
+                       capacity-dmips-mhz = <1024>;
+-                      clocks = <&scmi_clk ARMCLK_B>;
++                      clocks = <&scmi_clk SCMI_ARMCLK_B>;
+                       operating-points-v2 = <&cluster1_opp_table>;
+                       cpu-idle-states = <&CPU_SLEEP>;
+               };
+@@ -393,6 +393,11 @@
+               };
+       };
++      display_subsystem: display-subsystem {
++              compatible = "rockchip,display-subsystem";
++              ports = <&vop_out>;
++      };
++
+       firmware {
+               scmi: scmi {
+                       compatible = "arm,scmi-smc";
+@@ -408,6 +413,90 @@
+               };
+       };
++      hdmi_sound: hdmi-sound {
++              compatible = "simple-audio-card";
++              simple-audio-card,name = "HDMI";
++              simple-audio-card,format = "i2s";
++              simple-audio-card,mclk-fs = <256>;
++              status = "disabled";
++
++              simple-audio-card,codec {
++                      sound-dai = <&hdmi>;
++              };
++
++              simple-audio-card,cpu {
++                      sound-dai = <&sai6>;
++              };
++      };
++
++      pinctrl: pinctrl {
++              compatible = "rockchip,rk3576-pinctrl";
++              rockchip,grf = <&ioc_grf>;
++              #address-cells = <2>;
++              #size-cells = <2>;
++              ranges;
++
++              gpio0: gpio@27320000 {
++                      compatible = "rockchip,gpio-bank";
++                      reg = <0x0 0x27320000 0x0 0x200>;
++                      clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
++                      gpio-controller;
++                      gpio-ranges = <&pinctrl 0 0 32>;
++                      interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-controller;
++                      #gpio-cells = <2>;
++                      #interrupt-cells = <2>;
++              };
++
++              gpio1: gpio@2ae10000 {
++                      compatible = "rockchip,gpio-bank";
++                      reg = <0x0 0x2ae10000 0x0 0x200>;
++                      clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
++                      gpio-controller;
++                      gpio-ranges = <&pinctrl 0 32 32>;
++                      interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-controller;
++                      #gpio-cells = <2>;
++                      #interrupt-cells = <2>;
++              };
++
++              gpio2: gpio@2ae20000 {
++                      compatible = "rockchip,gpio-bank";
++                      reg = <0x0 0x2ae20000 0x0 0x200>;
++                      clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
++                      gpio-controller;
++                      gpio-ranges = <&pinctrl 0 64 32>;
++                      interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-controller;
++                      #gpio-cells = <2>;
++                      #interrupt-cells = <2>;
++              };
++
++              gpio3: gpio@2ae30000 {
++                      compatible = "rockchip,gpio-bank";
++                      reg = <0x0 0x2ae30000 0x0 0x200>;
++                      clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
++                      gpio-controller;
++                      gpio-ranges = <&pinctrl 0 96 32>;
++                      interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-controller;
++                      #gpio-cells = <2>;
++                      #interrupt-cells = <2>;
++              };
++
++              gpio4: gpio@2ae40000 {
++                      compatible = "rockchip,gpio-bank";
++                      reg = <0x0 0x2ae40000 0x0 0x200>;
++                      clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
++                      gpio-controller;
++                      gpio-ranges = <&pinctrl 0 128 32>;
++                      interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-controller;
++                      #gpio-cells = <2>;
++                      #interrupt-cells = <2>;
++              };
++      };
++
+       pmu_a53: pmu-a53 {
+               compatible = "arm,cortex-a53-pmu";
+               interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+@@ -445,6 +534,114 @@
+               #size-cells = <2>;
+               ranges;
++              pcie0: pcie@22000000 {
++                      compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
++                      reg = <0x0 0x22000000 0x0 0x00400000>,
++                            <0x0 0x2a200000 0x0 0x00010000>,
++                            <0x0 0x20000000 0x0 0x00100000>;
++                      reg-names = "dbi", "apb", "config";
++                      bus-range = <0x0 0xf>;
++                      clocks = <&cru ACLK_PCIE0_MST>, <&cru ACLK_PCIE0_SLV>,
++                               <&cru ACLK_PCIE0_DBI>, <&cru PCLK_PCIE0>,
++                               <&cru CLK_PCIE0_AUX>;
++                      clock-names = "aclk_mst", "aclk_slv",
++                                    "aclk_dbi", "pclk",
++                                    "aux";
++                      device_type = "pci";
++                      interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 278 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "sys", "pmc", "msg", "legacy", "err", "msi";
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 7>;
++                      interrupt-map = <0 0 0 1 &pcie0_intc 0>,
++                                      <0 0 0 2 &pcie0_intc 1>,
++                                      <0 0 0 3 &pcie0_intc 2>,
++                                      <0 0 0 4 &pcie0_intc 3>;
++                      linux,pci-domain = <0>;
++                      max-link-speed = <2>;
++                      num-ib-windows = <8>;
++                      num-viewport = <8>;
++                      num-ob-windows = <2>;
++                      num-lanes = <1>;
++                      phys = <&combphy0_ps PHY_TYPE_PCIE>;
++                      phy-names = "pcie-phy";
++                      power-domains = <&power RK3576_PD_PHP>;
++                      ranges = <0x01000000 0x0 0x20100000 0x0 0x20100000 0x0 0x00100000
++                                0x02000000 0x0 0x20200000 0x0 0x20200000 0x0 0x00e00000
++                                0x03000000 0x9 0x00000000 0x9 0x00000000 0x0 0x80000000>;
++                      resets = <&cru SRST_PCIE0_POWER_UP>, <&cru SRST_P_PCIE0>;
++                      reset-names = "pwr", "pipe";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      status = "disabled";
++
++                      pcie0_intc: legacy-interrupt-controller {
++                              interrupt-controller;
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-parent = <&gic>;
++                              interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>;
++                      };
++              };
++
++              pcie1: pcie@22400000 {
++                      compatible = "rockchip,rk3576-pcie", "rockchip,rk3568-pcie";
++                      reg = <0x0 0x22400000 0x0 0x00400000>,
++                            <0x0 0x2a210000 0x0 0x00010000>,
++                            <0x0 0x21000000 0x0 0x00100000>;
++                      reg-names = "dbi", "apb", "config";
++                      bus-range = <0x20 0x2f>;
++                      clocks = <&cru ACLK_PCIE1_MST>, <&cru ACLK_PCIE1_SLV>,
++                               <&cru ACLK_PCIE1_DBI>, <&cru PCLK_PCIE1>,
++                               <&cru CLK_PCIE1_AUX>;
++                      clock-names = "aclk_mst", "aclk_slv",
++                                    "aclk_dbi", "pclk",
++                                    "aux";
++                      device_type = "pci";
++                      interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "sys", "pmc", "msg", "legacy", "err", "msi";
++                      #interrupt-cells = <1>;
++                      interrupt-map-mask = <0 0 0 7>;
++                      interrupt-map = <0 0 0 1 &pcie1_intc 0>,
++                                      <0 0 0 2 &pcie1_intc 1>,
++                                      <0 0 0 3 &pcie1_intc 2>,
++                                      <0 0 0 4 &pcie1_intc 3>;
++                      linux,pci-domain = <1>;
++                      max-link-speed = <2>;
++                      num-ib-windows = <8>;
++                      num-viewport = <8>;
++                      num-ob-windows = <2>;
++                      num-lanes = <1>;
++                      phys = <&combphy1_psu PHY_TYPE_PCIE>;
++                      phy-names = "pcie-phy";
++                      power-domains = <&power RK3576_PD_SUBPHP>;
++                      ranges = <0x01000000 0x0 0x21100000 0x0 0x21100000 0x0 0x00100000
++                                0x02000000 0x0 0x21200000 0x0 0x21200000 0x0 0x00e00000
++                                0x03000000 0x9 0x80000000 0x9 0x80000000 0x0 0x80000000>;
++                      resets = <&cru SRST_PCIE1_POWER_UP>, <&cru SRST_P_PCIE1>;
++                      reset-names = "pwr", "pipe";
++                      #address-cells = <3>;
++                      #size-cells = <2>;
++                      status = "disabled";
++
++                      pcie1_intc: legacy-interrupt-controller {
++                              interrupt-controller;
++                              #address-cells = <0>;
++                              #interrupt-cells = <1>;
++                              interrupt-parent = <&gic>;
++                              interrupts = <GIC_SPI 266 IRQ_TYPE_EDGE_RISING>;
++                      };
++              };
++
+               usb_drd0_dwc3: usb@23000000 {
+                       compatible = "rockchip,rk3576-dwc3", "snps,dwc3";
+                       reg = <0x0 0x23000000 0x0 0x400000>;
+@@ -620,6 +817,11 @@
+                       };
+               };
++              hdptxphy_grf: syscon@26032000 {
++                      compatible = "rockchip,rk3576-hdptxphy-grf", "syscon";
++                      reg = <0x0 0x26032000 0x0 0x100>;
++              };
++
+               vo1_grf: syscon@26036000 {
+                       compatible = "rockchip,rk3576-vo1-grf", "syscon";
+                       reg = <0x0 0x26036000 0x0 0x100>;
+@@ -922,7 +1124,7 @@
+               gpu: gpu@27800000 {
+                       compatible = "rockchip,rk3576-mali", "arm,mali-bifrost";
+                       reg = <0x0 0x27800000 0x0 0x200000>;
+-                      assigned-clocks = <&scmi_clk CLK_GPU>;
++                      assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+                       assigned-clock-rates = <198000000>;
+                       clocks = <&cru CLK_GPU>;
+                       clock-names = "core";
+@@ -937,6 +1139,196 @@
+                       status = "disabled";
+               };
++              vop: vop@27d00000 {
++                      compatible = "rockchip,rk3576-vop";
++                      reg = <0x0 0x27d00000 0x0 0x3000>, <0x0 0x27d05000 0x0 0x1000>;
++                      reg-names = "vop", "gamma-lut";
++                      interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 380 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "sys",
++                                        "vp0",
++                                        "vp1",
++                                        "vp2";
++                      clocks = <&cru ACLK_VOP>,
++                               <&cru HCLK_VOP>,
++                               <&cru DCLK_VP0>,
++                               <&cru DCLK_VP1>,
++                               <&cru DCLK_VP2>;
++                      clock-names = "aclk",
++                                    "hclk",
++                                    "dclk_vp0",
++                                    "dclk_vp1",
++                                    "dclk_vp2";
++                      iommus = <&vop_mmu>;
++                      power-domains = <&power RK3576_PD_VOP>;
++                      rockchip,grf = <&sys_grf>;
++                      rockchip,pmu = <&pmu>;
++                      status = "disabled";
++
++                      vop_out: ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              vp0: port@0 {
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++                                      reg = <0>;
++                              };
++
++                              vp1: port@1 {
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++                                      reg = <1>;
++                              };
++
++                              vp2: port@2 {
++                                      #address-cells = <1>;
++                                      #size-cells = <0>;
++                                      reg = <2>;
++                              };
++                      };
++              };
++
++              vop_mmu: iommu@27d07e00 {
++                      compatible = "rockchip,rk3576-iommu", "rockchip,rk3568-iommu";
++                      reg = <0x0 0x27d07e00 0x0 0x100>, <0x0 0x27d07f00 0x0 0x100>;
++                      interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
++                      clock-names = "aclk", "iface";
++                      #iommu-cells = <0>;
++                      power-domains = <&power RK3576_PD_VOP>;
++                      status = "disabled";
++              };
++
++              sai5: sai@27d40000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x27d40000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI5_8CH>, <&cru HCLK_SAI5_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac2 3>;
++                      dma-names = "rx";
++                      power-domains = <&power RK3576_PD_VO0>;
++                      resets = <&cru SRST_M_SAI5_8CH>, <&cru SRST_H_SAI5_8CH>;
++                      reset-names = "m", "h";
++                      rockchip,sai-rx-route = <0 1 2 3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI5";
++                      status = "disabled";
++              };
++
++              sai6: sai@27d50000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x27d50000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI6_8CH>, <&cru HCLK_SAI6_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac2 4>, <&dmac2 5>;
++                      dma-names = "tx", "rx";
++                      power-domains = <&power RK3576_PD_VO0>;
++                      resets = <&cru SRST_M_SAI6_8CH>, <&cru SRST_H_SAI6_8CH>;
++                      reset-names = "m", "h";
++                      rockchip,sai-rx-route = <0 1 2 3>;
++                      rockchip,sai-tx-route = <0 1 2 3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI6";
++                      status = "disabled";
++              };
++
++              hdmi: hdmi@27da0000 {
++                      compatible = "rockchip,rk3576-dw-hdmi-qp";
++                      reg = <0x0 0x27da0000 0x0 0x20000>;
++                      clocks = <&cru PCLK_HDMITX0>,
++                               <&cru CLK_HDMITX0_EARC>,
++                               <&cru CLK_HDMITX0_REF>,
++                               <&cru MCLK_SAI6_8CH>,
++                               <&cru CLK_HDMITXHDP>,
++                               <&cru HCLK_VO0_ROOT>;
++                      clock-names = "pclk", "earc", "ref", "aud", "hdp", "hclk_vo1";
++                      interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
++                                   <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH>;
++                      interrupt-names = "avp", "cec", "earc", "main", "hpd";
++                      phys = <&hdptxphy>;
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&hdmi_txm0_pins &hdmi_tx_scl &hdmi_tx_sda>;
++                      power-domains = <&power RK3576_PD_VO0>;
++                      resets = <&cru SRST_HDMITX0_REF>, <&cru SRST_HDMITXHDP>;
++                      reset-names = "ref", "hdp";
++                      rockchip,grf = <&ioc_grf>;
++                      rockchip,vo-grf = <&vo0_grf>;
++                      #sound-dai-cells = <0>;
++                      status = "disabled";
++
++                      ports {
++                              #address-cells = <1>;
++                              #size-cells = <0>;
++
++                              hdmi_in: port@0 {
++                                      reg = <0>;
++                              };
++
++                              hdmi_out: port@1 {
++                                      reg = <1>;
++                              };
++                      };
++              };
++
++              sai7: sai@27ed0000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x27ed0000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI7_8CH>, <&cru HCLK_SAI7_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac2 19>;
++                      dma-names = "tx";
++                      power-domains = <&power RK3576_PD_VO1>;
++                      resets = <&cru SRST_M_SAI7_8CH>, <&cru SRST_H_SAI7_8CH>;
++                      reset-names = "m", "h";
++                      rockchip,sai-tx-route = <0 1 2 3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI7";
++                      status = "disabled";
++              };
++
++              sai8: sai@27ee0000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x27ee0000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI8_8CH>, <&cru HCLK_SAI8_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac1 7>;
++                      dma-names = "tx";
++                      power-domains = <&power RK3576_PD_VO1>;
++                      resets = <&cru SRST_M_SAI8_8CH>, <&cru SRST_H_SAI8_8CH>;
++                      reset-names = "m", "h";
++                      rockchip,sai-tx-route = <0 1 2 3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI8";
++                      status = "disabled";
++              };
++
++              sai9: sai@27ef0000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x27ef0000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI9_8CH>, <&cru HCLK_SAI9_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac0 26>;
++                      dma-names = "tx";
++                      power-domains = <&power RK3576_PD_VO1>;
++                      resets = <&cru SRST_M_SAI9_8CH>, <&cru SRST_H_SAI9_8CH>;
++                      reset-names = "m", "h";
++                      rockchip,sai-tx-route = <0 1 2 3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI9";
++                      status = "disabled";
++              };
++
+               qos_hdcp1: qos@27f02000 {
+                       compatible = "rockchip,rk3576-qos", "syscon";
+                       reg = <0x0 0x27f02000 0x0 0x20>;
+@@ -1221,6 +1613,72 @@
+                       };
+               };
++              sata0: sata@2a240000 {
++                      compatible = "rockchip,rk3576-dwc-ahci", "snps,dwc-ahci";
++                      reg = <0x0 0x2a240000 0x0 0x1000>;
++                      clocks = <&cru ACLK_SATA0>, <&cru CLK_PMALIVE0>,
++                               <&cru CLK_RXOOB0>;
++                      clock-names = "sata", "pmalive", "rxoob";
++                      interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH>;
++                      power-domains = <&power RK3576_PD_SUBPHP>;
++                      phys = <&combphy0_ps PHY_TYPE_SATA>;
++                      phy-names = "sata-phy";
++                      ports-implemented = <0x1>;
++                      dma-coherent;
++                      status = "disabled";
++              };
++
++              sata1: sata@2a250000 {
++                      compatible = "rockchip,rk3576-dwc-ahci", "snps,dwc-ahci";
++                      reg = <0x0 0x2a250000 0x0 0x1000>;
++                      clocks = <&cru ACLK_SATA1>, <&cru CLK_PMALIVE1>,
++                               <&cru CLK_RXOOB1>;
++                      clock-names = "sata", "pmalive", "rxoob";
++                      interrupts = <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>;
++                      power-domains = <&power RK3576_PD_SUBPHP>;
++                      phys = <&combphy1_psu PHY_TYPE_SATA>;
++                      phy-names = "sata-phy";
++                      ports-implemented = <0x1>;
++                      dma-coherent;
++                      status = "disabled";
++              };
++
++              ufshc: ufshc@2a2d0000 {
++                      compatible = "rockchip,rk3576-ufshc";
++                      reg = <0x0 0x2a2d0000 0x0 0x10000>,
++                            <0x0 0x2b040000 0x0 0x10000>,
++                            <0x0 0x2601f000 0x0 0x1000>,
++                            <0x0 0x2603c000 0x0 0x1000>,
++                            <0x0 0x2a2e0000 0x0 0x10000>;
++                      reg-names = "hci", "mphy", "hci_grf", "mphy_grf", "hci_apb";
++                      clocks = <&cru ACLK_UFS_SYS>, <&cru PCLK_USB_ROOT>, <&cru PCLK_MPHY>,
++                               <&cru CLK_REF_UFS_CLKOUT>;
++                      clock-names = "core", "pclk", "pclk_mphy", "ref_out";
++                      assigned-clocks = <&cru CLK_REF_OSC_MPHY>;
++                      assigned-clock-parents = <&cru CLK_REF_MPHY_26M>;
++                      interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
++                      power-domains = <&power RK3576_PD_USB>;
++                      pinctrl-0 = <&ufs_refclk>;
++                      pinctrl-names = "default";
++                      resets = <&cru SRST_A_UFS_BIU>, <&cru SRST_A_UFS_SYS>,
++                               <&cru SRST_A_UFS>, <&cru SRST_P_UFS_GRF>;
++                      reset-names = "biu", "sys", "ufs", "grf";
++                      reset-gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>;
++                      status = "disabled";
++              };
++
++              sfc1: spi@2a300000 {
++                      compatible = "rockchip,sfc";
++                      reg = <0x0 0x2a300000 0x0 0x4000>;
++                      interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru SCLK_FSPI1_X2>, <&cru HCLK_FSPI1>;
++                      clock-names = "clk_sfc", "hclk_sfc";
++                      power-domains = <&power RK3576_PD_SDGMAC>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
+               sdmmc: mmc@2a310000 {
+                       compatible = "rockchip,rk3576-dw-mshc";
+                       reg = <0x0 0x2a310000 0x0 0x4000>;
+@@ -1260,6 +1718,26 @@
+                       status = "disabled";
+               };
++              sfc0: spi@2a340000 {
++                      compatible = "rockchip,sfc";
++                      reg = <0x0 0x2a340000 0x0 0x4000>;
++                      interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru SCLK_FSPI_X2>, <&cru HCLK_FSPI>;
++                      clock-names = "clk_sfc", "hclk_sfc";
++                      power-domains = <&power RK3576_PD_NVM>;
++                      #address-cells = <1>;
++                      #size-cells = <0>;
++                      status = "disabled";
++              };
++
++              rng: rng@2a410000 {
++                      compatible = "rockchip,rk3576-rng";
++                      reg = <0x0 0x2a410000 0x0 0x200>;
++                      clocks = <&cru HCLK_TRNG_NS>;
++                      interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
++                      resets = <&cru SRST_H_TRNG_NS>;
++              };
++
+               otp: otp@2a580000 {
+                       compatible = "rockchip,rk3576-otp";
+                       reg = <0x0 0x2a580000 0x0 0x400>;
+@@ -1299,6 +1777,120 @@
+                       };
+               };
++              sai0: sai@2a600000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x2a600000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI0_8CH>, <&cru HCLK_SAI0_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac0 0>, <&dmac0 1>;
++                      dma-names = "tx", "rx";
++                      power-domains = <&power RK3576_PD_AUDIO>;
++                      resets = <&cru SRST_M_SAI0_8CH>, <&cru SRST_H_SAI0_8CH>;
++                      reset-names = "m", "h";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&sai0m0_lrck
++                              &sai0m0_sclk
++                              &sai0m0_sdi0
++                              &sai0m0_sdi1
++                              &sai0m0_sdi2
++                              &sai0m0_sdi3
++                              &sai0m0_sdo0
++                              &sai0m0_sdo1
++                              &sai0m0_sdo2
++                              &sai0m0_sdo3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI0";
++                      status = "disabled";
++              };
++
++              sai1: sai@2a610000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x2a610000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI1_8CH>, <&cru HCLK_SAI1_8CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac0 2>, <&dmac0 3>;
++                      dma-names = "tx", "rx";
++                      power-domains = <&power RK3576_PD_AUDIO>;
++                      resets = <&cru SRST_M_SAI1_8CH>, <&cru SRST_H_SAI1_8CH>;
++                      reset-names = "m", "h";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&sai1m0_lrck
++                              &sai1m0_sclk
++                              &sai1m0_sdi0
++                              &sai1m0_sdo0
++                              &sai1m0_sdo1
++                              &sai1m0_sdo2
++                              &sai1m0_sdo3>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI1";
++                      status = "disabled";
++              };
++
++              sai2: sai@2a620000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x2a620000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI2_2CH>, <&cru HCLK_SAI2_2CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac1 0>, <&dmac1 1>;
++                      dma-names = "tx", "rx";
++                      power-domains = <&power RK3576_PD_AUDIO>;
++                      resets = <&cru SRST_M_SAI2_2CH>, <&cru SRST_H_SAI2_2CH>;
++                      reset-names = "m", "h";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&sai2m0_lrck
++                              &sai2m0_sclk
++                              &sai2m0_sdi
++                              &sai2m0_sdo>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI2";
++                      status = "disabled";
++              };
++
++              sai3: sai@2a630000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x2a630000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI3_2CH>, <&cru HCLK_SAI3_2CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac1 2>, <&dmac1 3>;
++                      dma-names = "tx", "rx";
++                      power-domains = <&power RK3576_PD_AUDIO>;
++                      resets = <&cru SRST_M_SAI3_2CH>, <&cru SRST_H_SAI3_2CH>;
++                      reset-names = "m", "h";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&sai3m0_lrck
++                              &sai3m0_sclk
++                              &sai3m0_sdi
++                              &sai3m0_sdo>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI3";
++                      status = "disabled";
++              };
++
++              sai4: sai@2a640000 {
++                      compatible = "rockchip,rk3576-sai";
++                      reg = <0x0 0x2a640000 0x0 0x1000>;
++                      interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
++                      clocks = <&cru MCLK_SAI4_2CH>, <&cru HCLK_SAI4_2CH>;
++                      clock-names = "mclk", "hclk";
++                      dmas = <&dmac2 0>, <&dmac2 1>;
++                      dma-names = "tx", "rx";
++                      power-domains = <&power RK3576_PD_AUDIO>;
++                      resets = <&cru SRST_M_SAI4_2CH>, <&cru SRST_H_SAI4_2CH>;
++                      reset-names = "m", "h";
++                      pinctrl-names = "default";
++                      pinctrl-0 = <&sai4m0_lrck
++                              &sai4m0_sclk
++                              &sai4m0_sdi
++                              &sai4m0_sdo>;
++                      #sound-dai-cells = <0>;
++                      sound-name-prefix = "SAI4";
++                      status = "disabled";
++              };
++
+               gic: interrupt-controller@2a701000 {
+                       compatible = "arm,gic-400";
+                       reg = <0x0 0x2a701000 0 0x10000>,
+@@ -1410,7 +2002,6 @@
+                       status = "disabled";
+               };
+-
+               i2c6: i2c@2ac90000 {
+                       compatible = "rockchip,rk3576-i2c", "rockchip,rk3399-i2c";
+                       reg = <0x0 0x2ac90000 0x0 0x1000>;
+@@ -1795,6 +2386,19 @@
+                       status = "disabled";
+               };
++              hdptxphy: hdmiphy@2b000000 {
++                      compatible = "rockchip,rk3576-hdptx-phy", "rockchip,rk3588-hdptx-phy";
++                      reg = <0x0 0x2b000000 0x0 0x2000>;
++                      clocks = <&cru CLK_PHY_REF_SRC>, <&cru PCLK_HDPTX_APB>;
++                      clock-names = "ref", "apb";
++                      resets = <&cru SRST_P_HDPTX_APB>, <&cru SRST_HDPTX_INIT>,
++                               <&cru SRST_HDPTX_CMN>, <&cru SRST_HDPTX_LANE>;
++                      reset-names = "apb", "init", "cmn", "lane";
++                      rockchip,grf = <&hdptxphy_grf>;
++                      #phy-cells = <0>;
++                      status = "disabled";
++              };
++
+               sram: sram@3ff88000 {
+                       compatible = "mmio-sram";
+                       reg = <0x0 0x3ff88000 0x0 0x78000>;
+@@ -1812,74 +2416,6 @@
+                       compatible = "arm,scmi-shmem";
+                       reg = <0x0 0x4010f000 0x0 0x100>;
+               };
+-
+-              pinctrl: pinctrl {
+-                      compatible = "rockchip,rk3576-pinctrl";
+-                      rockchip,grf = <&ioc_grf>;
+-                      #address-cells = <2>;
+-                      #size-cells = <2>;
+-                      ranges;
+-
+-                      gpio0: gpio@27320000 {
+-                              compatible = "rockchip,gpio-bank";
+-                              reg = <0x0 0x27320000 0x0 0x200>;
+-                              clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>;
+-                              gpio-controller;
+-                              gpio-ranges = <&pinctrl 0 0 32>;
+-                              interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+-                              interrupt-controller;
+-                              #gpio-cells = <2>;
+-                              #interrupt-cells = <2>;
+-                      };
+-
+-                      gpio1: gpio@2ae10000 {
+-                              compatible = "rockchip,gpio-bank";
+-                              reg = <0x0 0x2ae10000 0x0 0x200>;
+-                              clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+-                              gpio-controller;
+-                              gpio-ranges = <&pinctrl 0 32 32>;
+-                              interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+-                              interrupt-controller;
+-                              #gpio-cells = <2>;
+-                              #interrupt-cells = <2>;
+-                      };
+-
+-                      gpio2: gpio@2ae20000 {
+-                              compatible = "rockchip,gpio-bank";
+-                              reg = <0x0 0x2ae20000 0x0 0x200>;
+-                              clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+-                              gpio-controller;
+-                              gpio-ranges = <&pinctrl 0 64 32>;
+-                              interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+-                              interrupt-controller;
+-                              #gpio-cells = <2>;
+-                              #interrupt-cells = <2>;
+-                      };
+-
+-                      gpio3: gpio@2ae30000 {
+-                              compatible = "rockchip,gpio-bank";
+-                              reg = <0x0 0x2ae30000 0x0 0x200>;
+-                              clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+-                              gpio-controller;
+-                              gpio-ranges = <&pinctrl 0 96 32>;
+-                              interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+-                              interrupt-controller;
+-                              #gpio-cells = <2>;
+-                              #interrupt-cells = <2>;
+-                      };
+-
+-                      gpio4: gpio@2ae40000 {
+-                              compatible = "rockchip,gpio-bank";
+-                              reg = <0x0 0x2ae40000 0x0 0x200>;
+-                              clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+-                              gpio-controller;
+-                              gpio-ranges = <&pinctrl 0 128 32>;
+-                              interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+-                              interrupt-controller;
+-                              #gpio-cells = <2>;
+-                              #interrupt-cells = <2>;
+-                      };
+-              };
+       };
+ };
+--- /dev/null
++++ b/arch/arm/dts/rk3576-generic-u-boot.dtsi
+@@ -0,0 +1,3 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++
++#include "rk3576-u-boot.dtsi"
+--- /dev/null
++++ b/arch/arm/dts/rk3576-generic.dts
+@@ -0,0 +1,63 @@
++// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++/*
++ * Minimal generic DT for RK3576 with eMMC, SD-card and USB OTG enabled
++ */
++
++/dts-v1/;
++
++#include <dt-bindings/gpio/gpio.h>
++#include "rk3576.dtsi"
++
++/ {
++      model = "Generic RK3576";
++      compatible = "rockchip,rk3576";
++
++      aliases {
++              mmc0 = &sdhci;
++              mmc1 = &sdmmc;
++      };
++
++      chosen {
++              stdout-path = "serial0:1500000n8";
++      };
++};
++
++&sdhci {
++      bus-width = <8>;
++      cap-mmc-highspeed;
++      mmc-hs200-1_8v;
++      no-sd;
++      no-sdio;
++      non-removable;
++      status = "okay";
++};
++
++&sdmmc {
++      bus-width = <4>;
++      cap-sd-highspeed;
++      disable-wp;
++      no-mmc;
++      no-sdio;
++      status = "okay";
++};
++
++&u2phy0 {
++      status = "okay";
++};
++
++&u2phy0_otg {
++      status = "okay";
++};
++
++&uart0 {
++      pinctrl-0 = <&uart0m0_xfer>;
++      status = "okay";
++};
++
++&usb_drd0_dwc3 {
++      dr_mode = "peripheral";
++      maximum-speed = "high-speed";
++      phys = <&u2phy0_otg>;
++      phy-names = "usb2-phy";
++      status = "okay";
++};
+--- /dev/null
++++ b/arch/arm/mach-rockchip/rk3576/MAINTAINERS
+@@ -0,0 +1,5 @@
++GENERIC-RK3576
++M:    Jonas Karlman <[email protected]>
++S:    Maintained
++F:    arch/arm/dts/rk3576-generic*
++F:    configs/generic-rk3576_defconfig
+--- /dev/null
++++ b/configs/generic-rk3576_defconfig
+@@ -0,0 +1,50 @@
++CONFIG_ARM=y
++CONFIG_SKIP_LOWLEVEL_INIT=y
++CONFIG_COUNTER_FREQUENCY=24000000
++CONFIG_ARCH_ROCKCHIP=y
++CONFIG_DEFAULT_DEVICE_TREE="rk3576-generic"
++CONFIG_ROCKCHIP_RK3576=y
++CONFIG_SYS_LOAD_ADDR=0x40c00800
++CONFIG_DEBUG_UART_BASE=0x2AD40000
++CONFIG_DEBUG_UART_CLOCK=24000000
++CONFIG_DEBUG_UART=y
++# CONFIG_BOOTMETH_VBE is not set
++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3576-generic.dtb"
++# CONFIG_DISPLAY_CPUINFO is not set
++CONFIG_SPL_MAX_SIZE=0x40000
++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
++CONFIG_CMD_MEMINFO=y
++CONFIG_CMD_MEMINFO_MAP=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_GPT=y
++CONFIG_CMD_MISC=y
++CONFIG_CMD_MMC=y
++CONFIG_CMD_ROCKUSB=y
++CONFIG_CMD_USB_MASS_STORAGE=y
++# CONFIG_CMD_SETEXPR is not set
++CONFIG_CMD_RNG=y
++# CONFIG_SPL_DOS_PARTITION is not set
++# CONFIG_OF_UPSTREAM is not set
++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
++CONFIG_NO_NET=y
++# CONFIG_ADC is not set
++# CONFIG_USB_FUNCTION_FASTBOOT is not set
++CONFIG_ROCKCHIP_GPIO=y
++CONFIG_SUPPORT_EMMC_RPMB=y
++CONFIG_MMC_DW=y
++CONFIG_MMC_DW_ROCKCHIP=y
++CONFIG_MMC_SDHCI=y
++CONFIG_MMC_SDHCI_SDMA=y
++CONFIG_MMC_SDHCI_ROCKCHIP=y
++CONFIG_PHY_ROCKCHIP_INNO_USB2=y
++CONFIG_BAUDRATE=1500000
++CONFIG_DEBUG_UART_SHIFT=2
++CONFIG_SYS_NS16550_MEM32=y
++CONFIG_SYSRESET_PSCI=y
++CONFIG_USB=y
++CONFIG_USB_DWC3=y
++CONFIG_USB_DWC3_GENERIC=y
++CONFIG_USB_GADGET=y
++CONFIG_USB_GADGET_DOWNLOAD=y
++CONFIG_USB_FUNCTION_ROCKUSB=y
++CONFIG_ERRNO_STR=y
+--- a/doc/board/rockchip/rockchip.rst
++++ b/doc/board/rockchip/rockchip.rst
+@@ -135,6 +135,7 @@ List of mainline supported Rockchip boar
+ * rk3576
+      - Firefly ROC-RK3576-PC (roc-pc-rk3576)
++     - Generic RK3576 (generic-rk3576)
+ * rk3588
+      - ArmSoM Sige7 (sige7-rk3588)
diff --git a/package/boot/uboot-rockchip/patches/005-rockchip-rk3576-Implement-to-print-SoC-variant.patch b/package/boot/uboot-rockchip/patches/005-rockchip-rk3576-Implement-to-print-SoC-variant.patch
new file mode 100644 (file)
index 0000000..de96450
--- /dev/null
@@ -0,0 +1,83 @@
+From a72e8feaca46ed41a8d6bb4e8c5961a29fe7a39e Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:40 +0000
+Subject: [PATCH] rockchip: rk3576: Implement checkboard() to print SoC variant
+
+Implement checkboard() to print current SoC model used by a board when
+U-Boot proper is running.
+
+  U-Boot 2025.04 (Apr 22 2025 - 20:43:17 +0000)
+
+  Model: Generic RK3576
+  SoC:   RK3576
+  DRAM:  8 GiB
+
+Information about the SoC model and variant is read from OTP.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ arch/arm/mach-rockchip/rk3576/rk3576.c | 48 ++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+--- a/arch/arm/mach-rockchip/rk3576/rk3576.c
++++ b/arch/arm/mach-rockchip/rk3576/rk3576.c
+@@ -3,6 +3,10 @@
+  * Copyright (c) 2024 Rockchip Electronics Co., Ltd
+  */
++#define LOG_CATEGORY LOGC_ARCH
++
++#include <dm.h>
++#include <misc.h>
+ #include <asm/armv8/mmu.h>
+ #include <asm/arch-rockchip/bootrom.h>
+ #include <asm/arch-rockchip/hardware.h>
+@@ -153,3 +157,47 @@ int arch_cpu_init(void)
+       return 0;
+ }
++
++#define RK3576_OTP_CPU_CODE_OFFSET            0x02
++#define RK3576_OTP_SPECIFICATION_OFFSET               0x08
++
++int checkboard(void)
++{
++      u8 cpu_code[2], specification;
++      struct udevice *dev;
++      char suffix[2];
++      int ret;
++
++      if (!IS_ENABLED(CONFIG_ROCKCHIP_OTP) || !CONFIG_IS_ENABLED(MISC))
++              return 0;
++
++      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 0;
++      }
++
++      /* cpu-code: SoC model, e.g. 0x35 0x76 */
++      ret = misc_read(dev, RK3576_OTP_CPU_CODE_OFFSET, cpu_code, 2);
++      if (ret < 0) {
++              log_debug("Could not read cpu-code, ret=%d\n", ret);
++              return 0;
++      }
++
++      /* specification: SoC variant, e.g. 0xA for RK3576J */
++      ret = misc_read(dev, RK3576_OTP_SPECIFICATION_OFFSET, &specification, 1);
++      if (ret < 0) {
++              log_debug("Could not read specification, ret=%d\n", ret);
++              return 0;
++      }
++      specification &= 0x1f;
++
++      /* for RK3576J i.e. '@' + 0xA = 'J' */
++      suffix[0] = specification > 1 ? '@' + specification : '\0';
++      suffix[1] = '\0';
++
++      printf("SoC:   RK%02x%02x%s\n", cpu_code[0], cpu_code[1], suffix);
++
++      return 0;
++}
diff --git a/package/boot/uboot-rockchip/patches/006-arm-dts-rockchip-Include-OTP-in-U-Boot-pre-reloc-phase-fo.patch b/package/boot/uboot-rockchip/patches/006-arm-dts-rockchip-Include-OTP-in-U-Boot-pre-reloc-phase-fo.patch
new file mode 100644 (file)
index 0000000..30fc579
--- /dev/null
@@ -0,0 +1,35 @@
+From bdcda6be27b69a6e7ced1d59f5d6ceb07c5414ac Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:41 +0000
+Subject: [PATCH] arm: dts: rockchip: Include OTP in U-Boot pre-reloc phase for
+ RK3576
+
+Update rk3576-u-boot.dtsi to include OTP in U-Boot pre-reloc phase for
+checkboard() to be able to read information about the running SoC model
+and variant from OTP and print it during boot:
+
+  U-Boot 2025.04 (Apr 22 2025 - 20:43:17 +0000)
+
+  Model: Generic RK3576
+  SoC:   RK3576
+  DRAM:  8 GiB
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ arch/arm/dts/rk3576-u-boot.dtsi | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/arm/dts/rk3576-u-boot.dtsi
++++ b/arch/arm/dts/rk3576-u-boot.dtsi
+@@ -49,6 +49,10 @@
+       bootph-all;
+ };
++&otp {
++      bootph-some-ram;
++};
++
+ &pcfg_pull_none {
+       bootph-all;
+ };
diff --git a/package/boot/uboot-rockchip/patches/007-usb-dwc3-generic-Use-combined-glue-and-ctrl-node-for-RK35.patch b/package/boot/uboot-rockchip/patches/007-usb-dwc3-generic-Use-combined-glue-and-ctrl-node-for-RK35.patch
new file mode 100644 (file)
index 0000000..2766f0f
--- /dev/null
@@ -0,0 +1,26 @@
+From 2d87afba58b95487f88717df33e16a909f90592a Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:42 +0000
+Subject: [PATCH] usb: dwc3-generic: Use combined glue and ctrl node for RK3576
+
+Like Rockchip RK3328, RK3568 and RK3588, the RK3576 also have a single
+node to represent the glue and ctrl for USB 3.0.
+
+Use rk_ops as driver data to select correct ctrl node for RK3576 DWC3.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/usb/dwc3/dwc3-generic.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/dwc3/dwc3-generic.c
++++ b/drivers/usb/dwc3/dwc3-generic.c
+@@ -699,6 +699,7 @@ static const struct udevice_id dwc3_glue
+       { .compatible = "rockchip,rk3328-dwc3", .data = (ulong)&rk_ops },
+       { .compatible = "rockchip,rk3399-dwc3" },
+       { .compatible = "rockchip,rk3568-dwc3", .data = (ulong)&rk_ops },
++      { .compatible = "rockchip,rk3576-dwc3", .data = (ulong)&rk_ops },
+       { .compatible = "rockchip,rk3588-dwc3", .data = (ulong)&rk_ops },
+       { .compatible = "qcom,dwc3", .data = (ulong)&qcom_ops },
+       { .compatible = "fsl,imx8mp-dwc3", .data = (ulong)&imx8mp_ops },
diff --git a/package/boot/uboot-rockchip/patches/008-phy-rockchip-inno-usb2-Add-support-for-RK3576.patch b/package/boot/uboot-rockchip/patches/008-phy-rockchip-inno-usb2-Add-support-for-RK3576.patch
new file mode 100644 (file)
index 0000000..afc5137
--- /dev/null
@@ -0,0 +1,58 @@
+From b518886f6d7061c127628c1e12f3921c49ffeaee Mon Sep 17 00:00:00 2001
+From: Frank Wang <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:43 +0000
+Subject: [PATCH] phy: rockchip-inno-usb2: Add support for RK3576
+
+Add support for the USB2.0 PHYs used in the RK3576 SoC.
+
+Config values are taken from vendor U-Boot linux-6.1-stan-rkr5 tag.
+
+Signed-off-by: Frank Wang <[email protected]>
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 26 +++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -465,6 +465,28 @@ static const struct rockchip_usb2phy_cfg
+       { /* sentinel */ }
+ };
++static const struct rockchip_usb2phy_cfg rk3576_phy_cfgs[] = {
++      {
++              .reg            = 0x0000,
++              .clkout_ctl     = { 0x0008, 0, 0, 1, 0 },
++              .port_cfgs      = {
++                      [USB2PHY_PORT_OTG] = {
++                              .phy_sus        = { 0x0000, 1, 0, 2, 1 },
++                      }
++              },
++      },
++      {
++              .reg            = 0x2000,
++              .clkout_ctl     = { 0x2008, 0, 0, 1, 0 },
++              .port_cfgs      = {
++                      [USB2PHY_PORT_OTG] = {
++                              .phy_sus        = { 0x2000, 1, 0, 2, 1 },
++                      }
++              },
++      },
++      { /* sentinel */ }
++};
++
+ static const struct rockchip_usb2phy_cfg rk3588_phy_cfgs[] = {
+       {
+               .reg            = 0x0000,
+@@ -527,6 +549,10 @@ static const struct udevice_id rockchip_
+               .data = (ulong)&rk3568_phy_cfgs,
+       },
+       {
++              .compatible = "rockchip,rk3576-usb2phy",
++              .data = (ulong)&rk3576_phy_cfgs,
++      },
++      {
+               .compatible = "rockchip,rk3588-usb2phy",
+               .data = (ulong)&rk3588_phy_cfgs,
+       },
diff --git a/package/boot/uboot-rockchip/patches/009-phy-rockchip-usbdp-Add-support-for-RK3576.patch b/package/boot/uboot-rockchip/patches/009-phy-rockchip-usbdp-Add-support-for-RK3576.patch
new file mode 100644 (file)
index 0000000..c99dc25
--- /dev/null
@@ -0,0 +1,58 @@
+From 0d966d3932e2e5e7d14301da9ced0d7a62fce367 Mon Sep 17 00:00:00 2001
+From: Frank Wang <[email protected]>
+Date: Fri, 1 Aug 2025 20:32:44 +0000
+Subject: [PATCH] phy: rockchip: usbdp: Add support for RK3576
+
+Add support for the USB3.0+DP PHY used in the RK3576 SoC.
+
+Config values are taken from vendor U-Boot linux-6.1-stan-rkr5 tag.
+
+Signed-off-by: Frank Wang <[email protected]>
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/phy/rockchip/phy-rockchip-usbdp.c | 26 +++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
+@@ -813,6 +813,28 @@ static const char * const rk3588_udphy_r
+       "init", "cmn", "lane", "pcs_apb", "pma_apb"
+ };
++static const struct rockchip_udphy_cfg rk3576_udphy_cfgs = {
++      .num_phys = 1,
++      .phy_ids = {
++              0x2b010000,
++      },
++      .num_rsts = ARRAY_SIZE(rk3588_udphy_rst_l),
++      .rst_list = rk3588_udphy_rst_l,
++      .grfcfg = {
++              /* u2phy-grf */
++              .bvalid_phy_con         = { 0x0010, 1, 0, 0x2, 0x3 },
++              .bvalid_grf_con         = { 0x0000, 15, 14, 0x1, 0x3 },
++
++              /* usb-grf */
++              .usb3otg0_cfg           = { 0x0030, 15, 0, 0x1100, 0x0188 },
++
++              /* usbdpphy-grf */
++              .low_pwrn               = { 0x0004, 13, 13, 0, 1 },
++              .rx_lfps                = { 0x0004, 14, 14, 0, 1 },
++      },
++      .combophy_init = rk3588_udphy_init,
++};
++
+ static const struct rockchip_udphy_cfg rk3588_udphy_cfgs = {
+       .num_phys = 2,
+       .phy_ids = {
+@@ -839,6 +861,10 @@ static const struct rockchip_udphy_cfg r
+ static const struct udevice_id rockchip_udphy_dt_match[] = {
+       {
++              .compatible = "rockchip,rk3576-usbdp-phy",
++              .data = (ulong)&rk3576_udphy_cfgs
++      },
++      {
+               .compatible = "rockchip,rk3588-usbdp-phy",
+               .data = (ulong)&rk3588_udphy_cfgs
+       },
diff --git a/package/boot/uboot-rockchip/patches/010-rockchip-clk-clk_rk3576-Add-dummy-CLK_REF_PCIEx_PHY.patch b/package/boot/uboot-rockchip/patches/010-rockchip-clk-clk_rk3576-Add-dummy-CLK_REF_PCIEx_PHY.patch
new file mode 100644 (file)
index 0000000..f5b66d0
--- /dev/null
@@ -0,0 +1,26 @@
+From 2a6039a20994c192edb6786fa97714180bd663cf Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Fri, 1 Aug 2025 20:43:37 +0000
+Subject: [PATCH] rockchip: clk: clk_rk3576: Add dummy CLK_REF_PCIEx_PHY
+ support
+
+Add dummy support for the CLK_REF_PCIEx_PHY clocks to allow probe of the
+phy-rockchip-naneng-combphy driver on RK3576.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/clk/rockchip/clk_rk3576.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/clk/rockchip/clk_rk3576.c
++++ b/drivers/clk/rockchip/clk_rk3576.c
+@@ -2168,6 +2168,8 @@ static ulong rk3576_clk_set_rate(struct
+       case CLK_CPLL_DIV10:
+       case FCLK_DDR_CM0_CORE:
+       case ACLK_PHP_ROOT:
++      case CLK_REF_PCIE0_PHY:
++      case CLK_REF_PCIE1_PHY:
+               ret = 0;
+               break;
+ #ifndef CONFIG_SPL_BUILD
diff --git a/package/boot/uboot-rockchip/patches/011-phy-rockchip-naneng-combphy-Add-support-for-RK3576.patch b/package/boot/uboot-rockchip/patches/011-phy-rockchip-naneng-combphy-Add-support-for-RK3576.patch
new file mode 100644 (file)
index 0000000..bfd0d84
--- /dev/null
@@ -0,0 +1,179 @@
+From cca7e79c7a42067fd8e65f4d2d2c73a98e42cd2e Mon Sep 17 00:00:00 2001
+From: Jon Lin <[email protected]>
+Date: Fri, 1 Aug 2025 20:43:38 +0000
+Subject: [PATCH] phy: rockchip: naneng-combphy: Add support for RK3576
+
+Add support for the PCIe/USB3/SATA combo PHYs used in the RK3576 SoC.
+
+Config values are taken from vendor U-Boot linux-6.1-stan-rkr5 tag.
+
+Signed-off-by: Jon Lin <[email protected]>
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ .../rockchip/phy-rockchip-naneng-combphy.c    | 147 ++++++++++++++++++
+ 1 file changed, 147 insertions(+)
+
+--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+@@ -453,6 +453,149 @@ static const struct rockchip_combphy_cfg
+       .combphy_cfg    = rk3568_combphy_cfg,
+ };
++static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv)
++{
++      const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
++      u32 val;
++
++      switch (priv->mode) {
++      case PHY_TYPE_PCIE:
++              param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
++              param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
++              param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
++              param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
++              break;
++      case PHY_TYPE_USB3:
++              /* Set SSC downward spread spectrum */
++              val = readl(priv->mmio + (0x1f << 2));
++              val &= ~GENMASK(5, 4);
++              val |= 0x01 << 4;
++              writel(val, priv->mmio + 0x7c);
++
++              /* Enable adaptive CTLE for USB3.0 Rx */
++              val = readl(priv->mmio + (0x0e << 2));
++              val &= ~GENMASK(0, 0);
++              val |= 0x01;
++              writel(val, priv->mmio + (0x0e << 2));
++
++              /* Set PLL KVCO fine tuning signals */
++              val = readl(priv->mmio + (0x20 << 2));
++              val &= ~(0x7 << 2);
++              val |= 0x2 << 2;
++              writel(val, priv->mmio + (0x20 << 2));
++
++              /* Set PLL LPF R1 to su_trim[10:7]=1001 */
++              writel(0x4, priv->mmio + (0xb << 2));
++
++              /* Set PLL input clock divider 1/2 */
++              val = readl(priv->mmio + (0x5 << 2));
++              val &= ~(0x3 << 6);
++              val |= 0x1 << 6;
++              writel(val, priv->mmio + (0x5 << 2));
++
++              /* Set PLL loop divider */
++              writel(0x32, priv->mmio + (0x11 << 2));
++
++              /* Set PLL KVCO to min and set PLL charge pump current to max */
++              writel(0xf0, priv->mmio + (0xa << 2));
++
++              /* Set Rx squelch input filler bandwidth */
++              writel(0x0d, priv->mmio + (0x14 << 2));
++
++              param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
++              param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
++              param_write(priv->phy_grf, &cfg->usb_mode_set, true);
++              param_write(priv->pipe_grf, &cfg->u3otg1_port_en, true);
++              break;
++      case PHY_TYPE_SATA:
++              /* Enable adaptive CTLE for SATA Rx */
++              val = readl(priv->mmio + (0x0e << 2));
++              val &= ~GENMASK(0, 0);
++              val |= 0x01;
++              writel(val, priv->mmio + (0x0e << 2));
++              /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */
++              writel(0x8F, priv->mmio + (0x06 << 2));
++
++              param_write(priv->phy_grf, &cfg->con0_for_sata, true);
++              param_write(priv->phy_grf, &cfg->con1_for_sata, true);
++              param_write(priv->phy_grf, &cfg->con2_for_sata, true);
++              param_write(priv->phy_grf, &cfg->con3_for_sata, true);
++              param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);
++              param_write(priv->pipe_grf, &cfg->pipe_con1_for_sata, true);
++              break;
++      case PHY_TYPE_SGMII:
++      case PHY_TYPE_QSGMII:
++      default:
++              dev_err(priv->dev, "incompatible PHY type\n");
++              return -EINVAL;
++      }
++
++      /* 100MHz refclock signal is good */
++      clk_set_rate(&priv->ref_clk, 100000000);
++      param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
++      if (priv->mode == PHY_TYPE_PCIE) {
++              /* gate_tx_pck_sel length select work for L1SS */
++              writel(0xc0, priv->mmio + 0x74);
++
++              /* PLL KVCO tuning fine */
++              val = readl(priv->mmio + (0x20 << 2));
++              val &= ~(0x7 << 2);
++              val |= 0x2 << 2;
++              writel(val, priv->mmio + (0x20 << 2));
++
++              /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */
++              writel(0x4c, priv->mmio + (0x1b << 2));
++
++              /* Set up su_trim: T3_P1 650mv */
++              writel(0x90, priv->mmio + (0xa << 2));
++              writel(0x43, priv->mmio + (0xb << 2));
++              writel(0x88, priv->mmio + (0xc << 2));
++              writel(0x56, priv->mmio + (0xd << 2));
++      }
++
++      return 0;
++}
++
++static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = {
++      /* pipe-phy-grf */
++      .pcie_mode_set          = { 0x0000, 5, 0, 0x00, 0x11 },
++      .usb_mode_set           = { 0x0000, 5, 0, 0x00, 0x04 },
++      .pipe_rxterm_set        = { 0x0000, 12, 12, 0x00, 0x01 },
++      .pipe_txelec_set        = { 0x0004, 1, 1, 0x00, 0x01 },
++      .pipe_txcomp_set        = { 0x0004, 4, 4, 0x00, 0x01 },
++      .pipe_clk_25m           = { 0x0004, 14, 13, 0x00, 0x01 },
++      .pipe_clk_100m          = { 0x0004, 14, 13, 0x00, 0x02 },
++      .pipe_phymode_sel       = { 0x0008, 1, 1, 0x00, 0x01 },
++      .pipe_rate_sel          = { 0x0008, 2, 2, 0x00, 0x01 },
++      .pipe_rxterm_sel        = { 0x0008, 8, 8, 0x00, 0x01 },
++      .pipe_txelec_sel        = { 0x0008, 12, 12, 0x00, 0x01 },
++      .pipe_txcomp_sel        = { 0x0008, 15, 15, 0x00, 0x01 },
++      .pipe_clk_ext           = { 0x000c, 9, 8, 0x02, 0x01 },
++      .pipe_phy_status        = { 0x0034, 6, 6, 0x01, 0x00 },
++      .con0_for_pcie          = { 0x0000, 15, 0, 0x00, 0x1000 },
++      .con1_for_pcie          = { 0x0004, 15, 0, 0x00, 0x0000 },
++      .con2_for_pcie          = { 0x0008, 15, 0, 0x00, 0x0101 },
++      .con3_for_pcie          = { 0x000c, 15, 0, 0x00, 0x0200 },
++      .con0_for_sata          = { 0x0000, 15, 0, 0x00, 0x0129 },
++      .con1_for_sata          = { 0x0004, 15, 0, 0x00, 0x0000 },
++      .con2_for_sata          = { 0x0008, 15, 0, 0x00, 0x80c1 },
++      .con3_for_sata          = { 0x000c, 15, 0, 0x00, 0x0407 },
++      /* php-grf */
++      .pipe_con0_for_sata     = { 0x001C, 2, 0, 0x00, 0x2 },
++      .pipe_con1_for_sata     = { 0x0020, 2, 0, 0x00, 0x2 },
++      .u3otg1_port_en         = { 0x0038, 15, 0, 0x0181, 0x1100 },
++};
++
++static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = {
++      .num_phys = 2,
++      .phy_ids = {
++              0x2b050000,
++              0x2b060000,
++      },
++      .grfcfg         = &rk3576_combphy_grfcfgs,
++      .combphy_cfg    = rk3576_combphy_cfg,
++};
++
+ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv)
+ {
+       const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
+@@ -565,6 +708,10 @@ static const struct udevice_id rockchip_
+               .data = (ulong)&rk3568_combphy_cfgs
+       },
+       {
++              .compatible = "rockchip,rk3576-naneng-combphy",
++              .data = (ulong)&rk3576_combphy_cfgs
++      },
++      {
+               .compatible = "rockchip,rk3588-naneng-combphy",
+               .data = (ulong)&rk3588_combphy_cfgs
+       },
diff --git a/package/boot/uboot-rockchip/patches/012-phy-rockchip-usbdp-Fix-Generic-PHY-reference-counting.patch b/package/boot/uboot-rockchip/patches/012-phy-rockchip-usbdp-Fix-Generic-PHY-reference-counting.patch
new file mode 100644 (file)
index 0000000..944d914
--- /dev/null
@@ -0,0 +1,67 @@
+From 0336e97b1187f7f54e11c6cb9f3fa938cc11204e Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:10 +0000
+Subject: [PATCH] phy: rockchip: usbdp: Fix Generic PHY reference counting
+
+Generic PHY reference counting helps ensure driver ops for init/exit and
+power on/off are called at correct state. For this to work the PHY
+driver must initialize PHY-id to a persistent value in of_xlate ops.
+
+The Rockchip USBDP PHY driver does not initialize the PHY-id field, this
+typically lead to use of unshared reference counting among different
+struct phy instances.
+
+Initialize the PHY-id in of_xlate ops to ensure use of shared reference
+counting among all struct phy instances.
+
+E.g. on a ROCK 5B following could be observed:
+
+  => usb start
+  starting USB...
+  [...]
+  Bus usb@fc400000: 2 USB Device(s) found
+         scanning usb for storage devices... 1 Storage Device(s) found
+
+  => usb reset
+  resetting USB...
+  [...]
+  rockchip_udphy phy@fed90000: cmn ana lcpll lock timeout
+  rockchip_udphy phy@fed90000: failed to init usbdp combophy
+  rockchip_udphy phy@fed90000: PHY: Failed to init phy@fed90000: -110.
+  Can't init PHY1
+  Bus usb@fc400000: probe failed, error -110
+         scanning usb for storage devices... 0 Storage Device(s) found
+
+With shared reference counting this is fixed:
+
+  => usb reset
+  resetting USB...
+  [...]
+  Bus usb@fc400000: 2 USB Device(s) found
+         scanning usb for storage devices... 1 Storage Device(s) found
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/phy/rockchip/phy-rockchip-usbdp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/phy/rockchip/phy-rockchip-usbdp.c
++++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c
+@@ -587,12 +587,16 @@ static int udphy_power_off(struct rockch
+ static int rockchip_u3phy_of_xlate(struct phy *phy,
+                                  struct ofnode_phandle_args *args)
+ {
++      struct rockchip_udphy *udphy = dev_get_priv(phy->dev);
++
+       if (args->args_count == 0)
+               return -EINVAL;
+       if (args->args[0] != PHY_TYPE_USB3)
+               return -EINVAL;
++      phy->id = udphy->id;
++
+       return 0;
+ }
diff --git a/package/boot/uboot-rockchip/patches/013-phy-rockchip-naneng-combphy-Simplify-init-ops.patch b/package/boot/uboot-rockchip/patches/013-phy-rockchip-naneng-combphy-Simplify-init-ops.patch
new file mode 100644 (file)
index 0000000..c15188a
--- /dev/null
@@ -0,0 +1,155 @@
+From 8a3d377d4ccd409b56b9a6eef20613472e4471fd Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:13 +0000
+Subject: [PATCH] phy: rockchip: naneng-combphy: Simplify init ops
+
+The init ops for Rockchip COMBPHY driver is more complex than it needs
+to be, e.g. declaring multiple init functions that only differ in the
+error message.
+
+Simplify the init ops based on code from the Linux mainline driver.
+
+This change also ensure that errors returned from combphy_cfg() and
+reset_deassert_bulk() is propertly propagated to the caller. No other
+runtime change is expected with this simplication.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ .../rockchip/phy-rockchip-naneng-combphy.c    | 101 ++++--------------
+ 1 file changed, 19 insertions(+), 82 deletions(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+@@ -98,104 +98,41 @@ static int param_write(struct regmap *ba
+       return regmap_write(base, reg->offset, val);
+ }
+-static int rockchip_combphy_pcie_init(struct rockchip_combphy_priv *priv)
+-{
+-      int ret = 0;
+-
+-      if (priv->cfg->combphy_cfg) {
+-              ret = priv->cfg->combphy_cfg(priv);
+-              if (ret) {
+-                      dev_err(priv->dev, "failed to init phy for pcie\n");
+-                      return ret;
+-              }
+-      }
+-
+-      return ret;
+-}
+-
+-static int rockchip_combphy_usb3_init(struct rockchip_combphy_priv *priv)
+-{
+-      int ret = 0;
+-
+-      if (priv->cfg->combphy_cfg) {
+-              ret = priv->cfg->combphy_cfg(priv);
+-              if (ret) {
+-                      dev_err(priv->dev, "failed to init phy for usb3\n");
+-                      return ret;
+-              }
+-      }
+-
+-      return ret;
+-}
+-
+-static int rockchip_combphy_sata_init(struct rockchip_combphy_priv *priv)
+-{
+-      int ret = 0;
+-
+-      if (priv->cfg->combphy_cfg) {
+-              ret = priv->cfg->combphy_cfg(priv);
+-              if (ret) {
+-                      dev_err(priv->dev, "failed to init phy for sata\n");
+-                      return ret;
+-              }
+-      }
+-
+-      return ret;
+-}
+-
+-static int rockchip_combphy_sgmii_init(struct rockchip_combphy_priv *priv)
++static int rockchip_combphy_init(struct phy *phy)
+ {
+-      int ret = 0;
+-
+-      if (priv->cfg->combphy_cfg) {
+-              ret = priv->cfg->combphy_cfg(priv);
+-              if (ret) {
+-                      dev_err(priv->dev, "failed to init phy for sgmii\n");
+-                      return ret;
+-              }
+-      }
++      struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
++      int ret;
+-      return ret;
+-}
++      ret = clk_enable(&priv->ref_clk);
++      if (ret < 0 && ret != -ENOSYS)
++              return ret;
+-static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)
+-{
+       switch (priv->mode) {
+       case PHY_TYPE_PCIE:
+-              rockchip_combphy_pcie_init(priv);
+-              break;
+       case PHY_TYPE_USB3:
+-              rockchip_combphy_usb3_init(priv);
+-              break;
+       case PHY_TYPE_SATA:
+-              rockchip_combphy_sata_init(priv);
+-              break;
+       case PHY_TYPE_SGMII:
+       case PHY_TYPE_QSGMII:
+-              return rockchip_combphy_sgmii_init(priv);
++              if (priv->cfg->combphy_cfg)
++                      ret = priv->cfg->combphy_cfg(priv);
++              else
++                      ret = 0;
++              break;
+       default:
+               dev_err(priv->dev, "incompatible PHY type\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              break;
+       }
+-      return 0;
+-}
+-
+-static int rockchip_combphy_init(struct phy *phy)
+-{
+-      struct rockchip_combphy_priv *priv = dev_get_priv(phy->dev);
+-      int ret;
+-
+-      ret = clk_enable(&priv->ref_clk);
+-      if (ret < 0 && ret != -ENOSYS)
+-              return ret;
++      if (ret) {
++              dev_err(priv->dev, "failed to init phy for phy type %x\n", priv->mode);
++              goto err_clk;
++      }
+-      ret = rockchip_combphy_set_mode(priv);
++      ret = reset_deassert_bulk(&priv->phy_rsts);
+       if (ret)
+               goto err_clk;
+-      reset_deassert_bulk(&priv->phy_rsts);
+-
+       return 0;
+ err_clk:
+@@ -304,7 +241,7 @@ static int rockchip_combphy_probe(struct
+       }
+       priv->dev = udev;
+-      priv->mode = PHY_TYPE_SATA;
++      priv->mode = PHY_NONE;
+       priv->cfg = phy_cfg;
+       return rockchip_combphy_parse_dt(udev, priv);
diff --git a/package/boot/uboot-rockchip/patches/014-phy-rockchip-naneng-combphy-Use-syscon_regmap_lookup_by_p.patch b/package/boot/uboot-rockchip/patches/014-phy-rockchip-naneng-combphy-Use-syscon_regmap_lookup_by_p.patch
new file mode 100644 (file)
index 0000000..0baa21a
--- /dev/null
@@ -0,0 +1,49 @@
+From 12dd645914a4e5e65d92a4754d0dacbdbf1e4a55 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:14 +0000
+Subject: [PATCH] phy: rockchip: naneng-combphy: Use
+ syscon_regmap_lookup_by_phandle
+
+Change to use syscon_regmap_lookup_by_phandle() helper instead of
+finding the syscon udevice and making a call to syscon_get_regmap().
+
+No runtime change is expected with this simplication.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ .../phy/rockchip/phy-rockchip-naneng-combphy.c  | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
+@@ -174,22 +174,19 @@ static const struct phy_ops rockchip_com
+ static int rockchip_combphy_parse_dt(struct udevice *dev,
+                                    struct rockchip_combphy_priv *priv)
+ {
+-      struct udevice *syscon;
+       int ret;
+-      ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-grf", &syscon);
+-      if (ret) {
+-              dev_err(dev, "failed to find peri_ctrl pipe-grf regmap");
+-              return ret;
++      priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,pipe-grf");
++      if (IS_ERR(priv->pipe_grf)) {
++              dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n");
++              return PTR_ERR(priv->pipe_grf);
+       }
+-      priv->pipe_grf = syscon_get_regmap(syscon);
+-      ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pipe-phy-grf", &syscon);
+-      if (ret) {
++      priv->phy_grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,pipe-phy-grf");
++      if (IS_ERR(priv->phy_grf)) {
+               dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
+-              return ret;
++              return PTR_ERR(priv->phy_grf);
+       }
+-      priv->phy_grf = syscon_get_regmap(syscon);
+       ret = clk_get_by_index(dev, 0, &priv->ref_clk);
+       if (ret) {
diff --git a/package/boot/uboot-rockchip/patches/015-phy-rockchip-inno-usb2-Fix-improper-use-of-UCLASS_PHY.patch b/package/boot/uboot-rockchip/patches/015-phy-rockchip-inno-usb2-Fix-improper-use-of-UCLASS_PHY.patch
new file mode 100644 (file)
index 0000000..58ee8b8
--- /dev/null
@@ -0,0 +1,30 @@
+From c8e6a7131d58511129cdec16f269600b51f0a45a Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:15 +0000
+Subject: [PATCH] phy: rockchip: inno-usb2: Fix improper use of UCLASS_PHY
+
+The Rockchip USB2PHY glue driver improperly present itself as a
+UCLASS_PHY driver, without ever implementing the required phy_ops.
+
+This is something that in special circumstances can lead to a NULL
+pointer dereference followed by a SError crash.
+
+Change the glue driver to use UCLASS_NOP to fix this.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
+@@ -573,7 +573,7 @@ U_BOOT_DRIVER(rockchip_usb2phy_clock) =
+ U_BOOT_DRIVER(rockchip_usb2phy) = {
+       .name   = "rockchip_usb2phy",
+-      .id     = UCLASS_PHY,
++      .id     = UCLASS_NOP,
+       .of_match = rockchip_usb2phy_ids,
+       .probe = rockchip_usb2phy_probe,
+       .bind = rockchip_usb2phy_bind,
diff --git a/package/boot/uboot-rockchip/patches/016-phy-rockchip-typec-Fix-improper-use-of-UCLASS_PHY.patch b/package/boot/uboot-rockchip/patches/016-phy-rockchip-typec-Fix-improper-use-of-UCLASS_PHY.patch
new file mode 100644 (file)
index 0000000..24b9e4c
--- /dev/null
@@ -0,0 +1,30 @@
+From fca01a8792e6ed48a00e08124d55f4f74e47b11d Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:16 +0000
+Subject: [PATCH] phy: rockchip: typec: Fix improper use of UCLASS_PHY
+
+The Rockchip TypeC glue driver improperly present itself as a UCLASS_PHY
+driver, without ever implementing the required phy_ops.
+
+This is something that in special circumstances can lead to a NULL
+pointer dereference followed by a SError crash.
+
+Change the glue driver to use UCLASS_NOP to fix this.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ drivers/phy/rockchip/phy-rockchip-typec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/phy/rockchip/phy-rockchip-typec.c
++++ b/drivers/phy/rockchip/phy-rockchip-typec.c
+@@ -788,7 +788,7 @@ U_BOOT_DRIVER(rockchip_tcphy_usb3_port)
+ U_BOOT_DRIVER(rockchip_typec_phy) = {
+       .name   = "rockchip_typec_phy",
+-      .id     = UCLASS_PHY,
++      .id     = UCLASS_NOP,
+       .of_match = rockchip_typec_phy_ids,
+       .probe = rockchip_tcphy_probe,
+       .bind = rockchip_tcphy_bind,
diff --git a/package/boot/uboot-rockchip/patches/017-rockchip-rk3588-Disable-USB3OTG-U3-ports-early.patch b/package/boot/uboot-rockchip/patches/017-rockchip-rk3588-Disable-USB3OTG-U3-ports-early.patch
new file mode 100644 (file)
index 0000000..d7fb41b
--- /dev/null
@@ -0,0 +1,46 @@
+From 9d39a56922878562b263e45f45523021cf5e7789 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:17 +0000
+Subject: [PATCH] rockchip: rk3588: Disable USB3OTG U3 ports early
+
+The RK3588 SoC comes with USB OTG support using a DWC3 controller with
+a USB2 PHY and a USB3 PHY (USBDP PHY).
+
+Some board designs may not use the USBDP PHY for USB3 purpose. For these
+board to use USB OTG the input clock source must change to use UTMI clk
+instead of PIPE clk.
+
+Change to always disable the USB3OTG U3 ports early and leave it to the
+USBDP PHY driver to re-enable the U3 port when a usb3-phy is described
+in the board device tree.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ arch/arm/mach-rockchip/rk3588/rk3588.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/arch/arm/mach-rockchip/rk3588/rk3588.c
++++ b/arch/arm/mach-rockchip/rk3588/rk3588.c
+@@ -15,6 +15,10 @@
+ #include <asm/arch-rockchip/hardware.h>
+ #include <asm/arch-rockchip/ioc_rk3588.h>
++#define USB_GRF_BASE                  0xfd5ac000
++#define USB3OTG0_CON1                 0x001c
++#define USB3OTG1_CON1                 0x0034
++
+ #define FIREWALL_DDR_BASE             0xfe030000
+ #define FW_DDR_MST5_REG                       0x54
+ #define FW_DDR_MST13_REG              0x74
+@@ -184,6 +188,10 @@ int arch_cpu_init(void)
+       /* Disable JTAG exposed on SDMMC */
+       rk_clrreg(&sys_grf->soc_con[6], SYS_GRF_FORCE_JTAG);
+ #endif
++
++      /* Disable USB3OTG U3 ports, later enabled by USBDP PHY driver */
++      writel(0xffff0188, USB_GRF_BASE + USB3OTG0_CON1);
++      writel(0xffff0188, USB_GRF_BASE + USB3OTG1_CON1);
+ #endif
+       return 0;
diff --git a/package/boot/uboot-rockchip/patches/018-rockchip-rk3576-Disable-USB3OTG0-U3-port-early.patch b/package/boot/uboot-rockchip/patches/018-rockchip-rk3576-Disable-USB3OTG0-U3-port-early.patch
new file mode 100644 (file)
index 0000000..12b7ff4
--- /dev/null
@@ -0,0 +1,44 @@
+From be585d4916864387c53c82b4bde7f04093aac440 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+Date: Mon, 21 Jul 2025 22:07:18 +0000
+Subject: [PATCH] rockchip: rk3576: Disable USB3OTG0 U3 port early
+
+The RK3576 SoC comes with USB OTG support using a DWC3 controller with
+a USB2 PHY and a USB3 PHY (USBDP PHY).
+
+Some board designs may not use the USBDP PHY for USB3 purpose. For these
+board to use USB OTG the input clock source must change to use UTMI clk
+instead of PIPE clk.
+
+Change to always disable the USB3OTG0 U3 port early and leave it to the
+USBDP PHY driver to re-enable the U3 port when a usb3-phy is described
+in the board device tree.
+
+Signed-off-by: Jonas Karlman <[email protected]>
+Reviewed-by: Kever Yang <[email protected]>
+---
+ arch/arm/mach-rockchip/rk3576/rk3576.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/arm/mach-rockchip/rk3576/rk3576.c
++++ b/arch/arm/mach-rockchip/rk3576/rk3576.c
+@@ -33,6 +33,9 @@
+ #define SGRF_DOMAIN_CON4      0x10
+ #define SGRF_DOMAIN_CON5      0x14
++#define USB_GRF_BASE          0x2601E000
++#define USB3OTG0_CON1         0x0030
++
+ const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+       [BROM_BOOTSOURCE_EMMC] = "/soc/mmc@2a330000",
+       [BROM_BOOTSOURCE_SD] = "/soc/mmc@2a310000",
+@@ -155,6 +158,9 @@ int arch_cpu_init(void)
+        */
+       writel(0xffffff00, SYS_SGRF_BASE + SYS_SGRF_SOC_CON20);
++      /* Disable USB3OTG0 U3 port, later enabled by USBDP PHY driver */
++      writel(0xffff0188, USB_GRF_BASE + USB3OTG0_CON1);
++
+       return 0;
+ }
diff --git a/package/boot/uboot-rockchip/patches/101-nanopc-t4-fix-memory-unstability.patch b/package/boot/uboot-rockchip/patches/101-nanopc-t4-fix-memory-unstability.patch
new file mode 100644 (file)
index 0000000..b467f48
--- /dev/null
@@ -0,0 +1,22 @@
+From 445502bc21ecf1b5120faee785cea578b810c759 Mon Sep 17 00:00:00 2001
+From: Lu jicong <[email protected]>
+Date: Wed, 5 Jul 2023 17:13:55 +0800
+Subject: [PATCH] rockchip: rk3399: nanopc-t4: use 1600MHz sdram config
+
+Current 1866MHz sdram config is too high for NanoPC-T4.
+On this frequency, its lpddr3 sdram becomes unstable,
+causing memtest failures and random kernel crashes.
+
+Signed-off-by: Lu jicong <[email protected]>
+---
+ arch/arm/dts/rk3399-nanopc-t4-u-boot.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm/dts/rk3399-nanopc-t4-u-boot.dtsi
++++ b/arch/arm/dts/rk3399-nanopc-t4-u-boot.dtsi
+@@ -4,4 +4,4 @@
+  */
+ #include "rk3399-nanopi4-u-boot.dtsi"
+-#include "rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi"
++#include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
diff --git a/package/boot/uboot-rockchip/patches/102-rockchip-Add-initial-RK3582-support.patch b/package/boot/uboot-rockchip/patches/102-rockchip-Add-initial-RK3582-support.patch
new file mode 100644 (file)
index 0000000..9eef599
--- /dev/null
@@ -0,0 +1,245 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+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 <[email protected]>
+
+--- 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>
+@@ -200,6 +201,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)
+ {
+@@ -245,3 +255,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@0", "cpu@100", "cpu@200", "cpu@300",
++              "cpu@400", "cpu@500", "cpu@600", "cpu@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@fdc38100");
++              fdt_status_fail_by_pathf(blob, "/iommu@fdc38700");
++      }
++      if (ip_state[1] & FAIL_RKVDEC1) {
++              log_debug("fail rkvdec1\n");
++              fdt_status_fail_by_pathf(blob, "/video-codec@fdc40100");
++              fdt_status_fail_by_pathf(blob, "/iommu@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@fdbd0000");
++              fdt_status_fail_by_pathf(blob, "/iommu@fdbdf000");
++      }
++      if (ip_state[2] & FAIL_RKVENC1) {
++              log_debug("fail rkvenc1\n");
++              fdt_status_fail_by_pathf(blob, "/video-codec@fdbe0000");
++              fdt_status_fail_by_pathf(blob, "/iommu@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/103-rockchip-rk3588-generic-Enable-support-for-RK3582.patch b/package/boot/uboot-rockchip/patches/103-rockchip-rk3588-generic-Enable-support-for-RK3582.patch
new file mode 100644 (file)
index 0000000..1990bf9
--- /dev/null
@@ -0,0 +1,72 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+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@400
+  fail cpu cpu@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@600
+  fail cpu cpu@700
+
+Signed-off-by: Jonas Karlman <[email protected]>
+
+--- 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
+@@ -147,7 +147,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/104-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch b/package/boot/uboot-rockchip/patches/104-rockchip-rk3588s-rock-5c-Add-support-for-ROCK-5C-Lit.patch
new file mode 100644 (file)
index 0000000..a69f9d8
--- /dev/null
@@ -0,0 +1,32 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jonas Karlman <[email protected]>
+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@600
+  fail cpu cpu@700
+
+Signed-off-by: Jonas Karlman <[email protected]>
+
+--- 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
diff --git a/package/boot/uboot-rockchip/patches/105-nanopc-t4-fix-memory-unstability.patch b/package/boot/uboot-rockchip/patches/105-nanopc-t4-fix-memory-unstability.patch
deleted file mode 100644 (file)
index b467f48..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From 445502bc21ecf1b5120faee785cea578b810c759 Mon Sep 17 00:00:00 2001
-From: Lu jicong <[email protected]>
-Date: Wed, 5 Jul 2023 17:13:55 +0800
-Subject: [PATCH] rockchip: rk3399: nanopc-t4: use 1600MHz sdram config
-
-Current 1866MHz sdram config is too high for NanoPC-T4.
-On this frequency, its lpddr3 sdram becomes unstable,
-causing memtest failures and random kernel crashes.
-
-Signed-off-by: Lu jicong <[email protected]>
----
- arch/arm/dts/rk3399-nanopc-t4-u-boot.dtsi | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/arm/dts/rk3399-nanopc-t4-u-boot.dtsi
-+++ b/arch/arm/dts/rk3399-nanopc-t4-u-boot.dtsi
-@@ -4,4 +4,4 @@
-  */
- #include "rk3399-nanopi4-u-boot.dtsi"
--#include "rk3399-sdram-lpddr3-samsung-4GB-1866.dtsi"
-+#include "rk3399-sdram-lpddr3-4GB-1600.dtsi"
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
deleted file mode 100644 (file)
index a2b5768..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jonas Karlman <[email protected]>
-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 <[email protected]>
-
---- 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@0", "cpu@100", "cpu@200", "cpu@300",
-+              "cpu@400", "cpu@500", "cpu@600", "cpu@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@fdc38100");
-+              fdt_status_fail_by_pathf(blob, "/iommu@fdc38700");
-+      }
-+      if (ip_state[1] & FAIL_RKVDEC1) {
-+              log_debug("fail rkvdec1\n");
-+              fdt_status_fail_by_pathf(blob, "/video-codec@fdc40100");
-+              fdt_status_fail_by_pathf(blob, "/iommu@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@fdbd0000");
-+              fdt_status_fail_by_pathf(blob, "/iommu@fdbdf000");
-+      }
-+      if (ip_state[2] & FAIL_RKVENC1) {
-+              log_debug("fail rkvenc1\n");
-+              fdt_status_fail_by_pathf(blob, "/video-codec@fdbe0000");
-+              fdt_status_fail_by_pathf(blob, "/iommu@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
deleted file mode 100644 (file)
index eb10ecb..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jonas Karlman <[email protected]>
-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@400
-  fail cpu cpu@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@600
-  fail cpu cpu@700
-
-Signed-off-by: Jonas Karlman <[email protected]>
-
---- 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
-@@ -146,7 +146,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
deleted file mode 100644 (file)
index a69f9d8..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jonas Karlman <[email protected]>
-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@600
-  fail cpu cpu@700
-
-Signed-off-by: Jonas Karlman <[email protected]>
-
---- 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