1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 4 * Texas Instruments Incorporated - http://www.ti.com/ 5 */ 6 #include <common.h> 7 #include <command.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <remoteproc.h> 12 13 /** 14 * print_remoteproc_list() - print all the remote processor devices 15 * 16 * Return: 0 if no error, else returns appropriate error value. 17 */ 18 static int print_remoteproc_list(void) 19 { 20 struct udevice *dev; 21 struct uclass *uc; 22 int ret; 23 char *type; 24 25 ret = uclass_get(UCLASS_REMOTEPROC, &uc); 26 if (ret) { 27 printf("Cannot find Remote processor class\n"); 28 return ret; 29 } 30 31 uclass_foreach_dev(dev, uc) { 32 struct dm_rproc_uclass_pdata *uc_pdata; 33 const struct dm_rproc_ops *ops = rproc_get_ops(dev); 34 35 uc_pdata = dev_get_uclass_platdata(dev); 36 37 switch (uc_pdata->mem_type) { 38 case RPROC_INTERNAL_MEMORY_MAPPED: 39 type = "internal memory mapped"; 40 break; 41 default: 42 type = "unknown"; 43 break; 44 } 45 printf("%d - Name:'%s' type:'%s' supports: %s%s%s%s%s%s\n", 46 dev->seq, 47 uc_pdata->name, 48 type, 49 ops->load ? "load " : "", 50 ops->start ? "start " : "", 51 ops->stop ? "stop " : "", 52 ops->reset ? "reset " : "", 53 ops->is_running ? "is_running " : "", 54 ops->ping ? "ping " : ""); 55 } 56 return 0; 57 } 58 59 /** 60 * do_rproc_init() - do basic initialization 61 * @cmdtp: unused 62 * @flag: unused 63 * @argc: unused 64 * @argv: unused 65 * 66 * Return: 0 if no error, else returns appropriate error value. 67 */ 68 static int do_rproc_init(cmd_tbl_t *cmdtp, int flag, int argc, 69 char *const argv[]) 70 { 71 if (rproc_is_initialized()) { 72 printf("\tRemote Processors are already initialized\n"); 73 } else { 74 if (!rproc_init()) 75 return 0; 76 printf("Few Remote Processors failed to be initalized\n"); 77 } 78 79 return CMD_RET_FAILURE; 80 } 81 82 /** 83 * do_remoteproc_list() - print list of remote proc devices. 84 * @cmdtp: unused 85 * @flag: unused 86 * @argc: unused 87 * @argv: unused 88 * 89 * Return: 0 if no error, else returns appropriate error value. 90 */ 91 static int do_remoteproc_list(cmd_tbl_t *cmdtp, int flag, int argc, 92 char *const argv[]) 93 { 94 if (!rproc_is_initialized()) { 95 printf("\t Remote Processors is not initialized\n"); 96 return CMD_RET_USAGE; 97 } 98 99 if (print_remoteproc_list()) 100 return CMD_RET_FAILURE; 101 102 return 0; 103 } 104 105 /** 106 * do_remoteproc_load() - Load a remote processor with binary image 107 * @cmdtp: unused 108 * @flag: unused 109 * @argc: argument count for the load function 110 * @argv: arguments for the load function 111 * 112 * Return: 0 if no error, else returns appropriate error value. 113 */ 114 static int do_remoteproc_load(cmd_tbl_t *cmdtp, int flag, int argc, 115 char *const argv[]) 116 { 117 ulong addr, size; 118 int id, ret; 119 120 if (argc != 4) 121 return CMD_RET_USAGE; 122 123 id = (int)simple_strtoul(argv[1], NULL, 3); 124 addr = simple_strtoul(argv[2], NULL, 16); 125 126 size = simple_strtoul(argv[3], NULL, 16); 127 128 if (!size) { 129 printf("\t Expect some size??\n"); 130 return CMD_RET_USAGE; 131 } 132 133 if (!rproc_is_initialized()) { 134 printf("\tRemote Processors are not initialized\n"); 135 return CMD_RET_USAGE; 136 } 137 138 ret = rproc_load(id, addr, size); 139 printf("Load Remote Processor %d with data@addr=0x%08lx %lu bytes:%s\n", 140 id, addr, size, ret ? " Failed!" : " Success!"); 141 142 return ret ? CMD_RET_FAILURE : 0; 143 } 144 145 /** 146 * do_remoteproc_wrapper() - wrapper for various rproc commands 147 * @cmdtp: unused 148 * @flag: unused 149 * @argc: argument count for the rproc command 150 * @argv: arguments for the rproc command 151 * 152 * Most of the commands just take id as a parameter andinvoke various 153 * helper routines in remote processor core. by using a set of 154 * common checks, we can reduce the amount of code used for this. 155 * 156 * Return: 0 if no error, else returns appropriate error value. 157 */ 158 static int do_remoteproc_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, 159 char *const argv[]) 160 { 161 int id, ret = CMD_RET_USAGE; 162 163 if (argc != 2) 164 return CMD_RET_USAGE; 165 166 id = (int)simple_strtoul(argv[1], NULL, 3); 167 168 if (!rproc_is_initialized()) { 169 printf("\tRemote Processors are not initialized\n"); 170 return CMD_RET_USAGE; 171 } 172 173 if (!strcmp(argv[0], "start")) { 174 ret = rproc_start(id); 175 } else if (!strcmp(argv[0], "stop")) { 176 ret = rproc_stop(id); 177 } else if (!strcmp(argv[0], "reset")) { 178 ret = rproc_reset(id); 179 } else if (!strcmp(argv[0], "is_running")) { 180 ret = rproc_is_running(id); 181 if (!ret) { 182 printf("Remote processor is Running\n"); 183 } else if (ret == 1) { 184 printf("Remote processor is NOT Running\n"); 185 ret = 0; 186 } 187 /* Else error.. */ 188 } else if (!strcmp(argv[0], "ping")) { 189 ret = rproc_ping(id); 190 if (!ret) { 191 printf("Remote processor responds 'Pong'\n"); 192 } else if (ret == 1) { 193 printf("No response from Remote processor\n"); 194 ret = 0; 195 } 196 /* Else error.. */ 197 } 198 199 if (ret < 0) 200 printf("Operation Failed with error (%d)\n", ret); 201 202 return ret ? CMD_RET_FAILURE : 0; 203 } 204 205 static cmd_tbl_t cmd_remoteproc_sub[] = { 206 U_BOOT_CMD_MKENT(init, 0, 1, do_rproc_init, 207 "Enumerate and initialize all processors", ""), 208 U_BOOT_CMD_MKENT(list, 0, 1, do_remoteproc_list, 209 "list remote processors", ""), 210 U_BOOT_CMD_MKENT(load, 5, 1, do_remoteproc_load, 211 "Load remote processor with provided image", 212 "<id> [addr] [size]\n" 213 "- id: ID of the remote processor(see 'list' cmd)\n" 214 "- addr: Address in memory of the image to loadup\n" 215 "- size: Size of the image to loadup\n"), 216 U_BOOT_CMD_MKENT(start, 1, 1, do_remoteproc_wrapper, 217 "Start remote processor", 218 "id - ID of the remote processor (see 'list' cmd)\n"), 219 U_BOOT_CMD_MKENT(stop, 1, 1, do_remoteproc_wrapper, 220 "Stop remote processor", 221 "id - ID of the remote processor (see 'list' cmd)\n"), 222 U_BOOT_CMD_MKENT(reset, 1, 1, do_remoteproc_wrapper, 223 "Reset remote processor", 224 "id - ID of the remote processor (see 'list' cmd)\n"), 225 U_BOOT_CMD_MKENT(is_running, 1, 1, do_remoteproc_wrapper, 226 "Check to see if remote processor is running\n", 227 "id - ID of the remote processor (see 'list' cmd)\n"), 228 U_BOOT_CMD_MKENT(ping, 1, 1, do_remoteproc_wrapper, 229 "Ping to communicate with remote processor\n", 230 "id - ID of the remote processor (see 'list' cmd)\n"), 231 }; 232 233 /** 234 * do_remoteproc() - (replace: short desc) 235 * @cmdtp: unused 236 * @flag: unused 237 * @argc: argument count 238 * @argv: argument list 239 * 240 * parses up the command table to invoke the correct command. 241 * 242 * Return: 0 if no error, else returns appropriate error value. 243 */ 244 static int do_remoteproc(cmd_tbl_t *cmdtp, int flag, int argc, 245 char *const argv[]) 246 { 247 cmd_tbl_t *c = NULL; 248 249 /* Strip off leading 'rproc' command argument */ 250 argc--; 251 argv++; 252 253 if (argc) 254 c = find_cmd_tbl(argv[0], cmd_remoteproc_sub, 255 ARRAY_SIZE(cmd_remoteproc_sub)); 256 if (c) 257 return c->cmd(cmdtp, flag, argc, argv); 258 259 return CMD_RET_USAGE; 260 } 261 262 U_BOOT_CMD(rproc, 5, 1, do_remoteproc, 263 "Control operation of remote processors in an SoC", 264 " [init|list|load|start|stop|reset|is_running|ping]\n" 265 "\t\t Where:\n" 266 "\t\t[addr] is a memory address\n" 267 "\t\t<id> is a numerical identifier for the remote processor\n" 268 "\t\t provided by 'list' command.\n" 269 "\t\tNote: Remote processors must be initalized prior to usage\n" 270 "\t\tNote: Services are dependent on the driver capability\n" 271 "\t\t 'list' command shows the capability of each device\n" 272 "\n\tSubcommands:\n" 273 "\tinit - Enumerate and initalize the remote processors\n" 274 "\tlist - list available remote processors\n" 275 "\tload <id> [addr] [size]- Load the remote processor with binary\n" 276 "\t image stored at address [addr] in memory\n" 277 "\tstart <id> - Start the remote processor(must be loaded)\n" 278 "\tstop <id> - Stop the remote processor\n" 279 "\treset <id> - Reset the remote processor\n" 280 "\tis_running <id> - Reports if the remote processor is running\n" 281 "\tping <id> - Ping the remote processor for communication\n"); 282