xref: /openbmc/u-boot/arch/arm/mach-rockchip/boot_mode.c (revision f07d76c00d1fe05baad1599d01d07a9226498923)
1e3067793SAndy Yan /*
2e3067793SAndy Yan  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
3e3067793SAndy Yan  *
4e3067793SAndy Yan  * SPDX-License-Identifier:     GPL-2.0+
5e3067793SAndy Yan  */
6e3067793SAndy Yan 
7e3067793SAndy Yan #include <common.h>
8ecb103bfSAndy Yan #include <adc.h>
9e3067793SAndy Yan #include <asm/io.h>
10e3067793SAndy Yan #include <asm/arch/boot_mode.h>
11e3067793SAndy Yan 
12*f07d76c0SPhilipp Tomsich #if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0)
13*f07d76c0SPhilipp Tomsich 
14*f07d76c0SPhilipp Tomsich int setup_boot_mode(void)
15*f07d76c0SPhilipp Tomsich {
16*f07d76c0SPhilipp Tomsich 	return 0;
17*f07d76c0SPhilipp Tomsich }
18*f07d76c0SPhilipp Tomsich 
19*f07d76c0SPhilipp Tomsich #else
20*f07d76c0SPhilipp Tomsich 
21ecb103bfSAndy Yan void set_back_to_bootrom_dnl_flag(void)
22ecb103bfSAndy Yan {
23ecb103bfSAndy Yan 	writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
24ecb103bfSAndy Yan }
25ecb103bfSAndy Yan 
26ecb103bfSAndy Yan /*
27ecb103bfSAndy Yan  * detect download key status by adc, most rockchip
28ecb103bfSAndy Yan  * based boards use adc sample the download key status,
29ecb103bfSAndy Yan  * but there are also some use gpio. So it's better to
30ecb103bfSAndy Yan  * make this a weak function that can be override by
31ecb103bfSAndy Yan  * some special boards.
32ecb103bfSAndy Yan  */
33ecb103bfSAndy Yan #define KEY_DOWN_MIN_VAL	0
34ecb103bfSAndy Yan #define KEY_DOWN_MAX_VAL	30
35ecb103bfSAndy Yan 
36ecb103bfSAndy Yan __weak int rockchip_dnl_key_pressed(void)
37ecb103bfSAndy Yan {
38ecb103bfSAndy Yan 	unsigned int val;
39ecb103bfSAndy Yan 
40ecb103bfSAndy Yan 	if (adc_channel_single_shot("saradc", 1, &val)) {
41ecb103bfSAndy Yan 		pr_err("%s: adc_channel_single_shot fail!\n", __func__);
42ecb103bfSAndy Yan 		return false;
43ecb103bfSAndy Yan 	}
44ecb103bfSAndy Yan 
45ecb103bfSAndy Yan 	if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
46ecb103bfSAndy Yan 		return true;
47ecb103bfSAndy Yan 	else
48ecb103bfSAndy Yan 		return false;
49ecb103bfSAndy Yan }
50ecb103bfSAndy Yan 
51ecb103bfSAndy Yan void rockchip_dnl_mode_check(void)
52ecb103bfSAndy Yan {
53ecb103bfSAndy Yan 	if (rockchip_dnl_key_pressed()) {
54ecb103bfSAndy Yan 		printf("download key pressed, entering download mode...");
55ecb103bfSAndy Yan 		set_back_to_bootrom_dnl_flag();
56ecb103bfSAndy Yan 		do_reset(NULL, 0, 0, NULL);
57ecb103bfSAndy Yan 	}
58ecb103bfSAndy Yan }
59ecb103bfSAndy Yan 
60e3067793SAndy Yan int setup_boot_mode(void)
61e3067793SAndy Yan {
62e3067793SAndy Yan 	void *reg = (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG;
63e3067793SAndy Yan 	int boot_mode = readl(reg);
64e3067793SAndy Yan 
65ecb103bfSAndy Yan 	rockchip_dnl_mode_check();
66ecb103bfSAndy Yan 
67ecb103bfSAndy Yan 	boot_mode = readl(reg);
68ecb103bfSAndy Yan 	debug("%s: boot mode 0x%08x\n", __func__, boot_mode);
69e3067793SAndy Yan 
70e3067793SAndy Yan 	/* Clear boot mode */
71e3067793SAndy Yan 	writel(BOOT_NORMAL, reg);
72e3067793SAndy Yan 
73e3067793SAndy Yan 	switch (boot_mode) {
74e3067793SAndy Yan 	case BOOT_FASTBOOT:
75ecb103bfSAndy Yan 		debug("%s: enter fastboot!\n", __func__);
76e3067793SAndy Yan 		env_set("preboot", "setenv preboot; fastboot usb0");
77e3067793SAndy Yan 		break;
78e3067793SAndy Yan 	case BOOT_UMS:
79ecb103bfSAndy Yan 		debug("%s: enter UMS!\n", __func__);
80e3067793SAndy Yan 		env_set("preboot", "setenv preboot; ums mmc 0");
81e3067793SAndy Yan 		break;
82e3067793SAndy Yan 	}
83e3067793SAndy Yan 
84e3067793SAndy Yan 	return 0;
85e3067793SAndy Yan }
86*f07d76c0SPhilipp Tomsich 
87*f07d76c0SPhilipp Tomsich #endif
88