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