blob: fb51e69ccc81397bc6ec5cc7a46e01ce32ecb6e7 [file] [log] [blame]
jason-ch chena07e3ea2021-11-16 10:18:46 +08001/*
2 * Copyright(C)2022, MediaTek Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stddef.h>
8#include <stdio.h>
9#include <string.h>
10#include <arch_helpers.h>
11#include <common/debug.h>
12#include <drivers/delay_timer.h>
13#include <lib/mmio.h>
14#include <lib/utils_def.h>
15#include <plat/common/platform.h>
16#include <mt_spm.h>
17#include <mt_spm_internal.h>
18#include <mt_spm_pmic_wrap.h>
19#include <mt_spm_reg.h>
20#include <mt_spm_vcorefs.h>
21#include <mtk_sip_svc.h>
22#include <plat_pm.h>
23#include <platform_def.h>
24#include <pmic.h>
25
26#define VCORE_CT_ENABLE BIT(5)
27#define VCORE_DRM_ENABLE BIT(31)
28#define VCORE_PTPOD_SHIFT (8)
29#define VCORE_POWER_SHIFT (2)
30
31#define VCORE_MAX_OPP (3)
32#define DRAM_MAX_OPP (6)
33
34#define SW_REQ5_INIT_VAL (6U << 12)
35#define V_VMODE_SHIFT (0)
36#define VCORE_HV (105)
37#define VCORE_LV (95)
38#define PMIC_STEP_UV (6250)
39
40static int vcore_opp_0_uv = 800000;
41static int vcore_opp_1_uv = 700000;
42static int vcore_opp_2_uv = 650000;
43
44static struct pwr_ctrl vcorefs_ctrl = {
45 .wake_src = R12_REG_CPU_WAKEUP,
46
47 /* default VCORE DVFS is disabled */
48 .pcm_flags = (SPM_FLAG_RUN_COMMON_SCENARIO |
49 SPM_FLAG_DISABLE_VCORE_DVS |
50 SPM_FLAG_DISABLE_VCORE_DFS),
51
52 /* Auto-gen Start */
53
54 /* SPM_AP_STANDBY_CON */
55 .reg_wfi_op = 0,
56 .reg_wfi_type = 0,
57 .reg_mp0_cputop_idle_mask = 0,
58 .reg_mp1_cputop_idle_mask = 0,
59 .reg_mcusys_idle_mask = 0,
60 .reg_md_apsrc_1_sel = 0,
61 .reg_md_apsrc_0_sel = 0,
62 .reg_conn_apsrc_sel = 0,
63
64 /* SPM_SRC6_MASK */
65 .reg_ccif_event_infra_req_mask_b = 0xFFFF,
66 .reg_ccif_event_apsrc_req_mask_b = 0xFFFF,
67
68 /* SPM_SRC_REQ */
69 .reg_spm_apsrc_req = 1,
70 .reg_spm_f26m_req = 1,
71 .reg_spm_infra_req = 1,
72 .reg_spm_vrf18_req = 1,
73 .reg_spm_ddren_req = 1,
74 .reg_spm_dvfs_req = 0,
75 .reg_spm_sw_mailbox_req = 0,
76 .reg_spm_sspm_mailbox_req = 0,
77 .reg_spm_adsp_mailbox_req = 0,
78 .reg_spm_scp_mailbox_req = 0,
79
80 /* SPM_SRC_MASK */
81 .reg_md_0_srcclkena_mask_b = 1,
82 .reg_md_0_infra_req_mask_b = 1,
83 .reg_md_0_apsrc_req_mask_b = 1,
84 .reg_md_0_vrf18_req_mask_b = 1,
85 .reg_md_0_ddren_req_mask_b = 1,
86 .reg_md_1_srcclkena_mask_b = 0,
87 .reg_md_1_infra_req_mask_b = 0,
88 .reg_md_1_apsrc_req_mask_b = 0,
89 .reg_md_1_vrf18_req_mask_b = 0,
90 .reg_md_1_ddren_req_mask_b = 0,
91 .reg_conn_srcclkena_mask_b = 1,
92 .reg_conn_srcclkenb_mask_b = 0,
93 .reg_conn_infra_req_mask_b = 1,
94 .reg_conn_apsrc_req_mask_b = 1,
95 .reg_conn_vrf18_req_mask_b = 1,
96 .reg_conn_ddren_req_mask_b = 1,
97 .reg_conn_vfe28_mask_b = 0,
98 .reg_srcclkeni_srcclkena_mask_b = 1,
99 .reg_srcclkeni_infra_req_mask_b = 1,
100 .reg_infrasys_apsrc_req_mask_b = 0,
101 .reg_infrasys_ddren_req_mask_b = 1,
102 .reg_sspm_srcclkena_mask_b = 1,
103 .reg_sspm_infra_req_mask_b = 1,
104 .reg_sspm_apsrc_req_mask_b = 1,
105 .reg_sspm_vrf18_req_mask_b = 1,
106 .reg_sspm_ddren_req_mask_b = 1,
107
108 /* SPM_SRC2_MASK */
109 .reg_scp_srcclkena_mask_b = 1,
110 .reg_scp_infra_req_mask_b = 1,
111 .reg_scp_apsrc_req_mask_b = 1,
112 .reg_scp_vrf18_req_mask_b = 1,
113 .reg_scp_ddren_req_mask_b = 1,
114 .reg_audio_dsp_srcclkena_mask_b = 1,
115 .reg_audio_dsp_infra_req_mask_b = 1,
116 .reg_audio_dsp_apsrc_req_mask_b = 1,
117 .reg_audio_dsp_vrf18_req_mask_b = 1,
118 .reg_audio_dsp_ddren_req_mask_b = 1,
119 .reg_ufs_srcclkena_mask_b = 1,
120 .reg_ufs_infra_req_mask_b = 1,
121 .reg_ufs_apsrc_req_mask_b = 1,
122 .reg_ufs_vrf18_req_mask_b = 1,
123 .reg_ufs_ddren_req_mask_b = 1,
124 .reg_disp0_apsrc_req_mask_b = 1,
125 .reg_disp0_ddren_req_mask_b = 1,
126 .reg_disp1_apsrc_req_mask_b = 1,
127 .reg_disp1_ddren_req_mask_b = 1,
128 .reg_gce_infra_req_mask_b = 1,
129 .reg_gce_apsrc_req_mask_b = 1,
130 .reg_gce_vrf18_req_mask_b = 1,
131 .reg_gce_ddren_req_mask_b = 1,
132 .reg_apu_srcclkena_mask_b = 0,
133 .reg_apu_infra_req_mask_b = 0,
134 .reg_apu_apsrc_req_mask_b = 0,
135 .reg_apu_vrf18_req_mask_b = 0,
136 .reg_apu_ddren_req_mask_b = 0,
137 .reg_cg_check_srcclkena_mask_b = 0,
138 .reg_cg_check_apsrc_req_mask_b = 0,
139 .reg_cg_check_vrf18_req_mask_b = 0,
140 .reg_cg_check_ddren_req_mask_b = 0,
141
142 /* SPM_SRC3_MASK */
143 .reg_dvfsrc_event_trigger_mask_b = 1,
144 .reg_sw2spm_wakeup_mask_b = 0,
145 .reg_adsp2spm_wakeup_mask_b = 0,
146 .reg_sspm2spm_wakeup_mask_b = 0,
147 .reg_scp2spm_wakeup_mask_b = 0,
148 .reg_csyspwrup_ack_mask = 1,
149 .reg_spm_reserved_srcclkena_mask_b = 0,
150 .reg_spm_reserved_infra_req_mask_b = 0,
151 .reg_spm_reserved_apsrc_req_mask_b = 0,
152 .reg_spm_reserved_vrf18_req_mask_b = 0,
153 .reg_spm_reserved_ddren_req_mask_b = 0,
154 .reg_mcupm_srcclkena_mask_b = 1,
155 .reg_mcupm_infra_req_mask_b = 1,
156 .reg_mcupm_apsrc_req_mask_b = 1,
157 .reg_mcupm_vrf18_req_mask_b = 1,
158 .reg_mcupm_ddren_req_mask_b = 1,
159 .reg_msdc0_srcclkena_mask_b = 1,
160 .reg_msdc0_infra_req_mask_b = 1,
161 .reg_msdc0_apsrc_req_mask_b = 1,
162 .reg_msdc0_vrf18_req_mask_b = 1,
163 .reg_msdc0_ddren_req_mask_b = 1,
164 .reg_msdc1_srcclkena_mask_b = 1,
165 .reg_msdc1_infra_req_mask_b = 1,
166 .reg_msdc1_apsrc_req_mask_b = 1,
167 .reg_msdc1_vrf18_req_mask_b = 1,
168 .reg_msdc1_ddren_req_mask_b = 1,
169
170 /* SPM_SRC4_MASK */
171 .reg_ccif_event_srcclkena_mask_b = 0x3FF,
172 .reg_bak_psri_srcclkena_mask_b = 0,
173 .reg_bak_psri_infra_req_mask_b = 0,
174 .reg_bak_psri_apsrc_req_mask_b = 0,
175 .reg_bak_psri_vrf18_req_mask_b = 0,
176 .reg_bak_psri_ddren_req_mask_b = 0,
177 .reg_dramc_md32_infra_req_mask_b = 1,
178 .reg_dramc_md32_vrf18_req_mask_b = 0,
179 .reg_conn_srcclkenb2pwrap_mask_b = 0,
180 .reg_dramc_md32_apsrc_req_mask_b = 0,
181
182 /* SPM_SRC5_MASK */
183 .reg_mcusys_merge_apsrc_req_mask_b = 0x14,
184 .reg_mcusys_merge_ddren_req_mask_b = 0x14,
185 .reg_afe_srcclkena_mask_b = 0,
186 .reg_afe_infra_req_mask_b = 0,
187 .reg_afe_apsrc_req_mask_b = 0,
188 .reg_afe_vrf18_req_mask_b = 0,
189 .reg_afe_ddren_req_mask_b = 0,
190 .reg_msdc2_srcclkena_mask_b = 0,
191 .reg_msdc2_infra_req_mask_b = 0,
192 .reg_msdc2_apsrc_req_mask_b = 0,
193 .reg_msdc2_vrf18_req_mask_b = 0,
194 .reg_msdc2_ddren_req_mask_b = 0,
195
196 /* SPM_WAKEUP_EVENT_MASK */
197 .reg_wakeup_event_mask = 0xEFFFFFFF,
198
199 /* SPM_WAKEUP_EVENT_EXT_MASK */
200 .reg_ext_wakeup_event_mask = 0xFFFFFFFF,
201
202 /* SPM_SRC7_MASK */
203 .reg_pcie_srcclkena_mask_b = 1,
204 .reg_pcie_infra_req_mask_b = 1,
205 .reg_pcie_apsrc_req_mask_b = 1,
206 .reg_pcie_vrf18_req_mask_b = 1,
207 .reg_pcie_ddren_req_mask_b = 1,
208 .reg_dpmaif_srcclkena_mask_b = 1,
209 .reg_dpmaif_infra_req_mask_b = 1,
210 .reg_dpmaif_apsrc_req_mask_b = 1,
211 .reg_dpmaif_vrf18_req_mask_b = 1,
212 .reg_dpmaif_ddren_req_mask_b = 1,
213
214 /* Auto-gen End */
215};
216
217struct spm_lp_scen __spm_vcorefs = {
218 .pwrctrl = &vcorefs_ctrl,
219};
220
221static struct reg_config dvfsrc_init_configs[] = {
222 {DVFSRC_HRT_REQ_UNIT, 0x0000001E},
223 {DVFSRC_DEBOUNCE_TIME, 0x00001965},
224 {DVFSRC_TIMEOUT_NEXTREQ, 0x00000015},
225 {DVFSRC_VCORE_REQUEST4, 0x22211100},
226 {DVFSRC_DDR_QOS0, 0x00000019},
227 {DVFSRC_DDR_QOS1, 0x00000026},
228 {DVFSRC_DDR_QOS2, 0x00000033},
229 {DVFSRC_DDR_QOS3, 0x0000004C},
230 {DVFSRC_DDR_QOS4, 0x00000066},
231 {DVFSRC_DDR_QOS5, 0x00000077},
232 {DVFSRC_DDR_QOS6, 0x00770077},
233 {DVFSRC_LEVEL_LABEL_0_1, 0x40225032},
234 {DVFSRC_LEVEL_LABEL_2_3, 0x20223012},
235 {DVFSRC_LEVEL_LABEL_4_5, 0x40211012},
236 {DVFSRC_LEVEL_LABEL_6_7, 0x20213011},
237 {DVFSRC_LEVEL_LABEL_8_9, 0x30101011},
238 {DVFSRC_LEVEL_LABEL_10_11, 0x10102000},
239 {DVFSRC_LEVEL_LABEL_12_13, 0x00000000},
240 {DVFSRC_LEVEL_LABEL_14_15, 0x00000000},
241 {DVFSRC_LEVEL_LABEL_16_17, 0x00000000},
242 {DVFSRC_LEVEL_LABEL_18_19, 0x00000000},
243 {DVFSRC_LEVEL_LABEL_20_21, 0x00000000},
244 {DVFSRC_LEVEL_MASK, 0x00000000},
245 {DVFSRC_MD_LATENCY_IMPROVE, 0x00000020},
246 {DVFSRC_HRT_BW_BASE, 0x00000004},
247 {DVSFRC_HRT_REQ_MD_URG, 0x000D50D5},
248 {DVFSRC_HRT_REQ_MD_BW_0, 0x00200802},
249 {DVFSRC_HRT_REQ_MD_BW_1, 0x00200802},
250 {DVFSRC_HRT_REQ_MD_BW_2, 0x00200800},
251 {DVFSRC_HRT_REQ_MD_BW_3, 0x00400802},
252 {DVFSRC_HRT_REQ_MD_BW_4, 0x00601404},
253 {DVFSRC_HRT_REQ_MD_BW_5, 0x00D02C09},
254 {DVFSRC_HRT_REQ_MD_BW_6, 0x00000012},
255 {DVFSRC_HRT_REQ_MD_BW_7, 0x00000024},
256 {DVFSRC_HRT_REQ_MD_BW_8, 0x00000000},
257 {DVFSRC_HRT_REQ_MD_BW_9, 0x00000000},
258 {DVFSRC_HRT_REQ_MD_BW_10, 0x00035400},
259 {DVFSRC_HRT1_REQ_MD_BW_0, 0x04B12C4B},
260 {DVFSRC_HRT1_REQ_MD_BW_1, 0x04B12C4B},
261 {DVFSRC_HRT1_REQ_MD_BW_2, 0x04B12C00},
262 {DVFSRC_HRT1_REQ_MD_BW_3, 0x04B12C4B},
263 {DVFSRC_HRT1_REQ_MD_BW_4, 0x04B12C4B},
264 {DVFSRC_HRT1_REQ_MD_BW_5, 0x04B12C4B},
265 {DVFSRC_HRT1_REQ_MD_BW_6, 0x0000004B},
266 {DVFSRC_HRT1_REQ_MD_BW_7, 0x0000005C},
267 {DVFSRC_HRT1_REQ_MD_BW_8, 0x00000000},
268 {DVFSRC_HRT1_REQ_MD_BW_9, 0x00000000},
269 {DVFSRC_HRT1_REQ_MD_BW_10, 0x00035400},
270 {DVFSRC_95MD_SCEN_BW0_T, 0x22222220},
271 {DVFSRC_95MD_SCEN_BW1_T, 0x22222222},
272 {DVFSRC_95MD_SCEN_BW2_T, 0x22222222},
273 {DVFSRC_95MD_SCEN_BW3_T, 0x52222222},
274 {DVFSRC_95MD_SCEN_BW4, 0x00000005},
275 {DVFSRC_RSRV_5, 0x00000001},
276#ifdef DVFSRC_1600_FLOOR
277 {DVFSRC_DDR_REQUEST, 0x00000022},
278#else
279 {DVFSRC_DDR_REQUEST, 0x00000021},
280#endif
281 {DVFSRC_DDR_REQUEST3, 0x00554300},
282 {DVFSRC_DDR_ADD_REQUEST, 0x55543210},
283#ifdef DVFSRC_1600_FLOOR
284 {DVFSRC_DDR_REQUEST5, 0x54322000},
285#else
286 {DVFSRC_DDR_REQUEST5, 0x54321000},
287#endif
288 {DVFSRC_DDR_REQUEST6, 0x53143130},
289 {DVFSRC_DDR_REQUEST7, 0x55000000},
290 {DVFSRC_DDR_REQUEST8, 0x05000000},
291 {DVFSRC_EMI_MON_DEBOUNCE_TIME, 0x4C2D0000},
292 {DVFSRC_EMI_ADD_REQUEST, 0x55543210},
293 {DVFSRC_VCORE_USER_REQ, 0x00010A29},
294 {DVFSRC_HRT_HIGH, 0x0E100960},
295 {DVFSRC_HRT_HIGH_1, 0x1AD21700},
296 {DVFSRC_HRT_HIGH_2, 0x314C2306},
297 {DVFSRC_HRT_HIGH_3, 0x314C314C},
298 {DVFSRC_HRT_LOW, 0x0E0F095F},
299 {DVFSRC_HRT_LOW_1, 0x1AD116FF},
300 {DVFSRC_HRT_LOW_2, 0x314B2305},
301 {DVFSRC_HRT_LOW_3, 0x314B314B},
302#ifdef DVFSRC_1600_FLOOR
303 {DVFSRC_HRT_REQUEST, 0x55554322},
304#else
305 {DVFSRC_HRT_REQUEST, 0x55554321},
306#endif
307 {DVFSRC_BASIC_CONTROL_3, 0x0000000E},
308 {DVFSRC_INT_EN, 0x00000002},
309 {DVFSRC_QOS_EN, 0x001e407C},
310 {DVFSRC_CURRENT_FORCE, 0x00000001},
311 {DVFSRC_BASIC_CONTROL, 0x0180004B},
312 {DVFSRC_BASIC_CONTROL, 0X0180404B},
313 {DVFSRC_BASIC_CONTROL, 0X0180014B},
314 {DVFSRC_CURRENT_FORCE, 0x00000000},
315};
316
317#define IS_PMIC_57() ((pmic_get_hwcid() >> 8) == 0x57)
318
319static inline unsigned int vcore_base_uv(void)
320{
321 static unsigned int vb;
322
323 if (vb == 0) {
324 vb = IS_PMIC_57() ? 518750 : 500000;
325 }
326
327 return vb;
328}
329
330#define _VCORE_STEP_UV (6250)
331
332#define __vcore_uv_to_pmic(uv) /* pmic >= uv */ \
333 ((((uv) - vcore_base_uv()) + (_VCORE_STEP_UV - 1)) / _VCORE_STEP_UV)
334
335static int devinfo_table[] = {
336 3539, 492, 1038, 106, 231, 17, 46, 2179,
337 4, 481, 1014, 103, 225, 17, 45, 2129,
338 3, 516, 1087, 111, 242, 19, 49, 2282,
339 4, 504, 1063, 108, 236, 18, 47, 2230,
340 4, 448, 946, 96, 210, 15, 41, 1986,
341 2, 438, 924, 93, 205, 14, 40, 1941,
342 2, 470, 991, 101, 220, 16, 43, 2080,
343 3, 459, 968, 98, 215, 16, 42, 2033,
344 3, 594, 1250, 129, 279, 23, 57, 2621,
345 6, 580, 1221, 126, 273, 22, 56, 2561,
346 6, 622, 1309, 136, 293, 24, 60, 2745,
347 7, 608, 1279, 132, 286, 23, 59, 2683,
348 6, 541, 1139, 117, 254, 20, 51, 2390,
349 5, 528, 1113, 114, 248, 19, 50, 2335,
350 4, 566, 1193, 123, 266, 21, 54, 2503,
351 5, 553, 1166, 120, 260, 21, 53, 2446,
352 5, 338, 715, 70, 157, 9, 29, 1505,
353 3153, 330, 699, 69, 153, 9, 28, 1470,
354 3081, 354, 750, 74, 165, 10, 31, 1576,
355 3302, 346, 732, 72, 161, 10, 30, 1540,
356 3227, 307, 652, 63, 142, 8, 26, 1371,
357 2875, 300, 637, 62, 139, 7, 25, 1340,
358 2809, 322, 683, 67, 149, 8, 27, 1436,
359 3011, 315, 667, 65, 146, 8, 26, 1404,
360 2942, 408, 862, 86, 191, 13, 37, 1811,
361 1, 398, 842, 84, 186, 12, 36, 1769,
362 1, 428, 903, 91, 200, 14, 39, 1896,
363 2, 418, 882, 89, 195, 13, 38, 1853,
364 2, 371, 785, 78, 173, 11, 33, 1651,
365 3458, 363, 767, 76, 169, 10, 32, 1613,
366 3379, 389, 823, 82, 182, 12, 35, 1729,
367 1, 380, 804, 80, 177, 11, 34, 1689,
368};
369
370static void spm_vcorefs_pwarp_cmd(uint64_t cmd, uint64_t val)
371{
372 if (cmd < NR_IDX_ALL) {
373 mt_spm_pmic_wrap_set_cmd(PMIC_WRAP_PHASE_ALLINONE, cmd, val);
374 } else {
375 INFO("cmd out of range!\n");
376 }
377}
378
379void spm_dvfsfw_init(uint64_t boot_up_opp, uint64_t dram_issue)
380{
381 mmio_write_32(OPP0_TABLE, 0xFFFF0000);
382 mmio_write_32(OPP1_TABLE, 0xFFFF0100);
383 mmio_write_32(OPP2_TABLE, 0xFFFF0300);
384 mmio_write_32(OPP3_TABLE, 0xFFFF0500);
385 mmio_write_32(OPP4_TABLE, 0xFFFF0700);
386 mmio_write_32(OPP5_TABLE, 0xFFFF0202);
387 mmio_write_32(OPP6_TABLE, 0xFFFF0302);
388 mmio_write_32(OPP7_TABLE, 0xFFFF0502);
389 mmio_write_32(OPP8_TABLE, 0xFFFF0702);
390 mmio_write_32(OPP9_TABLE, 0xFFFF0403);
391 mmio_write_32(OPP10_TABLE, 0xFFFF0603);
392 mmio_write_32(OPP11_TABLE, 0xFFFF0803);
393 mmio_write_32(OPP12_TABLE, 0xFFFF0903);
394 mmio_write_32(OPP13_TABLE, 0xFFFFFFFF);
395 mmio_write_32(OPP14_TABLE, 0xFFFFFFFF);
396 mmio_write_32(OPP15_TABLE, 0xFFFFFFFF);
397 mmio_write_32(OPP16_TABLE, 0xFFFFFFFF);
398 mmio_write_32(OPP17_TABLE, 0xFFFFFFFF);
399 mmio_write_32(SHU0_ARRAY, 0xFFFFFF00);
400 mmio_write_32(SHU1_ARRAY, 0xFFFFEE01);
401 mmio_write_32(SHU2_ARRAY, 0xFF05EEFF);
402 mmio_write_32(SHU3_ARRAY, 0xFF06EE02);
403 mmio_write_32(SHU4_ARRAY, 0x0906FFFF);
404 mmio_write_32(SHU5_ARRAY, 0xFF07EE03);
405 mmio_write_32(SHU6_ARRAY, 0x0A07FFFF);
406 mmio_write_32(SHU7_ARRAY, 0xFF08EE04);
407 mmio_write_32(SHU8_ARRAY, 0x0B08FFFF);
408 mmio_write_32(SHU9_ARRAY, 0x0CFFFFFF);
409
410 mmio_clrsetbits_32(SPM_DVFS_MISC, SPM_DVFS_FORCE_ENABLE_LSB,
411 SPM_DVFSRC_ENABLE_LSB);
412
413 mmio_write_32(SPM_DVFS_LEVEL, 0x00000001);
414 mmio_write_32(SPM_DVS_DFS_LEVEL, 0x00010001);
415}
416
417void __spm_sync_vcore_dvfs_power_control(struct pwr_ctrl *dest_pwr_ctrl,
418 const struct pwr_ctrl *src_pwr_ctrl)
419{
420 uint32_t dvfs_mask = SPM_FLAG_DISABLE_VCORE_DVS |
421 SPM_FLAG_DISABLE_VCORE_DFS |
422 SPM_FLAG_ENABLE_VOLTAGE_BIN;
423
424 dest_pwr_ctrl->pcm_flags = (dest_pwr_ctrl->pcm_flags & (~dvfs_mask)) |
425 (src_pwr_ctrl->pcm_flags & dvfs_mask);
426
427 if (dest_pwr_ctrl->pcm_flags_cust > 0U) {
428 dest_pwr_ctrl->pcm_flags_cust =
429 ((dest_pwr_ctrl->pcm_flags_cust) & (~dvfs_mask)) |
430 ((src_pwr_ctrl->pcm_flags) & (dvfs_mask));
431 }
432}
433
434static void spm_go_to_vcorefs(void)
435{
436 __spm_set_power_control(__spm_vcorefs.pwrctrl);
437 __spm_set_wakeup_event(__spm_vcorefs.pwrctrl);
438 __spm_set_pcm_flags(__spm_vcorefs.pwrctrl);
439 __spm_send_cpu_wakeup_event();
440}
441
442static void dvfsrc_init(void)
443{
444 uint32_t i;
445
446 for (i = 0U; i < ARRAY_SIZE(dvfsrc_init_configs); i++) {
447 mmio_write_32(dvfsrc_init_configs[i].offset,
448 dvfsrc_init_configs[i].val);
449 }
450}
451
452static void spm_vcorefs_vcore_setting(uint64_t flag)
453{
454 int idx, ptpod, rsv4;
455 int power = 0;
456
457 switch (flag) {
458 case 1: /*HV*/
459 vcore_opp_0_uv = 840000;
460 vcore_opp_1_uv = 725000;
461 vcore_opp_2_uv = 682500;
462 break;
463 case 2: /*LV*/
464 vcore_opp_0_uv = 760000;
465 vcore_opp_1_uv = 665000;
466 vcore_opp_2_uv = 617500;
467 break;
468 default:
469 break;
470 }
471
472 rsv4 = mmio_read_32(DVFSRC_RSRV_4);
473 ptpod = (rsv4 >> VCORE_PTPOD_SHIFT) & 0xF;
474 idx = (rsv4 >> VCORE_POWER_SHIFT) & 0xFF;
475
476 if (idx != 0) {
477 power = (int)devinfo_table[idx];
478 }
479
480 if (power > 0 && power <= 40) {
481 idx = ptpod & 0xF;
482 if (idx == 1) {
483 vcore_opp_2_uv = 700000;
484 } else if (idx > 1 && idx < 10) {
485 vcore_opp_2_uv = 675000;
486 }
487 }
488
489 spm_vcorefs_pwarp_cmd(3, __vcore_uv_to_pmic(vcore_opp_2_uv));
490 spm_vcorefs_pwarp_cmd(2, __vcore_uv_to_pmic(vcore_opp_1_uv));
491 spm_vcorefs_pwarp_cmd(0, __vcore_uv_to_pmic(vcore_opp_0_uv));
492}
493
494uint64_t spm_vcorefs_args(uint64_t x1, uint64_t x2, uint64_t x3, uint64_t *x4)
495{
496 uint64_t cmd = x1;
497 uint64_t spm_flags;
498
499 switch (cmd) {
500 case VCOREFS_SMC_CMD_INIT:
501 /* vcore_dvfs init + kick */
502 mmio_write_32(DVFSRC_SW_REQ5, SW_REQ5_INIT_VAL);
503 spm_dvfsfw_init(0ULL, 0ULL);
504 spm_vcorefs_vcore_setting(x3 & 0xF);
505 spm_flags = SPM_FLAG_RUN_COMMON_SCENARIO;
506 if ((x2 & 0x1) > 0U) {
507 spm_flags |= SPM_FLAG_DISABLE_VCORE_DVS;
508 }
509
510 if ((x2 & 0x2) > 0U) {
511 spm_flags |= SPM_FLAG_DISABLE_VCORE_DFS;
512 }
513
514 if ((mmio_read_32(DVFSRC_RSRV_4) & VCORE_CT_ENABLE) > 0U) {
515 spm_flags |= SPM_FLAG_ENABLE_VOLTAGE_BIN;
516 }
517
518 set_pwrctrl_pcm_flags(__spm_vcorefs.pwrctrl, spm_flags);
519 spm_go_to_vcorefs();
520 dvfsrc_init();
521
522 *x4 = 0U;
523 mmio_write_32(DVFSRC_SW_REQ5, 0U);
524 break;
525 case VCOREFS_SMC_CMD_KICK:
526 mmio_write_32(DVFSRC_SW_REQ5, 0U);
527 break;
528 default:
529 break;
530 }
531
532 return 0ULL;
533}