1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2df9041ecSHeiko Stübner /* 3df9041ecSHeiko Stübner * (C) Copyright 2015 Google, Inc 4df9041ecSHeiko Stübner */ 5df9041ecSHeiko Stübner 6f4f57c58SHeiko Stübner #include <clk.h> 7df9041ecSHeiko Stübner #include <common.h> 8df9041ecSHeiko Stübner #include <debug_uart.h> 9df9041ecSHeiko Stübner #include <dm.h> 10df9041ecSHeiko Stübner #include <fdtdec.h> 11df9041ecSHeiko Stübner #include <led.h> 12df9041ecSHeiko Stübner #include <malloc.h> 13df9041ecSHeiko Stübner #include <ram.h> 14df9041ecSHeiko Stübner #include <spl.h> 15df9041ecSHeiko Stübner #include <asm/gpio.h> 16df9041ecSHeiko Stübner #include <asm/io.h> 17df9041ecSHeiko Stübner #include <asm/arch/bootrom.h> 18df9041ecSHeiko Stübner #include <asm/arch/clock.h> 19df9041ecSHeiko Stübner #include <asm/arch/hardware.h> 20df9041ecSHeiko Stübner #include <asm/arch/periph.h> 21df9041ecSHeiko Stübner #include <asm/arch/pmu_rk3188.h> 22df9041ecSHeiko Stübner #include <asm/arch/sdram.h> 23df9041ecSHeiko Stübner #include <asm/arch/timer.h> 24df9041ecSHeiko Stübner #include <dm/pinctrl.h> 25df9041ecSHeiko Stübner #include <dm/root.h> 26df9041ecSHeiko Stübner #include <dm/test.h> 27df9041ecSHeiko Stübner #include <dm/util.h> 28df9041ecSHeiko Stübner #include <power/regulator.h> 29df9041ecSHeiko Stübner #include <syscon.h> 30df9041ecSHeiko Stübner 31df9041ecSHeiko Stübner DECLARE_GLOBAL_DATA_PTR; 32df9041ecSHeiko Stübner 33df9041ecSHeiko Stübner u32 spl_boot_device(void) 34df9041ecSHeiko Stübner { 35df9041ecSHeiko Stübner #if !CONFIG_IS_ENABLED(OF_PLATDATA) 36df9041ecSHeiko Stübner const void *blob = gd->fdt_blob; 37df9041ecSHeiko Stübner struct udevice *dev; 38df9041ecSHeiko Stübner const char *bootdev; 39df9041ecSHeiko Stübner int node; 40df9041ecSHeiko Stübner int ret; 41df9041ecSHeiko Stübner 42df9041ecSHeiko Stübner bootdev = fdtdec_get_config_string(blob, "u-boot,boot0"); 43df9041ecSHeiko Stübner debug("Boot device %s\n", bootdev); 44df9041ecSHeiko Stübner if (!bootdev) 45df9041ecSHeiko Stübner goto fallback; 46df9041ecSHeiko Stübner 47df9041ecSHeiko Stübner node = fdt_path_offset(blob, bootdev); 48df9041ecSHeiko Stübner if (node < 0) { 49df9041ecSHeiko Stübner debug("node=%d\n", node); 50df9041ecSHeiko Stübner goto fallback; 51df9041ecSHeiko Stübner } 52df9041ecSHeiko Stübner ret = device_get_global_by_of_offset(node, &dev); 53df9041ecSHeiko Stübner if (ret) { 54df9041ecSHeiko Stübner debug("device at node %s/%d not found: %d\n", bootdev, node, 55df9041ecSHeiko Stübner ret); 56df9041ecSHeiko Stübner goto fallback; 57df9041ecSHeiko Stübner } 58df9041ecSHeiko Stübner debug("Found device %s\n", dev->name); 59df9041ecSHeiko Stübner switch (device_get_uclass_id(dev)) { 60df9041ecSHeiko Stübner case UCLASS_SPI_FLASH: 61df9041ecSHeiko Stübner return BOOT_DEVICE_SPI; 62df9041ecSHeiko Stübner case UCLASS_MMC: 63df9041ecSHeiko Stübner return BOOT_DEVICE_MMC1; 64df9041ecSHeiko Stübner default: 65df9041ecSHeiko Stübner debug("Booting from device uclass '%s' not supported\n", 66df9041ecSHeiko Stübner dev_get_uclass_name(dev)); 67df9041ecSHeiko Stübner } 68df9041ecSHeiko Stübner 69df9041ecSHeiko Stübner fallback: 70df9041ecSHeiko Stübner #endif 71df9041ecSHeiko Stübner return BOOT_DEVICE_MMC1; 72df9041ecSHeiko Stübner } 73df9041ecSHeiko Stübner 74f4f57c58SHeiko Stübner static int setup_arm_clock(void) 75f4f57c58SHeiko Stübner { 76f4f57c58SHeiko Stübner struct udevice *dev; 77f4f57c58SHeiko Stübner struct clk clk; 78f4f57c58SHeiko Stübner int ret; 79f4f57c58SHeiko Stübner 80f4f57c58SHeiko Stübner ret = rockchip_get_clk(&dev); 81f4f57c58SHeiko Stübner if (ret) 82f4f57c58SHeiko Stübner return ret; 83f4f57c58SHeiko Stübner 84f4f57c58SHeiko Stübner clk.id = CLK_ARM; 85f4f57c58SHeiko Stübner ret = clk_request(dev, &clk); 86f4f57c58SHeiko Stübner if (ret < 0) 87f4f57c58SHeiko Stübner return ret; 88f4f57c58SHeiko Stübner 89f4f57c58SHeiko Stübner ret = clk_set_rate(&clk, 600000000); 90f4f57c58SHeiko Stübner 91f4f57c58SHeiko Stübner clk_free(&clk); 92f4f57c58SHeiko Stübner return ret; 93f4f57c58SHeiko Stübner } 94f4f57c58SHeiko Stübner 95df9041ecSHeiko Stübner void board_init_f(ulong dummy) 96df9041ecSHeiko Stübner { 97df9041ecSHeiko Stübner struct udevice *pinctrl, *dev; 98df9041ecSHeiko Stübner int ret; 99df9041ecSHeiko Stübner 100df9041ecSHeiko Stübner /* Example code showing how to enable the debug UART on RK3188 */ 101df9041ecSHeiko Stübner #ifdef EARLY_UART 102df9041ecSHeiko Stübner #include <asm/arch/grf_rk3188.h> 103df9041ecSHeiko Stübner /* Enable early UART on the RK3188 */ 104df9041ecSHeiko Stübner #define GRF_BASE 0x20008000 105df9041ecSHeiko Stübner struct rk3188_grf * const grf = (void *)GRF_BASE; 106df9041ecSHeiko Stübner 107df9041ecSHeiko Stübner rk_clrsetreg(&grf->gpio1b_iomux, 108df9041ecSHeiko Stübner GPIO1B1_MASK << GPIO1B1_SHIFT | 109df9041ecSHeiko Stübner GPIO1B0_MASK << GPIO1B0_SHIFT, 110df9041ecSHeiko Stübner GPIO1B1_UART2_SOUT << GPIO1B1_SHIFT | 111df9041ecSHeiko Stübner GPIO1B0_UART2_SIN << GPIO1B0_SHIFT); 112df9041ecSHeiko Stübner /* 113df9041ecSHeiko Stübner * Debug UART can be used from here if required: 114df9041ecSHeiko Stübner * 115df9041ecSHeiko Stübner * debug_uart_init(); 116df9041ecSHeiko Stübner * printch('a'); 117df9041ecSHeiko Stübner * printhex8(0x1234); 118df9041ecSHeiko Stübner * printascii("string"); 119df9041ecSHeiko Stübner */ 120df9041ecSHeiko Stübner debug_uart_init(); 121df9041ecSHeiko Stübner printch('s'); 122df9041ecSHeiko Stübner printch('p'); 123df9041ecSHeiko Stübner printch('l'); 124df9041ecSHeiko Stübner printch('\n'); 125df9041ecSHeiko Stübner #endif 126df9041ecSHeiko Stübner 127232cf962SKever Yang ret = spl_early_init(); 128df9041ecSHeiko Stübner if (ret) { 129232cf962SKever Yang debug("spl_early_init() failed: %d\n", ret); 130df9041ecSHeiko Stübner hang(); 131df9041ecSHeiko Stübner } 132df9041ecSHeiko Stübner 133df9041ecSHeiko Stübner ret = rockchip_get_clk(&dev); 134df9041ecSHeiko Stübner if (ret) { 135df9041ecSHeiko Stübner debug("CLK init failed: %d\n", ret); 136df9041ecSHeiko Stübner return; 137df9041ecSHeiko Stübner } 138df9041ecSHeiko Stübner 139df9041ecSHeiko Stübner ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 140df9041ecSHeiko Stübner if (ret) { 141df9041ecSHeiko Stübner debug("Pinctrl init failed: %d\n", ret); 142df9041ecSHeiko Stübner return; 143df9041ecSHeiko Stübner } 144df9041ecSHeiko Stübner 145df9041ecSHeiko Stübner ret = uclass_get_device(UCLASS_RAM, 0, &dev); 146df9041ecSHeiko Stübner if (ret) { 147df9041ecSHeiko Stübner debug("DRAM init failed: %d\n", ret); 148df9041ecSHeiko Stübner return; 149df9041ecSHeiko Stübner } 150df9041ecSHeiko Stübner 151f4f57c58SHeiko Stübner setup_arm_clock(); 152ee14d29dSPhilipp Tomsich #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) 153b82bd1f8SPhilipp Tomsich back_to_bootrom(BROM_BOOT_NEXTSTAGE); 154df9041ecSHeiko Stübner #endif 155df9041ecSHeiko Stübner } 156df9041ecSHeiko Stübner 157df9041ecSHeiko Stübner static int setup_led(void) 158df9041ecSHeiko Stübner { 159df9041ecSHeiko Stübner #ifdef CONFIG_SPL_LED 160df9041ecSHeiko Stübner struct udevice *dev; 161df9041ecSHeiko Stübner char *led_name; 162df9041ecSHeiko Stübner int ret; 163df9041ecSHeiko Stübner 164df9041ecSHeiko Stübner led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led"); 165df9041ecSHeiko Stübner if (!led_name) 166df9041ecSHeiko Stübner return 0; 167df9041ecSHeiko Stübner ret = led_get_by_label(led_name, &dev); 168df9041ecSHeiko Stübner if (ret) { 169df9041ecSHeiko Stübner debug("%s: get=%d\n", __func__, ret); 170df9041ecSHeiko Stübner return ret; 171df9041ecSHeiko Stübner } 172df9041ecSHeiko Stübner ret = led_set_on(dev, 1); 173df9041ecSHeiko Stübner if (ret) 174df9041ecSHeiko Stübner return ret; 175df9041ecSHeiko Stübner #endif 176df9041ecSHeiko Stübner 177df9041ecSHeiko Stübner return 0; 178df9041ecSHeiko Stübner } 179df9041ecSHeiko Stübner 180df9041ecSHeiko Stübner void spl_board_init(void) 181df9041ecSHeiko Stübner { 182df9041ecSHeiko Stübner struct udevice *pinctrl; 183df9041ecSHeiko Stübner int ret; 184df9041ecSHeiko Stübner 185df9041ecSHeiko Stübner ret = setup_led(); 186df9041ecSHeiko Stübner if (ret) { 187df9041ecSHeiko Stübner debug("LED ret=%d\n", ret); 188df9041ecSHeiko Stübner hang(); 189df9041ecSHeiko Stübner } 190df9041ecSHeiko Stübner 191df9041ecSHeiko Stübner ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 192df9041ecSHeiko Stübner if (ret) { 193df9041ecSHeiko Stübner debug("%s: Cannot find pinctrl device\n", __func__); 194df9041ecSHeiko Stübner goto err; 195df9041ecSHeiko Stübner } 196df9041ecSHeiko Stübner 197df9041ecSHeiko Stübner #ifdef CONFIG_SPL_MMC_SUPPORT 198df9041ecSHeiko Stübner ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); 199df9041ecSHeiko Stübner if (ret) { 200df9041ecSHeiko Stübner debug("%s: Failed to set up SD card\n", __func__); 201df9041ecSHeiko Stübner goto err; 202df9041ecSHeiko Stübner } 203df9041ecSHeiko Stübner #endif 204df9041ecSHeiko Stübner 205df9041ecSHeiko Stübner /* Enable debug UART */ 206df9041ecSHeiko Stübner ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG); 207df9041ecSHeiko Stübner if (ret) { 208df9041ecSHeiko Stübner debug("%s: Failed to set up console UART\n", __func__); 209df9041ecSHeiko Stübner goto err; 210df9041ecSHeiko Stübner } 211df9041ecSHeiko Stübner 212df9041ecSHeiko Stübner preloader_console_init(); 213ee14d29dSPhilipp Tomsich #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) 214b82bd1f8SPhilipp Tomsich back_to_bootrom(BROM_BOOT_NEXTSTAGE); 215df9041ecSHeiko Stübner #endif 216df9041ecSHeiko Stübner return; 217df9041ecSHeiko Stübner 218df9041ecSHeiko Stübner err: 219df9041ecSHeiko Stübner printf("spl_board_init: Error %d\n", ret); 220df9041ecSHeiko Stübner 221df9041ecSHeiko Stübner /* No way to report error here */ 222df9041ecSHeiko Stübner hang(); 223df9041ecSHeiko Stübner } 224