rockchip: rk3188: Add main, spl and tpl boards

A patch from »rk3188 uboot support« in state Mainline for u-boot

From: Heiko Stuebner <heiko@...> Date: Sun, 29 Jan 2017 21:14:09 +0100

Commit-Message

The rk3188 needs 3 U-Boot stages: a tpl living in 1KB of sram, a spl the resides in the rest of the sram and loads the regular U-Boot living in regular ram. Signed-off-by: Heiko Stuebner <heiko@...> Tested-by: Kever Yang <kever.yang@...>

Patch-Comment

arch/arm/mach-rockchip/Makefile | 7 +- arch/arm/mach-rockchip/rk3188-board-spl.c | 218 ++++++++++++++++++++++++++++++ arch/arm/mach-rockchip/rk3188-board-tpl.c | 86 ++++++++++++ arch/arm/mach-rockchip/rk3188-board.c | 71 ++++++++++ 4 files changed, 381 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

Statistics

  • 381 lines added
  • 1 lines removed

Changes

----------------------- arch/arm/mach-rockchip/Makefile ------------------------
index 2be7e14e3e..7b8abc2266 100644
@@ -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
------------------ arch/arm/mach-rockchip/rk3188-board-spl.c -------------------
new file mode 100644
index 0000000000..f93feae0c9
@@ -0,0 +1,218 @@
+/*
+ * (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/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;
+}
+
+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_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();
+}
------------------ arch/arm/mach-rockchip/rk3188-board-tpl.c -------------------
new file mode 100644
index 0000000000..442bfe7aa7
@@ -0,0 +1,86 @@
+/*
+ * (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/bootrom.h>
+#include <asm/arch/pmu_rk3188.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* track how often we were entered */
+static int rk3188_num_entries __attribute__ ((section(".data")));
+
+#define PMU_BASE 0x20004000
+#define TPL_ENTRY 0x10080C00
+
+static void jump_to_spl(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)
+{
+ /* 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_spl();
+ }
+}
-------------------- arch/arm/mach-rockchip/rk3188-board.c ---------------------
new file mode 100644
index 0000000000..16f38559af
@@ -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
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...