GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,376 @@
|
||||
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 SUPPORT_SPL
|
||||
select SPL
|
||||
select SUPPORT_TPL
|
||||
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_ATF_NO_PLATFORM_PARAM if 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 ROCKCHIP_COMMON_BOARD
|
||||
imply ROCKCHIP_SDRAM_COMMON
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
@@ -0,0 +1,48 @@
|
||||
# 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
|
||||
|
||||
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)
|
||||
@@ -0,0 +1,183 @@
|
||||
// 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 <init.h>
|
||||
#include <ram.h>
|
||||
#include <syscon.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(void)
|
||||
{
|
||||
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(void)
|
||||
{
|
||||
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
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2016 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <adc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/boot_mode.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;
|
||||
|
||||
if (adc_channel_single_shot("saradc", 1, &val)) {
|
||||
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
|
||||
@@ -0,0 +1,108 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/**
|
||||
* Copyright (c) 2017 Google, Inc
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch-rockchip/bootrom.h>
|
||||
#include <asm/arch-rockchip/boot_mode.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;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# Copyright (C) 2019 Rockchip Electronic Co.,Ltd
|
||||
#
|
||||
# Script to generate FIT image source for 32-bit Rockchip SoCs with
|
||||
# U-Boot proper, OPTEE, and devicetree.
|
||||
#
|
||||
# usage: $0 <dt_name>
|
||||
|
||||
[ -z "$TEE" ] && TEE="tee.bin"
|
||||
|
||||
if [ ! -f $TEE ]; then
|
||||
echo "WARNING: TEE file $TEE NOT found, U-Boot.itb is non-functional" >&2
|
||||
echo "Please export path for TEE or copy tee.bin to U-Boot folder" >&2
|
||||
TEE=/dev/null
|
||||
fi
|
||||
|
||||
dtname=$1
|
||||
text_base=`sed -n "/SYS_TEXT_BASE=/s/CONFIG_SYS_TEXT_BASE=//p" .config \
|
||||
|tr -d '\r'`
|
||||
dram_base=`sed -n "/SYS_SDRAM_BASE=/s/CONFIG_SYS_SDRAM_BASE=//p" \
|
||||
include/autoconf.mk|tr -d '\r'`
|
||||
tee_base=`echo "obase=16;$(($dram_base+0x8400000))"|bc`
|
||||
tee_base='0x'$tee_base
|
||||
|
||||
cat << __HEADER_EOF
|
||||
/*
|
||||
* Copyright (C) 2017-2019 Rockchip Electronic Co.,Ltd
|
||||
*
|
||||
* Simple U-boot FIT source file containing U-Boot, dtb and optee
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
/ {
|
||||
description = "FIT image with OP-TEE support";
|
||||
#address-cells = <1>;
|
||||
|
||||
images {
|
||||
uboot {
|
||||
description = "U-Boot";
|
||||
data = /incbin/("u-boot-nodtb.bin");
|
||||
type = "standalone";
|
||||
os = "U-Boot";
|
||||
arch = "arm";
|
||||
compression = "none";
|
||||
load = <$text_base>;
|
||||
};
|
||||
optee {
|
||||
description = "OP-TEE";
|
||||
data = /incbin/("$TEE");
|
||||
type = "firmware";
|
||||
arch = "arm";
|
||||
os = "tee";
|
||||
compression = "none";
|
||||
load = <$tee_base>;
|
||||
entry = <$tee_base>;
|
||||
};
|
||||
fdt {
|
||||
description = "$(basename $dtname .dtb)";
|
||||
data = /incbin/("$dtname");
|
||||
type = "flat_dt";
|
||||
compression = "none";
|
||||
};
|
||||
__HEADER_EOF
|
||||
|
||||
cat << __CONF_HEADER_EOF
|
||||
};
|
||||
|
||||
configurations {
|
||||
default = "conf";
|
||||
conf {
|
||||
description = "$(basename $dtname .dtb)";
|
||||
firmware = "optee";
|
||||
loadables = "uboot";
|
||||
fdt = "fdt";
|
||||
};
|
||||
__CONF_HEADER_EOF
|
||||
|
||||
cat << __ITS_EOF
|
||||
};
|
||||
};
|
||||
__ITS_EOF
|
||||
@@ -0,0 +1,239 @@
|
||||
#!/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_1";\n')
|
||||
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)
|
||||
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()
|
||||
@@ -0,0 +1,129 @@
|
||||
/* 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 <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_GET_DRIVER(rockchip_efuse), &dev);
|
||||
#elif CONFIG_IS_ENABLED(ROCKCHIP_OTP)
|
||||
ret = uclass_get_device_by_driver(UCLASS_MISC,
|
||||
DM_GET_DRIVER(rockchip_otp), &dev);
|
||||
#endif
|
||||
if (ret) {
|
||||
debug("%s: could not find efuse device\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <spl.h>
|
||||
#include <version.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/bootrom.h>
|
||||
#include <asm/arch-rockchip/sdram_px30.h>
|
||||
|
||||
#define TIMER_LOAD_COUNT0 0x00
|
||||
#define TIMER_LOAD_COUNT1 0x04
|
||||
#define TIMER_CUR_VALUE0 0x08
|
||||
#define TIMER_CUR_VALUE1 0x0c
|
||||
#define TIMER_CONTROL_REG 0x10
|
||||
|
||||
#define TIMER_EN 0x1
|
||||
#define TIMER_FMODE (0 << 1)
|
||||
#define TIMER_RMODE (1 << 1)
|
||||
|
||||
void secure_timer_init(void)
|
||||
{
|
||||
writel(0, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
|
||||
writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT0);
|
||||
writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + TIMER_LOAD_COUNT1);
|
||||
writel(TIMER_EN | TIMER_FMODE,
|
||||
CONFIG_ROCKCHIP_STIMER_BASE + TIMER_CONTROL_REG);
|
||||
}
|
||||
|
||||
void board_init_f(ulong dummy)
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
debug_uart_init();
|
||||
/*
|
||||
* Debug UART can be used from here if required:
|
||||
*
|
||||
* debug_uart_init();
|
||||
* printch('a');
|
||||
* printhex8(0x1234);
|
||||
* printascii("string");
|
||||
*/
|
||||
printascii("U-Boot TPL board init\n");
|
||||
#endif
|
||||
|
||||
secure_timer_init();
|
||||
ret = sdram_init();
|
||||
if (ret)
|
||||
printascii("sdram_init failed\n");
|
||||
|
||||
/* return to maskrom */
|
||||
back_to_bootrom(BROM_BOOT_NEXTSTAGE);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
if ROCKCHIP_PX30
|
||||
|
||||
config TARGET_EVB_PX30
|
||||
bool "EVB_PX30"
|
||||
|
||||
config ROCKCHIP_BOOT_MODE_REG
|
||||
default 0xff010200
|
||||
|
||||
config SYS_SOC
|
||||
default "px30"
|
||||
|
||||
config SYS_MALLOC_F_LEN
|
||||
default 0x400
|
||||
|
||||
config SPL_SERIAL_SUPPORT
|
||||
default y
|
||||
|
||||
config TPL_LDSCRIPT
|
||||
default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds"
|
||||
|
||||
config TPL_TEXT_BASE
|
||||
default 0xff0e1000
|
||||
|
||||
config TPL_MAX_SIZE
|
||||
default 10240
|
||||
|
||||
config TPL_STACK
|
||||
default 0xff0e4fff
|
||||
|
||||
config 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/rockchip/evb_px30/Kconfig"
|
||||
|
||||
endif
|
||||
@@ -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
|
||||
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_px30.h>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(rockchip_px30_cru), devp);
|
||||
}
|
||||
|
||||
void *rockchip_get_cru(void)
|
||||
{
|
||||
struct px30_clk_priv *priv;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = rockchip_get_clk(&dev);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
priv = dev_get_priv(dev);
|
||||
|
||||
return priv->cru;
|
||||
}
|
||||
@@ -0,0 +1,325 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2017 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <clk.h>
|
||||
#include <dm.h>
|
||||
#include <asm/armv8/mmu.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/grf_px30.h>
|
||||
#include <asm/arch-rockchip/hardware.h>
|
||||
#include <asm/arch-rockchip/uart.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_px30.h>
|
||||
#include <dt-bindings/clock/px30-cru.h>
|
||||
|
||||
static struct mm_region px30_mem_map[] = {
|
||||
{
|
||||
.virt = 0x0UL,
|
||||
.phys = 0x0UL,
|
||||
.size = 0xff000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
|
||||
PTE_BLOCK_INNER_SHARE
|
||||
}, {
|
||||
.virt = 0xff000000UL,
|
||||
.phys = 0xff000000UL,
|
||||
.size = 0x01000000UL,
|
||||
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
|
||||
PTE_BLOCK_NON_SHARE |
|
||||
PTE_BLOCK_PXN | PTE_BLOCK_UXN
|
||||
}, {
|
||||
/* List terminator */
|
||||
0,
|
||||
}
|
||||
};
|
||||
|
||||
struct mm_region *mem_map = px30_mem_map;
|
||||
|
||||
#define PMU_PWRDN_CON 0xff000018
|
||||
#define 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 */
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
|
||||
static const struct udevice_id px30_syscon_ids[] = {
|
||||
{ .compatible = "rockchip,px30-pmu", .data = ROCKCHIP_SYSCON_PMU },
|
||||
{ .compatible = "rockchip,px30-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
|
||||
{ .compatible = "rockchip,px30-grf", .data = ROCKCHIP_SYSCON_GRF },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(syscon_px30) = {
|
||||
.id = UCLASS_SYSCON,
|
||||
.name = "px30_syscon",
|
||||
.of_match = px30_syscon_ids,
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
static int px30_syscon_bind_of_platdata(struct udevice *dev)
|
||||
{
|
||||
dev->driver_data = dev->driver->of_match->data;
|
||||
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(rockchip_px30_pmu) = {
|
||||
.name = "rockchip_px30_pmu",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = px30_syscon_ids,
|
||||
.bind = px30_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_px30_pmugrf) = {
|
||||
.name = "rockchip_px30_pmugrf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = px30_syscon_ids + 1,
|
||||
.bind = px30_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_px30_grf) = {
|
||||
.name = "rockchip_px30_grf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = px30_syscon_ids + 2,
|
||||
.bind = px30_syscon_bind_of_platdata,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2015-2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.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)
|
||||
;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#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
|
||||
@@ -0,0 +1,765 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* (C) Copyright 2015 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.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>
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2017 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
/* We do some SoC one time setting here. */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <syscon.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>
|
||||
|
||||
#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
|
||||
|
||||
/* 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 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
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_on(dev, 1);
|
||||
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
|
||||
@@ -0,0 +1,54 @@
|
||||
// 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>
|
||||
|
||||
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_platdata(struct udevice *dev)
|
||||
{
|
||||
dev->driver_data = dev->driver->of_match->data;
|
||||
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3188_noc) = {
|
||||
.name = "rockchip_rk3188_noc",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3188_syscon_ids,
|
||||
.bind = rk3188_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3188_grf) = {
|
||||
.name = "rockchip_rk3188_grf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3188_syscon_ids + 1,
|
||||
.bind = rk3188_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3188_pmu) = {
|
||||
.name = "rockchip_rk3188_pmu",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3188_syscon_ids + 2,
|
||||
.bind = rk3188_syscon_bind_of_platdata,
|
||||
};
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2017 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_rk322x.h>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#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;
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
@@ -0,0 +1,196 @@
|
||||
if ROCKCHIP_RK3288
|
||||
|
||||
choice
|
||||
prompt "RK3288 board select"
|
||||
|
||||
config TARGET_CHROMEBOOK_JERRY
|
||||
bool "Google/Rockchip Veyron-Jerry Chromebook"
|
||||
select BOARD_LATE_INIT
|
||||
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 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
|
||||
@@ -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
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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_rk3288.h>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2016 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <env.h>
|
||||
#include <clk.h>
|
||||
#include <init.h>
|
||||
#include <asm/armv7.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/bootrom.h>
|
||||
#include <asm/arch-rockchip/clock.h>
|
||||
#include <asm/arch-rockchip/cru_rk3288.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>
|
||||
|
||||
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
|
||||
|
||||
static void rk3288_detect_reset_reason(void)
|
||||
{
|
||||
struct rk3288_cru *cru = rockchip_get_cru();
|
||||
const char *reason;
|
||||
|
||||
if (IS_ERR(cru))
|
||||
return;
|
||||
|
||||
switch (cru->cru_glb_rst_st) {
|
||||
case GLB_POR_RST:
|
||||
reason = "POR";
|
||||
break;
|
||||
case FST_GLB_RST_ST:
|
||||
case SND_GLB_RST_ST:
|
||||
reason = "RST";
|
||||
break;
|
||||
case FST_GLB_TSADC_RST_ST:
|
||||
case SND_GLB_TSADC_RST_ST:
|
||||
reason = "THERMAL";
|
||||
break;
|
||||
case FST_GLB_WDT_RST_ST:
|
||||
case SND_GLB_WDT_RST_ST:
|
||||
reason = "WDOG";
|
||||
break;
|
||||
default:
|
||||
reason = "unknown reset";
|
||||
}
|
||||
|
||||
env_set("reset_reason", reason);
|
||||
|
||||
/*
|
||||
* Clear cru_glb_rst_st, so we can determine the last reset cause
|
||||
* for following resets.
|
||||
*/
|
||||
rk_clrreg(&cru->cru_glb_rst_st, GLB_RST_ST_MASK);
|
||||
}
|
||||
|
||||
__weak int rk3288_board_late_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rk_board_late_init(void)
|
||||
{
|
||||
rk3288_detect_reset_reason();
|
||||
|
||||
return rk3288_board_late_init();
|
||||
}
|
||||
|
||||
static int do_clock(cmd_tbl_t *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",
|
||||
""
|
||||
);
|
||||
@@ -0,0 +1,62 @@
|
||||
// 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>
|
||||
|
||||
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_platdata(struct udevice *dev)
|
||||
{
|
||||
dev->driver_data = dev->driver->of_match->data;
|
||||
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3288_noc) = {
|
||||
.name = "rockchip_rk3288_noc",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3288_syscon_ids,
|
||||
.bind = rk3288_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3288_grf) = {
|
||||
.name = "rockchip_rk3288_grf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3288_syscon_ids + 1,
|
||||
.bind = rk3288_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3288_sgrf) = {
|
||||
.name = "rockchip_rk3288_sgrf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3288_syscon_ids + 2,
|
||||
.bind = rk3288_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3288_pmu) = {
|
||||
.name = "rockchip_rk3288_pmu",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3288_syscon_ids + 3,
|
||||
.bind = rk3288_syscon_bind_of_platdata,
|
||||
};
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,31 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
*Copyright (c) 2018 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
#include <common.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>
|
||||
|
||||
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
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,30 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2016 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.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/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);
|
||||
}
|
||||
@@ -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(syscon_rk3328) = {
|
||||
.name = "rk3328_syscon",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3328_syscon_ids,
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
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 0x2000
|
||||
|
||||
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 TPL_MAX_SIZE
|
||||
default 28672
|
||||
|
||||
config TPL_STACK
|
||||
default 0xff8cffff
|
||||
|
||||
config TPL_TEXT_BASE
|
||||
default 0xff8c1000
|
||||
|
||||
endif
|
||||
@@ -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
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2016 Rockchip Electronics Co., Ltd
|
||||
* Copyright (c) 2016 Andreas Färber
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/armv8/mmu.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>
|
||||
|
||||
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
|
||||
@@ -0,0 +1,67 @@
|
||||
// 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 <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_platdata(struct udevice *dev)
|
||||
{
|
||||
dev->driver_data = dev->driver->of_match->data;
|
||||
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3368_grf) = {
|
||||
.name = "rockchip_rk3368_grf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3368_syscon_ids,
|
||||
.bind = rk3368_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3368_pmugrf) = {
|
||||
.name = "rockchip_rk3368_pmugrf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3368_syscon_ids + 1,
|
||||
.bind = rk3368_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3368_msch) = {
|
||||
.name = "rockchip_rk3368_msch",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3368_syscon_ids + 2,
|
||||
.bind = rk3368_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3368_sgrf) = {
|
||||
.name = "rockchip_rk3368_sgrf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3368_syscon_ids + 3,
|
||||
.bind = rk3368_syscon_bind_of_platdata,
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
if ROCKCHIP_RK3399
|
||||
|
||||
choice
|
||||
prompt "RK3399 board select"
|
||||
|
||||
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_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_CHROMEBOOK_BOB
|
||||
bool "Asus Flip C101PA Chromebook (RK3399)"
|
||||
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_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
|
||||
|
||||
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
|
||||
|
||||
source "board/rockchip/evb_rk3399/Kconfig"
|
||||
source "board/theobroma-systems/puma_rk3399/Kconfig"
|
||||
source "board/vamrs/rock960_rk3399/Kconfig"
|
||||
source "board/google/gru/Kconfig"
|
||||
source "board/pine64/rockpro64_rk3399/Kconfig"
|
||||
|
||||
endif
|
||||
@@ -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
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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_rk3399.h>
|
||||
|
||||
static int rockchip_get_cruclk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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_GET_DRIVER(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;
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2016 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <spl.h>
|
||||
#include <spl_gpio.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/armv8/mmu.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 <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] = "/dwmmc@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, "/dwmmc@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 spl_board_init(void)
|
||||
{
|
||||
#if defined(SPL_GPIO_SUPPORT)
|
||||
struct rk3399_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
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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 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,
|
||||
.of_match = rk3399_syscon_ids,
|
||||
};
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
static int rk3399_syscon_bind_of_platdata(struct udevice *dev)
|
||||
{
|
||||
dev->driver_data = dev->driver->of_match->data;
|
||||
debug("syscon: %s %d\n", dev->name, (uint)dev->driver_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3399_grf) = {
|
||||
.name = "rockchip_rk3399_grf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3399_syscon_ids,
|
||||
.bind = rk3399_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3399_pmugrf) = {
|
||||
.name = "rockchip_rk3399_pmugrf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3399_syscon_ids + 1,
|
||||
.bind = rk3399_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3399_pmusgrf) = {
|
||||
.name = "rockchip_rk3399_pmusgrf",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3399_syscon_ids + 2,
|
||||
.bind = rk3399_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3399_cic) = {
|
||||
.name = "rockchip_rk3399_cic",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3399_syscon_ids + 3,
|
||||
.bind = rk3399_syscon_bind_of_platdata,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(rockchip_rk3399_pmu) = {
|
||||
.name = "rockchip_rk3399_pmu",
|
||||
.id = UCLASS_SYSCON,
|
||||
.of_match = rk3399_syscon_ids + 4,
|
||||
.bind = rk3399_syscon_bind_of_platdata,
|
||||
};
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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>
|
||||
|
||||
int rockchip_get_clk(struct udevice **devp)
|
||||
{
|
||||
return uclass_get_device_by_driver(UCLASS_CLK,
|
||||
DM_GET_DRIVER(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;
|
||||
}
|
||||
@@ -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>
|
||||
*/
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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 <ram.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),
|
||||
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 = gd->bd->bi_dram[0].start
|
||||
+ 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 = gd->bd->bi_dram[0].start
|
||||
+ 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;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <mmc.h>
|
||||
#include <spl.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_platdata(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)
|
||||
{
|
||||
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
|
||||
@@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <spl.h>
|
||||
#include <asm/arch-rockchip/bootrom.h>
|
||||
#include <asm/io.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)
|
||||
return BOOT_DEVICE_SPI;
|
||||
#endif
|
||||
if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
|
||||
return BOOT_DEVICE_BOOTROM;
|
||||
|
||||
return boot_device;
|
||||
}
|
||||
|
||||
u32 spl_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;
|
||||
#if !defined(CONFIG_TPL) || defined(CONFIG_SPL_OS_BOOT)
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
#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_OS_BOOT)
|
||||
debug("\nspl:init dram\n");
|
||||
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
|
||||
if (ret) {
|
||||
printf("DRAM init failed: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
preloader_console_init();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SPL_LOAD_FIT
|
||||
int board_fit_config_name_match(const char *name)
|
||||
{
|
||||
/* Just empty function now - can't decide what to choose */
|
||||
debug("%s: %s\n", __func__, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2019 Rockchip Electronics Co., Ltd
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <dm.h>
|
||||
#include <ram.h>
|
||||
#include <spl.h>
|
||||
#include <version.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch-rockchip/bootrom.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
Reference in New Issue
Block a user