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