remoteproc.c 7.7 KB

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