mt_spm_internal.c 21 KB

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