diff options
Diffstat (limited to 'roms/u-boot/arch/arm/mach-rockchip')
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" |