1 /* 2 * Copyright (c) 2024-2025, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <inttypes.h> 8 9 #include <include/drivers/spmi_api.h> 10 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 #include "apusys_power.h" 19 20 static void apu_w_are(int entry, uint32_t reg, uint32_t data) 21 { 22 uint32_t are_entry_addr; 23 24 are_entry_addr = APUSYS_BASE + APU_ARE + ARE_REG_SIZE * ARE_ENTRY(entry); 25 mmio_write_32(are_entry_addr, reg); 26 mmio_write_32((are_entry_addr + ARE_REG_SIZE), data); 27 } 28 29 static void get_pll_pcw(uint32_t clk_rate, uint32_t *r1, uint32_t *r2) 30 { 31 unsigned int fvco = clk_rate; 32 unsigned int pcw_val; 33 unsigned int postdiv_val = 1; 34 unsigned int postdiv_reg = 0; 35 36 while (fvco <= OUT_CLK_FREQ_MIN) { 37 postdiv_val = postdiv_val << 1; 38 postdiv_reg = postdiv_reg + 1; 39 fvco = fvco << 1; 40 } 41 42 pcw_val = (fvco * (1 << DDS_SHIFT)) / BASIC_CLK_FREQ; 43 44 if (postdiv_reg == 0) { 45 pcw_val = pcw_val * 2; 46 postdiv_val = postdiv_val << 1; 47 postdiv_reg = postdiv_reg + 1; 48 } 49 50 *r1 = postdiv_reg; 51 *r2 = pcw_val; 52 } 53 54 static void buck_off_by_pcu(uint32_t ofs, uint32_t shift, uint32_t slv_id) 55 { 56 uint32_t pmif_id = 0x0; 57 int retry = 10; 58 59 mmio_setbits_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, PMIC_IRQ_EN); 60 mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF1, 61 (ofs << PMIC_OFF_ADDR_OFF) | BIT(shift)); 62 mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_TAR_BUF2, 63 (slv_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_BUCK_OFF_CMD); 64 mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_CMD, PMIC_CMD_EN); 65 66 while ((mmio_read_32(APUSYS_PCU + APU_PCU_PMIC_IRQ) & PMIC_CMD_IRQ) == 0) { 67 udelay(10); 68 if (--retry < 0) 69 ERROR("%s wait APU_PCU_PMIC_IRQ timeout !\n", __func__); 70 } 71 72 mmio_write_32(APUSYS_PCU + APU_PCU_PMIC_IRQ, PMIC_CMD_IRQ); 73 } 74 75 static void apu_buck_off_cfg(void) 76 { 77 mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10)); 78 mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9)); 79 mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12)); 80 mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14)); 81 82 mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(10)); 83 mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(9)); 84 mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(12)); 85 mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CLR, BIT(14)); 86 udelay(1); 87 88 mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_PROT_REQ_SET); 89 udelay(1); 90 91 mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_LHENB_SET); 92 udelay(1); 93 94 mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, SRAM_AOC_ISO_SET); 95 udelay(1); 96 97 mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, PLL_AOC_ISO_EN_SET); 98 udelay(1); 99 100 mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_ELS_EN_SET); 101 udelay(1); 102 103 mmio_write_32(APUSYS_RPC + APU_RPC_HW_CON, BUCK_AO_RST_B_CLR); 104 udelay(1); 105 106 buck_off_by_pcu(BUCK_VAPU_PMIC_REG_EN_CLR_ADDR, BUCK_VAPU_PMIC_REG_EN_SHIFT, 107 BUCK_VAPU_PMIC_ID); 108 109 mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6)); 110 udelay(1); 111 mmio_setbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7)); 112 udelay(1); 113 mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(6)); 114 udelay(1); 115 mmio_clrbits_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_SET, BIT(7)); 116 udelay(1); 117 } 118 119 static void apu_acc_init(void) 120 { 121 uint32_t top_acc_base_arr[] = {MNOC_ACC_BASE, UP_ACC_BASE}; 122 uint32_t eng_acc_base_arr[] = {MVPU_ACC_BASE, MDLA_ACC_BASE}; 123 int acc_idx; 124 int are_idx = ACC_ENTRY_BEGIN; 125 uint32_t base_reg; 126 127 for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(top_acc_base_arr) ; acc_idx++) { 128 base_reg = APUSYS_ACC + top_acc_base_arr[acc_idx]; 129 #if CFG_APU_ARDCM_ENABLE 130 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0); 131 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0); 132 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1); 133 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1); 134 #endif 135 apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC); 136 apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN); 137 } 138 139 for (acc_idx = 0 ; acc_idx < ARRAY_SIZE(eng_acc_base_arr) ; acc_idx++) { 140 base_reg = APUSYS_ACC + eng_acc_base_arr[acc_idx]; 141 #if CFG_APU_ARDCM_ENABLE 142 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_0); 143 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_0); 144 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL1, APU_ARDCM_CTRL1_VAL_1); 145 apu_w_are(are_idx++, base_reg + APU_ARDCM_CTRL0, APU_ARDCM_CTRL0_VAL_1); 146 #endif 147 apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_CLR0, CGEN_SOC); 148 apu_w_are(are_idx++, base_reg + APU_ACC_CONFG_SET0, HW_CTRL_EN); 149 apu_w_are(are_idx++, base_reg + APU_ACC_AUTO_CTRL_SET0, CLK_REQ_SW_EN); 150 } 151 } 152 153 static void apu_pll_init(void) 154 { 155 uint32_t pll_base_arr[] = {MNOC_PLL_BASE, UP_PLL_BASE, MVPU_PLL_BASE, MDLA_PLL_BASE}; 156 int32_t pll_freq_out[] = { 157 APUPLL0_DEFAULT_FREQ, 158 APUPLL1_DEFAULT_FREQ, 159 APUPLL2_DEFAULT_FREQ, 160 APUPLL3_DEFAULT_FREQ 161 }; 162 uint32_t pcw_val, posdiv_val; 163 int pll_idx, are_idx; 164 uint32_t base_reg; 165 166 mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_RCX_AO_EN); 167 mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_RCX_AO_EN); 168 169 mmio_write_32(APUSYS_BASE + APU_ARE + ARE_RCX_AO_CONFIG, ARE_ENTRY(RCX_AO_BEGIN) | 170 (ARE_ENTRIES(RCX_AO_BEGIN, RCX_AO_END) << ARE_RCX_AO_CONFIG_HIGH_OFF)); 171 172 are_idx = PLL_ENTRY_BEGIN; 173 for (pll_idx = 0 ; pll_idx < ARRAY_SIZE(pll_base_arr) ; pll_idx++) { 174 base_reg = APUSYS_PLL + pll_base_arr[pll_idx]; 175 176 apu_w_are(are_idx++, base_reg + RG_PLLGP_LVR_REFSEL, RG_PLLGP_LVR_REFSEL_VAL); 177 apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_HP_EN, FHCTL_CTRL); 178 apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_RST_CON, FHCTL_NO_RESET); 179 apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL_CLK_CON, FHCTL_CLKEN); 180 apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_CFG, 181 FHCTL_HOPPING_EN | FHCTL_SFSTR0_EN); 182 183 posdiv_val = 0; 184 pcw_val = 0; 185 get_pll_pcw(pll_freq_out[pll_idx], &posdiv_val, &pcw_val); 186 187 apu_w_are(are_idx++, base_reg + PLL1C_PLL1_CON1, 188 ((0x1U << RG_PLL_SDM_PCW_CHG_OFF) | 189 (posdiv_val << RG_PLL_POSDIV_OFF) | pcw_val)); 190 191 apu_w_are(are_idx++, base_reg + PLL1CPLL_FHCTL0_DDS, 192 ((0x1U << FHCTL0_PLL_TGL_ORG) | pcw_val)); 193 } 194 } 195 196 static void apu_are_init(void) 197 { 198 int entry = 0; 199 200 mmio_clrbits_32(APUSYS_BASE + APU_ARE, 0xFFFU << ARE_VCORE_OFF); 201 202 mmio_setbits_32(APUSYS_BASE + APU_ARE, ARE_VCORE_EN); 203 mmio_setbits_32(APUSYS_BASE + APU_ARE_REG, ARE_VCORE_EN); 204 205 for (entry = ARE_CONF_START; entry < ARE_CONF_END; entry += 4) 206 mmio_write_32(APUSYS_BASE + APU_ARE + entry, 0); 207 } 208 209 static void apu_rpclite_init(void) 210 { 211 uint32_t sleep_type_offset[] = { 212 APU_RPC_SW_TYPE1_OFF, 213 APU_RPC_SW_TYPE2_OFF, 214 APU_RPC_SW_TYPE3_OFF, 215 APU_RPC_SW_TYPE4_OFF 216 }; 217 uint32_t rpc_lite_base[] = { 218 APU_ACX0_RPC_LITE, 219 APU_ACX1_RPC_LITE, 220 APU_ACX2_RPC_LITE, 221 }; 222 int ofs_idx, rpc_lite_idx; 223 uint32_t base; 224 225 for (rpc_lite_idx = 0; rpc_lite_idx < ARRAY_SIZE(rpc_lite_base); rpc_lite_idx++) { 226 base = APUSYS_BASE + rpc_lite_base[rpc_lite_idx]; 227 for (ofs_idx = 0; ofs_idx < ARRAY_SIZE(sleep_type_offset); ofs_idx++) 228 mmio_clrbits_32(base + sleep_type_offset[ofs_idx], 229 SW_TYPE_MVPU_MDLA_RV); 230 mmio_setbits_32(base + APU_RPC_TOP_SEL, TOP_SEL_VAL); 231 } 232 } 233 234 static void apu_rpc_mdla_init(void) 235 { 236 mmio_clrbits_32(APUSYS_BASE + APU_RPCTOP_MDLA + APU_RPC_SW_TYPE0_OFF, SW_TYPE_MVPU_MDLA_RV); 237 } 238 239 static void apu_rpc_init(void) 240 { 241 mmio_write_32(APUSYS_RPC + APU_RPC_SW_TYPE0_OFF, RPC_TYPE_INIT_VAL); 242 mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, RPC_TOP_SEL_VAL); 243 244 #if !CFG_CTL_RPC_BY_CE 245 mmio_clrbits_32(APUSYS_RPC + APU_RPC_TOP_SEL, CE_ENABLE); 246 #endif 247 248 mmio_setbits_32(APUSYS_RPC + APU_RPC_TOP_SEL_1, BUCK_PROT_SEL); 249 } 250 251 static int apu_pcu_init(void) 252 { 253 uint32_t pmif_id = 0x0; 254 uint32_t slave_id = BUCK_VAPU_PMIC_ID; 255 uint32_t en_set_offset = BUCK_VAPU_PMIC_REG_EN_SET_ADDR; 256 uint32_t en_clr_offset = BUCK_VAPU_PMIC_REG_EN_CLR_ADDR; 257 uint32_t en_shift = BUCK_VAPU_PMIC_REG_EN_SHIFT; 258 struct spmi_device *vsram_sdev; 259 unsigned char vsram = 0; 260 261 mmio_write_32(APUSYS_PCU + APU_PCUTOP_CTRL_SET, AUTO_BUCK_EN); 262 263 mmio_write_32((APUSYS_PCU + APU_PCU_BUCK_STEP_SEL), BUCK_STEP_SEL_VAL); 264 265 vsram_sdev = get_spmi_device(SPMI_MASTER_1, SPMI_SLAVE_4); 266 if (!vsram_sdev) { 267 ERROR("[APUPW] VSRAM BUCK4 get device fail\n"); 268 return -1; 269 } 270 271 if (spmi_ext_register_readl(vsram_sdev, MT6363_RG_BUCK_VBUCK4_VOSEL_ADDR, &vsram, 1)) { 272 ERROR("[APUPW] VSRAM BUCK4 read fail\n"); 273 return -1; 274 } 275 276 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_L, 277 (BUCK_VAPU_PMIC_REG_VOSEL_ADDR << PMIC_OFF_ADDR_OFF) | vsram); 278 279 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT0_H, 280 (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W); 281 282 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_L, 283 (en_set_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift)); 284 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_DAT1_H, 285 (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W); 286 287 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_L, 288 (en_clr_offset << PMIC_OFF_ADDR_OFF) | (0x1U << en_shift)); 289 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_OFF_DAT0_H, 290 (slave_id << PMIC_SLVID_OFF) | (pmif_id << PMIC_PMIFID_OFF) | PCU_CMD_OP_W); 291 292 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE0, 0); 293 mmio_write_32(APUSYS_PCU + APU_PCU_BUCK_ON_SLE1, VAPU_BUCK_ON_SETTLE_TIME); 294 295 return 0; 296 } 297 298 static void apu_aoc_init(void) 299 { 300 uint32_t reg; 301 302 mmio_setbits_32(SPM_BASE + 0xF6C, BIT(4)); 303 mmio_clrbits_32(SPM_BASE + 0x414, BIT(1)); 304 305 mmio_write_32(APUSYS_AO_CTL + APUSYS_AO_SRAM_CONFIG, APUSYS_AO_SRAM_EN); 306 udelay(1); 307 308 reg = APUSYS_AO_CTL + APUSYS_AO_SRAM_SET; 309 310 #if !CFG_CTL_RPC_BY_CE 311 mmio_setbits_32(reg, BIT(8)); 312 udelay(1); 313 mmio_setbits_32(reg, BIT(11)); 314 udelay(1); 315 mmio_setbits_32(reg, BIT(13)); 316 udelay(1); 317 318 mmio_clrbits_32(reg, BIT(8)); 319 udelay(1); 320 mmio_clrbits_32(reg, BIT(11)); 321 udelay(1); 322 mmio_clrbits_32(reg, BIT(13)); 323 #else 324 mmio_setbits_32(reg, BIT(9)); 325 mmio_setbits_32(reg, BIT(12)); 326 mmio_setbits_32(reg, BIT(14)); 327 328 mmio_clrbits_32(reg, BIT(9)); 329 mmio_clrbits_32(reg, BIT(12)); 330 mmio_clrbits_32(reg, BIT(14)); 331 udelay(1); 332 #endif 333 334 reg = APUSYS_RPC + APU_RPC_HW_CON; 335 336 mmio_write_32(reg, BUCK_ELS_EN_CLR); 337 udelay(1); 338 339 mmio_write_32(reg, BUCK_AO_RST_B_SET); 340 udelay(1); 341 342 mmio_write_32(reg, BUCK_PROT_REQ_CLR); 343 udelay(1); 344 345 mmio_write_32(reg, SRAM_AOC_ISO_CLR); 346 udelay(1); 347 348 mmio_write_32(reg, PLL_AOC_ISO_EN_CLR); 349 udelay(1); 350 } 351 352 static int init_hw_setting(void) 353 { 354 int ret; 355 356 apu_aoc_init(); 357 ret = apu_pcu_init(); 358 apu_rpc_init(); 359 apu_rpc_mdla_init(); 360 apu_rpclite_init(); 361 apu_are_init(); 362 apu_pll_init(); 363 apu_acc_init(); 364 apu_buck_off_cfg(); 365 366 return ret; 367 } 368 369 int apusys_power_init(void) 370 { 371 int ret; 372 373 ret = init_hw_setting(); 374 if (ret != 0) 375 ERROR("%s init HW failed\n", __func__); 376 else 377 INFO("%s init HW done\n", __func__); 378 379 mmio_write_32(APU_ACE_HW_FLAG_DIS, APU_ACE_DIS_FLAG_VAL); 380 381 return ret; 382 } 383