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