]> git.sur5r.net Git - u-boot/blob - arch/arm/mach-rockchip/rk3288-board-spl.c
rockchip: Allow jerry to use of-platdata
[u-boot] / arch / arm / mach-rockchip / rk3288-board-spl.c
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 <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>
21 #include <asm/arch/timer.h>
22 #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
28 DECLARE_GLOBAL_DATA_PTR;
29
30 u32 spl_boot_device(void)
31 {
32 #if !CONFIG_IS_ENABLED(OF_PLATDATA)
33         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
66 fallback:
67 #elif defined(CONFIG_TARGET_CHROMEBOOK_JERRY)
68         return BOOT_DEVICE_SPI;
69 #endif
70         return BOOT_DEVICE_MMC1;
71 }
72
73 u32 spl_boot_mode(const u32 boot_device)
74 {
75         return MMCSD_MODE_RAW;
76 }
77
78 /* read L2 control register (L2CTLR) */
79 static 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) */
89 static 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
99 static 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
118 #ifdef CONFIG_SPL_MMC_SUPPORT
119 static int configure_emmc(struct udevice *pinctrl)
120 {
121 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY)
122
123         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         }
152 #endif
153         return 0;
154 }
155 #endif
156 extern void back_to_bootrom(void);
157 void 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
191         rockchip_timer_init();
192         configure_l2ctlr();
193
194         ret = rockchip_get_clk(&dev);
195         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         }
211 #if defined(CONFIG_ROCKCHIP_SPL_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
212         back_to_bootrom();
213 #endif
214 }
215
216 static 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
239 void 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         }
256
257 #ifdef CONFIG_SPL_MMC_SUPPORT
258         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;
267         }
268 #endif
269
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();
278 #ifdef CONFIG_ROCKCHIP_SPL_BACK_TO_BROM
279         back_to_bootrom();
280 #endif
281         return;
282 err:
283         printf("spl_board_init: Error %d\n", ret);
284
285         /* No way to report error here */
286         hang();
287 }