s400_api.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2020 NXP
  4. *
  5. */
  6. #include <common.h>
  7. #include <hang.h>
  8. #include <malloc.h>
  9. #include <asm/io.h>
  10. #include <dm.h>
  11. #include <asm/arch/s400_api.h>
  12. #include <misc.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. int ahab_release_rdc(u8 core_id, bool xrdc, u32 *response)
  15. {
  16. struct udevice *dev = gd->arch.s400_dev;
  17. int size = sizeof(struct imx8ulp_s400_msg);
  18. struct imx8ulp_s400_msg msg;
  19. int ret;
  20. if (!dev) {
  21. printf("s400 dev is not initialized\n");
  22. return -ENODEV;
  23. }
  24. msg.version = AHAB_VERSION;
  25. msg.tag = AHAB_CMD_TAG;
  26. msg.size = 2;
  27. msg.command = AHAB_RELEASE_RDC_REQ_CID;
  28. if (xrdc)
  29. msg.data[0] = (0x78 << 8) | core_id;
  30. else
  31. msg.data[0] = (0x74 << 8) | core_id;
  32. ret = misc_call(dev, false, &msg, size, &msg, size);
  33. if (ret)
  34. printf("Error: %s: ret %d, core id %u, response 0x%x\n",
  35. __func__, ret, core_id, msg.data[0]);
  36. if (response)
  37. *response = msg.data[0];
  38. return ret;
  39. }
  40. int ahab_auth_oem_ctnr(ulong ctnr_addr, u32 *response)
  41. {
  42. struct udevice *dev = gd->arch.s400_dev;
  43. int size = sizeof(struct imx8ulp_s400_msg);
  44. struct imx8ulp_s400_msg msg;
  45. int ret;
  46. if (!dev) {
  47. printf("s400 dev is not initialized\n");
  48. return -ENODEV;
  49. }
  50. msg.version = AHAB_VERSION;
  51. msg.tag = AHAB_CMD_TAG;
  52. msg.size = 3;
  53. msg.command = AHAB_AUTH_OEM_CTNR_CID;
  54. msg.data[0] = upper_32_bits(ctnr_addr);
  55. msg.data[1] = lower_32_bits(ctnr_addr);
  56. ret = misc_call(dev, false, &msg, size, &msg, size);
  57. if (ret)
  58. printf("Error: %s: ret %d, cntr_addr 0x%lx, response 0x%x\n",
  59. __func__, ret, ctnr_addr, msg.data[0]);
  60. if (response)
  61. *response = msg.data[0];
  62. return ret;
  63. }
  64. int ahab_release_container(u32 *response)
  65. {
  66. struct udevice *dev = gd->arch.s400_dev;
  67. int size = sizeof(struct imx8ulp_s400_msg);
  68. struct imx8ulp_s400_msg msg;
  69. int ret;
  70. if (!dev) {
  71. printf("s400 dev is not initialized\n");
  72. return -ENODEV;
  73. }
  74. msg.version = AHAB_VERSION;
  75. msg.tag = AHAB_CMD_TAG;
  76. msg.size = 1;
  77. msg.command = AHAB_RELEASE_CTNR_CID;
  78. ret = misc_call(dev, false, &msg, size, &msg, size);
  79. if (ret)
  80. printf("Error: %s: ret %d, response 0x%x\n",
  81. __func__, ret, msg.data[0]);
  82. if (response)
  83. *response = msg.data[0];
  84. return ret;
  85. }
  86. int ahab_verify_image(u32 img_id, u32 *response)
  87. {
  88. struct udevice *dev = gd->arch.s400_dev;
  89. int size = sizeof(struct imx8ulp_s400_msg);
  90. struct imx8ulp_s400_msg msg;
  91. int ret;
  92. if (!dev) {
  93. printf("s400 dev is not initialized\n");
  94. return -ENODEV;
  95. }
  96. msg.version = AHAB_VERSION;
  97. msg.tag = AHAB_CMD_TAG;
  98. msg.size = 2;
  99. msg.command = AHAB_VERIFY_IMG_CID;
  100. msg.data[0] = 1 << img_id;
  101. ret = misc_call(dev, false, &msg, size, &msg, size);
  102. if (ret)
  103. printf("Error: %s: ret %d, img_id %u, response 0x%x\n",
  104. __func__, ret, img_id, msg.data[0]);
  105. if (response)
  106. *response = msg.data[0];
  107. return ret;
  108. }
  109. int ahab_forward_lifecycle(u16 life_cycle, u32 *response)
  110. {
  111. struct udevice *dev = gd->arch.s400_dev;
  112. int size = sizeof(struct imx8ulp_s400_msg);
  113. struct imx8ulp_s400_msg msg;
  114. int ret;
  115. if (!dev) {
  116. printf("s400 dev is not initialized\n");
  117. return -ENODEV;
  118. }
  119. msg.version = AHAB_VERSION;
  120. msg.tag = AHAB_CMD_TAG;
  121. msg.size = 2;
  122. msg.command = AHAB_FWD_LIFECYCLE_UP_REQ_CID;
  123. msg.data[0] = life_cycle;
  124. ret = misc_call(dev, false, &msg, size, &msg, size);
  125. if (ret)
  126. printf("Error: %s: ret %d, life_cycle 0x%x, response 0x%x\n",
  127. __func__, ret, life_cycle, msg.data[0]);
  128. if (response)
  129. *response = msg.data[0];
  130. return ret;
  131. }
  132. int ahab_read_common_fuse(u16 fuse_id, u32 *fuse_words, u32 fuse_num, u32 *response)
  133. {
  134. struct udevice *dev = gd->arch.s400_dev;
  135. int size = sizeof(struct imx8ulp_s400_msg);
  136. struct imx8ulp_s400_msg msg;
  137. int ret;
  138. if (!dev) {
  139. printf("s400 dev is not initialized\n");
  140. return -ENODEV;
  141. }
  142. if (!fuse_words) {
  143. printf("Invalid parameters for fuse read\n");
  144. return -EINVAL;
  145. }
  146. if ((fuse_id != 1 && fuse_num != 1) ||
  147. (fuse_id == 1 && fuse_num != 4)) {
  148. printf("Invalid fuse number parameter\n");
  149. return -EINVAL;
  150. }
  151. msg.version = AHAB_VERSION;
  152. msg.tag = AHAB_CMD_TAG;
  153. msg.size = 2;
  154. msg.command = AHAB_READ_FUSE_REQ_CID;
  155. msg.data[0] = fuse_id;
  156. ret = misc_call(dev, false, &msg, size, &msg, size);
  157. if (ret)
  158. printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
  159. __func__, ret, fuse_id, msg.data[0]);
  160. if (response)
  161. *response = msg.data[0];
  162. fuse_words[0] = msg.data[1];
  163. if (fuse_id == 1) {
  164. /* OTP_UNIQ_ID */
  165. fuse_words[1] = msg.data[2];
  166. fuse_words[2] = msg.data[3];
  167. fuse_words[3] = msg.data[4];
  168. }
  169. return ret;
  170. }
  171. int ahab_write_fuse(u16 fuse_id, u32 fuse_val, bool lock, u32 *response)
  172. {
  173. struct udevice *dev = gd->arch.s400_dev;
  174. int size = sizeof(struct imx8ulp_s400_msg);
  175. struct imx8ulp_s400_msg msg;
  176. int ret;
  177. if (!dev) {
  178. printf("s400 dev is not initialized\n");
  179. return -ENODEV;
  180. }
  181. msg.version = AHAB_VERSION;
  182. msg.tag = AHAB_CMD_TAG;
  183. msg.size = 3;
  184. msg.command = AHAB_WRITE_FUSE_REQ_CID;
  185. msg.data[0] = (32 << 16) | (fuse_id << 5);
  186. if (lock)
  187. msg.data[0] |= (1 << 31);
  188. msg.data[1] = fuse_val;
  189. ret = misc_call(dev, false, &msg, size, &msg, size);
  190. if (ret)
  191. printf("Error: %s: ret %d, fuse_id 0x%x, response 0x%x\n",
  192. __func__, ret, fuse_id, msg.data[0]);
  193. if (response)
  194. *response = msg.data[0];
  195. return ret;
  196. }