xref: /arm-trusted-firmware/plat/mediatek/drivers/spm/mt8188/mt_spm.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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