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