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