blob: 185b5fdcf7286e4ff7c79b10da8dc6017443b16f [file] [log] [blame]
Simon Glass2cffe662015-08-30 16:55:38 -06001/*
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 <led.h>
12#include <malloc.h>
13#include <ram.h>
14#include <spl.h>
15#include <asm/gpio.h>
16#include <asm/io.h>
17#include <asm/arch/clock.h>
18#include <asm/arch/hardware.h>
19#include <asm/arch/periph.h>
20#include <asm/arch/sdram.h>
huang lin8db3e242015-11-17 14:20:09 +080021#include <asm/arch/timer.h>
Simon Glass2cffe662015-08-30 16:55:38 -060022#include <dm/pinctrl.h>
23#include <dm/root.h>
24#include <dm/test.h>
25#include <dm/util.h>
26#include <power/regulator.h>
27
28DECLARE_GLOBAL_DATA_PTR;
29
30u32 spl_boot_device(void)
31{
Simon Glass26158ef2016-07-04 11:58:32 -060032#if !CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass2cffe662015-08-30 16:55:38 -060033 const void *blob = gd->fdt_blob;
34 struct udevice *dev;
35 const char *bootdev;
36 int node;
37 int ret;
38
39 bootdev = fdtdec_get_config_string(blob, "u-boot,boot0");
40 debug("Boot device %s\n", bootdev);
41 if (!bootdev)
42 goto fallback;
43
44 node = fdt_path_offset(blob, bootdev);
45 if (node < 0) {
46 debug("node=%d\n", node);
47 goto fallback;
48 }
49 ret = device_get_global_by_of_offset(node, &dev);
50 if (ret) {
51 debug("device at node %s/%d not found: %d\n", bootdev, node,
52 ret);
53 goto fallback;
54 }
55 debug("Found device %s\n", dev->name);
56 switch (device_get_uclass_id(dev)) {
57 case UCLASS_SPI_FLASH:
58 return BOOT_DEVICE_SPI;
59 case UCLASS_MMC:
60 return BOOT_DEVICE_MMC1;
61 default:
62 debug("Booting from device uclass '%s' not supported\n",
63 dev_get_uclass_name(dev));
64 }
65
66fallback:
Simon Glass6f9087c2016-11-13 14:21:57 -070067#elif defined(CONFIG_TARGET_CHROMEBOOK_JERRY)
68 return BOOT_DEVICE_SPI;
Simon Glass26158ef2016-07-04 11:58:32 -060069#endif
Simon Glass2cffe662015-08-30 16:55:38 -060070 return BOOT_DEVICE_MMC1;
71}
72
Marek Vasut64d64bb2016-05-14 23:42:07 +020073u32 spl_boot_mode(const u32 boot_device)
Simon Glass2cffe662015-08-30 16:55:38 -060074{
75 return MMCSD_MODE_RAW;
76}
77
78/* read L2 control register (L2CTLR) */
79static inline uint32_t read_l2ctlr(void)
80{
81 uint32_t val = 0;
82
83 asm volatile ("mrc p15, 1, %0, c9, c0, 2" : "=r" (val));
84
85 return val;
86}
87
88/* write L2 control register (L2CTLR) */
89static inline void write_l2ctlr(uint32_t val)
90{
91 /*
92 * Note: L2CTLR can only be written when the L2 memory system
93 * is idle, ie before the MMU is enabled.
94 */
95 asm volatile("mcr p15, 1, %0, c9, c0, 2" : : "r" (val) : "memory");
96 isb();
97}
98
99static void configure_l2ctlr(void)
100{
101 uint32_t l2ctlr;
102
103 l2ctlr = read_l2ctlr();
104 l2ctlr &= 0xfffc0000; /* clear bit0~bit17 */
105
106 /*
107 * Data RAM write latency: 2 cycles
108 * Data RAM read latency: 2 cycles
109 * Data RAM setup latency: 1 cycle
110 * Tag RAM write latency: 1 cycle
111 * Tag RAM read latency: 1 cycle
112 * Tag RAM setup latency: 1 cycle
113 */
114 l2ctlr |= (1 << 3 | 1 << 0);
115 write_l2ctlr(l2ctlr);
116}
117
Simon Glass4ba12932016-01-21 19:45:13 -0700118#ifdef CONFIG_SPL_MMC_SUPPORT
Simon Glass2cffe662015-08-30 16:55:38 -0600119static int configure_emmc(struct udevice *pinctrl)
120{
jk.kernel@gmail.comb1aeb092016-07-26 18:28:29 +0800121#if defined(CONFIG_TARGET_CHROMEBOOK_JERRY)
jk.kernel@gmail.com2b87b932016-07-26 18:28:23 +0800122
Simon Glass2cffe662015-08-30 16:55:38 -0600123 struct gpio_desc desc;
124 int ret;
125
126 pinctrl_request_noflags(pinctrl, PERIPH_ID_EMMC);
127
128 /*
129 * TODO(sjg@chromium.org): Pick this up from device tree or perhaps
130 * use the EMMC_PWREN setting.
131 */
132 ret = dm_gpio_lookup_name("D9", &desc);
133 if (ret) {
134 debug("gpio ret=%d\n", ret);
135 return ret;
136 }
137 ret = dm_gpio_request(&desc, "emmc_pwren");
138 if (ret) {
139 debug("gpio_request ret=%d\n", ret);
140 return ret;
141 }
142 ret = dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT);
143 if (ret) {
144 debug("gpio dir ret=%d\n", ret);
145 return ret;
146 }
147 ret = dm_gpio_set_value(&desc, 1);
148 if (ret) {
149 debug("gpio value ret=%d\n", ret);
150 return ret;
151 }
jk.kernel@gmail.com2b87b932016-07-26 18:28:23 +0800152#endif
Simon Glass2cffe662015-08-30 16:55:38 -0600153 return 0;
154}
Simon Glass4ba12932016-01-21 19:45:13 -0700155#endif
Xu Ziyuan5401eb82016-07-12 19:09:49 +0800156extern void back_to_bootrom(void);
Simon Glass2cffe662015-08-30 16:55:38 -0600157void board_init_f(ulong dummy)
158{
159 struct udevice *pinctrl;
160 struct udevice *dev;
161 int ret;
162
163 /* Example code showing how to enable the debug UART on RK3288 */
164#ifdef EARLY_UART
165#include <asm/arch/grf_rk3288.h>
166 /* Enable early UART on the RK3288 */
167#define GRF_BASE 0xff770000
168 struct rk3288_grf * const grf = (void *)GRF_BASE;
169
170 rk_clrsetreg(&grf->gpio7ch_iomux, GPIO7C7_MASK << GPIO7C7_SHIFT |
171 GPIO7C6_MASK << GPIO7C6_SHIFT,
172 GPIO7C7_UART2DBG_SOUT << GPIO7C7_SHIFT |
173 GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT);
174 /*
175 * Debug UART can be used from here if required:
176 *
177 * debug_uart_init();
178 * printch('a');
179 * printhex8(0x1234);
180 * printascii("string");
181 */
182 debug_uart_init();
183#endif
184
185 ret = spl_init();
186 if (ret) {
187 debug("spl_init() failed: %d\n", ret);
188 hang();
189 }
190
huang lin8db3e242015-11-17 14:20:09 +0800191 rockchip_timer_init();
Simon Glass2cffe662015-08-30 16:55:38 -0600192 configure_l2ctlr();
193
Simon Glassae8fe412016-07-17 15:23:17 -0600194 ret = rockchip_get_clk(&dev);
Simon Glass2cffe662015-08-30 16:55:38 -0600195 if (ret) {
196 debug("CLK init failed: %d\n", ret);
197 return;
198 }
199
200 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
201 if (ret) {
202 debug("Pinctrl init failed: %d\n", ret);
203 return;
204 }
205
206 ret = uclass_get_device(UCLASS_RAM, 0, &dev);
207 if (ret) {
208 debug("DRAM init failed: %d\n", ret);
209 return;
210 }
Sandy Pattersona9e92ee2016-08-10 10:21:47 -0400211#if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
Xu Ziyuan5401eb82016-07-12 19:09:49 +0800212 back_to_bootrom();
213#endif
Simon Glass2cffe662015-08-30 16:55:38 -0600214}
215
216static int setup_led(void)
217{
218#ifdef CONFIG_SPL_LED
219 struct udevice *dev;
220 char *led_name;
221 int ret;
222
223 led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
224 if (!led_name)
225 return 0;
226 ret = led_get_by_label(led_name, &dev);
227 if (ret) {
228 debug("%s: get=%d\n", __func__, ret);
229 return ret;
230 }
231 ret = led_set_on(dev, 1);
232 if (ret)
233 return ret;
234#endif
235
236 return 0;
237}
238
239void spl_board_init(void)
240{
241 struct udevice *pinctrl;
242 int ret;
243
244 ret = setup_led();
245
246 if (ret) {
247 debug("LED ret=%d\n", ret);
248 hang();
249 }
250
251 ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl);
252 if (ret) {
253 debug("%s: Cannot find pinctrl device\n", __func__);
254 goto err;
255 }
jk.kernel@gmail.com2b87b932016-07-26 18:28:23 +0800256
Simon Glass4ba12932016-01-21 19:45:13 -0700257#ifdef CONFIG_SPL_MMC_SUPPORT
jk.kernel@gmail.com2b87b932016-07-26 18:28:23 +0800258 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_SDCARD);
259 if (ret) {
260 debug("%s: Failed to set up SD card\n", __func__);
261 goto err;
262 }
263 ret = configure_emmc(pinctrl);
264 if (ret) {
265 debug("%s: Failed to set up eMMC\n", __func__);
266 goto err;
Simon Glass2cffe662015-08-30 16:55:38 -0600267 }
Simon Glass4ba12932016-01-21 19:45:13 -0700268#endif
Simon Glass2cffe662015-08-30 16:55:38 -0600269
270 /* Enable debug UART */
271 ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_UART_DBG);
272 if (ret) {
273 debug("%s: Failed to set up console UART\n", __func__);
274 goto err;
275 }
276
277 preloader_console_init();
Sandy Pattersona9e92ee2016-08-10 10:21:47 -0400278#ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
279 back_to_bootrom();
280#endif
Simon Glass2cffe662015-08-30 16:55:38 -0600281 return;
282err:
283 printf("spl_board_init: Error %d\n", ret);
284
285 /* No way to report error here */
286 hang();
287}