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