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