mt_spm_internal.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. /*
  2. * Copyright (c) 2022, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <stddef.h>
  8. #include <common/debug.h>
  9. #include <drivers/delay_timer.h>
  10. #include <lib/mmio.h>
  11. #include <mt_spm.h>
  12. #include <mt_spm_internal.h>
  13. #include <mt_spm_reg.h>
  14. #include <mt_spm_resource_req.h>
  15. #include <plat_pm.h>
  16. #include <platform_def.h>
  17. /* Define and Declare */
  18. #define ROOT_CORE_ADDR_OFFSET (0x20000000)
  19. #define SPM_WAKEUP_EVENT_MASK_CLEAN_MASK (0xefffffff)
  20. #define SPM_INIT_DONE_US (20)
  21. static unsigned int mt_spm_bblpm_cnt;
  22. const char *wakeup_src_str[32] = {
  23. [0] = "R12_PCM_TIMER",
  24. [1] = "R12_RESERVED_DEBUG_B",
  25. [2] = "R12_KP_IRQ_B",
  26. [3] = "R12_APWDT_EVENT_B",
  27. [4] = "R12_APXGPT1_EVENT_B",
  28. [5] = "R12_CONN2AP_SPM_WAKEUP_B",
  29. [6] = "R12_EINT_EVENT_B",
  30. [7] = "R12_CONN_WDT_IRQ_B",
  31. [8] = "R12_CCIF0_EVENT_B",
  32. [9] = "R12_LOWBATTERY_IRQ_B",
  33. [10] = "R12_SC_SSPM2SPM_WAKEUP_B",
  34. [11] = "R12_SC_SCP2SPM_WAKEUP_B",
  35. [12] = "R12_SC_ADSP2SPM_WAKEUP_B",
  36. [13] = "R12_PCM_WDT_WAKEUP_B",
  37. [14] = "R12_USB_CDSC_B",
  38. [15] = "R12_USB_POWERDWN_B",
  39. [16] = "R12_SYS_TIMER_EVENT_B",
  40. [17] = "R12_EINT_EVENT_SECURE_B",
  41. [18] = "R12_CCIF1_EVENT_B",
  42. [19] = "R12_UART0_IRQ_B",
  43. [20] = "R12_AFE_IRQ_MCU_B",
  44. [21] = "R12_THERM_CTRL_EVENT_B",
  45. [22] = "R12_SYS_CIRQ_IRQ_B",
  46. [23] = "R12_MD2AP_PEER_EVENT_B",
  47. [24] = "R12_CSYSPWREQ_B",
  48. [25] = "R12_MD1_WDT_B",
  49. [26] = "R12_AP2AP_PEER_WAKEUPEVENT_B",
  50. [27] = "R12_SEJ_EVENT_B",
  51. [28] = "R12_SPM_CPU_WAKEUPEVENT_B",
  52. [29] = "R12_APUSYS",
  53. [30] = "R12_PCIE_BRIDGE_IRQ",
  54. [31] = "R12_PCIE_IRQ",
  55. };
  56. /* Function and API */
  57. wake_reason_t __spm_output_wake_reason(int state_id, const struct wake_status *wakesta)
  58. {
  59. uint32_t i, bk_vtcxo_dur, spm_26m_off_pct = 0U;
  60. wake_reason_t wr = WR_UNKNOWN;
  61. if (wakesta != NULL) {
  62. if (wakesta->abort != 0U) {
  63. ERROR("spmfw flow is aborted: 0x%x, timer_out = %u\n",
  64. wakesta->abort, wakesta->timer_out);
  65. } else {
  66. for (i = 0U; i < 32U; i++) {
  67. if ((wakesta->r12 & BIT(i)) != 0U) {
  68. INFO("wake up by %s, timer_out = %u\n",
  69. wakeup_src_str[i], wakesta->timer_out);
  70. wr = WR_WAKE_SRC;
  71. break;
  72. }
  73. }
  74. }
  75. INFO("r12 = 0x%x, r12_ext = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n",
  76. wakesta->r12, wakesta->r12_ext, wakesta->r13, wakesta->debug_flag,
  77. wakesta->debug_flag1);
  78. INFO("raw_sta = 0x%x 0x%x 0x%x, idle_sta = 0x%x, cg_check_sta = 0x%x\n",
  79. wakesta->raw_sta, wakesta->md32pcm_wakeup_sta,
  80. wakesta->md32pcm_event_sta, wakesta->idle_sta,
  81. wakesta->cg_check_sta);
  82. INFO("req_sta = 0x%x 0x%x 0x%x 0x%x 0x%x, isr = 0x%x\n",
  83. wakesta->req_sta0, wakesta->req_sta1, wakesta->req_sta2,
  84. wakesta->req_sta3, wakesta->req_sta4, wakesta->isr);
  85. INFO("rt_req_sta0 = 0x%x, rt_req_sta1 = 0x%x, rt_req_sta2 = 0x%x\n",
  86. wakesta->rt_req_sta0, wakesta->rt_req_sta1, wakesta->rt_req_sta2);
  87. INFO("rt_req_sta3 = 0x%x, dram_sw_con_3 = 0x%x, raw_ext_sta = 0x%x\n",
  88. wakesta->rt_req_sta3, wakesta->rt_req_sta4, wakesta->raw_ext_sta);
  89. INFO("wake_misc = 0x%x, pcm_flag = 0x%x 0x%x 0x%x 0x%x, req = 0x%x\n",
  90. wakesta->wake_misc, wakesta->sw_flag0, wakesta->sw_flag1,
  91. wakesta->b_sw_flag0, wakesta->b_sw_flag1, wakesta->src_req);
  92. INFO("clk_settle = 0x%x, wlk_cntcv_l = 0x%x, wlk_cntcv_h = 0x%x\n",
  93. wakesta->clk_settle, mmio_read_32(SYS_TIMER_VALUE_L),
  94. mmio_read_32(SYS_TIMER_VALUE_H));
  95. if (wakesta->timer_out != 0U) {
  96. bk_vtcxo_dur = mmio_read_32(SPM_BK_VTCXO_DUR);
  97. spm_26m_off_pct = (100 * bk_vtcxo_dur) / wakesta->timer_out;
  98. INFO("spm_26m_off_pct = %u\n", spm_26m_off_pct);
  99. }
  100. }
  101. return wr;
  102. }
  103. void __spm_set_cpu_status(unsigned int cpu)
  104. {
  105. uint32_t root_core_addr;
  106. if (cpu < 8U) {
  107. mmio_write_32(ROOT_CPUTOP_ADDR, BIT(cpu));
  108. root_core_addr = SPM_CPU0_PWR_CON + (cpu * 0x4);
  109. root_core_addr += ROOT_CORE_ADDR_OFFSET;
  110. mmio_write_32(ROOT_CORE_ADDR, root_core_addr);
  111. /* Notify SSPM that preferred cpu wakeup */
  112. mmio_write_32(MCUPM_MBOX_WAKEUP_CPU, cpu);
  113. } else {
  114. ERROR("%s: error cpu number %d\n", __func__, cpu);
  115. }
  116. }
  117. void __spm_src_req_update(const struct pwr_ctrl *pwrctrl,
  118. unsigned int resource_usage)
  119. {
  120. uint8_t apsrc_req = ((resource_usage & MT_SPM_DRAM_S0) != 0U) ?
  121. 1 : pwrctrl->reg_spm_apsrc_req;
  122. uint8_t ddr_en_req = ((resource_usage & MT_SPM_DRAM_S1) != 0U) ?
  123. 1 : pwrctrl->reg_spm_ddren_req;
  124. uint8_t vrf18_req = ((resource_usage & MT_SPM_SYSPLL) != 0U) ?
  125. 1 : pwrctrl->reg_spm_vrf18_req;
  126. uint8_t infra_req = ((resource_usage & MT_SPM_INFRA) != 0U) ?
  127. 1 : pwrctrl->reg_spm_infra_req;
  128. uint8_t f26m_req = ((resource_usage & (MT_SPM_26M | MT_SPM_XO_FPM)) != 0U) ?
  129. 1 : pwrctrl->reg_spm_f26m_req;
  130. /*
  131. * if SPM_FLAG_SSPM_INFRA_SLEEP_MODE set,
  132. * clear sspm_srclkena_mask_b and sspm_infra_mask_b
  133. */
  134. uint8_t reg_sspm_srcclkena_mask_b =
  135. (pwrctrl->pcm_flags & SPM_FLAG_SSPM_INFRA_SLEEP_MODE)
  136. ? 0U : pwrctrl->reg_sspm_srcclkena_mask_b;
  137. uint8_t reg_sspm_infra_req_mask_b =
  138. (pwrctrl->pcm_flags & SPM_FLAG_SSPM_INFRA_SLEEP_MODE)
  139. ? 0 : pwrctrl->reg_sspm_infra_req_mask_b;
  140. /* SPM_SRC_REQ */
  141. mmio_write_32(SPM_SRC_REQ,
  142. ((apsrc_req & 0x1) << 0) |
  143. ((f26m_req & 0x1) << 1) |
  144. ((infra_req & 0x1) << 3) |
  145. ((vrf18_req & 0x1) << 4) |
  146. ((ddr_en_req & 0x1) << 7) |
  147. ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) |
  148. ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) |
  149. ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) |
  150. ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) |
  151. ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12));
  152. /* SPM_SRC_MASK */
  153. mmio_write_32(SPM_SRC_MASK,
  154. ((pwrctrl->reg_md_0_srcclkena_mask_b & 0x1) << 0) |
  155. ((pwrctrl->reg_md_0_infra_req_mask_b & 0x1) << 1) |
  156. ((pwrctrl->reg_md_0_apsrc_req_mask_b & 0x1) << 2) |
  157. ((pwrctrl->reg_md_0_vrf18_req_mask_b & 0x1) << 3) |
  158. ((pwrctrl->reg_md_0_ddren_req_mask_b & 0x1) << 4) |
  159. ((pwrctrl->reg_md_1_srcclkena_mask_b & 0x1) << 5) |
  160. ((pwrctrl->reg_md_1_infra_req_mask_b & 0x1) << 6) |
  161. ((pwrctrl->reg_md_1_apsrc_req_mask_b & 0x1) << 7) |
  162. ((pwrctrl->reg_md_1_vrf18_req_mask_b & 0x1) << 8) |
  163. ((pwrctrl->reg_md_1_ddren_req_mask_b & 0x1) << 9) |
  164. ((pwrctrl->reg_conn_srcclkena_mask_b & 0x1) << 10) |
  165. ((pwrctrl->reg_conn_srcclkenb_mask_b & 0x1) << 11) |
  166. ((pwrctrl->reg_conn_infra_req_mask_b & 0x1) << 12) |
  167. ((pwrctrl->reg_conn_apsrc_req_mask_b & 0x1) << 13) |
  168. ((pwrctrl->reg_conn_vrf18_req_mask_b & 0x1) << 14) |
  169. ((pwrctrl->reg_conn_ddren_req_mask_b & 0x1) << 15) |
  170. ((pwrctrl->reg_conn_vfe28_mask_b & 0x1) << 16) |
  171. ((pwrctrl->reg_srcclkeni_srcclkena_mask_b & 0x7) << 17) |
  172. ((pwrctrl->reg_srcclkeni_infra_req_mask_b & 0x7) << 20) |
  173. ((pwrctrl->reg_infrasys_apsrc_req_mask_b & 0x1) << 25) |
  174. ((pwrctrl->reg_infrasys_ddren_req_mask_b & 0x1) << 26) |
  175. ((reg_sspm_srcclkena_mask_b & 0x1) << 27) |
  176. ((reg_sspm_infra_req_mask_b & 0x1) << 28) |
  177. ((pwrctrl->reg_sspm_apsrc_req_mask_b & 0x1) << 29) |
  178. ((pwrctrl->reg_sspm_vrf18_req_mask_b & 0x1) << 30) |
  179. ((pwrctrl->reg_sspm_ddren_req_mask_b & 0x1) << 31));
  180. }
  181. void __spm_set_power_control(const struct pwr_ctrl *pwrctrl)
  182. {
  183. /* Auto-gen Start */
  184. /* SPM_AP_STANDBY_CON */
  185. mmio_write_32(SPM_AP_STANDBY_CON,
  186. ((pwrctrl->reg_wfi_op & 0x1) << 0) |
  187. ((pwrctrl->reg_wfi_type & 0x1) << 1) |
  188. ((pwrctrl->reg_mp0_cputop_idle_mask & 0x1) << 2) |
  189. ((pwrctrl->reg_mp1_cputop_idle_mask & 0x1) << 3) |
  190. ((pwrctrl->reg_mcusys_idle_mask & 0x1) << 4) |
  191. ((pwrctrl->reg_md_apsrc_1_sel & 0x1) << 25) |
  192. ((pwrctrl->reg_md_apsrc_0_sel & 0x1) << 26) |
  193. ((pwrctrl->reg_conn_apsrc_sel & 0x1) << 29));
  194. /* SPM_SRC6_MASK */
  195. mmio_write_32(SPM_SRC6_MASK,
  196. ((pwrctrl->reg_ccif_event_infra_req_mask_b & 0xffff) << 0) |
  197. ((pwrctrl->reg_ccif_event_apsrc_req_mask_b & 0xffff) << 16));
  198. /* SPM_SRC_REQ */
  199. mmio_write_32(SPM_SRC_REQ,
  200. ((pwrctrl->reg_spm_apsrc_req & 0x1) << 0) |
  201. ((pwrctrl->reg_spm_f26m_req & 0x1) << 1) |
  202. ((pwrctrl->reg_spm_infra_req & 0x1) << 3) |
  203. ((pwrctrl->reg_spm_vrf18_req & 0x1) << 4) |
  204. ((pwrctrl->reg_spm_ddren_req & 0x1) << 7) |
  205. ((pwrctrl->reg_spm_dvfs_req & 0x1) << 8) |
  206. ((pwrctrl->reg_spm_sw_mailbox_req & 0x1) << 9) |
  207. ((pwrctrl->reg_spm_sspm_mailbox_req & 0x1) << 10) |
  208. ((pwrctrl->reg_spm_adsp_mailbox_req & 0x1) << 11) |
  209. ((pwrctrl->reg_spm_scp_mailbox_req & 0x1) << 12));
  210. /* SPM_SRC_MASK */
  211. mmio_write_32(SPM_SRC_MASK,
  212. ((pwrctrl->reg_md_0_srcclkena_mask_b & 0x1) << 0) |
  213. ((pwrctrl->reg_md_0_infra_req_mask_b & 0x1) << 1) |
  214. ((pwrctrl->reg_md_0_apsrc_req_mask_b & 0x1) << 2) |
  215. ((pwrctrl->reg_md_0_vrf18_req_mask_b & 0x1) << 3) |
  216. ((pwrctrl->reg_md_0_ddren_req_mask_b & 0x1) << 4) |
  217. ((pwrctrl->reg_md_1_srcclkena_mask_b & 0x1) << 5) |
  218. ((pwrctrl->reg_md_1_infra_req_mask_b & 0x1) << 6) |
  219. ((pwrctrl->reg_md_1_apsrc_req_mask_b & 0x1) << 7) |
  220. ((pwrctrl->reg_md_1_vrf18_req_mask_b & 0x1) << 8) |
  221. ((pwrctrl->reg_md_1_ddren_req_mask_b & 0x1) << 9) |
  222. ((pwrctrl->reg_conn_srcclkena_mask_b & 0x1) << 10) |
  223. ((pwrctrl->reg_conn_srcclkenb_mask_b & 0x1) << 11) |
  224. ((pwrctrl->reg_conn_infra_req_mask_b & 0x1) << 12) |
  225. ((pwrctrl->reg_conn_apsrc_req_mask_b & 0x1) << 13) |
  226. ((pwrctrl->reg_conn_vrf18_req_mask_b & 0x1) << 14) |
  227. ((pwrctrl->reg_conn_ddren_req_mask_b & 0x1) << 15) |
  228. ((pwrctrl->reg_conn_vfe28_mask_b & 0x1) << 16) |
  229. ((pwrctrl->reg_srcclkeni_srcclkena_mask_b & 0x7) << 17) |
  230. ((pwrctrl->reg_srcclkeni_infra_req_mask_b & 0x7) << 20) |
  231. ((pwrctrl->reg_infrasys_apsrc_req_mask_b & 0x1) << 25) |
  232. ((pwrctrl->reg_infrasys_ddren_req_mask_b & 0x1) << 26) |
  233. ((pwrctrl->reg_sspm_srcclkena_mask_b & 0x1) << 27) |
  234. ((pwrctrl->reg_sspm_infra_req_mask_b & 0x1) << 28) |
  235. ((pwrctrl->reg_sspm_apsrc_req_mask_b & 0x1) << 29) |
  236. ((pwrctrl->reg_sspm_vrf18_req_mask_b & 0x1) << 30) |
  237. ((pwrctrl->reg_sspm_ddren_req_mask_b & 0x1) << 31));
  238. /* SPM_SRC2_MASK */
  239. mmio_write_32(SPM_SRC2_MASK,
  240. ((pwrctrl->reg_scp_srcclkena_mask_b & 0x1) << 0) |
  241. ((pwrctrl->reg_scp_infra_req_mask_b & 0x1) << 1) |
  242. ((pwrctrl->reg_scp_apsrc_req_mask_b & 0x1) << 2) |
  243. ((pwrctrl->reg_scp_vrf18_req_mask_b & 0x1) << 3) |
  244. ((pwrctrl->reg_scp_ddren_req_mask_b & 0x1) << 4) |
  245. ((pwrctrl->reg_audio_dsp_srcclkena_mask_b & 0x1) << 5) |
  246. ((pwrctrl->reg_audio_dsp_infra_req_mask_b & 0x1) << 6) |
  247. ((pwrctrl->reg_audio_dsp_apsrc_req_mask_b & 0x1) << 7) |
  248. ((pwrctrl->reg_audio_dsp_vrf18_req_mask_b & 0x1) << 8) |
  249. ((pwrctrl->reg_audio_dsp_ddren_req_mask_b & 0x1) << 9) |
  250. ((pwrctrl->reg_ufs_srcclkena_mask_b & 0x1) << 10) |
  251. ((pwrctrl->reg_ufs_infra_req_mask_b & 0x1) << 11) |
  252. ((pwrctrl->reg_ufs_apsrc_req_mask_b & 0x1) << 12) |
  253. ((pwrctrl->reg_ufs_vrf18_req_mask_b & 0x1) << 13) |
  254. ((pwrctrl->reg_ufs_ddren_req_mask_b & 0x1) << 14) |
  255. ((pwrctrl->reg_disp0_apsrc_req_mask_b & 0x1) << 15) |
  256. ((pwrctrl->reg_disp0_ddren_req_mask_b & 0x1) << 16) |
  257. ((pwrctrl->reg_disp1_apsrc_req_mask_b & 0x1) << 17) |
  258. ((pwrctrl->reg_disp1_ddren_req_mask_b & 0x1) << 18) |
  259. ((pwrctrl->reg_gce_infra_req_mask_b & 0x1) << 19) |
  260. ((pwrctrl->reg_gce_apsrc_req_mask_b & 0x1) << 20) |
  261. ((pwrctrl->reg_gce_vrf18_req_mask_b & 0x1) << 21) |
  262. ((pwrctrl->reg_gce_ddren_req_mask_b & 0x1) << 22) |
  263. ((pwrctrl->reg_apu_srcclkena_mask_b & 0x1) << 23) |
  264. ((pwrctrl->reg_apu_infra_req_mask_b & 0x1) << 24) |
  265. ((pwrctrl->reg_apu_apsrc_req_mask_b & 0x1) << 25) |
  266. ((pwrctrl->reg_apu_vrf18_req_mask_b & 0x1) << 26) |
  267. ((pwrctrl->reg_apu_ddren_req_mask_b & 0x1) << 27) |
  268. ((pwrctrl->reg_cg_check_srcclkena_mask_b & 0x1) << 28) |
  269. ((pwrctrl->reg_cg_check_apsrc_req_mask_b & 0x1) << 29) |
  270. ((pwrctrl->reg_cg_check_vrf18_req_mask_b & 0x1) << 30) |
  271. ((pwrctrl->reg_cg_check_ddren_req_mask_b & 0x1) << 31));
  272. /* SPM_SRC3_MASK */
  273. mmio_write_32(SPM_SRC3_MASK,
  274. ((pwrctrl->reg_dvfsrc_event_trigger_mask_b & 0x1) << 0) |
  275. ((pwrctrl->reg_sw2spm_wakeup_mask_b & 0xf) << 1) |
  276. ((pwrctrl->reg_adsp2spm_wakeup_mask_b & 0x1) << 5) |
  277. ((pwrctrl->reg_sspm2spm_wakeup_mask_b & 0xf) << 6) |
  278. ((pwrctrl->reg_scp2spm_wakeup_mask_b & 0x1) << 10) |
  279. ((pwrctrl->reg_csyspwrup_ack_mask & 0x1) << 11) |
  280. ((pwrctrl->reg_spm_reserved_srcclkena_mask_b & 0x1) << 12) |
  281. ((pwrctrl->reg_spm_reserved_infra_req_mask_b & 0x1) << 13) |
  282. ((pwrctrl->reg_spm_reserved_apsrc_req_mask_b & 0x1) << 14) |
  283. ((pwrctrl->reg_spm_reserved_vrf18_req_mask_b & 0x1) << 15) |
  284. ((pwrctrl->reg_spm_reserved_ddren_req_mask_b & 0x1) << 16) |
  285. ((pwrctrl->reg_mcupm_srcclkena_mask_b & 0x1) << 17) |
  286. ((pwrctrl->reg_mcupm_infra_req_mask_b & 0x1) << 18) |
  287. ((pwrctrl->reg_mcupm_apsrc_req_mask_b & 0x1) << 19) |
  288. ((pwrctrl->reg_mcupm_vrf18_req_mask_b & 0x1) << 20) |
  289. ((pwrctrl->reg_mcupm_ddren_req_mask_b & 0x1) << 21) |
  290. ((pwrctrl->reg_msdc0_srcclkena_mask_b & 0x1) << 22) |
  291. ((pwrctrl->reg_msdc0_infra_req_mask_b & 0x1) << 23) |
  292. ((pwrctrl->reg_msdc0_apsrc_req_mask_b & 0x1) << 24) |
  293. ((pwrctrl->reg_msdc0_vrf18_req_mask_b & 0x1) << 25) |
  294. ((pwrctrl->reg_msdc0_ddren_req_mask_b & 0x1) << 26) |
  295. ((pwrctrl->reg_msdc1_srcclkena_mask_b & 0x1) << 27) |
  296. ((pwrctrl->reg_msdc1_infra_req_mask_b & 0x1) << 28) |
  297. ((pwrctrl->reg_msdc1_apsrc_req_mask_b & 0x1) << 29) |
  298. ((pwrctrl->reg_msdc1_vrf18_req_mask_b & 0x1) << 30) |
  299. ((pwrctrl->reg_msdc1_ddren_req_mask_b & 0x1) << 31));
  300. /* SPM_SRC4_MASK */
  301. mmio_write_32(SPM_SRC4_MASK,
  302. ((pwrctrl->reg_ccif_event_srcclkena_mask_b & 0xffff) << 0) |
  303. ((pwrctrl->reg_bak_psri_srcclkena_mask_b & 0x1) << 16) |
  304. ((pwrctrl->reg_bak_psri_infra_req_mask_b & 0x1) << 17) |
  305. ((pwrctrl->reg_bak_psri_apsrc_req_mask_b & 0x1) << 18) |
  306. ((pwrctrl->reg_bak_psri_vrf18_req_mask_b & 0x1) << 19) |
  307. ((pwrctrl->reg_bak_psri_ddren_req_mask_b & 0x1) << 20) |
  308. ((pwrctrl->reg_dramc_md32_infra_req_mask_b & 0x3) << 21) |
  309. ((pwrctrl->reg_dramc_md32_vrf18_req_mask_b & 0x3) << 23) |
  310. ((pwrctrl->reg_conn_srcclkenb2pwrap_mask_b & 0x1) << 25) |
  311. ((pwrctrl->reg_dramc_md32_apsrc_req_mask_b & 0x3) << 26));
  312. /* SPM_SRC5_MASK */
  313. mmio_write_32(SPM_SRC5_MASK,
  314. ((pwrctrl->reg_mcusys_merge_apsrc_req_mask_b & 0x1ff) << 0) |
  315. ((pwrctrl->reg_mcusys_merge_ddren_req_mask_b & 0x1ff) << 9) |
  316. ((pwrctrl->reg_afe_srcclkena_mask_b & 0x1) << 18) |
  317. ((pwrctrl->reg_afe_infra_req_mask_b & 0x1) << 19) |
  318. ((pwrctrl->reg_afe_apsrc_req_mask_b & 0x1) << 20) |
  319. ((pwrctrl->reg_afe_vrf18_req_mask_b & 0x1) << 21) |
  320. ((pwrctrl->reg_afe_ddren_req_mask_b & 0x1) << 22) |
  321. ((pwrctrl->reg_msdc2_srcclkena_mask_b & 0x1) << 23) |
  322. ((pwrctrl->reg_msdc2_infra_req_mask_b & 0x1) << 24) |
  323. ((pwrctrl->reg_msdc2_apsrc_req_mask_b & 0x1) << 25) |
  324. ((pwrctrl->reg_msdc2_vrf18_req_mask_b & 0x1) << 26) |
  325. ((pwrctrl->reg_msdc2_ddren_req_mask_b & 0x1) << 27));
  326. /* SPM_WAKEUP_EVENT_MASK */
  327. mmio_write_32(SPM_WAKEUP_EVENT_MASK,
  328. ((pwrctrl->reg_wakeup_event_mask & 0xffffffff) << 0));
  329. /* SPM_WAKEUP_EVENT_EXT_MASK */
  330. mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK,
  331. ((pwrctrl->reg_ext_wakeup_event_mask & 0xffffffff) << 0));
  332. /* SPM_SRC7_MASK */
  333. mmio_write_32(SPM_SRC7_MASK,
  334. ((pwrctrl->reg_pcie_srcclkena_mask_b & 0x1) << 0) |
  335. ((pwrctrl->reg_pcie_infra_req_mask_b & 0x1) << 1) |
  336. ((pwrctrl->reg_pcie_apsrc_req_mask_b & 0x1) << 2) |
  337. ((pwrctrl->reg_pcie_vrf18_req_mask_b & 0x1) << 3) |
  338. ((pwrctrl->reg_pcie_ddren_req_mask_b & 0x1) << 4) |
  339. ((pwrctrl->reg_dpmaif_srcclkena_mask_b & 0x1) << 5) |
  340. ((pwrctrl->reg_dpmaif_infra_req_mask_b & 0x1) << 6) |
  341. ((pwrctrl->reg_dpmaif_apsrc_req_mask_b & 0x1) << 7) |
  342. ((pwrctrl->reg_dpmaif_vrf18_req_mask_b & 0x1) << 8) |
  343. ((pwrctrl->reg_dpmaif_ddren_req_mask_b & 0x1) << 9));
  344. /* Auto-gen End */
  345. }
  346. void __spm_disable_pcm_timer(void)
  347. {
  348. mmio_clrsetbits_32(PCM_CON1, RG_PCM_TIMER_EN_LSB, SPM_REGWR_CFG_KEY);
  349. }
  350. void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl)
  351. {
  352. uint32_t val, mask;
  353. /* toggle event counter clear */
  354. mmio_setbits_32(PCM_CON1,
  355. SPM_REGWR_CFG_KEY | REG_SPM_EVENT_COUNTER_CLR_LSB);
  356. /* toggle for reset SYS TIMER start point */
  357. mmio_setbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB);
  358. if (pwrctrl->timer_val_cust == 0U) {
  359. val = pwrctrl->timer_val ? (pwrctrl->timer_val) : (PCM_TIMER_MAX);
  360. } else {
  361. val = pwrctrl->timer_val_cust;
  362. }
  363. mmio_write_32(PCM_TIMER_VAL, val);
  364. mmio_setbits_32(PCM_CON1, (SPM_REGWR_CFG_KEY | RG_PCM_TIMER_EN_LSB));
  365. /* unmask AP wakeup source */
  366. if (pwrctrl->wake_src_cust == 0U) {
  367. mask = pwrctrl->wake_src;
  368. } else {
  369. mask = pwrctrl->wake_src_cust;
  370. }
  371. if (pwrctrl->reg_csyspwrup_ack_mask != 0U) {
  372. mask &= ~R12_CSYSPWREQ_B;
  373. }
  374. mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask);
  375. /* unmask SPM ISR (keep TWAM setting) */
  376. mmio_setbits_32(SPM_IRQ_MASK, ISRM_RET_IRQ_AUX);
  377. /* toggle event counter clear */
  378. mmio_clrsetbits_32(PCM_CON1, REG_SPM_EVENT_COUNTER_CLR_LSB,
  379. SPM_REGWR_CFG_KEY);
  380. /* toggle for reset SYS TIMER start point */
  381. mmio_clrbits_32(SYS_TIMER_CON, SYS_TIMER_START_EN_LSB);
  382. }
  383. void __spm_set_pcm_flags(struct pwr_ctrl *pwrctrl)
  384. {
  385. /* set PCM flags and data */
  386. if (pwrctrl->pcm_flags_cust_clr != 0U) {
  387. pwrctrl->pcm_flags &= ~pwrctrl->pcm_flags_cust_clr;
  388. }
  389. if (pwrctrl->pcm_flags_cust_set != 0U) {
  390. pwrctrl->pcm_flags |= pwrctrl->pcm_flags_cust_set;
  391. }
  392. if (pwrctrl->pcm_flags1_cust_clr != 0U) {
  393. pwrctrl->pcm_flags1 &= ~pwrctrl->pcm_flags1_cust_clr;
  394. }
  395. if (pwrctrl->pcm_flags1_cust_set != 0U) {
  396. pwrctrl->pcm_flags1 |= pwrctrl->pcm_flags1_cust_set;
  397. }
  398. mmio_write_32(SPM_SW_FLAG_0, pwrctrl->pcm_flags);
  399. mmio_write_32(SPM_SW_FLAG_1, pwrctrl->pcm_flags1);
  400. mmio_write_32(SPM_SW_RSV_7, pwrctrl->pcm_flags);
  401. mmio_write_32(SPM_SW_RSV_8, pwrctrl->pcm_flags1);
  402. }
  403. void __spm_get_wakeup_status(struct wake_status *wakesta,
  404. unsigned int ext_status)
  405. {
  406. wakesta->tr.comm.r12 = mmio_read_32(SPM_BK_WAKE_EVENT);
  407. wakesta->tr.comm.timer_out = mmio_read_32(SPM_BK_PCM_TIMER);
  408. wakesta->tr.comm.r13 = mmio_read_32(PCM_REG13_DATA);
  409. wakesta->tr.comm.req_sta0 = mmio_read_32(SRC_REQ_STA_0);
  410. wakesta->tr.comm.req_sta1 = mmio_read_32(SRC_REQ_STA_1);
  411. wakesta->tr.comm.req_sta2 = mmio_read_32(SRC_REQ_STA_2);
  412. wakesta->tr.comm.req_sta3 = mmio_read_32(SRC_REQ_STA_3);
  413. wakesta->tr.comm.req_sta4 = mmio_read_32(SRC_REQ_STA_4);
  414. wakesta->tr.comm.debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0);
  415. wakesta->tr.comm.debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1);
  416. if ((ext_status & SPM_INTERNAL_STATUS_HW_S1) != 0U) {
  417. wakesta->tr.comm.debug_flag |= (SPM_DBG_DEBUG_IDX_DDREN_WAKE |
  418. SPM_DBG_DEBUG_IDX_DDREN_SLEEP);
  419. mmio_write_32(PCM_WDT_LATCH_SPARE_0, wakesta->tr.comm.debug_flag);
  420. }
  421. wakesta->tr.comm.b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);
  422. wakesta->tr.comm.b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);
  423. /* record below spm info for debug */
  424. wakesta->r12 = mmio_read_32(SPM_BK_WAKE_EVENT);
  425. wakesta->r12_ext = mmio_read_32(SPM_WAKEUP_STA);
  426. wakesta->raw_sta = mmio_read_32(SPM_WAKEUP_STA);
  427. wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA);
  428. wakesta->md32pcm_wakeup_sta = mmio_read_32(MD32PCM_WAKEUP_STA);
  429. wakesta->md32pcm_event_sta = mmio_read_32(MD32PCM_EVENT_STA);
  430. wakesta->src_req = mmio_read_32(SPM_SRC_REQ);
  431. /* backup of SPM_WAKEUP_MISC */
  432. wakesta->wake_misc = mmio_read_32(SPM_BK_WAKE_MISC);
  433. /* get sleep time, backup of PCM_TIMER_OUT */
  434. wakesta->timer_out = mmio_read_32(SPM_BK_PCM_TIMER);
  435. /* get other SYS and co-clock status */
  436. wakesta->r13 = mmio_read_32(PCM_REG13_DATA);
  437. wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA);
  438. wakesta->req_sta0 = mmio_read_32(SRC_REQ_STA_0);
  439. wakesta->req_sta1 = mmio_read_32(SRC_REQ_STA_1);
  440. wakesta->req_sta2 = mmio_read_32(SRC_REQ_STA_2);
  441. wakesta->req_sta3 = mmio_read_32(SRC_REQ_STA_3);
  442. wakesta->req_sta4 = mmio_read_32(SRC_REQ_STA_4);
  443. /* get HW CG check status */
  444. wakesta->cg_check_sta = mmio_read_32(SPM_CG_CHECK_STA);
  445. /* get debug flag for PCM execution check */
  446. wakesta->debug_flag = mmio_read_32(PCM_WDT_LATCH_SPARE_0);
  447. wakesta->debug_flag1 = mmio_read_32(PCM_WDT_LATCH_SPARE_1);
  448. /* get backup SW flag status */
  449. wakesta->b_sw_flag0 = mmio_read_32(SPM_SW_RSV_7);
  450. wakesta->b_sw_flag1 = mmio_read_32(SPM_SW_RSV_8);
  451. wakesta->rt_req_sta0 = mmio_read_32(SPM_SW_RSV_2);
  452. wakesta->rt_req_sta1 = mmio_read_32(SPM_SW_RSV_3);
  453. wakesta->rt_req_sta2 = mmio_read_32(SPM_SW_RSV_4);
  454. wakesta->rt_req_sta3 = mmio_read_32(SPM_SW_RSV_5);
  455. wakesta->rt_req_sta4 = mmio_read_32(SPM_SW_RSV_6);
  456. /* get ISR status */
  457. wakesta->isr = mmio_read_32(SPM_IRQ_STA);
  458. /* get SW flag status */
  459. wakesta->sw_flag0 = mmio_read_32(SPM_SW_FLAG_0);
  460. wakesta->sw_flag1 = mmio_read_32(SPM_SW_FLAG_1);
  461. /* get CLK SETTLE */
  462. wakesta->clk_settle = mmio_read_32(SPM_CLK_SETTLE);
  463. /* check abort */
  464. wakesta->abort = ((wakesta->debug_flag & DEBUG_ABORT_MASK) |
  465. (wakesta->debug_flag1 & DEBUG_ABORT_MASK_1));
  466. }
  467. void __spm_clean_after_wakeup(void)
  468. {
  469. mmio_write_32(SPM_BK_WAKE_EVENT,
  470. (mmio_read_32(SPM_WAKEUP_STA) |
  471. mmio_read_32(SPM_BK_WAKE_EVENT)));
  472. mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0U);
  473. /*
  474. * clean wakeup event raw status (for edge trigger event)
  475. * bit[28] for cpu wake up event
  476. */
  477. mmio_write_32(SPM_WAKEUP_EVENT_MASK, SPM_WAKEUP_EVENT_MASK_CLEAN_MASK);
  478. /* clean ISR status (except TWAM) */
  479. mmio_setbits_32(SPM_IRQ_MASK, ISRM_ALL_EXC_TWAM);
  480. mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM);
  481. mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL);
  482. }
  483. void __spm_set_pcm_wdt(int en)
  484. {
  485. mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_EN_LSB,
  486. SPM_REGWR_CFG_KEY);
  487. if (en == 1) {
  488. mmio_clrsetbits_32(PCM_CON1, RG_PCM_WDT_WAKE_LSB,
  489. SPM_REGWR_CFG_KEY);
  490. if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX) {
  491. mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX);
  492. }
  493. mmio_write_32(PCM_WDT_VAL,
  494. mmio_read_32(PCM_TIMER_VAL) + PCM_WDT_TIMEOUT);
  495. mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | RG_PCM_WDT_EN_LSB);
  496. }
  497. }
  498. void __spm_send_cpu_wakeup_event(void)
  499. {
  500. /* SPM will clear SPM_CPU_WAKEUP_EVENT */
  501. mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1);
  502. }
  503. void __spm_ext_int_wakeup_req_clr(void)
  504. {
  505. unsigned int reg = mmio_read_32(SPM_MD32_IRQ) & (~(0x1U << 0));
  506. mmio_write_32(EXT_INT_WAKEUP_REQ_CLR, mmio_read_32(ROOT_CPUTOP_ADDR));
  507. /* Clear spm2mcupm wakeup interrupt status */
  508. mmio_write_32(SPM_MD32_IRQ, reg);
  509. }
  510. void __spm_xo_soc_bblpm(int en)
  511. {
  512. if (en == 1) {
  513. mmio_clrsetbits_32(RC_M00_SRCLKEN_CFG,
  514. RC_SW_SRCCLKEN_FPM, RC_SW_SRCCLKEN_RC);
  515. assert(mt_spm_bblpm_cnt == 0);
  516. mt_spm_bblpm_cnt += 1;
  517. } else {
  518. mmio_clrsetbits_32(RC_M00_SRCLKEN_CFG,
  519. RC_SW_SRCCLKEN_RC, RC_SW_SRCCLKEN_FPM);
  520. mt_spm_bblpm_cnt -= 1;
  521. }
  522. }
  523. void __spm_hw_s1_state_monitor(int en, unsigned int *status)
  524. {
  525. unsigned int reg = mmio_read_32(SPM_ACK_CHK_CON_3);
  526. if (en == 1) {
  527. reg = mmio_read_32(SPM_ACK_CHK_CON_3);
  528. reg &= ~SPM_ACK_CHK_3_CON_CLR_ALL;
  529. mmio_write_32(SPM_ACK_CHK_CON_3, reg);
  530. reg |= SPM_ACK_CHK_3_CON_EN;
  531. mmio_write_32(SPM_ACK_CHK_CON_3, reg);
  532. } else {
  533. if (((reg & SPM_ACK_CHK_3_CON_RESULT) != 0U) &&
  534. (status != NULL)) {
  535. *status |= SPM_INTERNAL_STATUS_HW_S1;
  536. }
  537. mmio_clrsetbits_32(SPM_ACK_CHK_CON_3, SPM_ACK_CHK_3_CON_EN,
  538. SPM_ACK_CHK_3_CON_HW_MODE_TRIG |
  539. SPM_ACK_CHK_3_CON_CLR_ALL);
  540. }
  541. }