scmi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /*
  2. * Copyright (c) 2023-2024, Advanced Micro Devices, Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <inttypes.h>
  9. #include <drivers/scmi-msg.h>
  10. #include <drivers/scmi.h>
  11. #include <lib/mmio.h>
  12. #include <lib/utils_def.h>
  13. #include <platform_def.h>
  14. #include <scmi.h>
  15. #include "plat_private.h"
  16. #define HIGH (1)
  17. #define LOW (0)
  18. struct scmi_clk {
  19. unsigned long clock_id;
  20. unsigned long rate;
  21. const char *name;
  22. bool enabled;
  23. };
  24. #define CLOCK_CELL(_scmi_id, _id, _name, _init_enabled, _rate) \
  25. [_scmi_id] = { \
  26. .clock_id = (_id), \
  27. .name = (_name), \
  28. .enabled = (_init_enabled), \
  29. .rate = (_rate), \
  30. }
  31. static struct scmi_clk scmi0_clock[] = {
  32. CLOCK_CELL(CLK_GEM0_0, CLK_GEM0_0, "gem0_pclk", true, 100000000),
  33. CLOCK_CELL(CLK_GEM0_1, CLK_GEM0_1, "gem0_hclk", true, 100000000),
  34. CLOCK_CELL(CLK_GEM0_2, CLK_GEM0_2, "gem0_tx_clk", true, 125000000),
  35. CLOCK_CELL(CLK_GEM0_3, CLK_GEM0_3, "gem0_rx_clk", true, 100000000),
  36. CLOCK_CELL(CLK_GEM0_4, CLK_GEM0_4, "gem0_tsu_clk", true, 100000000),
  37. CLOCK_CELL(CLK_GEM1_0, CLK_GEM1_0, "gem1_pclk", true, 100000000),
  38. CLOCK_CELL(CLK_GEM1_1, CLK_GEM1_1, "gem1_hclk", true, 100000000),
  39. CLOCK_CELL(CLK_GEM1_2, CLK_GEM1_2, "gem1_tx_clk", true, 125000000),
  40. CLOCK_CELL(CLK_GEM1_3, CLK_GEM1_3, "gem1_rx_clk", true, 100000000),
  41. CLOCK_CELL(CLK_GEM1_4, CLK_GEM1_4, "gem1_tsu_clk", true, 100000000),
  42. CLOCK_CELL(CLK_SERIAL0_0, CLK_SERIAL0_0, "uart0_uartclk", true, 100000000),
  43. CLOCK_CELL(CLK_SERIAL0_1, CLK_SERIAL0_1, "uart0_apb_pclk", true, 100000000),
  44. CLOCK_CELL(CLK_SERIAL1_0, CLK_SERIAL1_0, "uart1_uartclk", true, 100000000),
  45. CLOCK_CELL(CLK_SERIAL1_1, CLK_SERIAL1_1, "uart1_apb_pclk", true, 100000000),
  46. CLOCK_CELL(CLK_UFS0_0, CLK_UFS0_0, "ufs_core_clk", true, 100000000),
  47. CLOCK_CELL(CLK_UFS0_1, CLK_UFS0_1, "ufs_phy_clk", true, 26000000),
  48. CLOCK_CELL(CLK_UFS0_2, CLK_UFS0_2, "ufs_ref_pclk", true, 26000000),
  49. CLOCK_CELL(CLK_USB0_0, CLK_USB0_0, "usb0_bus_clk", true, 100000000),
  50. CLOCK_CELL(CLK_USB0_1, CLK_USB0_1, "usb0_ref_clk", true, 100000000),
  51. CLOCK_CELL(CLK_USB0_2, CLK_USB0_2, "usb0_dwc_clk", true, 100000000),
  52. CLOCK_CELL(CLK_USB1_0, CLK_USB1_0, "usb1_bus_clk", true, 100000000),
  53. CLOCK_CELL(CLK_USB1_1, CLK_USB1_1, "usb1_ref_clk", true, 100000000),
  54. CLOCK_CELL(CLK_USB1_2, CLK_USB1_2, "usb1_dwc_clk", true, 100000000),
  55. CLOCK_CELL(CLK_MMC0_0, CLK_MMC0_0, "mmc0_xin_clk", true, 100000000),
  56. CLOCK_CELL(CLK_MMC0_1, CLK_MMC0_1, "mmc0_ahb_clk", true, 100000000),
  57. CLOCK_CELL(CLK_MMC0_2, CLK_MMC0_2, "mmc0_gate_clk", true, 100000000),
  58. CLOCK_CELL(CLK_MMC1_0, CLK_MMC1_0, "mmc1_xin_clk", true, 100000000),
  59. CLOCK_CELL(CLK_MMC1_1, CLK_MMC1_1, "mmc1_ahb_clk", true, 100000000),
  60. CLOCK_CELL(CLK_MMC1_2, CLK_MMC1_2, "mmc1_gate_clk", true, 100000000),
  61. CLOCK_CELL(CLK_TTC0_0, CLK_TTC0_0, "ttc0_clk", true, 100000000),
  62. CLOCK_CELL(CLK_TTC1_0, CLK_TTC1_0, "ttc1_clk", true, 100000000),
  63. CLOCK_CELL(CLK_TTC2_0, CLK_TTC2_0, "ttc2_clk", true, 100000000),
  64. CLOCK_CELL(CLK_TTC3_0, CLK_TTC3_0, "ttc3_clk", true, 100000000),
  65. CLOCK_CELL(CLK_TTC4_0, CLK_TTC4_0, "ttc4_clk", true, 100000000),
  66. CLOCK_CELL(CLK_TTC5_0, CLK_TTC5_0, "ttc5_clk", true, 100000000),
  67. CLOCK_CELL(CLK_TTC6_0, CLK_TTC6_0, "ttc6_clk", true, 100000000),
  68. CLOCK_CELL(CLK_TTC7_0, CLK_TTC7_0, "ttc7_clk", true, 100000000),
  69. CLOCK_CELL(CLK_I2C0_0, CLK_I2C0_0, "i2c0_clk", true, 100000000),
  70. CLOCK_CELL(CLK_I2C1_0, CLK_I2C1_0, "i2c1_clk", true, 100000000),
  71. CLOCK_CELL(CLK_I2C2_0, CLK_I2C2_0, "i2c2_clk", true, 100000000),
  72. CLOCK_CELL(CLK_I2C3_0, CLK_I2C3_0, "i2c3_clk", true, 100000000),
  73. CLOCK_CELL(CLK_I2C4_0, CLK_I2C4_0, "i2c4_clk", true, 100000000),
  74. CLOCK_CELL(CLK_I2C5_0, CLK_I2C5_0, "i2c5_clk", true, 100000000),
  75. CLOCK_CELL(CLK_I2C6_0, CLK_I2C6_0, "i2c6_clk", true, 100000000),
  76. CLOCK_CELL(CLK_I2C7_0, CLK_I2C7_0, "i2c7_clk", true, 100000000),
  77. CLOCK_CELL(CLK_OSPI0_0, CLK_OSPI0_0, "ospi0_clk", true, 100000000),
  78. CLOCK_CELL(CLK_QSPI0_0, CLK_QSPI0_0, "qpsi0_ref_clk", true, 100000000),
  79. CLOCK_CELL(CLK_QSPI0_1, CLK_QSPI0_1, "qspi0_pclk", true, 100000000),
  80. CLOCK_CELL(CLK_WWDT0_0, CLK_WWDT0_0, "wwdt0_clk", true, 100000000),
  81. CLOCK_CELL(CLK_WWDT1_0, CLK_WWDT1_0, "wwdt1_clk", true, 100000000),
  82. CLOCK_CELL(CLK_WWDT2_0, CLK_WWDT2_0, "wwdt2_clk", true, 100000000),
  83. CLOCK_CELL(CLK_WWDT3_0, CLK_WWDT3_0, "wwdt3_clk", true, 100000000),
  84. CLOCK_CELL(CLK_ADMA0_0, CLK_ADMA0_0, "adma0_main_clk", true, 100000000),
  85. CLOCK_CELL(CLK_ADMA0_1, CLK_ADMA0_1, "adma0_apb_clk", true, 100000000),
  86. CLOCK_CELL(CLK_ADMA1_0, CLK_ADMA1_0, "adma1_main_clk", true, 100000000),
  87. CLOCK_CELL(CLK_ADMA1_1, CLK_ADMA1_1, "adma1_apb_clk", true, 100000000),
  88. CLOCK_CELL(CLK_ADMA2_0, CLK_ADMA2_0, "adma2_main_clk", true, 100000000),
  89. CLOCK_CELL(CLK_ADMA2_1, CLK_ADMA2_1, "adma2_apb_clk", true, 100000000),
  90. CLOCK_CELL(CLK_ADMA3_0, CLK_ADMA3_0, "adma3_main_clk", true, 100000000),
  91. CLOCK_CELL(CLK_ADMA3_1, CLK_ADMA3_1, "adma3_apb_clk", true, 100000000),
  92. CLOCK_CELL(CLK_ADMA4_0, CLK_ADMA4_0, "adma4_main_clk", true, 100000000),
  93. CLOCK_CELL(CLK_ADMA4_1, CLK_ADMA4_1, "adma4_apb_clk", true, 100000000),
  94. CLOCK_CELL(CLK_ADMA5_0, CLK_ADMA5_0, "adma5_main_clk", true, 100000000),
  95. CLOCK_CELL(CLK_ADMA5_1, CLK_ADMA5_1, "adma5_apb_clk", true, 100000000),
  96. CLOCK_CELL(CLK_ADMA6_0, CLK_ADMA6_0, "adma6_main_clk", true, 100000000),
  97. CLOCK_CELL(CLK_ADMA6_1, CLK_ADMA6_1, "adma6_apb_clk", true, 100000000),
  98. CLOCK_CELL(CLK_ADMA7_0, CLK_ADMA7_0, "adma7_main_clk", true, 100000000),
  99. CLOCK_CELL(CLK_ADMA7_1, CLK_ADMA7_1, "adma7_apb_clk", true, 100000000),
  100. CLOCK_CELL(CLK_CAN0_0, CLK_CAN0_0, "can0_can_clk", true, 100000000),
  101. CLOCK_CELL(CLK_CAN0_1, CLK_CAN0_1, "can0_axi_clk", true, 100000000),
  102. CLOCK_CELL(CLK_CAN1_0, CLK_CAN1_0, "can1_can_clk", true, 100000000),
  103. CLOCK_CELL(CLK_CAN1_1, CLK_CAN1_1, "can1_axi_clk", true, 100000000),
  104. CLOCK_CELL(CLK_CAN2_0, CLK_CAN2_0, "can2_can_clk", true, 100000000),
  105. CLOCK_CELL(CLK_CAN2_1, CLK_CAN2_1, "can2_axi_clk", true, 100000000),
  106. CLOCK_CELL(CLK_CAN3_0, CLK_CAN3_0, "can3_can_clk", true, 100000000),
  107. CLOCK_CELL(CLK_CAN3_1, CLK_CAN3_1, "can3_axi_clk", true, 100000000),
  108. CLOCK_CELL(CLK_PS_GPIO_0, CLK_PS_GPIO_0, "ps_gpio_clk", true, 100000000),
  109. CLOCK_CELL(CLK_PMC_GPIO_0, CLK_PMC_GPIO_0, "pmc_gpio_clk", true, 100000000),
  110. CLOCK_CELL(CLK_SPI0_0, CLK_SPI0_0, "spi0_ref_clk", true, 100000000),
  111. CLOCK_CELL(CLK_SPI0_1, CLK_SPI0_1, "spi0_pclk", true, 100000000),
  112. CLOCK_CELL(CLK_SPI1_0, CLK_SPI1_0, "spi1_ref_clk", true, 100000000),
  113. CLOCK_CELL(CLK_SPI1_1, CLK_SPI1_1, "spi1_pclk", true, 100000000),
  114. CLOCK_CELL(CLK_I3C0_0, CLK_I3C0_0, "i3c0_clk", true, 100000000),
  115. CLOCK_CELL(CLK_I3C1_0, CLK_I3C1_0, "i3c1_clk", true, 100000000),
  116. CLOCK_CELL(CLK_I3C2_0, CLK_I3C2_0, "i3c2_clk", true, 100000000),
  117. CLOCK_CELL(CLK_I3C3_0, CLK_I3C3_0, "i3c3_clk", true, 100000000),
  118. CLOCK_CELL(CLK_I3C4_0, CLK_I3C4_0, "i3c4_clk", true, 100000000),
  119. CLOCK_CELL(CLK_I3C5_0, CLK_I3C5_0, "i3c5_clk", true, 100000000),
  120. CLOCK_CELL(CLK_I3C6_0, CLK_I3C6_0, "i3c6_clk", true, 100000000),
  121. CLOCK_CELL(CLK_I3C7_0, CLK_I3C7_0, "i3c7_clk", true, 100000000),
  122. };
  123. /*
  124. * struct scmi_reset - Data for the exposed reset controller
  125. * @reset_id: Reset identifier in RCC reset driver
  126. * @name: Reset string ID exposed to agent
  127. */
  128. struct scmi_reset {
  129. unsigned long reset_id;
  130. const char *name;
  131. };
  132. #define RESET_CELL(_scmi_id, _id, _name) \
  133. [_scmi_id] = { \
  134. .reset_id = (_id), \
  135. .name = (_name), \
  136. }
  137. static struct scmi_reset scmi0_reset[] = {
  138. RESET_CELL(RESET_GEM0_0, RESET_GEM0_0, "gem0"),
  139. RESET_CELL(RESET_GEM1_0, RESET_GEM1_0, "gem1"),
  140. RESET_CELL(RESET_SERIAL0_0, RESET_SERIAL0_0, "serial0"),
  141. RESET_CELL(RESET_SERIAL1_0, RESET_SERIAL1_0, "serial1"),
  142. RESET_CELL(RESET_UFS0_0, RESET_UFS0_0, "ufs0"),
  143. RESET_CELL(RESET_I2C0_0, RESET_I2C0_0, "i2c0"),
  144. RESET_CELL(RESET_I2C1_0, RESET_I2C1_0, "i2c1"),
  145. RESET_CELL(RESET_I2C2_0, RESET_I2C2_0, "i2c2"),
  146. RESET_CELL(RESET_I2C3_0, RESET_I2C3_0, "i2c3"),
  147. RESET_CELL(RESET_I2C4_0, RESET_I2C4_0, "i2c4"),
  148. RESET_CELL(RESET_I2C5_0, RESET_I2C5_0, "i2c5"),
  149. RESET_CELL(RESET_I2C6_0, RESET_I2C6_0, "i2c6"),
  150. RESET_CELL(RESET_I2C7_0, RESET_I2C7_0, "i2c7"),
  151. RESET_CELL(RESET_I2C8_0, RESET_I2C8_0, "i2c8"),
  152. RESET_CELL(RESET_OSPI0_0, RESET_OSPI0_0, "ospi"),
  153. RESET_CELL(RESET_USB0_0, RESET_USB0_0, "usb0_0"),
  154. RESET_CELL(RESET_USB0_1, RESET_USB0_1, "usb0_1"),
  155. RESET_CELL(RESET_USB0_2, RESET_USB0_2, "usb0_2"),
  156. RESET_CELL(RESET_USB1_0, RESET_USB1_0, "usb1_0"),
  157. RESET_CELL(RESET_USB1_1, RESET_USB1_1, "usb1_1"),
  158. RESET_CELL(RESET_USB1_2, RESET_USB1_2, "usb1_2"),
  159. RESET_CELL(RESET_MMC0_0, RESET_MMC0_0, "mmc0"),
  160. RESET_CELL(RESET_MMC1_0, RESET_MMC1_0, "mmc1"),
  161. RESET_CELL(RESET_SPI0_0, RESET_SPI0_0, "spi0"),
  162. RESET_CELL(RESET_SPI1_0, RESET_SPI1_0, "spi1"),
  163. RESET_CELL(RESET_QSPI0_0, RESET_QSPI0_0, "qspi"),
  164. RESET_CELL(RESET_I3C0_0, RESET_I3C0_0, "i3c0"),
  165. RESET_CELL(RESET_I3C1_0, RESET_I3C1_0, "i3c1"),
  166. RESET_CELL(RESET_I3C2_0, RESET_I3C2_0, "i3c2"),
  167. RESET_CELL(RESET_I3C3_0, RESET_I3C3_0, "i3c3"),
  168. RESET_CELL(RESET_I3C4_0, RESET_I3C4_0, "i3c4"),
  169. RESET_CELL(RESET_I3C5_0, RESET_I3C5_0, "i3c5"),
  170. RESET_CELL(RESET_I3C6_0, RESET_I3C6_0, "i3c6"),
  171. RESET_CELL(RESET_I3C7_0, RESET_I3C7_0, "i3c7"),
  172. RESET_CELL(RESET_I3C8_0, RESET_I3C8_0, "i3c8"),
  173. RESET_CELL(RESET_UFSPHY_0, RESET_UFSPHY_0, "ufsphy0"),
  174. };
  175. /**
  176. * struct scmi_pd - Data for the exposed power domain controller
  177. * @pd_id: pd identifier in RCC reset driver
  178. * @name: pd string ID exposed to agent
  179. * @state: keep state setting
  180. */
  181. struct scmi_pd {
  182. unsigned long pd_id;
  183. const char *name;
  184. unsigned int state;
  185. };
  186. #define PD_CELL(_scmi_id, _id, _name, _state) \
  187. [_scmi_id] = { \
  188. .pd_id = _id, \
  189. .name = _name, \
  190. .state = _state, \
  191. }
  192. static struct scmi_pd scmi0_pd[] = {
  193. PD_CELL(PD_USB0, PD_USB0, "usb0", 0),
  194. PD_CELL(PD_USB1, PD_USB1, "usb1", 0),
  195. };
  196. struct scmi_resources {
  197. struct scmi_clk *clock;
  198. size_t clock_count;
  199. struct scmi_reset *reset;
  200. size_t reset_count;
  201. struct scmi_pd *pd;
  202. size_t pd_count;
  203. };
  204. static const struct scmi_resources resources[] = {
  205. [0] = {
  206. .clock = scmi0_clock,
  207. .clock_count = ARRAY_SIZE(scmi0_clock),
  208. .reset = scmi0_reset,
  209. .reset_count = ARRAY_SIZE(scmi0_reset),
  210. .pd = scmi0_pd,
  211. .pd_count = ARRAY_SIZE(scmi0_pd),
  212. },
  213. };
  214. static const struct scmi_resources *find_resource(unsigned int agent_id)
  215. {
  216. assert(agent_id < ARRAY_SIZE(resources));
  217. return &resources[agent_id];
  218. }
  219. static struct scmi_clk *clk_find(unsigned int agent_id, unsigned int scmi_id)
  220. {
  221. const struct scmi_resources *resource = find_resource(agent_id);
  222. size_t n = 0U;
  223. struct scmi_clk *ret = NULL;
  224. if (resource != NULL) {
  225. for (n = 0U; n < resource->clock_count; n++) {
  226. if (n == scmi_id) {
  227. ret = &resource->clock[n];
  228. break;
  229. }
  230. }
  231. }
  232. return ret;
  233. }
  234. size_t plat_scmi_clock_count(unsigned int agent_id)
  235. {
  236. const struct scmi_resources *resource = find_resource(agent_id);
  237. size_t ret;
  238. if (resource == NULL) {
  239. ret = 0U;
  240. } else {
  241. VERBOSE("SCMI: CLK: %d clocks\n", (unsigned int)resource->clock_count);
  242. ret = resource->clock_count;
  243. }
  244. return ret;
  245. }
  246. const char *plat_scmi_clock_get_name(unsigned int agent_id, unsigned int scmi_id)
  247. {
  248. const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
  249. const char *ret;
  250. if (clock == NULL) {
  251. ret = NULL;
  252. } else {
  253. VERBOSE("SCMI: CLK: id: %d, get_name: %s\n", scmi_id, clock->name);
  254. ret = clock->name;
  255. }
  256. return ret;
  257. };
  258. /* Called by Linux */
  259. int32_t plat_scmi_clock_rates_array(unsigned int agent_id, unsigned int scmi_id,
  260. unsigned long *array, size_t *nb_elts,
  261. uint32_t start_idx)
  262. {
  263. const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
  264. if (clock == NULL) {
  265. return SCMI_NOT_FOUND;
  266. }
  267. if (start_idx > 0) {
  268. return SCMI_OUT_OF_RANGE;
  269. }
  270. if (array == NULL) {
  271. *nb_elts = 1U;
  272. } else if (*nb_elts == 1U) {
  273. *array = clock->rate;
  274. VERBOSE("SCMI: CLK: id: %d, clk_name: %s, get_rate %lu\n",
  275. scmi_id, clock->name, *array);
  276. } else {
  277. return SCMI_GENERIC_ERROR;
  278. }
  279. return SCMI_SUCCESS;
  280. }
  281. unsigned long plat_scmi_clock_get_rate(unsigned int agent_id, unsigned int scmi_id)
  282. {
  283. const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
  284. unsigned long ret;
  285. if ((clock == NULL)) {
  286. ret = SCMI_NOT_FOUND;
  287. } else {
  288. VERBOSE("SCMI: CLK: id: %d, get_rate: %lu\n", scmi_id, clock->rate);
  289. ret = clock->rate;
  290. }
  291. return ret;
  292. }
  293. int32_t plat_scmi_clock_set_rate(unsigned int agent_id, unsigned int scmi_id,
  294. unsigned long rate)
  295. {
  296. struct scmi_clk *clock = clk_find(agent_id, scmi_id);
  297. unsigned long ret = UL(SCMI_SUCCESS);
  298. if ((clock == NULL)) {
  299. ret = SCMI_NOT_FOUND;
  300. } else {
  301. VERBOSE("SCMI: CLK: id: %d, set_rate: %lu\n", scmi_id, rate);
  302. clock->rate = rate;
  303. }
  304. return ret;
  305. }
  306. int32_t plat_scmi_clock_get_state(unsigned int agent_id, unsigned int scmi_id)
  307. {
  308. const struct scmi_clk *clock = clk_find(agent_id, scmi_id);
  309. int32_t ret;
  310. if ((clock == NULL)) {
  311. ret = SCMI_NOT_FOUND;
  312. } else {
  313. VERBOSE("SCMI: CLK: id: %d, get_state: %d\n", scmi_id, clock->enabled);
  314. if (clock->enabled) {
  315. ret = HIGH;
  316. } else {
  317. ret = LOW;
  318. }
  319. }
  320. return ret;
  321. }
  322. int32_t plat_scmi_clock_set_state(unsigned int agent_id, unsigned int scmi_id,
  323. bool enable_not_disable)
  324. {
  325. struct scmi_clk *clock = clk_find(agent_id, scmi_id);
  326. int32_t ret;
  327. if (clock == NULL) {
  328. ret = SCMI_NOT_FOUND;
  329. } else {
  330. if (enable_not_disable) {
  331. if (!clock->enabled) {
  332. VERBOSE("SCMI: clock: %u enable\n", scmi_id);
  333. clock->enabled = true;
  334. }
  335. } else {
  336. if (clock->enabled) {
  337. VERBOSE("SCMI: clock: %u disable\n", scmi_id);
  338. clock->enabled = false;
  339. }
  340. }
  341. VERBOSE("SCMI: CLK: id: %d, set_state: %d\n", scmi_id, clock->enabled);
  342. ret = SCMI_SUCCESS;
  343. }
  344. return ret;
  345. }
  346. /*
  347. * Platform SCMI reset domains
  348. */
  349. static struct scmi_reset *find_reset(unsigned int agent_id,
  350. unsigned int scmi_id)
  351. {
  352. const struct scmi_resources *resource = find_resource(agent_id);
  353. size_t n;
  354. if (resource != NULL) {
  355. for (n = 0U; n < resource->reset_count; n++) {
  356. if (n == scmi_id) {
  357. return &resource->reset[n];
  358. }
  359. }
  360. }
  361. return NULL;
  362. }
  363. const char *plat_scmi_rstd_get_name(unsigned int agent_id, unsigned int scmi_id)
  364. {
  365. const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
  366. if (reset == NULL) {
  367. return NULL;
  368. }
  369. return reset->name;
  370. }
  371. size_t plat_scmi_rstd_count(unsigned int agent_id)
  372. {
  373. const struct scmi_resources *resource = find_resource(agent_id);
  374. if (resource == NULL) {
  375. return 0U;
  376. }
  377. return resource->reset_count;
  378. }
  379. int32_t plat_scmi_rstd_autonomous(unsigned int agent_id, unsigned int scmi_id,
  380. uint32_t state)
  381. {
  382. const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
  383. if (reset == NULL) {
  384. return SCMI_NOT_FOUND;
  385. }
  386. /* Supports only reset with context loss */
  387. if (state != 0U) {
  388. return SCMI_NOT_SUPPORTED;
  389. }
  390. NOTICE("SCMI reset on ID %lu/%s\n",
  391. reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
  392. return SCMI_SUCCESS;
  393. }
  394. int32_t plat_scmi_rstd_set_state(unsigned int agent_id, unsigned int scmi_id,
  395. bool assert_not_deassert)
  396. {
  397. const struct scmi_reset *reset = find_reset(agent_id, scmi_id);
  398. if (reset == NULL) {
  399. return SCMI_NOT_FOUND;
  400. }
  401. if (assert_not_deassert) {
  402. NOTICE("SCMI reset %lu/%s set\n",
  403. reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
  404. switch (scmi_id) {
  405. case RESET_UFS0_0:
  406. mmio_write_32(PMXC_CRP_RST_UFS, 1);
  407. break;
  408. case RESET_UFSPHY_0:
  409. mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 1);
  410. break;
  411. default:
  412. break;
  413. }
  414. } else {
  415. NOTICE("SCMI reset %lu/%s release\n",
  416. reset->reset_id, plat_scmi_rstd_get_name(agent_id, scmi_id));
  417. switch (scmi_id) {
  418. case RESET_UFS0_0:
  419. mmio_write_32(PMXC_CRP_RST_UFS, 0);
  420. break;
  421. case RESET_UFSPHY_0:
  422. mmio_write_32(PMXC_IOU_SLCR_PHY_RESET, 0);
  423. break;
  424. default:
  425. break;
  426. }
  427. }
  428. return SCMI_SUCCESS;
  429. }
  430. /*
  431. * Platform SCMI reset domains
  432. */
  433. static struct scmi_pd *find_pd(unsigned int agent_id, unsigned int pd_id)
  434. {
  435. const struct scmi_resources *resource = find_resource(agent_id);
  436. size_t n;
  437. if (resource != NULL) {
  438. for (n = 0U; n < resource->pd_count; n++) {
  439. if (n == pd_id) {
  440. return &resource->pd[n];
  441. }
  442. }
  443. }
  444. return NULL;
  445. }
  446. size_t plat_scmi_pd_count(unsigned int agent_id)
  447. {
  448. const struct scmi_resources *resource = find_resource(agent_id);
  449. size_t ret;
  450. if (resource == NULL) {
  451. ret = 0U;
  452. } else {
  453. ret = resource->pd_count;
  454. NOTICE("SCMI: PD: %d\n", (unsigned int)ret);
  455. }
  456. return ret;
  457. }
  458. const char *plat_scmi_pd_get_name(unsigned int agent_id, unsigned int pd_id)
  459. {
  460. const struct scmi_pd *pd = find_pd(agent_id, pd_id);
  461. if (pd == NULL) {
  462. return NULL;
  463. }
  464. return pd->name;
  465. }
  466. unsigned int plat_scmi_pd_statistics(unsigned int agent_id, unsigned long *pd_id)
  467. {
  468. return 0U;
  469. }
  470. unsigned int plat_scmi_pd_get_attributes(unsigned int agent_id, unsigned int pd_id)
  471. {
  472. return 0U;
  473. }
  474. unsigned int plat_scmi_pd_get_state(unsigned int agent_id, unsigned int pd_id)
  475. {
  476. const struct scmi_pd *pd = find_pd(agent_id, pd_id);
  477. if (pd == NULL) {
  478. return SCMI_NOT_SUPPORTED;
  479. }
  480. NOTICE("SCMI: PD: get id: %d, state: %x\n", pd_id, pd->state);
  481. return pd->state;
  482. }
  483. int32_t plat_scmi_pd_set_state(unsigned int agent_id, unsigned int flags, unsigned int pd_id,
  484. unsigned int state)
  485. {
  486. struct scmi_pd *pd = find_pd(agent_id, pd_id);
  487. if (pd == NULL) {
  488. return SCMI_NOT_SUPPORTED;
  489. }
  490. NOTICE("SCMI: PD: set id: %d, orig state: %x, new state: %x, flags: %x\n",
  491. pd_id, pd->state, state, flags);
  492. pd->state = state;
  493. return 0U;
  494. }
  495. /* Currently only one channel is supported. Expectation is that channel 0 is used by NS SW */
  496. static struct scmi_msg_channel scmi_channel[] = {
  497. [0] = {
  498. .shm_addr = SMT_BUFFER_BASE,
  499. .shm_size = SMT_BUF_SLOT_SIZE,
  500. },
  501. };
  502. struct scmi_msg_channel *plat_scmi_get_channel(unsigned int agent_id)
  503. {
  504. assert(agent_id < ARRAY_SIZE(scmi_channel));
  505. VERBOSE("%d: SCMI asking for channel\n", agent_id);
  506. /* Just in case that code is reused */
  507. return &scmi_channel[agent_id];
  508. }
  509. /* Base protocol implementations */
  510. const char *plat_scmi_vendor_name(void)
  511. {
  512. return SCMI_VENDOR;
  513. }
  514. const char *plat_scmi_sub_vendor_name(void)
  515. {
  516. return SCMI_PRODUCT;
  517. }
  518. /* Currently supporting Clocks and Reset Domains */
  519. static const uint8_t plat_protocol_list[] = {
  520. SCMI_PROTOCOL_ID_BASE,
  521. SCMI_PROTOCOL_ID_CLOCK,
  522. SCMI_PROTOCOL_ID_RESET_DOMAIN,
  523. SCMI_PROTOCOL_ID_POWER_DOMAIN,
  524. /* SCMI_PROTOCOL_ID_SENSOR, */
  525. 0U /* Null termination */
  526. };
  527. size_t plat_scmi_protocol_count(void)
  528. {
  529. const size_t count = ARRAY_SIZE(plat_protocol_list) - 1U;
  530. VERBOSE("SCMI: Protocol count: %d\n", (int32_t)count);
  531. return count;
  532. }
  533. const uint8_t *plat_scmi_protocol_list(unsigned int agent_id __unused)
  534. {
  535. return plat_protocol_list;
  536. }
  537. void init_scmi_server(void)
  538. {
  539. size_t i;
  540. int32_t ret;
  541. for (i = 0U; i < ARRAY_SIZE(scmi_channel); i++)
  542. scmi_smt_init_agent_channel(&scmi_channel[i]);
  543. INFO("SCMI: Server initialized\n");
  544. if (platform_id == QEMU) {
  545. /* default setting is for QEMU */
  546. } else if (platform_id == SPP) {
  547. for (i = 0U; i < ARRAY_SIZE(scmi0_clock); i++) {
  548. /* Keep i2c on 100MHz to calculate rates properly */
  549. if ((i >= CLK_I2C0_0) && (i <= CLK_I2C7_0))
  550. continue;
  551. /* Keep UFS clocks to default values to get the expected rates */
  552. if (i >= CLK_UFS0_0 && i <= CLK_UFS0_2)
  553. continue;
  554. /*
  555. * SPP supports multiple versions.
  556. * The cpu_clock value is set to corresponding SPP
  557. * version in early platform setup, resuse the same
  558. * value here.
  559. */
  560. ret = plat_scmi_clock_set_rate(0, i, cpu_clock);
  561. if (ret < 0) {
  562. NOTICE("Failed to set clock rate for SPP scmi_id=%ld\n", i);
  563. }
  564. }
  565. } else {
  566. /* Making MISRA C 2012 15.7 compliant */
  567. }
  568. }