18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#include <linux/clk.h>
68c2ecf20Sopenharmony_ci#include <linux/init.h>
78c2ecf20Sopenharmony_ci#include <linux/io.h>
88c2ecf20Sopenharmony_ci#include <linux/iopoll.h>
98c2ecf20Sopenharmony_ci#include <linux/mfd/syscon.h>
108c2ecf20Sopenharmony_ci#include <linux/of_device.h>
118c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
128c2ecf20Sopenharmony_ci#include <linux/pm_domain.h>
138c2ecf20Sopenharmony_ci#include <linux/regulator/consumer.h>
148c2ecf20Sopenharmony_ci#include <linux/soc/mediatek/infracfg.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include <dt-bindings/power/mt2701-power.h>
178c2ecf20Sopenharmony_ci#include <dt-bindings/power/mt2712-power.h>
188c2ecf20Sopenharmony_ci#include <dt-bindings/power/mt6797-power.h>
198c2ecf20Sopenharmony_ci#include <dt-bindings/power/mt7622-power.h>
208c2ecf20Sopenharmony_ci#include <dt-bindings/power/mt7623a-power.h>
218c2ecf20Sopenharmony_ci#include <dt-bindings/power/mt8173-power.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#define MTK_POLL_DELAY_US   10
248c2ecf20Sopenharmony_ci#define MTK_POLL_TIMEOUT    USEC_PER_SEC
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
278c2ecf20Sopenharmony_ci#define MTK_SCPD_FWAIT_SRAM		BIT(1)
288c2ecf20Sopenharmony_ci#define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define SPM_VDE_PWR_CON			0x0210
318c2ecf20Sopenharmony_ci#define SPM_MFG_PWR_CON			0x0214
328c2ecf20Sopenharmony_ci#define SPM_VEN_PWR_CON			0x0230
338c2ecf20Sopenharmony_ci#define SPM_ISP_PWR_CON			0x0238
348c2ecf20Sopenharmony_ci#define SPM_DIS_PWR_CON			0x023c
358c2ecf20Sopenharmony_ci#define SPM_CONN_PWR_CON		0x0280
368c2ecf20Sopenharmony_ci#define SPM_VEN2_PWR_CON		0x0298
378c2ecf20Sopenharmony_ci#define SPM_AUDIO_PWR_CON		0x029c	/* MT8173, MT2712 */
388c2ecf20Sopenharmony_ci#define SPM_BDP_PWR_CON			0x029c	/* MT2701 */
398c2ecf20Sopenharmony_ci#define SPM_ETH_PWR_CON			0x02a0
408c2ecf20Sopenharmony_ci#define SPM_HIF_PWR_CON			0x02a4
418c2ecf20Sopenharmony_ci#define SPM_IFR_MSC_PWR_CON		0x02a8
428c2ecf20Sopenharmony_ci#define SPM_MFG_2D_PWR_CON		0x02c0
438c2ecf20Sopenharmony_ci#define SPM_MFG_ASYNC_PWR_CON		0x02c4
448c2ecf20Sopenharmony_ci#define SPM_USB_PWR_CON			0x02cc
458c2ecf20Sopenharmony_ci#define SPM_USB2_PWR_CON		0x02d4	/* MT2712 */
468c2ecf20Sopenharmony_ci#define SPM_ETHSYS_PWR_CON		0x02e0	/* MT7622 */
478c2ecf20Sopenharmony_ci#define SPM_HIF0_PWR_CON		0x02e4	/* MT7622 */
488c2ecf20Sopenharmony_ci#define SPM_HIF1_PWR_CON		0x02e8	/* MT7622 */
498c2ecf20Sopenharmony_ci#define SPM_WB_PWR_CON			0x02ec	/* MT7622 */
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci#define SPM_PWR_STATUS			0x060c
528c2ecf20Sopenharmony_ci#define SPM_PWR_STATUS_2ND		0x0610
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#define PWR_RST_B_BIT			BIT(0)
558c2ecf20Sopenharmony_ci#define PWR_ISO_BIT			BIT(1)
568c2ecf20Sopenharmony_ci#define PWR_ON_BIT			BIT(2)
578c2ecf20Sopenharmony_ci#define PWR_ON_2ND_BIT			BIT(3)
588c2ecf20Sopenharmony_ci#define PWR_CLK_DIS_BIT			BIT(4)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci#define PWR_STATUS_CONN			BIT(1)
618c2ecf20Sopenharmony_ci#define PWR_STATUS_DISP			BIT(3)
628c2ecf20Sopenharmony_ci#define PWR_STATUS_MFG			BIT(4)
638c2ecf20Sopenharmony_ci#define PWR_STATUS_ISP			BIT(5)
648c2ecf20Sopenharmony_ci#define PWR_STATUS_VDEC			BIT(7)
658c2ecf20Sopenharmony_ci#define PWR_STATUS_BDP			BIT(14)
668c2ecf20Sopenharmony_ci#define PWR_STATUS_ETH			BIT(15)
678c2ecf20Sopenharmony_ci#define PWR_STATUS_HIF			BIT(16)
688c2ecf20Sopenharmony_ci#define PWR_STATUS_IFR_MSC		BIT(17)
698c2ecf20Sopenharmony_ci#define PWR_STATUS_USB2			BIT(19)	/* MT2712 */
708c2ecf20Sopenharmony_ci#define PWR_STATUS_VENC_LT		BIT(20)
718c2ecf20Sopenharmony_ci#define PWR_STATUS_VENC			BIT(21)
728c2ecf20Sopenharmony_ci#define PWR_STATUS_MFG_2D		BIT(22)	/* MT8173 */
738c2ecf20Sopenharmony_ci#define PWR_STATUS_MFG_ASYNC		BIT(23)	/* MT8173 */
748c2ecf20Sopenharmony_ci#define PWR_STATUS_AUDIO		BIT(24)	/* MT8173, MT2712 */
758c2ecf20Sopenharmony_ci#define PWR_STATUS_USB			BIT(25)	/* MT8173, MT2712 */
768c2ecf20Sopenharmony_ci#define PWR_STATUS_ETHSYS		BIT(24)	/* MT7622 */
778c2ecf20Sopenharmony_ci#define PWR_STATUS_HIF0			BIT(25)	/* MT7622 */
788c2ecf20Sopenharmony_ci#define PWR_STATUS_HIF1			BIT(26)	/* MT7622 */
798c2ecf20Sopenharmony_ci#define PWR_STATUS_WB			BIT(27)	/* MT7622 */
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cienum clk_id {
828c2ecf20Sopenharmony_ci	CLK_NONE,
838c2ecf20Sopenharmony_ci	CLK_MM,
848c2ecf20Sopenharmony_ci	CLK_MFG,
858c2ecf20Sopenharmony_ci	CLK_VENC,
868c2ecf20Sopenharmony_ci	CLK_VENC_LT,
878c2ecf20Sopenharmony_ci	CLK_ETHIF,
888c2ecf20Sopenharmony_ci	CLK_VDEC,
898c2ecf20Sopenharmony_ci	CLK_HIFSEL,
908c2ecf20Sopenharmony_ci	CLK_JPGDEC,
918c2ecf20Sopenharmony_ci	CLK_AUDIO,
928c2ecf20Sopenharmony_ci	CLK_MAX,
938c2ecf20Sopenharmony_ci};
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistatic const char * const clk_names[] = {
968c2ecf20Sopenharmony_ci	NULL,
978c2ecf20Sopenharmony_ci	"mm",
988c2ecf20Sopenharmony_ci	"mfg",
998c2ecf20Sopenharmony_ci	"venc",
1008c2ecf20Sopenharmony_ci	"venc_lt",
1018c2ecf20Sopenharmony_ci	"ethif",
1028c2ecf20Sopenharmony_ci	"vdec",
1038c2ecf20Sopenharmony_ci	"hif_sel",
1048c2ecf20Sopenharmony_ci	"jpgdec",
1058c2ecf20Sopenharmony_ci	"audio",
1068c2ecf20Sopenharmony_ci	NULL,
1078c2ecf20Sopenharmony_ci};
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci#define MAX_CLKS	3
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/**
1128c2ecf20Sopenharmony_ci * struct scp_domain_data - scp domain data for power on/off flow
1138c2ecf20Sopenharmony_ci * @name: The domain name.
1148c2ecf20Sopenharmony_ci * @sta_mask: The mask for power on/off status bit.
1158c2ecf20Sopenharmony_ci * @ctl_offs: The offset for main power control register.
1168c2ecf20Sopenharmony_ci * @sram_pdn_bits: The mask for sram power control bits.
1178c2ecf20Sopenharmony_ci * @sram_pdn_ack_bits: The mask for sram power control acked bits.
1188c2ecf20Sopenharmony_ci * @bus_prot_mask: The mask for single step bus protection.
1198c2ecf20Sopenharmony_ci * @clk_id: The basic clocks required by this power domain.
1208c2ecf20Sopenharmony_ci * @caps: The flag for active wake-up action.
1218c2ecf20Sopenharmony_ci */
1228c2ecf20Sopenharmony_cistruct scp_domain_data {
1238c2ecf20Sopenharmony_ci	const char *name;
1248c2ecf20Sopenharmony_ci	u32 sta_mask;
1258c2ecf20Sopenharmony_ci	int ctl_offs;
1268c2ecf20Sopenharmony_ci	u32 sram_pdn_bits;
1278c2ecf20Sopenharmony_ci	u32 sram_pdn_ack_bits;
1288c2ecf20Sopenharmony_ci	u32 bus_prot_mask;
1298c2ecf20Sopenharmony_ci	enum clk_id clk_id[MAX_CLKS];
1308c2ecf20Sopenharmony_ci	u8 caps;
1318c2ecf20Sopenharmony_ci};
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cistruct scp;
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_cistruct scp_domain {
1368c2ecf20Sopenharmony_ci	struct generic_pm_domain genpd;
1378c2ecf20Sopenharmony_ci	struct scp *scp;
1388c2ecf20Sopenharmony_ci	struct clk *clk[MAX_CLKS];
1398c2ecf20Sopenharmony_ci	const struct scp_domain_data *data;
1408c2ecf20Sopenharmony_ci	struct regulator *supply;
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistruct scp_ctrl_reg {
1448c2ecf20Sopenharmony_ci	int pwr_sta_offs;
1458c2ecf20Sopenharmony_ci	int pwr_sta2nd_offs;
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistruct scp {
1498c2ecf20Sopenharmony_ci	struct scp_domain *domains;
1508c2ecf20Sopenharmony_ci	struct genpd_onecell_data pd_data;
1518c2ecf20Sopenharmony_ci	struct device *dev;
1528c2ecf20Sopenharmony_ci	void __iomem *base;
1538c2ecf20Sopenharmony_ci	struct regmap *infracfg;
1548c2ecf20Sopenharmony_ci	struct scp_ctrl_reg ctrl_reg;
1558c2ecf20Sopenharmony_ci	bool bus_prot_reg_update;
1568c2ecf20Sopenharmony_ci};
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_cistruct scp_subdomain {
1598c2ecf20Sopenharmony_ci	int origin;
1608c2ecf20Sopenharmony_ci	int subdomain;
1618c2ecf20Sopenharmony_ci};
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistruct scp_soc_data {
1648c2ecf20Sopenharmony_ci	const struct scp_domain_data *domains;
1658c2ecf20Sopenharmony_ci	int num_domains;
1668c2ecf20Sopenharmony_ci	const struct scp_subdomain *subdomains;
1678c2ecf20Sopenharmony_ci	int num_subdomains;
1688c2ecf20Sopenharmony_ci	const struct scp_ctrl_reg regs;
1698c2ecf20Sopenharmony_ci	bool bus_prot_reg_update;
1708c2ecf20Sopenharmony_ci};
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_cistatic int scpsys_domain_is_on(struct scp_domain *scpd)
1738c2ecf20Sopenharmony_ci{
1748c2ecf20Sopenharmony_ci	struct scp *scp = scpd->scp;
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
1778c2ecf20Sopenharmony_ci						scpd->data->sta_mask;
1788c2ecf20Sopenharmony_ci	u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
1798c2ecf20Sopenharmony_ci						scpd->data->sta_mask;
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_ci	/*
1828c2ecf20Sopenharmony_ci	 * A domain is on when both status bits are set. If only one is set
1838c2ecf20Sopenharmony_ci	 * return an error. This happens while powering up a domain
1848c2ecf20Sopenharmony_ci	 */
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci	if (status && status2)
1878c2ecf20Sopenharmony_ci		return true;
1888c2ecf20Sopenharmony_ci	if (!status && !status2)
1898c2ecf20Sopenharmony_ci		return false;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	return -EINVAL;
1928c2ecf20Sopenharmony_ci}
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_cistatic int scpsys_regulator_enable(struct scp_domain *scpd)
1958c2ecf20Sopenharmony_ci{
1968c2ecf20Sopenharmony_ci	if (!scpd->supply)
1978c2ecf20Sopenharmony_ci		return 0;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	return regulator_enable(scpd->supply);
2008c2ecf20Sopenharmony_ci}
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_cistatic int scpsys_regulator_disable(struct scp_domain *scpd)
2038c2ecf20Sopenharmony_ci{
2048c2ecf20Sopenharmony_ci	if (!scpd->supply)
2058c2ecf20Sopenharmony_ci		return 0;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	return regulator_disable(scpd->supply);
2088c2ecf20Sopenharmony_ci}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic void scpsys_clk_disable(struct clk *clk[], int max_num)
2118c2ecf20Sopenharmony_ci{
2128c2ecf20Sopenharmony_ci	int i;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	for (i = max_num - 1; i >= 0; i--)
2158c2ecf20Sopenharmony_ci		clk_disable_unprepare(clk[i]);
2168c2ecf20Sopenharmony_ci}
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_cistatic int scpsys_clk_enable(struct clk *clk[], int max_num)
2198c2ecf20Sopenharmony_ci{
2208c2ecf20Sopenharmony_ci	int i, ret = 0;
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	for (i = 0; i < max_num && clk[i]; i++) {
2238c2ecf20Sopenharmony_ci		ret = clk_prepare_enable(clk[i]);
2248c2ecf20Sopenharmony_ci		if (ret) {
2258c2ecf20Sopenharmony_ci			scpsys_clk_disable(clk, i);
2268c2ecf20Sopenharmony_ci			break;
2278c2ecf20Sopenharmony_ci		}
2288c2ecf20Sopenharmony_ci	}
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci	return ret;
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_cistatic int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
2348c2ecf20Sopenharmony_ci{
2358c2ecf20Sopenharmony_ci	u32 val;
2368c2ecf20Sopenharmony_ci	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
2378c2ecf20Sopenharmony_ci	int tmp;
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	val = readl(ctl_addr);
2408c2ecf20Sopenharmony_ci	val &= ~scpd->data->sram_pdn_bits;
2418c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci	/* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
2448c2ecf20Sopenharmony_ci	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
2458c2ecf20Sopenharmony_ci		/*
2468c2ecf20Sopenharmony_ci		 * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
2478c2ecf20Sopenharmony_ci		 * MT7622_POWER_DOMAIN_WB and thus just a trivial setup
2488c2ecf20Sopenharmony_ci		 * is applied here.
2498c2ecf20Sopenharmony_ci		 */
2508c2ecf20Sopenharmony_ci		usleep_range(12000, 12100);
2518c2ecf20Sopenharmony_ci	} else {
2528c2ecf20Sopenharmony_ci		/* Either wait until SRAM_PDN_ACK all 1 or 0 */
2538c2ecf20Sopenharmony_ci		int ret = readl_poll_timeout(ctl_addr, tmp,
2548c2ecf20Sopenharmony_ci				(tmp & pdn_ack) == 0,
2558c2ecf20Sopenharmony_ci				MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
2568c2ecf20Sopenharmony_ci		if (ret < 0)
2578c2ecf20Sopenharmony_ci			return ret;
2588c2ecf20Sopenharmony_ci	}
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	return 0;
2618c2ecf20Sopenharmony_ci}
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_cistatic int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
2648c2ecf20Sopenharmony_ci{
2658c2ecf20Sopenharmony_ci	u32 val;
2668c2ecf20Sopenharmony_ci	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
2678c2ecf20Sopenharmony_ci	int tmp;
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	val = readl(ctl_addr);
2708c2ecf20Sopenharmony_ci	val |= scpd->data->sram_pdn_bits;
2718c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	/* Either wait until SRAM_PDN_ACK all 1 or 0 */
2748c2ecf20Sopenharmony_ci	return readl_poll_timeout(ctl_addr, tmp,
2758c2ecf20Sopenharmony_ci			(tmp & pdn_ack) == pdn_ack,
2768c2ecf20Sopenharmony_ci			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
2778c2ecf20Sopenharmony_ci}
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_cistatic int scpsys_bus_protect_enable(struct scp_domain *scpd)
2808c2ecf20Sopenharmony_ci{
2818c2ecf20Sopenharmony_ci	struct scp *scp = scpd->scp;
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	if (!scpd->data->bus_prot_mask)
2848c2ecf20Sopenharmony_ci		return 0;
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci	return mtk_infracfg_set_bus_protection(scp->infracfg,
2878c2ecf20Sopenharmony_ci			scpd->data->bus_prot_mask,
2888c2ecf20Sopenharmony_ci			scp->bus_prot_reg_update);
2898c2ecf20Sopenharmony_ci}
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_cistatic int scpsys_bus_protect_disable(struct scp_domain *scpd)
2928c2ecf20Sopenharmony_ci{
2938c2ecf20Sopenharmony_ci	struct scp *scp = scpd->scp;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	if (!scpd->data->bus_prot_mask)
2968c2ecf20Sopenharmony_ci		return 0;
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci	return mtk_infracfg_clear_bus_protection(scp->infracfg,
2998c2ecf20Sopenharmony_ci			scpd->data->bus_prot_mask,
3008c2ecf20Sopenharmony_ci			scp->bus_prot_reg_update);
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_cistatic int scpsys_power_on(struct generic_pm_domain *genpd)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
3068c2ecf20Sopenharmony_ci	struct scp *scp = scpd->scp;
3078c2ecf20Sopenharmony_ci	void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
3088c2ecf20Sopenharmony_ci	u32 val;
3098c2ecf20Sopenharmony_ci	int ret, tmp;
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci	ret = scpsys_regulator_enable(scpd);
3128c2ecf20Sopenharmony_ci	if (ret < 0)
3138c2ecf20Sopenharmony_ci		return ret;
3148c2ecf20Sopenharmony_ci
3158c2ecf20Sopenharmony_ci	ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
3168c2ecf20Sopenharmony_ci	if (ret)
3178c2ecf20Sopenharmony_ci		goto err_clk;
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci	/* subsys power on */
3208c2ecf20Sopenharmony_ci	val = readl(ctl_addr);
3218c2ecf20Sopenharmony_ci	val |= PWR_ON_BIT;
3228c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3238c2ecf20Sopenharmony_ci	val |= PWR_ON_2ND_BIT;
3248c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci	/* wait until PWR_ACK = 1 */
3278c2ecf20Sopenharmony_ci	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
3288c2ecf20Sopenharmony_ci				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
3298c2ecf20Sopenharmony_ci	if (ret < 0)
3308c2ecf20Sopenharmony_ci		goto err_pwr_ack;
3318c2ecf20Sopenharmony_ci
3328c2ecf20Sopenharmony_ci	val &= ~PWR_CLK_DIS_BIT;
3338c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	val &= ~PWR_ISO_BIT;
3368c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	val |= PWR_RST_B_BIT;
3398c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci	ret = scpsys_sram_enable(scpd, ctl_addr);
3428c2ecf20Sopenharmony_ci	if (ret < 0)
3438c2ecf20Sopenharmony_ci		goto err_pwr_ack;
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci	ret = scpsys_bus_protect_disable(scpd);
3468c2ecf20Sopenharmony_ci	if (ret < 0)
3478c2ecf20Sopenharmony_ci		goto err_pwr_ack;
3488c2ecf20Sopenharmony_ci
3498c2ecf20Sopenharmony_ci	return 0;
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_cierr_pwr_ack:
3528c2ecf20Sopenharmony_ci	scpsys_clk_disable(scpd->clk, MAX_CLKS);
3538c2ecf20Sopenharmony_cierr_clk:
3548c2ecf20Sopenharmony_ci	scpsys_regulator_disable(scpd);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci	return ret;
3598c2ecf20Sopenharmony_ci}
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_cistatic int scpsys_power_off(struct generic_pm_domain *genpd)
3628c2ecf20Sopenharmony_ci{
3638c2ecf20Sopenharmony_ci	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
3648c2ecf20Sopenharmony_ci	struct scp *scp = scpd->scp;
3658c2ecf20Sopenharmony_ci	void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
3668c2ecf20Sopenharmony_ci	u32 val;
3678c2ecf20Sopenharmony_ci	int ret, tmp;
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci	ret = scpsys_bus_protect_enable(scpd);
3708c2ecf20Sopenharmony_ci	if (ret < 0)
3718c2ecf20Sopenharmony_ci		goto out;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	ret = scpsys_sram_disable(scpd, ctl_addr);
3748c2ecf20Sopenharmony_ci	if (ret < 0)
3758c2ecf20Sopenharmony_ci		goto out;
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	/* subsys power off */
3788c2ecf20Sopenharmony_ci	val = readl(ctl_addr);
3798c2ecf20Sopenharmony_ci	val |= PWR_ISO_BIT;
3808c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	val &= ~PWR_RST_B_BIT;
3838c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ci	val |= PWR_CLK_DIS_BIT;
3868c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci	val &= ~PWR_ON_BIT;
3898c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci	val &= ~PWR_ON_2ND_BIT;
3928c2ecf20Sopenharmony_ci	writel(val, ctl_addr);
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_ci	/* wait until PWR_ACK = 0 */
3958c2ecf20Sopenharmony_ci	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
3968c2ecf20Sopenharmony_ci				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
3978c2ecf20Sopenharmony_ci	if (ret < 0)
3988c2ecf20Sopenharmony_ci		goto out;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	scpsys_clk_disable(scpd->clk, MAX_CLKS);
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	ret = scpsys_regulator_disable(scpd);
4038c2ecf20Sopenharmony_ci	if (ret < 0)
4048c2ecf20Sopenharmony_ci		goto out;
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	return 0;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ciout:
4098c2ecf20Sopenharmony_ci	dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci	return ret;
4128c2ecf20Sopenharmony_ci}
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_cistatic void init_clks(struct platform_device *pdev, struct clk **clk)
4158c2ecf20Sopenharmony_ci{
4168c2ecf20Sopenharmony_ci	int i;
4178c2ecf20Sopenharmony_ci
4188c2ecf20Sopenharmony_ci	for (i = CLK_NONE + 1; i < CLK_MAX; i++)
4198c2ecf20Sopenharmony_ci		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
4208c2ecf20Sopenharmony_ci}
4218c2ecf20Sopenharmony_ci
4228c2ecf20Sopenharmony_cistatic struct scp *init_scp(struct platform_device *pdev,
4238c2ecf20Sopenharmony_ci			const struct scp_domain_data *scp_domain_data, int num,
4248c2ecf20Sopenharmony_ci			const struct scp_ctrl_reg *scp_ctrl_reg,
4258c2ecf20Sopenharmony_ci			bool bus_prot_reg_update)
4268c2ecf20Sopenharmony_ci{
4278c2ecf20Sopenharmony_ci	struct genpd_onecell_data *pd_data;
4288c2ecf20Sopenharmony_ci	struct resource *res;
4298c2ecf20Sopenharmony_ci	int i, j;
4308c2ecf20Sopenharmony_ci	struct scp *scp;
4318c2ecf20Sopenharmony_ci	struct clk *clk[CLK_MAX];
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci	scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
4348c2ecf20Sopenharmony_ci	if (!scp)
4358c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
4388c2ecf20Sopenharmony_ci	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	scp->bus_prot_reg_update = bus_prot_reg_update;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	scp->dev = &pdev->dev;
4438c2ecf20Sopenharmony_ci
4448c2ecf20Sopenharmony_ci	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
4458c2ecf20Sopenharmony_ci	scp->base = devm_ioremap_resource(&pdev->dev, res);
4468c2ecf20Sopenharmony_ci	if (IS_ERR(scp->base))
4478c2ecf20Sopenharmony_ci		return ERR_CAST(scp->base);
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci	scp->domains = devm_kcalloc(&pdev->dev,
4508c2ecf20Sopenharmony_ci				num, sizeof(*scp->domains), GFP_KERNEL);
4518c2ecf20Sopenharmony_ci	if (!scp->domains)
4528c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
4538c2ecf20Sopenharmony_ci
4548c2ecf20Sopenharmony_ci	pd_data = &scp->pd_data;
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci	pd_data->domains = devm_kcalloc(&pdev->dev,
4578c2ecf20Sopenharmony_ci			num, sizeof(*pd_data->domains), GFP_KERNEL);
4588c2ecf20Sopenharmony_ci	if (!pd_data->domains)
4598c2ecf20Sopenharmony_ci		return ERR_PTR(-ENOMEM);
4608c2ecf20Sopenharmony_ci
4618c2ecf20Sopenharmony_ci	scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
4628c2ecf20Sopenharmony_ci			"infracfg");
4638c2ecf20Sopenharmony_ci	if (IS_ERR(scp->infracfg)) {
4648c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
4658c2ecf20Sopenharmony_ci				PTR_ERR(scp->infracfg));
4668c2ecf20Sopenharmony_ci		return ERR_CAST(scp->infracfg);
4678c2ecf20Sopenharmony_ci	}
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	for (i = 0; i < num; i++) {
4708c2ecf20Sopenharmony_ci		struct scp_domain *scpd = &scp->domains[i];
4718c2ecf20Sopenharmony_ci		const struct scp_domain_data *data = &scp_domain_data[i];
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci		scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
4748c2ecf20Sopenharmony_ci		if (IS_ERR(scpd->supply)) {
4758c2ecf20Sopenharmony_ci			if (PTR_ERR(scpd->supply) == -ENODEV)
4768c2ecf20Sopenharmony_ci				scpd->supply = NULL;
4778c2ecf20Sopenharmony_ci			else
4788c2ecf20Sopenharmony_ci				return ERR_CAST(scpd->supply);
4798c2ecf20Sopenharmony_ci		}
4808c2ecf20Sopenharmony_ci	}
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_ci	pd_data->num_domains = num;
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_ci	init_clks(pdev, clk);
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	for (i = 0; i < num; i++) {
4878c2ecf20Sopenharmony_ci		struct scp_domain *scpd = &scp->domains[i];
4888c2ecf20Sopenharmony_ci		struct generic_pm_domain *genpd = &scpd->genpd;
4898c2ecf20Sopenharmony_ci		const struct scp_domain_data *data = &scp_domain_data[i];
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci		pd_data->domains[i] = genpd;
4928c2ecf20Sopenharmony_ci		scpd->scp = scp;
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci		scpd->data = data;
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_ci		for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
4978c2ecf20Sopenharmony_ci			struct clk *c = clk[data->clk_id[j]];
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_ci			if (IS_ERR(c)) {
5008c2ecf20Sopenharmony_ci				dev_err(&pdev->dev, "%s: clk unavailable\n",
5018c2ecf20Sopenharmony_ci					data->name);
5028c2ecf20Sopenharmony_ci				return ERR_CAST(c);
5038c2ecf20Sopenharmony_ci			}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci			scpd->clk[j] = c;
5068c2ecf20Sopenharmony_ci		}
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci		genpd->name = data->name;
5098c2ecf20Sopenharmony_ci		genpd->power_off = scpsys_power_off;
5108c2ecf20Sopenharmony_ci		genpd->power_on = scpsys_power_on;
5118c2ecf20Sopenharmony_ci		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
5128c2ecf20Sopenharmony_ci			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
5138c2ecf20Sopenharmony_ci	}
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ci	return scp;
5168c2ecf20Sopenharmony_ci}
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_cistatic void mtk_register_power_domains(struct platform_device *pdev,
5198c2ecf20Sopenharmony_ci				struct scp *scp, int num)
5208c2ecf20Sopenharmony_ci{
5218c2ecf20Sopenharmony_ci	struct genpd_onecell_data *pd_data;
5228c2ecf20Sopenharmony_ci	int i, ret;
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci	for (i = 0; i < num; i++) {
5258c2ecf20Sopenharmony_ci		struct scp_domain *scpd = &scp->domains[i];
5268c2ecf20Sopenharmony_ci		struct generic_pm_domain *genpd = &scpd->genpd;
5278c2ecf20Sopenharmony_ci		bool on;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci		/*
5308c2ecf20Sopenharmony_ci		 * Initially turn on all domains to make the domains usable
5318c2ecf20Sopenharmony_ci		 * with !CONFIG_PM and to get the hardware in sync with the
5328c2ecf20Sopenharmony_ci		 * software.  The unused domains will be switched off during
5338c2ecf20Sopenharmony_ci		 * late_init time.
5348c2ecf20Sopenharmony_ci		 */
5358c2ecf20Sopenharmony_ci		on = !WARN_ON(genpd->power_on(genpd) < 0);
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_ci		pm_genpd_init(genpd, NULL, !on);
5388c2ecf20Sopenharmony_ci	}
5398c2ecf20Sopenharmony_ci
5408c2ecf20Sopenharmony_ci	/*
5418c2ecf20Sopenharmony_ci	 * We are not allowed to fail here since there is no way to unregister
5428c2ecf20Sopenharmony_ci	 * a power domain. Once registered above we have to keep the domains
5438c2ecf20Sopenharmony_ci	 * valid.
5448c2ecf20Sopenharmony_ci	 */
5458c2ecf20Sopenharmony_ci
5468c2ecf20Sopenharmony_ci	pd_data = &scp->pd_data;
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_ci	ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
5498c2ecf20Sopenharmony_ci	if (ret)
5508c2ecf20Sopenharmony_ci		dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
5518c2ecf20Sopenharmony_ci}
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ci/*
5548c2ecf20Sopenharmony_ci * MT2701 power domain support
5558c2ecf20Sopenharmony_ci */
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt2701[] = {
5588c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_CONN] = {
5598c2ecf20Sopenharmony_ci		.name = "conn",
5608c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_CONN,
5618c2ecf20Sopenharmony_ci		.ctl_offs = SPM_CONN_PWR_CON,
5628c2ecf20Sopenharmony_ci		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
5638c2ecf20Sopenharmony_ci				 MT2701_TOP_AXI_PROT_EN_CONN_S,
5648c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
5658c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
5668c2ecf20Sopenharmony_ci	},
5678c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_DISP] = {
5688c2ecf20Sopenharmony_ci		.name = "disp",
5698c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_DISP,
5708c2ecf20Sopenharmony_ci		.ctl_offs = SPM_DIS_PWR_CON,
5718c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
5728c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
5738c2ecf20Sopenharmony_ci		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
5748c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
5758c2ecf20Sopenharmony_ci	},
5768c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_MFG] = {
5778c2ecf20Sopenharmony_ci		.name = "mfg",
5788c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG,
5798c2ecf20Sopenharmony_ci		.ctl_offs = SPM_MFG_PWR_CON,
5808c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
5818c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
5828c2ecf20Sopenharmony_ci		.clk_id = {CLK_MFG},
5838c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
5848c2ecf20Sopenharmony_ci	},
5858c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_VDEC] = {
5868c2ecf20Sopenharmony_ci		.name = "vdec",
5878c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_VDEC,
5888c2ecf20Sopenharmony_ci		.ctl_offs = SPM_VDE_PWR_CON,
5898c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
5908c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
5918c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
5928c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
5938c2ecf20Sopenharmony_ci	},
5948c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_ISP] = {
5958c2ecf20Sopenharmony_ci		.name = "isp",
5968c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_ISP,
5978c2ecf20Sopenharmony_ci		.ctl_offs = SPM_ISP_PWR_CON,
5988c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
5998c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
6008c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
6018c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6028c2ecf20Sopenharmony_ci	},
6038c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_BDP] = {
6048c2ecf20Sopenharmony_ci		.name = "bdp",
6058c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_BDP,
6068c2ecf20Sopenharmony_ci		.ctl_offs = SPM_BDP_PWR_CON,
6078c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
6088c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
6098c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6108c2ecf20Sopenharmony_ci	},
6118c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_ETH] = {
6128c2ecf20Sopenharmony_ci		.name = "eth",
6138c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_ETH,
6148c2ecf20Sopenharmony_ci		.ctl_offs = SPM_ETH_PWR_CON,
6158c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
6168c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
6178c2ecf20Sopenharmony_ci		.clk_id = {CLK_ETHIF},
6188c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6198c2ecf20Sopenharmony_ci	},
6208c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_HIF] = {
6218c2ecf20Sopenharmony_ci		.name = "hif",
6228c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF,
6238c2ecf20Sopenharmony_ci		.ctl_offs = SPM_HIF_PWR_CON,
6248c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
6258c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
6268c2ecf20Sopenharmony_ci		.clk_id = {CLK_ETHIF},
6278c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6288c2ecf20Sopenharmony_ci	},
6298c2ecf20Sopenharmony_ci	[MT2701_POWER_DOMAIN_IFR_MSC] = {
6308c2ecf20Sopenharmony_ci		.name = "ifr_msc",
6318c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_IFR_MSC,
6328c2ecf20Sopenharmony_ci		.ctl_offs = SPM_IFR_MSC_PWR_CON,
6338c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
6348c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6358c2ecf20Sopenharmony_ci	},
6368c2ecf20Sopenharmony_ci};
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci/*
6398c2ecf20Sopenharmony_ci * MT2712 power domain support
6408c2ecf20Sopenharmony_ci */
6418c2ecf20Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt2712[] = {
6428c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_MM] = {
6438c2ecf20Sopenharmony_ci		.name = "mm",
6448c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_DISP,
6458c2ecf20Sopenharmony_ci		.ctl_offs = SPM_DIS_PWR_CON,
6468c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
6478c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
6488c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
6498c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6508c2ecf20Sopenharmony_ci	},
6518c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_VDEC] = {
6528c2ecf20Sopenharmony_ci		.name = "vdec",
6538c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_VDEC,
6548c2ecf20Sopenharmony_ci		.ctl_offs = SPM_VDE_PWR_CON,
6558c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
6568c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
6578c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VDEC},
6588c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6598c2ecf20Sopenharmony_ci	},
6608c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_VENC] = {
6618c2ecf20Sopenharmony_ci		.name = "venc",
6628c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_VENC,
6638c2ecf20Sopenharmony_ci		.ctl_offs = SPM_VEN_PWR_CON,
6648c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
6658c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
6668c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
6678c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6688c2ecf20Sopenharmony_ci	},
6698c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_ISP] = {
6708c2ecf20Sopenharmony_ci		.name = "isp",
6718c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_ISP,
6728c2ecf20Sopenharmony_ci		.ctl_offs = SPM_ISP_PWR_CON,
6738c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
6748c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
6758c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
6768c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6778c2ecf20Sopenharmony_ci	},
6788c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_AUDIO] = {
6798c2ecf20Sopenharmony_ci		.name = "audio",
6808c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_AUDIO,
6818c2ecf20Sopenharmony_ci		.ctl_offs = SPM_AUDIO_PWR_CON,
6828c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
6838c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
6848c2ecf20Sopenharmony_ci		.clk_id = {CLK_AUDIO},
6858c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6868c2ecf20Sopenharmony_ci	},
6878c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_USB] = {
6888c2ecf20Sopenharmony_ci		.name = "usb",
6898c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_USB,
6908c2ecf20Sopenharmony_ci		.ctl_offs = SPM_USB_PWR_CON,
6918c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(10, 8),
6928c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(14, 12),
6938c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
6948c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
6958c2ecf20Sopenharmony_ci	},
6968c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_USB2] = {
6978c2ecf20Sopenharmony_ci		.name = "usb2",
6988c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_USB2,
6998c2ecf20Sopenharmony_ci		.ctl_offs = SPM_USB2_PWR_CON,
7008c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(10, 8),
7018c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(14, 12),
7028c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7038c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
7048c2ecf20Sopenharmony_ci	},
7058c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG] = {
7068c2ecf20Sopenharmony_ci		.name = "mfg",
7078c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG,
7088c2ecf20Sopenharmony_ci		.ctl_offs = SPM_MFG_PWR_CON,
7098c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
7108c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
7118c2ecf20Sopenharmony_ci		.clk_id = {CLK_MFG},
7128c2ecf20Sopenharmony_ci		.bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
7138c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
7148c2ecf20Sopenharmony_ci	},
7158c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG_SC1] = {
7168c2ecf20Sopenharmony_ci		.name = "mfg_sc1",
7178c2ecf20Sopenharmony_ci		.sta_mask = BIT(22),
7188c2ecf20Sopenharmony_ci		.ctl_offs = 0x02c0,
7198c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
7208c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
7218c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7228c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
7238c2ecf20Sopenharmony_ci	},
7248c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG_SC2] = {
7258c2ecf20Sopenharmony_ci		.name = "mfg_sc2",
7268c2ecf20Sopenharmony_ci		.sta_mask = BIT(23),
7278c2ecf20Sopenharmony_ci		.ctl_offs = 0x02c4,
7288c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
7298c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
7308c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7318c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
7328c2ecf20Sopenharmony_ci	},
7338c2ecf20Sopenharmony_ci	[MT2712_POWER_DOMAIN_MFG_SC3] = {
7348c2ecf20Sopenharmony_ci		.name = "mfg_sc3",
7358c2ecf20Sopenharmony_ci		.sta_mask = BIT(30),
7368c2ecf20Sopenharmony_ci		.ctl_offs = 0x01f8,
7378c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
7388c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(16, 16),
7398c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7408c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
7418c2ecf20Sopenharmony_ci	},
7428c2ecf20Sopenharmony_ci};
7438c2ecf20Sopenharmony_ci
7448c2ecf20Sopenharmony_cistatic const struct scp_subdomain scp_subdomain_mt2712[] = {
7458c2ecf20Sopenharmony_ci	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC},
7468c2ecf20Sopenharmony_ci	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC},
7478c2ecf20Sopenharmony_ci	{MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP},
7488c2ecf20Sopenharmony_ci	{MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1},
7498c2ecf20Sopenharmony_ci	{MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2},
7508c2ecf20Sopenharmony_ci	{MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3},
7518c2ecf20Sopenharmony_ci};
7528c2ecf20Sopenharmony_ci
7538c2ecf20Sopenharmony_ci/*
7548c2ecf20Sopenharmony_ci * MT6797 power domain support
7558c2ecf20Sopenharmony_ci */
7568c2ecf20Sopenharmony_ci
7578c2ecf20Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt6797[] = {
7588c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_VDEC] = {
7598c2ecf20Sopenharmony_ci		.name = "vdec",
7608c2ecf20Sopenharmony_ci		.sta_mask = BIT(7),
7618c2ecf20Sopenharmony_ci		.ctl_offs = 0x300,
7628c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
7638c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
7648c2ecf20Sopenharmony_ci		.clk_id = {CLK_VDEC},
7658c2ecf20Sopenharmony_ci	},
7668c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_VENC] = {
7678c2ecf20Sopenharmony_ci		.name = "venc",
7688c2ecf20Sopenharmony_ci		.sta_mask = BIT(21),
7698c2ecf20Sopenharmony_ci		.ctl_offs = 0x304,
7708c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
7718c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
7728c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7738c2ecf20Sopenharmony_ci	},
7748c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_ISP] = {
7758c2ecf20Sopenharmony_ci		.name = "isp",
7768c2ecf20Sopenharmony_ci		.sta_mask = BIT(5),
7778c2ecf20Sopenharmony_ci		.ctl_offs = 0x308,
7788c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(9, 8),
7798c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
7808c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7818c2ecf20Sopenharmony_ci	},
7828c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_MM] = {
7838c2ecf20Sopenharmony_ci		.name = "mm",
7848c2ecf20Sopenharmony_ci		.sta_mask = BIT(3),
7858c2ecf20Sopenharmony_ci		.ctl_offs = 0x30C,
7868c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
7878c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
7888c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
7898c2ecf20Sopenharmony_ci		.bus_prot_mask = (BIT(1) | BIT(2)),
7908c2ecf20Sopenharmony_ci	},
7918c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_AUDIO] = {
7928c2ecf20Sopenharmony_ci		.name = "audio",
7938c2ecf20Sopenharmony_ci		.sta_mask = BIT(24),
7948c2ecf20Sopenharmony_ci		.ctl_offs = 0x314,
7958c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
7968c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
7978c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
7988c2ecf20Sopenharmony_ci	},
7998c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_MFG_ASYNC] = {
8008c2ecf20Sopenharmony_ci		.name = "mfg_async",
8018c2ecf20Sopenharmony_ci		.sta_mask = BIT(13),
8028c2ecf20Sopenharmony_ci		.ctl_offs = 0x334,
8038c2ecf20Sopenharmony_ci		.sram_pdn_bits = 0,
8048c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = 0,
8058c2ecf20Sopenharmony_ci		.clk_id = {CLK_MFG},
8068c2ecf20Sopenharmony_ci	},
8078c2ecf20Sopenharmony_ci	[MT6797_POWER_DOMAIN_MJC] = {
8088c2ecf20Sopenharmony_ci		.name = "mjc",
8098c2ecf20Sopenharmony_ci		.sta_mask = BIT(20),
8108c2ecf20Sopenharmony_ci		.ctl_offs = 0x310,
8118c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(8, 8),
8128c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
8138c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
8148c2ecf20Sopenharmony_ci	},
8158c2ecf20Sopenharmony_ci};
8168c2ecf20Sopenharmony_ci
8178c2ecf20Sopenharmony_ci#define SPM_PWR_STATUS_MT6797		0x0180
8188c2ecf20Sopenharmony_ci#define SPM_PWR_STATUS_2ND_MT6797	0x0184
8198c2ecf20Sopenharmony_ci
8208c2ecf20Sopenharmony_cistatic const struct scp_subdomain scp_subdomain_mt6797[] = {
8218c2ecf20Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
8228c2ecf20Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
8238c2ecf20Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
8248c2ecf20Sopenharmony_ci	{MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
8258c2ecf20Sopenharmony_ci};
8268c2ecf20Sopenharmony_ci
8278c2ecf20Sopenharmony_ci/*
8288c2ecf20Sopenharmony_ci * MT7622 power domain support
8298c2ecf20Sopenharmony_ci */
8308c2ecf20Sopenharmony_ci
8318c2ecf20Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt7622[] = {
8328c2ecf20Sopenharmony_ci	[MT7622_POWER_DOMAIN_ETHSYS] = {
8338c2ecf20Sopenharmony_ci		.name = "ethsys",
8348c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_ETHSYS,
8358c2ecf20Sopenharmony_ci		.ctl_offs = SPM_ETHSYS_PWR_CON,
8368c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
8378c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
8388c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
8398c2ecf20Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
8408c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
8418c2ecf20Sopenharmony_ci	},
8428c2ecf20Sopenharmony_ci	[MT7622_POWER_DOMAIN_HIF0] = {
8438c2ecf20Sopenharmony_ci		.name = "hif0",
8448c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF0,
8458c2ecf20Sopenharmony_ci		.ctl_offs = SPM_HIF0_PWR_CON,
8468c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
8478c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
8488c2ecf20Sopenharmony_ci		.clk_id = {CLK_HIFSEL},
8498c2ecf20Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
8508c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
8518c2ecf20Sopenharmony_ci	},
8528c2ecf20Sopenharmony_ci	[MT7622_POWER_DOMAIN_HIF1] = {
8538c2ecf20Sopenharmony_ci		.name = "hif1",
8548c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF1,
8558c2ecf20Sopenharmony_ci		.ctl_offs = SPM_HIF1_PWR_CON,
8568c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
8578c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
8588c2ecf20Sopenharmony_ci		.clk_id = {CLK_HIFSEL},
8598c2ecf20Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
8608c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
8618c2ecf20Sopenharmony_ci	},
8628c2ecf20Sopenharmony_ci	[MT7622_POWER_DOMAIN_WB] = {
8638c2ecf20Sopenharmony_ci		.name = "wb",
8648c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_WB,
8658c2ecf20Sopenharmony_ci		.ctl_offs = SPM_WB_PWR_CON,
8668c2ecf20Sopenharmony_ci		.sram_pdn_bits = 0,
8678c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = 0,
8688c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
8698c2ecf20Sopenharmony_ci		.bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
8708c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM,
8718c2ecf20Sopenharmony_ci	},
8728c2ecf20Sopenharmony_ci};
8738c2ecf20Sopenharmony_ci
8748c2ecf20Sopenharmony_ci/*
8758c2ecf20Sopenharmony_ci * MT7623A power domain support
8768c2ecf20Sopenharmony_ci */
8778c2ecf20Sopenharmony_ci
8788c2ecf20Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt7623a[] = {
8798c2ecf20Sopenharmony_ci	[MT7623A_POWER_DOMAIN_CONN] = {
8808c2ecf20Sopenharmony_ci		.name = "conn",
8818c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_CONN,
8828c2ecf20Sopenharmony_ci		.ctl_offs = SPM_CONN_PWR_CON,
8838c2ecf20Sopenharmony_ci		.bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
8848c2ecf20Sopenharmony_ci				 MT2701_TOP_AXI_PROT_EN_CONN_S,
8858c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
8868c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
8878c2ecf20Sopenharmony_ci	},
8888c2ecf20Sopenharmony_ci	[MT7623A_POWER_DOMAIN_ETH] = {
8898c2ecf20Sopenharmony_ci		.name = "eth",
8908c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_ETH,
8918c2ecf20Sopenharmony_ci		.ctl_offs = SPM_ETH_PWR_CON,
8928c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
8938c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
8948c2ecf20Sopenharmony_ci		.clk_id = {CLK_ETHIF},
8958c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
8968c2ecf20Sopenharmony_ci	},
8978c2ecf20Sopenharmony_ci	[MT7623A_POWER_DOMAIN_HIF] = {
8988c2ecf20Sopenharmony_ci		.name = "hif",
8998c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_HIF,
9008c2ecf20Sopenharmony_ci		.ctl_offs = SPM_HIF_PWR_CON,
9018c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9028c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
9038c2ecf20Sopenharmony_ci		.clk_id = {CLK_ETHIF},
9048c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
9058c2ecf20Sopenharmony_ci	},
9068c2ecf20Sopenharmony_ci	[MT7623A_POWER_DOMAIN_IFR_MSC] = {
9078c2ecf20Sopenharmony_ci		.name = "ifr_msc",
9088c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_IFR_MSC,
9098c2ecf20Sopenharmony_ci		.ctl_offs = SPM_IFR_MSC_PWR_CON,
9108c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
9118c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
9128c2ecf20Sopenharmony_ci	},
9138c2ecf20Sopenharmony_ci};
9148c2ecf20Sopenharmony_ci
9158c2ecf20Sopenharmony_ci/*
9168c2ecf20Sopenharmony_ci * MT8173 power domain support
9178c2ecf20Sopenharmony_ci */
9188c2ecf20Sopenharmony_ci
9198c2ecf20Sopenharmony_cistatic const struct scp_domain_data scp_domain_data_mt8173[] = {
9208c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_VDEC] = {
9218c2ecf20Sopenharmony_ci		.name = "vdec",
9228c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_VDEC,
9238c2ecf20Sopenharmony_ci		.ctl_offs = SPM_VDE_PWR_CON,
9248c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9258c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
9268c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
9278c2ecf20Sopenharmony_ci	},
9288c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_VENC] = {
9298c2ecf20Sopenharmony_ci		.name = "venc",
9308c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_VENC,
9318c2ecf20Sopenharmony_ci		.ctl_offs = SPM_VEN_PWR_CON,
9328c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9338c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
9348c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VENC},
9358c2ecf20Sopenharmony_ci	},
9368c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_ISP] = {
9378c2ecf20Sopenharmony_ci		.name = "isp",
9388c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_ISP,
9398c2ecf20Sopenharmony_ci		.ctl_offs = SPM_ISP_PWR_CON,
9408c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9418c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
9428c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
9438c2ecf20Sopenharmony_ci	},
9448c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_MM] = {
9458c2ecf20Sopenharmony_ci		.name = "mm",
9468c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_DISP,
9478c2ecf20Sopenharmony_ci		.ctl_offs = SPM_DIS_PWR_CON,
9488c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9498c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(12, 12),
9508c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM},
9518c2ecf20Sopenharmony_ci		.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
9528c2ecf20Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MM_M1,
9538c2ecf20Sopenharmony_ci	},
9548c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_VENC_LT] = {
9558c2ecf20Sopenharmony_ci		.name = "venc_lt",
9568c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_VENC_LT,
9578c2ecf20Sopenharmony_ci		.ctl_offs = SPM_VEN2_PWR_CON,
9588c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9598c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
9608c2ecf20Sopenharmony_ci		.clk_id = {CLK_MM, CLK_VENC_LT},
9618c2ecf20Sopenharmony_ci	},
9628c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_AUDIO] = {
9638c2ecf20Sopenharmony_ci		.name = "audio",
9648c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_AUDIO,
9658c2ecf20Sopenharmony_ci		.ctl_offs = SPM_AUDIO_PWR_CON,
9668c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9678c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
9688c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
9698c2ecf20Sopenharmony_ci	},
9708c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_USB] = {
9718c2ecf20Sopenharmony_ci		.name = "usb",
9728c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_USB,
9738c2ecf20Sopenharmony_ci		.ctl_offs = SPM_USB_PWR_CON,
9748c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9758c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(15, 12),
9768c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
9778c2ecf20Sopenharmony_ci		.caps = MTK_SCPD_ACTIVE_WAKEUP,
9788c2ecf20Sopenharmony_ci	},
9798c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_MFG_ASYNC] = {
9808c2ecf20Sopenharmony_ci		.name = "mfg_async",
9818c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG_ASYNC,
9828c2ecf20Sopenharmony_ci		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
9838c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9848c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = 0,
9858c2ecf20Sopenharmony_ci		.clk_id = {CLK_MFG},
9868c2ecf20Sopenharmony_ci	},
9878c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_MFG_2D] = {
9888c2ecf20Sopenharmony_ci		.name = "mfg_2d",
9898c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG_2D,
9908c2ecf20Sopenharmony_ci		.ctl_offs = SPM_MFG_2D_PWR_CON,
9918c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(11, 8),
9928c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(13, 12),
9938c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
9948c2ecf20Sopenharmony_ci	},
9958c2ecf20Sopenharmony_ci	[MT8173_POWER_DOMAIN_MFG] = {
9968c2ecf20Sopenharmony_ci		.name = "mfg",
9978c2ecf20Sopenharmony_ci		.sta_mask = PWR_STATUS_MFG,
9988c2ecf20Sopenharmony_ci		.ctl_offs = SPM_MFG_PWR_CON,
9998c2ecf20Sopenharmony_ci		.sram_pdn_bits = GENMASK(13, 8),
10008c2ecf20Sopenharmony_ci		.sram_pdn_ack_bits = GENMASK(21, 16),
10018c2ecf20Sopenharmony_ci		.clk_id = {CLK_NONE},
10028c2ecf20Sopenharmony_ci		.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
10038c2ecf20Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MFG_M0 |
10048c2ecf20Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MFG_M1 |
10058c2ecf20Sopenharmony_ci			MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
10068c2ecf20Sopenharmony_ci	},
10078c2ecf20Sopenharmony_ci};
10088c2ecf20Sopenharmony_ci
10098c2ecf20Sopenharmony_cistatic const struct scp_subdomain scp_subdomain_mt8173[] = {
10108c2ecf20Sopenharmony_ci	{MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
10118c2ecf20Sopenharmony_ci	{MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
10128c2ecf20Sopenharmony_ci};
10138c2ecf20Sopenharmony_ci
10148c2ecf20Sopenharmony_cistatic const struct scp_soc_data mt2701_data = {
10158c2ecf20Sopenharmony_ci	.domains = scp_domain_data_mt2701,
10168c2ecf20Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
10178c2ecf20Sopenharmony_ci	.regs = {
10188c2ecf20Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
10198c2ecf20Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
10208c2ecf20Sopenharmony_ci	},
10218c2ecf20Sopenharmony_ci	.bus_prot_reg_update = true,
10228c2ecf20Sopenharmony_ci};
10238c2ecf20Sopenharmony_ci
10248c2ecf20Sopenharmony_cistatic const struct scp_soc_data mt2712_data = {
10258c2ecf20Sopenharmony_ci	.domains = scp_domain_data_mt2712,
10268c2ecf20Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt2712),
10278c2ecf20Sopenharmony_ci	.subdomains = scp_subdomain_mt2712,
10288c2ecf20Sopenharmony_ci	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712),
10298c2ecf20Sopenharmony_ci	.regs = {
10308c2ecf20Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
10318c2ecf20Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
10328c2ecf20Sopenharmony_ci	},
10338c2ecf20Sopenharmony_ci	.bus_prot_reg_update = false,
10348c2ecf20Sopenharmony_ci};
10358c2ecf20Sopenharmony_ci
10368c2ecf20Sopenharmony_cistatic const struct scp_soc_data mt6797_data = {
10378c2ecf20Sopenharmony_ci	.domains = scp_domain_data_mt6797,
10388c2ecf20Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
10398c2ecf20Sopenharmony_ci	.subdomains = scp_subdomain_mt6797,
10408c2ecf20Sopenharmony_ci	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
10418c2ecf20Sopenharmony_ci	.regs = {
10428c2ecf20Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS_MT6797,
10438c2ecf20Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
10448c2ecf20Sopenharmony_ci	},
10458c2ecf20Sopenharmony_ci	.bus_prot_reg_update = true,
10468c2ecf20Sopenharmony_ci};
10478c2ecf20Sopenharmony_ci
10488c2ecf20Sopenharmony_cistatic const struct scp_soc_data mt7622_data = {
10498c2ecf20Sopenharmony_ci	.domains = scp_domain_data_mt7622,
10508c2ecf20Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
10518c2ecf20Sopenharmony_ci	.regs = {
10528c2ecf20Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
10538c2ecf20Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
10548c2ecf20Sopenharmony_ci	},
10558c2ecf20Sopenharmony_ci	.bus_prot_reg_update = true,
10568c2ecf20Sopenharmony_ci};
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_cistatic const struct scp_soc_data mt7623a_data = {
10598c2ecf20Sopenharmony_ci	.domains = scp_domain_data_mt7623a,
10608c2ecf20Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt7623a),
10618c2ecf20Sopenharmony_ci	.regs = {
10628c2ecf20Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
10638c2ecf20Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
10648c2ecf20Sopenharmony_ci	},
10658c2ecf20Sopenharmony_ci	.bus_prot_reg_update = true,
10668c2ecf20Sopenharmony_ci};
10678c2ecf20Sopenharmony_ci
10688c2ecf20Sopenharmony_cistatic const struct scp_soc_data mt8173_data = {
10698c2ecf20Sopenharmony_ci	.domains = scp_domain_data_mt8173,
10708c2ecf20Sopenharmony_ci	.num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
10718c2ecf20Sopenharmony_ci	.subdomains = scp_subdomain_mt8173,
10728c2ecf20Sopenharmony_ci	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
10738c2ecf20Sopenharmony_ci	.regs = {
10748c2ecf20Sopenharmony_ci		.pwr_sta_offs = SPM_PWR_STATUS,
10758c2ecf20Sopenharmony_ci		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
10768c2ecf20Sopenharmony_ci	},
10778c2ecf20Sopenharmony_ci	.bus_prot_reg_update = true,
10788c2ecf20Sopenharmony_ci};
10798c2ecf20Sopenharmony_ci
10808c2ecf20Sopenharmony_ci/*
10818c2ecf20Sopenharmony_ci * scpsys driver init
10828c2ecf20Sopenharmony_ci */
10838c2ecf20Sopenharmony_ci
10848c2ecf20Sopenharmony_cistatic const struct of_device_id of_scpsys_match_tbl[] = {
10858c2ecf20Sopenharmony_ci	{
10868c2ecf20Sopenharmony_ci		.compatible = "mediatek,mt2701-scpsys",
10878c2ecf20Sopenharmony_ci		.data = &mt2701_data,
10888c2ecf20Sopenharmony_ci	}, {
10898c2ecf20Sopenharmony_ci		.compatible = "mediatek,mt2712-scpsys",
10908c2ecf20Sopenharmony_ci		.data = &mt2712_data,
10918c2ecf20Sopenharmony_ci	}, {
10928c2ecf20Sopenharmony_ci		.compatible = "mediatek,mt6797-scpsys",
10938c2ecf20Sopenharmony_ci		.data = &mt6797_data,
10948c2ecf20Sopenharmony_ci	}, {
10958c2ecf20Sopenharmony_ci		.compatible = "mediatek,mt7622-scpsys",
10968c2ecf20Sopenharmony_ci		.data = &mt7622_data,
10978c2ecf20Sopenharmony_ci	}, {
10988c2ecf20Sopenharmony_ci		.compatible = "mediatek,mt7623a-scpsys",
10998c2ecf20Sopenharmony_ci		.data = &mt7623a_data,
11008c2ecf20Sopenharmony_ci	}, {
11018c2ecf20Sopenharmony_ci		.compatible = "mediatek,mt8173-scpsys",
11028c2ecf20Sopenharmony_ci		.data = &mt8173_data,
11038c2ecf20Sopenharmony_ci	}, {
11048c2ecf20Sopenharmony_ci		/* sentinel */
11058c2ecf20Sopenharmony_ci	}
11068c2ecf20Sopenharmony_ci};
11078c2ecf20Sopenharmony_ci
11088c2ecf20Sopenharmony_cistatic int scpsys_probe(struct platform_device *pdev)
11098c2ecf20Sopenharmony_ci{
11108c2ecf20Sopenharmony_ci	const struct scp_subdomain *sd;
11118c2ecf20Sopenharmony_ci	const struct scp_soc_data *soc;
11128c2ecf20Sopenharmony_ci	struct scp *scp;
11138c2ecf20Sopenharmony_ci	struct genpd_onecell_data *pd_data;
11148c2ecf20Sopenharmony_ci	int i, ret;
11158c2ecf20Sopenharmony_ci
11168c2ecf20Sopenharmony_ci	soc = of_device_get_match_data(&pdev->dev);
11178c2ecf20Sopenharmony_ci
11188c2ecf20Sopenharmony_ci	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
11198c2ecf20Sopenharmony_ci			soc->bus_prot_reg_update);
11208c2ecf20Sopenharmony_ci	if (IS_ERR(scp))
11218c2ecf20Sopenharmony_ci		return PTR_ERR(scp);
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci	mtk_register_power_domains(pdev, scp, soc->num_domains);
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_ci	pd_data = &scp->pd_data;
11268c2ecf20Sopenharmony_ci
11278c2ecf20Sopenharmony_ci	for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) {
11288c2ecf20Sopenharmony_ci		ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
11298c2ecf20Sopenharmony_ci					     pd_data->domains[sd->subdomain]);
11308c2ecf20Sopenharmony_ci		if (ret && IS_ENABLED(CONFIG_PM))
11318c2ecf20Sopenharmony_ci			dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
11328c2ecf20Sopenharmony_ci				ret);
11338c2ecf20Sopenharmony_ci	}
11348c2ecf20Sopenharmony_ci
11358c2ecf20Sopenharmony_ci	return 0;
11368c2ecf20Sopenharmony_ci}
11378c2ecf20Sopenharmony_ci
11388c2ecf20Sopenharmony_cistatic struct platform_driver scpsys_drv = {
11398c2ecf20Sopenharmony_ci	.probe = scpsys_probe,
11408c2ecf20Sopenharmony_ci	.driver = {
11418c2ecf20Sopenharmony_ci		.name = "mtk-scpsys",
11428c2ecf20Sopenharmony_ci		.suppress_bind_attrs = true,
11438c2ecf20Sopenharmony_ci		.owner = THIS_MODULE,
11448c2ecf20Sopenharmony_ci		.of_match_table = of_match_ptr(of_scpsys_match_tbl),
11458c2ecf20Sopenharmony_ci	},
11468c2ecf20Sopenharmony_ci};
11478c2ecf20Sopenharmony_cibuiltin_platform_driver(scpsys_drv);
1148