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 struct resource *res; 429 int i, j; 430 struct scp *scp; 431 struct clk *clk[CLK_MAX]; 432 433 scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); 434 if (!scp) 435 return ERR_PTR(-ENOMEM); 436 437 scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs; 438 scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs; 439 440 scp->bus_prot_reg_update = bus_prot_reg_update; 441 442 scp->dev = &pdev->dev; 443 444 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 445 scp->base = devm_ioremap_resource(&pdev->dev, res); 446 if (IS_ERR(scp->base)) 447 return ERR_CAST(scp->base); 448 449 scp->domains = devm_kcalloc(&pdev->dev, 450 num, sizeof(*scp->domains), GFP_KERNEL); 451 if (!scp->domains) 452 return ERR_PTR(-ENOMEM); 453 454 pd_data = &scp->pd_data; 455 456 pd_data->domains = devm_kcalloc(&pdev->dev, 457 num, sizeof(*pd_data->domains), GFP_KERNEL); 458 if (!pd_data->domains) 459 return ERR_PTR(-ENOMEM); 460 461 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, 462 "infracfg"); 463 if (IS_ERR(scp->infracfg)) { 464 dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", 465 PTR_ERR(scp->infracfg)); 466 return ERR_CAST(scp->infracfg); 467 } 468 469 for (i = 0; i < num; i++) { 470 struct scp_domain *scpd = &scp->domains[i]; 471 const struct scp_domain_data *data = &scp_domain_data[i]; 472 473 scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name); 474 if (IS_ERR(scpd->supply)) { 475 if (PTR_ERR(scpd->supply) == -ENODEV) 476 scpd->supply = NULL; 477 else 478 return ERR_CAST(scpd->supply); 479 } 480 } 481 482 pd_data->num_domains = num; 483 484 init_clks(pdev, clk); 485 486 for (i = 0; i < num; i++) { 487 struct scp_domain *scpd = &scp->domains[i]; 488 struct generic_pm_domain *genpd = &scpd->genpd; 489 const struct scp_domain_data *data = &scp_domain_data[i]; 490 491 pd_data->domains[i] = genpd; 492 scpd->scp = scp; 493 494 scpd->data = data; 495 496 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) { 497 struct clk *c = clk[data->clk_id[j]]; 498 499 if (IS_ERR(c)) { 500 dev_err(&pdev->dev, "%s: clk unavailable\n", 501 data->name); 502 return ERR_CAST(c); 503 } 504 505 scpd->clk[j] = c; 506 } 507 508 genpd->name = data->name; 509 genpd->power_off = scpsys_power_off; 510 genpd->power_on = scpsys_power_on; 511 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP)) 512 genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; 513 } 514 515 return scp; 516 } 517 518 static void mtk_register_power_domains(struct platform_device *pdev, 519 struct scp *scp, int num) 520 { 521 struct genpd_onecell_data *pd_data; 522 int i, ret; 523 524 for (i = 0; i < num; i++) { 525 struct scp_domain *scpd = &scp->domains[i]; 526 struct generic_pm_domain *genpd = &scpd->genpd; 527 bool on; 528 529 /* 530 * Initially turn on all domains to make the domains usable 531 * with !CONFIG_PM and to get the hardware in sync with the 532 * software. The unused domains will be switched off during 533 * late_init time. 534 */ 535 on = !WARN_ON(genpd->power_on(genpd) < 0); 536 537 pm_genpd_init(genpd, NULL, !on); 538 } 539 540 /* 541 * We are not allowed to fail here since there is no way to unregister 542 * a power domain. Once registered above we have to keep the domains 543 * valid. 544 */ 545 546 pd_data = &scp->pd_data; 547 548 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data); 549 if (ret) 550 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret); 551 } 552 553 /* 554 * MT2701 power domain support 555 */ 556 557 static const struct scp_domain_data scp_domain_data_mt2701[] = { 558 [MT2701_POWER_DOMAIN_CONN] = { 559 .name = "conn", 560 .sta_mask = PWR_STATUS_CONN, 561 .ctl_offs = SPM_CONN_PWR_CON, 562 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 563 MT2701_TOP_AXI_PROT_EN_CONN_S, 564 .clk_id = {CLK_NONE}, 565 .caps = MTK_SCPD_ACTIVE_WAKEUP, 566 }, 567 [MT2701_POWER_DOMAIN_DISP] = { 568 .name = "disp", 569 .sta_mask = PWR_STATUS_DISP, 570 .ctl_offs = SPM_DIS_PWR_CON, 571 .sram_pdn_bits = GENMASK(11, 8), 572 .clk_id = {CLK_MM}, 573 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0, 574 .caps = MTK_SCPD_ACTIVE_WAKEUP, 575 }, 576 [MT2701_POWER_DOMAIN_MFG] = { 577 .name = "mfg", 578 .sta_mask = PWR_STATUS_MFG, 579 .ctl_offs = SPM_MFG_PWR_CON, 580 .sram_pdn_bits = GENMASK(11, 8), 581 .sram_pdn_ack_bits = GENMASK(12, 12), 582 .clk_id = {CLK_MFG}, 583 .caps = MTK_SCPD_ACTIVE_WAKEUP, 584 }, 585 [MT2701_POWER_DOMAIN_VDEC] = { 586 .name = "vdec", 587 .sta_mask = PWR_STATUS_VDEC, 588 .ctl_offs = SPM_VDE_PWR_CON, 589 .sram_pdn_bits = GENMASK(11, 8), 590 .sram_pdn_ack_bits = GENMASK(12, 12), 591 .clk_id = {CLK_MM}, 592 .caps = MTK_SCPD_ACTIVE_WAKEUP, 593 }, 594 [MT2701_POWER_DOMAIN_ISP] = { 595 .name = "isp", 596 .sta_mask = PWR_STATUS_ISP, 597 .ctl_offs = SPM_ISP_PWR_CON, 598 .sram_pdn_bits = GENMASK(11, 8), 599 .sram_pdn_ack_bits = GENMASK(13, 12), 600 .clk_id = {CLK_MM}, 601 .caps = MTK_SCPD_ACTIVE_WAKEUP, 602 }, 603 [MT2701_POWER_DOMAIN_BDP] = { 604 .name = "bdp", 605 .sta_mask = PWR_STATUS_BDP, 606 .ctl_offs = SPM_BDP_PWR_CON, 607 .sram_pdn_bits = GENMASK(11, 8), 608 .clk_id = {CLK_NONE}, 609 .caps = MTK_SCPD_ACTIVE_WAKEUP, 610 }, 611 [MT2701_POWER_DOMAIN_ETH] = { 612 .name = "eth", 613 .sta_mask = PWR_STATUS_ETH, 614 .ctl_offs = SPM_ETH_PWR_CON, 615 .sram_pdn_bits = GENMASK(11, 8), 616 .sram_pdn_ack_bits = GENMASK(15, 12), 617 .clk_id = {CLK_ETHIF}, 618 .caps = MTK_SCPD_ACTIVE_WAKEUP, 619 }, 620 [MT2701_POWER_DOMAIN_HIF] = { 621 .name = "hif", 622 .sta_mask = PWR_STATUS_HIF, 623 .ctl_offs = SPM_HIF_PWR_CON, 624 .sram_pdn_bits = GENMASK(11, 8), 625 .sram_pdn_ack_bits = GENMASK(15, 12), 626 .clk_id = {CLK_ETHIF}, 627 .caps = MTK_SCPD_ACTIVE_WAKEUP, 628 }, 629 [MT2701_POWER_DOMAIN_IFR_MSC] = { 630 .name = "ifr_msc", 631 .sta_mask = PWR_STATUS_IFR_MSC, 632 .ctl_offs = SPM_IFR_MSC_PWR_CON, 633 .clk_id = {CLK_NONE}, 634 .caps = MTK_SCPD_ACTIVE_WAKEUP, 635 }, 636 }; 637 638 /* 639 * MT2712 power domain support 640 */ 641 static const struct scp_domain_data scp_domain_data_mt2712[] = { 642 [MT2712_POWER_DOMAIN_MM] = { 643 .name = "mm", 644 .sta_mask = PWR_STATUS_DISP, 645 .ctl_offs = SPM_DIS_PWR_CON, 646 .sram_pdn_bits = GENMASK(8, 8), 647 .sram_pdn_ack_bits = GENMASK(12, 12), 648 .clk_id = {CLK_MM}, 649 .caps = MTK_SCPD_ACTIVE_WAKEUP, 650 }, 651 [MT2712_POWER_DOMAIN_VDEC] = { 652 .name = "vdec", 653 .sta_mask = PWR_STATUS_VDEC, 654 .ctl_offs = SPM_VDE_PWR_CON, 655 .sram_pdn_bits = GENMASK(8, 8), 656 .sram_pdn_ack_bits = GENMASK(12, 12), 657 .clk_id = {CLK_MM, CLK_VDEC}, 658 .caps = MTK_SCPD_ACTIVE_WAKEUP, 659 }, 660 [MT2712_POWER_DOMAIN_VENC] = { 661 .name = "venc", 662 .sta_mask = PWR_STATUS_VENC, 663 .ctl_offs = SPM_VEN_PWR_CON, 664 .sram_pdn_bits = GENMASK(11, 8), 665 .sram_pdn_ack_bits = GENMASK(15, 12), 666 .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC}, 667 .caps = MTK_SCPD_ACTIVE_WAKEUP, 668 }, 669 [MT2712_POWER_DOMAIN_ISP] = { 670 .name = "isp", 671 .sta_mask = PWR_STATUS_ISP, 672 .ctl_offs = SPM_ISP_PWR_CON, 673 .sram_pdn_bits = GENMASK(11, 8), 674 .sram_pdn_ack_bits = GENMASK(13, 12), 675 .clk_id = {CLK_MM}, 676 .caps = MTK_SCPD_ACTIVE_WAKEUP, 677 }, 678 [MT2712_POWER_DOMAIN_AUDIO] = { 679 .name = "audio", 680 .sta_mask = PWR_STATUS_AUDIO, 681 .ctl_offs = SPM_AUDIO_PWR_CON, 682 .sram_pdn_bits = GENMASK(11, 8), 683 .sram_pdn_ack_bits = GENMASK(15, 12), 684 .clk_id = {CLK_AUDIO}, 685 .caps = MTK_SCPD_ACTIVE_WAKEUP, 686 }, 687 [MT2712_POWER_DOMAIN_USB] = { 688 .name = "usb", 689 .sta_mask = PWR_STATUS_USB, 690 .ctl_offs = SPM_USB_PWR_CON, 691 .sram_pdn_bits = GENMASK(10, 8), 692 .sram_pdn_ack_bits = GENMASK(14, 12), 693 .clk_id = {CLK_NONE}, 694 .caps = MTK_SCPD_ACTIVE_WAKEUP, 695 }, 696 [MT2712_POWER_DOMAIN_USB2] = { 697 .name = "usb2", 698 .sta_mask = PWR_STATUS_USB2, 699 .ctl_offs = SPM_USB2_PWR_CON, 700 .sram_pdn_bits = GENMASK(10, 8), 701 .sram_pdn_ack_bits = GENMASK(14, 12), 702 .clk_id = {CLK_NONE}, 703 .caps = MTK_SCPD_ACTIVE_WAKEUP, 704 }, 705 [MT2712_POWER_DOMAIN_MFG] = { 706 .name = "mfg", 707 .sta_mask = PWR_STATUS_MFG, 708 .ctl_offs = SPM_MFG_PWR_CON, 709 .sram_pdn_bits = GENMASK(8, 8), 710 .sram_pdn_ack_bits = GENMASK(16, 16), 711 .clk_id = {CLK_MFG}, 712 .bus_prot_mask = BIT(14) | BIT(21) | BIT(23), 713 .caps = MTK_SCPD_ACTIVE_WAKEUP, 714 }, 715 [MT2712_POWER_DOMAIN_MFG_SC1] = { 716 .name = "mfg_sc1", 717 .sta_mask = BIT(22), 718 .ctl_offs = 0x02c0, 719 .sram_pdn_bits = GENMASK(8, 8), 720 .sram_pdn_ack_bits = GENMASK(16, 16), 721 .clk_id = {CLK_NONE}, 722 .caps = MTK_SCPD_ACTIVE_WAKEUP, 723 }, 724 [MT2712_POWER_DOMAIN_MFG_SC2] = { 725 .name = "mfg_sc2", 726 .sta_mask = BIT(23), 727 .ctl_offs = 0x02c4, 728 .sram_pdn_bits = GENMASK(8, 8), 729 .sram_pdn_ack_bits = GENMASK(16, 16), 730 .clk_id = {CLK_NONE}, 731 .caps = MTK_SCPD_ACTIVE_WAKEUP, 732 }, 733 [MT2712_POWER_DOMAIN_MFG_SC3] = { 734 .name = "mfg_sc3", 735 .sta_mask = BIT(30), 736 .ctl_offs = 0x01f8, 737 .sram_pdn_bits = GENMASK(8, 8), 738 .sram_pdn_ack_bits = GENMASK(16, 16), 739 .clk_id = {CLK_NONE}, 740 .caps = MTK_SCPD_ACTIVE_WAKEUP, 741 }, 742 }; 743 744 static const struct scp_subdomain scp_subdomain_mt2712[] = { 745 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC}, 746 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC}, 747 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP}, 748 {MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1}, 749 {MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2}, 750 {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3}, 751 }; 752 753 /* 754 * MT6797 power domain support 755 */ 756 757 static const struct scp_domain_data scp_domain_data_mt6797[] = { 758 [MT6797_POWER_DOMAIN_VDEC] = { 759 .name = "vdec", 760 .sta_mask = BIT(7), 761 .ctl_offs = 0x300, 762 .sram_pdn_bits = GENMASK(8, 8), 763 .sram_pdn_ack_bits = GENMASK(12, 12), 764 .clk_id = {CLK_VDEC}, 765 }, 766 [MT6797_POWER_DOMAIN_VENC] = { 767 .name = "venc", 768 .sta_mask = BIT(21), 769 .ctl_offs = 0x304, 770 .sram_pdn_bits = GENMASK(11, 8), 771 .sram_pdn_ack_bits = GENMASK(15, 12), 772 .clk_id = {CLK_NONE}, 773 }, 774 [MT6797_POWER_DOMAIN_ISP] = { 775 .name = "isp", 776 .sta_mask = BIT(5), 777 .ctl_offs = 0x308, 778 .sram_pdn_bits = GENMASK(9, 8), 779 .sram_pdn_ack_bits = GENMASK(13, 12), 780 .clk_id = {CLK_NONE}, 781 }, 782 [MT6797_POWER_DOMAIN_MM] = { 783 .name = "mm", 784 .sta_mask = BIT(3), 785 .ctl_offs = 0x30C, 786 .sram_pdn_bits = GENMASK(8, 8), 787 .sram_pdn_ack_bits = GENMASK(12, 12), 788 .clk_id = {CLK_MM}, 789 .bus_prot_mask = (BIT(1) | BIT(2)), 790 }, 791 [MT6797_POWER_DOMAIN_AUDIO] = { 792 .name = "audio", 793 .sta_mask = BIT(24), 794 .ctl_offs = 0x314, 795 .sram_pdn_bits = GENMASK(11, 8), 796 .sram_pdn_ack_bits = GENMASK(15, 12), 797 .clk_id = {CLK_NONE}, 798 }, 799 [MT6797_POWER_DOMAIN_MFG_ASYNC] = { 800 .name = "mfg_async", 801 .sta_mask = BIT(13), 802 .ctl_offs = 0x334, 803 .sram_pdn_bits = 0, 804 .sram_pdn_ack_bits = 0, 805 .clk_id = {CLK_MFG}, 806 }, 807 [MT6797_POWER_DOMAIN_MJC] = { 808 .name = "mjc", 809 .sta_mask = BIT(20), 810 .ctl_offs = 0x310, 811 .sram_pdn_bits = GENMASK(8, 8), 812 .sram_pdn_ack_bits = GENMASK(12, 12), 813 .clk_id = {CLK_NONE}, 814 }, 815 }; 816 817 #define SPM_PWR_STATUS_MT6797 0x0180 818 #define SPM_PWR_STATUS_2ND_MT6797 0x0184 819 820 static const struct scp_subdomain scp_subdomain_mt6797[] = { 821 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC}, 822 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP}, 823 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC}, 824 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC}, 825 }; 826 827 /* 828 * MT7622 power domain support 829 */ 830 831 static const struct scp_domain_data scp_domain_data_mt7622[] = { 832 [MT7622_POWER_DOMAIN_ETHSYS] = { 833 .name = "ethsys", 834 .sta_mask = PWR_STATUS_ETHSYS, 835 .ctl_offs = SPM_ETHSYS_PWR_CON, 836 .sram_pdn_bits = GENMASK(11, 8), 837 .sram_pdn_ack_bits = GENMASK(15, 12), 838 .clk_id = {CLK_NONE}, 839 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS, 840 .caps = MTK_SCPD_ACTIVE_WAKEUP, 841 }, 842 [MT7622_POWER_DOMAIN_HIF0] = { 843 .name = "hif0", 844 .sta_mask = PWR_STATUS_HIF0, 845 .ctl_offs = SPM_HIF0_PWR_CON, 846 .sram_pdn_bits = GENMASK(11, 8), 847 .sram_pdn_ack_bits = GENMASK(15, 12), 848 .clk_id = {CLK_HIFSEL}, 849 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0, 850 .caps = MTK_SCPD_ACTIVE_WAKEUP, 851 }, 852 [MT7622_POWER_DOMAIN_HIF1] = { 853 .name = "hif1", 854 .sta_mask = PWR_STATUS_HIF1, 855 .ctl_offs = SPM_HIF1_PWR_CON, 856 .sram_pdn_bits = GENMASK(11, 8), 857 .sram_pdn_ack_bits = GENMASK(15, 12), 858 .clk_id = {CLK_HIFSEL}, 859 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, 860 .caps = MTK_SCPD_ACTIVE_WAKEUP, 861 }, 862 [MT7622_POWER_DOMAIN_WB] = { 863 .name = "wb", 864 .sta_mask = PWR_STATUS_WB, 865 .ctl_offs = SPM_WB_PWR_CON, 866 .sram_pdn_bits = 0, 867 .sram_pdn_ack_bits = 0, 868 .clk_id = {CLK_NONE}, 869 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, 870 .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM, 871 }, 872 }; 873 874 /* 875 * MT7623A power domain support 876 */ 877 878 static const struct scp_domain_data scp_domain_data_mt7623a[] = { 879 [MT7623A_POWER_DOMAIN_CONN] = { 880 .name = "conn", 881 .sta_mask = PWR_STATUS_CONN, 882 .ctl_offs = SPM_CONN_PWR_CON, 883 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 884 MT2701_TOP_AXI_PROT_EN_CONN_S, 885 .clk_id = {CLK_NONE}, 886 .caps = MTK_SCPD_ACTIVE_WAKEUP, 887 }, 888 [MT7623A_POWER_DOMAIN_ETH] = { 889 .name = "eth", 890 .sta_mask = PWR_STATUS_ETH, 891 .ctl_offs = SPM_ETH_PWR_CON, 892 .sram_pdn_bits = GENMASK(11, 8), 893 .sram_pdn_ack_bits = GENMASK(15, 12), 894 .clk_id = {CLK_ETHIF}, 895 .caps = MTK_SCPD_ACTIVE_WAKEUP, 896 }, 897 [MT7623A_POWER_DOMAIN_HIF] = { 898 .name = "hif", 899 .sta_mask = PWR_STATUS_HIF, 900 .ctl_offs = SPM_HIF_PWR_CON, 901 .sram_pdn_bits = GENMASK(11, 8), 902 .sram_pdn_ack_bits = GENMASK(15, 12), 903 .clk_id = {CLK_ETHIF}, 904 .caps = MTK_SCPD_ACTIVE_WAKEUP, 905 }, 906 [MT7623A_POWER_DOMAIN_IFR_MSC] = { 907 .name = "ifr_msc", 908 .sta_mask = PWR_STATUS_IFR_MSC, 909 .ctl_offs = SPM_IFR_MSC_PWR_CON, 910 .clk_id = {CLK_NONE}, 911 .caps = MTK_SCPD_ACTIVE_WAKEUP, 912 }, 913 }; 914 915 /* 916 * MT8173 power domain support 917 */ 918 919 static const struct scp_domain_data scp_domain_data_mt8173[] = { 920 [MT8173_POWER_DOMAIN_VDEC] = { 921 .name = "vdec", 922 .sta_mask = PWR_STATUS_VDEC, 923 .ctl_offs = SPM_VDE_PWR_CON, 924 .sram_pdn_bits = GENMASK(11, 8), 925 .sram_pdn_ack_bits = GENMASK(12, 12), 926 .clk_id = {CLK_MM}, 927 }, 928 [MT8173_POWER_DOMAIN_VENC] = { 929 .name = "venc", 930 .sta_mask = PWR_STATUS_VENC, 931 .ctl_offs = SPM_VEN_PWR_CON, 932 .sram_pdn_bits = GENMASK(11, 8), 933 .sram_pdn_ack_bits = GENMASK(15, 12), 934 .clk_id = {CLK_MM, CLK_VENC}, 935 }, 936 [MT8173_POWER_DOMAIN_ISP] = { 937 .name = "isp", 938 .sta_mask = PWR_STATUS_ISP, 939 .ctl_offs = SPM_ISP_PWR_CON, 940 .sram_pdn_bits = GENMASK(11, 8), 941 .sram_pdn_ack_bits = GENMASK(13, 12), 942 .clk_id = {CLK_MM}, 943 }, 944 [MT8173_POWER_DOMAIN_MM] = { 945 .name = "mm", 946 .sta_mask = PWR_STATUS_DISP, 947 .ctl_offs = SPM_DIS_PWR_CON, 948 .sram_pdn_bits = GENMASK(11, 8), 949 .sram_pdn_ack_bits = GENMASK(12, 12), 950 .clk_id = {CLK_MM}, 951 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | 952 MT8173_TOP_AXI_PROT_EN_MM_M1, 953 }, 954 [MT8173_POWER_DOMAIN_VENC_LT] = { 955 .name = "venc_lt", 956 .sta_mask = PWR_STATUS_VENC_LT, 957 .ctl_offs = SPM_VEN2_PWR_CON, 958 .sram_pdn_bits = GENMASK(11, 8), 959 .sram_pdn_ack_bits = GENMASK(15, 12), 960 .clk_id = {CLK_MM, CLK_VENC_LT}, 961 }, 962 [MT8173_POWER_DOMAIN_AUDIO] = { 963 .name = "audio", 964 .sta_mask = PWR_STATUS_AUDIO, 965 .ctl_offs = SPM_AUDIO_PWR_CON, 966 .sram_pdn_bits = GENMASK(11, 8), 967 .sram_pdn_ack_bits = GENMASK(15, 12), 968 .clk_id = {CLK_NONE}, 969 }, 970 [MT8173_POWER_DOMAIN_USB] = { 971 .name = "usb", 972 .sta_mask = PWR_STATUS_USB, 973 .ctl_offs = SPM_USB_PWR_CON, 974 .sram_pdn_bits = GENMASK(11, 8), 975 .sram_pdn_ack_bits = GENMASK(15, 12), 976 .clk_id = {CLK_NONE}, 977 .caps = MTK_SCPD_ACTIVE_WAKEUP, 978 }, 979 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 980 .name = "mfg_async", 981 .sta_mask = PWR_STATUS_MFG_ASYNC, 982 .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 983 .sram_pdn_bits = GENMASK(11, 8), 984 .sram_pdn_ack_bits = 0, 985 .clk_id = {CLK_MFG}, 986 }, 987 [MT8173_POWER_DOMAIN_MFG_2D] = { 988 .name = "mfg_2d", 989 .sta_mask = PWR_STATUS_MFG_2D, 990 .ctl_offs = SPM_MFG_2D_PWR_CON, 991 .sram_pdn_bits = GENMASK(11, 8), 992 .sram_pdn_ack_bits = GENMASK(13, 12), 993 .clk_id = {CLK_NONE}, 994 }, 995 [MT8173_POWER_DOMAIN_MFG] = { 996 .name = "mfg", 997 .sta_mask = PWR_STATUS_MFG, 998 .ctl_offs = SPM_MFG_PWR_CON, 999 .sram_pdn_bits = GENMASK(13, 8), 1000 .sram_pdn_ack_bits = GENMASK(21, 16), 1001 .clk_id = {CLK_NONE}, 1002 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | 1003 MT8173_TOP_AXI_PROT_EN_MFG_M0 | 1004 MT8173_TOP_AXI_PROT_EN_MFG_M1 | 1005 MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT, 1006 }, 1007 }; 1008 1009 static const struct scp_subdomain scp_subdomain_mt8173[] = { 1010 {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D}, 1011 {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, 1012 }; 1013 1014 static const struct scp_soc_data mt2701_data = { 1015 .domains = scp_domain_data_mt2701, 1016 .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), 1017 .regs = { 1018 .pwr_sta_offs = SPM_PWR_STATUS, 1019 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1020 }, 1021 .bus_prot_reg_update = true, 1022 }; 1023 1024 static const struct scp_soc_data mt2712_data = { 1025 .domains = scp_domain_data_mt2712, 1026 .num_domains = ARRAY_SIZE(scp_domain_data_mt2712), 1027 .subdomains = scp_subdomain_mt2712, 1028 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712), 1029 .regs = { 1030 .pwr_sta_offs = SPM_PWR_STATUS, 1031 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1032 }, 1033 .bus_prot_reg_update = false, 1034 }; 1035 1036 static const struct scp_soc_data mt6797_data = { 1037 .domains = scp_domain_data_mt6797, 1038 .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), 1039 .subdomains = scp_subdomain_mt6797, 1040 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797), 1041 .regs = { 1042 .pwr_sta_offs = SPM_PWR_STATUS_MT6797, 1043 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 1044 }, 1045 .bus_prot_reg_update = true, 1046 }; 1047 1048 static const struct scp_soc_data mt7622_data = { 1049 .domains = scp_domain_data_mt7622, 1050 .num_domains = ARRAY_SIZE(scp_domain_data_mt7622), 1051 .regs = { 1052 .pwr_sta_offs = SPM_PWR_STATUS, 1053 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1054 }, 1055 .bus_prot_reg_update = true, 1056 }; 1057 1058 static const struct scp_soc_data mt7623a_data = { 1059 .domains = scp_domain_data_mt7623a, 1060 .num_domains = ARRAY_SIZE(scp_domain_data_mt7623a), 1061 .regs = { 1062 .pwr_sta_offs = SPM_PWR_STATUS, 1063 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1064 }, 1065 .bus_prot_reg_update = true, 1066 }; 1067 1068 static const struct scp_soc_data mt8173_data = { 1069 .domains = scp_domain_data_mt8173, 1070 .num_domains = ARRAY_SIZE(scp_domain_data_mt8173), 1071 .subdomains = scp_subdomain_mt8173, 1072 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173), 1073 .regs = { 1074 .pwr_sta_offs = SPM_PWR_STATUS, 1075 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1076 }, 1077 .bus_prot_reg_update = true, 1078 }; 1079 1080 /* 1081 * scpsys driver init 1082 */ 1083 1084 static const struct of_device_id of_scpsys_match_tbl[] = { 1085 { 1086 .compatible = "mediatek,mt2701-scpsys", 1087 .data = &mt2701_data, 1088 }, { 1089 .compatible = "mediatek,mt2712-scpsys", 1090 .data = &mt2712_data, 1091 }, { 1092 .compatible = "mediatek,mt6797-scpsys", 1093 .data = &mt6797_data, 1094 }, { 1095 .compatible = "mediatek,mt7622-scpsys", 1096 .data = &mt7622_data, 1097 }, { 1098 .compatible = "mediatek,mt7623a-scpsys", 1099 .data = &mt7623a_data, 1100 }, { 1101 .compatible = "mediatek,mt8173-scpsys", 1102 .data = &mt8173_data, 1103 }, { 1104 /* sentinel */ 1105 } 1106 }; 1107 1108 static int scpsys_probe(struct platform_device *pdev) 1109 { 1110 const struct scp_subdomain *sd; 1111 const struct scp_soc_data *soc; 1112 struct scp *scp; 1113 struct genpd_onecell_data *pd_data; 1114 int i, ret; 1115 1116 soc = of_device_get_match_data(&pdev->dev); 1117 1118 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs, 1119 soc->bus_prot_reg_update); 1120 if (IS_ERR(scp)) 1121 return PTR_ERR(scp); 1122 1123 mtk_register_power_domains(pdev, scp, soc->num_domains); 1124 1125 pd_data = &scp->pd_data; 1126 1127 for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { 1128 ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], 1129 pd_data->domains[sd->subdomain]); 1130 if (ret && IS_ENABLED(CONFIG_PM)) 1131 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", 1132 ret); 1133 } 1134 1135 return 0; 1136 } 1137 1138 static struct platform_driver scpsys_drv = { 1139 .probe = scpsys_probe, 1140 .driver = { 1141 .name = "mtk-scpsys", 1142 .suppress_bind_attrs = true, 1143 .owner = THIS_MODULE, 1144 .of_match_table = of_scpsys_match_tbl, 1145 }, 1146 }; 1147 builtin_platform_driver(scpsys_drv); 1148