blob: 55e9456668ae727a1afbc7e976e2218f1c362ad3 [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
Andy Yan215db9c2017-10-11 15:01:31 +08006#include <adc.h>
Simon Glassed38aef2020-05-10 11:40:03 -06007#include <command.h>
8#include <env.h>
Simon Glass0f2af882020-05-10 11:40:05 -06009#include <log.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>
Simon Glassbdd5f812023-09-14 18:21:46 -060014#include <linux/printk.h>
Andy Yan70378cb2017-10-11 15:00:16 +080015
Philipp Tomsich3a0df082017-11-24 14:44:58 +010016#if (CONFIG_ROCKCHIP_BOOT_MODE_REG == 0)
17
18int setup_boot_mode(void)
19{
20 return 0;
21}
22
23#else
24
Andy Yan215db9c2017-10-11 15:01:31 +080025void set_back_to_bootrom_dnl_flag(void)
26{
27 writel(BOOT_BROM_DOWNLOAD, CONFIG_ROCKCHIP_BOOT_MODE_REG);
28}
29
30/*
31 * detect download key status by adc, most rockchip
32 * based boards use adc sample the download key status,
33 * but there are also some use gpio. So it's better to
34 * make this a weak function that can be override by
35 * some special boards.
36 */
37#define KEY_DOWN_MIN_VAL 0
38#define KEY_DOWN_MAX_VAL 30
39
40__weak int rockchip_dnl_key_pressed(void)
41{
Quentin Schulzcc56d922024-03-14 10:36:29 +010042#if CONFIG_IS_ENABLED(ADC)
Andy Yan215db9c2017-10-11 15:01:31 +080043 unsigned int val;
Hugh Cole-Baker82820942020-01-25 16:19:36 +000044 struct udevice *dev;
45 struct uclass *uc;
46 int ret;
47
48 ret = uclass_get(UCLASS_ADC, &uc);
49 if (ret)
50 return false;
51
52 ret = -ENODEV;
53 uclass_foreach_dev(dev, uc) {
54 if (!strncmp(dev->name, "saradc", 6)) {
55 ret = adc_channel_single_shot(dev->name, 1, &val);
56 break;
57 }
58 }
Andy Yan215db9c2017-10-11 15:01:31 +080059
Hugh Cole-Baker82820942020-01-25 16:19:36 +000060 if (ret == -ENODEV) {
61 pr_warn("%s: no saradc device found\n", __func__);
62 return false;
63 } else if (ret) {
Andy Yan215db9c2017-10-11 15:01:31 +080064 pr_err("%s: adc_channel_single_shot fail!\n", __func__);
65 return false;
66 }
67
68 if ((val >= KEY_DOWN_MIN_VAL) && (val <= KEY_DOWN_MAX_VAL))
69 return true;
70 else
71 return false;
Quentin Schulzcc56d922024-03-14 10:36:29 +010072#else
73 return false;
74#endif
Andy Yan215db9c2017-10-11 15:01:31 +080075}
76
77void rockchip_dnl_mode_check(void)
78{
79 if (rockchip_dnl_key_pressed()) {
80 printf("download key pressed, entering download mode...");
81 set_back_to_bootrom_dnl_flag();
82 do_reset(NULL, 0, 0, NULL);
83 }
84}
85
Andy Yan70378cb2017-10-11 15:00:16 +080086int setup_boot_mode(void)
87{
88 void *reg = (void *)CONFIG_ROCKCHIP_BOOT_MODE_REG;
89 int boot_mode = readl(reg);
90
Philipp Tomsiche91b8452019-03-29 09:21:13 +010091 rockchip_dnl_mode_check();
Andy Yan215db9c2017-10-11 15:01:31 +080092
93 boot_mode = readl(reg);
94 debug("%s: boot mode 0x%08x\n", __func__, boot_mode);
Andy Yan70378cb2017-10-11 15:00:16 +080095
96 /* Clear boot mode */
97 writel(BOOT_NORMAL, reg);
98
99 switch (boot_mode) {
100 case BOOT_FASTBOOT:
Andy Yan215db9c2017-10-11 15:01:31 +0800101 debug("%s: enter fastboot!\n", __func__);
John Keeping1a76b3a2021-11-25 18:05:22 +0000102 env_set("preboot", "setenv preboot; fastboot usb 0");
Andy Yan70378cb2017-10-11 15:00:16 +0800103 break;
104 case BOOT_UMS:
Andy Yan215db9c2017-10-11 15:01:31 +0800105 debug("%s: enter UMS!\n", __func__);
Andy Yan70378cb2017-10-11 15:00:16 +0800106 env_set("preboot", "setenv preboot; ums mmc 0");
107 break;
108 }
109
110 return 0;
111}
Philipp Tomsich3a0df082017-11-24 14:44:58 +0100112
113#endif