From fdda7901cc77b5bc525263c385cc19f151b6612b Mon Sep 17 00:00:00 2001
From: Haolin Li
Date: Tue, 22 Mar 2022 05:58:02 -0700
Subject: [PATCH 01/48] mmc: rockchip_sdhci: Correct error checking
A pointer can not be negative. Use macro IS_ERR_OR_NULL() for checking.
Signed-off-by: Haolin Li
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
Reviewed-by: Jaehoon Chung
---
drivers/mmc/rockchip_sdhci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 1fdc8415178..9608770d4ec 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -227,7 +227,7 @@ static int rk3399_emmc_get_phy(struct udevice *dev)
}
grf_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
- if (grf_base < 0) {
+ if (IS_ERR_OR_NULL(grf_base)) {
printf("%s Get syscon grf failed", __func__);
return -ENODEV;
}
From e963228af50d317a83d4ceffb095e40ef3ab9d53 Mon Sep 17 00:00:00 2001
From: Peter Cai
Date: Fri, 4 Feb 2022 15:16:06 -0500
Subject: [PATCH 02/48] adc: rockchip-saradc: add support for getting reference
voltage value
Mirroring commit 97ab802aa36f ("adc: meson-saradc: add support for
getting reference voltage value") for meson-saradc, this adds support
for getting the "vref-supply" regulator and register it as the ADC's
reference voltage regulator, so clients can translate sampled ADC values
to voltage.
Signed-off-by: Peter Cai
Reviewed-by: John Keeping
Tested-by: John Keeping
Cc: Simon Glass
Cc: Philipp Tomsich
Cc: Kever Yang
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
drivers/adc/rockchip-saradc.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/drivers/adc/rockchip-saradc.c b/drivers/adc/rockchip-saradc.c
index e0cbab6aa06..760f8fe6280 100644
--- a/drivers/adc/rockchip-saradc.c
+++ b/drivers/adc/rockchip-saradc.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#define SARADC_CTRL_CHN_MASK GENMASK(2, 0)
#define SARADC_CTRL_POWER_CTRL BIT(3)
@@ -100,8 +101,11 @@ int rockchip_saradc_stop(struct udevice *dev)
int rockchip_saradc_probe(struct udevice *dev)
{
+ struct adc_uclass_plat *uc_pdata = dev_get_uclass_plat(dev);
struct rockchip_saradc_priv *priv = dev_get_priv(dev);
+ struct udevice *vref;
struct clk clk;
+ int vref_uv;
int ret;
ret = clk_get_by_index(dev, 0, &clk);
@@ -114,6 +118,23 @@ int rockchip_saradc_probe(struct udevice *dev)
priv->active_channel = -1;
+ ret = device_get_supply_regulator(dev, "vref-supply", &vref);
+ if (ret) {
+ printf("can't get vref-supply: %d\n", ret);
+ return ret;
+ }
+
+ vref_uv = regulator_get_value(vref);
+ if (vref_uv < 0) {
+ printf("can't get vref-supply value: %d\n", vref_uv);
+ return vref_uv;
+ }
+
+ /* VDD supplied by common vref pin */
+ uc_pdata->vdd_supply = vref;
+ uc_pdata->vdd_microvolts = vref_uv;
+ uc_pdata->vss_microvolts = 0;
+
return 0;
}
From f0d49d4f0dba4bd3dc4810dbfc48e315afe023fc Mon Sep 17 00:00:00 2001
From: Chris Morgan
Date: Fri, 25 Mar 2022 10:40:35 -0500
Subject: [PATCH 03/48] spi: rockchip_sfc: Add missing include for
dm/device_compat.h
Add missing include for dm/device_compat.h. Without this include the
SFC driver fails to compile because dev_err and dev_dbg are not
defined.
Signed-off-by: Chris Morgan
Reviewed-by: Kever Yang
---
drivers/spi/rockchip_sfc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c
index e098addddca..851a6482985 100644
--- a/drivers/spi/rockchip_sfc.c
+++ b/drivers/spi/rockchip_sfc.c
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
#include
#include
#include
From 0abb5b0426e5c20bdbb5748196569a2b5533d711 Mon Sep 17 00:00:00 2001
From: Chris Morgan
Date: Fri, 25 Mar 2022 12:09:22 -0500
Subject: [PATCH 04/48] rockchip: clk: add clocks to px30_clk_enable
Add the HCLK_OTG, HCLK_SFC, and SCLK_SFC clocks to px30_clk_enable.
Without this change U-Boot reports an error of "Enable
clock-controller@ff2b0000 failed" on boot when using the SFC or USB in
U-Boot.
Signed-off-by: Chris Morgan
Reviewed-by: Kever Yang
---
drivers/clk/rockchip/clk_px30.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c
index ea874e3f4b9..5d467447a17 100644
--- a/drivers/clk/rockchip/clk_px30.c
+++ b/drivers/clk/rockchip/clk_px30.c
@@ -1403,10 +1403,13 @@ static int px30_clk_enable(struct clk *clk)
{
switch (clk->id) {
case HCLK_HOST:
+ case HCLK_OTG:
+ case HCLK_SFC:
case SCLK_GMAC:
case SCLK_GMAC_RX_TX:
case SCLK_MAC_REF:
case SCLK_MAC_REFOUT:
+ case SCLK_SFC:
case ACLK_GMAC:
case PCLK_GMAC:
case SCLK_GMAC_RMII:
From 48cd7a1f6ccb7d971460e95a2b6c053d6e2a28d1 Mon Sep 17 00:00:00 2001
From: Vagrant Cascadian
Date: Wed, 6 Apr 2022 13:42:03 -0700
Subject: [PATCH 05/48] rockchip: Enable SCSI in distro bootcmd for rk3399.
Include SCSI in the list of boot targets if CONFIG_CMD_SCSI is
enabled.
Signed-off-by: Vagrant Cascadian
Reviewed-by: Kever Yang
---
include/configs/rockchip-common.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
index ba7061a287c..0c08776ae26 100644
--- a/include/configs/rockchip-common.h
+++ b/include/configs/rockchip-common.h
@@ -29,6 +29,12 @@
#define BOOT_TARGET_NVME(func)
#endif
+#if CONFIG_IS_ENABLED(CMD_SCSI)
+ #define BOOT_TARGET_SCSI(func) func(SCSI, scsi, 0)
+#else
+ #define BOOT_TARGET_SCSI(func)
+#endif
+
#if CONFIG_IS_ENABLED(CMD_USB)
#define BOOT_TARGET_USB(func) func(USB, usb, 0)
#else
@@ -57,6 +63,7 @@
#define BOOT_TARGET_DEVICES(func) \
BOOT_TARGET_MMC(func) \
BOOT_TARGET_NVME(func) \
+ BOOT_TARGET_SCSI(func) \
BOOT_TARGET_USB(func) \
BOOT_TARGET_PXE(func) \
BOOT_TARGET_DHCP(func) \
From 60be6e0860e3f7ea644c70f3342861be7cef8b8f Mon Sep 17 00:00:00 2001
From: Vagrant Cascadian
Date: Wed, 6 Apr 2022 13:42:04 -0700
Subject: [PATCH 06/48] rockchip: Enable AHCI/SCSI/SATA on rockpro64-rk3399.
Add options to enable AHCI, SCSI and SATA.
Signed-off-by: Vagrant Cascadian
Reviewed-by: Kever Yang
---
configs/rockpro64-rk3399_defconfig | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig
index dc9f5f2ac66..f44d15ebec9 100644
--- a/configs/rockpro64-rk3399_defconfig
+++ b/configs/rockpro64-rk3399_defconfig
@@ -28,6 +28,13 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
+CONFIG_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_SATA=y
+CONFIG_SATA_SIL=y
+CONFIG_SCSI=y
+CONFIG_SCSI_AHCI=y
+CONFIG_DM_SCSI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIME=y
CONFIG_SPL_OF_CONTROL=y
From 54562045e5937e724ae574f02bdb040338d258be Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:02 +0200
Subject: [PATCH 07/48] rockchip: move ROCKCHIP_STIMER_BASE to Kconfig
Move ROCKCHIP_STIMER_BASE to Kconfig.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/mach-rockchip/Kconfig | 10 ++++++++++
arch/arm/mach-rockchip/px30/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3036/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3128/Kconfig | 3 +++
arch/arm/mach-rockchip/rk322x/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3288/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3308/Kconfig | 10 ++++++----
arch/arm/mach-rockchip/rk3328/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3368/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3399/Kconfig | 3 +++
arch/arm/mach-rockchip/rk3568/Kconfig | 3 +++
configs/rock_defconfig | 1 +
include/configs/px30_common.h | 1 -
include/configs/rk3036_common.h | 1 -
include/configs/rk3128_common.h | 1 -
include/configs/rk322x_common.h | 1 -
include/configs/rk3288_common.h | 1 -
include/configs/rk3308_common.h | 1 -
include/configs/rk3328_common.h | 1 -
include/configs/rk3368_common.h | 1 -
include/configs/rk3399_common.h | 1 -
include/configs/rk3568_common.h | 1 -
22 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 308dc09b038..811964973ae 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -339,6 +339,16 @@ config ROCKCHIP_BOOT_MODE_REG
The Soc will enter to different boot mode(defined in asm/arch-rockchip/boot_mode.h)
according to the value from this register.
+config ROCKCHIP_STIMER
+ bool "Rockchip STIMER support"
+ default y
+ help
+ Enable Rockchip STIMER support.
+
+config ROCKCHIP_STIMER_BASE
+ hex
+ depends on ROCKCHIP_STIMER
+
config ROCKCHIP_SPL_RESERVE_IRAM
hex "Size of IRAM reserved in SPL"
default 0
diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig
index 145bf3591ff..4886fe946e3 100644
--- a/arch/arm/mach-rockchip/px30/Kconfig
+++ b/arch/arm/mach-rockchip/px30/Kconfig
@@ -38,6 +38,9 @@ config TARGET_PX30_CORE
config ROCKCHIP_BOOT_MODE_REG
default 0xff010200
+config ROCKCHIP_STIMER_BASE
+ default 0xff220020
+
config SYS_SOC
default "px30"
diff --git a/arch/arm/mach-rockchip/rk3036/Kconfig b/arch/arm/mach-rockchip/rk3036/Kconfig
index b746795d813..111531be1ef 100644
--- a/arch/arm/mach-rockchip/rk3036/Kconfig
+++ b/arch/arm/mach-rockchip/rk3036/Kconfig
@@ -16,6 +16,9 @@ endchoice
config ROCKCHIP_BOOT_MODE_REG
default 0x200081c8
+config ROCKCHIP_STIMER_BASE
+ default 0x200440a0
+
config SYS_SOC
default "rk3036"
diff --git a/arch/arm/mach-rockchip/rk3128/Kconfig b/arch/arm/mach-rockchip/rk3128/Kconfig
index b867401c7f5..9cc494eb409 100644
--- a/arch/arm/mach-rockchip/rk3128/Kconfig
+++ b/arch/arm/mach-rockchip/rk3128/Kconfig
@@ -16,6 +16,9 @@ endchoice
config ROCKCHIP_BOOT_MODE_REG
default 0x100a0038
+config ROCKCHIP_STIMER_BASE
+ default 0x200440a0
+
config SYS_SOC
default "rk3128"
diff --git a/arch/arm/mach-rockchip/rk322x/Kconfig b/arch/arm/mach-rockchip/rk322x/Kconfig
index 6458cd55814..058f848ddc7 100644
--- a/arch/arm/mach-rockchip/rk322x/Kconfig
+++ b/arch/arm/mach-rockchip/rk322x/Kconfig
@@ -8,6 +8,9 @@ config TARGET_EVB_RK3229
config ROCKCHIP_BOOT_MODE_REG
default 0x110005c8
+config ROCKCHIP_STIMER_BASE
+ default 0x110d0020
+
config SYS_SOC
default "rk322x"
diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
index f37b1bdfd50..dd8c7826fc1 100644
--- a/arch/arm/mach-rockchip/rk3288/Kconfig
+++ b/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -148,6 +148,9 @@ config ROCKCHIP_FAST_SPL
config ROCKCHIP_BOOT_MODE_REG
default 0xff730094
+config ROCKCHIP_STIMER_BASE
+ default 0xff810020
+
config SYS_SOC
default "rk3288"
diff --git a/arch/arm/mach-rockchip/rk3308/Kconfig b/arch/arm/mach-rockchip/rk3308/Kconfig
index 8fa536e15dc..194353e4cd9 100644
--- a/arch/arm/mach-rockchip/rk3308/Kconfig
+++ b/arch/arm/mach-rockchip/rk3308/Kconfig
@@ -8,6 +8,12 @@ config TARGET_ROC_RK3308_CC
bool "Firefly roc-rk3308-cc"
select BOARD_LATE_INIT
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff000500
+
+config ROCKCHIP_STIMER_BASE
+ default 0xff1b00a0
+
config SYS_SOC
default "rk3308"
@@ -17,10 +23,6 @@ config SYS_MALLOC_F_LEN
config SPL_SERIAL
default y
-config ROCKCHIP_BOOT_MODE_REG
- default 0xff000500
-
-
source "board/rockchip/evb_rk3308/Kconfig"
source "board/firefly/firefly-rk3308/Kconfig"
diff --git a/arch/arm/mach-rockchip/rk3328/Kconfig b/arch/arm/mach-rockchip/rk3328/Kconfig
index d13a1690226..f6f1e06a83f 100644
--- a/arch/arm/mach-rockchip/rk3328/Kconfig
+++ b/arch/arm/mach-rockchip/rk3328/Kconfig
@@ -15,6 +15,9 @@ endchoice
config ROCKCHIP_BOOT_MODE_REG
default 0xff1005c8
+config ROCKCHIP_STIMER_BASE
+ default 0xff1d0020
+
config SYS_SOC
default "rk3328"
diff --git a/arch/arm/mach-rockchip/rk3368/Kconfig b/arch/arm/mach-rockchip/rk3368/Kconfig
index 78eb96df3d1..104db36737b 100644
--- a/arch/arm/mach-rockchip/rk3368/Kconfig
+++ b/arch/arm/mach-rockchip/rk3368/Kconfig
@@ -45,6 +45,9 @@ endchoice
config ROCKCHIP_BOOT_MODE_REG
default 0xff738200
+config ROCKCHIP_STIMER_BASE
+ default 0xff830020
+
config SYS_SOC
default "rk3368"
diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig
index 0833e083d9e..c1f251316cb 100644
--- a/arch/arm/mach-rockchip/rk3399/Kconfig
+++ b/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -125,6 +125,9 @@ endchoice
config ROCKCHIP_BOOT_MODE_REG
default 0xff320300
+config ROCKCHIP_STIMER_BASE
+ default 0xff8680a0
+
config SYS_SOC
default "rk3399"
diff --git a/arch/arm/mach-rockchip/rk3568/Kconfig b/arch/arm/mach-rockchip/rk3568/Kconfig
index 201c63c2a9c..4e7c02cce06 100644
--- a/arch/arm/mach-rockchip/rk3568/Kconfig
+++ b/arch/arm/mach-rockchip/rk3568/Kconfig
@@ -9,6 +9,9 @@ config TARGET_EVB_RK3568
config ROCKCHIP_BOOT_MODE_REG
default 0xfdc20200
+config ROCKCHIP_STIMER_BASE
+ default 0xfdd1c020
+
config SYS_SOC
default "rk3568"
diff --git a/configs/rock_defconfig b/configs/rock_defconfig
index 290f5afd787..4aa4608f904 100644
--- a/configs/rock_defconfig
+++ b/configs/rock_defconfig
@@ -11,6 +11,7 @@ CONFIG_ENV_OFFSET=0x3F8000
CONFIG_DEFAULT_DEVICE_TREE="rk3188-radxarock"
CONFIG_SPL_TEXT_BASE=0x10080800
CONFIG_ROCKCHIP_RK3188=y
+# CONFIG_ROCKCHIP_STIMER is not set
CONFIG_TARGET_ROCK=y
CONFIG_SPL_STACK_R_ADDR=0x60080000
CONFIG_DEBUG_UART_BASE=0x20064000
diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h
index 09923871571..dc609013f32 100644
--- a/include/configs/px30_common.h
+++ b/include/configs/px30_common.h
@@ -12,7 +12,6 @@
#define CONFIG_SYS_NS16550_MEM32
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xff220020
#define COUNTER_FREQUENCY 24000000
/* FIXME: ff020000 is pmu_mem (10k), while ff0e0000 is regular int_mem */
diff --git a/include/configs/rk3036_common.h b/include/configs/rk3036_common.h
index 00c453d739d..5905518edf1 100644
--- a/include/configs/rk3036_common.h
+++ b/include/configs/rk3036_common.h
@@ -10,7 +10,6 @@
#define CONFIG_SYS_CBSIZE 1024
-#define CONFIG_ROCKCHIP_STIMER_BASE 0x200440a0
#define COUNTER_FREQUENCY 24000000
#define CONFIG_SYS_HZ_CLOCK 24000000
diff --git a/include/configs/rk3128_common.h b/include/configs/rk3128_common.h
index 97caceacfe6..d77a7d7b098 100644
--- a/include/configs/rk3128_common.h
+++ b/include/configs/rk3128_common.h
@@ -11,7 +11,6 @@
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_CBSIZE 1024
-#define CONFIG_ROCKCHIP_STIMER_BASE 0x200440a0
#define COUNTER_FREQUENCY 24000000
#define CONFIG_SYS_HZ_CLOCK 24000000
diff --git a/include/configs/rk322x_common.h b/include/configs/rk322x_common.h
index ef55ef0a83b..3258820fcdc 100644
--- a/include/configs/rk322x_common.h
+++ b/include/configs/rk322x_common.h
@@ -11,7 +11,6 @@
#define CONFIG_SYS_CBSIZE 1024
#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64M */
-#define CONFIG_ROCKCHIP_STIMER_BASE 0x110d0020
#define COUNTER_FREQUENCY 24000000
#define CONFIG_SYS_HZ_CLOCK 24000000
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 490da7cb23b..e2e0f70a70c 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -13,7 +13,6 @@
#define CONFIG_SYS_CBSIZE 1024
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xff810020
#define COUNTER_FREQUENCY 24000000
#define CONFIG_SYS_HZ_CLOCK 24000000
diff --git a/include/configs/rk3308_common.h b/include/configs/rk3308_common.h
index 1664707ca65..9cda8d9c48b 100644
--- a/include/configs/rk3308_common.h
+++ b/include/configs/rk3308_common.h
@@ -15,7 +15,6 @@
#define CONFIG_SYS_NS16550_MEM32
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xff1b00a0
#define CONFIG_IRAM_BASE 0xfff80000
#define CONFIG_SYS_INIT_SP_ADDR 0x00800000
#define CONFIG_SPL_STACK 0x00400000
diff --git a/include/configs/rk3328_common.h b/include/configs/rk3328_common.h
index c1e26a019b5..8a5f0c8999f 100644
--- a/include/configs/rk3328_common.h
+++ b/include/configs/rk3328_common.h
@@ -10,7 +10,6 @@
#define CONFIG_IRAM_BASE 0xff090000
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xff1d0020
#define COUNTER_FREQUENCY 24000000
#define CONFIG_SYS_CBSIZE 1024
diff --git a/include/configs/rk3368_common.h b/include/configs/rk3368_common.h
index 8b239ca07da..239296c1d22 100644
--- a/include/configs/rk3368_common.h
+++ b/include/configs/rk3368_common.h
@@ -15,7 +15,6 @@
#define SDRAM_MAX_SIZE 0xff000000
#define CONFIG_SYS_CBSIZE 1024
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xff830020
#define COUNTER_FREQUENCY 24000000
#define CONFIG_IRAM_BASE 0xff8c0000
diff --git a/include/configs/rk3399_common.h b/include/configs/rk3399_common.h
index ed72c8bb6b1..4037dba58cc 100644
--- a/include/configs/rk3399_common.h
+++ b/include/configs/rk3399_common.h
@@ -11,7 +11,6 @@
#define CONFIG_SYS_CBSIZE 1024
#define COUNTER_FREQUENCY 24000000
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xff8680a0
#define CONFIG_IRAM_BASE 0xff8c0000
diff --git a/include/configs/rk3568_common.h b/include/configs/rk3568_common.h
index 25d7c5cc8ff..5649cd64e0e 100644
--- a/include/configs/rk3568_common.h
+++ b/include/configs/rk3568_common.h
@@ -11,7 +11,6 @@
#define CONFIG_SYS_CBSIZE 1024
#define COUNTER_FREQUENCY 24000000
-#define CONFIG_ROCKCHIP_STIMER_BASE 0xfdd1c020
#define CONFIG_IRAM_BASE 0xfdcc0000
From 12a716422fa0f30ae1ce4ba27cee81a8fe890efc Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:03 +0200
Subject: [PATCH 08/48] rockchip: spl: change call condition
rockchip_stimer_init()
The Rockchip SoCs rk3066/rk3188 have no CONFIG_ROCKCHIP_STIMER_BASE
defined. Currently only rk3188 has an exception in SPL. Make this more
generic and compile code inside the function rockchip_stimer_init()
only when CONFIG_ROCKCHIP_STIMER_BASE is available.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/mach-rockchip/spl.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c
index d51a0727b47..eda2248029d 100644
--- a/arch/arm/mach-rockchip/spl.c
+++ b/arch/arm/mach-rockchip/spl.c
@@ -71,7 +71,6 @@ u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
return MMCSD_MODE_RAW;
}
-#if !defined(CONFIG_ROCKCHIP_RK3188)
#define TIMER_LOAD_COUNT_L 0x00
#define TIMER_LOAD_COUNT_H 0x04
#define TIMER_CONTROL_REG 0x10
@@ -81,6 +80,7 @@ u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
__weak void rockchip_stimer_init(void)
{
+#if defined(CONFIG_ROCKCHIP_STIMER_BASE)
/* If Timer already enabled, don't re-init it */
u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
@@ -95,8 +95,8 @@ __weak void rockchip_stimer_init(void)
writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
TIMER_CONTROL_REG);
-}
#endif
+}
__weak int board_early_init_f(void)
{
@@ -133,9 +133,9 @@ void board_init_f(ulong dummy)
hang();
}
arch_cpu_init();
-#if !defined(CONFIG_ROCKCHIP_RK3188)
+
rockchip_stimer_init();
-#endif
+
#ifdef CONFIG_SYS_ARCH_TIMER
/* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
timer_init();
From d23f55d21749fc1fc1147edad3b1782d479b9946 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:04 +0200
Subject: [PATCH 09/48] rockchip: tpl: change call condition
rockchip_stimer_init()
The Rockchip SoCs rk3066/rk3188 have no CONFIG_ROCKCHIP_STIMER_BASE
defined. Currently there's no exception in TPL. Make this more
generic and compile the code inside the function rockchip_stimer_init()
only when CONFIG_ROCKCHIP_STIMER_BASE is available.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/mach-rockchip/tpl.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/mach-rockchip/tpl.c b/arch/arm/mach-rockchip/tpl.c
index 3c007bb4508..7f43f584066 100644
--- a/arch/arm/mach-rockchip/tpl.c
+++ b/arch/arm/mach-rockchip/tpl.c
@@ -29,6 +29,7 @@
__weak void rockchip_stimer_init(void)
{
+#if defined(CONFIG_ROCKCHIP_STIMER_BASE)
/* If Timer already enabled, don't re-init it */
u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
@@ -45,6 +46,7 @@ __weak void rockchip_stimer_init(void)
writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
TIMER_CONTROL_REG);
+#endif
}
void board_init_f(ulong dummy)
From 30a7b824aa5a2774bf320c20f1d460aea2a56db0 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:05 +0200
Subject: [PATCH 10/48] rockchip: tpl: use IS_ENABLED for timer_init() call
condition
Not all Rockchip SoC models use the ARM arch timer.
Call the function timer_init() only when
CONFIG_SYS_ARCH_TIMER is available.
Use the call condition IS_ENABLED to increase
build coverage and make the code easier to read.
Signed-off-by: Johan Jonker
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
arch/arm/mach-rockchip/tpl.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-rockchip/tpl.c b/arch/arm/mach-rockchip/tpl.c
index 7f43f584066..8126587060f 100644
--- a/arch/arm/mach-rockchip/tpl.c
+++ b/arch/arm/mach-rockchip/tpl.c
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#if CONFIG_IS_ENABLED(BANNER_PRINT)
#include
@@ -77,8 +78,10 @@ void board_init_f(ulong dummy)
/* Init secure timer */
rockchip_stimer_init();
- /* Init ARM arch timer in arch/arm/cpu/ */
- timer_init();
+
+ /* Init ARM arch timer */
+ if (IS_ENABLED(CONFIG_SYS_ARCH_TIMER))
+ timer_init();
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
From 516e216a788f62d6638e69632d97bc5798d29f1c Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:06 +0200
Subject: [PATCH 11/48] rockchip: timer: add OF_PLATDATA support for
dw-apb-timer
The Rockchip rk3066 SoC has 3 dw-apb-timer nodes.
U-boot is compiled with OF_PLATDATA TPL/SPL options,
so add OF_PLATDATA support for the dw-apb-timer.
Also change driver name to be able to compile with
U-boot scripts. No reset OF_PLATDATA support was added,
because the rk3066 nodes don't need/have them.
Signed-off-by: Johan Jonker
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
drivers/timer/dw-apb-timer.c | 50 ++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
index 9aed5dd217a..f7226979342 100644
--- a/drivers/timer/dw-apb-timer.c
+++ b/drivers/timer/dw-apb-timer.c
@@ -8,10 +8,12 @@
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
@@ -25,6 +27,12 @@ struct dw_apb_timer_priv {
struct reset_ctl_bulk resets;
};
+struct dw_apb_timer_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_snps_dw_apb_timer dtplat;
+#endif
+};
+
static u64 dw_apb_timer_get_count(struct udevice *dev)
{
struct dw_apb_timer_priv *priv = dev_get_priv(dev);
@@ -43,20 +51,33 @@ static int dw_apb_timer_probe(struct udevice *dev)
struct dw_apb_timer_priv *priv = dev_get_priv(dev);
struct clk clk;
int ret;
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dw_apb_timer_plat *plat = dev_get_plat(dev);
+ struct dtd_snps_dw_apb_timer *dtplat = &plat->dtplat;
- ret = reset_get_bulk(dev, &priv->resets);
- if (ret)
- dev_warn(dev, "Can't get reset: %d\n", ret);
- else
- reset_deassert_bulk(&priv->resets);
+ priv->regs = dtplat->reg[0];
- ret = clk_get_by_index(dev, 0, &clk);
- if (ret)
+ ret = clk_get_by_phandle(dev, &dtplat->clocks[0], &clk);
+ if (ret < 0)
return ret;
- uc_priv->clock_rate = clk_get_rate(&clk);
+ uc_priv->clock_rate = dtplat->clock_frequency;
+#endif
+ if (CONFIG_IS_ENABLED(OF_REAL)) {
+ ret = reset_get_bulk(dev, &priv->resets);
+ if (ret)
+ dev_warn(dev, "Can't get reset: %d\n", ret);
+ else
+ reset_deassert_bulk(&priv->resets);
- clk_free(&clk);
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ uc_priv->clock_rate = clk_get_rate(&clk);
+
+ clk_free(&clk);
+ }
/* init timer */
writel(0xffffffff, priv->regs + DW_APB_LOAD_VAL);
@@ -68,9 +89,11 @@ static int dw_apb_timer_probe(struct udevice *dev)
static int dw_apb_timer_of_to_plat(struct udevice *dev)
{
- struct dw_apb_timer_priv *priv = dev_get_priv(dev);
+ if (CONFIG_IS_ENABLED(OF_REAL)) {
+ struct dw_apb_timer_priv *priv = dev_get_priv(dev);
- priv->regs = dev_read_addr(dev);
+ priv->regs = dev_read_addr(dev);
+ }
return 0;
}
@@ -91,8 +114,8 @@ static const struct udevice_id dw_apb_timer_ids[] = {
{}
};
-U_BOOT_DRIVER(dw_apb_timer) = {
- .name = "dw_apb_timer",
+U_BOOT_DRIVER(snps_dw_apb_timer) = {
+ .name = "snps_dw_apb_timer",
.id = UCLASS_TIMER,
.ops = &dw_apb_timer_ops,
.probe = dw_apb_timer_probe,
@@ -100,4 +123,5 @@ U_BOOT_DRIVER(dw_apb_timer) = {
.of_to_plat = dw_apb_timer_of_to_plat,
.remove = dw_apb_timer_remove,
.priv_auto = sizeof(struct dw_apb_timer_priv),
+ .plat_auto = sizeof(struct dw_apb_timer_plat),
};
From 3930209526b32d9075ee9c01e87ee50201934313 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:07 +0200
Subject: [PATCH 12/48] rockchip: timer: dw-apb-timer: fix whitespace in
U_BOOT_DRIVER structure
The line with .of_to_plat in the U_BOOT_DRIVER structure
of dw-apb-timer.c is not aligned with the rest.
Add an extra TAB to fix the whitespace.
Signed-off-by: Johan Jonker
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
drivers/timer/dw-apb-timer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
index f7226979342..10f0a9f646e 100644
--- a/drivers/timer/dw-apb-timer.c
+++ b/drivers/timer/dw-apb-timer.c
@@ -120,7 +120,7 @@ U_BOOT_DRIVER(snps_dw_apb_timer) = {
.ops = &dw_apb_timer_ops,
.probe = dw_apb_timer_probe,
.of_match = dw_apb_timer_ids,
- .of_to_plat = dw_apb_timer_of_to_plat,
+ .of_to_plat = dw_apb_timer_of_to_plat,
.remove = dw_apb_timer_remove,
.priv_auto = sizeof(struct dw_apb_timer_priv),
.plat_auto = sizeof(struct dw_apb_timer_plat),
From 9d75dafb1bee4cdc165c3c3ca246e9bc70690a7f Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:08 +0200
Subject: [PATCH 13/48] rockchip: mmc: rockchip_dw_mmc: fix ciu clock index
The document rockchip-dw-mshc.yaml decribes a maximum of 4 clocks.
In the rockchip_dw_mmc driver the clock name in use was "fixed"
to "ciu" with index 1, but later reverted back to index 0.
The clock drivers can handle both, but the calling driver
should submit correct data as a standard practice.
Fix the "ciu" clock index by setting it back to 1.
clock-names:
minItems: 2
items:
- const: biu
- const: ciu
- const: ciu-drive
- const: ciu-sample
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
drivers/mmc/rockchip_dw_mmc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 7f8dea1e343..be065ec0c34 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -123,11 +123,11 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
priv->minmax[0] = 400000; /* 400 kHz */
priv->minmax[1] = dtplat->max_frequency;
- ret = clk_get_by_phandle(dev, dtplat->clocks, &priv->clk);
+ ret = clk_get_by_phandle(dev, &dtplat->clocks[1], &priv->clk);
if (ret < 0)
return ret;
#else
- ret = clk_get_by_index(dev, 0, &priv->clk);
+ ret = clk_get_by_index(dev, 1, &priv->clk);
if (ret < 0)
return ret;
#endif
From 2d3bb400f37b86c3da3a64a9ee4c1d79caa2fdd6 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:09 +0200
Subject: [PATCH 14/48] rockchip: mmc: rockchip_dw_mmc: add rk3066/rk3188
support
The Rockchip SoCs rk3066/rk3188 have MMC DT nodes
with as compatible string "rockchip,rk2928-dw-mshc".
Add OF_PLATDATA support to the existing driver with
help of a DM_DRIVER_ALIAS.
This type needs a permanent enabled fifo.
The other Rockchip SoCs always have the property
"u-boot,spl-fifo-mode" in the MMC DT nodes,
because MMC to SRAM can't do DMA.
Make this property a requirement for MMC OF_PLATDATA
structures. The property "fifo-mode" must be added
for all other compile modes.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
drivers/mmc/rockchip_dw_mmc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index be065ec0c34..573bf16c875 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -119,7 +119,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
host->priv = dev;
host->dev_index = 0;
priv->fifo_depth = dtplat->fifo_depth;
- priv->fifo_mode = 0;
+ priv->fifo_mode = dtplat->u_boot_spl_fifo_mode;
priv->minmax[0] = 400000; /* 400 kHz */
priv->minmax[1] = dtplat->max_frequency;
@@ -180,5 +180,6 @@ U_BOOT_DRIVER(rockchip_rk3288_dw_mshc) = {
.plat_auto = sizeof(struct rockchip_mmc_plat),
};
+DM_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk2928_dw_mshc)
DM_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3328_dw_mshc)
DM_DRIVER_ALIAS(rockchip_rk3288_dw_mshc, rockchip_rk3368_dw_mshc)
From 728489753c75888b2ffd70ad37b2b0590edc45d9 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:10 +0200
Subject: [PATCH 15/48] rockchip: serial: restyle the serial_rockchip.c driver
The ns16550.c driver has the following conditions for .of_match:
CONFIG_IS_ENABLED(OF_REAL)
For Rockchip SoCs with TPL/SPL and platform data that need serial
support the serial_rockchip.c driver was made. It copies this data
and then calls ns16550_serial_probe(). With the addition of yet an other
SoC type this driver is in need for a little restyle.
Simplify struct rockchip_uart_plat and add extra SoCs with
DM_DRIVER_ALIAS(). Return -ENODEV when the ns16550.c driver
probe function is available.
Signed-off-by: Johan Jonker
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
drivers/serial/serial_rockchip.c | 37 +++++++++++++-------------------
1 file changed, 15 insertions(+), 22 deletions(-)
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
index 97d40869a2a..f5ac705f4de 100644
--- a/drivers/serial/serial_rockchip.c
+++ b/drivers/serial/serial_rockchip.c
@@ -12,22 +12,20 @@
#include
#include
-#if defined(CONFIG_ROCKCHIP_RK3188)
-struct rockchip_uart_plat {
- struct dtd_rockchip_rk3188_uart dtplat;
- struct ns16550_plat plat;
-};
-struct dtd_rockchip_rk3188_uart *dtplat, s_dtplat;
-#elif defined(CONFIG_ROCKCHIP_RK3288)
struct rockchip_uart_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3288_uart dtplat;
+#endif
struct ns16550_plat plat;
};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct dtd_rockchip_rk3288_uart *dtplat, s_dtplat;
#endif
static int rockchip_serial_probe(struct udevice *dev)
{
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
struct rockchip_uart_plat *plat = dev_get_plat(dev);
/* Create some new platform data for the standard driver */
@@ -38,24 +36,19 @@ static int rockchip_serial_probe(struct udevice *dev)
dev_set_plat(dev, &plat->plat);
return ns16550_serial_probe(dev);
+#else
+ return -ENODEV;
+#endif
}
-U_BOOT_DRIVER(rockchip_rk3188_uart) = {
- .name = "rockchip_rk3188_uart",
- .id = UCLASS_SERIAL,
- .priv_auto = sizeof(struct ns16550),
- .plat_auto = sizeof(struct rockchip_uart_plat),
- .probe = rockchip_serial_probe,
- .ops = &ns16550_serial_ops,
- .flags = DM_FLAG_PRE_RELOC,
-};
-
U_BOOT_DRIVER(rockchip_rk3288_uart) = {
- .name = "rockchip_rk3288_uart",
- .id = UCLASS_SERIAL,
+ .name = "rockchip_rk3288_uart",
+ .id = UCLASS_SERIAL,
.priv_auto = sizeof(struct ns16550),
.plat_auto = sizeof(struct rockchip_uart_plat),
- .probe = rockchip_serial_probe,
- .ops = &ns16550_serial_ops,
- .flags = DM_FLAG_PRE_RELOC,
+ .probe = rockchip_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
};
+DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3066_uart)
+DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3188_uart)
From 04ee76c988859a586e9bc6b7f65755a5af295105 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:11 +0200
Subject: [PATCH 16/48] rockchip: serial: move driver alias to
serial_rockchip.c
The Rockchip uart DT nodes have "snps,dw-apb-uart" as
fall back string. The driver ns16550.c has CONFIG_IS_ENABLED(OF_REAL)
as condition to of_match and does not copy dtplat data.
For TPL/SPL the driver serial_rockchip.c
is used. Move driver alias to correct driver.
Signed-off-by: Johan Jonker
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
drivers/serial/ns16550.c | 2 --
drivers/serial/serial_rockchip.c | 2 ++
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 796ff1658cd..a4220fd0ae2 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -624,8 +624,6 @@ U_BOOT_DRIVER(ns16550_serial) = {
#endif
};
-DM_DRIVER_ALIAS(ns16550_serial, rockchip_rk3328_uart)
-DM_DRIVER_ALIAS(ns16550_serial, rockchip_rk3368_uart)
DM_DRIVER_ALIAS(ns16550_serial, ti_da830_uart)
#endif
#endif /* SERIAL_PRESENT */
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
index f5ac705f4de..10e731caa18 100644
--- a/drivers/serial/serial_rockchip.c
+++ b/drivers/serial/serial_rockchip.c
@@ -52,3 +52,5 @@ U_BOOT_DRIVER(rockchip_rk3288_uart) = {
};
DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3066_uart)
DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3188_uart)
+DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3328_uart)
+DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3368_uart)
From 6e2ee2ebb808721ab5cb4b03642a169c5ec739c7 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:12 +0200
Subject: [PATCH 17/48] rockchip: serial: rename U_BOOT_DRIVER name to
rockchip_uart
When a defconfig for rk3288 is compiled it gives the warning:
rockchip_rk3288_uart: Missing .compatible in
./drivers/serial/serial_rockchip.c
: WARNING: the driver rockchip_rk3288_uart
was not found in the driver list
Fix by renaming U_BOOT_DRIVER name of serial_rockchip.c
to rockchip_uart. Add rk3288 serial support with
a DM_DRIVER_ALIAS define.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
drivers/serial/serial_rockchip.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c
index 10e731caa18..f4e9422ed91 100644
--- a/drivers/serial/serial_rockchip.c
+++ b/drivers/serial/serial_rockchip.c
@@ -14,13 +14,13 @@
struct rockchip_uart_plat {
#if CONFIG_IS_ENABLED(OF_PLATDATA)
- struct dtd_rockchip_rk3288_uart dtplat;
+ struct dtd_rockchip_uart dtplat;
#endif
struct ns16550_plat plat;
};
#if CONFIG_IS_ENABLED(OF_PLATDATA)
-struct dtd_rockchip_rk3288_uart *dtplat, s_dtplat;
+struct dtd_rockchip_uart *dtplat, s_dtplat;
#endif
static int rockchip_serial_probe(struct udevice *dev)
@@ -41,8 +41,8 @@ static int rockchip_serial_probe(struct udevice *dev)
#endif
}
-U_BOOT_DRIVER(rockchip_rk3288_uart) = {
- .name = "rockchip_rk3288_uart",
+U_BOOT_DRIVER(rockchip_uart) = {
+ .name = "rockchip_uart",
.id = UCLASS_SERIAL,
.priv_auto = sizeof(struct ns16550),
.plat_auto = sizeof(struct rockchip_uart_plat),
@@ -50,7 +50,8 @@ U_BOOT_DRIVER(rockchip_rk3288_uart) = {
.ops = &ns16550_serial_ops,
.flags = DM_FLAG_PRE_RELOC,
};
-DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3066_uart)
-DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3188_uart)
-DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3328_uart)
-DM_DRIVER_ALIAS(rockchip_rk3288_uart, rockchip_rk3368_uart)
+DM_DRIVER_ALIAS(rockchip_uart, rockchip_rk3066_uart)
+DM_DRIVER_ALIAS(rockchip_uart, rockchip_rk3188_uart)
+DM_DRIVER_ALIAS(rockchip_uart, rockchip_rk3288_uart)
+DM_DRIVER_ALIAS(rockchip_uart, rockchip_rk3328_uart)
+DM_DRIVER_ALIAS(rockchip_uart, rockchip_rk3368_uart)
From 6dcaf2d22b1c3f88481431372f1e48d36aa2a23c Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:13 +0200
Subject: [PATCH 18/48] rockchip: serial: Kconfig: add select SYS_NS16550 to
config ROCKCHIP_SERIAL
The Rockchip serial driver depends on an enabled NS16550 driver,
so add select SYS_NS16550 to config ROCKCHIP_SERIAL.
Signed-off-by: Johan Jonker
Reviewed-by: Simon Glass
Reviewed-by: Kever Yang
---
drivers/serial/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index dc514c95d33..b5c6005b048 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -763,6 +763,7 @@ config PL01X_SERIAL
config ROCKCHIP_SERIAL
bool "Rockchip on-chip UART support"
depends on DM_SERIAL && SPL_OF_PLATDATA
+ select SYS_NS16550
help
Select this to enable a debug UART for Rockchip devices when using
CONFIG_SPL_OF_PLATDATA (i.e. a compiled-in device tree replacemenmt).
From 9ee6c0766da8bb95c50a12bd774081bcdb0cdedb Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 9 Apr 2022 18:55:14 +0200
Subject: [PATCH 19/48] rockchip: serial: Kconfig: allow ROCKCHIP_SERIAL
enabled in TPL
The serial_rockchip.c driver converts platdata to the data structure
used in the ns16550.c file and then calls the function
ns16550_serial_probe().
When compiled with OF_REAL the serial_rockchip.c driver returns
now -ENODEV when probed and does no harm.
The config ROCKCHIP_SERIAL is currently depends on SPL_OF_PLATDATA.
Allow serial port use for both SPL and TPL by removing this
dependency and SPL_BUILD restriction.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
drivers/serial/Kconfig | 4 ++--
drivers/serial/Makefile | 2 --
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b5c6005b048..1e595d06004 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -762,11 +762,11 @@ config PL01X_SERIAL
config ROCKCHIP_SERIAL
bool "Rockchip on-chip UART support"
- depends on DM_SERIAL && SPL_OF_PLATDATA
+ depends on DM_SERIAL
select SYS_NS16550
help
Select this to enable a debug UART for Rockchip devices when using
- CONFIG_SPL_OF_PLATDATA (i.e. a compiled-in device tree replacemenmt).
+ OF_PLATDATA (i.e. a compiled-in device tree replacemenmt).
This uses the ns16550 driver, converting the platdata from of-platdata
to the ns16550 format.
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index b68b5e7b2bf..d8e26d72ea2 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -46,9 +46,7 @@ obj-$(CONFIG_MXC_UART) += serial_mxc.o
obj-$(CONFIG_PXA_SERIAL) += serial_pxa.o
obj-$(CONFIG_MESON_SERIAL) += serial_meson.o
obj-$(CONFIG_INTEL_MID_SERIAL) += serial_intel_mid.o
-ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o
-endif
obj-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
obj-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
obj-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
From 5e6ee6bde5dd8ef804665b6bf45237e30f45575b Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:37 +0200
Subject: [PATCH 20/48] rockchip: rk3066-power: sync power domain dt-binding
header from Linux
In order to update the DT for rk3066
sync the power domain dt-binding header.
This is the state as of v5.12 in Linux.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
include/dt-bindings/power/rk3066-power.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 include/dt-bindings/power/rk3066-power.h
diff --git a/include/dt-bindings/power/rk3066-power.h b/include/dt-bindings/power/rk3066-power.h
new file mode 100644
index 00000000000..acf9f310ac5
--- /dev/null
+++ b/include/dt-bindings/power/rk3066-power.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__
+#define __DT_BINDINGS_POWER_RK3066_POWER_H__
+
+/* VD_CORE */
+#define RK3066_PD_A9_0 0
+#define RK3066_PD_A9_1 1
+#define RK3066_PD_DBG 4
+#define RK3066_PD_SCU 5
+
+/* VD_LOGIC */
+#define RK3066_PD_VIDEO 6
+#define RK3066_PD_VIO 7
+#define RK3066_PD_GPU 8
+#define RK3066_PD_PERI 9
+#define RK3066_PD_CPU 10
+#define RK3066_PD_ALIVE 11
+
+/* VD_PMU */
+#define RK3066_PD_RTC 12
+
+#endif
From e6b0ed0e74099fcfa94263e849d8695992060e19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jarosz?=
Date: Sat, 16 Apr 2022 17:09:38 +0200
Subject: [PATCH 21/48] rockchip: rk3066: add grf header file
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
grf is needed by various drivers for rk3066 soc.
Signed-off-by: Paweł Jarosz
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
.../include/asm/arch-rockchip/grf_rk3066.h | 210 ++++++++++++++++++
1 file changed, 210 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rk3066.h
diff --git a/arch/arm/include/asm/arch-rockchip/grf_rk3066.h b/arch/arm/include/asm/arch-rockchip/grf_rk3066.h
new file mode 100644
index 00000000000..d8e0812ceea
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_rk3066.h
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2021 Paweł Jarosz
+ */
+
+#ifndef _ASM_ARCH_GRF_RK3066_H
+#define _ASM_ARCH_GRF_RK3066_H
+
+#include
+#include
+
+#define REG(name, h, l) \
+ name##_MASK = GENMASK(h, l), \
+ name##_SHIFT = __bf_shf(name##_MASK)
+
+struct rk3066_grf_gpio_lh {
+ u32 l;
+ u32 h;
+};
+
+struct rk3066_grf {
+ struct rk3066_grf_gpio_lh gpio_dir[7];
+ struct rk3066_grf_gpio_lh gpio_do[7];
+ struct rk3066_grf_gpio_lh gpio_en[7];
+
+ u32 gpio0a_iomux;
+ u32 gpio0b_iomux;
+ u32 gpio0c_iomux;
+ u32 gpio0d_iomux;
+
+ u32 gpio1a_iomux;
+ u32 gpio1b_iomux;
+ u32 gpio1c_iomux;
+ u32 gpio1d_iomux;
+
+ u32 gpio2a_iomux;
+ u32 gpio2b_iomux;
+ u32 gpio2c_iomux;
+ u32 gpio2d_iomux;
+
+ u32 gpio3a_iomux;
+ u32 gpio3b_iomux;
+ u32 gpio3c_iomux;
+ u32 gpio3d_iomux;
+
+ u32 gpio4a_iomux;
+ u32 gpio4b_iomux;
+ u32 gpio4c_iomux;
+ u32 gpio4d_iomux;
+
+ u32 reserved0[5];
+
+ u32 gpio6b_iomux;
+
+ u32 reserved1[2];
+
+ struct rk3066_grf_gpio_lh gpio_pull[7];
+
+ u32 soc_con0;
+ u32 soc_con1;
+ u32 soc_con2;
+
+ u32 soc_status0;
+
+ u32 dmac1_con[3];
+ u32 dmac2_con[4];
+
+ u32 uoc0_con[3];
+ u32 uoc1_con[4];
+ u32 ddrc_con;
+ u32 ddrc_stat;
+
+ u32 reserved2[10];
+
+ u32 os_reg[4];
+};
+
+check_member(rk3066_grf, os_reg[3], 0x01d4);
+
+/* GRF_GPIO1B_IOMUX */
+enum {
+ REG(GPIO1B1, 2, 2),
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_UART2_SOUT,
+
+ REG(GPIO1B0, 0, 0),
+ GPIO1B0_GPIO = 0,
+ GPIO1B0_UART2_SIN
+};
+
+/* GRF_GPIO3B_IOMUX */
+enum {
+ REG(GPIO3B6, 12, 12),
+ GPIO3B6_GPIO = 0,
+ GPIO3B6_SDMMC0_DECTN,
+
+ REG(GPIO3B5, 10, 10),
+ GPIO3B5_GPIO = 0,
+ GPIO3B5_SDMMC0_DATA3,
+
+ REG(GPIO3B4, 8, 8),
+ GPIO3B4_GPIO = 0,
+ GPIO3B4_SDMMC0_DATA2,
+
+ REG(GPIO3B3, 6, 6),
+ GPIO3B3_GPIO = 0,
+ GPIO3B3_SDMMC0_DATA1,
+
+ REG(GPIO3B2, 4, 4),
+ GPIO3B2_GPIO = 0,
+ GPIO3B2_SDMMC0_DATA0,
+
+ REG(GPIO3B1, 2, 2),
+ GPIO3B1_GPIO = 0,
+ GPIO3B1_SDMMC0_CMD,
+
+ REG(GPIO3B0, 0, 0),
+ GPIO3B0_GPIO = 0,
+ GPIO3B0_SDMMC0_CLKOUT,
+};
+
+/* GRF_SOC_CON0 */
+enum {
+ REG(SMC_MUX_CON, 13, 13),
+
+ REG(NOC_REMAP, 12, 12),
+
+ REG(EMMC_FLASH_SEL, 11, 11),
+
+ REG(TZPC_REVISION, 10, 7),
+
+ REG(L2CACHE_ACC, 6, 5),
+
+ REG(L2RD_WAIT, 4, 3),
+
+ REG(IMEMRD_WAIT, 2, 1),
+
+ REG(SOC_REMAP, 0, 0),
+};
+
+/* GRF_SOC_CON1 */
+enum {
+ REG(RKI2C4_SEL, 15, 15),
+
+ REG(RKI2C3_SEL, 14, 14),
+
+ REG(RKI2C2_SEL, 13, 13),
+
+ REG(RKI2C1_SEL, 12, 12),
+
+ REG(RKI2C0_SEL, 11, 11),
+
+ REG(VCODEC_SEL, 10, 10),
+
+ REG(PERI_EMEM_PAUSE, 9, 9),
+
+ REG(PERI_USB_PAUSE, 8, 8),
+
+ REG(SMC_MUX_MODE_0, 6, 6),
+
+ REG(SMC_SRAM_MW_0, 5, 4),
+
+ REG(SMC_REMAP_0, 3, 3),
+
+ REG(SMC_A_GT_M0_SYNC, 2, 2),
+
+ REG(EMAC_SPEED, 1, 1),
+
+ REG(EMAC_MODE, 0, 0),
+};
+
+/* GRF_SOC_CON2 */
+enum {
+ REG(MSCH4_MAINDDR3, 7, 7),
+ MSCH4_MAINDDR3_DDR3 = 1,
+
+ REG(EMAC_NEWRCV_EN, 6, 6),
+
+ REG(SW_ADDR15_EN, 5, 5),
+
+ REG(SW_ADDR16_EN, 4, 4),
+
+ REG(SW_ADDR17_EN, 3, 3),
+
+ REG(BANK2_TO_RANK_EN, 2, 2),
+
+ REG(RANK_TO_ROW15_EN, 1, 1),
+
+ REG(UPCTL_C_ACTIVE_IN, 0, 0),
+ UPCTL_C_ACTIVE_IN_MAY = 0,
+ UPCTL_C_ACTIVE_IN_WILL,
+};
+
+/* GRF_DDRC_CON0 */
+enum {
+ REG(DTO_LB, 12, 11),
+
+ REG(DTO_TE, 10, 9),
+
+ REG(DTO_PDR, 8, 7),
+
+ REG(DTO_PDD, 6, 5),
+
+ REG(DTO_IOM, 4, 3),
+
+ REG(DTO_OE, 2, 1),
+
+ REG(ATO_AE, 0, 0),
+};
+#endif
From 730a402450516667e51fab4c519ba16709d2251b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jarosz?=
Date: Sat, 16 Apr 2022 17:09:39 +0200
Subject: [PATCH 22/48] rockchip: rk3066: add clock driver for rk3066 soc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add the clock driver for the rk3066 platform.
Derived from the rk3288 and rk3188 driver it
supports only a bare minimum to bring up the system
to reduce the TPL size for:
SDRAM clock configuration.
The boot devices NAND, EMMC, SDMMC, SPI.
A UART for the debug messages (fixed) at 115200n8.
A SARADC for the recovery button.
A TIMER for the delays (fixed).
There's support for two possible frequencies,
the safe 600MHz which will work with default pmic settings and
will be set to get away from the 24MHz default and
the maximum of 1.416Ghz, which boards can set if they
were able to get pmic support for it.
After the clock tree is set during the TPL probe
there's no parent update support.
In OF_REAL mode the drivers ns16550.c and dw-apb-timer.c
obtain the (fixed) clk_get_rate from the clock driver
instead of platdata.
The rk3066 cru node has a number of assigned-clocks properties
that call the .set_rate() function. Add them to the list so that
they return a 0 instead of -ENOENT.
Signed-off-by: Paweł Jarosz
Signed-off-by: Johan Jonker
Reviewed-by: Sean Anderson
Reviewed-by: Kever Yang
---
.../include/asm/arch-rockchip/cru_rk3066.h | 157 ++++
drivers/clk/rockchip/Makefile | 1 +
drivers/clk/rockchip/clk_rk3066.c | 717 ++++++++++++++++++
3 files changed, 875 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3066.h
create mode 100644 drivers/clk/rockchip/clk_rk3066.c
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3066.h b/arch/arm/include/asm/arch-rockchip/cru_rk3066.h
new file mode 100644
index 00000000000..76a715a8e6a
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3066.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Paweł Jarosz
+ */
+
+#ifndef _ASM_ARCH_CRU_RK3066_H
+#define _ASM_ARCH_CRU_RK3066_H
+
+#include
+#include
+
+#define REG(name, h, l) \
+ name##_MASK = GENMASK(h, l), \
+ name##_SHIFT = __bf_shf(name##_MASK)
+
+#define OSC_HZ (24 * 1000 * 1000)
+
+#define APLL_HZ (1416 * 1000000)
+#define APLL_SAFE_HZ (600 * 1000000)
+#define GPLL_HZ (594 * 1000000)
+#define CPLL_HZ (384 * 1000000)
+
+/* The SRAM is clocked off aclk_cpu, so we want to max it out for boot speed */
+#define CPU_ACLK_HZ 297000000
+#define CPU_HCLK_HZ 148500000
+#define CPU_PCLK_HZ 74250000
+#define CPU_H2P_HZ 74250000
+
+#define PERI_ACLK_HZ 148500000
+#define PERI_HCLK_HZ 148500000
+#define PERI_PCLK_HZ 74250000
+
+/* Private data for the clock driver - used by rockchip_get_cru() */
+struct rk3066_clk_priv {
+ struct rk3066_grf *grf;
+ struct rk3066_cru *cru;
+ ulong rate;
+ bool has_bwadj;
+};
+
+struct rk3066_cru {
+ struct rk3066_pll {
+ u32 con0;
+ u32 con1;
+ u32 con2;
+ u32 con3;
+ } pll[4];
+ u32 cru_mode_con;
+ u32 cru_clksel_con[35];
+ u32 cru_clkgate_con[10];
+ u32 reserved1[2];
+ u32 cru_glb_srst_fst_value;
+ u32 cru_glb_srst_snd_value;
+ u32 reserved2[2];
+ u32 cru_softrst_con[9];
+ u32 cru_misc_con;
+ u32 reserved3[2];
+ u32 cru_glb_cnt_th;
+};
+
+check_member(rk3066_cru, cru_glb_cnt_th, 0x0140);
+
+/* CRU_CLKSEL0_CON */
+enum {
+ REG(CPU_ACLK_PLL, 8, 8),
+ CPU_ACLK_PLL_SELECT_APLL = 0,
+ CPU_ACLK_PLL_SELECT_GPLL,
+
+ REG(CORE_PERI_DIV, 7, 6),
+
+ REG(A9_CORE_DIV, 4, 0),
+};
+
+/* CRU_CLKSEL1_CON */
+enum {
+ REG(AHB2APB_DIV, 15, 14),
+
+ REG(CPU_PCLK_DIV, 13, 12),
+
+ REG(CPU_HCLK_DIV, 9, 8),
+
+ REG(CPU_ACLK_DIV, 2, 0),
+};
+
+/* CRU_CLKSEL10_CON */
+enum {
+ REG(PERI_SEL_PLL, 15, 15),
+ PERI_SEL_CPLL = 0,
+ PERI_SEL_GPLL,
+
+ REG(PERI_PCLK_DIV, 13, 12),
+
+ REG(PERI_HCLK_DIV, 9, 8),
+
+ REG(PERI_ACLK_DIV, 4, 0),
+};
+
+/* CRU_CLKSEL11_CON */
+enum {
+ REG(MMC0_DIV, 5, 0),
+};
+
+/* CRU_CLKSEL12_CON */
+enum {
+ REG(UART_PLL, 15, 15),
+ UART_PLL_SELECT_GENERAL = 0,
+ UART_PLL_SELECT_CODEC,
+
+ REG(EMMC_DIV, 13, 8),
+
+ REG(SDIO_DIV, 5, 0),
+};
+
+/* CRU_CLKSEL24_CON */
+enum {
+ REG(SARADC_DIV, 15, 8),
+};
+
+/* CRU_CLKSEL25_CON */
+enum {
+ REG(SPI1_DIV, 14, 8),
+
+ REG(SPI0_DIV, 6, 0),
+};
+
+/* CRU_CLKSEL34_CON */
+enum {
+ REG(TSADC_DIV, 15, 0),
+};
+
+/* CRU_MODE_CON */
+enum {
+ REG(GPLL_MODE, 13, 12),
+
+ REG(CPLL_MODE, 9, 8),
+
+ REG(DPLL_MODE, 5, 4),
+
+ REG(APLL_MODE, 1, 0),
+ PLL_MODE_SLOW = 0,
+ PLL_MODE_NORMAL,
+ PLL_MODE_DEEP,
+};
+
+/* CRU_APLL_CON0 */
+enum {
+ REG(CLKR, 13, 8),
+
+ REG(CLKOD, 3, 0),
+};
+
+/* CRU_APLL_CON1 */
+enum {
+ REG(CLKF, 12, 0),
+};
+
+#endif
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 913f611a0ff..a72d8fe58a6 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -6,6 +6,7 @@
obj-y += clk_pll.o
obj-$(CONFIG_ROCKCHIP_PX30) += clk_px30.o
obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3066) += clk_rk3066.o
obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o
diff --git a/drivers/clk/rockchip/clk_rk3066.c b/drivers/clk/rockchip/clk_rk3066.c
new file mode 100644
index 00000000000..2c12f6e0441
--- /dev/null
+++ b/drivers/clk/rockchip/clk_rk3066.c
@@ -0,0 +1,717 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2015 Google, Inc
+ * (C) Copyright 2016 Heiko Stuebner
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct rk3066_clk_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3066a_cru dtd;
+#endif
+};
+
+struct pll_div {
+ u32 nr;
+ u32 nf;
+ u32 no;
+};
+
+enum {
+ VCO_MAX_HZ = 1416U * 1000000,
+ VCO_MIN_HZ = 300 * 1000000,
+ OUTPUT_MAX_HZ = 1416U * 1000000,
+ OUTPUT_MIN_HZ = 30 * 1000000,
+ FREF_MAX_HZ = 1416U * 1000000,
+ FREF_MIN_HZ = 30 * 1000,
+};
+
+enum {
+ /* PLL CON0 */
+ PLL_OD_MASK = GENMASK(3, 0),
+
+ /* PLL CON1 */
+ PLL_NF_MASK = GENMASK(12, 0),
+
+ /* PLL CON2 */
+ PLL_BWADJ_MASK = GENMASK(11, 0),
+
+ /* PLL CON3 */
+ PLL_RESET_SHIFT = 5,
+
+ /* GRF_SOC_STATUS0 */
+ SOCSTS_DPLL_LOCK = BIT(4),
+ SOCSTS_APLL_LOCK = BIT(5),
+ SOCSTS_CPLL_LOCK = BIT(6),
+ SOCSTS_GPLL_LOCK = BIT(7),
+};
+
+#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1))
+
+#define PLL_DIVISORS(hz, _nr, _no) {\
+ .nr = _nr, .nf = (u32)((u64)hz * _nr * _no / OSC_HZ), .no = _no};\
+ _Static_assert(((u64)hz * _nr * _no / OSC_HZ) * OSC_HZ /\
+ (_nr * _no) == hz, #hz "Hz cannot be hit with PLL "\
+ "divisors on line " __stringify(__LINE__))
+
+/* Keep divisors as low as possible to reduce jitter and power usage. */
+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2);
+static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 1, 2);
+
+static int rk3066_clk_set_pll(struct rk3066_cru *cru, enum rk_clk_id clk_id,
+ const struct pll_div *div)
+{
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3066_pll *pll = &cru->pll[pll_id];
+ /* All PLLs have the same VCO and output frequency range restrictions. */
+ uint vco_hz = OSC_HZ / 1000 * div->nf / div->nr * 1000;
+ uint output_hz = vco_hz / div->no;
+
+ debug("%s: PLL at %x: nf=%d, nr=%d, no=%d, vco=%u Hz, output=%u Hz\n", __func__,
+ (uint)pll, div->nf, div->nr, div->no, vco_hz, output_hz);
+ assert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&
+ output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ &&
+ (div->no == 1 || !(div->no % 2)));
+
+ /* Enter reset. */
+ rk_setreg(&pll->con3, BIT(PLL_RESET_SHIFT));
+
+ rk_clrsetreg(&pll->con0,
+ CLKR_MASK | PLL_OD_MASK,
+ ((div->nr - 1) << CLKR_SHIFT) | (div->no - 1));
+ rk_clrsetreg(&pll->con1, CLKF_MASK, div->nf - 1);
+
+ rk_clrsetreg(&pll->con2, PLL_BWADJ_MASK, (div->nf >> 1) - 1);
+
+ /* Exit reset. */
+ rk_clrreg(&pll->con3, BIT(PLL_RESET_SHIFT));
+
+ return 0;
+}
+
+static int rk3066_clk_configure_ddr(struct rk3066_cru *cru, struct rk3066_grf *grf,
+ unsigned int hz)
+{
+ static const struct pll_div dpll_cfg[] = {
+ {.nf = 25, .nr = 2, .no = 1},
+ {.nf = 400, .nr = 9, .no = 2},
+ {.nf = 500, .nr = 9, .no = 2},
+ {.nf = 100, .nr = 3, .no = 1},
+ };
+ int cfg;
+
+ switch (hz) {
+ case 300000000:
+ cfg = 0;
+ break;
+ case 533000000: /* actually 533.3P MHz */
+ cfg = 1;
+ break;
+ case 666000000: /* actually 666.6P MHz */
+ cfg = 2;
+ break;
+ case 800000000:
+ cfg = 3;
+ break;
+ default:
+ debug("%s: unsupported SDRAM frequency", __func__);
+ return -EINVAL;
+ }
+
+ /* Enter PLL slow mode. */
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
+ PLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+ rk3066_clk_set_pll(cru, CLK_DDR, &dpll_cfg[cfg]);
+
+ /* Wait for PLL lock. */
+ while (!(readl(&grf->soc_status0) & SOCSTS_DPLL_LOCK))
+ udelay(1);
+
+ /* Enter PLL normal mode. */
+ rk_clrsetreg(&cru->cru_mode_con, DPLL_MODE_MASK,
+ PLL_MODE_NORMAL << DPLL_MODE_SHIFT);
+
+ return 0;
+}
+
+static int rk3066_clk_configure_cpu(struct rk3066_cru *cru, struct rk3066_grf *grf,
+ unsigned int hz)
+{
+ static const struct pll_div apll_cfg[] = {
+ {.nf = 50, .nr = 1, .no = 2},
+ {.nf = 59, .nr = 1, .no = 1},
+ };
+ int div_core_peri, div_cpu_aclk, cfg;
+
+ /*
+ * We support two possible frequencies, the safe 600MHz
+ * which will work with default pmic settings and will
+ * be set to get away from the 24MHz default and
+ * the maximum of 1.416Ghz, which boards can set if they
+ * were able to get pmic support for it.
+ */
+ switch (hz) {
+ case APLL_SAFE_HZ:
+ cfg = 0;
+ div_core_peri = 1;
+ div_cpu_aclk = 3;
+ break;
+ case APLL_HZ:
+ cfg = 1;
+ div_core_peri = 2;
+ div_cpu_aclk = 3;
+ break;
+ default:
+ debug("unsupported ARMCLK frequency");
+ return -EINVAL;
+ }
+
+ /* Enter PLL slow mode. */
+ rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
+ PLL_MODE_SLOW << APLL_MODE_SHIFT);
+
+ rk3066_clk_set_pll(cru, CLK_ARM, &apll_cfg[cfg]);
+
+ /* Wait for PLL lock. */
+ while (!(readl(&grf->soc_status0) & SOCSTS_APLL_LOCK))
+ udelay(1);
+
+ /* Set divider for peripherals attached to the CPU core. */
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CORE_PERI_DIV_MASK,
+ div_core_peri << CORE_PERI_DIV_SHIFT);
+
+ /* Set up dependent divisor for cpu_aclk. */
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ CPU_ACLK_DIV_MASK,
+ div_cpu_aclk << CPU_ACLK_DIV_SHIFT);
+
+ /* Enter PLL normal mode. */
+ rk_clrsetreg(&cru->cru_mode_con, APLL_MODE_MASK,
+ PLL_MODE_NORMAL << APLL_MODE_SHIFT);
+
+ return hz;
+}
+
+static uint32_t rk3066_clk_pll_get_rate(struct rk3066_cru *cru,
+ enum rk_clk_id clk_id)
+{
+ u32 nr, no, nf;
+ u32 con;
+ int pll_id = rk_pll_id(clk_id);
+ struct rk3066_pll *pll = &cru->pll[pll_id];
+ static u8 clk_shift[CLK_COUNT] = {
+ 0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+ GPLL_MODE_SHIFT
+ };
+ uint shift;
+
+ con = readl(&cru->cru_mode_con);
+ shift = clk_shift[clk_id];
+ switch (FIELD_GET(APLL_MODE_MASK, con >> shift)) {
+ case PLL_MODE_SLOW:
+ return OSC_HZ;
+ case PLL_MODE_NORMAL:
+ /* normal mode */
+ con = readl(&pll->con0);
+ no = bitfield_extract_by_mask(con, CLKOD_MASK) + 1;
+ nr = bitfield_extract_by_mask(con, CLKR_MASK) + 1;
+ con = readl(&pll->con1);
+ nf = bitfield_extract_by_mask(con, CLKF_MASK) + 1;
+
+ return (OSC_HZ * nf) / (nr * no);
+ case PLL_MODE_DEEP:
+ default:
+ return 32768;
+ }
+}
+
+static ulong rk3066_clk_mmc_get_clk(struct rk3066_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div;
+ u32 con;
+
+ switch (periph) {
+ case HCLK_EMMC:
+ case SCLK_EMMC:
+ con = readl(&cru->cru_clksel_con[12]);
+ div = bitfield_extract_by_mask(con, EMMC_DIV_MASK);
+ break;
+ case HCLK_SDMMC:
+ case SCLK_SDMMC:
+ con = readl(&cru->cru_clksel_con[11]);
+ div = bitfield_extract_by_mask(con, MMC0_DIV_MASK);
+ break;
+ case HCLK_SDIO:
+ case SCLK_SDIO:
+ con = readl(&cru->cru_clksel_con[12]);
+ div = bitfield_extract_by_mask(con, SDIO_DIV_MASK);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(gclk_rate, div) / 2;
+}
+
+static ulong rk3066_clk_mmc_set_clk(struct rk3066_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div;
+
+ debug("%s: gclk_rate=%u\n", __func__, gclk_rate);
+ /* MMC clock by default divides by 2 internally, so need to provide double in CRU. */
+ src_clk_div = DIV_ROUND_UP(gclk_rate / 2, freq) - 1;
+ assert(src_clk_div <= 0x3f);
+
+ switch (periph) {
+ case HCLK_EMMC:
+ case SCLK_EMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ EMMC_DIV_MASK,
+ src_clk_div << EMMC_DIV_SHIFT);
+ break;
+ case HCLK_SDMMC:
+ case SCLK_SDMMC:
+ rk_clrsetreg(&cru->cru_clksel_con[11],
+ MMC0_DIV_MASK,
+ src_clk_div << MMC0_DIV_SHIFT);
+ break;
+ case HCLK_SDIO:
+ case SCLK_SDIO:
+ rk_clrsetreg(&cru->cru_clksel_con[12],
+ SDIO_DIV_MASK,
+ src_clk_div << SDIO_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rk3066_clk_mmc_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rk3066_clk_spi_get_clk(struct rk3066_cru *cru, uint gclk_rate,
+ int periph)
+{
+ uint div;
+ u32 con;
+
+ switch (periph) {
+ case SCLK_SPI0:
+ con = readl(&cru->cru_clksel_con[25]);
+ div = bitfield_extract_by_mask(con, SPI0_DIV_MASK);
+ break;
+ case SCLK_SPI1:
+ con = readl(&cru->cru_clksel_con[25]);
+ div = bitfield_extract_by_mask(con, SPI1_DIV_MASK);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return DIV_TO_RATE(gclk_rate, div);
+}
+
+static ulong rk3066_clk_spi_set_clk(struct rk3066_cru *cru, uint gclk_rate,
+ int periph, uint freq)
+{
+ int src_clk_div = DIV_ROUND_UP(gclk_rate, freq) - 1;
+
+ assert(src_clk_div < 128);
+ switch (periph) {
+ case SCLK_SPI0:
+ assert(src_clk_div <= SPI0_DIV_MASK >> SPI0_DIV_SHIFT);
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI0_DIV_MASK,
+ src_clk_div << SPI0_DIV_SHIFT);
+ break;
+ case SCLK_SPI1:
+ assert(src_clk_div <= SPI1_DIV_MASK >> SPI1_DIV_SHIFT);
+ rk_clrsetreg(&cru->cru_clksel_con[25],
+ SPI1_DIV_MASK,
+ src_clk_div << SPI1_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rk3066_clk_spi_get_clk(cru, gclk_rate, periph);
+}
+
+static ulong rk3066_clk_saradc_get_clk(struct rk3066_cru *cru, int periph)
+{
+ u32 div, con;
+
+ switch (periph) {
+ case SCLK_SARADC:
+ con = readl(&cru->cru_clksel_con[24]);
+ div = bitfield_extract_by_mask(con, SARADC_DIV_MASK);
+ break;
+ case SCLK_TSADC:
+ con = readl(&cru->cru_clksel_con[34]);
+ div = bitfield_extract_by_mask(con, TSADC_DIV_MASK);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return DIV_TO_RATE(PERI_PCLK_HZ, div);
+}
+
+static ulong rk3066_clk_saradc_set_clk(struct rk3066_cru *cru, uint hz,
+ int periph)
+{
+ int src_clk_div;
+
+ src_clk_div = DIV_ROUND_UP(PERI_PCLK_HZ, hz) - 1;
+ assert(src_clk_div < 128);
+
+ switch (periph) {
+ case SCLK_SARADC:
+ rk_clrsetreg(&cru->cru_clksel_con[24],
+ SARADC_DIV_MASK,
+ src_clk_div << SARADC_DIV_SHIFT);
+ break;
+ case SCLK_TSADC:
+ rk_clrsetreg(&cru->cru_clksel_con[34],
+ SARADC_DIV_MASK,
+ src_clk_div << SARADC_DIV_SHIFT);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return rk3066_clk_saradc_get_clk(cru, periph);
+}
+
+static void rk3066_clk_init(struct rk3066_cru *cru, struct rk3066_grf *grf)
+{
+ u32 aclk_div, hclk_div, pclk_div, h2p_div;
+
+ /* Enter PLL slow mode. */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK |
+ CPLL_MODE_MASK,
+ PLL_MODE_SLOW << GPLL_MODE_SHIFT |
+ PLL_MODE_SLOW << CPLL_MODE_SHIFT);
+
+ /* Init PLL. */
+ rk3066_clk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);
+ rk3066_clk_set_pll(cru, CLK_CODEC, &cpll_init_cfg);
+
+ /* Wait for PLL lock. */
+ while ((readl(&grf->soc_status0) &
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK)) !=
+ (SOCSTS_CPLL_LOCK | SOCSTS_GPLL_LOCK))
+ udelay(1);
+
+ /*
+ * Select CPU clock PLL source and
+ * reparent aclk_cpu_pre from APPL to GPLL.
+ * Set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = DIV_ROUND_UP(GPLL_HZ, CPU_ACLK_HZ) - 1;
+ assert((aclk_div + 1) * CPU_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);
+
+ rk_clrsetreg(&cru->cru_clksel_con[0],
+ CPU_ACLK_PLL_MASK |
+ A9_CORE_DIV_MASK,
+ CPU_ACLK_PLL_SELECT_GPLL << CPU_ACLK_PLL_SHIFT |
+ aclk_div << A9_CORE_DIV_SHIFT);
+
+ hclk_div = ilog2(CPU_ACLK_HZ / CPU_HCLK_HZ);
+ assert((1 << hclk_div) * CPU_HCLK_HZ == CPU_ACLK_HZ && hclk_div < 0x3);
+ pclk_div = ilog2(CPU_ACLK_HZ / CPU_PCLK_HZ);
+ assert((1 << pclk_div) * CPU_PCLK_HZ == CPU_ACLK_HZ && pclk_div < 0x4);
+ h2p_div = ilog2(CPU_HCLK_HZ / CPU_H2P_HZ);
+ assert((1 << h2p_div) * CPU_H2P_HZ == CPU_HCLK_HZ && pclk_div < 0x3);
+
+ rk_clrsetreg(&cru->cru_clksel_con[1],
+ AHB2APB_DIV_MASK |
+ CPU_PCLK_DIV_MASK |
+ CPU_HCLK_DIV_MASK,
+ h2p_div << AHB2APB_DIV_SHIFT |
+ pclk_div << CPU_PCLK_DIV_SHIFT |
+ hclk_div << CPU_HCLK_DIV_SHIFT);
+
+ /*
+ * Select PERI clock PLL source and
+ * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+ */
+ aclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;
+ assert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);
+
+ hclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);
+ assert((1 << hclk_div) * PERI_HCLK_HZ ==
+ PERI_ACLK_HZ && (hclk_div < 0x4));
+
+ pclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);
+ assert((1 << pclk_div) * PERI_PCLK_HZ ==
+ PERI_ACLK_HZ && (pclk_div < 0x4));
+
+ rk_clrsetreg(&cru->cru_clksel_con[10],
+ PERI_PCLK_DIV_MASK |
+ PERI_HCLK_DIV_MASK |
+ PERI_ACLK_DIV_MASK,
+ PERI_SEL_GPLL << PERI_SEL_PLL_SHIFT |
+ pclk_div << PERI_PCLK_DIV_SHIFT |
+ hclk_div << PERI_HCLK_DIV_SHIFT |
+ aclk_div << PERI_ACLK_DIV_SHIFT);
+
+ /* Enter PLL normal mode. */
+ rk_clrsetreg(&cru->cru_mode_con,
+ GPLL_MODE_MASK |
+ CPLL_MODE_MASK,
+ PLL_MODE_NORMAL << GPLL_MODE_SHIFT |
+ PLL_MODE_NORMAL << CPLL_MODE_SHIFT);
+
+ rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ, HCLK_SDMMC, 16000000);
+}
+
+static ulong rk3066_clk_get_rate(struct clk *clk)
+{
+ struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong new_rate, gclk_rate;
+
+ gclk_rate = rk3066_clk_pll_get_rate(priv->cru, CLK_GENERAL);
+ switch (clk->id) {
+ case 1 ... 4:
+ new_rate = rk3066_clk_pll_get_rate(priv->cru, clk->id);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO:
+ case SCLK_EMMC:
+ case SCLK_SDMMC:
+ case SCLK_SDIO:
+ new_rate = rk3066_clk_mmc_get_clk(priv->cru, PERI_HCLK_HZ,
+ clk->id);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ new_rate = rk3066_clk_spi_get_clk(priv->cru, PERI_PCLK_HZ,
+ clk->id);
+ break;
+ case PCLK_I2C0:
+ case PCLK_I2C1:
+ case PCLK_I2C2:
+ case PCLK_I2C3:
+ case PCLK_I2C4:
+ return gclk_rate;
+ case SCLK_SARADC:
+ case SCLK_TSADC:
+ new_rate = rk3066_clk_saradc_get_clk(priv->cru, clk->id);
+ break;
+ case SCLK_TIMER0:
+ case SCLK_TIMER1:
+ case SCLK_TIMER2:
+ case SCLK_UART0:
+ case SCLK_UART1:
+ case SCLK_UART2:
+ case SCLK_UART3:
+ return OSC_HZ;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static ulong rk3066_clk_set_rate(struct clk *clk, ulong rate)
+{
+ struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+ struct rk3066_cru *cru = priv->cru;
+ ulong new_rate;
+
+ switch (clk->id) {
+ case PLL_APLL:
+ new_rate = rk3066_clk_configure_cpu(priv->cru, priv->grf, rate);
+ break;
+ case CLK_DDR:
+ new_rate = rk3066_clk_configure_ddr(priv->cru, priv->grf, rate);
+ break;
+ case HCLK_EMMC:
+ case HCLK_SDMMC:
+ case HCLK_SDIO:
+ case SCLK_EMMC:
+ case SCLK_SDMMC:
+ case SCLK_SDIO:
+ new_rate = rk3066_clk_mmc_set_clk(cru, PERI_HCLK_HZ,
+ clk->id, rate);
+ break;
+ case SCLK_SPI0:
+ case SCLK_SPI1:
+ new_rate = rk3066_clk_spi_set_clk(cru, PERI_PCLK_HZ,
+ clk->id, rate);
+ break;
+ case SCLK_SARADC:
+ case SCLK_TSADC:
+ new_rate = rk3066_clk_saradc_set_clk(cru, rate, clk->id);
+ break;
+ case PLL_CPLL:
+ case PLL_GPLL:
+ case ACLK_CPU:
+ case HCLK_CPU:
+ case PCLK_CPU:
+ case ACLK_PERI:
+ case HCLK_PERI:
+ case PCLK_PERI:
+ return 0;
+ default:
+ return -ENOENT;
+ }
+
+ return new_rate;
+}
+
+static int rk3066_clk_enable(struct clk *clk)
+{
+ struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case HCLK_NANDC0:
+ rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(9));
+ break;
+ case HCLK_SDMMC:
+ rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(10));
+ break;
+ case HCLK_SDIO:
+ rk_clrreg(&priv->cru->cru_clkgate_con[5], BIT(11));
+ break;
+ }
+
+ return 0;
+}
+
+static int rk3066_clk_disable(struct clk *clk)
+{
+ struct rk3066_clk_priv *priv = dev_get_priv(clk->dev);
+
+ switch (clk->id) {
+ case HCLK_NANDC0:
+ rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(9));
+ break;
+ case HCLK_SDMMC:
+ rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(10));
+ break;
+ case HCLK_SDIO:
+ rk_setreg(&priv->cru->cru_clkgate_con[5], BIT(11));
+ break;
+ }
+
+ return 0;
+}
+
+static struct clk_ops rk3066_clk_ops = {
+ .disable = rk3066_clk_disable,
+ .enable = rk3066_clk_enable,
+ .get_rate = rk3066_clk_get_rate,
+ .set_rate = rk3066_clk_set_rate,
+};
+
+static int rk3066_clk_of_to_plat(struct udevice *dev)
+{
+ if (CONFIG_IS_ENABLED(OF_REAL)) {
+ struct rk3066_clk_priv *priv = dev_get_priv(dev);
+
+ priv->cru = dev_read_addr_ptr(dev);
+ }
+
+ return 0;
+}
+
+static int rk3066_clk_probe(struct udevice *dev)
+{
+ struct rk3066_clk_priv *priv = dev_get_priv(dev);
+
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(priv->grf))
+ return PTR_ERR(priv->grf);
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3066_clk_plat *plat = dev_get_plat(dev);
+
+ priv->cru = map_sysmem(plat->dtd.reg[0], plat->dtd.reg[1]);
+#endif
+
+ if (IS_ENABLED(CONFIG_TPL_BUILD)) {
+ rk3066_clk_init(priv->cru, priv->grf);
+
+ /* Init CPU frequency. */
+ rk3066_clk_configure_cpu(priv->cru, priv->grf, APLL_SAFE_HZ);
+ }
+
+ return 0;
+}
+
+static int rk3066_clk_bind(struct udevice *dev)
+{
+ struct udevice *sys_child;
+ struct sysreset_reg *priv;
+ int reg_offset, ret;
+
+ /* The reset driver does not have a device node, so bind it here. */
+ ret = device_bind(dev, DM_DRIVER_GET(sysreset_rockchip), "sysreset",
+ NULL, ofnode_null(), &sys_child);
+ if (ret) {
+ dev_dbg(dev, "Warning: No sysreset driver: ret=%d\n", ret);
+ } else {
+ priv = malloc(sizeof(struct sysreset_reg));
+ priv->glb_srst_fst_value = offsetof(struct rk3066_cru,
+ cru_glb_srst_fst_value);
+ priv->glb_srst_snd_value = offsetof(struct rk3066_cru,
+ cru_glb_srst_snd_value);
+ dev_set_priv(sys_child, priv);
+ }
+
+ if (CONFIG_IS_ENABLED(RESET_ROCKCHIP)) {
+ reg_offset = offsetof(struct rk3066_cru, cru_softrst_con[0]);
+ ret = rockchip_reset_bind(dev, reg_offset, 9);
+ if (ret)
+ dev_dbg(dev, "Warning: software reset driver bind failed\n");
+ }
+
+ return 0;
+}
+
+static const struct udevice_id rk3066_clk_ids[] = {
+ { .compatible = "rockchip,rk3066a-cru" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3066a_cru) = {
+ .name = "rockchip_rk3066a_cru",
+ .id = UCLASS_CLK,
+ .ops = &rk3066_clk_ops,
+ .probe = rk3066_clk_probe,
+ .bind = rk3066_clk_bind,
+ .of_match = rk3066_clk_ids,
+ .of_to_plat = rk3066_clk_of_to_plat,
+ .priv_auto = sizeof(struct rk3066_clk_priv),
+ .plat_auto = sizeof(struct rk3066_clk_plat),
+};
From 086863c9829ed17e3a7d0425c63fd2898d6c04a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jarosz?=
Date: Sat, 16 Apr 2022 17:09:40 +0200
Subject: [PATCH 23/48] rockchip: rk3066: add rk3066 pinctrl driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add driver supporting pin multiplexing on rk3066 platform.
Signed-off-by: Paweł Jarosz
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
drivers/pinctrl/rockchip/Makefile | 1 +
drivers/pinctrl/rockchip/pinctrl-rk3066.c | 112 ++++++++++++++++++++++
2 files changed, 113 insertions(+)
create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3066.c
diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index fcf19f877a9..7d03f8101df 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -5,6 +5,7 @@
obj-y += pinctrl-rockchip-core.o
obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o
obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o
+obj-$(CONFIG_ROCKCHIP_RK3066) += pinctrl-rk3066.o
obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) += pinctrl-rk322x.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3066.c b/drivers/pinctrl/rockchip/pinctrl-rk3066.c
new file mode 100644
index 00000000000..598b63223e3
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-rk3066.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Rockchip Electronics Co., Ltd
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "pinctrl-rockchip.h"
+
+static int rk3066_pinctrl_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;
+
+ 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;
+ reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
+
+ data = (mask << (bit + 16));
+ data |= (mux & mask) << bit;
+ ret = regmap_write(regmap, reg, data);
+
+ return ret;
+}
+
+#define RK3066_PULL_OFFSET 0x118
+#define RK3066_PULL_PINS_PER_REG 16
+#define RK3066_PULL_BANK_STRIDE 8
+
+static void rk3066_pinctrl_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;
+
+ *regmap = priv->regmap_base;
+ *reg = RK3066_PULL_OFFSET;
+ *reg += bank->bank_num * RK3066_PULL_BANK_STRIDE;
+ *reg += (pin_num / RK3066_PULL_PINS_PER_REG) * 4;
+
+ *bit = pin_num % RK3066_PULL_PINS_PER_REG;
+};
+
+static int rk3066_pinctrl_set_pull(struct rockchip_pin_bank *bank,
+ int pin_num, int pull)
+{
+ struct regmap *regmap;
+ int reg, ret;
+ u8 bit;
+ u32 data;
+
+ if (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT &&
+ pull != PIN_CONFIG_BIAS_DISABLE)
+ return -EOPNOTSUPP;
+
+ rk3066_pinctrl_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit);
+ data = BIT(bit + 16);
+ if (pull == PIN_CONFIG_BIAS_DISABLE)
+ data |= BIT(bit);
+ ret = regmap_write(regmap, reg, data);
+
+ return ret;
+}
+
+static struct rockchip_pin_bank rk3066_pin_banks[] = {
+ PIN_BANK(0, 32, "gpio0"),
+ PIN_BANK(1, 32, "gpio1"),
+ PIN_BANK(2, 32, "gpio2"),
+ PIN_BANK(3, 32, "gpio3"),
+ PIN_BANK(4, 32, "gpio4"),
+ PIN_BANK(6, 16, "gpio6"),
+};
+
+static struct rockchip_pin_ctrl rk3066_pin_ctrl = {
+ .pin_banks = rk3066_pin_banks,
+ .nr_banks = ARRAY_SIZE(rk3066_pin_banks),
+ .grf_mux_offset = 0xa8,
+ .set_mux = rk3066_pinctrl_set_mux,
+ .set_pull = rk3066_pinctrl_set_pull,
+};
+
+static const struct udevice_id rk3066_pinctrl_ids[] = {
+ {
+ .compatible = "rockchip,rk3066a-pinctrl",
+ .data = (ulong)&rk3066_pin_ctrl
+ },
+ {}
+};
+
+U_BOOT_DRIVER(rockchip_rk3066a_pinctrl) = {
+ .name = "rockchip_rk3066a_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .ops = &rockchip_pinctrl_ops,
+ .probe = rockchip_pinctrl_probe,
+#if CONFIG_IS_ENABLED(OF_REAL)
+ .bind = dm_scan_fdt_dev,
+#endif
+ .of_match = rk3066_pinctrl_ids,
+ .priv_auto = sizeof(struct rockchip_pinctrl_priv),
+};
From 4b957e7ff5024c0e9105af331c3b2dc3073c44e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Jarosz?=
Date: Sat, 16 Apr 2022 17:09:41 +0200
Subject: [PATCH 24/48] rockchip: rk3066: add sdram driver
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add rockchip rk3066 sdram driver
Signed-off-by: Paweł Jarosz
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
drivers/ram/rockchip/Makefile | 1 +
drivers/ram/rockchip/sdram_rk3066.c | 892 ++++++++++++++++++++++++++++
2 files changed, 893 insertions(+)
create mode 100644 drivers/ram/rockchip/sdram_rk3066.c
diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index ca1c289b884..6d530c29afd 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_ROCKCHIP_PX30) += sdram_px30.o sdram_pctl_px30.o sdram_phy_px30.o
obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
+obj-$(CONFIG_ROCKCHIP_RK3066) = sdram_rk3066.o
obj-$(CONFIG_ROCKCHIP_RK3128) = sdram_rk3128.o
obj-$(CONFIG_ROCKCHIP_RK3188) = sdram_rk3188.o
obj-$(CONFIG_ROCKCHIP_RK322X) = sdram_rk322x.o
diff --git a/drivers/ram/rockchip/sdram_rk3066.c b/drivers/ram/rockchip/sdram_rk3066.c
new file mode 100644
index 00000000000..832154ee3af
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_rk3066.c
@@ -0,0 +1,892 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Copyright 2014 Rockchip Inc.
+ *
+ * Adapted from the very similar rk3188 ddr init.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct rk3066_dmc_chan_info {
+ struct rk3288_ddr_pctl *pctl;
+ struct rk3288_ddr_publ *publ;
+ struct rk3188_msch *msch;
+};
+
+struct rk3066_dmc_dram_info {
+ struct rk3066_dmc_chan_info chan[1];
+ struct ram_info info;
+ struct clk ddr_clk;
+ struct rk3066_cru *cru;
+ struct rk3066_grf *grf;
+ struct rk3066_sgrf *sgrf;
+ struct rk3188_pmu *pmu;
+};
+
+struct rk3066_dmc_sdram_params {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct dtd_rockchip_rk3066_dmc of_plat;
+#endif
+ struct rk3288_sdram_channel ch[2];
+ struct rk3288_sdram_pctl_timing pctl_timing;
+ struct rk3288_sdram_phy_timing phy_timing;
+ struct rk3288_base_params base;
+ int num_channels;
+ struct regmap *map;
+};
+
+const int rk3066_dmc_ddrconf_table[] = {
+ /*
+ * [5:4] row(13+n)
+ * [1:0] col(9+n), assume bw=2
+ * row col,bw
+ */
+ 0,
+ (2 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
+ (1 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
+ (0 << DDRCONF_ROW_SHIFT) | 1 << DDRCONF_COL_SHIFT,
+ (2 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
+ (1 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
+ (0 << DDRCONF_ROW_SHIFT) | 2 << DDRCONF_COL_SHIFT,
+ (1 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT,
+ (0 << DDRCONF_ROW_SHIFT) | 0 << DDRCONF_COL_SHIFT,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+};
+
+#define TEST_PATTERN 0x5aa5f00f
+#define DQS_GATE_TRAINING_ERROR_RANK0 BIT(4)
+#define DQS_GATE_TRAINING_ERROR_RANK1 BIT(5)
+
+static void rk3066_dmc_copy_to_reg(u32 *dest, const u32 *src, u32 n)
+{
+ int i;
+
+ for (i = 0; i < n / sizeof(u32); i++) {
+ writel(*src, dest);
+ src++;
+ dest++;
+ }
+}
+
+static void rk3066_dmc_ddr_reset(struct rk3066_cru *cru, u32 ch, u32 ctl, u32 phy)
+{
+ u32 phy_ctl_srstn_shift = 13;
+ u32 ctl_psrstn_shift = 11;
+ u32 ctl_srstn_shift = 10;
+ u32 phy_psrstn_shift = 9;
+ u32 phy_srstn_shift = 8;
+
+ rk_clrsetreg(&cru->cru_softrst_con[5],
+ 1 << phy_ctl_srstn_shift | 1 << ctl_psrstn_shift |
+ 1 << ctl_srstn_shift | 1 << phy_psrstn_shift |
+ 1 << phy_srstn_shift,
+ phy << phy_ctl_srstn_shift | ctl << ctl_psrstn_shift |
+ ctl << ctl_srstn_shift | phy << phy_psrstn_shift |
+ phy << phy_srstn_shift);
+}
+
+static void rk3066_dmc_ddr_phy_ctl_reset(struct rk3066_cru *cru, u32 ch, u32 n)
+{
+ u32 phy_ctl_srstn_shift = 13;
+
+ rk_clrsetreg(&cru->cru_softrst_con[5],
+ 1 << phy_ctl_srstn_shift, n << phy_ctl_srstn_shift);
+}
+
+static void rk3066_dmc_phy_pctrl_reset(struct rk3066_cru *cru,
+ struct rk3288_ddr_publ *publ,
+ int channel)
+{
+ int i;
+
+ rk3066_dmc_ddr_reset(cru, channel, 1, 1);
+ udelay(1);
+ clrbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+ for (i = 0; i < 4; i++)
+ clrbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+ udelay(10);
+ setbits_le32(&publ->acdllcr, ACDLLCR_DLLSRST);
+ for (i = 0; i < 4; i++)
+ setbits_le32(&publ->datx8[i].dxdllcr, DXDLLCR_DLLSRST);
+
+ udelay(10);
+ rk3066_dmc_ddr_reset(cru, channel, 1, 0);
+ udelay(10);
+ rk3066_dmc_ddr_reset(cru, channel, 0, 0);
+ udelay(10);
+}
+
+static void rk3066_dmc_phy_dll_bypass_set(struct rk3288_ddr_publ *publ, u32 freq)
+{
+ int i;
+
+ if (freq <= 250000000) {
+ if (freq <= 150000000)
+ clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+ else
+ setbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+ setbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+ for (i = 0; i < 4; i++)
+ setbits_le32(&publ->datx8[i].dxdllcr,
+ DXDLLCR_DLLDIS);
+
+ setbits_le32(&publ->pir, PIR_DLLBYP);
+ } else {
+ clrbits_le32(&publ->dllgcr, SBIAS_BYPASS);
+ clrbits_le32(&publ->acdllcr, ACDLLCR_DLLDIS);
+ for (i = 0; i < 4; i++) {
+ clrbits_le32(&publ->datx8[i].dxdllcr,
+ DXDLLCR_DLLDIS);
+ }
+
+ clrbits_le32(&publ->pir, PIR_DLLBYP);
+ }
+}
+
+static void rk3066_dmc_dfi_cfg(struct rk3288_ddr_pctl *pctl, u32 dramtype)
+{
+ writel(DFI_INIT_START, &pctl->dfistcfg0);
+ writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN,
+ &pctl->dfistcfg1);
+ writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
+ writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
+ &pctl->dfilpcfg0);
+
+ writel(2 << TCTRL_DELAY_TIME_SHIFT, &pctl->dfitctrldelay);
+ writel(1 << TPHY_WRDATA_TIME_SHIFT, &pctl->dfitphywrdata);
+ writel(0xf << TPHY_RDLAT_TIME_SHIFT, &pctl->dfitphyrdlat);
+ writel(2 << TDRAM_CLK_DIS_TIME_SHIFT, &pctl->dfitdramclkdis);
+ writel(2 << TDRAM_CLK_EN_TIME_SHIFT, &pctl->dfitdramclken);
+ writel(1, &pctl->dfitphyupdtype0);
+
+ /* CS0 and CS1 write ODT enable. */
+ writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
+ &pctl->dfiodtcfg);
+ /* Write ODT length. */
+ writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
+ /* Disable phyupd and ctrlupd. */
+ writel(0, &pctl->dfiupdcfg);
+}
+
+static void rk3066_dmc_ddr_set_ddr3_mode(struct rk3066_grf *grf, uint channel,
+ bool ddr3_mode)
+{
+ uint mask, val;
+
+ mask = MSCH4_MAINDDR3_MASK << MSCH4_MAINDDR3_SHIFT;
+ val = ddr3_mode << MSCH4_MAINDDR3_SHIFT;
+ rk_clrsetreg(&grf->soc_con2, mask, val);
+}
+
+static void rk3066_dmc_ddr_rank_2_row15en(struct rk3066_grf *grf, bool enable)
+{
+ uint mask, val;
+
+ mask = RANK_TO_ROW15_EN_MASK << RANK_TO_ROW15_EN_SHIFT;
+ val = enable << RANK_TO_ROW15_EN_SHIFT;
+ rk_clrsetreg(&grf->soc_con2, mask, val);
+}
+
+static void rk3066_dmc_pctl_cfg(int channel, struct rk3288_ddr_pctl *pctl,
+ struct rk3066_dmc_sdram_params *sdram_params,
+ struct rk3066_grf *grf)
+{
+ rk3066_dmc_copy_to_reg(&pctl->togcnt1u, &sdram_params->pctl_timing.togcnt1u,
+ sizeof(sdram_params->pctl_timing));
+ switch (sdram_params->base.dramtype) {
+ case DDR3:
+ if (sdram_params->phy_timing.mr[1] & DDR3_DLL_DISABLE) {
+ writel(sdram_params->pctl_timing.tcl - 3,
+ &pctl->dfitrddataen);
+ } else {
+ writel(sdram_params->pctl_timing.tcl - 2,
+ &pctl->dfitrddataen);
+ }
+ writel(sdram_params->pctl_timing.tcwl - 1,
+ &pctl->dfitphywrlat);
+ writel(0 << MDDR_LPDDR2_CLK_STOP_IDLE_SHIFT | DDR3_EN |
+ DDR2_DDR3_BL_8 | (6 - 4) << TFAW_SHIFT | PD_EXIT_SLOW |
+ 1 << PD_TYPE_SHIFT | 0 << PD_IDLE_SHIFT,
+ &pctl->mcfg);
+ rk3066_dmc_ddr_set_ddr3_mode(grf, channel, true);
+ break;
+ }
+
+ setbits_le32(&pctl->scfg, 1);
+}
+
+static void rk3066_dmc_phy_cfg(const struct rk3066_dmc_chan_info *chan, int channel,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3188_msch *msch = chan->msch;
+ uint ddr_freq_mhz = sdram_params->base.ddr_freq / 1000000;
+ u32 dinit2;
+ int i;
+
+ dinit2 = DIV_ROUND_UP(ddr_freq_mhz * 200000, 1000);
+ /* Set DDR PHY timing. */
+ rk3066_dmc_copy_to_reg(&publ->dtpr[0], &sdram_params->phy_timing.dtpr0,
+ sizeof(sdram_params->phy_timing));
+ writel(sdram_params->base.noc_timing, &msch->ddrtiming);
+ writel(0x3f, &msch->readlatency);
+ writel(DIV_ROUND_UP(ddr_freq_mhz * 5120, 1000) << PRT_DLLLOCK_SHIFT |
+ DIV_ROUND_UP(ddr_freq_mhz * 50, 1000) << PRT_DLLSRST_SHIFT |
+ 8 << PRT_ITMSRST_SHIFT, &publ->ptr[0]);
+ writel(DIV_ROUND_UP(ddr_freq_mhz * 500000, 1000) << PRT_DINIT0_SHIFT |
+ DIV_ROUND_UP(ddr_freq_mhz * 400, 1000) << PRT_DINIT1_SHIFT,
+ &publ->ptr[1]);
+ writel(min(dinit2, 0x1ffffU) << PRT_DINIT2_SHIFT |
+ DIV_ROUND_UP(ddr_freq_mhz * 1000, 1000) << PRT_DINIT3_SHIFT,
+ &publ->ptr[2]);
+
+ switch (sdram_params->base.dramtype) {
+ case DDR3:
+ clrbits_le32(&publ->pgcr, 0x1f);
+ clrsetbits_le32(&publ->dcr, DDRMD_MASK << DDRMD_SHIFT,
+ DDRMD_DDR3 << DDRMD_SHIFT);
+ break;
+ }
+ if (sdram_params->base.odt) {
+ /* Enable dynamic RTT. */
+ for (i = 0; i < 4; i++)
+ setbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+ } else {
+ /* Disable dynamic RTT. */
+ for (i = 0; i < 4; i++)
+ clrbits_le32(&publ->datx8[i].dxgcr, DQSRTT | DQRTT);
+ }
+}
+
+static void rk3066_dmc_phy_init(struct rk3288_ddr_publ *publ)
+{
+ setbits_le32(&publ->pir, PIR_INIT | PIR_DLLSRST
+ | PIR_DLLLOCK | PIR_ZCAL | PIR_ITMSRST | PIR_CLRSR);
+ udelay(1);
+ while ((readl(&publ->pgsr) &
+ (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE)) !=
+ (PGSR_IDONE | PGSR_DLDONE | PGSR_ZCDONE))
+ ;
+}
+
+static void rk3066_dmc_send_command(struct rk3288_ddr_pctl *pctl, u32 rank,
+ u32 cmd, u32 arg)
+{
+ writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+ udelay(1);
+ while (readl(&pctl->mcmd) & START_CMD)
+ ;
+}
+
+static inline void rk3066_dmc_send_command_op(struct rk3288_ddr_pctl *pctl,
+ u32 rank, u32 cmd, u32 ma, u32 op)
+{
+ rk3066_dmc_send_command(pctl, rank, cmd, (ma & LPDDR2_MA_MASK) << LPDDR2_MA_SHIFT |
+ (op & LPDDR2_OP_MASK) << LPDDR2_OP_SHIFT);
+}
+
+static void rk3066_dmc_memory_init(struct rk3288_ddr_publ *publ,
+ u32 dramtype)
+{
+ setbits_le32(&publ->pir,
+ (PIR_INIT | PIR_DRAMINIT | PIR_LOCKBYP
+ | PIR_ZCALBYP | PIR_CLRSR | PIR_ICPC
+ | (dramtype == DDR3 ? PIR_DRAMRST : 0)));
+ udelay(1);
+ while ((readl(&publ->pgsr) & (PGSR_IDONE | PGSR_DLDONE))
+ != (PGSR_IDONE | PGSR_DLDONE))
+ ;
+}
+
+static void rk3066_dmc_move_to_config_state(struct rk3288_ddr_publ *publ,
+ struct rk3288_ddr_pctl *pctl)
+{
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK)
+ != ACCESS)
+ ;
+ /* Wait DLL lock. */
+ while ((readl(&publ->pgsr) & PGSR_DLDONE)
+ != PGSR_DLDONE)
+ ;
+ /*
+ * If at low power state we need to wakeup first
+ * and then enter the config.
+ */
+ fallthrough;
+ case ACCESS:
+ fallthrough;
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+ ;
+ break;
+ case CONFIG:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void rk3066_dmc_set_bandwidth_ratio(const struct rk3066_dmc_chan_info *chan, int channel,
+ u32 n, struct rk3066_grf *grf)
+{
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3188_msch *msch = chan->msch;
+
+ if (n == 1) {
+ setbits_le32(&pctl->ppcfg, 1);
+ setbits_le32(&msch->ddrtiming, 1 << 31);
+ /* Data byte disable. */
+ clrbits_le32(&publ->datx8[2].dxgcr, 1);
+ clrbits_le32(&publ->datx8[3].dxgcr, 1);
+ /* Disable DLL. */
+ setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+ setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+ } else {
+ clrbits_le32(&pctl->ppcfg, 1);
+ clrbits_le32(&msch->ddrtiming, 1 << 31);
+ /* Data byte enable.*/
+ setbits_le32(&publ->datx8[2].dxgcr, 1);
+ setbits_le32(&publ->datx8[3].dxgcr, 1);
+
+ /* Enable DLL. */
+ clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLDIS);
+ clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLDIS);
+ /* Reset DLL. */
+ clrbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+ clrbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+ udelay(10);
+ setbits_le32(&publ->datx8[2].dxdllcr, DXDLLCR_DLLSRST);
+ setbits_le32(&publ->datx8[3].dxdllcr, DXDLLCR_DLLSRST);
+ }
+ setbits_le32(&pctl->dfistcfg0, 1 << 2);
+}
+
+static int rk3066_dmc_data_training(const struct rk3066_dmc_chan_info *chan, int channel,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ unsigned int j;
+ int ret = 0;
+ u32 rank;
+ int i;
+ u32 step[2] = { PIR_QSTRN, PIR_RVTRN };
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+
+ /* Disable auto refresh. */
+ writel(0, &pctl->trefi);
+
+ if (sdram_params->base.dramtype != LPDDR3)
+ setbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+ rank = sdram_params->ch[channel].rank | 1;
+ for (j = 0; j < ARRAY_SIZE(step); j++) {
+ /*
+ * Trigger QSTRN and RVTRN.
+ * Clear DTDONE status.
+ */
+ setbits_le32(&publ->pir, PIR_CLRSR);
+
+ /* Trigger DTT. */
+ setbits_le32(&publ->pir,
+ PIR_INIT | step[j] | PIR_LOCKBYP | PIR_ZCALBYP |
+ PIR_CLRSR);
+ udelay(1);
+ /* Wait echo byte DTDONE. */
+ while ((readl(&publ->datx8[0].dxgsr[0]) & rank)
+ != rank)
+ ;
+ while ((readl(&publ->datx8[1].dxgsr[0]) & rank)
+ != rank)
+ ;
+ if (!(readl(&pctl->ppcfg) & 1)) {
+ while ((readl(&publ->datx8[2].dxgsr[0])
+ & rank) != rank)
+ ;
+ while ((readl(&publ->datx8[3].dxgsr[0])
+ & rank) != rank)
+ ;
+ }
+ if (readl(&publ->pgsr) &
+ (PGSR_DTERR | PGSR_RVERR | PGSR_RVEIRR)) {
+ ret = -1;
+ break;
+ }
+ }
+ /* Send some auto refresh to complement the lost while DTT. */
+ for (i = 0; i < (rank > 1 ? 8 : 4); i++)
+ rk3066_dmc_send_command(pctl, rank, REF_CMD, 0);
+
+ if (sdram_params->base.dramtype != LPDDR3)
+ clrbits_le32(&publ->pgcr, 1 << PGCR_DQSCFG_SHIFT);
+
+ /* Resume auto refresh. */
+ writel(sdram_params->pctl_timing.trefi, &pctl->trefi);
+
+ return ret;
+}
+
+static void rk3066_dmc_move_to_access_state(const struct rk3066_dmc_chan_info *chan)
+{
+ struct rk3288_ddr_publ *publ = chan->publ;
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ unsigned int state;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MSK;
+
+ switch (state) {
+ case LOW_POWER:
+ if (((readl(&pctl->stat) >> LP_TRIG_SHIFT) &
+ LP_TRIG_MASK) == 1)
+ return;
+
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) != ACCESS)
+ ;
+ /* Wait DLL lock. */
+ while ((readl(&publ->pgsr) & PGSR_DLDONE)
+ != PGSR_DLDONE)
+ ;
+ break;
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) != CONFIG)
+ ;
+ fallthrough;
+ case CONFIG:
+ writel(GO_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MSK) == CONFIG)
+ ;
+ break;
+ case ACCESS:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void rk3066_dmc_dram_cfg_rbc(const struct rk3066_dmc_chan_info *chan, u32 chnum,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ struct rk3288_ddr_publ *publ = chan->publ;
+
+ if (sdram_params->ch[chnum].bk == 3)
+ clrsetbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT,
+ 1 << PDQ_SHIFT);
+ else
+ clrbits_le32(&publ->dcr, PDQ_MASK << PDQ_SHIFT);
+
+ writel(sdram_params->base.ddrconfig, &chan->msch->ddrconf);
+}
+
+static void rk3066_dmc_dram_all_config(const struct rk3066_dmc_dram_info *dram,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ unsigned int chan;
+ u32 sys_reg = 0;
+
+ sys_reg |= sdram_params->base.dramtype << SYS_REG_DDRTYPE_SHIFT;
+ sys_reg |= (sdram_params->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
+ for (chan = 0; chan < sdram_params->num_channels; chan++) {
+ const struct rk3288_sdram_channel *info =
+ &sdram_params->ch[chan];
+
+ sys_reg |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(chan);
+ sys_reg |= 1 << SYS_REG_CHINFO_SHIFT(chan);
+ sys_reg |= (info->rank - 1) << SYS_REG_RANK_SHIFT(chan);
+ sys_reg |= (info->col - 9) << SYS_REG_COL_SHIFT(chan);
+ sys_reg |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(chan);
+ sys_reg |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(chan);
+ sys_reg |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(chan);
+ sys_reg |= (2 >> info->bw) << SYS_REG_BW_SHIFT(chan);
+ sys_reg |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(chan);
+
+ rk3066_dmc_dram_cfg_rbc(&dram->chan[chan], chan, sdram_params);
+ }
+ if (sdram_params->ch[0].rank == 2)
+ rk3066_dmc_ddr_rank_2_row15en(dram->grf, 0);
+ else
+ rk3066_dmc_ddr_rank_2_row15en(dram->grf, 1);
+
+ writel(sys_reg, &dram->pmu->sys_reg[2]);
+}
+
+static int rk3066_dmc_sdram_rank_bw_detect(struct rk3066_dmc_dram_info *dram, int channel,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ int reg;
+ int need_trainig = 0;
+ const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
+ struct rk3288_ddr_publ *publ = chan->publ;
+
+ rk3066_dmc_ddr_rank_2_row15en(dram->grf, 0);
+
+ if (rk3066_dmc_data_training(chan, channel, sdram_params) < 0) {
+ debug("first data training fail!\n");
+ reg = readl(&publ->datx8[0].dxgsr[0]);
+ /* Check the result for rank 0. */
+ if (channel == 0 && (reg & DQS_GATE_TRAINING_ERROR_RANK0)) {
+ debug("data training fail!\n");
+ return -EIO;
+ }
+
+ /* Check the result for rank 1. */
+ if (reg & DQS_GATE_TRAINING_ERROR_RANK1) {
+ sdram_params->ch[channel].rank = 1;
+ clrsetbits_le32(&publ->pgcr, 0xF << 18,
+ sdram_params->ch[channel].rank << 18);
+ need_trainig = 1;
+ }
+ reg = readl(&publ->datx8[2].dxgsr[0]);
+ if (reg & (1 << 4)) {
+ sdram_params->ch[channel].bw = 1;
+ rk3066_dmc_set_bandwidth_ratio(chan, channel,
+ sdram_params->ch[channel].bw,
+ dram->grf);
+ need_trainig = 1;
+ }
+ }
+ /* Assume that the die bit width is equel to the chip bit width. */
+ sdram_params->ch[channel].dbw = sdram_params->ch[channel].bw;
+
+ if (need_trainig &&
+ (rk3066_dmc_data_training(chan, channel, sdram_params) < 0)) {
+ if (sdram_params->base.dramtype == LPDDR3) {
+ rk3066_dmc_ddr_phy_ctl_reset(dram->cru, channel, 1);
+ udelay(10);
+ rk3066_dmc_ddr_phy_ctl_reset(dram->cru, channel, 0);
+ udelay(10);
+ }
+ debug("2nd data training failed!");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int rk3066_dmc_sdram_col_row_detect(struct rk3066_dmc_dram_info *dram, int channel,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ int row, col;
+ unsigned int addr;
+ const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ struct rk3288_ddr_publ *publ = chan->publ;
+ int ret = 0;
+
+ /* Detect col. */
+ for (col = 11; col >= 9; col--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ addr = CONFIG_SYS_SDRAM_BASE +
+ (1 << (col + sdram_params->ch[channel].bw - 1));
+ writel(TEST_PATTERN, addr);
+ if ((readl(addr) == TEST_PATTERN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (col == 8) {
+ debug("Col detect error\n");
+ ret = -EINVAL;
+ goto out;
+ } else {
+ sdram_params->ch[channel].col = col;
+ }
+
+ rk3066_dmc_ddr_rank_2_row15en(dram->grf, 1);
+ rk3066_dmc_move_to_config_state(publ, pctl);
+ writel(1, &chan->msch->ddrconf);
+ rk3066_dmc_move_to_access_state(chan);
+ /* Detect row, max 15, min13 for rk3066 */
+ for (row = 16; row >= 13; row--) {
+ writel(0, CONFIG_SYS_SDRAM_BASE);
+ addr = CONFIG_SYS_SDRAM_BASE + (1 << (row + 15 - 1));
+ writel(TEST_PATTERN, addr);
+ if ((readl(addr) == TEST_PATTERN) &&
+ (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+ break;
+ }
+ if (row == 12) {
+ debug("Row detect error\n");
+ ret = -EINVAL;
+ } else {
+ sdram_params->ch[channel].cs1_row = row;
+ sdram_params->ch[channel].row_3_4 = 0;
+ debug("chn %d col %d, row %d\n", channel, col, row);
+ sdram_params->ch[channel].cs0_row = row;
+ }
+
+out:
+ return ret;
+}
+
+static int rk3066_dmc_sdram_get_niu_config(struct rk3066_dmc_sdram_params *sdram_params)
+{
+ int i, tmp, size, ret = 0;
+
+ tmp = sdram_params->ch[0].col - 9;
+ tmp -= (sdram_params->ch[0].bw == 2) ? 0 : 1;
+ tmp |= ((sdram_params->ch[0].cs0_row - 13) << 4);
+ size = ARRAY_SIZE(rk3066_dmc_ddrconf_table) / sizeof(rk3066_dmc_ddrconf_table[0]);
+ for (i = 0; i < size; i++)
+ if (tmp == rk3066_dmc_ddrconf_table[i])
+ break;
+ if (i >= size) {
+ debug("niu config not found\n");
+ ret = -EINVAL;
+ } else {
+ debug("niu config %d\n", i);
+ sdram_params->base.ddrconfig = i;
+ }
+
+ return ret;
+}
+
+static int rk3066_dmc_sdram_init(struct rk3066_dmc_dram_info *dram,
+ struct rk3066_dmc_sdram_params *sdram_params)
+{
+ int channel;
+ int zqcr;
+ int ret;
+
+ if ((sdram_params->base.dramtype == DDR3 &&
+ sdram_params->base.ddr_freq > 800000000)) {
+ debug("SDRAM frequency is too high!");
+ return -E2BIG;
+ }
+
+ ret = clk_set_rate(&dram->ddr_clk, sdram_params->base.ddr_freq);
+ if (ret) {
+ debug("Could not set DDR clock\n");
+ return ret;
+ }
+
+ for (channel = 0; channel < 1; channel++) {
+ const struct rk3066_dmc_chan_info *chan = &dram->chan[channel];
+ struct rk3288_ddr_pctl *pctl = chan->pctl;
+ struct rk3288_ddr_publ *publ = chan->publ;
+
+ rk3066_dmc_phy_pctrl_reset(dram->cru, publ, channel);
+ rk3066_dmc_phy_dll_bypass_set(publ, sdram_params->base.ddr_freq);
+
+ rk3066_dmc_dfi_cfg(pctl, sdram_params->base.dramtype);
+
+ rk3066_dmc_pctl_cfg(channel, pctl, sdram_params, dram->grf);
+
+ rk3066_dmc_phy_cfg(chan, channel, sdram_params);
+
+ rk3066_dmc_phy_init(publ);
+
+ writel(POWER_UP_START, &pctl->powctl);
+ while (!(readl(&pctl->powstat) & POWER_UP_DONE))
+ ;
+
+ rk3066_dmc_memory_init(publ, sdram_params->base.dramtype);
+ rk3066_dmc_move_to_config_state(publ, pctl);
+
+ /* Use 32bit bus width for detection. */
+ sdram_params->ch[channel].bw = 2;
+ rk3066_dmc_set_bandwidth_ratio(chan, channel,
+ sdram_params->ch[channel].bw, dram->grf);
+ /*
+ * set cs, using n=3 for detect
+ * CS0, n=1
+ * CS1, n=2
+ * CS0 & CS1, n = 3
+ */
+ sdram_params->ch[channel].rank = 2;
+ clrsetbits_le32(&publ->pgcr, 0xF << 18,
+ (sdram_params->ch[channel].rank | 1) << 18);
+
+ /* DS=40ohm,ODT=155ohm */
+ zqcr = 1 << ZDEN_SHIFT | 2 << PU_ONDIE_SHIFT |
+ 2 << PD_ONDIE_SHIFT | 0x19 << PU_OUTPUT_SHIFT |
+ 0x19 << PD_OUTPUT_SHIFT;
+ writel(zqcr, &publ->zq1cr[0]);
+ writel(zqcr, &publ->zq0cr[0]);
+
+ /* Detect the rank and bit-width with data-training. */
+ writel(1, &chan->msch->ddrconf);
+ rk3066_dmc_sdram_rank_bw_detect(dram, channel, sdram_params);
+
+ if (sdram_params->base.dramtype == LPDDR3) {
+ u32 i;
+
+ writel(0, &pctl->mrrcfg0);
+
+ for (i = 0; i < 17; i++)
+ rk3066_dmc_send_command_op(pctl, 1, MRR_CMD, i, 0);
+ }
+ writel(4, &chan->msch->ddrconf);
+ rk3066_dmc_move_to_access_state(chan);
+ /* DDR3 and LPDDR3 are always 8 bank, no need to detect. */
+ sdram_params->ch[channel].bk = 3;
+ /* Detect Col and Row number. */
+ ret = rk3066_dmc_sdram_col_row_detect(dram, channel, sdram_params);
+ if (ret)
+ goto error;
+ }
+ /* Find NIU DDR configuration. */
+ ret = rk3066_dmc_sdram_get_niu_config(sdram_params);
+ if (ret)
+ goto error;
+
+ rk3066_dmc_dram_all_config(dram, sdram_params);
+ debug("SDRAM init OK!\n");
+
+ return 0;
+error:
+ debug("SDRAM init failed!\n");
+ hang();
+}
+
+static int rk3066_dmc_setup_sdram(struct udevice *dev)
+{
+ struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
+ struct rk3066_dmc_sdram_params *params = dev_get_plat(dev);
+
+ return rk3066_dmc_sdram_init(priv, params);
+}
+
+static int rk3066_dmc_conv_of_plat(struct udevice *dev)
+{
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+ struct rk3066_dmc_sdram_params *plat = dev_get_plat(dev);
+ struct dtd_rockchip_rk3066_dmc *of_plat = &plat->of_plat;
+ int ret;
+
+ memcpy(&plat->pctl_timing, of_plat->rockchip_pctl_timing,
+ sizeof(plat->pctl_timing));
+ memcpy(&plat->phy_timing, of_plat->rockchip_phy_timing,
+ sizeof(plat->phy_timing));
+ memcpy(&plat->base, of_plat->rockchip_sdram_params, sizeof(plat->base));
+ /* RK3066 supports dual-channel, set default channel num to 2. */
+ plat->num_channels = 1;
+ ret = regmap_init_mem_plat(dev, of_plat->reg,
+ ARRAY_SIZE(of_plat->reg) / 2, &plat->map);
+ if (ret)
+ return ret;
+
+ return 0;
+#else
+ return -EINVAL;
+#endif
+}
+
+static int rk3066_dmc_probe(struct udevice *dev)
+{
+ struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
+
+ priv->pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
+
+ if (IS_ENABLED(CONFIG_TPL_BUILD)) {
+ struct rk3066_dmc_sdram_params *plat = dev_get_plat(dev);
+ struct regmap *map;
+ struct udevice *dev_clk;
+ int ret;
+
+ ret = rk3066_dmc_conv_of_plat(dev);
+ if (ret)
+ return ret;
+
+ map = syscon_get_regmap_by_driver_data(ROCKCHIP_SYSCON_NOC);
+ if (IS_ERR(map))
+ return PTR_ERR(map);
+ priv->chan[0].msch = regmap_get_range(map, 0);
+ priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+ priv->chan[0].pctl = regmap_get_range(plat->map, 0);
+ priv->chan[0].publ = regmap_get_range(plat->map, 1);
+
+ ret = rockchip_get_clk(&dev_clk);
+ if (ret)
+ return ret;
+
+ priv->ddr_clk.id = CLK_DDR;
+ ret = clk_request(dev_clk, &priv->ddr_clk);
+ if (ret)
+ return ret;
+
+ priv->cru = rockchip_get_cru();
+ if (IS_ERR(priv->cru))
+ return PTR_ERR(priv->cru);
+
+ ret = rk3066_dmc_setup_sdram(dev);
+ if (ret)
+ return ret;
+ } else {
+ priv->info.base = CONFIG_SYS_SDRAM_BASE;
+ priv->info.size = rockchip_sdram_size((phys_addr_t)&priv->pmu->sys_reg[2]);
+ }
+
+ return 0;
+}
+
+static int rk3066_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct rk3066_dmc_dram_info *priv = dev_get_priv(dev);
+
+ *info = priv->info;
+
+ return 0;
+}
+
+static struct ram_ops rk3066_dmc_ops = {
+ .get_info = rk3066_dmc_get_info,
+};
+
+static const struct udevice_id rk3066_dmc_ids[] = {
+ { .compatible = "rockchip,rk3066-dmc" },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3066_dmc) = {
+ .name = "rockchip_rk3066_dmc",
+ .id = UCLASS_RAM,
+ .ops = &rk3066_dmc_ops,
+ .probe = rk3066_dmc_probe,
+ .of_match = rk3066_dmc_ids,
+ .priv_auto = sizeof(struct rk3066_dmc_dram_info),
+#if IS_ENABLED(CONFIG_TPL_BUILD)
+ .plat_auto = sizeof(struct rk3066_dmc_sdram_params),
+#endif
+};
From c9b0051d67f133f0002ed4542fa84c9e3d99ca09 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:42 +0200
Subject: [PATCH 25/48] arm: dts: rockchip: fix rk3xxx-u-boot.dtsi
The file rk3xxx-u-boot.dtsi was original only for rk3188 and SPL.
With rk3066 added some nodes are also needed in TPL,
so change them to u-boot,dm-pre-reloc
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/dts/rk3xxx-u-boot.dtsi | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/dts/rk3xxx-u-boot.dtsi b/arch/arm/dts/rk3xxx-u-boot.dtsi
index 581594c35d3..e67432fb392 100644
--- a/arch/arm/dts/rk3xxx-u-boot.dtsi
+++ b/arch/arm/dts/rk3xxx-u-boot.dtsi
@@ -4,7 +4,7 @@
noc: syscon@10128000 {
compatible = "rockchip,rk3188-noc", "syscon";
reg = <0x10128000 0x2000>;
- u-boot,dm-spl;
+ u-boot,dm-pre-reloc;
};
dmc: dmc@20020000 {
@@ -18,16 +18,16 @@
rockchip,grf = <&grf>;
rockchip,pmu = <&pmu>;
rockchip,noc = <&noc>;
- u-boot,dm-spl;
+ u-boot,dm-pre-reloc;
};
};
&grf {
- u-boot,dm-spl;
+ u-boot,dm-pre-reloc;
};
&pmu {
- u-boot,dm-spl;
+ u-boot,dm-pre-reloc;
};
&uart2 {
From 65a28bc4db01ceed1593ced1076b6507af8a728f Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:43 +0200
Subject: [PATCH 26/48] arm: dts: rockchip: fix include rk3xxx-u-boot.dtsi
Move the include for rk3xxx-u-boot.dtsi to rk3188-u-boot.dtsi
to stay in line with U-boot dtsi files.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/dts/rk3188-u-boot.dtsi | 1 +
arch/arm/dts/rk3188.dtsi | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/rk3188-u-boot.dtsi b/arch/arm/dts/rk3188-u-boot.dtsi
index 43f05b9876d..735776c16b8 100644
--- a/arch/arm/dts/rk3188-u-boot.dtsi
+++ b/arch/arm/dts/rk3188-u-boot.dtsi
@@ -4,6 +4,7 @@
*/
#include "rockchip-u-boot.dtsi"
+#include "rk3xxx-u-boot.dtsi"
&global_timer {
status = "okay";
diff --git a/arch/arm/dts/rk3188.dtsi b/arch/arm/dts/rk3188.dtsi
index 6c1c2ff5339..6764776cce1 100644
--- a/arch/arm/dts/rk3188.dtsi
+++ b/arch/arm/dts/rk3188.dtsi
@@ -9,7 +9,6 @@
#include
#include
#include "rk3xxx.dtsi"
-#include "rk3xxx-u-boot.dtsi"
/ {
compatible = "rockchip,rk3188";
From b08f32c1595eacdbb2ae1be0c15edc1a63227e81 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:44 +0200
Subject: [PATCH 27/48] arm: dts: rockchip: add rk3066a.dtsi
In the Linux DT the file rk3xxx.dtsi is shared between
rk3066 and rk3188. Add rk3066a.dtsi. Move U-boot specific
things in a rk3066a-u-boot.dtsi file.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/dts/rk3066a-u-boot.dtsi | 4 +
arch/arm/dts/rk3066a.dtsi | 879 +++++++++++++++++++++++++++++++
2 files changed, 883 insertions(+)
create mode 100644 arch/arm/dts/rk3066a-u-boot.dtsi
create mode 100644 arch/arm/dts/rk3066a.dtsi
diff --git a/arch/arm/dts/rk3066a-u-boot.dtsi b/arch/arm/dts/rk3066a-u-boot.dtsi
new file mode 100644
index 00000000000..bc6e609d02b
--- /dev/null
+++ b/arch/arm/dts/rk3066a-u-boot.dtsi
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include "rockchip-u-boot.dtsi"
+#include "rk3xxx-u-boot.dtsi"
diff --git a/arch/arm/dts/rk3066a.dtsi b/arch/arm/dts/rk3066a.dtsi
new file mode 100644
index 00000000000..c25b9695db4
--- /dev/null
+++ b/arch/arm/dts/rk3066a.dtsi
@@ -0,0 +1,879 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2013 MundoReader S.L.
+ * Author: Heiko Stuebner
+ */
+
+#include
+#include
+#include
+#include
+#include "rk3xxx.dtsi"
+
+/ {
+ compatible = "rockchip,rk3066a";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "rockchip,rk3066-smp";
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x0>;
+ operating-points =
+ /* kHz uV */
+ <1416000 1300000>,
+ <1200000 1175000>,
+ <1008000 1125000>,
+ <816000 1125000>,
+ <600000 1100000>,
+ <504000 1100000>,
+ <312000 1075000>;
+ clock-latency = <40000>;
+ clocks = <&cru ARMCLK>;
+ };
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a9";
+ next-level-cache = <&L2>;
+ reg = <0x1>;
+ };
+ };
+
+ display-subsystem {
+ compatible = "rockchip,display-subsystem";
+ ports = <&vop0_out>, <&vop1_out>;
+ };
+
+ sram: sram@10080000 {
+ compatible = "mmio-sram";
+ reg = <0x10080000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x10080000 0x10000>;
+
+ smp-sram@0 {
+ compatible = "rockchip,rk3066-smp-sram";
+ reg = <0x0 0x50>;
+ };
+ };
+
+ vop0: vop@1010c000 {
+ compatible = "rockchip,rk3066-vop";
+ reg = <0x1010c000 0x19c>;
+ interrupts = ;
+ clocks = <&cru ACLK_LCDC0>,
+ <&cru DCLK_LCDC0>,
+ <&cru HCLK_LCDC0>;
+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+ power-domains = <&power RK3066_PD_VIO>;
+ resets = <&cru SRST_LCDC0_AXI>,
+ <&cru SRST_LCDC0_AHB>,
+ <&cru SRST_LCDC0_DCLK>;
+ reset-names = "axi", "ahb", "dclk";
+ status = "disabled";
+
+ vop0_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vop0_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vop0>;
+ };
+ };
+ };
+
+ vop1: vop@1010e000 {
+ compatible = "rockchip,rk3066-vop";
+ reg = <0x1010e000 0x19c>;
+ interrupts = ;
+ clocks = <&cru ACLK_LCDC1>,
+ <&cru DCLK_LCDC1>,
+ <&cru HCLK_LCDC1>;
+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+ power-domains = <&power RK3066_PD_VIO>;
+ resets = <&cru SRST_LCDC1_AXI>,
+ <&cru SRST_LCDC1_AHB>,
+ <&cru SRST_LCDC1_DCLK>;
+ reset-names = "axi", "ahb", "dclk";
+ status = "disabled";
+
+ vop1_out: port {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vop1_out_hdmi: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&hdmi_in_vop1>;
+ };
+ };
+ };
+
+ hdmi: hdmi@10116000 {
+ compatible = "rockchip,rk3066-hdmi";
+ reg = <0x10116000 0x2000>;
+ interrupts = ;
+ clocks = <&cru HCLK_HDMI>;
+ clock-names = "hclk";
+ pinctrl-names = "default";
+ pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>;
+ power-domains = <&power RK3066_PD_VIO>;
+ rockchip,grf = <&grf>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in: port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ hdmi_in_vop0: endpoint@0 {
+ reg = <0>;
+ remote-endpoint = <&vop0_out_hdmi>;
+ };
+
+ hdmi_in_vop1: endpoint@1 {
+ reg = <1>;
+ remote-endpoint = <&vop1_out_hdmi>;
+ };
+ };
+
+ hdmi_out: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
+ i2s0: i2s@10118000 {
+ compatible = "rockchip,rk3066-i2s";
+ reg = <0x10118000 0x2000>;
+ interrupts = ;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s0_bus>;
+ clocks = <&cru SCLK_I2S0>, <&cru HCLK_I2S0>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&dmac1_s 4>, <&dmac1_s 5>;
+ dma-names = "tx", "rx";
+ rockchip,playback-channels = <8>;
+ rockchip,capture-channels = <2>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s1: i2s@1011a000 {
+ compatible = "rockchip,rk3066-i2s";
+ reg = <0x1011a000 0x2000>;
+ interrupts = ;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1_bus>;
+ clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&dmac1_s 6>, <&dmac1_s 7>;
+ dma-names = "tx", "rx";
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ i2s2: i2s@1011c000 {
+ compatible = "rockchip,rk3066-i2s";
+ reg = <0x1011c000 0x2000>;
+ interrupts = ;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s2_bus>;
+ clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
+ clock-names = "i2s_clk", "i2s_hclk";
+ dmas = <&dmac1_s 9>, <&dmac1_s 10>;
+ dma-names = "tx", "rx";
+ rockchip,playback-channels = <2>;
+ rockchip,capture-channels = <2>;
+ #sound-dai-cells = <0>;
+ status = "disabled";
+ };
+
+ cru: clock-controller@20000000 {
+ compatible = "rockchip,rk3066a-cru";
+ reg = <0x20000000 0x1000>;
+ rockchip,grf = <&grf>;
+
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ assigned-clocks = <&cru PLL_CPLL>, <&cru PLL_GPLL>,
+ <&cru ACLK_CPU>, <&cru HCLK_CPU>,
+ <&cru PCLK_CPU>, <&cru ACLK_PERI>,
+ <&cru HCLK_PERI>, <&cru PCLK_PERI>;
+ assigned-clock-rates = <400000000>, <594000000>,
+ <300000000>, <150000000>,
+ <75000000>, <300000000>,
+ <150000000>, <75000000>;
+ };
+
+ timer2: timer@2000e000 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2000e000 0x100>;
+ interrupts = ;
+ clocks = <&cru SCLK_TIMER2>, <&cru PCLK_TIMER2>;
+ clock-names = "timer", "pclk";
+ };
+
+ efuse: efuse@20010000 {
+ compatible = "rockchip,rk3066a-efuse";
+ reg = <0x20010000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&cru PCLK_EFUSE>;
+ clock-names = "pclk_efuse";
+
+ cpu_leakage: cpu_leakage@17 {
+ reg = <0x17 0x1>;
+ };
+ };
+
+ timer0: timer@20038000 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x20038000 0x100>;
+ interrupts = ;
+ clocks = <&cru SCLK_TIMER0>, <&cru PCLK_TIMER0>;
+ clock-names = "timer", "pclk";
+ };
+
+ timer1: timer@2003a000 {
+ compatible = "snps,dw-apb-timer";
+ reg = <0x2003a000 0x100>;
+ interrupts = ;
+ clocks = <&cru SCLK_TIMER1>, <&cru PCLK_TIMER1>;
+ clock-names = "timer", "pclk";
+ };
+
+ tsadc: tsadc@20060000 {
+ compatible = "rockchip,rk3066-tsadc";
+ reg = <0x20060000 0x100>;
+ clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+ clock-names = "saradc", "apb_pclk";
+ interrupts = ;
+ #io-channel-cells = <1>;
+ resets = <&cru SRST_TSADC>;
+ reset-names = "saradc-apb";
+ status = "disabled";
+ };
+
+ pinctrl: pinctrl {
+ compatible = "rockchip,rk3066a-pinctrl";
+ rockchip,grf = <&grf>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ gpio0: gpio@20034000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20034000 0x100>;
+ interrupts = ;
+ clocks = <&cru PCLK_GPIO0>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio1: gpio@2003c000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003c000 0x100>;
+ interrupts = ;
+ clocks = <&cru PCLK_GPIO1>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@2003e000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2003e000 0x100>;
+ interrupts = ;
+ clocks = <&cru PCLK_GPIO2>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@20080000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20080000 0x100>;
+ interrupts = ;
+ clocks = <&cru PCLK_GPIO3>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@20084000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x20084000 0x100>;
+ interrupts = ;
+ clocks = <&cru PCLK_GPIO4>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@2000a000 {
+ compatible = "rockchip,gpio-bank";
+ reg = <0x2000a000 0x100>;
+ interrupts = ;
+ clocks = <&cru PCLK_GPIO6>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ pcfg_pull_default: pcfg-pull-default {
+ bias-pull-pin-default;
+ };
+
+ pcfg_pull_none: pcfg-pull-none {
+ bias-disable;
+ };
+
+ emac {
+ emac_xfer: emac-xfer {
+ rockchip,pins = <1 RK_PC0 2 &pcfg_pull_none>, /* mac_clk */
+ <1 RK_PC1 2 &pcfg_pull_none>, /* tx_en */
+ <1 RK_PC2 2 &pcfg_pull_none>, /* txd1 */
+ <1 RK_PC3 2 &pcfg_pull_none>, /* txd0 */
+ <1 RK_PC4 2 &pcfg_pull_none>, /* rx_err */
+ <1 RK_PC5 2 &pcfg_pull_none>, /* crs_dvalid */
+ <1 RK_PC6 2 &pcfg_pull_none>, /* rxd1 */
+ <1 RK_PC7 2 &pcfg_pull_none>; /* rxd0 */
+ };
+
+ emac_mdio: emac-mdio {
+ rockchip,pins = <1 RK_PD0 2 &pcfg_pull_none>, /* mac_md */
+ <1 RK_PD1 2 &pcfg_pull_none>; /* mac_mdclk */
+ };
+ };
+
+ emmc {
+ emmc_clk: emmc-clk {
+ rockchip,pins = <3 RK_PD7 2 &pcfg_pull_default>;
+ };
+
+ emmc_cmd: emmc-cmd {
+ rockchip,pins = <4 RK_PB1 2 &pcfg_pull_default>;
+ };
+
+ emmc_rst: emmc-rst {
+ rockchip,pins = <4 RK_PB2 2 &pcfg_pull_default>;
+ };
+
+ /*
+ * The data pins are shared between nandc and emmc and
+ * not accessible through pinctrl. Also they should've
+ * been already set correctly by firmware, as
+ * flash/emmc is the boot-device.
+ */
+ };
+
+ hdmi {
+ hdmi_hpd: hdmi-hpd {
+ rockchip,pins = <0 RK_PA0 1 &pcfg_pull_default>;
+ };
+
+ hdmii2c_xfer: hdmii2c-xfer {
+ rockchip,pins = <0 RK_PA1 1 &pcfg_pull_none>,
+ <0 RK_PA2 1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c0 {
+ i2c0_xfer: i2c0-xfer {
+ rockchip,pins = <2 RK_PD4 1 &pcfg_pull_none>,
+ <2 RK_PD5 1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c1 {
+ i2c1_xfer: i2c1-xfer {
+ rockchip,pins = <2 RK_PD6 1 &pcfg_pull_none>,
+ <2 RK_PD7 1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c2 {
+ i2c2_xfer: i2c2-xfer {
+ rockchip,pins = <3 RK_PA0 1 &pcfg_pull_none>,
+ <3 RK_PA1 1 &pcfg_pull_none>;
+ };
+ };
+
+ i2c3 {
+ i2c3_xfer: i2c3-xfer {
+ rockchip,pins = <3 RK_PA2 2 &pcfg_pull_none>,
+ <3 RK_PA3 2 &pcfg_pull_none>;
+ };
+ };
+
+ i2c4 {
+ i2c4_xfer: i2c4-xfer {
+ rockchip,pins = <3 RK_PA4 1 &pcfg_pull_none>,
+ <3 RK_PA5 1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm0 {
+ pwm0_out: pwm0-out {
+ rockchip,pins = <0 RK_PA3 1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm1 {
+ pwm1_out: pwm1-out {
+ rockchip,pins = <0 RK_PA4 1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm2 {
+ pwm2_out: pwm2-out {
+ rockchip,pins = <0 RK_PD6 1 &pcfg_pull_none>;
+ };
+ };
+
+ pwm3 {
+ pwm3_out: pwm3-out {
+ rockchip,pins = <0 RK_PD7 1 &pcfg_pull_none>;
+ };
+ };
+
+ spi0 {
+ spi0_clk: spi0-clk {
+ rockchip,pins = <1 RK_PA5 2 &pcfg_pull_default>;
+ };
+ spi0_cs0: spi0-cs0 {
+ rockchip,pins = <1 RK_PA4 2 &pcfg_pull_default>;
+ };
+ spi0_tx: spi0-tx {
+ rockchip,pins = <1 RK_PA7 2 &pcfg_pull_default>;
+ };
+ spi0_rx: spi0-rx {
+ rockchip,pins = <1 RK_PA6 2 &pcfg_pull_default>;
+ };
+ spi0_cs1: spi0-cs1 {
+ rockchip,pins = <4 RK_PB7 1 &pcfg_pull_default>;
+ };
+ };
+
+ spi1 {
+ spi1_clk: spi1-clk {
+ rockchip,pins = <2 RK_PC3 2 &pcfg_pull_default>;
+ };
+ spi1_cs0: spi1-cs0 {
+ rockchip,pins = <2 RK_PC4 2 &pcfg_pull_default>;
+ };
+ spi1_rx: spi1-rx {
+ rockchip,pins = <2 RK_PC6 2 &pcfg_pull_default>;
+ };
+ spi1_tx: spi1-tx {
+ rockchip,pins = <2 RK_PC5 2 &pcfg_pull_default>;
+ };
+ spi1_cs1: spi1-cs1 {
+ rockchip,pins = <2 RK_PC7 2 &pcfg_pull_default>;
+ };
+ };
+
+ uart0 {
+ uart0_xfer: uart0-xfer {
+ rockchip,pins = <1 RK_PA0 1 &pcfg_pull_default>,
+ <1 RK_PA1 1 &pcfg_pull_default>;
+ };
+
+ uart0_cts: uart0-cts {
+ rockchip,pins = <1 RK_PA2 1 &pcfg_pull_default>;
+ };
+
+ uart0_rts: uart0-rts {
+ rockchip,pins = <1 RK_PA3 1 &pcfg_pull_default>;
+ };
+ };
+
+ uart1 {
+ uart1_xfer: uart1-xfer {
+ rockchip,pins = <1 RK_PA4 1 &pcfg_pull_default>,
+ <1 RK_PA5 1 &pcfg_pull_default>;
+ };
+
+ uart1_cts: uart1-cts {
+ rockchip,pins = <1 RK_PA6 1 &pcfg_pull_default>;
+ };
+
+ uart1_rts: uart1-rts {
+ rockchip,pins = <1 RK_PA7 1 &pcfg_pull_default>;
+ };
+ };
+
+ uart2 {
+ uart2_xfer: uart2-xfer {
+ rockchip,pins = <1 RK_PB0 1 &pcfg_pull_default>,
+ <1 RK_PB1 1 &pcfg_pull_default>;
+ };
+ /* no rts / cts for uart2 */
+ };
+
+ uart3 {
+ uart3_xfer: uart3-xfer {
+ rockchip,pins = <3 RK_PD3 1 &pcfg_pull_default>,
+ <3 RK_PD4 1 &pcfg_pull_default>;
+ };
+
+ uart3_cts: uart3-cts {
+ rockchip,pins = <3 RK_PD5 1 &pcfg_pull_default>;
+ };
+
+ uart3_rts: uart3-rts {
+ rockchip,pins = <3 RK_PD6 1 &pcfg_pull_default>;
+ };
+ };
+
+ sd0 {
+ sd0_clk: sd0-clk {
+ rockchip,pins = <3 RK_PB0 1 &pcfg_pull_default>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ rockchip,pins = <3 RK_PB1 1 &pcfg_pull_default>;
+ };
+
+ sd0_cd: sd0-cd {
+ rockchip,pins = <3 RK_PB6 1 &pcfg_pull_default>;
+ };
+
+ sd0_wp: sd0-wp {
+ rockchip,pins = <3 RK_PB7 1 &pcfg_pull_default>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ rockchip,pins = <3 RK_PB2 1 &pcfg_pull_default>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ rockchip,pins = <3 RK_PB2 1 &pcfg_pull_default>,
+ <3 RK_PB3 1 &pcfg_pull_default>,
+ <3 RK_PB4 1 &pcfg_pull_default>,
+ <3 RK_PB5 1 &pcfg_pull_default>;
+ };
+ };
+
+ sd1 {
+ sd1_clk: sd1-clk {
+ rockchip,pins = <3 RK_PC5 1 &pcfg_pull_default>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ rockchip,pins = <3 RK_PC0 1 &pcfg_pull_default>;
+ };
+
+ sd1_cd: sd1-cd {
+ rockchip,pins = <3 RK_PC6 1 &pcfg_pull_default>;
+ };
+
+ sd1_wp: sd1-wp {
+ rockchip,pins = <3 RK_PC7 1 &pcfg_pull_default>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ rockchip,pins = <3 RK_PC1 1 &pcfg_pull_default>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ rockchip,pins = <3 RK_PC1 1 &pcfg_pull_default>,
+ <3 RK_PC2 1 &pcfg_pull_default>,
+ <3 RK_PC3 1 &pcfg_pull_default>,
+ <3 RK_PC4 1 &pcfg_pull_default>;
+ };
+ };
+
+ i2s0 {
+ i2s0_bus: i2s0-bus {
+ rockchip,pins = <0 RK_PA7 1 &pcfg_pull_default>,
+ <0 RK_PB0 1 &pcfg_pull_default>,
+ <0 RK_PB1 1 &pcfg_pull_default>,
+ <0 RK_PB2 1 &pcfg_pull_default>,
+ <0 RK_PB3 1 &pcfg_pull_default>,
+ <0 RK_PB4 1 &pcfg_pull_default>,
+ <0 RK_PB5 1 &pcfg_pull_default>,
+ <0 RK_PB6 1 &pcfg_pull_default>,
+ <0 RK_PB7 1 &pcfg_pull_default>;
+ };
+ };
+
+ i2s1 {
+ i2s1_bus: i2s1-bus {
+ rockchip,pins = <0 RK_PC0 1 &pcfg_pull_default>,
+ <0 RK_PC1 1 &pcfg_pull_default>,
+ <0 RK_PC2 1 &pcfg_pull_default>,
+ <0 RK_PC3 1 &pcfg_pull_default>,
+ <0 RK_PC4 1 &pcfg_pull_default>,
+ <0 RK_PC5 1 &pcfg_pull_default>;
+ };
+ };
+
+ i2s2 {
+ i2s2_bus: i2s2-bus {
+ rockchip,pins = <0 RK_PD0 1 &pcfg_pull_default>,
+ <0 RK_PD1 1 &pcfg_pull_default>,
+ <0 RK_PD2 1 &pcfg_pull_default>,
+ <0 RK_PD3 1 &pcfg_pull_default>,
+ <0 RK_PD4 1 &pcfg_pull_default>,
+ <0 RK_PD5 1 &pcfg_pull_default>;
+ };
+ };
+ };
+};
+
+&gpu {
+ compatible = "rockchip,rk3066-mali", "arm,mali-400";
+ interrupts = ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ,
+ ;
+ interrupt-names = "gp",
+ "gpmmu",
+ "pp0",
+ "ppmmu0",
+ "pp1",
+ "ppmmu1",
+ "pp2",
+ "ppmmu2",
+ "pp3",
+ "ppmmu3";
+ power-domains = <&power RK3066_PD_GPU>;
+};
+
+&grf {
+ compatible = "rockchip,rk3066-grf", "syscon", "simple-mfd";
+
+ usbphy: usbphy {
+ compatible = "rockchip,rk3066a-usb-phy";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ usbphy0: usb-phy@17c {
+ reg = <0x17c>;
+ clocks = <&cru SCLK_OTGPHY0>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ };
+
+ usbphy1: usb-phy@188 {
+ reg = <0x188>;
+ clocks = <&cru SCLK_OTGPHY1>;
+ clock-names = "phyclk";
+ #clock-cells = <0>;
+ #phy-cells = <0>;
+ };
+ };
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_xfer>;
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_xfer>;
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_xfer>;
+};
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_xfer>;
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_xfer>;
+};
+
+&mmc0 {
+ clock-frequency = <50000000>;
+ dmas = <&dmac2 1>;
+ dma-names = "rx-tx";
+ max-frequency = <50000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4>;
+};
+
+&mmc1 {
+ dmas = <&dmac2 3>;
+ dma-names = "rx-tx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_cd &sd1_bus4>;
+};
+
+&emmc {
+ dmas = <&dmac2 4>;
+ dma-names = "rx-tx";
+};
+
+&pmu {
+ power: power-controller {
+ compatible = "rockchip,rk3066-power-controller";
+ #power-domain-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-domain@RK3066_PD_VIO {
+ reg = ;
+ clocks = <&cru ACLK_LCDC0>,
+ <&cru ACLK_LCDC1>,
+ <&cru DCLK_LCDC0>,
+ <&cru DCLK_LCDC1>,
+ <&cru HCLK_LCDC0>,
+ <&cru HCLK_LCDC1>,
+ <&cru SCLK_CIF1>,
+ <&cru ACLK_CIF1>,
+ <&cru HCLK_CIF1>,
+ <&cru SCLK_CIF0>,
+ <&cru ACLK_CIF0>,
+ <&cru HCLK_CIF0>,
+ <&cru HCLK_HDMI>,
+ <&cru ACLK_IPP>,
+ <&cru HCLK_IPP>,
+ <&cru ACLK_RGA>,
+ <&cru HCLK_RGA>;
+ pm_qos = <&qos_lcdc0>,
+ <&qos_lcdc1>,
+ <&qos_cif0>,
+ <&qos_cif1>,
+ <&qos_ipp>,
+ <&qos_rga>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@RK3066_PD_VIDEO {
+ reg = ;
+ clocks = <&cru ACLK_VDPU>,
+ <&cru ACLK_VEPU>,
+ <&cru HCLK_VDPU>,
+ <&cru HCLK_VEPU>;
+ pm_qos = <&qos_vpu>;
+ #power-domain-cells = <0>;
+ };
+
+ power-domain@RK3066_PD_GPU {
+ reg = ;
+ clocks = <&cru ACLK_GPU>;
+ pm_qos = <&qos_gpu>;
+ #power-domain-cells = <0>;
+ };
+ };
+};
+
+&pwm0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm0_out>;
+};
+
+&pwm1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm1_out>;
+};
+
+&pwm2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm2_out>;
+};
+
+&pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pwm3_out>;
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>;
+};
+
+&spi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>;
+};
+
+&uart0 {
+ compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+ dmas = <&dmac1_s 0>, <&dmac1_s 1>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+};
+
+&uart1 {
+ compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+ dmas = <&dmac1_s 2>, <&dmac1_s 3>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_xfer>;
+};
+
+&uart2 {
+ compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+ dmas = <&dmac2 6>, <&dmac2 7>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_xfer>;
+};
+
+&uart3 {
+ compatible = "rockchip,rk3066-uart", "snps,dw-apb-uart";
+ dmas = <&dmac2 8>, <&dmac2 9>;
+ dma-names = "tx", "rx";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_xfer>;
+};
+
+&vpu {
+ power-domains = <&power RK3066_PD_VIDEO>;
+};
+
+&wdt {
+ compatible = "rockchip,rk3066-wdt", "snps,dw-wdt";
+};
+
+&emac {
+ compatible = "rockchip,rk3066-emac";
+};
From 41ed3912c0fd5b2c5a0e20e524aae28dc062769e Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:45 +0200
Subject: [PATCH 28/48] arm: dts: rockchip: add rk3066a-mk808.dts
MK808 is a RK3066-based board with 1 USB host and 1 USB OTG port,
HDMI and a micro-SD card slot. It also includes on-board NAND
and 1GB of SDRAM. Add rk3066a-mk808.dts. Move U-boot specific
things in a rk3066a-mk808-u-boot.dtsi file.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/dts/Makefile | 3 +
arch/arm/dts/rk3066a-mk808-u-boot.dtsi | 49 ++++++
arch/arm/dts/rk3066a-mk808.dts | 216 +++++++++++++++++++++++++
3 files changed, 268 insertions(+)
create mode 100644 arch/arm/dts/rk3066a-mk808-u-boot.dtsi
create mode 100644 arch/arm/dts/rk3066a-mk808.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index df7b4addf99..2a0efd8edad 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -90,6 +90,9 @@ dtb-$(CONFIG_ROCKCHIP_PX30) += \
dtb-$(CONFIG_ROCKCHIP_RK3036) += \
rk3036-sdk.dtb
+dtb-$(CONFIG_ROCKCHIP_RK3066) += \
+ rk3066a-mk808.dtb
+
dtb-$(CONFIG_ROCKCHIP_RK3128) += \
rk3128-evb.dtb
diff --git a/arch/arm/dts/rk3066a-mk808-u-boot.dtsi b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi
new file mode 100644
index 00000000000..e0aa929fcef
--- /dev/null
+++ b/arch/arm/dts/rk3066a-mk808-u-boot.dtsi
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include "rk3066a-u-boot.dtsi"
+
+/ {
+ config {
+ u-boot,boot-led = "mk808:blue:power";
+ };
+};
+
+&cru {
+ u-boot,dm-pre-reloc;
+};
+
+&dmc {
+ compatible = "rockchip,rk3066-dmc", "syscon";
+ rockchip,pctl-timing = <0x12c 0xc8 0x1f4 0x1e 0x4e 0x4 0x69 0x6
+ 0x3 0x0 0x6 0x5 0xc 0x10 0x6 0x4
+ 0x4 0x5 0x4 0x200 0x3 0xa 0x40 0x0
+ 0x1 0x5 0x5 0x3 0xc 0x1e 0x100 0x0
+ 0x4 0x0>;
+ rockchip,phy-timing = <0x208c6690 0x690878 0x10022a00
+ 0x220 0x40 0x0 0x0>;
+ rockchip,sdram-params = <0x24716310 0 2 300000000 3 9 0>;
+};
+
+&mmc0 {
+ fifo-mode;
+ max-frequency = <4000000>;
+ u-boot,dm-spl;
+ u-boot,spl-fifo-mode;
+};
+
+&mmc1 {
+ status = "disabled";
+};
+
+&noc {
+ compatible = "rockchip,rk3066-noc", "syscon";
+};
+
+&timer2 {
+ clock-frequency = <24000000>;
+ u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/rk3066a-mk808.dts b/arch/arm/dts/rk3066a-mk808.dts
new file mode 100644
index 00000000000..667d57a4ff4
--- /dev/null
+++ b/arch/arm/dts/rk3066a-mk808.dts
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2016 Paweł Jarosz
+ */
+
+/dts-v1/;
+#include
+#include "rk3066a.dtsi"
+
+/ {
+ model = "Rikomagic MK808";
+ compatible = "rikomagic,mk808", "rockchip,rk3066a";
+
+ aliases {
+ mmc0 = &mmc0;
+ mmc1 = &mmc1;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory@60000000 {
+ reg = <0x60000000 0x40000000>;
+ device_type = "memory";
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 1>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <2500000>;
+ poll-interval = <100>;
+
+ recovery {
+ label = "recovery";
+ linux,code = ;
+ press-threshold-microvolt = <0>;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+
+ blue_led: led-0 {
+ label = "mk808:blue:power";
+ gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ linux,default-trigger = "default-on";
+ };
+ };
+
+ hdmi_con {
+ compatible = "hdmi-connector";
+ type = "c";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ vcc_2v5: vcc-2v5 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_2v5";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <2500000>;
+ };
+
+ vcc_io: vcc-io {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_io";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcc_host: usb-host-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&host_drv>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-name = "host-pwr";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_otg: usb-otg-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&otg_drv>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-name = "vcc_otg";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_sd: sdmmc-regulator {
+ compatible = "regulator-fixed";
+ gpio = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
+ pinctrl-0 = <&sdmmc_pwr>;
+ pinctrl-names = "default";
+ regulator-name = "vcc_sd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+
+ vcc_wifi: sdio-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&wifi_pwr>;
+ pinctrl-names = "default";
+ regulator-name = "vcc_wifi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ vin-supply = <&vcc_io>;
+ };
+};
+
+&hdmi {
+ status = "okay";
+};
+
+&hdmi_in_vop1 {
+ status = "disabled";
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&mmc0 {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ vmmc-supply = <&vcc_sd>;
+ status = "okay";
+};
+
+&mmc1 {
+ bus-width = <4>;
+ non-removable;
+ pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>;
+ pinctrl-names = "default";
+ vmmc-supply = <&vcc_wifi>;
+ status = "okay";
+};
+
+&pinctrl {
+ usb-host {
+ host_drv: host-drv {
+ rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ usb-otg {
+ otg_drv: otg-drv {
+ rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ sdmmc {
+ sdmmc_pwr: sdmmc-pwr {
+ rockchip,pins = <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_default>;
+ };
+ };
+
+ sdio {
+ wifi_pwr: wifi-pwr {
+ rockchip,pins = <3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&saradc {
+ vref-supply = <&vcc_2v5>;
+ status = "okay";
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host {
+ status = "okay";
+};
+
+&usb_otg {
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
+
+&vop0 {
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
From 0034f1da5ae18cb21eb2012b1e175147118834cf Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:46 +0200
Subject: [PATCH 29/48] rockchip: tools: add rk3066 support to rkcommon.c
Add rk3066 support to rkcommon.c
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
tools/rkcommon.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index ff62c75caad..0db45c2d41c 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -123,6 +123,7 @@ struct spl_info {
static struct spl_info spl_infos[] = {
{ "px30", "RK33", 0x2800, false, RK_HEADER_V1 },
{ "rk3036", "RK30", 0x1000, false, RK_HEADER_V1 },
+ { "rk3066", "RK30", 0x8000 - 0x800, true, RK_HEADER_V1 },
{ "rk3128", "RK31", 0x1800, false, RK_HEADER_V1 },
{ "rk3188", "RK31", 0x8000 - 0x800, true, RK_HEADER_V1 },
{ "rk322x", "RK32", 0x8000 - 0x1000, false, RK_HEADER_V1 },
From 33f4750783080302afd8f00bb07bd18d6e94f073 Mon Sep 17 00:00:00 2001
From: Johan Jonker
Date: Sat, 16 Apr 2022 17:09:47 +0200
Subject: [PATCH 30/48] rockchip: rk3066: add core support
Add the core architecture code for the rk3066.
Signed-off-by: Johan Jonker
Reviewed-by: Kever Yang
---
arch/arm/include/asm/arch-rk3066/boot0.h | 8 +++
arch/arm/include/asm/arch-rk3066/gpio.h | 8 +++
arch/arm/include/asm/arch-rk3066/timer.h | 6 ++
arch/arm/mach-rockchip/Kconfig | 23 ++++++++
arch/arm/mach-rockchip/Makefile | 1 +
arch/arm/mach-rockchip/rk3066/Kconfig | 30 ++++++++++
arch/arm/mach-rockchip/rk3066/Makefile | 5 ++
arch/arm/mach-rockchip/rk3066/clk_rk3066.c | 33 +++++++++++
arch/arm/mach-rockchip/rk3066/rk3066.c | 49 +++++++++++++++++
arch/arm/mach-rockchip/rk3066/syscon_rk3066.c | 55 +++++++++++++++++++
include/configs/mk808.h | 9 +++
include/configs/rk3066_common.h | 47 ++++++++++++++++
12 files changed, 274 insertions(+)
create mode 100644 arch/arm/include/asm/arch-rk3066/boot0.h
create mode 100644 arch/arm/include/asm/arch-rk3066/gpio.h
create mode 100644 arch/arm/include/asm/arch-rk3066/timer.h
create mode 100644 arch/arm/mach-rockchip/rk3066/Kconfig
create mode 100644 arch/arm/mach-rockchip/rk3066/Makefile
create mode 100644 arch/arm/mach-rockchip/rk3066/clk_rk3066.c
create mode 100644 arch/arm/mach-rockchip/rk3066/rk3066.c
create mode 100644 arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
create mode 100644 include/configs/mk808.h
create mode 100644 include/configs/rk3066_common.h
diff --git a/arch/arm/include/asm/arch-rk3066/boot0.h b/arch/arm/include/asm/arch-rk3066/boot0.h
new file mode 100644
index 00000000000..28c0fb9a4c6
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3066/boot0.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3066/gpio.h b/arch/arm/include/asm/arch-rk3066/gpio.h
new file mode 100644
index 00000000000..a4a3b3289c2
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3066/gpio.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include
+
+#endif
diff --git a/arch/arm/include/asm/arch-rk3066/timer.h b/arch/arm/include/asm/arch-rk3066/timer.h
new file mode 100644
index 00000000000..3bb39428cd6
--- /dev/null
+++ b/arch/arm/include/asm/arch-rk3066/timer.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __ASM_ARCH_TIMER_H__
+#define __ASM_ARCH_TIMER_H__
+
+#endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index 811964973ae..18aff5480ba 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -35,6 +35,28 @@ config ROCKCHIP_RK3036
and video codec support. Peripherals include Gigabit Ethernet,
USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+config ROCKCHIP_RK3066
+ bool "Support Rockchip RK3066"
+ select CPU_V7A
+ select SPL_BOARD_INIT if SPL
+ select SUPPORT_SPL
+ select SUPPORT_TPL
+ select SPL
+ select TPL
+ select TPL_ROCKCHIP_BACK_TO_BROM
+ select TPL_ROCKCHIP_EARLYRETURN_TO_BROM
+ imply ROCKCHIP_COMMON_BOARD
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply SPL_SERIAL
+ imply TPL_ROCKCHIP_COMMON_BOARD
+ imply TPL_SERIAL
+ help
+ The Rockchip RK3066 is a ARM-based SoC with a dual-core Cortex-A9
+ including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
+ video interfaces, several memory options and video codec support.
+ Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
+ UART, SPI, I2C and PWMs.
+
config ROCKCHIP_RK3128
bool "Support Rockchip RK3128"
select CPU_V7A
@@ -405,6 +427,7 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE
source "arch/arm/mach-rockchip/px30/Kconfig"
source "arch/arm/mach-rockchip/rk3036/Kconfig"
+source "arch/arm/mach-rockchip/rk3066/Kconfig"
source "arch/arm/mach-rockchip/rk3128/Kconfig"
source "arch/arm/mach-rockchip/rk3188/Kconfig"
source "arch/arm/mach-rockchip/rk322x/Kconfig"
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 00aef0ecee6..6c1c7b8a108 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram.o
obj-$(CONFIG_ROCKCHIP_PX30) += px30/
obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3066) += rk3066/
obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x/
diff --git a/arch/arm/mach-rockchip/rk3066/Kconfig b/arch/arm/mach-rockchip/rk3066/Kconfig
new file mode 100644
index 00000000000..335f49bc557
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/Kconfig
@@ -0,0 +1,30 @@
+if ROCKCHIP_RK3066
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x20004040
+
+config SYS_SOC
+ default "rk3066"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config SPL_SERIAL
+ default y
+
+config TPL_LIBCOMMON_SUPPORT
+ default y
+
+config TPL_LIBGENERIC_SUPPORT
+ default y
+
+config TPL_SERIAL
+ default y
+
+endif
diff --git a/arch/arm/mach-rockchip/rk3066/Makefile b/arch/arm/mach-rockchip/rk3066/Makefile
new file mode 100644
index 00000000000..9e2a9d4b0aa
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += clk_rk3066.o
+obj-y += rk3066.o
+obj-y += syscon_rk3066.o
diff --git a/arch/arm/mach-rockchip/rk3066/clk_rk3066.c b/arch/arm/mach-rockchip/rk3066/clk_rk3066.c
new file mode 100644
index 00000000000..c47526dca5d
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/clk_rk3066.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3066a_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3066_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/rk3066/rk3066.c b/arch/arm/mach-rockchip/rk3066/rk3066.c
new file mode 100644
index 00000000000..78c7d894f90
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/rk3066.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include
+#include
+#include
+#include
+
+#define GRF_BASE 0x20008000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/mmc@1021c000",
+ [BROM_BOOTSOURCE_SD] = "/mmc@10214000",
+};
+
+void board_debug_uart_init(void)
+{
+ struct rk3066_grf * const grf = (void *)GRF_BASE;
+
+ /* Enable early UART on the RK3066 */
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK | GPIO1B0_MASK,
+ GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+ GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+}
+
+void spl_board_init(void)
+{
+ if (!IS_ENABLED(CONFIG_SPL_BUILD))
+ return;
+
+ if (IS_ENABLED(CONFIG_SPL_DM_MMC)) {
+ struct rk3066_grf * const grf = (void *)GRF_BASE;
+
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GPIO3B0_MASK | GPIO3B1_MASK | GPIO3B2_MASK |
+ GPIO3B3_MASK | GPIO3B4_MASK | GPIO3B5_MASK |
+ GPIO3B6_MASK,
+ GPIO3B0_SDMMC0_CLKOUT << GPIO3B0_SHIFT |
+ GPIO3B1_SDMMC0_CMD << GPIO3B1_SHIFT |
+ GPIO3B2_SDMMC0_DATA0 << GPIO3B2_SHIFT |
+ GPIO3B3_SDMMC0_DATA1 << GPIO3B3_SHIFT |
+ GPIO3B4_SDMMC0_DATA2 << GPIO3B4_SHIFT |
+ GPIO3B5_SDMMC0_DATA3 << GPIO3B5_SHIFT |
+ GPIO3B6_SDMMC0_DECTN << GPIO3B6_SHIFT);
+ }
+}
diff --git a/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c b/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
new file mode 100644
index 00000000000..a598f6400de
--- /dev/null
+++ b/arch/arm/mach-rockchip/rk3066/syscon_rk3066.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass
+ */
+
+#include
+#include
+#include
+#include