* [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support
@ 2026-02-08 21:26 Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support Fabio Estevam
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Fabio Estevam
From: Fabio Estevam <festevam@nabladev.com>
Hi,
This patch series adds support for the Onion RV1103B Omega4 board.
It covers SPL, SPI NAND boot, and the minimal board devicetree required to
boot the board.
Upstreaming the RV1103B devicetree in Linux is ongoing, but to avoid blocking
U-Boot support, this series introduces board-specific devicetrees for now.
Once the Linux RV1103B devicetrees are upstreamed, the OF_UPSTREAM mechanism
can be enabled.
In v2, the correct SoC name was used: RV1103B instead of RV1103 (Thanks Jonas!),
the RV1103B dt-bindings, devicetrees, clock and pinctrl drivers have been
submitted upstream.
The dt-bindings have already been reviewed by the Linux DT maintainer:
https://lore.kernel.org/linux-devicetree/cadee46d-589b-4833-8650-691f7a0f8321@kernel.org/
https://lore.kernel.org/linux-devicetree/a2be67b7-a33a-4d72-b5b7-fa900063b599@kernel.org/
https://lore.kernel.org/linux-devicetree/47561412-cbaa-42c7-b8ab-9cafb7e0f9be@kernel.org/
https://lore.kernel.org/linux-devicetree/20260207-hulking-elegant-ferret-8efcea@quoll/
https://lore.kernel.org/linux-devicetree/20260208-analytic-fine-grouse-e17baa@quoll/
https://lore.kernel.org/linux-devicetree/20260208-pearl-ammonite-of-warranty-2c9212@quoll/
Tested the boot of a 6.6 OpenWRT kernel and also a 6.19-rc8 mainline kernel.
This series has successfully passed through CI.
Elaine Zhang (1):
clk: rockchip: Add RV1103B clock driver
Fabio Estevam (4):
ARM: dts: Add RV1103B Omega4 support
rockchip: spl-boot-order: Add SPI NAND support
spl: add SPI NAND support via MTD in SPL
omega4-rv1103b: Add the initial support
Xuhui Lin (1):
tools: rkcommon: Add RV1103B support
Ye Zhang (1):
pinctrl: rockchip: Add RV1103B support
arch/arm/dts/rv1103b-omega4-u-boot.dtsi | 10 +
arch/arm/dts/rv1103b-omega4.dts | 105 ++
arch/arm/dts/rv1103b-pinctrl.dtsi | 831 +++++++++++++
arch/arm/dts/rv1103b-u-boot.dtsi | 4 +
arch/arm/dts/rv1103b.dtsi | 266 ++++
.../include/asm/arch-rockchip/cru_rv1103b.h | 266 ++++
.../include/asm/arch-rockchip/grf_rv1103b.h | 31 +
arch/arm/include/asm/arch-rv1103b/boot0.h | 11 +
arch/arm/mach-rockchip/Kconfig | 14 +
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rv1103b/Kconfig | 23 +
arch/arm/mach-rockchip/rv1103b/Makefile | 12 +
arch/arm/mach-rockchip/rv1103b/boot0.h | 5 +
arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c | 32 +
arch/arm/mach-rockchip/rv1103b/rv1103b.c | 133 ++
.../mach-rockchip/rv1103b/syscon_rv1103b.c | 19 +
arch/arm/mach-rockchip/spl-boot-order.c | 11 +-
board/onion/omega4_rv1103b/Kconfig | 12 +
board/onion/omega4_rv1103b/MAINTAINERS | 6 +
board/onion/omega4_rv1103b/Makefile | 7 +
board/onion/omega4_rv1103b/omega4_rv1103b.c | 19 +
board/onion/omega4_rv1103b/omega4_rv1103b.env | 5 +
common/spl/Kconfig | 10 +-
common/spl/Makefile | 1 +
common/spl/spl_spi_nand.c | 82 ++
configs/omega4-rv1103b_defconfig | 82 ++
doc/board/index.rst | 1 +
doc/board/onion/index.rst | 9 +
doc/board/onion/omega4-rv1103b.rst | 56 +
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk_rv1103b.c | 1068 +++++++++++++++++
drivers/mtd/Makefile | 1 +
drivers/mtd/nand/Makefile | 13 +-
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl-rv1103b.c | 398 ++++++
include/configs/omega4_rv1103b.h | 11 +
include/configs/rv1103b_common.h | 14 +
.../dt-bindings/clock/rockchip,rv1103b-cru.h | 220 ++++
tools/rkcommon.c | 1 +
39 files changed, 3788 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/dts/rv1103b-omega4-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103b-omega4.dts
create mode 100644 arch/arm/dts/rv1103b-pinctrl.dtsi
create mode 100644 arch/arm/dts/rv1103b-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103b.dtsi
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rv1103b.h
create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rv1103b.h
create mode 100644 arch/arm/include/asm/arch-rv1103b/boot0.h
create mode 100644 arch/arm/mach-rockchip/rv1103b/Kconfig
create mode 100644 arch/arm/mach-rockchip/rv1103b/Makefile
create mode 100644 arch/arm/mach-rockchip/rv1103b/boot0.h
create mode 100644 arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c
create mode 100644 arch/arm/mach-rockchip/rv1103b/rv1103b.c
create mode 100644 arch/arm/mach-rockchip/rv1103b/syscon_rv1103b.c
create mode 100644 board/onion/omega4_rv1103b/Kconfig
create mode 100644 board/onion/omega4_rv1103b/MAINTAINERS
create mode 100644 board/onion/omega4_rv1103b/Makefile
create mode 100644 board/onion/omega4_rv1103b/omega4_rv1103b.c
create mode 100644 board/onion/omega4_rv1103b/omega4_rv1103b.env
create mode 100644 common/spl/spl_spi_nand.c
create mode 100644 configs/omega4-rv1103b_defconfig
create mode 100644 doc/board/onion/index.rst
create mode 100644 doc/board/onion/omega4-rv1103b.rst
create mode 100644 drivers/clk/rockchip/clk_rv1103b.c
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1103b.c
create mode 100644 include/configs/omega4_rv1103b.h
create mode 100644 include/configs/rv1103b_common.h
create mode 100644 include/dt-bindings/clock/rockchip,rv1103b-cru.h
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
2026-02-09 10:45 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 2/7] pinctrl: rockchip: Add RV1103B support Fabio Estevam
` (5 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Fabio Estevam
From: Fabio Estevam <festevam@nabladev.com>
Add the necessary devicetrees to support the RV1103B Omega4 board.
The RV1103B is a Rockchip SoC that is still not supported in Linux
mainline.
The initial RV1103B support has already been submitted to Linux kernel
and it is under review.
Once the Linux RV1103 devicetrees are upstreamed, the OF_UPSTREAM mechanism
can be enabled.
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- Used the devicetrees submitted to upstream Linux.
arch/arm/dts/rv1103b-omega4-u-boot.dtsi | 10 +
arch/arm/dts/rv1103b-omega4.dts | 105 +++
arch/arm/dts/rv1103b-pinctrl.dtsi | 831 ++++++++++++++++++
arch/arm/dts/rv1103b-u-boot.dtsi | 4 +
arch/arm/dts/rv1103b.dtsi | 266 ++++++
.../dt-bindings/clock/rockchip,rv1103b-cru.h | 220 +++++
6 files changed, 1436 insertions(+)
create mode 100644 arch/arm/dts/rv1103b-omega4-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103b-omega4.dts
create mode 100644 arch/arm/dts/rv1103b-pinctrl.dtsi
create mode 100644 arch/arm/dts/rv1103b-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103b.dtsi
create mode 100644 include/dt-bindings/clock/rockchip,rv1103b-cru.h
diff --git a/arch/arm/dts/rv1103b-omega4-u-boot.dtsi b/arch/arm/dts/rv1103b-omega4-u-boot.dtsi
new file mode 100644
index 000000000000..c7616de1715c
--- /dev/null
+++ b/arch/arm/dts/rv1103b-omega4-u-boot.dtsi
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
+// (C) Copyright 2024 Rockchip Electronics Co., Ltd
+
+#include "rockchip-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = &spi_nand;
+ };
+};
diff --git a/arch/arm/dts/rv1103b-omega4.dts b/arch/arm/dts/rv1103b-omega4.dts
new file mode 100644
index 000000000000..3d58954d5e4a
--- /dev/null
+++ b/arch/arm/dts/rv1103b-omega4.dts
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2025 plan44.ch/luz
+ * Copyright (c) 2025 Onion Corporation
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "rv1103b.dtsi"
+
+/ {
+ model = "Onion RV1103 Omega4 Board";
+ compatible = "onion,rv1103b-omega4", "rockchip,rv1103b";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pin>;
+ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ label = "sys";
+ default-state = "on";
+ };
+ };
+};
+
+&fspi0 {
+ status = "okay";
+
+ spi_nand: flash@0 {
+ compatible = "spi-nand";
+ reg = <0>;
+ bootph-pre-ram;
+ bootph-some-ram;
+ spi-max-frequency = <75000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "env";
+ reg = <0x00000000 0x00040000>;
+ };
+
+ partition@40000 {
+ label = "idblock";
+ reg = <0x00040000 0x00100000>;
+ read-only;
+ };
+
+ partition@140000 {
+ label = "uboot";
+ reg = <0x00140000 0x00100000>;
+ read-only;
+ };
+
+ partition@240000 {
+ label = "boot";
+ reg = <0x00240000 0x00800000>;
+ };
+
+ partition@a40000 {
+ label = "ubi";
+ reg = <0x00a40000 0x0f5c0000>;
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0m0_xfer_pins>;
+ bootph-all;
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&pinctrl {
+ leds {
+ led_pin: led-pin {
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rv1103b-pinctrl.dtsi b/arch/arm/dts/rv1103b-pinctrl.dtsi
new file mode 100644
index 000000000000..bc4d8fcdfaf7
--- /dev/null
+++ b/arch/arm/dts/rv1103b-pinctrl.dtsi
@@ -0,0 +1,831 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <arm64/rockchip/rockchip-pinconf.dtsi>
+
+/*
+ * This file is auto generated by pin2dts tool, please keep these code
+ * by adding changes at end of this file.
+ */
+&pinctrl {
+ cam_clk0 {
+ cam_clk0_pins: cam-clk0-pins {
+ rockchip,pins =
+ /* cam_clk0_out */
+ <1 RK_PB5 1 &pcfg_pull_none>;
+ };
+ };
+
+ cam_clk1 {
+ cam_clk1_pins: cam-clk1-pins {
+ rockchip,pins =
+ /* cam_clk1_out */
+ <1 RK_PB6 1 &pcfg_pull_none>;
+ };
+ };
+
+ cam_spi {
+ cam_spi_bus4_pins: cam-spi-bus4-pins {
+ rockchip,pins =
+ /* cam_spi_d0 */
+ <0 RK_PB5 4 &pcfg_pull_up_drv_level_2>,
+ /* cam_spi_d1 */
+ <0 RK_PB2 4 &pcfg_pull_up_drv_level_2>,
+ /* cam_spi_d2 */
+ <0 RK_PB1 4 &pcfg_pull_up_drv_level_2>,
+ /* cam_spi_d3 */
+ <0 RK_PB0 4 &pcfg_pull_up_drv_level_2>;
+ };
+ cam_spi_clk_pins: cam-spi-clk-pins {
+ rockchip,pins =
+ /* cam_spi_clk */
+ <0 RK_PB4 4 &pcfg_pull_none>;
+ };
+ cam_spi_cs0n_pins: cam-spi-cs0n-pins {
+ rockchip,pins =
+ /* cam_spi_cs0n */
+ <0 RK_PB3 4 &pcfg_pull_none>;
+ };
+ };
+
+ clk {
+ clk_32k_pins: clk-32k-pins {
+ rockchip,pins =
+ /* clk_32k */
+ <0 RK_PA0 2 &pcfg_pull_none>;
+ };
+ };
+
+ clk_24m {
+ clk_24m_out_pins: clk-24m-out-pins {
+ rockchip,pins =
+ /* clk_24m_out */
+ <0 RK_PA0 3 &pcfg_pull_none>;
+ };
+ };
+
+ cpu {
+ cpu_pins: cpu-pins {
+ rockchip,pins =
+ /* cpu_avs */
+ <0 RK_PA1 2 &pcfg_pull_none>;
+ };
+ };
+
+ emmc {
+ emmc_bus4_pins: emmc-bus4-pins {
+ rockchip,pins =
+ /* emmc_d0 */
+ <1 RK_PA1 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d1 */
+ <1 RK_PA2 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d2 */
+ <1 RK_PA3 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d3 */
+ <1 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
+ };
+ emmc_clk_pins: emmc-clk-pins {
+ rockchip,pins =
+ /* emmc_clk */
+ <1 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
+ };
+ emmc_cmd_pins: emmc-cmd-pins {
+ rockchip,pins =
+ /* emmc_cmd */
+ <1 RK_PA5 1 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ emmc_testclk {
+ emmc_testclk_clk_pins: emmc-testclk-clk-pins {
+ rockchip,pins =
+ /* emmc_testclk_out */
+ <1 RK_PA7 3 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ emmc_testdata {
+ emmc_testdata_out_pins: emmc-testdata-out-pins {
+ rockchip,pins =
+ /* emmc_testdata_out */
+ <1 RK_PB0 3 &pcfg_pull_none>;
+ };
+ };
+
+ eth_led {
+ eth_led_dpx_pins: eth-led-dpx-pins {
+ rockchip,pins =
+ /* eth_led_dpx */
+ <2 RK_PA4 6 &pcfg_pull_none>;
+ };
+ eth_led_link_pins: eth-led-link-pins {
+ rockchip,pins =
+ /* eth_led_link */
+ <2 RK_PA6 6 &pcfg_pull_none>;
+ };
+ eth_led_spd_pins: eth-led-spd-pins {
+ rockchip,pins =
+ /* eth_led_spd */
+ <2 RK_PA7 6 &pcfg_pull_none>;
+ };
+ };
+
+ flash_trig {
+ flash_trig_pins: flash-trig-pins {
+ rockchip,pins =
+ /* flash_trig_out */
+ <2 RK_PB0 6 &pcfg_pull_none>;
+ };
+ };
+
+ fspi {
+ fspi_bus4_pins: fspi-bus4-pins {
+ rockchip,pins =
+ /* fspi_d0 */
+ <1 RK_PA1 2 &pcfg_pull_none>,
+ /* fspi_d1 */
+ <1 RK_PA2 2 &pcfg_pull_none>,
+ /* fspi_d2 */
+ <1 RK_PA3 2 &pcfg_pull_none>,
+ /* fspi_d3 */
+ <1 RK_PA0 2 &pcfg_pull_none>;
+ };
+ fspi_cs0_pins: fspi-cs0-pins {
+ rockchip,pins =
+ /* fspi_cs0n */
+ <1 RK_PA5 2 &pcfg_pull_up>;
+ };
+ fspi_clk_pins: fspi-clk-pins {
+ rockchip,pins =
+ /* fspi_clk */
+ <1 RK_PA4 2 &pcfg_pull_none>;
+ };
+ };
+
+ fspi_testclk {
+ fspi_testclk_out_pins: fspi-testclk-out-pins {
+ rockchip,pins =
+ /* fspi_testclk_out */
+ <1 RK_PA7 5 &pcfg_pull_none>;
+ };
+ };
+
+ fspi_testdata {
+ fspi_testdata_out_pins: fspi-testdata-out-pins {
+ rockchip,pins =
+ /* fspi_testdata_out */
+ <1 RK_PB0 5 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0m0_xfer_pins: i2c0m0-xfer-pins {
+ rockchip,pins =
+ /* i2c0_scl_m0 */
+ <0 RK_PA5 3 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m0 */
+ <0 RK_PA6 3 &pcfg_pull_none_smt>;
+ };
+ i2c0m1_xfer_pins: i2c0m1-xfer-pins {
+ rockchip,pins =
+ /* i2c0_scl_m1 */
+ <1 RK_PB4 5 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m1 */
+ <1 RK_PB3 5 &pcfg_pull_none_smt>;
+ };
+ i2c0m2_xfer_pins: i2c0m2-xfer-pins {
+ rockchip,pins =
+ /* i2c0_scl_m2 */
+ <1 RK_PB5 2 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m2 */
+ <1 RK_PB6 2 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c1 {
+ i2c1m0_xfer_pins: i2c1m0-xfer-pins {
+ rockchip,pins =
+ /* i2c1_scl_m0 */
+ <0 RK_PB0 1 &pcfg_pull_none_smt>,
+ /* i2c1_sda_m0 */
+ <0 RK_PB1 1 &pcfg_pull_none_smt>;
+ };
+ i2c1m1_xfer_pins: i2c1m1-xfer-pins {
+ rockchip,pins =
+ /* i2c1_scl_m1 */
+ <2 RK_PA4 4 &pcfg_pull_none_smt>,
+ /* i2c1_sda_m1 */
+ <2 RK_PA5 4 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c2 {
+ i2c2m0_xfer_pins: i2c2m0-xfer-pins {
+ rockchip,pins =
+ /* i2c2_scl_m0 */
+ <0 RK_PB2 1 &pcfg_pull_none_smt>,
+ /* i2c2_sda_m0 */
+ <0 RK_PB3 1 &pcfg_pull_none_smt>;
+ };
+ i2c2m1_xfer_pins: i2c2m1-xfer-pins {
+ rockchip,pins =
+ /* i2c2_scl_m1 */
+ <2 RK_PA6 4 &pcfg_pull_none_smt>,
+ /* i2c2_sda_m1 */
+ <2 RK_PA7 4 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c3 {
+ i2c3m0_xfer_pins: i2c3m0-xfer-pins {
+ rockchip,pins =
+ /* i2c3_scl_m0 */
+ <0 RK_PB4 1 &pcfg_pull_none_smt>,
+ /* i2c3_sda_m0 */
+ <0 RK_PB5 1 &pcfg_pull_none_smt>;
+ };
+ i2c3m1_xfer_pins: i2c3m1-xfer-pins {
+ rockchip,pins =
+ /* i2c3_scl_m1 */
+ <2 RK_PB3 4 &pcfg_pull_none_smt>,
+ /* i2c3_sda_m1 */
+ <2 RK_PB2 4 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c4 {
+ i2c4m0_xfer_pins: i2c4m0-xfer-pins {
+ rockchip,pins =
+ /* i2c4_scl_m0 */
+ <2 RK_PB0 4 &pcfg_pull_none_smt>,
+ /* i2c4_sda_m0 */
+ <2 RK_PB1 4 &pcfg_pull_none_smt>;
+ };
+ i2c4m1_xfer_pins: i2c4m1-xfer-pins {
+ rockchip,pins =
+ /* i2c4_scl_m1 */
+ <1 RK_PB7 2 &pcfg_pull_none_smt>,
+ /* i2c4_sda_m1 */
+ <1 RK_PC0 2 &pcfg_pull_none_smt>;
+ };
+ };
+
+ jtag {
+ jtagm0_pins: jtagm0-pins {
+ rockchip,pins =
+ /* jtag_tck_m0 */
+ <0 RK_PA5 5 &pcfg_pull_none>,
+ /* jtag_tms_m0 */
+ <0 RK_PA6 5 &pcfg_pull_none>;
+ };
+ jtagm1_pins: jtagm1-pins {
+ rockchip,pins =
+ /* jtag_tck_m1 */
+ <0 RK_PB4 3 &pcfg_pull_none>,
+ /* jtag_tms_m1 */
+ <0 RK_PB5 3 &pcfg_pull_none>;
+ };
+ jtagm2_pins: jtagm2-pins {
+ rockchip,pins =
+ /* jtag_tck_m2 */
+ <1 RK_PB4 3 &pcfg_pull_none>,
+ /* jtag_tms_m2 */
+ <1 RK_PB3 3 &pcfg_pull_none>;
+ };
+ };
+
+ pmu_debug_test {
+ pmu_debug_test_pins: pmu-debug-test-pins {
+ rockchip,pins =
+ /* pmu_debug_test_out */
+ <0 RK_PB1 5 &pcfg_pull_none>;
+ };
+ };
+
+ prelight_trig {
+ prelight_trig_pins: prelight-trig-pins {
+ rockchip,pins =
+ /* prelight_trig_out */
+ <2 RK_PB1 6 &pcfg_pull_none>;
+ };
+ };
+
+ psram_spi {
+ psram_spi_bus4_pins: psram-spi-bus4-pins {
+ rockchip,pins =
+ /* psram_spi_d0 */
+ <0 RK_PA2 4 &pcfg_pull_none>,
+ /* psram_spi_d1 */
+ <0 RK_PA1 4 &pcfg_pull_none>,
+ /* psram_spi_d2 */
+ <0 RK_PA5 4 &pcfg_pull_none>,
+ /* psram_spi_d3 */
+ <0 RK_PA6 4 &pcfg_pull_none>;
+ };
+ psram_spi_clk_pins: psram-spi-clk-pins {
+ rockchip,pins =
+ /* psram_spi_clk */
+ <0 RK_PA0 4 &pcfg_pull_none>;
+ };
+ psram_spi_cs0n_pins: psram-spi-cs0n-pins {
+ rockchip,pins =
+ /* psram_spi_cs0n */
+ <0 RK_PA4 4 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0m0_ch0_pins: pwm0m0-ch0-pins {
+ rockchip,pins =
+ /* pwm0m0_ch0 */
+ <0 RK_PA1 1 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m0_ch1_pins: pwm0m0-ch1-pins {
+ rockchip,pins =
+ /* pwm0m0_ch1 */
+ <0 RK_PA5 2 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m0_ch2_pins: pwm0m0-ch2-pins {
+ rockchip,pins =
+ /* pwm0m0_ch2 */
+ <0 RK_PA6 2 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m0_ch3_pins: pwm0m0-ch3-pins {
+ rockchip,pins =
+ /* pwm0m0_ch3 */
+ <0 RK_PA2 1 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m1_ch0_pins: pwm0m1-ch0-pins {
+ rockchip,pins =
+ /* pwm0m1_ch0 */
+ <2 RK_PA0 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m1_ch1_pins: pwm0m1-ch1-pins {
+ rockchip,pins =
+ /* pwm0m1_ch1 */
+ <2 RK_PA1 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m1_ch2_pins: pwm0m1-ch2-pins {
+ rockchip,pins =
+ /* pwm0m1_ch2 */
+ <2 RK_PA2 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m1_ch3_pins: pwm0m1-ch3-pins {
+ rockchip,pins =
+ /* pwm0m1_ch3 */
+ <2 RK_PB0 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m2_ch1_pins: pwm0m2-ch1-pins {
+ rockchip,pins =
+ /* pwm0m2_ch1 */
+ <1 RK_PB7 1 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm0m2_ch2_pins: pwm0m2-ch2-pins {
+ rockchip,pins =
+ /* pwm0m2_ch2 */
+ <1 RK_PC0 1 &pcfg_pull_none_drv_level_0>;
+ };
+ };
+
+ pwm1 {
+ pwm1m0_ch0_pins: pwm1m0-ch0-pins {
+ rockchip,pins =
+ /* pwm1m0_ch0 */
+ <0 RK_PB0 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m0_ch1_pins: pwm1m0-ch1-pins {
+ rockchip,pins =
+ /* pwm1m0_ch1 */
+ <0 RK_PB1 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m0_ch2_pins: pwm1m0-ch2-pins {
+ rockchip,pins =
+ /* pwm1m0_ch2 */
+ <0 RK_PB2 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m0_ch3_pins: pwm1m0-ch3-pins {
+ rockchip,pins =
+ /* pwm1m0_ch3 */
+ <0 RK_PB3 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m1_ch0_pins: pwm1m1-ch0-pins {
+ rockchip,pins =
+ /* pwm1m1_ch0 */
+ <2 RK_PA3 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m1_ch1_pins: pwm1m1-ch1-pins {
+ rockchip,pins =
+ /* pwm1m1_ch1 */
+ <2 RK_PA4 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m1_ch2_pins: pwm1m1-ch2-pins {
+ rockchip,pins =
+ /* pwm1m1_ch2 */
+ <2 RK_PA5 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm1m1_ch3_pins: pwm1m1-ch3-pins {
+ rockchip,pins =
+ /* pwm1m1_ch3 */
+ <2 RK_PB1 3 &pcfg_pull_none_drv_level_0>;
+ };
+ };
+
+ pwm2 {
+ pwm2m0_ch0_pins: pwm2m0-ch0-pins {
+ rockchip,pins =
+ /* pwm2m0_ch0 */
+ <1 RK_PB0 4 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m0_ch1_pins: pwm2m0-ch1-pins {
+ rockchip,pins =
+ /* pwm2m0_ch1 */
+ <1 RK_PA7 4 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m0_ch2_pins: pwm2m0-ch2-pins {
+ rockchip,pins =
+ /* pwm2m0_ch2 */
+ <1 RK_PB4 4 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m0_ch3_pins: pwm2m0-ch3-pins {
+ rockchip,pins =
+ /* pwm2m0_ch3 */
+ <1 RK_PB3 4 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m1_ch0_pins: pwm2m1-ch0-pins {
+ rockchip,pins =
+ /* pwm2m1_ch0 */
+ <2 RK_PA6 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m1_ch1_pins: pwm2m1-ch1-pins {
+ rockchip,pins =
+ /* pwm2m1_ch1 */
+ <2 RK_PA7 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m1_ch2_pins: pwm2m1-ch2-pins {
+ rockchip,pins =
+ /* pwm2m1_ch2 */
+ <2 RK_PB2 3 &pcfg_pull_none_drv_level_0>;
+ };
+ pwm2m1_ch3_pins: pwm2m1-ch3-pins {
+ rockchip,pins =
+ /* pwm2m1_ch3 */
+ <2 RK_PB3 3 &pcfg_pull_none_drv_level_0>;
+ };
+ };
+
+ pwr {
+ pwr_pins: pwr-pins {
+ rockchip,pins =
+ /* pwr_ctrl0 */
+ <0 RK_PA3 1 &pcfg_pull_none>,
+ /* pwr_ctrl1 */
+ <0 RK_PA4 1 &pcfg_pull_none>;
+ };
+ };
+
+ rtc_32k {
+ rtc_32k_pins: rtc-32k-pins {
+ rockchip,pins =
+ /* rtc_32k_out */
+ <0 RK_PA0 1 &pcfg_pull_none>;
+ };
+ };
+
+ sai {
+ sai_pins: sai-pins {
+ rockchip,pins =
+ /* sai_lrck */
+ <2 RK_PB1 5 &pcfg_pull_none>,
+ /* sai_mclk */
+ <2 RK_PB0 5 &pcfg_pull_none>,
+ /* sai_sclk */
+ <2 RK_PA7 5 &pcfg_pull_none>,
+ /* sai_sdi */
+ <2 RK_PA6 5 &pcfg_pull_none>,
+ /* sai_sdo */
+ <2 RK_PB2 5 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc0 {
+ sdmmc0_bus4_pins: sdmmc0-bus4-pins {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <1 RK_PB0 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d1 */
+ <1 RK_PA7 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d2 */
+ <1 RK_PB4 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d3 */
+ <1 RK_PB3 1 &pcfg_pull_up_drv_level_2>;
+ };
+ sdmmc0_clk_pins: sdmmc0-clk-pins {
+ rockchip,pins =
+ /* sdmmc0_clk */
+ <1 RK_PB1 1 &pcfg_pull_up_drv_level_2>;
+ };
+ sdmmc0_cmd_pins: sdmmc0-cmd-pins {
+ rockchip,pins =
+ /* sdmmc0_cmd */
+ <1 RK_PB2 1 &pcfg_pull_up_drv_level_2>;
+ };
+ sdmmc0_det_pins: sdmmc0-det-pins {
+ rockchip,pins =
+ /* sdmmc0_det */
+ <1 RK_PA6 1 &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc1 {
+ sdmmc1_bus4_pins: sdmmc1-bus4-pins {
+ rockchip,pins =
+ /* sdmmc1_d0 */
+ <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d1 */
+ <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d2 */
+ <2 RK_PA5 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d3 */
+ <2 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
+ };
+ sdmmc1_clk_pins: sdmmc1-clk-pins {
+ rockchip,pins =
+ /* sdmmc1_clk */
+ <2 RK_PA2 1 &pcfg_pull_up_drv_level_2>;
+ };
+ sdmmc1_cmd_pins: sdmmc1-cmd-pins {
+ rockchip,pins =
+ /* sdmmc1_cmd */
+ <2 RK_PA3 1 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ sdmmc0_testclk {
+ sdmmc0_testclk_clk_pins: sdmmc0-testclk-clk-pins {
+ rockchip,pins =
+ /* sdmmc0_testclk_out */
+ <1 RK_PA0 3 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ sdmmc0_testdata {
+ sdmmc0_testdata_out_pins: sdmmc0-testdata-out-pins {
+ rockchip,pins =
+ /* sdmmc0_testdata_out */
+ <1 RK_PA3 3 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc1_testclk {
+ sdmmc1_testclk_clk_pins: sdmmc1-testclk-clk-pins {
+ rockchip,pins =
+ /* sdmmc1_testclk_out */
+ <2 RK_PA6 7 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ sdmmc1_testdata {
+ sdmmc1_testdata_out_pins: sdmmc1-testdata-out-pins {
+ rockchip,pins =
+ /* sdmmc1_testdata_out */
+ <2 RK_PA7 7 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0m0_clk_pins: spi0m0-clk-pins {
+ rockchip,pins =
+ /* spi0_clk_m0 */
+ <2 RK_PB0 2 &pcfg_pull_none>,
+ /* spi0_miso_m0 */
+ <2 RK_PB3 2 &pcfg_pull_none>,
+ /* spi0_mosi_m0 */
+ <2 RK_PB1 2 &pcfg_pull_none>;
+ };
+ spi0m0_cs0_pins: spi0m0-cs0-pins {
+ rockchip,pins =
+ /* spi0_cs0n_m0 */
+ <2 RK_PB2 2 &pcfg_pull_none>;
+ };
+ spi0m0_cs1_pins: spi0m0-cs1-pins {
+ rockchip,pins =
+ /* spi0_cs1n_m0 */
+ <2 RK_PA7 2 &pcfg_pull_none>;
+ };
+ spi0m1_clk_pins: spi0m1-clk-pins {
+ rockchip,pins =
+ /* spi0_clk_m1 */
+ <2 RK_PA2 5 &pcfg_pull_none>,
+ /* spi0_miso_m1 */
+ <2 RK_PA4 5 &pcfg_pull_none>,
+ /* spi0_mosi_m1 */
+ <2 RK_PA1 5 &pcfg_pull_none>;
+ };
+ spi0m1_cs0_pins: spi0m1-cs0-pins {
+ rockchip,pins =
+ /* spi0_cs0n_m1 */
+ <2 RK_PA3 5 &pcfg_pull_none>;
+ };
+ spi0m1_cs1_pins: spi0m1-cs1-pins {
+ rockchip,pins =
+ /* spi0_cs1n_m1 */
+ <2 RK_PA0 5 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ uart0m0_xfer_pins: uart0m0-xfer-pins {
+ rockchip,pins =
+ /* uart0_rx_m0 */
+ <0 RK_PA6 1 &pcfg_pull_up>,
+ /* uart0_tx_m0 */
+ <0 RK_PA5 1 &pcfg_pull_up>;
+ };
+ uart0m1_xfer_pins: uart0m1-xfer-pins {
+ rockchip,pins =
+ /* uart0_rx_m1 */
+ <0 RK_PB5 2 &pcfg_pull_up>,
+ /* uart0_tx_m1 */
+ <0 RK_PB4 2 &pcfg_pull_up>;
+ };
+ uart0m2_xfer_pins: uart0m2-xfer-pins {
+ rockchip,pins =
+ /* uart0_rx_m2 */
+ <1 RK_PB3 2 &pcfg_pull_up>,
+ /* uart0_tx_m2 */
+ <1 RK_PB4 2 &pcfg_pull_up>;
+ };
+ };
+
+ uart1 {
+ uart1m0_xfer_pins: uart1m0-xfer-pins {
+ rockchip,pins =
+ /* uart1_rx_m0 */
+ <0 RK_PB2 2 &pcfg_pull_up>,
+ /* uart1_tx_m0 */
+ <0 RK_PB3 2 &pcfg_pull_up>;
+ };
+ uart1m0_ctsn_pins: uart1m0-ctsn-pins {
+ rockchip,pins =
+ /* uart1m0_ctsn */
+ <0 RK_PB5 5 &pcfg_pull_none>;
+ };
+ uart1m0_rtsn_pins: uart1m0-rtsn-pins {
+ rockchip,pins =
+ /* uart1m0_rtsn */
+ <0 RK_PB4 5 &pcfg_pull_none>;
+ };
+ uart1m1_xfer_pins: uart1m1-xfer-pins {
+ rockchip,pins =
+ /* uart1_rx_m1 */
+ <1 RK_PA7 2 &pcfg_pull_up>,
+ /* uart1_tx_m1 */
+ <1 RK_PB0 2 &pcfg_pull_up>;
+ };
+ uart1m1_ctsn_pins: uart1m1-ctsn-pins {
+ rockchip,pins =
+ /* uart1m1_ctsn */
+ <1 RK_PB2 2 &pcfg_pull_none>;
+ };
+ uart1m1_rtsn_pins: uart1m1-rtsn-pins {
+ rockchip,pins =
+ /* uart1m1_rtsn */
+ <1 RK_PB1 2 &pcfg_pull_none>;
+ };
+ uart1m2_xfer_pins: uart1m2-xfer-pins {
+ rockchip,pins =
+ /* uart1_rx_m2 */
+ <2 RK_PA7 1 &pcfg_pull_up>,
+ /* uart1_tx_m2 */
+ <2 RK_PA6 1 &pcfg_pull_up>;
+ };
+ uart1m2_ctsn_pins: uart1m2-ctsn-pins {
+ rockchip,pins =
+ /* uart1m2_ctsn */
+ <2 RK_PA5 2 &pcfg_pull_none>;
+ };
+ uart1m2_rtsn_pins: uart1m2-rtsn-pins {
+ rockchip,pins =
+ /* uart1m2_rtsn */
+ <2 RK_PA4 2 &pcfg_pull_none>;
+ };
+ uart1m3_xfer_pins: uart1m3-xfer-pins {
+ rockchip,pins =
+ /* uart1_rx_m3 */
+ <2 RK_PA3 2 &pcfg_pull_up>,
+ /* uart1_tx_m3 */
+ <2 RK_PA2 2 &pcfg_pull_up>;
+ };
+ uart1m3_ctsn_pins: uart1m3-ctsn-pins {
+ rockchip,pins =
+ /* uart1m3_ctsn */
+ <2 RK_PA1 2 &pcfg_pull_none>;
+ };
+ uart1m3_rtsn_pins: uart1m3-rtsn-pins {
+ rockchip,pins =
+ /* uart1m3_rtsn */
+ <2 RK_PA0 2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ uart2m0_xfer_pins: uart2m0-xfer-pins {
+ rockchip,pins =
+ /* uart2_rx_m0 */
+ <0 RK_PB1 2 &pcfg_pull_up>,
+ /* uart2_tx_m0 */
+ <0 RK_PB0 2 &pcfg_pull_up>;
+ };
+ uart2m0_ctsn_pins: uart2m0-ctsn-pins {
+ rockchip,pins =
+ /* uart2m0_ctsn */
+ <0 RK_PB3 5 &pcfg_pull_none>;
+ };
+ uart2m0_rtsn_pins: uart2m0-rtsn-pins {
+ rockchip,pins =
+ /* uart2m0_rtsn */
+ <0 RK_PB2 5 &pcfg_pull_none>;
+ };
+ uart2m1_xfer_pins: uart2m1-xfer-pins {
+ rockchip,pins =
+ /* uart2_rx_m1 */
+ <2 RK_PB1 1 &pcfg_pull_up>,
+ /* uart2_tx_m1 */
+ <2 RK_PB0 1 &pcfg_pull_up>;
+ };
+ uart2m1_ctsn_pins: uart2m1-ctsn-pins {
+ rockchip,pins =
+ /* uart2m1_ctsn */
+ <2 RK_PB3 1 &pcfg_pull_none>;
+ };
+ uart2m1_rtsn_pins: uart2m1-rtsn-pins {
+ rockchip,pins =
+ /* uart2m1_rtsn */
+ <2 RK_PB2 1 &pcfg_pull_none>;
+ };
+ uart2m2_xfer_pins: uart2m2-xfer-pins {
+ rockchip,pins =
+ /* uart2_rx_m2 */
+ <1 RK_PB6 3 &pcfg_pull_up>,
+ /* uart2_tx_m2 */
+ <1 RK_PB5 3 &pcfg_pull_up>;
+ };
+ uart2m2_ctsn_pins: uart2m2-ctsn-pins {
+ rockchip,pins =
+ /* uart2m2_ctsn */
+ <1 RK_PC0 3 &pcfg_pull_none>;
+ };
+ uart2m2_rtsn_pins: uart2m2-rtsn-pins {
+ rockchip,pins =
+ /* uart2m2_rtsn */
+ <1 RK_PB7 3 &pcfg_pull_none>;
+ };
+ };
+};
+
+&pinctrl {
+ sdmmc0 {
+ sdmmc0_clk_idle_pins: sdmmc0-clk-idle-pins {
+ rockchip,pins =
+ /* sdmmc0_clk */
+ <1 RK_PB1 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ sdmmc0_cmd_idle_pins: sdmmc0-cmd-idle-pins {
+ rockchip,pins =
+ /* sdmmc0_cmd */
+ <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ sdmmc0_bus1_pins: sdmmc0-bus1-pins {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <1 RK_PB0 1 &pcfg_pull_up_drv_level_2>;
+ };
+ sdmmc0_bus1_idle_pins: sdmmc0-bus1-idle-pins {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ sdmmc0_bus4_idle_pins: sdmmc0-bus4-idle-pins {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>,
+ /* sdmmc0_d1 */
+ <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>,
+ /* sdmmc0_d2 */
+ <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>,
+ /* sdmmc0_d3 */
+ <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ sdmmc1 {
+ sdmmc1_bus1_pins: sdmmc1-bus1-pins {
+ rockchip,pins =
+ /* sdmmc1_d0 */
+ <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rv1103b-u-boot.dtsi b/arch/arm/dts/rv1103b-u-boot.dtsi
new file mode 100644
index 000000000000..3b77dd31152f
--- /dev/null
+++ b/arch/arm/dts/rv1103b-u-boot.dtsi
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+// (C) Copyright 2024 Rockchip Electronics Co., Ltd
+
+#include "rockchip-u-boot.dtsi"
diff --git a/arch/arm/dts/rv1103b.dtsi b/arch/arm/dts/rv1103b.dtsi
new file mode 100644
index 000000000000..5c850aa56de7
--- /dev/null
+++ b/arch/arm/dts/rv1103b.dtsi
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/clock/rockchip,rv1103b-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "rockchip,rv1103b";
+
+ interrupt-parent = <&gic>;
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>;
+ };
+
+ xin32k: oscillator-32k {
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "xin32k";
+ #clock-cells = <0>;
+ };
+
+ xin24m: oscillator-24m {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ clocks = <&cru ARMCLK>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rv1103b-cru";
+ reg = <0x20000000 0x81000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ bootph-all;
+ assigned-clocks = <&cru PLL_GPLL>, <&cru CLK_GPLL_DIV12>;
+ assigned-clock-rates = <1188000000>, <100000000>;
+ };
+
+ /*
+ * Merge all GRF, each independent GRF offset is shown as bellow:
+ * VEPU_GRF: 0x20100000
+ * NPU_GRF: 0x20110000
+ * VI_GRF: 0x20120000
+ * CPU_GRF: 0x20130000
+ * DDR_GRF: 0x20140000
+ * SYS_GRF: 0x20150000
+ * PMU_GRF: 0x20160000
+ */
+ grf: syscon@20100000 {
+ compatible = "rockchip,rv1103b-grf", "syscon", "simple-mfd";
+ reg = <0x20100000 0x61000>;
+
+ reboot_mode: reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x60200>;
+ };
+ };
+
+ ioc: syscon@20170000 {
+ compatible = "rockchip,rv1103b-ioc", "syscon";
+ reg = <0x20170000 0x60000>;
+ };
+
+ gic: interrupt-controller@20411000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0x20411000 0x1000>,
+ <0x20412000 0x2000>,
+ <0x20414000 0x2000>,
+ <0x20416000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ uart0: serial@20540000 {
+ compatible = "rockchip,rv1103b-uart", "snps,dw-apb-uart";
+ reg = <0x20540000 0x100>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0m0_xfer_pins>;
+ status = "disabled";
+ };
+
+ sdmmc1: mmc@20650000 {
+ compatible = "rockchip,rv1103b-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x20650000 0x4000>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC1>, <&cru CCLK_SDMMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ max-frequency = <150000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_clk_pins &sdmmc1_cmd_pins &sdmmc1_bus4_pins>;
+ status = "disabled";
+ };
+
+ uart1: serial@20870000 {
+ compatible = "rockchip,rv1103b-uart", "snps,dw-apb-uart";
+ reg = <0x20870000 0x100>;
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_xfer_pins>;
+ status = "disabled";
+ };
+
+ uart2: serial@20880000 {
+ compatible = "rockchip,rv1103b-uart", "snps,dw-apb-uart";
+ reg = <0x20880000 0x100>;
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2m0_xfer_pins>;
+ status = "disabled";
+ };
+
+ wdt: watchdog@208d0000 {
+ compatible = "snps,dw-wdt";
+ reg = <0x208d0000 0x100>;
+ clocks = <&cru TCLK_WDT_NS>, <&cru PCLK_WDT_NS>;
+ clock-names = "tclk", "pclk";
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ status = "disabled";
+ };
+
+ sdmmc0: mmc@20d20000 {
+ compatible = "rockchip,rv1103b-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x20d20000 0x4000>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC0>, <&cru CCLK_SDMMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ max-frequency = <150000000>;
+ pinctrl-names = "normal", "idle";
+ pinctrl-0 = <&sdmmc0_det_pins
+ &sdmmc0_clk_pins
+ &sdmmc0_cmd_pins
+ &sdmmc0_bus4_pins>;
+ pinctrl-1 = <&sdmmc0_det_pins
+ &sdmmc0_clk_idle_pins
+ &sdmmc0_cmd_idle_pins
+ &sdmmc0_bus4_idle_pins>;
+ status = "disabled";
+ };
+
+ emmc: mmc@20d30000 {
+ compatible = "rockchip,rv1103b-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0x20d30000 0x4000>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru CCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ max-frequency = <150000000>;
+ status = "disabled";
+ };
+
+ fspi0: spi@20d40000 {
+ compatible = "rockchip,sfc";
+ reg = <0x20d40000 0x4000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_SFC_2X>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ system_sram: sram@210f6000 {
+ compatible = "mmio-sram";
+ reg = <0x210f6000 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x210f6000 0x8000>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rv1103b-pinctrl";
+ rockchip,grf = <&ioc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio@20520000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20520000 0x200>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_PMU_GPIO0>, <&cru DBCLK_PMU_GPIO0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 0 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@20d80000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20d80000 0x200>;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 32 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@20840000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20840000 0x200>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 64 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+};
+
+#include "rv1103b-pinctrl.dtsi"
diff --git a/include/dt-bindings/clock/rockchip,rv1103b-cru.h b/include/dt-bindings/clock/rockchip,rv1103b-cru.h
new file mode 100644
index 000000000000..35afdee7e961
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rv1103b-cru.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co. Ltd.
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1103B_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1103B_H
+
+#define PLL_GPLL 0
+#define ARMCLK 1
+#define PLL_DPLL 2
+#define XIN_OSC0_HALF 3
+#define CLK_GPLL_DIV24 4
+#define CLK_GPLL_DIV12 5
+#define CLK_GPLL_DIV6 6
+#define CLK_GPLL_DIV4 7
+#define CLK_GPLL_DIV3 8
+#define CLK_GPLL_DIV2P5 9
+#define CLK_GPLL_DIV2 10
+#define CLK_UART0_SRC 11
+#define CLK_UART1_SRC 12
+#define CLK_UART2_SRC 13
+#define CLK_UART0_FRAC 14
+#define CLK_UART1_FRAC 15
+#define CLK_UART2_FRAC 16
+#define CLK_SAI_SRC 17
+#define CLK_SAI_FRAC 18
+#define LSCLK_NPU_SRC 19
+#define CLK_NPU_SRC 20
+#define ACLK_VEPU_SRC 21
+#define CLK_VEPU_SRC 22
+#define ACLK_VI_SRC 23
+#define CLK_ISP_SRC 24
+#define DCLK_VICAP 25
+#define CCLK_EMMC 26
+#define CCLK_SDMMC0 27
+#define SCLK_SFC_2X 28
+#define LSCLK_PERI_SRC 29
+#define ACLK_PERI_SRC 30
+#define HCLK_HPMCU 31
+#define SCLK_UART0 32
+#define SCLK_UART1 33
+#define SCLK_UART2 34
+#define CLK_I2C_PMU 35
+#define CLK_I2C_PERI 36
+#define CLK_SPI0 37
+#define CLK_PWM0_SRC 38
+#define CLK_PWM1 39
+#define CLK_PWM2 40
+#define DCLK_DECOM_SRC 41
+#define CCLK_SDMMC1 42
+#define CLK_CORE_CRYPTO 43
+#define CLK_PKA_CRYPTO 44
+#define CLK_CORE_RGA 45
+#define MCLK_SAI_SRC 46
+#define CLK_FREQ_PWM0_SRC 47
+#define CLK_COUNTER_PWM0_SRC 48
+#define PCLK_TOP_ROOT 49
+#define CLK_REF_MIPI0 50
+#define CLK_MIPI0_OUT2IO 51
+#define CLK_REF_MIPI1 52
+#define CLK_MIPI1_OUT2IO 53
+#define MCLK_SAI_OUT2IO 54
+#define ACLK_NPU_ROOT 55
+#define HCLK_RKNN 56
+#define ACLK_RKNN 57
+#define LSCLK_VEPU_ROOT 58
+#define HCLK_VEPU 59
+#define ACLK_VEPU 60
+#define CLK_CORE_VEPU 61
+#define PCLK_IOC_VCCIO3 62
+#define PCLK_ACODEC 63
+#define PCLK_USBPHY 64
+#define LSCLK_VI_100M 65
+#define LSCLK_VI_ROOT 66
+#define HCLK_ISP 67
+#define ACLK_ISP 68
+#define CLK_CORE_ISP 69
+#define ACLK_VICAP 70
+#define HCLK_VICAP 71
+#define ISP0CLK_VICAP 72
+#define PCLK_CSI2HOST0 73
+#define PCLK_CSI2HOST1 74
+#define HCLK_EMMC 75
+#define HCLK_SFC 76
+#define HCLK_SFC_XIP 77
+#define HCLK_SDMMC0 78
+#define PCLK_CSIPHY 79
+#define PCLK_GPIO1 80
+#define DBCLK_GPIO1 81
+#define PCLK_IOC_VCCIO47 82
+#define LSCLK_DDR_ROOT 83
+#define CLK_TIMER_DDRMON 84
+#define LSCLK_PMU_ROOT 85
+#define PCLK_PMU 86
+#define XIN_RC_DIV 87
+#define CLK_32K 88
+#define PCLK_PMU_GPIO0 89
+#define DBCLK_PMU_GPIO0 90
+#define CLK_DDR_FAIL_SAFE 91
+#define PCLK_PMU_HP_TIMER 92
+#define CLK_PMU_32K_HP_TIMER 93
+#define PCLK_PWM0 94
+#define CLK_PWM0 95
+#define CLK_OSC_PWM0 96
+#define CLK_RC_PWM0 97
+#define CLK_FREQ_PWM0 98
+#define CLK_COUNTER_PWM0 99
+#define PCLK_I2C0 100
+#define CLK_I2C0 101
+#define PCLK_UART0 102
+#define PCLK_IOC_PMUIO0 103
+#define CLK_REFOUT 104
+#define CLK_PREROLL 105
+#define CLK_PREROLL_32K 106
+#define CLK_LPMCU_PMU 107
+#define PCLK_SPI2AHB 108
+#define HCLK_SPI2AHB 109
+#define SCLK_SPI2AHB 110
+#define PCLK_WDT_LPMCU 111
+#define TCLK_WDT_LPMCU 112
+#define HCLK_SFC_PMU1 113
+#define HCLK_SFC_XIP_PMU1 114
+#define SCLK_SFC_2X_PMU1 115
+#define CLK_LPMCU 116
+#define CLK_LPMCU_RTC 117
+#define PCLK_LPMCU_MAILBOX 118
+#define PCLK_IOC_PMUIO1 119
+#define PCLK_CRU_PMU1 120
+#define PCLK_PERI_ROOT 121
+#define PCLK_RTC_ROOT 122
+#define CLK_TIMER_ROOT 123
+#define PCLK_TIMER 124
+#define CLK_TIMER0 125
+#define CLK_TIMER1 126
+#define CLK_TIMER2 127
+#define CLK_TIMER3 128
+#define CLK_TIMER4 129
+#define CLK_TIMER5 130
+#define PCLK_STIMER 131
+#define CLK_STIMER0 132
+#define CLK_STIMER1 133
+#define PCLK_WDT_NS 134
+#define TCLK_WDT_NS 135
+#define PCLK_WDT_S 136
+#define TCLK_WDT_S 137
+#define PCLK_WDT_HPMCU 138
+#define TCLK_WDT_HPMCU 139
+#define PCLK_I2C1 140
+#define CLK_I2C1 141
+#define PCLK_I2C2 142
+#define CLK_I2C2 143
+#define PCLK_I2C3 144
+#define CLK_I2C3 145
+#define PCLK_I2C4 146
+#define CLK_I2C4 147
+#define PCLK_SPI0 148
+#define PCLK_PWM1 149
+#define CLK_OSC_PWM1 150
+#define PCLK_PWM2 151
+#define CLK_OSC_PWM2 152
+#define PCLK_UART2 153
+#define PCLK_UART1 154
+#define ACLK_RKDMA 155
+#define PCLK_TSADC 156
+#define CLK_TSADC 157
+#define CLK_TSADC_TSEN 158
+#define PCLK_SARADC 159
+#define CLK_SARADC 160
+#define PCLK_GPIO2 161
+#define DBCLK_GPIO2 162
+#define PCLK_IOC_VCCIO6 163
+#define ACLK_USBOTG 164
+#define CLK_REF_USBOTG 165
+#define HCLK_SDMMC1 166
+#define HCLK_SAI 167
+#define MCLK_SAI 168
+#define ACLK_CRYPTO 169
+#define HCLK_CRYPTO 170
+#define HCLK_RK_RNG_NS 171
+#define HCLK_RK_RNG_S 172
+#define PCLK_OTPC_NS 173
+#define CLK_OTPC_ROOT_NS 174
+#define CLK_SBPI_OTPC_NS 175
+#define CLK_USER_OTPC_NS 176
+#define PCLK_OTPC_S 177
+#define CLK_OTPC_ROOT_S 178
+#define CLK_SBPI_OTPC_S 179
+#define CLK_USER_OTPC_S 180
+#define CLK_OTPC_ARB 181
+#define PCLK_OTP_MASK 182
+#define HCLK_RGA 183
+#define ACLK_RGA 184
+#define ACLK_MAC 185
+#define PCLK_MAC 186
+#define CLK_MACPHY 187
+#define ACLK_SPINLOCK 188
+#define HCLK_CACHE 189
+#define PCLK_HPMCU_MAILBOX 190
+#define PCLK_HPMCU_INTMUX 191
+#define CLK_HPMCU 192
+#define CLK_HPMCU_RTC 193
+#define DCLK_DECOM 194
+#define ACLK_DECOM 195
+#define PCLK_DECOM 196
+#define ACLK_SYS_SRAM 197
+#define PCLK_DMA2DDR 198
+#define ACLK_DMA2DDR 199
+#define PCLK_DCF 200
+#define ACLK_DCF 201
+#define MCLK_ACODEC_TX 202
+#define SCLK_UART0_SRC 203
+#define SCLK_UART1_SRC 204
+#define SCLK_UART2_SRC 205
+#define XIN_RC_SRC 206
+#define CLK_UTMI_USBOTG 207
+#define CLK_REF_USBPHY 208
+
+#endif // _DT_BINDINGS_CLK_ROCKCHIP_RV1103B_H
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/7] pinctrl: rockchip: Add RV1103B support
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
2026-02-09 10:50 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 3/7] clk: rockchip: Add RV1103B clock driver Fabio Estevam
` (4 subsequent siblings)
6 siblings, 1 reply; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Ye Zhang, Fabio Estevam
From: Ye Zhang <ye.zhang@rock-chips.com>
Add pinctrl driver for RV1103.
Signed-off-by: Ye Zhang <ye.zhang@rock-chips.com>
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- Use the original author from Rockchip's vendor U-Boot tree.
- Use regmap_update_bits()
- Removed unneeded blank lines.
- Removed unneeded logging functions.
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl-rv1103b.c | 398 +++++++++++++++++++++
2 files changed, 399 insertions(+)
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1103b.c
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index e17415e1ca68..2bbee66bd3ca 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_ROCKCHIP_RK3528) += pinctrl-rk3528.o
obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
obj-$(CONFIG_ROCKCHIP_RK3576) += pinctrl-rk3576.o
obj-$(CONFIG_ROCKCHIP_RK3588) += pinctrl-rk3588.o
+obj-$(CONFIG_ROCKCHIP_RV1103B) += pinctrl-rv1103b.o
obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1103b.c b/drivers/pinctrl/rockchip/pinctrl-rv1103b.c
new file mode 100644
index 000000000000..fb946b036661
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rv1103b.c
@@ -0,0 +1,398 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2024 Rockchip Electronics Co., Ltd
+ */
+
+#include <dm.h>
+#include <log.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+
+#include "pinctrl-rockchip.h"
+
+static int rv1103b_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+ int iomux_num = (pin / 8);
+ struct regmap *regmap;
+ u32 data, rmask;
+ int reg, mask;
+ u8 bit;
+
+ if (bank->bank_num == 2 && pin >= 12)
+ return 0;
+
+ regmap = priv->regmap_base;
+ reg = bank->iomux[iomux_num].offset;
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ mask = 0xf;
+
+ if (bank->recalced_mask & BIT(pin))
+ rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask);
+ data = (mask << (bit + 16));
+ rmask = data | (data >> 16);
+ data |= (mux & mask) << bit;
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+}
+
+#define RV1103_DRV_BITS_PER_PIN 8
+#define RV1103_DRV_PINS_PER_REG 2
+#define RV1103_DRV_GPIO0_A_OFFSET 0x40100
+#define RV1103_DRV_GPIO0_B_OFFSET 0x50110
+#define RV1103_DRV_GPIO1_A01_OFFSET 0x140
+#define RV1103_DRV_GPIO1_A67_OFFSET 0x1014C
+#define RV1103_DRV_GPIO2_OFFSET 0x30180
+#define RV1103_DRV_GPIO2_SARADC_OFFSET 0x3080C
+
+static int rv1103b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+ int ret = 0;
+
+ *regmap = priv->regmap_base;
+ switch (bank->bank_num) {
+ case 0:
+ if (pin_num < 7)
+ *reg = RV1103_DRV_GPIO0_A_OFFSET;
+ else if (pin_num > 7 && pin_num < 14)
+ *reg = RV1103_DRV_GPIO0_B_OFFSET - 0x10;
+ else
+ ret = -EINVAL;
+ break;
+
+ case 1:
+ if (pin_num < 6)
+ *reg = RV1103_DRV_GPIO1_A01_OFFSET;
+ else if (pin_num >= 6 && pin_num < 23)
+ *reg = RV1103_DRV_GPIO1_A67_OFFSET - 0xc;
+ else if (pin_num >= 24 && pin_num < 30)
+ *reg = RV1103_DRV_GPIO1_A67_OFFSET - 0xc;
+ else
+ ret = -EINVAL;
+ break;
+
+ case 2:
+ if (pin_num < 12) {
+ *reg = RV1103_DRV_GPIO2_OFFSET;
+ } else if (pin_num >= 16) {
+ ret = -EINVAL;
+ } else {
+ *reg = RV1103_DRV_GPIO2_SARADC_OFFSET;
+ *bit = 10;
+
+ return 0;
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret) {
+ printf("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+ return ret;
+ }
+
+ *reg += ((pin_num / RV1103_DRV_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1103_DRV_PINS_PER_REG;
+ *bit *= RV1103_DRV_BITS_PER_PIN;
+
+ return 0;
+}
+
+static int rv1103b_set_drive(struct rockchip_pin_bank *bank,
+ int pin_num, int strength)
+{
+ struct regmap *regmap;
+ int reg, ret, i;
+ u32 data;
+ u8 bit;
+ int rmask_bits = RV1103_DRV_BITS_PER_PIN;
+
+ ret = rv1103b_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ if (ret)
+ return ret;
+
+ for (i = 0, ret = 1; i < strength; i++)
+ ret = (ret << 1) | 1;
+
+ if (bank->bank_num == 2 && pin_num >= 12) {
+ rmask_bits = 2;
+ ret = strength;
+ }
+
+ /* Enable the write to the equivalent lower bits */
+ data = ((1 << rmask_bits) - 1) << (bit + 16);
+ data |= (ret << bit);
+ return regmap_write(regmap, reg, data);
+}
+
+#define RV1103_PULL_BITS_PER_PIN 2
+#define RV1103_PULL_PINS_PER_REG 8
+#define RV1103_PULL_GPIO0_A_OFFSET 0x40200
+#define RV1103_PULL_GPIO0_B_OFFSET 0x50204
+#define RV1103_PULL_GPIO1_A01_OFFSET 0x210
+#define RV1103_PULL_GPIO1_A67_OFFSET 0x10210
+#define RV1103_PULL_GPIO2_OFFSET 0x30220
+#define RV1103_PULL_GPIO2_SARADC_OFFSET 0x3080C
+
+static int rv1103b_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+ int ret = 0;
+
+ *regmap = priv->regmap_base;
+ switch (bank->bank_num) {
+ case 0:
+ if (pin_num < 7)
+ *reg = RV1103_PULL_GPIO0_A_OFFSET;
+ else if (pin_num > 7 && pin_num < 14)
+ *reg = RV1103_PULL_GPIO0_B_OFFSET - 0x4;
+ else
+ ret = -EINVAL;
+ break;
+
+ case 1:
+ if (pin_num < 6)
+ *reg = RV1103_PULL_GPIO1_A01_OFFSET;
+ else if (pin_num >= 6 && pin_num < 23)
+ *reg = RV1103_PULL_GPIO1_A67_OFFSET;
+ else if (pin_num >= 24 && pin_num < 30)
+ *reg = RV1103_PULL_GPIO1_A67_OFFSET;
+ else
+ ret = -EINVAL;
+ break;
+
+ case 2:
+ if (pin_num < 12) {
+ *reg = RV1103_PULL_GPIO2_OFFSET;
+ } else if (pin_num >= 16) {
+ ret = -EINVAL;
+ } else {
+ *reg = RV1103_PULL_GPIO2_SARADC_OFFSET;
+ *bit = 13;
+
+ return 0;
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret) {
+ printf("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+ return ret;
+ }
+
+ *reg += ((pin_num / RV1103_PULL_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1103_PULL_PINS_PER_REG;
+ *bit *= RV1103_PULL_BITS_PER_PIN;
+
+ return 0;
+}
+
+static int rv1103b_set_pull(struct rockchip_pin_bank *bank,
+ int pin_num, int pull)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u8 bit, type;
+ u32 data;
+
+ if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+ return -EINVAL;
+
+ ret = rv1103b_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ if (ret)
+ return ret;
+ type = bank->pull_type[pin_num / 8];
+
+ if (bank->bank_num == 2 && pin_num >= 12)
+ type = 1;
+
+ ret = rockchip_translate_pull_value(type, pull);
+ if (ret < 0) {
+ debug("unsupported pull setting %d\n", pull);
+ return ret;
+ }
+
+ /* Enable the write to the equivalent lower bits */
+ data = ((1 << RV1103_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+
+ data |= (ret << bit);
+ ret = regmap_write(regmap, reg, data);
+
+ return ret;
+}
+
+#define RV1103_SMT_BITS_PER_PIN 1
+#define RV1103_SMT_PINS_PER_REG 8
+#define RV1103_SMT_GPIO0_A_OFFSET 0x40400
+#define RV1103_SMT_GPIO0_B_OFFSET 0x50404
+#define RV1103_SMT_GPIO1_A01_OFFSET 0x410
+#define RV1103_SMT_GPIO1_A67_OFFSET 0x10410
+#define RV1103_SMT_GPIO2_OFFSET 0x30420
+#define RV1103_SMT_GPIO2_SARADC_OFFSET 0x3080C
+
+static int rv1103b_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num,
+ struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+ int ret = 0;
+
+ *regmap = priv->regmap_base;
+ switch (bank->bank_num) {
+ case 0:
+ if (pin_num < 7)
+ *reg = RV1103_SMT_GPIO0_A_OFFSET;
+ else if (pin_num > 7 && pin_num < 14)
+ *reg = RV1103_SMT_GPIO0_B_OFFSET - 0x4;
+ else
+ ret = -EINVAL;
+ break;
+
+ case 1:
+ if (pin_num < 6)
+ *reg = RV1103_SMT_GPIO1_A01_OFFSET;
+ else if (pin_num >= 6 && pin_num < 23)
+ *reg = RV1103_SMT_GPIO1_A67_OFFSET;
+ else if (pin_num >= 24 && pin_num < 30)
+ *reg = RV1103_SMT_GPIO1_A67_OFFSET;
+ else
+ ret = -EINVAL;
+ break;
+
+ case 2:
+ if (pin_num < 12) {
+ *reg = RV1103_SMT_GPIO2_OFFSET;
+ } else if (pin_num >= 16) {
+ ret = -EINVAL;
+ } else {
+ *reg = RV1103_SMT_GPIO2_SARADC_OFFSET;
+ *bit = 8;
+
+ return 0;
+ }
+ break;
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret) {
+ printf("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
+ return ret;
+ }
+
+ *reg += ((pin_num / RV1103_SMT_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1103_SMT_PINS_PER_REG;
+ *bit *= RV1103_SMT_BITS_PER_PIN;
+
+ return 0;
+}
+
+static int rv1103b_set_schmitt(struct rockchip_pin_bank *bank,
+ int pin_num, int enable)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u32 data;
+ u8 bit;
+
+ ret = rv1103b_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ if (ret)
+ return ret;
+
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << RV1103_SMT_BITS_PER_PIN) - 1) << (bit + 16);
+ data |= (enable << bit);
+
+ if (bank->bank_num == 2 && pin_num >= 12) {
+ data = 0x3 << (bit + 16);
+ data |= ((enable ? 0x3 : 0) << bit);
+ }
+ return regmap_write(regmap, reg, data);
+}
+
+static struct rockchip_mux_recalced_data rv1103b_mux_recalced_data[] = {
+ {
+ .num = 1,
+ .pin = 6,
+ .reg = 0x10024,
+ .bit = 8,
+ .mask = 0xf
+ }, {
+ .num = 1,
+ .pin = 7,
+ .reg = 0x10024,
+ .bit = 12,
+ .mask = 0xf
+ },
+};
+
+static struct rockchip_pin_bank rv1103b_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0x40000, 0x50008, 0x50010, 0x50018),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0x20, 0x10028, 0x10030, 0x10038),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0x30040, 0x30048, 0x30050, 0x30058),
+};
+
+static const struct rockchip_pin_ctrl rv1103b_pin_ctrl = {
+ .pin_banks = rv1103b_pin_banks,
+ .nr_banks = ARRAY_SIZE(rv1103b_pin_banks),
+ .iomux_recalced = rv1103b_mux_recalced_data,
+ .niomux_recalced = ARRAY_SIZE(rv1103b_mux_recalced_data),
+ .set_mux = rv1103b_set_mux,
+ .set_pull = rv1103b_set_pull,
+ .set_drive = rv1103b_set_drive,
+ .set_schmitt = rv1103b_set_schmitt,
+};
+
+static const struct udevice_id rv1103b_pinctrl_ids[] = {
+ {
+ .compatible = "rockchip,rv1103b-pinctrl",
+ .data = (ulong)&rv1103b_pin_ctrl
+ },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rv1103b) = {
+ .name = "rockchip_rv1103b_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = rv1103b_pinctrl_ids,
+ .priv_auto = sizeof(struct rockchip_pinctrl_priv),
+ .ops = &rockchip_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .bind = dm_scan_fdt_dev,
+#endif
+ .probe = rockchip_pinctrl_probe,
+};
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/7] clk: rockchip: Add RV1103B clock driver
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 2/7] pinctrl: rockchip: Add RV1103B support Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 4/7] tools: rkcommon: Add RV1103B support Fabio Estevam
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Elaine Zhang, Fabio Estevam
From: Elaine Zhang <zhangqing@rock-chips.com>
Add basic clock for the RV1103B clock driver.
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- Use the original author from Rockchip's vendor U-Boot tree.
.../include/asm/arch-rockchip/cru_rv1103b.h | 266 ++++
.../include/asm/arch-rockchip/grf_rv1103b.h | 31 +
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk_rv1103b.c | 1068 +++++++++++++++++
4 files changed, 1366 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rv1103b.h
create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rv1103b.h
create mode 100644 drivers/clk/rockchip/clk_rv1103b.c
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1103b.h b/arch/arm/include/asm/arch-rockchip/cru_rv1103b.h
new file mode 100644
index 000000000000..fc7aa4dfc0db
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1103b.h
@@ -0,0 +1,266 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co. Ltd.
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#ifndef _ASM_ARCH_CRU_RV1103B_H
+#define _ASM_ARCH_CRU_RV1103B_H
+
+#define MHz 1000000
+#define KHz 1000
+#define OSC_HZ (24 * MHz)
+#define RC_OSC_HZ (125 * MHz)
+
+#define GPLL_HZ (1188 * MHz)
+
+/* RV1103B pll id */
+enum rv1103b_pll_id {
+ GPLL,
+ PLL_COUNT,
+};
+
+struct rv1103b_clk_info {
+ unsigned long id;
+ char *name;
+ bool is_cru;
+};
+
+struct rv1103b_clk_priv {
+ struct rv1103b_cru *cru;
+ struct rv1103b_grf *grf;
+ ulong gpll_hz;
+ ulong armclk_hz;
+ ulong armclk_enter_hz;
+ ulong armclk_init_hz;
+ bool sync_kernel;
+ bool set_armclk_rate;
+};
+
+struct rv1103b_grf_clk_priv {
+ struct rv1103b_grf *grf;
+};
+
+struct rv1103b_pll {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ unsigned int con4;
+ unsigned int reserved0[3];
+};
+
+struct rv1103b_cru {
+ unsigned int reserved0[192];
+ unsigned int peri_clksel_con[4];
+ unsigned int reserved1[316];
+ unsigned int peri_clkgate_con[12];
+ unsigned int reserved2[116];
+ unsigned int peri_softrst_con[12];
+ unsigned int reserved3[15924];
+ unsigned int vepu_clksel_con[3];
+ unsigned int reserved4[317];
+ unsigned int vepu_clkgate_con[1];
+ unsigned int reserved5[127];
+ unsigned int vepu_softrst_con[1];
+ unsigned int reserved6[15935];
+ unsigned int npu_clksel_con[3];
+ unsigned int reserved7[317];
+ unsigned int npu_clkgate_con[1];
+ unsigned int reserved8[127];
+ unsigned int npu_softrst_con[1];
+ unsigned int reserved9[15935];
+ unsigned int vi_clksel_con[1];
+ unsigned int reserved10[319];
+ unsigned int vi_clkgate_con[3];
+ unsigned int reserved11[125];
+ unsigned int vi_softrst_con[3];
+ unsigned int reserved12[15933];
+ unsigned int core_clksel_con[3];
+ unsigned int reserved13[16381];
+ unsigned int ddr_clksel_con[1];
+ unsigned int reserved14[16207];
+ struct rv1103b_pll pll[2];
+ unsigned int reserved15[128];
+ unsigned int mode;
+ unsigned int reserved16[31];
+ unsigned int clksel_con[42];
+ unsigned int reserved17[278];
+ unsigned int clkgate_con[7];
+ unsigned int reserved18[121];
+ unsigned int softrst_con[1];
+ unsigned int reserved19[127];
+ unsigned int glb_cnt_th;
+ unsigned int glb_rst_st;
+ unsigned int glb_srst_fst;
+ unsigned int glb_srst_snd;
+ unsigned int glb_rst_con;
+ unsigned int reserved20[15803];
+ unsigned int pmu_clksel_con[3];
+ unsigned int reserved21[317];
+ unsigned int pmu_clkgate_con[3];
+ unsigned int reserved22[125];
+ unsigned int pmu_softrst_con[3];
+ unsigned int reserved23[15933];
+ unsigned int pmu1_clksel_con[1];
+ unsigned int reserved24[319];
+ unsigned int pmu1_clkgate_con[2];
+ unsigned int reserved25[126];
+ unsigned int pmu1_softrst_con[2];
+};
+
+check_member(rv1103b_cru, pmu1_softrst_con[1], 0x80a04);
+
+struct pll_rate_table {
+ unsigned long rate;
+ unsigned int fbdiv;
+ unsigned int postdiv1;
+ unsigned int refdiv;
+ unsigned int postdiv2;
+ unsigned int dsmpd;
+ unsigned int frac;
+};
+
+#define RV1103B_TOPCRU_BASE 0x60000
+#define RV1103B_PERICRU_BASE 0x0
+#define RV1103B_VICRU_BASE 0x30000
+#define RV1103B_NPUCRU_BASE 0x20000
+#define RV1103B_CORECRU_BASE 0x40000
+#define RV1103B_VEPUCRU_BASE 0x10000
+#define RV1103B_DDRCRU_BASE 0x50000
+#define RV1103B_SUBDDRCRU_BASE 0x58000
+#define RV1103B_PMUCRU_BASE 0x70000
+#define RV1103B_PMU1CRU_BASE 0x80000
+
+#define RV1103B_CRU_BASE 0x20000000
+
+#define RV1103B_PLL_CON(x) ((x) * 0x4 + RV1103B_TOPCRU_BASE)
+#define RV1103B_MODE_CON (0x280 + RV1103B_TOPCRU_BASE)
+#define RV1103B_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1103B_TOPCRU_BASE)
+#define RV1103B_SUBDDRMODE_CON (0x280 + RV1103B_SUBDDRCRU_BASE)
+
+enum {
+ /* CORECRU_CLK_SEL0_CON */
+ CLK_CORE_SRC_SEL_SHIFT = 1,
+ CLK_CORE_SRC_SEL_MASK = 0x1 << CLK_CORE_SRC_SEL_SHIFT,
+ CLK_CORE_SRC_SEL_GPLL = 0,
+ CLK_CORE_SRC_SEL_PVTPLL,
+
+ /* CRU_PERI_CLK_SEL0_CON */
+ CLK_TSADC_TSEN_DIV_SHIFT = 10,
+ CLK_TSADC_TSEN_DIV_MASK = 0x1f << CLK_TSADC_TSEN_DIV_SHIFT,
+ CLK_TSADC_DIV_SHIFT = 4,
+ CLK_TSADC_DIV_MASK = 0x1f << CLK_TSADC_DIV_SHIFT,
+ PCLK_PERI_DIV_SHIFT = 0,
+ PCLK_PERI_DIV_MASK = 0x3 << PCLK_PERI_DIV_SHIFT,
+
+ /* CRU_PERI_CLK_SEL1_CON */
+ CLK_SARADC_DIV_SHIFT = 0,
+ CLK_SARADC_DIV_MASK = 0x7 << CLK_SARADC_DIV_SHIFT,
+
+ /* CRU_CLK_SEL5_CON */
+ CLK_UART2_SRC_DIV_SHIFT = 10,
+ CLK_UART2_SRC_DIV_MASK = 0x1f << CLK_UART2_SRC_DIV_SHIFT,
+ CLK_UART1_SRC_DIV_SHIFT = 5,
+ CLK_UART1_SRC_DIV_MASK = 0x1f << CLK_UART1_SRC_DIV_SHIFT,
+ CLK_UART0_SRC_DIV_SHIFT = 0,
+ CLK_UART0_SRC_DIV_MASK = 0x1f << CLK_UART0_SRC_DIV_SHIFT,
+
+ /* CRU_CLK_SEL10_CON */
+ CLK_UART_FRAC_NUMERATOR_SHIFT = 16,
+ CLK_UART_FRAC_NUMERATOR_MASK = 0xffff << 16,
+ CLK_UART_FRAC_DENOMINATOR_SHIFT = 0,
+ CLK_UART_FRAC_DENOMINATOR_MASK = 0xffff,
+
+ /* CRU_CLK_SEL31_CON */
+ CLK_EMMC_SEL_SHIFT = 15,
+ CLK_EMMC_SEL_MASK = 0x1 << CLK_EMMC_SEL_SHIFT,
+ ACLK_PERI_SEL_SHIFT = 10,
+ ACLK_PERI_SEL_MASK = 0x3 << ACLK_PERI_SEL_SHIFT,
+ ACLK_PERI_SEL_600M = 0,
+ ACLK_PERI_SEL_480M,
+ ACLK_PERI_SEL_400M,
+ LSCLK_PERI_SEL_SHIFT = 9,
+ LSCLK_PERI_SEL_MASK = 0x1 << LSCLK_PERI_SEL_SHIFT,
+ LSCLK_PERI_SEL_300M = 0,
+ LSCLK_PERI_SEL_200M,
+ CLK_EMMC_DIV_SHIFT = 0,
+ CLK_EMMC_DIV_MASK = 0xff << CLK_EMMC_DIV_SHIFT,
+
+ /* CRU_CLK_SEL32_CON */
+ CLK_SDMMC_SEL_SHIFT = 15,
+ CLK_SDMMC_SEL_MASK = 0x1 << CLK_SDMMC_SEL_SHIFT,
+ CLK_MMC_SEL_GPLL = 0,
+ CLK_MMC_SEL_OSC,
+ CLK_UART2_SEL_SHIFT = 12,
+ CLK_UART2_SEL_MASK = 3 << CLK_UART2_SEL_SHIFT,
+ CLK_UART1_SEL_SHIFT = 10,
+ CLK_UART1_SEL_MASK = 3 << CLK_UART1_SEL_SHIFT,
+ CLK_UART0_SEL_SHIFT = 8,
+ CLK_UART0_SEL_MASK = 3 << CLK_UART0_SEL_SHIFT,
+ CLK_UART_SEL_SRC = 0,
+ CLK_UART_SEL_FRAC,
+ CLK_UART_SEL_OSC,
+ CLK_SDMMC_DIV_SHIFT = 0,
+ CLK_SDMMC_DIV_MASK = 0xff << CLK_SDMMC_DIV_SHIFT,
+
+ /* CRU_CLK_SEL33_CON */
+ CLK_SFC_SEL_SHIFT = 15,
+ CLK_SFC_SEL_MASK = 0x1 << CLK_SFC_SEL_SHIFT,
+ CLK_SFC_DIV_SHIFT = 0,
+ CLK_SFC_DIV_MASK = 0xff << CLK_SFC_DIV_SHIFT,
+
+ /* CRU_CLK_SEL34_CON */
+ CLK_PWM2_SEL_SHIFT = 14,
+ CLK_PWM2_SEL_MASK = 1 << CLK_PWM2_SEL_SHIFT,
+ CLK_PWM1_SEL_SHIFT = 13,
+ CLK_PWM1_SEL_MASK = 1 << CLK_PWM1_SEL_SHIFT,
+ CLK_PWM0_SEL_SHIFT = 12,
+ CLK_PWM0_SEL_MASK = 1 << CLK_PWM0_SEL_SHIFT,
+ CLK_PWM_SEL_100M = 0,
+ CLK_PWM_SEL_24M,
+ CLK_SPI0_SEL_SHIFT = 2,
+ CLK_SPI0_SEL_MASK = 3 << CLK_SPI0_SEL_SHIFT,
+ CLK_SPI0_SEL_200M = 0,
+ CLK_SPI0_SEL_100M,
+ CLK_SPI0_SEL_50M,
+ CLK_SPI0_SEL_24M,
+ CLK_I2C1_SEL_SHIFT = 1,
+ CLK_I2C1_SEL_MASK = 0x1 << CLK_I2C1_SEL_SHIFT,
+ CLK_I2C0_SEL_SHIFT = 0,
+ CLK_I2C0_SEL_MASK = 0x1 << CLK_I2C0_SEL_SHIFT,
+ CLK_I2C_SEL_100M = 0,
+ CLK_I2C_SEL_24M,
+
+ /* CRU_CLK_SEL35_CON */
+ CLK_PKA_CRYPTO_SEL_SHIFT = 4,
+ CLK_PKA_CRYPTO_SEL_MASK = 0x3 << CLK_PKA_CRYPTO_SEL_SHIFT,
+ CLK_CORE_CRYPTO_SEL_SHIFT = 2,
+ CLK_CORE_CRYPTO_SEL_MASK = 0x3 << CLK_CORE_CRYPTO_SEL_SHIFT,
+ CLK_CORE_CRYPTO_SEL_300M = 0,
+ CLK_CORE_CRYPTO_SEL_200M,
+ CLK_CORE_CRYPTO_SEL_100M,
+ DCLK_DECOM_SEL_SHIFT = 0,
+ DCLK_DECOM_SEL_MASK = 0x3 << DCLK_DECOM_SEL_SHIFT,
+ DCLK_DECOM_SEL_480M = 0,
+ DCLK_DECOM_SEL_400M,
+ DCLK_DECOM_SEL_300M,
+
+ /* CRU_CLK_SEL37_CON */
+ CLK_CORE_GPLL_DIV_SHIFT = 13,
+ CLK_CORE_GPLL_DIV_MASK = 0x7 << CLK_CORE_GPLL_DIV_SHIFT,
+ CLK_CORE_GPLL_SEL_SHIFT = 12,
+ CLK_CORE_GPLL_SEL_MASK = 0x1 << CLK_CORE_GPLL_SEL_SHIFT,
+ CLK_CORE_GPLL_SEL_GPLL = 0,
+ CLK_CORE_GPLL_SEL_OSC,
+
+ /* CRU_PMU_CLK_SEL2_CON */
+ LSCLK_PMU_SEL_SHIFT = 4,
+ LSCLK_PMU_SEL_MASK = 0x1 << LSCLK_PMU_SEL_SHIFT,
+ LSCLK_PMU_SEL_24M = 0,
+ LSCLK_PMU_SEL_RC_OSC,
+ LSCLK_PMU_DIV_SHIFT = 0,
+ LSCLK_PMU_DIV_MASK = 0x3 << LSCLK_PMU_DIV_SHIFT,
+
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rv1103b.h b/arch/arm/include/asm/arch-rockchip/grf_rv1103b.h
new file mode 100644
index 000000000000..6bb382a8e079
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rv1103b.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+/*
+ * (C) Copyright 2024 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _ASM_ARCH_GRF_RV1103B_H
+#define _ASM_ARCH_GRF_RV1103B_H
+
+#define VEPU_GRF 0x20100000
+#define NPU_GRF 0x20110000
+#define VI_GRF 0x20120000
+#define CPU_GRF 0x20130000
+#define DDR_GRF 0x20140000
+#define SYS_GRF 0x20150000
+#define PMU_GRF 0x20160000
+
+struct rv1103b_grf {
+ u32 reserved0[(SYS_GRF + 0xA0 - VEPU_GRF) / 4];
+ u32 gmac_con0; /* address offset: 0x00a0 */
+ u32 gmac_clk_con; /* address offset: 0x00a4 */
+ u32 gmac_st; /* address offset: 0x00a8 */
+ u32 reserved00ac; /* address offset: 0x00ac */
+ u32 macphy_con0; /* address offset: 0x00b0 */
+ u32 macphy_con1; /* address offset: 0x00b4 */
+ u32 reserved1[(PMU_GRF + 0x10000 - (SYS_GRF + 0xB4)) / 4];
+};
+
+check_member(rv1103b_grf, macphy_con1, SYS_GRF + 0xB4 - VEPU_GRF);
+
+#endif /* _ASM_ARCH_GRF_RV1103B_H */
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 34b63d4df34a..7bb0df6748cc 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -19,5 +19,6 @@ obj-$(CONFIG_ROCKCHIP_RK3528) += clk_rk3528.o
obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o
obj-$(CONFIG_ROCKCHIP_RK3576) += clk_rk3576.o
obj-$(CONFIG_ROCKCHIP_RK3588) += clk_rk3588.o
+obj-$(CONFIG_ROCKCHIP_RV1103B) += clk_rv1103b.o
obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o
diff --git a/drivers/clk/rockchip/clk_rv1103b.c b/drivers/clk/rockchip/clk_rv1103b.c
new file mode 100644
index 000000000000..81d892bf43c6
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1103b.c
@@ -0,0 +1,1068 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rockchip,rv1103b-cru.h>
+
+#include <clk.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1103b.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <linux/delay.h>
+#include <linux/stringify.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#ifndef BITS_WITH_WMASK
+#define BITS_WITH_WMASK(bits, msk, shift) \
+ ((bits) << (shift)) | ((msk) << ((shift) + 16))
+#endif
+
+static struct rockchip_pll_rate_table rv1103b_pll_rates[] = {
+ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+ RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+ RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+ { /* sentinel */ },
+};
+
+static struct rockchip_pll_clock rv1103b_pll_clks[] = {
+ [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1103B_PLL_CON(24),
+ RV1103B_MODE_CON, 0, 10, 0, rv1103b_pll_rates),
+};
+
+static ulong rv1103b_peri_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 con, sel, div, rate, prate;
+
+ switch (clk_id) {
+ case ACLK_PERI_SRC:
+ con = readl(&cru->clksel_con[31]);
+ sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
+ if (sel == ACLK_PERI_SEL_600M)
+ rate = 600 * MHz;
+ else if (sel == ACLK_PERI_SEL_480M)
+ rate = 480 * MHz;
+ else
+ rate = 400 * MHz;
+ break;
+ case LSCLK_PERI_SRC:
+ con = readl(&cru->clksel_con[31]);
+ sel = (con & LSCLK_PERI_SEL_MASK) >> LSCLK_PERI_SEL_SHIFT;
+ if (sel == LSCLK_PERI_SEL_300M)
+ rate = 300 * MHz;
+ else
+ rate = 200 * MHz;
+ break;
+ case PCLK_PERI_ROOT:
+ con = readl(&cru->peri_clksel_con[0]);
+ div = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;
+ rate = DIV_TO_RATE(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),
+ div);
+ break;
+ case PCLK_TOP_ROOT:
+ rate = DIV_TO_RATE(priv->gpll_hz, 11);
+ break;
+ case LSCLK_PMU_ROOT:
+ case PCLK_PMU:
+ con = readl(&cru->pmu_clksel_con[2]);
+ sel = (con & LSCLK_PMU_SEL_MASK) >> LSCLK_PMU_SEL_SHIFT;
+ div = (con & LSCLK_PMU_DIV_MASK) >> LSCLK_PMU_DIV_SHIFT;
+ if (sel == LSCLK_PMU_SEL_24M)
+ prate = OSC_HZ;
+ else
+ prate = RC_OSC_HZ;
+ rate = DIV_TO_RATE(prate, div);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static ulong rv1103b_peri_set_clk(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ int src_clk, div;
+
+ switch (clk_id) {
+ case ACLK_PERI_SRC:
+ if (rate >= 594 * MHz)
+ src_clk = ACLK_PERI_SEL_600M;
+ else if (rate >= 480 * MHz)
+ src_clk = ACLK_PERI_SEL_480M;
+ else
+ src_clk = ACLK_PERI_SEL_400M;
+ rk_clrsetreg(&cru->clksel_con[31],
+ ACLK_PERI_SEL_MASK,
+ src_clk << ACLK_PERI_SEL_SHIFT);
+ break;
+ case LSCLK_PERI_SRC:
+ if (rate >= 297 * MHz)
+ src_clk = LSCLK_PERI_SEL_300M;
+ else
+ src_clk = LSCLK_PERI_SEL_200M;
+ rk_clrsetreg(&cru->clksel_con[31],
+ LSCLK_PERI_SEL_MASK,
+ src_clk << LSCLK_PERI_SEL_SHIFT);
+ break;
+ case PCLK_PERI_ROOT:
+ div = DIV_ROUND_UP(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),
+ rate);
+ rk_clrsetreg(&cru->peri_clksel_con[0],
+ PCLK_PERI_DIV_MASK,
+ (div - 1) << PCLK_PERI_DIV_SHIFT);
+ break;
+ case PCLK_TOP_ROOT:
+ break;
+ case LSCLK_PMU_ROOT:
+ case PCLK_PMU:
+ if (!(OSC_HZ % rate)) {
+ src_clk = LSCLK_PMU_SEL_24M;
+ div = DIV_ROUND_UP(OSC_HZ, rate);
+ } else {
+ src_clk = LSCLK_PMU_SEL_RC_OSC;
+ div = DIV_ROUND_UP(RC_OSC_HZ, rate);
+ }
+ rk_clrsetreg(&cru->pmu_clksel_con[2],
+ LSCLK_PMU_SEL_MASK | LSCLK_PMU_DIV_MASK,
+ (src_clk << LSCLK_PMU_SEL_SHIFT) |
+ ((div - 1) << LSCLK_PMU_DIV_SHIFT));
+ break;
+ default:
+ printf("do not support this permid freq\n");
+ return -EINVAL;
+ }
+
+ return rv1103b_peri_get_clk(priv, clk_id);
+}
+
+static ulong rv1103b_i2c_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel, con;
+ ulong rate;
+
+ switch (clk_id) {
+ case CLK_I2C1:
+ case CLK_I2C2:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ case CLK_I2C_PERI:
+ con = readl(&cru->clksel_con[34]);
+ sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
+ break;
+ case CLK_I2C0:
+ case CLK_I2C_PMU:
+ con = readl(&cru->clksel_con[34]);
+ sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ if (sel == CLK_I2C_SEL_100M)
+ rate = 100 * MHz;
+ else
+ rate = OSC_HZ;
+
+ return rate;
+}
+
+static ulong rv1103b_crypto_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel, con, rate;
+
+ switch (clk_id) {
+ case ACLK_CRYPTO:
+ case HCLK_CRYPTO:
+ case HCLK_RK_RNG_NS:
+ case HCLK_RK_RNG_S:
+ return rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC);
+ case CLK_CORE_CRYPTO:
+ con = readl(&cru->clksel_con[35]);
+ sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
+ CLK_CORE_CRYPTO_SEL_SHIFT;
+ break;
+ case CLK_PKA_CRYPTO:
+ con = readl(&cru->clksel_con[35]);
+ sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
+ CLK_PKA_CRYPTO_SEL_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+ if (sel == CLK_CORE_CRYPTO_SEL_300M)
+ rate = 300 * MHz;
+ else if (sel == CLK_CORE_CRYPTO_SEL_200M)
+ rate = 200 * MHz;
+ else
+ rate = 100 * MHz;
+
+ return rate;
+}
+
+static ulong rv1103b_crypto_set_clk(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel;
+
+ if (rate >= 297 * MHz)
+ sel = CLK_CORE_CRYPTO_SEL_300M;
+ else if (rate >= 198 * MHz)
+ sel = CLK_CORE_CRYPTO_SEL_200M;
+ else
+ sel = CLK_CORE_CRYPTO_SEL_100M;
+
+ switch (clk_id) {
+ case ACLK_CRYPTO:
+ case HCLK_CRYPTO:
+ case HCLK_RK_RNG_NS:
+ case HCLK_RK_RNG_S:
+ rv1103b_peri_set_clk(priv, LSCLK_PERI_SRC, rate);
+ case CLK_CORE_CRYPTO:
+ rk_clrsetreg(&cru->clksel_con[35],
+ CLK_CORE_CRYPTO_SEL_MASK,
+ (sel << CLK_CORE_CRYPTO_SEL_SHIFT));
+ break;
+ case CLK_PKA_CRYPTO:
+ rk_clrsetreg(&cru->clksel_con[35],
+ CLK_PKA_CRYPTO_SEL_MASK,
+ (sel << CLK_PKA_CRYPTO_SEL_SHIFT));
+ break;
+ default:
+ return -ENOENT;
+ }
+ return rv1103b_crypto_get_clk(priv, clk_id);
+}
+
+static ulong rv1103b_mmc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 div, sel, con, prate;
+
+ switch (clk_id) {
+ case CCLK_SDMMC1:
+ case HCLK_SDMMC1:
+ con = readl(&cru->clksel_con[36]);
+ sel = (con & CLK_SDMMC_SEL_MASK) >>
+ CLK_SDMMC_SEL_SHIFT;
+ div = (con & CLK_SDMMC_DIV_MASK) >>
+ CLK_SDMMC_DIV_SHIFT;
+ if (sel == CLK_MMC_SEL_GPLL)
+ prate = priv->gpll_hz;
+ else
+ prate = OSC_HZ;
+ return DIV_TO_RATE(prate, div);
+ case CCLK_SDMMC0:
+ case HCLK_SDMMC0:
+ con = readl(&cru->clksel_con[32]);
+ sel = (con & CLK_SDMMC_SEL_MASK) >>
+ CLK_SDMMC_SEL_SHIFT;
+ div = (con & CLK_SDMMC_DIV_MASK) >>
+ CLK_SDMMC_DIV_SHIFT;
+ if (sel == CLK_MMC_SEL_GPLL)
+ prate = priv->gpll_hz;
+ else
+ prate = OSC_HZ;
+ return DIV_TO_RATE(prate, div);
+ case CCLK_EMMC:
+ case HCLK_EMMC:
+ con = readl(&cru->clksel_con[31]);
+ sel = (con & CLK_EMMC_SEL_MASK) >>
+ CLK_EMMC_SEL_SHIFT;
+ div = (con & CLK_EMMC_DIV_MASK) >>
+ CLK_EMMC_DIV_SHIFT;
+ if (sel == CLK_MMC_SEL_GPLL)
+ prate = priv->gpll_hz;
+ else
+ prate = OSC_HZ;
+ return DIV_TO_RATE(prate, div);
+ case SCLK_SFC_2X:
+ case HCLK_SFC:
+ con = readl(&cru->clksel_con[33]);
+ sel = (con & CLK_SFC_SEL_MASK) >>
+ CLK_SFC_SEL_SHIFT;
+ div = (con & CLK_SFC_DIV_MASK) >>
+ CLK_SFC_DIV_SHIFT;
+ if (sel == CLK_MMC_SEL_GPLL)
+ prate = priv->gpll_hz;
+ else
+ prate = OSC_HZ;
+ return DIV_TO_RATE(prate, div);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1103b_mmc_set_clk(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel, src_clk_div;
+ ulong prate = 0;
+
+ if ((OSC_HZ % rate) == 0) {
+ sel = CLK_MMC_SEL_OSC;
+ prate = OSC_HZ;
+ } else {
+ sel = CLK_MMC_SEL_GPLL;
+ prate = priv->gpll_hz;
+ }
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+
+ switch (clk_id) {
+ case CCLK_SDMMC1:
+ case HCLK_SDMMC1:
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->clksel_con[36],
+ CLK_SDMMC_SEL_MASK |
+ CLK_SDMMC_DIV_MASK,
+ (sel << CLK_SDMMC_SEL_SHIFT) |
+ ((src_clk_div - 1) <<
+ CLK_SDMMC_DIV_SHIFT));
+ break;
+ case CCLK_SDMMC0:
+ case HCLK_SDMMC0:
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->clksel_con[32],
+ CLK_SDMMC_SEL_MASK |
+ CLK_SDMMC_DIV_MASK,
+ (sel << CLK_SDMMC_SEL_SHIFT) |
+ ((src_clk_div - 1) <<
+ CLK_SDMMC_DIV_SHIFT));
+ break;
+ case CCLK_EMMC:
+ case HCLK_EMMC:
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->clksel_con[31],
+ CLK_EMMC_SEL_MASK |
+ CLK_EMMC_DIV_MASK,
+ (sel << CLK_EMMC_SEL_SHIFT) |
+ ((src_clk_div - 1) <<
+ CLK_EMMC_DIV_SHIFT));
+ break;
+ case SCLK_SFC_2X:
+ case HCLK_SFC:
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->clksel_con[33],
+ CLK_SFC_SEL_MASK |
+ CLK_SFC_DIV_MASK,
+ (sel << CLK_SFC_SEL_SHIFT) |
+ ((src_clk_div - 1) <<
+ CLK_SFC_DIV_SHIFT));
+ break;
+ default:
+ return -ENOENT;
+ }
+ return rv1103b_mmc_get_clk(priv, clk_id);
+}
+
+static ulong rv1103b_i2c_set_clk(struct rv1103b_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ int src_clk;
+
+ if (rate == OSC_HZ)
+ src_clk = CLK_I2C_SEL_24M;
+ else
+ src_clk = CLK_I2C_SEL_100M;
+
+ switch (clk_id) {
+ case CLK_I2C1:
+ case CLK_I2C2:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ case CLK_I2C_PERI:
+ rk_clrsetreg(&cru->clksel_con[34], CLK_I2C1_SEL_MASK,
+ src_clk << CLK_I2C1_SEL_SHIFT);
+ break;
+ case CLK_I2C0:
+ case CLK_I2C_PMU:
+ rk_clrsetreg(&cru->clksel_con[34], CLK_I2C0_SEL_MASK,
+ src_clk << CLK_I2C0_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+ return rv1103b_i2c_get_clk(priv, clk_id);
+}
+
+static ulong rv1103b_spi_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel, con, rate;
+
+ switch (clk_id) {
+ case CLK_SPI0:
+ con = readl(&cru->clksel_con[34]);
+ sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+ if (sel == CLK_SPI0_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == CLK_SPI0_SEL_100M)
+ rate = 100 * MHz;
+ else if (sel == CLK_SPI0_SEL_50M)
+ rate = 50 * MHz;
+ else
+ rate = OSC_HZ;
+
+ return rate;
+}
+
+static ulong rv1103b_spi_set_clk(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ int src_clk;
+
+ if (rate >= 198 * MHz)
+ src_clk = CLK_SPI0_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = CLK_SPI0_SEL_100M;
+ else if (rate >= 48 * MHz)
+ src_clk = CLK_SPI0_SEL_50M;
+ else
+ src_clk = CLK_SPI0_SEL_24M;
+
+ switch (clk_id) {
+ case CLK_SPI0:
+ rk_clrsetreg(&cru->clksel_con[34], CLK_SPI0_SEL_MASK,
+ src_clk << CLK_SPI0_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1103b_spi_get_clk(priv, clk_id);
+}
+
+static ulong rv1103b_pwm_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel, con;
+
+ switch (clk_id) {
+ case CLK_PWM0:
+ case CLK_PWM0_SRC:
+ con = readl(&cru->clksel_con[34]);
+ sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
+ break;
+ case CLK_PWM1:
+ con = readl(&cru->clksel_con[34]);
+ sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
+ break;
+ case CLK_PWM2:
+ con = readl(&cru->clksel_con[34]);
+ sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ switch (sel) {
+ case CLK_PWM_SEL_100M:
+ return 100 * MHz;
+ case CLK_PWM_SEL_24M:
+ return OSC_HZ;
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1103b_pwm_set_clk(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ int src_clk;
+
+ if (rate >= 99 * MHz)
+ src_clk = CLK_PWM_SEL_100M;
+ else
+ src_clk = CLK_PWM_SEL_24M;
+
+ switch (clk_id) {
+ case CLK_PWM0:
+ case CLK_PWM0_SRC:
+ rk_clrsetreg(&cru->clksel_con[34],
+ CLK_PWM0_SEL_MASK,
+ src_clk << CLK_PWM0_SEL_SHIFT);
+ break;
+ case CLK_PWM1:
+ rk_clrsetreg(&cru->clksel_con[34],
+ CLK_PWM1_SEL_MASK,
+ src_clk << CLK_PWM1_SEL_SHIFT);
+ break;
+ case CLK_PWM2:
+ rk_clrsetreg(&cru->clksel_con[34],
+ CLK_PWM2_SEL_MASK,
+ src_clk << CLK_PWM2_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1103b_pwm_get_clk(priv, clk_id);
+}
+
+static ulong rv1103b_adc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 div, con;
+
+ switch (clk_id) {
+ case CLK_SARADC:
+ con = readl(&cru->peri_clksel_con[1]);
+ div = (con & CLK_SARADC_DIV_MASK) >>
+ CLK_SARADC_DIV_SHIFT;
+ return DIV_TO_RATE(OSC_HZ, div);
+ case CLK_TSADC_TSEN:
+ con = readl(&cru->peri_clksel_con[0]);
+ div = (con & CLK_TSADC_TSEN_DIV_MASK) >>
+ CLK_TSADC_TSEN_DIV_SHIFT;
+ return DIV_TO_RATE(OSC_HZ, div);
+ case CLK_TSADC:
+ con = readl(&cru->peri_clksel_con[0]);
+ div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
+ return DIV_TO_RATE(OSC_HZ, div);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1103b_adc_set_clk(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
+
+ switch (clk_id) {
+ case CLK_SARADC:
+ assert(src_clk_div - 1 <= 7);
+ rk_clrsetreg(&cru->peri_clksel_con[1],
+ CLK_SARADC_DIV_MASK,
+ (src_clk_div - 1) <<
+ CLK_SARADC_DIV_SHIFT);
+ break;
+ case CLK_TSADC_TSEN:
+ assert(src_clk_div - 1 <= 32);
+ rk_clrsetreg(&cru->peri_clksel_con[0],
+ CLK_TSADC_TSEN_DIV_MASK,
+ (src_clk_div - 1) <<
+ CLK_TSADC_TSEN_DIV_SHIFT);
+ break;
+ case CLK_TSADC:
+ assert(src_clk_div - 1 <= 32);
+ rk_clrsetreg(&cru->peri_clksel_con[0],
+ CLK_TSADC_DIV_MASK,
+ (src_clk_div - 1) <<
+ CLK_TSADC_DIV_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+ return rv1103b_adc_get_clk(priv, clk_id);
+}
+
+/*
+ *
+ * rational_best_approximation(31415, 10000,
+ * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+ unsigned long given_denominator,
+ unsigned long max_numerator,
+ unsigned long max_denominator,
+ unsigned long *best_numerator,
+ unsigned long *best_denominator)
+{
+ unsigned long n, d, n0, d0, n1, d1;
+
+ n = given_numerator;
+ d = given_denominator;
+ n0 = 0;
+ d1 = 0;
+ n1 = 1;
+ d0 = 1;
+ for (;;) {
+ unsigned long t, a;
+
+ if (n1 > max_numerator || d1 > max_denominator) {
+ n1 = n0;
+ d1 = d0;
+ break;
+ }
+ if (d == 0)
+ break;
+ t = d;
+ a = n / d;
+ d = n % d;
+ n = t;
+ t = n0 + a * n1;
+ n0 = n1;
+ n1 = t;
+ t = d0 + a * d1;
+ d0 = d1;
+ d1 = t;
+ }
+ *best_numerator = n1;
+ *best_denominator = d1;
+}
+
+static ulong rv1103b_uart_get_rate(struct rv1103b_clk_priv *priv, ulong clk_id)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 reg, con, fracdiv, div, src, p_rate;
+ unsigned long m, n;
+
+ switch (clk_id) {
+ case SCLK_UART0:
+ reg = 10;
+ con = readl(&cru->clksel_con[32]);
+ src = (con & CLK_UART0_SEL_MASK) >> CLK_UART0_SEL_SHIFT;
+ con = readl(&cru->clksel_con[5]);
+ div = (con & CLK_UART0_SRC_DIV_MASK) >> CLK_UART0_SRC_DIV_SHIFT;
+ break;
+ case SCLK_UART1:
+ reg = 11;
+ con = readl(&cru->clksel_con[32]);
+ src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;
+ con = readl(&cru->clksel_con[5]);
+ div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;
+ break;
+ case SCLK_UART2:
+ reg = 12;
+ con = readl(&cru->clksel_con[32]);
+ src = (con & CLK_UART2_SEL_MASK) >> CLK_UART2_SEL_SHIFT;
+ con = readl(&cru->clksel_con[5]);
+ div = (con & CLK_UART2_SRC_DIV_MASK) >> CLK_UART2_SRC_DIV_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ p_rate = priv->gpll_hz;
+ if (src == CLK_UART_SEL_SRC) {
+ return DIV_TO_RATE(p_rate, div);
+ } else if (src == CLK_UART_SEL_FRAC) {
+ fracdiv = readl(&cru->clksel_con[reg]);
+ n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
+ n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
+ m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
+ m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
+ return DIV_TO_RATE(p_rate, div) * n / m;
+ } else {
+ return OSC_HZ;
+ }
+}
+
+static ulong rv1103b_uart_set_rate(struct rv1103b_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 reg, uart_src, div;
+ unsigned long m = 0, n = 0, val;
+
+ if (priv->gpll_hz % rate == 0) {
+ uart_src = CLK_UART_SEL_SRC;
+ div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ } else if (rate == OSC_HZ) {
+ uart_src = CLK_UART_SEL_OSC;
+ div = 2;
+ } else {
+ uart_src = CLK_UART_SEL_FRAC;
+ div = 2;
+ rational_best_approximation(rate, priv->gpll_hz / div,
+ GENMASK(16 - 1, 0),
+ GENMASK(16 - 1, 0),
+ &m, &n);
+ }
+
+ switch (clk_id) {
+ case SCLK_UART0:
+ reg = 10;
+ rk_clrsetreg(&cru->clksel_con[5],
+ CLK_UART0_SRC_DIV_MASK,
+ div << CLK_UART0_SRC_DIV_SHIFT);
+ rk_clrsetreg(&cru->clksel_con[32],
+ CLK_UART0_SEL_MASK,
+ uart_src << CLK_UART0_SEL_SHIFT);
+ break;
+ case SCLK_UART1:
+ reg = 11;
+ rk_clrsetreg(&cru->clksel_con[5],
+ CLK_UART1_SRC_DIV_MASK,
+ div << CLK_UART1_SRC_DIV_SHIFT);
+ rk_clrsetreg(&cru->clksel_con[32],
+ CLK_UART1_SEL_MASK,
+ uart_src << CLK_UART1_SEL_SHIFT);
+ break;
+ case SCLK_UART2:
+ reg = 12;
+ rk_clrsetreg(&cru->clksel_con[5],
+ CLK_UART2_SRC_DIV_MASK,
+ div << CLK_UART2_SRC_DIV_SHIFT);
+ rk_clrsetreg(&cru->clksel_con[32],
+ CLK_UART2_SEL_MASK,
+ uart_src << CLK_UART2_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+ if (m && n) {
+ val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
+ writel(val, &cru->clksel_con[reg]);
+ }
+
+ return rv1103b_uart_get_rate(priv, clk_id);
+}
+
+static ulong rv1103b_decom_get_clk(struct rv1103b_clk_priv *priv)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel, con, prate;
+
+ con = readl(&cru->clksel_con[35]);
+ sel = (con & DCLK_DECOM_SEL_MASK) >>
+ DCLK_DECOM_SEL_SHIFT;
+ if (sel == DCLK_DECOM_SEL_480M)
+ prate = 480 * MHz;
+ else if (sel == DCLK_DECOM_SEL_400M)
+ prate = 400 * MHz;
+ else
+ prate = 300 * MHz;
+ return prate;
+}
+
+static ulong rv1103b_decom_set_clk(struct rv1103b_clk_priv *priv, ulong rate)
+{
+ struct rv1103b_cru *cru = priv->cru;
+ u32 sel;
+
+ if (rate >= 480 * MHz)
+ sel = DCLK_DECOM_SEL_480M;
+ else if (rate >= 396 * MHz)
+ sel = DCLK_DECOM_SEL_400M;
+ else
+ sel = DCLK_DECOM_SEL_300M;
+ rk_clrsetreg(&cru->clksel_con[35], DCLK_DECOM_SEL_MASK,
+ (sel << DCLK_DECOM_SEL_SHIFT));
+
+ return rv1103b_decom_get_clk(priv);
+}
+
+static ulong rv1103b_clk_get_rate(struct clk *clk)
+{
+ struct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ if (!priv->gpll_hz) {
+ printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+ return -ENOENT;
+ }
+
+ switch (clk->id) {
+ case PLL_GPLL:
+ rate = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL], priv->cru,
+ GPLL);
+ break;
+ case ACLK_PERI_SRC:
+ case LSCLK_PERI_SRC:
+ case PCLK_PERI_ROOT:
+ case PCLK_TOP_ROOT:
+ case LSCLK_PMU_ROOT:
+ case PCLK_PMU:
+ rate = rv1103b_peri_get_clk(priv, clk->id);
+ break;
+ case ACLK_CRYPTO:
+ case HCLK_CRYPTO:
+ case HCLK_RK_RNG_NS:
+ case HCLK_RK_RNG_S:
+ case CLK_CORE_CRYPTO:
+ case CLK_PKA_CRYPTO:
+ rate = rv1103b_crypto_get_clk(priv, clk->id);
+ break;
+ case CCLK_SDMMC1:
+ case HCLK_SDMMC1:
+ case CCLK_SDMMC0:
+ case HCLK_SDMMC0:
+ case CCLK_EMMC:
+ case HCLK_EMMC:
+ case SCLK_SFC_2X:
+ case HCLK_SFC:
+ rate = rv1103b_mmc_get_clk(priv, clk->id);
+ break;
+ case CLK_I2C1:
+ case CLK_I2C2:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ case CLK_I2C_PERI:
+ case CLK_I2C0:
+ case CLK_I2C_PMU:
+ rate = rv1103b_i2c_get_clk(priv, clk->id);
+ break;
+ case CLK_SPI0:
+ rate = rv1103b_spi_get_clk(priv, clk->id);
+ break;
+ case CLK_PWM0:
+ case CLK_PWM0_SRC:
+ case CLK_PWM1:
+ case CLK_PWM2:
+ rate = rv1103b_pwm_get_clk(priv, clk->id);
+ break;
+ case CLK_SARADC:
+ case CLK_TSADC_TSEN:
+ case CLK_TSADC:
+ rate = rv1103b_adc_get_clk(priv, clk->id);
+ break;
+ case SCLK_UART0:
+ case SCLK_UART1:
+ case SCLK_UART2:
+ rate = rv1103b_uart_get_rate(priv, clk->id);
+ break;
+ case DCLK_DECOM_SRC:
+ case DCLK_DECOM:
+ rate = rv1103b_decom_get_clk(priv);
+ break;
+ case TCLK_WDT_LPMCU:
+ case TCLK_WDT_HPMCU:
+ case TCLK_WDT_NS:
+ case TCLK_WDT_S:
+ rate = OSC_HZ;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rate;
+};
+
+static ulong rv1103b_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong ret = 0;
+
+ if (!priv->gpll_hz) {
+ printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+ return -ENOENT;
+ }
+
+ switch (clk->id) {
+ case PLL_GPLL:
+ ret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,
+ GPLL, rate);
+ break;
+ case ACLK_PERI_SRC:
+ case LSCLK_PERI_SRC:
+ case PCLK_PERI_ROOT:
+ case PCLK_TOP_ROOT:
+ case LSCLK_PMU_ROOT:
+ case PCLK_PMU:
+ ret = rv1103b_peri_set_clk(priv, clk->id, rate);
+ break;
+ case ACLK_CRYPTO:
+ case HCLK_CRYPTO:
+ case HCLK_RK_RNG_NS:
+ case HCLK_RK_RNG_S:
+ case CLK_CORE_CRYPTO:
+ case CLK_PKA_CRYPTO:
+ ret = rv1103b_crypto_set_clk(priv, clk->id, rate);
+ break;
+ case CCLK_SDMMC1:
+ case HCLK_SDMMC1:
+ case CCLK_SDMMC0:
+ case HCLK_SDMMC0:
+ case CCLK_EMMC:
+ case HCLK_EMMC:
+ case SCLK_SFC_2X:
+ case HCLK_SFC:
+ ret = rv1103b_mmc_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_I2C1:
+ case CLK_I2C2:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ case CLK_I2C_PERI:
+ case CLK_I2C0:
+ case CLK_I2C_PMU:
+ ret = rv1103b_i2c_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_SPI0:
+ ret = rv1103b_spi_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_PWM0:
+ case CLK_PWM0_SRC:
+ case CLK_PWM1:
+ case CLK_PWM2:
+ ret = rv1103b_pwm_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_SARADC:
+ case CLK_TSADC_TSEN:
+ case CLK_TSADC:
+ ret = rv1103b_adc_set_clk(priv, clk->id, rate);
+ break;
+ case SCLK_UART0:
+ case SCLK_UART1:
+ case SCLK_UART2:
+ ret = rv1103b_uart_set_rate(priv, clk->id, rate);
+ break;
+ case DCLK_DECOM_SRC:
+ case DCLK_DECOM:
+ rate = rv1103b_decom_set_clk(priv, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return ret;
+};
+
+static int rv1103b_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ switch (clk->id) {
+ default:
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+static struct clk_ops rv1103b_clk_ops = {
+ .get_rate = rv1103b_clk_get_rate,
+ .set_rate = rv1103b_clk_set_rate,
+#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))
+ .set_parent = rv1103b_clk_set_parent,
+#endif
+};
+
+static void rv1103b_clk_init(struct rv1103b_clk_priv *priv)
+{
+ int ret;
+ u32 div;
+
+ priv->sync_kernel = false;
+ priv->gpll_hz = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL],
+ priv->cru, GPLL);
+ if (priv->gpll_hz != GPLL_HZ) {
+ ret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,
+ GPLL, GPLL_HZ);
+ if (!ret)
+ priv->gpll_hz = GPLL_HZ;
+ }
+
+ if (!priv->armclk_enter_hz) {
+ div = (readl(&priv->cru->clksel_con[37]) &
+ CLK_CORE_GPLL_DIV_MASK) >>
+ CLK_CORE_GPLL_DIV_SHIFT;
+ priv->armclk_enter_hz = DIV_TO_RATE(priv->gpll_hz, div);
+ priv->armclk_init_hz = priv->armclk_enter_hz;
+ }
+}
+
+static int rv1103b_clk_probe(struct udevice *dev)
+{
+ struct rv1103b_clk_priv *priv = dev_get_priv(dev);
+ int ret;
+
+#ifdef CONFIG_SPL_BUILD
+ /* fix lsclk_prei div */
+ writel(BITS_WITH_WMASK(1, 0x1U, 9), RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(31));
+ /* fix cpu div */
+ writel(BITS_WITH_WMASK(1, 0x7U, 13), RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(37));
+ /* fix gpll postdiv1 */
+ writel(BITS_WITH_WMASK(1, 0x7U, 12), RV1103B_CRU_BASE + RV1103B_PLL_CON(24));
+#endif
+
+ rv1103b_clk_init(priv);
+
+ /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
+ ret = clk_set_defaults(dev, 1);
+ if (ret)
+ debug("%s clk_set_defaults failed %d\n", __func__, ret);
+ else
+ priv->sync_kernel = true;
+ return 0;
+}
+
+static int rv1103b_clk_of_to_plat(struct udevice *dev)
+{
+ struct rv1103b_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = dev_read_addr_ptr(dev);
+
+ return 0;
+}
+
+static int rv1103b_clk_bind(struct udevice *dev)
+{
+ struct udevice *sys_child;
+ struct sysreset_reg *priv;
+ int ret;
+
+ /* The sysreset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", &sys_child);
+ if (ret) {
+ debug("Warning: No sysreset driver: ret=%d\n", ret);
+ } else {
+ priv = malloc(sizeof(struct sysreset_reg));
+ priv->glb_srst_fst_value = offsetof(struct rv1103b_cru, glb_srst_fst);
+ priv->glb_srst_snd_value = offsetof(struct rv1103b_cru, glb_srst_snd);
+ dev_set_priv(sys_child, priv);
+ }
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+ ret = offsetof(struct rv1103b_cru, peri_softrst_con[0]);
+ ret = rockchip_reset_bind(dev, ret, 12); /* number of reset registers */
+ if (ret)
+ debug("Warning: software reset driver bind failed\n");
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id rv1103b_clk_ids[] = {
+ { .compatible = "rockchip,rv1103b-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(clk_rv1103b) = {
+ .name = "clk_rv1103b",
+ .id = UCLASS_CLK,
+ .of_match = rv1103b_clk_ids,
+ .priv_auto = sizeof(struct rv1103b_clk_priv),
+ .of_to_plat = rv1103b_clk_of_to_plat,
+ .ops = &rv1103b_clk_ops,
+ .bind = rv1103b_clk_bind,
+ .probe = rv1103b_clk_probe,
+};
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 4/7] tools: rkcommon: Add RV1103B support
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
` (2 preceding siblings ...)
2026-02-08 21:26 ` [PATCH v2 3/7] clk: rockchip: Add RV1103B clock driver Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 5/7] rockchip: spl-boot-order: Add SPI NAND support Fabio Estevam
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Xuhui Lin, Fabio Estevam
From: Xuhui Lin <xuhui.lin@rock-chips.com>
Allow rkcommon to generate an image for the RV1103B.
Signed-off-by: Xuhui Lin <xuhui.lin@rock-chips.com>
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- Use the original author from Rockchip's vendor U-Boot tre
tools/rkcommon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index e7e78ef7e5b7..15aaf8f890aa 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -148,6 +148,7 @@ static struct spl_info spl_infos[] = {
{ "rk3328", "RK32", 0x8000 - 0x800, false, RK_HEADER_V1 },
{ "rk3368", "RK33", 0x8000 - 0x1000, false, RK_HEADER_V1 },
{ "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 },
+ { "rv1103b", "110E", 0x40000 - 0x1000, false, RK_HEADER_V2 },
{ "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 },
{ "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 },
{ "rk3528", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 },
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 5/7] rockchip: spl-boot-order: Add SPI NAND support
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
` (3 preceding siblings ...)
2026-02-08 21:26 ` [PATCH v2 4/7] tools: rkcommon: Add RV1103B support Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
2026-02-09 9:56 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 6/7] spl: add SPI NAND support via MTD in SPL Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 7/7] omega4-rv1103b: Add the initial support Fabio Estevam
6 siblings, 1 reply; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Fabio Estevam
From: Fabio Estevam <festevam@nabladev.com>
Make spl-boot-order to accept boot from SPI NAND as well.
With this change, it is possible to specify spi_nand
as the boot medium like this:
u-boot,spl-boot-order = &spi_nand;
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- None.
arch/arm/mach-rockchip/spl-boot-order.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
index 6572dde29f65..e5897536934a 100644
--- a/arch/arm/mach-rockchip/spl-boot-order.c
+++ b/arch/arm/mach-rockchip/spl-boot-order.c
@@ -4,6 +4,7 @@
*/
#include <dm.h>
+#include <dm/device_compat.h>
#include <fdt_support.h>
#include <log.h>
#include <mmc.h>
@@ -75,6 +76,8 @@ static int spl_node_to_boot_device(int node)
*/
if (!uclass_find_device_by_of_offset(UCLASS_SPI_FLASH, node, &parent))
return BOOT_DEVICE_SPI;
+ if (fdt_node_check_compatible(gd->fdt_blob, node, "spi-nand") == 0)
+ return BOOT_DEVICE_SPI;
return -1;
}
@@ -221,8 +224,12 @@ int spl_decode_boot_device(u32 boot_device, char *buf, size_t buflen)
ret = uclass_find_device_by_of_offset(UCLASS_SPI_FLASH, node, &dev);
if (ret) {
- debug("%s: could not find udevice for %s\n", __func__, conf);
- continue;
+ ret = uclass_find_device_by_of_offset(UCLASS_MTD, node, &dev);
+ if (ret || !device_is_compatible(dev, "spi-nand")) {
+ debug("%s: could not find udevice for %s\n",
+ __func__, conf);
+ continue;
+ }
}
return ofnode_get_path(dev_ofnode(dev), buf, buflen);
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 6/7] spl: add SPI NAND support via MTD in SPL
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
` (4 preceding siblings ...)
2026-02-08 21:26 ` [PATCH v2 5/7] rockchip: spl-boot-order: Add SPI NAND support Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
2026-02-08 23:47 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 7/7] omega4-rv1103b: Add the initial support Fabio Estevam
6 siblings, 1 reply; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Fabio Estevam
From: Fabio Estevam <festevam@nabladev.com>
Add support for booting U-Boot SPL from SPI NAND devices
using the MTD subsystem.
- Introduce CONFIG_SPL_SPI_NAND_LOAD to enable SPL loading
from SPI NAND flash.
- Implement spl_spi_nand.c as a dedicated SPL loader that
reads the FIT image from SPI NAND via MTD.
- Update common/spl/Kconfig and Makefiles to include the
new loader in SPL builds.
- Adjust drivers/mtd/Makefile and drivers/mtd/nand/Makefile
to build the necessary SPI NAND MTD objects only when
CONFIG_SPL_SPI_NAND_LOAD is enabled, avoiding size impact
on other boards.
This allows boards like the Omega4 RV1103 to boot SPL directly
from SPI NAND, keeping the SPL small and avoiding unnecessary
inclusion of SPI NOR code.
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- None.
common/spl/Kconfig | 10 ++++-
common/spl/Makefile | 1 +
common/spl/spl_spi_nand.c | 82 +++++++++++++++++++++++++++++++++++++++
drivers/mtd/Makefile | 1 +
drivers/mtd/nand/Makefile | 13 ++++++-
5 files changed, 105 insertions(+), 2 deletions(-)
create mode 100644 common/spl/spl_spi_nand.c
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 2998b7acb75f..126855b804ce 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1576,13 +1576,21 @@ config SPL_SPI_LOAD
Enable support for loading next stage, U-Boot or otherwise, from
SPI NOR in U-Boot SPL.
+config SPL_SPI_NAND_LOAD
+ bool "Support loading from SPI NAND flash"
+ depends on SPL
+ depends on MTD && DM_MTD
+ help
+ Enable support for loading next stage, U-Boot or otherwise, from
+ SPI NAND in U-Boot SPL.
+
endif # SPL_SPI_FLASH_SUPPORT
config SYS_SPI_U_BOOT_OFFS
hex "address of u-boot payload in SPI flash"
default 0x8000 if ARCH_SUNXI
default 0x0
- depends on SPL_SPI_LOAD || SPL_SPI_SUNXI
+ depends on SPL_SPI_LOAD || SPL_SPI_NAND_LOAD || SPL_SPI_SUNXI
help
Address within SPI-Flash from where the u-boot payload is fetched
from.
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 4c9482bd3096..4628902e7e31 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_$(PHASE_)NVME) += spl_nvme.o
obj-$(CONFIG_$(PHASE_)SEMIHOSTING) += spl_semihosting.o
obj-$(CONFIG_$(PHASE_)DFU) += spl_dfu.o
obj-$(CONFIG_$(PHASE_)SPI_LOAD) += spl_spi.o
+obj-$(CONFIG_$(PHASE_)SPI_NAND_LOAD) += spl_spi_nand.o
obj-$(CONFIG_$(PHASE_)RAM_SUPPORT) += spl_ram.o
obj-$(CONFIG_$(PHASE_)USB_SDP_SUPPORT) += spl_sdp.o
endif
diff --git a/common/spl/spl_spi_nand.c b/common/spl/spl_spi_nand.c
new file mode 100644
index 000000000000..20b877f75a05
--- /dev/null
+++ b/common/spl/spl_spi_nand.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * SPL loader for SPI NAND devices using the MTD subsystem.
+ *
+ * Based on spl_spi.c, which is:
+ *
+ * Copyright (C) 2011 OMICRON electronics GmbH
+ *
+ * based on drivers/mtd/nand/raw/nand_spl_load.c
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ */
+
+#include <config.h>
+#include <image.h>
+#include <log.h>
+#include <errno.h>
+#include <spl.h>
+#include <spl_load.h>
+#include <asm/io.h>
+#include <dm/device_compat.h>
+#include <dm/ofnode.h>
+#include <dm/uclass.h>
+#include <mtd.h>
+
+static struct mtd_info *spl_spi_nand_get_mtd(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ for (ret = uclass_first_device_err(UCLASS_MTD, &dev);
+ dev;
+ ret = uclass_next_device_err(&dev)) {
+ if (ret)
+ continue;
+ if (device_is_compatible(dev, "spi-nand"))
+ return dev_get_uclass_priv(dev);
+ }
+
+ return NULL;
+}
+
+static ulong spl_spinand_fit_read(struct spl_load_info *load, ulong offs,
+ ulong size, void *buf)
+{
+ struct mtd_info *mtd = load->priv;
+ size_t retlen = 0;
+ int ret;
+
+ ret = mtd_read(mtd, offs, size, &retlen, buf);
+ if (ret && ret != -EUCLEAN) {
+ printf("SPI NAND read failed offs=0x%lx size=0x%lx ret=%d\n",
+ offs, size, ret);
+ return 0;
+ }
+ if (retlen != size)
+ return 0;
+
+ return retlen;
+}
+
+static int spl_spinand_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ struct spl_load_info load;
+ struct mtd_info *mtd;
+
+ mtd = spl_spi_nand_get_mtd();
+ if (!mtd) {
+ puts("SPI NAND probe failed.\n");
+ return -ENODEV;
+ }
+
+ spl_load_init(&load, spl_spinand_fit_read, mtd, 1);
+
+ return spl_load(spl_image, bootdev, &load, 0, CONFIG_SYS_SPI_U_BOOT_OFFS);
+}
+
+/* Use priority 1 so that boards can override this */
+SPL_LOAD_IMAGE_METHOD("SPI NAND", 1, BOOT_DEVICE_SPI, spl_spinand_load_image);
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index ce05e206073d..a12d880a9e90 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -34,6 +34,7 @@ else
ifneq ($(mtd-y),)
obj-$(CONFIG_SPL_MTD) += mtd.o
endif
+obj-$(CONFIG_SPL_SPI_NAND_LOAD) += nand/
obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += nand/
obj-$(CONFIG_SPL_ONENAND_SUPPORT) += onenand/
obj-$(CONFIG_$(PHASE_)SPI_FLASH_SUPPORT) += spi/
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index c8169cf73902..7cd2a5f1af9b 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -1,10 +1,21 @@
# SPDX-License-Identifier: GPL-2.0+
-ifeq ($(CONFIG_XPL_BUILD)$(CONFIG_TPL_BUILD),)
nandcore-objs := core.o bbt.o
+
+ifeq ($(CONFIG_XPL_BUILD)$(CONFIG_TPL_BUILD),)
+
+# U-Boot proper
obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
obj-$(CONFIG_MTD_RAW_NAND) += raw/
obj-$(CONFIG_MTD_SPI_NAND) += spi/
+
else
+
+# SPL / XPL / TPL
+# SPL has no MTD_NAND_CORE symbol, so we must key off SPI NAND usage
+obj-$(CONFIG_SPL_SPI_NAND_LOAD) += nandcore.o
+obj-$(CONFIG_SPL_SPI_NAND_LOAD) += spi/
+
+# raw NAND still follows the normal SPL rule
obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += raw/
endif
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 7/7] omega4-rv1103b: Add the initial support
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
` (5 preceding siblings ...)
2026-02-08 21:26 ` [PATCH v2 6/7] spl: add SPI NAND support via MTD in SPL Fabio Estevam
@ 2026-02-08 21:26 ` Fabio Estevam
6 siblings, 0 replies; 12+ messages in thread
From: Fabio Estevam @ 2026-02-08 21:26 UTC (permalink / raw)
To: kever.yang; +Cc: trini, jonas, u-boot, Fabio Estevam
From: Fabio Estevam <festevam@nabladev.com>
Add the initial support for Onion's Omega4 RV1103B board.
It boots from the SPI NAND.
Tested the boot of a 6.6 OpenWRT kernel and also a 6.19-rc8 mainline
kernel.
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
---
Changes since v1:
- Only adapted to the correct SoC name: RV1103B instead of RV1103.
arch/arm/include/asm/arch-rv1103b/boot0.h | 11 ++
arch/arm/mach-rockchip/Kconfig | 14 ++
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rv1103b/Kconfig | 23 +++
arch/arm/mach-rockchip/rv1103b/Makefile | 12 ++
arch/arm/mach-rockchip/rv1103b/boot0.h | 5 +
arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c | 32 +++++
arch/arm/mach-rockchip/rv1103b/rv1103b.c | 133 ++++++++++++++++++
.../mach-rockchip/rv1103b/syscon_rv1103b.c | 19 +++
board/onion/omega4_rv1103b/Kconfig | 12 ++
board/onion/omega4_rv1103b/MAINTAINERS | 6 +
board/onion/omega4_rv1103b/Makefile | 7 +
board/onion/omega4_rv1103b/omega4_rv1103b.c | 19 +++
board/onion/omega4_rv1103b/omega4_rv1103b.env | 5 +
configs/omega4-rv1103b_defconfig | 82 +++++++++++
doc/board/index.rst | 1 +
doc/board/onion/index.rst | 9 ++
doc/board/onion/omega4-rv1103b.rst | 56 ++++++++
include/configs/omega4_rv1103b.h | 11 ++
include/configs/rv1103b_common.h | 14 ++
20 files changed, 472 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rv1103b/boot0.h
create mode 100644 arch/arm/mach-rockchip/rv1103b/Kconfig
create mode 100644 arch/arm/mach-rockchip/rv1103b/Makefile
create mode 100644 arch/arm/mach-rockchip/rv1103b/boot0.h
create mode 100644 arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c
create mode 100644 arch/arm/mach-rockchip/rv1103b/rv1103b.c
create mode 100644 arch/arm/mach-rockchip/rv1103b/syscon_rv1103b.c
create mode 100644 board/onion/omega4_rv1103b/Kconfig
create mode 100644 board/onion/omega4_rv1103b/MAINTAINERS
create mode 100644 board/onion/omega4_rv1103b/Makefile
create mode 100644 board/onion/omega4_rv1103b/omega4_rv1103b.c
create mode 100644 board/onion/omega4_rv1103b/omega4_rv1103b.env
create mode 100644 configs/omega4-rv1103b_defconfig
create mode 100644 doc/board/onion/index.rst
create mode 100644 doc/board/onion/omega4-rv1103b.rst
create mode 100644 include/configs/omega4_rv1103b.h
create mode 100644 include/configs/rv1103b_common.h
diff --git a/arch/arm/include/asm/arch-rv1103b/boot0.h b/arch/arm/include/asm/arch-rv1103b/boot0.h
new file mode 100644
index 000000000000..2e78b074ade8
--- /dev/null
+++ b/arch/arm/include/asm/arch-rv1103b/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 92bb4aa62f11..c1faeb974328 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -487,6 +487,19 @@ config ROCKCHIP_RK3588
SD3.0/MMC4.5, USB OTG 3.0, Type-C, USB 2.0, PCIe 3.0, SATA 3, Ethernet,
SDIO3.0 I2C, UART, SPI, GPIO and PWM.
+config ROCKCHIP_RV1103B
+ bool "Support Rockchip RV1103B"
+ select CPU_V7A
+ select SPL_ARMV7_SET_CORTEX_SMPEN
+ select SUPPORT_SPL
+ select SPL
+ imply ROCKCHIP_COMMON_BOARD
+
+ help
+ The Rockchip RV1103B is an ARM-based SoC with a single Cortex-A7
+ 32-bit core which integrates NEON and FPU.
+ It contains a built-in NPU for AI related applications.
+
config ROCKCHIP_RV1108
bool "Support Rockchip RV1108"
select CPU_V7A
@@ -749,6 +762,7 @@ source "arch/arm/mach-rockchip/rk3528/Kconfig"
source "arch/arm/mach-rockchip/rk3568/Kconfig"
source "arch/arm/mach-rockchip/rk3576/Kconfig"
source "arch/arm/mach-rockchip/rk3588/Kconfig"
+source "arch/arm/mach-rockchip/rv1103b/Kconfig"
source "arch/arm/mach-rockchip/rv1108/Kconfig"
source "arch/arm/mach-rockchip/rv1126/Kconfig"
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 06fb527b21a0..7bbb1697836c 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_ROCKCHIP_RK3528) += rk3528/
obj-$(CONFIG_ROCKCHIP_RK3568) += rk3568/
obj-$(CONFIG_ROCKCHIP_RK3576) += rk3576/
obj-$(CONFIG_ROCKCHIP_RK3588) += rk3588/
+obj-$(CONFIG_ROCKCHIP_RV1103B) += rv1103b/
obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/
obj-$(CONFIG_ROCKCHIP_RV1126) += rv1126/
diff --git a/arch/arm/mach-rockchip/rv1103b/Kconfig b/arch/arm/mach-rockchip/rv1103b/Kconfig
new file mode 100644
index 000000000000..6b5f5b0b9e14
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/Kconfig
@@ -0,0 +1,23 @@
+if ROCKCHIP_RV1103B
+
+
+config TARGET_OMEGA4_RV1103B
+ bool "OMEGA4_RV1103B"
+ help
+ Support Onion's Omega4 RV1103B board.
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x20160200
+
+config ROCKCHIP_STIMER_BASE
+ default 0x20500000
+
+config SYS_SOC
+ default "rv1103b"
+
+config SYS_MALLOC_F_LEN
+ default 0x400
+
+source "board/onion/omega4_rv1103b/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rv1103b/Makefile b/arch/arm/mach-rockchip/rv1103b/Makefile
new file mode 100644
index 000000000000..2f34853adac5
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/Makefile
@@ -0,0 +1,12 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rv1103b.o
+obj-y += clk_rv1103b.o
+
+ifndef CONFIG_XPL_BUILD
+obj-y += syscon_rv1103b.o
+endif
diff --git a/arch/arm/mach-rockchip/rv1103b/boot0.h b/arch/arm/mach-rockchip/rv1103b/boot0.h
new file mode 100644
index 000000000000..466ab0e80770
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/boot0.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/* Dummy boot0.h for RV1103B — SoC does not require special boot0 setup. */
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+#endif
diff --git a/arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c b/arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c
new file mode 100644
index 000000000000..2bcbb08537e8
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/clk_rv1103b.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ */
+
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1103b.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(clk_rv1103b), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rv1103b_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rv1103b/rv1103b.c b/arch/arm/mach-rockchip/rv1103b/rv1103b.c
new file mode 100644
index 000000000000..a7ff1934f7db
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/rv1103b.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2024 Rockchip Electronics Co., Ltd
+
+#include <dm.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <image.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define PERI_CRU_BASE 0x20000000
+#define PERICRU_PERISOFTRST_CON10 0x0a28
+
+#define PMU0_CRU_BASE 0x20070000
+#define PMUCRU_PMUSOFTRST_CON02 0x0a08
+
+#define GRF_SYS_BASE 0x20150000
+#define GRF_SYS_HPMCU_CACHE_MISC 0x0214
+
+#define GPIO0_IOC_BASE 0x201B0000
+#define GPIO0A_IOMUX_SEL_H 0x04
+#define GPIO0_BASE 0x20520000
+#define GPIO_SWPORT_DR_L 0x00
+#define GPIO_SWPORT_DDR_L 0x08
+
+#define GPIO1_IOC_BASE 0x20170000
+#define GPIO1A_IOMUX_SEL_0 0x20
+#define GPIO1A_IOMUX_SEL_1_0 0x24
+#define GPIO1A_IOMUX_SEL_1_1 0x10024
+#define GPIO1B_IOMUX_SEL_0 0x10028
+#define GPIO1B_IOMUX_SEL_1 0x1002c
+#define GPIO1_IOC_GPIO1A_PULL_0 0x210
+#define GPIO1_IOC_GPIO1A_PULL_1 0x10210
+#define GPIO1_IOC_GPIO1B_PULL 0x10214
+#define GPIO1_IOC_JTAG_M2_CON 0x10810
+
+#define GPIO2_IOC_BASE 0x20840000
+#define GPIO2A_IOMUX_SEL_1_1 0x44
+
+#define SGRF_SYS_BASE 0x20250000
+#define SGRF_SYS_SOC_CON2 0x0008
+#define SGRF_SYS_SOC_CON3 0x000c
+#define SGRF_SYS_OTP_CON 0x0018
+#define FIREWALL_CON0 0x0020
+#define FIREWALL_CON1 0x0024
+#define FIREWALL_CON2 0x0028
+#define FIREWALL_CON3 0x002c
+#define FIREWALL_CON4 0x0030
+#define FIREWALL_CON5 0x0034
+#define FIREWALL_CON7 0x003c
+#define SGRF_SYS_HPMCU_BOOT_DDR 0x0080
+
+#define SGRF_PMU_BASE 0x20260000
+#define SGRF_PMU_SOC_CON0 0x0000
+#define SGRF_PMU_PMUMCU_BOOT_ADDR 0x0020
+
+#define SYS_GRF_BASE 0x20150000
+#define GRF_SYS_PERI_CON2 0x08
+#define GRF_SYS_USBPHY_CON0 0x50
+
+#define TOP_CRU_BASE 0x20060000
+#define TOPCRU_CRU_GLB_RST_CON 0xc10
+
+#define USBPHY_APB_BASE 0x20e10000
+#define USBPHY_FSLS_DIFF_RECEIVER 0x0100
+
+#define RV1103B_WDT_BASE 0x208d0000
+#define RV1103B_WDT_CR 0x00
+
+void board_debug_uart_init(void)
+{
+ /* No need to change uart */
+}
+
+#ifdef CONFIG_SPL_BUILD
+void rockchip_stimer_init(void)
+{
+ /* If Timer already enabled, don't re-init it */
+ u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
+
+ if (reg & 0x1)
+ return;
+ writel(0x00010000, CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
+
+ asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r"(CONFIG_COUNTER_FREQUENCY));
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x14);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x18);
+ writel(0x00010001, CONFIG_ROCKCHIP_STIMER_BASE + 0x4);
+}
+#endif
+
+#ifndef CONFIG_TPL_BUILD
+int arch_cpu_init(void)
+{
+ /* Stop any watchdog left running by BootROM/Boot1. */
+ writel(0, RV1103B_WDT_BASE + RV1103B_WDT_CR);
+
+#if defined(CONFIG_SPL_BUILD)
+ /* Set all devices to Non-secure */
+ writel(0xffff0000, SGRF_SYS_BASE + FIREWALL_CON0);
+ writel(0xffff0000, SGRF_SYS_BASE + FIREWALL_CON1);
+ writel(0xffff0000, SGRF_SYS_BASE + FIREWALL_CON2);
+ writel(0xffff0000, SGRF_SYS_BASE + FIREWALL_CON3);
+ writel(0xffff0000, SGRF_SYS_BASE + FIREWALL_CON4);
+ writel(0xffff0000, SGRF_SYS_BASE + FIREWALL_CON5);
+ writel(0x01f00000, SGRF_SYS_BASE + FIREWALL_CON7);
+ /* Set OTP to none secure mode */
+ writel(0x00020000, SGRF_SYS_BASE + SGRF_SYS_OTP_CON);
+
+ /* no-secure WDT reset output will reset SoC system. */
+ writel(0x00010001, SYS_GRF_BASE + GRF_SYS_PERI_CON2);
+ /* secure WDT reset output will reset SoC system. */
+ writel(0x00010001, SGRF_SYS_BASE + SGRF_SYS_SOC_CON2);
+ /*
+ * enable tsadc trigger global reset and select first reset.
+ * enable global reset and wdt trigger pmu reset.
+ * select first reset trigger pmu reset.
+ */
+ writel(0x0000ffdf, TOP_CRU_BASE + TOPCRU_CRU_GLB_RST_CON);
+
+ /*
+ * Set the USB2 PHY in suspend mode and turn off the
+ * USB2 PHY FS/LS differential receiver to save power:
+ * VCC1V8_USB : reduce 3.8 mA
+ * VDD_0V9 : reduce 4.4 mA
+ */
+ writel(0x01ff01d1, SYS_GRF_BASE + GRF_SYS_USBPHY_CON0);
+ writel(0x00000000, USBPHY_APB_BASE + USBPHY_FSLS_DIFF_RECEIVER);
+#endif
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rv1103b/syscon_rv1103b.c b/arch/arm/mach-rockchip/rv1103b/syscon_rv1103b.c
new file mode 100644
index 000000000000..545b4d8ebe12
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/syscon_rv1103b.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rv1103b_syscon_ids[] = {
+ { .compatible = "rockchip,rv1103b-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rv1103b) = {
+ .name = "rv1103b_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1103b_syscon_ids,
+};
diff --git a/board/onion/omega4_rv1103b/Kconfig b/board/onion/omega4_rv1103b/Kconfig
new file mode 100644
index 000000000000..43b126c20e9c
--- /dev/null
+++ b/board/onion/omega4_rv1103b/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_OMEGA4_RV1103B
+
+config SYS_BOARD
+ default "omega4_rv1103b"
+
+config SYS_VENDOR
+ default "onion"
+
+config SYS_CONFIG_NAME
+ default "omega4_rv1103b"
+
+endif
diff --git a/board/onion/omega4_rv1103b/MAINTAINERS b/board/onion/omega4_rv1103b/MAINTAINERS
new file mode 100644
index 000000000000..53d774535bdd
--- /dev/null
+++ b/board/onion/omega4_rv1103b/MAINTAINERS
@@ -0,0 +1,6 @@
+OMEGA4 RV1103B
+M: Fabio Estevam <festevam@nabladev.com>
+S: Maintained
+F: board/onion/omega4_rv1103b
+F: include/configs/omega4_rv1103b.h
+F: configs/omega4-rv1103b_defconfig
diff --git a/board/onion/omega4_rv1103b/Makefile b/board/onion/omega4_rv1103b/Makefile
new file mode 100644
index 000000000000..afa0a7f7a932
--- /dev/null
+++ b/board/onion/omega4_rv1103b/Makefile
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2026 Fabio Estevam <festevam@nabladev.com>
+#
+
+obj-y += omega4_rv1103b.o
diff --git a/board/onion/omega4_rv1103b/omega4_rv1103b.c b/board/onion/omega4_rv1103b/omega4_rv1103b.c
new file mode 100644
index 000000000000..9bdec3c396a8
--- /dev/null
+++ b/board/onion/omega4_rv1103b/omega4_rv1103b.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2026 Fabio Estevam <festevam@nabladev.com>
+
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ gd->ram_size = SZ_256M;
+
+ return 0;
+}
+
+phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
+{
+ return gd->ram_top;
+}
diff --git a/board/onion/omega4_rv1103b/omega4_rv1103b.env b/board/onion/omega4_rv1103b/omega4_rv1103b.env
new file mode 100644
index 000000000000..7ed232cab916
--- /dev/null
+++ b/board/onion/omega4_rv1103b/omega4_rv1103b.env
@@ -0,0 +1,5 @@
+kernel_addr_r=0x00800000
+fdt_addr_r=0x02000000
+ramdisk_addr_r=0x04000000
+bootargs=console=ttyS0,115200 mtdparts=spi1.0:256K(env),1M@256K(idblock),1M(uboot),8M(boot),-(ubi) ro rootwait ubi.mtd=ubi ubi.block=0,rootfs root=/dev/ubiblock0_0 rootfstype=squashfs
+bootcmd=mtd read spi-nand0 0x04000000 0x240000 0x800000;imxtract 0x04000000 kernel 0x00800000; imxtract 0x04000000 fdt 0x02000000; bootz 0x00800000 - 0x02000000
diff --git a/configs/omega4-rv1103b_defconfig b/configs/omega4-rv1103b_defconfig
new file mode 100644
index 000000000000..b1e8ede1cf6e
--- /dev/null
+++ b/configs/omega4-rv1103b_defconfig
@@ -0,0 +1,82 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_SYS_ARCH_TIMER=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00200000
+CONFIG_SYS_MALLOC_F_LEN=0x80000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x00400000
+CONFIG_SF_DEFAULT_SPEED=24000000
+CONFIG_DEFAULT_DEVICE_TREE="rv1103b-omega4"
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
+CONFIG_ROCKCHIP_RV1103B=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_ROCKCHIP_EXTERNAL_TPL=y
+CONFIG_SPL_SERIAL=y
+CONFIG_TARGET_OMEGA4_RV1103B=y
+CONFIG_SYS_BOOTM_LEN=0x04000000
+CONFIG_SYS_LOAD_ADDR=0x00008000
+CONFIG_SF_DEFAULT_BUS=1
+CONFIG_DEBUG_UART_BASE=0x20540000
+CONFIG_DEBUG_UART_CLOCK=24000000
+# CONFIG_DEBUG_UART_BOARD_INIT is not set
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_FIT_CIPHER=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_BEST_MATCH=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_BOOTDELAY=1
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_SPL_NO_BSS_LIMIT=y
+CONFIG_SPL_MTD=y
+CONFIG_SPL_SPI_NAND_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x140000
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+CONFIG_NO_NET=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+# CONFIG_MMC is not set
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PINCTRL_ROCKCHIP_RV1103B=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_ROCKCHIP_SFC=y
+CONFIG_SYSRESET=y
+# CONFIG_RSA is not set
+# CONFIG_SPL_SHA1 is not set
+# CONFIG_SPL_SHA256 is not set
+CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
+CONFIG_ERRNO_STR=y
diff --git a/doc/board/index.rst b/doc/board/index.rst
index 7870f1bc2461..d859f8a22bfe 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -45,6 +45,7 @@ Board-specific doc
motorola/index
nvidia/index
nxp/index
+ onion/index
openpiton/index
ouya/index
pegatron/index
diff --git a/doc/board/onion/index.rst b/doc/board/onion/index.rst
new file mode 100644
index 000000000000..2e106c8b7734
--- /dev/null
+++ b/doc/board/onion/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Onion
+=====
+
+.. toctree::
+ :maxdepth: 2
+
+ omega4-rv1103b
diff --git a/doc/board/onion/omega4-rv1103b.rst b/doc/board/onion/omega4-rv1103b.rst
new file mode 100644
index 000000000000..41c64f40d6c4
--- /dev/null
+++ b/doc/board/onion/omega4-rv1103b.rst
@@ -0,0 +1,56 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Onion Omega4 RV1103B board
+==========================
+
+U-Boot for the Onion Omega4 RV1103B board
+
+Quick Start
+-----------
+
+- Get the DDR initialization binary
+- Build U-Boot
+- Flash U-Boot into the SPI NAND
+
+Get the DDR initialization binary
+---------------------------------
+
+.. code-block:: bash
+
+ $ git clone https://github.com/rockchip-linux/rkbin.git
+
+The RV1103B DDR initialization is located at rkbin/bin/rv11/rv1103bb_ddr_924MHz_v1.05.bin
+
+Build U-Boot
+------------
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
+ $ export ROCKCHIP_TPL=<path-to-rkbin>/bin/rv11/rv1103bb_ddr_924MHz_v1.05.bin
+ $ make omega4-rv1103b_defconfig
+ $ make
+
+The idbloader-spi.img and u-boot.img are the binaries that need to be flashed
+into the SPI NAND.
+
+Flash U-Boot into the SPI NAND
+------------------------------
+
+Connect the USB OTG and UART console cables from the Omega4 board to
+the host PC.
+
+Press the BOOT button while applying power to the board.
+
+The string "RKUART" should appear on the console (115200,8N1).
+
+Install the rkdeveloptool from https://github.com/rockchip-linux/rkdeveloptool
+by following the instruction in the README file.
+
+.. code-block:: bash
+
+ $ sudo ./rkdeveloptool db download.bin
+ $ sudo ./rkdeveloptool wl 0x200 idbloader.img
+ $ sudo ./rkdeveloptool wl 0xa00 u-boot.img
+
+Power cycle the board and U-Boot output is seen on the console.
diff --git a/include/configs/omega4_rv1103b.h b/include/configs/omega4_rv1103b.h
new file mode 100644
index 000000000000..8430b0b4d091
--- /dev/null
+++ b/include/configs/omega4_rv1103b.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/rv1103b_common.h>
+
+#endif
diff --git a/include/configs/rv1103b_common.h b/include/configs/rv1103b_common.h
new file mode 100644
index 000000000000..8e970d710514
--- /dev/null
+++ b/include/configs/rv1103b_common.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+#ifndef __CONFIG_RV1103B_COMMON_H
+#define __CONFIG_RV1103B_COMMON_H
+
+#include "rockchip-common.h"
+#include <config_distro_bootcmd.h>
+
+#define CFG_IRAM_BASE 0x210f6000
+#define CFG_SYS_SDRAM_BASE 0x00000000
+
+#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 6/7] spl: add SPI NAND support via MTD in SPL
2026-02-08 21:26 ` [PATCH v2 6/7] spl: add SPI NAND support via MTD in SPL Fabio Estevam
@ 2026-02-08 23:47 ` Jonas Karlman
0 siblings, 0 replies; 12+ messages in thread
From: Jonas Karlman @ 2026-02-08 23:47 UTC (permalink / raw)
To: Fabio Estevam; +Cc: kever.yang, trini, u-boot, Fabio Estevam
Hi Fabio,
On 2/8/2026 10:26 PM, Fabio Estevam wrote:
> From: Fabio Estevam <festevam@nabladev.com>
>
> Add support for booting U-Boot SPL from SPI NAND devices
> using the MTD subsystem.
>
> - Introduce CONFIG_SPL_SPI_NAND_LOAD to enable SPL loading
> from SPI NAND flash.
> - Implement spl_spi_nand.c as a dedicated SPL loader that
> reads the FIT image from SPI NAND via MTD.
> - Update common/spl/Kconfig and Makefiles to include the
> new loader in SPL builds.
> - Adjust drivers/mtd/Makefile and drivers/mtd/nand/Makefile
> to build the necessary SPI NAND MTD objects only when
> CONFIG_SPL_SPI_NAND_LOAD is enabled, avoiding size impact
> on other boards.
>
> This allows boards like the Omega4 RV1103 to boot SPL directly
> from SPI NAND, keeping the SPL small and avoiding unnecessary
> inclusion of SPI NOR code.
The content in this patch seem very generic and could possible be sent
as a separate series that adds a generic SPL MTD loader.
There also seem to be another SPL NAND loader part of the series at [1]
that may be related.
[1] https://lore.kernel.org/all/20260129050446.8858-1-dinesh.maniyam@altera.com/
>
> Signed-off-by: Fabio Estevam <festevam@nabladev.com>
> ---
> Changes since v1:
> - None.
>
> common/spl/Kconfig | 10 ++++-
> common/spl/Makefile | 1 +
> common/spl/spl_spi_nand.c | 82 +++++++++++++++++++++++++++++++++++++++
> drivers/mtd/Makefile | 1 +
> drivers/mtd/nand/Makefile | 13 ++++++-
> 5 files changed, 105 insertions(+), 2 deletions(-)
> create mode 100644 common/spl/spl_spi_nand.c
>
> diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> index 2998b7acb75f..126855b804ce 100644
> --- a/common/spl/Kconfig
> +++ b/common/spl/Kconfig
> @@ -1576,13 +1576,21 @@ config SPL_SPI_LOAD
> Enable support for loading next stage, U-Boot or otherwise, from
> SPI NOR in U-Boot SPL.
>
> +config SPL_SPI_NAND_LOAD
> + bool "Support loading from SPI NAND flash"
> + depends on SPL
> + depends on MTD && DM_MTD
> + help
> + Enable support for loading next stage, U-Boot or otherwise, from
> + SPI NAND in U-Boot SPL.
> +
> endif # SPL_SPI_FLASH_SUPPORT
>
> config SYS_SPI_U_BOOT_OFFS
> hex "address of u-boot payload in SPI flash"
> default 0x8000 if ARCH_SUNXI
> default 0x0
> - depends on SPL_SPI_LOAD || SPL_SPI_SUNXI
> + depends on SPL_SPI_LOAD || SPL_SPI_NAND_LOAD || SPL_SPI_SUNXI
> help
> Address within SPI-Flash from where the u-boot payload is fetched
> from.
> diff --git a/common/spl/Makefile b/common/spl/Makefile
> index 4c9482bd3096..4628902e7e31 100644
> --- a/common/spl/Makefile
> +++ b/common/spl/Makefile
> @@ -35,6 +35,7 @@ obj-$(CONFIG_$(PHASE_)NVME) += spl_nvme.o
> obj-$(CONFIG_$(PHASE_)SEMIHOSTING) += spl_semihosting.o
> obj-$(CONFIG_$(PHASE_)DFU) += spl_dfu.o
> obj-$(CONFIG_$(PHASE_)SPI_LOAD) += spl_spi.o
> +obj-$(CONFIG_$(PHASE_)SPI_NAND_LOAD) += spl_spi_nand.o
> obj-$(CONFIG_$(PHASE_)RAM_SUPPORT) += spl_ram.o
> obj-$(CONFIG_$(PHASE_)USB_SDP_SUPPORT) += spl_sdp.o
> endif
> diff --git a/common/spl/spl_spi_nand.c b/common/spl/spl_spi_nand.c
> new file mode 100644
> index 000000000000..20b877f75a05
> --- /dev/null
> +++ b/common/spl/spl_spi_nand.c
> @@ -0,0 +1,82 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * SPL loader for SPI NAND devices using the MTD subsystem.
> + *
> + * Based on spl_spi.c, which is:
> + *
> + * Copyright (C) 2011 OMICRON electronics GmbH
> + *
> + * based on drivers/mtd/nand/raw/nand_spl_load.c
> + *
> + * Copyright (C) 2011
> + * Heiko Schocher, DENX Software Engineering, hs@denx.de.
> + */
> +
> +#include <config.h>
> +#include <image.h>
> +#include <log.h>
> +#include <errno.h>
> +#include <spl.h>
> +#include <spl_load.h>
> +#include <asm/io.h>
> +#include <dm/device_compat.h>
> +#include <dm/ofnode.h>
> +#include <dm/uclass.h>
> +#include <mtd.h>
> +
> +static struct mtd_info *spl_spi_nand_get_mtd(void)
> +{
> + struct udevice *dev;
> + int ret;
> +
> + for (ret = uclass_first_device_err(UCLASS_MTD, &dev);
> + dev;
> + ret = uclass_next_device_err(&dev)) {
> + if (ret)
> + continue;
> + if (device_is_compatible(dev, "spi-nand"))
> + return dev_get_uclass_priv(dev);
Is there a reason why you limit this to only spi-nand?
I think it would be better to pivot this into a more generic SPL MTD
loader.
> + }
> +
> + return NULL;
> +}
> +
> +static ulong spl_spinand_fit_read(struct spl_load_info *load, ulong offs,
> + ulong size, void *buf)
The _fit_ part can probably be dropped.
> +{
> + struct mtd_info *mtd = load->priv;
> + size_t retlen = 0;
> + int ret;
> +
> + ret = mtd_read(mtd, offs, size, &retlen, buf);
> + if (ret && ret != -EUCLEAN) {
Maybe use mtd_is_bitflip(ret)
> + printf("SPI NAND read failed offs=0x%lx size=0x%lx ret=%d\n",
> + offs, size, ret);
> + return 0;
> + }
> + if (retlen != size)
Why do we need an error message above and not here?
> + return 0;
> +
> + return retlen;
> +}
> +
> +static int spl_spinand_load_image(struct spl_image_info *spl_image,
> + struct spl_boot_device *bootdev)
> +{
> + struct spl_load_info load;
> + struct mtd_info *mtd;
> +
> + mtd = spl_spi_nand_get_mtd();
> + if (!mtd) {
> + puts("SPI NAND probe failed.\n");
> + return -ENODEV;
> + }
> +
> + spl_load_init(&load, spl_spinand_fit_read, mtd, 1);
Should probably use mtd->writesize as bl_len.
spl_load_init(&load, spl_mtd_read, mtd, mtd->writesize);
> +
> + return spl_load(spl_image, bootdev, &load, 0, CONFIG_SYS_SPI_U_BOOT_OFFS);
Suggest you could use something like following to closer match SPL flash.
offset = CONFIG_SYS_SPI_U_BOOT_OFFS;
if (CONFIG_IS_ENABLED(OF_REAL))
offset = ofnode_conf_read_int("u-boot,spl-payload-offset",
offset);
return spl_load(spl_image, bootdev, &load, 0, offset);
> +}
> +
> +/* Use priority 1 so that boards can override this */
> +SPL_LOAD_IMAGE_METHOD("SPI NAND", 1, BOOT_DEVICE_SPI, spl_spinand_load_image);
> diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
> index ce05e206073d..a12d880a9e90 100644
> --- a/drivers/mtd/Makefile
> +++ b/drivers/mtd/Makefile
> @@ -34,6 +34,7 @@ else
> ifneq ($(mtd-y),)
> obj-$(CONFIG_SPL_MTD) += mtd.o
> endif
> +obj-$(CONFIG_SPL_SPI_NAND_LOAD) += nand/
> obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += nand/
> obj-$(CONFIG_SPL_ONENAND_SUPPORT) += onenand/
> obj-$(CONFIG_$(PHASE_)SPI_FLASH_SUPPORT) += spi/
> diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
> index c8169cf73902..7cd2a5f1af9b 100644
> --- a/drivers/mtd/nand/Makefile
> +++ b/drivers/mtd/nand/Makefile
> @@ -1,10 +1,21 @@
> # SPDX-License-Identifier: GPL-2.0+
>
> -ifeq ($(CONFIG_XPL_BUILD)$(CONFIG_TPL_BUILD),)
> nandcore-objs := core.o bbt.o
> +
> +ifeq ($(CONFIG_XPL_BUILD)$(CONFIG_TPL_BUILD),)
Having both XPL and TPL is redundant and could be cleaned up to just
have ($(CONFIG_XPL_BUILD),).
Regards,
Jonas
> +
> +# U-Boot proper
> obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
> obj-$(CONFIG_MTD_RAW_NAND) += raw/
> obj-$(CONFIG_MTD_SPI_NAND) += spi/
> +
> else
> +
> +# SPL / XPL / TPL
> +# SPL has no MTD_NAND_CORE symbol, so we must key off SPI NAND usage
> +obj-$(CONFIG_SPL_SPI_NAND_LOAD) += nandcore.o
> +obj-$(CONFIG_SPL_SPI_NAND_LOAD) += spi/
> +
> +# raw NAND still follows the normal SPL rule
> obj-$(CONFIG_$(PHASE_)NAND_SUPPORT) += raw/
> endif
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 5/7] rockchip: spl-boot-order: Add SPI NAND support
2026-02-08 21:26 ` [PATCH v2 5/7] rockchip: spl-boot-order: Add SPI NAND support Fabio Estevam
@ 2026-02-09 9:56 ` Jonas Karlman
0 siblings, 0 replies; 12+ messages in thread
From: Jonas Karlman @ 2026-02-09 9:56 UTC (permalink / raw)
To: Fabio Estevam
Cc: kever.yang@rock-chips.com, trini@konsulko.com,
u-boot@lists.denx.de, Fabio Estevam
Hi Fabio,
On 2/8/2026 10:26 PM, Fabio Estevam wrote:
> From: Fabio Estevam <festevam@nabladev.com>
>
> Make spl-boot-order to accept boot from SPI NAND as well.
>
> With this change, it is possible to specify spi_nand
> as the boot medium like this:
>
> u-boot,spl-boot-order = &spi_nand;
You should probably include something like following (after DT has been
updated as per DT review) in rv1103b.c to also allow "same-as-spl" to
work.
const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
[BROM_BOOTSOURCE_EMMC] = "/soc/mmc@20d30000",
[BROM_BOOTSOURCE_SPINOR] = "/soc/spi@20d40000/flash@0",
[BROM_BOOTSOURCE_SD] = "/soc/mmc@20d20000",
};
> Signed-off-by: Fabio Estevam <festevam@nabladev.com>
> ---
> Changes since v1:
> - None.
>
> arch/arm/mach-rockchip/spl-boot-order.c | 11 +++++++++--
> 1 file changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
> index 6572dde29f65..e5897536934a 100644
> --- a/arch/arm/mach-rockchip/spl-boot-order.c
> +++ b/arch/arm/mach-rockchip/spl-boot-order.c
> @@ -4,6 +4,7 @@
> */
>
> #include <dm.h>
> +#include <dm/device_compat.h>
> #include <fdt_support.h>
> #include <log.h>
> #include <mmc.h>
> @@ -75,6 +76,8 @@ static int spl_node_to_boot_device(int node)
> */
> if (!uclass_find_device_by_of_offset(UCLASS_SPI_FLASH, node, &parent))
> return BOOT_DEVICE_SPI;
> + if (fdt_node_check_compatible(gd->fdt_blob, node, "spi-nand") == 0)
> + return BOOT_DEVICE_SPI;
I think something like following will be better:
if (!uclass_find_device_by_of_offset(UCLASS_MTD, node, &parent))
return BOOT_DEVICE_MTD;
And possible also with a protect check (should probably be fixed for
MMC/SPI_FLASH in a separate future patch/series).
if (CONFIG_IS_ENABLED(MTD_LOAD_SUPPORT) &&
!uclass_find_device_by_of_offset(UCLASS_MTD, node, &parent))
return BOOT_DEVICE_MTD;
Or whatever Kconfig option is used to ensure both UCLASS and SPL loader
is supported in the build. To avoid error messages about missing UCLASS
like following (from a different rk soc/board):
board_spl_was_booted_from: brom_bootdevice_id 3 maps to '/soc/spi@ffac0000/flash@0'
Cannot find uclass for id 119: please add the UCLASS_DRIVER() declaration for this UCLASS_... id
board_boot_order: could not map node /soc/spi@ffac0000/flash@0 to a boot-device
Cannot find uclass for id 119: please add the UCLASS_DRIVER() declaration for this UCLASS_... id
>
> return -1;
> }
> @@ -221,8 +224,12 @@ int spl_decode_boot_device(u32 boot_device, char *buf, size_t buflen)
>
> ret = uclass_find_device_by_of_offset(UCLASS_SPI_FLASH, node, &dev);
> if (ret) {
> - debug("%s: could not find udevice for %s\n", __func__, conf);
> - continue;
> + ret = uclass_find_device_by_of_offset(UCLASS_MTD, node, &dev);
> + if (ret || !device_is_compatible(dev, "spi-nand")) {
I do not think we need to check for spi-nand compatible here, make it
generic and only check for UCLASS_MTD. If the node binds to a UCLASS_MTD
driver it is likely we could use a generic SPL MTD loader that used mtd
read ops to load next stage.
With that we could possible also support SPI_FLASH_MTD and consolidate
and/or simplify SPL code, something that can be looked at in future once
we have a more generic SPL MTD loader in place.
Regards,
Jonas
> + debug("%s: could not find udevice for %s\n",
> + __func__, conf);
> + continue;
> + }
> }
>
> return ofnode_get_path(dev_ofnode(dev), buf, buflen);
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support
2026-02-08 21:26 ` [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support Fabio Estevam
@ 2026-02-09 10:45 ` Jonas Karlman
0 siblings, 0 replies; 12+ messages in thread
From: Jonas Karlman @ 2026-02-09 10:45 UTC (permalink / raw)
To: Fabio Estevam; +Cc: kever.yang, trini, u-boot, Fabio Estevam
Hi Fabio,
On 2/8/2026 10:26 PM, Fabio Estevam wrote:
> From: Fabio Estevam <festevam@nabladev.com>
>
> Add the necessary devicetrees to support the RV1103B Omega4 board.
>
> The RV1103B is a Rockchip SoC that is still not supported in Linux
> mainline.
>
> The initial RV1103B support has already been submitted to Linux kernel
> and it is under review.
>
> Once the Linux RV1103 devicetrees are upstreamed, the OF_UPSTREAM mechanism
> can be enabled.
Please address my upstream DT review and give it some more time before
adding DTs that cannot be picked to dts/upstream in U-Boot.
For the past two years the Rockchip platform has only allowed adding
arch and boards using DTs that come from dts/upstream. So please give a
good explanation why your arch/board cannot wait until that is the case
and need exception from this.
> Signed-off-by: Fabio Estevam <festevam@nabladev.com>
> ---
> Changes since v1:
> - Used the devicetrees submitted to upstream Linux.
>
> arch/arm/dts/rv1103b-omega4-u-boot.dtsi | 10 +
> arch/arm/dts/rv1103b-omega4.dts | 105 +++
> arch/arm/dts/rv1103b-pinctrl.dtsi | 831 ++++++++++++++++++
> arch/arm/dts/rv1103b-u-boot.dtsi | 4 +
> arch/arm/dts/rv1103b.dtsi | 266 ++++++
> .../dt-bindings/clock/rockchip,rv1103b-cru.h | 220 +++++
> 6 files changed, 1436 insertions(+)
> create mode 100644 arch/arm/dts/rv1103b-omega4-u-boot.dtsi
> create mode 100644 arch/arm/dts/rv1103b-omega4.dts
Please split patch 7/7 in two, one that add rv1103b arch support and a
second that add the omega4 board. Then please move the board DTs to the
patch that adds support for the omega4 board.
> create mode 100644 arch/arm/dts/rv1103b-pinctrl.dtsi
> create mode 100644 arch/arm/dts/rv1103b-u-boot.dtsi
The soc u-boot.dtsi is better to add in the patch that add rv1103b arch
support, i.e. this patch should only include DTs and headers that is a
drop in replacement for future files that are expected to land in
dts/upstream.
Regards,
Jonas
> create mode 100644 arch/arm/dts/rv1103b.dtsi
> create mode 100644 include/dt-bindings/clock/rockchip,rv1103b-cru.h
[snip]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/7] pinctrl: rockchip: Add RV1103B support
2026-02-08 21:26 ` [PATCH v2 2/7] pinctrl: rockchip: Add RV1103B support Fabio Estevam
@ 2026-02-09 10:50 ` Jonas Karlman
0 siblings, 0 replies; 12+ messages in thread
From: Jonas Karlman @ 2026-02-09 10:50 UTC (permalink / raw)
To: Fabio Estevam; +Cc: kever.yang, trini, u-boot, Ye Zhang, Fabio Estevam
Hi Fabio,
On 2/8/2026 10:26 PM, Fabio Estevam wrote:
> From: Ye Zhang <ye.zhang@rock-chips.com>
>
> Add pinctrl driver for RV1103.
>
> Signed-off-by: Ye Zhang <ye.zhang@rock-chips.com>
> Signed-off-by: Fabio Estevam <festevam@nabladev.com>
> ---
> Changes since v1:
> - Use the original author from Rockchip's vendor U-Boot tree.
> - Use regmap_update_bits()
> - Removed unneeded blank lines.
> - Removed unneeded logging functions.
>
> drivers/pinctrl/rockchip/Makefile | 1 +
> drivers/pinctrl/rockchip/pinctrl-rv1103b.c | 398 +++++++++++++++++++++
> 2 files changed, 399 insertions(+)
> create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1103b.c
>
> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> index e17415e1ca68..2bbee66bd3ca 100644
> --- a/drivers/pinctrl/rockchip/Makefile
> +++ b/drivers/pinctrl/rockchip/Makefile
> @@ -18,5 +18,6 @@ obj-$(CONFIG_ROCKCHIP_RK3528) += pinctrl-rk3528.o
> obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
> obj-$(CONFIG_ROCKCHIP_RK3576) += pinctrl-rk3576.o
> obj-$(CONFIG_ROCKCHIP_RK3588) += pinctrl-rk3588.o
> +obj-$(CONFIG_ROCKCHIP_RV1103B) += pinctrl-rv1103b.o
> obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
> obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o
> diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1103b.c b/drivers/pinctrl/rockchip/pinctrl-rv1103b.c
> new file mode 100644
> index 000000000000..fb946b036661
> --- /dev/null
> +++ b/drivers/pinctrl/rockchip/pinctrl-rv1103b.c
> @@ -0,0 +1,398 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2024 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <dm.h>
> +#include <log.h>
> +#include <dm/pinctrl.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +#include <linux/bitops.h>
> +
> +#include "pinctrl-rockchip.h"
> +
> +static int rv1103b_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
> +{
> + struct rockchip_pinctrl_priv *priv = bank->priv;
> + int iomux_num = (pin / 8);
> + struct regmap *regmap;
> + u32 data, rmask;
> + int reg, mask;
> + u8 bit;
> +
> + if (bank->bank_num == 2 && pin >= 12)
> + return 0;
> +
> + regmap = priv->regmap_base;
> + reg = bank->iomux[iomux_num].offset;
> + if ((pin % 8) >= 4)
> + reg += 0x4;
> + bit = (pin % 4) * 4;
> + mask = 0xf;
> +
> + if (bank->recalced_mask & BIT(pin))
> + rockchip_get_recalced_mux(bank, pin, ®, &bit, &mask);
> + data = (mask << (bit + 16));
> + rmask = data | (data >> 16);
> + data |= (mux & mask) << bit;
> +
> + return regmap_update_bits(regmap, reg, rmask, data);
This seem to have been updated to use regmap_update_bits(), thanks.
> +}
> +
> +#define RV1103_DRV_BITS_PER_PIN 8
> +#define RV1103_DRV_PINS_PER_REG 2
> +#define RV1103_DRV_GPIO0_A_OFFSET 0x40100
> +#define RV1103_DRV_GPIO0_B_OFFSET 0x50110
> +#define RV1103_DRV_GPIO1_A01_OFFSET 0x140
> +#define RV1103_DRV_GPIO1_A67_OFFSET 0x1014C
> +#define RV1103_DRV_GPIO2_OFFSET 0x30180
> +#define RV1103_DRV_GPIO2_SARADC_OFFSET 0x3080C
> +
> +static int rv1103b_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> + int pin_num, struct regmap **regmap,
> + int *reg, u8 *bit)
> +{
> + struct rockchip_pinctrl_priv *priv = bank->priv;
> + int ret = 0;
> +
> + *regmap = priv->regmap_base;
> + switch (bank->bank_num) {
> + case 0:
> + if (pin_num < 7)
> + *reg = RV1103_DRV_GPIO0_A_OFFSET;
> + else if (pin_num > 7 && pin_num < 14)
> + *reg = RV1103_DRV_GPIO0_B_OFFSET - 0x10;
> + else
> + ret = -EINVAL;
> + break;
> +
> + case 1:
> + if (pin_num < 6)
> + *reg = RV1103_DRV_GPIO1_A01_OFFSET;
> + else if (pin_num >= 6 && pin_num < 23)
> + *reg = RV1103_DRV_GPIO1_A67_OFFSET - 0xc;
> + else if (pin_num >= 24 && pin_num < 30)
> + *reg = RV1103_DRV_GPIO1_A67_OFFSET - 0xc;
> + else
> + ret = -EINVAL;
> + break;
> +
> + case 2:
> + if (pin_num < 12) {
> + *reg = RV1103_DRV_GPIO2_OFFSET;
> + } else if (pin_num >= 16) {
> + ret = -EINVAL;
> + } else {
> + *reg = RV1103_DRV_GPIO2_SARADC_OFFSET;
> + *bit = 10;
> +
> + return 0;
> + }
> + break;
> +
> + default:
> + ret = -EINVAL;
> + break;
> + }
> +
> + if (ret) {
> + printf("unsupported bank_num %d pin_num %d\n", bank->bank_num, pin_num);
> + return ret;
> + }
> +
> + *reg += ((pin_num / RV1103_DRV_PINS_PER_REG) * 4);
> + *bit = pin_num % RV1103_DRV_PINS_PER_REG;
> + *bit *= RV1103_DRV_BITS_PER_PIN;
> +
> + return 0;
> +}
> +
> +static int rv1103b_set_drive(struct rockchip_pin_bank *bank,
> + int pin_num, int strength)
> +{
> + struct regmap *regmap;
> + int reg, ret, i;
> + u32 data;
> + u8 bit;
> + int rmask_bits = RV1103_DRV_BITS_PER_PIN;
> +
> + ret = rv1103b_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
> + if (ret)
> + return ret;
> +
> + for (i = 0, ret = 1; i < strength; i++)
> + ret = (ret << 1) | 1;
> +
> + if (bank->bank_num == 2 && pin_num >= 12) {
> + rmask_bits = 2;
> + ret = strength;
> + }
> +
> + /* Enable the write to the equivalent lower bits */
> + data = ((1 << rmask_bits) - 1) << (bit + 16);
> + data |= (ret << bit);
> + return regmap_write(regmap, reg, data);
However, this and all remaining places still use regmap_write, please
change all instances of regmap_write to use regmap_update_bits.
This ensure the pins configuration in DT cannot overflow the fields,
that is something that has happened in the past and is why I ensure all
new rk pinctrl drivers matches Linux kernel and use regmap_update_bits
instead of regmap_write.
Regards,
Jonas
> +}
[snip]
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-02-09 10:50 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-08 21:26 [PATCH v2 0/7] ARM: Add RV1103B Omega4 board support Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 1/7] ARM: dts: Add RV1103B Omega4 support Fabio Estevam
2026-02-09 10:45 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 2/7] pinctrl: rockchip: Add RV1103B support Fabio Estevam
2026-02-09 10:50 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 3/7] clk: rockchip: Add RV1103B clock driver Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 4/7] tools: rkcommon: Add RV1103B support Fabio Estevam
2026-02-08 21:26 ` [PATCH v2 5/7] rockchip: spl-boot-order: Add SPI NAND support Fabio Estevam
2026-02-09 9:56 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 6/7] spl: add SPI NAND support via MTD in SPL Fabio Estevam
2026-02-08 23:47 ` Jonas Karlman
2026-02-08 21:26 ` [PATCH v2 7/7] omega4-rv1103b: Add the initial support Fabio Estevam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox