Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
   4 */
   5#include <linux/clk.h>
   6#include <linux/init.h>
   7#include <linux/io.h>
   8#include <linux/iopoll.h>
   9#include <linux/mfd/syscon.h>
  10#include <linux/of.h>
  11#include <linux/platform_device.h>
  12#include <linux/pm_domain.h>
  13#include <linux/regulator/consumer.h>
  14#include <linux/soc/mediatek/infracfg.h>
  15
  16#include <dt-bindings/power/mt2701-power.h>
  17#include <dt-bindings/power/mt2712-power.h>
  18#include <dt-bindings/power/mt6797-power.h>
  19#include <dt-bindings/power/mt7622-power.h>
  20#include <dt-bindings/power/mt7623a-power.h>
  21#include <dt-bindings/power/mt8173-power.h>
  22
  23#define MTK_POLL_DELAY_US   10
  24#define MTK_POLL_TIMEOUT    USEC_PER_SEC
  25
  26#define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
  27#define MTK_SCPD_FWAIT_SRAM		BIT(1)
  28#define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
  29
  30#define SPM_VDE_PWR_CON			0x0210
  31#define SPM_MFG_PWR_CON			0x0214
  32#define SPM_VEN_PWR_CON			0x0230
  33#define SPM_ISP_PWR_CON			0x0238
  34#define SPM_DIS_PWR_CON			0x023c
  35#define SPM_CONN_PWR_CON		0x0280
  36#define SPM_VEN2_PWR_CON		0x0298
  37#define SPM_AUDIO_PWR_CON		0x029c	/* MT8173, MT2712 */
  38#define SPM_BDP_PWR_CON			0x029c	/* MT2701 */
  39#define SPM_ETH_PWR_CON			0x02a0
  40#define SPM_HIF_PWR_CON			0x02a4
  41#define SPM_IFR_MSC_PWR_CON		0x02a8
  42#define SPM_MFG_2D_PWR_CON		0x02c0
  43#define SPM_MFG_ASYNC_PWR_CON		0x02c4
  44#define SPM_USB_PWR_CON			0x02cc
  45#define SPM_USB2_PWR_CON		0x02d4	/* MT2712 */
  46#define SPM_ETHSYS_PWR_CON		0x02e0	/* MT7622 */
  47#define SPM_HIF0_PWR_CON		0x02e4	/* MT7622 */
  48#define SPM_HIF1_PWR_CON		0x02e8	/* MT7622 */
  49#define SPM_WB_PWR_CON			0x02ec	/* MT7622 */
  50
  51#define SPM_PWR_STATUS			0x060c
  52#define SPM_PWR_STATUS_2ND		0x0610
  53
  54#define PWR_RST_B_BIT			BIT(0)
  55#define PWR_ISO_BIT			BIT(1)
  56#define PWR_ON_BIT			BIT(2)
  57#define PWR_ON_2ND_BIT			BIT(3)
  58#define PWR_CLK_DIS_BIT			BIT(4)
  59
  60#define PWR_STATUS_CONN			BIT(1)
  61#define PWR_STATUS_DISP			BIT(3)
  62#define PWR_STATUS_MFG			BIT(4)
  63#define PWR_STATUS_ISP			BIT(5)
  64#define PWR_STATUS_VDEC			BIT(7)
  65#define PWR_STATUS_BDP			BIT(14)
  66#define PWR_STATUS_ETH			BIT(15)
  67#define PWR_STATUS_HIF			BIT(16)
  68#define PWR_STATUS_IFR_MSC		BIT(17)
  69#define PWR_STATUS_USB2			BIT(19)	/* MT2712 */
  70#define PWR_STATUS_VENC_LT		BIT(20)
  71#define PWR_STATUS_VENC			BIT(21)
  72#define PWR_STATUS_MFG_2D		BIT(22)	/* MT8173 */
  73#define PWR_STATUS_MFG_ASYNC		BIT(23)	/* MT8173 */
  74#define PWR_STATUS_AUDIO		BIT(24)	/* MT8173, MT2712 */
  75#define PWR_STATUS_USB			BIT(25)	/* MT8173, MT2712 */
  76#define PWR_STATUS_ETHSYS		BIT(24)	/* MT7622 */
  77#define PWR_STATUS_HIF0			BIT(25)	/* MT7622 */
  78#define PWR_STATUS_HIF1			BIT(26)	/* MT7622 */
  79#define PWR_STATUS_WB			BIT(27)	/* MT7622 */
  80
  81enum clk_id {
  82	CLK_NONE,
  83	CLK_MM,
  84	CLK_MFG,
  85	CLK_VENC,
  86	CLK_VENC_LT,
  87	CLK_ETHIF,
  88	CLK_VDEC,
  89	CLK_HIFSEL,
  90	CLK_JPGDEC,
  91	CLK_AUDIO,
  92	CLK_MAX,
  93};
  94
  95static const char * const clk_names[] = {
  96	NULL,
  97	"mm",
  98	"mfg",
  99	"venc",
 100	"venc_lt",
 101	"ethif",
 102	"vdec",
 103	"hif_sel",
 104	"jpgdec",
 105	"audio",
 106	NULL,
 107};
 108
 109#define MAX_CLKS	3
 110
 111/**
 112 * struct scp_domain_data - scp domain data for power on/off flow
 113 * @name: The domain name.
 114 * @sta_mask: The mask for power on/off status bit.
 115 * @ctl_offs: The offset for main power control register.
 116 * @sram_pdn_bits: The mask for sram power control bits.
 117 * @sram_pdn_ack_bits: The mask for sram power control acked bits.
 118 * @bus_prot_mask: The mask for single step bus protection.
 119 * @clk_id: The basic clocks required by this power domain.
 120 * @caps: The flag for active wake-up action.
 121 */
 122struct scp_domain_data {
 123	const char *name;
 124	u32 sta_mask;
 125	int ctl_offs;
 126	u32 sram_pdn_bits;
 127	u32 sram_pdn_ack_bits;
 128	u32 bus_prot_mask;
 129	enum clk_id clk_id[MAX_CLKS];
 130	u8 caps;
 131};
 132
 133struct scp;
 134
 135struct scp_domain {
 136	struct generic_pm_domain genpd;
 137	struct scp *scp;
 138	struct clk *clk[MAX_CLKS];
 139	const struct scp_domain_data *data;
 140	struct regulator *supply;
 141};
 142
 143struct scp_ctrl_reg {
 144	int pwr_sta_offs;
 145	int pwr_sta2nd_offs;
 146};
 147
 148struct scp {
 149	struct scp_domain *domains;
 150	struct genpd_onecell_data pd_data;
 151	struct device *dev;
 152	void __iomem *base;
 153	struct regmap *infracfg;
 154	struct scp_ctrl_reg ctrl_reg;
 155	bool bus_prot_reg_update;
 156};
 157
 158struct scp_subdomain {
 159	int origin;
 160	int subdomain;
 161};
 162
 163struct scp_soc_data {
 164	const struct scp_domain_data *domains;
 165	int num_domains;
 166	const struct scp_subdomain *subdomains;
 167	int num_subdomains;
 168	const struct scp_ctrl_reg regs;
 169	bool bus_prot_reg_update;
 170};
 171
 172static int scpsys_domain_is_on(struct scp_domain *scpd)
 173{
 174	struct scp *scp = scpd->scp;
 175
 176	u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
 177						scpd->data->sta_mask;
 178	u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
 179						scpd->data->sta_mask;
 180
 181	/*
 182	 * A domain is on when both status bits are set. If only one is set
 183	 * return an error. This happens while powering up a domain
 184	 */
 185
 186	if (status && status2)
 187		return true;
 188	if (!status && !status2)
 189		return false;
 190
 191	return -EINVAL;
 192}
 193
 194static int scpsys_regulator_enable(struct scp_domain *scpd)
 195{
 196	if (!scpd->supply)
 197		return 0;
 198
 199	return regulator_enable(scpd->supply);
 200}
 201
 202static int scpsys_regulator_disable(struct scp_domain *scpd)
 203{
 204	if (!scpd->supply)
 205		return 0;
 206
 207	return regulator_disable(scpd->supply);
 208}
 209
 210static void scpsys_clk_disable(struct clk *clk[], int max_num)
 211{
 212	int i;
 213
 214	for (i = max_num - 1; i >= 0; i--)
 215		clk_disable_unprepare(clk[i]);
 216}
 217
 218static int scpsys_clk_enable(struct clk *clk[], int max_num)
 219{
 220	int i, ret = 0;
 221
 222	for (i = 0; i < max_num && clk[i]; i++) {
 223		ret = clk_prepare_enable(clk[i]);
 224		if (ret) {
 225			scpsys_clk_disable(clk, i);
 226			break;
 227		}
 228	}
 229
 230	return ret;
 231}
 232
 233static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
 234{
 235	u32 val;
 236	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
 237	int tmp;
 238
 239	val = readl(ctl_addr);
 240	val &= ~scpd->data->sram_pdn_bits;
 241	writel(val, ctl_addr);
 242
 243	/* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
 244	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
 245		/*
 246		 * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
 247		 * MT7622_POWER_DOMAIN_WB and thus just a trivial setup
 248		 * is applied here.
 249		 */
 250		usleep_range(12000, 12100);
 251	} else {
 252		/* Either wait until SRAM_PDN_ACK all 1 or 0 */
 253		int ret = readl_poll_timeout(ctl_addr, tmp,
 254				(tmp & pdn_ack) == 0,
 255				MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 256		if (ret < 0)
 257			return ret;
 258	}
 259
 260	return 0;
 261}
 262
 263static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
 264{
 265	u32 val;
 266	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
 267	int tmp;
 268
 269	val = readl(ctl_addr);
 270	val |= scpd->data->sram_pdn_bits;
 271	writel(val, ctl_addr);
 272
 273	/* Either wait until SRAM_PDN_ACK all 1 or 0 */
 274	return readl_poll_timeout(ctl_addr, tmp,
 275			(tmp & pdn_ack) == pdn_ack,
 276			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 277}
 278
 279static int scpsys_bus_protect_enable(struct scp_domain *scpd)
 280{
 281	struct scp *scp = scpd->scp;
 282
 283	if (!scpd->data->bus_prot_mask)
 284		return 0;
 285
 286	return mtk_infracfg_set_bus_protection(scp->infracfg,
 287			scpd->data->bus_prot_mask,
 288			scp->bus_prot_reg_update);
 289}
 290
 291static int scpsys_bus_protect_disable(struct scp_domain *scpd)
 292{
 293	struct scp *scp = scpd->scp;
 294
 295	if (!scpd->data->bus_prot_mask)
 296		return 0;
 297
 298	return mtk_infracfg_clear_bus_protection(scp->infracfg,
 299			scpd->data->bus_prot_mask,
 300			scp->bus_prot_reg_update);
 301}
 302
 303static int scpsys_power_on(struct generic_pm_domain *genpd)
 304{
 305	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
 306	struct scp *scp = scpd->scp;
 307	void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
 308	u32 val;
 309	int ret, tmp;
 310
 311	ret = scpsys_regulator_enable(scpd);
 312	if (ret < 0)
 313		return ret;
 314
 315	ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
 316	if (ret)
 317		goto err_clk;
 318
 319	/* subsys power on */
 320	val = readl(ctl_addr);
 321	val |= PWR_ON_BIT;
 322	writel(val, ctl_addr);
 323	val |= PWR_ON_2ND_BIT;
 324	writel(val, ctl_addr);
 325
 326	/* wait until PWR_ACK = 1 */
 327	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
 328				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 329	if (ret < 0)
 330		goto err_pwr_ack;
 331
 332	val &= ~PWR_CLK_DIS_BIT;
 333	writel(val, ctl_addr);
 334
 335	val &= ~PWR_ISO_BIT;
 336	writel(val, ctl_addr);
 337
 338	val |= PWR_RST_B_BIT;
 339	writel(val, ctl_addr);
 340
 341	ret = scpsys_sram_enable(scpd, ctl_addr);
 342	if (ret < 0)
 343		goto err_pwr_ack;
 344
 345	ret = scpsys_bus_protect_disable(scpd);
 346	if (ret < 0)
 347		goto err_pwr_ack;
 348
 349	return 0;
 350
 351err_pwr_ack:
 352	scpsys_clk_disable(scpd->clk, MAX_CLKS);
 353err_clk:
 354	scpsys_regulator_disable(scpd);
 355
 356	dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
 357
 358	return ret;
 359}
 360
 361static int scpsys_power_off(struct generic_pm_domain *genpd)
 362{
 363	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
 364	struct scp *scp = scpd->scp;
 365	void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
 366	u32 val;
 367	int ret, tmp;
 368
 369	ret = scpsys_bus_protect_enable(scpd);
 370	if (ret < 0)
 371		goto out;
 372
 373	ret = scpsys_sram_disable(scpd, ctl_addr);
 374	if (ret < 0)
 375		goto out;
 376
 377	/* subsys power off */
 378	val = readl(ctl_addr);
 379	val |= PWR_ISO_BIT;
 380	writel(val, ctl_addr);
 381
 382	val &= ~PWR_RST_B_BIT;
 383	writel(val, ctl_addr);
 384
 385	val |= PWR_CLK_DIS_BIT;
 386	writel(val, ctl_addr);
 387
 388	val &= ~PWR_ON_BIT;
 389	writel(val, ctl_addr);
 390
 391	val &= ~PWR_ON_2ND_BIT;
 392	writel(val, ctl_addr);
 393
 394	/* wait until PWR_ACK = 0 */
 395	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
 396				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 397	if (ret < 0)
 398		goto out;
 399
 400	scpsys_clk_disable(scpd->clk, MAX_CLKS);
 401
 402	ret = scpsys_regulator_disable(scpd);
 403	if (ret < 0)
 404		goto out;
 405
 406	return 0;
 407
 408out:
 409	dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
 410
 411	return ret;
 412}
 413
 414static void init_clks(struct platform_device *pdev, struct clk **clk)
 415{
 416	int i;
 417
 418	for (i = CLK_NONE + 1; i < CLK_MAX; i++)
 419		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
 420}
 421
 422static struct scp *init_scp(struct platform_device *pdev,
 423			const struct scp_domain_data *scp_domain_data, int num,
 424			const struct scp_ctrl_reg *scp_ctrl_reg,
 425			bool bus_prot_reg_update)
 426{
 427	struct genpd_onecell_data *pd_data;
 428	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_scpsys_match_tbl,
1145	},
1146};
1147builtin_platform_driver(scpsys_drv);