cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mtk-scpsys.c (28958B)


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