xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/boot_mode.c (revision 9fa74d15b8bbfcd01422cbb0d3be7683aa5fcca1)
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 <asm/arch/param.h>
12 #include <cli.h>
13 #include <dm.h>
14 #include <fdtdec.h>
15 #include <boot_rkimg.h>
16 #include <linux/usb/phy-rockchip-inno-usb2.h>
17 #include <key.h>
18 #ifdef CONFIG_DM_RAMDISK
19 #include <ramdisk.h>
20 #endif
21 #include <mmc.h>
22 
23 DECLARE_GLOBAL_DATA_PTR;
24 
25 #if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0)
26 
27 int setup_boot_mode(void)
28 {
29 	return 0;
30 }
31 
32 #else
33 
34 void set_back_to_bootrom_dnl_flag(void)
35 {
36 	writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
37 }
38 
39 /*
40  * detect download key status by adc, most rockchip
41  * based boards use adc sample the download key status,
42  * but there are also some use gpio. So it's better to
43  * make this a weak function that can be override by
44  * some special boards.
45  */
46 #define KEY_DOWN_MIN_VAL	0
47 #define KEY_DOWN_MAX_VAL	30
48 
49 __weak int rockchip_dnl_key_pressed(void)
50 {
51 	int keyval = false;
52 
53 /*
54  * This is a generic interface to read key
55  */
56 #if defined(CONFIG_DM_KEY)
57 	keyval = key_read(KEY_VOLUMEUP);
58 
59 	return key_is_pressed(keyval);
60 
61 #elif defined(CONFIG_ADC)
62 	const void *blob = gd->fdt_blob;
63 	unsigned int val;
64 	int channel = 1;
65 	int node;
66 	int ret;
67 	u32 chns[2];
68 
69 	node = fdt_node_offset_by_compatible(blob, 0, "adc-keys");
70 	if (node >= 0) {
71 	       if (!fdtdec_get_int_array(blob, node, "io-channels", chns, 2))
72 		       channel = chns[1];
73 	}
74 
75 	ret = adc_channel_single_shot("saradc", channel, &val);
76 	if (ret) {
77 		printf("%s adc_channel_single_shot fail! ret=%d\n", __func__, ret);
78 		return false;
79 	}
80 
81 	if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
82 		return true;
83 	else
84 		return false;
85 #endif
86 
87 	return keyval;
88 }
89 
90 void boot_devtype_init(void)
91 {
92 	const char *devtype_num_set = "run rkimg_bootdev";
93 	char *devtype = NULL, *devnum = NULL;
94 	static int done = 0;
95 	int atags_en = 0;
96 	int ret;
97 
98 	if (done)
99 		return;
100 
101 	ret = param_parse_bootdev(&devtype, &devnum);
102 	if (!ret) {
103 		atags_en = 1;
104 		env_set("devtype", devtype);
105 		env_set("devnum", devnum);
106 #ifdef CONFIG_DM_MMC
107 		if (!strcmp("mmc", devtype))
108 			mmc_initialize(gd->bd);
109 #endif
110 	} else {
111 #ifdef CONFIG_DM_MMC
112 		mmc_initialize(gd->bd);
113 #endif
114 		ret = run_command_list(devtype_num_set, -1, 0);
115 		if (ret) {
116 			/* Set default dev type/num if command not valid */
117 			devtype = "mmc";
118 			devnum = "0";
119 			env_set("devtype", devtype);
120 			env_set("devnum", devnum);
121 		}
122 	}
123 
124 	done = 1;
125 	printf("Bootdev%s: %s %s\n", atags_en ? "(atags)" : "",
126 	       env_get("devtype"), env_get("devnum"));
127 }
128 
129 void rockchip_dnl_mode_check(void)
130 {
131 	if (rockchip_dnl_key_pressed()) {
132 		printf("download key pressed... ");
133 		if (rockchip_u2phy_vbus_detect() > 0) {
134 			printf("entering download mode...\n");
135 			/* If failed, we fall back to bootrom download mode */
136 			run_command_list("rockusb 0 ${devtype} ${devnum}", -1, 0);
137 			set_back_to_bootrom_dnl_flag();
138 			do_reset(NULL, 0, 0, NULL);
139 		} else {
140 			printf("\n");
141 #ifdef CONFIG_RKIMG_BOOTLOADER
142 			/* If there is no recovery partition, just boot on */
143 			struct blk_desc *dev_desc;
144 			disk_partition_t part_info;
145 
146 			dev_desc = rockchip_get_bootdev();
147 			if (!dev_desc) {
148 				printf("%s: dev_desc is NULL!\n", __func__);
149 				return;
150 			}
151 			if (part_get_info_by_name(dev_desc, PART_RECOVERY,
152 						  &part_info)) {
153 				debug("%s: no recovery partition\n", __func__);
154 				return;
155 			}
156 #endif
157 			printf("recovery key pressed, entering recovery mode!\n");
158 			env_set("reboot_mode", "recovery");
159 		}
160 	}
161 }
162 
163 int setup_boot_mode(void)
164 {
165 	int boot_mode = BOOT_MODE_NORMAL;
166 	char env_preboot[256] = {0};
167 
168 	boot_devtype_init();
169 	rockchip_dnl_mode_check();
170 #ifdef CONFIG_RKIMG_BOOTLOADER
171 	boot_mode = rockchip_get_boot_mode();
172 #endif
173 	switch (boot_mode) {
174 	case BOOT_MODE_BOOTLOADER:
175 		printf("enter fastboot!\n");
176 #if defined(CONFIG_FASTBOOT_FLASH_MMC_DEV)
177 		snprintf(env_preboot, 256,
178 				"setenv preboot; mmc dev %x; fastboot usb 0; ",
179 				CONFIG_FASTBOOT_FLASH_MMC_DEV);
180 #elif defined(CONFIG_FASTBOOT_FLASH_NAND_DEV)
181 		snprintf(env_preboot, 256,
182 				"setenv preboot; fastboot usb 0; ");
183 #endif
184 		env_set("preboot", env_preboot);
185 		break;
186 	case BOOT_MODE_UMS:
187 		printf("enter UMS!\n");
188 		env_set("preboot", "setenv preboot; ums mmc 0");
189 		break;
190 	case BOOT_MODE_LOADER:
191 		printf("enter Rockusb!\n");
192 		env_set("preboot", "setenv preboot; rockusb 0 ${devtype} ${devnum}");
193 		break;
194 	case BOOT_MODE_CHARGING:
195 		printf("enter charging!\n");
196 		env_set("preboot", "setenv preboot; charge");
197 		break;
198 	case BOOT_MODE_RECOVERY:
199 		printf("enter Recovery mode!\n");
200 		env_set("reboot_mode", "recovery");
201 		break;
202 	}
203 
204 	return 0;
205 }
206 
207 #endif
208