1 /* 2 * (C) Copyright 2015 Google, Inc 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <debug_uart.h> 9 #include <dm.h> 10 #include <fdtdec.h> 11 #include <i2c.h> 12 #include <led.h> 13 #include <malloc.h> 14 #include <ram.h> 15 #include <spl.h> 16 #include <asm/gpio.h> 17 #include <asm/io.h> 18 #include <asm/arch/bootrom.h> 19 #include <asm/arch/clock.h> 20 #include <asm/arch/hardware.h> 21 #include <asm/arch/periph.h> 22 #include <asm/arch/sdram.h> 23 #include <asm/arch/timer.h> 24 #include <dm/pinctrl.h> 25 #include <dm/root.h> 26 #include <dm/test.h> 27 #include <dm/util.h> 28 #include <power/regulator.h> 29 #include <power/rk8xx_pmic.h> 30 31 DECLARE_GLOBAL_DATA_PTR; 32 33 u32 spl_boot_device(void) 34 { 35 #if !CONFIG_IS_ENABLED(OF_PLATDATA) 36 const void *blob = gd->fdt_blob; 37 struct udevice *dev; 38 const char *bootdev; 39 int node; 40 int ret; 41 42 bootdev = fdtdec_get_config_string(blob, "u-boot,boot0"); 43 debug("Boot device %s\n", bootdev); 44 if (!bootdev) 45 goto fallback; 46 47 node = fdt_path_offset(blob, bootdev); 48 if (node < 0) { 49 debug("node=%d\n", node); 50 goto fallback; 51 } 52 ret = device_get_global_by_of_offset(node, &dev); 53 if (ret) { 54 debug("device at node %s/%d not found: %d\n", bootdev, node, 55 ret); 56 goto fallback; 57 } 58 debug("Found device %s\n", dev->name); 59 switch (device_get_uclass_id(dev)) { 60 case UCLASS_SPI_FLASH: 61 return BOOT_DEVICE_SPI; 62 case UCLASS_MMC: 63 return BOOT_DEVICE_MMC1; 64 default: 65 debug("Booting from device uclass '%s' not supported\n", 66 dev_get_uclass_name(dev)); 67 } 68 69 fallback: 70 #elif defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ 71 defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \ 72 defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) 73 return BOOT_DEVICE_SPI; 74 #endif 75 return BOOT_DEVICE_MMC1; 76 } 77 78 u32 spl_boot_mode(const u32 boot_device) 79 { 80 return MMCSD_MODE_RAW; 81 } 82 83 /* read L2 control register (L2CTLR) */ 84 static inline uint32_t read_l2ctlr(void) 85 { 86 uint32_t val = 0; 87 88 asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val)); 89 90 return val; 91 } 92 93 /* write L2 control register (L2CTLR) */ 94 static inline void write_l2ctlr(uint32_t val) 95 { 96 /* 97 * Note: L2CTLR can only be written when the L2 memory system 98 * is idle, ie before the MMU is enabled. 99 */ 100 asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory"); 101 isb(); 102 } 103 104 static void configure_l2ctlr(void) 105 { 106 uint32_t l2ctlr; 107 108 l2ctlr = read_l2ctlr(); 109 l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */ 110 111 /* 112 * Data RAM write latency: 2 cycles 113 * Data RAM read latency: 2 cycles 114 * Data RAM setup latency: 1 cycle 115 * Tag RAM write latency: 1 cycle 116 * Tag RAM read latency: 1 cycle 117 * Tag RAM setup latency: 1 cycle 118 */ 119 l2ctlr |= (1 << 3 | 1 << 0); 120 write_l2ctlr(l2ctlr); 121 } 122 123 #ifdef CONFIG_SPL_MMC_SUPPORT 124 static int configure_emmc(struct udevice *pinctrl) 125 { 126 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) 127 128 struct gpio_desc desc; 129 int ret; 130 131 pinctrl_request_noflags(pinctrl, PERIPH_ID_EMMC); 132 133 /* 134 * TODO(sjg@chromium.org): Pick this up from device tree or perhaps 135 * use the EMMC_PWREN setting. 136 */ 137 ret = dm_gpio_lookup_name("D9", &desc); 138 if (ret) { 139 debug("gpio ret=%d\n", ret); 140 return ret; 141 } 142 ret = dm_gpio_request(&desc, "emmc_pwren"); 143 if (ret) { 144 debug("gpio_request ret=%d\n", ret); 145 return ret; 146 } 147 ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); 148 if (ret) { 149 debug("gpio dir ret=%d\n", ret); 150 return ret; 151 } 152 ret = dm_gpio_set_value(&desc, 1); 153 if (ret) { 154 debug("gpio value ret=%d\n", ret); 155 return ret; 156 } 157 #endif 158 return 0; 159 } 160 #endif 161 162 #if !defined(CONFIG_SPL_OF_PLATDATA) 163 static int phycore_init(void) 164 { 165 struct udevice *pmic; 166 int ret; 167 168 ret = uclass_first_device_err(UCLASS_PMIC, &pmic); 169 if (ret) 170 return ret; 171 172 #if defined(CONFIG_SPL_POWER_SUPPORT) 173 /* Increase USB input current to 2A */ 174 ret = rk818_spl_configure_usb_input_current(pmic, 2000); 175 if (ret) 176 return ret; 177 178 /* Close charger when USB lower then 3.26V */ 179 ret = rk818_spl_configure_usb_chrg_shutdown(pmic, 3260000); 180 if (ret) 181 return ret; 182 #endif 183 184 return 0; 185 } 186 #endif 187 188 void board_init_f(ulong dummy) 189 { 190 struct udevice *pinctrl; 191 struct udevice *dev; 192 int ret; 193 194 /* Example code showing how to enable the debug UART on RK3288 */ 195 #include <asm/arch/grf_rk3288.h> 196 /* Enable early UART on the RK3288 */ 197 #define GRF_BASE 0xff770000 198 struct rk3288_grf * const grf = (void *)GRF_BASE; 199 200 rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT | 201 GPIO7C6_MASK << GPIO7C6_SHIFT, 202 GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT | 203 GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT); 204 /* 205 * Debug UART can be used from here if required: 206 * 207 * debug_uart_init(); 208 * printch('a'); 209 * printhex8(0x1234); 210 * printascii("string"); 211 */ 212 debug_uart_init(); 213 debug("\nspl:debug uart enabled in %s\n", __func__); 214 ret = spl_early_init(); 215 if (ret) { 216 debug("spl_early_init() failed: %d\n", ret); 217 hang(); 218 } 219 220 rockchip_timer_init(); 221 configure_l2ctlr(); 222 223 ret = rockchip_get_clk(&dev); 224 if (ret) { 225 debug("CLK init failed: %d\n", ret); 226 return; 227 } 228 229 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 230 if (ret) { 231 debug("Pinctrl init failed: %d\n", ret); 232 return; 233 } 234 235 #if !defined(CONFIG_SPL_OF_PLATDATA) 236 if (of_machine_is_compatible("phytec,rk3288-phycore-som")) { 237 ret = phycore_init(); 238 if (ret) { 239 debug("Failed to set up phycore power settings: %d\n", 240 ret); 241 return; 242 } 243 } 244 #endif 245 246 debug("\nspl:init dram\n"); 247 ret = uclass_get_device(UCLASS_RAM, 0, &dev); 248 if (ret) { 249 debug("DRAM init failed: %d\n", ret); 250 return; 251 } 252 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT) 253 back_to_bootrom(); 254 #endif 255 } 256 257 static int setup_led(void) 258 { 259 #ifdef CONFIG_SPL_LED 260 struct udevice *dev; 261 char *led_name; 262 int ret; 263 264 led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led"); 265 if (!led_name) 266 return 0; 267 ret = led_get_by_label(led_name, &dev); 268 if (ret) { 269 debug("%s: get=%d\n", __func__, ret); 270 return ret; 271 } 272 ret = led_set_on(dev, 1); 273 if (ret) 274 return ret; 275 #endif 276 277 return 0; 278 } 279 280 void spl_board_init(void) 281 { 282 struct udevice *pinctrl; 283 int ret; 284 285 ret = setup_led(); 286 287 if (ret) { 288 debug("LED ret=%d\n", ret); 289 hang(); 290 } 291 292 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); 293 if (ret) { 294 debug("%s: Cannot find pinctrl device\n", __func__); 295 goto err; 296 } 297 298 #ifdef CONFIG_SPL_MMC_SUPPORT 299 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD); 300 if (ret) { 301 debug("%s: Failed to set up SD card\n", __func__); 302 goto err; 303 } 304 ret = configure_emmc(pinctrl); 305 if (ret) { 306 debug("%s: Failed to set up eMMC\n", __func__); 307 goto err; 308 } 309 #endif 310 311 /* Enable debug UART */ 312 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG); 313 if (ret) { 314 debug("%s: Failed to set up console UART\n", __func__); 315 goto err; 316 } 317 318 preloader_console_init(); 319 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) 320 back_to_bootrom(); 321 #endif 322 return; 323 err: 324 printf("spl_board_init: Error %d\n", ret); 325 326 /* No way to report error here */ 327 hang(); 328 } 329