mt_spm_conservation.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * Copyright (c) 2022, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <common/debug.h>
  7. #include <lib/mmio.h>
  8. #include <plat/common/platform.h>
  9. #include <mt_spm.h>
  10. #include <mt_spm_conservation.h>
  11. #include <mt_spm_internal.h>
  12. #include <mt_spm_reg.h>
  13. #include <mt_spm_resource_req.h>
  14. #include <mt_spm_vcorefs.h>
  15. #include <plat_mtk_lpm.h>
  16. #include <plat_pm.h>
  17. #include <platform_def.h>
  18. #define MT_RESUMETIME_THRESHOLD_MAX (5U) /*ms*/
  19. #define IS_RESUME_OVERTIME(delta) (delta > MT_RESUMETIME_THRESHOLD_MAX)
  20. static struct wake_status spm_wakesta; /* record last wakesta */
  21. static int go_to_spm_before_wfi(int state_id, unsigned int ext_opand,
  22. struct spm_lp_scen *spm_lp,
  23. unsigned int resource_req)
  24. {
  25. int ret = 0;
  26. struct pwr_ctrl *pwrctrl;
  27. uint32_t cpu = plat_my_core_pos();
  28. pwrctrl = spm_lp->pwrctrl;
  29. __spm_set_cpu_status(cpu);
  30. __spm_set_power_control(pwrctrl);
  31. __spm_set_wakeup_event(pwrctrl);
  32. __spm_sync_vcore_dvfs_power_control(pwrctrl, __spm_vcorefs.pwrctrl);
  33. __spm_set_pcm_flags(pwrctrl);
  34. __spm_src_req_update(pwrctrl, resource_req);
  35. if ((ext_opand & MT_SPM_EX_OP_SET_WDT) != 0U) {
  36. __spm_set_pcm_wdt(1);
  37. }
  38. if ((ext_opand & MT_SPM_EX_OP_SRCLKEN_RC_BBLPM) != 0U) {
  39. __spm_xo_soc_bblpm(1);
  40. }
  41. if ((ext_opand & MT_SPM_EX_OP_HW_S1_DETECT) != 0U) {
  42. spm_hw_s1_state_monitor_resume();
  43. }
  44. /* Disable auto resume by PCM in system suspend stage */
  45. if (IS_PLAT_SUSPEND_ID(state_id)) {
  46. __spm_disable_pcm_timer();
  47. __spm_set_pcm_wdt(0);
  48. }
  49. __spm_send_cpu_wakeup_event();
  50. INFO("cpu%d: wakesrc = 0x%x, settle = 0x%x, sec = %u\n",
  51. cpu, pwrctrl->wake_src, mmio_read_32(SPM_CLK_SETTLE),
  52. (mmio_read_32(PCM_TIMER_VAL) / 32768));
  53. INFO("sw_flag = 0x%x 0x%x, req = 0x%x, pwr = 0x%x 0x%x\n",
  54. pwrctrl->pcm_flags, pwrctrl->pcm_flags1,
  55. mmio_read_32(SPM_SRC_REQ), mmio_read_32(PWR_STATUS),
  56. mmio_read_32(PWR_STATUS_2ND));
  57. return ret;
  58. }
  59. static void go_to_spm_after_wfi(int state_id, unsigned int ext_opand,
  60. struct spm_lp_scen *spm_lp,
  61. struct wake_status **status)
  62. {
  63. unsigned int ext_status = 0U;
  64. spm_wakesta.tr.comm.resumetime = 0;
  65. spm_wakesta.tr.comm.times_h = spm_wakesta.tr.comm.times_l = 0;
  66. /* system watchdog will be resumed at kernel stage */
  67. if ((ext_opand & MT_SPM_EX_OP_SET_WDT) != 0U) {
  68. __spm_set_pcm_wdt(0);
  69. }
  70. if ((ext_opand & MT_SPM_EX_OP_SRCLKEN_RC_BBLPM) != 0U) {
  71. __spm_xo_soc_bblpm(0);
  72. }
  73. if ((ext_opand & MT_SPM_EX_OP_HW_S1_DETECT) != 0U) {
  74. spm_hw_s1_state_monitor_pause(&ext_status);
  75. }
  76. __spm_ext_int_wakeup_req_clr();
  77. __spm_get_wakeup_status(&spm_wakesta, ext_status);
  78. if (status != NULL) {
  79. *status = &spm_wakesta;
  80. }
  81. __spm_clean_after_wakeup();
  82. if (IS_PLAT_SUSPEND_ID(state_id)) {
  83. __spm_output_wake_reason(state_id, &spm_wakesta);
  84. }
  85. }
  86. int spm_conservation(int state_id, unsigned int ext_opand,
  87. struct spm_lp_scen *spm_lp, unsigned int resource_req)
  88. {
  89. int ret = 0;
  90. if (spm_lp == NULL) {
  91. ret = -1;
  92. } else {
  93. spm_lock_get();
  94. go_to_spm_before_wfi(state_id, ext_opand, spm_lp, resource_req);
  95. spm_lock_release();
  96. }
  97. return ret;
  98. }
  99. void spm_conservation_finish(int state_id, unsigned int ext_opand,
  100. struct spm_lp_scen *spm_lp,
  101. struct wake_status **status)
  102. {
  103. spm_lock_get();
  104. go_to_spm_after_wfi(state_id, ext_opand, spm_lp, status);
  105. spm_lock_release();
  106. }
  107. int spm_conservation_get_result(struct wake_status **res)
  108. {
  109. int ret = 0;
  110. if (res == NULL) {
  111. ret = -1;
  112. } else {
  113. *res = &spm_wakesta;
  114. }
  115. return ret;
  116. }
  117. #define GPIO_BANK (GPIO_BASE + 0x6F0)
  118. #define TRAP_UFS_FIRST BIT(11) /* bit 11, 0: UFS, 1: eMMC */
  119. void spm_conservation_pwrctrl_init(struct pwr_ctrl *pwrctrl)
  120. {
  121. if (pwrctrl != NULL) {
  122. /* For ufs, emmc storage type */
  123. if ((mmio_read_32(GPIO_BANK) & TRAP_UFS_FIRST) != 0U) {
  124. /* If eMMC is used, mask UFS req */
  125. pwrctrl->reg_ufs_srcclkena_mask_b = 0;
  126. pwrctrl->reg_ufs_infra_req_mask_b = 0;
  127. pwrctrl->reg_ufs_apsrc_req_mask_b = 0;
  128. pwrctrl->reg_ufs_vrf18_req_mask_b = 0;
  129. pwrctrl->reg_ufs_ddren_req_mask_b = 0;
  130. }
  131. }
  132. }