blob: 349c0648a6db22be66e5e8a2bb0092542320e739 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Yan70378cb2017-10-11 15:00:16 +08002/*
3 * (C) Copyright 2016 Rockchip Electronics Co., Ltd
Andy Yan70378cb2017-10-11 15:00:16 +08004 */
5
6#include <common.h>
Andy Yan215db9c2017-10-11 15:01:31 +08007#include <adc.h>
Simon Glassed38aef2020-05-10 11:40:03 -06008#include <command.h>
9#include <env.h>
Andy Yan70378cb2017-10-11 15:00:16 +080010#include <asm/io.h>
Kever Yang9fbe17c2019-03-28 11:01:23 +080011#include <asm/arch-rockchip/boot_mode.h>
Hugh Cole-Baker82820942020-01-25 16:19:36 +000012#include <dm/device.h>
13#include <dm/uclass.h>
Andy Yan70378cb2017-10-11 15:00:16 +080014
Philipp Tomsich3a0df082017-11-24 14:44:58 +010015#if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0)
16
17int setup_boot_mode(void)
18{
19 return 0;
20}
21
22#else
23
Andy Yan215db9c2017-10-11 15:01:31 +080024void set_back_to_bootrom_dnl_flag(void)
25{
26 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
27}
28
29/*
30 * detect download key status by adc, most rockchip
31 * based boards use adc sample the download key status,
32 * but there are also some use gpio. So it's better to
33 * make this a weak function that can be override by
34 * some special boards.
35 */
36#define KEY_DOWN_MIN_VAL 0
37#define KEY_DOWN_MAX_VAL 30
38
39__weak int rockchip_dnl_key_pressed(void)
40{
41 unsigned int val;
Hugh Cole-Baker82820942020-01-25 16:19:36 +000042 struct udevice *dev;
43 struct uclass *uc;
44 int ret;
45
46 ret = uclass_get(UCLASS_ADC, &uc);
47 if (ret)
48 return false;
49
50 ret = -ENODEV;
51 uclass_foreach_dev(dev, uc) {
52 if (!strncmp(dev->name, "saradc", 6)) {
53 ret = adc_channel_single_shot(dev->name, 1, &val);
54 break;
55 }
56 }
Andy Yan215db9c2017-10-11 15:01:31 +080057
Hugh Cole-Baker82820942020-01-25 16:19:36 +000058 if (ret == -ENODEV) {
59 pr_warn("%s: no saradc device found\n", __func__);
60 return false;
61 } else if (ret) {
Andy Yan215db9c2017-10-11 15:01:31 +080062 pr_err("%s: adc_channel_single_shot fail!\n", __func__);
63 return false;
64 }
65
66 if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
67 return true;
68 else
69 return false;
70}
71
72void rockchip_dnl_mode_check(void)
73{
74 if (rockchip_dnl_key_pressed()) {
75 printf("download key pressed, entering download mode...");
76 set_back_to_bootrom_dnl_flag();
77 do_reset(NULL, 0, 0, NULL);
78 }
79}
80
Andy Yan70378cb2017-10-11 15:00:16 +080081int setup_boot_mode(void)
82{
83 void *reg = (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG;
84 int boot_mode = readl(reg);
85
Philipp Tomsiche91b8452019-03-29 09:21:13 +010086 rockchip_dnl_mode_check();
Andy Yan215db9c2017-10-11 15:01:31 +080087
88 boot_mode = readl(reg);
89 debug("%s: boot mode 0x%08x\n", __func__, boot_mode);
Andy Yan70378cb2017-10-11 15:00:16 +080090
91 /* Clear boot mode */
92 writel(BOOT_NORMAL, reg);
93
94 switch (boot_mode) {
95 case BOOT_FASTBOOT:
Andy Yan215db9c2017-10-11 15:01:31 +080096 debug("%s: enter fastboot!\n", __func__);
Andy Yan70378cb2017-10-11 15:00:16 +080097 env_set("preboot", "setenv preboot; fastboot usb0");
98 break;
99 case BOOT_UMS:
Andy Yan215db9c2017-10-11 15:01:31 +0800100 debug("%s: enter UMS!\n", __func__);
Andy Yan70378cb2017-10-11 15:00:16 +0800101 env_set("preboot", "setenv preboot; ums mmc 0");
102 break;
103 }
104
105 return 0;
106}
Philipp Tomsich3a0df082017-11-24 14:44:58 +0100107
108#endif