* [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106
@ 2026-07-07 15:30 Simon Glass
2026-07-07 15:30 ` [PATCH v3 01/15] ARM: dts: Add the RV1103B devicetree files Simon Glass
` (15 more replies)
0 siblings, 16 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:30 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Albert Aribaud,
Alexander Feilke, Alexey Charkov, Alexey Charkov, Andrew Davis,
Anshul Dalal, Bastien Curutchet, Chris Morgan, Chris Packham,
Elaine Zhang, FUKAUMI Naoki, Finley Xiao, Heinrich Schuchardt,
Hrushikesh Salunke, Ilias Apalodimas, Jeffy Chen, Johan Jonker,
João Marcos Costa, Kever Yang, Lukasz Majewski,
Mattijs Korpershoek, Neil Armstrong, Niu Zhihong, Peng Fan,
Peter Robinson, Philipp Tomsich, Quentin Schulz, Richard Genoud,
Svyatoslav Ryhel, Tianling Shen, Tom Rini, Xuhui Lin, Ye Zhang,
huang lin
This series adds support for three small Rockchip camera SoCs and two
boards which use them.
The first eight patches are Fabio Estevam's series adding the RV1103B
and the Onion Omega4 board, updated here to address the review
comments on v2: the board patch is split into SoC and board patches,
the devicetree files move into the patches where they belong and the
pinctrl driver uses regmap_update_bits() throughout. All credit for
this work goes to Fabio. The devicetree concern raised in the v2
review is also resolved now: the devicetree files carried here are the
versions merged in Linux v7.1, verbatim, and can be dropped once the
next dts/upstream sync brings them in.
The remaining patches add the RV1106 and its RV1103 package variant,
following the same structure as the RV1103B patches, together with
the Luckfox Pico Mini B board. These SoCs have no mainline Linux
support yet, so their devicetrees are local for now. The clock and
pinctrl drivers are ported from the Rockchip vendor tree and are the
work of Elaine Zhang and Ye Zhang. The final patch makes the
maskrom-mode RAM-boot images work on 32-bit boards without OP-TEE,
which both of these boards rely on.
Tested on the Luckfox Pico Mini B: U-Boot runs from RAM over the USB
maskrom path and both the SPI NAND and a microSD card are usable. THe
board is running in my lab.
Changes in v3:
- Move the board devicetrees to the board patch and the SoC u-boot.dtsi
to the SoC patch (Jonas)
- Use the devicetree files as merged in Linux v7.1
- Use regmap_update_bits() in all the remaining places (Jonas)
- Align continuation lines with the open parenthesis (checkpatch)
- Use CONFIG_IS_ENABLED() to guard the set_parent operation, matching
clk_rk3588.c, since plain IS_ENABLED() needs the CONFIG_ prefix
- Guard the spi-nand checks with SPI_NAND_LOAD so that boards without
SPI NAND support do not grow in size
- New patch, split out from the board patch (Jonas)
- Include the SoC u-boot.dtsi here (Jonas)
- Match the pmu-grf compatible used by the devicetree merged in Linux
v7.1
- Split out the SoC support into its own patch (Jonas)
- Move the board devicetree files into this patch (Jonas)
- Add the board to the list in the Rockchip documentation
- Extend the MAINTAINERS entry to cover all the RV1103B files
- Use the board devicetree files as merged in Linux v7.1 and switch
the default devicetree to rv1103b-omega4-evb
Changes in v2:
- Use the devicetrees submitted to upstream Linux
- Use the original author from Rockchip's vendor U-Boot tree
- Use regmap_update_bits()
- Remove unneeded blank lines
- Remove unneeded logging functions
- Use the original author from Rockchip's vendor U-Boot tree
- Use RV1103B rather than RV1103, which is the correct SoC name
Elaine Zhang (1):
clk: rockchip: Add RV1103B clock driver
Fabio Estevam (5):
ARM: dts: Add the RV1103B devicetree files
rockchip: spl-boot-order: Add SPI NAND support
spl: Add SPI NAND support via MTD in SPL
rockchip: rv1103b: Add SoC support
omega4-rv1103b: Add the initial support
Simon Glass (7):
tools: rkcommon: Add RV1106 support
pinctrl: rockchip: Add RV1106 support
ARM: dts: Add the RV1103/RV1106 devicetree files
clk: rockchip: Add RV1106 clock driver
rockchip: rv1106: Add SoC support
luckfox-pico: Add the initial support
rockchip: Support legacy images when booting from RAM
Xuhui Lin (1):
tools: rkcommon: Add RV1103B support
Ye Zhang (1):
pinctrl: rockchip: Add RV1103B support
.../rv1103-luckfox-pico-mini-b-u-boot.dtsi | 10 +
arch/arm/dts/rv1103-luckfox-pico-mini-b.dts | 85 ++
arch/arm/dts/rv1103.dtsi | 16 +
arch/arm/dts/rv1103b-omega4-evb-u-boot.dtsi | 10 +
arch/arm/dts/rv1103b-omega4-evb.dts | 63 +
arch/arm/dts/rv1103b-omega4.dtsi | 147 ++
arch/arm/dts/rv1103b-pinctrl.dtsi | 816 ++++++++++
arch/arm/dts/rv1103b-u-boot.dtsi | 4 +
arch/arm/dts/rv1103b.dtsi | 239 +++
arch/arm/dts/rv1106-pinctrl.dtsi | 1102 ++++++++++++++
arch/arm/dts/rv1106-u-boot.dtsi | 4 +
arch/arm/dts/rv1106.dtsi | 328 ++++
.../include/asm/arch-rockchip/cru_rv1103b.h | 266 ++++
.../include/asm/arch-rockchip/cru_rv1106.h | 305 ++++
.../include/asm/arch-rockchip/grf_rv1103b.h | 31 +
arch/arm/include/asm/arch-rv1103b/boot0.h | 11 +
arch/arm/include/asm/arch-rv1106/boot0.h | 11 +
arch/arm/mach-rockchip/Kconfig | 28 +
arch/arm/mach-rockchip/Makefile | 2 +
arch/arm/mach-rockchip/rv1103b/Kconfig | 22 +
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/rv1106/Kconfig | 28 +
arch/arm/mach-rockchip/rv1106/Makefile | 12 +
arch/arm/mach-rockchip/rv1106/clk_rv1106.c | 31 +
arch/arm/mach-rockchip/rv1106/rv1106.c | 118 ++
arch/arm/mach-rockchip/rv1106/syscon_rv1106.c | 19 +
arch/arm/mach-rockchip/spl-boot-order.c | 12 +-
arch/arm/mach-rockchip/spl.c | 53 +-
board/luckfox/pico/Kconfig | 12 +
board/luckfox/pico/MAINTAINERS | 6 +
board/luckfox/pico/Makefile | 7 +
board/luckfox/pico/pico.c | 19 +
board/luckfox/pico/pico.env | 4 +
board/onion/omega4_rv1103b/Kconfig | 12 +
board/onion/omega4_rv1103b/MAINTAINERS | 15 +
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/luckfox-pico-mini-b-rv1103_defconfig | 79 +
configs/omega4-rv1103b_defconfig | 82 +
doc/board/index.rst | 2 +
doc/board/luckfox/index.rst | 9 +
doc/board/luckfox/luckfox-pico.rst | 71 +
doc/board/onion/index.rst | 9 +
doc/board/onion/omega4-rv1103b.rst | 56 +
doc/board/rockchip/rockchip.rst | 7 +
drivers/clk/rockchip/Makefile | 2 +
drivers/clk/rockchip/clk_rv1103b.c | 1068 +++++++++++++
drivers/clk/rockchip/clk_rv1106.c | 1319 +++++++++++++++++
drivers/mtd/Makefile | 1 +
drivers/mtd/nand/Makefile | 13 +-
drivers/pinctrl/rockchip/Makefile | 2 +
drivers/pinctrl/rockchip/pinctrl-rv1103b.c | 402 +++++
drivers/pinctrl/rockchip/pinctrl-rv1106.c | 320 ++++
include/configs/luckfox_pico.h | 11 +
include/configs/omega4_rv1103b.h | 11 +
include/configs/rv1103b_common.h | 14 +
include/configs/rv1106_common.h | 13 +
.../dt-bindings/clock/rockchip,rv1103b-cru.h | 220 +++
include/dt-bindings/clock/rv1106-cru.h | 572 +++++++
tools/rkcommon.c | 2 +
68 files changed, 8436 insertions(+), 22 deletions(-)
create mode 100644 arch/arm/dts/rv1103-luckfox-pico-mini-b-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103-luckfox-pico-mini-b.dts
create mode 100644 arch/arm/dts/rv1103.dtsi
create mode 100644 arch/arm/dts/rv1103b-omega4-evb-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103b-omega4-evb.dts
create mode 100644 arch/arm/dts/rv1103b-omega4.dtsi
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/dts/rv1106-pinctrl.dtsi
create mode 100644 arch/arm/dts/rv1106-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1106.dtsi
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rv1103b.h
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rv1106.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/include/asm/arch-rv1106/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 arch/arm/mach-rockchip/rv1106/Kconfig
create mode 100644 arch/arm/mach-rockchip/rv1106/Makefile
create mode 100644 arch/arm/mach-rockchip/rv1106/clk_rv1106.c
create mode 100644 arch/arm/mach-rockchip/rv1106/rv1106.c
create mode 100644 arch/arm/mach-rockchip/rv1106/syscon_rv1106.c
create mode 100644 board/luckfox/pico/Kconfig
create mode 100644 board/luckfox/pico/MAINTAINERS
create mode 100644 board/luckfox/pico/Makefile
create mode 100644 board/luckfox/pico/pico.c
create mode 100644 board/luckfox/pico/pico.env
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/luckfox-pico-mini-b-rv1103_defconfig
create mode 100644 configs/omega4-rv1103b_defconfig
create mode 100644 doc/board/luckfox/index.rst
create mode 100644 doc/board/luckfox/luckfox-pico.rst
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/clk/rockchip/clk_rv1106.c
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1103b.c
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1106.c
create mode 100644 include/configs/luckfox_pico.h
create mode 100644 include/configs/omega4_rv1103b.h
create mode 100644 include/configs/rv1103b_common.h
create mode 100644 include/configs/rv1106_common.h
create mode 100644 include/dt-bindings/clock/rockchip,rv1103b-cru.h
create mode 100644 include/dt-bindings/clock/rv1106-cru.h
---
base-commit: ee5d46b45ec0c63f8f9dd1e816e0dac3452ccc3d
branch: rocka-us3
--
2.43.0
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v3 01/15] ARM: dts: Add the RV1103B devicetree files
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
@ 2026-07-07 15:30 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 02/15] pinctrl: rockchip: Add RV1103B support Simon Glass
` (14 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:30 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Albert Aribaud,
Ilias Apalodimas, Kever Yang, Philipp Tomsich, Tom Rini
From: Fabio Estevam <festevam@nabladev.com>
Add the RV1103B SoC devicetree files, taken verbatim from Linux v7.1,
where the RV1103B support is merged.
Once U-Boot's dts/upstream subtree is updated to v7.1-dts, the
OF_UPSTREAM mechanism can be enabled and these files dropped.
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Move the board devicetrees to the board patch and the SoC u-boot.dtsi
to the SoC patch (Jonas)
- Use the devicetree files as merged in Linux v7.1
Changes in v2:
- Use the devicetrees submitted to upstream Linux
arch/arm/dts/rv1103b-pinctrl.dtsi | 816 ++++++++++++++++++
arch/arm/dts/rv1103b.dtsi | 239 +++++
.../dt-bindings/clock/rockchip,rv1103b-cru.h | 220 +++++
3 files changed, 1275 insertions(+)
create mode 100644 arch/arm/dts/rv1103b-pinctrl.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-pinctrl.dtsi b/arch/arm/dts/rv1103b-pinctrl.dtsi
new file mode 100644
index 00000000000..15516c38413
--- /dev/null
+++ b/arch/arm/dts/rv1103b-pinctrl.dtsi
@@ -0,0 +1,816 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2026 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <arm64/rockchip/rockchip-pinconf.dtsi>
+
+&pinctrl {
+ cam-clk0 {
+ /omit-if-no-ref/
+ cam_clk0: cam-clk0 {
+ rockchip,pins =
+ /* cam_clk0_out */
+ <1 RK_PB5 1 &pcfg_pull_none>;
+ };
+ };
+
+ cam-clk1 {
+ /omit-if-no-ref/
+ cam_clk1: cam-clk1 {
+ rockchip,pins =
+ /* cam_clk1_out */
+ <1 RK_PB6 1 &pcfg_pull_none>;
+ };
+ };
+
+ cam-spi {
+ /omit-if-no-ref/
+ cam_spi_bus4: cam-spi-bus4 {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ cam_spi_clk: cam-spi-clk {
+ rockchip,pins =
+ /* cam_spi_clk */
+ <0 RK_PB4 4 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ cam_spi_cs0n: cam-spi-cs0n {
+ rockchip,pins =
+ /* cam_spi_cs0n */
+ <0 RK_PB3 4 &pcfg_pull_none>;
+ };
+ };
+
+ clk {
+ /omit-if-no-ref/
+ clk_32k: clk-32k {
+ rockchip,pins =
+ /* clk_32k */
+ <0 RK_PA0 2 &pcfg_pull_none>;
+ };
+ };
+
+ clk-24m {
+ /omit-if-no-ref/
+ clk_24m_out: clk-24m-out {
+ rockchip,pins =
+ /* clk_24m_out */
+ <0 RK_PA0 3 &pcfg_pull_none>;
+ };
+ };
+
+ cpu {
+ /omit-if-no-ref/
+ cpu: cpu {
+ rockchip,pins =
+ /* cpu_avs */
+ <0 RK_PA1 2 &pcfg_pull_none>;
+ };
+ };
+
+ emmc {
+ /omit-if-no-ref/
+ emmc_bus4: emmc-bus4 {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ emmc_clk: emmc-clk {
+ rockchip,pins =
+ /* emmc_clk */
+ <1 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ /omit-if-no-ref/
+ emmc_cmd: emmc-cmd {
+ rockchip,pins =
+ /* emmc_cmd */
+ <1 RK_PA5 1 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ fspi {
+ /omit-if-no-ref/
+ fspi_bus4: fspi-bus4 {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ fspi_cs0: fspi-cs0 {
+ rockchip,pins =
+ /* fspi_cs0n */
+ <1 RK_PA5 2 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ fspi_clk: fspi-clk {
+ rockchip,pins =
+ /* fspi_clk */
+ <1 RK_PA4 2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ /omit-if-no-ref/
+ i2c0m0_xfer: i2c0m0-xfer {
+ rockchip,pins =
+ /* i2c0_scl_m0 */
+ <0 RK_PA5 3 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m0 */
+ <0 RK_PA6 3 &pcfg_pull_none_smt>;
+ };
+
+ /omit-if-no-ref/
+ i2c0m1_xfer: i2c0m1-xfer {
+ rockchip,pins =
+ /* i2c0_scl_m1 */
+ <1 RK_PB4 5 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m1 */
+ <1 RK_PB3 5 &pcfg_pull_none_smt>;
+ };
+
+ /omit-if-no-ref/
+ i2c0m2_xfer: i2c0m2-xfer {
+ 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 {
+ /omit-if-no-ref/
+ i2c1m0_xfer: i2c1m0-xfer {
+ rockchip,pins =
+ /* i2c1_scl_m0 */
+ <0 RK_PB0 1 &pcfg_pull_none_smt>,
+ /* i2c1_sda_m0 */
+ <0 RK_PB1 1 &pcfg_pull_none_smt>;
+ };
+
+ /omit-if-no-ref/
+ i2c1m1_xfer: i2c1m1-xfer {
+ 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 {
+ /omit-if-no-ref/
+ i2c2m0_xfer: i2c2m0-xfer {
+ rockchip,pins =
+ /* i2c2_scl_m0 */
+ <0 RK_PB2 1 &pcfg_pull_none_smt>,
+ /* i2c2_sda_m0 */
+ <0 RK_PB3 1 &pcfg_pull_none_smt>;
+ };
+
+ /omit-if-no-ref/
+ i2c2m1_xfer: i2c2m1-xfer {
+ 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 {
+ /omit-if-no-ref/
+ i2c3m0_xfer: i2c3m0-xfer {
+ rockchip,pins =
+ /* i2c3_scl_m0 */
+ <0 RK_PB4 1 &pcfg_pull_none_smt>,
+ /* i2c3_sda_m0 */
+ <0 RK_PB5 1 &pcfg_pull_none_smt>;
+ };
+
+ /omit-if-no-ref/
+ i2c3m1_xfer: i2c3m1-xfer {
+ 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 {
+ /omit-if-no-ref/
+ i2c4m0_xfer: i2c4m0-xfer {
+ rockchip,pins =
+ /* i2c4_scl_m0 */
+ <2 RK_PB0 4 &pcfg_pull_none_smt>,
+ /* i2c4_sda_m0 */
+ <2 RK_PB1 4 &pcfg_pull_none_smt>;
+ };
+
+ /omit-if-no-ref/
+ i2c4m1_xfer: i2c4m1-xfer {
+ 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 {
+ /omit-if-no-ref/
+ jtagm0: jtagm0 {
+ rockchip,pins =
+ /* jtag_tck_m0 */
+ <0 RK_PA5 5 &pcfg_pull_none>,
+ /* jtag_tms_m0 */
+ <0 RK_PA6 5 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ jtagm1: jtagm1 {
+ rockchip,pins =
+ /* jtag_tck_m1 */
+ <0 RK_PB4 3 &pcfg_pull_none>,
+ /* jtag_tms_m1 */
+ <0 RK_PB5 3 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ jtagm2: jtagm2 {
+ rockchip,pins =
+ /* jtag_tck_m2 */
+ <1 RK_PB4 3 &pcfg_pull_none>,
+ /* jtag_tms_m2 */
+ <1 RK_PB3 3 &pcfg_pull_none>;
+ };
+ };
+
+ psram-spi {
+ /omit-if-no-ref/
+ psram_spi_bus4: psram-spi-bus4 {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ psram_spi_clk: psram-spi-clk {
+ rockchip,pins =
+ /* psram_spi_clk */
+ <0 RK_PA0 4 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ psram_spi_cs0n: psram-spi-cs0n {
+ rockchip,pins =
+ /* psram_spi_cs0n */
+ <0 RK_PA4 4 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ /omit-if-no-ref/
+ pwm0m0_ch0: pwm0m0-ch0 {
+ rockchip,pins =
+ /* pwm0m0_ch0 */
+ <0 RK_PA1 1 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m0_ch1: pwm0m0-ch1 {
+ rockchip,pins =
+ /* pwm0m0_ch1 */
+ <0 RK_PA5 2 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m0_ch2: pwm0m0-ch2 {
+ rockchip,pins =
+ /* pwm0m0_ch2 */
+ <0 RK_PA6 2 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m0_ch3: pwm0m0-ch3 {
+ rockchip,pins =
+ /* pwm0m0_ch3 */
+ <0 RK_PA2 1 &pcfg_pull_none_drv_level_0>;
+ };
+
+ /omit-if-no-ref/
+ pwm0m1_ch0: pwm0m1-ch0 {
+ rockchip,pins =
+ /* pwm0m1_ch0 */
+ <2 RK_PA0 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m1_ch1: pwm0m1-ch1 {
+ rockchip,pins =
+ /* pwm0m1_ch1 */
+ <2 RK_PA1 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m1_ch2: pwm0m1-ch2 {
+ rockchip,pins =
+ /* pwm0m1_ch2 */
+ <2 RK_PA2 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m1_ch3: pwm0m1-ch3 {
+ rockchip,pins =
+ /* pwm0m1_ch3 */
+ <2 RK_PB0 3 &pcfg_pull_none_drv_level_0>;
+ };
+
+ /omit-if-no-ref/
+ pwm0m2_ch1: pwm0m2-ch1 {
+ rockchip,pins =
+ /* pwm0m2_ch1 */
+ <1 RK_PB7 1 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm0m2_ch2: pwm0m2-ch2 {
+ rockchip,pins =
+ /* pwm0m2_ch2 */
+ <1 RK_PC0 1 &pcfg_pull_none_drv_level_0>;
+ };
+ };
+
+ pwm1 {
+ /omit-if-no-ref/
+ pwm1m0_ch0: pwm1m0-ch0 {
+ rockchip,pins =
+ /* pwm1m0_ch0 */
+ <0 RK_PB0 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm1m0_ch1: pwm1m0-ch1 {
+ rockchip,pins =
+ /* pwm1m0_ch1 */
+ <0 RK_PB1 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm1m0_ch2: pwm1m0-ch2 {
+ rockchip,pins =
+ /* pwm1m0_ch2 */
+ <0 RK_PB2 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm1m0_ch3: pwm1m0-ch3 {
+ rockchip,pins =
+ /* pwm1m0_ch3 */
+ <0 RK_PB3 3 &pcfg_pull_none_drv_level_0>;
+ };
+
+ /omit-if-no-ref/
+ pwm1m1_ch0: pwm1m1-ch0 {
+ rockchip,pins =
+ /* pwm1m1_ch0 */
+ <2 RK_PA3 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm1m1_ch1: pwm1m1-ch1 {
+ rockchip,pins =
+ /* pwm1m1_ch1 */
+ <2 RK_PA4 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm1m1_ch2: pwm1m1-ch2 {
+ rockchip,pins =
+ /* pwm1m1_ch2 */
+ <2 RK_PA5 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm1m1_ch3: pwm1m1-ch3 {
+ rockchip,pins =
+ /* pwm1m1_ch3 */
+ <2 RK_PB1 3 &pcfg_pull_none_drv_level_0>;
+ };
+ };
+
+ pwm2 {
+ /omit-if-no-ref/
+ pwm2m0_ch0: pwm2m0-ch0 {
+ rockchip,pins =
+ /* pwm2m0_ch0 */
+ <1 RK_PB0 4 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm2m0_ch1: pwm2m0-ch1 {
+ rockchip,pins =
+ /* pwm2m0_ch1 */
+ <1 RK_PA7 4 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm2m0_ch2: pwm2m0-ch2 {
+ rockchip,pins =
+ /* pwm2m0_ch2 */
+ <1 RK_PB4 4 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm2m0_ch3: pwm2m0-ch3 {
+ rockchip,pins =
+ /* pwm2m0_ch3 */
+ <1 RK_PB3 4 &pcfg_pull_none_drv_level_0>;
+ };
+
+ /omit-if-no-ref/
+ pwm2m1_ch0: pwm2m1-ch0 {
+ rockchip,pins =
+ /* pwm2m1_ch0 */
+ <2 RK_PA6 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm2m1_ch1: pwm2m1-ch1 {
+ rockchip,pins =
+ /* pwm2m1_ch1 */
+ <2 RK_PA7 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm2m1_ch2: pwm2m1-ch2 {
+ rockchip,pins =
+ /* pwm2m1_ch2 */
+ <2 RK_PB2 3 &pcfg_pull_none_drv_level_0>;
+ };
+ /omit-if-no-ref/
+ pwm2m1_ch3: pwm2m1-ch3 {
+ rockchip,pins =
+ /* pwm2m1_ch3 */
+ <2 RK_PB3 3 &pcfg_pull_none_drv_level_0>;
+ };
+ };
+
+ pwr {
+ /omit-if-no-ref/
+ pwr: pwr {
+ rockchip,pins =
+ /* pwr_ctrl0 */
+ <0 RK_PA3 1 &pcfg_pull_none>,
+ /* pwr_ctrl1 */
+ <0 RK_PA4 1 &pcfg_pull_none>;
+ };
+ };
+
+ rtc_32k {
+ /omit-if-no-ref/
+ rtc_32k: rtc-32k {
+ rockchip,pins =
+ /* rtc_32k_out */
+ <0 RK_PA0 1 &pcfg_pull_none>;
+ };
+ };
+
+ sai {
+ /omit-if-no-ref/
+ sai: sai {
+ 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 {
+ /omit-if-no-ref/
+ sdmmc0_bus4: sdmmc0-bus4 {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ sdmmc0_clk: sdmmc0-clk {
+ rockchip,pins =
+ /* sdmmc0_clk */
+ <1 RK_PB1 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ /omit-if-no-ref/
+ sdmmc0_cmd: sdmmc0-cmd {
+ rockchip,pins =
+ /* sdmmc0_cmd */
+ <1 RK_PB2 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ /omit-if-no-ref/
+ sdmmc0_det: sdmmc0-det {
+ rockchip,pins =
+ /* sdmmc0_det */
+ <1 RK_PA6 1 &pcfg_pull_up>;
+ };
+ };
+
+ sdmmc1 {
+ /omit-if-no-ref/
+ sdmmc1_bus4: sdmmc1-bus4 {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ sdmmc1_clk: sdmmc1-clk {
+ rockchip,pins =
+ /* sdmmc1_clk */
+ <2 RK_PA2 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ /omit-if-no-ref/
+ sdmmc1_cmd: sdmmc1-cmd {
+ rockchip,pins =
+ /* sdmmc1_cmd */
+ <2 RK_PA3 1 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ spi0 {
+ /omit-if-no-ref/
+ spi0m0_clk: spi0m0-clk {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ spi0m0_cs0: spi0m0-cs0 {
+ rockchip,pins =
+ /* spi0_cs0n_m0 */
+ <2 RK_PB2 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ spi0m0_cs1: spi0m0-cs1 {
+ rockchip,pins =
+ /* spi0_cs1n_m0 */
+ <2 RK_PA7 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ spi0m1_clk: spi0m1-clk {
+ 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>;
+ };
+
+ /omit-if-no-ref/
+ spi0m1_cs0: spi0m1-cs0 {
+ rockchip,pins =
+ /* spi0_cs0n_m1 */
+ <2 RK_PA3 5 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ spi0m1_cs1: spi0m1-cs1 {
+ rockchip,pins =
+ /* spi0_cs1n_m1 */
+ <2 RK_PA0 5 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ /omit-if-no-ref/
+ uart0m0_xfer: uart0m0-xfer {
+ rockchip,pins =
+ /* uart0_rx_m0 */
+ <0 RK_PA6 1 &pcfg_pull_up>,
+ /* uart0_tx_m0 */
+ <0 RK_PA5 1 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart0m1_xfer: uart0m1-xfer {
+ rockchip,pins =
+ /* uart0_rx_m1 */
+ <0 RK_PB5 2 &pcfg_pull_up>,
+ /* uart0_tx_m1 */
+ <0 RK_PB4 2 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart0m2_xfer: uart0m2-xfer {
+ rockchip,pins =
+ /* uart0_rx_m2 */
+ <1 RK_PB3 2 &pcfg_pull_up>,
+ /* uart0_tx_m2 */
+ <1 RK_PB4 2 &pcfg_pull_up>;
+ };
+ };
+
+ uart1 {
+ /omit-if-no-ref/
+ uart1m0_xfer: uart1m0-xfer {
+ rockchip,pins =
+ /* uart1_rx_m0 */
+ <0 RK_PB2 2 &pcfg_pull_up>,
+ /* uart1_tx_m0 */
+ <0 RK_PB3 2 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart1m0_ctsn: uart1m0-ctsn {
+ rockchip,pins =
+ /* uart1m0_ctsn */
+ <0 RK_PB5 5 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart1m0_rtsn: uart1m0-rtsn {
+ rockchip,pins =
+ /* uart1m0_rtsn */
+ <0 RK_PB4 5 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ uart1m1_xfer: uart1m1-xfer {
+ rockchip,pins =
+ /* uart1_rx_m1 */
+ <1 RK_PA7 2 &pcfg_pull_up>,
+ /* uart1_tx_m1 */
+ <1 RK_PB0 2 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart1m1_ctsn: uart1m1-ctsn {
+ rockchip,pins =
+ /* uart1m1_ctsn */
+ <1 RK_PB2 2 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart1m1_rtsn: uart1m1-rtsn {
+ rockchip,pins =
+ /* uart1m1_rtsn */
+ <1 RK_PB1 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ uart1m2_xfer: uart1m2-xfer {
+ rockchip,pins =
+ /* uart1_rx_m2 */
+ <2 RK_PA7 1 &pcfg_pull_up>,
+ /* uart1_tx_m2 */
+ <2 RK_PA6 1 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart1m2_ctsn: uart1m2-ctsn {
+ rockchip,pins =
+ /* uart1m2_ctsn */
+ <2 RK_PA5 2 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart1m2_rtsn: uart1m2-rtsn {
+ rockchip,pins =
+ /* uart1m2_rtsn */
+ <2 RK_PA4 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ uart1m3_xfer: uart1m3-xfer {
+ rockchip,pins =
+ /* uart1_rx_m3 */
+ <2 RK_PA3 2 &pcfg_pull_up>,
+ /* uart1_tx_m3 */
+ <2 RK_PA2 2 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart1m3_ctsn: uart1m3-ctsn {
+ rockchip,pins =
+ /* uart1m3_ctsn */
+ <2 RK_PA1 2 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart1m3_rtsn: uart1m3-rtsn {
+ rockchip,pins =
+ /* uart1m3_rtsn */
+ <2 RK_PA0 2 &pcfg_pull_none>;
+ };
+ };
+
+ uart2 {
+ /omit-if-no-ref/
+ uart2m0_xfer: uart2m0-xfer {
+ rockchip,pins =
+ /* uart2_rx_m0 */
+ <0 RK_PB1 2 &pcfg_pull_up>,
+ /* uart2_tx_m0 */
+ <0 RK_PB0 2 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart2m0_ctsn: uart2m0-ctsn {
+ rockchip,pins =
+ /* uart2m0_ctsn */
+ <0 RK_PB3 5 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart2m0_rtsn: uart2m0-rtsn {
+ rockchip,pins =
+ /* uart2m0_rtsn */
+ <0 RK_PB2 5 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ uart2m1_xfer: uart2m1-xfer {
+ rockchip,pins =
+ /* uart2_rx_m1 */
+ <2 RK_PB1 1 &pcfg_pull_up>,
+ /* uart2_tx_m1 */
+ <2 RK_PB0 1 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart2m1_ctsn: uart2m1-ctsn {
+ rockchip,pins =
+ /* uart2m1_ctsn */
+ <2 RK_PB3 1 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart2m1_rtsn: uart2m1-rtsn {
+ rockchip,pins =
+ /* uart2m1_rtsn */
+ <2 RK_PB2 1 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ uart2m2_xfer: uart2m2-xfer {
+ rockchip,pins =
+ /* uart2_rx_m2 */
+ <1 RK_PB6 3 &pcfg_pull_up>,
+ /* uart2_tx_m2 */
+ <1 RK_PB5 3 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
+ uart2m2_ctsn: uart2m2-ctsn {
+ rockchip,pins =
+ /* uart2m2_ctsn */
+ <1 RK_PC0 3 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart2m2_rtsn: uart2m2-rtsn {
+ rockchip,pins =
+ /* uart2m2_rtsn */
+ <1 RK_PB7 3 &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rv1103b.dtsi b/arch/arm/dts/rv1103b.dtsi
new file mode 100644
index 00000000000..39f78e0733c
--- /dev/null
+++ b/arch/arm/dts/rv1103b.dtsi
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2026 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>
+#include <dt-bindings/soc/rockchip,boot-mode.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>;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@0 {
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ clocks = <&cru ARMCLK>;
+ device_type = "cpu";
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ clock-frequency = <24000000>;
+ 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)>;
+ };
+
+ xin24m: oscillator-24m {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rv1103b-pinctrl";
+ rockchip,grf = <&ioc>;
+ ranges;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ gpio0: gpio@20520000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20520000 0x200>;
+ clocks = <&cru PCLK_PMU_GPIO0>, <&cru DBCLK_PMU_GPIO0>;
+ gpio-controller;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@20d80000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20d80000 0x200>;
+ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+ gpio-controller;
+ interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@20840000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20840000 0x200>;
+ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+ gpio-controller;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-controller;
+ #gpio-cells = <2>;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rv1103b-cru";
+ reg = <0x20000000 0x81000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ pmu_grf: syscon@20160000 {
+ compatible = "rockchip,rv1103b-pmu-grf", "syscon", "simple-mfd";
+ reg = <0x20160000 0x1000>;
+
+ reboot_mode: reboot-mode {
+ compatible = "syscon-reboot-mode";
+ offset = <0x200>;
+ mode-normal = <BOOT_NORMAL>;
+ mode-recovery = <BOOT_RECOVERY>;
+ mode-bootloader = <BOOT_FASTBOOT>;
+ mode-loader = <BOOT_BL_DOWNLOAD>;
+ };
+ };
+
+ ioc: syscon@20170000 {
+ compatible = "rockchip,rv1103b-ioc", "syscon";
+ reg = <0x20170000 0x60000>;
+ };
+
+ gic: interrupt-controller@20411000 {
+ compatible = "arm,gic-400";
+ reg = <0x20411000 0x1000>,
+ <0x20412000 0x2000>,
+ <0x20414000 0x2000>,
+ <0x20416000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ };
+
+ uart0: serial@20540000 {
+ compatible = "rockchip,rv1103b-uart", "snps,dw-apb-uart";
+ reg = <0x20540000 0x100>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ sdmmc1: mmc@20650000 {
+ compatible = "rockchip,rv1103b-dw-mshc", "rockchip,rk3576-dw-mshc";
+ reg = <0x20650000 0x4000>;
+ clocks = <&cru HCLK_SDMMC1>, <&cru CCLK_SDMMC1>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+ max-frequency = <150000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_clk &sdmmc1_cmd &sdmmc1_bus4>;
+ status = "disabled";
+ };
+
+ uart1: serial@20870000 {
+ compatible = "rockchip,rv1103b-uart", "snps,dw-apb-uart";
+ reg = <0x20870000 0x100>;
+ clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart2: serial@20880000 {
+ compatible = "rockchip,rv1103b-uart", "snps,dw-apb-uart";
+ reg = <0x20880000 0x100>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ sdmmc0: mmc@20d20000 {
+ compatible = "rockchip,rv1103b-dw-mshc", "rockchip,rk3576-dw-mshc";
+ reg = <0x20d20000 0x4000>;
+ clocks = <&cru HCLK_SDMMC0>, <&cru CCLK_SDMMC0>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+ max-frequency = <150000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_det &sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4>;
+ status = "disabled";
+ };
+
+ emmc: mmc@20d30000 {
+ compatible = "rockchip,rv1103b-dw-mshc", "rockchip,rk3576-dw-mshc";
+ reg = <0x20d30000 0x4000>;
+ clocks = <&cru HCLK_EMMC>, <&cru CCLK_EMMC>;
+ clock-names = "biu", "ciu";
+ fifo-depth = <0x100>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+ max-frequency = <150000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus4>;
+ status = "disabled";
+ };
+
+ fspi0: spi@20d40000 {
+ compatible = "rockchip,sfc";
+ reg = <0x20d40000 0x4000>;
+ clocks = <&cru SCLK_SFC_2X>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspi_bus4 &fspi_cs0 &fspi_clk>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ system_sram: sram@210f6000 {
+ compatible = "mmio-sram";
+ reg = <0x210f6000 0x8000>;
+ ranges = <0 0x210f6000 0x8000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+};
+
+#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 00000000000..35afdee7e96
--- /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.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 02/15] pinctrl: rockchip: Add RV1103B support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
2026-07-07 15:30 ` [PATCH v3 01/15] ARM: dts: Add the RV1103B devicetree files Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 03/15] clk: rockchip: Add RV1103B clock driver Simon Glass
` (13 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Ye Zhang, Simon Glass, Jeffy Chen,
Kever Yang, Philipp Tomsich, Tom Rini, huang lin
From: Ye Zhang <ye.zhang@rock-chips.com>
Add the pinctrl driver for the RV1103B.
Signed-off-by: Ye Zhang <ye.zhang@rock-chips.com>
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Use regmap_update_bits() in all the remaining places (Jonas)
- Align continuation lines with the open parenthesis (checkpatch)
Changes in v2:
- Use the original author from Rockchip's vendor U-Boot tree
- Use regmap_update_bits()
- Remove unneeded blank lines
- Remove unneeded logging functions
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl-rv1103b.c | 402 +++++++++++++++++++++
2 files changed, 403 insertions(+)
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1103b.c
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 0405df128df..b7ce6402ea3 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -19,5 +19,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 00000000000..4bd74312c8c
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rv1103b.c
@@ -0,0 +1,402 @@
+// 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, rmask;
+ 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);
+ rmask = data | (data >> 16);
+ data |= (ret << bit);
+
+ return regmap_update_bits(regmap, reg, rmask, 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, rmask;
+
+ 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);
+ rmask = data | (data >> 16);
+ data |= (ret << bit);
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+}
+
+#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, rmask, mask;
+ u8 bit;
+
+ ret = rv1103b_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ if (ret)
+ return ret;
+
+ mask = (1 << RV1103_SMT_BITS_PER_PIN) - 1;
+ if (bank->bank_num == 2 && pin_num >= 12) {
+ mask = 0x3;
+ enable = enable ? 0x3 : 0;
+ }
+
+ /* enable the write to the equivalent lower bits */
+ data = mask << (bit + 16);
+ rmask = data | (data >> 16);
+ data |= (enable << bit);
+
+ return regmap_update_bits(regmap, reg, rmask, 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.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 03/15] clk: rockchip: Add RV1103B clock driver
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
2026-07-07 15:30 ` [PATCH v3 01/15] ARM: dts: Add the RV1103B devicetree files Simon Glass
2026-07-07 15:31 ` [PATCH v3 02/15] pinctrl: rockchip: Add RV1103B support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 04/15] tools: rkcommon: Add RV1103B support Simon Glass
` (12 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Elaine Zhang, Simon Glass,
Finley Xiao, Ilias Apalodimas, Jeffy Chen, Kever Yang,
Lukasz Majewski, Philipp Tomsich, Tom Rini, huang lin
From: Elaine Zhang <zhangqing@rock-chips.com>
Add the basic clock driver for the RV1103B.
Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com>
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Use CONFIG_IS_ENABLED() to guard the set_parent operation, matching
clk_rk3588.c, since plain IS_ENABLED() needs the CONFIG_ prefix
Changes in v2:
- 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 00000000000..fc7aa4dfc0d
--- /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 00000000000..6bb382a8e07
--- /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 07525c36432..de2635b7475 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -20,5 +20,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 00000000000..c94a6ebb3dd
--- /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 (CONFIG_IS_ENABLED(OF_CONTROL)) || (!CONFIG_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.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 04/15] tools: rkcommon: Add RV1103B support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (2 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 03/15] clk: rockchip: Add RV1103B clock driver Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 05/15] rockchip: spl-boot-order: Add SPI NAND support Simon Glass
` (11 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Xuhui Lin, Simon Glass,
Ilias Apalodimas, Kever Yang, Neil Armstrong, Philipp Tomsich,
Quentin Schulz, Tom Rini
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>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
tools/rkcommon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index b39777fc060..6f25a1cda31 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -153,6 +153,7 @@ static struct spl_info spl_infos[] = {
{ "rk3568", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 },
{ "rk3576", "RK35", 0x80000 - 0x1000, false, RK_HEADER_V2 },
{ "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 },
+ { "rv1103b", "110E", 0x40000 - 0x1000, false, RK_HEADER_V2 },
{ "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 },
{ "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 },
};
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 05/15] rockchip: spl-boot-order: Add SPI NAND support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (3 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 04/15] tools: rkcommon: Add RV1103B support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 06/15] spl: Add SPI NAND support via MTD in SPL Simon Glass
` (10 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Alexey Charkov,
Anshul Dalal, Ilias Apalodimas, Jeffy Chen, Kever Yang,
Philipp Tomsich, Quentin Schulz, Tom Rini, huang lin
From: Fabio Estevam <festevam@nabladev.com>
Make spl-boot-order accept booting 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>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Guard the spi-nand checks with SPI_NAND_LOAD so that boards without
SPI NAND support do not grow in size
arch/arm/mach-rockchip/spl-boot-order.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c
index d2dd5e10935..3942dfe6f5c 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,9 @@ 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 (CONFIG_IS_ENABLED(SPI_NAND_LOAD) &&
+ !fdt_node_check_compatible(gd->fdt_blob, node, "spi-nand"))
+ return BOOT_DEVICE_SPI;
if (!uclass_find_device_by_of_offset(UCLASS_UFS, node, &parent))
return BOOT_DEVICE_UFS;
@@ -223,8 +227,14 @@ 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 && CONFIG_IS_ENABLED(SPI_NAND_LOAD)) {
+ ret = uclass_find_device_by_of_offset(UCLASS_MTD, node, &dev);
+ if (!ret && !device_is_compatible(dev, "spi-nand"))
+ ret = -ENODEV;
+ }
if (ret) {
- debug("%s: could not find udevice for %s\n", __func__, conf);
+ debug("%s: could not find udevice for %s\n",
+ __func__, conf);
continue;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 06/15] spl: Add SPI NAND support via MTD in SPL
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (4 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 05/15] rockchip: spl-boot-order: Add SPI NAND support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 07/15] rockchip: rv1103b: Add SoC support Simon Glass
` (9 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Alexey Charkov,
Andrew Davis, Anshul Dalal, Bastien Curutchet, Hrushikesh Salunke,
Johan Jonker, João Marcos Costa, Mattijs Korpershoek,
Neil Armstrong, Peng Fan, Quentin Schulz, Richard Genoud,
Tom Rini
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 the 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 SPL_SPI_NAND_LOAD is
enabled, avoiding a size impact on other boards.
This allows boards like the Omega4 RV1103B 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>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
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 0618f42c941..0a3b53d0e66 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 9c94e8f143e..e8365b69825 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -36,6 +36,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
obj-$(CONFIG_$(PHASE_)UFS_SUPPORT) += spl_ufs.o
diff --git a/common/spl/spl_spi_nand.c b/common/spl/spl_spi_nand.c
new file mode 100644
index 00000000000..20b877f75a0
--- /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 ce05e206073..a12d880a9e9 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 c8169cf7390..7cd2a5f1af9 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.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 07/15] rockchip: rv1103b: Add SoC support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (5 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 06/15] spl: Add SPI NAND support via MTD in SPL Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 08/15] omega4-rv1103b: Add the initial support Simon Glass
` (8 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Heinrich Schuchardt,
Ilias Apalodimas, Jeffy Chen, Johan Jonker, Kever Yang,
Mattijs Korpershoek, Philipp Tomsich, Quentin Schulz, Tom Rini,
huang lin
From: Fabio Estevam <festevam@nabladev.com>
The 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.
Add the core SoC support for it: the Kconfig and Makefile entries,
the boot0 hook, the SoC init code, the syscon driver and the SPL
clock setup.
Signed-off-by: Fabio Estevam <festevam@nabladev.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- New patch, split out from the board patch (Jonas)
- Include the SoC u-boot.dtsi here (Jonas)
- Match the pmu-grf compatible used by the devicetree merged in Linux
v7.1
arch/arm/dts/rv1103b-u-boot.dtsi | 4 +
arch/arm/include/asm/arch-rv1103b/boot0.h | 11 ++
arch/arm/mach-rockchip/Kconfig | 13 ++
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rv1103b/Kconfig | 15 ++
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 +++
include/configs/rv1103b_common.h | 14 ++
11 files changed, 259 insertions(+)
create mode 100644 arch/arm/dts/rv1103b-u-boot.dtsi
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 include/configs/rv1103b_common.h
diff --git a/arch/arm/dts/rv1103b-u-boot.dtsi b/arch/arm/dts/rv1103b-u-boot.dtsi
new file mode 100644
index 00000000000..3b77dd31152
--- /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/include/asm/arch-rv1103b/boot0.h b/arch/arm/include/asm/arch-rv1103b/boot0.h
new file mode 100644
index 00000000000..2e78b074ade
--- /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 1a2e7847c9e..1969c313f47 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -532,6 +532,18 @@ 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
@@ -795,6 +807,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 d3bc0689f89..e09dc44a7ad 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -47,6 +47,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 00000000000..710a86aeb33
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1103b/Kconfig
@@ -0,0 +1,15 @@
+if ROCKCHIP_RV1103B
+
+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
+
+endif
diff --git a/arch/arm/mach-rockchip/rv1103b/Makefile b/arch/arm/mach-rockchip/rv1103b/Makefile
new file mode 100644
index 00000000000..2f34853adac
--- /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 00000000000..466ab0e8077
--- /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 00000000000..2bcbb08537e
--- /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 00000000000..a7ff1934f7d
--- /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 00000000000..7c71b1092f3
--- /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-pmu-grf", .data = ROCKCHIP_SYSCON_PMUGRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rv1103b) = {
+ .name = "rv1103b_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1103b_syscon_ids,
+};
diff --git a/include/configs/rv1103b_common.h b/include/configs/rv1103b_common.h
new file mode 100644
index 00000000000..8e970d71051
--- /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.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 08/15] omega4-rv1103b: Add the initial support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (6 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 07/15] rockchip: rv1103b: Add SoC support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 09/15] tools: rkcommon: Add RV1106 support Simon Glass
` (7 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Alexander Feilke,
Chris Morgan, Chris Packham, FUKAUMI Naoki, Ilias Apalodimas,
Johan Jonker, Kever Yang, Niu Zhihong, Peng Fan, Peter Robinson,
Philipp Tomsich, Quentin Schulz, Svyatoslav Ryhel, Tom Rini
From: Fabio Estevam <festevam@nabladev.com>
Add the initial support for Onion's Omega4 RV1103B board, using the
board devicetree files as merged in Linux v7.1, which split the board
into rv1103b-omega4.dtsi and rv1103b-omega4-evb.dts
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>
Signed-off-by: Simon Glass <sjg@chromium.org>
---
Changes in v3:
- Split out the SoC support into its own patch (Jonas)
- Move the board devicetree files into this patch (Jonas)
- Add the board to the list in the Rockchip documentation
- Extend the MAINTAINERS entry to cover all the RV1103B files
- Use the board devicetree files as merged in Linux v7.1 and switch
the default devicetree to rv1103b-omega4-evb
Changes in v2:
- Use RV1103B rather than RV1103, which is the correct SoC name
arch/arm/dts/rv1103b-omega4-evb-u-boot.dtsi | 10 ++
arch/arm/dts/rv1103b-omega4-evb.dts | 63 ++++++++
arch/arm/dts/rv1103b-omega4.dtsi | 147 ++++++++++++++++++
arch/arm/mach-rockchip/rv1103b/Kconfig | 7 +
board/onion/omega4_rv1103b/Kconfig | 12 ++
board/onion/omega4_rv1103b/MAINTAINERS | 15 ++
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 +++++++
doc/board/rockchip/rockchip.rst | 3 +
include/configs/omega4_rv1103b.h | 11 ++
15 files changed, 447 insertions(+)
create mode 100644 arch/arm/dts/rv1103b-omega4-evb-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103b-omega4-evb.dts
create mode 100644 arch/arm/dts/rv1103b-omega4.dtsi
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
diff --git a/arch/arm/dts/rv1103b-omega4-evb-u-boot.dtsi b/arch/arm/dts/rv1103b-omega4-evb-u-boot.dtsi
new file mode 100644
index 00000000000..c7616de1715
--- /dev/null
+++ b/arch/arm/dts/rv1103b-omega4-evb-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-evb.dts b/arch/arm/dts/rv1103b-omega4-evb.dts
new file mode 100644
index 00000000000..c6472f933aa
--- /dev/null
+++ b/arch/arm/dts/rv1103b-omega4-evb.dts
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2025 plan44.ch/luz
+ * Copyright (c) 2026 Onion Corporation
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "rv1103b-omega4.dtsi"
+
+/ {
+ model = "Onion Omega4 Evaluation Board";
+ compatible = "onion,omega4-evb", "onion,omega4", "rockchip,rv1103b";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-0 {
+ color = <LED_COLOR_ID_BLUE>;
+ default-state = "on";
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+ label = "sys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led>;
+ };
+ };
+};
+
+&fspi0 {
+ status = "okay";
+};
+
+&pinctrl {
+ leds {
+ led: led {
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdmmc0 {
+ status = "okay";
+};
+
+&sdmmc1 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rv1103b-omega4.dtsi b/arch/arm/dts/rv1103b-omega4.dtsi
new file mode 100644
index 00000000000..6a8e8e0f80c
--- /dev/null
+++ b/arch/arm/dts/rv1103b-omega4.dtsi
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2025 plan44.ch/luz
+ * Copyright (c) 2026 Onion Corporation
+ */
+
+/dts-v1/;
+
+#include "rv1103b.dtsi"
+
+/ {
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ post-power-on-delay-ms = <300>;
+ reset-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+ };
+
+ vcc3v3_sd: vcc3v3-sd {
+ compatible = "regulator-fixed";
+ gpio = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_pwren>;
+ regulator-name = "vcc3v3_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vccio_sd: vccio-sd {
+ compatible = "regulator-gpio";
+ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_volt>;
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ states = <3300000 1 1800000 0>;
+ };
+};
+
+&uart0 {
+ bootph-all;
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0m0_xfer>;
+};
+
+&fspi0 {
+ 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 {
+ reg = <0x00000000 0x00040000>;
+ label = "env";
+ };
+
+ partition@40000 {
+ reg = <0x00040000 0x00100000>;
+ label = "idblock";
+ read-only;
+ };
+
+ partition@140000 {
+ reg = <0x00140000 0x00100000>;
+ label = "uboot";
+ read-only;
+ };
+
+ partition@240000 {
+ reg = <0x00240000 0x00800000>;
+ label = "boot";
+ };
+
+ partition@a40000 {
+ reg = <0x00a40000 0x0f5c0000>;
+ label = "ubi";
+ };
+ };
+ };
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_sd>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "disabled";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ no-sd;
+ no-mmc;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_cmd &sdmmc1_clk &sdmmc1_bus4>;
+ status = "disabled";
+};
+
+&pinctrl {
+ sdio-pwrseq {
+ /omit-if-no-ref/
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <2 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc {
+ /omit-if-no-ref/
+ sdmmc_pwren: sdmmc-pwren {
+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ sdmmc_volt: sdmmc-volt {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ wireless-wlan {
+ /omit-if-no-ref/
+ wifi_host_wake_irq: wifi-host-wake-irq {
+ rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/mach-rockchip/rv1103b/Kconfig b/arch/arm/mach-rockchip/rv1103b/Kconfig
index 710a86aeb33..77699a5180e 100644
--- a/arch/arm/mach-rockchip/rv1103b/Kconfig
+++ b/arch/arm/mach-rockchip/rv1103b/Kconfig
@@ -1,5 +1,10 @@
if ROCKCHIP_RV1103B
+config TARGET_OMEGA4_RV1103B
+ bool "OMEGA4_RV1103B"
+ help
+ Support Onion's Omega4 RV1103B board.
+
config ROCKCHIP_BOOT_MODE_REG
default 0x20160200
@@ -12,4 +17,6 @@ config SYS_SOC
config SYS_MALLOC_F_LEN
default 0x400
+source "board/onion/omega4_rv1103b/Kconfig"
+
endif
diff --git a/board/onion/omega4_rv1103b/Kconfig b/board/onion/omega4_rv1103b/Kconfig
new file mode 100644
index 00000000000..43b126c20e9
--- /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 00000000000..5ad58118989
--- /dev/null
+++ b/board/onion/omega4_rv1103b/MAINTAINERS
@@ -0,0 +1,15 @@
+OMEGA4 RV1103B
+M: Fabio Estevam <festevam@nabladev.com>
+S: Maintained
+F: arch/arm/dts/rv1103b*
+F: arch/arm/include/asm/arch-rv1103b/
+F: arch/arm/include/asm/arch-rockchip/cru_rv1103b.h
+F: arch/arm/mach-rockchip/rv1103b/
+F: board/onion/omega4_rv1103b/
+F: configs/omega4-rv1103b_defconfig
+F: doc/board/onion/
+F: drivers/clk/rockchip/clk_rv1103b.c
+F: drivers/pinctrl/rockchip/pinctrl-rv1103b.c
+F: include/configs/omega4_rv1103b.h
+F: include/configs/rv1103b_common.h
+F: include/dt-bindings/clock/rockchip,rv1103b-cru.h
diff --git a/board/onion/omega4_rv1103b/Makefile b/board/onion/omega4_rv1103b/Makefile
new file mode 100644
index 00000000000..afa0a7f7a93
--- /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 00000000000..9bdec3c396a
--- /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 00000000000..7ed232cab91
--- /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 00000000000..04e51af605c
--- /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-evb"
+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 4103fef8d8f..2454c3598fb 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -46,6 +46,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 00000000000..2e106c8b773
--- /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 00000000000..41c64f40d6c
--- /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/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index a31ee7100b9..2574a1da52c 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -180,6 +180,9 @@ List of mainline supported Rockchip boards:
- Yanyi Tech CoolPi CM5 EVB (coolpi-cm5-evb-rk3588)
- Yanyi Tech CoolPi CM5 GenBook (coolpi-cm5-genbook-rk3588)
+* rv1103b
+ - Onion Omega4 (omega4-rv1103b), see :doc:`../onion/omega4-rv1103b`
+
* rv1108
- Rockchip Evb-rv1108 (evb-rv1108)
- Elgin-R1 (elgin-rv1108)
diff --git a/include/configs/omega4_rv1103b.h b/include/configs/omega4_rv1103b.h
new file mode 100644
index 00000000000..8430b0b4d09
--- /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
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 09/15] tools: rkcommon: Add RV1106 support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (7 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 08/15] omega4-rv1103b: Add the initial support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 10/15] pinctrl: rockchip: " Simon Glass
` (6 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Ilias Apalodimas,
Kever Yang, Neil Armstrong, Philipp Tomsich, Quentin Schulz,
Tom Rini, Xuhui Lin
Add rv1106 to the list of supported SoCs. Like the RV1103B, it uses
the version-2 image header, for which the 4-byte header tag is unused.
The RV1103 is a package variant of the RV1106 and uses the same boot
image format, so this entry covers both
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
tools/rkcommon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 6f25a1cda31..06df57ec72d 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -154,6 +154,7 @@ static struct spl_info spl_infos[] = {
{ "rk3576", "RK35", 0x80000 - 0x1000, false, RK_HEADER_V2 },
{ "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 },
{ "rv1103b", "110E", 0x40000 - 0x1000, false, RK_HEADER_V2 },
+ { "rv1106", "110C", 0x40000 - 0x1000, false, RK_HEADER_V2 },
{ "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 },
{ "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 },
};
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 10/15] pinctrl: rockchip: Add RV1106 support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (8 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 09/15] tools: rkcommon: Add RV1106 support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 11/15] ARM: dts: Add the RV1103/RV1106 devicetree files Simon Glass
` (5 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Jeffy Chen, Kever Yang,
Philipp Tomsich, Tom Rini, Ye Zhang, huang lin
Add the pinctrl driver for the RV1106, based on the driver in the
Rockchip vendor tree, converted to use regmap_update_bits() so that
the pin configuration in the devicetree cannot overflow the register
fields.
The RV1103 is a package variant of the RV1106 and shares this driver.
Unlike most Rockchip SoCs, the GPIO0 IOC block lives in the PMU, so
the driver selects the PMU regmap for bank 0
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl-rv1106.c | 320 ++++++++++++++++++++++
2 files changed, 321 insertions(+)
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rv1106.c
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index b7ce6402ea3..6d7a2548af5 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -20,5 +20,6 @@ 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_RV1106) += pinctrl-rv1106.o
obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1106.c b/drivers/pinctrl/rockchip/pinctrl-rv1106.c
new file mode 100644
index 00000000000..5c3ad3ed09d
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rv1106.c
@@ -0,0 +1,320 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 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 rv1106_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->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ regmap = priv->regmap_pmu;
+ else
+ regmap = priv->regmap_base;
+
+ reg = bank->iomux[iomux_num].offset;
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ mask = 0xf;
+
+ data = (mask << (bit + 16));
+ rmask = data | (data >> 16);
+ data |= (mux & mask) << bit;
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+}
+
+#define RV1106_DRV_BITS_PER_PIN 8
+#define RV1106_DRV_PINS_PER_REG 2
+#define RV1106_DRV_GPIO0_OFFSET 0x10
+#define RV1106_DRV_GPIO1_OFFSET 0x80
+#define RV1106_DRV_GPIO2_OFFSET 0x100c0
+#define RV1106_DRV_GPIO3_OFFSET 0x20100
+#define RV1106_DRV_GPIO4_OFFSET 0x30020
+
+static int rv1106_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;
+
+ /* GPIO0_IOC is located in the PMU */
+ switch (bank->bank_num) {
+ case 0:
+ *regmap = priv->regmap_pmu;
+ *reg = RV1106_DRV_GPIO0_OFFSET;
+ break;
+ case 1:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_DRV_GPIO1_OFFSET;
+ break;
+ case 2:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_DRV_GPIO2_OFFSET;
+ break;
+ case 3:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_DRV_GPIO3_OFFSET;
+ break;
+ case 4:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_DRV_GPIO4_OFFSET;
+ break;
+ default:
+ printf("unsupported bank_num %d\n", bank->bank_num);
+ return -EINVAL;
+ }
+
+ *reg += ((pin_num / RV1106_DRV_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1106_DRV_PINS_PER_REG;
+ *bit *= RV1106_DRV_BITS_PER_PIN;
+
+ return 0;
+}
+
+static int rv1106_set_drive(struct rockchip_pin_bank *bank,
+ int pin_num, int strength)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u32 data, rmask;
+ u8 bit;
+ int drv = (1 << (strength + 1)) - 1;
+
+ ret = rv1106_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ if (ret)
+ return ret;
+
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << RV1106_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+ rmask = data | (data >> 16);
+ data |= (drv << bit);
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+}
+
+#define RV1106_PULL_BITS_PER_PIN 2
+#define RV1106_PULL_PINS_PER_REG 8
+#define RV1106_PULL_GPIO0_OFFSET 0x38
+#define RV1106_PULL_GPIO1_OFFSET 0x1c0
+#define RV1106_PULL_GPIO2_OFFSET 0x101d0
+#define RV1106_PULL_GPIO3_OFFSET 0x201e0
+#define RV1106_PULL_GPIO4_OFFSET 0x30070
+
+static int rv1106_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;
+
+ /* GPIO0_IOC is located in the PMU */
+ switch (bank->bank_num) {
+ case 0:
+ *regmap = priv->regmap_pmu;
+ *reg = RV1106_PULL_GPIO0_OFFSET;
+ break;
+ case 1:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_PULL_GPIO1_OFFSET;
+ break;
+ case 2:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_PULL_GPIO2_OFFSET;
+ break;
+ case 3:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_PULL_GPIO3_OFFSET;
+ break;
+ case 4:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_PULL_GPIO4_OFFSET;
+ break;
+ default:
+ printf("unsupported bank_num %d\n", bank->bank_num);
+ return -EINVAL;
+ }
+
+ *reg += ((pin_num / RV1106_PULL_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1106_PULL_PINS_PER_REG;
+ *bit *= RV1106_PULL_BITS_PER_PIN;
+
+ return 0;
+}
+
+static int rv1106_set_pull(struct rockchip_pin_bank *bank,
+ int pin_num, int pull)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u8 bit, type;
+ u32 data, rmask;
+
+ if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+ return -ENOTSUPP;
+
+ ret = rv1106_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ if (ret)
+ return ret;
+
+ type = bank->pull_type[pin_num / 8];
+ 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 << RV1106_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+ rmask = data | (data >> 16);
+ data |= (ret << bit);
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+}
+
+#define RV1106_SMT_BITS_PER_PIN 1
+#define RV1106_SMT_PINS_PER_REG 8
+#define RV1106_SMT_GPIO0_OFFSET 0x40
+#define RV1106_SMT_GPIO1_OFFSET 0x280
+#define RV1106_SMT_GPIO2_OFFSET 0x10290
+#define RV1106_SMT_GPIO3_OFFSET 0x202a0
+#define RV1106_SMT_GPIO4_OFFSET 0x300a0
+
+static int rv1106_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;
+
+ /* GPIO0_IOC is located in the PMU */
+ switch (bank->bank_num) {
+ case 0:
+ *regmap = priv->regmap_pmu;
+ *reg = RV1106_SMT_GPIO0_OFFSET;
+ break;
+ case 1:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_SMT_GPIO1_OFFSET;
+ break;
+ case 2:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_SMT_GPIO2_OFFSET;
+ break;
+ case 3:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_SMT_GPIO3_OFFSET;
+ break;
+ case 4:
+ *regmap = priv->regmap_base;
+ *reg = RV1106_SMT_GPIO4_OFFSET;
+ break;
+ default:
+ printf("unsupported bank_num %d\n", bank->bank_num);
+ return -EINVAL;
+ }
+
+ *reg += ((pin_num / RV1106_SMT_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1106_SMT_PINS_PER_REG;
+ *bit *= RV1106_SMT_BITS_PER_PIN;
+
+ return 0;
+}
+
+static int rv1106_set_schmitt(struct rockchip_pin_bank *bank,
+ int pin_num, int enable)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u32 data, rmask;
+ u8 bit;
+
+ ret = rv1106_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®,
+ &bit);
+ if (ret)
+ return ret;
+
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << RV1106_SMT_BITS_PER_PIN) - 1) << (bit + 16);
+ rmask = data | (data >> 16);
+ data |= (enable << bit);
+
+ return regmap_update_bits(regmap, reg, rmask, data);
+}
+
+static struct rockchip_pin_bank rv1106_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0",
+ IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+ IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+ IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+ IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0, 0x08, 0x10, 0x18),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0x10020, 0x10028, 0, 0),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0x20040, 0x20048, 0x20050, 0x20058),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(4, 24, "gpio4",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0,
+ 0x30000, 0x30008, 0x30010, 0),
+};
+
+static const struct rockchip_pin_ctrl rv1106_pin_ctrl = {
+ .pin_banks = rv1106_pin_banks,
+ .nr_banks = ARRAY_SIZE(rv1106_pin_banks),
+ .grf_mux_offset = 0x0,
+ .pmu_mux_offset = 0x0,
+ .set_mux = rv1106_set_mux,
+ .set_pull = rv1106_set_pull,
+ .set_drive = rv1106_set_drive,
+ .set_schmitt = rv1106_set_schmitt,
+};
+
+static const struct udevice_id rv1106_pinctrl_ids[] = {
+ {
+ .compatible = "rockchip,rv1106-pinctrl",
+ .data = (ulong)&rv1106_pin_ctrl
+ },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rv1106) = {
+ .name = "rockchip_rv1106_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = rv1106_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.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 11/15] ARM: dts: Add the RV1103/RV1106 devicetree files
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (9 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 10/15] pinctrl: rockchip: " Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 12/15] clk: rockchip: Add RV1106 clock driver Simon Glass
` (4 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Albert Aribaud,
Ilias Apalodimas, Kever Yang, Philipp Tomsich, Tom Rini
Add the SoC devicetree files for the Rockchip RV1106 and its RV1103
package variant, based on the devicetrees in the Rockchip vendor tree,
trimmed to the devices that U-Boot supports.
The files come from the Luckfox Pico SDK [1] at commit 824b817f8:
rv1106-pinctrl.dtsi and the rv1106-cru.h binding header are verbatim
copies from its U-Boot tree (2017.09-based, with only the pinconf
include path adjusted), rv1106.dtsi is a trimmed version of the same
tree's file with the camera, codec and other vendor-only nodes
removed, and rv1103.dtsi follows the pattern of the corresponding
file in its kernel tree (Linux 5.10.160).
Neither SoC is supported in mainline Linux and no support is in
review, so there are no upstream devicetrees to inherit. Once Linux
gains RV1106 devicetrees, the OF_UPSTREAM mechanism can be enabled and
these files dropped.
[1] https://github.com/LuckfoxTECH/luckfox-pico
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
arch/arm/dts/rv1103.dtsi | 16 +
arch/arm/dts/rv1106-pinctrl.dtsi | 1102 ++++++++++++++++++++++++
arch/arm/dts/rv1106.dtsi | 328 +++++++
include/dt-bindings/clock/rv1106-cru.h | 572 ++++++++++++
4 files changed, 2018 insertions(+)
create mode 100644 arch/arm/dts/rv1103.dtsi
create mode 100644 arch/arm/dts/rv1106-pinctrl.dtsi
create mode 100644 arch/arm/dts/rv1106.dtsi
create mode 100644 include/dt-bindings/clock/rv1106-cru.h
diff --git a/arch/arm/dts/rv1103.dtsi b/arch/arm/dts/rv1103.dtsi
new file mode 100644
index 00000000000..025fde5bf09
--- /dev/null
+++ b/arch/arm/dts/rv1103.dtsi
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ */
+
+#include "rv1106.dtsi"
+
+/ {
+ compatible = "rockchip,rv1103";
+
+ aliases {
+ /delete-property/ gpio2;
+ };
+};
+
+/delete-node/ &gpio2;
diff --git a/arch/arm/dts/rv1106-pinctrl.dtsi b/arch/arm/dts/rv1106-pinctrl.dtsi
new file mode 100644
index 00000000000..8338556dafd
--- /dev/null
+++ b/arch/arm/dts/rv1106-pinctrl.dtsi
@@ -0,0 +1,1102 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 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 {
+ adc {
+ adc_pins: adc-pins {
+ rockchip,pins =
+ /* adc_in0 */
+ <4 RK_PC0 1 &pcfg_pull_none>,
+ /* adc_in1 */
+ <4 RK_PC1 1 &pcfg_pull_none>;
+ };
+ };
+
+ avs {
+ avs_pins: avs-pins {
+ rockchip,pins =
+ /* avs_arm */
+ <1 RK_PA2 2 &pcfg_pull_none>;
+ };
+ };
+
+ clk {
+ clk_32k: clk-32k {
+ rockchip,pins =
+ /* clk_32k */
+ <0 RK_PA0 2 &pcfg_pull_none>;
+ };
+ clk_refout: clk-refout {
+ rockchip,pins =
+ /* clk_refout */
+ <0 RK_PA0 3 &pcfg_pull_none>;
+ };
+ };
+
+ dsmaudio {
+ dsmaudio_pins: dsmaudio-pins {
+ rockchip,pins =
+ /* dsmaudio_n */
+ <1 RK_PD3 7 &pcfg_pull_none>,
+ /* dsmaudio_p */
+ <1 RK_PD2 7 &pcfg_pull_none>;
+ };
+ };
+
+ emmc {
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins =
+ /* emmc_d0 */
+ <4 RK_PA4 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d1 */
+ <4 RK_PA3 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d2 */
+ <4 RK_PA2 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d3 */
+ <4 RK_PA6 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d4 */
+ <4 RK_PA5 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d5 */
+ <4 RK_PA7 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d6 */
+ <4 RK_PA1 1 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d7 */
+ <4 RK_PA0 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ emmc_clk: emmc-clk {
+ rockchip,pins =
+ /* emmc_clk */
+ <4 RK_PB1 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins =
+ /* emmc_cmd */
+ <4 RK_PB0 1 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+
+ flash {
+ flash_pins: flash-pins {
+ rockchip,pins =
+ /* flash_trig_out */
+ <2 RK_PA6 6 &pcfg_pull_none>;
+ };
+ };
+
+ fspi {
+ fspi_pins: fspi-pins {
+ rockchip,pins =
+ /* fspi_clk */
+ <4 RK_PB1 2 &pcfg_pull_up_drv_level_2>,
+ /* fspi_d0 */
+ <4 RK_PA4 2 &pcfg_pull_none>,
+ /* fspi_d1 */
+ <4 RK_PA3 2 &pcfg_pull_none>,
+ /* fspi_d2 */
+ <4 RK_PA2 2 &pcfg_pull_none>,
+ /* fspi_d3 */
+ <4 RK_PA6 2 &pcfg_pull_none>;
+ };
+
+ fspi_cs0: fspi-cs0 {
+ rockchip,pins =
+ /* fspi_cs0n */
+ <4 RK_PB0 2 &pcfg_pull_up>;
+ };
+ };
+
+ hpmcu {
+ hpmcum0_pins: hpmcum0-pins {
+ rockchip,pins =
+ /* hpmcu_jtag_tck_m0 */
+ <1 RK_PB2 3 &pcfg_pull_none>,
+ /* hpmcu_jtag_tms_m0 */
+ <1 RK_PB3 3 &pcfg_pull_none>;
+ };
+
+ hpmcum1_pins: hpmcum1-pins {
+ rockchip,pins =
+ /* hpmcu_jtag_tck_m1 */
+ <3 RK_PA7 4 &pcfg_pull_none>,
+ /* hpmcu_jtag_tms_m1 */
+ <3 RK_PA6 4 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0m0_xfer: i2c0m0-xfer {
+ rockchip,pins =
+ /* i2c0_scl_m0 */
+ <1 RK_PA3 2 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m0 */
+ <1 RK_PA4 2 &pcfg_pull_none_smt>;
+ };
+
+ i2c0m1_xfer: i2c0m1-xfer {
+ rockchip,pins =
+ /* i2c0_scl_m1 */
+ <4 RK_PA1 4 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m1 */
+ <4 RK_PA0 4 &pcfg_pull_none_smt>;
+ };
+
+ i2c0m2_xfer: i2c0m2-xfer {
+ rockchip,pins =
+ /* i2c0_scl_m2 */
+ <3 RK_PA4 3 &pcfg_pull_none_smt>,
+ /* i2c0_sda_m2 */
+ <3 RK_PA5 3 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c1 {
+ i2c1m0_xfer: i2c1m0-xfer {
+ rockchip,pins =
+ /* i2c1_scl_m0 */
+ <0 RK_PA5 1 &pcfg_pull_none_smt>,
+ /* i2c1_sda_m0 */
+ <0 RK_PA6 1 &pcfg_pull_none_smt>;
+ };
+
+ i2c1m1_xfer: i2c1m1-xfer {
+ rockchip,pins =
+ /* i2c1_scl_m1 */
+ <2 RK_PB0 2 &pcfg_pull_none_smt>,
+ /* i2c1_sda_m1 */
+ <2 RK_PB1 2 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c2 {
+ i2c2m0_xfer: i2c2m0-xfer {
+ rockchip,pins =
+ /* i2c2_scl_m0 */
+ <1 RK_PA0 2 &pcfg_pull_none_smt>,
+ /* i2c2_sda_m0 */
+ <1 RK_PA1 2 &pcfg_pull_none_smt>;
+ };
+
+ i2c2m1_xfer: i2c2m1-xfer {
+ rockchip,pins =
+ /* i2c2_scl_m1 */
+ <4 RK_PA7 4 &pcfg_pull_none_smt>,
+ /* i2c2_sda_m1 */
+ <4 RK_PA5 4 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c3 {
+ i2c3m0_xfer: i2c3m0-xfer {
+ rockchip,pins =
+ /* i2c3_scl_m0 */
+ <2 RK_PA6 5 &pcfg_pull_none_smt>,
+ /* i2c3_sda_m0 */
+ <2 RK_PA7 5 &pcfg_pull_none_smt>;
+ };
+
+ i2c3m1_xfer: i2c3m1-xfer {
+ rockchip,pins =
+ /* i2c3_scl_m1 */
+ <1 RK_PD3 3 &pcfg_pull_none_smt>,
+ /* i2c3_sda_m1 */
+ <1 RK_PD2 3 &pcfg_pull_none_smt>;
+ };
+
+ i2c3m2_xfer: i2c3m2-xfer {
+ rockchip,pins =
+ /* i2c3_scl_m2 */
+ <3 RK_PD1 3 &pcfg_pull_none_smt>,
+ /* i2c3_sda_m2 */
+ <3 RK_PD2 3 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2c4 {
+ i2c4m0_xfer: i2c4m0-xfer {
+ rockchip,pins =
+ /* i2c4_scl_m0 */
+ <2 RK_PA1 5 &pcfg_pull_none_smt>,
+ /* i2c4_sda_m0 */
+ <2 RK_PA0 5 &pcfg_pull_none_smt>;
+ };
+
+ i2c4m1_xfer: i2c4m1-xfer {
+ rockchip,pins =
+ /* i2c4_scl_m1 */
+ <1 RK_PC2 4 &pcfg_pull_none_smt>,
+ /* i2c4_sda_m1 */
+ <1 RK_PC3 4 &pcfg_pull_none_smt>;
+ };
+
+ i2c4m2_xfer: i2c4m2-xfer {
+ rockchip,pins =
+ /* i2c4_scl_m2 */
+ <3 RK_PC7 3 &pcfg_pull_none_smt>,
+ /* i2c4_sda_m2 */
+ <3 RK_PD0 3 &pcfg_pull_none_smt>;
+ };
+ };
+
+ i2s0 {
+ i2s0_pins: i2s0-pins {
+ rockchip,pins =
+ /* i2s0_lrck */
+ <2 RK_PA1 2 &pcfg_pull_none>,
+ /* i2s0_mclk */
+ <2 RK_PA2 2 &pcfg_pull_none>,
+ /* i2s0_sclk */
+ <2 RK_PA0 2 &pcfg_pull_none>,
+ /* i2s0_sdi0 */
+ <2 RK_PA5 2 &pcfg_pull_none>,
+ /* i2s0_sdo0 */
+ <2 RK_PA4 2 &pcfg_pull_none>,
+ /* i2s0_sdo1_sdi3 */
+ <2 RK_PA7 2 &pcfg_pull_none>,
+ /* i2s0_sdo2_sdi2 */
+ <2 RK_PA6 2 &pcfg_pull_none>,
+ /* i2s0_sdo3_sdi1 */
+ <2 RK_PA3 2 &pcfg_pull_none>;
+ };
+ };
+
+ lcd {
+ lcd_pins: lcd-pins {
+ rockchip,pins =
+ /* lcd_clk */
+ <1 RK_PD3 1 &pcfg_pull_none>,
+ /* lcd_d0 */
+ <1 RK_PC7 1 &pcfg_pull_none>,
+ /* lcd_d1 */
+ <1 RK_PC6 1 &pcfg_pull_none>,
+ /* lcd_d2 */
+ <1 RK_PC5 1 &pcfg_pull_none>,
+ /* lcd_d3 */
+ <1 RK_PC4 1 &pcfg_pull_none>,
+ /* lcd_d4 */
+ <1 RK_PC3 1 &pcfg_pull_none>,
+ /* lcd_d5 */
+ <1 RK_PC2 1 &pcfg_pull_none>,
+ /* lcd_d6 */
+ <1 RK_PC1 1 &pcfg_pull_none>,
+ /* lcd_d7 */
+ <1 RK_PC0 1 &pcfg_pull_none>,
+ /* lcd_d8 */
+ <2 RK_PA0 3 &pcfg_pull_none>,
+ /* lcd_d9 */
+ <2 RK_PA1 3 &pcfg_pull_none>,
+ /* lcd_d10 */
+ <2 RK_PA2 3 &pcfg_pull_none>,
+ /* lcd_d11 */
+ <2 RK_PA3 3 &pcfg_pull_none>,
+ /* lcd_d12 */
+ <2 RK_PA4 3 &pcfg_pull_none>,
+ /* lcd_d13 */
+ <2 RK_PA5 3 &pcfg_pull_none>,
+ /* lcd_d14 */
+ <2 RK_PA6 3 &pcfg_pull_none>,
+ /* lcd_d15 */
+ <2 RK_PA7 3 &pcfg_pull_none>,
+ /* lcd_d16 */
+ <2 RK_PB0 3 &pcfg_pull_none>,
+ /* lcd_d17 */
+ <2 RK_PB1 3 &pcfg_pull_none>,
+ /* lcd_den */
+ <1 RK_PD0 1 &pcfg_pull_none>,
+ /* lcd_hsync */
+ <1 RK_PD1 1 &pcfg_pull_none>,
+ /* lcd_vsync */
+ <1 RK_PD2 1 &pcfg_pull_none>;
+ };
+ };
+
+ lpmcu {
+ lpmcum0_pins: lpmcum0-pins {
+ rockchip,pins =
+ /* lpmcu_jtag_tck_m0 */
+ <1 RK_PB2 4 &pcfg_pull_none>,
+ /* lpmcu_jtag_tms_m0 */
+ <1 RK_PB3 4 &pcfg_pull_none>;
+ };
+
+ lpmcum1_pins: lpmcum1-pins {
+ rockchip,pins =
+ /* lpmcu_jtag_tck_m1 */
+ <3 RK_PA4 4 &pcfg_pull_none>,
+ /* lpmcu_jtag_tms_m1 */
+ <3 RK_PA5 4 &pcfg_pull_none>;
+ };
+ };
+
+ mipi {
+ mipi_pins: mipi-pins {
+ rockchip,pins =
+ /* mipi_lvds_ck0n */
+ <3 RK_PC0 2 &pcfg_pull_none>,
+ /* mipi_lvds_ck0p */
+ <3 RK_PC1 2 &pcfg_pull_none>,
+ /* mipi_lvds_ck1n */
+ <3 RK_PB2 2 &pcfg_pull_none>,
+ /* mipi_lvds_ck1p */
+ <3 RK_PB3 2 &pcfg_pull_none>,
+ /* mipi_lvds_d0n */
+ <3 RK_PC2 2 &pcfg_pull_none>,
+ /* mipi_lvds_d0p */
+ <3 RK_PC3 2 &pcfg_pull_none>,
+ /* mipi_lvds_d1n */
+ <3 RK_PB6 2 &pcfg_pull_none>,
+ /* mipi_lvds_d1p */
+ <3 RK_PB7 2 &pcfg_pull_none>,
+ /* mipi_lvds_d2n */
+ <3 RK_PB4 2 &pcfg_pull_none>,
+ /* mipi_lvds_d2p */
+ <3 RK_PB5 2 &pcfg_pull_none>,
+ /* mipi_lvds_d3n */
+ <3 RK_PB0 2 &pcfg_pull_none>,
+ /* mipi_lvds_d3p */
+ <3 RK_PB1 2 &pcfg_pull_none>,
+ /* mipi_refclk_out0 */
+ <3 RK_PC4 2 &pcfg_pull_none>,
+ /* mipi_refclk_out1 */
+ <3 RK_PC6 3 &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmicm0_pins: pmicm0-pins {
+ rockchip,pins =
+ /* pmic_sleep_m0 */
+ <0 RK_PA4 1 &pcfg_pull_none>;
+ };
+
+ pmicm1_pins: pmicm1-pins {
+ rockchip,pins =
+ /* pmic_sleep_m1 */
+ <0 RK_PA3 1 &pcfg_pull_none>;
+ };
+ };
+
+ pmu {
+ pmu_pins: pmu-pins {
+ rockchip,pins =
+ /* pmu_debug */
+ <1 RK_PA1 3 &pcfg_pull_none>;
+ };
+ };
+
+ prelight {
+ prelight_pins: prelight-pins {
+ rockchip,pins =
+ /* prelight_trig_out */
+ <2 RK_PA7 6 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0m0_pins: pwm0m0-pins {
+ rockchip,pins =
+ /* pwm0_m0 */
+ <1 RK_PA2 1 &pcfg_pull_none>;
+ };
+
+ pwm0m1_pins: pwm0m1-pins {
+ rockchip,pins =
+ /* pwm0_m1 */
+ <1 RK_PD2 6 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1m0_pins: pwm1m0-pins {
+ rockchip,pins =
+ /* pwm1_m0 */
+ <0 RK_PA4 2 &pcfg_pull_none>;
+ };
+
+ pwm1m1_pins: pwm1m1-pins {
+ rockchip,pins =
+ /* pwm1_m1 */
+ <4 RK_PC1 2 &pcfg_pull_none>;
+ };
+
+ pwm1m2_pins: pwm1m2-pins {
+ rockchip,pins =
+ /* pwm1_m2 */
+ <3 RK_PD3 2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2m0_pins: pwm2m0-pins {
+ rockchip,pins =
+ /* pwm2_m0 */
+ <0 RK_PA1 2 &pcfg_pull_none>;
+ };
+
+ pwm2m1_pins: pwm2m1-pins {
+ rockchip,pins =
+ /* pwm2_m1 */
+ <2 RK_PA6 4 &pcfg_pull_none>;
+ };
+
+ pwm2m2_pins: pwm2m2-pins {
+ rockchip,pins =
+ /* pwm2_m2 */
+ <1 RK_PC0 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3m0_pins: pwm3m0-pins {
+ rockchip,pins =
+ /* pwm3_ir_m0 */
+ <0 RK_PA2 1 &pcfg_pull_none>;
+ };
+
+ pwm3m1_pins: pwm3m1-pins {
+ rockchip,pins =
+ /* pwm3_ir_m1 */
+ <1 RK_PB0 2 &pcfg_pull_none>;
+ };
+
+ pwm3m2_pins: pwm3m2-pins {
+ rockchip,pins =
+ /* pwm3_ir_m2 */
+ <1 RK_PD0 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm4 {
+ pwm4m0_pins: pwm4m0-pins {
+ rockchip,pins =
+ /* pwm4_m0 */
+ <1 RK_PA1 4 &pcfg_pull_none>;
+ };
+
+ pwm4m1_pins: pwm4m1-pins {
+ rockchip,pins =
+ /* pwm4_m1 */
+ <2 RK_PA7 4 &pcfg_pull_none>;
+ };
+
+ pwm4m2_pins: pwm4m2-pins {
+ rockchip,pins =
+ /* pwm4_m2 */
+ <1 RK_PC1 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm5 {
+ pwm5m0_pins: pwm5m0-pins {
+ rockchip,pins =
+ /* pwm5_m0 */
+ <0 RK_PA5 3 &pcfg_pull_none>;
+ };
+
+ pwm5m1_pins: pwm5m1-pins {
+ rockchip,pins =
+ /* pwm5_m1 */
+ <2 RK_PB0 4 &pcfg_pull_none>;
+ };
+
+ pwm5m2_pins: pwm5m2-pins {
+ rockchip,pins =
+ /* pwm5_m2 */
+ <1 RK_PC2 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm6 {
+ pwm6m0_pins: pwm6m0-pins {
+ rockchip,pins =
+ /* pwm6_m0 */
+ <0 RK_PA6 3 &pcfg_pull_none>;
+ };
+
+ pwm6m1_pins: pwm6m1-pins {
+ rockchip,pins =
+ /* pwm6_m1 */
+ <2 RK_PB1 4 &pcfg_pull_none>;
+ };
+
+ pwm6m2_pins: pwm6m2-pins {
+ rockchip,pins =
+ /* pwm6_m2 */
+ <1 RK_PC3 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm7 {
+ pwm7m0_pins: pwm7m0-pins {
+ rockchip,pins =
+ /* pwm7_ir_m0 */
+ <1 RK_PA0 3 &pcfg_pull_none>;
+ };
+
+ pwm7m1_pins: pwm7m1-pins {
+ rockchip,pins =
+ /* pwm7_ir_m1 */
+ <1 RK_PB1 2 &pcfg_pull_none>;
+ };
+
+ pwm7m2_pins: pwm7m2-pins {
+ rockchip,pins =
+ /* pwm7_ir_m2 */
+ <3 RK_PC6 2 &pcfg_pull_none>;
+ };
+ };
+
+ pwm8 {
+ pwm8m0_pins: pwm8m0-pins {
+ rockchip,pins =
+ /* pwm8_m0 */
+ <3 RK_PA3 4 &pcfg_pull_none>;
+ };
+
+ pwm8m1_pins: pwm8m1-pins {
+ rockchip,pins =
+ /* pwm8_m1 */
+ <1 RK_PC4 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm9 {
+ pwm9m0_pins: pwm9m0-pins {
+ rockchip,pins =
+ /* pwm9_m0 */
+ <3 RK_PA2 4 &pcfg_pull_none>;
+ };
+
+ pwm9m1_pins: pwm9m1-pins {
+ rockchip,pins =
+ /* pwm9_m1 */
+ <1 RK_PC5 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm10 {
+ pwm10m0_pins: pwm10m0-pins {
+ rockchip,pins =
+ /* pwm10_m0 */
+ <3 RK_PA4 5 &pcfg_pull_none>;
+ };
+
+ pwm10m1_pins: pwm10m1-pins {
+ rockchip,pins =
+ /* pwm10_m1 */
+ <1 RK_PC6 3 &pcfg_pull_none>;
+ };
+
+ pwm10m2_pins: pwm10m2-pins {
+ rockchip,pins =
+ /* pwm10_m2 */
+ <1 RK_PD1 3 &pcfg_pull_none>;
+ };
+ };
+
+ pwm11 {
+ pwm11m0_pins: pwm11m0-pins {
+ rockchip,pins =
+ /* pwm11_ir_m0 */
+ <3 RK_PA5 5 &pcfg_pull_none>;
+ };
+
+ pwm11m1_pins: pwm11m1-pins {
+ rockchip,pins =
+ /* pwm11_ir_m1 */
+ <1 RK_PC7 3 &pcfg_pull_none>;
+ };
+
+ pwm11m2_pins: pwm11m2-pins {
+ rockchip,pins =
+ /* pwm11_ir_m2 */
+ <1 RK_PD3 5 &pcfg_pull_none>;
+ };
+ };
+
+ rtc {
+ rtc_pins: rtc-pins {
+ rockchip,pins =
+ /* rtc_clko */
+ <0 RK_PA0 4 &pcfg_pull_none>;
+ };
+ };
+
+ sdmmc0: sdmmc0 {
+ sdmmc0_bus4: sdmmc0-bus4 {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <3 RK_PA3 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d1 */
+ <3 RK_PA2 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d2 */
+ <3 RK_PA7 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d3 */
+ <3 RK_PA6 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc0_clk: sdmmc0-clk {
+ rockchip,pins =
+ /* sdmmc0_clk */
+ <3 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc0_cmd: sdmmc0-cmd {
+ rockchip,pins =
+ /* sdmmc0_cmd */
+ <3 RK_PA5 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc0_det: sdmmc0-det {
+ rockchip,pins =
+ /* sdmmc0_det */
+ <3 RK_PA1 1 &pcfg_pull_up>;
+ };
+
+ sdmmc0_idle_pins: sdmmc0-idle-pins {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <3 RK_PA3 1 &pcfg_pull_down>,
+ /* sdmmc0_d1 */
+ <3 RK_PA2 1 &pcfg_pull_down>,
+ /* sdmmc0_d2 */
+ <3 RK_PA7 1 &pcfg_pull_down>,
+ /* sdmmc0_d3 */
+ <3 RK_PA6 1 &pcfg_pull_down>,
+ /* sdmmc0_clk */
+ <3 RK_PA4 1 &pcfg_pull_down>,
+ /* sdmmc0_cmd */
+ <3 RK_PA5 1 &pcfg_pull_down>;
+ };
+ };
+
+ sdmmc1 {
+ sdmmc1m0_bus4: sdmmc1m0-bus4 {
+ rockchip,pins =
+ /* sdmmc1_d0_m0 */
+ <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d1_m0 */
+ <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d2_m0 */
+ <2 RK_PA5 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d3_m0 */
+ <2 RK_PA4 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc1m0_clk: sdmmc1m0-clk {
+ rockchip,pins =
+ /* sdmmc1_clk_m0 */
+ <2 RK_PA2 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc1m0_cmd: sdmmc1m0-cmd {
+ rockchip,pins =
+ /* sdmmc1_cmd_m0 */
+ <2 RK_PA3 1 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc1m1_bus4: sdmmc1m1-bus4 {
+ rockchip,pins =
+ /* sdmmc1_d0_m1 */
+ <1 RK_PC1 5 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d1_m1 */
+ <1 RK_PC0 5 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d2_m1 */
+ <1 RK_PC5 5 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d3_m1 */
+ <1 RK_PC4 5 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc1m1_clk: sdmmc1m1-clk {
+ rockchip,pins =
+ /* sdmmc1_clk_m1 */
+ <1 RK_PC2 5 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc1m1_cmd: sdmmc1m1-cmd {
+ rockchip,pins =
+ /* sdmmc1_cmd_m1 */
+ <1 RK_PC3 5 &pcfg_pull_up_drv_level_2>;
+ };
+
+ sdmmc1m1_idle_pins: sdmmc1m1-idle-pins {
+ rockchip,pins =
+ /* sdmmc1_d0_m1 */
+ <1 RK_PC1 5 &pcfg_pull_down>,
+ /* sdmmc1_d1_m1 */
+ <1 RK_PC0 5 &pcfg_pull_down>,
+ /* sdmmc1_d2_m1 */
+ <1 RK_PC5 5 &pcfg_pull_down>,
+ /* sdmmc1_d3_m1 */
+ <1 RK_PC4 5 &pcfg_pull_down>,
+ /* sdmmc1_clk_m1 */
+ <1 RK_PC2 5 &pcfg_pull_down>,
+ /* sdmmc1_cmd_m1 */
+ <1 RK_PC3 5 &pcfg_pull_down>;
+ };
+ };
+
+ spi0 {
+ spi0m0_pins: spi0m0-pins {
+ rockchip,pins =
+ /* spi0_clk_m0 */
+ <1 RK_PC1 4 &pcfg_pull_none>,
+ /* spi0_miso_m0 */
+ <1 RK_PC3 6 &pcfg_pull_none>,
+ /* spi0_mosi_m0 */
+ <1 RK_PC2 6 &pcfg_pull_none>;
+ };
+
+ spi0m0_cs0: spi0m0-cs0 {
+ rockchip,pins =
+ /* spi0_cs0n_m0 */
+ <1 RK_PC0 4 &pcfg_pull_none>;
+ };
+
+ spi0m0_cs1: spi0m0-cs1 {
+ rockchip,pins =
+ /* spi0_cs1n_m0 */
+ <1 RK_PD2 5 &pcfg_pull_none>;
+ };
+ };
+
+ spi1 {
+ spi1m0_pins: spi1m0-pins {
+ rockchip,pins =
+ /* spi1_clk_m0 */
+ <4 RK_PA7 2 &pcfg_pull_none>,
+ /* spi1_miso_m0 */
+ <4 RK_PA0 2 &pcfg_pull_none>,
+ /* spi1_mosi_m0 */
+ <4 RK_PA1 2 &pcfg_pull_none>;
+ };
+
+ spi1m0_cs0: spi1m0-cs0 {
+ rockchip,pins =
+ /* spi1_cs0n_m0 */
+ <4 RK_PA5 2 &pcfg_pull_none>;
+ };
+
+ spi1m0_cs1: spi1m0-cs1 {
+ rockchip,pins =
+ /* spi1_cs1n_m0 */
+ <1 RK_PB1 3 &pcfg_pull_none>;
+ };
+ };
+
+ uart0 {
+ uart0m0_xfer: uart0m0-xfer {
+ rockchip,pins =
+ /* uart0_rx_m0 */
+ <0 RK_PA0 1 &pcfg_pull_up>,
+ /* uart0_tx_m0 */
+ <0 RK_PA1 1 &pcfg_pull_up>;
+ };
+
+ uart0m1_xfer: uart0m1-xfer {
+ rockchip,pins =
+ /* uart0_rx_m1 */
+ <2 RK_PB0 1 &pcfg_pull_up>,
+ /* uart0_tx_m1 */
+ <2 RK_PB1 1 &pcfg_pull_up>;
+ };
+
+ uart0m1_ctsn: uart0m1-ctsn {
+ rockchip,pins =
+ /* uart0m1_ctsn */
+ <2 RK_PA7 1 &pcfg_pull_none>;
+ };
+ uart0m1_rtsn: uart0m1-rtsn {
+ rockchip,pins =
+ /* uart0m1_rtsn */
+ <2 RK_PA6 1 &pcfg_pull_none>;
+ };
+
+ uart0m2_xfer: uart0m2-xfer {
+ rockchip,pins =
+ /* uart0_rx_m2 */
+ <4 RK_PA0 3 &pcfg_pull_up>,
+ /* uart0_tx_m2 */
+ <4 RK_PA1 3 &pcfg_pull_up>;
+ };
+ };
+
+ uart1 {
+ uart1m0_xfer: uart1m0-xfer {
+ rockchip,pins =
+ /* uart1_rx_m0 */
+ <1 RK_PA4 1 &pcfg_pull_up>,
+ /* uart1_tx_m0 */
+ <1 RK_PA3 1 &pcfg_pull_up>;
+ };
+
+ uart1m0_ctsn: uart1m0-ctsn {
+ rockchip,pins =
+ /* uart1m0_ctsn */
+ <0 RK_PA6 2 &pcfg_pull_none>;
+ };
+ uart1m0_rtsn: uart1m0-rtsn {
+ rockchip,pins =
+ /* uart1m0_rtsn */
+ <0 RK_PA5 2 &pcfg_pull_none>;
+ };
+
+ uart1m1_xfer: uart1m1-xfer {
+ rockchip,pins =
+ /* uart1_rx_m1 */
+ <2 RK_PA5 4 &pcfg_pull_up>,
+ /* uart1_tx_m1 */
+ <2 RK_PA4 4 &pcfg_pull_up>;
+ };
+
+ uart1m1_ctsn: uart1m1-ctsn {
+ rockchip,pins =
+ /* uart1m1_ctsn */
+ <2 RK_PA0 4 &pcfg_pull_none>;
+ };
+ uart1m1_rtsn: uart1m1-rtsn {
+ rockchip,pins =
+ /* uart1m1_rtsn */
+ <2 RK_PA1 4 &pcfg_pull_none>;
+ };
+
+ uart1m2_xfer: uart1m2-xfer {
+ rockchip,pins =
+ /* uart1_rx_m2 */
+ <4 RK_PA7 3 &pcfg_pull_up>,
+ /* uart1_tx_m2 */
+ <4 RK_PA5 3 &pcfg_pull_up>;
+ };
+ };
+
+ uart2 {
+ uart2m0_xfer: uart2m0-xfer {
+ rockchip,pins =
+ /* uart2_rx_m0 */
+ <3 RK_PA3 2 &pcfg_pull_up>,
+ /* uart2_tx_m0 */
+ <3 RK_PA2 2 &pcfg_pull_up>;
+ };
+
+ uart2m1_xfer: uart2m1-xfer {
+ rockchip,pins =
+ /* uart2_rx_m1 */
+ <1 RK_PB3 2 &pcfg_pull_up>,
+ /* uart2_tx_m1 */
+ <1 RK_PB2 2 &pcfg_pull_up>;
+ };
+ };
+
+ uart3 {
+ uart3m0_xfer: uart3m0-xfer {
+ rockchip,pins =
+ /* uart3_rx_m0 */
+ <1 RK_PA1 1 &pcfg_pull_up>,
+ /* uart3_tx_m0 */
+ <1 RK_PA0 1 &pcfg_pull_up>;
+ };
+
+ uart3m1_xfer: uart3m1-xfer {
+ rockchip,pins =
+ /* uart3_rx_m1 */
+ <1 RK_PD1 5 &pcfg_pull_up>,
+ /* uart3_tx_m1 */
+ <1 RK_PD0 5 &pcfg_pull_up>;
+ };
+ };
+
+ uart4 {
+ uart4m0_xfer: uart4m0-xfer {
+ rockchip,pins =
+ /* uart4_rx_m0 */
+ <1 RK_PB0 1 &pcfg_pull_up>,
+ /* uart4_tx_m0 */
+ <1 RK_PB1 1 &pcfg_pull_up>;
+ };
+
+ uart4m1_xfer: uart4m1-xfer {
+ rockchip,pins =
+ /* uart4_rx_m1 */
+ <1 RK_PC4 4 &pcfg_pull_up>,
+ /* uart4_tx_m1 */
+ <1 RK_PC5 4 &pcfg_pull_up>;
+ };
+
+ uart4m1_ctsn: uart4m1-ctsn {
+ rockchip,pins =
+ /* uart4m1_ctsn */
+ <1 RK_PC7 4 &pcfg_pull_none>;
+ };
+ uart4m1_rtsn: uart4m1-rtsn {
+ rockchip,pins =
+ /* uart4m1_rtsn */
+ <1 RK_PC6 4 &pcfg_pull_none>;
+ };
+ };
+
+ uart5 {
+ uart5m0_xfer: uart5m0-xfer {
+ rockchip,pins =
+ /* uart5_rx_m0 */
+ <3 RK_PA7 2 &pcfg_pull_up>,
+ /* uart5_tx_m0 */
+ <3 RK_PA6 2 &pcfg_pull_up>;
+ };
+
+ uart5m0_ctsn: uart5m0-ctsn {
+ rockchip,pins =
+ /* uart5m0_ctsn */
+ <3 RK_PA5 2 &pcfg_pull_none>;
+ };
+ uart5m0_rtsn: uart5m0-rtsn {
+ rockchip,pins =
+ /* uart5m0_rtsn */
+ <3 RK_PA4 2 &pcfg_pull_none>;
+ };
+
+ uart5m1_xfer: uart5m1-xfer {
+ rockchip,pins =
+ /* uart5_rx_m1 */
+ <1 RK_PD2 4 &pcfg_pull_up>,
+ /* uart5_tx_m1 */
+ <1 RK_PD3 4 &pcfg_pull_up>;
+ };
+
+ uart5m1_ctsn: uart5m1-ctsn {
+ rockchip,pins =
+ /* uart5m1_ctsn */
+ <1 RK_PD1 4 &pcfg_pull_none>;
+ };
+ uart5m1_rtsn: uart5m1-rtsn {
+ rockchip,pins =
+ /* uart5m1_rtsn */
+ <1 RK_PD0 4 &pcfg_pull_none>;
+ };
+
+ uart5m2_xfer: uart5m2-xfer {
+ rockchip,pins =
+ /* uart5_rx_m2 */
+ <3 RK_PD0 2 &pcfg_pull_up>,
+ /* uart5_tx_m2 */
+ <3 RK_PC7 2 &pcfg_pull_up>;
+ };
+
+ uart5m2_ctsn: uart5m2-ctsn {
+ rockchip,pins =
+ /* uart5m2_ctsn */
+ <3 RK_PD2 2 &pcfg_pull_none>;
+ };
+ uart5m2_rtsn: uart5m2-rtsn {
+ rockchip,pins =
+ /* uart5m2_rtsn */
+ <3 RK_PD1 2 &pcfg_pull_none>;
+ };
+ };
+
+ vicap {
+ vicapm0_pins: vicapm0-pins {
+ rockchip,pins =
+ /* vicap_clkin_m0 */
+ <3 RK_PC2 1 &pcfg_pull_none>,
+ /* vicap_clkout_m0 */
+ <3 RK_PC4 1 &pcfg_pull_none>,
+ /* vicap_d0_m0 */
+ <3 RK_PB0 1 &pcfg_pull_none>,
+ /* vicap_d1_m0 */
+ <3 RK_PB1 1 &pcfg_pull_none>,
+ /* vicap_d2_m0 */
+ <3 RK_PB2 1 &pcfg_pull_none>,
+ /* vicap_d3_m0 */
+ <3 RK_PB3 1 &pcfg_pull_none>,
+ /* vicap_d4_m0 */
+ <3 RK_PB4 1 &pcfg_pull_none>,
+ /* vicap_d5_m0 */
+ <3 RK_PB5 1 &pcfg_pull_none>,
+ /* vicap_d6_m0 */
+ <3 RK_PB6 1 &pcfg_pull_none>,
+ /* vicap_d7_m0 */
+ <3 RK_PB7 1 &pcfg_pull_none>,
+ /* vicap_d8_m0 */
+ <3 RK_PC0 1 &pcfg_pull_none>,
+ /* vicap_d9_m0 */
+ <3 RK_PC1 1 &pcfg_pull_none>,
+ /* vicap_hsync_m0 */
+ <3 RK_PC3 1 &pcfg_pull_none>,
+ /* vicap_vsync_m0 */
+ <3 RK_PC5 1 &pcfg_pull_none>;
+ };
+
+ vicapm1_pins: vicapm1-pins {
+ rockchip,pins =
+ /* vicap_clkin_m1 */
+ <1 RK_PD0 2 &pcfg_pull_none>,
+ /* vicap_clkout_m1 */
+ <1 RK_PD3 2 &pcfg_pull_none>,
+ /* vicap_d0_m1 */
+ <1 RK_PA2 3 &pcfg_pull_none>,
+ /* vicap_d1_m1 */
+ <1 RK_PB1 4 &pcfg_pull_none>,
+ /* vicap_d2_m1 */
+ <1 RK_PC0 2 &pcfg_pull_none>,
+ /* vicap_d3_m1 */
+ <1 RK_PC1 2 &pcfg_pull_none>,
+ /* vicap_d4_m1 */
+ <1 RK_PC2 2 &pcfg_pull_none>,
+ /* vicap_d5_m1 */
+ <1 RK_PC3 2 &pcfg_pull_none>,
+ /* vicap_d6_m1 */
+ <1 RK_PC4 2 &pcfg_pull_none>,
+ /* vicap_d7_m1 */
+ <1 RK_PC5 2 &pcfg_pull_none>,
+ /* vicap_d8_m1 */
+ <1 RK_PC6 2 &pcfg_pull_none>,
+ /* vicap_d9_m1 */
+ <1 RK_PC7 2 &pcfg_pull_none>,
+ /* vicap_hsync_m1 */
+ <1 RK_PD1 2 &pcfg_pull_none>,
+ /* vicap_vsync_m1 */
+ <1 RK_PD2 2 &pcfg_pull_none>;
+ };
+
+ vicap_d10: vicap-d10 {
+ rockchip,pins =
+ /* vicap_d10 */
+ <3 RK_PC6 1 &pcfg_pull_none>;
+ };
+ vicap_d11: vicap-d11 {
+ rockchip,pins =
+ /* vicap_d11 */
+ <3 RK_PC7 1 &pcfg_pull_none>;
+ };
+ vicap_d12: vicap-d12 {
+ rockchip,pins =
+ /* vicap_d12 */
+ <3 RK_PD0 1 &pcfg_pull_none>;
+ };
+ vicap_d13: vicap-d13 {
+ rockchip,pins =
+ /* vicap_d13 */
+ <3 RK_PD1 1 &pcfg_pull_none>;
+ };
+ vicap_d14: vicap-d14 {
+ rockchip,pins =
+ /* vicap_d14 */
+ <3 RK_PD2 1 &pcfg_pull_none>;
+ };
+ vicap_d15: vicap-d15 {
+ rockchip,pins =
+ /* vicap_d15 */
+ <3 RK_PD3 1 &pcfg_pull_none>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rv1106.dtsi b/arch/arm/dts/rv1106.dtsi
new file mode 100644
index 00000000000..df2386eb31e
--- /dev/null
+++ b/arch/arm/dts/rv1106.dtsi
@@ -0,0 +1,328 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/clock/rv1106-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "rockchip,rv1106";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ gpio0 = &gpio0;
+ gpio1 = &gpio1;
+ gpio2 = &gpio2;
+ gpio3 = &gpio3;
+ gpio4 = &gpio4;
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@f00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf00>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ grf: syscon@ff000000 {
+ compatible = "rockchip,rv1106-grf", "syscon", "simple-mfd";
+ reg = <0xff000000 0x68000>;
+
+ grf_cru: grf-clock-controller {
+ compatible = "rockchip,rv1106-grf-cru";
+ #clock-cells = <1>;
+ };
+ };
+
+ gic: interrupt-controller@ff1f0000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0xff1f1000 0x1000>,
+ <0xff1f2000 0x2000>,
+ <0xff1f4000 0x2000>,
+ <0xff1f6000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ pmuioc: syscon@ff388000 {
+ compatible = "rockchip,rv1106-pmuioc", "syscon";
+ reg = <0xff388000 0x1000>;
+ };
+
+ cru: clock-controller@ff3a0000 {
+ compatible = "rockchip,rv1106-cru";
+ reg = <0xff3a0000 0x20000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ assigned-clocks =
+ <&cru PLL_GPLL>, <&cru PLL_CPLL>,
+ <&cru ARMCLK>,
+ <&cru ACLK_PERI_ROOT>, <&cru HCLK_PERI_ROOT>,
+ <&cru PCLK_PERI_ROOT>, <&cru ACLK_BUS_ROOT>,
+ <&cru PCLK_TOP_ROOT>, <&cru PCLK_PMU_ROOT>,
+ <&cru HCLK_PMU_ROOT>;
+ assigned-clock-rates =
+ <1188000000>, <1000000000>,
+ <816000000>,
+ <400000000>, <200000000>,
+ <100000000>, <300000000>,
+ <100000000>, <100000000>,
+ <200000000>;
+ };
+
+ saradc: saradc@ff3c0000 {
+ compatible = "rockchip,rv1106-saradc";
+ reg = <0xff3c0000 0x100>;
+ interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ resets = <&cru SRST_P_SARADC>;
+ reset-names = "saradc-apb";
+ status = "disabled";
+ };
+
+ uart0: serial@ff4a0000 {
+ compatible = "rockchip,rv1106-uart", "snps,dw-apb-uart";
+ reg = <0xff4a0000 0x100>;
+ interrupts = <GIC_SPI 25 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";
+ status = "disabled";
+ };
+
+ uart1: serial@ff4b0000 {
+ compatible = "rockchip,rv1106-uart", "snps,dw-apb-uart";
+ reg = <0xff4b0000 0x100>;
+ interrupts = <GIC_SPI 26 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";
+ status = "disabled";
+ };
+
+ uart2: serial@ff4c0000 {
+ compatible = "rockchip,rv1106-uart", "snps,dw-apb-uart";
+ reg = <0xff4c0000 0x100>;
+ interrupts = <GIC_SPI 27 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 = <&uart2m1_xfer>;
+ status = "disabled";
+ };
+
+ uart3: serial@ff4d0000 {
+ compatible = "rockchip,rv1106-uart", "snps,dw-apb-uart";
+ reg = <0xff4d0000 0x100>;
+ interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ clock-names = "baudclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ uart4: serial@ff4e0000 {
+ compatible = "rockchip,rv1106-uart", "snps,dw-apb-uart";
+ reg = <0xff4e0000 0x100>;
+ interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+ clock-names = "baudclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ uart5: serial@ff4f0000 {
+ compatible = "rockchip,rv1106-uart", "snps,dw-apb-uart";
+ reg = <0xff4f0000 0x100>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+ clock-names = "baudclk", "apb_pclk";
+ status = "disabled";
+ };
+
+ ioc: syscon@ff538000 {
+ compatible = "rockchip,rv1106-ioc", "syscon";
+ reg = <0xff538000 0x40000>;
+ };
+
+ wdt: watchdog@ff5a0000 {
+ compatible = "rockchip,rv1106-wdt", "snps,dw-wdt";
+ reg = <0xff5a0000 0x100>;
+ clocks = <&cru TCLK_WDT_NS>, <&cru PCLK_WDT_NS>;
+ clock-names = "tclk", "pclk";
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ resets = <&cru SRST_P_WDT_NS>;
+ reset-names = "reset";
+ status = "disabled";
+ };
+
+ emmc: mmc@ffa90000 {
+ compatible = "rockchip,rv1106-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0xffa90000 0x4000>;
+ interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru CCLK_SRC_EMMC>,
+ <&grf_cru SCLK_EMMC_DRV>, <&grf_cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ status = "disabled";
+ };
+
+ sdmmc: mmc@ffaa0000 {
+ compatible = "rockchip,rv1106-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0xffaa0000 0x4000>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC>, <&cru CCLK_SRC_SDMMC>,
+ <&grf_cru SCLK_SDMMC_DRV>, <&grf_cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ cd-gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_HIGH>;
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_det &sdmmc0_bus4>;
+ status = "disabled";
+ };
+
+ sfc: spi@ffac0000 {
+ compatible = "rockchip,sfc";
+ reg = <0xffac0000 0x4000>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ assigned-clocks = <&cru SCLK_SFC>;
+ assigned-clock-rates = <75000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspi_pins &fspi_cs0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rv1106-pinctrl";
+ rockchip,grf = <&ioc>;
+ rockchip,pmu = <&pmuioc>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio@ff380000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff380000 0x100>;
+ interrupts = <GIC_SPI 5 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@ff530000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff530000 0x100>;
+ interrupts = <GIC_SPI 7 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@ff540000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff540000 0x100>;
+ interrupts = <GIC_SPI 9 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>;
+ };
+
+ gpio3: gpio@ff550000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff550000 0x100>;
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 96 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@ff560000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff560000 0x100>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl 0 128 32>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+};
+
+#include "rv1106-pinctrl.dtsi"
diff --git a/include/dt-bindings/clock/rv1106-cru.h b/include/dt-bindings/clock/rv1106-cru.h
new file mode 100644
index 00000000000..8febd5d8a66
--- /dev/null
+++ b/include/dt-bindings/clock/rv1106-cru.h
@@ -0,0 +1,572 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1106_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1106_H
+
+/* pll clocks */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_CPLL 3
+#define PLL_GPLL 4
+#define ARMCLK 5
+
+/* clk (clocks) */
+#define PCLK_DDRPHY 11
+#define PCLK_DDR_ROOT 12
+#define PCLK_DDRMON 13
+#define CLK_TIMER_DDRMON 14
+#define PCLK_DDRC 15
+#define PCLK_DFICTRL 16
+#define ACLK_DDR_ROOT 17
+#define ACLK_SYS_SHRM 18
+#define HCLK_NPU_ROOT 19
+#define ACLK_NPU_ROOT 20
+#define PCLK_NPU_ROOT 21
+#define HCLK_RKNN 22
+#define ACLK_RKNN 23
+#define PCLK_ACODEC 24
+#define MCLK_ACODEC_TX 25
+#define MCLK_ACODEC_RX 26
+#define CLK_CORE_CRYPTO 27
+#define CLK_PKA_CRYPTO 28
+#define ACLK_CRYPTO 29
+#define HCLK_CRYPTO 30
+#define ACLK_DECOM 31
+#define PCLK_DECOM 32
+#define DCLK_DECOM 33
+#define ACLK_DMAC 34
+#define PCLK_DSM 35
+#define MCLK_DSM 36
+#define CCLK_SRC_EMMC 37
+#define HCLK_EMMC 38
+#define PCLK_GPIO4 39
+#define DBCLK_GPIO4 40
+#define PCLK_I2C0 41
+#define CLK_I2C0 42
+#define PCLK_I2C2 43
+#define CLK_I2C2 44
+#define PCLK_I2C3 45
+#define CLK_I2C3 46
+#define PCLK_I2C4 47
+#define CLK_I2C4 48
+#define HCLK_I2S0 49
+#define PCLK_DFT2APB 50
+#define HCLK_IVE 51
+#define ACLK_IVE 52
+#define PCLK_PWM0_PERI 53
+#define CLK_PWM0_PERI 54
+#define CLK_CAPTURE_PWM0_PERI 55
+#define PCLK_PERI_ROOT 56
+#define ACLK_PERI_ROOT 57
+#define HCLK_PERI_ROOT 58
+#define CLK_TIMER_ROOT 59
+#define ACLK_BUS_ROOT 60
+#define HCLK_SFC 61
+#define SCLK_SFC 62
+#define PCLK_UART0 63
+#define CLK_PVTM_CORE 64
+#define PCLK_UART1 65
+#define CLK_CORE_MCU_RTC 66
+#define PCLK_PWM1_PERI 67
+#define CLK_PWM1_PERI 68
+#define CLK_CAPTURE_PWM1_PERI 69
+#define PCLK_PWM2_PERI 70
+#define CLK_PWM2_PERI 71
+#define CLK_CAPTURE_PWM2_PERI 72
+#define HCLK_BOOTROM 73
+#define HCLK_SAI 74
+#define MCLK_SAI 75
+#define PCLK_SARADC 76
+#define CLK_SARADC 77
+#define PCLK_SPI1 78
+#define CLK_SPI1 79
+#define PCLK_STIMER 80
+#define CLK_STIMER0 81
+#define CLK_STIMER1 82
+#define PCLK_TIMER 83
+#define CLK_TIMER0 84
+#define CLK_TIMER1 85
+#define CLK_TIMER2 86
+#define CLK_TIMER3 87
+#define CLK_TIMER4 88
+#define CLK_TIMER5 89
+#define HCLK_TRNG_NS 90
+#define HCLK_TRNG_S 91
+#define PCLK_UART2 92
+#define HCLK_CPU 93
+#define PCLK_UART3 94
+#define CLK_CORE_MCU 95
+#define PCLK_UART4 96
+#define PCLK_DDR_HWLP 97
+#define PCLK_UART5 98
+#define ACLK_USBOTG 100
+#define CLK_REF_USBOTG 101
+#define CLK_UTMI_USBOTG 102
+#define PCLK_USBPHY 103
+#define CLK_REF_USBPHY 104
+#define PCLK_WDT_NS 105
+#define TCLK_WDT_NS 106
+#define PCLK_WDT_S 107
+#define TCLK_WDT_S 108
+#define CLK_DDR_FAIL_SAFE 109
+#define XIN_OSC0_DIV 110
+#define CLK_DEEPSLOW 111
+#define PCLK_PMU_GPIO0 112
+#define DBCLK_PMU_GPIO0 113
+#define CLK_PMU 114
+#define PCLK_PMU 115
+#define PCLK_PMU_HP_TIMER 116
+#define CLK_PMU_HP_TIMER 117
+#define CLK_PMU_32K_HP_TIMER 118
+#define PCLK_I2C1 119
+#define CLK_I2C1 120
+#define PCLK_PMU_IOC 121
+#define PCLK_PMU_MAILBOX 122
+#define CLK_PMU_MCU 123
+#define CLK_PMU_MCU_RTC 124
+#define CLK_PMU_MCU_JTAG 125
+#define CLK_PVTM_PMU 126
+#define PCLK_PVTM_PMU 127
+#define CLK_REFOUT 128
+#define CLK_100M_PMU 129
+#define PCLK_PMU_ROOT 130
+#define HCLK_PMU_ROOT 131
+#define HCLK_PMU_SRAM 132
+#define PCLK_PMU_WDT 133
+#define TCLK_PMU_WDT 134
+#define CLK_DFICTRL 135
+#define CLK_DDRMON 136
+#define CLK_DDR_PHY 137
+#define ACLK_DDRC 138
+#define CLK_CORE_DDRC_SRC 139
+#define CLK_CORE_DDRC 140
+#define CLK_50M_SRC 141
+#define CLK_100M_SRC 142
+#define CLK_150M_SRC 143
+#define CLK_200M_SRC 144
+#define CLK_250M_SRC 145
+#define CLK_300M_SRC 146
+#define CLK_339M_SRC 147
+#define CLK_400M_SRC 148
+#define CLK_450M_SRC 149
+#define CLK_500M_SRC 150
+#define CLK_I2S0_8CH_TX_SRC 151
+#define CLK_I2S0_8CH_TX_FRAC 152
+#define CLK_I2S0_8CH_TX 153
+#define CLK_I2S0_8CH_RX_SRC 154
+#define CLK_I2S0_8CH_RX_FRAC 155
+#define CLK_I2S0_8CH_RX 156
+#define I2S0_8CH_MCLKOUT 157
+#define MCLK_I2S0_8CH_RX 158
+#define MCLK_I2S0_8CH_TX 159
+#define CLK_REF_MIPI0_SRC 160
+#define CLK_REF_MIPI0_FRAC 161
+#define CLK_REF_MIPI0_OUT 162
+#define CLK_REF_MIPI1_SRC 163
+#define CLK_REF_MIPI1_FRAC 164
+#define MCLK_REF_MIPI0 165
+#define MCLK_REF_MIPI1 166
+#define CLK_REF_MIPI0 167
+#define CLK_REF_MIPI1 168
+#define CLK_UART0_SRC 169
+#define CLK_UART0_FRAC 170
+#define CLK_UART0 171
+#define SCLK_UART0 172
+#define CLK_UART1_SRC 173
+#define CLK_UART1_FRAC 174
+#define CLK_UART1 175
+#define SCLK_UART1 176
+#define CLK_UART2_SRC 177
+#define CLK_UART2_FRAC 178
+#define CLK_UART2 179
+#define SCLK_UART2 180
+#define CLK_UART3_SRC 181
+#define CLK_UART3_FRAC 182
+#define CLK_UART3 183
+#define SCLK_UART3 184
+#define CLK_UART4_SRC 185
+#define CLK_UART4_FRAC 186
+#define CLK_UART4 187
+#define SCLK_UART4 188
+#define CLK_UART5_SRC 189
+#define CLK_UART5_FRAC 190
+#define CLK_UART5 191
+#define SCLK_UART5 192
+#define CLK_VICAP_M0_SRC 193
+#define CLK_VICAP_M0_FRAC 194
+#define CLK_VICAP_M0 195
+#define SCLK_VICAP_M0 196
+#define CLK_VICAP_M1_SRC 197
+#define CLK_VICAP_M1_FRAC 198
+#define CLK_VICAP_M1 199
+#define SCLK_VICAP_M1 200
+#define DCLK_VOP_SRC 201
+#define PCLK_CRU 202
+#define PCLK_TOP_ROOT 203
+#define PCLK_SPI0 204
+#define CLK_SPI0 205
+#define SCLK_IN_SPI0 206
+#define CLK_UART_DETN_FLT 207
+#define HCLK_VEPU 208
+#define ACLK_VEPU 209
+#define CLK_CORE_VEPU 210
+#define CLK_CORE_VEPU_DVBM 211
+#define PCLK_GPIO1 212
+#define DBCLK_GPIO1 213
+#define HCLK_VEPU_PP 214
+#define ACLK_VEPU_PP 215
+#define HCLK_VEPU_ROOT 216
+#define ACLK_VEPU_COM_ROOT 217
+#define ACLK_VEPU_ROOT 218
+#define PCLK_VEPU_ROOT 219
+#define PCLK_VICAP_VEPU 220
+#define PCLK_CSIHOST0 221
+#define CLK_RXBYTECLKHS_0 222
+#define PCLK_CSIHOST1 223
+#define CLK_RXBYTECLKHS_1 224
+#define PCLK_GPIO3 225
+#define DBCLK_GPIO3 226
+#define HCLK_ISP3P2 227
+#define ACLK_ISP3P2 228
+#define CLK_CORE_ISP3P2 229
+#define PCLK_MIPICSIPHY 230
+#define CCLK_SRC_SDMMC 231
+#define HCLK_SDMMC 232
+#define CLK_SDMMC_DETN_FLT 233
+#define HCLK_VI_ROOT 234
+#define ACLK_VI_ROOT 235
+#define PCLK_VI_ROOT 236
+#define PCLK_VI_RTC_ROOT 237
+#define PCLK_VI_RTC_TEST 238
+#define PCLK_VI_RTC_PHY 239
+#define DCLK_VICAP 240
+#define PCLK_VICAP 241
+#define ACLK_VICAP 242
+#define HCLK_VICAP 243
+#define I0CLK_VICAP 244
+#define I1CLK_VICAP 245
+#define RX0PCLK_VICAP 246
+#define RX1PCLK_VICAP 247
+#define ISP0CLK_VICAP 248
+#define PCLK_GPIO2 249
+#define DBCLK_GPIO2 250
+#define ACLK_MAC 251
+#define PCLK_MAC 252
+#define CLK_GMAC0_50M_O 253
+#define CLK_GMAC0_TX_50M_O 254
+#define CLK_GMAC0_REF_50M 255
+#define CLK_GMAC0_TX_50M 256
+#define CLK_GMAC0_RX_50M 257
+#define ACLK_MAC_ROOT 258
+#define CLK_MACPHY 259
+#define CLK_OTPC_ARB 260
+#define PCLK_OTPC_NS 261
+#define CLK_SBPI_OTPC_NS 262
+#define CLK_USER_OTPC_NS 263
+#define PCLK_OTPC_S 264
+#define CLK_SBPI_OTPC_S 265
+#define CLK_USER_OTPC_S 266
+#define PCLK_OTP_MASK 267
+#define CLK_PMC_OTP 268
+#define HCLK_RGA2E 269
+#define ACLK_RGA2E 270
+#define CLK_CORE_RGA2E 271
+#define CCLK_SRC_SDIO 272
+#define HCLK_SDIO 273
+#define PCLK_TSADC 274
+#define CLK_TSADC 275
+#define CLK_TSADC_TSEN 276
+#define ACLK_VO_ROOT 277
+#define HCLK_VO_ROOT 278
+#define PCLK_VO_ROOT 279
+#define ACLK_VOP_ROOT 280
+#define HCLK_VOP 281
+#define DCLK_VOP 282
+#define ACLK_VOP 283
+#define CLK_RTC_32K 284
+#define PCLK_MAILBOX 291
+
+#define CLK_NR_CLKS (PCLK_MAILBOX + 1)
+
+#define SCLK_EMMC_DRV 1
+#define SCLK_EMMC_SAMPLE 2
+#define SCLK_SDMMC_DRV 3
+#define SCLK_SDMMC_SAMPLE 4
+#define SCLK_SDIO_DRV 5
+#define SCLK_SDIO_SAMPLE 6
+
+#define CLK_NR_GRF_CLKS (SCLK_SDIO_SAMPLE + 1)
+
+/********Name=PMUSOFTRST_CON00,Offset=0xA00********/
+#define SRST_P_I2C1 3
+#define SRST_I2C1 4
+#define SRST_H_PMU_BIU 6
+#define SRST_P_PMU_BIU 7
+#define SRST_H_PMU_SRAM 8
+#define SRST_PMU_MCU 9
+#define SRST_PMU_MCU_PWRUP 10
+#define SRST_PMU_MCU_CPU 11
+#define SRST_T_PMU_MCU_CPU 12
+/********Name=PMUSOFTRST_CON01,Offset=0xA04********/
+#define SRST_P_PMU_GPIO0 18
+#define SRST_PMU_GPIO0 19
+#define SRST_PVTM_PMU 20
+#define SRST_P_PVTM_PMU 21
+#define SRST_DDR_FAIL_SAFE 31
+/********Name=PMUSOFTRST_CON02,Offset=0xA08********/
+#define SRST_P_PMU_HP_TIMER 32
+#define SRST_PMU_HP_TIMER 33
+#define SRST_PMU_32K_HP_TIMER 34
+#define SRST_P_PMU_IOC 35
+#define SRST_P_PMU_CRU 36
+#define SRST_P_PMU_GRF 37
+#define SRST_P_PMU_SGRF 38
+#define SRST_P_PMU_SGRF_REMAP 39
+#define SRST_P_PMU_WDT 40
+#define SRST_T_PMU_WDT 41
+#define SRST_P_PMU_MAILBOX 42
+#define SRST_WRITE_ENABLE 48
+/********Name=SOFTRST_CON02,Offset=0x10A08********/
+#define SRST_REF_PVTPLL_0 262183
+#define SRST_REF_PVTPLL_1 262184
+#define SRST_P_CRU 262186
+#define SRST_P_CRU_BIU 262187
+/********Name=PERISOFTRST_CON00,Offset=0x12A00********/
+#define SRST_P_PERI_BIU 294916
+#define SRST_A_PERI_BIU 294917
+#define SRST_H_PERI_BIU 294918
+#define SRST_H_BOOTROM 294919
+#define SRST_P_TIMER 294920
+#define SRST_TIMER0 294921
+#define SRST_TIMER1 294922
+#define SRST_TIMER2 294923
+#define SRST_TIMER3 294924
+#define SRST_TIMER4 294925
+#define SRST_TIMER5 294926
+#define SRST_P_STIMER 294927
+/********Name=PERISOFTRST_CON01,Offset=0x12A04********/
+#define SRST_STIMER0 294928
+#define SRST_STIMER1 294929
+#define SRST_P_WDT_NS 294930
+#define SRST_T_WDT_NS 294931
+#define SRST_P_WDT_S 294932
+#define SRST_T_WDT_S 294933
+#define SRST_P_I2C0 294934
+#define SRST_I2C0 294935
+#define SRST_P_I2C2 294938
+#define SRST_I2C2 294939
+#define SRST_P_I2C3 294940
+#define SRST_I2C3 294941
+#define SRST_P_I2C4 294942
+#define SRST_I2C4 294943
+/********Name=PERISOFTRST_CON02,Offset=0x12A08********/
+#define SRST_P_GPIO4 294944
+#define SRST_GPIO4 294945
+#define SRST_P_PERI_IOC 294946
+#define SRST_P_UART2 294947
+#define SRST_S_UART2 294950
+#define SRST_P_UART3 294951
+#define SRST_S_UART3 294954
+#define SRST_P_UART4 294955
+#define SRST_S_UART4 294958
+#define SRST_P_UART5 294959
+/********Name=PERISOFTRST_CON03,Offset=0x12A0C********/
+#define SRST_S_UART5 294962
+#define SRST_P_SARADC 294963
+#define SRST_SARADC 294964
+#define SRST_SARADC_PHY 294965
+#define SRST_P_SPI1 294966
+#define SRST_SPI1 294967
+#define SRST_H_TRNG_NS 294969
+#define SRST_H_TRNG_S 294970
+#define SRST_CORE_CRYPTO 294971
+#define SRST_PKA_CRYPTO 294972
+#define SRST_A_CRYPTO 294973
+#define SRST_H_CRYPTO 294974
+#define SRST_P_PWM1_PERI 294975
+/********Name=PERISOFTRST_CON04,Offset=0x12A10********/
+#define SRST_PWM1_PERI 294976
+#define SRST_P_PWM2_PERI 294978
+#define SRST_PWM2_PERI 294979
+#define SRST_P_PERI_GRF 294981
+#define SRST_P_PERI_CRU 294982
+#define SRST_A_USBOTG 294983
+#define SRST_A_BUS_BIU 294986
+#define SRST_H_EMMC 294989
+#define SRST_H_SFC 294990
+/********Name=PERISOFTRST_CON05,Offset=0x12A14********/
+#define SRST_S_SFC 294992
+#define SRST_P_USBPHY 294993
+#define SRST_USBPHY_POR 294994
+#define SRST_USBPHY_OTG 294995
+#define SRST_A_DMAC 295000
+#define SRST_A_DECOM 295001
+#define SRST_P_DECOM 295002
+#define SRST_D_DECOM 295003
+#define SRST_P_PERI_SGRF 295004
+#define SRST_H_SAI 295005
+#define SRST_M_SAI 295006
+#define SRST_M_I2S0_8CH_TX 295007
+/********Name=PERISOFTRST_CON06,Offset=0x12A18********/
+#define SRST_H_I2S0 295008
+#define SRST_M_DSM 295009
+#define SRST_P_DSM 295010
+#define SRST_P_ACODEC 295011
+#define SRST_M_I2S0_8CH_RX 295014
+#define SRST_P_DFT2APB 295015
+#define SRST_H_IVE 295017
+#define SRST_A_IVE 295018
+#define SRST_P_UART0 295019
+#define SRST_S_UART0 295022
+#define SRST_P_UART1 295023
+/********Name=PERISOFTRST_CON07,Offset=0x12A1C********/
+#define SRST_S_UART1 295026
+#define SRST_P_PWM0_PERI 295027
+#define SRST_PWM0_PERI 295028
+/********Name=VISOFTRST_CON00,Offset=0x14A00********/
+#define SRST_H_VI_BIU 327684
+#define SRST_A_VI_BIU 327685
+#define SRST_P_VI_BIU 327686
+#define SRST_CORE_ISP3P2 327689
+#define SRST_D_VICAP 327690
+#define SRST_P_VICAP 327691
+#define SRST_A_VICAP 327692
+#define SRST_H_VICAP 327693
+#define SRST_VICAP_I0 327694
+#define SRST_VICAP_I1 327695
+/********Name=VISOFTRST_CON01,Offset=0x14A04********/
+#define SRST_VICAP_RX0 327696
+#define SRST_VICAP_RX1 327697
+#define SRST_VICAP_ISP0 327698
+#define SRST_P_CSIHOST0 327700
+#define SRST_P_CSIHOST1 327702
+#define SRST_H_SDMMC 327708
+#define SRST_SDMMC_DETN_FLT 327709
+#define SRST_P_MIPICSIPHY 327710
+#define SRST_P_GPIO3 327711
+/********Name=VISOFTRST_CON02,Offset=0x14A08********/
+#define SRST_GPIO3 327712
+#define SRST_P_VI_IOC 327713
+#define SRST_P_VI_GRF 327714
+#define SRST_P_VI_SGRF 327715
+#define SRST_P_VI_CRU 327716
+#define SRST_P_VI_RTC_TEST 327717
+#define SRST_P_VI_RTC_NIU 327719
+/********Name=NPUSOFTRST_CON00,Offset=0x16A00********/
+#define SRST_H_NPU_BIU 360451
+#define SRST_A_NPU_BIU 360452
+#define SRST_P_NPU_BIU 360453
+#define SRST_P_NPU_CRU 360454
+#define SRST_P_NPU_SGRF 360455
+#define SRST_P_NPU_GRF 360456
+#define SRST_H_RKNN 360457
+#define SRST_A_RKNN 360458
+/********Name=CORESOFTRST_CON00,Offset=0x18A00********/
+#define SRST_NCOREPORESET 393217
+#define SRST_NCORESET 393218
+#define SRST_NDBGRESET 393219
+#define SRST_NL2RESET 393220
+#define SRST_A_M_CORE_BIU 393221
+#define SRST_P_DBG 393222
+#define SRST_POT_DBG 393223
+#define SRST_NT_DBG 393224
+#define SRST_P_CORE_GRF 393227
+#define SRST_H_CPU_BIU 393228
+#define SRST_P_CPU_BIU 393229
+#define SRST_PVTM_CORE 393230
+#define SRST_P_PVTM_CORE 393231
+/********Name=CORESOFTRST_CON01,Offset=0x18A04********/
+#define SRST_REF_PVTPLL_CORE 393232
+#define SRST_CORE_MCU 393233
+#define SRST_CORE_MCU_PWRUP 393234
+#define SRST_CORE_MCU_CPU 393235
+#define SRST_T_CORE_MCU_CPU 393236
+#define SRST_MCU_BIU 393237
+#define SRST_P_MAILBOX 393240
+#define SRST_P_INTMUX 393241
+#define SRST_P_CORE_CRU 393242
+#define SRST_P_CORE_SGRF 393243
+#define SRST_H_CACHE 393244
+/********Name=VEPUSOFTRST_CON00,Offset=0x1AA00********/
+#define SRST_H_VEPU_BIU 425988
+#define SRST_A_VEPU_BIU 425989
+#define SRST_A_VEPU_COM_BIU 425990
+#define SRST_P_VEPU_BIU 425991
+#define SRST_H_VEPU 425992
+#define SRST_A_VEPU 425993
+#define SRST_CORE_VEPU 425994
+#define SRST_H_VEPU_PP 425995
+#define SRST_A_VEPU_PP 425996
+#define SRST_CORE_VEPU_DVBM 425997
+#define SRST_P_VICAP_VEPU 425998
+#define SRST_P_GPIO1 425999
+/********Name=VEPUSOFTRST_CON01,Offset=0x1AA04********/
+#define SRST_GPIO1 426000
+#define SRST_P_VEPU_IOC 426001
+#define SRST_P_SPI0 426002
+#define SRST_SPI0 426003
+#define SRST_P_VEPU_CRU 426005
+#define SRST_P_VEPU_SGRF 426006
+#define SRST_P_VEPU_GRF 426007
+#define SRST_UART_DETN_FLT 426008
+/********Name=VOSOFTRST_CON00,Offset=0x1CA00********/
+#define SRST_A_VO_BIU 458755
+#define SRST_H_VO_BIU 458756
+#define SRST_H_RGA2E 458759
+#define SRST_A_RGA2E 458760
+#define SRST_CORE_RGA2E 458761
+#define SRST_P_VO_GRF 458762
+#define SRST_A_VOP_BIU 458764
+#define SRST_H_VOP 458765
+#define SRST_D_VOP 458766
+#define SRST_A_VOP 458767
+/********Name=VOSOFTRST_CON01,Offset=0x1CA04********/
+#define SRST_P_MAC_BIU 458774
+#define SRST_A_MAC_BIU 458775
+#define SRST_A_MAC 458776
+#define SRST_P_VO_SGRF 458780
+#define SRST_P_VO_CRU 458781
+#define SRST_H_SDIO 458783
+/********Name=VOSOFTRST_CON02,Offset=0x1CA08********/
+#define SRST_P_TSADC 458784
+#define SRST_TSADC 458785
+#define SRST_P_OTPC_NS 458787
+#define SRST_SBPI_OTPC_NS 458789
+#define SRST_USER_OTPC_NS 458790
+#define SRST_P_OTPC_S 458791
+#define SRST_SBPI_OTPC_S 458793
+#define SRST_USER_OTPC_S 458794
+#define SRST_OTPC_ARB 458795
+#define SRST_MACPHY 458797
+#define SRST_P_OTP_MASK 458798
+#define SRST_PMC_OTP 458799
+/********Name=VOSOFTRST_CON03,Offset=0x1CA0C********/
+#define SRST_P_GPIO2 458800
+#define SRST_GPIO2 458801
+#define SRST_P_VO_IOC 458802
+/********Name=DDRSOFTRST_CON00,Offset=0x1EA00********/
+#define SRST_P_DDR_BIU 491522
+#define SRST_P_DDRC 491525
+#define SRST_P_DDRMON 491527
+#define SRST_TIMER_DDRMON 491528
+#define SRST_P_DFICTRL 491531
+#define SRST_A_SYS_SHRM 491533
+#define SRST_A_SHRM_NIU 491534
+#define SRST_P_DDR_GRF 491535
+/********Name=DDRSOFTRST_CON01,Offset=0x1EA04********/
+#define SRST_P_DDR_CRU 491536
+#define SRST_P_DDR_HWLP 491538
+#define SRST_P_DDRPHY 491539
+/********Name=SUBDDRSOFTRST_CON00,Offset=0x1FA00********/
+#define SRST_MSCH_BIU 507904
+#define SRST_A_DDRC 507905
+#define SRST_CORE_DDRC 507907
+#define SRST_DDRMON 507908
+#define SRST_DFICTRL 507909
+#define SRST_DDR_PHY 507910
+
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 12/15] clk: rockchip: Add RV1106 clock driver
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (10 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 11/15] ARM: dts: Add the RV1103/RV1106 devicetree files Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 13/15] rockchip: rv1106: Add SoC support Simon Glass
` (3 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Elaine Zhang,
Finley Xiao, Ilias Apalodimas, Jeffy Chen, Kever Yang,
Lukasz Majewski, Philipp Tomsich, Tom Rini, huang lin
Add the clock driver for the RV1106, based on the driver in the
Rockchip vendor tree, with the vendor-specific clk-dump and MMC
phase-tuning code removed and the driver-model API usage brought up to
date.
The RV1103 is a package variant of the RV1106 and shares this driver
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
.../include/asm/arch-rockchip/cru_rv1106.h | 305 ++++
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk_rv1106.c | 1319 +++++++++++++++++
3 files changed, 1625 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rv1106.h
create mode 100644 drivers/clk/rockchip/clk_rv1106.c
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1106.h b/arch/arm/include/asm/arch-rockchip/cru_rv1106.h
new file mode 100644
index 00000000000..8e3ac228c2b
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1106.h
@@ -0,0 +1,305 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#ifndef _ASM_ARCH_CRU_RV1106_H
+#define _ASM_ARCH_CRU_RV1106_H
+
+
+#define MHz 1000000
+#define KHz 1000
+#define OSC_HZ (24 * MHz)
+
+#define APLL_HZ (816 * MHz)
+#define GPLL_HZ (1188 * MHz)
+#define CPLL_HZ (1000 * MHz)
+
+/* RV1106 pll id */
+enum rv1106_pll_id {
+ APLL,
+ DPLL,
+ CPLL,
+ GPLL,
+ PLL_COUNT,
+};
+
+struct rv1106_clk_info {
+ unsigned long id;
+ char *name;
+ bool is_cru;
+};
+
+struct rv1106_clk_priv {
+ struct rv1106_cru *cru;
+ struct rv1106_grf *grf;
+ ulong gpll_hz;
+ ulong cpll_hz;
+ ulong armclk_hz;
+ ulong armclk_enter_hz;
+ ulong armclk_init_hz;
+ bool sync_kernel;
+ bool set_armclk_rate;
+};
+
+struct rv1106_grf_clk_priv {
+ struct rv1106_grf *grf;
+};
+
+struct rv1106_pll {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ unsigned int con4;
+ unsigned int reserved0[3];
+};
+
+struct rv1106_cru {
+ unsigned int reserved0[192];
+ unsigned int pmu_clksel_con[8];
+ unsigned int reserved1[312];
+ unsigned int pmu_clkgate_con[3];
+ unsigned int reserved2[125];
+ unsigned int pmu_softrst_con[3];
+ unsigned int reserved3[15741];
+ struct rv1106_pll pll[4];
+ unsigned int reserved4[128];
+ unsigned int mode;
+ unsigned int reserved5[31];
+ unsigned int clksel_con[34];
+ unsigned int reserved6[286];
+ unsigned int clkgate_con[4];
+ unsigned int reserved7[124];
+ unsigned int softrst_con[3];
+ unsigned int reserved8[125];
+ 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 con[2];
+ unsigned int sdmmc_con[2];
+ unsigned int emmc_con[2];
+ unsigned int reserved9[1461];
+ unsigned int peri_clksel_con[12];
+ unsigned int reserved10[308];
+ unsigned int peri_clkgate_con[8];
+ unsigned int reserved11[120];
+ unsigned int peri_softrst_con[8];
+ unsigned int reserved12[1592];
+ unsigned int vi_clksel_con[4];
+ unsigned int reserved13[316];
+ unsigned int vi_clkgate_con[3];
+ unsigned int reserved14[125];
+ unsigned int vi_softrst_con[3];
+ unsigned int reserved15[3645];
+ unsigned int core_clksel_con[5];
+ unsigned int reserved16[2043];
+ unsigned int vepu_clksel_con[2];
+ unsigned int reserved17[318];
+ unsigned int vepu_clkgate_con[3];
+ unsigned int reserved18[125];
+ unsigned int vepu_softrst_con[2];
+ unsigned int reserved19[1598];
+ unsigned int vo_clksel_con[4];
+ unsigned int reserved20[316];
+ unsigned int vo_clkgate_con[3];
+ unsigned int reserved21[125];
+ unsigned int vo_softrst_con[4];
+};
+check_member(rv1106_cru, vo_softrst_con[0], 0x1ca00);
+
+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 RV1106_TOPCRU_BASE 0x10000
+#define RV1106_SUBDDRCRU_BASE 0x1F000
+
+#define RV1106_PLL_CON(x) ((x) * 0x4 + RV1106_TOPCRU_BASE)
+#define RV1106_MODE_CON (0x280 + RV1106_TOPCRU_BASE)
+#define RV1106_SUBDDRMODE_CON (0x280 + RV1106_SUBDDRCRU_BASE)
+
+enum {
+ /* CRU_PMU_CLK_SEL0_CON */
+ CLK_I2C1_SEL_SHIFT = 6,
+ CLK_I2C1_SEL_MASK = 0x3 << CLK_I2C1_SEL_SHIFT,
+ CLK_I2C1_SEL_200M = 0,
+ CLK_I2C1_SEL_100M,
+ CLK_I2C1_SEL_24M,
+ CLK_I2C1_SEL_32K,
+ HCLK_PMU_SEL_SHIFT = 4,
+ HCLK_PMU_SEL_MASK = 0x3 << HCLK_PMU_SEL_SHIFT,
+ HCLK_PMU_SEL_200M = 0,
+ HCLK_PMU_SEL_100M,
+ HCLK_PMU_SEL_24M,
+ PCLK_PMU_SEL_SHIFT = 3,
+ PCLK_PMU_SEL_MASK = 0x1 << PCLK_PMU_SEL_SHIFT,
+ PCLK_PMU_SEL_100M = 0,
+ PCLK_PMU_SEL_24M,
+
+ /* CRU_CLK_SEL5_CON */
+ CLK_UART_SRC_SEL_SHIFT = 5,
+ CLK_UART_SRC_SEL_MASK = 0x1 << CLK_UART_SRC_SEL_SHIFT,
+ CLK_UART_SRC_SEL_GPLL = 0,
+ CLK_UART_SRC_SEL_CPLL,
+ CLK_UART_SRC_DIV_SHIFT = 0,
+ CLK_UART_SRC_DIV_MASK = 0x1f << CLK_UART_SRC_DIV_SHIFT,
+
+ /* CRU_CLK_SEL6_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_SEL7_CON */
+ CLK_UART_SEL_SHIFT = 0,
+ CLK_UART_SEL_MASK = 0x3 << CLK_UART_SEL_SHIFT,
+ CLK_UART_SEL_SRC = 0,
+ CLK_UART_SEL_FRAC,
+ CLK_UART_SEL_XIN24M,
+
+ /* CRU_CLK_SEL23_CON */
+ DCLK_VOP_SEL_SHIFT = 8,
+ DCLK_VOP_SEL_MASK = 0x1 << DCLK_VOP_SEL_SHIFT,
+ DCLK_VOP_SEL_GPLL = 0,
+ DCLK_VOP_SEL_CPLL,
+ DCLK_VOP_DIV_SHIFT = 3,
+ DCLK_VOP_DIV_MASK = 0x1f << DCLK_VOP_DIV_SHIFT,
+
+ /* CRU_CLK_SEL24_CON */
+ PCLK_TOP_SEL_SHIFT = 5,
+ PCLK_TOP_SEL_MASK = 0x3 << PCLK_TOP_SEL_SHIFT,
+ PCLK_TOP_SEL_100M = 0,
+ PCLK_TOP_SEL_50M,
+ PCLK_TOP_SEL_24M,
+
+ /* CRU_PERI_CLK_SEL1_CON */
+ CLK_I2C3_SEL_SHIFT = 14,
+ CLK_I2C3_SEL_MASK = 0x3 << CLK_I2C3_SEL_SHIFT,
+ CLK_I2C2_SEL_SHIFT = 12,
+ CLK_I2C2_SEL_MASK = 0x3 << CLK_I2C2_SEL_SHIFT,
+ CLK_I2C0_SEL_SHIFT = 8,
+ CLK_I2C0_SEL_MASK = 0x3 << CLK_I2C0_SEL_SHIFT,
+ CLK_I2C0_SEL_200M = 0,
+ CLK_I2C0_SEL_100M,
+ CLK_I2C0_SEL_50M,
+ CLK_I2C0_SEL_24M,
+ HCLK_PERI_SEL_SHIFT = 4,
+ HCLK_PERI_SEL_MASK = 0x3 << HCLK_PERI_SEL_SHIFT,
+ HCLK_PERI_SEL_200M = 0,
+ HCLK_PERI_SEL_100M,
+ HCLK_PERI_SEL_50M,
+ HCLK_PERI_SEL_24M,
+ ACLK_PERI_SEL_SHIFT = 2,
+ ACLK_PERI_SEL_MASK = 0x3 << ACLK_PERI_SEL_SHIFT,
+ ACLK_PERI_SEL_400M = 0,
+ ACLK_PERI_SEL_200M,
+ ACLK_PERI_SEL_100M,
+ ACLK_PERI_SEL_24M,
+ PCLK_PERI_SEL_SHIFT = 0,
+ PCLK_PERI_SEL_MASK = 0x3 << PCLK_PERI_SEL_SHIFT,
+ PCLK_PERI_SEL_100M = 0,
+ PCLK_PERI_SEL_50M,
+ PCLK_PERI_SEL_24M,
+
+ /* CRU_PERI_CLK_SEL2_CON */
+ CLK_I2C4_SEL_SHIFT = 0,
+ CLK_I2C4_SEL_MASK = 0x3 << CLK_I2C4_SEL_SHIFT,
+
+ /* CRU_PERI_CLK_SEL6_CON */
+ CLK_PWM2_SEL_SHIFT = 11,
+ CLK_PWM2_SEL_MASK = 0x3 << CLK_PWM2_SEL_SHIFT,
+ CLK_PWM1_SEL_SHIFT = 9,
+ CLK_PWM1_SEL_MASK = 0x3 << CLK_PWM1_SEL_SHIFT,
+ CLK_PWM_SEL_100M = 0,
+ CLK_PWM_SEL_50M,
+ CLK_PWM_SEL_24M,
+ CLK_PKA_CRYPTO_SEL_SHIFT = 7,
+ CLK_PKA_CRYPTO_SEL_MASK = 0x3 << CLK_PKA_CRYPTO_SEL_SHIFT,
+ CLK_CORE_CRYPTO_SEL_SHIFT = 5,
+ CLK_CORE_CRYPTO_SEL_MASK = 0x3 << CLK_CORE_CRYPTO_SEL_SHIFT,
+ CLK_CRYPTO_SEL_300M = 0,
+ CLK_CRYPTO_SEL_200M,
+ CLK_CRYPTO_SEL_100M,
+ CLK_CRYPTO_SEL_24M,
+ CLK_SARADC_DIV_SHIFT = 0,
+ CLK_SARADC_DIV_MASK = 0x7 << CLK_SARADC_DIV_SHIFT,
+ CLK_SPI1_SEL_SHIFT = 3,
+ CLK_SPI1_SEL_MASK = 0x3 << CLK_SPI1_SEL_SHIFT,
+
+ /* CRU_PERI_CLK_SEL7_CON */
+ DCLK_DECOM_SEL_SHIFT = 14,
+ DCLK_DECOM_SEL_MASK = 0x3 << DCLK_DECOM_SEL_SHIFT,
+ DCLK_DECOM_SEL_400M = 0,
+ DCLK_DECOM_SEL_200M,
+ DCLK_DECOM_SEL_100M,
+ DCLK_DECOM_SEL_24M,
+ CLK_SFC_SEL_SHIFT = 12,
+ CLK_SFC_SEL_MASK = 0x3 << CLK_SFC_SEL_SHIFT,
+ CLK_SFC_SEL_500M = 0,
+ CLK_SFC_SEL_300M,
+ CLK_SFC_SEL_200M,
+ CLK_SFC_SEL_24M,
+ CLK_SFC_DIV_SHIFT = 7,
+ CLK_SFC_DIV_MASK = 0x1f << CLK_SFC_DIV_SHIFT,
+ CLK_EMMC_SEL_SHIFT = 6,
+ CLK_EMMC_SEL_MASK = 0x1 << CLK_EMMC_SEL_SHIFT,
+ CLK_MMC_SEL_400M = 0,
+ CLK_MMC_SEL_24M,
+ CLK_EMMC_DIV_SHIFT = 0,
+ CLK_EMMC_DIV_MASK = 0x3f << CLK_EMMC_DIV_SHIFT,
+
+ /* CRU_PERI_CLK_SEL9_CON */
+ ACLK_BUS_SEL_SHIFT = 0,
+ ACLK_BUS_SEL_MASK = 0x3 << ACLK_BUS_SEL_SHIFT,
+ ACLK_BUS_SEL_300M = 0,
+ ACLK_BUS_SEL_200M,
+ ACLK_BUS_SEL_100M,
+ ACLK_BUS_SEL_24M,
+
+ /* CRU_PERI_CLK_SEL11_CON */
+ CLK_PWM0_SEL_SHIFT = 0,
+ CLK_PWM0_SEL_MASK = 0x3 << CLK_PWM0_SEL_SHIFT,
+
+ /* CRU_VEPU_CLK_SEL0_CON */
+ CLK_SPI0_SEL_SHIFT = 12,
+ CLK_SPI0_SEL_MASK = 0x3 << CLK_SPI0_SEL_SHIFT,
+ CLK_SPI0_SEL_200M = 0,
+ CLK_SPI0_SEL_100M,
+ CLK_SPI0_SEL_50M,
+ CLK_SPI0_SEL_24M,
+
+ /* CRU_CORE_CLK_SEL0_CON */
+ CLK_CORE_DIV_SHIFT = 0,
+ CLK_CORE_DIV_MASK = 0x1f << CLK_CORE_DIV_SHIFT,
+
+ /* CRU_VI_CLK_SEL1_CON */
+ CLK_SDMMC_SEL_SHIFT = 14,
+ CLK_SDMMC_SEL_MASK = 0x1 << CLK_SDMMC_SEL_SHIFT,
+ CLK_SDMMC_DIV_SHIFT = 8,
+ CLK_SDMMC_DIV_MASK = 0x3f << CLK_SDMMC_DIV_SHIFT,
+
+ /* CRU_VO_CLK_SEL1_CON */
+ ACLK_VOP_SEL_SHIFT = 10,
+ ACLK_VOP_SEL_MASK = 0x3 << ACLK_VOP_SEL_SHIFT,
+ ACLK_VOP_SEL_300M = 0,
+ ACLK_VOP_SEL_200M,
+ ACLK_VOP_SEL_100M,
+ ACLK_VOP_SEL_24M,
+
+ /* CRU_VO_CLK_SEL3_CON */
+ CLK_TSADC_TSEN_DIV_SHIFT = 5,
+ CLK_TSADC_TSEN_DIV_MASK = 0x1F << CLK_TSADC_TSEN_DIV_SHIFT,
+ CLK_TSADC_DIV_SHIFT = 0,
+ CLK_TSADC_DIV_MASK = 0x1F << CLK_TSADC_DIV_SHIFT,
+};
+#endif
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index de2635b7475..d76f7d02634 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -21,5 +21,6 @@ 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_RV1106) += clk_rv1106.o
obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o
diff --git a/drivers/clk/rockchip/clk_rv1106.c b/drivers/clk/rockchip/clk_rv1106.c
new file mode 100644
index 00000000000..7c23c9633df
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1106.c
@@ -0,0 +1,1319 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd
+ * Author: Elaine Zhang <zhangqing@rock-chips.com>
+ */
+
+#include <bitfield.h>
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <malloc.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1106.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rv1106-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+static struct rockchip_pll_rate_table rv1106_pll_rates[] = {
+ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+ RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+ RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+ RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
+ RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+ { /* sentinel */ },
+};
+
+static struct rockchip_pll_clock rv1106_pll_clks[] = {
+ [APLL] = PLL(pll_rk3328, PLL_APLL, RV1106_PLL_CON(0),
+ RV1106_MODE_CON, 0, 10, 0, rv1106_pll_rates),
+ [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1106_PLL_CON(16),
+ RV1106_SUBDDRMODE_CON, 0, 10, 0, NULL),
+ [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1106_PLL_CON(8),
+ RV1106_MODE_CON, 2, 10, 0, rv1106_pll_rates),
+ [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1106_PLL_CON(24),
+ RV1106_MODE_CON, 4, 10, 0, rv1106_pll_rates),
+};
+
+static ulong rv1106_peri_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 con, sel, rate;
+
+ switch (clk_id) {
+ case ACLK_PERI_ROOT:
+ con = readl(&cru->peri_clksel_con[1]);
+ sel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;
+ if (sel == ACLK_PERI_SEL_400M)
+ rate = 400 * MHz;
+ else if (sel == ACLK_PERI_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == ACLK_PERI_SEL_100M)
+ rate = 100 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ case HCLK_PERI_ROOT:
+ con = readl(&cru->peri_clksel_con[1]);
+ sel = (con & HCLK_PERI_SEL_MASK) >> HCLK_PERI_SEL_SHIFT;
+ if (sel == HCLK_PERI_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == HCLK_PERI_SEL_100M)
+ rate = 100 * MHz;
+ else if (sel == HCLK_PERI_SEL_50M)
+ rate = 50 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ case PCLK_PERI_ROOT:
+ con = readl(&cru->peri_clksel_con[1]);
+ sel = (con & PCLK_PERI_SEL_MASK) >> PCLK_PERI_SEL_SHIFT;
+ if (sel == PCLK_PERI_SEL_100M)
+ rate = 100 * MHz;
+ else if (sel == PCLK_PERI_SEL_50M)
+ rate = 50 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ case ACLK_BUS_ROOT:
+ con = readl(&cru->peri_clksel_con[9]);
+ sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
+ if (sel == ACLK_BUS_SEL_300M)
+ rate = 300 * MHz;
+ else if (sel == ACLK_BUS_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == ACLK_BUS_SEL_100M)
+ rate = 100 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ case PCLK_TOP_ROOT:
+ con = readl(&cru->clksel_con[24]);
+ sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
+ if (sel == PCLK_TOP_SEL_100M)
+ rate = 100 * MHz;
+ else if (sel == PCLK_TOP_SEL_50M)
+ rate = 50 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ case PCLK_PMU_ROOT:
+ con = readl(&cru->pmu_clksel_con[0]);
+ sel = (con & PCLK_PMU_SEL_MASK) >> PCLK_PMU_SEL_SHIFT;
+ if (sel == PCLK_PMU_SEL_100M)
+ rate = 100 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ case HCLK_PMU_ROOT:
+ con = readl(&cru->pmu_clksel_con[0]);
+ sel = (con & HCLK_PMU_SEL_MASK) >> HCLK_PMU_SEL_SHIFT;
+ if (sel == HCLK_PMU_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == HCLK_PMU_SEL_100M)
+ rate = 100 * MHz;
+ else
+ rate = OSC_HZ;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static ulong rv1106_peri_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ int src_clk;
+
+ switch (clk_id) {
+ case ACLK_PERI_ROOT:
+ if (rate >= 396 * MHz)
+ src_clk = ACLK_PERI_SEL_400M;
+ else if (rate >= 198 * MHz)
+ src_clk = ACLK_PERI_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = ACLK_PERI_SEL_100M;
+ else
+ src_clk = ACLK_PERI_SEL_24M;
+ rk_clrsetreg(&cru->peri_clksel_con[1],
+ ACLK_PERI_SEL_MASK,
+ src_clk << ACLK_PERI_SEL_SHIFT);
+ break;
+ case HCLK_PERI_ROOT:
+ if (rate >= 198 * MHz)
+ src_clk = HCLK_PERI_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = HCLK_PERI_SEL_100M;
+ else if (rate >= 48 * MHz)
+ src_clk = HCLK_PERI_SEL_50M;
+ else
+ src_clk = HCLK_PERI_SEL_24M;
+ rk_clrsetreg(&cru->peri_clksel_con[1],
+ HCLK_PERI_SEL_MASK,
+ src_clk << HCLK_PERI_SEL_SHIFT);
+ break;
+ case PCLK_PERI_ROOT:
+ if (rate >= 99 * MHz)
+ src_clk = PCLK_PERI_SEL_100M;
+ else if (rate >= 48 * MHz)
+ src_clk = PCLK_PERI_SEL_50M;
+ else
+ src_clk = PCLK_PERI_SEL_24M;
+ rk_clrsetreg(&cru->peri_clksel_con[1],
+ PCLK_PERI_SEL_MASK,
+ src_clk << PCLK_PERI_SEL_SHIFT);
+ break;
+ case ACLK_BUS_ROOT:
+ if (rate >= 297 * MHz)
+ src_clk = ACLK_BUS_SEL_300M;
+ else if (rate >= 198 * MHz)
+ src_clk = ACLK_BUS_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = ACLK_BUS_SEL_100M;
+ else
+ src_clk = ACLK_BUS_SEL_24M;
+ rk_clrsetreg(&cru->peri_clksel_con[9],
+ ACLK_BUS_SEL_MASK,
+ src_clk << ACLK_BUS_SEL_SHIFT);
+ break;
+ case PCLK_TOP_ROOT:
+ if (rate >= 99 * MHz)
+ src_clk = PCLK_TOP_SEL_100M;
+ else if (rate >= 48 * MHz)
+ src_clk = PCLK_TOP_SEL_50M;
+ else
+ src_clk = PCLK_TOP_SEL_24M;
+ rk_clrsetreg(&cru->clksel_con[24],
+ PCLK_TOP_SEL_MASK,
+ src_clk << PCLK_TOP_SEL_SHIFT);
+ break;
+ case PCLK_PMU_ROOT:
+ if (rate >= 99 * MHz)
+ src_clk = PCLK_PMU_SEL_100M;
+ else
+ src_clk = PCLK_PMU_SEL_24M;
+ rk_clrsetreg(&cru->pmu_clksel_con[0],
+ PCLK_PMU_SEL_MASK,
+ src_clk << PCLK_PMU_SEL_SHIFT);
+ break;
+ case HCLK_PMU_ROOT:
+ if (rate >= 198 * MHz)
+ src_clk = HCLK_PMU_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = HCLK_PMU_SEL_100M;
+ else
+ src_clk = HCLK_PMU_SEL_24M;
+ rk_clrsetreg(&cru->pmu_clksel_con[0],
+ HCLK_PMU_SEL_MASK,
+ src_clk << HCLK_PMU_SEL_SHIFT);
+ break;
+ default:
+ printf("do not support this permid freq\n");
+ return -EINVAL;
+ }
+
+ return rv1106_peri_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_i2c_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel, con;
+ ulong rate;
+
+ switch (clk_id) {
+ case CLK_I2C1:
+ con = readl(&cru->pmu_clksel_con[0]);
+ sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
+ if (sel == CLK_I2C1_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == CLK_I2C1_SEL_100M)
+ rate = 100 * MHz;
+ else if (sel == CLK_I2C1_SEL_24M)
+ rate = OSC_HZ;
+ else
+ rate = 32768;
+ return rate;
+ case CLK_I2C0:
+ con = readl(&cru->peri_clksel_con[1]);
+ sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
+ break;
+ case CLK_I2C2:
+ con = readl(&cru->peri_clksel_con[1]);
+ sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
+ break;
+ case CLK_I2C3:
+ con = readl(&cru->peri_clksel_con[1]);
+ sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
+ break;
+ case CLK_I2C4:
+ con = readl(&cru->peri_clksel_con[2]);
+ sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ if (sel == CLK_I2C0_SEL_200M)
+ rate = 200 * MHz;
+ else if (sel == CLK_I2C0_SEL_100M)
+ rate = 100 * MHz;
+ else if (sel == CLK_I2C0_SEL_50M)
+ rate = 50 * MHz;
+ else
+ rate = OSC_HZ;
+
+ return rate;
+}
+
+static ulong rv1106_crypto_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel, con;
+
+ switch (clk_id) {
+ case CLK_CORE_CRYPTO:
+ con = readl(&cru->peri_clksel_con[6]);
+ sel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>
+ CLK_CORE_CRYPTO_SEL_SHIFT;
+ break;
+ case CLK_PKA_CRYPTO:
+ con = readl(&cru->peri_clksel_con[6]);
+ sel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>
+ CLK_PKA_CRYPTO_SEL_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+ switch (sel) {
+ case CLK_CRYPTO_SEL_300M:
+ return 300 * MHz;
+ case CLK_CRYPTO_SEL_200M:
+ return 200 * MHz;
+ case CLK_CRYPTO_SEL_100M:
+ return 100 * MHz;
+ case CLK_CRYPTO_SEL_24M:
+ return OSC_HZ;
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1106_crypto_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel;
+
+ if (rate >= 297 * MHz)
+ sel = CLK_CRYPTO_SEL_300M;
+ else if (rate >= 198 * MHz)
+ sel = CLK_CRYPTO_SEL_200M;
+ else if (rate >= 99 * MHz)
+ sel = CLK_CRYPTO_SEL_100M;
+ else
+ sel = CLK_CRYPTO_SEL_24M;
+
+ switch (clk_id) {
+ case CLK_CORE_CRYPTO:
+ rk_clrsetreg(&cru->peri_clksel_con[6],
+ CLK_CORE_CRYPTO_SEL_MASK,
+ sel << CLK_CORE_CRYPTO_SEL_SHIFT);
+ break;
+ case CLK_PKA_CRYPTO:
+ rk_clrsetreg(&cru->peri_clksel_con[6],
+ CLK_PKA_CRYPTO_SEL_MASK,
+ sel << CLK_PKA_CRYPTO_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+ return rv1106_crypto_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_mmc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 div, sel, con, prate;
+
+ switch (clk_id) {
+ case CCLK_SRC_SDMMC:
+ case HCLK_SDMMC:
+ con = readl(&cru->vi_clksel_con[1]);
+ 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_400M)
+ prate = 400 * MHz;
+ else
+ prate = OSC_HZ;
+ return DIV_TO_RATE(prate, div);
+ case CCLK_SRC_EMMC:
+ case HCLK_EMMC:
+ con = readl(&cru->peri_clksel_con[7]);
+ sel = (con & CLK_EMMC_SEL_MASK) >>
+ CLK_EMMC_SEL_SHIFT;
+ div = (con & CLK_EMMC_DIV_MASK) >>
+ CLK_EMMC_DIV_SHIFT;
+ if (sel)
+ prate = OSC_HZ;
+ else
+ prate = 400 * MHz;
+ return DIV_TO_RATE(prate, div);
+ case SCLK_SFC:
+ case HCLK_SFC:
+ con = readl(&cru->peri_clksel_con[7]);
+ sel = (con & CLK_SFC_SEL_MASK) >>
+ CLK_SFC_SEL_SHIFT;
+ div = (con & CLK_SFC_DIV_MASK) >>
+ CLK_SFC_DIV_SHIFT;
+ if (sel == CLK_SFC_SEL_500M)
+ prate = 500 * MHz;
+ else if (sel == CLK_SFC_SEL_300M)
+ prate = 300 * MHz;
+ else if (sel == CLK_SFC_SEL_200M)
+ prate = 200 * MHz;
+ else
+ prate = OSC_HZ;
+ return DIV_TO_RATE(prate, div);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1106_mmc_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel, src_clk_div;
+ ulong prate = 0;
+
+ if ((OSC_HZ % rate) == 0) {
+ sel = CLK_MMC_SEL_24M;
+ prate = OSC_HZ;
+ } else {
+ sel = CLK_MMC_SEL_400M;
+ prate = 400 * MHz;
+ }
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+
+ switch (clk_id) {
+ case CCLK_SRC_SDMMC:
+ case HCLK_SDMMC:
+ if ((OSC_HZ % rate) == 0) {
+ sel = CLK_MMC_SEL_24M;
+ prate = OSC_HZ;
+ } else {
+ sel = CLK_MMC_SEL_400M;
+ prate = 400 * MHz;
+ }
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->vi_clksel_con[1],
+ CLK_SDMMC_SEL_MASK |
+ CLK_SDMMC_DIV_MASK,
+ (sel << CLK_SDMMC_SEL_SHIFT) |
+ ((src_clk_div - 1) <<
+ CLK_SDMMC_DIV_SHIFT));
+ break;
+ case CCLK_SRC_EMMC:
+ case HCLK_EMMC:
+ if ((OSC_HZ % rate) == 0) {
+ sel = CLK_MMC_SEL_24M;
+ prate = OSC_HZ;
+ } else {
+ sel = CLK_MMC_SEL_400M;
+ prate = 400 * MHz;
+ }
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->peri_clksel_con[7],
+ 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:
+ case HCLK_SFC:
+ if ((OSC_HZ % rate) == 0) {
+ sel = CLK_SFC_SEL_24M;
+ prate = OSC_HZ;
+ } else if ((500 * MHz % rate) == 0) {
+ sel = CLK_SFC_SEL_500M;
+ prate = 500 * MHz;
+ } else if ((300 * MHz % rate) == 0) {
+ sel = CLK_SFC_SEL_300M;
+ prate = 300 * MHz;
+ } else {
+ sel = CLK_SFC_SEL_200M;
+ prate = 200 * MHz;
+ }
+ src_clk_div = DIV_ROUND_UP(prate, rate);
+ rk_clrsetreg(&cru->peri_clksel_con[7],
+ 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 rv1106_mmc_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_i2c_set_clk(struct rv1106_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ int src_clk;
+
+ if (rate >= 198 * MHz)
+ src_clk = CLK_I2C0_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = CLK_I2C0_SEL_100M;
+ else if (rate >= 48 * MHz)
+ src_clk = CLK_I2C0_SEL_50M;
+ else
+ src_clk = CLK_I2C0_SEL_24M;
+
+ switch (clk_id) {
+ case CLK_I2C1:
+ if (rate >= 198 * MHz)
+ src_clk = CLK_I2C1_SEL_200M;
+ else if (rate >= 99 * MHz)
+ src_clk = CLK_I2C1_SEL_100M;
+ else if (rate >= 24 * MHz)
+ src_clk = CLK_I2C1_SEL_24M;
+ else
+ src_clk = CLK_I2C1_SEL_32K;
+ rk_clrsetreg(&cru->clksel_con[71], CLK_I2C1_SEL_MASK,
+ src_clk << CLK_I2C1_SEL_SHIFT);
+ return rv1106_i2c_get_clk(priv, clk_id);
+ case CLK_I2C0:
+ rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C0_SEL_MASK,
+ src_clk << CLK_I2C0_SEL_SHIFT);
+ break;
+ case CLK_I2C2:
+ rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C2_SEL_MASK,
+ src_clk << CLK_I2C2_SEL_SHIFT);
+ break;
+ case CLK_I2C3:
+ rk_clrsetreg(&cru->peri_clksel_con[1], CLK_I2C3_SEL_MASK,
+ src_clk << CLK_I2C3_SEL_SHIFT);
+ break;
+ case CLK_I2C4:
+ rk_clrsetreg(&cru->peri_clksel_con[2], CLK_I2C4_SEL_MASK,
+ src_clk << CLK_I2C4_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1106_i2c_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_spi_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel, con, rate;
+
+ switch (clk_id) {
+ case CLK_SPI0:
+ con = readl(&cru->vepu_clksel_con[0]);
+ sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
+ break;
+ case CLK_SPI1:
+ con = readl(&cru->peri_clksel_con[6]);
+ sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_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 rv1106_spi_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_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->vepu_clksel_con[0], CLK_SPI0_SEL_MASK,
+ src_clk << CLK_SPI0_SEL_SHIFT);
+ break;
+ case CLK_SPI1:
+ rk_clrsetreg(&cru->peri_clksel_con[6], CLK_SPI1_SEL_MASK,
+ src_clk << CLK_SPI1_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1106_spi_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_pwm_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel, con;
+
+ switch (clk_id) {
+ case CLK_PWM0_PERI:
+ con = readl(&cru->peri_clksel_con[11]);
+ sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
+ break;
+ case CLK_PWM1_PERI:
+ con = readl(&cru->peri_clksel_con[6]);
+ sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
+ break;
+ case CLK_PWM2_PERI:
+ con = readl(&cru->peri_clksel_con[6]);
+ 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_50M:
+ return 100 * MHz;
+ case CLK_PWM_SEL_24M:
+ return OSC_HZ;
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1106_pwm_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ int src_clk;
+
+ if (rate >= 99 * MHz)
+ src_clk = CLK_PWM_SEL_100M;
+ else if (rate >= 48 * MHz)
+ src_clk = CLK_PWM_SEL_50M;
+ else
+ src_clk = CLK_PWM_SEL_24M;
+
+ switch (clk_id) {
+ case CLK_PWM0_PERI:
+ rk_clrsetreg(&cru->peri_clksel_con[11],
+ CLK_PWM0_SEL_MASK,
+ src_clk << CLK_PWM0_SEL_SHIFT);
+ break;
+ case CLK_PWM1_PERI:
+ rk_clrsetreg(&cru->peri_clksel_con[6],
+ CLK_PWM1_SEL_MASK,
+ src_clk << CLK_PWM1_SEL_SHIFT);
+ break;
+ case CLK_PWM2_PERI:
+ rk_clrsetreg(&cru->peri_clksel_con[6],
+ CLK_PWM2_SEL_MASK,
+ src_clk << CLK_PWM2_SEL_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1106_pwm_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_adc_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 div, con;
+
+ switch (clk_id) {
+ case CLK_SARADC:
+ con = readl(&cru->peri_clksel_con[6]);
+ div = (con & CLK_SARADC_DIV_MASK) >>
+ CLK_SARADC_DIV_SHIFT;
+ return DIV_TO_RATE(OSC_HZ, div);
+ case CLK_TSADC_TSEN:
+ con = readl(&cru->vo_clksel_con[3]);
+ 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->vo_clksel_con[3]);
+ div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
+ return DIV_TO_RATE(OSC_HZ, div);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1106_adc_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_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[6],
+ CLK_SARADC_DIV_MASK,
+ (src_clk_div - 1) <<
+ CLK_SARADC_DIV_SHIFT);
+ break;
+ case CLK_TSADC_TSEN:
+ assert(src_clk_div - 1 <= 128);
+ rk_clrsetreg(&cru->vo_clksel_con[3],
+ CLK_TSADC_TSEN_DIV_MASK,
+ (src_clk_div - 1) <<
+ CLK_TSADC_TSEN_DIV_SHIFT);
+ break;
+ case CLK_TSADC:
+ assert(src_clk_div - 1 <= 128);
+ rk_clrsetreg(&cru->vo_clksel_con[3],
+ CLK_TSADC_DIV_MASK,
+ (src_clk_div - 1) <<
+ CLK_TSADC_DIV_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+ return rv1106_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 rv1106_uart_get_rate(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 reg, con, fracdiv, div, src, p_src, p_rate;
+ unsigned long m, n;
+
+ switch (clk_id) {
+ case SCLK_UART0:
+ reg = 5;
+ break;
+ case SCLK_UART1:
+ reg = 7;
+ break;
+ case SCLK_UART2:
+ reg = 9;
+ break;
+ case SCLK_UART3:
+ reg = 11;
+ break;
+ case SCLK_UART4:
+ reg = 13;
+ break;
+ case SCLK_UART5:
+ reg = 15;
+ break;
+ default:
+ return -ENOENT;
+ }
+ con = readl(&cru->clksel_con[reg + 2]);
+ src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
+ con = readl(&cru->clksel_con[reg]);
+ div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
+ p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
+ if (p_src == CLK_UART_SRC_SEL_GPLL)
+ p_rate = priv->gpll_hz;
+ else if (p_src == CLK_UART_SRC_SEL_CPLL)
+ p_rate = priv->cpll_hz;
+ else
+ p_rate = 480000000;
+ 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 + 1]);
+ 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 rv1106_uart_set_rate(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 reg, clk_src, uart_src, div;
+ unsigned long m = 0, n = 0, val;
+
+ if (priv->gpll_hz % rate == 0) {
+ clk_src = CLK_UART_SRC_SEL_GPLL;
+ uart_src = CLK_UART_SEL_SRC;
+ div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ } else if (priv->cpll_hz % rate == 0) {
+ clk_src = CLK_UART_SRC_SEL_CPLL;
+ uart_src = CLK_UART_SEL_SRC;
+ div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ } else if (rate == OSC_HZ) {
+ clk_src = CLK_UART_SRC_SEL_GPLL;
+ uart_src = CLK_UART_SEL_XIN24M;
+ div = 2;
+ } else {
+ clk_src = CLK_UART_SRC_SEL_GPLL;
+ 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 = 5;
+ break;
+ case SCLK_UART1:
+ reg = 7;
+ break;
+ case SCLK_UART2:
+ reg = 9;
+ break;
+ case SCLK_UART3:
+ reg = 11;
+ break;
+ case SCLK_UART4:
+ reg = 13;
+ break;
+ case SCLK_UART5:
+ reg = 15;
+ break;
+ default:
+ return -ENOENT;
+ }
+ rk_clrsetreg(&cru->clksel_con[reg],
+ CLK_UART_SRC_SEL_MASK |
+ CLK_UART_SRC_DIV_MASK,
+ (clk_src << CLK_UART_SRC_SEL_SHIFT) |
+ ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
+ rk_clrsetreg(&cru->clksel_con[reg + 2],
+ CLK_UART_SEL_MASK,
+ uart_src << CLK_UART_SEL_SHIFT);
+ if (m && n) {
+ val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
+ writel(val, &cru->clksel_con[reg + 1]);
+ }
+
+ return rv1106_uart_get_rate(priv, clk_id);
+}
+
+static ulong rv1106_vop_get_clk(struct rv1106_clk_priv *priv, ulong clk_id)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 div, sel, con;
+
+ switch (clk_id) {
+ case ACLK_VOP_ROOT:
+ case ACLK_VOP:
+ con = readl(&cru->vo_clksel_con[1]);
+ sel = (con & ACLK_VOP_SEL_MASK) >> ACLK_VOP_SEL_SHIFT;
+ if (sel == ACLK_VOP_SEL_300M)
+ return 300 * MHz;
+ else if (sel == ACLK_VOP_SEL_200M)
+ return 200 * MHz;
+ else if (sel == ACLK_VOP_SEL_100M)
+ return 100 * MHz;
+ else
+ return OSC_HZ;
+ case DCLK_VOP_SRC:
+ case DCLK_VOP:
+ con = readl(&cru->clksel_con[23]);
+ sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
+ div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
+ if (sel == DCLK_VOP_SEL_GPLL)
+ return DIV_TO_RATE(priv->gpll_hz, div);
+ else
+ return DIV_TO_RATE(priv->cpll_hz, div);
+ default:
+ return -ENOENT;
+ }
+}
+
+static ulong rv1106_vop_set_clk(struct rv1106_clk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ int div, sel;
+
+ switch (clk_id) {
+ case ACLK_VOP_ROOT:
+ case ACLK_VOP:
+ if (rate >= 297 * MHz)
+ sel = ACLK_VOP_SEL_300M;
+ else if (rate >= 198 * MHz)
+ sel = ACLK_VOP_SEL_200M;
+ else if (rate >= 99 * MHz)
+ sel = ACLK_VOP_SEL_100M;
+ else
+ sel = ACLK_VOP_SEL_24M;
+ rk_clrsetreg(&cru->vo_clksel_con[1],
+ ACLK_VOP_SEL_MASK,
+ sel << ACLK_VOP_SEL_SHIFT);
+ break;
+ case DCLK_VOP_SRC:
+ case DCLK_VOP:
+ if ((priv->cpll_hz % rate) == 0) {
+ sel = DCLK_VOP_SEL_CPLL;
+ div = DIV_ROUND_UP(priv->cpll_hz, rate);
+ } else {
+ sel = DCLK_VOP_SEL_GPLL;
+ div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ }
+ rk_clrsetreg(&cru->clksel_con[23],
+ DCLK_VOP_SEL_MASK |
+ DCLK_VOP_DIV_MASK,
+ sel << DCLK_VOP_SEL_SHIFT |
+ (div - 1) << DCLK_VOP_DIV_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1106_vop_get_clk(priv, clk_id);
+}
+
+static ulong rv1106_decom_get_clk(struct rv1106_clk_priv *priv)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel, con, prate;
+
+ con = readl(&cru->peri_clksel_con[7]);
+ sel = (con & DCLK_DECOM_SEL_MASK) >>
+ DCLK_DECOM_SEL_SHIFT;
+ if (sel == DCLK_DECOM_SEL_400M)
+ prate = 400 * MHz;
+ else if (sel == DCLK_DECOM_SEL_200M)
+ prate = 200 * MHz;
+ else if (sel == DCLK_DECOM_SEL_100M)
+ prate = 100 * MHz;
+ else
+ prate = OSC_HZ;
+ return prate;
+}
+
+static ulong rv1106_decom_set_clk(struct rv1106_clk_priv *priv, ulong rate)
+{
+ struct rv1106_cru *cru = priv->cru;
+ u32 sel;
+
+ if (rate >= 396 * MHz)
+ sel = DCLK_DECOM_SEL_400M;
+ else if (rate >= 198 * MHz)
+ sel = DCLK_DECOM_SEL_200M;
+ else if (rate >= 99 * MHz)
+ sel = DCLK_DECOM_SEL_100M;
+ else
+ sel = DCLK_DECOM_SEL_24M;
+ rk_clrsetreg(&cru->peri_clksel_con[7], DCLK_DECOM_SEL_MASK,
+ (sel << DCLK_DECOM_SEL_SHIFT));
+
+ return rv1106_decom_get_clk(priv);
+}
+
+static ulong rv1106_clk_get_rate(struct clk *clk)
+{
+ struct rv1106_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_APLL:
+ rate = rockchip_pll_get_rate(&rv1106_pll_clks[APLL], priv->cru,
+ APLL);
+ break;
+ case PLL_DPLL:
+ rate = rockchip_pll_get_rate(&rv1106_pll_clks[DPLL], priv->cru,
+ DPLL);
+ break;
+ case PLL_CPLL:
+ rate = rockchip_pll_get_rate(&rv1106_pll_clks[CPLL], priv->cru,
+ CPLL);
+ break;
+ case PLL_GPLL:
+ rate = rockchip_pll_get_rate(&rv1106_pll_clks[GPLL], priv->cru,
+ GPLL);
+ break;
+ case ACLK_PERI_ROOT:
+ case HCLK_PERI_ROOT:
+ case PCLK_PERI_ROOT:
+ case ACLK_BUS_ROOT:
+ case PCLK_TOP_ROOT:
+ case PCLK_PMU_ROOT:
+ case HCLK_PMU_ROOT:
+ rate = rv1106_peri_get_clk(priv, clk->id);
+ break;
+ case CLK_CORE_CRYPTO:
+ case CLK_PKA_CRYPTO:
+ case ACLK_CRYPTO:
+ rate = rv1106_crypto_get_clk(priv, clk->id);
+ break;
+ case CCLK_SRC_SDMMC:
+ case CCLK_SRC_EMMC:
+ case SCLK_SFC:
+ case HCLK_SDMMC:
+ case HCLK_EMMC:
+ case HCLK_SFC:
+ rate = rv1106_mmc_get_clk(priv, clk->id);
+ break;
+ case CLK_I2C0:
+ case CLK_I2C1:
+ case CLK_I2C2:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ rate = rv1106_i2c_get_clk(priv, clk->id);
+ break;
+ case CLK_SPI0:
+ case CLK_SPI1:
+ rate = rv1106_spi_get_clk(priv, clk->id);
+ break;
+ case CLK_PWM0_PERI:
+ case CLK_PWM1_PERI:
+ case CLK_PWM2_PERI:
+ rate = rv1106_pwm_get_clk(priv, clk->id);
+ break;
+ case CLK_SARADC:
+ case CLK_TSADC_TSEN:
+ case CLK_TSADC:
+ rate = rv1106_adc_get_clk(priv, clk->id);
+ break;
+ case SCLK_UART0:
+ case SCLK_UART1:
+ case SCLK_UART2:
+ case SCLK_UART3:
+ case SCLK_UART4:
+ case SCLK_UART5:
+ rate = rv1106_uart_get_rate(priv, clk->id);
+ break;
+ case DCLK_VOP_SRC:
+ case DCLK_VOP:
+ case ACLK_VOP_ROOT:
+ case ACLK_VOP:
+ rate = rv1106_vop_get_clk(priv, clk->id);
+ break;
+ case DCLK_DECOM:
+ rate = rv1106_decom_get_clk(priv);
+ break;
+ case TCLK_WDT_NS:
+ rate = OSC_HZ;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rate;
+};
+
+static ulong rv1106_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rv1106_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_APLL:
+ ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
+ APLL, rate);
+ break;
+ case PLL_CPLL:
+ ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
+ CPLL, rate);
+ break;
+ case PLL_GPLL:
+ ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
+ GPLL, rate);
+ break;
+ case ACLK_PERI_ROOT:
+ case HCLK_PERI_ROOT:
+ case PCLK_PERI_ROOT:
+ case ACLK_BUS_ROOT:
+ case PCLK_TOP_ROOT:
+ case PCLK_PMU_ROOT:
+ case HCLK_PMU_ROOT:
+ ret = rv1106_peri_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_CORE_CRYPTO:
+ case CLK_PKA_CRYPTO:
+ case ACLK_CRYPTO:
+ ret = rv1106_crypto_set_clk(priv, clk->id, rate);
+ break;
+ case CCLK_SRC_SDMMC:
+ case CCLK_SRC_EMMC:
+ case SCLK_SFC:
+ case HCLK_SDMMC:
+ case HCLK_EMMC:
+ case HCLK_SFC:
+ ret = rv1106_mmc_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_I2C0:
+ case CLK_I2C1:
+ case CLK_I2C2:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ ret = rv1106_i2c_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_SPI0:
+ case CLK_SPI1:
+ ret = rv1106_spi_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_PWM0_PERI:
+ case CLK_PWM1_PERI:
+ case CLK_PWM2_PERI:
+ ret = rv1106_pwm_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_SARADC:
+ case CLK_TSADC_TSEN:
+ case CLK_TSADC:
+ ret = rv1106_adc_set_clk(priv, clk->id, rate);
+ break;
+ case SCLK_UART0:
+ case SCLK_UART1:
+ case SCLK_UART2:
+ case SCLK_UART3:
+ case SCLK_UART4:
+ case SCLK_UART5:
+ ret = rv1106_uart_set_rate(priv, clk->id, rate);
+ break;
+ case DCLK_VOP_SRC:
+ case DCLK_VOP:
+ case ACLK_VOP_ROOT:
+ case ACLK_VOP:
+ rate = rv1106_vop_set_clk(priv, clk->id, rate);
+ break;
+ case DCLK_DECOM:
+ rate = rv1106_decom_set_clk(priv, rate);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return ret;
+};
+
+static int rv1106_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ switch (clk->id) {
+ default:
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+static struct clk_ops rv1106_clk_ops = {
+ .get_rate = rv1106_clk_get_rate,
+ .set_rate = rv1106_clk_set_rate,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .set_parent = rv1106_clk_set_parent,
+#endif
+};
+
+static void rv1106_clk_init(struct rv1106_clk_priv *priv)
+{
+ int ret;
+
+ priv->sync_kernel = false;
+ if (!priv->armclk_enter_hz) {
+ priv->armclk_enter_hz =
+ rockchip_pll_get_rate(&rv1106_pll_clks[APLL],
+ priv->cru, APLL);
+ priv->armclk_init_hz = priv->armclk_enter_hz;
+ }
+
+ if (priv->armclk_init_hz != APLL_HZ) {
+ ret = rockchip_pll_set_rate(&rv1106_pll_clks[APLL], priv->cru,
+ APLL, APLL_HZ);
+ if (!ret)
+ priv->armclk_init_hz = APLL_HZ;
+ }
+
+ if (priv->cpll_hz != CPLL_HZ) {
+ ret = rockchip_pll_set_rate(&rv1106_pll_clks[CPLL], priv->cru,
+ CPLL, CPLL_HZ);
+ if (!ret)
+ priv->cpll_hz = CPLL_HZ;
+ }
+
+ if (priv->gpll_hz != GPLL_HZ) {
+ ret = rockchip_pll_set_rate(&rv1106_pll_clks[GPLL], priv->cru,
+ GPLL, GPLL_HZ);
+ if (!ret)
+ priv->gpll_hz = GPLL_HZ;
+ }
+}
+
+static int rv1106_clk_probe(struct udevice *dev)
+{
+ struct rv1106_clk_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ rv1106_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;
+ rk_clrsetreg(&priv->cru->core_clksel_con[0],
+ CLK_CORE_DIV_MASK,
+ 0 << CLK_CORE_DIV_SHIFT);
+
+ return 0;
+}
+
+static int rv1106_clk_of_to_plat(struct udevice *dev)
+{
+ struct rv1106_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = dev_read_addr_ptr(dev);
+
+ return 0;
+}
+
+static int rv1106_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 rv1106_cru,
+ glb_srst_fst);
+ priv->glb_srst_snd_value = offsetof(struct rv1106_cru,
+ glb_srst_snd);
+ dev_set_priv(sys_child, priv);
+ }
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+ ret = offsetof(struct rv1106_cru, pmu_softrst_con[0]);
+ ret = rockchip_reset_bind(dev, ret, 15);
+ if (ret)
+ debug("Warning: software reset driver bind failed\n");
+#endif
+
+ return 0;
+}
+
+static const struct udevice_id rv1106_clk_ids[] = {
+ { .compatible = "rockchip,rv1106-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rv1106_cru) = {
+ .name = "rockchip_rv1106_cru",
+ .id = UCLASS_CLK,
+ .of_match = rv1106_clk_ids,
+ .priv_auto = sizeof(struct rv1106_clk_priv),
+ .of_to_plat = rv1106_clk_of_to_plat,
+ .ops = &rv1106_clk_ops,
+ .bind = rv1106_clk_bind,
+ .probe = rv1106_clk_probe,
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 13/15] rockchip: rv1106: Add SoC support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (11 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 12/15] clk: rockchip: Add RV1106 clock driver Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 14/15] luckfox-pico: Add the initial support Simon Glass
` (2 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Heinrich Schuchardt,
Ilias Apalodimas, Jeffy Chen, Johan Jonker, Kever Yang,
Mattijs Korpershoek, Philipp Tomsich, Quentin Schulz, Tom Rini,
huang lin
The RV1106 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. The RV1103 is a package variant of the RV1106
with fewer pins.
Add the core SoC support for it: the Kconfig and Makefile entries, the
boot0 hook, the SoC init code (firewall setup, watchdog release and
the pvtpll reboot workaround from the vendor tree), the syscon driver
and the SoC u-boot.dtsi
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
arch/arm/dts/rv1106-u-boot.dtsi | 4 +
arch/arm/include/asm/arch-rv1106/boot0.h | 11 ++
arch/arm/mach-rockchip/Kconfig | 15 +++
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rv1106/Kconfig | 28 +++++
arch/arm/mach-rockchip/rv1106/Makefile | 12 ++
arch/arm/mach-rockchip/rv1106/clk_rv1106.c | 31 +++++
arch/arm/mach-rockchip/rv1106/rv1106.c | 118 ++++++++++++++++++
arch/arm/mach-rockchip/rv1106/syscon_rv1106.c | 19 +++
board/luckfox/pico/Kconfig | 12 ++
include/configs/rv1106_common.h | 13 ++
11 files changed, 264 insertions(+)
create mode 100644 arch/arm/dts/rv1106-u-boot.dtsi
create mode 100644 arch/arm/include/asm/arch-rv1106/boot0.h
create mode 100644 arch/arm/mach-rockchip/rv1106/Kconfig
create mode 100644 arch/arm/mach-rockchip/rv1106/Makefile
create mode 100644 arch/arm/mach-rockchip/rv1106/clk_rv1106.c
create mode 100644 arch/arm/mach-rockchip/rv1106/rv1106.c
create mode 100644 arch/arm/mach-rockchip/rv1106/syscon_rv1106.c
create mode 100644 board/luckfox/pico/Kconfig
create mode 100644 include/configs/rv1106_common.h
diff --git a/arch/arm/dts/rv1106-u-boot.dtsi b/arch/arm/dts/rv1106-u-boot.dtsi
new file mode 100644
index 00000000000..fa062c8ee84
--- /dev/null
+++ b/arch/arm/dts/rv1106-u-boot.dtsi
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+// (C) Copyright 2022 Rockchip Electronics Co., Ltd
+
+#include "rockchip-u-boot.dtsi"
diff --git a/arch/arm/include/asm/arch-rv1106/boot0.h b/arch/arm/include/asm/arch-rv1106/boot0.h
new file mode 100644
index 00000000000..e132eb98116
--- /dev/null
+++ b/arch/arm/include/asm/arch-rv1106/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2022 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 1969c313f47..5b1032f258b 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -544,6 +544,20 @@ config ROCKCHIP_RV1103B
32-bit core which integrates NEON and FPU.
It contains a built-in NPU for AI related applications.
+config ROCKCHIP_RV1106
+ bool "Support Rockchip RV1106"
+ select CPU_V7A
+ select SPL_ARMV7_SET_CORTEX_SMPEN
+ select SUPPORT_SPL
+ select SPL
+ imply ROCKCHIP_COMMON_BOARD
+ help
+ The Rockchip RV1106 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. The RV1103 is a package variant
+ of the RV1106 with fewer pins and is also supported by this
+ option.
+
config ROCKCHIP_RV1108
bool "Support Rockchip RV1108"
select CPU_V7A
@@ -808,6 +822,7 @@ 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/rv1106/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 e09dc44a7ad..0d42ddbe678 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_ROCKCHIP_RK3568) += rk3568/
obj-$(CONFIG_ROCKCHIP_RK3576) += rk3576/
obj-$(CONFIG_ROCKCHIP_RK3588) += rk3588/
obj-$(CONFIG_ROCKCHIP_RV1103B) += rv1103b/
+obj-$(CONFIG_ROCKCHIP_RV1106) += rv1106/
obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/
obj-$(CONFIG_ROCKCHIP_RV1126) += rv1126/
diff --git a/arch/arm/mach-rockchip/rv1106/Kconfig b/arch/arm/mach-rockchip/rv1106/Kconfig
new file mode 100644
index 00000000000..05eafd96833
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1106/Kconfig
@@ -0,0 +1,28 @@
+if ROCKCHIP_RV1106
+
+config TARGET_LUCKFOX_PICO_RV1103
+ bool "LUCKFOX_PICO_RV1103"
+ help
+ Support Luckfox's Pico series of RV1103 boards, such as the Pico
+ Mini B. These are small, low-cost boards with 64MB of in-package
+ DDR2, a microSD slot and a USB-C port used for both power and
+ maskrom-mode USB download; most I/O is on castellated edge pins.
+ The Mini B adds a 128MB Winbond SPI NAND, from which it boots.
+ U-Boot can also run entirely from RAM over USB, with nothing
+ written to the flash.
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff020200
+
+config ROCKCHIP_STIMER_BASE
+ default 0xff590020
+
+config SYS_SOC
+ default "rv1106"
+
+config SYS_MALLOC_F_LEN
+ default 0x400
+
+source "board/luckfox/pico/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/rv1106/Makefile b/arch/arm/mach-rockchip/rv1106/Makefile
new file mode 100644
index 00000000000..66aba9fbfe2
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1106/Makefile
@@ -0,0 +1,12 @@
+#
+# (C) Copyright 2022 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rv1106.o
+obj-y += clk_rv1106.o
+
+ifndef CONFIG_XPL_BUILD
+obj-y += syscon_rv1106.o
+endif
diff --git a/arch/arm/mach-rockchip/rv1106/clk_rv1106.c b/arch/arm/mach-rockchip/rv1106/clk_rv1106.c
new file mode 100644
index 00000000000..86020c45c22
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1106/clk_rv1106.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2022 Rockchip Electronics Co., Ltd
+ */
+
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1106.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rv1106_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rv1106_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/rv1106/rv1106.c b/arch/arm/mach-rockchip/rv1106/rv1106.c
new file mode 100644
index 00000000000..a93c3e5f2fe
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1106/rv1106.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 Rockchip Electronics Co., Ltd
+ */
+
+#include <dm.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define PERI_GRF_BASE 0xff000000
+#define PERI_GRF_PERI_CON1 0x0004
+
+#define PERI_SGRF_BASE 0xff070000
+#define PERI_SGRF_FIREWALL_CON0 0x0020
+#define PERI_SGRF_FIREWALL_CON1 0x0024
+#define PERI_SGRF_FIREWALL_CON2 0x0028
+#define PERI_SGRF_FIREWALL_CON3 0x002c
+#define PERI_SGRF_FIREWALL_CON4 0x0030
+#define PERI_SGRF_SOC_CON3 0x00bc
+
+#define CORE_SGRF_BASE 0xff076000
+#define CORE_SGRF_FIREWALL_CON0 0x0020
+#define CORE_SGRF_FIREWALL_CON1 0x0024
+#define CORE_SGRF_FIREWALL_CON2 0x0028
+#define CORE_SGRF_FIREWALL_CON3 0x002c
+#define CORE_SGRF_FIREWALL_CON4 0x0030
+#define CORE_SGRF_CPU_CTRL_CON 0x0040
+
+#define PMU_SGRF_BASE 0xff080000
+
+#define FW_DDR_BASE 0xff900000
+#define FW_DDR_MST3_REG 0x4c
+#define FW_SHRM_BASE 0xff910000
+#define FW_SHRM_MST1_REG 0x44
+
+#define CRU_BASE 0xff3b0000
+#define CRU_GLB_RST_CON 0x0c10
+#define CRU_PVTPLL0_CON0_L 0x1000
+#define CRU_PVTPLL0_CON1_L 0x1008
+#define CRU_PVTPLL1_CON0_L 0x1030
+#define CRU_PVTPLL1_CON1_L 0x1038
+
+#define VICRU_BASE 0xff3b4000
+#define VICRU_VISOFTRST_CON01 0x0a04
+
+#define CHIP_VER_REG 0xff020204
+#define CHIP_VER_MSK 0x7
+#define V(x) ((x) - 1)
+#define ROM_VER_REG 0xffff4ffc
+#define ROM_V2 0x30303256
+
+void board_debug_uart_init(void)
+{
+ /* The BootROM leaves the debug UART configured */
+}
+
+static void rv1106_xpl_init(void)
+{
+ /* Save the chip version to OS_REG1[2:0] */
+ if (readl(ROM_VER_REG) == ROM_V2)
+ writel((readl(CHIP_VER_REG) & ~CHIP_VER_MSK) | V(2),
+ CHIP_VER_REG);
+ else
+ writel((readl(CHIP_VER_REG) & ~CHIP_VER_MSK) | V(1),
+ CHIP_VER_REG);
+
+ /* Set all devices to non-secure */
+ writel(0xffff0000, PERI_SGRF_BASE + PERI_SGRF_FIREWALL_CON0);
+ writel(0xffff0000, PERI_SGRF_BASE + PERI_SGRF_FIREWALL_CON1);
+ writel(0xffff0000, PERI_SGRF_BASE + PERI_SGRF_FIREWALL_CON2);
+ writel(0xffff0000, PERI_SGRF_BASE + PERI_SGRF_FIREWALL_CON3);
+ writel(0xffff0000, PERI_SGRF_BASE + PERI_SGRF_FIREWALL_CON4);
+ writel(0x000f0000, PERI_SGRF_BASE + PERI_SGRF_SOC_CON3);
+ writel(0xffff0000, CORE_SGRF_BASE + CORE_SGRF_FIREWALL_CON0);
+ writel(0xffff0000, CORE_SGRF_BASE + CORE_SGRF_FIREWALL_CON1);
+ writel(0xffff0000, CORE_SGRF_BASE + CORE_SGRF_FIREWALL_CON2);
+ writel(0xffff0000, CORE_SGRF_BASE + CORE_SGRF_FIREWALL_CON3);
+ writel(0xffff0000, CORE_SGRF_BASE + CORE_SGRF_FIREWALL_CON4);
+ writel(0x00030002, CORE_SGRF_BASE + CORE_SGRF_CPU_CTRL_CON);
+ writel(0x20000000, PMU_SGRF_BASE);
+
+ /* Allow the eMMC and FSPI to access the secure area */
+ writel(0x00000000, FW_DDR_BASE + FW_DDR_MST3_REG);
+ writel(0xff00ffff, FW_SHRM_BASE + FW_SHRM_MST1_REG);
+
+ /* Release the watchdog */
+ writel(0x2000200, PERI_GRF_BASE + PERI_GRF_PERI_CON1);
+ writel(0x400040, CRU_BASE + CRU_GLB_RST_CON);
+
+ /*
+ * When the venc/npu use the pvtpll, a reboot fails because the
+ * pvtpll is reset before the venc/npu reset, so the venc/npu is
+ * not completely reset and the system blocks when accessing the
+ * NoC in SPL. Enable the pvtpll so that the venc/npu reset can
+ * complete.
+ */
+ writel(0xffff0018, CRU_BASE + CRU_PVTPLL0_CON1_L);
+ writel(0x00030003, CRU_BASE + CRU_PVTPLL0_CON0_L);
+ writel(0xffff0018, CRU_BASE + CRU_PVTPLL1_CON1_L);
+ writel(0x00030003, CRU_BASE + CRU_PVTPLL1_CON0_L);
+ udelay(2);
+}
+
+int arch_cpu_init(void)
+{
+ if (is_xpl())
+ rv1106_xpl_init();
+
+ /* Reset the sdmmc0 to prevent a power leak */
+ writel(0x30003000, VICRU_BASE + VICRU_VISOFTRST_CON01);
+ udelay(1);
+ writel(0x30000000, VICRU_BASE + VICRU_VISOFTRST_CON01);
+
+ return 0;
+}
diff --git a/arch/arm/mach-rockchip/rv1106/syscon_rv1106.c b/arch/arm/mach-rockchip/rv1106/syscon_rv1106.c
new file mode 100644
index 00000000000..d669991fbc5
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1106/syscon_rv1106.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 Rockchip Electronics Co., Ltd
+ */
+
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rv1106_syscon_ids[] = {
+ { .compatible = "rockchip,rv1106-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rv1106) = {
+ .name = "rv1106_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1106_syscon_ids,
+};
diff --git a/board/luckfox/pico/Kconfig b/board/luckfox/pico/Kconfig
new file mode 100644
index 00000000000..62176b3779f
--- /dev/null
+++ b/board/luckfox/pico/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_LUCKFOX_PICO_RV1103
+
+config SYS_BOARD
+ default "pico"
+
+config SYS_VENDOR
+ default "luckfox"
+
+config SYS_CONFIG_NAME
+ default "luckfox_pico"
+
+endif
diff --git a/include/configs/rv1106_common.h b/include/configs/rv1106_common.h
new file mode 100644
index 00000000000..1678fe54676
--- /dev/null
+++ b/include/configs/rv1106_common.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2022 Rockchip Electronics Co., Ltd
+ */
+#ifndef __CONFIG_RV1106_COMMON_H
+#define __CONFIG_RV1106_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CFG_IRAM_BASE 0xff6c0000
+#define CFG_SYS_SDRAM_BASE 0x00000000
+
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 14/15] luckfox-pico: Add the initial support
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (12 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 13/15] rockchip: rv1106: Add SoC support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:31 ` [PATCH v3 15/15] rockchip: Support legacy images when booting from RAM Simon Glass
2026-07-07 15:35 ` [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Tom Rini
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Alexander Feilke,
Chris Packham, FUKAUMI Naoki, Ilias Apalodimas, Johan Jonker,
Kever Yang, Niu Zhihong, Peng Fan, Peter Robinson,
Philipp Tomsich, Quentin Schulz, Svyatoslav Ryhel, Tianling Shen,
Tom Rini
Add the initial support for the Luckfox Pico Mini B board, which uses
the RV1103 with 64MB of in-package DDR2 and a 128MB Winbond SPI NAND.
The board boots from the SPI NAND, or over USB in maskrom mode using
the u-boot-rockchip-usb471/usb472 images, in which case U-Boot runs
entirely from RAM. The console is on UART2 at 115200 baud
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
.../rv1103-luckfox-pico-mini-b-u-boot.dtsi | 10 +++
arch/arm/dts/rv1103-luckfox-pico-mini-b.dts | 85 +++++++++++++++++++
board/luckfox/pico/MAINTAINERS | 6 ++
board/luckfox/pico/Makefile | 7 ++
board/luckfox/pico/pico.c | 19 +++++
board/luckfox/pico/pico.env | 4 +
configs/luckfox-pico-mini-b-rv1103_defconfig | 79 +++++++++++++++++
doc/board/index.rst | 1 +
doc/board/luckfox/index.rst | 9 ++
doc/board/luckfox/luckfox-pico.rst | 71 ++++++++++++++++
doc/board/rockchip/rockchip.rst | 4 +
include/configs/luckfox_pico.h | 11 +++
12 files changed, 306 insertions(+)
create mode 100644 arch/arm/dts/rv1103-luckfox-pico-mini-b-u-boot.dtsi
create mode 100644 arch/arm/dts/rv1103-luckfox-pico-mini-b.dts
create mode 100644 board/luckfox/pico/MAINTAINERS
create mode 100644 board/luckfox/pico/Makefile
create mode 100644 board/luckfox/pico/pico.c
create mode 100644 board/luckfox/pico/pico.env
create mode 100644 configs/luckfox-pico-mini-b-rv1103_defconfig
create mode 100644 doc/board/luckfox/index.rst
create mode 100644 doc/board/luckfox/luckfox-pico.rst
create mode 100644 include/configs/luckfox_pico.h
diff --git a/arch/arm/dts/rv1103-luckfox-pico-mini-b-u-boot.dtsi b/arch/arm/dts/rv1103-luckfox-pico-mini-b-u-boot.dtsi
new file mode 100644
index 00000000000..968bf1dfa66
--- /dev/null
+++ b/arch/arm/dts/rv1103-luckfox-pico-mini-b-u-boot.dtsi
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0+
+// (C) Copyright 2026 Simon Glass <sjg@chromium.org>
+
+#include "rockchip-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = &spi_nand;
+ };
+};
diff --git a/arch/arm/dts/rv1103-luckfox-pico-mini-b.dts b/arch/arm/dts/rv1103-luckfox-pico-mini-b.dts
new file mode 100644
index 00000000000..b0eac7d13c1
--- /dev/null
+++ b/arch/arm/dts/rv1103-luckfox-pico-mini-b.dts
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Luckfox Electronics Co., Ltd
+ */
+
+/dts-v1/;
+
+#include "rv1103.dtsi"
+
+/ {
+ model = "Luckfox Pico Mini B";
+ compatible = "luckfox,pico-mini-b", "rockchip,rv1103";
+
+ aliases {
+ mmc0 = &sdmmc;
+ spi0 = &sfc;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ status = "okay";
+};
+
+&sfc {
+ 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 0x075c0000>;
+ };
+ };
+ };
+};
+
+&uart2 {
+ bootph-all;
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/board/luckfox/pico/MAINTAINERS b/board/luckfox/pico/MAINTAINERS
new file mode 100644
index 00000000000..debf7059cf9
--- /dev/null
+++ b/board/luckfox/pico/MAINTAINERS
@@ -0,0 +1,6 @@
+LUCKFOX PICO
+M: Simon Glass <sjg@chromium.org>
+S: Maintained
+F: board/luckfox/pico
+F: include/configs/luckfox_pico.h
+F: configs/luckfox-pico-mini-b-rv1103_defconfig
diff --git a/board/luckfox/pico/Makefile b/board/luckfox/pico/Makefile
new file mode 100644
index 00000000000..4d2f5caff96
--- /dev/null
+++ b/board/luckfox/pico/Makefile
@@ -0,0 +1,7 @@
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2026 Simon Glass <sjg@chromium.org>
+#
+
+obj-y += pico.o
diff --git a/board/luckfox/pico/pico.c b/board/luckfox/pico/pico.c
new file mode 100644
index 00000000000..a8a471c20f3
--- /dev/null
+++ b/board/luckfox/pico/pico.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2026 Simon Glass <sjg@chromium.org>
+
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ gd->ram_size = SZ_64M;
+
+ return 0;
+}
+
+phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
+{
+ return gd->ram_top;
+}
diff --git a/board/luckfox/pico/pico.env b/board/luckfox/pico/pico.env
new file mode 100644
index 00000000000..0d954ee4f98
--- /dev/null
+++ b/board/luckfox/pico/pico.env
@@ -0,0 +1,4 @@
+kernel_addr_r=0x00800000
+fdt_addr_r=0x02000000
+ramdisk_addr_r=0x03000000
+bootargs=console=ttyS2,115200 mtdparts=spi0.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
diff --git a/configs/luckfox-pico-mini-b-rv1103_defconfig b/configs/luckfox-pico-mini-b-rv1103_defconfig
new file mode 100644
index 00000000000..f857f0a42c0
--- /dev/null
+++ b/configs/luckfox-pico-mini-b-rv1103_defconfig
@@ -0,0 +1,79 @@
+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="rv1103-luckfox-pico-mini-b"
+CONFIG_ROCKCHIP_RV1106=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_ROCKCHIP_EXTERNAL_TPL=y
+CONFIG_ROCKCHIP_MASKROM_IMAGE=y
+CONFIG_SPL_SERIAL=y
+CONFIG_TARGET_LUCKFOX_PICO_RV1103=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
+CONFIG_SYS_BOOTM_LEN=0x04000000
+CONFIG_SYS_LOAD_ADDR=0x00008000
+CONFIG_DEBUG_UART_BASE=0xff4c0000
+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_GPIO=y
+CONFIG_CMD_MMC=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_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+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_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_ERRNO_STR=y
diff --git a/doc/board/index.rst b/doc/board/index.rst
index 2454c3598fb..11ec39cf915 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -39,6 +39,7 @@ Board-specific doc
kontron/index
lenovo/index
lg/index
+ luckfox/index
liebherr/index
mediatek/index
microchip/index
diff --git a/doc/board/luckfox/index.rst b/doc/board/luckfox/index.rst
new file mode 100644
index 00000000000..66feee84257
--- /dev/null
+++ b/doc/board/luckfox/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Luckfox
+=======
+
+.. toctree::
+ :maxdepth: 2
+
+ luckfox-pico
diff --git a/doc/board/luckfox/luckfox-pico.rst b/doc/board/luckfox/luckfox-pico.rst
new file mode 100644
index 00000000000..a971ee67e0b
--- /dev/null
+++ b/doc/board/luckfox/luckfox-pico.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Luckfox Pico boards
+===================
+
+U-Boot for the Luckfox Pico series of RV1103/RV1106 boards. Only the
+Pico Mini B (RV1103, 64MB DDR2, 128MB SPI NAND) is supported so far.
+
+Quick Start
+-----------
+
+- Get the DDR initialization binary
+- Build U-Boot
+- Boot the board over USB, or 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 DDR initialization binary is at rkbin/bin/rv11/rv1106_ddr_924MHz_v1.15.bin
+and covers both the RV1103 and the RV1106.
+
+Build U-Boot
+------------
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=arm-linux-gnueabihf-
+ $ export ROCKCHIP_TPL=<path-to-rkbin>/bin/rv11/rv1106_ddr_924MHz_v1.15.bin
+ $ make luckfox-pico-mini-b-rv1103_defconfig
+ $ make
+
+This produces idbloader.img and u-boot.img for flashing to the SPI
+NAND, plus u-boot-rockchip-usb471.bin and u-boot-rockchip-usb472.bin
+for booting over USB.
+
+Boot over USB (maskrom mode)
+----------------------------
+
+Hold the BOOT button while applying power (or leave the boot media
+blank) and the BootROM enters maskrom mode on the USB OTG port,
+appearing as USB ID 2207:110c. U-Boot then runs entirely from RAM;
+nothing is written to the flash.
+
+Send the two images with a maskrom download tool such as rockusb or
+rkdeveloptool (note that the loader format parser in older
+rkdeveloptool versions is not needed here, since these are raw
+images):
+
+.. code-block:: bash
+
+ $ rockusb download-boot u-boot-rockchip-usb471.bin u-boot-rockchip-usb472.bin
+
+Flash U-Boot into the SPI NAND
+------------------------------
+
+Enter maskrom mode as above, then use a loader from rkbin to run the
+Rockchip usbplug and write the images:
+
+.. code-block:: bash
+
+ $ cd <path-to-rkbin>
+ $ ./tools/boot_merger RKBOOT/RV1106MINIALL.ini
+ $ ./tools/upgrade_tool db rv1106_download_*.bin
+ $ ./tools/upgrade_tool wl 0x200 idbloader.img
+ $ ./tools/upgrade_tool wl 0xa00 u-boot.img
+
+Power cycle the board and U-Boot output appears on UART2 (115200,8N1).
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index 2574a1da52c..532a13594fc 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -180,6 +180,10 @@ List of mainline supported Rockchip boards:
- Yanyi Tech CoolPi CM5 EVB (coolpi-cm5-evb-rk3588)
- Yanyi Tech CoolPi CM5 GenBook (coolpi-cm5-genbook-rk3588)
+* rv1103
+ - Luckfox Pico Mini B (luckfox-pico-mini-b-rv1103), see
+ :doc:`../luckfox/luckfox-pico`
+
* rv1103b
- Onion Omega4 (omega4-rv1103b), see :doc:`../onion/omega4-rv1103b`
diff --git a/include/configs/luckfox_pico.h b/include/configs/luckfox_pico.h
new file mode 100644
index 00000000000..107ab622dd5
--- /dev/null
+++ b/include/configs/luckfox_pico.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2026 Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/rv1106_common.h>
+
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v3 15/15] rockchip: Support legacy images when booting from RAM
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (13 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 14/15] luckfox-pico: Add the initial support Simon Glass
@ 2026-07-07 15:31 ` Simon Glass
2026-07-07 15:35 ` [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Tom Rini
15 siblings, 0 replies; 21+ messages in thread
From: Simon Glass @ 2026-07-07 15:31 UTC (permalink / raw)
To: u-boot
Cc: Fabio Estevam, Jonas Karlman, Simon Glass, Ilias Apalodimas,
Jeffy Chen, Kever Yang, Philipp Tomsich, Tom Rini, huang lin
The ramboot loader used for maskrom-mode USB boot only handles FIT
payloads, but the maskrom usb472 image contains a legacy image on
32-bit boards without OP-TEE, since the FIT template requires either
TF-A or OP-TEE. Such boards print 'Trying to boot from RAM' and then
hang.
Use the binman payload symbols to locate a legacy image placed
directly after SPL and load it with spl_load(). This allows boards
like the Luckfox Pico Mini and the Omega4 to run U-Boot entirely from
RAM in maskrom mode
Signed-off-by: Simon Glass <sjg@chromium.org>
---
(no changes since v1)
arch/arm/mach-rockchip/spl.c | 53 +++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
index e989c148079..1322fc000b0 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -14,6 +14,7 @@
#include <mapmem.h>
#include <ram.h>
#include <spl.h>
+#include <spl_load.h>
#include <asm/arch-rockchip/bootrom.h>
#include <asm/arch-rockchip/timer.h>
#include <asm/global_data.h>
@@ -153,15 +154,14 @@ void spl_board_prepare_for_boot(void)
cleanup_before_linux();
}
-#if CONFIG_IS_ENABLED(RAM_DEVICE) && IS_ENABLED(CONFIG_SPL_LOAD_FIT)
+#if CONFIG_IS_ENABLED(RAM_DEVICE)
binman_sym_declare_optional(ulong, payload, image_pos);
binman_sym_declare_optional(ulong, payload, size);
static ulong ramboot_load_read(struct spl_load_info *load, ulong sector,
ulong count, void *buf)
{
- ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT,
- CONFIG_SPL_LOAD_FIT_ADDRESS);
+ ulong addr = (ulong)load->priv;
memcpy(buf, map_sysmem(addr + sector, 0), count);
return count;
@@ -170,29 +170,44 @@ static ulong ramboot_load_read(struct spl_load_info *load, ulong sector,
static int ramboot_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
- struct legacy_img_hdr *header;
- ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT,
- CONFIG_SPL_LOAD_FIT_ADDRESS);
ulong image_pos = binman_sym(ulong, payload, image_pos);
ulong size = binman_sym(ulong, payload, size);
+ struct legacy_img_hdr *header;
+ struct spl_load_info load;
+
+ if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
+ ulong addr = IF_ENABLED_INT(CONFIG_SPL_LOAD_FIT,
+ CONFIG_SPL_LOAD_FIT_ADDRESS);
+
+ if (addr == CFG_SYS_SDRAM_BASE || addr == CONFIG_SPL_TEXT_BASE)
+ return -ENODEV;
+
+ if (image_pos != BINMAN_SYM_MISSING &&
+ size != BINMAN_SYM_MISSING) {
+ header = map_sysmem(image_pos, 0);
+ if (image_get_magic(header) == FDT_MAGIC) {
+ memmove(map_sysmem(addr, 0), header, size);
+ memset(header, 0, sizeof(*header));
+ }
+ }
- if (addr == CFG_SYS_SDRAM_BASE || addr == CONFIG_SPL_TEXT_BASE)
- return -ENODEV;
-
- if (image_pos != BINMAN_SYM_MISSING && size != BINMAN_SYM_MISSING) {
- header = map_sysmem(image_pos, 0);
+ header = map_sysmem(addr, 0);
if (image_get_magic(header) == FDT_MAGIC) {
- memmove(map_sysmem(addr, 0), header, size);
- memset(header, 0, sizeof(*header));
+ spl_load_init(&load, ramboot_load_read,
+ map_sysmem(addr, 0), 1);
+ return spl_load_simple_fit(spl_image, &load, 0,
+ header);
}
}
- header = map_sysmem(addr, 0);
- if (image_get_magic(header) == FDT_MAGIC) {
- struct spl_load_info load;
-
- spl_load_init(&load, ramboot_load_read, NULL, 1);
- return spl_load_simple_fit(spl_image, &load, 0, header);
+ /* Fall back to a legacy image placed directly after SPL */
+ if (image_pos != BINMAN_SYM_MISSING && size != BINMAN_SYM_MISSING) {
+ header = map_sysmem(image_pos, 0);
+ if (image_get_magic(header) == IH_MAGIC) {
+ spl_load_init(&load, ramboot_load_read,
+ map_sysmem(image_pos, 0), 1);
+ return spl_load(spl_image, bootdev, &load, size, 0);
+ }
}
return -ENODEV;
--
2.43.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
` (14 preceding siblings ...)
2026-07-07 15:31 ` [PATCH v3 15/15] rockchip: Support legacy images when booting from RAM Simon Glass
@ 2026-07-07 15:35 ` Tom Rini
2026-07-08 22:36 ` Simon Glass
15 siblings, 1 reply; 21+ messages in thread
From: Tom Rini @ 2026-07-07 15:35 UTC (permalink / raw)
To: Simon Glass
Cc: u-boot, Fabio Estevam, Jonas Karlman, Albert Aribaud,
Alexander Feilke, Alexey Charkov, Alexey Charkov, Andrew Davis,
Anshul Dalal, Bastien Curutchet, Chris Morgan, Chris Packham,
Elaine Zhang, FUKAUMI Naoki, Finley Xiao, Heinrich Schuchardt,
Hrushikesh Salunke, Ilias Apalodimas, Jeffy Chen, Johan Jonker,
João Marcos Costa, Kever Yang, Lukasz Majewski,
Mattijs Korpershoek, Neil Armstrong, Niu Zhihong, Peng Fan,
Peter Robinson, Philipp Tomsich, Quentin Schulz, Richard Genoud,
Svyatoslav Ryhel, Tianling Shen, Xuhui Lin, Ye Zhang, huang lin
[-- Attachment #1: Type: text/plain, Size: 1625 bytes --]
On Tue, Jul 07, 2026 at 09:30:58AM -0600, Simon Glass wrote:
> This series adds support for three small Rockchip camera SoCs and two
> boards which use them.
>
> The first eight patches are Fabio Estevam's series adding the RV1103B
> and the Onion Omega4 board, updated here to address the review
> comments on v2: the board patch is split into SoC and board patches,
> the devicetree files move into the patches where they belong and the
> pinctrl driver uses regmap_update_bits() throughout. All credit for
> this work goes to Fabio. The devicetree concern raised in the v2
> review is also resolved now: the devicetree files carried here are the
> versions merged in Linux v7.1, verbatim, and can be dropped once the
> next dts/upstream sync brings them in.
>
> The remaining patches add the RV1106 and its RV1103 package variant,
> following the same structure as the RV1103B patches, together with
> the Luckfox Pico Mini B board. These SoCs have no mainline Linux
> support yet, so their devicetrees are local for now. The clock and
> pinctrl drivers are ported from the Rockchip vendor tree and are the
> work of Elaine Zhang and Ye Zhang. The final patch makes the
> maskrom-mode RAM-boot images work on 32-bit boards without OP-TEE,
> which both of these boards rely on.
>
> Tested on the Luckfox Pico Mini B: U-Boot runs from RAM over the USB
> maskrom path and both the SPI NAND and a microSD card are usable. THe
> board is running in my lab.
I did ask you not to do this, Simon, as your patches aren't being picked
up until we've resolved the status of u-boot.org.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106
2026-07-07 15:35 ` [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Tom Rini
@ 2026-07-08 22:36 ` Simon Glass
2026-07-09 0:38 ` Tom Rini
0 siblings, 1 reply; 21+ messages in thread
From: Simon Glass @ 2026-07-08 22:36 UTC (permalink / raw)
To: Tom Rini
Cc: U-Boot Mailing List, Fabio Estevam, Jonas Karlman, Albert Aribaud,
Alexander Feilke, Alexey Charkov, Alexey Charkov, Andrew Davis,
Anshul Dalal, Bastien Curutchet, Chris Morgan, Chris Packham,
Elaine Zhang, FUKAUMI Naoki, Finley Xiao, Heinrich Schuchardt,
Hrushikesh Salunke, Ilias Apalodimas, Jeffy Chen, Johan Jonker,
João Marcos Costa, Kever Yang, Lukasz Majewski,
Mattijs Korpershoek, Neil Armstrong, Niu Zhihong, Peng Fan,
Peter Robinson, Philipp Tomsich, Quentin Schulz, Richard Genoud,
Svyatoslav Ryhel, Tianling Shen, Xuhui Lin, Ye Zhang, huang lin
Hi Tom,
On Tue, 7 Jul 2026 at 09:35, Tom Rini <trini@konsulko.com> wrote:
>
> On Tue, Jul 07, 2026 at 09:30:58AM -0600, Simon Glass wrote:
>
> > This series adds support for three small Rockchip camera SoCs and two
> > boards which use them.
> >
> > The first eight patches are Fabio Estevam's series adding the RV1103B
> > and the Onion Omega4 board, updated here to address the review
> > comments on v2: the board patch is split into SoC and board patches,
> > the devicetree files move into the patches where they belong and the
> > pinctrl driver uses regmap_update_bits() throughout. All credit for
> > this work goes to Fabio. The devicetree concern raised in the v2
> > review is also resolved now: the devicetree files carried here are the
> > versions merged in Linux v7.1, verbatim, and can be dropped once the
> > next dts/upstream sync brings them in.
> >
> > The remaining patches add the RV1106 and its RV1103 package variant,
> > following the same structure as the RV1103B patches, together with
> > the Luckfox Pico Mini B board. These SoCs have no mainline Linux
> > support yet, so their devicetrees are local for now. The clock and
> > pinctrl drivers are ported from the Rockchip vendor tree and are the
> > work of Elaine Zhang and Ye Zhang. The final patch makes the
> > maskrom-mode RAM-boot images work on 32-bit boards without OP-TEE,
> > which both of these boards rely on.
> >
> > Tested on the Luckfox Pico Mini B: U-Boot runs from RAM over the USB
> > maskrom path and both the SPI NAND and a microSD card are usable. THe
> > board is running in my lab.
>
> I did ask you not to do this, Simon, as your patches aren't being picked
> up until we've resolved the status of u-boot.org.
I just saw that email Tom...OK, so I should not send any patches at all?
Regards,
Simon
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106
2026-07-08 22:36 ` Simon Glass
@ 2026-07-09 0:38 ` Tom Rini
2026-07-09 1:27 ` Simon Glass
0 siblings, 1 reply; 21+ messages in thread
From: Tom Rini @ 2026-07-09 0:38 UTC (permalink / raw)
To: Simon Glass
Cc: U-Boot Mailing List, Fabio Estevam, Jonas Karlman, Albert Aribaud,
Alexander Feilke, Alexey Charkov, Alexey Charkov, Andrew Davis,
Anshul Dalal, Bastien Curutchet, Chris Morgan, Chris Packham,
Elaine Zhang, FUKAUMI Naoki, Finley Xiao, Heinrich Schuchardt,
Hrushikesh Salunke, Ilias Apalodimas, Jeffy Chen, Johan Jonker,
João Marcos Costa, Kever Yang, Lukasz Majewski,
Mattijs Korpershoek, Neil Armstrong, Niu Zhihong, Peng Fan,
Peter Robinson, Philipp Tomsich, Quentin Schulz, Richard Genoud,
Svyatoslav Ryhel, Tianling Shen, Xuhui Lin, Ye Zhang, huang lin
[-- Attachment #1: Type: text/plain, Size: 2173 bytes --]
On Wed, Jul 08, 2026 at 04:36:57PM -0600, Simon Glass wrote:
> Hi Tom,
>
> On Tue, 7 Jul 2026 at 09:35, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Tue, Jul 07, 2026 at 09:30:58AM -0600, Simon Glass wrote:
> >
> > > This series adds support for three small Rockchip camera SoCs and two
> > > boards which use them.
> > >
> > > The first eight patches are Fabio Estevam's series adding the RV1103B
> > > and the Onion Omega4 board, updated here to address the review
> > > comments on v2: the board patch is split into SoC and board patches,
> > > the devicetree files move into the patches where they belong and the
> > > pinctrl driver uses regmap_update_bits() throughout. All credit for
> > > this work goes to Fabio. The devicetree concern raised in the v2
> > > review is also resolved now: the devicetree files carried here are the
> > > versions merged in Linux v7.1, verbatim, and can be dropped once the
> > > next dts/upstream sync brings them in.
> > >
> > > The remaining patches add the RV1106 and its RV1103 package variant,
> > > following the same structure as the RV1103B patches, together with
> > > the Luckfox Pico Mini B board. These SoCs have no mainline Linux
> > > support yet, so their devicetrees are local for now. The clock and
> > > pinctrl drivers are ported from the Rockchip vendor tree and are the
> > > work of Elaine Zhang and Ye Zhang. The final patch makes the
> > > maskrom-mode RAM-boot images work on 32-bit boards without OP-TEE,
> > > which both of these boards rely on.
> > >
> > > Tested on the Luckfox Pico Mini B: U-Boot runs from RAM over the USB
> > > maskrom path and both the SPI NAND and a microSD card are usable. THe
> > > board is running in my lab.
> >
> > I did ask you not to do this, Simon, as your patches aren't being picked
> > up until we've resolved the status of u-boot.org.
>
> I just saw that email Tom...OK, so I should not send any patches at all?
As I told you on the community call over two weeks ago now, I'm not
comfortable taking your patches until we have resolved the u-boot.org
domain transfer. So no, your patches are not being merged.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106
2026-07-09 0:38 ` Tom Rini
@ 2026-07-09 1:27 ` Simon Glass
2026-07-09 1:40 ` Tom Rini
0 siblings, 1 reply; 21+ messages in thread
From: Simon Glass @ 2026-07-09 1:27 UTC (permalink / raw)
To: Tom Rini
Cc: U-Boot Mailing List, Fabio Estevam, Jonas Karlman, Albert Aribaud,
Alexander Feilke, Alexey Charkov, Alexey Charkov, Andrew Davis,
Anshul Dalal, Bastien Curutchet, Chris Morgan, Chris Packham,
Elaine Zhang, FUKAUMI Naoki, Finley Xiao, Heinrich Schuchardt,
Hrushikesh Salunke, Ilias Apalodimas, Jeffy Chen, Johan Jonker,
João Marcos Costa, Kever Yang, Lukasz Majewski,
Mattijs Korpershoek, Neil Armstrong, Niu Zhihong, Peng Fan,
Peter Robinson, Philipp Tomsich, Quentin Schulz, Richard Genoud,
Svyatoslav Ryhel, Tianling Shen, Xuhui Lin, Ye Zhang, huang lin
Hi Tom,
On Wed, 8 Jul 2026 at 18:38, Tom Rini <trini@konsulko.com> wrote:
>
> On Wed, Jul 08, 2026 at 04:36:57PM -0600, Simon Glass wrote:
> > Hi Tom,
> >
> > On Tue, 7 Jul 2026 at 09:35, Tom Rini <trini@konsulko.com> wrote:
> > >
> > > On Tue, Jul 07, 2026 at 09:30:58AM -0600, Simon Glass wrote:
> > >
> > > > This series adds support for three small Rockchip camera SoCs and two
> > > > boards which use them.
> > > >
> > > > The first eight patches are Fabio Estevam's series adding the RV1103B
> > > > and the Onion Omega4 board, updated here to address the review
> > > > comments on v2: the board patch is split into SoC and board patches,
> > > > the devicetree files move into the patches where they belong and the
> > > > pinctrl driver uses regmap_update_bits() throughout. All credit for
> > > > this work goes to Fabio. The devicetree concern raised in the v2
> > > > review is also resolved now: the devicetree files carried here are the
> > > > versions merged in Linux v7.1, verbatim, and can be dropped once the
> > > > next dts/upstream sync brings them in.
> > > >
> > > > The remaining patches add the RV1106 and its RV1103 package variant,
> > > > following the same structure as the RV1103B patches, together with
> > > > the Luckfox Pico Mini B board. These SoCs have no mainline Linux
> > > > support yet, so their devicetrees are local for now. The clock and
> > > > pinctrl drivers are ported from the Rockchip vendor tree and are the
> > > > work of Elaine Zhang and Ye Zhang. The final patch makes the
> > > > maskrom-mode RAM-boot images work on 32-bit boards without OP-TEE,
> > > > which both of these boards rely on.
> > > >
> > > > Tested on the Luckfox Pico Mini B: U-Boot runs from RAM over the USB
> > > > maskrom path and both the SPI NAND and a microSD card are usable. THe
> > > > board is running in my lab.
> > >
> > > I did ask you not to do this, Simon, as your patches aren't being picked
> > > up until we've resolved the status of u-boot.org.
> >
> > I just saw that email Tom...OK, so I should not send any patches at all?
>
> As I told you on the community call over two weeks ago now, I'm not
> comfortable taking your patches until we have resolved the u-boot.org
> domain transfer. So no, your patches are not being merged.
Do you mean:
- still send patches, they might be reviewed but will not be merged
until we resolve the Concept tree / domain
- stop sending patches completely
Regards,
Simon
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106
2026-07-09 1:27 ` Simon Glass
@ 2026-07-09 1:40 ` Tom Rini
0 siblings, 0 replies; 21+ messages in thread
From: Tom Rini @ 2026-07-09 1:40 UTC (permalink / raw)
To: Simon Glass; +Cc: U-Boot Mailing List
[-- Attachment #1: Type: text/plain, Size: 2979 bytes --]
Dropping everyone else except for the list itself.
On Wed, Jul 08, 2026 at 07:27:52PM -0600, Simon Glass wrote:
> Hi Tom,
>
> On Wed, 8 Jul 2026 at 18:38, Tom Rini <trini@konsulko.com> wrote:
> >
> > On Wed, Jul 08, 2026 at 04:36:57PM -0600, Simon Glass wrote:
> > > Hi Tom,
> > >
> > > On Tue, 7 Jul 2026 at 09:35, Tom Rini <trini@konsulko.com> wrote:
> > > >
> > > > On Tue, Jul 07, 2026 at 09:30:58AM -0600, Simon Glass wrote:
> > > >
> > > > > This series adds support for three small Rockchip camera SoCs and two
> > > > > boards which use them.
> > > > >
> > > > > The first eight patches are Fabio Estevam's series adding the RV1103B
> > > > > and the Onion Omega4 board, updated here to address the review
> > > > > comments on v2: the board patch is split into SoC and board patches,
> > > > > the devicetree files move into the patches where they belong and the
> > > > > pinctrl driver uses regmap_update_bits() throughout. All credit for
> > > > > this work goes to Fabio. The devicetree concern raised in the v2
> > > > > review is also resolved now: the devicetree files carried here are the
> > > > > versions merged in Linux v7.1, verbatim, and can be dropped once the
> > > > > next dts/upstream sync brings them in.
> > > > >
> > > > > The remaining patches add the RV1106 and its RV1103 package variant,
> > > > > following the same structure as the RV1103B patches, together with
> > > > > the Luckfox Pico Mini B board. These SoCs have no mainline Linux
> > > > > support yet, so their devicetrees are local for now. The clock and
> > > > > pinctrl drivers are ported from the Rockchip vendor tree and are the
> > > > > work of Elaine Zhang and Ye Zhang. The final patch makes the
> > > > > maskrom-mode RAM-boot images work on 32-bit boards without OP-TEE,
> > > > > which both of these boards rely on.
> > > > >
> > > > > Tested on the Luckfox Pico Mini B: U-Boot runs from RAM over the USB
> > > > > maskrom path and both the SPI NAND and a microSD card are usable. THe
> > > > > board is running in my lab.
> > > >
> > > > I did ask you not to do this, Simon, as your patches aren't being picked
> > > > up until we've resolved the status of u-boot.org.
> > >
> > > I just saw that email Tom...OK, so I should not send any patches at all?
> >
> > As I told you on the community call over two weeks ago now, I'm not
> > comfortable taking your patches until we have resolved the u-boot.org
> > domain transfer. So no, your patches are not being merged.
>
> Do you mean:
>
> - still send patches, they might be reviewed but will not be merged
> until we resolve the Concept tree / domain
> - stop sending patches completely
I don't want to start another mega-thread.
I'm unsure what is unclear about "I'm not comfortable taking your
patches until we have resolved the u-boot.org domain transfer".
I'm unsure what else I can add here that won't result in another
mega-thread.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2026-07-09 1:55 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 15:30 [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Simon Glass
2026-07-07 15:30 ` [PATCH v3 01/15] ARM: dts: Add the RV1103B devicetree files Simon Glass
2026-07-07 15:31 ` [PATCH v3 02/15] pinctrl: rockchip: Add RV1103B support Simon Glass
2026-07-07 15:31 ` [PATCH v3 03/15] clk: rockchip: Add RV1103B clock driver Simon Glass
2026-07-07 15:31 ` [PATCH v3 04/15] tools: rkcommon: Add RV1103B support Simon Glass
2026-07-07 15:31 ` [PATCH v3 05/15] rockchip: spl-boot-order: Add SPI NAND support Simon Glass
2026-07-07 15:31 ` [PATCH v3 06/15] spl: Add SPI NAND support via MTD in SPL Simon Glass
2026-07-07 15:31 ` [PATCH v3 07/15] rockchip: rv1103b: Add SoC support Simon Glass
2026-07-07 15:31 ` [PATCH v3 08/15] omega4-rv1103b: Add the initial support Simon Glass
2026-07-07 15:31 ` [PATCH v3 09/15] tools: rkcommon: Add RV1106 support Simon Glass
2026-07-07 15:31 ` [PATCH v3 10/15] pinctrl: rockchip: " Simon Glass
2026-07-07 15:31 ` [PATCH v3 11/15] ARM: dts: Add the RV1103/RV1106 devicetree files Simon Glass
2026-07-07 15:31 ` [PATCH v3 12/15] clk: rockchip: Add RV1106 clock driver Simon Glass
2026-07-07 15:31 ` [PATCH v3 13/15] rockchip: rv1106: Add SoC support Simon Glass
2026-07-07 15:31 ` [PATCH v3 14/15] luckfox-pico: Add the initial support Simon Glass
2026-07-07 15:31 ` [PATCH v3 15/15] rockchip: Support legacy images when booting from RAM Simon Glass
2026-07-07 15:35 ` [PATCH v3 00/15] rockchip: Add support for the RV1103B, RV1103 and RV1106 Tom Rini
2026-07-08 22:36 ` Simon Glass
2026-07-09 0:38 ` Tom Rini
2026-07-09 1:27 ` Simon Glass
2026-07-09 1:40 ` Tom Rini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox