u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices
@ 2023-01-05 15:34 Chris Morgan
  2023-01-05 15:34 ` [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux Chris Morgan
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Chris Morgan @ 2023-01-05 15:34 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan

From: Chris Morgan <macromorgan@hotmail.com>

This series is to lay the groundwork to improve support for the RK3566
based devices. This syncs the devicetrees with upstream Linux and adds
support for the pin controller of the rk356x series.

Future patches will be submitted that builds on top of this to support
devices such as the Anbernic RG353 and RG503 which are based on the
RK3566.

Chris Morgan (5):
  rockchip: vop2: Add vop2 dt-binding from Linux
  arm64: dts: rockchip: Sync rk356x from Linux main
  rockchip: rk3568: add boot device detection
  rockchip: rk3568: enable automatic power savings
  gpio/rockchip: rk_gpio support v2 gpio controller

 arch/arm/dts/Makefile                         |   2 +-
 arch/arm/dts/rk3568-evb.dts                   |  79 --
 arch/arm/dts/rk3568-evb1-v10.dts              | 692 ++++++++++++++++++
 arch/arm/dts/rk3568.dtsi                      | 122 +++
 arch/arm/dts/rk356x.dtsi                      | 182 ++++-
 arch/arm/include/asm/arch-rockchip/gpio.h     |  38 +
 arch/arm/mach-rockchip/rk3568/rk3568.c        |  31 +
 configs/evb-rk3568_defconfig                  |   4 +-
 drivers/gpio/Kconfig                          |  13 +
 drivers/gpio/rk_gpio.c                        | 103 ++-
 drivers/pinctrl/rockchip/Makefile             |   1 +
 drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++
 .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
 drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
 include/dt-bindings/soc/rockchip,vop2.h       |  14 +
 15 files changed, 1665 insertions(+), 123 deletions(-)
 delete mode 100644 arch/arm/dts/rk3568-evb.dts
 create mode 100644 arch/arm/dts/rk3568-evb1-v10.dts
 create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c
 create mode 100644 include/dt-bindings/soc/rockchip,vop2.h

-- 
2.34.1


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux
  2023-01-05 15:34 [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices Chris Morgan
@ 2023-01-05 15:34 ` Chris Morgan
  2023-01-17  2:07   ` Kever Yang
  2023-01-05 15:34 ` [PATCH 2/5] arm64: dts: rockchip: Sync rk356x from Linux main Chris Morgan
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Chris Morgan @ 2023-01-05 15:34 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan

From: Chris Morgan <macromorgan@hotmail.com>

In order to support Rockchip devices with the VOP2, import the VOP2
dt-bindings from Linux.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
 include/dt-bindings/soc/rockchip,vop2.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 include/dt-bindings/soc/rockchip,vop2.h

