u-boot/arch/arm/mach-rockchip/rk3188-board-spl.c
Philipp Tomsich ee14d29db0 rockchip: back-to-bootrom: split BACK_TO_BOOTROM for TPL/SPL
The back-to-bootrom option is rather unfortunately named
  CONFIG_ROCKCHIP_SPL_BACK_TO_BOOTROM
instead of
  CONFIG_SPL_ROCKCHIP_BACK_TO_BOOTROM

To make is selectable through CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BOOTROM),
we need to rename it.  At the same time, we introduce a TPL_ variant of
the option to give us finer-grained control over when it should be used.

This change is motivated by our RK3368 boot process, which returns to
the boot ROM only from the TPL stage, but not from the SPL stage.

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
[added fix-up for evb-rk3229_defconfig and phycore-rk3288_defconfig:]
[fixed inverted CONFIG_IS_ENABLED test for rk3288:]
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>

include/configs/rock.h: undef
2017-08-13 17:12:19 +02:00

241 lines
4.7 KiB
C

/*
* (C) Copyright 2015 Google, Inc
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <clk.h>
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <fdtdec.h>
#include <led.h>
#include <malloc.h>
#include <ram.h>
#include <spl.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/bootrom.h>
#include <asm/arch/clock.h>
#include <asm/arch/hardware.h>
#include <asm/arch/periph.h>
#include <asm/arch/pmu_rk3188.h>
#include <asm/arch/sdram.h>
#include <asm/arch/timer.h>
#include <dm/pinctrl.h>
#include <dm/root.h>
#include <dm/test.h>
#include <dm/util.h>
#include <power/regulator.h>
#include <syscon.h>
DECLARE_GLOBAL_DATA_PTR;
u32 spl_boot_device(void)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
const void *blob = gd->fdt_blob;
struct udevice *dev;
const char *bootdev;
int node;
int ret;
bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
debug("Boot device %s\n", bootdev);
if (!bootdev)
goto fallback;
node = fdt_path_offset(blob, bootdev);
if (node < 0) {
debug("node=%d\n", node);
goto fallback;
}
ret = device_get_global_by_of_offset(node, &dev);
if (ret) {
debug("device at node %s/%d not found: %d\n", bootdev, node,
ret);
goto fallback;
}
debug("Found device %s\n", dev->name);
switch (device_get_uclass_id(dev)) {
case UCLASS_SPI_FLASH:
return BOOT_DEVICE_SPI;
case UCLASS_MMC:
return BOOT_DEVICE_MMC1;
default:
debug("Booting from device uclass '%s' not supported\n",
dev_get_uclass_name(dev));
}
fallback:
#endif
return BOOT_DEVICE_MMC1;
}
u32 spl_boot_mode(const u32 boot_device)
{
return MMCSD_MODE_RAW;
}
static int setup_arm_clock(void)
{
struct udevice *dev;
struct clk clk;
int ret;
ret = rockchip_get_clk(&dev);
if (ret)
return ret;
clk.id = CLK_ARM;
ret = clk_request(dev, &clk);
if (ret < 0)
return ret;
ret = clk_set_rate(&clk, 600000000);
clk_free(&clk);
return ret;
}
void board_init_f(ulong dummy)
{
struct udevice *pinctrl, *dev;
struct rk3188_pmu *pmu;
int ret;
/* Example code showing how to enable the debug UART on RK3188 */
#ifdef EARLY_UART
#include <asm/arch/grf_rk3188.h>
/* Enable early UART on the RK3188 */
#define GRF_BASE 0x20008000
struct rk3188_grf * const grf = (void *)GRF_BASE;
rk_clrsetreg(&grf->gpio1b_iomux,
GPIO1B1_MASK << GPIO1B1_SHIFT |
GPIO1B0_MASK << GPIO1B0_SHIFT,
GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT |
GPIO1B0_UART2_SIN << GPIO1B0_SHIFT);
/*
* Debug UART can be used from here if required:
*
* debug_uart_init();
* printch('a');
* printhex8(0x1234);
* printascii("string");
*/
debug_uart_init();
printch('s');
printch('p');
printch('l');
printch('\n');
#endif
ret = spl_early_init();
if (ret) {
debug("spl_early_init() failed: %d\n", ret);
hang();
}
rockchip_timer_init();
ret = rockchip_get_clk(&dev);
if (ret) {
debug("CLK init failed: %d\n", ret);
return;
}
/*
* Recover the bootrom's stackpointer.
* For whatever reason needs to run after rockchip_get_clk.
*/
pmu = syscon_get_first_range(ROCKCHIP_SYSCON_PMU);
if (IS_ERR(pmu))
error("pmu syscon returned %ld\n", PTR_ERR(pmu));
SAVE_SP_ADDR = readl(&pmu->sys_reg[2]);
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("Pinctrl init failed: %d\n", ret);
return;
}
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
return;
}
setup_arm_clock();
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
back_to_bootrom();
#endif
}
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)
{
struct udevice *pinctrl;
int ret;
ret = setup_led();
if (ret) {
debug("LED ret=%d\n", ret);
hang();
}
ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
if (ret) {
debug("%s: Cannot find pinctrl device\n", __func__);
goto err;
}
#ifdef CONFIG_SPL_MMC_SUPPORT
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
if (ret) {
debug("%s: Failed to set up SD card\n", __func__);
goto err;
}
#endif
/* Enable debug UART */
ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
if (ret) {
debug("%s: Failed to set up console UART\n", __func__);
goto err;
}
preloader_console_init();
#if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
back_to_bootrom();
#endif
return;
err:
printf("spl_board_init: Error %d\n", ret);
/* No way to report error here */
hang();
}