xref: /OK3568_Linux_fs/u-boot/arch/arm/mach-rockchip/spl.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2018 Rockchip Electronics Co., Ltd
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:     GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <boot_rkimg.h>
9*4882a593Smuzhiyun #include <debug_uart.h>
10*4882a593Smuzhiyun #include <dm.h>
11*4882a593Smuzhiyun #include <key.h>
12*4882a593Smuzhiyun #include <led.h>
13*4882a593Smuzhiyun #include <misc.h>
14*4882a593Smuzhiyun #include <ram.h>
15*4882a593Smuzhiyun #include <spl.h>
16*4882a593Smuzhiyun #include <optee_include/OpteeClientInterface.h>
17*4882a593Smuzhiyun #include <power/fuel_gauge.h>
18*4882a593Smuzhiyun #include <asm/arch/bootrom.h>
19*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
20*4882a593Smuzhiyun #include <asm/arch/rk_atags.h>
21*4882a593Smuzhiyun #endif
22*4882a593Smuzhiyun #include <asm/arch/pcie_ep_boot.h>
23*4882a593Smuzhiyun #include <asm/arch/sdram.h>
24*4882a593Smuzhiyun #include <asm/arch/boot_mode.h>
25*4882a593Smuzhiyun #include <asm/arch-rockchip/sys_proto.h>
26*4882a593Smuzhiyun #include <asm/io.h>
27*4882a593Smuzhiyun #include <asm/arch/param.h>
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
30*4882a593Smuzhiyun 
board_return_to_bootrom(void)31*4882a593Smuzhiyun void board_return_to_bootrom(void)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun __weak const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun 
board_spl_was_booted_from(void)39*4882a593Smuzhiyun const char *board_spl_was_booted_from(void)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	u32  bootdevice_brom_id = readl(BROM_BOOTSOURCE_ID_ADDR);
42*4882a593Smuzhiyun 	const char *bootdevice_ofpath = NULL;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	if (bootdevice_brom_id < ARRAY_SIZE(boot_devices))
45*4882a593Smuzhiyun 		bootdevice_ofpath = boot_devices[bootdevice_brom_id];
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	if (bootdevice_ofpath)
48*4882a593Smuzhiyun 		debug("%s: brom_bootdevice_id %x maps to '%s'\n",
49*4882a593Smuzhiyun 		      __func__, bootdevice_brom_id, bootdevice_ofpath);
50*4882a593Smuzhiyun 	else
51*4882a593Smuzhiyun 		debug("%s: failed to resolve brom_bootdevice_id %x\n",
52*4882a593Smuzhiyun 		      __func__, bootdevice_brom_id);
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	return bootdevice_ofpath;
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
spl_boot_device(void)57*4882a593Smuzhiyun u32 spl_boot_device(void)
58*4882a593Smuzhiyun {
59*4882a593Smuzhiyun 	u32 boot_device = BOOT_DEVICE_MMC1;
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
62*4882a593Smuzhiyun 		defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
63*4882a593Smuzhiyun 		defined(CONFIG_TARGET_CHROMEBOOK_MINNIE)
64*4882a593Smuzhiyun 	return BOOT_DEVICE_SPI;
65*4882a593Smuzhiyun #endif
66*4882a593Smuzhiyun 	if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM))
67*4882a593Smuzhiyun 		return BOOT_DEVICE_BOOTROM;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	return boot_device;
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun 
spl_boot_mode(const u32 boot_device)72*4882a593Smuzhiyun u32 spl_boot_mode(const u32 boot_device)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	return MMCSD_MODE_RAW;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
rockchip_stimer_init(void)77*4882a593Smuzhiyun __weak void rockchip_stimer_init(void)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	/* If Timer already enabled, don't re-init it */
80*4882a593Smuzhiyun 	u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
81*4882a593Smuzhiyun 	if ( reg & 0x1 )
82*4882a593Smuzhiyun 		return;
83*4882a593Smuzhiyun #ifndef CONFIG_ARM64
84*4882a593Smuzhiyun 	asm volatile("mcr p15, 0, %0, c14, c0, 0"
85*4882a593Smuzhiyun 		     : : "r"(COUNTER_FREQUENCY));
86*4882a593Smuzhiyun #endif
87*4882a593Smuzhiyun 	writel(0, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
88*4882a593Smuzhiyun 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE);
89*4882a593Smuzhiyun 	writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 4);
90*4882a593Smuzhiyun 	writel(1, CONFIG_ROCKCHIP_STIMER_BASE + 0x10);
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
arch_cpu_init(void)93*4882a593Smuzhiyun __weak int arch_cpu_init(void)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	return 0;
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun 
rk_board_init_f(void)98*4882a593Smuzhiyun __weak int rk_board_init_f(void)
99*4882a593Smuzhiyun {
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun #ifndef CONFIG_SPL_LIBGENERIC_SUPPORT
udelay(unsigned long usec)104*4882a593Smuzhiyun void udelay(unsigned long usec)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	__udelay(usec);
107*4882a593Smuzhiyun }
108*4882a593Smuzhiyun 
hang(void)109*4882a593Smuzhiyun void hang(void)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun 	bootstage_error(BOOTSTAGE_ID_NEED_RESET);
112*4882a593Smuzhiyun 	for (;;)
113*4882a593Smuzhiyun 		;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun /**
117*4882a593Smuzhiyun  * memset - Fill a region of memory with the given value
118*4882a593Smuzhiyun  * @s: Pointer to the start of the area.
119*4882a593Smuzhiyun  * @c: The byte to fill the area with
120*4882a593Smuzhiyun  * @count: The size of the area.
121*4882a593Smuzhiyun  *
122*4882a593Smuzhiyun  * Do not use memset() to access IO space, use memset_io() instead.
123*4882a593Smuzhiyun  */
memset(void * s,int c,size_t count)124*4882a593Smuzhiyun void *memset(void *s, int c, size_t count)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun 	unsigned long *sl = (unsigned long *)s;
127*4882a593Smuzhiyun 	char *s8;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun #if !CONFIG_IS_ENABLED(TINY_MEMSET)
130*4882a593Smuzhiyun 	unsigned long cl = 0;
131*4882a593Smuzhiyun 	int i;
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	/* do it one word at a time (32 bits or 64 bits) while possible */
134*4882a593Smuzhiyun 	if (((ulong)s & (sizeof(*sl) - 1)) == 0) {
135*4882a593Smuzhiyun 		for (i = 0; i < sizeof(*sl); i++) {
136*4882a593Smuzhiyun 			cl <<= 8;
137*4882a593Smuzhiyun 			cl |= c & 0xff;
138*4882a593Smuzhiyun 		}
139*4882a593Smuzhiyun 		while (count >= sizeof(*sl)) {
140*4882a593Smuzhiyun 			*sl++ = cl;
141*4882a593Smuzhiyun 			count -= sizeof(*sl);
142*4882a593Smuzhiyun 		}
143*4882a593Smuzhiyun 	}
144*4882a593Smuzhiyun #endif /* fill 8 bits at a time */
145*4882a593Smuzhiyun 	s8 = (char *)sl;
146*4882a593Smuzhiyun 	while (count--)
147*4882a593Smuzhiyun 		*s8++ = c;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	return s;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun #endif
152*4882a593Smuzhiyun 
board_init_f(ulong dummy)153*4882a593Smuzhiyun void board_init_f(ulong dummy)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun #ifdef CONFIG_SPL_FRAMEWORK
156*4882a593Smuzhiyun 	int ret;
157*4882a593Smuzhiyun #if !defined(CONFIG_SUPPORT_TPL)
158*4882a593Smuzhiyun 	struct udevice *dev;
159*4882a593Smuzhiyun #endif
160*4882a593Smuzhiyun #endif
161*4882a593Smuzhiyun 	gd->flags = dummy;
162*4882a593Smuzhiyun 	rockchip_stimer_init();
163*4882a593Smuzhiyun #define EARLY_UART
164*4882a593Smuzhiyun #if defined(EARLY_UART) && defined(CONFIG_DEBUG_UART)
165*4882a593Smuzhiyun 	/*
166*4882a593Smuzhiyun 	 * Debug UART can be used from here if required:
167*4882a593Smuzhiyun 	 *
168*4882a593Smuzhiyun 	 * debug_uart_init();
169*4882a593Smuzhiyun 	 * printch('a');
170*4882a593Smuzhiyun 	 * printhex8(0x1234);
171*4882a593Smuzhiyun 	 * printascii("string");
172*4882a593Smuzhiyun 	 */
173*4882a593Smuzhiyun 	if (!gd->serial.using_pre_serial &&
174*4882a593Smuzhiyun 	    !(gd->flags & GD_FLG_DISABLE_CONSOLE))
175*4882a593Smuzhiyun 		debug_uart_init();
176*4882a593Smuzhiyun 	printascii("U-Boot SPL board init");
177*4882a593Smuzhiyun #endif
178*4882a593Smuzhiyun 	gd->sys_start_tick = get_ticks();
179*4882a593Smuzhiyun #ifdef CONFIG_SPL_PCIE_EP_SUPPORT
180*4882a593Smuzhiyun 	rockchip_pcie_ep_init();
181*4882a593Smuzhiyun #endif
182*4882a593Smuzhiyun #ifdef CONFIG_SPL_FRAMEWORK
183*4882a593Smuzhiyun 	ret = spl_early_init();
184*4882a593Smuzhiyun 	if (ret) {
185*4882a593Smuzhiyun 		printf("spl_early_init() failed: %d\n", ret);
186*4882a593Smuzhiyun 		hang();
187*4882a593Smuzhiyun 	}
188*4882a593Smuzhiyun #if !defined(CONFIG_SUPPORT_TPL)
189*4882a593Smuzhiyun 	debug("\nspl:init dram\n");
190*4882a593Smuzhiyun 	ret = uclass_get_device(UCLASS_RAM, 0, &dev);
191*4882a593Smuzhiyun 	if (ret) {
192*4882a593Smuzhiyun 		printf("DRAM init failed: %d\n", ret);
193*4882a593Smuzhiyun 		return;
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun #endif
196*4882a593Smuzhiyun 	preloader_console_init();
197*4882a593Smuzhiyun #else
198*4882a593Smuzhiyun 	/* Some SoCs like rk3036 does not use any frame work */
199*4882a593Smuzhiyun 	sdram_init();
200*4882a593Smuzhiyun #endif
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	arch_cpu_init();
203*4882a593Smuzhiyun 	rk_board_init_f();
204*4882a593Smuzhiyun #ifdef CONFIG_SPL_RAM_DEVICE
205*4882a593Smuzhiyun 	rockchip_pcie_ep_get_firmware();
206*4882a593Smuzhiyun #endif
207*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM) && !defined(CONFIG_SPL_BOARD_INIT)
208*4882a593Smuzhiyun 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
209*4882a593Smuzhiyun #endif
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun #ifdef CONFIG_SPL_LOAD_FIT
board_fit_config_name_match(const char * name)214*4882a593Smuzhiyun int board_fit_config_name_match(const char *name)
215*4882a593Smuzhiyun {
216*4882a593Smuzhiyun 	/* Just empty function now - can't decide what to choose */
217*4882a593Smuzhiyun 	debug("%s: %s\n", __func__, name);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	return 0;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun #endif
222*4882a593Smuzhiyun 
board_init_f_boot_flags(void)223*4882a593Smuzhiyun int board_init_f_boot_flags(void)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	int boot_flags = 0;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun #ifdef CONFIG_FPGA_ROCKCHIP
228*4882a593Smuzhiyun 	arch_fpga_init();
229*4882a593Smuzhiyun #endif
230*4882a593Smuzhiyun #ifdef CONFIG_PSTORE
231*4882a593Smuzhiyun 	param_parse_pstore();
232*4882a593Smuzhiyun #endif
233*4882a593Smuzhiyun 	/* pre-loader serial */
234*4882a593Smuzhiyun #if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \
235*4882a593Smuzhiyun     defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS)
236*4882a593Smuzhiyun 	struct tag *t;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	t = atags_get_tag(ATAG_SERIAL);
239*4882a593Smuzhiyun 	if (t) {
240*4882a593Smuzhiyun 		gd->serial.using_pre_serial = 1;
241*4882a593Smuzhiyun 		gd->serial.enable = t->u.serial.enable;
242*4882a593Smuzhiyun 		gd->serial.baudrate = t->u.serial.baudrate;
243*4882a593Smuzhiyun 		gd->serial.addr = t->u.serial.addr;
244*4882a593Smuzhiyun 		gd->serial.id = t->u.serial.id;
245*4882a593Smuzhiyun 		gd->baudrate = t->u.serial.baudrate;
246*4882a593Smuzhiyun 		if (!t->u.serial.enable)
247*4882a593Smuzhiyun 			boot_flags |= GD_FLG_DISABLE_CONSOLE;
248*4882a593Smuzhiyun 		debug("preloader: enable=%d, addr=0x%x, baudrate=%d, id=%d\n",
249*4882a593Smuzhiyun 		      t->u.serial.enable, (u32)t->u.serial.addr,
250*4882a593Smuzhiyun 		      t->u.serial.baudrate, t->u.serial.id);
251*4882a593Smuzhiyun 	} else
252*4882a593Smuzhiyun #endif
253*4882a593Smuzhiyun 	{
254*4882a593Smuzhiyun 		gd->baudrate = CONFIG_BAUDRATE;
255*4882a593Smuzhiyun 		gd->serial.baudrate = CONFIG_BAUDRATE;
256*4882a593Smuzhiyun 		gd->serial.addr = CONFIG_DEBUG_UART_BASE;
257*4882a593Smuzhiyun 	}
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	/* The highest priority to turn off (override) console */
260*4882a593Smuzhiyun #if defined(CONFIG_DISABLE_CONSOLE)
261*4882a593Smuzhiyun 	boot_flags |= GD_FLG_DISABLE_CONSOLE;
262*4882a593Smuzhiyun #endif
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun 	return boot_flags;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun #ifdef CONFIG_SPL_BOARD_INIT
rk_spl_board_init(void)268*4882a593Smuzhiyun __weak int rk_spl_board_init(void)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun 	return 0;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
setup_led(void)273*4882a593Smuzhiyun static int setup_led(void)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun #ifdef CONFIG_SPL_LED
276*4882a593Smuzhiyun 	struct udevice *dev;
277*4882a593Smuzhiyun 	char *led_name;
278*4882a593Smuzhiyun 	int ret;
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	led_name = fdtdec_get_config_string(gd->fdt_blob, "u-boot,boot-led");
281*4882a593Smuzhiyun 	if (!led_name)
282*4882a593Smuzhiyun 		return 0;
283*4882a593Smuzhiyun 	ret = led_get_by_label(led_name, &dev);
284*4882a593Smuzhiyun 	if (ret) {
285*4882a593Smuzhiyun 		debug("%s: get=%d\n", __func__, ret);
286*4882a593Smuzhiyun 		return ret;
287*4882a593Smuzhiyun 	}
288*4882a593Smuzhiyun 	ret = led_set_state(dev, LEDST_ON);
289*4882a593Smuzhiyun 	if (ret)
290*4882a593Smuzhiyun 		return ret;
291*4882a593Smuzhiyun #endif
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 	return 0;
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun 
spl_board_init(void)296*4882a593Smuzhiyun void spl_board_init(void)
297*4882a593Smuzhiyun {
298*4882a593Smuzhiyun 	int ret;
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	ret = setup_led();
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	if (ret) {
303*4882a593Smuzhiyun 		debug("LED ret=%d\n", ret);
304*4882a593Smuzhiyun 		hang();
305*4882a593Smuzhiyun 	}
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	rk_spl_board_init();
308*4882a593Smuzhiyun #if CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)
309*4882a593Smuzhiyun 	back_to_bootrom(BROM_BOOT_NEXTSTAGE);
310*4882a593Smuzhiyun #endif
311*4882a593Smuzhiyun 	return;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun #endif
314*4882a593Smuzhiyun 
spl_perform_fixups(struct spl_image_info * spl_image)315*4882a593Smuzhiyun void spl_perform_fixups(struct spl_image_info *spl_image)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS
318*4882a593Smuzhiyun 	atags_set_bootdev_by_spl_bootdevice(spl_image->boot_device);
319*4882a593Smuzhiyun #endif
320*4882a593Smuzhiyun 	return;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun #ifdef CONFIG_SPL_KERNEL_BOOT
spl_rockchip_dnl_key_pressed(void)324*4882a593Smuzhiyun static int spl_rockchip_dnl_key_pressed(void)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun #if defined(CONFIG_SPL_INPUT)
327*4882a593Smuzhiyun 	return key_read(KEY_VOLUMEUP);
328*4882a593Smuzhiyun #else
329*4882a593Smuzhiyun 	return 0;
330*4882a593Smuzhiyun #endif
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun #ifdef CONFIG_SPL_DM_FUEL_GAUGE
spl_is_low_power(void)334*4882a593Smuzhiyun bool spl_is_low_power(void)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun 	struct udevice *dev;
337*4882a593Smuzhiyun 	int ret, voltage;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	ret = uclass_get_device(UCLASS_FG, 0, &dev);
340*4882a593Smuzhiyun 	if (ret) {
341*4882a593Smuzhiyun 		debug("Get charge display failed, ret=%d\n", ret);
342*4882a593Smuzhiyun 		return false;
343*4882a593Smuzhiyun 	}
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	voltage = fuel_gauge_get_voltage(dev);
346*4882a593Smuzhiyun 	if (voltage >= CONFIG_SPL_POWER_LOW_VOLTAGE_THRESHOLD)
347*4882a593Smuzhiyun 		return false;
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun 	return true;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun #endif
352*4882a593Smuzhiyun 
spl_next_stage(struct spl_image_info * spl)353*4882a593Smuzhiyun void spl_next_stage(struct spl_image_info *spl)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	uint32_t reg_boot_mode;
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun 	if (spl_rockchip_dnl_key_pressed()) {
358*4882a593Smuzhiyun 		spl->next_stage = SPL_NEXT_STAGE_UBOOT;
359*4882a593Smuzhiyun 		return;
360*4882a593Smuzhiyun 	}
361*4882a593Smuzhiyun #ifdef CONFIG_SPL_DM_FUEL_GAUGE
362*4882a593Smuzhiyun 	if (spl_is_low_power()) {
363*4882a593Smuzhiyun 		spl->next_stage = SPL_NEXT_STAGE_UBOOT;
364*4882a593Smuzhiyun 		return;
365*4882a593Smuzhiyun 	}
366*4882a593Smuzhiyun #endif
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	reg_boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG);
369*4882a593Smuzhiyun 	switch (reg_boot_mode) {
370*4882a593Smuzhiyun 	case BOOT_COLD:
371*4882a593Smuzhiyun 	case BOOT_PANIC:
372*4882a593Smuzhiyun 	case BOOT_WATCHDOG:
373*4882a593Smuzhiyun 	case BOOT_NORMAL:
374*4882a593Smuzhiyun 	case BOOT_RECOVERY:
375*4882a593Smuzhiyun 		spl->next_stage = SPL_NEXT_STAGE_KERNEL;
376*4882a593Smuzhiyun 		break;
377*4882a593Smuzhiyun 	default:
378*4882a593Smuzhiyun 		if ((reg_boot_mode & REBOOT_FLAG) != REBOOT_FLAG)
379*4882a593Smuzhiyun 			spl->next_stage = SPL_NEXT_STAGE_KERNEL;
380*4882a593Smuzhiyun 		else
381*4882a593Smuzhiyun 			spl->next_stage = SPL_NEXT_STAGE_UBOOT;
382*4882a593Smuzhiyun 	}
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun #endif
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun #ifdef CONFIG_SPL_KERNEL_BOOT
spl_kernel_partition(struct spl_image_info * spl,struct spl_load_info * info)387*4882a593Smuzhiyun const char *spl_kernel_partition(struct spl_image_info *spl,
388*4882a593Smuzhiyun 				 struct spl_load_info *info)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	struct bootloader_message *bmsg = NULL;
391*4882a593Smuzhiyun 	u32 boot_mode;
392*4882a593Smuzhiyun 	int ret, cnt;
393*4882a593Smuzhiyun 	u32 sector = 0;
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBDISK_SUPPORT
396*4882a593Smuzhiyun 	disk_partition_t part_info;
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun 	ret = part_get_info_by_name(info->dev, PART_MISC, &part_info);
399*4882a593Smuzhiyun 	if (ret >= 0)
400*4882a593Smuzhiyun 		sector = part_info.start;
401*4882a593Smuzhiyun #else
402*4882a593Smuzhiyun 	sector = CONFIG_SPL_MISC_SECTOR;
403*4882a593Smuzhiyun #endif
404*4882a593Smuzhiyun 	if (sector) {
405*4882a593Smuzhiyun 		cnt = DIV_ROUND_UP(sizeof(*bmsg), info->bl_len);
406*4882a593Smuzhiyun 		bmsg = memalign(ARCH_DMA_MINALIGN, cnt * info->bl_len);
407*4882a593Smuzhiyun 		ret = info->read(info, sector + BCB_MESSAGE_BLK_OFFSET,
408*4882a593Smuzhiyun 				 cnt, bmsg);
409*4882a593Smuzhiyun 		if (ret == cnt && !strcmp(bmsg->command, "boot-recovery")) {
410*4882a593Smuzhiyun 			free(bmsg);
411*4882a593Smuzhiyun 			return PART_RECOVERY;
412*4882a593Smuzhiyun 		} else {
413*4882a593Smuzhiyun 			free(bmsg);
414*4882a593Smuzhiyun 		}
415*4882a593Smuzhiyun 	}
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	boot_mode = readl((void *)CONFIG_ROCKCHIP_BOOT_MODE_REG);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	return (boot_mode == BOOT_RECOVERY) ? PART_RECOVERY : PART_BOOT;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun #endif
422*4882a593Smuzhiyun 
spl_hang_reset(void)423*4882a593Smuzhiyun void spl_hang_reset(void)
424*4882a593Smuzhiyun {
425*4882a593Smuzhiyun 	printf("# Reset the board to bootrom #\n");
426*4882a593Smuzhiyun #if defined(CONFIG_SPL_SYSRESET) && defined(CONFIG_SPL_DRIVERS_MISC_SUPPORT)
427*4882a593Smuzhiyun 	/* reset is available after dm setup */
428*4882a593Smuzhiyun 	if (gd->flags & GD_FLG_SPL_EARLY_INIT) {
429*4882a593Smuzhiyun 		writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
430*4882a593Smuzhiyun 		do_reset(NULL, 0, 0, NULL);
431*4882a593Smuzhiyun 	}
432*4882a593Smuzhiyun #endif
433*4882a593Smuzhiyun }
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun #ifdef CONFIG_SPL_FIT_ROLLBACK_PROTECT
fit_read_otp_rollback_index(uint32_t fit_index,uint32_t * otp_index)436*4882a593Smuzhiyun int fit_read_otp_rollback_index(uint32_t fit_index, uint32_t *otp_index)
437*4882a593Smuzhiyun {
438*4882a593Smuzhiyun 	int ret = 0;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	*otp_index = 0;
441*4882a593Smuzhiyun #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP)
442*4882a593Smuzhiyun 	struct udevice *dev;
443*4882a593Smuzhiyun 	u32 index, i, otp_version;
444*4882a593Smuzhiyun 	u32 bit_count;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	dev = misc_otp_get_device(OTP_S);
447*4882a593Smuzhiyun 	if (!dev)
448*4882a593Smuzhiyun 		return -ENODEV;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	otp_version = 0;
451*4882a593Smuzhiyun 	for (i = 0; i < OTP_UBOOT_ROLLBACK_WORDS; i++) {
452*4882a593Smuzhiyun 		if (misc_otp_read(dev, OTP_UBOOT_ROLLBACK_OFFSET + i * 4,
453*4882a593Smuzhiyun 		    &index,
454*4882a593Smuzhiyun 		    4)) {
455*4882a593Smuzhiyun 			printf("Can't read rollback index\n");
456*4882a593Smuzhiyun 			return -EIO;
457*4882a593Smuzhiyun 		}
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 		bit_count = fls(index);
460*4882a593Smuzhiyun 		otp_version += bit_count;
461*4882a593Smuzhiyun 	}
462*4882a593Smuzhiyun 	*otp_index = otp_version;
463*4882a593Smuzhiyun #endif
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	return ret;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun 
fit_write_otp_rollback_index(u32 fit_index)468*4882a593Smuzhiyun static int fit_write_otp_rollback_index(u32 fit_index)
469*4882a593Smuzhiyun {
470*4882a593Smuzhiyun #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP)
471*4882a593Smuzhiyun 	struct udevice *dev;
472*4882a593Smuzhiyun 	u32 index, i, otp_index;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	if (!fit_index)
475*4882a593Smuzhiyun 		return 0;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	if (fit_index > OTP_UBOOT_ROLLBACK_WORDS * 32)
478*4882a593Smuzhiyun 		return -EINVAL;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 	dev = misc_otp_get_device(OTP_S);
481*4882a593Smuzhiyun 	if (!dev)
482*4882a593Smuzhiyun 		return -ENODEV;
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	if (fit_read_otp_rollback_index(fit_index, &otp_index))
485*4882a593Smuzhiyun 		return -EIO;
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	if (otp_index < fit_index) {
488*4882a593Smuzhiyun 		/* Write new SW version to otp */
489*4882a593Smuzhiyun 		for (i = 0; i < OTP_UBOOT_ROLLBACK_WORDS; i++) {
490*4882a593Smuzhiyun 			/*
491*4882a593Smuzhiyun 			 * If fit_index is equal to 0, then execute 0xffffffff >> 32.
492*4882a593Smuzhiyun 			 * But the operand can only be 0 - 31. The "0xffffffff >> 32" is
493*4882a593Smuzhiyun 			 * actually be "0xffffffff >> 0".
494*4882a593Smuzhiyun 			 */
495*4882a593Smuzhiyun 			if (!fit_index)
496*4882a593Smuzhiyun 				break;
497*4882a593Smuzhiyun 			/* convert to base-1 representation */
498*4882a593Smuzhiyun 			index = 0xffffffff >> (OTP_ALL_ONES_NUM_BITS -
499*4882a593Smuzhiyun 				min(fit_index, (u32)OTP_ALL_ONES_NUM_BITS));
500*4882a593Smuzhiyun 			fit_index -= min(fit_index,
501*4882a593Smuzhiyun 					  (u32)OTP_ALL_ONES_NUM_BITS);
502*4882a593Smuzhiyun 			if (index) {
503*4882a593Smuzhiyun 				if (misc_otp_write(dev, OTP_UBOOT_ROLLBACK_OFFSET + i * 4,
504*4882a593Smuzhiyun 				    &index,
505*4882a593Smuzhiyun 				    4)) {
506*4882a593Smuzhiyun 					printf("Can't write rollback index\n");
507*4882a593Smuzhiyun 					return -EIO;
508*4882a593Smuzhiyun 				}
509*4882a593Smuzhiyun 			}
510*4882a593Smuzhiyun 		}
511*4882a593Smuzhiyun 	}
512*4882a593Smuzhiyun #endif
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	return 0;
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun #endif
517*4882a593Smuzhiyun 
spl_board_prepare_for_jump(struct spl_image_info * spl_image)518*4882a593Smuzhiyun int spl_board_prepare_for_jump(struct spl_image_info *spl_image)
519*4882a593Smuzhiyun {
520*4882a593Smuzhiyun #ifdef CONFIG_SPL_FIT_ROLLBACK_PROTECT
521*4882a593Smuzhiyun 	int ret;
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	ret = fit_write_otp_rollback_index(gd->rollback_index);
524*4882a593Smuzhiyun 	if (ret) {
525*4882a593Smuzhiyun 		panic("Failed to write fit rollback index %d, ret=%d",
526*4882a593Smuzhiyun 		      gd->rollback_index, ret);
527*4882a593Smuzhiyun 	}
528*4882a593Smuzhiyun #endif
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun #ifdef CONFIG_SPL_ROCKCHIP_HW_DECOMPRESS
531*4882a593Smuzhiyun 	misc_decompress_cleanup();
532*4882a593Smuzhiyun #endif
533*4882a593Smuzhiyun 	return 0;
534*4882a593Smuzhiyun }
535