xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/boot_mode.c (revision 3c3675ddd7dfb95c8dc592003d9f5feb2e081ff9)
1 /*
2  * (C) Copyright 2016 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <adc.h>
9 #include <asm/io.h>
10 #include <asm/arch/boot_mode.h>
11 #include <cli.h>
12 #include <dm.h>
13 #include <fdtdec.h>
14 #include <boot_rkimg.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0)
19 
20 int setup_boot_mode(void)
21 {
22 	return 0;
23 }
24 
25 #else
26 
27 void set_back_to_bootrom_dnl_flag(void)
28 {
29 	writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
30 }
31 
32 /*
33  * detect download key status by adc, most rockchip
34  * based boards use adc sample the download key status,
35  * but there are also some use gpio. So it's better to
36  * make this a weak function that can be override by
37  * some special boards.
38  */
39 #define KEY_DOWN_MIN_VAL	0
40 #define KEY_DOWN_MAX_VAL	30
41 
42 __weak int rockchip_dnl_key_pressed(void)
43 {
44 	const void *blob = gd->fdt_blob;
45 	unsigned int val;
46 	int channel = 1;
47 	int node;
48 	u32 chns[2];
49 
50 	node = fdt_node_offset_by_compatible(blob, 0, "adc-keys");
51 	if (node >= 0) {
52 	       if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2))
53 		       channel = chns[1];
54 	}
55 
56 	if (adc_channel_single_shot("saradc", channel, &val)) {
57 		printf("%s adc_channel_single_shot fail!\n", __func__);
58 		return false;
59 	}
60 
61 	if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
62 		return true;
63 	else
64 		return false;
65 }
66 
67 void devtype_num_envset(void)
68 {
69 	static int done = 0;
70 
71 	if (done)
72 		return;
73 
74 	const char *devtype_num_set =
75 	"if mmc dev 0; then setenv devtype mmc; setenv devnum 0;"
76 	"else if rknand dev 0; then setenv devtype rknand; setenv devnum 0; fi;"
77 	"fi;";
78 
79 	run_command_list(devtype_num_set, -1, 0);
80 	done = 1;
81 }
82 
83 void rockchip_dnl_mode_check(void)
84 {
85 	if (rockchip_dnl_key_pressed()) {
86 		printf("download key pressed, entering download mode...\n");
87 		/* If failed, we fall back to bootrom download mode */
88 		run_command_list("rockusb 0 ${devtype} ${devnum}", -1, 0);
89 		set_back_to_bootrom_dnl_flag();
90 		do_reset(NULL, 0, 0, NULL);
91 	}
92 }
93 
94 int setup_boot_mode(void)
95 {
96 	int boot_mode = BOOT_MODE_NORMAL;
97 	char env_preboot[256] = {0};
98 
99 	devtype_num_envset();
100 	rockchip_dnl_mode_check();
101 #ifdef CONFIG_RKIMG_BOOTLOADER
102 	boot_mode = rockchip_get_boot_mode();
103 #endif
104 	switch (boot_mode) {
105 	case BOOT_MODE_BOOTLOADER:
106 		printf("enter fastboot!\n");
107 #if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV)
108 		snprintf(env_preboot, 256,
109 				"setenv preboot; mmc dev %x; fastboot usb 0; ",
110 				CONFIG_FASTBOOT_FLASH_MMC_DEV);
111 #elif defined(CONFIG_FASTBOOT_FLASH_NAND_DEV)
112 		snprintf(env_preboot, 256,
113 				"setenv preboot; fastboot usb 0; ");
114 #endif
115 		env_set("preboot", env_preboot);
116 		break;
117 	case BOOT_MODE_UMS:
118 		printf("enter UMS!\n");
119 		env_set("preboot", "setenv preboot; ums mmc 0");
120 		break;
121 	case BOOT_MODE_LOADER:
122 		printf("enter Rockusb!\n");
123 		env_set("preboot", "setenv preboot; rockusb 0 ${devtype} ${devnum}");
124 		break;
125 	case BOOT_MODE_CHARGING:
126 		printf("enter charging!\n");
127 		env_set("preboot", "setenv preboot; charge");
128 		break;
129 	case BOOT_MODE_RECOVERY:
130 		printf("enter Recovery mode!\n");
131 		env_set("reboot_mode", "recovery");
132 		break;
133 	}
134 
135 	return 0;
136 }
137 
138 #endif
139