pm_api_ioctl.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720
  1. /*
  2. * Copyright (c) 2018-2022, Arm Limited and Contributors. All rights reserved.
  3. * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. /*
  8. * ZynqMP system level PM-API functions for ioctl.
  9. */
  10. #include <arch_helpers.h>
  11. #include <drivers/delay_timer.h>
  12. #include <lib/mmio.h>
  13. #include <plat/common/platform.h>
  14. #include "pm_api_clock.h"
  15. #include "pm_api_ioctl.h"
  16. #include "pm_client.h"
  17. #include "pm_common.h"
  18. #include "pm_ipi.h"
  19. #include <zynqmp_def.h>
  20. #include "zynqmp_pm_api_sys.h"
  21. /**
  22. * pm_ioctl_get_rpu_oper_mode () - Get current RPU operation mode.
  23. * @mode: Buffer to store value of oper mode(Split/Lock-step)
  24. *
  25. * This function provides current configured RPU operational mode.
  26. *
  27. * Return: Returns status, either success or error+reason.
  28. *
  29. */
  30. static enum pm_ret_status pm_ioctl_get_rpu_oper_mode(uint32_t *mode)
  31. {
  32. uint32_t val;
  33. val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
  34. val &= ZYNQMP_SLSPLIT_MASK;
  35. if (val == 0U) {
  36. *mode = PM_RPU_MODE_LOCKSTEP;
  37. } else {
  38. *mode = PM_RPU_MODE_SPLIT;
  39. }
  40. return PM_RET_SUCCESS;
  41. }
  42. /**
  43. * pm_ioctl_set_rpu_oper_mode () - Configure RPU operation mode.
  44. * @mode: Value to set for oper mode(Split/Lock-step).
  45. *
  46. * This function configures RPU operational mode(Split/Lock-step).
  47. * It also sets TCM combined mode in RPU lock-step and TCM non-combined
  48. * mode for RPU split mode. In case of Lock step mode, RPU1's output is
  49. * clamped.
  50. *
  51. * Return: Returns status, either success or error+reason.
  52. *
  53. */
  54. static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(uint32_t mode)
  55. {
  56. uint32_t val;
  57. if ((mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) != 0U) {
  58. return PM_RET_ERROR_ACCESS;
  59. }
  60. val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
  61. if (mode == PM_RPU_MODE_SPLIT) {
  62. val |= ZYNQMP_SLSPLIT_MASK;
  63. val &= ~ZYNQMP_TCM_COMB_MASK;
  64. val &= ~ZYNQMP_SLCLAMP_MASK;
  65. } else if (mode == PM_RPU_MODE_LOCKSTEP) {
  66. val &= ~ZYNQMP_SLSPLIT_MASK;
  67. val |= ZYNQMP_TCM_COMB_MASK;
  68. val |= ZYNQMP_SLCLAMP_MASK;
  69. } else {
  70. return PM_RET_ERROR_ARGS;
  71. }
  72. mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
  73. return PM_RET_SUCCESS;
  74. }
  75. /**
  76. * pm_ioctl_config_boot_addr() - Configure RPU boot address.
  77. * @nid: Node ID of RPU.
  78. * @value: Value to set for boot address (TCM/OCM).
  79. *
  80. * This function configures RPU boot address(memory).
  81. *
  82. * Return: Returns status, either success or error+reason.
  83. *
  84. */
  85. static enum pm_ret_status pm_ioctl_config_boot_addr(enum pm_node_id nid,
  86. uint32_t value)
  87. {
  88. uint32_t rpu_cfg_addr, val;
  89. if (nid == NODE_RPU_0) {
  90. rpu_cfg_addr = ZYNQMP_RPU0_CFG;
  91. } else if (nid == NODE_RPU_1) {
  92. rpu_cfg_addr = ZYNQMP_RPU1_CFG;
  93. } else {
  94. return PM_RET_ERROR_ARGS;
  95. }
  96. val = mmio_read_32(rpu_cfg_addr);
  97. if (value == PM_RPU_BOOTMEM_LOVEC) {
  98. val &= ~ZYNQMP_VINITHI_MASK;
  99. } else if (value == PM_RPU_BOOTMEM_HIVEC) {
  100. val |= ZYNQMP_VINITHI_MASK;
  101. } else {
  102. return PM_RET_ERROR_ARGS;
  103. }
  104. mmio_write_32(rpu_cfg_addr, val);
  105. return PM_RET_SUCCESS;
  106. }
  107. /**
  108. * pm_ioctl_config_tcm_comb() - Configure TCM combined mode.
  109. * @value: Value to set (Split/Combined).
  110. *
  111. * This function configures TCM to be in split mode or combined
  112. * mode.
  113. *
  114. * Return: Returns status, either success or error+reason.
  115. *
  116. */
  117. static enum pm_ret_status pm_ioctl_config_tcm_comb(uint32_t value)
  118. {
  119. uint32_t val;
  120. val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL);
  121. if (value == PM_RPU_TCM_SPLIT) {
  122. val &= ~ZYNQMP_TCM_COMB_MASK;
  123. } else if (value == PM_RPU_TCM_COMB) {
  124. val |= ZYNQMP_TCM_COMB_MASK;
  125. } else {
  126. return PM_RET_ERROR_ARGS;
  127. }
  128. mmio_write_32(ZYNQMP_RPU_GLBL_CNTL, val);
  129. return PM_RET_SUCCESS;
  130. }
  131. /**
  132. * pm_ioctl_set_tapdelay_bypass() - Enable/Disable tap delay bypass.
  133. * @type: Type of tap delay to enable/disable (e.g. QSPI).
  134. * @value: Enable/Disable.
  135. *
  136. * This function enable/disable tap delay bypass.
  137. *
  138. * Return: Returns status, either success or error+reason.
  139. *
  140. */
  141. static enum pm_ret_status pm_ioctl_set_tapdelay_bypass(uint32_t type,
  142. uint32_t value)
  143. {
  144. if ((((value != PM_TAPDELAY_BYPASS_ENABLE) &&
  145. (value != PM_TAPDELAY_BYPASS_DISABLE)) || (type >= PM_TAPDELAY_MAX))) {
  146. return PM_RET_ERROR_ARGS;
  147. }
  148. return pm_mmio_write(IOU_TAPDLY_BYPASS, TAP_DELAY_MASK, value << type);
  149. }
  150. /**
  151. * pm_ioctl_sd_dll_reset() - Reset DLL logic.
  152. * @nid: Node ID of the device.
  153. * @type: Reset type.
  154. *
  155. * This function resets DLL logic for the SD device.
  156. *
  157. * Return: Returns status, either success or error+reason.
  158. *
  159. */
  160. static enum pm_ret_status pm_ioctl_sd_dll_reset(enum pm_node_id nid,
  161. uint32_t type)
  162. {
  163. uint32_t mask, val;
  164. enum pm_ret_status ret;
  165. if (nid == NODE_SD_0) {
  166. mask = ZYNQMP_SD0_DLL_RST_MASK;
  167. val = ZYNQMP_SD0_DLL_RST;
  168. } else if (nid == NODE_SD_1) {
  169. mask = ZYNQMP_SD1_DLL_RST_MASK;
  170. val = ZYNQMP_SD1_DLL_RST;
  171. } else {
  172. return PM_RET_ERROR_ARGS;
  173. }
  174. switch (type) {
  175. case PM_DLL_RESET_ASSERT:
  176. case PM_DLL_RESET_PULSE:
  177. ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, val);
  178. if (ret != PM_RET_SUCCESS) {
  179. return ret;
  180. }
  181. if (type == PM_DLL_RESET_ASSERT) {
  182. break;
  183. }
  184. mdelay(1);
  185. /* Fallthrough */
  186. case PM_DLL_RESET_RELEASE:
  187. ret = pm_mmio_write(ZYNQMP_SD_DLL_CTRL, mask, 0);
  188. break;
  189. default:
  190. ret = PM_RET_ERROR_ARGS;
  191. break;
  192. }
  193. return ret;
  194. }
  195. /**
  196. * pm_ioctl_sd_set_tapdelay() - Set tap delay for the SD device.
  197. * @nid: Node ID of the device.
  198. * @type: Type of tap delay to set (input/output).
  199. * @value: Value to set fot the tap delay.
  200. *
  201. * This function sets input/output tap delay for the SD device.
  202. *
  203. * Return: Returns status, either success or error+reason.
  204. *
  205. */
  206. static enum pm_ret_status pm_ioctl_sd_set_tapdelay(enum pm_node_id nid,
  207. enum tap_delay_type type,
  208. uint32_t value)
  209. {
  210. uint32_t shift;
  211. enum pm_ret_status ret;
  212. uint32_t val, mask;
  213. if (nid == NODE_SD_0) {
  214. shift = 0;
  215. mask = ZYNQMP_SD0_DLL_RST_MASK;
  216. } else if (nid == NODE_SD_1) {
  217. shift = ZYNQMP_SD_TAP_OFFSET;
  218. mask = ZYNQMP_SD1_DLL_RST_MASK;
  219. } else {
  220. return PM_RET_ERROR_ARGS;
  221. }
  222. ret = pm_mmio_read(ZYNQMP_SD_DLL_CTRL, &val);
  223. if (ret != PM_RET_SUCCESS) {
  224. return ret;
  225. }
  226. if ((val & mask) == 0U) {
  227. ret = pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_ASSERT);
  228. if (ret != PM_RET_SUCCESS) {
  229. return ret;
  230. }
  231. }
  232. if (type == PM_TAPDELAY_INPUT) {
  233. ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
  234. (ZYNQMP_SD_ITAPCHGWIN_MASK << shift),
  235. (ZYNQMP_SD_ITAPCHGWIN << shift));
  236. if (ret != PM_RET_SUCCESS) {
  237. goto reset_release;
  238. }
  239. if (value == 0U) {
  240. ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
  241. (ZYNQMP_SD_ITAPDLYENA_MASK <<
  242. shift), 0);
  243. } else {
  244. ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
  245. (ZYNQMP_SD_ITAPDLYENA_MASK <<
  246. shift), (ZYNQMP_SD_ITAPDLYENA <<
  247. shift));
  248. }
  249. if (ret != PM_RET_SUCCESS) {
  250. goto reset_release;
  251. }
  252. ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
  253. (ZYNQMP_SD_ITAPDLYSEL_MASK << shift),
  254. (value << shift));
  255. if (ret != PM_RET_SUCCESS) {
  256. goto reset_release;
  257. }
  258. ret = pm_mmio_write(ZYNQMP_SD_ITAP_DLY,
  259. (ZYNQMP_SD_ITAPCHGWIN_MASK << shift), 0);
  260. } else if (type == PM_TAPDELAY_OUTPUT) {
  261. ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
  262. (ZYNQMP_SD_OTAPDLYENA_MASK << shift), 0);
  263. if (ret != PM_RET_SUCCESS) {
  264. goto reset_release;
  265. }
  266. ret = pm_mmio_write(ZYNQMP_SD_OTAP_DLY,
  267. (ZYNQMP_SD_OTAPDLYSEL_MASK << shift),
  268. (value << shift));
  269. } else {
  270. ret = PM_RET_ERROR_ARGS;
  271. }
  272. reset_release:
  273. if ((val & mask) == 0) {
  274. (void)pm_ioctl_sd_dll_reset(nid, PM_DLL_RESET_RELEASE);
  275. }
  276. return ret;
  277. }
  278. /**
  279. * pm_ioctl_set_pll_frac_mode() - Ioctl function for setting pll mode.
  280. * @pll: PLL clock id.
  281. * @mode: Mode fraction/integar.
  282. *
  283. * This function sets PLL mode.
  284. *
  285. * Return: Returns status, either success or error+reason.
  286. *
  287. */
  288. static enum pm_ret_status pm_ioctl_set_pll_frac_mode
  289. (uint32_t pll, uint32_t mode)
  290. {
  291. return pm_clock_set_pll_mode(pll, mode);
  292. }
  293. /**
  294. * pm_ioctl_get_pll_frac_mode() - Ioctl function for getting pll mode.
  295. * @pll: PLL clock id.
  296. * @mode: Mode fraction/integar.
  297. *
  298. * This function return current PLL mode.
  299. *
  300. * Return: Returns status, either success or error+reason.
  301. *
  302. */
  303. static enum pm_ret_status pm_ioctl_get_pll_frac_mode
  304. (uint32_t pll, uint32_t *mode)
  305. {
  306. return pm_clock_get_pll_mode(pll, mode);
  307. }
  308. /**
  309. * pm_ioctl_set_pll_frac_data() - Ioctl function for setting pll fraction data.
  310. * @pll: PLL clock id.
  311. * @data: fraction data.
  312. *
  313. * This function sets fraction data.
  314. * It is valid for fraction mode only.
  315. *
  316. * Return: Returns status, either success or error+reason.
  317. *
  318. */
  319. static enum pm_ret_status pm_ioctl_set_pll_frac_data
  320. (uint32_t pll, uint32_t data)
  321. {
  322. enum pm_node_id pll_nid;
  323. enum pm_ret_status status;
  324. /* Get PLL node ID using PLL clock ID */
  325. status = pm_clock_get_pll_node_id(pll, &pll_nid);
  326. if (status != PM_RET_SUCCESS) {
  327. return status;
  328. }
  329. return pm_pll_set_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
  330. }
  331. /**
  332. * pm_ioctl_get_pll_frac_data() - Ioctl function for getting pll fraction data.
  333. * @pll: PLL clock id.
  334. * @data: fraction data.
  335. *
  336. * This function returns fraction data value.
  337. *
  338. * Return: Returns status, either success or error+reason.
  339. *
  340. */
  341. static enum pm_ret_status pm_ioctl_get_pll_frac_data
  342. (uint32_t pll, uint32_t *data)
  343. {
  344. enum pm_node_id pll_nid;
  345. enum pm_ret_status status;
  346. /* Get PLL node ID using PLL clock ID */
  347. status = pm_clock_get_pll_node_id(pll, &pll_nid);
  348. if (status != PM_RET_SUCCESS) {
  349. return status;
  350. }
  351. return pm_pll_get_parameter(pll_nid, PM_PLL_PARAM_DATA, data);
  352. }
  353. /**
  354. * pm_ioctl_write_ggs() - Ioctl function for writing global general storage
  355. * (ggs).
  356. * @index: GGS register index.
  357. * @value: Register value to be written.
  358. *
  359. * This function writes value to GGS register.
  360. *
  361. * Return: Returns status, either success or error+reason.
  362. *
  363. */
  364. static enum pm_ret_status pm_ioctl_write_ggs(uint32_t index,
  365. uint32_t value)
  366. {
  367. if (index >= GGS_NUM_REGS) {
  368. return PM_RET_ERROR_ARGS;
  369. }
  370. return pm_mmio_write(GGS_BASEADDR + (index << 2),
  371. 0xFFFFFFFFU, value);
  372. }
  373. /**
  374. * pm_ioctl_read_ggs() - Ioctl function for reading global general storage
  375. * (ggs).
  376. * @index: GGS register index.
  377. * @value: Register value.
  378. *
  379. * This function returns GGS register value.
  380. *
  381. * Return: Returns status, either success or error+reason.
  382. *
  383. */
  384. static enum pm_ret_status pm_ioctl_read_ggs(uint32_t index,
  385. uint32_t *value)
  386. {
  387. if (index >= GGS_NUM_REGS) {
  388. return PM_RET_ERROR_ARGS;
  389. }
  390. return pm_mmio_read(GGS_BASEADDR + (index << 2), value);
  391. }
  392. /**
  393. * pm_ioctl_write_pggs() - Ioctl function for writing persistent global general
  394. * storage (pggs).
  395. * @index: PGGS register index.
  396. * @value: Register value to be written.
  397. *
  398. * This function writes value to PGGS register.
  399. *
  400. * Return: Returns status, either success or error+reason.
  401. *
  402. */
  403. static enum pm_ret_status pm_ioctl_write_pggs(uint32_t index,
  404. uint32_t value)
  405. {
  406. if (index >= PGGS_NUM_REGS) {
  407. return PM_RET_ERROR_ARGS;
  408. }
  409. return pm_mmio_write(PGGS_BASEADDR + (index << 2),
  410. 0xFFFFFFFFU, value);
  411. }
  412. /**
  413. * pm_ioctl_afi() - Ioctl function for writing afi values.
  414. * @index: AFI register index.
  415. * @value: Register value to be written.
  416. *
  417. * Return: Returns status, either success or error+reason.
  418. *
  419. */
  420. static enum pm_ret_status pm_ioctl_afi(uint32_t index,
  421. uint32_t value)
  422. {
  423. uint32_t mask;
  424. const uint32_t regarr[] = {0xFD360000U,
  425. 0xFD360014U,
  426. 0xFD370000U,
  427. 0xFD370014U,
  428. 0xFD380000U,
  429. 0xFD380014U,
  430. 0xFD390000U,
  431. 0xFD390014U,
  432. 0xFD3a0000U,
  433. 0xFD3a0014U,
  434. 0xFD3b0000U,
  435. 0xFD3b0014U,
  436. 0xFF9b0000U,
  437. 0xFF9b0014U,
  438. 0xFD615000U,
  439. 0xFF419000U,
  440. };
  441. if (index >= ARRAY_SIZE(regarr)) {
  442. return PM_RET_ERROR_ARGS;
  443. }
  444. if (index <= AFIFM6_WRCTRL) {
  445. mask = FABRIC_WIDTH;
  446. } else {
  447. mask = 0xf00;
  448. }
  449. return pm_mmio_write(regarr[index], mask, value);
  450. }
  451. /**
  452. * pm_ioctl_read_pggs() - Ioctl function for reading persistent global general
  453. * storage (pggs).
  454. * @index: PGGS register index.
  455. * @value: Register value.
  456. *
  457. * This function returns PGGS register value.
  458. *
  459. * Return: Returns status, either success or error+reason.
  460. *
  461. */
  462. static enum pm_ret_status pm_ioctl_read_pggs(uint32_t index,
  463. uint32_t *value)
  464. {
  465. if (index >= PGGS_NUM_REGS) {
  466. return PM_RET_ERROR_ARGS;
  467. }
  468. return pm_mmio_read(PGGS_BASEADDR + (index << 2), value);
  469. }
  470. /**
  471. * pm_ioctl_ulpi_reset() - Ioctl function for performing ULPI reset.
  472. *
  473. * Return: Returns status, either success or error+reason.
  474. *
  475. * This function peerforms the ULPI reset sequence for resetting
  476. * the ULPI transceiver.
  477. */
  478. static enum pm_ret_status pm_ioctl_ulpi_reset(void)
  479. {
  480. enum pm_ret_status ret;
  481. ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
  482. ZYNQMP_ULPI_RESET_VAL_HIGH);
  483. if (ret != PM_RET_SUCCESS) {
  484. return ret;
  485. }
  486. /* Drive ULPI assert for atleast 1ms */
  487. mdelay(1);
  488. ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
  489. ZYNQMP_ULPI_RESET_VAL_LOW);
  490. if (ret != PM_RET_SUCCESS) {
  491. return ret;
  492. }
  493. /* Drive ULPI de-assert for atleast 1ms */
  494. mdelay(1);
  495. ret = pm_mmio_write(CRL_APB_BOOT_PIN_CTRL, CRL_APB_BOOT_PIN_MASK,
  496. ZYNQMP_ULPI_RESET_VAL_HIGH);
  497. return ret;
  498. }
  499. /**
  500. * pm_ioctl_set_boot_health_status() - Ioctl for setting healthy boot status.
  501. * @value: Value to write.
  502. *
  503. * This function sets healthy bit value to indicate boot health status
  504. * to firmware.
  505. *
  506. * Return: Returns status, either success or error+reason.
  507. *
  508. */
  509. static enum pm_ret_status pm_ioctl_set_boot_health_status(uint32_t value)
  510. {
  511. return pm_mmio_write(PMU_GLOBAL_GEN_STORAGE4,
  512. PM_BOOT_HEALTH_STATUS_MASK, value);
  513. }
  514. /**
  515. * pm_api_ioctl() - PM IOCTL API for device control and configs.
  516. * @nid: Node ID of the device.
  517. * @ioctl_id: ID of the requested IOCTL.
  518. * @arg1: Argument 1 to requested IOCTL call.
  519. * @arg2: Argument 2 to requested IOCTL call.
  520. * @value: Returned output value.
  521. *
  522. * This function calls IOCTL to firmware for device control and configuration.
  523. *
  524. * Return: Returns status, either success or error+reason.
  525. *
  526. */
  527. enum pm_ret_status pm_api_ioctl(enum pm_node_id nid,
  528. uint32_t ioctl_id,
  529. uint32_t arg1,
  530. uint32_t arg2,
  531. uint32_t *value)
  532. {
  533. enum pm_ret_status ret;
  534. uint32_t payload[PAYLOAD_ARG_CNT];
  535. switch (ioctl_id) {
  536. case IOCTL_GET_RPU_OPER_MODE:
  537. ret = pm_ioctl_get_rpu_oper_mode(value);
  538. break;
  539. case IOCTL_SET_RPU_OPER_MODE:
  540. ret = pm_ioctl_set_rpu_oper_mode(arg1);
  541. break;
  542. case IOCTL_RPU_BOOT_ADDR_CONFIG:
  543. ret = pm_ioctl_config_boot_addr(nid, arg1);
  544. break;
  545. case IOCTL_TCM_COMB_CONFIG:
  546. ret = pm_ioctl_config_tcm_comb(arg1);
  547. break;
  548. case IOCTL_SET_TAPDELAY_BYPASS:
  549. ret = pm_ioctl_set_tapdelay_bypass(arg1, arg2);
  550. break;
  551. case IOCTL_SD_DLL_RESET:
  552. ret = pm_ioctl_sd_dll_reset(nid, arg1);
  553. break;
  554. case IOCTL_SET_SD_TAPDELAY:
  555. ret = pm_ioctl_sd_set_tapdelay(nid, arg1, arg2);
  556. break;
  557. case IOCTL_SET_PLL_FRAC_MODE:
  558. ret = pm_ioctl_set_pll_frac_mode(arg1, arg2);
  559. break;
  560. case IOCTL_GET_PLL_FRAC_MODE:
  561. ret = pm_ioctl_get_pll_frac_mode(arg1, value);
  562. break;
  563. case IOCTL_SET_PLL_FRAC_DATA:
  564. ret = pm_ioctl_set_pll_frac_data(arg1, arg2);
  565. break;
  566. case IOCTL_GET_PLL_FRAC_DATA:
  567. ret = pm_ioctl_get_pll_frac_data(arg1, value);
  568. break;
  569. case IOCTL_WRITE_GGS:
  570. ret = pm_ioctl_write_ggs(arg1, arg2);
  571. break;
  572. case IOCTL_READ_GGS:
  573. ret = pm_ioctl_read_ggs(arg1, value);
  574. break;
  575. case IOCTL_WRITE_PGGS:
  576. ret = pm_ioctl_write_pggs(arg1, arg2);
  577. break;
  578. case IOCTL_READ_PGGS:
  579. ret = pm_ioctl_read_pggs(arg1, value);
  580. break;
  581. case IOCTL_ULPI_RESET:
  582. ret = pm_ioctl_ulpi_reset();
  583. break;
  584. case IOCTL_SET_BOOT_HEALTH_STATUS:
  585. ret = pm_ioctl_set_boot_health_status(arg1);
  586. break;
  587. case IOCTL_AFI:
  588. ret = pm_ioctl_afi(arg1, arg2);
  589. break;
  590. default:
  591. /* Send request to the PMU */
  592. PM_PACK_PAYLOAD5(payload, PM_IOCTL, nid, ioctl_id, arg1, arg2);
  593. ret = pm_ipi_send_sync(primary_proc, payload, value, 1);
  594. break;
  595. }
  596. return ret;
  597. }
  598. /**
  599. * tfa_ioctl_bitmask() - API to get supported IOCTL ID mask.
  600. * @bit_mask: Returned bit mask of supported IOCTL IDs.
  601. *
  602. * Return: 0 success, negative value for errors.
  603. *
  604. */
  605. enum pm_ret_status tfa_ioctl_bitmask(uint32_t *bit_mask)
  606. {
  607. const uint8_t supported_ids[] = {
  608. IOCTL_GET_RPU_OPER_MODE,
  609. IOCTL_SET_RPU_OPER_MODE,
  610. IOCTL_RPU_BOOT_ADDR_CONFIG,
  611. IOCTL_TCM_COMB_CONFIG,
  612. IOCTL_SET_TAPDELAY_BYPASS,
  613. IOCTL_SD_DLL_RESET,
  614. IOCTL_SET_SD_TAPDELAY,
  615. IOCTL_SET_PLL_FRAC_MODE,
  616. IOCTL_GET_PLL_FRAC_MODE,
  617. IOCTL_SET_PLL_FRAC_DATA,
  618. IOCTL_GET_PLL_FRAC_DATA,
  619. IOCTL_WRITE_GGS,
  620. IOCTL_READ_GGS,
  621. IOCTL_WRITE_PGGS,
  622. IOCTL_READ_PGGS,
  623. IOCTL_ULPI_RESET,
  624. IOCTL_SET_BOOT_HEALTH_STATUS,
  625. IOCTL_AFI,
  626. };
  627. uint8_t i, ioctl_id;
  628. int32_t ret;
  629. for (i = 0U; i < ARRAY_SIZE(supported_ids); i++) {
  630. ioctl_id = supported_ids[i];
  631. if (ioctl_id >= 64U) {
  632. return PM_RET_ERROR_NOTSUPPORTED;
  633. }
  634. ret = check_api_dependency(ioctl_id);
  635. if (ret == PM_RET_SUCCESS) {
  636. bit_mask[ioctl_id / 32U] |= BIT(ioctl_id % 32U);
  637. }
  638. }
  639. return PM_RET_SUCCESS;
  640. }