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