summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-10-24 09:39:52 -0400
committerTom Rini <trini@konsulko.com>2023-10-24 09:39:52 -0400
commit5cab3515f8c9796015739c1750b8933291c816be (patch)
treea661c61e1645b6d26c622b818afd09bacff3624b
parent1b2a3d08c0440db4ee37d748b491673f1db0d384 (diff)
parentd039b1b551e8dbb2c309d35bb19b7866caa4dcc1 (diff)
downloadu-boot-5cab3515f8c9796015739c1750b8933291c816be.tar.gz
u-boot-5cab3515f8c9796015739c1750b8933291c816be.tar.bz2
u-boot-5cab3515f8c9796015739c1750b8933291c816be.zip
Merge tag 'u-boot-rockchip-20231024' of https://source.denx.de/u-boot/custodians/u-boot-rockchip
- Add Board: rk3588 NanoPC-T6, Orange Pi 5, Orange Pi 5 Plus; - clk driver fix for rk3568 and rk3588; - rkmtd cmd support for rockchip nand device; - dts update and sync from linux;
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/rk3328-rock64.dts14
-rw-r--r--arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi11
-rw-r--r--arch/arm/dts/rk3588-evb1-v10-u-boot.dtsi11
-rw-r--r--arch/arm/dts/rk3588-evb1-v10.dts136
-rw-r--r--arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi36
-rw-r--r--arch/arm/dts/rk3588-nanopc-t6.dts916
-rw-r--r--arch/arm/dts/rk3588-orangepi-5-plus-u-boot.dtsi27
-rw-r--r--arch/arm/dts/rk3588-orangepi-5-plus.dts848
-rw-r--r--arch/arm/dts/rk3588-rock-5b-u-boot.dtsi204
-rw-r--r--arch/arm/dts/rk3588-rock-5b.dts145
-rw-r--r--arch/arm/dts/rk3588-u-boot.dtsi40
-rw-r--r--arch/arm/dts/rk3588s-orangepi-5-u-boot.dtsi22
-rw-r--r--arch/arm/dts/rk3588s-orangepi-5.dts662
-rw-r--r--arch/arm/dts/rk3588s-pinctrl.dtsi44
-rw-r--r--arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi4
-rw-r--r--arch/arm/dts/rk3588s-u-boot.dtsi78
-rw-r--r--arch/arm/dts/rk3588s.dtsi24
-rw-r--r--arch/arm/mach-rockchip/rk3588/Kconfig46
-rw-r--r--board/friendlyelec/nanopc-t6-rk3588/Kconfig15
-rw-r--r--board/friendlyelec/nanopc-t6-rk3588/MAINTAINERS9
-rw-r--r--board/friendlyelec/nanopc-t6-rk3588/Makefile6
-rw-r--r--board/friendlyelec/nanopc-t6-rk3588/nanopc-t6-rk3588.c39
-rw-r--r--board/rockchip/evb_rk3588/MAINTAINERS14
-rw-r--r--cmd/Kconfig8
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/rkmtd.c204
-rw-r--r--configs/nanopc-t6-rk3588_defconfig108
-rw-r--r--configs/orangepi-5-plus-rk3588_defconfig105
-rw-r--r--configs/orangepi-5-rk3588s_defconfig102
-rw-r--r--configs/radxa-e25-rk3568_defconfig1
-rw-r--r--configs/rock5a-rk3588s_defconfig16
-rw-r--r--configs/rock5b-rk3588_defconfig7
-rw-r--r--configs/sandbox64_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--disk/part.c4
-rw-r--r--doc/board/rockchip/index.rst1
-rw-r--r--doc/board/rockchip/rkmtd.rst105
-rw-r--r--doc/board/rockchip/rockchip.rst3
-rw-r--r--drivers/block/Kconfig7
-rw-r--r--drivers/block/Makefile2
-rw-r--r--drivers/block/blk-uclass.c5
-rw-r--r--drivers/block/rkmtd.c1152
-rw-r--r--drivers/clk/rockchip/clk_pll.c102
-rw-r--r--drivers/clk/rockchip/clk_rk3568.c10
-rw-r--r--drivers/clk/rockchip/clk_rk3588.c35
-rw-r--r--drivers/mtd/nand/raw/Kconfig9
-rw-r--r--drivers/mtd/nand/raw/rockchip_nfc.c3
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c1
-rw-r--r--drivers/scsi/scsi.c4
-rw-r--r--include/blk.h1
-rw-r--r--include/configs/nanopc-t6-rk3588.h15
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/dt-bindings/leds/common.h7
-rw-r--r--include/rkmtd.h191
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/rkmtd.c200
57 files changed, 5472 insertions, 295 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 96066a2b6b..70079974fa 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -191,6 +191,9 @@ dtb-$(CONFIG_ROCKCHIP_RK3588) += \
rk3588-edgeble-neu6a-io.dtb \
rk3588-edgeble-neu6b-io.dtb \
rk3588-evb1-v10.dtb \
+ rk3588-nanopc-t6.dtb \
+ rk3588s-orangepi-5.dtb \
+ rk3588-orangepi-5-plus.dtb \
rk3588s-rock-5a.dtb \
rk3588-rock-5b.dtb
diff --git a/arch/arm/dts/rk3328-rock64.dts b/arch/arm/dts/rk3328-rock64.dts
index f69a38f42d..0a27fa5271 100644
--- a/arch/arm/dts/rk3328-rock64.dts
+++ b/arch/arm/dts/rk3328-rock64.dts
@@ -37,7 +37,8 @@
vin-supply = <&vcc_io>;
};
- vcc_host_5v: vcc-host-5v-regulator {
+ /* Common enable line for all of the rails mentioned in the labels */
+ vcc_host_5v: vcc_host1_5v: vcc_otg_5v: vcc-host-5v-regulator {
compatible = "regulator-fixed";
gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
pinctrl-names = "default";
@@ -48,17 +49,6 @@
vin-supply = <&vcc_sys>;
};
- vcc_host1_5v: vcc_otg_5v: vcc-host1-5v-regulator {
- compatible = "regulator-fixed";
- gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
- pinctrl-names = "default";
- pinctrl-0 = <&usb20_host_drv>;
- regulator-name = "vcc_host1_5v";
- regulator-always-on;
- regulator-boot-on;
- vin-supply = <&vcc_sys>;
- };
-
vcc_sys: vcc-sys {
compatible = "regulator-fixed";
regulator-name = "vcc_sys";
diff --git a/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi b/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi
index 572bdc5665..1136f0bb3b 100644
--- a/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi
+++ b/arch/arm/dts/rk3568-radxa-e25-u-boot.dtsi
@@ -8,9 +8,16 @@
};
};
-/* PCIe PHY driver in U-Boot does not support bifurcation */
&pcie3x1 {
- status = "disabled";
+ pinctrl-0 = <&pcie30x1_reset_h>;
+};
+
+&pinctrl {
+ pcie {
+ pcie30x1_reset_h: pcie30x1-reset-h {
+ rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&sdhci {
diff --git a/arch/arm/dts/rk3588-evb1-v10-u-boot.dtsi b/arch/arm/dts/rk3588-evb1-v10-u-boot.dtsi
index bd2e259486..e8566785e9 100644
--- a/arch/arm/dts/rk3588-evb1-v10-u-boot.dtsi
+++ b/arch/arm/dts/rk3588-evb1-v10-u-boot.dtsi
@@ -6,16 +6,7 @@
#include "rk3588-u-boot.dtsi"
/ {
- aliases {
- mmc0 = &sdmmc;
- mmc1 = &sdhci;
- };
-
chosen {
- u-boot,spl-boot-order = &sdhci;
+ u-boot,spl-boot-order = "same-as-spl", &sdhci;
};
};
-
-&sdhci {
- bootph-all;
-};
diff --git a/arch/arm/dts/rk3588-evb1-v10.dts b/arch/arm/dts/rk3588-evb1-v10.dts
index 229a9111f5..b9d789d578 100644
--- a/arch/arm/dts/rk3588-evb1-v10.dts
+++ b/arch/arm/dts/rk3588-evb1-v10.dts
@@ -7,6 +7,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include "rk3588.dtsi"
@@ -23,12 +24,84 @@
stdout-path = "serial2:1500000n8";
};
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-vol-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <17000>;
+ };
+
+ button-vol-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <417000>;
+ };
+
+ button-menu {
+ label = "Menu";
+ linux,code = <KEY_MENU>;
+ press-threshold-microvolt = <890000>;
+ };
+
+ button-escape {
+ label = "Escape";
+ linux,code = <KEY_ESC>;
+ press-threshold-microvolt = <1235000>;
+ };
+ };
+
backlight: backlight {
compatible = "pwm-backlight";
power-supply = <&vcc12v_dcin>;
pwms = <&pwm2 0 25000 0>;
};
+ pcie20_avdd0v85: pcie20-avdd0v85-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie20_avdd0v85";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ vin-supply = <&avdd_0v85_s0>;
+ };
+
+ pcie20_avdd1v8: pcie20-avdd1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie20_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&avcc_1v8_s0>;
+ };
+
+ pcie30_avdd0v75: pcie30-avdd0v75-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd0v75";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ vin-supply = <&avdd_0v75_s0>;
+ };
+
+ pcie30_avdd1v8: pcie30-avdd1v8-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "pcie30_avdd1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&avcc_1v8_s0>;
+ };
+
vcc12v_dcin: vcc12v-dcin-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc12v_dcin";
@@ -38,6 +111,19 @@
regulator-max-microvolt = <12000000>;
};
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_HIGH>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc12v_dcin>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc3v3_pcie30_en>;
+ };
+
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
@@ -87,6 +173,10 @@
status = "okay";
};
+&combphy2_psu {
+ status = "okay";
+};
+
&cpu_b0 {
cpu-supply = <&vdd_cpu_big0_s0>;
};
@@ -163,7 +253,32 @@
};
};
+&pcie2x1l1 {
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_rst>, <&rtl8111_isolate>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_reset>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
&pinctrl {
+ rtl8111 {
+ rtl8111_isolate: rtl8111-isolate {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
rtl8211f {
rtl8211f_rst: rtl8211f-rst {
rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -177,6 +292,22 @@
};
};
+ pcie2 {
+ pcie2_1_rst: pcie2-1-rst {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_reset: pcie3-reset {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ vcc3v3_pcie30_en: vcc3v3-pcie30-en {
+ rockchip,pins = <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -188,6 +319,11 @@
status = "okay";
};
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
&sdhci {
bus-width = <8>;
no-sdio;
diff --git a/arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi b/arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi
new file mode 100644
index 0000000000..87831c9d43
--- /dev/null
+++ b/arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 John Clark <inindev@gmail.com>
+ *
+ */
+
+#include "rk3588-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci;
+ };
+};
+
+&fspim1_pins {
+ bootph-all;
+};
+
+&sfc {
+ bootph-pre-ram;
+ u-boot,spl-sfc-no-dma;
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim1_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ flash@0 {
+ bootph-pre-ram;
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <24000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
diff --git a/arch/arm/dts/rk3588-nanopc-t6.dts b/arch/arm/dts/rk3588-nanopc-t6.dts
new file mode 100644
index 0000000000..97af4f9128
--- /dev/null
+++ b/arch/arm/dts/rk3588-nanopc-t6.dts
@@ -0,0 +1,916 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2023 Thomas McKahan
+ *
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "FriendlyElec NanoPC-T6";
+ compatible = "friendlyarm,nanopc-t6", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ sys_led: led-0 {
+ gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
+ label = "system-led";
+ linux,default-trigger = "heartbeat";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sys_led_pin>;
+ };
+
+ usr_led: led-1 {
+ gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+ label = "user-led";
+ pinctrl-names = "default";
+ pinctrl-0 = <&usr_led_pin>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_det>;
+
+ simple-audio-card,name = "realtek,rt5616-codec";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+
+ simple-audio-card,hp-det-gpio = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>;
+ simple-audio-card,hp-pin-name = "Headphones";
+
+ simple-audio-card,widgets =
+ "Headphone", "Headphones",
+ "Microphone", "Microphone Jack";
+ simple-audio-card,routing =
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "MIC1", "Microphone Jack",
+ "Microphone Jack", "micbias1";
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ };
+ simple-audio-card,codec {
+ sound-dai = <&rt5616>;
+ };
+ };
+
+ vcc12v_dcin: vcc12v-dcin-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc12v_dcin";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ /* vcc5v0_sys powers peripherals */
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ /* vcc4v0_sys powers the RK806, RK860's */
+ vcc4v0_sys: vcc4v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc4v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <4000000>;
+ vin-supply = <&vcc12v_dcin>;
+ };
+
+ vcc_1v1_nldo_s3: vcc-1v1-nldo-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-1v1-nldo-s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ vin-supply = <&vcc4v0_sys>;
+ };
+
+ vcc_3v3_pcie20: vcc3v3-pcie20-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_3v3_pcie20";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vbus5v0_typec: vbus5v0-typec-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec5v_pwren>;
+ regulator-name = "vbus5v0_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_m2_1_pwren>;
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie_m2_0_pwren>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_b0{
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1{
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2{
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3{
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&gpio0 {
+ gpio-line-names = /* GPIO0 A0-A7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO0 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO0 C0-C7 */
+ "", "", "", "",
+ "HEADER_10", "HEADER_08", "HEADER_32", "",
+ /* GPIO0 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio1 {
+ gpio-line-names = /* GPIO1 A0-A7 */
+ "HEADER_27", "HEADER_28", "", "",
+ "", "", "", "HEADER_15",
+ /* GPIO1 B0-B7 */
+ "HEADER_26", "HEADER_21", "HEADER_19", "HEADER_23",
+ "HEADER_24", "HEADER_22", "", "",
+ /* GPIO1 C0-C7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO1 D0-D7 */
+ "", "", "", "",
+ "", "", "HEADER_05", "HEADER_03";
+};
+
+&gpio2 {
+ gpio-line-names = /* GPIO2 A0-A7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO2 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO2 C0-C7 */
+ "", "CSI1_11", "CSI1_12", "",
+ "", "", "", "",
+ /* GPIO2 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&gpio3 {
+ gpio-line-names = /* GPIO3 A0-A7 */
+ "HEADER_35", "HEADER_38", "HEADER_40", "HEADER_36",
+ "HEADER_37", "", "DSI0_12", "",
+ /* GPIO3 B0-B7 */
+ "HEADER_33", "DSI0_10", "HEADER_07", "HEADER_16",
+ "HEADER_18", "HEADER_29", "HEADER_31", "HEADER_12",
+ /* GPIO3 C0-C7 */
+ "DSI0_08", "DSI0_14", "HEADER_11", "HEADER_13",
+ "", "", "", "",
+ /* GPIO3 D0-D7 */
+ "", "", "", "",
+ "", "DSI1_10", "", "";
+};
+
+&gpio4 {
+ gpio-line-names = /* GPIO4 A0-A7 */
+ "DSI1_08", "DSI1_14", "", "DSI1_12",
+ "", "", "", "",
+ /* GPIO4 B0-B7 */
+ "", "", "", "",
+ "", "", "", "",
+ /* GPIO4 C0-C7 */
+ "", "", "", "",
+ "CSI0_11", "CSI0_12", "", "",
+ /* GPIO4 D0-D7 */
+ "", "", "", "",
+ "", "", "", "";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ rockchip,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc4v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ clock-frequency = <200000>;
+ status = "okay";
+
+ fusb302: typec-portc@22 {
+ compatible = "fcs,fusb302";
+ reg = <0x22>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&usbc0_int>;
+ pinctrl-names = "default";
+ vbus-supply = <&vbus5v0_typec>;
+
+ connector {
+ compatible = "usb-c-connector";
+ data-role = "dual";
+ label = "USB-C";
+ power-role = "dual";
+ try-power-role = "sink";
+ source-pdos = <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>;
+ sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+ op-sink-microwatt = <1000000>;
+ };
+ };
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&i2c7 {
+ clock-frequency = <200000>;
+ status = "okay";
+
+ rt5616: codec@1b {
+ compatible = "realtek,rt5616";
+ reg = <0x1b>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+
+ port {
+ rt5616_p0_0: endpoint {
+ remote-endpoint = <&i2s0_8ch_p0_0>;
+ };
+ };
+ };
+
+ /* connected with MIPI-CSI1 */
+};
+
+&i2c8 {
+ pinctrl-0 = <&i2c8m2_xfer>;
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+
+ i2s0_8ch_p0: port {
+ i2s0_8ch_p0_0: endpoint {
+ dai-format = "i2s";
+ mclk-fs = <256>;
+ remote-endpoint = <&rt5616_p0_0>;
+ };
+ };
+};
+
+&pcie2x1l0 {
+ reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_pcie20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_rst>;
+ status = "okay";
+};
+
+&pcie2x1l1 {
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_1_rst>;
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc_3v3_pcie20>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-leds {
+ sys_led_pin: sys-led-pin {
+ rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usr_led_pin: usr-led-pin {
+ rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ headphone {
+ hp_det: hp-det {
+ rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pcie {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_1_rst: pcie2-1-rst {
+ rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie_m2_0_pwren: pcie-m20-pwren {
+ rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie_m2_1_pwren: pcie-m21-pwren {
+ rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ usbc0_int: usbc0-int {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&pwm1 {
+ pinctrl-0 = <&pwm1m1_pins>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ max-frequency = <200000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ status = "okay";
+};
+
+&sdmmc {
+ max-frequency = <200000000>;
+ no-sdio;
+ no-mmc;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ disable-wp;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ num-cs = <1>;
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ spi-max-frequency = <1000000>;
+ reg = <0x0>;
+
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+
+ vcc1-supply = <&vcc4v0_sys>;
+ vcc2-supply = <&vcc4v0_sys>;
+ vcc3-supply = <&vcc4v0_sys>;
+ vcc4-supply = <&vcc4v0_sys>;
+ vcc5-supply = <&vcc4v0_sys>;
+ vcc6-supply = <&vcc4v0_sys>;
+ vcc7-supply = <&vcc4v0_sys>;
+ vcc8-supply = <&vcc4v0_sys>;
+ vcc9-supply = <&vcc4v0_sys>;
+ vcc10-supply = <&vcc4v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc4v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc4v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 {
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_gpu_s0";
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_cpu_lit_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_log_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-init-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_vdenc_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vdd2_ddr_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vdd_2v0_pldo_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_3v3_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-name = "vddq_ddr_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "avcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-name = "avdd_1v2_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vcc_3v3_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ regulator-name = "vccio_sd_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "pldo6_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s3";
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_ddr_pll_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "avdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+ regulator-name = "vdd_0v85_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+ regulator-name = "vdd_0v75_s0";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&u2phy2_host {
+ status = "okay";
+};
+
+&u2phy3_host {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-orangepi-5-plus-u-boot.dtsi b/arch/arm/dts/rk3588-orangepi-5-plus-u-boot.dtsi
new file mode 100644
index 0000000000..b0f5c66719
--- /dev/null
+++ b/arch/arm/dts/rk3588-orangepi-5-plus-u-boot.dtsi
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include "rk3588-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci;
+ };
+};
+
+&fspim1_pins {
+ bootph-all;
+};
+
+&sdhci {
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+};
+
+&sfc {
+ bootph-pre-ram;
+ u-boot,spl-sfc-no-dma;
+
+ flash@0 {
+ bootph-pre-ram;
+ };
+};
diff --git a/arch/arm/dts/rk3588-orangepi-5-plus.dts b/arch/arm/dts/rk3588-orangepi-5-plus.dts
new file mode 100644
index 0000000000..298c183d6f
--- /dev/null
+++ b/arch/arm/dts/rk3588-orangepi-5-plus.dts
@@ -0,0 +1,848 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2023 Ondřej Jirman <megi@xff.cz>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/usb/pd.h>
+#include "rk3588.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 5 Plus";
+ compatible = "xunlong,orangepi-5-plus", "rockchip,rk3588";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys-0 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-maskrom {
+ label = "Mask Rom";
+ linux,code = <KEY_SETUP>;
+ press-threshold-microvolt = <2000>;
+ };
+ };
+
+ adc-keys-1 {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <2000>;
+ };
+ };
+
+ speaker_amp: speaker-audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ headphone_amp: headphones-audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_HIGH>;
+ sound-name-prefix = "Headphones Amp";
+ };
+
+ ir-receiver {
+ compatible = "gpio-ir-receiver";
+ gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&ir_receiver_pin>;
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&blue_led_pin>;
+
+ led {
+ color = <LED_COLOR_ID_BLUE>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <1>;
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ fan: pwm-fan {
+ compatible = "pwm-fan";
+ cooling-levels = <0 70 75 80 100>;
+ fan-supply = <&vcc5v0_sys>;
+ pwms = <&pwm3 0 50000 0>;
+ #cooling-cells = <2>;
+ };
+
+ pwm-leds {
+ compatible = "pwm-leds";
+
+ led {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_INDICATOR;
+ function-enumerator = <2>;
+ max-brightness = <255>;
+ pwms = <&pwm2 0 25000 0>;
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hp_detect>;
+ simple-audio-card,name = "Analog";
+ simple-audio-card,aux-devs = <&speaker_amp>, <&headphone_amp>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,hp-det-gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_LOW>;
+ simple-audio-card,bitclock-master = <&daicpu>;
+ simple-audio-card,frame-master = <&daicpu>;
+ /*TODO: SARADC_IN3 is used as MIC detection / key input */
+
+ simple-audio-card,widgets =
+ "Microphone", "Onboard Microphone",
+ "Microphone", "Microphone Jack",
+ "Speaker", "Speaker",
+ "Headphone", "Headphones";
+
+ simple-audio-card,routing =
+ "Headphones", "LOUT1",
+ "Headphones", "ROUT1",
+ "Speaker", "LOUT2",
+ "Speaker", "ROUT2",
+
+ "Headphones", "Headphones Amp OUTL",
+ "Headphones", "Headphones Amp OUTR",
+ "Headphones Amp INL", "LOUT1",
+ "Headphones Amp INR", "ROUT1",
+
+ "Speaker", "Speaker Amp OUTL",
+ "Speaker", "Speaker Amp OUTR",
+ "Speaker Amp INL", "LOUT2",
+ "Speaker Amp INR", "ROUT2",
+
+ /* single ended signal to LINPUT1 */
+ "LINPUT1", "Microphone Jack",
+ "RINPUT1", "Microphone Jack",
+ /* differential signal */
+ "LINPUT2", "Onboard Microphone",
+ "RINPUT2", "Onboard Microphone";
+
+ daicpu: simple-audio-card,cpu {
+ sound-dai = <&i2s0_8ch>;
+ system-clock-frequency = <12288000>;
+ };
+
+ daicodec: simple-audio-card,codec {
+ sound-dai = <&es8388>;
+ system-clock-frequency = <12288000>;
+ };
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie_eth: vcc3v3-pcie-eth-regulator {
+ compatible = "regulator-fixed";
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ regulator-name = "vcc3v3_pcie_eth";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_wf: vcc3v3-wf-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_wf";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc5v0_usb20: vcc5v0-usb20-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc5v0_usb20_en>;
+ regulator-name = "vcc5v0_usb20";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ wakeup-source;
+ };
+};
+
+&i2c7 {
+ status = "okay";
+
+ /* PLDO2 vcca 1.8V, BUCK8 gated by PLDO2 being enabled */
+ es8388: audio-codec@11 {
+ compatible = "everest,es8388";
+ reg = <0x11>;
+ clocks = <&cru I2S0_8CH_MCLKOUT>;
+ clock-names = "mclk";
+ AVDD-supply = <&vcc_1v8_s0>;
+ DVDD-supply = <&vcc_1v8_s0>;
+ HPVDD-supply = <&vcc_3v3_s0>;
+ PVDD-supply = <&vcc_3v3_s0>;
+ assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
+ assigned-clock-rates = <12288000>;
+ #sound-dai-cells = <0>;
+ };
+};
+
+&i2s0_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_lrck
+ &i2s0_mclk
+ &i2s0_sclk
+ &i2s0_sdi0
+ &i2s0_sdo0>;
+ status = "okay";
+};
+
+&i2s2_2ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2m0_lrck
+ &i2s2m0_sclk
+ &i2s2m0_sdi
+ &i2s2m0_sdo>;
+ status = "okay";
+};
+
+/* phy1 - M.KEY socket */
+&pcie2x1l0 {
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_wf>;
+ status = "okay";
+};
+
+/* phy2 - right ethernet port */
+&pcie2x1l1 {
+ reset-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie_eth>;
+ status = "okay";
+};
+
+/* phy0 - left ethernet port */
+&pcie2x1l2 {
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie_eth>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
+&pinctrl {
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ blue_led_pin: blue-led {
+ rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ ir-receiver {
+ ir_receiver_pin: ir-receiver-pin {
+ rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ hp_detect: hp-detect {
+ rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb {
+ vcc5v0_usb20_en: vcc5v0-usb20-en {
+ rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm2 {
+ pinctrl-0 = <&pwm2m1_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pwm3 {
+ pinctrl-0 = <&pwm3m1_pins>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ no-sdio;
+ no-sd;
+ non-removable;
+ max-frequency = <200000000>;
+ mmc-hs400-1_8v;
+ mmc-hs400-enhanced-strobe;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-sdio;
+ no-mmc;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_s3>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim1_pins>;
+ status = "okay";
+
+ spi_flash: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <100000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+ status = "okay";
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vdd2_ddr_s3>;
+ vcc14-supply = <&vdd2_ddr_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: dcdc-reg1 {
+ regulator-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-enable-ramp-delay = <400>;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <825000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <825000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ /* shorted to avcc_1v8_s0 on the board */
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ /*
+ * The schematic mentions that actual setting
+ * should be 0.8375V. RK3588 datasheet specifies
+ * maximum as 0.825V. So we set datasheet max
+ * here.
+ */
+ regulator-min-microvolt = <825000>;
+ regulator-max-microvolt = <825000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ phy-supply = <&vcc5v0_usb20>;
+ status = "okay";
+};
+
+&u2phy3_host {
+ phy-supply = <&vcc5v0_usb20>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&uart9 {
+ pinctrl-0 = <&uart9m0_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi
index 96cc84e5aa..b595ddef70 100644
--- a/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi
+++ b/arch/arm/dts/rk3588-rock-5b-u-boot.dtsi
@@ -4,9 +4,6 @@
*/
#include "rk3588-u-boot.dtsi"
-#include <dt-bindings/pinctrl/rockchip.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/usb/pd.h>
/ {
@@ -22,54 +19,9 @@
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
};
-
- vcc3v3_pcie30: vcc3v3-pcie30-regulator {
- compatible = "regulator-fixed";
- regulator-name = "vcc3v3_pcie30";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- enable-active-high;
- gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
- startup-delay-us = <5000>;
- vin-supply = <&vcc5v0_sys>;
- pinctrl-names = "default";
- pinctrl-0 = <&pcie3_vcc3v3_en>;
- };
-
- vcc5v0_usbdcin: vcc5v0-usbdcin {
- compatible = "regulator-fixed";
- regulator-name = "vcc5v0_usbdcin";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- vin-supply = <&vcc12v_dcin>;
- };
-
- vcc5v0_usb: vcc5v0-usb {
- compatible = "regulator-fixed";
- regulator-name = "vcc5v0_usb";
- regulator-always-on;
- regulator-boot-on;
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- vin-supply = <&vcc5v0_usbdcin>;
- };
-
- vbus5v0_typec: vbus5v0-typec {
- compatible = "regulator-fixed";
- regulator-name = "vbus5v0_typec";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- enable-active-high;
- gpio = <&gpio2 RK_PB6 GPIO_ACTIVE_HIGH>;
- vin-supply = <&vcc5v0_usb>;
- pinctrl-names = "default";
- pinctrl-0 = <&typec5v_pwren>;
- };
};
-&combphy0_ps {
+&combphy2_psu {
status = "okay";
};
@@ -77,52 +29,10 @@
bootph-all;
};
-&pcie2x1l2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pcie2x1l2_pins &pcie_reset_h>;
- reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
- status = "okay";
-};
-
-&pcie30phy {
- status = "okay";
-};
-
-&pcie3x4 {
- reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
- vpcie3v3-supply = <&vcc3v3_pcie30>;
- pinctrl-names = "default";
- pinctrl-0 = <&pcie3_rst>;
- status = "okay";
-};
-
&pinctrl {
- pcie {
- pcie_reset_h: pcie-reset-h {
- rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
- };
-
- pcie2x1l2_pins: pcie2x1l2-pins {
- rockchip,pins = <3 RK_PC7 4 &pcfg_pull_none>,
- <3 RK_PD0 4 &pcfg_pull_none>;
- };
-
- pcie3_rst: pcie3-rst {
- rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
- };
-
- pcie3_vcc3v3_en: pcie3-vcc3v3-en {
- rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
- };
- };
-
- usb-typec {
+ usb {
usbc0_int: usbc0-int {
- rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>;
- };
-
- typec5v_pwren: typec5v-pwren {
- rockchip,pins = <2 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ rockchip,pins = <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
@@ -138,8 +48,6 @@
u-boot,spl-sfc-no-dma;
pinctrl-names = "default";
pinctrl-0 = <&fspim2_pins>;
- #address-cells = <1>;
- #size-cells = <0>;
status = "okay";
flash@0 {
@@ -157,7 +65,6 @@
};
&u2phy0_otg {
- rockchip,typec-vbus-det;
status = "okay";
};
@@ -169,25 +76,17 @@
status = "okay";
};
-&usb2phy2_grf {
+&usbdp_phy1 {
status = "okay";
};
-&usb2phy3_grf {
+&usbdp_phy1_u3 {
status = "okay";
};
-&usb_host0_ehci {
- companion = <&usb_host0_ohci>;
-};
-
-&usb_host1_ehci {
- companion = <&usb_host1_ohci>;
-};
-
&usbdp_phy0 {
orientation-switch;
- svid = <0xff01>;
+ mode-switch;
sbu1-dc-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>;
sbu2-dc-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
status = "okay";
@@ -195,14 +94,15 @@
port {
#address-cells = <1>;
#size-cells = <0>;
- usbdp_phy0_orientation_switch: endpoint@0 {
+
+ usbdp_phy0_typec_ss: endpoint@0 {
reg = <0>;
- remote-endpoint = <&usbc0_orien_sw>;
+ remote-endpoint = <&usbc0_ss>;
};
- usbdp_phy0_dp_altmode_mux: endpoint@1 {
+ usbdp_phy0_typec_sbu: endpoint@1 {
reg = <1>;
- remote-endpoint = <&dp_altmode_mux>;
+ remote-endpoint = <&usbc0_sbu>;
};
};
};
@@ -211,84 +111,53 @@
status = "okay";
};
-&usbdp_phy1 {
- rockchip,dp-lane-mux = <2 3>;
+&usb_host0_xhci {
+ usb-role-switch;
status = "okay";
-};
-&usbdp_phy1_u3 {
- status = "okay";
-};
+ port {
+ #address-cells = <1>;
+ #size-cells = <0>;
-&usbdrd3_0 {
- status = "okay";
+ usb_host0_xhci_drd_sw: endpoint {
+ remote-endpoint = <&usbc0_hs>;
+ };
+ };
};
-&usbdrd3_1 {
+&usb_host1_xhci {
status = "okay";
};
-&usbdrd_dwc3_0 {
- usb-role-switch;
-
- port {
- #address-cells = <1>;
- #size-cells = <0>;
- dwc3_0_role_switch: endpoint@0 {
- reg = <0>;
- remote-endpoint = <&usbc0_role_sw>;
- };
- };
+&usb_host2_xhci {
+ status = "okay";
};
&i2c4 {
+ pinctrl-names = "default";
pinctrl-0 = <&i2c4m1_xfer>;
status = "okay";
- usbc0: fusb302@22 {
+ usbc0: usb-typec@22 {
compatible = "fcs,fusb302";
reg = <0x22>;
interrupt-parent = <&gpio3>;
interrupts = <RK_PB4 IRQ_TYPE_LEVEL_LOW>;
pinctrl-names = "default";
pinctrl-0 = <&usbc0_int>;
- vbus-supply = <&vbus5v0_typec>;
+ vbus-supply = <&vcc12v_dcin>;
status = "okay";
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
- usbc0_role_sw: endpoint@0 {
- remote-endpoint = <&dwc3_0_role_switch>;
- };
- };
- };
-
usb_con: connector {
compatible = "usb-c-connector";
label = "USB-C";
data-role = "dual";
- power-role = "dual";
+ power-role = "sink";
try-power-role = "sink";
op-sink-microwatt = <1000000>;
sink-pdos =
- <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>;
- source-pdos =
- <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
-
- altmodes {
- #address-cells = <1>;
- #size-cells = <0>;
-
- altmode@0 {
- reg = <0>;
- svid = <0xff01>;
- vdo = <0xffffffff>;
- };
- };
+ <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>,
+ <PDO_VAR(5000, 20000, 5000)>;
ports {
#address-cells = <1>;
@@ -296,15 +165,22 @@
port@0 {
reg = <0>;
- usbc0_orien_sw: endpoint {
- remote-endpoint = <&usbdp_phy0_orientation_switch>;
+ usbc0_hs: endpoint {
+ remote-endpoint = <&usb_host0_xhci_drd_sw>;
};
};
port@1 {
reg = <1>;
- dp_altmode_mux: endpoint {
- remote-endpoint = <&usbdp_phy0_dp_altmode_mux>;
+ usbc0_ss: endpoint {
+ remote-endpoint = <&usbdp_phy0_typec_ss>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ usbc0_sbu: endpoint {
+ remote-endpoint = <&usbdp_phy0_typec_sbu>;
};
};
};
diff --git a/arch/arm/dts/rk3588-rock-5b.dts b/arch/arm/dts/rk3588-rock-5b.dts
index 8ab60968f2..741f631db3 100644
--- a/arch/arm/dts/rk3588-rock-5b.dts
+++ b/arch/arm/dts/rk3588-rock-5b.dts
@@ -3,6 +3,7 @@
/dts-v1/;
#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
#include "rk3588.dtsi"
/ {
@@ -12,6 +13,7 @@
aliases {
mmc0 = &sdhci;
mmc1 = &sdmmc;
+ mmc2 = &sdio;
serial2 = &uart2;
};
@@ -36,6 +38,19 @@
pinctrl-0 = <&hp_detect>;
};
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_rgb_b>;
+
+ led_rgb_b {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_BLUE>;
+ gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
fan: pwm-fan {
compatible = "pwm-fan";
cooling-levels = <0 95 145 195 255>;
@@ -44,6 +59,43 @@
#cooling-cells = <2>;
};
+ vcc3v3_pcie2x1l0: vcc3v3-pcie2x1l0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie2x1l0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc3v3_pcie2x1l2: vcc3v3-pcie2x1l2-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_pcie2x1l2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_pcie30: vcc3v3-pcie30-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_vcc3v3_en>;
+ regulator-name = "vcc3v3_pcie30";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <5000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc5v0_host";
@@ -78,6 +130,14 @@
};
};
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy1_ps {
+ status = "okay";
+};
+
&cpu_b0 {
cpu-supply = <&vdd_cpu_big0_s0>;
};
@@ -204,6 +264,34 @@
};
};
+&pcie2x1l0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_0_rst>;
+ reset-gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l0>;
+ status = "okay";
+};
+
+&pcie2x1l2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie2_2_rst>;
+ reset-gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie2x1l2>;
+ status = "okay";
+};
+
+&pcie30phy {
+ status = "okay";
+};
+
+&pcie3x4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pcie3_rst>;
+ reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie30>;
+ status = "okay";
+};
+
&pinctrl {
hym8563 {
hym8563_int: hym8563-int {
@@ -211,12 +299,42 @@
};
};
+ leds {
+ led_rgb_b: led-rgb-b {
+ rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
sound {
hp_detect: hp-detect {
rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+ pcie2 {
+ pcie2_0_rst: pcie2-0-rst {
+ rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_0_vcc3v3_en: pcie2-0-vcc-en {
+ rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie2_2_rst: pcie2-2-rst {
+ rockchip,pins = <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pcie3 {
+ pcie3_rst: pcie3-rst {
+ rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ pcie3_vcc3v3_en: pcie3-vcc3v3-en {
+ rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
usb {
vcc5v0_host_en: vcc5v0-host-en {
rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -258,6 +376,33 @@
status = "okay";
};
+&sdio {
+ max-frequency = <200000000>;
+ no-sd;
+ no-mmc;
+ non-removable;
+ bus-width = <4>;
+ cap-sdio-irq;
+ disable-wp;
+ keep-power-in-suspend;
+ wakeup-source;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_pcie2x1l0>;
+ vqmmc-supply = <&vcc_1v8_s3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdiom0_pins>;
+ status = "okay";
+};
+
+&uart6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart6m1_xfer &uart6m1_ctsn &uart6m1_rtsn>;
+ status = "okay";
+};
+
&spi2 {
status = "okay";
assigned-clocks = <&cru CLK_SPI2>;
diff --git a/arch/arm/dts/rk3588-u-boot.dtsi b/arch/arm/dts/rk3588-u-boot.dtsi
index 68b419f3ab..31046fc7fe 100644
--- a/arch/arm/dts/rk3588-u-boot.dtsi
+++ b/arch/arm/dts/rk3588-u-boot.dtsi
@@ -3,36 +3,27 @@
* Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
*/
-#include "rockchip-u-boot.dtsi"
#include "rk3588s-u-boot.dtsi"
/ {
- usbdrd3_1: usbdrd3_1 {
- compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
+ usb_host1_xhci: usb@fc400000 {
+ compatible = "rockchip,rk3588-dwc3", "rockchip,rk3568-dwc3", "snps,dwc3";
+ reg = <0x0 0xfc400000 0x0 0x400000>;
+ interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru REF_CLK_USB3OTG1>, <&cru SUSPEND_CLK_USB3OTG1>,
<&cru ACLK_USB3OTG1>;
- clock-names = "ref", "suspend", "bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ clock-names = "ref_clk", "suspend_clk", "bus_clk";
+ dr_mode = "host";
+ phys = <&u2phy1_otg>, <&usbdp_phy1_u3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ phy_type = "utmi_wide";
+ power-domains = <&power RK3588_PD_USB>;
+ resets = <&cru SRST_A_USB3OTG1>;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
status = "disabled";
-
- usbdrd_dwc3_1: usb@fc400000 {
- compatible = "snps,dwc3";
- reg = <0x0 0xfc400000 0x0 0x400000>;
- interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH 0>;
- power-domains = <&power RK3588_PD_USB>;
- resets = <&cru SRST_A_USB3OTG1>;
- reset-names = "usb3-otg";
- dr_mode = "host";
- phys = <&u2phy1_otg>, <&usbdp_phy1_u3>;
- phy-names = "usb2-phy", "usb3-phy";
- phy_type = "utmi_wide";
- snps,dis_enblslpm_quirk;
- snps,dis-u2-freeclk-exists-quirk;
- snps,dis-del-phy-power-chg-quirk;
- snps,dis-tx-ipgap-linecheck-quirk;
- };
};
usbdpphy1_grf: syscon@fd5cc000 {
@@ -57,7 +48,6 @@
clock-names = "phyclk";
clock-output-names = "usb480m_phy1";
#clock-cells = <0>;
- rockchip,usbctrl-grf = <&usb_grf>;
status = "disabled";
u2phy1_otg: otg-port {
diff --git a/arch/arm/dts/rk3588s-orangepi-5-u-boot.dtsi b/arch/arm/dts/rk3588s-orangepi-5-u-boot.dtsi
new file mode 100644
index 0000000000..888d1b9c12
--- /dev/null
+++ b/arch/arm/dts/rk3588s-orangepi-5-u-boot.dtsi
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include "rk3588s-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdmmc;
+ };
+};
+
+&fspim0_pins {
+ bootph-all;
+};
+
+&sfc {
+ bootph-pre-ram;
+ u-boot,spl-sfc-no-dma;
+
+ flash@0 {
+ bootph-pre-ram;
+ };
+};
diff --git a/arch/arm/dts/rk3588s-orangepi-5.dts b/arch/arm/dts/rk3588s-orangepi-5.dts
new file mode 100644
index 0000000000..8f399c4317
--- /dev/null
+++ b/arch/arm/dts/rk3588s-orangepi-5.dts
@@ -0,0 +1,662 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3588s.dtsi"
+
+/ {
+ model = "Xunlong Orange Pi 5";
+ compatible = "xunlong,orangepi-5", "rockchip,rk3588s";
+
+ aliases {
+ mmc0 = &sdmmc;
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <100>;
+
+ button-recovery {
+ label = "Recovery";
+ linux,code = <KEY_VENDOR>;
+ press-threshold-microvolt = <1800>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 =<&leds_gpio>;
+
+ led-1 {
+ gpios = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;
+ label = "status_led";
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ vbus_typec: vbus-typec-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&typec5v_pwren>;
+ regulator-name = "vbus_typec";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
+ compatible = "regulator-fixed";
+ enable-active-low;
+ gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>;
+ regulator-name = "vcc_3v3_sd_s0";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_3v3_s3>;
+ };
+
+ vcc3v3_pcie20: vcc3v3-pcie20-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ regulator-name = "vcc3v3_pcie20";
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ startup-delay-us = <50000>;
+ vin-supply = <&vcc5v0_sys>;
+ };
+};
+
+&combphy0_ps {
+ status = "okay";
+};
+
+&combphy2_psu {
+ status = "okay";
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_big0_s0>;
+};
+
+&cpu_b2 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_b3 {
+ cpu-supply = <&vdd_cpu_big1_s0>;
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_lit_s0>;
+};
+
+&gmac1 {
+ clock_in_out = "output";
+ phy-handle = <&rgmii_phy1>;
+ phy-mode = "rgmii-rxid";
+ pinctrl-0 = <&gmac1_miim
+ &gmac1_tx_bus2
+ &gmac1_rx_bus2
+ &gmac1_rgmii_clk
+ &gmac1_rgmii_bus>;
+ pinctrl-names = "default";
+ tx_delay = <0x42>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0m2_xfer>;
+ status = "okay";
+
+ vdd_cpu_big0_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big0_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_big1_s0: regulator@43 {
+ compatible = "rockchip,rk8603", "rockchip,rk8602";
+ reg = <0x43>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_big1_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c2 {
+ status = "okay";
+
+ vdd_npu_s0: regulator@42 {
+ compatible = "rockchip,rk8602";
+ reg = <0x42>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_npu_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc5v0_sys>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c6 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c6m3_xfer>;
+ status = "okay";
+
+ hym8563: rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ clock-output-names = "hym8563";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hym8563_int>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>;
+ wakeup-source;
+ };
+};
+
+&mdio1 {
+ rgmii_phy1: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0x1>;
+ reset-assert-us = <20000>;
+ reset-deassert-us = <100000>;
+ reset-gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&pcie2x1l2 {
+ reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>;
+ vpcie3v3-supply = <&vcc3v3_pcie20>;
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-func {
+ leds_gpio: leds-gpio {
+ rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ hym8563 {
+ hym8563_int: hym8563-int {
+ rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ usb-typec {
+ usbc0_int: usbc0-int {
+ rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ typec5v_pwren: typec5v-pwren {
+ rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&avcc_1v8_s0>;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ disable-wp;
+ max-frequency = <150000000>;
+ no-mmc;
+ no-sdio;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3_sd_s0>;
+ vqmmc-supply = <&vccio_sd_s0>;
+ status = "okay";
+};
+
+&sfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fspim0_pins>;
+ status = "okay";
+
+ flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0x0>;
+ spi-max-frequency = <100000000>;
+ spi-rx-bus-width = <4>;
+ spi-tx-bus-width = <1>;
+ };
+};
+
+&spi2 {
+ status = "okay";
+ assigned-clocks = <&cru CLK_SPI2>;
+ assigned-clock-rates = <200000000>;
+ num-cs = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>;
+
+ pmic@0 {
+ compatible = "rockchip,rk806";
+ reg = <0x0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
+ <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+ spi-max-frequency = <1000000>;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc5v0_sys>;
+ vcc6-supply = <&vcc5v0_sys>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc5v0_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+ vcc10-supply = <&vcc5v0_sys>;
+ vcc11-supply = <&vcc_2v0_pldo_s3>;
+ vcc12-supply = <&vcc5v0_sys>;
+ vcc13-supply = <&vcc_1v1_nldo_s3>;
+ vcc14-supply = <&vcc_1v1_nldo_s3>;
+ vcca-supply = <&vcc5v0_sys>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ rk806_dvs1_null: dvs1-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs2_null: dvs2-null-pins {
+ pins = "gpio_pwrctrl2";
+ function = "pin_fun0";
+ };
+
+ rk806_dvs3_null: dvs3-null-pins {
+ pins = "gpio_pwrctrl3";
+ function = "pin_fun0";
+ };
+
+ regulators {
+ vdd_gpu_s0: dcdc-reg1 {
+ regulator-name = "vdd_gpu_s0";
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <400>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_cpu_lit_s0: dcdc-reg2 {
+ regulator-name = "vdd_cpu_lit_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_log_s0: dcdc-reg3 {
+ regulator-name = "vdd_log_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <750000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_vdenc_s0: dcdc-reg4 {
+ regulator-name = "vdd_vdenc_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_ddr_s0: dcdc-reg5 {
+ regulator-name = "vdd_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <675000>;
+ regulator-max-microvolt = <900000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ vcc_1v1_nldo_s3: vdd2_ddr_s3: dcdc-reg6 {
+ regulator-name = "vdd2_ddr_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-max-microvolt = <1100000>;
+ regulator-min-microvolt = <1100000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_2v0_pldo_s3: dcdc-reg7 {
+ regulator-name = "vdd_2v0_pldo_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2000000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2000000>;
+ };
+ };
+
+ vcc_3v3_s3: dcdc-reg8 {
+ regulator-name = "vcc_3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vddq_ddr_s0: dcdc-reg9 {
+ regulator-name = "vddq_ddr_s0";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s3: dcdc-reg10 {
+ regulator-name = "vcc_1v8_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avcc_1v8_s0: pldo-reg1 {
+ regulator-name = "avcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_1v8_s0: pldo-reg2 {
+ regulator-name = "vcc_1v8_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ avdd_1v2_s0: pldo-reg3 {
+ regulator-name = "avdd_1v2_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_3v3_s0: pldo-reg4 {
+ regulator-name = "vcc_3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd_s0: pldo-reg5 {
+ regulator-name = "vccio_sd_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ pldo6_s3: pldo-reg6 {
+ regulator-name = "pldo6_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdd_0v75_s3: nldo-reg1 {
+ regulator-name = "vdd_0v75_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <750000>;
+ };
+ };
+
+ vdd_ddr_pll_s0: nldo-reg2 {
+ regulator-name = "vdd_ddr_pll_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <850000>;
+ };
+ };
+
+ avdd_0v75_s0: nldo-reg3 {
+ regulator-name = "avdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v85_s0: nldo-reg4 {
+ regulator-name = "vdd_0v85_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <850000>;
+ regulator-max-microvolt = <850000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_0v75_s0: nldo-reg5 {
+ regulator-name = "vdd_0v75_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <750000>;
+ regulator-max-microvolt = <750000>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy2 {
+ status = "okay";
+};
+
+&u2phy2_host {
+ status = "okay";
+};
+
+&u2phy3 {
+ status = "okay";
+};
+
+&u2phy3_host {
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-0 = <&uart2m0_xfer>;
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3588s-pinctrl.dtsi b/arch/arm/dts/rk3588s-pinctrl.dtsi
index 48181671ea..63151d9d23 100644
--- a/arch/arm/dts/rk3588s-pinctrl.dtsi
+++ b/arch/arm/dts/rk3588s-pinctrl.dtsi
@@ -1350,6 +1350,41 @@
i2s2 {
/omit-if-no-ref/
+ i2s2m0_lrck: i2s2m0-lrck {
+ rockchip,pins =
+ /* i2s2m0_lrck */
+ <2 RK_PC0 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_mclk: i2s2m0-mclk {
+ rockchip,pins =
+ /* i2s2m0_mclk */
+ <2 RK_PB6 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_sclk: i2s2m0-sclk {
+ rockchip,pins =
+ /* i2s2m0_sclk */
+ <2 RK_PB7 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_sdi: i2s2m0-sdi {
+ rockchip,pins =
+ /* i2s2m0_sdi */
+ <2 RK_PC3 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
+ i2s2m0_sdo: i2s2m0-sdo {
+ rockchip,pins =
+ /* i2s2m0_sdo */
+ <4 RK_PC3 2 &pcfg_pull_none>;
+ };
+
+ /omit-if-no-ref/
i2s2m1_lrck: i2s2m1-lrck {
rockchip,pins =
/* i2s2m1_lrck */
@@ -3308,6 +3343,15 @@
uart9 {
/omit-if-no-ref/
+ uart9m0_xfer: uart9m0-xfer {
+ rockchip,pins =
+ /* uart9_rx_m0 */
+ <2 RK_PC4 10 &pcfg_pull_up>,
+ /* uart9_tx_m0 */
+ <2 RK_PC2 10 &pcfg_pull_up>;
+ };
+
+ /omit-if-no-ref/
uart9m1_xfer: uart9m1-xfer {
rockchip,pins =
/* uart9_rx_m1 */
diff --git a/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi b/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi
index c47b0a7112..584476f77b 100644
--- a/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi
+++ b/arch/arm/dts/rk3588s-rock-5a-u-boot.dtsi
@@ -4,10 +4,6 @@
*/
#include "rk3588s-u-boot.dtsi"
-#include <dt-bindings/pinctrl/rockchip.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/usb/pd.h>
/ {
chosen {
diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi
index 27b2d7eff8..c0fd16c402 100644
--- a/arch/arm/dts/rk3588s-u-boot.dtsi
+++ b/arch/arm/dts/rk3588s-u-boot.dtsi
@@ -4,7 +4,6 @@
*/
#include "rockchip-u-boot.dtsi"
-#include <dt-bindings/phy/phy.h>
/ {
aliases {
@@ -22,35 +21,47 @@
status = "okay";
};
- usbdrd3_0: usbdrd3_0 {
- compatible = "rockchip,rk3588-dwc3", "rockchip,rk3399-dwc3";
+ usb_host0_xhci: usb@fc000000 {
+ compatible = "rockchip,rk3588-dwc3", "rockchip,rk3568-dwc3", "snps,dwc3";
+ reg = <0x0 0xfc000000 0x0 0x400000>;
+ interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
clocks = <&cru REF_CLK_USB3OTG0>, <&cru SUSPEND_CLK_USB3OTG0>,
<&cru ACLK_USB3OTG0>;
- clock-names = "ref", "suspend", "bus";
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
+ clock-names = "ref_clk", "suspend_clk", "bus_clk";
+ dr_mode = "otg";
+ phys = <&u2phy0_otg>, <&usbdp_phy0_u3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ phy_type = "utmi_wide";
+ power-domains = <&power RK3588_PD_USB>;
+ resets = <&cru SRST_A_USB3OTG0>;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u1-entry-quirk;
+ snps,dis-u2-entry-quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
status = "disabled";
+ };
- usbdrd_dwc3_0: usb@fc000000 {
- compatible = "snps,dwc3";
- reg = <0x0 0xfc000000 0x0 0x400000>;
- interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH 0>;
- power-domains = <&power RK3588_PD_USB>;
- resets = <&cru SRST_A_USB3OTG0>;
- reset-names = "usb3-otg";
- dr_mode = "otg";
- phys = <&u2phy0_otg>, <&usbdp_phy0_u3>;
- phy-names = "usb2-phy", "usb3-phy";
- phy_type = "utmi_wide";
- snps,dis_enblslpm_quirk;
- snps,dis-u1-entry-quirk;
- snps,dis-u2-entry-quirk;
- snps,dis-u2-freeclk-exists-quirk;
- snps,dis-del-phy-power-chg-quirk;
- snps,dis-tx-ipgap-linecheck-quirk;
- quirk-skip-phy-init;
- };
+ usb_host2_xhci: usb@fcd00000 {
+ compatible = "rockchip,rk3588-dwc3", "rockchip,rk3568-dwc3", "snps,dwc3";
+ reg = <0x0 0xfcd00000 0x0 0x400000>;
+ interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru REF_CLK_USB3OTG2>, <&cru SUSPEND_CLK_USB3OTG2>,
+ <&cru ACLK_USB3OTG2>, <&cru CLK_UTMI_OTG2>,
+ <&cru CLK_PIPEPHY2_PIPE_U3_G>;
+ clock-names = "ref_clk", "suspend_clk", "bus_clk", "utmi", "pipe";
+ dr_mode = "host";
+ phys = <&combphy2_psu PHY_TYPE_USB3>;
+ phy-names = "usb3-phy";
+ phy_type = "utmi_wide";
+ resets = <&cru SRST_A_USB3OTG2>;
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ snps,dis_rxdet_inp3_quirk;
+ status = "disabled";
};
pmu1_grf: syscon@fd58a000 {
@@ -59,6 +70,11 @@
reg = <0x0 0xfd58a000 0x0 0x2000>;
};
+ usbdpphy0_grf: syscon@fd5c8000 {
+ compatible = "rockchip,rk3588-usbdpphy-grf", "syscon";
+ reg = <0x0 0xfd5c8000 0x0 0x4000>;
+ };
+
usb2phy0_grf: syscon@fd5d0000 {
compatible = "rockchip,rk3588-usb2phy-grf", "syscon",
"simple-mfd";
@@ -76,7 +92,6 @@
clock-names = "phyclk";
clock-output-names = "usb480m_phy0";
#clock-cells = <0>;
- rockchip,usbctrl-grf = <&usb_grf>;
status = "disabled";
u2phy0_otg: otg-port {
@@ -102,15 +117,6 @@
reg = <0x0 0xfd5c8000 0x0 0x4000>;
};
- sfc: spi@fe2b0000 {
- compatible = "rockchip,sfc";
- reg = <0x0 0xfe2b0000 0x0 0x4000>;
- interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
- clock-names = "clk_sfc", "hclk_sfc";
- status = "disabled";
- };
-
rng: rng@fe378000 {
compatible = "rockchip,trngv1";
reg = <0x0 0xfe378000 0x0 0x200>;
diff --git a/arch/arm/dts/rk3588s.dtsi b/arch/arm/dts/rk3588s.dtsi
index 5544f66c6f..61a9a11c3b 100644
--- a/arch/arm/dts/rk3588s.dtsi
+++ b/arch/arm/dts/rk3588s.dtsi
@@ -1424,6 +1424,17 @@
};
};
+ sfc: spi@fe2b0000 {
+ compatible = "rockchip,sfc";
+ reg = <0x0 0xfe2b0000 0x0 0x4000>;
+ interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH 0>;
+ clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>;
+ clock-names = "clk_sfc", "hclk_sfc";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
sdmmc: mmc@fe2c0000 {
compatible = "rockchip,rk3588-dw-mshc", "rockchip,rk3288-dw-mshc";
reg = <0x0 0xfe2c0000 0x0 0x4000>;
@@ -2304,6 +2315,19 @@
#interrupt-cells = <2>;
};
};
+
+ av1d: video-codec@fdc70000 {
+ compatible = "rockchip,rk3588-av1-vpu";
+ reg = <0x0 0xfdc70000 0x0 0x800>;
+ interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH 0>;
+ interrupt-names = "vdpu";
+ assigned-clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+ assigned-clock-rates = <400000000>, <400000000>;
+ clocks = <&cru ACLK_AV1>, <&cru PCLK_AV1>;
+ clock-names = "aclk", "hclk";
+ power-domains = <&power RK3588_PD_AV1>;
+ resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
+ };
};
#include "rk3588s-pinctrl.dtsi"
diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig
index 79fcc99b89..1ff6b7d2cd 100644
--- a/arch/arm/mach-rockchip/rk3588/Kconfig
+++ b/arch/arm/mach-rockchip/rk3588/Kconfig
@@ -6,6 +6,51 @@ config TARGET_EVB_RK3588
help
RK3588 EVB is a evaluation board for Rockchp RK3588.
+config TARGET_NANOPCT6_RK3588
+ bool "FriendlyElec NanoPC-T6 RK3588 board"
+ select BOARD_LATE_INIT
+ help
+ The NanoPC-T6 is a Rockchip RK3588 based SBC by FriendlyElec.
+
+ There are four variants depending on the DRAM size: 4G/32GB eMMC,
+ 8G/64GB eMMC, 16G/16MB SPI NOR, and 16G/256GB eMMC/16MB SPI NOR
+
+ Specifications:
+
+ CPU: Rockchip RK3588, 4x Cortex-A76 (up to 2.4GHz)
+ + 4x Cortex-A55 (up to 1.8GHz)
+ GPU: Mali-G610 MP4
+ VPU: 8K@60fps H.265 and VP9 decoder, 8K@30fps H.264 decoder,
+ 4K@60fps AV1 decoder, 8K@30fps H.264 and H.265 encoder
+ NPU: 6TOPs, supports INT4/INT8/INT16/FP16
+ RAM: 64-bit 4GB/8GB/16GB LPDDR4X at 2133MHz
+ eMMC: 0GB/32GB/64GB/256GB HS400
+ MicroSD Slot: MicroSD SDR104
+ PCIe 3.0: M.2 M-Key x1, PCIe 3.0 x4 for NVMe SSDs up to 2,500 MB/s
+ Ethernet: PCIe 2.5G 2x Ethernet (RTL8125BG)
+ PCIe 2.1: M.2 E-Key x1, PCIe 2.1 x1 and USB2.0 Host,
+ supports M.2 WiFi and Bluetooth
+ 4G Module: MiniPCIe x1, MicroSIM Card Slot x1
+ Audio Out: 3.5mm jack for stereo headphone output
+ Audio In: 2.0mm PH-2A connector for analog microphone input
+ Video Input: standard HDMI input port, up to 4Kp60
+ 2x 4-lane MIPI-CSI, compatible with MIPI V1.2
+ Video Output: 2x standard HDMI output ports compatible with HDMI2.1,
+ HDMI2.0, and HDMI1.4
+ 2x 4-lane MIPI-DSI, compatible with MIPI DPHY 2.0 or CPHY 1.1
+ USB-A: USB 3.0, Type A
+ USB-C: Full function USB Type‑C port, DP display up to 4Kp60, USB 3.0
+ 40-pin 2.54mm header connector: up to 2x SPIs, 6x UARTs, 1x I2Cs,
+ 8x PWMs, 2x I2Ss, 28x GPIOs
+ Debug UART: 3 Pin 2.54mm header, 3V level, 1500000bps
+ Onboard IR receiver: 38KHz carrier frequency
+ RTC Battery: 2 Pin 1.27/1.25mm RTC battery connector for low power
+ RTC IC HYM8563TS
+ 5V Fan connector
+ Working Temperature: 0C to 70C
+ Power: 5.5*2.1mm DC Jack, 12VDC input
+ Dimensions: 110x80x1.6mm (without case) / 86x114.5x30mm (with case)
+
config TARGET_RK3588_NEU6
bool "Edgeble Neural Compute Module 6(Neu6) SoM"
select BOARD_LATE_INIT
@@ -93,6 +138,7 @@ config SYS_MALLOC_F_LEN
default 0x80000
source board/edgeble/neural-compute-module-6/Kconfig
+source board/friendlyelec/nanopc-t6-rk3588/Kconfig
source board/rockchip/evb_rk3588/Kconfig
source board/radxa/rock5a-rk3588s/Kconfig
source board/radxa/rock5b-rk3588/Kconfig
diff --git a/board/friendlyelec/nanopc-t6-rk3588/Kconfig b/board/friendlyelec/nanopc-t6-rk3588/Kconfig
new file mode 100644
index 0000000000..032ef48610
--- /dev/null
+++ b/board/friendlyelec/nanopc-t6-rk3588/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_NANOPCT6_RK3588
+
+config SYS_BOARD
+ default "nanopc-t6-rk3588"
+
+config SYS_VENDOR
+ default "friendlyelec"
+
+config SYS_CONFIG_NAME
+ default "nanopc-t6-rk3588"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+
+endif
diff --git a/board/friendlyelec/nanopc-t6-rk3588/MAINTAINERS b/board/friendlyelec/nanopc-t6-rk3588/MAINTAINERS
new file mode 100644
index 0000000000..63ff6fafc8
--- /dev/null
+++ b/board/friendlyelec/nanopc-t6-rk3588/MAINTAINERS
@@ -0,0 +1,9 @@
+NANOPCT6-RK3588
+M: John Clark <inindev@gmail.com>
+R: Jonas Karlman <jonas@kwiboo.se>
+S: Maintained
+F: board/friendlyelec/nanopc-t6-rk3588
+F: include/configs/nanopc-t6-rk3588.h
+F: configs/nanopc-t6-rk3588_defconfig
+F: arch/arm/dts/rk3588-nanopc-t6.dts
+F: arch/arm/dts/rk3588-nanopc-t6-u-boot.dtsi
diff --git a/board/friendlyelec/nanopc-t6-rk3588/Makefile b/board/friendlyelec/nanopc-t6-rk3588/Makefile
new file mode 100644
index 0000000000..c1c49b1970
--- /dev/null
+++ b/board/friendlyelec/nanopc-t6-rk3588/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2023 Rockchip Electronics Co,. Ltd.
+#
+
+obj-y += nanopc-t6-rk3588.o
diff --git a/board/friendlyelec/nanopc-t6-rk3588/nanopc-t6-rk3588.c b/board/friendlyelec/nanopc-t6-rk3588/nanopc-t6-rk3588.c
new file mode 100644
index 0000000000..99bbef964e
--- /dev/null
+++ b/board/friendlyelec/nanopc-t6-rk3588/nanopc-t6-rk3588.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co,. Ltd.
+ */
+
+#include <fdtdec.h>
+#include <fdt_support.h>
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int nanopc_t6_add_reserved_memory_fdt_nodes(void *new_blob)
+{
+ struct fdt_memory gap1 = {
+ .start = 0x3fc000000,
+ .end = 0x3fc4fffff,
+ };
+ struct fdt_memory gap2 = {
+ .start = 0x3fff00000,
+ .end = 0x3ffffffff,
+ };
+ unsigned long flags = FDTDEC_RESERVED_MEMORY_NO_MAP;
+ unsigned int ret;
+
+ /*
+ * Inject the reserved-memory nodes into the DTS
+ */
+ ret = fdtdec_add_reserved_memory(new_blob, "gap1", &gap1, NULL, 0,
+ NULL, flags);
+ if (ret)
+ return ret;
+
+ return fdtdec_add_reserved_memory(new_blob, "gap2", &gap2, NULL, 0,
+ NULL, flags);
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+ return nanopc_t6_add_reserved_memory_fdt_nodes(blob);
+}
+#endif
diff --git a/board/rockchip/evb_rk3588/MAINTAINERS b/board/rockchip/evb_rk3588/MAINTAINERS
index 6b2c257a17..2bd44bc587 100644
--- a/board/rockchip/evb_rk3588/MAINTAINERS
+++ b/board/rockchip/evb_rk3588/MAINTAINERS
@@ -6,3 +6,17 @@ F: include/configs/evb_rk3588.h
F: configs/evb-rk3588_defconfig
F: arch/arm/dts/rk3588-evb1-v10.dts
F: arch/arm/dts/rk3588-evb1-v10-u-boot.dtsi
+
+ORANGEPI-5-RK3588
+M: Jonas Karlman <jonas@kwiboo.se>
+S: Maintained
+F: configs/orangepi-5-rk3588s_defconfig
+F: arch/arm/dts/rk3588s-orangepi-5.dts
+F: arch/arm/dts/rk3588s-orangepi-5-u-boot.dtsi
+
+ORANGEPI-5-PLUS-RK3588
+M: Jonas Karlman <jonas@kwiboo.se>
+S: Maintained
+F: configs/orangepi-5-plus-rk3588_defconfig
+F: arch/arm/dts/rk3588-orangepi-5-plus.dts
+F: arch/arm/dts/rk3588-orangepi-5-plus-u-boot.dtsi
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 5bc0a92d57..205df2f1fb 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1568,6 +1568,14 @@ config CMD_USB_SDP
Enables the command "sdp" which is used to have U-Boot emulating the
Serial Download Protocol (SDP) via USB.
+config CMD_RKMTD
+ bool "rkmtd"
+ select RKMTD
+ help
+ Enable the command "rkmtd" to create a virtual block device to transfer
+ Rockchip boot block data to and from NAND with block orientated tools
+ like "ums" and "rockusb".
+
config CMD_ROCKUSB
bool "rockusb"
depends on USB_FUNCTION_ROCKUSB
diff --git a/cmd/Makefile b/cmd/Makefile
index 44db5f2286..9a6790cc17 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -151,6 +151,7 @@ obj-$(CONFIG_CMD_REISER) += reiser.o
obj-$(CONFIG_CMD_REMOTEPROC) += remoteproc.o
obj-$(CONFIG_CMD_RNG) += rng.o
obj-$(CONFIG_CMD_KASLRSEED) += kaslrseed.o
+obj-$(CONFIG_CMD_RKMTD) += rkmtd.o
obj-$(CONFIG_CMD_ROCKUSB) += rockusb.o
obj-$(CONFIG_CMD_RTC) += rtc.o
obj-$(CONFIG_SANDBOX) += host.o
diff --git a/cmd/rkmtd.c b/cmd/rkmtd.c
new file mode 100644
index 0000000000..5b80427cb9
--- /dev/null
+++ b/cmd/rkmtd.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *
+ * Driver interface derived from:
+ * /cmd/host.c
+ * Copyright (c) 2012, Google Inc.
+ *
+ * Copyright (C) 2023 Johan Jonker <jbx6244@gmail.com>
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <command.h>
+#include <dm.h>
+#include <rkmtd.h>
+#include <stdio.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
+
+static int do_rkmtd_bind(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ const char *label;
+ int ret;
+
+ argc--;
+ argv++;
+
+ if (argc < 1)
+ return CMD_RET_USAGE;
+
+ if (argc > 1)
+ return CMD_RET_USAGE;
+
+ label = argv[0];
+ ret = rkmtd_create_attach_mtd(label, &dev);
+ if (ret) {
+ printf("Cannot create device / bind mtd\n");
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
+static struct udevice *parse_rkmtd_label(const char *label)
+{
+ struct udevice *dev;
+
+ dev = rkmtd_find_by_label(label);
+ if (!dev) {
+ int devnum;
+ char *ep;
+
+ devnum = hextoul(label, &ep);
+ if (*ep ||
+ uclass_find_device_by_seq(UCLASS_RKMTD, devnum, &dev)) {
+ printf("No such device '%s'\n", label);
+ return NULL;
+ }
+ }
+
+ return dev;
+}
+
+static int do_rkmtd_unbind(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ const char *label;
+ int ret;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ label = argv[1];
+ dev = parse_rkmtd_label(label);
+ if (!dev)
+ return CMD_RET_FAILURE;
+
+ ret = rkmtd_detach(dev);
+ if (ret) {
+ printf("Cannot detach mtd\n");
+ return CMD_RET_FAILURE;
+ }
+
+ ret = device_unbind(dev);
+ if (ret) {
+ printf("Cannot unbind device '%s'\n", dev->name);
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
+static void show_rkmtd_dev(struct udevice *dev)
+{
+ struct rkmtd_dev *plat = dev_get_plat(dev);
+ struct blk_desc *desc;
+ struct udevice *blk;
+ int ret;
+
+ printf("%3d ", dev_seq(dev));
+
+ ret = blk_get_from_parent(dev, &blk);
+ if (ret)
+ return;
+
+ desc = dev_get_uclass_plat(blk);
+ printf("%12lu %-15s\n", (unsigned long)desc->lba, plat->label);
+}
+
+static int do_rkmtd_info(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+
+ if (argc < 1)
+ return CMD_RET_USAGE;
+
+ dev = NULL;
+ if (argc >= 2) {
+ dev = parse_rkmtd_label(argv[1]);
+ if (!dev)
+ return CMD_RET_FAILURE;
+ }
+
+ printf("%3s %12s %-15s\n", "dev", "blocks", "label");
+ if (dev) {
+ show_rkmtd_dev(dev);
+ } else {
+ struct uclass *uc;
+
+ uclass_id_foreach_dev(UCLASS_RKMTD, dev, uc)
+ show_rkmtd_dev(dev);
+ }
+
+ return 0;
+}
+
+static int do_rkmtd_dev(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct udevice *dev;
+ const char *label;
+
+ if (argc < 1 || argc > 3)
+ return CMD_RET_USAGE;
+
+ if (argc == 1) {
+ struct rkmtd_dev *plat;
+
+ dev = rkmtd_get_cur_dev();
+ if (!dev) {
+ printf("No current rkmtd device\n");
+ return CMD_RET_FAILURE;
+ }
+ plat = dev_get_plat(dev);
+ printf("Current rkmtd device: %d: %s\n", dev_seq(dev),
+ plat->label);
+ return 0;
+ }
+
+ label = argv[1];
+ dev = parse_rkmtd_label(argv[1]);
+ if (!dev)
+ return CMD_RET_FAILURE;
+
+ rkmtd_set_cur_dev(dev);
+
+ return 0;
+}
+
+static struct cmd_tbl cmd_rkmtd_sub[] = {
+ U_BOOT_CMD_MKENT(bind, 4, 0, do_rkmtd_bind, "", ""),
+ U_BOOT_CMD_MKENT(unbind, 4, 0, do_rkmtd_unbind, "", ""),
+ U_BOOT_CMD_MKENT(info, 3, 0, do_rkmtd_info, "", ""),
+ U_BOOT_CMD_MKENT(dev, 0, 1, do_rkmtd_dev, "", ""),
+};
+
+static int do_rkmtd(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct cmd_tbl *c;
+
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], cmd_rkmtd_sub, ARRAY_SIZE(cmd_rkmtd_sub));
+
+ if (c)
+ return c->cmd(cmdtp, flag, argc, argv);
+ else
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ rkmtd, 8, 1, do_rkmtd,
+ "Rockchip MTD sub-system",
+ "bind <label> - bind RKMTD device\n"
+ "rkmtd unbind <label> - unbind RKMTD device\n"
+ "rkmtd info [<label>] - show all available RKMTD devices\n"
+ "rkmtd dev [<label>] - show or set current RKMTD device\n"
+);
diff --git a/configs/nanopc-t6-rk3588_defconfig b/configs/nanopc-t6-rk3588_defconfig
new file mode 100644
index 0000000000..070399ce2a
--- /dev/null
+++ b/configs/nanopc-t6-rk3588_defconfig
@@ -0,0 +1,108 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_SF_DEFAULT_SPEED=24000000
+CONFIG_SF_DEFAULT_MODE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588-nanopc-t6"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_NANOPCT6_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_PCI=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-nanopc-t6.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_SF_DEFAULT_BUS=5
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_PHYLIB=y
+CONFIG_RTL8169=y
+CONFIG_NVME_PCI=y
+CONFIG_PCIE_DW_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_ROCKCHIP_SFC=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_ASIX88179=y
+CONFIG_USB_ETHER_MCS7830=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_ETHER_SMSC95XX=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/orangepi-5-plus-rk3588_defconfig b/configs/orangepi-5-plus-rk3588_defconfig
new file mode 100644
index 0000000000..0473699621
--- /dev/null
+++ b/configs/orangepi-5-plus-rk3588_defconfig
@@ -0,0 +1,105 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_SYS_HAS_NONCACHED_MEMORY=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_SF_DEFAULT_SPEED=24000000
+CONFIG_SF_DEFAULT_MODE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588-orangepi-5-plus"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_PCI=y
+CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-orangepi-5-plus.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_AHCI_PCI=y
+CONFIG_DWC_AHCI=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_SF_DEFAULT_BUS=5
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_PHYLIB=y
+CONFIG_RTL8169=y
+CONFIG_NVME_PCI=y
+CONFIG_PCIE_DW_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_ROCKCHIP_SFC=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/orangepi-5-rk3588s_defconfig b/configs/orangepi-5-rk3588s_defconfig
new file mode 100644
index 0000000000..feb45a5385
--- /dev/null
+++ b/configs/orangepi-5-rk3588s_defconfig
@@ -0,0 +1,102 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00a00000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
+CONFIG_SF_DEFAULT_SPEED=24000000
+CONFIG_SF_DEFAULT_MODE=0x2000
+CONFIG_DEFAULT_DEVICE_TREE="rk3588s-orangepi-5"
+CONFIG_ROCKCHIP_RK3588=y
+CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_TARGET_EVB_RK3588=y
+CONFIG_SPL_STACK=0x400000
+CONFIG_DEBUG_UART_BASE=0xFEB50000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+CONFIG_SYS_LOAD_ADDR=0xc00800
+CONFIG_PCI=y
+CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_FIT_SIGNATURE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588s-orangepi-5.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000
+CONFIG_SPL_ATF=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+# CONFIG_SPL_DOS_PARTITION is not set
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SPL_SYSCON=y
+CONFIG_AHCI_PCI=y
+CONFIG_DWC_AHCI=y
+CONFIG_SPL_CLK=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_SF_DEFAULT_BUS=5
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_PHY_MOTORCOMM=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
+CONFIG_NVME_PCI=y
+CONFIG_PCIE_DW_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SPL_RAM=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_ROCKCHIP_SFC=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/radxa-e25-rk3568_defconfig b/configs/radxa-e25-rk3568_defconfig
index a905100a79..2dfff6af3b 100644
--- a/configs/radxa-e25-rk3568_defconfig
+++ b/configs/radxa-e25-rk3568_defconfig
@@ -54,7 +54,6 @@ CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigne
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_REGMAP=y
CONFIG_SPL_SYSCON=y
-CONFIG_AHCI_PCI=y
CONFIG_DWC_AHCI=y
CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
diff --git a/configs/rock5a-rk3588s_defconfig b/configs/rock5a-rk3588s_defconfig
index bccdb1e3ec..a6471a5195 100644
--- a/configs/rock5a-rk3588s_defconfig
+++ b/configs/rock5a-rk3588s_defconfig
@@ -39,13 +39,16 @@ CONFIG_SPL_STACK_R=y
CONFIG_SPL_ATF=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_REGULATOR=y
# CONFIG_SPL_DOS_PARTITION is not set
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_LIVE=y
CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_REGMAP=y
CONFIG_SPL_SYSCON=y
CONFIG_SPL_CLK=y
@@ -61,12 +64,23 @@ CONFIG_MMC_SDHCI_ROCKCHIP=y
CONFIG_PHY_REALTEK=y
CONFIG_DWC_ETH_QOS=y
CONFIG_DWC_ETH_QOS_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
+CONFIG_PHY_ROCKCHIP_USBDP=y
CONFIG_SPL_PINCTRL=y
-CONFIG_REGULATOR_PWM=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_SPL_RAM=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
CONFIG_ERRNO_STR=y
diff --git a/configs/rock5b-rk3588_defconfig b/configs/rock5b-rk3588_defconfig
index 447913facc..0595325e81 100644
--- a/configs/rock5b-rk3588_defconfig
+++ b/configs/rock5b-rk3588_defconfig
@@ -26,6 +26,7 @@ CONFIG_SPL_SPI=y
CONFIG_SYS_LOAD_ADDR=0xc00800
CONFIG_PCI=y
CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_FIT_SIGNATURE=y
@@ -35,7 +36,6 @@ CONFIG_OF_BOARD_SETUP=y
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3588-rock-5b.dtb"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_PCI_INIT_R=y
CONFIG_SPL_MAX_SIZE=0x40000
CONFIG_SPL_PAD_TO=0x7f8000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
@@ -63,6 +63,8 @@ CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigne
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_REGMAP=y
CONFIG_SPL_SYSCON=y
+CONFIG_AHCI_PCI=y
+CONFIG_DWC_AHCI=y
CONFIG_SPL_CLK=y
# CONFIG_USB_FUNCTION_FASTBOOT is not set
CONFIG_ROCKCHIP_GPIO=y
@@ -89,6 +91,8 @@ CONFIG_SPL_PINCTRL=y
CONFIG_REGULATOR_PWM=y
CONFIG_PWM_ROCKCHIP=y
CONFIG_SPL_RAM=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
@@ -97,7 +101,6 @@ CONFIG_SYSRESET=y
CONFIG_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
-# CONFIG_USB_XHCI_DWC3_OF_SIMPLE is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 1a033b2201..1a01f51a0b 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -58,6 +58,7 @@ CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_TEMPERATURE=y
CONFIG_CMD_USB=y
+CONFIG_CMD_RKMTD=y
CONFIG_CMD_WDT=y
CONFIG_CMD_WRITE=y
CONFIG_CMD_CAT=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 47417cb039..03475a5a29 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -84,6 +84,7 @@ CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_TEMPERATURE=y
CONFIG_CMD_USB=y
+CONFIG_CMD_RKMTD=y
CONFIG_CMD_WDT=y
CONFIG_CMD_WRITE=y
CONFIG_CMD_AXI=y
diff --git a/disk/part.c b/disk/part.c
index 85244b09f3..36b88205ec 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -197,6 +197,7 @@ void dev_print(struct blk_desc *desc)
case UCLASS_PVBLOCK:
case UCLASS_HOST:
case UCLASS_BLKMAP:
+ case UCLASS_RKMTD:
printf ("Vendor: %s Rev: %s Prod: %s\n",
desc->vendor,
desc->revision,
@@ -330,6 +331,9 @@ static void print_part_header(const char *type, struct blk_desc *desc)
case UCLASS_PVBLOCK:
puts("PV BLOCK");
break;
+ case UCLASS_RKMTD:
+ puts("RKMTD");
+ break;
case UCLASS_VIRTIO:
puts("VirtIO");
break;
diff --git a/doc/board/rockchip/index.rst b/doc/board/rockchip/index.rst
index 0c377e9bbb..9a87a035e9 100644
--- a/doc/board/rockchip/index.rst
+++ b/doc/board/rockchip/index.rst
@@ -8,3 +8,4 @@ Rockchip
:maxdepth: 2
rockchip
+ rkmtd
diff --git a/doc/board/rockchip/rkmtd.rst b/doc/board/rockchip/rkmtd.rst
new file mode 100644
index 0000000000..1481380ba6
--- /dev/null
+++ b/doc/board/rockchip/rkmtd.rst
@@ -0,0 +1,105 @@
+.. SPDX-License-Identifier: GPL-2.0+
+.. Copyright (C) 2023 Johan Jonker <jbx6244@gmail.com>
+
+RKMTD
+=====
+
+Info
+----
+
+The command rkmtd creates a virtual block device to transfer
+Rockchip boot block data to and from NAND with block orientated
+tools like "ums" and "rockusb".
+
+It uses the Rockchip MTD driver to scan for boot blocks and copies
+data from the first block in a GPT formatted virtual disk.
+Data must be written in U-boot "idbloader.img" format and start at
+partition "loader1" offset 64. The data header is parsed
+for length and offset. When the last sector is received
+it erases up to 5 erase blocks on NAND and writes boot blocks
+in a pattern depending on the NAND ID. Data is then verified.
+When a block turns out bad the block header is discarded.
+
+Limitations
+-----------
+
+- Support with CONFIG_ROCKCHIP_NAND MTD driver only.
+- Support for Rockchip boot block header type 1 only.
+- Pattern for listed NAND IDs only. (Logic still not disclosed by Rockchip)
+- The MTD framework driver data and NAND ID must be extracted at a lower level.
+
+Available rkmtd commands
+------------------------
+
+.. code-block:: bash
+
+ rkmtd bind <label> - bind RKMTD device
+ rkmtd unbind <label> - unbind RKMTD device
+ rkmtd info [<label>] - show all available RKMTD devices
+ rkmtd dev [<label>] - show or set current RKMTD device
+
+U-boot settings
+---------------
+
+Config to enable Rockchip MTD support:
+
+.. code-block:: bash
+
+ CONFIG_MTD=y
+ CONFIG_MTD_RAW_NAND=y
+ CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT=y
+ CONFIG_SYS_NAND_USE_FLASH_BBT=y
+ CONFIG_ROCKCHIP_NAND=y
+
+Option to keep existing NAND data unchanged:
+
+.. code-block:: bash
+
+ CONFIG_ROCKCHIP_NAND_SKIP_BBTSCAN=y
+
+Commands to enable:
+
+.. code-block:: bash
+
+ CONFIG_CMD_USB=y
+ CONFIG_CMD_RKMTD=y
+ CONFIG_CMD_ROCKUSB=y
+ CONFIG_CMD_USB_MASS_STORAGE=y
+
+Linux Host (PC) tool commands combinations that work
+----------------------------------------------------
+
+.. table::
+ :widths: 20 44
+
+ ==================== ============================================
+ U-boot Linux
+ ==================== ============================================
+ rkmtd bind 0
+ rockusb 0 rkmtd 0
+ upgrade_tool pl
+
+ upgrade_tool rl 64 512 idbloader_backup.img
+
+ upgrade_tool wl 64 idbloader.img
+
+ upgrade_tool rd
+
+ rkdeveloptool ppt
+
+ rkdeveloptool rl 64 512 idbloader_backup.img
+
+ rkdeveloptool wlx loader1 idbloader.img
+
+ rkdeveloptool wl 64 idbloader.img
+
+ rkdeveloptool rd
+
+ rkflashtool r 64 512 > idbloader_backup.img
+
+ rkflashtool w 64 512 < idbloader.img
+ ums 0 rkmtd 0
+ dd if=/dev/sda1 of=idbloader_backup.img
+
+ dd if=idbloader.img of=/dev/sda1
+ ==================== ============================================
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index 8262fc0d32..ffbebd0bb3 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -115,8 +115,11 @@ List of mainline supported Rockchip boards:
- Rockchip EVB (evb-rk3588)
- Edgeble Neural Compute Module 6A SoM - Neu6a (neu6a-io-rk3588)
- Edgeble Neural Compute Module 6B SoM - Neu6b (neu6b-io-rk3588)
+ - FriendlyElec NanoPC-T6 (nanopc-t6-rk3588)
- Radxa ROCK 5A (rock5a-rk3588s)
- Radxa ROCK 5B (rock5b-rk3588)
+ - Xunlong Orange Pi 5 (orangepi-5-rk3588s)
+ - Xunlong Orange Pi 5 Plus (orangepi-5-plus-rk3588)
* rv1108
- Rockchip Evb-rv1108 (evb-rv1108)
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index 1abea3f10d..048a6caef0 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -262,3 +262,10 @@ config SYS_64BIT_LBA
help
Make the block subsystem use 64bit sector addresses, rather than the
default of 32bit.
+
+config RKMTD
+ bool "Rockchip rkmtd virtual block device"
+ help
+ Enable "rkmtd" class and driver to create a virtual block device
+ to transfer Rockchip boot block data to and from NAND with block
+ orientate tools like "ums" and "rockusb".
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index a161d145fd..fdcba5c831 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -11,6 +11,7 @@ endif
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_IDE) += ide.o
+obj-$(CONFIG_RKMTD) += rkmtd.o
endif
obj-$(CONFIG_SANDBOX) += sandbox.o host-uclass.o host_dev.o
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
@@ -19,3 +20,4 @@ obj-$(CONFIG_BLKMAP) += blkmap.o
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o
+
diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c
index f126547cc7..77066da352 100644
--- a/drivers/block/blk-uclass.c
+++ b/drivers/block/blk-uclass.c
@@ -36,6 +36,7 @@ static struct {
{ UCLASS_VIRTIO, "virtio" },
{ UCLASS_PVBLOCK, "pvblock" },
{ UCLASS_BLKMAP, "blkmap" },
+ { UCLASS_RKMTD, "rkmtd" },
};
static enum uclass_id uclass_name_to_iftype(const char *uclass_idname)
@@ -440,7 +441,7 @@ long blk_read(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *buf)
start, blkcnt, desc->blksz, buf))
return blkcnt;
- if (IS_ENABLED(CONFIG_BOUNCE_BUFFER)) {
+ if (IS_ENABLED(CONFIG_BOUNCE_BUFFER) && desc->bb) {
struct blk_bounce_buffer bbstate = { .dev = dev };
int ret;
@@ -477,7 +478,7 @@ long blk_write(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
blkcache_invalidate(desc->uclass_id, desc->devnum);
- if (IS_ENABLED(CONFIG_BOUNCE_BUFFER)) {
+ if (IS_ENABLED(CONFIG_BOUNCE_BUFFER) && desc->bb) {
struct blk_bounce_buffer bbstate = { .dev = dev };
int ret;
diff --git a/drivers/block/rkmtd.c b/drivers/block/rkmtd.c
new file mode 100644
index 0000000000..c55f052e51
--- /dev/null
+++ b/drivers/block/rkmtd.c
@@ -0,0 +1,1152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Some functions are derived from:
+ * https://github.com/rockchip-linux/u-boot/blob/next-dev/drivers/rknand/rk_ftl_arm_v7.S
+ * Copyright (c) 2016-2018, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Driver interface derived from:
+ * /drivers/block/host_dev.c
+ * /drivers/block/host-uclass.c
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * Copyright (C) 2023 Johan Jonker <jbx6244@gmail.com>
+ */
+
+#include <blk.h>
+#include <dm.h>
+#include <nand.h>
+#include <part.h>
+#include <rkmtd.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dm/device-internal.h>
+#include <dm/devres.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+#include <linux/mtd/mtd.h>
+#if !IS_ENABLED(CONFIG_SANDBOX)
+#include <linux/mtd/rawnand.h>
+#endif
+#include <u-boot/crc.h>
+
+struct nand_para_info nand_para_tbl[] = {
+ {6, {0x2c, 0x64, 0x44, 0x4b, 0xa9, 0x00}, 4, 1, 16, 256, 2, 2, 2048, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x44, 0x44, 0x4b, 0xa9, 0x00}, 4, 1, 16, 256, 2, 2, 1064, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x68, 0x04, 0x4a, 0xa9, 0x00}, 4, 1, 8, 256, 2, 2, 2048, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x88, 0x04, 0x4b, 0xa9, 0x00}, 4, 1, 16, 256, 2, 2, 2048, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0xa8, 0x05, 0xcb, 0xa9, 0x00}, 4, 2, 16, 256, 2, 2, 2048, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x68, 0x04, 0x46, 0x89, 0x00}, 4, 1, 8, 256, 2, 2, 2048, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x48, 0x04, 0x4a, 0xa5, 0x00}, 4, 1, 8, 256, 2, 2, 1024, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x84, 0x64, 0x3c, 0xa5, 0x00}, 4, 1, 32, 512, 2, 2, 1024, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0x64, 0x54, 0xa9, 0x00}, 4, 1, 32, 512, 2, 2, 1024, 0x01df, 4, 18, 60, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0xd7, 0x94, 0x3e, 0x84, 0x00}, 4, 1, 8, 128, 2, 2, 4096, 0x0117, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x48, 0x04, 0x46, 0x85, 0x00}, 4, 1, 8, 256, 2, 2, 1024, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x88, 0x05, 0xc6, 0x89, 0x00}, 4, 2, 8, 256, 2, 2, 2048, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x88, 0x24, 0x4b, 0xa9, 0x00}, 4, 1, 16, 256, 2, 2, 2048, 0x011f, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x68, 0x00, 0x27, 0xa9, 0x00}, 4, 1, 16, 128, 1, 2, 2048, 0x011f, 0, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x64, 0x64, 0x56, 0xa5, 0x00}, 4, 1, 24, 512, 2, 2, 700, 0x01df, 4, 18, 60, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0x84, 0xc5, 0x4b, 0xa9, 0x00}, 4, 2, 16, 256, 2, 2, 2048, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0xd5, 0xd1, 0xa6, 0x68, 0x00}, 4, 2, 8, 64, 1, 2, 2048, 0x0117, 0, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0xdc, 0x90, 0xa6, 0x54, 0x00}, 4, 1, 8, 64, 1, 2, 1024, 0x0117, 0, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x64, 0x64, 0x54, 0xa4, 0x00}, 4, 1, 32, 512, 2, 1, 1024, 0x01df, 4, 18, 60, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0x44, 0x32, 0xaa, 0x00}, 4, 1, 32, 512, 2, 1, 2184, 0x05c7, 5, 19, 60, 32, 1, 0, 1, 0, 1, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x64, 0x44, 0x32, 0xa5, 0x00}, 4, 1, 32, 512, 2, 1, 1048, 0x05c7, 5, 19, 60, 32, 1, 0, 1, 0, 1, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x64, 0x64, 0x3c, 0xa5, 0x00}, 4, 1, 32, 512, 2, 1, 1044, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0x44, 0x32, 0xaa, 0x00}, 4, 1, 32, 512, 2, 1, 2184, 0x05c7, 5, 19, 60, 32, 1, 0, 4, 0, 1, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0x44, 0x34, 0xaa, 0x00}, 4, 1, 32, 512, 2, 1, 2184, 0x05c7, 5, 19, 60, 32, 1, 0, 4, 0, 1, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0xc4, 0x34, 0xaa, 0x00}, 4, 1, 32, 512, 2, 1, 2184, 0x05c7, 5, 19, 60, 32, 1, 0, 1, 0, 1, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0x44, 0x34, 0xa4, 0x00}, 4, 1, 32, 512, 2, 1, 2184, 0x05c7, 5, 19, 60, 32, 1, 0, 1, 0, 1, {0, 0, 0, 0, 0}},
+ {5, {0x2c, 0x84, 0x64, 0x3c, 0xa9, 0x00}, 4, 1, 32, 512, 2, 2, 1024, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x2c, 0xa4, 0x64, 0x32, 0xaa, 0x04}, 4, 1, 32, 1024, 2, 1, 2192, 0x05c7, 10, 19, 60, 32, 1, 0, 4, 0, 1, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xde, 0x94, 0xd2, 0x04, 0x43}, 2, 1, 16, 256, 2, 2, 2048, 0x01d9, 1, 1, 24, 32, 4, 0, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xd7, 0x94, 0xda, 0x74, 0xc3}, 2, 1, 16, 256, 2, 2, 1024, 0x01d9, 1, 2, 40, 32, 4, 0, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xd7, 0x94, 0x91, 0x60, 0x44}, 2, 1, 16, 256, 2, 2, 1046, 0x01d9, 1, 3, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xde, 0x94, 0xda, 0x74, 0xc4}, 2, 1, 16, 256, 2, 2, 2090, 0x01d9, 1, 4, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xde, 0x94, 0xeb, 0x74, 0x44}, 2, 1, 32, 256, 2, 2, 1066, 0x01d9, 1, 7, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xd5, 0x94, 0xda, 0x74, 0xc4}, 2, 1, 16, 256, 2, 2, 530, 0x01d9, 1, 3, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xd7, 0x94, 0x9a, 0x74, 0x42}, 2, 1, 16, 256, 2, 2, 1024, 0x0119, 1, 0, 24, 32, 4, 0, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xde, 0x14, 0xa7, 0x42, 0x4a}, 2, 1, 32, 256, 2, 2, 1060, 0x01d9, 2, 5, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xd7, 0x14, 0x9e, 0x34, 0x4a}, 2, 1, 16, 256, 2, 2, 1056, 0x01d9, 2, 5, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xde, 0x94, 0xa7, 0x42, 0x48}, 2, 1, 32, 256, 2, 2, 1060, 0x01d9, 2, 5, 40, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xde, 0x14, 0xab, 0x42, 0x4a}, 2, 1, 32, 256, 2, 2, 1056, 0x01d9, 2, 6, 40, 32, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0x3a, 0x14, 0xab, 0x42, 0x4a}, 2, 1, 32, 256, 2, 2, 2092, 0x01d9, 2, 5, 40, 32, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0xd5, 0x94, 0x9a, 0x74, 0x42}, 2, 1, 16, 256, 2, 1, 1024, 0x0111, 1, 0, 24, 32, 4, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xad, 0x3a, 0x14, 0x03, 0x08, 0x50}, 2, 1, 32, 388, 2, 2, 1362, 0x01d9, 9, 8, 40, 32, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x64, 0x44, 0x4b, 0xa9, 0x00}, 7, 1, 16, 256, 2, 2, 2048, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x88, 0x24, 0x4b, 0xa9, 0x84}, 7, 1, 16, 256, 2, 2, 2048, 0x01df, 3, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x88, 0x24, 0x4b, 0xa9, 0x00}, 7, 1, 16, 256, 2, 2, 2048, 0x0117, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x68, 0x24, 0x4a, 0xa9, 0x00}, 7, 1, 8, 256, 2, 2, 2048, 0x0117, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x68, 0x04, 0x4a, 0xa9, 0x00}, 7, 1, 8, 256, 2, 2, 2048, 0x0117, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0xd7, 0x94, 0x3e, 0x84, 0x00}, 7, 1, 8, 256, 2, 2, 2048, 0x0117, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x68, 0x04, 0x46, 0xa9, 0x00}, 7, 1, 8, 256, 2, 2, 2048, 0x0117, 1, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x89, 0x64, 0x64, 0x3c, 0xa1, 0x00}, 7, 1, 32, 512, 2, 1, 1024, 0x01c7, 4, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {5, {0x89, 0x84, 0x64, 0x3c, 0xa5, 0x00}, 7, 1, 32, 512, 2, 2, 1024, 0x01c7, 4, 17, 40, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x89, 0x88, 0x24, 0x3b, 0xa9, 0x00}, 7, 1, 16, 192, 2, 2, 2048, 0x0117, 12, 0, 24, 32, 1, 0, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xd7, 0x84, 0x93, 0x72, 0x57}, 1, 1, 32, 256, 2, 1, 1060, 0x05c1, 2, 33, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xde, 0x84, 0x93, 0x72, 0x57}, 1, 1, 32, 256, 2, 1, 2092, 0x05c1, 2, 33, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0x3a, 0x85, 0x93, 0x76, 0x57}, 1, 2, 32, 256, 2, 1, 2092, 0x05e1, 2, 33, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xd5, 0x84, 0x32, 0x72, 0x56}, 1, 1, 16, 128, 2, 1, 2056, 0x05c1, 2, 33, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xd7, 0x94, 0x32, 0x76, 0x56}, 1, 1, 16, 128, 2, 2, 2058, 0x05d1, 2, 33, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xde, 0x94, 0x82, 0x76, 0x56}, 1, 1, 16, 256, 2, 2, 2062, 0x05d1, 1, 33, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xde, 0x94, 0x93, 0x76, 0x50}, 1, 1, 32, 256, 2, 2, 1066, 0x05d9, 2, 34, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0x3a, 0x95, 0x93, 0x7a, 0x50}, 1, 2, 32, 256, 2, 2, 1066, 0x05d9, 2, 34, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xd7, 0x94, 0x32, 0x76, 0x55}, 1, 1, 16, 128, 2, 2, 2050, 0x0191, 2, 0, 24, 32, 1, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xde, 0x94, 0x93, 0x76, 0x57}, 1, 1, 32, 256, 2, 2, 1058, 0x05d9, 2, 33, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xd7, 0x84, 0x93, 0x72, 0x50}, 1, 1, 32, 256, 2, 1, 1060, 0x05c1, 2, 34, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xde, 0x94, 0x93, 0x76, 0x51}, 1, 1, 32, 256, 2, 2, 1074, 0x05d9, 2, 35, 40, 32, 3, 1, 4, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0x3a, 0x94, 0x93, 0x76, 0x51}, 1, 1, 32, 256, 2, 2, 2106, 0x05d9, 2, 35, 40, 32, 3, 1, 4, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xd7, 0x84, 0x93, 0x72, 0x51}, 1, 1, 32, 256, 2, 1, 1056, 0x05d9, 2, 35, 40, 32, 3, 1, 4, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x98, 0xde, 0x94, 0x93, 0x76, 0xd1}, 1, 1, 32, 256, 2, 2, 1074, 0x05d9, 2, 35, 40, 32, 3, 1, 4, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0x94, 0x93, 0x76, 0x57}, 8, 1, 32, 256, 2, 2, 1058, 0x05d9, 2, 66, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xd7, 0x84, 0x93, 0x72, 0x57}, 8, 1, 32, 256, 2, 1, 1060, 0x05c1, 2, 66, 40, 32, 2, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0xa4, 0x82, 0x76, 0x56}, 8, 1, 16, 256, 2, 2, 2082, 0x01d9, 1, 65, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0x94, 0x93, 0x76, 0x50}, 8, 1, 32, 256, 2, 2, 1066, 0x05d9, 2, 67, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xd7, 0x84, 0x93, 0x72, 0x50}, 8, 1, 32, 256, 2, 1, 1060, 0x05c1, 2, 67, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0xa4, 0x82, 0x76, 0xd7}, 8, 1, 16, 256, 2, 2, 2090, 0x04d9, 1, 66, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0x84, 0x93, 0x72, 0x57}, 8, 1, 32, 256, 2, 1, 2092, 0x05c1, 2, 66, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0x3a, 0x94, 0x93, 0x76, 0x51}, 8, 1, 32, 256, 2, 2, 2106, 0x01d9, 2, 68, 40, 32, 3, 1, 4, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0x94, 0x93, 0x76, 0x51}, 8, 1, 32, 256, 2, 2, 1074, 0x01d9, 2, 68, 40, 32, 3, 1, 4, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0x3a, 0xa4, 0x93, 0x7a, 0x50}, 8, 1, 32, 256, 2, 2, 2138, 0x05d9, 2, 0, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0x94, 0x82, 0x76, 0x56}, 8, 1, 16, 256, 2, 2, 2062, 0x01d9, 1, 0, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0x45, 0xde, 0x94, 0x93, 0x76, 0xd7}, 8, 1, 32, 256, 2, 2, 1058, 0x05d9, 2, 66, 40, 32, 3, 1, 1, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xd7, 0x94, 0x7e, 0x64, 0x44}, 0, 1, 16, 128, 2, 2, 2048, 0x01d9, 2, 49, 60, 36, 3, 0, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xde, 0xd5, 0x7e, 0x68, 0x44}, 0, 2, 16, 128, 2, 2, 2048, 0x01f9, 2, 49, 60, 36, 3, 0, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xd7, 0x94, 0x7a, 0x54, 0x43}, 0, 1, 16, 128, 2, 2, 2076, 0x0199, 2, 0, 40, 36, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xde, 0xd5, 0x7a, 0x58, 0x43}, 0, 2, 16, 128, 2, 2, 2076, 0x01b9, 2, 0, 40, 36, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xd5, 0x94, 0x76, 0x54, 0x43}, 0, 1, 16, 128, 2, 2, 1038, 0x0119, 2, 0, 24, 36, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xd7, 0x14, 0x76, 0x54, 0xc2}, 0, 1, 16, 128, 2, 2, 2076, 0x0491, 2, 0, 24, 40, 3, 1, 3, 0, 0, {0, 0, 0, 0, 0}},
+ {6, {0xec, 0xde, 0x94, 0xc3, 0xa4, 0xca}, 0, 1, 32, 792, 2, 1, 688, 0x04c1, 11, 50, 40, 32, 3, 1, 1, 0, 1, {0, 0, 0, 0, 0}},
+};
+
+#if !IS_ENABLED(CONFIG_SANDBOX)
+static int rkmtd_write_oob(struct rkmtd_dev *plat, ulong off, u_char *datbuf, u_char *oobbuf)
+{
+ struct mtd_info *mtd = plat->mtd;
+ struct mtd_oob_ops ops;
+ loff_t addr;
+ int ret;
+
+ off &= ~(mtd->writesize - 1);
+ addr = (loff_t)off;
+
+ memset(&ops, 0, sizeof(ops));
+ ops.datbuf = datbuf;
+ ops.oobbuf = oobbuf;
+ ops.len = mtd->writesize;
+ ops.ooblen = mtd->oobsize;
+ ops.mode = MTD_OPS_PLACE_OOB;
+ ret = mtd_write_oob(mtd, addr, &ops);
+ if (ret < 0) {
+ debug("Error (%d) writing page %08lx\n", ret, off);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int rkmtd_read_oob(struct rkmtd_dev *plat, ulong off, u_char *datbuf, u_char *oobbuf)
+{
+ struct mtd_info *mtd = plat->mtd;
+ struct mtd_oob_ops ops;
+ loff_t addr;
+ int ret;
+
+ off &= ~(mtd->writesize - 1);
+ addr = (loff_t)off;
+
+ memset(&ops, 0, sizeof(ops));
+ ops.datbuf = datbuf;
+ ops.oobbuf = oobbuf;
+ ops.len = mtd->writesize;
+ ops.ooblen = mtd->oobsize;
+ ops.mode = MTD_OPS_PLACE_OOB;
+ ret = mtd_read_oob(mtd, addr, &ops);
+ if (ret < 0) {
+ debug("Error (%d) reading page %08lx\n", ret, off);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int rkmtd_erase(struct rkmtd_dev *plat, ulong off)
+{
+ struct mtd_info *mtd = plat->mtd;
+ struct erase_info info;
+ loff_t addr;
+ int ret;
+
+ off &= ~(mtd->writesize - 1);
+ addr = (loff_t)off;
+
+ memset(&info, 0, sizeof(info));
+ info.mtd = mtd;
+ info.addr = addr;
+ info.len = mtd->erasesize;
+ info.scrub = 1;
+ ret = mtd_erase(mtd, &info);
+ if (ret) {
+ debug("Error (%d) erasing page %08lx\n", ret, off);
+ return 1;
+ }
+
+ return 0;
+}
+#endif
+void rkmtd_scan_block(struct rkmtd_dev *plat)
+{
+ plat->blk_counter = 0;
+
+#if !IS_ENABLED(CONFIG_SANDBOX)
+ u32 blk;
+
+ for (blk = 0; blk < plat->boot_blks; blk++) {
+ rkmtd_read_oob(plat, blk * plat->mtd->erasesize, plat->datbuf, plat->oobbuf);
+ if (*(u32 *)plat->datbuf == RK_TAG) {
+ struct sector0 *sec0 = (struct sector0 *)plat->datbuf;
+
+ rkmtd_rc4(plat->datbuf, 512);
+
+ plat->idblock[plat->blk_counter].blk = blk;
+ plat->idblock[plat->blk_counter].offset = sec0->boot_code1_offset;
+ plat->idblock[plat->blk_counter].boot_size = sec0->flash_boot_size;
+
+ debug("\nblk : %d\n", plat->idblock[plat->blk_counter].blk);
+ debug("offset : %d\n", plat->idblock[plat->blk_counter].offset);
+ debug("boot_size : %d\n", plat->idblock[plat->blk_counter].boot_size);
+
+ plat->blk_counter += 1;
+
+ if (plat->blk_counter >= ARRAY_SIZE(plat->idblock))
+ return;
+ }
+ }
+#endif
+}
+
+void rkmtd_read_block(struct rkmtd_dev *plat, u32 idx, u8 *buf)
+{
+#if !IS_ENABLED(CONFIG_SANDBOX)
+ ulong off = plat->idblock[idx].blk * plat->mtd->erasesize;
+ struct nand_chip *chip = mtd_to_nand(plat->mtd);
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ int counter = 0;
+ u32 spare0 = 0;
+ u32 *p_spare;
+ int sector;
+ int page;
+
+ rkmtd_read_oob(plat, off,
+ plat->datbuf, plat->oobbuf);
+
+ memcpy(buf, plat->datbuf, BLK_SIZE);
+
+ while (counter < plat->idblock[idx].boot_size) {
+ if (spare0)
+ page = (plat->idblock[idx].offset + spare0) / 4;
+ else
+ page = (plat->idblock[idx].offset + counter) / 4;
+
+ rkmtd_read_oob(plat,
+ off + page * plat->mtd->writesize,
+ plat->datbuf, plat->oobbuf);
+
+ sector = plat->idblock[idx].offset + counter;
+
+ memcpy(&buf[(sector / 4) * BLK_SIZE], plat->datbuf, BLK_SIZE);
+
+ p_spare = (u32 *)&plat->oobbuf[(ecc->steps - 1) * NFC_SYS_DATA_SIZE];
+
+ spare0 = *p_spare;
+ if (spare0 == -1)
+ break;
+
+ counter += 4;
+ }
+#endif
+}
+
+void rkmtd_write_block(struct rkmtd_dev *plat, u32 idx, u8 *buf)
+{
+#if !IS_ENABLED(CONFIG_SANDBOX)
+ ulong off = plat->idblock[idx].blk * plat->mtd->erasesize;
+ struct nand_chip *chip = mtd_to_nand(plat->mtd);
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ int counter = 0;
+ u32 *p_spare;
+ int sector;
+ int page;
+ int j, w, r;
+
+ rkmtd_erase(plat, off);
+
+ memset(plat->datbuf, 0xff, plat->mtd->writesize);
+ memcpy(plat->datbuf, buf, BLK_SIZE);
+ memset(plat->oobbuf, 0xff, plat->mtd->oobsize);
+
+ rkmtd_write_oob(plat, off,
+ plat->datbuf, plat->oobbuf);
+
+ while (counter < plat->idblock[idx].boot_size) {
+ sector = plat->idblock[idx].offset + counter;
+
+ memset(plat->datbuf, 0xff, plat->mtd->writesize);
+ memcpy(plat->datbuf, &buf[(sector / 4) * BLK_SIZE], BLK_SIZE);
+ memset(plat->oobbuf, 0xff, plat->mtd->oobsize);
+
+ p_spare = (u32 *)&plat->oobbuf[(ecc->steps - 1) * NFC_SYS_DATA_SIZE];
+
+ *p_spare = (plat->page_table[sector / 4 + 1] - 1) * 4;
+
+ page = plat->page_table[sector / 4];
+
+ rkmtd_write_oob(plat,
+ off + page * plat->mtd->writesize,
+ plat->datbuf, plat->oobbuf);
+
+ counter += 4;
+ }
+
+ memset(plat->check, 0, BUF_SIZE);
+ rkmtd_read_block(plat, idx, plat->check);
+
+ for (j = 0; j < BLK_SIZE; j++) {
+ w = *(buf + j);
+ r = *(plat->check + j);
+
+ if (r != w)
+ goto dumpblock;
+ }
+
+ for (j = 0; j < (plat->idblock[idx].boot_size * 512); j++) {
+ w = *(buf + plat->idblock[idx].offset * 512 + j);
+ r = *(plat->check + plat->idblock[idx].offset * 512 + j);
+
+ if (r != w)
+ goto dumpblock;
+ }
+
+ debug("write OK\n");
+ return;
+
+dumpblock:
+ debug("write and check error:%x r=%x w=%x\n", j, r, w);
+
+ plat->idblock[idx].offset = 0;
+ plat->idblock[idx].boot_size = 0;
+
+ memset(plat->datbuf, 0xff, plat->mtd->writesize);
+ memset(plat->datbuf, 0, BLK_SIZE);
+ memset(plat->oobbuf, 0xff, plat->mtd->oobsize);
+
+ rkmtd_write_oob(plat, off, plat->datbuf, plat->oobbuf);
+#endif
+}
+
+ulong rkmtd_bread(struct udevice *udev, lbaint_t start,
+ lbaint_t blkcnt, void *dst)
+{
+ struct blk_desc *block_dev = dev_get_uclass_plat(udev);
+ struct udevice *parent_dev = dev_get_parent(udev);
+ struct rkmtd_dev *plat = dev_get_plat(parent_dev);
+ char *buf = dst;
+ int i;
+
+ if (blkcnt == 0)
+ return 0;
+
+ if (start > (block_dev->lba - 1) ||
+ (start + blkcnt) > block_dev->lba)
+ return 0;
+
+ memset(dst, 0, blkcnt * block_dev->blksz);
+
+ for (i = start; i < (start + blkcnt); i++) {
+ if (i == 0) {
+ debug("mbr : %d\n", i);
+
+ memcpy(&buf[(i - start) * block_dev->blksz],
+ plat->mbr, sizeof(legacy_mbr));
+ } else if (i == 1) {
+ debug("gpt_h : %d\n", i);
+
+ memcpy(&buf[(i - start) * block_dev->blksz],
+ plat->gpt_h, sizeof(gpt_header));
+ } else if (i == (block_dev->lba - 1)) {
+ debug("gpt_h2 : %d\n", i);
+
+ memcpy(&buf[(i - start) * block_dev->blksz],
+ plat->gpt_h2, sizeof(gpt_header));
+ } else if (i == 2 || i == (block_dev->lba - 33)) {
+ debug("gpt_e : %d\n", i);
+
+ memcpy(&buf[(i - start) * block_dev->blksz],
+ plat->gpt_e, sizeof(gpt_entry));
+ } else if (i >= 64 && i < (block_dev->lba - 33)) {
+ debug("rd : %d\n", i);
+
+ memcpy(&buf[(i - start) * block_dev->blksz],
+ &plat->idb[(i - 64) * block_dev->blksz], block_dev->blksz);
+ }
+ }
+
+ return blkcnt;
+}
+
+ulong rkmtd_bwrite(struct udevice *udev, lbaint_t start,
+ lbaint_t blkcnt, const void *src)
+{
+ struct blk_desc *block_dev = dev_get_uclass_plat(udev);
+ struct udevice *parent_dev = dev_get_parent(udev);
+ struct rkmtd_dev *plat = dev_get_plat(parent_dev);
+ struct sector0 *sec0;
+ int i, j;
+
+ if (blkcnt == 0)
+ return 0;
+
+ if (start > (block_dev->lba - 1) ||
+ (start + blkcnt) > block_dev->lba)
+ return 0;
+
+ for (i = start; i < (start + blkcnt); i++) {
+ debug("wr : %d\n", i);
+
+ if (i >= 64 && i < (block_dev->lba - 33)) {
+ if (i == 64) {
+ debug("first block\n");
+
+ plat->idb_need_write_back = 1;
+ memset(plat->idb, 0, BUF_SIZE);
+ }
+
+ if (plat->idb_need_write_back) {
+ char *buf = (char *)src;
+
+ memcpy(&plat->idb[(i - 64) * block_dev->blksz],
+ &buf[(i - start) * block_dev->blksz],
+ block_dev->blksz);
+
+ if (i == 64) {
+ memcpy(plat->check, plat->idb, 512);
+
+ if (*(u32 *)plat->check == RK_TAG) {
+ rkmtd_rc4(plat->check, 512);
+
+ sec0 = (struct sector0 *)plat->check;
+ plat->offset = sec0->boot_code1_offset;
+ plat->boot_size = sec0->flash_boot_size;
+
+ if (plat->offset + plat->boot_size > 512) {
+ debug("max size limit\n");
+ plat->idb_need_write_back = 0;
+ }
+ } else {
+ debug("no IDB block found\n");
+ plat->idb_need_write_back = 0;
+ }
+ }
+
+ if (i == (64 + plat->offset + plat->boot_size - 1)) {
+ debug("last block\n");
+
+ plat->idb_need_write_back = 0;
+
+ if (!plat->blk_counter) {
+ plat->idblock[0].blk = 2;
+ plat->idblock[1].blk = 3;
+ plat->idblock[2].blk = 4;
+ plat->idblock[3].blk = 5;
+ plat->idblock[4].blk = 6;
+ plat->blk_counter = 5;
+ }
+
+ for (j = 0; j < plat->blk_counter; j++) {
+ if (plat->idblock[j].blk < plat->boot_blks) {
+ plat->idblock[j].offset = plat->offset;
+ plat->idblock[j].boot_size = plat->boot_size;
+ rkmtd_write_block(plat, j, plat->idb);
+ }
+ }
+
+ rkmtd_scan_block(plat);
+
+ if (!IS_ENABLED(CONFIG_SANDBOX))
+ memset(plat->idb, 0, BUF_SIZE);
+
+ if (plat->blk_counter)
+ rkmtd_read_block(plat, 0, plat->idb);
+ }
+ }
+ } else if (plat->idb_need_write_back) {
+ plat->idb_need_write_back = 0;
+
+ memset(plat->idb, 0, BUF_SIZE);
+
+ if (plat->blk_counter)
+ rkmtd_read_block(plat, 0, plat->idb);
+ }
+ }
+
+ return blkcnt;
+}
+
+static const struct blk_ops rkmtd_blk_ops = {
+ .read = rkmtd_bread,
+ .write = rkmtd_bwrite,
+};
+
+U_BOOT_DRIVER(rkmtd_blk) = {
+ .name = "rkmtd_blk",
+ .id = UCLASS_BLK,
+ .ops = &rkmtd_blk_ops,
+};
+
+void rkmtd_build_page_table(struct rkmtd_dev *plat)
+{
+ u32 counter;
+ u32 counter2;
+
+ switch (plat->lsb_mode) {
+ case 0:
+ counter = 0;
+ do {
+ u16 val = counter;
+
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ case 1:
+ counter = 0;
+ do {
+ u16 val = counter;
+
+ if (counter > 3) {
+ u16 offset;
+
+ if (counter & 1)
+ offset = 3;
+ else
+ offset = 2;
+ val = 2 * counter - offset;
+ }
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ case 2:
+ counter = 0;
+ do {
+ u16 val = counter;
+
+ if (counter > 1)
+ val = 2 * counter - 1;
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ case 3:
+ counter = 0;
+ do {
+ u16 val = counter;
+
+ if (counter > 5) {
+ u16 offset;
+
+ if (counter & 1)
+ offset = 5;
+ else
+ offset = 4;
+ val = 2 * counter - offset;
+ }
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ case 4:
+ counter = 8;
+ plat->page_table[0] = 0;
+ plat->page_table[1] = 1;
+ plat->page_table[2] = 2;
+ plat->page_table[3] = 3;
+ plat->page_table[4] = 4;
+ plat->page_table[5] = 5;
+ plat->page_table[6] = 7;
+ plat->page_table[7] = 8;
+ do {
+ u32 offset;
+ u32 val;
+
+ if (counter & 1)
+ offset = 7;
+ else
+ offset = 6;
+ val = 2 * counter - offset;
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ case 5:
+ counter = 0;
+ counter2 = 16;
+ do {
+ u16 val = counter;
+
+ plat->page_table[counter++] = val;
+ } while (counter != 16);
+ do {
+ plat->page_table[counter++] = counter2;
+ counter2 = counter2 + 2;
+ } while (counter != 512);
+ break;
+ case 6:
+ counter = 0;
+ counter2 = 0;
+ do {
+ u16 val = counter;
+
+ if (counter > 5) {
+ u16 offset;
+
+ if (counter & 1)
+ offset = 12;
+ else
+ offset = 10;
+ val = counter2 - offset;
+ }
+ plat->page_table[counter++] = val;
+ counter2 = counter2 + 3;
+ } while (counter != 512);
+ break;
+ case 9:
+ counter = 3;
+ counter2 = 3;
+ plat->page_table[0] = 0;
+ plat->page_table[1] = 1;
+ plat->page_table[2] = 2;
+ do {
+ plat->page_table[counter++] = counter2;
+ counter2 = counter2 + 2;
+ } while (counter != 512);
+ break;
+ case 10:
+ counter = 0;
+ counter2 = 63;
+ do {
+ u16 val = counter;
+
+ plat->page_table[counter++] = val;
+ } while (counter != 63);
+ do {
+ plat->page_table[counter++] = counter2;
+ counter2 = counter2 + 2;
+ } while (counter != 512);
+ break;
+ case 11:
+ counter = 0;
+ do {
+ u16 val = counter;
+
+ plat->page_table[counter++] = val;
+ } while (counter != 8);
+ do {
+ u32 offset;
+ u32 val;
+
+ if (counter & 1)
+ offset = 7;
+ else
+ offset = 6;
+ val = 2 * counter - offset;
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ case 12:
+ counter = 4;
+ plat->page_table[0] = 0;
+ plat->page_table[1] = 1;
+ plat->page_table[2] = 2;
+ plat->page_table[3] = 3;
+ do {
+ u32 val = counter - 1 + (counter >> 1);
+
+ plat->page_table[counter++] = val;
+ } while (counter != 512);
+ break;
+ }
+}
+
+static inline u32 efi_crc32(const void *buf, u32 len)
+{
+ return crc32(0, buf, len);
+}
+
+int rkmtd_init_plat(struct udevice *dev)
+{
+ static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID;
+ struct rkmtd_dev *plat = dev_get_plat(dev);
+ size_t efiname_len, dosname_len;
+ uchar name[] = "loader1";
+ u32 calc_crc32;
+ int k;
+
+ gen_rand_uuid_str(plat->uuid_disk_str, UUID_STR_FORMAT_GUID);
+ gen_rand_uuid_str(plat->uuid_part_str, UUID_STR_FORMAT_GUID);
+
+ debug("uuid_part_str : %s\n", plat->uuid_part_str);
+ debug("uuid_disk_str : %s\n", plat->uuid_disk_str);
+
+ plat->idb = devm_kzalloc(plat->dev, BUF_SIZE, GFP_KERNEL);
+ if (!plat->idb)
+ return -ENOMEM;
+
+ plat->check = devm_kzalloc(plat->dev, BUF_SIZE, GFP_KERNEL);
+ if (!plat->check)
+ return -ENOMEM;
+
+ plat->mbr = devm_kzalloc(plat->dev, sizeof(legacy_mbr), GFP_KERNEL);
+ if (!plat->mbr)
+ return -ENOMEM;
+
+ plat->gpt_e = devm_kzalloc(plat->dev, sizeof(gpt_entry), GFP_KERNEL);
+ if (!plat->gpt_e)
+ return -ENOMEM;
+
+ plat->gpt_h = devm_kzalloc(plat->dev, sizeof(gpt_header), GFP_KERNEL);
+ if (!plat->gpt_h)
+ return -ENOMEM;
+
+ plat->gpt_h2 = devm_kzalloc(plat->dev, sizeof(gpt_header), GFP_KERNEL);
+ if (!plat->gpt_h2)
+ return -ENOMEM;
+
+ /* Init mbr */
+ plat->mbr->signature = MSDOS_MBR_SIGNATURE;
+ plat->mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
+ plat->mbr->partition_record[0].start_sect = 1;
+ plat->mbr->partition_record[0].nr_sects = LBA - 1;
+
+ /* Init gpt_e */
+ plat->gpt_e->starting_lba = cpu_to_le64(64);
+ plat->gpt_e->ending_lba = cpu_to_le64(LBA - 34);
+
+ debug("starting_lba : %llu\n", le64_to_cpu(plat->gpt_e->starting_lba));
+ debug("ending_lba : %llu\n", le64_to_cpu(plat->gpt_e->ending_lba));
+
+ memcpy(plat->gpt_e->partition_type_guid.b, &partition_basic_data_guid, 16);
+
+ uuid_str_to_bin(plat->uuid_part_str, plat->gpt_e->unique_partition_guid.b,
+ UUID_STR_FORMAT_GUID);
+
+ efiname_len = sizeof(plat->gpt_e->partition_name) / sizeof(efi_char16_t);
+ dosname_len = sizeof(name);
+
+ for (k = 0; k < min(dosname_len, efiname_len); k++)
+ plat->gpt_e->partition_name[k] = (efi_char16_t)(name[k]);
+
+ /* Init gpt_h */
+ plat->gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE_UBOOT);
+ plat->gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
+ plat->gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
+ plat->gpt_h->first_usable_lba = cpu_to_le64(64);
+ plat->gpt_h->last_usable_lba = cpu_to_le64(LBA - 34);
+ plat->gpt_h->num_partition_entries = cpu_to_le32(1);
+ plat->gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
+
+ uuid_str_to_bin(plat->uuid_disk_str, plat->gpt_h->disk_guid.b,
+ UUID_STR_FORMAT_GUID);
+
+ plat->gpt_h->partition_entry_array_crc32 = 0;
+ calc_crc32 = efi_crc32((const unsigned char *)plat->gpt_e,
+ le32_to_cpu(plat->gpt_h->num_partition_entries) *
+ le32_to_cpu(plat->gpt_h->sizeof_partition_entry));
+ plat->gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);
+
+ debug("partition crc32 : 0x%08x\n", calc_crc32);
+
+ plat->gpt_h->my_lba = cpu_to_le64(1);
+ plat->gpt_h->partition_entry_lba = cpu_to_le64(2);
+ plat->gpt_h->alternate_lba = cpu_to_le64(LBA - 1);
+
+ plat->gpt_h->header_crc32 = 0;
+ calc_crc32 = efi_crc32((const unsigned char *)plat->gpt_h,
+ le32_to_cpu(plat->gpt_h->header_size));
+ plat->gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
+
+ debug("header h1 crc32 : 0x%08x\n", calc_crc32);
+
+ /* Init gpt_h2 */
+ memcpy(plat->gpt_h2, plat->gpt_h, sizeof(gpt_header));
+
+ plat->gpt_h2->my_lba = cpu_to_le64(LBA - 1);
+ plat->gpt_h2->partition_entry_lba =
+ cpu_to_le64(le64_to_cpu(plat->gpt_h2->last_usable_lba) + 1);
+ plat->gpt_h2->alternate_lba = cpu_to_le64(1);
+
+ plat->gpt_h2->header_crc32 = 0;
+ calc_crc32 = efi_crc32((const unsigned char *)plat->gpt_h2,
+ le32_to_cpu(plat->gpt_h2->header_size));
+ plat->gpt_h2->header_crc32 = cpu_to_le32(calc_crc32);
+
+ debug("header h2 crc32 : 0x%08x\n", calc_crc32);
+
+ part_init(plat->desc);
+
+ return 0;
+}
+
+static void rkmtd_blk_kmalloc_release(struct udevice *dev, void *res)
+{
+ /* noop */
+}
+
+static int rkmtd_bind(struct udevice *dev)
+{
+ struct rkmtd_dev *plat = dev_get_plat(dev);
+ char dev_name[30], *str;
+ struct blk_desc *desc;
+ struct udevice *bdev;
+ int ret;
+
+ snprintf(dev_name, sizeof(dev_name), "%s.%s", dev->name, "blk");
+
+ str = devres_alloc(rkmtd_blk_kmalloc_release, strlen(dev_name) + 1, GFP_KERNEL);
+ if (unlikely(!str))
+ return -ENOMEM;
+
+ strcpy(str, dev_name);
+
+ ret = blk_create_device(dev, "rkmtd_blk", str, UCLASS_RKMTD,
+ -1, 512, LBA, &bdev);
+ if (ret) {
+ free(str);
+ return log_msg_ret("blk", ret);
+ }
+
+ devres_add(dev, str);
+
+ desc = dev_get_uclass_plat(bdev);
+ sprintf(desc->vendor, "0x%.4x", 0x2207);
+ memcpy(desc->product, "RKMTD", sizeof("RKMTD"));
+ memcpy(desc->revision, "V1.00", sizeof("V1.00"));
+ plat->desc = desc;
+
+ return 0;
+}
+
+static int rkmtd_attach_mtd(struct udevice *dev)
+{
+ struct rkmtd_dev *plat = dev_get_plat(dev);
+ struct mtd_info *mtd;
+ struct udevice *blk;
+ int ret;
+
+ plat->dev = dev;
+
+ /* Sanity check that rkmtd_bind() has been used */
+ ret = blk_find_from_parent(dev, &blk);
+ if (ret)
+ return ret;
+
+#if IS_ENABLED(CONFIG_SANDBOX)
+ plat->mtd = devm_kzalloc(dev, sizeof(struct mtd_info), GFP_KERNEL);
+ if (!plat->mtd)
+ return -ENOMEM;
+
+ mtd = plat->mtd;
+ mtd->erasesize = 2 ^ 3 * BLK_SIZE;
+ mtd->writesize = BLK_SIZE;
+ mtd->oobsize = BLK_SIZE / STEP_SIZE * NFC_SYS_DATA_SIZE;
+ plat->boot_blks = 0;
+ plat->lsb_mode = 0;
+#else
+ struct nand_chip *chip;
+ u8 id[6];
+ int i, j;
+ u32 tmp;
+
+ mtd = get_nand_dev_by_index(0);
+ if (!mtd)
+ return -ENOSYS;
+
+ chip = mtd_to_nand(mtd);
+
+ ret = ofnode_read_u32(chip->flash_node, "rockchip,boot-blks", &tmp);
+ plat->boot_blks = ret ? 0 : tmp;
+ plat->mtd = mtd;
+
+ if (chip->select_chip)
+ chip->select_chip(mtd, 0);
+
+ nand_readid_op(chip, 0, id, 6);
+
+ if (chip->select_chip)
+ chip->select_chip(mtd, -1);
+
+ for (i = 0; i < ARRAY_SIZE(nand_para_tbl); i++) {
+ plat->info = (struct nand_para_info *)&nand_para_tbl[i];
+ for (j = 0; j < plat->info->id_bytes; j++) {
+ if (plat->info->nand_id[j] != id[j])
+ break;
+ if (j == plat->info->id_bytes - 1)
+ goto valid;
+ }
+ }
+
+ debug("no nand_para_info found\n");
+ return -ENODEV;
+valid:
+ plat->lsb_mode = plat->info->lsb_mode;
+
+ debug("FLASH ID :");
+
+ for (j = 0; j < plat->info->id_bytes; j++)
+ debug(" %x", id[j]);
+
+ debug("\n");
+#endif
+
+ rkmtd_build_page_table(plat);
+
+ plat->datbuf = devm_kzalloc(dev, mtd->writesize, GFP_KERNEL);
+ if (!plat->datbuf)
+ return -ENOMEM;
+
+ plat->oobbuf = devm_kzalloc(dev, mtd->oobsize, GFP_KERNEL);
+ if (!plat->oobbuf)
+ return -ENOMEM;
+
+ debug("erasesize %8d\n", mtd->erasesize);
+ debug("writesize %8d\n", mtd->writesize);
+ debug("oobsize %8d\n", mtd->oobsize);
+ debug("boot_blks %8d\n", plat->boot_blks);
+ debug("lsb_mode %8d\n", plat->lsb_mode);
+
+ ret = rkmtd_init_plat(dev);
+ if (ret) {
+ debug("rkmtd_init_plat failed\n");
+ return -ENOENT;
+ }
+
+ rkmtd_scan_block(plat);
+
+ memset(plat->idb, 0, BUF_SIZE);
+
+ if (plat->blk_counter)
+ rkmtd_read_block(plat, 0, plat->idb);
+
+ return 0;
+}
+
+int rkmtd_detach_mtd(struct udevice *dev)
+{
+ int ret;
+
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
+ if (ret)
+ return log_msg_ret("rem", ret);
+
+ ret = device_chld_unbind(dev, NULL);
+ if (ret)
+ return log_msg_ret("unb", ret);
+
+ return 0;
+}
+
+struct rkmtd_ops rkmtd_ops = {
+ .attach_mtd = rkmtd_attach_mtd,
+ .detach_mtd = rkmtd_detach_mtd,
+};
+
+U_BOOT_DRIVER(rkmtd_drv) = {
+ .name = "rkmtd_drv",
+ .id = UCLASS_RKMTD,
+ .ops = &rkmtd_ops,
+ .bind = rkmtd_bind,
+ .plat_auto = sizeof(struct rkmtd_dev),
+};
+
+struct rkmtd_priv {
+ struct udevice *cur_dev;
+};
+
+void rkmtd_rc4(u8 *buf, u32 len)
+{
+ u8 S[256], K[256], temp;
+ u32 i, j, t, x;
+ u8 key[16] = { 124, 78, 3, 4, 85, 5, 9, 7, 45, 44, 123, 56, 23, 13, 23, 17};
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ S[i] = (u8)i;
+ j &= 0x0f;
+ K[i] = key[j];
+ j++;
+ }
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ j = (j + S[i] + K[i]) % 256;
+ temp = S[i];
+ S[i] = S[j];
+ S[j] = temp;
+ }
+
+ i = 0;
+ j = 0;
+ for (x = 0; x < len; x++) {
+ i = (i + 1) % 256;
+ j = (j + S[i]) % 256;
+ temp = S[i];
+ S[i] = S[j];
+ S[j] = temp;
+ t = (S[i] + (S[j] % 256)) % 256;
+ buf[x] = buf[x] ^ S[t];
+ }
+}
+
+struct udevice *rkmtd_get_cur_dev(void)
+{
+ struct uclass *uc = uclass_find(UCLASS_RKMTD);
+
+ if (uc) {
+ struct rkmtd_priv *priv = uclass_get_priv(uc);
+
+ return priv->cur_dev;
+ }
+
+ return NULL;
+}
+
+void rkmtd_set_cur_dev(struct udevice *dev)
+{
+ struct uclass *uc = uclass_find(UCLASS_RKMTD);
+
+ if (uc) {
+ struct rkmtd_priv *priv = uclass_get_priv(uc);
+
+ priv->cur_dev = dev;
+ }
+}
+
+struct udevice *rkmtd_find_by_label(const char *label)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+
+ uclass_id_foreach_dev(UCLASS_RKMTD, dev, uc) {
+ struct rkmtd_dev *plat = dev_get_plat(dev);
+
+ if (plat->label && !strcmp(label, plat->label))
+ return dev;
+ }
+
+ return NULL;
+}
+
+int rkmtd_attach(struct udevice *dev)
+{
+ struct rkmtd_ops *ops = rkmtd_get_ops(dev);
+
+ if (!ops->attach_mtd)
+ return -ENOSYS;
+
+ return ops->attach_mtd(dev);
+}
+
+int rkmtd_detach(struct udevice *dev)
+{
+ struct rkmtd_ops *ops = rkmtd_get_ops(dev);
+
+ if (!ops->detach_mtd)
+ return -ENOSYS;
+
+ if (dev == rkmtd_get_cur_dev())
+ rkmtd_set_cur_dev(NULL);
+
+ return ops->detach_mtd(dev);
+}
+
+static void rkmtd_drv_kmalloc_release(struct udevice *dev, void *res)
+{
+ /* noop */
+}
+
+int rkmtd_create_device(const char *label, struct udevice **devp)
+{
+ char dev_name[30], *str, *label_new;
+ struct udevice *dev, *blk;
+ struct rkmtd_dev *plat;
+ int ret;
+
+ /* unbind any existing device with this label */
+ dev = rkmtd_find_by_label(label);
+ if (dev) {
+ ret = rkmtd_detach(dev);
+ if (ret)
+ return log_msg_ret("det", ret);
+
+ ret = device_unbind(dev);
+ if (ret)
+ return log_msg_ret("unb", ret);
+ }
+
+ snprintf(dev_name, sizeof(dev_name), "rkmtd-%s", label);
+
+ str = devres_alloc(rkmtd_drv_kmalloc_release, strlen(dev_name) + 1, GFP_KERNEL);
+ if (unlikely(!str))
+ return -ENOMEM;
+
+ strcpy(str, dev_name);
+
+ ret = device_bind_driver(dm_root(), "rkmtd_drv", str, &dev);
+ if (ret) {
+ free(str);
+ return log_msg_ret("drv", ret);
+ }
+
+ devres_add(dev, str);
+
+ if (!blk_find_from_parent(dev, &blk)) {
+ struct blk_desc *desc = dev_get_uclass_plat(blk);
+
+ desc->removable = true;
+ }
+
+ label_new = devm_kzalloc(dev, strlen(label) + 1, GFP_KERNEL);
+ if (!label_new)
+ return -ENOMEM;
+
+ strcpy(label_new, label);
+
+ plat = dev_get_plat(dev);
+ plat->label = label_new;
+ *devp = dev;
+
+ return 0;
+}
+
+int rkmtd_create_attach_mtd(const char *label, struct udevice **devp)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = rkmtd_create_device(label, &dev);
+ if (ret)
+ return log_msg_ret("cre", ret);
+
+ ret = rkmtd_attach(dev);
+ if (ret) {
+ device_unbind(dev);
+ return log_msg_ret("att", ret);
+ }
+ *devp = dev;
+
+ return 0;
+}
+
+UCLASS_DRIVER(rkmtd) = {
+ .name = "rkmtd",
+ .id = UCLASS_RKMTD,
+ .post_bind = dm_scan_fdt_dev,
+ .priv_auto = sizeof(struct rkmtd_priv),
+};
diff --git a/drivers/clk/rockchip/clk_pll.c b/drivers/clk/rockchip/clk_pll.c
index d657ef38f3..1bb31b3313 100644
--- a/drivers/clk/rockchip/clk_pll.c
+++ b/drivers/clk/rockchip/clk_pll.c
@@ -168,13 +168,71 @@ rockchip_pll_clk_set_by_auto(ulong fin_hz,
return rate_table;
}
+static u32
+rockchip_rk3588_pll_k_get(u32 m, u32 p, u32 s, u64 fin_hz, u64 fvco)
+{
+ u64 fref, fout, ffrac;
+ u32 k = 0;
+
+ fref = fin_hz / p;
+ ffrac = fvco - (m * fref);
+ fout = ffrac * 65536;
+ k = fout / fref;
+ if (k > 32767) {
+ fref = fin_hz / p;
+ ffrac = ((m + 1) * fref) - fvco;
+ fout = ffrac * 65536;
+ k = ((fout * 10 / fref) + 7) / 10;
+ if (k > 32767)
+ k = 0;
+ else
+ k = ~k + 1;
+ }
+ return k;
+}
+
+static struct rockchip_pll_rate_table *
+rockchip_rk3588_pll_frac_by_auto(unsigned long fin_hz, unsigned long fout_hz)
+{
+ struct rockchip_pll_rate_table *rate_table = &rockchip_auto_table;
+ u32 p, m, s, k;
+ u64 fvco;
+
+ for (s = 0; s <= 6; s++) {
+ fvco = (u64)fout_hz << s;
+ if (fvco < RK3588_VCO_MIN_HZ || fvco > RK3588_VCO_MAX_HZ)
+ continue;
+ for (p = 1; p <= 4; p++) {
+ for (m = 64; m <= 1023; m++) {
+ if ((fvco >= m * fin_hz / p) &&
+ (fvco < (m + 1) * fin_hz / p)) {
+ k = rockchip_rk3588_pll_k_get(m, p, s,
+ fin_hz,
+ fvco);
+ if (!k)
+ continue;
+ rate_table->p = p;
+ rate_table->s = s;
+ rate_table->k = k;
+ if (k > 32767)
+ rate_table->m = m + 1;
+ else
+ rate_table->m = m;
+ return rate_table;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
static struct rockchip_pll_rate_table *
rk3588_pll_clk_set_by_auto(unsigned long fin_hz,
unsigned long fout_hz)
{
struct rockchip_pll_rate_table *rate_table = &rockchip_auto_table;
u32 p, m, s;
- ulong fvco, fref, fout, ffrac;
+ ulong fvco;
if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
return NULL;
@@ -202,27 +260,12 @@ rk3588_pll_clk_set_by_auto(unsigned long fin_hz,
}
pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
} else {
- for (s = 0; s <= 6; s++) {
- fvco = fout_hz << s;
- if (fvco < RK3588_VCO_MIN_HZ ||
- fvco > RK3588_VCO_MAX_HZ)
- continue;
- for (p = 1; p <= 4; p++) {
- for (m = 64; m <= 1023; m++) {
- if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p)) {
- rate_table->p = p;
- rate_table->m = m;
- rate_table->s = s;
- fref = fin_hz / p;
- ffrac = fvco - (m * fref);
- fout = ffrac * 65536;
- rate_table->k = fout / fref;
- return rate_table;
- }
- }
- }
- }
- pr_err("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
+ rate_table = rockchip_rk3588_pll_frac_by_auto(fin_hz, fout_hz);
+ if (!rate_table)
+ pr_err("CANNOT FIND Fout by auto,fout = %lu\n",
+ fout_hz);
+ else
+ return rate_table;
}
return NULL;
}
@@ -533,11 +576,22 @@ static ulong rk3588_pll_get_rate(struct rockchip_pll_clock *pll,
rate = OSC_HZ / p;
rate *= m;
- if (k) {
+ if (k & BIT(15)) {
+ /* fractional mode */
+ u64 frac_rate64;
+
+ k = (~(k - 1)) & RK3588_PLLCON2_K_MASK;
+ frac_rate64 = OSC_HZ * k;
+ postdiv = p;
+ postdiv *= 65536;
+ do_div(frac_rate64, postdiv);
+ rate -= frac_rate64;
+ } else {
/* fractional mode */
u64 frac_rate64 = OSC_HZ * k;
- postdiv = p * 65536;
+ postdiv = p;
+ postdiv *= 65536;
do_div(frac_rate64, postdiv);
rate += frac_rate64;
}
diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c
index 599b7b130e..68f5bbbb9e 100644
--- a/drivers/clk/rockchip/clk_rk3568.c
+++ b/drivers/clk/rockchip/clk_rk3568.c
@@ -1838,7 +1838,7 @@ static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv,
rockchip_pll_set_rate(&rk3568_pll_clks[VPLL],
priv->cru, VPLL, div * rate);
} else {
- for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
+ for (i = sel; i <= DCLK_VOP_SEL_CPLL; i++) {
switch (i) {
case DCLK_VOP_SEL_GPLL:
pll_rate = priv->gpll_hz;
@@ -2785,9 +2785,15 @@ static int rk3568_dclk_vop_set_parent(struct clk *clk, struct clk *parent)
if (parent->id == PLL_VPLL) {
rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
- } else {
+ } else if (parent->id == PLL_HPLL) {
rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
+ } else if (parent->id == PLL_CPLL) {
+ rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
+ DCLK_VOP_SEL_CPLL << DCLK0_VOP_SEL_SHIFT);
+ } else {
+ rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
+ DCLK_VOP_SEL_GPLL << DCLK0_VOP_SEL_SHIFT);
}
return 0;
diff --git a/drivers/clk/rockchip/clk_rk3588.c b/drivers/clk/rockchip/clk_rk3588.c
index 119b1337bd..a995dd5591 100644
--- a/drivers/clk/rockchip/clk_rk3588.c
+++ b/drivers/clk/rockchip/clk_rk3588.c
@@ -36,6 +36,7 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
+ RK3588_PLL_RATE(742500000, 4, 495, 2, 0),
RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
@@ -305,12 +306,18 @@ static ulong rk3588_top_set_clk(struct rk3588_clk_priv *priv,
switch (clk_id) {
case ACLK_TOP_ROOT:
- src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ if (!(priv->cpll_hz % rate)) {
+ src_clk = ACLK_TOP_ROOT_SRC_SEL_CPLL;
+ src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
+ } else {
+ src_clk = ACLK_TOP_ROOT_SRC_SEL_GPLL;
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ }
assert(src_clk_div - 1 <= 31);
rk_clrsetreg(&cru->clksel_con[8],
ACLK_TOP_ROOT_DIV_MASK |
ACLK_TOP_ROOT_SRC_SEL_MASK,
- (ACLK_TOP_ROOT_SRC_SEL_GPLL <<
+ (src_clk <<
ACLK_TOP_ROOT_SRC_SEL_SHIFT) |
(src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT);
break;
@@ -1123,13 +1130,23 @@ static ulong rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv,
}
if (sel == DCLK_VOP_SRC_SEL_V0PLL) {
- div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
- rk_clrsetreg(&cru->clksel_con[conid],
- mask,
- DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
- ((div - 1) << div_shift));
- rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
- priv->cru, V0PLL, div * rate);
+ pll_rate = rockchip_pll_get_rate(&rk3588_pll_clks[V0PLL],
+ priv->cru, V0PLL);
+ if (pll_rate >= RK3588_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) {
+ div = DIV_ROUND_UP(pll_rate, rate);
+ rk_clrsetreg(&cru->clksel_con[conid],
+ mask,
+ DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
+ ((div - 1) << div_shift));
+ } else {
+ div = DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
+ rk_clrsetreg(&cru->clksel_con[conid],
+ mask,
+ DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
+ ((div - 1) << div_shift));
+ rockchip_pll_set_rate(&rk3588_pll_clks[V0PLL],
+ priv->cru, V0PLL, div * rate);
+ }
} else {
for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++) {
switch (i) {
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index d624589a89..72547f00fb 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -611,6 +611,15 @@ config ROCKCHIP_NAND
NFC v800: RK3308, RV1108
NFC v900: PX30, RK3326
+config ROCKCHIP_NAND_SKIP_BBTSCAN
+ bool "Skip the automatic BBT scan with Rockchip NAND controllers"
+ depends on ROCKCHIP_NAND
+ default n
+ help
+ Skip the automatic BBT scan with the NAND_SKIP_BBTSCAN
+ option when data content is not in MTD format or
+ must remain unchanged.
+
config TEGRA_NAND
bool "Support for NAND controller on Tegra SoCs"
depends on ARCH_TEGRA
diff --git a/drivers/mtd/nand/raw/rockchip_nfc.c b/drivers/mtd/nand/raw/rockchip_nfc.c
index 274489ecbc..088cc7fead 100644
--- a/drivers/mtd/nand/raw/rockchip_nfc.c
+++ b/drivers/mtd/nand/raw/rockchip_nfc.c
@@ -955,6 +955,9 @@ static int rk_nfc_nand_chip_init(ofnode node, struct rk_nfc *nfc, int devnum)
chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER;
+ if (IS_ENABLED(CONFIG_ROCKCHIP_NAND_SKIP_BBTSCAN))
+ chip->options |= NAND_SKIP_BBTSCAN;
+
rk_nfc_hw_init(nfc);
ret = nand_scan_ident(mtd, nsels, NULL);
if (ret)
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index b03dd1cd08..77eb9f352c 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -532,6 +532,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("XM25QH64A", 0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("XM25QH64C", 0x204017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("XM25QU128C", 0x204118, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif
#ifdef CONFIG_SPI_FLASH_XTX
/* XTX Technology Limited */
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 7411660d46..779a34bd2f 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -459,6 +459,9 @@ static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc)
dev_desc->product[0] = 0;
dev_desc->revision[0] = 0;
dev_desc->removable = false;
+#if IS_ENABLED(CONFIG_BOUNCE_BUFFER)
+ dev_desc->bb = true;
+#endif /* CONFIG_BOUNCE_BUFFER */
}
#if !defined(CONFIG_DM_SCSI)
@@ -606,6 +609,7 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose)
bdesc->lun = lun;
bdesc->removable = bd.removable;
bdesc->type = bd.type;
+ bdesc->bb = bd.bb;
memcpy(&bdesc->vendor, &bd.vendor, sizeof(bd.vendor));
memcpy(&bdesc->product, &bd.product, sizeof(bd.product));
memcpy(&bdesc->revision, &bd.revision, sizeof(bd.revision));
diff --git a/include/blk.h b/include/blk.h
index 76bd5baf99..7c7cf7f2b1 100644
--- a/include/blk.h
+++ b/include/blk.h
@@ -68,6 +68,7 @@ struct blk_desc {
/* device can use 48bit addr (ATA/ATAPI v7) */
bool lba48;
unsigned char atapi; /* Use ATAPI protocol */
+ unsigned char bb; /* Use bounce buffer */
lbaint_t lba; /* number of blocks */
unsigned long blksz; /* block size */
int log2blksz; /* for convenience: log2(blksz) */
diff --git a/include/configs/nanopc-t6-rk3588.h b/include/configs/nanopc-t6-rk3588.h
new file mode 100644
index 0000000000..1ece6f9383
--- /dev/null
+++ b/include/configs/nanopc-t6-rk3588.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2023 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef __NANOPCT6_RK3588_H
+#define __NANOPCT6_RK3588_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#include <configs/rk3588_common.h>
+
+#endif /* __NANOPCT6_RK3588_H */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index a6045f5cc8..5271e646bb 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -121,6 +121,7 @@ enum uclass_id {
UCLASS_REGULATOR, /* Regulator device */
UCLASS_REMOTEPROC, /* Remote Processor device */
UCLASS_RESET, /* Reset controller device */
+ UCLASS_RKMTD, /* Rockchip MTD device */
UCLASS_RNG, /* Random Number Generator */
UCLASS_RTC, /* Real time clock device */
UCLASS_SCMI_AGENT, /* Interface with an SCMI server */
diff --git a/include/dt-bindings/leds/common.h b/include/dt-bindings/leds/common.h
index 3be89a7c20..9a0d33d027 100644
--- a/include/dt-bindings/leds/common.h
+++ b/include/dt-bindings/leds/common.h
@@ -33,7 +33,12 @@
#define LED_COLOR_ID_MULTI 8 /* For multicolor LEDs */
#define LED_COLOR_ID_RGB 9 /* For multicolor LEDs that can do arbitrary color,
so this would include RGBW and similar */
-#define LED_COLOR_ID_MAX 10
+#define LED_COLOR_ID_PURPLE 10
+#define LED_COLOR_ID_ORANGE 11
+#define LED_COLOR_ID_PINK 12
+#define LED_COLOR_ID_CYAN 13
+#define LED_COLOR_ID_LIME 14
+#define LED_COLOR_ID_MAX 15
/* Standard LED functions */
/* Keyboard LEDs, usually it would be input4::capslock etc. */
diff --git a/include/rkmtd.h b/include/rkmtd.h
new file mode 100644
index 0000000000..145fede6c8
--- /dev/null
+++ b/include/rkmtd.h
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Driver interface derived from:
+ * /include/sandbox_host.h
+ * Copyright 2022 Google LLC
+ *
+ * Copyright 2023 Johan Jonker <jbx6244@gmail.com>
+ */
+
+#ifndef __RKMTD__
+#define __RKMTD__
+
+#include <part_efi.h>
+#include <uuid.h>
+
+#define LBA 64 + 512 + 33
+
+#define RK_TAG 0xFCDC8C3B
+#define NFC_SYS_DATA_SIZE 4
+#define BLK_SIZE 2048
+#define STEP_SIZE 1024
+#define BUF_SIZE 512 * 512
+
+struct nand_para_info {
+ u8 id_bytes;
+ u8 nand_id[6];
+ u8 vendor;
+ u8 die_per_chip;
+ u8 sec_per_page;
+ u16 page_per_blk;
+ u8 cell;
+ u8 plane_per_die;
+ u16 blk_per_plane;
+ u16 operation_opt;
+ u8 lsb_mode;
+ u8 read_retry_mode;
+ u8 ecc_bits;
+ u8 access_freq;
+ u8 opt_mode;
+ u8 die_gap;
+ u8 bad_block_mode;
+ u8 multi_plane_mode;
+ u8 slc_mode;
+ u8 reserved[5];
+};
+
+struct bootblk {
+ int blk;
+ int boot_size;
+ int offset;
+};
+
+struct rkmtd_dev {
+ struct udevice *dev;
+ struct blk_desc *desc;
+ char *label;
+ legacy_mbr *mbr;
+ gpt_header *gpt_h;
+ gpt_header *gpt_h2;
+ gpt_entry *gpt_e;
+ char *check;
+ char *idb;
+ char *str;
+ char uuid_part_str[UUID_STR_LEN + 1];
+ char uuid_disk_str[UUID_STR_LEN + 1];
+ char *datbuf;
+ char *oobbuf;
+ struct mtd_info *mtd;
+ struct nand_para_info *info;
+ u16 page_table[512];
+ u32 idb_need_write_back;
+ struct bootblk idblock[5];
+ u32 blk_counter;
+ u32 boot_blks;
+ u32 offset;
+ u32 boot_size;
+ u32 lsb_mode;
+};
+
+struct sector0 {
+ u32 magic;
+ u8 reserved[4];
+ u32 rc4_flag;
+ u16 boot_code1_offset;
+ u16 boot_code2_offset;
+ u8 reserved1[490];
+ u16 flash_data_size;
+ u16 flash_boot_size;
+ u8 reserved2[2];
+} __packed;
+
+/**
+ * rkmtd_rc4() - Rockchip specific RC4 Encryption Algorithm
+ *
+ * Encrypt Rockchip boot block header version 1 and data
+ *
+ * @buf: Pointer to data buffer
+ * @len: Data buffer size
+ */
+void rkmtd_rc4(u8 *buf, u32 len);
+
+/**
+ * struct rkmtd_ops - operations supported by UCLASS_RKMTD
+ */
+struct rkmtd_ops {
+ /**
+ * @attach_mtd: - Attach a new rkmtd driver to the device structure
+ *
+ * @attach_mtd.dev: Device to update
+ * @attach_mtd.Returns: 0 if OK, -EEXIST if a driver is already attached,
+ * other -ve on other error
+ */
+ int (*attach_mtd)(struct udevice *dev);
+
+ /**
+ * @detach_mtd: - Detach a rkmtd driver from the device structure
+ *
+ * @detach_mtd.dev: Device to detach from
+ * @detach_mtd.Returns: 0 if OK, -ENOENT if no driver is attached,
+ * other -ve on other error
+ */
+ int (*detach_mtd)(struct udevice *dev);
+};
+
+#define rkmtd_get_ops(dev) ((struct rkmtd_ops *)(dev)->driver->ops)
+
+/**
+ * rkmtd_get_cur_dev() - Get the current device
+ *
+ * Returns current device, or NULL if none
+ */
+struct udevice *rkmtd_get_cur_dev(void);
+
+/**
+ * rkmtd_set_cur_dev() - Set the current device
+ *
+ * Sets the current device, or clears it if @dev is NULL
+ *
+ * @dev: Device to set as the current one
+ */
+void rkmtd_set_cur_dev(struct udevice *dev);
+
+/**
+ * rkmtd_find_by_label() - Find a rkmtd device by label
+ *
+ * Searches all rkmtd devices to find one with the given label
+ *
+ * @label: Label to find
+ * Returns: associated device, or NULL if not found
+ */
+struct udevice *rkmtd_find_by_label(const char *label);
+
+/**
+ * rkmtd_attach() - Attach a new rkmtd driver to the device structure
+ *
+ * @dev: Device to update
+ * Returns: 0 if OK, -EEXIST if a file is already attached, other -ve on
+ * other error
+ */
+int rkmtd_attach(struct udevice *dev);
+
+/**
+ * rkmtd_detach() - Detach a rkmtd driver from the device structure
+ *
+ * @dev: Device to detach from
+ * Returns: 0 if OK, -ENOENT if no file is attached, other -ve on other
+ * error
+ */
+int rkmtd_detach(struct udevice *dev);
+
+/**
+ * rkmtd_create_device() - Create a new rkmtd device
+ *
+ * Any existing device with the same label is removed and unbound first
+ *
+ * @label: Label of the attachment, e.g. "test1"
+ * @devp: Returns the device created, on success
+ * Returns: 0 if OK, -ve on error
+ */
+int rkmtd_create_device(const char *label, struct udevice **devp);
+
+/**
+ * rkmtd_create_attach_mtd() - Create a new rkmtd device and attach driver
+ *
+ * @label: Label of the attachment, e.g. "test1"
+ * @devp: Returns the device created, on success
+ * Returns: 0 if OK, -ve on error
+ */
+int rkmtd_create_attach_mtd(const char *label, struct udevice **devp);
+
+#endif /* __RKMTD__ */
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 02c651a786..cb82d839f8 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_REMOTEPROC) += remoteproc.o
obj-$(CONFIG_DM_RESET) += reset.o
obj-$(CONFIG_SYSRESET) += sysreset.o
obj-$(CONFIG_DM_REGULATOR) += regulator.o
+obj-$(CONFIG_CMD_RKMTD) += rkmtd.o
obj-$(CONFIG_DM_RNG) += rng.o
obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o
diff --git a/test/dm/rkmtd.c b/test/dm/rkmtd.c
new file mode 100644
index 0000000000..3c3e8efa92
--- /dev/null
+++ b/test/dm/rkmtd.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Test derived from:
+ * /test/dm/host.c
+ * Copyright 2022 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * Copyright (C) 2023 Johan Jonker <jbx6244@gmail.com>
+ */
+
+#include <common.h>
+#include <blk.h>
+#include <dm.h>
+#include <fs.h>
+#include <rkmtd.h>
+#include <asm/test.h>
+#include <dm/device-internal.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+#define RW_BUF_SIZE 12 * 512
+
+/* Basic test of the RKMTD interface */
+static int dm_test_rkmtd(struct unit_test_state *uts)
+{
+ struct udevice *dev, *part, *chk, *blk;
+ char write[RW_BUF_SIZE], read[RW_BUF_SIZE];
+ static const char label[] = "test";
+ struct rkmtd_dev *plat;
+ struct blk_desc *desc;
+ struct sector0 *sec0;
+ int i;
+
+ ut_asserteq(-ENODEV, uclass_first_device_err(UCLASS_RKMTD, &dev));
+ ut_asserteq(-ENODEV, uclass_first_device_err(UCLASS_PARTITION, &part));
+
+ ut_assertok(rkmtd_create_device(label, &dev));
+
+ /* Check that the plat data has been allocated */
+ plat = dev_get_plat(dev);
+ ut_asserteq_str("test", plat->label);
+ ut_assert(label != plat->label);
+
+ /* Attach RKMTD driver */
+ ut_assertok(rkmtd_attach(dev));
+ ut_assertok(uclass_first_device_err(UCLASS_RKMTD, &chk));
+ ut_asserteq_ptr(chk, dev);
+
+ /* Get RKMTD block device */
+ ut_assertok(blk_get_from_parent(dev, &blk));
+ ut_assertok(device_probe(blk));
+
+ /* There should be a GPT partition table in this device */
+ ut_asserteq(0, uclass_first_device_err(UCLASS_PARTITION, &part));
+
+ /* Write a boot block and verify that we get the same data back */
+ desc = dev_get_uclass_plat(blk);
+ ut_asserteq(true, desc->removable);
+ ut_asserteq(LBA, desc->lba);
+
+ memset(write, '\0', BLK_SIZE);
+
+ for (i = BLK_SIZE; i < sizeof(write); i++)
+ write[i] = i;
+
+ sec0 = (struct sector0 *)write;
+ sec0->magic = 0x0FF0AA55;
+ sec0->rc4_flag = 0;
+ sec0->boot_code1_offset = 4;
+ sec0->boot_code2_offset = 4;
+ sec0->flash_data_size = 4;
+ sec0->flash_boot_size = 8;
+
+ rkmtd_rc4(write, 512);
+ ut_asserteq(RK_TAG, sec0->magic);
+
+ ut_asserteq(12, blk_dwrite(desc, 64, 12, write));
+ ut_asserteq(12, blk_dread(desc, 64, 12, read));
+ ut_asserteq_mem(write, read, RW_BUF_SIZE);
+
+ ut_assertok(rkmtd_detach(dev));
+
+ ut_asserteq(-ENODEV, blk_get_from_parent(dev, &blk));
+ ut_assertok(device_unbind(dev));
+
+ return 0;
+}
+DM_TEST(dm_test_rkmtd, UT_TESTF_SCAN_FDT);
+
+/* Reusing the same label should work */
+static int dm_test_rkmtd_dup(struct unit_test_state *uts)
+{
+ static const char label[] = "test";
+ struct udevice *dev, *chk;
+
+ /* Create a RKMTD device with label "test" */
+ ut_asserteq(0, uclass_id_count(UCLASS_RKMTD));
+ ut_assertok(rkmtd_create_device(label, &dev));
+ ut_assertok(rkmtd_attach(dev));
+ ut_assertok(uclass_first_device_err(UCLASS_RKMTD, &chk));
+ ut_asserteq_ptr(chk, dev);
+ ut_asserteq(1, uclass_id_count(UCLASS_RKMTD));
+
+ /* Create another device with the same label (should remove old one) */
+ ut_assertok(rkmtd_create_device(label, &dev));
+ ut_assertok(rkmtd_attach(dev));
+ ut_assertok(uclass_first_device_err(UCLASS_RKMTD, &chk));
+ ut_asserteq_ptr(chk, dev);
+
+ /* Make sure there is still only one device */
+ ut_asserteq(1, uclass_id_count(UCLASS_RKMTD));
+
+ return 0;
+}
+DM_TEST(dm_test_rkmtd_dup, UT_TESTF_SCAN_FDT);
+
+/* Basic test of the 'rkmtd' command */
+static int dm_test_rkmtd_cmd(struct unit_test_state *uts)
+{
+ struct udevice *dev, *blk;
+ struct blk_desc *desc;
+
+ /* First check 'rkmtd info' with binding */
+ ut_assertok(run_command("rkmtd info", 0));
+ ut_assert_nextline("dev blocks label ");
+ ut_assert_console_end();
+
+ /* Bind device 1 */
+ ut_assertok(run_commandf("rkmtd bind test1"));
+ ut_assertok(uclass_first_device_err(UCLASS_RKMTD, &dev));
+ ut_assertok(blk_get_from_parent(dev, &blk));
+ desc = dev_get_uclass_plat(blk);
+
+ ut_assertok(run_command("rkmtd info", 0));
+ ut_assert_nextline("dev blocks label ");
+ ut_assert_nextline(" 0 609 test1 ");
+ ut_assert_console_end();
+
+ /* Bind device 2 */
+ ut_assertok(run_commandf("rkmtd bind test2"));
+ ut_assertok(uclass_next_device_err(&dev));
+ ut_assertok(blk_get_from_parent(dev, &blk));
+ desc = dev_get_uclass_plat(blk);
+
+ ut_assertok(run_command("rkmtd info", 0));
+ ut_assert_nextline("dev blocks label ");
+ ut_assert_nextline(" 0 609 test1 ");
+ ut_assert_nextline(" 1 609 test2 ");
+ ut_assert_console_end();
+
+ ut_asserteq(1, run_command("rkmtd info test", 0));
+ ut_assert_nextline("No such device 'test'");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("rkmtd info test2", 0));
+ ut_assert_nextline("dev blocks label ");
+ ut_assert_nextline(" 1 609 test2 ");
+ ut_assert_console_end();
+
+ /* Check 'rkmtd dev' */
+ ut_asserteq(1, run_command("rkmtd dev", 0));
+ ut_assert_nextline("No current rkmtd device");
+ ut_assert_console_end();
+
+ ut_asserteq(1, run_command("rkmtd dev missing", 0));
+ ut_assert_nextline("No such device 'missing'");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("rkmtd dev test2", 0));
+ ut_assert_console_end();
+
+ ut_assertok(run_command("rkmtd dev", 0));
+ ut_assert_nextline("Current rkmtd device: 1: test2");
+ ut_assert_console_end();
+
+ /* Try a numerical label */
+ ut_assertok(run_command("rkmtd dev 0", 0));
+ ut_assert_console_end();
+
+ ut_assertok(run_command("rkmtd dev", 0));
+ ut_assert_nextline("Current rkmtd device: 0: test1");
+ ut_assert_console_end();
+
+ /* Remove one of the bindings */
+ ut_assertok(run_commandf("rkmtd unbind test1"));
+
+ /* There should now be no current device */
+ ut_asserteq(1, run_command("rkmtd dev", 0));
+ ut_assert_nextline("No current rkmtd device");
+ ut_assert_console_end();
+
+ ut_assertok(run_command("rkmtd info", 0));
+ ut_assert_nextline("dev blocks label ");
+ ut_assert_nextline(" 1 609 test2 ");
+ ut_assert_console_end();
+
+ return 0;
+}
+DM_TEST(dm_test_rkmtd_cmd, UT_TESTF_SCAN_FDT | UT_TESTF_CONSOLE_REC);