xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/spl.c (revision e65bf00a8cc4457af9d351e0129b24292fd5b7ff)
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 <key.h>
11 #include <ram.h>
12 #include <spl.h>
13 #include <optee_include/OpteeClientInterface.h>
14 #include <asm/arch/bootrom.h>
15 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
16 #include <asm/arch/rk_atags.h>
17 #endif
18 #include <asm/arch/sdram.h>
19 #include <asm/arch/boot_mode.h>
20 #include <asm/arch-rockchip/sys_proto.h>
21 #include <asm/io.h>
22 
23 DECLARE_GLOBAL_DATA_PTR;
24 
25 void board_return_to_bootrom(void)
26 {
27 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
28 }
29 
30 __weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
31 };
32 
33 const char *board_spl_was_booted_from(void)
34 {
35 	u32  bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR);
36 	const char *bootdevice_ofpath = NULL;
37 
38 	if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
39 		bootdevice_ofpath = boot_devices[bootdevice_brom_id];
40 
41 	if (bootdevice_ofpath)
42 		debug("%s: brom_bootdevice_id %x maps to '%s'\n",
43 		      __func__, bootdevice_brom_id, bootdevice_ofpath);
44 	else
45 		debug("%s: failed to resolve brom_bootdevice_id %x\n",
46 		      __func__, bootdevice_brom_id);
47 
48 	return bootdevice_ofpath;
49 }
50 
51 u32 spl_boot_device(void)
52 {
53 	u32 boot_device = BOOT_DEVICE_MMC1;
54 
55 #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
56 		defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
57 		defined(CONFIG_TARGET_CHROMEBOOK_MINNIE)
58 	return BOOT_DEVICE_SPI;
59 #endif
60 	if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
61 		return BOOT_DEVICE_BOOTROM;
62 
63 	return boot_device;
64 }
65 
66 u32 spl_boot_mode(const u32 boot_device)
67 {
68 	return MMCSD_MODE_RAW;
69 }
70 
71 __weak void rockchip_stimer_init(void)
72 {
73 	/* If Timer already enabled, don't re-init it */
74 	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
75 	if ( reg & 0x1 )
76 		return;
77 #ifndef CONFIG_ARM64
78 	asm volatile("mcr p15, 0, %0, c14, c0, 0"
79 		     : : "r"(COUNTER_FREQUENCY));
80 #endif
81 	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
82 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
83 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
84 	writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
85 }
86 
87 __weak int arch_cpu_init(void)
88 {
89 	return 0;
90 }
91 
92 __weak int rk_board_init_f(void)
93 {
94 	return 0;
95 }
96 
97 #ifndef CONFIG_SPL_LIBGENERIC_SUPPORT
98 void udelay(unsigned long usec)
99 {
100 	__udelay(usec);
101 }
102 
103 void hang(void)
104 {
105 	bootstage_error(BOOTSTAGE_ID_NEED_RESET);
106 	for (;;)
107 		;
108 }
109 
110 /**
111  * memset - Fill a region of memory with the given value
112  * @s: Pointer to the start of the area.
113  * @c: The byte to fill the area with
114  * @count: The size of the area.
115  *
116  * Do not use memset() to access IO space, use memset_io() instead.
117  */
118 void *memset(void *s, int c, size_t count)
119 {
120 	unsigned long *sl = (unsigned long *)s;
121 	char *s8;
122 
123 #if !CONFIG_IS_ENABLED(TINY_MEMSET)
124 	unsigned long cl = 0;
125 	int i;
126 
127 	/* do it one word at a time (32 bits or 64 bits) while possible */
128 	if (((ulong)s & (sizeof(*sl) - 1)) == 0) {
129 		for (i = 0; i < sizeof(*sl); i++) {
130 			cl <<= 8;
131 			cl |= c & 0xff;
132 		}
133 		while (count >= sizeof(*sl)) {
134 			*sl++ = cl;
135 			count -= sizeof(*sl);
136 		}
137 	}
138 #endif /* fill 8 bits at a time */
139 	s8 = (char *)sl;
140 	while (count--)
141 		*s8++ = c;
142 
143 	return s;
144 }
145 #endif
146 
147 void board_init_f(ulong dummy)
148 {
149 #ifdef CONFIG_SPL_FRAMEWORK
150 	int ret;
151 #if !defined(CONFIG_SUPPORT_TPL)
152 	struct udevice *dev;
153 #endif
154 #endif
155 
156 	rockchip_stimer_init();
157 #define EARLY_UART
158 #if defined(EARLY_UART) && defined(CONFIG_DEBUG_UART)
159 	/*
160 	 * Debug UART can be used from here if required:
161 	 *
162 	 * debug_uart_init();
163 	 * printch('a');
164 	 * printhex8(0x1234);
165 	 * printascii("string");
166 	 */
167 	debug_uart_init();
168 	printascii("U-Boot SPL board init");
169 #endif
170 
171 #ifdef CONFIG_SPL_FRAMEWORK
172 	ret = spl_early_init();
173 	if (ret) {
174 		printf("spl_early_init() failed: %d\n", ret);
175 		hang();
176 	}
177 #if !defined(CONFIG_SUPPORT_TPL)
178 	debug("\nspl:init dram\n");
179 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
180 	if (ret) {
181 		printf("DRAM init failed: %d\n", ret);
182 		return;
183 	}
184 #endif
185 	preloader_console_init();
186 #else
187 	/* Some SoCs like rk3036 does not use any frame work */
188 	sdram_init();
189 #endif
190 
191 	arch_cpu_init();
192 	rk_board_init_f();
193 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
194 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
195 #endif
196 
197 }
198 
199 #ifdef CONFIG_SPL_LOAD_FIT
200 int board_fit_config_name_match(const char *name)
201 {
202 	/* Just empty function now - can't decide what to choose */
203 	debug("%s: %s\n", __func__, name);
204 
205 	return 0;
206 }
207 #endif
208 
209 #ifdef CONFIG_SPL_BOARD_INIT
210 __weak int rk_spl_board_init(void)
211 {
212 	return 0;
213 }
214 
215 static int setup_led(void)
216 {
217 #ifdef CONFIG_SPL_LED
218 	struct udevice *dev;
219 	char *led_name;
220 	int ret;
221 
222 	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
223 	if (!led_name)
224 		return 0;
225 	ret = led_get_by_label(led_name, &dev);
226 	if (ret) {
227 		debug("%s: get=%d\n", __func__, ret);
228 		return ret;
229 	}
230 	ret = led_set_on(dev, 1);
231 	if (ret)
232 		return ret;
233 #endif
234 
235 	return 0;
236 }
237 
238 void spl_board_init(void)
239 {
240 	int ret;
241 
242 	ret = setup_led();
243 
244 	if (ret) {
245 		debug("LED ret=%d\n", ret);
246 		hang();
247 	}
248 
249 	rk_spl_board_init();
250 #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
251 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
252 #endif
253 	return;
254 }
255 #endif
256 
257 void spl_perform_fixups(struct spl_image_info *spl_image)
258 {
259 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
260 	atags_set_bootdev_by_spl_bootdevice(spl_image->boot_device);
261 #endif
262 	return;
263 }
264 
265 #ifdef CONFIG_SPL_KERNEL_BOOT
266 static int spl_rockchip_dnl_key_pressed(void)
267 {
268 #if defined(CONFIG_SPL_INPUT)
269 	return key_read(KEY_VOLUMEUP);
270 #else
271 	return 0;
272 #endif
273 }
274 
275 void spl_next_stage(struct spl_image_info *spl)
276 {
277 	uint32_t reg_boot_mode;
278 
279 	if (spl_rockchip_dnl_key_pressed()) {
280 		spl->next_stage = SPL_NEXT_STAGE_UBOOT;
281 		return;
282 	}
283 
284 	reg_boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG);
285 	switch (reg_boot_mode) {
286 	case BOOT_PANIC:
287 	case BOOT_WATCHDOG:
288 	case BOOT_NORMAL:
289 		spl->next_stage = SPL_NEXT_STAGE_KERNEL;
290 		break;
291 	default:
292 		spl->next_stage = SPL_NEXT_STAGE_UBOOT;
293 	}
294 }
295 #endif
296 
297 int spl_board_prepare_for_jump(struct spl_image_info *spl_image)
298 {
299 #if CONFIG_SPL_FIT_ROLLBACK_PROTECT
300 	/* TODO */
301 	printf("spl fit: rollback protect not implement\n");
302 #endif
303 	return 0;
304 }
305 
306 void spl_hang_reset(void)
307 {
308 	printf("# Reset the board to bootrom #\n");
309 #if defined(CONFIG_SPL_SYSRESET) && defined(CONFIG_SPL_DRIVERS_MISC_SUPPORT)
310 	writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
311 	do_reset(NULL, 0, 0, NULL);
312 #endif
313 }
314