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