1 /*
2 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0
5 */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <sysreset.h>
10 #include <linux/io.h>
11 #include <asm/arch/boot_mode.h>
12
13 #define CMD_PREFIX "mode-"
14
15 struct command {
16 const char *name;
17 u32 magic;
18 };
19
20 static const struct command static_defined_command[] = {
21 { .name = "bootrom", .magic = BOOT_BROM_DOWNLOAD, }
22 };
23
syscon_reboot_request_by_mode(struct udevice * dev,const char * mode)24 static int syscon_reboot_request_by_mode(struct udevice *dev, const char *mode)
25 {
26 const char *prefix = CMD_PREFIX;
27 char *command;
28 u32 magic;
29 int i;
30
31 if (!mode)
32 return 0;
33
34 command = calloc(1, strlen(mode) + sizeof(prefix));
35 if (!command)
36 return -ENOMEM;
37
38 strcat(command, prefix);
39 strcat(command, mode);
40
41 magic = dev_read_u32_default(dev, command, BOOT_NORMAL);
42 if (magic == BOOT_NORMAL) {
43 for (i = 0; i < ARRAY_SIZE(static_defined_command); i++) {
44 if (!strcmp(static_defined_command[i].name, mode)) {
45 magic = static_defined_command[i].magic;
46 break;
47 }
48 }
49 }
50
51 printf("## Reboot mode: %s(%x)\n\n", mode, magic);
52
53 writel(magic, CONFIG_ROCKCHIP_BOOT_MODE_REG);
54 free(command);
55
56 return 0;
57 }
58
59 static const struct sysreset_ops syscon_reboot_ops = {
60 .request_by_mode = syscon_reboot_request_by_mode,
61 };
62
63 static const struct udevice_id syscon_reboot_match[] = {
64 { .compatible = "syscon-reboot-mode", },
65 {},
66 };
67
68 U_BOOT_DRIVER(sysreset_syscon_reboot) = {
69 .name = "sysreset_syscon_reboot",
70 .id = UCLASS_SYSRESET,
71 .of_match = syscon_reboot_match,
72 .ops = &syscon_reboot_ops,
73 };
74