1 /* 2 * Copyright (c) 2023-2024, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 #include <inttypes.h> 9 10 /* TF-A system header */ 11 #include <common/debug.h> 12 #include <drivers/delay_timer.h> 13 #include <lib/mmio.h> 14 #include <lib/spinlock.h> 15 #include <lib/utils_def.h> 16 #include <lib/xlat_tables/xlat_tables_v2.h> 17 18 /* Vendor header */ 19 #include "apusys.h" 20 #include "apusys_power.h" 21 #include "apusys_rv.h" 22 #include "apusys_rv_pwr_ctrl.h" 23 #include <mtk_mmap_pool.h> 24 25 static spinlock_t apu_lock; 26 static bool apusys_top_on; 27 28 static int apu_poll(uintptr_t reg, uint32_t mask, uint32_t value, uint32_t timeout_us) 29 { 30 uint32_t reg_val, count; 31 32 count = timeout_us / APU_POLL_STEP_US; 33 if (count == 0) { 34 count = 1; 35 } 36 37 do { 38 reg_val = mmio_read_32(reg); 39 if ((reg_val & mask) == value) { 40 return 0; 41 } 42 udelay(APU_POLL_STEP_US); 43 } while (--count); 44 45 ERROR(MODULE_TAG "Timeout polling APU register %#" PRIxPTR "\n", reg); 46 ERROR(MODULE_TAG "Read value 0x%x, expected 0x%x\n", reg_val, 47 (value == 0U) ? (reg_val & ~mask) : (reg_val | mask)); 48 49 return -1; 50 } 51 52 static void apu_backup_restore(enum APU_BACKUP_RESTORE_CTRL ctrl) 53 { 54 int i; 55 static struct apu_restore_data apu_restore_data[] = { 56 { UP_NORMAL_DOMAIN_NS, 0 }, 57 { UP_PRI_DOMAIN_NS, 0 }, 58 { UP_IOMMU_CTRL, 0 }, 59 { UP_CORE0_VABASE0, 0 }, 60 { UP_CORE0_MVABASE0, 0 }, 61 { UP_CORE0_VABASE1, 0 }, 62 { UP_CORE0_MVABASE1, 0 }, 63 { UP_CORE0_VABASE2, 0 }, 64 { UP_CORE0_MVABASE2, 0 }, 65 { UP_CORE0_VABASE3, 0 }, 66 { UP_CORE0_MVABASE3, 0 }, 67 { MD32_SYS_CTRL, 0 }, 68 { MD32_CLK_CTRL, 0 }, 69 { UP_WAKE_HOST_MASK0, 0 } 70 }; 71 72 switch (ctrl) { 73 case APU_CTRL_BACKUP: 74 for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) { 75 apu_restore_data[i].data = mmio_read_32(apu_restore_data[i].reg); 76 } 77 break; 78 case APU_CTRL_RESTORE: 79 for (i = 0; i < ARRAY_SIZE(apu_restore_data); i++) { 80 mmio_write_32(apu_restore_data[i].reg, apu_restore_data[i].data); 81 } 82 break; 83 default: 84 ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, ctrl); 85 break; 86 } 87 } 88 89 static void apu_xpu2apusys_d4_slv_en(enum APU_D4_SLV_CTRL en) 90 { 91 switch (en) { 92 case D4_SLV_OFF: 93 mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI21_CTRL_0, 94 INFRA_FMEM_BUS_u_SI21_CTRL_EN); 95 mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI22_CTRL_0, 96 INFRA_FMEM_BUS_u_SI22_CTRL_EN); 97 mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI11_CTRL_0, 98 INFRA_FMEM_BUS_u_SI11_CTRL_EN); 99 mmio_setbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0, 100 INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN); 101 break; 102 case D4_SLV_ON: 103 mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI21_CTRL_0, 104 INFRA_FMEM_BUS_u_SI21_CTRL_EN); 105 mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI22_CTRL_0, 106 INFRA_FMEM_BUS_u_SI22_CTRL_EN); 107 mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_BUS_u_SI11_CTRL_0, 108 INFRA_FMEM_BUS_u_SI11_CTRL_EN); 109 mmio_clrbits_32(BCRM_FMEM_PDN_BASE + INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_0, 110 INFRA_FMEM_M6M7_BUS_u_SI24_CTRL_EN); 111 break; 112 default: 113 ERROR(MODULE_TAG "%s invalid op: %d\n", __func__, en); 114 break; 115 } 116 } 117 118 static void apu_pwr_flow_remote_sync(uint32_t cfg) 119 { 120 mmio_write_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG, (cfg & 0x1)); 121 } 122 123 static int apusys_kernel_apusys_pwr_top_on(void) 124 { 125 int ret; 126 127 spin_lock(&apu_lock); 128 129 if (apusys_top_on == true) { 130 INFO(MODULE_TAG "%s: APUSYS already powered on!\n", __func__); 131 spin_unlock(&apu_lock); 132 return 0; 133 } 134 135 apu_pwr_flow_remote_sync(1); 136 137 mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL_1, AFC_ENA); 138 139 mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_SET); 140 141 ret = apu_poll(APU_RPC_BASE + APU_RPC_INTF_PWR_RDY, 142 PWR_RDY, PWR_RDY, APU_TOP_ON_POLLING_TIMEOUT_US); 143 if (ret != 0) { 144 ERROR(MODULE_TAG "%s polling RPC RDY timeout, ret %d\n", __func__, ret); 145 spin_unlock(&apu_lock); 146 return ret; 147 } 148 149 ret = apu_poll(APU_RPC_BASE + APU_RPC_STATUS, 150 RPC_STATUS_RDY, RPC_STATUS_RDY, APU_TOP_ON_POLLING_TIMEOUT_US); 151 if (ret != 0) { 152 ERROR(MODULE_TAG "%s polling ARE FSM timeout, ret %d\n", __func__, ret); 153 spin_unlock(&apu_lock); 154 return ret; 155 } 156 157 mmio_write_32(APU_VCORE_BASE + APUSYS_VCORE_CG_CLR, CG_CLR); 158 mmio_write_32(APU_RCX_BASE + APU_RCX_CG_CLR, CG_CLR); 159 160 apu_xpu2apusys_d4_slv_en(D4_SLV_OFF); 161 162 apu_backup_restore(APU_CTRL_RESTORE); 163 164 apusys_top_on = true; 165 166 spin_unlock(&apu_lock); 167 return ret; 168 } 169 170 static void apu_sleep_rpc_rcx(void) 171 { 172 mmio_write_32(APU_RPC_BASE + APU_RPC_TOP_CON, REG_WAKEUP_CLR); 173 dsb(); 174 udelay(10); 175 176 mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, (RPC_CTRL | RSV10)); 177 dsb(); 178 udelay(10); 179 180 mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, CLR_IRQ); 181 dsb(); 182 udelay(10); 183 184 mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_CON, SLEEP_REQ); 185 dsb(); 186 udelay(100); 187 } 188 189 static int apusys_kernel_apusys_pwr_top_off(void) 190 { 191 int ret; 192 193 spin_lock(&apu_lock); 194 195 if (apusys_top_on == false) { 196 INFO(MODULE_TAG "%s: APUSYS already powered off!\n", __func__); 197 spin_unlock(&apu_lock); 198 return 0; 199 } 200 201 apu_backup_restore(APU_CTRL_BACKUP); 202 203 apu_xpu2apusys_d4_slv_en(D4_SLV_ON); 204 205 if (mmio_read_32(APU_MBOX0_BASE + PWR_FLOW_SYNC_REG) == 0) { 206 apu_pwr_flow_remote_sync(1); 207 } else { 208 apu_sleep_rpc_rcx(); 209 } 210 211 ret = apu_poll(APU_RPC_BASE + APU_RPC_INTF_PWR_RDY, 212 PWR_RDY, PWR_OFF, APU_TOP_OFF_POLLING_TIMEOUT_US); 213 if (ret != 0) { 214 ERROR(MODULE_TAG "%s timeout to wait RPC sleep (val:%d), ret %d\n", 215 __func__, APU_TOP_OFF_POLLING_TIMEOUT_US, ret); 216 spin_unlock(&apu_lock); 217 return ret; 218 } 219 220 apusys_top_on = false; 221 222 spin_unlock(&apu_lock); 223 return ret; 224 } 225 226 int apusys_rv_pwr_ctrl(enum APU_PWR_OP op) 227 { 228 if (op != APU_PWR_OFF && op != APU_PWR_ON) { 229 ERROR(MODULE_TAG "%s unknown request_ops = %d\n", __func__, op); 230 return -EINVAL; 231 } 232 233 if (op == APU_PWR_ON) 234 return apusys_kernel_apusys_pwr_top_on(); 235 236 return apusys_kernel_apusys_pwr_top_off(); 237 } 238 239 static void get_pll_pcw(const uint32_t clk_rate, uint32_t *r1, uint32_t *r2) 240 { 241 unsigned int fvco = clk_rate; 242 unsigned int pcw_val; 243 unsigned int postdiv_val = 1; 244 unsigned int postdiv_reg = 0; 245 246 while (fvco <= OUT_CLK_FREQ_MIN) { 247 postdiv_val = postdiv_val << 1; 248 postdiv_reg = postdiv_reg + 1; 249 fvco = fvco << 1; 250 } 251 252 pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ; 253 254 if (postdiv_reg == 0) { 255 pcw_val = pcw_val * 2; 256 postdiv_val = postdiv_val << 1; 257 postdiv_reg = postdiv_reg + 1; 258 } 259 260 *r1 = postdiv_reg; 261 *r2 = pcw_val; 262 } 263 264 static void apu_pll_init(void) 265 { 266 const uint32_t pll_hfctl_cfg[PLL_NUM] = { 267 PLL4HPLL_FHCTL0_CFG, 268 PLL4HPLL_FHCTL1_CFG, 269 PLL4HPLL_FHCTL2_CFG, 270 PLL4HPLL_FHCTL3_CFG 271 }; 272 const uint32_t pll_con1[PLL_NUM] = { 273 PLL4H_PLL1_CON1, 274 PLL4H_PLL2_CON1, 275 PLL4H_PLL3_CON1, 276 PLL4H_PLL4_CON1 277 }; 278 const uint32_t pll_fhctl_dds[PLL_NUM] = { 279 PLL4HPLL_FHCTL0_DDS, 280 PLL4HPLL_FHCTL1_DDS, 281 PLL4HPLL_FHCTL2_DDS, 282 PLL4HPLL_FHCTL3_DDS 283 }; 284 const uint32_t pll_freq_out[PLL_NUM] = { 285 APUPLL0_DEFAULT_FREQ, 286 APUPLL1_DEFAULT_FREQ, 287 APUPLL2_DEFAULT_FREQ, 288 APUPLL3_DEFAULT_FREQ 289 }; 290 uint32_t pcw_val, posdiv_val; 291 int pll_idx; 292 293 mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_RST_CON, PLL4H_PLL_HP_SWRSTB); 294 mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_HP_EN, PLL4H_PLL_HP_EN); 295 mmio_setbits_32(APU_PLL_BASE + PLL4HPLL_FHCTL_CLK_CON, PLL4H_PLL_HP_CLKEN); 296 297 for (pll_idx = 0; pll_idx < PLL_NUM; pll_idx++) { 298 mmio_setbits_32(APU_PLL_BASE + pll_hfctl_cfg[pll_idx], (FHCTL0_EN | SFSTR0_EN)); 299 300 posdiv_val = 0; 301 pcw_val = 0; 302 get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val); 303 304 mmio_clrsetbits_32(APU_PLL_BASE + pll_con1[pll_idx], 305 (RG_PLL_POSDIV_MASK << RG_PLL_POSDIV_SFT), 306 (posdiv_val << RG_PLL_POSDIV_SFT)); 307 mmio_write_32(APU_PLL_BASE + pll_fhctl_dds[pll_idx], 308 (FHCTL_PLL_TGL_ORG | pcw_val)); 309 } 310 } 311 312 static void apu_acc_init(void) 313 { 314 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR0, CGEN_SOC); 315 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET0, HW_CTRL_EN); 316 317 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR1, CGEN_SOC); 318 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET1, HW_CTRL_EN); 319 320 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR2, CGEN_SOC); 321 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET2, HW_CTRL_EN); 322 mmio_write_32(APU_ACC_BASE + APU_ACC_AUTO_CTRL_SET2, CLK_REQ_SW_EN); 323 324 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_CLR3, CGEN_SOC); 325 mmio_write_32(APU_ACC_BASE + APU_ACC_CONFG_SET3, HW_CTRL_EN); 326 mmio_write_32(APU_ACC_BASE + APU_ACC_AUTO_CTRL_SET3, CLK_REQ_SW_EN); 327 328 mmio_write_32(APU_ACC_BASE + APU_ACC_CLK_INV_EN_SET, CLK_INV_EN); 329 } 330 331 static void apu_buck_off_cfg(void) 332 { 333 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_SET); 334 dsb(); 335 udelay(10); 336 337 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_SET); 338 dsb(); 339 udelay(10); 340 341 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR); 342 dsb(); 343 udelay(10); 344 } 345 346 static void apu_pcu_init(void) 347 { 348 uint32_t vapu_en_offset = BUCK_VAPU_PMIC_REG_EN_ADDR; 349 uint32_t vapu_sram_en_offset = BUCK_VAPU_SRAM_PMIC_REG_EN_ADDR; 350 351 mmio_write_32(APU_PCU_BASE + APU_PCU_CTRL_SET, AUTO_BUCK_EN); 352 353 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_STEP_SEL, BUCK_ON_OFF_CMD_EN); 354 355 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT0_L, 356 ((vapu_sram_en_offset << BUCK_OFFSET_SFT) + BUCK_ON_CMD)); 357 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT0_H, CMD_OP); 358 359 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT1_L, 360 ((vapu_en_offset << BUCK_OFFSET_SFT) + BUCK_ON_CMD)); 361 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_DAT1_H, CMD_OP); 362 363 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT0_L, 364 ((vapu_en_offset << BUCK_OFFSET_SFT) + BUCK_OFF_CMD)); 365 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT0_H, CMD_OP); 366 367 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT1_L, 368 ((vapu_sram_en_offset << BUCK_OFFSET_SFT) + BUCK_OFF_CMD)); 369 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_OFF_DAT1_H, CMD_OP); 370 371 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_SLE0, APU_PCU_BUCK_ON_SETTLE_TIME); 372 mmio_write_32(APU_PCU_BASE + APU_PCU_BUCK_ON_SLE1, APU_PCU_BUCK_ON_SETTLE_TIME); 373 } 374 375 static void apu_rpclite_init(void) 376 { 377 const uint32_t sleep_type_offset[] = { 378 APU_RPC_SW_TYPE2, 379 APU_RPC_SW_TYPE3, 380 APU_RPC_SW_TYPE4, 381 APU_RPC_SW_TYPE5, 382 APU_RPC_SW_TYPE6, 383 APU_RPC_SW_TYPE7, 384 APU_RPC_SW_TYPE8, 385 APU_RPC_SW_TYPE9 386 }; 387 int ofs_arr_size = ARRAY_SIZE(sleep_type_offset); 388 int ofs_idx; 389 390 for (ofs_idx = 0 ; ofs_idx < ofs_arr_size ; ofs_idx++) { 391 mmio_clrbits_32(APU_ACX0_RPC_LITE_BASE + sleep_type_offset[ofs_idx], 392 SW_TYPE); 393 } 394 395 mmio_setbits_32(APU_ACX0_RPC_LITE_BASE + APU_RPC_TOP_SEL, RPC_CTRL); 396 } 397 398 static void apu_rpc_init(void) 399 { 400 mmio_clrbits_32(APU_RPC_BASE + APU_RPC_SW_TYPE0, SW_TYPE); 401 mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL, RPC_TOP_CTRL); 402 mmio_setbits_32(APU_RPC_BASE + APU_RPC_TOP_SEL_1, RPC_TOP_CTRL1); 403 } 404 405 static int apu_are_init(void) 406 { 407 int ret; 408 int are_id = 0; 409 const uint32_t are_base[APU_ARE_NUM] = { APU_ARE0_BASE, APU_ARE1_BASE, APU_ARE2_BASE }; 410 const uint32_t are_entry2_cfg_l[APU_ARE_NUM] = { 411 ARE0_ENTRY2_CFG_L, 412 ARE1_ENTRY2_CFG_L, 413 ARE2_ENTRY2_CFG_L 414 }; 415 416 mmio_setbits_32(APU_AO_CTL_BASE + CSR_DUMMY_0_ADDR, VCORE_ARE_REQ); 417 418 ret = apu_poll(APU_ARE2_BASE + APU_ARE_GLO_FSM, ARE_GLO_FSM_IDLE, ARE_GLO_FSM_IDLE, 419 APU_ARE_POLLING_TIMEOUT_US); 420 if (ret != 0) { 421 ERROR(MODULE_TAG "[%s][%d] ARE init timeout\n", 422 __func__, __LINE__); 423 return ret; 424 } 425 426 for (are_id = APU_ARE0; are_id < APU_ARE_NUM; are_id++) { 427 mmio_write_32(are_base[are_id] + APU_ARE_ENTRY0_SRAM_H, ARE_ENTRY0_SRAM_H_INIT); 428 mmio_write_32(are_base[are_id] + APU_ARE_ENTRY0_SRAM_L, ARE_ENTRY0_SRAM_L_INIT); 429 430 mmio_write_32(are_base[are_id] + APU_ARE_ENTRY1_SRAM_H, ARE_ENTRY1_SRAM_H_INIT); 431 mmio_write_32(are_base[are_id] + APU_ARE_ENTRY1_SRAM_L, ARE_ENTRY1_SRAM_L_INIT); 432 433 mmio_write_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_H, ARE_ENTRY_CFG_H); 434 mmio_write_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_L, are_entry2_cfg_l[are_id]); 435 436 mmio_read_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_H); 437 mmio_read_32(are_base[are_id] + APU_ARE_ENTRY2_SRAM_L); 438 439 mmio_write_32(are_base[are_id] + APU_ARE_INI_CTRL, ARE_CONFG_INI); 440 } 441 442 return ret; 443 } 444 445 static void apu_aoc_init(void) 446 { 447 mmio_clrbits_32(SPM_BASE + APUSYS_BUCK_ISOLATION, IPU_EXT_BUCK_ISO); 448 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_ELS_EN_CLR); 449 dsb(); 450 udelay(10); 451 452 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_AO_RST_B_SET); 453 dsb(); 454 udelay(10); 455 456 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, BUCK_PROT_REQ_CLR); 457 dsb(); 458 udelay(10); 459 460 mmio_write_32(APU_RPC_BASE + APU_RPC_HW_CON, SRAM_AOC_ISO_CLR); 461 dsb(); 462 udelay(10); 463 } 464 465 static int init_hw_setting(void) 466 { 467 int ret; 468 469 apu_aoc_init(); 470 apu_pcu_init(); 471 apu_rpc_init(); 472 apu_rpclite_init(); 473 474 ret = apu_are_init(); 475 if (ret != 0) { 476 return ret; 477 } 478 479 apu_pll_init(); 480 apu_acc_init(); 481 apu_buck_off_cfg(); 482 483 return ret; 484 } 485 486 int apusys_power_init(void) 487 { 488 int ret; 489 490 ret = init_hw_setting(); 491 if (ret != 0) { 492 ERROR(MODULE_TAG "%s initial fail\n", __func__); 493 } else { 494 INFO(MODULE_TAG "%s initial done\n", __func__); 495 } 496 497 return ret; 498 } 499 500 int apusys_infra_dcm_setup(void) 501 { 502 WARN(MODULE_TAG "%s not support\n", __func__); 503 504 return -EOPNOTSUPP; 505 } 506