diff --git a/include/dt-bindings/soc/rockchip,vop2.h b/include/dt-bindings/soc/rockchip,vop2.h
new file mode 100644
index 0000000000..6e66a802b9
--- /dev/null
+++ b/include/dt-bindings/soc/rockchip,vop2.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+
+#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H
+#define __DT_BINDINGS_ROCKCHIP_VOP2_H
+
+#define ROCKCHIP_VOP2_EP_RGB0	1
+#define ROCKCHIP_VOP2_EP_HDMI0	2
+#define ROCKCHIP_VOP2_EP_EDP0	3
+#define ROCKCHIP_VOP2_EP_MIPI0	4
+#define ROCKCHIP_VOP2_EP_LVDS0	5
+#define ROCKCHIP_VOP2_EP_MIPI1	6
+#define ROCKCHIP_VOP2_EP_LVDS1	7
+
+#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/5] arm64: dts: rockchip: Sync rk356x from Linux main
  2023-01-05 15:34 [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices Chris Morgan
  2023-01-05 15:34 ` [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux Chris Morgan
@ 2023-01-05 15:34 ` Chris Morgan
  2023-01-09 22:34   ` Johan Jonker
  2023-01-05 15:34 ` [PATCH 3/5] rockchip: rk3568: add boot device detection Chris Morgan
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Chris Morgan @ 2023-01-05 15:34 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan

From: Chris Morgan <macromorgan@hotmail.com>

Sync rk3566 and rk3568 from the mainline Linux kernel (6.2-rc2 as of
this writing).

Note that this will rename the rk3568-evb to rk3568-evb1-v10.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
 arch/arm/dts/Makefile            |   2 +-
 arch/arm/dts/rk3568-evb.dts      |  79 ----
 arch/arm/dts/rk3568-evb1-v10.dts | 692 +++++++++++++++++++++++++++++++
 arch/arm/dts/rk3568.dtsi         | 122 ++++++
 arch/arm/dts/rk356x.dtsi         | 182 +++++++-
 configs/evb-rk3568_defconfig     |   4 +-
 6 files changed, 985 insertions(+), 96 deletions(-)
 delete mode 100644 arch/arm/dts/rk3568-evb.dts
 create mode 100644 arch/arm/dts/rk3568-evb1-v10.dts

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 43951a7731..e1d8866bbf 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -164,7 +164,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
 	rk3399pro-rock-pi-n10.dtb
 
 dtb-$(CONFIG_ROCKCHIP_RK3568) += \
-	rk3568-evb.dtb
+	rk3568-evb1-v10.dtb
 
 dtb-$(CONFIG_ROCKCHIP_RV1108) += \
 	rv1108-elgin-r1.dtb \
diff --git a/arch/arm/dts/rk3568-evb.dts b/arch/arm/dts/rk3568-evb.dts
deleted file mode 100644
index 6978655709..0000000000
--- a/arch/arm/dts/rk3568-evb.dts
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
- *
- */
-
-/dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/pinctrl/rockchip.h>
-#include "rk3568.dtsi"
-
-/ {
-	model = "Rockchip RK3568 EVB1 DDR4 V10 Board";
-	compatible = "rockchip,rk3568-evb1-v10", "rockchip,rk3568";
-
-	chosen: chosen {
-		stdout-path = "serial2:1500000n8";
-	};
-
-	dc_12v: dc-12v {
-		compatible = "regulator-fixed";
-		regulator-name = "dc_12v";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <12000000>;
-		regulator-max-microvolt = <12000000>;
-	};
-
-	vcc3v3_sys: vcc3v3-sys {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc3v3_sys";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
-		vin-supply = <&dc_12v>;
-	};
-
-	vcc5v0_sys: vcc5v0-sys {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_sys";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-		vin-supply = <&dc_12v>;
-	};
-
-	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc3v3_lcd0_n";
-		regulator-boot-on;
-
-		regulator-state-mem {
-			regulator-off-in-suspend;
-		};
-	};
-
-	vcc3v3_lcd1_n: vcc3v3-lcd1-n {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc3v3_lcd1_n";
-		regulator-boot-on;
-
-		regulator-state-mem {
-			regulator-off-in-suspend;
-		};
-	};
-};
-
-&sdhci {
-	bus-width = <8>;
-	max-frequency = <200000000>;
-	non-removable;
-	status = "okay";
-};
-
-&uart2 {
-	status = "okay";
-};
diff --git a/arch/arm/dts/rk3568-evb1-v10.dts b/arch/arm/dts/rk3568-evb1-v10.dts
new file mode 100644
index 0000000000..674792567f
--- /dev/null
+++ b/arch/arm/dts/rk3568-evb1-v10.dts
@@ -0,0 +1,692 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3568.dtsi"
+
+/ {
+	model = "Rockchip RK3568 EVB1 DDR4 V10 Board";
+	compatible = "rockchip,rk3568-evb1-v10", "rockchip,rk3568";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdmmc0;
+		mmc1 = &sdhci;
+	};
+
+	chosen: chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led_work: led-0 {
+			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
+			function = LED_FUNCTION_HEARTBEAT;
+			color = <LED_COLOR_ID_BLUE>;
+			linux,default-trigger = "heartbeat";
+			pinctrl-names = "default";
+			pinctrl-0 = <&led_work_en>;
+		};
+	};
+
+	rk809-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,name = "Analog RK809";
+		simple-audio-card,mclk-fs = <256>;
+
+		simple-audio-card,cpu {
+			sound-dai = <&i2s1_8ch>;
+		};
+		simple-audio-card,codec {
+			sound-dai = <&rk809>;
+		};
+	};
+
+	vcc3v3_sys: vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	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 = <&dc_12v>;
+	};
+
+	vcc5v0_usb_host: vcc5v0-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_host_en>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc5v0_usb_otg: vcc5v0-usb-otg {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_otg_en>;
+		regulator-name = "vcc5v0_usb_otg";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
+	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_lcd0_n";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd0_n_en>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	vcc3v3_lcd1_n: vcc3v3-lcd1-n {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_lcd1_n";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd1_n_en>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+};
+
+&combphy0 {
+	status = "okay";
+};
+
+&combphy1 {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&gmac0 {
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii-id";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+	status = "okay";
+};
+
+&gmac1 {
+	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
+	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>;
+	assigned-clock-rates = <0>, <125000000>;
+	clock_in_out = "output";
+	phy-handle = <&rgmii_phy1>;
+	phy-mode = "rgmii-id";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac1m1_miim
+		     &gmac1m1_tx_bus2
+		     &gmac1m1_rx_bus2
+		     &gmac1m1_rgmii_clk
+		     &gmac1m1_rgmii_bus>;
+	status = "okay";
+};
+
+&gpu {
+	mali-supply = <&vdd_gpu>;
+	status = "okay";
+};
+
+&hdmi {
+	avdd-0v9-supply = <&vdda0v9_image>;
+	avdd-1v8-supply = <&vcca1v8_image>;
+	status = "okay";
+};
+
+&hdmi_in {
+	hdmi_in_vp0: endpoint {
+		remote-endpoint = <&vp0_out_hdmi>;
+	};
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&hdmi_sound {
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	vdd_cpu: regulator@1c {
+		compatible = "tcs,tcs4525";
+		reg = <0x1c>;
+		fcs,suspend-voltage-selector = <1>;
+		regulator-name = "vdd_cpu";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <800000>;
+		regulator-max-microvolt = <1150000>;
+		regulator-ramp-delay = <2300>;
+		vin-supply = <&vcc5v0_sys>;
+
+		regulator-state-mem {
+			regulator-off-in-suspend;
+		};
+	};
+
+	rk809: pmic@20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		#clock-cells = <1>;
+		clock-names = "mclk";
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>;
+		rockchip,system-power-controller;
+		#sound-dai-cells = <0>;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-always-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				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>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				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>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+
+		codec {
+			mic-in-differential;
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	touchscreen0: goodix@14 {
+		compatible = "goodix,gt1151";
+		reg = <0x14>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB5 IRQ_TYPE_EDGE_FALLING>;
+		AVDD28-supply = <&vcc3v3_lcd0_n>;
+		irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touch_int &touch_rst>;
+		reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+		VDDIO-supply = <&vcc3v3_lcd0_n>;
+	};
+};
+
+&i2s0_8ch {
+	status = "okay";
+};
+
+&i2s1_8ch {
+	rockchip,trcm-sync-tx-only;
+	status = "okay";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&mdio1 {
+	rgmii_phy1: ethernet-phy@0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+		reset-assert-us = <20000>;
+		reset-deassert-us = <100000>;
+		reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pinctrl {
+	display {
+		vcc3v3_lcd0_n_en: vcc3v3_lcd0_n_en {
+			rockchip,pins = <0 RK_PC7 0 &pcfg_pull_none>;
+		};
+		vcc3v3_lcd1_n_en: vcc3v3_lcd1_n_en {
+			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+		};
+	};
+
+	leds {
+		led_work_en: led_work_en {
+			rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	touchscreen {
+		touch_int: touch_int {
+			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+		touch_rst: touch_rst {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	usb {
+		vcc5v0_usb_host_en: vcc5v0_usb_host_en {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		vcc5v0_usb_otg_en: vcc5v0_usb_otg_en {
+			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_1v8>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	status = "okay";
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <1>;
+	rockchip,hw-tshut-polarity = <0>;
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host0_xhci {
+	extcon = <&usb2phy0>;
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb_host1_xhci {
+	status = "okay";
+};
+
+&usb2phy0 {
+	status = "okay";
+};
+
+&usb2phy0_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy0_otg {
+	phy-supply = <&vcc5v0_usb_otg>;
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&vop {
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&vp0 {
+	vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+		remote-endpoint = <&hdmi_in_vp0>;
+	};
+};
diff --git a/arch/arm/dts/rk3568.dtsi b/arch/arm/dts/rk3568.dtsi
index 2bdf8c7e97..ba67b58f05 100644
--- a/arch/arm/dts/rk3568.dtsi
+++ b/arch/arm/dts/rk3568.dtsi
@@ -42,6 +42,128 @@
 		reg = <0x0 0xfe190200 0x0 0x20>;
 	};
 
+	pcie30_phy_grf: syscon@fdcb8000 {
+		compatible = "rockchip,rk3568-pcie3-phy-grf", "syscon";
+		reg = <0x0 0xfdcb8000 0x0 0x10000>;
+	};
+
+	pcie30phy: phy@fe8c0000 {
+		compatible = "rockchip,rk3568-pcie3-phy";
+		reg = <0x0 0xfe8c0000 0x0 0x20000>;
+		#phy-cells = <0>;
+		clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>,
+			 <&cru PCLK_PCIE30PHY>;
+		clock-names = "refclk_m", "refclk_n", "pclk";
+		resets = <&cru SRST_PCIE30PHY>;
+		reset-names = "phy";
+		rockchip,phy-grf = <&pcie30_phy_grf>;
+		status = "disabled";
+	};
+
+	pcie3x1: pcie@fe270000 {
+		compatible = "rockchip,rk3568-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		bus-range = <0x0 0xf>;
+		clocks = <&cru ACLK_PCIE30X1_MST>, <&cru ACLK_PCIE30X1_SLV>,
+			 <&cru ACLK_PCIE30X1_DBI>, <&cru PCLK_PCIE30X1>,
+			 <&cru CLK_PCIE30X1_AUX_NDFT>;
+		clock-names = "aclk_mst", "aclk_slv",
+			      "aclk_dbi", "pclk", "aux";
+		device_type = "pci";
+		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie3x1_intc 0>,
+				<0 0 0 2 &pcie3x1_intc 1>,
+				<0 0 0 3 &pcie3x1_intc 2>,
+				<0 0 0 4 &pcie3x1_intc 3>;
+		linux,pci-domain = <1>;
+		num-ib-windows = <6>;
+		num-ob-windows = <2>;
+		max-link-speed = <3>;
+		msi-map = <0x0 &gic 0x1000 0x1000>;
+		num-lanes = <1>;
+		phys = <&pcie30phy>;
+		phy-names = "pcie-phy";
+		power-domains = <&power RK3568_PD_PIPE>;
+		reg = <0x3 0xc0400000 0x0 0x00400000>,
+		      <0x0 0xfe270000 0x0 0x00010000>,
+		      <0x3 0x7f000000 0x0 0x01000000>;
+		ranges = <0x01000000 0x0 0x3ef00000 0x3 0x7ef00000 0x0 0x00100000>,
+			 <0x02000000 0x0 0x00000000 0x3 0x40000000 0x0 0x3ef00000>;
+		reg-names = "dbi", "apb", "config";
+		resets = <&cru SRST_PCIE30X1_POWERUP>;
+		reset-names = "pipe";
+		/* bifurcation; lane1 when using 1+1 */
+		status = "disabled";
+
+		pcie3x1_intc: legacy-interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>;
+		};
+	};
+
+	pcie3x2: pcie@fe280000 {
+		compatible = "rockchip,rk3568-pcie";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		bus-range = <0x0 0xf>;
+		clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>,
+			 <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>,
+			 <&cru CLK_PCIE30X2_AUX_NDFT>;
+		clock-names = "aclk_mst", "aclk_slv",
+			      "aclk_dbi", "pclk", "aux";
+		device_type = "pci";
+		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "sys", "pmc", "msg", "legacy", "err";
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
+				<0 0 0 2 &pcie3x2_intc 1>,
+				<0 0 0 3 &pcie3x2_intc 2>,
+				<0 0 0 4 &pcie3x2_intc 3>;
+		linux,pci-domain = <2>;
+		num-ib-windows = <6>;
+		num-ob-windows = <2>;
+		max-link-speed = <3>;
+		msi-map = <0x0 &gic 0x2000 0x1000>;
+		num-lanes = <2>;
+		phys = <&pcie30phy>;
+		phy-names = "pcie-phy";
+		power-domains = <&power RK3568_PD_PIPE>;
+		reg = <0x3 0xc0800000 0x0 0x00400000>,
+		      <0x0 0xfe280000 0x0 0x00010000>,
+		      <0x3 0xbf000000 0x0 0x01000000>;
+		ranges = <0x01000000 0x0 0x3ef00000 0x3 0xbef00000 0x0 0x00100000>,
+			 <0x02000000 0x0 0x00000000 0x3 0x80000000 0x0 0x3ef00000>;
+		reg-names = "dbi", "apb", "config";
+		resets = <&cru SRST_PCIE30X2_POWERUP>;
+		reset-names = "pipe";
+		/* bifurcation; lane0 when using 1+1 */
+		status = "disabled";
+
+		pcie3x2_intc: legacy-interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
+		};
+	};
+
 	gmac0: ethernet@fe2a0000 {
 		compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a";
 		reg = <0x0 0xfe2a0000 0x0 0x10000>;
diff --git a/arch/arm/dts/rk356x.dtsi b/arch/arm/dts/rk356x.dtsi
index 319981c3e9..5706c3e24f 100644
--- a/arch/arm/dts/rk356x.dtsi
+++ b/arch/arm/dts/rk356x.dtsi
@@ -592,6 +592,46 @@
 		status = "disabled";
 	};
 
+	vpu: video-codec@fdea0400 {
+		compatible = "rockchip,rk3568-vpu";
+		reg = <0x0 0xfdea0000 0x0 0x800>;
+		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		clock-names = "aclk", "hclk";
+		iommus = <&vdpu_mmu>;
+		power-domains = <&power RK3568_PD_VPU>;
+	};
+
+	vdpu_mmu: iommu@fdea0800 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfdea0800 0x0 0x40>;
+		interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "aclk", "iface";
+		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+		power-domains = <&power RK3568_PD_VPU>;
+		#iommu-cells = <0>;
+	};
+
+	vepu: video-codec@fdee0000 {
+		compatible = "rockchip,rk3568-vepu";
+		reg = <0x0 0xfdee0000 0x0 0x800>;
+		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_JENC>, <&cru HCLK_JENC>;
+		clock-names = "aclk", "hclk";
+		iommus = <&vepu_mmu>;
+		power-domains = <&power RK3568_PD_RGA>;
+	};
+
+	vepu_mmu: iommu@fdee0800 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfdee0800 0x0 0x40>;
+		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_JENC>, <&cru HCLK_JENC>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power RK3568_PD_RGA>;
+		#iommu-cells = <0>;
+	};
+
 	sdmmc2: mmc@fe000000 {
 		compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc";
 		reg = <0x0 0xfe000000 0x0 0x4000>;
@@ -699,6 +739,62 @@
 		status = "disabled";
 	};
 
+	dsi0: dsi@fe060000 {
+		compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
+		reg = <0x00 0xfe060000 0x00 0x10000>;
+		interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "pclk", "hclk";
+		clocks = <&cru PCLK_DSITX_0>, <&cru HCLK_VO>;
+		phy-names = "dphy";
+		phys = <&dsi_dphy0>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_DSITX_0>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dsi0_in: port@0 {
+				reg = <0>;
+			};
+
+			dsi0_out: port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	dsi1: dsi@fe070000 {
+		compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
+		reg = <0x0 0xfe070000 0x0 0x10000>;
+		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "pclk", "hclk";
+		clocks = <&cru PCLK_DSITX_1>, <&cru HCLK_VO>;
+		phy-names = "dphy";
+		phys = <&dsi_dphy1>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_DSITX_1>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			dsi1_in: port@0 {
+				reg = <0>;
+			};
+
+			dsi1_out: port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	hdmi: hdmi@fe0a0000 {
 		compatible = "rockchip,rk3568-dw-hdmi";
 		reg = <0x0 0xfe0a0000 0x0 0x20000>;
@@ -953,20 +1049,6 @@
 		status = "disabled";
 	};
 
-	spdif: spdif@fe460000 {
-		compatible = "rockchip,rk3568-spdif";
-		reg = <0x0 0xfe460000 0x0 0x1000>;
-		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-		clock-names = "mclk", "hclk";
-		clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>;
-		dmas = <&dmac1 1>;
-		dma-names = "tx";
-		pinctrl-names = "default";
-		pinctrl-0 = <&spdifm0_tx>;
-		#sound-dai-cells = <0>;
-		status = "disabled";
-	};
-
 	i2s0_8ch: i2s@fe400000 {
 		compatible = "rockchip,rk3568-i2s-tdm";
 		reg = <0x0 0xfe400000 0x0 0x1000>;
@@ -1009,6 +1091,28 @@
 		status = "disabled";
 	};
 
+	i2s2_2ch: i2s@fe420000 {
+		compatible = "rockchip,rk3568-i2s-tdm";
+		reg = <0x0 0xfe420000 0x0 0x1000>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
+		assigned-clock-rates = <1188000000>;
+		clocks = <&cru MCLK_I2S2_2CH>, <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
+		clock-names = "mclk_tx", "mclk_rx", "hclk";
+		dmas = <&dmac1 4>, <&dmac1 5>;
+		dma-names = "tx", "rx";
+		resets = <&cru SRST_M_I2S2_2CH>;
+		reset-names = "m";
+		rockchip,grf = <&grf>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s2m0_sclktx
+				&i2s2m0_lrcktx
+				&i2s2m0_sdi
+				&i2s2m0_sdo>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
 	i2s3_2ch: i2s@fe430000 {
 		compatible = "rockchip,rk3568-i2s-tdm";
 		reg = <0x0 0xfe430000 0x0 0x1000>;
@@ -1046,6 +1150,20 @@
 		status = "disabled";
 	};
 
+	spdif: spdif@fe460000 {
+		compatible = "rockchip,rk3568-spdif";
+		reg = <0x0 0xfe460000 0x0 0x1000>;
+		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+		clock-names = "mclk", "hclk";
+		clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>;
+		dmas = <&dmac1 1>;
+		dma-names = "tx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spdifm0_tx>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
 	dmac0: dma-controller@fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
@@ -1594,6 +1712,42 @@
 		status = "disabled";
 	};
 
+	csi_dphy: phy@fe870000 {
+		compatible = "rockchip,rk3568-csi-dphy";
+		reg = <0x0 0xfe870000 0x0 0x10000>;
+		clocks = <&cru PCLK_MIPICSIPHY>;
+		clock-names = "pclk";
+		#phy-cells = <0>;
+		resets = <&cru SRST_P_MIPICSIPHY>;
+		reset-names = "apb";
+		rockchip,grf = <&grf>;
+		status = "disabled";
+	};
+
+	dsi_dphy0: mipi-dphy@fe850000 {
+		compatible = "rockchip,rk3568-dsi-dphy";
+		reg = <0x0 0xfe850000 0x0 0x10000>;
+		clock-names = "ref", "pclk";
+		clocks = <&pmucru CLK_MIPIDSIPHY0_REF>, <&cru PCLK_MIPIDSIPHY0>;
+		#phy-cells = <0>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_MIPIDSIPHY0>;
+		status = "disabled";
+	};
+
+	dsi_dphy1: mipi-dphy@fe860000 {
+		compatible = "rockchip,rk3568-dsi-dphy";
+		reg = <0x0 0xfe860000 0x0 0x10000>;
+		clock-names = "ref", "pclk";
+		clocks = <&pmucru CLK_MIPIDSIPHY1_REF>, <&cru PCLK_MIPIDSIPHY1>;
+		#phy-cells = <0>;
+		power-domains = <&power RK3568_PD_VO>;
+		reset-names = "apb";
+		resets = <&cru SRST_P_MIPIDSIPHY1>;
+		status = "disabled";
+	};
+
 	usb2phy0: usb2phy@fe8a0000 {
 		compatible = "rockchip,rk3568-usb2phy";
 		reg = <0x0 0xfe8a0000 0x0 0x10000>;
diff --git a/configs/evb-rk3568_defconfig b/configs/evb-rk3568_defconfig
index db3acf5be5..2e9891bb1b 100644
--- a/configs/evb-rk3568_defconfig
+++ b/configs/evb-rk3568_defconfig
@@ -6,7 +6,7 @@ CONFIG_TEXT_BASE=0x00a00000
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
 CONFIG_NR_DRAM_BANKS=2
-CONFIG_DEFAULT_DEVICE_TREE="rk3568-evb"
+CONFIG_DEFAULT_DEVICE_TREE="rk3568-evb1-v10"
 CONFIG_ROCKCHIP_RK3568=y
 CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
 CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
@@ -23,7 +23,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
 CONFIG_FIT=y
 CONFIG_FIT_VERBOSE=y
 CONFIG_SPL_LOAD_FIT=y
-CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-evb.dtb"
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-evb1-v10.dtb"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_SPL_MAX_SIZE=0x20000
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 3/5] rockchip: rk3568: add boot device detection
  2023-01-05 15:34 [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices Chris Morgan
  2023-01-05 15:34 ` [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux Chris Morgan
  2023-01-05 15:34 ` [PATCH 2/5] arm64: dts: rockchip: Sync rk356x from Linux main Chris Morgan
@ 2023-01-05 15:34 ` Chris Morgan
  2023-01-17  2:09   ` Kever Yang
  2023-01-05 15:34 ` [PATCH 4/5] rockchip: rk3568: enable automatic power savings Chris Morgan
  2023-01-05 15:34 ` [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller Chris Morgan
  4 siblings, 1 reply; 14+ messages in thread
From: Chris Morgan @ 2023-01-05 15:34 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan

From: Chris Morgan <macromorgan@hotmail.com>

Enable spl to detect which device it was booted from.

Adapted from Peter Geis's work located here:
https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/3a10fb6bfbbaa747b425233b1fc08cd008084281

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
 arch/arm/mach-rockchip/rk3568/rk3568.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-rockchip/rk3568/rk3568.c b/arch/arm/mach-rockchip/rk3568/rk3568.c
index 22eeb77d41..a2d59abc26 100644
--- a/arch/arm/mach-rockchip/rk3568/rk3568.c
+++ b/arch/arm/mach-rockchip/rk3568/rk3568.c
@@ -7,6 +7,7 @@
 #include <dm.h>
 #include <asm/armv8/mmu.h>
 #include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
 #include <asm/arch-rockchip/grf_rk3568.h>
 #include <asm/arch-rockchip/hardware.h>
 #include <dt-bindings/clock/rk3568-cru.h>
@@ -70,6 +71,12 @@ static struct mm_region rk3568_mem_map[] = {
 	}
 };
 
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+	[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe310000",
+	[BROM_BOOTSOURCE_SPINOR] = "/spi@fe300000/flash@0",
+	[BROM_BOOTSOURCE_SD] = "/mmc@fe2b0000",
+};
+
 struct mm_region *mem_map = rk3568_mem_map;
 
 void board_debug_uart_init(void)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 4/5] rockchip: rk3568: enable automatic power savings
  2023-01-05 15:34 [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices Chris Morgan
                   ` (2 preceding siblings ...)
  2023-01-05 15:34 ` [PATCH 3/5] rockchip: rk3568: add boot device detection Chris Morgan
@ 2023-01-05 15:34 ` Chris Morgan
  2023-01-05 15:34 ` [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller Chris Morgan
  4 siblings, 0 replies; 14+ messages in thread
From: Chris Morgan @ 2023-01-05 15:34 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan

From: Chris Morgan <macromorgan@hotmail.com>

This is adapted from Peter Geis's work located here:
https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/ec20b790adc41bb400e2c523cb35ffee14e223f4

It enables automatic clock gating on idle, disables the eDP phy by
default, and sets the core pvtpll ring length. It is reported this
lowers the temperature on at least one SoC by 7C.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
 arch/arm/mach-rockchip/rk3568/rk3568.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/mach-rockchip/rk3568/rk3568.c b/arch/arm/mach-rockchip/rk3568/rk3568.c
index a2d59abc26..4a08820a09 100644
--- a/arch/arm/mach-rockchip/rk3568/rk3568.c
+++ b/arch/arm/mach-rockchip/rk3568/rk3568.c
@@ -24,6 +24,16 @@
 #define SGRF_SOC_CON4			0x10
 #define EMMC_HPROT_SECURE_CTRL		0x03
 #define SDMMC0_HPROT_SECURE_CTRL	0x01
+
+#define PMU_BASE_ADDR		0xfdd90000
+#define PMU_NOC_AUTO_CON0	(0x70)
+#define PMU_NOC_AUTO_CON1	(0x74)
+#define EDP_PHY_GRF_BASE	0xfdcb0000
+#define EDP_PHY_GRF_CON0	(EDP_PHY_GRF_BASE + 0x00)
+#define EDP_PHY_GRF_CON10	(EDP_PHY_GRF_BASE + 0x28)
+#define CPU_GRF_BASE		0xfdc30000
+#define GRF_CORE_PVTPLL_CON0	(0x10)
+
 /* PMU_GRF_GPIO0D_IOMUX_L */
 enum {
 	GPIO0D1_SHIFT		= 4,
@@ -98,6 +108,20 @@ void board_debug_uart_init(void)
 int arch_cpu_init(void)
 {
 #ifdef CONFIG_SPL_BUILD
+	/*
+	 * When perform idle operation, corresponding clock can
+	 * be opened or gated automatically.
+	 */
+	writel(0xffffffff, PMU_BASE_ADDR + PMU_NOC_AUTO_CON0);
+	writel(0x000f000f, PMU_BASE_ADDR + PMU_NOC_AUTO_CON1);
+
+	/* Disable eDP phy by default */
+	writel(0x00070007, EDP_PHY_GRF_CON10);
+	writel(0x0ff10ff1, EDP_PHY_GRF_CON0);
+
+	/* Set core pvtpll ring length */
+	writel(0x00ff002b, CPU_GRF_BASE + GRF_CORE_PVTPLL_CON0);
+
 	/* Set the emmc sdmmc0 to secure */
 	rk_clrreg(SGRF_BASE + SGRF_SOC_CON4, (EMMC_HPROT_SECURE_CTRL << 11
 		| SDMMC0_HPROT_SECURE_CTRL << 4));
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller
  2023-01-05 15:34 [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices Chris Morgan
                   ` (3 preceding siblings ...)
  2023-01-05 15:34 ` [PATCH 4/5] rockchip: rk3568: enable automatic power savings Chris Morgan
@ 2023-01-05 15:34 ` Chris Morgan
  2023-01-05 18:01   ` Quentin Schulz
  4 siblings, 1 reply; 14+ messages in thread
From: Chris Morgan @ 2023-01-05 15:34 UTC (permalink / raw)
  To: u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan

From: Chris Morgan <macromorgan@hotmail.com>

Add support for the newer GPIO controller used by the rk356x series,
as well as the pinctrl device for the rk356x series. The GPIOv2
controller has a write enable bit for some registers which differs
from the older versions of the GPIO controller.

Adapted from Peter Geis's gitlab located here:
https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
 arch/arm/include/asm/arch-rockchip/gpio.h     |  38 ++
 drivers/gpio/Kconfig                          |  13 +
 drivers/gpio/rk_gpio.c                        | 103 +++-
 drivers/pinctrl/rockchip/Makefile             |   1 +
 drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++++++++
 .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
 drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
 7 files changed, 635 insertions(+), 27 deletions(-)
 create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c

diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
index 1aaec5faec..29120ceaf3 100644
--- a/arch/arm/include/asm/arch-rockchip/gpio.h
+++ b/arch/arm/include/asm/arch-rockchip/gpio.h
@@ -6,6 +6,7 @@
 #ifndef _ASM_ARCH_GPIO_H
 #define _ASM_ARCH_GPIO_H
 
+#ifndef CONFIG_ROCKCHIP_GPIO_V2
 struct rockchip_gpio_regs {
 	u32 swport_dr;
 	u32 swport_ddr;
@@ -22,7 +23,44 @@ struct rockchip_gpio_regs {
 	u32 reserved1[(0x60 - 0x54) / 4];
 	u32 ls_sync;
 };
+
 check_member(rockchip_gpio_regs, ls_sync, 0x60);
+#else
+struct rockchip_gpio_regs {
+	u32 swport_dr_l;                        /* ADDRESS OFFSET: 0x0000 */
+	u32 swport_dr_h;                        /* ADDRESS OFFSET: 0x0004 */
+	u32 swport_ddr_l;                       /* ADDRESS OFFSET: 0x0008 */
+	u32 swport_ddr_h;                       /* ADDRESS OFFSET: 0x000c */
+	u32 int_en_l;                           /* ADDRESS OFFSET: 0x0010 */
+	u32 int_en_h;                           /* ADDRESS OFFSET: 0x0014 */
+	u32 int_mask_l;                         /* ADDRESS OFFSET: 0x0018 */
+	u32 int_mask_h;                         /* ADDRESS OFFSET: 0x001c */
+	u32 int_type_l;                         /* ADDRESS OFFSET: 0x0020 */
+	u32 int_type_h;                         /* ADDRESS OFFSET: 0x0024 */
+	u32 int_polarity_l;                     /* ADDRESS OFFSET: 0x0028 */
+	u32 int_polarity_h;                     /* ADDRESS OFFSET: 0x002c */
+	u32 int_bothedge_l;                     /* ADDRESS OFFSET: 0x0030 */
+	u32 int_bothedge_h;                     /* ADDRESS OFFSET: 0x0034 */
+	u32 debounce_l;                         /* ADDRESS OFFSET: 0x0038 */
+	u32 debounce_h;                         /* ADDRESS OFFSET: 0x003c */
+	u32 dbclk_div_en_l;                     /* ADDRESS OFFSET: 0x0040 */
+	u32 dbclk_div_en_h;                     /* ADDRESS OFFSET: 0x0044 */
+	u32 dbclk_div_con;                      /* ADDRESS OFFSET: 0x0048 */
+	u32 reserved004c;                       /* ADDRESS OFFSET: 0x004c */
+	u32 int_status;                         /* ADDRESS OFFSET: 0x0050 */
+	u32 reserved0054;                       /* ADDRESS OFFSET: 0x0054 */
+	u32 int_rawstatus;                      /* ADDRESS OFFSET: 0x0058 */
+	u32 reserved005c;                       /* ADDRESS OFFSET: 0x005c */
+	u32 port_eoi_l;                         /* ADDRESS OFFSET: 0x0060 */
+	u32 port_eoi_h;                         /* ADDRESS OFFSET: 0x0064 */
+	u32 reserved0068[2];                    /* ADDRESS OFFSET: 0x0068 */
+	u32 ext_port;                           /* ADDRESS OFFSET: 0x0070 */
+	u32 reserved0074;                       /* ADDRESS OFFSET: 0x0074 */
+	u32 ver_id;                             /* ADDRESS OFFSET: 0x0078 */
+};
+
+check_member(rockchip_gpio_regs, ver_id, 0x0078);
+#endif
 
 enum gpio_pu_pd {
 	GPIO_PULL_NORMAL = 0,
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ff87fbfb39..bd7422a0b3 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -340,6 +340,19 @@ config ROCKCHIP_GPIO
 	  The GPIOs for a device are defined in the device tree with one node
 	  for each bank.
 
+config ROCKCHIP_GPIO_V2
+	bool "Rockchip GPIO driver version 2.0"
+	depends on ROCKCHIP_GPIO
+	default n
+	help
+	  Support GPIO access on Rockchip SoCs. The GPIOs are arranged into
+	  a number of banks (different for each SoC type) each with 32 GPIOs.
+	  The GPIOs for a device are defined in the device tree with one node
+	  for each bank.
+
+	  Support version 2.0 GPIO controller, which support write enable bits
+	  for some registers, such as dr, ddr.
+
 config SANDBOX_GPIO
 	bool "Enable sandbox GPIO driver"
 	depends on SANDBOX && DM && DM_GPIO
diff --git a/drivers/gpio/rk_gpio.c b/drivers/gpio/rk_gpio.c
index 68f30157a9..6b195a39a1 100644
--- a/drivers/gpio/rk_gpio.c
+++ b/drivers/gpio/rk_gpio.c
@@ -2,12 +2,15 @@
 /*
  * (C) Copyright 2015 Google, Inc
  *
- * (C) Copyright 2008-2014 Rockchip Electronics
+ * (C) Copyright 2008-2020 Rockchip Electronics
  * Peter, Software Engineering, <superpeter.cai@gmail.com>.
+ * Jianqun Xu, Software Engineering, <jay.xu@rock-chips.com>.
  */
 
 #include <common.h>
 #include <dm.h>
+#include <dm/of_access.h>
+#include <dm/device_compat.h>
 #include <syscon.h>
 #include <linux/errno.h>
 #include <asm/gpio.h>
@@ -17,12 +20,34 @@
 #include <dm/pinctrl.h>
 #include <dt-bindings/clock/rk3288-cru.h>
 
-enum {
-	ROCKCHIP_GPIOS_PER_BANK		= 32,
-};
+#include "../pinctrl/rockchip/pinctrl-rockchip.h"
 
 #define OFFSET_TO_BIT(bit)	(1UL << (bit))
 
+#ifdef CONFIG_ROCKCHIP_GPIO_V2
+#define REG_L(R)	(R##_l)
+#define REG_H(R)	(R##_h)
+#define READ_REG(REG)	((readl(REG_L(REG)) & 0xFFFF) | \
+			((readl(REG_H(REG)) & 0xFFFF) << 16))
+#define WRITE_REG(REG, VAL)	\
+{\
+	writel(((VAL) & 0xFFFF) | 0xFFFF0000, REG_L(REG)); \
+	writel((((VAL) & 0xFFFF0000) >> 16) | 0xFFFF0000, REG_H(REG));\
+}
+
+#define CLRBITS_LE32(REG, MASK)	WRITE_REG(REG, READ_REG(REG) & ~(MASK))
+#define SETBITS_LE32(REG, MASK)	WRITE_REG(REG, READ_REG(REG) | (MASK))
+#define CLRSETBITS_LE32(REG, MASK, VAL)	WRITE_REG(REG, \
+				(READ_REG(REG) & ~(MASK)) | (VAL))
+
+#else
+#define READ_REG(REG)			readl(REG)
+#define WRITE_REG(REG, VAL)		writel(VAL, REG)
+#define CLRBITS_LE32(REG, MASK)		clrbits_le32(REG, MASK)
+#define SETBITS_LE32(REG, MASK)		setbits_le32(REG, MASK)
+#define CLRSETBITS_LE32(REG, MASK, VAL)	clrsetbits_le32(REG, MASK, VAL)
+#endif
+
 struct rockchip_gpio_priv {
 	struct rockchip_gpio_regs *regs;
 	struct udevice *pinctrl;
@@ -30,30 +55,33 @@ struct rockchip_gpio_priv {
 	char name[2];
 };
 
-static int rockchip_gpio_direction_input(struct udevice *dev, unsigned offset)
+static int rockchip_gpio_direction_input(struct udevice *dev,
+					 unsigned int offset)
 {
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
 	struct rockchip_gpio_regs *regs = priv->regs;
 
-	clrbits_le32(&regs->swport_ddr, OFFSET_TO_BIT(offset));
+	CLRBITS_LE32(&regs->swport_ddr, OFFSET_TO_BIT(offset));
 
 	return 0;
 }
 
-static int rockchip_gpio_direction_output(struct udevice *dev, unsigned offset,
+static int rockchip_gpio_direction_output(struct udevice *dev,
+					  unsigned int offset,
 					  int value)
 {
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
 	struct rockchip_gpio_regs *regs = priv->regs;
 	int mask = OFFSET_TO_BIT(offset);
 
-	clrsetbits_le32(&regs->swport_dr, mask, value ? mask : 0);
-	setbits_le32(&regs->swport_ddr, mask);
+	CLRSETBITS_LE32(&regs->swport_dr, mask, value ? mask : 0);
+	SETBITS_LE32(&regs->swport_ddr, mask);
 
 	return 0;
 }
 
-static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset)
+static int rockchip_gpio_get_value(struct udevice *dev,
+				   unsigned int offset)
 {
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
 	struct rockchip_gpio_regs *regs = priv->regs;
@@ -61,19 +89,20 @@ static int rockchip_gpio_get_value(struct udevice *dev, unsigned offset)
 	return readl(&regs->ext_port) & OFFSET_TO_BIT(offset) ? 1 : 0;
 }
 
-static int rockchip_gpio_set_value(struct udevice *dev, unsigned offset,
-				   int value)
+static int rockchip_gpio_set_value(struct udevice *dev,
+				   unsigned int offset, int value)
 {
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
 	struct rockchip_gpio_regs *regs = priv->regs;
 	int mask = OFFSET_TO_BIT(offset);
 
-	clrsetbits_le32(&regs->swport_dr, mask, value ? mask : 0);
+	CLRSETBITS_LE32(&regs->swport_dr, mask, value ? mask : 0);
 
 	return 0;
 }
 
-static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
+static int rockchip_gpio_get_function(struct udevice *dev,
+				      unsigned int offset)
 {
 #ifdef CONFIG_SPL_BUILD
 	return -ENODATA;
@@ -86,7 +115,7 @@ static int rockchip_gpio_get_function(struct udevice *dev, unsigned offset)
 	ret = pinctrl_get_gpio_mux(priv->pinctrl, priv->bank, offset);
 	if (ret)
 		return ret;
-	is_output = readl(&regs->swport_ddr) & OFFSET_TO_BIT(offset);
+	is_output = READ_REG(&regs->swport_ddr) & OFFSET_TO_BIT(offset);
 
 	return is_output ? GPIOF_OUTPUT : GPIOF_INPUT;
 #endif
@@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev)
 {
 	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
-	char *end;
-	int ret;
+	struct rockchip_pinctrl_priv *pctrl_priv;
+	struct rockchip_pin_bank *bank;
+	char *end = NULL;
+	static int gpio;
+	int id = -1, ret;
 
 	priv->regs = dev_read_addr_ptr(dev);
 	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
-	if (ret)
+	if (ret) {
+		dev_err(dev, "failed to get pinctrl device %d\n", ret);
 		return ret;
+	}
+
+	pctrl_priv = dev_get_priv(priv->pinctrl);
+	if (!pctrl_priv) {
+		dev_err(dev, "failed to get pinctrl priv\n");
+		return -EINVAL;
+	}
 
-	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
 	end = strrchr(dev->name, '@');
-	priv->bank = trailing_strtoln(dev->name, end);
-	priv->name[0] = 'A' + priv->bank;
-	uc_priv->bank_name = priv->name;
+	if (end)
+		id = trailing_strtoln(dev->name, end);
+	else
+		dev_read_alias_seq(dev, &id);
+
+	if (id < 0)
+		id = gpio++;
+
+	if (id >= pctrl_priv->ctrl->nr_banks) {
+		dev_err(dev, "bank id invalid\n");
+		return -EINVAL;
+	}
+
+	bank = &pctrl_priv->ctrl->pin_banks[id];
+	if (bank->bank_num != id) {
+		dev_err(dev, "bank id mismatch with pinctrl\n");
+		return -EINVAL;
+	}
+
+	priv->bank = bank->bank_num;
+	uc_priv->gpio_count = bank->nr_pins;
+	uc_priv->gpio_base = bank->pin_base;
+	uc_priv->bank_name = bank->name;
 
 	return 0;
 }
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 7d03f8101d..c78fc2c331 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o
 obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
 obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
 obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
+obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
 obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
new file mode 100644
index 0000000000..dce1c1e7ee
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+
+#include "pinctrl-rockchip.h"
+
+static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
+	/* CAN0 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)),
+	/* CAN0 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)),
+	/* CAN1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)),
+	/* CAN1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)),
+	/* CAN2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)),
+	/* CAN2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)),
+	/* EDPDP_HPDIN IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)),
+	/* EDPDP_HPDIN IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)),
+	/* GMAC1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)),
+	/* GMAC1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)),
+	/* HDMITX IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)),
+	/* HDMITX IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)),
+	/* I2C2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)),
+	/* I2C2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)),
+	/* I2C3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)),
+	/* I2C3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)),
+	/* I2C4 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)),
+	/* I2C4 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)),
+	/* I2C5 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)),
+	/* I2C5 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)),
+	/* PWM4 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)),
+	/* PWM4 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)),
+	/* PWM5 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)),
+	/* PWM5 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)),
+	/* PWM6 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)),
+	/* PWM6 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)),
+	/* PWM7 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)),
+	/* PWM7 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)),
+	/* PWM8 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)),
+	/* PWM8 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)),
+	/* PWM9 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)),
+	/* PWM9 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)),
+	/* PWM10 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)),
+	/* PWM10 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)),
+	/* PWM11 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)),
+	/* PWM11 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)),
+	/* PWM12 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)),
+	/* PWM12 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)),
+	/* PWM13 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)),
+	/* PWM13 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)),
+	/* PWM14 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)),
+	/* PWM14 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)),
+	/* PWM15 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)),
+	/* PWM15 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)),
+	/* SDMMC2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)),
+	/* SDMMC2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)),
+	/* SPI0 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)),
+	/* SPI0 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)),
+	/* SPI1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)),
+	/* SPI1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)),
+	/* SPI2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)),
+	/* SPI2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)),
+	/* SPI3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)),
+	/* SPI3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)),
+	/* UART1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)),
+	/* UART1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)),
+	/* UART2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)),
+	/* UART2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)),
+	/* UART3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)),
+	/* UART3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)),
+	/* UART4 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)),
+	/* UART4 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)),
+	/* UART5 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)),
+	/* UART5 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)),
+	/* UART6 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)),
+	/* UART6 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)),
+	/* UART7 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)),
+	/* UART7 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)),
+	/* UART7 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)),
+	/* UART8 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)),
+	/* UART8 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)),
+	/* UART9 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)),
+	/* UART9 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)),
+	/* UART9 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)),
+	/* I2S1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)),
+	/* I2S1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)),
+	/* I2S1 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)),
+	/* I2S2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)),
+	/* I2S2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)),
+	/* I2S3 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)),
+	/* I2S3 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)),
+	/* PDM IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)),
+	/* PDM IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)),
+	/* PCIE20 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)),
+	/* PCIE20 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)),
+	/* PCIE20 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)),
+	/* PCIE30X1 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)),
+	/* PCIE30X1 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)),
+	/* PCIE30X1 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)),
+	/* PCIE30X2 IO mux selection M0 */
+	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)),
+	/* PCIE30X2 IO mux selection M1 */
+	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)),
+	/* PCIE30X2 IO mux selection M2 */
+	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)),
+};
+
+static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+	int iomux_num = (pin / 8);
+	struct regmap *regmap;
+	int reg, ret, mask;
+	u8 bit;
+	u32 data;
+
+	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
+
+	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+		regmap = priv->regmap_pmu;
+	else
+		regmap = priv->regmap_base;
+
+	reg = bank->iomux[iomux_num].offset;
+	if ((pin % 8) >= 4)
+		reg += 0x4;
+	bit = (pin % 4) * 4;
+	mask = 0xf;
+
+	data = (mask << (bit + 16));
+	data |= (mux & mask) << bit;
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define RK3568_PULL_PMU_OFFSET		0x20
+#define RK3568_PULL_GRF_OFFSET		0x80
+#define RK3568_PULL_BITS_PER_PIN	2
+#define RK3568_PULL_PINS_PER_REG	8
+#define RK3568_PULL_BANK_STRIDE		0x10
+
+static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+					 int pin_num, struct regmap **regmap,
+					 int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *info = bank->priv;
+
+	if (bank->bank_num == 0) {
+		*regmap = info->regmap_pmu;
+		*reg = RK3568_PULL_PMU_OFFSET;
+		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
+	} else {
+		*regmap = info->regmap_base;
+		*reg = RK3568_PULL_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
+	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
+	*bit *= RK3568_PULL_BITS_PER_PIN;
+}
+
+#define RK3568_DRV_PMU_OFFSET		0x70
+#define RK3568_DRV_GRF_OFFSET		0x200
+#define RK3568_DRV_BITS_PER_PIN		8
+#define RK3568_DRV_PINS_PER_REG		2
+#define RK3568_DRV_BANK_STRIDE		0x40
+
+static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+					int pin_num, struct regmap **regmap,
+					int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *info = bank->priv;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*regmap = info->regmap_pmu;
+		*reg = RK3568_DRV_PMU_OFFSET;
+	} else {
+		*regmap = info->regmap_base;
+		*reg = RK3568_DRV_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
+	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
+	*bit *= RK3568_DRV_BITS_PER_PIN;
+}
+
+#define RK3568_SCHMITT_BITS_PER_PIN		2
+#define RK3568_SCHMITT_PINS_PER_REG		8
+#define RK3568_SCHMITT_BANK_STRIDE		0x10
+#define RK3568_SCHMITT_GRF_OFFSET		0xc0
+#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
+
+static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+					   int pin_num, struct regmap **regmap,
+					   int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *info = bank->priv;
+
+	if (bank->bank_num == 0) {
+		*regmap = info->regmap_pmu;
+		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
+	} else {
+		*regmap = info->regmap_base;
+		*reg = RK3568_SCHMITT_GRF_OFFSET;
+		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
+	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
+	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
+
+	return 0;
+}
+
+static int rk3568_set_pull(struct rockchip_pin_bank *bank,
+			   int pin_num, int pull)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u8 bit, type;
+	u32 data;
+
+	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+		return -EOPNOTSUPP;
+
+	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	type = bank->pull_type[pin_num / 8];
+	ret = rockchip_translate_pull_value(type, pull);
+	if (ret < 0) {
+		debug("unsupported pull setting %d\n", pull);
+		return ret;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+
+	data |= (ret << bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+static int rk3568_set_drive(struct rockchip_pin_bank *bank,
+			    int pin_num, int strength)
+{
+	struct regmap *regmap;
+	int reg;
+	u32 data;
+	u8 bit;
+	int drv = (1 << (strength + 1)) - 1;
+	int ret = 0;
+
+	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+	data |= (drv << bit);
+
+	ret = regmap_write(regmap, reg, data);
+	if (ret)
+		return ret;
+
+	if (bank->bank_num == 1 && pin_num == 21)
+		reg = 0x0840;
+	else if (bank->bank_num == 2 && pin_num == 2)
+		reg = 0x0844;
+	else if (bank->bank_num == 2 && pin_num == 8)
+		reg = 0x0848;
+	else if (bank->bank_num == 3 && pin_num == 0)
+		reg = 0x084c;
+	else if (bank->bank_num == 3 && pin_num == 6)
+		reg = 0x0850;
+	else if (bank->bank_num == 4 && pin_num == 0)
+		reg = 0x0854;
+	else
+		return 0;
+
+	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
+	data |= drv;
+
+	return regmap_write(regmap, reg, data);
+}
+
+static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
+			      int pin_num, int enable)
+{
+	struct regmap *regmap;
+	int reg;
+	u32 data;
+	u8 bit;
+
+	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
+	data |= (enable << bit);
+
+	return regmap_write(regmap, reg, data);
+}
+
+static struct rockchip_pin_bank rk3568_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
+			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT,
+			     IOMUX_WIDTH_4BIT),
+};
+
+static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
+	.pin_banks		= rk3568_pin_banks,
+	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
+	.nr_pins		= 160,
+	.grf_mux_offset		= 0x0,
+	.pmu_mux_offset		= 0x0,
+	.iomux_routes		= rk3568_mux_route_data,
+	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
+	.set_mux		= rk3568_set_mux,
+	.set_pull		= rk3568_set_pull,
+	.set_drive		= rk3568_set_drive,
+	.set_schmitt		= rk3568_set_schmitt,
+};
+
+static const struct udevice_id rk3568_pinctrl_ids[] = {
+	{
+		.compatible = "rockchip,rk3568-pinctrl",
+		.data = (ulong)&rk3568_pin_ctrl
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_rk3568) = {
+	.name		= "rockchip_rk3568_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= rk3568_pinctrl_ids,
+	.priv_auto = sizeof(struct rockchip_pinctrl_priv),
+	.ops		= &rockchip_pinctrl_ops,
+#if !IS_ENABLED(CONFIG_OF_PLATDATA)
+	.bind		= dm_scan_fdt_dev,
+#endif
+	.probe		= rockchip_pinctrl_probe,
+};
diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
index 630513ba3a..5f0016ff60 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
@@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
 	int prop_len, param;
 	const u32 *data;
 	ofnode node;
-#ifdef CONFIG_OF_LIVE
+#if CONFIG_IS_ENABLED(OF_LIVE)
 	const struct device_node *np;
 	struct property *pp;
 #else
@@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
 		node = ofnode_get_by_phandle(conf);
 		if (!ofnode_valid(node))
 			return -ENODEV;
-#ifdef CONFIG_OF_LIVE
+#if CONFIG_IS_ENABLED(OF_LIVE)
 		np = ofnode_to_np(node);
 		for (pp = np->properties; pp; pp = pp->next) {
 			prop_name = pp->name;
@@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
 
 			/* preset iomux offset value, set new start value */
 			if (iom->offset >= 0) {
-				if (iom->type & IOMUX_SOURCE_PMU)
+				if ((iom->type & IOMUX_SOURCE_PMU) || \
+				    (iom->type & IOMUX_L_SOURCE_PMU))
 					pmu_offs = iom->offset;
 				else
 					grf_offs = iom->offset;
 			} else { /* set current iomux offset */
-				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
-							pmu_offs : grf_offs;
+				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
+						(iom->type & IOMUX_L_SOURCE_PMU)) ?
+						pmu_offs : grf_offs;
 			}
 
 			/* preset drv offset value, set new start value */
diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h
index d969c20082..cfd636ce3a 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h
@@ -6,9 +6,13 @@
 #ifndef __DRIVERS_PINCTRL_ROCKCHIP_H
 #define __DRIVERS_PINCTRL_ROCKCHIP_H
 
+#include <dt-bindings/pinctrl/rockchip.h>
 #include <linux/bitops.h>
 #include <linux/types.h>
 
+#define RK_GENMASK_VAL(h, l, v) \
+	(GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & GENMASK((h), (l))))
+
 /**
  * Encode variants of iomux registers into a type variable
  */
@@ -18,6 +22,8 @@
 #define IOMUX_UNROUTED		BIT(3)
 #define IOMUX_WIDTH_3BIT	BIT(4)
 #define IOMUX_8WIDTH_2BIT	BIT(5)
+#define IOMUX_WRITABLE_32BIT	BIT(6)
+#define IOMUX_L_SOURCE_PMU	BIT(7)
 
 /**
  * Defined some common pins constants
@@ -62,6 +68,21 @@ enum rockchip_pin_pull_type {
 	PULL_TYPE_MAX
 };
 
+/**
+ * enum mux route register type, should be invalid/default/topgrf/pmugrf.
+ * INVALID: means do not need to set mux route
+ * DEFAULT: means same regmap as pin iomux
+ * TOPGRF: means mux route setting in topgrf
+ * PMUGRF: means mux route setting in pmugrf
+ */
+enum rockchip_pin_route_type {
+	ROUTE_TYPE_DEFAULT = 0,
+	ROUTE_TYPE_TOPGRF = 1,
+	ROUTE_TYPE_PMUGRF = 2,
+
+	ROUTE_TYPE_INVALID = -1,
+};
+
 /**
  * @drv_type: drive strength variant using rockchip_perpin_drv_type
  * @offset: if initialized to -1 it will be autocalculated, by specifying
@@ -220,6 +241,25 @@ struct rockchip_pin_bank {
 		.pull_type[3] = pull3,					\
 	}
 
+#define PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, FLAG)		\
+	{								\
+		.bank_num	= ID,					\
+		.pin		= PIN,					\
+		.func		= FUNC,					\
+		.route_offset	= REG,					\
+		.route_val	= VAL,					\
+		.route_type	= FLAG,					\
+	}
+
+#define MR_DEFAULT(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_DEFAULT)
+
+#define MR_TOPGRF(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_TOPGRF)
+
+#define MR_PMUGRF(ID, PIN, FUNC, REG, VAL)	\
+	PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_PMUGRF)
+
 /**
  * struct rockchip_mux_recalced_data: recalculate a pin iomux data.
  * @num: bank number.
@@ -241,6 +281,7 @@ struct rockchip_mux_recalced_data {
  * @bank_num: bank number.
  * @pin: index at register or used to calc index.
  * @func: the min pin.
+ * @route_type: the register type.
  * @route_offset: the max pin.
  * @route_val: the register offset.
  */
@@ -248,6 +289,7 @@ struct rockchip_mux_route_data {
 	u8 bank_num;
 	u8 pin;
 	u8 func;
+	enum rockchip_pin_route_type route_type : 8;
 	u32 route_offset;
 	u32 route_val;
 };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller
  2023-01-05 15:34 ` [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller Chris Morgan
@ 2023-01-05 18:01   ` Quentin Schulz
  2023-01-19 18:21     ` Chris Morgan
  0 siblings, 1 reply; 14+ messages in thread
From: Quentin Schulz @ 2023-01-05 18:01 UTC (permalink / raw)
  To: Chris Morgan, u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	Chris Morgan, Heiko Stuebner

Hi Chris,

Cc'ing the new mail address of Heiko so he receives this mail :)

On 1/5/23 16:34, Chris Morgan wrote:
> From: Chris Morgan <macromorgan@hotmail.com>
> 
> Add support for the newer GPIO controller used by the rk356x series,
> as well as the pinctrl device for the rk356x series. The GPIOv2
> controller has a write enable bit for some registers which differs
> from the older versions of the GPIO controller.
> 
> Adapted from Peter Geis's gitlab located here:
> https://urldefense.com/v3/__https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd__;!!OOPJP91ZZw!i7xaxb0VOR6CU_lauUnYs4-WlEgdGZCaETaNwp--V4jwJoQguyPr07GTOXDhDNNYL4vYLzae_eObZKZUYUAm4pVFA6vGK-JnXjIz$
> 
> Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> ---
>   arch/arm/include/asm/arch-rockchip/gpio.h     |  38 ++
>   drivers/gpio/Kconfig                          |  13 +
>   drivers/gpio/rk_gpio.c                        | 103 +++-
>   drivers/pinctrl/rockchip/Makefile             |   1 +
>   drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++++++++
>   .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
>   drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
>   7 files changed, 635 insertions(+), 27 deletions(-)
>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c
> 
> diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
> index 1aaec5faec..29120ceaf3 100644
> --- a/arch/arm/include/asm/arch-rockchip/gpio.h
> +++ b/arch/arm/include/asm/arch-rockchip/gpio.h
> @@ -6,6 +6,7 @@
>   #ifndef _ASM_ARCH_GPIO_H
>   #define _ASM_ARCH_GPIO_H
>   
> +#ifndef CONFIG_ROCKCHIP_GPIO_V2
>   struct rockchip_gpio_regs {
>   	u32 swport_dr;
>   	u32 swport_ddr;
> @@ -22,7 +23,44 @@ struct rockchip_gpio_regs {
>   	u32 reserved1[(0x60 - 0x54) / 4];
>   	u32 ls_sync;
>   };
> +
>   check_member(rockchip_gpio_regs, ls_sync, 0x60);
> +#else
> +struct rockchip_gpio_regs {
> +	u32 swport_dr_l;                        /* ADDRESS OFFSET: 0x0000 */
> +	u32 swport_dr_h;                        /* ADDRESS OFFSET: 0x0004 */
> +	u32 swport_ddr_l;                       /* ADDRESS OFFSET: 0x0008 */
> +	u32 swport_ddr_h;                       /* ADDRESS OFFSET: 0x000c */
> +	u32 int_en_l;                           /* ADDRESS OFFSET: 0x0010 */
> +	u32 int_en_h;                           /* ADDRESS OFFSET: 0x0014 */
> +	u32 int_mask_l;                         /* ADDRESS OFFSET: 0x0018 */
> +	u32 int_mask_h;                         /* ADDRESS OFFSET: 0x001c */
> +	u32 int_type_l;                         /* ADDRESS OFFSET: 0x0020 */
> +	u32 int_type_h;                         /* ADDRESS OFFSET: 0x0024 */
> +	u32 int_polarity_l;                     /* ADDRESS OFFSET: 0x0028 */
> +	u32 int_polarity_h;                     /* ADDRESS OFFSET: 0x002c */
> +	u32 int_bothedge_l;                     /* ADDRESS OFFSET: 0x0030 */
> +	u32 int_bothedge_h;                     /* ADDRESS OFFSET: 0x0034 */
> +	u32 debounce_l;                         /* ADDRESS OFFSET: 0x0038 */
> +	u32 debounce_h;                         /* ADDRESS OFFSET: 0x003c */
> +	u32 dbclk_div_en_l;                     /* ADDRESS OFFSET: 0x0040 */
> +	u32 dbclk_div_en_h;                     /* ADDRESS OFFSET: 0x0044 */
> +	u32 dbclk_div_con;                      /* ADDRESS OFFSET: 0x0048 */
> +	u32 reserved004c;                       /* ADDRESS OFFSET: 0x004c */
> +	u32 int_status;                         /* ADDRESS OFFSET: 0x0050 */
> +	u32 reserved0054;                       /* ADDRESS OFFSET: 0x0054 */
> +	u32 int_rawstatus;                      /* ADDRESS OFFSET: 0x0058 */
> +	u32 reserved005c;                       /* ADDRESS OFFSET: 0x005c */
> +	u32 port_eoi_l;                         /* ADDRESS OFFSET: 0x0060 */
> +	u32 port_eoi_h;                         /* ADDRESS OFFSET: 0x0064 */
> +	u32 reserved0068[2];                    /* ADDRESS OFFSET: 0x0068 */
> +	u32 ext_port;                           /* ADDRESS OFFSET: 0x0070 */
> +	u32 reserved0074;                       /* ADDRESS OFFSET: 0x0074 */
> +	u32 ver_id;                             /* ADDRESS OFFSET: 0x0078 */
> +};
> +
> +check_member(rockchip_gpio_regs, ver_id, 0x0078);
> +#endif
>   
>   enum gpio_pu_pd {
>   	GPIO_PULL_NORMAL = 0,
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index ff87fbfb39..bd7422a0b3 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -340,6 +340,19 @@ config ROCKCHIP_GPIO
>   	  The GPIOs for a device are defined in the device tree with one node
>   	  for each bank.
>   
> +config ROCKCHIP_GPIO_V2
> +	bool "Rockchip GPIO driver version 2.0"
> +	depends on ROCKCHIP_GPIO

I would make ROCKCHIP_GPIO and ROCKCHIP_GPIO_V2 incompatible with each 
other, otherwise ROCKCHIP_GPIO represents both the GPIO controller and 
the v1, but not v1 if v2 is selected. That's a bit confusing to me.

[...]
> @@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev)
>   {
>   	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
>   	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
> -	char *end;
> -	int ret;
> +	struct rockchip_pinctrl_priv *pctrl_priv;
> +	struct rockchip_pin_bank *bank;
> +	char *end = NULL;
> +	static int gpio;
> +	int id = -1, ret;
>   
>   	priv->regs = dev_read_addr_ptr(dev);
>   	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
> -	if (ret)
> +	if (ret) {
> +		dev_err(dev, "failed to get pinctrl device %d\n", ret);
>   		return ret;
> +	}
> +
> +	pctrl_priv = dev_get_priv(priv->pinctrl);
> +	if (!pctrl_priv) {
> +		dev_err(dev, "failed to get pinctrl priv\n");
> +		return -EINVAL;
> +	}
>   
> -	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
>   	end = strrchr(dev->name, '@');
> -	priv->bank = trailing_strtoln(dev->name, end);
> -	priv->name[0] = 'A' + priv->bank;
> -	uc_priv->bank_name = priv->name;
> +	if (end)
> +		id = trailing_strtoln(dev->name, end);
> +	else
> +		dev_read_alias_seq(dev, &id);
> +
> +	if (id < 0)
> +		id = gpio++;
> +

NACK. This does not work.

This means that the gpio bank detection depends on:
1) the index of the alias (no guarantee it's stable/not overwritten by a 
board dts),
2) if no support for aliases (e.g. in TPL/SPL) or the alias does not 
exist, the probe order of the GPIO controller device will define its 
bank. This is somewhat working in the Linux kernel by chance but does 
NOT work in U-Boot (devices are probed only when used, so you could very 
well have gpio4 controller probed before gpio0 and then gpio4 would 
represent bank 0 and then gpio0 represent bank 1).

Yes, the current code will not work for "newer" DTS and needs to be 
adapted (FWIW, it does not work on PX30 already because the node name is 
gpio@addr instead of gpioX@addr), but the Linux kernel implementation 
(the one used above) is not correct and should not be used.

I've two suggestions:
1) a rockchip,gpio-controller-bank = <0>; property in the -u-boot.dtsi 
for each gpio-controller and then you get the index from there in the 
driver,
2) get the register address of the node of the device you're currently 
probing and maintain a mapping of which address maps to which bank,

We could also start a discussion with upstream Linux to see what they 
would like to go for so we don't have two different implementations.

> +	if (id >= pctrl_priv->ctrl->nr_banks) {
> +		dev_err(dev, "bank id invalid\n");
> +		return -EINVAL;
> +	}
> +
> +	bank = &pctrl_priv->ctrl->pin_banks[id];
> +	if (bank->bank_num != id) {
> +		dev_err(dev, "bank id mismatch with pinctrl\n");
> +		return -EINVAL;
> +	}
> +
> +	priv->bank = bank->bank_num;
> +	uc_priv->gpio_count = bank->nr_pins;
> +	uc_priv->gpio_base = bank->pin_base;
> +	uc_priv->bank_name = bank->name;
>   
>   	return 0;
>   }
> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> index 7d03f8101d..c78fc2c331 100644
> --- a/drivers/pinctrl/rockchip/Makefile
> +++ b/drivers/pinctrl/rockchip/Makefile
> @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o
>   obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
>   obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
>   obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
> +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
>   obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
> diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> new file mode 100644
> index 0000000000..dce1c1e7ee
> --- /dev/null
> +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> @@ -0,0 +1,453 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2020 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/pinctrl.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +
> +#include "pinctrl-rockchip.h"
> +
> +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
> +	/* CAN0 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)),
> +	/* CAN0 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)),
> +	/* CAN1 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)),
> +	/* CAN1 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)),
> +	/* CAN2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)),
> +	/* CAN2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)),
> +	/* EDPDP_HPDIN IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)),
> +	/* EDPDP_HPDIN IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)),
> +	/* GMAC1 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)),
> +	/* GMAC1 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)),
> +	/* HDMITX IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)),
> +	/* HDMITX IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)),
> +	/* I2C2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)),
> +	/* I2C2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)),
> +	/* I2C3 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)),
> +	/* I2C3 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)),
> +	/* I2C4 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)),
> +	/* I2C4 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)),
> +	/* I2C5 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)),
> +	/* I2C5 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)),
> +	/* PWM4 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)),
> +	/* PWM4 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)),
> +	/* PWM5 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)),
> +	/* PWM5 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)),
> +	/* PWM6 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)),
> +	/* PWM6 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)),
> +	/* PWM7 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)),
> +	/* PWM7 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)),
> +	/* PWM8 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)),
> +	/* PWM8 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)),
> +	/* PWM9 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)),
> +	/* PWM9 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)),
> +	/* PWM10 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)),
> +	/* PWM10 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)),
> +	/* PWM11 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)),
> +	/* PWM11 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)),
> +	/* PWM12 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)),
> +	/* PWM12 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)),
> +	/* PWM13 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)),
> +	/* PWM13 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)),
> +	/* PWM14 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)),
> +	/* PWM14 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)),
> +	/* PWM15 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)),
> +	/* PWM15 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)),
> +	/* SDMMC2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)),
> +	/* SDMMC2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)),
> +	/* SPI0 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)),
> +	/* SPI0 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)),
> +	/* SPI1 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)),
> +	/* SPI1 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)),
> +	/* SPI2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)),
> +	/* SPI2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)),
> +	/* SPI3 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)),
> +	/* SPI3 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)),
> +	/* UART1 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)),
> +	/* UART1 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)),
> +	/* UART2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)),
> +	/* UART2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)),
> +	/* UART3 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)),
> +	/* UART3 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)),
> +	/* UART4 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)),
> +	/* UART4 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)),
> +	/* UART5 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)),
> +	/* UART5 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)),
> +	/* UART6 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)),
> +	/* UART6 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)),
> +	/* UART7 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)),
> +	/* UART7 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)),
> +	/* UART7 IO mux selection M2 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)),
> +	/* UART8 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)),
> +	/* UART8 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)),
> +	/* UART9 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)),
> +	/* UART9 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)),
> +	/* UART9 IO mux selection M2 */
> +	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)),
> +	/* I2S1 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)),
> +	/* I2S1 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)),
> +	/* I2S1 IO mux selection M2 */
> +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)),
> +	/* I2S2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)),
> +	/* I2S2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)),
> +	/* I2S3 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)),
> +	/* I2S3 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)),
> +	/* PDM IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)),
> +	/* PDM IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)),
> +	/* PCIE20 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)),
> +	/* PCIE20 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)),
> +	/* PCIE20 IO mux selection M2 */
> +	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)),
> +	/* PCIE30X1 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)),
> +	/* PCIE30X1 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)),
> +	/* PCIE30X1 IO mux selection M2 */
> +	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)),
> +	/* PCIE30X2 IO mux selection M0 */
> +	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)),
> +	/* PCIE30X2 IO mux selection M1 */
> +	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)),
> +	/* PCIE30X2 IO mux selection M2 */
> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)),
> +};
> +
> +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
> +{
> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> +	int iomux_num = (pin / 8);
> +	struct regmap *regmap;
> +	int reg, ret, mask;
> +	u8 bit;
> +	u32 data;
> +
> +	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
> +
> +	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
> +		regmap = priv->regmap_pmu;
> +	else
> +		regmap = priv->regmap_base;
> +
> +	reg = bank->iomux[iomux_num].offset;
> +	if ((pin % 8) >= 4)
> +		reg += 0x4;
> +	bit = (pin % 4) * 4;
> +	mask = 0xf;
> +
> +	data = (mask << (bit + 16));
> +	data |= (mux & mask) << bit;
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +#define RK3568_PULL_PMU_OFFSET		0x20
> +#define RK3568_PULL_GRF_OFFSET		0x80
> +#define RK3568_PULL_BITS_PER_PIN	2
> +#define RK3568_PULL_PINS_PER_REG	8
> +#define RK3568_PULL_BANK_STRIDE		0x10
> +
> +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> +					 int pin_num, struct regmap **regmap,
> +					 int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *info = bank->priv;
> +
> +	if (bank->bank_num == 0) {
> +		*regmap = info->regmap_pmu;
> +		*reg = RK3568_PULL_PMU_OFFSET;
> +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
> +	} else {
> +		*regmap = info->regmap_base;
> +		*reg = RK3568_PULL_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
> +	}
> +
> +	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> +	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
> +	*bit *= RK3568_PULL_BITS_PER_PIN;
> +}
> +
> +#define RK3568_DRV_PMU_OFFSET		0x70
> +#define RK3568_DRV_GRF_OFFSET		0x200
> +#define RK3568_DRV_BITS_PER_PIN		8
> +#define RK3568_DRV_PINS_PER_REG		2
> +#define RK3568_DRV_BANK_STRIDE		0x40
> +
> +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> +					int pin_num, struct regmap **regmap,
> +					int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *info = bank->priv;
> +
> +	/* The first 32 pins of the first bank are located in PMU */
> +	if (bank->bank_num == 0) {
> +		*regmap = info->regmap_pmu;
> +		*reg = RK3568_DRV_PMU_OFFSET;
> +	} else {
> +		*regmap = info->regmap_base;
> +		*reg = RK3568_DRV_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
> +	}
> +
> +	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> +	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
> +	*bit *= RK3568_DRV_BITS_PER_PIN;
> +}
> +
> +#define RK3568_SCHMITT_BITS_PER_PIN		2
> +#define RK3568_SCHMITT_PINS_PER_REG		8
> +#define RK3568_SCHMITT_BANK_STRIDE		0x10
> +#define RK3568_SCHMITT_GRF_OFFSET		0xc0
> +#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
> +
> +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
> +					   int pin_num, struct regmap **regmap,
> +					   int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *info = bank->priv;
> +
> +	if (bank->bank_num == 0) {
> +		*regmap = info->regmap_pmu;
> +		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
> +	} else {
> +		*regmap = info->regmap_base;
> +		*reg = RK3568_SCHMITT_GRF_OFFSET;
> +		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
> +	}
> +
> +	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
> +	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
> +	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
> +
> +	return 0;
> +}
> +
> +static int rk3568_set_pull(struct rockchip_pin_bank *bank,
> +			   int pin_num, int pull)
> +{
> +	struct regmap *regmap;
> +	int reg, ret;
> +	u8 bit, type;
> +	u32 data;
> +
> +	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
> +		return -EOPNOTSUPP;
> +
> +	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +	type = bank->pull_type[pin_num / 8];
> +	ret = rockchip_translate_pull_value(type, pull);
> +	if (ret < 0) {
> +		debug("unsupported pull setting %d\n", pull);
> +		return ret;
> +	}
> +
> +	/* enable the write to the equivalent lower bits */
> +	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
> +
> +	data |= (ret << bit);
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +static int rk3568_set_drive(struct rockchip_pin_bank *bank,
> +			    int pin_num, int strength)
> +{
> +	struct regmap *regmap;
> +	int reg;
> +	u32 data;
> +	u8 bit;
> +	int drv = (1 << (strength + 1)) - 1;
> +	int ret = 0;
> +
> +	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +
> +	/* enable the write to the equivalent lower bits */
> +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
> +	data |= (drv << bit);
> +
> +	ret = regmap_write(regmap, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	if (bank->bank_num == 1 && pin_num == 21)
> +		reg = 0x0840;
> +	else if (bank->bank_num == 2 && pin_num == 2)
> +		reg = 0x0844;
> +	else if (bank->bank_num == 2 && pin_num == 8)
> +		reg = 0x0848;
> +	else if (bank->bank_num == 3 && pin_num == 0)
> +		reg = 0x084c;
> +	else if (bank->bank_num == 3 && pin_num == 6)
> +		reg = 0x0850;
> +	else if (bank->bank_num == 4 && pin_num == 0)
> +		reg = 0x0854;
> +	else
> +		return 0;
> +
> +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
> +	data |= drv;
> +
> +	return regmap_write(regmap, reg, data);
> +}
> +
> +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
> +			      int pin_num, int enable)
> +{
> +	struct regmap *regmap;
> +	int reg;
> +	u32 data;
> +	u8 bit;
> +
> +	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +
> +	/* enable the write to the equivalent lower bits */
> +	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
> +	data |= (enable << bit);
> +
> +	return regmap_write(regmap, reg, data);
> +}
> +
> +static struct rockchip_pin_bank rk3568_pin_banks[] = {
> +	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT),
> +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT,
> +			     IOMUX_WIDTH_4BIT),
> +};
> +
> +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
> +	.pin_banks		= rk3568_pin_banks,
> +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
> +	.nr_pins		= 160,
> +	.grf_mux_offset		= 0x0,
> +	.pmu_mux_offset		= 0x0,
> +	.iomux_routes		= rk3568_mux_route_data,
> +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
> +	.set_mux		= rk3568_set_mux,
> +	.set_pull		= rk3568_set_pull,
> +	.set_drive		= rk3568_set_drive,
> +	.set_schmitt		= rk3568_set_schmitt,
> +};
> +
> +static const struct udevice_id rk3568_pinctrl_ids[] = {
> +	{
> +		.compatible = "rockchip,rk3568-pinctrl",
> +		.data = (ulong)&rk3568_pin_ctrl
> +	},
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(pinctrl_rk3568) = {
> +	.name		= "rockchip_rk3568_pinctrl",
> +	.id		= UCLASS_PINCTRL,
> +	.of_match	= rk3568_pinctrl_ids,
> +	.priv_auto = sizeof(struct rockchip_pinctrl_priv),
> +	.ops		= &rockchip_pinctrl_ops,
> +#if !IS_ENABLED(CONFIG_OF_PLATDATA)
> +	.bind		= dm_scan_fdt_dev,
> +#endif
> +	.probe		= rockchip_pinctrl_probe,
> +};
> diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> index 630513ba3a..5f0016ff60 100644
> --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> @@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
>   	int prop_len, param;
>   	const u32 *data;
>   	ofnode node;
> -#ifdef CONFIG_OF_LIVE
> +#if CONFIG_IS_ENABLED(OF_LIVE)

Not sure this is really related or not, would be better in its own 
commit I believe.

>   	const struct device_node *np;
>   	struct property *pp;
>   #else
> @@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
>   		node = ofnode_get_by_phandle(conf);
>   		if (!ofnode_valid(node))
>   			return -ENODEV;
> -#ifdef CONFIG_OF_LIVE
> +#if CONFIG_IS_ENABLED(OF_LIVE)
>   		np = ofnode_to_np(node);
>   		for (pp = np->properties; pp; pp = pp->next) {
>   			prop_name = pp->name;
> @@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
>   
>   			/* preset iomux offset value, set new start value */
>   			if (iom->offset >= 0) {
> -				if (iom->type & IOMUX_SOURCE_PMU)
> +				if ((iom->type & IOMUX_SOURCE_PMU) || \
> +				    (iom->type & IOMUX_L_SOURCE_PMU))

nitpick: Could be if (iom->type & (IOMUX_SOURCE_PMU | 
IOMUX_L_SOURCE_PMU)) instead.

>   					pmu_offs = iom->offset;
>   				else
>   					grf_offs = iom->offset;
>   			} else { /* set current iomux offset */
> -				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
> -							pmu_offs : grf_offs;
> +				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
> +						(iom->type & IOMUX_L_SOURCE_PMU)) ?

Ditto.

Cheers,
Quentin

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/5] arm64: dts: rockchip: Sync rk356x from Linux main
  2023-01-05 15:34 ` [PATCH 2/5] arm64: dts: rockchip: Sync rk356x from Linux main Chris Morgan
@ 2023-01-09 22:34   ` Johan Jonker
  0 siblings, 0 replies; 14+ messages in thread
From: Johan Jonker @ 2023-01-09 22:34 UTC (permalink / raw)
  To: Chris Morgan, u-boot
  Cc: sjg, philipp.tomsich, kever.yang, chenjh, pgwipeout,
	heiko.stuebner, Chris Morgan



On 1/5/23 16:34, Chris Morgan wrote:
> From: Chris Morgan <macromorgan@hotmail.com>
> 
> Sync rk3566 and rk3568 from the mainline Linux kernel (6.2-rc2 as of
> this writing).
> 
> Note that this will rename the rk3568-evb to rk3568-evb1-v10.
> 
> Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> ---
>  arch/arm/dts/Makefile            |   2 +-
>  arch/arm/dts/rk3568-evb.dts      |  79 ----
>  arch/arm/dts/rk3568-evb1-v10.dts | 692 +++++++++++++++++++++++++++++++
>  arch/arm/dts/rk3568.dtsi         | 122 ++++++
>  arch/arm/dts/rk356x.dtsi         | 182 +++++++-
>  configs/evb-rk3568_defconfig     |   4 +-
>  6 files changed, 985 insertions(+), 96 deletions(-)
>  delete mode 100644 arch/arm/dts/rk3568-evb.dts
>  create mode 100644 arch/arm/dts/rk3568-evb1-v10.dts
> 
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index 43951a7731..e1d8866bbf 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -164,7 +164,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
>  	rk3399pro-rock-pi-n10.dtb
>  
>  dtb-$(CONFIG_ROCKCHIP_RK3568) += \
> -	rk3568-evb.dtb
> +	rk3568-evb1-v10.dtb
>  
>  dtb-$(CONFIG_ROCKCHIP_RV1108) += \
>  	rv1108-elgin-r1.dtb \
> diff --git a/arch/arm/dts/rk3568-evb.dts b/arch/arm/dts/rk3568-evb.dts
> deleted file mode 100644
> index 6978655709..0000000000
> --- a/arch/arm/dts/rk3568-evb.dts
> +++ /dev/null
> @@ -1,79 +0,0 @@
> -// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> -/*
> - * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
> - *
> - */
> -
> -/dts-v1/;
> -#include <dt-bindings/gpio/gpio.h>
> -#include <dt-bindings/pinctrl/rockchip.h>
> -#include "rk3568.dtsi"
> -
> -/ {
> -	model = "Rockchip RK3568 EVB1 DDR4 V10 Board";
> -	compatible = "rockchip,rk3568-evb1-v10", "rockchip,rk3568";
> -
> -	chosen: chosen {
> -		stdout-path = "serial2:1500000n8";
> -	};
> -
> -	dc_12v: dc-12v {
> -		compatible = "regulator-fixed";
> -		regulator-name = "dc_12v";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <12000000>;
> -		regulator-max-microvolt = <12000000>;
> -	};
> -
> -	vcc3v3_sys: vcc3v3-sys {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc3v3_sys";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <3300000>;
> -		regulator-max-microvolt = <3300000>;
> -		vin-supply = <&dc_12v>;
> -	};
> -
> -	vcc5v0_sys: vcc5v0-sys {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc5v0_sys";
> -		regulator-always-on;
> -		regulator-boot-on;
> -		regulator-min-microvolt = <5000000>;
> -		regulator-max-microvolt = <5000000>;
> -		vin-supply = <&dc_12v>;
> -	};
> -
> -	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc3v3_lcd0_n";
> -		regulator-boot-on;
> -
> -		regulator-state-mem {
> -			regulator-off-in-suspend;
> -		};
> -	};
> -
> -	vcc3v3_lcd1_n: vcc3v3-lcd1-n {
> -		compatible = "regulator-fixed";
> -		regulator-name = "vcc3v3_lcd1_n";
> -		regulator-boot-on;
> -
> -		regulator-state-mem {
> -			regulator-off-in-suspend;
> -		};
> -	};
> -};
> -
> -&sdhci {
> -	bus-width = <8>;
> -	max-frequency = <200000000>;
> -	non-removable;
> -	status = "okay";
> -};
> -
> -&uart2 {
> -	status = "okay";
> -};

> diff --git a/arch/arm/dts/rk3568-evb1-v10.dts b/arch/arm/dts/rk3568-evb1-v10.dts

Hi Chris,

Is it possible to add this file and rk3568-evb-u-boot.dtsi to:
/board/rockchip/evb_rk3568/MAINTAINERS

Fix order with (From Linux):
./scripts/parse-maintainers.pl --input=MAINTAINERS --output=MAINTAINERS --order


Also add to:
/doc/board/rockchip/rockchip.rst

Add to the list of mainline supported Rockchip boards.
Make a "To build rk3568 boards:"

Johan

> new file mode 100644
> index 0000000000..674792567f
> --- /dev/null
> +++ b/arch/arm/dts/rk3568-evb1-v10.dts
> @@ -0,0 +1,692 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2021 Rockchip Electronics Co., Ltd.
> + *
> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/leds/common.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/soc/rockchip,vop2.h>
> +#include "rk3568.dtsi"
> +
> +/ {
> +	model = "Rockchip RK3568 EVB1 DDR4 V10 Board";
> +	compatible = "rockchip,rk3568-evb1-v10", "rockchip,rk3568";
> +
> +	aliases {
> +		ethernet0 = &gmac0;
> +		ethernet1 = &gmac1;
> +		mmc0 = &sdmmc0;
> +		mmc1 = &sdhci;
> +	};
> +
> +	chosen: chosen {
> +		stdout-path = "serial2:1500000n8";
> +	};
> +
> +	dc_12v: dc-12v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "dc_12v";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <12000000>;
> +		regulator-max-microvolt = <12000000>;
> +	};
> +
> +	hdmi-con {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_in: endpoint {
> +				remote-endpoint = <&hdmi_out_con>;
> +			};
> +		};
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +
> +		led_work: led-0 {
> +			gpios = <&gpio0 RK_PC0 GPIO_ACTIVE_HIGH>;
> +			function = LED_FUNCTION_HEARTBEAT;
> +			color = <LED_COLOR_ID_BLUE>;
> +			linux,default-trigger = "heartbeat";
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&led_work_en>;
> +		};
> +	};
> +
> +	rk809-sound {
> +		compatible = "simple-audio-card";
> +		simple-audio-card,format = "i2s";
> +		simple-audio-card,name = "Analog RK809";
> +		simple-audio-card,mclk-fs = <256>;
> +
> +		simple-audio-card,cpu {
> +			sound-dai = <&i2s1_8ch>;
> +		};
> +		simple-audio-card,codec {
> +			sound-dai = <&rk809>;
> +		};
> +	};
> +
> +	vcc3v3_sys: vcc3v3-sys {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc3v3_sys";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&dc_12v>;
> +	};
> +
> +	vcc5v0_sys: vcc5v0-sys {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc5v0_sys";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&dc_12v>;
> +	};
> +
> +	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 = <&dc_12v>;
> +	};
> +
> +	vcc5v0_usb_host: vcc5v0-usb-host {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&vcc5v0_usb_host_en>;
> +		regulator-name = "vcc5v0_usb_host";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc5v0_usb>;
> +	};
> +
> +	vcc5v0_usb_otg: vcc5v0-usb-otg {
> +		compatible = "regulator-fixed";
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&vcc5v0_usb_otg_en>;
> +		regulator-name = "vcc5v0_usb_otg";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&vcc5v0_usb>;
> +	};
> +
> +	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc3v3_lcd0_n";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
> +		vin-supply = <&vcc3v3_sys>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&vcc3v3_lcd0_n_en>;
> +
> +		regulator-state-mem {
> +			regulator-off-in-suspend;
> +		};
> +	};
> +
> +	vcc3v3_lcd1_n: vcc3v3-lcd1-n {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc3v3_lcd1_n";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		enable-active-high;
> +		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
> +		vin-supply = <&vcc3v3_sys>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&vcc3v3_lcd1_n_en>;
> +
> +		regulator-state-mem {
> +			regulator-off-in-suspend;
> +		};
> +	};
> +};
> +
> +&combphy0 {
> +	status = "okay";
> +};
> +
> +&combphy1 {
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vdd_cpu>;
> +};
> +
> +&cpu1 {
> +	cpu-supply = <&vdd_cpu>;
> +};
> +
> +&cpu2 {
> +	cpu-supply = <&vdd_cpu>;
> +};
> +
> +&cpu3 {
> +	cpu-supply = <&vdd_cpu>;
> +};
> +
> +&gmac0 {
> +	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
> +	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>;
> +	assigned-clock-rates = <0>, <125000000>;
> +	clock_in_out = "output";
> +	phy-handle = <&rgmii_phy0>;
> +	phy-mode = "rgmii-id";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac0_miim
> +		     &gmac0_tx_bus2
> +		     &gmac0_rx_bus2
> +		     &gmac0_rgmii_clk
> +		     &gmac0_rgmii_bus>;
> +	status = "okay";
> +};
> +
> +&gmac1 {
> +	assigned-clocks = <&cru SCLK_GMAC1_RX_TX>, <&cru SCLK_GMAC1>;
> +	assigned-clock-parents = <&cru SCLK_GMAC1_RGMII_SPEED>;
> +	assigned-clock-rates = <0>, <125000000>;
> +	clock_in_out = "output";
> +	phy-handle = <&rgmii_phy1>;
> +	phy-mode = "rgmii-id";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac1m1_miim
> +		     &gmac1m1_tx_bus2
> +		     &gmac1m1_rx_bus2
> +		     &gmac1m1_rgmii_clk
> +		     &gmac1m1_rgmii_bus>;
> +	status = "okay";
> +};
> +
> +&gpu {
> +	mali-supply = <&vdd_gpu>;
> +	status = "okay";
> +};
> +
> +&hdmi {
> +	avdd-0v9-supply = <&vdda0v9_image>;
> +	avdd-1v8-supply = <&vcca1v8_image>;
> +	status = "okay";
> +};
> +
> +&hdmi_in {
> +	hdmi_in_vp0: endpoint {
> +		remote-endpoint = <&vp0_out_hdmi>;
> +	};
> +};
> +
> +&hdmi_out {
> +	hdmi_out_con: endpoint {
> +		remote-endpoint = <&hdmi_con_in>;
> +	};
> +};
> +
> +&hdmi_sound {
> +	status = "okay";
> +};
> +
> +&i2c0 {
> +	status = "okay";
> +
> +	vdd_cpu: regulator@1c {
> +		compatible = "tcs,tcs4525";
> +		reg = <0x1c>;
> +		fcs,suspend-voltage-selector = <1>;
> +		regulator-name = "vdd_cpu";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <800000>;
> +		regulator-max-microvolt = <1150000>;
> +		regulator-ramp-delay = <2300>;
> +		vin-supply = <&vcc5v0_sys>;
> +
> +		regulator-state-mem {
> +			regulator-off-in-suspend;
> +		};
> +	};
> +
> +	rk809: pmic@20 {
> +		compatible = "rockchip,rk809";
> +		reg = <0x20>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
> +		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
> +		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
> +		#clock-cells = <1>;
> +		clock-names = "mclk";
> +		clocks = <&cru I2S1_MCLKOUT_TX>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pmic_int>, <&i2s1m0_mclk>;
> +		rockchip,system-power-controller;
> +		#sound-dai-cells = <0>;
> +		vcc1-supply = <&vcc3v3_sys>;
> +		vcc2-supply = <&vcc3v3_sys>;
> +		vcc3-supply = <&vcc3v3_sys>;
> +		vcc4-supply = <&vcc3v3_sys>;
> +		vcc5-supply = <&vcc3v3_sys>;
> +		vcc6-supply = <&vcc3v3_sys>;
> +		vcc7-supply = <&vcc3v3_sys>;
> +		vcc8-supply = <&vcc3v3_sys>;
> +		vcc9-supply = <&vcc3v3_sys>;
> +		wakeup-source;
> +
> +		regulators {
> +			vdd_logic: DCDC_REG1 {
> +				regulator-name = "vdd_logic";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-init-microvolt = <900000>;
> +				regulator-initial-mode = <0x2>;
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-ramp-delay = <6001>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdd_gpu: DCDC_REG2 {
> +				regulator-name = "vdd_gpu";
> +				regulator-always-on;
> +				regulator-init-microvolt = <900000>;
> +				regulator-initial-mode = <0x2>;
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-ramp-delay = <6001>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_ddr: DCDC_REG3 {
> +				regulator-name = "vcc_ddr";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-initial-mode = <0x2>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			vdd_npu: DCDC_REG4 {
> +				regulator-name = "vdd_npu";
> +				regulator-init-microvolt = <900000>;
> +				regulator-initial-mode = <0x2>;
> +				regulator-min-microvolt = <500000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-ramp-delay = <6001>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_1v8: DCDC_REG5 {
> +				regulator-name = "vcc_1v8";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdda0v9_image: LDO_REG1 {
> +				regulator-name = "vdda0v9_image";
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdda_0v9: LDO_REG2 {
> +				regulator-name = "vdda_0v9";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vdda0v9_pmu: LDO_REG3 {
> +				regulator-name = "vdda0v9_pmu";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <900000>;
> +				};
> +			};
> +
> +			vccio_acodec: LDO_REG4 {
> +				regulator-name = "vccio_acodec";
> +				regulator-always-on;
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vccio_sd: LDO_REG5 {
> +				regulator-name = "vccio_sd";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc3v3_pmu: LDO_REG6 {
> +				regulator-name = "vcc3v3_pmu";
> +				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>;
> +				};
> +			};
> +
> +			vcca_1v8: LDO_REG7 {
> +				regulator-name = "vcca_1v8";
> +				regulator-always-on;
> +				regulator-boot-on;
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcca1v8_pmu: LDO_REG8 {
> +				regulator-name = "vcca1v8_pmu";
> +				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>;
> +				};
> +			};
> +
> +			vcca1v8_image: LDO_REG9 {
> +				regulator-name = "vcca1v8_image";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc_3v3: SWITCH_REG1 {
> +				regulator-name = "vcc_3v3";
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			vcc3v3_sd: SWITCH_REG2 {
> +				regulator-name = "vcc3v3_sd";
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +		};
> +
> +		codec {
> +			mic-in-differential;
> +		};
> +	};
> +};
> +
> +&i2c1 {
> +	status = "okay";
> +
> +	touchscreen0: goodix@14 {
> +		compatible = "goodix,gt1151";
> +		reg = <0x14>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <RK_PB5 IRQ_TYPE_EDGE_FALLING>;
> +		AVDD28-supply = <&vcc3v3_lcd0_n>;
> +		irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&touch_int &touch_rst>;
> +		reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
> +		VDDIO-supply = <&vcc3v3_lcd0_n>;
> +	};
> +};
> +
> +&i2s0_8ch {
> +	status = "okay";
> +};
> +
> +&i2s1_8ch {
> +	rockchip,trcm-sync-tx-only;
> +	status = "okay";
> +};
> +
> +&mdio0 {
> +	rgmii_phy0: ethernet-phy@0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0x0>;
> +		reset-assert-us = <20000>;
> +		reset-deassert-us = <100000>;
> +		reset-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_LOW>;
> +	};
> +};
> +
> +&mdio1 {
> +	rgmii_phy1: ethernet-phy@0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0x0>;
> +		reset-assert-us = <20000>;
> +		reset-deassert-us = <100000>;
> +		reset-gpios = <&gpio2 RK_PD1 GPIO_ACTIVE_LOW>;
> +	};
> +};
> +
> +&pinctrl {
> +	display {
> +		vcc3v3_lcd0_n_en: vcc3v3_lcd0_n_en {
> +			rockchip,pins = <0 RK_PC7 0 &pcfg_pull_none>;
> +		};
> +		vcc3v3_lcd1_n_en: vcc3v3_lcd1_n_en {
> +			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
> +		};
> +	};
> +
> +	leds {
> +		led_work_en: led_work_en {
> +			rockchip,pins = <0 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	pmic {
> +		pmic_int: pmic_int {
> +			rockchip,pins =
> +				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +	};
> +
> +	touchscreen {
> +		touch_int: touch_int {
> +			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +		touch_rst: touch_rst {
> +			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	usb {
> +		vcc5v0_usb_host_en: vcc5v0_usb_host_en {
> +			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +		vcc5v0_usb_otg_en: vcc5v0_usb_otg_en {
> +			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +};
> +
> +&pmu_io_domains {
> +	pmuio1-supply = <&vcc3v3_pmu>;
> +	pmuio2-supply = <&vcc3v3_pmu>;
> +	vccio1-supply = <&vccio_acodec>;
> +	vccio2-supply = <&vcc_1v8>;
> +	vccio3-supply = <&vccio_sd>;
> +	vccio4-supply = <&vcc_1v8>;
> +	vccio5-supply = <&vcc_3v3>;
> +	vccio6-supply = <&vcc_1v8>;
> +	vccio7-supply = <&vcc_3v3>;
> +	status = "okay";
> +};
> +
> +&saradc {
> +	vref-supply = <&vcca_1v8>;
> +	status = "okay";
> +};
> +
> +&sdhci {
> +	bus-width = <8>;
> +	max-frequency = <200000000>;
> +	non-removable;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
> +	status = "okay";
> +};
> +
> +&sdmmc0 {
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
> +	disable-wp;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
> +	sd-uhs-sdr104;
> +	vmmc-supply = <&vcc3v3_sd>;
> +	vqmmc-supply = <&vccio_sd>;
> +	status = "okay";
> +};
> +
> +&tsadc {
> +	rockchip,hw-tshut-mode = <1>;
> +	rockchip,hw-tshut-polarity = <0>;
> +	status = "okay";
> +};
> +
> +&uart2 {
> +	status = "okay";
> +};
> +
> +&usb_host0_ehci {
> +	status = "okay";
> +};
> +
> +&usb_host0_ohci {
> +	status = "okay";
> +};
> +
> +&usb_host0_xhci {
> +	extcon = <&usb2phy0>;
> +	status = "okay";
> +};
> +
> +&usb_host1_ehci {
> +	status = "okay";
> +};
> +
> +&usb_host1_ohci {
> +	status = "okay";
> +};
> +
> +&usb_host1_xhci {
> +	status = "okay";
> +};
> +
> +&usb2phy0 {
> +	status = "okay";
> +};
> +
> +&usb2phy0_host {
> +	phy-supply = <&vcc5v0_usb_host>;
> +	status = "okay";
> +};
> +
> +&usb2phy0_otg {
> +	phy-supply = <&vcc5v0_usb_otg>;
> +	status = "okay";
> +};
> +
> +&usb2phy1 {
> +	status = "okay";
> +};
> +
> +&usb2phy1_host {
> +	phy-supply = <&vcc5v0_usb_host>;
> +	status = "okay";
> +};
> +
> +&usb2phy1_otg {
> +	phy-supply = <&vcc5v0_usb_host>;
> +	status = "okay";
> +};
> +
> +&vop {
> +	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
> +	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
> +	status = "okay";
> +};
> +
> +&vop_mmu {
> +	status = "okay";
> +};
> +
> +&vp0 {
> +	vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
> +		reg = <ROCKCHIP_VOP2_EP_HDMI0>;
> +		remote-endpoint = <&hdmi_in_vp0>;
> +	};
> +};
> diff --git a/arch/arm/dts/rk3568.dtsi b/arch/arm/dts/rk3568.dtsi
> index 2bdf8c7e97..ba67b58f05 100644
> --- a/arch/arm/dts/rk3568.dtsi
> +++ b/arch/arm/dts/rk3568.dtsi
> @@ -42,6 +42,128 @@
>  		reg = <0x0 0xfe190200 0x0 0x20>;
>  	};
>  
> +	pcie30_phy_grf: syscon@fdcb8000 {
> +		compatible = "rockchip,rk3568-pcie3-phy-grf", "syscon";
> +		reg = <0x0 0xfdcb8000 0x0 0x10000>;
> +	};
> +
> +	pcie30phy: phy@fe8c0000 {
> +		compatible = "rockchip,rk3568-pcie3-phy";
> +		reg = <0x0 0xfe8c0000 0x0 0x20000>;
> +		#phy-cells = <0>;
> +		clocks = <&pmucru CLK_PCIE30PHY_REF_M>, <&pmucru CLK_PCIE30PHY_REF_N>,
> +			 <&cru PCLK_PCIE30PHY>;
> +		clock-names = "refclk_m", "refclk_n", "pclk";
> +		resets = <&cru SRST_PCIE30PHY>;
> +		reset-names = "phy";
> +		rockchip,phy-grf = <&pcie30_phy_grf>;
> +		status = "disabled";
> +	};
> +
> +	pcie3x1: pcie@fe270000 {
> +		compatible = "rockchip,rk3568-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +		bus-range = <0x0 0xf>;
> +		clocks = <&cru ACLK_PCIE30X1_MST>, <&cru ACLK_PCIE30X1_SLV>,
> +			 <&cru ACLK_PCIE30X1_DBI>, <&cru PCLK_PCIE30X1>,
> +			 <&cru CLK_PCIE30X1_AUX_NDFT>;
> +		clock-names = "aclk_mst", "aclk_slv",
> +			      "aclk_dbi", "pclk", "aux";
> +		device_type = "pci";
> +		interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "sys", "pmc", "msg", "legacy", "err";
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0 0 0 7>;
> +		interrupt-map = <0 0 0 1 &pcie3x1_intc 0>,
> +				<0 0 0 2 &pcie3x1_intc 1>,
> +				<0 0 0 3 &pcie3x1_intc 2>,
> +				<0 0 0 4 &pcie3x1_intc 3>;
> +		linux,pci-domain = <1>;
> +		num-ib-windows = <6>;
> +		num-ob-windows = <2>;
> +		max-link-speed = <3>;
> +		msi-map = <0x0 &gic 0x1000 0x1000>;
> +		num-lanes = <1>;
> +		phys = <&pcie30phy>;
> +		phy-names = "pcie-phy";
> +		power-domains = <&power RK3568_PD_PIPE>;
> +		reg = <0x3 0xc0400000 0x0 0x00400000>,
> +		      <0x0 0xfe270000 0x0 0x00010000>,
> +		      <0x3 0x7f000000 0x0 0x01000000>;
> +		ranges = <0x01000000 0x0 0x3ef00000 0x3 0x7ef00000 0x0 0x00100000>,
> +			 <0x02000000 0x0 0x00000000 0x3 0x40000000 0x0 0x3ef00000>;
> +		reg-names = "dbi", "apb", "config";
> +		resets = <&cru SRST_PCIE30X1_POWERUP>;
> +		reset-names = "pipe";
> +		/* bifurcation; lane1 when using 1+1 */
> +		status = "disabled";
> +
> +		pcie3x1_intc: legacy-interrupt-controller {
> +			interrupt-controller;
> +			#address-cells = <0>;
> +			#interrupt-cells = <1>;
> +			interrupt-parent = <&gic>;
> +			interrupts = <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>;
> +		};
> +	};
> +
> +	pcie3x2: pcie@fe280000 {
> +		compatible = "rockchip,rk3568-pcie";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +		bus-range = <0x0 0xf>;
> +		clocks = <&cru ACLK_PCIE30X2_MST>, <&cru ACLK_PCIE30X2_SLV>,
> +			 <&cru ACLK_PCIE30X2_DBI>, <&cru PCLK_PCIE30X2>,
> +			 <&cru CLK_PCIE30X2_AUX_NDFT>;
> +		clock-names = "aclk_mst", "aclk_slv",
> +			      "aclk_dbi", "pclk", "aux";
> +		device_type = "pci";
> +		interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "sys", "pmc", "msg", "legacy", "err";
> +		#interrupt-cells = <1>;
> +		interrupt-map-mask = <0 0 0 7>;
> +		interrupt-map = <0 0 0 1 &pcie3x2_intc 0>,
> +				<0 0 0 2 &pcie3x2_intc 1>,
> +				<0 0 0 3 &pcie3x2_intc 2>,
> +				<0 0 0 4 &pcie3x2_intc 3>;
> +		linux,pci-domain = <2>;
> +		num-ib-windows = <6>;
> +		num-ob-windows = <2>;
> +		max-link-speed = <3>;
> +		msi-map = <0x0 &gic 0x2000 0x1000>;
> +		num-lanes = <2>;
> +		phys = <&pcie30phy>;
> +		phy-names = "pcie-phy";
> +		power-domains = <&power RK3568_PD_PIPE>;
> +		reg = <0x3 0xc0800000 0x0 0x00400000>,
> +		      <0x0 0xfe280000 0x0 0x00010000>,
> +		      <0x3 0xbf000000 0x0 0x01000000>;
> +		ranges = <0x01000000 0x0 0x3ef00000 0x3 0xbef00000 0x0 0x00100000>,
> +			 <0x02000000 0x0 0x00000000 0x3 0x80000000 0x0 0x3ef00000>;
> +		reg-names = "dbi", "apb", "config";
> +		resets = <&cru SRST_PCIE30X2_POWERUP>;
> +		reset-names = "pipe";
> +		/* bifurcation; lane0 when using 1+1 */
> +		status = "disabled";
> +
> +		pcie3x2_intc: legacy-interrupt-controller {
> +			interrupt-controller;
> +			#address-cells = <0>;
> +			#interrupt-cells = <1>;
> +			interrupt-parent = <&gic>;
> +			interrupts = <GIC_SPI 162 IRQ_TYPE_EDGE_RISING>;
> +		};
> +	};
> +
>  	gmac0: ethernet@fe2a0000 {
>  		compatible = "rockchip,rk3568-gmac", "snps,dwmac-4.20a";
>  		reg = <0x0 0xfe2a0000 0x0 0x10000>;
> diff --git a/arch/arm/dts/rk356x.dtsi b/arch/arm/dts/rk356x.dtsi
> index 319981c3e9..5706c3e24f 100644
> --- a/arch/arm/dts/rk356x.dtsi
> +++ b/arch/arm/dts/rk356x.dtsi
> @@ -592,6 +592,46 @@
>  		status = "disabled";
>  	};
>  
> +	vpu: video-codec@fdea0400 {
> +		compatible = "rockchip,rk3568-vpu";
> +		reg = <0x0 0xfdea0000 0x0 0x800>;
> +		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +		clock-names = "aclk", "hclk";
> +		iommus = <&vdpu_mmu>;
> +		power-domains = <&power RK3568_PD_VPU>;
> +	};
> +
> +	vdpu_mmu: iommu@fdea0800 {
> +		compatible = "rockchip,rk3568-iommu";
> +		reg = <0x0 0xfdea0800 0x0 0x40>;
> +		interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
> +		clock-names = "aclk", "iface";
> +		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
> +		power-domains = <&power RK3568_PD_VPU>;
> +		#iommu-cells = <0>;
> +	};
> +
> +	vepu: video-codec@fdee0000 {
> +		compatible = "rockchip,rk3568-vepu";
> +		reg = <0x0 0xfdee0000 0x0 0x800>;
> +		interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_JENC>, <&cru HCLK_JENC>;
> +		clock-names = "aclk", "hclk";
> +		iommus = <&vepu_mmu>;
> +		power-domains = <&power RK3568_PD_RGA>;
> +	};
> +
> +	vepu_mmu: iommu@fdee0800 {
> +		compatible = "rockchip,rk3568-iommu";
> +		reg = <0x0 0xfdee0800 0x0 0x40>;
> +		interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_JENC>, <&cru HCLK_JENC>;
> +		clock-names = "aclk", "iface";
> +		power-domains = <&power RK3568_PD_RGA>;
> +		#iommu-cells = <0>;
> +	};
> +
>  	sdmmc2: mmc@fe000000 {
>  		compatible = "rockchip,rk3568-dw-mshc", "rockchip,rk3288-dw-mshc";
>  		reg = <0x0 0xfe000000 0x0 0x4000>;
> @@ -699,6 +739,62 @@
>  		status = "disabled";
>  	};
>  
> +	dsi0: dsi@fe060000 {
> +		compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
> +		reg = <0x00 0xfe060000 0x00 0x10000>;
> +		interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
> +		clock-names = "pclk", "hclk";
> +		clocks = <&cru PCLK_DSITX_0>, <&cru HCLK_VO>;
> +		phy-names = "dphy";
> +		phys = <&dsi_dphy0>;
> +		power-domains = <&power RK3568_PD_VO>;
> +		reset-names = "apb";
> +		resets = <&cru SRST_P_DSITX_0>;
> +		rockchip,grf = <&grf>;
> +		status = "disabled";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			dsi0_in: port@0 {
> +				reg = <0>;
> +			};
> +
> +			dsi0_out: port@1 {
> +				reg = <1>;
> +			};
> +		};
> +	};
> +
> +	dsi1: dsi@fe070000 {
> +		compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
> +		reg = <0x0 0xfe070000 0x0 0x10000>;
> +		interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
> +		clock-names = "pclk", "hclk";
> +		clocks = <&cru PCLK_DSITX_1>, <&cru HCLK_VO>;
> +		phy-names = "dphy";
> +		phys = <&dsi_dphy1>;
> +		power-domains = <&power RK3568_PD_VO>;
> +		reset-names = "apb";
> +		resets = <&cru SRST_P_DSITX_1>;
> +		rockchip,grf = <&grf>;
> +		status = "disabled";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			dsi1_in: port@0 {
> +				reg = <0>;
> +			};
> +
> +			dsi1_out: port@1 {
> +				reg = <1>;
> +			};
> +		};
> +	};
> +
>  	hdmi: hdmi@fe0a0000 {
>  		compatible = "rockchip,rk3568-dw-hdmi";
>  		reg = <0x0 0xfe0a0000 0x0 0x20000>;
> @@ -953,20 +1049,6 @@
>  		status = "disabled";
>  	};
>  
> -	spdif: spdif@fe460000 {
> -		compatible = "rockchip,rk3568-spdif";
> -		reg = <0x0 0xfe460000 0x0 0x1000>;
> -		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> -		clock-names = "mclk", "hclk";
> -		clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>;
> -		dmas = <&dmac1 1>;
> -		dma-names = "tx";
> -		pinctrl-names = "default";
> -		pinctrl-0 = <&spdifm0_tx>;
> -		#sound-dai-cells = <0>;
> -		status = "disabled";
> -	};
> -
>  	i2s0_8ch: i2s@fe400000 {
>  		compatible = "rockchip,rk3568-i2s-tdm";
>  		reg = <0x0 0xfe400000 0x0 0x1000>;
> @@ -1009,6 +1091,28 @@
>  		status = "disabled";
>  	};
>  
> +	i2s2_2ch: i2s@fe420000 {
> +		compatible = "rockchip,rk3568-i2s-tdm";
> +		reg = <0x0 0xfe420000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
> +		assigned-clocks = <&cru CLK_I2S2_2CH_SRC>;
> +		assigned-clock-rates = <1188000000>;
> +		clocks = <&cru MCLK_I2S2_2CH>, <&cru MCLK_I2S2_2CH>, <&cru HCLK_I2S2_2CH>;
> +		clock-names = "mclk_tx", "mclk_rx", "hclk";
> +		dmas = <&dmac1 4>, <&dmac1 5>;
> +		dma-names = "tx", "rx";
> +		resets = <&cru SRST_M_I2S2_2CH>;
> +		reset-names = "m";
> +		rockchip,grf = <&grf>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2s2m0_sclktx
> +				&i2s2m0_lrcktx
> +				&i2s2m0_sdi
> +				&i2s2m0_sdo>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
>  	i2s3_2ch: i2s@fe430000 {
>  		compatible = "rockchip,rk3568-i2s-tdm";
>  		reg = <0x0 0xfe430000 0x0 0x1000>;
> @@ -1046,6 +1150,20 @@
>  		status = "disabled";
>  	};
>  
> +	spdif: spdif@fe460000 {
> +		compatible = "rockchip,rk3568-spdif";
> +		reg = <0x0 0xfe460000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> +		clock-names = "mclk", "hclk";
> +		clocks = <&cru MCLK_SPDIF_8CH>, <&cru HCLK_SPDIF_8CH>;
> +		dmas = <&dmac1 1>;
> +		dma-names = "tx";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&spdifm0_tx>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
>  	dmac0: dma-controller@fe530000 {
>  		compatible = "arm,pl330", "arm,primecell";
>  		reg = <0x0 0xfe530000 0x0 0x4000>;
> @@ -1594,6 +1712,42 @@
>  		status = "disabled";
>  	};
>  
> +	csi_dphy: phy@fe870000 {
> +		compatible = "rockchip,rk3568-csi-dphy";
> +		reg = <0x0 0xfe870000 0x0 0x10000>;
> +		clocks = <&cru PCLK_MIPICSIPHY>;
> +		clock-names = "pclk";
> +		#phy-cells = <0>;
> +		resets = <&cru SRST_P_MIPICSIPHY>;
> +		reset-names = "apb";
> +		rockchip,grf = <&grf>;
> +		status = "disabled";
> +	};
> +
> +	dsi_dphy0: mipi-dphy@fe850000 {
> +		compatible = "rockchip,rk3568-dsi-dphy";
> +		reg = <0x0 0xfe850000 0x0 0x10000>;
> +		clock-names = "ref", "pclk";
> +		clocks = <&pmucru CLK_MIPIDSIPHY0_REF>, <&cru PCLK_MIPIDSIPHY0>;
> +		#phy-cells = <0>;
> +		power-domains = <&power RK3568_PD_VO>;
> +		reset-names = "apb";
> +		resets = <&cru SRST_P_MIPIDSIPHY0>;
> +		status = "disabled";
> +	};
> +
> +	dsi_dphy1: mipi-dphy@fe860000 {
> +		compatible = "rockchip,rk3568-dsi-dphy";
> +		reg = <0x0 0xfe860000 0x0 0x10000>;
> +		clock-names = "ref", "pclk";
> +		clocks = <&pmucru CLK_MIPIDSIPHY1_REF>, <&cru PCLK_MIPIDSIPHY1>;
> +		#phy-cells = <0>;
> +		power-domains = <&power RK3568_PD_VO>;
> +		reset-names = "apb";
> +		resets = <&cru SRST_P_MIPIDSIPHY1>;
> +		status = "disabled";
> +	};
> +
>  	usb2phy0: usb2phy@fe8a0000 {
>  		compatible = "rockchip,rk3568-usb2phy";
>  		reg = <0x0 0xfe8a0000 0x0 0x10000>;
> diff --git a/configs/evb-rk3568_defconfig b/configs/evb-rk3568_defconfig
> index db3acf5be5..2e9891bb1b 100644
> --- a/configs/evb-rk3568_defconfig
> +++ b/configs/evb-rk3568_defconfig
> @@ -6,7 +6,7 @@ CONFIG_TEXT_BASE=0x00a00000
>  CONFIG_SPL_LIBCOMMON_SUPPORT=y
>  CONFIG_SPL_LIBGENERIC_SUPPORT=y
>  CONFIG_NR_DRAM_BANKS=2
> -CONFIG_DEFAULT_DEVICE_TREE="rk3568-evb"
> +CONFIG_DEFAULT_DEVICE_TREE="rk3568-evb1-v10"
>  CONFIG_ROCKCHIP_RK3568=y
>  CONFIG_SPL_ROCKCHIP_BACK_TO_BROM=y
>  CONFIG_SPL_ROCKCHIP_COMMON_BOARD=y
> @@ -23,7 +23,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xc00000
>  CONFIG_FIT=y
>  CONFIG_FIT_VERBOSE=y
>  CONFIG_SPL_LOAD_FIT=y
> -CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-evb.dtb"
> +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3568-evb1-v10.dtb"
>  # CONFIG_DISPLAY_CPUINFO is not set
>  CONFIG_DISPLAY_BOARDINFO_LATE=y
>  CONFIG_SPL_MAX_SIZE=0x20000

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux
  2023-01-05 15:34 ` [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux Chris Morgan
@ 2023-01-17  2:07   ` Kever Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2023-01-17  2:07 UTC (permalink / raw)
  To: Chris Morgan, u-boot
  Cc: sjg, philipp.tomsich, chenjh, pgwipeout, heiko.stuebner, Chris Morgan


On 2023/1/5 23:34, Chris Morgan wrote:
> From: Chris Morgan <macromorgan@hotmail.com>
>
> In order to support Rockchip devices with the VOP2, import the VOP2
> dt-bindings from Linux.
>
> Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   include/dt-bindings/soc/rockchip,vop2.h | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
>   create mode 100644 include/dt-bindings/soc/rockchip,vop2.h
>
> diff --git a/include/dt-bindings/soc/rockchip,vop2.h b/include/dt-bindings/soc/rockchip,vop2.h
> new file mode 100644
> index 0000000000..6e66a802b9
> --- /dev/null
> +++ b/include/dt-bindings/soc/rockchip,vop2.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
> +
> +#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H
> +#define __DT_BINDINGS_ROCKCHIP_VOP2_H
> +
> +#define ROCKCHIP_VOP2_EP_RGB0	1
> +#define ROCKCHIP_VOP2_EP_HDMI0	2
> +#define ROCKCHIP_VOP2_EP_EDP0	3
> +#define ROCKCHIP_VOP2_EP_MIPI0	4
> +#define ROCKCHIP_VOP2_EP_LVDS0	5
> +#define ROCKCHIP_VOP2_EP_MIPI1	6
> +#define ROCKCHIP_VOP2_EP_LVDS1	7
> +
> +#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 3/5] rockchip: rk3568: add boot device detection
  2023-01-05 15:34 ` [PATCH 3/5] rockchip: rk3568: add boot device detection Chris Morgan
@ 2023-01-17  2:09   ` Kever Yang
  0 siblings, 0 replies; 14+ messages in thread
From: Kever Yang @ 2023-01-17  2:09 UTC (permalink / raw)
  To: Chris Morgan, u-boot
  Cc: sjg, philipp.tomsich, chenjh, pgwipeout, heiko.stuebner, Chris Morgan

Hi Chris,

On 2023/1/5 23:34, Chris Morgan wrote:
> From: Chris Morgan <macromorgan@hotmail.com>
>
> Enable spl to detect which device it was booted from.
>
> Adapted from Peter Geis's work located here:
> https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/3a10fb6bfbbaa747b425233b1fc08cd008084281

You can add "Signed-off-by " for Peter Geis, which means you are the 
co-author of this patch,

and remove the link of personal gitlab above.


Thanks,

- Kever

>
> Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> ---
>   arch/arm/mach-rockchip/rk3568/rk3568.c | 7 +++++++
>   1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm/mach-rockchip/rk3568/rk3568.c b/arch/arm/mach-rockchip/rk3568/rk3568.c
> index 22eeb77d41..a2d59abc26 100644
> --- a/arch/arm/mach-rockchip/rk3568/rk3568.c
> +++ b/arch/arm/mach-rockchip/rk3568/rk3568.c
> @@ -7,6 +7,7 @@
>   #include <dm.h>
>   #include <asm/armv8/mmu.h>
>   #include <asm/io.h>
> +#include <asm/arch-rockchip/bootrom.h>
>   #include <asm/arch-rockchip/grf_rk3568.h>
>   #include <asm/arch-rockchip/hardware.h>
>   #include <dt-bindings/clock/rk3568-cru.h>
> @@ -70,6 +71,12 @@ static struct mm_region rk3568_mem_map[] = {
>   	}
>   };
>   
> +const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
> +	[BROM_BOOTSOURCE_EMMC] = "/sdhci@fe310000",
> +	[BROM_BOOTSOURCE_SPINOR] = "/spi@fe300000/flash@0",
> +	[BROM_BOOTSOURCE_SD] = "/mmc@fe2b0000",
> +};
> +
>   struct mm_region *mem_map = rk3568_mem_map;
>   
>   void board_debug_uart_init(void)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller
  2023-01-05 18:01   ` Quentin Schulz
@ 2023-01-19 18:21     ` Chris Morgan
  2023-01-26 16:11       ` Chris Morgan
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Morgan @ 2023-01-19 18:21 UTC (permalink / raw)
  To: Quentin Schulz
  Cc: Chris Morgan, u-boot, sjg, philipp.tomsich, kever.yang, chenjh,
	pgwipeout, Heiko Stuebner

On Thu, Jan 05, 2023 at 07:01:40PM +0100, Quentin Schulz wrote:
> Hi Chris,
> 
> Cc'ing the new mail address of Heiko so he receives this mail :)
> 
> On 1/5/23 16:34, Chris Morgan wrote:
> > From: Chris Morgan <macromorgan@hotmail.com>
> > 
> > Add support for the newer GPIO controller used by the rk356x series,
> > as well as the pinctrl device for the rk356x series. The GPIOv2
> > controller has a write enable bit for some registers which differs
> > from the older versions of the GPIO controller.
> > 
> > Adapted from Peter Geis's gitlab located here:
> > https://urldefense.com/v3/__https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd__;!!OOPJP91ZZw!i7xaxb0VOR6CU_lauUnYs4-WlEgdGZCaETaNwp--V4jwJoQguyPr07GTOXDhDNNYL4vYLzae_eObZKZUYUAm4pVFA6vGK-JnXjIz$
> > 
> > Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> > ---
> >   arch/arm/include/asm/arch-rockchip/gpio.h     |  38 ++
> >   drivers/gpio/Kconfig                          |  13 +
> >   drivers/gpio/rk_gpio.c                        | 103 +++-
> >   drivers/pinctrl/rockchip/Makefile             |   1 +
> >   drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++++++++
> >   .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
> >   drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
> >   7 files changed, 635 insertions(+), 27 deletions(-)
> >   create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c
> > 
> > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
> > index 1aaec5faec..29120ceaf3 100644
> > --- a/arch/arm/include/asm/arch-rockchip/gpio.h
> > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h
> > @@ -6,6 +6,7 @@
> >   #ifndef _ASM_ARCH_GPIO_H
> >   #define _ASM_ARCH_GPIO_H
> > +#ifndef CONFIG_ROCKCHIP_GPIO_V2
> >   struct rockchip_gpio_regs {
> >   	u32 swport_dr;
> >   	u32 swport_ddr;
> > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs {
> >   	u32 reserved1[(0x60 - 0x54) / 4];
> >   	u32 ls_sync;
> >   };
> > +
> >   check_member(rockchip_gpio_regs, ls_sync, 0x60);
> > +#else
> > +struct rockchip_gpio_regs {
> > +	u32 swport_dr_l;                        /* ADDRESS OFFSET: 0x0000 */
> > +	u32 swport_dr_h;                        /* ADDRESS OFFSET: 0x0004 */
> > +	u32 swport_ddr_l;                       /* ADDRESS OFFSET: 0x0008 */
> > +	u32 swport_ddr_h;                       /* ADDRESS OFFSET: 0x000c */
> > +	u32 int_en_l;                           /* ADDRESS OFFSET: 0x0010 */
> > +	u32 int_en_h;                           /* ADDRESS OFFSET: 0x0014 */
> > +	u32 int_mask_l;                         /* ADDRESS OFFSET: 0x0018 */
> > +	u32 int_mask_h;                         /* ADDRESS OFFSET: 0x001c */
> > +	u32 int_type_l;                         /* ADDRESS OFFSET: 0x0020 */
> > +	u32 int_type_h;                         /* ADDRESS OFFSET: 0x0024 */
> > +	u32 int_polarity_l;                     /* ADDRESS OFFSET: 0x0028 */
> > +	u32 int_polarity_h;                     /* ADDRESS OFFSET: 0x002c */
> > +	u32 int_bothedge_l;                     /* ADDRESS OFFSET: 0x0030 */
> > +	u32 int_bothedge_h;                     /* ADDRESS OFFSET: 0x0034 */
> > +	u32 debounce_l;                         /* ADDRESS OFFSET: 0x0038 */
> > +	u32 debounce_h;                         /* ADDRESS OFFSET: 0x003c */
> > +	u32 dbclk_div_en_l;                     /* ADDRESS OFFSET: 0x0040 */
> > +	u32 dbclk_div_en_h;                     /* ADDRESS OFFSET: 0x0044 */
> > +	u32 dbclk_div_con;                      /* ADDRESS OFFSET: 0x0048 */
> > +	u32 reserved004c;                       /* ADDRESS OFFSET: 0x004c */
> > +	u32 int_status;                         /* ADDRESS OFFSET: 0x0050 */
> > +	u32 reserved0054;                       /* ADDRESS OFFSET: 0x0054 */
> > +	u32 int_rawstatus;                      /* ADDRESS OFFSET: 0x0058 */
> > +	u32 reserved005c;                       /* ADDRESS OFFSET: 0x005c */
> > +	u32 port_eoi_l;                         /* ADDRESS OFFSET: 0x0060 */
> > +	u32 port_eoi_h;                         /* ADDRESS OFFSET: 0x0064 */
> > +	u32 reserved0068[2];                    /* ADDRESS OFFSET: 0x0068 */
> > +	u32 ext_port;                           /* ADDRESS OFFSET: 0x0070 */
> > +	u32 reserved0074;                       /* ADDRESS OFFSET: 0x0074 */
> > +	u32 ver_id;                             /* ADDRESS OFFSET: 0x0078 */
> > +};
> > +
> > +check_member(rockchip_gpio_regs, ver_id, 0x0078);
> > +#endif
> >   enum gpio_pu_pd {
> >   	GPIO_PULL_NORMAL = 0,
> > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > index ff87fbfb39..bd7422a0b3 100644
> > --- a/drivers/gpio/Kconfig
> > +++ b/drivers/gpio/Kconfig
> > @@ -340,6 +340,19 @@ config ROCKCHIP_GPIO
> >   	  The GPIOs for a device are defined in the device tree with one node
> >   	  for each bank.
> > +config ROCKCHIP_GPIO_V2
> > +	bool "Rockchip GPIO driver version 2.0"
> > +	depends on ROCKCHIP_GPIO
> 
> I would make ROCKCHIP_GPIO and ROCKCHIP_GPIO_V2 incompatible with each
> other, otherwise ROCKCHIP_GPIO represents both the GPIO controller and the
> v1, but not v1 if v2 is selected. That's a bit confusing to me.
> 
> [...]
> > @@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev)
> >   {
> >   	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> >   	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
> > -	char *end;
> > -	int ret;
> > +	struct rockchip_pinctrl_priv *pctrl_priv;
> > +	struct rockchip_pin_bank *bank;
> > +	char *end = NULL;
> > +	static int gpio;
> > +	int id = -1, ret;
> >   	priv->regs = dev_read_addr_ptr(dev);
> >   	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
> > -	if (ret)
> > +	if (ret) {
> > +		dev_err(dev, "failed to get pinctrl device %d\n", ret);
> >   		return ret;
> > +	}
> > +
> > +	pctrl_priv = dev_get_priv(priv->pinctrl);
> > +	if (!pctrl_priv) {
> > +		dev_err(dev, "failed to get pinctrl priv\n");
> > +		return -EINVAL;
> > +	}
> > -	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
> >   	end = strrchr(dev->name, '@');
> > -	priv->bank = trailing_strtoln(dev->name, end);
> > -	priv->name[0] = 'A' + priv->bank;
> > -	uc_priv->bank_name = priv->name;
> > +	if (end)
> > +		id = trailing_strtoln(dev->name, end);
> > +	else
> > +		dev_read_alias_seq(dev, &id);
> > +
> > +	if (id < 0)
> > +		id = gpio++;
> > +
> 
> NACK. This does not work.
> 
> This means that the gpio bank detection depends on:
> 1) the index of the alias (no guarantee it's stable/not overwritten by a
> board dts),
> 2) if no support for aliases (e.g. in TPL/SPL) or the alias does not exist,
> the probe order of the GPIO controller device will define its bank. This is
> somewhat working in the Linux kernel by chance but does NOT work in U-Boot
> (devices are probed only when used, so you could very well have gpio4
> controller probed before gpio0 and then gpio4 would represent bank 0 and
> then gpio0 represent bank 1).
> 
> Yes, the current code will not work for "newer" DTS and needs to be adapted
> (FWIW, it does not work on PX30 already because the node name is gpio@addr
> instead of gpioX@addr), but the Linux kernel implementation (the one used
> above) is not correct and should not be used.
> 
> I've two suggestions:
> 1) a rockchip,gpio-controller-bank = <0>; property in the -u-boot.dtsi for
> each gpio-controller and then you get the index from there in the driver,
> 2) get the register address of the node of the device you're currently
> probing and maintain a mapping of which address maps to which bank,
> 
> We could also start a discussion with upstream Linux to see what they would
> like to go for so we don't have two different implementations.

I see RFC patches for Linux to use a property called "gpio-ranges".
I'll wait for that to gain traction as a solution before I resubmit
this so that Linux/U-Boot use roughly the same method (assuming
Johan doesn't beat me to the punch, since it's his Linux patches
I'm following).

Thank you.

> 
> > +	if (id >= pctrl_priv->ctrl->nr_banks) {
> > +		dev_err(dev, "bank id invalid\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	bank = &pctrl_priv->ctrl->pin_banks[id];
> > +	if (bank->bank_num != id) {
> > +		dev_err(dev, "bank id mismatch with pinctrl\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	priv->bank = bank->bank_num;
> > +	uc_priv->gpio_count = bank->nr_pins;
> > +	uc_priv->gpio_base = bank->pin_base;
> > +	uc_priv->bank_name = bank->name;
> >   	return 0;
> >   }
> > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> > index 7d03f8101d..c78fc2c331 100644
> > --- a/drivers/pinctrl/rockchip/Makefile
> > +++ b/drivers/pinctrl/rockchip/Makefile
> > @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o
> >   obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
> >   obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
> >   obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
> > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
> >   obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
> > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> > new file mode 100644
> > index 0000000000..dce1c1e7ee
> > --- /dev/null
> > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> > @@ -0,0 +1,453 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd
> > + */
> > +
> > +#include <common.h>
> > +#include <dm.h>
> > +#include <dm/pinctrl.h>
> > +#include <regmap.h>
> > +#include <syscon.h>
> > +
> > +#include "pinctrl-rockchip.h"
> > +
> > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
> > +	/* CAN0 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)),
> > +	/* CAN0 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)),
> > +	/* CAN1 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)),
> > +	/* CAN1 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)),
> > +	/* CAN2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)),
> > +	/* CAN2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)),
> > +	/* EDPDP_HPDIN IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)),
> > +	/* EDPDP_HPDIN IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)),
> > +	/* GMAC1 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)),
> > +	/* GMAC1 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)),
> > +	/* HDMITX IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)),
> > +	/* HDMITX IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)),
> > +	/* I2C2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)),
> > +	/* I2C2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)),
> > +	/* I2C3 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)),
> > +	/* I2C3 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)),
> > +	/* I2C4 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)),
> > +	/* I2C4 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)),
> > +	/* I2C5 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)),
> > +	/* I2C5 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)),
> > +	/* PWM4 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)),
> > +	/* PWM4 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)),
> > +	/* PWM5 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)),
> > +	/* PWM5 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)),
> > +	/* PWM6 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)),
> > +	/* PWM6 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)),
> > +	/* PWM7 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)),
> > +	/* PWM7 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)),
> > +	/* PWM8 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)),
> > +	/* PWM8 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)),
> > +	/* PWM9 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)),
> > +	/* PWM9 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)),
> > +	/* PWM10 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)),
> > +	/* PWM10 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)),
> > +	/* PWM11 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)),
> > +	/* PWM11 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)),
> > +	/* PWM12 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)),
> > +	/* PWM12 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)),
> > +	/* PWM13 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)),
> > +	/* PWM13 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)),
> > +	/* PWM14 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)),
> > +	/* PWM14 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)),
> > +	/* PWM15 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)),
> > +	/* PWM15 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)),
> > +	/* SDMMC2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)),
> > +	/* SDMMC2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)),
> > +	/* SPI0 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)),
> > +	/* SPI0 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)),
> > +	/* SPI1 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)),
> > +	/* SPI1 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)),
> > +	/* SPI2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)),
> > +	/* SPI2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)),
> > +	/* SPI3 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)),
> > +	/* SPI3 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)),
> > +	/* UART1 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)),
> > +	/* UART1 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)),
> > +	/* UART2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)),
> > +	/* UART2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)),
> > +	/* UART3 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)),
> > +	/* UART3 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)),
> > +	/* UART4 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)),
> > +	/* UART4 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)),
> > +	/* UART5 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)),
> > +	/* UART5 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)),
> > +	/* UART6 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)),
> > +	/* UART6 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)),
> > +	/* UART7 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)),
> > +	/* UART7 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)),
> > +	/* UART7 IO mux selection M2 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)),
> > +	/* UART8 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)),
> > +	/* UART8 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)),
> > +	/* UART9 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)),
> > +	/* UART9 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)),
> > +	/* UART9 IO mux selection M2 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)),
> > +	/* I2S1 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)),
> > +	/* I2S1 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)),
> > +	/* I2S1 IO mux selection M2 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)),
> > +	/* I2S2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)),
> > +	/* I2S2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)),
> > +	/* I2S3 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)),
> > +	/* I2S3 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)),
> > +	/* PDM IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)),
> > +	/* PDM IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)),
> > +	/* PCIE20 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)),
> > +	/* PCIE20 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)),
> > +	/* PCIE20 IO mux selection M2 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)),
> > +	/* PCIE30X1 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)),
> > +	/* PCIE30X1 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)),
> > +	/* PCIE30X1 IO mux selection M2 */
> > +	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)),
> > +	/* PCIE30X2 IO mux selection M0 */
> > +	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)),
> > +	/* PCIE30X2 IO mux selection M1 */
> > +	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)),
> > +	/* PCIE30X2 IO mux selection M2 */
> > +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)),
> > +};
> > +
> > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
> > +{
> > +	struct rockchip_pinctrl_priv *priv = bank->priv;
> > +	int iomux_num = (pin / 8);
> > +	struct regmap *regmap;
> > +	int reg, ret, mask;
> > +	u8 bit;
> > +	u32 data;
> > +
> > +	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
> > +
> > +	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
> > +		regmap = priv->regmap_pmu;
> > +	else
> > +		regmap = priv->regmap_base;
> > +
> > +	reg = bank->iomux[iomux_num].offset;
> > +	if ((pin % 8) >= 4)
> > +		reg += 0x4;
> > +	bit = (pin % 4) * 4;
> > +	mask = 0xf;
> > +
> > +	data = (mask << (bit + 16));
> > +	data |= (mux & mask) << bit;
> > +	ret = regmap_write(regmap, reg, data);
> > +
> > +	return ret;
> > +}
> > +
> > +#define RK3568_PULL_PMU_OFFSET		0x20
> > +#define RK3568_PULL_GRF_OFFSET		0x80
> > +#define RK3568_PULL_BITS_PER_PIN	2
> > +#define RK3568_PULL_PINS_PER_REG	8
> > +#define RK3568_PULL_BANK_STRIDE		0x10
> > +
> > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> > +					 int pin_num, struct regmap **regmap,
> > +					 int *reg, u8 *bit)
> > +{
> > +	struct rockchip_pinctrl_priv *info = bank->priv;
> > +
> > +	if (bank->bank_num == 0) {
> > +		*regmap = info->regmap_pmu;
> > +		*reg = RK3568_PULL_PMU_OFFSET;
> > +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
> > +	} else {
> > +		*regmap = info->regmap_base;
> > +		*reg = RK3568_PULL_GRF_OFFSET;
> > +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
> > +	}
> > +
> > +	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> > +	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
> > +	*bit *= RK3568_PULL_BITS_PER_PIN;
> > +}
> > +
> > +#define RK3568_DRV_PMU_OFFSET		0x70
> > +#define RK3568_DRV_GRF_OFFSET		0x200
> > +#define RK3568_DRV_BITS_PER_PIN		8
> > +#define RK3568_DRV_PINS_PER_REG		2
> > +#define RK3568_DRV_BANK_STRIDE		0x40
> > +
> > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> > +					int pin_num, struct regmap **regmap,
> > +					int *reg, u8 *bit)
> > +{
> > +	struct rockchip_pinctrl_priv *info = bank->priv;
> > +
> > +	/* The first 32 pins of the first bank are located in PMU */
> > +	if (bank->bank_num == 0) {
> > +		*regmap = info->regmap_pmu;
> > +		*reg = RK3568_DRV_PMU_OFFSET;
> > +	} else {
> > +		*regmap = info->regmap_base;
> > +		*reg = RK3568_DRV_GRF_OFFSET;
> > +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
> > +	}
> > +
> > +	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> > +	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
> > +	*bit *= RK3568_DRV_BITS_PER_PIN;
> > +}
> > +
> > +#define RK3568_SCHMITT_BITS_PER_PIN		2
> > +#define RK3568_SCHMITT_PINS_PER_REG		8
> > +#define RK3568_SCHMITT_BANK_STRIDE		0x10
> > +#define RK3568_SCHMITT_GRF_OFFSET		0xc0
> > +#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
> > +
> > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
> > +					   int pin_num, struct regmap **regmap,
> > +					   int *reg, u8 *bit)
> > +{
> > +	struct rockchip_pinctrl_priv *info = bank->priv;
> > +
> > +	if (bank->bank_num == 0) {
> > +		*regmap = info->regmap_pmu;
> > +		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
> > +	} else {
> > +		*regmap = info->regmap_base;
> > +		*reg = RK3568_SCHMITT_GRF_OFFSET;
> > +		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
> > +	}
> > +
> > +	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
> > +	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
> > +	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
> > +
> > +	return 0;
> > +}
> > +
> > +static int rk3568_set_pull(struct rockchip_pin_bank *bank,
> > +			   int pin_num, int pull)
> > +{
> > +	struct regmap *regmap;
> > +	int reg, ret;
> > +	u8 bit, type;
> > +	u32 data;
> > +
> > +	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
> > +		return -EOPNOTSUPP;
> > +
> > +	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> > +	type = bank->pull_type[pin_num / 8];
> > +	ret = rockchip_translate_pull_value(type, pull);
> > +	if (ret < 0) {
> > +		debug("unsupported pull setting %d\n", pull);
> > +		return ret;
> > +	}
> > +
> > +	/* enable the write to the equivalent lower bits */
> > +	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
> > +
> > +	data |= (ret << bit);
> > +	ret = regmap_write(regmap, reg, data);
> > +
> > +	return ret;
> > +}
> > +
> > +static int rk3568_set_drive(struct rockchip_pin_bank *bank,
> > +			    int pin_num, int strength)
> > +{
> > +	struct regmap *regmap;
> > +	int reg;
> > +	u32 data;
> > +	u8 bit;
> > +	int drv = (1 << (strength + 1)) - 1;
> > +	int ret = 0;
> > +
> > +	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> > +
> > +	/* enable the write to the equivalent lower bits */
> > +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
> > +	data |= (drv << bit);
> > +
> > +	ret = regmap_write(regmap, reg, data);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (bank->bank_num == 1 && pin_num == 21)
> > +		reg = 0x0840;
> > +	else if (bank->bank_num == 2 && pin_num == 2)
> > +		reg = 0x0844;
> > +	else if (bank->bank_num == 2 && pin_num == 8)
> > +		reg = 0x0848;
> > +	else if (bank->bank_num == 3 && pin_num == 0)
> > +		reg = 0x084c;
> > +	else if (bank->bank_num == 3 && pin_num == 6)
> > +		reg = 0x0850;
> > +	else if (bank->bank_num == 4 && pin_num == 0)
> > +		reg = 0x0854;
> > +	else
> > +		return 0;
> > +
> > +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
> > +	data |= drv;
> > +
> > +	return regmap_write(regmap, reg, data);
> > +}
> > +
> > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
> > +			      int pin_num, int enable)
> > +{
> > +	struct regmap *regmap;
> > +	int reg;
> > +	u32 data;
> > +	u8 bit;
> > +
> > +	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> > +
> > +	/* enable the write to the equivalent lower bits */
> > +	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
> > +	data |= (enable << bit);
> > +
> > +	return regmap_write(regmap, reg, data);
> > +}
> > +
> > +static struct rockchip_pin_bank rk3568_pin_banks[] = {
> > +	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> > +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> > +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> > +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
> > +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT),
> > +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT),
> > +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT),
> > +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT,
> > +			     IOMUX_WIDTH_4BIT),
> > +};
> > +
> > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
> > +	.pin_banks		= rk3568_pin_banks,
> > +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
> > +	.nr_pins		= 160,
> > +	.grf_mux_offset		= 0x0,
> > +	.pmu_mux_offset		= 0x0,
> > +	.iomux_routes		= rk3568_mux_route_data,
> > +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
> > +	.set_mux		= rk3568_set_mux,
> > +	.set_pull		= rk3568_set_pull,
> > +	.set_drive		= rk3568_set_drive,
> > +	.set_schmitt		= rk3568_set_schmitt,
> > +};
> > +
> > +static const struct udevice_id rk3568_pinctrl_ids[] = {
> > +	{
> > +		.compatible = "rockchip,rk3568-pinctrl",
> > +		.data = (ulong)&rk3568_pin_ctrl
> > +	},
> > +	{ }
> > +};
> > +
> > +U_BOOT_DRIVER(pinctrl_rk3568) = {
> > +	.name		= "rockchip_rk3568_pinctrl",
> > +	.id		= UCLASS_PINCTRL,
> > +	.of_match	= rk3568_pinctrl_ids,
> > +	.priv_auto = sizeof(struct rockchip_pinctrl_priv),
> > +	.ops		= &rockchip_pinctrl_ops,
> > +#if !IS_ENABLED(CONFIG_OF_PLATDATA)
> > +	.bind		= dm_scan_fdt_dev,
> > +#endif
> > +	.probe		= rockchip_pinctrl_probe,
> > +};
> > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> > index 630513ba3a..5f0016ff60 100644
> > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> > @@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
> >   	int prop_len, param;
> >   	const u32 *data;
> >   	ofnode node;
> > -#ifdef CONFIG_OF_LIVE
> > +#if CONFIG_IS_ENABLED(OF_LIVE)
> 
> Not sure this is really related or not, would be better in its own commit I
> believe.
> 
> >   	const struct device_node *np;
> >   	struct property *pp;
> >   #else
> > @@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
> >   		node = ofnode_get_by_phandle(conf);
> >   		if (!ofnode_valid(node))
> >   			return -ENODEV;
> > -#ifdef CONFIG_OF_LIVE
> > +#if CONFIG_IS_ENABLED(OF_LIVE)
> >   		np = ofnode_to_np(node);
> >   		for (pp = np->properties; pp; pp = pp->next) {
> >   			prop_name = pp->name;
> > @@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
> >   			/* preset iomux offset value, set new start value */
> >   			if (iom->offset >= 0) {
> > -				if (iom->type & IOMUX_SOURCE_PMU)
> > +				if ((iom->type & IOMUX_SOURCE_PMU) || \
> > +				    (iom->type & IOMUX_L_SOURCE_PMU))
> 
> nitpick: Could be if (iom->type & (IOMUX_SOURCE_PMU | IOMUX_L_SOURCE_PMU))
> instead.
> 
> >   					pmu_offs = iom->offset;
> >   				else
> >   					grf_offs = iom->offset;
> >   			} else { /* set current iomux offset */
> > -				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
> > -							pmu_offs : grf_offs;
> > +				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
> > +						(iom->type & IOMUX_L_SOURCE_PMU)) ?
> 
> Ditto.
> 
> Cheers,
> Quentin

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller
  2023-01-19 18:21     ` Chris Morgan
@ 2023-01-26 16:11       ` Chris Morgan
  2023-01-26 18:11         ` Johan Jonker
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Morgan @ 2023-01-26 16:11 UTC (permalink / raw)
  To: Chris Morgan
  Cc: Quentin Schulz, u-boot, sjg, philipp.tomsich, kever.yang, chenjh,
	pgwipeout, Heiko Stuebner, jbx6244

On Thu, Jan 19, 2023 at 12:21:02PM -0600, Chris Morgan wrote:
> On Thu, Jan 05, 2023 at 07:01:40PM +0100, Quentin Schulz wrote:
> > Hi Chris,
> > 
> > Cc'ing the new mail address of Heiko so he receives this mail :)
> > 
> > On 1/5/23 16:34, Chris Morgan wrote:
> > > From: Chris Morgan <macromorgan@hotmail.com>
> > > 
> > > Add support for the newer GPIO controller used by the rk356x series,
> > > as well as the pinctrl device for the rk356x series. The GPIOv2
> > > controller has a write enable bit for some registers which differs
> > > from the older versions of the GPIO controller.
> > > 
> > > Adapted from Peter Geis's gitlab located here:
> > > https://urldefense.com/v3/__https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd__;!!OOPJP91ZZw!i7xaxb0VOR6CU_lauUnYs4-WlEgdGZCaETaNwp--V4jwJoQguyPr07GTOXDhDNNYL4vYLzae_eObZKZUYUAm4pVFA6vGK-JnXjIz$
> > > 
> > > Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> > > ---
> > >   arch/arm/include/asm/arch-rockchip/gpio.h     |  38 ++
> > >   drivers/gpio/Kconfig                          |  13 +
> > >   drivers/gpio/rk_gpio.c                        | 103 +++-
> > >   drivers/pinctrl/rockchip/Makefile             |   1 +
> > >   drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++++++++
> > >   .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
> > >   drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
> > >   7 files changed, 635 insertions(+), 27 deletions(-)
> > >   create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c
> > > 
> > > diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
> > > index 1aaec5faec..29120ceaf3 100644
> > > --- a/arch/arm/include/asm/arch-rockchip/gpio.h
> > > +++ b/arch/arm/include/asm/arch-rockchip/gpio.h
> > > @@ -6,6 +6,7 @@
> > >   #ifndef _ASM_ARCH_GPIO_H
> > >   #define _ASM_ARCH_GPIO_H
> > > +#ifndef CONFIG_ROCKCHIP_GPIO_V2
> > >   struct rockchip_gpio_regs {
> > >   	u32 swport_dr;
> > >   	u32 swport_ddr;
> > > @@ -22,7 +23,44 @@ struct rockchip_gpio_regs {
> > >   	u32 reserved1[(0x60 - 0x54) / 4];
> > >   	u32 ls_sync;
> > >   };
> > > +
> > >   check_member(rockchip_gpio_regs, ls_sync, 0x60);
> > > +#else
> > > +struct rockchip_gpio_regs {
> > > +	u32 swport_dr_l;                        /* ADDRESS OFFSET: 0x0000 */
> > > +	u32 swport_dr_h;                        /* ADDRESS OFFSET: 0x0004 */
> > > +	u32 swport_ddr_l;                       /* ADDRESS OFFSET: 0x0008 */
> > > +	u32 swport_ddr_h;                       /* ADDRESS OFFSET: 0x000c */
> > > +	u32 int_en_l;                           /* ADDRESS OFFSET: 0x0010 */
> > > +	u32 int_en_h;                           /* ADDRESS OFFSET: 0x0014 */
> > > +	u32 int_mask_l;                         /* ADDRESS OFFSET: 0x0018 */
> > > +	u32 int_mask_h;                         /* ADDRESS OFFSET: 0x001c */
> > > +	u32 int_type_l;                         /* ADDRESS OFFSET: 0x0020 */
> > > +	u32 int_type_h;                         /* ADDRESS OFFSET: 0x0024 */
> > > +	u32 int_polarity_l;                     /* ADDRESS OFFSET: 0x0028 */
> > > +	u32 int_polarity_h;                     /* ADDRESS OFFSET: 0x002c */
> > > +	u32 int_bothedge_l;                     /* ADDRESS OFFSET: 0x0030 */
> > > +	u32 int_bothedge_h;                     /* ADDRESS OFFSET: 0x0034 */
> > > +	u32 debounce_l;                         /* ADDRESS OFFSET: 0x0038 */
> > > +	u32 debounce_h;                         /* ADDRESS OFFSET: 0x003c */
> > > +	u32 dbclk_div_en_l;                     /* ADDRESS OFFSET: 0x0040 */
> > > +	u32 dbclk_div_en_h;                     /* ADDRESS OFFSET: 0x0044 */
> > > +	u32 dbclk_div_con;                      /* ADDRESS OFFSET: 0x0048 */
> > > +	u32 reserved004c;                       /* ADDRESS OFFSET: 0x004c */
> > > +	u32 int_status;                         /* ADDRESS OFFSET: 0x0050 */
> > > +	u32 reserved0054;                       /* ADDRESS OFFSET: 0x0054 */
> > > +	u32 int_rawstatus;                      /* ADDRESS OFFSET: 0x0058 */
> > > +	u32 reserved005c;                       /* ADDRESS OFFSET: 0x005c */
> > > +	u32 port_eoi_l;                         /* ADDRESS OFFSET: 0x0060 */
> > > +	u32 port_eoi_h;                         /* ADDRESS OFFSET: 0x0064 */
> > > +	u32 reserved0068[2];                    /* ADDRESS OFFSET: 0x0068 */
> > > +	u32 ext_port;                           /* ADDRESS OFFSET: 0x0070 */
> > > +	u32 reserved0074;                       /* ADDRESS OFFSET: 0x0074 */
> > > +	u32 ver_id;                             /* ADDRESS OFFSET: 0x0078 */
> > > +};
> > > +
> > > +check_member(rockchip_gpio_regs, ver_id, 0x0078);
> > > +#endif
> > >   enum gpio_pu_pd {
> > >   	GPIO_PULL_NORMAL = 0,
> > > diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> > > index ff87fbfb39..bd7422a0b3 100644
> > > --- a/drivers/gpio/Kconfig
> > > +++ b/drivers/gpio/Kconfig
> > > @@ -340,6 +340,19 @@ config ROCKCHIP_GPIO
> > >   	  The GPIOs for a device are defined in the device tree with one node
> > >   	  for each bank.
> > > +config ROCKCHIP_GPIO_V2
> > > +	bool "Rockchip GPIO driver version 2.0"
> > > +	depends on ROCKCHIP_GPIO
> > 
> > I would make ROCKCHIP_GPIO and ROCKCHIP_GPIO_V2 incompatible with each
> > other, otherwise ROCKCHIP_GPIO represents both the GPIO controller and the
> > v1, but not v1 if v2 is selected. That's a bit confusing to me.
> > 
> > [...]
> > > @@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev)
> > >   {
> > >   	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> > >   	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
> > > -	char *end;
> > > -	int ret;
> > > +	struct rockchip_pinctrl_priv *pctrl_priv;
> > > +	struct rockchip_pin_bank *bank;
> > > +	char *end = NULL;
> > > +	static int gpio;
> > > +	int id = -1, ret;
> > >   	priv->regs = dev_read_addr_ptr(dev);
> > >   	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
> > > -	if (ret)
> > > +	if (ret) {
> > > +		dev_err(dev, "failed to get pinctrl device %d\n", ret);
> > >   		return ret;
> > > +	}
> > > +
> > > +	pctrl_priv = dev_get_priv(priv->pinctrl);
> > > +	if (!pctrl_priv) {
> > > +		dev_err(dev, "failed to get pinctrl priv\n");
> > > +		return -EINVAL;
> > > +	}
> > > -	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
> > >   	end = strrchr(dev->name, '@');
> > > -	priv->bank = trailing_strtoln(dev->name, end);
> > > -	priv->name[0] = 'A' + priv->bank;
> > > -	uc_priv->bank_name = priv->name;
> > > +	if (end)
> > > +		id = trailing_strtoln(dev->name, end);
> > > +	else
> > > +		dev_read_alias_seq(dev, &id);
> > > +
> > > +	if (id < 0)
> > > +		id = gpio++;
> > > +
> > 
> > NACK. This does not work.
> > 
> > This means that the gpio bank detection depends on:
> > 1) the index of the alias (no guarantee it's stable/not overwritten by a
> > board dts),
> > 2) if no support for aliases (e.g. in TPL/SPL) or the alias does not exist,
> > the probe order of the GPIO controller device will define its bank. This is
> > somewhat working in the Linux kernel by chance but does NOT work in U-Boot
> > (devices are probed only when used, so you could very well have gpio4
> > controller probed before gpio0 and then gpio4 would represent bank 0 and
> > then gpio0 represent bank 1).
> > 
> > Yes, the current code will not work for "newer" DTS and needs to be adapted
> > (FWIW, it does not work on PX30 already because the node name is gpio@addr
> > instead of gpioX@addr), but the Linux kernel implementation (the one used
> > above) is not correct and should not be used.
> > 
> > I've two suggestions:
> > 1) a rockchip,gpio-controller-bank = <0>; property in the -u-boot.dtsi for
> > each gpio-controller and then you get the index from there in the driver,
> > 2) get the register address of the node of the device you're currently
> > probing and maintain a mapping of which address maps to which bank,
> > 
> > We could also start a discussion with upstream Linux to see what they would
> > like to go for so we don't have two different implementations.
> 
> I see RFC patches for Linux to use a property called "gpio-ranges".
> I'll wait for that to gain traction as a solution before I resubmit
> this so that Linux/U-Boot use roughly the same method (assuming
> Johan doesn't beat me to the punch, since it's his Linux patches
> I'm following).
> 
> Thank you.

I see the mainline patches that Johan Jonker put together have been 
acked. Johan, are you going to also include these in U-Boot or would
you like for me to try my hand at it here as part of this series?

Thank you.

> 
> > 
> > > +	if (id >= pctrl_priv->ctrl->nr_banks) {
> > > +		dev_err(dev, "bank id invalid\n");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	bank = &pctrl_priv->ctrl->pin_banks[id];
> > > +	if (bank->bank_num != id) {
> > > +		dev_err(dev, "bank id mismatch with pinctrl\n");
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	priv->bank = bank->bank_num;
> > > +	uc_priv->gpio_count = bank->nr_pins;
> > > +	uc_priv->gpio_base = bank->pin_base;
> > > +	uc_priv->bank_name = bank->name;
> > >   	return 0;
> > >   }
> > > diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> > > index 7d03f8101d..c78fc2c331 100644
> > > --- a/drivers/pinctrl/rockchip/Makefile
> > > +++ b/drivers/pinctrl/rockchip/Makefile
> > > @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o
> > >   obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
> > >   obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
> > >   obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
> > > +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
> > >   obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
> > > diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> > > new file mode 100644
> > > index 0000000000..dce1c1e7ee
> > > --- /dev/null
> > > +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> > > @@ -0,0 +1,453 @@
> > > +// SPDX-License-Identifier: GPL-2.0+
> > > +/*
> > > + * (C) Copyright 2020 Rockchip Electronics Co., Ltd
> > > + */
> > > +
> > > +#include <common.h>
> > > +#include <dm.h>
> > > +#include <dm/pinctrl.h>
> > > +#include <regmap.h>
> > > +#include <syscon.h>
> > > +
> > > +#include "pinctrl-rockchip.h"
> > > +
> > > +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
> > > +	/* CAN0 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)),
> > > +	/* CAN0 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)),
> > > +	/* CAN1 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)),
> > > +	/* CAN1 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)),
> > > +	/* CAN2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)),
> > > +	/* CAN2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)),
> > > +	/* EDPDP_HPDIN IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)),
> > > +	/* EDPDP_HPDIN IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)),
> > > +	/* GMAC1 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)),
> > > +	/* GMAC1 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)),
> > > +	/* HDMITX IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)),
> > > +	/* HDMITX IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)),
> > > +	/* I2C2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)),
> > > +	/* I2C2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)),
> > > +	/* I2C3 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)),
> > > +	/* I2C3 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)),
> > > +	/* I2C4 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)),
> > > +	/* I2C4 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)),
> > > +	/* I2C5 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)),
> > > +	/* I2C5 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)),
> > > +	/* PWM4 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)),
> > > +	/* PWM4 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)),
> > > +	/* PWM5 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)),
> > > +	/* PWM5 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)),
> > > +	/* PWM6 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)),
> > > +	/* PWM6 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)),
> > > +	/* PWM7 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)),
> > > +	/* PWM7 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)),
> > > +	/* PWM8 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)),
> > > +	/* PWM8 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)),
> > > +	/* PWM9 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)),
> > > +	/* PWM9 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)),
> > > +	/* PWM10 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)),
> > > +	/* PWM10 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)),
> > > +	/* PWM11 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)),
> > > +	/* PWM11 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)),
> > > +	/* PWM12 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)),
> > > +	/* PWM12 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)),
> > > +	/* PWM13 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)),
> > > +	/* PWM13 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)),
> > > +	/* PWM14 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)),
> > > +	/* PWM14 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)),
> > > +	/* PWM15 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)),
> > > +	/* PWM15 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)),
> > > +	/* SDMMC2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)),
> > > +	/* SDMMC2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)),
> > > +	/* SPI0 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)),
> > > +	/* SPI0 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)),
> > > +	/* SPI1 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)),
> > > +	/* SPI1 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)),
> > > +	/* SPI2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)),
> > > +	/* SPI2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)),
> > > +	/* SPI3 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)),
> > > +	/* SPI3 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)),
> > > +	/* UART1 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)),
> > > +	/* UART1 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)),
> > > +	/* UART2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)),
> > > +	/* UART2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)),
> > > +	/* UART3 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)),
> > > +	/* UART3 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)),
> > > +	/* UART4 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)),
> > > +	/* UART4 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)),
> > > +	/* UART5 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)),
> > > +	/* UART5 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)),
> > > +	/* UART6 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)),
> > > +	/* UART6 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)),
> > > +	/* UART7 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)),
> > > +	/* UART7 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)),
> > > +	/* UART7 IO mux selection M2 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)),
> > > +	/* UART8 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)),
> > > +	/* UART8 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)),
> > > +	/* UART9 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)),
> > > +	/* UART9 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)),
> > > +	/* UART9 IO mux selection M2 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)),
> > > +	/* I2S1 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)),
> > > +	/* I2S1 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)),
> > > +	/* I2S1 IO mux selection M2 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)),
> > > +	/* I2S2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)),
> > > +	/* I2S2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)),
> > > +	/* I2S3 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)),
> > > +	/* I2S3 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)),
> > > +	/* PDM IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)),
> > > +	/* PDM IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)),
> > > +	/* PCIE20 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)),
> > > +	/* PCIE20 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)),
> > > +	/* PCIE20 IO mux selection M2 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)),
> > > +	/* PCIE30X1 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)),
> > > +	/* PCIE30X1 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)),
> > > +	/* PCIE30X1 IO mux selection M2 */
> > > +	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)),
> > > +	/* PCIE30X2 IO mux selection M0 */
> > > +	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)),
> > > +	/* PCIE30X2 IO mux selection M1 */
> > > +	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)),
> > > +	/* PCIE30X2 IO mux selection M2 */
> > > +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)),
> > > +};
> > > +
> > > +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
> > > +{
> > > +	struct rockchip_pinctrl_priv *priv = bank->priv;
> > > +	int iomux_num = (pin / 8);
> > > +	struct regmap *regmap;
> > > +	int reg, ret, mask;
> > > +	u8 bit;
> > > +	u32 data;
> > > +
> > > +	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
> > > +
> > > +	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
> > > +		regmap = priv->regmap_pmu;
> > > +	else
> > > +		regmap = priv->regmap_base;
> > > +
> > > +	reg = bank->iomux[iomux_num].offset;
> > > +	if ((pin % 8) >= 4)
> > > +		reg += 0x4;
> > > +	bit = (pin % 4) * 4;
> > > +	mask = 0xf;
> > > +
> > > +	data = (mask << (bit + 16));
> > > +	data |= (mux & mask) << bit;
> > > +	ret = regmap_write(regmap, reg, data);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +#define RK3568_PULL_PMU_OFFSET		0x20
> > > +#define RK3568_PULL_GRF_OFFSET		0x80
> > > +#define RK3568_PULL_BITS_PER_PIN	2
> > > +#define RK3568_PULL_PINS_PER_REG	8
> > > +#define RK3568_PULL_BANK_STRIDE		0x10
> > > +
> > > +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> > > +					 int pin_num, struct regmap **regmap,
> > > +					 int *reg, u8 *bit)
> > > +{
> > > +	struct rockchip_pinctrl_priv *info = bank->priv;
> > > +
> > > +	if (bank->bank_num == 0) {
> > > +		*regmap = info->regmap_pmu;
> > > +		*reg = RK3568_PULL_PMU_OFFSET;
> > > +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
> > > +	} else {
> > > +		*regmap = info->regmap_base;
> > > +		*reg = RK3568_PULL_GRF_OFFSET;
> > > +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
> > > +	}
> > > +
> > > +	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> > > +	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
> > > +	*bit *= RK3568_PULL_BITS_PER_PIN;
> > > +}
> > > +
> > > +#define RK3568_DRV_PMU_OFFSET		0x70
> > > +#define RK3568_DRV_GRF_OFFSET		0x200
> > > +#define RK3568_DRV_BITS_PER_PIN		8
> > > +#define RK3568_DRV_PINS_PER_REG		2
> > > +#define RK3568_DRV_BANK_STRIDE		0x40
> > > +
> > > +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> > > +					int pin_num, struct regmap **regmap,
> > > +					int *reg, u8 *bit)
> > > +{
> > > +	struct rockchip_pinctrl_priv *info = bank->priv;
> > > +
> > > +	/* The first 32 pins of the first bank are located in PMU */
> > > +	if (bank->bank_num == 0) {
> > > +		*regmap = info->regmap_pmu;
> > > +		*reg = RK3568_DRV_PMU_OFFSET;
> > > +	} else {
> > > +		*regmap = info->regmap_base;
> > > +		*reg = RK3568_DRV_GRF_OFFSET;
> > > +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
> > > +	}
> > > +
> > > +	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> > > +	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
> > > +	*bit *= RK3568_DRV_BITS_PER_PIN;
> > > +}
> > > +
> > > +#define RK3568_SCHMITT_BITS_PER_PIN		2
> > > +#define RK3568_SCHMITT_PINS_PER_REG		8
> > > +#define RK3568_SCHMITT_BANK_STRIDE		0x10
> > > +#define RK3568_SCHMITT_GRF_OFFSET		0xc0
> > > +#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
> > > +
> > > +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
> > > +					   int pin_num, struct regmap **regmap,
> > > +					   int *reg, u8 *bit)
> > > +{
> > > +	struct rockchip_pinctrl_priv *info = bank->priv;
> > > +
> > > +	if (bank->bank_num == 0) {
> > > +		*regmap = info->regmap_pmu;
> > > +		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
> > > +	} else {
> > > +		*regmap = info->regmap_base;
> > > +		*reg = RK3568_SCHMITT_GRF_OFFSET;
> > > +		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
> > > +	}
> > > +
> > > +	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
> > > +	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
> > > +	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static int rk3568_set_pull(struct rockchip_pin_bank *bank,
> > > +			   int pin_num, int pull)
> > > +{
> > > +	struct regmap *regmap;
> > > +	int reg, ret;
> > > +	u8 bit, type;
> > > +	u32 data;
> > > +
> > > +	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
> > > +		return -EOPNOTSUPP;
> > > +
> > > +	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> > > +	type = bank->pull_type[pin_num / 8];
> > > +	ret = rockchip_translate_pull_value(type, pull);
> > > +	if (ret < 0) {
> > > +		debug("unsupported pull setting %d\n", pull);
> > > +		return ret;
> > > +	}
> > > +
> > > +	/* enable the write to the equivalent lower bits */
> > > +	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
> > > +
> > > +	data |= (ret << bit);
> > > +	ret = regmap_write(regmap, reg, data);
> > > +
> > > +	return ret;
> > > +}
> > > +
> > > +static int rk3568_set_drive(struct rockchip_pin_bank *bank,
> > > +			    int pin_num, int strength)
> > > +{
> > > +	struct regmap *regmap;
> > > +	int reg;
> > > +	u32 data;
> > > +	u8 bit;
> > > +	int drv = (1 << (strength + 1)) - 1;
> > > +	int ret = 0;
> > > +
> > > +	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> > > +
> > > +	/* enable the write to the equivalent lower bits */
> > > +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
> > > +	data |= (drv << bit);
> > > +
> > > +	ret = regmap_write(regmap, reg, data);
> > > +	if (ret)
> > > +		return ret;
> > > +
> > > +	if (bank->bank_num == 1 && pin_num == 21)
> > > +		reg = 0x0840;
> > > +	else if (bank->bank_num == 2 && pin_num == 2)
> > > +		reg = 0x0844;
> > > +	else if (bank->bank_num == 2 && pin_num == 8)
> > > +		reg = 0x0848;
> > > +	else if (bank->bank_num == 3 && pin_num == 0)
> > > +		reg = 0x084c;
> > > +	else if (bank->bank_num == 3 && pin_num == 6)
> > > +		reg = 0x0850;
> > > +	else if (bank->bank_num == 4 && pin_num == 0)
> > > +		reg = 0x0854;
> > > +	else
> > > +		return 0;
> > > +
> > > +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
> > > +	data |= drv;
> > > +
> > > +	return regmap_write(regmap, reg, data);
> > > +}
> > > +
> > > +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
> > > +			      int pin_num, int enable)
> > > +{
> > > +	struct regmap *regmap;
> > > +	int reg;
> > > +	u32 data;
> > > +	u8 bit;
> > > +
> > > +	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> > > +
> > > +	/* enable the write to the equivalent lower bits */
> > > +	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
> > > +	data |= (enable << bit);
> > > +
> > > +	return regmap_write(regmap, reg, data);
> > > +}
> > > +
> > > +static struct rockchip_pin_bank rk3568_pin_banks[] = {
> > > +	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
> > > +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT),
> > > +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT),
> > > +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT),
> > > +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT,
> > > +			     IOMUX_WIDTH_4BIT),
> > > +};
> > > +
> > > +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
> > > +	.pin_banks		= rk3568_pin_banks,
> > > +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
> > > +	.nr_pins		= 160,
> > > +	.grf_mux_offset		= 0x0,
> > > +	.pmu_mux_offset		= 0x0,
> > > +	.iomux_routes		= rk3568_mux_route_data,
> > > +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
> > > +	.set_mux		= rk3568_set_mux,
> > > +	.set_pull		= rk3568_set_pull,
> > > +	.set_drive		= rk3568_set_drive,
> > > +	.set_schmitt		= rk3568_set_schmitt,
> > > +};
> > > +
> > > +static const struct udevice_id rk3568_pinctrl_ids[] = {
> > > +	{
> > > +		.compatible = "rockchip,rk3568-pinctrl",
> > > +		.data = (ulong)&rk3568_pin_ctrl
> > > +	},
> > > +	{ }
> > > +};
> > > +
> > > +U_BOOT_DRIVER(pinctrl_rk3568) = {
> > > +	.name		= "rockchip_rk3568_pinctrl",
> > > +	.id		= UCLASS_PINCTRL,
> > > +	.of_match	= rk3568_pinctrl_ids,
> > > +	.priv_auto = sizeof(struct rockchip_pinctrl_priv),
> > > +	.ops		= &rockchip_pinctrl_ops,
> > > +#if !IS_ENABLED(CONFIG_OF_PLATDATA)
> > > +	.bind		= dm_scan_fdt_dev,
> > > +#endif
> > > +	.probe		= rockchip_pinctrl_probe,
> > > +};
> > > diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> > > index 630513ba3a..5f0016ff60 100644
> > > --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> > > +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> > > @@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
> > >   	int prop_len, param;
> > >   	const u32 *data;
> > >   	ofnode node;
> > > -#ifdef CONFIG_OF_LIVE
> > > +#if CONFIG_IS_ENABLED(OF_LIVE)
> > 
> > Not sure this is really related or not, would be better in its own commit I
> > believe.
> > 
> > >   	const struct device_node *np;
> > >   	struct property *pp;
> > >   #else
> > > @@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
> > >   		node = ofnode_get_by_phandle(conf);
> > >   		if (!ofnode_valid(node))
> > >   			return -ENODEV;
> > > -#ifdef CONFIG_OF_LIVE
> > > +#if CONFIG_IS_ENABLED(OF_LIVE)
> > >   		np = ofnode_to_np(node);
> > >   		for (pp = np->properties; pp; pp = pp->next) {
> > >   			prop_name = pp->name;
> > > @@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
> > >   			/* preset iomux offset value, set new start value */
> > >   			if (iom->offset >= 0) {
> > > -				if (iom->type & IOMUX_SOURCE_PMU)
> > > +				if ((iom->type & IOMUX_SOURCE_PMU) || \
> > > +				    (iom->type & IOMUX_L_SOURCE_PMU))
> > 
> > nitpick: Could be if (iom->type & (IOMUX_SOURCE_PMU | IOMUX_L_SOURCE_PMU))
> > instead.
> > 
> > >   					pmu_offs = iom->offset;
> > >   				else
> > >   					grf_offs = iom->offset;
> > >   			} else { /* set current iomux offset */
> > > -				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
> > > -							pmu_offs : grf_offs;
> > > +				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
> > > +						(iom->type & IOMUX_L_SOURCE_PMU)) ?
> > 
> > Ditto.
> > 
> > Cheers,
> > Quentin

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller
  2023-01-26 16:11       ` Chris Morgan
@ 2023-01-26 18:11         ` Johan Jonker
  2023-01-27 16:50           ` Chris Morgan
  0 siblings, 1 reply; 14+ messages in thread
From: Johan Jonker @ 2023-01-26 18:11 UTC (permalink / raw)
  To: Chris Morgan, Chris Morgan
  Cc: Quentin Schulz, u-boot, sjg, philipp.tomsich, kever.yang, chenjh,
	pgwipeout, Heiko Stuebner



On 1/26/23 17:11, Chris Morgan wrote:
> On Thu, Jan 19, 2023 at 12:21:02PM -0600, Chris Morgan wrote:
>> On Thu, Jan 05, 2023 at 07:01:40PM +0100, Quentin Schulz wrote:
>>> Hi Chris,
>>>
>>> Cc'ing the new mail address of Heiko so he receives this mail :)
>>>
>>> On 1/5/23 16:34, Chris Morgan wrote:
>>>> From: Chris Morgan <macromorgan@hotmail.com>
>>>>
>>>> Add support for the newer GPIO controller used by the rk356x series,
>>>> as well as the pinctrl device for the rk356x series. The GPIOv2
>>>> controller has a write enable bit for some registers which differs
>>>> from the older versions of the GPIO controller.
>>>>
>>>> Adapted from Peter Geis's gitlab located here:
>>>> https://urldefense.com/v3/__https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd__;!!OOPJP91ZZw!i7xaxb0VOR6CU_lauUnYs4-WlEgdGZCaETaNwp--V4jwJoQguyPr07GTOXDhDNNYL4vYLzae_eObZKZUYUAm4pVFA6vGK-JnXjIz$
>>>>
>>>> Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
>>>> ---
>>>>   arch/arm/include/asm/arch-rockchip/gpio.h     |  38 ++
>>>>   drivers/gpio/Kconfig                          |  13 +
>>>>   drivers/gpio/rk_gpio.c                        | 103 +++-
>>>>   drivers/pinctrl/rockchip/Makefile             |   1 +
>>>>   drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++++++++
>>>>   .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
>>>>   drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
>>>>   7 files changed, 635 insertions(+), 27 deletions(-)
>>>>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c
>>>>
>>>> diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
>>>> index 1aaec5faec..29120ceaf3 100644
>>>> --- a/arch/arm/include/asm/arch-rockchip/gpio.h
>>>> +++ b/arch/arm/include/asm/arch-rockchip/gpio.h
>>>> @@ -6,6 +6,7 @@
>>>>   #ifndef _ASM_ARCH_GPIO_H
>>>>   #define _ASM_ARCH_GPIO_H
>>>> +#ifndef CONFIG_ROCKCHIP_GPIO_V2
>>>>   struct rockchip_gpio_regs {
>>>>   	u32 swport_dr;
>>>>   	u32 swport_ddr;
>>>> @@ -22,7 +23,44 @@ struct rockchip_gpio_regs {
>>>>   	u32 reserved1[(0x60 - 0x54) / 4];
>>>>   	u32 ls_sync;
>>>>   };
>>>> +
>>>>   check_member(rockchip_gpio_regs, ls_sync, 0x60);
>>>> +#else
>>>> +struct rockchip_gpio_regs {
>>>> +	u32 swport_dr_l;                        /* ADDRESS OFFSET: 0x0000 */
>>>> +	u32 swport_dr_h;                        /* ADDRESS OFFSET: 0x0004 */
>>>> +	u32 swport_ddr_l;                       /* ADDRESS OFFSET: 0x0008 */
>>>> +	u32 swport_ddr_h;                       /* ADDRESS OFFSET: 0x000c */
>>>> +	u32 int_en_l;                           /* ADDRESS OFFSET: 0x0010 */
>>>> +	u32 int_en_h;                           /* ADDRESS OFFSET: 0x0014 */
>>>> +	u32 int_mask_l;                         /* ADDRESS OFFSET: 0x0018 */
>>>> +	u32 int_mask_h;                         /* ADDRESS OFFSET: 0x001c */
>>>> +	u32 int_type_l;                         /* ADDRESS OFFSET: 0x0020 */
>>>> +	u32 int_type_h;                         /* ADDRESS OFFSET: 0x0024 */
>>>> +	u32 int_polarity_l;                     /* ADDRESS OFFSET: 0x0028 */
>>>> +	u32 int_polarity_h;                     /* ADDRESS OFFSET: 0x002c */
>>>> +	u32 int_bothedge_l;                     /* ADDRESS OFFSET: 0x0030 */
>>>> +	u32 int_bothedge_h;                     /* ADDRESS OFFSET: 0x0034 */
>>>> +	u32 debounce_l;                         /* ADDRESS OFFSET: 0x0038 */
>>>> +	u32 debounce_h;                         /* ADDRESS OFFSET: 0x003c */
>>>> +	u32 dbclk_div_en_l;                     /* ADDRESS OFFSET: 0x0040 */
>>>> +	u32 dbclk_div_en_h;                     /* ADDRESS OFFSET: 0x0044 */
>>>> +	u32 dbclk_div_con;                      /* ADDRESS OFFSET: 0x0048 */
>>>> +	u32 reserved004c;                       /* ADDRESS OFFSET: 0x004c */
>>>> +	u32 int_status;                         /* ADDRESS OFFSET: 0x0050 */
>>>> +	u32 reserved0054;                       /* ADDRESS OFFSET: 0x0054 */
>>>> +	u32 int_rawstatus;                      /* ADDRESS OFFSET: 0x0058 */
>>>> +	u32 reserved005c;                       /* ADDRESS OFFSET: 0x005c */
>>>> +	u32 port_eoi_l;                         /* ADDRESS OFFSET: 0x0060 */
>>>> +	u32 port_eoi_h;                         /* ADDRESS OFFSET: 0x0064 */
>>>> +	u32 reserved0068[2];                    /* ADDRESS OFFSET: 0x0068 */
>>>> +	u32 ext_port;                           /* ADDRESS OFFSET: 0x0070 */
>>>> +	u32 reserved0074;                       /* ADDRESS OFFSET: 0x0074 */
>>>> +	u32 ver_id;                             /* ADDRESS OFFSET: 0x0078 */
>>>> +};
>>>> +
>>>> +check_member(rockchip_gpio_regs, ver_id, 0x0078);
>>>> +#endif
>>>>   enum gpio_pu_pd {
>>>>   	GPIO_PULL_NORMAL = 0,
>>>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>>>> index ff87fbfb39..bd7422a0b3 100644
>>>> --- a/drivers/gpio/Kconfig
>>>> +++ b/drivers/gpio/Kconfig
>>>> @@ -340,6 +340,19 @@ config ROCKCHIP_GPIO
>>>>   	  The GPIOs for a device are defined in the device tree with one node
>>>>   	  for each bank.
>>>> +config ROCKCHIP_GPIO_V2
>>>> +	bool "Rockchip GPIO driver version 2.0"
>>>> +	depends on ROCKCHIP_GPIO
>>>


>>> I would make ROCKCHIP_GPIO and ROCKCHIP_GPIO_V2 incompatible with each
>>> other, otherwise ROCKCHIP_GPIO represents both the GPIO controller and the
>>> v1, but not v1 if v2 is selected. That's a bit confusing to me.
>>>
>>> [...]


In Linux they think it is better to use one common fall back string .
compatible = "rockchip,rk3568-gpio-bank", "rockchip,gpio-bank";

>>>> @@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev)
>>>>   {
>>>>   	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
>>>>   	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
>>>> -	char *end;
>>>> -	int ret;
>>>> +	struct rockchip_pinctrl_priv *pctrl_priv;
>>>> +	struct rockchip_pin_bank *bank;
>>>> +	char *end = NULL;
>>>> +	static int gpio;
>>>> +	int id = -1, ret;
>>>>   	priv->regs = dev_read_addr_ptr(dev);
>>>>   	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
>>>> -	if (ret)
>>>> +	if (ret) {
>>>> +		dev_err(dev, "failed to get pinctrl device %d\n", ret);
>>>>   		return ret;
>>>> +	}
>>>> +
>>>> +	pctrl_priv = dev_get_priv(priv->pinctrl);
>>>> +	if (!pctrl_priv) {
>>>> +		dev_err(dev, "failed to get pinctrl priv\n");
>>>> +		return -EINVAL;
>>>> +	}

>>>> -	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
>>>>   	end = strrchr(dev->name, '@');

Question for the Rockchip U-boot maintainers:

Would you like to keep this method for backward compatibillity together with "gpio-ranges"?
All dtsi files must be changed first!

>>>> -	priv->bank = trailing_strtoln(dev->name, end);
>>>> -	priv->name[0] = 'A' + priv->bank;
>>>> -	uc_priv->bank_name = priv->name;
>>>> +	if (end)
>>>> +		id = trailing_strtoln(dev->name, end);
>>>> +	else
>>>> +		dev_read_alias_seq(dev, &id);
>>>> +
>>>> +	if (id < 0)
>>>> +		id = gpio++;
>>>> +
>>>
>>> NACK. This does not work.
>>>
>>> This means that the gpio bank detection depends on:
>>> 1) the index of the alias (no guarantee it's stable/not overwritten by a
>>> board dts),
>>> 2) if no support for aliases (e.g. in TPL/SPL) or the alias does not exist,
>>> the probe order of the GPIO controller device will define its bank. This is
>>> somewhat working in the Linux kernel by chance but does NOT work in U-Boot
>>> (devices are probed only when used, so you could very well have gpio4
>>> controller probed before gpio0 and then gpio4 would represent bank 0 and
>>> then gpio0 represent bank 1).
>>>
>>> Yes, the current code will not work for "newer" DTS and needs to be adapted
>>> (FWIW, it does not work on PX30 already because the node name is gpio@addr
>>> instead of gpioX@addr), but the Linux kernel implementation (the one used
>>> above) is not correct and should not be used.
>>>
>>> I've two suggestions:
>>> 1) a rockchip,gpio-controller-bank = <0>; property in the -u-boot.dtsi for
>>> each gpio-controller and then you get the index from there in the driver,
>>> 2) get the register address of the node of the device you're currently
>>> probing and maintain a mapping of which address maps to which bank,
>>>
>>> We could also start a discussion with upstream Linux to see what they would
>>> like to go for so we don't have two different implementations.
>>
>> I see RFC patches for Linux to use a property called "gpio-ranges".
>> I'll wait for that to gain traction as a solution before I resubmit
>> this so that Linux/U-Boot use roughly the same method (assuming
>> Johan doesn't beat me to the punch, since it's his Linux patches
>> I'm following).
>>
>> Thank you.
> 
> I see the mainline patches that Johan Jonker put together have been 
> acked. Johan, are you going to also include these in U-Boot or would
> you like for me to try my hand at it here as part of this series?

If you have the time...
As you are already touching gpio with a common fall back string then it's best you do that in separate patch series.
Mind it involves a lot of dtsi changes before this can be merged. 
Moving gpio nodes to root must also make it work both full U-boot and SPL reduced DT and with platdata if possible.


Johan


> 
> Thank you.
> 
>>
>>>
>>>> +	if (id >= pctrl_priv->ctrl->nr_banks) {
>>>> +		dev_err(dev, "bank id invalid\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	bank = &pctrl_priv->ctrl->pin_banks[id];
>>>> +	if (bank->bank_num != id) {
>>>> +		dev_err(dev, "bank id mismatch with pinctrl\n");
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	priv->bank = bank->bank_num;
>>>> +	uc_priv->gpio_count = bank->nr_pins;
>>>> +	uc_priv->gpio_base = bank->pin_base;
>>>> +	uc_priv->bank_name = bank->name;
>>>>   	return 0;
>>>>   }



>>>> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
>>>> index 7d03f8101d..c78fc2c331 100644
>>>> --- a/drivers/pinctrl/rockchip/Makefile
>>>> +++ b/drivers/pinctrl/rockchip/Makefile
>>>> @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o
>>>>   obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
>>>>   obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
>>>>   obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
>>>> +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
>>>>   obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
>>>> diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
>>>> new file mode 100644
>>>> index 0000000000..dce1c1e7ee
>>>> --- /dev/null
>>>> +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
>>>> @@ -0,0 +1,453 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +/*
>>>> + * (C) Copyright 2020 Rockchip Electronics Co., Ltd
>>>> + */
>>>> +
>>>> +#include <common.h>
>>>> +#include <dm.h>
>>>> +#include <dm/pinctrl.h>
>>>> +#include <regmap.h>
>>>> +#include <syscon.h>
>>>> +
>>>> +#include "pinctrl-rockchip.h"
>>>> +
>>>> +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
>>>> +	/* CAN0 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)),
>>>> +	/* CAN0 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)),
>>>> +	/* CAN1 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)),
>>>> +	/* CAN1 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)),
>>>> +	/* CAN2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)),
>>>> +	/* CAN2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)),
>>>> +	/* EDPDP_HPDIN IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)),
>>>> +	/* EDPDP_HPDIN IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)),
>>>> +	/* GMAC1 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)),
>>>> +	/* GMAC1 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)),
>>>> +	/* HDMITX IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)),
>>>> +	/* HDMITX IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)),
>>>> +	/* I2C2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)),
>>>> +	/* I2C2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)),
>>>> +	/* I2C3 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)),
>>>> +	/* I2C3 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)),
>>>> +	/* I2C4 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)),
>>>> +	/* I2C4 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)),
>>>> +	/* I2C5 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)),
>>>> +	/* I2C5 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)),
>>>> +	/* PWM4 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)),
>>>> +	/* PWM4 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)),
>>>> +	/* PWM5 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)),
>>>> +	/* PWM5 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)),
>>>> +	/* PWM6 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)),
>>>> +	/* PWM6 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)),
>>>> +	/* PWM7 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)),
>>>> +	/* PWM7 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)),
>>>> +	/* PWM8 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)),
>>>> +	/* PWM8 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)),
>>>> +	/* PWM9 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)),
>>>> +	/* PWM9 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)),
>>>> +	/* PWM10 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)),
>>>> +	/* PWM10 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)),
>>>> +	/* PWM11 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)),
>>>> +	/* PWM11 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)),
>>>> +	/* PWM12 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)),
>>>> +	/* PWM12 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)),
>>>> +	/* PWM13 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)),
>>>> +	/* PWM13 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)),
>>>> +	/* PWM14 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)),
>>>> +	/* PWM14 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)),
>>>> +	/* PWM15 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)),
>>>> +	/* PWM15 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)),
>>>> +	/* SDMMC2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)),
>>>> +	/* SDMMC2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)),
>>>> +	/* SPI0 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)),
>>>> +	/* SPI0 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)),
>>>> +	/* SPI1 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)),
>>>> +	/* SPI1 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)),
>>>> +	/* SPI2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)),
>>>> +	/* SPI2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)),
>>>> +	/* SPI3 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)),
>>>> +	/* SPI3 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)),
>>>> +	/* UART1 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)),
>>>> +	/* UART1 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)),
>>>> +	/* UART2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)),
>>>> +	/* UART2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)),
>>>> +	/* UART3 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)),
>>>> +	/* UART3 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)),
>>>> +	/* UART4 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)),
>>>> +	/* UART4 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)),
>>>> +	/* UART5 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)),
>>>> +	/* UART5 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)),
>>>> +	/* UART6 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)),
>>>> +	/* UART6 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)),
>>>> +	/* UART7 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)),
>>>> +	/* UART7 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)),
>>>> +	/* UART7 IO mux selection M2 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)),
>>>> +	/* UART8 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)),
>>>> +	/* UART8 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)),
>>>> +	/* UART9 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)),
>>>> +	/* UART9 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)),
>>>> +	/* UART9 IO mux selection M2 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)),
>>>> +	/* I2S1 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)),
>>>> +	/* I2S1 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)),
>>>> +	/* I2S1 IO mux selection M2 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)),
>>>> +	/* I2S2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)),
>>>> +	/* I2S2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)),
>>>> +	/* I2S3 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)),
>>>> +	/* I2S3 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)),
>>>> +	/* PDM IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)),
>>>> +	/* PDM IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)),
>>>> +	/* PCIE20 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)),
>>>> +	/* PCIE20 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)),
>>>> +	/* PCIE20 IO mux selection M2 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)),
>>>> +	/* PCIE30X1 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)),
>>>> +	/* PCIE30X1 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)),
>>>> +	/* PCIE30X1 IO mux selection M2 */
>>>> +	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)),
>>>> +	/* PCIE30X2 IO mux selection M0 */
>>>> +	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)),
>>>> +	/* PCIE30X2 IO mux selection M1 */
>>>> +	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)),
>>>> +	/* PCIE30X2 IO mux selection M2 */
>>>> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)),
>>>> +};
>>>> +
>>>> +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
>>>> +{
>>>> +	struct rockchip_pinctrl_priv *priv = bank->priv;
>>>> +	int iomux_num = (pin / 8);
>>>> +	struct regmap *regmap;
>>>> +	int reg, ret, mask;
>>>> +	u8 bit;
>>>> +	u32 data;
>>>> +
>>>> +	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
>>>> +
>>>> +	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
>>>> +		regmap = priv->regmap_pmu;
>>>> +	else
>>>> +		regmap = priv->regmap_base;
>>>> +
>>>> +	reg = bank->iomux[iomux_num].offset;
>>>> +	if ((pin % 8) >= 4)
>>>> +		reg += 0x4;
>>>> +	bit = (pin % 4) * 4;
>>>> +	mask = 0xf;
>>>> +
>>>> +	data = (mask << (bit + 16));
>>>> +	data |= (mux & mask) << bit;
>>>> +	ret = regmap_write(regmap, reg, data);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +#define RK3568_PULL_PMU_OFFSET		0x20
>>>> +#define RK3568_PULL_GRF_OFFSET		0x80
>>>> +#define RK3568_PULL_BITS_PER_PIN	2
>>>> +#define RK3568_PULL_PINS_PER_REG	8
>>>> +#define RK3568_PULL_BANK_STRIDE		0x10
>>>> +
>>>> +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
>>>> +					 int pin_num, struct regmap **regmap,
>>>> +					 int *reg, u8 *bit)
>>>> +{
>>>> +	struct rockchip_pinctrl_priv *info = bank->priv;
>>>> +
>>>> +	if (bank->bank_num == 0) {
>>>> +		*regmap = info->regmap_pmu;
>>>> +		*reg = RK3568_PULL_PMU_OFFSET;
>>>> +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
>>>> +	} else {
>>>> +		*regmap = info->regmap_base;
>>>> +		*reg = RK3568_PULL_GRF_OFFSET;
>>>> +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
>>>> +	}
>>>> +
>>>> +	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
>>>> +	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
>>>> +	*bit *= RK3568_PULL_BITS_PER_PIN;
>>>> +}
>>>> +
>>>> +#define RK3568_DRV_PMU_OFFSET		0x70
>>>> +#define RK3568_DRV_GRF_OFFSET		0x200
>>>> +#define RK3568_DRV_BITS_PER_PIN		8
>>>> +#define RK3568_DRV_PINS_PER_REG		2
>>>> +#define RK3568_DRV_BANK_STRIDE		0x40
>>>> +
>>>> +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
>>>> +					int pin_num, struct regmap **regmap,
>>>> +					int *reg, u8 *bit)
>>>> +{
>>>> +	struct rockchip_pinctrl_priv *info = bank->priv;
>>>> +
>>>> +	/* The first 32 pins of the first bank are located in PMU */
>>>> +	if (bank->bank_num == 0) {
>>>> +		*regmap = info->regmap_pmu;
>>>> +		*reg = RK3568_DRV_PMU_OFFSET;
>>>> +	} else {
>>>> +		*regmap = info->regmap_base;
>>>> +		*reg = RK3568_DRV_GRF_OFFSET;
>>>> +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
>>>> +	}
>>>> +
>>>> +	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
>>>> +	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
>>>> +	*bit *= RK3568_DRV_BITS_PER_PIN;
>>>> +}
>>>> +
>>>> +#define RK3568_SCHMITT_BITS_PER_PIN		2
>>>> +#define RK3568_SCHMITT_PINS_PER_REG		8
>>>> +#define RK3568_SCHMITT_BANK_STRIDE		0x10
>>>> +#define RK3568_SCHMITT_GRF_OFFSET		0xc0
>>>> +#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
>>>> +
>>>> +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
>>>> +					   int pin_num, struct regmap **regmap,
>>>> +					   int *reg, u8 *bit)
>>>> +{
>>>> +	struct rockchip_pinctrl_priv *info = bank->priv;
>>>> +
>>>> +	if (bank->bank_num == 0) {
>>>> +		*regmap = info->regmap_pmu;
>>>> +		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
>>>> +	} else {
>>>> +		*regmap = info->regmap_base;
>>>> +		*reg = RK3568_SCHMITT_GRF_OFFSET;
>>>> +		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
>>>> +	}
>>>> +
>>>> +	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
>>>> +	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
>>>> +	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
>>>> +
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static int rk3568_set_pull(struct rockchip_pin_bank *bank,
>>>> +			   int pin_num, int pull)
>>>> +{
>>>> +	struct regmap *regmap;
>>>> +	int reg, ret;
>>>> +	u8 bit, type;
>>>> +	u32 data;
>>>> +
>>>> +	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
>>>> +		return -EOPNOTSUPP;
>>>> +
>>>> +	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
>>>> +	type = bank->pull_type[pin_num / 8];
>>>> +	ret = rockchip_translate_pull_value(type, pull);
>>>> +	if (ret < 0) {
>>>> +		debug("unsupported pull setting %d\n", pull);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	/* enable the write to the equivalent lower bits */
>>>> +	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
>>>> +
>>>> +	data |= (ret << bit);
>>>> +	ret = regmap_write(regmap, reg, data);
>>>> +
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static int rk3568_set_drive(struct rockchip_pin_bank *bank,
>>>> +			    int pin_num, int strength)
>>>> +{
>>>> +	struct regmap *regmap;
>>>> +	int reg;
>>>> +	u32 data;
>>>> +	u8 bit;
>>>> +	int drv = (1 << (strength + 1)) - 1;
>>>> +	int ret = 0;
>>>> +
>>>> +	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
>>>> +
>>>> +	/* enable the write to the equivalent lower bits */
>>>> +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
>>>> +	data |= (drv << bit);
>>>> +
>>>> +	ret = regmap_write(regmap, reg, data);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	if (bank->bank_num == 1 && pin_num == 21)
>>>> +		reg = 0x0840;
>>>> +	else if (bank->bank_num == 2 && pin_num == 2)
>>>> +		reg = 0x0844;
>>>> +	else if (bank->bank_num == 2 && pin_num == 8)
>>>> +		reg = 0x0848;
>>>> +	else if (bank->bank_num == 3 && pin_num == 0)
>>>> +		reg = 0x084c;
>>>> +	else if (bank->bank_num == 3 && pin_num == 6)
>>>> +		reg = 0x0850;
>>>> +	else if (bank->bank_num == 4 && pin_num == 0)
>>>> +		reg = 0x0854;
>>>> +	else
>>>> +		return 0;
>>>> +
>>>> +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
>>>> +	data |= drv;
>>>> +
>>>> +	return regmap_write(regmap, reg, data);
>>>> +}
>>>> +
>>>> +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
>>>> +			      int pin_num, int enable)
>>>> +{
>>>> +	struct regmap *regmap;
>>>> +	int reg;
>>>> +	u32 data;
>>>> +	u8 bit;
>>>> +
>>>> +	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
>>>> +
>>>> +	/* enable the write to the equivalent lower bits */
>>>> +	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
>>>> +	data |= (enable << bit);
>>>> +
>>>> +	return regmap_write(regmap, reg, data);
>>>> +}
>>>> +
>>>> +static struct rockchip_pin_bank rk3568_pin_banks[] = {
>>>> +	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
>>>> +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT),
>>>> +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT),
>>>> +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT),
>>>> +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT,
>>>> +			     IOMUX_WIDTH_4BIT),
>>>> +};
>>>> +
>>>> +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
>>>> +	.pin_banks		= rk3568_pin_banks,
>>>> +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
>>>> +	.nr_pins		= 160,
>>>> +	.grf_mux_offset		= 0x0,
>>>> +	.pmu_mux_offset		= 0x0,
>>>> +	.iomux_routes		= rk3568_mux_route_data,
>>>> +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
>>>> +	.set_mux		= rk3568_set_mux,
>>>> +	.set_pull		= rk3568_set_pull,
>>>> +	.set_drive		= rk3568_set_drive,
>>>> +	.set_schmitt		= rk3568_set_schmitt,
>>>> +};
>>>> +
>>>> +static const struct udevice_id rk3568_pinctrl_ids[] = {
>>>> +	{
>>>> +		.compatible = "rockchip,rk3568-pinctrl",
>>>> +		.data = (ulong)&rk3568_pin_ctrl
>>>> +	},
>>>> +	{ }
>>>> +};
>>>> +
>>>> +U_BOOT_DRIVER(pinctrl_rk3568) = {
>>>> +	.name		= "rockchip_rk3568_pinctrl",
>>>> +	.id		= UCLASS_PINCTRL,
>>>> +	.of_match	= rk3568_pinctrl_ids,
>>>> +	.priv_auto = sizeof(struct rockchip_pinctrl_priv),
>>>> +	.ops		= &rockchip_pinctrl_ops,
>>>> +#if !IS_ENABLED(CONFIG_OF_PLATDATA)
>>>> +	.bind		= dm_scan_fdt_dev,
>>>> +#endif
>>>> +	.probe		= rockchip_pinctrl_probe,
>>>> +};
>>>> diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
>>>> index 630513ba3a..5f0016ff60 100644
>>>> --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
>>>> +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
>>>> @@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
>>>>   	int prop_len, param;
>>>>   	const u32 *data;
>>>>   	ofnode node;
>>>> -#ifdef CONFIG_OF_LIVE
>>>> +#if CONFIG_IS_ENABLED(OF_LIVE)
>>>
>>> Not sure this is really related or not, would be better in its own commit I
>>> believe.
>>>
>>>>   	const struct device_node *np;
>>>>   	struct property *pp;
>>>>   #else
>>>> @@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
>>>>   		node = ofnode_get_by_phandle(conf);
>>>>   		if (!ofnode_valid(node))
>>>>   			return -ENODEV;
>>>> -#ifdef CONFIG_OF_LIVE
>>>> +#if CONFIG_IS_ENABLED(OF_LIVE)
>>>>   		np = ofnode_to_np(node);
>>>>   		for (pp = np->properties; pp; pp = pp->next) {
>>>>   			prop_name = pp->name;
>>>> @@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
>>>>   			/* preset iomux offset value, set new start value */
>>>>   			if (iom->offset >= 0) {
>>>> -				if (iom->type & IOMUX_SOURCE_PMU)
>>>> +				if ((iom->type & IOMUX_SOURCE_PMU) || \
>>>> +				    (iom->type & IOMUX_L_SOURCE_PMU))
>>>
>>> nitpick: Could be if (iom->type & (IOMUX_SOURCE_PMU | IOMUX_L_SOURCE_PMU))
>>> instead.
>>>
>>>>   					pmu_offs = iom->offset;
>>>>   				else
>>>>   					grf_offs = iom->offset;
>>>>   			} else { /* set current iomux offset */
>>>> -				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
>>>> -							pmu_offs : grf_offs;
>>>> +				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
>>>> +						(iom->type & IOMUX_L_SOURCE_PMU)) ?
>>>
>>> Ditto.
>>>
>>> Cheers,
>>> Quentin

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller
  2023-01-26 18:11         ` Johan Jonker
@ 2023-01-27 16:50           ` Chris Morgan
  0 siblings, 0 replies; 14+ messages in thread
From: Chris Morgan @ 2023-01-27 16:50 UTC (permalink / raw)
  To: Johan Jonker
  Cc: Chris Morgan, Quentin Schulz, u-boot, sjg, philipp.tomsich,
	kever.yang, chenjh, pgwipeout, Heiko Stuebner

On Thu, Jan 26, 2023 at 07:11:15PM +0100, Johan Jonker wrote:
> 
> 
> On 1/26/23 17:11, Chris Morgan wrote:
> > On Thu, Jan 19, 2023 at 12:21:02PM -0600, Chris Morgan wrote:
> >> On Thu, Jan 05, 2023 at 07:01:40PM +0100, Quentin Schulz wrote:
> >>> Hi Chris,
> >>>
> >>> Cc'ing the new mail address of Heiko so he receives this mail :)
> >>>
> >>> On 1/5/23 16:34, Chris Morgan wrote:
> >>>> From: Chris Morgan <macromorgan@hotmail.com>
> >>>>
> >>>> Add support for the newer GPIO controller used by the rk356x series,
> >>>> as well as the pinctrl device for the rk356x series. The GPIOv2
> >>>> controller has a write enable bit for some registers which differs
> >>>> from the older versions of the GPIO controller.
> >>>>
> >>>> Adapted from Peter Geis's gitlab located here:
> >>>> https://urldefense.com/v3/__https://gitlab.com/pgwipeout/u-boot-quartz64/-/commit/1a84cc483d0979fa00c6f7d6c76d870c25ab3cbd__;!!OOPJP91ZZw!i7xaxb0VOR6CU_lauUnYs4-WlEgdGZCaETaNwp--V4jwJoQguyPr07GTOXDhDNNYL4vYLzae_eObZKZUYUAm4pVFA6vGK-JnXjIz$
> >>>>
> >>>> Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
> >>>> ---
> >>>>   arch/arm/include/asm/arch-rockchip/gpio.h     |  38 ++
> >>>>   drivers/gpio/Kconfig                          |  13 +
> >>>>   drivers/gpio/rk_gpio.c                        | 103 +++-
> >>>>   drivers/pinctrl/rockchip/Makefile             |   1 +
> >>>>   drivers/pinctrl/rockchip/pinctrl-rk3568.c     | 453 ++++++++++++++++++
> >>>>   .../pinctrl/rockchip/pinctrl-rockchip-core.c  |  12 +-
> >>>>   drivers/pinctrl/rockchip/pinctrl-rockchip.h   |  42 ++
> >>>>   7 files changed, 635 insertions(+), 27 deletions(-)
> >>>>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3568.c
> >>>>
> >>>> diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h
> >>>> index 1aaec5faec..29120ceaf3 100644
> >>>> --- a/arch/arm/include/asm/arch-rockchip/gpio.h
> >>>> +++ b/arch/arm/include/asm/arch-rockchip/gpio.h
> >>>> @@ -6,6 +6,7 @@
> >>>>   #ifndef _ASM_ARCH_GPIO_H
> >>>>   #define _ASM_ARCH_GPIO_H
> >>>> +#ifndef CONFIG_ROCKCHIP_GPIO_V2
> >>>>   struct rockchip_gpio_regs {
> >>>>   	u32 swport_dr;
> >>>>   	u32 swport_ddr;
> >>>> @@ -22,7 +23,44 @@ struct rockchip_gpio_regs {
> >>>>   	u32 reserved1[(0x60 - 0x54) / 4];
> >>>>   	u32 ls_sync;
> >>>>   };
> >>>> +
> >>>>   check_member(rockchip_gpio_regs, ls_sync, 0x60);
> >>>> +#else
> >>>> +struct rockchip_gpio_regs {
> >>>> +	u32 swport_dr_l;                        /* ADDRESS OFFSET: 0x0000 */
> >>>> +	u32 swport_dr_h;                        /* ADDRESS OFFSET: 0x0004 */
> >>>> +	u32 swport_ddr_l;                       /* ADDRESS OFFSET: 0x0008 */
> >>>> +	u32 swport_ddr_h;                       /* ADDRESS OFFSET: 0x000c */
> >>>> +	u32 int_en_l;                           /* ADDRESS OFFSET: 0x0010 */
> >>>> +	u32 int_en_h;                           /* ADDRESS OFFSET: 0x0014 */
> >>>> +	u32 int_mask_l;                         /* ADDRESS OFFSET: 0x0018 */
> >>>> +	u32 int_mask_h;                         /* ADDRESS OFFSET: 0x001c */
> >>>> +	u32 int_type_l;                         /* ADDRESS OFFSET: 0x0020 */
> >>>> +	u32 int_type_h;                         /* ADDRESS OFFSET: 0x0024 */
> >>>> +	u32 int_polarity_l;                     /* ADDRESS OFFSET: 0x0028 */
> >>>> +	u32 int_polarity_h;                     /* ADDRESS OFFSET: 0x002c */
> >>>> +	u32 int_bothedge_l;                     /* ADDRESS OFFSET: 0x0030 */
> >>>> +	u32 int_bothedge_h;                     /* ADDRESS OFFSET: 0x0034 */
> >>>> +	u32 debounce_l;                         /* ADDRESS OFFSET: 0x0038 */
> >>>> +	u32 debounce_h;                         /* ADDRESS OFFSET: 0x003c */
> >>>> +	u32 dbclk_div_en_l;                     /* ADDRESS OFFSET: 0x0040 */
> >>>> +	u32 dbclk_div_en_h;                     /* ADDRESS OFFSET: 0x0044 */
> >>>> +	u32 dbclk_div_con;                      /* ADDRESS OFFSET: 0x0048 */
> >>>> +	u32 reserved004c;                       /* ADDRESS OFFSET: 0x004c */
> >>>> +	u32 int_status;                         /* ADDRESS OFFSET: 0x0050 */
> >>>> +	u32 reserved0054;                       /* ADDRESS OFFSET: 0x0054 */
> >>>> +	u32 int_rawstatus;                      /* ADDRESS OFFSET: 0x0058 */
> >>>> +	u32 reserved005c;                       /* ADDRESS OFFSET: 0x005c */
> >>>> +	u32 port_eoi_l;                         /* ADDRESS OFFSET: 0x0060 */
> >>>> +	u32 port_eoi_h;                         /* ADDRESS OFFSET: 0x0064 */
> >>>> +	u32 reserved0068[2];                    /* ADDRESS OFFSET: 0x0068 */
> >>>> +	u32 ext_port;                           /* ADDRESS OFFSET: 0x0070 */
> >>>> +	u32 reserved0074;                       /* ADDRESS OFFSET: 0x0074 */
> >>>> +	u32 ver_id;                             /* ADDRESS OFFSET: 0x0078 */
> >>>> +};
> >>>> +
> >>>> +check_member(rockchip_gpio_regs, ver_id, 0x0078);
> >>>> +#endif
> >>>>   enum gpio_pu_pd {
> >>>>   	GPIO_PULL_NORMAL = 0,
> >>>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> >>>> index ff87fbfb39..bd7422a0b3 100644
> >>>> --- a/drivers/gpio/Kconfig
> >>>> +++ b/drivers/gpio/Kconfig
> >>>> @@ -340,6 +340,19 @@ config ROCKCHIP_GPIO
> >>>>   	  The GPIOs for a device are defined in the device tree with one node
> >>>>   	  for each bank.
> >>>> +config ROCKCHIP_GPIO_V2
> >>>> +	bool "Rockchip GPIO driver version 2.0"
> >>>> +	depends on ROCKCHIP_GPIO
> >>>
> 
> 
> >>> I would make ROCKCHIP_GPIO and ROCKCHIP_GPIO_V2 incompatible with each
> >>> other, otherwise ROCKCHIP_GPIO represents both the GPIO controller and the
> >>> v1, but not v1 if v2 is selected. That's a bit confusing to me.
> >>>
> >>> [...]
> 
> 
> In Linux they think it is better to use one common fall back string .
> compatible = "rockchip,rk3568-gpio-bank", "rockchip,gpio-bank";
> 
> >>>> @@ -142,19 +171,49 @@ static int rockchip_gpio_probe(struct udevice *dev)
> >>>>   {
> >>>>   	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
> >>>>   	struct rockchip_gpio_priv *priv = dev_get_priv(dev);
> >>>> -	char *end;
> >>>> -	int ret;
> >>>> +	struct rockchip_pinctrl_priv *pctrl_priv;
> >>>> +	struct rockchip_pin_bank *bank;
> >>>> +	char *end = NULL;
> >>>> +	static int gpio;
> >>>> +	int id = -1, ret;
> >>>>   	priv->regs = dev_read_addr_ptr(dev);
> >>>>   	ret = uclass_first_device_err(UCLASS_PINCTRL, &priv->pinctrl);
> >>>> -	if (ret)
> >>>> +	if (ret) {
> >>>> +		dev_err(dev, "failed to get pinctrl device %d\n", ret);
> >>>>   		return ret;
> >>>> +	}
> >>>> +
> >>>> +	pctrl_priv = dev_get_priv(priv->pinctrl);
> >>>> +	if (!pctrl_priv) {
> >>>> +		dev_err(dev, "failed to get pinctrl priv\n");
> >>>> +		return -EINVAL;
> >>>> +	}
> 
> >>>> -	uc_priv->gpio_count = ROCKCHIP_GPIOS_PER_BANK;
> >>>>   	end = strrchr(dev->name, '@');
> 
> Question for the Rockchip U-boot maintainers:
> 
> Would you like to keep this method for backward compatibillity together with "gpio-ranges"?
> All dtsi files must be changed first!
> 
> >>>> -	priv->bank = trailing_strtoln(dev->name, end);
> >>>> -	priv->name[0] = 'A' + priv->bank;
> >>>> -	uc_priv->bank_name = priv->name;
> >>>> +	if (end)
> >>>> +		id = trailing_strtoln(dev->name, end);
> >>>> +	else
> >>>> +		dev_read_alias_seq(dev, &id);
> >>>> +
> >>>> +	if (id < 0)
> >>>> +		id = gpio++;
> >>>> +
> >>>
> >>> NACK. This does not work.
> >>>
> >>> This means that the gpio bank detection depends on:
> >>> 1) the index of the alias (no guarantee it's stable/not overwritten by a
> >>> board dts),
> >>> 2) if no support for aliases (e.g. in TPL/SPL) or the alias does not exist,
> >>> the probe order of the GPIO controller device will define its bank. This is
> >>> somewhat working in the Linux kernel by chance but does NOT work in U-Boot
> >>> (devices are probed only when used, so you could very well have gpio4
> >>> controller probed before gpio0 and then gpio4 would represent bank 0 and
> >>> then gpio0 represent bank 1).
> >>>
> >>> Yes, the current code will not work for "newer" DTS and needs to be adapted
> >>> (FWIW, it does not work on PX30 already because the node name is gpio@addr
> >>> instead of gpioX@addr), but the Linux kernel implementation (the one used
> >>> above) is not correct and should not be used.
> >>>
> >>> I've two suggestions:
> >>> 1) a rockchip,gpio-controller-bank = <0>; property in the -u-boot.dtsi for
> >>> each gpio-controller and then you get the index from there in the driver,
> >>> 2) get the register address of the node of the device you're currently
> >>> probing and maintain a mapping of which address maps to which bank,
> >>>
> >>> We could also start a discussion with upstream Linux to see what they would
> >>> like to go for so we don't have two different implementations.
> >>
> >> I see RFC patches for Linux to use a property called "gpio-ranges".
> >> I'll wait for that to gain traction as a solution before I resubmit
> >> this so that Linux/U-Boot use roughly the same method (assuming
> >> Johan doesn't beat me to the punch, since it's his Linux patches
> >> I'm following).
> >>
> >> Thank you.
> > 
> > I see the mainline patches that Johan Jonker put together have been 
> > acked. Johan, are you going to also include these in U-Boot or would
> > you like for me to try my hand at it here as part of this series?
> 
> If you have the time...
> As you are already touching gpio with a common fall back string then it's best you do that in separate patch series.
> Mind it involves a lot of dtsi changes before this can be merged. 
> Moving gpio nodes to root must also make it work both full U-boot and SPL reduced DT and with platdata if possible.

I'm wondering if I can be allowed to do it for now just for the rk3566
and rk3588 (and the PX30)? I don't have the devices to regression test
all of them, just an rk3326 along with a series of rk3566 and rk3588
devices I want to support. It'll have to be done eventually if we want
to keep the trees in sync with Linux though, I guess.

Thank you.

> 
> 
> Johan
> 
> 
> > 
> > Thank you.
> > 
> >>
> >>>
> >>>> +	if (id >= pctrl_priv->ctrl->nr_banks) {
> >>>> +		dev_err(dev, "bank id invalid\n");
> >>>> +		return -EINVAL;
> >>>> +	}
> >>>> +
> >>>> +	bank = &pctrl_priv->ctrl->pin_banks[id];
> >>>> +	if (bank->bank_num != id) {
> >>>> +		dev_err(dev, "bank id mismatch with pinctrl\n");
> >>>> +		return -EINVAL;
> >>>> +	}
> >>>> +
> >>>> +	priv->bank = bank->bank_num;
> >>>> +	uc_priv->gpio_count = bank->nr_pins;
> >>>> +	uc_priv->gpio_base = bank->pin_base;
> >>>> +	uc_priv->bank_name = bank->name;
> >>>>   	return 0;
> >>>>   }
> 
> 
> 
> >>>> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> >>>> index 7d03f8101d..c78fc2c331 100644
> >>>> --- a/drivers/pinctrl/rockchip/Makefile
> >>>> +++ b/drivers/pinctrl/rockchip/Makefile
> >>>> @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o
> >>>>   obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
> >>>>   obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
> >>>>   obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
> >>>> +obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o
> >>>>   obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
> >>>> diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3568.c b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> >>>> new file mode 100644
> >>>> index 0000000000..dce1c1e7ee
> >>>> --- /dev/null
> >>>> +++ b/drivers/pinctrl/rockchip/pinctrl-rk3568.c
> >>>> @@ -0,0 +1,453 @@
> >>>> +// SPDX-License-Identifier: GPL-2.0+
> >>>> +/*
> >>>> + * (C) Copyright 2020 Rockchip Electronics Co., Ltd
> >>>> + */
> >>>> +
> >>>> +#include <common.h>
> >>>> +#include <dm.h>
> >>>> +#include <dm/pinctrl.h>
> >>>> +#include <regmap.h>
> >>>> +#include <syscon.h>
> >>>> +
> >>>> +#include "pinctrl-rockchip.h"
> >>>> +
> >>>> +static struct rockchip_mux_route_data rk3568_mux_route_data[] = {
> >>>> +	/* CAN0 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PB3, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(0, 0, 0)),
> >>>> +	/* CAN0 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PA1, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(0, 0, 1)),
> >>>> +	/* CAN1 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 0)),
> >>>> +	/* CAN1 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PC3, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(2, 2, 1)),
> >>>> +	/* CAN2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PB5, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(4, 4, 0)),
> >>>> +	/* CAN2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PB2, RK_FUNC_4, 0x0300, RK_GENMASK_VAL(4, 4, 1)),
> >>>> +	/* EDPDP_HPDIN IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PC4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(6, 6, 0)),
> >>>> +	/* EDPDP_HPDIN IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PC2, RK_FUNC_2, 0x0300, RK_GENMASK_VAL(6, 6, 1)),
> >>>> +	/* GMAC1 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PB1, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 0)),
> >>>> +	/* GMAC1 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PA7, RK_FUNC_3, 0x0300, RK_GENMASK_VAL(8, 8, 1)),
> >>>> +	/* HDMITX IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PD1, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 0)),
> >>>> +	/* HDMITX IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PC7, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(10, 10, 1)),
> >>>> +	/* I2C2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PB6, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 0)),
> >>>> +	/* I2C2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PB4, RK_FUNC_1, 0x0300, RK_GENMASK_VAL(14, 14, 1)),
> >>>> +	/* I2C3 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA0, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(0, 0, 0)),
> >>>> +	/* I2C3 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PB6, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(0, 0, 1)),
> >>>> +	/* I2C4 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PB2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(2, 2, 0)),
> >>>> +	/* I2C4 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PB1, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(2, 2, 1)),
> >>>> +	/* I2C5 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PB4, RK_FUNC_4, 0x0304, RK_GENMASK_VAL(4, 4, 0)),
> >>>> +	/* I2C5 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PD0, RK_FUNC_2, 0x0304, RK_GENMASK_VAL(4, 4, 1)),
> >>>> +	/* PWM4 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 0)),
> >>>> +	/* PWM4 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(6, 6, 1)),
> >>>> +	/* PWM5 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 0)),
> >>>> +	/* PWM5 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(8, 8, 1)),
> >>>> +	/* PWM6 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 0)),
> >>>> +	/* PWM6 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(10, 10, 1)),
> >>>> +	/* PWM7 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 0)),
> >>>> +	/* PWM7 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(12, 12, 1)),
> >>>> +	/* PWM8 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 0)),
> >>>> +	/* PWM8 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0304, RK_GENMASK_VAL(14, 14, 1)),
> >>>> +	/* PWM9 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 0)),
> >>>> +	/* PWM9 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(0, 0, 1)),
> >>>> +	/* PWM10 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 0)),
> >>>> +	/* PWM10 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(2, 2, 1)),
> >>>> +	/* PWM11 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 0)),
> >>>> +	/* PWM11 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(4, 4, 1)),
> >>>> +	/* PWM12 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 0)),
> >>>> +	/* PWM12 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(6, 6, 1)),
> >>>> +	/* PWM13 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 0)),
> >>>> +	/* PWM13 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(8, 8, 1)),
> >>>> +	/* PWM14 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 0)),
> >>>> +	/* PWM14 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(10, 10, 1)),
> >>>> +	/* PWM15 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 0)),
> >>>> +	/* PWM15 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0308, RK_GENMASK_VAL(12, 12, 1)),
> >>>> +	/* SDMMC2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_3, 0x0308, RK_GENMASK_VAL(14, 14, 0)),
> >>>> +	/* SDMMC2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PA5, RK_FUNC_5, 0x0308, RK_GENMASK_VAL(14, 14, 1)),
> >>>> +	/* SPI0 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PB5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(0, 0, 0)),
> >>>> +	/* SPI0 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PD3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(0, 0, 1)),
> >>>> +	/* SPI1 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PB5, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 0)),
> >>>> +	/* SPI1 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PC3, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(2, 2, 1)),
> >>>> +	/* SPI2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(4, 4, 0)),
> >>>> +	/* SPI2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PA0, RK_FUNC_3, 0x030c, RK_GENMASK_VAL(4, 4, 1)),
> >>>> +	/* SPI3 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PB3, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(6, 6, 0)),
> >>>> +	/* SPI3 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(6, 6, 1)),
> >>>> +	/* UART1 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PB4, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(8, 8, 0)),
> >>>> +	/* UART1 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(8, 8, 1)),
> >>>> +	/* UART2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PD1, RK_FUNC_1, 0x030c, RK_GENMASK_VAL(10, 10, 0)),
> >>>> +	/* UART2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(10, 10, 1)),
> >>>> +	/* UART3 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA1, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(12, 12, 0)),
> >>>> +	/* UART3 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PB7, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(12, 12, 1)),
> >>>> +	/* UART4 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_2, 0x030c, RK_GENMASK_VAL(14, 14, 0)),
> >>>> +	/* UART4 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PB2, RK_FUNC_4, 0x030c, RK_GENMASK_VAL(14, 14, 1)),
> >>>> +	/* UART5 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PA2, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(0, 0, 0)),
> >>>> +	/* UART5 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PC2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(0, 0, 1)),
> >>>> +	/* UART6 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PA4, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 0)),
> >>>> +	/* UART6 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PD5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(2, 2, 1)),
> >>>> +	/* UART7 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PA6, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(5, 4, 0)),
> >>>> +	/* UART7 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PC4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(5, 4, 1)),
> >>>> +	/* UART7 IO mux selection M2 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(5, 4, 2)),
> >>>> +	/* UART8 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PC5, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(6, 6, 0)),
> >>>> +	/* UART8 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PD7, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(6, 6, 1)),
> >>>> +	/* UART9 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PB0, RK_FUNC_3, 0x0310, RK_GENMASK_VAL(9, 8, 0)),
> >>>> +	/* UART9 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PC5, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 1)),
> >>>> +	/* UART9 IO mux selection M2 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PA4, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(9, 8, 2)),
> >>>> +	/* I2S1 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA2, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(11, 10, 0)),
> >>>> +	/* I2S1 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PC6, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(11, 10, 1)),
> >>>> +	/* I2S1 IO mux selection M2 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(11, 10, 2)),
> >>>> +	/* I2S2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PC1, RK_FUNC_1, 0x0310, RK_GENMASK_VAL(12, 12, 0)),
> >>>> +	/* I2S2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PB6, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(12, 12, 1)),
> >>>> +	/* I2S3 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PA2, RK_FUNC_4, 0x0310, RK_GENMASK_VAL(14, 14, 0)),
> >>>> +	/* I2S3 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_5, 0x0310, RK_GENMASK_VAL(14, 14, 1)),
> >>>> +	/* PDM IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA6, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(0, 0, 0)),
> >>>> +	/* PDM IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO3, RK_PD6, RK_FUNC_5, 0x0314, RK_GENMASK_VAL(0, 0, 1)),
> >>>> +	/* PCIE20 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PA5, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(3, 2, 0)),
> >>>> +	/* PCIE20 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PD0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 1)),
> >>>> +	/* PCIE20 IO mux selection M2 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PB0, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(3, 2, 2)),
> >>>> +	/* PCIE30X1 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PA4, RK_FUNC_3, 0x0314, RK_GENMASK_VAL(5, 4, 0)),
> >>>> +	/* PCIE30X1 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PD2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 1)),
> >>>> +	/* PCIE30X1 IO mux selection M2 */
> >>>> +	MR_TOPGRF(RK_GPIO1, RK_PA5, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(5, 4, 2)),
> >>>> +	/* PCIE30X2 IO mux selection M0 */
> >>>> +	MR_TOPGRF(RK_GPIO0, RK_PA6, RK_FUNC_2, 0x0314, RK_GENMASK_VAL(7, 6, 0)),
> >>>> +	/* PCIE30X2 IO mux selection M1 */
> >>>> +	MR_TOPGRF(RK_GPIO2, RK_PD4, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 1)),
> >>>> +	/* PCIE30X2 IO mux selection M2 */
> >>>> +	MR_TOPGRF(RK_GPIO4, RK_PC2, RK_FUNC_4, 0x0314, RK_GENMASK_VAL(7, 6, 2)),
> >>>> +};
> >>>> +
> >>>> +static int rk3568_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
> >>>> +{
> >>>> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> >>>> +	int iomux_num = (pin / 8);
> >>>> +	struct regmap *regmap;
> >>>> +	int reg, ret, mask;
> >>>> +	u8 bit;
> >>>> +	u32 data;
> >>>> +
> >>>> +	debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
> >>>> +
> >>>> +	if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
> >>>> +		regmap = priv->regmap_pmu;
> >>>> +	else
> >>>> +		regmap = priv->regmap_base;
> >>>> +
> >>>> +	reg = bank->iomux[iomux_num].offset;
> >>>> +	if ((pin % 8) >= 4)
> >>>> +		reg += 0x4;
> >>>> +	bit = (pin % 4) * 4;
> >>>> +	mask = 0xf;
> >>>> +
> >>>> +	data = (mask << (bit + 16));
> >>>> +	data |= (mux & mask) << bit;
> >>>> +	ret = regmap_write(regmap, reg, data);
> >>>> +
> >>>> +	return ret;
> >>>> +}
> >>>> +
> >>>> +#define RK3568_PULL_PMU_OFFSET		0x20
> >>>> +#define RK3568_PULL_GRF_OFFSET		0x80
> >>>> +#define RK3568_PULL_BITS_PER_PIN	2
> >>>> +#define RK3568_PULL_PINS_PER_REG	8
> >>>> +#define RK3568_PULL_BANK_STRIDE		0x10
> >>>> +
> >>>> +static void rk3568_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> >>>> +					 int pin_num, struct regmap **regmap,
> >>>> +					 int *reg, u8 *bit)
> >>>> +{
> >>>> +	struct rockchip_pinctrl_priv *info = bank->priv;
> >>>> +
> >>>> +	if (bank->bank_num == 0) {
> >>>> +		*regmap = info->regmap_pmu;
> >>>> +		*reg = RK3568_PULL_PMU_OFFSET;
> >>>> +		*reg += bank->bank_num * RK3568_PULL_BANK_STRIDE;
> >>>> +	} else {
> >>>> +		*regmap = info->regmap_base;
> >>>> +		*reg = RK3568_PULL_GRF_OFFSET;
> >>>> +		*reg += (bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE;
> >>>> +	}
> >>>> +
> >>>> +	*reg += ((pin_num / RK3568_PULL_PINS_PER_REG) * 4);
> >>>> +	*bit = (pin_num % RK3568_PULL_PINS_PER_REG);
> >>>> +	*bit *= RK3568_PULL_BITS_PER_PIN;
> >>>> +}
> >>>> +
> >>>> +#define RK3568_DRV_PMU_OFFSET		0x70
> >>>> +#define RK3568_DRV_GRF_OFFSET		0x200
> >>>> +#define RK3568_DRV_BITS_PER_PIN		8
> >>>> +#define RK3568_DRV_PINS_PER_REG		2
> >>>> +#define RK3568_DRV_BANK_STRIDE		0x40
> >>>> +
> >>>> +static void rk3568_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> >>>> +					int pin_num, struct regmap **regmap,
> >>>> +					int *reg, u8 *bit)
> >>>> +{
> >>>> +	struct rockchip_pinctrl_priv *info = bank->priv;
> >>>> +
> >>>> +	/* The first 32 pins of the first bank are located in PMU */
> >>>> +	if (bank->bank_num == 0) {
> >>>> +		*regmap = info->regmap_pmu;
> >>>> +		*reg = RK3568_DRV_PMU_OFFSET;
> >>>> +	} else {
> >>>> +		*regmap = info->regmap_base;
> >>>> +		*reg = RK3568_DRV_GRF_OFFSET;
> >>>> +		*reg += (bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE;
> >>>> +	}
> >>>> +
> >>>> +	*reg += ((pin_num / RK3568_DRV_PINS_PER_REG) * 4);
> >>>> +	*bit = (pin_num % RK3568_DRV_PINS_PER_REG);
> >>>> +	*bit *= RK3568_DRV_BITS_PER_PIN;
> >>>> +}
> >>>> +
> >>>> +#define RK3568_SCHMITT_BITS_PER_PIN		2
> >>>> +#define RK3568_SCHMITT_PINS_PER_REG		8
> >>>> +#define RK3568_SCHMITT_BANK_STRIDE		0x10
> >>>> +#define RK3568_SCHMITT_GRF_OFFSET		0xc0
> >>>> +#define RK3568_SCHMITT_PMUGRF_OFFSET		0x30
> >>>> +
> >>>> +static int rk3568_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
> >>>> +					   int pin_num, struct regmap **regmap,
> >>>> +					   int *reg, u8 *bit)
> >>>> +{
> >>>> +	struct rockchip_pinctrl_priv *info = bank->priv;
> >>>> +
> >>>> +	if (bank->bank_num == 0) {
> >>>> +		*regmap = info->regmap_pmu;
> >>>> +		*reg = RK3568_SCHMITT_PMUGRF_OFFSET;
> >>>> +	} else {
> >>>> +		*regmap = info->regmap_base;
> >>>> +		*reg = RK3568_SCHMITT_GRF_OFFSET;
> >>>> +		*reg += (bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE;
> >>>> +	}
> >>>> +
> >>>> +	*reg += ((pin_num / RK3568_SCHMITT_PINS_PER_REG) * 4);
> >>>> +	*bit = pin_num % RK3568_SCHMITT_PINS_PER_REG;
> >>>> +	*bit *= RK3568_SCHMITT_BITS_PER_PIN;
> >>>> +
> >>>> +	return 0;
> >>>> +}
> >>>> +
> >>>> +static int rk3568_set_pull(struct rockchip_pin_bank *bank,
> >>>> +			   int pin_num, int pull)
> >>>> +{
> >>>> +	struct regmap *regmap;
> >>>> +	int reg, ret;
> >>>> +	u8 bit, type;
> >>>> +	u32 data;
> >>>> +
> >>>> +	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
> >>>> +		return -EOPNOTSUPP;
> >>>> +
> >>>> +	rk3568_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> >>>> +	type = bank->pull_type[pin_num / 8];
> >>>> +	ret = rockchip_translate_pull_value(type, pull);
> >>>> +	if (ret < 0) {
> >>>> +		debug("unsupported pull setting %d\n", pull);
> >>>> +		return ret;
> >>>> +	}
> >>>> +
> >>>> +	/* enable the write to the equivalent lower bits */
> >>>> +	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
> >>>> +
> >>>> +	data |= (ret << bit);
> >>>> +	ret = regmap_write(regmap, reg, data);
> >>>> +
> >>>> +	return ret;
> >>>> +}
> >>>> +
> >>>> +static int rk3568_set_drive(struct rockchip_pin_bank *bank,
> >>>> +			    int pin_num, int strength)
> >>>> +{
> >>>> +	struct regmap *regmap;
> >>>> +	int reg;
> >>>> +	u32 data;
> >>>> +	u8 bit;
> >>>> +	int drv = (1 << (strength + 1)) - 1;
> >>>> +	int ret = 0;
> >>>> +
> >>>> +	rk3568_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> >>>> +
> >>>> +	/* enable the write to the equivalent lower bits */
> >>>> +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16);
> >>>> +	data |= (drv << bit);
> >>>> +
> >>>> +	ret = regmap_write(regmap, reg, data);
> >>>> +	if (ret)
> >>>> +		return ret;
> >>>> +
> >>>> +	if (bank->bank_num == 1 && pin_num == 21)
> >>>> +		reg = 0x0840;
> >>>> +	else if (bank->bank_num == 2 && pin_num == 2)
> >>>> +		reg = 0x0844;
> >>>> +	else if (bank->bank_num == 2 && pin_num == 8)
> >>>> +		reg = 0x0848;
> >>>> +	else if (bank->bank_num == 3 && pin_num == 0)
> >>>> +		reg = 0x084c;
> >>>> +	else if (bank->bank_num == 3 && pin_num == 6)
> >>>> +		reg = 0x0850;
> >>>> +	else if (bank->bank_num == 4 && pin_num == 0)
> >>>> +		reg = 0x0854;
> >>>> +	else
> >>>> +		return 0;
> >>>> +
> >>>> +	data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16;
> >>>> +	data |= drv;
> >>>> +
> >>>> +	return regmap_write(regmap, reg, data);
> >>>> +}
> >>>> +
> >>>> +static int rk3568_set_schmitt(struct rockchip_pin_bank *bank,
> >>>> +			      int pin_num, int enable)
> >>>> +{
> >>>> +	struct regmap *regmap;
> >>>> +	int reg;
> >>>> +	u32 data;
> >>>> +	u8 bit;
> >>>> +
> >>>> +	rk3568_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> >>>> +
> >>>> +	/* enable the write to the equivalent lower bits */
> >>>> +	data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16);
> >>>> +	data |= (enable << bit);
> >>>> +
> >>>> +	return regmap_write(regmap, reg, data);
> >>>> +}
> >>>> +
> >>>> +static struct rockchip_pin_bank rk3568_pin_banks[] = {
> >>>> +	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT),
> >>>> +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT),
> >>>> +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT),
> >>>> +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT),
> >>>> +	PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT,
> >>>> +			     IOMUX_WIDTH_4BIT),
> >>>> +};
> >>>> +
> >>>> +static const struct rockchip_pin_ctrl rk3568_pin_ctrl = {
> >>>> +	.pin_banks		= rk3568_pin_banks,
> >>>> +	.nr_banks		= ARRAY_SIZE(rk3568_pin_banks),
> >>>> +	.nr_pins		= 160,
> >>>> +	.grf_mux_offset		= 0x0,
> >>>> +	.pmu_mux_offset		= 0x0,
> >>>> +	.iomux_routes		= rk3568_mux_route_data,
> >>>> +	.niomux_routes		= ARRAY_SIZE(rk3568_mux_route_data),
> >>>> +	.set_mux		= rk3568_set_mux,
> >>>> +	.set_pull		= rk3568_set_pull,
> >>>> +	.set_drive		= rk3568_set_drive,
> >>>> +	.set_schmitt		= rk3568_set_schmitt,
> >>>> +};
> >>>> +
> >>>> +static const struct udevice_id rk3568_pinctrl_ids[] = {
> >>>> +	{
> >>>> +		.compatible = "rockchip,rk3568-pinctrl",
> >>>> +		.data = (ulong)&rk3568_pin_ctrl
> >>>> +	},
> >>>> +	{ }
> >>>> +};
> >>>> +
> >>>> +U_BOOT_DRIVER(pinctrl_rk3568) = {
> >>>> +	.name		= "rockchip_rk3568_pinctrl",
> >>>> +	.id		= UCLASS_PINCTRL,
> >>>> +	.of_match	= rk3568_pinctrl_ids,
> >>>> +	.priv_auto = sizeof(struct rockchip_pinctrl_priv),
> >>>> +	.ops		= &rockchip_pinctrl_ops,
> >>>> +#if !IS_ENABLED(CONFIG_OF_PLATDATA)
> >>>> +	.bind		= dm_scan_fdt_dev,
> >>>> +#endif
> >>>> +	.probe		= rockchip_pinctrl_probe,
> >>>> +};
> >>>> diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> >>>> index 630513ba3a..5f0016ff60 100644
> >>>> --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> >>>> +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> >>>> @@ -400,7 +400,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
> >>>>   	int prop_len, param;
> >>>>   	const u32 *data;
> >>>>   	ofnode node;
> >>>> -#ifdef CONFIG_OF_LIVE
> >>>> +#if CONFIG_IS_ENABLED(OF_LIVE)
> >>>
> >>> Not sure this is really related or not, would be better in its own commit I
> >>> believe.
> >>>
> >>>>   	const struct device_node *np;
> >>>>   	struct property *pp;
> >>>>   #else
> >>>> @@ -440,7 +440,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
> >>>>   		node = ofnode_get_by_phandle(conf);
> >>>>   		if (!ofnode_valid(node))
> >>>>   			return -ENODEV;
> >>>> -#ifdef CONFIG_OF_LIVE
> >>>> +#if CONFIG_IS_ENABLED(OF_LIVE)
> >>>>   		np = ofnode_to_np(node);
> >>>>   		for (pp = np->properties; pp; pp = pp->next) {
> >>>>   			prop_name = pp->name;
> >>>> @@ -515,13 +515,15 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
> >>>>   			/* preset iomux offset value, set new start value */
> >>>>   			if (iom->offset >= 0) {
> >>>> -				if (iom->type & IOMUX_SOURCE_PMU)
> >>>> +				if ((iom->type & IOMUX_SOURCE_PMU) || \
> >>>> +				    (iom->type & IOMUX_L_SOURCE_PMU))
> >>>
> >>> nitpick: Could be if (iom->type & (IOMUX_SOURCE_PMU | IOMUX_L_SOURCE_PMU))
> >>> instead.
> >>>
> >>>>   					pmu_offs = iom->offset;
> >>>>   				else
> >>>>   					grf_offs = iom->offset;
> >>>>   			} else { /* set current iomux offset */
> >>>> -				iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
> >>>> -							pmu_offs : grf_offs;
> >>>> +				iom->offset = ((iom->type & IOMUX_SOURCE_PMU) ||
> >>>> +						(iom->type & IOMUX_L_SOURCE_PMU)) ?
> >>>
> >>> Ditto.
> >>>
> >>> Cheers,
> >>> Quentin

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2023-01-27 16:50 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-05 15:34 [PATCH 0/5] Rockchip: Improve Support for RK3566 Devices Chris Morgan
2023-01-05 15:34 ` [PATCH 1/5] rockchip: vop2: Add vop2 dt-binding from Linux Chris Morgan
2023-01-17  2:07   ` Kever Yang
2023-01-05 15:34 ` [PATCH 2/5] arm64: dts: rockchip: Sync rk356x from Linux main Chris Morgan
2023-01-09 22:34   ` Johan Jonker
2023-01-05 15:34 ` [PATCH 3/5] rockchip: rk3568: add boot device detection Chris Morgan
2023-01-17  2:09   ` Kever Yang
2023-01-05 15:34 ` [PATCH 4/5] rockchip: rk3568: enable automatic power savings Chris Morgan
2023-01-05 15:34 ` [PATCH 5/5] gpio/rockchip: rk_gpio support v2 gpio controller Chris Morgan
2023-01-05 18:01   ` Quentin Schulz
2023-01-19 18:21     ` Chris Morgan
2023-01-26 16:11       ` Chris Morgan
2023-01-26 18:11         ` Johan Jonker
2023-01-27 16:50           ` Chris Morgan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).