scu_api.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2018 NXP
  4. *
  5. * Peng Fan <peng.fan@nxp.com>
  6. */
  7. #include <common.h>
  8. #include <asm/io.h>
  9. #include <dm.h>
  10. #include <asm/arch/sci/sci.h>
  11. #include <misc.h>
  12. DECLARE_GLOBAL_DATA_PTR;
  13. /* CLK and PM */
  14. int sc_pm_set_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
  15. sc_pm_clock_rate_t *rate)
  16. {
  17. struct udevice *dev = gd->arch.scu_dev;
  18. int size = sizeof(struct sc_rpc_msg_s);
  19. struct sc_rpc_msg_s msg;
  20. int ret;
  21. RPC_VER(&msg) = SC_RPC_VERSION;
  22. RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  23. RPC_FUNC(&msg) = (u8)PM_FUNC_SET_CLOCK_RATE;
  24. RPC_U32(&msg, 0U) = *(u32 *)rate;
  25. RPC_U16(&msg, 4U) = (u16)resource;
  26. RPC_U8(&msg, 6U) = (u8)clk;
  27. RPC_SIZE(&msg) = 3U;
  28. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  29. if (ret)
  30. printf("%s: rate:%u resource:%u: clk:%u res:%d\n",
  31. __func__, *rate, resource, clk, RPC_R8(&msg));
  32. *rate = RPC_U32(&msg, 0U);
  33. return ret;
  34. }
  35. int sc_pm_get_clock_rate(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
  36. sc_pm_clock_rate_t *rate)
  37. {
  38. struct udevice *dev = gd->arch.scu_dev;
  39. int size = sizeof(struct sc_rpc_msg_s);
  40. struct sc_rpc_msg_s msg;
  41. int ret;
  42. RPC_VER(&msg) = SC_RPC_VERSION;
  43. RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  44. RPC_FUNC(&msg) = (u8)PM_FUNC_GET_CLOCK_RATE;
  45. RPC_U16(&msg, 0U) = (u16)resource;
  46. RPC_U8(&msg, 2U) = (u8)clk;
  47. RPC_SIZE(&msg) = 2U;
  48. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  49. if (ret) {
  50. printf("%s: resource:%d clk:%d: res:%d\n",
  51. __func__, resource, clk, RPC_R8(&msg));
  52. return ret;
  53. }
  54. if (rate)
  55. *rate = RPC_U32(&msg, 0U);
  56. return 0;
  57. }
  58. int sc_pm_clock_enable(sc_ipc_t ipc, sc_rsrc_t resource, sc_pm_clk_t clk,
  59. sc_bool_t enable, sc_bool_t autog)
  60. {
  61. struct udevice *dev = gd->arch.scu_dev;
  62. int size = sizeof(struct sc_rpc_msg_s);
  63. struct sc_rpc_msg_s msg;
  64. int ret;
  65. RPC_VER(&msg) = SC_RPC_VERSION;
  66. RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  67. RPC_FUNC(&msg) = (u8)PM_FUNC_CLOCK_ENABLE;
  68. RPC_U16(&msg, 0U) = (u16)resource;
  69. RPC_U8(&msg, 2U) = (u8)clk;
  70. RPC_U8(&msg, 3U) = (u8)enable;
  71. RPC_U8(&msg, 4U) = (u8)autog;
  72. RPC_SIZE(&msg) = 3U;
  73. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  74. if (ret)
  75. printf("%s: resource:%d clk:%d: enable:%d autog: %d, res:%d\n",
  76. __func__, resource, clk, enable, autog, RPC_R8(&msg));
  77. return ret;
  78. }
  79. int sc_pm_set_resource_power_mode(sc_ipc_t ipc, sc_rsrc_t resource,
  80. sc_pm_power_mode_t mode)
  81. {
  82. struct udevice *dev = gd->arch.scu_dev;
  83. int size = sizeof(struct sc_rpc_msg_s);
  84. struct sc_rpc_msg_s msg;
  85. int ret;
  86. if (!dev)
  87. hang();
  88. RPC_VER(&msg) = SC_RPC_VERSION;
  89. RPC_SVC(&msg) = (u8)SC_RPC_SVC_PM;
  90. RPC_FUNC(&msg) = (u8)PM_FUNC_SET_RESOURCE_POWER_MODE;
  91. RPC_U16(&msg, 0U) = (u16)resource;
  92. RPC_U8(&msg, 2U) = (u8)mode;
  93. RPC_SIZE(&msg) = 2U;
  94. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  95. if (ret)
  96. printf("%s: resource:%d mode:%d: res:%d\n",
  97. __func__, resource, mode, RPC_R8(&msg));
  98. return ret;
  99. }
  100. /* PAD */
  101. int sc_pad_set(sc_ipc_t ipc, sc_pad_t pad, u32 val)
  102. {
  103. struct udevice *dev = gd->arch.scu_dev;
  104. int size = sizeof(struct sc_rpc_msg_s);
  105. struct sc_rpc_msg_s msg;
  106. int ret;
  107. if (!dev)
  108. hang();
  109. RPC_VER(&msg) = SC_RPC_VERSION;
  110. RPC_SVC(&msg) = (u8)SC_RPC_SVC_PAD;
  111. RPC_FUNC(&msg) = (u8)PAD_FUNC_SET;
  112. RPC_U32(&msg, 0U) = (u32)val;
  113. RPC_U16(&msg, 4U) = (u16)pad;
  114. RPC_SIZE(&msg) = 3U;
  115. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  116. if (ret)
  117. printf("%s: val:%d pad:%d: res:%d\n",
  118. __func__, val, pad, RPC_R8(&msg));
  119. return ret;
  120. }
  121. /* MISC */
  122. int sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource, sc_ctrl_t ctrl,
  123. u32 *val)
  124. {
  125. struct udevice *dev = gd->arch.scu_dev;
  126. int size = sizeof(struct sc_rpc_msg_s);
  127. struct sc_rpc_msg_s msg;
  128. int ret;
  129. if (!dev)
  130. hang();
  131. RPC_VER(&msg) = SC_RPC_VERSION;
  132. RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
  133. RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_CONTROL;
  134. RPC_U32(&msg, 0U) = (u32)ctrl;
  135. RPC_U16(&msg, 4U) = (u16)resource;
  136. RPC_SIZE(&msg) = 3U;
  137. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  138. if (ret)
  139. printf("%s: ctrl:%d resource:%d: res:%d\n",
  140. __func__, ctrl, resource, RPC_R8(&msg));
  141. if (!val)
  142. *val = RPC_U32(&msg, 0U);
  143. return ret;
  144. }
  145. void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *boot_dev)
  146. {
  147. struct udevice *dev = gd->arch.scu_dev;
  148. int size = sizeof(struct sc_rpc_msg_s);
  149. struct sc_rpc_msg_s msg;
  150. int ret;
  151. if (!dev)
  152. hang();
  153. RPC_VER(&msg) = SC_RPC_VERSION;
  154. RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
  155. RPC_FUNC(&msg) = (u8)MISC_FUNC_GET_BOOT_DEV;
  156. RPC_SIZE(&msg) = 1U;
  157. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  158. if (ret)
  159. printf("%s: res:%d\n", __func__, RPC_R8(&msg));
  160. if (!boot_dev)
  161. *boot_dev = RPC_U16(&msg, 0U);
  162. }
  163. void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
  164. {
  165. struct udevice *dev = gd->arch.scu_dev;
  166. int size = sizeof(struct sc_rpc_msg_s);
  167. struct sc_rpc_msg_s msg;
  168. int ret;
  169. if (!dev)
  170. hang();
  171. RPC_VER(&msg) = SC_RPC_VERSION;
  172. RPC_SVC(&msg) = (u8)SC_RPC_SVC_MISC;
  173. RPC_FUNC(&msg) = (u8)MISC_FUNC_BOOT_STATUS;
  174. RPC_U8(&msg, 0U) = (u8)status;
  175. RPC_SIZE(&msg) = 2U;
  176. ret = misc_call(dev, SC_TRUE, &msg, size, &msg, size);
  177. if (ret)
  178. printf("%s: status:%d res:%d\n",
  179. __func__, status, RPC_R8(&msg));
  180. }
  181. void sc_misc_build_info(sc_ipc_t ipc, u32 *build, u32 *commit)
  182. {
  183. struct udevice *dev = gd->arch.scu_dev;
  184. int size = sizeof(struct sc_rpc_msg_s);
  185. struct sc_rpc_msg_s msg;
  186. int ret;
  187. if (!dev)
  188. hang();
  189. RPC_VER(&msg) = SC_RPC_VERSION;
  190. RPC_SVC(&msg) = SC_RPC_SVC_MISC;
  191. RPC_FUNC(&msg) = MISC_FUNC_BUILD_INFO;
  192. RPC_SIZE(&msg) = 1;
  193. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  194. if (ret < 0) {
  195. printf("%s: err: %d\n", __func__, ret);
  196. return;
  197. }
  198. if (build)
  199. *build = RPC_U32(&msg, 0);
  200. if (commit)
  201. *commit = RPC_U32(&msg, 4);
  202. }
  203. int sc_misc_otp_fuse_read(sc_ipc_t ipc, u32 word, u32 *val)
  204. {
  205. struct udevice *dev = gd->arch.scu_dev;
  206. int size = sizeof(struct sc_rpc_msg_s);
  207. struct sc_rpc_msg_s msg;
  208. int ret;
  209. if (!dev)
  210. hang();
  211. RPC_VER(&msg) = SC_RPC_VERSION;
  212. RPC_SVC(&msg) = SC_RPC_SVC_MISC;
  213. RPC_FUNC(&msg) = MISC_FUNC_OTP_FUSE_READ;
  214. RPC_U32(&msg, 0) = word;
  215. RPC_SIZE(&msg) = 2;
  216. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  217. if (ret < 0)
  218. return ret;
  219. if (val)
  220. *val = RPC_U32(&msg, 0U);
  221. return 0;
  222. }
  223. /* RM */
  224. sc_bool_t sc_rm_is_memreg_owned(sc_ipc_t ipc, sc_rm_mr_t mr)
  225. {
  226. struct udevice *dev = gd->arch.scu_dev;
  227. int size = sizeof(struct sc_rpc_msg_s);
  228. struct sc_rpc_msg_s msg;
  229. int ret;
  230. sc_err_t result;
  231. if (!dev)
  232. hang();
  233. RPC_VER(&msg) = SC_RPC_VERSION;
  234. RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
  235. RPC_FUNC(&msg) = (u8)RM_FUNC_IS_MEMREG_OWNED;
  236. RPC_U8(&msg, 0U) = (u8)mr;
  237. RPC_SIZE(&msg) = 2U;
  238. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  239. result = RPC_R8(&msg);
  240. if (result != 0 && result != 1) {
  241. printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
  242. if (ret)
  243. printf("%s: mr:%d res:%d\n", __func__, mr,
  244. RPC_R8(&msg));
  245. }
  246. return (sc_bool_t)result;
  247. }
  248. int sc_rm_get_memreg_info(sc_ipc_t ipc, sc_rm_mr_t mr, sc_faddr_t *addr_start,
  249. sc_faddr_t *addr_end)
  250. {
  251. struct udevice *dev = gd->arch.scu_dev;
  252. int size = sizeof(struct sc_rpc_msg_s);
  253. struct sc_rpc_msg_s msg;
  254. int ret;
  255. if (!dev)
  256. hang();
  257. RPC_VER(&msg) = SC_RPC_VERSION;
  258. RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
  259. RPC_FUNC(&msg) = (u8)RM_FUNC_GET_MEMREG_INFO;
  260. RPC_U8(&msg, 0U) = (u8)mr;
  261. RPC_SIZE(&msg) = 2U;
  262. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  263. if (ret)
  264. printf("%s: mr:%d res:%d\n", __func__, mr, RPC_R8(&msg));
  265. if (addr_start)
  266. *addr_start = ((u64)RPC_U32(&msg, 0U) << 32U) |
  267. RPC_U32(&msg, 4U);
  268. if (addr_end)
  269. *addr_end = ((u64)RPC_U32(&msg, 8U) << 32U) |
  270. RPC_U32(&msg, 12U);
  271. return ret;
  272. }
  273. sc_bool_t sc_rm_is_resource_owned(sc_ipc_t ipc, sc_rsrc_t resource)
  274. {
  275. struct udevice *dev = gd->arch.scu_dev;
  276. int size = sizeof(struct sc_rpc_msg_s);
  277. struct sc_rpc_msg_s msg;
  278. int ret;
  279. u8 result;
  280. if (!dev)
  281. hang();
  282. RPC_VER(&msg) = SC_RPC_VERSION;
  283. RPC_SVC(&msg) = (u8)SC_RPC_SVC_RM;
  284. RPC_FUNC(&msg) = (u8)RM_FUNC_IS_RESOURCE_OWNED;
  285. RPC_U16(&msg, 0U) = (u16)resource;
  286. RPC_SIZE(&msg) = 2U;
  287. ret = misc_call(dev, SC_FALSE, &msg, size, &msg, size);
  288. result = RPC_R8(&msg);
  289. if (result != 0 && result != 1) {
  290. printf("%s: resource:%d res:%d\n",
  291. __func__, resource, RPC_R8(&msg));
  292. if (ret)
  293. printf("%s: res:%d res:%d\n", __func__, resource,
  294. RPC_R8(&msg));
  295. }
  296. return !!result;
  297. }