plat_pm.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. /*
  2. * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <errno.h>
  7. #include <arch_helpers.h>
  8. #include <common/bl_common.h>
  9. #include <common/debug.h>
  10. #include <drivers/arm/cci.h>
  11. #include <drivers/arm/gicv2.h>
  12. #include <lib/bakery_lock.h>
  13. #include <lib/mmio.h>
  14. #include <lib/psci/psci.h>
  15. #include <plat/common/platform.h>
  16. #include "iic_dvfs.h"
  17. #include "platform_def.h"
  18. #include "pwrc.h"
  19. #include "rcar_def.h"
  20. #include "rcar_private.h"
  21. #if RCAR_GEN3_ULCB
  22. #include "ulcb_cpld.h"
  23. #endif /* RCAR_GEN3_ULCB */
  24. #define DVFS_SET_VID_0V (0x00)
  25. #define P_ALL_OFF (0x80)
  26. #define KEEPON_DDR1C (0x08)
  27. #define KEEPON_DDR0C (0x04)
  28. #define KEEPON_DDR1 (0x02)
  29. #define KEEPON_DDR0 (0x01)
  30. #define SYSTEM_PWR_STATE(s) ((s)->pwr_domain_state[PLAT_MAX_PWR_LVL])
  31. #define CLUSTER_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL1])
  32. #define CORE_PWR_STATE(s) ((s)->pwr_domain_state[MPIDR_AFFLVL0])
  33. extern void rcar_pwrc_restore_generic_timer(uint64_t *stack);
  34. extern void plat_rcar_gic_driver_init(void);
  35. extern void plat_rcar_gic_init(void);
  36. static uintptr_t rcar_sec_entrypoint;
  37. static void rcar_program_mailbox(u_register_t mpidr, uintptr_t address)
  38. {
  39. mailbox_t *rcar_mboxes = (mailbox_t *) MBOX_BASE;
  40. uint64_t linear_id = plat_core_pos_by_mpidr(mpidr);
  41. unsigned long range;
  42. rcar_mboxes[linear_id].value = address;
  43. range = (unsigned long)&rcar_mboxes[linear_id];
  44. flush_dcache_range(range, sizeof(range));
  45. }
  46. static void rcar_cpu_standby(plat_local_state_t cpu_state)
  47. {
  48. u_register_t scr_el3 = read_scr_el3();
  49. write_scr_el3(scr_el3 | SCR_IRQ_BIT);
  50. dsb();
  51. wfi();
  52. write_scr_el3(scr_el3);
  53. }
  54. static int rcar_pwr_domain_on(u_register_t mpidr)
  55. {
  56. rcar_program_mailbox(mpidr, rcar_sec_entrypoint);
  57. rcar_pwrc_cpuon(mpidr);
  58. return PSCI_E_SUCCESS;
  59. }
  60. static void rcar_pwr_domain_on_finish(const psci_power_state_t *target_state)
  61. {
  62. uint32_t cluster_type = rcar_pwrc_get_cluster();
  63. u_register_t mpidr = read_mpidr_el1();
  64. if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
  65. if (cluster_type == RCAR_CLUSTER_A53A57)
  66. plat_cci_enable();
  67. rcar_program_mailbox(mpidr, 0);
  68. rcar_pwrc_enable_interrupt_wakeup(mpidr);
  69. gicv2_cpuif_enable();
  70. gicv2_pcpu_distif_init();
  71. }
  72. static void rcar_pwr_domain_off(const psci_power_state_t *target_state)
  73. {
  74. #if RCAR_LSI != RCAR_D3
  75. uint32_t cluster_type = rcar_pwrc_get_cluster();
  76. #endif
  77. u_register_t mpidr = read_mpidr_el1();
  78. rcar_pwrc_disable_interrupt_wakeup(mpidr);
  79. gicv2_cpuif_disable();
  80. rcar_pwrc_cpuoff(mpidr);
  81. #if RCAR_LSI != RCAR_D3
  82. if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
  83. if (cluster_type == RCAR_CLUSTER_A53A57)
  84. plat_cci_disable();
  85. rcar_pwrc_clusteroff(mpidr);
  86. }
  87. #endif
  88. }
  89. static void rcar_pwr_domain_suspend(const psci_power_state_t *target_state)
  90. {
  91. uint32_t cluster_type = rcar_pwrc_get_cluster();
  92. u_register_t mpidr = read_mpidr_el1();
  93. if (CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
  94. return;
  95. rcar_program_mailbox(mpidr, rcar_sec_entrypoint);
  96. rcar_pwrc_enable_interrupt_wakeup(mpidr);
  97. gicv2_cpuif_disable();
  98. rcar_pwrc_cpuoff(mpidr);
  99. if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
  100. if (cluster_type == RCAR_CLUSTER_A53A57)
  101. plat_cci_disable();
  102. rcar_pwrc_clusteroff(mpidr);
  103. }
  104. }
  105. static void rcar_pwr_domain_suspend_finish(const psci_power_state_t
  106. *target_state)
  107. {
  108. uint32_t cluster_type = rcar_pwrc_get_cluster();
  109. if (SYSTEM_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE)
  110. goto finish;
  111. plat_rcar_gic_driver_init();
  112. plat_rcar_gic_init();
  113. if (cluster_type == RCAR_CLUSTER_A53A57)
  114. plat_cci_init();
  115. rcar_pwrc_restore_timer_state();
  116. rcar_pwrc_setup();
  117. rcar_pwrc_code_copy_to_system_ram();
  118. #if RCAR_SYSTEM_SUSPEND
  119. rcar_pwrc_init_suspend_to_ram();
  120. #endif
  121. finish:
  122. rcar_pwr_domain_on_finish(target_state);
  123. }
  124. static void __dead2 rcar_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
  125. {
  126. #if RCAR_SYSTEM_SUSPEND
  127. if (SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
  128. rcar_pwrc_suspend_to_ram();
  129. #endif
  130. wfi();
  131. ERROR("RCAR Power Down: operation not handled.\n");
  132. panic();
  133. }
  134. static void __dead2 rcar_system_off(void)
  135. {
  136. #if PMIC_ROHM_BD9571
  137. #if PMIC_LEVEL_MODE
  138. if (rcar_iic_dvfs_send(PMIC, DVFS_SET_VID, DVFS_SET_VID_0V))
  139. ERROR("BL3-1:Failed the SYSTEM-OFF.\n");
  140. #else
  141. if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF))
  142. ERROR("BL3-1:Failed the SYSTEM-RESET.\n");
  143. #endif
  144. #else
  145. u_register_t mpidr = read_mpidr_el1();
  146. u_register_t cpu = mpidr & 0x0000ffffU;
  147. int32_t rtn_on;
  148. rtn_on = rcar_pwrc_cpu_on_check(mpidr);
  149. if (cpu != rcar_boot_mpidr) {
  150. panic();
  151. }
  152. if (rtn_on != 0) {
  153. panic();
  154. }
  155. rcar_pwrc_cpuoff(mpidr);
  156. rcar_pwrc_clusteroff(mpidr);
  157. #endif /* PMIC_ROHM_BD9571 */
  158. wfi();
  159. ERROR("RCAR System Off: operation not handled.\n");
  160. panic();
  161. }
  162. static void __dead2 rcar_system_reset(void)
  163. {
  164. #if PMIC_ROHM_BD9571
  165. #if PMIC_LEVEL_MODE
  166. #if RCAR_SYSTEM_RESET_KEEPON_DDR
  167. uint8_t mode;
  168. int32_t error;
  169. error = rcar_iic_dvfs_send(PMIC, REG_KEEP10, KEEP10_MAGIC);
  170. if (error) {
  171. ERROR("Failed send KEEP10 magic ret=%d\n", error);
  172. goto done;
  173. }
  174. error = rcar_iic_dvfs_receive(PMIC, BKUP_MODE_CNT, &mode);
  175. if (error) {
  176. ERROR("Failed receive BKUP_Mode_Cnt ret=%d\n", error);
  177. goto done;
  178. }
  179. mode |= KEEPON_DDR1C | KEEPON_DDR0C | KEEPON_DDR1 | KEEPON_DDR0;
  180. error = rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, mode);
  181. if (error) {
  182. ERROR("Failed send KEEPON_DDRx ret=%d\n", error);
  183. goto done;
  184. }
  185. rcar_pwrc_set_suspend_to_ram();
  186. done:
  187. #else
  188. if (rcar_iic_dvfs_send(PMIC, BKUP_MODE_CNT, P_ALL_OFF))
  189. ERROR("BL3-1:Failed the SYSTEM-RESET.\n");
  190. #endif
  191. #else
  192. #if (RCAR_GEN3_ULCB == 1)
  193. rcar_cpld_reset_cpu();
  194. #endif
  195. #endif
  196. #else
  197. rcar_pwrc_system_reset();
  198. #endif
  199. wfi();
  200. ERROR("RCAR System Reset: operation not handled.\n");
  201. panic();
  202. }
  203. static int rcar_validate_power_state(unsigned int power_state,
  204. psci_power_state_t *req_state)
  205. {
  206. unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
  207. unsigned int pstate = psci_get_pstate_type(power_state);
  208. uint32_t i;
  209. if (pstate == PSTATE_TYPE_STANDBY) {
  210. if (pwr_lvl != MPIDR_AFFLVL0)
  211. return PSCI_E_INVALID_PARAMS;
  212. req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE;
  213. } else {
  214. for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++)
  215. req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
  216. }
  217. if (psci_get_pstate_id(power_state))
  218. return PSCI_E_INVALID_PARAMS;
  219. return PSCI_E_SUCCESS;
  220. }
  221. #if RCAR_SYSTEM_SUSPEND
  222. static void rcar_get_sys_suspend_power_state(psci_power_state_t *req_state)
  223. {
  224. u_register_t mpidr = read_mpidr_el1() & 0x0000ffffU;
  225. int i;
  226. if (mpidr != rcar_boot_mpidr)
  227. goto deny;
  228. for (i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
  229. req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
  230. return;
  231. deny:
  232. /* deny system suspend entry */
  233. req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] = PSCI_LOCAL_STATE_RUN;
  234. for (i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++)
  235. req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE;
  236. }
  237. #endif
  238. static const plat_psci_ops_t rcar_plat_psci_ops = {
  239. .cpu_standby = rcar_cpu_standby,
  240. .pwr_domain_on = rcar_pwr_domain_on,
  241. .pwr_domain_off = rcar_pwr_domain_off,
  242. .pwr_domain_suspend = rcar_pwr_domain_suspend,
  243. .pwr_domain_on_finish = rcar_pwr_domain_on_finish,
  244. .pwr_domain_suspend_finish = rcar_pwr_domain_suspend_finish,
  245. .system_off = rcar_system_off,
  246. .system_reset = rcar_system_reset,
  247. .validate_power_state = rcar_validate_power_state,
  248. .pwr_domain_pwr_down_wfi = rcar_pwr_domain_pwr_down_wfi,
  249. #if RCAR_SYSTEM_SUSPEND
  250. .get_sys_suspend_power_state = rcar_get_sys_suspend_power_state,
  251. #endif
  252. };
  253. int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops)
  254. {
  255. *psci_ops = &rcar_plat_psci_ops;
  256. rcar_sec_entrypoint = sec_entrypoint;
  257. #if RCAR_SYSTEM_SUSPEND
  258. rcar_pwrc_init_suspend_to_ram();
  259. #endif
  260. return 0;
  261. }