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