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 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 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 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 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 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 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 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 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