1 /*
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 
40 static int vcore_opp_0_uv = 800000;
41 static int vcore_opp_1_uv = 700000;
42 static int vcore_opp_2_uv = 650000;
43 
44 static 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 
217 struct spm_lp_scen __spm_vcorefs = {
218 	.pwrctrl	= &vcorefs_ctrl,
219 };
220 
221 static 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 
vcore_base_uv(void)319 static 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 
335 static 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 
spm_vcorefs_pwarp_cmd(uint64_t cmd,uint64_t val)370 static 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 
spm_dvfsfw_init(uint64_t boot_up_opp,uint64_t dram_issue)379 void 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 
__spm_sync_vcore_dvfs_power_control(struct pwr_ctrl * dest_pwr_ctrl,const struct pwr_ctrl * src_pwr_ctrl)417 void __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 
spm_go_to_vcorefs(void)434 static 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 
dvfsrc_init(void)442 static 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 
spm_vcorefs_vcore_setting(uint64_t flag)452 static 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 
spm_vcorefs_args(uint64_t x1,uint64_t x2,uint64_t x3,uint64_t * x4)494 uint64_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 }
534