2018-01-22 06:49:12 +00:00
|
|
|
/*
|
|
|
|
|
* (C) Copyright 2017 Rockchip Electronics Co., Ltd.
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
|
|
|
*/
|
|
|
|
|
#include <common.h>
|
|
|
|
|
#include <clk.h>
|
|
|
|
|
#include <dm.h>
|
2018-02-10 08:41:01 +00:00
|
|
|
#include <debug_uart.h>
|
2018-01-22 06:49:12 +00:00
|
|
|
#include <ram.h>
|
|
|
|
|
#include <syscon.h>
|
2019-01-13 11:05:14 +00:00
|
|
|
#include <sysmem.h>
|
2018-01-22 06:49:12 +00:00
|
|
|
#include <asm/io.h>
|
2018-06-01 09:42:16 +00:00
|
|
|
#include <asm/arch/vendor.h>
|
|
|
|
|
#include <misc.h>
|
2018-01-22 06:49:12 +00:00
|
|
|
#include <asm/gpio.h>
|
|
|
|
|
#include <asm/arch/clock.h>
|
|
|
|
|
#include <asm/arch/periph.h>
|
|
|
|
|
#include <asm/arch/boot_mode.h>
|
2018-10-09 11:45:00 +00:00
|
|
|
#include <asm/arch/rk_atags.h>
|
2019-01-13 11:05:14 +00:00
|
|
|
#include <asm/arch/param.h>
|
2018-01-22 06:49:12 +00:00
|
|
|
#ifdef CONFIG_DM_CHARGE_DISPLAY
|
|
|
|
|
#include <power/charge_display.h>
|
|
|
|
|
#endif
|
2018-11-19 10:42:21 +00:00
|
|
|
#ifdef CONFIG_DM_DVFS
|
|
|
|
|
#include <dvfs.h>
|
|
|
|
|
#endif
|
2018-12-17 09:56:40 +00:00
|
|
|
#ifdef CONFIG_ROCKCHIP_IO_DOMAIN
|
|
|
|
|
#include <io-domain.h>
|
|
|
|
|
#endif
|
2018-01-22 06:49:12 +00:00
|
|
|
#ifdef CONFIG_DM_REGULATOR
|
|
|
|
|
#include <power/regulator.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef CONFIG_DRM_ROCKCHIP
|
|
|
|
|
#include <video_rockchip.h>
|
|
|
|
|
#endif
|
2018-06-07 04:01:09 +00:00
|
|
|
#ifdef CONFIG_ROCKCHIP_DEBUGGER
|
|
|
|
|
#include <rockchip_debugger.h>
|
|
|
|
|
#endif
|
2018-02-07 03:10:27 +00:00
|
|
|
#include <of_live.h>
|
|
|
|
|
#include <dm/root.h>
|
2019-01-25 11:29:52 +00:00
|
|
|
#include <console.h>
|
2018-01-22 06:49:12 +00:00
|
|
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
2018-06-01 09:42:16 +00:00
|
|
|
/* define serialno max length, the max length is 512 Bytes
|
|
|
|
|
* The remaining bytes are used to ensure that the first 512 bytes
|
|
|
|
|
* are valid when executing 'env_set("serial#", value)'.
|
|
|
|
|
*/
|
|
|
|
|
#define VENDOR_SN_MAX 513
|
|
|
|
|
#define CPUID_LEN 0x10
|
|
|
|
|
#define CPUID_OFF 0x7
|
|
|
|
|
|
2019-02-21 07:28:16 +00:00
|
|
|
static int rockchip_set_ethaddr(void)
|
|
|
|
|
{
|
|
|
|
|
#ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
|
|
|
|
|
int ret;
|
|
|
|
|
u8 ethaddr[ARP_HLEN];
|
|
|
|
|
char buf[ARP_HLEN_ASCII + 1];
|
|
|
|
|
|
|
|
|
|
ret = vendor_storage_read(VENDOR_LAN_MAC_ID, ethaddr, sizeof(ethaddr));
|
|
|
|
|
if (ret > 0 && is_valid_ethaddr(ethaddr)) {
|
|
|
|
|
sprintf(buf, "%pM", ethaddr);
|
|
|
|
|
env_set("ethaddr", buf);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-01 09:42:16 +00:00
|
|
|
static int rockchip_set_serialno(void)
|
|
|
|
|
{
|
|
|
|
|
char serialno_str[VENDOR_SN_MAX];
|
|
|
|
|
int ret = 0, i;
|
|
|
|
|
u8 cpuid[CPUID_LEN] = {0};
|
|
|
|
|
u8 low[CPUID_LEN / 2], high[CPUID_LEN / 2];
|
|
|
|
|
u64 serialno;
|
|
|
|
|
|
|
|
|
|
/* Read serial number from vendor storage part */
|
|
|
|
|
memset(serialno_str, 0, VENDOR_SN_MAX);
|
|
|
|
|
#ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
|
|
|
|
|
ret = vendor_storage_read(VENDOR_SN_ID, serialno_str, (VENDOR_SN_MAX-1));
|
|
|
|
|
if (ret > 0) {
|
|
|
|
|
env_set("serial#", serialno_str);
|
|
|
|
|
} else {
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef CONFIG_ROCKCHIP_EFUSE
|
|
|
|
|
struct udevice *dev;
|
|
|
|
|
|
|
|
|
|
/* retrieve the device */
|
|
|
|
|
ret = uclass_get_device_by_driver(UCLASS_MISC,
|
|
|
|
|
DM_GET_DRIVER(rockchip_efuse), &dev);
|
|
|
|
|
if (ret) {
|
|
|
|
|
printf("%s: could not find efuse device\n", __func__);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
/* read the cpu_id range from the efuses */
|
|
|
|
|
ret = misc_read(dev, CPUID_OFF, &cpuid, sizeof(cpuid));
|
|
|
|
|
if (ret) {
|
|
|
|
|
printf("%s: reading cpuid from the efuses failed\n", __func__);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
/* generate random cpuid */
|
|
|
|
|
for (i = 0; i < CPUID_LEN; i++) {
|
|
|
|
|
cpuid[i] = (u8)(rand());
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
/* Generate the serial number based on CPU ID */
|
|
|
|
|
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), "%llx", serialno);
|
|
|
|
|
|
|
|
|
|
env_set("serial#", serialno_str);
|
|
|
|
|
#ifdef CONFIG_ROCKCHIP_VENDOR_PARTITION
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2018-01-22 06:49:12 +00:00
|
|
|
|
|
|
|
|
#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
|
|
|
|
|
int fb_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
|
|
|
|
|
|
|
|
|
|
__weak int rk_board_init(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__weak int rk_board_late_init(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-18 13:27:00 +00:00
|
|
|
__weak int soc_clk_dump(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-24 03:29:52 +00:00
|
|
|
__weak int set_armclk_rate(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-22 06:49:12 +00:00
|
|
|
int board_late_init(void)
|
|
|
|
|
{
|
2019-02-21 07:28:16 +00:00
|
|
|
rockchip_set_ethaddr();
|
2018-11-21 05:40:41 +00:00
|
|
|
rockchip_set_serialno();
|
2018-01-22 06:49:12 +00:00
|
|
|
#if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0)
|
|
|
|
|
setup_boot_mode();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_DM_CHARGE_DISPLAY
|
|
|
|
|
charge_display();
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_DRM_ROCKCHIP
|
|
|
|
|
rockchip_show_logo();
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-05-18 13:27:00 +00:00
|
|
|
soc_clk_dump();
|
|
|
|
|
|
2018-01-22 06:49:12 +00:00
|
|
|
return rk_board_late_init();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-07 03:10:27 +00:00
|
|
|
#ifdef CONFIG_USING_KERNEL_DTB
|
|
|
|
|
#include <asm/arch/resource_img.h>
|
2018-05-03 11:52:53 +00:00
|
|
|
|
2018-02-07 03:10:27 +00:00
|
|
|
int init_kernel_dtb(void)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
ulong fdt_addr = 0;
|
|
|
|
|
|
|
|
|
|
fdt_addr = env_get_ulong("fdt_addr_r", 16, 0);
|
|
|
|
|
if (!fdt_addr) {
|
|
|
|
|
printf("No Found FDT Load Address.\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-03 11:52:53 +00:00
|
|
|
ret = rockchip_read_dtb_file((void *)fdt_addr);
|
2018-02-07 03:10:27 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
|
printf("%s dtb in resource read fail\n", __func__);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
of_live_build((void *)fdt_addr, (struct device_node **)&gd->of_root);
|
|
|
|
|
|
|
|
|
|
dm_scan_fdt((void *)fdt_addr, false);
|
|
|
|
|
|
|
|
|
|
gd->fdt_blob = (void *)fdt_addr;
|
|
|
|
|
|
2019-01-13 11:05:14 +00:00
|
|
|
/* Reserve 'reserved-memory' */
|
|
|
|
|
ret = boot_fdt_add_sysmem_rsv_regions((void *)gd->fdt_blob);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
|
2018-02-07 03:10:27 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-12-04 09:21:31 +00:00
|
|
|
void board_env_fixup(void)
|
|
|
|
|
{
|
|
|
|
|
ulong kernel_addr_r;
|
|
|
|
|
|
|
|
|
|
if (gd->flags & GD_FLG_BL32_ENABLED)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* If bl32 is disabled, maybe kernel can be load to lower address. */
|
|
|
|
|
kernel_addr_r = env_get_ulong("kernel_addr_no_bl32_r", 16, -1);
|
|
|
|
|
if (kernel_addr_r != -1)
|
|
|
|
|
env_set_hex("kernel_addr_r", kernel_addr_r);
|
|
|
|
|
}
|
2018-02-07 03:10:27 +00:00
|
|
|
|
2019-01-25 11:29:52 +00:00
|
|
|
static void early_bootrom_download(void)
|
|
|
|
|
{
|
|
|
|
|
if (!tstc())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
gd->console_evt = getc();
|
|
|
|
|
#if (CONFIG_ROCKCHIP_BOOT_MODE_REG > 0)
|
|
|
|
|
/* ctrl+b */
|
|
|
|
|
if (gd->console_evt == CONSOLE_EVT_CTRL_B) {
|
|
|
|
|
printf("Enter bootrom download...");
|
|
|
|
|
mdelay(100);
|
|
|
|
|
writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
|
|
|
|
|
do_reset(NULL, 0, 0, NULL);
|
|
|
|
|
printf("failed!\n");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-22 06:49:12 +00:00
|
|
|
int board_init(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
2018-02-10 08:41:01 +00:00
|
|
|
board_debug_uart_init();
|
2019-01-25 11:29:52 +00:00
|
|
|
early_bootrom_download();
|
2018-07-23 11:57:20 +00:00
|
|
|
|
2018-02-07 03:10:27 +00:00
|
|
|
#ifdef CONFIG_USING_KERNEL_DTB
|
|
|
|
|
init_kernel_dtb();
|
|
|
|
|
#endif
|
2018-03-21 07:00:31 +00:00
|
|
|
/*
|
|
|
|
|
* pmucru isn't referenced on some platforms, so pmucru driver can't
|
|
|
|
|
* probe that the "assigned-clocks" is unused.
|
|
|
|
|
*/
|
|
|
|
|
clks_probe();
|
2018-01-22 06:49:12 +00:00
|
|
|
#ifdef CONFIG_DM_REGULATOR
|
|
|
|
|
ret = regulators_enable_boot_on(false);
|
|
|
|
|
if (ret)
|
|
|
|
|
debug("%s: Cannot enable boot on regulator\n", __func__);
|
|
|
|
|
#endif
|
2018-12-17 09:56:40 +00:00
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROCKCHIP_IO_DOMAIN
|
|
|
|
|
io_domain_init();
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-03-24 03:29:52 +00:00
|
|
|
set_armclk_rate();
|
2018-01-22 06:49:12 +00:00
|
|
|
|
2018-11-19 10:42:21 +00:00
|
|
|
#ifdef CONFIG_DM_DVFS
|
|
|
|
|
dvfs_init(true);
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-01-22 06:49:12 +00:00
|
|
|
return rk_board_init();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-07 04:01:09 +00:00
|
|
|
int interrupt_debugger_init(void)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_ROCKCHIP_DEBUGGER
|
|
|
|
|
ret = rockchip_debugger_init();
|
|
|
|
|
#endif
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-14 11:20:11 +00:00
|
|
|
#if defined(CONFIG_ROCKCHIP_RK1808) && !defined(CONFIG_COPROCESSOR_RK1808)
|
2019-03-11 06:44:52 +00:00
|
|
|
#define PINCTRL_EMMC_BUS8_PATH "/pinctrl/emmc/emmc-bus8"
|
|
|
|
|
#define PINCTRL_EMMC_CMD_PATH "/pinctrl/emmc/emmc-cmd"
|
|
|
|
|
#define PINCTRL_EMMC_CLK_PATH "/pinctrl/emmc/emmc-clk"
|
|
|
|
|
#define PINCTRL_PCFG_PU_2MA_PATH "/pinctrl/pcfg-pull-up-2ma"
|
|
|
|
|
#define MAX_ROCKCHIP_PINS_ENTRIES 12
|
|
|
|
|
|
|
|
|
|
static int rockchip_pinctrl_cfg_fdt_fixup(const char *path, u32 new_phandle)
|
|
|
|
|
{
|
|
|
|
|
u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4];
|
|
|
|
|
const u32 *data;
|
|
|
|
|
int i, count;
|
|
|
|
|
int node;
|
|
|
|
|
|
|
|
|
|
node = fdt_path_offset(gd->fdt_blob, path);
|
|
|
|
|
if (node < 0) {
|
|
|
|
|
debug("%s: can't find: %s\n", __func__, path);
|
|
|
|
|
return node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data = fdt_getprop(gd->fdt_blob, node, "rockchip,pins", &count);
|
|
|
|
|
if (!data) {
|
|
|
|
|
debug("%s: can't find prop \"rockchip,pins\"\n", __func__);
|
|
|
|
|
return -ENODATA;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
count /= sizeof(u32);
|
|
|
|
|
if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) {
|
|
|
|
|
debug("%s: %d is over max count\n", __func__, count);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
|
cells[i] = data[i];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < (count >> 2); i++)
|
|
|
|
|
cells[4 * i + 3] = cpu_to_fdt32(new_phandle);
|
|
|
|
|
|
|
|
|
|
fdt_setprop((void *)gd->fdt_blob, node, "rockchip,pins",
|
|
|
|
|
&cells, count * sizeof(u32));
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-06-01 09:46:16 +00:00
|
|
|
int board_fdt_fixup(void *blob)
|
|
|
|
|
{
|
2019-03-11 06:44:52 +00:00
|
|
|
int ret = 0;
|
2018-06-01 09:46:16 +00:00
|
|
|
|
2019-03-11 06:44:52 +00:00
|
|
|
/*
|
|
|
|
|
* Common fixup for DRM
|
|
|
|
|
*/
|
2018-06-01 09:46:16 +00:00
|
|
|
#ifdef CONFIG_DRM_ROCKCHIP
|
|
|
|
|
rockchip_display_fixup(blob);
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-03-11 06:44:52 +00:00
|
|
|
/*
|
|
|
|
|
* Platform fixup:
|
|
|
|
|
*
|
|
|
|
|
* - RK3288: Recognize RK3288W by HDMI Revision ID is 0x1A;
|
|
|
|
|
* - RK1808: MMC strength 2mA;
|
|
|
|
|
*/
|
2018-06-01 09:46:16 +00:00
|
|
|
#ifdef CONFIG_ROCKCHIP_RK3288
|
|
|
|
|
if (readl(0xff980004) == 0x1A) {
|
|
|
|
|
ret = fdt_setprop_string(blob, 0,
|
|
|
|
|
"compatible", "rockchip,rk3288w");
|
|
|
|
|
if (ret)
|
|
|
|
|
printf("fdt set compatible failed: %d\n", ret);
|
|
|
|
|
}
|
2019-03-14 11:20:11 +00:00
|
|
|
#elif defined(CONFIG_ROCKCHIP_RK1808) && !defined(CONFIG_COPROCESSOR_RK1808)
|
2019-03-11 06:44:52 +00:00
|
|
|
struct tag *t;
|
|
|
|
|
u32 ph_pu_2ma;
|
|
|
|
|
|
|
|
|
|
t = atags_get_tag(ATAG_SOC_INFO);
|
|
|
|
|
if (!t)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
debug("soc=0x%x, flags=0x%x\n", t->u.soc.name, t->u.soc.flags);
|
|
|
|
|
|
|
|
|
|
if (t->u.soc.flags != SOC_FLAGS_ET00)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ph_pu_2ma = fdt_get_phandle(gd->fdt_blob,
|
|
|
|
|
fdt_path_offset(gd->fdt_blob, PINCTRL_PCFG_PU_2MA_PATH));
|
|
|
|
|
if (!ph_pu_2ma) {
|
|
|
|
|
debug("Can't find: %s\n", PINCTRL_PCFG_PU_2MA_PATH);
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret |= rockchip_pinctrl_cfg_fdt_fixup(PINCTRL_EMMC_BUS8_PATH, ph_pu_2ma);
|
|
|
|
|
ret |= rockchip_pinctrl_cfg_fdt_fixup(PINCTRL_EMMC_CMD_PATH, ph_pu_2ma);
|
|
|
|
|
ret |= rockchip_pinctrl_cfg_fdt_fixup(PINCTRL_EMMC_CLK_PATH, ph_pu_2ma);
|
2018-06-01 09:46:16 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-14 11:35:41 +00:00
|
|
|
#ifdef CONFIG_ARM64_BOOT_AARCH32
|
|
|
|
|
/*
|
|
|
|
|
* Fixup MMU region attr for OP-TEE on ARMv8 CPU:
|
|
|
|
|
*
|
|
|
|
|
* What ever U-Boot is 64-bit or 32-bit mode, the OP-TEE is always 64-bit mode.
|
|
|
|
|
*
|
|
|
|
|
* Command for OP-TEE:
|
|
|
|
|
* 64-bit mode: dcache is always enabled;
|
|
|
|
|
* 32-bit mode: dcache is always disabled(Due to some unknown issue);
|
|
|
|
|
*
|
|
|
|
|
* Command for U-Boot:
|
|
|
|
|
* 64-bit mode: MMU table is static defined in rkxxx.c file, all memory
|
|
|
|
|
* regions are mapped. That's good to match OP-TEE MMU policy.
|
|
|
|
|
*
|
|
|
|
|
* 32-bit mode: MMU table is setup according to gd->bd->bi_dram[..] where
|
|
|
|
|
* the OP-TEE region has been reserved, so it can not be
|
|
|
|
|
* mapped(i.e. dcache is disabled). That's also good to match
|
|
|
|
|
* OP-TEE MMU policy.
|
|
|
|
|
*
|
|
|
|
|
* For the data coherence when communication between U-Boot and OP-TEE, U-Boot
|
|
|
|
|
* should follow OP-TEE MMU policy.
|
|
|
|
|
*
|
|
|
|
|
* Here is the special:
|
|
|
|
|
* When CONFIG_ARM64_BOOT_AARCH32 is enabled, U-Boot is 32-bit mode while
|
|
|
|
|
* OP-TEE is still 64-bit mode. U-Boot would not map MMU table for OP-TEE
|
|
|
|
|
* region(but OP-TEE requires it cacheable) so we fixup here.
|
|
|
|
|
*/
|
|
|
|
|
int board_initr_caches_fixup(void)
|
|
|
|
|
{
|
|
|
|
|
struct memblock mem;
|
|
|
|
|
|
|
|
|
|
mem = param_parse_optee_mem();
|
|
|
|
|
if (mem.size)
|
|
|
|
|
mmu_set_region_dcache_behaviour(mem.base, mem.size,
|
|
|
|
|
DCACHE_WRITEBACK);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-12-10 09:51:46 +00:00
|
|
|
void board_quiesce_devices(void)
|
|
|
|
|
{
|
2019-01-13 11:48:19 +00:00
|
|
|
#ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
|
2018-12-10 09:51:46 +00:00
|
|
|
/* Destroy atags makes next warm boot safer */
|
|
|
|
|
atags_destroy();
|
2019-01-13 11:48:19 +00:00
|
|
|
#endif
|
2018-12-10 09:51:46 +00:00
|
|
|
}
|
|
|
|
|
|
2018-01-22 06:49:12 +00:00
|
|
|
void enable_caches(void)
|
|
|
|
|
{
|
2018-08-28 03:22:04 +00:00
|
|
|
icache_enable();
|
2018-01-22 06:49:12 +00:00
|
|
|
dcache_enable();
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-15 07:55:56 +00:00
|
|
|
#ifdef CONFIG_LMB
|
2018-11-02 03:35:19 +00:00
|
|
|
/*
|
|
|
|
|
* Using last bi_dram[...] to initialize "bootm_low" and "bootm_mapsize".
|
|
|
|
|
* This makes lmb_alloc_base() always alloc from tail of sdram.
|
|
|
|
|
* If we don't assign it, bi_dram[0] is used by default and it may cause
|
|
|
|
|
* lmb_alloc_base() fail when bi_dram[0] range is small.
|
|
|
|
|
*/
|
|
|
|
|
void board_lmb_reserve(struct lmb *lmb)
|
|
|
|
|
{
|
|
|
|
|
u64 start, size;
|
|
|
|
|
char bootm_low[32];
|
|
|
|
|
char bootm_mapsize[32];
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
|
|
|
|
|
if (!gd->bd->bi_dram[i].size)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start = gd->bd->bi_dram[i - 1].start;
|
|
|
|
|
size = gd->bd->bi_dram[i - 1].size;
|
|
|
|
|
|
|
|
|
|
/*
|
2018-11-15 07:55:56 +00:00
|
|
|
* 32-bit kernel: ramdisk/fdt shouldn't be loaded to highmem area(768MB+),
|
|
|
|
|
* otherwise "Unable to handle kernel paging request at virtual address ...".
|
|
|
|
|
*
|
|
|
|
|
* So that we hope limit highest address at 768M, but there comes the the
|
|
|
|
|
* problem: ramdisk is a compressed image and it expands after descompress,
|
|
|
|
|
* so it accesses 768MB+ and brings the above "Unable to handle kernel ...".
|
|
|
|
|
*
|
|
|
|
|
* We make a appointment that the highest memory address is 512MB, it
|
|
|
|
|
* makes lmb alloc safer.
|
2018-11-02 03:35:19 +00:00
|
|
|
*/
|
2018-11-15 07:55:56 +00:00
|
|
|
#ifndef CONFIG_ARM64
|
|
|
|
|
if (start >= ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M)) {
|
2018-11-02 03:35:19 +00:00
|
|
|
start = gd->bd->bi_dram[i - 2].start;
|
|
|
|
|
size = gd->bd->bi_dram[i - 2].size;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-15 07:55:56 +00:00
|
|
|
if ((start + size) > ((u64)CONFIG_SYS_SDRAM_BASE + SZ_512M))
|
|
|
|
|
size = (u64)CONFIG_SYS_SDRAM_BASE + SZ_512M - start;
|
2018-11-02 03:35:19 +00:00
|
|
|
#endif
|
|
|
|
|
sprintf(bootm_low, "0x%llx", start);
|
|
|
|
|
sprintf(bootm_mapsize, "0x%llx", size);
|
|
|
|
|
env_set("bootm_low", bootm_low);
|
|
|
|
|
env_set("bootm_mapsize", bootm_mapsize);
|
|
|
|
|
}
|
2018-11-15 07:55:56 +00:00
|
|
|
#endif
|
2018-11-02 03:35:19 +00:00
|
|
|
|
2019-01-13 11:48:19 +00:00
|
|
|
#if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \
|
|
|
|
|
defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS)
|
2018-10-09 11:45:00 +00:00
|
|
|
int board_init_f_init_serial(void)
|
|
|
|
|
{
|
|
|
|
|
struct tag *t = atags_get_tag(ATAG_SERIAL);
|
|
|
|
|
|
|
|
|
|
if (t) {
|
|
|
|
|
gd->serial.using_pre_serial = t->u.serial.enable;
|
|
|
|
|
gd->serial.addr = t->u.serial.addr;
|
|
|
|
|
gd->serial.baudrate = t->u.serial.baudrate;
|
|
|
|
|
gd->serial.id = t->u.serial.id;
|
|
|
|
|
|
|
|
|
|
debug("%s: enable=%d, addr=0x%lx, baudrate=%d, id=%d\n",
|
|
|
|
|
__func__, gd->serial.using_pre_serial,
|
|
|
|
|
gd->serial.addr, gd->serial.baudrate,
|
|
|
|
|
gd->serial.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-01-22 06:49:12 +00:00
|
|
|
#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
|
2018-05-23 06:08:17 +00:00
|
|
|
#include <fdt_support.h>
|
2018-01-22 06:49:12 +00:00
|
|
|
#include <usb.h>
|
|
|
|
|
#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)
|
|
|
|
|
{
|
|
|
|
|
int node;
|
2018-05-23 06:08:17 +00:00
|
|
|
fdt_addr_t addr;
|
|
|
|
|
const fdt32_t *reg;
|
2018-01-22 06:49:12 +00:00
|
|
|
const void *blob = gd->fdt_blob;
|
|
|
|
|
|
|
|
|
|
/* find the usb_otg node */
|
rockchip: board: rework board usb init
Currently, usb 2.0 otg node was found by the compatible
"snps,dwc2" and the property "dr_mode". However, the
"dr_mode" isn't a necessary condition, more seriously,
if the dr_mode is set to "host" or "peripheral", we
will fail to get the otg node.
This patch finds otg node by the compatible "snps,dwc2"
for most of Rockchip SoCs supported only one DWC2 controller.
For RK3288, it supports two DWC2 controllers with the
same compatible "snps,dwc2", so we add another condition
(reg addr = 0xff580000) to get the otg node.
Change-Id: I16acbf3e8da9bec19b8ec0a331b9114cb5462ac0
Signed-off-by: William Wu <william.wu@rock-chips.com>
2019-01-29 06:26:12 +00:00
|
|
|
node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2");
|
|
|
|
|
|
|
|
|
|
retry:
|
|
|
|
|
if (node > 0) {
|
|
|
|
|
reg = fdt_getprop(blob, node, "reg", NULL);
|
|
|
|
|
if (!reg)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
addr = fdt_translate_address(blob, node, reg);
|
|
|
|
|
if (addr == OF_BAD_ADDR) {
|
|
|
|
|
pr_err("Not found usb_otg address\n");
|
|
|
|
|
return -EINVAL;
|
2018-01-22 06:49:12 +00:00
|
|
|
}
|
|
|
|
|
|
rockchip: board: rework board usb init
Currently, usb 2.0 otg node was found by the compatible
"snps,dwc2" and the property "dr_mode". However, the
"dr_mode" isn't a necessary condition, more seriously,
if the dr_mode is set to "host" or "peripheral", we
will fail to get the otg node.
This patch finds otg node by the compatible "snps,dwc2"
for most of Rockchip SoCs supported only one DWC2 controller.
For RK3288, it supports two DWC2 controllers with the
same compatible "snps,dwc2", so we add another condition
(reg addr = 0xff580000) to get the otg node.
Change-Id: I16acbf3e8da9bec19b8ec0a331b9114cb5462ac0
Signed-off-by: William Wu <william.wu@rock-chips.com>
2019-01-29 06:26:12 +00:00
|
|
|
#if defined(CONFIG_ROCKCHIP_RK3288)
|
|
|
|
|
if (addr != 0xff580000) {
|
|
|
|
|
node = fdt_node_offset_by_compatible(blob, node,
|
|
|
|
|
"snps,dwc2");
|
|
|
|
|
goto retry;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
} else {
|
2018-07-09 00:55:21 +00:00
|
|
|
/*
|
|
|
|
|
* With kernel dtb support, rk3288 dwc2 otg node
|
|
|
|
|
* use the rockchip legacy dwc2 driver "dwc_otg_310"
|
2018-08-13 07:33:26 +00:00
|
|
|
* with the compatible "rockchip,rk3288_usb20_otg",
|
|
|
|
|
* and rk3368 also use the "dwc_otg_310" driver with
|
|
|
|
|
* the compatible "rockchip,rk3368-usb".
|
2018-07-09 00:55:21 +00:00
|
|
|
*/
|
2018-08-13 07:33:26 +00:00
|
|
|
#if defined(CONFIG_ROCKCHIP_RK3288)
|
2018-07-09 00:55:21 +00:00
|
|
|
node = fdt_node_offset_by_compatible(blob, -1,
|
|
|
|
|
"rockchip,rk3288_usb20_otg");
|
2018-08-13 07:33:26 +00:00
|
|
|
#elif defined(CONFIG_ROCKCHIP_RK3368)
|
|
|
|
|
node = fdt_node_offset_by_compatible(blob, -1,
|
|
|
|
|
"rockchip,rk3368-usb");
|
|
|
|
|
#endif
|
2018-07-09 00:55:21 +00:00
|
|
|
if (node > 0) {
|
rockchip: board: rework board usb init
Currently, usb 2.0 otg node was found by the compatible
"snps,dwc2" and the property "dr_mode". However, the
"dr_mode" isn't a necessary condition, more seriously,
if the dr_mode is set to "host" or "peripheral", we
will fail to get the otg node.
This patch finds otg node by the compatible "snps,dwc2"
for most of Rockchip SoCs supported only one DWC2 controller.
For RK3288, it supports two DWC2 controllers with the
same compatible "snps,dwc2", so we add another condition
(reg addr = 0xff580000) to get the otg node.
Change-Id: I16acbf3e8da9bec19b8ec0a331b9114cb5462ac0
Signed-off-by: William Wu <william.wu@rock-chips.com>
2019-01-29 06:26:12 +00:00
|
|
|
goto retry;
|
2018-07-09 00:55:21 +00:00
|
|
|
} else {
|
|
|
|
|
pr_err("Not found usb_otg device\n");
|
|
|
|
|
return -ENODEV;
|
|
|
|
|
}
|
2018-01-22 06:49:12 +00:00
|
|
|
}
|
2018-05-23 06:08:17 +00:00
|
|
|
|
|
|
|
|
otg_data.regs_otg = (uintptr_t)addr;
|
2018-01-22 06:49:12 +00:00
|
|
|
|
|
|
|
|
return dwc2_udc_probe(&otg_data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int board_usb_cleanup(int index, enum usb_init_type init)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|