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