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

Message ID 20170203160939.27594-15-heiko@sntech.de
State Superseded
Delegated to: Simon Glass
Headers show

Commit Message

Heiko Stuebner Feb. 3, 2017, 4:09 p.m. UTC
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

Comments

Simon Glass Feb. 6, 2017, 3:35 p.m. UTC | #1
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
Heiko Stuebner Feb. 11, 2017, 12:47 a.m. UTC | #2
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

Patch
diff mbox

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