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