aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/arch/arm/mach-rockchip
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/arch/arm/mach-rockchip')
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/Kconfig390
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/Makefile52
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/board.c190
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/boot_mode.c109
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/bootrom.c110
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/cpu-info.c65
-rwxr-xr-xroms/u-boot/arch/arm/mach-rockchip/make_fit_atf.py240
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/misc.c131
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/px30-board-tpl.c60
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/px30/Kconfig67
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/px30/Makefile13
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/px30/clk_px30.c32
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/px30/px30.c326
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/px30/syscon_px30.c54
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036-board-spl.c58
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036/Kconfig31
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036/Makefile14
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036/clk_rk3036.c33
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036/rk3036.c58
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c767
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c20
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3128/Kconfig27
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3128/Makefile9
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3128/clk_rk3128.c32
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3128/rk3128.c16
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3128/syscon_rk3128.c20
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3188/Kconfig38
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3188/Makefile11
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3188/clk_rk3188.c33
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3188/rk3188.c144
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c55
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk322x/Kconfig37
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk322x/Makefile9
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk322x/clk_rk322x.c32
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk322x/rk322x.c74
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c21
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3288/Kconfig199
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3288/Makefile9
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3288/clk_rk3288.c33
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3288/rk3288.c198
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c63
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3308/Kconfig27
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3308/Makefile9
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3308/clk_rk3308.c32
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3308/rk3308.c216
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c20
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3328/Kconfig44
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3328/Makefile9
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3328/clk_rk3328.c31
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3328/rk3328.c102
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c20
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3368/Kconfig80
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3368/Makefile6
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3368/clk_rk3368.c33
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3368/rk3368.c241
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c68
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3399/Kconfig162
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3399/Makefile9
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3399/clk_rk3399.c54
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3399/rk3399.c284
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c73
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rv1108/Kconfig42
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rv1108/Makefile11
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rv1108/clk_rv1108.c33
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rv1108/rv1108.c5
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c20
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/sdram.c213
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/spl-boot-order.c164
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/spl.c153
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/tpl.c95
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl-v8.lds94
-rw-r--r--roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl.lds12
72 files changed, 6242 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/mach-rockchip/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/Kconfig
new file mode 100644
index 000000000..407bf3fbe
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/Kconfig
@@ -0,0 +1,390 @@
+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
+ select SUPPORT_SPL
+ select SPL
+ imply USB_FUNCTION_ROCKUSB
+ imply CMD_ROCKUSB
+ imply ROCKCHIP_COMMON_BOARD
+ help
+ The Rockchip RK3036 is a ARM-based SoC with a dual-core Cortex-A7
+ 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_RK3128
+ bool "Support Rockchip RK3128"
+ select CPU_V7A
+ imply ROCKCHIP_COMMON_BOARD
+ help
+ The Rockchip RK3128 is a ARM-based SoC with a quad-core Cortex-A7
+ 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_RK3188
+ bool "Support Rockchip RK3188"
+ select CPU_V7A
+ select SPL_BOARD_INIT if SPL
+ select SUPPORT_SPL
+ select SPL
+ select SPL_CLK
+ select SPL_REGMAP
+ select SPL_SYSCON
+ select SPL_RAM
+ select SPL_DRIVERS_MISC_SUPPORT
+ select SPL_ROCKCHIP_EARLYRETURN_TO_BROM
+ select SPL_ROCKCHIP_BACK_TO_BROM
+ select BOARD_LATE_INIT
+ imply ROCKCHIP_COMMON_BOARD
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ help
+ The Rockchip RK3188 is a ARM-based SoC with a quad-core Cortex-A9
+ including NEON and GPU, 512KB L2 cache, Mali-400 graphics, two
+ video interfaces, several memory options and video codec support.
+ Peripherals include Fast Ethernet, USB2 host and OTG, SDIO, I2S,
+ UART, SPI, I2C and PWMs.
+
+config ROCKCHIP_RK322X
+ bool "Support Rockchip RK3228/RK3229"
+ select CPU_V7A
+ select SUPPORT_SPL
+ select SUPPORT_TPL
+ select SPL
+ select SPL_DM
+ select SPL_OF_LIBFDT
+ select TPL
+ select TPL_DM
+ select TPL_OF_LIBFDT
+ select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
+ select TPL_NEEDS_SEPARATE_STACK if TPL
+ select SPL_DRIVERS_MISC_SUPPORT
+ imply ROCKCHIP_COMMON_BOARD
+ imply SPL_SERIAL_SUPPORT
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply TPL_SERIAL_SUPPORT
+ imply TPL_ROCKCHIP_COMMON_BOARD
+ select TPL_LIBCOMMON_SUPPORT
+ select TPL_LIBGENERIC_SUPPORT
+ help
+ The Rockchip RK3229 is a ARM-based SoC with a dual-core Cortex-A7
+ 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_RK3288
+ bool "Support Rockchip RK3288"
+ select CPU_V7A
+ select OF_BOARD_SETUP
+ select SUPPORT_SPL
+ select SPL
+ select SUPPORT_TPL
+ imply PRE_CONSOLE_BUFFER
+ imply ROCKCHIP_COMMON_BOARD
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply TPL_CLK
+ imply TPL_DM
+ imply TPL_DRIVERS_MISC_SUPPORT
+ imply TPL_LIBCOMMON_SUPPORT
+ imply TPL_LIBGENERIC_SUPPORT
+ imply TPL_NEEDS_SEPARATE_TEXT_BASE
+ imply TPL_NEEDS_SEPARATE_STACK
+ imply TPL_OF_CONTROL
+ imply TPL_OF_PLATDATA
+ imply TPL_RAM
+ imply TPL_REGMAP
+ imply TPL_ROCKCHIP_COMMON_BOARD
+ imply TPL_SERIAL_SUPPORT
+ imply TPL_SYSCON
+ imply USB_FUNCTION_ROCKUSB
+ imply CMD_ROCKUSB
+ help
+ The Rockchip RK3288 is a ARM-based SoC with a quad-core Cortex-A17
+ including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+ video interfaces supporting HDMI and eDP, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
+
+config ROCKCHIP_RK3308
+ bool "Support Rockchip RK3308"
+ select ARM64
+ select DEBUG_UART_BOARD_INIT
+ select SUPPORT_SPL
+ select SUPPORT_TPL
+ select SPL
+ select SPL_ATF
+ select SPL_ATF_NO_PLATFORM_PARAM
+ select SPL_LOAD_FIT
+ imply ROCKCHIP_COMMON_BOARD
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply SPL_CLK
+ imply SPL_REGMAP
+ imply SPL_SYSCON
+ imply SPL_RAM
+ imply SPL_SERIAL_SUPPORT
+ imply TPL_SERIAL_SUPPORT
+ imply SPL_SEPARATE_BSS
+ help
+ The Rockchip RK3308 is a ARM-based Soc which embedded with quad
+ Cortex-A35 and highly integrated audio interfaces.
+
+config ROCKCHIP_RK3328
+ bool "Support Rockchip RK3328"
+ select ARM64
+ select SUPPORT_SPL
+ select SPL
+ select SUPPORT_TPL
+ select TPL
+ select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
+ select TPL_NEEDS_SEPARATE_STACK if TPL
+ imply ROCKCHIP_COMMON_BOARD
+ imply ROCKCHIP_SDRAM_COMMON
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply SPL_SERIAL_SUPPORT
+ imply TPL_SERIAL_SUPPORT
+ imply SPL_SEPARATE_BSS
+ select ENABLE_ARM_SOC_BOOT0_HOOK
+ select DEBUG_UART_BOARD_INIT
+ select SYS_NS16550
+ help
+ The Rockchip RK3328 is a ARM-based SoC with a quad-core Cortex-A53.
+ including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+ video interfaces supporting HDMI and eDP, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
+
+config ROCKCHIP_RK3368
+ bool "Support Rockchip RK3368"
+ select ARM64
+ select SUPPORT_SPL
+ select SUPPORT_TPL
+ select TPL_NEEDS_SEPARATE_TEXT_BASE if SPL
+ select TPL_NEEDS_SEPARATE_STACK if TPL
+ imply ROCKCHIP_COMMON_BOARD
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply SPL_SEPARATE_BSS
+ imply SPL_SERIAL_SUPPORT
+ imply TPL_SERIAL_SUPPORT
+ imply TPL_ROCKCHIP_COMMON_BOARD
+ help
+ The Rockchip RK3368 is a ARM-based SoC with a octa-core (organised
+ into a big and little cluster with 4 cores each) Cortex-A53 including
+ AdvSIMD, 512KB L2 cache (for the big cluster) and 256 KB L2 cache
+ (for the little cluster), PowerVR G6110 based graphics, one video
+ output processor supporting LVDS/HDMI/eDP, several DDR3 options and
+ video codec support.
+
+ On-chip peripherals include Gigabit Ethernet, USB2 host and OTG, SDIO,
+ I2S, UARTs, SPI, I2C and PWMs.
+
+config ROCKCHIP_RK3399
+ bool "Support Rockchip RK3399"
+ select ARM64
+ select SUPPORT_SPL
+ select SUPPORT_TPL
+ select SPL
+ select SPL_ATF
+ select SPL_BOARD_INIT if SPL
+ select SPL_LOAD_FIT
+ select SPL_CLK if SPL
+ select SPL_PINCTRL if SPL
+ select SPL_RAM if SPL
+ select SPL_REGMAP if SPL
+ select SPL_SYSCON if SPL
+ select TPL_NEEDS_SEPARATE_TEXT_BASE if TPL
+ select TPL_NEEDS_SEPARATE_STACK if TPL
+ select SPL_SEPARATE_BSS
+ select SPL_SERIAL_SUPPORT
+ select SPL_DRIVERS_MISC_SUPPORT
+ select CLK
+ select FIT
+ select PINCTRL
+ select RAM
+ select REGMAP
+ select SYSCON
+ select DM_PMIC
+ select DM_REGULATOR_FIXED
+ select BOARD_LATE_INIT
+ imply PRE_CONSOLE_BUFFER
+ imply ROCKCHIP_COMMON_BOARD
+ imply ROCKCHIP_SDRAM_COMMON
+ imply SPL_ATF_NO_PLATFORM_PARAM if SPL_ATF
+ imply SPL_ROCKCHIP_COMMON_BOARD
+ imply TPL_SERIAL_SUPPORT
+ imply TPL_LIBCOMMON_SUPPORT
+ imply TPL_LIBGENERIC_SUPPORT
+ imply TPL_SYS_MALLOC_SIMPLE
+ imply TPL_DRIVERS_MISC_SUPPORT
+ imply TPL_OF_CONTROL
+ imply TPL_DM
+ imply TPL_REGMAP
+ imply TPL_SYSCON
+ imply TPL_RAM
+ imply TPL_CLK
+ imply TPL_TINY_MEMSET
+ imply TPL_ROCKCHIP_COMMON_BOARD
+ imply SYS_BOOTCOUNT_SINGLEWORD if BOOTCOUNT_LIMIT
+ imply CMD_BOOTCOUNT if BOOTCOUNT_LIMIT
+ help
+ The Rockchip RK3399 is a ARM-based SoC with a dual-core Cortex-A72
+ and quad-core Cortex-A53.
+ including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two
+ video interfaces supporting HDMI and eDP, several DDR3 options
+ and video codec support. Peripherals include Gigabit Ethernet,
+ USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs.
+
+config ROCKCHIP_RV1108
+ bool "Support Rockchip RV1108"
+ select CPU_V7A
+ imply ROCKCHIP_COMMON_BOARD
+ help
+ The Rockchip RV1108 is a ARM-based SoC with a single-core Cortex-A7
+ and a DSP.
+
+config ROCKCHIP_USB_UART
+ bool "Route uart output to usb pins"
+ help
+ Rockchip SoCs have the ability to route the signals of the debug
+ uart through the d+ and d- pins of a specific usb phy to enable
+ some form of closed-case debugging. With this option supported
+ SoCs will enable this routing as a debug measure.
+
+config SPL_ROCKCHIP_BACK_TO_BROM
+ bool "SPL returns to bootrom"
+ default y if ROCKCHIP_RK3036
+ select ROCKCHIP_BROM_HELPER
+ select SPL_BOOTROM_SUPPORT
+ depends on SPL
+ help
+ Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
+ SPL will return to the boot rom, which will then load the U-Boot
+ binary to keep going on.
+
+config TPL_ROCKCHIP_BACK_TO_BROM
+ bool "TPL returns to bootrom"
+ default y
+ select ROCKCHIP_BROM_HELPER
+ select TPL_BOOTROM_SUPPORT
+ depends on TPL
+ help
+ Rockchip SoCs have ability to load SPL & U-Boot binary. If enabled,
+ SPL will return to the boot rom, which will then load the U-Boot
+ binary to keep going on.
+
+config ROCKCHIP_COMMON_BOARD
+ bool "Rockchip common board file"
+ help
+ Rockchip SoCs have similar boot process, Common board file is mainly
+ in charge of common process of board_init() and board_late_init() for
+ U-Boot proper.
+
+config SPL_ROCKCHIP_COMMON_BOARD
+ bool "Rockchip SPL common board file"
+ depends on SPL
+ help
+ Rockchip SoCs have similar boot process, SPL is mainly in charge of
+ load and boot Trust ATF/U-Boot firmware, and DRAM init if there is
+ no TPL for the board.
+
+config TPL_ROCKCHIP_COMMON_BOARD
+ bool "Rockchip TPL common board file"
+ depends on TPL
+ help
+ Rockchip SoCs have similar boot process, prefer to use TPL for DRAM
+ init and back to bootrom, and SPL as Trust ATF/U-Boot loader. TPL
+ common board is a basic TPL board init which can be shared for most
+ of SoCs to avoid copy-paste for different SoCs.
+
+config ROCKCHIP_BOOT_MODE_REG
+ hex "Rockchip boot mode flag register address"
+ help
+ The Soc will enter to different boot mode(defined in asm/arch-rockchip/boot_mode.h)
+ according to the value from this register.
+
+config ROCKCHIP_SPL_RESERVE_IRAM
+ hex "Size of IRAM reserved in SPL"
+ default 0
+ help
+ SPL may need reserve memory for firmware loaded by SPL, whose load
+ address is in IRAM and may overlay with SPL text area if not
+ reserved.
+
+config ROCKCHIP_BROM_HELPER
+ bool
+
+config SPL_ROCKCHIP_EARLYRETURN_TO_BROM
+ bool "SPL requires early-return (for RK3188-style BROM) to BROM"
+ depends on SPL && ENABLE_ARM_SOC_BOOT0_HOOK
+ help
+ Some Rockchip BROM variants (e.g. on the RK3188) load the
+ first stage in segments and enter multiple times. E.g. on
+ the RK3188, the first 1KB of the first stage are loaded
+ first and entered; after returning to the BROM, the
+ remainder of the first stage is loaded, but the BROM
+ re-enters at the same address/to the same code as previously.
+
+ This enables support code in the BOOT0 hook for the SPL stage
+ to allow multiple entries.
+
+config TPL_ROCKCHIP_EARLYRETURN_TO_BROM
+ bool "TPL requires early-return (for RK3188-style BROM) to BROM"
+ depends on TPL && ENABLE_ARM_SOC_BOOT0_HOOK
+ help
+ Some Rockchip BROM variants (e.g. on the RK3188) load the
+ first stage in segments and enter multiple times. E.g. on
+ the RK3188, the first 1KB of the first stage are loaded
+ first and entered; after returning to the BROM, the
+ remainder of the first stage is loaded, but the BROM
+ re-enters at the same address/to the same code as previously.
+
+ This enables support code in the BOOT0 hook for the TPL stage
+ to allow multiple entries.
+
+config SPL_MMC_SUPPORT
+ default y if !SPL_ROCKCHIP_BACK_TO_BROM
+
+config ROCKCHIP_SPI_IMAGE
+ bool "Build a SPI image for rockchip"
+ depends on HAS_ROM
+ help
+ Some Rockchip SoCs support booting from SPI flash. Enable this
+ option to produce a 4MB SPI-flash image (called u-boot.rom)
+ containing U-Boot. The image is built by binman. U-Boot sits near
+ the start of the image.
+
+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"
+source "arch/arm/mach-rockchip/rk322x/Kconfig"
+source "arch/arm/mach-rockchip/rk3288/Kconfig"
+source "arch/arm/mach-rockchip/rk3308/Kconfig"
+source "arch/arm/mach-rockchip/rk3328/Kconfig"
+source "arch/arm/mach-rockchip/rk3368/Kconfig"
+source "arch/arm/mach-rockchip/rk3399/Kconfig"
+source "arch/arm/mach-rockchip/rv1108/Kconfig"
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/Makefile b/roms/u-boot/arch/arm/mach-rockchip/Makefile
new file mode 100644
index 000000000..121f23a56
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/Makefile
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2014 Google, Inc
+# Copyright (c) 2019 Rockchip Electronics Co., Ltd.
+
+# We don't want the bootrom-helper present in a full U-Boot build, as
+# this may have entered from ATF with the stack-pointer pointing to
+# inaccessible/protected memory (and the bootrom-helper assumes that
+# the stack-pointer is valid before switching to the U-Boot stack).
+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
+
+ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
+
+# Always include boot_mode.o, as we bypass it (i.e. turn it off)
+# inside of boot_mode.c when CONFIG_BOOT_MODE_REG is 0. This way,
+# we can have the preprocessor correctly recognise both 0x0 and 0
+# meaning "turn it off".
+obj-y += boot_mode.o
+obj-$(CONFIG_ROCKCHIP_COMMON_BOARD) += board.o
+obj-$(CONFIG_MISC_INIT_R) += misc.o
+endif
+
+ifeq ($(CONFIG_TPL_BUILD),)
+obj-$(CONFIG_DISPLAY_CPUINFO) += cpu-info.o
+endif
+
+obj-$(CONFIG_$(SPL_TPL_)RAM) += sdram.o
+
+obj-$(CONFIG_ROCKCHIP_PX30) += px30/
+obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036/
+obj-$(CONFIG_ROCKCHIP_RK3128) += rk3128/
+obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188/
+obj-$(CONFIG_ROCKCHIP_RK322X) += rk322x/
+obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288/
+obj-$(CONFIG_ROCKCHIP_RK3308) += rk3308/
+obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328/
+obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/
+obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/
+obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/
+
+# Clear out SPL objects, in case this is a TPL build
+obj-spl-$(CONFIG_TPL_BUILD) =
+
+# Now add SPL/TPL objects back into the main build
+obj-$(CONFIG_SPL_BUILD) += $(obj-spl-y)
+obj-$(CONFIG_TPL_BUILD) += $(obj-tpl-y)
diff --git a/roms/u-boot/arch/arm/mach-rockchip/board.c b/roms/u-boot/arch/arm/mach-rockchip/board.c
new file mode 100644
index 000000000..5304eb055
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/board.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd.
+ */
+#include <common.h>
+#include <clk.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <fastboot.h>
+#include <init.h>
+#include <log.h>
+#include <ram.h>
+#include <syscon.h>
+#include <asm/cache.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/boot_mode.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/periph.h>
+#include <asm/arch-rockchip/misc.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak int rk_board_late_init(void)
+{
+ return 0;
+}
+
+int board_late_init(void)
+{
+ setup_boot_mode();
+
+ return rk_board_late_init();
+}
+
+int board_init(void)
+{
+ int ret;
+
+#ifdef CONFIG_DM_REGULATOR
+ ret = regulators_enable_boot_on(false);
+ if (ret)
+ debug("%s: Cannot enable boot on regulator\n", __func__);
+#endif
+
+ return 0;
+}
+
+#if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
+#endif
+
+#if defined(CONFIG_USB_GADGET)
+#include <usb.h>
+
+#if defined(CONFIG_USB_GADGET_DWC2_OTG)
+#include <usb/dwc2_udc.h>
+
+static struct dwc2_plat_otg_data otg_data = {
+ .rx_fifo_sz = 512,
+ .np_tx_fifo_sz = 16,
+ .tx_fifo_sz = 128,
+};
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ ofnode node;
+ const char *mode;
+ bool matched = false;
+
+ /* find the usb_otg node */
+ node = ofnode_by_compatible(ofnode_null(), "snps,dwc2");
+ while (ofnode_valid(node)) {
+ mode = ofnode_read_string(node, "dr_mode");
+ if (mode && strcmp(mode, "otg") == 0) {
+ matched = true;
+ break;
+ }
+
+ node = ofnode_by_compatible(node, "snps,dwc2");
+ }
+ if (!matched) {
+ debug("Not found usb_otg device\n");
+ return -ENODEV;
+ }
+ otg_data.regs_otg = ofnode_get_addr(node);
+
+#ifdef CONFIG_ROCKCHIP_RK3288
+ int ret;
+ u32 phandle, offset;
+ ofnode phy_node;
+
+ ret = ofnode_read_u32(node, "phys", &phandle);
+ if (ret)
+ return ret;
+
+ node = ofnode_get_by_phandle(phandle);
+ if (!ofnode_valid(node)) {
+ debug("Not found usb phy device\n");
+ return -ENODEV;
+ }
+
+ phy_node = ofnode_get_parent(node);
+ if (!ofnode_valid(node)) {
+ debug("Not found usb phy device\n");
+ return -ENODEV;
+ }
+
+ otg_data.phy_of_node = phy_node;
+ ret = ofnode_read_u32(node, "reg", &offset);
+ if (ret)
+ return ret;
+ otg_data.regs_phy = offset +
+ (u32)syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+#endif
+ return dwc2_udc_probe(&otg_data);
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ return 0;
+}
+#endif /* CONFIG_USB_GADGET_DWC2_OTG */
+
+#if defined(CONFIG_USB_DWC3_GADGET) && !defined(CONFIG_DM_USB_GADGET)
+#include <dwc3-uboot.h>
+
+static struct dwc3_device dwc3_device_data = {
+ .maximum_speed = USB_SPEED_HIGH,
+ .base = 0xfe800000,
+ .dr_mode = USB_DR_MODE_PERIPHERAL,
+ .index = 0,
+ .dis_u2_susphy_quirk = 1,
+ .hsphy_mode = USBPHY_INTERFACE_MODE_UTMIW,
+};
+
+int usb_gadget_handle_interrupts(int index)
+{
+ dwc3_uboot_handle_interrupt(0);
+ return 0;
+}
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ return dwc3_uboot_init(&dwc3_device_data);
+}
+#endif /* CONFIG_USB_DWC3_GADGET */
+
+#endif /* CONFIG_USB_GADGET */
+
+#if CONFIG_IS_ENABLED(FASTBOOT)
+int fastboot_set_reboot_flag(enum fastboot_reboot_reason reason)
+{
+ if (reason != FASTBOOT_REBOOT_REASON_BOOTLOADER)
+ return -ENOTSUPP;
+
+ printf("Setting reboot to fastboot flag ...\n");
+ /* Set boot mode to fastboot */
+ writel(BOOT_FASTBOOT, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_MISC_INIT_R
+__weak int misc_init_r(void)
+{
+ const u32 cpuid_offset = 0x7;
+ const u32 cpuid_length = 0x10;
+ u8 cpuid[cpuid_length];
+ int ret;
+
+ ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
+ if (ret)
+ return ret;
+
+ ret = rockchip_cpuid_set(cpuid, cpuid_length);
+ if (ret)
+ return ret;
+
+ ret = rockchip_setup_macaddr();
+
+ return ret;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/boot_mode.c b/roms/u-boot/arch/arm/mach-rockchip/boot_mode.c
new file mode 100644
index 000000000..215893415
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/boot_mode.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <adc.h>
+#include <command.h>
+#include <env.h>
+#include <log.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/boot_mode.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+
+#if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0)
+
+int setup_boot_mode(void)
+{
+ return 0;
+}
+
+#else
+
+void set_back_to_bootrom_dnl_flag(void)
+{
+ writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+}
+
+/*
+ * detect download key status by adc, most rockchip
+ * based boards use adc sample the download key status,
+ * but there are also some use gpio. So it's better to
+ * make this a weak function that can be override by
+ * some special boards.
+ */
+#define KEY_DOWN_MIN_VAL 0
+#define KEY_DOWN_MAX_VAL 30
+
+__weak int rockchip_dnl_key_pressed(void)
+{
+ unsigned int val;
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_ADC, &uc);
+ if (ret)
+ return false;
+
+ ret = -ENODEV;
+ uclass_foreach_dev(dev, uc) {
+ if (!strncmp(dev->name, "saradc", 6)) {
+ ret = adc_channel_single_shot(dev->name, 1, &val);
+ break;
+ }
+ }
+
+ if (ret == -ENODEV) {
+ pr_warn("%s: no saradc device found\n", __func__);
+ return false;
+ } else if (ret) {
+ pr_err("%s: adc_channel_single_shot fail!\n", __func__);
+ return false;
+ }
+
+ if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
+ return true;
+ else
+ return false;
+}
+
+void rockchip_dnl_mode_check(void)
+{
+ if (rockchip_dnl_key_pressed()) {
+ printf("download key pressed, entering download mode...");
+ set_back_to_bootrom_dnl_flag();
+ do_reset(NULL, 0, 0, NULL);
+ }
+}
+
+int setup_boot_mode(void)
+{
+ void *reg = (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG;
+ int boot_mode = readl(reg);
+
+ rockchip_dnl_mode_check();
+
+ boot_mode = readl(reg);
+ debug("%s: boot mode 0x%08x\n", __func__, boot_mode);
+
+ /* Clear boot mode */
+ writel(BOOT_NORMAL, reg);
+
+ switch (boot_mode) {
+ case BOOT_FASTBOOT:
+ debug("%s: enter fastboot!\n", __func__);
+ env_set("preboot", "setenv preboot; fastboot usb0");
+ break;
+ case BOOT_UMS:
+ debug("%s: enter UMS!\n", __func__);
+ env_set("preboot", "setenv preboot; ums mmc 0");
+ break;
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/bootrom.c b/roms/u-boot/arch/arm/mach-rockchip/bootrom.c
new file mode 100644
index 000000000..b36e559e8
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/bootrom.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0+
+/**
+ * Copyright (c) 2017 Google, Inc
+ */
+
+#include <common.h>
+#include <hang.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/boot_mode.h>
+#include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/setjmp.h>
+#include <asm/system.h>
+
+/*
+ * Force the jmp_buf to the data-section, as .bss will not be valid
+ * when save_boot_params is invoked.
+ */
+static jmp_buf brom_ctx __section(".data");
+
+static void _back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd)
+{
+ longjmp(brom_ctx, brom_cmd);
+}
+
+void back_to_bootrom(enum rockchip_bootrom_cmd brom_cmd)
+{
+#if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT)
+ puts("Returning to boot ROM...\n");
+#endif
+ _back_to_bootrom(brom_cmd);
+}
+
+/*
+ * we back to bootrom download mode if get a
+ * BOOT_BROM_DOWNLOAD flag in boot mode register
+ *
+ * note: the boot mode register is configured by
+ * application(next stage bootloader, kernel, etc),
+ * and the bootrom never check this register, so we need
+ * to check it and back to bootrom at very early bootstage(before
+ * some basic configurations(such as interrupts) been
+ * changed by TPL/SPL, as the bootrom download operation
+ * relies on many default settings(such as interrupts) by
+ * itself.
+ */
+static bool check_back_to_brom_dnl_flag(void)
+{
+ u32 boot_mode;
+
+ if (CONFIG_ROCKCHIP_BOOT_MODE_REG) {
+ boot_mode = readl(CONFIG_ROCKCHIP_BOOT_MODE_REG);
+ if (boot_mode == BOOT_BROM_DOWNLOAD) {
+ writel(0, CONFIG_ROCKCHIP_BOOT_MODE_REG);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*
+ * All Rockchip BROM implementations enter with a valid stack-pointer,
+ * so this can safely be implemented in C (providing a single
+ * implementation both for ARMv7 and AArch64).
+ */
+int save_boot_params(void)
+{
+ int ret = setjmp(brom_ctx);
+
+ switch (ret) {
+ case 0:
+ if (check_back_to_brom_dnl_flag())
+ _back_to_bootrom(BROM_BOOT_ENTER_DNL);
+ /*
+ * This is the initial pass through this function
+ * (i.e. saving the context), setjmp just setup up the
+ * brom_ctx: transfer back into the startup-code at
+ * 'save_boot_params_ret' and let the compiler know
+ * that this will not return.
+ */
+ save_boot_params_ret();
+ while (true)
+ /* does not return */;
+ break;
+
+ case BROM_BOOT_NEXTSTAGE:
+ /*
+ * To instruct the BROM to boot the next stage, we
+ * need to return 0 to it: i.e. we need to rewrite
+ * the return code once more.
+ */
+ ret = 0;
+ break;
+ case BROM_BOOT_ENTER_DNL:
+ /*
+ * A non-zero return value will instruct the BROM enter
+ * download mode.
+ */
+ ret = 1;
+ break;
+ default:
+#if CONFIG_IS_ENABLED(LIBCOMMON_SUPPORT)
+ puts("FATAL: unexpected command to back_to_bootrom()\n");
+#endif
+ hang();
+ };
+
+ return ret;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/cpu-info.c b/roms/u-boot/arch/arm/mach-rockchip/cpu-info.c
new file mode 100644
index 000000000..d0f030109
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/cpu-info.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * (C) Copyright 2019 Amarula Solutions(India)
+ * Author: Jagan Teki <jagan@amarulasolutions.com>
+ */
+
+#include <common.h>
+#include <env.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <linux/err.h>
+
+char *get_reset_cause(void)
+{
+ struct rockchip_cru *cru = rockchip_get_cru();
+ char *cause = NULL;
+
+ if (IS_ERR(cru))
+ return cause;
+
+ switch (cru->glb_rst_st) {
+ case GLB_POR_RST:
+ cause = "POR";
+ break;
+ case FST_GLB_RST_ST:
+ case SND_GLB_RST_ST:
+ cause = "RST";
+ break;
+ case FST_GLB_TSADC_RST_ST:
+ case SND_GLB_TSADC_RST_ST:
+ cause = "THERMAL";
+ break;
+ case FST_GLB_WDT_RST_ST:
+ case SND_GLB_WDT_RST_ST:
+ cause = "WDOG";
+ break;
+ default:
+ cause = "unknown reset";
+ }
+
+ return cause;
+}
+
+#if CONFIG_IS_ENABLED(DISPLAY_CPUINFO)
+int print_cpuinfo(void)
+{
+ char *cause = get_reset_cause();
+
+ printf("SoC: Rockchip %s\n", CONFIG_SYS_SOC);
+ printf("Reset cause: %s\n", cause);
+
+ /**
+ * reset_reason env is used by rk3288, due to special use case
+ * to figure it the boot behavior. so keep this as it is.
+ */
+ env_set("reset_reason", cause);
+
+ /* TODO print operating temparature and clock */
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/make_fit_atf.py b/roms/u-boot/arch/arm/mach-rockchip/make_fit_atf.py
new file mode 100755
index 000000000..f3224d255
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/make_fit_atf.py
@@ -0,0 +1,240 @@
+#!/usr/bin/env python3
+"""
+# SPDX-License-Identifier: GPL-2.0+
+#
+# A script to generate FIT image source for rockchip boards
+# with ARM Trusted Firmware
+# and multiple device trees (given on the command line)
+#
+# usage: $0 <dt_name> [<dt_name> [<dt_name] ...]
+"""
+
+import os
+import sys
+import getopt
+import logging
+import struct
+
+DT_HEADER = """
+/*
+ * This is a generated file.
+ */
+/dts-v1/;
+
+/ {
+ description = "FIT image for U-Boot with bl31 (TF-A)";
+ #address-cells = <1>;
+
+ images {
+"""
+
+DT_UBOOT = """
+ uboot {
+ description = "U-Boot (64-bit)";
+ data = /incbin/("u-boot-nodtb.bin");
+ type = "standalone";
+ os = "U-Boot";
+ arch = "arm64";
+ compression = "none";
+ load = <0x%08x>;
+ };
+
+"""
+
+DT_IMAGES_NODE_END = """ };
+
+"""
+
+DT_END = "};"
+
+def append_bl31_node(file, atf_index, phy_addr, elf_entry):
+ # Append BL31 DT node to input FIT dts file.
+ data = 'bl31_0x%08x.bin' % phy_addr
+ file.write('\t\tatf_%d {\n' % atf_index)
+ file.write('\t\t\tdescription = \"ARM Trusted Firmware\";\n')
+ file.write('\t\t\tdata = /incbin/("%s");\n' % data)
+ file.write('\t\t\ttype = "firmware";\n')
+ file.write('\t\t\tarch = "arm64";\n')
+ file.write('\t\t\tos = "arm-trusted-firmware";\n')
+ file.write('\t\t\tcompression = "none";\n')
+ file.write('\t\t\tload = <0x%08x>;\n' % phy_addr)
+ if atf_index == 1:
+ file.write('\t\t\tentry = <0x%08x>;\n' % elf_entry)
+ file.write('\t\t};\n')
+ file.write('\n')
+
+def append_tee_node(file, atf_index, phy_addr, elf_entry):
+ # Append TEE DT node to input FIT dts file.
+ data = 'tee_0x%08x.bin' % phy_addr
+ file.write('\t\tatf_%d {\n' % atf_index)
+ file.write('\t\t\tdescription = \"TEE\";\n')
+ file.write('\t\t\tdata = /incbin/("%s");\n' % data)
+ file.write('\t\t\ttype = "tee";\n')
+ file.write('\t\t\tarch = "arm64";\n')
+ file.write('\t\t\tos = "tee";\n')
+ file.write('\t\t\tcompression = "none";\n')
+ file.write('\t\t\tload = <0x%08x>;\n' % phy_addr)
+ file.write('\t\t\tentry = <0x%08x>;\n' % elf_entry)
+ file.write('\t\t};\n')
+ file.write('\n')
+
+def append_fdt_node(file, dtbs):
+ # Append FDT nodes.
+ cnt = 1
+ for dtb in dtbs:
+ dtname = os.path.basename(dtb)
+ file.write('\t\tfdt_%d {\n' % cnt)
+ file.write('\t\t\tdescription = "%s";\n' % dtname)
+ file.write('\t\t\tdata = /incbin/("%s");\n' % dtb)
+ file.write('\t\t\ttype = "flat_dt";\n')
+ file.write('\t\t\tcompression = "none";\n')
+ file.write('\t\t};\n')
+ file.write('\n')
+ cnt = cnt + 1
+
+def append_conf_section(file, cnt, dtname, segments):
+ file.write('\t\tconfig_%d {\n' % cnt)
+ file.write('\t\t\tdescription = "%s";\n' % dtname)
+ file.write('\t\t\tfirmware = "atf_1";\n')
+ file.write('\t\t\tloadables = "uboot"')
+ if segments > 1:
+ file.write(',')
+ for i in range(1, segments):
+ file.write('"atf_%d"' % (i + 1))
+ if i != (segments - 1):
+ file.write(',')
+ else:
+ file.write(';\n')
+ if segments <= 1:
+ file.write(';\n')
+ file.write('\t\t\tfdt = "fdt_%d";\n' % cnt)
+ file.write('\t\t};\n')
+ file.write('\n')
+
+def append_conf_node(file, dtbs, segments):
+ # Append configeration nodes.
+ cnt = 1
+ file.write('\tconfigurations {\n')
+ file.write('\t\tdefault = "config_1";\n')
+ for dtb in dtbs:
+ dtname = os.path.basename(dtb)
+ append_conf_section(file, cnt, dtname, segments)
+ cnt = cnt + 1
+ file.write('\t};\n')
+ file.write('\n')
+
+def generate_atf_fit_dts_uboot(fit_file, uboot_file_name):
+ segments = unpack_elf(uboot_file_name)
+ if len(segments) != 1:
+ raise ValueError("Invalid u-boot ELF image '%s'" % uboot_file_name)
+ index, entry, p_paddr, data = segments[0]
+ fit_file.write(DT_UBOOT % p_paddr)
+
+def generate_atf_fit_dts_bl31(fit_file, bl31_file_name, tee_file_name, dtbs_file_name):
+ segments = unpack_elf(bl31_file_name)
+ for index, entry, paddr, data in segments:
+ append_bl31_node(fit_file, index + 1, paddr, entry)
+ num_segments = len(segments)
+
+ if tee_file_name:
+ tee_segments = unpack_elf(tee_file_name)
+ for index, entry, paddr, data in tee_segments:
+ append_tee_node(fit_file, num_segments + index + 1, paddr, entry)
+ num_segments = num_segments + len(tee_segments)
+
+ append_fdt_node(fit_file, dtbs_file_name)
+ fit_file.write(DT_IMAGES_NODE_END)
+ append_conf_node(fit_file, dtbs_file_name, num_segments)
+
+def generate_atf_fit_dts(fit_file_name, bl31_file_name, tee_file_name, uboot_file_name, dtbs_file_name):
+ # Generate FIT script for ATF image.
+ if fit_file_name != sys.stdout:
+ fit_file = open(fit_file_name, "wb")
+ else:
+ fit_file = sys.stdout
+
+ fit_file.write(DT_HEADER)
+ generate_atf_fit_dts_uboot(fit_file, uboot_file_name)
+ generate_atf_fit_dts_bl31(fit_file, bl31_file_name, tee_file_name, dtbs_file_name)
+ fit_file.write(DT_END)
+
+ if fit_file_name != sys.stdout:
+ fit_file.close()
+
+def generate_atf_binary(bl31_file_name):
+ for index, entry, paddr, data in unpack_elf(bl31_file_name):
+ file_name = 'bl31_0x%08x.bin' % paddr
+ with open(file_name, "wb") as atf:
+ atf.write(data)
+
+def generate_tee_binary(tee_file_name):
+ if tee_file_name:
+ for index, entry, paddr, data in unpack_elf(tee_file_name):
+ file_name = 'tee_0x%08x.bin' % paddr
+ with open(file_name, "wb") as atf:
+ atf.write(data)
+
+def unpack_elf(filename):
+ with open(filename, 'rb') as file:
+ elf = file.read()
+ if elf[0:7] != b'\x7fELF\x02\x01\x01' or elf[18:20] != b'\xb7\x00':
+ raise ValueError("Invalid arm64 ELF file '%s'" % filename)
+
+ e_entry, e_phoff = struct.unpack_from('<2Q', elf, 0x18)
+ e_phentsize, e_phnum = struct.unpack_from('<2H', elf, 0x36)
+ segments = []
+
+ for index in range(e_phnum):
+ offset = e_phoff + e_phentsize * index
+ p_type, p_flags, p_offset = struct.unpack_from('<LLQ', elf, offset)
+ if p_type == 1: # PT_LOAD
+ p_paddr, p_filesz = struct.unpack_from('<2Q', elf, offset + 0x18)
+ if p_filesz > 0:
+ p_data = elf[p_offset:p_offset + p_filesz]
+ segments.append((index, e_entry, p_paddr, p_data))
+ return segments
+
+def main():
+ uboot_elf = "./u-boot"
+ fit_its = sys.stdout
+ if "BL31" in os.environ:
+ bl31_elf=os.getenv("BL31");
+ elif os.path.isfile("./bl31.elf"):
+ bl31_elf = "./bl31.elf"
+ else:
+ os.system("echo 'int main(){}' > bl31.c")
+ os.system("${CROSS_COMPILE}gcc -c bl31.c -o bl31.elf")
+ bl31_elf = "./bl31.elf"
+ logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
+ logging.warning(' BL31 file bl31.elf NOT found, resulting binary is non-functional')
+ logging.warning(' Please read Building section in doc/README.rockchip')
+
+ if "TEE" in os.environ:
+ tee_elf = os.getenv("TEE")
+ elif os.path.isfile("./tee.elf"):
+ tee_elf = "./tee.elf"
+ else:
+ tee_elf = ""
+
+ opts, args = getopt.getopt(sys.argv[1:], "o:u:b:t:h")
+ for opt, val in opts:
+ if opt == "-o":
+ fit_its = val
+ elif opt == "-u":
+ uboot_elf = val
+ elif opt == "-b":
+ bl31_elf = val
+ elif opt == "-t":
+ tee_elf = val
+ elif opt == "-h":
+ print(__doc__)
+ sys.exit(2)
+
+ dtbs = args
+
+ generate_atf_fit_dts(fit_its, bl31_elf, tee_elf, uboot_elf, dtbs)
+ generate_atf_binary(bl31_elf)
+ generate_tee_binary(tee_elf)
+
+if __name__ == "__main__":
+ main()
diff --git a/roms/u-boot/arch/arm/mach-rockchip/misc.c b/roms/u-boot/arch/arm/mach-rockchip/misc.c
new file mode 100644
index 000000000..87eebd987
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/misc.c
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * RK3399: Architecture common definitions
+ *
+ * Copyright (C) 2019 Collabora Inc - https://www.collabora.com/
+ * Rohan Garg <rohan.garg@collabora.com>
+ *
+ * Based on puma-rk3399.c:
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <env.h>
+#include <dm.h>
+#include <hash.h>
+#include <log.h>
+#include <dm/uclass-internal.h>
+#include <misc.h>
+#include <u-boot/crc.h>
+#include <u-boot/sha256.h>
+
+#include <asm/arch-rockchip/misc.h>
+
+int rockchip_setup_macaddr(void)
+{
+#if CONFIG_IS_ENABLED(CMD_NET)
+ int ret;
+ const char *cpuid = env_get("cpuid#");
+ u8 hash[SHA256_SUM_LEN];
+ int size = sizeof(hash);
+ u8 mac_addr[6];
+
+ /* Only generate a MAC address, if none is set in the environment */
+ if (env_get("ethaddr"))
+ return 0;
+
+ if (!cpuid) {
+ debug("%s: could not retrieve 'cpuid#'\n", __func__);
+ return -1;
+ }
+
+ ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size);
+ if (ret) {
+ debug("%s: failed to calculate SHA256\n", __func__);
+ return -1;
+ }
+
+ /* Copy 6 bytes of the hash to base the MAC address on */
+ memcpy(mac_addr, hash, 6);
+
+ /* Make this a valid MAC address and set it */
+ mac_addr[0] &= 0xfe; /* clear multicast bit */
+ mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */
+ eth_env_set_enetaddr("ethaddr", mac_addr);
+#endif
+ return 0;
+}
+
+int rockchip_cpuid_from_efuse(const u32 cpuid_offset,
+ const u32 cpuid_length,
+ u8 *cpuid)
+{
+#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_DRIVER_GET(rockchip_efuse), &dev);
+#elif CONFIG_IS_ENABLED(ROCKCHIP_OTP)
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_DRIVER_GET(rockchip_otp), &dev);
+#endif
+ if (ret) {
+ debug("%s: could not find efuse device\n", __func__);
+ return -1;
+ }
+
+ /* read the cpu_id range from the efuses */
+ ret = misc_read(dev, cpuid_offset, cpuid, cpuid_length);
+ if (ret) {
+ debug("%s: reading cpuid from the efuses failed\n",
+ __func__);
+ return -1;
+ }
+#endif
+ return 0;
+}
+
+int rockchip_cpuid_set(const u8 *cpuid, const u32 cpuid_length)
+{
+ u8 low[cpuid_length / 2], high[cpuid_length / 2];
+ char cpuid_str[cpuid_length * 2 + 1];
+ u64 serialno;
+ char serialno_str[17];
+ const char *oldid;
+ int i;
+
+ memset(cpuid_str, 0, sizeof(cpuid_str));
+ for (i = 0; i < 16; i++)
+ sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]);
+
+ debug("cpuid: %s\n", cpuid_str);
+
+ /*
+ * Mix the cpuid bytes using the same rules as in
+ * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c
+ */
+ for (i = 0; i < 8; i++) {
+ low[i] = cpuid[1 + (i << 1)];
+ high[i] = cpuid[i << 1];
+ }
+
+ serialno = crc32_no_comp(0, low, 8);
+ serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32;
+ snprintf(serialno_str, sizeof(serialno_str), "%016llx", serialno);
+
+ oldid = env_get("cpuid#");
+ if (oldid && strcmp(oldid, cpuid_str) != 0)
+ printf("cpuid: value %s present in env does not match hardware %s\n",
+ oldid, cpuid_str);
+
+ env_set("cpuid#", cpuid_str);
+
+ /* Only generate serial# when none is set yet */
+ if (!env_get("serial#"))
+ env_set("serial#", serialno_str);
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/px30-board-tpl.c b/roms/u-boot/arch/arm/mach-rockchip/px30-board-tpl.c
new file mode 100644
index 000000000..085e65062
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/px30-board-tpl.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <init.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/roms/u-boot/arch/arm/mach-rockchip/px30/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/px30/Kconfig
new file mode 100644
index 000000000..16090f5b0
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/px30/Kconfig
@@ -0,0 +1,67 @@
+if ROCKCHIP_PX30
+
+config TARGET_EVB_PX30
+ bool "EVB_PX30"
+ help
+ This target config option used for below listed px30 boards.
+
+ EVB_PX30:
+ * EVB_PX30 is an evaluation board for Rockchip PX30.
+
+config TARGET_ODROID_GO2
+ bool "ODROID_GO2"
+
+config TARGET_PX30_CORE
+ bool "Engicam PX30.Core"
+ help
+ PX30.Core EDIMM2.2:
+ * PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam.
+ * EDIMM2.2 is a Form Factor Capacitive Evaluation Board from Engicam.
+ * PX30.Core needs to mount on top of EDIMM2.2 for creating complete
+ PX30.Core EDIMM2.2 Starter Kit.
+
+ PX30.Core CTOUCH2:
+ * PX30.Core is an EDIMM SOM based on Rockchip PX30 from Engicam.
+ * CTOUCH2.0 is a general purpose Carrier board with capacitive
+ touch interface support.
+ * PX30.Core needs to mount on top of CTOUCH2.0 for creating complete
+ PX30.Core C.TOUCH Carrier board.
+
+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 DEBUG_UART_CHANNEL
+ int "Mux channel to use for debug UART2/UART3"
+ depends on DEBUG_UART_BOARD_INIT
+ default 0
+ help
+ UART2 and UART3 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/engicam/px30_core/Kconfig"
+source "board/hardkernel/odroid_go2/Kconfig"
+source "board/rockchip/evb_px30/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/px30/Makefile b/roms/u-boot/arch/arm/mach-rockchip/px30/Makefile
new file mode 100644
index 000000000..080ce146f
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/px30/Makefile
@@ -0,0 +1,13 @@
+#
+# (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
diff --git a/roms/u-boot/arch/arm/mach-rockchip/px30/clk_px30.c b/roms/u-boot/arch/arm/mach-rockchip/px30/clk_px30.c
new file mode 100644
index 000000000..7edf1321f
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/px30/clk_px30.c
@@ -0,0 +1,32 @@
+// 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>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(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/roms/u-boot/arch/arm/mach-rockchip/px30/px30.c b/roms/u-boot/arch/arm/mach-rockchip/px30/px30.c
new file mode 100644
index 000000000..6fcef63c1
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/px30/px30.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <init.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 PMUGRF_BASE 0xff010000
+#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_GPIO1BH_IOMUX */
+enum {
+ GPIO1B7_SHIFT = 12,
+ GPIO1B7_MASK = 0xf << GPIO1B7_SHIFT,
+ GPIO1B7_GPIO = 0,
+ GPIO1B7_FLASH_RDN,
+ GPIO1B7_UART3_RXM1,
+ GPIO1B7_SPI0_CLK,
+
+ GPIO1B6_SHIFT = 8,
+ GPIO1B6_MASK = 0xf << GPIO1B6_SHIFT,
+ GPIO1B6_GPIO = 0,
+ GPIO1B6_FLASH_CS1,
+ GPIO1B6_UART3_TXM1,
+ GPIO1B6_SPI0_CSN,
+};
+
+/* 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,
+};
+
+/* PMUGRF_GPIO0CL_IOMUX */
+enum {
+ GPIO0C1_SHIFT = 2,
+ GPIO0C1_MASK = 0x3 << GPIO0C1_SHIFT,
+ GPIO0C1_GPIO = 0,
+ GPIO0C1_PWM_3,
+ GPIO0C1_UART3_RXM0,
+ GPIO0C1_PMU_DEBUG4,
+
+ GPIO0C0_SHIFT = 0,
+ GPIO0C0_MASK = 0x3 << GPIO0C0_SHIFT,
+ GPIO0C0_GPIO = 0,
+ GPIO0C0_PWM_1,
+ GPIO0C0_UART3_TXM0,
+ GPIO0C0_PMU_DEBUG3,
+};
+
+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)
+{
+#if defined(CONFIG_DEBUG_UART_BASE) && \
+ (CONFIG_DEBUG_UART_BASE == 0xff168000) && \
+ (CONFIG_DEBUG_UART_CHANNEL != 1)
+ static struct px30_pmugrf * const pmugrf = (void *)PMUGRF_BASE;
+#endif
+ 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 == 0xff168000)
+ /* GRF_IOFUNC_CON0 */
+ enum {
+ CON_IOMUX_UART3SEL_SHIFT = 9,
+ CON_IOMUX_UART3SEL_MASK = 1 << CON_IOMUX_UART3SEL_SHIFT,
+ CON_IOMUX_UART3SEL_M0 = 0,
+ CON_IOMUX_UART3SEL_M1,
+ };
+
+ /* uart_sel_clk default select 24MHz */
+ rk_clrsetreg(&cru->clksel_con[40],
+ UART3_PLL_SEL_MASK | UART3_DIV_CON_MASK,
+ UART3_PLL_SEL_24M << UART3_PLL_SEL_SHIFT | 0);
+ rk_clrsetreg(&cru->clksel_con[41],
+ UART3_CLK_SEL_MASK,
+ UART3_CLK_SEL_UART3 << UART3_CLK_SEL_SHIFT);
+
+#if (CONFIG_DEBUG_UART_CHANNEL == 1)
+ rk_clrsetreg(&grf->iofunc_con0,
+ CON_IOMUX_UART3SEL_MASK,
+ CON_IOMUX_UART3SEL_M1 << CON_IOMUX_UART3SEL_SHIFT);
+
+ rk_clrsetreg(&grf->gpio1bh_iomux,
+ GPIO1B7_MASK | GPIO1B6_MASK,
+ GPIO1B7_UART3_RXM1 << GPIO1B7_SHIFT |
+ GPIO1B6_UART3_TXM1 << GPIO1B6_SHIFT);
+#else
+ rk_clrsetreg(&grf->iofunc_con0,
+ CON_IOMUX_UART3SEL_MASK,
+ CON_IOMUX_UART3SEL_M0 << CON_IOMUX_UART3SEL_SHIFT);
+
+ rk_clrsetreg(&pmugrf->gpio0cl_iomux,
+ GPIO0C1_MASK | GPIO0C0_MASK,
+ GPIO0C1_UART3_RXM0 << GPIO0C1_SHIFT |
+ GPIO0C0_UART3_TXM0 << GPIO0C0_SHIFT);
+#endif /* CONFIG_DEBUG_UART_CHANNEL == 1 */
+
+#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_UART_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_UART_CHANNEL == 1 */
+
+#endif /* CONFIG_DEBUG_UART_BASE && CONFIG_DEBUG_UART_BASE == ... */
+}
+#endif /* CONFIG_DEBUG_UART_BOARD_INIT */
diff --git a/roms/u-boot/arch/arm/mach-rockchip/px30/syscon_px30.c b/roms/u-boot/arch/arm/mach-rockchip/px30/syscon_px30.c
new file mode 100644
index 000000000..37e88f5cc
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/px30/syscon_px30.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.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_plat(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_px30_pmu) = {
+ .name = "rockchip_px30_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = px30_syscon_ids,
+ .bind = px30_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_px30_pmugrf) = {
+ .name = "rockchip_px30_pmugrf",
+ .id = UCLASS_SYSCON,
+ .of_match = px30_syscon_ids + 1,
+ .bind = px30_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_px30_grf) = {
+ .name = "rockchip_px30_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = px30_syscon_ids + 2,
+ .bind = px30_syscon_bind_of_plat,
+};
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3036-board-spl.c b/roms/u-boot/arch/arm/mach-rockchip/rk3036-board-spl.c
new file mode 100644
index 000000000..6eb89e15b
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036-board-spl.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2015-2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/sdram_rk3036.h>
+
+#define TIMER_LOAD_COUNT_L 0x00
+#define TIMER_LOAD_COUNT_H 0x04
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_EN 0x1
+#define TIMER_FMODE (0 << 1)
+#define TIMER_RMODE (1 << 1)
+
+void rockchip_stimer_init(void)
+{
+ asm volatile("mcr p15, 0, %0, c14, c0, 0"
+ : : "r"(COUNTER_FREQUENCY));
+
+ writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+ writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+ TIMER_CONTROL_REG);
+}
+
+void board_init_f(ulong dummy)
+{
+#ifdef CONFIG_DEBUG_UART
+ debug_uart_init();
+#endif
+
+ /* Init secure timer */
+ rockchip_stimer_init();
+ /* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+ timer_init();
+
+ sdram_init();
+
+ /* return to maskrom */
+ back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+}
+
+/* Place Holders */
+void board_init_r(gd_t *id, ulong dest_addr)
+{
+ /*
+ * Function attribute is no-return
+ * This Function never executes
+ */
+ while (1)
+ ;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3036/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3036/Kconfig
new file mode 100644
index 000000000..51cd43b39
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036/Kconfig
@@ -0,0 +1,31 @@
+if ROCKCHIP_RK3036
+
+choice
+ prompt "RK3036 board select"
+
+config TARGET_EVB_RK3036
+ bool "EVB_RK3036"
+ select BOARD_LATE_INIT
+
+config TARGET_KYLIN_RK3036
+ bool "KYLIN_RK3036"
+ select BOARD_LATE_INIT
+
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x200081c8
+
+config SYS_SOC
+ default "rk3036"
+
+config SYS_MALLOC_F_LEN
+ default 0x400
+
+config SPL_SERIAL_SUPPORT
+ default y
+
+source "board/rockchip/evb_rk3036/Kconfig"
+source "board/rockchip/kylin_rk3036/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3036/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3036/Makefile
new file mode 100644
index 000000000..299fc5063
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036/Makefile
@@ -0,0 +1,14 @@
+#
+# (C) Copyright 2015 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk3036.o
+
+ifndef CONFIG_SPL_BUILD
+obj-y += syscon_rk3036.o
+endif
+
+obj-y += rk3036.o
+obj-y += sdram_rk3036.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3036/clk_rk3036.c b/roms/u-boot/arch/arm/mach-rockchip/rk3036/clk_rk3036.c
new file mode 100644
index 000000000..116dccd7b
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036/clk_rk3036.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3036.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3036_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3036_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/roms/u-boot/arch/arm/mach-rockchip/rk3036/rk3036.c b/roms/u-boot/arch/arm/mach-rockchip/rk3036/rk3036.c
new file mode 100644
index 000000000..0a072cf03
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036/rk3036.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/grf_rk3036.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram_rk3036.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+#define GRF_BASE 0x20008000
+ struct rk3036_grf * const grf = (void *)GRF_BASE;
+ enum {
+ GPIO1C3_SHIFT = 6,
+ GPIO1C3_MASK = 3 << GPIO1C3_SHIFT,
+ GPIO1C3_GPIO = 0,
+ GPIO1C3_MMC0_D1,
+ GPIO1C3_UART2_SOUT,
+
+ GPIO1C2_SHIFT = 4,
+ GPIO1C2_MASK = 3 << GPIO1C2_SHIFT,
+ GPIO1C2_GPIO = 0,
+ GPIO1C2_MMC0_D0,
+ GPIO1C2_UART2_SIN,
+ };
+ /*
+ * NOTE: sd card and debug uart use same iomux in rk3036,
+ * so if you enable uart,
+ * you can not boot from sdcard
+ */
+ rk_clrsetreg(&grf->gpio1c_iomux,
+ GPIO1C3_MASK << GPIO1C3_SHIFT |
+ GPIO1C2_MASK << GPIO1C2_SHIFT,
+ GPIO1C3_UART2_SOUT << GPIO1C3_SHIFT |
+ GPIO1C2_UART2_SIN << GPIO1C2_SHIFT);
+}
+#endif
+
+#if !CONFIG_IS_ENABLED(RAM)
+/*
+ * When CONFIG_RAM is enabled, the dram_init() function is implemented
+ * in sdram.c.
+ */
+int dram_init(void)
+{
+ gd->ram_size = sdram_size();
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c b/roms/u-boot/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
new file mode 100644
index 000000000..6ae254e99
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036/sdram_rk3036.c
@@ -0,0 +1,767 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/arch-rockchip/cru_rk3036.h>
+#include <asm/arch-rockchip/grf_rk3036.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/sdram_rk3036.h>
+#include <asm/arch-rockchip/uart.h>
+#include <linux/delay.h>
+
+/*
+ * we can not fit the code to access the device tree in SPL
+ * (due to 4K SRAM size limits), so these are hard-coded
+ */
+#define CRU_BASE 0x20000000
+#define GRF_BASE 0x20008000
+#define DDR_PHY_BASE 0x2000a000
+#define DDR_PCTL_BASE 0x20004000
+#define CPU_AXI_BUS_BASE 0x10128000
+
+struct rk3036_sdram_priv {
+ struct rk3036_cru *cru;
+ struct rk3036_grf *grf;
+ struct rk3036_ddr_phy *phy;
+ struct rk3036_ddr_pctl *pctl;
+ struct rk3036_service_sys *axi_bus;
+
+ /* ddr die config */
+ struct rk3036_ddr_config ddr_config;
+};
+
+/*
+ * use integer mode, dpll output 792MHz and ddr get 396MHz
+ * refdiv, fbdiv, postdiv1, postdiv2
+ */
+const struct pll_div dpll_init_cfg = {1, 66, 2, 1};
+
+/* 396Mhz ddr timing */
+const struct rk3036_ddr_timing ddr_timing = {0x18c,
+ {0x18c, 0xc8, 0x1f4, 0x27, 0x4e,
+ 0x4, 0x8b, 0x06, 0x03, 0x0, 0x06, 0x05, 0x0f, 0x15, 0x06, 0x04, 0x04,
+ 0x06, 0x04, 0x200, 0x03, 0x0a, 0x40, 0x2710, 0x01, 0x05, 0x05, 0x03,
+ 0x0c, 0x28, 0x100, 0x0, 0x04, 0x0},
+ {{0x420, 0x42, 0x0, 0x0}, 0x01, 0x60},
+ {0x24717315} };
+
+/*
+ * [7:6] bank(n:n bit bank)
+ * [5:4] row(13+n)
+ * [3] cs(0:1 cs, 1:2 cs)
+ * [2:1] bank(n:n bit bank)
+ * [0] col(10+n)
+ */
+const char ddr_cfg_2_rbc[] = {
+ ((3 << 6) | (3 << 4) | (0 << 3) | (0 << 1) | 1),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (1 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (2 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (3 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (0 << 4) | (0 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (0 << 4) | (0 << 3) | (3 << 1) | 1),
+ ((0 << 6) | (3 << 4) | (1 << 3) | (3 << 1) | 0),
+ ((0 << 6) | (3 << 4) | (1 << 3) | (3 << 1) | 1),
+ ((1 << 6) | (2 << 4) | (0 << 3) | (2 << 1) | 0),
+ ((3 << 6) | (2 << 4) | (0 << 3) | (0 << 1) | 1),
+ ((3 << 6) | (3 << 4) | (0 << 3) | (0 << 1) | 0),
+};
+
+/* DDRPHY REG */
+enum {
+ /* DDRPHY_REG1 */
+ SOFT_RESET_MASK = 3,
+ SOFT_RESET_SHIFT = 2,
+
+ /* DDRPHY_REG2 */
+ MEMORY_SELECT_DDR3 = 0 << 6,
+ DQS_SQU_CAL_NORMAL_MODE = 0 << 1,
+ DQS_SQU_CAL_START = 1 << 0,
+ DQS_SQU_NO_CAL = 0 << 0,
+
+ /* DDRPHY_REG2A */
+ CMD_DLL_BYPASS = 1 << 4,
+ CMD_DLL_BYPASS_DISABLE = 0 << 4,
+ HIGH_8BIT_DLL_BYPASS = 1 << 3,
+ HIGH_8BIT_DLL_BYPASS_DISABLE = 0 << 3,
+ LOW_8BIT_DLL_BYPASS = 1 << 2,
+ LOW_8BIT_DLL_BYPASS_DISABLE = 0 << 2,
+
+ /* DDRPHY_REG19 */
+ CMD_FEEDBACK_ENABLE = 1 << 5,
+ CMD_SLAVE_DLL_INVERSE_MODE = 1 << 4,
+ CMD_SLAVE_DLL_NO_INVERSE_MODE = 0 << 4,
+ CMD_SLAVE_DLL_ENALBE = 1 << 3,
+ CMD_TX_SLAVE_DLL_DELAY_MASK = 7,
+ CMD_TX_SLAVE_DLL_DELAY_SHIFT = 0,
+
+ /* DDRPHY_REG6 */
+ LEFT_CHN_TX_DQ_PHASE_BYPASS_90 = 1 << 4,
+ LEFT_CHN_TX_DQ_PHASE_BYPASS_0 = 0 << 4,
+ LEFT_CHN_TX_DQ_DLL_ENABLE = 1 << 3,
+ LEFT_CHN_TX_DQ_DLL_DELAY_MASK = 7,
+ LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT = 0,
+
+ /* DDRPHY_REG8 */
+ LEFT_CHN_RX_DQS_DELAY_TAP_MASK = 3,
+ LEFT_CHN_RX_DQS_DELAY_TAP_SHIFT = 0,
+
+ /* DDRPHY_REG9 */
+ RIGHT_CHN_TX_DQ_PHASE_BYPASS_90 = 1 << 4,
+ RIGHT_CHN_TX_DQ_PHASE_BYPASS_0 = 0 << 4,
+ RIGHT_CHN_TX_DQ_DLL_ENABLE = 1 << 3,
+ RIGHT_CHN_TX_DQ_DLL_DELAY_MASK = 7,
+ RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT = 0,
+
+ /* DDRPHY_REG11 */
+ RIGHT_CHN_RX_DQS_DELAY_TAP_MASK = 3,
+ RIGHT_CHN_RX_DQS_DELAY_TAP_SHIFT = 0,
+
+ /* DDRPHY_REG62 */
+ CAL_DONE_MASK = 3,
+ HIGH_8BIT_CAL_DONE = 1 << 1,
+ LOW_8BIT_CAL_DONE = 1 << 0,
+};
+
+/* PTCL */
+enum {
+ /* PCTL_DFISTCFG0 */
+ DFI_INIT_START = 1 << 0,
+ DFI_DATA_BYTE_DISABLE_EN = 1 << 2,
+
+ /* PCTL_DFISTCFG1 */
+ DFI_DRAM_CLK_SR_EN = 1 << 0,
+ DFI_DRAM_CLK_DPD_EN = 1 << 1,
+
+ /* PCTL_DFISTCFG2 */
+ DFI_PARITY_INTR_EN = 1 << 0,
+ DFI_PARITY_EN = 1 << 1,
+
+ /* PCTL_DFILPCFG0 */
+ TLP_RESP_TIME_SHIFT = 16,
+ LP_SR_EN = 1 << 8,
+ LP_PD_EN = 1 << 0,
+
+ /* PCTL_DFIODTCFG */
+ RANK0_ODT_WRITE_SEL = 1 << 3,
+ RANK1_ODT_WRITE_SEL = 1 << 11,
+
+ /* PCTL_DFIODTCFG1 */
+ ODT_LEN_BL8_W_SHIFT = 16,
+
+ /* PCTL_MCFG */
+ TFAW_CFG_MASK = 3,
+ TFAW_CFG_SHIFT = 18,
+ PD_EXIT_SLOW_MODE = 0 << 17,
+ PD_ACTIVE_POWER_DOWN = 1 << 16,
+ PD_IDLE_MASK = 0xff,
+ PD_IDLE_SHIFT = 8,
+ MEM_BL4 = 0 << 0,
+ MEM_BL8 = 1 << 0,
+
+ /* PCTL_MCFG1 */
+ HW_EXIT_IDLE_EN_MASK = 1,
+ HW_EXIT_IDLE_EN_SHIFT = 31,
+ SR_IDLE_MASK = 0x1ff,
+ SR_IDLE_SHIFT = 0,
+
+ /* PCTL_SCFG */
+ HW_LOW_POWER_EN = 1 << 0,
+
+ /* PCTL_POWCTL */
+ POWER_UP_START = 1 << 0,
+
+ /* PCTL_POWSTAT */
+ POWER_UP_DONE = 1 << 0,
+
+ /* PCTL_MCMD */
+ START_CMD = 1 << 31,
+ BANK_ADDR_MASK = 7,
+ BANK_ADDR_SHIFT = 17,
+ CMD_ADDR_MASK = 0x1fff,
+ CMD_ADDR_SHIFT = 4,
+ DESELECT_CMD = 0,
+ PREA_CMD,
+ REF_CMD,
+ MRS_CMD,
+ ZQCS_CMD,
+ ZQCL_CMD,
+ RSTL_CMD,
+ MRR_CMD = 8,
+
+ /* PCTL_STAT */
+ INIT_MEM = 0,
+ CONFIG,
+ CONFIG_REQ,
+ ACCESS,
+ ACCESS_REQ,
+ LOW_POWER,
+ LOW_POWER_ENTRY_REQ,
+ LOW_POWER_EXIT_REQ,
+ PCTL_STAT_MASK = 7,
+
+ /* PCTL_SCTL */
+ INIT_STATE = 0,
+ CFG_STATE = 1,
+ GO_STATE = 2,
+ SLEEP_STATE = 3,
+ WAKEUP_STATE = 4,
+};
+
+/* GRF_SOC_CON2 */
+#define MSCH4_MAINDDR3 (1 << 7)
+#define PHY_DRV_ODT_SET(n) ((n << 4) | n)
+#define DDR3_DLL_RESET (1 << 8)
+
+/* CK pull up/down driver strength control */
+enum {
+ PHY_RON_DISABLE = 0,
+ PHY_RON_309OHM = 1,
+ PHY_RON_155OHM,
+ PHY_RON_103OHM = 3,
+ PHY_RON_63OHM = 5,
+ PHY_RON_45OHM = 7,
+ PHY_RON_77OHM,
+ PHY_RON_62OHM,
+ PHY_RON_52OHM,
+ PHY_RON_44OHM,
+ PHY_RON_39OHM,
+ PHY_RON_34OHM,
+ PHY_RON_31OHM,
+ PHY_RON_28OHM,
+};
+
+/* DQ pull up/down control */
+enum {
+ PHY_RTT_DISABLE = 0,
+ PHY_RTT_861OHM = 1,
+ PHY_RTT_431OHM,
+ PHY_RTT_287OHM,
+ PHY_RTT_216OHM,
+ PHY_RTT_172OHM,
+ PHY_RTT_145OHM,
+ PHY_RTT_124OHM,
+ PHY_RTT_215OHM,
+ PHY_RTT_144OHM = 0xa,
+ PHY_RTT_123OHM,
+ PHY_RTT_108OHM,
+ PHY_RTT_96OHM,
+ PHY_RTT_86OHM,
+ PHY_RTT_78OHM,
+};
+
+/* DQS squelch DLL delay */
+enum {
+ DQS_DLL_NO_DELAY = 0,
+ DQS_DLL_22P5_DELAY,
+ DQS_DLL_45_DELAY,
+ DQS_DLL_67P5_DELAY,
+ DQS_DLL_90_DELAY,
+ DQS_DLL_112P5_DELAY,
+ DQS_DLL_135_DELAY,
+ DQS_DLL_157P5_DELAY,
+};
+
+/* GRF_OS_REG1 */
+enum {
+ /*
+ * 000: lpddr
+ * 001: ddr
+ * 010: ddr2
+ * 011: ddr3
+ * 100: lpddr2-s2
+ * 101: lpddr2-s4
+ * 110: lpddr3
+ */
+ DDR_TYPE_MASK = 7,
+ DDR_TYPE_SHIFT = 13,
+
+ /* 0: 1 chn, 1: 2 chn */
+ DDR_CHN_CNT_SHIFT = 12,
+
+ /* 0: 1 rank, 1: 2 rank */
+ DDR_RANK_CNT_MASK = 1,
+ DDR_RANK_CNT_SHIFT = 11,
+
+ /*
+ * 00: 9col
+ * 01: 10col
+ * 10: 11col
+ * 11: 12col
+ */
+ DDR_COL_MASK = 3,
+ DDR_COL_SHIFT = 9,
+
+ /* 0: 8 bank, 1: 4 bank*/
+ DDR_BANK_MASK = 1,
+ DDR_BANK_SHIFT = 8,
+
+ /*
+ * 00: 13 row
+ * 01: 14 row
+ * 10: 15 row
+ * 11: 16 row
+ */
+ DDR_CS0_ROW_MASK = 3,
+ DDR_CS0_ROW_SHIFT = 6,
+ DDR_CS1_ROW_MASK = 3,
+ DDR_CS1_ROW_SHIFT = 4,
+
+ /*
+ * 00: 32 bit
+ * 01: 16 bit
+ * 10: 8 bit
+ * rk3036 only support 16bit
+ */
+ DDR_BW_MASK = 3,
+ DDR_BW_SHIFT = 2,
+ DDR_DIE_BW_MASK = 3,
+ DDR_DIE_BW_SHIFT = 0,
+};
+
+static void rkdclk_init(struct rk3036_sdram_priv *priv)
+{
+ struct rk3036_pll *pll = &priv->cru->pll[1];
+
+ /* pll enter slow-mode */
+ rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
+ DPLL_MODE_SLOW << DPLL_MODE_SHIFT);
+
+ /* use integer mode */
+ rk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);
+
+ rk_clrsetreg(&pll->con0,
+ PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,
+ (dpll_init_cfg.postdiv1 << PLL_POSTDIV1_SHIFT) |
+ dpll_init_cfg.fbdiv);
+ rk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,
+ (dpll_init_cfg.postdiv2 << PLL_POSTDIV2_SHIFT |
+ dpll_init_cfg.refdiv << PLL_REFDIV_SHIFT));
+
+ /* waiting for pll lock */
+ while (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))
+ udelay(1);
+
+ /* PLL enter normal-mode */
+ rk_clrsetreg(&priv->cru->cru_mode_con, DPLL_MODE_MASK,
+ DPLL_MODE_NORM << DPLL_MODE_SHIFT);
+}
+
+static void 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++;
+ }
+}
+
+void phy_pctrl_reset(struct rk3036_sdram_priv *priv)
+{
+ struct rk3036_ddr_phy *ddr_phy = priv->phy;
+
+ rk_clrsetreg(&priv->cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT | 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT,
+ 1 << DDRCTRL_PSRST_SHIFT | 1 << DDRCTRL_SRST_SHIFT |
+ 1 << DDRPHY_PSRST_SHIFT | 1 << DDRPHY_SRST_SHIFT);
+
+ udelay(10);
+
+ rk_clrreg(&priv->cru->cru_softrst_con[5], 1 << DDRPHY_PSRST_SHIFT |
+ 1 << DDRPHY_SRST_SHIFT);
+ udelay(10);
+
+ rk_clrreg(&priv->cru->cru_softrst_con[5], 1 << DDRCTRL_PSRST_SHIFT |
+ 1 << DDRCTRL_SRST_SHIFT);
+ udelay(10);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg1,
+ SOFT_RESET_MASK << SOFT_RESET_SHIFT,
+ 0 << SOFT_RESET_SHIFT);
+ udelay(10);
+ clrsetbits_le32(&ddr_phy->ddrphy_reg1,
+ SOFT_RESET_MASK << SOFT_RESET_SHIFT,
+ 3 << SOFT_RESET_SHIFT);
+
+ udelay(1);
+}
+
+void phy_dll_bypass_set(struct rk3036_sdram_priv *priv, unsigned int freq)
+{
+ struct rk3036_ddr_phy *ddr_phy = priv->phy;
+
+ if (freq < ddr_timing.freq) {
+ writel(CMD_DLL_BYPASS | HIGH_8BIT_DLL_BYPASS |
+ LOW_8BIT_DLL_BYPASS, &ddr_phy->ddrphy_reg2a);
+
+ writel(LEFT_CHN_TX_DQ_PHASE_BYPASS_90 |
+ LEFT_CHN_TX_DQ_DLL_ENABLE |
+ (0 & LEFT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg6);
+
+ writel(RIGHT_CHN_TX_DQ_PHASE_BYPASS_90 |
+ RIGHT_CHN_TX_DQ_DLL_ENABLE |
+ (0 & RIGHT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT,
+ &ddr_phy->ddrphy_reg9);
+ } else {
+ writel(CMD_DLL_BYPASS_DISABLE | HIGH_8BIT_DLL_BYPASS_DISABLE |
+ LOW_8BIT_DLL_BYPASS_DISABLE, &ddr_phy->ddrphy_reg2a);
+
+ writel(LEFT_CHN_TX_DQ_PHASE_BYPASS_0 |
+ LEFT_CHN_TX_DQ_DLL_ENABLE |
+ (4 & LEFT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ LEFT_CHN_TX_DQ_DLL_DELAY_SHIFT,
+ &ddr_phy->ddrphy_reg6);
+
+ writel(RIGHT_CHN_TX_DQ_PHASE_BYPASS_0 |
+ RIGHT_CHN_TX_DQ_DLL_ENABLE |
+ (4 & RIGHT_CHN_TX_DQ_DLL_DELAY_MASK) <<
+ RIGHT_CHN_TX_DQ_DLL_DELAY_SHIFT,
+ &ddr_phy->ddrphy_reg9);
+ }
+
+ writel(CMD_SLAVE_DLL_NO_INVERSE_MODE | CMD_SLAVE_DLL_ENALBE |
+ (0 & CMD_TX_SLAVE_DLL_DELAY_MASK) <<
+ CMD_TX_SLAVE_DLL_DELAY_SHIFT, &ddr_phy->ddrphy_reg19);
+
+ /* 45 degree delay */
+ writel((DQS_DLL_45_DELAY & LEFT_CHN_RX_DQS_DELAY_TAP_MASK) <<
+ LEFT_CHN_RX_DQS_DELAY_TAP_SHIFT, &ddr_phy->ddrphy_reg8);
+ writel((DQS_DLL_45_DELAY & RIGHT_CHN_RX_DQS_DELAY_TAP_MASK) <<
+ RIGHT_CHN_RX_DQS_DELAY_TAP_SHIFT, &ddr_phy->ddrphy_reg11);
+}
+
+static void send_command(struct rk3036_ddr_pctl *pctl,
+ u32 rank, u32 cmd, u32 arg)
+{
+ writel((START_CMD | (rank << 20) | arg | cmd), &pctl->mcmd);
+ udelay(1);
+ while (readl(&pctl->mcmd) & START_CMD)
+ ;
+}
+
+static void memory_init(struct rk3036_sdram_priv *priv)
+{
+ struct rk3036_ddr_pctl *pctl = priv->pctl;
+
+ send_command(pctl, 3, DESELECT_CMD, 0);
+ udelay(1);
+ send_command(pctl, 3, PREA_CMD, 0);
+ send_command(pctl, 3, MRS_CMD,
+ (0x02 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[2] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, MRS_CMD,
+ (0x03 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[3] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, MRS_CMD,
+ (0x01 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[1] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT);
+
+ send_command(pctl, 3, MRS_CMD,
+ (0x00 & BANK_ADDR_MASK) << BANK_ADDR_SHIFT |
+ (ddr_timing.phy_timing.mr[0] & CMD_ADDR_MASK) <<
+ CMD_ADDR_SHIFT | DDR3_DLL_RESET);
+
+ send_command(pctl, 3, ZQCL_CMD, 0);
+}
+
+static void data_training(struct rk3036_sdram_priv *priv)
+{
+ struct rk3036_ddr_phy *ddr_phy = priv->phy;
+ struct rk3036_ddr_pctl *pctl = priv->pctl;
+ u32 value;
+
+ /* disable auto refresh */
+ value = readl(&pctl->trefi),
+ writel(0, &pctl->trefi);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
+ DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_CAL_START);
+
+ udelay(1);
+ while ((readl(&ddr_phy->ddrphy_reg62) & CAL_DONE_MASK) !=
+ (HIGH_8BIT_CAL_DONE | LOW_8BIT_CAL_DONE)) {
+ ;
+ }
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg2, 0x03,
+ DQS_SQU_CAL_NORMAL_MODE | DQS_SQU_NO_CAL);
+
+ /*
+ * since data training will take about 20us, so send some auto
+ * refresh(about 7.8us) to complement the lost time
+ */
+ send_command(pctl, 3, REF_CMD, 0);
+ send_command(pctl, 3, REF_CMD, 0);
+ send_command(pctl, 3, REF_CMD, 0);
+
+ writel(value, &pctl->trefi);
+}
+
+static void move_to_config_state(struct rk3036_sdram_priv *priv)
+{
+ unsigned int state;
+ struct rk3036_ddr_pctl *pctl = priv->pctl;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK)
+ != ACCESS)
+ ;
+ /*
+ * If at low power state, need wakeup first, and then
+ * enter the config, so fallthrough
+ */
+ case ACCESS:
+ /* fallthrough */
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ break;
+ case CONFIG:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void move_to_access_state(struct rk3036_sdram_priv *priv)
+{
+ unsigned int state;
+ struct rk3036_ddr_pctl *pctl = priv->pctl;
+
+ while (1) {
+ state = readl(&pctl->stat) & PCTL_STAT_MASK;
+ switch (state) {
+ case LOW_POWER:
+ writel(WAKEUP_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case INIT_MEM:
+ writel(CFG_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != CONFIG)
+ ;
+ /* fallthrough */
+ case CONFIG:
+ writel(GO_STATE, &pctl->sctl);
+ while ((readl(&pctl->stat) & PCTL_STAT_MASK) != ACCESS)
+ ;
+ break;
+ case ACCESS:
+ return;
+ default:
+ break;
+ }
+ }
+}
+
+static void pctl_cfg(struct rk3036_sdram_priv *priv)
+{
+ struct rk3036_ddr_pctl *pctl = priv->pctl;
+ u32 burst_len;
+ u32 reg;
+
+ writel(DFI_INIT_START | DFI_DATA_BYTE_DISABLE_EN, &pctl->dfistcfg0);
+ writel(DFI_DRAM_CLK_SR_EN | DFI_DRAM_CLK_DPD_EN, &pctl->dfistcfg1);
+ writel(DFI_PARITY_INTR_EN | DFI_PARITY_EN, &pctl->dfistcfg2);
+ writel(7 << TLP_RESP_TIME_SHIFT | LP_SR_EN | LP_PD_EN,
+ &pctl->dfilpcfg0);
+
+ writel(1, &pctl->dfitphyupdtype0);
+ writel(0x0d, &pctl->dfitphyrdlat);
+
+ /* cs0 and cs1 write odt enable */
+ writel((RANK0_ODT_WRITE_SEL | RANK1_ODT_WRITE_SEL),
+ &pctl->dfiodtcfg);
+
+ /* odt write length */
+ writel(7 << ODT_LEN_BL8_W_SHIFT, &pctl->dfiodtcfg1);
+
+ /* phyupd and ctrlupd disabled */
+ writel(0, &pctl->dfiupdcfg);
+
+ if ((ddr_timing.noc_timing.burstlen << 1) == 4)
+ burst_len = MEM_BL4;
+ else
+ burst_len = MEM_BL8;
+
+ copy_to_reg(&pctl->togcnt1u, &ddr_timing.pctl_timing.togcnt1u,
+ sizeof(struct rk3036_pctl_timing));
+ reg = readl(&pctl->tcl);
+ writel(reg - 3, &pctl->dfitrddataen);
+ reg = readl(&pctl->tcwl);
+ writel(reg - 1, &pctl->dfitphywrlat);
+
+ writel(burst_len | (1 & TFAW_CFG_MASK) << TFAW_CFG_SHIFT |
+ PD_EXIT_SLOW_MODE | PD_ACTIVE_POWER_DOWN |
+ (0 & PD_IDLE_MASK) << PD_IDLE_SHIFT,
+ &pctl->mcfg);
+
+ writel(RK_SETBITS(MSCH4_MAINDDR3), &priv->grf->soc_con2);
+ setbits_le32(&pctl->scfg, HW_LOW_POWER_EN);
+}
+
+static void phy_cfg(struct rk3036_sdram_priv *priv)
+{
+ struct rk3036_ddr_phy *ddr_phy = priv->phy;
+ struct rk3036_service_sys *axi_bus = priv->axi_bus;
+
+ writel(ddr_timing.noc_timing.noc_timing, &axi_bus->ddrtiming);
+ writel(0x3f, &axi_bus->readlatency);
+
+ writel(MEMORY_SELECT_DDR3 | DQS_SQU_CAL_NORMAL_MODE,
+ &ddr_phy->ddrphy_reg2);
+
+ clrsetbits_le32(&ddr_phy->ddrphy_reg3, 1, ddr_timing.phy_timing.bl);
+ writel(ddr_timing.phy_timing.cl_al, &ddr_phy->ddrphy_reg4a);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg16);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg22);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg25);
+ writel(PHY_DRV_ODT_SET(PHY_RON_44OHM), &ddr_phy->ddrphy_reg26);
+ writel(PHY_DRV_ODT_SET(PHY_RTT_216OHM), &ddr_phy->ddrphy_reg27);
+ writel(PHY_DRV_ODT_SET(PHY_RTT_216OHM), &ddr_phy->ddrphy_reg28);
+}
+
+void dram_cfg_rbc(struct rk3036_sdram_priv *priv)
+{
+ char noc_config;
+ int i = 0;
+ struct rk3036_ddr_config config = priv->ddr_config;
+ struct rk3036_service_sys *axi_bus = priv->axi_bus;
+
+ move_to_config_state(priv);
+
+ /* 2bit in BIT1, 2 */
+ if (config.rank == 2) {
+ noc_config = (config.cs0_row - 13) << 4 | config.bank << 1 |
+ 1 << 3 | (config.col - 10);
+ if (noc_config == ddr_cfg_2_rbc[9]) {
+ i = 9;
+ goto finish;
+ } else if (noc_config == ddr_cfg_2_rbc[10]) {
+ i = 10;
+ goto finish;
+ }
+ }
+
+ noc_config = (config.cs0_row - 13) << 4 | config.bank << 1 |
+ (config.col - 10);
+
+ for (i = 0; i < sizeof(ddr_cfg_2_rbc); i++) {
+ if (noc_config == ddr_cfg_2_rbc[i])
+ goto finish;
+ }
+
+ /* bank: 1 bit in BIT6,7, 1bit in BIT1, 2 */
+ noc_config = 1 << 6 | (config.cs0_row - 13) << 4 |
+ 2 << 1 | (config.col - 10);
+ if (noc_config == ddr_cfg_2_rbc[11]) {
+ i = 11;
+ goto finish;
+ }
+
+ /* bank: 2bit in BIT6,7 */
+ noc_config = (config.bank << 6) | (config.cs0_row - 13) << 4 |
+ (config.col - 10);
+
+ if (noc_config == ddr_cfg_2_rbc[0])
+ i = 0;
+ else if (noc_config == ddr_cfg_2_rbc[12])
+ i = 12;
+ else if (noc_config == ddr_cfg_2_rbc[13])
+ i = 13;
+finish:
+ writel(i, &axi_bus->ddrconf);
+ move_to_access_state(priv);
+}
+
+static void sdram_all_config(struct rk3036_sdram_priv *priv)
+{
+ u32 os_reg = 0;
+ u32 cs1_row = 0;
+ struct rk3036_ddr_config config = priv->ddr_config;
+
+ if (config.rank > 1)
+ cs1_row = config.cs1_row - 13;
+
+ os_reg = config.ddr_type << DDR_TYPE_SHIFT |
+ 0 << DDR_CHN_CNT_SHIFT |
+ (config.rank - 1) << DDR_RANK_CNT_SHIFT |
+ (config.col - 9) << DDR_COL_SHIFT |
+ (config.bank == 3 ? 0 : 1) << DDR_BANK_SHIFT |
+ (config.cs0_row - 13) << DDR_CS0_ROW_SHIFT |
+ cs1_row << DDR_CS1_ROW_SHIFT |
+ 1 << DDR_BW_SHIFT |
+ (2 >> config.bw) << DDR_DIE_BW_SHIFT;
+ writel(os_reg, &priv->grf->os_reg[1]);
+}
+
+size_t sdram_size(void)
+{
+ u32 size, os_reg, cs0_row, cs1_row, col, bank, rank;
+ struct rk3036_grf *grf = (void *)GRF_BASE;
+
+ os_reg = readl(&grf->os_reg[1]);
+
+ cs0_row = 13 + ((os_reg >> DDR_CS0_ROW_SHIFT) & DDR_CS0_ROW_MASK);
+ cs1_row = 13 + ((os_reg >> DDR_CS1_ROW_SHIFT) & DDR_CS1_ROW_MASK);
+ col = 9 + ((os_reg >> DDR_COL_SHIFT) & DDR_COL_MASK);
+ bank = 3 - ((os_reg >> DDR_BANK_SHIFT) & DDR_BANK_MASK);
+ rank = 1 + ((os_reg >> DDR_RANK_CNT_SHIFT) & DDR_RANK_CNT_MASK);
+
+ /* row + col + bank + bw(rk3036 only support 16bit, so fix in 1) */
+ size = 1 << (cs0_row + col + bank + 1);
+
+ if (rank > 1)
+ size += size >> (cs0_row - cs1_row);
+
+ return size;
+}
+
+void sdram_init(void)
+{
+ struct rk3036_sdram_priv sdram_priv;
+
+ sdram_priv.cru = (void *)CRU_BASE;
+ sdram_priv.grf = (void *)GRF_BASE;
+ sdram_priv.phy = (void *)DDR_PHY_BASE;
+ sdram_priv.pctl = (void *)DDR_PCTL_BASE;
+ sdram_priv.axi_bus = (void *)CPU_AXI_BUS_BASE;
+
+ get_ddr_config(&sdram_priv.ddr_config);
+ sdram_all_config(&sdram_priv);
+ rkdclk_init(&sdram_priv);
+ phy_pctrl_reset(&sdram_priv);
+ phy_dll_bypass_set(&sdram_priv, ddr_timing.freq);
+ pctl_cfg(&sdram_priv);
+ phy_cfg(&sdram_priv);
+ writel(POWER_UP_START, &sdram_priv.pctl->powctl);
+ while (!(readl(&sdram_priv.pctl->powstat) & POWER_UP_DONE))
+ ;
+ memory_init(&sdram_priv);
+ move_to_config_state(&sdram_priv);
+ data_training(&sdram_priv);
+ move_to_access_state(&sdram_priv);
+ dram_cfg_rbc(&sdram_priv);
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c b/roms/u-boot/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c
new file mode 100644
index 000000000..c2fd16079
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3036/syscon_rk3036.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2015 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3036_syscon_ids[] = {
+ { .compatible = "rockchip,rk3036-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3036) = {
+ .name = "rk3036_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3036_syscon_ids,
+};
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3128/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3128/Kconfig
new file mode 100644
index 000000000..b867401c7
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3128/Kconfig
@@ -0,0 +1,27 @@
+if ROCKCHIP_RK3128
+
+choice
+ prompt "RK3128 board select"
+
+config TARGET_EVB_RK3128
+ bool "RK3128 evaluation board"
+ select BOARD_LATE_INIT
+ help
+ RK3128evb is a evaluation board for Rockchip rk3128,
+ with full function and phisical connectors support like
+ usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
+
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x100a0038
+
+config SYS_SOC
+ default "rk3128"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+source "board/rockchip/evb_rk3128/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3128/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3128/Makefile
new file mode 100644
index 000000000..50e111754
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3128/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += rk3128.o
+obj-y += syscon_rk3128.o
+obj-y += clk_rk3128.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3128/clk_rk3128.c b/roms/u-boot/arch/arm/mach-rockchip/rk3128/clk_rk3128.c
new file mode 100644
index 000000000..a1b038c64
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3128/clk_rk3128.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 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_rk3128.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3128_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3128_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/roms/u-boot/arch/arm/mach-rockchip/rk3128/rk3128.c b/roms/u-boot/arch/arm/mach-rockchip/rk3128/rk3128.c
new file mode 100644
index 000000000..01dbfa75c
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3128/rk3128.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <init.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int arch_cpu_init(void)
+{
+ /* We do some SoC one time setting here. */
+
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3128/syscon_rk3128.c b/roms/u-boot/arch/arm/mach-rockchip/rk3128/syscon_rk3128.c
new file mode 100644
index 000000000..1406d5d0d
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3128/syscon_rk3128.c
@@ -0,0 +1,20 @@
+// 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 rk3128_syscon_ids[] = {
+ { .compatible = "rockchip,rk3128-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3128) = {
+ .name = "rk3128_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3128_syscon_ids,
+};
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3188/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3188/Kconfig
new file mode 100644
index 000000000..e24e68ea5
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3188/Kconfig
@@ -0,0 +1,38 @@
+if ROCKCHIP_RK3188
+
+config TARGET_ROCK
+ bool "Radxa Rock"
+ help
+ Rock is a RK3188-based development board with 2 USB and 1 otg
+ ports, HDMI, TV-out, micro-SD card, audio, WiFi and 100MBit
+ Ethernet, It also includes on-board nand and 1GB of SDRAM.
+ Expansion connectors provide access to display pins, I2C, SPI,
+ UART and GPIOs.
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x20004040
+
+config SYS_SOC
+ default "rk3188"
+
+config SYS_MALLOC_F_LEN
+ default 0x0800
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config SPL_SERIAL_SUPPORT
+ default y
+
+config TPL_LIBCOMMON_SUPPORT
+ default y
+
+config TPL_LIBGENERIC_SUPPORT
+ default y
+
+source "board/radxa/rock/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3188/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3188/Makefile
new file mode 100644
index 000000000..7dc123a3d
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3188/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+ifndef CONFIG_TPL_BUILD
+obj-y += clk_rk3188.o
+obj-y += rk3188.o
+obj-y += syscon_rk3188.o
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3188/clk_rk3188.c b/roms/u-boot/arch/arm/mach-rockchip/rk3188/clk_rk3188.c
new file mode 100644
index 000000000..94d1d23e1
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3188/clk_rk3188.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3188.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3188_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3188_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/roms/u-boot/arch/arm/mach-rockchip/rk3188/rk3188.c b/roms/u-boot/arch/arm/mach-rockchip/rk3188/rk3188.c
new file mode 100644
index 000000000..ad8c6cd1d
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3188/rk3188.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <dm.h>
+#include <hang.h>
+#include <init.h>
+#include <led.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3188.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <linux/err.h>
+
+#define GRF_BASE 0x20008000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@1021c000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@10214000",
+};
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+ /* Enable early UART on the RK3188 */
+ struct rk3188_grf * const grf = (void *)GRF_BASE;
+ enum {
+ GPIO1B1_SHIFT = 2,
+ GPIO1B1_MASK = 3,
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_UART2_SOUT,
+ GPIO1B1_JTAG_TDO,
+
+ GPIO1B0_SHIFT = 0,
+ GPIO1B0_MASK = 3,
+ GPIO1B0_GPIO = 0,
+ GPIO1B0_UART2_SIN,
+ GPIO1B0_JTAG_TDI,
+ };
+
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK << GPIO1B1_SHIFT |
+ GPIO1B0_MASK << GPIO1B0_SHIFT,
+ GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
+ GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
+}
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+int arch_cpu_init(void)
+{
+ struct rk3188_grf *grf;
+
+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(grf)) {
+ pr_err("grf syscon returned %ld\n", PTR_ERR(grf));
+ return 0;
+ }
+#ifdef CONFIG_ROCKCHIP_USB_UART
+ rk_clrsetreg(&grf->uoc0_con[0],
+ SIDDQ_MASK | UOC_DISABLE_MASK | COMMON_ON_N_MASK,
+ 1 << SIDDQ_SHIFT | 1 << UOC_DISABLE_SHIFT |
+ 1 << COMMON_ON_N_SHIFT);
+ rk_clrsetreg(&grf->uoc0_con[2],
+ SOFT_CON_SEL_MASK, 1 << SOFT_CON_SEL_SHIFT);
+ rk_clrsetreg(&grf->uoc0_con[3],
+ OPMODE_MASK | XCVRSELECT_MASK |
+ TERMSEL_FULLSPEED_MASK | SUSPENDN_MASK,
+ OPMODE_NODRIVING << OPMODE_SHIFT |
+ XCVRSELECT_FSTRANSC << XCVRSELECT_SHIFT |
+ 1 << TERMSEL_FULLSPEED_SHIFT |
+ 1 << SUSPENDN_SHIFT);
+ rk_clrsetreg(&grf->uoc0_con[0],
+ BYPASSSEL_MASK | BYPASSDMEN_MASK,
+ 1 << BYPASSSEL_SHIFT | 1 << BYPASSDMEN_SHIFT);
+#endif
+ return 0;
+}
+#endif
+
+__weak int rk3188_board_late_init(void)
+{
+ return 0;
+}
+
+int rk_board_late_init(void)
+{
+ struct rk3188_grf *grf;
+
+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ if (IS_ERR(grf)) {
+ pr_err("grf syscon returned %ld\n", PTR_ERR(grf));
+ return 0;
+ }
+
+ /* enable noc remap to mimic legacy loaders */
+ rk_clrsetreg(&grf->soc_con0,
+ NOC_REMAP_MASK << NOC_REMAP_SHIFT,
+ NOC_REMAP_MASK << NOC_REMAP_SHIFT);
+
+ return rk3188_board_late_init();
+}
+
+#ifdef CONFIG_SPL_BUILD
+DECLARE_GLOBAL_DATA_PTR;
+static int setup_led(void)
+{
+#ifdef CONFIG_SPL_LED
+ struct udevice *dev;
+ char *led_name;
+ int ret;
+
+ led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
+ if (!led_name)
+ return 0;
+ ret = led_get_by_label(led_name, &dev);
+ if (ret) {
+ debug("%s: get=%d\n", __func__, ret);
+ return ret;
+ }
+ ret = led_set_state(dev, LEDST_ON);
+ if (ret)
+ return ret;
+#endif
+
+ return 0;
+}
+
+void spl_board_init(void)
+{
+ int ret;
+
+ ret = setup_led();
+ if (ret) {
+ debug("LED ret=%d\n", ret);
+ hang();
+ }
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c b/roms/u-boot/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
new file mode 100644
index 000000000..917ff37c0
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3188/syscon_rk3188.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3188_syscon_ids[] = {
+ { .compatible = "rockchip,rk3188-noc", .data = ROCKCHIP_SYSCON_NOC },
+ { .compatible = "rockchip,rk3188-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3188-pmu", .data = ROCKCHIP_SYSCON_PMU },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3188) = {
+ .name = "rk3188_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3188_syscon_bind_of_plat(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3188_noc) = {
+ .name = "rockchip_rk3188_noc",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids,
+ .bind = rk3188_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3188_grf) = {
+ .name = "rockchip_rk3188_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids + 1,
+ .bind = rk3188_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3188_pmu) = {
+ .name = "rockchip_rk3188_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3188_syscon_ids + 2,
+ .bind = rk3188_syscon_bind_of_plat,
+};
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk322x/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk322x/Kconfig
new file mode 100644
index 000000000..2fc6f6ea3
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk322x/Kconfig
@@ -0,0 +1,37 @@
+if ROCKCHIP_RK322X
+
+
+config TARGET_EVB_RK3229
+ bool "EVB_RK3229"
+ select BOARD_LATE_INIT
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x110005c8
+
+config SYS_SOC
+ default "rk322x"
+
+config SYS_MALLOC_F_LEN
+ default 0x800
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config SPL_SERIAL_SUPPORT
+ default y
+
+config TPL_MAX_SIZE
+ default 28672
+
+config TPL_STACK
+ default 0x10088000
+
+config TPL_TEXT_BASE
+ default 0x10081000
+
+source "board/rockchip/evb_rk3229/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk322x/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk322x/Makefile
new file mode 100644
index 000000000..89b0fed69
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk322x/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2017 Rockchip Electronics Co., Ltd.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk322x.o
+obj-y += rk322x.o
+obj-y += syscon_rk322x.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk322x/clk_rk322x.c b/roms/u-boot/arch/arm/mach-rockchip/rk322x/clk_rk322x.c
new file mode 100644
index 000000000..2e57672b2
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk322x/clk_rk322x.c
@@ -0,0 +1,32 @@
+// 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_rk322x.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk322x_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk322x_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/roms/u-boot/arch/arm/mach-rockchip/rk322x/rk322x.c b/roms/u-boot/arch/arm/mach-rockchip/rk322x/rk322x.c
new file mode 100644
index 000000000..ad4ac62e5
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk322x/rk322x.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+#include <init.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/grf_rk322x.h>
+#include <asm/arch-rockchip/hardware.h>
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@30020000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@30000000",
+};
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+#define GRF_BASE 0x11000000
+ static struct rk322x_grf * const grf = (void *)GRF_BASE;
+ enum {
+ GPIO1B2_SHIFT = 4,
+ GPIO1B2_MASK = 3 << GPIO1B2_SHIFT,
+ GPIO1B2_GPIO = 0,
+ GPIO1B2_UART1_SIN,
+ GPIO1B2_UART21_SIN,
+
+ GPIO1B1_SHIFT = 2,
+ GPIO1B1_MASK = 3 << GPIO1B1_SHIFT,
+ GPIO1B1_GPIO = 0,
+ GPIO1B1_UART1_SOUT,
+ GPIO1B1_UART21_SOUT,
+ };
+ enum {
+ CON_IOMUX_UART2SEL_SHIFT = 8,
+ CON_IOMUX_UART2SEL_MASK = 1 << CON_IOMUX_UART2SEL_SHIFT,
+ CON_IOMUX_UART2SEL_2 = 0,
+ CON_IOMUX_UART2SEL_21,
+ };
+
+ /* Enable early UART2 channel 1 on the RK322x */
+ rk_clrsetreg(&grf->gpio1b_iomux,
+ GPIO1B1_MASK | GPIO1B2_MASK,
+ GPIO1B2_UART21_SIN << GPIO1B2_SHIFT |
+ GPIO1B1_UART21_SOUT << GPIO1B1_SHIFT);
+ /* Set channel C as UART2 input */
+ rk_clrsetreg(&grf->con_iomux,
+ CON_IOMUX_UART2SEL_MASK,
+ CON_IOMUX_UART2SEL_21 << CON_IOMUX_UART2SEL_SHIFT);
+}
+#endif
+
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+#define SGRF_BASE 0x10150000
+ static struct rk322x_sgrf * const sgrf = (void *)SGRF_BASE;
+
+ /* Disable the ddr secure region setting to make it non-secure */
+ rk_clrreg(&sgrf->soc_con[0], 0x4000);
+#else
+#define GRF_BASE 0x11000000
+ static struct rk322x_grf * const grf = (void *)GRF_BASE;
+ /*
+ * The integrated macphy is enabled by default, disable it
+ * for saving power consuming.
+ */
+ rk_clrsetreg(&grf->macphy_con[0],
+ MACPHY_CFG_ENABLE_MASK,
+ 0 << MACPHY_CFG_ENABLE_SHIFT);
+
+#endif
+ return 0;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c b/roms/u-boot/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c
new file mode 100644
index 000000000..0d9dca817
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk322x/syscon_rk322x.c
@@ -0,0 +1,21 @@
+// 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 rk322x_syscon_ids[] = {
+ { .compatible = "rockchip,rk3228-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3228-msch", .data = ROCKCHIP_SYSCON_MSCH },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk322x) = {
+ .name = "rk322x_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk322x_syscon_ids,
+};
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3288/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3288/Kconfig
new file mode 100644
index 000000000..20a00c5be
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3288/Kconfig
@@ -0,0 +1,199 @@
+if ROCKCHIP_RK3288
+
+choice
+ prompt "RK3288 board select"
+
+config TARGET_CHROMEBOOK_JERRY
+ bool "Google/Rockchip Veyron-Jerry Chromebook"
+ select HAS_ROM
+ select BOARD_LATE_INIT
+ select ROCKCHIP_SPI_IMAGE
+ help
+ Jerry is a RK3288-based clamshell device with 2 USB 3.0 ports,
+ HDMI, an 11.9 inch EDP display, micro-SD card, touchpad and
+ WiFi. It includes a Chrome OS EC (Cortex-M3) to provide access to
+ the keyboard and battery functions.
+
+config TARGET_CHROMEBIT_MICKEY
+ bool "Google/Rockchip Veyron-Mickey Chromebit"
+ select BOARD_LATE_INIT
+ help
+ Mickey is a small RK3288-based device with one USB 3.0 port, HDMI
+ and WiFi. It has a separate power port and is designed to connect
+ to the HDMI input of a monitor or TV. It has no internal battery.
+ Typically a USB hub or wireless keyboard/touchpad is used to get
+ keyboard and mouse access.
+
+config TARGET_CHROMEBOOK_MINNIE
+ bool "Google/Rockchip Veyron-Minnie Chromebook"
+ select BOARD_LATE_INIT
+ help
+ Minnie is a RK3288-based convertible clamshell device with 2 USB 3.0
+ ports, micro HDMI, a 10.1-inch 1280x800 EDP display, micro-SD card,
+ HD camera, touchpad, WiFi and Bluetooth. It includes a Chrome OS
+ EC (Cortex-M3) to provide access to the keyboard and battery
+ functions. It includes 2 or 4GB of SDRAM and 16 or 32GB of
+ internal MMC. The product name is ASUS Chromebook Flip.
+
+config TARGET_CHROMEBOOK_SPEEDY
+ bool "Google/Rockchip Veyron-Speedy Chromebook"
+ select BOARD_LATE_INIT
+ help
+ Speedy is a RK3288-based clamshell device with 2 USB 2.0 ports,
+ micro HDMI, an 11.6 inch display, micro-SD card,
+ HD camera, touchpad, wifi and Bluetooth. It includes a Chrome OS
+ EC (Cortex-M3) to provide access to the keyboard and battery
+ functions. It includes 2 or 4GB of SDRAM and 16GB of internal MMC.
+ The product name is Asus Chromebook C201PA.
+
+config TARGET_EVB_RK3288
+ bool "Evb-RK3288"
+ select HAS_ROM
+ select BOARD_LATE_INIT
+ select TPL
+ help
+ EVB-RK3288 is a RK3288-based development board with 2 USB ports,
+ HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It
+ also includes on-board eMMC and 2GB of SDRAM. Expansion connectors
+ provide access to display pins, I2C, SPI, UART and GPIOs.
+
+config TARGET_FENNEC_RK3288
+ bool "Fennec-RK3288"
+ select BOARD_LATE_INIT
+ help
+ Fennec is a RK3288-based development board with 2 USB ports,
+ HDMI, micro-SD card, audio, WiFi and Gigabit Ethernet. It also
+ includes on-board eMMC and 2GB of SDRAM. Expansion connectors
+ provide access to display pins, I2C, SPI, UART and GPIOs.
+
+config TARGET_FIREFLY_RK3288
+ bool "Firefly-RK3288"
+ select BOARD_LATE_INIT
+ select SPL_BOARD_INIT if SPL
+ select TPL
+ help
+ Firefly is a RK3288-based development board with 2 USB ports,
+ HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It
+ also includes on-board eMMC and 1GB of SDRAM. Expansion connectors
+ provide access to display pins, I2C, SPI, UART and GPIOs.
+
+config TARGET_MIQI_RK3288
+ bool "MiQi-RK3288"
+ select BOARD_LATE_INIT
+ help
+ MiQi-RK3288 is a RK3288-based development board with 4 USB 2.0
+ ports, HDMI, micro-SD card, 16 GB eMMC and Gigabit Ethernet. It
+ has 1 or 2 GiB SDRAM. Expansion connectors provide access to
+ I2C, SPI, UART, GPIOs and fan control.
+
+config TARGET_PHYCORE_RK3288
+ bool "phyCORE-RK3288"
+ select BOARD_LATE_INIT
+ select SPL_BOARD_INIT if SPL
+ help
+ Add basic support for the PCM-947 carrier board, a RK3288 based
+ development board made by PHYTEC. This board works in a combination
+ with the phyCORE-RK3288 System on Module.
+
+config TARGET_POPMETAL_RK3288
+ bool "PopMetal-RK3288"
+ select BOARD_LATE_INIT
+ help
+ PopMetal is a RK3288-based development board with 3 USB host ports,
+ 1 micro USB OTG port, HDMI, VGA, micro-SD card, audio, WiFi, Gigabit
+ Ethernet and lots of sensors. It also includes on-board 8 GeMMC and
+ 2GB DDR3. Expansion connectors provide access to I2C, SPI, UART,
+ GPIOs and display interface.
+
+config TARGET_VYASA_RK3288
+ bool "Vyasa-RK3288"
+ select BOARD_LATE_INIT
+ select TPL
+ help
+ Vyasa is a RK3288-based development board with 2 USB ports,
+ HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It
+ also includes on-board eMMC and 2GB of SDRAM. Expansion connectors
+ provide access to display pins, I2C, SPI, UART and GPIOs.
+
+config TARGET_ROCK2
+ bool "Radxa Rock 2"
+ select BOARD_LATE_INIT
+ help
+ Rock 2 is a SOM and base-board combination based on RK3288. It
+ includes Ethernet, HDMI, 3 USB, micro-SD, audio, SATA, WiFi and
+ space for a real-time-clock battery. There is also an expansion
+ interface which provides access to many pins.
+
+config TARGET_TINKER_RK3288
+ bool "Tinker-RK3288"
+ select BOARD_LATE_INIT
+ select TPL
+ help
+ Tinker is a RK3288-based development board with 2 USB ports, HDMI,
+ micro-SD card, audio, Gigabit Ethernet. It also includes on-board
+ 8GB eMMC and 2GB of SDRAM. Expansion connectors provide access to
+ I2C, SPI, UART, GPIOs.
+
+endchoice
+
+config ROCKCHIP_FAST_SPL
+ bool "Change the CPU to full speed in SPL"
+ depends on TARGET_CHROMEBOOK_JERRY
+ help
+ Some boards want to boot as fast as possible. We can increase the
+ CPU frequency in SPL if the power supply is configured to the correct
+ voltage. This option is only available on boards which support it
+ and have the required PMIC code.
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff730094
+
+config SYS_SOC
+ default "rk3288"
+
+config SYS_MALLOC_F_LEN
+ default 0x2000
+
+config SPL_DRIVERS_MISC_SUPPORT
+ default y
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config SPL_SERIAL_SUPPORT
+ default y
+
+config TPL_LDSCRIPT
+ default "arch/arm/mach-rockchip/u-boot-tpl.lds"
+
+config TPL_MAX_SIZE
+ default 32768
+
+config TPL_STACK
+ default 0xff718000
+
+config TPL_TEXT_BASE
+ default 0xff704000
+
+source "board/amarula/vyasa-rk3288/Kconfig"
+
+source "board/chipspark/popmetal_rk3288/Kconfig"
+
+source "board/firefly/firefly-rk3288/Kconfig"
+
+source "board/google/veyron/Kconfig"
+
+source "board/mqmaker/miqi_rk3288/Kconfig"
+
+source "board/phytec/phycore_rk3288/Kconfig"
+
+source "board/radxa/rock2/Kconfig"
+
+source "board/rockchip/evb_rk3288/Kconfig"
+
+source "board/rockchip/tinker_rk3288/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3288/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3288/Makefile
new file mode 100644
index 000000000..a0033a0d8
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3288/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk3288.o
+obj-y += rk3288.o
+obj-y += syscon_rk3288.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3288/clk_rk3288.c b/roms/u-boot/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
new file mode 100644
index 000000000..fb4c0891d
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3288/clk_rk3288.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3288_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3288_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/roms/u-boot/arch/arm/mach-rockchip/rk3288/rk3288.c b/roms/u-boot/arch/arm/mach-rockchip/rk3288/rk3288.c
new file mode 100644
index 000000000..bc20bc5ab
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <env.h>
+#include <clk.h>
+#include <init.h>
+#include <malloc.h>
+#include <asm/armv7.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cpu_rk3288.h>
+#include <asm/arch-rockchip/cru.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk3288.h>
+#include <asm/arch-rockchip/pmu_rk3288.h>
+#include <asm/arch-rockchip/qos_rk3288.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <linux/err.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define GRF_BASE 0xff770000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
+};
+
+#ifdef CONFIG_SPL_BUILD
+static void configure_l2ctlr(void)
+{
+ u32 l2ctlr;
+
+ l2ctlr = read_l2ctlr();
+ l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
+
+ /*
+ * Data RAM write latency: 2 cycles
+ * Data RAM read latency: 2 cycles
+ * Data RAM setup latency: 1 cycle
+ * Tag RAM write latency: 1 cycle
+ * Tag RAM read latency: 1 cycle
+ * Tag RAM setup latency: 1 cycle
+ */
+ l2ctlr |= (1 << 3 | 1 << 0);
+ write_l2ctlr(l2ctlr);
+}
+#endif
+
+int rk3288_qos_init(void)
+{
+ int val = 2 << PRIORITY_HIGH_SHIFT | 2 << PRIORITY_LOW_SHIFT;
+ /* set vop qos to higher priority */
+ writel(val, CPU_AXI_QOS_PRIORITY + VIO0_VOP_QOS);
+ writel(val, CPU_AXI_QOS_PRIORITY + VIO1_VOP_QOS);
+
+ if (!fdt_node_check_compatible(gd->fdt_blob, 0,
+ "rockchip,rk3288-tinker")) {
+ /* set isp qos to higher priority */
+ writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_R_QOS);
+ writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W0_QOS);
+ writel(val, CPU_AXI_QOS_PRIORITY + VIO1_ISP_W1_QOS);
+ }
+
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+ configure_l2ctlr();
+#else
+ /* We do some SoC one time setting here. */
+ struct rk3288_grf * const grf = (void *)GRF_BASE;
+
+ /* Use rkpwm by default */
+ rk_setreg(&grf->soc_con2, 1 << 0);
+
+ /*
+ * Disable JTAG on sdmmc0 IO. The SDMMC won't work until this bit is
+ * cleared
+ */
+ rk_clrreg(&grf->soc_con0, 1 << 12);
+
+ rk3288_qos_init();
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+ /* Enable early UART on the RK3288 */
+ struct rk3288_grf * const grf = (void *)GRF_BASE;
+
+ rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
+ GPIO7C6_MASK << GPIO7C6_SHIFT,
+ GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
+ GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
+}
+#endif
+
+__weak int rk3288_board_late_init(void)
+{
+ return 0;
+}
+
+int rk_board_late_init(void)
+{
+ return rk3288_board_late_init();
+}
+
+static int ft_rk3288w_setup(void *blob)
+{
+ const char *path;
+ int offs, ret;
+
+ path = "/clock-controller@ff760000";
+ offs = fdt_path_offset(blob, path);
+ if (offs < 0) {
+ debug("failed to found fdt path %s\n", path);
+ return offs;
+ }
+
+ ret = fdt_setprop_string(blob, offs, "compatible", "rockchip,rk3288w-cru");
+ if (ret) {
+ printf("failed to set rk3288w-cru compatible (ret=%d)\n", ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+ if (soc_is_rk3288w())
+ return ft_rk3288w_setup(blob);
+
+ return 0;
+}
+
+static int do_clock(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ static const struct {
+ char *name;
+ int id;
+ } clks[] = {
+ { "osc", CLK_OSC },
+ { "apll", CLK_ARM },
+ { "dpll", CLK_DDR },
+ { "cpll", CLK_CODEC },
+ { "gpll", CLK_GENERAL },
+#ifdef CONFIG_ROCKCHIP_RK3036
+ { "mpll", CLK_NEW },
+#else
+ { "npll", CLK_NEW },
+#endif
+ };
+ int ret, i;
+ struct udevice *dev;
+
+ ret = rockchip_get_clk(&dev);
+ if (ret) {
+ printf("clk-uclass not found\n");
+ return 0;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(clks); i++) {
+ struct clk clk;
+ ulong rate;
+
+ clk.id = clks[i].id;
+ ret = clk_request(dev, &clk);
+ if (ret < 0)
+ continue;
+
+ rate = clk_get_rate(&clk);
+ printf("%s: %lu\n", clks[i].name, rate);
+
+ clk_free(&clk);
+ }
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ clock, 2, 1, do_clock,
+ "display information about clocks",
+ ""
+);
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c b/roms/u-boot/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
new file mode 100644
index 000000000..9c1ae880c
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3288/syscon_rk3288.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3288_syscon_ids[] = {
+ { .compatible = "rockchip,rk3288-noc", .data = ROCKCHIP_SYSCON_NOC },
+ { .compatible = "rockchip,rk3288-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3288-sgrf", .data = ROCKCHIP_SYSCON_SGRF },
+ { .compatible = "rockchip,rk3288-pmu", .data = ROCKCHIP_SYSCON_PMU },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3288) = {
+ .name = "rk3288_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3288_syscon_bind_of_plat(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3288_noc) = {
+ .name = "rockchip_rk3288_noc",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids,
+ .bind = rk3288_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_grf) = {
+ .name = "rockchip_rk3288_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 1,
+ .bind = rk3288_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_sgrf) = {
+ .name = "rockchip_rk3288_sgrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 2,
+ .bind = rk3288_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3288_pmu) = {
+ .name = "rockchip_rk3288_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3288_syscon_ids + 3,
+ .bind = rk3288_syscon_bind_of_plat,
+};
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3308/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3308/Kconfig
new file mode 100644
index 000000000..b9fdfe2e9
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3308/Kconfig
@@ -0,0 +1,27 @@
+if ROCKCHIP_RK3308
+
+config TARGET_EVB_RK3308
+ bool "EVB_RK3308"
+ select BOARD_LATE_INIT
+
+config TARGET_ROC_RK3308_CC
+ bool "Firefly roc-rk3308-cc"
+ select BOARD_LATE_INIT
+
+config SYS_SOC
+ default "rk3308"
+
+config SYS_MALLOC_F_LEN
+ default 0x400
+
+config SPL_SERIAL_SUPPORT
+ default y
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff000500
+
+
+source "board/rockchip/evb_rk3308/Kconfig"
+source "board/firefly/firefly-rk3308/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3308/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3308/Makefile
new file mode 100644
index 000000000..ce4d44bb3
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3308/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2018 Rockchip Electronics Co., Ltd.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += syscon_rk3308.o
+obj-y += rk3308.o
+obj-y += clk_rk3308.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3308/clk_rk3308.c b/roms/u-boot/arch/arm/mach-rockchip/rk3308/clk_rk3308.c
new file mode 100644
index 000000000..ccda53380
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3308/clk_rk3308.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch/cru_rk3308.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3308_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3308_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/roms/u-boot/arch/arm/mach-rockchip/rk3308/rk3308.c b/roms/u-boot/arch/arm/mach-rockchip/rk3308/rk3308.c
new file mode 100644
index 000000000..70fe0d0ac
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3308/rk3308.c
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *Copyright (c) 2018 Rockchip Electronics Co., Ltd
+ */
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch/grf_rk3308.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/gpio.h>
+#include <debug_uart.h>
+#include <linux/bitops.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#include <asm/armv8/mmu.h>
+static struct mm_region rk3308_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 = rk3308_mem_map;
+
+#define GRF_BASE 0xff000000
+#define SGRF_BASE 0xff2b0000
+
+enum {
+ GPIO1C7_SHIFT = 8,
+ GPIO1C7_MASK = GENMASK(11, 8),
+ GPIO1C7_GPIO = 0,
+ GPIO1C7_UART1_RTSN,
+ GPIO1C7_UART2_TX_M0,
+ GPIO1C7_SPI2_MOSI,
+ GPIO1C7_JTAG_TMS,
+
+ GPIO1C6_SHIFT = 4,
+ GPIO1C6_MASK = GENMASK(7, 4),
+ GPIO1C6_GPIO = 0,
+ GPIO1C6_UART1_CTSN,
+ GPIO1C6_UART2_RX_M0,
+ GPIO1C6_SPI2_MISO,
+ GPIO1C6_JTAG_TCLK,
+
+ GPIO4D3_SHIFT = 6,
+ GPIO4D3_MASK = GENMASK(7, 6),
+ GPIO4D3_GPIO = 0,
+ GPIO4D3_SDMMC_D3,
+ GPIO4D3_UART2_TX_M1,
+
+ GPIO4D2_SHIFT = 4,
+ GPIO4D2_MASK = GENMASK(5, 4),
+ GPIO4D2_GPIO = 0,
+ GPIO4D2_SDMMC_D2,
+ GPIO4D2_UART2_RX_M1,
+
+ UART2_IO_SEL_SHIFT = 2,
+ UART2_IO_SEL_MASK = GENMASK(3, 2),
+ UART2_IO_SEL_M0 = 0,
+ UART2_IO_SEL_M1,
+ UART2_IO_SEL_USB,
+
+ GPIO2C0_SEL_SRC_CTRL_SHIFT = 11,
+ GPIO2C0_SEL_SRC_CTRL_MASK = BIT(11),
+ GPIO2C0_SEL_SRC_CTRL_IOMUX = 0,
+ GPIO2C0_SEL_SRC_CTRL_SEL_PLUS,
+
+ GPIO3B3_SEL_SRC_CTRL_SHIFT = 7,
+ GPIO3B3_SEL_SRC_CTRL_MASK = BIT(7),
+ GPIO3B3_SEL_SRC_CTRL_IOMUX = 0,
+ GPIO3B3_SEL_SRC_CTRL_SEL_PLUS,
+
+ GPIO3B3_SEL_PLUS_SHIFT = 4,
+ GPIO3B3_SEL_PLUS_MASK = GENMASK(6, 4),
+ GPIO3B3_SEL_PLUS_GPIO3_B3 = 0,
+ GPIO3B3_SEL_PLUS_FLASH_ALE,
+ GPIO3B3_SEL_PLUS_EMMC_PWREN,
+ GPIO3B3_SEL_PLUS_SPI1_CLK,
+ GPIO3B3_SEL_PLUS_LCDC_D23_M1,
+
+ GPIO3B2_SEL_SRC_CTRL_SHIFT = 3,
+ GPIO3B2_SEL_SRC_CTRL_MASK = BIT(3),
+ GPIO3B2_SEL_SRC_CTRL_IOMUX = 0,
+ GPIO3B2_SEL_SRC_CTRL_SEL_PLUS,
+
+ GPIO3B2_SEL_PLUS_SHIFT = 0,
+ GPIO3B2_SEL_PLUS_MASK = GENMASK(2, 0),
+ GPIO3B2_SEL_PLUS_GPIO3_B2 = 0,
+ GPIO3B2_SEL_PLUS_FLASH_RDN,
+ GPIO3B2_SEL_PLUS_EMMC_RSTN,
+ GPIO3B2_SEL_PLUS_SPI1_MISO,
+ GPIO3B2_SEL_PLUS_LCDC_D22_M1,
+
+ I2C3_IOFUNC_SRC_CTRL_SHIFT = 10,
+ I2C3_IOFUNC_SRC_CTRL_MASK = BIT(10),
+ I2C3_IOFUNC_SRC_CTRL_SEL_PLUS = 1,
+
+ GPIO2A3_SEL_SRC_CTRL_SHIFT = 7,
+ GPIO2A3_SEL_SRC_CTRL_MASK = BIT(7),
+ GPIO2A3_SEL_SRC_CTRL_SEL_PLUS = 1,
+
+ GPIO2A2_SEL_SRC_CTRL_SHIFT = 3,
+ GPIO2A2_SEL_SRC_CTRL_MASK = BIT(3),
+ GPIO2A2_SEL_SRC_CTRL_SEL_PLUS = 1,
+};
+
+enum {
+ IOVSEL3_CTRL_SHIFT = 8,
+ IOVSEL3_CTRL_MASK = BIT(8),
+ VCCIO3_SEL_BY_GPIO = 0,
+ VCCIO3_SEL_BY_IOVSEL3,
+
+ IOVSEL3_SHIFT = 3,
+ IOVSEL3_MASK = BIT(3),
+ VCCIO3_3V3 = 0,
+ VCCIO3_1V8,
+};
+
+/*
+ * The voltage of VCCIO3(which is the voltage domain of emmc/flash/sfc
+ * interface) can indicated by GPIO0_A4 or io_vsel3. The SOC defaults
+ * use GPIO0_A4 to indicate power supply voltage for VCCIO3 by hardware,
+ * then we can switch to io_vsel3 after system power on, and release GPIO0_A4
+ * for other usage.
+ */
+
+#define GPIO0_A4 4
+
+int rk_board_init(void)
+{
+ static struct rk3308_grf * const grf = (void *)GRF_BASE;
+ u32 val;
+ int ret;
+
+ ret = gpio_request(GPIO0_A4, "gpio0_a4");
+ if (ret < 0) {
+ printf("request for gpio0_a4 failed:%d\n", ret);
+ return 0;
+ }
+
+ gpio_direction_input(GPIO0_A4);
+
+ if (gpio_get_value(GPIO0_A4))
+ val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT |
+ VCCIO3_1V8 << IOVSEL3_SHIFT;
+ else
+ val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT |
+ VCCIO3_3V3 << IOVSEL3_SHIFT;
+ rk_clrsetreg(&grf->soc_con0, IOVSEL3_CTRL_MASK | IOVSEL3_MASK, val);
+
+ gpio_free(GPIO0_A4);
+ return 0;
+}
+
+#if defined(CONFIG_DEBUG_UART)
+__weak void board_debug_uart_init(void)
+{
+ static struct rk3308_grf * const grf = (void *)GRF_BASE;
+
+ /* Enable early UART2 channel m1 on the rk3308 */
+ rk_clrsetreg(&grf->soc_con5, UART2_IO_SEL_MASK,
+ UART2_IO_SEL_M1 << UART2_IO_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio4d_iomux,
+ GPIO4D3_MASK | GPIO4D2_MASK,
+ GPIO4D2_UART2_RX_M1 << GPIO4D2_SHIFT |
+ GPIO4D3_UART2_TX_M1 << GPIO4D3_SHIFT);
+}
+#endif
+
+#if defined(CONFIG_SPL_BUILD)
+int arch_cpu_init(void)
+{
+ static struct rk3308_sgrf * const sgrf = (void *)SGRF_BASE;
+ static struct rk3308_grf * const grf = (void *)GRF_BASE;
+
+ /* Set CRYPTO SDMMC EMMC NAND SFC USB master bus to be secure access */
+ rk_clrreg(&sgrf->con_secure0, 0x2b83);
+
+ /*
+ * Enable plus options to use more pinctrl functions, including
+ * GPIO2A2_PLUS, GPIO2A3_PLUS and I2C3_MULTI_SRC_PLUS.
+ */
+ rk_clrsetreg(&grf->soc_con13,
+ I2C3_IOFUNC_SRC_CTRL_MASK | GPIO2A3_SEL_SRC_CTRL_MASK |
+ GPIO2A2_SEL_SRC_CTRL_MASK,
+ I2C3_IOFUNC_SRC_CTRL_SEL_PLUS << I2C3_IOFUNC_SRC_CTRL_SHIFT |
+ GPIO2A3_SEL_SRC_CTRL_SEL_PLUS << GPIO2A3_SEL_SRC_CTRL_SHIFT |
+ GPIO2A2_SEL_SRC_CTRL_SEL_PLUS << GPIO2A2_SEL_SRC_CTRL_SHIFT);
+
+ /* Plus options about GPIO3B2_PLUS, GPIO3B3_PLUS and GPIO2C0_PLUS. */
+ rk_clrsetreg(&grf->soc_con15,
+ GPIO2C0_SEL_SRC_CTRL_MASK | GPIO3B3_SEL_SRC_CTRL_MASK |
+ GPIO3B2_SEL_SRC_CTRL_MASK,
+ GPIO2C0_SEL_SRC_CTRL_SEL_PLUS << GPIO2C0_SEL_SRC_CTRL_SHIFT |
+ GPIO3B3_SEL_SRC_CTRL_SEL_PLUS << GPIO3B3_SEL_SRC_CTRL_SHIFT |
+ GPIO3B2_SEL_SRC_CTRL_SEL_PLUS << GPIO3B2_SEL_SRC_CTRL_SHIFT);
+
+ return 0;
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c b/roms/u-boot/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c
new file mode 100644
index 000000000..b380ff572
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3308/syscon_rk3308.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3308_syscon_ids[] = {
+ { .compatible = "rockchip,rk3308-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3308) = {
+ .name = "rk3308_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3308_syscon_ids,
+};
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3328/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3328/Kconfig
new file mode 100644
index 000000000..d13a16902
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3328/Kconfig
@@ -0,0 +1,44 @@
+if ROCKCHIP_RK3328
+
+choice
+ prompt "RK3328 board select"
+
+config TARGET_EVB_RK3328
+ bool "RK3328 evaluation board"
+ help
+ RK3328evb is a evaluation board for Rockchip rk3328,
+ with full function and phisical connectors support like
+ usb2.0 host ports, LVDS, JTAG, MAC, SDcard, HDMI, USB-2-serial...
+
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff1005c8
+
+config SYS_SOC
+ default "rk3328"
+
+config SYS_MALLOC_F_LEN
+ default 0x2000
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config TPL_LDSCRIPT
+ default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
+
+config TPL_TEXT_BASE
+ default 0xff091000
+
+config TPL_MAX_SIZE
+ default 28672
+
+config TPL_STACK
+ default 0xff098000
+
+source "board/rockchip/evb_rk3328/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3328/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3328/Makefile
new file mode 100644
index 000000000..bbab036a1
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3328/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk3328.o
+obj-y += rk3328.o
+obj-y += syscon_rk3328.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3328/clk_rk3328.c b/roms/u-boot/arch/arm/mach-rockchip/rk3328/clk_rk3328.c
new file mode 100644
index 000000000..70c0eb6f9
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3328/clk_rk3328.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 <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3328.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3328_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3328_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/roms/u-boot/arch/arm/mach-rockchip/rk3328/rk3328.c b/roms/u-boot/arch/arm/mach-rockchip/rk3328/rk3328.c
new file mode 100644
index 000000000..ec3336cb4
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3328/rk3328.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/grf_rk3328.h>
+#include <asm/arch-rockchip/uart.h>
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define CRU_BASE 0xFF440000
+#define GRF_BASE 0xFF100000
+#define UART2_BASE 0xFF130000
+#define FW_DDR_CON_REG 0xFF7C0040
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/rksdmmc@ff520000",
+ [BROM_BOOTSOURCE_SD] = "/rksdmmc@ff500000",
+};
+
+static struct mm_region rk3328_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0xff000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xff000000UL,
+ .phys = 0xff000000UL,
+ .size = 0x1000000UL,
+ .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 = rk3328_mem_map;
+
+int arch_cpu_init(void)
+{
+#ifdef CONFIG_SPL_BUILD
+ /* We do some SoC one time setting here. */
+
+ /* Disable the ddr secure region setting to make it non-secure */
+ rk_setreg(FW_DDR_CON_REG, 0x200);
+#endif
+ return 0;
+}
+
+void board_debug_uart_init(void)
+{
+ struct rk3328_grf_regs * const grf = (void *)GRF_BASE;
+ struct rk_uart * const uart = (void *)UART2_BASE;
+ enum{
+ GPIO2A0_SEL_SHIFT = 0,
+ GPIO2A0_SEL_MASK = 3 << GPIO2A0_SEL_SHIFT,
+ GPIO2A0_UART2_TX_M1 = 1,
+
+ GPIO2A1_SEL_SHIFT = 2,
+ GPIO2A1_SEL_MASK = 3 << GPIO2A1_SEL_SHIFT,
+ GPIO2A1_UART2_RX_M1 = 1,
+ };
+ enum {
+ IOMUX_SEL_UART2_SHIFT = 0,
+ IOMUX_SEL_UART2_MASK = 3 << IOMUX_SEL_UART2_SHIFT,
+ IOMUX_SEL_UART2_M0 = 0,
+ IOMUX_SEL_UART2_M1,
+ };
+
+ /* uart_sel_clk default select 24MHz */
+ writel((3 << (8 + 16)) | (2 << 8), CRU_BASE + 0x148);
+
+ /* init uart baud rate 1500000 */
+ writel(0x83, &uart->lcr);
+ writel(0x1, &uart->rbr);
+ writel(0x3, &uart->lcr);
+
+ /* Enable early UART2 */
+ rk_clrsetreg(&grf->com_iomux,
+ IOMUX_SEL_UART2_MASK,
+ IOMUX_SEL_UART2_M1 << IOMUX_SEL_UART2_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A0_SEL_MASK,
+ GPIO2A0_UART2_TX_M1 << GPIO2A0_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A1_SEL_MASK,
+ GPIO2A1_UART2_RX_M1 << GPIO2A1_SEL_SHIFT);
+
+ /* enable FIFO */
+ writel(0x1, &uart->sfe);
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c b/roms/u-boot/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
new file mode 100644
index 000000000..daf74a0e2
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3328/syscon_rk3328.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <asm/arch-rockchip/clock.h>
+#include <dm.h>
+#include <syscon.h>
+
+static const struct udevice_id rk3328_syscon_ids[] = {
+ { .compatible = "rockchip,rk3328-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(rockchip_rk3328_grf) = {
+ .name = "rockchip_rk3328_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3328_syscon_ids,
+};
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3368/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3368/Kconfig
new file mode 100644
index 000000000..78eb96df3
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3368/Kconfig
@@ -0,0 +1,80 @@
+if ROCKCHIP_RK3368
+
+choice
+ prompt "RK3368 board"
+
+config TARGET_LION_RK3368
+ bool "Theobroma Systems RK3368-uQ7 (Lion) module"
+ help
+ The RK3368-uQ7 is a micro-Qseven form-factor (40mm x 70mm,
+ MXM-230 connector) system-on-module designed by Theobroma
+ Systems for industrial applications.
+
+ It provides the following features:
+ - 8x Cortex-A53 (in 2 clusters of 4 cores each)
+ - (on-module) up to 4GB of DDR3 memory
+ - (on-module) SPI-NOR flash
+ - (on-module) eMMC
+ - Gigabit Ethernet (with an on-module KSZ9031 PHY)
+ - USB
+ - HDMI
+ - MIPI-DSI/single-channel LVDS (muxed on the 'LVDS-A' pin-group)
+ - various 'slow' interfaces (e.g. UART, SPI, I2C, I2S, ...)
+ - on-module STM32 providing CAN, RTC and fan-control
+ - (optional on-module) EAL4+-certified security module
+
+config TARGET_SHEEP
+ bool "Sheep board"
+ help
+ Sheep board is designed by Rockchip as a EVB board
+ for rk3368.
+
+config TARGET_GEEKBOX
+ bool "GeekBox"
+
+config TARGET_EVB_PX5
+ bool "Evb-PX5"
+ help
+ PX5 EVB is designed by Rockchip for automotive field
+ with integrated CVBS (TP2825) / MIPI DSI / CSI / LVDS
+ HDMI video input/output interface, audio codec ES8396,
+ WIFI/BT (on RTL8723BS), Gsensor BMA250E and light&proximity
+ sensor STK3410.
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff738200
+
+config SYS_SOC
+ default "rk3368"
+
+config SYS_MALLOC_F_LEN
+ default 0x4000
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+source "board/theobroma-systems/lion_rk3368/Kconfig"
+source "board/rockchip/sheep_rk3368/Kconfig"
+source "board/geekbuying/geekbox/Kconfig"
+source "board/rockchip/evb_px5/Kconfig"
+
+config SPL_LDSCRIPT
+ default "arch/arm/cpu/armv8/u-boot-spl.lds"
+
+config SPL_STACK_R_ADDR
+ default 0x04000000
+
+config TPL_MAX_SIZE
+ default 28672
+
+config TPL_STACK
+ default 0xff8cffff
+
+config TPL_TEXT_BASE
+ default 0xff8c1000
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3368/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3368/Makefile
new file mode 100644
index 000000000..3bddc104a
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3368/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2016 Andreas Färber
+obj-y += clk_rk3368.o
+obj-y += rk3368.o
+obj-y += syscon_rk3368.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3368/clk_rk3368.c b/roms/u-boot/arch/arm/mach-rockchip/rk3368/clk_rk3368.c
new file mode 100644
index 000000000..b07531972
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3368/clk_rk3368.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3368.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3368_cru), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3368_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/roms/u-boot/arch/arm/mach-rockchip/rk3368/rk3368.c b/roms/u-boot/arch/arm/mach-rockchip/rk3368/rk3368.c
new file mode 100644
index 000000000..9b7132d47
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3368/rk3368.c
@@ -0,0 +1,241 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ * Copyright (c) 2016 Andreas Färber
+ */
+
+#include <common.h>
+#include <init.h>
+#include <syscon.h>
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rk3368.h>
+#include <asm/arch-rockchip/grf_rk3368.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define IMEM_BASE 0xFF8C0000
+
+/* Max MCU's SRAM value is 8K, begin at (IMEM_BASE + 4K) */
+#define MCU_SRAM_BASE (IMEM_BASE + 1024 * 4)
+#define MCU_SRAM_BASE_BIT31_BIT28 ((MCU_SRAM_BASE & GENMASK(31, 28)) >> 28)
+#define MCU_SRAM_BASE_BIT27_BIT12 ((MCU_SRAM_BASE & GENMASK(27, 12)) >> 12)
+/* exsram may using by mcu to accessing dram(0x0-0x20000000) */
+#define MCU_EXSRAM_BASE (0)
+#define MCU_EXSRAM_BASE_BIT31_BIT28 ((MCU_EXSRAM_BASE & GENMASK(31, 28)) >> 28)
+#define MCU_EXSRAM_BASE_BIT27_BIT12 ((MCU_EXSRAM_BASE & GENMASK(27, 12)) >> 12)
+/* experi no used, reserved value = 0 */
+#define MCU_EXPERI_BASE (0)
+#define MCU_EXPERI_BASE_BIT31_BIT28 ((MCU_EXPERI_BASE & GENMASK(31, 28)) >> 28)
+#define MCU_EXPERI_BASE_BIT27_BIT12 ((MCU_EXPERI_BASE & GENMASK(27, 12)) >> 12)
+
+static struct mm_region rk3368_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xf0000000UL,
+ .phys = 0xf0000000UL,
+ .size = 0x10000000UL,
+ .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 = rk3368_mem_map;
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/dwmmc@ff0f0000",
+ [BROM_BOOTSOURCE_SD] = "/dwmmc@ff0c0000",
+};
+
+#ifdef CONFIG_ARCH_EARLY_INIT_R
+static int mcu_init(void)
+{
+ struct rk3368_grf *grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ struct rk3368_cru *cru = rockchip_get_cru();
+
+ rk_clrsetreg(&grf->soc_con14, MCU_SRAM_BASE_BIT31_BIT28_MASK,
+ MCU_SRAM_BASE_BIT31_BIT28 << MCU_SRAM_BASE_BIT31_BIT28_SHIFT);
+ rk_clrsetreg(&grf->soc_con11, MCU_SRAM_BASE_BIT27_BIT12_MASK,
+ MCU_SRAM_BASE_BIT27_BIT12 << MCU_SRAM_BASE_BIT27_BIT12_SHIFT);
+ rk_clrsetreg(&grf->soc_con14, MCU_EXSRAM_BASE_BIT31_BIT28_MASK,
+ MCU_EXSRAM_BASE_BIT31_BIT28 << MCU_EXSRAM_BASE_BIT31_BIT28_SHIFT);
+ rk_clrsetreg(&grf->soc_con12, MCU_EXSRAM_BASE_BIT27_BIT12_MASK,
+ MCU_EXSRAM_BASE_BIT27_BIT12 << MCU_EXSRAM_BASE_BIT27_BIT12_SHIFT);
+ rk_clrsetreg(&grf->soc_con14, MCU_EXPERI_BASE_BIT31_BIT28_MASK,
+ MCU_EXPERI_BASE_BIT31_BIT28 << MCU_EXPERI_BASE_BIT31_BIT28_SHIFT);
+ rk_clrsetreg(&grf->soc_con13, MCU_EXPERI_BASE_BIT27_BIT12_MASK,
+ MCU_EXPERI_BASE_BIT27_BIT12 << MCU_EXPERI_BASE_BIT27_BIT12_SHIFT);
+
+ rk_clrsetreg(&cru->clksel_con[12], MCU_PLL_SEL_MASK | MCU_CLK_DIV_MASK,
+ (MCU_PLL_SEL_GPLL << MCU_PLL_SEL_SHIFT) |
+ (5 << MCU_CLK_DIV_SHIFT));
+
+ /* mcu dereset, for start running */
+ rk_clrreg(&cru->softrst_con[1], MCU_PO_SRST_MASK | MCU_SYS_SRST_MASK);
+
+ return 0;
+}
+
+int arch_early_init_r(void)
+{
+ return mcu_init();
+}
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+/*
+ * The SPL (and also the full U-Boot stage on the RK3368) will run in
+ * secure mode (i.e. EL3) and an ATF will eventually be booted before
+ * starting up the operating system... so we can initialize the SGRF
+ * here and rely on the ATF installing the final (secure) policy
+ * later.
+ */
+static inline uintptr_t sgrf_soc_con_addr(unsigned int no)
+{
+ const uintptr_t SGRF_BASE =
+ (uintptr_t)syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
+
+ return SGRF_BASE + sizeof(u32) * no;
+}
+
+static inline uintptr_t sgrf_busdmac_addr(unsigned int no)
+{
+ const uintptr_t SGRF_BASE =
+ (uintptr_t)syscon_get_first_range(ROCKCHIP_SYSCON_SGRF);
+ const uintptr_t SGRF_BUSDMAC_OFFSET = 0x100;
+ const uintptr_t SGRF_BUSDMAC_BASE = SGRF_BASE + SGRF_BUSDMAC_OFFSET;
+
+ return SGRF_BUSDMAC_BASE + sizeof(u32) * no;
+}
+
+static void sgrf_init(void)
+{
+ struct rk3368_cru * const cru =
+ (struct rk3368_cru * const)rockchip_get_cru();
+ const u16 SGRF_SOC_CON_SEC = GENMASK(15, 0);
+ const u16 SGRF_BUSDMAC_CON0_SEC = BIT(2);
+ const u16 SGRF_BUSDMAC_CON1_SEC = GENMASK(15, 12);
+
+ /* Set all configurable IP to 'non secure'-mode */
+ rk_setreg(sgrf_soc_con_addr(5), SGRF_SOC_CON_SEC);
+ rk_setreg(sgrf_soc_con_addr(6), SGRF_SOC_CON_SEC);
+ rk_setreg(sgrf_soc_con_addr(7), SGRF_SOC_CON_SEC);
+
+ /*
+ * From rockchip-uboot/arch/arm/cpu/armv8/rk33xx/cpu.c
+ * Original comment: "ddr space set no secure mode"
+ */
+ rk_clrreg(sgrf_soc_con_addr(8), SGRF_SOC_CON_SEC);
+ rk_clrreg(sgrf_soc_con_addr(9), SGRF_SOC_CON_SEC);
+ rk_clrreg(sgrf_soc_con_addr(10), SGRF_SOC_CON_SEC);
+
+ /* Set 'secure dma' to 'non secure'-mode */
+ rk_setreg(sgrf_busdmac_addr(0), SGRF_BUSDMAC_CON0_SEC);
+ rk_setreg(sgrf_busdmac_addr(1), SGRF_BUSDMAC_CON1_SEC);
+
+ dsb(); /* barrier */
+
+ rk_setreg(&cru->softrst_con[1], DMA1_SRST_REQ);
+ rk_setreg(&cru->softrst_con[4], DMA2_SRST_REQ);
+
+ dsb(); /* barrier */
+ udelay(10);
+
+ rk_clrreg(&cru->softrst_con[1], DMA1_SRST_REQ);
+ rk_clrreg(&cru->softrst_con[4], DMA2_SRST_REQ);
+}
+
+int arch_cpu_init(void)
+{
+ /* Reset security, so we can use DMA in the MMC drivers */
+ sgrf_init();
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+ /*
+ * N.B.: This is called before the device-model has been
+ * initialised. For this reason, we can not access
+ * the GRF address range using the syscon API.
+ */
+#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff180000)
+ struct rk3368_grf * const grf =
+ (struct rk3368_grf * const)0xff770000;
+
+ enum {
+ GPIO2D1_MASK = GENMASK(3, 2),
+ GPIO2D1_GPIO = 0,
+ GPIO2D1_UART0_SOUT = (1 << 2),
+
+ GPIO2D0_MASK = GENMASK(1, 0),
+ GPIO2D0_GPIO = 0,
+ GPIO2D0_UART0_SIN = (1 << 0),
+ };
+
+ /* Enable early UART0 on the RK3368 */
+ rk_clrsetreg(&grf->gpio2d_iomux,
+ GPIO2D0_MASK, GPIO2D0_UART0_SIN);
+ rk_clrsetreg(&grf->gpio2d_iomux,
+ GPIO2D1_MASK, GPIO2D1_UART0_SOUT);
+#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff1c0000)
+ struct rk3368_pmu_grf * const pmugrf __maybe_unused =
+ (struct rk3368_pmu_grf * const)0xff738000;
+
+ enum {
+ /* UART4 */
+ GPIO0D2_MASK = GENMASK(5, 4),
+ GPIO0D2_GPIO = 0,
+ GPIO0D2_UART4_SOUT = (3 << 4),
+
+ GPIO0D3_MASK = GENMASK(7, 6),
+ GPIO0D3_GPIO = 0,
+ GPIO0D3_UART4_SIN = (3 << 6),
+ };
+
+ /* Enable early UART4 on the PX5 */
+ rk_clrsetreg(&pmugrf->gpio0d_iomux,
+ GPIO0D2_MASK | GPIO0D3_MASK,
+ GPIO0D2_UART4_SOUT | GPIO0D3_UART4_SIN);
+#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff690000)
+ struct rk3368_grf * const grf =
+ (struct rk3368_grf * const)0xff770000;
+
+ enum {
+ GPIO2A6_SHIFT = 12,
+ GPIO2A6_MASK = GENMASK(13, 12),
+ GPIO2A6_GPIO = 0,
+ GPIO2A6_UART2_SIN = (2 << GPIO2A6_SHIFT),
+
+ GPIO2A5_SHIFT = 10,
+ GPIO2A5_MASK = GENMASK(11, 10),
+ GPIO2A5_GPIO = 0,
+ GPIO2A5_UART2_SOUT = (2 << GPIO2A5_SHIFT),
+ };
+
+ /* Enable early UART2 on the RK3368 */
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A6_MASK, GPIO2A6_UART2_SIN);
+ rk_clrsetreg(&grf->gpio2a_iomux,
+ GPIO2A5_MASK, GPIO2A5_UART2_SOUT);
+#endif
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c b/roms/u-boot/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c
new file mode 100644
index 000000000..dc2d831dd
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3368/syscon_rk3368.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3368_syscon_ids[] = {
+ { .compatible = "rockchip,rk3368-grf",
+ .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3368-pmugrf",
+ .data = ROCKCHIP_SYSCON_PMUGRF },
+ { .compatible = "rockchip,rk3368-msch",
+ .data = ROCKCHIP_SYSCON_MSCH },
+ { .compatible = "rockchip,rk3368-sgrf",
+ .data = ROCKCHIP_SYSCON_SGRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3368) = {
+ .name = "rk3368_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3368_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3368_syscon_bind_of_plat(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3368_grf) = {
+ .name = "rockchip_rk3368_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3368_syscon_ids,
+ .bind = rk3368_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3368_pmugrf) = {
+ .name = "rockchip_rk3368_pmugrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3368_syscon_ids + 1,
+ .bind = rk3368_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3368_msch) = {
+ .name = "rockchip_rk3368_msch",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3368_syscon_ids + 2,
+ .bind = rk3368_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3368_sgrf) = {
+ .name = "rockchip_rk3368_sgrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3368_syscon_ids + 3,
+ .bind = rk3368_syscon_bind_of_plat,
+};
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3399/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rk3399/Kconfig
new file mode 100644
index 000000000..17628f917
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3399/Kconfig
@@ -0,0 +1,162 @@
+if ROCKCHIP_RK3399
+
+choice
+ prompt "RK3399 board select"
+
+config TARGET_CHROMEBOOK_BOB
+ bool "Asus Flip C101PA Chromebook (RK3399)"
+ select HAS_ROM
+ select ROCKCHIP_SPI_IMAGE
+ help
+ Bob is a small RK3299-based device similar in apperance to Minnie.
+ It has two USB 3.0 type-C ports, 4GB of SDRAM, WiFi and a 10.1",
+ 1280x800 display. It uses its USB ports for both power and external
+ display. It includes a Chrome OS EC (Cortex-M3) to provide access to
+ the keyboard and battery functions.
+
+config TARGET_EVB_RK3399
+ bool "RK3399 evaluation board"
+ help
+ RK3399evb is a evaluation board for Rockchip RK3399,
+ with full function and physical connectors support like Type-C ports,
+ USB.0 host ports, LVDS, JTAG, MAC, SD card, HDMI, USB-to-serial...
+
+config TARGET_PINEBOOK_PRO_RK3399
+ bool "Pinebook Pro"
+ help
+ Pinebook Pro is a laptop based on the Rockchip rk3399 SoC
+ with 4Gb RAM, onboard eMMC, USB-C, a USB3 and USB2 port,
+ 1920*1080 screen and all the usual laptop features.
+
+config TARGET_PUMA_RK3399
+ bool "Theobroma Systems RK3399-Q7 (Puma)"
+ help
+ The RK3399-Q7 (Puma) is a system-on-module (designed and
+ marketed by Theobroma Systems) featuring the Rockchip RK3399
+ in a Qseven-compatible form-factor (running of a single 5V
+ supply and exposing its external interfaces on a MXM-230
+ connector).
+
+ Key features of the RK3399-Q7 include:
+ * on-module USB 3.0 hub (2x USB 3.0 host + 1x USB 2.0 host)
+ * USB 3.0 dual-role
+ * on-module Micrel KSZ9031 GbE PHY
+ * on-module eMMC (up to 256GB configurations available)
+ * on-module DDR3 (1GB, 2GB and 4GB configurations available)
+ * HDMI, eDP, MIPI-DSI, MIPI-DSI/CSI and MIPI-CSI
+ * SPI, I2C, I2S, UART, GPIO, ...
+
+config TARGET_ROCK960_RK3399
+ bool "Vamrs Limited Rock960 board family"
+ help
+ Support for Rock960 board family by Vamrs Limited. This board
+ family consists of Rock960 (Consumer Edition) and Ficus
+ (Enterprise Edition) 96Boards.
+
+ Common features implemented on both boards:
+ * Rockchip RK3399 SoC (2xCortex A72, 4xCortex A53, ARM Mali T860MP4)
+ * 16/32GB eMMC, uSD slot
+ * HDMI/DP/MIPI
+ * 20-pin low speed and 40-pin high speed expanders, 6 LED, 3 buttons
+
+ Additional features of Rock960:
+ * 2GiB/4GiB LPDDR3 RAM
+ * 1x USB 3.0 type A, 1x USB 2.0 type A (host mode only),
+ 1x USB 3.0 type C OTG
+
+ Additional features of Ficus:
+ * 2GiB/4GiB DDR3 RAM
+ * Ethernet
+ * Dual SATA
+ * 2x USB 3.0 type A, 2x USB 2.0 type A (host mode only),
+ 1x USB 3.0 type C OTG
+
+config TARGET_ROCKPRO64_RK3399
+ bool "Pine64 Rockpro64 board"
+ help
+ Rockro64 is SBC produced by Pine64. Key features:
+
+ * Rockchip RK3399
+ * 2/4GB Dual-Channel LPDDR3
+ * SD card slot
+ * eMMC socket
+ * 128Mb SPI Flash
+ * Gigabit ethernet
+ * PCIe 4X slot
+ * WiFI/BT module socket
+ * HDMI In/Out, DP, MIPI DSI/CSI, eDP
+ * USB 3.0, 2.0
+ * USB Type C power and data
+ * GPIO expansion ports
+ * DC 12V/2A
+
+config TARGET_ROC_PC_RK3399
+ bool "Firefly ROC-RK3399-PC board"
+ help
+ ROC-RK3399-PC is SBC produced by Firefly. Key features:
+
+ * Rockchip RK3399
+ * 4GB Dual-Channel LPDDR4 64-bit
+ * SD card slot
+ * eMMC socket
+ * 16MB SPI Flash
+ * Gigabit ethernet
+ * PCIe
+ * HDMI In/Out, DP, MIPI DSI/CSI, eDP
+ * USB 3.0, 2.0
+ * USB Type C power and data
+ * GPIO expansion ports
+ * wide voltage input(5V-15V), dual cell battery
+ * Wifi/BT accessible via expansion board M.2
+
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0xff320300
+
+config SYS_SOC
+ default "rk3399"
+
+config SYS_MALLOC_F_LEN
+ default 0x4000
+
+config SPL_LIBCOMMON_SUPPORT
+ default y
+
+config SPL_LIBGENERIC_SUPPORT
+ default y
+
+config TPL_LDSCRIPT
+ default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
+
+config TPL_MAX_SIZE
+ default 188416
+
+config TPL_STACK
+ default 0xff8effff
+
+config TPL_TEXT_BASE
+ default 0xff8c2000
+
+config SPL_STACK_R_ADDR
+ default 0x04000000
+
+if BOOTCOUNT_LIMIT
+
+config BOOTCOUNT_BOOTLIMIT
+ default 3
+
+config SYS_BOOTCOUNT_ADDR
+ default 0xff3100f0 # PMU_SYS_REG0
+
+endif # BOOTCOUNT_LIMIT
+
+source "board/firefly/roc-pc-rk3399/Kconfig"
+source "board/google/gru/Kconfig"
+source "board/pine64/pinebook-pro-rk3399/Kconfig"
+source "board/pine64/rockpro64_rk3399/Kconfig"
+source "board/rockchip/evb_rk3399/Kconfig"
+source "board/theobroma-systems/puma_rk3399/Kconfig"
+source "board/vamrs/rock960_rk3399/Kconfig"
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3399/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rk3399/Makefile
new file mode 100644
index 000000000..98ebeac34
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3399/Makefile
@@ -0,0 +1,9 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clk_rk3399.o
+obj-y += rk3399.o
+obj-y += syscon_rk3399.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3399/clk_rk3399.c b/roms/u-boot/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
new file mode 100644
index 000000000..9d9a837fc
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3399/clk_rk3399.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru.h>
+#include <linux/err.h>
+
+static int rockchip_get_cruclk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(clk_rk3399), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rk3399_clk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_cruclk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->cru;
+}
+
+static int rockchip_get_pmucruclk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(rockchip_rk3399_pmuclk), devp);
+}
+
+void *rockchip_get_pmucru(void)
+{
+ struct rk3399_pmuclk_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ ret = rockchip_get_pmucruclk(&dev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ priv = dev_get_priv(dev);
+
+ return priv->pmucru;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3399/rk3399.c b/roms/u-boot/arch/arm/mach-rockchip/rk3399/rk3399.c
new file mode 100644
index 000000000..869d2159b
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3399/rk3399.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <fdt_support.h>
+#include <init.h>
+#include <log.h>
+#include <spl.h>
+#include <spl_gpio.h>
+#include <syscon.h>
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/gpio.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <linux/bitops.h>
+#include <power/regulator.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define GRF_EMMCCORE_CON11 0xff77f02c
+#define GRF_BASE 0xff770000
+
+const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+ [BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
+ [BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000",
+ [BROM_BOOTSOURCE_SD] = "/mmc@fe320000",
+};
+
+static struct mm_region rk3399_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0xf8000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xf8000000UL,
+ .phys = 0xf8000000UL,
+ .size = 0x08000000UL,
+ .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 = rk3399_mem_map;
+
+#ifdef CONFIG_SPL_BUILD
+
+#define TIMER_END_COUNT_L 0x00
+#define TIMER_END_COUNT_H 0x04
+#define TIMER_INIT_COUNT_L 0x10
+#define TIMER_INIT_COUNT_H 0x14
+#define TIMER_CONTROL_REG 0x1c
+
+#define TIMER_EN 0x1
+#define TIMER_FMODE BIT(0)
+#define TIMER_RMODE BIT(1)
+
+void rockchip_stimer_init(void)
+{
+ /* If Timer already enabled, don't re-init it */
+ u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+ if (reg & TIMER_EN)
+ return;
+
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_END_COUNT_L);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_END_COUNT_H);
+ writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_INIT_COUNT_L);
+ writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_INIT_COUNT_H);
+ writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE + \
+ TIMER_CONTROL_REG);
+}
+#endif
+
+int arch_cpu_init(void)
+{
+
+#ifdef CONFIG_SPL_BUILD
+ struct rk3399_pmusgrf_regs *sgrf;
+ struct rk3399_grf_regs *grf;
+
+ /*
+ * Disable DDR and SRAM security regions.
+ *
+ * As we are entered from the BootROM, the region from
+ * 0x0 through 0xfffff (i.e. the first MB of memory) will
+ * be protected. This will cause issues with the DW_MMC
+ * driver, which tries to DMA from/to the stack (likely)
+ * located in this range.
+ */
+ sgrf = syscon_get_first_range(ROCKCHIP_SYSCON_PMUSGRF);
+ rk_clrsetreg(&sgrf->ddr_rgn_con[16], 0x1ff, 0);
+ rk_clrreg(&sgrf->slv_secure_con4, 0x2000);
+
+ /* eMMC clock generator: disable the clock multipilier */
+ grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+ rk_clrreg(&grf->emmccore_con[11], 0x0ff);
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_UART_BOARD_INIT
+void board_debug_uart_init(void)
+{
+#define GRF_BASE 0xff770000
+#define GPIO0_BASE 0xff720000
+#define PMUGRF_BASE 0xff320000
+ struct rk3399_grf_regs * const grf = (void *)GRF_BASE;
+#ifdef CONFIG_TARGET_CHROMEBOOK_BOB
+ struct rk3399_pmugrf_regs * const pmugrf = (void *)PMUGRF_BASE;
+ struct rockchip_gpio_regs * const gpio = (void *)GPIO0_BASE;
+#endif
+
+#if defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff180000)
+ /* Enable early UART0 on the RK3399 */
+ rk_clrsetreg(&grf->gpio2c_iomux,
+ GRF_GPIO2C0_SEL_MASK,
+ GRF_UART0BT_SIN << GRF_GPIO2C0_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio2c_iomux,
+ GRF_GPIO2C1_SEL_MASK,
+ GRF_UART0BT_SOUT << GRF_GPIO2C1_SEL_SHIFT);
+#elif defined(CONFIG_DEBUG_UART_BASE) && (CONFIG_DEBUG_UART_BASE == 0xff1B0000)
+ /* Enable early UART3 on the RK3399 */
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GRF_GPIO3B6_SEL_MASK,
+ GRF_UART3_SIN << GRF_GPIO3B6_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio3b_iomux,
+ GRF_GPIO3B7_SEL_MASK,
+ GRF_UART3_SOUT << GRF_GPIO3B7_SEL_SHIFT);
+#else
+# ifdef CONFIG_TARGET_CHROMEBOOK_BOB
+ rk_setreg(&grf->io_vsel, 1 << 0);
+
+ /*
+ * Let's enable these power rails here, we are already running the SPI
+ * Flash based code.
+ */
+ spl_gpio_output(gpio, GPIO(BANK_B, 2), 1); /* PP1500_EN */
+ spl_gpio_set_pull(&pmugrf->gpio0_p, GPIO(BANK_B, 2), GPIO_PULL_NORMAL);
+
+ spl_gpio_output(gpio, GPIO(BANK_B, 4), 1); /* PP3000_EN */
+ spl_gpio_set_pull(&pmugrf->gpio0_p, GPIO(BANK_B, 4), GPIO_PULL_NORMAL);
+#endif /* CONFIG_TARGET_CHROMEBOOK_BOB */
+
+ /* Enable early UART2 channel C on the RK3399 */
+ rk_clrsetreg(&grf->gpio4c_iomux,
+ GRF_GPIO4C3_SEL_MASK,
+ GRF_UART2DGBC_SIN << GRF_GPIO4C3_SEL_SHIFT);
+ rk_clrsetreg(&grf->gpio4c_iomux,
+ GRF_GPIO4C4_SEL_MASK,
+ GRF_UART2DBGC_SOUT << GRF_GPIO4C4_SEL_SHIFT);
+ /* Set channel C as UART2 input */
+ rk_clrsetreg(&grf->soc_con7,
+ GRF_UART_DBG_SEL_MASK,
+ GRF_UART_DBG_SEL_C << GRF_UART_DBG_SEL_SHIFT);
+#endif
+}
+#endif
+
+#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
+const char *spl_decode_boot_device(u32 boot_device)
+{
+ int i;
+ static const struct {
+ u32 boot_device;
+ const char *ofpath;
+ } spl_boot_devices_tbl[] = {
+ { BOOT_DEVICE_MMC1, "/mmc@fe320000" },
+ { BOOT_DEVICE_MMC2, "/sdhci@fe330000" },
+ { BOOT_DEVICE_SPI, "/spi@ff1d0000" },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(spl_boot_devices_tbl); ++i)
+ if (spl_boot_devices_tbl[i].boot_device == boot_device)
+ return spl_boot_devices_tbl[i].ofpath;
+
+ return NULL;
+}
+
+void spl_perform_fixups(struct spl_image_info *spl_image)
+{
+ void *blob = spl_image->fdt_addr;
+ const char *boot_ofpath;
+ int chosen;
+
+ /*
+ * Inject the ofpath of the device the full U-Boot (or Linux in
+ * Falcon-mode) was booted from into the FDT, if a FDT has been
+ * loaded at the same time.
+ */
+ if (!blob)
+ return;
+
+ boot_ofpath = spl_decode_boot_device(spl_image->boot_device);
+ if (!boot_ofpath) {
+ pr_err("%s: could not map boot_device to ofpath\n", __func__);
+ return;
+ }
+
+ chosen = fdt_find_or_add_subnode(blob, 0, "chosen");
+ if (chosen < 0) {
+ pr_err("%s: could not find/create '/chosen'\n", __func__);
+ return;
+ }
+ fdt_setprop_string(blob, chosen,
+ "u-boot,spl-boot-device", boot_ofpath);
+}
+
+#if defined(SPL_GPIO_SUPPORT)
+static void rk3399_force_power_on_reset(void)
+{
+ ofnode node;
+ struct gpio_desc sysreset_gpio;
+
+ debug("%s: trying to force a power-on reset\n", __func__);
+
+ node = ofnode_path("/config");
+ if (!ofnode_valid(node)) {
+ debug("%s: no /config node?\n", __func__);
+ return;
+ }
+
+ if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0,
+ &sysreset_gpio, GPIOD_IS_OUT)) {
+ debug("%s: could not find a /config/sysreset-gpio\n", __func__);
+ return;
+ }
+
+ dm_gpio_set_value(&sysreset_gpio, 1);
+}
+#endif
+
+void __weak led_setup(void)
+{
+}
+
+void spl_board_init(void)
+{
+ led_setup();
+
+#if defined(SPL_GPIO_SUPPORT)
+ struct rockchip_cru *cru = rockchip_get_cru();
+
+ /*
+ * The RK3399 resets only 'almost all logic' (see also in the TRM
+ * "3.9.4 Global software reset"), when issuing a software reset.
+ * This may cause issues during boot-up for some configurations of
+ * the application software stack.
+ *
+ * To work around this, we test whether the last reset reason was
+ * a power-on reset and (if not) issue an overtemp-reset to reset
+ * the entire module.
+ *
+ * While this was previously fixed by modifying the various places
+ * that could generate a software reset (e.g. U-Boot's sysreset
+ * driver, the ATF or Linux), we now have it here to ensure that
+ * we no longer have to track this through the various components.
+ */
+ if (cru->glb_rst_st != 0)
+ rk3399_force_power_on_reset();
+#endif
+
+#if defined(SPL_DM_REGULATOR)
+ /*
+ * Turning the eMMC and SPI back on (if disabled via the Qseven
+ * BIOS_ENABLE) signal is done through a always-on regulator).
+ */
+ if (regulators_enable_boot_on(false))
+ debug("%s: Cannot enable boot on regulator\n", __func__);
+#endif
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/roms/u-boot/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
new file mode 100644
index 000000000..b360ca7dd
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rk3399_syscon_ids[] = {
+ { .compatible = "rockchip,rk3399-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
+ { .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
+ { .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
+ { .compatible = "rockchip,rk3399-pmu", .data = ROCKCHIP_SYSCON_PMU },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rk3399) = {
+ .name = "rk3399_syscon",
+ .id = UCLASS_SYSCON,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+ .bind = dm_scan_fdt_dev,
+#endif
+ .of_match = rk3399_syscon_ids,
+};
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+static int rk3399_syscon_bind_of_plat(struct udevice *dev)
+{
+ dev->driver_data = dev->driver->of_match->data;
+ debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(rockchip_rk3399_grf) = {
+ .name = "rockchip_rk3399_grf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids,
+ .bind = rk3399_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmugrf) = {
+ .name = "rockchip_rk3399_pmugrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 1,
+ .bind = rk3399_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmusgrf) = {
+ .name = "rockchip_rk3399_pmusgrf",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 2,
+ .bind = rk3399_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_cic) = {
+ .name = "rockchip_rk3399_cic",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 3,
+ .bind = rk3399_syscon_bind_of_plat,
+};
+
+U_BOOT_DRIVER(rockchip_rk3399_pmu) = {
+ .name = "rockchip_rk3399_pmu",
+ .id = UCLASS_SYSCON,
+ .of_match = rk3399_syscon_ids + 4,
+ .bind = rk3399_syscon_bind_of_plat,
+};
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rv1108/Kconfig b/roms/u-boot/arch/arm/mach-rockchip/rv1108/Kconfig
new file mode 100644
index 000000000..a12216dcc
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rv1108/Kconfig
@@ -0,0 +1,42 @@
+if ROCKCHIP_RV1108
+
+choice
+ prompt "RV1108 board select"
+
+config TARGET_EVB_RV1108
+ bool "EVB_RV1108"
+ help
+ RV1108 EVB is a evaluation board for Rockchp RV1108.
+
+ Key features of the board include:
+ * one macro USB OTG port
+ * one USB HOST port
+ * one RS232 to USB port route to UART2 as debug port
+ * MIPI screen with resolution 720 x 1280
+ * 128M DDR3
+ * 64M SPI Nor Flash
+ * macro SD card interface
+ * HDMI output
+ * 10/100 Mbps Ethernet
+ * camera interface compatible with imx323 / ov2710 / ov4689
+
+config TARGET_ELGIN_RV1108
+ bool "ELGIN_RV1108"
+ help
+ RV1108 ELGIN is a board based on the Rockchip RV1108.
+
+endchoice
+
+config ROCKCHIP_BOOT_MODE_REG
+ default 0x10300580
+
+config SYS_SOC
+ default "rv1108"
+
+config SYS_MALLOC_F_LEN
+ default 0x400
+
+source board/rockchip/evb_rv1108/Kconfig
+source board/elgin/elgin_rv1108/Kconfig
+
+endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rv1108/Makefile b/roms/u-boot/arch/arm/mach-rockchip/rv1108/Makefile
new file mode 100644
index 000000000..9035a1a89
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rv1108/Makefile
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2016 Rockchip Electronics Co., Ltd
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+ifndef CONFIG_SPL_BUILD
+obj-y += syscon_rv1108.o
+endif
+obj-y += rv1108.o
+obj-y += clk_rv1108.o
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rv1108/clk_rv1108.c b/roms/u-boot/arch/arm/mach-rockchip/rv1108/clk_rv1108.c
new file mode 100644
index 000000000..44b53c407
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rv1108/clk_rv1108.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/cru_rv1108.h>
+#include <linux/err.h>
+
+int rockchip_get_clk(struct udevice **devp)
+{
+ return uclass_get_device_by_driver(UCLASS_CLK,
+ DM_DRIVER_GET(clk_rv1108), devp);
+}
+
+void *rockchip_get_cru(void)
+{
+ struct rv1108_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/roms/u-boot/arch/arm/mach-rockchip/rv1108/rv1108.c b/roms/u-boot/arch/arm/mach-rockchip/rv1108/rv1108.c
new file mode 100644
index 000000000..6362af995
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rv1108/rv1108.c
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * Author: Andy Yan <andy.yan@rock-chips.com>
+ */
diff --git a/roms/u-boot/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c b/roms/u-boot/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c
new file mode 100644
index 000000000..babdf5720
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/rv1108/syscon_rv1108.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/arch-rockchip/clock.h>
+
+static const struct udevice_id rv1108_syscon_ids[] = {
+ { .compatible = "rockchip,rv1108-grf", .data = ROCKCHIP_SYSCON_GRF },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_rv1108) = {
+ .name = "rv1108_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = rv1108_syscon_ids,
+};
diff --git a/roms/u-boot/arch/arm/mach-rockchip/sdram.c b/roms/u-boot/arch/arm/mach-rockchip/sdram.c
new file mode 100644
index 000000000..28c379ef0
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/sdram.c
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <init.h>
+#include <log.h>
+#include <ram.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/sdram.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TRUST_PARAMETER_OFFSET (34 * 1024 * 1024)
+
+struct tos_parameter_t {
+ u32 version;
+ u32 checksum;
+ struct {
+ char name[8];
+ s64 phy_addr;
+ u32 size;
+ u32 flags;
+ } tee_mem;
+ struct {
+ char name[8];
+ s64 phy_addr;
+ u32 size;
+ u32 flags;
+ } drm_mem;
+ s64 reserve[8];
+};
+
+int dram_init_banksize(void)
+{
+ size_t top = min((unsigned long)(gd->ram_size + CONFIG_SYS_SDRAM_BASE),
+ (unsigned long)(gd->ram_top));
+
+#ifdef CONFIG_ARM64
+ /* Reserve 0x200000 for ATF bl31 */
+ gd->bd->bi_dram[0].start = 0x200000;
+ gd->bd->bi_dram[0].size = top - gd->bd->bi_dram[0].start;
+#else
+#ifdef CONFIG_SPL_OPTEE
+ struct tos_parameter_t *tos_parameter;
+
+ tos_parameter = (struct tos_parameter_t *)(CONFIG_SYS_SDRAM_BASE +
+ TRUST_PARAMETER_OFFSET);
+
+ if (tos_parameter->tee_mem.flags == 1) {
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = tos_parameter->tee_mem.phy_addr
+ - CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[1].start = tos_parameter->tee_mem.phy_addr +
+ tos_parameter->tee_mem.size;
+ gd->bd->bi_dram[1].size = top - gd->bd->bi_dram[1].start;
+ } else {
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = 0x8400000;
+ /* Reserve 32M for OPTEE with TA */
+ gd->bd->bi_dram[1].start = CONFIG_SYS_SDRAM_BASE
+ + gd->bd->bi_dram[0].size + 0x2000000;
+ gd->bd->bi_dram[1].size = top - gd->bd->bi_dram[1].start;
+ }
+#else
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ gd->bd->bi_dram[0].size = top - gd->bd->bi_dram[0].start;
+#endif
+#endif
+
+ return 0;
+}
+
+size_t rockchip_sdram_size(phys_addr_t reg)
+{
+ u32 rank, cs0_col, bk, cs0_row, cs1_row, bw, row_3_4;
+ size_t chipsize_mb = 0;
+ size_t size_mb = 0;
+ u32 ch;
+ u32 cs1_col = 0;
+ u32 bg = 0;
+ u32 dbw, dram_type;
+ u32 sys_reg2 = readl(reg);
+ u32 sys_reg3 = readl(reg + 4);
+ u32 ch_num = 1 + ((sys_reg2 >> SYS_REG_NUM_CH_SHIFT)
+ & SYS_REG_NUM_CH_MASK);
+
+ dram_type = (sys_reg2 >> SYS_REG_DDRTYPE_SHIFT) & SYS_REG_DDRTYPE_MASK;
+ debug("%s %x %x\n", __func__, (u32)reg, sys_reg2);
+ for (ch = 0; ch < ch_num; ch++) {
+ rank = 1 + (sys_reg2 >> SYS_REG_RANK_SHIFT(ch) &
+ SYS_REG_RANK_MASK);
+ cs0_col = 9 + (sys_reg2 >> SYS_REG_COL_SHIFT(ch) &
+ SYS_REG_COL_MASK);
+ cs1_col = cs0_col;
+ bk = 3 - ((sys_reg2 >> SYS_REG_BK_SHIFT(ch)) & SYS_REG_BK_MASK);
+ if ((sys_reg3 >> SYS_REG_VERSION_SHIFT &
+ SYS_REG_VERSION_MASK) == 0x2) {
+ cs1_col = 9 + (sys_reg3 >> SYS_REG_CS1_COL_SHIFT(ch) &
+ SYS_REG_CS1_COL_MASK);
+ if (((sys_reg3 >> SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) &
+ SYS_REG_EXTEND_CS0_ROW_MASK) << 2) + (sys_reg2 >>
+ SYS_REG_CS0_ROW_SHIFT(ch) &
+ SYS_REG_CS0_ROW_MASK) == 7)
+ cs0_row = 12;
+ else
+ cs0_row = 13 + (sys_reg2 >>
+ SYS_REG_CS0_ROW_SHIFT(ch) &
+ SYS_REG_CS0_ROW_MASK) +
+ ((sys_reg3 >>
+ SYS_REG_EXTEND_CS0_ROW_SHIFT(ch) &
+ SYS_REG_EXTEND_CS0_ROW_MASK) << 2);
+ if (((sys_reg3 >> SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) &
+ SYS_REG_EXTEND_CS1_ROW_MASK) << 2) + (sys_reg2 >>
+ SYS_REG_CS1_ROW_SHIFT(ch) &
+ SYS_REG_CS1_ROW_MASK) == 7)
+ cs1_row = 12;
+ else
+ cs1_row = 13 + (sys_reg2 >>
+ SYS_REG_CS1_ROW_SHIFT(ch) &
+ SYS_REG_CS1_ROW_MASK) +
+ ((sys_reg3 >>
+ SYS_REG_EXTEND_CS1_ROW_SHIFT(ch) &
+ SYS_REG_EXTEND_CS1_ROW_MASK) << 2);
+ } else {
+ cs0_row = 13 + (sys_reg2 >> SYS_REG_CS0_ROW_SHIFT(ch) &
+ SYS_REG_CS0_ROW_MASK);
+ cs1_row = 13 + (sys_reg2 >> SYS_REG_CS1_ROW_SHIFT(ch) &
+ SYS_REG_CS1_ROW_MASK);
+ }
+ bw = (2 >> ((sys_reg2 >> SYS_REG_BW_SHIFT(ch)) &
+ SYS_REG_BW_MASK));
+ row_3_4 = sys_reg2 >> SYS_REG_ROW_3_4_SHIFT(ch) &
+ SYS_REG_ROW_3_4_MASK;
+ if (dram_type == DDR4) {
+ dbw = (sys_reg2 >> SYS_REG_DBW_SHIFT(ch)) &
+ SYS_REG_DBW_MASK;
+ bg = (dbw == 2) ? 2 : 1;
+ }
+ chipsize_mb = (1 << (cs0_row + cs0_col + bk + bg + bw - 20));
+
+ if (rank > 1)
+ chipsize_mb += chipsize_mb >> ((cs0_row - cs1_row) +
+ (cs0_col - cs1_col));
+ if (row_3_4)
+ chipsize_mb = chipsize_mb * 3 / 4;
+ size_mb += chipsize_mb;
+ if (rank > 1)
+ debug("rank %d cs0_col %d cs1_col %d bk %d cs0_row %d\
+ cs1_row %d bw %d row_3_4 %d\n",
+ rank, cs0_col, cs1_col, bk, cs0_row,
+ cs1_row, bw, row_3_4);
+ else
+ debug("rank %d cs0_col %d bk %d cs0_row %d\
+ bw %d row_3_4 %d\n",
+ rank, cs0_col, bk, cs0_row,
+ bw, row_3_4);
+ }
+
+ /*
+ * This is workaround for issue we can't get correct size for 4GB ram
+ * in 32bit system and available before we really need ram space
+ * out of 4GB, eg.enable ARM LAPE(rk3288 supports 8GB ram).
+ * The size of 4GB is '0x1 00000000', and this value will be truncated
+ * to 0 in 32bit system, and system can not get correct ram size.
+ * Rockchip SoCs reserve a blob of space for peripheral near 4GB,
+ * and we are now setting SDRAM_MAX_SIZE as max available space for
+ * ram in 4GB, so we can use this directly to workaround the issue.
+ * TODO:
+ * 1. update correct value for SDRAM_MAX_SIZE as what dram
+ * controller sees.
+ * 2. update board_get_usable_ram_top() and dram_init_banksize()
+ * to reserve memory for peripheral space after previous update.
+ */
+ if (size_mb > (SDRAM_MAX_SIZE >> 20))
+ size_mb = (SDRAM_MAX_SIZE >> 20);
+
+ return (size_t)size_mb << 20;
+}
+
+int dram_init(void)
+{
+ struct ram_info ram;
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ debug("DRAM init failed: %d\n", ret);
+ return ret;
+ }
+ ret = ram_get_info(dev, &ram);
+ if (ret) {
+ debug("Cannot get DRAM size: %d\n", ret);
+ return ret;
+ }
+ gd->ram_size = ram.size;
+ debug("SDRAM base=%lx, size=%lx\n",
+ (unsigned long)ram.base, (unsigned long)ram.size);
+
+ return 0;
+}
+
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ unsigned long top = CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE;
+
+ return (gd->ram_top > top) ? top : gd->ram_top;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/spl-boot-order.c b/roms/u-boot/arch/arm/mach-rockchip/spl-boot-order.c
new file mode 100644
index 000000000..93b8e7de4
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/spl-boot-order.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <mmc.h>
+#include <spl.h>
+#include <asm/global_data.h>
+
+#if CONFIG_IS_ENABLED(OF_LIBFDT)
+/**
+ * spl_node_to_boot_device() - maps from a DT-node to a SPL boot device
+ * @node: of_offset of the node
+ *
+ * The SPL framework uses BOOT_DEVICE_... constants to identify its boot
+ * sources. These may take on a device-specific meaning, depending on
+ * what nodes are enabled in a DTS (e.g. BOOT_DEVICE_MMC1 may refer to
+ * different controllers/block-devices, depending on which SD/MMC controllers
+ * are enabled in any given DTS). This function maps from a DT-node back
+ * onto a BOOT_DEVICE_... constant, considering the currently active devices.
+ *
+ * Returns
+ * -ENOENT, if no device matching the node could be found
+ * -ENOSYS, if the device matching the node can not be mapped onto a
+ * SPL boot device (e.g. the third MMC device)
+ * -1, for unspecified failures
+ * a positive integer (from the BOOT_DEVICE_... family) on succes.
+ */
+
+static int spl_node_to_boot_device(int node)
+{
+ struct udevice *parent;
+
+ /*
+ * This should eventually move into the SPL code, once SPL becomes
+ * aware of the block-device layer. Until then (and to avoid unneeded
+ * delays in getting this feature out), it lives at the board-level.
+ */
+ if (!uclass_get_device_by_of_offset(UCLASS_MMC, node, &parent)) {
+ struct udevice *dev;
+ struct blk_desc *desc = NULL;
+
+ for (device_find_first_child(parent, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ if (device_get_uclass_id(dev) == UCLASS_BLK) {
+ desc = dev_get_uclass_plat(dev);
+ break;
+ }
+ }
+
+ if (!desc)
+ return -ENOENT;
+
+ switch (desc->devnum) {
+ case 0:
+ return BOOT_DEVICE_MMC1;
+ case 1:
+ return BOOT_DEVICE_MMC2;
+ default:
+ return -ENOSYS;
+ }
+ } else if (!uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node,
+ &parent)) {
+ return BOOT_DEVICE_SPI;
+ }
+
+ /*
+ * SPL doesn't differentiate SPI flashes, so we keep the detection
+ * brief and inaccurate... hopefully, the common SPL layer can be
+ * extended with awareness of the BLK layer (and matching OF_CONTROL)
+ * soon.
+ */
+ if (!uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node, &parent))
+ return BOOT_DEVICE_SPI;
+
+ return -1;
+}
+
+/**
+ * board_spl_was_booted_from() - retrieves the of-path the SPL was loaded from
+ *
+ * To support a 'same-as-spl' specification in the search-order for the next
+ * stage, we need a SoC- or board-specific way to handshake with what 'came
+ * before us' (either a BROM or TPL stage) and map the info retrieved onto
+ * a OF path.
+ *
+ * Returns
+ * NULL, on failure or if the device could not be identified
+ * a of_path (a string), on success
+ */
+__weak const char *board_spl_was_booted_from(void)
+{
+ debug("%s: no support for 'same-as-spl' for this board\n", __func__);
+ return NULL;
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+ /* In case of no fdt (or only plat), use spl_boot_device() */
+ if (!CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA)) {
+ spl_boot_list[0] = spl_boot_device();
+ return;
+ }
+
+ const void *blob = gd->fdt_blob;
+ int chosen_node = fdt_path_offset(blob, "/chosen");
+ int idx = 0;
+ int elem;
+ int boot_device;
+ int node;
+ const char *conf;
+
+ if (chosen_node < 0) {
+ debug("%s: /chosen not found, using spl_boot_device()\n",
+ __func__);
+ spl_boot_list[0] = spl_boot_device();
+ return;
+ }
+
+ for (elem = 0;
+ (conf = fdt_stringlist_get(blob, chosen_node,
+ "u-boot,spl-boot-order", elem, NULL));
+ elem++) {
+ const char *alias;
+
+ /* Handle the case of 'same device the SPL was loaded from' */
+ if (strncmp(conf, "same-as-spl", 11) == 0) {
+ conf = board_spl_was_booted_from();
+ if (!conf)
+ continue;
+ }
+
+ /* First check if the list element is an alias */
+ alias = fdt_get_alias(blob, conf);
+ if (alias)
+ conf = alias;
+
+ /* Try to resolve the config item (or alias) as a path */
+ node = fdt_path_offset(blob, conf);
+ if (node < 0) {
+ debug("%s: could not find %s in FDT\n", __func__, conf);
+ continue;
+ }
+
+ /* Try to map this back onto SPL boot devices */
+ boot_device = spl_node_to_boot_device(node);
+ if (boot_device < 0) {
+ debug("%s: could not map node @%x to a boot-device\n",
+ __func__, node);
+ continue;
+ }
+
+ spl_boot_list[idx++] = boot_device;
+ }
+
+ /* If we had no matches, fall back to spl_boot_device */
+ if (idx == 0)
+ spl_boot_list[0] = spl_boot_device();
+}
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/spl.c b/roms/u-boot/arch/arm/mach-rockchip/spl.c
new file mode 100644
index 000000000..02c40fb37
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/spl.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <hang.h>
+#include <image.h>
+#include <init.h>
+#include <log.h>
+#include <ram.h>
+#include <spl.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_return_to_bootrom(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+
+ return 0;
+}
+
+__weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
+};
+
+const char *board_spl_was_booted_from(void)
+{
+ u32 bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR);
+ const char *bootdevice_ofpath = NULL;
+
+ if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
+ bootdevice_ofpath = boot_devices[bootdevice_brom_id];
+
+ if (bootdevice_ofpath)
+ debug("%s: brom_bootdevice_id %x maps to '%s'\n",
+ __func__, bootdevice_brom_id, bootdevice_ofpath);
+ else
+ debug("%s: failed to resolve brom_bootdevice_id %x\n",
+ __func__, bootdevice_brom_id);
+
+ return bootdevice_ofpath;
+}
+
+u32 spl_boot_device(void)
+{
+ u32 boot_device = BOOT_DEVICE_MMC1;
+
+#if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
+ defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
+ defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) || \
+ defined(CONFIG_TARGET_CHROMEBOOK_SPEEDY) || \
+ defined(CONFIG_TARGET_CHROMEBOOK_BOB)
+ return BOOT_DEVICE_SPI;
+#endif
+ if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
+ return BOOT_DEVICE_BOOTROM;
+
+ return boot_device;
+}
+
+u32 spl_mmc_boot_mode(const u32 boot_device)
+{
+ return MMCSD_MODE_RAW;
+}
+
+#if !defined(CONFIG_ROCKCHIP_RK3188)
+#define TIMER_LOAD_COUNT_L 0x00
+#define TIMER_LOAD_COUNT_H 0x04
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_EN 0x1
+#define TIMER_FMODE BIT(0)
+#define TIMER_RMODE BIT(1)
+
+__weak void rockchip_stimer_init(void)
+{
+ /* If Timer already enabled, don't re-init it */
+ u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+ if (reg & TIMER_EN)
+ return;
+#ifndef CONFIG_ARM64
+ asm volatile("mcr p15, 0, %0, c14, c0, 0"
+ : : "r"(COUNTER_FREQUENCY));
+#endif
+ writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+ writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+ TIMER_CONTROL_REG);
+}
+#endif
+
+__weak int board_early_init_f(void)
+{
+ return 0;
+}
+
+__weak int arch_cpu_init(void)
+{
+ return 0;
+}
+
+void board_init_f(ulong dummy)
+{
+ int ret;
+
+#ifdef CONFIG_DEBUG_UART
+ /*
+ * Debug UART can be used from here if required:
+ *
+ * debug_uart_init();
+ * printch('a');
+ * printhex8(0x1234);
+ * printascii("string");
+ */
+ debug_uart_init();
+ debug("\nspl:debug uart enabled in %s\n", __func__);
+#endif
+
+ board_early_init_f();
+
+ ret = spl_early_init();
+ if (ret) {
+ printf("spl_early_init() failed: %d\n", ret);
+ hang();
+ }
+ arch_cpu_init();
+#if !defined(CONFIG_ROCKCHIP_RK3188)
+ rockchip_stimer_init();
+#endif
+#ifdef CONFIG_SYS_ARCH_TIMER
+ /* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
+ timer_init();
+#endif
+#if !defined(CONFIG_TPL) || defined(CONFIG_SPL_RAM)
+ debug("\nspl:init dram\n");
+ ret = dram_init();
+ if (ret) {
+ printf("DRAM init failed: %d\n", ret);
+ return;
+ }
+ gd->ram_top = gd->ram_base + get_effective_memsize();
+ gd->ram_top = board_get_usable_ram_top(gd->ram_size);
+#endif
+ preloader_console_init();
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/tpl.c b/roms/u-boot/arch/arm/mach-rockchip/tpl.c
new file mode 100644
index 000000000..cc908e1b0
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/tpl.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019 Rockchip Electronics Co., Ltd
+ */
+
+#include <common.h>
+#include <debug_uart.h>
+#include <dm.h>
+#include <hang.h>
+#include <init.h>
+#include <log.h>
+#include <ram.h>
+#include <spl.h>
+#include <version.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/bootrom.h>
+#include <linux/bitops.h>
+
+#define TIMER_LOAD_COUNT_L 0x00
+#define TIMER_LOAD_COUNT_H 0x04
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_EN 0x1
+#define TIMER_FMODE BIT(0)
+#define TIMER_RMODE BIT(1)
+
+__weak void rockchip_stimer_init(void)
+{
+ /* If Timer already enabled, don't re-init it */
+ u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+
+ if (reg & TIMER_EN)
+ return;
+
+#ifndef CONFIG_ARM64
+ asm volatile("mcr p15, 0, %0, c14, c0, 0"
+ : : "r"(COUNTER_FREQUENCY));
+#endif
+
+ writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
+ writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
+ writel(TIMER_EN | TIMER_FMODE, CONFIG_ROCKCHIP_STIMER_BASE +
+ TIMER_CONTROL_REG);
+}
+
+void board_init_f(ulong dummy)
+{
+ struct udevice *dev;
+ int ret;
+
+#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_TPL_SERIAL_SUPPORT)
+ /*
+ * Debug UART can be used from here if required:
+ *
+ * debug_uart_init();
+ * printch('a');
+ * printhex8(0x1234);
+ * printascii("string");
+ */
+ debug_uart_init();
+#ifdef CONFIG_TPL_BANNER_PRINT
+ printascii("\nU-Boot TPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
+ U_BOOT_TIME ")\n");
+#endif
+#endif
+ ret = spl_early_init();
+ if (ret) {
+ debug("spl_early_init() failed: %d\n", ret);
+ hang();
+ }
+
+ /* Init secure timer */
+ rockchip_stimer_init();
+ /* Init ARM arch timer in arch/arm/cpu/ */
+ timer_init();
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ printf("DRAM init failed: %d\n", ret);
+ return;
+ }
+}
+
+int board_return_to_bootrom(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ back_to_bootrom(BROM_BOOT_NEXTSTAGE);
+
+ return 0;
+}
+
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_BOOTROM;
+}
diff --git a/roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl-v8.lds b/roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl-v8.lds
new file mode 100644
index 000000000..9869972e2
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl-v8.lds
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2019
+ * Rockchip Electronics Co., Ltd
+ * Kever Yang<kever.yang@rock-chips.com>
+ *
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ .text : {
+ . = ALIGN(8);
+ *(.__image_copy_start)
+ CPUDIR/start.o (.text*)
+ *(.text*)
+ }
+
+ .rodata : {
+ . = ALIGN(8);
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ }
+
+ .data : {
+ . = ALIGN(8);
+ *(.data*)
+ }
+
+ .u_boot_list : {
+ . = ALIGN(8);
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ .image_copy_end : {
+ . = ALIGN(8);
+ *(.__image_copy_end)
+ }
+
+ .end : {
+ . = ALIGN(8);
+ *(.__end)
+ }
+
+ _image_binary_end = .;
+
+ .bss_start (NOLOAD) : {
+ . = ALIGN(8);
+ KEEP(*(.__bss_start));
+ }
+
+ .bss (NOLOAD) : {
+ *(.bss*)
+ . = ALIGN(8);
+ }
+
+ .bss_end (NOLOAD) : {
+ KEEP(*(.__bss_end));
+ }
+
+ /DISCARD/ : { *(.dynsym) }
+ /DISCARD/ : { *(.dynstr*) }
+ /DISCARD/ : { *(.dynamic*) }
+ /DISCARD/ : { *(.plt*) }
+ /DISCARD/ : { *(.interp*) }
+ /DISCARD/ : { *(.gnu*) }
+}
+
+#if defined(CONFIG_TPL_MAX_SIZE)
+ASSERT(__image_copy_end - __image_copy_start < (CONFIG_TPL_MAX_SIZE), \
+ "TPL image too big");
+#endif
+
+#if defined(CONFIG_TPL_BSS_MAX_SIZE)
+ASSERT(__bss_end - __bss_start < (CONFIG_TPL_BSS_MAX_SIZE), \
+ "TPL image BSS too big");
+#endif
+
+#if defined(CONFIG_TPL_MAX_FOOTPRINT)
+ASSERT(__bss_end - _start < (CONFIG_TPL_MAX_FOOTPRINT), \
+ "TPL image plus BSS too big");
+#endif
diff --git a/roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl.lds b/roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl.lds
new file mode 100644
index 000000000..f5a89721c
--- /dev/null
+++ b/roms/u-boot/arch/arm/mach-rockchip/u-boot-tpl.lds
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Rockchip Electronic Co.,Ltd
+ */
+
+#undef CONFIG_SPL_TEXT_BASE
+#define CONFIG_SPL_TEXT_BASE CONFIG_TPL_TEXT_BASE
+
+#undef CONFIG_SPL_MAX_SIZE
+#define CONFIG_SPL_MAX_SIZE CONFIG_TPL_MAX_SIZE
+
+#include "../cpu/u-boot-spl.lds"