xref: /rk3399_rockchip-uboot/drivers/sysreset/sysreset-syscon-reboot.c (revision 8f7de5145da2de88e169e58343cceeee233362d4)
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 
24 static int syscon_reboot_request_by_mode(struct udevice *dev, const char *str)
25 {
26 	const char *prefix = CMD_PREFIX;
27 	const char *mode;
28 	char *command;
29 	u32 magic;
30 	int i;
31 
32 	mode = str ? str : "normal";
33 	command = calloc(1, strlen(mode) + sizeof(prefix));
34 	if (!command)
35 		return -ENOMEM;
36 
37 	strcat(command, prefix);
38 	strcat(command, mode);
39 
40 	magic = dev_read_u32_default(dev, command, -EINVAL);
41 	if (magic == -EINVAL) {
42 		for (i = 0; i < ARRAY_SIZE(static_defined_command); i++) {
43 			if (!strcmp(static_defined_command[i].name, mode)) {
44 				magic = static_defined_command[i].magic;
45 				break;
46 			}
47 		}
48 	}
49 
50 	debug("## Reboot mode: %s(%x)\n\n", mode, magic);
51 
52 	writel(magic, CONFIG_ROCKCHIP_BOOT_MODE_REG);
53 	free(command);
54 
55 	return 0;
56 }
57 
58 static const struct sysreset_ops syscon_reboot_ops = {
59 	.request_by_mode = syscon_reboot_request_by_mode,
60 };
61 
62 static const struct udevice_id syscon_reboot_match[] = {
63 	{ .compatible = "syscon-reboot-mode", },
64 	{},
65 };
66 
67 U_BOOT_DRIVER(sysreset_syscon_reboot) = {
68 	.name = "sysreset_syscon_reboot",
69 	.id = UCLASS_SYSRESET,
70 	.of_match = syscon_reboot_match,
71 	.ops = &syscon_reboot_ops,
72 };
73