xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/spl.c (revision b8fa3d2a17dce6006a8a5f46cbc978a19a3fdf82)
1 /*
2  * (C) Copyright 2018 Rockchip Electronics Co., Ltd
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 <ram.h>
11 #include <spl.h>
12 #include <asm/arch/bootrom.h>
13 #include <asm/arch/sdram_common.h>
14 #include <asm/arch-rockchip/sys_proto.h>
15 #include <asm/io.h>
16 
17 DECLARE_GLOBAL_DATA_PTR;
18 
19 void board_return_to_bootrom(void)
20 {
21 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
22 }
23 
24 __weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
25 };
26 
27 const char *board_spl_was_booted_from(void)
28 {
29 	u32  bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR);
30 	const char *bootdevice_ofpath = NULL;
31 
32 	if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
33 		bootdevice_ofpath = boot_devices[bootdevice_brom_id];
34 
35 	if (bootdevice_ofpath)
36 		debug("%s: brom_bootdevice_id %x maps to '%s'\n",
37 		      __func__, bootdevice_brom_id, bootdevice_ofpath);
38 	else
39 		debug("%s: failed to resolve brom_bootdevice_id %x\n",
40 		      __func__, bootdevice_brom_id);
41 
42 	return bootdevice_ofpath;
43 }
44 
45 u32 spl_boot_device(void)
46 {
47 	u32 boot_device = BOOT_DEVICE_MMC1;
48 
49 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
50 		defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
51 		defined(CONFIG_TARGET_CHROMEBOOK_MINNIE)
52 	return BOOT_DEVICE_SPI;
53 #endif
54 	if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
55 		return BOOT_DEVICE_BOOTROM;
56 
57 	return boot_device;
58 }
59 
60 u32 spl_boot_mode(const u32 boot_device)
61 {
62 	return MMCSD_MODE_RAW;
63 }
64 
65 __weak void rockchip_stimer_init(void)
66 {
67 #ifdef CONFIG_SYS_ARCH_TIMER
68 #ifndef CONFIG_ARM64
69 	asm volatile("mcr p15, 0, %0, c14, c0, 0"
70 		     : : "r"(COUNTER_FREQUENCY));
71 #endif
72 	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
73 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
74 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
75 	writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
76 #endif
77 }
78 
79 __weak int arch_cpu_init(void)
80 {
81 	return 0;
82 }
83 
84 __weak int rk_board_init_f(void)
85 {
86 	return 0;
87 }
88 
89 #ifndef CONFIG_SPL_LIBGENERIC_SUPPORT
90 void udelay(unsigned long usec)
91 {
92 	__udelay(usec);
93 }
94 
95 void hang(void)
96 {
97 	bootstage_error(BOOTSTAGE_ID_NEED_RESET);
98 	for (;;)
99 		;
100 }
101 
102 /**
103  * memset - Fill a region of memory with the given value
104  * @s: Pointer to the start of the area.
105  * @c: The byte to fill the area with
106  * @count: The size of the area.
107  *
108  * Do not use memset() to access IO space, use memset_io() instead.
109  */
110 void *memset(void *s, int c, size_t count)
111 {
112 	unsigned long *sl = (unsigned long *)s;
113 	char *s8;
114 
115 #if !CONFIG_IS_ENABLED(TINY_MEMSET)
116 	unsigned long cl = 0;
117 	int i;
118 
119 	/* do it one word at a time (32 bits or 64 bits) while possible */
120 	if (((ulong)s & (sizeof(*sl) - 1)) == 0) {
121 		for (i = 0; i < sizeof(*sl); i++) {
122 			cl <<= 8;
123 			cl |= c & 0xff;
124 		}
125 		while (count >= sizeof(*sl)) {
126 			*sl++ = cl;
127 			count -= sizeof(*sl);
128 		}
129 	}
130 #endif /* fill 8 bits at a time */
131 	s8 = (char *)sl;
132 	while (count--)
133 		*s8++ = c;
134 
135 	return s;
136 }
137 #endif
138 
139 void board_init_f(ulong dummy)
140 {
141 #ifdef CONFIG_SPL_FRAMEWORK
142 	int ret;
143 #if !defined(CONFIG_SUPPORT_TPL)
144 	struct udevice *dev;
145 #endif
146 #endif
147 
148 #if !defined(CONFIG_SUPPORT_TPL)
149 	rockchip_stimer_init();
150 	arch_cpu_init();
151 #endif
152 #define EARLY_UART
153 #if defined(EARLY_UART) && defined(CONFIG_DEBUG_UART)
154 	/*
155 	 * Debug UART can be used from here if required:
156 	 *
157 	 * debug_uart_init();
158 	 * printch('a');
159 	 * printhex8(0x1234);
160 	 * printascii("string");
161 	 */
162 	debug_uart_init();
163 	printascii("U-Boot SPL board init");
164 #endif
165 
166 #ifdef CONFIG_SPL_FRAMEWORK
167 	ret = spl_early_init();
168 	if (ret) {
169 		printf("spl_early_init() failed: %d\n", ret);
170 		hang();
171 	}
172 #if !defined(CONFIG_SUPPORT_TPL)
173 	debug("\nspl:init dram\n");
174 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
175 	if (ret) {
176 		printf("DRAM init failed: %d\n", ret);
177 		return;
178 	}
179 #endif
180 	preloader_console_init();
181 #else
182 	/* Some SoCs like rk3036 does not use any frame work */
183 	sdram_init();
184 #endif
185 
186 	rk_board_init_f();
187 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
188 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
189 #endif
190 
191 }
192 
193 #ifdef CONFIG_SPL_LOAD_FIT
194 int board_fit_config_name_match(const char *name)
195 {
196 	/* Just empty function now - can't decide what to choose */
197 	debug("%s: %s\n", __func__, name);
198 
199 	return 0;
200 }
201 #endif
202 
203 #ifdef CONFIG_SPL_BOARD_INIT
204 __weak int rk_spl_board_init(void)
205 {
206 	return 0;
207 }
208 
209 static int setup_led(void)
210 {
211 #ifdef CONFIG_SPL_LED
212 	struct udevice *dev;
213 	char *led_name;
214 	int ret;
215 
216 	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
217 	if (!led_name)
218 		return 0;
219 	ret = led_get_by_label(led_name, &dev);
220 	if (ret) {
221 		debug("%s: get=%d\n", __func__, ret);
222 		return ret;
223 	}
224 	ret = led_set_on(dev, 1);
225 	if (ret)
226 		return ret;
227 #endif
228 
229 	return 0;
230 }
231 
232 void spl_board_init(void)
233 {
234 	int ret;
235 
236 	ret = setup_led();
237 
238 	if (ret) {
239 		debug("LED ret=%d\n", ret);
240 		hang();
241 	}
242 
243 	rk_spl_board_init();
244 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
245 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
246 #endif
247 	return;
248 }
249 #endif
250