Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 1154 lines 29 kB view raw
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 81enum 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 95static 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 */ 122struct 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 133struct scp; 134 135struct 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 143struct scp_ctrl_reg { 144 int pwr_sta_offs; 145 int pwr_sta2nd_offs; 146}; 147 148struct 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 158struct scp_subdomain { 159 int origin; 160 int subdomain; 161}; 162 163struct 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 172static 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 194static 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 202static 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 210static 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 218static 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 233static 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 263static 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 279static 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 291static 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 303static 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 351err_pwr_ack: 352 scpsys_clk_disable(scpd->clk, MAX_CLKS); 353err_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 361static 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 408out: 409 dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name); 410 411 return ret; 412} 413 414static 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 422static 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 516static 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 555static 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 */ 639static 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 742static 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 755static 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 818static 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 829static 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 [MT7622_POWER_DOMAIN_AUDIO] = { 871 .name = "audsys", 872 .sta_mask = PWR_STATUS_AUDIO, 873 .ctl_offs = SPM_AUDIO_PWR_CON, 874 .sram_pdn_bits = GENMASK(11, 8), 875 .sram_pdn_ack_bits = GENMASK(15, 12), 876 .clk_id = {CLK_NONE}, 877 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, 878 .caps = MTK_SCPD_ACTIVE_WAKEUP, 879 }, 880}; 881 882/* 883 * MT7623A power domain support 884 */ 885 886static const struct scp_domain_data scp_domain_data_mt7623a[] = { 887 [MT7623A_POWER_DOMAIN_CONN] = { 888 .name = "conn", 889 .sta_mask = PWR_STATUS_CONN, 890 .ctl_offs = SPM_CONN_PWR_CON, 891 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | 892 MT2701_TOP_AXI_PROT_EN_CONN_S, 893 .clk_id = {CLK_NONE}, 894 .caps = MTK_SCPD_ACTIVE_WAKEUP, 895 }, 896 [MT7623A_POWER_DOMAIN_ETH] = { 897 .name = "eth", 898 .sta_mask = PWR_STATUS_ETH, 899 .ctl_offs = SPM_ETH_PWR_CON, 900 .sram_pdn_bits = GENMASK(11, 8), 901 .sram_pdn_ack_bits = GENMASK(15, 12), 902 .clk_id = {CLK_ETHIF}, 903 .caps = MTK_SCPD_ACTIVE_WAKEUP, 904 }, 905 [MT7623A_POWER_DOMAIN_HIF] = { 906 .name = "hif", 907 .sta_mask = PWR_STATUS_HIF, 908 .ctl_offs = SPM_HIF_PWR_CON, 909 .sram_pdn_bits = GENMASK(11, 8), 910 .sram_pdn_ack_bits = GENMASK(15, 12), 911 .clk_id = {CLK_ETHIF}, 912 .caps = MTK_SCPD_ACTIVE_WAKEUP, 913 }, 914 [MT7623A_POWER_DOMAIN_IFR_MSC] = { 915 .name = "ifr_msc", 916 .sta_mask = PWR_STATUS_IFR_MSC, 917 .ctl_offs = SPM_IFR_MSC_PWR_CON, 918 .clk_id = {CLK_NONE}, 919 .caps = MTK_SCPD_ACTIVE_WAKEUP, 920 }, 921}; 922 923/* 924 * MT8173 power domain support 925 */ 926 927static const struct scp_domain_data scp_domain_data_mt8173[] = { 928 [MT8173_POWER_DOMAIN_VDEC] = { 929 .name = "vdec", 930 .sta_mask = PWR_STATUS_VDEC, 931 .ctl_offs = SPM_VDE_PWR_CON, 932 .sram_pdn_bits = GENMASK(11, 8), 933 .sram_pdn_ack_bits = GENMASK(12, 12), 934 .clk_id = {CLK_MM}, 935 }, 936 [MT8173_POWER_DOMAIN_VENC] = { 937 .name = "venc", 938 .sta_mask = PWR_STATUS_VENC, 939 .ctl_offs = SPM_VEN_PWR_CON, 940 .sram_pdn_bits = GENMASK(11, 8), 941 .sram_pdn_ack_bits = GENMASK(15, 12), 942 .clk_id = {CLK_MM, CLK_VENC}, 943 }, 944 [MT8173_POWER_DOMAIN_ISP] = { 945 .name = "isp", 946 .sta_mask = PWR_STATUS_ISP, 947 .ctl_offs = SPM_ISP_PWR_CON, 948 .sram_pdn_bits = GENMASK(11, 8), 949 .sram_pdn_ack_bits = GENMASK(13, 12), 950 .clk_id = {CLK_MM}, 951 }, 952 [MT8173_POWER_DOMAIN_MM] = { 953 .name = "mm", 954 .sta_mask = PWR_STATUS_DISP, 955 .ctl_offs = SPM_DIS_PWR_CON, 956 .sram_pdn_bits = GENMASK(11, 8), 957 .sram_pdn_ack_bits = GENMASK(12, 12), 958 .clk_id = {CLK_MM}, 959 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | 960 MT8173_TOP_AXI_PROT_EN_MM_M1, 961 }, 962 [MT8173_POWER_DOMAIN_VENC_LT] = { 963 .name = "venc_lt", 964 .sta_mask = PWR_STATUS_VENC_LT, 965 .ctl_offs = SPM_VEN2_PWR_CON, 966 .sram_pdn_bits = GENMASK(11, 8), 967 .sram_pdn_ack_bits = GENMASK(15, 12), 968 .clk_id = {CLK_MM, CLK_VENC_LT}, 969 }, 970 [MT8173_POWER_DOMAIN_AUDIO] = { 971 .name = "audio", 972 .sta_mask = PWR_STATUS_AUDIO, 973 .ctl_offs = SPM_AUDIO_PWR_CON, 974 .sram_pdn_bits = GENMASK(11, 8), 975 .sram_pdn_ack_bits = GENMASK(15, 12), 976 .clk_id = {CLK_NONE}, 977 }, 978 [MT8173_POWER_DOMAIN_USB] = { 979 .name = "usb", 980 .sta_mask = PWR_STATUS_USB, 981 .ctl_offs = SPM_USB_PWR_CON, 982 .sram_pdn_bits = GENMASK(11, 8), 983 .sram_pdn_ack_bits = GENMASK(15, 12), 984 .clk_id = {CLK_NONE}, 985 .caps = MTK_SCPD_ACTIVE_WAKEUP, 986 }, 987 [MT8173_POWER_DOMAIN_MFG_ASYNC] = { 988 .name = "mfg_async", 989 .sta_mask = PWR_STATUS_MFG_ASYNC, 990 .ctl_offs = SPM_MFG_ASYNC_PWR_CON, 991 .sram_pdn_bits = GENMASK(11, 8), 992 .sram_pdn_ack_bits = 0, 993 .clk_id = {CLK_MFG}, 994 }, 995 [MT8173_POWER_DOMAIN_MFG_2D] = { 996 .name = "mfg_2d", 997 .sta_mask = PWR_STATUS_MFG_2D, 998 .ctl_offs = SPM_MFG_2D_PWR_CON, 999 .sram_pdn_bits = GENMASK(11, 8), 1000 .sram_pdn_ack_bits = GENMASK(13, 12), 1001 .clk_id = {CLK_NONE}, 1002 }, 1003 [MT8173_POWER_DOMAIN_MFG] = { 1004 .name = "mfg", 1005 .sta_mask = PWR_STATUS_MFG, 1006 .ctl_offs = SPM_MFG_PWR_CON, 1007 .sram_pdn_bits = GENMASK(13, 8), 1008 .sram_pdn_ack_bits = GENMASK(21, 16), 1009 .clk_id = {CLK_NONE}, 1010 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | 1011 MT8173_TOP_AXI_PROT_EN_MFG_M0 | 1012 MT8173_TOP_AXI_PROT_EN_MFG_M1 | 1013 MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT, 1014 }, 1015}; 1016 1017static const struct scp_subdomain scp_subdomain_mt8173[] = { 1018 {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D}, 1019 {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, 1020}; 1021 1022static const struct scp_soc_data mt2701_data = { 1023 .domains = scp_domain_data_mt2701, 1024 .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), 1025 .regs = { 1026 .pwr_sta_offs = SPM_PWR_STATUS, 1027 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1028 }, 1029 .bus_prot_reg_update = true, 1030}; 1031 1032static const struct scp_soc_data mt2712_data = { 1033 .domains = scp_domain_data_mt2712, 1034 .num_domains = ARRAY_SIZE(scp_domain_data_mt2712), 1035 .subdomains = scp_subdomain_mt2712, 1036 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712), 1037 .regs = { 1038 .pwr_sta_offs = SPM_PWR_STATUS, 1039 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1040 }, 1041 .bus_prot_reg_update = false, 1042}; 1043 1044static const struct scp_soc_data mt6797_data = { 1045 .domains = scp_domain_data_mt6797, 1046 .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), 1047 .subdomains = scp_subdomain_mt6797, 1048 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797), 1049 .regs = { 1050 .pwr_sta_offs = SPM_PWR_STATUS_MT6797, 1051 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 1052 }, 1053 .bus_prot_reg_update = true, 1054}; 1055 1056static const struct scp_soc_data mt7622_data = { 1057 .domains = scp_domain_data_mt7622, 1058 .num_domains = ARRAY_SIZE(scp_domain_data_mt7622), 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 1066static const struct scp_soc_data mt7623a_data = { 1067 .domains = scp_domain_data_mt7623a, 1068 .num_domains = ARRAY_SIZE(scp_domain_data_mt7623a), 1069 .regs = { 1070 .pwr_sta_offs = SPM_PWR_STATUS, 1071 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1072 }, 1073 .bus_prot_reg_update = true, 1074}; 1075 1076static const struct scp_soc_data mt8173_data = { 1077 .domains = scp_domain_data_mt8173, 1078 .num_domains = ARRAY_SIZE(scp_domain_data_mt8173), 1079 .subdomains = scp_subdomain_mt8173, 1080 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173), 1081 .regs = { 1082 .pwr_sta_offs = SPM_PWR_STATUS, 1083 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND 1084 }, 1085 .bus_prot_reg_update = true, 1086}; 1087 1088/* 1089 * scpsys driver init 1090 */ 1091 1092static const struct of_device_id of_scpsys_match_tbl[] = { 1093 { 1094 .compatible = "mediatek,mt2701-scpsys", 1095 .data = &mt2701_data, 1096 }, { 1097 .compatible = "mediatek,mt2712-scpsys", 1098 .data = &mt2712_data, 1099 }, { 1100 .compatible = "mediatek,mt6797-scpsys", 1101 .data = &mt6797_data, 1102 }, { 1103 .compatible = "mediatek,mt7622-scpsys", 1104 .data = &mt7622_data, 1105 }, { 1106 .compatible = "mediatek,mt7623a-scpsys", 1107 .data = &mt7623a_data, 1108 }, { 1109 .compatible = "mediatek,mt8173-scpsys", 1110 .data = &mt8173_data, 1111 }, { 1112 /* sentinel */ 1113 } 1114}; 1115 1116static int scpsys_probe(struct platform_device *pdev) 1117{ 1118 const struct scp_subdomain *sd; 1119 const struct scp_soc_data *soc; 1120 struct scp *scp; 1121 struct genpd_onecell_data *pd_data; 1122 int i, ret; 1123 1124 soc = of_device_get_match_data(&pdev->dev); 1125 1126 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs, 1127 soc->bus_prot_reg_update); 1128 if (IS_ERR(scp)) 1129 return PTR_ERR(scp); 1130 1131 mtk_register_power_domains(pdev, scp, soc->num_domains); 1132 1133 pd_data = &scp->pd_data; 1134 1135 for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) { 1136 ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], 1137 pd_data->domains[sd->subdomain]); 1138 if (ret && IS_ENABLED(CONFIG_PM)) 1139 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", 1140 ret); 1141 } 1142 1143 return 0; 1144} 1145 1146static struct platform_driver scpsys_drv = { 1147 .probe = scpsys_probe, 1148 .driver = { 1149 .name = "mtk-scpsys", 1150 .suppress_bind_attrs = true, 1151 .of_match_table = of_scpsys_match_tbl, 1152 }, 1153}; 1154builtin_platform_driver(scpsys_drv);