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