Message ID | 20170203160939.27594-15-heiko@sntech.de |
---|---|
State | Superseded |
Delegated to: | Simon Glass |
Headers | show |
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
Am Montag, 6. Februar 2017, 07:35:25 CET schrieb Simon Glass: > 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? not sure about that. In the end the amount of code is not that much - essentially the setup_led() and spl_board_init() could be unified a bit, but then spl_board_init() would probably require empty functions for not implemented stuff - configure_emmc on rk3188 for example. So I'm not sure if this would help or just makes everything more complicated. > > > 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"); actually using printascii at this point make the board hang in the past. So far I haven't figured out why printch works but printascii does not. I'll try again, maybe it magically fixed itself > > +#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? ok, I'll give that a try. So far I've never reached linker stuff, but judging from other uboot code a " __attribute__ ((section(".data")))" should be sufficient? > > > +extern void back_to_bootrom(void); > > Should be in a header file somewhere So far each board has declared this itself, but I've moved it to a header now for all of them. > > + > > +#define PMU_BASE 0x20004000 > > +#define TPL_ENTRY 0x10080C00 > > +extern u32 SAVE_SP_ADDR; I've also moved this to my new bootrom.h > > Blank line ok > > +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() see spl printascii comment :-) > > > + 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; yep, I plan on doing this once the jump from spl to uboot actually works :-) > > + > > + 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
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'); +#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; +extern void back_to_bootrom(void); + +#define PMU_BASE 0x20004000 +#define TPL_ENTRY 0x10080C00 +extern u32 SAVE_SP_ADDR; +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('-'); + 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 */ + 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
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. Signed-off-by: Heiko Stuebner <heiko@sntech.de> --- arch/arm/mach-rockchip/Makefile | 7 +- arch/arm/mach-rockchip/rk3188-board-spl.c | 220 ++++++++++++++++++++++++++++++ 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