xref: /rk3399_ARM-atf/plat/mediatek/drivers/spm/mt8188/mt_spm.c (revision 79c262327aa8ccc1ae5a0ee7f7ead3bf5ce8e022)
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 
get_spm_res_user(void)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 
spm_boot_init(void)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