/* * Copyright (c) 2023, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include #include #include #include #include #include "constraints/mt_spm_rc_internal.h" #include #include #include #include #include #include #include "mt_spm.h" #include "mt_spm_cond.h" #include "mt_spm_conservation.h" #include "mt_spm_constraint.h" #include "mt_spm_idle.h" #include "mt_spm_internal.h" #include "mt_spm_pmic_wrap.h" #include "mt_spm_reg.h" #include "mt_spm_suspend.h" #include #include #include "sleep_def.h" /* * System Power Manager (SPM) is a hardware module which provides CPU idle * and system suspend features. */ spinlock_t spm_lock; #ifdef MTK_PLAT_SPM_UNSUPPORT struct mt_resource_manager plat_mt8188_rm = { }; #else struct mt_lp_res_req rq_xo_fpm = { .res_id = MT_LP_RQ_XO_FPM, .res_rq = MT_SPM_XO_FPM, .res_usage = 0, }; struct mt_lp_res_req rq_26m = { .res_id = MT_LP_RQ_26M, .res_rq = MT_SPM_26M, .res_usage = 0, }; struct mt_lp_res_req rq_infra = { .res_id = MT_LP_RQ_INFRA, .res_rq = MT_SPM_INFRA, .res_usage = 0, }; struct mt_lp_res_req rq_syspll = { .res_id = MT_LP_RQ_SYSPLL, .res_rq = MT_SPM_SYSPLL, .res_usage = 0, }; struct mt_lp_res_req rq_dram_s0 = { .res_id = MT_LP_RQ_DRAM, .res_rq = MT_SPM_DRAM_S0, .res_usage = 0, }; struct mt_lp_res_req rq_dram_s1 = { .res_id = MT_LP_RQ_DRAM, .res_rq = MT_SPM_DRAM_S1, .res_usage = 0, }; struct mt_lp_res_req *spm_resources[] = { &rq_xo_fpm, &rq_26m, &rq_infra, &rq_syspll, &rq_dram_s0, &rq_dram_s1, NULL, }; struct mt_resource_req_manager plat_mt8188_rq = { .res = spm_resources, }; struct mt_resource_constraint plat_constraint_bus26m = { .is_valid = spm_is_valid_rc_bus26m, .update = spm_update_rc_bus26m, .allow = spm_allow_rc_bus26m, .run = spm_run_rc_bus26m, .reset = spm_reset_rc_bus26m, .get_status = spm_get_status_rc_bus26m, }; struct mt_resource_constraint plat_constraint_syspll = { .is_valid = spm_is_valid_rc_syspll, .update = spm_update_rc_syspll, .allow = spm_allow_rc_syspll, .run = spm_run_rc_syspll, .reset = spm_reset_rc_syspll, .get_status = spm_get_status_rc_syspll, }; struct mt_resource_constraint plat_constraint_dram = { .is_valid = spm_is_valid_rc_dram, .update = spm_update_rc_dram, .allow = spm_allow_rc_dram, .run = spm_run_rc_dram, .reset = spm_reset_rc_dram, .get_status = spm_get_status_rc_dram, }; struct mt_resource_constraint plat_constraint_cpu = { .is_valid = spm_is_valid_rc_cpu_buck_ldo, .update = spm_update_rc_cpu_buck_ldo, .allow = spm_allow_rc_cpu_buck_ldo, .run = spm_run_rc_cpu_buck_ldo, .reset = spm_reset_rc_cpu_buck_ldo, .get_status = spm_get_status_rc_cpu_buck_ldo, }; struct mt_resource_constraint *plat_constraints[] = { &plat_constraint_bus26m, &plat_constraint_syspll, &plat_constraint_dram, &plat_constraint_cpu, NULL, }; struct mt_resource_manager plat_mt8188_rm = { .update = mt_spm_cond_update, .consts = plat_constraints, }; #endif /* Determine for SPM software resource user */ static struct mt_lp_resource_user spm_res_user; struct mt_lp_resource_user *get_spm_res_user(void) { return &spm_res_user; } int spm_boot_init(void) { mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE); mt_lp_rm_register(&plat_mt8188_rm); /* SPM service won't run when SPM not ready */ #ifndef MTK_PLAT_SPM_UNSUPPORT mt_lp_resource_request_manager_register(&plat_mt8188_rq); mt_lp_resource_user_register("SPM", &spm_res_user); #endif return 0; } MTK_ARCH_INIT(spm_boot_init);