1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> 4 */ 5 #include <linux/clk.h> 6 #include <linux/init.h> 7 #include <linux/io.h> 8 #include <linux/iopoll.h> 9 #include <linux/mfd/syscon.h> 10 #include <linux/of.h> 11 #include <linux/platform_device.h> 12 #include <linux/pm_domain.h> 13 #include <linux/regulator/consumer.h> 14 #include <linux/soc/mediatek/infracfg.h> 15 16 #include <dt-bindings/power/mt2701-power.h> 17 #include <dt-bindings/power/mt2712-power.h> 18 #include <dt-bindings/power/mt6797-power.h> 19 #include <dt-bindings/power/mt7622-power.h> 20 #include <dt-bindings/power/mt7623a-power.h> 21 #include <dt-bindings/power/mt8173-power.h> 22 23 #define MTK_POLL_DELAY_US 10 24 #define MTK_POLL_TIMEOUT USEC_PER_SEC 25 26 #define MTK_SCPD_ACTIVE_WAKEUP BIT(0) 27 #define MTK_SCPD_FWAIT_SRAM BIT(1) 28 #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) 29 30 #define SPM_VDE_PWR_CON 0x0210 31 #define SPM_MFG_PWR_CON 0x0214 32 #define SPM_VEN_PWR_CON 0x0230 33 #define SPM_ISP_PWR_CON 0x0238 34 #define SPM_DIS_PWR_CON 0x023c 35 #define SPM_CONN_PWR_CON 0x0280 36 #define SPM_VEN2_PWR_CON 0x0298 37 #define SPM_AUDIO_PWR_CON 0x029c /* MT8173, MT2712 */ 38 #define SPM_BDP_PWR_CON 0x029c /* MT2701 */ 39 #define SPM_ETH_PWR_CON 0x02a0 40 #define SPM_HIF_PWR_CON 0x02a4 41 #define SPM_IFR_MSC_PWR_CON 0x02a8 42 #define SPM_MFG_2D_PWR_CON 0x02c0 43 #define SPM_MFG_ASYNC_PWR_CON 0x02c4 44 #define SPM_USB_PWR_CON 0x02cc 45 #define SPM_USB2_PWR_CON 0x02d4 /* MT2712 */ 46 #define SPM_ETHSYS_PWR_CON 0x02e0 /* MT7622 */ 47 #define SPM_HIF0_PWR_CON 0x02e4 /* MT7622 */ 48 #define SPM_HIF1_PWR_CON 0x02e8 /* MT7622 */ 49 #define SPM_WB_PWR_CON 0x02ec /* MT7622 */ 50 51 #define SPM_PWR_STATUS 0x060c 52 #define SPM_PWR_STATUS_2ND 0x0610 53 54 #define PWR_RST_B_BIT BIT(0) 55 #define PWR_ISO_BIT BIT(1) 56 #define PWR_ON_BIT BIT(2) 57 #define PWR_ON_2ND_BIT BIT(3) 58 #define PWR_CLK_DIS_BIT BIT(4) 59 60 #define PWR_STATUS_CONN BIT(1) 61 #define PWR_STATUS_DISP BIT(3) 62 #define PWR_STATUS_MFG BIT(4) 63 #define PWR_STATUS_ISP BIT(5) 64 #define PWR_STATUS_VDEC BIT(7) 65 #define PWR_STATUS_BDP BIT(14) 66 #define PWR_STATUS_ETH BIT(15) 67 #define PWR_STATUS_HIF BIT(16) 68 #define PWR_STATUS_IFR_MSC BIT(17) 69 #define PWR_STATUS_USB2 BIT(19) /* MT2712 */ 70 #define PWR_STATUS_VENC_LT BIT(20) 71 #define PWR_STATUS_VENC BIT(21) 72 #define PWR_STATUS_MFG_2D BIT(22) /* MT8173 */ 73 #define PWR_STATUS_MFG_ASYNC BIT(23) /* MT8173 */ 74 #define PWR_STATUS_AUDIO BIT(24) /* MT8173, MT2712 */ 75 #define PWR_STATUS_USB BIT(25) /* MT8173, MT2712 */ 76 #define PWR_STATUS_ETHSYS BIT(24) /* MT7622 */ 77 #define PWR_STATUS_HIF0 BIT(25) /* MT7622 */ 78 #define PWR_STATUS_HIF1 BIT(26) /* MT7622 */ 79 #define PWR_STATUS_WB BIT(27) /* MT7622 */ 80 81 enum clk_id { 82 CLK_NONE, 83 CLK_MM, 84 CLK_MFG, 85 CLK_VENC, 86 CLK_VENC_LT, 87 CLK_ETHIF, 88 CLK_VDEC, 89 CLK_HIFSEL, 90 CLK_JPGDEC, 91 CLK_AUDIO, 92 CLK_MAX, 93 }; 94 95 static const char * const clk_names[] = { 96 NULL, 97 "mm", 98 "mfg", 99 "venc", 100 "venc_lt", 101 "ethif", 102 "vdec", 103 "hif_sel", 104 "jpgdec", 105 "audio", 106 NULL, 107 }; 108 109 #define MAX_CLKS 3 110 111 /** 112 * struct scp_domain_data - scp domain data for power on/off flow 113 * @name: The domain name. 114 * @sta_mask: The mask for power on/off status bit. 115 * @ctl_offs: The offset for main power control register. 116 * @sram_pdn_bits: The mask for sram power control bits. 117 * @sram_pdn_ack_bits: The mask for sram power control acked bits. 118 * @bus_prot_mask: The mask for single step bus protection. 119 * @clk_id: The basic clocks required by this power domain. 120 * @caps: The flag for active wake-up action. 121 */ 122 struct scp_domain_data { 123 const char *name; 124 u32 sta_mask; 125 int ctl_offs; 126 u32 sram_pdn_bits; 127 u32 sram_pdn_ack_bits; 128 u32 bus_prot_mask; 129 enum clk_id clk_id[MAX_CLKS]; 130 u8 caps; 131 }; 132 133 struct scp; 134 135 struct scp_domain { 136 struct generic_pm_domain genpd; 137 struct scp *scp; 138 struct clk *clk[MAX_CLKS]; 139 const struct scp_domain_data *data; 140 struct regulator *supply; 141 }; 142 143 struct scp_ctrl_reg { 144 int pwr_sta_offs; 145 int pwr_sta2nd_offs; 146 }; 147 148 struct scp { 149 struct scp_domain *domains; 150 struct genpd_onecell_data pd_data; 151 struct device *dev; 152 void __iomem *base; 153 struct regmap *infracfg; 154 struct scp_ctrl_reg ctrl_reg; 155 bool bus_prot_reg_update; 156 }; 157 158 struct scp_subdomain { 159 int origin; 160 int subdomain; 161 }; 162 163 struct scp_soc_data { 164 const struct scp_domain_data *domains; 165 int num_domains; 166 const struct scp_subdomain *subdomains; 167 int num_subdomains; 168 const struct scp_ctrl_reg regs; 169 bool bus_prot_reg_update; 170 }; 171 172 static int scpsys_domain_is_on(struct scp_domain *scpd) 173 { 174 struct scp *scp = scpd->scp; 175 176 u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) & 177 scpd->data->sta_mask; 178 u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) & 179 scpd->data->sta_mask; 180 181 /* 182 * A domain is on when both status bits are set. If only one is set 183 * return an error. This happens while powering up a domain 184 */ 185 186 if (status && status2) 187 return true; 188 if (!status && !status2) 189 return false; 190 191 return -EINVAL; 192 } 193 194 static int scpsys_regulator_enable(struct scp_domain *scpd) 195 { 196 if (!scpd->supply) 197 return 0; 198 199 return regulator_enable(scpd->supply); 200 } 201 202 static int scpsys_regulator_disable(struct scp_domain *scpd) 203 { 204 if (!scpd->supply) 205 return 0; 206 207 return regulator_disable(scpd->supply); 208 } 209 210 static void scpsys_clk_disable(struct clk *clk[], int max_num) 211 { 212 int i; 213 214 for (i = max_num - 1; i >= 0; i--) 215 clk_disable_unprepare(clk[i]); 216 } 217 218 static int scpsys_clk_enable(struct clk *clk[], int max_num) 219 { 220 int i, ret = 0; 221 222 for (i = 0; i < max_num && clk[i]; i++) { 223 ret = clk_prepare_enable(clk[i]); 224 if (ret) { 225 scpsys_clk_disable(clk, i); 226 break; 227 } 228 } 229 230 return ret; 231 } 232 233 static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr) 234 { 235 u32 val; 236 u32 pdn_ack = scpd->data->sram_pdn_ack_bits; 237 int tmp; 238 239 val = readl(ctl_addr); 240 val &= ~scpd->data->sram_pdn_bits; 241 writel(val, ctl_addr); 242 243 /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */ 244 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) { 245 /* 246 * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for 247 * MT7622_POWER_DOMAIN_WB and thus just a trivial setup 248 * is applied here. 249 */ 250 usleep_range(12000, 12100); 251 } else { 252 /* Either wait until SRAM_PDN_ACK all 1 or 0 */ 253 int ret = readl_poll_timeout(ctl_addr, tmp, 254 (tmp & pdn_ack) == 0, 255 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 256 if (ret < 0) 257 return ret; 258 } 259 260 return 0; 261 } 262 263 static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr) 264 { 265 u32 val; 266 u32 pdn_ack = scpd->data->sram_pdn_ack_bits; 267 int tmp; 268 269 val = readl(ctl_addr); 270 val |= scpd->data->sram_pdn_bits; 271 writel(val, ctl_addr); 272 273 /* Either wait until SRAM_PDN_ACK all 1 or 0 */ 274 return readl_poll_timeout(ctl_addr, tmp, 275 (tmp & pdn_ack) == pdn_ack, 276 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 277 } 278 279 static int scpsys_bus_protect_enable(struct scp_domain *scpd) 280 { 281 struct scp *scp = scpd->scp; 282 283 if (!scpd->data->bus_prot_mask) 284 return 0; 285 286 return mtk_infracfg_set_bus_protection(scp->infracfg, 287 scpd->data->bus_prot_mask, 288 scp->bus_prot_reg_update); 289 } 290 291 static int scpsys_bus_protect_disable(struct scp_domain *scpd) 292 { 293 struct scp *scp = scpd->scp; 294 295 if (!scpd->data->bus_prot_mask) 296 return 0; 297 298 return mtk_infracfg_clear_bus_protection(scp->infracfg, 299 scpd->data->bus_prot_mask, 300 scp->bus_prot_reg_update); 301 } 302 303 static int scpsys_power_on(struct generic_pm_domain *genpd) 304 { 305 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); 306 struct scp *scp = scpd->scp; 307 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; 308 u32 val; 309 int ret, tmp; 310 311 ret = scpsys_regulator_enable(scpd); 312 if (ret < 0) 313 return ret; 314 315 ret = scpsys_clk_enable(scpd->clk, MAX_CLKS); 316 if (ret) 317 goto err_clk; 318 319 /* subsys power on */ 320 val = readl(ctl_addr); 321 val |= PWR_ON_BIT; 322 writel(val, ctl_addr); 323 val |= PWR_ON_2ND_BIT; 324 writel(val, ctl_addr); 325 326 /* wait until PWR_ACK = 1 */ 327 ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0, 328 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 329 if (ret < 0) 330 goto err_pwr_ack; 331 332 val &= ~PWR_CLK_DIS_BIT; 333 writel(val, ctl_addr); 334 335 val &= ~PWR_ISO_BIT; 336 writel(val, ctl_addr); 337 338 val |= PWR_RST_B_BIT; 339 writel(val, ctl_addr); 340 341 ret = scpsys_sram_enable(scpd, ctl_addr); 342 if (ret < 0) 343 goto err_pwr_ack; 344 345 ret = scpsys_bus_protect_disable(scpd); 346 if (ret < 0) 347 goto err_pwr_ack; 348 349 return 0; 350 351 err_pwr_ack: 352 scpsys_clk_disable(scpd->clk, MAX_CLKS); 353 err_clk: 354 scpsys_regulator_disable(scpd); 355 356 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); 357 358 return ret; 359 } 360 361 static int scpsys_power_off(struct generic_pm_domain *genpd) 362 { 363 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); 364 struct scp *scp = scpd->scp; 365 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs; 366 u32 val; 367 int ret, tmp; 368 369 ret = scpsys_bus_protect_enable(scpd); 370 if (ret < 0) 371 goto out; 372 373 ret = scpsys_sram_disable(scpd, ctl_addr); 374 if (ret < 0) 375 goto out; 376 377 /* subsys power off */ 378 val = readl(ctl_addr); 379 val |= PWR_ISO_BIT; 380 writel(val, ctl_addr); 381 382 val &= ~PWR_RST_B_BIT; 383 writel(val, ctl_addr); 384 385 val |= PWR_CLK_DIS_BIT; 386 writel(val, ctl_addr); 387 388 val &= ~PWR_ON_BIT; 389 writel(val, ctl_addr); 390 391 val &= ~PWR_ON_2ND_BIT; 392 writel(val, ctl_addr); 393 394 /* wait until PWR_ACK = 0 */ 395 ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0, 396 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 397 if (ret < 0) 398 goto out; 399 400 scpsys_clk_disable(scpd->clk, MAX_CLKS); 401 402 ret = scpsys_regulator_disable(scpd); 403 if (ret < 0) 404 goto out; 405 406 return 0; 407 408 out: 409 dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name); 410 411 return ret; 412 } 413 414 static void init_clks(struct platform_device *pdev, struct clk **clk) 415 { 416 int i; 417 418 for (i = CLK_NONE + 1; i < CLK_MAX; i++) 419 clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); 420 } 421 422 static struct scp *init_scp(struct platform_device *pdev, 423 const struct scp_domain_data *scp_domain_data, int num, 424 const struct scp_ctrl_reg *scp_ctrl_reg, 425 bool bus_prot_reg_update) 426 { 427 struct genpd_onecell_data *pd_data; 428 int i, j; 429 struct scp *scp; 430 struct clk *clk[CLK_MAX]; 431 432 scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); 433 if (!scp) 434 return ERR_PTR(-ENOMEM); 435 436 scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs; 437 scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs; 438 439 scp->bus_prot_reg_update = bus_prot_reg_update; 440 441 scp->dev = &pdev->dev; 442 443 scp->base = devm_platform_ioremap_resource(pdev, 0); 444 if (IS_ERR(scp->base)) 445 return ERR_CAST(scp->base); 446 447 scp->domains = devm_kcalloc(&pdev->dev, 448 num, sizeof(*scp->domains), GFP_KERNEL); 449 if (!scp->domains) 450 return ERR_PTR(-ENOMEM); 451 452 pd_data = &scp->pd_data; 453 454 pd_data->domains = devm_kcalloc(&pdev->dev, 455 num, sizeof(*pd_data->domains), GFP_KERNEL); 456 if (!pd_data->domains) 457 return ERR_PTR(-ENOMEM); 458 459 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 460 "infracfg"); 461 if (IS_ERR(scp->infracfg)) { 462 dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", 463 PTR_ERR(scp->infracfg)); 464 return ERR_CAST(scp->infracfg); 465 } 466 467 for (i = 0; i < num; i++) { 468 struct scp_domain *scpd = &scp->domains[i]; 469 const struct scp_domain_data *data = &scp_domain_data[i]; 470 471 scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name); 472 if (IS_ERR(scpd->supply)) { 473 if (PTR_ERR(scpd->supply) == -ENODEV) 474 scpd->supply = NULL; 475 else 476 return ERR_CAST(scpd->supply); 477 } 478 } 479 480 pd_data->num_domains = num; 481 482 init_clks(pdev, clk); 483 484 for (i = 0; i < num; i++) { 485 struct scp_domain *scpd = &scp->domains[i]; 486 struct generic_pm_domain *genpd = &scpd->genpd; 487 const struct scp_domain_data *data = &scp_domain_data[i]; 488 489 pd_data->domains[i] = genpd; 490 scpd->scp = scp; 491 492 scpd->data = data; 493 494 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) { 495 struct clk *c = clk[data->clk_id[j]]; 496 497 if (IS_ERR(c)) { 498 dev_err(&pdev->dev, "%s: clk unavailable\n", 499 data->name); 500 return ERR_CAST(c); 501 } 502 503 scpd->clk[j] = c; 504 } 505 506 genpd->name = data->name; 507 genpd->power_off = scpsys_power_off; 508 genpd->power_on = scpsys_power_on; 509 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP)) 510 genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; 511 } 512 513 return scp; 514 } 515 516 static void mtk_register_power_domains(struct platform_device *pdev, 517 struct scp *scp, int num) 518 { 519 struct genpd_onecell_data *pd_data; 520 int i, ret; 521 522 for (i = 0; i < num; i++) { 523 struct scp_domain *scpd = &scp->domains[i]; 524 struct generic_pm_domain *genpd = &scpd->genpd; 525 bool on; 526 527 /* 528 * Initially turn on all domains to make the domains usable 529 * with !CONFIG_PM and to get the hardware in sync with the 530 * software. The unused domains will be switched off during 531 * late_init time. 532 */ 533 on = !WARN_ON(genpd->power_on(genpd) < 0); 534 535 pm_genpd_init(genpd, NULL, !on); 536 } 537 538 /* 539 * We are not allowed to fail here since there is no way to unregister 540 * a power domain. Once registered above we have to keep the domains 541 * valid. 542 */ 543 544 pd_data = &scp->pd_data; 545 546 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data); 547 if (ret) 548 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret); 549 } 550 551 /* 552 * MT2701 power domain support 553 */ 554 555 static const struct scp_domain_data scp_domain_data_mt2701[] = { 556 [MT2701_POWER_DOMAIN_CONN] = { 557 .name = "conn", 558 .sta_mask = PWR_STATUS_CONN, 559 .ctl_offs = SPM_CONN_PWR_CON, 560 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 561 MT2701_TOP_AXI_PROT_EN_CONN_S, 562 .clk_id = {CLK_NONE}, 563 .caps = MTK_SCPD_ACTIVE_WAKEUP, 564 }, 565 [MT2701_POWER_DOMAIN_DISP] = { 566 .name = "disp", 567 .sta_mask = PWR_STATUS_DISP, 568 .ctl_offs = SPM_DIS_PWR_CON, 569 .sram_pdn_bits = GENMASK(11, 8), 570 .clk_id = {CLK_MM}, 571 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0, 572 .caps = MTK_SCPD_ACTIVE_WAKEUP, 573 }, 574 [MT2701_POWER_DOMAIN_MFG] = { 575 .name = "mfg", 576 .sta_mask = PWR_STATUS_MFG, 577 .ctl_offs = SPM_MFG_PWR_CON, 578 .sram_pdn_bits = GENMASK(11, 8), 579 .sram_pdn_ack_bits = GENMASK(12, 12), 580 .clk_id = {CLK_MFG}, 581 .caps = MTK_SCPD_ACTIVE_WAKEUP, 582 }, 583 [MT2701_POWER_DOMAIN_VDEC] = { 584 .name = "vdec", 585 .sta_mask = PWR_STATUS_VDEC, 586 .ctl_offs = SPM_VDE_PWR_CON, 587 .sram_pdn_bits = GENMASK(11, 8), 588 .sram_pdn_ack_bits = GENMASK(12, 12), 589 .clk_id = {CLK_MM}, 590 .caps = MTK_SCPD_ACTIVE_WAKEUP, 591 }, 592 [MT2701_POWER_DOMAIN_ISP] = { 593 .name = "isp", 594 .sta_mask = PWR_STATUS_ISP, 595 .ctl_offs = SPM_ISP_PWR_CON, 596 .sram_pdn_bits = GENMASK(11, 8), 597 .sram_pdn_ack_bits = GENMASK(13, 12), 598 .clk_id = {CLK_MM}, 599 .caps = MTK_SCPD_ACTIVE_WAKEUP, 600 }, 601 [MT2701_POWER_DOMAIN_BDP] = { 602 .name = "bdp", 603 .sta_mask = PWR_STATUS_BDP, 604 .ctl_offs = SPM_BDP_PWR_CON, 605 .sram_pdn_bits = GENMASK(11, 8), 606 .clk_id = {CLK_NONE}, 607 .caps = MTK_SCPD_ACTIVE_WAKEUP, 608 }, 609 [MT2701_POWER_DOMAIN_ETH] = { 610 .name = "eth", 611 .sta_mask = PWR_STATUS_ETH, 612 .ctl_offs = SPM_ETH_PWR_CON, 613 .sram_pdn_bits = GENMASK(11, 8), 614 .sram_pdn_ack_bits = GENMASK(15, 12), 615 .clk_id = {CLK_ETHIF}, 616 .caps = MTK_SCPD_ACTIVE_WAKEUP, 617 }, 618 [MT2701_POWER_DOMAIN_HIF] = { 619 .name = "hif", 620 .sta_mask = PWR_STATUS_HIF, 621 .ctl_offs = SPM_HIF_PWR_CON, 622 .sram_pdn_bits = GENMASK(11, 8), 623 .sram_pdn_ack_bits = GENMASK(15, 12), 624 .clk_id = {CLK_ETHIF}, 625 .caps = MTK_SCPD_ACTIVE_WAKEUP, 626 }, 627 [MT2701_POWER_DOMAIN_IFR_MSC] = { 628 .name = "ifr_msc", 629 .sta_mask = PWR_STATUS_IFR_MSC, 630 .ctl_offs = SPM_IFR_MSC_PWR_CON, 631 .clk_id = {CLK_NONE}, 632 .caps = MTK_SCPD_ACTIVE_WAKEUP, 633 }, 634 }; 635 636 /* 637 * MT2712 power domain support 638 */ 639 static const struct scp_domain_data scp_domain_data_mt2712[] = { 640 [MT2712_POWER_DOMAIN_MM] = { 641 .name = "mm", 642 .sta_mask = PWR_STATUS_DISP, 643 .ctl_offs = SPM_DIS_PWR_CON, 644 .sram_pdn_bits = GENMASK(8, 8), 645 .sram_pdn_ack_bits = GENMASK(12, 12), 646 .clk_id = {CLK_MM}, 647 .caps = MTK_SCPD_ACTIVE_WAKEUP, 648 }, 649 [MT2712_POWER_DOMAIN_VDEC] = { 650 .name = "vdec", 651 .sta_mask = PWR_STATUS_VDEC, 652 .ctl_offs = SPM_VDE_PWR_CON, 653 .sram_pdn_bits = GENMASK(8, 8), 654 .sram_pdn_ack_bits = GENMASK(12, 12), 655 .clk_id = {CLK_MM, CLK_VDEC}, 656 .caps = MTK_SCPD_ACTIVE_WAKEUP, 657 }, 658 [MT2712_POWER_DOMAIN_VENC] = { 659 .name = "venc", 660 .sta_mask = PWR_STATUS_VENC, 661 .ctl_offs = SPM_VEN_PWR_CON, 662 .sram_pdn_bits = GENMASK(11, 8), 663 .sram_pdn_ack_bits = GENMASK(15, 12), 664 .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC}, 665 .caps = MTK_SCPD_ACTIVE_WAKEUP, 666 }, 667 [MT2712_POWER_DOMAIN_ISP] = { 668 .name = "isp", 669 .sta_mask = PWR_STATUS_ISP, 670 .ctl_offs = SPM_ISP_PWR_CON, 671 .sram_pdn_bits = GENMASK(11, 8), 672 .sram_pdn_ack_bits = GENMASK(13, 12), 673 .clk_id = {CLK_MM}, 674 .caps = MTK_SCPD_ACTIVE_WAKEUP, 675 }, 676 [MT2712_POWER_DOMAIN_AUDIO] = { 677 .name = "audio", 678 .sta_mask = PWR_STATUS_AUDIO, 679 .ctl_offs = SPM_AUDIO_PWR_CON, 680 .sram_pdn_bits = GENMASK(11, 8), 681 .sram_pdn_ack_bits = GENMASK(15, 12), 682 .clk_id = {CLK_AUDIO}, 683 .caps = MTK_SCPD_ACTIVE_WAKEUP, 684 }, 685 [MT2712_POWER_DOMAIN_USB] = { 686 .name = "usb", 687 .sta_mask = PWR_STATUS_USB, 688 .ctl_offs = SPM_USB_PWR_CON, 689 .sram_pdn_bits = GENMASK(10, 8), 690 .sram_pdn_ack_bits = GENMASK(14, 12), 691 .clk_id = {CLK_NONE}, 692 .caps = MTK_SCPD_ACTIVE_WAKEUP, 693 }, 694 [MT2712_POWER_DOMAIN_USB2] = { 695 .name = "usb2", 696 .sta_mask = PWR_STATUS_USB2, 697 .ctl_offs = SPM_USB2_PWR_CON, 698 .sram_pdn_bits = GENMASK(10, 8), 699 .sram_pdn_ack_bits = GENMASK(14, 12), 700 .clk_id = {CLK_NONE}, 701 .caps = MTK_SCPD_ACTIVE_WAKEUP, 702 }, 703 [MT2712_POWER_DOMAIN_MFG] = { 704 .name = "mfg", 705 .sta_mask = PWR_STATUS_MFG, 706 .ctl_offs = SPM_MFG_PWR_CON, 707 .sram_pdn_bits = GENMASK(8, 8), 708 .sram_pdn_ack_bits = GENMASK(16, 16), 709 .clk_id = {CLK_MFG}, 710 .bus_prot_mask = BIT(14) | BIT(21) | BIT(23), 711 .caps = MTK_SCPD_ACTIVE_WAKEUP, 712 }, 713 [MT2712_POWER_DOMAIN_MFG_SC1] = { 714 .name = "mfg_sc1", 715 .sta_mask = BIT(22), 716 .ctl_offs = 0x02c0, 717 .sram_pdn_bits = GENMASK(8, 8), 718 .sram_pdn_ack_bits = GENMASK(16, 16), 719 .clk_id = {CLK_NONE}, 720 .caps = MTK_SCPD_ACTIVE_WAKEUP, 721 }, 722 [MT2712_POWER_DOMAIN_MFG_SC2] = { 723 .name = "mfg_sc2", 724 .sta_mask = BIT(23), 725 .ctl_offs = 0x02c4, 726 .sram_pdn_bits = GENMASK(8, 8), 727 .sram_pdn_ack_bits = GENMASK(16, 16), 728 .clk_id = {CLK_NONE}, 729 .caps = MTK_SCPD_ACTIVE_WAKEUP, 730 }, 731 [MT2712_POWER_DOMAIN_MFG_SC3] = { 732 .name = "mfg_sc3", 733 .sta_mask = BIT(30), 734 .ctl_offs = 0x01f8, 735 .sram_pdn_bits = GENMASK(8, 8), 736 .sram_pdn_ack_bits = GENMASK(16, 16), 737 .clk_id = {CLK_NONE}, 738 .caps = MTK_SCPD_ACTIVE_WAKEUP, 739 }, 740 }; 741 742 static const struct scp_subdomain scp_subdomain_mt2712[] = { 743 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC}, 744 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC}, 745 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP}, 746 {MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1}, 747 {MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2}, 748 {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3}, 749 }; 750 751 /* 752 * MT6797 power domain support 753 */ 754 755 static const struct scp_domain_data scp_domain_data_mt6797[] = { 756 [MT6797_POWER_DOMAIN_VDEC] = { 757 .name = "vdec", 758 .sta_mask = BIT(7), 759 .ctl_offs = 0x300, 760 .sram_pdn_bits = GENMASK(8, 8), 761 .sram_pdn_ack_bits = GENMASK(12, 12), 762 .clk_id = {CLK_VDEC}, 763 }, 764 [MT6797_POWER_DOMAIN_VENC] = { 765 .name = "venc", 766 .sta_mask = BIT(21), 767 .ctl_offs = 0x304, 768 .sram_pdn_bits = GENMASK(11, 8), 769 .sram_pdn_ack_bits = GENMASK(15, 12), 770 .clk_id = {CLK_NONE}, 771 }, 772 [MT6797_POWER_DOMAIN_ISP] = { 773 .name = "isp", 774 .sta_mask = BIT(5), 775 .ctl_offs = 0x308, 776 .sram_pdn_bits = GENMASK(9, 8), 777 .sram_pdn_ack_bits = GENMASK(13, 12), 778 .clk_id = {CLK_NONE}, 779 }, 780 [MT6797_POWER_DOMAIN_MM] = { 781 .name = "mm", 782 .sta_mask = BIT(3), 783 .ctl_offs = 0x30C, 784 .sram_pdn_bits = GENMASK(8, 8), 785 .sram_pdn_ack_bits = GENMASK(12, 12), 786 .clk_id = {CLK_MM}, 787 .bus_prot_mask = (BIT(1) | BIT(2)), 788 }, 789 [MT6797_POWER_DOMAIN_AUDIO] = { 790 .name = "audio", 791 .sta_mask = BIT(24), 792 .ctl_offs = 0x314, 793 .sram_pdn_bits = GENMASK(11, 8), 794 .sram_pdn_ack_bits = GENMASK(15, 12), 795 .clk_id = {CLK_NONE}, 796 }, 797 [MT6797_POWER_DOMAIN_MFG_ASYNC] = { 798 .name = "mfg_async", 799 .sta_mask = BIT(13), 800 .ctl_offs = 0x334, 801 .sram_pdn_bits = 0, 802 .sram_pdn_ack_bits = 0, 803 .clk_id = {CLK_MFG}, 804 }, 805 [MT6797_POWER_DOMAIN_MJC] = { 806 .name = "mjc", 807 .sta_mask = BIT(20), 808 .ctl_offs = 0x310, 809 .sram_pdn_bits = GENMASK(8, 8), 810 .sram_pdn_ack_bits = GENMASK(12, 12), 811 .clk_id = {CLK_NONE}, 812 }, 813 }; 814 815 #define SPM_PWR_STATUS_MT6797 0x0180 816 #define SPM_PWR_STATUS_2ND_MT6797 0x0184 817 818 static const struct scp_subdomain scp_subdomain_mt6797[] = { 819 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC}, 820 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP}, 821 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC}, 822 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC}, 823 }; 824 825 /* 826 * MT7622 power domain support 827 */ 828 829 static const struct scp_domain_data scp_domain_data_mt7622[] = { 830 [MT7622_POWER_DOMAIN_ETHSYS] = { 831 .name = "ethsys", 832 .sta_mask = PWR_STATUS_ETHSYS, 833 .ctl_offs = SPM_ETHSYS_PWR_CON, 834 .sram_pdn_bits = GENMASK(11, 8), 835 .sram_pdn_ack_bits = GENMASK(15, 12), 836 .clk_id = {CLK_NONE}, 837 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS, 838 .caps = MTK_SCPD_ACTIVE_WAKEUP, 839 }, 840 [MT7622_POWER_DOMAIN_HIF0] = { 841 .name = "hif0", 842 .sta_mask = PWR_STATUS_HIF0, 843 .ctl_offs = SPM_HIF0_PWR_CON, 844 .sram_pdn_bits = GENMASK(11, 8), 845 .sram_pdn_ack_bits = GENMASK(15, 12), 846 .clk_id = {CLK_HIFSEL}, 847 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0, 848 .caps = MTK_SCPD_ACTIVE_WAKEUP, 849 }, 850 [MT7622_POWER_DOMAIN_HIF1] = { 851 .name = "hif1", 852 .sta_mask = PWR_STATUS_HIF1, 853 .ctl_offs = SPM_HIF1_PWR_CON, 854 .sram_pdn_bits = GENMASK(11, 8), 855 .sram_pdn_ack_bits = GENMASK(15, 12), 856 .clk_id = {CLK_HIFSEL}, 857 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, 858 .caps = MTK_SCPD_ACTIVE_WAKEUP, 859 }, 860 [MT7622_POWER_DOMAIN_WB] = { 861 .name = "wb", 862 .sta_mask = PWR_STATUS_WB, 863 .ctl_offs = SPM_WB_PWR_CON, 864 .sram_pdn_bits = 0, 865 .sram_pdn_ack_bits = 0, 866 .clk_id = {CLK_NONE}, 867 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, 868 .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM, 869 }, 870 }; 871 872 /* 873 * MT7623A power domain support 874 */ 875 876 static const struct scp_domain_data scp_domain_data_mt7623a[] = { 877 [MT7623A_POWER_DOMAIN_CONN] = { 878 .name = "conn", 879 .sta_mask = PWR_STATUS_CONN, 880 .ctl_offs = SPM_CONN_PWR_CON, 881 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 882 MT2701_TOP_AXI_PROT_EN_CONN_S, 883 .clk_id = {CLK_NONE}, 884 .caps = MTK_SCPD_ACTIVE_WAKEUP, 885 }, 886 [MT7623A_POWER_DOMAIN_ETH] = { 887 .name = "eth", 888 .sta_mask = PWR_STATUS_ETH, 889 .ctl_offs = SPM_ETH_PWR_CON, 890 .sram_pdn_bits = GENMASK(11, 8), 891 .sram_pdn_ack_bits = GENMASK(15, 12), 892 .clk_id = {CLK_ETHIF}, 893 .caps = MTK_SCPD_ACTIVE_WAKEUP, 894 }, 895 [MT7623A_POWER_DOMAIN_HIF] = { 896 .name = "hif", 897 .sta_mask = PWR_STATUS_HIF, 898 .ctl_offs = SPM_HIF_PWR_CON, 899 .sram_pdn_bits = GENMASK(11, 8), 900 .sram_pdn_ack_bits = GENMASK(15, 12), 901 .clk_id = {CLK_ETHIF}, 902 .caps = MTK_SCPD_ACTIVE_WAKEUP, 903 }, 904 [MT7623A_POWER_DOMAIN_IFR_MSC] = { 905 .name = "ifr_msc", 906 .sta_mask = PWR_STATUS_IFR_MSC, 907 .ctl_offs = SPM_IFR_MSC_PWR_CON, 908 .clk_id = {CLK_NONE}, 909 .caps = MTK_SCPD_ACTIVE_WAKEUP, 910 }, 911 }; 912 913 /* 914 * MT8173 power domain support 915 */ 916 917 static const struct scp_domain_data scp_domain_data_mt8173[] = { 918 [MT8173_POWER_DOMAIN_VDEC] = { 919 .name = "vdec", 920 .sta_mask = PWR_STATUS_VDEC, 921 .ctl_offs = SPM_VDE_PWR_CON, 922 .sram_pdn_bits = GENMASK(11, 8), 923 .sram_pdn_ack_bits = GENMASK(12, 12), 924 .clk_id = {CLK_MM}, 925 }, 926 [MT8173_POWER_DOMAIN_VENC] = { 927 .name = "venc", 928 .sta_mask = PWR_STATUS_VENC, 929 .ctl_offs = SPM_VEN_PWR_CON, 930 .sram_pdn_bits = GENMASK(11, 8), 931 .sram_pdn_ack_bits = GENMASK(15, 12), 932 .clk_id = {CLK_MM, CLK_VENC}, 933 }, 934 [MT8173_POWER_DOMAIN_ISP] = { 935 .name = "isp", 936 .sta_mask = PWR_STATUS_ISP, 937 .ctl_offs = SPM_ISP_PWR_CON, 938 .sram_pdn_bits = GENMASK(11, 8), 939 .sram_pdn_ack_bits = GENMASK(13, 12), 940 .clk_id = {CLK_MM}, 941 }, 942 [MT8173_POWER_DOMAIN_MM] = { 943 .name = "mm", 944 .sta_mask = PWR_STATUS_DISP, 945 .ctl_offs = SPM_DIS_PWR_CON, 946 .sram_pdn_bits = GENMASK(11, 8), 947 .sram_pdn_ack_bits = GENMASK(12, 12), 948 .clk_id = {CLK_MM}, 949 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | 950 MT8173_TOP_AXI_PROT_EN_MM_M1, 951 }, 952 [MT8173_POWER_DOMAIN_VENC_LT] = { 953 .name = "venc_lt", 954 .sta_mask = PWR_STATUS_VENC_LT, 955 .ctl_offs = SPM_VEN2_PWR_CON, 956 .sram_pdn_bits = GENMASK(11, 8), 957 .sram_pdn_ack_bits = GENMASK(15, 12), 958 .clk_id = {CLK_MM, CLK_VENC_LT}, 959 }, 960 [MT8173_POWER_DOMAIN_AUDIO] = { 961 .name = "audio", 962 .sta_mask = PWR_STATUS_AUDIO, 963 .ctl_offs = SPM_AUDIO_PWR_CON, 964 .sram_pdn_bits = GENMASK(11, 8), 965 .sram_pdn_ack_bits = GENMASK(15, 12), 966 .clk_id = {CLK_NONE}, 967 }, 968 [MT8173_POWER_DOMAIN_USB] = { 969 .name = "usb", 970 .sta_mask = PWR_STATUS_USB, 971 .ctl_offs = SPM_USB_PWR_CON, 972 .sram_pdn_bits = GENMASK(11, 8), 973 .sram_pdn_ack_bits = GENMASK(15, 12), 974 .clk_id = {CLK_NONE}, 975 .caps = MTK_SCPD_ACTIVE_WAKEUP, 976 }, 977 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 978 .name = "mfg_async", 979 .sta_mask = PWR_STATUS_MFG_ASYNC, 980 .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 981 .sram_pdn_bits = GENMASK(11, 8), 982 .sram_pdn_ack_bits = 0, 983 .clk_id = {CLK_MFG}, 984 }, 985 [MT8173_POWER_DOMAIN_MFG_2D] = { 986 .name = "mfg_2d", 987 .sta_mask = PWR_STATUS_MFG_2D, 988 .ctl_offs = SPM_MFG_2D_PWR_CON, 989 .sram_pdn_bits = GENMASK(11, 8), 990 .sram_pdn_ack_bits = GENMASK(13, 12), 991 .clk_id = {CLK_NONE}, 992 }, 993 [MT8173_POWER_DOMAIN_MFG] = { 994 .name = "mfg", 995 .sta_mask = PWR_STATUS_MFG, 996 .ctl_offs = SPM_MFG_PWR_CON, 997 .sram_pdn_bits = GENMASK(13, 8), 998 .sram_pdn_ack_bits = GENMASK(21, 16), 999 .clk_id = {CLK_NONE}, 1000 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | 1001 MT8173_TOP_AXI_PROT_EN_MFG_M0 | 1002 MT8173_TOP_AXI_PROT_EN_MFG_M1 | 1003 MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT, 1004 }, 1005 }; 1006 1007 static const struct scp_subdomain scp_subdomain_mt8173[] = { 1008 {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D}, 1009 {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, 1010 }; 1011 1012 static const struct scp_soc_data mt2701_data = { 1013 .domains = scp_domain_data_mt2701, 1014 .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), 1015 .regs = { 1016 .pwr_sta_offs = SPM_PWR_STATUS, 1017 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1018 }, 1019 .bus_prot_reg_update = true, 1020 }; 1021 1022 static const struct scp_soc_data mt2712_data = { 1023 .domains = scp_domain_data_mt2712, 1024 .num_domains = ARRAY_SIZE(scp_domain_data_mt2712), 1025 .subdomains = scp_subdomain_mt2712, 1026 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712), 1027 .regs = { 1028 .pwr_sta_offs = SPM_PWR_STATUS, 1029 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1030 }, 1031 .bus_prot_reg_update = false, 1032 }; 1033 1034 static const struct scp_soc_data mt6797_data = { 1035 .domains = scp_domain_data_mt6797, 1036 .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), 1037 .subdomains = scp_subdomain_mt6797, 1038 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797), 1039 .regs = { 1040 .pwr_sta_offs = SPM_PWR_STATUS_MT6797, 1041 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 1042 }, 1043 .bus_prot_reg_update = true, 1044 }; 1045 1046 static const struct scp_soc_data mt7622_data = { 1047 .domains = scp_domain_data_mt7622, 1048 .num_domains = ARRAY_SIZE(scp_domain_data_mt7622), 1049 .regs = { 1050 .pwr_sta_offs = SPM_PWR_STATUS, 1051 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1052 }, 1053 .bus_prot_reg_update = true, 1054 }; 1055 1056 static const struct scp_soc_data mt7623a_data = { 1057 .domains = scp_domain_data_mt7623a, 1058 .num_domains = ARRAY_SIZE(scp_domain_data_mt7623a), 1059 .regs = { 1060 .pwr_sta_offs = SPM_PWR_STATUS, 1061 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1062 }, 1063 .bus_prot_reg_update = true, 1064 }; 1065 1066 static const struct scp_soc_data mt8173_data = { 1067 .domains = scp_domain_data_mt8173, 1068 .num_domains = ARRAY_SIZE(scp_domain_data_mt8173), 1069 .subdomains = scp_subdomain_mt8173, 1070 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173), 1071 .regs = { 1072 .pwr_sta_offs = SPM_PWR_STATUS, 1073 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1074 }, 1075 .bus_prot_reg_update = true, 1076 }; 1077 1078 /* 1079 * scpsys driver init 1080 */ 1081 1082 static const struct of_device_id of_scpsys_match_tbl[] = { 1083 { 1084 .compatible = "mediatek,mt2701-scpsys", 1085 .data = &mt2701_data, 1086 }, { 1087 .compatible = "mediatek,mt2712-scpsys", 1088 .data = &mt2712_data, 1089 }, { 1090 .compatible = "mediatek,mt6797-scpsys", 1091 .data = &mt6797_data, 1092 }, { 1093 .compatible = "mediatek,mt7622-scpsys", 1094 .data = &mt7622_data, 1095 }, { 1096 .compatible = "mediatek,mt7623a-scpsys", 1097 .data = &mt7623a_data, 1098 }, { 1099 .compatible = "mediatek,mt8173-scpsys", 1100 .data = &mt8173_data, 1101 }, { 1102 /* sentinel */ 1103 } 1104 }; 1105 1106 static int scpsys_probe(struct platform_device *pdev) 1107 { 1108 const struct scp_subdomain *sd; 1109 const struct scp_soc_data *soc; 1110 struct scp *scp; 1111 struct genpd_onecell_data *pd_data; 1112 int i, ret; 1113 1114 soc = of_device_get_match_data(&pdev->dev); 1115 1116 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs, 1117 soc->bus_prot_reg_update); 1118 if (IS_ERR(scp)) 1119 return PTR_ERR(scp); 1120 1121 mtk_register_power_domains(pdev, scp, soc->num_domains); 1122 1123 pd_data = &scp->pd_data; 1124 1125 for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { 1126 ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], 1127 pd_data->domains[sd->subdomain]); 1128 if (ret && IS_ENABLED(CONFIG_PM)) 1129 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", 1130 ret); 1131 } 1132 1133 return 0; 1134 } 1135 1136 static struct platform_driver scpsys_drv = { 1137 .probe = scpsys_probe, 1138 .driver = { 1139 .name = "mtk-scpsys", 1140 .suppress_bind_attrs = true, 1141 .of_match_table = of_scpsys_match_tbl, 1142 }, 1143 }; 1144 builtin_platform_driver(scpsys_drv); 1145