1 /* 2 * Copyright (c) 2025, Mediatek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <common/debug.h> 8 #include <lib/mmio.h> 9 #include <platform_def.h> 10 11 #include <mt_spm_hwreq.h> 12 #include <mt_spm_reg.h> 13 14 /* Ddren, apsrc and emi resource have become hw resource_req. 15 * So we don't need to use HW CG for request resource. 16 */ 17 #define SPM_HWCG_DDREN_PWR_MB 0 18 #define SPM_HWCG_DDREN_PWR_MSB_MB 0 19 #define SPM_HWCG_DDREN_MODULE_BUSY_MB 0 20 21 /* VRF18 */ 22 #define SPM_HWCG_VRF18_PWR_MB 0 23 #define SPM_HWCG_VRF18_PWR_MSB_MB 0 24 #define SPM_HWCG_VRF18_MODULE_BUSY_MB 0 25 26 /* INFRA */ 27 #define SPM_HWCG_INFRA_PWR_MB SPM_HWCG_VRF18_PWR_MB 28 #define SPM_HWCG_INFRA_PWR_MSB_MB SPM_HWCG_VRF18_PWR_MSB_MB 29 #define SPM_HWCG_INFRA_MODULE_BUSY_MB 0 30 31 /* PMIC */ 32 #define SPM_HWCG_PMIC_PWR_MB SPM_HWCG_VRF18_PWR_MB 33 #define SPM_HWCG_PMIC_PWR_MSB_MB SPM_HWCG_VRF18_PWR_MSB_MB 34 #define SPM_HWCG_PMIC_MODULE_BUSY_MB 0 35 36 /* F26M */ 37 #define SPM_HWCG_F26M_PWR_MB SPM_HWCG_PMIC_PWR_MB 38 #define SPM_HWCG_F26M_PWR_MSB_MB SPM_HWCG_PMIC_PWR_MSB_MB 39 #define SPM_HWCG_F26M_MODULE_BUSY_MB 0 40 41 /* VCORE */ 42 #define SPM_HWCG_VCORE_PWR_MB SPM_HWCG_F26M_PWR_MB 43 #define SPM_HWCG_VCORE_PWR_MSB_MB SPM_HWCG_F26M_PWR_MSB_MB 44 #define SPM_HWCG_VCORE_MODULE_BUSY_MB SPM_HWCG_F26M_MODULE_BUSY_MB 45 46 #define INFRA_SW_CG_MB 0 47 48 struct spm_hwcg_info { 49 uint32_t pwr; 50 uint32_t pwr_msb; 51 uint32_t module_busy; 52 }; 53 54 #define HWCG_INFO_INIT(_info) ({ \ 55 _info.pwr = _info.pwr_msb = _info.module_busy = 0; }) 56 57 #define DECLARE_HWCG_REG(_name_, _info) ({ \ 58 _info.pwr = REG_PWR_STATUS_##_name_##_REQ_MASK; \ 59 _info.pwr_msb = REG_PWR_STATUS_MSB_##_name_##_REQ_MASK; \ 60 _info.module_busy = REG_MODULE_BUSY_##_name_##_REQ_MASK; }) 61 62 #define DECLARE_HWCG_DEFAULT(_name_, _info) ({ \ 63 _info.pwr = SPM_HWCG_##_name_##_PWR_MB; \ 64 _info.pwr_msb = SPM_HWCG_##_name_##_PWR_MSB_MB; \ 65 _info.module_busy = SPM_HWCG_##_name_##_MODULE_BUSY_MB; }) 66 67 #define PERI_REQ_EN_INFO_INIT(_info) ({_info.req_en = 0; }) 68 69 #define PERI_REQ_STA_INFO_INIT(_info) ({_info.req_sta = 0; }) 70 71 #define DECLARE_PERI_REQ_EN_REG(_offset, _info) ({ \ 72 _info.req_en = REG_PERI_REQ_EN(_offset); }) 73 74 #define DECLARE_PERI_REQ_STA_REG(_offset, _info) ({ \ 75 _info.req_sta = REG_PERI_REQ_STA(_offset); }) 76 77 #define DECLARE_PERI_REQ_DEFAULT(_name_, _info) ({ \ 78 _info.req_en = PERI_REQ_##_name_##_MB; }) 79 80 #define PERI_REQ_EN_MASK 0x3FFFFF 81 82 static uint32_t spm_hwcg_index2res(uint32_t idx) 83 { 84 uint32_t res; 85 86 if (idx >= HWCG_MAX) 87 return 0; 88 89 switch (idx) { 90 case HWCG_DDREN: 91 res = (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI); 92 break; 93 case HWCG_VRF18: 94 res = MT_SPM_SYSPLL; 95 break; 96 case HWCG_INFRA: 97 res = MT_SPM_INFRA; 98 break; 99 case HWCG_PMIC: 100 res = MT_SPM_PMIC; 101 break; 102 case HWCG_F26M: 103 res = MT_SPM_26M; 104 break; 105 case HWCG_VCORE: 106 res = MT_SPM_VCORE; 107 break; 108 default: 109 res = 0; 110 } 111 return res; 112 } 113 114 static uint32_t spm_hwcg_ctrl_get(struct spm_hwcg_info *info, 115 enum spm_hwcg_setting type) 116 { 117 uint32_t reg = 0; 118 119 if (!info) 120 return 0; 121 122 switch (type) { 123 case HWCG_PWR: 124 reg = info->pwr; 125 break; 126 case HWCG_PWR_MSB: 127 reg = info->pwr_msb; 128 break; 129 default: 130 reg = info->module_busy; 131 break; 132 } 133 return reg; 134 } 135 136 static void __spm_hwcg_ctrl(struct spm_hwcg_info *info, 137 enum spm_hwcg_setting type, 138 uint32_t is_set, uint32_t val) 139 { 140 uint32_t reg; 141 142 reg = spm_hwcg_ctrl_get(info, type); 143 144 if (!reg) 145 return; 146 147 if (is_set) 148 mmio_setbits_32(reg, val); 149 else 150 mmio_clrbits_32(reg, val); 151 } 152 153 void spm_hwcg_ctrl(uint32_t res, enum spm_hwcg_setting type, 154 uint32_t is_set, uint32_t val) 155 { 156 struct spm_hwcg_info info; 157 158 if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI)) 159 DECLARE_HWCG_REG(DDREN, info); 160 else if (res & MT_SPM_SYSPLL) 161 DECLARE_HWCG_REG(VRF18, info); 162 else if (res & MT_SPM_INFRA) 163 DECLARE_HWCG_REG(INFRA, info); 164 else if (res & MT_SPM_PMIC) 165 DECLARE_HWCG_REG(PMIC, info); 166 else if (res & MT_SPM_26M) 167 DECLARE_HWCG_REG(F26M, info); 168 else if (res & MT_SPM_VCORE) 169 DECLARE_HWCG_REG(VCORE, info); 170 else 171 HWCG_INFO_INIT(info); 172 173 if (info.pwr) 174 __spm_hwcg_ctrl(&info, type, is_set, val); 175 } 176 177 void spm_hwcg_ctrl_by_index(uint32_t idx, enum spm_hwcg_setting type, 178 uint32_t is_set, uint32_t val) 179 { 180 uint32_t res = spm_hwcg_index2res(idx); 181 182 if (res) 183 spm_hwcg_ctrl(res, type, is_set, val); 184 } 185 186 static uint32_t spm_hwcg_mask_get(uint32_t res, enum spm_hwcg_setting type) 187 { 188 struct spm_hwcg_info info; 189 uint32_t raw_val = 0, reg = 0; 190 191 if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI)) 192 DECLARE_HWCG_REG(DDREN, info); 193 else if (res & MT_SPM_SYSPLL) 194 DECLARE_HWCG_REG(VRF18, info); 195 else if (res & MT_SPM_INFRA) 196 DECLARE_HWCG_REG(INFRA, info); 197 else if (res & MT_SPM_PMIC) 198 DECLARE_HWCG_REG(PMIC, info); 199 else if (res & MT_SPM_26M) 200 DECLARE_HWCG_REG(F26M, info); 201 else if (res & MT_SPM_VCORE) 202 DECLARE_HWCG_REG(VCORE, info); 203 else 204 HWCG_INFO_INIT(info); 205 206 if (!info.pwr) 207 return 0; 208 209 reg = spm_hwcg_ctrl_get(&info, type); 210 211 if (!reg) 212 return 0; 213 214 raw_val = ~mmio_read_32(reg); 215 216 return raw_val; 217 } 218 219 static uint32_t spm_hwcg_get_default(uint32_t res, enum spm_hwcg_setting type) 220 { 221 struct spm_hwcg_info info; 222 223 if (res & (MT_SPM_DRAM_S0 | MT_SPM_DRAM_S1 | MT_SPM_EMI)) 224 DECLARE_HWCG_DEFAULT(DDREN, info); 225 else if (res & MT_SPM_SYSPLL) 226 DECLARE_HWCG_DEFAULT(VRF18, info); 227 else if (res & MT_SPM_INFRA) 228 DECLARE_HWCG_DEFAULT(INFRA, info); 229 else if (res & MT_SPM_PMIC) 230 DECLARE_HWCG_DEFAULT(PMIC, info); 231 else if (res & MT_SPM_26M) 232 DECLARE_HWCG_DEFAULT(F26M, info); 233 else if (res & MT_SPM_VCORE) 234 DECLARE_HWCG_DEFAULT(VCORE, info); 235 else 236 HWCG_INFO_INIT(info); 237 238 if (!info.pwr) 239 return 0; 240 241 return spm_hwcg_ctrl_get(&info, type); 242 } 243 244 uint32_t spm_hwcg_get_status(uint32_t idx, enum spm_hwcg_setting type) 245 { 246 uint32_t val = 0; 247 248 switch (type) { 249 case HWCG_PWR: 250 val = mmio_read_32(PWR_STATUS); 251 break; 252 case HWCG_PWR_MSB: 253 val = mmio_read_32(PWR_STATUS_MSB); 254 break; 255 default: 256 break; 257 } 258 return val; 259 } 260 261 int spm_hwcg_get_setting(uint32_t res, enum spm_hwcg_sta_type sta_type, 262 enum spm_hwcg_setting type, 263 struct spm_hwcg_sta *sta) 264 { 265 int ret = 0; 266 267 if (!sta) 268 return -1; 269 270 switch (sta_type) { 271 case HWCG_STA_DEFAULT_MASK: 272 sta->sta = spm_hwcg_get_default(res, type); 273 break; 274 case HWCG_STA_MASK: 275 sta->sta = spm_hwcg_mask_get(res, type); 276 break; 277 default: 278 ret = -1; 279 MT_SPM_HW_CG_STA_INIT(sta); 280 break; 281 } 282 return ret; 283 } 284 285 int spm_hwcg_get_setting_by_index(uint32_t idx, 286 enum spm_hwcg_sta_type sta_type, 287 enum spm_hwcg_setting type, 288 struct spm_hwcg_sta *sta) 289 { 290 uint32_t res = spm_hwcg_index2res(idx); 291 292 return spm_hwcg_get_setting(res, sta_type, type, sta); 293 } 294 295 int spm_hwcg_name(uint32_t idex, char *name, size_t sz) 296 { 297 int ret = 0; 298 299 if (!name) 300 return -1; 301 302 switch (idex) { 303 case HWCG_DDREN: 304 ret = snprintf(name, sz - 1, "dram"); 305 break; 306 case HWCG_VRF18: 307 ret = snprintf(name, sz - 1, "vrf18"); 308 break; 309 case HWCG_INFRA: 310 ret = snprintf(name, sz - 1, "infra"); 311 break; 312 case HWCG_PMIC: 313 ret = snprintf(name, sz - 1, "pmic"); 314 break; 315 case HWCG_F26M: 316 ret = snprintf(name, sz - 1, "26m"); 317 break; 318 case HWCG_VCORE: 319 ret = snprintf(name, sz - 1, "vcore"); 320 break; 321 default: 322 ret = -1; 323 break; 324 } 325 326 if (ret < 0) 327 ret = -1; 328 329 name[sz-1] = '\0'; 330 331 return ret; 332 } 333 334 static void spm_infra_swcg_init(void) 335 { 336 mmio_write_32(INFRA_SW_CG_MASK, ~INFRA_SW_CG_MB); 337 } 338 339 static void spm_hwcg_init(void) 340 { 341 /* HW CG for ddren, apsrc, emi resource req */ 342 mmio_write_32(REG_PWR_STATUS_DDREN_REQ_MASK, 343 ~SPM_HWCG_DDREN_PWR_MB); 344 mmio_write_32(REG_PWR_STATUS_MSB_DDREN_REQ_MASK, 345 ~SPM_HWCG_DDREN_PWR_MSB_MB); 346 mmio_write_32(REG_MODULE_BUSY_DDREN_REQ_MASK, 347 ~SPM_HWCG_DDREN_MODULE_BUSY_MB); 348 349 /* HW CG for vrf18 resource req */ 350 mmio_write_32(REG_PWR_STATUS_VRF18_REQ_MASK, 351 ~SPM_HWCG_VRF18_PWR_MB); 352 mmio_write_32(REG_PWR_STATUS_MSB_VRF18_REQ_MASK, 353 ~SPM_HWCG_VRF18_PWR_MSB_MB); 354 mmio_write_32(REG_MODULE_BUSY_VRF18_REQ_MASK, 355 ~SPM_HWCG_VRF18_MODULE_BUSY_MB); 356 357 /* HW CG for infra resource req */ 358 mmio_write_32(REG_PWR_STATUS_INFRA_REQ_MASK, 359 ~SPM_HWCG_INFRA_PWR_MB); 360 mmio_write_32(REG_PWR_STATUS_MSB_INFRA_REQ_MASK, 361 ~SPM_HWCG_INFRA_PWR_MSB_MB); 362 mmio_write_32(REG_MODULE_BUSY_INFRA_REQ_MASK, 363 ~SPM_HWCG_INFRA_MODULE_BUSY_MB); 364 365 /* HW CG for pmic resource req */ 366 mmio_write_32(REG_PWR_STATUS_PMIC_REQ_MASK, 367 ~SPM_HWCG_PMIC_PWR_MB); 368 mmio_write_32(REG_PWR_STATUS_MSB_PMIC_REQ_MASK, 369 ~SPM_HWCG_PMIC_PWR_MSB_MB); 370 mmio_write_32(REG_MODULE_BUSY_PMIC_REQ_MASK, 371 ~SPM_HWCG_PMIC_MODULE_BUSY_MB); 372 373 /* HW CG for f26m resource req */ 374 mmio_write_32(REG_PWR_STATUS_F26M_REQ_MASK, 375 ~SPM_HWCG_F26M_PWR_MB); 376 mmio_write_32(REG_PWR_STATUS_MSB_F26M_REQ_MASK, 377 ~SPM_HWCG_F26M_PWR_MSB_MB); 378 mmio_write_32(REG_MODULE_BUSY_F26M_REQ_MASK, 379 ~SPM_HWCG_F26M_MODULE_BUSY_MB); 380 381 /* HW CG for vcore resource req */ 382 mmio_write_32(REG_PWR_STATUS_VCORE_REQ_MASK, 383 ~SPM_HWCG_VCORE_PWR_MB); 384 mmio_write_32(REG_PWR_STATUS_MSB_VCORE_REQ_MASK, 385 ~SPM_HWCG_VCORE_PWR_MSB_MB); 386 mmio_write_32(REG_MODULE_BUSY_VCORE_REQ_MASK, 387 ~SPM_HWCG_VCORE_MODULE_BUSY_MB); 388 } 389 390 #define PERI_CG(ofs) (PERICFG_AO_BASE + 0x10 + (0x4 * (ofs))) 391 #define PERI_REQ_DEFAULT_MB (BIT(PERI_REQ_EN_FLASHIF) | \ 392 BIT(PERI_REQ_EN_AP_DMA) | \ 393 BIT(PERI_REQ_EN_UART1) | \ 394 BIT(PERI_REQ_EN_UART2) | \ 395 BIT(PERI_REQ_EN_UART4) | \ 396 BIT(PERI_REQ_EN_UART5) | \ 397 BIT(PERI_REQ_EN_PWM) | \ 398 BIT(PERI_REQ_EN_SPI0) | \ 399 BIT(PERI_REQ_EN_SPI0_INCR16) | \ 400 BIT(PERI_REQ_EN_SPI1) | \ 401 BIT(PERI_REQ_EN_SPI2) | \ 402 BIT(PERI_REQ_EN_SPI3) | \ 403 BIT(PERI_REQ_EN_SPI4) | \ 404 BIT(PERI_REQ_EN_SPI5) | \ 405 BIT(PERI_REQ_EN_SPI6) | \ 406 BIT(PERI_REQ_EN_SPI7) | \ 407 BIT(PERI_REQ_EN_IMP_IIC)) 408 409 /* For MSDC reqesut WA: PERI_REQ_EN_RSV_FOR_MSDC */ 410 #define PERI_REQ_APSRC_MB (PERI_REQ_DEFAULT_MB | \ 411 BIT(PERI_REQ_EN_RSV_FOR_MSDC)) 412 413 #define PERI_REQ_DDREN_MB (PERI_REQ_DEFAULT_MB | \ 414 BIT(PERI_REQ_EN_USB) | \ 415 BIT(PERI_REQ_EN_UFS0) | \ 416 BIT(PERI_REQ_EN_PEXTP1) | \ 417 BIT(PERI_REQ_EN_PEXTP0) | \ 418 BIT(PERI_REQ_EN_PERI_BUS_TRAFFIC)) 419 #define PERI_REQ_EMI_MB (PERI_REQ_DEFAULT_MB) 420 #define PERI_REQ_INFRA_MB (PERI_REQ_DEFAULT_MB) 421 #define PERI_REQ_SYSPLL_MB (PERI_REQ_DEFAULT_MB) 422 #define PERI_REQ_F26M_MB (PERI_REQ_DEFAULT_MB) 423 424 uint32_t spm_peri_req_get_status(uint32_t idx, enum spm_peri_req_status type) 425 { 426 uint32_t val = 0, reg = 0; 427 struct spm_peri_req_info info; 428 429 switch (type) { 430 case PERI_RES_REQ_EN: 431 432 switch (idx) { 433 case PERI_REQ_DDREN: 434 DECLARE_PERI_REQ_STA_REG(PERI_REQ_DDREN, info); 435 436 break; 437 case PERI_REQ_EMI: 438 DECLARE_PERI_REQ_STA_REG(PERI_REQ_EMI, info); 439 440 break; 441 case PERI_REQ_APSRC: 442 DECLARE_PERI_REQ_STA_REG(PERI_REQ_APSRC, info); 443 444 break; 445 case PERI_REQ_SYSPLL: 446 DECLARE_PERI_REQ_STA_REG(PERI_REQ_SYSPLL, info); 447 448 break; 449 case PERI_REQ_INFRA: 450 DECLARE_PERI_REQ_STA_REG(PERI_REQ_INFRA, info); 451 452 break; 453 case PERI_REQ_F26M: 454 DECLARE_PERI_REQ_STA_REG(PERI_REQ_F26M, info); 455 456 break; 457 default: 458 PERI_REQ_STA_INFO_INIT(info); 459 break; 460 } 461 462 if (!info.req_sta) 463 return 0; 464 465 reg = info.req_sta; 466 val = (mmio_read_32(reg) & PERI_REQ_EN_MASK); 467 468 break; 469 default: 470 break; 471 } 472 return val; 473 } 474 475 int spm_peri_req_name(uint32_t idex, char *name, size_t sz) 476 { 477 int ret = 0; 478 479 if (!name) 480 return -1; 481 482 switch (idex) { 483 case PERI_REQ_DDREN: 484 ret = snprintf(name, sz - 1, "ddren"); 485 break; 486 case PERI_REQ_EMI: 487 ret = snprintf(name, sz - 1, "emi"); 488 break; 489 case PERI_REQ_APSRC: 490 ret = snprintf(name, sz - 1, "apsrc"); 491 break; 492 case PERI_REQ_SYSPLL: 493 ret = snprintf(name, sz - 1, "syspll"); 494 break; 495 case PERI_REQ_INFRA: 496 ret = snprintf(name, sz - 1, "infra"); 497 break; 498 case PERI_REQ_F26M: 499 ret = snprintf(name, sz - 1, "26m_pmic_vcore"); 500 break; 501 default: 502 ret = -1; 503 break; 504 } 505 506 if (ret < 0) 507 ret = -1; 508 509 name[sz-1] = '\0'; 510 511 return ret; 512 } 513 514 uint32_t spm_peri_req_get_status_raw(enum spm_peri_req_status_raw type, 515 uint32_t idx, 516 char *name, size_t sz) 517 { 518 return 0; 519 } 520 521 static uint32_t spm_peri_req_get_default(uint32_t res) 522 { 523 struct spm_peri_req_info info; 524 525 if (res & MT_SPM_DRAM_S1) 526 DECLARE_PERI_REQ_DEFAULT(DDREN, info); 527 else if (res & MT_SPM_EMI) 528 DECLARE_PERI_REQ_DEFAULT(EMI, info); 529 else if (res & MT_SPM_DRAM_S0) 530 DECLARE_PERI_REQ_DEFAULT(APSRC, info); 531 else if (res & MT_SPM_SYSPLL) 532 DECLARE_PERI_REQ_DEFAULT(SYSPLL, info); 533 else if (res & MT_SPM_INFRA) 534 DECLARE_PERI_REQ_DEFAULT(INFRA, info); 535 else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE)) 536 DECLARE_PERI_REQ_DEFAULT(F26M, info); 537 else 538 PERI_REQ_EN_INFO_INIT(info); 539 540 return info.req_en; 541 } 542 543 static uint32_t spm_peri_req_mask_get(uint32_t res) 544 { 545 struct spm_peri_req_info info; 546 uint32_t raw_val = 0, reg = 0; 547 548 if (res & MT_SPM_DRAM_S1) 549 DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info); 550 else if (res & MT_SPM_EMI) 551 DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info); 552 else if (res & MT_SPM_DRAM_S0) 553 DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info); 554 else if (res & MT_SPM_SYSPLL) 555 DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info); 556 else if (res & MT_SPM_INFRA) 557 DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info); 558 else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE)) 559 DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info); 560 else 561 PERI_REQ_EN_INFO_INIT(info); 562 563 if (!info.req_en) 564 return 0; 565 566 reg = info.req_en; 567 568 raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK); 569 570 return raw_val; 571 } 572 573 int spm_peri_req_get_setting(uint32_t res, 574 enum spm_peri_req_sta_type sta_type, 575 struct spm_peri_req_sta *sta) 576 { 577 int ret = 0; 578 579 if (!sta) 580 return -1; 581 582 switch (sta_type) { 583 case PERI_REQ_STA_DEFAULT_MASK: 584 sta->sta = spm_peri_req_get_default(res); 585 break; 586 case PERI_REQ_STA_MASK: 587 sta->sta = spm_peri_req_mask_get(res); 588 break; 589 default: 590 ret = -1; 591 MT_SPM_HW_CG_STA_INIT(sta); 592 break; 593 } 594 return ret; 595 } 596 597 static uint32_t spm_peri_req_index2res(uint32_t idx) 598 { 599 uint32_t res; 600 601 if (idx >= PERI_REQ_MAX) 602 return 0; 603 604 switch (idx) { 605 case PERI_REQ_DDREN: 606 res = MT_SPM_DRAM_S1; 607 break; 608 case PERI_REQ_EMI: 609 res = MT_SPM_EMI; 610 break; 611 case PERI_REQ_APSRC: 612 res = MT_SPM_DRAM_S0; 613 break; 614 case PERI_REQ_SYSPLL: 615 res = MT_SPM_SYSPLL; 616 break; 617 case PERI_REQ_INFRA: 618 res = MT_SPM_INFRA; 619 break; 620 case PERI_REQ_F26M: 621 res = (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE); 622 break; 623 default: 624 res = 0; 625 } 626 return res; 627 628 } 629 630 int spm_peri_req_get_setting_by_index(uint32_t idx, 631 enum spm_peri_req_sta_type sta_type, 632 struct spm_peri_req_sta *sta) 633 { 634 uint32_t res = spm_peri_req_index2res(idx); 635 636 return spm_peri_req_get_setting(res, sta_type, sta); 637 } 638 639 static void __spm_peri_req_ctrl(struct spm_peri_req_info *info, 640 uint32_t is_set, uint32_t val) 641 { 642 uint32_t raw_val, reg; 643 644 reg = info->req_en; 645 646 if (!reg) 647 return; 648 649 raw_val = (mmio_read_32(reg) & PERI_REQ_EN_MASK); 650 651 if (is_set) 652 raw_val |= val; 653 else 654 raw_val &= ~val; 655 656 mmio_write_32(reg, raw_val); 657 } 658 659 void spm_peri_req_ctrl(uint32_t res, 660 uint32_t is_set, uint32_t val) 661 { 662 struct spm_peri_req_info info; 663 664 if (res & MT_SPM_DRAM_S1) 665 DECLARE_PERI_REQ_EN_REG(PERI_REQ_DDREN, info); 666 else if (res & MT_SPM_EMI) 667 DECLARE_PERI_REQ_EN_REG(PERI_REQ_EMI, info); 668 else if (res & MT_SPM_DRAM_S0) 669 DECLARE_PERI_REQ_EN_REG(PERI_REQ_APSRC, info); 670 else if (res & MT_SPM_SYSPLL) 671 DECLARE_PERI_REQ_EN_REG(PERI_REQ_SYSPLL, info); 672 else if (res & MT_SPM_INFRA) 673 DECLARE_PERI_REQ_EN_REG(PERI_REQ_INFRA, info); 674 else if (res & (MT_SPM_PMIC | MT_SPM_26M | MT_SPM_VCORE)) 675 DECLARE_PERI_REQ_EN_REG(PERI_REQ_F26M, info); 676 else 677 PERI_REQ_EN_INFO_INIT(info); 678 679 if (info.req_en) 680 __spm_peri_req_ctrl(&info, is_set, val); 681 } 682 683 void spm_peri_req_ctrl_by_index(uint32_t idx, 684 uint32_t is_set, uint32_t val) 685 { 686 uint32_t res = spm_peri_req_index2res(idx); 687 688 if (res) 689 spm_peri_req_ctrl(res, is_set, val); 690 } 691 692 static void spm_peri_req_init(void) 693 { 694 mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_DDREN), PERI_REQ_DDREN_MB); 695 mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_EMI), PERI_REQ_EMI_MB); 696 mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_APSRC), PERI_REQ_APSRC_MB); 697 mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_INFRA), PERI_REQ_INFRA_MB); 698 mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_SYSPLL), PERI_REQ_SYSPLL_MB); 699 mmio_write_32(REG_PERI_REQ_EN(PERI_REQ_F26M), PERI_REQ_F26M_MB); 700 } 701 702 void spm_hwreq_init(void) 703 { 704 spm_infra_swcg_init(); 705 spm_hwcg_init(); 706 spm_peri_req_init(); 707 } 708