rio.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * (C) Copyright 2017
  3. * Texas Instruments Incorporated, <www.ti.com>
  4. * Authors: Aurelien Jacquiot <a-jacquiot@ti.com>
  5. * WingMan Kwok <w-kwok2@ti.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. /*
  10. * RapidIO support
  11. */
  12. #include <common.h>
  13. #include <command.h>
  14. #include <mapmem.h>
  15. #include <asm/io.h>
  16. #include <watchdog.h>
  17. #include <rio.h>
  18. static struct udevice *rio_dev;
  19. static int do_rio_local_write(cmd_tbl_t *cmdtp, int flag, int argc,
  20. char * const argv[])
  21. {
  22. u32 offset, val;
  23. int ret;
  24. offset = simple_strtoul(argv[0], NULL, 16);
  25. val = simple_strtoul(argv[1], NULL, 16);
  26. ret = rio_local_config_write(rio_dev, offset, sizeof(val), val);
  27. if (ret) {
  28. printf("cannot perform local write\n");
  29. return CMD_RET_FAILURE;
  30. }
  31. return CMD_RET_SUCCESS;
  32. }
  33. static int do_rio_local_read(cmd_tbl_t *cmdtp, int flag, int argc,
  34. char * const argv[])
  35. {
  36. u32 offset, val;
  37. int ret;
  38. offset = simple_strtoul(argv[0], NULL, 16);
  39. ret = rio_local_config_read(rio_dev, offset, sizeof(val), &val);
  40. if (ret) {
  41. printf("cannot perform local read\n");
  42. return CMD_RET_FAILURE;
  43. }
  44. /* Display value */
  45. print_buffer(offset, (const void *)&val, sizeof(val), 1, 0);
  46. return CMD_RET_SUCCESS;
  47. }
  48. static int do_rio_write(cmd_tbl_t *cmdtp, int flag, int argc,
  49. char * const argv[])
  50. {
  51. int portid;
  52. u16 destid;
  53. u8 hopcount;
  54. u32 offset;
  55. u32 val;
  56. int ret;
  57. portid = simple_strtol(argv[0], NULL, 10);
  58. destid = simple_strtol(argv[1], NULL, 10) & 0xffff;
  59. hopcount = simple_strtoul(argv[2], NULL, 10) & 0xff;
  60. offset = simple_strtoul(argv[3], NULL, 16);
  61. val = simple_strtoul(argv[4], NULL, 16);
  62. /* Do maintenance write */
  63. ret = rio_config_write(rio_dev, portid, destid, hopcount,
  64. offset, sizeof(val), val);
  65. if (ret) {
  66. printf("cannot perform maintenance write\n");
  67. return CMD_RET_FAILURE;
  68. }
  69. return CMD_RET_SUCCESS;
  70. }
  71. static int do_rio_read(cmd_tbl_t *cmdtp, int flag, int argc,
  72. char * const argv[])
  73. {
  74. int portid;
  75. u16 destid;
  76. u8 hopcount;
  77. u32 offset;
  78. u32 val;
  79. int ret;
  80. portid = simple_strtol(argv[0], NULL, 10);
  81. destid = simple_strtol(argv[1], NULL, 10) & 0xffff;
  82. hopcount = simple_strtoul(argv[2], NULL, 10) & 0xff;
  83. offset = simple_strtoul(argv[3], NULL, 16);
  84. /* Do maintenance read */
  85. ret = rio_config_read(rio_dev, portid, destid, hopcount,
  86. offset, sizeof(val), &val);
  87. if (ret) {
  88. printf("cannot perform maintenance read\n");
  89. return CMD_RET_FAILURE;
  90. }
  91. /* Display value */
  92. print_buffer(offset, (const void *)&val, sizeof(val), 1, 0);
  93. return CMD_RET_SUCCESS;
  94. }
  95. static int do_rio_doorbell_rx(cmd_tbl_t *cmdtp, int flag, int argc,
  96. char * const argv[])
  97. {
  98. u32 info = 0;
  99. int ret;
  100. if (!argc)
  101. return CMD_RET_USAGE;
  102. info = simple_strtoul(argv[0], NULL, 16);
  103. ret = rio_doorbell_rx(rio_dev, info);
  104. if (!ret)
  105. return CMD_RET_SUCCESS;
  106. return CMD_RET_FAILURE;
  107. }
  108. static int do_rio_remove(cmd_tbl_t *cmdtp, int flag, int argc,
  109. char * const argv[])
  110. {
  111. rio_remove(rio_dev);
  112. rio_dev = NULL;
  113. return CMD_RET_SUCCESS;
  114. }
  115. static int do_rio_devices(cmd_tbl_t *cmdtp, int flag,
  116. int argc, char * const argv[])
  117. {
  118. struct udevice *dev;
  119. int i, ret;
  120. puts("RapidIO uclass entries:\n");
  121. printf("devnum device driver\n");
  122. for (i = 0, ret = uclass_first_device(UCLASS_RIO, &dev);
  123. dev;
  124. ret = uclass_next_device(&dev)) {
  125. printf(" %d %s %s\n",
  126. i++, dev->name, dev->driver->name);
  127. }
  128. return cmd_process_error(cmdtp, ret);
  129. }
  130. static cmd_tbl_t rio_commands[] = {
  131. U_BOOT_CMD_MKENT(devices, 0, 1, do_rio_devices, "", ""),
  132. U_BOOT_CMD_MKENT(remove, 1, 0, do_rio_remove, "", ""),
  133. U_BOOT_CMD_MKENT(doorbell_rx, 2, 0, do_rio_doorbell_rx, "", ""),
  134. U_BOOT_CMD_MKENT(r, 5, 1, do_rio_read, "", ""),
  135. U_BOOT_CMD_MKENT(w, 6, 0, do_rio_write, "", ""),
  136. U_BOOT_CMD_MKENT(lr, 2, 1, do_rio_local_read, "", ""),
  137. U_BOOT_CMD_MKENT(lw, 3, 0, do_rio_local_write, "", ""),
  138. };
  139. static int do_rio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  140. {
  141. cmd_tbl_t *rio_cmd;
  142. int devnum = 0;
  143. int ret;
  144. if (argc < 2)
  145. return CMD_RET_USAGE;
  146. rio_cmd = find_cmd_tbl(argv[1], rio_commands,
  147. ARRAY_SIZE(rio_commands));
  148. argc -= 2;
  149. argv += 2;
  150. if ((!rio_cmd || argc > rio_cmd->maxargs) ||
  151. ((strcmp(rio_cmd->name, "devices")) && (argc < 1)))
  152. return CMD_RET_USAGE;
  153. if (argc) {
  154. devnum = simple_strtoul(argv[0], NULL, 10);
  155. ret = uclass_get_device(UCLASS_RIO, devnum, &rio_dev);
  156. if (ret)
  157. return cmd_process_error(cmdtp, ret);
  158. argc--;
  159. argv++;
  160. } else {
  161. rio_dev = NULL;
  162. if (rio_cmd->cmd != do_rio_devices)
  163. return CMD_RET_USAGE;
  164. }
  165. ret = rio_cmd->cmd(rio_cmd, flag, argc, argv);
  166. return cmd_process_error(rio_cmd, ret);
  167. }
  168. U_BOOT_CMD(rio, CONFIG_SYS_MAXARGS, 0, do_rio,
  169. "RapidIO sub-system",
  170. "devices - show available RapidIO devices\n"
  171. "rio remove <devnum> - remove RapidIO device\n"
  172. "rio doorbell_rx <devnum> [info] - blocking wait for doorbell info\n"
  173. "rio r <devnum> port dst_id hopcount offset - perform config read\n"
  174. "rio w <devnum> port dst_id hopcount offset value - perform config write\n"
  175. "rio lr <devnum> offset - perform local config read\n"
  176. "rio lw <devnum> offset value - perform local config write\n"
  177. );