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 *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