0001
0002
0003
0004
0005 #include <linux/clk.h>
0006 #include <linux/init.h>
0007 #include <linux/io.h>
0008 #include <linux/iopoll.h>
0009 #include <linux/mfd/syscon.h>
0010 #include <linux/of_device.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/pm_domain.h>
0013 #include <linux/regulator/consumer.h>
0014 #include <linux/soc/mediatek/infracfg.h>
0015
0016 #include <dt-bindings/power/mt2701-power.h>
0017 #include <dt-bindings/power/mt2712-power.h>
0018 #include <dt-bindings/power/mt6797-power.h>
0019 #include <dt-bindings/power/mt7622-power.h>
0020 #include <dt-bindings/power/mt7623a-power.h>
0021 #include <dt-bindings/power/mt8173-power.h>
0022
0023 #define MTK_POLL_DELAY_US 10
0024 #define MTK_POLL_TIMEOUT USEC_PER_SEC
0025
0026 #define MTK_SCPD_ACTIVE_WAKEUP BIT(0)
0027 #define MTK_SCPD_FWAIT_SRAM BIT(1)
0028 #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x))
0029
0030 #define SPM_VDE_PWR_CON 0x0210
0031 #define SPM_MFG_PWR_CON 0x0214
0032 #define SPM_VEN_PWR_CON 0x0230
0033 #define SPM_ISP_PWR_CON 0x0238
0034 #define SPM_DIS_PWR_CON 0x023c
0035 #define SPM_CONN_PWR_CON 0x0280
0036 #define SPM_VEN2_PWR_CON 0x0298
0037 #define SPM_AUDIO_PWR_CON 0x029c
0038 #define SPM_BDP_PWR_CON 0x029c
0039 #define SPM_ETH_PWR_CON 0x02a0
0040 #define SPM_HIF_PWR_CON 0x02a4
0041 #define SPM_IFR_MSC_PWR_CON 0x02a8
0042 #define SPM_MFG_2D_PWR_CON 0x02c0
0043 #define SPM_MFG_ASYNC_PWR_CON 0x02c4
0044 #define SPM_USB_PWR_CON 0x02cc
0045 #define SPM_USB2_PWR_CON 0x02d4
0046 #define SPM_ETHSYS_PWR_CON 0x02e0
0047 #define SPM_HIF0_PWR_CON 0x02e4
0048 #define SPM_HIF1_PWR_CON 0x02e8
0049 #define SPM_WB_PWR_CON 0x02ec
0050
0051 #define SPM_PWR_STATUS 0x060c
0052 #define SPM_PWR_STATUS_2ND 0x0610
0053
0054 #define PWR_RST_B_BIT BIT(0)
0055 #define PWR_ISO_BIT BIT(1)
0056 #define PWR_ON_BIT BIT(2)
0057 #define PWR_ON_2ND_BIT BIT(3)
0058 #define PWR_CLK_DIS_BIT BIT(4)
0059
0060 #define PWR_STATUS_CONN BIT(1)
0061 #define PWR_STATUS_DISP BIT(3)
0062 #define PWR_STATUS_MFG BIT(4)
0063 #define PWR_STATUS_ISP BIT(5)
0064 #define PWR_STATUS_VDEC BIT(7)
0065 #define PWR_STATUS_BDP BIT(14)
0066 #define PWR_STATUS_ETH BIT(15)
0067 #define PWR_STATUS_HIF BIT(16)
0068 #define PWR_STATUS_IFR_MSC BIT(17)
0069 #define PWR_STATUS_USB2 BIT(19)
0070 #define PWR_STATUS_VENC_LT BIT(20)
0071 #define PWR_STATUS_VENC BIT(21)
0072 #define PWR_STATUS_MFG_2D BIT(22)
0073 #define PWR_STATUS_MFG_ASYNC BIT(23)
0074 #define PWR_STATUS_AUDIO BIT(24)
0075 #define PWR_STATUS_USB BIT(25)
0076 #define PWR_STATUS_ETHSYS BIT(24)
0077 #define PWR_STATUS_HIF0 BIT(25)
0078 #define PWR_STATUS_HIF1 BIT(26)
0079 #define PWR_STATUS_WB BIT(27)
0080
0081 enum clk_id {
0082 CLK_NONE,
0083 CLK_MM,
0084 CLK_MFG,
0085 CLK_VENC,
0086 CLK_VENC_LT,
0087 CLK_ETHIF,
0088 CLK_VDEC,
0089 CLK_HIFSEL,
0090 CLK_JPGDEC,
0091 CLK_AUDIO,
0092 CLK_MAX,
0093 };
0094
0095 static const char * const clk_names[] = {
0096 NULL,
0097 "mm",
0098 "mfg",
0099 "venc",
0100 "venc_lt",
0101 "ethif",
0102 "vdec",
0103 "hif_sel",
0104 "jpgdec",
0105 "audio",
0106 NULL,
0107 };
0108
0109 #define MAX_CLKS 3
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 struct scp_domain_data {
0123 const char *name;
0124 u32 sta_mask;
0125 int ctl_offs;
0126 u32 sram_pdn_bits;
0127 u32 sram_pdn_ack_bits;
0128 u32 bus_prot_mask;
0129 enum clk_id clk_id[MAX_CLKS];
0130 u8 caps;
0131 };
0132
0133 struct scp;
0134
0135 struct scp_domain {
0136 struct generic_pm_domain genpd;
0137 struct scp *scp;
0138 struct clk *clk[MAX_CLKS];
0139 const struct scp_domain_data *data;
0140 struct regulator *supply;
0141 };
0142
0143 struct scp_ctrl_reg {
0144 int pwr_sta_offs;
0145 int pwr_sta2nd_offs;
0146 };
0147
0148 struct scp {
0149 struct scp_domain *domains;
0150 struct genpd_onecell_data pd_data;
0151 struct device *dev;
0152 void __iomem *base;
0153 struct regmap *infracfg;
0154 struct scp_ctrl_reg ctrl_reg;
0155 bool bus_prot_reg_update;
0156 };
0157
0158 struct scp_subdomain {
0159 int origin;
0160 int subdomain;
0161 };
0162
0163 struct scp_soc_data {
0164 const struct scp_domain_data *domains;
0165 int num_domains;
0166 const struct scp_subdomain *subdomains;
0167 int num_subdomains;
0168 const struct scp_ctrl_reg regs;
0169 bool bus_prot_reg_update;
0170 };
0171
0172 static int scpsys_domain_is_on(struct scp_domain *scpd)
0173 {
0174 struct scp *scp = scpd->scp;
0175
0176 u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
0177 scpd->data->sta_mask;
0178 u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
0179 scpd->data->sta_mask;
0180
0181
0182
0183
0184
0185
0186 if (status && status2)
0187 return true;
0188 if (!status && !status2)
0189 return false;
0190
0191 return -EINVAL;
0192 }
0193
0194 static int scpsys_regulator_enable(struct scp_domain *scpd)
0195 {
0196 if (!scpd->supply)
0197 return 0;
0198
0199 return regulator_enable(scpd->supply);
0200 }
0201
0202 static int scpsys_regulator_disable(struct scp_domain *scpd)
0203 {
0204 if (!scpd->supply)
0205 return 0;
0206
0207 return regulator_disable(scpd->supply);
0208 }
0209
0210 static void scpsys_clk_disable(struct clk *clk[], int max_num)
0211 {
0212 int i;
0213
0214 for (i = max_num - 1; i >= 0; i--)
0215 clk_disable_unprepare(clk[i]);
0216 }
0217
0218 static int scpsys_clk_enable(struct clk *clk[], int max_num)
0219 {
0220 int i, ret = 0;
0221
0222 for (i = 0; i < max_num && clk[i]; i++) {
0223 ret = clk_prepare_enable(clk[i]);
0224 if (ret) {
0225 scpsys_clk_disable(clk, i);
0226 break;
0227 }
0228 }
0229
0230 return ret;
0231 }
0232
0233 static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
0234 {
0235 u32 val;
0236 u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
0237 int tmp;
0238
0239 val = readl(ctl_addr);
0240 val &= ~scpd->data->sram_pdn_bits;
0241 writel(val, ctl_addr);
0242
0243
0244 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
0245
0246
0247
0248
0249
0250 usleep_range(12000, 12100);
0251 } else {
0252
0253 int ret = readl_poll_timeout(ctl_addr, tmp,
0254 (tmp & pdn_ack) == 0,
0255 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
0256 if (ret < 0)
0257 return ret;
0258 }
0259
0260 return 0;
0261 }
0262
0263 static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
0264 {
0265 u32 val;
0266 u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
0267 int tmp;
0268
0269 val = readl(ctl_addr);
0270 val |= scpd->data->sram_pdn_bits;
0271 writel(val, ctl_addr);
0272
0273
0274 return readl_poll_timeout(ctl_addr, tmp,
0275 (tmp & pdn_ack) == pdn_ack,
0276 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
0277 }
0278
0279 static int scpsys_bus_protect_enable(struct scp_domain *scpd)
0280 {
0281 struct scp *scp = scpd->scp;
0282
0283 if (!scpd->data->bus_prot_mask)
0284 return 0;
0285
0286 return mtk_infracfg_set_bus_protection(scp->infracfg,
0287 scpd->data->bus_prot_mask,
0288 scp->bus_prot_reg_update);
0289 }
0290
0291 static int scpsys_bus_protect_disable(struct scp_domain *scpd)
0292 {
0293 struct scp *scp = scpd->scp;
0294
0295 if (!scpd->data->bus_prot_mask)
0296 return 0;
0297
0298 return mtk_infracfg_clear_bus_protection(scp->infracfg,
0299 scpd->data->bus_prot_mask,
0300 scp->bus_prot_reg_update);
0301 }
0302
0303 static int scpsys_power_on(struct generic_pm_domain *genpd)
0304 {
0305 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
0306 struct scp *scp = scpd->scp;
0307 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
0308 u32 val;
0309 int ret, tmp;
0310
0311 ret = scpsys_regulator_enable(scpd);
0312 if (ret < 0)
0313 return ret;
0314
0315 ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
0316 if (ret)
0317 goto err_clk;
0318
0319
0320 val = readl(ctl_addr);
0321 val |= PWR_ON_BIT;
0322 writel(val, ctl_addr);
0323 val |= PWR_ON_2ND_BIT;
0324 writel(val, ctl_addr);
0325
0326
0327 ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
0328 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
0329 if (ret < 0)
0330 goto err_pwr_ack;
0331
0332 val &= ~PWR_CLK_DIS_BIT;
0333 writel(val, ctl_addr);
0334
0335 val &= ~PWR_ISO_BIT;
0336 writel(val, ctl_addr);
0337
0338 val |= PWR_RST_B_BIT;
0339 writel(val, ctl_addr);
0340
0341 ret = scpsys_sram_enable(scpd, ctl_addr);
0342 if (ret < 0)
0343 goto err_pwr_ack;
0344
0345 ret = scpsys_bus_protect_disable(scpd);
0346 if (ret < 0)
0347 goto err_pwr_ack;
0348
0349 return 0;
0350
0351 err_pwr_ack:
0352 scpsys_clk_disable(scpd->clk, MAX_CLKS);
0353 err_clk:
0354 scpsys_regulator_disable(scpd);
0355
0356 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
0357
0358 return ret;
0359 }
0360
0361 static int scpsys_power_off(struct generic_pm_domain *genpd)
0362 {
0363 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
0364 struct scp *scp = scpd->scp;
0365 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
0366 u32 val;
0367 int ret, tmp;
0368
0369 ret = scpsys_bus_protect_enable(scpd);
0370 if (ret < 0)
0371 goto out;
0372
0373 ret = scpsys_sram_disable(scpd, ctl_addr);
0374 if (ret < 0)
0375 goto out;
0376
0377
0378 val = readl(ctl_addr);
0379 val |= PWR_ISO_BIT;
0380 writel(val, ctl_addr);
0381
0382 val &= ~PWR_RST_B_BIT;
0383 writel(val, ctl_addr);
0384
0385 val |= PWR_CLK_DIS_BIT;
0386 writel(val, ctl_addr);
0387
0388 val &= ~PWR_ON_BIT;
0389 writel(val, ctl_addr);
0390
0391 val &= ~PWR_ON_2ND_BIT;
0392 writel(val, ctl_addr);
0393
0394
0395 ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
0396 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
0397 if (ret < 0)
0398 goto out;
0399
0400 scpsys_clk_disable(scpd->clk, MAX_CLKS);
0401
0402 ret = scpsys_regulator_disable(scpd);
0403 if (ret < 0)
0404 goto out;
0405
0406 return 0;
0407
0408 out:
0409 dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
0410
0411 return ret;
0412 }
0413
0414 static void init_clks(struct platform_device *pdev, struct clk **clk)
0415 {
0416 int i;
0417
0418 for (i = CLK_NONE + 1; i < CLK_MAX; i++)
0419 clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
0420 }
0421
0422 static struct scp *init_scp(struct platform_device *pdev,
0423 const struct scp_domain_data *scp_domain_data, int num,
0424 const struct scp_ctrl_reg *scp_ctrl_reg,
0425 bool bus_prot_reg_update)
0426 {
0427 struct genpd_onecell_data *pd_data;
0428 struct resource *res;
0429 int i, j;
0430 struct scp *scp;
0431 struct clk *clk[CLK_MAX];
0432
0433 scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
0434 if (!scp)
0435 return ERR_PTR(-ENOMEM);
0436
0437 scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
0438 scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
0439
0440 scp->bus_prot_reg_update = bus_prot_reg_update;
0441
0442 scp->dev = &pdev->dev;
0443
0444 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0445 scp->base = devm_ioremap_resource(&pdev->dev, res);
0446 if (IS_ERR(scp->base))
0447 return ERR_CAST(scp->base);
0448
0449 scp->domains = devm_kcalloc(&pdev->dev,
0450 num, sizeof(*scp->domains), GFP_KERNEL);
0451 if (!scp->domains)
0452 return ERR_PTR(-ENOMEM);
0453
0454 pd_data = &scp->pd_data;
0455
0456 pd_data->domains = devm_kcalloc(&pdev->dev,
0457 num, sizeof(*pd_data->domains), GFP_KERNEL);
0458 if (!pd_data->domains)
0459 return ERR_PTR(-ENOMEM);
0460
0461 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
0462 "infracfg");
0463 if (IS_ERR(scp->infracfg)) {
0464 dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
0465 PTR_ERR(scp->infracfg));
0466 return ERR_CAST(scp->infracfg);
0467 }
0468
0469 for (i = 0; i < num; i++) {
0470 struct scp_domain *scpd = &scp->domains[i];
0471 const struct scp_domain_data *data = &scp_domain_data[i];
0472
0473 scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
0474 if (IS_ERR(scpd->supply)) {
0475 if (PTR_ERR(scpd->supply) == -ENODEV)
0476 scpd->supply = NULL;
0477 else
0478 return ERR_CAST(scpd->supply);
0479 }
0480 }
0481
0482 pd_data->num_domains = num;
0483
0484 init_clks(pdev, clk);
0485
0486 for (i = 0; i < num; i++) {
0487 struct scp_domain *scpd = &scp->domains[i];
0488 struct generic_pm_domain *genpd = &scpd->genpd;
0489 const struct scp_domain_data *data = &scp_domain_data[i];
0490
0491 pd_data->domains[i] = genpd;
0492 scpd->scp = scp;
0493
0494 scpd->data = data;
0495
0496 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
0497 struct clk *c = clk[data->clk_id[j]];
0498
0499 if (IS_ERR(c)) {
0500 dev_err(&pdev->dev, "%s: clk unavailable\n",
0501 data->name);
0502 return ERR_CAST(c);
0503 }
0504
0505 scpd->clk[j] = c;
0506 }
0507
0508 genpd->name = data->name;
0509 genpd->power_off = scpsys_power_off;
0510 genpd->power_on = scpsys_power_on;
0511 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
0512 genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
0513 }
0514
0515 return scp;
0516 }
0517
0518 static void mtk_register_power_domains(struct platform_device *pdev,
0519 struct scp *scp, int num)
0520 {
0521 struct genpd_onecell_data *pd_data;
0522 int i, ret;
0523
0524 for (i = 0; i < num; i++) {
0525 struct scp_domain *scpd = &scp->domains[i];
0526 struct generic_pm_domain *genpd = &scpd->genpd;
0527 bool on;
0528
0529
0530
0531
0532
0533
0534
0535 on = !WARN_ON(genpd->power_on(genpd) < 0);
0536
0537 pm_genpd_init(genpd, NULL, !on);
0538 }
0539
0540
0541
0542
0543
0544
0545
0546 pd_data = &scp->pd_data;
0547
0548 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
0549 if (ret)
0550 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
0551 }
0552
0553
0554
0555
0556
0557 static const struct scp_domain_data scp_domain_data_mt2701[] = {
0558 [MT2701_POWER_DOMAIN_CONN] = {
0559 .name = "conn",
0560 .sta_mask = PWR_STATUS_CONN,
0561 .ctl_offs = SPM_CONN_PWR_CON,
0562 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
0563 MT2701_TOP_AXI_PROT_EN_CONN_S,
0564 .clk_id = {CLK_NONE},
0565 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0566 },
0567 [MT2701_POWER_DOMAIN_DISP] = {
0568 .name = "disp",
0569 .sta_mask = PWR_STATUS_DISP,
0570 .ctl_offs = SPM_DIS_PWR_CON,
0571 .sram_pdn_bits = GENMASK(11, 8),
0572 .clk_id = {CLK_MM},
0573 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
0574 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0575 },
0576 [MT2701_POWER_DOMAIN_MFG] = {
0577 .name = "mfg",
0578 .sta_mask = PWR_STATUS_MFG,
0579 .ctl_offs = SPM_MFG_PWR_CON,
0580 .sram_pdn_bits = GENMASK(11, 8),
0581 .sram_pdn_ack_bits = GENMASK(12, 12),
0582 .clk_id = {CLK_MFG},
0583 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0584 },
0585 [MT2701_POWER_DOMAIN_VDEC] = {
0586 .name = "vdec",
0587 .sta_mask = PWR_STATUS_VDEC,
0588 .ctl_offs = SPM_VDE_PWR_CON,
0589 .sram_pdn_bits = GENMASK(11, 8),
0590 .sram_pdn_ack_bits = GENMASK(12, 12),
0591 .clk_id = {CLK_MM},
0592 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0593 },
0594 [MT2701_POWER_DOMAIN_ISP] = {
0595 .name = "isp",
0596 .sta_mask = PWR_STATUS_ISP,
0597 .ctl_offs = SPM_ISP_PWR_CON,
0598 .sram_pdn_bits = GENMASK(11, 8),
0599 .sram_pdn_ack_bits = GENMASK(13, 12),
0600 .clk_id = {CLK_MM},
0601 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0602 },
0603 [MT2701_POWER_DOMAIN_BDP] = {
0604 .name = "bdp",
0605 .sta_mask = PWR_STATUS_BDP,
0606 .ctl_offs = SPM_BDP_PWR_CON,
0607 .sram_pdn_bits = GENMASK(11, 8),
0608 .clk_id = {CLK_NONE},
0609 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0610 },
0611 [MT2701_POWER_DOMAIN_ETH] = {
0612 .name = "eth",
0613 .sta_mask = PWR_STATUS_ETH,
0614 .ctl_offs = SPM_ETH_PWR_CON,
0615 .sram_pdn_bits = GENMASK(11, 8),
0616 .sram_pdn_ack_bits = GENMASK(15, 12),
0617 .clk_id = {CLK_ETHIF},
0618 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0619 },
0620 [MT2701_POWER_DOMAIN_HIF] = {
0621 .name = "hif",
0622 .sta_mask = PWR_STATUS_HIF,
0623 .ctl_offs = SPM_HIF_PWR_CON,
0624 .sram_pdn_bits = GENMASK(11, 8),
0625 .sram_pdn_ack_bits = GENMASK(15, 12),
0626 .clk_id = {CLK_ETHIF},
0627 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0628 },
0629 [MT2701_POWER_DOMAIN_IFR_MSC] = {
0630 .name = "ifr_msc",
0631 .sta_mask = PWR_STATUS_IFR_MSC,
0632 .ctl_offs = SPM_IFR_MSC_PWR_CON,
0633 .clk_id = {CLK_NONE},
0634 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0635 },
0636 };
0637
0638
0639
0640
0641 static const struct scp_domain_data scp_domain_data_mt2712[] = {
0642 [MT2712_POWER_DOMAIN_MM] = {
0643 .name = "mm",
0644 .sta_mask = PWR_STATUS_DISP,
0645 .ctl_offs = SPM_DIS_PWR_CON,
0646 .sram_pdn_bits = GENMASK(8, 8),
0647 .sram_pdn_ack_bits = GENMASK(12, 12),
0648 .clk_id = {CLK_MM},
0649 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0650 },
0651 [MT2712_POWER_DOMAIN_VDEC] = {
0652 .name = "vdec",
0653 .sta_mask = PWR_STATUS_VDEC,
0654 .ctl_offs = SPM_VDE_PWR_CON,
0655 .sram_pdn_bits = GENMASK(8, 8),
0656 .sram_pdn_ack_bits = GENMASK(12, 12),
0657 .clk_id = {CLK_MM, CLK_VDEC},
0658 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0659 },
0660 [MT2712_POWER_DOMAIN_VENC] = {
0661 .name = "venc",
0662 .sta_mask = PWR_STATUS_VENC,
0663 .ctl_offs = SPM_VEN_PWR_CON,
0664 .sram_pdn_bits = GENMASK(11, 8),
0665 .sram_pdn_ack_bits = GENMASK(15, 12),
0666 .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
0667 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0668 },
0669 [MT2712_POWER_DOMAIN_ISP] = {
0670 .name = "isp",
0671 .sta_mask = PWR_STATUS_ISP,
0672 .ctl_offs = SPM_ISP_PWR_CON,
0673 .sram_pdn_bits = GENMASK(11, 8),
0674 .sram_pdn_ack_bits = GENMASK(13, 12),
0675 .clk_id = {CLK_MM},
0676 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0677 },
0678 [MT2712_POWER_DOMAIN_AUDIO] = {
0679 .name = "audio",
0680 .sta_mask = PWR_STATUS_AUDIO,
0681 .ctl_offs = SPM_AUDIO_PWR_CON,
0682 .sram_pdn_bits = GENMASK(11, 8),
0683 .sram_pdn_ack_bits = GENMASK(15, 12),
0684 .clk_id = {CLK_AUDIO},
0685 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0686 },
0687 [MT2712_POWER_DOMAIN_USB] = {
0688 .name = "usb",
0689 .sta_mask = PWR_STATUS_USB,
0690 .ctl_offs = SPM_USB_PWR_CON,
0691 .sram_pdn_bits = GENMASK(10, 8),
0692 .sram_pdn_ack_bits = GENMASK(14, 12),
0693 .clk_id = {CLK_NONE},
0694 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0695 },
0696 [MT2712_POWER_DOMAIN_USB2] = {
0697 .name = "usb2",
0698 .sta_mask = PWR_STATUS_USB2,
0699 .ctl_offs = SPM_USB2_PWR_CON,
0700 .sram_pdn_bits = GENMASK(10, 8),
0701 .sram_pdn_ack_bits = GENMASK(14, 12),
0702 .clk_id = {CLK_NONE},
0703 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0704 },
0705 [MT2712_POWER_DOMAIN_MFG] = {
0706 .name = "mfg",
0707 .sta_mask = PWR_STATUS_MFG,
0708 .ctl_offs = SPM_MFG_PWR_CON,
0709 .sram_pdn_bits = GENMASK(8, 8),
0710 .sram_pdn_ack_bits = GENMASK(16, 16),
0711 .clk_id = {CLK_MFG},
0712 .bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
0713 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0714 },
0715 [MT2712_POWER_DOMAIN_MFG_SC1] = {
0716 .name = "mfg_sc1",
0717 .sta_mask = BIT(22),
0718 .ctl_offs = 0x02c0,
0719 .sram_pdn_bits = GENMASK(8, 8),
0720 .sram_pdn_ack_bits = GENMASK(16, 16),
0721 .clk_id = {CLK_NONE},
0722 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0723 },
0724 [MT2712_POWER_DOMAIN_MFG_SC2] = {
0725 .name = "mfg_sc2",
0726 .sta_mask = BIT(23),
0727 .ctl_offs = 0x02c4,
0728 .sram_pdn_bits = GENMASK(8, 8),
0729 .sram_pdn_ack_bits = GENMASK(16, 16),
0730 .clk_id = {CLK_NONE},
0731 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0732 },
0733 [MT2712_POWER_DOMAIN_MFG_SC3] = {
0734 .name = "mfg_sc3",
0735 .sta_mask = BIT(30),
0736 .ctl_offs = 0x01f8,
0737 .sram_pdn_bits = GENMASK(8, 8),
0738 .sram_pdn_ack_bits = GENMASK(16, 16),
0739 .clk_id = {CLK_NONE},
0740 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0741 },
0742 };
0743
0744 static const struct scp_subdomain scp_subdomain_mt2712[] = {
0745 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC},
0746 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC},
0747 {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP},
0748 {MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1},
0749 {MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2},
0750 {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3},
0751 };
0752
0753
0754
0755
0756
0757 static const struct scp_domain_data scp_domain_data_mt6797[] = {
0758 [MT6797_POWER_DOMAIN_VDEC] = {
0759 .name = "vdec",
0760 .sta_mask = BIT(7),
0761 .ctl_offs = 0x300,
0762 .sram_pdn_bits = GENMASK(8, 8),
0763 .sram_pdn_ack_bits = GENMASK(12, 12),
0764 .clk_id = {CLK_VDEC},
0765 },
0766 [MT6797_POWER_DOMAIN_VENC] = {
0767 .name = "venc",
0768 .sta_mask = BIT(21),
0769 .ctl_offs = 0x304,
0770 .sram_pdn_bits = GENMASK(11, 8),
0771 .sram_pdn_ack_bits = GENMASK(15, 12),
0772 .clk_id = {CLK_NONE},
0773 },
0774 [MT6797_POWER_DOMAIN_ISP] = {
0775 .name = "isp",
0776 .sta_mask = BIT(5),
0777 .ctl_offs = 0x308,
0778 .sram_pdn_bits = GENMASK(9, 8),
0779 .sram_pdn_ack_bits = GENMASK(13, 12),
0780 .clk_id = {CLK_NONE},
0781 },
0782 [MT6797_POWER_DOMAIN_MM] = {
0783 .name = "mm",
0784 .sta_mask = BIT(3),
0785 .ctl_offs = 0x30C,
0786 .sram_pdn_bits = GENMASK(8, 8),
0787 .sram_pdn_ack_bits = GENMASK(12, 12),
0788 .clk_id = {CLK_MM},
0789 .bus_prot_mask = (BIT(1) | BIT(2)),
0790 },
0791 [MT6797_POWER_DOMAIN_AUDIO] = {
0792 .name = "audio",
0793 .sta_mask = BIT(24),
0794 .ctl_offs = 0x314,
0795 .sram_pdn_bits = GENMASK(11, 8),
0796 .sram_pdn_ack_bits = GENMASK(15, 12),
0797 .clk_id = {CLK_NONE},
0798 },
0799 [MT6797_POWER_DOMAIN_MFG_ASYNC] = {
0800 .name = "mfg_async",
0801 .sta_mask = BIT(13),
0802 .ctl_offs = 0x334,
0803 .sram_pdn_bits = 0,
0804 .sram_pdn_ack_bits = 0,
0805 .clk_id = {CLK_MFG},
0806 },
0807 [MT6797_POWER_DOMAIN_MJC] = {
0808 .name = "mjc",
0809 .sta_mask = BIT(20),
0810 .ctl_offs = 0x310,
0811 .sram_pdn_bits = GENMASK(8, 8),
0812 .sram_pdn_ack_bits = GENMASK(12, 12),
0813 .clk_id = {CLK_NONE},
0814 },
0815 };
0816
0817 #define SPM_PWR_STATUS_MT6797 0x0180
0818 #define SPM_PWR_STATUS_2ND_MT6797 0x0184
0819
0820 static const struct scp_subdomain scp_subdomain_mt6797[] = {
0821 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
0822 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
0823 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
0824 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
0825 };
0826
0827
0828
0829
0830
0831 static const struct scp_domain_data scp_domain_data_mt7622[] = {
0832 [MT7622_POWER_DOMAIN_ETHSYS] = {
0833 .name = "ethsys",
0834 .sta_mask = PWR_STATUS_ETHSYS,
0835 .ctl_offs = SPM_ETHSYS_PWR_CON,
0836 .sram_pdn_bits = GENMASK(11, 8),
0837 .sram_pdn_ack_bits = GENMASK(15, 12),
0838 .clk_id = {CLK_NONE},
0839 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
0840 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0841 },
0842 [MT7622_POWER_DOMAIN_HIF0] = {
0843 .name = "hif0",
0844 .sta_mask = PWR_STATUS_HIF0,
0845 .ctl_offs = SPM_HIF0_PWR_CON,
0846 .sram_pdn_bits = GENMASK(11, 8),
0847 .sram_pdn_ack_bits = GENMASK(15, 12),
0848 .clk_id = {CLK_HIFSEL},
0849 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
0850 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0851 },
0852 [MT7622_POWER_DOMAIN_HIF1] = {
0853 .name = "hif1",
0854 .sta_mask = PWR_STATUS_HIF1,
0855 .ctl_offs = SPM_HIF1_PWR_CON,
0856 .sram_pdn_bits = GENMASK(11, 8),
0857 .sram_pdn_ack_bits = GENMASK(15, 12),
0858 .clk_id = {CLK_HIFSEL},
0859 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
0860 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0861 },
0862 [MT7622_POWER_DOMAIN_WB] = {
0863 .name = "wb",
0864 .sta_mask = PWR_STATUS_WB,
0865 .ctl_offs = SPM_WB_PWR_CON,
0866 .sram_pdn_bits = 0,
0867 .sram_pdn_ack_bits = 0,
0868 .clk_id = {CLK_NONE},
0869 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
0870 .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM,
0871 },
0872 };
0873
0874
0875
0876
0877
0878 static const struct scp_domain_data scp_domain_data_mt7623a[] = {
0879 [MT7623A_POWER_DOMAIN_CONN] = {
0880 .name = "conn",
0881 .sta_mask = PWR_STATUS_CONN,
0882 .ctl_offs = SPM_CONN_PWR_CON,
0883 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
0884 MT2701_TOP_AXI_PROT_EN_CONN_S,
0885 .clk_id = {CLK_NONE},
0886 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0887 },
0888 [MT7623A_POWER_DOMAIN_ETH] = {
0889 .name = "eth",
0890 .sta_mask = PWR_STATUS_ETH,
0891 .ctl_offs = SPM_ETH_PWR_CON,
0892 .sram_pdn_bits = GENMASK(11, 8),
0893 .sram_pdn_ack_bits = GENMASK(15, 12),
0894 .clk_id = {CLK_ETHIF},
0895 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0896 },
0897 [MT7623A_POWER_DOMAIN_HIF] = {
0898 .name = "hif",
0899 .sta_mask = PWR_STATUS_HIF,
0900 .ctl_offs = SPM_HIF_PWR_CON,
0901 .sram_pdn_bits = GENMASK(11, 8),
0902 .sram_pdn_ack_bits = GENMASK(15, 12),
0903 .clk_id = {CLK_ETHIF},
0904 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0905 },
0906 [MT7623A_POWER_DOMAIN_IFR_MSC] = {
0907 .name = "ifr_msc",
0908 .sta_mask = PWR_STATUS_IFR_MSC,
0909 .ctl_offs = SPM_IFR_MSC_PWR_CON,
0910 .clk_id = {CLK_NONE},
0911 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0912 },
0913 };
0914
0915
0916
0917
0918
0919 static const struct scp_domain_data scp_domain_data_mt8173[] = {
0920 [MT8173_POWER_DOMAIN_VDEC] = {
0921 .name = "vdec",
0922 .sta_mask = PWR_STATUS_VDEC,
0923 .ctl_offs = SPM_VDE_PWR_CON,
0924 .sram_pdn_bits = GENMASK(11, 8),
0925 .sram_pdn_ack_bits = GENMASK(12, 12),
0926 .clk_id = {CLK_MM},
0927 },
0928 [MT8173_POWER_DOMAIN_VENC] = {
0929 .name = "venc",
0930 .sta_mask = PWR_STATUS_VENC,
0931 .ctl_offs = SPM_VEN_PWR_CON,
0932 .sram_pdn_bits = GENMASK(11, 8),
0933 .sram_pdn_ack_bits = GENMASK(15, 12),
0934 .clk_id = {CLK_MM, CLK_VENC},
0935 },
0936 [MT8173_POWER_DOMAIN_ISP] = {
0937 .name = "isp",
0938 .sta_mask = PWR_STATUS_ISP,
0939 .ctl_offs = SPM_ISP_PWR_CON,
0940 .sram_pdn_bits = GENMASK(11, 8),
0941 .sram_pdn_ack_bits = GENMASK(13, 12),
0942 .clk_id = {CLK_MM},
0943 },
0944 [MT8173_POWER_DOMAIN_MM] = {
0945 .name = "mm",
0946 .sta_mask = PWR_STATUS_DISP,
0947 .ctl_offs = SPM_DIS_PWR_CON,
0948 .sram_pdn_bits = GENMASK(11, 8),
0949 .sram_pdn_ack_bits = GENMASK(12, 12),
0950 .clk_id = {CLK_MM},
0951 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
0952 MT8173_TOP_AXI_PROT_EN_MM_M1,
0953 },
0954 [MT8173_POWER_DOMAIN_VENC_LT] = {
0955 .name = "venc_lt",
0956 .sta_mask = PWR_STATUS_VENC_LT,
0957 .ctl_offs = SPM_VEN2_PWR_CON,
0958 .sram_pdn_bits = GENMASK(11, 8),
0959 .sram_pdn_ack_bits = GENMASK(15, 12),
0960 .clk_id = {CLK_MM, CLK_VENC_LT},
0961 },
0962 [MT8173_POWER_DOMAIN_AUDIO] = {
0963 .name = "audio",
0964 .sta_mask = PWR_STATUS_AUDIO,
0965 .ctl_offs = SPM_AUDIO_PWR_CON,
0966 .sram_pdn_bits = GENMASK(11, 8),
0967 .sram_pdn_ack_bits = GENMASK(15, 12),
0968 .clk_id = {CLK_NONE},
0969 },
0970 [MT8173_POWER_DOMAIN_USB] = {
0971 .name = "usb",
0972 .sta_mask = PWR_STATUS_USB,
0973 .ctl_offs = SPM_USB_PWR_CON,
0974 .sram_pdn_bits = GENMASK(11, 8),
0975 .sram_pdn_ack_bits = GENMASK(15, 12),
0976 .clk_id = {CLK_NONE},
0977 .caps = MTK_SCPD_ACTIVE_WAKEUP,
0978 },
0979 [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
0980 .name = "mfg_async",
0981 .sta_mask = PWR_STATUS_MFG_ASYNC,
0982 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
0983 .sram_pdn_bits = GENMASK(11, 8),
0984 .sram_pdn_ack_bits = 0,
0985 .clk_id = {CLK_MFG},
0986 },
0987 [MT8173_POWER_DOMAIN_MFG_2D] = {
0988 .name = "mfg_2d",
0989 .sta_mask = PWR_STATUS_MFG_2D,
0990 .ctl_offs = SPM_MFG_2D_PWR_CON,
0991 .sram_pdn_bits = GENMASK(11, 8),
0992 .sram_pdn_ack_bits = GENMASK(13, 12),
0993 .clk_id = {CLK_NONE},
0994 },
0995 [MT8173_POWER_DOMAIN_MFG] = {
0996 .name = "mfg",
0997 .sta_mask = PWR_STATUS_MFG,
0998 .ctl_offs = SPM_MFG_PWR_CON,
0999 .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
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
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_match_ptr(of_scpsys_match_tbl),
1145 },
1146 };
1147 builtin_platform_driver(scpsys_drv);