All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/12] rockchip: add support for px30
@ 2019-10-24 23:27 Heiko Stuebner
  2019-10-24 23:27 ` [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl Heiko Stuebner
                   ` (13 more replies)
  0 siblings, 14 replies; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

This series adds support for the px30 soc and its evaluation board.
The most interesting aspect is the sram size which is only 10kb,
so the TPL doing the DDR init needs to be really tiny, while the
SPL then should use devicemanager and all other newer features.

I'm not yet sure if there is a better solution for the first patch
but right now without it there is no way to build SPL with Framework
and TPL without.

David Wu (1):
  pinctrl: rockchip: add px30 pinctrl driver

Finley Xiao (1):
  misc: add driver for the Rockchip otp controller

Heiko Stuebner (8):
  spl: separate SPL_FRAMEWORK config for spl and tpl
  rockchip: add core px30 headers
  net: gmac_rockchip: add support for px30
  rockchip: misc: read cpuid either from efuse or otp
  rockchip: ram: add dm-based sdram driver
  rockchip: add px30 devicetrees
  rockchip: add px30-evb board

Kever Yang (2):
  rockchip: clk: add px30 clock driver
  rockchip: mkimage: add support for px30
  rockchip: add px30 architecture core

 arch/arm/dts/Makefile                         |    3 +
 arch/arm/dts/px30-evb-u-boot.dtsi             |   81 +
 arch/arm/dts/px30-evb.dts                     |  527 +++++
 arch/arm/dts/px30.dtsi                        | 2068 +++++++++++++++++
 arch/arm/include/asm/arch-px30/boot0.h        |   11 +
 arch/arm/include/asm/arch-px30/gpio.h         |   11 +
 arch/arm/include/asm/arch-rockchip/cru_px30.h |  432 ++++
 arch/arm/include/asm/arch-rockchip/grf_px30.h |  144 ++
 .../include/asm/arch-rockchip/sdram_px30.h    |  359 +++
 arch/arm/lib/Makefile                         |    2 +-
 arch/arm/lib/crt0.S                           |    2 +-
 arch/arm/lib/crt0_64.S                        |    2 +
 arch/arm/mach-rockchip/Kconfig                |   23 +
 arch/arm/mach-rockchip/Makefile               |    2 +
 arch/arm/mach-rockchip/misc.c                 |    7 +-
 arch/arm/mach-rockchip/px30-board-tpl.c       |   59 +
 arch/arm/mach-rockchip/px30/Kconfig           |   48 +
 arch/arm/mach-rockchip/px30/Makefile          |   14 +
 arch/arm/mach-rockchip/px30/clk_px30.c        |   31 +
 arch/arm/mach-rockchip/px30/px30.c            |  248 ++
 .../px30/sdram-px30-ddr3-detect-333.inc       |   70 +
 .../px30/sdram-px30-ddr4-detect-333.inc       |   73 +
 .../px30/sdram-px30-ddr_skew.inc              |  121 +
 .../px30/sdram-px30-lpddr2-detect-333.inc     |   71 +
 .../px30/sdram-px30-lpddr3-detect-333.inc     |   72 +
 arch/arm/mach-rockchip/px30/sdram_px30.c      | 1405 +++++++++++
 arch/arm/mach-rockchip/px30/syscon_px30.c     |   53 +
 arch/powerpc/lib/Makefile                     |    2 +-
 board/rockchip/evb_px30/Kconfig               |   15 +
 board/rockchip/evb_px30/MAINTAINERS           |    6 +
 board/rockchip/evb_px30/Makefile              |    7 +
 board/rockchip/evb_px30/evb_px30.c            |    4 +
 common/spl/Kconfig                            |    8 +
 common/spl/Makefile                           |    2 +-
 configs/evb-px30_defconfig                    |  113 +
 drivers/clk/rockchip/Makefile                 |    1 +
 drivers/clk/rockchip/clk_px30.c               | 1630 +++++++++++++
 drivers/misc/Kconfig                          |    9 +
 drivers/misc/Makefile                         |    1 +
 drivers/misc/rockchip-otp.c                   |  176 ++
 drivers/net/gmac_rockchip.c                   |   69 +
 drivers/pinctrl/rockchip/Makefile             |    1 +
 drivers/pinctrl/rockchip/pinctrl-px30.c       |  368 +++
 drivers/ram/rockchip/Makefile                 |    1 +
 drivers/ram/rockchip/sdram_px30.c             |   57 +
 include/configs/evb_px30.h                    |   19 +
 include/configs/px30_common.h                 |   62 +
 include/dt-bindings/clock/px30-cru.h          |  389 ++++
 include/dt-bindings/power/px30-power.h        |   27 +
 include/dt-bindings/soc/rockchip,boot-mode.h  |   16 +
 scripts/Makefile.spl                          |    4 +
 tools/rkcommon.c                              |    1 +
 52 files changed, 8922 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/dts/px30-evb-u-boot.dtsi
 create mode 100644 arch/arm/dts/px30-evb.dts
 create mode 100644 arch/arm/dts/px30.dtsi
 create mode 100644 arch/arm/include/asm/arch-px30/boot0.h
 create mode 100644 arch/arm/include/asm/arch-px30/gpio.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/cru_px30.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/grf_px30.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h
 create mode 100644 arch/arm/mach-rockchip/px30-board-tpl.c
 create mode 100644 arch/arm/mach-rockchip/px30/Kconfig
 create mode 100644 arch/arm/mach-rockchip/px30/Makefile
 create mode 100644 arch/arm/mach-rockchip/px30/clk_px30.c
 create mode 100644 arch/arm/mach-rockchip/px30/px30.c
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram_px30.c
 create mode 100644 arch/arm/mach-rockchip/px30/syscon_px30.c
 create mode 100644 board/rockchip/evb_px30/Kconfig
 create mode 100644 board/rockchip/evb_px30/MAINTAINERS
 create mode 100644 board/rockchip/evb_px30/Makefile
 create mode 100644 board/rockchip/evb_px30/evb_px30.c
 create mode 100644 configs/evb-px30_defconfig
 create mode 100644 drivers/clk/rockchip/clk_px30.c
 create mode 100644 drivers/misc/rockchip-otp.c
 create mode 100644 drivers/pinctrl/rockchip/pinctrl-px30.c
 create mode 100644 drivers/ram/rockchip/sdram_px30.c
 create mode 100644 include/configs/evb_px30.h
 create mode 100644 include/configs/px30_common.h
 create mode 100644 include/dt-bindings/clock/px30-cru.h
 create mode 100644 include/dt-bindings/power/px30-power.h
 create mode 100644 include/dt-bindings/soc/rockchip,boot-mode.h

-- 
2.23.0

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

* [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  1:55   ` Kever Yang
  2019-10-24 23:27 ` [U-Boot] [PATCH 02/12] rockchip: add core px30 headers Heiko Stuebner
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

Right now enabling SPL_FRAMEWORK will also enable it for the TPL in all
cases, making the TPL bigger. There may be cases where the TPL is really
size constrained due to its underlying ram size.

Therefore introduce a new TPL_FRAMEWORK option and make the relevant
conditionals check for both. The default is set to "y if SPL_FRAMEWORK"
to mimic the previous behaviour where the TPL would always get the
SPL framework if it was enabled in SPL.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 arch/arm/lib/Makefile     | 2 +-
 arch/arm/lib/crt0.S       | 2 +-
 arch/arm/lib/crt0_64.S    | 2 ++
 arch/powerpc/lib/Makefile | 2 +-
 common/spl/Kconfig        | 8 ++++++++
 common/spl/Makefile       | 2 +-
 scripts/Makefile.spl      | 4 ++++
 7 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 48ee6c3c60..9de9a9acee 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -35,7 +35,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o
 obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
 obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
 else
-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
 obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o
 obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
 endif
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index c74641dcd9..fb6c37cf51 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -149,7 +149,7 @@ here:
 
 	bl	c_runtime_cpu_setup	/* we still call old routine here */
 #endif
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
+#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
 
 #if !defined(CONFIG_SPL_EARLY_BSS)
 	SPL_CLEAR_BSS
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index e76b25a03e..04afa518ac 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -120,6 +120,7 @@ relocation_return:
  */
 	bl	c_runtime_cpu_setup		/* still call old routine */
 #endif /* !CONFIG_SPL_BUILD */
+#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
 #if defined(CONFIG_SPL_BUILD)
 	bl	spl_relocate_stack_gd           /* may return NULL */
 	/* set up gd here, outside any C code, if new stack is returned */
@@ -152,5 +153,6 @@ clear_loop:
 	b	board_init_r			/* PC relative jump */
 
 	/* NOTREACHED - board_init_r() does not return */
+#endif
 
 ENDPROC(_main)
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 8ac49bdd06..01c9dd51be 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -41,5 +41,5 @@ obj-y	+= time.o
 endif # not minimal
 
 ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL)_FRAMEWORK) += spl.o
 endif
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index f467eca2be..4d5c4ddc46 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1183,6 +1183,14 @@ config TPL
 
 if TPL
 
+config TPL_FRAMEWORK
+	bool "Support TPL based upon the common SPL framework"
+	default y if SPL_FRAMEWORK
+	help
+	  Enable the SPL framework under common/spl/ for TPL builds.
+	  This framework supports MMC, NAND and YMODEM and other methods
+	  loading of U-Boot's SPL stage. If unsure, say Y.
+
 config TPL_HANDOFF
 	bool "Pass hand-off information from TPL to SPL and U-Boot proper"
 	depends on HANDOFF
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 5ce6f4ae48..eaa57f5ce5 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -7,7 +7,7 @@
 #
 
 ifdef CONFIG_SPL_BUILD
-obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
+obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
 obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o
 obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o
 obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 7af6b120b6..090c831710 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -71,7 +71,11 @@ HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makef
 libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
 libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
 
+ifeq ($(CONFIG_TPL_BUILD),y)
+libs-$(CONFIG_TPL_FRAMEWORK) += common/spl/
+else
 libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
+endif
 libs-y += common/init/
 
 # Special handling for a few options which support SPL/TPL
-- 
2.23.0

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

* [U-Boot] [PATCH 02/12] rockchip: add core px30 headers
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
  2019-10-24 23:27 ` [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  2:04   ` Kever Yang
  2019-10-24 23:27 ` [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver Heiko Stuebner
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

Add headers needed by the upcoming px30 support, including two
new dt-binding headers taken from the Linux kernel.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 arch/arm/include/asm/arch-rockchip/grf_px30.h | 144 ++++++++++++++++++
 include/configs/px30_common.h                 |  62 ++++++++
 include/dt-bindings/power/px30-power.h        |  27 ++++
 include/dt-bindings/soc/rockchip,boot-mode.h  |  16 ++
 4 files changed, 249 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/grf_px30.h
 create mode 100644 include/configs/px30_common.h
 create mode 100644 include/dt-bindings/power/px30-power.h
 create mode 100644 include/dt-bindings/soc/rockchip,boot-mode.h

diff --git a/arch/arm/include/asm/arch-rockchip/grf_px30.h b/arch/arm/include/asm/arch-rockchip/grf_px30.h
new file mode 100644
index 0000000000..c167bb42fa
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/grf_px30.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_GRF_px30_H
+#define _ASM_ARCH_GRF_px30_H
+
+#include <common.h>
+
+struct px30_grf {
+	unsigned int gpio1al_iomux;
+	unsigned int gpio1ah_iomux;
+	unsigned int gpio1bl_iomux;
+	unsigned int gpio1bh_iomux;
+	unsigned int gpio1cl_iomux;
+	unsigned int gpio1ch_iomux;
+	unsigned int gpio1dl_iomux;
+	unsigned int gpio1dh_iomux;
+
+	unsigned int gpio2al_iomux;
+	unsigned int gpio2ah_iomux;
+	unsigned int gpio2bl_iomux;
+	unsigned int gpio2bh_iomux;
+	unsigned int gpio2cl_iomux;
+	unsigned int gpio2ch_iomux;
+	unsigned int gpio2dl_iomux;
+	unsigned int gpio2dh_iomux;
+
+	unsigned int gpio3al_iomux;
+	unsigned int gpio3ah_iomux;
+	unsigned int gpio3bl_iomux;
+	unsigned int gpio3bh_iomux;
+	unsigned int gpio3cl_iomux;
+	unsigned int gpio3ch_iomux;
+	unsigned int gpio3dl_iomux;
+	unsigned int gpio3dh_iomux;
+
+	unsigned int gpio1a_p;
+	unsigned int gpio1b_p;
+	unsigned int gpio1c_p;
+	unsigned int gpio1d_p;
+	unsigned int gpio2a_p;
+	unsigned int gpio2b_p;
+	unsigned int gpio2c_p;
+	unsigned int gpio2d_p;
+	unsigned int gpio3a_p;
+	unsigned int gpio3b_p;
+	unsigned int gpio3c_p;
+	unsigned int gpio3d_p;
+	unsigned int gpio1a_sr;
+	unsigned int gpio1b_sr;
+	unsigned int gpio1c_sr;
+	unsigned int gpio1d_sr;
+	unsigned int gpio2a_sr;
+	unsigned int gpio2b_sr;
+	unsigned int gpio2c_sr;
+	unsigned int gpio2d_sr;
+	unsigned int gpio3a_sr;
+	unsigned int gpio3b_sr;
+	unsigned int gpio3c_sr;
+	unsigned int gpio3d_sr;
+	unsigned int gpio1a_smt;
+	unsigned int gpio1b_smt;
+	unsigned int gpio1c_smt;
+	unsigned int gpio1d_smt;
+	unsigned int gpio2a_smt;
+	unsigned int gpio2b_smt;
+	unsigned int gpio2c_smt;
+	unsigned int gpio2d_smt;
+	unsigned int gpio3a_smt;
+	unsigned int gpio3b_smt;
+	unsigned int gpio3c_smt;
+	unsigned int gpio3d_smt;
+	unsigned int gpio1a_e;
+	unsigned int gpio1b_e;
+	unsigned int gpio1c_e;
+	unsigned int gpio1d_e;
+	unsigned int gpio2a_e;
+	unsigned int gpio2b_e;
+	unsigned int gpio2c_e;
+	unsigned int gpio2d_e;
+	unsigned int gpio3a_e;
+	unsigned int gpio3b_e;
+	unsigned int gpio3c_e;
+	unsigned int gpio3d_e;
+
+	unsigned int reserved0[(0x180 - 0x11C) / 4 - 1];
+	unsigned int io_vsel;
+	unsigned int iofunc_con0;
+	unsigned int reserved1[(0x400 - 0x184) / 4 - 1];
+	unsigned int soc_con[6];
+	unsigned int reserved2[(0x480 - 0x414) / 4 - 1];
+	unsigned int soc_status0;
+	unsigned int reserved3[(0x500 - 0x480) / 4 - 1];
+	unsigned int cpu_con[3];
+	unsigned int reserved4[5];
+	unsigned int cpu_status[2];
+	unsigned int reserved5[2];
+	unsigned int soc_noc_con[2];
+	unsigned int reserved6[6];
+	unsigned int ddr_bankhash[4];
+	unsigned int reserved7[(0x700 - 0x55c) / 4 - 1];
+	unsigned int host0_con[2];
+	unsigned int reserved8[(0x880 - 0x704) / 4 - 1];
+	unsigned int otg_con3;
+	unsigned int reserved9[3];
+	unsigned int host0_status4;
+	unsigned int reserved10[(0x904 - 0x890) / 4 - 1];
+	unsigned int mac_con1;
+};
+
+check_member(px30_grf, mac_con1, 0x904);
+
+struct px30_pmugrf {
+	unsigned int gpio0a_e;
+	unsigned int gpio0b_e;
+	unsigned int gpio0c_e;
+	unsigned int gpio0d_e;
+	unsigned int gpio0a_p;
+	unsigned int gpio0b_p;
+	unsigned int gpio0c_p;
+	unsigned int gpio0d_p;
+	unsigned int gpio0al_iomux;
+	unsigned int gpio0bl_iomux;
+	unsigned int gpio0cl_iomux;
+	unsigned int gpio0dl_iomux;
+	unsigned int gpio0l_sr;
+	unsigned int gpio0h_sr;
+	unsigned int gpio0l_smt;
+	unsigned int gpio0h_smt;
+	unsigned int reserved1[(0x100 - 0x3c) / 4 - 1];
+	unsigned int soc_con[4];
+	unsigned int reserved2[(0x180 - 0x10c) / 4 - 1];
+	unsigned int pvtm_con[2];
+	unsigned int reserved3[2];
+	unsigned int pvtm_status[2];
+	unsigned int reserved4[(0x200 - 0x194) / 4 - 1];
+	unsigned int os_reg[12];
+	unsigned int reset_function_status;
+};
+
+check_member(px30_pmugrf, reset_function_status, 0x230);
+
+#endif
diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h
new file mode 100644
index 0000000000..d6c70601dd
--- /dev/null
+++ b/include/configs/px30_common.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __CONFIG_PX30_COMMON_H
+#define __CONFIG_PX30_COMMON_H
+
+#include "rockchip-common.h"
+
+#define CONFIG_SYS_CBSIZE		1024
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+#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 */
+#define CONFIG_IRAM_BASE		0xff020000
+
+#define CONFIG_SYS_INIT_SP_ADDR		0x00400000
+#define CONFIG_SYS_LOAD_ADDR		0x00800800
+#define CONFIG_SPL_STACK		0x00400000
+#define CONFIG_SPL_MAX_SIZE		0x20000
+#define CONFIG_SPL_BSS_START_ADDR	0x4000000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x4000
+#define CONFIG_SYS_BOOTM_LEN		(64 << 20)	/* 64M */
+
+#define GICD_BASE			0xff131000
+#define GICC_BASE			0xff132000
+
+#define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
+
+/* MMC/SD IP block */
+//#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_SYS_SDRAM_BASE		0
+#define SDRAM_MAX_SIZE			0xff000000
+#define SDRAM_BANK_SIZE			(2UL << 30)
+
+#ifndef CONFIG_SPL_BUILD
+
+#define ENV_MEM_LAYOUT_SETTINGS \
+	"scriptaddr=0x00500000\0" \
+	"pxefile_addr_r=0x00600000\0" \
+	"fdt_addr_r=0x08300000\0" \
+	"kernel_addr_r=0x00280000\0" \
+	"kernel_addr_c=0x03e80000\0" \
+	"ramdisk_addr_r=0x0a200000\0"
+
+#include <config_distro_bootcmd.h>
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	ENV_MEM_LAYOUT_SETTINGS \
+	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
+	"partitions=" PARTS_DEFAULT \
+	ROCKCHIP_DEVICE_SETTINGS \
+	BOOTENV
+
+#endif
+
+#endif
diff --git a/include/dt-bindings/power/px30-power.h b/include/dt-bindings/power/px30-power.h
new file mode 100644
index 0000000000..30917a99ad
--- /dev/null
+++ b/include/dt-bindings/power/px30-power.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__
+#define __DT_BINDINGS_POWER_PX30_POWER_H__
+
+/* VD_CORE */
+#define PX30_PD_A35_0		0
+#define PX30_PD_A35_1		1
+#define PX30_PD_A35_2		2
+#define PX30_PD_A35_3		3
+#define PX30_PD_SCU		4
+
+/* VD_LOGIC */
+#define PX30_PD_USB		5
+#define PX30_PD_DDR		6
+#define PX30_PD_SDCARD		7
+#define PX30_PD_CRYPTO		8
+#define PX30_PD_GMAC		9
+#define PX30_PD_MMC_NAND	10
+#define PX30_PD_VPU		11
+#define PX30_PD_VO		12
+#define PX30_PD_VI		13
+#define PX30_PD_GPU		14
+
+/* VD_PMU */
+#define PX30_PD_PMU		15
+
+#endif
diff --git a/include/dt-bindings/soc/rockchip,boot-mode.h b/include/dt-bindings/soc/rockchip,boot-mode.h
new file mode 100644
index 0000000000..4b0914c098
--- /dev/null
+++ b/include/dt-bindings/soc/rockchip,boot-mode.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ROCKCHIP_BOOT_MODE_H
+#define __ROCKCHIP_BOOT_MODE_H
+
+/*high 24 bits is tag, low 8 bits is type*/
+#define REBOOT_FLAG		0x5242C300
+/* normal boot */
+#define BOOT_NORMAL		(REBOOT_FLAG + 0)
+/* enter bootloader rockusb mode */
+#define BOOT_BL_DOWNLOAD	(REBOOT_FLAG + 1)
+/* enter recovery */
+#define BOOT_RECOVERY		(REBOOT_FLAG + 3)
+ /* enter fastboot mode */
+#define BOOT_FASTBOOT		(REBOOT_FLAG + 9)
+
+#endif
-- 
2.23.0

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

* [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
  2019-10-24 23:27 ` [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl Heiko Stuebner
  2019-10-24 23:27 ` [U-Boot] [PATCH 02/12] rockchip: add core px30 headers Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  2:07   ` Kever Yang
  2019-10-24 23:27 ` [U-Boot] [PATCH 04/12] rockchip: clk: add px30 clock driver Heiko Stuebner
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: David Wu <david.wu@rock-chips.com>

Add the necessary glue code to allow pinctrl setting on px30 socs.

Signed-off-by: David Wu <david.wu@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 drivers/pinctrl/rockchip/Makefile       |   1 +
 drivers/pinctrl/rockchip/pinctrl-px30.c | 368 ++++++++++++++++++++++++
 2 files changed, 369 insertions(+)
 create mode 100644 drivers/pinctrl/rockchip/pinctrl-px30.c

diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
index a616d8587f..83913f668f 100644
--- a/drivers/pinctrl/rockchip/Makefile
+++ b/drivers/pinctrl/rockchip/Makefile
@@ -3,6 +3,7 @@
 # Copyright (c) 2017 Rockchip Electronics Co., Ltd
 
 obj-y += pinctrl-rockchip-core.o
+obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o
 obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o
diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c
new file mode 100644
index 0000000000..bb56ae9fb3
--- /dev/null
+++ b/drivers/pinctrl/rockchip/pinctrl-px30.c
@@ -0,0 +1,368 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <regmap.h>
+#include <syscon.h>
+
+#include "pinctrl-rockchip.h"
+
+static struct rockchip_mux_route_data px30_mux_route_data[] = {
+	{
+		/* cif-d2m0 */
+		.bank_num = 2,
+		.pin = 0,
+		.func = 1,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 7),
+	}, {
+		/* cif-d2m1 */
+		.bank_num = 3,
+		.pin = 3,
+		.func = 3,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 7) | BIT(7),
+	}, {
+		/* pdm-m0 */
+		.bank_num = 3,
+		.pin = 22,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 8),
+	}, {
+		/* pdm-m1 */
+		.bank_num = 2,
+		.pin = 22,
+		.func = 1,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 8) | BIT(8),
+	}, {
+		/* uart2-rxm0 */
+		.bank_num = 1,
+		.pin = 27,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 10),
+	}, {
+		/* uart2-rxm1 */
+		.bank_num = 2,
+		.pin = 14,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 10) | BIT(10),
+	}, {
+		/* uart3-rxm0 */
+		.bank_num = 0,
+		.pin = 17,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 9),
+	}, {
+		/* uart3-rxm1 */
+		.bank_num = 1,
+		.pin = 15,
+		.func = 2,
+		.route_offset = 0x184,
+		.route_val = BIT(16 + 9) | BIT(9),
+	},
+};
+
+static int px30_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, route_reg, route_val;
+
+	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
+				? priv->regmap_pmu : 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);
+
+	if (bank->route_mask & BIT(pin)) {
+		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
+					   &route_val)) {
+			ret = regmap_write(regmap, route_reg, route_val);
+			if (ret)
+				return ret;
+		}
+	}
+
+	data = (mask << (bit + 16));
+	data |= (mux & mask) << bit;
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define PX30_PULL_PMU_OFFSET		0x10
+#define PX30_PULL_GRF_OFFSET		0x60
+#define PX30_PULL_BITS_PER_PIN		2
+#define PX30_PULL_PINS_PER_REG		8
+#define PX30_PULL_BANK_STRIDE		16
+
+static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
+				       int pin_num, struct regmap **regmap,
+				       int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*regmap = priv->regmap_pmu;
+		*reg = PX30_PULL_PMU_OFFSET;
+	} else {
+		*regmap = priv->regmap_base;
+		*reg = PX30_PULL_GRF_OFFSET;
+
+		/* correct the offset, as we're starting with the 2nd bank */
+		*reg -= 0x10;
+		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
+	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
+	*bit *= PX30_PULL_BITS_PER_PIN;
+}
+
+static int px30_set_pull(struct rockchip_pin_bank *bank,
+			 int pin_num, int pull)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u8 bit, type;
+	u32 data;
+
+	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
+		return -ENOTSUPP;
+
+	px30_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	type = bank->pull_type[pin_num / 8];
+	ret = rockchip_translate_pull_value(type, pull);
+	if (ret < 0) {
+		debug("unsupported pull setting %d\n", pull);
+		return ret;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
+	data |= (ret << bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define PX30_DRV_PMU_OFFSET		0x20
+#define PX30_DRV_GRF_OFFSET		0xf0
+#define PX30_DRV_BITS_PER_PIN		2
+#define PX30_DRV_PINS_PER_REG		8
+#define PX30_DRV_BANK_STRIDE		16
+
+static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
+				      int pin_num, struct regmap **regmap,
+				      int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+
+	/* The first 32 pins of the first bank are located in PMU */
+	if (bank->bank_num == 0) {
+		*regmap = priv->regmap_pmu;
+		*reg = PX30_DRV_PMU_OFFSET;
+	} else {
+		*regmap = priv->regmap_base;
+		*reg = PX30_DRV_GRF_OFFSET;
+
+		/* correct the offset, as we're starting with the 2nd bank */
+		*reg -= 0x10;
+		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
+	}
+
+	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
+	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
+	*bit *= PX30_DRV_BITS_PER_PIN;
+}
+
+static int px30_set_drive(struct rockchip_pin_bank *bank,
+			  int pin_num, int strength)
+{
+	struct regmap *regmap;
+	int reg, ret;
+	u32 data, rmask_bits, temp;
+	u8 bit;
+	int drv_type = bank->drv[pin_num / 8].drv_type;
+
+	px30_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	ret = rockchip_translate_drive_value(drv_type, strength);
+	if (ret < 0) {
+		debug("unsupported driver strength %d\n", strength);
+		return ret;
+	}
+
+	switch (drv_type) {
+	case DRV_TYPE_IO_1V8_3V0_AUTO:
+	case DRV_TYPE_IO_3V3_ONLY:
+		rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
+		switch (bit) {
+		case 0 ... 12:
+			/* regular case, nothing to do */
+			break;
+		case 15:
+			/*
+			 * drive-strength offset is special, as it is spread
+			 * over 2 registers, the bit data[15] contains bit 0
+			 * of the value while temp[1:0] contains bits 2 and 1
+			 */
+			data = (ret & 0x1) << 15;
+			temp = (ret >> 0x1) & 0x3;
+
+			data |= BIT(31);
+			ret = regmap_write(regmap, reg, data);
+			if (ret)
+				return ret;
+
+			temp |= (0x3 << 16);
+			reg += 0x4;
+			ret = regmap_write(regmap, reg, temp);
+
+			return ret;
+		case 18 ... 21:
+			/* setting fully enclosed in the second register */
+			reg += 4;
+			bit -= 16;
+			break;
+		default:
+			debug("unsupported bit: %d for pinctrl drive type: %d\n",
+			      bit, drv_type);
+			return -EINVAL;
+		}
+		break;
+	case DRV_TYPE_IO_DEFAULT:
+	case DRV_TYPE_IO_1V8_OR_3V0:
+	case DRV_TYPE_IO_1V8_ONLY:
+		rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
+		break;
+	default:
+		debug("unsupported pinctrl drive type: %d\n",
+		      drv_type);
+		return -EINVAL;
+	}
+
+	/* enable the write to the equivalent lower bits */
+	data = ((1 << rmask_bits) - 1) << (bit + 16);
+	data |= (ret << bit);
+	ret = regmap_write(regmap, reg, data);
+
+	return ret;
+}
+
+#define PX30_SCHMITT_PMU_OFFSET			0x38
+#define PX30_SCHMITT_GRF_OFFSET			0xc0
+#define PX30_SCHMITT_PINS_PER_PMU_REG		16
+#define PX30_SCHMITT_BANK_STRIDE		16
+#define PX30_SCHMITT_PINS_PER_GRF_REG		8
+
+static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
+					 int pin_num,
+					 struct regmap **regmap,
+					 int *reg, u8 *bit)
+{
+	struct rockchip_pinctrl_priv *priv = bank->priv;
+	int pins_per_reg;
+
+	if (bank->bank_num == 0) {
+		*regmap = priv->regmap_pmu;
+		*reg = PX30_SCHMITT_PMU_OFFSET;
+		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
+	} else {
+		*regmap = priv->regmap_base;
+		*reg = PX30_SCHMITT_GRF_OFFSET;
+		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
+		*reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
+	}
+	*reg += ((pin_num / pins_per_reg) * 4);
+	*bit = pin_num % pins_per_reg;
+
+	return 0;
+}
+
+static int px30_set_schmitt(struct rockchip_pin_bank *bank,
+			    int pin_num, int enable)
+{
+	struct regmap *regmap;
+	int reg;
+	u8 bit;
+	u32 data;
+
+	px30_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
+	/* enable the write to the equivalent lower bits */
+	data = BIT(bit + 16) | (enable << bit);
+
+	return regmap_write(regmap, reg, data);
+}
+
+static struct rockchip_pin_bank px30_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU
+			    ),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT
+			    ),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT
+			    ),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT,
+					     IOMUX_WIDTH_4BIT
+			    ),
+};
+
+static struct rockchip_pin_ctrl px30_pin_ctrl = {
+	.pin_banks		= px30_pin_banks,
+	.nr_banks		= ARRAY_SIZE(px30_pin_banks),
+	.grf_mux_offset		= 0x0,
+	.pmu_mux_offset		= 0x0,
+	.grf_drv_offset		= 0xf0,
+	.pmu_drv_offset		= 0x20,
+	.iomux_routes		= px30_mux_route_data,
+	.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
+	.set_mux		= px30_set_mux,
+	.set_pull		= px30_set_pull,
+	.set_drive		= px30_set_drive,
+	.set_schmitt		= px30_set_schmitt,
+};
+
+static const struct udevice_id px30_pinctrl_ids[] = {
+	{
+		.compatible = "rockchip,px30-pinctrl",
+		.data = (ulong)&px30_pin_ctrl
+	},
+	{ }
+};
+
+U_BOOT_DRIVER(pinctrl_px30) = {
+	.name		= "rockchip_px30_pinctrl",
+	.id		= UCLASS_PINCTRL,
+	.of_match	= px30_pinctrl_ids,
+	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
+	.ops		= &rockchip_pinctrl_ops,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	.bind		= dm_scan_fdt_dev,
+#endif
+	.probe		= rockchip_pinctrl_probe,
+};
-- 
2.23.0

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

* [U-Boot] [PATCH 04/12] rockchip: clk: add px30 clock driver
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (2 preceding siblings ...)
  2019-10-24 23:27 ` [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-24 23:27 ` [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30 Heiko Stuebner
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: Kever Yang <kever.yang@rock-chips.com>

The px30 contains 2 separate clock controllers, pmucru and cru.
Add drivers for them.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 arch/arm/include/asm/arch-rockchip/cru_px30.h |  432 +++++
 drivers/clk/rockchip/Makefile                 |    1 +
 drivers/clk/rockchip/clk_px30.c               | 1630 +++++++++++++++++
 include/dt-bindings/clock/px30-cru.h          |  389 ++++
 4 files changed, 2452 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-rockchip/cru_px30.h
 create mode 100644 drivers/clk/rockchip/clk_px30.c
 create mode 100644 include/dt-bindings/clock/px30-cru.h

diff --git a/arch/arm/include/asm/arch-rockchip/cru_px30.h b/arch/arm/include/asm/arch-rockchip/cru_px30.h
new file mode 100644
index 0000000000..7d9fd181ac
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/cru_px30.h
@@ -0,0 +1,432 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+#ifndef _ASM_ARCH_CRU_PX30_H
+#define _ASM_ARCH_CRU_PX30_H
+
+#include <common.h>
+
+#define MHz		1000000
+#define KHz		1000
+#define OSC_HZ		(24 * MHz)
+
+#define APLL_HZ		(600 * MHz)
+#define GPLL_HZ		(1200 * MHz)
+#define NPLL_HZ		(1188 * MHz)
+#define ACLK_BUS_HZ	(200 * MHz)
+#define HCLK_BUS_HZ	(150 * MHz)
+#define PCLK_BUS_HZ	(100 * MHz)
+#define ACLK_PERI_HZ	(200 * MHz)
+#define HCLK_PERI_HZ	(150 * MHz)
+#define PCLK_PMU_HZ	(100 * MHz)
+
+/* PX30 pll id */
+enum px30_pll_id {
+	APLL,
+	DPLL,
+	CPLL,
+	NPLL,
+	GPLL,
+	PLL_COUNT,
+};
+
+struct px30_clk_priv {
+	struct px30_cru *cru;
+	ulong gpll_hz;
+};
+
+struct px30_pmuclk_priv {
+	struct px30_pmucru *pmucru;
+	ulong gpll_hz;
+};
+
+struct px30_pll {
+	unsigned int con0;
+	unsigned int con1;
+	unsigned int con2;
+	unsigned int con3;
+	unsigned int con4;
+	unsigned int reserved0[3];
+};
+
+struct px30_cru {
+	struct px30_pll pll[4];
+	unsigned int reserved1[8];
+	unsigned int mode;
+	unsigned int misc;
+	unsigned int reserved2[2];
+	unsigned int glb_cnt_th;
+	unsigned int glb_rst_st;
+	unsigned int glb_srst_fst;
+	unsigned int glb_srst_snd;
+	unsigned int glb_rst_con;
+	unsigned int reserved3[7];
+	unsigned int hwffc_con0;
+	unsigned int reserved4;
+	unsigned int hwffc_th;
+	unsigned int hwffc_intst;
+	unsigned int apll_con0_s;
+	unsigned int apll_con1_s;
+	unsigned int clksel_con0_s;
+	unsigned int reserved5;
+	unsigned int clksel_con[60];
+	unsigned int reserved6[4];
+	unsigned int clkgate_con[18];
+	unsigned int reserved7[(0x280 - 0x244) / 4 - 1];
+	unsigned int ssgtbl[32];
+	unsigned int softrst_con[12];
+	unsigned int reserved8[(0x380 - 0x32c) / 4 - 1];
+	unsigned int sdmmc_con[2];
+	unsigned int sdio_con[2];
+	unsigned int emmc_con[2];
+	unsigned int reserved9[(0x400 - 0x394) / 4 - 1];
+	unsigned int autocs_con[8];
+};
+
+check_member(px30_cru, autocs_con[7], 0x41c);
+
+struct px30_pmucru {
+	struct px30_pll pll;
+	unsigned int pmu_mode;
+	unsigned int reserved1[7];
+	unsigned int pmu_clksel_con[6];
+	unsigned int reserved2[10];
+	unsigned int pmu_clkgate_con[2];
+	unsigned int reserved3[14];
+	unsigned int pmu_autocs_con[2];
+};
+
+check_member(px30_pmucru, pmu_autocs_con[1], 0xc4);
+
+struct pll_rate_table {
+	unsigned long rate;
+	unsigned int fbdiv;
+	unsigned int postdiv1;
+	unsigned int refdiv;
+	unsigned int postdiv2;
+	unsigned int dsmpd;
+	unsigned int frac;
+};
+
+struct cpu_rate_table {
+	unsigned long rate;
+	unsigned int aclk_div;
+	unsigned int pclk_div;
+};
+
+enum {
+	/* PLLCON0*/
+	PLL_BP_SHIFT		= 15,
+	PLL_POSTDIV1_SHIFT	= 12,
+	PLL_POSTDIV1_MASK	= 7 << PLL_POSTDIV1_SHIFT,
+	PLL_FBDIV_SHIFT		= 0,
+	PLL_FBDIV_MASK		= 0xfff,
+
+	/* PLLCON1 */
+	PLL_PDSEL_SHIFT		= 15,
+	PLL_PD1_SHIFT		= 14,
+	PLL_PD_SHIFT		= 13,
+	PLL_PD_MASK		= 1 << PLL_PD_SHIFT,
+	PLL_DSMPD_SHIFT		= 12,
+	PLL_DSMPD_MASK		= 1 << PLL_DSMPD_SHIFT,
+	PLL_LOCK_STATUS_SHIFT	= 10,
+	PLL_LOCK_STATUS_MASK	= 1 << PLL_LOCK_STATUS_SHIFT,
+	PLL_POSTDIV2_SHIFT	= 6,
+	PLL_POSTDIV2_MASK	= 7 << PLL_POSTDIV2_SHIFT,
+	PLL_REFDIV_SHIFT	= 0,
+	PLL_REFDIV_MASK		= 0x3f,
+
+	/* PLLCON2 */
+	PLL_FOUT4PHASEPD_SHIFT	= 27,
+	PLL_FOUTVCOPD_SHIFT	= 26,
+	PLL_FOUTPOSTDIVPD_SHIFT	= 25,
+	PLL_DACPD_SHIFT		= 24,
+	PLL_FRAC_DIV	= 0xffffff,
+
+	/* CRU_MODE */
+	PLLMUX_FROM_XIN24M	= 0,
+	PLLMUX_FROM_PLL,
+	PLLMUX_FROM_RTC32K,
+	USBPHY480M_MODE_SHIFT	= 8,
+	USBPHY480M_MODE_MASK	= 3 << USBPHY480M_MODE_SHIFT,
+	NPLL_MODE_SHIFT		= 6,
+	NPLL_MODE_MASK		= 3 << NPLL_MODE_SHIFT,
+	DPLL_MODE_SHIFT		= 4,
+	DPLL_MODE_MASK		= 3 << DPLL_MODE_SHIFT,
+	CPLL_MODE_SHIFT		= 2,
+	CPLL_MODE_MASK		= 3 << CPLL_MODE_SHIFT,
+	APLL_MODE_SHIFT		= 0,
+	APLL_MODE_MASK		= 3 << APLL_MODE_SHIFT,
+
+	/* CRU_CLK_SEL0_CON */
+	CORE_ACLK_DIV_SHIFT	= 12,
+	CORE_ACLK_DIV_MASK	= 0x07 << CORE_ACLK_DIV_SHIFT,
+	CORE_DBG_DIV_SHIFT	= 8,
+	CORE_DBG_DIV_MASK	= 0x03 << CORE_DBG_DIV_SHIFT,
+	CORE_CLK_PLL_SEL_SHIFT	= 7,
+	CORE_CLK_PLL_SEL_MASK	= 1 << CORE_CLK_PLL_SEL_SHIFT,
+	CORE_CLK_PLL_SEL_APLL	= 0,
+	CORE_CLK_PLL_SEL_GPLL,
+	CORE_DIV_CON_SHIFT	= 0,
+	CORE_DIV_CON_MASK	= 0x0f << CORE_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL3_CON */
+	ACLK_VO_PLL_SHIFT	= 6,
+	ACLK_VO_PLL_MASK	= 0x3 << ACLK_VO_PLL_SHIFT,
+	ACLK_VO_SEL_GPLL	= 0,
+	ACLK_VO_SEL_CPLL,
+	ACLK_VO_SEL_NPLL,
+	ACLK_VO_DIV_SHIFT	= 0,
+	ACLK_VO_DIV_MASK	= 0x1f << ACLK_VO_DIV_SHIFT,
+
+	/* CRU_CLK_SEL5_CON */
+	DCLK_VOPB_SEL_SHIFT	= 14,
+	DCLK_VOPB_SEL_MASK	= 0x3 << DCLK_VOPB_SEL_SHIFT,
+	DCLK_VOPB_SEL_DIVOUT	= 0,
+	DCLK_VOPB_SEL_FRACOUT,
+	DCLK_VOPB_SEL_24M,
+	DCLK_VOPB_PLL_SEL_SHIFT	= 11,
+	DCLK_VOPB_PLL_SEL_MASK	= 0x1 << DCLK_VOPB_PLL_SEL_SHIFT,
+	DCLK_VOPB_PLL_SEL_CPLL	= 0,
+	DCLK_VOPB_PLL_SEL_NPLL,
+	DCLK_VOPB_DIV_SHIFT	= 0,
+	DCLK_VOPB_DIV_MASK	= 0xff,
+
+	/* CRU_CLK_SEL8_CON */
+	DCLK_VOPL_SEL_SHIFT	= 14,
+	DCLK_VOPL_SEL_MASK	= 0x3 << DCLK_VOPL_SEL_SHIFT,
+	DCLK_VOPL_SEL_DIVOUT	= 0,
+	DCLK_VOPL_SEL_FRACOUT,
+	DCLK_VOPL_SEL_24M,
+	DCLK_VOPL_PLL_SEL_SHIFT	= 11,
+	DCLK_VOPL_PLL_SEL_MASK	= 0x1 << DCLK_VOPL_PLL_SEL_SHIFT,
+	DCLK_VOPL_PLL_SEL_NPLL	= 0,
+	DCLK_VOPL_PLL_SEL_CPLL,
+	DCLK_VOPL_DIV_SHIFT	= 0,
+	DCLK_VOPL_DIV_MASK	= 0xff,
+
+	/* CRU_CLK_SEL14_CON */
+	PERI_PLL_SEL_SHIFT	= 15,
+	PERI_PLL_SEL_MASK	= 3 << PERI_PLL_SEL_SHIFT,
+	PERI_PLL_GPLL		= 0,
+	PERI_PLL_CPLL,
+	PERI_HCLK_DIV_SHIFT	= 8,
+	PERI_HCLK_DIV_MASK	= 0x1f << PERI_HCLK_DIV_SHIFT,
+	PERI_ACLK_DIV_SHIFT	= 0,
+	PERI_ACLK_DIV_MASK	= 0x1f << PERI_ACLK_DIV_SHIFT,
+
+	/* CRU_CLKSEL15_CON */
+	NANDC_CLK_SEL_SHIFT	= 15,
+	NANDC_CLK_SEL_MASK	= 0x1 << NANDC_CLK_SEL_SHIFT,
+	NANDC_CLK_SEL_NANDC	= 0,
+	NANDC_CLK_SEL_NANDC_DIV50,
+	NANDC_DIV50_SHIFT	= 8,
+	NANDC_DIV50_MASK	= 0x1f << NANDC_DIV50_SHIFT,
+	NANDC_PLL_SHIFT		= 6,
+	NANDC_PLL_MASK		= 0x3 << NANDC_PLL_SHIFT,
+	NANDC_SEL_GPLL		= 0,
+	NANDC_SEL_CPLL,
+	NANDC_SEL_NPLL,
+	NANDC_DIV_SHIFT		= 0,
+	NANDC_DIV_MASK		= 0x1f << NANDC_DIV_SHIFT,
+
+	/* CRU_CLKSEL20_CON */
+	EMMC_PLL_SHIFT		= 14,
+	EMMC_PLL_MASK		= 3 << EMMC_PLL_SHIFT,
+	EMMC_SEL_GPLL		= 0,
+	EMMC_SEL_CPLL,
+	EMMC_SEL_NPLL,
+	EMMC_SEL_24M,
+	EMMC_DIV_SHIFT		= 0,
+	EMMC_DIV_MASK		= 0xff << EMMC_DIV_SHIFT,
+
+	/* CRU_CLKSEL21_CON */
+	EMMC_CLK_SEL_SHIFT	= 15,
+	EMMC_CLK_SEL_MASK	= 1 << EMMC_CLK_SEL_SHIFT,
+	EMMC_CLK_SEL_EMMC	= 0,
+	EMMC_CLK_SEL_EMMC_DIV50,
+	EMMC_DIV50_SHIFT	= 0,
+	EMMC_DIV50_MASK		= 0xff << EMMC_DIV_SHIFT,
+
+	/* CRU_CLKSEL22_CON */
+	GMAC_PLL_SEL_SHIFT	= 14,
+	GMAC_PLL_SEL_MASK	= 3 << GMAC_PLL_SEL_SHIFT,
+	GMAC_PLL_SEL_GPLL	= 0,
+	GMAC_PLL_SEL_CPLL,
+	GMAC_PLL_SEL_NPLL,
+	CLK_GMAC_DIV_SHIFT	= 8,
+	CLK_GMAC_DIV_MASK	= 0x1f << CLK_GMAC_DIV_SHIFT,
+	SFC_PLL_SEL_SHIFT	= 7,
+	SFC_PLL_SEL_MASK	= 1 << SFC_PLL_SEL_SHIFT,
+	SFC_DIV_CON_SHIFT	= 0,
+	SFC_DIV_CON_MASK	= 0x7f,
+
+	/* CRU_CLK_SEL23_CON */
+	BUS_PLL_SEL_SHIFT	= 15,
+	BUS_PLL_SEL_MASK	= 1 << BUS_PLL_SEL_SHIFT,
+	BUS_PLL_SEL_GPLL	= 0,
+	BUS_PLL_SEL_CPLL,
+	BUS_ACLK_DIV_SHIFT	= 8,
+	BUS_ACLK_DIV_MASK	= 0x1f << BUS_ACLK_DIV_SHIFT,
+	RMII_CLK_SEL_SHIFT	= 7,
+	RMII_CLK_SEL_MASK	= 1 << RMII_CLK_SEL_SHIFT,
+	RMII_CLK_SEL_10M	= 0,
+	RMII_CLK_SEL_100M,
+	RMII_EXTCLK_SEL_SHIFT	= 6,
+	RMII_EXTCLK_SEL_MASK	= 1 << RMII_EXTCLK_SEL_SHIFT,
+	RMII_EXTCLK_SEL_INT	= 0,
+	RMII_EXTCLK_SEL_EXT,
+	PCLK_GMAC_DIV_SHIFT	= 0,
+	PCLK_GMAC_DIV_MASK	= 0x0f << PCLK_GMAC_DIV_SHIFT,
+
+	/* CRU_CLK_SEL24_CON */
+	BUS_PCLK_DIV_SHIFT	= 8,
+	BUS_PCLK_DIV_MASK	= 3 << BUS_PCLK_DIV_SHIFT,
+	BUS_HCLK_DIV_SHIFT	= 0,
+	BUS_HCLK_DIV_MASK	= 0x1f << BUS_HCLK_DIV_SHIFT,
+
+	/* CRU_CLK_SEL25_CON */
+	CRYPTO_APK_SEL_SHIFT	= 14,
+	CRYPTO_APK_PLL_SEL_MASK	= 3 << CRYPTO_APK_SEL_SHIFT,
+	CRYPTO_PLL_SEL_GPLL	= 0,
+	CRYPTO_PLL_SEL_CPLL,
+	CRYPTO_PLL_SEL_NPLL	= 0,
+	CRYPTO_APK_DIV_SHIFT	= 8,
+	CRYPTO_APK_DIV_MASK	= 0x1f << CRYPTO_APK_DIV_SHIFT,
+	CRYPTO_PLL_SEL_SHIFT	= 6,
+	CRYPTO_PLL_SEL_MASK	= 3 << CRYPTO_PLL_SEL_SHIFT,
+	CRYPTO_DIV_SHIFT	= 0,
+	CRYPTO_DIV_MASK		= 0x1f << CRYPTO_DIV_SHIFT,
+
+	/* CRU_CLK_SEL30_CON */
+	CLK_I2S1_DIV_CON_MASK	= 0x7f,
+	CLK_I2S1_PLL_SEL_MASK	= 0X1 << 8,
+	CLK_I2S1_PLL_SEL_GPLL	= 0X0 << 8,
+	CLK_I2S1_PLL_SEL_NPLL	= 0X1 << 8,
+	CLK_I2S1_SEL_MASK	= 0x3 << 10,
+	CLK_I2S1_SEL_I2S1	= 0x0 << 10,
+	CLK_I2S1_SEL_FRAC	= 0x1 << 10,
+	CLK_I2S1_SEL_MCLK_IN	= 0x2 << 10,
+	CLK_I2S1_SEL_OSC	= 0x3 << 10,
+	CLK_I2S1_OUT_SEL_MASK	= 0x1 << 15,
+	CLK_I2S1_OUT_SEL_I2S1	= 0x0 << 15,
+	CLK_I2S1_OUT_SEL_OSC	= 0x1 << 15,
+
+	/* CRU_CLK_SEL31_CON */
+	CLK_I2S1_FRAC_NUMERATOR_SHIFT	= 16,
+	CLK_I2S1_FRAC_NUMERATOR_MASK	= 0xffff << 16,
+	CLK_I2S1_FRAC_DENOMINATOR_SHIFT	= 0,
+	CLK_I2S1_FRAC_DENOMINATOR_MASK	= 0xffff,
+
+	/* CRU_CLK_SEL34_CON */
+	UART1_PLL_SEL_SHIFT	= 14,
+	UART1_PLL_SEL_MASK	= 3 << UART1_PLL_SEL_SHIFT,
+	UART1_PLL_SEL_GPLL	= 0,
+	UART1_PLL_SEL_24M,
+	UART1_PLL_SEL_480M,
+	UART1_PLL_SEL_NPLL,
+	UART1_DIV_CON_SHIFT	= 0,
+	UART1_DIV_CON_MASK	= 0x1f << UART1_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL35_CON */
+	UART1_CLK_SEL_SHIFT	= 14,
+	UART1_CLK_SEL_MASK	= 3 << UART1_PLL_SEL_SHIFT,
+	UART1_CLK_SEL_UART1	= 0,
+	UART1_CLK_SEL_UART1_NP5,
+	UART1_CLK_SEL_UART1_FRAC,
+	UART1_DIVNP5_SHIFT	= 0,
+	UART1_DIVNP5_MASK	= 0x1f << UART1_DIVNP5_SHIFT,
+
+	/* CRU_CLK_SEL37_CON */
+	UART2_PLL_SEL_SHIFT	= 14,
+	UART2_PLL_SEL_MASK	= 3 << UART2_PLL_SEL_SHIFT,
+	UART2_PLL_SEL_GPLL	= 0,
+	UART2_PLL_SEL_24M,
+	UART2_PLL_SEL_480M,
+	UART2_PLL_SEL_NPLL,
+	UART2_DIV_CON_SHIFT	= 0,
+	UART2_DIV_CON_MASK	= 0x1f << UART2_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL38_CON */
+	UART2_CLK_SEL_SHIFT	= 14,
+	UART2_CLK_SEL_MASK	= 3 << UART2_PLL_SEL_SHIFT,
+	UART2_CLK_SEL_UART2	= 0,
+	UART2_CLK_SEL_UART2_NP5,
+	UART2_CLK_SEL_UART2_FRAC,
+	UART2_DIVNP5_SHIFT	= 0,
+	UART2_DIVNP5_MASK	= 0x1f << UART2_DIVNP5_SHIFT,
+
+	/* CRU_CLK_SEL46_CON */
+	UART5_PLL_SEL_SHIFT	= 14,
+	UART5_PLL_SEL_MASK	= 3 << UART5_PLL_SEL_SHIFT,
+	UART5_PLL_SEL_GPLL	= 0,
+	UART5_PLL_SEL_24M,
+	UART5_PLL_SEL_480M,
+	UART5_PLL_SEL_NPLL,
+	UART5_DIV_CON_SHIFT	= 0,
+	UART5_DIV_CON_MASK	= 0x1f << UART5_DIV_CON_SHIFT,
+
+	/* CRU_CLK_SEL47_CON */
+	UART5_CLK_SEL_SHIFT	= 14,
+	UART5_CLK_SEL_MASK	= 3 << UART5_PLL_SEL_SHIFT,
+	UART5_CLK_SEL_UART5	= 0,
+	UART5_CLK_SEL_UART5_NP5,
+	UART5_CLK_SEL_UART5_FRAC,
+	UART5_DIVNP5_SHIFT	= 0,
+	UART5_DIVNP5_MASK	= 0x1f << UART5_DIVNP5_SHIFT,
+
+	/* CRU_CLK_SEL49_CON */
+	CLK_I2C_PLL_SEL_GPLL		= 0,
+	CLK_I2C_PLL_SEL_24M,
+	CLK_I2C_DIV_CON_MASK		= 0x7f,
+	CLK_I2C_PLL_SEL_MASK		= 1,
+	CLK_I2C1_PLL_SEL_SHIFT		= 15,
+	CLK_I2C1_DIV_CON_SHIFT		= 8,
+	CLK_I2C0_PLL_SEL_SHIFT		= 7,
+	CLK_I2C0_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL50_CON */
+	CLK_I2C3_PLL_SEL_SHIFT		= 15,
+	CLK_I2C3_DIV_CON_SHIFT		= 8,
+	CLK_I2C2_PLL_SEL_SHIFT		= 7,
+	CLK_I2C2_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL52_CON */
+	CLK_PWM_PLL_SEL_GPLL		= 0,
+	CLK_PWM_PLL_SEL_24M,
+	CLK_PWM_DIV_CON_MASK		= 0x7f,
+	CLK_PWM_PLL_SEL_MASK		= 1,
+	CLK_PWM1_PLL_SEL_SHIFT		= 15,
+	CLK_PWM1_DIV_CON_SHIFT		= 8,
+	CLK_PWM0_PLL_SEL_SHIFT		= 7,
+	CLK_PWM0_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL53_CON */
+	CLK_SPI_PLL_SEL_GPLL		= 0,
+	CLK_SPI_PLL_SEL_24M,
+	CLK_SPI_DIV_CON_MASK		= 0x7f,
+	CLK_SPI_PLL_SEL_MASK		= 1,
+	CLK_SPI1_PLL_SEL_SHIFT		= 15,
+	CLK_SPI1_DIV_CON_SHIFT		= 8,
+	CLK_SPI0_PLL_SEL_SHIFT		= 7,
+	CLK_SPI0_DIV_CON_SHIFT		= 0,
+
+	/* CRU_CLK_SEL55_CON */
+	CLK_SARADC_DIV_CON_SHIFT	= 0,
+	CLK_SARADC_DIV_CON_MASK		= 0x7ff,
+
+	/* CRU_CLK_GATE10_CON */
+	CLK_I2S1_OUT_MCLK_PAD_MASK	= 0x1 << 9,
+	CLK_I2S1_OUT_MCLK_PAD_ENABLE	= 0x1 << 9,
+	CLK_I2S1_OUT_MCLK_PAD_DISABLE	= 0x0 << 9,
+
+	/* CRU_PMU_MODE */
+	GPLL_MODE_SHIFT			= 0,
+	GPLL_MODE_MASK			= 3 << GPLL_MODE_SHIFT,
+
+	/* CRU_PMU_CLK_SEL0_CON */
+	CLK_PMU_PCLK_DIV_SHIFT		= 0,
+	CLK_PMU_PCLK_DIV_MASK		= 0x1f << CLK_PMU_PCLK_DIV_SHIFT,
+};
+#endif
diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index 41cfb7ad3f..f9134fd51f 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -3,6 +3,7 @@
 # Copyright (c) 2017 Rockchip Electronics Co., Ltd
 #
 
+obj-$(CONFIG_ROCKCHIP_PX30) += clk_px30.o
 obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o
 obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o
 obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o
diff --git a/drivers/clk/rockchip/clk_px30.c b/drivers/clk/rockchip/clk_px30.c
new file mode 100644
index 0000000000..36764c128b
--- /dev/null
+++ b/drivers/clk/rockchip/clk_px30.c
@@ -0,0 +1,1630 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <bitfield.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/io.h>
+#include <dm/lists.h>
+#include <dt-bindings/clock/px30-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	VCO_MAX_HZ	= 3200U * 1000000,
+	VCO_MIN_HZ	= 800 * 1000000,
+	OUTPUT_MAX_HZ	= 3200U * 1000000,
+	OUTPUT_MIN_HZ	= 24 * 1000000,
+};
+
+#define PX30_VOP_PLL_LIMIT			600000000
+
+#define PX30_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1,	\
+			_postdiv2, _dsmpd, _frac)		\
+{								\
+	.rate	= _rate##U,					\
+	.fbdiv = _fbdiv,					\
+	.postdiv1 = _postdiv1,					\
+	.refdiv = _refdiv,					\
+	.postdiv2 = _postdiv2,					\
+	.dsmpd = _dsmpd,					\
+	.frac = _frac,						\
+}
+
+#define PX30_CPUCLK_RATE(_rate, _aclk_div, _pclk_div)		\
+{								\
+	.rate	= _rate##U,					\
+	.aclk_div = _aclk_div,					\
+	.pclk_div = _pclk_div,					\
+}
+
+#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+
+#define PX30_CLK_DUMP(_id, _name, _iscru)	\
+{						\
+	.id = _id,				\
+	.name = _name,				\
+	.is_cru = _iscru,			\
+}
+
+static struct pll_rate_table px30_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	PX30_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	PX30_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+	PX30_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+	PX30_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	PX30_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+	PX30_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+	PX30_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
+};
+
+static struct cpu_rate_table px30_cpu_rates[] = {
+	PX30_CPUCLK_RATE(1200000000, 1, 5),
+	PX30_CPUCLK_RATE(1008000000, 1, 5),
+	PX30_CPUCLK_RATE(816000000, 1, 3),
+	PX30_CPUCLK_RATE(600000000, 1, 3),
+	PX30_CPUCLK_RATE(408000000, 1, 1),
+};
+
+static u8 pll_mode_shift[PLL_COUNT] = {
+	APLL_MODE_SHIFT, DPLL_MODE_SHIFT, CPLL_MODE_SHIFT,
+	NPLL_MODE_SHIFT, GPLL_MODE_SHIFT
+};
+
+static u32 pll_mode_mask[PLL_COUNT] = {
+	APLL_MODE_MASK, DPLL_MODE_MASK, CPLL_MODE_MASK,
+	NPLL_MODE_MASK, GPLL_MODE_MASK
+};
+
+static struct pll_rate_table auto_table;
+
+static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
+				   enum px30_pll_id pll_id);
+
+static struct pll_rate_table *pll_clk_set_by_auto(u32 drate)
+{
+	struct pll_rate_table *rate = &auto_table;
+	u32 ref_khz = OSC_HZ / KHz, refdiv, fbdiv = 0;
+	u32 postdiv1, postdiv2 = 1;
+	u32 fref_khz;
+	u32 diff_khz, best_diff_khz;
+	const u32 max_refdiv = 63, max_fbdiv = 3200, min_fbdiv = 16;
+	const u32 max_postdiv1 = 7, max_postdiv2 = 7;
+	u32 vco_khz;
+	u32 rate_khz = drate / KHz;
+
+	if (!drate) {
+		printf("%s: the frequency can't be 0 Hz\n", __func__);
+		return NULL;
+	}
+
+	postdiv1 = DIV_ROUND_UP(VCO_MIN_HZ / 1000, rate_khz);
+	if (postdiv1 > max_postdiv1) {
+		postdiv2 = DIV_ROUND_UP(postdiv1, max_postdiv1);
+		postdiv1 = DIV_ROUND_UP(postdiv1, postdiv2);
+	}
+
+	vco_khz = rate_khz * postdiv1 * postdiv2;
+
+	if (vco_khz < (VCO_MIN_HZ / KHz) || vco_khz > (VCO_MAX_HZ / KHz) ||
+	    postdiv2 > max_postdiv2) {
+		printf("%s: Cannot find out a supported VCO for Freq (%uHz)\n",
+		       __func__, rate_khz);
+		return NULL;
+	}
+
+	rate->postdiv1 = postdiv1;
+	rate->postdiv2 = postdiv2;
+
+	best_diff_khz = vco_khz;
+	for (refdiv = 1; refdiv < max_refdiv && best_diff_khz; refdiv++) {
+		fref_khz = ref_khz / refdiv;
+
+		fbdiv = vco_khz / fref_khz;
+		if (fbdiv >= max_fbdiv || fbdiv <= min_fbdiv)
+			continue;
+
+		diff_khz = vco_khz - fbdiv * fref_khz;
+		if (fbdiv + 1 < max_fbdiv && diff_khz > fref_khz / 2) {
+			fbdiv++;
+			diff_khz = fref_khz - diff_khz;
+		}
+
+		if (diff_khz >= best_diff_khz)
+			continue;
+
+		best_diff_khz = diff_khz;
+		rate->refdiv = refdiv;
+		rate->fbdiv = fbdiv;
+	}
+
+	if (best_diff_khz > 4 * (MHz / KHz)) {
+		printf("%s: Failed to match output frequency %u bestis %u Hz\n",
+		       __func__, rate_khz,
+		       best_diff_khz * KHz);
+		return NULL;
+	}
+
+	return rate;
+}
+
+static const struct pll_rate_table *get_pll_settings(unsigned long rate)
+{
+	unsigned int rate_count = ARRAY_SIZE(px30_pll_rates);
+	int i;
+
+	for (i = 0; i < rate_count; i++) {
+		if (rate == px30_pll_rates[i].rate)
+			return &px30_pll_rates[i];
+	}
+
+	return pll_clk_set_by_auto(rate);
+}
+
+static const struct cpu_rate_table *get_cpu_settings(unsigned long rate)
+{
+	unsigned int rate_count = ARRAY_SIZE(px30_cpu_rates);
+	int i;
+
+	for (i = 0; i < rate_count; i++) {
+		if (rate == px30_cpu_rates[i].rate)
+			return &px30_cpu_rates[i];
+	}
+
+	return NULL;
+}
+
+/*
+ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
+ * Formulas also embedded within the Fractional PLL Verilog model:
+ * If DSMPD = 1 (DSM is disabled, "integer mode")
+ * FOUTVCO = FREF / REFDIV * FBDIV
+ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
+ * Where:
+ * FOUTVCO = Fractional PLL non-divided output frequency
+ * FOUTPOSTDIV = Fractional PLL divided output frequency
+ *               (output of second post divider)
+ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
+ * REFDIV = Fractional PLL input reference clock divider
+ * FBDIV = Integer value programmed into feedback divide
+ *
+ */
+static int rkclk_set_pll(struct px30_pll *pll, unsigned int *mode,
+			 enum px30_pll_id pll_id,
+			 unsigned long drate)
+{
+	const struct pll_rate_table *rate;
+	uint vco_hz, output_hz;
+
+	rate = get_pll_settings(drate);
+	if (!rate) {
+		printf("%s unsupport rate\n", __func__);
+		return -EINVAL;
+	}
+
+	/* All PLLs have same VCO and output frequency range restrictions. */
+	vco_hz = OSC_HZ / 1000 * rate->fbdiv / rate->refdiv * 1000;
+	output_hz = vco_hz / rate->postdiv1 / rate->postdiv2;
+
+	debug("PLL at %p: fb=%d, ref=%d, pst1=%d, pst2=%d, vco=%u Hz, output=%u Hz\n",
+	      pll, rate->fbdiv, rate->refdiv, rate->postdiv1,
+	      rate->postdiv2, 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);
+
+	/*
+	 * When power on or changing PLL setting,
+	 * we must force PLL into slow mode to ensure output stable clock.
+	 */
+	rk_clrsetreg(mode, pll_mode_mask[pll_id],
+		     PLLMUX_FROM_XIN24M << pll_mode_shift[pll_id]);
+
+	/* use integer mode */
+	rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+	/* Power down */
+	rk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+	rk_clrsetreg(&pll->con0,
+		     PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
+		     (rate->postdiv1 << PLL_POSTDIV1_SHIFT) | rate->fbdiv);
+	rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+		     (rate->postdiv2 << PLL_POSTDIV2_SHIFT |
+		     rate->refdiv << PLL_REFDIV_SHIFT));
+
+	/* Power Up */
+	rk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);
+
+	/* waiting for pll lock */
+	while (!(readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT)))
+		udelay(1);
+
+	rk_clrsetreg(mode, pll_mode_mask[pll_id],
+		     PLLMUX_FROM_PLL << pll_mode_shift[pll_id]);
+
+	return 0;
+}
+
+static uint32_t rkclk_pll_get_rate(struct px30_pll *pll, unsigned int *mode,
+				   enum px30_pll_id pll_id)
+{
+	u32 refdiv, fbdiv, postdiv1, postdiv2;
+	u32 con, shift, mask;
+
+	con = readl(mode);
+	shift = pll_mode_shift[pll_id];
+	mask = pll_mode_mask[pll_id];
+
+	switch ((con & mask) >> shift) {
+	case PLLMUX_FROM_XIN24M:
+		return OSC_HZ;
+	case PLLMUX_FROM_PLL:
+		/* normal mode */
+		con = readl(&pll->con0);
+		postdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;
+		fbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
+		con = readl(&pll->con1);
+		postdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;
+		refdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;
+		return (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+	case PLLMUX_FROM_RTC32K:
+	default:
+		return 32768;
+	}
+}
+
+static ulong px30_i2c_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_I2C0:
+		con = readl(&cru->clksel_con[49]);
+		div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	case SCLK_I2C1:
+		con = readl(&cru->clksel_con[49]);
+		div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	case SCLK_I2C2:
+		con = readl(&cru->clksel_con[50]);
+		div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	case SCLK_I2C3:
+		con = readl(&cru->clksel_con[50]);
+		div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK;
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_i2c_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_I2C0:
+		rk_clrsetreg(&cru->clksel_con[49],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT);
+		break;
+	case SCLK_I2C1:
+		rk_clrsetreg(&cru->clksel_con[49],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT);
+		break;
+	case SCLK_I2C2:
+		rk_clrsetreg(&cru->clksel_con[50],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT);
+		break;
+	case SCLK_I2C3:
+		rk_clrsetreg(&cru->clksel_con[50],
+			     CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT |
+			     CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this i2c bus\n");
+		return -EINVAL;
+	}
+
+	return px30_i2c_get_clk(priv, clk_id);
+}
+
+/*
+ * calculate best rational approximation for a given fraction
+ * taking into account restricted register size, e.g. to find
+ * appropriate values for a pll with 5 bit denominator and
+ * 8 bit numerator register fields, trying to set up with a
+ * frequency ratio of 3.1415, one would say:
+ *
+ * rational_best_approximation(31415, 10000,
+ *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look@given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+static void rational_best_approximation(unsigned long given_numerator,
+					unsigned long given_denominator,
+					unsigned long max_numerator,
+					unsigned long max_denominator,
+					unsigned long *best_numerator,
+					unsigned long *best_denominator)
+{
+	unsigned long n, d, n0, d0, n1, d1;
+
+	n = given_numerator;
+	d = given_denominator;
+	n0 = 0;
+	d1 = 0;
+	n1 = 1;
+	d0 = 1;
+	for (;;) {
+		unsigned long t, a;
+
+		if (n1 > max_numerator || d1 > max_denominator) {
+			n1 = n0;
+			d1 = d0;
+			break;
+		}
+		if (d == 0)
+			break;
+		t = d;
+		a = n / d;
+		d = n % d;
+		n = t;
+		t = n0 + a * n1;
+		n0 = n1;
+		n1 = t;
+		t = d0 + a * d1;
+		d0 = d1;
+		d1 = t;
+	}
+	*best_numerator = n1;
+	*best_denominator = d1;
+}
+
+static ulong px30_i2s_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	u32 con, fracdiv, gate;
+	u32 clk_src = priv->gpll_hz / 2;
+	unsigned long m, n;
+	struct px30_cru *cru = priv->cru;
+
+	switch (clk_id) {
+	case SCLK_I2S1:
+		con = readl(&cru->clksel_con[30]);
+		fracdiv = readl(&cru->clksel_con[31]);
+		gate = readl(&cru->clkgate_con[10]);
+		m = fracdiv & CLK_I2S1_FRAC_NUMERATOR_MASK;
+		m >>= CLK_I2S1_FRAC_NUMERATOR_SHIFT;
+		n = fracdiv & CLK_I2S1_FRAC_DENOMINATOR_MASK;
+		n >>= CLK_I2S1_FRAC_DENOMINATOR_SHIFT;
+		debug("con30: 0x%x, gate: 0x%x, frac: 0x%x\n",
+		      con, gate, fracdiv);
+		break;
+	default:
+		printf("do not support this i2s bus\n");
+		return -EINVAL;
+	}
+
+	return clk_src * n / m;
+}
+
+static ulong px30_i2s_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	u32 clk_src;
+	unsigned long m, n, val;
+	struct px30_cru *cru = priv->cru;
+
+	clk_src = priv->gpll_hz / 2;
+	rational_best_approximation(hz, clk_src,
+				    GENMASK(16 - 1, 0),
+				    GENMASK(16 - 1, 0),
+				    &m, &n);
+	switch (clk_id) {
+	case SCLK_I2S1:
+		rk_clrsetreg(&cru->clksel_con[30],
+			     CLK_I2S1_PLL_SEL_MASK, CLK_I2S1_PLL_SEL_GPLL);
+		rk_clrsetreg(&cru->clksel_con[30],
+			     CLK_I2S1_DIV_CON_MASK, 0x1);
+		rk_clrsetreg(&cru->clksel_con[30],
+			     CLK_I2S1_SEL_MASK, CLK_I2S1_SEL_FRAC);
+		val = m << CLK_I2S1_FRAC_NUMERATOR_SHIFT | n;
+		writel(val, &cru->clksel_con[31]);
+		rk_clrsetreg(&cru->clkgate_con[10],
+			     CLK_I2S1_OUT_MCLK_PAD_MASK,
+			     CLK_I2S1_OUT_MCLK_PAD_ENABLE);
+		break;
+	default:
+		printf("do not support this i2s bus\n");
+		return -EINVAL;
+	}
+
+	return px30_i2s_get_clk(priv, clk_id);
+}
+
+static ulong px30_nandc_get_clk(struct px30_clk_priv *priv)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[15]);
+	div = (con & NANDC_DIV_MASK) >> NANDC_DIV_SHIFT;
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_nandc_set_clk(struct px30_clk_priv *priv,
+				ulong set_rate)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	/* Select nandc source from GPLL by default */
+	/* nandc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, set_rate);
+	assert(src_clk_div - 1 <= 31);
+
+	rk_clrsetreg(&cru->clksel_con[15],
+		     NANDC_CLK_SEL_MASK | NANDC_PLL_MASK |
+		     NANDC_DIV_MASK,
+		     NANDC_CLK_SEL_NANDC << NANDC_CLK_SEL_SHIFT |
+		     NANDC_SEL_GPLL << NANDC_PLL_SHIFT |
+		     (src_clk_div - 1) << NANDC_DIV_SHIFT);
+
+	return px30_nandc_get_clk(priv);
+}
+
+static ulong px30_mmc_get_clk(struct px30_clk_priv *priv, uint clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, con_id;
+
+	switch (clk_id) {
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con_id = 16;
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		con_id = 20;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	con = readl(&cru->clksel_con[con_id]);
+	div = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;
+
+	if ((con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT
+	    == EMMC_SEL_24M)
+		return DIV_TO_RATE(OSC_HZ, div) / 2;
+	else
+		return DIV_TO_RATE(priv->gpll_hz, div) / 2;
+}
+
+static ulong px30_mmc_set_clk(struct px30_clk_priv *priv,
+			      ulong clk_id, ulong set_rate)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+	u32 con_id;
+
+	switch (clk_id) {
+	case HCLK_SDMMC:
+	case SCLK_SDMMC:
+		con_id = 16;
+		break;
+	case HCLK_EMMC:
+	case SCLK_EMMC:
+		con_id = 20;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Select clk_sdmmc/emmc source from GPLL by default */
+	/* mmc clock defaulg div 2 internal, need provide double in cru */
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz / 2, set_rate);
+
+	if (src_clk_div > 127) {
+		/* use 24MHz source for 400KHz clock */
+		src_clk_div = DIV_ROUND_UP(OSC_HZ / 2, set_rate);
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     EMMC_PLL_MASK | EMMC_DIV_MASK,
+			     EMMC_SEL_24M << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+	} else {
+		rk_clrsetreg(&cru->clksel_con[con_id],
+			     EMMC_PLL_MASK | EMMC_DIV_MASK,
+			     EMMC_SEL_GPLL << EMMC_PLL_SHIFT |
+			     (src_clk_div - 1) << EMMC_DIV_SHIFT);
+	}
+	rk_clrsetreg(&cru->clksel_con[con_id + 1], EMMC_CLK_SEL_MASK,
+		     EMMC_CLK_SEL_EMMC);
+
+	return px30_mmc_get_clk(priv, clk_id);
+}
+
+static ulong px30_pwm_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_PWM0:
+		con = readl(&cru->clksel_con[52]);
+		div = con >> CLK_PWM0_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
+		break;
+	case SCLK_PWM1:
+		con = readl(&cru->clksel_con[52]);
+		div = con >> CLK_PWM1_DIV_CON_SHIFT & CLK_PWM_DIV_CON_MASK;
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_pwm_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_PWM0:
+		rk_clrsetreg(&cru->clksel_con[52],
+			     CLK_PWM_DIV_CON_MASK << CLK_PWM0_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_MASK << CLK_PWM0_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_PWM0_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM0_PLL_SEL_SHIFT);
+		break;
+	case SCLK_PWM1:
+		rk_clrsetreg(&cru->clksel_con[52],
+			     CLK_PWM_DIV_CON_MASK << CLK_PWM1_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_MASK << CLK_PWM1_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_PWM1_DIV_CON_SHIFT |
+			     CLK_PWM_PLL_SEL_GPLL << CLK_PWM1_PLL_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return px30_pwm_get_clk(priv, clk_id);
+}
+
+static ulong px30_saradc_get_clk(struct px30_clk_priv *priv)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[55]);
+	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong px30_saradc_set_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
+	assert(src_clk_div - 1 <= 2047);
+
+	rk_clrsetreg(&cru->clksel_con[55],
+		     CLK_SARADC_DIV_CON_MASK,
+		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
+
+	return px30_saradc_get_clk(priv);
+}
+
+static ulong px30_tsadc_get_clk(struct px30_clk_priv *priv)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	con = readl(&cru->clksel_con[54]);
+	div = con >> CLK_SARADC_DIV_CON_SHIFT & CLK_SARADC_DIV_CON_MASK;
+
+	return DIV_TO_RATE(OSC_HZ, div);
+}
+
+static ulong px30_tsadc_set_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(OSC_HZ, hz);
+	assert(src_clk_div - 1 <= 2047);
+
+	rk_clrsetreg(&cru->clksel_con[54],
+		     CLK_SARADC_DIV_CON_MASK,
+		     (src_clk_div - 1) << CLK_SARADC_DIV_CON_SHIFT);
+
+	return px30_tsadc_get_clk(priv);
+}
+
+static ulong px30_spi_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con;
+
+	switch (clk_id) {
+	case SCLK_SPI0:
+		con = readl(&cru->clksel_con[53]);
+		div = con >> CLK_SPI0_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
+		break;
+	case SCLK_SPI1:
+		con = readl(&cru->clksel_con[53]);
+		div = con >> CLK_SPI1_DIV_CON_SHIFT & CLK_SPI_DIV_CON_MASK;
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_spi_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 127);
+
+	switch (clk_id) {
+	case SCLK_SPI0:
+		rk_clrsetreg(&cru->clksel_con[53],
+			     CLK_SPI_DIV_CON_MASK << CLK_SPI0_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_MASK << CLK_SPI0_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_SPI0_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI0_PLL_SEL_SHIFT);
+		break;
+	case SCLK_SPI1:
+		rk_clrsetreg(&cru->clksel_con[53],
+			     CLK_SPI_DIV_CON_MASK << CLK_SPI1_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_MASK << CLK_SPI1_PLL_SEL_SHIFT,
+			     (src_clk_div - 1) << CLK_SPI1_DIV_CON_SHIFT |
+			     CLK_SPI_PLL_SEL_GPLL << CLK_SPI1_PLL_SEL_SHIFT);
+		break;
+	default:
+		printf("do not support this pwm bus\n");
+		return -EINVAL;
+	}
+
+	return px30_spi_get_clk(priv, clk_id);
+}
+
+static ulong px30_vop_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+		con = readl(&cru->clksel_con[3]);
+		div = con & ACLK_VO_DIV_MASK;
+		parent = priv->gpll_hz;
+		break;
+	case DCLK_VOPB:
+		con = readl(&cru->clksel_con[5]);
+		div = con & DCLK_VOPB_DIV_MASK;
+		parent = rkclk_pll_get_rate(&cru->pll[CPLL], &cru->mode, CPLL);
+		break;
+	case DCLK_VOPL:
+		con = readl(&cru->clksel_con[8]);
+		div = con & DCLK_VOPL_DIV_MASK;
+		parent = rkclk_pll_get_rate(&cru->pll[NPLL], &cru->mode, NPLL);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_vop_set_clk(struct px30_clk_priv *priv, ulong clk_id, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	ulong npll_hz;
+	int src_clk_div;
+
+	switch (clk_id) {
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[3],
+			     ACLK_VO_PLL_MASK | ACLK_VO_DIV_MASK,
+			     ACLK_VO_SEL_GPLL << ACLK_VO_PLL_SHIFT |
+			     (src_clk_div - 1) << ACLK_VO_DIV_SHIFT);
+		break;
+	case DCLK_VOPB:
+		if (hz < PX30_VOP_PLL_LIMIT) {
+			src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT, hz);
+			if (src_clk_div % 2)
+				src_clk_div = src_clk_div - 1;
+		} else {
+			src_clk_div = 1;
+		}
+		assert(src_clk_div - 1 <= 255);
+		rkclk_set_pll(&cru->pll[CPLL], &cru->mode,
+			      CPLL, hz * src_clk_div);
+		rk_clrsetreg(&cru->clksel_con[5],
+			     DCLK_VOPB_SEL_MASK | DCLK_VOPB_PLL_SEL_MASK |
+			     DCLK_VOPB_DIV_MASK,
+			     DCLK_VOPB_SEL_DIVOUT << DCLK_VOPB_SEL_SHIFT |
+			     DCLK_VOPB_PLL_SEL_CPLL << DCLK_VOPB_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << DCLK_VOPB_DIV_SHIFT);
+		break;
+	case DCLK_VOPL:
+		npll_hz = px30_clk_get_pll_rate(priv, NPLL);
+		if (npll_hz >= PX30_VOP_PLL_LIMIT && npll_hz >= hz &&
+		    npll_hz % hz == 0) {
+			src_clk_div = npll_hz / hz;
+			assert(src_clk_div - 1 <= 255);
+		} else {
+			if (hz < PX30_VOP_PLL_LIMIT) {
+				src_clk_div = DIV_ROUND_UP(PX30_VOP_PLL_LIMIT,
+							   hz);
+				if (src_clk_div % 2)
+					src_clk_div = src_clk_div - 1;
+			} else {
+				src_clk_div = 1;
+			}
+			assert(src_clk_div - 1 <= 255);
+			rkclk_set_pll(&cru->pll[NPLL], &cru->mode, NPLL,
+				      hz * src_clk_div);
+		}
+		rk_clrsetreg(&cru->clksel_con[8],
+			     DCLK_VOPL_SEL_MASK | DCLK_VOPL_PLL_SEL_MASK |
+			     DCLK_VOPL_DIV_MASK,
+			     DCLK_VOPL_SEL_DIVOUT << DCLK_VOPL_SEL_SHIFT |
+			     DCLK_VOPL_PLL_SEL_NPLL << DCLK_VOPL_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << DCLK_VOPL_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this vop freq\n");
+		return -EINVAL;
+	}
+
+	return px30_vop_get_clk(priv, clk_id);
+}
+
+static ulong px30_bus_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case ACLK_BUS_PRE:
+		con = readl(&cru->clksel_con[23]);
+		div = (con & BUS_ACLK_DIV_MASK) >> BUS_ACLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case HCLK_BUS_PRE:
+		con = readl(&cru->clksel_con[24]);
+		div = (con & BUS_HCLK_DIV_MASK) >> BUS_HCLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case PCLK_BUS_PRE:
+	case PCLK_WDT_NS:
+		parent = px30_bus_get_clk(priv, ACLK_BUS_PRE);
+		con = readl(&cru->clksel_con[24]);
+		div = (con & BUS_PCLK_DIV_MASK) >> BUS_PCLK_DIV_SHIFT;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_bus_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+			      ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	/*
+	 * select gpll as pd_bus bus clock source and
+	 * set up dependent divisors for PCLK/HCLK and ACLK clocks.
+	 */
+	switch (clk_id) {
+	case ACLK_BUS_PRE:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[23],
+			     BUS_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,
+			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << BUS_ACLK_DIV_SHIFT);
+		break;
+	case HCLK_BUS_PRE:
+		src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+		assert(src_clk_div - 1 <= 31);
+		rk_clrsetreg(&cru->clksel_con[24],
+			     BUS_PLL_SEL_MASK | BUS_HCLK_DIV_MASK,
+			     BUS_PLL_SEL_GPLL << BUS_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << BUS_HCLK_DIV_SHIFT);
+		break;
+	case PCLK_BUS_PRE:
+		src_clk_div =
+			DIV_ROUND_UP(px30_bus_get_clk(priv, ACLK_BUS_PRE), hz);
+		assert(src_clk_div - 1 <= 3);
+		rk_clrsetreg(&cru->clksel_con[24],
+			     BUS_PCLK_DIV_MASK,
+			     (src_clk_div - 1) << BUS_PCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this bus freq\n");
+		return -EINVAL;
+	}
+
+	return px30_bus_get_clk(priv, clk_id);
+}
+
+static ulong px30_peri_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case ACLK_PERI_PRE:
+		con = readl(&cru->clksel_con[14]);
+		div = (con & PERI_ACLK_DIV_MASK) >> PERI_ACLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case HCLK_PERI_PRE:
+		con = readl(&cru->clksel_con[14]);
+		div = (con & PERI_HCLK_DIV_MASK) >> PERI_HCLK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_peri_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+			       ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select gpll as pd_peri bus clock source and
+	 * set up dependent divisors for HCLK and ACLK clocks.
+	 */
+	switch (clk_id) {
+	case ACLK_PERI_PRE:
+		rk_clrsetreg(&cru->clksel_con[14],
+			     PERI_PLL_SEL_MASK | PERI_ACLK_DIV_MASK,
+			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << PERI_ACLK_DIV_SHIFT);
+		break;
+	case HCLK_PERI_PRE:
+		rk_clrsetreg(&cru->clksel_con[14],
+			     PERI_PLL_SEL_MASK | PERI_HCLK_DIV_MASK,
+			     PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << PERI_HCLK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this peri freq\n");
+		return -EINVAL;
+	}
+
+	return px30_peri_get_clk(priv, clk_id);
+}
+
+#ifndef CONFIG_SPL_BUILD
+static ulong px30_crypto_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 div, con, parent;
+
+	switch (clk_id) {
+	case SCLK_CRYPTO:
+		con = readl(&cru->clksel_con[25]);
+		div = (con & CRYPTO_DIV_MASK) >> CRYPTO_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	case SCLK_CRYPTO_APK:
+		con = readl(&cru->clksel_con[25]);
+		div = (con & CRYPTO_APK_DIV_MASK) >> CRYPTO_APK_DIV_SHIFT;
+		parent = priv->gpll_hz;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return DIV_TO_RATE(parent, div);
+}
+
+static ulong px30_crypto_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+				 ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	/*
+	 * select gpll as crypto clock source and
+	 * set up dependent divisors for crypto clocks.
+	 */
+	switch (clk_id) {
+	case SCLK_CRYPTO:
+		rk_clrsetreg(&cru->clksel_con[25],
+			     CRYPTO_PLL_SEL_MASK | CRYPTO_DIV_MASK,
+			     CRYPTO_PLL_SEL_GPLL << CRYPTO_PLL_SEL_SHIFT |
+			     (src_clk_div - 1) << CRYPTO_DIV_SHIFT);
+		break;
+	case SCLK_CRYPTO_APK:
+		rk_clrsetreg(&cru->clksel_con[25],
+			     CRYPTO_APK_PLL_SEL_MASK | CRYPTO_APK_DIV_MASK,
+			     CRYPTO_PLL_SEL_GPLL << CRYPTO_APK_SEL_SHIFT |
+			     (src_clk_div - 1) << CRYPTO_APK_DIV_SHIFT);
+		break;
+	default:
+		printf("do not support this peri freq\n");
+		return -EINVAL;
+	}
+
+	return px30_crypto_get_clk(priv, clk_id);
+}
+
+static ulong px30_i2s1_mclk_get_clk(struct px30_clk_priv *priv, ulong clk_id)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 con;
+
+	con = readl(&cru->clksel_con[30]);
+
+	if (!(con & CLK_I2S1_OUT_SEL_MASK))
+		return -ENOENT;
+
+	return 12000000;
+}
+
+static ulong px30_i2s1_mclk_set_clk(struct px30_clk_priv *priv, ulong clk_id,
+				    ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+
+	if (hz != 12000000) {
+		printf("do not support this i2s1_mclk freq\n");
+		return -EINVAL;
+	}
+
+	rk_clrsetreg(&cru->clksel_con[30], CLK_I2S1_OUT_SEL_MASK,
+		     CLK_I2S1_OUT_SEL_OSC);
+	rk_clrsetreg(&cru->clkgate_con[10], CLK_I2S1_OUT_MCLK_PAD_MASK,
+		     CLK_I2S1_OUT_MCLK_PAD_ENABLE);
+
+	return px30_i2s1_mclk_get_clk(priv, clk_id);
+}
+
+static ulong px30_mac_set_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+	u32 con = readl(&cru->clksel_con[22]);
+	ulong pll_rate;
+	u8 div;
+
+	if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_CPLL)
+		pll_rate = px30_clk_get_pll_rate(priv, CPLL);
+	else if ((con >> GMAC_PLL_SEL_SHIFT) & GMAC_PLL_SEL_NPLL)
+		pll_rate = px30_clk_get_pll_rate(priv, NPLL);
+	else
+		pll_rate = priv->gpll_hz;
+
+	/*default set 50MHZ for gmac*/
+	if (!hz)
+		hz = 50000000;
+
+	div = DIV_ROUND_UP(pll_rate, hz) - 1;
+	assert(div < 32);
+	rk_clrsetreg(&cru->clksel_con[22], CLK_GMAC_DIV_MASK,
+		     div << CLK_GMAC_DIV_SHIFT);
+
+	return DIV_TO_RATE(pll_rate, div);
+}
+
+static int px30_mac_set_speed_clk(struct px30_clk_priv *priv, uint hz)
+{
+	struct px30_cru *cru = priv->cru;
+
+	if (hz != 2500000 && hz != 25000000) {
+		debug("Unsupported mac speed:%d\n", hz);
+		return -EINVAL;
+	}
+
+	rk_clrsetreg(&cru->clksel_con[23], RMII_CLK_SEL_MASK,
+		     ((hz == 2500000) ? 0 : 1) << RMII_CLK_SEL_SHIFT);
+
+	return 0;
+}
+
+#endif
+
+static ulong px30_clk_get_pll_rate(struct px30_clk_priv *priv,
+				   enum px30_pll_id pll_id)
+{
+	struct px30_cru *cru = priv->cru;
+
+	return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
+}
+
+static ulong px30_clk_set_pll_rate(struct px30_clk_priv *priv,
+				   enum px30_pll_id pll_id, ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+
+	if (rkclk_set_pll(&cru->pll[pll_id], &cru->mode, pll_id, hz))
+		return -EINVAL;
+	return rkclk_pll_get_rate(&cru->pll[pll_id], &cru->mode, pll_id);
+}
+
+static ulong px30_armclk_set_clk(struct px30_clk_priv *priv, ulong hz)
+{
+	struct px30_cru *cru = priv->cru;
+	const struct cpu_rate_table *rate;
+	ulong old_rate;
+
+	rate = get_cpu_settings(hz);
+	if (!rate) {
+		printf("%s unsupport rate\n", __func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * select apll as cpu/core clock pll source and
+	 * set up dependent divisors for PERI and ACLK clocks.
+	 * core hz : apll = 1:1
+	 */
+	old_rate = px30_clk_get_pll_rate(priv, APLL);
+	if (old_rate > hz) {
+		if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
+			return -EINVAL;
+		rk_clrsetreg(&cru->clksel_con[0],
+			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
+			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
+			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
+			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
+			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+			     0 << CORE_DIV_CON_SHIFT);
+	} else if (old_rate < hz) {
+		rk_clrsetreg(&cru->clksel_con[0],
+			     CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK |
+			     CORE_ACLK_DIV_MASK | CORE_DBG_DIV_MASK,
+			     rate->aclk_div << CORE_ACLK_DIV_SHIFT |
+			     rate->pclk_div << CORE_DBG_DIV_SHIFT |
+			     CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |
+			     0 << CORE_DIV_CON_SHIFT);
+		if (rkclk_set_pll(&cru->pll[APLL], &cru->mode, APLL, hz))
+			return -EINVAL;
+	}
+
+	return px30_clk_get_pll_rate(priv, APLL);
+}
+
+static ulong px30_clk_get_rate(struct clk *clk)
+{
+	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	if (!priv->gpll_hz && clk->id > ARMCLK) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	debug("%s %ld\n", __func__, clk->id);
+	switch (clk->id) {
+	case PLL_APLL:
+		rate = px30_clk_get_pll_rate(priv, APLL);
+		break;
+	case PLL_DPLL:
+		rate = px30_clk_get_pll_rate(priv, DPLL);
+		break;
+	case PLL_CPLL:
+		rate = px30_clk_get_pll_rate(priv, CPLL);
+		break;
+	case PLL_NPLL:
+		rate = px30_clk_get_pll_rate(priv, NPLL);
+		break;
+	case ARMCLK:
+		rate = px30_clk_get_pll_rate(priv, APLL);
+		break;
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+	case SCLK_EMMC_SAMPLE:
+		rate = px30_mmc_get_clk(priv, clk->id);
+		break;
+	case SCLK_I2C0:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		rate = px30_i2c_get_clk(priv, clk->id);
+		break;
+	case SCLK_I2S1:
+		rate = px30_i2s_get_clk(priv, clk->id);
+		break;
+	case SCLK_NANDC:
+		rate = px30_nandc_get_clk(priv);
+		break;
+	case SCLK_PWM0:
+	case SCLK_PWM1:
+		rate = px30_pwm_get_clk(priv, clk->id);
+		break;
+	case SCLK_SARADC:
+		rate = px30_saradc_get_clk(priv);
+		break;
+	case SCLK_TSADC:
+		rate = px30_tsadc_get_clk(priv);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		rate = px30_spi_get_clk(priv, clk->id);
+		break;
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+	case DCLK_VOPB:
+	case DCLK_VOPL:
+		rate = px30_vop_get_clk(priv, clk->id);
+		break;
+	case ACLK_BUS_PRE:
+	case HCLK_BUS_PRE:
+	case PCLK_BUS_PRE:
+	case PCLK_WDT_NS:
+		rate = px30_bus_get_clk(priv, clk->id);
+		break;
+	case ACLK_PERI_PRE:
+	case HCLK_PERI_PRE:
+		rate = px30_peri_get_clk(priv, clk->id);
+		break;
+#ifndef CONFIG_SPL_BUILD
+	case SCLK_CRYPTO:
+	case SCLK_CRYPTO_APK:
+		rate = px30_crypto_get_clk(priv, clk->id);
+		break;
+#endif
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong px30_clk_set_rate(struct clk *clk, ulong rate)
+{
+	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	if (!priv->gpll_hz && clk->id > ARMCLK) {
+		printf("%s gpll=%lu\n", __func__, priv->gpll_hz);
+		return -ENOENT;
+	}
+
+	debug("%s %ld %ld\n", __func__, clk->id, rate);
+	switch (clk->id) {
+	case PLL_NPLL:
+		ret = px30_clk_set_pll_rate(priv, NPLL, rate);
+		break;
+	case ARMCLK:
+		ret = px30_armclk_set_clk(priv, rate);
+		break;
+	case HCLK_SDMMC:
+	case HCLK_EMMC:
+	case SCLK_SDMMC:
+	case SCLK_EMMC:
+		ret = px30_mmc_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_I2C0:
+	case SCLK_I2C1:
+	case SCLK_I2C2:
+	case SCLK_I2C3:
+		ret = px30_i2c_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_I2S1:
+		ret = px30_i2s_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_NANDC:
+		ret = px30_nandc_set_clk(priv, rate);
+		break;
+	case SCLK_PWM0:
+	case SCLK_PWM1:
+		ret = px30_pwm_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_SARADC:
+		ret = px30_saradc_set_clk(priv, rate);
+		break;
+	case SCLK_TSADC:
+		ret = px30_tsadc_set_clk(priv, rate);
+		break;
+	case SCLK_SPI0:
+	case SCLK_SPI1:
+		ret = px30_spi_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_VOPB:
+	case ACLK_VOPL:
+	case DCLK_VOPB:
+	case DCLK_VOPL:
+		ret = px30_vop_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_BUS_PRE:
+	case HCLK_BUS_PRE:
+	case PCLK_BUS_PRE:
+		ret = px30_bus_set_clk(priv, clk->id, rate);
+		break;
+	case ACLK_PERI_PRE:
+	case HCLK_PERI_PRE:
+		ret = px30_peri_set_clk(priv, clk->id, rate);
+		break;
+#ifndef CONFIG_SPL_BUILD
+	case SCLK_CRYPTO:
+	case SCLK_CRYPTO_APK:
+		ret = px30_crypto_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_I2S1_OUT:
+		ret = px30_i2s1_mclk_set_clk(priv, clk->id, rate);
+		break;
+	case SCLK_GMAC:
+	case SCLK_GMAC_SRC:
+		ret = px30_mac_set_clk(priv, rate);
+		break;
+	case SCLK_GMAC_RMII:
+		ret = px30_mac_set_speed_clk(priv, rate);
+		break;
+#endif
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int px30_gmac_set_parent(struct clk *clk, struct clk *parent)
+{
+	struct px30_clk_priv *priv = dev_get_priv(clk->dev);
+	struct px30_cru *cru = priv->cru;
+
+	if (parent->id == SCLK_GMAC_SRC) {
+		debug("%s: switching GAMC to SCLK_GMAC_SRC\n", __func__);
+		rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
+			     RMII_EXTCLK_SEL_INT << RMII_EXTCLK_SEL_SHIFT);
+	} else {
+		debug("%s: switching GMAC to external clock\n", __func__);
+		rk_clrsetreg(&cru->clksel_con[23], RMII_EXTCLK_SEL_MASK,
+			     RMII_EXTCLK_SEL_EXT << RMII_EXTCLK_SEL_SHIFT);
+	}
+	return 0;
+}
+
+static int px30_clk_set_parent(struct clk *clk, struct clk *parent)
+{
+	switch (clk->id) {
+	case SCLK_GMAC:
+		return px30_gmac_set_parent(clk, parent);
+	default:
+		return -ENOENT;
+	}
+}
+#endif
+
+static int px30_clk_enable(struct clk *clk)
+{
+	switch (clk->id) {
+	case HCLK_HOST:
+	case SCLK_GMAC:
+	case SCLK_GMAC_RX_TX:
+	case SCLK_MAC_REF:
+	case SCLK_MAC_REFOUT:
+	case ACLK_GMAC:
+	case PCLK_GMAC:
+	case SCLK_GMAC_RMII:
+		/* Required to successfully probe the Designware GMAC driver */
+		return 0;
+	}
+
+	debug("%s: unsupported clk %ld\n", __func__, clk->id);
+	return -ENOENT;
+}
+
+static struct clk_ops px30_clk_ops = {
+	.get_rate = px30_clk_get_rate,
+	.set_rate = px30_clk_set_rate,
+#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
+	.set_parent = px30_clk_set_parent,
+#endif
+	.enable = px30_clk_enable,
+};
+
+static void px30_clk_init(struct px30_clk_priv *priv)
+{
+	ulong npll_hz;
+	int ret;
+
+	npll_hz = px30_clk_get_pll_rate(priv, NPLL);
+	if (npll_hz != NPLL_HZ) {
+		ret = px30_clk_set_pll_rate(priv, NPLL, NPLL_HZ);
+		if (ret < 0)
+			printf("%s failed to set npll rate\n", __func__);
+	}
+
+	px30_bus_set_clk(priv, ACLK_BUS_PRE, ACLK_BUS_HZ);
+	px30_bus_set_clk(priv, HCLK_BUS_PRE, HCLK_BUS_HZ);
+	px30_bus_set_clk(priv, PCLK_BUS_PRE, PCLK_BUS_HZ);
+	px30_peri_set_clk(priv, ACLK_PERI_PRE, ACLK_PERI_HZ);
+	px30_peri_set_clk(priv, HCLK_PERI_PRE, HCLK_PERI_HZ);
+}
+
+static int px30_clk_probe(struct udevice *dev)
+{
+	struct px30_clk_priv *priv = dev_get_priv(dev);
+	struct clk clk_gpll;
+	int ret;
+
+	if (px30_clk_get_pll_rate(priv, APLL) != APLL_HZ)
+		px30_armclk_set_clk(priv, APLL_HZ);
+
+	/* get the GPLL rate from the pmucru */
+	ret = clk_get_by_name(dev, "gpll", &clk_gpll);
+	if (ret) {
+		printf("%s: failed to get gpll clk from pmucru\n", __func__);
+		return ret;
+	}
+
+	priv->gpll_hz = clk_get_rate(&clk_gpll);
+
+	px30_clk_init(priv);
+
+	return 0;
+}
+
+static int px30_clk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct px30_clk_priv *priv = dev_get_priv(dev);
+
+	priv->cru = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static int px30_clk_bind(struct udevice *dev)
+{
+	int ret;
+	struct udevice *sys_child;
+	struct sysreset_reg *priv;
+
+	/* The reset driver does not have a device node, so bind it here */
+	ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset",
+				 &sys_child);
+	if (ret) {
+		debug("Warning: No sysreset driver: ret=%d\n", ret);
+	} else {
+		priv = malloc(sizeof(struct sysreset_reg));
+		priv->glb_srst_fst_value = offsetof(struct px30_cru,
+						    glb_srst_fst);
+		priv->glb_srst_snd_value = offsetof(struct px30_cru,
+						    glb_srst_snd);
+		sys_child->priv = priv;
+	}
+
+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)
+	ret = offsetof(struct px30_cru, softrst_con[0]);
+	ret = rockchip_reset_bind(dev, ret, 12);
+	if (ret)
+		debug("Warning: software reset driver bind faile\n");
+#endif
+
+	return 0;
+}
+
+static const struct udevice_id px30_clk_ids[] = {
+	{ .compatible = "rockchip,px30-cru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_px30_cru) = {
+	.name		= "rockchip_px30_cru",
+	.id		= UCLASS_CLK,
+	.of_match	= px30_clk_ids,
+	.priv_auto_alloc_size = sizeof(struct px30_clk_priv),
+	.ofdata_to_platdata = px30_clk_ofdata_to_platdata,
+	.ops		= &px30_clk_ops,
+	.bind		= px30_clk_bind,
+	.probe		= px30_clk_probe,
+};
+
+static ulong px30_pclk_pmu_get_pmuclk(struct px30_pmuclk_priv *priv)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+	u32 div, con;
+
+	con = readl(&pmucru->pmu_clksel_con[0]);
+	div = (con & CLK_PMU_PCLK_DIV_MASK) >> CLK_PMU_PCLK_DIV_SHIFT;
+
+	return DIV_TO_RATE(priv->gpll_hz, div);
+}
+
+static ulong px30_pclk_pmu_set_pmuclk(struct px30_pmuclk_priv *priv, ulong hz)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+	int src_clk_div;
+
+	src_clk_div = DIV_ROUND_UP(priv->gpll_hz, hz);
+	assert(src_clk_div - 1 <= 31);
+
+	rk_clrsetreg(&pmucru->pmu_clksel_con[0],
+		     CLK_PMU_PCLK_DIV_MASK,
+		     (src_clk_div - 1) << CLK_PMU_PCLK_DIV_SHIFT);
+
+	return px30_pclk_pmu_get_pmuclk(priv);
+}
+
+static ulong px30_pmuclk_get_gpll_rate(struct px30_pmuclk_priv *priv)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+
+	return rkclk_pll_get_rate(&pmucru->pll, &pmucru->pmu_mode, GPLL);
+}
+
+static ulong px30_pmuclk_set_gpll_rate(struct px30_pmuclk_priv *priv, ulong hz)
+{
+	struct px30_pmucru *pmucru = priv->pmucru;
+	ulong pclk_pmu_rate;
+	u32 div;
+
+	if (priv->gpll_hz == hz)
+		return priv->gpll_hz;
+
+	div = DIV_ROUND_UP(hz, priv->gpll_hz);
+
+	/* save clock rate */
+	pclk_pmu_rate = px30_pclk_pmu_get_pmuclk(priv);
+
+	/* avoid rate too large, reduce rate first */
+	px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate / div);
+
+	/* change gpll rate */
+	rkclk_set_pll(&pmucru->pll, &pmucru->pmu_mode, GPLL, hz);
+	priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv);
+
+	/* restore clock rate */
+	px30_pclk_pmu_set_pmuclk(priv, pclk_pmu_rate);
+
+	return priv->gpll_hz;
+}
+
+static ulong px30_pmuclk_get_rate(struct clk *clk)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
+	ulong rate = 0;
+
+	debug("%s %ld\n", __func__, clk->id);
+	switch (clk->id) {
+	case PLL_GPLL:
+		rate = px30_pmuclk_get_gpll_rate(priv);
+		break;
+	case PCLK_PMU_PRE:
+		rate = px30_pclk_pmu_get_pmuclk(priv);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return rate;
+}
+
+static ulong px30_pmuclk_set_rate(struct clk *clk, ulong rate)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(clk->dev);
+	ulong ret = 0;
+
+	debug("%s %ld %ld\n", __func__, clk->id, rate);
+	switch (clk->id) {
+	case PLL_GPLL:
+		ret = px30_pmuclk_set_gpll_rate(priv, rate);
+		break;
+	case PCLK_PMU_PRE:
+		ret = px30_pclk_pmu_set_pmuclk(priv, rate);
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	return ret;
+}
+
+static struct clk_ops px30_pmuclk_ops = {
+	.get_rate = px30_pmuclk_get_rate,
+	.set_rate = px30_pmuclk_set_rate,
+};
+
+static void px30_pmuclk_init(struct px30_pmuclk_priv *priv)
+{
+	priv->gpll_hz = px30_pmuclk_get_gpll_rate(priv);
+	px30_pmuclk_set_gpll_rate(priv, GPLL_HZ);
+
+	px30_pclk_pmu_set_pmuclk(priv, PCLK_PMU_HZ);
+}
+
+static int px30_pmuclk_probe(struct udevice *dev)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(dev);
+
+	px30_pmuclk_init(priv);
+
+	return 0;
+}
+
+static int px30_pmuclk_ofdata_to_platdata(struct udevice *dev)
+{
+	struct px30_pmuclk_priv *priv = dev_get_priv(dev);
+
+	priv->pmucru = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static const struct udevice_id px30_pmuclk_ids[] = {
+	{ .compatible = "rockchip,px30-pmucru" },
+	{ }
+};
+
+U_BOOT_DRIVER(rockchip_px30_pmucru) = {
+	.name		= "rockchip_px30_pmucru",
+	.id		= UCLASS_CLK,
+	.of_match	= px30_pmuclk_ids,
+	.priv_auto_alloc_size = sizeof(struct px30_pmuclk_priv),
+	.ofdata_to_platdata = px30_pmuclk_ofdata_to_platdata,
+	.ops		= &px30_pmuclk_ops,
+	.probe		= px30_pmuclk_probe,
+};
diff --git a/include/dt-bindings/clock/px30-cru.h b/include/dt-bindings/clock/px30-cru.h
new file mode 100644
index 0000000000..e5e59690b5
--- /dev/null
+++ b/include/dt-bindings/clock/px30-cru.h
@@ -0,0 +1,389 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co. Ltd.
+ * Author: Elaine <zhangqing@rock-chips.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_PX30_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_PX30_H
+
+/* core clocks */
+#define PLL_APLL		1
+#define PLL_DPLL		2
+#define PLL_CPLL		3
+#define PLL_NPLL		4
+#define APLL_BOOST_H		5
+#define APLL_BOOST_L		6
+#define ARMCLK			7
+
+/* sclk gates (special clocks) */
+#define USB480M			14
+#define SCLK_PDM		15
+#define SCLK_I2S0_TX		16
+#define SCLK_I2S0_TX_OUT	17
+#define SCLK_I2S0_RX		18
+#define SCLK_I2S0_RX_OUT	19
+#define SCLK_I2S1		20
+#define SCLK_I2S1_OUT		21
+#define SCLK_I2S2		22
+#define SCLK_I2S2_OUT		23
+#define SCLK_UART1		24
+#define SCLK_UART2		25
+#define SCLK_UART3		26
+#define SCLK_UART4		27
+#define SCLK_UART5		28
+#define SCLK_I2C0		29
+#define SCLK_I2C1		30
+#define SCLK_I2C2		31
+#define SCLK_I2C3		32
+#define SCLK_I2C4		33
+#define SCLK_PWM0		34
+#define SCLK_PWM1		35
+#define SCLK_SPI0		36
+#define SCLK_SPI1		37
+#define SCLK_TIMER0		38
+#define SCLK_TIMER1		39
+#define SCLK_TIMER2		40
+#define SCLK_TIMER3		41
+#define SCLK_TIMER4		42
+#define SCLK_TIMER5		43
+#define SCLK_TSADC		44
+#define SCLK_SARADC		45
+#define SCLK_OTP		46
+#define SCLK_OTP_USR		47
+#define SCLK_CRYPTO		48
+#define SCLK_CRYPTO_APK		49
+#define SCLK_DDRC		50
+#define SCLK_ISP		51
+#define SCLK_CIF_OUT		52
+#define SCLK_RGA_CORE		53
+#define SCLK_VOPB_PWM		54
+#define SCLK_NANDC		55
+#define SCLK_SDIO		56
+#define SCLK_EMMC		57
+#define SCLK_SFC		58
+#define SCLK_SDMMC		59
+#define SCLK_OTG_ADP		60
+#define SCLK_GMAC_SRC		61
+#define SCLK_GMAC		62
+#define SCLK_GMAC_RX_TX		63
+#define SCLK_MAC_REF		64
+#define SCLK_MAC_REFOUT		65
+#define SCLK_MAC_OUT		66
+#define SCLK_SDMMC_DRV		67
+#define SCLK_SDMMC_SAMPLE	68
+#define SCLK_SDIO_DRV		69
+#define SCLK_SDIO_SAMPLE	70
+#define SCLK_EMMC_DRV		71
+#define SCLK_EMMC_SAMPLE	72
+#define SCLK_GPU		73
+#define SCLK_PVTM		74
+#define SCLK_CORE_VPU		75
+#define SCLK_GMAC_RMII		76
+#define SCLK_UART2_SRC		77
+#define SCLK_NANDC_DIV		78
+#define SCLK_NANDC_DIV50	79
+#define SCLK_SDIO_DIV		80
+#define SCLK_SDIO_DIV50		81
+#define SCLK_EMMC_DIV		82
+#define SCLK_EMMC_DIV50		83
+
+/* dclk gates */
+#define DCLK_VOPB		150
+#define DCLK_VOPL		151
+
+/* aclk gates */
+#define ACLK_GPU		170
+#define ACLK_BUS_PRE		171
+#define ACLK_CRYPTO		172
+#define ACLK_VI_PRE		173
+#define ACLK_VO_PRE		174
+#define ACLK_VPU		175
+#define ACLK_PERI_PRE		176
+#define ACLK_GMAC		178
+#define ACLK_CIF		179
+#define ACLK_ISP		180
+#define ACLK_VOPB		181
+#define ACLK_VOPL		182
+#define ACLK_RGA		183
+#define ACLK_GIC		184
+#define ACLK_DCF		186
+#define ACLK_DMAC		187
+
+/* hclk gates */
+#define HCLK_BUS_PRE		240
+#define HCLK_CRYPTO		241
+#define HCLK_VI_PRE		242
+#define HCLK_VO_PRE		243
+#define HCLK_VPU		244
+#define HCLK_PERI_PRE		245
+#define HCLK_MMC_NAND		246
+#define HCLK_SDMMC		247
+#define HCLK_USB		248
+#define HCLK_CIF		249
+#define HCLK_ISP		250
+#define HCLK_VOPB		251
+#define HCLK_VOPL		252
+#define HCLK_RGA		253
+#define HCLK_NANDC		254
+#define HCLK_SDIO		255
+#define HCLK_EMMC		256
+#define HCLK_SFC		257
+#define HCLK_OTG		258
+#define HCLK_HOST		259
+#define HCLK_HOST_ARB		260
+#define HCLK_PDM		261
+#define HCLK_I2S0		262
+#define HCLK_I2S1		263
+#define HCLK_I2S2		264
+
+/* pclk gates */
+#define PCLK_BUS_PRE		320
+#define PCLK_DDR		321
+#define PCLK_VO_PRE		322
+#define PCLK_GMAC		323
+#define PCLK_MIPI_DSI		324
+#define PCLK_MIPIDSIPHY		325
+#define PCLK_MIPICSIPHY		326
+#define PCLK_USB_GRF		327
+#define PCLK_DCF		328
+#define PCLK_UART1		329
+#define PCLK_UART2		330
+#define PCLK_UART3		331
+#define PCLK_UART4		332
+#define PCLK_UART5		333
+#define PCLK_I2C0		334
+#define PCLK_I2C1		335
+#define PCLK_I2C2		336
+#define PCLK_I2C3		337
+#define PCLK_I2C4		338
+#define PCLK_PWM0		339
+#define PCLK_PWM1		340
+#define PCLK_SPI0		341
+#define PCLK_SPI1		342
+#define PCLK_SARADC		343
+#define PCLK_TSADC		344
+#define PCLK_TIMER		345
+#define PCLK_OTP_NS		346
+#define PCLK_WDT_NS		347
+#define PCLK_GPIO1		348
+#define PCLK_GPIO2		349
+#define PCLK_GPIO3		350
+#define PCLK_ISP		351
+#define PCLK_CIF		352
+#define PCLK_OTP_PHY		353
+
+#define CLK_NR_CLKS		(PCLK_OTP_PHY + 1)
+
+/* pmu-clocks indices */
+
+#define PLL_GPLL		1
+
+#define SCLK_RTC32K_PMU		4
+#define SCLK_WIFI_PMU		5
+#define SCLK_UART0_PMU		6
+#define SCLK_PVTM_PMU		7
+#define PCLK_PMU_PRE		8
+#define SCLK_REF24M_PMU		9
+#define SCLK_USBPHY_REF		10
+#define SCLK_MIPIDSIPHY_REF	11
+
+#define XIN24M_DIV		12
+
+#define PCLK_GPIO0_PMU		20
+#define PCLK_UART0_PMU		21
+
+#define CLKPMU_NR_CLKS		(PCLK_UART0_PMU + 1)
+
+/* soft-reset indices */
+#define SRST_CORE0_PO		0
+#define SRST_CORE1_PO		1
+#define SRST_CORE2_PO		2
+#define SRST_CORE3_PO		3
+#define SRST_CORE0		4
+#define SRST_CORE1		5
+#define SRST_CORE2		6
+#define SRST_CORE3		7
+#define SRST_CORE0_DBG		8
+#define SRST_CORE1_DBG		9
+#define SRST_CORE2_DBG		10
+#define SRST_CORE3_DBG		11
+#define SRST_TOPDBG		12
+#define SRST_CORE_NOC		13
+#define SRST_STRC_A		14
+#define SRST_L2C		15
+
+#define SRST_DAP		16
+#define SRST_CORE_PVTM		17
+#define SRST_GPU		18
+#define SRST_GPU_NIU		19
+#define SRST_UPCTL2		20
+#define SRST_UPCTL2_A		21
+#define SRST_UPCTL2_P		22
+#define SRST_MSCH		23
+#define SRST_MSCH_P		24
+#define SRST_DDRMON_P		25
+#define SRST_DDRSTDBY_P		26
+#define SRST_DDRSTDBY		27
+#define SRST_DDRGRF_p		28
+#define SRST_AXI_SPLIT_A	29
+#define SRST_AXI_CMD_A		30
+#define SRST_AXI_CMD_P		31
+
+#define SRST_DDRPHY		32
+#define SRST_DDRPHYDIV		33
+#define SRST_DDRPHY_P		34
+#define SRST_VPU_A		36
+#define SRST_VPU_NIU_A		37
+#define SRST_VPU_H		38
+#define SRST_VPU_NIU_H		39
+#define SRST_VI_NIU_A		40
+#define SRST_VI_NIU_H		41
+#define SRST_ISP_H		42
+#define SRST_ISP		43
+#define SRST_CIF_A		44
+#define SRST_CIF_H		45
+#define SRST_CIF_PCLKIN		46
+#define SRST_MIPICSIPHY_P	47
+
+#define SRST_VO_NIU_A		48
+#define SRST_VO_NIU_H		49
+#define SRST_VO_NIU_P		50
+#define SRST_VOPB_A		51
+#define SRST_VOPB_H		52
+#define SRST_VOPB		53
+#define SRST_PWM_VOPB		54
+#define SRST_VOPL_A		55
+#define SRST_VOPL_H		56
+#define SRST_VOPL		57
+#define SRST_RGA_A		58
+#define SRST_RGA_H		59
+#define SRST_RGA		60
+#define SRST_MIPIDSI_HOST_P	61
+#define SRST_MIPIDSIPHY_P	62
+#define SRST_VPU_CORE		63
+
+#define SRST_PERI_NIU_A		64
+#define SRST_USB_NIU_H		65
+#define SRST_USB2OTG_H		66
+#define SRST_USB2OTG		67
+#define SRST_USB2OTG_ADP	68
+#define SRST_USB2HOST_H		69
+#define SRST_USB2HOST_ARB_H	70
+#define SRST_USB2HOST_AUX_H	71
+#define SRST_USB2HOST_EHCI	72
+#define SRST_USB2HOST		73
+#define SRST_USBPHYPOR		74
+#define SRST_USBPHY_OTG_PORT	75
+#define SRST_USBPHY_HOST_PORT	76
+#define SRST_USBPHY_GRF		77
+#define SRST_CPU_BOOST_P	78
+#define SRST_CPU_BOOST		79
+
+#define SRST_MMC_NAND_NIU_H	80
+#define SRST_SDIO_H		81
+#define SRST_EMMC_H		82
+#define SRST_SFC_H		83
+#define SRST_SFC		84
+#define SRST_SDCARD_NIU_H	85
+#define SRST_SDMMC_H		86
+#define SRST_NANDC_H		89
+#define SRST_NANDC		90
+#define SRST_GMAC_NIU_A		92
+#define SRST_GMAC_NIU_P		93
+#define SRST_GMAC_A		94
+
+#define SRST_PMU_NIU_P		96
+#define SRST_PMU_SGRF_P		97
+#define SRST_PMU_GRF_P		98
+#define SRST_PMU		99
+#define SRST_PMU_MEM_P		100
+#define SRST_PMU_GPIO0_P	101
+#define SRST_PMU_UART0_P	102
+#define SRST_PMU_CRU_P		103
+#define SRST_PMU_PVTM		104
+#define SRST_PMU_UART		105
+#define SRST_PMU_NIU_H		106
+#define SRST_PMU_DDR_FAIL_SAVE	107
+#define SRST_PMU_CORE_PERF_A	108
+#define SRST_PMU_CORE_GRF_P	109
+#define SRST_PMU_GPU_PERF_A	110
+#define SRST_PMU_GPU_GRF_P	111
+
+#define SRST_CRYPTO_NIU_A	112
+#define SRST_CRYPTO_NIU_H	113
+#define SRST_CRYPTO_A		114
+#define SRST_CRYPTO_H		115
+#define SRST_CRYPTO		116
+#define SRST_CRYPTO_APK		117
+#define SRST_BUS_NIU_H		120
+#define SRST_USB_NIU_P		121
+#define SRST_BUS_TOP_NIU_P	122
+#define SRST_INTMEM_A		123
+#define SRST_GIC_A		124
+#define SRST_ROM_H		126
+#define SRST_DCF_A		127
+
+#define SRST_DCF_P		128
+#define SRST_PDM_H		129
+#define SRST_PDM		130
+#define SRST_I2S0_H		131
+#define SRST_I2S0_TX		132
+#define SRST_I2S1_H		133
+#define SRST_I2S1		134
+#define SRST_I2S2_H		135
+#define SRST_I2S2		136
+#define SRST_UART1_P		137
+#define SRST_UART1		138
+#define SRST_UART2_P		139
+#define SRST_UART2		140
+#define SRST_UART3_P		141
+#define SRST_UART3		142
+#define SRST_UART4_P		143
+
+#define SRST_UART4		144
+#define SRST_UART5_P		145
+#define SRST_UART5		146
+#define SRST_I2C0_P		147
+#define SRST_I2C0		148
+#define SRST_I2C1_P		149
+#define SRST_I2C1		150
+#define SRST_I2C2_P		151
+#define SRST_I2C2		152
+#define SRST_I2C3_P		153
+#define SRST_I2C3		154
+#define SRST_PWM0_P		157
+#define SRST_PWM0		158
+#define SRST_PWM1_P		159
+
+#define SRST_PWM1		160
+#define SRST_SPI0_P		161
+#define SRST_SPI0		162
+#define SRST_SPI1_P		163
+#define SRST_SPI1		164
+#define SRST_SARADC_P		165
+#define SRST_SARADC		166
+#define SRST_TSADC_P		167
+#define SRST_TSADC		168
+#define SRST_TIMER_P		169
+#define SRST_TIMER0		170
+#define SRST_TIMER1		171
+#define SRST_TIMER2		172
+#define SRST_TIMER3		173
+#define SRST_TIMER4		174
+#define SRST_TIMER5		175
+
+#define SRST_OTP_NS_P		176
+#define SRST_OTP_NS_SBPI	177
+#define SRST_OTP_NS_USR		178
+#define SRST_OTP_PHY_P		179
+#define SRST_OTP_PHY		180
+#define SRST_WDT_NS_P		181
+#define SRST_GPIO1_P		182
+#define SRST_GPIO2_P		183
+#define SRST_GPIO3_P		184
+#define SRST_SGRF_P		185
+#define SRST_GRF_P		186
+#define SRST_I2S0_RX		191
+
+#endif
-- 
2.23.0

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

* [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (3 preceding siblings ...)
  2019-10-24 23:27 ` [U-Boot] [PATCH 04/12] rockchip: clk: add px30 clock driver Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  2:09   ` Kever Yang
  2019-10-24 23:27 ` [U-Boot] [PATCH 06/12] rockchip: mkimage: " Heiko Stuebner
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

Add the glue code to allow the px30 variant of the Rockchip gmac
to provide network functionality.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 drivers/net/gmac_rockchip.c | 69 +++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
index 26a6121175..3f3e38a2c6 100644
--- a/drivers/net/gmac_rockchip.c
+++ b/drivers/net/gmac_rockchip.c
@@ -14,6 +14,7 @@
 #include <asm/arch-rockchip/periph.h>
 #include <asm/arch-rockchip/clock.h>
 #include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_px30.h>
 #include <asm/arch-rockchip/grf_rk322x.h>
 #include <asm/arch-rockchip/grf_rk3288.h>
 #include <asm/arch-rockchip/grf_rk3328.h>
@@ -72,6 +73,47 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
 	return designware_eth_ofdata_to_platdata(dev);
 }
 
+static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
+{
+	struct px30_grf *grf;
+	struct clk clk_speed;
+	int speed, ret;
+	enum {
+		PX30_GMAC_SPEED_SHIFT = 0x2,
+		PX30_GMAC_SPEED_MASK  = BIT(2),
+		PX30_GMAC_SPEED_10M   = 0,
+		PX30_GMAC_SPEED_100M  = BIT(2),
+	};
+
+	ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
+			      &clk_speed);
+	if (ret)
+		return ret;
+
+	switch (priv->phydev->speed) {
+	case 10:
+		speed = PX30_GMAC_SPEED_10M;
+		ret = clk_set_rate(&clk_speed, 2500000);
+		if (ret)
+			return ret;
+		break;
+	case 100:
+		speed = PX30_GMAC_SPEED_100M;
+		ret = clk_set_rate(&clk_speed, 25000000);
+		if (ret)
+			return ret;
+		break;
+	default:
+		debug("Unknown phy speed: %d\n", priv->phydev->speed);
+		return -EINVAL;
+	}
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+	rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
+
+	return 0;
+}
+
 static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
 {
 	struct rk322x_grf *grf;
@@ -257,6 +299,22 @@ static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
 	return 0;
 }
 
+static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
+{
+	struct px30_grf *grf;
+	enum {
+		PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
+		PX30_GMAC_PHY_INTF_SEL_MASK  = GENMASK(4, 6),
+		PX30_GMAC_PHY_INTF_SEL_RMII  = BIT(6),
+	};
+
+	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+
+	rk_clrsetreg(&grf->mac_con1,
+		     PX30_GMAC_PHY_INTF_SEL_MASK,
+		     PX30_GMAC_PHY_INTF_SEL_RMII);
+}
+
 static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
 {
 	struct rk322x_grf *grf;
@@ -445,6 +503,10 @@ static int gmac_rockchip_probe(struct udevice *dev)
 	ulong rate;
 	int ret;
 
+	ret = clk_set_defaults(dev);
+	if (ret)
+		debug("%s clk_set_defaults failed %d\n", __func__, ret);
+
 	ret = clk_get_by_index(dev, 0, &clk);
 	if (ret)
 		return ret;
@@ -569,6 +631,11 @@ const struct eth_ops gmac_rockchip_eth_ops = {
 	.write_hwaddr		= designware_eth_write_hwaddr,
 };
 
+const struct rk_gmac_ops px30_gmac_ops = {
+	.fix_mac_speed = px30_gmac_fix_mac_speed,
+	.set_to_rmii = px30_gmac_set_to_rmii,
+};
+
 const struct rk_gmac_ops rk3228_gmac_ops = {
 	.fix_mac_speed = rk3228_gmac_fix_mac_speed,
 	.set_to_rgmii = rk3228_gmac_set_to_rgmii,
@@ -600,6 +667,8 @@ const struct rk_gmac_ops rv1108_gmac_ops = {
 };
 
 static const struct udevice_id rockchip_gmac_ids[] = {
+	{ .compatible = "rockchip,px30-gmac",
+	  .data = (ulong)&px30_gmac_ops },
 	{ .compatible = "rockchip,rk3228-gmac",
 	  .data = (ulong)&rk3228_gmac_ops },
 	{ .compatible = "rockchip,rk3288-gmac",
-- 
2.23.0

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

* [U-Boot] [PATCH 06/12] rockchip: mkimage: add support for px30
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (4 preceding siblings ...)
  2019-10-24 23:27 ` [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30 Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  2:09   ` Kever Yang
  2019-10-24 23:27 ` [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller Heiko Stuebner
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: Kever Yang <kever.yang@rock-chips.com>

Add the table entry for px30 socs.
The px30 has 10K of sram available.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 tools/rkcommon.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 831c2ad820..83df82e4b0 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -67,6 +67,7 @@ struct spl_info {
 };
 
 static struct spl_info spl_infos[] = {
+	{ "px30", "RK33", 0x2800, false },
 	{ "rk3036", "RK30", 0x1000, false },
 	{ "rk3128", "RK31", 0x1800, false },
 	{ "rk3188", "RK31", 0x8000 - 0x800, true },
-- 
2.23.0

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

* [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (5 preceding siblings ...)
  2019-10-24 23:27 ` [U-Boot] [PATCH 06/12] rockchip: mkimage: " Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  2:10   ` Kever Yang
  2019-10-24 23:27 ` [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp Heiko Stuebner
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: Finley Xiao <finley.xiao@rock-chips.com>

Newer Rockchip socs like the px30 use a different ip block to handle
one-time-programmable memory, so add a misc driver for it as well.

Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 drivers/misc/Kconfig        |   9 ++
 drivers/misc/Makefile       |   1 +
 drivers/misc/rockchip-otp.c | 176 ++++++++++++++++++++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 drivers/misc/rockchip-otp.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 8037b6ee2d..d68b24e6ec 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -59,6 +59,15 @@ config ROCKCHIP_EFUSE
 	  extended (by porting the read function from the Linux kernel sources)
 	  to support other recent Rockchip devices.
 
+config ROCKCHIP_OTP
+	bool "Rockchip OTP Support"
+	depends on MISC
+	help
+	  Enable (read-only) access for the one-time-programmable memory block
+	  found in Rockchip SoCs: accesses can either be made using byte
+	  addressing and a length or through child-nodes that are generated
+	  based on the e-fuse map retrieved from the DTS.
+
 config VEXPRESS_CONFIG
 	bool "Enable support for Arm Versatile Express config bus"
 	depends on MISC
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 509c588582..b172567297 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
 obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
 obj-$(CONFIG_QFW) += qfw.o
 obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
+obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
 obj-$(CONFIG_SANDBOX) += swap_case.o
 obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
 obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c
new file mode 100644
index 0000000000..bdd443b3db
--- /dev/null
+++ b/drivers/misc/rockchip-otp.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <command.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <misc.h>
+
+/* OTP Register Offsets */
+#define OTPC_SBPI_CTRL			0x0020
+#define OTPC_SBPI_CMD_VALID_PRE		0x0024
+#define OTPC_SBPI_CS_VALID_PRE		0x0028
+#define OTPC_SBPI_STATUS		0x002C
+#define OTPC_USER_CTRL			0x0100
+#define OTPC_USER_ADDR			0x0104
+#define OTPC_USER_ENABLE		0x0108
+#define OTPC_USER_QP			0x0120
+#define OTPC_USER_Q			0x0124
+#define OTPC_INT_STATUS			0x0304
+#define OTPC_SBPI_CMD0_OFFSET		0x1000
+#define OTPC_SBPI_CMD1_OFFSET		0x1004
+
+/* OTP Register bits and masks */
+#define OTPC_USER_ADDR_MASK		GENMASK(31, 16)
+#define OTPC_USE_USER			BIT(0)
+#define OTPC_USE_USER_MASK		GENMASK(16, 16)
+#define OTPC_USER_FSM_ENABLE		BIT(0)
+#define OTPC_USER_FSM_ENABLE_MASK	GENMASK(16, 16)
+#define OTPC_SBPI_DONE			BIT(1)
+#define OTPC_USER_DONE			BIT(2)
+
+#define SBPI_DAP_ADDR			0x02
+#define SBPI_DAP_ADDR_SHIFT		8
+#define SBPI_DAP_ADDR_MASK		GENMASK(31, 24)
+#define SBPI_CMD_VALID_MASK		GENMASK(31, 16)
+#define SBPI_DAP_CMD_WRF		0xC0
+#define SBPI_DAP_REG_ECC		0x3A
+#define SBPI_ECC_ENABLE			0x00
+#define SBPI_ECC_DISABLE		0x09
+#define SBPI_ENABLE			BIT(0)
+#define SBPI_ENABLE_MASK		GENMASK(16, 16)
+
+#define OTPC_TIMEOUT			10000
+
+struct rockchip_otp_platdata {
+	void __iomem *base;
+	unsigned long secure_conf_base;
+	unsigned long otp_mask_base;
+};
+
+static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp,
+				    u32 flag)
+{
+	int delay = OTPC_TIMEOUT;
+
+	while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) {
+		udelay(1);
+		delay--;
+		if (delay <= 0) {
+			printf("%s: wait init status timeout\n", __func__);
+			return -ETIMEDOUT;
+		}
+	}
+
+	/* clean int status */
+	writel(flag, otp->base + OTPC_INT_STATUS);
+
+	return 0;
+}
+
+static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp,
+				   bool enable)
+{
+	int ret = 0;
+
+	writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
+	       otp->base + OTPC_SBPI_CTRL);
+
+	writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
+	writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
+	       otp->base + OTPC_SBPI_CMD0_OFFSET);
+
+	if (enable)
+		writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
+	else
+		writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
+
+	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
+
+	ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
+	if (ret < 0)
+		printf("%s timeout during ecc_enable\n", __func__);
+
+	return ret;
+}
+
+static int rockchip_px30_otp_read(struct udevice *dev, int offset,
+				  void *buf, int size)
+{
+	struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
+	u8 *buffer = buf;
+	int ret = 0;
+
+	ret = rockchip_otp_ecc_enable(otp, false);
+	if (ret < 0) {
+		printf("%s rockchip_otp_ecc_enable err\n", __func__);
+		return ret;
+	}
+
+	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+	udelay(5);
+	while (size--) {
+		writel(offset++ | OTPC_USER_ADDR_MASK,
+		       otp->base + OTPC_USER_ADDR);
+		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
+		       otp->base + OTPC_USER_ENABLE);
+
+		ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
+		if (ret < 0) {
+			printf("%s timeout during read setup\n", __func__);
+			goto read_end;
+		}
+
+		*buffer++ = readb(otp->base + OTPC_USER_Q);
+	}
+
+read_end:
+	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
+
+	return ret;
+}
+
+static int rockchip_otp_read(struct udevice *dev, int offset,
+			     void *buf, int size)
+{
+	return rockchip_px30_otp_read(dev, offset, buf, size);
+}
+
+static const struct misc_ops rockchip_otp_ops = {
+	.read = rockchip_otp_read,
+};
+
+static int rockchip_otp_ofdata_to_platdata(struct udevice *dev)
+{
+	struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
+
+	otp->base = dev_read_addr_ptr(dev);
+
+	return 0;
+}
+
+static const struct udevice_id rockchip_otp_ids[] = {
+	{
+		.compatible = "rockchip,px30-otp",
+		.data = (ulong)&rockchip_px30_otp_read,
+	},
+	{
+		.compatible = "rockchip,rk3308-otp",
+		.data = (ulong)&rockchip_px30_otp_read,
+	},
+	{}
+};
+
+U_BOOT_DRIVER(rockchip_otp) = {
+	.name = "rockchip_otp",
+	.id = UCLASS_MISC,
+	.of_match = rockchip_otp_ids,
+	.ops = &rockchip_otp_ops,
+	.ofdata_to_platdata = rockchip_otp_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata),
+};
-- 
2.23.0

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

* [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (6 preceding siblings ...)
  2019-10-24 23:27 ` [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller Heiko Stuebner
@ 2019-10-24 23:27 ` Heiko Stuebner
  2019-10-25  2:11   ` Kever Yang
  2019-10-24 23:28 ` [U-Boot] [PATCH 09/12] rockchip: ram: add dm-based sdram driver Heiko Stuebner
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:27 UTC (permalink / raw)
  To: u-boot

From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

Newer Rockchip socs use a different ip block to handle one-time-
programmable memory, so depending on what got enabled get the cpuid
from either source.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 arch/arm/mach-rockchip/misc.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c
index c0e4fdbc00..bed4317f7e 100644
--- a/arch/arm/mach-rockchip/misc.c
+++ b/arch/arm/mach-rockchip/misc.c
@@ -57,13 +57,18 @@ int rockchip_cpuid_from_efuse(const u32 cpuid_offset,
 			      const u32 cpuid_length,
 			      u8 *cpuid)
 {
-#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
+#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) || CONFIG_IS_ENABLED(ROCKCHIP_OTP)
 	struct udevice *dev;
 	int ret;
 
 	/* retrieve the device */
+#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
 	ret = uclass_get_device_by_driver(UCLASS_MISC,
 					  DM_GET_DRIVER(rockchip_efuse), &dev);
+#elif CONFIG_IS_ENABLED(ROCKCHIP_OTP)
+	ret = uclass_get_device_by_driver(UCLASS_MISC,
+					  DM_GET_DRIVER(rockchip_otp), &dev);
+#endif
 	if (ret) {
 		debug("%s: could not find efuse device\n", __func__);
 		return -1;
-- 
2.23.0

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

* [U-Boot] [PATCH 09/12] rockchip: ram: add dm-based sdram driver
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (7 preceding siblings ...)
  2019-10-24 23:27 ` [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp Heiko Stuebner
@ 2019-10-24 23:28 ` Heiko Stuebner
  2019-10-24 23:28 ` [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees Heiko Stuebner
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:28 UTC (permalink / raw)
  To: u-boot

From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

sdram configuration happens outside of dm-infrastructure in special
tpl-code, so the sdram driver itself has just the function to read
back the sdram configuration and allow main uboot to handle dram sizes.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 drivers/ram/rockchip/Makefile     |  1 +
 drivers/ram/rockchip/sdram_px30.c | 57 +++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+)
 create mode 100644 drivers/ram/rockchip/sdram_px30.c

diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile
index feb1f82d00..a51df57411 100644
--- a/drivers/ram/rockchip/Makefile
+++ b/drivers/ram/rockchip/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_RAM_ROCKCHIP_DEBUG) += sdram_debug.o
 obj-$(CONFIG_ROCKCHIP_RK3368) = dmc-rk3368.o
+obj-$(CONFIG_ROCKCHIP_PX30) = sdram_px30.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_px30.c b/drivers/ram/rockchip/sdram_px30.c
new file mode 100644
index 0000000000..bdb97f2b5c
--- /dev/null
+++ b/drivers/ram/rockchip/sdram_px30.c
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_px30.h>
+#include <asm/arch-rockchip/sdram_common.h>
+
+struct dram_info {
+	struct ram_info info;
+	struct px30_pmugrf *pmugrf;
+};
+
+static int px30_dmc_probe(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	priv->pmugrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+	debug("%s: grf=%p\n", __func__, priv->pmugrf);
+	priv->info.base = CONFIG_SYS_SDRAM_BASE;
+	priv->info.size =
+		rockchip_sdram_size((phys_addr_t)&priv->pmugrf->os_reg[2]);
+
+	return 0;
+}
+
+static int px30_dmc_get_info(struct udevice *dev, struct ram_info *info)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+
+	*info = priv->info;
+
+	return 0;
+}
+
+static struct ram_ops px30_dmc_ops = {
+	.get_info = px30_dmc_get_info,
+};
+
+static const struct udevice_id px30_dmc_ids[] = {
+	{ .compatible = "rockchip,px30-dmc" },
+	{ }
+};
+
+U_BOOT_DRIVER(dmc_px30) = {
+	.name = "rockchip_px30_dmc",
+	.id = UCLASS_RAM,
+	.of_match = px30_dmc_ids,
+	.ops = &px30_dmc_ops,
+	.probe = px30_dmc_probe,
+	.priv_auto_alloc_size = sizeof(struct dram_info),
+};
-- 
2.23.0

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

* [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (8 preceding siblings ...)
  2019-10-24 23:28 ` [U-Boot] [PATCH 09/12] rockchip: ram: add dm-based sdram driver Heiko Stuebner
@ 2019-10-24 23:28 ` Heiko Stuebner
  2019-10-25  2:39   ` Kever Yang
  2019-10-24 23:28 ` [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core Heiko Stuebner
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:28 UTC (permalink / raw)
  To: u-boot

From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

Add px30 related devicetrees synced from the Linux kernel.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 arch/arm/dts/Makefile             |    3 +
 arch/arm/dts/px30-evb-u-boot.dtsi |   81 ++
 arch/arm/dts/px30-evb.dts         |  527 ++++++++
 arch/arm/dts/px30.dtsi            | 2068 +++++++++++++++++++++++++++++
 4 files changed, 2679 insertions(+)
 create mode 100644 arch/arm/dts/px30-evb-u-boot.dtsi
 create mode 100644 arch/arm/dts/px30-evb.dts
 create mode 100644 arch/arm/dts/px30.dtsi

diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index dbb062edda..04ddbfb11f 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -67,6 +67,9 @@ dtb-$(CONFIG_KIRKWOOD) += \
 dtb-$(CONFIG_ARCH_OWL) += \
 	bubblegum_96.dtb
 
+dtb-$(CONFIG_ROCKCHIP_PX30) += \
+	px30-evb.dtb
+
 dtb-$(CONFIG_ROCKCHIP_RK3036) += \
 	rk3036-sdk.dtb
 
diff --git a/arch/arm/dts/px30-evb-u-boot.dtsi b/arch/arm/dts/px30-evb-u-boot.dtsi
new file mode 100644
index 0000000000..3de9c7068e
--- /dev/null
+++ b/arch/arm/dts/px30-evb-u-boot.dtsi
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+/ {
+	aliases {
+		mmc0 = &emmc;
+		mmc1 = &sdmmc;
+	};
+
+	chosen {
+		u-boot,spl-boot-order = &emmc, &sdmmc;
+	};
+};
+
+&dmc {
+	u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&uart5 {
+	clock-frequency = <24000000>;
+	u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+	u-boot,dm-pre-reloc;
+
+	/* temporary till I find out why dma mode doesn't work */
+	fifo-mode;
+};
+
+&emmc {
+	u-boot,dm-pre-reloc;
+};
+
+&grf {
+	u-boot,dm-pre-reloc;
+};
+
+&pmugrf {
+	u-boot,dm-pre-reloc;
+};
+
+&xin24m {
+	u-boot,dm-pre-reloc;
+};
+
+&cru {
+	u-boot,dm-pre-reloc;
+};
+
+&pmucru {
+	u-boot,dm-pre-reloc;
+};
+
+&saradc {
+	u-boot,dm-pre-reloc;
+	status = "okay";
+};
+
+&gpio0 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio1 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio2 {
+	u-boot,dm-pre-reloc;
+};
+
+&gpio3 {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/px30-evb.dts b/arch/arm/dts/px30-evb.dts
new file mode 100644
index 0000000000..089a7ade4e
--- /dev/null
+++ b/arch/arm/dts/px30-evb.dts
@@ -0,0 +1,527 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "px30.dtsi"
+#include "px30-evb-u-boot.dtsi"
+
+/ {
+	model = "Rockchip PX30 EVB";
+	compatible = "rockchip,px30-evb", "rockchip,px30";
+
+	chosen {
+		stdout-path = "serial5:115200n8";
+	};
+
+	adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 2>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1800000>;
+		poll-interval = <100>;
+
+		esc-key {
+			label = "esc";
+			linux,code = <KEY_ESC>;
+			press-threshold-microvolt = <1310000>;
+		};
+
+		home-key {
+			label = "home";
+			linux,code = <KEY_HOME>;
+			press-threshold-microvolt = <624000>;
+		};
+
+		menu-key {
+			label = "menu";
+			linux,code = <KEY_MENU>;
+			press-threshold-microvolt = <987000>;
+		};
+
+		vol-down-key {
+			label = "volume down";
+			linux,code = <KEY_VOLUMEDOWN>;
+			press-threshold-microvolt = <300000>;
+		};
+
+		vol-up-key {
+			label = "volume up";
+			linux,code = <KEY_VOLUMEUP>;
+			press-threshold-microvolt = <17000>;
+		};
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm1 0 25000 0>;
+		power-supply = <&vcc3v3_lcd>;
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		pinctrl-0 = <&emmc_reset>;
+		pinctrl-names = "default";
+		reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+
+		/*
+		 * On the module itself this is one of these (depending
+		 * on the actual card populated):
+		 * - SDIO_RESET_L_WL_REG_ON
+		 * - PDN (power down when low)
+		 */
+		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */
+	};
+
+	vcc5v0_sys: vccsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+	status = "okay";
+};
+
+&dsi {
+	status = "okay";
+
+	ports {
+		mipi_out: port at 1 {
+			reg = <1>;
+
+			mipi_out_panel: endpoint {
+				remote-endpoint = <&mipi_in_panel>;
+			};
+		};
+	};
+
+	panel at 0 {
+		compatible = "sitronix,st7703";
+		reg = <0>;
+		backlight = <&backlight>;
+		iovcc-supply = <&vcc_1v8>;
+		vci-supply = <&vcc3v3_lcd>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				mipi_in_panel: endpoint {
+					remote-endpoint = <&mipi_out_panel>;
+				};
+			};
+		};
+	};
+};
+
+&dsi_dphy {
+	status = "okay";
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+	non-removable;
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vcc_3v0>;
+	vqmmc-supply = <&vccio_flash>;
+	status = "okay";
+};
+
+&gmac {
+	clock_in_out = "output";
+	phy-supply = <&vcc_rmii>;
+	snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	snps,reset-delays-us = <0 50000 50000>;
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		wakeup-source;
+		#clock-cells = <0>;
+		clock-output-names = "xin32k";
+
+		vcc1-supply = <&vcc5v0_sys>;
+		vcc2-supply = <&vcc5v0_sys>;
+		vcc3-supply = <&vcc5v0_sys>;
+		vcc4-supply = <&vcc5v0_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc5v0_sys>;
+
+		regulators {
+			vdd_log: DCDC_REG1 {
+				regulator-name = "vdd_log";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vdd_arm: DCDC_REG2 {
+				regulator-name = "vdd_arm";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_3v0: vcc_rmii: DCDC_REG4 {
+				regulator-name = "vcc_3v0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3000000>;
+				};
+			};
+
+			vcc3v3_sys: DCDC_REG5 {
+				regulator-name = "vcc3v3_sys";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_1v0: LDO_REG1 {
+				regulator-name = "vcc_1v0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vcc_1v8: vccio_flash: vccio_sdio: LDO_REG2 {
+				regulator-name = "vcc_1v8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_1v0: LDO_REG3 {
+				regulator-name = "vdd_1v0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vcc3v0_pmu: LDO_REG4 {
+				regulator-name = "vcc3v0_pmu";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3000000>;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_sd: LDO_REG6 {
+				regulator-name = "vcc_sd";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc2v8_dvp: LDO_REG7 {
+				regulator-name = "vcc2v8_dvp";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <2800000>;
+				};
+			};
+
+			vcc1v8_dvp: LDO_REG8 {
+				regulator-name = "vcc1v8_dvp";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc1v5_dvp: LDO_REG9 {
+				regulator-name = "vcc1v5_dvp";
+				regulator-min-microvolt = <1500000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <1500000>;
+				};
+			};
+
+			vcc3v3_lcd: SWITCH_REG1 {
+				regulator-name = "vcc3v3_lcd";
+				regulator-boot-on;
+			};
+
+			vcc5v0_host: SWITCH_REG2 {
+				regulator-name = "vcc5v0_host";
+				regulator-always-on;
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
+&i2s1_2ch {
+	status = "okay";
+};
+
+&io_domains {
+	status = "okay";
+
+	vccio1-supply = <&vccio_sdio>;
+	vccio2-supply = <&vccio_sd>;
+	vccio3-supply = <&vcc_3v0>;
+	vccio4-supply = <&vcc3v0_pmu>;
+	vccio5-supply = <&vcc_3v0>;
+	vccio6-supply = <&vccio_flash>;
+};
+
+&pinctrl {
+	headphone {
+		hp_det: hp-det {
+			rockchip,pins =
+				<2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	emmc {
+		emmc_reset: emmc-reset {
+			rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		soc_slppin_gpio: soc_slppin_gpio {
+			rockchip,pins =
+				<0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
+		};
+
+		soc_slppin_slp: soc_slppin_slp {
+			rockchip,pins =
+				<0 RK_PA4 1 &pcfg_pull_none>;
+		};
+
+		soc_slppin_rst: soc_slppin_rst {
+			rockchip,pins =
+				<0 RK_PA4 2 &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins =
+				<0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	status = "okay";
+
+	pmuio1-supply = <&vcc3v0_pmu>;
+	pmuio2-supply = <&vcc3v0_pmu>;
+};
+
+&pwm1 {
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-mmc-highspeed;
+	cap-sd-highspeed;
+	card-detect-delay = <800>;
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&sdio {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	keep-power-in-suspend;
+	non-removable;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	sd-uhs-sdr104;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_xfer &uart1_cts>;
+	status = "okay";
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&usb20_otg {
+	status = "okay";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&vopb {
+	status = "okay";
+};
+
+&vopb_mmu {
+	status = "okay";
+};
+
+&vopl {
+	status = "okay";
+};
+
+&vopl_mmu {
+	status = "okay";
+};
diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi
new file mode 100644
index 0000000000..0d2325a77f
--- /dev/null
+++ b/arch/arm/dts/px30.dtsi
@@ -0,0 +1,2068 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <dt-bindings/clock/px30-cru.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/power/px30-power.h>
+#include <dt-bindings/soc/rockchip,boot-mode.h>
+
+/ {
+	compatible = "rockchip,px30";
+
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		ethernet0 = &gmac;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial4 = &uart4;
+		serial5 = &uart5;
+		spi0 = &spi0;
+		spi1 = &spi1;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+			clocks = <&cru ARMCLK>;
+			#cooling-cells = <2>;
+			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
+			dynamic-power-coefficient = <90>;
+			operating-points-v2 = <&cpu0_opp_table>;
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP: cpu-sleep {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <120>;
+				exit-latency-us = <250>;
+				min-residency-us = <900>;
+			};
+
+			CLUSTER_SLEEP: cluster-sleep {
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x1010000>;
+				entry-latency-us = <400>;
+				exit-latency-us = <500>;
+				min-residency-us = <2000>;
+			};
+		};
+	};
+
+	cpu0_opp_table: cpu0-opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-408000000 {
+			opp-hz = /bits/ 64 <408000000>;
+			opp-microvolt = <950000 950000 1350000>;
+			clock-latency-ns = <40000>;
+			opp-suspend;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <950000 950000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-816000000 {
+			opp-hz = /bits/ 64 <816000000>;
+			opp-microvolt = <1050000 1050000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1008000000 {
+			opp-hz = /bits/ 64 <1008000000>;
+			opp-microvolt = <1175000 1175000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1300000 1300000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+		opp-1296000000 {
+			opp-hz = /bits/ 64 <1296000000>;
+			opp-microvolt = <1350000 1350000 1350000>;
+			clock-latency-ns = <40000>;
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a53-pmu";
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
+	dmc: dmc {
+		compatible = "rockchip,px30-dmc", "syscon";
+		reg = <0x0 0xff2a0000 0x0 0x1000>;
+	};
+
+	display_subsystem: display-subsystem {
+		compatible = "rockchip,display-subsystem";
+		ports = <&vopb_out>, <&vopl_out>;
+		status = "disabled";
+	};
+
+	gmac_clkin: external-gmac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <50000000>;
+		clock-output-names = "gmac_clkin";
+		#clock-cells = <0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	xin24m: xin24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+	};
+
+	pmu: power-management at ff000000 {
+		compatible = "rockchip,px30-pmu", "syscon", "simple-mfd";
+		reg = <0x0 0xff000000 0x0 0x1000>;
+
+		power: power-controller {
+			compatible = "rockchip,px30-power-controller";
+			#power-domain-cells = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* These power domains are grouped by VD_LOGIC */
+			pd_usb at PX30_PD_USB {
+				reg = <PX30_PD_USB>;
+				clocks = <&cru HCLK_HOST>,
+					 <&cru HCLK_OTG>,
+					 <&cru SCLK_OTG_ADP>;
+				pm_qos = <&qos_usb_host>, <&qos_usb_otg>;
+			};
+			pd_sdcard at PX30_PD_SDCARD {
+				reg = <PX30_PD_SDCARD>;
+				clocks = <&cru HCLK_SDMMC>,
+					 <&cru SCLK_SDMMC>;
+				pm_qos = <&qos_sdmmc>;
+			};
+			pd_gmac at PX30_PD_GMAC {
+				reg = <PX30_PD_GMAC>;
+				clocks = <&cru ACLK_GMAC>,
+					 <&cru PCLK_GMAC>,
+					 <&cru SCLK_MAC_REF>,
+					 <&cru SCLK_GMAC_RX_TX>;
+				pm_qos = <&qos_gmac>;
+			};
+			pd_mmc_nand at PX30_PD_MMC_NAND {
+				reg = <PX30_PD_MMC_NAND>;
+				clocks =  <&cru HCLK_NANDC>,
+					  <&cru HCLK_EMMC>,
+					  <&cru HCLK_SDIO>,
+					  <&cru HCLK_SFC>,
+					  <&cru SCLK_EMMC>,
+					  <&cru SCLK_NANDC>,
+					  <&cru SCLK_SDIO>,
+					  <&cru SCLK_SFC>;
+				pm_qos = <&qos_emmc>, <&qos_nand>,
+					 <&qos_sdio>, <&qos_sfc>;
+			};
+			pd_vpu at PX30_PD_VPU {
+				reg = <PX30_PD_VPU>;
+				clocks = <&cru ACLK_VPU>,
+					 <&cru HCLK_VPU>,
+					 <&cru SCLK_CORE_VPU>;
+				pm_qos = <&qos_vpu>, <&qos_vpu_r128>;
+			};
+			pd_vo at PX30_PD_VO {
+				reg = <PX30_PD_VO>;
+				clocks = <&cru ACLK_RGA>,
+					 <&cru ACLK_VOPB>,
+					 <&cru ACLK_VOPL>,
+					 <&cru DCLK_VOPB>,
+					 <&cru DCLK_VOPL>,
+					 <&cru HCLK_RGA>,
+					 <&cru HCLK_VOPB>,
+					 <&cru HCLK_VOPL>,
+					 <&cru PCLK_MIPI_DSI>,
+					 <&cru SCLK_RGA_CORE>,
+					 <&cru SCLK_VOPB_PWM>;
+				pm_qos = <&qos_rga_rd>, <&qos_rga_wr>,
+					 <&qos_vop_m0>, <&qos_vop_m1>;
+			};
+			pd_vi at PX30_PD_VI {
+				reg = <PX30_PD_VI>;
+				clocks = <&cru ACLK_CIF>,
+					 <&cru ACLK_ISP>,
+					 <&cru HCLK_CIF>,
+					 <&cru HCLK_ISP>,
+					 <&cru SCLK_ISP>;
+				pm_qos = <&qos_isp_128>, <&qos_isp_rd>,
+					 <&qos_isp_wr>, <&qos_isp_m1>,
+					 <&qos_vip>;
+			};
+			pd_gpu at PX30_PD_GPU {
+				reg = <PX30_PD_GPU>;
+				clocks = <&cru SCLK_GPU>;
+				pm_qos = <&qos_gpu>;
+			};
+		};
+	};
+
+	pmugrf: syscon at ff010000 {
+		compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd";
+		reg = <0x0 0xff010000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		pmu_io_domains: io-domains {
+			compatible = "rockchip,px30-pmu-io-voltage-domain";
+			status = "disabled";
+		};
+
+		reboot-mode {
+			compatible = "syscon-reboot-mode";
+			offset = <0x200>;
+			mode-bootloader = <BOOT_BL_DOWNLOAD>;
+			mode-fastboot = <BOOT_FASTBOOT>;
+			mode-loader = <BOOT_BL_DOWNLOAD>;
+			mode-normal = <BOOT_NORMAL>;
+			mode-recovery = <BOOT_RECOVERY>;
+		};
+	};
+
+	uart0: serial at ff030000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff030000 0x0 0x100>;
+		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 0>, <&dmac 1>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+		status = "disabled";
+	};
+
+	i2s1_2ch: i2s at ff070000 {
+		compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff070000 0x0 0x1000>;
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac 18>, <&dmac 19>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s1_2ch_sclk &i2s1_2ch_lrck
+			     &i2s1_2ch_sdi &i2s1_2ch_sdo>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	i2s2_2ch: i2s at ff080000 {
+		compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
+		reg = <0x0 0xff080000 0x0 0x1000>;
+		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
+		clock-names = "i2s_clk", "i2s_hclk";
+		dmas = <&dmac 20>, <&dmac 21>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2s2_2ch_sclk &i2s2_2ch_lrck
+			     &i2s2_2ch_sdi &i2s2_2ch_sdo>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
+	gic: interrupt-controller at ff131000 {
+		compatible = "arm,gic-400";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0xff131000 0 0x1000>,
+		      <0x0 0xff132000 0 0x2000>,
+		      <0x0 0xff134000 0 0x2000>,
+		      <0x0 0xff136000 0 0x2000>;
+		interrupts = <GIC_PPI 9
+		      (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+	};
+
+	grf: syscon at ff140000 {
+		compatible = "rockchip,px30-grf", "syscon", "simple-mfd";
+		reg = <0x0 0xff140000 0x0 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		io_domains: io-domains {
+			compatible = "rockchip,px30-io-voltage-domain";
+			status = "disabled";
+		};
+	};
+
+	uart1: serial at ff158000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff158000 0x0 0x100>;
+		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 2>, <&dmac 3>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
+		status = "disabled";
+	};
+
+	uart2: serial at ff160000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff160000 0x0 0x100>;
+		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 4>, <&dmac 5>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2m0_xfer>;
+		status = "disabled";
+	};
+
+	uart3: serial at ff168000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff168000 0x0 0x100>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 6>, <&dmac 7>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>;
+		status = "disabled";
+	};
+
+	uart4: serial at ff170000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff170000 0x0 0x100>;
+		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 8>, <&dmac 9>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
+		status = "disabled";
+	};
+
+	uart5: serial at ff178000 {
+		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
+		reg = <0x0 0xff178000 0x0 0x100>;
+		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
+		clock-names = "baudclk", "apb_pclk";
+		dmas = <&dmac 10>, <&dmac 11>;
+		dma-names = "tx", "rx";
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>;
+		status = "disabled";
+	};
+
+	i2c0: i2c at ff180000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff180000 0x0 0x1000>;
+		clocks =  <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c1: i2c at ff190000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff190000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c1_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c2: i2c at ff1a0000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff1a0000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c2_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	i2c3: i2c at ff1b0000 {
+		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
+		reg = <0x0 0xff1b0000 0x0 0x1000>;
+		clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c3_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi0: spi at ff1d0000 {
+		compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff1d0000 0x0 0x1000>;
+		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac 12>, <&dmac 13>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	spi1: spi at ff1d8000 {
+		compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
+		reg = <0x0 0xff1d8000 0x0 0x1000>;
+		interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
+		clock-names = "spiclk", "apb_pclk";
+		dmas = <&dmac 14>, <&dmac 15>;
+		dma-names = "tx", "rx";
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
+	wdt: watchdog at ff1e0000 {
+		compatible = "snps,dw-wdt";
+		reg = <0x0 0xff1e0000 0x0 0x100>;
+		clocks = <&cru PCLK_WDT_NS>;
+		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+		status = "disabled";
+	};
+
+	pwm0: pwm at ff200000 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200000 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm0_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm1: pwm at ff200010 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200010 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm1_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm2: pwm at ff200020 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200020 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm2_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm3: pwm at ff200030 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff200030 0x0 0x10>;
+		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm3_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm4: pwm at ff208000 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208000 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm4_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm5: pwm at ff208010 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208010 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm5_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm6: pwm at ff208020 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208020 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm6_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	pwm7: pwm at ff208030 {
+		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
+		reg = <0x0 0xff208030 0x0 0x10>;
+		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
+		clock-names = "pwm", "pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pwm7_pin>;
+		#pwm-cells = <3>;
+		status = "disabled";
+	};
+
+	rktimer: timer at ff210000 {
+		compatible = "rockchip,px30-timer", "rockchip,rk3288-timer";
+		reg = <0x0 0xff210000 0x0 0x1000>;
+		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>;
+		clock-names = "pclk", "timer";
+	};
+
+	amba {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		dmac: dmac at ff240000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0xff240000 0x0 0x4000>;
+			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru ACLK_DMAC>;
+			clock-names = "apb_pclk";
+			#dma-cells = <1>;
+		};
+	};
+
+	saradc: saradc at ff288000 {
+		compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc";
+		reg = <0x0 0xff288000 0x0 0x100>;
+		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+		#io-channel-cells = <1>;
+		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
+		clock-names = "saradc", "apb_pclk";
+		resets = <&cru SRST_SARADC_P>;
+		reset-names = "saradc-apb";
+		status = "disabled";
+	};
+
+	otp: nvmem at ff290000 {
+		compatible = "rockchip,px30-otp";
+		reg = <0x0 0xff290000 0x0 0x4000>;
+		clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
+			 <&cru PCLK_OTP_PHY>;
+		clock-names = "otp", "apb_pclk", "phy";
+		resets = <&cru SRST_OTP_PHY>;
+		reset-names = "phy";
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		/* Data cells */
+		cpu_id: id at 7 {
+			reg = <0x07 0x10>;
+		};
+		cpu_leakage: cpu-leakage at 17 {
+			reg = <0x17 0x1>;
+		};
+		performance: performance at 1e {
+			reg = <0x1e 0x1>;
+			bits = <4 3>;
+		};
+	};
+
+	cru: clock-controller at ff2b0000 {
+		compatible = "rockchip,px30-cru";
+		reg = <0x0 0xff2b0000 0x0 0x1000>;
+		clocks = <&xin24m>, <&pmucru PLL_GPLL>;
+		clock-names = "xin24m", "gpll";
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	pmucru: clock-controller at ff2bc000 {
+		compatible = "rockchip,px30-pmucru";
+		reg = <0x0 0xff2bc000 0x0 0x1000>;
+		clocks = <&xin24m>;
+		clock-names = "xin24m";
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	dsi_dphy: phy at ff2e0000 {
+		compatible = "rockchip,px30-dsi-dphy";
+		reg = <0x0 0xff2e0000 0x0 0x10000>;
+		clocks = <&pmucru SCLK_MIPIDSIPHY_REF>, <&cru PCLK_MIPIDSIPHY>;
+		clock-names = "ref", "pclk";
+		#clock-cells = <0>;
+		resets = <&cru SRST_MIPIDSIPHY_P>;
+		reset-names = "apb";
+		#phy-cells = <0>;
+		power-domains = <&power PX30_PD_VO>;
+		status = "disabled";
+	};
+
+	usb20_otg: usb at ff300000 {
+		compatible = "rockchip,px30-usb", "rockchip,rk3066-usb",
+			     "snps,dwc2";
+		reg = <0x0 0xff300000 0x0 0x40000>;
+		interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_OTG>;
+		clock-names = "otg";
+		dr_mode = "otg";
+		g-np-tx-fifo-size = <16>;
+		g-rx-fifo-size = <280>;
+		g-tx-fifo-size = <256 128 128 64 32 16>;
+		g-use-dma;
+		power-domains = <&power PX30_PD_USB>;
+		status = "disabled";
+	};
+
+	usb_host0_ehci: usb at ff340000 {
+		compatible = "generic-ehci";
+		reg = <0x0 0xff340000 0x0 0x10000>;
+		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HOST>;
+		clock-names = "usbhost";
+		power-domains = <&power PX30_PD_USB>;
+		status = "disabled";
+	};
+
+	usb_host0_ohci: usb at ff350000 {
+		compatible = "generic-ohci";
+		reg = <0x0 0xff350000 0x0 0x10000>;
+		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_HOST>;
+		clock-names = "usbhost";
+		power-domains = <&power PX30_PD_USB>;
+		status = "disabled";
+	};
+
+	gmac: ethernet at ff360000 {
+		compatible = "rockchip,px30-gmac";
+		reg = <0x0 0xff360000 0x0 0x10000>;
+		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "macirq";
+		clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>,
+			 <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>,
+			 <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>,
+			 <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>;
+		clock-names = "stmmaceth", "mac_clk_rx",
+			      "mac_clk_tx", "clk_mac_ref",
+			      "clk_mac_refout", "aclk_mac",
+			      "pclk_mac", "clk_mac_speed";
+		rockchip,grf = <&grf>;
+		phy-mode = "rmii";
+		pinctrl-names = "default";
+		pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
+		power-domains = <&power PX30_PD_GMAC>;
+		resets = <&cru SRST_GMAC_A>;
+		reset-names = "stmmaceth";
+		status = "disabled";
+	};
+
+	sdmmc: dwmmc at ff370000 {
+		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff370000 0x0 0x4000>;
+		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
+		power-domains = <&power PX30_PD_SDCARD>;
+		status = "disabled";
+	};
+
+	sdio: dwmmc at ff380000 {
+		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff380000 0x0 0x4000>;
+		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>;
+		power-domains = <&power PX30_PD_MMC_NAND>;
+		status = "disabled";
+	};
+
+	emmc: dwmmc at ff390000 {
+		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
+		reg = <0x0 0xff390000 0x0 0x4000>;
+		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+		fifo-depth = <0x100>;
+		max-frequency = <150000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+		power-domains = <&power PX30_PD_MMC_NAND>;
+		status = "disabled";
+	};
+
+	dsi: dsi at ff450000 {
+		compatible = "rockchip,px30-mipi-dsi";
+		reg = <0x0 0xff450000 0x0 0x10000>;
+		interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_MIPI_DSI>, <&dsi_dphy>;
+		clock-names = "pclk", "pll";
+		resets = <&cru SRST_MIPIDSI_HOST_P>;
+		reset-names = "apb";
+		phys = <&dsi_dphy>;
+		phy-names = "dphy";
+		power-domains = <&power PX30_PD_VO>;
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				dsi_in_vopb: endpoint at 0 {
+					reg = <0>;
+					remote-endpoint = <&vopb_out_dsi>;
+				};
+
+				dsi_in_vopl: endpoint at 1 {
+					reg = <1>;
+					remote-endpoint = <&vopl_out_dsi>;
+				};
+			};
+		};
+	};
+
+	vopb: vop at ff460000 {
+		compatible = "rockchip,px30-vop-big";
+		reg = <0x0 0xff460000 0x0 0xefc>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>,
+			 <&cru HCLK_VOPB>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		resets = <&cru SRST_VOPB_A>, <&cru SRST_VOPB_H>, <&cru SRST_VOPB>;
+		reset-names = "axi", "ahb", "dclk";
+		iommus = <&vopb_mmu>;
+		power-domains = <&power PX30_PD_VO>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		vopb_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vopb_out_dsi: endpoint at 0 {
+				reg = <0>;
+				remote-endpoint = <&dsi_in_vopb>;
+			};
+		};
+	};
+
+	vopb_mmu: iommu at ff460f00 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff460f00 0x0 0x100>;
+		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vopb_mmu";
+		clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power PX30_PD_VO>;
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	vopl: vop at ff470000 {
+		compatible = "rockchip,px30-vop-lit";
+		reg = <0x0 0xff470000 0x0 0xefc>;
+		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>,
+			 <&cru HCLK_VOPL>;
+		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+		resets = <&cru SRST_VOPL_A>, <&cru SRST_VOPL_H>, <&cru SRST_VOPL>;
+		reset-names = "axi", "ahb", "dclk";
+		iommus = <&vopl_mmu>;
+		power-domains = <&power PX30_PD_VO>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		vopl_out: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vopl_out_dsi: endpoint at 0 {
+				reg = <0>;
+				remote-endpoint = <&dsi_in_vopl>;
+			};
+		};
+	};
+
+	vopl_mmu: iommu at ff470f00 {
+		compatible = "rockchip,iommu";
+		reg = <0x0 0xff470f00 0x0 0x100>;
+		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vopl_mmu";
+		clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>;
+		clock-names = "aclk", "iface";
+		power-domains = <&power PX30_PD_VO>;
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
+	qos_gmac: qos at ff518000 {
+		compatible = "syscon";
+		reg = <0x0 0xff518000 0x0 0x20>;
+	};
+
+	qos_gpu: qos at ff520000 {
+		compatible = "syscon";
+		reg = <0x0 0xff520000 0x0 0x20>;
+	};
+
+	qos_sdmmc: qos at ff52c000 {
+		compatible = "syscon";
+		reg = <0x0 0xff52c000 0x0 0x20>;
+	};
+
+	qos_emmc: qos at ff538000 {
+		compatible = "syscon";
+		reg = <0x0 0xff538000 0x0 0x20>;
+	};
+
+	qos_nand: qos at ff538080 {
+		compatible = "syscon";
+		reg = <0x0 0xff538080 0x0 0x20>;
+	};
+
+	qos_sdio: qos at ff538100 {
+		compatible = "syscon";
+		reg = <0x0 0xff538100 0x0 0x20>;
+	};
+
+	qos_sfc: qos at ff538180 {
+		compatible = "syscon";
+		reg = <0x0 0xff538180 0x0 0x20>;
+	};
+
+	qos_usb_host: qos at ff540000 {
+		compatible = "syscon";
+		reg = <0x0 0xff540000 0x0 0x20>;
+	};
+
+	qos_usb_otg: qos at ff540080 {
+		compatible = "syscon";
+		reg = <0x0 0xff540080 0x0 0x20>;
+	};
+
+	qos_isp_128: qos at ff548000 {
+		compatible = "syscon";
+		reg = <0x0 0xff548000 0x0 0x20>;
+	};
+
+	qos_isp_rd: qos at ff548080 {
+		compatible = "syscon";
+		reg = <0x0 0xff548080 0x0 0x20>;
+	};
+
+	qos_isp_wr: qos at ff548100 {
+		compatible = "syscon";
+		reg = <0x0 0xff548100 0x0 0x20>;
+	};
+
+	qos_isp_m1: qos at ff548180 {
+		compatible = "syscon";
+		reg = <0x0 0xff548180 0x0 0x20>;
+	};
+
+	qos_vip: qos at ff548200 {
+		compatible = "syscon";
+		reg = <0x0 0xff548200 0x0 0x20>;
+	};
+
+	qos_rga_rd: qos at ff550000 {
+		compatible = "syscon";
+		reg = <0x0 0xff550000 0x0 0x20>;
+	};
+
+	qos_rga_wr: qos at ff550080 {
+		compatible = "syscon";
+		reg = <0x0 0xff550080 0x0 0x20>;
+	};
+
+	qos_vop_m0: qos at ff550100 {
+		compatible = "syscon";
+		reg = <0x0 0xff550100 0x0 0x20>;
+	};
+
+	qos_vop_m1: qos at ff550180 {
+		compatible = "syscon";
+		reg = <0x0 0xff550180 0x0 0x20>;
+	};
+
+	qos_vpu: qos at ff558000 {
+		compatible = "syscon";
+		reg = <0x0 0xff558000 0x0 0x20>;
+	};
+
+	qos_vpu_r128: qos at ff558080 {
+		compatible = "syscon";
+		reg = <0x0 0xff558080 0x0 0x20>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,px30-pinctrl";
+		rockchip,grf = <&grf>;
+		rockchip,pmu = <&pmugrf>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gpio0: gpio0 at ff040000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff040000 0x0 0x100>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmucru PCLK_GPIO0_PMU>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1 at ff250000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff250000 0x0 0x100>;
+			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2 at ff260000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff260000 0x0 0x100>;
+			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio3 at ff270000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x0 0xff270000 0x0 0x100>;
+			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cru PCLK_GPIO3>;
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_2ma: pcfg-pull-none-2ma {
+			bias-disable;
+			drive-strength = <2>;
+		};
+
+		pcfg_pull_up_2ma: pcfg-pull-up-2ma {
+			bias-pull-up;
+			drive-strength = <2>;
+		};
+
+		pcfg_pull_up_4ma: pcfg-pull-up-4ma {
+			bias-pull-up;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_none_4ma: pcfg-pull-none-4ma {
+			bias-disable;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_down_4ma: pcfg-pull-down-4ma {
+			bias-pull-down;
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_none_8ma: pcfg-pull-none-8ma {
+			bias-disable;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_up_8ma: pcfg-pull-up-8ma {
+			bias-pull-up;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+			bias-disable;
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_up_12ma: pcfg-pull-up-12ma {
+			bias-pull-up;
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_none_smt: pcfg-pull-none-smt {
+			bias-disable;
+			input-schmitt-enable;
+		};
+
+		pcfg_output_high: pcfg-output-high {
+			output-high;
+		};
+
+		pcfg_output_low: pcfg-output-low {
+			output-low;
+		};
+
+		pcfg_input_high: pcfg-input-high {
+			bias-pull-up;
+			input-enable;
+		};
+
+		pcfg_input: pcfg-input {
+			input-enable;
+		};
+
+		i2c0 {
+			i2c0_xfer: i2c0-xfer {
+				rockchip,pins =
+					<0 RK_PB0 1 &pcfg_pull_none_smt>,
+					<0 RK_PB1 1 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins =
+					<0 RK_PC2 1 &pcfg_pull_none_smt>,
+					<0 RK_PC3 1 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c2 {
+			i2c2_xfer: i2c2-xfer {
+				rockchip,pins =
+					<2 RK_PB7 2 &pcfg_pull_none_smt>,
+					<2 RK_PC0 2 &pcfg_pull_none_smt>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins =
+					<1 RK_PB4 4 &pcfg_pull_none_smt>,
+					<1 RK_PB5 4 &pcfg_pull_none_smt>;
+			};
+		};
+
+		tsadc {
+			tsadc_otp_gpio: tsadc-otp-gpio {
+				rockchip,pins =
+					<0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+
+			tsadc_otp_out: tsadc-otp-out {
+				rockchip,pins =
+					<0 RK_PA6 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins =
+					<0 RK_PB2 1 &pcfg_pull_up>,
+					<0 RK_PB3 1 &pcfg_pull_up>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins =
+					<0 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins =
+					<0 RK_PB5 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins =
+					<1 RK_PC1 1 &pcfg_pull_up>,
+					<1 RK_PC0 1 &pcfg_pull_up>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins =
+					<1 RK_PC2 1 &pcfg_pull_none>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins =
+					<1 RK_PC3 1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2-m0 {
+			uart2m0_xfer: uart2m0-xfer {
+				rockchip,pins =
+					<1 RK_PD2 2 &pcfg_pull_up>,
+					<1 RK_PD3 2 &pcfg_pull_up>;
+			};
+		};
+
+		uart2-m1 {
+			uart2m1_xfer: uart2m1-xfer {
+				rockchip,pins =
+					<2 RK_PB4 2 &pcfg_pull_up>,
+					<2 RK_PB6 2 &pcfg_pull_up>;
+			};
+		};
+
+		uart3-m0 {
+			uart3m0_xfer: uart3m0-xfer {
+				rockchip,pins =
+					<0 RK_PC0 2 &pcfg_pull_up>,
+					<0 RK_PC1 2 &pcfg_pull_up>;
+			};
+
+			uart3m0_cts: uart3m0-cts {
+				rockchip,pins =
+					<0 RK_PC2 2 &pcfg_pull_none>;
+			};
+
+			uart3m0_rts: uart3m0-rts {
+				rockchip,pins =
+					<0 RK_PC3 2 &pcfg_pull_none>;
+			};
+		};
+
+		uart3-m1 {
+			uart3m1_xfer: uart3m1-xfer {
+				rockchip,pins =
+					<1 RK_PB6 2 &pcfg_pull_up>,
+					<1 RK_PB7 2 &pcfg_pull_up>;
+			};
+
+			uart3m1_cts: uart3m1-cts {
+				rockchip,pins =
+					<1 RK_PB4 2 &pcfg_pull_none>;
+			};
+
+			uart3m1_rts: uart3m1-rts {
+				rockchip,pins =
+					<1 RK_PB5 2 &pcfg_pull_none>;
+			};
+		};
+
+		uart4 {
+			uart4_xfer: uart4-xfer {
+				rockchip,pins =
+					<1 RK_PD4 2 &pcfg_pull_up>,
+					<1 RK_PD5 2 &pcfg_pull_up>;
+			};
+
+			uart4_cts: uart4-cts {
+				rockchip,pins =
+					<1 RK_PD6 2 &pcfg_pull_none>;
+			};
+
+			uart4_rts: uart4-rts {
+				rockchip,pins =
+					<1 RK_PD7 2 &pcfg_pull_none>;
+			};
+		};
+
+		uart5 {
+			uart5_xfer: uart5-xfer {
+				rockchip,pins =
+					<3 RK_PA2 4 &pcfg_pull_up>,
+					<3 RK_PA1 4 &pcfg_pull_up>;
+			};
+
+			uart5_cts: uart5-cts {
+				rockchip,pins =
+					<3 RK_PA3 4 &pcfg_pull_none>;
+			};
+
+			uart5_rts: uart5-rts {
+				rockchip,pins =
+					<3 RK_PA5 4 &pcfg_pull_none>;
+			};
+		};
+
+		spi0 {
+			spi0_clk: spi0-clk {
+				rockchip,pins =
+					<1 RK_PB7 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_csn: spi0-csn {
+				rockchip,pins =
+					<1 RK_PB6 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_miso: spi0-miso {
+				rockchip,pins =
+					<1 RK_PB5 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_mosi: spi0-mosi {
+				rockchip,pins =
+					<1 RK_PB4 3 &pcfg_pull_up_4ma>;
+			};
+
+			spi0_clk_hs: spi0-clk-hs {
+				rockchip,pins =
+					<1 RK_PB7 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi0_miso_hs: spi0-miso-hs {
+				rockchip,pins =
+					<1 RK_PB5 3 &pcfg_pull_up_8ma>;
+			};
+
+			spi0_mosi_hs: spi0-mosi-hs {
+				rockchip,pins =
+					<1 RK_PB4 3 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		spi1 {
+			spi1_clk: spi1-clk {
+				rockchip,pins =
+					<3 RK_PB7 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_csn0: spi1-csn0 {
+				rockchip,pins =
+					<3 RK_PB1 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_csn1: spi1-csn1 {
+				rockchip,pins =
+					<3 RK_PB2 2 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_miso: spi1-miso {
+				rockchip,pins =
+					<3 RK_PB6 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_mosi: spi1-mosi {
+				rockchip,pins =
+					<3 RK_PB4 4 &pcfg_pull_up_4ma>;
+			};
+
+			spi1_clk_hs: spi1-clk-hs {
+				rockchip,pins =
+					<3 RK_PB7 4 &pcfg_pull_up_8ma>;
+			};
+
+			spi1_miso_hs: spi1-miso-hs {
+				rockchip,pins =
+					<3 RK_PB6 4 &pcfg_pull_up_8ma>;
+			};
+
+			spi1_mosi_hs: spi1-mosi-hs {
+				rockchip,pins =
+					<3 RK_PB4 4 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		pdm {
+			pdm_clk0m0: pdm-clk0m0 {
+				rockchip,pins =
+					<3 RK_PC6 2 &pcfg_pull_none>;
+			};
+
+			pdm_clk0m1: pdm-clk0m1 {
+				rockchip,pins =
+					<2 RK_PC6 1 &pcfg_pull_none>;
+			};
+
+			pdm_clk1: pdm-clk1 {
+				rockchip,pins =
+					<3 RK_PC7 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi0m0: pdm-sdi0m0 {
+				rockchip,pins =
+					<3 RK_PD3 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi0m1: pdm-sdi0m1 {
+				rockchip,pins =
+					<2 RK_PC5 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi1: pdm-sdi1 {
+				rockchip,pins =
+					<3 RK_PD0 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi2: pdm-sdi2 {
+				rockchip,pins =
+					<3 RK_PD1 2 &pcfg_pull_none>;
+			};
+
+			pdm_sdi3: pdm-sdi3 {
+				rockchip,pins =
+					<3 RK_PD2 2 &pcfg_pull_none>;
+			};
+
+			pdm_clk0m0_sleep: pdm-clk0m0-sleep {
+				rockchip,pins =
+					<3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_clk0m_sleep1: pdm-clk0m1-sleep {
+				rockchip,pins =
+					<2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_clk1_sleep: pdm-clk1-sleep {
+				rockchip,pins =
+					<3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi0m0_sleep: pdm-sdi0m0-sleep {
+				rockchip,pins =
+					<3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi0m1_sleep: pdm-sdi0m1-sleep {
+				rockchip,pins =
+					<2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi1_sleep: pdm-sdi1-sleep {
+				rockchip,pins =
+					<3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi2_sleep: pdm-sdi2-sleep {
+				rockchip,pins =
+					<3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+
+			pdm_sdi3_sleep: pdm-sdi3-sleep {
+				rockchip,pins =
+					<3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>;
+			};
+		};
+
+		i2s0 {
+			i2s0_8ch_mclk: i2s0-8ch-mclk {
+				rockchip,pins =
+					<3 RK_PC1 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sclktx: i2s0-8ch-sclktx {
+				rockchip,pins =
+					<3 RK_PC3 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sclkrx: i2s0-8ch-sclkrx {
+				rockchip,pins =
+					<3 RK_PB4 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_lrcktx: i2s0-8ch-lrcktx {
+				rockchip,pins =
+					<3 RK_PC2 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_lrckrx: i2s0-8ch-lrckrx {
+				rockchip,pins =
+					<3 RK_PB5 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo0: i2s0-8ch-sdo0 {
+				rockchip,pins =
+					<3 RK_PC4 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo1: i2s0-8ch-sdo1 {
+				rockchip,pins =
+					<3 RK_PC0 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo2: i2s0-8ch-sdo2 {
+				rockchip,pins =
+					<3 RK_PB7 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdo3: i2s0-8ch-sdo3 {
+				rockchip,pins =
+					<3 RK_PB6 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi0: i2s0-8ch-sdi0 {
+				rockchip,pins =
+					<3 RK_PC5 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi1: i2s0-8ch-sdi1 {
+				rockchip,pins =
+					<3 RK_PB3 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi2: i2s0-8ch-sdi2 {
+				rockchip,pins =
+					<3 RK_PB1 2 &pcfg_pull_none>;
+			};
+
+			i2s0_8ch_sdi3: i2s0-8ch-sdi3 {
+				rockchip,pins =
+					<3 RK_PB0 2 &pcfg_pull_none>;
+			};
+		};
+
+		i2s1 {
+			i2s1_2ch_mclk: i2s1-2ch-mclk {
+				rockchip,pins =
+					<2 RK_PC3 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_sclk: i2s1-2ch-sclk {
+				rockchip,pins =
+					<2 RK_PC2 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_lrck: i2s1-2ch-lrck {
+				rockchip,pins =
+					<2 RK_PC1 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_sdi: i2s1-2ch-sdi {
+				rockchip,pins =
+					<2 RK_PC5 1 &pcfg_pull_none>;
+			};
+
+			i2s1_2ch_sdo: i2s1-2ch-sdo {
+				rockchip,pins =
+					<2 RK_PC4 1 &pcfg_pull_none>;
+			};
+		};
+
+		i2s2 {
+			i2s2_2ch_mclk: i2s2-2ch-mclk {
+				rockchip,pins =
+					<3 RK_PA1 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_sclk: i2s2-2ch-sclk {
+				rockchip,pins =
+					<3 RK_PA2 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_lrck: i2s2-2ch-lrck {
+				rockchip,pins =
+					<3 RK_PA3 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_sdi: i2s2-2ch-sdi {
+				rockchip,pins =
+					<3 RK_PA5 2 &pcfg_pull_none>;
+			};
+
+			i2s2_2ch_sdo: i2s2-2ch-sdo {
+				rockchip,pins =
+					<3 RK_PA7 2 &pcfg_pull_none>;
+			};
+		};
+
+		sdmmc {
+			sdmmc_clk: sdmmc-clk {
+				rockchip,pins =
+					<1 RK_PD6 1 &pcfg_pull_none_8ma>;
+			};
+
+			sdmmc_cmd: sdmmc-cmd {
+				rockchip,pins =
+					<1 RK_PD7 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdmmc_det: sdmmc-det {
+				rockchip,pins =
+					<0 RK_PA3 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdmmc_bus1: sdmmc-bus1 {
+				rockchip,pins =
+					<1 RK_PD2 1 &pcfg_pull_up_8ma>;
+			};
+
+			sdmmc_bus4: sdmmc-bus4 {
+				rockchip,pins =
+					<1 RK_PD2 1 &pcfg_pull_up_8ma>,
+					<1 RK_PD3 1 &pcfg_pull_up_8ma>,
+					<1 RK_PD4 1 &pcfg_pull_up_8ma>,
+					<1 RK_PD5 1 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		sdio {
+			sdio_clk: sdio-clk {
+				rockchip,pins =
+					<1 RK_PC5 1 &pcfg_pull_none>;
+			};
+
+			sdio_cmd: sdio-cmd {
+				rockchip,pins =
+					<1 RK_PC4 1 &pcfg_pull_up>;
+			};
+
+			sdio_bus4: sdio-bus4 {
+				rockchip,pins =
+					<1 RK_PC6 1 &pcfg_pull_up>,
+					<1 RK_PC7 1 &pcfg_pull_up>,
+					<1 RK_PD0 1 &pcfg_pull_up>,
+					<1 RK_PD1 1 &pcfg_pull_up>;
+			};
+		};
+
+		emmc {
+			emmc_clk: emmc-clk {
+				rockchip,pins =
+					<1 RK_PB1 2 &pcfg_pull_none_8ma>;
+			};
+
+			emmc_cmd: emmc-cmd {
+				rockchip,pins =
+					<1 RK_PB2 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_rstnout: emmc-rstnout {
+				rockchip,pins =
+					<1 RK_PB3 2 &pcfg_pull_none>;
+			};
+
+			emmc_bus1: emmc-bus1 {
+				rockchip,pins =
+					<1 RK_PA0 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_bus4: emmc-bus4 {
+				rockchip,pins =
+					<1 RK_PA0 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA1 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA2 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA3 2 &pcfg_pull_up_8ma>;
+			};
+
+			emmc_bus8: emmc-bus8 {
+				rockchip,pins =
+					<1 RK_PA0 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA1 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA2 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA3 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA4 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA5 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA6 2 &pcfg_pull_up_8ma>,
+					<1 RK_PA7 2 &pcfg_pull_up_8ma>;
+			};
+		};
+
+		flash {
+			flash_cs0: flash-cs0 {
+				rockchip,pins =
+					<1 RK_PB0 1 &pcfg_pull_none>;
+			};
+
+			flash_rdy: flash-rdy {
+				rockchip,pins =
+					<1 RK_PB1 1 &pcfg_pull_none>;
+			};
+
+			flash_dqs: flash-dqs {
+				rockchip,pins =
+					<1 RK_PB2 1 &pcfg_pull_none>;
+			};
+
+			flash_ale: flash-ale {
+				rockchip,pins =
+					<1 RK_PB3 1 &pcfg_pull_none>;
+			};
+
+			flash_cle: flash-cle {
+				rockchip,pins =
+					<1 RK_PB4 1 &pcfg_pull_none>;
+			};
+
+			flash_wrn: flash-wrn {
+				rockchip,pins =
+					<1 RK_PB5 1 &pcfg_pull_none>;
+			};
+
+			flash_csl: flash-csl {
+				rockchip,pins =
+					<1 RK_PB6 1 &pcfg_pull_none>;
+			};
+
+			flash_rdn: flash-rdn {
+				rockchip,pins =
+					<1 RK_PB7 1 &pcfg_pull_none>;
+			};
+
+			flash_bus8: flash-bus8 {
+				rockchip,pins =
+					<1 RK_PA0 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA1 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA2 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA3 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA4 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA5 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA6 1 &pcfg_pull_up_12ma>,
+					<1 RK_PA7 1 &pcfg_pull_up_12ma>;
+			};
+		};
+
+		lcdc {
+			lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin {
+				rockchip,pins =
+					<3 RK_PA0 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb_m0_hsync_pin: lcdc-rgb-m0-hsync-pin {
+				rockchip,pins =
+					<3 RK_PA1 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb_m0_vsync_pin: lcdc-rgb-m0-vsync-pin {
+				rockchip,pins =
+					<3 RK_PA2 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb_m0_den_pin: lcdc-rgb-m0-den-pin {
+				rockchip,pins =
+					<3 RK_PA3 1 &pcfg_pull_none_12ma>;
+			};
+
+			lcdc_rgb888_m0_data_pins: lcdc-rgb888-m0-data-pins {
+				rockchip,pins =
+					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
+					<3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
+					<3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
+					<3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
+					<3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
+					<3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
+			};
+
+			lcdc_rgb666_m0_data_pins: lcdc-rgb666-m0-data-pins {
+				rockchip,pins =
+					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
+			};
+
+			lcdc_rgb565_m0_data_pins: lcdc-rgb565-m0-data-pins {
+				rockchip,pins =
+					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
+					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
+					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
+					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
+			};
+
+			lcdc_rgb888_m1_data_pins: lcdc-rgb888-m1-data-pins {
+				rockchip,pins =
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
+					<3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
+					<3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
+					<3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
+					<3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
+					<3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
+			};
+
+			lcdc_rgb666_m1_data_pins: lcdc-rgb666-m1-data-pins {
+				rockchip,pins =
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
+					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
+					<3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
+			};
+
+			lcdc_rgb565_m1_data_pins: lcdc-rgb565-m1-data-pins {
+				rockchip,pins =
+					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
+					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
+					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
+					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
+					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
+					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
+					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
+					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
+					<3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
+			};
+		};
+
+		pwm0 {
+			pwm0_pin: pwm0-pin {
+				rockchip,pins =
+					<0 RK_PB7 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm1 {
+			pwm1_pin: pwm1-pin {
+				rockchip,pins =
+					<0 RK_PC0 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm2 {
+			pwm2_pin: pwm2-pin {
+				rockchip,pins =
+					<2 RK_PB5 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm3 {
+			pwm3_pin: pwm3-pin {
+				rockchip,pins =
+					<0 RK_PC1 1 &pcfg_pull_none>;
+			};
+		};
+
+		pwm4 {
+			pwm4_pin: pwm4-pin {
+				rockchip,pins =
+					<3 RK_PC2 3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm5 {
+			pwm5_pin: pwm5-pin {
+				rockchip,pins =
+					<3 RK_PC3 3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm6 {
+			pwm6_pin: pwm6-pin {
+				rockchip,pins =
+					<3 RK_PC4 3 &pcfg_pull_none>;
+			};
+		};
+
+		pwm7 {
+			pwm7_pin: pwm7-pin {
+				rockchip,pins =
+					<3 RK_PC5 3 &pcfg_pull_none>;
+			};
+		};
+
+		gmac {
+			rmii_pins: rmii-pins {
+				rockchip,pins =
+					<2 RK_PA0 2 &pcfg_pull_none_12ma>, /* mac_txen */
+					<2 RK_PA1 2 &pcfg_pull_none_12ma>, /* mac_txd1 */
+					<2 RK_PA2 2 &pcfg_pull_none_12ma>, /* mac_txd0 */
+					<2 RK_PA3 2 &pcfg_pull_none>, /* mac_rxd0 */
+					<2 RK_PA4 2 &pcfg_pull_none>, /* mac_rxd1 */
+					<2 RK_PA5 2 &pcfg_pull_none>, /* mac_rxer */
+					<2 RK_PA6 2 &pcfg_pull_none>, /* mac_rxdv */
+					<2 RK_PA7 2 &pcfg_pull_none>, /* mac_mdio */
+					<2 RK_PB1 2 &pcfg_pull_none>; /* mac_mdc */
+			};
+
+			mac_refclk_12ma: mac-refclk-12ma {
+				rockchip,pins =
+					<2 RK_PB2 2 &pcfg_pull_none_12ma>;
+			};
+
+			mac_refclk: mac-refclk {
+				rockchip,pins =
+					<2 RK_PB2 2 &pcfg_pull_none>;
+			};
+		};
+
+		cif-m0 {
+			cif_clkout_m0: cif-clkout-m0 {
+				rockchip,pins =
+					<2 RK_PB3 1 &pcfg_pull_none>;
+			};
+
+			dvp_d2d9_m0: dvp-d2d9-m0 {
+				rockchip,pins =
+					<2 RK_PA0 1 &pcfg_pull_none>, /* cif_data2 */
+					<2 RK_PA1 1 &pcfg_pull_none>, /* cif_data3 */
+					<2 RK_PA2 1 &pcfg_pull_none>, /* cif_data4 */
+					<2 RK_PA3 1 &pcfg_pull_none>, /* cif_data5 */
+					<2 RK_PA4 1 &pcfg_pull_none>, /* cif_data6 */
+					<2 RK_PA5 1 &pcfg_pull_none>, /* cif_data7 */
+					<2 RK_PA6 1 &pcfg_pull_none>, /* cif_data8 */
+					<2 RK_PA7 1 &pcfg_pull_none>, /* cif_data9 */
+					<2 RK_PB0 1 &pcfg_pull_none>, /* cif_sync */
+					<2 RK_PB1 1 &pcfg_pull_none>, /* cif_href */
+					<2 RK_PB2 1 &pcfg_pull_none>, /* cif_clkin */
+					<2 RK_PB3 1 &pcfg_pull_none>; /* cif_clkout */
+			};
+
+			dvp_d0d1_m0: dvp-d0d1-m0 {
+				rockchip,pins =
+					<2 RK_PB4 1 &pcfg_pull_none>, /* cif_data0 */
+					<2 RK_PB6 1 &pcfg_pull_none>; /* cif_data1 */
+			};
+
+			dvp_d10d11_m0:d10-d11-m0 {
+				rockchip,pins =
+					<2 RK_PB7 1 &pcfg_pull_none>, /* cif_data10 */
+					<2 RK_PC0 1 &pcfg_pull_none>; /* cif_data11 */
+			};
+		};
+
+		cif-m1 {
+			cif_clkout_m1: cif-clkout-m1 {
+				rockchip,pins =
+					<3 RK_PD0 3 &pcfg_pull_none>;
+			};
+
+			dvp_d2d9_m1: dvp-d2d9-m1 {
+				rockchip,pins =
+					<3 RK_PA3 3 &pcfg_pull_none>, /* cif_data2 */
+					<3 RK_PA5 3 &pcfg_pull_none>, /* cif_data3 */
+					<3 RK_PA7 3 &pcfg_pull_none>, /* cif_data4 */
+					<3 RK_PB0 3 &pcfg_pull_none>, /* cif_data5 */
+					<3 RK_PB1 3 &pcfg_pull_none>, /* cif_data6 */
+					<3 RK_PB4 3 &pcfg_pull_none>, /* cif_data7 */
+					<3 RK_PB6 3 &pcfg_pull_none>, /* cif_data8 */
+					<3 RK_PB7 3 &pcfg_pull_none>, /* cif_data9 */
+					<3 RK_PD1 3 &pcfg_pull_none>, /* cif_sync */
+					<3 RK_PD2 3 &pcfg_pull_none>, /* cif_href */
+					<3 RK_PD3 3 &pcfg_pull_none>, /* cif_clkin */
+					<3 RK_PD0 3 &pcfg_pull_none>; /* cif_clkout */
+			};
+
+			dvp_d0d1_m1: dvp-d0d1-m1 {
+				rockchip,pins =
+					<3 RK_PA1 3 &pcfg_pull_none>, /* cif_data0 */
+					<3 RK_PA2 3 &pcfg_pull_none>; /* cif_data1 */
+			};
+
+			dvp_d10d11_m1:d10-d11-m1 {
+				rockchip,pins =
+					<3 RK_PC6 3 &pcfg_pull_none>, /* cif_data10 */
+					<3 RK_PC7 3 &pcfg_pull_none>; /* cif_data11 */
+			};
+		};
+
+		isp {
+			isp_prelight: isp-prelight {
+				rockchip,pins =
+					<3 RK_PD1 4 &pcfg_pull_none>;
+			};
+		};
+	};
+};
-- 
2.23.0

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

* [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (9 preceding siblings ...)
  2019-10-24 23:28 ` [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees Heiko Stuebner
@ 2019-10-24 23:28 ` Heiko Stuebner
  2019-10-25  2:49   ` Kever Yang
  2019-10-24 23:28 ` [U-Boot] [PATCH 12/12] rockchip: add px30-evb board Heiko Stuebner
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:28 UTC (permalink / raw)
  To: u-boot

From: Kever Yang <kever.yang@rock-chips.com>

Add core architecture code to support the px30 soc.
This includes a separate tpl board file due to very limited
sram size as well as a non-dm sdram driver, as this also has
to fit into the tiny sram.

Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 arch/arm/include/asm/arch-px30/boot0.h        |   11 +
 arch/arm/include/asm/arch-px30/gpio.h         |   11 +
 .../include/asm/arch-rockchip/sdram_px30.h    |  359 +++++
 arch/arm/mach-rockchip/Kconfig                |   23 +
 arch/arm/mach-rockchip/Makefile               |    2 +
 arch/arm/mach-rockchip/px30-board-tpl.c       |   59 +
 arch/arm/mach-rockchip/px30/Kconfig           |   48 +
 arch/arm/mach-rockchip/px30/Makefile          |   14 +
 arch/arm/mach-rockchip/px30/clk_px30.c        |   31 +
 arch/arm/mach-rockchip/px30/px30.c            |  248 +++
 .../px30/sdram-px30-ddr3-detect-333.inc       |   70 +
 .../px30/sdram-px30-ddr4-detect-333.inc       |   73 +
 .../px30/sdram-px30-ddr_skew.inc              |  121 ++
 .../px30/sdram-px30-lpddr2-detect-333.inc     |   71 +
 .../px30/sdram-px30-lpddr3-detect-333.inc     |   72 +
 arch/arm/mach-rockchip/px30/sdram_px30.c      | 1405 +++++++++++++++++
 arch/arm/mach-rockchip/px30/syscon_px30.c     |   53 +
 17 files changed, 2671 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-px30/boot0.h
 create mode 100644 arch/arm/include/asm/arch-px30/gpio.h
 create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h
 create mode 100644 arch/arm/mach-rockchip/px30-board-tpl.c
 create mode 100644 arch/arm/mach-rockchip/px30/Kconfig
 create mode 100644 arch/arm/mach-rockchip/px30/Makefile
 create mode 100644 arch/arm/mach-rockchip/px30/clk_px30.c
 create mode 100644 arch/arm/mach-rockchip/px30/px30.c
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
 create mode 100644 arch/arm/mach-rockchip/px30/sdram_px30.c
 create mode 100644 arch/arm/mach-rockchip/px30/syscon_px30.c

diff --git a/arch/arm/include/asm/arch-px30/boot0.h b/arch/arm/include/asm/arch-px30/boot0.h
new file mode 100644
index 0000000000..2e78b074ad
--- /dev/null
+++ b/arch/arm/include/asm/arch-px30/boot0.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_BOOT0_H__
+#define __ASM_ARCH_BOOT0_H__
+
+#include <asm/arch-rockchip/boot0.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-px30/gpio.h b/arch/arm/include/asm/arch-px30/gpio.h
new file mode 100644
index 0000000000..eca79d5159
--- /dev/null
+++ b/arch/arm/include/asm/arch-px30/gpio.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __ASM_ARCH_GPIO_H__
+#define __ASM_ARCH_GPIO_H__
+
+#include <asm/arch-rockchip/gpio.h>
+
+#endif
diff --git a/arch/arm/include/asm/arch-rockchip/sdram_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
new file mode 100644
index 0000000000..e10eb97b89
--- /dev/null
+++ b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
@@ -0,0 +1,359 @@
+/* SPDX-License-Identifier:     GPL-2.0+ */
+/*
+ * Copyright (C) 2018 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef _ASM_ARCH_SDRAM_PX30_H
+#define _ASM_ARCH_SDRAM_PX30_H
+
+struct ddr_pctl_regs {
+	u32 pctl[30][2];
+};
+
+/* ddr pctl registers define */
+#define DDR_PCTL2_MSTR			0x0
+#define DDR_PCTL2_STAT			0x4
+#define DDR_PCTL2_MSTR1			0x8
+#define DDR_PCTL2_MRCTRL0		0x10
+#define DDR_PCTL2_MRCTRL1		0x14
+#define DDR_PCTL2_MRSTAT		0x18
+#define DDR_PCTL2_MRCTRL2		0x1c
+#define DDR_PCTL2_DERATEEN		0x20
+#define DDR_PCTL2_DERATEINT		0x24
+#define DDR_PCTL2_PWRCTL		0x30
+#define DDR_PCTL2_PWRTMG		0x34
+#define DDR_PCTL2_HWLPCTL		0x38
+#define DDR_PCTL2_RFSHCTL0		0x50
+#define DDR_PCTL2_RFSHCTL1		0x54
+#define DDR_PCTL2_RFSHCTL2		0x58
+#define DDR_PCTL2_RFSHCTL4		0x5c
+#define DDR_PCTL2_RFSHCTL3		0x60
+#define DDR_PCTL2_RFSHTMG		0x64
+#define DDR_PCTL2_RFSHTMG1		0x68
+#define DDR_PCTL2_RFSHCTL5		0x6c
+#define DDR_PCTL2_INIT0			0xd0
+#define DDR_PCTL2_INIT1			0xd4
+#define DDR_PCTL2_INIT2			0xd8
+#define DDR_PCTL2_INIT3			0xdc
+#define DDR_PCTL2_INIT4			0xe0
+#define DDR_PCTL2_INIT5			0xe4
+#define DDR_PCTL2_INIT6			0xe8
+#define DDR_PCTL2_INIT7			0xec
+#define DDR_PCTL2_DIMMCTL		0xf0
+#define DDR_PCTL2_RANKCTL		0xf4
+#define DDR_PCTL2_CHCTL			0xfc
+#define DDR_PCTL2_DRAMTMG0		0x100
+#define DDR_PCTL2_DRAMTMG1		0x104
+#define DDR_PCTL2_DRAMTMG2		0x108
+#define DDR_PCTL2_DRAMTMG3		0x10c
+#define DDR_PCTL2_DRAMTMG4		0x110
+#define DDR_PCTL2_DRAMTMG5		0x114
+#define DDR_PCTL2_DRAMTMG6		0x118
+#define DDR_PCTL2_DRAMTMG7		0x11c
+#define DDR_PCTL2_DRAMTMG8		0x120
+#define DDR_PCTL2_DRAMTMG9		0x124
+#define DDR_PCTL2_DRAMTMG10		0x128
+#define DDR_PCTL2_DRAMTMG11		0x12c
+#define DDR_PCTL2_DRAMTMG12		0x130
+#define DDR_PCTL2_DRAMTMG13		0x134
+#define DDR_PCTL2_DRAMTMG14		0x138
+#define DDR_PCTL2_DRAMTMG15		0x13c
+#define DDR_PCTL2_DRAMTMG16		0x140
+#define DDR_PCTL2_ZQCTL0		0x180
+#define DDR_PCTL2_ZQCTL1		0x184
+#define DDR_PCTL2_ZQCTL2		0x188
+#define DDR_PCTL2_ZQSTAT		0x18c
+#define DDR_PCTL2_DFITMG0		0x190
+#define DDR_PCTL2_DFITMG1		0x194
+#define DDR_PCTL2_DFILPCFG0		0x198
+#define DDR_PCTL2_DFILPCFG1		0x19c
+#define DDR_PCTL2_DFIUPD0		0x1a0
+#define DDR_PCTL2_DFIUPD1		0x1a4
+#define DDR_PCTL2_DFIUPD2		0x1a8
+#define DDR_PCTL2_DFIMISC		0x1b0
+#define DDR_PCTL2_DFITMG2		0x1b4
+#define DDR_PCTL2_DFITMG3		0x1b8
+#define DDR_PCTL2_DFISTAT		0x1bc
+#define DDR_PCTL2_DBICTL		0x1c0
+#define DDR_PCTL2_ADDRMAP0		0x200
+#define DDR_PCTL2_ADDRMAP1		0x204
+#define DDR_PCTL2_ADDRMAP2		0x208
+#define DDR_PCTL2_ADDRMAP3		0x20c
+#define DDR_PCTL2_ADDRMAP4		0x210
+#define DDR_PCTL2_ADDRMAP5		0x214
+#define DDR_PCTL2_ADDRMAP6		0x218
+#define DDR_PCTL2_ADDRMAP7		0x21c
+#define DDR_PCTL2_ADDRMAP8		0x220
+#define DDR_PCTL2_ADDRMAP9		0x224
+#define DDR_PCTL2_ADDRMAP10		0x228
+#define DDR_PCTL2_ADDRMAP11		0x22c
+#define DDR_PCTL2_ODTCFG		0x240
+#define DDR_PCTL2_ODTMAP		0x244
+#define DDR_PCTL2_SCHED			0x250
+#define DDR_PCTL2_SCHED1		0x254
+#define DDR_PCTL2_PERFHPR1		0x25c
+#define DDR_PCTL2_PERFLPR1		0x264
+#define DDR_PCTL2_PERFWR1		0x26c
+#define DDR_PCTL2_DQMAP0		0x280
+#define DDR_PCTL2_DQMAP1		0x284
+#define DDR_PCTL2_DQMAP2		0x288
+#define DDR_PCTL2_DQMAP3		0x28c
+#define DDR_PCTL2_DQMAP4		0x290
+#define DDR_PCTL2_DQMAP5		0x294
+#define DDR_PCTL2_DBG0			0x300
+#define DDR_PCTL2_DBG1			0x304
+#define DDR_PCTL2_DBGCAM		0x308
+#define DDR_PCTL2_DBGCMD		0x30c
+#define DDR_PCTL2_DBGSTAT		0x310
+#define DDR_PCTL2_SWCTL			0x320
+#define DDR_PCTL2_SWSTAT		0x324
+#define DDR_PCTL2_POISONCFG		0x36c
+#define DDR_PCTL2_POISONSTAT		0x370
+#define DDR_PCTL2_ADVECCINDEX		0x374
+#define DDR_PCTL2_ADVECCSTAT		0x378
+#define DDR_PCTL2_PSTAT			0x3fc
+#define DDR_PCTL2_PCCFG			0x400
+#define DDR_PCTL2_PCFGR_n		0x404
+#define DDR_PCTL2_PCFGW_n		0x408
+#define DDR_PCTL2_PCTRL_n		0x490
+
+/* PCTL2_MRSTAT */
+#define MR_WR_BUSY			BIT(0)
+
+#define PHY_DDR3_RON_RTT_DISABLE	(0)
+#define PHY_DDR3_RON_RTT_451ohm		(1)
+#define PHY_DDR3_RON_RTT_225ohm		(2)
+#define PHY_DDR3_RON_RTT_150ohm		(3)
+#define PHY_DDR3_RON_RTT_112ohm		(4)
+#define PHY_DDR3_RON_RTT_90ohm		(5)
+#define PHY_DDR3_RON_RTT_75ohm		(6)
+#define PHY_DDR3_RON_RTT_64ohm		(7)
+#define PHY_DDR3_RON_RTT_56ohm		(16)
+#define PHY_DDR3_RON_RTT_50ohm		(17)
+#define PHY_DDR3_RON_RTT_45ohm		(18)
+#define PHY_DDR3_RON_RTT_41ohm		(19)
+#define PHY_DDR3_RON_RTT_37ohm		(20)
+#define PHY_DDR3_RON_RTT_34ohm		(21)
+#define PHY_DDR3_RON_RTT_33ohm		(22)
+#define PHY_DDR3_RON_RTT_30ohm		(23)
+#define PHY_DDR3_RON_RTT_28ohm		(24)
+#define PHY_DDR3_RON_RTT_26ohm		(25)
+#define PHY_DDR3_RON_RTT_25ohm		(26)
+#define PHY_DDR3_RON_RTT_23ohm		(27)
+#define PHY_DDR3_RON_RTT_22ohm		(28)
+#define PHY_DDR3_RON_RTT_21ohm		(29)
+#define PHY_DDR3_RON_RTT_20ohm		(30)
+#define PHY_DDR3_RON_RTT_19ohm		(31)
+
+#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE	(0)
+#define PHY_DDR4_LPDDR3_RON_RTT_480ohm	(1)
+#define PHY_DDR4_LPDDR3_RON_RTT_240ohm	(2)
+#define PHY_DDR4_LPDDR3_RON_RTT_160ohm	(3)
+#define PHY_DDR4_LPDDR3_RON_RTT_120ohm	(4)
+#define PHY_DDR4_LPDDR3_RON_RTT_96ohm	(5)
+#define PHY_DDR4_LPDDR3_RON_RTT_80ohm	(6)
+#define PHY_DDR4_LPDDR3_RON_RTT_68ohm	(7)
+#define PHY_DDR4_LPDDR3_RON_RTT_60ohm	(16)
+#define PHY_DDR4_LPDDR3_RON_RTT_53ohm	(17)
+#define PHY_DDR4_LPDDR3_RON_RTT_48ohm	(18)
+#define PHY_DDR4_LPDDR3_RON_RTT_43ohm	(19)
+#define PHY_DDR4_LPDDR3_RON_RTT_40ohm	(20)
+#define PHY_DDR4_LPDDR3_RON_RTT_37ohm	(21)
+#define PHY_DDR4_LPDDR3_RON_RTT_34ohm	(22)
+#define PHY_DDR4_LPDDR3_RON_RTT_32ohm	(23)
+#define PHY_DDR4_LPDDR3_RON_RTT_30ohm	(24)
+#define PHY_DDR4_LPDDR3_RON_RTT_28ohm	(25)
+#define PHY_DDR4_LPDDR3_RON_RTT_26ohm	(26)
+#define PHY_DDR4_LPDDR3_RON_RTT_25ohm	(27)
+#define PHY_DDR4_LPDDR3_RON_RTT_24ohm	(28)
+#define PHY_DDR4_LPDDR3_RON_RTT_22ohm	(29)
+#define PHY_DDR4_LPDDR3_RON_RTT_21ohm	(30)
+#define PHY_DDR4_LPDDR3_RON_RTT_20ohm	(31)
+
+struct ddr_phy_regs {
+	u32 phy[5][2];
+};
+
+#define PHY_REG(base, n)		((base) + 4 * (n))
+
+/* PHY_REG0 */
+#define DIGITAL_DERESET			BIT(3)
+#define ANALOG_DERESET			BIT(2)
+#define DIGITAL_RESET			(0 << 3)
+#define ANALOG_RESET			(0 << 2)
+
+/* PHY_REG1 */
+#define PHY_DDR2			(0)
+#define PHY_LPDDR2			(1)
+#define PHY_DDR3			(2)
+#define PHY_LPDDR3			(3)
+#define PHY_DDR4			(4)
+#define PHY_BL_4			(0 << 2)
+#define PHY_BL_8			BIT(2)
+
+/* PHY_REG2 */
+#define PHY_DTT_EN			BIT(0)
+#define PHY_DTT_DISB			(0 << 0)
+#define PHY_WRITE_LEVELING_EN		BIT(2)
+#define PHY_WRITE_LEVELING_DISB		(0 << 2)
+#define PHY_SELECT_CS0			(2)
+#define PHY_SELECT_CS1			(1)
+#define PHY_SELECT_CS0_1		(0)
+#define PHY_WRITE_LEVELING_SELECTCS(n)	((n) << 6)
+#define PHY_DATA_TRAINING_SELECTCS(n)	((n) << 4)
+
+struct ddr_phy_skew {
+	u32 a0_a1_skew[15];
+	u32 cs0_dm0_skew[11];
+	u32 cs0_dm1_skew[11];
+	u32 cs0_dm2_skew[11];
+	u32 cs0_dm3_skew[11];
+	u32 cs1_dm0_skew[11];
+	u32 cs1_dm1_skew[11];
+	u32 cs1_dm2_skew[11];
+	u32 cs1_dm3_skew[11];
+};
+
+#define SR_IDLE				93
+#define PD_IDLE				13
+
+/* PMUGRF */
+#define PMUGRF_OS_REG0			(0x200)
+#define PMUGRF_OS_REG(n)		(PMUGRF_OS_REG0 + (n) * 4)
+
+/* DDR GRF */
+#define DDR_GRF_CON(n)			(0 + (n) * 4)
+#define DDR_GRF_STATUS_BASE		(0X100)
+#define DDR_GRF_STATUS(n)		(DDR_GRF_STATUS_BASE + (n) * 4)
+#define DDR_GRF_LP_CON			(0x20)
+
+#define SPLIT_MODE_32_L16_VALID		(0)
+#define SPLIT_MODE_32_H16_VALID		(1)
+#define SPLIT_MODE_16_L8_VALID		(2)
+#define SPLIT_MODE_16_H8_VALID		(3)
+
+#define DDR_GRF_SPLIT_CON		(0x8)
+#define SPLIT_MODE_MASK			(0x3)
+#define SPLIT_MODE_OFFSET		(9)
+#define SPLIT_BYPASS_MASK		(1)
+#define SPLIT_BYPASS_OFFSET		(8)
+#define SPLIT_SIZE_MASK			(0xff)
+#define SPLIT_SIZE_OFFSET		(0)
+
+/* CRU define */
+/* CRU_PLL_CON0 */
+#define PB(n)				((0x1 << (15 + 16)) | ((n) << 15))
+#define POSTDIV1(n)			((0x7 << (12 + 16)) | ((n) << 12))
+#define FBDIV(n)			((0xFFF << 16) | (n))
+
+/* CRU_PLL_CON1 */
+#define RSTMODE(n)			((0x1 << (15 + 16)) | ((n) << 15))
+#define RST(n)				((0x1 << (14 + 16)) | ((n) << 14))
+#define PD(n)				((0x1 << (13 + 16)) | ((n) << 13))
+#define DSMPD(n)			((0x1 << (12 + 16)) | ((n) << 12))
+#define LOCK(n)				(((n) >> 10) & 0x1)
+#define POSTDIV2(n)			((0x7 << (6 + 16)) | ((n) << 6))
+#define REFDIV(n)			((0x3F << 16) | (n))
+
+/* CRU_MODE */
+#define CLOCK_FROM_XIN_OSC		(0)
+#define CLOCK_FROM_PLL			(1)
+#define CLOCK_FROM_RTC_32K		(2)
+#define DPLL_MODE(n)			((0x3 << (4 + 16)) | ((n) << 4))
+
+/* CRU_SOFTRESET_CON1 */
+#define upctl2_psrstn_req(n)		(((0x1 << 6) << 16) | ((n) << 6))
+#define upctl2_asrstn_req(n)		(((0x1 << 5) << 16) | ((n) << 5))
+#define upctl2_srstn_req(n)		(((0x1 << 4) << 16) | ((n) << 4))
+
+/* CRU_SOFTRESET_CON2 */
+#define ddrphy_psrstn_req(n)		(((0x1 << 2) << 16) | ((n) << 2))
+#define ddrphy_srstn_req(n)		(((0x1 << 0) << 16) | ((n) << 0))
+
+/* CRU register */
+#define CRU_PLL_CON(pll_id, n)		((pll_id)  * 0x20 + (n) * 4)
+#define CRU_MODE			(0xa0)
+#define CRU_GLB_CNT_TH			(0xb0)
+#define CRU_CLKSEL_CON_BASE		0x100
+#define CRU_CLKSELS_CON(i)		(CRU_CLKSEL_CON_BASE + ((i) * 4))
+#define CRU_CLKGATE_CON_BASE		0x200
+#define CRU_CLKGATE_CON(i)		(CRU_CLKGATE_CON_BASE + ((i) * 4))
+#define CRU_CLKSFTRST_CON_BASE		0x300
+#define CRU_CLKSFTRST_CON(i)		(CRU_CLKSFTRST_CON_BASE + ((i) * 4))
+
+struct px30_ddr_grf_regs {
+	u32 ddr_grf_con[4];
+	u32 reserved1[(0x20 - 0x10) / 4];
+	u32 ddr_grf_lp_con;
+	u32 reserved2[(0x100 - 0x24) / 4];
+	u32 ddr_grf_status[11];
+};
+
+struct px30_msch_timings {
+	u32 ddrtiminga0;
+	u32 ddrtimingb0;
+	u32 ddrtimingc0;
+	u32 devtodev0;
+	u32 ddrmode;
+	u32 ddr4timing;
+	u32 agingx0;
+};
+
+struct px30_sdram_channel {
+	unsigned int rank;
+	unsigned int col;
+	/* 3:8bank, 2:4bank */
+	unsigned int bk;
+	/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
+	unsigned int bw;
+	/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
+	unsigned int dbw;
+	unsigned int row_3_4;
+	unsigned int cs0_row;
+	unsigned int cs1_row;
+	unsigned int cs0_high16bit_row;
+	unsigned int cs1_high16bit_row;
+	unsigned int ddrconfig;
+	struct px30_msch_timings noc_timings;
+};
+
+struct px30_base_params {
+	unsigned int ddr_freq;
+	unsigned int dramtype;
+	unsigned int num_channels;
+	unsigned int stride;
+	unsigned int odt;
+};
+
+struct px30_sdram_params {
+	struct px30_sdram_channel ch;
+	struct px30_base_params base;
+	struct ddr_pctl_regs pctl_regs;
+	struct ddr_phy_regs phy_regs;
+	struct ddr_phy_skew *skew;
+};
+
+struct px30_msch_regs {
+	u32 coreid;
+	u32 revisionid;
+	u32 deviceconf;
+	u32 devicesize;
+	u32 ddrtiminga0;
+	u32 ddrtimingb0;
+	u32 ddrtimingc0;
+	u32 devtodev0;
+	u32 reserved1[(0x110 - 0x20) / 4];
+	u32 ddrmode;
+	u32 ddr4timing;
+	u32 reserved2[(0x1000 - 0x118) / 4];
+	u32 agingx0;
+	u32 reserved3[(0x1040 - 0x1004) / 4];
+	u32 aging0;
+	u32 aging1;
+	u32 aging2;
+	u32 aging3;
+};
+
+int sdram_init(void);
+
+#endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index f5a80b4f0c..116b40a3c5 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -1,5 +1,27 @@
 if ARCH_ROCKCHIP
 
+config ROCKCHIP_PX30
+	bool "Support Rockchip PX30"
+	select ARM64
+	select SUPPORT_SPL
+	select SUPPORT_TPL
+	select SPL
+	select TPL
+	select TPL_TINY_FRAMEWORK if TPL
+	select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
+	select TPL_NEEDS_SEPARATE_STACK if TPL
+	imply SPL_SEPARATE_BSS
+	select SPL_SERIAL_SUPPORT
+	select TPL_SERIAL_SUPPORT
+	select DEBUG_UART_BOARD_INIT
+	imply ROCKCHIP_COMMON_BOARD
+	imply SPL_ROCKCHIP_COMMON_BOARD
+	help
+	  The Rockchip PX30 is a ARM-based SoC with a quad-core Cortex-A35
+	  including NEON and GPU, Mali-400 graphics, several DDR3 options
+	  and video codec support. Peripherals include Gigabit Ethernet,
+	  USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
+
 config ROCKCHIP_RK3036
 	bool "Support Rockchip RK3036"
 	select CPU_V7A
@@ -315,6 +337,7 @@ config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
 config SPL_MMC_SUPPORT
 	default y if !SPL_ROCKCHIP_BACK_TO_BROM
 
+source "arch/arm/mach-rockchip/px30/Kconfig"
 source "arch/arm/mach-rockchip/rk3036/Kconfig"
 source "arch/arm/mach-rockchip/rk3128/Kconfig"
 source "arch/arm/mach-rockchip/rk3188/Kconfig"
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index 45d9b06233..ddff566dee 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -11,6 +11,7 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
 obj-spl-$(CONFIG_SPL_ROCKCHIP_COMMON_BOARD) += spl.o spl-boot-order.o
 obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
 obj-tpl-$(CONFIG_TPL_ROCKCHIP_COMMON_BOARD) += tpl.o
+obj-tpl-$(CONFIG_ROCKCHIP_PX30) += px30-board-tpl.o
 
 obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
 
@@ -27,6 +28,7 @@ endif
 
 obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
 
+obj-$(CONFIG_ROCKCHIP_PX30) += px30/
 obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
 obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
 obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
diff --git a/arch/arm/mach-rockchip/px30-board-tpl.c b/arch/arm/mach-rockchip/px30-board-tpl.c
new file mode 100644
index 0000000000..8c8976f61c
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30-board-tpl.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <ram.h>
+#include <spl.h>
+#include <version.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/sdram_px30.h>
+
+#define TIMER_LOAD_COUNT0	0x00
+#define TIMER_LOAD_COUNT1	0x04
+#define TIMER_CUR_VALUE0	0x08
+#define TIMER_CUR_VALUE1	0x0c
+#define TIMER_CONTROL_REG	0x10
+
+#define TIMER_EN	0x1
+#define	TIMER_FMODE	(0 << 1)
+#define	TIMER_RMODE	(1 << 1)
+
+void secure_timer_init(void)
+{
+	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT0);
+	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT1);
+	writel(TIMER_EN | TIMER_FMODE,
+	       CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+}
+
+void board_init_f(ulong dummy)
+{
+	int ret;
+
+#ifdef CONFIG_DEBUG_UART
+	debug_uart_init();
+	/*
+	 * Debug UART can be used from here if required:
+	 *
+	 * debug_uart_init();
+	 * printch('a');
+	 * printhex8(0x1234);
+	 * printascii("string");
+	 */
+	printascii("U-Boot TPL board init\n");
+#endif
+
+	secure_timer_init();
+	ret = sdram_init();
+	if (ret)
+		printascii("sdram_init failed\n");
+
+	/* return to maskrom */
+	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+}
diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig
new file mode 100644
index 0000000000..ef04afca8d
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/Kconfig
@@ -0,0 +1,48 @@
+if ROCKCHIP_PX30
+
+config TARGET_EVB_PX30
+	bool "EVB_PX30"
+
+config ROCKCHIP_BOOT_MODE_REG
+	default 0xff010200
+
+config SYS_SOC
+	default "px30"
+
+config SYS_MALLOC_F_LEN
+	default 0x400
+
+config SPL_SERIAL_SUPPORT
+	default y
+
+config TPL_LDSCRIPT
+	default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
+
+config TPL_TEXT_BASE
+	default 0xff0e1000
+
+config TPL_MAX_SIZE
+	default 10240
+
+config TPL_STACK
+	default 0xff0e4fff
+
+config ROCKCHIP_RK3326
+	bool "Support Rockchip RK3326 "
+	help
+	  RK3326 can use most code from PX30, but@some situations we have
+	  to distinguish between RK3326 and PX30, so this macro gives help.
+	  It is usually selected in rk3326 board defconfig.
+
+config DEBUG_UART2_CHANNEL
+	int "Mux channel to use for debug UART2"
+	depends on DEBUG_UART_BOARD_INIT
+	default 0
+	help
+	  UART2 can use two different set of pins to route the output.
+	  For using the UART for early debugging the route to use needs
+	  to be declared (0 or 1).
+
+source "board/rockchip/evb_px30/Kconfig"
+
+endif
diff --git a/arch/arm/mach-rockchip/px30/Makefile b/arch/arm/mach-rockchip/px30/Makefile
new file mode 100644
index 0000000000..6d0742bcab
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/Makefile
@@ -0,0 +1,14 @@
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += clk_px30.o
+
+ifndef CONFIG_TPL_BUILD
+obj-y += syscon_px30.o
+endif
+
+obj-y += px30.o
+obj-y += sdram_px30.o
diff --git a/arch/arm/mach-rockchip/px30/clk_px30.c b/arch/arm/mach-rockchip/px30/clk_px30.c
new file mode 100644
index 0000000000..0bd6b471da
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/clk_px30.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+	return uclass_get_device_by_driver(UCLASS_CLK,
+			DM_GET_DRIVER(rockchip_px30_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+	struct px30_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/px30/px30.c b/arch/arm/mach-rockchip/px30/px30.c
new file mode 100644
index 0000000000..7cd2292fe2
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/px30.c
@@ -0,0 +1,248 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/grf_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/uart.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+#include <dt-bindings/clock/px30-cru.h>
+
+static struct mm_region px30_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0xff000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		.virt = 0xff000000UL,
+		.phys = 0xff000000UL,
+		.size = 0x01000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = px30_mem_map;
+
+#define PMU_PWRDN_CON			0xff000018
+#define GRF_BASE			0xff140000
+#define CRU_BASE			0xff2b0000
+#define VIDEO_PHY_BASE			0xff2e0000
+#define SERVICE_CORE_ADDR		0xff508000
+#define DDR_FW_BASE			0xff534000
+
+#define FW_DDR_CON			0x40
+
+#define QOS_PRIORITY			0x08
+
+#define QOS_PRIORITY_LEVEL(h, l)	((((h) & 3) << 8) | ((l) & 3))
+
+/* GRF_GPIO1CL_IOMUX */
+enum {
+	GPIO1C1_SHIFT		= 4,
+	GPIO1C1_MASK		= 0xf << GPIO1C1_SHIFT,
+	GPIO1C1_GPIO		= 0,
+	GPIO1C1_UART1_TX,
+
+	GPIO1C0_SHIFT		= 0,
+	GPIO1C0_MASK		= 0xf << GPIO1C0_SHIFT,
+	GPIO1C0_GPIO		= 0,
+	GPIO1C0_UART1_RX,
+};
+
+/* GRF_GPIO1DL_IOMUX */
+enum {
+	GPIO1D3_SHIFT		= 12,
+	GPIO1D3_MASK		= 0xf << GPIO1D3_SHIFT,
+	GPIO1D3_GPIO		= 0,
+	GPIO1D3_SDMMC_D1,
+	GPIO1D3_UART2_RXM0,
+
+	GPIO1D2_SHIFT		= 8,
+	GPIO1D2_MASK		= 0xf << GPIO1D2_SHIFT,
+	GPIO1D2_GPIO		= 0,
+	GPIO1D2_SDMMC_D0,
+	GPIO1D2_UART2_TXM0,
+};
+
+/* GRF_GPIO1DH_IOMUX */
+enum {
+	GPIO1D7_SHIFT		= 12,
+	GPIO1D7_MASK		= 0xf << GPIO1D7_SHIFT,
+	GPIO1D7_GPIO		= 0,
+	GPIO1D7_SDMMC_CMD,
+
+	GPIO1D6_SHIFT		= 8,
+	GPIO1D6_MASK		= 0xf << GPIO1D6_SHIFT,
+	GPIO1D6_GPIO		= 0,
+	GPIO1D6_SDMMC_CLK,
+
+	GPIO1D5_SHIFT		= 4,
+	GPIO1D5_MASK		= 0xf << GPIO1D5_SHIFT,
+	GPIO1D5_GPIO		= 0,
+	GPIO1D5_SDMMC_D3,
+
+	GPIO1D4_SHIFT		= 0,
+	GPIO1D4_MASK		= 0xf << GPIO1D4_SHIFT,
+	GPIO1D4_GPIO		= 0,
+	GPIO1D4_SDMMC_D2,
+};
+
+/* GRF_GPIO2BH_IOMUX */
+enum {
+	GPIO2B6_SHIFT		= 8,
+	GPIO2B6_MASK		= 0xf << GPIO2B6_SHIFT,
+	GPIO2B6_GPIO		= 0,
+	GPIO2B6_CIF_D1M0,
+	GPIO2B6_UART2_RXM1,
+
+	GPIO2B4_SHIFT		= 0,
+	GPIO2B4_MASK		= 0xf << GPIO2B4_SHIFT,
+	GPIO2B4_GPIO		= 0,
+	GPIO2B4_CIF_D0M0,
+	GPIO2B4_UART2_TXM1,
+};
+
+/* GRF_GPIO3AL_IOMUX */
+enum {
+	GPIO3A2_SHIFT		= 8,
+	GPIO3A2_MASK		= 0xf << GPIO3A2_SHIFT,
+	GPIO3A2_GPIO		= 0,
+	GPIO3A2_UART5_TX	= 4,
+
+	GPIO3A1_SHIFT		= 4,
+	GPIO3A1_MASK		= 0xf << GPIO3A1_SHIFT,
+	GPIO3A1_GPIO		= 0,
+	GPIO3A1_UART5_RX	= 4,
+};
+
+int arch_cpu_init(void)
+{
+	static struct px30_grf * const grf = (void *)GRF_BASE;
+	u32 __maybe_unused val;
+
+#ifdef CONFIG_SPL_BUILD
+	/* We do some SoC one time setting here. */
+	/* Disable the ddr secure region setting to make it non-secure */
+	writel(0x0, DDR_FW_BASE + FW_DDR_CON);
+
+	/* Set cpu qos priority */
+	writel(QOS_PRIORITY_LEVEL(1, 1), SERVICE_CORE_ADDR + QOS_PRIORITY);
+
+#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) || \
+    (CONFIG_DEBUG_UART_BASE != 0xff160000) || \
+    (CONFIG_DEBUG_UART_CHANNEL != 0)
+	/* fix sdmmc pinmux if not using uart2-channel0 as debug uart */
+	rk_clrsetreg(&grf->gpio1dl_iomux,
+		     GPIO1D3_MASK | GPIO1D2_MASK,
+		     GPIO1D3_SDMMC_D1 << GPIO1D3_SHIFT |
+		     GPIO1D2_SDMMC_D0 << GPIO1D2_SHIFT);
+	rk_clrsetreg(&grf->gpio1dh_iomux,
+		     GPIO1D7_MASK | GPIO1D6_MASK | GPIO1D5_MASK | GPIO1D4_MASK,
+		     GPIO1D7_SDMMC_CMD << GPIO1D7_SHIFT |
+		     GPIO1D6_SDMMC_CLK << GPIO1D6_SHIFT |
+		     GPIO1D5_SDMMC_D3 << GPIO1D5_SHIFT |
+		     GPIO1D4_SDMMC_D2 << GPIO1D4_SHIFT);
+#endif
+
+#endif
+
+	/* Enable PD_VO (default disable@reset) */
+	rk_clrreg(PMU_PWRDN_CON, 1 << 13);
+
+	/* Disable video phy bandgap by default */
+	writel(0x82, VIDEO_PHY_BASE + 0x0000);
+	writel(0x05, VIDEO_PHY_BASE + 0x03ac);
+
+	/* Clear the force_jtag */
+	rk_clrreg(&grf->cpu_con[1], 1 << 7);
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+	static struct px30_grf * const grf = (void *)GRF_BASE;
+	static struct px30_cru * const cru = (void *)CRU_BASE;
+
+#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff158000)
+	/* uart_sel_clk default select 24MHz */
+	rk_clrsetreg(&cru->clksel_con[34],
+		     UART1_PLL_SEL_MASK | UART1_DIV_CON_MASK,
+		     UART1_PLL_SEL_24M << UART1_PLL_SEL_SHIFT | 0);
+	rk_clrsetreg(&cru->clksel_con[35],
+		     UART1_CLK_SEL_MASK,
+		     UART1_CLK_SEL_UART1 << UART1_CLK_SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio1cl_iomux,
+		     GPIO1C1_MASK | GPIO1C0_MASK,
+		     GPIO1C1_UART1_TX << GPIO1C1_SHIFT |
+		     GPIO1C0_UART1_RX << GPIO1C0_SHIFT);
+#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff178000)
+	/* uart_sel_clk default select 24MHz */
+	rk_clrsetreg(&cru->clksel_con[46],
+		     UART5_PLL_SEL_MASK | UART5_DIV_CON_MASK,
+		     UART5_PLL_SEL_24M << UART5_PLL_SEL_SHIFT | 0);
+	rk_clrsetreg(&cru->clksel_con[47],
+		     UART5_CLK_SEL_MASK,
+		     UART5_CLK_SEL_UART5 << UART5_CLK_SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio3al_iomux,
+		     GPIO3A2_MASK | GPIO3A1_MASK,
+		     GPIO3A2_UART5_TX << GPIO3A2_SHIFT |
+		     GPIO3A1_UART5_RX << GPIO3A1_SHIFT);
+#else
+	/* GRF_IOFUNC_CON0 */
+	enum {
+		CON_IOMUX_UART2SEL_SHIFT	= 10,
+		CON_IOMUX_UART2SEL_MASK = 3 << CON_IOMUX_UART2SEL_SHIFT,
+		CON_IOMUX_UART2SEL_M0	= 0,
+		CON_IOMUX_UART2SEL_M1,
+		CON_IOMUX_UART2SEL_USBPHY,
+	};
+
+	/* uart_sel_clk default select 24MHz */
+	rk_clrsetreg(&cru->clksel_con[37],
+		     UART2_PLL_SEL_MASK | UART2_DIV_CON_MASK,
+		     UART2_PLL_SEL_24M << UART2_PLL_SEL_SHIFT | 0);
+	rk_clrsetreg(&cru->clksel_con[38],
+		     UART2_CLK_SEL_MASK,
+		     UART2_CLK_SEL_UART2 << UART2_CLK_SEL_SHIFT);
+
+#if (CONFIG_DEBUG_UART2_CHANNEL == 1)
+	/* Enable early UART2 */
+	rk_clrsetreg(&grf->iofunc_con0,
+		     CON_IOMUX_UART2SEL_MASK,
+		     CON_IOMUX_UART2SEL_M1 << CON_IOMUX_UART2SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio2bh_iomux,
+		     GPIO2B6_MASK | GPIO2B4_MASK,
+		     GPIO2B6_UART2_RXM1 << GPIO2B6_SHIFT |
+		     GPIO2B4_UART2_TXM1 << GPIO2B4_SHIFT);
+#else
+	rk_clrsetreg(&grf->iofunc_con0,
+		     CON_IOMUX_UART2SEL_MASK,
+		     CON_IOMUX_UART2SEL_M0 << CON_IOMUX_UART2SEL_SHIFT);
+
+	rk_clrsetreg(&grf->gpio1dl_iomux,
+		     GPIO1D3_MASK | GPIO1D2_MASK,
+		     GPIO1D3_UART2_RXM0 << GPIO1D3_SHIFT |
+		     GPIO1D2_UART2_TXM0 << GPIO1D2_SHIFT);
+#endif /* CONFIG_DEBUG_UART2_CHANNEL == 1 */
+
+#endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */
+}
+#endif /* CONFIG_DEBUG_UART_BOARD_INIT */
diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
new file mode 100644
index 0000000000..e17b2ed86c
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
@@ -0,0 +1,70 @@
+{
+	{
+		.rank = 0x1,
+		.col = 0xC,
+		.bk = 0x3,
+		.bw = 0x1,
+		.dbw = 0x0,
+		.row_3_4 = 0x0,
+		.cs0_row = 0x10,
+		.cs1_row = 0x10,
+		.cs0_high16bit_row = 0x10,
+		.cs1_high16bit_row = 0x10,
+		.ddrconfig = 0,
+		{
+			0x290b0609,
+			0x08020401,
+			0x00000002,
+			0x00001111,
+			0x0000000c,
+			0x00000222,
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = DDR3,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x43041001},	/* MSTR */
+			{0x00000064, 0x0028003b},	/* RFSHTMG */
+			{0x000000d0, 0x00020053},	/* INIT0 */
+			{0x000000d4, 0x00020000},	/* INIT1 */
+			{0x000000d8, 0x00000100},	/* INIT2 */
+			{0x000000dc, 0x03200000},	/* INIT3 */
+			{0x000000e0, 0x00000000},	/* INIT4 */
+			{0x000000e4, 0x00090000},	/* INIT5 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x07090b06},	/* DRAMTMG0 */
+			{0x00000104, 0x00050209},	/* DRAMTMG1 */
+			{0x00000108, 0x03030407},	/* DRAMTMG2 */
+			{0x0000010c, 0x00202006},	/* DRAMTMG3 */
+			{0x00000110, 0x03020204},	/* DRAMTMG4 */
+			{0x00000114, 0x03030202},	/* DRAMTMG5 */
+			{0x00000120, 0x00000903},	/* DRAMTMG8 */
+			{0x00000180, 0x00800020},	/* ZQCTL0 */
+			{0x00000184, 0x00000000},	/* ZQCTL1 */
+			{0x00000190, 0x07010001},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x06000604},	/* ODTCFG */
+			{0x00000244, 0x00000201},	/* ODTMAP */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x0000000a},	/* PHYREG01 */
+			{0x00000028, 0x00000006},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000005},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
new file mode 100644
index 0000000000..cdc417405a
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
@@ -0,0 +1,73 @@
+{
+	{
+		.rank = 0x1,
+		.col = 0xA,
+		.bk = 0x2,
+		.bw = 0x1,
+		.dbw = 0x0,
+		.row_3_4 = 0x0,
+		.cs0_row = 0x11,
+		.cs1_row = 0x0,
+		.cs0_high16bit_row = 0x11,
+		.cs1_high16bit_row = 0x0,
+		.ddrconfig = 0,
+		{
+			0x4d110a08,
+			0x06020501,
+			0x00000002,
+			0x00001111,
+			0x0000000c,
+			0x0000022a,
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = DDR4,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x43049010},	/* MSTR */
+			{0x00000064, 0x0028003b},	/* RFSHTMG */
+			{0x000000d0, 0x00020053},	/* INIT0 */
+			{0x000000d4, 0x00220000},	/* INIT1 */
+			{0x000000d8, 0x00000100},	/* INIT2 */
+			{0x000000dc, 0x00040000},	/* INIT3 */
+			{0x000000e0, 0x00000000},	/* INIT4 */
+			{0x000000e4, 0x00110000},	/* INIT5 */
+			{0x000000e8, 0x00000420},	/* INIT6 */
+			{0x000000ec, 0x00000400},	/* INIT7 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x09060b06},	/* DRAMTMG0 */
+			{0x00000104, 0x00020209},	/* DRAMTMG1 */
+			{0x00000108, 0x0505040a},	/* DRAMTMG2 */
+			{0x0000010c, 0x0040400c},	/* DRAMTMG3 */
+			{0x00000110, 0x05030206},	/* DRAMTMG4 */
+			{0x00000114, 0x03030202},	/* DRAMTMG5 */
+			{0x00000120, 0x03030b03},	/* DRAMTMG8 */
+			{0x00000124, 0x00020208},	/* DRAMTMG9 */
+			{0x00000180, 0x01000040},	/* ZQCTL0 */
+			{0x00000184, 0x00000000},	/* ZQCTL1 */
+			{0x00000190, 0x07030003},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x06000604},	/* ODTCFG */
+			{0x00000244, 0x00000201},	/* ODTMAP */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x0000000c},	/* PHYREG01 */
+			{0x00000028, 0x0000000a},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000009},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
\ No newline@end of file
diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
new file mode 100644
index 0000000000..f24343dda1
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
@@ -0,0 +1,121 @@
+		{
+			0x77,
+			0x88,
+			0x79,
+			0x79,
+			0x87,
+			0x97,
+			0x87,
+			0x78,
+			0x77,
+			0x78,
+			0x87,
+			0x88,
+			0x87,
+			0x87,
+			0x77
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x79,
+			0x9,
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x79,
+			0x9,
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x78,
+			0x77,
+			0x79,
+			0x9,
+		},
+		{
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x78,
+			0x69,
+			0x9,
+		},
+		{
+			0x77,
+			0x78,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x77,
+			0x79,
+			0x9,
+		}
diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
new file mode 100644
index 0000000000..3bde062d62
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
@@ -0,0 +1,71 @@
+{
+	{
+		.rank = 0x1,
+		.col = 0xC,
+		.bk = 0x3,
+		.bw = 0x1,
+		.dbw = 0x0,
+		.row_3_4 = 0x0,
+		.cs0_row = 0xF,
+		.cs1_row = 0xF,
+		.cs0_high16bit_row = 0xF,
+		.cs1_high16bit_row = 0xF,
+		.ddrconfig = 0,
+		{
+			0x2b0c070a,
+			0x08020303,
+			0x00000002,
+			0x00001111,
+			0x0000000c,
+			0x00000219,
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = LPDDR2,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x41041004},	/* MSTR */
+			{0x00000064, 0x00140023},	/* RFSHTMG */
+			{0x000000d0, 0x00220002},	/* INIT0 */
+			{0x000000d4, 0x00010000},	/* INIT1 */
+			{0x000000d8, 0x00000703},	/* INIT2 */
+			{0x000000dc, 0x00630005},	/* INIT3 */
+			{0x000000e0, 0x00010000},	/* INIT4 */
+			{0x000000e4, 0x00070003},	/* INIT5 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x07090b07},	/* DRAMTMG0 */
+			{0x00000104, 0x0002010b},	/* DRAMTMG1 */
+			{0x00000108, 0x02040506},	/* DRAMTMG2 */
+			{0x0000010c, 0x00303000},	/* DRAMTMG3 */
+			{0x00000110, 0x04010204},	/* DRAMTMG4 */
+			{0x00000114, 0x01010303},	/* DRAMTMG5 */
+			{0x00000118, 0x02020003},	/* DRAMTMG6 */
+			{0x00000120, 0x00000303},	/* DRAMTMG8 */
+			{0x00000138, 0x00000025},	/* DRAMTMG14 */
+			{0x00000180, 0x003c000f},	/* ZQCTL0 */
+			{0x00000184, 0x00900000},	/* ZQCTL1 */
+			{0x00000190, 0x07020001},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x07030718},	/* ODTCFG */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x00000009},	/* PHYREG01 */
+			{0x00000028, 0x00000007},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000004},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
new file mode 100644
index 0000000000..a205fc9332
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
@@ -0,0 +1,72 @@
+{
+	{
+		.rank = 0x1,
+		.col = 0xC,
+		.bk = 0x3,
+		.bw = 0x1,
+		.dbw = 0x0,
+		.row_3_4 = 0x0,
+		.cs0_row = 0x10,
+		.cs1_row = 0x10,
+		.cs0_high16bit_row = 0x10,
+		.cs1_high16bit_row = 0x10,
+		.ddrconfig = 0,
+		{
+			0x290a060a,
+			0x08020303,
+			0x00000002,
+			0x00001111,
+			0x0000000c,
+			0x0000021a,
+			0x000000ff
+		}
+	},
+	{
+		.ddr_freq = 333,
+		.dramtype = LPDDR3,
+		.num_channels = 1,
+		.stride = 0,
+		.odt = 0,
+	},
+	{
+		{
+			{0x00000000, 0x43041008},	/* MSTR */
+			{0x00000064, 0x00140023},	/* RFSHTMG */
+			{0x000000d0, 0x00220002},	/* INIT0 */
+			{0x000000d4, 0x00010000},	/* INIT1 */
+			{0x000000d8, 0x00000703},	/* INIT2 */
+			{0x000000dc, 0x00830004},	/* INIT3 */
+			{0x000000e0, 0x00010000},	/* INIT4 */
+			{0x000000e4, 0x00070003},	/* INIT5 */
+			{0x000000f4, 0x000f012f},	/* RANKCTL */
+			{0x00000100, 0x06090b07},	/* DRAMTMG0 */
+			{0x00000104, 0x0002020b},	/* DRAMTMG1 */
+			{0x00000108, 0x02030506},	/* DRAMTMG2 */
+			{0x0000010c, 0x00505000},	/* DRAMTMG3 */
+			{0x00000110, 0x03020204},	/* DRAMTMG4 */
+			{0x00000114, 0x01010303},	/* DRAMTMG5 */
+			{0x00000118, 0x02020003},	/* DRAMTMG6 */
+			{0x00000120, 0x00000303},	/* DRAMTMG8 */
+			{0x00000138, 0x00000025},	/* DRAMTMG14 */
+			{0x00000180, 0x003c000f},	/* ZQCTL0 */
+			{0x00000184, 0x00900000},	/* ZQCTL1 */
+			{0x00000190, 0x07020000},	/* DFITMG0 */
+			{0x00000198, 0x07000101},	/* DFILPCFG0 */
+			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
+			{0x00000240, 0x0900090c},	/* ODTCFG */
+			{0x00000244, 0x00000101},	/* ODTMAP */
+			{0x00000250, 0x00001f00},	/* SCHED */
+			{0x00000490, 0x00000001},	/* PCTRL_0 */
+			{0xffffffff, 0xffffffff}
+		}
+	},
+	{
+		{
+			{0x00000004, 0x0000000b},	/* PHYREG01 */
+			{0x00000028, 0x00000006},	/* PHYREG0A */
+			{0x0000002c, 0x00000000},	/* PHYREG0B */
+			{0x00000030, 0x00000003},	/* PHYREG0C */
+			{0xffffffff, 0xffffffff}
+		}
+	}
+},
diff --git a/arch/arm/mach-rockchip/px30/sdram_px30.c b/arch/arm/mach-rockchip/px30/sdram_px30.c
new file mode 100644
index 0000000000..2590d9366e
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/sdram_px30.c
@@ -0,0 +1,1405 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_px30.h>
+#include <asm/arch-rockchip/grf_px30.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram_common.h>
+#include <asm/arch-rockchip/sdram_px30.h>
+
+#define TIMER_CUR_VALUE0	0x08
+#define TIMER_CUR_VALUE1	0x0c
+
+static u64 rockchip_get_ticks(void)
+{
+	u64 timebase_h, timebase_l;
+
+	timebase_l = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CUR_VALUE0);
+	timebase_h = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CUR_VALUE1);
+
+	return timebase_h << 32 | timebase_l;
+}
+
+void rockchip_udelay(unsigned int usec)
+{
+	u64 tmp;
+
+	/* get timestamp */
+	tmp = rockchip_get_ticks() + usec_to_tick(usec);
+
+	/* loop till event */
+	while (rockchip_get_ticks() < tmp + 1)
+		;
+}
+
+u8 ddr_cfg_2_rbc[] = {
+	/*
+	 * [6:4] max row: 13+n
+	 * [3]  bank(0:4bank,1:8bank)
+	 * [2:0]    col(10+n)
+	 */
+	((5 << 4) | (1 << 3) | 0), /* 0 */
+	((5 << 4) | (1 << 3) | 1), /* 1 */
+	((4 << 4) | (1 << 3) | 2), /* 2 */
+	((3 << 4) | (1 << 3) | 3), /* 3 */
+	((2 << 4) | (1 << 3) | 4), /* 4 */
+	((5 << 4) | (0 << 3) | 2), /* 5 */
+	((4 << 4) | (1 << 3) | 2), /* 6 */
+};
+
+#ifdef CONFIG_TPL_BUILD
+
+/*
+ * for ddr4 if ddrconfig=7, upctl should set 7 and noc should
+ * set to 1 for more efficient.
+ * noc ddrconf, upctl addrmap
+ * 1  7
+ * 2  8
+ * 3  9
+ * 12 10
+ * 5  11
+ */
+static u8 d4_rbc_2_d3_rbc[] = {
+	1, /* 7 */
+	2, /* 8 */
+	3, /* 9 */
+	12, /* 10 */
+	5, /* 11 */
+};
+
+/*
+ * row higher than cs should be disabled by set to 0xf
+ * rank addrmap calculate by real cap.
+ */
+static u32 addrmap[][8] = {
+	/* map0 map1,   map2,       map3,       map4,      map5
+	 * map6,        map7,       map8
+	 * -------------------------------------------------------
+	 * bk2-0       col 5-2     col 9-6    col 11-10   row 11-0
+	 * row 15-12   row 17-16   bg1,0
+	 * -------------------------------------------------------
+	 * 4,3,2       5-2         9-6                    6
+	 *                         3,2
+	 */
+	{0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
+		0x05050505, 0x00000505, 0x3f3f}, /* 0 */
+	{0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x06060606, 0x3f3f}, /* 1 */
+	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x3f3f}, /* 2 */
+	{0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
+		0x08080808, 0x00000f0f, 0x3f3f}, /* 3 */
+	{0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
+		0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
+	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x3f3f}, /* 5 */
+	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f0f, 0x3f3f}, /* 6 */
+	{0x003f0808, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x0600}, /* 7 */
+	{0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x0700}, /* 8 */
+	{0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
+		0x08080808, 0x00000f0f, 0x0801}, /* 9 */
+	{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x3f01}, /* 10 */
+	{0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x3f00}, /* 11 */
+	/* when ddr4 12 map to 10, when ddr3 12 unused */
+	{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
+		0x07070707, 0x00000f07, 0x3f01}, /* 10 */
+	{0x00070706, 0x00000000, 0x1f010000, 0x00001f1f, 0x06060606,
+		0x06060606, 0x00000606, 0x3f3f}, /* 13 */
+};
+
+DECLARE_GLOBAL_DATA_PTR;
+struct dram_info {
+	struct ddr_pctl_regs *pctl;
+	struct ddr_phy_regs *phy;
+	struct px30_cru *cru;
+	struct px30_msch_regs *msch;
+	struct px30_ddr_grf_regs *ddr_grf;
+	struct px30_grf *grf;
+	struct ram_info info;
+	struct px30_pmugrf *pmugrf;
+};
+
+#define PMUGRF_BASE_ADDR		0xFF010000
+#define CRU_BASE_ADDR			0xFF2B0000
+#define GRF_BASE_ADDR			0xFF140000
+#define DDRC_BASE_ADDR			0xFF600000
+#define DDR_PHY_BASE_ADDR		0xFF2A0000
+#define SERVER_MSCH0_BASE_ADDR		0xFF530000
+#define DDR_GRF_BASE_ADDR		0xff630000
+
+struct dram_info dram_info;
+
+struct px30_sdram_params sdram_configs[] = {
+#include	"sdram-px30-ddr3-detect-333.inc"
+};
+
+struct ddr_phy_skew skew = {
+#include	"sdram-px30-ddr_skew.inc"
+};
+
+#define PATTERN				(0x5aa5f00f)
+
+/*
+ * cs: 0:cs0
+ *	   1:cs1
+ *     else cs0+cs1
+ * note: it didn't consider about row_3_4
+ */
+u64 sdram_get_cs_cap(struct px30_sdram_channel *cap_info, u32 cs, u32 dram_type)
+{
+	u32 bg;
+	u64 cap[2];
+
+	if (dram_type == DDR4)
+		/* DDR4 8bit dram BG = 2(4bank groups),
+		 * 16bit dram BG = 1 (2 bank groups)
+		 */
+		bg = (cap_info->dbw == 0) ? 2 : 1;
+	else
+		bg = 0;
+	cap[0] = 1llu << (cap_info->bw + cap_info->col +
+		bg + cap_info->bk + cap_info->cs0_row);
+
+	if (cap_info->rank == 2)
+		cap[1] = 1llu << (cap_info->bw + cap_info->col +
+			bg + cap_info->bk + cap_info->cs1_row);
+	else
+		cap[1] = 0;
+
+	if (cs == 0)
+		return cap[0];
+	else if (cs == 1)
+		return cap[1];
+	else
+		return (cap[0] + cap[1]);
+}
+
+/* n: Unit bytes */
+void sdram_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 sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
+{
+	u32 tmp;
+	u32 i, j;
+
+	setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
+	clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
+	for (i = 0; i < 4; i++) {
+		j = 0x26 + i * 0x10;
+		setbits_le32(PHY_REG(phy_base, j), 1 << 4);
+		clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
+	}
+
+	if (freq <= (400000000))
+		/* DLL bypass */
+		setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
+	else
+		clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
+
+	if (freq <= (801000000))
+		tmp = 2;
+	else
+		tmp = 1;
+
+	for (i = 0; i < 4; i++) {
+		j = 0x28 + i * 0x10;
+		writel(tmp, PHY_REG(phy_base, j));
+	}
+}
+
+static void sdram_phy_set_ds_odt(void __iomem *phy_base,
+				 u32 dram_type)
+{
+	u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
+	u32 i, j;
+
+	if (dram_type == DDR3) {
+		cmd_drv = PHY_DDR3_RON_RTT_34ohm;
+		clk_drv = PHY_DDR3_RON_RTT_45ohm;
+		dqs_drv = PHY_DDR3_RON_RTT_34ohm;
+		dqs_odt = PHY_DDR3_RON_RTT_225ohm;
+	} else {
+		cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
+		clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
+		dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
+		if (dram_type == LPDDR2)
+			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
+		else
+			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
+	}
+	/* DS */
+	writel(cmd_drv, PHY_REG(phy_base, 0x11));
+	clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
+	writel(clk_drv, PHY_REG(phy_base, 0x16));
+	writel(clk_drv, PHY_REG(phy_base, 0x18));
+
+	for (i = 0; i < 4; i++) {
+		j = 0x20 + i * 0x10;
+		writel(dqs_drv, PHY_REG(phy_base, j));
+		writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
+		/* ODT */
+		writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
+		writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
+	}
+}
+
+static void phy_soft_reset(void __iomem *phy_base)
+{
+	clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
+	udelay(1);
+	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
+	udelay(5);
+	setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
+	udelay(1);
+}
+
+static void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
+{
+	if (bw == 2) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
+		setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	} else if (bw == 1) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	} else if (bw == 0) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
+		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	}
+
+	phy_soft_reset(phy_base);
+}
+
+static int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
+{
+	u32 ret;
+	u32 odt_val;
+	u32 i, j;
+
+	odt_val = readl(PHY_REG(phy_base, 0x2e));
+
+	for (i = 0; i < 4; i++) {
+		j = 0x20 + i * 0x10;
+		writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
+		writel(0, PHY_REG(phy_base, j + 0xe));
+	}
+
+	if (dramtype == DDR4) {
+		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
+		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
+		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
+		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
+	}
+	/* choose training cs */
+	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
+	/* enable gate training */
+	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
+	udelay(50);
+	ret = readl(PHY_REG(phy_base, 0xff));
+	/* disable gate training */
+	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
+	clrbits_le32(PHY_REG(phy_base, 2), 0x30);
+
+	if (dramtype == DDR4) {
+		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
+		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
+		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
+		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
+	}
+
+	if (ret & 0x10) {
+		ret = -1;
+	} else {
+		ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
+		ret = (ret == 0) ? 0 : -1;
+	}
+
+	for (i = 0; i < 4; i++) {
+		j = 0x20 + i * 0x10;
+		writel(odt_val, PHY_REG(phy_base, j + 0x1));
+		writel(odt_val, PHY_REG(phy_base, j + 0xe));
+	}
+
+	return ret;
+}
+
+static void phy_cfg(void __iomem *phy_base,
+		    struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
+		    struct px30_base_params *base, u32 bw)
+{
+	u32 i;
+
+	sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
+	for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
+		writel(phy_regs->phy[i][1],
+		       phy_base + phy_regs->phy[i][0]);
+	}
+	if (bw == 2) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
+	} else if (bw == 1) {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
+		/* disable DQS2,DQS3 tx dll  for saving power */
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	} else {
+		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
+		/* disable DQS2,DQS3 tx dll  for saving power */
+		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
+		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
+	}
+	sdram_phy_set_ds_odt(phy_base, base->dramtype);
+
+	/* deskew */
+	setbits_le32(PHY_REG(phy_base, 2), 8);
+	sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
+			  &skew->a0_a1_skew[0], 15 * 4);
+	sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
+			  &skew->cs0_dm0_skew[0], 44 * 4);
+	sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
+			  &skew->cs1_dm0_skew[0], 44 * 4);
+}
+
+void sdram_org_config(struct px30_sdram_channel *info,
+		      struct px30_base_params *base,
+		      u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
+{
+	*p_os_reg2 |= base->dramtype << SYS_REG_DDRTYPE_SHIFT;
+	*p_os_reg2 |= (base->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
+	*p_os_reg2 |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel);
+	*p_os_reg2 |= 1 << SYS_REG_CHINFO_SHIFT(channel);
+	*p_os_reg2 |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel);
+	*p_os_reg2 |= (info->col - 9) << SYS_REG_COL_SHIFT(channel);
+	*p_os_reg2 |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel);
+	*p_os_reg2 |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel);
+	if (info->cs1_row >= 13)
+		*p_os_reg2 |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel);
+	*p_os_reg2 |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel);
+	*p_os_reg2 |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel);
+}
+
+void sdram_msch_config(struct px30_msch_regs *msch,
+		       struct px30_msch_timings *noc_timings,
+		       struct px30_sdram_channel *cap_info,
+		       struct px30_base_params *base)
+{
+	u64 cs_cap[2];
+
+	cs_cap[0] = sdram_get_cs_cap(cap_info, 0, base->dramtype);
+	cs_cap[1] = sdram_get_cs_cap(cap_info, 1, base->dramtype);
+	writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
+			(((cs_cap[0] >> 20) / 64) & 0xff),
+			&msch->devicesize);
+
+	writel(noc_timings->ddrtiminga0, &msch->ddrtiminga0);
+	writel(noc_timings->ddrtimingb0, &msch->ddrtimingb0);
+	writel(noc_timings->ddrtimingc0, &msch->ddrtimingc0);
+	writel(noc_timings->devtodev0, &msch->devtodev0);
+	writel(noc_timings->ddrmode, &msch->ddrmode);
+	writel(noc_timings->ddr4timing, &msch->ddr4timing);
+	writel(noc_timings->agingx0, &msch->agingx0);
+	writel(noc_timings->agingx0, &msch->aging0);
+	writel(noc_timings->agingx0, &msch->aging1);
+	writel(noc_timings->agingx0, &msch->aging2);
+	writel(noc_timings->agingx0, &msch->aging3);
+}
+
+int sdram_detect_bw(struct px30_sdram_channel *cap_info)
+{
+	return 0;
+}
+
+int sdram_detect_cs(struct px30_sdram_channel *cap_info)
+{
+	return 0;
+}
+
+int sdram_detect_col(struct px30_sdram_channel *cap_info,
+		     u32 coltmp)
+{
+	void __iomem *test_addr;
+	u32 col;
+	u32 bw = cap_info->bw;
+
+	for (col = coltmp; col >= 9; col -= 1) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+				(1ul << (col + bw - 1ul)));
+		writel(PATTERN, test_addr);
+		if ((readl(test_addr) == PATTERN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (col == 8) {
+		printascii("col error\n");
+		return -1;
+	}
+
+	cap_info->col = col;
+
+	return 0;
+}
+
+int sdram_detect_bank(struct px30_sdram_channel *cap_info,
+		      u32 coltmp, u32 bktmp)
+{
+	void __iomem *test_addr;
+	u32 bk;
+	u32 bw = cap_info->bw;
+
+	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+			(1ul << (coltmp + bktmp + bw - 1ul)));
+	writel(0, CONFIG_SYS_SDRAM_BASE);
+	writel(PATTERN, test_addr);
+	if ((readl(test_addr) == PATTERN) &&
+	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+		bk = 3;
+	else
+		bk = 2;
+
+	cap_info->bk = bk;
+
+	return 0;
+}
+
+/* detect bg for ddr4 */
+int sdram_detect_bg(struct px30_sdram_channel *cap_info,
+		    u32 coltmp)
+{
+	void __iomem *test_addr;
+	u32 dbw;
+	u32 bw = cap_info->bw;
+
+	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+			(1ul << (coltmp + bw + 1ul)));
+	writel(0, CONFIG_SYS_SDRAM_BASE);
+	writel(PATTERN, test_addr);
+	if ((readl(test_addr) == PATTERN) &&
+	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+		dbw = 0;
+	else
+		dbw = 1;
+
+	cap_info->dbw = dbw;
+
+	return 0;
+}
+
+/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
+int sdram_detect_dbw(struct px30_sdram_channel *cap_info, u32 dram_type)
+{
+	u32 row, col, bk, bw, cs_cap, cs;
+	u32 die_bw_0 = 0, die_bw_1 = 0;
+
+	if (dram_type == DDR3 || dram_type == LPDDR4) {
+		cap_info->dbw = 1;
+	} else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
+		row = cap_info->cs0_row;
+		col = cap_info->col;
+		bk = cap_info->bk;
+		cs = cap_info->rank;
+		bw = cap_info->bw;
+		cs_cap = (1 << (row + col + bk + bw - 20));
+		if (bw == 2) {
+			if (cs_cap <= 0x2000000) /* 256Mb */
+				die_bw_0 = (col < 9) ? 2 : 1;
+			else if (cs_cap <= 0x10000000) /* 2Gb */
+				die_bw_0 = (col < 10) ? 2 : 1;
+			else if (cs_cap <= 0x40000000) /* 8Gb */
+				die_bw_0 = (col < 11) ? 2 : 1;
+			else
+				die_bw_0 = (col < 12) ? 2 : 1;
+			if (cs > 1) {
+				row = cap_info->cs1_row;
+				cs_cap = (1 << (row + col + bk + bw - 20));
+				if (cs_cap <= 0x2000000) /* 256Mb */
+					die_bw_0 = (col < 9) ? 2 : 1;
+				else if (cs_cap <= 0x10000000) /* 2Gb */
+					die_bw_0 = (col < 10) ? 2 : 1;
+				else if (cs_cap <= 0x40000000) /* 8Gb */
+					die_bw_0 = (col < 11) ? 2 : 1;
+				else
+					die_bw_0 = (col < 12) ? 2 : 1;
+			}
+		} else {
+			die_bw_1 = 1;
+			die_bw_0 = 1;
+		}
+		cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
+	}
+
+	return 0;
+}
+
+int sdram_detect_row(struct px30_sdram_channel *cap_info,
+		     u32 coltmp, u32 bktmp, u32 rowtmp)
+{
+	u32 row;
+	u32 bw = cap_info->bw;
+	void __iomem *test_addr;
+
+	for (row = rowtmp; row > 12; row--) {
+		writel(0, CONFIG_SYS_SDRAM_BASE);
+		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+				(1ul << (row + bktmp + coltmp + bw - 1ul)));
+		writel(PATTERN, test_addr);
+		if ((readl(test_addr) == PATTERN) &&
+		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
+			break;
+	}
+	if (row == 12) {
+		printascii("row error");
+		return -1;
+	}
+
+	cap_info->cs0_row = row;
+
+	return 0;
+}
+
+int sdram_detect_row_3_4(struct px30_sdram_channel *cap_info,
+			 u32 coltmp, u32 bktmp)
+{
+	u32 row_3_4;
+	u32 bw = cap_info->bw;
+	u32 row = cap_info->cs0_row;
+	void __iomem *test_addr, *test_addr1;
+
+	test_addr = CONFIG_SYS_SDRAM_BASE;
+	test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
+
+	writel(0, test_addr);
+	writel(PATTERN, test_addr1);
+	if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
+		row_3_4 = 0;
+	else
+		row_3_4 = 1;
+
+	cap_info->row_3_4 = row_3_4;
+
+	return 0;
+}
+
+int sdram_detect_high_row(struct px30_sdram_channel *cap_info)
+{
+	cap_info->cs0_high16bit_row = cap_info->cs0_row;
+	cap_info->cs1_high16bit_row = cap_info->cs1_row;
+
+	return 0;
+}
+
+int sdram_detect_cs1_row(struct px30_sdram_channel *cap_info, u32 dram_type)
+{
+	void __iomem *test_addr;
+	u32 row = 0, bktmp, coltmp, bw;
+	ulong cs0_cap;
+	u32 byte_mask;
+
+	if (cap_info->rank == 2) {
+		cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
+
+		if (dram_type == DDR4) {
+			if (cap_info->dbw == 0)
+				bktmp = cap_info->bk + 2;
+			else
+				bktmp = cap_info->bk + 1;
+		} else {
+			bktmp = cap_info->bk;
+		}
+		bw = cap_info->bw;
+		coltmp = cap_info->col;
+
+		/*
+		 * because px30 support axi split,min bandwidth
+		 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
+		 * so we check low 16bit data when detect cs1 row.
+		 * if cs0 is 16bit/8bit, we check low 8bit data.
+		 */
+		if (bw == 2)
+			byte_mask = 0xFFFF;
+		else
+			byte_mask = 0xFF;
+
+		/* detect cs1 row */
+		for (row = cap_info->cs0_row; row > 12; row--) {
+			test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
+				    cs0_cap +
+				    (1ul << (row + bktmp + coltmp + bw - 1ul)));
+			writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
+			writel(PATTERN, test_addr);
+
+			if (((readl(test_addr) & byte_mask) ==
+			     (PATTERN & byte_mask)) &&
+			    ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
+			      byte_mask) == 0)) {
+				break;
+			}
+		}
+	}
+
+	cap_info->cs1_row = row;
+
+	return 0;
+}
+
+static void rkclk_ddr_reset(struct dram_info *dram,
+			    u32 ctl_srstn, u32 ctl_psrstn,
+			    u32 phy_srstn, u32 phy_psrstn)
+{
+	writel(upctl2_srstn_req(ctl_srstn) | upctl2_psrstn_req(ctl_psrstn) |
+	       upctl2_asrstn_req(ctl_srstn),
+	       &dram->cru->softrst_con[1]);
+	writel(ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn),
+	       &dram->cru->softrst_con[2]);
+}
+
+static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
+{
+	unsigned int refdiv, postdiv1, postdiv2, fbdiv;
+	int delay = 1000;
+	u32 mhz = hz / MHz;
+
+	refdiv = 1;
+	if (mhz <= 300) {
+		postdiv1 = 4;
+		postdiv2 = 2;
+	} else if (mhz <= 400) {
+		postdiv1 = 6;
+		postdiv2 = 1;
+	} else if (mhz <= 600) {
+		postdiv1 = 4;
+		postdiv2 = 1;
+	} else if (mhz <= 800) {
+		postdiv1 = 3;
+		postdiv2 = 1;
+	} else if (mhz <= 1600) {
+		postdiv1 = 2;
+		postdiv2 = 1;
+	} else {
+		postdiv1 = 1;
+		postdiv2 = 1;
+	}
+	fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
+
+	writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
+
+	writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
+	writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv),
+	       &dram->cru->pll[1].con1);
+
+	while (delay > 0) {
+		rockchip_udelay(1);
+		if (LOCK(readl(&dram->cru->pll[1].con1)))
+			break;
+		delay--;
+	}
+
+	writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
+}
+
+static void rkclk_configure_ddr(struct dram_info *dram,
+				struct px30_sdram_params *sdram_params)
+{
+	/* for inno ddr phy need 2*freq */
+	rkclk_set_dpll(dram,  sdram_params->base.ddr_freq * MHz * 2);
+}
+
+/* return ddrconfig value
+ *       (-1), find ddrconfig fail
+ *       other, the ddrconfig value
+ * only support cs0_row >= cs1_row
+ */
+static unsigned int calculate_ddrconfig(struct px30_sdram_params *sdram_params)
+{
+	struct px30_sdram_channel *cap_info = &sdram_params->ch;
+	u32 bw, die_bw, col, bank;
+	u32 i, tmp;
+	u32 ddrconf = -1;
+
+	bw = cap_info->bw;
+	die_bw = cap_info->dbw;
+	col = cap_info->col;
+	bank = cap_info->bk;
+
+	if (sdram_params->base.dramtype == DDR4) {
+		if (die_bw == 0)
+			ddrconf = 7 + bw;
+		else
+			ddrconf = 12 - bw;
+		ddrconf = d4_rbc_2_d3_rbc[ddrconf - 7];
+	} else {
+		tmp = ((bank - 2) << 3) | (col + bw - 10);
+		for (i = 0; i < 7; i++)
+			if ((ddr_cfg_2_rbc[i] & 0xf) == tmp) {
+				ddrconf = i;
+				break;
+			}
+		if (i > 6)
+			printascii("calculate ddrconfig error\n");
+	}
+
+	return ddrconf;
+}
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+static void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
+{
+	writel((rank << 4) | (1 << 0), pctl_base + DDR_PCTL2_MRCTRL0);
+	writel((mr_num << 8), pctl_base + DDR_PCTL2_MRCTRL1);
+	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
+	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
+		continue;
+	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+		continue;
+}
+
+/* rank = 1: cs0
+ * rank = 2: cs1
+ * rank = 3: cs0 & cs1
+ * note: be careful of keep mr original val
+ */
+static int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
+			 u32 dramtype)
+{
+	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+		continue;
+	if (dramtype == DDR3 || dramtype == DDR4) {
+		writel((mr_num << 12) | (rank << 4) | (0 << 0),
+		       pctl_base + DDR_PCTL2_MRCTRL0);
+		writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
+	} else {
+		writel((rank << 4) | (0 << 0),
+		       pctl_base + DDR_PCTL2_MRCTRL0);
+		writel((mr_num << 8) | (arg & 0xff),
+		       pctl_base + DDR_PCTL2_MRCTRL1);
+	}
+
+	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
+	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
+		continue;
+	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
+		continue;
+
+	return 0;
+}
+
+static int upctl2_update_ref_reg(void __iomem *pctl_base)
+{
+	u32 ret;
+
+	ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
+	writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
+
+	return 0;
+}
+
+static u32 pctl_dis_zqcs_aref(void __iomem *pctl_base)
+{
+	u32 dis_auto_zq = 0;
+
+	/* disable zqcs */
+	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
+		(1ul << 31))) {
+		dis_auto_zq = 1;
+		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
+	}
+
+	/* disable auto refresh */
+	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
+
+	upctl2_update_ref_reg(pctl_base);
+
+	return dis_auto_zq;
+}
+
+static void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq)
+{
+	/* restore zqcs */
+	if (dis_auto_zq)
+		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
+
+	/* restore auto refresh */
+	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
+
+	upctl2_update_ref_reg(pctl_base);
+}
+
+/*
+ * rank : 1:cs0, 2:cs1, 3:cs0&cs1
+ * vrefrate: 4500: 45%,
+ */
+static int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
+			     u32 dramtype)
+{
+	u32 tccd_l, value;
+	u32 dis_auto_zq = 0;
+
+	if (dramtype != DDR4 || vrefrate < 4500 ||
+	    vrefrate > 9200)
+		return (-1);
+
+	tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
+	tccd_l = (tccd_l - 4) << 10;
+
+	if (vrefrate > 7500) {
+		/* range 1 */
+		value = ((vrefrate - 6000) / 65) | tccd_l;
+	} else {
+		/* range 2 */
+		value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
+	}
+
+	dis_auto_zq = pctl_dis_zqcs_aref(pctl_base);
+
+	/* enable vrefdq calibratin */
+	pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
+	udelay(1);/* tvrefdqe */
+	/* write vrefdq value */
+	pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
+	udelay(1);/* tvref_time */
+	pctl_write_mr(pctl_base, rank, 6, value | (0 << 7), dramtype);
+	udelay(1);/* tvrefdqx */
+
+	pctl_rest_zqcs_aref(pctl_base, dis_auto_zq);
+
+	return 0;
+}
+
+static u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
+				      struct px30_sdram_channel *cap_info,
+			       u32 dram_type)
+{
+	u32 tmp = 0, tmp_adr = 0, i;
+
+	for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
+		if (pctl_regs->pctl[i][0] == 0) {
+			tmp = pctl_regs->pctl[i][1];/* MSTR */
+			tmp_adr = i;
+		}
+	}
+
+	tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
+
+	switch (cap_info->dbw) {
+	case 2:
+		tmp |= (3ul << 30);
+		break;
+	case 1:
+		tmp |= (2ul << 30);
+		break;
+	case 0:
+	default:
+		tmp |= (1ul << 30);
+		break;
+	}
+
+	/*
+	 * If DDR3 or DDR4 MSTR.active_ranks=1,
+	 * it will gate memory clock when enter power down.
+	 * Force set active_ranks to 3 to workaround it.
+	 */
+	if (cap_info->rank == 2 || dram_type == DDR3 ||
+	    dram_type == DDR4)
+		tmp |= 3 << 24;
+	else
+		tmp |= 1 << 24;
+
+	tmp |= (2 - cap_info->bw) << 12;
+
+	pctl_regs->pctl[tmp_adr][1] = tmp;
+
+	return 0;
+}
+
+static int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
+		    u32 sr_idle, u32 pd_idle)
+{
+	u32 i;
+
+	for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
+		writel(pctl_regs->pctl[i][1],
+		       pctl_base + pctl_regs->pctl[i][0]);
+	}
+	clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
+			(0xff << 16) | 0x1f,
+			((sr_idle & 0xff) << 16) | (pd_idle & 0x1f));
+
+	clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
+			0xfff << 16,
+			5 << 16);
+	/* disable zqcs */
+	setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
+
+	return 0;
+}
+
+/*
+ * calculate controller dram address map, and setting to register.
+ * argument sdram_params->ch.ddrconf must be right value before
+ * call this function.
+ */
+static void set_ctl_address_map(struct dram_info *dram,
+				struct px30_sdram_params *sdram_params)
+{
+	struct px30_sdram_channel *cap_info = &sdram_params->ch;
+	void __iomem *pctl_base = dram->pctl;
+	u32 cs_pst, bg, max_row, ddrconf;
+	u32 i;
+
+	if (sdram_params->base.dramtype == DDR4)
+		/*
+		 * DDR4 8bit dram BG = 2(4bank groups),
+		 * 16bit dram BG = 1 (2 bank groups)
+		 */
+		bg = (cap_info->dbw == 0) ? 2 : 1;
+	else
+		bg = 0;
+
+	cs_pst = cap_info->bw + cap_info->col +
+		bg + cap_info->bk + cap_info->cs0_row;
+	if (cs_pst >= 32 || cap_info->rank == 1)
+		writel(0x1f, pctl_base + DDR_PCTL2_ADDRMAP0);
+	else
+		writel(cs_pst - 8, pctl_base + DDR_PCTL2_ADDRMAP0);
+
+	ddrconf = cap_info->ddrconfig;
+	if (sdram_params->base.dramtype == DDR4) {
+		for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc); i++) {
+			if (d4_rbc_2_d3_rbc[i] == ddrconf) {
+				ddrconf = 7 + i;
+				break;
+			}
+		}
+	}
+
+	sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP1),
+			  &addrmap[ddrconf][0], 8 * 4);
+	max_row = cs_pst - 1 - 8 - (addrmap[ddrconf][5] & 0xf);
+
+	if (max_row < 12)
+		printascii("set addrmap fail\n");
+	/* need to disable row ahead of rank by set to 0xf */
+	for (i = 17; i > max_row; i--)
+		clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
+			((i - 12) * 8 / 32) * 4,
+			0xf << ((i - 12) * 8 % 32),
+			0xf << ((i - 12) * 8 % 32));
+
+	if ((sdram_params->base.dramtype == LPDDR3 ||
+	     sdram_params->base.dramtype == LPDDR2) &&
+		 cap_info->row_3_4)
+		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
+	if (sdram_params->base.dramtype == DDR4 && cap_info->bw != 0x2)
+		setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
+}
+
+/*
+ * rank = 1: cs0
+ * rank = 2: cs1
+ */
+int read_mr(struct dram_info *dram, u32 rank, u32 mr_num)
+{
+	void __iomem *ddr_grf_base = dram->ddr_grf;
+
+	pctl_read_mr(dram->pctl, rank, mr_num);
+
+	return (readl(ddr_grf_base + DDR_GRF_STATUS(0)) & 0xff);
+}
+
+#define MIN(a, b)	(((a) > (b)) ? (b) : (a))
+#define MAX(a, b)	(((a) > (b)) ? (a) : (b))
+static u32 check_rd_gate(struct dram_info *dram)
+{
+	void __iomem *phy_base = dram->phy;
+
+	u32 max_val = 0;
+	u32 min_val = 0xff;
+	u32 gate[4];
+	u32 i, bw;
+
+	bw = (readl(PHY_REG(phy_base, 0x0)) >> 4) & 0xf;
+	switch (bw) {
+	case 0x1:
+		bw = 1;
+		break;
+	case 0x3:
+		bw = 2;
+		break;
+	case 0xf:
+	default:
+		bw = 4;
+		break;
+	}
+
+	for (i = 0; i < bw; i++) {
+		gate[i] = readl(PHY_REG(phy_base, 0xfb + i));
+		max_val = MAX(max_val, gate[i]);
+		min_val = MIN(min_val, gate[i]);
+	}
+
+	if (max_val > 0x80 || min_val < 0x20)
+		return -1;
+	else
+		return 0;
+}
+
+static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
+{
+	void __iomem *pctl_base = dram->pctl;
+	u32 dis_auto_zq = 0;
+	u32 pwrctl;
+	u32 ret;
+
+	/* disable auto low-power */
+	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
+	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
+
+	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
+
+	ret = phy_data_training(dram->phy, cs, dramtype);
+
+	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
+
+	/* restore auto low-power */
+	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
+
+	return ret;
+}
+
+static void dram_set_bw(struct dram_info *dram, u32 bw)
+{
+	phy_dram_set_bw(dram->phy, bw);
+}
+
+static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
+{
+	writel(ddrconfig | (ddrconfig << 8), &dram->msch->deviceconf);
+	rk_clrsetreg(&dram->grf->soc_noc_con[1], 0x3 << 14, 0 << 14);
+}
+
+static void dram_all_config(struct dram_info *dram,
+			    struct px30_sdram_params *sdram_params)
+{
+	struct px30_sdram_channel *cap_info = &sdram_params->ch;
+	u32 sys_reg2 = 0;
+	u32 sys_reg3 = 0;
+
+	set_ddrconfig(dram, cap_info->ddrconfig);
+	sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
+			 &sys_reg3, 0);
+	writel(sys_reg2, &dram->pmugrf->os_reg[2]);
+	writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+	sdram_msch_config(dram->msch, &sdram_params->ch.noc_timings, cap_info,
+			  &sdram_params->base);
+}
+
+static void enable_low_power(struct dram_info *dram,
+			     struct px30_sdram_params *sdram_params)
+{
+	void __iomem *pctl_base = dram->pctl;
+	void __iomem *phy_base = dram->phy;
+	void __iomem *ddr_grf_base = dram->ddr_grf;
+	u32 grf_lp_con;
+
+	/*
+	 * bit0: grf_upctl_axi_cg_en = 1 enable upctl2 axi clk auto gating
+	 * bit1: grf_upctl_apb_cg_en = 1 ungated axi,core clk for apb access
+	 * bit2: grf_upctl_core_cg_en = 1 enable upctl2 core clk auto gating
+	 * bit3: grf_selfref_type2_en = 0 disable core clk gating when type2 sr
+	 * bit4: grf_upctl_syscreq_cg_en = 1
+	 *       ungating coreclk when c_sysreq assert
+	 * bit8-11: grf_auto_sr_dly = 6
+	 */
+	writel(0x1f1f0617, &dram->ddr_grf->ddr_grf_con[1]);
+
+	if (sdram_params->base.dramtype == DDR4)
+		grf_lp_con = (0x7 << 16) | (1 << 1);
+	else if (sdram_params->base.dramtype == DDR3)
+		grf_lp_con = (0x7 << 16) | (1 << 0);
+	else
+		grf_lp_con = (0x7 << 16) | (1 << 2);
+
+	/* en lpckdis_en */
+	grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
+	writel(grf_lp_con, ddr_grf_base + DDR_GRF_LP_CON);
+
+	/* off digit module clock when enter power down */
+	setbits_le32(PHY_REG(phy_base, 7), 1 << 7);
+
+	/* enable sr, pd */
+	if (PD_IDLE == 0)
+		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+	else
+		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
+	if (SR_IDLE == 0)
+		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+	else
+		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
+	setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
+}
+
+/*
+ * pre_init: 0: pre init for dram cap detect
+ * 1: detect correct cap(except cs1 row)info, than reinit
+ * 2: after reinit, we detect cs1_row, if cs1_row not equal
+ *    to cs0_row and cs is in middle on ddrconf map, we need
+ *    to reinit dram, than set the correct ddrconf.
+ */
+static int sdram_init_(struct dram_info *dram,
+		       struct px30_sdram_params *sdram_params, u32 pre_init)
+{
+	struct px30_sdram_channel *cap_info = &sdram_params->ch;
+	void __iomem *pctl_base = dram->pctl;
+
+	rkclk_ddr_reset(dram, 1, 1, 1, 1);
+	rockchip_udelay(10);
+	/*
+	 * dereset ddr phy psrstn to config pll,
+	 * if using phy pll psrstn must be dereset
+	 * before config pll
+	 */
+	rkclk_ddr_reset(dram, 1, 1, 1, 0);
+	rkclk_configure_ddr(dram, sdram_params);
+
+	/* release phy srst to provide clk to ctrl */
+	rkclk_ddr_reset(dram, 1, 1, 0, 0);
+	rockchip_udelay(10);
+	phy_soft_reset(dram->phy);
+
+	/* release ctrl presetn, and config ctl registers */
+	rkclk_ddr_reset(dram, 1, 0, 0, 0);
+	pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
+	cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
+	set_ctl_address_map(dram, sdram_params);
+	phy_cfg(dram->phy, &sdram_params->phy_regs, sdram_params->skew,
+		&sdram_params->base, cap_info->bw);
+
+	/* enable dfi_init_start to init phy after ctl srstn deassert */
+	setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
+
+	rkclk_ddr_reset(dram, 0, 0, 0, 0);
+	/* wait for dfi_init_done and dram init complete */
+	while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
+		continue;
+
+	if (sdram_params->base.dramtype == LPDDR3)
+		pctl_write_mr(dram->pctl, 3, 11, 3, LPDDR3);
+
+	/* do ddr gate training */
+redo_cs0_training:
+	if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
+		if (pre_init != 0)
+			printascii("DTT cs0 error\n");
+		return -1;
+	}
+	if (check_rd_gate(dram)) {
+		printascii("re training cs0");
+		goto redo_cs0_training;
+	}
+
+	if (sdram_params->base.dramtype == LPDDR3) {
+		if ((read_mr(dram, 1, 8) & 0x3) != 0x3)
+			return -1;
+	} else if (sdram_params->base.dramtype == LPDDR2) {
+		if ((read_mr(dram, 1, 8) & 0x3) != 0x0)
+			return -1;
+	}
+
+	/* for px30: when 2cs, both 2 cs should be training */
+	if (pre_init != 0 && cap_info->rank == 2) {
+redo_cs1_training:
+		if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
+			printascii("DTT cs1 error\n");
+			return -1;
+		}
+		if (check_rd_gate(dram)) {
+			printascii("re training cs1");
+			goto redo_cs1_training;
+		}
+	}
+
+	if (sdram_params->base.dramtype == DDR4)
+		pctl_write_vrefdq(dram->pctl, 0x3, 5670,
+				  sdram_params->base.dramtype);
+
+	dram_all_config(dram, sdram_params);
+	enable_low_power(dram, sdram_params);
+
+	return 0;
+}
+
+static int dram_detect_cap(struct dram_info *dram,
+			   struct px30_sdram_params *sdram_params,
+			   unsigned char channel)
+{
+	struct px30_sdram_channel *cap_info = &sdram_params->ch;
+
+	/*
+	 * for ddr3: ddrconf = 3
+	 * for ddr4: ddrconf = 12
+	 * for lpddr3: ddrconf = 3
+	 * default bw = 1
+	 */
+	u32 bk, bktmp;
+	u32 col, coltmp;
+	u32 rowtmp;
+	u32 cs;
+	u32 bw = 1;
+	u32 dram_type = sdram_params->base.dramtype;
+
+	if (dram_type != DDR4) {
+		/* detect col and bk for ddr3/lpddr3 */
+		coltmp = 12;
+		bktmp = 3;
+		if (dram_type == LPDDR2)
+			rowtmp = 15;
+		else
+			rowtmp = 16;
+
+		if (sdram_detect_col(cap_info, coltmp) != 0)
+			goto cap_err;
+		sdram_detect_bank(cap_info, coltmp, bktmp);
+		sdram_detect_dbw(cap_info, dram_type);
+	} else {
+		/* detect bg for ddr4 */
+		coltmp = 10;
+		bktmp = 4;
+		rowtmp = 17;
+
+		col = 10;
+		bk = 2;
+		cap_info->col = col;
+		cap_info->bk = bk;
+		sdram_detect_bg(cap_info, coltmp);
+	}
+
+	/* detect row */
+	if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
+		goto cap_err;
+
+	/* detect row_3_4 */
+	sdram_detect_row_3_4(cap_info, coltmp, bktmp);
+
+	/* bw and cs detect using data training */
+	if (data_training(dram, 1, dram_type) == 0)
+		cs = 1;
+	else
+		cs = 0;
+	cap_info->rank = cs + 1;
+
+	dram_set_bw(dram, 2);
+	if (data_training(dram, 0, dram_type) == 0)
+		bw = 2;
+	else
+		bw = 1;
+	cap_info->bw = bw;
+
+	cap_info->cs0_high16bit_row = cap_info->cs0_row;
+	if (cs) {
+		cap_info->cs1_row = cap_info->cs0_row;
+		cap_info->cs1_high16bit_row = cap_info->cs0_row;
+	} else {
+		cap_info->cs1_row = 0;
+		cap_info->cs1_high16bit_row = 0;
+	}
+
+	return 0;
+cap_err:
+	return -1;
+}
+
+static int sdram_init_detect(struct dram_info *dram,
+			     struct px30_sdram_params *sdram_params)
+{
+	struct px30_sdram_channel *cap_info = &sdram_params->ch;
+	u32 ret;
+	u32 sys_reg = 0;
+	u32 sys_reg3 = 0;
+
+	if (sdram_init_(dram, sdram_params, 0) != 0)
+		return -1;
+
+	if (dram_detect_cap(dram, sdram_params, 0) != 0)
+		return -1;
+
+	/* modify bw, cs related timing */
+	pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
+				   sdram_params->base.dramtype);
+	/* reinit sdram by real dram cap */
+	ret = sdram_init_(dram, sdram_params, 1);
+	if (ret != 0)
+		goto out;
+
+	/* redetect cs1 row */
+	sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
+	if (cap_info->cs1_row) {
+		sys_reg = readl(&dram->pmugrf->os_reg[2]);
+		sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
+		writel(sys_reg, &dram->pmugrf->os_reg[2]);
+		writel(sys_reg3, &dram->pmugrf->os_reg[3]);
+	}
+
+	ret = sdram_detect_high_row(cap_info);
+
+out:
+	return ret;
+}
+
+struct px30_sdram_params *get_default_sdram_config(void)
+{
+	sdram_configs[0].skew = &skew;
+
+	return &sdram_configs[0];
+}
+
+int sdram_init(void)
+{
+	struct px30_sdram_params *sdram_params;
+	int ret = 0;
+
+	dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
+	dram_info.pctl = (void *)DDRC_BASE_ADDR;
+	dram_info.grf = (void *)GRF_BASE_ADDR;
+	dram_info.cru = (void *)CRU_BASE_ADDR;
+	dram_info.msch = (void *)SERVER_MSCH0_BASE_ADDR;
+	dram_info.ddr_grf = (void *)DDR_GRF_BASE_ADDR;
+	dram_info.pmugrf = (void *)PMUGRF_BASE_ADDR;
+
+	sdram_params = get_default_sdram_config();
+	ret = sdram_init_detect(&dram_info, sdram_params);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+#endif /* CONFIG_TPL_BUILD */
diff --git a/arch/arm/mach-rockchip/px30/syscon_px30.c b/arch/arm/mach-rockchip/px30/syscon_px30.c
new file mode 100644
index 0000000000..0331491b40
--- /dev/null
+++ b/arch/arm/mach-rockchip/px30/syscon_px30.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id px30_syscon_ids[] = {
+	{ .compatible = "rockchip,px30-pmu", .data = ROCKCHIP_SYSCON_PMU },
+	{ .compatible = "rockchip,px30-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
+	{ .compatible = "rockchip,px30-grf", .data = ROCKCHIP_SYSCON_GRF },
+	{ }
+};
+
+U_BOOT_DRIVER(syscon_px30) = {
+	.id = UCLASS_SYSCON,
+	.name = "px30_syscon",
+	.of_match = px30_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int px30_syscon_bind_of_platdata(struct udevice *dev)
+{
+	dev->driver_data = dev->driver->of_match->data;
+	debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(rockchip_px30_pmu) = {
+	.name = "rockchip_px30_pmu",
+	.id = UCLASS_SYSCON,
+	.of_match = px30_syscon_ids,
+	.bind = px30_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_px30_pmugrf) = {
+	.name = "rockchip_px30_pmugrf",
+	.id = UCLASS_SYSCON,
+	.of_match = px30_syscon_ids + 1,
+	.bind = px30_syscon_bind_of_platdata,
+};
+
+U_BOOT_DRIVER(rockchip_px30_grf) = {
+	.name = "rockchip_px30_grf",
+	.id = UCLASS_SYSCON,
+	.of_match = px30_syscon_ids + 2,
+	.bind = px30_syscon_bind_of_platdata,
+};
+#endif
-- 
2.23.0

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

* [U-Boot] [PATCH 12/12] rockchip: add px30-evb board
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (10 preceding siblings ...)
  2019-10-24 23:28 ` [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core Heiko Stuebner
@ 2019-10-24 23:28 ` Heiko Stuebner
  2019-10-25  2:51   ` Kever Yang
  2019-10-25  1:44 ` [U-Boot] [PATCH 00/12] rockchip: add support for px30 Kever Yang
  2019-11-18  2:57 ` Kever Yang
  13 siblings, 1 reply; 28+ messages in thread
From: Heiko Stuebner @ 2019-10-24 23:28 UTC (permalink / raw)
  To: u-boot

From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

The px30 evb is an evaluation board for the px30 together with a dsi-
connected display. This adds board and config files for it.

Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
---
 board/rockchip/evb_px30/Kconfig     |  15 ++++
 board/rockchip/evb_px30/MAINTAINERS |   6 ++
 board/rockchip/evb_px30/Makefile    |   7 ++
 board/rockchip/evb_px30/evb_px30.c  |   4 +
 configs/evb-px30_defconfig          | 113 ++++++++++++++++++++++++++++
 include/configs/evb_px30.h          |  19 +++++
 6 files changed, 164 insertions(+)
 create mode 100644 board/rockchip/evb_px30/Kconfig
 create mode 100644 board/rockchip/evb_px30/MAINTAINERS
 create mode 100644 board/rockchip/evb_px30/Makefile
 create mode 100644 board/rockchip/evb_px30/evb_px30.c
 create mode 100644 configs/evb-px30_defconfig
 create mode 100644 include/configs/evb_px30.h

diff --git a/board/rockchip/evb_px30/Kconfig b/board/rockchip/evb_px30/Kconfig
new file mode 100644
index 0000000000..0042c8e4db
--- /dev/null
+++ b/board/rockchip/evb_px30/Kconfig
@@ -0,0 +1,15 @@
+if TARGET_EVB_PX30
+
+config SYS_BOARD
+	default "evb_px30"
+
+config SYS_VENDOR
+	default "rockchip"
+
+config SYS_CONFIG_NAME
+	default "evb_px30"
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+
+endif
diff --git a/board/rockchip/evb_px30/MAINTAINERS b/board/rockchip/evb_px30/MAINTAINERS
new file mode 100644
index 0000000000..cf13f2419e
--- /dev/null
+++ b/board/rockchip/evb_px30/MAINTAINERS
@@ -0,0 +1,6 @@
+EVB-PX30
+M:      Kever Yang <kever.yang@rock-chips.com>
+S:      Maintained
+F:      board/rockchip/evb_px30
+F:      include/configs/evb_px30.h
+F:      configs/evb-px30_defconfig
diff --git a/board/rockchip/evb_px30/Makefile b/board/rockchip/evb_px30/Makefile
new file mode 100644
index 0000000000..74b0b9f44f
--- /dev/null
+++ b/board/rockchip/evb_px30/Makefile
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y	+= evb_px30.o
diff --git a/board/rockchip/evb_px30/evb_px30.c b/board/rockchip/evb_px30/evb_px30.c
new file mode 100644
index 0000000000..29464ae63e
--- /dev/null
+++ b/board/rockchip/evb_px30/evb_px30.c
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig
new file mode 100644
index 0000000000..d1cc1788c9
--- /dev/null
+++ b/configs/evb-px30_defconfig
@@ -0,0 +1,113 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00200000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_ROCKCHIP_PX30=y
+CONFIG_TARGET_EVB_PX30=y
+CONFIG_TPL_LIBGENERIC_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL_STACK_R_ADDR=0x600000
+CONFIG_DEBUG_UART_BASE=0xFF178000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_DEBUG_UART=y
+CONFIG_TPL_SYS_MALLOC_F_LEN=0x600
+# CONFIG_ANDROID_BOOT_IMAGE is not set
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_SPL_LOAD_FIT=y
+# CONFIG_CONSOLE_MUX is not set
+CONFIG_DEFAULT_FDT_FILE="rockchip/px30-evb.dtb"
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_BOUNCE_BUFFER_STATIC=y
+CONFIG_SPL_TEXT_BASE=0x00000000
+# CONFIG_SPL_BOARD_INIT is not set
+CONFIG_SPL_BOOTROM_SUPPORT=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set
+CONFIG_SPL_STACK_R=y
+# CONFIG_TPL_BANNER_PRINT is not set
+CONFIG_SPL_CRC32_SUPPORT=y
+CONFIG_SPL_ATF=y
+# CONFIG_TPL_FRAMEWORK is not set
+# CONFIG_CMD_BOOTD is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+# CONFIG_CMD_ITEST is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_MISC is not set
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_OF_LIVE=y
+CONFIG_DEFAULT_DEVICE_TREE="px30-evb"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x800800
+CONFIG_FASTBOOT_BUF_SIZE=0x04000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_OTP=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_PINCTRL=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_RESET=y
+# CONFIG_SPECIFY_CONSOLE_INDEX is not set
+# CONFIG_TPL_DM_SERIAL is not set
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_SOUND=y
+CONFIG_SYSRESET=y
+CONFIG_OPTEE=y
+CONFIG_DM_THERMAL=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_LCD=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_TPL_TINY_MEMSET=y
+CONFIG_LZ4=y
+CONFIG_LZO=y
+CONFIG_ERRNO_STR=y
+# CONFIG_EFI_LOADER is not set
diff --git a/include/configs/evb_px30.h b/include/configs/evb_px30.h
new file mode 100644
index 0000000000..e761c7c519
--- /dev/null
+++ b/include/configs/evb_px30.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#ifndef __EVB_PX30_H
+#define __EVB_PX30_H
+
+#include <configs/px30_common.h>
+
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+		"stdout=serial,vidconsole\0" \
+		"stderr=serial,vidconsole\0"
+
+#define CONFIG_SUPPORT_EMMC_RPMB
+
+#endif
-- 
2.23.0

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

* [U-Boot] [PATCH 00/12] rockchip: add support for px30
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (11 preceding siblings ...)
  2019-10-24 23:28 ` [U-Boot] [PATCH 12/12] rockchip: add px30-evb board Heiko Stuebner
@ 2019-10-25  1:44 ` Kever Yang
  2019-11-18  2:57 ` Kever Yang
  13 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  1:44 UTC (permalink / raw)
  To: u-boot

Hi Heiko,

     Thanks very much for you patches.


Thanks,
- Kever
On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
>
> This series adds support for the px30 soc and its evaluation board.
> The most interesting aspect is the sram size which is only 10kb,
> so the TPL doing the DDR init needs to be really tiny, while the
> SPL then should use devicemanager and all other newer features.
>
> I'm not yet sure if there is a better solution for the first patch
> but right now without it there is no way to build SPL with Framework
> and TPL without.
>
> David Wu (1):
>    pinctrl: rockchip: add px30 pinctrl driver
>
> Finley Xiao (1):
>    misc: add driver for the Rockchip otp controller
>
> Heiko Stuebner (8):
>    spl: separate SPL_FRAMEWORK config for spl and tpl
>    rockchip: add core px30 headers
>    net: gmac_rockchip: add support for px30
>    rockchip: misc: read cpuid either from efuse or otp
>    rockchip: ram: add dm-based sdram driver
>    rockchip: add px30 devicetrees
>    rockchip: add px30-evb board
>
> Kever Yang (2):
>    rockchip: clk: add px30 clock driver
>    rockchip: mkimage: add support for px30
>    rockchip: add px30 architecture core
>
>   arch/arm/dts/Makefile                         |    3 +
>   arch/arm/dts/px30-evb-u-boot.dtsi             |   81 +
>   arch/arm/dts/px30-evb.dts                     |  527 +++++
>   arch/arm/dts/px30.dtsi                        | 2068 +++++++++++++++++
>   arch/arm/include/asm/arch-px30/boot0.h        |   11 +
>   arch/arm/include/asm/arch-px30/gpio.h         |   11 +
>   arch/arm/include/asm/arch-rockchip/cru_px30.h |  432 ++++
>   arch/arm/include/asm/arch-rockchip/grf_px30.h |  144 ++
>   .../include/asm/arch-rockchip/sdram_px30.h    |  359 +++
>   arch/arm/lib/Makefile                         |    2 +-
>   arch/arm/lib/crt0.S                           |    2 +-
>   arch/arm/lib/crt0_64.S                        |    2 +
>   arch/arm/mach-rockchip/Kconfig                |   23 +
>   arch/arm/mach-rockchip/Makefile               |    2 +
>   arch/arm/mach-rockchip/misc.c                 |    7 +-
>   arch/arm/mach-rockchip/px30-board-tpl.c       |   59 +
>   arch/arm/mach-rockchip/px30/Kconfig           |   48 +
>   arch/arm/mach-rockchip/px30/Makefile          |   14 +
>   arch/arm/mach-rockchip/px30/clk_px30.c        |   31 +
>   arch/arm/mach-rockchip/px30/px30.c            |  248 ++
>   .../px30/sdram-px30-ddr3-detect-333.inc       |   70 +
>   .../px30/sdram-px30-ddr4-detect-333.inc       |   73 +
>   .../px30/sdram-px30-ddr_skew.inc              |  121 +
>   .../px30/sdram-px30-lpddr2-detect-333.inc     |   71 +
>   .../px30/sdram-px30-lpddr3-detect-333.inc     |   72 +
>   arch/arm/mach-rockchip/px30/sdram_px30.c      | 1405 +++++++++++
>   arch/arm/mach-rockchip/px30/syscon_px30.c     |   53 +
>   arch/powerpc/lib/Makefile                     |    2 +-
>   board/rockchip/evb_px30/Kconfig               |   15 +
>   board/rockchip/evb_px30/MAINTAINERS           |    6 +
>   board/rockchip/evb_px30/Makefile              |    7 +
>   board/rockchip/evb_px30/evb_px30.c            |    4 +
>   common/spl/Kconfig                            |    8 +
>   common/spl/Makefile                           |    2 +-
>   configs/evb-px30_defconfig                    |  113 +
>   drivers/clk/rockchip/Makefile                 |    1 +
>   drivers/clk/rockchip/clk_px30.c               | 1630 +++++++++++++
>   drivers/misc/Kconfig                          |    9 +
>   drivers/misc/Makefile                         |    1 +
>   drivers/misc/rockchip-otp.c                   |  176 ++
>   drivers/net/gmac_rockchip.c                   |   69 +
>   drivers/pinctrl/rockchip/Makefile             |    1 +
>   drivers/pinctrl/rockchip/pinctrl-px30.c       |  368 +++
>   drivers/ram/rockchip/Makefile                 |    1 +
>   drivers/ram/rockchip/sdram_px30.c             |   57 +
>   include/configs/evb_px30.h                    |   19 +
>   include/configs/px30_common.h                 |   62 +
>   include/dt-bindings/clock/px30-cru.h          |  389 ++++
>   include/dt-bindings/power/px30-power.h        |   27 +
>   include/dt-bindings/soc/rockchip,boot-mode.h  |   16 +
>   scripts/Makefile.spl                          |    4 +
>   tools/rkcommon.c                              |    1 +
>   52 files changed, 8922 insertions(+), 5 deletions(-)
>   create mode 100644 arch/arm/dts/px30-evb-u-boot.dtsi
>   create mode 100644 arch/arm/dts/px30-evb.dts
>   create mode 100644 arch/arm/dts/px30.dtsi
>   create mode 100644 arch/arm/include/asm/arch-px30/boot0.h
>   create mode 100644 arch/arm/include/asm/arch-px30/gpio.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/cru_px30.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/grf_px30.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h
>   create mode 100644 arch/arm/mach-rockchip/px30-board-tpl.c
>   create mode 100644 arch/arm/mach-rockchip/px30/Kconfig
>   create mode 100644 arch/arm/mach-rockchip/px30/Makefile
>   create mode 100644 arch/arm/mach-rockchip/px30/clk_px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram_px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/syscon_px30.c
>   create mode 100644 board/rockchip/evb_px30/Kconfig
>   create mode 100644 board/rockchip/evb_px30/MAINTAINERS
>   create mode 100644 board/rockchip/evb_px30/Makefile
>   create mode 100644 board/rockchip/evb_px30/evb_px30.c
>   create mode 100644 configs/evb-px30_defconfig
>   create mode 100644 drivers/clk/rockchip/clk_px30.c
>   create mode 100644 drivers/misc/rockchip-otp.c
>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-px30.c
>   create mode 100644 drivers/ram/rockchip/sdram_px30.c
>   create mode 100644 include/configs/evb_px30.h
>   create mode 100644 include/configs/px30_common.h
>   create mode 100644 include/dt-bindings/clock/px30-cru.h
>   create mode 100644 include/dt-bindings/power/px30-power.h
>   create mode 100644 include/dt-bindings/soc/rockchip,boot-mode.h
>

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

* [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl
  2019-10-24 23:27 ` [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl Heiko Stuebner
@ 2019-10-25  1:55   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  1:55 UTC (permalink / raw)
  To: u-boot

Heiko,


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
>
> Right now enabling SPL_FRAMEWORK will also enable it for the TPL in all
> cases, making the TPL bigger. There may be cases where the TPL is really
> size constrained due to its underlying ram size.
>
> Therefore introduce a new TPL_FRAMEWORK option and make the relevant
> conditionals check for both. The default is set to "y if SPL_FRAMEWORK"
> to mimic the previous behaviour where the TPL would always get the
> SPL framework if it was enabled in SPL.


New TPL_FRAMEWORK looks reasonable, after this patch, only the 
board_init_f() is available while

board_init_r() is drop, right?

> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
> ---
>   arch/arm/lib/Makefile     | 2 +-
>   arch/arm/lib/crt0.S       | 2 +-
>   arch/arm/lib/crt0_64.S    | 2 ++
>   arch/powerpc/lib/Makefile | 2 +-
>   common/spl/Kconfig        | 8 ++++++++
>   common/spl/Makefile       | 2 +-
>   scripts/Makefile.spl      | 4 ++++
>   7 files changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
> index 48ee6c3c60..9de9a9acee 100644
> --- a/arch/arm/lib/Makefile
> +++ b/arch/arm/lib/Makefile
> @@ -35,7 +35,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o
>   obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
>   obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
>   else
> -obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
> +obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
>   obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o
>   obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
>   endif
> diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
> index c74641dcd9..fb6c37cf51 100644
> --- a/arch/arm/lib/crt0.S
> +++ b/arch/arm/lib/crt0.S
> @@ -149,7 +149,7 @@ here:
>   
>   	bl	c_runtime_cpu_setup	/* we still call old routine here */
>   #endif
> -#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
> +#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
>   
>   #if !defined(CONFIG_SPL_EARLY_BSS)
>   	SPL_CLEAR_BSS
> diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
> index e76b25a03e..04afa518ac 100644
> --- a/arch/arm/lib/crt0_64.S
> +++ b/arch/arm/lib/crt0_64.S
> @@ -120,6 +120,7 @@ relocation_return:
>    */
>   	bl	c_runtime_cpu_setup		/* still call old routine */
>   #endif /* !CONFIG_SPL_BUILD */
> +#if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(FRAMEWORK)
>   #if defined(CONFIG_SPL_BUILD)
>   	bl	spl_relocate_stack_gd           /* may return NULL */
>   	/* set up gd here, outside any C code, if new stack is returned */
> @@ -152,5 +153,6 @@ clear_loop:
>   	b	board_init_r			/* PC relative jump */
>   
>   	/* NOTREACHED - board_init_r() does not return */
> +#endif
>   
>   ENDPROC(_main)
> diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
> index 8ac49bdd06..01c9dd51be 100644
> --- a/arch/powerpc/lib/Makefile
> +++ b/arch/powerpc/lib/Makefile
> @@ -41,5 +41,5 @@ obj-y	+= time.o
>   endif # not minimal
>   
>   ifdef CONFIG_SPL_BUILD
> -obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
> +obj-$(CONFIG_$(SPL_TPL)_FRAMEWORK) += spl.o
>   endif
> diff --git a/common/spl/Kconfig b/common/spl/Kconfig
> index f467eca2be..4d5c4ddc46 100644
> --- a/common/spl/Kconfig
> +++ b/common/spl/Kconfig
> @@ -1183,6 +1183,14 @@ config TPL
>   
>   if TPL
>   
> +config TPL_FRAMEWORK
> +	bool "Support TPL based upon the common SPL framework"
> +	default y if SPL_FRAMEWORK
> +	help
> +	  Enable the SPL framework under common/spl/ for TPL builds.
> +	  This framework supports MMC, NAND and YMODEM and other methods
> +	  loading of U-Boot's SPL stage. If unsure, say Y.
> +
>   config TPL_HANDOFF
>   	bool "Pass hand-off information from TPL to SPL and U-Boot proper"
>   	depends on HANDOFF
> diff --git a/common/spl/Makefile b/common/spl/Makefile
> index 5ce6f4ae48..eaa57f5ce5 100644
> --- a/common/spl/Makefile
> +++ b/common/spl/Makefile
> @@ -7,7 +7,7 @@
>   #
>   
>   ifdef CONFIG_SPL_BUILD
> -obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
> +obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
>   obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o
>   obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o
>   obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o
> diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
> index 7af6b120b6..090c831710 100644
> --- a/scripts/Makefile.spl
> +++ b/scripts/Makefile.spl
> @@ -71,7 +71,11 @@ HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makef
>   libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
>   libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/
>   
> +ifeq ($(CONFIG_TPL_BUILD),y)
> +libs-$(CONFIG_TPL_FRAMEWORK) += common/spl/
> +else
>   libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
> +endif
Is it able to use code like:

libs-$(CONFIG_$(SPL_TPL_)FRAMEWORK) +=

Thanks,
- Kever

>   libs-y += common/init/
>   
>   # Special handling for a few options which support SPL/TPL

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

* [U-Boot] [PATCH 02/12] rockchip: add core px30 headers
  2019-10-24 23:27 ` [U-Boot] [PATCH 02/12] rockchip: add core px30 headers Heiko Stuebner
@ 2019-10-25  2:04   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:04 UTC (permalink / raw)
  To: u-boot

Heiko,

On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> Add headers needed by the upcoming px30 support, including two
> new dt-binding headers taken from the Linux kernel.
>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
> ---
>   arch/arm/include/asm/arch-rockchip/grf_px30.h | 144 ++++++++++++++++++
>   include/configs/px30_common.h                 |  62 ++++++++
>   include/dt-bindings/power/px30-power.h        |  27 ++++
>   include/dt-bindings/soc/rockchip,boot-mode.h  |  16 ++
>   4 files changed, 249 insertions(+)
>   create mode 100644 arch/arm/include/asm/arch-rockchip/grf_px30.h
>   create mode 100644 include/configs/px30_common.h
>   create mode 100644 include/dt-bindings/power/px30-power.h
>   create mode 100644 include/dt-bindings/soc/rockchip,boot-mode.h
>
> diff --git a/arch/arm/include/asm/arch-rockchip/grf_px30.h b/arch/arm/include/asm/arch-rockchip/grf_px30.h
> new file mode 100644
> index 0000000000..c167bb42fa
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-rockchip/grf_px30.h
> @@ -0,0 +1,144 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
> + */
> +#ifndef _ASM_ARCH_GRF_px30_H
> +#define _ASM_ARCH_GRF_px30_H
> +
> +#include <common.h>
> +
> +struct px30_grf {
> +	unsigned int gpio1al_iomux;
> +	unsigned int gpio1ah_iomux;
> +	unsigned int gpio1bl_iomux;
> +	unsigned int gpio1bh_iomux;
> +	unsigned int gpio1cl_iomux;
> +	unsigned int gpio1ch_iomux;
> +	unsigned int gpio1dl_iomux;
> +	unsigned int gpio1dh_iomux;
> +
> +	unsigned int gpio2al_iomux;
> +	unsigned int gpio2ah_iomux;
> +	unsigned int gpio2bl_iomux;
> +	unsigned int gpio2bh_iomux;
> +	unsigned int gpio2cl_iomux;
> +	unsigned int gpio2ch_iomux;
> +	unsigned int gpio2dl_iomux;
> +	unsigned int gpio2dh_iomux;
> +
> +	unsigned int gpio3al_iomux;
> +	unsigned int gpio3ah_iomux;
> +	unsigned int gpio3bl_iomux;
> +	unsigned int gpio3bh_iomux;
> +	unsigned int gpio3cl_iomux;
> +	unsigned int gpio3ch_iomux;
> +	unsigned int gpio3dl_iomux;
> +	unsigned int gpio3dh_iomux;
> +
> +	unsigned int gpio1a_p;
> +	unsigned int gpio1b_p;
> +	unsigned int gpio1c_p;
> +	unsigned int gpio1d_p;
> +	unsigned int gpio2a_p;
> +	unsigned int gpio2b_p;
> +	unsigned int gpio2c_p;
> +	unsigned int gpio2d_p;
> +	unsigned int gpio3a_p;
> +	unsigned int gpio3b_p;
> +	unsigned int gpio3c_p;
> +	unsigned int gpio3d_p;
> +	unsigned int gpio1a_sr;
> +	unsigned int gpio1b_sr;
> +	unsigned int gpio1c_sr;
> +	unsigned int gpio1d_sr;
> +	unsigned int gpio2a_sr;
> +	unsigned int gpio2b_sr;
> +	unsigned int gpio2c_sr;
> +	unsigned int gpio2d_sr;
> +	unsigned int gpio3a_sr;
> +	unsigned int gpio3b_sr;
> +	unsigned int gpio3c_sr;
> +	unsigned int gpio3d_sr;
> +	unsigned int gpio1a_smt;
> +	unsigned int gpio1b_smt;
> +	unsigned int gpio1c_smt;
> +	unsigned int gpio1d_smt;
> +	unsigned int gpio2a_smt;
> +	unsigned int gpio2b_smt;
> +	unsigned int gpio2c_smt;
> +	unsigned int gpio2d_smt;
> +	unsigned int gpio3a_smt;
> +	unsigned int gpio3b_smt;
> +	unsigned int gpio3c_smt;
> +	unsigned int gpio3d_smt;
> +	unsigned int gpio1a_e;
> +	unsigned int gpio1b_e;
> +	unsigned int gpio1c_e;
> +	unsigned int gpio1d_e;
> +	unsigned int gpio2a_e;
> +	unsigned int gpio2b_e;
> +	unsigned int gpio2c_e;
> +	unsigned int gpio2d_e;
> +	unsigned int gpio3a_e;
> +	unsigned int gpio3b_e;
> +	unsigned int gpio3c_e;
> +	unsigned int gpio3d_e;
> +
> +	unsigned int reserved0[(0x180 - 0x11C) / 4 - 1];
> +	unsigned int io_vsel;
> +	unsigned int iofunc_con0;
> +	unsigned int reserved1[(0x400 - 0x184) / 4 - 1];
> +	unsigned int soc_con[6];
> +	unsigned int reserved2[(0x480 - 0x414) / 4 - 1];
> +	unsigned int soc_status0;
> +	unsigned int reserved3[(0x500 - 0x480) / 4 - 1];
> +	unsigned int cpu_con[3];
> +	unsigned int reserved4[5];
> +	unsigned int cpu_status[2];
> +	unsigned int reserved5[2];
> +	unsigned int soc_noc_con[2];
> +	unsigned int reserved6[6];
> +	unsigned int ddr_bankhash[4];
> +	unsigned int reserved7[(0x700 - 0x55c) / 4 - 1];
> +	unsigned int host0_con[2];
> +	unsigned int reserved8[(0x880 - 0x704) / 4 - 1];
> +	unsigned int otg_con3;
> +	unsigned int reserved9[3];
> +	unsigned int host0_status4;
> +	unsigned int reserved10[(0x904 - 0x890) / 4 - 1];
> +	unsigned int mac_con1;
> +};
> +
> +check_member(px30_grf, mac_con1, 0x904);
> +
> +struct px30_pmugrf {
> +	unsigned int gpio0a_e;
> +	unsigned int gpio0b_e;
> +	unsigned int gpio0c_e;
> +	unsigned int gpio0d_e;
> +	unsigned int gpio0a_p;
> +	unsigned int gpio0b_p;
> +	unsigned int gpio0c_p;
> +	unsigned int gpio0d_p;
> +	unsigned int gpio0al_iomux;
> +	unsigned int gpio0bl_iomux;
> +	unsigned int gpio0cl_iomux;
> +	unsigned int gpio0dl_iomux;
> +	unsigned int gpio0l_sr;
> +	unsigned int gpio0h_sr;
> +	unsigned int gpio0l_smt;
> +	unsigned int gpio0h_smt;
> +	unsigned int reserved1[(0x100 - 0x3c) / 4 - 1];
> +	unsigned int soc_con[4];
> +	unsigned int reserved2[(0x180 - 0x10c) / 4 - 1];
> +	unsigned int pvtm_con[2];
> +	unsigned int reserved3[2];
> +	unsigned int pvtm_status[2];
> +	unsigned int reserved4[(0x200 - 0x194) / 4 - 1];
> +	unsigned int os_reg[12];
> +	unsigned int reset_function_status;
> +};
> +
> +check_member(px30_pmugrf, reset_function_status, 0x230);
> +
> +#endif
> diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h
> new file mode 100644
> index 0000000000..d6c70601dd
> --- /dev/null
> +++ b/include/configs/px30_common.h
> @@ -0,0 +1,62 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2017 Rockchip Electronics Co., Ltd
> + */
> +
> +#ifndef __CONFIG_PX30_COMMON_H
> +#define __CONFIG_PX30_COMMON_H
> +
> +#include "rockchip-common.h"
> +
> +#define CONFIG_SYS_CBSIZE		1024
> +#define CONFIG_SKIP_LOWLEVEL_INIT
> +
> +#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 */
> +#define CONFIG_IRAM_BASE		0xff020000
> +
> +#define CONFIG_SYS_INIT_SP_ADDR		0x00400000
> +#define CONFIG_SYS_LOAD_ADDR		0x00800800
> +#define CONFIG_SPL_STACK		0x00400000
> +#define CONFIG_SPL_MAX_SIZE		0x20000
> +#define CONFIG_SPL_BSS_START_ADDR	0x4000000
> +#define CONFIG_SPL_BSS_MAX_SIZE		0x4000
> +#define CONFIG_SYS_BOOTM_LEN		(64 << 20)	/* 64M */
> +
> +#define GICD_BASE			0xff131000
> +#define GICC_BASE			0xff132000
> +
> +#define CONFIG_SYS_BOOTM_LEN	(64 << 20)	/* 64M */
> +
> +/* MMC/SD IP block */
> +//#define CONFIG_BOUNCE_BUFFER


Why does the bounce buffer removed? We should always need this in case user

send a non-aligned address to the driver.


Thanks,

- Kever

> +
> +#define CONFIG_SYS_SDRAM_BASE		0
> +#define SDRAM_MAX_SIZE			0xff000000
> +#define SDRAM_BANK_SIZE			(2UL << 30)
> +
> +#ifndef CONFIG_SPL_BUILD
> +
> +#define ENV_MEM_LAYOUT_SETTINGS \
> +	"scriptaddr=0x00500000\0" \
> +	"pxefile_addr_r=0x00600000\0" \
> +	"fdt_addr_r=0x08300000\0" \
> +	"kernel_addr_r=0x00280000\0" \
> +	"kernel_addr_c=0x03e80000\0" \
> +	"ramdisk_addr_r=0x0a200000\0"
> +
> +#include <config_distro_bootcmd.h>
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> +	ENV_MEM_LAYOUT_SETTINGS \
> +	"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
> +	"partitions=" PARTS_DEFAULT \
> +	ROCKCHIP_DEVICE_SETTINGS \
> +	BOOTENV
> +
> +#endif
> +
> +#endif
> diff --git a/include/dt-bindings/power/px30-power.h b/include/dt-bindings/power/px30-power.h
> new file mode 100644
> index 0000000000..30917a99ad
> --- /dev/null
> +++ b/include/dt-bindings/power/px30-power.h
> @@ -0,0 +1,27 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__
> +#define __DT_BINDINGS_POWER_PX30_POWER_H__
> +
> +/* VD_CORE */
> +#define PX30_PD_A35_0		0
> +#define PX30_PD_A35_1		1
> +#define PX30_PD_A35_2		2
> +#define PX30_PD_A35_3		3
> +#define PX30_PD_SCU		4
> +
> +/* VD_LOGIC */
> +#define PX30_PD_USB		5
> +#define PX30_PD_DDR		6
> +#define PX30_PD_SDCARD		7
> +#define PX30_PD_CRYPTO		8
> +#define PX30_PD_GMAC		9
> +#define PX30_PD_MMC_NAND	10
> +#define PX30_PD_VPU		11
> +#define PX30_PD_VO		12
> +#define PX30_PD_VI		13
> +#define PX30_PD_GPU		14
> +
> +/* VD_PMU */
> +#define PX30_PD_PMU		15
> +
> +#endif
> diff --git a/include/dt-bindings/soc/rockchip,boot-mode.h b/include/dt-bindings/soc/rockchip,boot-mode.h
> new file mode 100644
> index 0000000000..4b0914c098
> --- /dev/null
> +++ b/include/dt-bindings/soc/rockchip,boot-mode.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ROCKCHIP_BOOT_MODE_H
> +#define __ROCKCHIP_BOOT_MODE_H
> +
> +/*high 24 bits is tag, low 8 bits is type*/
> +#define REBOOT_FLAG		0x5242C300
> +/* normal boot */
> +#define BOOT_NORMAL		(REBOOT_FLAG + 0)
> +/* enter bootloader rockusb mode */
> +#define BOOT_BL_DOWNLOAD	(REBOOT_FLAG + 1)
> +/* enter recovery */
> +#define BOOT_RECOVERY		(REBOOT_FLAG + 3)
> + /* enter fastboot mode */
> +#define BOOT_FASTBOOT		(REBOOT_FLAG + 9)
> +
> +#endif

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

* [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver
  2019-10-24 23:27 ` [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver Heiko Stuebner
@ 2019-10-25  2:07   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:07 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: David Wu <david.wu@rock-chips.com>
>
> Add the necessary glue code to allow pinctrl setting on px30 socs.
>
> Signed-off-by: David Wu <david.wu@rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>


Reviewed-by: Kever Yang<kever.yang@rock-chips.com>

Thanks,
- Kever

> ---
>   drivers/pinctrl/rockchip/Makefile       |   1 +
>   drivers/pinctrl/rockchip/pinctrl-px30.c | 368 ++++++++++++++++++++++++
>   2 files changed, 369 insertions(+)
>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-px30.c
>
> diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile
> index a616d8587f..83913f668f 100644
> --- a/drivers/pinctrl/rockchip/Makefile
> +++ b/drivers/pinctrl/rockchip/Makefile
> @@ -3,6 +3,7 @@
>   # Copyright (c) 2017 Rockchip Electronics Co., Ltd
>   
>   obj-y += pinctrl-rockchip-core.o
> +obj-$(CONFIG_ROCKCHIP_PX30) += pinctrl-px30.o
>   obj-$(CONFIG_ROCKCHIP_RK3036) += pinctrl-rk3036.o
>   obj-$(CONFIG_ROCKCHIP_RK3128) += pinctrl-rk3128.o
>   obj-$(CONFIG_ROCKCHIP_RK3188) += pinctrl-rk3188.o
> diff --git a/drivers/pinctrl/rockchip/pinctrl-px30.c b/drivers/pinctrl/rockchip/pinctrl-px30.c
> new file mode 100644
> index 0000000000..bb56ae9fb3
> --- /dev/null
> +++ b/drivers/pinctrl/rockchip/pinctrl-px30.c
> @@ -0,0 +1,368 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <dm/pinctrl.h>
> +#include <regmap.h>
> +#include <syscon.h>
> +
> +#include "pinctrl-rockchip.h"
> +
> +static struct rockchip_mux_route_data px30_mux_route_data[] = {
> +	{
> +		/* cif-d2m0 */
> +		.bank_num = 2,
> +		.pin = 0,
> +		.func = 1,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 7),
> +	}, {
> +		/* cif-d2m1 */
> +		.bank_num = 3,
> +		.pin = 3,
> +		.func = 3,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 7) | BIT(7),
> +	}, {
> +		/* pdm-m0 */
> +		.bank_num = 3,
> +		.pin = 22,
> +		.func = 2,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 8),
> +	}, {
> +		/* pdm-m1 */
> +		.bank_num = 2,
> +		.pin = 22,
> +		.func = 1,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 8) | BIT(8),
> +	}, {
> +		/* uart2-rxm0 */
> +		.bank_num = 1,
> +		.pin = 27,
> +		.func = 2,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 10),
> +	}, {
> +		/* uart2-rxm1 */
> +		.bank_num = 2,
> +		.pin = 14,
> +		.func = 2,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 10) | BIT(10),
> +	}, {
> +		/* uart3-rxm0 */
> +		.bank_num = 0,
> +		.pin = 17,
> +		.func = 2,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 9),
> +	}, {
> +		/* uart3-rxm1 */
> +		.bank_num = 1,
> +		.pin = 15,
> +		.func = 2,
> +		.route_offset = 0x184,
> +		.route_val = BIT(16 + 9) | BIT(9),
> +	},
> +};
> +
> +static int px30_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, route_reg, route_val;
> +
> +	regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
> +				? priv->regmap_pmu : 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);
> +
> +	if (bank->route_mask & BIT(pin)) {
> +		if (rockchip_get_mux_route(bank, pin, mux, &route_reg,
> +					   &route_val)) {
> +			ret = regmap_write(regmap, route_reg, route_val);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
> +	data = (mask << (bit + 16));
> +	data |= (mux & mask) << bit;
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +#define PX30_PULL_PMU_OFFSET		0x10
> +#define PX30_PULL_GRF_OFFSET		0x60
> +#define PX30_PULL_BITS_PER_PIN		2
> +#define PX30_PULL_PINS_PER_REG		8
> +#define PX30_PULL_BANK_STRIDE		16
> +
> +static void px30_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank,
> +				       int pin_num, struct regmap **regmap,
> +				       int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> +
> +	/* The first 32 pins of the first bank are located in PMU */
> +	if (bank->bank_num == 0) {
> +		*regmap = priv->regmap_pmu;
> +		*reg = PX30_PULL_PMU_OFFSET;
> +	} else {
> +		*regmap = priv->regmap_base;
> +		*reg = PX30_PULL_GRF_OFFSET;
> +
> +		/* correct the offset, as we're starting with the 2nd bank */
> +		*reg -= 0x10;
> +		*reg += bank->bank_num * PX30_PULL_BANK_STRIDE;
> +	}
> +
> +	*reg += ((pin_num / PX30_PULL_PINS_PER_REG) * 4);
> +	*bit = (pin_num % PX30_PULL_PINS_PER_REG);
> +	*bit *= PX30_PULL_BITS_PER_PIN;
> +}
> +
> +static int px30_set_pull(struct rockchip_pin_bank *bank,
> +			 int pin_num, int pull)
> +{
> +	struct regmap *regmap;
> +	int reg, ret;
> +	u8 bit, type;
> +	u32 data;
> +
> +	if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT)
> +		return -ENOTSUPP;
> +
> +	px30_calc_pull_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +	type = bank->pull_type[pin_num / 8];
> +	ret = rockchip_translate_pull_value(type, pull);
> +	if (ret < 0) {
> +		debug("unsupported pull setting %d\n", pull);
> +		return ret;
> +	}
> +
> +	/* enable the write to the equivalent lower bits */
> +	data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16);
> +	data |= (ret << bit);
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +#define PX30_DRV_PMU_OFFSET		0x20
> +#define PX30_DRV_GRF_OFFSET		0xf0
> +#define PX30_DRV_BITS_PER_PIN		2
> +#define PX30_DRV_PINS_PER_REG		8
> +#define PX30_DRV_BANK_STRIDE		16
> +
> +static void px30_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank,
> +				      int pin_num, struct regmap **regmap,
> +				      int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> +
> +	/* The first 32 pins of the first bank are located in PMU */
> +	if (bank->bank_num == 0) {
> +		*regmap = priv->regmap_pmu;
> +		*reg = PX30_DRV_PMU_OFFSET;
> +	} else {
> +		*regmap = priv->regmap_base;
> +		*reg = PX30_DRV_GRF_OFFSET;
> +
> +		/* correct the offset, as we're starting with the 2nd bank */
> +		*reg -= 0x10;
> +		*reg += bank->bank_num * PX30_DRV_BANK_STRIDE;
> +	}
> +
> +	*reg += ((pin_num / PX30_DRV_PINS_PER_REG) * 4);
> +	*bit = (pin_num % PX30_DRV_PINS_PER_REG);
> +	*bit *= PX30_DRV_BITS_PER_PIN;
> +}
> +
> +static int px30_set_drive(struct rockchip_pin_bank *bank,
> +			  int pin_num, int strength)
> +{
> +	struct regmap *regmap;
> +	int reg, ret;
> +	u32 data, rmask_bits, temp;
> +	u8 bit;
> +	int drv_type = bank->drv[pin_num / 8].drv_type;
> +
> +	px30_calc_drv_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +	ret = rockchip_translate_drive_value(drv_type, strength);
> +	if (ret < 0) {
> +		debug("unsupported driver strength %d\n", strength);
> +		return ret;
> +	}
> +
> +	switch (drv_type) {
> +	case DRV_TYPE_IO_1V8_3V0_AUTO:
> +	case DRV_TYPE_IO_3V3_ONLY:
> +		rmask_bits = ROCKCHIP_DRV_3BITS_PER_PIN;
> +		switch (bit) {
> +		case 0 ... 12:
> +			/* regular case, nothing to do */
> +			break;
> +		case 15:
> +			/*
> +			 * drive-strength offset is special, as it is spread
> +			 * over 2 registers, the bit data[15] contains bit 0
> +			 * of the value while temp[1:0] contains bits 2 and 1
> +			 */
> +			data = (ret & 0x1) << 15;
> +			temp = (ret >> 0x1) & 0x3;
> +
> +			data |= BIT(31);
> +			ret = regmap_write(regmap, reg, data);
> +			if (ret)
> +				return ret;
> +
> +			temp |= (0x3 << 16);
> +			reg += 0x4;
> +			ret = regmap_write(regmap, reg, temp);
> +
> +			return ret;
> +		case 18 ... 21:
> +			/* setting fully enclosed in the second register */
> +			reg += 4;
> +			bit -= 16;
> +			break;
> +		default:
> +			debug("unsupported bit: %d for pinctrl drive type: %d\n",
> +			      bit, drv_type);
> +			return -EINVAL;
> +		}
> +		break;
> +	case DRV_TYPE_IO_DEFAULT:
> +	case DRV_TYPE_IO_1V8_OR_3V0:
> +	case DRV_TYPE_IO_1V8_ONLY:
> +		rmask_bits = ROCKCHIP_DRV_BITS_PER_PIN;
> +		break;
> +	default:
> +		debug("unsupported pinctrl drive type: %d\n",
> +		      drv_type);
> +		return -EINVAL;
> +	}
> +
> +	/* enable the write to the equivalent lower bits */
> +	data = ((1 << rmask_bits) - 1) << (bit + 16);
> +	data |= (ret << bit);
> +	ret = regmap_write(regmap, reg, data);
> +
> +	return ret;
> +}
> +
> +#define PX30_SCHMITT_PMU_OFFSET			0x38
> +#define PX30_SCHMITT_GRF_OFFSET			0xc0
> +#define PX30_SCHMITT_PINS_PER_PMU_REG		16
> +#define PX30_SCHMITT_BANK_STRIDE		16
> +#define PX30_SCHMITT_PINS_PER_GRF_REG		8
> +
> +static int px30_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank,
> +					 int pin_num,
> +					 struct regmap **regmap,
> +					 int *reg, u8 *bit)
> +{
> +	struct rockchip_pinctrl_priv *priv = bank->priv;
> +	int pins_per_reg;
> +
> +	if (bank->bank_num == 0) {
> +		*regmap = priv->regmap_pmu;
> +		*reg = PX30_SCHMITT_PMU_OFFSET;
> +		pins_per_reg = PX30_SCHMITT_PINS_PER_PMU_REG;
> +	} else {
> +		*regmap = priv->regmap_base;
> +		*reg = PX30_SCHMITT_GRF_OFFSET;
> +		pins_per_reg = PX30_SCHMITT_PINS_PER_GRF_REG;
> +		*reg += (bank->bank_num - 1) * PX30_SCHMITT_BANK_STRIDE;
> +	}
> +	*reg += ((pin_num / pins_per_reg) * 4);
> +	*bit = pin_num % pins_per_reg;
> +
> +	return 0;
> +}
> +
> +static int px30_set_schmitt(struct rockchip_pin_bank *bank,
> +			    int pin_num, int enable)
> +{
> +	struct regmap *regmap;
> +	int reg;
> +	u8 bit;
> +	u32 data;
> +
> +	px30_calc_schmitt_reg_and_bit(bank, pin_num, &regmap, &reg, &bit);
> +	/* enable the write to the equivalent lower bits */
> +	data = BIT(bit + 16) | (enable << bit);
> +
> +	return regmap_write(regmap, reg, data);
> +}
> +
> +static struct rockchip_pin_bank px30_pin_banks[] = {
> +	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
> +					     IOMUX_SOURCE_PMU,
> +					     IOMUX_SOURCE_PMU,
> +					     IOMUX_SOURCE_PMU
> +			    ),
> +	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT
> +			    ),
> +	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT
> +			    ),
> +	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT,
> +					     IOMUX_WIDTH_4BIT
> +			    ),
> +};
> +
> +static struct rockchip_pin_ctrl px30_pin_ctrl = {
> +	.pin_banks		= px30_pin_banks,
> +	.nr_banks		= ARRAY_SIZE(px30_pin_banks),
> +	.grf_mux_offset		= 0x0,
> +	.pmu_mux_offset		= 0x0,
> +	.grf_drv_offset		= 0xf0,
> +	.pmu_drv_offset		= 0x20,
> +	.iomux_routes		= px30_mux_route_data,
> +	.niomux_routes		= ARRAY_SIZE(px30_mux_route_data),
> +	.set_mux		= px30_set_mux,
> +	.set_pull		= px30_set_pull,
> +	.set_drive		= px30_set_drive,
> +	.set_schmitt		= px30_set_schmitt,
> +};
> +
> +static const struct udevice_id px30_pinctrl_ids[] = {
> +	{
> +		.compatible = "rockchip,px30-pinctrl",
> +		.data = (ulong)&px30_pin_ctrl
> +	},
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(pinctrl_px30) = {
> +	.name		= "rockchip_px30_pinctrl",
> +	.id		= UCLASS_PINCTRL,
> +	.of_match	= px30_pinctrl_ids,
> +	.priv_auto_alloc_size = sizeof(struct rockchip_pinctrl_priv),
> +	.ops		= &rockchip_pinctrl_ops,
> +#if !CONFIG_IS_ENABLED(OF_PLATDATA)
> +	.bind		= dm_scan_fdt_dev,
> +#endif
> +	.probe		= rockchip_pinctrl_probe,
> +};

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

* [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30
  2019-10-24 23:27 ` [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30 Heiko Stuebner
@ 2019-10-25  2:09   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:09 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> Add the glue code to allow the px30 variant of the Rockchip gmac
> to provide network functionality.
>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>

Reviewed-by: Kever Yang<kever.yang@rock-chips.com>

Thanks,
- Kever

> ---
>   drivers/net/gmac_rockchip.c | 69 +++++++++++++++++++++++++++++++++++++
>   1 file changed, 69 insertions(+)
>
> diff --git a/drivers/net/gmac_rockchip.c b/drivers/net/gmac_rockchip.c
> index 26a6121175..3f3e38a2c6 100644
> --- a/drivers/net/gmac_rockchip.c
> +++ b/drivers/net/gmac_rockchip.c
> @@ -14,6 +14,7 @@
>   #include <asm/arch-rockchip/periph.h>
>   #include <asm/arch-rockchip/clock.h>
>   #include <asm/arch-rockchip/hardware.h>
> +#include <asm/arch-rockchip/grf_px30.h>
>   #include <asm/arch-rockchip/grf_rk322x.h>
>   #include <asm/arch-rockchip/grf_rk3288.h>
>   #include <asm/arch-rockchip/grf_rk3328.h>
> @@ -72,6 +73,47 @@ static int gmac_rockchip_ofdata_to_platdata(struct udevice *dev)
>   	return designware_eth_ofdata_to_platdata(dev);
>   }
>   
> +static int px30_gmac_fix_mac_speed(struct dw_eth_dev *priv)
> +{
> +	struct px30_grf *grf;
> +	struct clk clk_speed;
> +	int speed, ret;
> +	enum {
> +		PX30_GMAC_SPEED_SHIFT = 0x2,
> +		PX30_GMAC_SPEED_MASK  = BIT(2),
> +		PX30_GMAC_SPEED_10M   = 0,
> +		PX30_GMAC_SPEED_100M  = BIT(2),
> +	};
> +
> +	ret = clk_get_by_name(priv->phydev->dev, "clk_mac_speed",
> +			      &clk_speed);
> +	if (ret)
> +		return ret;
> +
> +	switch (priv->phydev->speed) {
> +	case 10:
> +		speed = PX30_GMAC_SPEED_10M;
> +		ret = clk_set_rate(&clk_speed, 2500000);
> +		if (ret)
> +			return ret;
> +		break;
> +	case 100:
> +		speed = PX30_GMAC_SPEED_100M;
> +		ret = clk_set_rate(&clk_speed, 25000000);
> +		if (ret)
> +			return ret;
> +		break;
> +	default:
> +		debug("Unknown phy speed: %d\n", priv->phydev->speed);
> +		return -EINVAL;
> +	}
> +
> +	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
> +	rk_clrsetreg(&grf->mac_con1, PX30_GMAC_SPEED_MASK, speed);
> +
> +	return 0;
> +}
> +
>   static int rk3228_gmac_fix_mac_speed(struct dw_eth_dev *priv)
>   {
>   	struct rk322x_grf *grf;
> @@ -257,6 +299,22 @@ static int rv1108_set_rmii_speed(struct dw_eth_dev *priv)
>   	return 0;
>   }
>   
> +static void px30_gmac_set_to_rmii(struct gmac_rockchip_platdata *pdata)
> +{
> +	struct px30_grf *grf;
> +	enum {
> +		PX30_GMAC_PHY_INTF_SEL_SHIFT = 4,
> +		PX30_GMAC_PHY_INTF_SEL_MASK  = GENMASK(4, 6),
> +		PX30_GMAC_PHY_INTF_SEL_RMII  = BIT(6),
> +	};
> +
> +	grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
> +
> +	rk_clrsetreg(&grf->mac_con1,
> +		     PX30_GMAC_PHY_INTF_SEL_MASK,
> +		     PX30_GMAC_PHY_INTF_SEL_RMII);
> +}
> +
>   static void rk3228_gmac_set_to_rgmii(struct gmac_rockchip_platdata *pdata)
>   {
>   	struct rk322x_grf *grf;
> @@ -445,6 +503,10 @@ static int gmac_rockchip_probe(struct udevice *dev)
>   	ulong rate;
>   	int ret;
>   
> +	ret = clk_set_defaults(dev);
> +	if (ret)
> +		debug("%s clk_set_defaults failed %d\n", __func__, ret);
> +
>   	ret = clk_get_by_index(dev, 0, &clk);
>   	if (ret)
>   		return ret;
> @@ -569,6 +631,11 @@ const struct eth_ops gmac_rockchip_eth_ops = {
>   	.write_hwaddr		= designware_eth_write_hwaddr,
>   };
>   
> +const struct rk_gmac_ops px30_gmac_ops = {
> +	.fix_mac_speed = px30_gmac_fix_mac_speed,
> +	.set_to_rmii = px30_gmac_set_to_rmii,
> +};
> +
>   const struct rk_gmac_ops rk3228_gmac_ops = {
>   	.fix_mac_speed = rk3228_gmac_fix_mac_speed,
>   	.set_to_rgmii = rk3228_gmac_set_to_rgmii,
> @@ -600,6 +667,8 @@ const struct rk_gmac_ops rv1108_gmac_ops = {
>   };
>   
>   static const struct udevice_id rockchip_gmac_ids[] = {
> +	{ .compatible = "rockchip,px30-gmac",
> +	  .data = (ulong)&px30_gmac_ops },
>   	{ .compatible = "rockchip,rk3228-gmac",
>   	  .data = (ulong)&rk3228_gmac_ops },
>   	{ .compatible = "rockchip,rk3288-gmac",

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

* [U-Boot] [PATCH 06/12] rockchip: mkimage: add support for px30
  2019-10-24 23:27 ` [U-Boot] [PATCH 06/12] rockchip: mkimage: " Heiko Stuebner
@ 2019-10-25  2:09   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:09 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: Kever Yang <kever.yang@rock-chips.com>
>
> Add the table entry for px30 socs.
> The px30 has 10K of sram available.
>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>


Reviewed-by: Kever Yang<kever.yang@rock-chips.com>

Thanks,
- Kever

> ---
>   tools/rkcommon.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/tools/rkcommon.c b/tools/rkcommon.c
> index 831c2ad820..83df82e4b0 100644
> --- a/tools/rkcommon.c
> +++ b/tools/rkcommon.c
> @@ -67,6 +67,7 @@ struct spl_info {
>   };
>   
>   static struct spl_info spl_infos[] = {
> +	{ "px30", "RK33", 0x2800, false },
>   	{ "rk3036", "RK30", 0x1000, false },
>   	{ "rk3128", "RK31", 0x1800, false },
>   	{ "rk3188", "RK31", 0x8000 - 0x800, true },

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

* [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller
  2019-10-24 23:27 ` [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller Heiko Stuebner
@ 2019-10-25  2:10   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:10 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: Finley Xiao <finley.xiao@rock-chips.com>
>
> Newer Rockchip socs like the px30 use a different ip block to handle
> one-time-programmable memory, so add a misc driver for it as well.
>
> Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: Kever Yang<kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   drivers/misc/Kconfig        |   9 ++
>   drivers/misc/Makefile       |   1 +
>   drivers/misc/rockchip-otp.c | 176 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 186 insertions(+)
>   create mode 100644 drivers/misc/rockchip-otp.c
>
> diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
> index 8037b6ee2d..d68b24e6ec 100644
> --- a/drivers/misc/Kconfig
> +++ b/drivers/misc/Kconfig
> @@ -59,6 +59,15 @@ config ROCKCHIP_EFUSE
>   	  extended (by porting the read function from the Linux kernel sources)
>   	  to support other recent Rockchip devices.
>   
> +config ROCKCHIP_OTP
> +	bool "Rockchip OTP Support"
> +	depends on MISC
> +	help
> +	  Enable (read-only) access for the one-time-programmable memory block
> +	  found in Rockchip SoCs: accesses can either be made using byte
> +	  addressing and a length or through child-nodes that are generated
> +	  based on the e-fuse map retrieved from the DTS.
> +
>   config VEXPRESS_CONFIG
>   	bool "Enable support for Arm Versatile Express config bus"
>   	depends on MISC
> diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
> index 509c588582..b172567297 100644
> --- a/drivers/misc/Makefile
> +++ b/drivers/misc/Makefile
> @@ -52,6 +52,7 @@ obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
>   obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
>   obj-$(CONFIG_QFW) += qfw.o
>   obj-$(CONFIG_ROCKCHIP_EFUSE) += rockchip-efuse.o
> +obj-$(CONFIG_ROCKCHIP_OTP) += rockchip-otp.o
>   obj-$(CONFIG_SANDBOX) += swap_case.o
>   obj-$(CONFIG_SANDBOX) += syscon_sandbox.o misc_sandbox.o
>   obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
> diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c
> new file mode 100644
> index 0000000000..bdd443b3db
> --- /dev/null
> +++ b/drivers/misc/rockchip-otp.c
> @@ -0,0 +1,176 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <command.h>
> +#include <dm.h>
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +#include <misc.h>
> +
> +/* OTP Register Offsets */
> +#define OTPC_SBPI_CTRL			0x0020
> +#define OTPC_SBPI_CMD_VALID_PRE		0x0024
> +#define OTPC_SBPI_CS_VALID_PRE		0x0028
> +#define OTPC_SBPI_STATUS		0x002C
> +#define OTPC_USER_CTRL			0x0100
> +#define OTPC_USER_ADDR			0x0104
> +#define OTPC_USER_ENABLE		0x0108
> +#define OTPC_USER_QP			0x0120
> +#define OTPC_USER_Q			0x0124
> +#define OTPC_INT_STATUS			0x0304
> +#define OTPC_SBPI_CMD0_OFFSET		0x1000
> +#define OTPC_SBPI_CMD1_OFFSET		0x1004
> +
> +/* OTP Register bits and masks */
> +#define OTPC_USER_ADDR_MASK		GENMASK(31, 16)
> +#define OTPC_USE_USER			BIT(0)
> +#define OTPC_USE_USER_MASK		GENMASK(16, 16)
> +#define OTPC_USER_FSM_ENABLE		BIT(0)
> +#define OTPC_USER_FSM_ENABLE_MASK	GENMASK(16, 16)
> +#define OTPC_SBPI_DONE			BIT(1)
> +#define OTPC_USER_DONE			BIT(2)
> +
> +#define SBPI_DAP_ADDR			0x02
> +#define SBPI_DAP_ADDR_SHIFT		8
> +#define SBPI_DAP_ADDR_MASK		GENMASK(31, 24)
> +#define SBPI_CMD_VALID_MASK		GENMASK(31, 16)
> +#define SBPI_DAP_CMD_WRF		0xC0
> +#define SBPI_DAP_REG_ECC		0x3A
> +#define SBPI_ECC_ENABLE			0x00
> +#define SBPI_ECC_DISABLE		0x09
> +#define SBPI_ENABLE			BIT(0)
> +#define SBPI_ENABLE_MASK		GENMASK(16, 16)
> +
> +#define OTPC_TIMEOUT			10000
> +
> +struct rockchip_otp_platdata {
> +	void __iomem *base;
> +	unsigned long secure_conf_base;
> +	unsigned long otp_mask_base;
> +};
> +
> +static int rockchip_otp_wait_status(struct rockchip_otp_platdata *otp,
> +				    u32 flag)
> +{
> +	int delay = OTPC_TIMEOUT;
> +
> +	while (!(readl(otp->base + OTPC_INT_STATUS) & flag)) {
> +		udelay(1);
> +		delay--;
> +		if (delay <= 0) {
> +			printf("%s: wait init status timeout\n", __func__);
> +			return -ETIMEDOUT;
> +		}
> +	}
> +
> +	/* clean int status */
> +	writel(flag, otp->base + OTPC_INT_STATUS);
> +
> +	return 0;
> +}
> +
> +static int rockchip_otp_ecc_enable(struct rockchip_otp_platdata *otp,
> +				   bool enable)
> +{
> +	int ret = 0;
> +
> +	writel(SBPI_DAP_ADDR_MASK | (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT),
> +	       otp->base + OTPC_SBPI_CTRL);
> +
> +	writel(SBPI_CMD_VALID_MASK | 0x1, otp->base + OTPC_SBPI_CMD_VALID_PRE);
> +	writel(SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC,
> +	       otp->base + OTPC_SBPI_CMD0_OFFSET);
> +
> +	if (enable)
> +		writel(SBPI_ECC_ENABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
> +	else
> +		writel(SBPI_ECC_DISABLE, otp->base + OTPC_SBPI_CMD1_OFFSET);
> +
> +	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
> +
> +	ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
> +	if (ret < 0)
> +		printf("%s timeout during ecc_enable\n", __func__);
> +
> +	return ret;
> +}
> +
> +static int rockchip_px30_otp_read(struct udevice *dev, int offset,
> +				  void *buf, int size)
> +{
> +	struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
> +	u8 *buffer = buf;
> +	int ret = 0;
> +
> +	ret = rockchip_otp_ecc_enable(otp, false);
> +	if (ret < 0) {
> +		printf("%s rockchip_otp_ecc_enable err\n", __func__);
> +		return ret;
> +	}
> +
> +	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
> +	udelay(5);
> +	while (size--) {
> +		writel(offset++ | OTPC_USER_ADDR_MASK,
> +		       otp->base + OTPC_USER_ADDR);
> +		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
> +		       otp->base + OTPC_USER_ENABLE);
> +
> +		ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
> +		if (ret < 0) {
> +			printf("%s timeout during read setup\n", __func__);
> +			goto read_end;
> +		}
> +
> +		*buffer++ = readb(otp->base + OTPC_USER_Q);
> +	}
> +
> +read_end:
> +	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
> +
> +	return ret;
> +}
> +
> +static int rockchip_otp_read(struct udevice *dev, int offset,
> +			     void *buf, int size)
> +{
> +	return rockchip_px30_otp_read(dev, offset, buf, size);
> +}
> +
> +static const struct misc_ops rockchip_otp_ops = {
> +	.read = rockchip_otp_read,
> +};
> +
> +static int rockchip_otp_ofdata_to_platdata(struct udevice *dev)
> +{
> +	struct rockchip_otp_platdata *otp = dev_get_platdata(dev);
> +
> +	otp->base = dev_read_addr_ptr(dev);
> +
> +	return 0;
> +}
> +
> +static const struct udevice_id rockchip_otp_ids[] = {
> +	{
> +		.compatible = "rockchip,px30-otp",
> +		.data = (ulong)&rockchip_px30_otp_read,
> +	},
> +	{
> +		.compatible = "rockchip,rk3308-otp",
> +		.data = (ulong)&rockchip_px30_otp_read,
> +	},
> +	{}
> +};
> +
> +U_BOOT_DRIVER(rockchip_otp) = {
> +	.name = "rockchip_otp",
> +	.id = UCLASS_MISC,
> +	.of_match = rockchip_otp_ids,
> +	.ops = &rockchip_otp_ops,
> +	.ofdata_to_platdata = rockchip_otp_ofdata_to_platdata,
> +	.platdata_auto_alloc_size = sizeof(struct rockchip_otp_platdata),
> +};

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

* [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp
  2019-10-24 23:27 ` [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp Heiko Stuebner
@ 2019-10-25  2:11   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:11 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
>
> Newer Rockchip socs use a different ip block to handle one-time-
> programmable memory, so depending on what got enabled get the cpuid
> from either source.
>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
Reviewed-by: Kever Yang<kever.yang@rock-chips.com>

Thanks,
- Kever
> ---
>   arch/arm/mach-rockchip/misc.c | 7 ++++++-
>   1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-rockchip/misc.c b/arch/arm/mach-rockchip/misc.c
> index c0e4fdbc00..bed4317f7e 100644
> --- a/arch/arm/mach-rockchip/misc.c
> +++ b/arch/arm/mach-rockchip/misc.c
> @@ -57,13 +57,18 @@ int rockchip_cpuid_from_efuse(const u32 cpuid_offset,
>   			      const u32 cpuid_length,
>   			      u8 *cpuid)
>   {
> -#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
> +#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) || CONFIG_IS_ENABLED(ROCKCHIP_OTP)
>   	struct udevice *dev;
>   	int ret;
>   
>   	/* retrieve the device */
> +#if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE)
>   	ret = uclass_get_device_by_driver(UCLASS_MISC,
>   					  DM_GET_DRIVER(rockchip_efuse), &dev);
> +#elif CONFIG_IS_ENABLED(ROCKCHIP_OTP)
> +	ret = uclass_get_device_by_driver(UCLASS_MISC,
> +					  DM_GET_DRIVER(rockchip_otp), &dev);
> +#endif
>   	if (ret) {
>   		debug("%s: could not find efuse device\n", __func__);
>   		return -1;

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

* [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees
  2019-10-24 23:28 ` [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees Heiko Stuebner
@ 2019-10-25  2:39   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:39 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:28, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
>
> Add px30 related devicetrees synced from the Linux kernel.

The kernel dts should have been on kernel mainline, could you provide 
which commit

do you sync from?


Thanks,

- Kever

>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
> ---
>   arch/arm/dts/Makefile             |    3 +
>   arch/arm/dts/px30-evb-u-boot.dtsi |   81 ++
>   arch/arm/dts/px30-evb.dts         |  527 ++++++++
>   arch/arm/dts/px30.dtsi            | 2068 +++++++++++++++++++++++++++++
>   4 files changed, 2679 insertions(+)
>   create mode 100644 arch/arm/dts/px30-evb-u-boot.dtsi
>   create mode 100644 arch/arm/dts/px30-evb.dts
>   create mode 100644 arch/arm/dts/px30.dtsi
>
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index dbb062edda..04ddbfb11f 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -67,6 +67,9 @@ dtb-$(CONFIG_KIRKWOOD) += \
>   dtb-$(CONFIG_ARCH_OWL) += \
>   	bubblegum_96.dtb
>   
> +dtb-$(CONFIG_ROCKCHIP_PX30) += \
> +	px30-evb.dtb
> +
>   dtb-$(CONFIG_ROCKCHIP_RK3036) += \
>   	rk3036-sdk.dtb
>   
> diff --git a/arch/arm/dts/px30-evb-u-boot.dtsi b/arch/arm/dts/px30-evb-u-boot.dtsi
> new file mode 100644
> index 0000000000..3de9c7068e
> --- /dev/null
> +++ b/arch/arm/dts/px30-evb-u-boot.dtsi
> @@ -0,0 +1,81 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * (C) Copyright 2017 Rockchip Electronics Co., Ltd
> + */
> +
> +/ {
> +	aliases {
> +		mmc0 = &emmc;
> +		mmc1 = &sdmmc;
> +	};
> +
> +	chosen {
> +		u-boot,spl-boot-order = &emmc, &sdmmc;
> +	};
> +};
> +
> +&dmc {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&uart2 {
> +	clock-frequency = <24000000>;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&uart5 {
> +	clock-frequency = <24000000>;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&sdmmc {
> +	u-boot,dm-pre-reloc;
> +
> +	/* temporary till I find out why dma mode doesn't work */
> +	fifo-mode;
> +};
> +
> +&emmc {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&grf {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pmugrf {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&xin24m {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&cru {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pmucru {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&saradc {
> +	u-boot,dm-pre-reloc;
> +	status = "okay";
> +};
> +
> +&gpio0 {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&gpio1 {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&gpio2 {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&gpio3 {
> +	u-boot,dm-pre-reloc;
> +};
> diff --git a/arch/arm/dts/px30-evb.dts b/arch/arm/dts/px30-evb.dts
> new file mode 100644
> index 0000000000..089a7ade4e
> --- /dev/null
> +++ b/arch/arm/dts/px30-evb.dts
> @@ -0,0 +1,527 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
> + */
> +
> +/dts-v1/;
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include "px30.dtsi"
> +#include "px30-evb-u-boot.dtsi"
> +
> +/ {
> +	model = "Rockchip PX30 EVB";
> +	compatible = "rockchip,px30-evb", "rockchip,px30";
> +
> +	chosen {
> +		stdout-path = "serial5:115200n8";
> +	};
> +
> +	adc-keys {
> +		compatible = "adc-keys";
> +		io-channels = <&saradc 2>;
> +		io-channel-names = "buttons";
> +		keyup-threshold-microvolt = <1800000>;
> +		poll-interval = <100>;
> +
> +		esc-key {
> +			label = "esc";
> +			linux,code = <KEY_ESC>;
> +			press-threshold-microvolt = <1310000>;
> +		};
> +
> +		home-key {
> +			label = "home";
> +			linux,code = <KEY_HOME>;
> +			press-threshold-microvolt = <624000>;
> +		};
> +
> +		menu-key {
> +			label = "menu";
> +			linux,code = <KEY_MENU>;
> +			press-threshold-microvolt = <987000>;
> +		};
> +
> +		vol-down-key {
> +			label = "volume down";
> +			linux,code = <KEY_VOLUMEDOWN>;
> +			press-threshold-microvolt = <300000>;
> +		};
> +
> +		vol-up-key {
> +			label = "volume up";
> +			linux,code = <KEY_VOLUMEUP>;
> +			press-threshold-microvolt = <17000>;
> +		};
> +	};
> +
> +	backlight: backlight {
> +		compatible = "pwm-backlight";
> +		pwms = <&pwm1 0 25000 0>;
> +		power-supply = <&vcc3v3_lcd>;
> +	};
> +
> +	emmc_pwrseq: emmc-pwrseq {
> +		compatible = "mmc-pwrseq-emmc";
> +		pinctrl-0 = <&emmc_reset>;
> +		pinctrl-names = "default";
> +		reset-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
> +	};
> +
> +	sdio_pwrseq: sdio-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&wifi_enable_h>;
> +
> +		/*
> +		 * On the module itself this is one of these (depending
> +		 * on the actual card populated):
> +		 * - SDIO_RESET_L_WL_REG_ON
> +		 * - PDN (power down when low)
> +		 */
> +		reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; /* GPIO3_A4 */
> +	};
> +
> +	vcc5v0_sys: vccsys {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc5v0_sys";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +	};
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vdd_arm>;
> +};
> +
> +&cpu1 {
> +	cpu-supply = <&vdd_arm>;
> +};
> +
> +&cpu2 {
> +	cpu-supply = <&vdd_arm>;
> +};
> +
> +&cpu3 {
> +	cpu-supply = <&vdd_arm>;
> +};
> +
> +&display_subsystem {
> +	status = "okay";
> +};
> +
> +&dsi {
> +	status = "okay";
> +
> +	ports {
> +		mipi_out: port at 1 {
> +			reg = <1>;
> +
> +			mipi_out_panel: endpoint {
> +				remote-endpoint = <&mipi_in_panel>;
> +			};
> +		};
> +	};
> +
> +	panel at 0 {
> +		compatible = "sitronix,st7703";
> +		reg = <0>;
> +		backlight = <&backlight>;
> +		iovcc-supply = <&vcc_1v8>;
> +		vci-supply = <&vcc3v3_lcd>;
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <0>;
> +
> +				mipi_in_panel: endpoint {
> +					remote-endpoint = <&mipi_out_panel>;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&dsi_dphy {
> +	status = "okay";
> +};
> +
> +&emmc {
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	mmc-hs200-1_8v;
> +	non-removable;
> +	mmc-pwrseq = <&emmc_pwrseq>;
> +	vmmc-supply = <&vcc_3v0>;
> +	vqmmc-supply = <&vccio_flash>;
> +	status = "okay";
> +};
> +
> +&gmac {
> +	clock_in_out = "output";
> +	phy-supply = <&vcc_rmii>;
> +	snps,reset-gpio = <&gpio2 13 GPIO_ACTIVE_LOW>;
> +	snps,reset-active-low;
> +	snps,reset-delays-us = <0 50000 50000>;
> +	status = "okay";
> +};
> +
> +&i2c0 {
> +	status = "okay";
> +
> +	rk809: pmic at 20 {
> +		compatible = "rockchip,rk809";
> +		reg = <0x20>;
> +		interrupt-parent = <&gpio0>;
> +		interrupts = <7 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pmic_int>;
> +		rockchip,system-power-controller;
> +		wakeup-source;
> +		#clock-cells = <0>;
> +		clock-output-names = "xin32k";
> +
> +		vcc1-supply = <&vcc5v0_sys>;
> +		vcc2-supply = <&vcc5v0_sys>;
> +		vcc3-supply = <&vcc5v0_sys>;
> +		vcc4-supply = <&vcc5v0_sys>;
> +		vcc5-supply = <&vcc3v3_sys>;
> +		vcc6-supply = <&vcc3v3_sys>;
> +		vcc7-supply = <&vcc3v3_sys>;
> +		vcc8-supply = <&vcc3v3_sys>;
> +		vcc9-supply = <&vcc5v0_sys>;
> +
> +		regulators {
> +			vdd_log: DCDC_REG1 {
> +				regulator-name = "vdd_log";
> +				regulator-min-microvolt = <950000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-ramp-delay = <6001>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <950000>;
> +				};
> +			};
> +
> +			vdd_arm: DCDC_REG2 {
> +				regulator-name = "vdd_arm";
> +				regulator-min-microvolt = <950000>;
> +				regulator-max-microvolt = <1350000>;
> +				regulator-ramp-delay = <6001>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +					regulator-suspend-microvolt = <950000>;
> +				};
> +			};
> +
> +			vcc_ddr: DCDC_REG3 {
> +				regulator-name = "vcc_ddr";
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			vcc_3v0: vcc_rmii: DCDC_REG4 {
> +				regulator-name = "vcc_3v0";
> +				regulator-min-microvolt = <3000000>;
> +				regulator-max-microvolt = <3000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3000000>;
> +				};
> +			};
> +
> +			vcc3v3_sys: DCDC_REG5 {
> +				regulator-name = "vcc3v3_sys";
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3300000>;
> +				};
> +			};
> +
> +			vcc_1v0: LDO_REG1 {
> +				regulator-name = "vcc_1v0";
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <1000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1000000>;
> +				};
> +			};
> +
> +			vcc_1v8: vccio_flash: vccio_sdio: LDO_REG2 {
> +				regulator-name = "vcc_1v8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vdd_1v0: LDO_REG3 {
> +				regulator-name = "vdd_1v0";
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <1000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1000000>;
> +				};
> +			};
> +
> +			vcc3v0_pmu: LDO_REG4 {
> +				regulator-name = "vcc3v0_pmu";
> +				regulator-min-microvolt = <3000000>;
> +				regulator-max-microvolt = <3000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3000000>;
> +				};
> +			};
> +
> +			vccio_sd: LDO_REG5 {
> +				regulator-name = "vccio_sd";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3300000>;
> +				};
> +			};
> +
> +			vcc_sd: LDO_REG6 {
> +				regulator-name = "vcc_sd";
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <3300000>;
> +				};
> +			};
> +
> +			vcc2v8_dvp: LDO_REG7 {
> +				regulator-name = "vcc2v8_dvp";
> +				regulator-min-microvolt = <2800000>;
> +				regulator-max-microvolt = <2800000>;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +					regulator-suspend-microvolt = <2800000>;
> +				};
> +			};
> +
> +			vcc1v8_dvp: LDO_REG8 {
> +				regulator-name = "vcc1v8_dvp";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +					regulator-suspend-microvolt = <1800000>;
> +				};
> +			};
> +
> +			vcc1v5_dvp: LDO_REG9 {
> +				regulator-name = "vcc1v5_dvp";
> +				regulator-min-microvolt = <1500000>;
> +				regulator-max-microvolt = <1500000>;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +					regulator-suspend-microvolt = <1500000>;
> +				};
> +			};
> +
> +			vcc3v3_lcd: SWITCH_REG1 {
> +				regulator-name = "vcc3v3_lcd";
> +				regulator-boot-on;
> +			};
> +
> +			vcc5v0_host: SWITCH_REG2 {
> +				regulator-name = "vcc5v0_host";
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +		};
> +	};
> +};
> +
> +&i2s1_2ch {
> +	status = "okay";
> +};
> +
> +&io_domains {
> +	status = "okay";
> +
> +	vccio1-supply = <&vccio_sdio>;
> +	vccio2-supply = <&vccio_sd>;
> +	vccio3-supply = <&vcc_3v0>;
> +	vccio4-supply = <&vcc3v0_pmu>;
> +	vccio5-supply = <&vcc_3v0>;
> +	vccio6-supply = <&vccio_flash>;
> +};
> +
> +&pinctrl {
> +	headphone {
> +		hp_det: hp-det {
> +			rockchip,pins =
> +				<2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_down>;
> +		};
> +	};
> +
> +	emmc {
> +		emmc_reset: emmc-reset {
> +			rockchip,pins = <1 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
> +	pmic {
> +		pmic_int: pmic_int {
> +			rockchip,pins =
> +				<0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
> +		};
> +
> +		soc_slppin_gpio: soc_slppin_gpio {
> +			rockchip,pins =
> +				<0 RK_PA4 RK_FUNC_GPIO &pcfg_output_low>;
> +		};
> +
> +		soc_slppin_slp: soc_slppin_slp {
> +			rockchip,pins =
> +				<0 RK_PA4 1 &pcfg_pull_none>;
> +		};
> +
> +		soc_slppin_rst: soc_slppin_rst {
> +			rockchip,pins =
> +				<0 RK_PA4 2 &pcfg_pull_none>;
> +		};
> +	};
> +
> +	sdio-pwrseq {
> +		wifi_enable_h: wifi-enable-h {
> +			rockchip,pins =
> +				<0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +};
> +
> +&pmu_io_domains {
> +	status = "okay";
> +
> +	pmuio1-supply = <&vcc3v0_pmu>;
> +	pmuio2-supply = <&vcc3v0_pmu>;
> +};
> +
> +&pwm1 {
> +	status = "okay";
> +};
> +
> +&saradc {
> +	vref-supply = <&vcc_1v8>;
> +	status = "okay";
> +};
> +
> +&sdmmc {
> +	bus-width = <4>;
> +	cap-mmc-highspeed;
> +	cap-sd-highspeed;
> +	card-detect-delay = <800>;
> +	sd-uhs-sdr12;
> +	sd-uhs-sdr25;
> +	sd-uhs-sdr50;
> +	sd-uhs-sdr104;
> +	vmmc-supply = <&vcc_sd>;
> +	vqmmc-supply = <&vccio_sd>;
> +	status = "okay";
> +};
> +
> +&sdio {
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	keep-power-in-suspend;
> +	non-removable;
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +	sd-uhs-sdr104;
> +	status = "okay";
> +};
> +
> +&uart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart1_xfer &uart1_cts>;
> +	status = "okay";
> +};
> +
> +&uart5 {
> +	status = "okay";
> +};
> +
> +&usb20_otg {
> +	status = "okay";
> +};
> +
> +&usb_host0_ehci {
> +	status = "okay";
> +};
> +
> +&usb_host0_ohci {
> +	status = "okay";
> +};
> +
> +&vopb {
> +	status = "okay";
> +};
> +
> +&vopb_mmu {
> +	status = "okay";
> +};
> +
> +&vopl {
> +	status = "okay";
> +};
> +
> +&vopl_mmu {
> +	status = "okay";
> +};
> diff --git a/arch/arm/dts/px30.dtsi b/arch/arm/dts/px30.dtsi
> new file mode 100644
> index 0000000000..0d2325a77f
> --- /dev/null
> +++ b/arch/arm/dts/px30.dtsi
> @@ -0,0 +1,2068 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
> + */
> +
> +#include <dt-bindings/clock/px30-cru.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/pinctrl/rockchip.h>
> +#include <dt-bindings/power/px30-power.h>
> +#include <dt-bindings/soc/rockchip,boot-mode.h>
> +
> +/ {
> +	compatible = "rockchip,px30";
> +
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		ethernet0 = &gmac;
> +		i2c0 = &i2c0;
> +		i2c1 = &i2c1;
> +		i2c2 = &i2c2;
> +		i2c3 = &i2c3;
> +		serial0 = &uart0;
> +		serial1 = &uart1;
> +		serial2 = &uart2;
> +		serial3 = &uart3;
> +		serial4 = &uart4;
> +		serial5 = &uart5;
> +		spi0 = &spi0;
> +		spi1 = &spi1;
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		cpu0: cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35";
> +			reg = <0x0 0x0>;
> +			enable-method = "psci";
> +			clocks = <&cru ARMCLK>;
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
> +			dynamic-power-coefficient = <90>;
> +			operating-points-v2 = <&cpu0_opp_table>;
> +		};
> +
> +		cpu1: cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35";
> +			reg = <0x0 0x1>;
> +			enable-method = "psci";
> +			clocks = <&cru ARMCLK>;
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
> +			dynamic-power-coefficient = <90>;
> +			operating-points-v2 = <&cpu0_opp_table>;
> +		};
> +
> +		cpu2: cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35";
> +			reg = <0x0 0x2>;
> +			enable-method = "psci";
> +			clocks = <&cru ARMCLK>;
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
> +			dynamic-power-coefficient = <90>;
> +			operating-points-v2 = <&cpu0_opp_table>;
> +		};
> +
> +		cpu3: cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35";
> +			reg = <0x0 0x3>;
> +			enable-method = "psci";
> +			clocks = <&cru ARMCLK>;
> +			#cooling-cells = <2>;
> +			cpu-idle-states = <&CPU_SLEEP &CLUSTER_SLEEP>;
> +			dynamic-power-coefficient = <90>;
> +			operating-points-v2 = <&cpu0_opp_table>;
> +		};
> +
> +		idle-states {
> +			entry-method = "psci";
> +
> +			CPU_SLEEP: cpu-sleep {
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				arm,psci-suspend-param = <0x0010000>;
> +				entry-latency-us = <120>;
> +				exit-latency-us = <250>;
> +				min-residency-us = <900>;
> +			};
> +
> +			CLUSTER_SLEEP: cluster-sleep {
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				arm,psci-suspend-param = <0x1010000>;
> +				entry-latency-us = <400>;
> +				exit-latency-us = <500>;
> +				min-residency-us = <2000>;
> +			};
> +		};
> +	};
> +
> +	cpu0_opp_table: cpu0-opp-table {
> +		compatible = "operating-points-v2";
> +		opp-shared;
> +
> +		opp-408000000 {
> +			opp-hz = /bits/ 64 <408000000>;
> +			opp-microvolt = <950000 950000 1350000>;
> +			clock-latency-ns = <40000>;
> +			opp-suspend;
> +		};
> +		opp-600000000 {
> +			opp-hz = /bits/ 64 <600000000>;
> +			opp-microvolt = <950000 950000 1350000>;
> +			clock-latency-ns = <40000>;
> +		};
> +		opp-816000000 {
> +			opp-hz = /bits/ 64 <816000000>;
> +			opp-microvolt = <1050000 1050000 1350000>;
> +			clock-latency-ns = <40000>;
> +		};
> +		opp-1008000000 {
> +			opp-hz = /bits/ 64 <1008000000>;
> +			opp-microvolt = <1175000 1175000 1350000>;
> +			clock-latency-ns = <40000>;
> +		};
> +		opp-1200000000 {
> +			opp-hz = /bits/ 64 <1200000000>;
> +			opp-microvolt = <1300000 1300000 1350000>;
> +			clock-latency-ns = <40000>;
> +		};
> +		opp-1296000000 {
> +			opp-hz = /bits/ 64 <1296000000>;
> +			opp-microvolt = <1350000 1350000 1350000>;
> +			clock-latency-ns = <40000>;
> +		};
> +	};
> +
> +	arm-pmu {
> +		compatible = "arm,cortex-a53-pmu";
> +		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
> +	};
> +
> +	dmc: dmc {
> +		compatible = "rockchip,px30-dmc", "syscon";
> +		reg = <0x0 0xff2a0000 0x0 0x1000>;
> +	};
> +
> +	display_subsystem: display-subsystem {
> +		compatible = "rockchip,display-subsystem";
> +		ports = <&vopb_out>, <&vopl_out>;
> +		status = "disabled";
> +	};
> +
> +	gmac_clkin: external-gmac-clock {
> +		compatible = "fixed-clock";
> +		clock-frequency = <50000000>;
> +		clock-output-names = "gmac_clkin";
> +		#clock-cells = <0>;
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-1.0";
> +		method = "smc";
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	xin24m: xin24m {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +		clock-output-names = "xin24m";
> +	};
> +
> +	pmu: power-management at ff000000 {
> +		compatible = "rockchip,px30-pmu", "syscon", "simple-mfd";
> +		reg = <0x0 0xff000000 0x0 0x1000>;
> +
> +		power: power-controller {
> +			compatible = "rockchip,px30-power-controller";
> +			#power-domain-cells = <1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* These power domains are grouped by VD_LOGIC */
> +			pd_usb at PX30_PD_USB {
> +				reg = <PX30_PD_USB>;
> +				clocks = <&cru HCLK_HOST>,
> +					 <&cru HCLK_OTG>,
> +					 <&cru SCLK_OTG_ADP>;
> +				pm_qos = <&qos_usb_host>, <&qos_usb_otg>;
> +			};
> +			pd_sdcard at PX30_PD_SDCARD {
> +				reg = <PX30_PD_SDCARD>;
> +				clocks = <&cru HCLK_SDMMC>,
> +					 <&cru SCLK_SDMMC>;
> +				pm_qos = <&qos_sdmmc>;
> +			};
> +			pd_gmac at PX30_PD_GMAC {
> +				reg = <PX30_PD_GMAC>;
> +				clocks = <&cru ACLK_GMAC>,
> +					 <&cru PCLK_GMAC>,
> +					 <&cru SCLK_MAC_REF>,
> +					 <&cru SCLK_GMAC_RX_TX>;
> +				pm_qos = <&qos_gmac>;
> +			};
> +			pd_mmc_nand at PX30_PD_MMC_NAND {
> +				reg = <PX30_PD_MMC_NAND>;
> +				clocks =  <&cru HCLK_NANDC>,
> +					  <&cru HCLK_EMMC>,
> +					  <&cru HCLK_SDIO>,
> +					  <&cru HCLK_SFC>,
> +					  <&cru SCLK_EMMC>,
> +					  <&cru SCLK_NANDC>,
> +					  <&cru SCLK_SDIO>,
> +					  <&cru SCLK_SFC>;
> +				pm_qos = <&qos_emmc>, <&qos_nand>,
> +					 <&qos_sdio>, <&qos_sfc>;
> +			};
> +			pd_vpu at PX30_PD_VPU {
> +				reg = <PX30_PD_VPU>;
> +				clocks = <&cru ACLK_VPU>,
> +					 <&cru HCLK_VPU>,
> +					 <&cru SCLK_CORE_VPU>;
> +				pm_qos = <&qos_vpu>, <&qos_vpu_r128>;
> +			};
> +			pd_vo at PX30_PD_VO {
> +				reg = <PX30_PD_VO>;
> +				clocks = <&cru ACLK_RGA>,
> +					 <&cru ACLK_VOPB>,
> +					 <&cru ACLK_VOPL>,
> +					 <&cru DCLK_VOPB>,
> +					 <&cru DCLK_VOPL>,
> +					 <&cru HCLK_RGA>,
> +					 <&cru HCLK_VOPB>,
> +					 <&cru HCLK_VOPL>,
> +					 <&cru PCLK_MIPI_DSI>,
> +					 <&cru SCLK_RGA_CORE>,
> +					 <&cru SCLK_VOPB_PWM>;
> +				pm_qos = <&qos_rga_rd>, <&qos_rga_wr>,
> +					 <&qos_vop_m0>, <&qos_vop_m1>;
> +			};
> +			pd_vi at PX30_PD_VI {
> +				reg = <PX30_PD_VI>;
> +				clocks = <&cru ACLK_CIF>,
> +					 <&cru ACLK_ISP>,
> +					 <&cru HCLK_CIF>,
> +					 <&cru HCLK_ISP>,
> +					 <&cru SCLK_ISP>;
> +				pm_qos = <&qos_isp_128>, <&qos_isp_rd>,
> +					 <&qos_isp_wr>, <&qos_isp_m1>,
> +					 <&qos_vip>;
> +			};
> +			pd_gpu at PX30_PD_GPU {
> +				reg = <PX30_PD_GPU>;
> +				clocks = <&cru SCLK_GPU>;
> +				pm_qos = <&qos_gpu>;
> +			};
> +		};
> +	};
> +
> +	pmugrf: syscon at ff010000 {
> +		compatible = "rockchip,px30-pmugrf", "syscon", "simple-mfd";
> +		reg = <0x0 0xff010000 0x0 0x1000>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		pmu_io_domains: io-domains {
> +			compatible = "rockchip,px30-pmu-io-voltage-domain";
> +			status = "disabled";
> +		};
> +
> +		reboot-mode {
> +			compatible = "syscon-reboot-mode";
> +			offset = <0x200>;
> +			mode-bootloader = <BOOT_BL_DOWNLOAD>;
> +			mode-fastboot = <BOOT_FASTBOOT>;
> +			mode-loader = <BOOT_BL_DOWNLOAD>;
> +			mode-normal = <BOOT_NORMAL>;
> +			mode-recovery = <BOOT_RECOVERY>;
> +		};
> +	};
> +
> +	uart0: serial at ff030000 {
> +		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
> +		reg = <0x0 0xff030000 0x0 0x100>;
> +		interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>;
> +		clock-names = "baudclk", "apb_pclk";
> +		dmas = <&dmac 0>, <&dmac 1>;
> +		dma-names = "tx", "rx";
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
> +		status = "disabled";
> +	};
> +
> +	i2s1_2ch: i2s at ff070000 {
> +		compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
> +		reg = <0x0 0xff070000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_I2S1>, <&cru HCLK_I2S1>;
> +		clock-names = "i2s_clk", "i2s_hclk";
> +		dmas = <&dmac 18>, <&dmac 19>;
> +		dma-names = "tx", "rx";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2s1_2ch_sclk &i2s1_2ch_lrck
> +			     &i2s1_2ch_sdi &i2s1_2ch_sdo>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	i2s2_2ch: i2s at ff080000 {
> +		compatible = "rockchip,px30-i2s", "rockchip,rk3066-i2s";
> +		reg = <0x0 0xff080000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_I2S2>, <&cru HCLK_I2S2>;
> +		clock-names = "i2s_clk", "i2s_hclk";
> +		dmas = <&dmac 20>, <&dmac 21>;
> +		dma-names = "tx", "rx";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2s2_2ch_sclk &i2s2_2ch_lrck
> +			     &i2s2_2ch_sdi &i2s2_2ch_sdo>;
> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	gic: interrupt-controller at ff131000 {
> +		compatible = "arm,gic-400";
> +		#interrupt-cells = <3>;
> +		#address-cells = <0>;
> +		interrupt-controller;
> +		reg = <0x0 0xff131000 0 0x1000>,
> +		      <0x0 0xff132000 0 0x2000>,
> +		      <0x0 0xff134000 0 0x2000>,
> +		      <0x0 0xff136000 0 0x2000>;
> +		interrupts = <GIC_PPI 9
> +		      (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +	};
> +
> +	grf: syscon at ff140000 {
> +		compatible = "rockchip,px30-grf", "syscon", "simple-mfd";
> +		reg = <0x0 0xff140000 0x0 0x1000>;
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		io_domains: io-domains {
> +			compatible = "rockchip,px30-io-voltage-domain";
> +			status = "disabled";
> +		};
> +	};
> +
> +	uart1: serial at ff158000 {
> +		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
> +		reg = <0x0 0xff158000 0x0 0x100>;
> +		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
> +		clock-names = "baudclk", "apb_pclk";
> +		dmas = <&dmac 2>, <&dmac 3>;
> +		dma-names = "tx", "rx";
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart1_xfer &uart1_cts &uart1_rts>;
> +		status = "disabled";
> +	};
> +
> +	uart2: serial at ff160000 {
> +		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
> +		reg = <0x0 0xff160000 0x0 0x100>;
> +		interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
> +		clock-names = "baudclk", "apb_pclk";
> +		dmas = <&dmac 4>, <&dmac 5>;
> +		dma-names = "tx", "rx";
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart2m0_xfer>;
> +		status = "disabled";
> +	};
> +
> +	uart3: serial at ff168000 {
> +		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
> +		reg = <0x0 0xff168000 0x0 0x100>;
> +		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>;
> +		clock-names = "baudclk", "apb_pclk";
> +		dmas = <&dmac 6>, <&dmac 7>;
> +		dma-names = "tx", "rx";
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart3m1_xfer &uart3m1_cts &uart3m1_rts>;
> +		status = "disabled";
> +	};
> +
> +	uart4: serial at ff170000 {
> +		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
> +		reg = <0x0 0xff170000 0x0 0x100>;
> +		interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>;
> +		clock-names = "baudclk", "apb_pclk";
> +		dmas = <&dmac 8>, <&dmac 9>;
> +		dma-names = "tx", "rx";
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart4_xfer &uart4_cts &uart4_rts>;
> +		status = "disabled";
> +	};
> +
> +	uart5: serial at ff178000 {
> +		compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
> +		reg = <0x0 0xff178000 0x0 0x100>;
> +		interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>;
> +		clock-names = "baudclk", "apb_pclk";
> +		dmas = <&dmac 10>, <&dmac 11>;
> +		dma-names = "tx", "rx";
> +		reg-shift = <2>;
> +		reg-io-width = <4>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&uart5_xfer &uart5_cts &uart5_rts>;
> +		status = "disabled";
> +	};
> +
> +	i2c0: i2c at ff180000 {
> +		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
> +		reg = <0x0 0xff180000 0x0 0x1000>;
> +		clocks =  <&cru SCLK_I2C0>, <&cru PCLK_I2C0>;
> +		clock-names = "i2c", "pclk";
> +		interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2c0_xfer>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	i2c1: i2c at ff190000 {
> +		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
> +		reg = <0x0 0xff190000 0x0 0x1000>;
> +		clocks = <&cru SCLK_I2C1>, <&cru PCLK_I2C1>;
> +		clock-names = "i2c", "pclk";
> +		interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2c1_xfer>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	i2c2: i2c at ff1a0000 {
> +		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
> +		reg = <0x0 0xff1a0000 0x0 0x1000>;
> +		clocks = <&cru SCLK_I2C2>, <&cru PCLK_I2C2>;
> +		clock-names = "i2c", "pclk";
> +		interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2c2_xfer>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	i2c3: i2c at ff1b0000 {
> +		compatible = "rockchip,px30-i2c", "rockchip,rk3399-i2c";
> +		reg = <0x0 0xff1b0000 0x0 0x1000>;
> +		clocks = <&cru SCLK_I2C3>, <&cru PCLK_I2C3>;
> +		clock-names = "i2c", "pclk";
> +		interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&i2c3_xfer>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	spi0: spi at ff1d0000 {
> +		compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
> +		reg = <0x0 0xff1d0000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
> +		clock-names = "spiclk", "apb_pclk";
> +		dmas = <&dmac 12>, <&dmac 13>;
> +		dma-names = "tx", "rx";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&spi0_clk &spi0_csn &spi0_miso &spi0_mosi>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	spi1: spi at ff1d8000 {
> +		compatible = "rockchip,px30-spi", "rockchip,rk3066-spi";
> +		reg = <0x0 0xff1d8000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>;
> +		clock-names = "spiclk", "apb_pclk";
> +		dmas = <&dmac 14>, <&dmac 15>;
> +		dma-names = "tx", "rx";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&spi1_clk &spi1_csn0 &spi1_csn1 &spi1_miso &spi1_mosi>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	wdt: watchdog at ff1e0000 {
> +		compatible = "snps,dw-wdt";
> +		reg = <0x0 0xff1e0000 0x0 0x100>;
> +		clocks = <&cru PCLK_WDT_NS>;
> +		interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
> +		status = "disabled";
> +	};
> +
> +	pwm0: pwm at ff200000 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff200000 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm0_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm1: pwm at ff200010 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff200010 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm1_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm2: pwm at ff200020 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff200020 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm2_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm3: pwm at ff200030 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff200030 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM0>, <&cru PCLK_PWM0>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm3_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm4: pwm at ff208000 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff208000 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm4_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm5: pwm at ff208010 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff208010 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm5_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm6: pwm at ff208020 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff208020 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm6_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	pwm7: pwm at ff208030 {
> +		compatible = "rockchip,px30-pwm", "rockchip,rk3328-pwm";
> +		reg = <0x0 0xff208030 0x0 0x10>;
> +		clocks = <&cru SCLK_PWM1>, <&cru PCLK_PWM1>;
> +		clock-names = "pwm", "pclk";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pwm7_pin>;
> +		#pwm-cells = <3>;
> +		status = "disabled";
> +	};
> +
> +	rktimer: timer at ff210000 {
> +		compatible = "rockchip,px30-timer", "rockchip,rk3288-timer";
> +		reg = <0x0 0xff210000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru PCLK_TIMER>, <&cru SCLK_TIMER0>;
> +		clock-names = "pclk", "timer";
> +	};
> +
> +	amba {
> +		compatible = "simple-bus";
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		dmac: dmac at ff240000 {
> +			compatible = "arm,pl330", "arm,primecell";
> +			reg = <0x0 0xff240000 0x0 0x4000>;
> +			interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru ACLK_DMAC>;
> +			clock-names = "apb_pclk";
> +			#dma-cells = <1>;
> +		};
> +	};
> +
> +	saradc: saradc at ff288000 {
> +		compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc";
> +		reg = <0x0 0xff288000 0x0 0x100>;
> +		interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
> +		#io-channel-cells = <1>;
> +		clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>;
> +		clock-names = "saradc", "apb_pclk";
> +		resets = <&cru SRST_SARADC_P>;
> +		reset-names = "saradc-apb";
> +		status = "disabled";
> +	};
> +
> +	otp: nvmem at ff290000 {
> +		compatible = "rockchip,px30-otp";
> +		reg = <0x0 0xff290000 0x0 0x4000>;
> +		clocks = <&cru SCLK_OTP_USR>, <&cru PCLK_OTP_NS>,
> +			 <&cru PCLK_OTP_PHY>;
> +		clock-names = "otp", "apb_pclk", "phy";
> +		resets = <&cru SRST_OTP_PHY>;
> +		reset-names = "phy";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		/* Data cells */
> +		cpu_id: id at 7 {
> +			reg = <0x07 0x10>;
> +		};
> +		cpu_leakage: cpu-leakage at 17 {
> +			reg = <0x17 0x1>;
> +		};
> +		performance: performance at 1e {
> +			reg = <0x1e 0x1>;
> +			bits = <4 3>;
> +		};
> +	};
> +
> +	cru: clock-controller at ff2b0000 {
> +		compatible = "rockchip,px30-cru";
> +		reg = <0x0 0xff2b0000 0x0 0x1000>;
> +		clocks = <&xin24m>, <&pmucru PLL_GPLL>;
> +		clock-names = "xin24m", "gpll";
> +		rockchip,grf = <&grf>;
> +		#clock-cells = <1>;
> +		#reset-cells = <1>;
> +	};
> +
> +	pmucru: clock-controller at ff2bc000 {
> +		compatible = "rockchip,px30-pmucru";
> +		reg = <0x0 0xff2bc000 0x0 0x1000>;
> +		clocks = <&xin24m>;
> +		clock-names = "xin24m";
> +		rockchip,grf = <&grf>;
> +		#clock-cells = <1>;
> +		#reset-cells = <1>;
> +	};
> +
> +	dsi_dphy: phy at ff2e0000 {
> +		compatible = "rockchip,px30-dsi-dphy";
> +		reg = <0x0 0xff2e0000 0x0 0x10000>;
> +		clocks = <&pmucru SCLK_MIPIDSIPHY_REF>, <&cru PCLK_MIPIDSIPHY>;
> +		clock-names = "ref", "pclk";
> +		#clock-cells = <0>;
> +		resets = <&cru SRST_MIPIDSIPHY_P>;
> +		reset-names = "apb";
> +		#phy-cells = <0>;
> +		power-domains = <&power PX30_PD_VO>;
> +		status = "disabled";
> +	};
> +
> +	usb20_otg: usb at ff300000 {
> +		compatible = "rockchip,px30-usb", "rockchip,rk3066-usb",
> +			     "snps,dwc2";
> +		reg = <0x0 0xff300000 0x0 0x40000>;
> +		interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_OTG>;
> +		clock-names = "otg";
> +		dr_mode = "otg";
> +		g-np-tx-fifo-size = <16>;
> +		g-rx-fifo-size = <280>;
> +		g-tx-fifo-size = <256 128 128 64 32 16>;
> +		g-use-dma;
> +		power-domains = <&power PX30_PD_USB>;
> +		status = "disabled";
> +	};
> +
> +	usb_host0_ehci: usb at ff340000 {
> +		compatible = "generic-ehci";
> +		reg = <0x0 0xff340000 0x0 0x10000>;
> +		interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_HOST>;
> +		clock-names = "usbhost";
> +		power-domains = <&power PX30_PD_USB>;
> +		status = "disabled";
> +	};
> +
> +	usb_host0_ohci: usb at ff350000 {
> +		compatible = "generic-ohci";
> +		reg = <0x0 0xff350000 0x0 0x10000>;
> +		interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_HOST>;
> +		clock-names = "usbhost";
> +		power-domains = <&power PX30_PD_USB>;
> +		status = "disabled";
> +	};
> +
> +	gmac: ethernet at ff360000 {
> +		compatible = "rockchip,px30-gmac";
> +		reg = <0x0 0xff360000 0x0 0x10000>;
> +		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "macirq";
> +		clocks = <&cru SCLK_GMAC>, <&cru SCLK_GMAC_RX_TX>,
> +			 <&cru SCLK_GMAC_RX_TX>, <&cru SCLK_MAC_REF>,
> +			 <&cru SCLK_MAC_REFOUT>, <&cru ACLK_GMAC>,
> +			 <&cru PCLK_GMAC>, <&cru SCLK_GMAC_RMII>;
> +		clock-names = "stmmaceth", "mac_clk_rx",
> +			      "mac_clk_tx", "clk_mac_ref",
> +			      "clk_mac_refout", "aclk_mac",
> +			      "pclk_mac", "clk_mac_speed";
> +		rockchip,grf = <&grf>;
> +		phy-mode = "rmii";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
> +		power-domains = <&power PX30_PD_GMAC>;
> +		resets = <&cru SRST_GMAC_A>;
> +		reset-names = "stmmaceth";
> +		status = "disabled";
> +	};
> +
> +	sdmmc: dwmmc at ff370000 {
> +		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
> +		reg = <0x0 0xff370000 0x0 0x4000>;
> +		interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
> +			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
> +		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
> +		fifo-depth = <0x100>;
> +		max-frequency = <150000000>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_det &sdmmc_bus4>;
> +		power-domains = <&power PX30_PD_SDCARD>;
> +		status = "disabled";
> +	};
> +
> +	sdio: dwmmc at ff380000 {
> +		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
> +		reg = <0x0 0xff380000 0x0 0x4000>;
> +		interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
> +			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
> +		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
> +		fifo-depth = <0x100>;
> +		max-frequency = <150000000>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&sdio_bus4 &sdio_cmd &sdio_clk>;
> +		power-domains = <&power PX30_PD_MMC_NAND>;
> +		status = "disabled";
> +	};
> +
> +	emmc: dwmmc at ff390000 {
> +		compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
> +		reg = <0x0 0xff390000 0x0 0x4000>;
> +		interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
> +			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
> +		clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
> +		fifo-depth = <0x100>;
> +		max-frequency = <150000000>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
> +		power-domains = <&power PX30_PD_MMC_NAND>;
> +		status = "disabled";
> +	};
> +
> +	dsi: dsi at ff450000 {
> +		compatible = "rockchip,px30-mipi-dsi";
> +		reg = <0x0 0xff450000 0x0 0x10000>;
> +		interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru PCLK_MIPI_DSI>, <&dsi_dphy>;
> +		clock-names = "pclk", "pll";
> +		resets = <&cru SRST_MIPIDSI_HOST_P>;
> +		reset-names = "apb";
> +		phys = <&dsi_dphy>;
> +		phy-names = "dphy";
> +		power-domains = <&power PX30_PD_VO>;
> +		rockchip,grf = <&grf>;
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +		status = "disabled";
> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <0>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +
> +				dsi_in_vopb: endpoint at 0 {
> +					reg = <0>;
> +					remote-endpoint = <&vopb_out_dsi>;
> +				};
> +
> +				dsi_in_vopl: endpoint at 1 {
> +					reg = <1>;
> +					remote-endpoint = <&vopl_out_dsi>;
> +				};
> +			};
> +		};
> +	};
> +
> +	vopb: vop at ff460000 {
> +		compatible = "rockchip,px30-vop-big";
> +		reg = <0x0 0xff460000 0x0 0xefc>;
> +		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_VOPB>, <&cru DCLK_VOPB>,
> +			 <&cru HCLK_VOPB>;
> +		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
> +		resets = <&cru SRST_VOPB_A>, <&cru SRST_VOPB_H>, <&cru SRST_VOPB>;
> +		reset-names = "axi", "ahb", "dclk";
> +		iommus = <&vopb_mmu>;
> +		power-domains = <&power PX30_PD_VO>;
> +		rockchip,grf = <&grf>;
> +		status = "disabled";
> +
> +		vopb_out: port {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			vopb_out_dsi: endpoint at 0 {
> +				reg = <0>;
> +				remote-endpoint = <&dsi_in_vopb>;
> +			};
> +		};
> +	};
> +
> +	vopb_mmu: iommu at ff460f00 {
> +		compatible = "rockchip,iommu";
> +		reg = <0x0 0xff460f00 0x0 0x100>;
> +		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "vopb_mmu";
> +		clocks = <&cru ACLK_VOPB>, <&cru HCLK_VOPB>;
> +		clock-names = "aclk", "iface";
> +		power-domains = <&power PX30_PD_VO>;
> +		#iommu-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	vopl: vop at ff470000 {
> +		compatible = "rockchip,px30-vop-lit";
> +		reg = <0x0 0xff470000 0x0 0xefc>;
> +		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru ACLK_VOPL>, <&cru DCLK_VOPL>,
> +			 <&cru HCLK_VOPL>;
> +		clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
> +		resets = <&cru SRST_VOPL_A>, <&cru SRST_VOPL_H>, <&cru SRST_VOPL>;
> +		reset-names = "axi", "ahb", "dclk";
> +		iommus = <&vopl_mmu>;
> +		power-domains = <&power PX30_PD_VO>;
> +		rockchip,grf = <&grf>;
> +		status = "disabled";
> +
> +		vopl_out: port {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			vopl_out_dsi: endpoint at 0 {
> +				reg = <0>;
> +				remote-endpoint = <&dsi_in_vopl>;
> +			};
> +		};
> +	};
> +
> +	vopl_mmu: iommu at ff470f00 {
> +		compatible = "rockchip,iommu";
> +		reg = <0x0 0xff470f00 0x0 0x100>;
> +		interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "vopl_mmu";
> +		clocks = <&cru ACLK_VOPL>, <&cru HCLK_VOPL>;
> +		clock-names = "aclk", "iface";
> +		power-domains = <&power PX30_PD_VO>;
> +		#iommu-cells = <0>;
> +		status = "disabled";
> +	};
> +
> +	qos_gmac: qos at ff518000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff518000 0x0 0x20>;
> +	};
> +
> +	qos_gpu: qos at ff520000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff520000 0x0 0x20>;
> +	};
> +
> +	qos_sdmmc: qos at ff52c000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff52c000 0x0 0x20>;
> +	};
> +
> +	qos_emmc: qos at ff538000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff538000 0x0 0x20>;
> +	};
> +
> +	qos_nand: qos at ff538080 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff538080 0x0 0x20>;
> +	};
> +
> +	qos_sdio: qos at ff538100 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff538100 0x0 0x20>;
> +	};
> +
> +	qos_sfc: qos at ff538180 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff538180 0x0 0x20>;
> +	};
> +
> +	qos_usb_host: qos at ff540000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff540000 0x0 0x20>;
> +	};
> +
> +	qos_usb_otg: qos at ff540080 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff540080 0x0 0x20>;
> +	};
> +
> +	qos_isp_128: qos at ff548000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff548000 0x0 0x20>;
> +	};
> +
> +	qos_isp_rd: qos at ff548080 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff548080 0x0 0x20>;
> +	};
> +
> +	qos_isp_wr: qos at ff548100 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff548100 0x0 0x20>;
> +	};
> +
> +	qos_isp_m1: qos at ff548180 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff548180 0x0 0x20>;
> +	};
> +
> +	qos_vip: qos at ff548200 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff548200 0x0 0x20>;
> +	};
> +
> +	qos_rga_rd: qos at ff550000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff550000 0x0 0x20>;
> +	};
> +
> +	qos_rga_wr: qos at ff550080 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff550080 0x0 0x20>;
> +	};
> +
> +	qos_vop_m0: qos at ff550100 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff550100 0x0 0x20>;
> +	};
> +
> +	qos_vop_m1: qos at ff550180 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff550180 0x0 0x20>;
> +	};
> +
> +	qos_vpu: qos at ff558000 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff558000 0x0 0x20>;
> +	};
> +
> +	qos_vpu_r128: qos at ff558080 {
> +		compatible = "syscon";
> +		reg = <0x0 0xff558080 0x0 0x20>;
> +	};
> +
> +	pinctrl: pinctrl {
> +		compatible = "rockchip,px30-pinctrl";
> +		rockchip,grf = <&grf>;
> +		rockchip,pmu = <&pmugrf>;
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		gpio0: gpio0 at ff040000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x0 0xff040000 0x0 0x100>;
> +			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&pmucru PCLK_GPIO0_PMU>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio1: gpio1 at ff250000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x0 0xff250000 0x0 0x100>;
> +			interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO1>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio2: gpio2 at ff260000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x0 0xff260000 0x0 0x100>;
> +			interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO2>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio3: gpio3 at ff270000 {
> +			compatible = "rockchip,gpio-bank";
> +			reg = <0x0 0xff270000 0x0 0x100>;
> +			interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&cru PCLK_GPIO3>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		pcfg_pull_up: pcfg-pull-up {
> +			bias-pull-up;
> +		};
> +
> +		pcfg_pull_down: pcfg-pull-down {
> +			bias-pull-down;
> +		};
> +
> +		pcfg_pull_none: pcfg-pull-none {
> +			bias-disable;
> +		};
> +
> +		pcfg_pull_none_2ma: pcfg-pull-none-2ma {
> +			bias-disable;
> +			drive-strength = <2>;
> +		};
> +
> +		pcfg_pull_up_2ma: pcfg-pull-up-2ma {
> +			bias-pull-up;
> +			drive-strength = <2>;
> +		};
> +
> +		pcfg_pull_up_4ma: pcfg-pull-up-4ma {
> +			bias-pull-up;
> +			drive-strength = <4>;
> +		};
> +
> +		pcfg_pull_none_4ma: pcfg-pull-none-4ma {
> +			bias-disable;
> +			drive-strength = <4>;
> +		};
> +
> +		pcfg_pull_down_4ma: pcfg-pull-down-4ma {
> +			bias-pull-down;
> +			drive-strength = <4>;
> +		};
> +
> +		pcfg_pull_none_8ma: pcfg-pull-none-8ma {
> +			bias-disable;
> +			drive-strength = <8>;
> +		};
> +
> +		pcfg_pull_up_8ma: pcfg-pull-up-8ma {
> +			bias-pull-up;
> +			drive-strength = <8>;
> +		};
> +
> +		pcfg_pull_none_12ma: pcfg-pull-none-12ma {
> +			bias-disable;
> +			drive-strength = <12>;
> +		};
> +
> +		pcfg_pull_up_12ma: pcfg-pull-up-12ma {
> +			bias-pull-up;
> +			drive-strength = <12>;
> +		};
> +
> +		pcfg_pull_none_smt: pcfg-pull-none-smt {
> +			bias-disable;
> +			input-schmitt-enable;
> +		};
> +
> +		pcfg_output_high: pcfg-output-high {
> +			output-high;
> +		};
> +
> +		pcfg_output_low: pcfg-output-low {
> +			output-low;
> +		};
> +
> +		pcfg_input_high: pcfg-input-high {
> +			bias-pull-up;
> +			input-enable;
> +		};
> +
> +		pcfg_input: pcfg-input {
> +			input-enable;
> +		};
> +
> +		i2c0 {
> +			i2c0_xfer: i2c0-xfer {
> +				rockchip,pins =
> +					<0 RK_PB0 1 &pcfg_pull_none_smt>,
> +					<0 RK_PB1 1 &pcfg_pull_none_smt>;
> +			};
> +		};
> +
> +		i2c1 {
> +			i2c1_xfer: i2c1-xfer {
> +				rockchip,pins =
> +					<0 RK_PC2 1 &pcfg_pull_none_smt>,
> +					<0 RK_PC3 1 &pcfg_pull_none_smt>;
> +			};
> +		};
> +
> +		i2c2 {
> +			i2c2_xfer: i2c2-xfer {
> +				rockchip,pins =
> +					<2 RK_PB7 2 &pcfg_pull_none_smt>,
> +					<2 RK_PC0 2 &pcfg_pull_none_smt>;
> +			};
> +		};
> +
> +		i2c3 {
> +			i2c3_xfer: i2c3-xfer {
> +				rockchip,pins =
> +					<1 RK_PB4 4 &pcfg_pull_none_smt>,
> +					<1 RK_PB5 4 &pcfg_pull_none_smt>;
> +			};
> +		};
> +
> +		tsadc {
> +			tsadc_otp_gpio: tsadc-otp-gpio {
> +				rockchip,pins =
> +					<0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
> +			};
> +
> +			tsadc_otp_out: tsadc-otp-out {
> +				rockchip,pins =
> +					<0 RK_PA6 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart0 {
> +			uart0_xfer: uart0-xfer {
> +				rockchip,pins =
> +					<0 RK_PB2 1 &pcfg_pull_up>,
> +					<0 RK_PB3 1 &pcfg_pull_up>;
> +			};
> +
> +			uart0_cts: uart0-cts {
> +				rockchip,pins =
> +					<0 RK_PB4 1 &pcfg_pull_none>;
> +			};
> +
> +			uart0_rts: uart0-rts {
> +				rockchip,pins =
> +					<0 RK_PB5 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart1 {
> +			uart1_xfer: uart1-xfer {
> +				rockchip,pins =
> +					<1 RK_PC1 1 &pcfg_pull_up>,
> +					<1 RK_PC0 1 &pcfg_pull_up>;
> +			};
> +
> +			uart1_cts: uart1-cts {
> +				rockchip,pins =
> +					<1 RK_PC2 1 &pcfg_pull_none>;
> +			};
> +
> +			uart1_rts: uart1-rts {
> +				rockchip,pins =
> +					<1 RK_PC3 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart2-m0 {
> +			uart2m0_xfer: uart2m0-xfer {
> +				rockchip,pins =
> +					<1 RK_PD2 2 &pcfg_pull_up>,
> +					<1 RK_PD3 2 &pcfg_pull_up>;
> +			};
> +		};
> +
> +		uart2-m1 {
> +			uart2m1_xfer: uart2m1-xfer {
> +				rockchip,pins =
> +					<2 RK_PB4 2 &pcfg_pull_up>,
> +					<2 RK_PB6 2 &pcfg_pull_up>;
> +			};
> +		};
> +
> +		uart3-m0 {
> +			uart3m0_xfer: uart3m0-xfer {
> +				rockchip,pins =
> +					<0 RK_PC0 2 &pcfg_pull_up>,
> +					<0 RK_PC1 2 &pcfg_pull_up>;
> +			};
> +
> +			uart3m0_cts: uart3m0-cts {
> +				rockchip,pins =
> +					<0 RK_PC2 2 &pcfg_pull_none>;
> +			};
> +
> +			uart3m0_rts: uart3m0-rts {
> +				rockchip,pins =
> +					<0 RK_PC3 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart3-m1 {
> +			uart3m1_xfer: uart3m1-xfer {
> +				rockchip,pins =
> +					<1 RK_PB6 2 &pcfg_pull_up>,
> +					<1 RK_PB7 2 &pcfg_pull_up>;
> +			};
> +
> +			uart3m1_cts: uart3m1-cts {
> +				rockchip,pins =
> +					<1 RK_PB4 2 &pcfg_pull_none>;
> +			};
> +
> +			uart3m1_rts: uart3m1-rts {
> +				rockchip,pins =
> +					<1 RK_PB5 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart4 {
> +			uart4_xfer: uart4-xfer {
> +				rockchip,pins =
> +					<1 RK_PD4 2 &pcfg_pull_up>,
> +					<1 RK_PD5 2 &pcfg_pull_up>;
> +			};
> +
> +			uart4_cts: uart4-cts {
> +				rockchip,pins =
> +					<1 RK_PD6 2 &pcfg_pull_none>;
> +			};
> +
> +			uart4_rts: uart4-rts {
> +				rockchip,pins =
> +					<1 RK_PD7 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		uart5 {
> +			uart5_xfer: uart5-xfer {
> +				rockchip,pins =
> +					<3 RK_PA2 4 &pcfg_pull_up>,
> +					<3 RK_PA1 4 &pcfg_pull_up>;
> +			};
> +
> +			uart5_cts: uart5-cts {
> +				rockchip,pins =
> +					<3 RK_PA3 4 &pcfg_pull_none>;
> +			};
> +
> +			uart5_rts: uart5-rts {
> +				rockchip,pins =
> +					<3 RK_PA5 4 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		spi0 {
> +			spi0_clk: spi0-clk {
> +				rockchip,pins =
> +					<1 RK_PB7 3 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi0_csn: spi0-csn {
> +				rockchip,pins =
> +					<1 RK_PB6 3 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi0_miso: spi0-miso {
> +				rockchip,pins =
> +					<1 RK_PB5 3 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi0_mosi: spi0-mosi {
> +				rockchip,pins =
> +					<1 RK_PB4 3 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi0_clk_hs: spi0-clk-hs {
> +				rockchip,pins =
> +					<1 RK_PB7 3 &pcfg_pull_up_8ma>;
> +			};
> +
> +			spi0_miso_hs: spi0-miso-hs {
> +				rockchip,pins =
> +					<1 RK_PB5 3 &pcfg_pull_up_8ma>;
> +			};
> +
> +			spi0_mosi_hs: spi0-mosi-hs {
> +				rockchip,pins =
> +					<1 RK_PB4 3 &pcfg_pull_up_8ma>;
> +			};
> +		};
> +
> +		spi1 {
> +			spi1_clk: spi1-clk {
> +				rockchip,pins =
> +					<3 RK_PB7 4 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi1_csn0: spi1-csn0 {
> +				rockchip,pins =
> +					<3 RK_PB1 4 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi1_csn1: spi1-csn1 {
> +				rockchip,pins =
> +					<3 RK_PB2 2 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi1_miso: spi1-miso {
> +				rockchip,pins =
> +					<3 RK_PB6 4 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi1_mosi: spi1-mosi {
> +				rockchip,pins =
> +					<3 RK_PB4 4 &pcfg_pull_up_4ma>;
> +			};
> +
> +			spi1_clk_hs: spi1-clk-hs {
> +				rockchip,pins =
> +					<3 RK_PB7 4 &pcfg_pull_up_8ma>;
> +			};
> +
> +			spi1_miso_hs: spi1-miso-hs {
> +				rockchip,pins =
> +					<3 RK_PB6 4 &pcfg_pull_up_8ma>;
> +			};
> +
> +			spi1_mosi_hs: spi1-mosi-hs {
> +				rockchip,pins =
> +					<3 RK_PB4 4 &pcfg_pull_up_8ma>;
> +			};
> +		};
> +
> +		pdm {
> +			pdm_clk0m0: pdm-clk0m0 {
> +				rockchip,pins =
> +					<3 RK_PC6 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_clk0m1: pdm-clk0m1 {
> +				rockchip,pins =
> +					<2 RK_PC6 1 &pcfg_pull_none>;
> +			};
> +
> +			pdm_clk1: pdm-clk1 {
> +				rockchip,pins =
> +					<3 RK_PC7 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_sdi0m0: pdm-sdi0m0 {
> +				rockchip,pins =
> +					<3 RK_PD3 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_sdi0m1: pdm-sdi0m1 {
> +				rockchip,pins =
> +					<2 RK_PC5 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_sdi1: pdm-sdi1 {
> +				rockchip,pins =
> +					<3 RK_PD0 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_sdi2: pdm-sdi2 {
> +				rockchip,pins =
> +					<3 RK_PD1 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_sdi3: pdm-sdi3 {
> +				rockchip,pins =
> +					<3 RK_PD2 2 &pcfg_pull_none>;
> +			};
> +
> +			pdm_clk0m0_sleep: pdm-clk0m0-sleep {
> +				rockchip,pins =
> +					<3 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_clk0m_sleep1: pdm-clk0m1-sleep {
> +				rockchip,pins =
> +					<2 RK_PC6 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_clk1_sleep: pdm-clk1-sleep {
> +				rockchip,pins =
> +					<3 RK_PC7 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_sdi0m0_sleep: pdm-sdi0m0-sleep {
> +				rockchip,pins =
> +					<3 RK_PD3 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_sdi0m1_sleep: pdm-sdi0m1-sleep {
> +				rockchip,pins =
> +					<2 RK_PC5 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_sdi1_sleep: pdm-sdi1-sleep {
> +				rockchip,pins =
> +					<3 RK_PD0 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_sdi2_sleep: pdm-sdi2-sleep {
> +				rockchip,pins =
> +					<3 RK_PD1 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +
> +			pdm_sdi3_sleep: pdm-sdi3-sleep {
> +				rockchip,pins =
> +					<3 RK_PD2 RK_FUNC_GPIO &pcfg_input_high>;
> +			};
> +		};
> +
> +		i2s0 {
> +			i2s0_8ch_mclk: i2s0-8ch-mclk {
> +				rockchip,pins =
> +					<3 RK_PC1 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sclktx: i2s0-8ch-sclktx {
> +				rockchip,pins =
> +					<3 RK_PC3 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sclkrx: i2s0-8ch-sclkrx {
> +				rockchip,pins =
> +					<3 RK_PB4 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_lrcktx: i2s0-8ch-lrcktx {
> +				rockchip,pins =
> +					<3 RK_PC2 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_lrckrx: i2s0-8ch-lrckrx {
> +				rockchip,pins =
> +					<3 RK_PB5 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdo0: i2s0-8ch-sdo0 {
> +				rockchip,pins =
> +					<3 RK_PC4 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdo1: i2s0-8ch-sdo1 {
> +				rockchip,pins =
> +					<3 RK_PC0 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdo2: i2s0-8ch-sdo2 {
> +				rockchip,pins =
> +					<3 RK_PB7 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdo3: i2s0-8ch-sdo3 {
> +				rockchip,pins =
> +					<3 RK_PB6 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdi0: i2s0-8ch-sdi0 {
> +				rockchip,pins =
> +					<3 RK_PC5 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdi1: i2s0-8ch-sdi1 {
> +				rockchip,pins =
> +					<3 RK_PB3 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdi2: i2s0-8ch-sdi2 {
> +				rockchip,pins =
> +					<3 RK_PB1 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s0_8ch_sdi3: i2s0-8ch-sdi3 {
> +				rockchip,pins =
> +					<3 RK_PB0 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2s1 {
> +			i2s1_2ch_mclk: i2s1-2ch-mclk {
> +				rockchip,pins =
> +					<2 RK_PC3 1 &pcfg_pull_none>;
> +			};
> +
> +			i2s1_2ch_sclk: i2s1-2ch-sclk {
> +				rockchip,pins =
> +					<2 RK_PC2 1 &pcfg_pull_none>;
> +			};
> +
> +			i2s1_2ch_lrck: i2s1-2ch-lrck {
> +				rockchip,pins =
> +					<2 RK_PC1 1 &pcfg_pull_none>;
> +			};
> +
> +			i2s1_2ch_sdi: i2s1-2ch-sdi {
> +				rockchip,pins =
> +					<2 RK_PC5 1 &pcfg_pull_none>;
> +			};
> +
> +			i2s1_2ch_sdo: i2s1-2ch-sdo {
> +				rockchip,pins =
> +					<2 RK_PC4 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		i2s2 {
> +			i2s2_2ch_mclk: i2s2-2ch-mclk {
> +				rockchip,pins =
> +					<3 RK_PA1 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s2_2ch_sclk: i2s2-2ch-sclk {
> +				rockchip,pins =
> +					<3 RK_PA2 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s2_2ch_lrck: i2s2-2ch-lrck {
> +				rockchip,pins =
> +					<3 RK_PA3 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s2_2ch_sdi: i2s2-2ch-sdi {
> +				rockchip,pins =
> +					<3 RK_PA5 2 &pcfg_pull_none>;
> +			};
> +
> +			i2s2_2ch_sdo: i2s2-2ch-sdo {
> +				rockchip,pins =
> +					<3 RK_PA7 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		sdmmc {
> +			sdmmc_clk: sdmmc-clk {
> +				rockchip,pins =
> +					<1 RK_PD6 1 &pcfg_pull_none_8ma>;
> +			};
> +
> +			sdmmc_cmd: sdmmc-cmd {
> +				rockchip,pins =
> +					<1 RK_PD7 1 &pcfg_pull_up_8ma>;
> +			};
> +
> +			sdmmc_det: sdmmc-det {
> +				rockchip,pins =
> +					<0 RK_PA3 1 &pcfg_pull_up_8ma>;
> +			};
> +
> +			sdmmc_bus1: sdmmc-bus1 {
> +				rockchip,pins =
> +					<1 RK_PD2 1 &pcfg_pull_up_8ma>;
> +			};
> +
> +			sdmmc_bus4: sdmmc-bus4 {
> +				rockchip,pins =
> +					<1 RK_PD2 1 &pcfg_pull_up_8ma>,
> +					<1 RK_PD3 1 &pcfg_pull_up_8ma>,
> +					<1 RK_PD4 1 &pcfg_pull_up_8ma>,
> +					<1 RK_PD5 1 &pcfg_pull_up_8ma>;
> +			};
> +		};
> +
> +		sdio {
> +			sdio_clk: sdio-clk {
> +				rockchip,pins =
> +					<1 RK_PC5 1 &pcfg_pull_none>;
> +			};
> +
> +			sdio_cmd: sdio-cmd {
> +				rockchip,pins =
> +					<1 RK_PC4 1 &pcfg_pull_up>;
> +			};
> +
> +			sdio_bus4: sdio-bus4 {
> +				rockchip,pins =
> +					<1 RK_PC6 1 &pcfg_pull_up>,
> +					<1 RK_PC7 1 &pcfg_pull_up>,
> +					<1 RK_PD0 1 &pcfg_pull_up>,
> +					<1 RK_PD1 1 &pcfg_pull_up>;
> +			};
> +		};
> +
> +		emmc {
> +			emmc_clk: emmc-clk {
> +				rockchip,pins =
> +					<1 RK_PB1 2 &pcfg_pull_none_8ma>;
> +			};
> +
> +			emmc_cmd: emmc-cmd {
> +				rockchip,pins =
> +					<1 RK_PB2 2 &pcfg_pull_up_8ma>;
> +			};
> +
> +			emmc_rstnout: emmc-rstnout {
> +				rockchip,pins =
> +					<1 RK_PB3 2 &pcfg_pull_none>;
> +			};
> +
> +			emmc_bus1: emmc-bus1 {
> +				rockchip,pins =
> +					<1 RK_PA0 2 &pcfg_pull_up_8ma>;
> +			};
> +
> +			emmc_bus4: emmc-bus4 {
> +				rockchip,pins =
> +					<1 RK_PA0 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA1 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA2 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA3 2 &pcfg_pull_up_8ma>;
> +			};
> +
> +			emmc_bus8: emmc-bus8 {
> +				rockchip,pins =
> +					<1 RK_PA0 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA1 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA2 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA3 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA4 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA5 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA6 2 &pcfg_pull_up_8ma>,
> +					<1 RK_PA7 2 &pcfg_pull_up_8ma>;
> +			};
> +		};
> +
> +		flash {
> +			flash_cs0: flash-cs0 {
> +				rockchip,pins =
> +					<1 RK_PB0 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_rdy: flash-rdy {
> +				rockchip,pins =
> +					<1 RK_PB1 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_dqs: flash-dqs {
> +				rockchip,pins =
> +					<1 RK_PB2 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_ale: flash-ale {
> +				rockchip,pins =
> +					<1 RK_PB3 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_cle: flash-cle {
> +				rockchip,pins =
> +					<1 RK_PB4 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_wrn: flash-wrn {
> +				rockchip,pins =
> +					<1 RK_PB5 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_csl: flash-csl {
> +				rockchip,pins =
> +					<1 RK_PB6 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_rdn: flash-rdn {
> +				rockchip,pins =
> +					<1 RK_PB7 1 &pcfg_pull_none>;
> +			};
> +
> +			flash_bus8: flash-bus8 {
> +				rockchip,pins =
> +					<1 RK_PA0 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA1 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA2 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA3 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA4 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA5 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA6 1 &pcfg_pull_up_12ma>,
> +					<1 RK_PA7 1 &pcfg_pull_up_12ma>;
> +			};
> +		};
> +
> +		lcdc {
> +			lcdc_rgb_dclk_pin: lcdc-rgb-dclk-pin {
> +				rockchip,pins =
> +					<3 RK_PA0 1 &pcfg_pull_none_12ma>;
> +			};
> +
> +			lcdc_rgb_m0_hsync_pin: lcdc-rgb-m0-hsync-pin {
> +				rockchip,pins =
> +					<3 RK_PA1 1 &pcfg_pull_none_12ma>;
> +			};
> +
> +			lcdc_rgb_m0_vsync_pin: lcdc-rgb-m0-vsync-pin {
> +				rockchip,pins =
> +					<3 RK_PA2 1 &pcfg_pull_none_12ma>;
> +			};
> +
> +			lcdc_rgb_m0_den_pin: lcdc-rgb-m0-den-pin {
> +				rockchip,pins =
> +					<3 RK_PA3 1 &pcfg_pull_none_12ma>;
> +			};
> +
> +			lcdc_rgb888_m0_data_pins: lcdc-rgb888-m0-data-pins {
> +				rockchip,pins =
> +					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
> +					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
> +					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
> +					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
> +					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
> +					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
> +					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
> +					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
> +					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
> +					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
> +					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
> +					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
> +					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
> +					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
> +					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
> +					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
> +					<3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
> +					<3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
> +					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
> +					<3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
> +					<3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
> +					<3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
> +					<3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
> +					<3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
> +			};
> +
> +			lcdc_rgb666_m0_data_pins: lcdc-rgb666-m0-data-pins {
> +				rockchip,pins =
> +					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
> +					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
> +					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
> +					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
> +					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
> +					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
> +					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
> +					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
> +					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
> +					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
> +					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
> +					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
> +					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
> +					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
> +					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
> +					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
> +					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
> +					<3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
> +			};
> +
> +			lcdc_rgb565_m0_data_pins: lcdc-rgb565-m0-data-pins {
> +				rockchip,pins =
> +					<3 RK_PA7 1 &pcfg_pull_none_8ma>, /* lcdc_d3 */
> +					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
> +					<3 RK_PA5 1 &pcfg_pull_none_8ma>, /* lcdc_d1 */
> +					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
> +					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
> +					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
> +					<3 RK_PB1 1 &pcfg_pull_none_8ma>, /* lcdc_d5 */
> +					<3 RK_PB0 1 &pcfg_pull_none_8ma>, /* lcdc_d4 */
> +					<3 RK_PB7 1 &pcfg_pull_none_8ma>, /* lcdc_d11 */
> +					<3 RK_PB6 1 &pcfg_pull_none_8ma>, /* lcdc_d10 */
> +					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
> +					<3 RK_PB4 1 &pcfg_pull_none_8ma>, /* lcdc_d8 */
> +					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
> +					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
> +					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
> +					<3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
> +			};
> +
> +			lcdc_rgb888_m1_data_pins: lcdc-rgb888-m1-data-pins {
> +				rockchip,pins =
> +					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
> +					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
> +					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
> +					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
> +					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
> +					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
> +					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
> +					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
> +					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
> +					<3 RK_PC7 1 &pcfg_pull_none_8ma>, /* lcdc_d19 */
> +					<3 RK_PC6 1 &pcfg_pull_none_8ma>, /* lcdc_d18 */
> +					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
> +					<3 RK_PC4 1 &pcfg_pull_none_8ma>, /* lcdc_d16 */
> +					<3 RK_PD3 1 &pcfg_pull_none_8ma>, /* lcdc_d23 */
> +					<3 RK_PD2 1 &pcfg_pull_none_8ma>, /* lcdc_d22 */
> +					<3 RK_PD1 1 &pcfg_pull_none_8ma>, /* lcdc_d21 */
> +					<3 RK_PD0 1 &pcfg_pull_none_8ma>; /* lcdc_d20 */
> +			};
> +
> +			lcdc_rgb666_m1_data_pins: lcdc-rgb666-m1-data-pins {
> +				rockchip,pins =
> +					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
> +					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
> +					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
> +					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
> +					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
> +					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
> +					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
> +					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
> +					<3 RK_PC0 1 &pcfg_pull_none_8ma>, /* lcdc_d12 */
> +					<3 RK_PC5 1 &pcfg_pull_none_8ma>, /* lcdc_d17 */
> +					<3 RK_PC4 1 &pcfg_pull_none_8ma>; /* lcdc_d16 */
> +			};
> +
> +			lcdc_rgb565_m1_data_pins: lcdc-rgb565-m1-data-pins {
> +				rockchip,pins =
> +					<3 RK_PA6 1 &pcfg_pull_none_8ma>, /* lcdc_d2 */
> +					<3 RK_PA4 1 &pcfg_pull_none_8ma>, /* lcdc_d0 */
> +					<3 RK_PB3 1 &pcfg_pull_none_8ma>, /* lcdc_d7 */
> +					<3 RK_PB2 1 &pcfg_pull_none_8ma>, /* lcdc_d6 */
> +					<3 RK_PB5 1 &pcfg_pull_none_8ma>, /* lcdc_d9 */
> +					<3 RK_PC3 1 &pcfg_pull_none_8ma>, /* lcdc_d15 */
> +					<3 RK_PC2 1 &pcfg_pull_none_8ma>, /* lcdc_d14 */
> +					<3 RK_PC1 1 &pcfg_pull_none_8ma>, /* lcdc_d13 */
> +					<3 RK_PC0 1 &pcfg_pull_none_8ma>; /* lcdc_d12 */
> +			};
> +		};
> +
> +		pwm0 {
> +			pwm0_pin: pwm0-pin {
> +				rockchip,pins =
> +					<0 RK_PB7 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm1 {
> +			pwm1_pin: pwm1-pin {
> +				rockchip,pins =
> +					<0 RK_PC0 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm2 {
> +			pwm2_pin: pwm2-pin {
> +				rockchip,pins =
> +					<2 RK_PB5 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm3 {
> +			pwm3_pin: pwm3-pin {
> +				rockchip,pins =
> +					<0 RK_PC1 1 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm4 {
> +			pwm4_pin: pwm4-pin {
> +				rockchip,pins =
> +					<3 RK_PC2 3 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm5 {
> +			pwm5_pin: pwm5-pin {
> +				rockchip,pins =
> +					<3 RK_PC3 3 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm6 {
> +			pwm6_pin: pwm6-pin {
> +				rockchip,pins =
> +					<3 RK_PC4 3 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		pwm7 {
> +			pwm7_pin: pwm7-pin {
> +				rockchip,pins =
> +					<3 RK_PC5 3 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		gmac {
> +			rmii_pins: rmii-pins {
> +				rockchip,pins =
> +					<2 RK_PA0 2 &pcfg_pull_none_12ma>, /* mac_txen */
> +					<2 RK_PA1 2 &pcfg_pull_none_12ma>, /* mac_txd1 */
> +					<2 RK_PA2 2 &pcfg_pull_none_12ma>, /* mac_txd0 */
> +					<2 RK_PA3 2 &pcfg_pull_none>, /* mac_rxd0 */
> +					<2 RK_PA4 2 &pcfg_pull_none>, /* mac_rxd1 */
> +					<2 RK_PA5 2 &pcfg_pull_none>, /* mac_rxer */
> +					<2 RK_PA6 2 &pcfg_pull_none>, /* mac_rxdv */
> +					<2 RK_PA7 2 &pcfg_pull_none>, /* mac_mdio */
> +					<2 RK_PB1 2 &pcfg_pull_none>; /* mac_mdc */
> +			};
> +
> +			mac_refclk_12ma: mac-refclk-12ma {
> +				rockchip,pins =
> +					<2 RK_PB2 2 &pcfg_pull_none_12ma>;
> +			};
> +
> +			mac_refclk: mac-refclk {
> +				rockchip,pins =
> +					<2 RK_PB2 2 &pcfg_pull_none>;
> +			};
> +		};
> +
> +		cif-m0 {
> +			cif_clkout_m0: cif-clkout-m0 {
> +				rockchip,pins =
> +					<2 RK_PB3 1 &pcfg_pull_none>;
> +			};
> +
> +			dvp_d2d9_m0: dvp-d2d9-m0 {
> +				rockchip,pins =
> +					<2 RK_PA0 1 &pcfg_pull_none>, /* cif_data2 */
> +					<2 RK_PA1 1 &pcfg_pull_none>, /* cif_data3 */
> +					<2 RK_PA2 1 &pcfg_pull_none>, /* cif_data4 */
> +					<2 RK_PA3 1 &pcfg_pull_none>, /* cif_data5 */
> +					<2 RK_PA4 1 &pcfg_pull_none>, /* cif_data6 */
> +					<2 RK_PA5 1 &pcfg_pull_none>, /* cif_data7 */
> +					<2 RK_PA6 1 &pcfg_pull_none>, /* cif_data8 */
> +					<2 RK_PA7 1 &pcfg_pull_none>, /* cif_data9 */
> +					<2 RK_PB0 1 &pcfg_pull_none>, /* cif_sync */
> +					<2 RK_PB1 1 &pcfg_pull_none>, /* cif_href */
> +					<2 RK_PB2 1 &pcfg_pull_none>, /* cif_clkin */
> +					<2 RK_PB3 1 &pcfg_pull_none>; /* cif_clkout */
> +			};
> +
> +			dvp_d0d1_m0: dvp-d0d1-m0 {
> +				rockchip,pins =
> +					<2 RK_PB4 1 &pcfg_pull_none>, /* cif_data0 */
> +					<2 RK_PB6 1 &pcfg_pull_none>; /* cif_data1 */
> +			};
> +
> +			dvp_d10d11_m0:d10-d11-m0 {
> +				rockchip,pins =
> +					<2 RK_PB7 1 &pcfg_pull_none>, /* cif_data10 */
> +					<2 RK_PC0 1 &pcfg_pull_none>; /* cif_data11 */
> +			};
> +		};
> +
> +		cif-m1 {
> +			cif_clkout_m1: cif-clkout-m1 {
> +				rockchip,pins =
> +					<3 RK_PD0 3 &pcfg_pull_none>;
> +			};
> +
> +			dvp_d2d9_m1: dvp-d2d9-m1 {
> +				rockchip,pins =
> +					<3 RK_PA3 3 &pcfg_pull_none>, /* cif_data2 */
> +					<3 RK_PA5 3 &pcfg_pull_none>, /* cif_data3 */
> +					<3 RK_PA7 3 &pcfg_pull_none>, /* cif_data4 */
> +					<3 RK_PB0 3 &pcfg_pull_none>, /* cif_data5 */
> +					<3 RK_PB1 3 &pcfg_pull_none>, /* cif_data6 */
> +					<3 RK_PB4 3 &pcfg_pull_none>, /* cif_data7 */
> +					<3 RK_PB6 3 &pcfg_pull_none>, /* cif_data8 */
> +					<3 RK_PB7 3 &pcfg_pull_none>, /* cif_data9 */
> +					<3 RK_PD1 3 &pcfg_pull_none>, /* cif_sync */
> +					<3 RK_PD2 3 &pcfg_pull_none>, /* cif_href */
> +					<3 RK_PD3 3 &pcfg_pull_none>, /* cif_clkin */
> +					<3 RK_PD0 3 &pcfg_pull_none>; /* cif_clkout */
> +			};
> +
> +			dvp_d0d1_m1: dvp-d0d1-m1 {
> +				rockchip,pins =
> +					<3 RK_PA1 3 &pcfg_pull_none>, /* cif_data0 */
> +					<3 RK_PA2 3 &pcfg_pull_none>; /* cif_data1 */
> +			};
> +
> +			dvp_d10d11_m1:d10-d11-m1 {
> +				rockchip,pins =
> +					<3 RK_PC6 3 &pcfg_pull_none>, /* cif_data10 */
> +					<3 RK_PC7 3 &pcfg_pull_none>; /* cif_data11 */
> +			};
> +		};
> +
> +		isp {
> +			isp_prelight: isp-prelight {
> +				rockchip,pins =
> +					<3 RK_PD1 4 &pcfg_pull_none>;
> +			};
> +		};
> +	};
> +};

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

* [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core
  2019-10-24 23:28 ` [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core Heiko Stuebner
@ 2019-10-25  2:49   ` Kever Yang
  2019-10-25  7:47     ` Heiko Stübner
  0 siblings, 1 reply; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:49 UTC (permalink / raw)
  To: u-boot

Heiko,

On 2019/10/25 上午7:28, Heiko Stuebner wrote:
> From: Kever Yang <kever.yang@rock-chips.com>
>
> Add core architecture code to support the px30 soc.
> This includes a separate tpl board file due to very limited
> sram size as well as a non-dm sdram driver, as this also has
> to fit into the tiny sram.


Could you leave the sram code and make it possible to use the common 
sdram code

I have send out:

https://patchwork.ozlabs.org/cover/1183700/

The sram driver should goes to driver/ram folder instead of arch/arm folder.

>
> Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
> ---
>   arch/arm/include/asm/arch-px30/boot0.h        |   11 +
>   arch/arm/include/asm/arch-px30/gpio.h         |   11 +
>   .../include/asm/arch-rockchip/sdram_px30.h    |  359 +++++
>   arch/arm/mach-rockchip/Kconfig                |   23 +
>   arch/arm/mach-rockchip/Makefile               |    2 +
>   arch/arm/mach-rockchip/px30-board-tpl.c       |   59 +
>   arch/arm/mach-rockchip/px30/Kconfig           |   48 +
>   arch/arm/mach-rockchip/px30/Makefile          |   14 +
>   arch/arm/mach-rockchip/px30/clk_px30.c        |   31 +
>   arch/arm/mach-rockchip/px30/px30.c            |  248 +++
>   .../px30/sdram-px30-ddr3-detect-333.inc       |   70 +
>   .../px30/sdram-px30-ddr4-detect-333.inc       |   73 +
>   .../px30/sdram-px30-ddr_skew.inc              |  121 ++
>   .../px30/sdram-px30-lpddr2-detect-333.inc     |   71 +
>   .../px30/sdram-px30-lpddr3-detect-333.inc     |   72 +
>   arch/arm/mach-rockchip/px30/sdram_px30.c      | 1405 +++++++++++++++++
>   arch/arm/mach-rockchip/px30/syscon_px30.c     |   53 +
>   17 files changed, 2671 insertions(+)
>   create mode 100644 arch/arm/include/asm/arch-px30/boot0.h
>   create mode 100644 arch/arm/include/asm/arch-px30/gpio.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h
>   create mode 100644 arch/arm/mach-rockchip/px30-board-tpl.c
>   create mode 100644 arch/arm/mach-rockchip/px30/Kconfig
>   create mode 100644 arch/arm/mach-rockchip/px30/Makefile
>   create mode 100644 arch/arm/mach-rockchip/px30/clk_px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram_px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/syscon_px30.c
>
> diff --git a/arch/arm/include/asm/arch-px30/boot0.h b/arch/arm/include/asm/arch-px30/boot0.h
> new file mode 100644
> index 0000000000..2e78b074ad
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-px30/boot0.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2019 Rockchip Electronics Co., Ltd
> + */
> +
> +#ifndef __ASM_ARCH_BOOT0_H__
> +#define __ASM_ARCH_BOOT0_H__
> +
> +#include <asm/arch-rockchip/boot0.h>
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-px30/gpio.h b/arch/arm/include/asm/arch-px30/gpio.h
> new file mode 100644
> index 0000000000..eca79d5159
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-px30/gpio.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2019 Rockchip Electronics Co., Ltd
> + */
> +
> +#ifndef __ASM_ARCH_GPIO_H__
> +#define __ASM_ARCH_GPIO_H__
> +
> +#include <asm/arch-rockchip/gpio.h>
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-rockchip/sdram_px30.h b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
> new file mode 100644
> index 0000000000..e10eb97b89
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-rockchip/sdram_px30.h
> @@ -0,0 +1,359 @@
> +/* SPDX-License-Identifier:     GPL-2.0+ */
> +/*
> + * Copyright (C) 2018 Rockchip Electronics Co., Ltd
> + */
> +
> +#ifndef _ASM_ARCH_SDRAM_PX30_H
> +#define _ASM_ARCH_SDRAM_PX30_H
> +
> +struct ddr_pctl_regs {
> +	u32 pctl[30][2];
> +};
> +
> +/* ddr pctl registers define */
> +#define DDR_PCTL2_MSTR			0x0
> +#define DDR_PCTL2_STAT			0x4
> +#define DDR_PCTL2_MSTR1			0x8
> +#define DDR_PCTL2_MRCTRL0		0x10
> +#define DDR_PCTL2_MRCTRL1		0x14
> +#define DDR_PCTL2_MRSTAT		0x18
> +#define DDR_PCTL2_MRCTRL2		0x1c
> +#define DDR_PCTL2_DERATEEN		0x20
> +#define DDR_PCTL2_DERATEINT		0x24
> +#define DDR_PCTL2_PWRCTL		0x30
> +#define DDR_PCTL2_PWRTMG		0x34
> +#define DDR_PCTL2_HWLPCTL		0x38
> +#define DDR_PCTL2_RFSHCTL0		0x50
> +#define DDR_PCTL2_RFSHCTL1		0x54
> +#define DDR_PCTL2_RFSHCTL2		0x58
> +#define DDR_PCTL2_RFSHCTL4		0x5c
> +#define DDR_PCTL2_RFSHCTL3		0x60
> +#define DDR_PCTL2_RFSHTMG		0x64
> +#define DDR_PCTL2_RFSHTMG1		0x68
> +#define DDR_PCTL2_RFSHCTL5		0x6c
> +#define DDR_PCTL2_INIT0			0xd0
> +#define DDR_PCTL2_INIT1			0xd4
> +#define DDR_PCTL2_INIT2			0xd8
> +#define DDR_PCTL2_INIT3			0xdc
> +#define DDR_PCTL2_INIT4			0xe0
> +#define DDR_PCTL2_INIT5			0xe4
> +#define DDR_PCTL2_INIT6			0xe8
> +#define DDR_PCTL2_INIT7			0xec
> +#define DDR_PCTL2_DIMMCTL		0xf0
> +#define DDR_PCTL2_RANKCTL		0xf4
> +#define DDR_PCTL2_CHCTL			0xfc
> +#define DDR_PCTL2_DRAMTMG0		0x100
> +#define DDR_PCTL2_DRAMTMG1		0x104
> +#define DDR_PCTL2_DRAMTMG2		0x108
> +#define DDR_PCTL2_DRAMTMG3		0x10c
> +#define DDR_PCTL2_DRAMTMG4		0x110
> +#define DDR_PCTL2_DRAMTMG5		0x114
> +#define DDR_PCTL2_DRAMTMG6		0x118
> +#define DDR_PCTL2_DRAMTMG7		0x11c
> +#define DDR_PCTL2_DRAMTMG8		0x120
> +#define DDR_PCTL2_DRAMTMG9		0x124
> +#define DDR_PCTL2_DRAMTMG10		0x128
> +#define DDR_PCTL2_DRAMTMG11		0x12c
> +#define DDR_PCTL2_DRAMTMG12		0x130
> +#define DDR_PCTL2_DRAMTMG13		0x134
> +#define DDR_PCTL2_DRAMTMG14		0x138
> +#define DDR_PCTL2_DRAMTMG15		0x13c
> +#define DDR_PCTL2_DRAMTMG16		0x140
> +#define DDR_PCTL2_ZQCTL0		0x180
> +#define DDR_PCTL2_ZQCTL1		0x184
> +#define DDR_PCTL2_ZQCTL2		0x188
> +#define DDR_PCTL2_ZQSTAT		0x18c
> +#define DDR_PCTL2_DFITMG0		0x190
> +#define DDR_PCTL2_DFITMG1		0x194
> +#define DDR_PCTL2_DFILPCFG0		0x198
> +#define DDR_PCTL2_DFILPCFG1		0x19c
> +#define DDR_PCTL2_DFIUPD0		0x1a0
> +#define DDR_PCTL2_DFIUPD1		0x1a4
> +#define DDR_PCTL2_DFIUPD2		0x1a8
> +#define DDR_PCTL2_DFIMISC		0x1b0
> +#define DDR_PCTL2_DFITMG2		0x1b4
> +#define DDR_PCTL2_DFITMG3		0x1b8
> +#define DDR_PCTL2_DFISTAT		0x1bc
> +#define DDR_PCTL2_DBICTL		0x1c0
> +#define DDR_PCTL2_ADDRMAP0		0x200
> +#define DDR_PCTL2_ADDRMAP1		0x204
> +#define DDR_PCTL2_ADDRMAP2		0x208
> +#define DDR_PCTL2_ADDRMAP3		0x20c
> +#define DDR_PCTL2_ADDRMAP4		0x210
> +#define DDR_PCTL2_ADDRMAP5		0x214
> +#define DDR_PCTL2_ADDRMAP6		0x218
> +#define DDR_PCTL2_ADDRMAP7		0x21c
> +#define DDR_PCTL2_ADDRMAP8		0x220
> +#define DDR_PCTL2_ADDRMAP9		0x224
> +#define DDR_PCTL2_ADDRMAP10		0x228
> +#define DDR_PCTL2_ADDRMAP11		0x22c
> +#define DDR_PCTL2_ODTCFG		0x240
> +#define DDR_PCTL2_ODTMAP		0x244
> +#define DDR_PCTL2_SCHED			0x250
> +#define DDR_PCTL2_SCHED1		0x254
> +#define DDR_PCTL2_PERFHPR1		0x25c
> +#define DDR_PCTL2_PERFLPR1		0x264
> +#define DDR_PCTL2_PERFWR1		0x26c
> +#define DDR_PCTL2_DQMAP0		0x280
> +#define DDR_PCTL2_DQMAP1		0x284
> +#define DDR_PCTL2_DQMAP2		0x288
> +#define DDR_PCTL2_DQMAP3		0x28c
> +#define DDR_PCTL2_DQMAP4		0x290
> +#define DDR_PCTL2_DQMAP5		0x294
> +#define DDR_PCTL2_DBG0			0x300
> +#define DDR_PCTL2_DBG1			0x304
> +#define DDR_PCTL2_DBGCAM		0x308
> +#define DDR_PCTL2_DBGCMD		0x30c
> +#define DDR_PCTL2_DBGSTAT		0x310
> +#define DDR_PCTL2_SWCTL			0x320
> +#define DDR_PCTL2_SWSTAT		0x324
> +#define DDR_PCTL2_POISONCFG		0x36c
> +#define DDR_PCTL2_POISONSTAT		0x370
> +#define DDR_PCTL2_ADVECCINDEX		0x374
> +#define DDR_PCTL2_ADVECCSTAT		0x378
> +#define DDR_PCTL2_PSTAT			0x3fc
> +#define DDR_PCTL2_PCCFG			0x400
> +#define DDR_PCTL2_PCFGR_n		0x404
> +#define DDR_PCTL2_PCFGW_n		0x408
> +#define DDR_PCTL2_PCTRL_n		0x490
> +
> +/* PCTL2_MRSTAT */
> +#define MR_WR_BUSY			BIT(0)
> +
> +#define PHY_DDR3_RON_RTT_DISABLE	(0)
> +#define PHY_DDR3_RON_RTT_451ohm		(1)
> +#define PHY_DDR3_RON_RTT_225ohm		(2)
> +#define PHY_DDR3_RON_RTT_150ohm		(3)
> +#define PHY_DDR3_RON_RTT_112ohm		(4)
> +#define PHY_DDR3_RON_RTT_90ohm		(5)
> +#define PHY_DDR3_RON_RTT_75ohm		(6)
> +#define PHY_DDR3_RON_RTT_64ohm		(7)
> +#define PHY_DDR3_RON_RTT_56ohm		(16)
> +#define PHY_DDR3_RON_RTT_50ohm		(17)
> +#define PHY_DDR3_RON_RTT_45ohm		(18)
> +#define PHY_DDR3_RON_RTT_41ohm		(19)
> +#define PHY_DDR3_RON_RTT_37ohm		(20)
> +#define PHY_DDR3_RON_RTT_34ohm		(21)
> +#define PHY_DDR3_RON_RTT_33ohm		(22)
> +#define PHY_DDR3_RON_RTT_30ohm		(23)
> +#define PHY_DDR3_RON_RTT_28ohm		(24)
> +#define PHY_DDR3_RON_RTT_26ohm		(25)
> +#define PHY_DDR3_RON_RTT_25ohm		(26)
> +#define PHY_DDR3_RON_RTT_23ohm		(27)
> +#define PHY_DDR3_RON_RTT_22ohm		(28)
> +#define PHY_DDR3_RON_RTT_21ohm		(29)
> +#define PHY_DDR3_RON_RTT_20ohm		(30)
> +#define PHY_DDR3_RON_RTT_19ohm		(31)
> +
> +#define PHY_DDR4_LPDDR3_RON_RTT_DISABLE	(0)
> +#define PHY_DDR4_LPDDR3_RON_RTT_480ohm	(1)
> +#define PHY_DDR4_LPDDR3_RON_RTT_240ohm	(2)
> +#define PHY_DDR4_LPDDR3_RON_RTT_160ohm	(3)
> +#define PHY_DDR4_LPDDR3_RON_RTT_120ohm	(4)
> +#define PHY_DDR4_LPDDR3_RON_RTT_96ohm	(5)
> +#define PHY_DDR4_LPDDR3_RON_RTT_80ohm	(6)
> +#define PHY_DDR4_LPDDR3_RON_RTT_68ohm	(7)
> +#define PHY_DDR4_LPDDR3_RON_RTT_60ohm	(16)
> +#define PHY_DDR4_LPDDR3_RON_RTT_53ohm	(17)
> +#define PHY_DDR4_LPDDR3_RON_RTT_48ohm	(18)
> +#define PHY_DDR4_LPDDR3_RON_RTT_43ohm	(19)
> +#define PHY_DDR4_LPDDR3_RON_RTT_40ohm	(20)
> +#define PHY_DDR4_LPDDR3_RON_RTT_37ohm	(21)
> +#define PHY_DDR4_LPDDR3_RON_RTT_34ohm	(22)
> +#define PHY_DDR4_LPDDR3_RON_RTT_32ohm	(23)
> +#define PHY_DDR4_LPDDR3_RON_RTT_30ohm	(24)
> +#define PHY_DDR4_LPDDR3_RON_RTT_28ohm	(25)
> +#define PHY_DDR4_LPDDR3_RON_RTT_26ohm	(26)
> +#define PHY_DDR4_LPDDR3_RON_RTT_25ohm	(27)
> +#define PHY_DDR4_LPDDR3_RON_RTT_24ohm	(28)
> +#define PHY_DDR4_LPDDR3_RON_RTT_22ohm	(29)
> +#define PHY_DDR4_LPDDR3_RON_RTT_21ohm	(30)
> +#define PHY_DDR4_LPDDR3_RON_RTT_20ohm	(31)
> +
> +struct ddr_phy_regs {
> +	u32 phy[5][2];
> +};
> +
> +#define PHY_REG(base, n)		((base) + 4 * (n))
> +
> +/* PHY_REG0 */
> +#define DIGITAL_DERESET			BIT(3)
> +#define ANALOG_DERESET			BIT(2)
> +#define DIGITAL_RESET			(0 << 3)
> +#define ANALOG_RESET			(0 << 2)
> +
> +/* PHY_REG1 */
> +#define PHY_DDR2			(0)
> +#define PHY_LPDDR2			(1)
> +#define PHY_DDR3			(2)
> +#define PHY_LPDDR3			(3)
> +#define PHY_DDR4			(4)
> +#define PHY_BL_4			(0 << 2)
> +#define PHY_BL_8			BIT(2)
> +
> +/* PHY_REG2 */
> +#define PHY_DTT_EN			BIT(0)
> +#define PHY_DTT_DISB			(0 << 0)
> +#define PHY_WRITE_LEVELING_EN		BIT(2)
> +#define PHY_WRITE_LEVELING_DISB		(0 << 2)
> +#define PHY_SELECT_CS0			(2)
> +#define PHY_SELECT_CS1			(1)
> +#define PHY_SELECT_CS0_1		(0)
> +#define PHY_WRITE_LEVELING_SELECTCS(n)	((n) << 6)
> +#define PHY_DATA_TRAINING_SELECTCS(n)	((n) << 4)
> +
> +struct ddr_phy_skew {
> +	u32 a0_a1_skew[15];
> +	u32 cs0_dm0_skew[11];
> +	u32 cs0_dm1_skew[11];
> +	u32 cs0_dm2_skew[11];
> +	u32 cs0_dm3_skew[11];
> +	u32 cs1_dm0_skew[11];
> +	u32 cs1_dm1_skew[11];
> +	u32 cs1_dm2_skew[11];
> +	u32 cs1_dm3_skew[11];
> +};
> +
> +#define SR_IDLE				93
> +#define PD_IDLE				13
> +
> +/* PMUGRF */
> +#define PMUGRF_OS_REG0			(0x200)
> +#define PMUGRF_OS_REG(n)		(PMUGRF_OS_REG0 + (n) * 4)
> +
> +/* DDR GRF */
> +#define DDR_GRF_CON(n)			(0 + (n) * 4)
> +#define DDR_GRF_STATUS_BASE		(0X100)
> +#define DDR_GRF_STATUS(n)		(DDR_GRF_STATUS_BASE + (n) * 4)
> +#define DDR_GRF_LP_CON			(0x20)
> +
> +#define SPLIT_MODE_32_L16_VALID		(0)
> +#define SPLIT_MODE_32_H16_VALID		(1)
> +#define SPLIT_MODE_16_L8_VALID		(2)
> +#define SPLIT_MODE_16_H8_VALID		(3)
> +
> +#define DDR_GRF_SPLIT_CON		(0x8)
> +#define SPLIT_MODE_MASK			(0x3)
> +#define SPLIT_MODE_OFFSET		(9)
> +#define SPLIT_BYPASS_MASK		(1)
> +#define SPLIT_BYPASS_OFFSET		(8)
> +#define SPLIT_SIZE_MASK			(0xff)
> +#define SPLIT_SIZE_OFFSET		(0)
> +
> +/* CRU define */
> +/* CRU_PLL_CON0 */
> +#define PB(n)				((0x1 << (15 + 16)) | ((n) << 15))
> +#define POSTDIV1(n)			((0x7 << (12 + 16)) | ((n) << 12))
> +#define FBDIV(n)			((0xFFF << 16) | (n))
> +
> +/* CRU_PLL_CON1 */
> +#define RSTMODE(n)			((0x1 << (15 + 16)) | ((n) << 15))
> +#define RST(n)				((0x1 << (14 + 16)) | ((n) << 14))
> +#define PD(n)				((0x1 << (13 + 16)) | ((n) << 13))
> +#define DSMPD(n)			((0x1 << (12 + 16)) | ((n) << 12))
> +#define LOCK(n)				(((n) >> 10) & 0x1)
> +#define POSTDIV2(n)			((0x7 << (6 + 16)) | ((n) << 6))
> +#define REFDIV(n)			((0x3F << 16) | (n))
> +
> +/* CRU_MODE */
> +#define CLOCK_FROM_XIN_OSC		(0)
> +#define CLOCK_FROM_PLL			(1)
> +#define CLOCK_FROM_RTC_32K		(2)
> +#define DPLL_MODE(n)			((0x3 << (4 + 16)) | ((n) << 4))
> +
> +/* CRU_SOFTRESET_CON1 */
> +#define upctl2_psrstn_req(n)		(((0x1 << 6) << 16) | ((n) << 6))
> +#define upctl2_asrstn_req(n)		(((0x1 << 5) << 16) | ((n) << 5))
> +#define upctl2_srstn_req(n)		(((0x1 << 4) << 16) | ((n) << 4))
> +
> +/* CRU_SOFTRESET_CON2 */
> +#define ddrphy_psrstn_req(n)		(((0x1 << 2) << 16) | ((n) << 2))
> +#define ddrphy_srstn_req(n)		(((0x1 << 0) << 16) | ((n) << 0))
> +
> +/* CRU register */
> +#define CRU_PLL_CON(pll_id, n)		((pll_id)  * 0x20 + (n) * 4)
> +#define CRU_MODE			(0xa0)
> +#define CRU_GLB_CNT_TH			(0xb0)
> +#define CRU_CLKSEL_CON_BASE		0x100
> +#define CRU_CLKSELS_CON(i)		(CRU_CLKSEL_CON_BASE + ((i) * 4))
> +#define CRU_CLKGATE_CON_BASE		0x200
> +#define CRU_CLKGATE_CON(i)		(CRU_CLKGATE_CON_BASE + ((i) * 4))
> +#define CRU_CLKSFTRST_CON_BASE		0x300
> +#define CRU_CLKSFTRST_CON(i)		(CRU_CLKSFTRST_CON_BASE + ((i) * 4))
> +
> +struct px30_ddr_grf_regs {
> +	u32 ddr_grf_con[4];
> +	u32 reserved1[(0x20 - 0x10) / 4];
> +	u32 ddr_grf_lp_con;
> +	u32 reserved2[(0x100 - 0x24) / 4];
> +	u32 ddr_grf_status[11];
> +};
> +
> +struct px30_msch_timings {
> +	u32 ddrtiminga0;
> +	u32 ddrtimingb0;
> +	u32 ddrtimingc0;
> +	u32 devtodev0;
> +	u32 ddrmode;
> +	u32 ddr4timing;
> +	u32 agingx0;
> +};
> +
> +struct px30_sdram_channel {
> +	unsigned int rank;
> +	unsigned int col;
> +	/* 3:8bank, 2:4bank */
> +	unsigned int bk;
> +	/* channel buswidth, 2:32bit, 1:16bit, 0:8bit */
> +	unsigned int bw;
> +	/* die buswidth, 2:32bit, 1:16bit, 0:8bit */
> +	unsigned int dbw;
> +	unsigned int row_3_4;
> +	unsigned int cs0_row;
> +	unsigned int cs1_row;
> +	unsigned int cs0_high16bit_row;
> +	unsigned int cs1_high16bit_row;
> +	unsigned int ddrconfig;
> +	struct px30_msch_timings noc_timings;
> +};
> +
> +struct px30_base_params {
> +	unsigned int ddr_freq;
> +	unsigned int dramtype;
> +	unsigned int num_channels;
> +	unsigned int stride;
> +	unsigned int odt;
> +};
> +
> +struct px30_sdram_params {
> +	struct px30_sdram_channel ch;
> +	struct px30_base_params base;
> +	struct ddr_pctl_regs pctl_regs;
> +	struct ddr_phy_regs phy_regs;
> +	struct ddr_phy_skew *skew;
> +};
> +
> +struct px30_msch_regs {
> +	u32 coreid;
> +	u32 revisionid;
> +	u32 deviceconf;
> +	u32 devicesize;
> +	u32 ddrtiminga0;
> +	u32 ddrtimingb0;
> +	u32 ddrtimingc0;
> +	u32 devtodev0;
> +	u32 reserved1[(0x110 - 0x20) / 4];
> +	u32 ddrmode;
> +	u32 ddr4timing;
> +	u32 reserved2[(0x1000 - 0x118) / 4];
> +	u32 agingx0;
> +	u32 reserved3[(0x1040 - 0x1004) / 4];
> +	u32 aging0;
> +	u32 aging1;
> +	u32 aging2;
> +	u32 aging3;
> +};
> +
> +int sdram_init(void);
> +
> +#endif
> diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
> index f5a80b4f0c..116b40a3c5 100644
> --- a/arch/arm/mach-rockchip/Kconfig
> +++ b/arch/arm/mach-rockchip/Kconfig
> @@ -1,5 +1,27 @@
>   if ARCH_ROCKCHIP
>   
> +config ROCKCHIP_PX30
> +	bool "Support Rockchip PX30"
> +	select ARM64
> +	select SUPPORT_SPL
> +	select SUPPORT_TPL
> +	select SPL
> +	select TPL
> +	select TPL_TINY_FRAMEWORK if TPL


This TPL_TINY_FRAMEWORK is not available on upstream, remove it.

Other code looks good for me.

Thanks,

- Kever

> +	select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
> +	select TPL_NEEDS_SEPARATE_STACK if TPL
> +	imply SPL_SEPARATE_BSS
> +	select SPL_SERIAL_SUPPORT
> +	select TPL_SERIAL_SUPPORT
> +	select DEBUG_UART_BOARD_INIT
> +	imply ROCKCHIP_COMMON_BOARD
> +	imply SPL_ROCKCHIP_COMMON_BOARD
> +	help
> +	  The Rockchip PX30 is a ARM-based SoC with a quad-core Cortex-A35
> +	  including NEON and GPU, Mali-400 graphics, several DDR3 options
> +	  and video codec support. Peripherals include Gigabit Ethernet,
> +	  USB2 host and OTG, SDIO, I2S, UART, SPI, I2C and PWMs.
> +
>   config ROCKCHIP_RK3036
>   	bool "Support Rockchip RK3036"
>   	select CPU_V7A
> @@ -315,6 +337,7 @@ config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
>   config SPL_MMC_SUPPORT
>   	default y if !SPL_ROCKCHIP_BACK_TO_BROM
>   
> +source "arch/arm/mach-rockchip/px30/Kconfig"
>   source "arch/arm/mach-rockchip/rk3036/Kconfig"
>   source "arch/arm/mach-rockchip/rk3128/Kconfig"
>   source "arch/arm/mach-rockchip/rk3188/Kconfig"
> diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
> index 45d9b06233..ddff566dee 100644
> --- a/arch/arm/mach-rockchip/Makefile
> +++ b/arch/arm/mach-rockchip/Makefile
> @@ -11,6 +11,7 @@ obj-spl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
>   obj-spl-$(CONFIG_SPL_ROCKCHIP_COMMON_BOARD) += spl.o spl-boot-order.o
>   obj-tpl-$(CONFIG_ROCKCHIP_BROM_HELPER) += bootrom.o
>   obj-tpl-$(CONFIG_TPL_ROCKCHIP_COMMON_BOARD) += tpl.o
> +obj-tpl-$(CONFIG_ROCKCHIP_PX30) += px30-board-tpl.o
>   
>   obj-spl-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
>   
> @@ -27,6 +28,7 @@ endif
>   
>   obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram_common.o
>   
> +obj-$(CONFIG_ROCKCHIP_PX30) += px30/
>   obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
>   obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
>   obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
> diff --git a/arch/arm/mach-rockchip/px30-board-tpl.c b/arch/arm/mach-rockchip/px30-board-tpl.c
> new file mode 100644
> index 0000000000..8c8976f61c
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30-board-tpl.c
> @@ -0,0 +1,59 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <debug_uart.h>
> +#include <dm.h>
> +#include <ram.h>
> +#include <spl.h>
> +#include <version.h>
> +#include <asm/io.h>
> +#include <asm/arch-rockchip/bootrom.h>
> +#include <asm/arch-rockchip/sdram_px30.h>
> +
> +#define TIMER_LOAD_COUNT0	0x00
> +#define TIMER_LOAD_COUNT1	0x04
> +#define TIMER_CUR_VALUE0	0x08
> +#define TIMER_CUR_VALUE1	0x0c
> +#define TIMER_CONTROL_REG	0x10
> +
> +#define TIMER_EN	0x1
> +#define	TIMER_FMODE	(0 << 1)
> +#define	TIMER_RMODE	(1 << 1)
> +
> +void secure_timer_init(void)
> +{
> +	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
> +	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT0);
> +	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT1);
> +	writel(TIMER_EN | TIMER_FMODE,
> +	       CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +	int ret;
> +
> +#ifdef CONFIG_DEBUG_UART
> +	debug_uart_init();
> +	/*
> +	 * Debug UART can be used from here if required:
> +	 *
> +	 * debug_uart_init();
> +	 * printch('a');
> +	 * printhex8(0x1234);
> +	 * printascii("string");
> +	 */
> +	printascii("U-Boot TPL board init\n");
> +#endif
> +
> +	secure_timer_init();
> +	ret = sdram_init();
> +	if (ret)
> +		printascii("sdram_init failed\n");
> +
> +	/* return to maskrom */
> +	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
> +}
> diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig
> new file mode 100644
> index 0000000000..ef04afca8d
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/Kconfig
> @@ -0,0 +1,48 @@
> +if ROCKCHIP_PX30
> +
> +config TARGET_EVB_PX30
> +	bool "EVB_PX30"
> +
> +config ROCKCHIP_BOOT_MODE_REG
> +	default 0xff010200
> +
> +config SYS_SOC
> +	default "px30"
> +
> +config SYS_MALLOC_F_LEN
> +	default 0x400
> +
> +config SPL_SERIAL_SUPPORT
> +	default y
> +
> +config TPL_LDSCRIPT
> +	default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
> +
> +config TPL_TEXT_BASE
> +	default 0xff0e1000
> +
> +config TPL_MAX_SIZE
> +	default 10240
> +
> +config TPL_STACK
> +	default 0xff0e4fff
> +
> +config ROCKCHIP_RK3326
> +	bool "Support Rockchip RK3326 "
> +	help
> +	  RK3326 can use most code from PX30, but at some situations we have
> +	  to distinguish between RK3326 and PX30, so this macro gives help.
> +	  It is usually selected in rk3326 board defconfig.
> +
> +config DEBUG_UART2_CHANNEL
> +	int "Mux channel to use for debug UART2"
> +	depends on DEBUG_UART_BOARD_INIT
> +	default 0
> +	help
> +	  UART2 can use two different set of pins to route the output.
> +	  For using the UART for early debugging the route to use needs
> +	  to be declared (0 or 1).
> +
> +source "board/rockchip/evb_px30/Kconfig"
> +
> +endif
> diff --git a/arch/arm/mach-rockchip/px30/Makefile b/arch/arm/mach-rockchip/px30/Makefile
> new file mode 100644
> index 0000000000..6d0742bcab
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/Makefile
> @@ -0,0 +1,14 @@
> +#
> +# (C) Copyright 2017 Rockchip Electronics Co., Ltd.
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y += clk_px30.o
> +
> +ifndef CONFIG_TPL_BUILD
> +obj-y += syscon_px30.o
> +endif
> +
> +obj-y += px30.o
> +obj-y += sdram_px30.o
> diff --git a/arch/arm/mach-rockchip/px30/clk_px30.c b/arch/arm/mach-rockchip/px30/clk_px30.c
> new file mode 100644
> index 0000000000..0bd6b471da
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/clk_px30.c
> @@ -0,0 +1,31 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * (C) Copyright 2017 Rockchip Electronics Co., Ltd.
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <syscon.h>
> +#include <asm/arch-rockchip/clock.h>
> +#include <asm/arch-rockchip/cru_px30.h>
> +
> +int rockchip_get_clk(struct udevice **devp)
> +{
> +	return uclass_get_device_by_driver(UCLASS_CLK,
> +			DM_GET_DRIVER(rockchip_px30_cru), devp);
> +}
> +
> +void *rockchip_get_cru(void)
> +{
> +	struct px30_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/px30/px30.c b/arch/arm/mach-rockchip/px30/px30.c
> new file mode 100644
> index 0000000000..7cd2292fe2
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/px30.c
> @@ -0,0 +1,248 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2017 Rockchip Electronics Co., Ltd
> + */
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <asm/armv8/mmu.h>
> +#include <asm/io.h>
> +#include <asm/arch-rockchip/grf_px30.h>
> +#include <asm/arch-rockchip/hardware.h>
> +#include <asm/arch-rockchip/uart.h>
> +#include <asm/arch-rockchip/clock.h>
> +#include <asm/arch-rockchip/cru_px30.h>
> +#include <dt-bindings/clock/px30-cru.h>
> +
> +static struct mm_region px30_mem_map[] = {
> +	{
> +		.virt = 0x0UL,
> +		.phys = 0x0UL,
> +		.size = 0xff000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> +			 PTE_BLOCK_INNER_SHARE
> +	}, {
> +		.virt = 0xff000000UL,
> +		.phys = 0xff000000UL,
> +		.size = 0x01000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> +			 PTE_BLOCK_NON_SHARE |
> +			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
> +	}, {
> +		/* List terminator */
> +		0,
> +	}
> +};
> +
> +struct mm_region *mem_map = px30_mem_map;
> +
> +#define PMU_PWRDN_CON			0xff000018
> +#define GRF_BASE			0xff140000
> +#define CRU_BASE			0xff2b0000
> +#define VIDEO_PHY_BASE			0xff2e0000
> +#define SERVICE_CORE_ADDR		0xff508000
> +#define DDR_FW_BASE			0xff534000
> +
> +#define FW_DDR_CON			0x40
> +
> +#define QOS_PRIORITY			0x08
> +
> +#define QOS_PRIORITY_LEVEL(h, l)	((((h) & 3) << 8) | ((l) & 3))
> +
> +/* GRF_GPIO1CL_IOMUX */
> +enum {
> +	GPIO1C1_SHIFT		= 4,
> +	GPIO1C1_MASK		= 0xf << GPIO1C1_SHIFT,
> +	GPIO1C1_GPIO		= 0,
> +	GPIO1C1_UART1_TX,
> +
> +	GPIO1C0_SHIFT		= 0,
> +	GPIO1C0_MASK		= 0xf << GPIO1C0_SHIFT,
> +	GPIO1C0_GPIO		= 0,
> +	GPIO1C0_UART1_RX,
> +};
> +
> +/* GRF_GPIO1DL_IOMUX */
> +enum {
> +	GPIO1D3_SHIFT		= 12,
> +	GPIO1D3_MASK		= 0xf << GPIO1D3_SHIFT,
> +	GPIO1D3_GPIO		= 0,
> +	GPIO1D3_SDMMC_D1,
> +	GPIO1D3_UART2_RXM0,
> +
> +	GPIO1D2_SHIFT		= 8,
> +	GPIO1D2_MASK		= 0xf << GPIO1D2_SHIFT,
> +	GPIO1D2_GPIO		= 0,
> +	GPIO1D2_SDMMC_D0,
> +	GPIO1D2_UART2_TXM0,
> +};
> +
> +/* GRF_GPIO1DH_IOMUX */
> +enum {
> +	GPIO1D7_SHIFT		= 12,
> +	GPIO1D7_MASK		= 0xf << GPIO1D7_SHIFT,
> +	GPIO1D7_GPIO		= 0,
> +	GPIO1D7_SDMMC_CMD,
> +
> +	GPIO1D6_SHIFT		= 8,
> +	GPIO1D6_MASK		= 0xf << GPIO1D6_SHIFT,
> +	GPIO1D6_GPIO		= 0,
> +	GPIO1D6_SDMMC_CLK,
> +
> +	GPIO1D5_SHIFT		= 4,
> +	GPIO1D5_MASK		= 0xf << GPIO1D5_SHIFT,
> +	GPIO1D5_GPIO		= 0,
> +	GPIO1D5_SDMMC_D3,
> +
> +	GPIO1D4_SHIFT		= 0,
> +	GPIO1D4_MASK		= 0xf << GPIO1D4_SHIFT,
> +	GPIO1D4_GPIO		= 0,
> +	GPIO1D4_SDMMC_D2,
> +};
> +
> +/* GRF_GPIO2BH_IOMUX */
> +enum {
> +	GPIO2B6_SHIFT		= 8,
> +	GPIO2B6_MASK		= 0xf << GPIO2B6_SHIFT,
> +	GPIO2B6_GPIO		= 0,
> +	GPIO2B6_CIF_D1M0,
> +	GPIO2B6_UART2_RXM1,
> +
> +	GPIO2B4_SHIFT		= 0,
> +	GPIO2B4_MASK		= 0xf << GPIO2B4_SHIFT,
> +	GPIO2B4_GPIO		= 0,
> +	GPIO2B4_CIF_D0M0,
> +	GPIO2B4_UART2_TXM1,
> +};
> +
> +/* GRF_GPIO3AL_IOMUX */
> +enum {
> +	GPIO3A2_SHIFT		= 8,
> +	GPIO3A2_MASK		= 0xf << GPIO3A2_SHIFT,
> +	GPIO3A2_GPIO		= 0,
> +	GPIO3A2_UART5_TX	= 4,
> +
> +	GPIO3A1_SHIFT		= 4,
> +	GPIO3A1_MASK		= 0xf << GPIO3A1_SHIFT,
> +	GPIO3A1_GPIO		= 0,
> +	GPIO3A1_UART5_RX	= 4,
> +};
> +
> +int arch_cpu_init(void)
> +{
> +	static struct px30_grf * const grf = (void *)GRF_BASE;
> +	u32 __maybe_unused val;
> +
> +#ifdef CONFIG_SPL_BUILD
> +	/* We do some SoC one time setting here. */
> +	/* Disable the ddr secure region setting to make it non-secure */
> +	writel(0x0, DDR_FW_BASE + FW_DDR_CON);
> +
> +	/* Set cpu qos priority */
> +	writel(QOS_PRIORITY_LEVEL(1, 1), SERVICE_CORE_ADDR + QOS_PRIORITY);
> +
> +#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) || \
> +    (CONFIG_DEBUG_UART_BASE != 0xff160000) || \
> +    (CONFIG_DEBUG_UART_CHANNEL != 0)
> +	/* fix sdmmc pinmux if not using uart2-channel0 as debug uart */
> +	rk_clrsetreg(&grf->gpio1dl_iomux,
> +		     GPIO1D3_MASK | GPIO1D2_MASK,
> +		     GPIO1D3_SDMMC_D1 << GPIO1D3_SHIFT |
> +		     GPIO1D2_SDMMC_D0 << GPIO1D2_SHIFT);
> +	rk_clrsetreg(&grf->gpio1dh_iomux,
> +		     GPIO1D7_MASK | GPIO1D6_MASK | GPIO1D5_MASK | GPIO1D4_MASK,
> +		     GPIO1D7_SDMMC_CMD << GPIO1D7_SHIFT |
> +		     GPIO1D6_SDMMC_CLK << GPIO1D6_SHIFT |
> +		     GPIO1D5_SDMMC_D3 << GPIO1D5_SHIFT |
> +		     GPIO1D4_SDMMC_D2 << GPIO1D4_SHIFT);
> +#endif
> +
> +#endif
> +
> +	/* Enable PD_VO (default disable at reset) */
> +	rk_clrreg(PMU_PWRDN_CON, 1 << 13);
> +
> +	/* Disable video phy bandgap by default */
> +	writel(0x82, VIDEO_PHY_BASE + 0x0000);
> +	writel(0x05, VIDEO_PHY_BASE + 0x03ac);
> +
> +	/* Clear the force_jtag */
> +	rk_clrreg(&grf->cpu_con[1], 1 << 7);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_DEBUG_UART_BOARD_INIT
> +void board_debug_uart_init(void)
> +{
> +	static struct px30_grf * const grf = (void *)GRF_BASE;
> +	static struct px30_cru * const cru = (void *)CRU_BASE;
> +
> +#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff158000)
> +	/* uart_sel_clk default select 24MHz */
> +	rk_clrsetreg(&cru->clksel_con[34],
> +		     UART1_PLL_SEL_MASK | UART1_DIV_CON_MASK,
> +		     UART1_PLL_SEL_24M << UART1_PLL_SEL_SHIFT | 0);
> +	rk_clrsetreg(&cru->clksel_con[35],
> +		     UART1_CLK_SEL_MASK,
> +		     UART1_CLK_SEL_UART1 << UART1_CLK_SEL_SHIFT);
> +
> +	rk_clrsetreg(&grf->gpio1cl_iomux,
> +		     GPIO1C1_MASK | GPIO1C0_MASK,
> +		     GPIO1C1_UART1_TX << GPIO1C1_SHIFT |
> +		     GPIO1C0_UART1_RX << GPIO1C0_SHIFT);
> +#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff178000)
> +	/* uart_sel_clk default select 24MHz */
> +	rk_clrsetreg(&cru->clksel_con[46],
> +		     UART5_PLL_SEL_MASK | UART5_DIV_CON_MASK,
> +		     UART5_PLL_SEL_24M << UART5_PLL_SEL_SHIFT | 0);
> +	rk_clrsetreg(&cru->clksel_con[47],
> +		     UART5_CLK_SEL_MASK,
> +		     UART5_CLK_SEL_UART5 << UART5_CLK_SEL_SHIFT);
> +
> +	rk_clrsetreg(&grf->gpio3al_iomux,
> +		     GPIO3A2_MASK | GPIO3A1_MASK,
> +		     GPIO3A2_UART5_TX << GPIO3A2_SHIFT |
> +		     GPIO3A1_UART5_RX << GPIO3A1_SHIFT);
> +#else
> +	/* GRF_IOFUNC_CON0 */
> +	enum {
> +		CON_IOMUX_UART2SEL_SHIFT	= 10,
> +		CON_IOMUX_UART2SEL_MASK = 3 << CON_IOMUX_UART2SEL_SHIFT,
> +		CON_IOMUX_UART2SEL_M0	= 0,
> +		CON_IOMUX_UART2SEL_M1,
> +		CON_IOMUX_UART2SEL_USBPHY,
> +	};
> +
> +	/* uart_sel_clk default select 24MHz */
> +	rk_clrsetreg(&cru->clksel_con[37],
> +		     UART2_PLL_SEL_MASK | UART2_DIV_CON_MASK,
> +		     UART2_PLL_SEL_24M << UART2_PLL_SEL_SHIFT | 0);
> +	rk_clrsetreg(&cru->clksel_con[38],
> +		     UART2_CLK_SEL_MASK,
> +		     UART2_CLK_SEL_UART2 << UART2_CLK_SEL_SHIFT);
> +
> +#if (CONFIG_DEBUG_UART2_CHANNEL == 1)
> +	/* Enable early UART2 */
> +	rk_clrsetreg(&grf->iofunc_con0,
> +		     CON_IOMUX_UART2SEL_MASK,
> +		     CON_IOMUX_UART2SEL_M1 << CON_IOMUX_UART2SEL_SHIFT);
> +
> +	rk_clrsetreg(&grf->gpio2bh_iomux,
> +		     GPIO2B6_MASK | GPIO2B4_MASK,
> +		     GPIO2B6_UART2_RXM1 << GPIO2B6_SHIFT |
> +		     GPIO2B4_UART2_TXM1 << GPIO2B4_SHIFT);
> +#else
> +	rk_clrsetreg(&grf->iofunc_con0,
> +		     CON_IOMUX_UART2SEL_MASK,
> +		     CON_IOMUX_UART2SEL_M0 << CON_IOMUX_UART2SEL_SHIFT);
> +
> +	rk_clrsetreg(&grf->gpio1dl_iomux,
> +		     GPIO1D3_MASK | GPIO1D2_MASK,
> +		     GPIO1D3_UART2_RXM0 << GPIO1D3_SHIFT |
> +		     GPIO1D2_UART2_TXM0 << GPIO1D2_SHIFT);
> +#endif /* CONFIG_DEBUG_UART2_CHANNEL == 1 */
> +
> +#endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */
> +}
> +#endif /* CONFIG_DEBUG_UART_BOARD_INIT */
> diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
> new file mode 100644
> index 0000000000..e17b2ed86c
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
> @@ -0,0 +1,70 @@
> +{
> +	{
> +		.rank = 0x1,
> +		.col = 0xC,
> +		.bk = 0x3,
> +		.bw = 0x1,
> +		.dbw = 0x0,
> +		.row_3_4 = 0x0,
> +		.cs0_row = 0x10,
> +		.cs1_row = 0x10,
> +		.cs0_high16bit_row = 0x10,
> +		.cs1_high16bit_row = 0x10,
> +		.ddrconfig = 0,
> +		{
> +			0x290b0609,
> +			0x08020401,
> +			0x00000002,
> +			0x00001111,
> +			0x0000000c,
> +			0x00000222,
> +			0x000000ff
> +		}
> +	},
> +	{
> +		.ddr_freq = 333,
> +		.dramtype = DDR3,
> +		.num_channels = 1,
> +		.stride = 0,
> +		.odt = 0,
> +	},
> +	{
> +		{
> +			{0x00000000, 0x43041001},	/* MSTR */
> +			{0x00000064, 0x0028003b},	/* RFSHTMG */
> +			{0x000000d0, 0x00020053},	/* INIT0 */
> +			{0x000000d4, 0x00020000},	/* INIT1 */
> +			{0x000000d8, 0x00000100},	/* INIT2 */
> +			{0x000000dc, 0x03200000},	/* INIT3 */
> +			{0x000000e0, 0x00000000},	/* INIT4 */
> +			{0x000000e4, 0x00090000},	/* INIT5 */
> +			{0x000000f4, 0x000f012f},	/* RANKCTL */
> +			{0x00000100, 0x07090b06},	/* DRAMTMG0 */
> +			{0x00000104, 0x00050209},	/* DRAMTMG1 */
> +			{0x00000108, 0x03030407},	/* DRAMTMG2 */
> +			{0x0000010c, 0x00202006},	/* DRAMTMG3 */
> +			{0x00000110, 0x03020204},	/* DRAMTMG4 */
> +			{0x00000114, 0x03030202},	/* DRAMTMG5 */
> +			{0x00000120, 0x00000903},	/* DRAMTMG8 */
> +			{0x00000180, 0x00800020},	/* ZQCTL0 */
> +			{0x00000184, 0x00000000},	/* ZQCTL1 */
> +			{0x00000190, 0x07010001},	/* DFITMG0 */
> +			{0x00000198, 0x07000101},	/* DFILPCFG0 */
> +			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
> +			{0x00000240, 0x06000604},	/* ODTCFG */
> +			{0x00000244, 0x00000201},	/* ODTMAP */
> +			{0x00000250, 0x00001f00},	/* SCHED */
> +			{0x00000490, 0x00000001},	/* PCTRL_0 */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	},
> +	{
> +		{
> +			{0x00000004, 0x0000000a},	/* PHYREG01 */
> +			{0x00000028, 0x00000006},	/* PHYREG0A */
> +			{0x0000002c, 0x00000000},	/* PHYREG0B */
> +			{0x00000030, 0x00000005},	/* PHYREG0C */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	}
> +},
> diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
> new file mode 100644
> index 0000000000..cdc417405a
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
> @@ -0,0 +1,73 @@
> +{
> +	{
> +		.rank = 0x1,
> +		.col = 0xA,
> +		.bk = 0x2,
> +		.bw = 0x1,
> +		.dbw = 0x0,
> +		.row_3_4 = 0x0,
> +		.cs0_row = 0x11,
> +		.cs1_row = 0x0,
> +		.cs0_high16bit_row = 0x11,
> +		.cs1_high16bit_row = 0x0,
> +		.ddrconfig = 0,
> +		{
> +			0x4d110a08,
> +			0x06020501,
> +			0x00000002,
> +			0x00001111,
> +			0x0000000c,
> +			0x0000022a,
> +			0x000000ff
> +		}
> +	},
> +	{
> +		.ddr_freq = 333,
> +		.dramtype = DDR4,
> +		.num_channels = 1,
> +		.stride = 0,
> +		.odt = 0,
> +	},
> +	{
> +		{
> +			{0x00000000, 0x43049010},	/* MSTR */
> +			{0x00000064, 0x0028003b},	/* RFSHTMG */
> +			{0x000000d0, 0x00020053},	/* INIT0 */
> +			{0x000000d4, 0x00220000},	/* INIT1 */
> +			{0x000000d8, 0x00000100},	/* INIT2 */
> +			{0x000000dc, 0x00040000},	/* INIT3 */
> +			{0x000000e0, 0x00000000},	/* INIT4 */
> +			{0x000000e4, 0x00110000},	/* INIT5 */
> +			{0x000000e8, 0x00000420},	/* INIT6 */
> +			{0x000000ec, 0x00000400},	/* INIT7 */
> +			{0x000000f4, 0x000f012f},	/* RANKCTL */
> +			{0x00000100, 0x09060b06},	/* DRAMTMG0 */
> +			{0x00000104, 0x00020209},	/* DRAMTMG1 */
> +			{0x00000108, 0x0505040a},	/* DRAMTMG2 */
> +			{0x0000010c, 0x0040400c},	/* DRAMTMG3 */
> +			{0x00000110, 0x05030206},	/* DRAMTMG4 */
> +			{0x00000114, 0x03030202},	/* DRAMTMG5 */
> +			{0x00000120, 0x03030b03},	/* DRAMTMG8 */
> +			{0x00000124, 0x00020208},	/* DRAMTMG9 */
> +			{0x00000180, 0x01000040},	/* ZQCTL0 */
> +			{0x00000184, 0x00000000},	/* ZQCTL1 */
> +			{0x00000190, 0x07030003},	/* DFITMG0 */
> +			{0x00000198, 0x07000101},	/* DFILPCFG0 */
> +			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
> +			{0x00000240, 0x06000604},	/* ODTCFG */
> +			{0x00000244, 0x00000201},	/* ODTMAP */
> +			{0x00000250, 0x00001f00},	/* SCHED */
> +			{0x00000490, 0x00000001},	/* PCTRL_0 */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	},
> +	{
> +		{
> +			{0x00000004, 0x0000000c},	/* PHYREG01 */
> +			{0x00000028, 0x0000000a},	/* PHYREG0A */
> +			{0x0000002c, 0x00000000},	/* PHYREG0B */
> +			{0x00000030, 0x00000009},	/* PHYREG0C */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	}
> +},
> \ No newline at end of file
> diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc b/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
> new file mode 100644
> index 0000000000..f24343dda1
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
> @@ -0,0 +1,121 @@
> +		{
> +			0x77,
> +			0x88,
> +			0x79,
> +			0x79,
> +			0x87,
> +			0x97,
> +			0x87,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x87,
> +			0x88,
> +			0x87,
> +			0x87,
> +			0x77
> +		},
> +		{
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x69,
> +			0x9,
> +		},
> +		{
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x79,
> +			0x9,
> +		},
> +		{
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x69,
> +			0x9,
> +		},
> +		{
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x79,
> +			0x9,
> +		},
> +		{
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x69,
> +			0x9,
> +		},
> +		{
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x79,
> +			0x9,
> +		},
> +		{
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x78,
> +			0x69,
> +			0x9,
> +		},
> +		{
> +			0x77,
> +			0x78,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x77,
> +			0x79,
> +			0x9,
> +		}
> diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
> new file mode 100644
> index 0000000000..3bde062d62
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
> @@ -0,0 +1,71 @@
> +{
> +	{
> +		.rank = 0x1,
> +		.col = 0xC,
> +		.bk = 0x3,
> +		.bw = 0x1,
> +		.dbw = 0x0,
> +		.row_3_4 = 0x0,
> +		.cs0_row = 0xF,
> +		.cs1_row = 0xF,
> +		.cs0_high16bit_row = 0xF,
> +		.cs1_high16bit_row = 0xF,
> +		.ddrconfig = 0,
> +		{
> +			0x2b0c070a,
> +			0x08020303,
> +			0x00000002,
> +			0x00001111,
> +			0x0000000c,
> +			0x00000219,
> +			0x000000ff
> +		}
> +	},
> +	{
> +		.ddr_freq = 333,
> +		.dramtype = LPDDR2,
> +		.num_channels = 1,
> +		.stride = 0,
> +		.odt = 0,
> +	},
> +	{
> +		{
> +			{0x00000000, 0x41041004},	/* MSTR */
> +			{0x00000064, 0x00140023},	/* RFSHTMG */
> +			{0x000000d0, 0x00220002},	/* INIT0 */
> +			{0x000000d4, 0x00010000},	/* INIT1 */
> +			{0x000000d8, 0x00000703},	/* INIT2 */
> +			{0x000000dc, 0x00630005},	/* INIT3 */
> +			{0x000000e0, 0x00010000},	/* INIT4 */
> +			{0x000000e4, 0x00070003},	/* INIT5 */
> +			{0x000000f4, 0x000f012f},	/* RANKCTL */
> +			{0x00000100, 0x07090b07},	/* DRAMTMG0 */
> +			{0x00000104, 0x0002010b},	/* DRAMTMG1 */
> +			{0x00000108, 0x02040506},	/* DRAMTMG2 */
> +			{0x0000010c, 0x00303000},	/* DRAMTMG3 */
> +			{0x00000110, 0x04010204},	/* DRAMTMG4 */
> +			{0x00000114, 0x01010303},	/* DRAMTMG5 */
> +			{0x00000118, 0x02020003},	/* DRAMTMG6 */
> +			{0x00000120, 0x00000303},	/* DRAMTMG8 */
> +			{0x00000138, 0x00000025},	/* DRAMTMG14 */
> +			{0x00000180, 0x003c000f},	/* ZQCTL0 */
> +			{0x00000184, 0x00900000},	/* ZQCTL1 */
> +			{0x00000190, 0x07020001},	/* DFITMG0 */
> +			{0x00000198, 0x07000101},	/* DFILPCFG0 */
> +			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
> +			{0x00000240, 0x07030718},	/* ODTCFG */
> +			{0x00000250, 0x00001f00},	/* SCHED */
> +			{0x00000490, 0x00000001},	/* PCTRL_0 */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	},
> +	{
> +		{
> +			{0x00000004, 0x00000009},	/* PHYREG01 */
> +			{0x00000028, 0x00000007},	/* PHYREG0A */
> +			{0x0000002c, 0x00000000},	/* PHYREG0B */
> +			{0x00000030, 0x00000004},	/* PHYREG0C */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	}
> +},
> diff --git a/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
> new file mode 100644
> index 0000000000..a205fc9332
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
> @@ -0,0 +1,72 @@
> +{
> +	{
> +		.rank = 0x1,
> +		.col = 0xC,
> +		.bk = 0x3,
> +		.bw = 0x1,
> +		.dbw = 0x0,
> +		.row_3_4 = 0x0,
> +		.cs0_row = 0x10,
> +		.cs1_row = 0x10,
> +		.cs0_high16bit_row = 0x10,
> +		.cs1_high16bit_row = 0x10,
> +		.ddrconfig = 0,
> +		{
> +			0x290a060a,
> +			0x08020303,
> +			0x00000002,
> +			0x00001111,
> +			0x0000000c,
> +			0x0000021a,
> +			0x000000ff
> +		}
> +	},
> +	{
> +		.ddr_freq = 333,
> +		.dramtype = LPDDR3,
> +		.num_channels = 1,
> +		.stride = 0,
> +		.odt = 0,
> +	},
> +	{
> +		{
> +			{0x00000000, 0x43041008},	/* MSTR */
> +			{0x00000064, 0x00140023},	/* RFSHTMG */
> +			{0x000000d0, 0x00220002},	/* INIT0 */
> +			{0x000000d4, 0x00010000},	/* INIT1 */
> +			{0x000000d8, 0x00000703},	/* INIT2 */
> +			{0x000000dc, 0x00830004},	/* INIT3 */
> +			{0x000000e0, 0x00010000},	/* INIT4 */
> +			{0x000000e4, 0x00070003},	/* INIT5 */
> +			{0x000000f4, 0x000f012f},	/* RANKCTL */
> +			{0x00000100, 0x06090b07},	/* DRAMTMG0 */
> +			{0x00000104, 0x0002020b},	/* DRAMTMG1 */
> +			{0x00000108, 0x02030506},	/* DRAMTMG2 */
> +			{0x0000010c, 0x00505000},	/* DRAMTMG3 */
> +			{0x00000110, 0x03020204},	/* DRAMTMG4 */
> +			{0x00000114, 0x01010303},	/* DRAMTMG5 */
> +			{0x00000118, 0x02020003},	/* DRAMTMG6 */
> +			{0x00000120, 0x00000303},	/* DRAMTMG8 */
> +			{0x00000138, 0x00000025},	/* DRAMTMG14 */
> +			{0x00000180, 0x003c000f},	/* ZQCTL0 */
> +			{0x00000184, 0x00900000},	/* ZQCTL1 */
> +			{0x00000190, 0x07020000},	/* DFITMG0 */
> +			{0x00000198, 0x07000101},	/* DFILPCFG0 */
> +			{0x000001a0, 0xc0400003},	/* DFIUPD0 */
> +			{0x00000240, 0x0900090c},	/* ODTCFG */
> +			{0x00000244, 0x00000101},	/* ODTMAP */
> +			{0x00000250, 0x00001f00},	/* SCHED */
> +			{0x00000490, 0x00000001},	/* PCTRL_0 */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	},
> +	{
> +		{
> +			{0x00000004, 0x0000000b},	/* PHYREG01 */
> +			{0x00000028, 0x00000006},	/* PHYREG0A */
> +			{0x0000002c, 0x00000000},	/* PHYREG0B */
> +			{0x00000030, 0x00000003},	/* PHYREG0C */
> +			{0xffffffff, 0xffffffff}
> +		}
> +	}
> +},
> diff --git a/arch/arm/mach-rockchip/px30/sdram_px30.c b/arch/arm/mach-rockchip/px30/sdram_px30.c
> new file mode 100644
> index 0000000000..2590d9366e
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/sdram_px30.c
> @@ -0,0 +1,1405 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * (C) Copyright 2018 Rockchip Electronics Co., Ltd.
> + */
> +
> +#include <common.h>
> +#include <debug_uart.h>
> +#include <dm.h>
> +#include <ram.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <asm/arch-rockchip/clock.h>
> +#include <asm/arch-rockchip/cru_px30.h>
> +#include <asm/arch-rockchip/grf_px30.h>
> +#include <asm/arch-rockchip/hardware.h>
> +#include <asm/arch-rockchip/sdram_common.h>
> +#include <asm/arch-rockchip/sdram_px30.h>
> +
> +#define TIMER_CUR_VALUE0	0x08
> +#define TIMER_CUR_VALUE1	0x0c
> +
> +static u64 rockchip_get_ticks(void)
> +{
> +	u64 timebase_h, timebase_l;
> +
> +	timebase_l = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CUR_VALUE0);
> +	timebase_h = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CUR_VALUE1);
> +
> +	return timebase_h << 32 | timebase_l;
> +}
> +
> +void rockchip_udelay(unsigned int usec)
> +{
> +	u64 tmp;
> +
> +	/* get timestamp */
> +	tmp = rockchip_get_ticks() + usec_to_tick(usec);
> +
> +	/* loop till event */
> +	while (rockchip_get_ticks() < tmp + 1)
> +		;
> +}
> +
> +u8 ddr_cfg_2_rbc[] = {
> +	/*
> +	 * [6:4] max row: 13+n
> +	 * [3]  bank(0:4bank,1:8bank)
> +	 * [2:0]    col(10+n)
> +	 */
> +	((5 << 4) | (1 << 3) | 0), /* 0 */
> +	((5 << 4) | (1 << 3) | 1), /* 1 */
> +	((4 << 4) | (1 << 3) | 2), /* 2 */
> +	((3 << 4) | (1 << 3) | 3), /* 3 */
> +	((2 << 4) | (1 << 3) | 4), /* 4 */
> +	((5 << 4) | (0 << 3) | 2), /* 5 */
> +	((4 << 4) | (1 << 3) | 2), /* 6 */
> +};
> +
> +#ifdef CONFIG_TPL_BUILD
> +
> +/*
> + * for ddr4 if ddrconfig=7, upctl should set 7 and noc should
> + * set to 1 for more efficient.
> + * noc ddrconf, upctl addrmap
> + * 1  7
> + * 2  8
> + * 3  9
> + * 12 10
> + * 5  11
> + */
> +static u8 d4_rbc_2_d3_rbc[] = {
> +	1, /* 7 */
> +	2, /* 8 */
> +	3, /* 9 */
> +	12, /* 10 */
> +	5, /* 11 */
> +};
> +
> +/*
> + * row higher than cs should be disabled by set to 0xf
> + * rank addrmap calculate by real cap.
> + */
> +static u32 addrmap[][8] = {
> +	/* map0 map1,   map2,       map3,       map4,      map5
> +	 * map6,        map7,       map8
> +	 * -------------------------------------------------------
> +	 * bk2-0       col 5-2     col 9-6    col 11-10   row 11-0
> +	 * row 15-12   row 17-16   bg1,0
> +	 * -------------------------------------------------------
> +	 * 4,3,2       5-2         9-6                    6
> +	 *                         3,2
> +	 */
> +	{0x00060606, 0x00000000, 0x1f1f0000, 0x00001f1f, 0x05050505,
> +		0x05050505, 0x00000505, 0x3f3f}, /* 0 */
> +	{0x00070707, 0x00000000, 0x1f000000, 0x00001f1f, 0x06060606,
> +		0x06060606, 0x06060606, 0x3f3f}, /* 1 */
> +	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
> +		0x07070707, 0x00000f07, 0x3f3f}, /* 2 */
> +	{0x00090909, 0x00000000, 0x00000000, 0x00001f00, 0x08080808,
> +		0x08080808, 0x00000f0f, 0x3f3f}, /* 3 */
> +	{0x000a0a0a, 0x00000000, 0x00000000, 0x00000000, 0x09090909,
> +		0x0f090909, 0x00000f0f, 0x3f3f}, /* 4 */
> +	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x06060606,
> +		0x06060606, 0x00000606, 0x3f3f}, /* 5 */
> +	{0x00080808, 0x00000000, 0x00000000, 0x00001f1f, 0x07070707,
> +		0x07070707, 0x00000f0f, 0x3f3f}, /* 6 */
> +	{0x003f0808, 0x00000006, 0x1f1f0000, 0x00001f1f, 0x06060606,
> +		0x06060606, 0x00000606, 0x0600}, /* 7 */
> +	{0x003f0909, 0x00000007, 0x1f000000, 0x00001f1f, 0x07070707,
> +		0x07070707, 0x00000f07, 0x0700}, /* 8 */
> +	{0x003f0a0a, 0x01010100, 0x01010101, 0x00001f1f, 0x08080808,
> +		0x08080808, 0x00000f0f, 0x0801}, /* 9 */
> +	{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
> +		0x07070707, 0x00000f07, 0x3f01}, /* 10 */
> +	{0x003f0808, 0x00000007, 0x1f000000, 0x00001f1f, 0x06060606,
> +		0x06060606, 0x00000606, 0x3f00}, /* 11 */
> +	/* when ddr4 12 map to 10, when ddr3 12 unused */
> +	{0x003f0909, 0x01010100, 0x01010101, 0x00001f1f, 0x07070707,
> +		0x07070707, 0x00000f07, 0x3f01}, /* 10 */
> +	{0x00070706, 0x00000000, 0x1f010000, 0x00001f1f, 0x06060606,
> +		0x06060606, 0x00000606, 0x3f3f}, /* 13 */
> +};
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +struct dram_info {
> +	struct ddr_pctl_regs *pctl;
> +	struct ddr_phy_regs *phy;
> +	struct px30_cru *cru;
> +	struct px30_msch_regs *msch;
> +	struct px30_ddr_grf_regs *ddr_grf;
> +	struct px30_grf *grf;
> +	struct ram_info info;
> +	struct px30_pmugrf *pmugrf;
> +};
> +
> +#define PMUGRF_BASE_ADDR		0xFF010000
> +#define CRU_BASE_ADDR			0xFF2B0000
> +#define GRF_BASE_ADDR			0xFF140000
> +#define DDRC_BASE_ADDR			0xFF600000
> +#define DDR_PHY_BASE_ADDR		0xFF2A0000
> +#define SERVER_MSCH0_BASE_ADDR		0xFF530000
> +#define DDR_GRF_BASE_ADDR		0xff630000
> +
> +struct dram_info dram_info;
> +
> +struct px30_sdram_params sdram_configs[] = {
> +#include	"sdram-px30-ddr3-detect-333.inc"
> +};
> +
> +struct ddr_phy_skew skew = {
> +#include	"sdram-px30-ddr_skew.inc"
> +};
> +
> +#define PATTERN				(0x5aa5f00f)
> +
> +/*
> + * cs: 0:cs0
> + *	   1:cs1
> + *     else cs0+cs1
> + * note: it didn't consider about row_3_4
> + */
> +u64 sdram_get_cs_cap(struct px30_sdram_channel *cap_info, u32 cs, u32 dram_type)
> +{
> +	u32 bg;
> +	u64 cap[2];
> +
> +	if (dram_type == DDR4)
> +		/* DDR4 8bit dram BG = 2(4bank groups),
> +		 * 16bit dram BG = 1 (2 bank groups)
> +		 */
> +		bg = (cap_info->dbw == 0) ? 2 : 1;
> +	else
> +		bg = 0;
> +	cap[0] = 1llu << (cap_info->bw + cap_info->col +
> +		bg + cap_info->bk + cap_info->cs0_row);
> +
> +	if (cap_info->rank == 2)
> +		cap[1] = 1llu << (cap_info->bw + cap_info->col +
> +			bg + cap_info->bk + cap_info->cs1_row);
> +	else
> +		cap[1] = 0;
> +
> +	if (cs == 0)
> +		return cap[0];
> +	else if (cs == 1)
> +		return cap[1];
> +	else
> +		return (cap[0] + cap[1]);
> +}
> +
> +/* n: Unit bytes */
> +void sdram_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 sdram_phy_dll_bypass_set(void __iomem *phy_base, u32 freq)
> +{
> +	u32 tmp;
> +	u32 i, j;
> +
> +	setbits_le32(PHY_REG(phy_base, 0x13), 1 << 4);
> +	clrbits_le32(PHY_REG(phy_base, 0x14), 1 << 3);
> +	for (i = 0; i < 4; i++) {
> +		j = 0x26 + i * 0x10;
> +		setbits_le32(PHY_REG(phy_base, j), 1 << 4);
> +		clrbits_le32(PHY_REG(phy_base, j + 0x1), 1 << 3);
> +	}
> +
> +	if (freq <= (400000000))
> +		/* DLL bypass */
> +		setbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
> +	else
> +		clrbits_le32(PHY_REG(phy_base, 0xa4), 0x1f);
> +
> +	if (freq <= (801000000))
> +		tmp = 2;
> +	else
> +		tmp = 1;
> +
> +	for (i = 0; i < 4; i++) {
> +		j = 0x28 + i * 0x10;
> +		writel(tmp, PHY_REG(phy_base, j));
> +	}
> +}
> +
> +static void sdram_phy_set_ds_odt(void __iomem *phy_base,
> +				 u32 dram_type)
> +{
> +	u32 cmd_drv, clk_drv, dqs_drv, dqs_odt;
> +	u32 i, j;
> +
> +	if (dram_type == DDR3) {
> +		cmd_drv = PHY_DDR3_RON_RTT_34ohm;
> +		clk_drv = PHY_DDR3_RON_RTT_45ohm;
> +		dqs_drv = PHY_DDR3_RON_RTT_34ohm;
> +		dqs_odt = PHY_DDR3_RON_RTT_225ohm;
> +	} else {
> +		cmd_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
> +		clk_drv = PHY_DDR4_LPDDR3_RON_RTT_43ohm;
> +		dqs_drv = PHY_DDR4_LPDDR3_RON_RTT_34ohm;
> +		if (dram_type == LPDDR2)
> +			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_DISABLE;
> +		else
> +			dqs_odt = PHY_DDR4_LPDDR3_RON_RTT_240ohm;
> +	}
> +	/* DS */
> +	writel(cmd_drv, PHY_REG(phy_base, 0x11));
> +	clrsetbits_le32(PHY_REG(phy_base, 0x12), 0x1f << 3, cmd_drv << 3);
> +	writel(clk_drv, PHY_REG(phy_base, 0x16));
> +	writel(clk_drv, PHY_REG(phy_base, 0x18));
> +
> +	for (i = 0; i < 4; i++) {
> +		j = 0x20 + i * 0x10;
> +		writel(dqs_drv, PHY_REG(phy_base, j));
> +		writel(dqs_drv, PHY_REG(phy_base, j + 0xf));
> +		/* ODT */
> +		writel(dqs_odt, PHY_REG(phy_base, j + 0x1));
> +		writel(dqs_odt, PHY_REG(phy_base, j + 0xe));
> +	}
> +}
> +
> +static void phy_soft_reset(void __iomem *phy_base)
> +{
> +	clrbits_le32(PHY_REG(phy_base, 0), 0x3 << 2);
> +	udelay(1);
> +	setbits_le32(PHY_REG(phy_base, 0), ANALOG_DERESET);
> +	udelay(5);
> +	setbits_le32(PHY_REG(phy_base, 0), DIGITAL_DERESET);
> +	udelay(1);
> +}
> +
> +static void phy_dram_set_bw(void __iomem *phy_base, u32 bw)
> +{
> +	if (bw == 2) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
> +		setbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
> +		setbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
> +	} else if (bw == 1) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
> +		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
> +		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
> +	} else if (bw == 0) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
> +		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
> +		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
> +		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
> +	}
> +
> +	phy_soft_reset(phy_base);
> +}
> +
> +static int phy_data_training(void __iomem *phy_base, u32 cs, u32 dramtype)
> +{
> +	u32 ret;
> +	u32 odt_val;
> +	u32 i, j;
> +
> +	odt_val = readl(PHY_REG(phy_base, 0x2e));
> +
> +	for (i = 0; i < 4; i++) {
> +		j = 0x20 + i * 0x10;
> +		writel(PHY_DDR3_RON_RTT_225ohm, PHY_REG(phy_base, j + 0x1));
> +		writel(0, PHY_REG(phy_base, j + 0xe));
> +	}
> +
> +	if (dramtype == DDR4) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0);
> +		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0);
> +		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0);
> +		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0);
> +	}
> +	/* choose training cs */
> +	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs));
> +	/* enable gate training */
> +	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 1);
> +	udelay(50);
> +	ret = readl(PHY_REG(phy_base, 0xff));
> +	/* disable gate training */
> +	clrsetbits_le32(PHY_REG(phy_base, 2), 0x33, (0x20 >> cs) | 0);
> +	clrbits_le32(PHY_REG(phy_base, 2), 0x30);
> +
> +	if (dramtype == DDR4) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0x29), 0x3, 0x2);
> +		clrsetbits_le32(PHY_REG(phy_base, 0x39), 0x3, 0x2);
> +		clrsetbits_le32(PHY_REG(phy_base, 0x49), 0x3, 0x2);
> +		clrsetbits_le32(PHY_REG(phy_base, 0x59), 0x3, 0x2);
> +	}
> +
> +	if (ret & 0x10) {
> +		ret = -1;
> +	} else {
> +		ret = (ret & 0xf) ^ (readl(PHY_REG(phy_base, 0)) >> 4);
> +		ret = (ret == 0) ? 0 : -1;
> +	}
> +
> +	for (i = 0; i < 4; i++) {
> +		j = 0x20 + i * 0x10;
> +		writel(odt_val, PHY_REG(phy_base, j + 0x1));
> +		writel(odt_val, PHY_REG(phy_base, j + 0xe));
> +	}
> +
> +	return ret;
> +}
> +
> +static void phy_cfg(void __iomem *phy_base,
> +		    struct ddr_phy_regs *phy_regs, struct ddr_phy_skew *skew,
> +		    struct px30_base_params *base, u32 bw)
> +{
> +	u32 i;
> +
> +	sdram_phy_dll_bypass_set(phy_base, base->ddr_freq);
> +	for (i = 0; phy_regs->phy[i][0] != 0xFFFFFFFF; i++) {
> +		writel(phy_regs->phy[i][1],
> +		       phy_base + phy_regs->phy[i][0]);
> +	}
> +	if (bw == 2) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 0xf << 4);
> +	} else if (bw == 1) {
> +		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 3 << 4);
> +		/* disable DQS2,DQS3 tx dll  for saving power */
> +		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
> +		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
> +	} else {
> +		clrsetbits_le32(PHY_REG(phy_base, 0), 0xf << 4, 1 << 4);
> +		/* disable DQS2,DQS3 tx dll  for saving power */
> +		clrbits_le32(PHY_REG(phy_base, 0x36), 1 << 3);
> +		clrbits_le32(PHY_REG(phy_base, 0x46), 1 << 3);
> +		clrbits_le32(PHY_REG(phy_base, 0x56), 1 << 3);
> +	}
> +	sdram_phy_set_ds_odt(phy_base, base->dramtype);
> +
> +	/* deskew */
> +	setbits_le32(PHY_REG(phy_base, 2), 8);
> +	sdram_copy_to_reg(PHY_REG(phy_base, 0xb0),
> +			  &skew->a0_a1_skew[0], 15 * 4);
> +	sdram_copy_to_reg(PHY_REG(phy_base, 0x70),
> +			  &skew->cs0_dm0_skew[0], 44 * 4);
> +	sdram_copy_to_reg(PHY_REG(phy_base, 0xc0),
> +			  &skew->cs1_dm0_skew[0], 44 * 4);
> +}
> +
> +void sdram_org_config(struct px30_sdram_channel *info,
> +		      struct px30_base_params *base,
> +		      u32 *p_os_reg2, u32 *p_os_reg3, u32 channel)
> +{
> +	*p_os_reg2 |= base->dramtype << SYS_REG_DDRTYPE_SHIFT;
> +	*p_os_reg2 |= (base->num_channels - 1) << SYS_REG_NUM_CH_SHIFT;
> +	*p_os_reg2 |= info->row_3_4 << SYS_REG_ROW_3_4_SHIFT(channel);
> +	*p_os_reg2 |= 1 << SYS_REG_CHINFO_SHIFT(channel);
> +	*p_os_reg2 |= (info->rank - 1) << SYS_REG_RANK_SHIFT(channel);
> +	*p_os_reg2 |= (info->col - 9) << SYS_REG_COL_SHIFT(channel);
> +	*p_os_reg2 |= info->bk == 3 ? 0 : 1 << SYS_REG_BK_SHIFT(channel);
> +	*p_os_reg2 |= (info->cs0_row - 13) << SYS_REG_CS0_ROW_SHIFT(channel);
> +	if (info->cs1_row >= 13)
> +		*p_os_reg2 |= (info->cs1_row - 13) << SYS_REG_CS1_ROW_SHIFT(channel);
> +	*p_os_reg2 |= (2 >> info->bw) << SYS_REG_BW_SHIFT(channel);
> +	*p_os_reg2 |= (2 >> info->dbw) << SYS_REG_DBW_SHIFT(channel);
> +}
> +
> +void sdram_msch_config(struct px30_msch_regs *msch,
> +		       struct px30_msch_timings *noc_timings,
> +		       struct px30_sdram_channel *cap_info,
> +		       struct px30_base_params *base)
> +{
> +	u64 cs_cap[2];
> +
> +	cs_cap[0] = sdram_get_cs_cap(cap_info, 0, base->dramtype);
> +	cs_cap[1] = sdram_get_cs_cap(cap_info, 1, base->dramtype);
> +	writel(((((cs_cap[1] >> 20) / 64) & 0xff) << 8) |
> +			(((cs_cap[0] >> 20) / 64) & 0xff),
> +			&msch->devicesize);
> +
> +	writel(noc_timings->ddrtiminga0, &msch->ddrtiminga0);
> +	writel(noc_timings->ddrtimingb0, &msch->ddrtimingb0);
> +	writel(noc_timings->ddrtimingc0, &msch->ddrtimingc0);
> +	writel(noc_timings->devtodev0, &msch->devtodev0);
> +	writel(noc_timings->ddrmode, &msch->ddrmode);
> +	writel(noc_timings->ddr4timing, &msch->ddr4timing);
> +	writel(noc_timings->agingx0, &msch->agingx0);
> +	writel(noc_timings->agingx0, &msch->aging0);
> +	writel(noc_timings->agingx0, &msch->aging1);
> +	writel(noc_timings->agingx0, &msch->aging2);
> +	writel(noc_timings->agingx0, &msch->aging3);
> +}
> +
> +int sdram_detect_bw(struct px30_sdram_channel *cap_info)
> +{
> +	return 0;
> +}
> +
> +int sdram_detect_cs(struct px30_sdram_channel *cap_info)
> +{
> +	return 0;
> +}
> +
> +int sdram_detect_col(struct px30_sdram_channel *cap_info,
> +		     u32 coltmp)
> +{
> +	void __iomem *test_addr;
> +	u32 col;
> +	u32 bw = cap_info->bw;
> +
> +	for (col = coltmp; col >= 9; col -= 1) {
> +		writel(0, CONFIG_SYS_SDRAM_BASE);
> +		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
> +				(1ul << (col + bw - 1ul)));
> +		writel(PATTERN, test_addr);
> +		if ((readl(test_addr) == PATTERN) &&
> +		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
> +			break;
> +	}
> +	if (col == 8) {
> +		printascii("col error\n");
> +		return -1;
> +	}
> +
> +	cap_info->col = col;
> +
> +	return 0;
> +}
> +
> +int sdram_detect_bank(struct px30_sdram_channel *cap_info,
> +		      u32 coltmp, u32 bktmp)
> +{
> +	void __iomem *test_addr;
> +	u32 bk;
> +	u32 bw = cap_info->bw;
> +
> +	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
> +			(1ul << (coltmp + bktmp + bw - 1ul)));
> +	writel(0, CONFIG_SYS_SDRAM_BASE);
> +	writel(PATTERN, test_addr);
> +	if ((readl(test_addr) == PATTERN) &&
> +	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
> +		bk = 3;
> +	else
> +		bk = 2;
> +
> +	cap_info->bk = bk;
> +
> +	return 0;
> +}
> +
> +/* detect bg for ddr4 */
> +int sdram_detect_bg(struct px30_sdram_channel *cap_info,
> +		    u32 coltmp)
> +{
> +	void __iomem *test_addr;
> +	u32 dbw;
> +	u32 bw = cap_info->bw;
> +
> +	test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
> +			(1ul << (coltmp + bw + 1ul)));
> +	writel(0, CONFIG_SYS_SDRAM_BASE);
> +	writel(PATTERN, test_addr);
> +	if ((readl(test_addr) == PATTERN) &&
> +	    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
> +		dbw = 0;
> +	else
> +		dbw = 1;
> +
> +	cap_info->dbw = dbw;
> +
> +	return 0;
> +}
> +
> +/* detect dbw for ddr3,lpddr2,lpddr3,lpddr4 */
> +int sdram_detect_dbw(struct px30_sdram_channel *cap_info, u32 dram_type)
> +{
> +	u32 row, col, bk, bw, cs_cap, cs;
> +	u32 die_bw_0 = 0, die_bw_1 = 0;
> +
> +	if (dram_type == DDR3 || dram_type == LPDDR4) {
> +		cap_info->dbw = 1;
> +	} else if (dram_type == LPDDR3 || dram_type == LPDDR2) {
> +		row = cap_info->cs0_row;
> +		col = cap_info->col;
> +		bk = cap_info->bk;
> +		cs = cap_info->rank;
> +		bw = cap_info->bw;
> +		cs_cap = (1 << (row + col + bk + bw - 20));
> +		if (bw == 2) {
> +			if (cs_cap <= 0x2000000) /* 256Mb */
> +				die_bw_0 = (col < 9) ? 2 : 1;
> +			else if (cs_cap <= 0x10000000) /* 2Gb */
> +				die_bw_0 = (col < 10) ? 2 : 1;
> +			else if (cs_cap <= 0x40000000) /* 8Gb */
> +				die_bw_0 = (col < 11) ? 2 : 1;
> +			else
> +				die_bw_0 = (col < 12) ? 2 : 1;
> +			if (cs > 1) {
> +				row = cap_info->cs1_row;
> +				cs_cap = (1 << (row + col + bk + bw - 20));
> +				if (cs_cap <= 0x2000000) /* 256Mb */
> +					die_bw_0 = (col < 9) ? 2 : 1;
> +				else if (cs_cap <= 0x10000000) /* 2Gb */
> +					die_bw_0 = (col < 10) ? 2 : 1;
> +				else if (cs_cap <= 0x40000000) /* 8Gb */
> +					die_bw_0 = (col < 11) ? 2 : 1;
> +				else
> +					die_bw_0 = (col < 12) ? 2 : 1;
> +			}
> +		} else {
> +			die_bw_1 = 1;
> +			die_bw_0 = 1;
> +		}
> +		cap_info->dbw = (die_bw_0 > die_bw_1) ? die_bw_0 : die_bw_1;
> +	}
> +
> +	return 0;
> +}
> +
> +int sdram_detect_row(struct px30_sdram_channel *cap_info,
> +		     u32 coltmp, u32 bktmp, u32 rowtmp)
> +{
> +	u32 row;
> +	u32 bw = cap_info->bw;
> +	void __iomem *test_addr;
> +
> +	for (row = rowtmp; row > 12; row--) {
> +		writel(0, CONFIG_SYS_SDRAM_BASE);
> +		test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
> +				(1ul << (row + bktmp + coltmp + bw - 1ul)));
> +		writel(PATTERN, test_addr);
> +		if ((readl(test_addr) == PATTERN) &&
> +		    (readl(CONFIG_SYS_SDRAM_BASE) == 0))
> +			break;
> +	}
> +	if (row == 12) {
> +		printascii("row error");
> +		return -1;
> +	}
> +
> +	cap_info->cs0_row = row;
> +
> +	return 0;
> +}
> +
> +int sdram_detect_row_3_4(struct px30_sdram_channel *cap_info,
> +			 u32 coltmp, u32 bktmp)
> +{
> +	u32 row_3_4;
> +	u32 bw = cap_info->bw;
> +	u32 row = cap_info->cs0_row;
> +	void __iomem *test_addr, *test_addr1;
> +
> +	test_addr = CONFIG_SYS_SDRAM_BASE;
> +	test_addr1 = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
> +			(0x3ul << (row + bktmp + coltmp + bw - 1ul - 1ul)));
> +
> +	writel(0, test_addr);
> +	writel(PATTERN, test_addr1);
> +	if ((readl(test_addr) == 0) && (readl(test_addr1) == PATTERN))
> +		row_3_4 = 0;
> +	else
> +		row_3_4 = 1;
> +
> +	cap_info->row_3_4 = row_3_4;
> +
> +	return 0;
> +}
> +
> +int sdram_detect_high_row(struct px30_sdram_channel *cap_info)
> +{
> +	cap_info->cs0_high16bit_row = cap_info->cs0_row;
> +	cap_info->cs1_high16bit_row = cap_info->cs1_row;
> +
> +	return 0;
> +}
> +
> +int sdram_detect_cs1_row(struct px30_sdram_channel *cap_info, u32 dram_type)
> +{
> +	void __iomem *test_addr;
> +	u32 row = 0, bktmp, coltmp, bw;
> +	ulong cs0_cap;
> +	u32 byte_mask;
> +
> +	if (cap_info->rank == 2) {
> +		cs0_cap = sdram_get_cs_cap(cap_info, 0, dram_type);
> +
> +		if (dram_type == DDR4) {
> +			if (cap_info->dbw == 0)
> +				bktmp = cap_info->bk + 2;
> +			else
> +				bktmp = cap_info->bk + 1;
> +		} else {
> +			bktmp = cap_info->bk;
> +		}
> +		bw = cap_info->bw;
> +		coltmp = cap_info->col;
> +
> +		/*
> +		 * because px30 support axi split,min bandwidth
> +		 * is 8bit. if cs0 is 32bit, cs1 may 32bit or 16bit
> +		 * so we check low 16bit data when detect cs1 row.
> +		 * if cs0 is 16bit/8bit, we check low 8bit data.
> +		 */
> +		if (bw == 2)
> +			byte_mask = 0xFFFF;
> +		else
> +			byte_mask = 0xFF;
> +
> +		/* detect cs1 row */
> +		for (row = cap_info->cs0_row; row > 12; row--) {
> +			test_addr = (void __iomem *)(CONFIG_SYS_SDRAM_BASE +
> +				    cs0_cap +
> +				    (1ul << (row + bktmp + coltmp + bw - 1ul)));
> +			writel(0, CONFIG_SYS_SDRAM_BASE + cs0_cap);
> +			writel(PATTERN, test_addr);
> +
> +			if (((readl(test_addr) & byte_mask) ==
> +			     (PATTERN & byte_mask)) &&
> +			    ((readl(CONFIG_SYS_SDRAM_BASE + cs0_cap) &
> +			      byte_mask) == 0)) {
> +				break;
> +			}
> +		}
> +	}
> +
> +	cap_info->cs1_row = row;
> +
> +	return 0;
> +}
> +
> +static void rkclk_ddr_reset(struct dram_info *dram,
> +			    u32 ctl_srstn, u32 ctl_psrstn,
> +			    u32 phy_srstn, u32 phy_psrstn)
> +{
> +	writel(upctl2_srstn_req(ctl_srstn) | upctl2_psrstn_req(ctl_psrstn) |
> +	       upctl2_asrstn_req(ctl_srstn),
> +	       &dram->cru->softrst_con[1]);
> +	writel(ddrphy_srstn_req(phy_srstn) | ddrphy_psrstn_req(phy_psrstn),
> +	       &dram->cru->softrst_con[2]);
> +}
> +
> +static void rkclk_set_dpll(struct dram_info *dram, unsigned int hz)
> +{
> +	unsigned int refdiv, postdiv1, postdiv2, fbdiv;
> +	int delay = 1000;
> +	u32 mhz = hz / MHz;
> +
> +	refdiv = 1;
> +	if (mhz <= 300) {
> +		postdiv1 = 4;
> +		postdiv2 = 2;
> +	} else if (mhz <= 400) {
> +		postdiv1 = 6;
> +		postdiv2 = 1;
> +	} else if (mhz <= 600) {
> +		postdiv1 = 4;
> +		postdiv2 = 1;
> +	} else if (mhz <= 800) {
> +		postdiv1 = 3;
> +		postdiv2 = 1;
> +	} else if (mhz <= 1600) {
> +		postdiv1 = 2;
> +		postdiv2 = 1;
> +	} else {
> +		postdiv1 = 1;
> +		postdiv2 = 1;
> +	}
> +	fbdiv = (mhz * refdiv * postdiv1 * postdiv2) / 24;
> +
> +	writel(DPLL_MODE(CLOCK_FROM_XIN_OSC), &dram->cru->mode);
> +
> +	writel(POSTDIV1(postdiv1) | FBDIV(fbdiv), &dram->cru->pll[1].con0);
> +	writel(DSMPD(1) | POSTDIV2(postdiv2) | REFDIV(refdiv),
> +	       &dram->cru->pll[1].con1);
> +
> +	while (delay > 0) {
> +		rockchip_udelay(1);
> +		if (LOCK(readl(&dram->cru->pll[1].con1)))
> +			break;
> +		delay--;
> +	}
> +
> +	writel(DPLL_MODE(CLOCK_FROM_PLL), &dram->cru->mode);
> +}
> +
> +static void rkclk_configure_ddr(struct dram_info *dram,
> +				struct px30_sdram_params *sdram_params)
> +{
> +	/* for inno ddr phy need 2*freq */
> +	rkclk_set_dpll(dram,  sdram_params->base.ddr_freq * MHz * 2);
> +}
> +
> +/* return ddrconfig value
> + *       (-1), find ddrconfig fail
> + *       other, the ddrconfig value
> + * only support cs0_row >= cs1_row
> + */
> +static unsigned int calculate_ddrconfig(struct px30_sdram_params *sdram_params)
> +{
> +	struct px30_sdram_channel *cap_info = &sdram_params->ch;
> +	u32 bw, die_bw, col, bank;
> +	u32 i, tmp;
> +	u32 ddrconf = -1;
> +
> +	bw = cap_info->bw;
> +	die_bw = cap_info->dbw;
> +	col = cap_info->col;
> +	bank = cap_info->bk;
> +
> +	if (sdram_params->base.dramtype == DDR4) {
> +		if (die_bw == 0)
> +			ddrconf = 7 + bw;
> +		else
> +			ddrconf = 12 - bw;
> +		ddrconf = d4_rbc_2_d3_rbc[ddrconf - 7];
> +	} else {
> +		tmp = ((bank - 2) << 3) | (col + bw - 10);
> +		for (i = 0; i < 7; i++)
> +			if ((ddr_cfg_2_rbc[i] & 0xf) == tmp) {
> +				ddrconf = i;
> +				break;
> +			}
> +		if (i > 6)
> +			printascii("calculate ddrconfig error\n");
> +	}
> +
> +	return ddrconf;
> +}
> +
> +/*
> + * rank = 1: cs0
> + * rank = 2: cs1
> + */
> +static void pctl_read_mr(void __iomem *pctl_base, u32 rank, u32 mr_num)
> +{
> +	writel((rank << 4) | (1 << 0), pctl_base + DDR_PCTL2_MRCTRL0);
> +	writel((mr_num << 8), pctl_base + DDR_PCTL2_MRCTRL1);
> +	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
> +	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
> +		continue;
> +	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
> +		continue;
> +}
> +
> +/* rank = 1: cs0
> + * rank = 2: cs1
> + * rank = 3: cs0 & cs1
> + * note: be careful of keep mr original val
> + */
> +static int pctl_write_mr(void __iomem *pctl_base, u32 rank, u32 mr_num, u32 arg,
> +			 u32 dramtype)
> +{
> +	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
> +		continue;
> +	if (dramtype == DDR3 || dramtype == DDR4) {
> +		writel((mr_num << 12) | (rank << 4) | (0 << 0),
> +		       pctl_base + DDR_PCTL2_MRCTRL0);
> +		writel(arg, pctl_base + DDR_PCTL2_MRCTRL1);
> +	} else {
> +		writel((rank << 4) | (0 << 0),
> +		       pctl_base + DDR_PCTL2_MRCTRL0);
> +		writel((mr_num << 8) | (arg & 0xff),
> +		       pctl_base + DDR_PCTL2_MRCTRL1);
> +	}
> +
> +	setbits_le32(pctl_base + DDR_PCTL2_MRCTRL0, 1u << 31);
> +	while (readl(pctl_base + DDR_PCTL2_MRCTRL0) & (1u << 31))
> +		continue;
> +	while (readl(pctl_base + DDR_PCTL2_MRSTAT) & MR_WR_BUSY)
> +		continue;
> +
> +	return 0;
> +}
> +
> +static int upctl2_update_ref_reg(void __iomem *pctl_base)
> +{
> +	u32 ret;
> +
> +	ret = readl(pctl_base + DDR_PCTL2_RFSHCTL3) ^ (1 << 1);
> +	writel(ret, pctl_base + DDR_PCTL2_RFSHCTL3);
> +
> +	return 0;
> +}
> +
> +static u32 pctl_dis_zqcs_aref(void __iomem *pctl_base)
> +{
> +	u32 dis_auto_zq = 0;
> +
> +	/* disable zqcs */
> +	if (!(readl(pctl_base + DDR_PCTL2_ZQCTL0) &
> +		(1ul << 31))) {
> +		dis_auto_zq = 1;
> +		setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
> +	}
> +
> +	/* disable auto refresh */
> +	setbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
> +
> +	upctl2_update_ref_reg(pctl_base);
> +
> +	return dis_auto_zq;
> +}
> +
> +static void pctl_rest_zqcs_aref(void __iomem *pctl_base, u32 dis_auto_zq)
> +{
> +	/* restore zqcs */
> +	if (dis_auto_zq)
> +		clrbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1 << 31);
> +
> +	/* restore auto refresh */
> +	clrbits_le32(pctl_base + DDR_PCTL2_RFSHCTL3, 1);
> +
> +	upctl2_update_ref_reg(pctl_base);
> +}
> +
> +/*
> + * rank : 1:cs0, 2:cs1, 3:cs0&cs1
> + * vrefrate: 4500: 45%,
> + */
> +static int pctl_write_vrefdq(void __iomem *pctl_base, u32 rank, u32 vrefrate,
> +			     u32 dramtype)
> +{
> +	u32 tccd_l, value;
> +	u32 dis_auto_zq = 0;
> +
> +	if (dramtype != DDR4 || vrefrate < 4500 ||
> +	    vrefrate > 9200)
> +		return (-1);
> +
> +	tccd_l = (readl(pctl_base + DDR_PCTL2_DRAMTMG4) >> 16) & 0xf;
> +	tccd_l = (tccd_l - 4) << 10;
> +
> +	if (vrefrate > 7500) {
> +		/* range 1 */
> +		value = ((vrefrate - 6000) / 65) | tccd_l;
> +	} else {
> +		/* range 2 */
> +		value = ((vrefrate - 4500) / 65) | tccd_l | (1 << 6);
> +	}
> +
> +	dis_auto_zq = pctl_dis_zqcs_aref(pctl_base);
> +
> +	/* enable vrefdq calibratin */
> +	pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
> +	udelay(1);/* tvrefdqe */
> +	/* write vrefdq value */
> +	pctl_write_mr(pctl_base, rank, 6, value | (1 << 7), dramtype);
> +	udelay(1);/* tvref_time */
> +	pctl_write_mr(pctl_base, rank, 6, value | (0 << 7), dramtype);
> +	udelay(1);/* tvrefdqx */
> +
> +	pctl_rest_zqcs_aref(pctl_base, dis_auto_zq);
> +
> +	return 0;
> +}
> +
> +static u32 pctl_remodify_sdram_params(struct ddr_pctl_regs *pctl_regs,
> +				      struct px30_sdram_channel *cap_info,
> +			       u32 dram_type)
> +{
> +	u32 tmp = 0, tmp_adr = 0, i;
> +
> +	for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
> +		if (pctl_regs->pctl[i][0] == 0) {
> +			tmp = pctl_regs->pctl[i][1];/* MSTR */
> +			tmp_adr = i;
> +		}
> +	}
> +
> +	tmp &= ~((3ul << 30) | (3ul << 24) | (3ul << 12));
> +
> +	switch (cap_info->dbw) {
> +	case 2:
> +		tmp |= (3ul << 30);
> +		break;
> +	case 1:
> +		tmp |= (2ul << 30);
> +		break;
> +	case 0:
> +	default:
> +		tmp |= (1ul << 30);
> +		break;
> +	}
> +
> +	/*
> +	 * If DDR3 or DDR4 MSTR.active_ranks=1,
> +	 * it will gate memory clock when enter power down.
> +	 * Force set active_ranks to 3 to workaround it.
> +	 */
> +	if (cap_info->rank == 2 || dram_type == DDR3 ||
> +	    dram_type == DDR4)
> +		tmp |= 3 << 24;
> +	else
> +		tmp |= 1 << 24;
> +
> +	tmp |= (2 - cap_info->bw) << 12;
> +
> +	pctl_regs->pctl[tmp_adr][1] = tmp;
> +
> +	return 0;
> +}
> +
> +static int pctl_cfg(void __iomem *pctl_base, struct ddr_pctl_regs *pctl_regs,
> +		    u32 sr_idle, u32 pd_idle)
> +{
> +	u32 i;
> +
> +	for (i = 0; pctl_regs->pctl[i][0] != 0xFFFFFFFF; i++) {
> +		writel(pctl_regs->pctl[i][1],
> +		       pctl_base + pctl_regs->pctl[i][0]);
> +	}
> +	clrsetbits_le32(pctl_base + DDR_PCTL2_PWRTMG,
> +			(0xff << 16) | 0x1f,
> +			((sr_idle & 0xff) << 16) | (pd_idle & 0x1f));
> +
> +	clrsetbits_le32(pctl_base + DDR_PCTL2_HWLPCTL,
> +			0xfff << 16,
> +			5 << 16);
> +	/* disable zqcs */
> +	setbits_le32(pctl_base + DDR_PCTL2_ZQCTL0, 1u << 31);
> +
> +	return 0;
> +}
> +
> +/*
> + * calculate controller dram address map, and setting to register.
> + * argument sdram_params->ch.ddrconf must be right value before
> + * call this function.
> + */
> +static void set_ctl_address_map(struct dram_info *dram,
> +				struct px30_sdram_params *sdram_params)
> +{
> +	struct px30_sdram_channel *cap_info = &sdram_params->ch;
> +	void __iomem *pctl_base = dram->pctl;
> +	u32 cs_pst, bg, max_row, ddrconf;
> +	u32 i;
> +
> +	if (sdram_params->base.dramtype == DDR4)
> +		/*
> +		 * DDR4 8bit dram BG = 2(4bank groups),
> +		 * 16bit dram BG = 1 (2 bank groups)
> +		 */
> +		bg = (cap_info->dbw == 0) ? 2 : 1;
> +	else
> +		bg = 0;
> +
> +	cs_pst = cap_info->bw + cap_info->col +
> +		bg + cap_info->bk + cap_info->cs0_row;
> +	if (cs_pst >= 32 || cap_info->rank == 1)
> +		writel(0x1f, pctl_base + DDR_PCTL2_ADDRMAP0);
> +	else
> +		writel(cs_pst - 8, pctl_base + DDR_PCTL2_ADDRMAP0);
> +
> +	ddrconf = cap_info->ddrconfig;
> +	if (sdram_params->base.dramtype == DDR4) {
> +		for (i = 0; i < ARRAY_SIZE(d4_rbc_2_d3_rbc); i++) {
> +			if (d4_rbc_2_d3_rbc[i] == ddrconf) {
> +				ddrconf = 7 + i;
> +				break;
> +			}
> +		}
> +	}
> +
> +	sdram_copy_to_reg((u32 *)(pctl_base + DDR_PCTL2_ADDRMAP1),
> +			  &addrmap[ddrconf][0], 8 * 4);
> +	max_row = cs_pst - 1 - 8 - (addrmap[ddrconf][5] & 0xf);
> +
> +	if (max_row < 12)
> +		printascii("set addrmap fail\n");
> +	/* need to disable row ahead of rank by set to 0xf */
> +	for (i = 17; i > max_row; i--)
> +		clrsetbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6 +
> +			((i - 12) * 8 / 32) * 4,
> +			0xf << ((i - 12) * 8 % 32),
> +			0xf << ((i - 12) * 8 % 32));
> +
> +	if ((sdram_params->base.dramtype == LPDDR3 ||
> +	     sdram_params->base.dramtype == LPDDR2) &&
> +		 cap_info->row_3_4)
> +		setbits_le32(pctl_base + DDR_PCTL2_ADDRMAP6, 1 << 31);
> +	if (sdram_params->base.dramtype == DDR4 && cap_info->bw != 0x2)
> +		setbits_le32(pctl_base + DDR_PCTL2_PCCFG, 1 << 8);
> +}
> +
> +/*
> + * rank = 1: cs0
> + * rank = 2: cs1
> + */
> +int read_mr(struct dram_info *dram, u32 rank, u32 mr_num)
> +{
> +	void __iomem *ddr_grf_base = dram->ddr_grf;
> +
> +	pctl_read_mr(dram->pctl, rank, mr_num);
> +
> +	return (readl(ddr_grf_base + DDR_GRF_STATUS(0)) & 0xff);
> +}
> +
> +#define MIN(a, b)	(((a) > (b)) ? (b) : (a))
> +#define MAX(a, b)	(((a) > (b)) ? (a) : (b))
> +static u32 check_rd_gate(struct dram_info *dram)
> +{
> +	void __iomem *phy_base = dram->phy;
> +
> +	u32 max_val = 0;
> +	u32 min_val = 0xff;
> +	u32 gate[4];
> +	u32 i, bw;
> +
> +	bw = (readl(PHY_REG(phy_base, 0x0)) >> 4) & 0xf;
> +	switch (bw) {
> +	case 0x1:
> +		bw = 1;
> +		break;
> +	case 0x3:
> +		bw = 2;
> +		break;
> +	case 0xf:
> +	default:
> +		bw = 4;
> +		break;
> +	}
> +
> +	for (i = 0; i < bw; i++) {
> +		gate[i] = readl(PHY_REG(phy_base, 0xfb + i));
> +		max_val = MAX(max_val, gate[i]);
> +		min_val = MIN(min_val, gate[i]);
> +	}
> +
> +	if (max_val > 0x80 || min_val < 0x20)
> +		return -1;
> +	else
> +		return 0;
> +}
> +
> +static int data_training(struct dram_info *dram, u32 cs, u32 dramtype)
> +{
> +	void __iomem *pctl_base = dram->pctl;
> +	u32 dis_auto_zq = 0;
> +	u32 pwrctl;
> +	u32 ret;
> +
> +	/* disable auto low-power */
> +	pwrctl = readl(pctl_base + DDR_PCTL2_PWRCTL);
> +	writel(0, pctl_base + DDR_PCTL2_PWRCTL);
> +
> +	dis_auto_zq = pctl_dis_zqcs_aref(dram->pctl);
> +
> +	ret = phy_data_training(dram->phy, cs, dramtype);
> +
> +	pctl_rest_zqcs_aref(dram->pctl, dis_auto_zq);
> +
> +	/* restore auto low-power */
> +	writel(pwrctl, pctl_base + DDR_PCTL2_PWRCTL);
> +
> +	return ret;
> +}
> +
> +static void dram_set_bw(struct dram_info *dram, u32 bw)
> +{
> +	phy_dram_set_bw(dram->phy, bw);
> +}
> +
> +static void set_ddrconfig(struct dram_info *dram, u32 ddrconfig)
> +{
> +	writel(ddrconfig | (ddrconfig << 8), &dram->msch->deviceconf);
> +	rk_clrsetreg(&dram->grf->soc_noc_con[1], 0x3 << 14, 0 << 14);
> +}
> +
> +static void dram_all_config(struct dram_info *dram,
> +			    struct px30_sdram_params *sdram_params)
> +{
> +	struct px30_sdram_channel *cap_info = &sdram_params->ch;
> +	u32 sys_reg2 = 0;
> +	u32 sys_reg3 = 0;
> +
> +	set_ddrconfig(dram, cap_info->ddrconfig);
> +	sdram_org_config(cap_info, &sdram_params->base, &sys_reg2,
> +			 &sys_reg3, 0);
> +	writel(sys_reg2, &dram->pmugrf->os_reg[2]);
> +	writel(sys_reg3, &dram->pmugrf->os_reg[3]);
> +	sdram_msch_config(dram->msch, &sdram_params->ch.noc_timings, cap_info,
> +			  &sdram_params->base);
> +}
> +
> +static void enable_low_power(struct dram_info *dram,
> +			     struct px30_sdram_params *sdram_params)
> +{
> +	void __iomem *pctl_base = dram->pctl;
> +	void __iomem *phy_base = dram->phy;
> +	void __iomem *ddr_grf_base = dram->ddr_grf;
> +	u32 grf_lp_con;
> +
> +	/*
> +	 * bit0: grf_upctl_axi_cg_en = 1 enable upctl2 axi clk auto gating
> +	 * bit1: grf_upctl_apb_cg_en = 1 ungated axi,core clk for apb access
> +	 * bit2: grf_upctl_core_cg_en = 1 enable upctl2 core clk auto gating
> +	 * bit3: grf_selfref_type2_en = 0 disable core clk gating when type2 sr
> +	 * bit4: grf_upctl_syscreq_cg_en = 1
> +	 *       ungating coreclk when c_sysreq assert
> +	 * bit8-11: grf_auto_sr_dly = 6
> +	 */
> +	writel(0x1f1f0617, &dram->ddr_grf->ddr_grf_con[1]);
> +
> +	if (sdram_params->base.dramtype == DDR4)
> +		grf_lp_con = (0x7 << 16) | (1 << 1);
> +	else if (sdram_params->base.dramtype == DDR3)
> +		grf_lp_con = (0x7 << 16) | (1 << 0);
> +	else
> +		grf_lp_con = (0x7 << 16) | (1 << 2);
> +
> +	/* en lpckdis_en */
> +	grf_lp_con = grf_lp_con | (0x1 << (9 + 16)) | (0x1 << 9);
> +	writel(grf_lp_con, ddr_grf_base + DDR_GRF_LP_CON);
> +
> +	/* off digit module clock when enter power down */
> +	setbits_le32(PHY_REG(phy_base, 7), 1 << 7);
> +
> +	/* enable sr, pd */
> +	if (PD_IDLE == 0)
> +		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
> +	else
> +		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 1));
> +	if (SR_IDLE == 0)
> +		clrbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
> +	else
> +		setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, 1);
> +	setbits_le32(pctl_base + DDR_PCTL2_PWRCTL, (1 << 3));
> +}
> +
> +/*
> + * pre_init: 0: pre init for dram cap detect
> + * 1: detect correct cap(except cs1 row)info, than reinit
> + * 2: after reinit, we detect cs1_row, if cs1_row not equal
> + *    to cs0_row and cs is in middle on ddrconf map, we need
> + *    to reinit dram, than set the correct ddrconf.
> + */
> +static int sdram_init_(struct dram_info *dram,
> +		       struct px30_sdram_params *sdram_params, u32 pre_init)
> +{
> +	struct px30_sdram_channel *cap_info = &sdram_params->ch;
> +	void __iomem *pctl_base = dram->pctl;
> +
> +	rkclk_ddr_reset(dram, 1, 1, 1, 1);
> +	rockchip_udelay(10);
> +	/*
> +	 * dereset ddr phy psrstn to config pll,
> +	 * if using phy pll psrstn must be dereset
> +	 * before config pll
> +	 */
> +	rkclk_ddr_reset(dram, 1, 1, 1, 0);
> +	rkclk_configure_ddr(dram, sdram_params);
> +
> +	/* release phy srst to provide clk to ctrl */
> +	rkclk_ddr_reset(dram, 1, 1, 0, 0);
> +	rockchip_udelay(10);
> +	phy_soft_reset(dram->phy);
> +
> +	/* release ctrl presetn, and config ctl registers */
> +	rkclk_ddr_reset(dram, 1, 0, 0, 0);
> +	pctl_cfg(dram->pctl, &sdram_params->pctl_regs, SR_IDLE, PD_IDLE);
> +	cap_info->ddrconfig = calculate_ddrconfig(sdram_params);
> +	set_ctl_address_map(dram, sdram_params);
> +	phy_cfg(dram->phy, &sdram_params->phy_regs, sdram_params->skew,
> +		&sdram_params->base, cap_info->bw);
> +
> +	/* enable dfi_init_start to init phy after ctl srstn deassert */
> +	setbits_le32(pctl_base + DDR_PCTL2_DFIMISC, (1 << 5) | (1 << 4));
> +
> +	rkclk_ddr_reset(dram, 0, 0, 0, 0);
> +	/* wait for dfi_init_done and dram init complete */
> +	while ((readl(pctl_base + DDR_PCTL2_STAT) & 0x7) == 0)
> +		continue;
> +
> +	if (sdram_params->base.dramtype == LPDDR3)
> +		pctl_write_mr(dram->pctl, 3, 11, 3, LPDDR3);
> +
> +	/* do ddr gate training */
> +redo_cs0_training:
> +	if (data_training(dram, 0, sdram_params->base.dramtype) != 0) {
> +		if (pre_init != 0)
> +			printascii("DTT cs0 error\n");
> +		return -1;
> +	}
> +	if (check_rd_gate(dram)) {
> +		printascii("re training cs0");
> +		goto redo_cs0_training;
> +	}
> +
> +	if (sdram_params->base.dramtype == LPDDR3) {
> +		if ((read_mr(dram, 1, 8) & 0x3) != 0x3)
> +			return -1;
> +	} else if (sdram_params->base.dramtype == LPDDR2) {
> +		if ((read_mr(dram, 1, 8) & 0x3) != 0x0)
> +			return -1;
> +	}
> +
> +	/* for px30: when 2cs, both 2 cs should be training */
> +	if (pre_init != 0 && cap_info->rank == 2) {
> +redo_cs1_training:
> +		if (data_training(dram, 1, sdram_params->base.dramtype) != 0) {
> +			printascii("DTT cs1 error\n");
> +			return -1;
> +		}
> +		if (check_rd_gate(dram)) {
> +			printascii("re training cs1");
> +			goto redo_cs1_training;
> +		}
> +	}
> +
> +	if (sdram_params->base.dramtype == DDR4)
> +		pctl_write_vrefdq(dram->pctl, 0x3, 5670,
> +				  sdram_params->base.dramtype);
> +
> +	dram_all_config(dram, sdram_params);
> +	enable_low_power(dram, sdram_params);
> +
> +	return 0;
> +}
> +
> +static int dram_detect_cap(struct dram_info *dram,
> +			   struct px30_sdram_params *sdram_params,
> +			   unsigned char channel)
> +{
> +	struct px30_sdram_channel *cap_info = &sdram_params->ch;
> +
> +	/*
> +	 * for ddr3: ddrconf = 3
> +	 * for ddr4: ddrconf = 12
> +	 * for lpddr3: ddrconf = 3
> +	 * default bw = 1
> +	 */
> +	u32 bk, bktmp;
> +	u32 col, coltmp;
> +	u32 rowtmp;
> +	u32 cs;
> +	u32 bw = 1;
> +	u32 dram_type = sdram_params->base.dramtype;
> +
> +	if (dram_type != DDR4) {
> +		/* detect col and bk for ddr3/lpddr3 */
> +		coltmp = 12;
> +		bktmp = 3;
> +		if (dram_type == LPDDR2)
> +			rowtmp = 15;
> +		else
> +			rowtmp = 16;
> +
> +		if (sdram_detect_col(cap_info, coltmp) != 0)
> +			goto cap_err;
> +		sdram_detect_bank(cap_info, coltmp, bktmp);
> +		sdram_detect_dbw(cap_info, dram_type);
> +	} else {
> +		/* detect bg for ddr4 */
> +		coltmp = 10;
> +		bktmp = 4;
> +		rowtmp = 17;
> +
> +		col = 10;
> +		bk = 2;
> +		cap_info->col = col;
> +		cap_info->bk = bk;
> +		sdram_detect_bg(cap_info, coltmp);
> +	}
> +
> +	/* detect row */
> +	if (sdram_detect_row(cap_info, coltmp, bktmp, rowtmp) != 0)
> +		goto cap_err;
> +
> +	/* detect row_3_4 */
> +	sdram_detect_row_3_4(cap_info, coltmp, bktmp);
> +
> +	/* bw and cs detect using data training */
> +	if (data_training(dram, 1, dram_type) == 0)
> +		cs = 1;
> +	else
> +		cs = 0;
> +	cap_info->rank = cs + 1;
> +
> +	dram_set_bw(dram, 2);
> +	if (data_training(dram, 0, dram_type) == 0)
> +		bw = 2;
> +	else
> +		bw = 1;
> +	cap_info->bw = bw;
> +
> +	cap_info->cs0_high16bit_row = cap_info->cs0_row;
> +	if (cs) {
> +		cap_info->cs1_row = cap_info->cs0_row;
> +		cap_info->cs1_high16bit_row = cap_info->cs0_row;
> +	} else {
> +		cap_info->cs1_row = 0;
> +		cap_info->cs1_high16bit_row = 0;
> +	}
> +
> +	return 0;
> +cap_err:
> +	return -1;
> +}
> +
> +static int sdram_init_detect(struct dram_info *dram,
> +			     struct px30_sdram_params *sdram_params)
> +{
> +	struct px30_sdram_channel *cap_info = &sdram_params->ch;
> +	u32 ret;
> +	u32 sys_reg = 0;
> +	u32 sys_reg3 = 0;
> +
> +	if (sdram_init_(dram, sdram_params, 0) != 0)
> +		return -1;
> +
> +	if (dram_detect_cap(dram, sdram_params, 0) != 0)
> +		return -1;
> +
> +	/* modify bw, cs related timing */
> +	pctl_remodify_sdram_params(&sdram_params->pctl_regs, cap_info,
> +				   sdram_params->base.dramtype);
> +	/* reinit sdram by real dram cap */
> +	ret = sdram_init_(dram, sdram_params, 1);
> +	if (ret != 0)
> +		goto out;
> +
> +	/* redetect cs1 row */
> +	sdram_detect_cs1_row(cap_info, sdram_params->base.dramtype);
> +	if (cap_info->cs1_row) {
> +		sys_reg = readl(&dram->pmugrf->os_reg[2]);
> +		sys_reg3 = readl(&dram->pmugrf->os_reg[3]);
> +		writel(sys_reg, &dram->pmugrf->os_reg[2]);
> +		writel(sys_reg3, &dram->pmugrf->os_reg[3]);
> +	}
> +
> +	ret = sdram_detect_high_row(cap_info);
> +
> +out:
> +	return ret;
> +}
> +
> +struct px30_sdram_params *get_default_sdram_config(void)
> +{
> +	sdram_configs[0].skew = &skew;
> +
> +	return &sdram_configs[0];
> +}
> +
> +int sdram_init(void)
> +{
> +	struct px30_sdram_params *sdram_params;
> +	int ret = 0;
> +
> +	dram_info.phy = (void *)DDR_PHY_BASE_ADDR;
> +	dram_info.pctl = (void *)DDRC_BASE_ADDR;
> +	dram_info.grf = (void *)GRF_BASE_ADDR;
> +	dram_info.cru = (void *)CRU_BASE_ADDR;
> +	dram_info.msch = (void *)SERVER_MSCH0_BASE_ADDR;
> +	dram_info.ddr_grf = (void *)DDR_GRF_BASE_ADDR;
> +	dram_info.pmugrf = (void *)PMUGRF_BASE_ADDR;
> +
> +	sdram_params = get_default_sdram_config();
> +	ret = sdram_init_detect(&dram_info, sdram_params);
> +	if (ret)
> +		return ret;
> +
> +	return ret;
> +}
> +#endif /* CONFIG_TPL_BUILD */
> diff --git a/arch/arm/mach-rockchip/px30/syscon_px30.c b/arch/arm/mach-rockchip/px30/syscon_px30.c
> new file mode 100644
> index 0000000000..0331491b40
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/px30/syscon_px30.c
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * (C) Copyright 2017 Rockchip Electronics Co., Ltd
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <syscon.h>
> +#include <asm/arch-rockchip/clock.h>
> +
> +static const struct udevice_id px30_syscon_ids[] = {
> +	{ .compatible = "rockchip,px30-pmu", .data = ROCKCHIP_SYSCON_PMU },
> +	{ .compatible = "rockchip,px30-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
> +	{ .compatible = "rockchip,px30-grf", .data = ROCKCHIP_SYSCON_GRF },
> +	{ }
> +};
> +
> +U_BOOT_DRIVER(syscon_px30) = {
> +	.id = UCLASS_SYSCON,
> +	.name = "px30_syscon",
> +	.of_match = px30_syscon_ids,
> +};
> +
> +#if CONFIG_IS_ENABLED(OF_PLATDATA)
> +static int px30_syscon_bind_of_platdata(struct udevice *dev)
> +{
> +	dev->driver_data = dev->driver->of_match->data;
> +	debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
> +
> +	return 0;
> +}
> +
> +U_BOOT_DRIVER(rockchip_px30_pmu) = {
> +	.name = "rockchip_px30_pmu",
> +	.id = UCLASS_SYSCON,
> +	.of_match = px30_syscon_ids,
> +	.bind = px30_syscon_bind_of_platdata,
> +};
> +
> +U_BOOT_DRIVER(rockchip_px30_pmugrf) = {
> +	.name = "rockchip_px30_pmugrf",
> +	.id = UCLASS_SYSCON,
> +	.of_match = px30_syscon_ids + 1,
> +	.bind = px30_syscon_bind_of_platdata,
> +};
> +
> +U_BOOT_DRIVER(rockchip_px30_grf) = {
> +	.name = "rockchip_px30_grf",
> +	.id = UCLASS_SYSCON,
> +	.of_match = px30_syscon_ids + 2,
> +	.bind = px30_syscon_bind_of_platdata,
> +};
> +#endif

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

* [U-Boot] [PATCH 12/12] rockchip: add px30-evb board
  2019-10-24 23:28 ` [U-Boot] [PATCH 12/12] rockchip: add px30-evb board Heiko Stuebner
@ 2019-10-25  2:51   ` Kever Yang
  0 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-10-25  2:51 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:28, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
>
> The px30 evb is an evaluation board for the px30 together with a dsi-
> connected display. This adds board and config files for it.
>
> Signed-off-by: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>


Reviewed-by: Kever Yang<kever.yang@rock-chips.com>


Thanks,
- Kever
> ---
>   board/rockchip/evb_px30/Kconfig     |  15 ++++
>   board/rockchip/evb_px30/MAINTAINERS |   6 ++
>   board/rockchip/evb_px30/Makefile    |   7 ++
>   board/rockchip/evb_px30/evb_px30.c  |   4 +
>   configs/evb-px30_defconfig          | 113 ++++++++++++++++++++++++++++
>   include/configs/evb_px30.h          |  19 +++++
>   6 files changed, 164 insertions(+)
>   create mode 100644 board/rockchip/evb_px30/Kconfig
>   create mode 100644 board/rockchip/evb_px30/MAINTAINERS
>   create mode 100644 board/rockchip/evb_px30/Makefile
>   create mode 100644 board/rockchip/evb_px30/evb_px30.c
>   create mode 100644 configs/evb-px30_defconfig
>   create mode 100644 include/configs/evb_px30.h
>
> diff --git a/board/rockchip/evb_px30/Kconfig b/board/rockchip/evb_px30/Kconfig
> new file mode 100644
> index 0000000000..0042c8e4db
> --- /dev/null
> +++ b/board/rockchip/evb_px30/Kconfig
> @@ -0,0 +1,15 @@
> +if TARGET_EVB_PX30
> +
> +config SYS_BOARD
> +	default "evb_px30"
> +
> +config SYS_VENDOR
> +	default "rockchip"
> +
> +config SYS_CONFIG_NAME
> +	default "evb_px30"
> +
> +config BOARD_SPECIFIC_OPTIONS # dummy
> +	def_bool y
> +
> +endif
> diff --git a/board/rockchip/evb_px30/MAINTAINERS b/board/rockchip/evb_px30/MAINTAINERS
> new file mode 100644
> index 0000000000..cf13f2419e
> --- /dev/null
> +++ b/board/rockchip/evb_px30/MAINTAINERS
> @@ -0,0 +1,6 @@
> +EVB-PX30
> +M:      Kever Yang <kever.yang@rock-chips.com>
> +S:      Maintained
> +F:      board/rockchip/evb_px30
> +F:      include/configs/evb_px30.h
> +F:      configs/evb-px30_defconfig
> diff --git a/board/rockchip/evb_px30/Makefile b/board/rockchip/evb_px30/Makefile
> new file mode 100644
> index 0000000000..74b0b9f44f
> --- /dev/null
> +++ b/board/rockchip/evb_px30/Makefile
> @@ -0,0 +1,7 @@
> +#
> +# (C) Copyright 2017 Rockchip Electronics Co., Ltd
> +#
> +# SPDX-License-Identifier:     GPL-2.0+
> +#
> +
> +obj-y	+= evb_px30.o
> diff --git a/board/rockchip/evb_px30/evb_px30.c b/board/rockchip/evb_px30/evb_px30.c
> new file mode 100644
> index 0000000000..29464ae63e
> --- /dev/null
> +++ b/board/rockchip/evb_px30/evb_px30.c
> @@ -0,0 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * (C) Copyright 2019 Rockchip Electronics Co., Ltd
> + */
> diff --git a/configs/evb-px30_defconfig b/configs/evb-px30_defconfig
> new file mode 100644
> index 0000000000..d1cc1788c9
> --- /dev/null
> +++ b/configs/evb-px30_defconfig
> @@ -0,0 +1,113 @@
> +CONFIG_ARM=y
> +CONFIG_ARCH_ROCKCHIP=y
> +CONFIG_SYS_TEXT_BASE=0x00200000
> +CONFIG_SPL_LIBCOMMON_SUPPORT=y
> +CONFIG_SPL_LIBGENERIC_SUPPORT=y
> +CONFIG_SYS_MALLOC_F_LEN=0x2000
> +CONFIG_ROCKCHIP_PX30=y
> +CONFIG_TARGET_EVB_PX30=y
> +CONFIG_TPL_LIBGENERIC_SUPPORT=y
> +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_SPL_STACK_R_ADDR=0x600000
> +CONFIG_DEBUG_UART_BASE=0xFF178000
> +CONFIG_DEBUG_UART_CLOCK=24000000
> +CONFIG_DEBUG_UART=y
> +CONFIG_TPL_SYS_MALLOC_F_LEN=0x600
> +# CONFIG_ANDROID_BOOT_IMAGE is not set
> +CONFIG_FIT=y
> +CONFIG_FIT_VERBOSE=y
> +CONFIG_SPL_LOAD_FIT=y
> +# CONFIG_CONSOLE_MUX is not set
> +CONFIG_DEFAULT_FDT_FILE="rockchip/px30-evb.dtb"
> +CONFIG_MISC_INIT_R=y
> +# CONFIG_DISPLAY_CPUINFO is not set
> +CONFIG_DISPLAY_BOARDINFO_LATE=y
> +CONFIG_SPL_BOUNCE_BUFFER_STATIC=y
> +CONFIG_SPL_TEXT_BASE=0x00000000
> +# CONFIG_SPL_BOARD_INIT is not set
> +CONFIG_SPL_BOOTROM_SUPPORT=y
> +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
> +# CONFIG_SPL_LEGACY_IMAGE_SUPPORT is not set
> +CONFIG_SPL_STACK_R=y
> +# CONFIG_TPL_BANNER_PRINT is not set
> +CONFIG_SPL_CRC32_SUPPORT=y
> +CONFIG_SPL_ATF=y
> +# CONFIG_TPL_FRAMEWORK is not set
> +# CONFIG_CMD_BOOTD is not set
> +# CONFIG_CMD_ELF is not set
> +# CONFIG_CMD_IMI is not set
> +# CONFIG_CMD_XIMG is not set
> +# CONFIG_CMD_LZMADEC is not set
> +# CONFIG_CMD_UNZIP is not set
> +# CONFIG_CMD_FLASH is not set
> +CONFIG_CMD_GPT=y
> +# CONFIG_CMD_LOADB is not set
> +# CONFIG_CMD_LOADS is not set
> +CONFIG_CMD_MMC=y
> +CONFIG_CMD_USB=y
> +CONFIG_CMD_USB_MASS_STORAGE=y
> +# CONFIG_CMD_ITEST is not set
> +# CONFIG_CMD_SETEXPR is not set
> +# CONFIG_CMD_MISC is not set
> +# CONFIG_SPL_DOS_PARTITION is not set
> +# CONFIG_ISO_PARTITION is not set
> +CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=64
> +CONFIG_SPL_OF_CONTROL=y
> +CONFIG_OF_LIVE=y
> +CONFIG_DEFAULT_DEVICE_TREE="px30-evb"
> +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
> +CONFIG_ENV_IS_IN_MMC=y
> +CONFIG_REGMAP=y
> +CONFIG_SPL_REGMAP=y
> +CONFIG_SYSCON=y
> +CONFIG_SPL_SYSCON=y
> +CONFIG_CLK=y
> +CONFIG_SPL_CLK=y
> +CONFIG_FASTBOOT_BUF_ADDR=0x800800
> +CONFIG_FASTBOOT_BUF_SIZE=0x04000000
> +CONFIG_FASTBOOT_FLASH=y
> +CONFIG_FASTBOOT_FLASH_MMC_DEV=0
> +CONFIG_ROCKCHIP_GPIO=y
> +CONFIG_SYS_I2C_ROCKCHIP=y
> +CONFIG_MISC=y
> +CONFIG_ROCKCHIP_OTP=y
> +CONFIG_MMC_DW=y
> +CONFIG_MMC_DW_ROCKCHIP=y
> +CONFIG_DM_ETH=y
> +CONFIG_ETH_DESIGNWARE=y
> +CONFIG_GMAC_ROCKCHIP=y
> +CONFIG_PHY_REALTEK=y
> +CONFIG_PINCTRL=y
> +CONFIG_DM_PMIC=y
> +CONFIG_PMIC_RK8XX=y
> +CONFIG_REGULATOR_PWM=y
> +CONFIG_DM_REGULATOR_FIXED=y
> +CONFIG_REGULATOR_RK8XX=y
> +CONFIG_PWM_ROCKCHIP=y
> +CONFIG_RAM=y
> +CONFIG_SPL_RAM=y
> +CONFIG_DM_RESET=y
> +# CONFIG_SPECIFY_CONSOLE_INDEX is not set
> +# CONFIG_TPL_DM_SERIAL is not set
> +CONFIG_DEBUG_UART_SHIFT=2
> +CONFIG_DEBUG_UART_SKIP_INIT=y
> +CONFIG_SOUND=y
> +CONFIG_SYSRESET=y
> +CONFIG_OPTEE=y
> +CONFIG_DM_THERMAL=y
> +CONFIG_USB=y
> +CONFIG_USB_EHCI_HCD=y
> +CONFIG_USB_EHCI_GENERIC=y
> +CONFIG_USB_GADGET=y
> +CONFIG_USB_GADGET_DWC2_OTG=y
> +CONFIG_DM_VIDEO=y
> +CONFIG_DISPLAY=y
> +CONFIG_LCD=y
> +CONFIG_USE_TINY_PRINTF=y
> +CONFIG_SPL_TINY_MEMSET=y
> +CONFIG_TPL_TINY_MEMSET=y
> +CONFIG_LZ4=y
> +CONFIG_LZO=y
> +CONFIG_ERRNO_STR=y
> +# CONFIG_EFI_LOADER is not set
> diff --git a/include/configs/evb_px30.h b/include/configs/evb_px30.h
> new file mode 100644
> index 0000000000..e761c7c519
> --- /dev/null
> +++ b/include/configs/evb_px30.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2017 Rockchip Electronics Co., Ltd
> + */
> +
> +#ifndef __EVB_PX30_H
> +#define __EVB_PX30_H
> +
> +#include <configs/px30_common.h>
> +
> +#define CONFIG_SYS_MMC_ENV_DEV 0
> +
> +#define ROCKCHIP_DEVICE_SETTINGS \
> +		"stdout=serial,vidconsole\0" \
> +		"stderr=serial,vidconsole\0"
> +
> +#define CONFIG_SUPPORT_EMMC_RPMB
> +
> +#endif

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

* [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core
  2019-10-25  2:49   ` Kever Yang
@ 2019-10-25  7:47     ` Heiko Stübner
  2019-11-10 14:13       ` Kever Yang
  0 siblings, 1 reply; 28+ messages in thread
From: Heiko Stübner @ 2019-10-25  7:47 UTC (permalink / raw)
  To: u-boot

Hi Kever,

Am Freitag, 25. Oktober 2019, 04:49:54 CEST schrieb Kever Yang:
> On 2019/10/25 上午7:28, Heiko Stuebner wrote:
> > From: Kever Yang <kever.yang@rock-chips.com>
> >
> > Add core architecture code to support the px30 soc.
> > This includes a separate tpl board file due to very limited
> > sram size as well as a non-dm sdram driver, as this also has
> > to fit into the tiny sram.
> 
> 
> Could you leave the sram code and make it possible to use the common 
> sdram code
> 
> I have send out:
> 
> https://patchwork.ozlabs.org/cover/1183700/
> 
> The sram driver should goes to driver/ram folder instead of arch/arm folder.

That won't work. For the px30, the ddr-init portion will need to stay in
arch-rockchip/px30 I'm afraid.

To compile things in drivers/ram you need to have TPL_RAM enabled
which in turn depends on TPL_DM which in turn makes the tpl size
to big.

So drivers/ram/... can probably only contain the dm-based part I introduce
in patch9 of this series.


Heiko

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

* [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core
  2019-10-25  7:47     ` Heiko Stübner
@ 2019-11-10 14:13       ` Kever Yang
  2019-11-10 14:46         ` Heiko Stuebner
  0 siblings, 1 reply; 28+ messages in thread
From: Kever Yang @ 2019-11-10 14:13 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 下午3:47, Heiko Stübner wrote:
> Hi Kever,
>
> Am Freitag, 25. Oktober 2019, 04:49:54 CEST schrieb Kever Yang:
>> On 2019/10/25 上午7:28, Heiko Stuebner wrote:
>>> From: Kever Yang <kever.yang@rock-chips.com>
>>>
>>> Add core architecture code to support the px30 soc.
>>> This includes a separate tpl board file due to very limited
>>> sram size as well as a non-dm sdram driver, as this also has
>>> to fit into the tiny sram.
>>
>> Could you leave the sram code and make it possible to use the common
>> sdram code
>>
>> I have send out:
>>
>> https://patchwork.ozlabs.org/cover/1183700/
>>
>> The sram driver should goes to driver/ram folder instead of arch/arm folder.
> That won't work. For the px30, the ddr-init portion will need to stay in
> arch-rockchip/px30 I'm afraid.
>
> To compile things in drivers/ram you need to have TPL_RAM enabled
> which in turn depends on TPL_DM which in turn makes the tpl size
> to big.


Can we just update the TPL_RAM not depends on DM, and leave the code in 
the driver/ram folder,

and let the code itself to decide if use DM or not? We do use 
CONFIG_TPL_BUILD and CONFIG_SPL_BUILD

for dram driver code to make choice.

The core implement of PX30 DRAM driver is shared with other SoCs, it 
should be at the same place with

other SoCs.

Thanks,

  - Kever

>
> So drivers/ram/... can probably only contain the dm-based part I introduce
> in patch9 of this series.
>
>
> Heiko
>
>
>

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

* [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core
  2019-11-10 14:13       ` Kever Yang
@ 2019-11-10 14:46         ` Heiko Stuebner
  0 siblings, 0 replies; 28+ messages in thread
From: Heiko Stuebner @ 2019-11-10 14:46 UTC (permalink / raw)
  To: u-boot

Hi Kever,

Am Sonntag, 10. November 2019, 15:13:52 CET schrieb Kever Yang:
> On 2019/10/25 下午3:47, Heiko Stübner wrote:
> > Am Freitag, 25. Oktober 2019, 04:49:54 CEST schrieb Kever Yang:
> >> On 2019/10/25 上午7:28, Heiko Stuebner wrote:
> >>> From: Kever Yang <kever.yang@rock-chips.com>
> >>>
> >>> Add core architecture code to support the px30 soc.
> >>> This includes a separate tpl board file due to very limited
> >>> sram size as well as a non-dm sdram driver, as this also has
> >>> to fit into the tiny sram.
> >>
> >> Could you leave the sram code and make it possible to use the common
> >> sdram code
> >>
> >> I have send out:
> >>
> >> https://patchwork.ozlabs.org/cover/1183700/
> >>
> >> The sram driver should goes to driver/ram folder instead of arch/arm folder.
> > That won't work. For the px30, the ddr-init portion will need to stay in
> > arch-rockchip/px30 I'm afraid.
> >
> > To compile things in drivers/ram you need to have TPL_RAM enabled
> > which in turn depends on TPL_DM which in turn makes the tpl size
> > to big.
> 
> 
> Can we just update the TPL_RAM not depends on DM, and leave the code in 
> the driver/ram folder,
> 
> and let the code itself to decide if use DM or not? We do use 
> CONFIG_TPL_BUILD and CONFIG_SPL_BUILD
> 
> for dram driver code to make choice.
> 
> The core implement of PX30 DRAM driver is shared with other SoCs, it 
> should be at the same place with
> other SoCs.

CONFIG_RAM (the core symbol) already depends on CONFIG_DM, so changing
this will cause a lot of churn for us but also other drivers living there.
And thus probably a long and detailed discussion.

And while this will be worthwhile in the long run (also for the rk3036
and future socs), can we maybe do that in 2 steps?

Aka doing your ddr-series and px30-support and then in a second step adapt
drivers/ram as needed and move rk3036 + px30 over there?
That way we don't get stalled until everybody is happy with a solution.


Thanks
Heiko

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

* [U-Boot] [PATCH 00/12] rockchip: add support for px30
  2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
                   ` (12 preceding siblings ...)
  2019-10-25  1:44 ` [U-Boot] [PATCH 00/12] rockchip: add support for px30 Kever Yang
@ 2019-11-18  2:57 ` Kever Yang
  13 siblings, 0 replies; 28+ messages in thread
From: Kever Yang @ 2019-11-18  2:57 UTC (permalink / raw)
  To: u-boot


On 2019/10/25 上午7:27, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@theobroma-systems.com>
>
> This series adds support for the px30 soc and its evaluation board.
> The most interesting aspect is the sram size which is only 10kb,
> so the TPL doing the DDR init needs to be really tiny, while the
> SPL then should use devicemanager and all other newer features.
>
> I'm not yet sure if there is a better solution for the first patch
> but right now without it there is no way to build SPL with Framework
> and TPL without.
>
> David Wu (1):
>    pinctrl: rockchip: add px30 pinctrl driver
>
> Finley Xiao (1):
>    misc: add driver for the Rockchip otp controller
>
> Heiko Stuebner (8):
>    spl: separate SPL_FRAMEWORK config for spl and tpl
>    rockchip: add core px30 headers
>    net: gmac_rockchip: add support for px30
>    rockchip: misc: read cpuid either from efuse or otp
>    rockchip: ram: add dm-based sdram driver
>    rockchip: add px30 devicetrees
>    rockchip: add px30-evb board
>
> Kever Yang (2):
>    rockchip: clk: add px30 clock driver
>    rockchip: mkimage: add support for px30
>    rockchip: add px30 architecture core
Applied to u-boot-rockchip master with rebase on  TOF and some 
checkpatch warning fix.

Thanks,
- Kever
>
>   arch/arm/dts/Makefile                         |    3 +
>   arch/arm/dts/px30-evb-u-boot.dtsi             |   81 +
>   arch/arm/dts/px30-evb.dts                     |  527 +++++
>   arch/arm/dts/px30.dtsi                        | 2068 +++++++++++++++++
>   arch/arm/include/asm/arch-px30/boot0.h        |   11 +
>   arch/arm/include/asm/arch-px30/gpio.h         |   11 +
>   arch/arm/include/asm/arch-rockchip/cru_px30.h |  432 ++++
>   arch/arm/include/asm/arch-rockchip/grf_px30.h |  144 ++
>   .../include/asm/arch-rockchip/sdram_px30.h    |  359 +++
>   arch/arm/lib/Makefile                         |    2 +-
>   arch/arm/lib/crt0.S                           |    2 +-
>   arch/arm/lib/crt0_64.S                        |    2 +
>   arch/arm/mach-rockchip/Kconfig                |   23 +
>   arch/arm/mach-rockchip/Makefile               |    2 +
>   arch/arm/mach-rockchip/misc.c                 |    7 +-
>   arch/arm/mach-rockchip/px30-board-tpl.c       |   59 +
>   arch/arm/mach-rockchip/px30/Kconfig           |   48 +
>   arch/arm/mach-rockchip/px30/Makefile          |   14 +
>   arch/arm/mach-rockchip/px30/clk_px30.c        |   31 +
>   arch/arm/mach-rockchip/px30/px30.c            |  248 ++
>   .../px30/sdram-px30-ddr3-detect-333.inc       |   70 +
>   .../px30/sdram-px30-ddr4-detect-333.inc       |   73 +
>   .../px30/sdram-px30-ddr_skew.inc              |  121 +
>   .../px30/sdram-px30-lpddr2-detect-333.inc     |   71 +
>   .../px30/sdram-px30-lpddr3-detect-333.inc     |   72 +
>   arch/arm/mach-rockchip/px30/sdram_px30.c      | 1405 +++++++++++
>   arch/arm/mach-rockchip/px30/syscon_px30.c     |   53 +
>   arch/powerpc/lib/Makefile                     |    2 +-
>   board/rockchip/evb_px30/Kconfig               |   15 +
>   board/rockchip/evb_px30/MAINTAINERS           |    6 +
>   board/rockchip/evb_px30/Makefile              |    7 +
>   board/rockchip/evb_px30/evb_px30.c            |    4 +
>   common/spl/Kconfig                            |    8 +
>   common/spl/Makefile                           |    2 +-
>   configs/evb-px30_defconfig                    |  113 +
>   drivers/clk/rockchip/Makefile                 |    1 +
>   drivers/clk/rockchip/clk_px30.c               | 1630 +++++++++++++
>   drivers/misc/Kconfig                          |    9 +
>   drivers/misc/Makefile                         |    1 +
>   drivers/misc/rockchip-otp.c                   |  176 ++
>   drivers/net/gmac_rockchip.c                   |   69 +
>   drivers/pinctrl/rockchip/Makefile             |    1 +
>   drivers/pinctrl/rockchip/pinctrl-px30.c       |  368 +++
>   drivers/ram/rockchip/Makefile                 |    1 +
>   drivers/ram/rockchip/sdram_px30.c             |   57 +
>   include/configs/evb_px30.h                    |   19 +
>   include/configs/px30_common.h                 |   62 +
>   include/dt-bindings/clock/px30-cru.h          |  389 ++++
>   include/dt-bindings/power/px30-power.h        |   27 +
>   include/dt-bindings/soc/rockchip,boot-mode.h  |   16 +
>   scripts/Makefile.spl                          |    4 +
>   tools/rkcommon.c                              |    1 +
>   52 files changed, 8922 insertions(+), 5 deletions(-)
>   create mode 100644 arch/arm/dts/px30-evb-u-boot.dtsi
>   create mode 100644 arch/arm/dts/px30-evb.dts
>   create mode 100644 arch/arm/dts/px30.dtsi
>   create mode 100644 arch/arm/include/asm/arch-px30/boot0.h
>   create mode 100644 arch/arm/include/asm/arch-px30/gpio.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/cru_px30.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/grf_px30.h
>   create mode 100644 arch/arm/include/asm/arch-rockchip/sdram_px30.h
>   create mode 100644 arch/arm/mach-rockchip/px30-board-tpl.c
>   create mode 100644 arch/arm/mach-rockchip/px30/Kconfig
>   create mode 100644 arch/arm/mach-rockchip/px30/Makefile
>   create mode 100644 arch/arm/mach-rockchip/px30/clk_px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr3-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr4-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-ddr_skew.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr2-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram-px30-lpddr3-detect-333.inc
>   create mode 100644 arch/arm/mach-rockchip/px30/sdram_px30.c
>   create mode 100644 arch/arm/mach-rockchip/px30/syscon_px30.c
>   create mode 100644 board/rockchip/evb_px30/Kconfig
>   create mode 100644 board/rockchip/evb_px30/MAINTAINERS
>   create mode 100644 board/rockchip/evb_px30/Makefile
>   create mode 100644 board/rockchip/evb_px30/evb_px30.c
>   create mode 100644 configs/evb-px30_defconfig
>   create mode 100644 drivers/clk/rockchip/clk_px30.c
>   create mode 100644 drivers/misc/rockchip-otp.c
>   create mode 100644 drivers/pinctrl/rockchip/pinctrl-px30.c
>   create mode 100644 drivers/ram/rockchip/sdram_px30.c
>   create mode 100644 include/configs/evb_px30.h
>   create mode 100644 include/configs/px30_common.h
>   create mode 100644 include/dt-bindings/clock/px30-cru.h
>   create mode 100644 include/dt-bindings/power/px30-power.h
>   create mode 100644 include/dt-bindings/soc/rockchip,boot-mode.h
>

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

end of thread, other threads:[~2019-11-18  2:57 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-24 23:27 [U-Boot] [PATCH 00/12] rockchip: add support for px30 Heiko Stuebner
2019-10-24 23:27 ` [U-Boot] [PATCH 01/12] spl: separate SPL_FRAMEWORK config for spl and tpl Heiko Stuebner
2019-10-25  1:55   ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 02/12] rockchip: add core px30 headers Heiko Stuebner
2019-10-25  2:04   ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 03/12] pinctrl: rockchip: add px30 pinctrl driver Heiko Stuebner
2019-10-25  2:07   ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 04/12] rockchip: clk: add px30 clock driver Heiko Stuebner
2019-10-24 23:27 ` [U-Boot] [PATCH 05/12] net: gmac_rockchip: add support for px30 Heiko Stuebner
2019-10-25  2:09   ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 06/12] rockchip: mkimage: " Heiko Stuebner
2019-10-25  2:09   ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 07/12] misc: add driver for the Rockchip otp controller Heiko Stuebner
2019-10-25  2:10   ` Kever Yang
2019-10-24 23:27 ` [U-Boot] [PATCH 08/12] rockchip: misc: read cpuid either from efuse or otp Heiko Stuebner
2019-10-25  2:11   ` Kever Yang
2019-10-24 23:28 ` [U-Boot] [PATCH 09/12] rockchip: ram: add dm-based sdram driver Heiko Stuebner
2019-10-24 23:28 ` [U-Boot] [PATCH 10/12] rockchip: add px30 devicetrees Heiko Stuebner
2019-10-25  2:39   ` Kever Yang
2019-10-24 23:28 ` [U-Boot] [PATCH 11/12] rockchip: add px30 architecture core Heiko Stuebner
2019-10-25  2:49   ` Kever Yang
2019-10-25  7:47     ` Heiko Stübner
2019-11-10 14:13       ` Kever Yang
2019-11-10 14:46         ` Heiko Stuebner
2019-10-24 23:28 ` [U-Boot] [PATCH 12/12] rockchip: add px30-evb board Heiko Stuebner
2019-10-25  2:51   ` Kever Yang
2019-10-25  1:44 ` [U-Boot] [PATCH 00/12] rockchip: add support for px30 Kever Yang
2019-11-18  2:57 ` Kever Yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.