aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/Makefile4
-rw-r--r--arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi91
-rw-r--r--arch/arm/dts/px30-ringneck-haikou.dts232
-rw-r--r--arch/arm/dts/px30-ringneck.dtsi382
-rw-r--r--arch/arm/dts/px30.dtsi28
-rw-r--r--arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi31
-rw-r--r--arch/arm/dts/rk3399-pinephone-pro.dts474
-rw-r--r--arch/arm/dts/rk3399-puma-haikou.dts5
-rw-r--r--arch/arm/dts/rk3399-puma.dtsi32
-rw-r--r--arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi10
-rw-r--r--arch/arm/dts/rv1126-edgeble-neu2-io.dts42
-rw-r--r--arch/arm/dts/rv1126-edgeble-neu2.dtsi338
-rw-r--r--arch/arm/dts/rv1126-pinctrl.dtsi211
-rw-r--r--arch/arm/dts/rv1126-u-boot.dtsi62
-rw-r--r--arch/arm/dts/rv1126.dtsi438
-rw-r--r--arch/arm/include/asm/arch-rockchip/cru_rv1126.h459
-rw-r--r--arch/arm/include/asm/arch-rockchip/dram_spec_timing.h452
-rw-r--r--arch/arm/include/asm/arch-rockchip/grf_rv1126.h251
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_common.h214
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_msch.h12
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h100
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h93
-rw-r--r--arch/arm/include/asm/arch-rockchip/sdram_rv1126.h420
-rw-r--r--arch/arm/include/asm/arch-rv1126/boot0.h11
-rw-r--r--arch/arm/include/asm/arch-rv1126/gpio.h11
-rw-r--r--arch/arm/mach-kirkwood/Kconfig22
-rw-r--r--arch/arm/mach-rockchip/Kconfig46
-rw-r--r--arch/arm/mach-rockchip/Makefile1
-rw-r--r--arch/arm/mach-rockchip/px30/Kconfig25
-rw-r--r--arch/arm/mach-rockchip/px30/px30.c71
-rw-r--r--arch/arm/mach-rockchip/rk3399/Kconfig8
-rw-r--r--arch/arm/mach-rockchip/rv1126/Kconfig59
-rw-r--r--arch/arm/mach-rockchip/rv1126/Makefile13
-rw-r--r--arch/arm/mach-rockchip/rv1126/clk_rv1126.c33
-rw-r--r--arch/arm/mach-rockchip/rv1126/rv1126.c75
-rw-r--r--arch/arm/mach-rockchip/rv1126/syscon_rv1126.c47
-rw-r--r--board/edgeble/neural-compute-module-2/Kconfig16
-rw-r--r--board/edgeble/neural-compute-module-2/MAINTAINERS6
-rw-r--r--board/edgeble/neural-compute-module-2/Makefile7
-rw-r--r--board/edgeble/neural-compute-module-2/neu2.c4
-rw-r--r--board/engicam/px30_core/Kconfig2
-rw-r--r--board/pine64/pinephone-pro-rk3399/Kconfig15
-rw-r--r--board/pine64/pinephone-pro-rk3399/MAINTAINERS8
-rw-r--r--board/pine64/pinephone-pro-rk3399/Makefile1
-rw-r--r--board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c76
-rw-r--r--board/theobroma-systems/ringneck_px30/Kconfig18
-rw-r--r--board/theobroma-systems/ringneck_px30/MAINTAINERS9
-rw-r--r--board/theobroma-systems/ringneck_px30/Makefile7
-rw-r--r--board/theobroma-systems/ringneck_px30/README69
-rw-r--r--board/theobroma-systems/ringneck_px30/ringneck-px30.c175
-rw-r--r--common/spl/Kconfig.tpl2
-rw-r--r--configs/khadas-edge-captain-rk3399_defconfig2
-rw-r--r--configs/khadas-edge-rk3399_defconfig2
-rw-r--r--configs/khadas-edge-v-rk3399_defconfig2
-rw-r--r--configs/leez-rk3399_defconfig2
-rw-r--r--configs/nanopi-r4s-rk3399_defconfig2
-rw-r--r--configs/neu2-io-rv1126_defconfig57
-rw-r--r--configs/pinebook-pro-rk3399_defconfig2
-rw-r--r--configs/pinephone-pro-rk3399_defconfig104
-rw-r--r--configs/ringneck-px30_defconfig129
-rw-r--r--configs/roc-pc-mezzanine-rk3399_defconfig4
-rw-r--r--configs/roc-pc-rk3399_defconfig4
-rw-r--r--configs/rock-pi-4-rk3399_defconfig2
-rw-r--r--configs/rock-pi-4c-rk3399_defconfig2
-rw-r--r--configs/rockpro64-rk3399_defconfig2
-rw-r--r--doc/board/rockchip/rockchip.rst4
-rw-r--r--drivers/clk/rockchip/Makefile1
-rw-r--r--drivers/clk/rockchip/clk_px30.c3
-rw-r--r--drivers/clk/rockchip/clk_rv1126.c1889
-rw-r--r--drivers/pinctrl/rockchip/Makefile1
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-px30.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3128.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk322x.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3288.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3308.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3328.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rk3399.c11
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rockchip-core.c45
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rockchip.h58
-rw-r--r--drivers/pinctrl/rockchip/pinctrl-rv1126.c416
-rw-r--r--drivers/ram/Makefile2
-rw-r--r--drivers/ram/rockchip/Kconfig32
-rw-r--r--drivers/ram/rockchip/Makefile1
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc72
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-loader_params.inc197
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc78
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc78
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc78
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc78
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc78
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc78
-rw-r--r--drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc78
-rw-r--r--drivers/ram/rockchip/sdram_common.c6
-rw-r--r--drivers/ram/rockchip/sdram_pctl_px30.c6
-rw-r--r--drivers/ram/rockchip/sdram_px30.c8
-rw-r--r--drivers/ram/rockchip/sdram_rk3328.c2
-rw-r--r--drivers/ram/rockchip/sdram_rk3399.c9
-rw-r--r--drivers/ram/rockchip/sdram_rv1126.c3543
-rw-r--r--drivers/timer/orion-timer.c3
-rw-r--r--include/configs/neural-compute-module-2.h21
-rw-r--r--include/configs/pinephone-pro-rk3399.h19
-rw-r--r--include/configs/px30_common.h3
-rw-r--r--include/configs/ringneck_px30.h15
-rw-r--r--include/configs/rv1126_common.h40
-rw-r--r--include/dt-bindings/clock/rockchip,rv1126-cru.h632
-rw-r--r--include/dt-bindings/power/rockchip,rv1126-power.h35
-rw-r--r--include/rc4.h2
-rw-r--r--lib/rc4.c2
-rw-r--r--tools/rkcommon.c3
115 files changed, 13520 insertions, 139 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index b3baaf482908..44256d9fa940 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -153,6 +153,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
rk3399-nanopi-r4s.dtb \
rk3399-orangepi.dtb \
rk3399-pinebook-pro.dtb \
+ rk3399-pinephone-pro.dtb \
rk3399-puma-haikou.dtb \
rk3399-roc-pc.dtb \
rk3399-roc-pc-mezzanine.dtb \
@@ -170,6 +171,9 @@ dtb-$(CONFIG_ROCKCHIP_RV1108) += \
rv1108-elgin-r1.dtb \
rv1108-evb.dtb
+dtb-$(CONFIG_ROCKCHIP_RV1126) += \
+ rv1126-edgeble-neu2-io.dtb
+
dtb-$(CONFIG_ARCH_S5P4418) += \
s5p4418-nanopi2.dtb
diff --git a/arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi b/arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi
new file mode 100644
index 000000000000..e8a34c7c1eb8
--- /dev/null
+++ b/arch/arm/dts/px30-ringneck-haikou-u-boot.dtsi
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "px30-u-boot.dtsi"
+
+/ {
+ config {
+ u-boot,mmc-env-offset = <0x5000>; /* @ 20KB */
+ u-boot,efi-partition-entries-offset = <0x200000>; /* 2MB */
+ u-boot,boot-led = "module_led";
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ u-boot,spl-boot-order = "same-as-spl", &emmc, &sdmmc;
+ };
+};
+
+&binman {
+ simple-bin {
+ blob {
+ offset = <((CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR - 64) * 512)>;
+ };
+ };
+};
+
+&emmc_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&emmc_cmd {
+ u-boot,dm-pre-reloc;
+};
+
+&emmc_bus8 {
+ u-boot,dm-pre-reloc;
+};
+
+&gpio0 {
+ u-boot,dm-pre-reloc;
+};
+
+&gpio1 {
+ u-boot,dm-pre-reloc;
+};
+
+&gpio2 {
+ u-boot,dm-pre-reloc;
+
+ /*
+ * The Qseven BIOS_DISABLE signal on the PX30-µQ7 keeps the on-module
+ * eMMC powered-down initially (in fact it keeps the reset signal
+ * asserted). BIOS_DISABLE_OVERRIDE pin allows to re-enable eMMC after
+ * the SPL has been booted from SD Card.
+ */
+ bios-disable-override-hog {
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&pinctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&pcfg_pull_none_8ma {
+ u-boot,dm-pre-reloc;
+};
+
+&pcfg_pull_up_8ma {
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc_bus4 {
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc_clk {
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc_cmd {
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc_det {
+ u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+ clock-frequency = <24000000>;
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/px30-ringneck-haikou.dts b/arch/arm/dts/px30-ringneck-haikou.dts
new file mode 100644
index 000000000000..08a3ad3e7ae9
--- /dev/null
+++ b/arch/arm/dts/px30-ringneck-haikou.dts
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include "px30-ringneck.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Theobroma Systems PX30-uQ7 SoM on Haikou devkit";
+ compatible = "tsd,px30-ringneck-haikou", "rockchip,px30";
+
+ aliases {
+ mmc2 = &sdmmc;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&haikou_keys_pin>;
+ pinctrl-names = "default";
+
+ button-batlow-n {
+ label = "BATLOW#";
+ linux,code = <KEY_BATTERY>;
+ gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
+ };
+
+ button-slp-btn-n {
+ label = "SLP_BTN#";
+ linux,code = <KEY_SLEEP>;
+ gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+
+ button-wake-n {
+ label = "WAKE#";
+ linux,code = <KEY_WAKEUP>;
+ gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ switch-lid-btn-n {
+ label = "LID_BTN#";
+ linux,code = <SW_LID>;
+ linux,input-type = <EV_SW>;
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ leds {
+ pinctrl-0 = <&module_led_pin>, <&sd_card_led_pin>;
+
+ sd_card_led: led-1 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "mmc2";
+ function = LED_FUNCTION_SD;
+ color = <LED_COLOR_ID_BLUE>;
+ };
+ };
+
+ i2s0-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "Haikou,I2S-codec";
+ simple-audio-card,mclk-fs = <512>;
+
+ simple-audio-card,codec {
+ clocks = <&sgtl5000_clk>;
+ sound-dai = <&sgtl5000>;
+ };
+
+ simple-audio-card,cpu {
+ bitclock-master;
+ frame-master;
+ sound-dai = <&i2s0_8ch>;
+ };
+ };
+
+ sgtl5000_clk: sgtl5000-oscillator {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>;
+ };
+
+ dc_12v: dc-12v-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "dc_12v";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ };
+
+ vcc3v3_baseboard: vcc3v3-baseboard-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_baseboard";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vcc5v0_baseboard: vcc5v0-baseboard-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_baseboard";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_12v>;
+ };
+
+ vdda_codec: vdda-codec-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vdda_codec";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc5v0_baseboard>;
+ };
+
+ vddd_codec: vddd-codec-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vddd_codec";
+ regulator-boot-on;
+ regulator-min-microvolt = <1600000>;
+ regulator-max-microvolt = <1600000>;
+ vin-supply = <&vcc5v0_baseboard>;
+ };
+};
+
+&i2c2 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ sgtl5000: codec@a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&sgtl5000_clk>;
+ #sound-dai-cells = <0>;
+ VDDA-supply = <&vdda_codec>;
+ VDDIO-supply = <&vcc3v3_baseboard>;
+ VDDD-supply = <&vddd_codec>;
+ };
+};
+
+&i2c3 {
+ eeprom@50 {
+ reg = <0x50>;
+ compatible = "atmel,24c01";
+ pagesize = <8>;
+ size = <128>;
+ vcc-supply = <&vcc3v3_baseboard>;
+ };
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&gmac {
+ status = "okay";
+};
+
+&pinctrl {
+ haikou {
+ haikou_keys_pin: haikou-keys-pin {
+ rockchip,pins =
+ /* WAKE# */
+ <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* SLP_BTN# */
+ <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* LID_BTN */
+ <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* BATLOW# */
+ <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+ /* BIOS_DISABLE# */
+ <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ leds {
+ sd_card_led_pin: sd-card-led-pin {
+ rockchip,pins =
+ <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm0 {
+ status = "okay";
+};
+
+&sdmmc {
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ vmmc-supply = <&vcc3v3_baseboard>;
+ status = "okay";
+};
+
+&spi1 {
+ status = "okay";
+};
+
+&u2phy_otg {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart5 {
+ pinctrl-0 = <&uart5_xfer>;
+ status = "okay";
+};
+
+&usb20_otg {
+ status = "okay";
+};
diff --git a/arch/arm/dts/px30-ringneck.dtsi b/arch/arm/dts/px30-ringneck.dtsi
new file mode 100644
index 000000000000..12397755830b
--- /dev/null
+++ b/arch/arm/dts/px30-ringneck.dtsi
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Theobroma Systems Design und Consulting GmbH
+ */
+
+/dts-v1/;
+#include "px30.dtsi"
+#include <dt-bindings/leds/common.h>
+
+/ {
+ aliases {
+ mmc0 = &emmc;
+ mmc1 = &sdio;
+ rtc0 = &rtc_twi;
+ rtc1 = &rk809;
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-0 = <&emmc_reset>;
+ pinctrl-names = "default";
+ reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&module_led_pin>;
+ status = "okay";
+
+ module_led: led-0 {
+ gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>;
+ function = LED_FUNCTION_HEARTBEAT;
+ linux,default-trigger = "heartbeat";
+ color = <LED_COLOR_ID_AMBER>;
+ };
+ };
+
+ vcc5v0_sys: vccsys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&emmc {
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-hs200-1_8v;
+ supports-emmc;
+ mmc-pwrseq = <&emmc_pwrseq>;
+ non-removable;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_emmc>;
+
+ status = "okay";
+};
+
+/* On-module TI DP83825I PHY but no connector, enable in carrierboard */
+&gmac {
+ snps,reset-gpio = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 50000 50000>;
+ phy-supply = <&vcc_3v3>;
+ clock_in_out = "output";
+};
+
+&gpio2 {
+ /*
+ * The Qseven BIOS_DISABLE signal on the PX30-µQ7 keeps the on-module
+ * eMMC powered-down initially (in fact it keeps the reset signal
+ * asserted). BIOS_DISABLE_OVERRIDE pin allows to re-enable eMMC after
+ * the SPL has been booted from SD Card.
+ */
+ bios-disable-override-hog {
+ gpios = <RK_PB5 GPIO_ACTIVE_LOW>;
+ output-high;
+ line-name = "bios_disable_override";
+ gpio-hog;
+ };
+
+ /*
+ * The BIOS_DISABLE hog is a feedback pin for the actual status of the
+ * signal, ignoring the BIOS_DISABLE_OVERRIDE logic. This usually
+ * represents the state of a switch on the baseboard.
+ */
+ bios-disable-n-hog {
+ gpios = <RK_PC2 GPIO_ACTIVE_LOW>;
+ line-name = "bios_disable";
+ input;
+ gpio-hog;
+ };
+};
+
+&gpu {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+ pinctrl-0 = <&pmic_int>;
+ pinctrl-names = "default";
+ #clock-cells = <0>;
+ clock-output-names = "xin32k";
+ rockchip,system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc_3v3>;
+ vcc6-supply = <&vcc_3v3>;
+ vcc7-supply = <&vcc_3v3>;
+ vcc9-supply = <&vcc5v0_sys>;
+
+ regulators {
+ vdd_log: DCDC_REG1 {
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <950000>;
+ };
+ };
+
+ vdd_arm: DCDC_REG2 {
+ regulator-name = "vdd_arm";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-ramp-delay = <6001>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <950000>;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-name = "vcc_ddr";
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_3v0_1v8: vcc_emmc: DCDC_REG4 {
+ regulator-name = "vcc_3v0_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3000000>;
+ };
+ };
+
+ vcc_3v3: DCDC_REG5 {
+ regulator-name = "vcc_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_1v8: LDO_REG2 {
+ regulator-name = "vcc_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcc_1v0: LDO_REG3 {
+ regulator-name = "vcc_1v0";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_lcd: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-name = "vcc_lcd";
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1000000>;
+ };
+ };
+
+ vcc_1v8_lcd: LDO_REG8 {
+ regulator-name = "vcc_1v8_lcd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vcca_1v8: LDO_REG9 {
+ regulator-name = "vcca_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+
+ /* SE05x is limited to Fast Mode */
+ clock-frequency = <400000>;
+
+ fan: fan@18 {
+ compatible = "ti,amc6821";
+ reg = <0x18>;
+ #cooling-cells = <2>;
+ };
+
+ rtc_twi: rtc@6f {
+ compatible = "isil,isl1208";
+ reg = <0x6f>;
+ };
+};
+
+&i2c3 {
+ status = "okay";
+};
+
+&i2s0_8ch {
+ rockchip,trcm-sync-tx-only;
+
+ pinctrl-0 = <&i2s0_8ch_sclktx &i2s0_8ch_lrcktx
+ &i2s0_8ch_sdo0 &i2s0_8ch_sdi0>;
+};
+
+&io_domains {
+ vccio1-supply = <&vcc_3v3>;
+ vccio2-supply = <&vccio_sd>;
+ vccio3-supply = <&vcc_3v3>;
+ vccio4-supply = <&vcc_3v3>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc_emmc>;
+ vccio-oscgpi-supply = <&vcc_3v3>;
+
+ status = "okay";
+};
+
+&pinctrl {
+ emmc {
+ emmc_reset: emmc-reset {
+ rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ leds {
+ module_led_pin: module-led-pin {
+ rockchip,pins = <1 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int: pmic-int {
+ rockchip,pins =
+ <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc {
+ vqmmc-supply = <&vccio_sd>;
+};
+
+&tsadc {
+ status = "okay";
+};
+
+&u2phy {
+ status = "okay";
+};
+
+&u2phy_host {
+ status = "okay";
+};
+
+/* Mule UCAN */
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi
index 00f50b05d55a..bfa3580429d1 100644
--- a/arch/arm/dts/px30.dtsi
+++ b/arch/arm/dts/px30.dtsi
@@ -365,6 +365,28 @@
status = "disabled";
};
+ i2s0_8ch: i2s@ff060000 {
+ compatible = "rockchip,px30-i2s-tdm";
+ reg = <0x0 0xff060000 0x0 0x1000>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru SCLK_I2S0_TX>, <&cru SCLK_I2S0_RX>, <&cru HCLK_I2S0>;
+ clock-names = "mclk_tx", "mclk_rx", "hclk";
+ dmas = <&dmac 16>, <&dmac 17>;
+ dma-names = "tx", "rx";
+ rockchip,grf = <&grf>;
+ resets = <&cru SRST_I2S0_TX>, <&cru SRST_I2S0_RX>;
+ reset-names = "tx-m", "rx-m";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_8ch_sclktx &i2s0_8ch_sclkrx
+ &i2s0_8ch_lrcktx &i2s0_8ch_lrckrx
+ &i2s0_8ch_sdo0 &i2s0_8ch_sdi0
+ &i2s0_8ch_sdo1 &i2s0_8ch_sdi1
+ &i2s0_8ch_sdo2 &i2s0_8ch_sdi2
+ &i2s0_8ch_sdo3 &i2s0_8ch_sdi3>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
i2s1_2ch: i2s@ff070000 {
compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
reg = <0x0 0xff070000 0x0 0x1000>;
@@ -528,7 +550,7 @@
i2c0: i2c@ff180000 {
compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
reg = <0x0 0xff180000 0x0 0x1000>;
- clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+ clocks = <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
clock-names = "i2c", "pclk";
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
pinctrl-names = "default";
@@ -711,7 +733,7 @@
clock-names = "pclk", "timer";
};
- dmac: dmac@ff240000 {
+ dmac: dma-controller@ff240000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x0 0xff240000 0x0 0x4000>;
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
@@ -1072,7 +1094,7 @@
};
dsi: dsi@ff450000 {
- compatible = "rockchip,px30-mipi-dsi";
+ compatible = "rockchip,px30-mipi-dsi", "snps,dw-mipi-dsi";
reg = <0x0 0xff450000 0x0 0x10000>;
interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_MIPI_DSI>;
diff --git a/arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi b/arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi
new file mode 100644
index 000000000000..1dad283ad052
--- /dev/null
+++ b/arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Peter Robinson <pbrobinson at gmail.com>
+ */
+
+#include "rk3399-u-boot.dtsi"
+#include "rk3399-sdram-lpddr4-100.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+ };
+
+ config {
+ u-boot,spl-payload-offset = <0x60000>; /* @ 384KB */
+ };
+};
+
+&rng {
+ status = "okay";
+};
+
+&sdhci {
+ max-frequency = <25000000>;
+ u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+ max-frequency = <20000000>;
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3399-pinephone-pro.dts b/arch/arm/dts/rk3399-pinephone-pro.dts
new file mode 100644
index 000000000000..04403a76238b
--- /dev/null
+++ b/arch/arm/dts/rk3399-pinephone-pro.dts
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Martijn Braam <martijn@brixit.nl>
+ * Copyright (c) 2021 Kamil Trzciński <ayufan@ayufan.eu>
+ */
+
+/*
+ * PinePhone Pro datasheet:
+ * https://files.pine64.org/doc/PinePhonePro/PinephonePro-Schematic-V1.0-20211127.pdf
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+ model = "Pine64 PinePhonePro";
+ compatible = "pine64,pinephone-pro", "rockchip,rk3399";
+ chassis-type = "handset";
+
+ aliases {
+ mmc0 = &sdio0;
+ mmc1 = &sdmmc;
+ mmc2 = &sdhci;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwrbtn_pin>;
+
+ key-power {
+ debounce-interval = <20>;
+ gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "Power";
+ linux,code = <KEY_POWER>;
+ wakeup-source;
+ };
+ };
+
+ vcc_sys: vcc-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc3v3_sys: vcc3v3-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vcc_sys>;
+ };
+
+ vcca1v8_s3: vcc1v8-s3-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcca1v8_s3";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc3v3_sys>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vcc1v8_codec: vcc1v8-codec-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PA4 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc1v8_codec_en>;
+ regulator-name = "vcc1v8_codec";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc3v3_sys>;
+ };
+
+ wifi_pwrseq: sdio-wifi-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk818 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h_pin>;
+ /*
+ * Wait between power-on and SDIO access for CYP43455
+ * POR circuit.
+ */
+ post-power-on-delay-ms = <110>;
+ /*
+ * Wait between consecutive toggles for CYP43455 CBUCK
+ * regulator discharge.
+ */
+ power-off-delay-us = <10000>;
+
+ /* WL_REG_ON on module */
+ reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&cpu_l0 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l1 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l2 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l3 {
+ cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_b0 {
+ cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_b1 {
+ cpu-supply = <&vdd_cpu_b>;
+};
+
+&emmc_phy {
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ i2c-scl-rising-time-ns = <168>;
+ i2c-scl-falling-time-ns = <4>;
+ status = "okay";
+
+ rk818: pmic@1c {
+ compatible = "rockchip,rk818";
+ reg = <0x1c>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <RK_PC5 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ clock-output-names = "xin32k", "rk808-clkout2";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc3v3_sys>;
+ vcc8-supply = <&vcc_sys>;
+ vcc9-supply = <&vcc3v3_sys>;
+
+ regulators {
+ vdd_cpu_l: DCDC_REG1 {
+ regulator-name = "vdd_cpu_l";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <975000>;
+ regulator-ramp-delay = <6001>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_center: DCDC_REG2 {
+ regulator-name = "vdd_center";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1000000>;
+ 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-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_1v8: DCDC_REG4 {
+ regulator-name = "vcc_1v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcca3v0_codec: LDO_REG1 {
+ regulator-name = "vcca3v0_codec";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vcc3v0_touch: LDO_REG2 {
+ regulator-name = "vcc3v0_touch";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vcca1v8_codec: LDO_REG3 {
+ regulator-name = "vcca1v8_codec";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ rk818_pwr_on: LDO_REG4 {
+ regulator-name = "rk818_pwr_on";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_3v0: LDO_REG5 {
+ regulator-name = "vcc_3v0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_1v5: LDO_REG6 {
+ regulator-name = "vcc_1v5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc1v8_dvp: LDO_REG7 {
+ regulator-name = "vcc1v8_dvp";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vcc3v3_s3: LDO_REG8 {
+ regulator-name = "vcc3v3_s3";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG9 {
+ regulator-name = "vccio_sd";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc3v3_s0: SWITCH_REG {
+ regulator-name = "vcc3v3_s0";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+ };
+ };
+
+ vdd_cpu_b: regulator@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vsel1_pin>;
+ regulator-name = "vdd_cpu_b";
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-ramp-delay = <1000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_gpu: regulator@41 {
+ compatible = "silergy,syr828";
+ reg = <0x41>;
+ fcs,suspend-voltage-selector = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vsel2_pin>;
+ regulator-name = "vdd_gpu";
+ regulator-min-microvolt = <875000>;
+ regulator-max-microvolt = <975000>;
+ regulator-ramp-delay = <1000>;
+ regulator-always-on;
+ regulator-boot-on;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&cluster0_opp {
+ opp04 {
+ status = "disabled";
+ };
+
+ opp05 {
+ status = "disabled";
+ };
+};
+
+&cluster1_opp {
+ opp06 {
+ opp-hz = /bits/ 64 <1500000000>;
+ opp-microvolt = <1100000 1100000 1150000>;
+ };
+
+ opp07 {
+ status = "disabled";
+ };
+};
+
+&io_domains {
+ bt656-supply = <&vcc1v8_dvp>;
+ audio-supply = <&vcca1v8_codec>;
+ sdmmc-supply = <&vccio_sd>;
+ gpio1830-supply = <&vcc_3v0>;
+ status = "okay";
+};
+
+&pmu_io_domains {
+ pmu1830-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&pinctrl {
+ buttons {
+ pwrbtn_pin: pwrbtn-pin {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ vsel1_pin: vsel1-pin {
+ rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+
+ vsel2_pin: vsel2-pin {
+ rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h_pin: wifi-enable-h-pin {
+ rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ sound {
+ vcc1v8_codec_en: vcc1v8-codec-en {
+ rockchip,pins = <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>;
+ };
+ };
+
+ wireless-bluetooth {
+ bt_wake_pin: bt-wake-pin {
+ rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_host_wake_pin: bt-host-wake-pin {
+ rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ bt_reset_pin: bt-reset-pin {
+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&sdio0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ disable-wp;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ max-frequency = <150000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+ vmmc-supply = <&vcc3v3_sys>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdhci {
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ non-removable;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <1>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "brcm,bcm4345c5";
+ clocks = <&rk818 1>;
+ clock-names = "lpo";
+ device-wakeup-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>;
+ host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+ max-speed = <1500000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_host_wake_pin &bt_wake_pin &bt_reset_pin>;
+ shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+ vbat-supply = <&vcc3v3_sys>;
+ vddio-supply = <&vcc_1v8>;
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rk3399-puma-haikou.dts b/arch/arm/dts/rk3399-puma-haikou.dts
index 292bb7e80cf3..115c14c0a3c6 100644
--- a/arch/arm/dts/rk3399-puma-haikou.dts
+++ b/arch/arm/dts/rk3399-puma-haikou.dts
@@ -49,7 +49,7 @@
sgtl5000_clk: sgtl5000-oscillator {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <24576000>;
+ clock-frequency = <24576000>;
};
dc_12v: dc-12v {
@@ -207,7 +207,7 @@
cap-sd-highspeed;
cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
disable-wp;
- max-frequency = <150000000>;
+ max-frequency = <40000000>;
pinctrl-names = "default";
pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
vmmc-supply = <&vcc3v3_baseboard>;
@@ -232,6 +232,7 @@
&usbdrd_dwc3_0 {
dr_mode = "otg";
+ extcon = <&extcon_usb3>;
status = "okay";
};
diff --git a/arch/arm/dts/rk3399-puma.dtsi b/arch/arm/dts/rk3399-puma.dtsi
index fb67db4619ea..aa3e21bd6c8f 100644
--- a/arch/arm/dts/rk3399-puma.dtsi
+++ b/arch/arm/dts/rk3399-puma.dtsi
@@ -25,6 +25,13 @@
};
};
+ extcon_usb3: extcon-usb3 {
+ compatible = "linux,extcon-usb-gpio";
+ id-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&usb3_id>;
+ };
+
clkin_gmac: external-gmac-clock {
compatible = "fixed-clock";
clock-frequency = <125000000>;
@@ -55,7 +62,6 @@
vcc5v0_host: vcc5v0-host-regulator {
compatible = "regulator-fixed";
gpio = <&gpio4 RK_PA3 GPIO_ACTIVE_LOW>;
- enable-active-low;
pinctrl-names = "default";
pinctrl-0 = <&vcc5v0_host_en>;
regulator-name = "vcc5v0_host";
@@ -71,6 +77,17 @@
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
+
+ vdd_log: vdd-log {
+ compatible = "pwm-regulator";
+ pwms = <&pwm2 0 25000 1>;
+ pwm-supply = <&vcc5v0_sys>;
+ regulator-name = "vdd_log";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&cpu_b0 {
@@ -422,9 +439,22 @@
<4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ usb3 {
+ usb3_id: usb3-id {
+ rockchip,pins =
+ <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&sdhci {
+ /*
+ * Signal integrity isn't great at 200MHz but 100MHz has proven stable
+ * enough.
+ */
+ max-frequency = <100000000>;
+
bus-width = <8>;
mmc-hs400-1_8v;
mmc-hs400-enhanced-strobe;
diff --git a/arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi b/arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi
new file mode 100644
index 000000000000..51a1617708ae
--- /dev/null
+++ b/arch/arm/dts/rv1126-edgeble-neu2-io-u-boot.dtsi
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include "rv1126-u-boot.dtsi"
+
+&sdio {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/rv1126-edgeble-neu2-io.dts b/arch/arm/dts/rv1126-edgeble-neu2-io.dts
new file mode 100644
index 000000000000..dded0a12f0cd
--- /dev/null
+++ b/arch/arm/dts/rv1126-edgeble-neu2-io.dts
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+/dts-v1/;
+#include "rv1126.dtsi"
+#include "rv1126-edgeble-neu2.dtsi"
+
+/ {
+ model = "Edgeble Neu2 IO Board";
+ compatible = "edgeble,neural-compute-module-2-io",
+ "edgeble,neural-compute-module-2", "rockchip,rv1126";
+
+ aliases {
+ serial2 = &uart2;
+ };
+
+ chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+};
+
+&sdmmc {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ card-detect-delay = <200>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_bus4 &sdmmc0_det>;
+ rockchip,default-sample-phase = <90>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr104;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/rv1126-edgeble-neu2.dtsi b/arch/arm/dts/rv1126-edgeble-neu2.dtsi
new file mode 100644
index 000000000000..cc64ba4be344
--- /dev/null
+++ b/arch/arm/dts/rv1126-edgeble-neu2.dtsi
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+/ {
+ compatible = "edgeble,neural-compute-module-2", "rockchip,rv1126";
+
+ aliases {
+ mmc0 = &emmc;
+ };
+
+ vcc5v0_sys: vcc5v0-sys-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc5v0_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ };
+
+ vccio_flash: vccio-flash-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&flash_vol_sel>;
+ regulator-name = "vccio_flash";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ };
+
+ sdio_pwrseq: pwrseq-sdio {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk809 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ reset-gpios = <&gpio1 RK_PD0 GPIO_ACTIVE_LOW>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_arm>;
+};
+
+&emmc {
+ bus-width = <8>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_bus8 &emmc_cmd &emmc_clk &emmc_rstnout>;
+ rockchip,default-sample-phase = <90>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vccio_flash>;
+ status = "okay";
+};
+
+&i2c0 {
+ clock-frequency = <400000>;
+ status = "okay";
+
+ rk809: pmic@20 {
+ compatible = "rockchip,rk809";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PB1 IRQ_TYPE_LEVEL_LOW>;
+ #clock-cells = <1>;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ wakeup-source;
+
+ vcc1-supply = <&vcc5v0_sys>;
+ vcc2-supply = <&vcc5v0_sys>;
+ vcc3-supply = <&vcc5v0_sys>;
+ vcc4-supply = <&vcc5v0_sys>;
+ vcc5-supply = <&vcc_buck5>;
+ vcc6-supply = <&vcc_buck5>;
+ vcc7-supply = <&vcc5v0_sys>;
+ vcc8-supply = <&vcc3v3_sys>;
+ vcc9-supply = <&vcc5v0_sys>;
+
+ regulators {
+ vdd_npu_vepu: DCDC_REG1 {
+ regulator-name = "vdd_npu_vepu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <650000>;
+ regulator-max-microvolt = <950000>;
+ regulator-ramp-delay = <6001>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_arm: DCDC_REG2 {
+ regulator-name = "vdd_arm";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <725000>;
+ 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;
+ };
+ };
+
+ vcc3v3_sys: DCDC_REG4 {
+ regulator-name = "vcc3v3_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_buck5: DCDC_REG5 {
+ regulator-name = "vcc_buck5";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <2200000>;
+ };
+ };
+
+ vcc_0v8: LDO_REG1 {
+ regulator-name = "vcc_0v8";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8_pmu: LDO_REG2 {
+ regulator-name = "vcc1v8_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>;
+ };
+ };
+
+ vdd0v8_pmu: LDO_REG3 {
+ regulator-name = "vcc0v8_pmu";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <800000>;
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <800000>;
+ };
+ };
+
+ vcc_1v8: LDO_REG4 {
+ regulator-name = "vcc_1v8";
+ 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>;
+ };
+ };
+
+ vcc_dovdd: LDO_REG5 {
+ regulator-name = "vcc_dovdd";
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_dvdd: LDO_REG6 {
+ regulator-name = "vcc_dvdd";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_avdd: LDO_REG7 {
+ regulator-name = "vcc_avdd";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG8 {
+ regulator-name = "vccio_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_sd: LDO_REG9 {
+ regulator-name = "vcc3v3_sd";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_5v0: SWITCH_REG1 {
+ regulator-name = "vcc_5v0";
+ };
+
+ vcc_3v3: SWITCH_REG2 {
+ regulator-name = "vcc_3v3";
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+};
+
+&pinctrl {
+ bt {
+ bt_enable: bt-enable {
+ rockchip,pins = <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ flash {
+ flash_vol_sel: flash-vol-sel {
+ rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ wifi {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ pmuio0-supply = <&vcc1v8_pmu>;
+ pmuio1-supply = <&vcc3v3_sys>;
+ vccio1-supply = <&vccio_flash>;
+ vccio2-supply = <&vccio_sd>;
+ vccio3-supply = <&vcc_1v8>;
+ vccio4-supply = <&vcc_dovdd>;
+ vccio5-supply = <&vcc_1v8>;
+ vccio6-supply = <&vcc_1v8>;
+ vccio7-supply = <&vcc_dovdd>;
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdio {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ max-frequency = <100000000>;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_clk &sdmmc1_cmd &sdmmc1_bus4>;
+ rockchip,default-sample-phase = <90>;
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc3v3_sys>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer &uart0_ctsn &uart0_rtsn>;
+ status = "okay";
+
+ bluetooth {
+ compatible = "qcom,qca9377-bt";
+ clocks = <&rk809 1>;
+ enable-gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>; /* BT_RST */
+ max-speed = <2000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&bt_enable>;
+ vddxo-supply = <&vcc3v3_sys>;
+ vddio-supply = <&vcc_1v8>;
+ };
+};
diff --git a/arch/arm/dts/rv1126-pinctrl.dtsi b/arch/arm/dts/rv1126-pinctrl.dtsi
new file mode 100644
index 000000000000..28d8d29942fd
--- /dev/null
+++ b/arch/arm/dts/rv1126-pinctrl.dtsi
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rockchip-pinconf.dtsi"
+
+/*
+ * This file is auto generated by pin2dts tool, please keep these code
+ * by adding changes at end of this file.
+ */
+&pinctrl {
+ emmc {
+ /omit-if-no-ref/
+ emmc_rstnout: emmc-rstnout {
+ rockchip,pins =
+ /* emmc_rstn */
+ <1 RK_PA3 2 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ emmc_bus8: emmc-bus8 {
+ rockchip,pins =
+ /* emmc_d0 */
+ <0 RK_PC4 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d1 */
+ <0 RK_PC5 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d2 */
+ <0 RK_PC6 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d3 */
+ <0 RK_PC7 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d4 */
+ <0 RK_PD0 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d5 */
+ <0 RK_PD1 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d6 */
+ <0 RK_PD2 2 &pcfg_pull_up_drv_level_2>,
+ /* emmc_d7 */
+ <0 RK_PD3 2 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ emmc_clk: emmc-clk {
+ rockchip,pins =
+ /* emmc_clko */
+ <0 RK_PD7 2 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ emmc_cmd: emmc-cmd {
+ rockchip,pins =
+ /* emmc_cmd */
+ <0 RK_PD5 2 &pcfg_pull_up_drv_level_2>;
+ };
+ };
+ i2c0 {
+ /omit-if-no-ref/
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins =
+ /* i2c0_scl */
+ <0 RK_PB4 1 &pcfg_pull_none_drv_level_0_smt>,
+ /* i2c0_sda */
+ <0 RK_PB5 1 &pcfg_pull_none_drv_level_0_smt>;
+ };
+ };
+ sdmmc0 {
+ /omit-if-no-ref/
+ sdmmc0_bus4: sdmmc0-bus4 {
+ rockchip,pins =
+ /* sdmmc0_d0 */
+ <1 RK_PA4 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d1 */
+ <1 RK_PA5 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d2 */
+ <1 RK_PA6 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc0_d3 */
+ <1 RK_PA7 1 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ sdmmc0_clk: sdmmc0-clk {
+ rockchip,pins =
+ /* sdmmc0_clk */
+ <1 RK_PB0 1 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ sdmmc0_cmd: sdmmc0-cmd {
+ rockchip,pins =
+ /* sdmmc0_cmd */
+ <1 RK_PB1 1 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ sdmmc0_det: sdmmc0-det {
+ rockchip,pins =
+ <0 RK_PA3 1 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ sdmmc0_pwr: sdmmc0-pwr {
+ rockchip,pins =
+ <0 RK_PC0 1 &pcfg_pull_none>;
+ };
+ };
+ sdmmc1 {
+ /omit-if-no-ref/
+ sdmmc1_bus4: sdmmc1-bus4 {
+ rockchip,pins =
+ /* sdmmc1_d0 */
+ <1 RK_PB4 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d1 */
+ <1 RK_PB5 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d2 */
+ <1 RK_PB6 1 &pcfg_pull_up_drv_level_2>,
+ /* sdmmc1_d3 */
+ <1 RK_PB7 1 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ sdmmc1_clk: sdmmc1-clk {
+ rockchip,pins =
+ /* sdmmc1_clk */
+ <1 RK_PB2 1 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ sdmmc1_cmd: sdmmc1-cmd {
+ rockchip,pins =
+ /* sdmmc1_cmd */
+ <1 RK_PB3 1 &pcfg_pull_up_drv_level_2>;
+ };
+ /omit-if-no-ref/
+ sdmmc1_det: sdmmc1-det {
+ rockchip,pins =
+ <1 RK_PD0 2 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ sdmmc1_pwr: sdmmc1-pwr {
+ rockchip,pins =
+ <1 RK_PD1 2 &pcfg_pull_none>;
+ };
+ };
+ uart0 {
+ /omit-if-no-ref/
+ uart0_xfer: uart0-xfer {
+ rockchip,pins =
+ /* uart0_rx */
+ <1 RK_PC2 1 &pcfg_pull_up>,
+ /* uart0_tx */
+ <1 RK_PC3 1 &pcfg_pull_up>;
+ };
+ /omit-if-no-ref/
+ uart0_ctsn: uart0-ctsn {
+ rockchip,pins =
+ <1 RK_PC1 1 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart0_rtsn: uart0-rtsn {
+ rockchip,pins =
+ <1 RK_PC0 1 &pcfg_pull_none>;
+ };
+ /omit-if-no-ref/
+ uart0_rtsn_gpio: uart0-rts-pin {
+ rockchip,pins =
+ <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+ uart1 {
+ /omit-if-no-ref/
+ uart1m0_xfer: uart1m0-xfer {
+ rockchip,pins =
+ /* uart1_rx_m0 */
+ <0 RK_PB7 2 &pcfg_pull_up>,
+ /* uart1_tx_m0 */
+ <0 RK_PB6 2 &pcfg_pull_up>;
+ };
+ };
+ uart2 {
+ /omit-if-no-ref/
+ uart2m1_xfer: uart2m1-xfer {
+ rockchip,pins =
+ /* uart2_rx_m1 */
+ <3 RK_PA3 1 &pcfg_pull_up>,
+ /* uart2_tx_m1 */
+ <3 RK_PA2 1 &pcfg_pull_up>;
+ };
+ };
+ uart3 {
+ /omit-if-no-ref/
+ uart3m0_xfer: uart3m0-xfer {
+ rockchip,pins =
+ /* uart3_rx_m0 */
+ <3 RK_PC7 4 &pcfg_pull_up>,
+ /* uart3_tx_m0 */
+ <3 RK_PC6 4 &pcfg_pull_up>;
+ };
+ };
+ uart4 {
+ /omit-if-no-ref/
+ uart4m0_xfer: uart4m0-xfer {
+ rockchip,pins =
+ /* uart4_rx_m0 */
+ <3 RK_PA5 4 &pcfg_pull_up>,
+ /* uart4_tx_m0 */
+ <3 RK_PA4 4 &pcfg_pull_up>;
+ };
+ };
+ uart5 {
+ /omit-if-no-ref/
+ uart5m0_xfer: uart5m0-xfer {
+ rockchip,pins =
+ /* uart5_rx_m0 */
+ <3 RK_PA7 4 &pcfg_pull_up>,
+ /* uart5_tx_m0 */
+ <3 RK_PA6 4 &pcfg_pull_up>;
+ };
+ };
+};
diff --git a/arch/arm/dts/rv1126-u-boot.dtsi b/arch/arm/dts/rv1126-u-boot.dtsi
new file mode 100644
index 000000000000..bc77037760e4
--- /dev/null
+++ b/arch/arm/dts/rv1126-u-boot.dtsi
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include "rockchip-u-boot.dtsi"
+
+/ {
+ chosen {
+ u-boot,spl-boot-order = \
+ "same-as-spl", &emmc, &sdmmc;
+ };
+
+ dmc {
+ compatible = "rockchip,rv1126-dmc";
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&gpio0 {
+ u-boot,dm-spl;
+};
+
+&gpio1 {
+ u-boot,dm-spl;
+};
+
+&grf {
+ u-boot,dm-spl;
+};
+
+&pmu {
+ u-boot,dm-spl;
+};
+
+&pmugrf {
+ u-boot,dm-spl;
+};
+
+&xin24m {
+ u-boot,dm-spl;
+};
+
+&cru {
+ u-boot,dm-spl;
+};
+
+&pmucru {
+ u-boot,dm-spl;
+};
+
+&sdmmc {
+ u-boot,dm-spl;
+};
+
+&emmc {
+ u-boot,dm-spl;
+};
+
+&uart2 {
+ u-boot,dm-spl;
+};
diff --git a/arch/arm/dts/rv1126.dtsi b/arch/arm/dts/rv1126.dtsi
new file mode 100644
index 000000000000..1cb43147e90b
--- /dev/null
+++ b/arch/arm/dts/rv1126.dtsi
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd.
+ */
+
+#include <dt-bindings/clock/rockchip,rv1126-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/power/rockchip,rv1126-power.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ compatible = "rockchip,rv1126";
+
+ interrupt-parent = <&gic>;
+
+ aliases {
+ i2c0 = &i2c0;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu0: cpu@f00 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf00>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLK>;
+ };
+
+ cpu1: cpu@f01 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf01>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLK>;
+ };
+
+ cpu2: cpu@f02 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf02>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLK>;
+ };
+
+ cpu3: cpu@f03 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0xf03>;
+ enable-method = "psci";
+ clocks = <&cru ARMCLK>;
+ };
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <24000000>;
+ };
+
+ xin24m: oscillator {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xin24m";
+ #clock-cells = <0>;
+ };
+
+ grf: syscon@fe000000 {
+ compatible = "rockchip,rv1126-grf", "syscon", "simple-mfd";
+ reg = <0xfe000000 0x20000>;
+ };
+
+ pmugrf: syscon@fe020000 {
+ compatible = "rockchip,rv1126-pmugrf", "syscon", "simple-mfd";
+ reg = <0xfe020000 0x1000>;
+
+ pmu_io_domains: io-domains {
+ compatible = "rockchip,rv1126-pmu-io-voltage-domain";
+ status = "disabled";
+ };
+ };
+
+ qos_emmc: qos@fe860000 {
+ compatible = "rockchip,rv1126-qos", "syscon";
+ reg = <0xfe860000 0x20>;
+ };
+
+ qos_nandc: qos@fe860080 {
+ compatible = "rockchip,rv1126-qos", "syscon";
+ reg = <0xfe860080 0x20>;
+ };
+
+ qos_sfc: qos@fe860200 {
+ compatible = "rockchip,rv1126-qos", "syscon";
+ reg = <0xfe860200 0x20>;
+ };
+
+ qos_sdio: qos@fe86c000 {
+ compatible = "rockchip,rv1126-qos", "syscon";
+ reg = <0xfe86c000 0x20>;
+ };
+
+ gic: interrupt-controller@feff0000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+
+ reg = <0xfeff1000 0x1000>,
+ <0xfeff2000 0x2000>,
+ <0xfeff4000 0x2000>,
+ <0xfeff6000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ };
+
+ pmu: power-management@ff3e0000 {
+ compatible = "rockchip,rv1126-pmu", "syscon", "simple-mfd";
+ reg = <0xff3e0000 0x1000>;
+
+ power: power-controller {
+ compatible = "rockchip,rv1126-power-controller";
+ #power-domain-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-domain@RV1126_PD_NVM {
+ reg = <RV1126_PD_NVM>;
+ clocks = <&cru HCLK_EMMC>,
+ <&cru CLK_EMMC>,
+ <&cru HCLK_NANDC>,
+ <&cru CLK_NANDC>,
+ <&cru HCLK_SFC>,
+ <&cru HCLK_SFCXIP>,
+ <&cru SCLK_SFC>;
+ pm_qos = <&qos_emmc>,
+ <&qos_nandc>,
+ <&qos_sfc>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@RV1126_PD_SDIO {
+ reg = <RV1126_PD_SDIO>;
+ clocks = <&cru HCLK_SDIO>,
+ <&cru CLK_SDIO>;
+ pm_qos = <&qos_sdio>;
+ #power-domain-cells = <0>;
+ };
+ };
+ };
+
+ i2c0: i2c@ff3f0000 {
+ compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
+ reg = <0xff3f0000 0x1000>;
+ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+ rockchip,grf = <&pmugrf>;
+ clocks = <&pmucru CLK_I2C0>, <&pmucru PCLK_I2C0>;
+ clock-names = "i2c", "pclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ uart1: serial@ff410000 {
+ compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
+ reg = <0xff410000 0x100>;
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&pmucru SCLK_UART1>, <&pmucru PCLK_UART1>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac 7>, <&dmac 6>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ pmucru: clock-controller@ff480000 {
+ compatible = "rockchip,rv1126-pmucru";
+ reg = <0xff480000 0x1000>;
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ cru: clock-controller@ff490000 {
+ compatible = "rockchip,rv1126-cru";
+ reg = <0xff490000 0x1000>;
+ clocks = <&xin24m>;
+ clock-names = "xin24m";
+ rockchip,grf = <&grf>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ dmac: dma-controller@ff4e0000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xff4e0000 0x4000>;
+ interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+ #dma-cells = <1>;
+ arm,pl330-periph-burst;
+ clocks = <&cru ACLK_DMAC>;
+ clock-names = "apb_pclk";
+ };
+
+ uart0: serial@ff560000 {
+ compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
+ reg = <0xff560000 0x100>;
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac 5>, <&dmac 4>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart2: serial@ff570000 {
+ compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
+ reg = <0xff570000 0x100>;
+ interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac 9>, <&dmac 8>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2m1_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@ff580000 {
+ compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
+ reg = <0xff580000 0x100>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac 11>, <&dmac 10>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart4: serial@ff590000 {
+ compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
+ reg = <0xff590000 0x100>;
+ interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac 13>, <&dmac 12>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ uart5: serial@ff5a0000 {
+ compatible = "rockchip,rv1126-uart", "snps,dw-apb-uart";
+ reg = <0xff5a0000 0x100>;
+ interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <24000000>;
+ clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+ clock-names = "baudclk", "apb_pclk";
+ dmas = <&dmac 15>, <&dmac 14>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart5m0_xfer>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ status = "disabled";
+ };
+
+ saradc: adc@ff5e0000 {
+ compatible = "rockchip,rv1126-saradc", "rockchip,rk3399-saradc";
+ reg = <0xff5e0000 0x100>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+ #io-channel-cells = <1>;
+ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>;
+ clock-names = "saradc", "apb_pclk";
+ resets = <&cru SRST_SARADC_P>;
+ reset-names = "saradc-apb";
+ status = "disabled";
+ };
+
+ timer0: timer@ff660000 {
+ compatible = "rockchip,rv1126-timer", "rockchip,rk3288-timer";
+ reg = <0xff660000 0x20>;
+ interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_TIMER>, <&cru CLK_TIMER0>;
+ clock-names = "pclk", "timer";
+ };
+
+ emmc: mmc@ffc50000 {
+ compatible = "rockchip,rv1126-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0xffc50000 0x4000>;
+ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_EMMC>, <&cru CLK_EMMC>,
+ <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ power-domains = <&power RV1126_PD_NVM>;
+ status = "disabled";
+ };
+
+ sdmmc: mmc@ffc60000 {
+ compatible = "rockchip,rv1126-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0xffc60000 0x4000>;
+ interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDMMC>, <&cru CLK_SDMMC>,
+ <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ status = "disabled";
+ };
+
+ sdio: mmc@ffc70000 {
+ compatible = "rockchip,rv1126-dw-mshc", "rockchip,rk3288-dw-mshc";
+ reg = <0xffc70000 0x4000>;
+ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru HCLK_SDIO>, <&cru CLK_SDIO>,
+ <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+ clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+ fifo-depth = <0x100>;
+ max-frequency = <200000000>;
+ power-domains = <&power RV1126_PD_SDIO>;
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rv1126-pinctrl";
+ rockchip,grf = <&grf>;
+ rockchip,pmu = <&pmugrf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio@ff460000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff460000 0x100>;
+ interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&pmucru PCLK_GPIO0>, <&pmucru DBCLK_GPIO0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@ff620000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff620000 0x100>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@ff630000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff630000 0x100>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@ff640000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff640000 0x100>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@ff650000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0xff650000 0x100>;
+ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+};
+
+#include "rv1126-pinctrl.dtsi"
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1126.h b/arch/arm/include/asm/arch-rockchip/cru_rv1126.h
new file mode 100644
index 000000000000..49a1f763795b
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1126.h
@@ -0,0 +1,459 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 Rockchip Electronics Co. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef _ASM_ARCH_CRU_RV1126_H
+#define _ASM_ARCH_CRU_RV1126_H
+
+#define MHz 1000000
+#define KHz 1000
+#define OSC_HZ (24 * MHz)
+
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
+#define APLL_HZ (1008 * MHz)
+#else
+#define APLL_HZ (816 * MHz)
+#endif
+#define GPLL_HZ (1188 * MHz)
+#define CPLL_HZ (500 * MHz)
+#define HPLL_HZ (1400 * MHz)
+#define PCLK_PDPMU_HZ (100 * MHz)
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
+#define ACLK_PDBUS_HZ (396 * MHz)
+#else
+#define ACLK_PDBUS_HZ (500 * MHz)
+#endif
+#define HCLK_PDBUS_HZ (200 * MHz)
+#define PCLK_PDBUS_HZ (100 * MHz)
+#define ACLK_PDPHP_HZ (300 * MHz)
+#define HCLK_PDPHP_HZ (200 * MHz)
+#define HCLK_PDCORE_HZ (200 * MHz)
+#define HCLK_PDAUDIO_HZ (150 * MHz)
+#define CLK_OSC0_DIV_HZ (32768)
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
+#define ACLK_PDVI_HZ (297 * MHz)
+#define CLK_ISP_HZ (297 * MHz)
+#define ACLK_PDISPP_HZ (297 * MHz)
+#define CLK_ISPP_HZ (237 * MHz)
+#define ACLK_VOP_HZ (300 * MHz)
+#define DCLK_VOP_HZ (65 * MHz)
+#endif
+
+/* RV1126 pll id */
+enum rv1126_pll_id {
+ APLL,
+ DPLL,
+ CPLL,
+ HPLL,
+ GPLL,
+ PLL_COUNT,
+};
+
+struct rv1126_clk_info {
+ unsigned long id;
+ char *name;
+ bool is_cru;
+};
+
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rv1126_pmuclk_priv {
+ struct rv1126_pmucru *pmucru;
+ ulong gpll_hz;
+};
+
+struct rv1126_clk_priv {
+ struct rv1126_cru *cru;
+ struct rv1126_grf *grf;
+ ulong gpll_hz;
+ ulong cpll_hz;
+ ulong hpll_hz;
+ ulong armclk_hz;
+ ulong armclk_enter_hz;
+ ulong armclk_init_hz;
+ bool sync_kernel;
+ bool set_armclk_rate;
+};
+
+struct rv1126_pll {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ unsigned int con4;
+ unsigned int con5;
+ unsigned int con6;
+ unsigned int reserved0[1];
+};
+
+struct rv1126_pmucru {
+ unsigned int pmu_mode;
+ unsigned int reserved1[3];
+ struct rv1126_pll pll;
+ unsigned int offsetcal_status;
+ unsigned int reserved2[51];
+ unsigned int pmu_clksel_con[14];
+ unsigned int reserved3[18];
+ unsigned int pmu_clkgate_con[3];
+ unsigned int reserved4[29];
+ unsigned int pmu_softrst_con[2];
+ unsigned int reserved5[14];
+ unsigned int pmu_autocs_con[2];
+};
+
+check_member(rv1126_pmucru, pmu_autocs_con[1], 0x244);
+
+struct rv1126_cru {
+ struct rv1126_pll pll[4];
+ unsigned int offsetcal_status[4];
+ unsigned int mode;
+ unsigned int reserved1[27];
+ unsigned int clksel_con[78];
+ unsigned int reserved2[18];
+ unsigned int clkgate_con[25];
+ unsigned int reserved3[7];
+ unsigned int softrst_con[15];
+ unsigned int reserved4[17];
+ unsigned int ssgtbl[32];
+ unsigned int glb_cnt_th;
+ unsigned int glb_rst_st;
+ unsigned int glb_srst_fst;
+ unsigned int glb_srst_snd;
+ unsigned int glb_rst_con;
+ unsigned int reserved5[11];
+ unsigned int sdmmc_con[2];
+ unsigned int sdio_con[2];
+ unsigned int emmc_con[2];
+ unsigned int reserved6[2];
+ unsigned int gmac_con;
+ unsigned int misc[2];
+ unsigned int reserved7[45];
+ unsigned int autocs_con[26];
+};
+
+check_member(rv1126_cru, autocs_con[25], 0x584);
+
+struct pll_rate_table {
+ unsigned long rate;
+ unsigned int fbdiv;
+ unsigned int postdiv1;
+ unsigned int refdiv;
+ unsigned int postdiv2;
+ unsigned int dsmpd;
+ unsigned int frac;
+};
+
+struct cpu_rate_table {
+ unsigned long rate;
+ unsigned int aclk_div;
+ unsigned int pclk_div;
+};
+
+#define RV1126_PMU_MODE 0x0
+#define RV1126_PMU_PLL_CON(x) ((x) * 0x4 + 0x10)
+#define RV1126_PLL_CON(x) ((x) * 0x4)
+#define RV1126_MODE_CON 0x90
+
+enum {
+ /* CRU_PMU_CLK_SEL0_CON */
+ RTC32K_SEL_SHIFT = 7,
+ RTC32K_SEL_MASK = 0x3 << RTC32K_SEL_SHIFT,
+ RTC32K_SEL_PMUPVTM = 0,
+ RTC32K_SEL_OSC1_32K,
+ RTC32K_SEL_OSC0_DIV32K,
+
+ /* CRU_PMU_CLK_SEL1_CON */
+ PCLK_PDPMU_DIV_SHIFT = 0,
+ PCLK_PDPMU_DIV_MASK = 0x1f,
+
+ /* CRU_PMU_CLK_SEL2_CON */
+ CLK_I2C0_DIV_SHIFT = 0,
+ CLK_I2C0_DIV_MASK = 0x7f,
+
+ /* CRU_PMU_CLK_SEL3_CON */
+ CLK_I2C2_DIV_SHIFT = 0,
+ CLK_I2C2_DIV_MASK = 0x7f,
+
+ /* CRU_PMU_CLK_SEL6_CON */
+ CLK_PWM1_SEL_SHIFT = 15,
+ CLK_PWM1_SEL_MASK = 1 << CLK_PWM1_SEL_SHIFT,
+ CLK_PWM1_SEL_XIN24M = 0,
+ CLK_PWM1_SEL_GPLL,
+ CLK_PWM1_DIV_SHIFT = 8,
+ CLK_PWM1_DIV_MASK = 0x7f << CLK_PWM1_DIV_SHIFT,
+ CLK_PWM0_SEL_SHIFT = 7,
+ CLK_PWM0_SEL_MASK = 1 << CLK_PWM0_SEL_SHIFT,
+ CLK_PWM0_SEL_XIN24M = 0,
+ CLK_PWM0_SEL_GPLL,
+ CLK_PWM0_DIV_SHIFT = 0,
+ CLK_PWM0_DIV_MASK = 0x7f,
+
+ /* CRU_PMU_CLK_SEL9_CON */
+ CLK_SPI0_SEL_SHIFT = 7,
+ CLK_SPI0_SEL_MASK = 1 << CLK_SPI0_SEL_SHIFT,
+ CLK_SPI0_SEL_GPLL = 0,
+ CLK_SPI0_SEL_XIN24M,
+ CLK_SPI0_DIV_SHIFT = 0,
+ CLK_SPI0_DIV_MASK = 0x7f,
+
+ /* CRU_PMU_CLK_SEL13_CON */
+ CLK_RTC32K_FRAC_NUMERATOR_SHIFT = 16,
+ CLK_RTC32K_FRAC_NUMERATOR_MASK = 0xffff << 16,
+ CLK_RTC32K_FRAC_DENOMINATOR_SHIFT = 0,
+ CLK_RTC32K_FRAC_DENOMINATOR_MASK = 0xffff,
+
+ /* CRU_CLK_SEL0_CON */
+ CORE_HCLK_DIV_SHIFT = 8,
+ CORE_HCLK_DIV_MASK = 0x1f << CORE_HCLK_DIV_SHIFT,
+
+ /* CRU_CLK_SEL1_CON */
+ CORE_ACLK_DIV_SHIFT = 4,
+ CORE_ACLK_DIV_MASK = 0xf << CORE_ACLK_DIV_SHIFT,
+ CORE_DBG_DIV_SHIFT = 0,
+ CORE_DBG_DIV_MASK = 0x7,
+
+ /* CRU_CLK_SEL2_CON */
+ HCLK_PDBUS_SEL_SHIFT = 15,
+ HCLK_PDBUS_SEL_MASK = 1 << HCLK_PDBUS_SEL_SHIFT,
+ HCLK_PDBUS_SEL_GPLL = 0,
+ HCLK_PDBUS_SEL_CPLL,
+ HCLK_PDBUS_DIV_SHIFT = 8,
+ HCLK_PDBUS_DIV_MASK = 0x1f << HCLK_PDBUS_DIV_SHIFT,
+ ACLK_PDBUS_SEL_SHIFT = 6,
+ ACLK_PDBUS_SEL_MASK = 0x3 << ACLK_PDBUS_SEL_SHIFT,
+ ACLK_PDBUS_SEL_GPLL = 0,
+ ACLK_PDBUS_SEL_CPLL,
+ ACLK_PDBUS_SEL_DPLL,
+ ACLK_PDBUS_DIV_SHIFT = 0,
+ ACLK_PDBUS_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL3_CON */
+ CLK_SCR1_SEL_SHIFT = 15,
+ CLK_SCR1_SEL_MASK = 1 << CLK_SCR1_SEL_SHIFT,
+ CLK_SCR1_SEL_GPLL = 0,
+ CLK_SCR1_SEL_CPLL,
+ CLK_SCR1_DIV_SHIFT = 8,
+ CLK_SCR1_DIV_MASK = 0x1f << CLK_SCR1_DIV_SHIFT,
+ PCLK_PDBUS_SEL_SHIFT = 7,
+ PCLK_PDBUS_SEL_MASK = 1 << PCLK_PDBUS_SEL_SHIFT,
+ PCLK_PDBUS_SEL_GPLL = 0,
+ PCLK_PDBUS_SEL_CPLL,
+ PCLK_PDBUS_DIV_SHIFT = 0,
+ PCLK_PDBUS_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL4_CON */
+ ACLK_CRYPTO_SEL_SHIFT = 7,
+ ACLK_CRYPTO_SEL_MASK = 1 << ACLK_CRYPTO_SEL_SHIFT,
+ ACLK_CRYPTO_SEL_GPLL = 0,
+ ACLK_CRYPTO_SEL_CPLL,
+ ACLK_CRYPTO_DIV_SHIFT = 0,
+ ACLK_CRYPTO_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL5_CON */
+ CLK_I2C3_DIV_SHIFT = 8,
+ CLK_I2C3_DIV_MASK = 0x7f << CLK_I2C3_DIV_SHIFT,
+ CLK_I2C1_DIV_SHIFT = 0,
+ CLK_I2C1_DIV_MASK = 0x7f,
+
+ /* CRU_CLK_SEL6_CON */
+ CLK_I2C5_DIV_SHIFT = 8,
+ CLK_I2C5_DIV_MASK = 0x7f << CLK_I2C5_DIV_SHIFT,
+ CLK_I2C4_DIV_SHIFT = 0,
+ CLK_I2C4_DIV_MASK = 0x7f,
+
+ /* CRU_CLK_SEL7_CON */
+ CLK_CRYPTO_PKA_SEL_SHIFT = 15,
+ CLK_CRYPTO_PKA_SEL_MASK = 1 << CLK_CRYPTO_PKA_SEL_SHIFT,
+ CLK_CRYPTO_PKA_SEL_GPLL = 0,
+ CLK_CRYPTO_PKA_SEL_CPLL,
+ CLK_CRYPTO_PKA_DIV_SHIFT = 8,
+ CLK_CRYPTO_PKA_DIV_MASK = 0x1f << CLK_CRYPTO_PKA_DIV_SHIFT,
+ CLK_CRYPTO_CORE_SEL_SHIFT = 7,
+ CLK_CRYPTO_CORE_SEL_MASK = 1 << CLK_CRYPTO_CORE_SEL_SHIFT,
+ CLK_CRYPTO_CORE_SEL_GPLL = 0,
+ CLK_CRYPTO_CORE_SEL_CPLL,
+ CLK_CRYPTO_CORE_DIV_SHIFT = 0,
+ CLK_CRYPTO_CORE_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL8_CON */
+ CLK_SPI1_SEL_SHIFT = 8,
+ CLK_SPI1_SEL_MASK = 1 << CLK_SPI1_SEL_SHIFT,
+ CLK_SPI1_SEL_GPLL = 0,
+ CLK_SPI1_SEL_XIN24M,
+ CLK_SPI1_DIV_SHIFT = 0,
+ CLK_SPI1_DIV_MASK = 0x7f,
+
+ /* CRU_CLK_SEL9_CON */
+ CLK_PWM2_SEL_SHIFT = 15,
+ CLK_PWM2_SEL_MASK = 1 << CLK_PWM2_SEL_SHIFT,
+ CLK_PWM2_SEL_XIN24M = 0,
+ CLK_PWM2_SEL_GPLL,
+ CLK_PWM2_DIV_SHIFT = 8,
+ CLK_PWM2_DIV_MASK = 0x7f << CLK_PWM2_DIV_SHIFT,
+
+ /* CRU_CLK_SEL20_CON */
+ CLK_SARADC_DIV_SHIFT = 0,
+ CLK_SARADC_DIV_MASK = 0x7ff,
+
+ /* CRU_CLK_SEL25_CON */
+ DCLK_DECOM_SEL_SHIFT = 15,
+ DCLK_DECOM_SEL_MASK = 1 << DCLK_DECOM_SEL_SHIFT,
+ DCLK_DECOM_SEL_GPLL = 0,
+ DCLK_DECOM_SEL_CPLL,
+ DCLK_DECOM_DIV_SHIFT = 8,
+ DCLK_DECOM_DIV_MASK = 0x7f << DCLK_DECOM_DIV_SHIFT,
+
+ /* CRU_CLK_SEL26_CON */
+ HCLK_PDAUDIO_DIV_SHIFT = 0,
+ HCLK_PDAUDIO_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL45_CON */
+ ACLK_PDVO_SEL_SHIFT = 7,
+ ACLK_PDVO_SEL_MASK = 1 << ACLK_PDVO_SEL_SHIFT,
+ ACLK_PDVO_SEL_GPLL = 0,
+ ACLK_PDVO_SEL_CPLL,
+ ACLK_PDVO_DIV_SHIFT = 0,
+ ACLK_PDVO_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL47_CON */
+ DCLK_VOP_SEL_SHIFT = 8,
+ DCLK_VOP_SEL_MASK = 1 << DCLK_VOP_SEL_SHIFT,
+ DCLK_VOP_SEL_GPLL = 0,
+ DCLK_VOP_SEL_CPLL,
+ DCLK_VOP_DIV_SHIFT = 0,
+ DCLK_VOP_DIV_MASK = 0xff,
+
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
+ /* CRU_CLK_SEL49_CON */
+ ACLK_PDVI_SEL_SHIFT = 6,
+ ACLK_PDVI_SEL_MASK = 0x3 << ACLK_PDVI_SEL_SHIFT,
+ ACLK_PDVI_SEL_CPLL = 0,
+ ACLK_PDVI_SEL_GPLL,
+ ACLK_PDVI_SEL_HPLL,
+ ACLK_PDVI_DIV_SHIFT = 0,
+ ACLK_PDVI_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL50_CON */
+ CLK_ISP_SEL_SHIFT = 6,
+ CLK_ISP_SEL_MASK = 0x3 << CLK_ISP_SEL_SHIFT,
+ CLK_ISP_SEL_GPLL = 0,
+ CLK_ISP_SEL_CPLL,
+ CLK_ISP_SEL_HPLL,
+ CLK_ISP_DIV_SHIFT = 0,
+ CLK_ISP_DIV_MASK = 0x1f,
+#endif
+
+ /* CRU_CLK_SEL53_CON */
+ HCLK_PDPHP_DIV_SHIFT = 8,
+ HCLK_PDPHP_DIV_MASK = 0x1f << HCLK_PDPHP_DIV_SHIFT,
+ ACLK_PDPHP_SEL_SHIFT = 7,
+ ACLK_PDPHP_SEL_MASK = 1 << ACLK_PDPHP_SEL_SHIFT,
+ ACLK_PDPHP_SEL_GPLL = 0,
+ ACLK_PDPHP_SEL_CPLL,
+ ACLK_PDPHP_DIV_SHIFT = 0,
+ ACLK_PDPHP_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL57_CON */
+ EMMC_SEL_SHIFT = 14,
+ EMMC_SEL_MASK = 0x3 << EMMC_SEL_SHIFT,
+ EMMC_SEL_GPLL = 0,
+ EMMC_SEL_CPLL,
+ EMMC_SEL_XIN24M,
+ EMMC_DIV_SHIFT = 0,
+ EMMC_DIV_MASK = 0xff,
+
+ /* CRU_CLK_SEL58_CON */
+ SCLK_SFC_SEL_SHIFT = 15,
+ SCLK_SFC_SEL_MASK = 0x1 << SCLK_SFC_SEL_SHIFT,
+ SCLK_SFC_SEL_CPLL = 0,
+ SCLK_SFC_SEL_GPLL,
+ SCLK_SFC_DIV_SHIFT = 0,
+ SCLK_SFC_DIV_MASK = 0xff,
+
+ /* CRU_CLK_SEL59_CON */
+ CLK_NANDC_SEL_SHIFT = 15,
+ CLK_NANDC_SEL_MASK = 0x1 << CLK_NANDC_SEL_SHIFT,
+ CLK_NANDC_SEL_GPLL = 0,
+ CLK_NANDC_SEL_CPLL,
+ CLK_NANDC_DIV_SHIFT = 0,
+ CLK_NANDC_DIV_MASK = 0xff,
+
+ /* CRU_CLK_SEL61_CON */
+ CLK_GMAC_OUT_SEL_SHIFT = 15,
+ CLK_GMAC_OUT_SEL_MASK = 0x1 << CLK_GMAC_OUT_SEL_SHIFT,
+ CLK_GMAC_OUT_SEL_CPLL = 0,
+ CLK_GMAC_OUT_SEL_GPLL,
+ CLK_GMAC_OUT_DIV_SHIFT = 8,
+ CLK_GMAC_OUT_DIV_MASK = 0x1f << CLK_GMAC_OUT_DIV_SHIFT,
+
+ /* CRU_CLK_SEL63_CON */
+ PCLK_GMAC_DIV_SHIFT = 8,
+ PCLK_GMAC_DIV_MASK = 0x1f << PCLK_GMAC_DIV_SHIFT,
+ CLK_GMAC_SRC_SEL_SHIFT = 7,
+ CLK_GMAC_SRC_SEL_MASK = 0x1 << CLK_GMAC_SRC_SEL_SHIFT,
+ CLK_GMAC_SRC_SEL_CPLL = 0,
+ CLK_GMAC_SRC_SEL_GPLL,
+ CLK_GMAC_SRC_DIV_SHIFT = 0,
+ CLK_GMAC_SRC_DIV_MASK = 0x1f << CLK_GMAC_SRC_DIV_SHIFT,
+
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_KERNEL_BOOT)
+ /* CRU_CLK_SEL68_CON */
+ ACLK_PDISPP_SEL_SHIFT = 6,
+ ACLK_PDISPP_SEL_MASK = 0x3 << ACLK_PDISPP_SEL_SHIFT,
+ ACLK_PDISPP_SEL_CPLL = 0,
+ ACLK_PDISPP_SEL_GPLL,
+ ACLK_PDISPP_SEL_HPLL,
+ ACLK_PDISPP_DIV_SHIFT = 0,
+ ACLK_PDISPP_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL69_CON */
+ CLK_ISPP_SEL_SHIFT = 6,
+ CLK_ISPP_SEL_MASK = 0x3 << CLK_ISPP_SEL_SHIFT,
+ CLK_ISPP_SEL_CPLL = 0,
+ CLK_ISPP_SEL_GPLL,
+ CLK_ISPP_SEL_HPLL,
+ CLK_ISPP_DIV_SHIFT = 0,
+ CLK_ISPP_DIV_MASK = 0x1f,
+
+ /* CRU_CLK_SEL73_CON */
+ MIPICSI_OUT_SEL_SHIFT = 10,
+ MIPICSI_OUT_SEL_MASK = 0x3 << MIPICSI_OUT_SEL_SHIFT,
+ MIPICSI_OUT_SEL_XIN24M = 0,
+ MIPICSI_OUT_SEL_DIV,
+ MIPICSI_OUT_SEL_FRACDIV,
+ MIPICSI_OUT_DIV_SHIFT = 0,
+ MIPICSI_OUT_DIV_MASK = 0x1f,
+#endif
+
+ /* CRU_GMAC_CON */
+ GMAC_SRC_M1_SEL_SHIFT = 5,
+ GMAC_SRC_M1_SEL_MASK = 0x1 << GMAC_SRC_M1_SEL_SHIFT,
+ GMAC_SRC_M1_SEL_INT = 0,
+ GMAC_SRC_M1_SEL_EXT,
+ GMAC_MODE_SEL_SHIFT = 4,
+ GMAC_MODE_SEL_MASK = 0x1 << GMAC_MODE_SEL_SHIFT,
+ GMAC_RGMII_MODE = 0,
+ GMAC_RMII_MODE,
+ RGMII_CLK_SEL_SHIFT = 2,
+ RGMII_CLK_SEL_MASK = 0x3 << RGMII_CLK_SEL_SHIFT,
+ RGMII_CLK_DIV0 = 0,
+ RGMII_CLK_DIV1,
+ RGMII_CLK_DIV50,
+ RGMII_CLK_DIV5,
+ RMII_CLK_SEL_SHIFT = 1,
+ RMII_CLK_SEL_MASK = 0x1 << RMII_CLK_SEL_SHIFT,
+ RMII_CLK_DIV20 = 0,
+ RMII_CLK_DIV2,
+ GMAC_SRC_M0_SEL_SHIFT = 0,
+ GMAC_SRC_M0_SEL_MASK = 0x1,
+ GMAC_SRC_M0_SEL_INT = 0,
+ GMAC_SRC_M0_SEL_EXT,
+
+ /* GRF_IOFUNC_CON1 */
+ GMAC_SRC_SEL_SHIFT = 12,
+ GMAC_SRC_SEL_MASK = 1 << GMAC_SRC_SEL_SHIFT,
+ GMAC_SRC_SEL_M0 = 0,
+ GMAC_SRC_SEL_M1,
+};
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/dram_spec_timing.h b/arch/arm/include/asm/arch-rockchip/dram_spec_timing.h
new file mode 100644
index 000000000000..a691e97a8b27
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/dram_spec_timing.h
@@ -0,0 +1,452 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ROCKCHIP_DRAM_SPEC_TIMING_H__
+#define __ROCKCHIP_DRAM_SPEC_TIMING_H__
+
+enum ddr3_speed_rate {
+ /* 5-5-5 */
+ DDR3_800D = 0,
+ /* 6-6-6 */
+ DDR3_800E = 1,
+ /* 6-6-6 */
+ DDR3_1066E = 2,
+ /* 7-7-7 */
+ DDR3_1066F = 3,
+ /* 8-8-8 */
+ DDR3_1066G = 4,
+ /* 7-7-7 */
+ DDR3_1333F = 5,
+ /* 8-8-8 */
+ DDR3_1333G = 6,
+ /* 9-9-9 */
+ DDR3_1333H = 7,
+ /* 10-10-10 */
+ DDR3_1333J = 8,
+ /* 8-8-8 */
+ DDR3_1600G = 9,
+ /* 9-9-9 */
+ DDR3_1600H = 10,
+ /* 10-10-10 */
+ DDR3_1600J = 11,
+ /* 11-11-11 */
+ DDR3_1600K = 12,
+ /* 10-10-10 */
+ DDR3_1866J = 13,
+ /* 11-11-11 */
+ DDR3_1866K = 14,
+ /* 12-12-12 */
+ DDR3_1866L = 15,
+ /* 13-13-13 */
+ DDR3_1866M = 16,
+ /* 11-11-11 */
+ DDR3_2133K = 17,
+ /* 12-12-12 */
+ DDR3_2133L = 18,
+ /* 13-13-13 */
+ DDR3_2133M = 19,
+ /* 14-14-14 */
+ DDR3_2133N = 20,
+ DDR3_DEFAULT = 21,
+};
+
+enum ddr4_speed_rate {
+ /* DDR4_1600J (10-10-10) */
+ DDR4_1600J = 0,
+ /* DDR4_1600K (11-11-11) */
+ DDR4_1600K = 1,
+ /* DDR4_1600L (12-12-12) */
+ DDR4_1600L = 2,
+ /* DDR4_1800L (12-12-12) */
+ DDR4_1866L = 3,
+ /* DDR4_1800M (13-13-13) */
+ DDR4_1866M = 4,
+ /* DDR4_1800N (14-14-14) */
+ DDR4_1866N = 5,
+ /* DDR4_2133N (14-14-14) */
+ DDR4_2133N = 6,
+ /* DDR4_2133P (15-15-15) */
+ DDR4_2133P = 7,
+ /* DDR4_2133R (16-16-16) */
+ DDR4_2133R = 8,
+ /* DDR4_2400P (15-15-15) */
+ DDR4_2400P = 9,
+ /* DDR4_2400R (16-16-16) */
+ DDR4_2400R = 10,
+ /* DDR4_2400U (18-18-18) */
+ DDR4_2400U = 11,
+ /* DEFAULT */
+ DDR4_DEFAULT = 12,
+};
+
+/* mr0 for ddr3 */
+#define DDR3_BL8 (0)
+#define DDR3_BC4_8 (1)
+#define DDR3_BC4 (2)
+#define DDR3_CL(n) (((((n) - 4) & 0x7) << 4)\
+ | ((((n) - 4) & 0x8) >> 1))
+#define DDR3_WR(n) (((n) & 0x7) << 9)
+#define DDR3_DLL_RESET (1 << 8)
+#define DDR3_DLL_DERESET (0 << 8)
+
+/* mr1 for ddr3 */
+#define DDR3_DLL_ENABLE (0)
+#define DDR3_DLL_DISABLE (1)
+#define DDR3_MR1_AL(n) (((n) & 0x3) << 3)
+
+#define DDR3_DS_40 (0)
+#define DDR3_DS_34 BIT(1)
+#define DDR3_DS_MASK ((1 << 1) | (1 << 5))
+#define DDR3_RTT_NOM_MASK ((1 << 2) | (1 << 6) | (1 << 9))
+#define DDR3_RTT_NOM_DIS (0)
+#define DDR3_RTT_NOM_60 BIT(2)
+#define DDR3_RTT_NOM_120 BIT(6)
+#define DDR3_RTT_NOM_40 ((1 << 2) | (1 << 6))
+#define DDR3_TDQS BIT(11)
+
+/* mr2 for ddr3 */
+#define DDR3_MR2_CWL(n) ((((n) - 5) & 0x7) << 3)
+#define DDR3_RTT_WR_DIS (0)
+#define DDR3_RTT_WR_60 (1 << 9)
+#define DDR3_RTT_WR_120 (2 << 9)
+
+/*
+ * MR0 (Device Information)
+ * 0:DAI complete, 1:DAI still in progress
+ */
+#define LPDDR2_DAI (0x1)
+/* 0:S2 or S4 SDRAM, 1:NVM */
+#define LPDDR2_DI (0x1 << 1)
+/* 0:DNV not supported, 1:DNV supported */
+#define LPDDR2_DNVI (0x1 << 2)
+#define LPDDR2_RZQI (0x3 << 3)
+
+/*
+ * 00:RZQ self test not supported,
+ * 01:ZQ-pin may connect to VDDCA or float
+ * 10:ZQ-pin may short to GND.
+ * 11:ZQ-pin self test completed, no error condition detected.
+ */
+
+/* MR1 (Device Feature) */
+#define LPDDR2_BL4 (0x2)
+#define LPDDR2_BL8 (0x3)
+#define LPDDR2_BL16 (0x4)
+#define LPDDR2_N_WR(n) (((n) - 2) << 5)
+
+/* MR2 (Device Feature 2) */
+#define LPDDR2_RL3_WL1 (0x1)
+#define LPDDR2_RL4_WL2 (0x2)
+#define LPDDR2_RL5_WL2 (0x3)
+#define LPDDR2_RL6_WL3 (0x4)
+#define LPDDR2_RL7_WL4 (0x5)
+#define LPDDR2_RL8_WL4 (0x6)
+
+/* MR3 (IO Configuration 1) */
+#define LPDDR2_DS_34 (0x1)
+#define LPDDR2_DS_40 (0x2)
+#define LPDDR2_DS_48 (0x3)
+#define LPDDR2_DS_60 (0x4)
+#define LPDDR2_DS_80 (0x6)
+/* optional */
+#define LPDDR2_DS_120 (0x7)
+
+/* MR4 (Device Temperature) */
+#define LPDDR2_TREF_MASK (0x7)
+#define LPDDR2_4_TREF (0x1)
+#define LPDDR2_2_TREF (0x2)
+#define LPDDR2_1_TREF (0x3)
+#define LPDDR2_025_TREF (0x5)
+#define LPDDR2_025_TREF_DERATE (0x6)
+
+#define LPDDR2_TUF (0x1 << 7)
+
+/* MR8 (Basic configuration 4) */
+#define LPDDR2_S4 (0x0)
+#define LPDDR2_S2 (0x1)
+#define LPDDR2_N (0x2)
+/* Unit:MB */
+#define LPDDR2_DENSITY(mr8) (8 << (((mr8) >> 2) & 0xf))
+#define LPDDR2_IO_WIDTH(mr8) (32 >> (((mr8) >> 6) & 0x3))
+
+/* MR10 (Calibration) */
+#define LPDDR2_ZQINIT (0xff)
+#define LPDDR2_ZQCL (0xab)
+#define LPDDR2_ZQCS (0x56)
+#define LPDDR2_ZQRESET (0xc3)
+
+/* MR16 (PASR Bank Mask), S2 SDRAM Only */
+#define LPDDR2_PASR_FULL (0x0)
+#define LPDDR2_PASR_1_2 (0x1)
+#define LPDDR2_PASR_1_4 (0x2)
+#define LPDDR2_PASR_1_8 (0x3)
+
+/*
+ * MR0 (Device Information)
+ * 0:DAI complete,
+ * 1:DAI still in progress
+ */
+#define LPDDR3_DAI (0x1)
+/*
+ * 00:RZQ self test not supported,
+ * 01:ZQ-pin may connect to VDDCA or float
+ * 10:ZQ-pin may short to GND.
+ * 11:ZQ-pin self test completed, no error condition detected.
+ */
+#define LPDDR3_RZQI (0x3 << 3)
+/*
+ * 0:DRAM does not support WL(Set B),
+ * 1:DRAM support WL(Set B)
+ */
+#define LPDDR3_WL_SUPOT BIT(6)
+/*
+ * 0:DRAM does not support RL=3,nWR=3,WL=1;
+ * 1:DRAM supports RL=3,nWR=3,WL=1 for frequencies <=166
+ */
+#define LPDDR3_RL3_SUPOT BIT(7)
+
+/* MR1 (Device Feature) */
+#define LPDDR3_BL8 (0x3)
+#define LPDDR3_N_WR(n) ((n) << 5)
+
+/* MR2 (Device Feature 2), WL Set A,default */
+/* <=166MHz,optional*/
+#define LPDDR3_RL3_WL1 (0x1)
+/* <=400MHz*/
+#define LPDDR3_RL6_WL3 (0x4)
+/* <=533MHz*/
+#define LPDDR3_RL8_WL4 (0x6)
+/* <=600MHz*/
+#define LPDDR3_RL9_WL5 (0x7)
+/* <=667MHz,default*/
+#define LPDDR3_RL10_WL6 (0x8)
+/* <=733MHz*/
+#define LPDDR3_RL11_WL6 (0x9)
+/* <=800MHz*/
+#define LPDDR3_RL12_WL6 (0xa)
+/* <=933MHz*/
+#define LPDDR3_RL14_WL8 (0xc)
+/* <=1066MHz*/
+#define LPDDR3_RL16_WL8 (0xe)
+
+/* WL Set B, optional */
+/* <=667MHz,default*/
+#define LPDDR3_RL10_WL8 (0x8)
+/* <=733MHz*/
+#define LPDDR3_RL11_WL9 (0x9)
+/* <=800MHz*/
+#define LPDDR3_RL12_WL9 (0xa)
+/* <=933MHz*/
+#define LPDDR3_RL14_WL11 (0xc)
+/* <=1066MHz*/
+#define LPDDR3_RL16_WL13 (0xe)
+
+/* 1:enable nWR programming > 9(default)*/
+#define LPDDR3_N_WRE BIT(4)
+/* 1:Select WL Set B*/
+#define LPDDR3_WL_S BIT(6)
+/* 1:enable*/
+#define LPDDR3_WR_LEVEL BIT(7)
+
+/* MR3 (IO Configuration 1) */
+#define LPDDR3_DS_34 (0x1)
+#define LPDDR3_DS_40 (0x2)
+#define LPDDR3_DS_48 (0x3)
+#define LPDDR3_DS_60 (0x4)
+#define LPDDR3_DS_80 (0x6)
+#define LPDDR3_DS_34D_40U (0x9)
+#define LPDDR3_DS_40D_48U (0xa)
+#define LPDDR3_DS_34D_48U (0xb)
+
+/* MR4 (Device Temperature) */
+#define LPDDR3_TREF_MASK (0x7)
+/* SDRAM Low temperature operating limit exceeded */
+#define LPDDR3_LT_EXED (0x0)
+#define LPDDR3_4_TREF (0x1)
+#define LPDDR3_2_TREF (0x2)
+#define LPDDR3_1_TREF (0x3)
+#define LPDDR3_05_TREF (0x4)
+#define LPDDR3_025_TREF (0x5)
+#define LPDDR3_025_TREF_DERATE (0x6)
+/* SDRAM High temperature operating limit exceeded */
+#define LPDDR3_HT_EXED (0x7)
+
+/* 1:value has changed since last read of MR4 */
+#define LPDDR3_TUF (0x1 << 7)
+
+/* MR8 (Basic configuration 4) */
+#define LPDDR3_S8 (0x3)
+#define LPDDR3_DENSITY(mr8) (8 << (((mr8) >> 2) & 0xf))
+#define LPDDR3_IO_WIDTH(mr8) (32 >> (((mr8) >> 6) & 0x3))
+
+/* MR10 (Calibration) */
+#define LPDDR3_ZQINIT (0xff)
+#define LPDDR3_ZQCL (0xab)
+#define LPDDR3_ZQCS (0x56)
+#define LPDDR3_ZQRESET (0xc3)
+
+/* MR11 (ODT Control) */
+#define LPDDR3_ODT_60 (1)
+#define LPDDR3_ODT_120 (2)
+#define LPDDR3_ODT_240 (3)
+#define LPDDR3_ODT_DIS (0)
+
+/* MR2 (Device Feature 2) */
+/* RL & nRTP for DBI-RD Disabled */
+#define LPDDR4_RL6_NRTP8 (0x0)
+#define LPDDR4_RL10_NRTP8 (0x1)
+#define LPDDR4_RL14_NRTP8 (0x2)
+#define LPDDR4_RL20_NRTP8 (0x3)
+#define LPDDR4_RL24_NRTP10 (0x4)
+#define LPDDR4_RL28_NRTP12 (0x5)
+#define LPDDR4_RL32_NRTP14 (0x6)
+#define LPDDR4_RL36_NRTP16 (0x7)
+/* RL & nRTP for DBI-RD Disabled */
+#define LPDDR4_RL12_NRTP8 (0x1)
+#define LPDDR4_RL16_NRTP8 (0x2)
+#define LPDDR4_RL22_NRTP8 (0x3)
+#define LPDDR4_RL28_NRTP10 (0x4)
+#define LPDDR4_RL32_NRTP12 (0x5)
+#define LPDDR4_RL36_NRTP14 (0x6)
+#define LPDDR4_RL40_NRTP16 (0x7)
+/* WL Set A,default */
+#define LPDDR4_A_WL4 (0x0 << 3)
+#define LPDDR4_A_WL6 (0x1 << 3)
+#define LPDDR4_A_WL8 (0x2 << 3)
+#define LPDDR4_A_WL10 (0x3 << 3)
+#define LPDDR4_A_WL12 (0x4 << 3)
+#define LPDDR4_A_WL14 (0x5 << 3)
+#define LPDDR4_A_WL16 (0x6 << 3)
+#define LPDDR4_A_WL18 (0x7 << 3)
+/* WL Set B, optional */
+#define LPDDR4_B_WL4 (0x0 << 3)
+#define LPDDR4_B_WL8 (0x1 << 3)
+#define LPDDR4_B_WL12 (0x2 << 3)
+#define LPDDR4_B_WL18 (0x3 << 3)
+#define LPDDR4_B_WL22 (0x4 << 3)
+#define LPDDR4_B_WL26 (0x5 << 3)
+#define LPDDR4_B_WL30 (0x6 << 3)
+#define LPDDR4_B_WL34 (0x7 << 3)
+/* 1:Select WL Set B*/
+#define LPDDR4_WL_B BIT(6)
+/* 1:enable*/
+#define LPDDR4_WR_LEVEL BIT(7)
+
+/* MR3 */
+#define LPDDR4_VDDQ_2_5 (0)
+#define LPDDR4_VDDQ_3 (1)
+#define LPDDR4_PU_CAL_MASK (1)
+#define LPDDR4_WRPST_0_5_TCK (0 << 1)
+#define LPDDR4_WRPST_1_5_TCK (1 << 1)
+#define LPDDR4_PPR_EN (1 << 2)
+/* PDDS */
+#define LPDDR4_PDDS_MASK (0x7 << 3)
+#define LPDDR4_PDDS_SHIFT (3)
+#define LPDDR4_PDDS_240 (0x1 << 3)
+#define LPDDR4_PDDS_120 (0x2 << 3)
+#define LPDDR4_PDDS_80 (0x3 << 3)
+#define LPDDR4_PDDS_60 (0x4 << 3)
+#define LPDDR4_PDDS_48 (0x5 << 3)
+#define LPDDR4_PDDS_40 (0x6 << 3)
+#define LPDDR4_DBI_RD_EN BIT(6)
+#define LPDDR4_DBI_WR_EN BIT(7)
+
+/* MR11 (ODT Control) */
+#define LPDDR4_DQODT_MASK (0x7)
+#define LPDDR4_DQODT_SHIFT (0x0)
+#define LPDDR4_DQODT_240 (1)
+#define LPDDR4_DQODT_120 (2)
+#define LPDDR4_DQODT_80 (3)
+#define LPDDR4_DQODT_60 (4)
+#define LPDDR4_DQODT_48 (5)
+#define LPDDR4_DQODT_40 (6)
+#define LPDDR4_DQODT_DIS (0)
+#define LPDDR4_CAODT_MASK (0x7 << 4)
+#define LPDDR4_CAODT_SHIFT (4)
+#define LPDDR4_CAODT_240 (1 << 4)
+#define LPDDR4_CAODT_120 (2 << 4)
+#define LPDDR4_CAODT_80 (3 << 4)
+#define LPDDR4_CAODT_60 (4 << 4)
+#define LPDDR4_CAODT_48 (5 << 4)
+#define LPDDR4_CAODT_40 (6 << 4)
+#define LPDDR4_CAODT_DIS (0 << 4)
+
+/* MR22 */
+#define LPDDR4_ODTE_CK_SHIFT (3)
+#define LPDDR4_ODTE_CS_SHIFT (4)
+#define LPDDR4_ODTD_CA_SHIFT (5)
+#define LPDDR4_SOC_ODT_MASK (0x7)
+#define LPDDR4_SOC_ODT_SHIFT (0)
+#define LPDDR4_SOC_ODT_240 (1)
+#define LPDDR4_SOC_ODT_120 (2)
+#define LPDDR4_SOC_ODT_80 (3)
+#define LPDDR4_SOC_ODT_60 (4)
+#define LPDDR4_SOC_ODT_48 (5)
+#define LPDDR4_SOC_ODT_40 (6)
+#define LPDDR4_SOC_ODT_DIS (0)
+
+/* LPDDR4x */
+/* MR3 */
+#define LPDDR4X_VDDQ_0_6 (0)
+#define LPDDR4X_VDDQ_0_5 (1)
+
+/* mr0 for ddr4 */
+#define DDR4_BL8 (0)
+#define DDR4_BC4_8 (1)
+#define DDR4_BC4 (2)
+#define DDR4_WR_RTP(n) ((n) << 9)
+#define DDR4_CL(n) ((((n) & 0xe) << 3) | ((n) & 1) << 2)
+#define DDR4_DLL_RESET(n) ((n) << 8)
+#define DDR4_DLL_ON BIT(0)
+#define DDR4_DLL_OFF (0 << 0)
+
+/* mr1 for ddr4 */
+#define DDR4_AL ((n) << 3)
+#define DDR4_DS_34 (0)
+#define DDR4_DS_48 BIT(1)
+#define DDR4_DS_MASK (0x3 << 1)
+#define DDR4_RTT_NOM_MASK (0x7 << 8)
+#define DDR4_RTT_NOM_DIS (0)
+#define DDR4_RTT_NOM_60 BIT(8)
+#define DDR4_RTT_NOM_120 (2 << 8)
+#define DDR4_RTT_NOM_40 (0x3 << 8)
+#define DDR4_RTT_NOM_240 (0x4 << 8)
+#define DDR4_RTT_NOM_48 (0x5 << 8)
+#define DDR4_RTT_NOM_80 (0x6 << 8)
+#define DDR4_RTT_NOM_34 (0x7 << 8)
+
+/* mr2 for ddr4 */
+#define DDR4_MR2_CWL(n) ((n) << 3)
+#define DDR4_RTT_WR_DIS (0)
+#define DDR4_RTT_WR_120 BIT(9)
+#define DDR4_RTT_WR_240 (2 << 9)
+
+/* mr4 for ddr4 */
+#define DDR4_READ_PREAMBLE(n) ((n) << 11)
+#define DDR4_WRITE_PREAMBLE(n) ((n) << 12)
+#define DDR4_READ_PREAMBLE_TRAIN(n) ((n) << 10)
+
+/* mr5 for ddr4 */
+#define DDR4_RD_DBI(n) ((n) << 12)
+#define DDR4_WR_DBI(n) ((n) << 11)
+#define DDR4_DM(n) ((n) << 10)
+#define DDR4_RTT_PARK_DIS (0 << 6)
+#define DDR4_RTT_PARK_60 (1 << 6)
+#define DDR4_RTT_PARK_120 (2 << 6)
+#define DDR4_RTT_PARK_40 (3 << 6)
+#define DDR4_RTT_PARK_240 (4 << 6)
+#define DDR4_RTT_PARK_48 (5 << 6)
+#define DDR4_RTT_PARK_80 (6 << 6)
+#define DDR4_RTT_PARK_34 (7 << 6)
+#define DIS_ODT_PD (1 << 5)
+#define EN_ODT_PD (0 << 5)
+
+/* mr6 for ddr4 */
+#define DDR4_TCCD_L(n) (((n) - 4) << 10)
+
+#define PS_2_CLK(freq, ps) (((uint64_t)(ps) / 100 * (uint64_t)(freq) +\
+ 9999) / 10000)
+
+#endif /* __ROCKCHIP_DRAM_SPEC_TIMING_H__ */
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rv1126.h b/arch/arm/include/asm/arch-rockchip/grf_rv1126.h
new file mode 100644
index 000000000000..4e0488b91aed
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rv1126.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
+ */
+
+#ifndef _ASM_ARCH_GRF_RV1126_H
+#define _ASM_ARCH_GRF_RV1126_H
+
+struct rv1126_grf {
+ unsigned int soc_con0;
+ unsigned int soc_con1;
+ unsigned int soc_con2;
+ unsigned int reserved0[1];
+ unsigned int soc_status0;
+ unsigned int soc_status1;
+ unsigned int reserved1[2];
+ unsigned int cpu_con0;
+ unsigned int cpu_con1;
+ unsigned int reserved2[2];
+ unsigned int cpu_status0;
+ unsigned int reserved3[3];
+ unsigned int noc_con0;
+ unsigned int noc_con1;
+ unsigned int noc_con2;
+ unsigned int noc_con3;
+ unsigned int usbhost_con0;
+ unsigned int usbhost_con1;
+ unsigned int usbhost_status0;
+ unsigned int usbotg_con0;
+ unsigned int usbotg_con1;
+ unsigned int usbotg_status0;
+ unsigned int usbotg_status1;
+ unsigned int usbotg_status2;
+ unsigned int mac_con0;
+ unsigned int mac_con1;
+ unsigned int mac_con2;
+ unsigned int reserved4[2];
+ unsigned int mac_status0;
+ unsigned int mac_status1;
+ unsigned int mac_status2;
+ unsigned int mem_con0;
+ unsigned int mem_con1;
+ unsigned int mem_con2;
+ unsigned int mem_con3;
+ unsigned int reserved5[(0x100 - 0x09c) / 4 - 1];
+ unsigned int tsadc_con0;
+ unsigned int reserved6[3];
+ unsigned int chip_id;
+ unsigned int reserved7[(0x10000 - 0x110) / 4 - 1];
+ unsigned int gpio0c_iomux_h;
+ unsigned int gpio0d_iomux_l;
+ unsigned int gpio0d_iomux_h;
+ unsigned int reserved8[1];
+ unsigned int gpio1a_iomux_l;
+ unsigned int gpio1a_iomux_h;
+ unsigned int gpio1b_iomux_l;
+ unsigned int gpio1b_iomux_h;
+ unsigned int gpio1c_iomux_l;
+ unsigned int gpio1c_iomux_h;
+ unsigned int gpio1d_iomux_l;
+ unsigned int gpio1d_iomux_h;
+ unsigned int gpio2a_iomux_l;
+ unsigned int gpio2a_iomux_h;
+ unsigned int gpio2b_iomux_l;
+ unsigned int gpio2b_iomux_h;
+ unsigned int gpio2c_iomux_l;
+ unsigned int gpio2c_iomux_h;
+ unsigned int gpio2d_iomux_l;
+ unsigned int gpio2d_iomux_h;
+ unsigned int gpio3a_iomux_l;
+ unsigned int gpio3a_iomux_h;
+ unsigned int gpio3b_iomux_l;
+ unsigned int gpio3b_iomux_h;
+ unsigned int gpio3c_iomux_l;
+ unsigned int gpio3c_iomux_h;
+ unsigned int gpio3d_iomux_l;
+ unsigned int gpio3d_iomux_h;
+ unsigned int gpio4a_iomux_l;
+ unsigned int reserved9[3];
+ unsigned int gpio0c_ds_h;
+ unsigned int gpio0d_ds_l;
+ unsigned int gpio0d_ds_h;
+ unsigned int reserved10[1];
+ unsigned int gpio1a_ds_l;
+ unsigned int gpio1a_ds_h;
+ unsigned int gpio1b_ds_l;
+ unsigned int gpio1b_ds_h;
+ unsigned int gpio1c_ds_l;
+ unsigned int gpio1c_ds_h;
+ unsigned int gpio1d_ds_l;
+ unsigned int gpio1d_ds_h;
+ unsigned int gpio2a_ds_l;
+ unsigned int gpio2a_ds_h;
+ unsigned int gpio2b_ds_l;
+ unsigned int gpio2b_ds_h;
+ unsigned int gpio2c_ds_l;
+ unsigned int gpio2c_ds_h;
+ unsigned int gpio2d_ds_l;
+ unsigned int gpio2d_ds_h;
+ unsigned int gpio3a_ds_l;
+ unsigned int gpio3a_ds_h;
+ unsigned int gpio3b_ds_l;
+ unsigned int gpio3b_ds_h;
+ unsigned int gpio3c_ds_l;
+ unsigned int gpio3c_ds_h;
+ unsigned int gpio3d_ds_l;
+ unsigned int gpio3d_ds_h;
+ unsigned int gpio4a_ds_l;
+ unsigned int reserved12[3];
+ unsigned int gpio0c_p_h;
+ unsigned int gpio0d_p;
+ unsigned int gpio1a_p;
+ unsigned int gpio1b_p;
+ unsigned int gpio1c_p;
+ unsigned int gpio1d_p;
+ unsigned int gpio2a_p;
+ unsigned int gpio2b_p;
+ unsigned int gpio2c_p;
+ unsigned int gpio2d_p;
+ unsigned int gpio3a_p;
+ unsigned int gpio3b_p;
+ unsigned int gpio3c_p;
+ unsigned int gpio3d_p;
+ unsigned int gpio4a_p;
+ unsigned int reserved13[1];
+ unsigned int gpio0c_ie_h;
+ unsigned int gpio0d_ie;
+ unsigned int gpio1a_ie;
+ unsigned int gpio1b_ie;
+ unsigned int gpio1c_ie;
+ unsigned int gpio1d_ie;
+ unsigned int gpio2a_ie;
+ unsigned int gpio2b_ie;
+ unsigned int gpio2c_ie;
+ unsigned int gpio2d_ie;
+ unsigned int gpio3a_ie;
+ unsigned int gpio3b_ie;
+ unsigned int gpio3c_ie;
+ unsigned int gpio3d_ie;
+ unsigned int gpio4a_ie;
+ unsigned int reserved14[1];
+ unsigned int gpio0c_smt_h;
+ unsigned int gpio0d_smt;
+ unsigned int gpio1a_smt;
+ unsigned int gpio1b_smt;
+ unsigned int gpio1c_smt;
+ unsigned int gpio1d_smt;
+ unsigned int gpio2a_smt;
+ unsigned int gpio2b_smt;
+ unsigned int gpio2c_smt;
+ unsigned int gpio2d_smt;
+ unsigned int gpio3a_smt;
+ unsigned int gpio3b_smt;
+ unsigned int gpio3c_smt;
+ unsigned int gpio3d_smt;
+ unsigned int gpio4a_smt;
+ unsigned int reserved15[(0x10200 - 0x101b8) / 4 - 1];
+ unsigned int csiphy0_con;
+ unsigned int reserved16[1];
+ unsigned int csiphy0_status;
+ unsigned int reserved17[1];
+ unsigned int csiphy1_con;
+ unsigned int reserved18[1];
+ unsigned int csiphy1_status;
+ unsigned int reserved19[1];
+ unsigned int dsiphy_con;
+ unsigned int reserved20[3];
+ unsigned int usbphy_con0;
+ unsigned int usbphy_con1;
+ unsigned int usbphy_con2;
+ unsigned int reserved21[3];
+ unsigned int usbphy_status;
+ unsigned int reserved22[1];
+ unsigned int cifio_con;
+ unsigned int sddetflt_con;
+ unsigned int uart2rx_low_con;
+ unsigned int reserved23[1];
+ unsigned int iofunc_con0;
+ unsigned int iofunc_con1;
+ unsigned int iofunc_con2;
+ unsigned int iofunc_con3;
+ unsigned int usbphy0_cfg_con;
+ unsigned int usbphy0_cfg_addrin;
+ unsigned int usbphy0_cfg_addrout;
+ unsigned int usbphy0_cfg_dly_con;
+ unsigned int usbphy1_cfg_con;
+ unsigned int usbphy1_cfg_addrin;
+ unsigned int usbphy1_cfg_addrout;
+ unsigned int usbphy1_cfg_dly_con;
+ unsigned int reserved24[(0x10300 - 0x1028c) / 4 - 1];
+ unsigned int usb_sig_detect_con;
+ unsigned int usb_sig_detect_status;
+ unsigned int usb_sig_detect_clr;
+ unsigned int reserved25[1];
+ unsigned int usb_linestate_con;
+ unsigned int usb_disconnect_con;
+ unsigned int usb_bvalid_con;
+ unsigned int usb_id_con;
+};
+
+check_member(rv1126_grf, usb_id_con, 0x1031c);
+
+struct rv1126_pmugrf {
+ unsigned int gpio0a_iomux_l;
+ unsigned int gpio0a_iomux_h;
+ unsigned int gpio0b_iomux_l;
+ unsigned int gpio0b_iomux_h;
+ unsigned int gpio0c_iomux_l;
+ unsigned int reserved0[3];
+ unsigned int gpio0a_ds_l;
+ unsigned int gpio0a_ds_h;
+ unsigned int gpio0b_ds_l;
+ unsigned int gpio0b_ds_h;
+ unsigned int gpio0c_ds_l;
+ unsigned int osc_ds;
+ unsigned int reserved1[2];
+ unsigned int gpio0a_p;
+ unsigned int gpio0b_p;
+ unsigned int gpio0c_p_l;
+ unsigned int reserved2[1];
+ unsigned int gpio0a_ie;
+ unsigned int gpio0b_ie;
+ unsigned int gpio0c_ie_l;
+ unsigned int reserved3[1];
+ unsigned int gpio0a_smt;
+ unsigned int gpio0b_smt;
+ unsigned int gpio0c_smt_l;
+ unsigned int reserved4[(0x100 - 0x68) / 4 - 1];
+ unsigned int soc_con[7];
+ unsigned int reserved5[(0x140 - 0x118) / 4 - 1];
+ unsigned int io_vsel;
+ unsigned int io_vret;
+ unsigned int reserved6[(0x180 - 0x144) / 4 - 1];
+ unsigned int pmupvtm_clkdiv;
+ unsigned int reserved7[(0x200 - 0x180) / 4 - 1];
+ unsigned int os_reg[12];
+ unsigned int rstfunc_status;
+ unsigned int rstfunc_clr;
+ unsigned int reserved8[(0x380 - 0x234) / 4 - 1];
+ unsigned int sd_detect_con;
+ unsigned int reserved9[3];
+ unsigned int sd_detect_status;
+ unsigned int reserved10[3];
+ unsigned int sd_detect_clr;
+ unsigned int reserved11[3];
+ unsigned int sd_det_count;
+};
+
+check_member(rv1126_pmugrf, sd_det_count, 0x3b0);
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_common.h b/arch/arm/include/asm/arch-rockchip/sdram_common.h
index 5efa6e9445d5..e53e5a9ca589 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_common.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_common.h
@@ -15,6 +15,210 @@
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+/* get head info for initial */
+#define DDR_FREQ_F0_SHIFT (0)
+#define DDR_FREQ_F1_SHIFT (12)
+#define DDR_FREQ_F2_SHIFT (0)
+#define DDR_FREQ_F3_SHIFT (12)
+#define DDR_FREQ_F4_SHIFT (0)
+#define DDR_FREQ_F5_SHIFT (12)
+#define DDR_FREQ_MASK (0xfff)
+
+#define UART_INFO_ID_SHIFT (28)
+#define UART_INFO_IOMUX_SHIFT (24)
+#define UART_INFO_BAUD_SHIFT (0)
+#define UART_INFO_ID(n) (((n) >> 28) & 0xf)
+#define UART_INFO_IOMUX(n) (((n) >> 24) & 0xf)
+#define UART_INFO_BAUD(n) ((n) & 0xffffff)
+
+/* g_ch_info[15:0]: g_stdby_idle */
+#define STANDBY_IDLE(n) ((n) & 0xffff)
+
+#define SR_INFO(n) (((n) >> 16) & 0xffff)
+#define PD_INFO(n) ((n) & 0xffff)
+
+#define FIRST_SCAN_CH(n) (((n) >> 28) & 0xf)
+#define CHANNEL_MASK(n) (((n) >> 24) & 0xf)
+#define STRIDE_TYPE(n) (((n) >> 16) & 0xff)
+
+#define DDR_2T_INFO(n) ((n) & 1)
+#define PLL_SSMOD_SPREAD(n) (((n) >> 1) & 0xff)
+#define PLL_SSMOD_DIV(n) (((n) >> 9) & 0xff)
+#define PLL_SSMOD_DOWNSPREAD(n) (((n) >> 17) & 0x3)
+
+/* sdram_head_info_v2 define */
+/* for *_drv_odten and *_drv_odtoff */
+#define PHY_DQ_DRV_SHIFT 0
+#define PHY_CA_DRV_SHIFT 8
+#define PHY_CLK_DRV_SHIFT 16
+#define DRAM_DQ_DRV_SHIFT 24
+#define DRV_INFO_PHY_DQ_DRV(n) ((n) & 0xff)
+#define DRV_INFO_PHY_CA_DRV(n) (((n) >> PHY_CA_DRV_SHIFT) & 0xff)
+#define DRV_INFO_PHY_CLK_DRV(n) (((n) >> PHY_CLK_DRV_SHIFT) & 0xff)
+#define DRV_INFO_DRAM_DQ_DRV(n) (((n) >> DRAM_DQ_DRV_SHIFT) & 0xff)
+
+/* for *_odt_info */
+#define DRAM_ODT_SHIFT 0
+#define PHY_ODT_SHIFT 8
+#define PHY_ODT_PUUP_EN_SHIFT 18
+#define PHY_ODT_PUDN_EN_SHIFT 19
+#define ODT_INFO_DRAM_ODT(n) (((n) >> DRAM_ODT_SHIFT) & 0xff)
+#define ODT_INFO_PHY_ODT(n) (((n) >> PHY_ODT_SHIFT) & 0x3ff)
+#define ODT_INFO_PULLUP_EN(n) (((n) >> PHY_ODT_PUUP_EN_SHIFT) & 1)
+#define ODT_INFO_PULLDOWN_EN(n) (((n) >> PHY_ODT_PUDN_EN_SHIFT) & 1)
+
+/* for *odt_en_freq; */
+#define DRAM_ODT_EN_FREQ_SHIFT 0
+#define PHY_ODT_EN_FREQ_SHIFT 12
+#define DRAMODT_EN_FREQ(n) (((n) >> DRAM_ODT_EN_FREQ_SHIFT) & \
+ 0xfff)
+#define PHYODT_EN_FREQ(n) (((n) >> PHY_ODT_EN_FREQ_SHIFT) & 0xfff)
+
+#define PHY_DQ_SR_SHIFT 0
+#define PHY_CA_SR_SHIFT 8
+#define PHY_CLK_SR_SHIFT 16
+#define DQ_SR_INFO(n) (((n) >> PHY_DQ_SR_SHIFT) & 0xff)
+#define CA_SR_INFO(n) (((n) >> PHY_CA_SR_SHIFT) & 0xff)
+#define CLK_SR_INFO(n) (((n) >> PHY_CLK_SR_SHIFT) & 0xff)
+
+/* LP4 */
+#define LP4_CA_ODT_SHIFT (18)
+#define LP4_DRV_PU_CAL_ODTEN_SHIFT (26)
+#define LP4_DRV_PU_CAL_ODTOFF_SHIFT (27)
+#define PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT (28)
+#define PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT (29)
+#define ODT_INFO_LP4_CA_ODT(n) (((n) >> LP4_CA_ODT_SHIFT) & \
+ 0xff)
+#define LP4_DRV_PU_CAL_ODTEN(n) \
+ (((n) >> LP4_DRV_PU_CAL_ODTEN_SHIFT) & 1)
+#define LP4_DRV_PU_CAL_ODTOFF(n) \
+ (((n) >> LP4_DRV_PU_CAL_ODTOFF_SHIFT) & 1)
+#define PHY_LP4_DRV_PULLDOWN_EN_ODTEN(n) \
+ (((n) >> PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT) & 1)
+#define PHY_LP4_DRV_PULLDOWN_EN_ODTOFF(n) \
+ (((n) >> PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT) & 1)
+
+#define PHY_LP4_CS_DRV_ODTEN_SHIFT (0)
+#define PHY_LP4_CS_DRV_ODTOFF_SHIFT (8)
+#define LP4_ODTE_CK_SHIFT (16)
+#define LP4_ODTE_CS_EN_SHIFT (17)
+#define LP4_ODTD_CA_EN_SHIFT (18)
+#define PHY_LP4_CS_DRV_ODTEN(n) \
+ (((n) >> PHY_LP4_CS_DRV_ODTEN_SHIFT) & 0xff)
+#define PHY_LP4_CS_DRV_ODTOFF(n) \
+ (((n) >> PHY_LP4_CS_DRV_ODTOFF_SHIFT) & 0xff)
+#define LP4_ODTE_CK_EN(n) (((n) >> LP4_ODTE_CK_SHIFT) & 1)
+#define LP4_ODTE_CS_EN(n) (((n) >> LP4_ODTE_CS_EN_SHIFT) & 1)
+#define LP4_ODTD_CA_EN(n) (((n) >> LP4_ODTD_CA_EN_SHIFT) & 1)
+
+#define PHY_LP4_DQ_VREF_SHIFT (0)
+#define LP4_DQ_VREF_SHIFT (10)
+#define LP4_CA_VREF_SHIFT (20)
+
+#define PHY_LP4_DQ_VREF(n) \
+ (((n) >> PHY_LP4_DQ_VREF_SHIFT) & 0x3ff)
+#define LP4_DQ_VREF(n) (((n) >> LP4_DQ_VREF_SHIFT) & 0x3ff)
+#define LP4_CA_VREF(n) (((n) >> LP4_CA_VREF_SHIFT) & 0x3ff)
+
+#define LP4_DQ_ODT_EN_FREQ_SHIFT (0)
+#define PHY_LP4_ODT_EN_FREQ_SHIFT (12)
+#define LP4_CA_ODT_EN_FREQ_SHIFT (0)
+#define PHY_LP4_ODT_EN_FREQ(n) \
+ (((n) >> PHY_LP4_ODT_EN_FREQ_SHIFT) & 0xfff)
+#define LP4_DQ_ODT_EN_FREQ(n) \
+ (((n) >> LP4_DQ_ODT_EN_FREQ_SHIFT) & 0xfff)
+#define LP4_CA_ODT_EN_FREQ(n) \
+ (((n) >> LP4_CA_ODT_EN_FREQ_SHIFT) & 0xfff)
+
+struct sdram_head_info_v0 {
+ u32 start_tag;
+ u32 version_info;
+ u32 gcpu_gen_freq;
+ u32 g_d2_lp2_freq;
+ u32 g_d3_lp3_freq;
+ u32 g_d4_lp4_freq;
+ u32 g_uart_info;
+ u32 g_sr_pd_idle;
+ u32 g_ch_info;
+ u32 g_2t_info;
+ u32 reserved11;
+ u32 reserved12;
+ u32 reserved13;
+};
+
+struct index_info {
+ u8 offset;
+ u8 size;
+};
+
+struct sdram_head_info_index_v2 {
+ u32 start_tag;
+ u32 version_info;
+ struct index_info cpu_gen_index;
+ struct index_info global_index;
+
+ struct index_info ddr2_index;
+ struct index_info ddr3_index;
+
+ struct index_info ddr4_index;
+ struct index_info ddr5_index;
+
+ struct index_info lp2_index;
+ struct index_info lp3_index;
+
+ struct index_info lp4_index;
+ struct index_info lp5_index;
+
+ struct index_info skew_index;
+ struct index_info dq_map_index;
+
+ struct index_info lp4x_index;
+ struct index_info reserved;
+};
+
+struct global_info {
+ u32 uart_info;
+ u32 sr_pd_info;
+ u32 ch_info;
+ u32 info_2t;
+ u32 reserved[4];
+};
+
+struct ddr2_3_4_lp2_3_info {
+ u32 ddr_freq0_1;
+ u32 ddr_freq2_3;
+ u32 ddr_freq4_5;
+ u32 drv_when_odten;
+ u32 drv_when_odtoff;
+ u32 odt_info;
+ u32 odten_freq;
+ u32 sr_when_odten;
+ u32 sr_when_odtoff;
+};
+
+struct lp4_info {
+ u32 ddr_freq0_1;
+ u32 ddr_freq2_3;
+ u32 ddr_freq4_5;
+ u32 drv_when_odten;
+ u32 drv_when_odtoff;
+ u32 odt_info;
+ u32 dq_odten_freq;
+ u32 sr_when_odten;
+ u32 sr_when_odtoff;
+ u32 ca_odten_freq;
+ u32 cs_drv_ca_odt_info;
+ u32 vref_when_odten;
+ u32 vref_when_odtoff;
+};
+
+struct dq_map_info {
+ u32 byte_map[2];
+ u32 lp3_dq0_7_map;
+ u32 lp2_dq0_7_map;
+ u32 ddr4_dq_map[4];
+};
+
struct sdram_cap_info {
unsigned int rank;
/* dram column number, 0 means this channel is invalid */
@@ -46,6 +250,14 @@ struct sdram_base_params {
};
#define DDR_SYS_REG_VERSION (0x2)
+/* for modify tRFC and related timing */
+#define DIE_CAP_512MBIT 64
+#define DIE_CAP_1GBIT 128
+#define DIE_CAP_2GBIT 256
+#define DIE_CAP_4GBIT 512
+#define DIE_CAP_8GBIT 1024
+#define DIE_CAP_16GBIT 2048
+#define DIE_CAP_32GBIT 4096
/*
* sys_reg2 bitfield struct
* [31] row_3_4_ch1
@@ -116,7 +328,7 @@ struct sdram_base_params {
void sdram_print_dram_type(unsigned char dramtype);
void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base);
+ struct sdram_base_params *base, u32 split);
void sdram_print_stride(unsigned int stride);
void sdram_org_config(struct sdram_cap_info *cap_info,
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_msch.h b/arch/arm/include/asm/arch-rockchip/sdram_msch.h
index cfb3d9cc8698..d1926f4bf20a 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_msch.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_msch.h
@@ -57,6 +57,18 @@ union noc_devtodev0 {
} b;
};
+union noc_devtodev_rv1126 {
+ u32 d32;
+ struct {
+ unsigned busrdtord : 3;
+ unsigned reserved0 : 1;
+ unsigned busrdtowr : 4;
+ unsigned buswrtord : 4;
+ unsigned buswrtowr : 3;
+ unsigned reserved2 : 17;
+ } b;
+};
+
union noc_ddrmode {
u32 d32;
struct {
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
index 3a3657789f6b..3780dc6ea5b2 100644
--- a/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
+++ b/arch/arm/include/asm/arch-rockchip/sdram_pctl_px30.h
@@ -12,7 +12,7 @@
#endif
struct ddr_pctl_regs {
- u32 pctl[30][2];
+ u32 pctl[35][2];
};
/* ddr pctl registers define */
@@ -25,6 +25,7 @@ struct ddr_pctl_regs {
#define DDR_PCTL2_MRCTRL2 0x1c
#define DDR_PCTL2_DERATEEN 0x20
#define DDR_PCTL2_DERATEINT 0x24
+#define DDR_PCTL2_MSTR2 0x28
#define DDR_PCTL2_PWRCTL 0x30
#define DDR_PCTL2_PWRTMG 0x34
#define DDR_PCTL2_HWLPCTL 0x38
@@ -122,8 +123,103 @@ struct ddr_pctl_regs {
#define DDR_PCTL2_PCFGW_n 0x408
#define DDR_PCTL2_PCTRL_n 0x490
+#define UMCTL2_REGS_FREQ(n) \
+ ((0x1000 * (n) + (((n) > 0) ? 0x1000 : 0)))
+
+/* PCTL2_MSTR */
+#define PCTL2_FREQUENCY_MODE_MASK (1)
+#define PCTL2_FREQUENCY_MODE_SHIFT (29)
+#define PCTL2_DLL_OFF_MODE BIT(15)
+/* PCTL2_STAT */
+#define PCTL2_SELFREF_TYPE_MASK (3 << 4)
+#define PCTL2_SELFREF_TYPE_SR_NOT_AUTO (2 << 4)
+#define PCTL2_OPERATING_MODE_MASK (7)
+#define PCTL2_OPERATING_MODE_INIT (0)
+#define PCTL2_OPERATING_MODE_NORMAL (1)
+#define PCTL2_OPERATING_MODE_PD (2)
+#define PCTL2_OPERATING_MODE_SR (3)
+/* PCTL2_MRCTRL0 */
+#define PCTL2_MR_WR BIT(31)
+#define PCTL2_MR_ADDR_SHIFT (12)
+#define PCTL2_MR_RANK_SHIFT (4)
+#define PCTL2_MR_TYPE_WR (0)
+#define PCTL2_MR_TYPE_RD (1)
+/* PCTL2_MRCTRL1 */
+#define PCTL2_MR_ADDRESS_SHIFT (8)
+#define PCTL2_MR_DATA_MASK (0xff)
/* PCTL2_MRSTAT */
-#define MR_WR_BUSY BIT(0)
+#define PCTL2_MR_WR_BUSY BIT(0)
+/* PCTL2_DERATEEN */
+#define PCTL2_DERATE_ENABLE (1)
+/* PCTL2_PWRCTL */
+#define PCTL2_SELFREF_SW BIT(5)
+#define PCTL2_POWERDOWN_EN BIT(1)
+#define PCTL2_SELFREF_EN (1)
+/* PCTL2_PWRTMG */
+#define PCTL2_SELFREF_TO_X32_MASK (0xFF)
+#define PCTL2_SELFREF_TO_X32_SHIFT (16)
+#define PCTL2_POWERDOWN_TO_X32_MASK (0x1F)
+/* PCTL2_INIT3 */
+#define PCTL2_DDR34_MR0_SHIFT (16)
+#define PCTL2_LPDDR234_MR1_SHIFT (16)
+#define PCTL2_DDR34_MR1_SHIFT (0)
+#define PCTL2_LPDDR234_MR2_SHIFT (0)
+/* PCTL2_INIT4 */
+#define PCTL2_DDR34_MR2_SHIFT (16)
+#define PCTL2_LPDDR234_MR3_SHIFT (16)
+#define PCTL2_DDR34_MR3_SHIFT (0)
+#define PCTL2_LPDDR4_MR13_SHIFT (0)
+
+/* PCTL2_INIT6 */
+#define PCTL2_DDR4_MR4_SHIFT (16)
+#define PCTL2_LPDDR4_MR11_SHIFT (16)
+#define PCTL2_DDR4_MR5_SHIFT (0)
+#define PCTL2_LPDDR4_MR12_SHIFT (0)
+
+/* PCTL2_INIT7 */
+#define PCTL2_LPDDR4_MR22_SHIFT (16)
+#define PCTL2_DDR4_MR6_SHIFT (0)
+#define PCTL2_LPDDR4_MR14_SHIFT (0)
+
+#define PCTL2_MR_MASK (0xffff)
+
+/* PCTL2_RFSHCTL3 */
+#define PCTL2_DIS_AUTO_REFRESH (1)
+/* PCTL2_ZQCTL0 */
+#define PCTL2_DIS_AUTO_ZQ BIT(31)
+#define PCTL2_DIS_SRX_ZQCL BIT(30)
+/* PCTL2_DFILPCFG0 */
+#define PCTL2_DFI_LP_EN_SR BIT(8)
+#define PCTL2_DFI_LP_EN_SR_MASK BIT(8)
+#define PCTL2_DFI_LP_EN_SR_SHIFT (8)
+/* PCTL2_DFIMISC */
+#define PCTL2_DFI_INIT_COMPLETE_EN (1)
+/* PCTL2_DFISTAT */
+#define PCTL2_DFI_LP_ACK BIT(1)
+#define PCTL2_DFI_INIT_COMPLETE (1)
+/* PCTL2_DBG1 */
+#define PCTL2_DIS_HIF BIT(1)
+/* PCTL2_DBGCAM */
+#define PCTL2_DBG_WR_Q_EMPTY BIT(26)
+#define PCTL2_DBG_RD_Q_EMPTY BIT(25)
+#define PCTL2_DBG_LPR_Q_DEPTH_MASK (0xffff << 8)
+#define PCTL2_DBG_LPR_Q_DEPTH_EMPTY (0x0 << 8)
+/* PCTL2_DBGCMD */
+#define PCTL2_RANK1_REFRESH BIT(1)
+#define PCTL2_RANK0_REFRESH (1)
+/* PCTL2_DBGSTAT */
+#define PCTL2_RANK1_REFRESH_BUSY BIT(1)
+#define PCTL2_RANK0_REFRESH_BUSY (1)
+/* PCTL2_SWCTL */
+#define PCTL2_SW_DONE (1)
+#define PCTL2_SW_DONE_CLEAR (0)
+/* PCTL2_SWSTAT */
+#define PCTL2_SW_DONE_ACK (1)
+/* PCTL2_PSTAT */
+#define PCTL2_WR_PORT_BUSY_0 BIT(16)
+#define PCTL2_RD_PORT_BUSY_0 (1)
+/* PCTL2_PCTRLn */
+#define PCTL2_PORT_EN (1)
void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num);
int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h b/arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h
new file mode 100644
index 000000000000..5b64ec335280
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_phy_rv1126.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_RK1126_PHY_H
+#define _ASM_ARCH_SDRAM_RK1126_PHY_H
+
+/* PHY_REG0 */
+#define DIGITAL_DERESET BIT(3)
+#define ANALOG_DERESET BIT(2)
+#define DIGITAL_RESET (0 << 3)
+#define ANALOG_RESET (0 << 2)
+
+/* PHY_REG1 */
+#define PHY_DDR2 (0)
+#define PHY_LPDDR2 (1)
+#define PHY_DDR3 (2)
+#define PHY_LPDDR3 (3)
+#define PHY_DDR4 (4)
+#define PHY_DDR5 (5)
+#define PHY_BL_4 (0 << 3)
+#define PHY_BL_8_OR_16 BIT(3)
+
+/* PHY_REG2 */
+#define PHY_DTT_EN BIT(0)
+#define PHY_DTT_DISB (0 << 0)
+#define PHY_WRITE_LEVELING_EN BIT(2)
+#define PHY_WRITE_LEVELING_DISB (0 << 2)
+#define PHY_SELECT_CS0 (2)
+#define PHY_SELECT_CS1 (1)
+#define PHY_SELECT_CS0_1 (0)
+#define PHY_WRITE_LEVELING_SELECTCS(n) ((n) << 6)
+#define PHY_DATA_TRAINING_SELECTCS(n) ((n) << 4)
+
+/* PHY_REGf */
+#define PHY_DQ_WIDTH_MASK (0xf)
+
+/* PHY_REG51 */
+#define PHY_PBDIV_BIT9_MASK BIT(0)
+#define PHY_PBDIV_BIT9_SHIFT (0)
+#define PHY_POSTDIV_EN_MASK BIT(7)
+#define PHY_POSTDIV_EN_SHIFT (7)
+
+/* PHY_REG52 */
+#define PHY_PREDIV_MASK (0x1F)
+#define PHY_PREDIV_SHIFT (0)
+
+/* PHY_REG53*/
+#define PHY_POSTDIV_MASK (0x7)
+#define PHY_POSTDIV_SHIFT (5)
+#define PHY_PD_DISB BIT(3)
+
+/* PHY_REG90 */
+#define PHY_PLL_LOCK BIT(2)
+
+struct ca_skew {
+ u32 a0_a3_a3_cke1_a_de_skew;
+ u32 a1_ba1_null_cke0_b_de_skew;
+ u32 a2_a9_a9_a4_a_de_skew;
+ u32 a3_a15_null_a5_b_de_skew;
+ u32 a4_a6_a6_ck_a_de_skew;
+ u32 a5_a12_null_odt0_b_de_skew;
+ u32 a6_ba2_null_a0_a_de_skew;
+ u32 a7_a4_a4_odt0_a_de_skew;
+ u32 a8_a1_a1_cke0_a_de_skew;
+ u32 a9_a5_a5_a5_a_de_skew;
+ u32 a10_a8_a8_clkb_a_de_skew;
+ u32 a11_a7_a7_ca2_a_de_skew;
+ u32 a12_rasn_null_ca1_a_de_skew;
+ u32 a13_a13_null_ca3_a_de_skew;
+ u32 a14_a14_null_csb1_b_de_skew;
+ u32 a15_a10_null_ca0_b_de_skew;
+ u32 a16_a11_null_csb0_b_de_skew;
+ u32 a17_null_null_null_de_skew;
+ u32 ba0_csb1_csb1_csb0_a_de_skew;
+ u32 ba1_wen_null_cke1_b_de_skew;
+ u32 bg0_odt1_odt1_csb1_a_de_skew;
+ u32 bg1_a2_a2_odt1_a_de_skew;
+ u32 cke0_casb_null_ca1_b_de_skew;
+ u32 ck_ck_ck_ck_b_de_skew;
+ u32 ckb_ckb_ckb_ckb_b_de_skew;
+ u32 csb0_odt0_odt0_ca2_b_de_skew;
+ u32 odt0_csb0_csb0_ca4_b_de_skew;
+ u32 resetn_resetn_null_resetn_de_skew;
+ u32 actn_cke_cke_ca3_b_de_skew;
+ u32 null_null_null_null_de_skew;
+ u32 csb1_ba0_null_null_de_skew;
+ u32 odt1_a0_a0_odt1_b_de_skew;
+};
+
+#define PHY_REG(base, n) ((base) + 4 * (n))
+#endif /* _ASM_ARCH_SDRAM_RK1126_PHY_H */
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_rv1126.h b/arch/arm/include/asm/arch-rockchip/sdram_rv1126.h
new file mode 100644
index 000000000000..6a07436059cd
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_rv1126.h
@@ -0,0 +1,420 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_RK1126_H
+#define _ASM_ARCH_SDRAM_RK1126_H
+
+#include <asm/arch-rockchip/dram_spec_timing.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_msch.h>
+#include <asm/arch-rockchip/sdram_pctl_px30.h>
+#include <asm/arch-rockchip/sdram_phy_rv1126.h>
+
+#define AGINGX0_VAL (4)
+#define AGING_CPU_VAL (0xff)
+#define AGING_NPU_VAL (0xff)
+#define AGING_OTHER_VAL (0x33)
+
+#define PATTERN (0x5aa5f00f)
+
+#define PHY_DDR3_RON_DISABLE (0)
+#define PHY_DDR3_RON_455ohm (1)
+#define PHY_DDR3_RON_230ohm (2)
+#define PHY_DDR3_RON_153ohm (3)
+#define PHY_DDR3_RON_115ohm (4)
+#define PHY_DDR3_RON_91ohm (5)
+#define PHY_DDR3_RON_76ohm (6)
+#define PHY_DDR3_RON_65ohm (7)
+#define PHY_DDR3_RON_57ohm (16)
+#define PHY_DDR3_RON_51ohm (17)
+#define PHY_DDR3_RON_46ohm (18)
+#define PHY_DDR3_RON_41ohm (19)
+#define PHY_DDR3_RON_38ohm (20)
+#define PHY_DDR3_RON_35ohm (21)
+#define PHY_DDR3_RON_32ohm (22)
+#define PHY_DDR3_RON_30ohm (23)
+#define PHY_DDR3_RON_28ohm (24)
+#define PHY_DDR3_RON_27ohm (25)
+#define PHY_DDR3_RON_25ohm (26)
+#define PHY_DDR3_RON_24ohm (27)
+#define PHY_DDR3_RON_23ohm (28)
+#define PHY_DDR3_RON_22ohm (29)
+#define PHY_DDR3_RON_21ohm (30)
+#define PHY_DDR3_RON_20ohm (31)
+
+#define PHY_DDR3_RTT_DISABLE (0)
+#define PHY_DDR3_RTT_561ohm (1)
+#define PHY_DDR3_RTT_282ohm (2)
+#define PHY_DDR3_RTT_188ohm (3)
+#define PHY_DDR3_RTT_141ohm (4)
+#define PHY_DDR3_RTT_113ohm (5)
+#define PHY_DDR3_RTT_94ohm (6)
+#define PHY_DDR3_RTT_81ohm (7)
+#define PHY_DDR3_RTT_72ohm (16)
+#define PHY_DDR3_RTT_64ohm (17)
+#define PHY_DDR3_RTT_58ohm (18)
+#define PHY_DDR3_RTT_52ohm (19)
+#define PHY_DDR3_RTT_48ohm (20)
+#define PHY_DDR3_RTT_44ohm (21)
+#define PHY_DDR3_RTT_41ohm (22)
+#define PHY_DDR3_RTT_38ohm (23)
+#define PHY_DDR3_RTT_37ohm (24)
+#define PHY_DDR3_RTT_34ohm (25)
+#define PHY_DDR3_RTT_32ohm (26)
+#define PHY_DDR3_RTT_31ohm (27)
+#define PHY_DDR3_RTT_29ohm (28)
+#define PHY_DDR3_RTT_28ohm (29)
+#define PHY_DDR3_RTT_27ohm (30)
+#define PHY_DDR3_RTT_25ohm (31)
+
+#define PHY_DDR4_LPDDR3_RON_DISABLE (0)
+#define PHY_DDR4_LPDDR3_RON_482ohm (1)
+#define PHY_DDR4_LPDDR3_RON_244ohm (2)
+#define PHY_DDR4_LPDDR3_RON_162ohm (3)
+#define PHY_DDR4_LPDDR3_RON_122ohm (4)
+#define PHY_DDR4_LPDDR3_RON_97ohm (5)
+#define PHY_DDR4_LPDDR3_RON_81ohm (6)
+#define PHY_DDR4_LPDDR3_RON_69ohm (7)
+#define PHY_DDR4_LPDDR3_RON_61ohm (16)
+#define PHY_DDR4_LPDDR3_RON_54ohm (17)
+#define PHY_DDR4_LPDDR3_RON_48ohm (18)
+#define PHY_DDR4_LPDDR3_RON_44ohm (19)
+#define PHY_DDR4_LPDDR3_RON_40ohm (20)
+#define PHY_DDR4_LPDDR3_RON_37ohm (21)
+#define PHY_DDR4_LPDDR3_RON_34ohm (22)
+#define PHY_DDR4_LPDDR3_RON_32ohm (23)
+#define PHY_DDR4_LPDDR3_RON_30ohm (24)
+#define PHY_DDR4_LPDDR3_RON_28ohm (25)
+#define PHY_DDR4_LPDDR3_RON_27ohm (26)
+#define PHY_DDR4_LPDDR3_RON_25ohm (27)
+#define PHY_DDR4_LPDDR3_RON_24ohm (28)
+#define PHY_DDR4_LPDDR3_RON_23ohm (29)
+#define PHY_DDR4_LPDDR3_RON_22ohm (30)
+#define PHY_DDR4_LPDDR3_RON_21ohm (31)
+
+#define PHY_DDR4_LPDDR3_RTT_DISABLE (0)
+#define PHY_DDR4_LPDDR3_RTT_586ohm (1)
+#define PHY_DDR4_LPDDR3_RTT_294ohm (2)
+#define PHY_DDR4_LPDDR3_RTT_196ohm (3)
+#define PHY_DDR4_LPDDR3_RTT_148ohm (4)
+#define PHY_DDR4_LPDDR3_RTT_118ohm (5)
+#define PHY_DDR4_LPDDR3_RTT_99ohm (6)
+#define PHY_DDR4_LPDDR3_RTT_85ohm (7)
+#define PHY_DDR4_LPDDR3_RTT_76ohm (16)
+#define PHY_DDR4_LPDDR3_RTT_67ohm (17)
+#define PHY_DDR4_LPDDR3_RTT_60ohm (18)
+#define PHY_DDR4_LPDDR3_RTT_55ohm (19)
+#define PHY_DDR4_LPDDR3_RTT_50ohm (20)
+#define PHY_DDR4_LPDDR3_RTT_46ohm (21)
+#define PHY_DDR4_LPDDR3_RTT_43ohm (22)
+#define PHY_DDR4_LPDDR3_RTT_40ohm (23)
+#define PHY_DDR4_LPDDR3_RTT_38ohm (24)
+#define PHY_DDR4_LPDDR3_RTT_36ohm (25)
+#define PHY_DDR4_LPDDR3_RTT_34ohm (26)
+#define PHY_DDR4_LPDDR3_RTT_32ohm (27)
+#define PHY_DDR4_LPDDR3_RTT_31ohm (28)
+#define PHY_DDR4_LPDDR3_RTT_29ohm (29)
+#define PHY_DDR4_LPDDR3_RTT_28ohm (30)
+#define PHY_DDR4_LPDDR3_RTT_27ohm (31)
+
+#define PHY_LPDDR4_RON_DISABLE (0)
+#define PHY_LPDDR4_RON_501ohm (1)
+#define PHY_LPDDR4_RON_253ohm (2)
+#define PHY_LPDDR4_RON_168ohm (3)
+#define PHY_LPDDR4_RON_126ohm (4)
+#define PHY_LPDDR4_RON_101ohm (5)
+#define PHY_LPDDR4_RON_84ohm (6)
+#define PHY_LPDDR4_RON_72ohm (7)
+#define PHY_LPDDR4_RON_63ohm (16)
+#define PHY_LPDDR4_RON_56ohm (17)
+#define PHY_LPDDR4_RON_50ohm (18)
+#define PHY_LPDDR4_RON_46ohm (19)
+#define PHY_LPDDR4_RON_42ohm (20)
+#define PHY_LPDDR4_RON_38ohm (21)
+#define PHY_LPDDR4_RON_36ohm (22)
+#define PHY_LPDDR4_RON_33ohm (23)
+#define PHY_LPDDR4_RON_31ohm (24)
+#define PHY_LPDDR4_RON_29ohm (25)
+#define PHY_LPDDR4_RON_28ohm (26)
+#define PHY_LPDDR4_RON_26ohm (27)
+#define PHY_LPDDR4_RON_25ohm (28)
+#define PHY_LPDDR4_RON_24ohm (29)
+#define PHY_LPDDR4_RON_23ohm (30)
+#define PHY_LPDDR4_RON_22ohm (31)
+
+#define PHY_LPDDR4_RTT_DISABLE (0)
+#define PHY_LPDDR4_RTT_604ohm (1)
+#define PHY_LPDDR4_RTT_303ohm (2)
+#define PHY_LPDDR4_RTT_202ohm (3)
+#define PHY_LPDDR4_RTT_152ohm (4)
+#define PHY_LPDDR4_RTT_122ohm (5)
+#define PHY_LPDDR4_RTT_101ohm (6)
+#define PHY_LPDDR4_RTT_87ohm (7)
+#define PHY_LPDDR4_RTT_78ohm (16)
+#define PHY_LPDDR4_RTT_69ohm (17)
+#define PHY_LPDDR4_RTT_62ohm (18)
+#define PHY_LPDDR4_RTT_56ohm (19)
+#define PHY_LPDDR4_RTT_52ohm (20)
+#define PHY_LPDDR4_RTT_48ohm (21)
+#define PHY_LPDDR4_RTT_44ohm (22)
+#define PHY_LPDDR4_RTT_41ohm (23)
+#define PHY_LPDDR4_RTT_39ohm (24)
+#define PHY_LPDDR4_RTT_37ohm (25)
+#define PHY_LPDDR4_RTT_35ohm (26)
+#define PHY_LPDDR4_RTT_33ohm (27)
+#define PHY_LPDDR4_RTT_32ohm (28)
+#define PHY_LPDDR4_RTT_30ohm (29)
+#define PHY_LPDDR4_RTT_29ohm (30)
+#define PHY_LPDDR4_RTT_27ohm (31)
+
+#define ADD_CMD_CA (0x150)
+#define ADD_GROUP_CS0_A (0x170)
+#define ADD_GROUP_CS0_B (0x1d0)
+#define ADD_GROUP_CS1_A (0x1a0)
+#define ADD_GROUP_CS1_B (0x200)
+
+/* PMUGRF */
+#define PMUGRF_OS_REG0 (0x200)
+#define PMUGRF_OS_REG(n) (PMUGRF_OS_REG0 + (n) * 4)
+#define PMUGRF_CON_DDRPHY_BUFFEREN_MASK (0x3 << (12 + 16))
+#define PMUGRF_CON_DDRPHY_BUFFEREN_EN (0x1 << 12)
+#define PMUGRF_CON_DDRPHY_BUFFEREN_DIS (0x2 << 12)
+
+/* DDR GRF */
+#define DDR_GRF_CON(n) (0 + (n) * 4)
+#define DDR_GRF_STATUS_BASE (0X100)
+#define DDR_GRF_STATUS(n) (DDR_GRF_STATUS_BASE + (n) * 4)
+#define DDR_GRF_LP_CON (0x20)
+
+#define SPLIT_MODE_32_L16_VALID (0)
+#define SPLIT_MODE_32_H16_VALID (1)
+#define SPLIT_MODE_16_L8_VALID (2)
+#define SPLIT_MODE_16_H8_VALID (3)
+
+#define DDR_GRF_SPLIT_CON (0x10)
+#define SPLIT_MODE_MASK (0x3)
+#define SPLIT_MODE_OFFSET (9)
+#define SPLIT_BYPASS_MASK (1)
+#define SPLIT_BYPASS_OFFSET (8)
+#define SPLIT_SIZE_MASK (0xff)
+#define SPLIT_SIZE_OFFSET (0)
+
+/* SGRF SOC_CON13 */
+#define UPCTL2_ASRSTN_REQ(n) (((0x1 << 0) << 16) | ((n) << 0))
+#define UPCTL2_PSRSTN_REQ(n) (((0x1 << 1) << 16) | ((n) << 1))
+#define UPCTL2_SRSTN_REQ(n) (((0x1 << 2) << 16) | ((n) << 2))
+
+/* CRU define */
+/* CRU_PLL_CON0 */
+#define PB(n) ((0x1 << (15 + 16)) | ((n) << 15))
+#define POSTDIV1(n) ((0x7 << (12 + 16)) | ((n) << 12))
+#define FBDIV(n) ((0xFFF << 16) | (n))
+
+/* CRU_PLL_CON1 */
+#define RSTMODE(n) ((0x1 << (15 + 16)) | ((n) << 15))
+#define RST(n) ((0x1 << (14 + 16)) | ((n) << 14))
+#define PD(n) ((0x1 << (13 + 16)) | ((n) << 13))
+#define DSMPD(n) ((0x1 << (12 + 16)) | ((n) << 12))
+#define LOCK(n) (((n) >> 10) & 0x1)
+#define POSTDIV2(n) ((0x7 << (6 + 16)) | ((n) << 6))
+#define REFDIV(n) ((0x3F << 16) | (n))
+
+/* CRU_PLL_CON3 */
+#define SSMOD_SPREAD(n) ((0x1f << (8 + 16)) | ((n) << 8))
+#define SSMOD_DIVVAL(n) ((0xf << (4 + 16)) | ((n) << 4))
+#define SSMOD_DOWNSPREAD(n) ((0x1 << (3 + 16)) | ((n) << 3))
+#define SSMOD_RESET(n) ((0x1 << (2 + 16)) | ((n) << 2))
+#define SSMOD_DIS_SSCG(n) ((0x1 << (1 + 16)) | ((n) << 1))
+#define SSMOD_BP(n) ((0x1 << (0 + 16)) | ((n) << 0))
+
+/* CRU_MODE */
+#define CLOCK_FROM_XIN_OSC (0)
+#define CLOCK_FROM_PLL (1)
+#define CLOCK_FROM_RTC_32K (2)
+#define DPLL_MODE(n) ((0x3 << (2 + 16)) | ((n) << 2))
+
+/* CRU_SOFTRESET_CON1 */
+#define DDRPHY_PSRSTN_REQ(n) (((0x1 << 14) << 16) | ((n) << 14))
+#define DDRPHY_SRSTN_REQ(n) (((0x1 << 15) << 16) | ((n) << 15))
+/* CRU_CLKGATE_CON2 */
+#define DDR_MSCH_EN_MASK ((0x1 << 10) << 16)
+#define DDR_MSCH_EN_SHIFT (10)
+
+/* CRU register */
+#define CRU_PLL_CON(pll_id, n) ((pll_id) * 0x20 + (n) * 4)
+#define CRU_MODE (0xa0)
+#define CRU_GLB_CNT_TH (0xb0)
+#define CRU_CLKSEL_CON_BASE 0x100
+#define CRU_CLKSELS_CON(i) (CRU_CLKSEL_CON_BASE + ((i) * 4))
+#define CRU_CLKGATE_CON_BASE 0x230
+#define CRU_CLKGATE_CON(i) (CRU_CLKGATE_CON_BASE + ((i) * 4))
+#define CRU_CLKSFTRST_CON_BASE 0x300
+#define CRU_CLKSFTRST_CON(i) (CRU_CLKSFTRST_CON_BASE + ((i) * 4))
+
+/* SGRF_SOC_CON2 */
+#define MSCH_AXI_BYPASS_ALL_MASK (1)
+#define MSCH_AXI_BYPASS_ALL_SHIFT (15)
+
+/* SGRF_SOC_CON12 */
+#define CLK_DDR_UPCTL_EN_MASK ((0x1 << 2) << 16)
+#define CLK_DDR_UPCTL_EN_SHIFT (2)
+#define ACLK_DDR_UPCTL_EN_MASK ((0x1 << 0) << 16)
+#define ACLK_DDR_UPCTL_EN_SHIFT (0)
+
+/* DDRGRF DDR CON2 */
+#define DFI_FREQ_CHANGE_ACK BIT(10)
+/* DDRGRF status8 */
+#define DFI_FREQ_CHANGE_REQ BIT(19)
+
+struct rv1126_ddrgrf {
+ u32 ddr_grf_con[4];
+ u32 grf_ddrsplit_con;
+ u32 reserved1[(0x20 - 0x10) / 4 - 1];
+ u32 ddr_grf_lp_con;
+ u32 reserved2[(0x40 - 0x20) / 4 - 1];
+ u32 grf_ddrphy_con[6];
+ u32 reserved3[(0x100 - 0x54) / 4 - 1];
+ u32 ddr_grf_status[18];
+ u32 reserved4[(0x150 - 0x144) / 4 - 1];
+ u32 grf_ddrhold_status;
+ u32 reserved5[(0x160 - 0x150) / 4 - 1];
+ u32 grf_ddrphy_status[2];
+};
+
+struct rv1126_ddr_phy_regs {
+ u32 phy[8][2];
+};
+
+struct msch_regs {
+ u32 coreid;
+ u32 revisionid;
+ u32 deviceconf;
+ u32 devicesize;
+ u32 ddrtiminga0;
+ u32 ddrtimingb0;
+ u32 ddrtimingc0;
+ u32 devtodev0;
+ u32 reserved1[(0x110 - 0x20) / 4];
+ u32 ddrmode;
+ u32 ddr4timing;
+ u32 reserved2[(0x1000 - 0x118) / 4];
+ u32 agingx0;
+ u32 reserved3[(0x1040 - 0x1004) / 4];
+ u32 aging0;
+ u32 aging1;
+ u32 aging2;
+ u32 aging3;
+};
+
+struct sdram_msch_timings {
+ union noc_ddrtiminga0 ddrtiminga0;
+ union noc_ddrtimingb0 ddrtimingb0;
+ union noc_ddrtimingc0 ddrtimingc0;
+ union noc_devtodev_rv1126 devtodev0;
+ union noc_ddrmode ddrmode;
+ union noc_ddr4timing ddr4timing;
+ u32 agingx0;
+ u32 aging0;
+ u32 aging1;
+ u32 aging2;
+ u32 aging3;
+};
+
+struct rv1126_sdram_channel {
+ struct sdram_cap_info cap_info;
+ struct sdram_msch_timings noc_timings;
+};
+
+struct rv1126_sdram_params {
+ struct rv1126_sdram_channel ch;
+ struct sdram_base_params base;
+ struct ddr_pctl_regs pctl_regs;
+ struct rv1126_ddr_phy_regs phy_regs;
+};
+
+struct rv1126_fsp_param {
+ u32 flag;
+ u32 freq_mhz;
+
+ /* dram size */
+ u32 dq_odt;
+ u32 ca_odt;
+ u32 ds_pdds;
+ u32 vref_ca[2];
+ u32 vref_dq[2];
+
+ /* phy side */
+ u32 wr_dq_drv;
+ u32 wr_ca_drv;
+ u32 wr_ckcs_drv;
+ u32 rd_odt;
+ u32 rd_odt_up_en;
+ u32 rd_odt_down_en;
+ u32 vref_inner;
+ u32 vref_out;
+ u32 lp4_drv_pd_en;
+
+ struct sdram_msch_timings noc_timings;
+};
+
+#define MAX_IDX (4)
+#define FSP_FLAG (0xfead0001)
+#define SHARE_MEM_BASE (0x100000)
+/*
+ * Borrow share memory space to temporarily store FSP parame.
+ * In the stage of DDR init write FSP parame to this space.
+ * In the stage of trust init move FSP parame to SRAM space
+ * from share memory space.
+ */
+#define FSP_PARAM_STORE_ADDR (SHARE_MEM_BASE)
+
+/* store result of read and write training, for ddr_dq_eye tool in u-boot */
+#define RW_TRN_RESULT_ADDR (0x2000000 + 0x8000) /* 32M + 32k */
+#define PRINT_STEP 1
+
+#undef FSP_NUM
+#undef CS_NUM
+#undef BYTE_NUM
+
+#define FSP_NUM 4
+#define CS_NUM 2
+#define BYTE_NUM 4
+#define RD_DESKEW_NUM 64
+#define WR_DESKEW_NUM 64
+
+#define LP4_WIDTH_REF_MHZ_H 1056
+#define LP4_RD_WIDTH_REF_H 12
+#define LP4_WR_WIDTH_REF_H 13
+
+#define LP4_WIDTH_REF_MHZ_L 924
+#define LP4_RD_WIDTH_REF_L 15
+#define LP4_WR_WIDTH_REF_L 15
+
+#define DDR4_WIDTH_REF_MHZ_H 1056
+#define DDR4_RD_WIDTH_REF_H 13
+#define DDR4_WR_WIDTH_REF_H 9
+
+#define DDR4_WIDTH_REF_MHZ_L 924
+#define DDR4_RD_WIDTH_REF_L 15
+#define DDR4_WR_WIDTH_REF_L 11
+
+#define LP3_WIDTH_REF_MHZ_H 1056
+#define LP3_RD_WIDTH_REF_H 15
+#define LP3_WR_WIDTH_REF_H 13
+
+#define LP3_WIDTH_REF_MHZ_L 924
+#define LP3_RD_WIDTH_REF_L 16
+#define LP3_WR_WIDTH_REF_L 15
+
+#define DDR3_WIDTH_REF_MHZ_H 1056
+#define DDR3_RD_WIDTH_REF_H 14
+#define DDR3_WR_WIDTH_REF_H 14
+
+#define DDR3_WIDTH_REF_MHZ_L 924
+#define DDR3_RD_WIDTH_REF_L 17
+#define DDR3_WR_WIDTH_REF_L 17
+
+#endif /* _ASM_ARCH_SDRAM_RK1126_H */
diff --git a/arch/arm/include/asm/arch-rv1126/boot0.h b/arch/arm/include/asm/arch-rv1126/boot0.h
new file mode 100644
index 000000000000..2e78b074ade8
--- /dev/null
+++ b/arch/arm/include/asm/arch-rv1126/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rv1126/gpio.h b/arch/arm/include/asm/arch-rv1126/gpio.h
new file mode 100644
index 000000000000..eca79d515940
--- /dev/null
+++ b/arch/arm/include/asm/arch-rv1126/gpio.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include <asm/arch-rockchip/gpio.h>
+
+#endif
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index c8a193dd4cdf..45cc9326368c 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -12,6 +12,19 @@ config KW88F6281
config SHEEVA_88SV131
bool
+config KIRKWOOD_COMMON
+ bool
+ select DM_SERIAL
+
+config HAS_CUSTOM_SYS_INIT_SP_ADDR
+ bool "Use a custom location for the initial stack pointer address"
+ default y
+
+config CUSTOM_SYS_INIT_SP_ADDR
+ hex "Static location for the initial stack pointer"
+ depends on HAS_CUSTOM_SYS_INIT_SP_ADDR
+ default 0x5ff000
+
choice
prompt "Marvell Kirkwood board select"
optional
@@ -25,6 +38,7 @@ config TARGET_DREAMPLUG
bool "DreamPlug Board"
select KW88F6281
select SHEEVA_88SV131
+ select KIRKWOOD_COMMON
config TARGET_DS109
bool "Synology DS109"
@@ -40,6 +54,7 @@ config TARGET_SHEEVAPLUG
bool "SheevaPlug Board"
select FEROCEON_88FR131
select KW88F6281
+ select KIRKWOOD_COMMON
config TARGET_LSXL
bool "lsxl Board"
@@ -47,16 +62,19 @@ config TARGET_LSXL
select KW88F6281
select BOARD_EARLY_INIT_R
select MISC_INIT_R
+ select KIRKWOOD_COMMON
config TARGET_POGO_E02
bool "pogo_e02 Board"
select FEROCEON_88FR131
select KW88F6281
+ select KIRKWOOD_COMMON
config TARGET_POGO_V4
bool "Pogoplug V4 Board"
select FEROCEON_88FR131
select KW88F6192
+ select KIRKWOOD_COMMON
config TARGET_DNS325
bool "dns325 Board"
@@ -67,6 +85,7 @@ config TARGET_ICONNECT
bool "iconnect Board"
select FEROCEON_88FR131
select KW88F6281
+ select KIRKWOOD_COMMON
config TARGET_KM_KIRKWOOD
bool "KM Kirkwood Board"
@@ -92,11 +111,13 @@ config TARGET_DOCKSTAR
bool "Dockstar Board"
select FEROCEON_88FR131
select KW88F6281
+ select KIRKWOOD_COMMON
config TARGET_GOFLEXHOME
bool "GoFlex Home Board"
select FEROCEON_88FR131
select KW88F6281
+ select KIRKWOOD_COMMON
config TARGET_NAS220
bool "BlackArmor NAS220"
@@ -107,6 +128,7 @@ config TARGET_NSA310S
bool "Zyxel NSA310S"
select FEROCEON_88FR131
select KW88F6192
+ select KIRKWOOD_COMMON
config TARGET_SBx81LIFKW
bool "Allied Telesis SBx81GS24/SBx81GT40/SBx81XS6/SBx81XS16"
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 4898260017d4..b678ec41318e 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -302,6 +302,51 @@ config ROCKCHIP_RV1108
The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7
and a DSP.
+config ROCKCHIP_RV1126
+ bool "Support Rockchip RV1126"
+ select CPU_V7A
+ select SKIP_LOWLEVEL_INIT_ONLY
+ select TPL
+ select SUPPORT_TPL
+ select TPL_NEEDS_SEPARATE_STACK
+ select TPL_ROCKCHIP_BACK_TO_BROM
+ select SPL
+ select SUPPORT_SPL
+ select SPL_STACK_R
+ select CLK
+ select FIT
+ select PINCTRL
+ select RAM
+ select ROCKCHIP_SDRAM_COMMON
+ select REGMAP
+ select SYSCON
+ select DM_PMIC
+ select DM_REGULATOR_FIXED
+ select DM_RESET
+ select REGULATOR_RK8XX
+ select PMIC_RK8XX
+ select BOARD_LATE_INIT
+ imply ROCKCHIP_COMMON_BOARD
+ imply TPL_DM
+ imply TPL_LIBCOMMON_SUPPORT
+ imply TPL_LIBGENERIC_SUPPORT
+ imply TPL_OF_CONTROL
+ imply TPL_OF_PLATDATA
+ imply TPL_RAM
+ imply TPL_ROCKCHIP_COMMON_BOARD
+ imply TPL_SERIAL
+ imply SPL_CLK
+ imply SPL_DM
+ imply SPL_DRIVERS_MISC
+ imply SPL_LIBCOMMON_SUPPORT
+ imply SPL_LIBGENERIC_SUPPORT
+ imply SPL_OF_CONTROL
+ imply SPL_RAM
+ imply SPL_REGMAP
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply SPL_SERIAL
+ imply SPL_SYSCON
+
config ROCKCHIP_USB_UART
bool "Route uart output to usb pins"
help
@@ -447,4 +492,5 @@ source "arch/arm/mach-rockchip/rk3368/Kconfig"
source "arch/arm/mach-rockchip/rk3399/Kconfig"
source "arch/arm/mach-rockchip/rk3568/Kconfig"
source "arch/arm/mach-rockchip/rv1108/Kconfig"
+source "arch/arm/mach-rockchip/rv1126/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 6c1c7b8a1080..32138fa723fe 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/
obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
obj-$(CONFIG_ROCKCHIP_RK3568) += rk3568/
obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/
+obj-$(CONFIG_ROCKCHIP_RV1126) += rv1126/
# Clear out SPL objects, in case this is a TPL build
obj-spl-$(CONFIG_TPL_BUILD) =
diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig
index 28639c00414c..41893920cb4d 100644
--- a/arch/arm/mach-rockchip/px30/Kconfig
+++ b/arch/arm/mach-rockchip/px30/Kconfig
@@ -35,6 +35,30 @@ config TARGET_PX30_CORE
* PX30.Core needs to mount on top of C.TOUCH 2.0 carrier with pluged
10.1" OF for creating complete PX30.Core C.TOUCH 2.0 10.1" Open Frame.
+config TARGET_RINGNECK_PX30
+ bool "Theobroma Systems PX30-µQ7 (Ringneck)"
+ help
+ The PX30-uQ7 (Ringneck) SoM is a µQseven-compatible (40mmx70mm,
+ MXM-230 connector) system-on-module from Theobroma Systems[1],
+ featuring the Rockchip PX30.
+
+ It provides the following feature set:
+ * up to 4GB DDR4
+ * up to 128GB on-module eMMC (with 8-bit 1.8V interface)
+ * SD card (on a baseboard) via edge connector
+ * Fast Ethernet with on-module TI DP83825I PHY
+ * MIPI-DSI/LVDS
+ * MIPI-CSI
+ * USB
+ - 1x USB 2.0 dual-role
+ - 3x USB 2.0 host
+ * on-module companion controller (STM32 Cortex-M0 or ATtiny), implementing:
+ - low-power RTC functionality (ISL1208 emulation)
+ - fan controller (AMC6821 emulation)
+ - USB<->CAN bridge controller (STM32 only)
+ * on-module Espressif ESP32 for Bluetooth + 2.4GHz WiFi
+ * on-module NXP SE05x Secure Element
+
config ROCKCHIP_BOOT_MODE_REG
default 0xff010200
@@ -71,5 +95,6 @@ config DEBUG_UART_CHANNEL
source "board/engicam/px30_core/Kconfig"
source "board/hardkernel/odroid_go2/Kconfig"
source "board/rockchip/evb_px30/Kconfig"
+source "board/theobroma-systems/ringneck_px30/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/px30/px30.c b/arch/arm/mach-rockchip/px30/px30.c
index 0641e6af0f74..3bca25c609fe 100644
--- a/arch/arm/mach-rockchip/px30/px30.c
+++ b/arch/arm/mach-rockchip/px30/px30.c
@@ -5,9 +5,12 @@
#include <common.h>
#include <clk.h>
#include <dm.h>
+#include <fdt_support.h>
#include <init.h>
+#include <spl.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
#include <asm/arch-rockchip/grf_px30.h>
#include <asm/arch-rockchip/hardware.h>
#include <asm/arch-rockchip/uart.h>
@@ -15,6 +18,11 @@
#include <asm/arch-rockchip/cru_px30.h>
#include <dt-bindings/clock/px30-cru.h>
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/mmc@ff390000",
+ [BROM_BOOTSOURCE_SD] = "/mmc@ff370000",
+};
+
static struct mm_region px30_mem_map[] = {
{
.virt = 0x0UL,
@@ -234,6 +242,7 @@ enum {
int arch_cpu_init(void)
{
static struct px30_grf * const grf = (void *)GRF_BASE;
+ static struct px30_cru * const cru = (void *)CRU_BASE;
u32 __maybe_unused val;
#ifdef CONFIG_SPL_BUILD
@@ -285,6 +294,9 @@ int arch_cpu_init(void)
/* Clear the force_jtag */
rk_clrreg(&grf->cpu_con[1], 1 << 7);
+ /* Make TSADC and WDT trigger a first global reset */
+ clrsetbits_le32(&cru->glb_rst_con, 0x3, 0x3);
+
return 0;
}
@@ -297,8 +309,18 @@ void board_debug_uart_init(void)
CONFIG_DEBUG_UART_BASE == 0xff030000)
static struct px30_pmugrf * const pmugrf = (void *)PMUGRF_BASE;
#endif
+#if !defined(CONFIG_DEBUG_UART_BASE) || \
+ (CONFIG_DEBUG_UART_BASE != 0xff158000 && \
+ CONFIG_DEBUG_UART_BASE != 0xff168000 && \
+ CONFIG_DEBUG_UART_BASE != 0xff178000 && \
+ CONFIG_DEBUG_UART_BASE != 0xff030000) || \
+ (defined(CONFIG_DEBUG_UART_BASE) && \
+ (CONFIG_DEBUG_UART_BASE == 0xff158000 || \
+ CONFIG_DEBUG_UART_BASE == 0xff168000 || \
+ CONFIG_DEBUG_UART_BASE == 0xff178000))
static struct px30_grf * const grf = (void *)GRF_BASE;
static struct px30_cru * const cru = (void *)CRU_BASE;
+#endif
#if defined(CONFIG_DEBUG_UART_BASE) && CONFIG_DEBUG_UART_BASE == 0xff030000
static struct px30_pmucru * const pmucru = (void *)PMUCRU_BASE;
#endif
@@ -421,3 +443,52 @@ void board_debug_uart_init(void)
#endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */
}
#endif /* CONFIG_DEBUG_UART_BOARD_INIT */
+
+#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
+const char *spl_decode_boot_device(u32 boot_device)
+{
+ int i;
+ static const struct {
+ u32 boot_device;
+ const char *ofpath;
+ } spl_boot_devices_tbl[] = {
+ { BOOT_DEVICE_MMC2, "/mmc@ff370000" },
+ { BOOT_DEVICE_MMC1, "/mmc@ff390000" },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i)
+ if (spl_boot_devices_tbl[i].boot_device == boot_device)
+ return spl_boot_devices_tbl[i].ofpath;
+
+ return NULL;
+}
+
+void spl_perform_fixups(struct spl_image_info *spl_image)
+{
+ void *blob = spl_image->fdt_addr;
+ const char *boot_ofpath;
+ int chosen;
+
+ /*
+ * Inject the ofpath of the device the full U-Boot (or Linux in
+ * Falcon-mode) was booted from into the FDT, if a FDT has been
+ * loaded at the same time.
+ */
+ if (!blob)
+ return;
+
+ boot_ofpath = spl_decode_boot_device(spl_image->boot_device);
+ if (!boot_ofpath) {
+ pr_err("%s: could not map boot_device to ofpath\n", __func__);
+ return;
+ }
+
+ chosen = fdt_find_or_add_subnode(blob, 0, "chosen");
+ if (chosen < 0) {
+ pr_err("%s: could not find/create '/chosen'\n", __func__);
+ return;
+ }
+ fdt_setprop_string(blob, chosen,
+ "u-boot,spl-boot-device", boot_ofpath);
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
index b48feeb3466c..d01063ac98b6 100644
--- a/arch/arm/mach-rockchip/rk3399/Kconfig
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -39,6 +39,13 @@ config TARGET_PINEBOOK_PRO_RK3399
with 4Gb RAM, onboard eMMC, USB-C, a USB3 and USB2 port,
1920*1080 screen and all the usual laptop features.
+config TARGET_PINEPHONE_PRO_RK3399
+ bool "PinePhone Pro"
+ help
+ PinePhone Pro is a phone based on a variant of the Rockchip
+ rk3399 SoC with 4Gb RAM, onboard eMMC, USB-C, headphone jack,
+ 720x1440 screen and a Quectel 4G/LTE modem.
+
config TARGET_PUMA_RK3399
bool "Theobroma Systems RK3399-Q7 (Puma)"
help
@@ -165,6 +172,7 @@ endif # BOOTCOUNT_LIMIT
source "board/firefly/roc-pc-rk3399/Kconfig"
source "board/google/gru/Kconfig"
source "board/pine64/pinebook-pro-rk3399/Kconfig"
+source "board/pine64/pinephone-pro-rk3399/Kconfig"
source "board/pine64/rockpro64_rk3399/Kconfig"
source "board/rockchip/evb_rk3399/Kconfig"
source "board/theobroma-systems/puma_rk3399/Kconfig"
diff --git a/arch/arm/mach-rockchip/rv1126/Kconfig b/arch/arm/mach-rockchip/rv1126/Kconfig
new file mode 100644
index 000000000000..7382c5599661
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1126/Kconfig
@@ -0,0 +1,59 @@
+if ROCKCHIP_RV1126
+
+config TARGET_RV1126_NEU2
+ bool "Edgeble Neural Compute Module 2(Neu2) SoM"
+ help
+ Neu2:
+ Neural Compute Module 2(Neu2) is a 96boards SoM-CB compute module
+ based on Rockchip RV1126 from Edgeble AI.
+ Neu2 powered with Consumer grade (0 to +80 °C) RV1126 SoC.
+ Neu2k powered with Industrial grade (-40 °C to +85 °C) RV1126K SoC.
+
+ Neu2-IO:
+ Neural Compute Module 2(Neu2) IO board is an industrial form factor
+ IO board and Neu2 needs to mount on top of this IO board in order to
+ create complete Edgeble Neural Compute Module 2(Neu2) IO platform.
+
+config SOC_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select HAS_CUSTOM_SYS_INIT_SP_ADDR
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xfe020200
+
+config ROCKCHIP_STIMER_BASE
+ default 0xff670020
+
+config SYS_SOC
+ default "rv1126"
+
+config CUSTOM_SYS_INIT_SP_ADDR
+ default 0x800000
+
+config SPL_STACK
+ default 0x600000
+
+config SPL_STACK_R_ADDR
+ default 0x800000
+
+config TPL_LDSCRIPT
+ default "arch/arm/mach-rockchip/u-boot-tpl.lds"
+
+config TPL_STACK
+ default 0xff718000
+
+config TPL_SYS_MALLOC_F_LEN
+ default 0x2000
+
+config TPL_TEXT_BASE
+ default 0xff701000
+
+config SYS_MALLOC_F_LEN
+ default 0x2000
+
+config TEXT_BASE
+ default 0x600000
+
+source board/edgeble/neural-compute-module-2/Kconfig
+
+endif
diff --git a/arch/arm/mach-rockchip/rv1126/Makefile b/arch/arm/mach-rockchip/rv1126/Makefile
new file mode 100644
index 000000000000..b2875633db59
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1126/Makefile
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2019 Rockchip Electronics Co., Ltd
+# Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rv1126.o
+
+ifndef CONFIG_TPL_BUILD
+obj-y += clk_rv1126.o
+obj-y += syscon_rv1126.o
+endif
diff --git a/arch/arm/mach-rockchip/rv1126/clk_rv1126.c b/arch/arm/mach-rockchip/rv1126/clk_rv1126.c
new file mode 100644
index 000000000000..bd8902718f20
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1126/clk_rv1126.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1126.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rv1126_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rv1126_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
diff --git a/arch/arm/mach-rockchip/rv1126/rv1126.c b/arch/arm/mach-rockchip/rv1126/rv1126.c
new file mode 100644
index 000000000000..b9b898756f73
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1126/rv1126.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rv1126.h>
+
+#define FIREWALL_APB_BASE 0xffa60000
+#define FW_DDR_CON_REG 0x80
+#define GRF_BASE 0xFE000000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/mmc@ffc50000",
+ [BROM_BOOTSOURCE_SD] = "/mmc@ffc60000",
+};
+
+/* GRF_GPIO3A_IOMUX_L */
+enum {
+ GPIO3A3_SHIFT = 12,
+ GPIO3A3_MASK = GENMASK(14, 12),
+ GPIO3A3_GPIO = 0,
+ GPIO3A3_UART2_RX_M1,
+ GPIO3A3_A7_JTAG_TMS_M1,
+
+ GPIO3A2_SHIFT = 8,
+ GPIO3A2_MASK = GENMASK(10, 8),
+ GPIO3A2_GPIO = 0,
+ GPIO3A2_UART2_TX_M1,
+ GPIO3A2_A7_JTAG_TCK_M1,
+};
+
+/* GRF_IOFUNC_CON2 */
+enum {
+ UART2_IO_SEL_SHIFT = 8,
+ UART2_IO_SEL_MASK = GENMASK(8, 8),
+ UART2_IO_SEL_M0 = 0,
+ UART2_IO_SEL_M1,
+};
+
+void board_debug_uart_init(void)
+{
+ static struct rv1126_grf * const grf = (void *)GRF_BASE;
+
+ /* Enable early UART2 channel m1 on the rv1126 */
+ rk_clrsetreg(&grf->iofunc_con2, UART2_IO_SEL_MASK,
+ UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT);
+
+ /* Switch iomux */
+ rk_clrsetreg(&grf->gpio3a_iomux_l,
+ GPIO3A3_MASK | GPIO3A2_MASK,
+ GPIO3A3_UART2_RX_M1 << GPIO3A3_SHIFT |
+ GPIO3A2_UART2_TX_M1 << GPIO3A2_SHIFT);
+}
+
+#ifndef CONFIG_TPL_BUILD
+int arch_cpu_init(void)
+{
+ /**
+ * Set dram area unsecure in spl
+ *
+ * usb & mmc & sfc controllers can read data to dram
+ * since they are unsecure.
+ * (Note: only secure-world can access this register)
+ */
+ if (IS_ENABLED(CONFIG_SPL_BUILD))
+ writel(0, FIREWALL_APB_BASE + FW_DDR_CON_REG);
+
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-rockchip/rv1126/syscon_rv1126.c b/arch/arm/mach-rockchip/rv1126/syscon_rv1126.c
new file mode 100644
index 000000000000..599ea66e3d67
--- /dev/null
+++ b/arch/arm/mach-rockchip/rv1126/syscon_rv1126.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rv1126_syscon_ids[] = {
+ { .compatible = "rockchip,rv1126-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rv1126-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rv1126) = {
+ .name = "rv1126_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1126_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rv1126_syscon_bind_of_plat(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rv1126_pmu) = {
+ .name = "rockchip_rv1126_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1126_syscon_ids,
+ .bind = rv1126_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rv1126_pmugrf) = {
+ .name = "rockchip_rv1126_pmugrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1126_syscon_ids + 1,
+ .bind = rv1126_syscon_bind_of_plat,
+};
+#endif
diff --git a/board/edgeble/neural-compute-module-2/Kconfig b/board/edgeble/neural-compute-module-2/Kconfig
new file mode 100644
index 000000000000..21faf4ad260c
--- /dev/null
+++ b/board/edgeble/neural-compute-module-2/Kconfig
@@ -0,0 +1,16 @@
+if TARGET_RV1126_NEU2
+
+config SYS_BOARD
+ default "neural-compute-module-2"
+
+config SYS_VENDOR
+ default "edgeble"
+
+config SYS_CONFIG_NAME
+ default "neural-compute-module-2"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select RAM_ROCKCHIP_LPDDR4
+
+endif
diff --git a/board/edgeble/neural-compute-module-2/MAINTAINERS b/board/edgeble/neural-compute-module-2/MAINTAINERS
new file mode 100644
index 000000000000..38edb3a36036
--- /dev/null
+++ b/board/edgeble/neural-compute-module-2/MAINTAINERS
@@ -0,0 +1,6 @@
+RV1126-ECM0
+M: Jagan Teki <jagan@edgeble.ai>
+S: Maintained
+F: board/edgeble/neural-compute-module-2
+F: include/configs/neural-compute-module-2.h
+F: configs/neu2-io-rv1126_defconfig
diff --git a/board/edgeble/neural-compute-module-2/Makefile b/board/edgeble/neural-compute-module-2/Makefile
new file mode 100644
index 000000000000..3bfc89fa1531
--- /dev/null
+++ b/board/edgeble/neural-compute-module-2/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += neu2.o
diff --git a/board/edgeble/neural-compute-module-2/neu2.c b/board/edgeble/neural-compute-module-2/neu2.c
new file mode 100644
index 000000000000..3d2262ce977e
--- /dev/null
+++ b/board/edgeble/neural-compute-module-2/neu2.c
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
diff --git a/board/engicam/px30_core/Kconfig b/board/engicam/px30_core/Kconfig
index a03be78369c9..924c30f3e170 100644
--- a/board/engicam/px30_core/Kconfig
+++ b/board/engicam/px30_core/Kconfig
@@ -11,6 +11,6 @@ config SYS_CONFIG_NAME
config BOARD_SPECIFIC_OPTIONS # dummy
def_bool y
- select RAM_PX30_DDR4
+ select RAM_ROCKCHIP_DDR4
endif
diff --git a/board/pine64/pinephone-pro-rk3399/Kconfig b/board/pine64/pinephone-pro-rk3399/Kconfig
new file mode 100644
index 000000000000..13d6465ae6e6
--- /dev/null
+++ b/board/pine64/pinephone-pro-rk3399/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_PINEPHONE_PRO_RK3399
+
+config SYS_BOARD
+ default "pinephone-pro-rk3399"
+
+config SYS_VENDOR
+ default "pine64"
+
+config SYS_CONFIG_NAME
+ default "pinephone-pro-rk3399"
+
+config BOARD_SPECIFIC_OPTIONS
+ def_bool y
+
+endif
diff --git a/board/pine64/pinephone-pro-rk3399/MAINTAINERS b/board/pine64/pinephone-pro-rk3399/MAINTAINERS
new file mode 100644
index 000000000000..c923ff1be32f
--- /dev/null
+++ b/board/pine64/pinephone-pro-rk3399/MAINTAINERS
@@ -0,0 +1,8 @@
+PINEPHONE_PRO
+M: Peter Robinson <pbrobinson@gmail.com>
+S: Maintained
+F: board/pine64/rk3399-pinephone-pro/
+F: include/configs/rk3399-pinephone-pro.h
+F: arch/arm/dts/rk3399-pinephone-pro.dts
+F: arch/arm/dts/rk3399-pinephone-pro-u-boot.dtsi
+F: configs/pinephone-pro-rk3399_defconfig
diff --git a/board/pine64/pinephone-pro-rk3399/Makefile b/board/pine64/pinephone-pro-rk3399/Makefile
new file mode 100644
index 000000000000..8d9203053e57
--- /dev/null
+++ b/board/pine64/pinephone-pro-rk3399/Makefile
@@ -0,0 +1 @@
+obj-y += pinephone-pro-rk3399.o
diff --git a/board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c b/board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c
new file mode 100644
index 000000000000..eb639cd0d070
--- /dev/null
+++ b/board/pine64/pinephone-pro-rk3399/pinephone-pro-rk3399.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * (C) Copyright 2022 Peter Robinson <pbrobinson at gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <init.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/misc.h>
+#include <power/regulator.h>
+
+#define GRF_IO_VSEL_BT565_SHIFT 0
+#define PMUGRF_CON0_VSEL_SHIFT 8
+
+#ifndef CONFIG_SPL_BUILD
+int board_early_init_f(void)
+{
+ struct udevice *regulator;
+ int ret;
+
+ ret = regulator_get_by_platname("vcc5v0_usb", &regulator);
+ if (ret) {
+ pr_debug("%s vcc5v0_usb init fail! ret %d\n", __func__, ret);
+ goto out;
+ }
+
+ ret = regulator_set_enable(regulator, true);
+ if (ret)
+ pr_debug("%s vcc5v0-host-en-gpio set fail! ret %d\n", __func__, ret);
+
+out:
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_MISC_INIT_R
+static void setup_iodomain(void)
+{
+ struct rk3399_grf_regs *grf =
+ syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ struct rk3399_pmugrf_regs *pmugrf =
+ syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+
+ /* BT565 is in 1.8v domain */
+ rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_BT565_SHIFT);
+
+ /* Set GPIO1 1.8v/3.0v source select to PMU1830_VOL */
+ rk_setreg(&pmugrf->soc_con0, 1 << PMUGRF_CON0_VSEL_SHIFT);
+}
+
+int misc_init_r(void)
+{
+ const u32 cpuid_offset = 0x7;
+ const u32 cpuid_length = 0x10;
+ u8 cpuid[cpuid_length];
+ int ret;
+
+ setup_iodomain();
+
+ ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
+ if (ret)
+ return ret;
+
+ ret = rockchip_cpuid_set(cpuid, cpuid_length);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+#endif
diff --git a/board/theobroma-systems/ringneck_px30/Kconfig b/board/theobroma-systems/ringneck_px30/Kconfig
new file mode 100644
index 000000000000..24d94807db8a
--- /dev/null
+++ b/board/theobroma-systems/ringneck_px30/Kconfig
@@ -0,0 +1,18 @@
+if TARGET_RINGNECK_PX30
+
+config SYS_BOARD
+ default "ringneck_px30"
+
+config SYS_VENDOR
+ default "theobroma-systems"
+
+config SYS_CONFIG_NAME
+ default "ringneck_px30"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+
+config ENV_SIZE
+ default 0x3000
+
+endif
diff --git a/board/theobroma-systems/ringneck_px30/MAINTAINERS b/board/theobroma-systems/ringneck_px30/MAINTAINERS
new file mode 100644
index 000000000000..d764e26066c3
--- /dev/null
+++ b/board/theobroma-systems/ringneck_px30/MAINTAINERS
@@ -0,0 +1,9 @@
+RINGNECK-PX30
+M: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+M: Klaus Goger <klaus.goger@theobroma-systems.com>
+S: Maintained
+F: board/theobroma-systems/ringneck_px30
+F: include/configs/ringneck_px30.h
+F: arch/arm/dts/px30-ringneck*
+F: configs/ringneck-px30_defconfig
+W: https://www.theobroma-systems.com/px30-uq7#tech-spec
diff --git a/board/theobroma-systems/ringneck_px30/Makefile b/board/theobroma-systems/ringneck_px30/Makefile
new file mode 100644
index 000000000000..31ada1a69422
--- /dev/null
+++ b/board/theobroma-systems/ringneck_px30/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += ringneck-px30.o
diff --git a/board/theobroma-systems/ringneck_px30/README b/board/theobroma-systems/ringneck_px30/README
new file mode 100644
index 000000000000..e756b3a8ffcc
--- /dev/null
+++ b/board/theobroma-systems/ringneck_px30/README
@@ -0,0 +1,69 @@
+Introduction
+============
+
+The PX30-uQ7 (Ringneck) SoM is a µQseven-compatible (40mmx70mm, MXM-230
+connector) system-on-module from Theobroma Systems[1], featuring the
+Rockchip PX30.
+
+It provides the following feature set:
+ * up to 4GB DDR4
+ * up to 128GB on-module eMMC (with 8-bit 1.8V interface)
+ * SD card (on a baseboard) via edge connector
+ * Fast Ethernet with on-module TI DP83825I PHY
+ * MIPI-DSI/LVDS
+ * MIPI-CSI
+ * USB
+ - 1x USB 2.0 dual-role
+ - 3x USB 2.0 host
+ * on-module companion controller (STM32 Cortex-M0 or ATtiny), implementing:
+ - low-power RTC functionality (ISL1208 emulation)
+ - fan controller (AMC6821 emulation)
+ - USB<->CAN bridge controller (STM32 only)
+ * on-module Espressif ESP32 for Bluetooth + 2.4GHz WiFi
+ * on-module NXP SE05x Secure Element
+
+Here is the step-by-step to boot to U-Boot on px30.
+
+Get the Source and build ATF binary
+===================================
+
+ > git clone https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
+
+Compile the ATF
+===============
+
+ > cd trusted-firmware-a
+ > make CROSS_COMPILE=aarch64-linux-gnu- PLAT=px30 bl31
+ > cp build/px30/release/bl31/bl31.elf ../u-boot/bl31.elf
+
+Compile the U-Boot
+==================
+
+ > cd ../u-boot
+ > make CROSS_COMPILE=aarch64-linux-gnu- ringneck-px30_defconfig all
+
+Flash the image
+===============
+
+Copy u-boot-rockchip.bin to offset 32k for SD/eMMC.
+
+SD-Card
+-------
+
+ > dd if=u-boot-rockchip.bin of=/dev/sdb seek=64
+
+eMMC
+----
+
+rkdeveloptool allows to flash the on-board eMMC via the USB OTG interface with
+help of the Rockchip loader binary.
+
+ > git clone https://github.com/rockchip-linux/rkdeveloptool
+ > cd rkdeveloptool
+ > autoreconf -i && ./configure && make
+ > git clone https://github.com/rockchip-linux/rkbin.git
+ > cd rkbin
+ > ./tools/boot_merger RKBOOT/PX30MINIALL.ini
+ > cd ..
+ > ./rkdeveloptool db rkbin/px30_loader_v1.16.131.bin
+ > ./rkdeveloptool wl 64 ../u-boot-rockchip.bin
diff --git a/board/theobroma-systems/ringneck_px30/ringneck-px30.c b/board/theobroma-systems/ringneck_px30/ringneck-px30.c
new file mode 100644
index 000000000000..47d1a40ef7c6
--- /dev/null
+++ b/board/theobroma-systems/ringneck_px30/ringneck-px30.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <env.h>
+#include <env_internal.h>
+#include <init.h>
+#include <log.h>
+#include <misc.h>
+#include <spl.h>
+#include <syscon.h>
+#include <u-boot/crc.h>
+#include <usb.h>
+#include <dm/pinctrl.h>
+#include <dm/uclass-internal.h>
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/periph.h>
+#include <asm/arch-rockchip/misc.h>
+#include <power/regulator.h>
+#include <u-boot/sha256.h>
+
+/*
+ * Swap mmc0 and mmc1 in boot_targets if booted from SD-Card.
+ *
+ * If bootsource is uSD-card we can assume that we want to use the
+ * SD-Card instead of the eMMC as first boot_target for distroboot.
+ * We only want to swap the defaults and not any custom environment a
+ * user has set. We exit early if a changed boot_targets environment
+ * is detected.
+ */
+static int setup_boottargets(void)
+{
+ const char *boot_device =
+ ofnode_read_chosen_string("u-boot,spl-boot-device");
+ char *env_default, *env;
+
+ if (!boot_device) {
+ debug("%s: /chosen/u-boot,spl-boot-device not set\n",
+ __func__);
+ return -1;
+ }
+ debug("%s: booted from %s\n", __func__, boot_device);
+
+ env_default = env_get_default("boot_targets");
+ env = env_get("boot_targets");
+ if (!env) {
+ debug("%s: boot_targets does not exist\n", __func__);
+ return -1;
+ }
+ debug("%s: boot_targets current: %s - default: %s\n",
+ __func__, env, env_default);
+
+ if (strcmp(env_default, env) != 0) {
+ debug("%s: boot_targets not default, don't change it\n",
+ __func__);
+ return 0;
+ }
+
+ /*
+ * Make the default boot medium between SD Card and eMMC, the one that
+ * was used to load U-Boot proper.
+ */
+ bool sd_booted = !strcmp(boot_device, "/mmc@ff370000");
+ char *mmc0, *mmc1;
+
+ debug("%s: booted from %s\n", __func__,
+ sd_booted ? "SD-Card" : "eMMC");
+ mmc0 = strstr(env, "mmc0");
+ mmc1 = strstr(env, "mmc1");
+
+ if (!mmc0 || !mmc1) {
+ debug("%s: only one mmc boot_target found\n", __func__);
+ return -1;
+ }
+
+ /*
+ * If mmc0 comes first in the boot order and U-Boot proper was
+ * loaded from mmc1, swap mmc0 and mmc1 in the list.
+ * If mmc1 comes first in the boot order and U-Boot proper was
+ * loaded from mmc0, swap mmc0 and mmc1 in the list.
+ */
+ if ((mmc0 < mmc1 && sd_booted) ||
+ (mmc0 > mmc1 && !sd_booted)) {
+ mmc0[3] = '1';
+ mmc1[3] = '0';
+ debug("%s: set boot_targets to: %s\n", __func__, env);
+ env_set("boot_targets", env);
+ }
+
+ return 0;
+}
+
+int mmc_get_env_dev(void)
+{
+ const char *boot_device =
+ ofnode_read_chosen_string("u-boot,spl-boot-device");
+
+ if (!boot_device) {
+ debug("%s: /chosen/u-boot,spl-boot-device not set\n",
+ __func__);
+ return CONFIG_SYS_MMC_ENV_DEV;
+ }
+
+ debug("%s: booted from %s\n", __func__, boot_device);
+
+ if (!strcmp(boot_device, "/mmc@ff370000"))
+ return 1;
+
+ if (!strcmp(boot_device, "/mmc@ff390000"))
+ return 0;
+
+ return CONFIG_SYS_MMC_ENV_DEV;
+}
+
+#if !IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
+#error Please enable CONFIG_ENV_IS_NOWHERE
+#endif
+
+enum env_location arch_env_get_location(enum env_operation op, int prio)
+{
+ const char *boot_device =
+ ofnode_read_chosen_string("u-boot,spl-boot-device");
+
+ if (prio > 0)
+ return ENVL_UNKNOWN;
+
+ if (!boot_device) {
+ debug("%s: /chosen/u-boot,spl-boot-device not set\n",
+ __func__);
+ return ENVL_NOWHERE;
+ }
+
+ debug("%s: booted from %s\n", __func__, boot_device);
+
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC) &&
+ (!strcmp(boot_device, "/mmc@ff370000") ||
+ !strcmp(boot_device, "/mmc@ff390000")))
+ return ENVL_MMC;
+
+ printf("%s: No environment available: booted from %s but U-Boot "
+ "config does not allow loading environment from it.",
+ __func__, boot_device);
+
+ return ENVL_NOWHERE;
+}
+
+int misc_init_r(void)
+{
+ const u32 cpuid_offset = 0x7;
+ const u32 cpuid_length = 0x10;
+ u8 cpuid[cpuid_length];
+ int ret;
+
+ ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
+ if (ret)
+ return ret;
+
+ ret = rockchip_cpuid_set(cpuid, cpuid_length);
+ if (ret)
+ return ret;
+
+ ret = rockchip_setup_macaddr();
+ if (ret)
+ return ret;
+
+ setup_boottargets();
+
+ return 0;
+}
diff --git a/common/spl/Kconfig.tpl b/common/spl/Kconfig.tpl
index e314b793a2e9..1874f9db4f94 100644
--- a/common/spl/Kconfig.tpl
+++ b/common/spl/Kconfig.tpl
@@ -132,7 +132,7 @@ config TPL_TEXT_BASE
config TPL_MAX_SIZE
hex "Maximum size (in bytes) for the TPL stage"
default 0x2e000 if ROCKCHIP_RK3399
- default 0x8000 if ROCKCHIP_RK3288
+ default 0x8000 if ROCKCHIP_RK3288 || ROCKCHIP_RV1126
default 0x7000 if ROCKCHIP_RK322X || ROCKCHIP_RK3328 || ROCKCHIP_RK3368
default 0x2800 if ROCKCHIP_PX30
default 0x0
diff --git a/configs/khadas-edge-captain-rk3399_defconfig b/configs/khadas-edge-captain-rk3399_defconfig
index 754fd4e3c6d5..f6e90bf392e7 100644
--- a/configs/khadas-edge-captain-rk3399_defconfig
+++ b/configs/khadas-edge-captain-rk3399_defconfig
@@ -53,7 +53,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/khadas-edge-rk3399_defconfig b/configs/khadas-edge-rk3399_defconfig
index 7518f7f2edef..f74963cad6a4 100644
--- a/configs/khadas-edge-rk3399_defconfig
+++ b/configs/khadas-edge-rk3399_defconfig
@@ -52,7 +52,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/khadas-edge-v-rk3399_defconfig b/configs/khadas-edge-v-rk3399_defconfig
index 4c4301a9e7c5..3abfef15fc8a 100644
--- a/configs/khadas-edge-v-rk3399_defconfig
+++ b/configs/khadas-edge-v-rk3399_defconfig
@@ -53,7 +53,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/leez-rk3399_defconfig b/configs/leez-rk3399_defconfig
index 5a958ee36a3f..bee55f8165b7 100644
--- a/configs/leez-rk3399_defconfig
+++ b/configs/leez-rk3399_defconfig
@@ -48,7 +48,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/nanopi-r4s-rk3399_defconfig b/configs/nanopi-r4s-rk3399_defconfig
index 40a45a0f4bbe..0ef5486f82fb 100644
--- a/configs/nanopi-r4s-rk3399_defconfig
+++ b/configs/nanopi-r4s-rk3399_defconfig
@@ -49,7 +49,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/neu2-io-rv1126_defconfig b/configs/neu2-io-rv1126_defconfig
new file mode 100644
index 000000000000..e0816f84394a
--- /dev/null
+++ b/configs/neu2-io-rv1126_defconfig
@@ -0,0 +1,57 @@
+CONFIG_ARM=y
+CONFIG_SPL_SKIP_LOWLEVEL_INIT_ONLY=y
+CONFIG_TPL_SKIP_LOWLEVEL_INIT_ONLY=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_SYS_ARCH_TIMER=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_DEFAULT_DEVICE_TREE="rv1126-edgeble-neu2-io"
+CONFIG_ROCKCHIP_RV1126=y
+CONFIG_TARGET_RV1126_NEU2=y
+CONFIG_DEBUG_UART_BASE=0xff570000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0xe00800
+CONFIG_DEBUG_UART=y
+CONFIG_SYS_MONITOR_LEN=614400
+CONFIG_FIT_VERBOSE=y
+CONFIG_DEFAULT_FDT_FILE="rv1126-edgeble-neu2-io.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_R=y
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_NO_BSS_LIMIT=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+# CONFIG_CMD_BOOTD is not set
+CONFIG_SYS_BOOTM_LEN=0x4000000
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_PWM_ROCKCHIP=y
+# CONFIG_RAM_ROCKCHIP_DEBUG is not set
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYSRESET=y
+# CONFIG_TPL_SYSRESET is not set
+CONFIG_DM_THERMAL=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/pinebook-pro-rk3399_defconfig b/configs/pinebook-pro-rk3399_defconfig
index dfbf5e70f4a1..c885cbaf5a12 100644
--- a/configs/pinebook-pro-rk3399_defconfig
+++ b/configs/pinebook-pro-rk3399_defconfig
@@ -74,7 +74,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_DM_RNG=y
CONFIG_RNG_ROCKCHIP=y
diff --git a/configs/pinephone-pro-rk3399_defconfig b/configs/pinephone-pro-rk3399_defconfig
new file mode 100644
index 000000000000..eb979f6c0513
--- /dev/null
+++ b/configs/pinephone-pro-rk3399_defconfig
@@ -0,0 +1,104 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00200000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x8000
+CONFIG_ENV_OFFSET=0x3F8000
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-pinephone-pro"
+CONFIG_ROCKCHIP_RK3399=y
+CONFIG_TARGET_PINEPHONE_PRO_RK3399=y
+CONFIG_DEBUG_UART_BASE=0xFF1A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_SPI=y
+CONFIG_SYS_LOAD_ADDR=0x800800
+CONFIG_DEBUG_UART=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
+CONFIG_BOOTDELAY=3
+CONFIG_USE_PREBOOT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-pinephone-pro.dtb"
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_R=y
+CONFIG_SPL_MAX_SIZE=0x2e000
+CONFIG_SPL_PAD_TO=0x7f8000
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x400000
+CONFIG_SPL_BSS_MAX_SIZE=0x2000
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x400000
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_SPL_SPI_LOAD=y
+CONFIG_TPL=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_DM_KEYBOARD=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_SF_DEFAULT_BUS=1
+CONFIG_SF_DEFAULT_SPEED=20000000
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_TYPEC=y
+CONFIG_DM_PMIC_FAN53555=y
+CONFIG_DM_REGULATOR_FAN53555=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_DM_RESET=y
+CONFIG_DM_RNG=y
+CONFIG_RNG_ROCKCHIP=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_ROCKCHIP_SPI=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_EDP=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_ERRNO_STR=y
diff --git a/configs/ringneck-px30_defconfig b/configs/ringneck-px30_defconfig
new file mode 100644
index 000000000000..dd332ece7219
--- /dev/null
+++ b/configs/ringneck-px30_defconfig
@@ -0,0 +1,129 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_COUNTER_FREQUENCY=24000000
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_TEXT_BASE=0x00200000
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SPL_GPIO=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_DEFAULT_DEVICE_TREE="px30-ringneck-haikou"
+CONFIG_SPL_TEXT_BASE=0x00000000
+CONFIG_ROCKCHIP_PX30=y
+CONFIG_TARGET_RINGNECK_PX30=y
+CONFIG_TPL_LIBGENERIC_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC=y
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_DEBUG_UART_BASE=0xFF030000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SYS_LOAD_ADDR=0x800800
+CONFIG_TPL_MAX_SIZE=0x20000
+CONFIG_DEBUG_UART=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x400000
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x600
+# CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/px30-ringneck-haikou.dtb"
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_R=y
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_PAD_TO=0x0
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+CONFIG_SPL_BOOTROM_SUPPORT=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x400000
+CONFIG_SPL_STACK_R=y
+CONFIG_SYS_SPL_MALLOC=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x200
+CONFIG_SPL_ATF=y
+# CONFIG_TPL_FRAMEWORK is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_SLEEP is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_NOWHERE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_BUTTON=y
+CONFIG_BUTTON_GPIO=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x800800
+CONFIG_FASTBOOT_BUF_SIZE=0x04000000
+CONFIG_GPIO_HOG=y
+CONFIG_SPL_GPIO_HOG=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_OTP=y
+CONFIG_SUPPORT_EMMC_RPMB=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_PHY_TI_GENERIC=y
+CONFIG_PHY_GIGE=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PINCTRL=y
+CONFIG_SPL_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_TPL_RAM=y
+CONFIG_ROCKCHIP_SDRAM_COMMON=y
+CONFIG_RAM_PX30_DDR4=y
+CONFIG_DM_RESET=y
+CONFIG_DM_RNG=y
+CONFIG_RNG_ROCKCHIP=y
+# CONFIG_SPECIFY_CONSOLE_INDEX is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SYS_NS16550_MEM32=y
+CONFIG_SOUND=y
+CONFIG_SYSRESET=y
+CONFIG_DM_THERMAL=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_TPL_TINY_MEMSET=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig
index 6827c98ed9f1..00239c258242 100644
--- a/configs/roc-pc-mezzanine-rk3399_defconfig
+++ b/configs/roc-pc-mezzanine-rk3399_defconfig
@@ -22,6 +22,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
# CONFIG_ANDROID_BOOT_IMAGE is not set
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-roc-pc-mezzanine.dtb"
CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_R=y
CONFIG_SPL_MAX_SIZE=0x2e000
CONFIG_SPL_PAD_TO=0x7f8000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
@@ -50,6 +51,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
@@ -67,7 +69,7 @@ CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
# CONFIG_RAM_ROCKCHIP_DEBUG is not set
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig
index 3e58db07da67..ed70ce0cddd1 100644
--- a/configs/roc-pc-rk3399_defconfig
+++ b/configs/roc-pc-rk3399_defconfig
@@ -23,6 +23,7 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
CONFIG_USE_PREBOOT=y
CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-roc-pc.dtb"
CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_MISC_INIT_R=y
CONFIG_SPL_MAX_SIZE=0x2e000
CONFIG_SPL_PAD_TO=0x7f8000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
@@ -50,6 +51,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_ROCKCHIP=y
CONFIG_MMC_SDHCI=y
@@ -66,7 +68,7 @@ CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
# CONFIG_RAM_ROCKCHIP_DEBUG is not set
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_DM_RNG=y
CONFIG_RNG_ROCKCHIP=y
diff --git a/configs/rock-pi-4-rk3399_defconfig b/configs/rock-pi-4-rk3399_defconfig
index 7c49ccd064d0..ac182eeef0fb 100644
--- a/configs/rock-pi-4-rk3399_defconfig
+++ b/configs/rock-pi-4-rk3399_defconfig
@@ -64,7 +64,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
diff --git a/configs/rock-pi-4c-rk3399_defconfig b/configs/rock-pi-4c-rk3399_defconfig
index 4f61a0ff661a..292436b6378e 100644
--- a/configs/rock-pi-4c-rk3399_defconfig
+++ b/configs/rock-pi-4c-rk3399_defconfig
@@ -64,7 +64,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_BAUDRATE=1500000
CONFIG_DEBUG_UART_SHIFT=2
diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig
index 5b8d678f6bb5..6422b9fa7f74 100644
--- a/configs/rockpro64-rk3399_defconfig
+++ b/configs/rockpro64-rk3399_defconfig
@@ -71,7 +71,7 @@ CONFIG_PMIC_RK8XX=y
CONFIG_REGULATOR_PWM=y
CONFIG_REGULATOR_RK8XX=y
CONFIG_PWM_ROCKCHIP=y
-CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_RAM_ROCKCHIP_LPDDR4=y
CONFIG_DM_RESET=y
CONFIG_DM_RNG=y
CONFIG_RNG_ROCKCHIP=y
diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst
index 4ca7b00b1fb5..28c837a38200 100644
--- a/doc/board/rockchip/rockchip.rst
+++ b/doc/board/rockchip/rockchip.rst
@@ -27,6 +27,7 @@ List of mainline supported Rockchip boards:
- Engicam PX30.Core C.TOUCH 2.0 10.1 (px30-core-ctouch2-of10-px30)
- Engicam PX30.Core EDIMM2.2 Starter Kit (px30-core-edimm2.2-px30)
- Firefly Core-PX30-JD4 (firefly-px30)
+ - Theobroma Systems PX30-µQ7 SoM - Ringneck (ringneck-px30)
* rk3036
- Rockchip Evb-RK3036 (evb-rk3036)
- Kylin (kylin_rk3036)
@@ -89,6 +90,9 @@ List of mainline supported Rockchip boards:
- Rockchip Evb-rv1108 (evb-rv1108)
- Elgin-R1 (elgin-rv1108)
+* rv1126
+ - Edgeble Neural Compute Module 2 SoM - Neu2/Neu2k (neu2-io-r1126)
+
Building
--------
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index a72d8fe58a6b..f719f4e37914 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o
obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o
obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o
+obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o
diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c
index 5d467447a175..33a7348b9fc9 100644
--- a/drivers/clk/rockchip/clk_px30.c
+++ b/drivers/clk/rockchip/clk_px30.c
@@ -1415,6 +1415,9 @@ static int px30_clk_enable(struct clk *clk)
case SCLK_GMAC_RMII:
/* Required to successfully probe the Designware GMAC driver */
return 0;
+ case PCLK_WDT_NS:
+ /* Required to successfully probe the Designware watchdog driver */
+ return 0;
}
debug("%s: unsupported clk %ld\n", __func__, clk->id);
diff --git a/drivers/clk/rockchip/clk_rv1126.c b/drivers/clk/rockchip/clk_rv1126.c
new file mode 100644
index 000000000000..3ed29364deb8
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rv1126.c
@@ -0,0 +1,1889 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#include <common.h>
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1126.h>
+#include <asm/arch-rockchip/grf_rv1126.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <dm/device-internal.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/rockchip,rv1126-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define RV1126_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \
+{ \
+ .rate = _rate##U, \
+ .aclk_div = _aclk_div, \
+ .pclk_div = _pclk_div, \
+}
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+static struct rockchip_cpu_rate_table rv1126_cpu_rates[] = {
+ RV1126_CPUCLK_RATE(1200000000, 1, 5),
+ RV1126_CPUCLK_RATE(1008000000, 1, 5),
+ RV1126_CPUCLK_RATE(816000000, 1, 3),
+ RV1126_CPUCLK_RATE(600000000, 1, 3),
+ RV1126_CPUCLK_RATE(408000000, 1, 1),
+};
+
+static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
+ /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+ RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+ RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+ RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+ RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+ RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+ RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
+ RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+ RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
+ RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0),
+ RK3036_PLL_RATE(100000000, 1, 100, 6, 4, 1, 0),
+ { /* sentinel */ },
+};
+
+static struct rockchip_pll_clock rv1126_pll_clks[] = {
+ [APLL] = PLL(pll_rk3328, PLL_APLL, RV1126_PLL_CON(0),
+ RV1126_MODE_CON, 0, 10, 0, rv1126_pll_rates),
+ [DPLL] = PLL(pll_rk3328, PLL_DPLL, RV1126_PLL_CON(8),
+ RV1126_MODE_CON, 2, 10, 0, NULL),
+ [CPLL] = PLL(pll_rk3328, PLL_CPLL, RV1126_PLL_CON(16),
+ RV1126_MODE_CON, 4, 10, 0, rv1126_pll_rates),
+ [HPLL] = PLL(pll_rk3328, PLL_HPLL, RV1126_PLL_CON(24),
+ RV1126_MODE_CON, 6, 10, 0, rv1126_pll_rates),
+ [GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1126_PMU_PLL_CON(0),
+ RV1126_PMU_MODE, 0, 10, 0, rv1126_pll_rates),
+};
+
+static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
+ struct rv1126_pmuclk_priv *pmu_priv,
+ ulong rate);
+/*
+ *
+ * rational_best_approximation(31415, 10000,
+ * (1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+ unsigned long given_denominator,
+ unsigned long max_numerator,
+ unsigned long max_denominator,
+ unsigned long *best_numerator,
+ unsigned long *best_denominator)
+{
+ unsigned long n, d, n0, d0, n1, d1;
+
+ n = given_numerator;
+ d = given_denominator;
+ n0 = 0;
+ d1 = 0;
+ n1 = 1;
+ d0 = 1;
+ for (;;) {
+ unsigned long t, a;
+
+ if (n1 > max_numerator || d1 > max_denominator) {
+ n1 = n0;
+ d1 = d0;
+ break;
+ }
+ if (d == 0)
+ break;
+ t = d;
+ a = n / d;
+ d = n % d;
+ n = t;
+ t = n0 + a * n1;
+ n0 = n1;
+ n1 = t;
+ t = d0 + a * d1;
+ d0 = d1;
+ d1 = t;
+ }
+ *best_numerator = n1;
+ *best_denominator = d1;
+}
+
+static ulong rv1126_gpll_get_pmuclk(struct rv1126_pmuclk_priv *priv)
+{
+ return rockchip_pll_get_rate(&rv1126_pll_clks[GPLL],
+ priv->pmucru, GPLL);
+}
+
+static ulong rv1126_gpll_set_pmuclk(struct rv1126_pmuclk_priv *pmu_priv, ulong rate)
+{
+ struct udevice *cru_dev;
+ struct rv1126_clk_priv *priv;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rv1126_cru),
+ &cru_dev);
+ if (ret) {
+ printf("%s: could not find cru device\n", __func__);
+ return ret;
+ }
+ priv = dev_get_priv(cru_dev);
+
+ if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
+ printf("%s: failed to set gpll rate %lu\n", __func__, rate);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static ulong rv1126_rtc32k_get_pmuclk(struct rv1126_pmuclk_priv *priv)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ unsigned long m, n;
+ u32 fracdiv;
+
+ fracdiv = readl(&pmucru->pmu_clksel_con[13]);
+ m = fracdiv & CLK_RTC32K_FRAC_NUMERATOR_MASK;
+ m >>= CLK_RTC32K_FRAC_NUMERATOR_SHIFT;
+ n = fracdiv & CLK_RTC32K_FRAC_DENOMINATOR_MASK;
+ n >>= CLK_RTC32K_FRAC_DENOMINATOR_SHIFT;
+
+ return OSC_HZ * m / n;
+}
+
+static ulong rv1126_rtc32k_set_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong rate)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ unsigned long m, n, val;
+
+ rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
+ RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
+
+ rational_best_approximation(rate, OSC_HZ,
+ GENMASK(16 - 1, 0),
+ GENMASK(16 - 1, 0),
+ &m, &n);
+ val = m << CLK_RTC32K_FRAC_NUMERATOR_SHIFT | n;
+ writel(val, &pmucru->pmu_clksel_con[13]);
+
+ return rv1126_rtc32k_get_pmuclk(priv);
+}
+
+static ulong rv1126_i2c_get_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong clk_id)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ u32 div, con;
+
+ switch (clk_id) {
+ case CLK_I2C0:
+ con = readl(&pmucru->pmu_clksel_con[2]);
+ div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
+ break;
+ case CLK_I2C2:
+ con = readl(&pmucru->pmu_clksel_con[3]);
+ div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_i2c_set_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+
+ switch (clk_id) {
+ case CLK_I2C0:
+ rk_clrsetreg(&pmucru->pmu_clksel_con[2], CLK_I2C0_DIV_MASK,
+ (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
+ break;
+ case CLK_I2C2:
+ rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C2_DIV_MASK,
+ (src_clk_div - 1) << CLK_I2C2_DIV_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1126_i2c_get_pmuclk(priv, clk_id);
+}
+
+static ulong rv1126_pwm_get_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong clk_id)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ u32 div, sel, con;
+
+ switch (clk_id) {
+ case CLK_PWM0:
+ con = readl(&pmucru->pmu_clksel_con[6]);
+ sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
+ div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
+ if (sel == CLK_PWM0_SEL_XIN24M)
+ return OSC_HZ;
+ break;
+ case CLK_PWM1:
+ con = readl(&pmucru->pmu_clksel_con[6]);
+ sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
+ div = (con & CLK_PWM1_DIV_MASK) >> CLK_PWM1_DIV_SHIFT;
+ if (sel == CLK_PWM1_SEL_XIN24M)
+ return OSC_HZ;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_pwm_set_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong clk_id, ulong rate)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ int src_clk_div;
+
+ switch (clk_id) {
+ case CLK_PWM0:
+ if (rate == OSC_HZ) {
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM0_SEL_MASK,
+ CLK_PWM0_SEL_XIN24M << CLK_PWM0_SEL_SHIFT);
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM0_DIV_MASK, 0);
+ } else {
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM0_DIV_MASK,
+ (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM0_SEL_MASK,
+ CLK_PWM0_SEL_GPLL << CLK_PWM0_SEL_SHIFT);
+ }
+ break;
+ case CLK_PWM1:
+ if (rate == OSC_HZ) {
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM1_SEL_MASK,
+ CLK_PWM1_SEL_XIN24M << CLK_PWM1_SEL_SHIFT);
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM1_DIV_MASK, 0);
+ } else {
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM1_DIV_MASK,
+ (src_clk_div - 1) << CLK_PWM1_DIV_SHIFT);
+ rk_clrsetreg(&pmucru->pmu_clksel_con[6],
+ CLK_PWM1_SEL_MASK,
+ CLK_PWM1_SEL_GPLL << CLK_PWM1_SEL_SHIFT);
+ }
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1126_pwm_get_pmuclk(priv, clk_id);
+}
+
+static ulong rv1126_spi_get_pmuclk(struct rv1126_pmuclk_priv *priv)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ u32 div, con;
+
+ con = readl(&pmucru->pmu_clksel_con[9]);
+ div = (con & CLK_SPI0_DIV_MASK) >> CLK_SPI0_DIV_SHIFT;
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_spi_set_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong rate)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+
+ rk_clrsetreg(&pmucru->pmu_clksel_con[9],
+ CLK_SPI0_SEL_MASK | CLK_SPI0_DIV_MASK,
+ CLK_SPI0_SEL_GPLL << CLK_SPI0_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_SPI0_DIV_SHIFT);
+
+ return rv1126_spi_get_pmuclk(priv);
+}
+
+static ulong rv1126_pdpmu_get_pmuclk(struct rv1126_pmuclk_priv *priv)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ u32 div, con;
+
+ con = readl(&pmucru->pmu_clksel_con[1]);
+ div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_pdpmu_set_pmuclk(struct rv1126_pmuclk_priv *priv,
+ ulong rate)
+{
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+
+ rk_clrsetreg(&pmucru->pmu_clksel_con[1],
+ PCLK_PDPMU_DIV_MASK,
+ (src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT);
+
+ return rv1126_pdpmu_get_pmuclk(priv);
+}
+
+static ulong rv1126_pmuclk_get_rate(struct clk *clk)
+{
+ struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ if (!priv->gpll_hz) {
+ printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+ return -ENOENT;
+ }
+
+ debug("%s %ld\n", __func__, clk->id);
+ switch (clk->id) {
+ case PLL_GPLL:
+ rate = rv1126_gpll_get_pmuclk(priv);
+ break;
+ case CLK_RTC32K:
+ rate = rv1126_rtc32k_get_pmuclk(priv);
+ break;
+ case CLK_I2C0:
+ case CLK_I2C2:
+ rate = rv1126_i2c_get_pmuclk(priv, clk->id);
+ break;
+ case CLK_PWM0:
+ case CLK_PWM1:
+ rate = rv1126_pwm_get_pmuclk(priv, clk->id);
+ break;
+ case CLK_SPI0:
+ rate = rv1126_spi_get_pmuclk(priv);
+ break;
+ case PCLK_PDPMU:
+ rate = rv1126_pdpmu_get_pmuclk(priv);
+ break;
+ default:
+ debug("%s: Unsupported CLK#%ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static ulong rv1126_pmuclk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
+ ulong ret = 0;
+
+ if (!priv->gpll_hz) {
+ printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+ return -ENOENT;
+ }
+
+ debug("%s %ld %ld\n", __func__, clk->id, rate);
+ switch (clk->id) {
+ case PLL_GPLL:
+ ret = rv1126_gpll_set_pmuclk(priv, rate);
+ break;
+ case CLK_RTC32K:
+ ret = rv1126_rtc32k_set_pmuclk(priv, rate);
+ break;
+ case CLK_I2C0:
+ case CLK_I2C2:
+ ret = rv1126_i2c_set_pmuclk(priv, clk->id, rate);
+ break;
+ case CLK_PWM0:
+ case CLK_PWM1:
+ ret = rv1126_pwm_set_pmuclk(priv, clk->id, rate);
+ break;
+ case CLK_SPI0:
+ ret = rv1126_spi_set_pmuclk(priv, rate);
+ break;
+ case PCLK_PDPMU:
+ ret = rv1126_pdpmu_set_pmuclk(priv, rate);
+ break;
+ default:
+ debug("%s: Unsupported CLK#%ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return ret;
+}
+
+static int rv1126_rtc32k_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct rv1126_pmuclk_priv *priv = dev_get_priv(clk->dev);
+ struct rv1126_pmucru *pmucru = priv->pmucru;
+
+ if (parent->id == CLK_OSC0_DIV32K)
+ rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
+ RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
+ else
+ rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
+ RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
+
+ return 0;
+}
+
+static int rv1126_pmuclk_set_parent(struct clk *clk, struct clk *parent)
+{
+ switch (clk->id) {
+ case CLK_RTC32K:
+ return rv1126_rtc32k_set_parent(clk, parent);
+ default:
+ debug("%s: Unsupported CLK#%ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+}
+
+static struct clk_ops rv1126_pmuclk_ops = {
+ .get_rate = rv1126_pmuclk_get_rate,
+ .set_rate = rv1126_pmuclk_set_rate,
+ .set_parent = rv1126_pmuclk_set_parent,
+};
+
+static int rv1126_pmuclk_probe(struct udevice *dev)
+{
+ struct rv1126_pmuclk_priv *priv = dev_get_priv(dev);
+
+ priv->gpll_hz = rv1126_gpll_get_pmuclk(priv);
+
+ return 0;
+}
+
+static int rv1126_pmuclk_of_to_plat(struct udevice *dev)
+{
+ struct rv1126_pmuclk_priv *priv = dev_get_priv(dev);
+
+ priv->pmucru = dev_read_addr_ptr(dev);
+
+ return 0;
+}
+
+static int rv1126_pmuclk_bind(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+ int ret;
+
+ ret = offsetof(struct rv1126_pmucru, pmu_softrst_con[0]);
+ ret = rockchip_reset_bind(dev, ret, 2);
+ if (ret)
+ debug("Warning: software reset driver bind faile\n");
+#endif
+ return 0;
+}
+
+static const struct udevice_id rv1126_pmuclk_ids[] = {
+ { .compatible = "rockchip,rv1126-pmucru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rv1126_pmucru) = {
+ .name = "rockchip_rv1126_pmucru",
+ .id = UCLASS_CLK,
+ .of_match = rv1126_pmuclk_ids,
+ .priv_auto = sizeof(struct rv1126_pmuclk_priv),
+ .of_to_plat = rv1126_pmuclk_of_to_plat,
+ .ops = &rv1126_pmuclk_ops,
+ .bind = rv1126_pmuclk_bind,
+ .probe = rv1126_pmuclk_probe,
+};
+
+static int rv1126_armclk_set_clk(struct rv1126_clk_priv *priv, ulong hz)
+{
+ struct rv1126_cru *cru = priv->cru;
+ const struct rockchip_cpu_rate_table *rate;
+ ulong old_rate;
+
+ rate = rockchip_get_cpu_settings(rv1126_cpu_rates, hz);
+ if (!rate) {
+ printf("%s unsupported rate\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * set up dependent divisors for DBG and ACLK clocks.
+ */
+ old_rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
+ priv->cru, APLL);
+ if (old_rate > hz) {
+ if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL],
+ priv->cru, APLL, hz))
+ return -EINVAL;
+ rk_clrsetreg(&cru->clksel_con[1],
+ CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK,
+ rate->pclk_div << CORE_DBG_DIV_SHIFT |
+ rate->aclk_div << CORE_ACLK_DIV_SHIFT);
+ } else if (old_rate < hz) {
+ rk_clrsetreg(&cru->clksel_con[1],
+ CORE_DBG_DIV_MASK | CORE_ACLK_DIV_MASK,
+ rate->pclk_div << CORE_DBG_DIV_SHIFT |
+ rate->aclk_div << CORE_ACLK_DIV_SHIFT);
+ if (rockchip_pll_set_rate(&rv1126_pll_clks[APLL],
+ priv->cru, APLL, hz))
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static ulong rv1126_pdcore_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 con, div;
+
+ con = readl(&cru->clksel_con[0]);
+ div = (con & CORE_HCLK_DIV_MASK) >> CORE_HCLK_DIV_SHIFT;
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_pdcore_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+
+ rk_clrsetreg(&cru->clksel_con[0], CORE_HCLK_DIV_MASK,
+ (src_clk_div - 1) << CORE_HCLK_DIV_SHIFT);
+
+ return rv1126_pdcore_get_clk(priv);
+}
+
+static ulong rv1126_pdbus_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 con, div, sel, parent;
+
+ switch (clk_id) {
+ case ACLK_PDBUS:
+ con = readl(&cru->clksel_con[2]);
+ div = (con & ACLK_PDBUS_DIV_MASK) >> ACLK_PDBUS_DIV_SHIFT;
+ sel = (con & ACLK_PDBUS_SEL_MASK) >> ACLK_PDBUS_SEL_SHIFT;
+ if (sel == ACLK_PDBUS_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == ACLK_PDBUS_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+ break;
+ case HCLK_PDBUS:
+ con = readl(&cru->clksel_con[2]);
+ div = (con & HCLK_PDBUS_DIV_MASK) >> HCLK_PDBUS_DIV_SHIFT;
+ sel = (con & HCLK_PDBUS_SEL_MASK) >> HCLK_PDBUS_SEL_SHIFT;
+ if (sel == HCLK_PDBUS_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == HCLK_PDBUS_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+ break;
+ case PCLK_PDBUS:
+ case PCLK_WDT:
+ con = readl(&cru->clksel_con[3]);
+ div = (con & PCLK_PDBUS_DIV_MASK) >> PCLK_PDBUS_DIV_SHIFT;
+ sel = (con & PCLK_PDBUS_SEL_MASK) >> PCLK_PDBUS_SEL_SHIFT;
+ if (sel == PCLK_PDBUS_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == PCLK_PDBUS_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_pdbus_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div, clk_sel;
+
+ switch (clk_id) {
+ case ACLK_PDBUS:
+ if (CPLL_HZ % rate) {
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ clk_sel = ACLK_PDBUS_SEL_GPLL;
+ } else {
+ src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
+ clk_sel = ACLK_PDBUS_SEL_CPLL;
+ }
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[2],
+ ACLK_PDBUS_SEL_MASK | ACLK_PDBUS_DIV_MASK,
+ clk_sel << ACLK_PDBUS_SEL_SHIFT |
+ (src_clk_div - 1) << ACLK_PDBUS_DIV_SHIFT);
+ break;
+ case HCLK_PDBUS:
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[2],
+ HCLK_PDBUS_SEL_MASK | HCLK_PDBUS_DIV_MASK,
+ HCLK_PDBUS_SEL_GPLL << HCLK_PDBUS_SEL_SHIFT |
+ (src_clk_div - 1) << HCLK_PDBUS_DIV_SHIFT);
+ break;
+ case PCLK_PDBUS:
+ case PCLK_WDT:
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[3],
+ PCLK_PDBUS_SEL_MASK | PCLK_PDBUS_DIV_MASK,
+ PCLK_PDBUS_SEL_GPLL << PCLK_PDBUS_SEL_SHIFT |
+ (src_clk_div - 1) << PCLK_PDBUS_DIV_SHIFT);
+ break;
+
+ default:
+ printf("do not support this pdbus freq\n");
+ return -EINVAL;
+ }
+
+ return rv1126_pdbus_get_clk(priv, clk_id);
+}
+
+static ulong rv1126_pdphp_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 con, div, parent;
+
+ switch (clk_id) {
+ case ACLK_PDPHP:
+ con = readl(&cru->clksel_con[53]);
+ div = (con & ACLK_PDPHP_DIV_MASK) >> ACLK_PDPHP_DIV_SHIFT;
+ parent = priv->gpll_hz;
+ break;
+ case HCLK_PDPHP:
+ con = readl(&cru->clksel_con[53]);
+ div = (con & HCLK_PDPHP_DIV_MASK) >> HCLK_PDPHP_DIV_SHIFT;
+ parent = priv->gpll_hz;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_pdphp_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+
+ switch (clk_id) {
+ case ACLK_PDPHP:
+ rk_clrsetreg(&cru->clksel_con[53],
+ ACLK_PDPHP_SEL_MASK | ACLK_PDPHP_DIV_MASK,
+ ACLK_PDPHP_SEL_GPLL << ACLK_PDPHP_SEL_SHIFT |
+ (src_clk_div - 1) << ACLK_PDPHP_DIV_SHIFT);
+ break;
+ case HCLK_PDPHP:
+ rk_clrsetreg(&cru->clksel_con[53],
+ HCLK_PDPHP_DIV_MASK,
+ (src_clk_div - 1) << HCLK_PDPHP_DIV_SHIFT);
+ break;
+ default:
+ printf("do not support this pdphp freq\n");
+ return -EINVAL;
+ }
+
+ return rv1126_pdphp_get_clk(priv, clk_id);
+}
+
+static ulong rv1126_pdaudio_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 con, div;
+
+ con = readl(&cru->clksel_con[26]);
+ div = (con & HCLK_PDAUDIO_DIV_MASK) >> HCLK_PDAUDIO_DIV_SHIFT;
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_pdaudio_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+
+ rk_clrsetreg(&cru->clksel_con[26], HCLK_PDAUDIO_DIV_MASK,
+ (src_clk_div - 1) << HCLK_PDAUDIO_DIV_SHIFT);
+
+ return rv1126_pdaudio_get_clk(priv);
+}
+
+static ulong rv1126_i2c_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, con;
+
+ switch (clk_id) {
+ case CLK_I2C1:
+ con = readl(&cru->clksel_con[5]);
+ div = (con & CLK_I2C1_DIV_MASK) >> CLK_I2C1_DIV_SHIFT;
+ break;
+ case CLK_I2C3:
+ con = readl(&cru->clksel_con[5]);
+ div = (con & CLK_I2C3_DIV_MASK) >> CLK_I2C3_DIV_SHIFT;
+ break;
+ case CLK_I2C4:
+ con = readl(&cru->clksel_con[6]);
+ div = (con & CLK_I2C4_DIV_MASK) >> CLK_I2C4_DIV_SHIFT;
+ break;
+ case CLK_I2C5:
+ con = readl(&cru->clksel_con[6]);
+ div = (con & CLK_I2C5_DIV_MASK) >> CLK_I2C5_DIV_SHIFT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_i2c_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+
+ switch (clk_id) {
+ case CLK_I2C1:
+ rk_clrsetreg(&cru->clksel_con[5], CLK_I2C1_DIV_MASK,
+ (src_clk_div - 1) << CLK_I2C1_DIV_SHIFT);
+ break;
+ case CLK_I2C3:
+ rk_clrsetreg(&cru->clksel_con[5], CLK_I2C3_DIV_MASK,
+ (src_clk_div - 1) << CLK_I2C3_DIV_SHIFT);
+ break;
+ case CLK_I2C4:
+ rk_clrsetreg(&cru->clksel_con[6], CLK_I2C4_DIV_MASK,
+ (src_clk_div - 1) << CLK_I2C4_DIV_SHIFT);
+ break;
+ case CLK_I2C5:
+ rk_clrsetreg(&cru->clksel_con[6], CLK_I2C5_DIV_MASK,
+ (src_clk_div - 1) << CLK_I2C5_DIV_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1126_i2c_get_clk(priv, clk_id);
+}
+
+static ulong rv1126_spi_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, con;
+
+ con = readl(&cru->clksel_con[8]);
+ div = (con & CLK_SPI1_DIV_MASK) >> CLK_SPI1_DIV_SHIFT;
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_spi_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+
+ rk_clrsetreg(&cru->clksel_con[8],
+ CLK_SPI1_SEL_MASK | CLK_SPI1_DIV_MASK,
+ CLK_SPI1_SEL_GPLL << CLK_SPI1_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_SPI1_DIV_SHIFT);
+
+ return rv1126_spi_get_clk(priv);
+}
+
+static ulong rv1126_pwm_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con;
+
+ con = readl(&cru->clksel_con[9]);
+ sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
+ div = (con & CLK_PWM2_DIV_MASK) >> CLK_PWM2_DIV_SHIFT;
+ if (sel == CLK_PWM2_SEL_XIN24M)
+ return OSC_HZ;
+
+ return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong rv1126_pwm_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ if (rate == OSC_HZ) {
+ rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
+ CLK_PWM2_SEL_XIN24M << CLK_PWM2_SEL_SHIFT);
+ rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK, 0);
+ } else {
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+ rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_DIV_MASK,
+ (src_clk_div - 1) << CLK_PWM2_DIV_SHIFT);
+ rk_clrsetreg(&cru->clksel_con[9], CLK_PWM2_SEL_MASK,
+ CLK_PWM2_SEL_GPLL << CLK_PWM2_SEL_SHIFT);
+ }
+
+ return rv1126_pwm_get_clk(priv);
+}
+
+static ulong rv1126_saradc_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, con;
+
+ con = readl(&cru->clksel_con[20]);
+ div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
+
+ return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong rv1126_saradc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(OSC_HZ, rate);
+ assert(src_clk_div - 1 <= 2047);
+ rk_clrsetreg(&cru->clksel_con[20], CLK_SARADC_DIV_MASK,
+ (src_clk_div - 1) << CLK_SARADC_DIV_SHIFT);
+
+ return rv1126_saradc_get_clk(priv);
+}
+
+static ulong rv1126_crypto_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ switch (clk_id) {
+ case CLK_CRYPTO_CORE:
+ con = readl(&cru->clksel_con[7]);
+ div = (con & CLK_CRYPTO_CORE_DIV_MASK) >> CLK_CRYPTO_CORE_DIV_SHIFT;
+ sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT;
+ if (sel == CLK_CRYPTO_CORE_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == CLK_CRYPTO_CORE_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+ break;
+ case CLK_CRYPTO_PKA:
+ con = readl(&cru->clksel_con[7]);
+ div = (con & CLK_CRYPTO_PKA_DIV_MASK) >> CLK_CRYPTO_PKA_DIV_SHIFT;
+ sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT;
+ if (sel == CLK_CRYPTO_PKA_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == CLK_CRYPTO_PKA_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+ break;
+ case ACLK_CRYPTO:
+ con = readl(&cru->clksel_con[4]);
+ div = (con & ACLK_CRYPTO_DIV_MASK) >> ACLK_CRYPTO_DIV_SHIFT;
+ sel = (con & ACLK_CRYPTO_SEL_MASK) >> ACLK_CRYPTO_SEL_SHIFT;
+ if (sel == ACLK_CRYPTO_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == ACLK_CRYPTO_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_crypto_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+
+ switch (clk_id) {
+ case CLK_CRYPTO_CORE:
+ rk_clrsetreg(&cru->clksel_con[7],
+ CLK_CRYPTO_CORE_SEL_MASK |
+ CLK_CRYPTO_CORE_DIV_MASK,
+ CLK_CRYPTO_CORE_SEL_GPLL <<
+ CLK_CRYPTO_CORE_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_CRYPTO_CORE_DIV_SHIFT);
+ break;
+ case CLK_CRYPTO_PKA:
+ rk_clrsetreg(&cru->clksel_con[7],
+ CLK_CRYPTO_PKA_SEL_MASK |
+ CLK_CRYPTO_PKA_DIV_MASK,
+ CLK_CRYPTO_PKA_SEL_GPLL <<
+ CLK_CRYPTO_PKA_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_CRYPTO_PKA_DIV_SHIFT);
+ break;
+ case ACLK_CRYPTO:
+ rk_clrsetreg(&cru->clksel_con[4],
+ ACLK_CRYPTO_SEL_MASK | ACLK_CRYPTO_DIV_MASK,
+ ACLK_CRYPTO_SEL_GPLL << ACLK_CRYPTO_SEL_SHIFT |
+ (src_clk_div - 1) << ACLK_CRYPTO_DIV_SHIFT);
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ return rv1126_crypto_get_clk(priv, clk_id);
+}
+
+static ulong rv1126_mmc_get_clk(struct rv1126_clk_priv *priv, ulong clk_id)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, con_id;
+
+ switch (clk_id) {
+ case HCLK_SDMMC:
+ case CLK_SDMMC:
+ con_id = 55;
+ break;
+ case HCLK_SDIO:
+ case CLK_SDIO:
+ con_id = 56;
+ break;
+ case HCLK_EMMC:
+ case CLK_EMMC:
+ case SCLK_EMMC_SAMPLE:
+ con_id = 57;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ con = readl(&cru->clksel_con[con_id]);
+ div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
+ sel = (con & EMMC_SEL_MASK) >> EMMC_SEL_SHIFT;
+ if (sel == EMMC_SEL_GPLL)
+ return DIV_TO_RATE(priv->gpll_hz, div) / 2;
+ else if (sel == EMMC_SEL_CPLL)
+ return DIV_TO_RATE(priv->cpll_hz, div) / 2;
+ else if (sel == EMMC_SEL_XIN24M)
+ return DIV_TO_RATE(OSC_HZ, div) / 2;
+
+ return -ENOENT;
+}
+
+static ulong rv1126_mmc_set_clk(struct rv1126_clk_priv *priv, ulong clk_id,
+ ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+ u32 con_id;
+
+ switch (clk_id) {
+ case HCLK_SDMMC:
+ case CLK_SDMMC:
+ con_id = 55;
+ break;
+ case HCLK_SDIO:
+ case CLK_SDIO:
+ con_id = 56;
+ break;
+ case HCLK_EMMC:
+ case CLK_EMMC:
+ con_id = 57;
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ /* Select clk_sdmmc/emmc source from GPLL by default */
+ /* mmc clock defaulg div 2 internal, need provide double in cru */
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, rate);
+
+ if (src_clk_div > 127) {
+ /* use 24MHz source for 400KHz clock */
+ src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, rate);
+ rk_clrsetreg(&cru->clksel_con[con_id],
+ EMMC_SEL_MASK | EMMC_DIV_MASK,
+ EMMC_SEL_XIN24M << EMMC_SEL_SHIFT |
+ (src_clk_div - 1) << EMMC_DIV_SHIFT);
+ } else {
+ rk_clrsetreg(&cru->clksel_con[con_id],
+ EMMC_SEL_MASK | EMMC_DIV_MASK,
+ EMMC_SEL_GPLL << EMMC_SEL_SHIFT |
+ (src_clk_div - 1) << EMMC_DIV_SHIFT);
+ }
+
+ return rv1126_mmc_get_clk(priv, clk_id);
+}
+
+static ulong rv1126_sfc_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[58]);
+ div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
+ sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
+ if (sel == SCLK_SFC_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == SCLK_SFC_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_sfc_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ rk_clrsetreg(&cru->clksel_con[58],
+ SCLK_SFC_SEL_MASK | SCLK_SFC_DIV_MASK,
+ SCLK_SFC_SEL_GPLL << SCLK_SFC_SEL_SHIFT |
+ (src_clk_div - 1) << SCLK_SFC_DIV_SHIFT);
+
+ return rv1126_sfc_get_clk(priv);
+}
+
+static ulong rv1126_nand_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[59]);
+ div = (con & CLK_NANDC_DIV_MASK) >> CLK_NANDC_DIV_SHIFT;
+ sel = (con & CLK_NANDC_SEL_MASK) >> CLK_NANDC_SEL_SHIFT;
+ if (sel == CLK_NANDC_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == CLK_NANDC_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_nand_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ rk_clrsetreg(&cru->clksel_con[59],
+ CLK_NANDC_SEL_MASK | CLK_NANDC_DIV_MASK,
+ CLK_NANDC_SEL_GPLL << CLK_NANDC_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_NANDC_DIV_SHIFT);
+
+ return rv1126_nand_get_clk(priv);
+}
+
+static ulong rv1126_aclk_vop_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[45]);
+ div = (con & ACLK_PDVO_DIV_MASK) >> ACLK_PDVO_DIV_SHIFT;
+ sel = (con & ACLK_PDVO_SEL_MASK) >> ACLK_PDVO_SEL_SHIFT;
+ if (sel == ACLK_PDVO_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == ACLK_PDVO_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_aclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[45],
+ ACLK_PDVO_SEL_MASK | ACLK_PDVO_DIV_MASK,
+ ACLK_PDVO_SEL_GPLL << ACLK_PDVO_SEL_SHIFT |
+ (src_clk_div - 1) << ACLK_PDVO_DIV_SHIFT);
+
+ return rv1126_aclk_vop_get_clk(priv);
+}
+
+static ulong rv1126_dclk_vop_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[47]);
+ div = (con & DCLK_VOP_DIV_MASK) >> DCLK_VOP_DIV_SHIFT;
+ sel = (con & DCLK_VOP_SEL_MASK) >> DCLK_VOP_SEL_SHIFT;
+ if (sel == DCLK_VOP_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == DCLK_VOP_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_dclk_vop_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ ulong pll_rate, now, best_rate = 0;
+ u32 i, div, best_div = 0, best_sel = 0;
+
+ for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) {
+ switch (i) {
+ case DCLK_VOP_SEL_GPLL:
+ pll_rate = priv->gpll_hz;
+ break;
+ case DCLK_VOP_SEL_CPLL:
+ pll_rate = priv->cpll_hz;
+ break;
+ default:
+ printf("do not support this vop pll sel\n");
+ return -EINVAL;
+ }
+
+ div = DIV_ROUND_UP(pll_rate, rate);
+ if (div > 255)
+ continue;
+ now = pll_rate / div;
+ if (abs(rate - now) < abs(rate - best_rate)) {
+ best_rate = now;
+ best_div = div;
+ best_sel = i;
+ }
+ debug("pll_rate=%lu, best_rate=%lu, best_div=%u, best_sel=%u\n",
+ pll_rate, best_rate, best_div, best_sel);
+ }
+
+ if (best_rate) {
+ rk_clrsetreg(&cru->clksel_con[47],
+ DCLK_VOP_SEL_MASK | DCLK_VOP_DIV_MASK,
+ best_sel << DCLK_VOP_SEL_SHIFT |
+ (best_div - 1) << DCLK_VOP_DIV_SHIFT);
+ } else {
+ printf("do not support this vop freq %lu\n", rate);
+ return -EINVAL;
+ }
+
+ return rv1126_dclk_vop_get_clk(priv);
+}
+
+static ulong rv1126_scr1_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[3]);
+ div = (con & CLK_SCR1_DIV_MASK) >> CLK_SCR1_DIV_SHIFT;
+ sel = (con & CLK_SCR1_SEL_MASK) >> CLK_SCR1_SEL_SHIFT;
+ if (sel == CLK_SCR1_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == CLK_SCR1_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_scr1_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[3],
+ CLK_SCR1_SEL_MASK | CLK_SCR1_DIV_MASK,
+ CLK_SCR1_SEL_GPLL << CLK_SCR1_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_SCR1_DIV_SHIFT);
+
+ return rv1126_scr1_get_clk(priv);
+}
+
+static ulong rv1126_gmac_src_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[63]);
+ div = (con & CLK_GMAC_SRC_DIV_MASK) >> CLK_GMAC_SRC_DIV_SHIFT;
+ sel = (con & CLK_GMAC_SRC_SEL_MASK) >> CLK_GMAC_SRC_SEL_SHIFT;
+ if (sel == CLK_GMAC_SRC_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else if (sel == CLK_GMAC_SRC_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_gmac_src_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[63],
+ CLK_GMAC_SRC_SEL_MASK | CLK_GMAC_SRC_DIV_MASK,
+ CLK_GMAC_SRC_SEL_CPLL << CLK_GMAC_SRC_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_GMAC_SRC_DIV_SHIFT);
+
+ return rv1126_gmac_src_get_clk(priv);
+}
+
+static ulong rv1126_gmac_out_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[61]);
+ div = (con & CLK_GMAC_OUT_DIV_MASK) >> CLK_GMAC_OUT_DIV_SHIFT;
+ sel = (con & CLK_GMAC_OUT_SEL_MASK) >> CLK_GMAC_OUT_SEL_SHIFT;
+ if (sel == CLK_GMAC_OUT_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else if (sel == CLK_GMAC_OUT_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_gmac_out_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate);
+ assert(src_clk_div - 1 <= 31);
+ rk_clrsetreg(&cru->clksel_con[61],
+ CLK_GMAC_OUT_SEL_MASK | CLK_GMAC_OUT_DIV_MASK,
+ CLK_GMAC_OUT_SEL_CPLL << CLK_GMAC_OUT_SEL_SHIFT |
+ (src_clk_div - 1) << CLK_GMAC_OUT_DIV_SHIFT);
+
+ return rv1126_gmac_out_get_clk(priv);
+}
+
+static ulong rv1126_gmac_tx_rx_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 con, sel, div_sel;
+
+ con = readl(&cru->gmac_con);
+ sel = (con & GMAC_MODE_SEL_MASK) >> GMAC_MODE_SEL_SHIFT;
+
+ if (sel == GMAC_RGMII_MODE) {
+ if (rate == 2500000)
+ div_sel = RGMII_CLK_DIV50;
+ else if (rate == 25000000)
+ div_sel = RGMII_CLK_DIV5;
+ else
+ div_sel = RGMII_CLK_DIV0;
+ rk_clrsetreg(&cru->gmac_con, RGMII_CLK_SEL_MASK,
+ div_sel << RGMII_CLK_SEL_SHIFT);
+ } else if (sel == GMAC_RMII_MODE) {
+ if (rate == 2500000)
+ div_sel = RMII_CLK_DIV20;
+ else
+ div_sel = RMII_CLK_DIV2;
+ rk_clrsetreg(&cru->gmac_con, RMII_CLK_SEL_MASK,
+ div_sel << RMII_CLK_SEL_SHIFT);
+ }
+
+ return 0;
+}
+
+static ulong rv1126_pclk_gmac_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, con, parent;
+
+ parent = rv1126_pdphp_get_clk(priv, ACLK_PDPHP);
+
+ con = readl(&cru->clksel_con[63]);
+ div = (con & PCLK_GMAC_DIV_MASK) >> PCLK_GMAC_DIV_SHIFT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_dclk_decom_get_clk(struct rv1126_clk_priv *priv)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 div, sel, con, parent;
+
+ con = readl(&cru->clksel_con[25]);
+ div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
+ sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT;
+ if (sel == DCLK_DECOM_SEL_GPLL)
+ parent = priv->gpll_hz;
+ else if (sel == DCLK_DECOM_SEL_CPLL)
+ parent = priv->cpll_hz;
+ else
+ return -ENOENT;
+
+ return DIV_TO_RATE(parent, div);
+}
+
+static ulong rv1126_dclk_decom_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct rv1126_cru *cru = priv->cru;
+ u32 src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate);
+ assert(src_clk_div - 1 <= 127);
+ rk_clrsetreg(&cru->clksel_con[25],
+ DCLK_DECOM_SEL_MASK | DCLK_DECOM_DIV_MASK,
+ DCLK_DECOM_SEL_GPLL << DCLK_DECOM_SEL_SHIFT |
+ (src_clk_div - 1) << DCLK_DECOM_DIV_SHIFT);
+
+ return rv1126_dclk_decom_get_clk(priv);
+}
+
+static ulong rv1126_clk_get_rate(struct clk *clk)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ if (!priv->gpll_hz) {
+ printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+ return -ENOENT;
+ }
+
+ switch (clk->id) {
+ case PLL_APLL:
+ case ARMCLK:
+ rate = rockchip_pll_get_rate(&rv1126_pll_clks[APLL], priv->cru,
+ APLL);
+ break;
+ case PLL_CPLL:
+ rate = rockchip_pll_get_rate(&rv1126_pll_clks[CPLL], priv->cru,
+ CPLL);
+ break;
+ case PLL_HPLL:
+ rate = rockchip_pll_get_rate(&rv1126_pll_clks[HPLL], priv->cru,
+ HPLL);
+ break;
+ case PLL_DPLL:
+ rate = rockchip_pll_get_rate(&rv1126_pll_clks[DPLL], priv->cru,
+ DPLL);
+ break;
+ case HCLK_PDCORE_NIU:
+ rate = rv1126_pdcore_get_clk(priv);
+ break;
+ case ACLK_PDBUS:
+ case HCLK_PDBUS:
+ case PCLK_PDBUS:
+ case PCLK_WDT:
+ rate = rv1126_pdbus_get_clk(priv, clk->id);
+ break;
+ case ACLK_PDPHP:
+ case HCLK_PDPHP:
+ rate = rv1126_pdphp_get_clk(priv, clk->id);
+ break;
+ case HCLK_PDAUDIO:
+ rate = rv1126_pdaudio_get_clk(priv);
+ break;
+ case CLK_I2C1:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ case CLK_I2C5:
+ rate = rv1126_i2c_get_clk(priv, clk->id);
+ break;
+ case CLK_SPI1:
+ rate = rv1126_spi_get_clk(priv);
+ break;
+ case CLK_PWM2:
+ rate = rv1126_pwm_get_clk(priv);
+ break;
+ case CLK_SARADC:
+ rate = rv1126_saradc_get_clk(priv);
+ break;
+ case CLK_CRYPTO_CORE:
+ case CLK_CRYPTO_PKA:
+ case ACLK_CRYPTO:
+ rate = rv1126_crypto_get_clk(priv, clk->id);
+ break;
+ case CLK_SDMMC:
+ case HCLK_SDMMC:
+ case CLK_SDIO:
+ case HCLK_SDIO:
+ case CLK_EMMC:
+ case HCLK_EMMC:
+ case SCLK_EMMC_SAMPLE:
+ rate = rv1126_mmc_get_clk(priv, clk->id);
+ break;
+ case SCLK_SFC:
+ rate = rv1126_sfc_get_clk(priv);
+ break;
+ case CLK_NANDC:
+ rate = rv1126_nand_get_clk(priv);
+ break;
+ case ACLK_PDVO:
+ case ACLK_VOP:
+ rate = rv1126_aclk_vop_get_clk(priv);
+ break;
+ case DCLK_VOP:
+ rate = rv1126_dclk_vop_get_clk(priv);
+ break;
+ case CLK_SCR1_CORE:
+ rate = rv1126_scr1_get_clk(priv);
+ break;
+ case CLK_GMAC_SRC:
+ rate = rv1126_gmac_src_get_clk(priv);
+ break;
+ case CLK_GMAC_ETHERNET_OUT:
+ rate = rv1126_gmac_out_get_clk(priv);
+ break;
+ case PCLK_GMAC:
+ rate = rv1126_pclk_gmac_get_clk(priv);
+ break;
+ case DCLK_DECOM:
+ rate = rv1126_dclk_decom_get_clk(priv);
+ break;
+ default:
+ debug("%s: Unsupported CLK#%ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+};
+
+static ulong rv1126_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong ret = 0;
+
+ if (!priv->gpll_hz) {
+ printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+ return -ENOENT;
+ }
+
+ switch (clk->id) {
+ case PLL_APLL:
+ case ARMCLK:
+ if (priv->armclk_hz)
+ rv1126_armclk_set_clk(priv, rate);
+ priv->armclk_hz = rate;
+ break;
+ case PLL_CPLL:
+ ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
+ CPLL, rate);
+ break;
+ case PLL_HPLL:
+ ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
+ HPLL, rate);
+ break;
+ case ACLK_PDBUS:
+ case HCLK_PDBUS:
+ case PCLK_PDBUS:
+ case PCLK_WDT:
+ ret = rv1126_pdbus_set_clk(priv, clk->id, rate);
+ break;
+ case ACLK_PDPHP:
+ case HCLK_PDPHP:
+ ret = rv1126_pdphp_set_clk(priv, clk->id, rate);
+ break;
+ case HCLK_PDCORE_NIU:
+ ret = rv1126_pdcore_set_clk(priv, rate);
+ break;
+ case HCLK_PDAUDIO:
+ ret = rv1126_pdaudio_set_clk(priv, rate);
+ break;
+ case CLK_I2C1:
+ case CLK_I2C3:
+ case CLK_I2C4:
+ case CLK_I2C5:
+ ret = rv1126_i2c_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_SPI1:
+ ret = rv1126_spi_set_clk(priv, rate);
+ break;
+ case CLK_PWM2:
+ ret = rv1126_pwm_set_clk(priv, rate);
+ break;
+ case CLK_SARADC:
+ ret = rv1126_saradc_set_clk(priv, rate);
+ break;
+ case CLK_CRYPTO_CORE:
+ case CLK_CRYPTO_PKA:
+ case ACLK_CRYPTO:
+ ret = rv1126_crypto_set_clk(priv, clk->id, rate);
+ break;
+ case CLK_SDMMC:
+ case HCLK_SDMMC:
+ case CLK_SDIO:
+ case HCLK_SDIO:
+ case CLK_EMMC:
+ case HCLK_EMMC:
+ ret = rv1126_mmc_set_clk(priv, clk->id, rate);
+ break;
+ case SCLK_SFC:
+ ret = rv1126_sfc_set_clk(priv, rate);
+ break;
+ case CLK_NANDC:
+ ret = rv1126_nand_set_clk(priv, rate);
+ break;
+ case ACLK_PDVO:
+ case ACLK_VOP:
+ ret = rv1126_aclk_vop_set_clk(priv, rate);
+ break;
+ case DCLK_VOP:
+ ret = rv1126_dclk_vop_set_clk(priv, rate);
+ break;
+ case CLK_SCR1_CORE:
+ ret = rv1126_scr1_set_clk(priv, rate);
+ break;
+ case CLK_GMAC_SRC:
+ ret = rv1126_gmac_src_set_clk(priv, rate);
+ break;
+ case CLK_GMAC_ETHERNET_OUT:
+ ret = rv1126_gmac_out_set_clk(priv, rate);
+ break;
+ case CLK_GMAC_TX_RX:
+ ret = rv1126_gmac_tx_rx_set_clk(priv, rate);
+ break;
+ case DCLK_DECOM:
+ ret = rv1126_dclk_decom_set_clk(priv, rate);
+ break;
+ default:
+ debug("%s: Unsupported CLK#%ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return ret;
+};
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rv1126_gmac_src_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rv1126_grf *grf = priv->grf;
+
+ if (parent->id == CLK_GMAC_SRC_M0)
+ rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
+ GMAC_SRC_SEL_M0 << GMAC_SRC_SEL_SHIFT);
+ else if (parent->id == CLK_GMAC_SRC_M1)
+ rk_clrsetreg(&grf->iofunc_con1, GMAC_SRC_SEL_MASK,
+ GMAC_SRC_SEL_M1 << GMAC_SRC_SEL_SHIFT);
+
+ return 0;
+}
+
+static int rv1126_gmac_src_m0_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rv1126_cru *cru = priv->cru;
+
+ if (parent->id == CLK_GMAC_DIV)
+ rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
+ GMAC_SRC_M0_SEL_INT << GMAC_SRC_M0_SEL_SHIFT);
+ else
+ rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M0_SEL_MASK,
+ GMAC_SRC_M0_SEL_EXT << GMAC_SRC_M0_SEL_SHIFT);
+
+ return 0;
+}
+
+static int rv1126_gmac_src_m1_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rv1126_cru *cru = priv->cru;
+
+ if (parent->id == CLK_GMAC_DIV)
+ rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK,
+ GMAC_SRC_M1_SEL_INT << GMAC_SRC_M1_SEL_SHIFT);
+ else
+ rk_clrsetreg(&cru->gmac_con, GMAC_SRC_M1_SEL_MASK,
+ GMAC_SRC_M1_SEL_EXT << GMAC_SRC_M1_SEL_SHIFT);
+
+ return 0;
+}
+
+static int rv1126_gmac_tx_rx_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rv1126_cru *cru = priv->cru;
+
+ if (parent->id == RGMII_MODE_CLK)
+ rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
+ GMAC_RGMII_MODE << GMAC_MODE_SEL_SHIFT);
+ else
+ rk_clrsetreg(&cru->gmac_con, GMAC_MODE_SEL_MASK,
+ GMAC_RMII_MODE << GMAC_MODE_SEL_SHIFT);
+
+ return 0;
+}
+
+static int rv1126_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ switch (clk->id) {
+ case CLK_GMAC_SRC:
+ return rv1126_gmac_src_set_parent(clk, parent);
+ case CLK_GMAC_SRC_M0:
+ return rv1126_gmac_src_m0_set_parent(clk, parent);
+ case CLK_GMAC_SRC_M1:
+ return rv1126_gmac_src_m1_set_parent(clk, parent);
+ case CLK_GMAC_TX_RX:
+ return rv1126_gmac_tx_rx_set_parent(clk, parent);
+ default:
+ return -ENOENT;
+ }
+
+ return 0;
+}
+#endif
+
+static struct clk_ops rv1126_clk_ops = {
+ .get_rate = rv1126_clk_get_rate,
+ .set_rate = rv1126_clk_set_rate,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .set_parent = rv1126_clk_set_parent,
+#endif
+};
+
+static ulong rv1126_gpll_set_rate(struct rv1126_clk_priv *priv,
+ struct rv1126_pmuclk_priv *pmu_priv,
+ ulong rate)
+{
+ ulong emmc_rate, sfc_rate, nandc_rate;
+ bool restore = false;
+
+ if (priv->gpll_hz != OSC_HZ) {
+ emmc_rate = rv1126_mmc_get_clk(priv, CLK_EMMC);
+ sfc_rate = rv1126_sfc_get_clk(priv);
+ nandc_rate = rv1126_nand_get_clk(priv);
+ debug("%s emmc=%lu, sfc=%lu, nandc=%lu\n", __func__,
+ emmc_rate, sfc_rate, nandc_rate);
+ restore = true;
+ }
+
+ /*
+ * the child div is big enough for gpll 1188MHz,
+ * even maskrom has change some clocks.
+ */
+ if (rockchip_pll_set_rate(&rv1126_pll_clks[GPLL],
+ pmu_priv->pmucru, GPLL, rate))
+ return -EINVAL;
+ pmu_priv->gpll_hz = rate;
+ priv->gpll_hz = rate;
+
+ if (restore) {
+ rv1126_mmc_set_clk(priv, CLK_EMMC, emmc_rate);
+ rv1126_sfc_set_clk(priv, sfc_rate);
+ rv1126_nand_set_clk(priv, nandc_rate);
+ }
+
+ return 0;
+}
+
+static int rv1126_gpll_set_clk(struct rv1126_clk_priv *priv, ulong rate)
+{
+ struct udevice *pmucru_dev;
+ struct rv1126_pmuclk_priv *pmu_priv;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rv1126_pmucru),
+ &pmucru_dev);
+ if (ret) {
+ printf("%s: could not find pmucru device\n", __func__);
+ return ret;
+ }
+ pmu_priv = dev_get_priv(pmucru_dev);
+ priv->gpll_hz = pmu_priv->gpll_hz;
+
+ if (rv1126_gpll_set_rate(priv, pmu_priv, rate)) {
+ printf("%s: failed to set gpll rate %lu\n", __func__, rate);
+ return -EINVAL;
+ }
+
+ rv1126_pdpmu_set_pmuclk(pmu_priv, PCLK_PDPMU_HZ);
+ rv1126_rtc32k_set_pmuclk(pmu_priv, CLK_OSC0_DIV_HZ);
+
+ return 0;
+}
+
+static void rv1126_clk_init(struct rv1126_clk_priv *priv)
+{
+ int ret;
+
+ priv->sync_kernel = false;
+ if (!priv->armclk_enter_hz) {
+ priv->armclk_enter_hz =
+ rockchip_pll_get_rate(&rv1126_pll_clks[APLL],
+ priv->cru, APLL);
+ priv->armclk_init_hz = priv->armclk_enter_hz;
+ }
+
+ if (priv->armclk_init_hz != APLL_HZ) {
+ ret = rv1126_armclk_set_clk(priv, APLL_HZ);
+ if (!ret)
+ priv->armclk_init_hz = APLL_HZ;
+ }
+ if (priv->cpll_hz != CPLL_HZ) {
+ ret = rockchip_pll_set_rate(&rv1126_pll_clks[CPLL], priv->cru,
+ CPLL, CPLL_HZ);
+ if (!ret)
+ priv->cpll_hz = CPLL_HZ;
+ }
+ if (priv->hpll_hz != HPLL_HZ) {
+ ret = rockchip_pll_set_rate(&rv1126_pll_clks[HPLL], priv->cru,
+ HPLL, HPLL_HZ);
+ if (!ret)
+ priv->hpll_hz = HPLL_HZ;
+ }
+ if (priv->gpll_hz != GPLL_HZ)
+ rv1126_gpll_set_clk(priv, GPLL_HZ);
+
+ rv1126_pdbus_set_clk(priv, ACLK_PDBUS, ACLK_PDBUS_HZ);
+ rv1126_pdbus_set_clk(priv, HCLK_PDBUS, HCLK_PDBUS_HZ);
+ rv1126_pdbus_set_clk(priv, PCLK_PDBUS, PCLK_PDBUS_HZ);
+ rv1126_pdphp_set_clk(priv, ACLK_PDPHP, ACLK_PDPHP_HZ);
+ rv1126_pdphp_set_clk(priv, HCLK_PDPHP, HCLK_PDPHP_HZ);
+ rv1126_pdcore_set_clk(priv, HCLK_PDCORE_HZ);
+ rv1126_pdaudio_set_clk(priv, HCLK_PDAUDIO_HZ);
+}
+
+static int rv1126_clk_probe(struct udevice *dev)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(priv->grf))
+ return PTR_ERR(priv->grf);
+
+ rv1126_clk_init(priv);
+
+ /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */
+ ret = clk_set_defaults(dev, 1);
+ if (ret)
+ debug("%s clk_set_defaults failed %d\n", __func__, ret);
+ else
+ priv->sync_kernel = true;
+
+ return 0;
+}
+
+static int rv1126_clk_of_to_plat(struct udevice *dev)
+{
+ struct rv1126_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = dev_read_addr_ptr(dev);
+
+ return 0;
+}
+
+static int rv1126_clk_bind(struct udevice *dev)
+{
+ int ret;
+ struct udevice *sys_child;
+ struct sysreset_reg *priv;
+
+ /* The reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+ &sys_child);
+ if (ret) {
+ debug("Warning: No sysreset driver: ret=%d\n", ret);
+ } else {
+ priv = malloc(sizeof(struct sysreset_reg));
+ priv->glb_srst_fst_value = offsetof(struct rv1126_cru,
+ glb_srst_fst);
+ priv->glb_srst_snd_value = offsetof(struct rv1126_cru,
+ glb_srst_snd);
+ dev_set_priv(sys_child, priv);
+ }
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+ ret = offsetof(struct rv1126_cru, softrst_con[0]);
+ ret = rockchip_reset_bind(dev, ret, 15);
+ if (ret)
+ debug("Warning: software reset driver bind faile\n");
+#endif
+ return 0;
+}
+
+static const struct udevice_id rv1126_clk_ids[] = {
+ { .compatible = "rockchip,rv1126-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rv1126_cru) = {
+ .name = "rockchip_rv1126_cru",
+ .id = UCLASS_CLK,
+ .of_match = rv1126_clk_ids,
+ .priv_auto = sizeof(struct rv1126_clk_priv),
+ .of_to_plat = rv1126_clk_of_to_plat,
+ .ops = &rv1126_clk_ops,
+ .bind = rv1126_clk_bind,
+ .probe = rv1126_clk_probe,
+};
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index 7d03f8101dfa..98843554733a 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o
obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o
obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o
obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o
+obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c
index 9de29c0b8b43..2c35491b24d8 100644
--- a/drivers/pinctrl/rockchip/pinctrl-px30.c
+++ b/drivers/pinctrl/rockchip/pinctrl-px30.c
@@ -80,7 +80,7 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -90,15 +90,6 @@ static int px30_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3128.c b/drivers/pinctrl/rockchip/pinctrl-rk3128.c
index e6dc1af86e96..355c45eb7f8c 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3128.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3128.c
@@ -106,7 +106,7 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -119,15 +119,6 @@ static int rk3128_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk322x.c b/drivers/pinctrl/rockchip/pinctrl-rk322x.c
index 7c58f40d93db..351406da2d45 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk322x.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk322x.c
@@ -150,7 +150,7 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -160,15 +160,6 @@ static int rk3228_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3288.c b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
index 5894f47f534b..a976b7aeeb27 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3288.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3288.c
@@ -37,7 +37,7 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -47,15 +47,6 @@ static int rk3288_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
/* bank0 is special, there are no higher 16 bit writing bits. */
if (bank->bank_num == 0) {
regmap_read(regmap, reg, &data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3308.c b/drivers/pinctrl/rockchip/pinctrl-rk3308.c
index 83186f40f6f0..f9ac6347eaf1 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3308.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3308.c
@@ -258,7 +258,7 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -271,15 +271,6 @@ static int rk3308_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3328.c b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
index 1c3c5986a504..65a750076773 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3328.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3328.c
@@ -130,7 +130,7 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -143,15 +143,6 @@ static int rk3328_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
if (bank->recalced_mask & BIT(pin))
rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3399.c b/drivers/pinctrl/rockchip/pinctrl-rk3399.c
index caa92200c6eb..ae785573baf5 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rk3399.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3399.c
@@ -59,7 +59,7 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
struct regmap *regmap;
int reg, ret, mask, mux_type;
u8 bit;
- u32 data, route_reg, route_val;
+ u32 data;
regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
? priv->regmap_pmu : priv->regmap_base;
@@ -69,15 +69,6 @@ static int rk3399_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
reg = bank->iomux[iomux_num].offset;
reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
- if (bank->route_mask & BIT(pin)) {
- if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
- &route_val)) {
- ret = regmap_write(regmap, route_reg, route_val);
- if (ret)
- return ret;
- }
- }
-
data = (mask << (bit + 16));
data |= (mux & mask) << bit;
ret = regmap_write(regmap, reg, data);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
index 630513ba3a22..d9d61fdb726a 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
@@ -62,8 +62,9 @@ void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
*bit = data->bit;
}
-bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
- int mux, u32 *reg, u32 *value)
+static enum rockchip_pin_route_type
+rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
+ int mux, u32 *reg, u32 *value)
{
struct rockchip_pinctrl_priv *priv = bank->priv;
struct rockchip_pin_ctrl *ctrl = priv->ctrl;
@@ -78,12 +79,12 @@ bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
}
if (i >= ctrl->niomux_routes)
- return false;
+ return ROUTE_TYPE_INVALID;
*reg = data->route_offset;
*value = data->route_val;
- return true;
+ return data->route_type;
}
int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask)
@@ -214,8 +215,40 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
return -ENOTSUPP;
ret = ctrl->set_mux(bank, pin, mux);
+ if (ret)
+ return ret;
- return ret;
+ if (bank->route_mask & BIT(pin)) {
+ struct regmap *regmap;
+ u32 route_reg = 0, route_val = 0;
+
+ ret = rockchip_get_mux_route(bank, pin, mux,
+ &route_reg, &route_val);
+ switch (ret) {
+ case ROUTE_TYPE_DEFAULT:
+ if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+ regmap = priv->regmap_pmu;
+ else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
+ regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
+ else
+ regmap = priv->regmap_base;
+
+ regmap_write(regmap, route_reg, route_val);
+ break;
+ case ROUTE_TYPE_TOPGRF:
+ regmap_write(priv->regmap_base, route_reg, route_val);
+ break;
+ case ROUTE_TYPE_PMUGRF:
+ regmap_write(priv->regmap_pmu, route_reg, route_val);
+ break;
+ case ROUTE_TYPE_INVALID:
+ fallthrough;
+ default:
+ break;
+ }
+ }
+
+ return 0;
}
static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
@@ -545,7 +578,7 @@ static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *d
inc = (iom->type & (IOMUX_WIDTH_4BIT |
IOMUX_WIDTH_3BIT |
IOMUX_8WIDTH_2BIT)) ? 8 : 4;
- if (iom->type & IOMUX_SOURCE_PMU)
+ if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
pmu_offs += inc;
else
grf_offs += inc;
diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h
index d969c200826c..8dfaba5c74d2 100644
--- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h
+++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h
@@ -9,6 +9,9 @@
#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 +21,7 @@
#define IOMUX_UNROUTED BIT(3)
#define IOMUX_WIDTH_3BIT BIT(4)
#define IOMUX_8WIDTH_2BIT BIT(5)
+#define IOMUX_L_SOURCE_PMU BIT(6)
/**
* Defined some common pins constants
@@ -63,6 +67,22 @@ enum rockchip_pin_pull_type {
};
/**
+ * Rockchip pinctrl route type
+ *
+ * DEFAULT : Same regmap as pin iomux
+ * TOPGRF : Mux route setting in topgrf
+ * PMUGRF : Mux route setting in pmugrf
+ * INVALID : Nnot need to set mux route
+ */
+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
* an initial offset value the relevant source offset can be reset
@@ -126,6 +146,21 @@ struct rockchip_pin_bank {
}, \
}
+#define PIN_BANK_IOMUX_FLAGS_OFFSET(id, pins, label, iom0, iom1, iom2, \
+ iom3, offset0, offset1, offset2, \
+ offset3) \
+ { \
+ .bank_num = id, \
+ .nr_pins = pins, \
+ .name = label, \
+ .iomux = { \
+ { .type = iom0, .offset = offset0 }, \
+ { .type = iom1, .offset = offset1 }, \
+ { .type = iom2, .offset = offset2 }, \
+ { .type = iom3, .offset = offset3 }, \
+ }, \
+ }
+
#define PIN_BANK_DRV_FLAGS(id, pins, label, type0, type1, type2, type3) \
{ \
.bank_num = id, \
@@ -220,6 +255,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 +295,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 +303,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;
};
@@ -289,8 +345,6 @@ extern const struct pinctrl_ops rockchip_pinctrl_ops;
int rockchip_pinctrl_probe(struct udevice *dev);
void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
int *reg, u8 *bit, int *mask);
-bool rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
- int mux, u32 *reg, u32 *value);
int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask);
int rockchip_translate_drive_value(int type, int strength);
int rockchip_translate_pull_value(int type, int pull);
diff --git a/drivers/pinctrl/rockchip/pinctrl-rv1126.c b/drivers/pinctrl/rockchip/pinctrl-rv1126.c
new file mode 100644
index 000000000000..eefb8b17768b
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rv1126.c
@@ -0,0 +1,416 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2020 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#include "pinctrl-rockchip.h"
+
+static struct rockchip_mux_recalced_data rv1126_mux_recalced_data[] = {
+ {
+ .num = 0,
+ .pin = 20,
+ .reg = 0x10000,
+ .bit = 0,
+ .mask = 0xf
+ },
+ {
+ .num = 0,
+ .pin = 21,
+ .reg = 0x10000,
+ .bit = 4,
+ .mask = 0xf
+ },
+ {
+ .num = 0,
+ .pin = 22,
+ .reg = 0x10000,
+ .bit = 8,
+ .mask = 0xf
+ },
+ {
+ .num = 0,
+ .pin = 23,
+ .reg = 0x10000,
+ .bit = 12,
+ .mask = 0xf
+ },
+};
+
+static struct rockchip_mux_route_data rv1126_mux_route_data[] = {
+ MR_TOPGRF(RK_GPIO3, RK_PD2, 1, 0x10260, RK_GENMASK_VAL(0, 0, 0)), /* I2S0_MCLK_M0 */
+ MR_TOPGRF(RK_GPIO3, RK_PB0, 3, 0x10260, RK_GENMASK_VAL(0, 0, 1)), /* I2S0_MCLK_M1 */
+
+ MR_TOPGRF(RK_GPIO0, RK_PD4, 4, 0x10260, RK_GENMASK_VAL(3, 2, 0)), /* I2S1_MCLK_M0 */
+ MR_TOPGRF(RK_GPIO1, RK_PD5, 2, 0x10260, RK_GENMASK_VAL(3, 2, 1)), /* I2S1_MCLK_M1 */
+ MR_TOPGRF(RK_GPIO2, RK_PC7, 6, 0x10260, RK_GENMASK_VAL(3, 2, 2)), /* I2S1_MCLK_M2 */
+
+ MR_TOPGRF(RK_GPIO1, RK_PD0, 1, 0x10260, RK_GENMASK_VAL(4, 4, 0)), /* I2S2_MCLK_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PB3, 2, 0x10260, RK_GENMASK_VAL(4, 4, 1)), /* I2S2_MCLK_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PD4, 2, 0x10260, RK_GENMASK_VAL(12, 12, 0)), /* PDM_CLK0_M0 */
+ MR_TOPGRF(RK_GPIO3, RK_PC0, 3, 0x10260, RK_GENMASK_VAL(12, 12, 1)), /* PDM_CLK0_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PC6, 1, 0x10264, RK_GENMASK_VAL(0, 0, 0)), /* CIF_CLKOUT_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PD1, 3, 0x10264, RK_GENMASK_VAL(0, 0, 1)), /* CIF_CLKOUT_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA4, 5, 0x10264, RK_GENMASK_VAL(5, 4, 0)), /* I2C3_SCL_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PD4, 7, 0x10264, RK_GENMASK_VAL(5, 4, 1)), /* I2C3_SCL_M1 */
+ MR_TOPGRF(RK_GPIO1, RK_PD6, 3, 0x10264, RK_GENMASK_VAL(5, 4, 2)), /* I2C3_SCL_M2 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA0, 7, 0x10264, RK_GENMASK_VAL(6, 6, 0)), /* I2C4_SCL_M0 */
+ MR_TOPGRF(RK_GPIO4, RK_PA0, 4, 0x10264, RK_GENMASK_VAL(6, 6, 1)), /* I2C4_SCL_M1 */
+
+ MR_TOPGRF(RK_GPIO2, RK_PA5, 7, 0x10264, RK_GENMASK_VAL(9, 8, 0)), /* I2C5_SCL_M0 */
+ MR_TOPGRF(RK_GPIO3, RK_PB0, 5, 0x10264, RK_GENMASK_VAL(9, 8, 1)), /* I2C5_SCL_M1 */
+ MR_TOPGRF(RK_GPIO1, RK_PD0, 4, 0x10264, RK_GENMASK_VAL(9, 8, 2)), /* I2C5_SCL_M2 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PC0, 5, 0x10264, RK_GENMASK_VAL(11, 10, 0)), /* SPI1_CLK_M0 */
+ MR_TOPGRF(RK_GPIO1, RK_PC6, 3, 0x10264, RK_GENMASK_VAL(11, 10, 1)), /* SPI1_CLK_M1 */
+ MR_TOPGRF(RK_GPIO2, RK_PD5, 6, 0x10264, RK_GENMASK_VAL(11, 10, 2)), /* SPI1_CLK_M2 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PC0, 2, 0x10264, RK_GENMASK_VAL(12, 12, 0)), /* RGMII_CLK_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PB7, 2, 0x10264, RK_GENMASK_VAL(12, 12, 1)), /* RGMII_CLK_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA1, 3, 0x10264, RK_GENMASK_VAL(13, 13, 0)), /* CAN_TXD_M0 */
+ MR_TOPGRF(RK_GPIO3, RK_PA7, 5, 0x10264, RK_GENMASK_VAL(13, 13, 1)), /* CAN_TXD_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA4, 6, 0x10268, RK_GENMASK_VAL(0, 0, 0)), /* PWM8_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PD7, 5, 0x10268, RK_GENMASK_VAL(0, 0, 1)), /* PWM8_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA5, 6, 0x10268, RK_GENMASK_VAL(2, 2, 0)), /* PWM9_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PD6, 5, 0x10268, RK_GENMASK_VAL(2, 2, 1)), /* PWM9_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA6, 6, 0x10268, RK_GENMASK_VAL(4, 4, 0)), /* PWM10_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PD5, 5, 0x10268, RK_GENMASK_VAL(4, 4, 1)), /* PWM10_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA7, 6, 0x10268, RK_GENMASK_VAL(6, 6, 0)), /* PWM11_IR_M0 */
+ MR_TOPGRF(RK_GPIO3, RK_PA1, 5, 0x10268, RK_GENMASK_VAL(6, 6, 1)), /* PWM11_IR_M1 */
+
+ MR_TOPGRF(RK_GPIO1, RK_PA5, 3, 0x10268, RK_GENMASK_VAL(8, 8, 0)), /* UART2_TX_M0 */
+ MR_TOPGRF(RK_GPIO3, RK_PA2, 1, 0x10268, RK_GENMASK_VAL(8, 8, 1)), /* UART2_TX_M1 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PC6, 3, 0x10268, RK_GENMASK_VAL(11, 10, 0)), /* UART3_TX_M0 */
+ MR_TOPGRF(RK_GPIO1, RK_PA7, 2, 0x10268, RK_GENMASK_VAL(11, 10, 1)), /* UART3_TX_M1 */
+ MR_TOPGRF(RK_GPIO3, RK_PA0, 4, 0x10268, RK_GENMASK_VAL(11, 10, 2)), /* UART3_TX_M2 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA4, 4, 0x10268, RK_GENMASK_VAL(13, 12, 0)), /* UART4_TX_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PA6, 4, 0x10268, RK_GENMASK_VAL(13, 12, 1)), /* UART4_TX_M1 */
+ MR_TOPGRF(RK_GPIO1, RK_PD5, 3, 0x10268, RK_GENMASK_VAL(13, 12, 2)), /* UART4_TX_M2 */
+
+ MR_TOPGRF(RK_GPIO3, RK_PA6, 4, 0x10268, RK_GENMASK_VAL(15, 14, 0)), /* UART5_TX_M0 */
+ MR_TOPGRF(RK_GPIO2, RK_PB0, 4, 0x10268, RK_GENMASK_VAL(15, 14, 1)), /* UART5_TX_M1 */
+ MR_TOPGRF(RK_GPIO2, RK_PA0, 3, 0x10268, RK_GENMASK_VAL(15, 14, 2)), /* UART5_TX_M2 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PB6, 3, 0x0114, RK_GENMASK_VAL(0, 0, 0)), /* PWM0_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PB3, 5, 0x0114, RK_GENMASK_VAL(0, 0, 1)), /* PWM0_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PB7, 3, 0x0114, RK_GENMASK_VAL(2, 2, 0)), /* PWM1_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PB2, 5, 0x0114, RK_GENMASK_VAL(2, 2, 1)), /* PWM1_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PC0, 3, 0x0114, RK_GENMASK_VAL(4, 4, 0)), /* PWM2_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PB1, 5, 0x0114, RK_GENMASK_VAL(4, 4, 1)), /* PWM2_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PC1, 3, 0x0114, RK_GENMASK_VAL(6, 6, 0)), /* PWM3_IR_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PB0, 5, 0x0114, RK_GENMASK_VAL(6, 6, 1)), /* PWM3_IR_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PC2, 3, 0x0114, RK_GENMASK_VAL(8, 8, 0)), /* PWM4_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PA7, 5, 0x0114, RK_GENMASK_VAL(8, 8, 1)), /* PWM4_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PC3, 3, 0x0114, RK_GENMASK_VAL(10, 10, 0)), /* PWM5_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PA6, 5, 0x0114, RK_GENMASK_VAL(10, 10, 1)), /* PWM5_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PB2, 3, 0x0114, RK_GENMASK_VAL(12, 12, 0)), /* PWM6_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PD4, 5, 0x0114, RK_GENMASK_VAL(12, 12, 1)), /* PWM6_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PB1, 3, 0x0114, RK_GENMASK_VAL(14, 14, 0)), /* PWM7_IR_M0 */
+ MR_PMUGRF(RK_GPIO3, RK_PA0, 5, 0x0114, RK_GENMASK_VAL(14, 14, 1)), /* PWM7_IR_M1 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PB0, 1, 0x0118, RK_GENMASK_VAL(1, 0, 0)), /* SPI0_CLK_M0 */
+ MR_PMUGRF(RK_GPIO2, RK_PA1, 1, 0x0118, RK_GENMASK_VAL(1, 0, 1)), /* SPI0_CLK_M1 */
+ MR_PMUGRF(RK_GPIO2, RK_PB2, 6, 0x0118, RK_GENMASK_VAL(1, 0, 2)), /* SPI0_CLK_M2 */
+
+ MR_PMUGRF(RK_GPIO0, RK_PB6, 2, 0x0118, RK_GENMASK_VAL(2, 2, 0)), /* UART1_TX_M0 */
+ MR_PMUGRF(RK_GPIO1, RK_PD0, 5, 0x0118, RK_GENMASK_VAL(2, 2, 1)), /* UART1_TX_M1 */
+ MR_PMUGRF(RK_GPIO0, RK_PC3, 1, 0x0118, RK_GENMASK_VAL(4, 4, 1)), /* I2C2 */
+};
+
+static int rv1126_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, mux_type;
+ 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 if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
+ regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
+ else
+ regmap = priv->regmap_base;
+
+ /* get basic quadrupel of mux registers and the correct reg inside */
+ mux_type = bank->iomux[iomux_num].type;
+ reg = bank->iomux[iomux_num].offset;
+ if (mux_type & IOMUX_WIDTH_4BIT) {
+ if ((pin % 8) >= 4)
+ reg += 0x4;
+ bit = (pin % 4) * 4;
+ mask = 0xf;
+ } else {
+ bit = (pin % 8) * 2;
+ mask = 0x3;
+ }
+
+ if (bank->recalced_mask & BIT(pin))
+ rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
+
+ data = (mask << (bit + 16));
+ data |= (mux & mask) << bit;
+ ret = regmap_write(regmap, reg, data);
+
+ return ret;
+}
+
+#define RV1126_PULL_PMU_OFFSET 0x40
+#define RV1126_PULL_GRF_GPIO1A0_OFFSET 0x10108
+#define RV1126_PULL_PINS_PER_REG 8
+#define RV1126_PULL_BITS_PER_PIN 2
+#define RV1126_PULL_BANK_STRIDE 16
+#define RV1126_GPIO_C4_D7(p) (p >= 20 && p <= 31) /* GPIO0_C4 ~ GPIO0_D7 */
+
+static void rv1126_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+
+ /* The first 24 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ if (RV1126_GPIO_C4_D7(pin_num)) {
+ *regmap = priv->regmap_base;
+ *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET;
+ *reg -= (((31 - pin_num) / RV1126_PULL_PINS_PER_REG + 1) * 4);
+ *bit = pin_num % RV1126_PULL_PINS_PER_REG;
+ *bit *= RV1126_PULL_BITS_PER_PIN;
+ return;
+ }
+ *regmap = priv->regmap_pmu;
+ *reg = RV1126_PULL_PMU_OFFSET;
+ } else {
+ *reg = RV1126_PULL_GRF_GPIO1A0_OFFSET;
+ *regmap = priv->regmap_base;
+ *reg += (bank->bank_num - 1) * RV1126_PULL_BANK_STRIDE;
+ }
+
+ *reg += ((pin_num / RV1126_PULL_PINS_PER_REG) * 4);
+ *bit = (pin_num % RV1126_PULL_PINS_PER_REG);
+ *bit *= RV1126_PULL_BITS_PER_PIN;
+}
+
+static int rv1126_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;
+
+ rv1126_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;
+}
+
+#define RV1126_DRV_PMU_OFFSET 0x20
+#define RV1126_DRV_GRF_GPIO1A0_OFFSET 0x10090
+#define RV1126_DRV_BITS_PER_PIN 4
+#define RV1126_DRV_PINS_PER_REG 4
+#define RV1126_DRV_BANK_STRIDE 32
+
+static void rv1126_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num, struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+
+ /* The first 24 pins of the first bank are located in PMU */
+ if (bank->bank_num == 0) {
+ if (RV1126_GPIO_C4_D7(pin_num)) {
+ *regmap = priv->regmap_base;
+ *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET;
+ *reg -= (((31 - pin_num) / RV1126_DRV_PINS_PER_REG + 1) * 4);
+ *reg -= 0x4;
+ *bit = pin_num % RV1126_DRV_PINS_PER_REG;
+ *bit *= RV1126_DRV_BITS_PER_PIN;
+ return;
+ }
+ *regmap = priv->regmap_pmu;
+ *reg = RV1126_DRV_PMU_OFFSET;
+ } else {
+ *regmap = priv->regmap_base;
+ *reg = RV1126_DRV_GRF_GPIO1A0_OFFSET;
+ *reg += (bank->bank_num - 1) * RV1126_DRV_BANK_STRIDE;
+ }
+
+ *reg += ((pin_num / RV1126_DRV_PINS_PER_REG) * 4);
+ *bit = pin_num % RV1126_DRV_PINS_PER_REG;
+ *bit *= RV1126_DRV_BITS_PER_PIN;
+}
+
+static int rv1126_set_drive(struct rockchip_pin_bank *bank,
+ int pin_num, int strength)
+{
+ struct regmap *regmap;
+ int reg;
+ u32 data;
+ u8 bit;
+
+ rv1126_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+
+ /* enable the write to the equivalent lower bits */
+ data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16);
+ data |= (strength << bit);
+
+ return regmap_write(regmap, reg, data);
+}
+
+#define RV1126_SCHMITT_PMU_OFFSET 0x60
+#define RV1126_SCHMITT_GRF_GPIO1A0_OFFSET 0x10188
+#define RV1126_SCHMITT_BANK_STRIDE 16
+#define RV1126_SCHMITT_PINS_PER_GRF_REG 8
+#define RV1126_SCHMITT_PINS_PER_PMU_REG 8
+
+static int rv1126_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+ int pin_num,
+ struct regmap **regmap,
+ int *reg, u8 *bit)
+{
+ struct rockchip_pinctrl_priv *priv = bank->priv;
+ int pins_per_reg;
+
+ if (bank->bank_num == 0) {
+ if (RV1126_GPIO_C4_D7(pin_num)) {
+ *regmap = priv->regmap_base;
+ *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET;
+ *reg -= (((31 - pin_num) / RV1126_SCHMITT_PINS_PER_GRF_REG + 1) * 4);
+ *bit = pin_num % RV1126_SCHMITT_PINS_PER_GRF_REG;
+ return 0;
+ }
+ *regmap = priv->regmap_pmu;
+ *reg = RV1126_SCHMITT_PMU_OFFSET;
+ pins_per_reg = RV1126_SCHMITT_PINS_PER_PMU_REG;
+ } else {
+ *regmap = priv->regmap_base;
+ *reg = RV1126_SCHMITT_GRF_GPIO1A0_OFFSET;
+ pins_per_reg = RV1126_SCHMITT_PINS_PER_GRF_REG;
+ *reg += (bank->bank_num - 1) * RV1126_SCHMITT_BANK_STRIDE;
+ }
+ *reg += ((pin_num / pins_per_reg) * 4);
+ *bit = pin_num % pins_per_reg;
+
+ return 0;
+}
+
+static int rv1126_set_schmitt(struct rockchip_pin_bank *bank,
+ int pin_num, int enable)
+{
+ struct regmap *regmap;
+ int reg;
+ u8 bit;
+ u32 data;
+
+ rv1126_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+ /* enable the write to the equivalent lower bits */
+ data = BIT(bit + 16) | (enable << bit);
+
+ return regmap_write(regmap, reg, data);
+}
+
+static struct rockchip_pin_bank rv1126_pin_banks[] = {
+ PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0",
+ IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+ IOMUX_WIDTH_4BIT | IOMUX_SOURCE_PMU,
+ IOMUX_WIDTH_4BIT | IOMUX_L_SOURCE_PMU,
+ IOMUX_WIDTH_4BIT),
+ PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1",
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ IOMUX_WIDTH_4BIT,
+ 0x10010, 0x10018, 0x10020, 0x10028),
+ 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, 2, "gpio4",
+ IOMUX_WIDTH_4BIT, 0, 0, 0),
+};
+
+static const struct rockchip_pin_ctrl rv1126_pin_ctrl = {
+ .pin_banks = rv1126_pin_banks,
+ .nr_banks = ARRAY_SIZE(rv1126_pin_banks),
+ .nr_pins = 130,
+ .grf_mux_offset = 0x10004, /* mux offset from GPIO0_D0 */
+ .pmu_mux_offset = 0x0,
+ .iomux_routes = rv1126_mux_route_data,
+ .niomux_routes = ARRAY_SIZE(rv1126_mux_route_data),
+ .iomux_recalced = rv1126_mux_recalced_data,
+ .niomux_recalced = ARRAY_SIZE(rv1126_mux_recalced_data),
+ .set_mux = rv1126_set_mux,
+ .set_pull = rv1126_set_pull,
+ .set_drive = rv1126_set_drive,
+ .set_schmitt = rv1126_set_schmitt,
+};
+
+static const struct udevice_id rv1126_pinctrl_ids[] = {
+ {
+ .compatible = "rockchip,rv1126-pinctrl",
+ .data = (ulong)&rv1126_pin_ctrl
+ },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_rv1126) = {
+ .name = "rockchip_rv1126_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = rv1126_pinctrl_ids,
+ .priv_auto = sizeof(struct rockchip_pinctrl_priv),
+ .ops = &rockchip_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .bind = dm_scan_fdt_dev,
+#endif
+ .probe = rockchip_pinctrl_probe,
+};
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index 5a39611349d2..83948e2c43ef 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -3,7 +3,7 @@
# Copyright (c) 2015 Google, Inc
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
-obj-$(CONFIG_RAM) += ram-uclass.o
+obj-$(CONFIG_$(SPL_TPL_)DM) += ram-uclass.o
obj-$(CONFIG_MPC83XX_SDRAM) += mpc83xx_sdram.o
obj-$(CONFIG_SANDBOX) += sandbox_ram.o
obj-$(CONFIG_STM32MP1_DDR) += stm32mp1/
diff --git a/drivers/ram/rockchip/Kconfig b/drivers/ram/rockchip/Kconfig
index c29d5e8b38cf..67c63ecba047 100644
--- a/drivers/ram/rockchip/Kconfig
+++ b/drivers/ram/rockchip/Kconfig
@@ -11,9 +11,10 @@ config ROCKCHIP_SDRAM_COMMON
help
This enable sdram common driver
+if RAM_ROCKCHIP
+
config RAM_ROCKCHIP_DEBUG
bool "Rockchip ram drivers debugging"
- depends on RAM_ROCKCHIP
default y
help
This enables debugging ram driver API's for the platforms
@@ -22,31 +23,28 @@ config RAM_ROCKCHIP_DEBUG
This is an option for developers to understand the ram drivers
initialization, configurations and etc.
-config RAM_PX30_DDR4
- bool "DDR4 support for Rockchip PX30"
- depends on RAM_ROCKCHIP && ROCKCHIP_PX30
+config RAM_ROCKCHIP_DDR4
+ bool "DDR4 support for Rockchip SoCs"
help
This enables DDR4 sdram support instead of the default DDR3 support
- on Rockchip PC30 SoCs.
+ on Rockchip SoCs.
-config RAM_PX30_LPDDR2
- bool "LPDDR2 support for Rockchip PX30"
- depends on RAM_ROCKCHIP && ROCKCHIP_PX30
+config RAM_ROCKCHIP_LPDDR2
+ bool "LPDDR2 support for Rockchip SoCs"
help
This enables LPDDR2 sdram support instead of the default DDR3 support
- on Rockchip PC30 SoCs.
+ on Rockchip SoCs.
-config RAM_PX30_LPDDR3
- bool "LPDDR3 support for Rockchip PX30"
- depends on RAM_ROCKCHIP && ROCKCHIP_PX30
+config RAM_ROCKCHIP_LPDDR3
+ bool "LPDDR3 support for Rockchip SoCs"
help
This enables LPDDR3 sdram support instead of the default DDR3 support
- on Rockchip PC30 SoCs.
+ on Rockchip SoCs.
-config RAM_RK3399_LPDDR4
- bool "LPDDR4 support for Rockchip RK3399"
- depends on RAM_ROCKCHIP && ROCKCHIP_RK3399
+config RAM_ROCKCHIP_LPDDR4
+ bool "LPDDR4 support for Rockchip SoCs"
help
This enables LPDDR4 sdram code support for the platforms based
- on Rockchip RK3399 SoC.
+ on Rockchip SoCs.
+endif # RAM_ROCKCHIP
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index 6d530c29afd7..98839ad6a6c4 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) = sdram_rk3308.o
obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o
obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o
obj-$(CONFIG_ROCKCHIP_RK3568) += sdram_rk3568.o
+obj-$(CONFIG_ROCKCHIP_RV1126) += sdram_rv1126.o sdram_pctl_px30.o
obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc
new file mode 100644
index 000000000000..4cde21565b0d
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-1056.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x351b1019},
+ {0x12030903},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 1056, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x008000b9}, /* RFSHTMG */
+ {0x000000d0, 0x00020103}, /* INIT0 */
+ {0x000000d4, 0x00690000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x01240040}, /* INIT3 */
+ {0x000000e0, 0x00280000}, /* INIT4 */
+ {0x000000e4, 0x000c0000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x0f132414}, /* DRAMTMG0 */
+ {0x00000104, 0x000d0419}, /* DRAMTMG1 */
+ {0x00000108, 0x0507050b}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202008}, /* DRAMTMG3 */
+ {0x00000110, 0x07020408}, /* DRAMTMG4 */
+ {0x00000114, 0x06060404}, /* DRAMTMG5 */
+ {0x00000120, 0x00000907}, /* DRAMTMG8 */
+ {0x00000180, 0x00a9002b}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07050003}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000610}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x0000000e}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x0000000a}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc
new file mode 100644
index 000000000000..eef61ab500f9
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-328.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x270a0509},
+ {0x08020401},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 328, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x0027003a}, /* RFSHTMG */
+ {0x000000d0, 0x00020052}, /* INIT0 */
+ {0x000000d4, 0x00220000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x03100000}, /* INIT3 */
+ {0x000000e0, 0x00000000}, /* INIT4 */
+ {0x000000e4, 0x00090000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x07090b06}, /* DRAMTMG0 */
+ {0x00000104, 0x00050209}, /* DRAMTMG1 */
+ {0x00000108, 0x03030307}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202006}, /* DRAMTMG3 */
+ {0x00000110, 0x03020203}, /* DRAMTMG4 */
+ {0x00000114, 0x03030202}, /* DRAMTMG5 */
+ {0x00000120, 0x00000903}, /* DRAMTMG8 */
+ {0x00000180, 0x00800020}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07010001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000600}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x00000005}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000005}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc
new file mode 100644
index 000000000000..39a827181524
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-396.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x290b060a},
+ {0x0a020401},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 396, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x00300046}, /* RFSHTMG */
+ {0x000000d0, 0x00020062}, /* INIT0 */
+ {0x000000d4, 0x00280000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x05200000}, /* INIT3 */
+ {0x000000e0, 0x00000000}, /* INIT4 */
+ {0x000000e4, 0x00090000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x070a0d07}, /* DRAMTMG0 */
+ {0x00000104, 0x0005020b}, /* DRAMTMG1 */
+ {0x00000108, 0x03030407}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202006}, /* DRAMTMG3 */
+ {0x00000110, 0x03020204}, /* DRAMTMG4 */
+ {0x00000114, 0x03030202}, /* DRAMTMG5 */
+ {0x00000120, 0x00000904}, /* DRAMTMG8 */
+ {0x00000180, 0x00800020}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07010001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000604}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x00000006}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000005}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc
new file mode 100644
index 000000000000..9dbbb1aa9e2d
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-528.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x2c0f080e},
+ {0x0d030502},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 528, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x0040005d}, /* RFSHTMG */
+ {0x000000d0, 0x00020082}, /* INIT0 */
+ {0x000000d4, 0x00350000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x09400000}, /* INIT3 */
+ {0x000000e0, 0x00080000}, /* INIT4 */
+ {0x000000e4, 0x00090000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x090e120a}, /* DRAMTMG0 */
+ {0x00000104, 0x0007020e}, /* DRAMTMG1 */
+ {0x00000108, 0x03040407}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202006}, /* DRAMTMG3 */
+ {0x00000110, 0x04020305}, /* DRAMTMG4 */
+ {0x00000114, 0x03030302}, /* DRAMTMG5 */
+ {0x00000120, 0x00000904}, /* DRAMTMG8 */
+ {0x00000180, 0x00800020}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07020001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000608}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x00000008}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000006}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc
new file mode 100644
index 000000000000..2b5713279497
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-664.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x2f120a11},
+ {0x0f020602},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 664, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x00500075}, /* RFSHTMG */
+ {0x000000d0, 0x000200a4}, /* INIT0 */
+ {0x000000d4, 0x00420000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x0b600040}, /* INIT3 */
+ {0x000000e0, 0x00100000}, /* INIT4 */
+ {0x000000e4, 0x00090000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x0a0f160c}, /* DRAMTMG0 */
+ {0x00000104, 0x00080211}, /* DRAMTMG1 */
+ {0x00000108, 0x04050508}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202006}, /* DRAMTMG3 */
+ {0x00000110, 0x05020306}, /* DRAMTMG4 */
+ {0x00000114, 0x04040302}, /* DRAMTMG5 */
+ {0x00000120, 0x00000905}, /* DRAMTMG8 */
+ {0x00000180, 0x00800020}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07030002}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0600060c}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x0000000a}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000007}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc
new file mode 100644
index 000000000000..8ad22727fcbb
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-784.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x30150c13},
+ {0x10030702},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 784, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x005f008a}, /* RFSHTMG */
+ {0x000000d0, 0x000200c1}, /* INIT0 */
+ {0x000000d4, 0x004e0000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x0d700040}, /* INIT3 */
+ {0x000000e0, 0x00180000}, /* INIT4 */
+ {0x000000e4, 0x00090000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x0c101a0f}, /* DRAMTMG0 */
+ {0x00000104, 0x000a0314}, /* DRAMTMG1 */
+ {0x00000108, 0x04060509}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202006}, /* DRAMTMG3 */
+ {0x00000110, 0x06020306}, /* DRAMTMG4 */
+ {0x00000114, 0x04040303}, /* DRAMTMG5 */
+ {0x00000120, 0x00000906}, /* DRAMTMG8 */
+ {0x00000180, 0x00800020}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07040002}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0600060c}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x0000000b}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000008}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc
new file mode 100644
index 000000000000..4cc36b05d257
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-ddr3-detect-924.inc
@@ -0,0 +1,72 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xC,
+ .bk = 0x3,
+ .bw = 0x0,
+ .dbw = 0x0,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x10,
+ .cs1_row = 0x10,
+ .cs0_high16bit_row = 0x10,
+ .cs1_high16bit_row = 0x10,
+ .ddrconfig = 0
+ },
+ {
+ {0x33180e16},
+ {0x10030803},
+ {0x00000002},
+ {0x00001111},
+ {0x0000000c},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 924, /* clock rate(MHz) */
+ .dramtype = DDR3,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x43042001}, /* MSTR */
+ {0x00000064, 0x007000a2}, /* RFSHTMG */
+ {0x000000d0, 0x000200e3}, /* INIT0 */
+ {0x000000d4, 0x005c0000}, /* INIT1 */
+ {0x000000d8, 0x00000100}, /* INIT2 */
+ {0x000000dc, 0x0f140040}, /* INIT3 */
+ {0x000000e0, 0x00200000}, /* INIT4 */
+ {0x000000e4, 0x000b0000}, /* INIT5 */
+ {0x000000f4, 0x000f011f}, /* RANKCTL */
+ {0x00000100, 0x0d111f11}, /* DRAMTMG0 */
+ {0x00000104, 0x000c0317}, /* DRAMTMG1 */
+ {0x00000108, 0x0507050a}, /* DRAMTMG2 */
+ {0x0000010c, 0x00202007}, /* DRAMTMG3 */
+ {0x00000110, 0x07020307}, /* DRAMTMG4 */
+ {0x00000114, 0x05050403}, /* DRAMTMG5 */
+ {0x00000120, 0x00000907}, /* DRAMTMG8 */
+ {0x00000180, 0x00940025}, /* ZQCTL0 */
+ {0x00000184, 0x00000000}, /* ZQCTL1 */
+ {0x00000190, 0x07050003}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x06000610}, /* ODTCFG */
+ {0x00000244, 0x00000201}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008a}, /* PHYREG01 */
+ {0x00000014, 0x0000000d}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000009}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-loader_params.inc b/drivers/ram/rockchip/sdram-rv1126-loader_params.inc
new file mode 100644
index 000000000000..a4c9e7f3287e
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-loader_params.inc
@@ -0,0 +1,197 @@
+0x12345678,
+2,/* version */
+(0 << 0) | (1 << 8) | (9 << 16) | (8 << 24),/* cpu_gen,global index */
+(0 << 0) | (9 << 8) | (17 << 16) | (9 << 24),/* d2,d3 index */
+(26 << 0) | (9 << 8) | (0 << 16) | (0 << 24),/* d4,d5 index */
+(0 << 0) | (9 << 8) | (35 << 16) | (9 << 24),/* lp2,lp3 index */
+(44 << 0) | (13 << 8) | (0 << 16) | (0 << 24),/* lp4,lp5 index */
+(0 << 0) | (0 << 8) | (57 << 16) | (8 << 24),/* skew index, dq_map index */
+(65 << 0) | (13 << 8) | (0 << 16) | (0 << 24), /*lp4x index*/
+/* global info */
+0,
+(93 << 16) | 13,/* sr_idle << 16 | pd_idle */
+0,/* channel info */
+1,/* 2t info */
+0, 0, 0, 0,/* reserved */
+
+/* ddr3 */
+(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT),
+(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT),
+(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT),
+/* drv when odt on */
+(30 << PHY_DQ_DRV_SHIFT) | (41 << PHY_CA_DRV_SHIFT) |
+ (38 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT),
+/* drv when odt off */
+(30 << PHY_DQ_DRV_SHIFT) | (30 << PHY_CA_DRV_SHIFT) |
+ (38 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT),
+/* odt info */
+(120 << DRAM_ODT_SHIFT) | (141 << PHY_ODT_SHIFT) |
+ (1 << PHY_ODT_PUUP_EN_SHIFT) |
+ (0 << PHY_ODT_PUDN_EN_SHIFT),
+/* odt enable freq */
+(333 << DRAM_ODT_EN_FREQ_SHIFT) | (333 << PHY_ODT_EN_FREQ_SHIFT),
+/* slew rate when odt enable */
+(0x1f << PHY_DQ_SR_SHIFT) | (0x1f << PHY_CA_SR_SHIFT) |
+ (0x1f << PHY_CLK_SR_SHIFT),
+/* slew ratee when odt disable */
+(0x1f << PHY_DQ_SR_SHIFT) | (0x1f << PHY_CA_SR_SHIFT) |
+ (0x1f << PHY_CLK_SR_SHIFT),
+
+/* ddr4 */
+(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT),
+(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT),
+(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT),
+/* drv when odt on */
+(37 << PHY_DQ_DRV_SHIFT) | (44 << PHY_CA_DRV_SHIFT) |
+ (37 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT),
+/* drv when odt off */
+(37 << PHY_DQ_DRV_SHIFT) | (44 << PHY_CA_DRV_SHIFT) |
+ (37 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT),
+/* odt info */
+(120 << DRAM_ODT_SHIFT) | (148 << PHY_ODT_SHIFT) |
+ (1 << PHY_ODT_PUUP_EN_SHIFT) | (1 << PHY_ODT_PUDN_EN_SHIFT),
+/* odt enable freq */
+(625 << DRAM_ODT_EN_FREQ_SHIFT) | (625 << PHY_ODT_EN_FREQ_SHIFT),
+/* slew rate when odt enable */
+(0xe << PHY_DQ_SR_SHIFT) | (0x3 << PHY_CA_SR_SHIFT) |
+ (0x3 << PHY_CLK_SR_SHIFT),
+/* slew ratee when odt disable */
+(0xe << PHY_DQ_SR_SHIFT) | (0x3 << PHY_CA_SR_SHIFT) |
+ (0x3 << PHY_CLK_SR_SHIFT),
+
+/* lpddr3 */
+(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT),
+(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT),
+(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT),
+/* drv when odt on */
+(28 << PHY_DQ_DRV_SHIFT) | (37 << PHY_CA_DRV_SHIFT) |
+ (34 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT),
+/* drv when odt off */
+(28 << PHY_DQ_DRV_SHIFT) | (37 << PHY_CA_DRV_SHIFT) |
+ (34 << PHY_CLK_DRV_SHIFT) | (34 << DRAM_DQ_DRV_SHIFT),
+/* odt info */
+(120 << DRAM_ODT_SHIFT) | (148 << PHY_ODT_SHIFT) |
+ (1 << PHY_ODT_PUUP_EN_SHIFT) | (1 << PHY_ODT_PUDN_EN_SHIFT),
+/* odt enable freq */
+(333 << DRAM_ODT_EN_FREQ_SHIFT) | (333 << PHY_ODT_EN_FREQ_SHIFT),
+
+/* slew rate when odt enable */
+(0xe << PHY_DQ_SR_SHIFT) | (0x0 << PHY_CA_SR_SHIFT) |
+ (0x0 << PHY_CLK_SR_SHIFT),
+/* slew ratee when odt disable */
+(0xe << PHY_DQ_SR_SHIFT) | (0x0 << PHY_CA_SR_SHIFT) |
+ (0x0 << PHY_CLK_SR_SHIFT),
+
+/* lpddr4 */
+(924 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT),
+(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT),
+(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT),
+
+/* drv when odt on */
+(38 << PHY_DQ_DRV_SHIFT) | (46 << PHY_CA_DRV_SHIFT) |
+ (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT),
+/* drv when odt off */
+(38 << PHY_DQ_DRV_SHIFT) | (46 << PHY_CA_DRV_SHIFT) |
+ (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT),
+/* odt info and PU-cal info */
+(240 << DRAM_ODT_SHIFT) | (80 << PHY_ODT_SHIFT) |
+ (0 << LP4_CA_ODT_SHIFT) |
+ (LPDDR4_VDDQ_2_5 << LP4_DRV_PU_CAL_ODTEN_SHIFT) |
+ (LPDDR4_VDDQ_2_5 << LP4_DRV_PU_CAL_ODTOFF_SHIFT) |
+ (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT) |
+ (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT),
+/* odt enable freq */
+(333 << PHY_LP4_ODT_EN_FREQ_SHIFT) | (333 << LP4_DQ_ODT_EN_FREQ_SHIFT),
+/* slew rate when odt enable */
+(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) |
+ (0xf << PHY_CLK_SR_SHIFT),
+/* slew ratee when odt disable */
+(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) |
+ (0xf << PHY_CLK_SR_SHIFT),
+/* ca odt en freq */
+(333 << LP4_CA_ODT_EN_FREQ_SHIFT),
+/* cs drv info and ca odt info */
+(0 << PHY_LP4_CS_DRV_ODTEN_SHIFT) |
+ (0 << PHY_LP4_CS_DRV_ODTOFF_SHIFT) |
+ (0 << LP4_ODTE_CK_SHIFT) | (0 << LP4_ODTE_CS_EN_SHIFT) |
+ (0 << LP4_ODTD_CA_EN_SHIFT),
+/* vref info when odt enable */
+(200 << PHY_LP4_DQ_VREF_SHIFT) | (420 << LP4_DQ_VREF_SHIFT) |
+ (420 << LP4_CA_VREF_SHIFT),
+/* vref info when odt disable */
+(420 << PHY_LP4_DQ_VREF_SHIFT) | (420 << LP4_DQ_VREF_SHIFT) |
+ (420 << LP4_CA_VREF_SHIFT),
+/* ddr4 map << 0 | ddr3 map << 24 */
+((0x2 << 6) | (0x1 << 4) | (0x3 << 2) | (0x0 << 0)) |
+ (0 << 8) | (0 << 16) |
+ (((0x2 << 6) | (0x1 << 4) | (0x3 << 2) | (0x0 << 0)) << 24),
+/* lp3 map << 16 | lp4 map << 24 */
+/* lp4 should equal to 0xc9 */
+(((0x3 << 6) | (0x2 << 4) | (0x1 << 2) | (0x0 << 0)) << 16) |
+ (((0x3 << 6) | (0x0 << 4) | (0x2 << 2) | (0x1 << 0)) << 24),
+/* lp3 dq0-7 map */
+(2 << 0) | (6 << 4) | (4 << 8) | (0 << 12) | (3 << 16) | (7 << 20) |
+ ( 5 << 24) | (1 << 28),
+/* lp2 dq0-7 map */
+0,
+/* ddr4 dq map */
+/* cs0 dq0-15 */
+ ((2 << 0 | 0 << 2 | 3 << 4 | 1 << 6) << 0) |
+ ((0 << 0 | 2 << 2 | 3 << 4 | 1 << 6) << 8) |
+ ((2 << 0 | 2 << 2 | 1 << 4 | 3 << 6) << 16) |
+ ((1 << 0 | 3 << 2 | 0 << 4 | 0 << 6) << 24),
+/* cs0 dq16-31 */
+ ((2 << 0 | 0 << 2 | 2 << 4 | 0 << 6) << 0) |
+ ((1 << 0 | 3 << 2 | 3 << 4 | 1 << 6) << 8) |
+ ((0 << 0 | 0 << 2 | 1 << 4 | 3 << 6) << 16) |
+ ((1 << 0 | 3 << 2 | 2 << 4 | 2 << 6) << 24),
+/* cs1 dq0-15 */
+ ((2 << 0 | 0 << 2 | 3 << 4 | 1 << 6) << 0) |
+ ((0 << 0 | 2 << 2 | 3 << 4 | 1 << 6) << 8) |
+ ((2 << 0 | 2 << 2 | 1 << 4 | 3 << 6) << 16) |
+ ((1 << 0 | 3 << 2 | 0 << 4 | 0 << 6) << 24),
+/* cs1 dq16-31 */
+ ((2 << 0 | 0 << 2 | 2 << 4 | 0 << 6) << 0) |
+ ((1 << 0 | 3 << 2 | 3 << 4 | 1 << 6) << 8) |
+ ((0 << 0 | 0 << 2 | 1 << 4 | 3 << 6) << 16) |
+ ((1 << 0 | 3 << 2 | 2 << 4 | 2 << 6) << 24),
+
+/* lpddr4x */
+(1056 << DDR_FREQ_F0_SHIFT) | (328 << DDR_FREQ_F1_SHIFT),
+(528 << DDR_FREQ_F2_SHIFT) | (784 << DDR_FREQ_F3_SHIFT),
+(0 << DDR_FREQ_F4_SHIFT) | (0 << DDR_FREQ_F5_SHIFT),
+
+/* drv when odt on */
+(38 << PHY_DQ_DRV_SHIFT) | (38 << PHY_CA_DRV_SHIFT) |
+ (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT),
+/* drv when odt off */
+(38 << PHY_DQ_DRV_SHIFT) | (38 << PHY_CA_DRV_SHIFT) |
+ (38 << PHY_CLK_DRV_SHIFT) | (40 << DRAM_DQ_DRV_SHIFT),
+/* odt info and PU-cal info */
+(48 << DRAM_ODT_SHIFT) | (60 << PHY_ODT_SHIFT) |
+ (120 << LP4_CA_ODT_SHIFT) |
+ (LPDDR4X_VDDQ_0_6 << LP4_DRV_PU_CAL_ODTEN_SHIFT) |
+ (LPDDR4X_VDDQ_0_6 << LP4_DRV_PU_CAL_ODTOFF_SHIFT) |
+ (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTEN_SHIFT) |
+ (0 << PHY_LP4_DRV_PULLDOWN_EN_ODTOFF_SHIFT),
+/* odt enable freq */
+(0 << PHY_LP4_ODT_EN_FREQ_SHIFT) | (0 << LP4_DQ_ODT_EN_FREQ_SHIFT),
+/* slew rate when odt enable */
+(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) |
+ (0xf << PHY_CLK_SR_SHIFT),
+/* slew ratee when odt disable */
+(0xf << PHY_DQ_SR_SHIFT) | (0xf << PHY_CA_SR_SHIFT) |
+ (0xf << PHY_CLK_SR_SHIFT),
+/* ca odt en freq */
+(333 << LP4_CA_ODT_EN_FREQ_SHIFT),
+/* cs drv info and ca odt info */
+(0 << PHY_LP4_CS_DRV_ODTEN_SHIFT) |
+ (0 << PHY_LP4_CS_DRV_ODTOFF_SHIFT) |
+ (0 << LP4_ODTE_CK_SHIFT) | (0 << LP4_ODTE_CS_EN_SHIFT) |
+ (0 << LP4_ODTD_CA_EN_SHIFT),
+/* vref info when odt enable, phy vddq=1.1V, lp4x vddq=0.6V */
+(153 << PHY_LP4_DQ_VREF_SHIFT) | (515 << LP4_DQ_VREF_SHIFT) |
+ (629 << LP4_CA_VREF_SHIFT),
+/* vref info when odt disable */
+(153 << PHY_LP4_DQ_VREF_SHIFT) | (629 << LP4_DQ_VREF_SHIFT) |
+ (629 << LP4_CA_VREF_SHIFT),
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc
new file mode 100644
index 000000000000..705cbfb5cb08
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-1056.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x41241522},
+ {0x15050b07},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 1056, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x00400094}, /* RFSHTMG */
+ {0x000000d0, 0x00030409}, /* INIT0 */
+ {0x000000d4, 0x00690000}, /* INIT1 */
+ {0x000000d8, 0x00000206}, /* INIT2 */
+ {0x000000dc, 0x0034001b}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00110000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x14161217}, /* DRAMTMG0 */
+ {0x00000104, 0x00040422}, /* DRAMTMG1 */
+ {0x00000108, 0x050a0e0f}, /* DRAMTMG2 */
+ {0x0000010c, 0x00808000}, /* DRAMTMG3 */
+ {0x00000110, 0x0a04060c}, /* DRAMTMG4 */
+ {0x00000114, 0x02040808}, /* DRAMTMG5 */
+ {0x00000118, 0x01010005}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000401}, /* DRAMTMG7 */
+ {0x00000120, 0x00000606}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x0a100002}, /* DRAMTMG13 */
+ {0x00000138, 0x00000098}, /* DRAMTMG14 */
+ {0x00000180, 0x02100010}, /* ZQCTL0 */
+ {0x00000184, 0x01b00000}, /* ZQCTL1 */
+ {0x00000190, 0x07070001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0b050d3c}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x00000014}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x0000000a}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc
new file mode 100644
index 000000000000..3864b0097fea
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-328.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x2f0d060a},
+ {0x07020804},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 328, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x0014002e}, /* RFSHTMG */
+ {0x000000d0, 0x00020142}, /* INIT0 */
+ {0x000000d4, 0x00220000}, /* INIT1 */
+ {0x000000d8, 0x00000202}, /* INIT2 */
+ {0x000000dc, 0x00240012}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00100000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x0c070507}, /* DRAMTMG0 */
+ {0x00000104, 0x0003040b}, /* DRAMTMG1 */
+ {0x00000108, 0x04070c0d}, /* DRAMTMG2 */
+ {0x0000010c, 0x00505000}, /* DRAMTMG3 */
+ {0x00000110, 0x03040204}, /* DRAMTMG4 */
+ {0x00000114, 0x02030303}, /* DRAMTMG5 */
+ {0x00000118, 0x01010004}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000301}, /* DRAMTMG7 */
+ {0x00000120, 0x00000303}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x00100002}, /* DRAMTMG13 */
+ {0x00000138, 0x00000030}, /* DRAMTMG14 */
+ {0x00000180, 0x00a40005}, /* ZQCTL0 */
+ {0x00000184, 0x00900000}, /* ZQCTL1 */
+ {0x00000190, 0x07040000}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0905092c}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x0000000e}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000008}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc
new file mode 100644
index 000000000000..9018c3a7635b
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-396.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x3110080d},
+ {0x08020804},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 396, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x00180038}, /* RFSHTMG */
+ {0x000000d0, 0x00020184}, /* INIT0 */
+ {0x000000d4, 0x00280000}, /* INIT1 */
+ {0x000000d8, 0x00000202}, /* INIT2 */
+ {0x000000dc, 0x00240012}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00100000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x0d080609}, /* DRAMTMG0 */
+ {0x00000104, 0x0003040d}, /* DRAMTMG1 */
+ {0x00000108, 0x04070c0d}, /* DRAMTMG2 */
+ {0x0000010c, 0x00505000}, /* DRAMTMG3 */
+ {0x00000110, 0x04040205}, /* DRAMTMG4 */
+ {0x00000114, 0x02030303}, /* DRAMTMG5 */
+ {0x00000118, 0x01010004}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000301}, /* DRAMTMG7 */
+ {0x00000120, 0x00000303}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x00100002}, /* DRAMTMG13 */
+ {0x00000138, 0x00000039}, /* DRAMTMG14 */
+ {0x00000180, 0x00c60006}, /* ZQCTL0 */
+ {0x00000184, 0x00a00000}, /* ZQCTL1 */
+ {0x00000190, 0x07040000}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0905092c}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x0000000e}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000008}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc
new file mode 100644
index 000000000000..8c8e14c37642
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-528.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x34140b11},
+ {0x0b030804},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 528, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 0
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x0020004a}, /* RFSHTMG */
+ {0x000000d0, 0x00020205}, /* INIT0 */
+ {0x000000d4, 0x00350000}, /* INIT1 */
+ {0x000000d8, 0x00000203}, /* INIT2 */
+ {0x000000dc, 0x00240012}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00100000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x0e0b090c}, /* DRAMTMG0 */
+ {0x00000104, 0x00030412}, /* DRAMTMG1 */
+ {0x00000108, 0x04070c0d}, /* DRAMTMG2 */
+ {0x0000010c, 0x00505000}, /* DRAMTMG3 */
+ {0x00000110, 0x05040306}, /* DRAMTMG4 */
+ {0x00000114, 0x02030404}, /* DRAMTMG5 */
+ {0x00000118, 0x01010004}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000301}, /* DRAMTMG7 */
+ {0x00000120, 0x00000404}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x00100002}, /* DRAMTMG13 */
+ {0x00000138, 0x0000004c}, /* DRAMTMG14 */
+ {0x00000180, 0x01080008}, /* ZQCTL0 */
+ {0x00000184, 0x00e00000}, /* ZQCTL1 */
+ {0x00000190, 0x07040000}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0905092c}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x0000000e}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000008}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc
new file mode 100644
index 000000000000..f601fe5cb6a1
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-664.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x36170d15},
+ {0x0d030805},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 664, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x0028005d}, /* RFSHTMG */
+ {0x000000d0, 0x0002028a}, /* INIT0 */
+ {0x000000d4, 0x00420000}, /* INIT1 */
+ {0x000000d8, 0x00000204}, /* INIT2 */
+ {0x000000dc, 0x00240012}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00110000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x0f0e0b0e}, /* DRAMTMG0 */
+ {0x00000104, 0x00030415}, /* DRAMTMG1 */
+ {0x00000108, 0x04070d0d}, /* DRAMTMG2 */
+ {0x0000010c, 0x00505000}, /* DRAMTMG3 */
+ {0x00000110, 0x06040407}, /* DRAMTMG4 */
+ {0x00000114, 0x02030505}, /* DRAMTMG5 */
+ {0x00000118, 0x01010004}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000301}, /* DRAMTMG7 */
+ {0x00000120, 0x00000404}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x00100002}, /* DRAMTMG13 */
+ {0x00000138, 0x00000060}, /* DRAMTMG14 */
+ {0x00000180, 0x014c000a}, /* ZQCTL0 */
+ {0x00000184, 0x01100000}, /* ZQCTL1 */
+ {0x00000190, 0x07040000}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0a040b28}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x0000000e}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000008}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc
new file mode 100644
index 000000000000..b8d9d5f1ce7b
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-784.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x391b1019},
+ {0x10040805},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 784, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x002f006e}, /* RFSHTMG */
+ {0x000000d0, 0x000202ff}, /* INIT0 */
+ {0x000000d4, 0x004e0000}, /* INIT1 */
+ {0x000000d8, 0x00000204}, /* INIT2 */
+ {0x000000dc, 0x00240012}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00110000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x10100d11}, /* DRAMTMG0 */
+ {0x00000104, 0x00030419}, /* DRAMTMG1 */
+ {0x00000108, 0x04070c0d}, /* DRAMTMG2 */
+ {0x0000010c, 0x00606000}, /* DRAMTMG3 */
+ {0x00000110, 0x08040409}, /* DRAMTMG4 */
+ {0x00000114, 0x02030606}, /* DRAMTMG5 */
+ {0x00000118, 0x01010004}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000301}, /* DRAMTMG7 */
+ {0x00000120, 0x00000505}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x00100002}, /* DRAMTMG13 */
+ {0x00000138, 0x00000071}, /* DRAMTMG14 */
+ {0x00000180, 0x0188000c}, /* ZQCTL0 */
+ {0x00000184, 0x01400000}, /* ZQCTL1 */
+ {0x00000190, 0x07040000}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0a040b28}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x0000000e}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x00000008}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc
new file mode 100644
index 000000000000..a2050f615343
--- /dev/null
+++ b/drivers/ram/rockchip/sdram-rv1126-lpddr4-detect-924.inc
@@ -0,0 +1,78 @@
+{
+ {
+ {
+ .rank = 0x1,
+ .col = 0xB,
+ .bk = 0x3,
+ .bw = 0x1,
+ .dbw = 0x1,
+ .row_3_4 = 0x0,
+ .cs0_row = 0x11,
+ .cs1_row = 0x11,
+ .cs0_high16bit_row = 0x0,
+ .cs1_high16bit_row = 0x0,
+ .ddrconfig = 0
+ },
+ {
+ {0x3e20121d},
+ {0x12050a07},
+ {0x00000602},
+ {0x00001111},
+ {0x00000054},
+ {0x00000000},
+ 0x000000ff
+ }
+ },
+ {
+ .ddr_freq = 924, /* clock rate(MHz) */
+ .dramtype = LPDDR4,
+ .num_channels = 1,
+ .stride = 0,
+ .odt = 1
+ },
+ {
+ {
+ {0x00000000, 0x81081020}, /* MSTR */
+ {0x00000064, 0x00380082}, /* RFSHTMG */
+ {0x000000d0, 0x00020388}, /* INIT0 */
+ {0x000000d4, 0x005c0000}, /* INIT1 */
+ {0x000000d8, 0x00000205}, /* INIT2 */
+ {0x000000dc, 0x0034001b}, /* INIT3 */
+ {0x000000e0, 0x00310000}, /* INIT4 */
+ {0x000000e8, 0x00110000}, /* INIT6 */
+ {0x000000ec, 0x00000000}, /* INIT7 */
+ {0x000000f4, 0x000f033f}, /* RANKCTL */
+ {0x00000100, 0x12130f14}, /* DRAMTMG0 */
+ {0x00000104, 0x0004041e}, /* DRAMTMG1 */
+ {0x00000108, 0x050a0e0f}, /* DRAMTMG2 */
+ {0x0000010c, 0x00707000}, /* DRAMTMG3 */
+ {0x00000110, 0x0904050a}, /* DRAMTMG4 */
+ {0x00000114, 0x02040707}, /* DRAMTMG5 */
+ {0x00000118, 0x01010005}, /* DRAMTMG6 */
+ {0x0000011c, 0x00000401}, /* DRAMTMG7 */
+ {0x00000120, 0x00000606}, /* DRAMTMG8 */
+ {0x00000130, 0x00020000}, /* DRAMTMG12 */
+ {0x00000134, 0x0a100002}, /* DRAMTMG13 */
+ {0x00000138, 0x00000085}, /* DRAMTMG14 */
+ {0x00000180, 0x01ce000e}, /* ZQCTL0 */
+ {0x00000184, 0x01800000}, /* ZQCTL1 */
+ {0x00000190, 0x07070001}, /* DFITMG0 */
+ {0x00000198, 0x07000101}, /* DFILPCFG0 */
+ {0x000001a0, 0xc0400003}, /* DFIUPD0 */
+ {0x00000240, 0x0b050d3c}, /* ODTCFG */
+ {0x00000244, 0x00000101}, /* ODTMAP */
+ {0x00000250, 0x00001f00}, /* SCHED */
+ {0x00000490, 0x00000001}, /* PCTRL_0 */
+ {0xffffffff, 0xffffffff}
+ }
+ },
+ {
+ {
+ {0x00000004, 0x0000008d}, /* PHYREG01 */
+ {0x00000014, 0x00000014}, /* PHYREG05 */
+ {0x00000018, 0x00000000}, /* PHYREG06 */
+ {0x0000001c, 0x0000000a}, /* PHYREG07 */
+ {0xffffffff, 0xffffffff}
+ }
+ }
+},
diff --git a/drivers/ram/rockchip/sdram_common.c b/drivers/ram/rockchip/sdram_common.c
index ec46ba54575e..60fc90d0a5c0 100644
--- a/drivers/ram/rockchip/sdram_common.c
+++ b/drivers/ram/rockchip/sdram_common.c
@@ -36,7 +36,7 @@ void sdram_print_dram_type(unsigned char dramtype)
}
void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base)
+ struct sdram_base_params *base, u32 split)
{
u64 cap;
u32 bg;
@@ -83,6 +83,8 @@ void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
cap = sdram_get_cs_cap(cap_info, 3, base->dramtype);
if (cap_info->row_3_4)
cap = cap * 3 / 4;
+ else if (split)
+ cap = cap / 2 + (split << 24) / 2;
printascii(" Size=");
printdec(cap >> 20);
@@ -123,7 +125,7 @@ inline void sdram_print_dram_type(unsigned char dramtype)
}
inline void sdram_print_ddr_info(struct sdram_cap_info *cap_info,
- struct sdram_base_params *base)
+ struct sdram_base_params *base, u32 split)
{
}
diff --git a/drivers/ram/rockchip/sdram_pctl_px30.c b/drivers/ram/rockchip/sdram_pctl_px30.c
index 331d85fba269..e5c80fb83b3f 100644
--- a/drivers/ram/rockchip/sdram_pctl_px30.c
+++ b/drivers/ram/rockchip/sdram_pctl_px30.c
@@ -21,7 +21,7 @@ void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
continue;
- while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & PCTL2_MR_WR_BUSY)
continue;
}
@@ -33,7 +33,7 @@ void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
u32 dramtype)
{
- while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & PCTL2_MR_WR_BUSY)
continue;
if (dramtype == DDR3 || dramtype == DDR4) {
writel((mr_num << 12) | (rank << 4) | (0 << 0),
@@ -49,7 +49,7 @@ int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
continue;
- while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+ while (readl(pctl_base + DDR_PCTL2_MRSTAT) & PCTL2_MR_WR_BUSY)
continue;
return 0;
diff --git a/drivers/ram/rockchip/sdram_px30.c b/drivers/ram/rockchip/sdram_px30.c
index 98b2593ac49f..2728d93be322 100644
--- a/drivers/ram/rockchip/sdram_px30.c
+++ b/drivers/ram/rockchip/sdram_px30.c
@@ -125,11 +125,11 @@ u32 addrmap[][8] = {
struct dram_info dram_info;
struct px30_sdram_params sdram_configs[] = {
-#if defined(CONFIG_RAM_PX30_DDR4)
+#if defined(CONFIG_RAM_ROCKCHIP_DDR4)
#include "sdram-px30-ddr4-detect-333.inc"
-#elif defined(CONFIG_RAM_PX30_LPDDR2)
+#elif defined(CONFIG_RAM_ROCKCHIP_LPDDR2)
#include "sdram-px30-lpddr2-detect-333.inc"
-#elif defined(CONFIG_RAM_PX30_LPDDR3)
+#elif defined(CONFIG_RAM_ROCKCHIP_LPDDR3)
#include "sdram-px30-lpddr3-detect-333.inc"
#else
#include "sdram-px30-ddr3-detect-333.inc"
@@ -711,7 +711,7 @@ int sdram_init(void)
if (ret)
goto error;
- sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
+ sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base, 0);
printascii("out\n");
return ret;
diff --git a/drivers/ram/rockchip/sdram_rk3328.c b/drivers/ram/rockchip/sdram_rk3328.c
index b511c6bf6fe5..184c93f7763d 100644
--- a/drivers/ram/rockchip/sdram_rk3328.c
+++ b/drivers/ram/rockchip/sdram_rk3328.c
@@ -506,7 +506,7 @@ static int sdram_init_detect(struct dram_info *dram,
writel(sys_reg3, &dram->grf->os_reg[3]);
}
- sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base);
+ sdram_print_ddr_info(&sdram_params->ch.cap_info, &sdram_params->base, 0);
return 0;
}
diff --git a/drivers/ram/rockchip/sdram_rk3399.c b/drivers/ram/rockchip/sdram_rk3399.c
index 136e4ede7122..b1fea04e84ae 100644
--- a/drivers/ram/rockchip/sdram_rk3399.c
+++ b/drivers/ram/rockchip/sdram_rk3399.c
@@ -1625,7 +1625,7 @@ static void set_ddr_stride(struct rk3399_pmusgrf_regs *pmusgrf, u32 stride)
rk_clrsetreg(&pmusgrf->soc_con4, 0x1f << 10, stride << 10);
}
-#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+#if !defined(CONFIG_RAM_ROCKCHIP_LPDDR4)
static int data_training_first(struct dram_info *dram, u32 channel, u8 rank,
struct rk3399_sdram_params *params)
{
@@ -2558,8 +2558,7 @@ static int lpddr4_set_rate(struct dram_info *dram,
return 0;
}
-
-#endif /* CONFIG_RAM_RK3399_LPDDR4 */
+#endif /* CONFIG_RAM_ROCKCHIP_LPDDR4 */
/* CS0,n=1
* CS1,n=2
@@ -2987,7 +2986,7 @@ static int sdram_init(struct dram_info *dram,
continue;
}
- sdram_print_ddr_info(cap_info, &params->base);
+ sdram_print_ddr_info(cap_info, &params->base, 0);
set_memory_map(chan, channel, params);
cap_info->ddrconfig =
calculate_ddrconfig(params, channel);
@@ -3059,7 +3058,7 @@ static int conv_of_plat(struct udevice *dev)
#endif
static const struct sdram_rk3399_ops rk3399_ops = {
-#if !defined(CONFIG_RAM_RK3399_LPDDR4)
+#if !defined(CONFIG_RAM_ROCKCHIP_LPDDR4)
.data_training_first = data_training_first,
.set_rate_index = switch_to_phy_index1,
.modify_param = modify_param,
diff --git a/drivers/ram/rockchip/sdram_rv1126.c b/drivers/ram/rockchip/sdram_rv1126.c
new file mode 100644
index 000000000000..9e1376a940fc
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rv1126.c
@@ -0,0 +1,3543 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2020 Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/cru_rv1126.h>
+#include <asm/arch-rockchip/grf_rv1126.h>
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_rv1126.h>
+#include <linux/delay.h>
+
+/* define training flag */
+#define CA_TRAINING (0x1 << 0)
+#define READ_GATE_TRAINING (0x1 << 1)
+#define WRITE_LEVELING (0x1 << 2)
+#define WRITE_TRAINING (0x1 << 3)
+#define READ_TRAINING (0x1 << 4)
+#define FULL_TRAINING (0xff)
+
+#define SKEW_RX_SIGNAL (0)
+#define SKEW_TX_SIGNAL (1)
+#define SKEW_CA_SIGNAL (2)
+
+#define DESKEW_MDF_ABS_VAL (0)
+#define DESKEW_MDF_DIFF_VAL (1)
+
+struct dram_info {
+#if defined(CONFIG_TPL_BUILD) || \
+ (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
+ void __iomem *pctl;
+ void __iomem *phy;
+ struct rv1126_cru *cru;
+ struct msch_regs *msch;
+ struct rv1126_ddrgrf *ddrgrf;
+ struct rv1126_grf *grf;
+ u32 sr_idle;
+ u32 pd_idle;
+#endif
+ struct ram_info info;
+ struct rv1126_pmugrf *pmugrf;
+};
+
+#if defined(CONFIG_TPL_BUILD) || \
+ (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
+
+#define GRF_BASE_ADDR 0xfe000000
+#define PMU_GRF_BASE_ADDR 0xfe020000
+#define DDR_GRF_BASE_ADDR 0xfe030000
+#define BUS_SGRF_BASE_ADDR 0xfe0a0000
+#define SERVER_MSCH_BASE_ADDR 0xfe800000
+#define CRU_BASE_ADDR 0xff490000
+#define DDR_PHY_BASE_ADDR 0xff4a0000
+#define UPCTL2_BASE_ADDR 0xffa50000
+
+#define SGRF_SOC_CON2 0x8
+#define SGRF_SOC_CON12 0x30
+#define SGRF_SOC_CON13 0x34
+
+struct dram_info dram_info;
+
+struct rv1126_sdram_params sdram_configs[] = {
+#if defined(CONFIG_RAM_ROCKCHIP_LPDDR4)
+# include "sdram-rv1126-lpddr4-detect-328.inc"
+# include "sdram-rv1126-lpddr4-detect-396.inc"
+# include "sdram-rv1126-lpddr4-detect-528.inc"
+# include "sdram-rv1126-lpddr4-detect-664.inc"
+# include "sdram-rv1126-lpddr4-detect-784.inc"
+# include "sdram-rv1126-lpddr4-detect-924.inc"
+# include "sdram-rv1126-lpddr4-detect-1056.inc"
+#else
+# include "sdram-rv1126-ddr3-detect-328.inc"
+# include "sdram-rv1126-ddr3-detect-396.inc"
+# include "sdram-rv1126-ddr3-detect-528.inc"
+# include "sdram-rv1126-ddr3-detect-664.inc"
+# include "sdram-rv1126-ddr3-detect-784.inc"
+# include "sdram-rv1126-ddr3-detect-924.inc"
+# include "sdram-rv1126-ddr3-detect-1056.inc"
+#endif
+};
+
+u32 common_info[] = {
+#include "sdram-rv1126-loader_params.inc"
+};
+
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+static struct rw_trn_result rw_trn_result;
+#endif
+
+static struct rv1126_fsp_param fsp_param[MAX_IDX];
+
+static u8 lp3_odt_value;
+
+static s8 wrlvl_result[2][4];
+
+/* DDR configuration 0-9 */
+u16 ddr_cfg_2_rbc[] = {
+ ((0 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 3), /* 0 */
+ ((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 2), /* 1 */
+ ((1 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 3), /* 2 */
+ ((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 1), /* 3 */
+ ((0 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 4), /* 4 */
+ ((0 << 8) | (3 << 5) | (1 << 4) | (1 << 3) | 1), /* 5 */
+ ((0 << 8) | (3 << 5) | (1 << 4) | (1 << 3) | 2), /* 6 */
+ ((0 << 8) | (2 << 5) | (1 << 4) | (1 << 3) | 3), /* 7 */
+ ((1 << 8) | (3 << 5) | (0 << 4) | (0 << 3) | 2), /* 8 */
+ ((1 << 8) | (2 << 5) | (0 << 4) | (1 << 3) | 2) /* 9 */
+};
+
+/* DDR configuration 10-21 */
+u8 ddr4_cfg_2_rbc[] = {
+ ((0 << 7) | (3 << 4) | (0 << 3) | (2 << 1) | 0), /* 10 */
+ ((1 << 7) | (2 << 4) | (0 << 3) | (2 << 1) | 0), /* 11 */
+ ((0 << 7) | (4 << 4) | (0 << 3) | (1 << 1) | 0), /* 12 */
+ ((1 << 7) | (3 << 4) | (0 << 3) | (1 << 1) | 0), /* 13 */
+ ((0 << 7) | (4 << 4) | (0 << 3) | (2 << 1) | 1), /* 14 */
+ ((1 << 7) | (3 << 4) | (0 << 3) | (2 << 1) | 1), /* 15 */
+ ((1 << 7) | (4 << 4) | (0 << 3) | (1 << 1) | 1), /* 16 */
+ ((0 << 7) | (2 << 4) | (1 << 3) | (2 << 1) | 0), /* 17 */
+ ((0 << 7) | (3 << 4) | (1 << 3) | (1 << 1) | 0), /* 18 */
+ ((0 << 7) | (3 << 4) | (1 << 3) | (2 << 1) | 1), /* 19 */
+ ((0 << 7) | (4 << 4) | (1 << 3) | (1 << 1) | 1), /* 20 */
+ ((1 << 7) | (4 << 4) | (0 << 3) | (0 << 1) | 0) /* 21 */
+};
+
+/* DDR configuration 22-28 */
+u16 ddr_cfg_2_rbc_p2[] = {
+ ((1 << 8) | (3 << 5) | (0 << 4) | (1 << 3) | 0), /* 22 */
+ ((0 << 8) | (4 << 5) | (0 << 4) | (1 << 3) | 2), /* 23 */
+ ((1 << 8) | (3 << 5) | (0 << 4) | (0 << 3) | 3), /* 24 */
+ ((0 << 8) | (3 << 5) | (1 << 4) | (0 << 3) | 3), /* 25 */
+ ((0 << 8) | (4 << 5) | (1 << 4) | (0 << 3) | 2), /* 26 */
+ ((1 << 8) | (4 << 5) | (0 << 4) | (0 << 3) | 2), /* 27 */
+ ((0 << 8) | (4 << 5) | (0 << 4) | (0 << 3) | 3) /* 28 */
+};
+
+u8 d4_rbc_2_d3_rbc[][2] = {
+ {10, 0},
+ {11, 2},
+ {12, 23},
+ {13, 1},
+ {14, 28},
+ {15, 24},
+ {16, 27},
+ {17, 7},
+ {18, 6},
+ {19, 25},
+ {20, 26},
+ {21, 3}
+};
+
+u32 addrmap[29][9] = {
+ {24, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x3f3f}, /* 0 */
+ {23, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f0f, 0x3f3f}, /* 1 */
+ {23, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
+ 0x0f080808, 0x00000f0f, 0x3f3f}, /* 2 */
+ {22, 0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000f0f, 0x3f3f}, /* 3 */
+ {24, 0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
+ 0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
+ {6, 0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f0f, 0x3f3f}, /* 5 */
+ {7, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x3f3f}, /* 6 */
+ {8, 0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x09090909,
+ 0x0f090909, 0x00000f0f, 0x3f3f}, /* 7 */
+ {22, 0x001f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000f0f, 0x3f3f}, /* 8 */
+ {23, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+ 0x0f070707, 0x00000f0f, 0x3f3f}, /* 9 */
+
+ {24, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x0801}, /* 10 */
+ {23, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
+ 0x0f080808, 0x00000f0f, 0x0801}, /* 11 */
+ {24, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x0700}, /* 12 */
+ {23, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f0f, 0x0700}, /* 13 */
+ {24, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f01}, /* 14 */
+ {23, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f0f, 0x3f01}, /* 15 */
+ {23, 0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000f06, 0x3f00}, /* 16 */
+ {8, 0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x09090909,
+ 0x0f090909, 0x00000f0f, 0x0801}, /* 17 */
+ {7, 0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x0700}, /* 18 */
+ {7, 0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x3f01}, /* 19 */
+
+ {6, 0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f00}, /* 20 */
+ {23, 0x003f0909, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000f06, 0x0600}, /* 21 */
+ {21, 0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
+ 0x05050505, 0x00000f0f, 0x3f3f}, /* 22 */
+
+ {24, 0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f3f}, /* 23 */
+ {23, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x07070707,
+ 0x07070707, 0x00000f0f, 0x3f3f}, /* 24 */
+ {7, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
+ 0x08080808, 0x00000f0f, 0x3f3f}, /* 25 */
+ {6, 0x003f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f3f}, /* 26 */
+ {23, 0x003f0808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
+ 0x06060606, 0x00000f06, 0x3f3f}, /* 27 */
+ {24, 0x003f0909, 0x00000000, 0x00000000, 0x00001f00, 0x07070707,
+ 0x07070707, 0x00000f07, 0x3f3f} /* 28 */
+};
+
+static u8 dq_sel[22][3] = {
+ {0x0, 0x17, 0x22},
+ {0x1, 0x18, 0x23},
+ {0x2, 0x19, 0x24},
+ {0x3, 0x1a, 0x25},
+ {0x4, 0x1b, 0x26},
+ {0x5, 0x1c, 0x27},
+ {0x6, 0x1d, 0x28},
+ {0x7, 0x1e, 0x29},
+ {0x8, 0x16, 0x21},
+ {0x9, 0x1f, 0x2a},
+ {0xa, 0x20, 0x2b},
+ {0x10, 0x1, 0xc},
+ {0x11, 0x2, 0xd},
+ {0x12, 0x3, 0xe},
+ {0x13, 0x4, 0xf},
+ {0x14, 0x5, 0x10},
+ {0x15, 0x6, 0x11},
+ {0x16, 0x7, 0x12},
+ {0x17, 0x8, 0x13},
+ {0x18, 0x0, 0xb},
+ {0x19, 0x9, 0x14},
+ {0x1a, 0xa, 0x15}
+};
+
+static u16 grp_addr[4] = {
+ ADD_GROUP_CS0_A,
+ ADD_GROUP_CS0_B,
+ ADD_GROUP_CS1_A,
+ ADD_GROUP_CS1_B
+};
+
+static u8 wrlvl_result_offset[2][4] = {
+ {0xa0 + 0x26, 0xa0 + 0x27, 0xd0 + 0x26, 0xd0 + 0x27},
+ {0xa0 + 0x28, 0xa0 + 0x29, 0xd0 + 0x28, 0xd0 + 0x29},
+};
+
+static u16 dqs_dq_skew_adr[16] = {
+ 0x170 + 0, /* SKEW_UPDATE_RX_CS0_DQS0 */
+ 0x170 + 0xb, /* SKEW_UPDATE_RX_CS0_DQS1 */
+ 0x1d0 + 0, /* SKEW_UPDATE_RX_CS0_DQS2 */
+ 0x1d0 + 0xb, /* SKEW_UPDATE_RX_CS0_DQS3 */
+ 0x1a0 + 0, /* SKEW_UPDATE_RX_CS1_DQS0 */
+ 0x1a0 + 0xb, /* SKEW_UPDATE_RX_CS1_DQS1 */
+ 0x200 + 0, /* SKEW_UPDATE_RX_CS1_DQS2 */
+ 0x200 + 0xb, /* SKEW_UPDATE_RX_CS1_DQS3 */
+ 0x170 + 0x16, /* SKEW_UPDATE_TX_CS0_DQS0 */
+ 0x170 + 0x21, /* SKEW_UPDATE_TX_CS0_DQS1 */
+ 0x1d0 + 0x16, /* SKEW_UPDATE_TX_CS0_DQS2 */
+ 0x1d0 + 0x21, /* SKEW_UPDATE_TX_CS0_DQS3 */
+ 0x1a0 + 0x16, /* SKEW_UPDATE_TX_CS1_DQS0 */
+ 0x1a0 + 0x21, /* SKEW_UPDATE_TX_CS1_DQS1 */
+ 0x200 + 0x16, /* SKEW_UPDATE_TX_CS1_DQS2 */
+ 0x200 + 0x21, /* SKEW_UPDATE_TX_CS1_DQS3 */
+};
+
+static void rkclk_ddr_reset(struct dram_info *dram,
+ u32 ctl_srstn, u32 ctl_psrstn,
+ u32 phy_srstn, u32 phy_psrstn)
+{
+ writel(UPCTL2_SRSTN_REQ(ctl_srstn) | UPCTL2_PSRSTN_REQ(ctl_psrstn) |
+ UPCTL2_ASRSTN_REQ(ctl_srstn),
+ BUS_SGRF_BASE_ADDR + SGRF_SOC_CON13);
+
+ writel(DDRPHY_SRSTN_REQ(phy_srstn) | DDRPHY_PSRSTN_REQ(phy_psrstn),
+ &dram->cru->softrst_con[12]);
+}
+
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
+{
+ unsigned int refdiv, postdiv1, postdiv2, fbdiv;
+ int delay = 1000;
+ u32 mhz = hz / MHz;
+ struct global_info *gbl_info;
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ u32 ssmod_info;
+ u32 dsmpd = 1;
+
+ gbl_info = (struct global_info *)((void *)common_info +
+ index->global_index.offset * 4);
+ ssmod_info = gbl_info->info_2t;
+ refdiv = 1;
+ if (mhz <= 100) {
+ postdiv1 = 6;
+ postdiv2 = 4;
+ } else if (mhz <= 150) {
+ postdiv1 = 4;
+ postdiv2 = 4;
+ } else if (mhz <= 200) {
+ postdiv1 = 6;
+ postdiv2 = 2;
+ } else if (mhz <= 300) {
+ postdiv1 = 4;
+ postdiv2 = 2;
+ } else if (mhz <= 400) {
+ postdiv1 = 6;
+ postdiv2 = 1;
+ } else {
+ postdiv1 = 4;
+ postdiv2 = 1;
+ }
+ fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
+
+ writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
+
+ writel(0x1f000000, &dram->cru->clksel_con[64]);
+ writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
+ /* enable ssmod */
+ if (PLL_SSMOD_SPREAD(ssmod_info)) {
+ dsmpd = 0;
+ clrsetbits_le32(&dram->cru->pll[1].con2,
+ 0xffffff << 0, 0x0 << 0);
+ writel(SSMOD_SPREAD(PLL_SSMOD_SPREAD(ssmod_info)) |
+ SSMOD_DIVVAL(PLL_SSMOD_DIV(ssmod_info)) |
+ SSMOD_DOWNSPREAD(PLL_SSMOD_DOWNSPREAD(ssmod_info)) |
+ SSMOD_RESET(0) |
+ SSMOD_DIS_SSCG(0) |
+ SSMOD_BP(0),
+ &dram->cru->pll[1].con3);
+ }
+ writel(DSMPD(dsmpd) | POSTDIV2(postdiv2) | REFDIV(refdiv),
+ &dram->cru->pll[1].con1);
+
+ while (delay > 0) {
+ udelay(1);
+ if (LOCK(readl(&dram->cru->pll[1].con1)))
+ break;
+ delay--;
+ }
+
+ writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
+}
+
+static void rkclk_configure_ddr(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ /* for inno ddr phy need freq / 2 */
+ rkclk_set_dpll(dram, sdram_params->base.ddr_freq * MHZ / 2);
+}
+
+static unsigned int
+ calculate_ddrconfig(struct rv1126_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 cs, bw, die_bw, col, row, bank;
+ u32 cs1_row;
+ u32 i, tmp;
+ u32 ddrconf = -1;
+ u32 row_3_4;
+
+ cs = cap_info->rank;
+ bw = cap_info->bw;
+ die_bw = cap_info->dbw;
+ col = cap_info->col;
+ row = cap_info->cs0_row;
+ cs1_row = cap_info->cs1_row;
+ bank = cap_info->bk;
+ row_3_4 = cap_info->row_3_4;
+
+ if (sdram_params->base.dramtype == DDR4) {
+ if (cs == 2 && row == cs1_row && !row_3_4) {
+ tmp = ((row - 13) << 4) | (1 << 3) | (bw << 1) |
+ die_bw;
+ for (i = 17; i < 21; i++) {
+ if (((tmp & 0xf) ==
+ (ddr4_cfg_2_rbc[i - 10] & 0xf)) &&
+ ((tmp & 0x70) <=
+ (ddr4_cfg_2_rbc[i - 10] & 0x70))) {
+ ddrconf = i;
+ goto out;
+ }
+ }
+ }
+
+ tmp = ((cs - 1) << 7) | ((row - 13) << 4) | (bw << 1) | die_bw;
+ for (i = 10; i < 21; i++) {
+ if (((tmp & 0xf) == (ddr4_cfg_2_rbc[i - 10] & 0xf)) &&
+ ((tmp & 0x70) <= (ddr4_cfg_2_rbc[i - 10] & 0x70)) &&
+ ((tmp & 0x80) <= (ddr4_cfg_2_rbc[i - 10] & 0x80))) {
+ ddrconf = i;
+ goto out;
+ }
+ }
+ } else {
+ if (cs == 2 && row == cs1_row && bank == 3) {
+ for (i = 5; i < 8; i++) {
+ if (((bw + col - 10) == (ddr_cfg_2_rbc[i] &
+ 0x7)) &&
+ ((row - 13) << 5) <= (ddr_cfg_2_rbc[i] &
+ (0x7 << 5))) {
+ ddrconf = i;
+ goto out;
+ }
+ }
+ }
+
+ tmp = ((cs - 1) << 8) | ((row - 13) << 5) |
+ ((bw + col - 10) << 0);
+ if (bank == 3)
+ tmp |= (1 << 3);
+
+ for (i = 0; i < 9; i++)
+ if (((tmp & 0x1f) == (ddr_cfg_2_rbc[i] & 0x1f)) &&
+ ((tmp & (7 << 5)) <=
+ (ddr_cfg_2_rbc[i] & (7 << 5))) &&
+ ((tmp & (1 << 8)) <=
+ (ddr_cfg_2_rbc[i] & (1 << 8)))) {
+ ddrconf = i;
+ goto out;
+ }
+
+ for (i = 0; i < 7; i++)
+ if (((tmp & 0x1f) == (ddr_cfg_2_rbc_p2[i] & 0x1f)) &&
+ ((tmp & (7 << 5)) <=
+ (ddr_cfg_2_rbc_p2[i] & (7 << 5))) &&
+ ((tmp & (1 << 8)) <=
+ (ddr_cfg_2_rbc_p2[i] & (1 << 8)))) {
+ ddrconf = i + 22;
+ goto out;
+ }
+
+ if (cs == 1 && bank == 3 && row <= 17 &&
+ (col + bw) == 12)
+ ddrconf = 23;
+ }
+
+out:
+ if (ddrconf > 28)
+ printascii("calculate ddrconfig error\n");
+
+ if (sdram_params->base.dramtype == DDR4) {
+ for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc) ; i++) {
+ if (ddrconf == d4_rbc_2_d3_rbc[i][0]) {
+ if (ddrconf == 21 && row > 16)
+ printascii("warn:ddrconf21 row > 16\n");
+ else
+ ddrconf = d4_rbc_2_d3_rbc[i][1];
+ break;
+ }
+ }
+ }
+
+ return ddrconf;
+}
+
+static void sw_set_req(struct dram_info *dram)
+{
+ void __iomem *pctl_base = dram->pctl;
+
+ /* clear sw_done=0 */
+ writel(PCTL2_SW_DONE_CLEAR, pctl_base + DDR_PCTL2_SWCTL);
+}
+
+static void sw_set_ack(struct dram_info *dram)
+{
+ void __iomem *pctl_base = dram->pctl;
+
+ /* set sw_done=1 */
+ writel(PCTL2_SW_DONE, pctl_base + DDR_PCTL2_SWCTL);
+ while (1) {
+ /* wait programming done */
+ if (readl(pctl_base + DDR_PCTL2_SWSTAT) &
+ PCTL2_SW_DONE_ACK)
+ break;
+ }
+}
+
+static void set_ctl_address_map(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ void __iomem *pctl_base = dram->pctl;
+ u32 ddrconf = cap_info->ddrconfig;
+ u32 i, row;
+
+ row = cap_info->cs0_row;
+ if (sdram_params->base.dramtype == DDR4) {
+ for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc) ; i++) {
+ if (ddrconf == d4_rbc_2_d3_rbc[i][1]) {
+ ddrconf = d4_rbc_2_d3_rbc[i][0];
+ break;
+ }
+ }
+ }
+
+ if (ddrconf >= ARRAY_SIZE(addrmap)) {
+ printascii("set ctl address map fail\n");
+ return;
+ }
+
+ sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP0),
+ &addrmap[ddrconf][0], ARRAY_SIZE(addrmap[ddrconf]) * 4);
+
+ /* unused row set to 0xf */
+ for (i = 17; i >= row; i--)
+ setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
+ ((i - 12) * 8 / 32) * 4,
+ 0xf << ((i - 12) * 8 % 32));
+
+ if (sdram_params->base.dramtype == LPDDR3 && cap_info->row_3_4)
+ setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
+ if (sdram_params->base.dramtype == DDR4 && cap_info->bw == 0x1)
+ setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
+
+ if (cap_info->rank == 1)
+ clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP0, 0x1f, 0x1f);
+}
+
+static void phy_pll_set(struct dram_info *dram, u32 freq, u32 wait)
+{
+ void __iomem *phy_base = dram->phy;
+ u32 fbdiv, prediv, postdiv, postdiv_en;
+
+ if (wait) {
+ clrbits_le32(PHY_REG(phy_base, 0x53), PHY_PD_DISB);
+ while (!(readl(PHY_REG(phy_base, 0x90)) & PHY_PLL_LOCK))
+ continue;
+ } else {
+ freq /= MHz;
+ prediv = 1;
+ if (freq <= 200) {
+ fbdiv = 16;
+ postdiv = 2;
+ postdiv_en = 1;
+ } else if (freq <= 456) {
+ fbdiv = 8;
+ postdiv = 1;
+ postdiv_en = 1;
+ } else {
+ fbdiv = 4;
+ postdiv = 0;
+ postdiv_en = 0;
+ }
+ writel(fbdiv & 0xff, PHY_REG(phy_base, 0x50));
+ clrsetbits_le32(PHY_REG(phy_base, 0x51), PHY_PBDIV_BIT9_MASK,
+ (fbdiv >> 8) & 1);
+ clrsetbits_le32(PHY_REG(phy_base, 0x51), PHY_POSTDIV_EN_MASK,
+ postdiv_en << PHY_POSTDIV_EN_SHIFT);
+
+ clrsetbits_le32(PHY_REG(phy_base, 0x52),
+ PHY_PREDIV_MASK << PHY_PREDIV_SHIFT, prediv);
+ clrsetbits_le32(PHY_REG(phy_base, 0x53),
+ PHY_POSTDIV_MASK << PHY_POSTDIV_SHIFT,
+ postdiv << PHY_POSTDIV_SHIFT);
+ }
+}
+
+static const u16 d3_phy_drv_2_ohm[][2] = {
+ {PHY_DDR3_RON_455ohm, 455},
+ {PHY_DDR3_RON_230ohm, 230},
+ {PHY_DDR3_RON_153ohm, 153},
+ {PHY_DDR3_RON_115ohm, 115},
+ {PHY_DDR3_RON_91ohm, 91},
+ {PHY_DDR3_RON_76ohm, 76},
+ {PHY_DDR3_RON_65ohm, 65},
+ {PHY_DDR3_RON_57ohm, 57},
+ {PHY_DDR3_RON_51ohm, 51},
+ {PHY_DDR3_RON_46ohm, 46},
+ {PHY_DDR3_RON_41ohm, 41},
+ {PHY_DDR3_RON_38ohm, 38},
+ {PHY_DDR3_RON_35ohm, 35},
+ {PHY_DDR3_RON_32ohm, 32},
+ {PHY_DDR3_RON_30ohm, 30},
+ {PHY_DDR3_RON_28ohm, 28},
+ {PHY_DDR3_RON_27ohm, 27},
+ {PHY_DDR3_RON_25ohm, 25},
+ {PHY_DDR3_RON_24ohm, 24},
+ {PHY_DDR3_RON_23ohm, 23},
+ {PHY_DDR3_RON_22ohm, 22},
+ {PHY_DDR3_RON_21ohm, 21},
+ {PHY_DDR3_RON_20ohm, 20}
+};
+
+static u16 d3_phy_odt_2_ohm[][2] = {
+ {PHY_DDR3_RTT_DISABLE, 0},
+ {PHY_DDR3_RTT_561ohm, 561},
+ {PHY_DDR3_RTT_282ohm, 282},
+ {PHY_DDR3_RTT_188ohm, 188},
+ {PHY_DDR3_RTT_141ohm, 141},
+ {PHY_DDR3_RTT_113ohm, 113},
+ {PHY_DDR3_RTT_94ohm, 94},
+ {PHY_DDR3_RTT_81ohm, 81},
+ {PHY_DDR3_RTT_72ohm, 72},
+ {PHY_DDR3_RTT_64ohm, 64},
+ {PHY_DDR3_RTT_58ohm, 58},
+ {PHY_DDR3_RTT_52ohm, 52},
+ {PHY_DDR3_RTT_48ohm, 48},
+ {PHY_DDR3_RTT_44ohm, 44},
+ {PHY_DDR3_RTT_41ohm, 41},
+ {PHY_DDR3_RTT_38ohm, 38},
+ {PHY_DDR3_RTT_37ohm, 37},
+ {PHY_DDR3_RTT_34ohm, 34},
+ {PHY_DDR3_RTT_32ohm, 32},
+ {PHY_DDR3_RTT_31ohm, 31},
+ {PHY_DDR3_RTT_29ohm, 29},
+ {PHY_DDR3_RTT_28ohm, 28},
+ {PHY_DDR3_RTT_27ohm, 27},
+ {PHY_DDR3_RTT_25ohm, 25}
+};
+
+static u16 d4lp3_phy_drv_2_ohm[][2] = {
+ {PHY_DDR4_LPDDR3_RON_482ohm, 482},
+ {PHY_DDR4_LPDDR3_RON_244ohm, 244},
+ {PHY_DDR4_LPDDR3_RON_162ohm, 162},
+ {PHY_DDR4_LPDDR3_RON_122ohm, 122},
+ {PHY_DDR4_LPDDR3_RON_97ohm, 97},
+ {PHY_DDR4_LPDDR3_RON_81ohm, 81},
+ {PHY_DDR4_LPDDR3_RON_69ohm, 69},
+ {PHY_DDR4_LPDDR3_RON_61ohm, 61},
+ {PHY_DDR4_LPDDR3_RON_54ohm, 54},
+ {PHY_DDR4_LPDDR3_RON_48ohm, 48},
+ {PHY_DDR4_LPDDR3_RON_44ohm, 44},
+ {PHY_DDR4_LPDDR3_RON_40ohm, 40},
+ {PHY_DDR4_LPDDR3_RON_37ohm, 37},
+ {PHY_DDR4_LPDDR3_RON_34ohm, 34},
+ {PHY_DDR4_LPDDR3_RON_32ohm, 32},
+ {PHY_DDR4_LPDDR3_RON_30ohm, 30},
+ {PHY_DDR4_LPDDR3_RON_28ohm, 28},
+ {PHY_DDR4_LPDDR3_RON_27ohm, 27},
+ {PHY_DDR4_LPDDR3_RON_25ohm, 25},
+ {PHY_DDR4_LPDDR3_RON_24ohm, 24},
+ {PHY_DDR4_LPDDR3_RON_23ohm, 23},
+ {PHY_DDR4_LPDDR3_RON_22ohm, 22},
+ {PHY_DDR4_LPDDR3_RON_21ohm, 21}
+};
+
+static u16 d4lp3_phy_odt_2_ohm[][2] = {
+ {PHY_DDR4_LPDDR3_RTT_DISABLE, 0},
+ {PHY_DDR4_LPDDR3_RTT_586ohm, 586},
+ {PHY_DDR4_LPDDR3_RTT_294ohm, 294},
+ {PHY_DDR4_LPDDR3_RTT_196ohm, 196},
+ {PHY_DDR4_LPDDR3_RTT_148ohm, 148},
+ {PHY_DDR4_LPDDR3_RTT_118ohm, 118},
+ {PHY_DDR4_LPDDR3_RTT_99ohm, 99},
+ {PHY_DDR4_LPDDR3_RTT_85ohm, 58},
+ {PHY_DDR4_LPDDR3_RTT_76ohm, 76},
+ {PHY_DDR4_LPDDR3_RTT_67ohm, 67},
+ {PHY_DDR4_LPDDR3_RTT_60ohm, 60},
+ {PHY_DDR4_LPDDR3_RTT_55ohm, 55},
+ {PHY_DDR4_LPDDR3_RTT_50ohm, 50},
+ {PHY_DDR4_LPDDR3_RTT_46ohm, 46},
+ {PHY_DDR4_LPDDR3_RTT_43ohm, 43},
+ {PHY_DDR4_LPDDR3_RTT_40ohm, 40},
+ {PHY_DDR4_LPDDR3_RTT_38ohm, 38},
+ {PHY_DDR4_LPDDR3_RTT_36ohm, 36},
+ {PHY_DDR4_LPDDR3_RTT_34ohm, 34},
+ {PHY_DDR4_LPDDR3_RTT_32ohm, 32},
+ {PHY_DDR4_LPDDR3_RTT_31ohm, 31},
+ {PHY_DDR4_LPDDR3_RTT_29ohm, 29},
+ {PHY_DDR4_LPDDR3_RTT_28ohm, 28},
+ {PHY_DDR4_LPDDR3_RTT_27ohm, 27}
+};
+
+static u16 lp4_phy_drv_2_ohm[][2] = {
+ {PHY_LPDDR4_RON_501ohm, 501},
+ {PHY_LPDDR4_RON_253ohm, 253},
+ {PHY_LPDDR4_RON_168ohm, 168},
+ {PHY_LPDDR4_RON_126ohm, 126},
+ {PHY_LPDDR4_RON_101ohm, 101},
+ {PHY_LPDDR4_RON_84ohm, 84},
+ {PHY_LPDDR4_RON_72ohm, 72},
+ {PHY_LPDDR4_RON_63ohm, 63},
+ {PHY_LPDDR4_RON_56ohm, 56},
+ {PHY_LPDDR4_RON_50ohm, 50},
+ {PHY_LPDDR4_RON_46ohm, 46},
+ {PHY_LPDDR4_RON_42ohm, 42},
+ {PHY_LPDDR4_RON_38ohm, 38},
+ {PHY_LPDDR4_RON_36ohm, 36},
+ {PHY_LPDDR4_RON_33ohm, 33},
+ {PHY_LPDDR4_RON_31ohm, 31},
+ {PHY_LPDDR4_RON_29ohm, 29},
+ {PHY_LPDDR4_RON_28ohm, 28},
+ {PHY_LPDDR4_RON_26ohm, 26},
+ {PHY_LPDDR4_RON_25ohm, 25},
+ {PHY_LPDDR4_RON_24ohm, 24},
+ {PHY_LPDDR4_RON_23ohm, 23},
+ {PHY_LPDDR4_RON_22ohm, 22}
+};
+
+static u16 lp4_phy_odt_2_ohm[][2] = {
+ {PHY_LPDDR4_RTT_DISABLE, 0},
+ {PHY_LPDDR4_RTT_604ohm, 604},
+ {PHY_LPDDR4_RTT_303ohm, 303},
+ {PHY_LPDDR4_RTT_202ohm, 202},
+ {PHY_LPDDR4_RTT_152ohm, 152},
+ {PHY_LPDDR4_RTT_122ohm, 122},
+ {PHY_LPDDR4_RTT_101ohm, 101},
+ {PHY_LPDDR4_RTT_87ohm, 87},
+ {PHY_LPDDR4_RTT_78ohm, 78},
+ {PHY_LPDDR4_RTT_69ohm, 69},
+ {PHY_LPDDR4_RTT_62ohm, 62},
+ {PHY_LPDDR4_RTT_56ohm, 56},
+ {PHY_LPDDR4_RTT_52ohm, 52},
+ {PHY_LPDDR4_RTT_48ohm, 48},
+ {PHY_LPDDR4_RTT_44ohm, 44},
+ {PHY_LPDDR4_RTT_41ohm, 41},
+ {PHY_LPDDR4_RTT_39ohm, 39},
+ {PHY_LPDDR4_RTT_37ohm, 37},
+ {PHY_LPDDR4_RTT_35ohm, 35},
+ {PHY_LPDDR4_RTT_33ohm, 33},
+ {PHY_LPDDR4_RTT_32ohm, 32},
+ {PHY_LPDDR4_RTT_30ohm, 30},
+ {PHY_LPDDR4_RTT_29ohm, 29},
+ {PHY_LPDDR4_RTT_27ohm, 27}
+};
+
+static u32 lp4_odt_calc(u32 odt_ohm)
+{
+ u32 odt;
+
+ if (odt_ohm == 0)
+ odt = LPDDR4_DQODT_DIS;
+ else if (odt_ohm <= 40)
+ odt = LPDDR4_DQODT_40;
+ else if (odt_ohm <= 48)
+ odt = LPDDR4_DQODT_48;
+ else if (odt_ohm <= 60)
+ odt = LPDDR4_DQODT_60;
+ else if (odt_ohm <= 80)
+ odt = LPDDR4_DQODT_80;
+ else if (odt_ohm <= 120)
+ odt = LPDDR4_DQODT_120;
+ else
+ odt = LPDDR4_DQODT_240;
+
+ return odt;
+}
+
+static void *get_ddr_drv_odt_info(u32 dramtype)
+{
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ void *ddr_info = 0;
+
+ if (dramtype == DDR4)
+ ddr_info = (void *)common_info + index->ddr4_index.offset * 4;
+ else if (dramtype == DDR3)
+ ddr_info = (void *)common_info + index->ddr3_index.offset * 4;
+ else if (dramtype == LPDDR3)
+ ddr_info = (void *)common_info + index->lp3_index.offset * 4;
+ else if (dramtype == LPDDR4)
+ ddr_info = (void *)common_info + index->lp4_index.offset * 4;
+ else
+ printascii("unsupported dram type\n");
+ return ddr_info;
+}
+
+static void set_lp4_vref(struct dram_info *dram, struct lp4_info *lp4_info,
+ u32 freq_mhz, u32 dst_fsp, u32 dramtype)
+{
+ void __iomem *pctl_base = dram->pctl;
+ u32 ca_vref, dq_vref;
+
+ if (freq_mhz <= LP4_CA_ODT_EN_FREQ(lp4_info->ca_odten_freq))
+ ca_vref = LP4_CA_VREF(lp4_info->vref_when_odtoff);
+ else
+ ca_vref = LP4_CA_VREF(lp4_info->vref_when_odten);
+
+ if (freq_mhz <= LP4_DQ_ODT_EN_FREQ(lp4_info->dq_odten_freq))
+ dq_vref = LP4_DQ_VREF(lp4_info->vref_when_odtoff);
+ else
+ dq_vref = LP4_DQ_VREF(lp4_info->vref_when_odten);
+
+ if (dramtype == LPDDR4) {
+ if (ca_vref < 100)
+ ca_vref = 100;
+ if (ca_vref > 420)
+ ca_vref = 420;
+
+ if (ca_vref <= 300)
+ ca_vref = (0 << 6) | (ca_vref - 100) / 4;
+ else
+ ca_vref = (1 << 6) | (ca_vref - 220) / 4;
+
+ if (dq_vref < 100)
+ dq_vref = 100;
+ if (dq_vref > 420)
+ dq_vref = 420;
+
+ if (dq_vref <= 300)
+ dq_vref = (0 << 6) | (dq_vref - 100) / 4;
+ else
+ dq_vref = (1 << 6) | (dq_vref - 220) / 4;
+ } else {
+ ca_vref = ca_vref * 11 / 6;
+ if (ca_vref < 150)
+ ca_vref = 150;
+ if (ca_vref > 629)
+ ca_vref = 629;
+
+ if (ca_vref <= 449)
+ ca_vref = (0 << 6) | (ca_vref - 150) / 4;
+ else
+ ca_vref = (1 << 6) | (ca_vref - 329) / 4;
+
+ if (dq_vref < 150)
+ dq_vref = 150;
+ if (dq_vref > 629)
+ dq_vref = 629;
+
+ if (dq_vref <= 449)
+ dq_vref = (0 << 6) | (dq_vref - 150) / 6;
+ else
+ dq_vref = (1 << 6) | (dq_vref - 329) / 6;
+ }
+ sw_set_req(dram);
+ clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT6,
+ PCTL2_MR_MASK << PCTL2_LPDDR4_MR12_SHIFT,
+ ca_vref << PCTL2_LPDDR4_MR12_SHIFT);
+
+ clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT7,
+ PCTL2_MR_MASK << PCTL2_LPDDR4_MR14_SHIFT,
+ dq_vref << PCTL2_LPDDR4_MR14_SHIFT);
+ sw_set_ack(dram);
+}
+
+static void set_ds_odt(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params, u32 dst_fsp)
+{
+ void __iomem *phy_base = dram->phy;
+ void __iomem *pctl_base = dram->pctl;
+ u32 dramtype = sdram_params->base.dramtype;
+ struct ddr2_3_4_lp2_3_info *ddr_info;
+ struct lp4_info *lp4_info;
+ u32 i, j, tmp;
+ const u16 (*p_drv)[2];
+ const u16 (*p_odt)[2];
+ u32 drv_info, sr_info;
+ u32 phy_dq_drv_ohm, phy_clk_drv_ohm, phy_ca_drv_ohm, dram_drv_ohm;
+ u32 phy_odt_ohm, dram_odt_ohm;
+ u32 lp4_pu_cal, phy_lp4_drv_pd_en;
+ u32 phy_odt_up_en, phy_odt_dn_en;
+ u32 sr_dq, sr_clk;
+ u32 freq = sdram_params->base.ddr_freq;
+ u32 mr1_mr3, mr11, mr22, vref_out, vref_inner;
+ u32 phy_clk_drv = 0, phy_odt = 0, phy_ca_drv = 0, dram_caodt_ohm = 0;
+ u32 phy_dq_drv = 0;
+ u32 phy_odt_up = 0, phy_odt_dn = 0;
+
+ ddr_info = get_ddr_drv_odt_info(dramtype);
+ lp4_info = (void *)ddr_info;
+
+ if (!ddr_info)
+ return;
+
+ /* dram odt en freq control phy drv, dram odt and phy sr */
+ if (freq <= DRAMODT_EN_FREQ(ddr_info->odten_freq)) {
+ drv_info = ddr_info->drv_when_odtoff;
+ dram_odt_ohm = 0;
+ sr_info = ddr_info->sr_when_odtoff;
+ phy_lp4_drv_pd_en =
+ PHY_LP4_DRV_PULLDOWN_EN_ODTOFF(lp4_info->odt_info);
+ } else {
+ drv_info = ddr_info->drv_when_odten;
+ dram_odt_ohm = ODT_INFO_DRAM_ODT(ddr_info->odt_info);
+ sr_info = ddr_info->sr_when_odten;
+ phy_lp4_drv_pd_en =
+ PHY_LP4_DRV_PULLDOWN_EN_ODTEN(lp4_info->odt_info);
+ }
+ phy_dq_drv_ohm =
+ DRV_INFO_PHY_DQ_DRV(drv_info);
+ phy_clk_drv_ohm =
+ DRV_INFO_PHY_CLK_DRV(drv_info);
+ phy_ca_drv_ohm =
+ DRV_INFO_PHY_CA_DRV(drv_info);
+
+ sr_dq = DQ_SR_INFO(sr_info);
+ sr_clk = CLK_SR_INFO(sr_info);
+
+ /* phy odt en freq control dram drv and phy odt */
+ if (freq <= PHYODT_EN_FREQ(ddr_info->odten_freq)) {
+ dram_drv_ohm = DRV_INFO_DRAM_DQ_DRV(ddr_info->drv_when_odtoff);
+ lp4_pu_cal = LP4_DRV_PU_CAL_ODTOFF(lp4_info->odt_info);
+ phy_odt_ohm = 0;
+ phy_odt_up_en = 0;
+ phy_odt_dn_en = 0;
+ } else {
+ dram_drv_ohm =
+ DRV_INFO_DRAM_DQ_DRV(ddr_info->drv_when_odten);
+ phy_odt_ohm = ODT_INFO_PHY_ODT(ddr_info->odt_info);
+ phy_odt_up_en =
+ ODT_INFO_PULLUP_EN(ddr_info->odt_info);
+ phy_odt_dn_en =
+ ODT_INFO_PULLDOWN_EN(ddr_info->odt_info);
+ lp4_pu_cal = LP4_DRV_PU_CAL_ODTEN(lp4_info->odt_info);
+ }
+
+ if (dramtype == LPDDR4) {
+ if (phy_odt_ohm) {
+ phy_odt_up_en = 0;
+ phy_odt_dn_en = 1;
+ }
+ if (freq <= LP4_CA_ODT_EN_FREQ(lp4_info->ca_odten_freq))
+ dram_caodt_ohm = 0;
+ else
+ dram_caodt_ohm =
+ ODT_INFO_LP4_CA_ODT(lp4_info->odt_info);
+ }
+
+ if (dramtype == DDR3) {
+ p_drv = d3_phy_drv_2_ohm;
+ p_odt = d3_phy_odt_2_ohm;
+ } else if (dramtype == LPDDR4) {
+ p_drv = lp4_phy_drv_2_ohm;
+ p_odt = lp4_phy_odt_2_ohm;
+ } else {
+ p_drv = d4lp3_phy_drv_2_ohm;
+ p_odt = d4lp3_phy_odt_2_ohm;
+ }
+
+ for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) {
+ if (phy_dq_drv_ohm <= *(*(p_drv + i) + 1)) {
+ phy_dq_drv = **(p_drv + i);
+ break;
+ }
+ if (i == 0)
+ break;
+ }
+ for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) {
+ if (phy_clk_drv_ohm <= *(*(p_drv + i) + 1)) {
+ phy_clk_drv = **(p_drv + i);
+ break;
+ }
+ if (i == 0)
+ break;
+ }
+ for (i = ARRAY_SIZE(d3_phy_drv_2_ohm) - 1; ; i--) {
+ if (phy_ca_drv_ohm <= *(*(p_drv + i) + 1)) {
+ phy_ca_drv = **(p_drv + i);
+ break;
+ }
+ if (i == 0)
+ break;
+ }
+ if (!phy_odt_ohm)
+ phy_odt = 0;
+ else
+ for (i = ARRAY_SIZE(d4lp3_phy_odt_2_ohm) - 1; ; i--) {
+ if (phy_odt_ohm <= *(*(p_odt + i) + 1)) {
+ phy_odt = **(p_odt + i);
+ break;
+ }
+ if (i == 0)
+ break;
+ }
+
+ if (dramtype != LPDDR4) {
+ if (!phy_odt_ohm || (phy_odt_up_en && phy_odt_dn_en))
+ vref_inner = 0x80;
+ else if (phy_odt_up_en)
+ vref_inner = (2 * dram_drv_ohm + phy_odt_ohm) * 128 /
+ (dram_drv_ohm + phy_odt_ohm);
+ else
+ vref_inner = phy_odt_ohm * 128 /
+ (phy_odt_ohm + dram_drv_ohm);
+
+ if (dramtype != DDR3 && dram_odt_ohm)
+ vref_out = (2 * phy_dq_drv_ohm + dram_odt_ohm) * 128 /
+ (phy_dq_drv_ohm + dram_odt_ohm);
+ else
+ vref_out = 0x80;
+ } else {
+ /* for lp4 and lp4x*/
+ if (phy_odt_ohm)
+ vref_inner =
+ (PHY_LP4_DQ_VREF(lp4_info->vref_when_odten) *
+ 256) / 1000;
+ else
+ vref_inner =
+ (PHY_LP4_DQ_VREF(lp4_info->vref_when_odtoff) *
+ 256) / 1000;
+
+ vref_out = 0x80;
+ }
+
+ /* default ZQCALIB bypass mode */
+ clrsetbits_le32(PHY_REG(phy_base, 0x100), 0x1f, phy_ca_drv);
+ clrsetbits_le32(PHY_REG(phy_base, 0x101), 0x1f, phy_ca_drv);
+ clrsetbits_le32(PHY_REG(phy_base, 0x102), 0x1f, phy_clk_drv);
+ clrsetbits_le32(PHY_REG(phy_base, 0x103), 0x1f, phy_clk_drv);
+ if (dramtype == LPDDR4) {
+ clrsetbits_le32(PHY_REG(phy_base, 0x107), 0x1f, phy_clk_drv);
+ clrsetbits_le32(PHY_REG(phy_base, 0x108), 0x1f, phy_clk_drv);
+ } else {
+ clrsetbits_le32(PHY_REG(phy_base, 0x107), 0x1f, phy_ca_drv);
+ clrsetbits_le32(PHY_REG(phy_base, 0x108), 0x1f, phy_ca_drv);
+ }
+ /* clk / cmd slew rate */
+ clrsetbits_le32(PHY_REG(phy_base, 0x106), 0x1f, sr_clk);
+
+ phy_lp4_drv_pd_en = (~phy_lp4_drv_pd_en) & 1;
+ if (phy_odt_up_en)
+ phy_odt_up = phy_odt;
+ if (phy_odt_dn_en)
+ phy_odt_dn = phy_odt;
+
+ for (i = 0; i < 4; i++) {
+ j = 0x110 + i * 0x10;
+ clrsetbits_le32(PHY_REG(phy_base, j + 1), 0x1f, phy_odt_up);
+ clrsetbits_le32(PHY_REG(phy_base, j), 0x1f, phy_odt_dn);
+ clrsetbits_le32(PHY_REG(phy_base, j + 2), 0x1f, phy_dq_drv);
+ clrsetbits_le32(PHY_REG(phy_base, j + 3), 0x1f, phy_dq_drv);
+ writel(vref_inner, PHY_REG(phy_base, 0x118 + i * 0x10));
+
+ clrsetbits_le32(PHY_REG(phy_base, 0x114 + i * 0x10),
+ 1 << 3, phy_lp4_drv_pd_en << 3);
+ if (dramtype == LPDDR4)
+ clrbits_le32(PHY_REG(phy_base, 0x114 + i * 0x10), BIT(5));
+ /* dq slew rate */
+ clrsetbits_le32(PHY_REG(phy_base, 0x117 + i * 0x10),
+ 0x1f, sr_dq);
+ }
+
+ /* reg_rx_vref_value_update */
+ setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+ clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+
+ /* RAM VREF */
+ writel(vref_out, PHY_REG(phy_base, 0x105));
+ if (dramtype == LPDDR3)
+ udelay(100);
+
+ if (dramtype == LPDDR4)
+ set_lp4_vref(dram, lp4_info, freq, dst_fsp, dramtype);
+
+ if (dramtype == DDR3 || dramtype == DDR4) {
+ mr1_mr3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT3);
+ mr1_mr3 = mr1_mr3 >> PCTL2_DDR34_MR1_SHIFT & PCTL2_MR_MASK;
+ } else {
+ mr1_mr3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT4);
+ mr1_mr3 = mr1_mr3 >> PCTL2_LPDDR234_MR3_SHIFT & PCTL2_MR_MASK;
+ }
+
+ if (dramtype == DDR3) {
+ mr1_mr3 &= ~(DDR3_DS_MASK | DDR3_RTT_NOM_MASK);
+ if (dram_drv_ohm == 34)
+ mr1_mr3 |= DDR3_DS_34;
+
+ if (dram_odt_ohm == 0)
+ mr1_mr3 |= DDR3_RTT_NOM_DIS;
+ else if (dram_odt_ohm <= 40)
+ mr1_mr3 |= DDR3_RTT_NOM_40;
+ else if (dram_odt_ohm <= 60)
+ mr1_mr3 |= DDR3_RTT_NOM_60;
+ else
+ mr1_mr3 |= DDR3_RTT_NOM_120;
+
+ } else if (dramtype == DDR4) {
+ mr1_mr3 &= ~(DDR4_DS_MASK | DDR4_RTT_NOM_MASK);
+ if (dram_drv_ohm == 48)
+ mr1_mr3 |= DDR4_DS_48;
+
+ if (dram_odt_ohm == 0)
+ mr1_mr3 |= DDR4_RTT_NOM_DIS;
+ else if (dram_odt_ohm <= 34)
+ mr1_mr3 |= DDR4_RTT_NOM_34;
+ else if (dram_odt_ohm <= 40)
+ mr1_mr3 |= DDR4_RTT_NOM_40;
+ else if (dram_odt_ohm <= 48)
+ mr1_mr3 |= DDR4_RTT_NOM_48;
+ else if (dram_odt_ohm <= 60)
+ mr1_mr3 |= DDR4_RTT_NOM_60;
+ else
+ mr1_mr3 |= DDR4_RTT_NOM_120;
+
+ } else if (dramtype == LPDDR3) {
+ if (dram_drv_ohm <= 34)
+ mr1_mr3 |= LPDDR3_DS_34;
+ else if (dram_drv_ohm <= 40)
+ mr1_mr3 |= LPDDR3_DS_40;
+ else if (dram_drv_ohm <= 48)
+ mr1_mr3 |= LPDDR3_DS_48;
+ else if (dram_drv_ohm <= 60)
+ mr1_mr3 |= LPDDR3_DS_60;
+ else if (dram_drv_ohm <= 80)
+ mr1_mr3 |= LPDDR3_DS_80;
+
+ if (dram_odt_ohm == 0)
+ lp3_odt_value = LPDDR3_ODT_DIS;
+ else if (dram_odt_ohm <= 60)
+ lp3_odt_value = LPDDR3_ODT_60;
+ else if (dram_odt_ohm <= 120)
+ lp3_odt_value = LPDDR3_ODT_120;
+ else
+ lp3_odt_value = LPDDR3_ODT_240;
+ } else {/* for lpddr4 and lpddr4x */
+ /* MR3 for lp4 PU-CAL and PDDS */
+ mr1_mr3 &= ~(LPDDR4_PDDS_MASK | LPDDR4_PU_CAL_MASK);
+ mr1_mr3 |= lp4_pu_cal;
+
+ tmp = lp4_odt_calc(dram_drv_ohm);
+ if (!tmp)
+ tmp = LPDDR4_PDDS_240;
+ mr1_mr3 |= (tmp << LPDDR4_PDDS_SHIFT);
+
+ /* MR11 for lp4 ca odt, dq odt set */
+ mr11 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT6);
+ mr11 = mr11 >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK;
+
+ mr11 &= ~(LPDDR4_DQODT_MASK | LPDDR4_CAODT_MASK);
+
+ tmp = lp4_odt_calc(dram_odt_ohm);
+ mr11 |= (tmp << LPDDR4_DQODT_SHIFT);
+
+ tmp = lp4_odt_calc(dram_caodt_ohm);
+ mr11 |= (tmp << LPDDR4_CAODT_SHIFT);
+ sw_set_req(dram);
+ clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT6,
+ PCTL2_MR_MASK << PCTL2_LPDDR4_MR11_SHIFT,
+ mr11 << PCTL2_LPDDR4_MR11_SHIFT);
+ sw_set_ack(dram);
+
+ /* MR22 for soc odt/odt-ck/odt-cs/odt-ca */
+ mr22 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT7);
+ mr22 = mr22 >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK;
+ mr22 &= ~LPDDR4_SOC_ODT_MASK;
+
+ tmp = lp4_odt_calc(phy_odt_ohm);
+ mr22 |= tmp;
+ mr22 = mr22 |
+ (LP4_ODTE_CK_EN(lp4_info->cs_drv_ca_odt_info) <<
+ LPDDR4_ODTE_CK_SHIFT) |
+ (LP4_ODTE_CS_EN(lp4_info->cs_drv_ca_odt_info) <<
+ LPDDR4_ODTE_CS_SHIFT) |
+ (LP4_ODTD_CA_EN(lp4_info->cs_drv_ca_odt_info) <<
+ LPDDR4_ODTD_CA_SHIFT);
+
+ sw_set_req(dram);
+ clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT7,
+ PCTL2_MR_MASK << PCTL2_LPDDR4_MR22_SHIFT,
+ mr22 << PCTL2_LPDDR4_MR22_SHIFT);
+ sw_set_ack(dram);
+ }
+
+ if (dramtype == DDR4 || dramtype == DDR3) {
+ sw_set_req(dram);
+ clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT3,
+ PCTL2_MR_MASK << PCTL2_DDR34_MR1_SHIFT,
+ mr1_mr3 << PCTL2_DDR34_MR1_SHIFT);
+ sw_set_ack(dram);
+ } else {
+ sw_set_req(dram);
+ clrsetbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT4,
+ PCTL2_MR_MASK << PCTL2_LPDDR234_MR3_SHIFT,
+ mr1_mr3 << PCTL2_LPDDR234_MR3_SHIFT);
+ sw_set_ack(dram);
+ }
+}
+
+static int sdram_cmd_dq_path_remap(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ void __iomem *phy_base = dram->phy;
+ u32 dramtype = sdram_params->base.dramtype;
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ struct dq_map_info *map_info;
+
+ map_info = (struct dq_map_info *)((void *)common_info +
+ index->dq_map_index.offset * 4);
+
+ if (dramtype <= LPDDR4)
+ writel((map_info->byte_map[dramtype / 4] >>
+ ((dramtype % 4) * 8)) & 0xff,
+ PHY_REG(phy_base, 0x4f));
+
+ return 0;
+}
+
+static void phy_cfg(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ void __iomem *phy_base = dram->phy;
+ u32 i, dq_map, tmp;
+ u32 byte1 = 0, byte0 = 0;
+
+ sdram_cmd_dq_path_remap(dram, sdram_params);
+
+ phy_pll_set(dram, sdram_params->base.ddr_freq * MHZ, 0);
+ for (i = 0; sdram_params->phy_regs.phy[i][0] != 0xFFFFFFFF; i++) {
+ writel(sdram_params->phy_regs.phy[i][1],
+ phy_base + sdram_params->phy_regs.phy[i][0]);
+ }
+
+ clrbits_le32(PHY_REG(phy_base, 0x62), BIT(5));
+ dq_map = readl(PHY_REG(phy_base, 0x4f));
+ for (i = 0; i < 4; i++) {
+ if (((dq_map >> (i * 2)) & 0x3) == 0)
+ byte0 = i;
+ if (((dq_map >> (i * 2)) & 0x3) == 1)
+ byte1 = i;
+ }
+
+ tmp = readl(PHY_REG(phy_base, 0xf)) & (~PHY_DQ_WIDTH_MASK);
+ if (cap_info->bw == 2)
+ tmp |= 0xf;
+ else if (cap_info->bw == 1)
+ tmp |= ((1 << byte0) | (1 << byte1));
+ else
+ tmp |= (1 << byte0);
+
+ writel(tmp, PHY_REG(phy_base, 0xf));
+
+ /* lpddr4 odt control by phy, enable cs0 odt */
+ if (sdram_params->base.dramtype == LPDDR4)
+ clrsetbits_le32(PHY_REG(phy_base, 0x20), 0x7 << 4,
+ (1 << 6) | (1 << 4));
+ /* for ca training ca vref choose range1 */
+ setbits_le32(PHY_REG(phy_base, 0x1e), BIT(6));
+ setbits_le32(PHY_REG(phy_base, 0x1f), BIT(6));
+ /* for wr training PHY_0x7c[5], choose range0 */
+ clrbits_le32(PHY_REG(phy_base, 0x7c), BIT(5));
+}
+
+static int update_refresh_reg(struct dram_info *dram)
+{
+ void __iomem *pctl_base = dram->pctl;
+ u32 ret;
+
+ ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
+ writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
+
+ return 0;
+}
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+int read_mr(struct dram_info *dram, u32 rank, u32 mr_num, u32 dramtype)
+{
+ u32 ret;
+ u32 i, temp;
+ u32 dqmap;
+
+ void __iomem *pctl_base = dram->pctl;
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ struct dq_map_info *map_info;
+
+ map_info = (struct dq_map_info *)((void *)common_info +
+ index->dq_map_index.offset * 4);
+
+ if (dramtype == LPDDR2)
+ dqmap = map_info->lp2_dq0_7_map;
+ else
+ dqmap = map_info->lp3_dq0_7_map;
+
+ pctl_read_mr(pctl_base, rank, mr_num);
+
+ ret = (readl(&dram->ddrgrf->ddr_grf_status[0]) & 0xff);
+
+ if (dramtype != LPDDR4) {
+ temp = 0;
+ for (i = 0; i < 8; i++) {
+ temp = temp | (((ret >> i) & 0x1) <<
+ ((dqmap >> (i * 4)) & 0xf));
+ }
+ } else {
+ temp = (readl(&dram->ddrgrf->ddr_grf_status[1]) & 0xff);
+ }
+
+ return temp;
+}
+
+/* before call this function autorefresh should be disabled */
+void send_a_refresh(struct dram_info *dram)
+{
+ void __iomem *pctl_base = dram->pctl;
+
+ while (readl(pctl_base + DDR_PCTL2_DBGSTAT) & 0x3)
+ continue;
+ writel(0x3, pctl_base + DDR_PCTL2_DBGCMD);
+}
+
+static void enter_sr(struct dram_info *dram, u32 en)
+{
+ void __iomem *pctl_base = dram->pctl;
+
+ if (en) {
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, PCTL2_SELFREF_SW);
+ while (1) {
+ if (((readl(pctl_base + DDR_PCTL2_STAT) &
+ PCTL2_SELFREF_TYPE_MASK) ==
+ PCTL2_SELFREF_TYPE_SR_NOT_AUTO) &&
+ ((readl(pctl_base + DDR_PCTL2_STAT) &
+ PCTL2_OPERATING_MODE_MASK) ==
+ PCTL2_OPERATING_MODE_SR))
+ break;
+ }
+ } else {
+ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, PCTL2_SELFREF_SW);
+ while ((readl(pctl_base + DDR_PCTL2_STAT) &
+ PCTL2_OPERATING_MODE_MASK) == PCTL2_OPERATING_MODE_SR)
+ continue;
+ }
+}
+
+void record_dq_prebit(struct dram_info *dram)
+{
+ u32 group, i, tmp;
+ void __iomem *phy_base = dram->phy;
+
+ for (group = 0; group < 4; group++) {
+ for (i = 0; i < ARRAY_SIZE(dq_sel); i++) {
+ /* l_loop_invdelaysel */
+ writel(dq_sel[i][0], PHY_REG(phy_base,
+ grp_addr[group] + 0x2c));
+ tmp = readl(PHY_REG(phy_base, grp_addr[group] + 0x2e));
+ writel(tmp, PHY_REG(phy_base,
+ grp_addr[group] + dq_sel[i][1]));
+
+ /* r_loop_invdelaysel */
+ writel(dq_sel[i][0], PHY_REG(phy_base,
+ grp_addr[group] + 0x2d));
+ tmp = readl(PHY_REG(phy_base, grp_addr[group] + 0x2f));
+ writel(tmp, PHY_REG(phy_base,
+ grp_addr[group] + dq_sel[i][2]));
+ }
+ }
+}
+
+static void update_dq_rx_prebit(struct dram_info *dram)
+{
+ void __iomem *phy_base = dram->phy;
+
+ clrsetbits_le32(PHY_REG(phy_base, 0x70), BIT(1) | BIT(6) | BIT(4),
+ BIT(4));
+ udelay(1);
+ clrbits_le32(PHY_REG(phy_base, 0x70), BIT(4));
+}
+
+static void update_dq_tx_prebit(struct dram_info *dram)
+{
+ void __iomem *phy_base = dram->phy;
+
+ clrbits_le32(PHY_REG(phy_base, 0x7a), BIT(1));
+ setbits_le32(PHY_REG(phy_base, 0x2), BIT(3));
+ setbits_le32(PHY_REG(phy_base, 0xc), BIT(6));
+ udelay(1);
+ clrbits_le32(PHY_REG(phy_base, 0xc), BIT(6));
+}
+
+static void update_ca_prebit(struct dram_info *dram)
+{
+ void __iomem *phy_base = dram->phy;
+
+ clrbits_le32(PHY_REG(phy_base, 0x25), BIT(2));
+ setbits_le32(PHY_REG(phy_base, 0x22), BIT(6));
+ udelay(1);
+ clrbits_le32(PHY_REG(phy_base, 0x22), BIT(6));
+}
+
+/*
+ * dir: 0: de-skew = delta_*
+ * 1: de-skew = reg val - delta_*
+ * delta_dir: value for differential signal: clk/
+ * delta_sig: value for single signal: ca/cmd
+ */
+static void modify_ca_deskew(struct dram_info *dram, u32 dir, int delta_dif,
+ int delta_sig, u32 cs, u32 dramtype)
+{
+ void __iomem *phy_base = dram->phy;
+ u32 i, cs_en, tmp;
+ u32 dfi_lp_stat = 0;
+
+ if (cs == 0)
+ cs_en = 1;
+ else if (cs == 2)
+ cs_en = 2;
+ else
+ cs_en = 3;
+
+ if (dramtype == LPDDR4 &&
+ ((readl(PHY_REG(phy_base, 0x60)) & BIT(5)) == 0)) {
+ dfi_lp_stat = 1;
+ setbits_le32(PHY_REG(phy_base, 0x60), BIT(5));
+ }
+ enter_sr(dram, 1);
+
+ for (i = 0; i < 0x20; i++) {
+ if (dir == DESKEW_MDF_ABS_VAL)
+ tmp = delta_sig;
+ else
+ tmp = readl(PHY_REG(phy_base, 0x150 + i)) +
+ delta_sig;
+ writel(tmp, PHY_REG(phy_base, 0x150 + i));
+ }
+
+ if (dir == DESKEW_MDF_ABS_VAL)
+ tmp = delta_dif;
+ else
+ tmp = readl(PHY_REG(phy_base, 0x150 + 0x17)) -
+ delta_sig + delta_dif;
+ writel(tmp, PHY_REG(phy_base, 0x150 + 0x17));
+ writel(tmp, PHY_REG(phy_base, 0x150 + 0x18));
+ if (dramtype == LPDDR4) {
+ writel(tmp, PHY_REG(phy_base, 0x150 + 0x4));
+ writel(tmp, PHY_REG(phy_base, 0x150 + 0xa));
+
+ clrbits_le32(PHY_REG(phy_base, 0x10), cs_en << 6);
+ update_ca_prebit(dram);
+ }
+ enter_sr(dram, 0);
+
+ if (dfi_lp_stat)
+ clrbits_le32(PHY_REG(phy_base, 0x60), BIT(5));
+}
+
+static u32 get_min_value(struct dram_info *dram, u32 signal, u32 rank)
+{
+ u32 i, j, offset = 0;
+ u32 min = 0x3f;
+ void __iomem *phy_base = dram->phy;
+ u32 byte_en;
+
+ if (signal == SKEW_TX_SIGNAL)
+ offset = 8;
+
+ if (signal == SKEW_CA_SIGNAL) {
+ for (i = 0; i < 0x20; i++)
+ min = MIN(min, readl(PHY_REG(phy_base, 0x150 + i)));
+ } else {
+ byte_en = readl(PHY_REG(phy_base, 0xf)) & 0xf;
+ for (j = offset; j < offset + rank * 4; j++) {
+ if (!((byte_en >> (j % 4)) & 1))
+ continue;
+ for (i = 0; i < 11; i++)
+ min = MIN(min,
+ readl(PHY_REG(phy_base,
+ dqs_dq_skew_adr[j] +
+ i)));
+ }
+ }
+
+ return min;
+}
+
+static u32 low_power_update(struct dram_info *dram, u32 en)
+{
+ void __iomem *pctl_base = dram->pctl;
+ u32 lp_stat = 0;
+
+ if (en) {
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, en & 0xf);
+ } else {
+ lp_stat = readl(pctl_base + DDR_PCTL2_PWRCTL) & 0xf;
+ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 0xf);
+ }
+
+ return lp_stat;
+}
+
+/*
+ * signal:
+ * dir: 0: de-skew = delta_*
+ * 1: de-skew = reg val - delta_*
+ * delta_dir: value for differential signal: dqs
+ * delta_sig: value for single signal: dq/dm
+ */
+static void modify_dq_deskew(struct dram_info *dram, u32 signal, u32 dir,
+ int delta_dif, int delta_sig, u32 rank)
+{
+ void __iomem *phy_base = dram->phy;
+ u32 i, j, tmp, offset;
+ u32 byte_en;
+
+ byte_en = readl(PHY_REG(phy_base, 0xf)) & 0xf;
+
+ if (signal == SKEW_RX_SIGNAL)
+ offset = 0;
+ else
+ offset = 8;
+
+ for (j = offset; j < (offset + rank * 4); j++) {
+ if (!((byte_en >> (j % 4)) & 1))
+ continue;
+ for (i = 0; i < 0x9; i++) {
+ if (dir == DESKEW_MDF_ABS_VAL)
+ tmp = delta_sig;
+ else
+ tmp = delta_sig + readl(PHY_REG(phy_base,
+ dqs_dq_skew_adr[j] +
+ i));
+ writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + i));
+ }
+ if (dir == DESKEW_MDF_ABS_VAL)
+ tmp = delta_dif;
+ else
+ tmp = delta_dif + readl(PHY_REG(phy_base,
+ dqs_dq_skew_adr[j] + 9));
+ writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + 9));
+ writel(tmp, PHY_REG(phy_base, dqs_dq_skew_adr[j] + 0xa));
+ }
+ if (signal == SKEW_RX_SIGNAL)
+ update_dq_rx_prebit(dram);
+ else
+ update_dq_tx_prebit(dram);
+}
+
+static int data_training_rg(struct dram_info *dram, u32 cs, u32 dramtype)
+{
+ void __iomem *phy_base = dram->phy;
+ u32 ret;
+ u32 dis_auto_zq = 0;
+ u32 odt_val_up, odt_val_dn;
+ u32 i, j;
+
+ odt_val_dn = readl(PHY_REG(phy_base, 0x110));
+ odt_val_up = readl(PHY_REG(phy_base, 0x111));
+
+ if (dramtype != LPDDR4) {
+ for (i = 0; i < 4; i++) {
+ j = 0x110 + i * 0x10;
+ writel(PHY_DDR4_LPDDR3_RTT_294ohm,
+ PHY_REG(phy_base, j));
+ writel(PHY_DDR4_LPDDR3_RTT_DISABLE,
+ PHY_REG(phy_base, j + 0x1));
+ }
+ }
+ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+ /* use normal read mode for data training */
+ clrbits_le32(PHY_REG(phy_base, 0xc), BIT(1));
+
+ if (dramtype == DDR4)
+ setbits_le32(PHY_REG(phy_base, 0xc), BIT(1));
+
+ /* choose training cs */
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
+ /* enable gate training */
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
+ udelay(50);
+ ret = readl(PHY_REG(phy_base, 0x91));
+ /* disable gate training */
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
+ clrbits_le32(PHY_REG(phy_base, 2), 0x30);
+ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+ ret = (ret & 0x2f) ^ (readl(PHY_REG(phy_base, 0xf)) & 0xf);
+
+ if (dramtype != LPDDR4) {
+ for (i = 0; i < 4; i++) {
+ j = 0x110 + i * 0x10;
+ writel(odt_val_dn, PHY_REG(phy_base, j));
+ writel(odt_val_up, PHY_REG(phy_base, j + 0x1));
+ }
+ }
+ return ret;
+}
+
+static int data_training_wl(struct dram_info *dram, u32 cs, u32 dramtype,
+ u32 rank)
+{
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ u32 dis_auto_zq = 0;
+ u32 tmp;
+ u32 cur_fsp;
+ u32 timeout_us = 1000;
+
+ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+
+ clrbits_le32(PHY_REG(phy_base, 0x7a), 0x1);
+
+ cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
+ tmp = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + DDR_PCTL2_INIT3) &
+ 0xffff;
+ writel(tmp & 0xff, PHY_REG(phy_base, 0x3));
+
+ /* disable another cs's output */
+ if ((dramtype == DDR3 || dramtype == DDR4) && rank == 2)
+ pctl_write_mr(dram->pctl, (cs + 1) & 1, 1, tmp | (1 << 12),
+ dramtype);
+ if (dramtype == DDR3 || dramtype == DDR4)
+ writel(0x40 | ((tmp >> 8) & 0x3f), PHY_REG(phy_base, 0x4));
+ else
+ writel(0x80 | ((tmp >> 8) & 0x3f), PHY_REG(phy_base, 0x4));
+
+ /* choose cs */
+ clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2),
+ ((0x2 >> cs) << 6) | (0 << 2));
+ /* enable write leveling */
+ clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2),
+ ((0x2 >> cs) << 6) | (1 << 2));
+
+ while (1) {
+ if ((readl(PHY_REG(phy_base, 0x92)) & 0xf) ==
+ (readl(PHY_REG(phy_base, 0xf)) & 0xf))
+ break;
+
+ udelay(1);
+ if (timeout_us-- == 0) {
+ printascii("error: write leveling timeout\n");
+ while (1)
+ ;
+ }
+ }
+
+ /* disable write leveling */
+ clrsetbits_le32(PHY_REG(phy_base, 2), (0x3 << 6) | (0x3 << 2),
+ ((0x2 >> cs) << 6) | (0 << 2));
+ clrsetbits_le32(PHY_REG(phy_base, 2), 0x3 << 6, 0 << 6);
+
+ /* enable another cs's output */
+ if ((dramtype == DDR3 || dramtype == DDR4) && rank == 2)
+ pctl_write_mr(dram->pctl, (cs + 1) & 1, 1, tmp & ~(1 << 12),
+ dramtype);
+
+ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+ return 0;
+}
+
+char pattern[32] = {
+ 0xaa, 0x55, 0xaa, 0x55, 0x55, 0xaa, 0x55, 0xaa,
+ 0x55, 0xaa, 0x55, 0xaa, 0xaa, 0x55, 0xaa, 0x55,
+ 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55,
+ 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa
+};
+
+static int data_training_rd(struct dram_info *dram, u32 cs, u32 dramtype,
+ u32 mhz)
+{
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ u32 trefi_1x, trfc_1x;
+ u32 dis_auto_zq = 0;
+ u32 timeout_us = 1000;
+ u32 dqs_default;
+ u32 cur_fsp;
+ u32 vref_inner;
+ u32 i;
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ struct dq_map_info *map_info;
+
+ vref_inner = readl(PHY_REG(phy_base, 0x128)) & 0xff;
+ if (dramtype == DDR3 && vref_inner == 0x80) {
+ for (i = 0; i < 4; i++)
+ writel(vref_inner - 0xa,
+ PHY_REG(phy_base, 0x118 + i * 0x10));
+
+ /* reg_rx_vref_value_update */
+ setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+ clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+ }
+
+ map_info = (struct dq_map_info *)((void *)common_info +
+ index->dq_map_index.offset * 4);
+ /* only 1cs a time, 0:cs0 1 cs1 */
+ if (cs > 1)
+ return -1;
+
+ dqs_default = 0xf;
+ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+
+ cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
+ /* config refresh timing */
+ trefi_1x = ((readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
+ DDR_PCTL2_RFSHTMG) >> 16) & 0xfff) * 32;
+ trfc_1x = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
+ DDR_PCTL2_RFSHTMG) & 0x3ff;
+ /* reg_phy_trefi[7:0] and reg_phy_trefi[13:8] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xff, trefi_1x & 0xff);
+ clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x3f, (trefi_1x >> 8) & 0x3f);
+ /* reg_phy_trfc */
+ clrsetbits_le32(PHY_REG(phy_base, 0x57), 0xff, trfc_1x);
+ /* reg_max_refi_cnt */
+ clrsetbits_le32(PHY_REG(phy_base, 0x61), 0xf << 4, 0x8 << 4);
+
+ /* choose training cs */
+ clrsetbits_le32(PHY_REG(phy_base, 0x71), 0x3 << 6, (0x2 >> cs) << 6);
+
+ /* set dq map for ddr4 */
+ if (dramtype == DDR4) {
+ setbits_le32(PHY_REG(phy_base, 0x70), BIT(7));
+ for (i = 0; i < 4; i++) {
+ writel((map_info->ddr4_dq_map[cs * 2] >>
+ ((i % 4) * 8)) & 0xff,
+ PHY_REG(phy_base, 0x238 + i));
+ writel((map_info->ddr4_dq_map[cs * 2 + 1] >>
+ ((i % 4) * 8)) & 0xff,
+ PHY_REG(phy_base, 0x2b8 + i));
+ }
+ }
+
+ /* cha_l reg_l_rd_train_dqs_default[5:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x230), 0x3f, dqs_default);
+ /* cha_h reg_h_rd_train_dqs_default[5:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x234), 0x3f, dqs_default);
+ /* chb_l reg_l_rd_train_dqs_default[5:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x2b0), 0x3f, dqs_default);
+ /* chb_h reg_h_rd_train_dqs_default[5:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x2b4), 0x3f, dqs_default);
+
+ /* Choose the read train auto mode */
+ clrsetbits_le32(PHY_REG(phy_base, 0x70), 0x3, 0x1);
+ /* Enable the auto train of the read train */
+ clrsetbits_le32(PHY_REG(phy_base, 0x70), 0x3, 0x3);
+
+ /* Wait the train done. */
+ while (1) {
+ if ((readl(PHY_REG(phy_base, 0x93)) >> 7) & 0x1)
+ break;
+
+ udelay(1);
+ if (timeout_us-- == 0) {
+ printascii("error: read training timeout\n");
+ return -1;
+ }
+ }
+
+ /* Check the read train state */
+ if ((readl(PHY_REG(phy_base, 0x240)) & 0x3) ||
+ (readl(PHY_REG(phy_base, 0x2c0)) & 0x3)) {
+ printascii("error: read training error\n");
+ return -1;
+ }
+
+ /* Exit the Read Training by setting */
+ clrbits_le32(PHY_REG(phy_base, 0x70), BIT(1));
+
+ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+ if (dramtype == DDR3 && vref_inner == 0x80) {
+ for (i = 0; i < 4; i++)
+ writel(vref_inner,
+ PHY_REG(phy_base, 0x118 + i * 0x10));
+
+ /* reg_rx_vref_value_update */
+ setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+ clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+ }
+
+ return 0;
+}
+
+static int data_training_wr(struct dram_info *dram, u32 cs, u32 dramtype,
+ u32 mhz, u32 dst_fsp)
+{
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ u32 trefi_1x, trfc_1x;
+ u32 dis_auto_zq = 0;
+ u32 timeout_us = 1000;
+ u32 cur_fsp;
+ u32 mr_tmp, cl, cwl, phy_fsp, offset = 0;
+
+ if (dramtype == LPDDR3 && mhz <= 400) {
+ phy_fsp = (readl(PHY_REG(phy_base, 0xc)) >> 0x2) & 0x3;
+ offset = (phy_fsp == 0) ? 0x5 : 0x387 + (phy_fsp - 1) * 3;
+ cl = readl(PHY_REG(phy_base, offset));
+ cwl = readl(PHY_REG(phy_base, offset + 2));
+
+ clrsetbits_le32(PHY_REG(phy_base, offset), 0x1f, 0x8);
+ clrsetbits_le32(PHY_REG(phy_base, offset + 2), 0x1f, 0x4);
+ pctl_write_mr(dram->pctl, 3, 2, 0x6, dramtype);
+ }
+
+ dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+
+ /* PHY_0x7b[7:0] reg_train_col_addr[7:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x7b), 0xff, 0x0);
+ /* PHY_0x7c[4:2] reg_train_ba_addr[2:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x7 << 2, 0x0 << 2);
+ /* PHY_0x7c[1:0] reg_train_col_addr[9:8] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x3, 0x0);
+ /* PHY_0x7d[7:0] reg_train_row_addr[7:0] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x7d), 0xff, 0x0);
+ /* PHY_0x7e[7:0] reg_train_row_addr[15:8] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x7e), 0xff, 0x0);
+
+ /* PHY_0x71[3] wrtrain_check_data_value_random_gen */
+ clrbits_le32(PHY_REG(phy_base, 0x71), BIT(3));
+
+ /* config refresh timing */
+ cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
+ trefi_1x = ((readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
+ DDR_PCTL2_RFSHTMG) >> 16) & 0xfff) * 32;
+ trfc_1x = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
+ DDR_PCTL2_RFSHTMG) & 0x3ff;
+ /* reg_phy_trefi[7:0] and reg_phy_trefi[13:8] */
+ clrsetbits_le32(PHY_REG(phy_base, 0x6e), 0xff, trefi_1x & 0xff);
+ clrsetbits_le32(PHY_REG(phy_base, 0x6f), 0x3f, (trefi_1x >> 8) & 0x3f);
+ /* reg_phy_trfc */
+ clrsetbits_le32(PHY_REG(phy_base, 0x57), 0xff, trfc_1x);
+ /* reg_max_refi_cnt */
+ clrsetbits_le32(PHY_REG(phy_base, 0x61), 0xf << 4, 0x8 << 4);
+
+ /* choose training cs */
+ clrsetbits_le32(PHY_REG(phy_base, 0x7c), 0x3 << 6, (0x2 >> cs) << 6);
+
+ /* PHY_0x7a [4] reg_wr_train_dqs_default_bypass */
+ /* 0: Use the write-leveling value. */
+ /* 1: use reg0x233 0x237 0x2b3 0x2b7 */
+ setbits_le32(PHY_REG(phy_base, 0x7a), BIT(4));
+
+ /* PHY_0x7a [0] reg_dq_wr_train_auto */
+ setbits_le32(PHY_REG(phy_base, 0x7a), 0x1);
+
+ /* PHY_0x7a [1] reg_dq_wr_train_en */
+ setbits_le32(PHY_REG(phy_base, 0x7a), BIT(1));
+
+ send_a_refresh(dram);
+
+ while (1) {
+ if ((readl(PHY_REG(phy_base, 0x92)) >> 7) & 0x1)
+ break;
+
+ udelay(1);
+ if (timeout_us-- == 0) {
+ printascii("error: write training timeout\n");
+ while (1)
+ ;
+ }
+ }
+
+ /* Check the write train state */
+ if ((readl(PHY_REG(phy_base, 0x90)) >> 5) & 0x7) {
+ printascii("error: write training error\n");
+ return -1;
+ }
+
+ /* PHY_0x7a [1] reg_dq_wr_train_en */
+ clrbits_le32(PHY_REG(phy_base, 0x7a), BIT(1));
+
+ pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+ /* save LPDDR4 write vref to fsp_param for dfs */
+ if (dramtype == LPDDR4) {
+ fsp_param[dst_fsp].vref_dq[cs] =
+ ((readl(PHY_REG(phy_base, 0x384)) & 0x3f) +
+ (readl(PHY_REG(phy_base, 0x385)) & 0x3f)) / 2;
+ /* add range info */
+ fsp_param[dst_fsp].vref_dq[cs] |=
+ ((readl(PHY_REG(phy_base, 0x7c)) & BIT(5)) << 1);
+ }
+
+ if (dramtype == LPDDR3 && mhz <= 400) {
+ clrsetbits_le32(PHY_REG(phy_base, offset), 0x1f, cl);
+ clrsetbits_le32(PHY_REG(phy_base, offset + 2), 0x1f, cwl);
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
+ DDR_PCTL2_INIT3);
+ pctl_write_mr(dram->pctl, 3, 2, mr_tmp & PCTL2_MR_MASK,
+ dramtype);
+ }
+
+ return 0;
+}
+
+static int data_training(struct dram_info *dram, u32 cs,
+ struct rv1126_sdram_params *sdram_params, u32 dst_fsp,
+ u32 training_flag)
+{
+ u32 ret = 0;
+
+ if (training_flag == FULL_TRAINING)
+ training_flag = READ_GATE_TRAINING | WRITE_LEVELING |
+ WRITE_TRAINING | READ_TRAINING;
+
+ if ((training_flag & WRITE_LEVELING) == WRITE_LEVELING) {
+ ret = data_training_wl(dram, cs,
+ sdram_params->base.dramtype,
+ sdram_params->ch.cap_info.rank);
+ if (ret != 0)
+ goto out;
+ }
+
+ if ((training_flag & READ_GATE_TRAINING) == READ_GATE_TRAINING) {
+ ret = data_training_rg(dram, cs,
+ sdram_params->base.dramtype);
+ if (ret != 0)
+ goto out;
+ }
+
+ if ((training_flag & READ_TRAINING) == READ_TRAINING) {
+ ret = data_training_rd(dram, cs,
+ sdram_params->base.dramtype,
+ sdram_params->base.ddr_freq);
+ if (ret != 0)
+ goto out;
+ }
+
+ if ((training_flag & WRITE_TRAINING) == WRITE_TRAINING) {
+ ret = data_training_wr(dram, cs,
+ sdram_params->base.dramtype,
+ sdram_params->base.ddr_freq, dst_fsp);
+ if (ret != 0)
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static int get_wrlvl_val(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ int i, j, clk_skew;
+ void __iomem *phy_base = dram->phy;
+ u32 lp_stat;
+ int ret;
+
+ lp_stat = low_power_update(dram, 0);
+
+ clk_skew = 0x1f;
+ modify_ca_deskew(dram, DESKEW_MDF_ABS_VAL, clk_skew, clk_skew, 3,
+ sdram_params->base.dramtype);
+
+ ret = data_training(dram, 0, sdram_params, 0, WRITE_LEVELING);
+ if (sdram_params->ch.cap_info.rank == 2)
+ ret |= data_training(dram, 1, sdram_params, 0, WRITE_LEVELING);
+
+ for (j = 0; j < 2; j++)
+ for (i = 0; i < 4; i++)
+ wrlvl_result[j][i] =
+ (readl(PHY_REG(phy_base, wrlvl_result_offset[j][i])) & 0x3f) -
+ clk_skew;
+
+ low_power_update(dram, lp_stat);
+
+ return ret;
+}
+
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+static void init_rw_trn_result_struct(struct rw_trn_result *result,
+ void __iomem *phy_base, u8 cs_num)
+{
+ int i;
+
+ result->cs_num = cs_num;
+ result->byte_en = readb(PHY_REG(dram_info.phy, 0xf)) &
+ PHY_DQ_WIDTH_MASK;
+ for (i = 0; i < FSP_NUM; i++)
+ result->fsp_mhz[i] = 0;
+}
+
+static void save_rw_trn_min_max(void __iomem *phy_base,
+ struct cs_rw_trn_result *rd_result,
+ struct cs_rw_trn_result *wr_result,
+ u8 byte_en)
+{
+ u16 phy_ofs;
+ u8 dqs;
+ u8 dq;
+
+ for (dqs = 0; dqs < BYTE_NUM; dqs++) {
+ if ((byte_en & BIT(dqs)) == 0)
+ continue;
+
+ /* Channel A or B (low or high 16 bit) */
+ phy_ofs = dqs < 2 ? 0x230 : 0x2b0;
+ /* low or high 8 bit */
+ phy_ofs += (dqs & 0x1) == 0 ? 0 : 0x9;
+ for (dq = 0; dq < 8; dq++) {
+ rd_result->dqs[dqs].dq_min[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0x15 + dq));
+ rd_result->dqs[dqs].dq_max[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0x27 + dq));
+ wr_result->dqs[dqs].dq_min[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0x3d + dq));
+ wr_result->dqs[dqs].dq_max[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0x4f + dq));
+ }
+ }
+}
+
+static void save_rw_trn_deskew(void __iomem *phy_base,
+ struct fsp_rw_trn_result *result, u8 cs_num,
+ int min_val, bool rw)
+{
+ u16 phy_ofs;
+ u8 cs;
+ u8 dq;
+
+ result->min_val = min_val;
+
+ for (cs = 0; cs < cs_num; cs++) {
+ phy_ofs = cs == 0 ? 0x170 : 0x1a0;
+ phy_ofs += rw == SKEW_RX_SIGNAL ? 0x1 : 0x17;
+ for (dq = 0; dq < 8; dq++) {
+ result->cs[cs].dqs[0].dq_deskew[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + dq));
+ result->cs[cs].dqs[1].dq_deskew[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0xb + dq));
+ result->cs[cs].dqs[2].dq_deskew[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0x60 + dq));
+ result->cs[cs].dqs[3].dq_deskew[dq] =
+ readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0xb + dq));
+ }
+
+ result->cs[cs].dqs[0].dqs_deskew =
+ readb(PHY_REG(phy_base, phy_ofs + 0x8));
+ result->cs[cs].dqs[1].dqs_deskew =
+ readb(PHY_REG(phy_base, phy_ofs + 0xb + 0x8));
+ result->cs[cs].dqs[2].dqs_deskew =
+ readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0x8));
+ result->cs[cs].dqs[3].dqs_deskew =
+ readb(PHY_REG(phy_base, phy_ofs + 0x60 + 0xb + 0x8));
+ }
+}
+
+static void save_rw_trn_result_to_ddr(struct rw_trn_result *result)
+{
+ result->flag = DDR_DQ_EYE_FLAG;
+ memcpy((void *)(RW_TRN_RESULT_ADDR), result, sizeof(*result));
+}
+#endif
+
+static int high_freq_training(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params,
+ u32 fsp)
+{
+ u32 i, j;
+ void __iomem *phy_base = dram->phy;
+ u32 dramtype = sdram_params->base.dramtype;
+ int min_val;
+ int dqs_skew, clk_skew, ca_skew;
+ u8 byte_en;
+ int ret;
+
+ byte_en = readl(PHY_REG(phy_base, 0xf)) & PHY_DQ_WIDTH_MASK;
+ dqs_skew = 0;
+ for (j = 0; j < sdram_params->ch.cap_info.rank; j++) {
+ for (i = 0; i < ARRAY_SIZE(wrlvl_result[0]); i++) {
+ if ((byte_en & BIT(i)) != 0)
+ dqs_skew += wrlvl_result[j][i];
+ }
+ }
+ dqs_skew = dqs_skew /
+ (int)(sdram_params->ch.cap_info.rank * (1 << sdram_params->ch.cap_info.bw));
+
+ clk_skew = 0x20 - dqs_skew;
+ dqs_skew = 0x20;
+
+ if (dramtype == LPDDR4) {
+ min_val = 0xff;
+ for (j = 0; j < sdram_params->ch.cap_info.rank; j++)
+ for (i = 0; i < sdram_params->ch.cap_info.bw; i++)
+ min_val = MIN(wrlvl_result[j][i], min_val);
+
+ if (min_val < 0) {
+ clk_skew = -min_val;
+ ca_skew = -min_val;
+ } else {
+ clk_skew = 0;
+ ca_skew = 0;
+ }
+ } else if (dramtype == LPDDR3) {
+ ca_skew = clk_skew - 4;
+ } else {
+ ca_skew = clk_skew;
+ }
+ modify_ca_deskew(dram, DESKEW_MDF_ABS_VAL, clk_skew, ca_skew, 3,
+ dramtype);
+
+ writel(wrlvl_result[0][0] + clk_skew, PHY_REG(phy_base, 0x233));
+ writel(wrlvl_result[0][1] + clk_skew, PHY_REG(phy_base, 0x237));
+ writel(wrlvl_result[0][2] + clk_skew, PHY_REG(phy_base, 0x2b3));
+ writel(wrlvl_result[0][3] + clk_skew, PHY_REG(phy_base, 0x2b7));
+ ret = data_training(dram, 0, sdram_params, fsp, READ_GATE_TRAINING |
+ READ_TRAINING | WRITE_TRAINING);
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+ rw_trn_result.fsp_mhz[fsp] = (u16)sdram_params->base.ddr_freq;
+ save_rw_trn_min_max(phy_base, &rw_trn_result.rd_fsp[fsp].cs[0],
+ &rw_trn_result.wr_fsp[fsp].cs[0],
+ rw_trn_result.byte_en);
+#endif
+ if (sdram_params->ch.cap_info.rank == 2) {
+ writel(wrlvl_result[1][0] + clk_skew, PHY_REG(phy_base, 0x233));
+ writel(wrlvl_result[1][1] + clk_skew, PHY_REG(phy_base, 0x237));
+ writel(wrlvl_result[1][2] + clk_skew, PHY_REG(phy_base, 0x2b3));
+ writel(wrlvl_result[1][3] + clk_skew, PHY_REG(phy_base, 0x2b7));
+ ret |= data_training(dram, 1, sdram_params, fsp,
+ READ_GATE_TRAINING | READ_TRAINING |
+ WRITE_TRAINING);
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+ save_rw_trn_min_max(phy_base, &rw_trn_result.rd_fsp[fsp].cs[1],
+ &rw_trn_result.wr_fsp[fsp].cs[1],
+ rw_trn_result.byte_en);
+#endif
+ }
+ if (ret)
+ goto out;
+
+ record_dq_prebit(dram);
+
+ min_val = get_min_value(dram, SKEW_RX_SIGNAL,
+ sdram_params->ch.cap_info.rank) * -1;
+ modify_dq_deskew(dram, SKEW_RX_SIGNAL, DESKEW_MDF_DIFF_VAL,
+ min_val, min_val, sdram_params->ch.cap_info.rank);
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+ save_rw_trn_deskew(phy_base, &rw_trn_result.rd_fsp[fsp],
+ rw_trn_result.cs_num, (u8)(min_val * (-1)),
+ SKEW_RX_SIGNAL);
+#endif
+
+ min_val = MIN(get_min_value(dram, SKEW_TX_SIGNAL,
+ sdram_params->ch.cap_info.rank),
+ get_min_value(dram, SKEW_CA_SIGNAL,
+ sdram_params->ch.cap_info.rank)) * -1;
+
+ /* clk = 0, rx all skew -7, tx - min_value */
+ modify_ca_deskew(dram, DESKEW_MDF_DIFF_VAL, min_val, min_val, 3,
+ dramtype);
+
+ modify_dq_deskew(dram, SKEW_TX_SIGNAL, DESKEW_MDF_DIFF_VAL,
+ min_val, min_val, sdram_params->ch.cap_info.rank);
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+ save_rw_trn_deskew(phy_base, &rw_trn_result.wr_fsp[fsp],
+ rw_trn_result.cs_num, (u8)(min_val * (-1)),
+ SKEW_TX_SIGNAL);
+#endif
+
+ ret = data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING);
+ if (sdram_params->ch.cap_info.rank == 2)
+ ret |= data_training(dram, 1, sdram_params, 0,
+ READ_GATE_TRAINING);
+out:
+ return ret;
+}
+
+static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
+{
+ writel(ddrconfig, &dram->msch->deviceconf);
+ clrsetbits_le32(&dram->grf->noc_con0, 0x3 << 0, 0 << 0);
+}
+
+static void update_noc_timing(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ void __iomem *pctl_base = dram->pctl;
+ u32 bw, bl;
+
+ bw = 8 << sdram_params->ch.cap_info.bw;
+ bl = ((readl(pctl_base + DDR_PCTL2_MSTR) >> 16) & 0xf) * 2;
+
+ /* update the noc timing related to data bus width */
+ if ((bw / 8 * bl) <= 16)
+ sdram_params->ch.noc_timings.ddrmode.b.burstsize = 0;
+ else if ((bw / 8 * bl) == 32)
+ sdram_params->ch.noc_timings.ddrmode.b.burstsize = 1;
+ else if ((bw / 8 * bl) == 64)
+ sdram_params->ch.noc_timings.ddrmode.b.burstsize = 2;
+ else
+ sdram_params->ch.noc_timings.ddrmode.b.burstsize = 3;
+
+ sdram_params->ch.noc_timings.ddrtimingc0.b.burstpenalty =
+ (bl * bw / 8) > 16 ? (bl / 4) : (16 / (bl * bw / 8)) * bl / 4;
+
+ if (sdram_params->base.dramtype == LPDDR4) {
+ sdram_params->ch.noc_timings.ddrmode.b.mwrsize =
+ (bw == 16) ? 0x1 : 0x2;
+ sdram_params->ch.noc_timings.ddrtimingc0.b.wrtomwr =
+ 3 * sdram_params->ch.noc_timings.ddrtimingc0.b.burstpenalty;
+ }
+
+ writel(sdram_params->ch.noc_timings.ddrtiminga0.d32,
+ &dram->msch->ddrtiminga0);
+ writel(sdram_params->ch.noc_timings.ddrtimingb0.d32,
+ &dram->msch->ddrtimingb0);
+ writel(sdram_params->ch.noc_timings.ddrtimingc0.d32,
+ &dram->msch->ddrtimingc0);
+ writel(sdram_params->ch.noc_timings.devtodev0.d32,
+ &dram->msch->devtodev0);
+ writel(sdram_params->ch.noc_timings.ddrmode.d32, &dram->msch->ddrmode);
+ writel(sdram_params->ch.noc_timings.ddr4timing.d32,
+ &dram->msch->ddr4timing);
+}
+
+static int split_setup(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 dramtype = sdram_params->base.dramtype;
+ u32 split_size, split_mode;
+ u64 cs_cap[2], cap;
+
+ cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dramtype);
+ cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dramtype);
+ /* only support the larger cap is in low 16bit */
+ if (cap_info->cs0_high16bit_row < cap_info->cs0_row) {
+ cap = cs_cap[0] / (1 << (cap_info->cs0_row -
+ cap_info->cs0_high16bit_row));
+ } else if ((cap_info->cs1_high16bit_row < cap_info->cs1_row) &&
+ (cap_info->rank == 2)) {
+ if (!cap_info->cs1_high16bit_row)
+ cap = cs_cap[0];
+ else
+ cap = cs_cap[0] + cs_cap[1] / (1 << (cap_info->cs1_row -
+ cap_info->cs1_high16bit_row));
+ } else {
+ goto out;
+ }
+ split_size = (u32)(cap >> 24) & SPLIT_SIZE_MASK;
+ if (cap_info->bw == 2)
+ split_mode = SPLIT_MODE_32_L16_VALID;
+ else
+ split_mode = SPLIT_MODE_16_L8_VALID;
+
+ rk_clrsetreg(&dram->ddrgrf->grf_ddrsplit_con,
+ (SPLIT_MODE_MASK << SPLIT_MODE_OFFSET) |
+ (SPLIT_BYPASS_MASK << SPLIT_BYPASS_OFFSET) |
+ (SPLIT_SIZE_MASK << SPLIT_SIZE_OFFSET),
+ (split_mode << SPLIT_MODE_OFFSET) |
+ (0x0 << SPLIT_BYPASS_OFFSET) |
+ (split_size << SPLIT_SIZE_OFFSET));
+
+ rk_clrsetreg(BUS_SGRF_BASE_ADDR + SGRF_SOC_CON2,
+ MSCH_AXI_BYPASS_ALL_MASK << MSCH_AXI_BYPASS_ALL_SHIFT,
+ 0x0 << MSCH_AXI_BYPASS_ALL_SHIFT);
+
+out:
+ return 0;
+}
+
+static void split_bypass(struct dram_info *dram)
+{
+ if ((readl(&dram->ddrgrf->grf_ddrsplit_con) &
+ (1 << SPLIT_BYPASS_OFFSET)) != 0)
+ return;
+
+ /* bypass split */
+ rk_clrsetreg(&dram->ddrgrf->grf_ddrsplit_con,
+ (SPLIT_BYPASS_MASK << SPLIT_BYPASS_OFFSET) |
+ (SPLIT_SIZE_MASK << SPLIT_SIZE_OFFSET),
+ (0x1 << SPLIT_BYPASS_OFFSET) |
+ (0x0 << SPLIT_SIZE_OFFSET));
+}
+
+static void dram_all_config(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 dram_type = sdram_params->base.dramtype;
+ void __iomem *pctl_base = dram->pctl;
+ u32 sys_reg2 = 0;
+ u32 sys_reg3 = 0;
+ u64 cs_cap[2];
+ u32 cs_pst;
+
+ set_ddrconfig(dram, cap_info->ddrconfig);
+ sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+ &sys_reg3, 0);
+ writel(sys_reg2, &dram->pmugrf->os_reg[2]);
+ writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+
+ cs_cap[0] = sdram_get_cs_cap(cap_info, 0, dram_type);
+ cs_cap[1] = sdram_get_cs_cap(cap_info, 1, dram_type);
+
+ if (cap_info->rank == 2) {
+ cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) +
+ 6 + 2;
+ if (cs_pst > 28)
+ cs_cap[0] = 1llu << cs_pst;
+ }
+
+ writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
+ (((cs_cap[0] >> 20) / 64) & 0xff),
+ &dram->msch->devicesize);
+ update_noc_timing(dram, sdram_params);
+}
+
+static void enable_low_power(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ void __iomem *pctl_base = dram->pctl;
+ u32 grf_lp_con;
+
+ writel(0x1f1f0617, &dram->ddrgrf->ddr_grf_con[1]);
+
+ if (sdram_params->base.dramtype == DDR4)
+ grf_lp_con = (0x7 << 16) | (1 << 1);
+ else if (sdram_params->base.dramtype == DDR3)
+ grf_lp_con = (0x7 << 16) | (1 << 0);
+ else
+ grf_lp_con = (0x7 << 16) | (1 << 2);
+
+ /* en lpckdis_en */
+ grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
+ writel(grf_lp_con, &dram->ddrgrf->ddr_grf_lp_con);
+
+ /* enable sr, pd */
+ if (dram->pd_idle == 0)
+ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+ else
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+ if (dram->sr_idle == 0)
+ clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+ else
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+ setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
+}
+
+static void print_ddr_info(struct rv1126_sdram_params *sdram_params)
+{
+ u32 split;
+
+ if ((readl(DDR_GRF_BASE_ADDR + DDR_GRF_SPLIT_CON) &
+ (1 << SPLIT_BYPASS_OFFSET)) != 0)
+ split = 0;
+ else
+ split = readl(DDR_GRF_BASE_ADDR + DDR_GRF_SPLIT_CON) &
+ SPLIT_SIZE_MASK;
+
+ sdram_print_ddr_info(&sdram_params->ch.cap_info,
+ &sdram_params->base, split);
+}
+
+static int sdram_init_(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params, u32 post_init)
+{
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ u32 ddr4_vref;
+ u32 mr_tmp;
+
+ rkclk_configure_ddr(dram, sdram_params);
+
+ rkclk_ddr_reset(dram, 1, 1, 1, 1);
+ udelay(10);
+
+ rkclk_ddr_reset(dram, 1, 1, 1, 0);
+ phy_cfg(dram, sdram_params);
+
+ rkclk_ddr_reset(dram, 1, 1, 0, 0);
+ phy_pll_set(dram, sdram_params->base.ddr_freq * MHZ, 1);
+
+ rkclk_ddr_reset(dram, 1, 0, 0, 0);
+ pctl_cfg(dram->pctl, &sdram_params->pctl_regs,
+ dram->sr_idle, dram->pd_idle);
+
+ if (sdram_params->ch.cap_info.bw == 2) {
+ /* 32bit interface use pageclose */
+ setbits_le32(pctl_base + DDR_PCTL2_SCHED, 1 << 2);
+ /* pageclose = 1, pageclose_timer = 0 will err in lp4 328MHz */
+ clrsetbits_le32(pctl_base + DDR_PCTL2_SCHED1, 0xff, 0x1 << 0);
+ } else {
+ clrbits_le32(pctl_base + DDR_PCTL2_SCHED, 1 << 2);
+ }
+
+#ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT
+ u32 tmp, trefi;
+
+ tmp = readl(pctl_base + DDR_PCTL2_RFSHTMG);
+ trefi = (tmp >> 16) & 0xfff;
+ writel((tmp & 0xf000ffff) | (trefi / 2) << 16,
+ pctl_base + DDR_PCTL2_RFSHTMG);
+#endif
+
+ /* set frequency_mode */
+ setbits_le32(pctl_base + DDR_PCTL2_MSTR, 0x1 << 29);
+ /* set target_frequency to Frequency 0 */
+ clrsetbits_le32(pctl_base + DDR_PCTL2_MSTR2, 0x3, 0);
+
+ set_ds_odt(dram, sdram_params, 0);
+ sdram_params->ch.cap_info.ddrconfig = calculate_ddrconfig(sdram_params);
+ set_ctl_address_map(dram, sdram_params);
+
+ setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
+
+ rkclk_ddr_reset(dram, 0, 0, 0, 0);
+
+ while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
+ continue;
+
+ if (sdram_params->base.dramtype == LPDDR3) {
+ pctl_write_mr(dram->pctl, 3, 11, lp3_odt_value, LPDDR3);
+ } else if (sdram_params->base.dramtype == LPDDR4) {
+ mr_tmp = readl(pctl_base + DDR_PCTL2_INIT6);
+ /* MR11 */
+ pctl_write_mr(dram->pctl, 3, 11,
+ mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK,
+ LPDDR4);
+ /* MR12 */
+ pctl_write_mr(dram->pctl, 3, 12,
+ mr_tmp >> PCTL2_LPDDR4_MR12_SHIFT & PCTL2_MR_MASK,
+ LPDDR4);
+
+ mr_tmp = readl(pctl_base + DDR_PCTL2_INIT7);
+ /* MR22 */
+ pctl_write_mr(dram->pctl, 3, 22,
+ mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK,
+ LPDDR4);
+ }
+
+ if (data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING) != 0) {
+ if (post_init != 0)
+ printascii("DTT cs0 error\n");
+ return -1;
+ }
+
+ if (sdram_params->base.dramtype == LPDDR4) {
+ mr_tmp = read_mr(dram, 1, 14, LPDDR4);
+
+ if (mr_tmp != 0x4d)
+ return -1;
+ }
+
+ if (sdram_params->base.dramtype == LPDDR4) {
+ mr_tmp = readl(pctl_base + DDR_PCTL2_INIT7);
+ /* MR14 */
+ pctl_write_mr(dram->pctl, 3, 14,
+ mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK,
+ LPDDR4);
+ }
+ if (post_init != 0 && sdram_params->ch.cap_info.rank == 2) {
+ if (data_training(dram, 1, sdram_params, 0,
+ READ_GATE_TRAINING) != 0) {
+ printascii("DTT cs1 error\n");
+ return -1;
+ }
+ }
+
+ if (sdram_params->base.dramtype == DDR4) {
+ ddr4_vref = readl(PHY_REG(phy_base, 0x105)) * 39;
+ pctl_write_vrefdq(dram->pctl, 0x3, ddr4_vref,
+ sdram_params->base.dramtype);
+ }
+
+ dram_all_config(dram, sdram_params);
+ enable_low_power(dram, sdram_params);
+
+ return 0;
+}
+
+static u64 dram_detect_cap(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params,
+ unsigned char channel)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ u32 mr8;
+
+ u32 bktmp;
+ u32 coltmp;
+ u32 rowtmp;
+ u32 cs;
+ u32 dram_type = sdram_params->base.dramtype;
+ u32 pwrctl;
+ u32 i, dq_map;
+ u32 byte1 = 0, byte0 = 0;
+ u32 tmp, byte;
+ struct sdram_head_info_index_v2 *index = (struct sdram_head_info_index_v2 *)common_info;
+ struct dq_map_info *map_info = (struct dq_map_info *)
+ ((void *)common_info + index->dq_map_index.offset * 4);
+
+ cap_info->bw = dram_type == DDR3 ? 0 : 1;
+ if (dram_type != LPDDR4) {
+ if (dram_type != DDR4) {
+ coltmp = 12;
+ bktmp = 3;
+ if (dram_type == LPDDR2)
+ rowtmp = 15;
+ else
+ rowtmp = 16;
+
+ if (sdram_detect_col(cap_info, coltmp) != 0)
+ goto cap_err;
+
+ sdram_detect_bank(cap_info, coltmp, bktmp);
+ if (dram_type != LPDDR3)
+ sdram_detect_dbw(cap_info, dram_type);
+ } else {
+ coltmp = 10;
+ bktmp = 4;
+ rowtmp = 17;
+
+ cap_info->col = 10;
+ cap_info->bk = 2;
+ sdram_detect_bg(cap_info, coltmp);
+ }
+
+ if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
+ goto cap_err;
+
+ sdram_detect_row_3_4(cap_info, coltmp, bktmp);
+ } else {
+ cap_info->col = 10;
+ cap_info->bk = 3;
+ mr8 = read_mr(dram, 1, 8, dram_type);
+ cap_info->dbw = ((mr8 >> 6) & 0x3) == 0 ? 1 : 0;
+ mr8 = (mr8 >> 2) & 0xf;
+ if (mr8 >= 0 && mr8 <= 6) {
+ cap_info->cs0_row = 14 + (mr8 + 1) / 2;
+ } else if (mr8 == 0xc) {
+ cap_info->cs0_row = 13;
+ } else {
+ printascii("Cap ERR: Fail to get cap of LPDDR4/X from MR8\n");
+ goto cap_err;
+ }
+ if (cap_info->dbw == 0)
+ cap_info->cs0_row++;
+ cap_info->row_3_4 = mr8 % 2 == 1 ? 1 : 0;
+ if (cap_info->cs0_row >= 17) {
+ printascii("Cap ERR: ");
+ printascii("RV1126 LPDDR4/X cannot support row >= 17\n");
+ goto cap_err;
+ // cap_info->cs0_row = 16;
+ // cap_info->row_3_4 = 0;
+ }
+ }
+
+ pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+ writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+
+ if (data_training(dram, 1, sdram_params, 0, READ_GATE_TRAINING) == 0)
+ cs = 1;
+ else
+ cs = 0;
+ cap_info->rank = cs + 1;
+
+ setbits_le32(PHY_REG(phy_base, 0xf), 0xf);
+
+ tmp = data_training_rg(dram, 0, dram_type) & 0xf;
+
+ if (tmp == 0) {
+ cap_info->bw = 2;
+ } else {
+ if (dram_type == DDR3 || dram_type == DDR4) {
+ dq_map = 0;
+ byte = 0;
+ for (i = 0; i < 4; i++) {
+ if ((tmp & BIT(i)) == 0) {
+ dq_map |= byte << (i * 2);
+ byte++;
+ }
+ }
+ cap_info->bw = byte / 2;
+ for (i = 0; i < 4; i++) {
+ if ((tmp & BIT(i)) != 0) {
+ dq_map |= byte << (i * 2);
+ byte++;
+ }
+ }
+ clrsetbits_le32(&map_info->byte_map[0], 0xff << 24, dq_map << 24);
+ } else {
+ dq_map = readl(PHY_REG(phy_base, 0x4f));
+ for (i = 0; i < 4; i++) {
+ if (((dq_map >> (i * 2)) & 0x3) == 0)
+ byte0 = i;
+ if (((dq_map >> (i * 2)) & 0x3) == 1)
+ byte1 = i;
+ }
+ clrsetbits_le32(PHY_REG(phy_base, 0xf), PHY_DQ_WIDTH_MASK,
+ BIT(byte0) | BIT(byte1));
+ if (data_training(dram, 0, sdram_params, 0, READ_GATE_TRAINING) == 0)
+ cap_info->bw = 1;
+ else
+ cap_info->bw = 0;
+ }
+ }
+ if (cap_info->bw > 0)
+ cap_info->dbw = 1;
+
+ writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
+
+ cap_info->cs0_high16bit_row = cap_info->cs0_row;
+ if (cs) {
+ cap_info->cs1_row = cap_info->cs0_row;
+ cap_info->cs1_high16bit_row = cap_info->cs0_row;
+ } else {
+ cap_info->cs1_row = 0;
+ cap_info->cs1_high16bit_row = 0;
+ }
+
+ if (dram_type == LPDDR3)
+ sdram_detect_dbw(cap_info, dram_type);
+
+ return 0;
+cap_err:
+ return -1;
+}
+
+static int dram_detect_cs1_row(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params,
+ unsigned char channel)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ void __iomem *pctl_base = dram->pctl;
+ u32 ret = 0;
+ void __iomem *test_addr;
+ u32 row, bktmp, coltmp, bw;
+ u64 cs0_cap;
+ u32 byte_mask;
+ u32 cs_pst;
+ u32 cs_add = 0;
+ u32 max_row;
+
+ if (cap_info->rank == 2) {
+ cs_pst = (readl(pctl_base + DDR_PCTL2_ADDRMAP0) & 0x1f) +
+ 6 + 2;
+ if (cs_pst < 28)
+ cs_add = 1;
+
+ cs0_cap = 1 << cs_pst;
+
+ if (sdram_params->base.dramtype == DDR4) {
+ if (cap_info->dbw == 0)
+ bktmp = cap_info->bk + 2;
+ else
+ bktmp = cap_info->bk + 1;
+ } else {
+ bktmp = cap_info->bk;
+ }
+ bw = cap_info->bw;
+ coltmp = cap_info->col;
+
+ if (bw == 2)
+ byte_mask = 0xFFFF;
+ else
+ byte_mask = 0xFF;
+
+ max_row = (cs_pst == 31) ? 30 : 31;
+
+ max_row = max_row - bktmp - coltmp - bw - cs_add + 1;
+
+ row = (cap_info->cs0_row > max_row) ? max_row :
+ cap_info->cs0_row;
+
+ for (; row > 12; row--) {
+ test_addr = (void __iomem *)(CFG_SYS_SDRAM_BASE +
+ (u32)cs0_cap +
+ (1ul << (row + bktmp + coltmp +
+ cs_add + bw - 1ul)));
+
+ writel(0, CFG_SYS_SDRAM_BASE + (u32)cs0_cap);
+ writel(PATTERN, test_addr);
+
+ if (((readl(test_addr) & byte_mask) ==
+ (PATTERN & byte_mask)) &&
+ ((readl(CFG_SYS_SDRAM_BASE + (u32)cs0_cap) &
+ byte_mask) == 0)) {
+ ret = row;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/* return: 0 = success, other = fail */
+static int sdram_init_detect(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ struct sdram_cap_info *cap_info = &sdram_params->ch.cap_info;
+ u32 ret;
+ u32 sys_reg = 0;
+ u32 sys_reg3 = 0;
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ struct dq_map_info *map_info;
+
+ map_info = (struct dq_map_info *)((void *)common_info +
+ index->dq_map_index.offset * 4);
+
+ if (sdram_init_(dram, sdram_params, 0)) {
+ if (sdram_params->base.dramtype == DDR3) {
+ clrsetbits_le32(&map_info->byte_map[0], 0xff << 24,
+ ((0x1 << 6) | (0x3 << 4) | (0x2 << 2) |
+ (0x0 << 0)) << 24);
+ if (sdram_init_(dram, sdram_params, 0))
+ return -1;
+ } else {
+ return -1;
+ }
+ }
+
+ if (sdram_params->base.dramtype == DDR3) {
+ writel(PATTERN, CFG_SYS_SDRAM_BASE);
+ if (readl(CFG_SYS_SDRAM_BASE) != PATTERN)
+ return -1;
+ }
+
+ split_bypass(dram);
+ if (dram_detect_cap(dram, sdram_params, 0) != 0)
+ return -1;
+
+ pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+ sdram_params->base.dramtype);
+ ret = sdram_init_(dram, sdram_params, 1);
+ if (ret != 0)
+ goto out;
+
+ cap_info->cs1_row =
+ dram_detect_cs1_row(dram, sdram_params, 0);
+ if (cap_info->cs1_row) {
+ sys_reg = readl(&dram->pmugrf->os_reg[2]);
+ sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
+ SYS_REG_ENC_CS1_ROW(cap_info->cs1_row,
+ sys_reg, sys_reg3, 0);
+ writel(sys_reg, &dram->pmugrf->os_reg[2]);
+ writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+ }
+
+ sdram_detect_high_row(cap_info);
+ split_setup(dram, sdram_params);
+out:
+ return ret;
+}
+
+struct rv1126_sdram_params *get_default_sdram_config(u32 freq_mhz)
+{
+ u32 i;
+ u32 offset = 0;
+ struct ddr2_3_4_lp2_3_info *ddr_info;
+
+ if (!freq_mhz) {
+ ddr_info = get_ddr_drv_odt_info(sdram_configs[0].base.dramtype);
+ if (ddr_info)
+ freq_mhz =
+ (ddr_info->ddr_freq0_1 >> DDR_FREQ_F0_SHIFT) &
+ DDR_FREQ_MASK;
+ else
+ freq_mhz = 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(sdram_configs); i++) {
+ if (sdram_configs[i].base.ddr_freq == 0 ||
+ freq_mhz < sdram_configs[i].base.ddr_freq)
+ break;
+ }
+ offset = i == 0 ? 0 : i - 1;
+
+ return &sdram_configs[offset];
+}
+
+static const u16 pctl_need_update_reg[] = {
+ DDR_PCTL2_RFSHTMG,
+ DDR_PCTL2_INIT3,
+ DDR_PCTL2_INIT4,
+ DDR_PCTL2_INIT6,
+ DDR_PCTL2_INIT7,
+ DDR_PCTL2_DRAMTMG0,
+ DDR_PCTL2_DRAMTMG1,
+ DDR_PCTL2_DRAMTMG2,
+ DDR_PCTL2_DRAMTMG3,
+ DDR_PCTL2_DRAMTMG4,
+ DDR_PCTL2_DRAMTMG5,
+ DDR_PCTL2_DRAMTMG6,
+ DDR_PCTL2_DRAMTMG7,
+ DDR_PCTL2_DRAMTMG8,
+ DDR_PCTL2_DRAMTMG9,
+ DDR_PCTL2_DRAMTMG12,
+ DDR_PCTL2_DRAMTMG13,
+ DDR_PCTL2_DRAMTMG14,
+ DDR_PCTL2_ZQCTL0,
+ DDR_PCTL2_DFITMG0,
+ DDR_PCTL2_ODTCFG
+};
+
+static const u16 phy_need_update_reg[] = {
+ 0x14,
+ 0x18,
+ 0x1c
+};
+
+static void pre_set_rate(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params,
+ u32 dst_fsp, u32 dst_fsp_lp4)
+{
+ u32 i, j, find;
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ u32 phy_offset;
+ u32 mr_tmp;
+ u32 dramtype = sdram_params->base.dramtype;
+
+ sw_set_req(dram);
+ /* pctl timing update */
+ for (i = 0, find = 0; i < ARRAY_SIZE(pctl_need_update_reg); i++) {
+ for (j = find; sdram_params->pctl_regs.pctl[j][0] != 0xFFFFFFFF;
+ j++) {
+ if (sdram_params->pctl_regs.pctl[j][0] ==
+ pctl_need_update_reg[i]) {
+ writel(sdram_params->pctl_regs.pctl[j][1],
+ pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ pctl_need_update_reg[i]);
+ find = j;
+ break;
+ }
+ }
+ }
+
+#ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT
+ u32 tmp, trefi;
+
+ tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_RFSHTMG);
+ trefi = (tmp >> 16) & 0xfff;
+ writel((tmp & 0xf000ffff) | (trefi / 2) << 16,
+ pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_RFSHTMG);
+#endif
+
+ sw_set_ack(dram);
+
+ /* phy timing update */
+ if (dst_fsp == 0)
+ phy_offset = 0;
+ else
+ phy_offset = PHY_REG(0, 0x387 - 5 + (dst_fsp - 1) * 3);
+ /* cl cwl al update */
+ for (i = 0, find = 0; i < ARRAY_SIZE(phy_need_update_reg); i++) {
+ for (j = find; sdram_params->phy_regs.phy[j][0] != 0xFFFFFFFF;
+ j++) {
+ if (sdram_params->phy_regs.phy[j][0] ==
+ phy_need_update_reg[i]) {
+ writel(sdram_params->phy_regs.phy[j][1],
+ phy_base + phy_offset +
+ phy_need_update_reg[i]);
+ find = j;
+ break;
+ }
+ }
+ }
+
+ set_ds_odt(dram, sdram_params, dst_fsp);
+ if (dramtype == LPDDR4) {
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT4);
+ /* MR13 */
+ pctl_write_mr(dram->pctl, 3, 13,
+ ((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT &
+ PCTL2_MR_MASK) & (~(BIT(7) | BIT(6)))) |
+ ((0x2 << 6) >> dst_fsp_lp4), dramtype);
+ writel(((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT &
+ PCTL2_MR_MASK) & (~(BIT(7) | BIT(6)))) |
+ ((0x2 << 6) >> dst_fsp_lp4),
+ PHY_REG(phy_base, 0x1b));
+ /* MR3 */
+ pctl_write_mr(dram->pctl, 3, 3,
+ mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT &
+ PCTL2_MR_MASK,
+ dramtype);
+ writel(mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT & PCTL2_MR_MASK,
+ PHY_REG(phy_base, 0x19));
+
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT3);
+ /* MR1 */
+ pctl_write_mr(dram->pctl, 3, 1,
+ mr_tmp >> PCTL2_LPDDR234_MR1_SHIFT &
+ PCTL2_MR_MASK,
+ dramtype);
+ writel(mr_tmp >> PCTL2_LPDDR234_MR1_SHIFT & PCTL2_MR_MASK,
+ PHY_REG(phy_base, 0x17));
+ /* MR2 */
+ pctl_write_mr(dram->pctl, 3, 2, mr_tmp & PCTL2_MR_MASK,
+ dramtype);
+ writel(mr_tmp & PCTL2_MR_MASK,
+ PHY_REG(phy_base, 0x18));
+
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT6);
+ /* MR11 */
+ pctl_write_mr(dram->pctl, 3, 11,
+ mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK,
+ dramtype);
+ writel(mr_tmp >> PCTL2_LPDDR4_MR11_SHIFT & PCTL2_MR_MASK,
+ PHY_REG(phy_base, 0x1a));
+ /* MR12 */
+ pctl_write_mr(dram->pctl, 3, 12,
+ mr_tmp >> PCTL2_LPDDR4_MR12_SHIFT & PCTL2_MR_MASK,
+ dramtype);
+
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT7);
+ /* MR22 */
+ pctl_write_mr(dram->pctl, 3, 22,
+ mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK,
+ dramtype);
+ writel(mr_tmp >> PCTL2_LPDDR4_MR22_SHIFT & PCTL2_MR_MASK,
+ PHY_REG(phy_base, 0x1d));
+ /* MR14 */
+ pctl_write_mr(dram->pctl, 3, 14,
+ mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK,
+ dramtype);
+ writel(mr_tmp >> PCTL2_LPDDR4_MR14_SHIFT & PCTL2_MR_MASK,
+ PHY_REG(phy_base, 0x1c));
+ }
+
+ update_noc_timing(dram, sdram_params);
+}
+
+static void save_fsp_param(struct dram_info *dram, u32 dst_fsp,
+ struct rv1126_sdram_params *sdram_params)
+{
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+ struct rv1126_fsp_param *p_fsp_param = &fsp_param[dst_fsp];
+ u32 temp, temp1;
+ struct ddr2_3_4_lp2_3_info *ddr_info;
+
+ ddr_info = get_ddr_drv_odt_info(sdram_params->base.dramtype);
+
+ p_fsp_param->freq_mhz = sdram_params->base.ddr_freq;
+
+ if (sdram_params->base.dramtype == LPDDR4) {
+ p_fsp_param->rd_odt_up_en = 0;
+ p_fsp_param->rd_odt_down_en = 1;
+ } else {
+ p_fsp_param->rd_odt_up_en =
+ ODT_INFO_PULLUP_EN(ddr_info->odt_info);
+ p_fsp_param->rd_odt_down_en =
+ ODT_INFO_PULLDOWN_EN(ddr_info->odt_info);
+ }
+
+ if (p_fsp_param->rd_odt_up_en)
+ p_fsp_param->rd_odt = readl(PHY_REG(phy_base, 0x111));
+ else if (p_fsp_param->rd_odt_down_en)
+ p_fsp_param->rd_odt = readl(PHY_REG(phy_base, 0x110));
+ else
+ p_fsp_param->rd_odt = 0;
+ p_fsp_param->wr_dq_drv = readl(PHY_REG(phy_base, 0x112));
+ p_fsp_param->wr_ca_drv = readl(PHY_REG(phy_base, 0x100));
+ p_fsp_param->wr_ckcs_drv = readl(PHY_REG(phy_base, 0x102));
+ p_fsp_param->vref_inner = readl(PHY_REG(phy_base, 0x128));
+ p_fsp_param->vref_out = readl(PHY_REG(phy_base, 0x105));
+
+ if (sdram_params->base.dramtype == DDR3) {
+ temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT3);
+ temp = (temp >> PCTL2_DDR34_MR1_SHIFT) & PCTL2_MR_MASK;
+ p_fsp_param->ds_pdds = temp & DDR3_DS_MASK;
+ p_fsp_param->dq_odt = temp & DDR3_RTT_NOM_MASK;
+ p_fsp_param->ca_odt = p_fsp_param->dq_odt;
+ } else if (sdram_params->base.dramtype == DDR4) {
+ temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT3);
+ temp = (temp >> PCTL2_DDR34_MR1_SHIFT) & PCTL2_MR_MASK;
+ p_fsp_param->ds_pdds = temp & DDR4_DS_MASK;
+ p_fsp_param->dq_odt = temp & DDR4_RTT_NOM_MASK;
+ p_fsp_param->ca_odt = p_fsp_param->dq_odt;
+ } else if (sdram_params->base.dramtype == LPDDR3) {
+ temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT4);
+ temp = (temp >> PCTL2_LPDDR234_MR3_SHIFT) & PCTL2_MR_MASK;
+ p_fsp_param->ds_pdds = temp & 0xf;
+
+ p_fsp_param->dq_odt = lp3_odt_value;
+ p_fsp_param->ca_odt = p_fsp_param->dq_odt;
+ } else if (sdram_params->base.dramtype == LPDDR4) {
+ temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT4);
+ temp = (temp >> PCTL2_LPDDR234_MR3_SHIFT) & PCTL2_MR_MASK;
+ p_fsp_param->ds_pdds = temp & LPDDR4_PDDS_MASK;
+
+ temp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT6);
+ temp = (temp >> PCTL2_LPDDR4_MR11_SHIFT) & PCTL2_MR_MASK;
+ p_fsp_param->dq_odt = temp & LPDDR4_DQODT_MASK;
+ p_fsp_param->ca_odt = temp & LPDDR4_CAODT_MASK;
+
+ temp = MAX(readl(PHY_REG(phy_base, 0x3ae)),
+ readl(PHY_REG(phy_base, 0x3ce)));
+ temp1 = MIN(readl(PHY_REG(phy_base, 0x3be)),
+ readl(PHY_REG(phy_base, 0x3de)));
+ p_fsp_param->vref_ca[0] = (temp + temp1) / 2;
+ temp = MAX(readl(PHY_REG(phy_base, 0x3af)),
+ readl(PHY_REG(phy_base, 0x3cf)));
+ temp1 = MIN(readl(PHY_REG(phy_base, 0x3bf)),
+ readl(PHY_REG(phy_base, 0x3df)));
+ p_fsp_param->vref_ca[1] = (temp + temp1) / 2;
+ p_fsp_param->vref_ca[0] |=
+ (readl(PHY_REG(phy_base, 0x1e)) & BIT(6));
+ p_fsp_param->vref_ca[1] |=
+ (readl(PHY_REG(phy_base, 0x1e)) & BIT(6));
+
+ p_fsp_param->lp4_drv_pd_en = (readl(PHY_REG(phy_base, 0x114)) >>
+ 3) & 0x1;
+ }
+
+ p_fsp_param->noc_timings.ddrtiminga0 =
+ sdram_params->ch.noc_timings.ddrtiminga0;
+ p_fsp_param->noc_timings.ddrtimingb0 =
+ sdram_params->ch.noc_timings.ddrtimingb0;
+ p_fsp_param->noc_timings.ddrtimingc0 =
+ sdram_params->ch.noc_timings.ddrtimingc0;
+ p_fsp_param->noc_timings.devtodev0 =
+ sdram_params->ch.noc_timings.devtodev0;
+ p_fsp_param->noc_timings.ddrmode =
+ sdram_params->ch.noc_timings.ddrmode;
+ p_fsp_param->noc_timings.ddr4timing =
+ sdram_params->ch.noc_timings.ddr4timing;
+ p_fsp_param->noc_timings.agingx0 =
+ sdram_params->ch.noc_timings.agingx0;
+ p_fsp_param->noc_timings.aging0 =
+ sdram_params->ch.noc_timings.aging0;
+ p_fsp_param->noc_timings.aging1 =
+ sdram_params->ch.noc_timings.aging1;
+ p_fsp_param->noc_timings.aging2 =
+ sdram_params->ch.noc_timings.aging2;
+ p_fsp_param->noc_timings.aging3 =
+ sdram_params->ch.noc_timings.aging3;
+
+ p_fsp_param->flag = FSP_FLAG;
+}
+
+static void copy_fsp_param_to_ddr(void)
+{
+ memcpy((void *)FSP_PARAM_STORE_ADDR, (void *)&fsp_param,
+ sizeof(fsp_param));
+}
+
+static void pctl_modify_trfc(struct ddr_pctl_regs *pctl_regs,
+ struct sdram_cap_info *cap_info, u32 dram_type,
+ u32 freq)
+{
+ u64 cs0_cap;
+ u32 die_cap;
+ u32 trfc_ns, trfc4_ns;
+ u32 trfc, txsnr;
+ u32 txs_abort_fast = 0;
+ u32 tmp;
+
+ cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
+ die_cap = (u32)(cs0_cap >> (20 + (cap_info->bw - cap_info->dbw)));
+
+ switch (dram_type) {
+ case DDR3:
+ if (die_cap <= DIE_CAP_512MBIT)
+ trfc_ns = 90;
+ else if (die_cap <= DIE_CAP_1GBIT)
+ trfc_ns = 110;
+ else if (die_cap <= DIE_CAP_2GBIT)
+ trfc_ns = 160;
+ else if (die_cap <= DIE_CAP_4GBIT)
+ trfc_ns = 260;
+ else
+ trfc_ns = 350;
+ txsnr = MAX(5, ((trfc_ns + 10) * freq + 999) / 1000);
+ break;
+
+ case DDR4:
+ if (die_cap <= DIE_CAP_2GBIT) {
+ trfc_ns = 160;
+ trfc4_ns = 90;
+ } else if (die_cap <= DIE_CAP_4GBIT) {
+ trfc_ns = 260;
+ trfc4_ns = 110;
+ } else if (die_cap <= DIE_CAP_8GBIT) {
+ trfc_ns = 350;
+ trfc4_ns = 160;
+ } else {
+ trfc_ns = 550;
+ trfc4_ns = 260;
+ }
+ txsnr = ((trfc_ns + 10) * freq + 999) / 1000;
+ txs_abort_fast = ((trfc4_ns + 10) * freq + 999) / 1000;
+ break;
+
+ case LPDDR3:
+ if (die_cap <= DIE_CAP_4GBIT)
+ trfc_ns = 130;
+ else
+ trfc_ns = 210;
+ txsnr = MAX(2, ((trfc_ns + 10) * freq + 999) / 1000);
+ break;
+
+ case LPDDR4:
+ if (die_cap <= DIE_CAP_2GBIT)
+ trfc_ns = 130;
+ else if (die_cap <= DIE_CAP_4GBIT)
+ trfc_ns = 180;
+ else if (die_cap <= DIE_CAP_8GBIT)
+ trfc_ns = 280;
+ else
+ trfc_ns = 380;
+ txsnr = MAX(2, ((trfc_ns + 10) * freq + 999) / 1000);
+ break;
+
+ default:
+ return;
+ }
+ trfc = (trfc_ns * freq + 999) / 1000;
+
+ for (int i = 0; pctl_regs->pctl[i][0] != 0xffffffff; i++) {
+ switch (pctl_regs->pctl[i][0]) {
+ case DDR_PCTL2_RFSHTMG:
+ tmp = pctl_regs->pctl[i][1];
+ /* t_rfc_min */
+ tmp &= ~((u32)0x3ff);
+ tmp |= ((trfc + 1) / 2) & 0x3ff;
+ pctl_regs->pctl[i][1] = tmp;
+ break;
+
+ case DDR_PCTL2_DRAMTMG8:
+ if (dram_type == DDR3 || dram_type == DDR4) {
+ tmp = pctl_regs->pctl[i][1];
+ /* t_xs_x32 */
+ tmp &= ~((u32)0x7f);
+ tmp |= ((txsnr + 63) / 64) & 0x7f;
+
+ if (dram_type == DDR4) {
+ /* t_xs_abort_x32 */
+ tmp &= ~((u32)(0x7f << 16));
+ tmp |= (((txs_abort_fast + 63) / 64) & 0x7f) << 16;
+ /* t_xs_fast_x32 */
+ tmp &= ~((u32)(0x7f << 24));
+ tmp |= (((txs_abort_fast + 63) / 64) & 0x7f) << 24;
+ }
+
+ pctl_regs->pctl[i][1] = tmp;
+ }
+ break;
+
+ case DDR_PCTL2_DRAMTMG14:
+ if (dram_type == LPDDR3 ||
+ dram_type == LPDDR4) {
+ tmp = pctl_regs->pctl[i][1];
+ /* t_xsr */
+ tmp &= ~((u32)0xfff);
+ tmp |= ((txsnr + 1) / 2) & 0xfff;
+ pctl_regs->pctl[i][1] = tmp;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void ddr_set_rate(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params,
+ u32 freq, u32 cur_freq, u32 dst_fsp,
+ u32 dst_fsp_lp4, u32 training_en)
+{
+ u32 dest_dll_off, cur_init3, dst_init3, cur_fsp, cur_dll_off;
+ u32 mr_tmp;
+ u32 lp_stat;
+ u32 dramtype = sdram_params->base.dramtype;
+ struct rv1126_sdram_params *sdram_params_new;
+ void __iomem *pctl_base = dram->pctl;
+ void __iomem *phy_base = dram->phy;
+
+ lp_stat = low_power_update(dram, 0);
+ sdram_params_new = get_default_sdram_config(freq);
+ sdram_params_new->ch.cap_info.rank = sdram_params->ch.cap_info.rank;
+ sdram_params_new->ch.cap_info.bw = sdram_params->ch.cap_info.bw;
+
+ pctl_modify_trfc(&sdram_params_new->pctl_regs,
+ &sdram_params->ch.cap_info, dramtype, freq);
+ pre_set_rate(dram, sdram_params_new, dst_fsp, dst_fsp_lp4);
+
+ while ((readl(pctl_base + DDR_PCTL2_STAT) &
+ PCTL2_OPERATING_MODE_MASK) ==
+ PCTL2_OPERATING_MODE_SR)
+ continue;
+
+ dest_dll_off = 0;
+ dst_init3 = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT3);
+ if ((dramtype == DDR3 && (dst_init3 & 1)) ||
+ (dramtype == DDR4 && !(dst_init3 & 1)))
+ dest_dll_off = 1;
+
+ cur_fsp = readl(pctl_base + DDR_PCTL2_MSTR2) & 0x3;
+ cur_init3 = readl(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) +
+ DDR_PCTL2_INIT3);
+ cur_init3 &= PCTL2_MR_MASK;
+ cur_dll_off = 1;
+ if ((dramtype == DDR3 && !(cur_init3 & 1)) ||
+ (dramtype == DDR4 && (cur_init3 & 1)))
+ cur_dll_off = 0;
+
+ if (!cur_dll_off) {
+ if (dramtype == DDR3)
+ cur_init3 |= 1;
+ else
+ cur_init3 &= ~1;
+ pctl_write_mr(dram->pctl, 2, 1, cur_init3, dramtype);
+ }
+
+ setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3,
+ PCTL2_DIS_AUTO_REFRESH);
+ update_refresh_reg(dram);
+
+ enter_sr(dram, 1);
+
+ writel(PMUGRF_CON_DDRPHY_BUFFEREN_MASK |
+ PMUGRF_CON_DDRPHY_BUFFEREN_EN,
+ &dram->pmugrf->soc_con[0]);
+ sw_set_req(dram);
+ clrbits_le32(pctl_base + DDR_PCTL2_DFIMISC,
+ PCTL2_DFI_INIT_COMPLETE_EN);
+ sw_set_ack(dram);
+
+ sw_set_req(dram);
+ if ((dramtype == DDR3 || dramtype == DDR4) && dest_dll_off)
+ setbits_le32(pctl_base + DDR_PCTL2_MSTR, PCTL2_DLL_OFF_MODE);
+ else
+ clrbits_le32(pctl_base + DDR_PCTL2_MSTR, PCTL2_DLL_OFF_MODE);
+
+ setbits_le32(pctl_base + UMCTL2_REGS_FREQ(cur_fsp) + DDR_PCTL2_ZQCTL0,
+ PCTL2_DIS_SRX_ZQCL);
+ setbits_le32(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_ZQCTL0,
+ PCTL2_DIS_SRX_ZQCL);
+ sw_set_ack(dram);
+
+ writel(DDR_MSCH_EN_MASK | (0x1 << DDR_MSCH_EN_SHIFT),
+ &dram->cru->clkgate_con[21]);
+ writel(CLK_DDR_UPCTL_EN_MASK | ACLK_DDR_UPCTL_EN_MASK |
+ (0x1 << CLK_DDR_UPCTL_EN_SHIFT) |
+ (0x1 << ACLK_DDR_UPCTL_EN_SHIFT),
+ BUS_SGRF_BASE_ADDR + SGRF_SOC_CON12);
+
+ clrbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET | DIGITAL_DERESET);
+ rkclk_set_dpll(dram, freq * MHz / 2);
+ phy_pll_set(dram, freq * MHz, 0);
+ phy_pll_set(dram, freq * MHz, 1);
+ setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET | DIGITAL_DERESET);
+
+ writel(PMUGRF_CON_DDRPHY_BUFFEREN_MASK |
+ PMUGRF_CON_DDRPHY_BUFFEREN_DIS,
+ &dram->pmugrf->soc_con[0]);
+ writel(DDR_MSCH_EN_MASK | (0x0 << DDR_MSCH_EN_SHIFT),
+ &dram->cru->clkgate_con[21]);
+ writel(CLK_DDR_UPCTL_EN_MASK | ACLK_DDR_UPCTL_EN_MASK |
+ (0x0 << CLK_DDR_UPCTL_EN_SHIFT) |
+ (0x0 << ACLK_DDR_UPCTL_EN_SHIFT),
+ BUS_SGRF_BASE_ADDR + SGRF_SOC_CON12);
+ while ((readl(pctl_base + DDR_PCTL2_DFISTAT) &
+ PCTL2_DFI_INIT_COMPLETE) != PCTL2_DFI_INIT_COMPLETE)
+ continue;
+
+ sw_set_req(dram);
+ setbits_le32(pctl_base + DDR_PCTL2_MSTR, 0x1 << 29);
+ clrsetbits_le32(pctl_base + DDR_PCTL2_MSTR2, 0x3, dst_fsp);
+ sw_set_ack(dram);
+ update_refresh_reg(dram);
+ clrsetbits_le32(PHY_REG(phy_base, 0xc), 0x3 << 2, dst_fsp << 2);
+
+ enter_sr(dram, 0);
+
+ setbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+ clrbits_le32(PHY_REG(phy_base, 0x71), 1 << 5);
+
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) + DDR_PCTL2_INIT4);
+ if (dramtype == LPDDR3) {
+ pctl_write_mr(dram->pctl, 3, 1,
+ (dst_init3 >> PCTL2_LPDDR234_MR1_SHIFT) &
+ PCTL2_MR_MASK,
+ dramtype);
+ pctl_write_mr(dram->pctl, 3, 2, dst_init3 & PCTL2_MR_MASK,
+ dramtype);
+ pctl_write_mr(dram->pctl, 3, 3,
+ (mr_tmp >> PCTL2_LPDDR234_MR3_SHIFT) &
+ PCTL2_MR_MASK,
+ dramtype);
+ pctl_write_mr(dram->pctl, 3, 11, lp3_odt_value, dramtype);
+ } else if ((dramtype == DDR3) || (dramtype == DDR4)) {
+ pctl_write_mr(dram->pctl, 3, 1, dst_init3 & PCTL2_MR_MASK,
+ dramtype);
+ if (!dest_dll_off) {
+ pctl_write_mr(dram->pctl, 3, 0,
+ ((dst_init3 >> PCTL2_DDR34_MR0_SHIFT) &
+ PCTL2_MR_MASK) | DDR3_DLL_RESET,
+ dramtype);
+ udelay(2);
+ }
+ pctl_write_mr(dram->pctl, 3, 0,
+ (dst_init3 >> PCTL2_DDR34_MR0_SHIFT &
+ PCTL2_MR_MASK) & (~DDR3_DLL_RESET),
+ dramtype);
+ pctl_write_mr(dram->pctl, 3, 2,
+ ((mr_tmp >> PCTL2_DDR34_MR2_SHIFT) &
+ PCTL2_MR_MASK), dramtype);
+ if (dramtype == DDR4) {
+ pctl_write_mr(dram->pctl, 3, 3, mr_tmp & PCTL2_MR_MASK,
+ dramtype);
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT6);
+ pctl_write_mr(dram->pctl, 3, 4,
+ (mr_tmp >> PCTL2_DDR4_MR4_SHIFT) &
+ PCTL2_MR_MASK,
+ dramtype);
+ pctl_write_mr(dram->pctl, 3, 5,
+ mr_tmp >> PCTL2_DDR4_MR5_SHIFT &
+ PCTL2_MR_MASK,
+ dramtype);
+
+ mr_tmp = readl(pctl_base + UMCTL2_REGS_FREQ(dst_fsp) +
+ DDR_PCTL2_INIT7);
+ pctl_write_mr(dram->pctl, 3, 6,
+ mr_tmp >> PCTL2_DDR4_MR6_SHIFT &
+ PCTL2_MR_MASK,
+ dramtype);
+ }
+ } else if (dramtype == LPDDR4) {
+ pctl_write_mr(dram->pctl, 3, 13,
+ ((mr_tmp >> PCTL2_LPDDR4_MR13_SHIFT &
+ PCTL2_MR_MASK) & (~(BIT(7)))) |
+ dst_fsp_lp4 << 7, dramtype);
+ }
+ clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3,
+ PCTL2_DIS_AUTO_REFRESH);
+ update_refresh_reg(dram);
+
+ /* training */
+ high_freq_training(dram, sdram_params_new, dst_fsp);
+ low_power_update(dram, lp_stat);
+
+ save_fsp_param(dram, dst_fsp, sdram_params_new);
+}
+
+static void ddr_set_rate_for_fsp(struct dram_info *dram,
+ struct rv1126_sdram_params *sdram_params)
+{
+ struct ddr2_3_4_lp2_3_info *ddr_info;
+ u32 f0;
+ u32 dramtype = sdram_params->base.dramtype;
+ u32 f1, f2, f3;
+
+ ddr_info = get_ddr_drv_odt_info(dramtype);
+ if (!ddr_info)
+ return;
+
+ f0 = (ddr_info->ddr_freq0_1 >> DDR_FREQ_F0_SHIFT) &
+ DDR_FREQ_MASK;
+
+ memset((void *)FSP_PARAM_STORE_ADDR, 0, sizeof(fsp_param));
+ memset((void *)&fsp_param, 0, sizeof(fsp_param));
+
+ f1 = (ddr_info->ddr_freq0_1 >> DDR_FREQ_F1_SHIFT) &
+ DDR_FREQ_MASK;
+ f2 = (ddr_info->ddr_freq2_3 >> DDR_FREQ_F2_SHIFT) &
+ DDR_FREQ_MASK;
+ f3 = (ddr_info->ddr_freq2_3 >> DDR_FREQ_F3_SHIFT) &
+ DDR_FREQ_MASK;
+
+ if (get_wrlvl_val(dram, sdram_params))
+ printascii("get wrlvl value fail\n");
+
+ if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) {
+ printascii("change to: ");
+ printdec(f1);
+ printascii("MHz\n");
+ }
+ ddr_set_rate(&dram_info, sdram_params, f1,
+ sdram_params->base.ddr_freq, 1, 1, 1);
+
+ if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) {
+ printascii("change to: ");
+ printdec(f2);
+ printascii("MHz\n");
+ }
+ ddr_set_rate(&dram_info, sdram_params, f2, f1, 2, 0, 1);
+
+ if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) {
+ printascii("change to: ");
+ printdec(f3);
+ printascii("MHz\n");
+ }
+ ddr_set_rate(&dram_info, sdram_params, f3, f2, 3, 1, 1);
+
+ if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG)) {
+ printascii("change to: ");
+ printdec(f0);
+ printascii("MHz(final freq)\n");
+ }
+ ddr_set_rate(&dram_info, sdram_params, f0, f3, 0, 0, 1);
+}
+
+int get_uart_config(void)
+{
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ struct global_info *gbl_info;
+
+ gbl_info = (struct global_info *)((void *)common_info +
+ index->global_index.offset * 4);
+
+ return gbl_info->uart_info;
+}
+
+/* return: 0 = success, other = fail */
+static int rv1126_dmc_init(struct udevice *dev)
+{
+ struct rv1126_sdram_params *sdram_params;
+ int ret = 0;
+ struct sdram_head_info_index_v2 *index =
+ (struct sdram_head_info_index_v2 *)common_info;
+ struct global_info *gbl_info;
+
+ dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
+ dram_info.pctl = (void *)UPCTL2_BASE_ADDR;
+ dram_info.grf = (void *)GRF_BASE_ADDR;
+ dram_info.cru = (void *)CRU_BASE_ADDR;
+ dram_info.msch = (void *)SERVER_MSCH_BASE_ADDR;
+ dram_info.ddrgrf = (void *)DDR_GRF_BASE_ADDR;
+ dram_info.pmugrf = (void *)PMU_GRF_BASE_ADDR;
+
+#ifdef CONFIG_ROCKCHIP_DRAM_EXTENDED_TEMP_SUPPORT
+ printascii("extended temp support\n");
+#endif
+ if (index->version_info != 2 ||
+ (index->global_index.size != sizeof(struct global_info) / 4) ||
+ (index->ddr3_index.size !=
+ sizeof(struct ddr2_3_4_lp2_3_info) / 4) ||
+ (index->ddr4_index.size !=
+ sizeof(struct ddr2_3_4_lp2_3_info) / 4) ||
+ (index->lp3_index.size !=
+ sizeof(struct ddr2_3_4_lp2_3_info) / 4) ||
+ (index->lp4_index.size != (sizeof(struct lp4_info) / 4)) ||
+ (index->lp4x_index.size != (sizeof(struct lp4_info) / 4)) ||
+ index->global_index.offset == 0 ||
+ index->ddr3_index.offset == 0 ||
+ index->ddr4_index.offset == 0 ||
+ index->lp3_index.offset == 0 ||
+ index->lp4_index.offset == 0 ||
+ index->lp4x_index.offset == 0) {
+ printascii("common info error\n");
+ goto error;
+ }
+
+ gbl_info = (struct global_info *)((void *)common_info +
+ index->global_index.offset * 4);
+
+ dram_info.sr_idle = SR_INFO(gbl_info->sr_pd_info);
+ dram_info.pd_idle = PD_INFO(gbl_info->sr_pd_info);
+
+ sdram_params = &sdram_configs[0];
+ if (sdram_params->base.dramtype == DDR3 ||
+ sdram_params->base.dramtype == DDR4) {
+ if (DDR_2T_INFO(gbl_info->info_2t))
+ sdram_params->pctl_regs.pctl[0][1] |= 0x1 << 10;
+ else
+ sdram_params->pctl_regs.pctl[0][1] &=
+ ~(0x1 << 10);
+ }
+ ret = sdram_init_detect(&dram_info, sdram_params);
+ if (ret) {
+ sdram_print_dram_type(sdram_params->base.dramtype);
+ printascii(", ");
+ printdec(sdram_params->base.ddr_freq);
+ printascii("MHz\n");
+ goto error;
+ }
+ print_ddr_info(sdram_params);
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+ init_rw_trn_result_struct(&rw_trn_result, dram_info.phy,
+ (u8)sdram_params->ch.cap_info.rank);
+#endif
+
+ ddr_set_rate_for_fsp(&dram_info, sdram_params);
+ copy_fsp_param_to_ddr();
+
+#if defined(CONFIG_CMD_DDR_TEST_TOOL)
+ save_rw_trn_result_to_ddr(&rw_trn_result);
+#endif
+
+ if (IS_ENABLED(CONFIG_RAM_ROCKCHIP_DEBUG))
+ printascii("out\n");
+
+ return ret;
+error:
+ printascii("error\n");
+ return (-1);
+}
+
+#endif
+
+static int rv1126_dmc_probe(struct udevice *dev)
+{
+#if defined(CONFIG_TPL_BUILD) || \
+ (!defined(CONFIG_TPL) && defined(CONFIG_SPL_BUILD))
+ if (rv1126_dmc_init(dev))
+ return 0;
+#else
+ struct dram_info *priv = dev_get_priv(dev);
+
+ priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+ debug("%s: grf=%p\n", __func__, priv->pmugrf);
+ priv->info.base = CFG_SYS_SDRAM_BASE;
+ priv->info.size =
+ rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]);
+#endif
+ return 0;
+}
+
+static int rv1126_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct dram_info *priv = dev_get_priv(dev);
+
+ *info = priv->info;
+
+ return 0;
+}
+
+static struct ram_ops rv1126_dmc_ops = {
+ .get_info = rv1126_dmc_get_info,
+};
+
+static const struct udevice_id rv1126_dmc_ids[] = {
+ { .compatible = "rockchip,rv1126-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(dmc_rv1126) = {
+ .name = "rockchip_rv1126_dmc",
+ .id = UCLASS_RAM,
+ .of_match = rv1126_dmc_ids,
+ .ops = &rv1126_dmc_ops,
+ .probe = rv1126_dmc_probe,
+ .priv_auto = sizeof(struct dram_info),
+};
diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c
index 810a03d54960..9cab27f2e48b 100644
--- a/drivers/timer/orion-timer.c
+++ b/drivers/timer/orion-timer.c
@@ -25,7 +25,8 @@ struct orion_timer_priv {
static bool early_init_done(void *base)
{
- if (readl(base + TIMER_CTRL) & TIMER0_EN)
+ if ((readl(base + TIMER_CTRL) & TIMER0_EN) &&
+ (readl(base + TIMER0_RELOAD) == ~0))
return true;
return false;
}
diff --git a/include/configs/neural-compute-module-2.h b/include/configs/neural-compute-module-2.h
new file mode 100644
index 000000000000..f0934ae00c7c
--- /dev/null
+++ b/include/configs/neural-compute-module-2.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#ifndef __NEURAL_COMPUTE_MODULE_2_H
+#define __NEURAL_COMPUTE_MODULE_2_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#include <configs/rv1126_common.h>
+
+#undef BOOT_TARGET_DEVICES
+
+#define BOOT_TARGET_DEVICES(func) \
+ func(MMC, mmc, 0) \
+ func(MMC, mmc, 1)
+
+#endif /* __NEURAL_COMPUTE_MODULE_2_H */
diff --git a/include/configs/pinephone-pro-rk3399.h b/include/configs/pinephone-pro-rk3399.h
new file mode 100644
index 000000000000..78017d6bcc37
--- /dev/null
+++ b/include/configs/pinephone-pro-rk3399.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd
+ * Copyright (C) 2022 Peter Robinson <pbrobinson at gmail.com>
+ */
+
+#ifndef __PINEPHONE_PRO_RK3399_H
+#define __PINEPHONE_PRO_RK3399_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+ "stdin=serial,usbkbd\0" \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#include <configs/rk3399_common.h>
+
+#define SDRAM_BANK_SIZE (2UL << 30)
+
+#endif
diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h
index 3f1595cdc95f..c0896e5f6281 100644
--- a/include/configs/px30_common.h
+++ b/include/configs/px30_common.h
@@ -8,8 +8,7 @@
#include "rockchip-common.h"
-/* FIXME: ff020000 is pmu_mem (10k), while ff0e0000 is regular int_mem */
-#define CFG_IRAM_BASE 0xff020000
+#define CFG_IRAM_BASE 0xff0e0000
#define GICD_BASE 0xff131000
#define GICC_BASE 0xff132000
diff --git a/include/configs/ringneck_px30.h b/include/configs/ringneck_px30.h
new file mode 100644
index 000000000000..c63c935e9aa8
--- /dev/null
+++ b/include/configs/ringneck_px30.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH
+ */
+
+#ifndef __RINGNECK_PX30_H
+#define __RINGNECK_PX30_H
+
+#include <configs/px30_common.h>
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+ "stdout=serial,vidconsole\0" \
+ "stderr=serial,vidconsole\0"
+
+#endif
diff --git a/include/configs/rv1126_common.h b/include/configs/rv1126_common.h
new file mode 100644
index 000000000000..1ec1640f99d0
--- /dev/null
+++ b/include/configs/rv1126_common.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2022 Edgeble AI Technologies Pvt. Ltd.
+ */
+
+#ifndef __CONFIG_RV1126_COMMON_H
+#define __CONFIG_RV1126_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CFG_SYS_HZ_CLOCK 24000000
+
+#define CFG_IRAM_BASE 0xff700000
+
+#define GICD_BASE 0xfeff1000
+#define GICC_BASE 0xfeff2000
+
+#define CFG_SYS_SDRAM_BASE 0
+#define SDRAM_MAX_SIZE 0xfd000000
+
+/* memory size > 128MB */
+#define ENV_MEM_LAYOUT_SETTINGS \
+ "scriptaddr=0x00000000\0" \
+ "pxefile_addr_r=0x00100000\0" \
+ "fdt_addr_r=0x08300000\0" \
+ "kernel_addr_r=0x02008000\0" \
+ "ramdisk_addr_r=0x0a200000\0"
+
+#include <config_distro_bootcmd.h>
+#define CFG_EXTRA_ENV_SETTINGS \
+ "fdt_high=0x0fffffff\0" \
+ "initrd_high=0x0fffffff\0" \
+ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
+ "partitions=" PARTS_DEFAULT \
+ ENV_MEM_LAYOUT_SETTINGS \
+ ROCKCHIP_DEVICE_SETTINGS \
+ BOOTENV
+
+#endif /* __CONFIG_RV1126_COMMON_H */
diff --git a/include/dt-bindings/clock/rockchip,rv1126-cru.h b/include/dt-bindings/clock/rockchip,rv1126-cru.h
new file mode 100644
index 000000000000..e89a3a5a4a34
--- /dev/null
+++ b/include/dt-bindings/clock/rockchip,rv1126-cru.h
@@ -0,0 +1,632 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Rockchip Electronics Co. Ltd.
+ * Author: Finley Xiao <finley.xiao@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RV1126_H
+
+/* pmucru-clocks indices */
+
+/* pll clocks */
+#define PLL_GPLL 1
+
+/* sclk (special clocks) */
+#define CLK_OSC0_DIV32K 2
+#define CLK_RTC32K 3
+#define CLK_WIFI_DIV 4
+#define CLK_WIFI_OSC0 5
+#define CLK_WIFI 6
+#define CLK_PMU 7
+#define SCLK_UART1_DIV 8
+#define SCLK_UART1_FRACDIV 9
+#define SCLK_UART1_MUX 10
+#define SCLK_UART1 11
+#define CLK_I2C0 12
+#define CLK_I2C2 13
+#define CLK_CAPTURE_PWM0 14
+#define CLK_PWM0 15
+#define CLK_CAPTURE_PWM1 16
+#define CLK_PWM1 17
+#define CLK_SPI0 18
+#define DBCLK_GPIO0 19
+#define CLK_PMUPVTM 20
+#define CLK_CORE_PMUPVTM 21
+#define CLK_REF12M 22
+#define CLK_USBPHY_OTG_REF 23
+#define CLK_USBPHY_HOST_REF 24
+#define CLK_REF24M 25
+#define CLK_MIPIDSIPHY_REF 26
+
+/* pclk */
+#define PCLK_PDPMU 30
+#define PCLK_PMU 31
+#define PCLK_UART1 32
+#define PCLK_I2C0 33
+#define PCLK_I2C2 34
+#define PCLK_PWM0 35
+#define PCLK_PWM1 36
+#define PCLK_SPI0 37
+#define PCLK_GPIO0 38
+#define PCLK_PMUSGRF 39
+#define PCLK_PMUGRF 40
+#define PCLK_PMUCRU 41
+#define PCLK_CHIPVEROTP 42
+#define PCLK_PDPMU_NIU 43
+#define PCLK_PMUPVTM 44
+#define PCLK_SCRKEYGEN 45
+
+#define CLKPMU_NR_CLKS (PCLK_SCRKEYGEN + 1)
+
+/* cru-clocks indices */
+
+/* pll clocks */
+#define PLL_APLL 1
+#define PLL_DPLL 2
+#define PLL_CPLL 3
+#define PLL_HPLL 4
+
+/* sclk (special clocks) */
+#define ARMCLK 5
+#define USB480M 6
+#define CLK_CORE_CPUPVTM 7
+#define CLK_CPUPVTM 8
+#define CLK_SCR1 9
+#define CLK_SCR1_CORE 10
+#define CLK_SCR1_RTC 11
+#define CLK_SCR1_JTAG 12
+#define SCLK_UART0_DIV 13
+#define SCLK_UART0_FRAC 14
+#define SCLK_UART0_MUX 15
+#define SCLK_UART0 16
+#define SCLK_UART2_DIV 17
+#define SCLK_UART2_FRAC 18
+#define SCLK_UART2_MUX 19
+#define SCLK_UART2 20
+#define SCLK_UART3_DIV 21
+#define SCLK_UART3_FRAC 22
+#define SCLK_UART3_MUX 23
+#define SCLK_UART3 24
+#define SCLK_UART4_DIV 25
+#define SCLK_UART4_FRAC 26
+#define SCLK_UART4_MUX 27
+#define SCLK_UART4 28
+#define SCLK_UART5_DIV 29
+#define SCLK_UART5_FRAC 30
+#define SCLK_UART5_MUX 31
+#define SCLK_UART5 32
+#define CLK_I2C1 33
+#define CLK_I2C3 34
+#define CLK_I2C4 35
+#define CLK_I2C5 36
+#define CLK_SPI1 37
+#define CLK_CAPTURE_PWM2 38
+#define CLK_PWM2 39
+#define DBCLK_GPIO1 40
+#define DBCLK_GPIO2 41
+#define DBCLK_GPIO3 42
+#define DBCLK_GPIO4 43
+#define CLK_SARADC 44
+#define CLK_TIMER0 45
+#define CLK_TIMER1 46
+#define CLK_TIMER2 47
+#define CLK_TIMER3 48
+#define CLK_TIMER4 49
+#define CLK_TIMER5 50
+#define CLK_CAN 51
+#define CLK_NPU_TSADC 52
+#define CLK_NPU_TSADCPHY 53
+#define CLK_CPU_TSADC 54
+#define CLK_CPU_TSADCPHY 55
+#define CLK_CRYPTO_CORE 56
+#define CLK_CRYPTO_PKA 57
+#define MCLK_I2S0_TX_DIV 58
+#define MCLK_I2S0_TX_FRACDIV 59
+#define MCLK_I2S0_TX_MUX 60
+#define MCLK_I2S0_TX 61
+#define MCLK_I2S0_RX_DIV 62
+#define MCLK_I2S0_RX_FRACDIV 63
+#define MCLK_I2S0_RX_MUX 64
+#define MCLK_I2S0_RX 65
+#define MCLK_I2S0_TX_OUT2IO 66
+#define MCLK_I2S0_RX_OUT2IO 67
+#define MCLK_I2S1_DIV 68
+#define MCLK_I2S1_FRACDIV 69
+#define MCLK_I2S1_MUX 70
+#define MCLK_I2S1 71
+#define MCLK_I2S1_OUT2IO 72
+#define MCLK_I2S2_DIV 73
+#define MCLK_I2S2_FRACDIV 74
+#define MCLK_I2S2_MUX 75
+#define MCLK_I2S2 76
+#define MCLK_I2S2_OUT2IO 77
+#define MCLK_PDM 78
+#define SCLK_ADUPWM_DIV 79
+#define SCLK_AUDPWM_FRACDIV 80
+#define SCLK_AUDPWM_MUX 81
+#define SCLK_AUDPWM 82
+#define CLK_ACDCDIG_ADC 83
+#define CLK_ACDCDIG_DAC 84
+#define CLK_ACDCDIG_I2C 85
+#define CLK_VENC_CORE 86
+#define CLK_VDEC_CORE 87
+#define CLK_VDEC_CA 88
+#define CLK_VDEC_HEVC_CA 89
+#define CLK_RGA_CORE 90
+#define CLK_IEP_CORE 91
+#define CLK_ISP_DIV 92
+#define CLK_ISP_NP5 93
+#define CLK_ISP_NUX 94
+#define CLK_ISP 95
+#define CLK_CIF_OUT_DIV 96
+#define CLK_CIF_OUT_FRACDIV 97
+#define CLK_CIF_OUT_MUX 98
+#define CLK_CIF_OUT 99
+#define CLK_MIPICSI_OUT_DIV 100
+#define CLK_MIPICSI_OUT_FRACDIV 101
+#define CLK_MIPICSI_OUT_MUX 102
+#define CLK_MIPICSI_OUT 103
+#define CLK_ISPP_DIV 104
+#define CLK_ISPP_NP5 105
+#define CLK_ISPP_NUX 106
+#define CLK_ISPP 107
+#define CLK_SDMMC 108
+#define SCLK_SDMMC_DRV 109
+#define SCLK_SDMMC_SAMPLE 110
+#define CLK_SDIO 111
+#define SCLK_SDIO_DRV 112
+#define SCLK_SDIO_SAMPLE 113
+#define CLK_EMMC 114
+#define SCLK_EMMC_DRV 115
+#define SCLK_EMMC_SAMPLE 116
+#define CLK_NANDC 117
+#define SCLK_SFC 118
+#define CLK_USBHOST_UTMI_OHCI 119
+#define CLK_USBOTG_REF 120
+#define CLK_GMAC_DIV 121
+#define CLK_GMAC_RGMII_M0 122
+#define CLK_GMAC_SRC_M0 123
+#define CLK_GMAC_RGMII_M1 124
+#define CLK_GMAC_SRC_M1 125
+#define CLK_GMAC_SRC 126
+#define CLK_GMAC_REF 127
+#define CLK_GMAC_TX_SRC 128
+#define CLK_GMAC_TX_DIV5 129
+#define CLK_GMAC_TX_DIV50 130
+#define RGMII_MODE_CLK 131
+#define CLK_GMAC_RX_SRC 132
+#define CLK_GMAC_RX_DIV2 133
+#define CLK_GMAC_RX_DIV20 134
+#define RMII_MODE_CLK 135
+#define CLK_GMAC_TX_RX 136
+#define CLK_GMAC_PTPREF 137
+#define CLK_GMAC_ETHERNET_OUT 138
+#define CLK_DDRPHY 139
+#define CLK_DDR_MON 140
+#define TMCLK_DDR_MON 141
+#define CLK_NPU_DIV 142
+#define CLK_NPU_NP5 143
+#define CLK_CORE_NPU 144
+#define CLK_CORE_NPUPVTM 145
+#define CLK_NPUPVTM 146
+#define SCLK_DDRCLK 147
+#define CLK_OTP 148
+
+/* dclk */
+#define DCLK_DECOM 150
+#define DCLK_VOP_DIV 151
+#define DCLK_VOP_FRACDIV 152
+#define DCLK_VOP_MUX 153
+#define DCLK_VOP 154
+#define DCLK_CIF 155
+#define DCLK_CIFLITE 156
+
+/* aclk */
+#define ACLK_PDBUS 160
+#define ACLK_DMAC 161
+#define ACLK_DCF 162
+#define ACLK_SPINLOCK 163
+#define ACLK_DECOM 164
+#define ACLK_PDCRYPTO 165
+#define ACLK_CRYPTO 166
+#define ACLK_PDVEPU 167
+#define ACLK_VENC 168
+#define ACLK_PDVDEC 169
+#define ACLK_PDJPEG 170
+#define ACLK_VDEC 171
+#define ACLK_JPEG 172
+#define ACLK_PDVO 173
+#define ACLK_RGA 174
+#define ACLK_VOP 175
+#define ACLK_IEP 176
+#define ACLK_PDVI_DIV 177
+#define ACLK_PDVI_NP5 178
+#define ACLK_PDVI 179
+#define ACLK_ISP 180
+#define ACLK_CIF 181
+#define ACLK_CIFLITE 182
+#define ACLK_PDISPP_DIV 183
+#define ACLK_PDISPP_NP5 184
+#define ACLK_PDISPP 185
+#define ACLK_ISPP 186
+#define ACLK_PDPHP 187
+#define ACLK_PDUSB 188
+#define ACLK_USBOTG 189
+#define ACLK_PDGMAC 190
+#define ACLK_GMAC 191
+#define ACLK_PDNPU_DIV 192
+#define ACLK_PDNPU_NP5 193
+#define ACLK_PDNPU 194
+#define ACLK_NPU 195
+
+/* hclk */
+#define HCLK_PDCORE_NIU 200
+#define HCLK_PDUSB 201
+#define HCLK_PDCRYPTO 202
+#define HCLK_CRYPTO 203
+#define HCLK_PDAUDIO 204
+#define HCLK_I2S0 205
+#define HCLK_I2S1 206
+#define HCLK_I2S2 207
+#define HCLK_PDM 208
+#define HCLK_AUDPWM 209
+#define HCLK_PDVEPU 210
+#define HCLK_VENC 211
+#define HCLK_PDVDEC 212
+#define HCLK_PDJPEG 213
+#define HCLK_VDEC 214
+#define HCLK_JPEG 215
+#define HCLK_PDVO 216
+#define HCLK_RGA 217
+#define HCLK_VOP 218
+#define HCLK_IEP 219
+#define HCLK_PDVI 220
+#define HCLK_ISP 221
+#define HCLK_CIF 222
+#define HCLK_CIFLITE 223
+#define HCLK_PDISPP 224
+#define HCLK_ISPP 225
+#define HCLK_PDPHP 226
+#define HCLK_PDSDMMC 227
+#define HCLK_SDMMC 228
+#define HCLK_PDSDIO 229
+#define HCLK_SDIO 230
+#define HCLK_PDNVM 231
+#define HCLK_EMMC 232
+#define HCLK_NANDC 233
+#define HCLK_SFC 234
+#define HCLK_SFCXIP 235
+#define HCLK_PDBUS 236
+#define HCLK_USBHOST 237
+#define HCLK_USBHOST_ARB 238
+#define HCLK_PDNPU 239
+#define HCLK_NPU 240
+
+/* pclk */
+#define PCLK_CPUPVTM 245
+#define PCLK_PDBUS 246
+#define PCLK_DCF 247
+#define PCLK_WDT 248
+#define PCLK_MAILBOX 249
+#define PCLK_UART0 250
+#define PCLK_UART2 251
+#define PCLK_UART3 252
+#define PCLK_UART4 253
+#define PCLK_UART5 254
+#define PCLK_I2C1 255
+#define PCLK_I2C3 256
+#define PCLK_I2C4 257
+#define PCLK_I2C5 258
+#define PCLK_SPI1 259
+#define PCLK_PWM2 261
+#define PCLK_GPIO1 262
+#define PCLK_GPIO2 263
+#define PCLK_GPIO3 264
+#define PCLK_GPIO4 265
+#define PCLK_SARADC 266
+#define PCLK_TIMER 267
+#define PCLK_DECOM 268
+#define PCLK_CAN 269
+#define PCLK_NPU_TSADC 270
+#define PCLK_CPU_TSADC 271
+#define PCLK_ACDCDIG 272
+#define PCLK_PDVO 273
+#define PCLK_DSIHOST 274
+#define PCLK_PDVI 275
+#define PCLK_CSIHOST 276
+#define PCLK_PDGMAC 277
+#define PCLK_GMAC 278
+#define PCLK_PDDDR 279
+#define PCLK_DDR_MON 280
+#define PCLK_PDNPU 281
+#define PCLK_NPUPVTM 282
+#define PCLK_PDTOP 283
+#define PCLK_TOPCRU 284
+#define PCLK_TOPGRF 285
+#define PCLK_CPUEMADET 286
+#define PCLK_DDRPHY 287
+#define PCLK_DSIPHY 289
+#define PCLK_CSIPHY0 290
+#define PCLK_CSIPHY1 291
+#define PCLK_USBPHY_HOST 292
+#define PCLK_USBPHY_OTG 293
+#define PCLK_OTP 294
+
+#define CLK_NR_CLKS (PCLK_OTP + 1)
+
+/* pmu soft-reset indices */
+
+/* pmu_cru_softrst_con0 */
+#define SRST_PDPMU_NIU_P 0
+#define SRST_PMU_SGRF_P 1
+#define SRST_PMU_SGRF_REMAP_P 2
+#define SRST_I2C0_P 3
+#define SRST_I2C0 4
+#define SRST_I2C2_P 7
+#define SRST_I2C2 8
+#define SRST_UART1_P 9
+#define SRST_UART1 10
+#define SRST_PWM0_P 11
+#define SRST_PWM0 12
+#define SRST_PWM1_P 13
+#define SRST_PWM1 14
+#define SRST_DDR_FAIL_SAFE 15
+
+/* pmu_cru_softrst_con1 */
+#define SRST_GPIO0_P 17
+#define SRST_GPIO0_DB 18
+#define SRST_SPI0_P 19
+#define SRST_SPI0 20
+#define SRST_PMUGRF_P 21
+#define SRST_CHIPVEROTP_P 22
+#define SRST_PMUPVTM 24
+#define SRST_PMUPVTM_P 25
+#define SRST_PMUCRU_P 30
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_CORE0_PO 0
+#define SRST_CORE1_PO 1
+#define SRST_CORE2_PO 2
+#define SRST_CORE3_PO 3
+#define SRST_CORE0 4
+#define SRST_CORE1 5
+#define SRST_CORE2 6
+#define SRST_CORE3 7
+#define SRST_CORE0_DBG 8
+#define SRST_CORE1_DBG 9
+#define SRST_CORE2_DBG 10
+#define SRST_CORE3_DBG 11
+#define SRST_NL2 12
+#define SRST_CORE_NIU_A 13
+#define SRST_DBG_DAPLITE_P 14
+#define SRST_DAPLITE_P 15
+
+/* cru_softrst_con1 */
+#define SRST_PDBUS_NIU1_A 16
+#define SRST_PDBUS_NIU1_H 17
+#define SRST_PDBUS_NIU1_P 18
+#define SRST_PDBUS_NIU2_A 19
+#define SRST_PDBUS_NIU2_H 20
+#define SRST_PDBUS_NIU3_A 21
+#define SRST_PDBUS_NIU3_H 22
+#define SRST_PDBUS_HOLD_NIU1_A 23
+#define SRST_DBG_NIU_P 24
+#define SRST_PDCORE_NIIU_H 25
+#define SRST_MUC_NIU 26
+#define SRST_DCF_A 29
+#define SRST_DCF_P 30
+#define SRST_SYSTEM_SRAM_A 31
+
+/* cru_softrst_con2 */
+#define SRST_I2C1_P 32
+#define SRST_I2C1 33
+#define SRST_I2C3_P 34
+#define SRST_I2C3 35
+#define SRST_I2C4_P 36
+#define SRST_I2C4 37
+#define SRST_I2C5_P 38
+#define SRST_I2C5 39
+#define SRST_SPI1_P 40
+#define SRST_SPI1 41
+#define SRST_MCU_CORE 42
+#define SRST_PWM2_P 44
+#define SRST_PWM2 45
+#define SRST_SPINLOCK_A 46
+
+/* cru_softrst_con3 */
+#define SRST_UART0_P 48
+#define SRST_UART0 49
+#define SRST_UART2_P 50
+#define SRST_UART2 51
+#define SRST_UART3_P 52
+#define SRST_UART3 53
+#define SRST_UART4_P 54
+#define SRST_UART4 55
+#define SRST_UART5_P 56
+#define SRST_UART5 57
+#define SRST_WDT_P 58
+#define SRST_SARADC_P 59
+#define SRST_GRF_P 61
+#define SRST_TIMER_P 62
+#define SRST_MAILBOX_P 63
+
+/* cru_softrst_con4 */
+#define SRST_TIMER0 64
+#define SRST_TIMER1 65
+#define SRST_TIMER2 66
+#define SRST_TIMER3 67
+#define SRST_TIMER4 68
+#define SRST_TIMER5 69
+#define SRST_INTMUX_P 70
+#define SRST_GPIO1_P 72
+#define SRST_GPIO1_DB 73
+#define SRST_GPIO2_P 74
+#define SRST_GPIO2_DB 75
+#define SRST_GPIO3_P 76
+#define SRST_GPIO3_DB 77
+#define SRST_GPIO4_P 78
+#define SRST_GPIO4_DB 79
+
+/* cru_softrst_con5 */
+#define SRST_CAN_P 80
+#define SRST_CAN 81
+#define SRST_DECOM_A 85
+#define SRST_DECOM_P 86
+#define SRST_DECOM_D 87
+#define SRST_PDCRYPTO_NIU_A 88
+#define SRST_PDCRYPTO_NIU_H 89
+#define SRST_CRYPTO_A 90
+#define SRST_CRYPTO_H 91
+#define SRST_CRYPTO_CORE 92
+#define SRST_CRYPTO_PKA 93
+#define SRST_SGRF_P 95
+
+/* cru_softrst_con6 */
+#define SRST_PDAUDIO_NIU_H 96
+#define SRST_PDAUDIO_NIU_P 97
+#define SRST_I2S0_H 98
+#define SRST_I2S0_TX_M 99
+#define SRST_I2S0_RX_M 100
+#define SRST_I2S1_H 101
+#define SRST_I2S1_M 102
+#define SRST_I2S2_H 103
+#define SRST_I2S2_M 104
+#define SRST_PDM_H 105
+#define SRST_PDM_M 106
+#define SRST_AUDPWM_H 107
+#define SRST_AUDPWM 108
+#define SRST_ACDCDIG_P 109
+#define SRST_ACDCDIG 110
+
+/* cru_softrst_con7 */
+#define SRST_PDVEPU_NIU_A 112
+#define SRST_PDVEPU_NIU_H 113
+#define SRST_VENC_A 114
+#define SRST_VENC_H 115
+#define SRST_VENC_CORE 116
+#define SRST_PDVDEC_NIU_A 117
+#define SRST_PDVDEC_NIU_H 118
+#define SRST_VDEC_A 119
+#define SRST_VDEC_H 120
+#define SRST_VDEC_CORE 121
+#define SRST_VDEC_CA 122
+#define SRST_VDEC_HEVC_CA 123
+#define SRST_PDJPEG_NIU_A 124
+#define SRST_PDJPEG_NIU_H 125
+#define SRST_JPEG_A 126
+#define SRST_JPEG_H 127
+
+/* cru_softrst_con8 */
+#define SRST_PDVO_NIU_A 128
+#define SRST_PDVO_NIU_H 129
+#define SRST_PDVO_NIU_P 130
+#define SRST_RGA_A 131
+#define SRST_RGA_H 132
+#define SRST_RGA_CORE 133
+#define SRST_VOP_A 134
+#define SRST_VOP_H 135
+#define SRST_VOP_D 136
+#define SRST_TXBYTEHS_DSIHOST 137
+#define SRST_DSIHOST_P 138
+#define SRST_IEP_A 139
+#define SRST_IEP_H 140
+#define SRST_IEP_CORE 141
+#define SRST_ISP_RX_P 142
+
+/* cru_softrst_con9 */
+#define SRST_PDVI_NIU_A 144
+#define SRST_PDVI_NIU_H 145
+#define SRST_PDVI_NIU_P 146
+#define SRST_ISP 147
+#define SRST_CIF_A 148
+#define SRST_CIF_H 149
+#define SRST_CIF_D 150
+#define SRST_CIF_P 151
+#define SRST_CIF_I 152
+#define SRST_CIF_RX_P 153
+#define SRST_PDISPP_NIU_A 154
+#define SRST_PDISPP_NIU_H 155
+#define SRST_ISPP_A 156
+#define SRST_ISPP_H 157
+#define SRST_ISPP 158
+#define SRST_CSIHOST_P 159
+
+/* cru_softrst_con10 */
+#define SRST_PDPHPMID_NIU_A 160
+#define SRST_PDPHPMID_NIU_H 161
+#define SRST_PDNVM_NIU_H 163
+#define SRST_SDMMC_H 164
+#define SRST_SDIO_H 165
+#define SRST_EMMC_H 166
+#define SRST_SFC_H 167
+#define SRST_SFCXIP_H 168
+#define SRST_SFC 169
+#define SRST_NANDC_H 170
+#define SRST_NANDC 171
+#define SRST_PDSDMMC_H 173
+#define SRST_PDSDIO_H 174
+
+/* cru_softrst_con11 */
+#define SRST_PDUSB_NIU_A 176
+#define SRST_PDUSB_NIU_H 177
+#define SRST_USBHOST_H 178
+#define SRST_USBHOST_ARB_H 179
+#define SRST_USBHOST_UTMI 180
+#define SRST_USBOTG_A 181
+#define SRST_USBPHY_OTG_P 182
+#define SRST_USBPHY_HOST_P 183
+#define SRST_USBPHYPOR_OTG 184
+#define SRST_USBPHYPOR_HOST 185
+#define SRST_PDGMAC_NIU_A 188
+#define SRST_PDGMAC_NIU_P 189
+#define SRST_GMAC_A 190
+
+/* cru_softrst_con12 */
+#define SRST_DDR_DFICTL_P 193
+#define SRST_DDR_MON_P 194
+#define SRST_DDR_STANDBY_P 195
+#define SRST_DDR_GRF_P 196
+#define SRST_DDR_MSCH_P 197
+#define SRST_DDR_SPLIT_A 198
+#define SRST_DDR_MSCH 199
+#define SRST_DDR_DFICTL 202
+#define SRST_DDR_STANDBY 203
+#define SRST_NPUMCU_NIU 205
+#define SRST_DDRPHY_P 206
+#define SRST_DDRPHY 207
+
+/* cru_softrst_con13 */
+#define SRST_PDNPU_NIU_A 208
+#define SRST_PDNPU_NIU_H 209
+#define SRST_PDNPU_NIU_P 210
+#define SRST_NPU_A 211
+#define SRST_NPU_H 212
+#define SRST_NPU 213
+#define SRST_NPUPVTM_P 214
+#define SRST_NPUPVTM 215
+#define SRST_NPU_TSADC_P 216
+#define SRST_NPU_TSADC 217
+#define SRST_NPU_TSADCPHY 218
+#define SRST_CIFLITE_A 220
+#define SRST_CIFLITE_H 221
+#define SRST_CIFLITE_D 222
+#define SRST_CIFLITE_RX_P 223
+
+/* cru_softrst_con14 */
+#define SRST_TOPNIU_P 224
+#define SRST_TOPCRU_P 225
+#define SRST_TOPGRF_P 226
+#define SRST_CPUEMADET_P 227
+#define SRST_CSIPHY0_P 228
+#define SRST_CSIPHY1_P 229
+#define SRST_DSIPHY_P 230
+#define SRST_CPU_TSADC_P 232
+#define SRST_CPU_TSADC 233
+#define SRST_CPU_TSADCPHY 234
+#define SRST_CPUPVTM_P 235
+#define SRST_CPUPVTM 236
+
+#endif
diff --git a/include/dt-bindings/power/rockchip,rv1126-power.h b/include/dt-bindings/power/rockchip,rv1126-power.h
new file mode 100644
index 000000000000..38a68e000d38
--- /dev/null
+++ b/include/dt-bindings/power/rockchip,rv1126-power.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __DT_BINDINGS_POWER_RV1126_POWER_H__
+#define __DT_BINDINGS_POWER_RV1126_POWER_H__
+
+/* VD_CORE */
+#define RV1126_PD_CPU_0 0
+#define RV1126_PD_CPU_1 1
+#define RV1126_PD_CPU_2 2
+#define RV1126_PD_CPU_3 3
+#define RV1126_PD_CORE_ALIVE 4
+
+/* VD_PMU */
+#define RV1126_PD_PMU 5
+#define RV1126_PD_PMU_ALIVE 6
+
+/* VD_NPU */
+#define RV1126_PD_NPU 7
+
+/* VD_VEPU */
+#define RV1126_PD_VEPU 8
+
+/* VD_LOGIC */
+#define RV1126_PD_VI 9
+#define RV1126_PD_VO 10
+#define RV1126_PD_ISPP 11
+#define RV1126_PD_VDPU 12
+#define RV1126_PD_CRYPTO 13
+#define RV1126_PD_DDR 14
+#define RV1126_PD_NVM 15
+#define RV1126_PD_SDIO 16
+#define RV1126_PD_USB 17
+#define RV1126_PD_LOGIC_ALIVE 18
+
+#endif
diff --git a/include/rc4.h b/include/rc4.h
index c1ff1349d4b8..d1257f20a44c 100644
--- a/include/rc4.h
+++ b/include/rc4.h
@@ -15,6 +15,6 @@
* @len: Length of buffer in bytes
* @key: 16-byte key to use
*/
-void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16]);
+void rc4_encode(unsigned char *buf, unsigned int len, const unsigned char key[16]);
#endif
diff --git a/lib/rc4.c b/lib/rc4.c
index 0c0043984361..720112d1fd8e 100644
--- a/lib/rc4.c
+++ b/lib/rc4.c
@@ -12,7 +12,7 @@
#endif
#include <rc4.h>
-void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16])
+void rc4_encode(unsigned char *buf, unsigned int len, const unsigned char key[16])
{
unsigned char s[256], k[256], temp;
unsigned short i, j, t;
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 0db45c2d41cb..1f1eaa16752b 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -133,6 +133,7 @@ static struct spl_info spl_infos[] = {
{ "rk3368", "RK33", 0x8000 - 0x1000, false, RK_HEADER_V1 },
{ "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 },
{ "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 },
+ { "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 },
{ "rk3568", "RK35", 0x14000 - 0x1000, false, RK_HEADER_V2 },
};
@@ -154,7 +155,7 @@ struct spl_params {
static struct spl_params spl_params = { 0 };
-static unsigned char rc4_key[16] = {
+static const unsigned char rc4_key[16] = {
124, 78, 3, 4, 85, 5, 9, 7,
45, 44, 123, 56, 23, 13, 23, 17
};