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