remoteproc.c 7.8 KB

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