[U-Boot] [PATCH v3 14/16] rockchip: rk3188: Add main, spl and tpl boards

Simon Glass
2017-02-06T15:35:25Z

Hi Heiko,

On 3 February 2017 at 08:09, Heiko Stuebner <heiko@sntech.de> wrote:
> The rk3188 needs 3 uboot stages: a tpl living in 1KB of sram, a spl
> the resides in the rest of the sram and loads the regular uboot living
> in regular ram.

s/uboot/U-Boot/

>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
> arch/arm/mach-rockchip/Makefile | 7 +-
> arch/arm/mach-rockchip/rk3188-board-spl.c | 220 ++++++++++++++++++++++++++++++

There is a lot of common code here with rk3288 - can we unify it a
bit, or is that not feasible?

> arch/arm/mach-rockchip/rk3188-board-tpl.c | 87 ++++++++++++
> arch/arm/mach-rockchip/rk3188-board.c | 71 ++++++++++
> 4 files changed, 384 insertions(+), 1 deletion(-)
> create mode 100644 arch/arm/mach-rockchip/rk3188-board-spl.c
> create mode 100644 arch/arm/mach-rockchip/rk3188-board-tpl.c
> create mode 100644 arch/arm/mach-rockchip/rk3188-board.c
>
> diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
> index 2be7e14e3e..7b8abc2266 100644
> --- a/arch/arm/mach-rockchip/Makefile
> +++ b/arch/arm/mach-rockchip/Makefile
> @@ -4,11 +4,16 @@
> # SPDX-License-Identifier: GPL-2.0+
> #
>
> -ifdef CONFIG_SPL_BUILD
> +ifdef CONFIG_TPL_BUILD
> +obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-tpl.o
> +obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
> +else ifdef CONFIG_SPL_BUILD
> obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board-spl.o
> +obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board-spl.o
> obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board-spl.o
> obj-$(CONFIG_ROCKCHIP_BROM_HELPER) += save_boot_param.o
> else
> +obj-$(CONFIG_ROCKCHIP_RK3188) += rk3188-board.o
> obj-$(CONFIG_ROCKCHIP_RK3288) += rk3288-board.o
> obj-$(CONFIG_ROCKCHIP_RK3036) += rk3036-board.o
> endif
> diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c
> new file mode 100644
> index 0000000000..b528a2f73d
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3188-board-spl.c
> @@ -0,0 +1,220 @@
> +/*
> + * (C) Copyright 2015 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#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/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;
> +}
> +
> +extern u32 SAVE_SP_ADDR;
> +extern void back_to_bootrom(void);
> +void board_init_f(ulong dummy)
> +{
> + struct udevice *pinctrl, *dev;
> + struct rk3188_pmu *pmu;
> + int ret;
> +
> +#define EARLY_UART
> + /* 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');

printascii("spl\n");

> +#endif
> +
> + ret = spl_init();
> + if (ret) {
> + debug("spl_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;
> + }
> +
> +#if defined(CONFIG_ROCKCHIP_SPL_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();
> +#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
> + back_to_bootrom();
> +#endif
> + return;
> +
> +err:
> + printf("spl_board_init: Error %d\n", ret);
> +
> + /* No way to report error here */
> + hang();
> +}
> diff --git a/arch/arm/mach-rockchip/rk3188-board-tpl.c b/arch/arm/mach-rockchip/rk3188-board-tpl.c
> new file mode 100644
> index 0000000000..62cdb8976a
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3188-board-tpl.c
> @@ -0,0 +1,87 @@
> +/*
> + * (C) Copyright 2015 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <debug_uart.h>
> +#include <spl.h>
> +#include <asm/io.h>
> +#include <asm/arch/pmu_rk3188.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* track how often we were entered */
> +static int rk3188_num_entries;

Is this in BSS? I suspect it might cause problems. Perhaps put it in
the data section?

> +extern void back_to_bootrom(void);

Should be in a header file somewhere

> +
> +#define PMU_BASE 0x20004000
> +#define TPL_ENTRY 0x10080C00
> +extern u32 SAVE_SP_ADDR;

Blank line

> +static void jump_to_tpl(void)
> +{
> + typedef void __noreturn (*image_entry_noargs_t)(void);
> +
> + struct rk3188_pmu * const pmu = (void *)PMU_BASE;
> + image_entry_noargs_t tpl_entry =
> + (image_entry_noargs_t)(unsigned long)TPL_ENTRY;
> +
> + /* Store the SAVE_SP_ADDR in a location shared with TPL. */
> + writel(SAVE_SP_ADDR, &pmu->sys_reg[2]);
> + tpl_entry();
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +#define EARLY_UART
> + /* 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('t');
> + printch('p');
> + printch('l');
> + printch('-');

printascii()

> + printch(rk3188_num_entries + 1 + '0');
> + printch('\n');
> +#endif
> +
> + rk3188_num_entries++;
> +
> + if (rk3188_num_entries == 1) {
> + /*
> + * The original loader did some very basic integrity
> + * checking at this point, but the remaining few bytes
> + * could be used for any improvement making sense
> + * really early on.
> + */
> +
> + back_to_bootrom();
> + } else {
> + /*
> + * TPL part of the loader should now wait for us
> + * at offset 0xC00 in the sram. Should never return
> + * from there.
> + */
> + jump_to_tpl();
> + }
> +}
> diff --git a/arch/arm/mach-rockchip/rk3188-board.c b/arch/arm/mach-rockchip/rk3188-board.c
> new file mode 100644
> index 0000000000..16f38559af
> --- /dev/null
> +++ b/arch/arm/mach-rockchip/rk3188-board.c
> @@ -0,0 +1,71 @@
> +/*
> + * (C) Copyright 2015 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <ram.h>
> +#include <syscon.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/periph.h>
> +#include <asm/arch/pmu_rk3288.h>
> +#include <asm/arch/boot_mode.h>
> +#include <asm/gpio.h>
> +#include <dm/pinctrl.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int board_init(void)
> +{
> +#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM)
> + struct udevice *pinctrl;
> + int ret;
> +
> + /*
> + * We need to implement sdcard iomux here for the further
> + * initialization, otherwise, it'll hit sdcard command sending
> + * timeout exception.
> + */
> + ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
> + if (ret) {
> + debug("%s: Cannot find pinctrl device\n", __func__);
> + goto err;
> + }
> + ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
> + if (ret) {
> + debug("%s: Failed to set up SD card\n", __func__);
> + goto err;
> + }
> +
> + return 0;
> +err:
> + printf("board_init: Error %d\n", ret);
> +
> + /* No way to report error here */
> + hang();
> +
> + return -1;
> +#else
> + return 0;
> +#endif
> +}
> +
> +int dram_init(void)
> +{
> + /* FIXME: read back ram size from sys_reg2 */

TODO(email):

> + gd->ram_size = 0x40000000;
> +
> + return 0;
> +}
> +
> +#ifndef CONFIG_SYS_DCACHE_OFF
> +void enable_caches(void)
> +{
> + /* Enable D-cache. I-cache is already enabled in start.S */
> + dcache_enable();
> +}
> +#endif
> --
> 2.11.0
>

Regards,
Simon