1 /* 2 * Copyright (c) 2023, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <stddef.h> 9 #include <stdio.h> 10 #include <string.h> 11 12 #include <arch.h> 13 #include <common/debug.h> 14 #include <drivers/console.h> 15 #include <lib/mmio.h> 16 #include <lib/utils_def.h> 17 18 #include "constraints/mt_spm_rc_internal.h" 19 #include <drivers/spm/mt_spm_resource_req.h> 20 #include <lib/mtk_init/mtk_init.h> 21 #include <lib/pm/mtk_pm.h> 22 #include <lpm/mt_lp_rm.h> 23 #include <lpm/mt_lp_rqm.h> 24 #include <lpm/mt_lpm_smc.h> 25 #include "mt_spm.h" 26 #include "mt_spm_cond.h" 27 #include "mt_spm_conservation.h" 28 #include "mt_spm_constraint.h" 29 #include "mt_spm_idle.h" 30 #include "mt_spm_internal.h" 31 #include "mt_spm_pmic_wrap.h" 32 #include "mt_spm_reg.h" 33 #include "mt_spm_suspend.h" 34 #include <mtk_mmap_pool.h> 35 #include <platform_def.h> 36 #include "sleep_def.h" 37 38 /* 39 * System Power Manager (SPM) is a hardware module which provides CPU idle 40 * and system suspend features. 41 */ 42 43 spinlock_t spm_lock; 44 45 #ifdef MTK_PLAT_SPM_UNSUPPORT 46 struct mt_resource_manager plat_mt8188_rm = { 47 }; 48 #else 49 struct mt_lp_res_req rq_xo_fpm = { 50 .res_id = MT_LP_RQ_XO_FPM, 51 .res_rq = MT_SPM_XO_FPM, 52 .res_usage = 0, 53 }; 54 55 struct mt_lp_res_req rq_26m = { 56 .res_id = MT_LP_RQ_26M, 57 .res_rq = MT_SPM_26M, 58 .res_usage = 0, 59 }; 60 61 struct mt_lp_res_req rq_infra = { 62 .res_id = MT_LP_RQ_INFRA, 63 .res_rq = MT_SPM_INFRA, 64 .res_usage = 0, 65 }; 66 67 struct mt_lp_res_req rq_syspll = { 68 .res_id = MT_LP_RQ_SYSPLL, 69 .res_rq = MT_SPM_SYSPLL, 70 .res_usage = 0, 71 }; 72 73 struct mt_lp_res_req rq_dram_s0 = { 74 .res_id = MT_LP_RQ_DRAM, 75 .res_rq = MT_SPM_DRAM_S0, 76 .res_usage = 0, 77 }; 78 79 struct mt_lp_res_req rq_dram_s1 = { 80 .res_id = MT_LP_RQ_DRAM, 81 .res_rq = MT_SPM_DRAM_S1, 82 .res_usage = 0, 83 }; 84 85 struct mt_lp_res_req *spm_resources[] = { 86 &rq_xo_fpm, 87 &rq_26m, 88 &rq_infra, 89 &rq_syspll, 90 &rq_dram_s0, 91 &rq_dram_s1, 92 NULL, 93 }; 94 95 struct mt_resource_req_manager plat_mt8188_rq = { 96 .res = spm_resources, 97 }; 98 99 struct mt_resource_constraint plat_constraint_bus26m = { 100 .is_valid = spm_is_valid_rc_bus26m, 101 .update = spm_update_rc_bus26m, 102 .allow = spm_allow_rc_bus26m, 103 .run = spm_run_rc_bus26m, 104 .reset = spm_reset_rc_bus26m, 105 .get_status = spm_get_status_rc_bus26m, 106 }; 107 108 struct mt_resource_constraint plat_constraint_syspll = { 109 .is_valid = spm_is_valid_rc_syspll, 110 .update = spm_update_rc_syspll, 111 .allow = spm_allow_rc_syspll, 112 .run = spm_run_rc_syspll, 113 .reset = spm_reset_rc_syspll, 114 .get_status = spm_get_status_rc_syspll, 115 }; 116 117 struct mt_resource_constraint plat_constraint_dram = { 118 .is_valid = spm_is_valid_rc_dram, 119 .update = spm_update_rc_dram, 120 .allow = spm_allow_rc_dram, 121 .run = spm_run_rc_dram, 122 .reset = spm_reset_rc_dram, 123 .get_status = spm_get_status_rc_dram, 124 }; 125 126 struct mt_resource_constraint plat_constraint_cpu = { 127 .is_valid = spm_is_valid_rc_cpu_buck_ldo, 128 .update = spm_update_rc_cpu_buck_ldo, 129 .allow = spm_allow_rc_cpu_buck_ldo, 130 .run = spm_run_rc_cpu_buck_ldo, 131 .reset = spm_reset_rc_cpu_buck_ldo, 132 .get_status = spm_get_status_rc_cpu_buck_ldo, 133 }; 134 135 struct mt_resource_constraint *plat_constraints[] = { 136 &plat_constraint_bus26m, 137 &plat_constraint_syspll, 138 &plat_constraint_dram, 139 &plat_constraint_cpu, 140 NULL, 141 }; 142 143 struct mt_resource_manager plat_mt8188_rm = { 144 .update = mt_spm_cond_update, 145 .consts = plat_constraints, 146 }; 147 #endif 148 149 /* Determine for SPM software resource user */ 150 static struct mt_lp_resource_user spm_res_user; 151 152 struct mt_lp_resource_user *get_spm_res_user(void) 153 { 154 return &spm_res_user; 155 } 156 157 int spm_boot_init(void) 158 { 159 mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE); 160 mt_lp_rm_register(&plat_mt8188_rm); 161 162 /* SPM service won't run when SPM not ready */ 163 #ifndef MTK_PLAT_SPM_UNSUPPORT 164 mt_lp_resource_request_manager_register(&plat_mt8188_rq); 165 mt_lp_resource_user_register("SPM", &spm_res_user); 166 #endif 167 168 return 0; 169 } 170 MTK_ARCH_INIT(spm_boot_init); 171