Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
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  /* MT8173, MT2712 */
0038 #define SPM_BDP_PWR_CON         0x029c  /* MT2701 */
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  /* MT2712 */
0046 #define SPM_ETHSYS_PWR_CON      0x02e0  /* MT7622 */
0047 #define SPM_HIF0_PWR_CON        0x02e4  /* MT7622 */
0048 #define SPM_HIF1_PWR_CON        0x02e8  /* MT7622 */
0049 #define SPM_WB_PWR_CON          0x02ec  /* MT7622 */
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) /* MT2712 */
0070 #define PWR_STATUS_VENC_LT      BIT(20)
0071 #define PWR_STATUS_VENC         BIT(21)
0072 #define PWR_STATUS_MFG_2D       BIT(22) /* MT8173 */
0073 #define PWR_STATUS_MFG_ASYNC        BIT(23) /* MT8173 */
0074 #define PWR_STATUS_AUDIO        BIT(24) /* MT8173, MT2712 */
0075 #define PWR_STATUS_USB          BIT(25) /* MT8173, MT2712 */
0076 #define PWR_STATUS_ETHSYS       BIT(24) /* MT7622 */
0077 #define PWR_STATUS_HIF0         BIT(25) /* MT7622 */
0078 #define PWR_STATUS_HIF1         BIT(26) /* MT7622 */
0079 #define PWR_STATUS_WB           BIT(27) /* MT7622 */
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  * struct scp_domain_data - scp domain data for power on/off flow
0113  * @name: The domain name.
0114  * @sta_mask: The mask for power on/off status bit.
0115  * @ctl_offs: The offset for main power control register.
0116  * @sram_pdn_bits: The mask for sram power control bits.
0117  * @sram_pdn_ack_bits: The mask for sram power control acked bits.
0118  * @bus_prot_mask: The mask for single step bus protection.
0119  * @clk_id: The basic clocks required by this power domain.
0120  * @caps: The flag for active wake-up action.
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      * A domain is on when both status bits are set. If only one is set
0183      * return an error. This happens while powering up a domain
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     /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
0244     if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
0245         /*
0246          * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
0247          * MT7622_POWER_DOMAIN_WB and thus just a trivial setup
0248          * is applied here.
0249          */
0250         usleep_range(12000, 12100);
0251     } else {
0252         /* Either wait until SRAM_PDN_ACK all 1 or 0 */
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     /* Either wait until SRAM_PDN_ACK all 1 or 0 */
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     /* subsys power on */
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     /* wait until PWR_ACK = 1 */
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     /* subsys power off */
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     /* wait until PWR_ACK = 0 */
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          * Initially turn on all domains to make the domains usable
0531          * with !CONFIG_PM and to get the hardware in sync with the
0532          * software.  The unused domains will be switched off during
0533          * late_init time.
0534          */
0535         on = !WARN_ON(genpd->power_on(genpd) < 0);
0536 
0537         pm_genpd_init(genpd, NULL, !on);
0538     }
0539 
0540     /*
0541      * We are not allowed to fail here since there is no way to unregister
0542      * a power domain. Once registered above we have to keep the domains
0543      * valid.
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  * MT2701 power domain support
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  * MT2712 power domain support
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  * MT6797 power domain support
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  * MT7622 power domain support
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  * MT7623A power domain support
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  * MT8173 power domain support
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  * scpsys driver init
1082  */
1083 
1084 static const struct of_device_id of_scpsys_match_tbl[] = {
1085     {
1086         .compatible = "mediatek,mt2701-scpsys",
1087         .data = &mt2701_data,
1088     }, {
1089         .compatible = "mediatek,mt2712-scpsys",
1090         .data = &mt2712_data,
1091     }, {
1092         .compatible = "mediatek,mt6797-scpsys",
1093         .data = &mt6797_data,
1094     }, {
1095         .compatible = "mediatek,mt7622-scpsys",
1096         .data = &mt7622_data,
1097     }, {
1098         .compatible = "mediatek,mt7623a-scpsys",
1099         .data = &mt7623a_data,
1100     }, {
1101         .compatible = "mediatek,mt8173-scpsys",
1102         .data = &mt8173_data,
1103     }, {
1104         /* sentinel */
1105     }
1106 };
1107 
1108 static int scpsys_probe(struct platform_device *pdev)
1109 {
1110     const struct scp_subdomain *sd;
1111     const struct scp_soc_data *soc;
1112     struct scp *scp;
1113     struct genpd_onecell_data *pd_data;
1114     int i, ret;
1115 
1116     soc = of_device_get_match_data(&pdev->dev);
1117 
1118     scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
1119             soc->bus_prot_reg_update);
1120     if (IS_ERR(scp))
1121         return PTR_ERR(scp);
1122 
1123     mtk_register_power_domains(pdev, scp, soc->num_domains);
1124 
1125     pd_data = &scp->pd_data;
1126 
1127     for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) {
1128         ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
1129                          pd_data->domains[sd->subdomain]);
1130         if (ret && IS_ENABLED(CONFIG_PM))
1131             dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
1132                 ret);
1133     }
1134 
1135     return 0;
1136 }
1137 
1138 static struct platform_driver scpsys_drv = {
1139     .probe = scpsys_probe,
1140     .driver = {
1141         .name = "mtk-scpsys",
1142         .suppress_bind_attrs = true,
1143         .owner = THIS_MODULE,
1144         .of_match_table = of_match_ptr(of_scpsys_match_tbl),
1145     },
1146 };
1147 builtin_platform_driver(scpsys_drv);