162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci#include <linux/clk.h>
662306a36Sopenharmony_ci#include <linux/init.h>
762306a36Sopenharmony_ci#include <linux/io.h>
862306a36Sopenharmony_ci#include <linux/iopoll.h>
962306a36Sopenharmony_ci#include <linux/mfd/syscon.h>
1062306a36Sopenharmony_ci#include <linux/of.h>
1162306a36Sopenharmony_ci#include <linux/platform_device.h>
1262306a36Sopenharmony_ci#include <linux/pm_domain.h>
1362306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
1462306a36Sopenharmony_ci#include <linux/soc/mediatek/infracfg.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include <dt-bindings/power/mt2701-power.h>
1762306a36Sopenharmony_ci#include <dt-bindings/power/mt2712-power.h>
1862306a36Sopenharmony_ci#include <dt-bindings/power/mt6797-power.h>
1962306a36Sopenharmony_ci#include <dt-bindings/power/mt7622-power.h>
2062306a36Sopenharmony_ci#include <dt-bindings/power/mt7623a-power.h>
2162306a36Sopenharmony_ci#include <dt-bindings/power/mt8173-power.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define MTK_POLL_DELAY_US   10
2462306a36Sopenharmony_ci#define MTK_POLL_TIMEOUT    USEC_PER_SEC
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
2762306a36Sopenharmony_ci#define MTK_SCPD_FWAIT_SRAM		BIT(1)
2862306a36Sopenharmony_ci#define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci#define SPM_VDE_PWR_CON			0x0210
3162306a36Sopenharmony_ci#define SPM_MFG_PWR_CON			0x0214
3262306a36Sopenharmony_ci#define SPM_VEN_PWR_CON			0x0230
3362306a36Sopenharmony_ci#define SPM_ISP_PWR_CON			0x0238
3462306a36Sopenharmony_ci#define SPM_DIS_PWR_CON			0x023c
3562306a36Sopenharmony_ci#define SPM_CONN_PWR_CON		0x0280
3662306a36Sopenharmony_ci#define SPM_VEN2_PWR_CON		0x0298
3762306a36Sopenharmony_ci#define SPM_AUDIO_PWR_CON		0x029c	/* MT8173, MT2712 */
3862306a36Sopenharmony_ci#define SPM_BDP_PWR_CON			0x029c	/* MT2701 */
3962306a36Sopenharmony_ci#define SPM_ETH_PWR_CON			0x02a0
4062306a36Sopenharmony_ci#define SPM_HIF_PWR_CON			0x02a4
4162306a36Sopenharmony_ci#define SPM_IFR_MSC_PWR_CON		0x02a8
4262306a36Sopenharmony_ci#define SPM_MFG_2D_PWR_CON		0x02c0
4362306a36Sopenharmony_ci#define SPM_MFG_ASYNC_PWR_CON		0x02c4
4462306a36Sopenharmony_ci#define SPM_USB_PWR_CON			0x02cc
4562306a36Sopenharmony_ci#define SPM_USB2_PWR_CON		0x02d4	/* MT2712 */
4662306a36Sopenharmony_ci#define SPM_ETHSYS_PWR_CON		0x02e0	/* MT7622 */
4762306a36Sopenharmony_ci#define SPM_HIF0_PWR_CON		0x02e4	/* MT7622 */
4862306a36Sopenharmony_ci#define SPM_HIF1_PWR_CON		0x02e8	/* MT7622 */
4962306a36Sopenharmony_ci#define SPM_WB_PWR_CON			0x02ec	/* MT7622 */
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define SPM_PWR_STATUS			0x060c
5262306a36Sopenharmony_ci#define SPM_PWR_STATUS_2ND		0x0610
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#define PWR_RST_B_BIT			BIT(0)
5562306a36Sopenharmony_ci#define PWR_ISO_BIT			BIT(1)
5662306a36Sopenharmony_ci#define PWR_ON_BIT			BIT(2)
5762306a36Sopenharmony_ci#define PWR_ON_2ND_BIT			BIT(3)
5862306a36Sopenharmony_ci#define PWR_CLK_DIS_BIT			BIT(4)
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define PWR_STATUS_CONN			BIT(1)
6162306a36Sopenharmony_ci#define PWR_STATUS_DISP			BIT(3)
6262306a36Sopenharmony_ci#define PWR_STATUS_MFG			BIT(4)
6362306a36Sopenharmony_ci#define PWR_STATUS_ISP			BIT(5)
6462306a36Sopenharmony_ci#define PWR_STATUS_VDEC			BIT(7)
6562306a36Sopenharmony_ci#define PWR_STATUS_BDP			BIT(14)
6662306a36Sopenharmony_ci#define PWR_STATUS_ETH			BIT(15)
6762306a36Sopenharmony_ci#define PWR_STATUS_HIF			BIT(16)
6862306a36Sopenharmony_ci#define PWR_STATUS_IFR_MSC		BIT(17)
6962306a36Sopenharmony_ci#define PWR_STATUS_USB2			BIT(19)	/* MT2712 */
7062306a36Sopenharmony_ci#define PWR_STATUS_VENC_LT		BIT(20)
7162306a36Sopenharmony_ci#define PWR_STATUS_VENC			BIT(21)
7262306a36Sopenharmony_ci#define PWR_STATUS_MFG_2D		BIT(22)	/* MT8173 */
7362306a36Sopenharmony_ci#define PWR_STATUS_MFG_ASYNC		BIT(23)	/* MT8173 */
7462306a36Sopenharmony_ci#define PWR_STATUS_AUDIO		BIT(24)	/* MT8173, MT2712 */
7562306a36Sopenharmony_ci#define PWR_STATUS_USB			BIT(25)	/* MT8173, MT2712 */
7662306a36Sopenharmony_ci#define PWR_STATUS_ETHSYS		BIT(24)	/* MT7622 */
7762306a36Sopenharmony_ci#define PWR_STATUS_HIF0			BIT(25)	/* MT7622 */
7862306a36Sopenharmony_ci#define PWR_STATUS_HIF1			BIT(26)	/* MT7622 */
7962306a36Sopenharmony_ci#define PWR_STATUS_WB			BIT(27)	/* MT7622 */
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cienum clk_id {
8262306a36Sopenharmony_ci	CLK_NONE,
8362306a36Sopenharmony_ci	CLK_MM,
8462306a36Sopenharmony_ci	CLK_MFG,
8562306a36Sopenharmony_ci	CLK_VENC,
8662306a36Sopenharmony_ci	CLK_VENC_LT,
8762306a36Sopenharmony_ci	CLK_ETHIF,
8862306a36Sopenharmony_ci	CLK_VDEC,
8962306a36Sopenharmony_ci	CLK_HIFSEL,
9062306a36Sopenharmony_ci	CLK_JPGDEC,
9162306a36Sopenharmony_ci	CLK_AUDIO,
9262306a36Sopenharmony_ci	CLK_MAX,
9362306a36Sopenharmony_ci};
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic const char * const clk_names[] = {
9662306a36Sopenharmony_ci	NULL,
9762306a36Sopenharmony_ci	"mm",
9862306a36Sopenharmony_ci	"mfg",
9962306a36Sopenharmony_ci	"venc",
10062306a36Sopenharmony_ci	"venc_lt",
10162306a36Sopenharmony_ci	"ethif",
10262306a36Sopenharmony_ci	"vdec",
10362306a36Sopenharmony_ci	"hif_sel",
10462306a36Sopenharmony_ci	"jpgdec",
10562306a36Sopenharmony_ci	"audio",
10662306a36Sopenharmony_ci	NULL,
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci#define MAX_CLKS	3
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci/**
11262306a36Sopenharmony_ci * struct scp_domain_data - scp domain data for power on/off flow
11362306a36Sopenharmony_ci * @name: The domain name.
11462306a36Sopenharmony_ci * @sta_mask: The mask for power on/off status bit.
11562306a36Sopenharmony_ci * @ctl_offs: The offset for main power control register.
11662306a36Sopenharmony_ci * @sram_pdn_bits: The mask for sram power control bits.
11762306a36Sopenharmony_ci * @sram_pdn_ack_bits: The mask for sram power control acked bits.
11862306a36Sopenharmony_ci * @bus_prot_mask: The mask for single step bus protection.
11962306a36Sopenharmony_ci * @clk_id: The basic clocks required by this power domain.
12062306a36Sopenharmony_ci * @caps: The flag for active wake-up action.
12162306a36Sopenharmony_ci */
12262306a36Sopenharmony_cistruct scp_domain_data {
12362306a36Sopenharmony_ci	const char *name;
12462306a36Sopenharmony_ci	u32 sta_mask;
12562306a36Sopenharmony_ci	int ctl_offs;
12662306a36Sopenharmony_ci	u32 sram_pdn_bits;
12762306a36Sopenharmony_ci	u32 sram_pdn_ack_bits;
12862306a36Sopenharmony_ci	u32 bus_prot_mask;
12962306a36Sopenharmony_ci	enum clk_id clk_id[MAX_CLKS];
13062306a36Sopenharmony_ci	u8 caps;
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistruct scp;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistruct scp_domain {
13662306a36Sopenharmony_ci	struct generic_pm_domain genpd;
13762306a36Sopenharmony_ci	struct scp *scp;
13862306a36Sopenharmony_ci	struct clk *clk[MAX_CLKS];
13962306a36Sopenharmony_ci	const struct scp_domain_data *data;
14062306a36Sopenharmony_ci	struct regulator *supply;
14162306a36Sopenharmony_ci};
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_cistruct scp_ctrl_reg {
14462306a36Sopenharmony_ci	int pwr_sta_offs;
14562306a36Sopenharmony_ci	int pwr_sta2nd_offs;
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_cistruct scp {
14962306a36Sopenharmony_ci	struct scp_domain *domains;
15062306a36Sopenharmony_ci	struct genpd_onecell_data pd_data;
15162306a36Sopenharmony_ci	struct device *dev;
15262306a36Sopenharmony_ci	void __iomem *base;
15362306a36Sopenharmony_ci	struct regmap *infracfg;
15462306a36Sopenharmony_ci	struct scp_ctrl_reg ctrl_reg;
15562306a36Sopenharmony_ci	bool bus_prot_reg_update;
15662306a36Sopenharmony_ci};
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistruct scp_subdomain {
15962306a36Sopenharmony_ci	int origin;
16062306a36Sopenharmony_ci	int subdomain;
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistruct scp_soc_data {
16462306a36Sopenharmony_ci	const struct scp_domain_data *domains;
16562306a36Sopenharmony_ci	int num_domains;
16662306a36Sopenharmony_ci	const struct scp_subdomain *subdomains;
16762306a36Sopenharmony_ci	int num_subdomains;
16862306a36Sopenharmony_ci	const struct scp_ctrl_reg regs;
16962306a36Sopenharmony_ci	bool bus_prot_reg_update;
17062306a36Sopenharmony_ci};
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic int scpsys_domain_is_on(struct scp_domain *scpd)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	struct scp *scp = scpd->scp;
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
17762306a36Sopenharmony_ci						scpd->data->sta_mask;
17862306a36Sopenharmony_ci	u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
17962306a36Sopenharmony_ci						scpd->data->sta_mask;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	/*
18262306a36Sopenharmony_ci	 * A domain is on when both status bits are set. If only one is set
18362306a36Sopenharmony_ci	 * return an error. This happens while powering up a domain
18462306a36Sopenharmony_ci	 */
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	if (status && status2)
18762306a36Sopenharmony_ci		return true;
18862306a36Sopenharmony_ci	if (!status && !status2)
18962306a36Sopenharmony_ci		return false;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	return -EINVAL;
19262306a36Sopenharmony_ci}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cistatic int scpsys_regulator_enable(struct scp_domain *scpd)
19562306a36Sopenharmony_ci{
19662306a36Sopenharmony_ci	if (!scpd->supply)
19762306a36Sopenharmony_ci		return 0;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return regulator_enable(scpd->supply);
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_cistatic int scpsys_regulator_disable(struct scp_domain *scpd)
20362306a36Sopenharmony_ci{
20462306a36Sopenharmony_ci	if (!scpd->supply)
20562306a36Sopenharmony_ci		return 0;
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	return regulator_disable(scpd->supply);
20862306a36Sopenharmony_ci}
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic void scpsys_clk_disable(struct clk *clk[], int max_num)
21162306a36Sopenharmony_ci{
21262306a36Sopenharmony_ci	int i;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	for (i = max_num - 1; i >= 0; i--)
21562306a36Sopenharmony_ci		clk_disable_unprepare(clk[i]);
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_cistatic int scpsys_clk_enable(struct clk *clk[], int max_num)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	int i, ret = 0;
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	for (i = 0; i < max_num && clk[i]; i++) {
22362306a36Sopenharmony_ci		ret = clk_prepare_enable(clk[i]);
22462306a36Sopenharmony_ci		if (ret) {
22562306a36Sopenharmony_ci			scpsys_clk_disable(clk, i);
22662306a36Sopenharmony_ci			break;
22762306a36Sopenharmony_ci		}
22862306a36Sopenharmony_ci	}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	return ret;
23162306a36Sopenharmony_ci}
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_cistatic int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	u32 val;
23662306a36Sopenharmony_ci	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
23762306a36Sopenharmony_ci	int tmp;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	val = readl(ctl_addr);
24062306a36Sopenharmony_ci	val &= ~scpd->data->sram_pdn_bits;
24162306a36Sopenharmony_ci	writel(val, ctl_addr);
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	/* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
24462306a36Sopenharmony_ci	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
24562306a36Sopenharmony_ci		/*
24662306a36Sopenharmony_ci		 * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
24762306a36Sopenharmony_ci		 * MT7622_POWER_DOMAIN_WB and thus just a trivial setup
24862306a36Sopenharmony_ci		 * is applied here.
24962306a36Sopenharmony_ci		 */
25062306a36Sopenharmony_ci		usleep_range(12000, 12100);
25162306a36Sopenharmony_ci	} else {
25262306a36Sopenharmony_ci		/* Either wait until SRAM_PDN_ACK all 1 or 0 */
25362306a36Sopenharmony_ci		int ret = readl_poll_timeout(ctl_addr, tmp,
25462306a36Sopenharmony_ci				(tmp & pdn_ack) == 0,
25562306a36Sopenharmony_ci				MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
25662306a36Sopenharmony_ci		if (ret < 0)
25762306a36Sopenharmony_ci			return ret;
25862306a36Sopenharmony_ci	}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci	return 0;
26162306a36Sopenharmony_ci}
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_cistatic int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
26462306a36Sopenharmony_ci{
26562306a36Sopenharmony_ci	u32 val;
26662306a36Sopenharmony_ci	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
26762306a36Sopenharmony_ci	int tmp;
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	val = readl(ctl_addr);
27062306a36Sopenharmony_ci	val |= scpd->data->sram_pdn_bits;
27162306a36Sopenharmony_ci	writel(val, ctl_addr);
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	/* Either wait until SRAM_PDN_ACK all 1 or 0 */
27462306a36Sopenharmony_ci	return readl_poll_timeout(ctl_addr, tmp,
27562306a36Sopenharmony_ci			(tmp & pdn_ack) == pdn_ack,
27662306a36Sopenharmony_ci			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
27762306a36Sopenharmony_ci}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_cistatic int scpsys_bus_protect_enable(struct scp_domain *scpd)
28062306a36Sopenharmony_ci{
28162306a36Sopenharmony_ci	struct scp *scp = scpd->scp;
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	if (!scpd->data->bus_prot_mask)
28462306a36Sopenharmony_ci		return 0;
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	return mtk_infracfg_set_bus_protection(scp->infracfg,
28762306a36Sopenharmony_ci			scpd->data->bus_prot_mask,
28862306a36Sopenharmony_ci			scp->bus_prot_reg_update);
28962306a36Sopenharmony_ci}
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistatic int scpsys_bus_protect_disable(struct scp_domain *scpd)
29262306a36Sopenharmony_ci{
29362306a36Sopenharmony_ci	struct scp *scp = scpd->scp;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	if (!scpd->data->bus_prot_mask)
29662306a36Sopenharmony_ci		return 0;
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_ci	return mtk_infracfg_clear_bus_protection(scp->infracfg,
29962306a36Sopenharmony_ci			scpd->data->bus_prot_mask,
30062306a36Sopenharmony_ci			scp->bus_prot_reg_update);
30162306a36Sopenharmony_ci}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_cistatic int scpsys_power_on(struct generic_pm_domain *genpd)
30462306a36Sopenharmony_ci{
30562306a36Sopenharmony_ci	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
30662306a36Sopenharmony_ci	struct scp *scp = scpd->scp;
30762306a36Sopenharmony_ci	void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
30862306a36Sopenharmony_ci	u32 val;
30962306a36Sopenharmony_ci	int ret, tmp;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	ret = scpsys_regulator_enable(scpd);
31262306a36Sopenharmony_ci	if (ret < 0)
31362306a36Sopenharmony_ci		return ret;
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
31662306a36Sopenharmony_ci	if (ret)
31762306a36Sopenharmony_ci		goto err_clk;
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	/* subsys power on */
32062306a36Sopenharmony_ci	val = readl(ctl_addr);
32162306a36Sopenharmony_ci	val |= PWR_ON_BIT;
32262306a36Sopenharmony_ci	writel(val, ctl_addr);
32362306a36Sopenharmony_ci	val |= PWR_ON_2ND_BIT;
32462306a36Sopenharmony_ci	writel(val, ctl_addr);
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	/* wait until PWR_ACK = 1 */
32762306a36Sopenharmony_ci	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
32862306a36Sopenharmony_ci				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
32962306a36Sopenharmony_ci	if (ret < 0)
33062306a36Sopenharmony_ci		goto err_pwr_ack;
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	val &= ~PWR_CLK_DIS_BIT;
33362306a36Sopenharmony_ci	writel(val, ctl_addr);
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_ci	val &= ~PWR_ISO_BIT;
33662306a36Sopenharmony_ci	writel(val, ctl_addr);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	val |= PWR_RST_B_BIT;
33962306a36Sopenharmony_ci	writel(val, ctl_addr);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci	ret = scpsys_sram_enable(scpd, ctl_addr);
34262306a36Sopenharmony_ci	if (ret < 0)
34362306a36Sopenharmony_ci		goto err_pwr_ack;
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	ret = scpsys_bus_protect_disable(scpd);
34662306a36Sopenharmony_ci	if (ret < 0)
34762306a36Sopenharmony_ci		goto err_pwr_ack;
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	return 0;
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cierr_pwr_ack:
35262306a36Sopenharmony_ci	scpsys_clk_disable(scpd->clk, MAX_CLKS);
35362306a36Sopenharmony_cierr_clk:
35462306a36Sopenharmony_ci	scpsys_regulator_disable(scpd);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci	return ret;
35962306a36Sopenharmony_ci}
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_cistatic int scpsys_power_off(struct generic_pm_domain *genpd)
36262306a36Sopenharmony_ci{
36362306a36Sopenharmony_ci	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
36462306a36Sopenharmony_ci	struct scp *scp = scpd->scp;
36562306a36Sopenharmony_ci	void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
36662306a36Sopenharmony_ci	u32 val;
36762306a36Sopenharmony_ci	int ret, tmp;
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	ret = scpsys_bus_protect_enable(scpd);
37062306a36Sopenharmony_ci	if (ret < 0)
37162306a36Sopenharmony_ci		goto out;
37262306a36Sopenharmony_ci
37362306a36Sopenharmony_ci	ret = scpsys_sram_disable(scpd, ctl_addr);
37462306a36Sopenharmony_ci	if (ret < 0)
37562306a36Sopenharmony_ci		goto out;
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	/* subsys power off */
37862306a36Sopenharmony_ci	val = readl(ctl_addr);
37962306a36Sopenharmony_ci	val |= PWR_ISO_BIT;
38062306a36Sopenharmony_ci	writel(val, ctl_addr);
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	val &= ~PWR_RST_B_BIT;
38362306a36Sopenharmony_ci	writel(val, ctl_addr);
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	val |= PWR_CLK_DIS_BIT;
38662306a36Sopenharmony_ci	writel(val, ctl_addr);
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	val &= ~PWR_ON_BIT;
38962306a36Sopenharmony_ci	writel(val, ctl_addr);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	val &= ~PWR_ON_2ND_BIT;
39262306a36Sopenharmony_ci	writel(val, ctl_addr);
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	/* wait until PWR_ACK = 0 */
39562306a36Sopenharmony_ci	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
39662306a36Sopenharmony_ci				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
39762306a36Sopenharmony_ci	if (ret < 0)
39862306a36Sopenharmony_ci		goto out;
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	scpsys_clk_disable(scpd->clk, MAX_CLKS);
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	ret = scpsys_regulator_disable(scpd);
40362306a36Sopenharmony_ci	if (ret < 0)
40462306a36Sopenharmony_ci		goto out;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	return 0;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ciout:
40962306a36Sopenharmony_ci	dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	return ret;
41262306a36Sopenharmony_ci}
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_cistatic void init_clks(struct platform_device *pdev, struct clk **clk)
41562306a36Sopenharmony_ci{
41662306a36Sopenharmony_ci	int i;
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci	for (i = CLK_NONE + 1; i < CLK_MAX; i++)
41962306a36Sopenharmony_ci		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_cistatic struct scp *init_scp(struct platform_device *pdev,
42362306a36Sopenharmony_ci			const struct scp_domain_data *scp_domain_data, int num,
42462306a36Sopenharmony_ci			const struct scp_ctrl_reg *scp_ctrl_reg,
42562306a36Sopenharmony_ci			bool bus_prot_reg_update)
42662306a36Sopenharmony_ci{
42762306a36Sopenharmony_ci	struct genpd_onecell_data *pd_data;
42862306a36Sopenharmony_ci	struct resource *res;
42962306a36Sopenharmony_ci	int i, j;
43062306a36Sopenharmony_ci	struct scp *scp;
43162306a36Sopenharmony_ci	struct clk *clk[CLK_MAX];
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_ci	scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
43462306a36Sopenharmony_ci	if (!scp)
43562306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
43662306a36Sopenharmony_ci
43762306a36Sopenharmony_ci	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
43862306a36Sopenharmony_ci	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	scp->bus_prot_reg_update = bus_prot_reg_update;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	scp->dev = &pdev->dev;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
44562306a36Sopenharmony_ci	scp->base = devm_ioremap_resource(&pdev->dev, res);
44662306a36Sopenharmony_ci	if (IS_ERR(scp->base))
44762306a36Sopenharmony_ci		return ERR_CAST(scp->base);
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	scp->domains = devm_kcalloc(&pdev->dev,
45062306a36Sopenharmony_ci				num, sizeof(*scp->domains), GFP_KERNEL);
45162306a36Sopenharmony_ci	if (!scp->domains)
45262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	pd_data = &scp->pd_data;
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci	pd_data->domains = devm_kcalloc(&pdev->dev,
45762306a36Sopenharmony_ci			num, sizeof(*pd_data->domains), GFP_KERNEL);
45862306a36Sopenharmony_ci	if (!pd_data->domains)
45962306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
46262306a36Sopenharmony_ci			"infracfg");
46362306a36Sopenharmony_ci	if (IS_ERR(scp->infracfg)) {
46462306a36Sopenharmony_ci		dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
46562306a36Sopenharmony_ci				PTR_ERR(scp->infracfg));
46662306a36Sopenharmony_ci		return ERR_CAST(scp->infracfg);
46762306a36Sopenharmony_ci	}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
47062306a36Sopenharmony_ci		struct scp_domain *scpd = &scp->domains[i];
47162306a36Sopenharmony_ci		const struct scp_domain_data *data = &scp_domain_data[i];
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci		scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
47462306a36Sopenharmony_ci		if (IS_ERR(scpd->supply)) {
47562306a36Sopenharmony_ci			if (PTR_ERR(scpd->supply) == -ENODEV)
47662306a36Sopenharmony_ci				scpd->supply = NULL;
47762306a36Sopenharmony_ci			else
47862306a36Sopenharmony_ci				return ERR_CAST(scpd->supply);
47962306a36Sopenharmony_ci		}
48062306a36Sopenharmony_ci	}
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	pd_data->num_domains = num;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	init_clks(pdev, clk);
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
48762306a36Sopenharmony_ci		struct scp_domain *scpd = &scp->domains[i];
48862306a36Sopenharmony_ci		struct generic_pm_domain *genpd = &scpd->genpd;
48962306a36Sopenharmony_ci		const struct scp_domain_data *data = &scp_domain_data[i];
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci		pd_data->domains[i] = genpd;
49262306a36Sopenharmony_ci		scpd->scp = scp;
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci		scpd->data = data;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci		for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
49762306a36Sopenharmony_ci			struct clk *c = clk[data->clk_id[j]];
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci			if (IS_ERR(c)) {
50062306a36Sopenharmony_ci				dev_err(&pdev->dev, "%s: clk unavailable\n",
50162306a36Sopenharmony_ci					data->name);
50262306a36Sopenharmony_ci				return ERR_CAST(c);
50362306a36Sopenharmony_ci			}
50462306a36Sopenharmony_ci
50562306a36Sopenharmony_ci			scpd->clk[j] = c;
50662306a36Sopenharmony_ci		}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci		genpd->name = data->name;
50962306a36Sopenharmony_ci		genpd->power_off = scpsys_power_off;
51062306a36Sopenharmony_ci		genpd->power_on = scpsys_power_on;
51162306a36Sopenharmony_ci		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
51262306a36Sopenharmony_ci			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
51362306a36Sopenharmony_ci	}
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci	return scp;
51662306a36Sopenharmony_ci}
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_cistatic void mtk_register_power_domains(struct platform_device *pdev,
51962306a36Sopenharmony_ci				struct scp *scp, int num)
52062306a36Sopenharmony_ci{
52162306a36Sopenharmony_ci	struct genpd_onecell_data *pd_data;
52262306a36Sopenharmony_ci	int i, ret;
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
52562306a36Sopenharmony_ci		struct scp_domain *scpd = &scp->domains[i];
52662306a36Sopenharmony_ci		struct generic_pm_domain *genpd = &scpd->genpd;
52762306a36Sopenharmony_ci		bool on;
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci		/*
53062306a36Sopenharmony_ci		 * Initially turn on all domains to make the domains usable
53162306a36Sopenharmony_ci		 * with !CONFIG_PM and to get the hardware in sync with the
53262306a36Sopenharmony_ci		 * software.  The unused domains will be switched off during
53362306a36Sopenharmony_ci		 * late_init time.
53462306a36Sopenharmony_ci		 */
53562306a36Sopenharmony_ci		on = !WARN_ON(genpd->power_on(genpd) < 0);
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci		pm_genpd_init(genpd, NULL, !on);
53862306a36Sopenharmony_ci	}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	/*
54162306a36Sopenharmony_ci	 * We are not allowed to fail here since there is no way to unregister
54262306a36Sopenharmony_ci	 * a power domain. Once registered above we have to keep the domains
54362306a36Sopenharmony_ci	 * valid.
54462306a36Sopenharmony_ci	 */
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	pd_data = &scp->pd_data;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
54962306a36Sopenharmony_ci	if (ret)
55062306a36Sopenharmony_ci		dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
55162306a36Sopenharmony_ci}
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci/*
55462306a36Sopenharmony_ci * MT2701 power domain support
55562306a36Sopenharmony_ci */
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt2701[] = {
55862306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_CONN] = {
55962306a36Sopenharmony_ci		.name = "conn",
56062306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_CONN,
56162306a36Sopenharmony_ci		.ctl_offs = SPM_CONN_PWR_CON,
56262306a36Sopenharmony_ci		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
56362306a36Sopenharmony_ci				 MT2701_TOP_AXI_PROT_EN_CONN_S,
56462306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
56562306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
56662306a36Sopenharmony_ci	},
56762306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_DISP] = {
56862306a36Sopenharmony_ci		.name = "disp",
56962306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_DISP,
57062306a36Sopenharmony_ci		.ctl_offs = SPM_DIS_PWR_CON,
57162306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
57262306a36Sopenharmony_ci		.clk_id = {CLK_MM},
57362306a36Sopenharmony_ci		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
57462306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
57562306a36Sopenharmony_ci	},
57662306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_MFG] = {
57762306a36Sopenharmony_ci		.name = "mfg",
57862306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG,
57962306a36Sopenharmony_ci		.ctl_offs = SPM_MFG_PWR_CON,
58062306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
58162306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
58262306a36Sopenharmony_ci		.clk_id = {CLK_MFG},
58362306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
58462306a36Sopenharmony_ci	},
58562306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_VDEC] = {
58662306a36Sopenharmony_ci		.name = "vdec",
58762306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_VDEC,
58862306a36Sopenharmony_ci		.ctl_offs = SPM_VDE_PWR_CON,
58962306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
59062306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
59162306a36Sopenharmony_ci		.clk_id = {CLK_MM},
59262306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
59362306a36Sopenharmony_ci	},
59462306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_ISP] = {
59562306a36Sopenharmony_ci		.name = "isp",
59662306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_ISP,
59762306a36Sopenharmony_ci		.ctl_offs = SPM_ISP_PWR_CON,
59862306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
59962306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
60062306a36Sopenharmony_ci		.clk_id = {CLK_MM},
60162306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
60262306a36Sopenharmony_ci	},
60362306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_BDP] = {
60462306a36Sopenharmony_ci		.name = "bdp",
60562306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_BDP,
60662306a36Sopenharmony_ci		.ctl_offs = SPM_BDP_PWR_CON,
60762306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
60862306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
60962306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
61062306a36Sopenharmony_ci	},
61162306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_ETH] = {
61262306a36Sopenharmony_ci		.name = "eth",
61362306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_ETH,
61462306a36Sopenharmony_ci		.ctl_offs = SPM_ETH_PWR_CON,
61562306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
61662306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
61762306a36Sopenharmony_ci		.clk_id = {CLK_ETHIF},
61862306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
61962306a36Sopenharmony_ci	},
62062306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_HIF] = {
62162306a36Sopenharmony_ci		.name = "hif",
62262306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF,
62362306a36Sopenharmony_ci		.ctl_offs = SPM_HIF_PWR_CON,
62462306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
62562306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
62662306a36Sopenharmony_ci		.clk_id = {CLK_ETHIF},
62762306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
62862306a36Sopenharmony_ci	},
62962306a36Sopenharmony_ci	[MT2701_POWER_DOMAIN_IFR_MSC] = {
63062306a36Sopenharmony_ci		.name = "ifr_msc",
63162306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_IFR_MSC,
63262306a36Sopenharmony_ci		.ctl_offs = SPM_IFR_MSC_PWR_CON,
63362306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
63462306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
63562306a36Sopenharmony_ci	},
63662306a36Sopenharmony_ci};
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci/*
63962306a36Sopenharmony_ci * MT2712 power domain support
64062306a36Sopenharmony_ci */
64162306a36Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt2712[] = {
64262306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_MM] = {
64362306a36Sopenharmony_ci		.name = "mm",
64462306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_DISP,
64562306a36Sopenharmony_ci		.ctl_offs = SPM_DIS_PWR_CON,
64662306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
64762306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
64862306a36Sopenharmony_ci		.clk_id = {CLK_MM},
64962306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
65062306a36Sopenharmony_ci	},
65162306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_VDEC] = {
65262306a36Sopenharmony_ci		.name = "vdec",
65362306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_VDEC,
65462306a36Sopenharmony_ci		.ctl_offs = SPM_VDE_PWR_CON,
65562306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
65662306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
65762306a36Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VDEC},
65862306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
65962306a36Sopenharmony_ci	},
66062306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_VENC] = {
66162306a36Sopenharmony_ci		.name = "venc",
66262306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_VENC,
66362306a36Sopenharmony_ci		.ctl_offs = SPM_VEN_PWR_CON,
66462306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
66562306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
66662306a36Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
66762306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
66862306a36Sopenharmony_ci	},
66962306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_ISP] = {
67062306a36Sopenharmony_ci		.name = "isp",
67162306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_ISP,
67262306a36Sopenharmony_ci		.ctl_offs = SPM_ISP_PWR_CON,
67362306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
67462306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
67562306a36Sopenharmony_ci		.clk_id = {CLK_MM},
67662306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
67762306a36Sopenharmony_ci	},
67862306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_AUDIO] = {
67962306a36Sopenharmony_ci		.name = "audio",
68062306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_AUDIO,
68162306a36Sopenharmony_ci		.ctl_offs = SPM_AUDIO_PWR_CON,
68262306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
68362306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
68462306a36Sopenharmony_ci		.clk_id = {CLK_AUDIO},
68562306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
68662306a36Sopenharmony_ci	},
68762306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_USB] = {
68862306a36Sopenharmony_ci		.name = "usb",
68962306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_USB,
69062306a36Sopenharmony_ci		.ctl_offs = SPM_USB_PWR_CON,
69162306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(10, 8),
69262306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(14, 12),
69362306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
69462306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
69562306a36Sopenharmony_ci	},
69662306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_USB2] = {
69762306a36Sopenharmony_ci		.name = "usb2",
69862306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_USB2,
69962306a36Sopenharmony_ci		.ctl_offs = SPM_USB2_PWR_CON,
70062306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(10, 8),
70162306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(14, 12),
70262306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
70362306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
70462306a36Sopenharmony_ci	},
70562306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG] = {
70662306a36Sopenharmony_ci		.name = "mfg",
70762306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG,
70862306a36Sopenharmony_ci		.ctl_offs = SPM_MFG_PWR_CON,
70962306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
71062306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
71162306a36Sopenharmony_ci		.clk_id = {CLK_MFG},
71262306a36Sopenharmony_ci		.bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
71362306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
71462306a36Sopenharmony_ci	},
71562306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG_SC1] = {
71662306a36Sopenharmony_ci		.name = "mfg_sc1",
71762306a36Sopenharmony_ci		.sta_mask = BIT(22),
71862306a36Sopenharmony_ci		.ctl_offs = 0x02c0,
71962306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
72062306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
72162306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
72262306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
72362306a36Sopenharmony_ci	},
72462306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG_SC2] = {
72562306a36Sopenharmony_ci		.name = "mfg_sc2",
72662306a36Sopenharmony_ci		.sta_mask = BIT(23),
72762306a36Sopenharmony_ci		.ctl_offs = 0x02c4,
72862306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
72962306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
73062306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
73162306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
73262306a36Sopenharmony_ci	},
73362306a36Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG_SC3] = {
73462306a36Sopenharmony_ci		.name = "mfg_sc3",
73562306a36Sopenharmony_ci		.sta_mask = BIT(30),
73662306a36Sopenharmony_ci		.ctl_offs = 0x01f8,
73762306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
73862306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
73962306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
74062306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
74162306a36Sopenharmony_ci	},
74262306a36Sopenharmony_ci};
74362306a36Sopenharmony_ci
74462306a36Sopenharmony_cistatic const struct scp_subdomain scp_subdomain_mt2712[] = {
74562306a36Sopenharmony_ci	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC},
74662306a36Sopenharmony_ci	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC},
74762306a36Sopenharmony_ci	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP},
74862306a36Sopenharmony_ci	{MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1},
74962306a36Sopenharmony_ci	{MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2},
75062306a36Sopenharmony_ci	{MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3},
75162306a36Sopenharmony_ci};
75262306a36Sopenharmony_ci
75362306a36Sopenharmony_ci/*
75462306a36Sopenharmony_ci * MT6797 power domain support
75562306a36Sopenharmony_ci */
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt6797[] = {
75862306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_VDEC] = {
75962306a36Sopenharmony_ci		.name = "vdec",
76062306a36Sopenharmony_ci		.sta_mask = BIT(7),
76162306a36Sopenharmony_ci		.ctl_offs = 0x300,
76262306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
76362306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
76462306a36Sopenharmony_ci		.clk_id = {CLK_VDEC},
76562306a36Sopenharmony_ci	},
76662306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_VENC] = {
76762306a36Sopenharmony_ci		.name = "venc",
76862306a36Sopenharmony_ci		.sta_mask = BIT(21),
76962306a36Sopenharmony_ci		.ctl_offs = 0x304,
77062306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
77162306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
77262306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
77362306a36Sopenharmony_ci	},
77462306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_ISP] = {
77562306a36Sopenharmony_ci		.name = "isp",
77662306a36Sopenharmony_ci		.sta_mask = BIT(5),
77762306a36Sopenharmony_ci		.ctl_offs = 0x308,
77862306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(9, 8),
77962306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
78062306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
78162306a36Sopenharmony_ci	},
78262306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_MM] = {
78362306a36Sopenharmony_ci		.name = "mm",
78462306a36Sopenharmony_ci		.sta_mask = BIT(3),
78562306a36Sopenharmony_ci		.ctl_offs = 0x30C,
78662306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
78762306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
78862306a36Sopenharmony_ci		.clk_id = {CLK_MM},
78962306a36Sopenharmony_ci		.bus_prot_mask = (BIT(1) | BIT(2)),
79062306a36Sopenharmony_ci	},
79162306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_AUDIO] = {
79262306a36Sopenharmony_ci		.name = "audio",
79362306a36Sopenharmony_ci		.sta_mask = BIT(24),
79462306a36Sopenharmony_ci		.ctl_offs = 0x314,
79562306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
79662306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
79762306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
79862306a36Sopenharmony_ci	},
79962306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_MFG_ASYNC] = {
80062306a36Sopenharmony_ci		.name = "mfg_async",
80162306a36Sopenharmony_ci		.sta_mask = BIT(13),
80262306a36Sopenharmony_ci		.ctl_offs = 0x334,
80362306a36Sopenharmony_ci		.sram_pdn_bits = 0,
80462306a36Sopenharmony_ci		.sram_pdn_ack_bits = 0,
80562306a36Sopenharmony_ci		.clk_id = {CLK_MFG},
80662306a36Sopenharmony_ci	},
80762306a36Sopenharmony_ci	[MT6797_POWER_DOMAIN_MJC] = {
80862306a36Sopenharmony_ci		.name = "mjc",
80962306a36Sopenharmony_ci		.sta_mask = BIT(20),
81062306a36Sopenharmony_ci		.ctl_offs = 0x310,
81162306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
81262306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
81362306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
81462306a36Sopenharmony_ci	},
81562306a36Sopenharmony_ci};
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci#define SPM_PWR_STATUS_MT6797		0x0180
81862306a36Sopenharmony_ci#define SPM_PWR_STATUS_2ND_MT6797	0x0184
81962306a36Sopenharmony_ci
82062306a36Sopenharmony_cistatic const struct scp_subdomain scp_subdomain_mt6797[] = {
82162306a36Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
82262306a36Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
82362306a36Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
82462306a36Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
82562306a36Sopenharmony_ci};
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci/*
82862306a36Sopenharmony_ci * MT7622 power domain support
82962306a36Sopenharmony_ci */
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt7622[] = {
83262306a36Sopenharmony_ci	[MT7622_POWER_DOMAIN_ETHSYS] = {
83362306a36Sopenharmony_ci		.name = "ethsys",
83462306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_ETHSYS,
83562306a36Sopenharmony_ci		.ctl_offs = SPM_ETHSYS_PWR_CON,
83662306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
83762306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
83862306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
83962306a36Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
84062306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
84162306a36Sopenharmony_ci	},
84262306a36Sopenharmony_ci	[MT7622_POWER_DOMAIN_HIF0] = {
84362306a36Sopenharmony_ci		.name = "hif0",
84462306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF0,
84562306a36Sopenharmony_ci		.ctl_offs = SPM_HIF0_PWR_CON,
84662306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
84762306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
84862306a36Sopenharmony_ci		.clk_id = {CLK_HIFSEL},
84962306a36Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
85062306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
85162306a36Sopenharmony_ci	},
85262306a36Sopenharmony_ci	[MT7622_POWER_DOMAIN_HIF1] = {
85362306a36Sopenharmony_ci		.name = "hif1",
85462306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF1,
85562306a36Sopenharmony_ci		.ctl_offs = SPM_HIF1_PWR_CON,
85662306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
85762306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
85862306a36Sopenharmony_ci		.clk_id = {CLK_HIFSEL},
85962306a36Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
86062306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
86162306a36Sopenharmony_ci	},
86262306a36Sopenharmony_ci	[MT7622_POWER_DOMAIN_WB] = {
86362306a36Sopenharmony_ci		.name = "wb",
86462306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_WB,
86562306a36Sopenharmony_ci		.ctl_offs = SPM_WB_PWR_CON,
86662306a36Sopenharmony_ci		.sram_pdn_bits = 0,
86762306a36Sopenharmony_ci		.sram_pdn_ack_bits = 0,
86862306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
86962306a36Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
87062306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM,
87162306a36Sopenharmony_ci	},
87262306a36Sopenharmony_ci};
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci/*
87562306a36Sopenharmony_ci * MT7623A power domain support
87662306a36Sopenharmony_ci */
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt7623a[] = {
87962306a36Sopenharmony_ci	[MT7623A_POWER_DOMAIN_CONN] = {
88062306a36Sopenharmony_ci		.name = "conn",
88162306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_CONN,
88262306a36Sopenharmony_ci		.ctl_offs = SPM_CONN_PWR_CON,
88362306a36Sopenharmony_ci		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
88462306a36Sopenharmony_ci				 MT2701_TOP_AXI_PROT_EN_CONN_S,
88562306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
88662306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
88762306a36Sopenharmony_ci	},
88862306a36Sopenharmony_ci	[MT7623A_POWER_DOMAIN_ETH] = {
88962306a36Sopenharmony_ci		.name = "eth",
89062306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_ETH,
89162306a36Sopenharmony_ci		.ctl_offs = SPM_ETH_PWR_CON,
89262306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
89362306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
89462306a36Sopenharmony_ci		.clk_id = {CLK_ETHIF},
89562306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
89662306a36Sopenharmony_ci	},
89762306a36Sopenharmony_ci	[MT7623A_POWER_DOMAIN_HIF] = {
89862306a36Sopenharmony_ci		.name = "hif",
89962306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF,
90062306a36Sopenharmony_ci		.ctl_offs = SPM_HIF_PWR_CON,
90162306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
90262306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
90362306a36Sopenharmony_ci		.clk_id = {CLK_ETHIF},
90462306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
90562306a36Sopenharmony_ci	},
90662306a36Sopenharmony_ci	[MT7623A_POWER_DOMAIN_IFR_MSC] = {
90762306a36Sopenharmony_ci		.name = "ifr_msc",
90862306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_IFR_MSC,
90962306a36Sopenharmony_ci		.ctl_offs = SPM_IFR_MSC_PWR_CON,
91062306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
91162306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
91262306a36Sopenharmony_ci	},
91362306a36Sopenharmony_ci};
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci/*
91662306a36Sopenharmony_ci * MT8173 power domain support
91762306a36Sopenharmony_ci */
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt8173[] = {
92062306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_VDEC] = {
92162306a36Sopenharmony_ci		.name = "vdec",
92262306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_VDEC,
92362306a36Sopenharmony_ci		.ctl_offs = SPM_VDE_PWR_CON,
92462306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
92562306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
92662306a36Sopenharmony_ci		.clk_id = {CLK_MM},
92762306a36Sopenharmony_ci	},
92862306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_VENC] = {
92962306a36Sopenharmony_ci		.name = "venc",
93062306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_VENC,
93162306a36Sopenharmony_ci		.ctl_offs = SPM_VEN_PWR_CON,
93262306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
93362306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
93462306a36Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VENC},
93562306a36Sopenharmony_ci	},
93662306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_ISP] = {
93762306a36Sopenharmony_ci		.name = "isp",
93862306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_ISP,
93962306a36Sopenharmony_ci		.ctl_offs = SPM_ISP_PWR_CON,
94062306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
94162306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
94262306a36Sopenharmony_ci		.clk_id = {CLK_MM},
94362306a36Sopenharmony_ci	},
94462306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_MM] = {
94562306a36Sopenharmony_ci		.name = "mm",
94662306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_DISP,
94762306a36Sopenharmony_ci		.ctl_offs = SPM_DIS_PWR_CON,
94862306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
94962306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
95062306a36Sopenharmony_ci		.clk_id = {CLK_MM},
95162306a36Sopenharmony_ci		.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
95262306a36Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MM_M1,
95362306a36Sopenharmony_ci	},
95462306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_VENC_LT] = {
95562306a36Sopenharmony_ci		.name = "venc_lt",
95662306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_VENC_LT,
95762306a36Sopenharmony_ci		.ctl_offs = SPM_VEN2_PWR_CON,
95862306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
95962306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
96062306a36Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VENC_LT},
96162306a36Sopenharmony_ci	},
96262306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_AUDIO] = {
96362306a36Sopenharmony_ci		.name = "audio",
96462306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_AUDIO,
96562306a36Sopenharmony_ci		.ctl_offs = SPM_AUDIO_PWR_CON,
96662306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
96762306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
96862306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
96962306a36Sopenharmony_ci	},
97062306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_USB] = {
97162306a36Sopenharmony_ci		.name = "usb",
97262306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_USB,
97362306a36Sopenharmony_ci		.ctl_offs = SPM_USB_PWR_CON,
97462306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
97562306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
97662306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
97762306a36Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
97862306a36Sopenharmony_ci	},
97962306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_MFG_ASYNC] = {
98062306a36Sopenharmony_ci		.name = "mfg_async",
98162306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG_ASYNC,
98262306a36Sopenharmony_ci		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
98362306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
98462306a36Sopenharmony_ci		.sram_pdn_ack_bits = 0,
98562306a36Sopenharmony_ci		.clk_id = {CLK_MFG},
98662306a36Sopenharmony_ci	},
98762306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_MFG_2D] = {
98862306a36Sopenharmony_ci		.name = "mfg_2d",
98962306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG_2D,
99062306a36Sopenharmony_ci		.ctl_offs = SPM_MFG_2D_PWR_CON,
99162306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
99262306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
99362306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
99462306a36Sopenharmony_ci	},
99562306a36Sopenharmony_ci	[MT8173_POWER_DOMAIN_MFG] = {
99662306a36Sopenharmony_ci		.name = "mfg",
99762306a36Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG,
99862306a36Sopenharmony_ci		.ctl_offs = SPM_MFG_PWR_CON,
99962306a36Sopenharmony_ci		.sram_pdn_bits = GENMASK(13, 8),
100062306a36Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(21, 16),
100162306a36Sopenharmony_ci		.clk_id = {CLK_NONE},
100262306a36Sopenharmony_ci		.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
100362306a36Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MFG_M0 |
100462306a36Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MFG_M1 |
100562306a36Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
100662306a36Sopenharmony_ci	},
100762306a36Sopenharmony_ci};
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_cistatic const struct scp_subdomain scp_subdomain_mt8173[] = {
101062306a36Sopenharmony_ci	{MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
101162306a36Sopenharmony_ci	{MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
101262306a36Sopenharmony_ci};
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_cistatic const struct scp_soc_data mt2701_data = {
101562306a36Sopenharmony_ci	.domains = scp_domain_data_mt2701,
101662306a36Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
101762306a36Sopenharmony_ci	.regs = {
101862306a36Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
101962306a36Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
102062306a36Sopenharmony_ci	},
102162306a36Sopenharmony_ci	.bus_prot_reg_update = true,
102262306a36Sopenharmony_ci};
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_cistatic const struct scp_soc_data mt2712_data = {
102562306a36Sopenharmony_ci	.domains = scp_domain_data_mt2712,
102662306a36Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt2712),
102762306a36Sopenharmony_ci	.subdomains = scp_subdomain_mt2712,
102862306a36Sopenharmony_ci	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712),
102962306a36Sopenharmony_ci	.regs = {
103062306a36Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
103162306a36Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
103262306a36Sopenharmony_ci	},
103362306a36Sopenharmony_ci	.bus_prot_reg_update = false,
103462306a36Sopenharmony_ci};
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_cistatic const struct scp_soc_data mt6797_data = {
103762306a36Sopenharmony_ci	.domains = scp_domain_data_mt6797,
103862306a36Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
103962306a36Sopenharmony_ci	.subdomains = scp_subdomain_mt6797,
104062306a36Sopenharmony_ci	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
104162306a36Sopenharmony_ci	.regs = {
104262306a36Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
104362306a36Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
104462306a36Sopenharmony_ci	},
104562306a36Sopenharmony_ci	.bus_prot_reg_update = true,
104662306a36Sopenharmony_ci};
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_cistatic const struct scp_soc_data mt7622_data = {
104962306a36Sopenharmony_ci	.domains = scp_domain_data_mt7622,
105062306a36Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
105162306a36Sopenharmony_ci	.regs = {
105262306a36Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
105362306a36Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
105462306a36Sopenharmony_ci	},
105562306a36Sopenharmony_ci	.bus_prot_reg_update = true,
105662306a36Sopenharmony_ci};
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_cistatic const struct scp_soc_data mt7623a_data = {
105962306a36Sopenharmony_ci	.domains = scp_domain_data_mt7623a,
106062306a36Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt7623a),
106162306a36Sopenharmony_ci	.regs = {
106262306a36Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
106362306a36Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
106462306a36Sopenharmony_ci	},
106562306a36Sopenharmony_ci	.bus_prot_reg_update = true,
106662306a36Sopenharmony_ci};
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_cistatic const struct scp_soc_data mt8173_data = {
106962306a36Sopenharmony_ci	.domains = scp_domain_data_mt8173,
107062306a36Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
107162306a36Sopenharmony_ci	.subdomains = scp_subdomain_mt8173,
107262306a36Sopenharmony_ci	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
107362306a36Sopenharmony_ci	.regs = {
107462306a36Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
107562306a36Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
107662306a36Sopenharmony_ci	},
107762306a36Sopenharmony_ci	.bus_prot_reg_update = true,
107862306a36Sopenharmony_ci};
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci/*
108162306a36Sopenharmony_ci * scpsys driver init
108262306a36Sopenharmony_ci */
108362306a36Sopenharmony_ci
108462306a36Sopenharmony_cistatic const struct of_device_id of_scpsys_match_tbl[] = {
108562306a36Sopenharmony_ci	{
108662306a36Sopenharmony_ci		.compatible = "mediatek,mt2701-scpsys",
108762306a36Sopenharmony_ci		.data = &mt2701_data,
108862306a36Sopenharmony_ci	}, {
108962306a36Sopenharmony_ci		.compatible = "mediatek,mt2712-scpsys",
109062306a36Sopenharmony_ci		.data = &mt2712_data,
109162306a36Sopenharmony_ci	}, {
109262306a36Sopenharmony_ci		.compatible = "mediatek,mt6797-scpsys",
109362306a36Sopenharmony_ci		.data = &mt6797_data,
109462306a36Sopenharmony_ci	}, {
109562306a36Sopenharmony_ci		.compatible = "mediatek,mt7622-scpsys",
109662306a36Sopenharmony_ci		.data = &mt7622_data,
109762306a36Sopenharmony_ci	}, {
109862306a36Sopenharmony_ci		.compatible = "mediatek,mt7623a-scpsys",
109962306a36Sopenharmony_ci		.data = &mt7623a_data,
110062306a36Sopenharmony_ci	}, {
110162306a36Sopenharmony_ci		.compatible = "mediatek,mt8173-scpsys",
110262306a36Sopenharmony_ci		.data = &mt8173_data,
110362306a36Sopenharmony_ci	}, {
110462306a36Sopenharmony_ci		/* sentinel */
110562306a36Sopenharmony_ci	}
110662306a36Sopenharmony_ci};
110762306a36Sopenharmony_ci
110862306a36Sopenharmony_cistatic int scpsys_probe(struct platform_device *pdev)
110962306a36Sopenharmony_ci{
111062306a36Sopenharmony_ci	const struct scp_subdomain *sd;
111162306a36Sopenharmony_ci	const struct scp_soc_data *soc;
111262306a36Sopenharmony_ci	struct scp *scp;
111362306a36Sopenharmony_ci	struct genpd_onecell_data *pd_data;
111462306a36Sopenharmony_ci	int i, ret;
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	soc = of_device_get_match_data(&pdev->dev);
111762306a36Sopenharmony_ci
111862306a36Sopenharmony_ci	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
111962306a36Sopenharmony_ci			soc->bus_prot_reg_update);
112062306a36Sopenharmony_ci	if (IS_ERR(scp))
112162306a36Sopenharmony_ci		return PTR_ERR(scp);
112262306a36Sopenharmony_ci
112362306a36Sopenharmony_ci	mtk_register_power_domains(pdev, scp, soc->num_domains);
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	pd_data = &scp->pd_data;
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci	for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) {
112862306a36Sopenharmony_ci		ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
112962306a36Sopenharmony_ci					     pd_data->domains[sd->subdomain]);
113062306a36Sopenharmony_ci		if (ret && IS_ENABLED(CONFIG_PM))
113162306a36Sopenharmony_ci			dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
113262306a36Sopenharmony_ci				ret);
113362306a36Sopenharmony_ci	}
113462306a36Sopenharmony_ci
113562306a36Sopenharmony_ci	return 0;
113662306a36Sopenharmony_ci}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_cistatic struct platform_driver scpsys_drv = {
113962306a36Sopenharmony_ci	.probe = scpsys_probe,
114062306a36Sopenharmony_ci	.driver = {
114162306a36Sopenharmony_ci		.name = "mtk-scpsys",
114262306a36Sopenharmony_ci		.suppress_bind_attrs = true,
114362306a36Sopenharmony_ci		.owner = THIS_MODULE,
114462306a36Sopenharmony_ci		.of_match_table = of_scpsys_match_tbl,
114562306a36Sopenharmony_ci	},
114662306a36Sopenharmony_ci};
114762306a36Sopenharmony_cibuiltin_platform_driver(scpsys_drv);
1148