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