Linux-mediatek Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain
@ 2025-03-07  3:44 Guangjie Song
  2025-03-07  3:44 ` [PATCH 01/13] pmdomain: mediatek: Support sram isolation Guangjie Song
                   ` (13 more replies)
  0 siblings, 14 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

This series is based on linux-next, tag: next-20250306.

Changes:
- Update mtk-scpsys driver for MT8196
- Add MT8196 power domain support

Guangjie Song (13):
  pmdomain: mediatek: Support sram isolation
  pmdomain: mediatek: Support sram low power
  pmdomain: mediatek: Support power on bypass
  pmdomain: mediatek: Support check power on/off ack
  pmdomain: mediatek: Support voting for power domain
  pmdomain: mediatek: Support trigger subsys save/restore regesters
  pmdomain: mediatek: Support power domain irq safe
  pmdomain: mediatek: Support power domain always on
  pmdomain: mediatek: Refactor parameters of init_scp
  pmdomain: mediatek: Support bus protect with table
  pmdomain: mediatek: Add post init callback
  dt-bindings: power: mediatek: Add new MT8196 power domain
  pmdomain: mediatek: Add MT8196 power domain support

 .../mediatek,mt8196-power-controller.yaml     |   74 +
 drivers/pmdomain/mediatek/mt8196-scpsys.h     |  114 ++
 drivers/pmdomain/mediatek/mtk-scpsys.c        | 1276 ++++++++++++++++-
 include/dt-bindings/power/mt8196-power.h      |   57 +
 4 files changed, 1483 insertions(+), 38 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
 create mode 100644 drivers/pmdomain/mediatek/mt8196-scpsys.h
 create mode 100644 include/dt-bindings/power/mt8196-power.h

-- 
2.45.2



^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/13] pmdomain: mediatek: Support sram isolation
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 02/13] pmdomain: mediatek: Support sram low power Guangjie Song
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support sram isolation to isolate signals and prevent current leakage.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 1a80c1537a43..d53bd07a6804 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -25,6 +25,7 @@
 
 #define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
 #define MTK_SCPD_FWAIT_SRAM		BIT(1)
+#define MTK_SCPD_SRAM_ISO		BIT(2)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -56,6 +57,8 @@
 #define PWR_ON_BIT			BIT(2)
 #define PWR_ON_2ND_BIT			BIT(3)
 #define PWR_CLK_DIS_BIT			BIT(4)
+#define PWR_SRAM_CLKISO_BIT		BIT(5)
+#define PWR_SRAM_ISOINT_B_BIT		BIT(6)
 
 #define PWR_STATUS_CONN			BIT(1)
 #define PWR_STATUS_DISP			BIT(3)
@@ -257,6 +260,14 @@ static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
 			return ret;
 	}
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) {
+		val = readl(ctl_addr) | PWR_SRAM_ISOINT_B_BIT;
+		writel(val, ctl_addr);
+		udelay(1);
+		val &= ~PWR_SRAM_CLKISO_BIT;
+		writel(val, ctl_addr);
+	}
+
 	return 0;
 }
 
@@ -266,6 +277,14 @@ static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
 	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
 	int tmp;
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) {
+		val = readl(ctl_addr) | PWR_SRAM_CLKISO_BIT;
+		writel(val, ctl_addr);
+		val &= ~PWR_SRAM_ISOINT_B_BIT;
+		writel(val, ctl_addr);
+		udelay(1);
+	}
+
 	val = readl(ctl_addr);
 	val |= scpd->data->sram_pdn_bits;
 	writel(val, ctl_addr);
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 02/13] pmdomain: mediatek: Support sram low power
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
  2025-03-07  3:44 ` [PATCH 01/13] pmdomain: mediatek: Support sram isolation Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 03/13] pmdomain: mediatek: Support power on bypass Guangjie Song
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support sram enter/exit low power mode.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 36 ++++++++++++++++++++------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index d53bd07a6804..9d03249284d6 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -26,6 +26,7 @@
 #define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
 #define MTK_SCPD_FWAIT_SRAM		BIT(1)
 #define MTK_SCPD_SRAM_ISO		BIT(2)
+#define MTK_SCPD_SRAM_SLP		BIT(3)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -118,6 +119,8 @@ static const char * const clk_names[] = {
  * @ctl_offs: The offset for main power control register.
  * @sram_pdn_bits: The mask for sram power control bits.
  * @sram_pdn_ack_bits: The mask for sram power control acked bits.
+ * @sram_slp_bits: The mask for sram low power control bits.
+ * @sram_slp_ack_bits: The mask for sram low power control acked bits.
  * @bus_prot_mask: The mask for single step bus protection.
  * @clk_id: The basic clocks required by this power domain.
  * @caps: The flag for active wake-up action.
@@ -128,6 +131,8 @@ struct scp_domain_data {
 	int ctl_offs;
 	u32 sram_pdn_bits;
 	u32 sram_pdn_ack_bits;
+	u32 sram_slp_bits;
+	u32 sram_slp_ack_bits;
 	u32 bus_prot_mask;
 	enum clk_id clk_id[MAX_CLKS];
 	u8 caps;
@@ -236,11 +241,19 @@ static int scpsys_clk_enable(struct clk *clk[], int max_num)
 static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
 {
 	u32 val;
-	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
+	u32 ack_mask, ack_sta;
 	int tmp;
 
-	val = readl(ctl_addr);
-	val &= ~scpd->data->sram_pdn_bits;
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_SLP)) {
+		ack_mask = scpd->data->sram_slp_ack_bits;
+		ack_sta = ack_mask;
+		val = readl(ctl_addr) | scpd->data->sram_slp_bits;
+	} else {
+		ack_mask = scpd->data->sram_pdn_ack_bits;
+		ack_sta = 0;
+		val = readl(ctl_addr) & ~scpd->data->sram_pdn_bits;
+	}
+
 	writel(val, ctl_addr);
 
 	/* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
@@ -254,7 +267,7 @@ static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
 	} else {
 		/* Either wait until SRAM_PDN_ACK all 1 or 0 */
 		int ret = readl_poll_timeout(ctl_addr, tmp,
-				(tmp & pdn_ack) == 0,
+				(tmp & ack_mask) == ack_sta,
 				MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 		if (ret < 0)
 			return ret;
@@ -274,7 +287,7 @@ static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
 static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
 {
 	u32 val;
-	u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
+	u32 ack_mask, ack_sta;
 	int tmp;
 
 	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) {
@@ -285,13 +298,20 @@ static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
 		udelay(1);
 	}
 
-	val = readl(ctl_addr);
-	val |= scpd->data->sram_pdn_bits;
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_SLP)) {
+		ack_mask = scpd->data->sram_slp_ack_bits;
+		ack_sta = 0;
+		val = readl(ctl_addr) & ~scpd->data->sram_slp_bits;
+	} else {
+		ack_mask = scpd->data->sram_pdn_ack_bits;
+		ack_sta = ack_mask;
+		val = readl(ctl_addr) | scpd->data->sram_pdn_bits;
+	}
 	writel(val, ctl_addr);
 
 	/* Either wait until SRAM_PDN_ACK all 1 or 0 */
 	return readl_poll_timeout(ctl_addr, tmp,
-			(tmp & pdn_ack) == pdn_ack,
+			(tmp & ack_mask) == ack_sta,
 			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 }
 
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 03/13] pmdomain: mediatek: Support power on bypass
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
  2025-03-07  3:44 ` [PATCH 01/13] pmdomain: mediatek: Support sram isolation Guangjie Song
  2025-03-07  3:44 ` [PATCH 02/13] pmdomain: mediatek: Support sram low power Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 04/13] pmdomain: mediatek: Support check power on/off ack Guangjie Song
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support power on bypass in pmdomain driver probe.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 9d03249284d6..3c8b5d8e7ee9 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -27,6 +27,7 @@
 #define MTK_SCPD_FWAIT_SRAM		BIT(1)
 #define MTK_SCPD_SRAM_ISO		BIT(2)
 #define MTK_SCPD_SRAM_SLP		BIT(3)
+#define MTK_SCPD_BYPASS_INIT_ON		BIT(4)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -569,7 +570,10 @@ static void mtk_register_power_domains(struct platform_device *pdev,
 		 * software.  The unused domains will be switched off during
 		 * late_init time.
 		 */
-		on = !WARN_ON(genpd->power_on(genpd) < 0);
+		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_BYPASS_INIT_ON))
+			on = false;
+		else
+			on = !WARN_ON(genpd->power_on(genpd) < 0);
 
 		pm_genpd_init(genpd, NULL, !on);
 	}
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 04/13] pmdomain: mediatek: Support check power on/off ack
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (2 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 03/13] pmdomain: mediatek: Support power on bypass Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 05/13] pmdomain: mediatek: Support voting for power domain Guangjie Song
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support check ack bits for pmdomain on/off.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 50 +++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 3c8b5d8e7ee9..2f75c606f7ba 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -22,12 +22,14 @@
 
 #define MTK_POLL_DELAY_US   10
 #define MTK_POLL_TIMEOUT    USEC_PER_SEC
+#define MTK_ACK_DELAY_US		50
 
 #define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
 #define MTK_SCPD_FWAIT_SRAM		BIT(1)
 #define MTK_SCPD_SRAM_ISO		BIT(2)
 #define MTK_SCPD_SRAM_SLP		BIT(3)
 #define MTK_SCPD_BYPASS_INIT_ON		BIT(4)
+#define MTK_SCPD_IS_PWR_CON_ON		BIT(5)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -61,6 +63,8 @@
 #define PWR_CLK_DIS_BIT			BIT(4)
 #define PWR_SRAM_CLKISO_BIT		BIT(5)
 #define PWR_SRAM_ISOINT_B_BIT		BIT(6)
+#define PWR_ACK				BIT(30)
+#define PWR_ACK_2ND			BIT(31)
 
 #define PWR_STATUS_CONN			BIT(1)
 #define PWR_STATUS_DISP			BIT(3)
@@ -200,6 +204,20 @@ static int scpsys_domain_is_on(struct scp_domain *scpd)
 	return -EINVAL;
 }
 
+static int scpsys_pwr_ack_is_on(struct scp_domain *scpd)
+{
+	u32 status = readl(scpd->scp->base + scpd->data->ctl_offs) & PWR_ACK;
+
+	return status ? true : false;
+}
+
+static int scpsys_pwr_ack_2nd_is_on(struct scp_domain *scpd)
+{
+	u32 status = readl(scpd->scp->base + scpd->data->ctl_offs) & PWR_ACK_2ND;
+
+	return status ? true : false;
+}
+
 static int scpsys_regulator_enable(struct scp_domain *scpd)
 {
 	if (!scpd->supply)
@@ -360,12 +378,25 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	val = readl(ctl_addr);
 	val |= PWR_ON_BIT;
 	writel(val, ctl_addr);
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON)) {
+		ret = readx_poll_timeout_atomic(scpsys_pwr_ack_is_on, scpd, tmp, tmp > 0,
+						MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+		if (ret < 0)
+			goto err_pwr_ack;
+
+		udelay(MTK_ACK_DELAY_US);
+	}
+
 	val |= PWR_ON_2ND_BIT;
 	writel(val, ctl_addr);
 
 	/* wait until PWR_ACK = 1 */
-	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
-				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON))
+		ret = readx_poll_timeout_atomic(scpsys_pwr_ack_2nd_is_on, scpd, tmp, tmp > 0,
+						MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	else
+		ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
+					 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 	if (ret < 0)
 		goto err_pwr_ack;
 
@@ -428,12 +459,23 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	val &= ~PWR_ON_BIT;
 	writel(val, ctl_addr);
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON)) {
+		ret = readx_poll_timeout_atomic(scpsys_pwr_ack_is_on, scpd, tmp, tmp == 0,
+						MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+		if (ret < 0)
+			goto out;
+	}
+
 	val &= ~PWR_ON_2ND_BIT;
 	writel(val, ctl_addr);
 
 	/* wait until PWR_ACK = 0 */
-	ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
-				 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IS_PWR_CON_ON))
+		ret = readx_poll_timeout_atomic(scpsys_pwr_ack_2nd_is_on, scpd, tmp, tmp == 0,
+						MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	else
+		ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
+					 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 	if (ret < 0)
 		goto out;
 
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 05/13] pmdomain: mediatek: Support voting for power domain
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (3 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 04/13] pmdomain: mediatek: Support check power on/off ack Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 06/13] pmdomain: mediatek: Support trigger subsys save/restore regesters Guangjie Song
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Power domain supports voting mechanism. If any xPU votes power domain
on, the power domain keep on.
Add power domain vote support.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 207 ++++++++++++++++++++++++-
 1 file changed, 205 insertions(+), 2 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 2f75c606f7ba..df9cd012006c 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -10,6 +10,7 @@
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/soc/mediatek/infracfg.h>
 
@@ -22,7 +23,12 @@
 
 #define MTK_POLL_DELAY_US   10
 #define MTK_POLL_TIMEOUT    USEC_PER_SEC
+#define MTK_POLL_TIMEOUT_300MS		(300 * USEC_PER_MSEC)
+#define MTK_POLL_IRQ_TIMEOUT		USEC_PER_SEC
+#define MTK_POLL_VOTE_PREPARE_CNT	2500
+#define MTK_POLL_VOTE_PREPARE_US	2
 #define MTK_ACK_DELAY_US		50
+#define MTK_STABLE_DELAY_US		100
 
 #define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
 #define MTK_SCPD_FWAIT_SRAM		BIT(1)
@@ -30,6 +36,7 @@
 #define MTK_SCPD_SRAM_SLP		BIT(3)
 #define MTK_SCPD_BYPASS_INIT_ON		BIT(4)
 #define MTK_SCPD_IS_PWR_CON_ON		BIT(5)
+#define MTK_SCPD_VOTE_OPS		BIT(6)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -120,8 +127,18 @@ static const char * const clk_names[] = {
 /**
  * struct scp_domain_data - scp domain data for power on/off flow
  * @name: The domain name.
+ * @vote_comp: The vote name.
  * @sta_mask: The mask for power on/off status bit.
  * @ctl_offs: The offset for main power control register.
+ * @vote_done_ofs: The offset for vote done register.
+ * @vote_ofs: The offset for vote register.
+ * @vote_set_ofs: The offset for vote set register.
+ * @vote_clr_ofs: The offset for vote clear register.
+ * @vote_en_ofs: The offset for voted register.
+ * @vote_set_sta_ofs: The offset for vote set status register.
+ * @vote_clr_sta_ofs: The offset for vote clear status register.
+ * @vote_ack_ofs: The offset for power control ack register.
+ * @vote_shift: The bit of vote.
  * @sram_pdn_bits: The mask for sram power control bits.
  * @sram_pdn_ack_bits: The mask for sram power control acked bits.
  * @sram_slp_bits: The mask for sram low power control bits.
@@ -132,8 +149,18 @@ static const char * const clk_names[] = {
  */
 struct scp_domain_data {
 	const char *name;
+	const char *vote_comp;
 	u32 sta_mask;
 	int ctl_offs;
+	u32 vote_done_ofs;
+	u32 vote_ofs;
+	u32 vote_set_ofs;
+	u32 vote_clr_ofs;
+	u32 vote_en_ofs;
+	u32 vote_set_sta_ofs;
+	u32 vote_clr_sta_ofs;
+	u32 vote_ack_ofs;
+	u8 vote_shift;
 	u32 sram_pdn_bits;
 	u32 sram_pdn_ack_bits;
 	u32 sram_slp_bits;
@@ -151,6 +178,7 @@ struct scp_domain {
 	struct clk *clk[MAX_CLKS];
 	const struct scp_domain_data *data;
 	struct regulator *supply;
+	struct regmap *vote_regmap;
 };
 
 struct scp_ctrl_reg {
@@ -493,6 +521,154 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	return ret;
 }
 
+static int mtk_vote_is_done(struct scp_domain *scpd)
+{
+	u32 val = 0, mask = 0;
+
+	regmap_read(scpd->vote_regmap, scpd->data->vote_done_ofs, &val);
+	mask = BIT(scpd->data->vote_shift);
+	if ((val & mask) == mask)
+		return 1;
+
+	return 0;
+}
+
+static int mtk_vote_is_enable_done(struct scp_domain *scpd)
+{
+	u32 done = 0, en = 0, set_sta = 0, mask = 0, ack = 0;
+
+	regmap_read(scpd->vote_regmap, scpd->data->vote_done_ofs, &done);
+	regmap_read(scpd->vote_regmap, scpd->data->vote_en_ofs, &en);
+	regmap_read(scpd->vote_regmap, scpd->data->vote_set_sta_ofs, &set_sta);
+	mask = BIT(scpd->data->vote_shift);
+
+	if ((done & mask) && (en & mask) && !(set_sta & mask)) {
+		if (scpd->data->vote_ack_ofs) {
+			regmap_read(scpd->vote_regmap, scpd->data->vote_ack_ofs, &ack);
+			if (!(ack & mask))
+				return 0;
+		}
+
+		return 1;
+	}
+
+	return 0;
+}
+
+static int mtk_vote_is_disable_done(struct scp_domain *scpd)
+{
+	u32 val = 0, val2 = 0;
+
+	regmap_read(scpd->vote_regmap, scpd->data->vote_done_ofs, &val);
+	regmap_read(scpd->vote_regmap, scpd->data->vote_clr_sta_ofs, &val2);
+
+	if ((val & BIT(scpd->data->vote_shift)) &&
+	    ((val2 & BIT(scpd->data->vote_shift)) == 0x0))
+		return 1;
+
+	return 0;
+}
+
+static int scpsys_vote_power_on(struct generic_pm_domain *genpd)
+{
+	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
+	struct scp *scp = scpd->scp;
+	u32 val = 0;
+	int ret = 0;
+	int tmp;
+	int i = 0;
+
+	ret = scpsys_regulator_enable(scpd);
+	if (ret < 0)
+		goto out;
+
+	ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
+	if (ret)
+		goto out;
+
+	ret = readx_poll_timeout_atomic(mtk_vote_is_done, scpd, tmp, tmp > 0,
+					MTK_POLL_DELAY_US, MTK_POLL_IRQ_TIMEOUT);
+	if (ret < 0)
+		goto out;
+
+	val = BIT(scpd->data->vote_shift);
+	regmap_write(scpd->vote_regmap, scpd->data->vote_set_ofs, val);
+	do {
+		regmap_read(scpd->vote_regmap, scpd->data->vote_set_ofs, &val);
+		if ((val & BIT(scpd->data->vote_shift)) != 0)
+			break;
+
+		if (i > MTK_POLL_VOTE_PREPARE_CNT)
+			goto out;
+
+		udelay(MTK_POLL_VOTE_PREPARE_US);
+		i++;
+	} while (1);
+
+	/* add debounce time */
+	udelay(1);
+
+	/* wait until VOTER_ACK = 1 */
+	ret = readx_poll_timeout_atomic(mtk_vote_is_enable_done, scpd, tmp, tmp > 0,
+					MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT_300MS);
+	if (ret < 0)
+		goto out;
+
+	return 0;
+out:
+	dev_err(scp->dev, "Failed to power on domain %s(%d)\n", genpd->name, ret);
+	return ret;
+}
+
+static int scpsys_vote_power_off(struct generic_pm_domain *genpd)
+{
+	struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
+	struct scp *scp = scpd->scp;
+	u32 val = 0;
+	int ret = 0;
+	int tmp;
+	int i = 0;
+
+	ret = readx_poll_timeout_atomic(mtk_vote_is_done, scpd, tmp, tmp > 0,
+					MTK_POLL_DELAY_US, MTK_POLL_IRQ_TIMEOUT);
+	if (ret < 0)
+		goto out;
+
+	val = BIT(scpd->data->vote_shift);
+	regmap_write(scpd->vote_regmap, scpd->data->vote_clr_ofs, val);
+	do {
+		regmap_read(scpd->vote_regmap, scpd->data->vote_clr_ofs, &val);
+		if ((val & BIT(scpd->data->vote_shift)) == 0)
+			break;
+
+		if (i > MTK_POLL_VOTE_PREPARE_CNT)
+			goto out;
+
+		i++;
+		udelay(MTK_POLL_VOTE_PREPARE_US);
+	} while (1);
+
+	/* delay 100us for stable status */
+	udelay(MTK_STABLE_DELAY_US);
+
+	/* wait until VOTER_ACK = 0 */
+	ret = readx_poll_timeout_atomic(mtk_vote_is_disable_done, scpd, tmp, tmp > 0,
+					MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT_300MS);
+	if (ret < 0)
+		goto out;
+
+	scpsys_clk_disable(scpd->clk, MAX_CLKS);
+
+	ret = scpsys_regulator_disable(scpd);
+	if (ret < 0)
+		goto out;
+
+	return 0;
+out:
+	dev_err(scp->dev, "Failed to power off domain %s(%d)\n", genpd->name, ret);
+	return ret;
+}
+
 static void init_clks(struct platform_device *pdev, struct clk **clk)
 {
 	int i;
@@ -501,6 +677,21 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
 		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
 }
 
+static int mtk_pd_get_regmap(struct platform_device *pdev, struct regmap **regmap,
+			     const char *name)
+{
+	*regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, name);
+	if (PTR_ERR(*regmap) == -ENODEV) {
+		dev_notice(&pdev->dev, "%s regmap is null(%ld)\n", name, PTR_ERR(*regmap));
+		*regmap = NULL;
+	} else if (IS_ERR(*regmap)) {
+		dev_notice(&pdev->dev, "Cannot find %s controller: %ld\n", name, PTR_ERR(*regmap));
+		return PTR_ERR(*regmap);
+	}
+
+	return 0;
+}
+
 static struct scp *init_scp(struct platform_device *pdev,
 			const struct scp_domain_data *scp_domain_data, int num,
 			const struct scp_ctrl_reg *scp_ctrl_reg,
@@ -510,6 +701,7 @@ static struct scp *init_scp(struct platform_device *pdev,
 	int i, j;
 	struct scp *scp;
 	struct clk *clk[CLK_MAX];
+	int ret;
 
 	scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
 	if (!scp)
@@ -585,9 +777,20 @@ static struct scp *init_scp(struct platform_device *pdev,
 			scpd->clk[j] = c;
 		}
 
+		if (data->vote_comp) {
+			ret = mtk_pd_get_regmap(pdev, &scpd->vote_regmap, data->vote_comp);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+
 		genpd->name = data->name;
-		genpd->power_off = scpsys_power_off;
-		genpd->power_on = scpsys_power_on;
+		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_VOTE_OPS)) {
+			genpd->power_on = scpsys_vote_power_on;
+			genpd->power_off = scpsys_vote_power_off;
+		} else {
+			genpd->power_off = scpsys_power_off;
+			genpd->power_on = scpsys_power_on;
+		}
 		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
 			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
 	}
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 06/13] pmdomain: mediatek: Support trigger subsys save/restore regesters
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (4 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 05/13] pmdomain: mediatek: Support voting for power domain Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 07/13] pmdomain: mediatek: Support power domain irq safe Guangjie Song
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support trigger subsys save/restore registers during power domain
on/off.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 106 ++++++++++++++++++++++++-
 1 file changed, 105 insertions(+), 1 deletion(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index df9cd012006c..0ae4c617b5a6 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -28,6 +28,7 @@
 #define MTK_POLL_VOTE_PREPARE_CNT	2500
 #define MTK_POLL_VOTE_PREPARE_US	2
 #define MTK_ACK_DELAY_US		50
+#define MTK_RTFF_DELAY_US		10
 #define MTK_STABLE_DELAY_US		100
 
 #define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
@@ -37,6 +38,10 @@
 #define MTK_SCPD_BYPASS_INIT_ON		BIT(4)
 #define MTK_SCPD_IS_PWR_CON_ON		BIT(5)
 #define MTK_SCPD_VOTE_OPS		BIT(6)
+#define MTK_SCPD_NON_CPU_RTFF		BIT(7)
+#define MTK_SCPD_PEXTP_PHY_RTFF		BIT(8)
+#define MTK_SCPD_UFS_RTFF		BIT(9)
+#define MTK_SCPD_RTFF_DELAY		BIT(10)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -70,6 +75,11 @@
 #define PWR_CLK_DIS_BIT			BIT(4)
 #define PWR_SRAM_CLKISO_BIT		BIT(5)
 #define PWR_SRAM_ISOINT_B_BIT		BIT(6)
+#define PWR_RTFF_SAVE			BIT(24)
+#define PWR_RTFF_NRESTORE		BIT(25)
+#define PWR_RTFF_CLK_DIS		BIT(26)
+#define PWR_RTFF_SAVE_FLAG		BIT(27)
+#define PWR_RTFF_UFS_CLK_DIS		BIT(28)
 #define PWR_ACK				BIT(30)
 #define PWR_ACK_2ND			BIT(31)
 
@@ -167,7 +177,7 @@ struct scp_domain_data {
 	u32 sram_slp_ack_bits;
 	u32 bus_prot_mask;
 	enum clk_id clk_id[MAX_CLKS];
-	u8 caps;
+	u32 caps;
 };
 
 struct scp;
@@ -179,6 +189,7 @@ struct scp_domain {
 	const struct scp_domain_data *data;
 	struct regulator *supply;
 	struct regmap *vote_regmap;
+	bool rtff_flag;
 };
 
 struct scp_ctrl_reg {
@@ -428,15 +439,72 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	if (ret < 0)
 		goto err_pwr_ack;
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_PEXTP_PHY_RTFF) && scpd->rtff_flag) {
+		val |= PWR_RTFF_CLK_DIS;
+		writel(val, ctl_addr);
+	}
+
 	val &= ~PWR_CLK_DIS_BIT;
 	writel(val, ctl_addr);
 
 	val &= ~PWR_ISO_BIT;
 	writel(val, ctl_addr);
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_RTFF_DELAY) && scpd->rtff_flag)
+		udelay(MTK_RTFF_DELAY_US);
+
 	val |= PWR_RST_B_BIT;
 	writel(val, ctl_addr);
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_NON_CPU_RTFF)) {
+		val = readl(ctl_addr);
+		if (val & PWR_RTFF_SAVE_FLAG) {
+			val &= ~PWR_RTFF_SAVE_FLAG;
+			writel(val, ctl_addr);
+
+			val |= PWR_RTFF_CLK_DIS;
+			writel(val, ctl_addr);
+
+			val &= ~PWR_RTFF_NRESTORE;
+			writel(val, ctl_addr);
+
+			val |= PWR_RTFF_NRESTORE;
+			writel(val, ctl_addr);
+
+			val &= ~PWR_RTFF_CLK_DIS;
+			writel(val, ctl_addr);
+		}
+	} else if (MTK_SCPD_CAPS(scpd, MTK_SCPD_PEXTP_PHY_RTFF)) {
+		val = readl(ctl_addr);
+		if (val & PWR_RTFF_SAVE_FLAG) {
+			val &= ~PWR_RTFF_SAVE_FLAG;
+			writel(val, ctl_addr);
+
+			val &= ~PWR_RTFF_NRESTORE;
+			writel(val, ctl_addr);
+
+			val |= PWR_RTFF_NRESTORE;
+			writel(val, ctl_addr);
+
+			val &= ~PWR_RTFF_CLK_DIS;
+			writel(val, ctl_addr);
+		}
+	} else if (MTK_SCPD_CAPS(scpd, MTK_SCPD_UFS_RTFF) && scpd->rtff_flag) {
+		val |= PWR_RTFF_UFS_CLK_DIS;
+		writel(val, ctl_addr);
+
+		val &= ~PWR_RTFF_NRESTORE;
+		writel(val, ctl_addr);
+
+		val |= PWR_RTFF_NRESTORE;
+		writel(val, ctl_addr);
+
+		val &= ~PWR_RTFF_UFS_CLK_DIS;
+		writel(val, ctl_addr);
+
+		scpd->rtff_flag = false;
+	}
+
 	ret = scpsys_sram_enable(scpd, ctl_addr);
 	if (ret < 0)
 		goto err_pwr_ack;
@@ -475,9 +543,45 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 
 	/* subsys power off */
 	val = readl(ctl_addr);
+
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_NON_CPU_RTFF) ||
+	    MTK_SCPD_CAPS(scpd, MTK_SCPD_PEXTP_PHY_RTFF)) {
+		val |= PWR_RTFF_CLK_DIS;
+		writel(val, ctl_addr);
+
+		val |= PWR_RTFF_SAVE;
+		writel(val, ctl_addr);
+
+		val &= ~PWR_RTFF_SAVE;
+		writel(val, ctl_addr);
+
+		val &= ~PWR_RTFF_CLK_DIS;
+		writel(val, ctl_addr);
+
+		val |= PWR_RTFF_SAVE_FLAG;
+		writel(val, ctl_addr);
+	} else if (MTK_SCPD_CAPS(scpd, MTK_SCPD_UFS_RTFF)) {
+		val |= PWR_RTFF_UFS_CLK_DIS;
+		writel(val, ctl_addr);
+
+		val |= PWR_RTFF_SAVE;
+		writel(val, ctl_addr);
+
+		val &= ~PWR_RTFF_SAVE;
+		writel(val, ctl_addr);
+
+		val &= ~PWR_RTFF_UFS_CLK_DIS;
+		writel(val, ctl_addr);
+		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_UFS_RTFF))
+			scpd->rtff_flag = true;
+	}
+
 	val |= PWR_ISO_BIT;
 	writel(val, ctl_addr);
 
+	if (MTK_SCPD_CAPS(scpd, MTK_SCPD_RTFF_DELAY) && scpd->rtff_flag)
+		udelay(1);
+
 	val &= ~PWR_RST_B_BIT;
 	writel(val, ctl_addr);
 
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 07/13] pmdomain: mediatek: Support power domain irq safe
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (5 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 06/13] pmdomain: mediatek: Support trigger subsys save/restore regesters Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 08/13] pmdomain: mediatek: Support power domain always on Guangjie Song
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support power domain is irq safe with MTK_SCPD_IRQ_SAFE.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 0ae4c617b5a6..467c54e24bea 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -42,6 +42,7 @@
 #define MTK_SCPD_PEXTP_PHY_RTFF		BIT(8)
 #define MTK_SCPD_UFS_RTFF		BIT(9)
 #define MTK_SCPD_RTFF_DELAY		BIT(10)
+#define MTK_SCPD_IRQ_SAFE		BIT(11)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -897,6 +898,8 @@ static struct scp *init_scp(struct platform_device *pdev,
 		}
 		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
 			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IRQ_SAFE))
+			genpd->flags |= GENPD_FLAG_IRQ_SAFE;
 	}
 
 	return scp;
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 08/13] pmdomain: mediatek: Support power domain always on
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (6 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 07/13] pmdomain: mediatek: Support power domain irq safe Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 09/13] pmdomain: mediatek: Refactor parameters of init_scp Guangjie Song
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support power domain always on with MTK_SCPD_ALWAYS_ON.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 467c54e24bea..f0a5e1653b5f 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -43,6 +43,7 @@
 #define MTK_SCPD_UFS_RTFF		BIT(9)
 #define MTK_SCPD_RTFF_DELAY		BIT(10)
 #define MTK_SCPD_IRQ_SAFE		BIT(11)
+#define MTK_SCPD_ALWAYS_ON		BIT(12)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
@@ -900,6 +901,8 @@ static struct scp *init_scp(struct platform_device *pdev,
 			genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
 		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_IRQ_SAFE))
 			genpd->flags |= GENPD_FLAG_IRQ_SAFE;
+		if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ALWAYS_ON))
+			genpd->flags |= GENPD_FLAG_ALWAYS_ON;
 	}
 
 	return scp;
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 09/13] pmdomain: mediatek: Refactor parameters of init_scp
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (7 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 08/13] pmdomain: mediatek: Support power domain always on Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 10/13] pmdomain: mediatek: Support bus protect with table Guangjie Song
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Refactor parameters of init_scp which will use other fields of soc data.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 28 +++++++++++---------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index f0a5e1653b5f..47d5d5abcaee 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -798,10 +798,7 @@ static int mtk_pd_get_regmap(struct platform_device *pdev, struct regmap **regma
 	return 0;
 }
 
-static struct scp *init_scp(struct platform_device *pdev,
-			const struct scp_domain_data *scp_domain_data, int num,
-			const struct scp_ctrl_reg *scp_ctrl_reg,
-			bool bus_prot_reg_update)
+static struct scp *init_scp(struct platform_device *pdev, const struct scp_soc_data *soc)
 {
 	struct genpd_onecell_data *pd_data;
 	int i, j;
@@ -813,10 +810,10 @@ static struct scp *init_scp(struct platform_device *pdev,
 	if (!scp)
 		return ERR_PTR(-ENOMEM);
 
-	scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
-	scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
+	scp->ctrl_reg.pwr_sta_offs = soc->regs.pwr_sta_offs;
+	scp->ctrl_reg.pwr_sta2nd_offs = soc->regs.pwr_sta2nd_offs;
 
-	scp->bus_prot_reg_update = bus_prot_reg_update;
+	scp->bus_prot_reg_update = soc->bus_prot_reg_update;
 
 	scp->dev = &pdev->dev;
 
@@ -825,14 +822,14 @@ static struct scp *init_scp(struct platform_device *pdev,
 		return ERR_CAST(scp->base);
 
 	scp->domains = devm_kcalloc(&pdev->dev,
-				num, sizeof(*scp->domains), GFP_KERNEL);
+				soc->num_domains, sizeof(*scp->domains), GFP_KERNEL);
 	if (!scp->domains)
 		return ERR_PTR(-ENOMEM);
 
 	pd_data = &scp->pd_data;
 
 	pd_data->domains = devm_kcalloc(&pdev->dev,
-			num, sizeof(*pd_data->domains), GFP_KERNEL);
+			soc->num_domains, sizeof(*pd_data->domains), GFP_KERNEL);
 	if (!pd_data->domains)
 		return ERR_PTR(-ENOMEM);
 
@@ -844,9 +841,9 @@ static struct scp *init_scp(struct platform_device *pdev,
 		return ERR_CAST(scp->infracfg);
 	}
 
-	for (i = 0; i < num; i++) {
+	for (i = 0; i < soc->num_domains; i++) {
 		struct scp_domain *scpd = &scp->domains[i];
-		const struct scp_domain_data *data = &scp_domain_data[i];
+		const struct scp_domain_data *data = &soc->domains[i];
 
 		scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
 		if (IS_ERR(scpd->supply)) {
@@ -857,14 +854,14 @@ static struct scp *init_scp(struct platform_device *pdev,
 		}
 	}
 
-	pd_data->num_domains = num;
+	pd_data->num_domains = soc->num_domains;
 
 	init_clks(pdev, clk);
 
-	for (i = 0; i < num; i++) {
+	for (i = 0; i < soc->num_domains; i++) {
 		struct scp_domain *scpd = &scp->domains[i];
 		struct generic_pm_domain *genpd = &scpd->genpd;
-		const struct scp_domain_data *data = &scp_domain_data[i];
+		const struct scp_domain_data *data = &soc->domains[i];
 
 		pd_data->domains[i] = genpd;
 		scpd->scp = scp;
@@ -1511,8 +1508,7 @@ static int scpsys_probe(struct platform_device *pdev)
 
 	soc = of_device_get_match_data(&pdev->dev);
 
-	scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
-			soc->bus_prot_reg_update);
+	scp = init_scp(pdev, soc);
 	if (IS_ERR(scp))
 		return PTR_ERR(scp);
 
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 10/13] pmdomain: mediatek: Support bus protect with table
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (8 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 09/13] pmdomain: mediatek: Refactor parameters of init_scp Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 11/13] pmdomain: mediatek: Add post init callback Guangjie Song
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Support bus protect with table which can contain multiple items.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 179 ++++++++++++++++++++++++-
 1 file changed, 173 insertions(+), 6 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 47d5d5abcaee..c10756fa1685 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -31,6 +31,8 @@
 #define MTK_RTFF_DELAY_US		10
 #define MTK_STABLE_DELAY_US		100
 
+#define MTK_BUS_PROTECTION_RETY_TIMES	10
+
 #define MTK_SCPD_ACTIVE_WAKEUP		BIT(0)
 #define MTK_SCPD_FWAIT_SRAM		BIT(1)
 #define MTK_SCPD_SRAM_ISO		BIT(2)
@@ -106,6 +108,24 @@
 #define PWR_STATUS_HIF1			BIT(26)	/* MT7622 */
 #define PWR_STATUS_WB			BIT(27)	/* MT7622 */
 
+#define _BUS_PROT(_type, _set_ofs, _clr_ofs,			\
+		_en_ofs, _sta_ofs, _mask, _ack_mask,		\
+		_ignore_clr_ack) {				\
+		.type = _type,					\
+		.set_ofs = _set_ofs,				\
+		.clr_ofs = _clr_ofs,				\
+		.en_ofs = _en_ofs,				\
+		.sta_ofs = _sta_ofs,				\
+		.mask = _mask,					\
+		.ack_mask = _ack_mask,				\
+		.ignore_clr_ack = _ignore_clr_ack,		\
+	}
+
+#define BUS_PROT_IGN(_type, _set_ofs, _clr_ofs,	\
+		_en_ofs, _sta_ofs, _mask)		\
+		_BUS_PROT(_type, _set_ofs, _clr_ofs,	\
+		_en_ofs, _sta_ofs, _mask, _mask, true)
+
 enum clk_id {
 	CLK_NONE,
 	CLK_MM,
@@ -135,6 +155,18 @@ static const char * const clk_names[] = {
 };
 
 #define MAX_CLKS	3
+#define MAX_STEPS	3
+
+struct bus_prot {
+	u32 type;
+	u32 set_ofs;
+	u32 clr_ofs;
+	u32 en_ofs;
+	u32 sta_ofs;
+	u32 mask;
+	u32 ack_mask;
+	bool ignore_clr_ack;
+};
 
 /**
  * struct scp_domain_data - scp domain data for power on/off flow
@@ -157,6 +189,7 @@ static const char * const clk_names[] = {
  * @sram_slp_ack_bits: The mask for sram low power control acked bits.
  * @bus_prot_mask: The mask for single step bus protection.
  * @clk_id: The basic clocks required by this power domain.
+ * @bp_table: The bus protect configs for the power domain.
  * @caps: The flag for active wake-up action.
  */
 struct scp_domain_data {
@@ -179,6 +212,7 @@ struct scp_domain_data {
 	u32 sram_slp_ack_bits;
 	u32 bus_prot_mask;
 	enum clk_id clk_id[MAX_CLKS];
+	struct bus_prot bp_table[MAX_STEPS];
 	u32 caps;
 };
 
@@ -207,6 +241,8 @@ struct scp {
 	struct regmap *infracfg;
 	struct scp_ctrl_reg ctrl_reg;
 	bool bus_prot_reg_update;
+	struct regmap **bp_regmap;
+	int num_bp;
 };
 
 struct scp_subdomain {
@@ -221,6 +257,8 @@ struct scp_soc_data {
 	int num_subdomains;
 	const struct scp_ctrl_reg regs;
 	bool bus_prot_reg_update;
+	const char **bp_list;
+	int num_bp;
 };
 
 static int scpsys_domain_is_on(struct scp_domain *scpd)
@@ -375,10 +413,121 @@ static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
 			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 }
 
+static int set_bus_protection(struct regmap *map, struct bus_prot *bp)
+{
+	u32 val = 0;
+	int retry = 0;
+	int ret = 0;
+
+	while (retry <= MTK_BUS_PROTECTION_RETY_TIMES) {
+		if (bp->set_ofs)
+			regmap_write(map,  bp->set_ofs, bp->mask);
+		else
+			regmap_update_bits(map, bp->en_ofs, bp->mask, bp->mask);
+
+		/* check bus protect enable setting */
+		regmap_read(map, bp->en_ofs, &val);
+		if ((val & bp->mask) == bp->mask)
+			break;
+
+		retry++;
+	}
+
+	ret = regmap_read_poll_timeout_atomic(map, bp->sta_ofs, val,
+					      (val & bp->ack_mask) == bp->ack_mask,
+					      MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	if (ret < 0) {
+		pr_err("%s val=0x%x, mask=0x%x, (val & mask)=0x%x\n",
+		       __func__, val, bp->ack_mask, (val & bp->ack_mask));
+	}
+
+	return ret;
+}
+
+static int clear_bus_protection(struct regmap *map, struct bus_prot *bp)
+{
+	u32 val = 0;
+	int ret = 0;
+
+	if (bp->clr_ofs)
+		regmap_write(map, bp->clr_ofs, bp->mask);
+	else
+		regmap_update_bits(map, bp->en_ofs, bp->mask, 0);
+
+	if (bp->ignore_clr_ack)
+		return 0;
+
+	ret = regmap_read_poll_timeout_atomic(map, bp->sta_ofs, val,
+					      !(val & bp->ack_mask),
+					      MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
+	if (ret < 0) {
+		pr_err("%s val=0x%x, mask=0x%x, (val & mask)=0x%x\n",
+		       __func__, val, bp->ack_mask, (val & bp->ack_mask));
+	}
+	return ret;
+}
+
+static int scpsys_bus_protect_table_disable(struct scp_domain *scpd, unsigned int index)
+{
+	struct scp *scp = scpd->scp;
+	const struct bus_prot *bp_table = scpd->data->bp_table;
+	int ret = 0;
+	int i;
+
+	for (i = index; i >= 0; i--) {
+		struct regmap *map;
+		struct bus_prot bp = bp_table[i];
+
+		if (bp.type == 0 || bp.type >= scp->num_bp)
+			continue;
+
+		map = scp->bp_regmap[bp.type];
+		if (!map)
+			continue;
+
+		ret = clear_bus_protection(map, &bp);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int scpsys_bus_protect_table_enable(struct scp_domain *scpd)
+{
+	struct scp *scp = scpd->scp;
+	const struct bus_prot *bp_table = scpd->data->bp_table;
+	int ret = 0;
+	int i;
+
+	for (i = 0; i < MAX_STEPS; i++) {
+		struct regmap *map;
+		struct bus_prot bp = bp_table[i];
+
+		if (bp.type == 0 || bp.type >= scp->num_bp)
+			continue;
+
+		map = scp->bp_regmap[bp.type];
+		if (!map)
+			continue;
+
+		ret = set_bus_protection(map, &bp);
+		if (ret) {
+			scpsys_bus_protect_table_disable(scpd, i);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
 static int scpsys_bus_protect_enable(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
 
+	if (scp->bp_regmap && scp->num_bp > 0)
+		return scpsys_bus_protect_table_enable(scpd);
+
 	if (!scpd->data->bus_prot_mask)
 		return 0;
 
@@ -391,6 +540,9 @@ static int scpsys_bus_protect_disable(struct scp_domain *scpd)
 {
 	struct scp *scp = scpd->scp;
 
+	if (scp->bp_regmap && scp->num_bp > 0)
+		return scpsys_bus_protect_table_disable(scpd, MAX_STEPS - 1);
+
 	if (!scpd->data->bus_prot_mask)
 		return 0;
 
@@ -833,12 +985,27 @@ static struct scp *init_scp(struct platform_device *pdev, const struct scp_soc_d
 	if (!pd_data->domains)
 		return ERR_PTR(-ENOMEM);
 
-	scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
-			"infracfg");
-	if (IS_ERR(scp->infracfg)) {
-		dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
-				PTR_ERR(scp->infracfg));
-		return ERR_CAST(scp->infracfg);
+	if (soc->bp_list && soc->num_bp > 0) {
+		scp->num_bp = soc->num_bp;
+		scp->bp_regmap = devm_kcalloc(&pdev->dev, scp->num_bp,
+					      sizeof(*scp->bp_regmap), GFP_KERNEL);
+		if (!scp->bp_regmap)
+			return ERR_PTR(-ENOMEM);
+
+		/* get bus prot regmap from dts node, 0 means invalid bus type */
+		for (i = 1; i < scp->num_bp; i++) {
+			ret = mtk_pd_get_regmap(pdev, &scp->bp_regmap[i], soc->bp_list[i]);
+			if (ret)
+				return ERR_PTR(ret);
+		}
+	} else {
+		scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+				"infracfg");
+		if (IS_ERR(scp->infracfg)) {
+			dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
+					PTR_ERR(scp->infracfg));
+			return ERR_CAST(scp->infracfg);
+		}
 	}
 
 	for (i = 0; i < soc->num_domains; i++) {
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 11/13] pmdomain: mediatek: Add post init callback
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (9 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 10/13] pmdomain: mediatek: Support bus protect with table Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  3:44 ` [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain Guangjie Song
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Add post init callback.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mtk-scpsys.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index c10756fa1685..7bfe36c1a1ae 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -250,6 +250,9 @@ struct scp_subdomain {
 	int subdomain;
 };
 
+typedef int (*scp_soc_post_probe_fn)(struct platform_device *pdev,
+		struct scp *scp);
+
 struct scp_soc_data {
 	const struct scp_domain_data *domains;
 	int num_domains;
@@ -259,6 +262,7 @@ struct scp_soc_data {
 	bool bus_prot_reg_update;
 	const char **bp_list;
 	int num_bp;
+	scp_soc_post_probe_fn post_probe;
 };
 
 static int scpsys_domain_is_on(struct scp_domain *scpd)
@@ -1691,6 +1695,12 @@ static int scpsys_probe(struct platform_device *pdev)
 				ret);
 	}
 
+	if (soc->post_probe) {
+		ret = soc->post_probe(pdev, scp);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (10 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 11/13] pmdomain: mediatek: Add post init callback Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-07  5:42   ` Rob Herring (Arm)
  2025-03-07  7:41   ` Krzysztof Kozlowski
  2025-03-07  3:44 ` [PATCH 13/13] pmdomain: mediatek: Add MT8196 power domain support Guangjie Song
  2025-03-10 13:08 ` [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain AngeloGioacchino Del Regno
  13 siblings, 2 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Add the binding documentation for power domain on MediaTek MT8196.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 .../mediatek,mt8196-power-controller.yaml     | 74 +++++++++++++++++++
 include/dt-bindings/power/mt8196-power.h      | 57 ++++++++++++++
 2 files changed, 131 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
 create mode 100644 include/dt-bindings/power/mt8196-power.h

diff --git a/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
new file mode 100644
index 000000000000..6c2867b25967
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/mediatek,mt8196-power-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8196 Power Domains Controller
+
+maintainers:
+  - Guangjie Song <guangjie.song@mediatek.com>
+
+description: |
+  Mediatek processors include support for multiple power domains which can be
+  powered up/down by software based on different application scenes to save power.
+
+properties:
+  $nodename:
+    pattern: '^power-controller(@[0-9a-f]+)?$'
+
+  compatible:
+    enum:
+      - mediatek,mt8196-scpsys
+      - mediatek,mt8196-hfrpsys
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    description: Address range of the power controller.
+
+  clocks:
+    description: |
+      A number of phandles to clocks that need to be enabled during domain
+      power-up sequencing.
+
+  clock-names:
+    description: |
+      List of names of clock.
+
+  domain-supply:
+    description: domain regulator supply.
+
+  spm:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the device containing the spm register range.
+
+  mmpc:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the device containing the mmpc register range.
+
+  vote-regmap:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the device containing the vote register range.
+
+  mm-vote-regmap:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: phandle to the device containing the mm-vote register range.
+
+required:
+  - compatible
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/power/mt8196-power.h>
+
+    scpsys: power-controller@1c004000 {
+      compatible = "mediatek,mt8196-scpsys", "syscon";
+      reg = <0 0x1c004000 0 0x1000>;
+      #power-domain-cells = <1>;
+      spm = <&scpsys_bus>;
+      vote-regmap = <&vote>;
+    };
diff --git a/include/dt-bindings/power/mt8196-power.h b/include/dt-bindings/power/mt8196-power.h
new file mode 100644
index 000000000000..b0db89cc435d
--- /dev/null
+++ b/include/dt-bindings/power/mt8196-power.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Chong-ming Wei <chong-ming.wei@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT8196_POWER_H
+#define _DT_BINDINGS_POWER_MT8196_POWER_H
+
+/* SPM */
+#define MT8196_POWER_DOMAIN_CONN			0
+#define MT8196_POWER_DOMAIN_SSUSB_P0			1
+#define MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0		2
+#define MT8196_POWER_DOMAIN_SSUSB_P1			3
+#define MT8196_POWER_DOMAIN_SSUSB_P23			4
+#define MT8196_POWER_DOMAIN_SSUSB_PHY_P2		5
+#define MT8196_POWER_DOMAIN_PEXTP_MAC0			6
+#define MT8196_POWER_DOMAIN_PEXTP_MAC1			7
+#define MT8196_POWER_DOMAIN_PEXTP_MAC2			8
+#define MT8196_POWER_DOMAIN_PEXTP_PHY0			9
+#define MT8196_POWER_DOMAIN_PEXTP_PHY1			10
+#define MT8196_POWER_DOMAIN_PEXTP_PHY2			11
+#define MT8196_POWER_DOMAIN_ADSP_AO			12
+#define MT8196_POWER_DOMAIN_ADSP_INFRA			13
+#define MT8196_POWER_DOMAIN_AUDIO			14
+#define MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT		15
+#define MT8196_POWER_DOMAIN_MM_PROC_DORMANT		16
+#define MT8196_POWER_DOMAIN_SSR				17
+#define MT8196_SPM_POWER_DOMAIN_NR			18
+
+/* MMPC */
+#define MT8196_POWER_DOMAIN_MM_INFRA_AO			0
+#define MT8196_POWER_DOMAIN_MM_INFRA0			1
+#define MT8196_POWER_DOMAIN_MM_INFRA1			2
+#define MT8196_POWER_DOMAIN_VDE_VCORE0			3
+#define MT8196_POWER_DOMAIN_VDE0			4
+#define MT8196_POWER_DOMAIN_VDE1			5
+#define MT8196_POWER_DOMAIN_VEN0			6
+#define MT8196_POWER_DOMAIN_VEN1			7
+#define MT8196_POWER_DOMAIN_VEN2			8
+#define MT8196_POWER_DOMAIN_DISP_VCORE			9
+#define MT8196_POWER_DOMAIN_DIS0_DORMANT		10
+#define MT8196_POWER_DOMAIN_DIS1_DORMANT		11
+#define MT8196_POWER_DOMAIN_OVL0_DORMANT		12
+#define MT8196_POWER_DOMAIN_OVL1_DORMANT		13
+#define MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT		14
+#define MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT		15
+#define MT8196_POWER_DOMAIN_MML0_SHUTDOWN		16
+#define MT8196_POWER_DOMAIN_MML1_SHUTDOWN		17
+#define MT8196_POWER_DOMAIN_CSI_BS_RX			18
+#define MT8196_POWER_DOMAIN_CSI_LS_RX			19
+#define MT8196_POWER_DOMAIN_DSI_PHY0			20
+#define MT8196_POWER_DOMAIN_DSI_PHY1			21
+#define MT8196_POWER_DOMAIN_DSI_PHY2			22
+#define MT8196_MMPC_POWER_DOMAIN_NR			23
+
+#endif /* _DT_BINDINGS_POWER_MT8196_POWER_H */
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH 13/13] pmdomain: mediatek: Add MT8196 power domain support
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (11 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain Guangjie Song
@ 2025-03-07  3:44 ` Guangjie Song
  2025-03-10 13:08 ` [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain AngeloGioacchino Del Regno
  13 siblings, 0 replies; 17+ messages in thread
From: Guangjie Song @ 2025-03-07  3:44 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Guangjie Song, Project_Global_Chrome_Upstream_Group

Add power domain support for MT8196.

Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
---
 drivers/pmdomain/mediatek/mt8196-scpsys.h | 114 ++++
 drivers/pmdomain/mediatek/mtk-scpsys.c    | 629 ++++++++++++++++++++++
 2 files changed, 743 insertions(+)
 create mode 100644 drivers/pmdomain/mediatek/mt8196-scpsys.h

diff --git a/drivers/pmdomain/mediatek/mt8196-scpsys.h b/drivers/pmdomain/mediatek/mt8196-scpsys.h
new file mode 100644
index 000000000000..07cb08eaa920
--- /dev/null
+++ b/drivers/pmdomain/mediatek/mt8196-scpsys.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 MediaTek Inc.
+ * Author: Guangjie Song <guangjie.song@mediatek.com>
+ */
+#ifndef __PMDOMAIN_MEDIATEK_MT8196_SCPSYS_H
+#define __PMDOMAIN_MEDIATEK_MT8196_SCPSYS_H
+
+#define MT8196_SPM_CONN_PWR_CON			0xe04
+#define MT8196_SPM_SSUSB_DP_PHY_P0_PWR_CON	0xe18
+#define MT8196_SPM_SSUSB_P0_PWR_CON		0xe1c
+#define MT8196_SPM_SSUSB_P1_PWR_CON		0xe20
+#define MT8196_SPM_SSUSB_P23_PWR_CON		0xe24
+#define MT8196_SPM_SSUSB_PHY_P2_PWR_CON		0xe28
+#define MT8196_SPM_PEXTP_MAC0_PWR_CON		0xe34
+#define MT8196_SPM_PEXTP_MAC1_PWR_CON		0xe38
+#define MT8196_SPM_PEXTP_MAC2_PWR_CON		0xe3c
+#define MT8196_SPM_PEXTP_PHY0_PWR_CON		0xe40
+#define MT8196_SPM_PEXTP_PHY1_PWR_CON		0xe44
+#define MT8196_SPM_PEXTP_PHY2_PWR_CON		0xe48
+#define MT8196_SPM_AUDIO_PWR_CON		0xe4c
+#define MT8196_SPM_ADSP_TOP_PWR_CON		0xe54
+#define MT8196_SPM_ADSP_INFRA_PWR_CON		0xe58
+#define MT8196_SPM_ADSP_AO_PWR_CON		0xe5c
+#define MT8196_SPM_PWR_STATUS			0xf14
+#define MT8196_SPM_PWR_STATUS_2ND		0xf18
+
+#define MT8196_SPM_BUS_PROTECT_EN		0xd8
+#define MT8196_SPM_BUS_PROTECT_EN_SET		0xdc
+#define MT8196_SPM_BUS_PROTECT_EN_CLR		0xe0
+#define MT8196_SPM_BUS_PROTECT_RDY		0x208
+
+#define MT8196_MM_PWR_STATUS			0x100
+#define MT8196_MM_PWR_STATUS_2ND		0x104
+
+#define MT8196_VOTE_MTCMOS_SET0			0x218
+#define MT8196_VOTE_MTCMOS_CLR0			0x21c
+#define MT8196_VOTE_MTCMOS_ENABLE0		0x1410
+#define MT8196_VOTE_MTCMOS_DONE0		0x141c
+#define MT8196_VOTE_MTCMOS_SET_STATUS0		0x146c
+#define MT8196_VOTE_MTCMOS_CLR_STATUS0		0x1470
+
+#define MT8196_MM_VOTE_MTCMOS_SET0		0x218
+#define MT8196_MM_VOTE_MTCMOS_CLR0		0x21c
+#define MT8196_MM_VOTE_MTCMOS_SET1		0x220
+#define MT8196_MM_VOTE_MTCMOS_CLR1		0x224
+#define MT8196_MM_VOTE_MTCMOS_ENABLE0		0x1410
+#define MT8196_MM_VOTE_MTCMOS_DONE0		0x141c
+#define MT8196_MM_VOTE_MTCMOS_ENABLE1		0x1420
+#define MT8196_MM_VOTE_MTCMOS_DONE1		0x142c
+#define MT8196_MM_VOTE_MTCMOS_SET_STATUS0	0x146c
+#define MT8196_MM_VOTE_MTCMOS_CLR_STATUS0	0x1470
+#define MT8196_MM_VOTE_MTCMOS_SET_STATUS1	0x1474
+#define MT8196_MM_VOTE_MTCMOS_CLR_STATUS1	0x1478
+#define MT8196_MM_VOTE_MTCMOS_PM_ACK0		0x5514
+#define MT8196_MM_VOTE_MTCMOS_PM_ACK1		0x5518
+
+#define MT8196_SPM_PROT_EN_BUS_CONN		BIT(1)
+#define MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0	BIT(6)
+#define MT8196_SPM_PROT_EN_BUS_SSUSB_P0		BIT(7)
+#define MT8196_SPM_PROT_EN_BUS_SSUSB_P1		BIT(8)
+#define MT8196_SPM_PROT_EN_BUS_SSUSB_P23	BIT(9)
+#define MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2	BIT(10)
+#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0	BIT(13)
+#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1	BIT(14)
+#define MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2	BIT(15)
+#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0	BIT(16)
+#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1	BIT(17)
+#define MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2	BIT(18)
+#define MT8196_SPM_PROT_EN_BUS_AUDIO		BIT(19)
+#define MT8196_SPM_PROT_EN_BUS_ADSP_TOP		BIT(21)
+#define MT8196_SPM_PROT_EN_BUS_ADSP_INFRA	BIT(22)
+#define MT8196_SPM_PROT_EN_BUS_ADSP_AO		BIT(23)
+
+#define MT8196_VOTE_MM_PROC_SHIFT		0
+#define MT8196_VOTE_SSR_SHIFT			1
+
+#define MT8196_MM_VOTE_VDE0_SHIFT		7
+#define MT8196_MM_VOTE_VDE1_SHIFT		8
+#define MT8196_MM_VOTE_VDE_VCORE0_SHIFT		9
+#define MT8196_MM_VOTE_VEN0_SHIFT		10
+#define MT8196_MM_VOTE_VEN1_SHIFT		11
+#define MT8196_MM_VOTE_VEN2_SHIFT		12
+#define MT8196_MM_VOTE_DISP_VCORE_SHIFT		24
+#define MT8196_MM_VOTE_DIS0_SHIFT		25
+#define MT8196_MM_VOTE_DIS1_SHIFT		26
+#define MT8196_MM_VOTE_OVL0_SHIFT		27
+#define MT8196_MM_VOTE_OVL1_SHIFT		28
+#define MT8196_MM_VOTE_DISP_EDPTX_SHIFT		29
+#define MT8196_MM_VOTE_DISP_DPTX_SHIFT		30
+#define MT8196_MM_VOTE_MML0_SHIFT		31
+#define MT8196_MM_VOTE_MML1_SHIFT		0
+#define MT8196_MM_VOTE_MM_INFRA0_SHIFT		1
+#define MT8196_MM_VOTE_MM_INFRA1_SHIFT		2
+#define MT8196_MM_VOTE_MM_INFRA_AO_SHIFT	3
+#define MT8196_MM_VOTE_CSI_BS_RX_SHIFT		5
+#define MT8196_MM_VOTE_CSI_LS_RX_SHIFT		6
+#define MT8196_MM_VOTE_DSI_PHY0_SHIFT		7
+#define MT8196_MM_VOTE_DSI_PHY1_SHIFT		8
+#define MT8196_MM_VOTE_DSI_PHY2_SHIFT		9
+
+enum {
+	MT8196_SPM_BP_INVALID = 0,
+	MT8196_SPM_BP_SPM,
+	MT8196_SPM_BP_NR
+};
+
+enum {
+	MT8196_MMPC_BP_INVALID = 0,
+	MT8196_MMPC_BP_MMPC,
+	MT8196_MMPC_BP_NR,
+};
+
+#endif /* __PMDOMAIN_MEDIATEK_MT8196_SCPSYS_H */
diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index 7bfe36c1a1ae..667e69ada125 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -20,6 +20,9 @@
 #include <dt-bindings/power/mt7622-power.h>
 #include <dt-bindings/power/mt7623a-power.h>
 #include <dt-bindings/power/mt8173-power.h>
+#include <dt-bindings/power/mt8196-power.h>
+
+#include "mt8196-scpsys.h"
 
 #define MTK_POLL_DELAY_US   10
 #define MTK_POLL_TIMEOUT    USEC_PER_SEC
@@ -137,6 +140,8 @@ enum clk_id {
 	CLK_HIFSEL,
 	CLK_JPGDEC,
 	CLK_AUDIO,
+	CLK_DISP_AO_CONFIG,
+	CLK_DISP_DPC,
 	CLK_MAX,
 };
 
@@ -151,6 +156,8 @@ static const char * const clk_names[] = {
 	"hif_sel",
 	"jpgdec",
 	"audio",
+	"disp_ao_config",
+	"disp_dpc",
 	NULL,
 };
 
@@ -1575,6 +1582,594 @@ static const struct scp_subdomain scp_subdomain_mt8173[] = {
 	{MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
 };
 
+/*
+ * MT8196 power domain support
+ */
+static const char *mt8196_spm_bp_list[MT8196_SPM_BP_NR] = {
+	[MT8196_SPM_BP_SPM] = "spm",
+};
+
+static const struct scp_domain_data scp_domain_mt8196_spm_vote_data[] = {
+	[MT8196_POWER_DOMAIN_CONN] = {
+		.name = "conn",
+		.ctl_offs = MT8196_SPM_CONN_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_CONN),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_BYPASS_INIT_ON,
+	},
+	[MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0] = {
+		.name = "ssusb-dp-phy-p0",
+		.ctl_offs = MT8196_SPM_SSUSB_DP_PHY_P0_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY,
+				     MT8196_SPM_PROT_EN_BUS_SSUSB_DP_PHY_P0),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON,
+	},
+	[MT8196_POWER_DOMAIN_SSUSB_P0] = {
+		.name = "ssusb-p0",
+		.ctl_offs = MT8196_SPM_SSUSB_P0_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_P0),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON,
+	},
+	[MT8196_POWER_DOMAIN_SSUSB_P1] = {
+		.name = "ssusb-p1",
+		.ctl_offs = MT8196_SPM_SSUSB_P1_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_P1),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON,
+	},
+	[MT8196_POWER_DOMAIN_SSUSB_P23] = {
+		.name = "ssusb-p23",
+		.ctl_offs = MT8196_SPM_SSUSB_P23_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_SSUSB_P23),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_BYPASS_INIT_ON,
+	},
+	[MT8196_POWER_DOMAIN_SSUSB_PHY_P2] = {
+		.name = "ssusb-phy-p2",
+		.ctl_offs = MT8196_SPM_SSUSB_PHY_P2_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY,
+				     MT8196_SPM_PROT_EN_BUS_SSUSB_PHY_P2),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_BYPASS_INIT_ON,
+	},
+	[MT8196_POWER_DOMAIN_PEXTP_MAC0] = {
+		.name = "pextp-mac0",
+		.ctl_offs = MT8196_SPM_PEXTP_MAC0_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC0),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY,
+	},
+	[MT8196_POWER_DOMAIN_PEXTP_MAC1] = {
+		.name = "pextp-mac1",
+		.ctl_offs = MT8196_SPM_PEXTP_MAC1_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC1),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY,
+	},
+	[MT8196_POWER_DOMAIN_PEXTP_MAC2] = {
+		.name = "pextp-mac2",
+		.ctl_offs = MT8196_SPM_PEXTP_MAC2_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_MAC2),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY,
+	},
+	[MT8196_POWER_DOMAIN_PEXTP_PHY0] = {
+		.name = "pextp-phy0",
+		.ctl_offs = MT8196_SPM_PEXTP_PHY0_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY0),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY,
+	},
+	[MT8196_POWER_DOMAIN_PEXTP_PHY1] = {
+		.name = "pextp-phy1",
+		.ctl_offs = MT8196_SPM_PEXTP_PHY1_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY1),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY,
+	},
+	[MT8196_POWER_DOMAIN_PEXTP_PHY2] = {
+		.name = "pextp-phy2",
+		.ctl_offs = MT8196_SPM_PEXTP_PHY2_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_PEXTP_PHY2),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_PEXTP_PHY_RTFF | MTK_SCPD_RTFF_DELAY,
+	},
+	[MT8196_POWER_DOMAIN_AUDIO] = {
+		.name = "audio",
+		.ctl_offs = MT8196_SPM_AUDIO_PWR_CON,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_AUDIO),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF,
+	},
+	[MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT] = {
+		.name = "adsp-top-dormant",
+		.ctl_offs = MT8196_SPM_ADSP_TOP_PWR_CON,
+		.sram_slp_bits = GENMASK(9, 9),
+		.sram_slp_ack_bits = GENMASK(13, 13),
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_ADSP_TOP),
+		},
+		.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_SRAM_SLP | MTK_SCPD_IS_PWR_CON_ON,
+	},
+	[MT8196_POWER_DOMAIN_ADSP_INFRA] = {
+		.name = "adsp-infra",
+		.ctl_offs = MT8196_SPM_ADSP_INFRA_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_ADSP_INFRA),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON,
+	},
+	[MT8196_POWER_DOMAIN_ADSP_AO] = {
+		.name = "adsp-ao",
+		.ctl_offs = MT8196_SPM_ADSP_AO_PWR_CON,
+		.bp_table = {
+			BUS_PROT_IGN(MT8196_SPM_BP_SPM, MT8196_SPM_BUS_PROTECT_EN_SET,
+				     MT8196_SPM_BUS_PROTECT_EN_CLR, MT8196_SPM_BUS_PROTECT_EN,
+				     MT8196_SPM_BUS_PROTECT_RDY, MT8196_SPM_PROT_EN_BUS_ADSP_AO),
+		},
+		.caps = MTK_SCPD_IS_PWR_CON_ON | MTK_SCPD_NON_CPU_RTFF | MTK_SCPD_ALWAYS_ON,
+	},
+	[MT8196_POWER_DOMAIN_MM_PROC_DORMANT] = {
+		.name = "mm-proc-dormant",
+		.vote_comp = "vote-regmap",
+		.vote_set_ofs = MT8196_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_VOTE_MTCMOS_ENABLE0,
+		.vote_set_sta_ofs = MT8196_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_shift = MT8196_VOTE_MM_PROC_SHIFT,
+		/* TODO: drop MTK_SCPD_ALWAYS_ON after fixing suspend issue. */
+		.caps = MTK_SCPD_VOTE_OPS |  MTK_SCPD_IRQ_SAFE | MTK_SCPD_ALWAYS_ON,
+	},
+	[MT8196_POWER_DOMAIN_SSR] = {
+		.name = "ssrsys",
+		.vote_comp = "vote-regmap",
+		.vote_set_ofs = MT8196_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_VOTE_MTCMOS_ENABLE0,
+		.vote_set_sta_ofs = MT8196_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_shift = MT8196_VOTE_SSR_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+};
+
+static const struct scp_subdomain scp_subdomain_mt8196_spm[] = {
+	{MT8196_POWER_DOMAIN_SSUSB_P0, MT8196_POWER_DOMAIN_SSUSB_DP_PHY_P0},
+	{MT8196_POWER_DOMAIN_SSUSB_P23, MT8196_POWER_DOMAIN_SSUSB_PHY_P2},
+	{MT8196_POWER_DOMAIN_PEXTP_MAC0, MT8196_POWER_DOMAIN_PEXTP_PHY0},
+	{MT8196_POWER_DOMAIN_PEXTP_MAC1, MT8196_POWER_DOMAIN_PEXTP_PHY1},
+	{MT8196_POWER_DOMAIN_PEXTP_MAC2, MT8196_POWER_DOMAIN_PEXTP_PHY2},
+	{MT8196_POWER_DOMAIN_ADSP_INFRA, MT8196_POWER_DOMAIN_AUDIO},
+	{MT8196_POWER_DOMAIN_ADSP_INFRA, MT8196_POWER_DOMAIN_ADSP_TOP_DORMANT},
+	{MT8196_POWER_DOMAIN_ADSP_AO, MT8196_POWER_DOMAIN_ADSP_INFRA},
+};
+
+static struct generic_pm_domain *mt8196_mm_proc_domain;
+
+static int mt8196_spm_post_probe(struct platform_device *pdev, struct scp *scp)
+{
+	mt8196_mm_proc_domain = scp->pd_data.domains[MT8196_POWER_DOMAIN_MM_PROC_DORMANT];
+
+	return 0;
+}
+
+static const char *mt8196_mmpc_bp_list[MT8196_MMPC_BP_NR] = {
+	[MT8196_MMPC_BP_MMPC] = "mmpc",
+};
+
+static const struct scp_domain_data scp_domain_mt8196_mmpc_vote_data[] = {
+	[MT8196_POWER_DOMAIN_VDE0] = {
+		.name = "vde0",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_VDE0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_VDE1] = {
+		.name = "vde1",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_VDE1_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_VDE_VCORE0] = {
+		.name = "vde-vcore0",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_VDE_VCORE0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_VEN0] = {
+		.name = "ven0",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_VEN0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_VEN1] = {
+		.name = "ven1",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_VEN1_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_VEN2] = {
+		.name = "ven2",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_VEN2_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DISP_VCORE] = {
+		.name = "disp-vcore",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_DISP_VCORE_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DIS0_DORMANT] = {
+		.name = "dis0-dormant",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_DIS0_SHIFT,
+		.clk_id = {CLK_DISP_AO_CONFIG, CLK_DISP_DPC},
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DIS1_DORMANT] = {
+		.name = "dis1-dormant",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_DIS1_SHIFT,
+		.clk_id = {CLK_DISP_AO_CONFIG, CLK_DISP_DPC},
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_OVL0_DORMANT] = {
+		.name = "ovl0-dormant",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_OVL0_SHIFT,
+		.clk_id = {CLK_DISP_AO_CONFIG, CLK_DISP_DPC},
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_OVL1_DORMANT] = {
+		.name = "ovl1-dormant",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_OVL1_SHIFT,
+		.clk_id = {CLK_DISP_AO_CONFIG, CLK_DISP_DPC},
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT] = {
+		.name = "disp-edptx-dormant",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_DISP_EDPTX_SHIFT,
+		.clk_id = {CLK_DISP_AO_CONFIG, CLK_DISP_DPC},
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT] = {
+		.name = "disp-dptx-dormant",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_DISP_DPTX_SHIFT,
+		.clk_id = {CLK_DISP_AO_CONFIG, CLK_DISP_DPC},
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_MML0_SHUTDOWN] = {
+		.name = "mml0-shutdown",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET0,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE0,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_CLR0,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS0,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS0,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK0,
+		.vote_shift = MT8196_MM_VOTE_MML0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_MML1_SHUTDOWN] = {
+		.name = "mml1-shutdown",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_MML0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_MM_INFRA0] = {
+		.name = "mm-infra0",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_MM_INFRA0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS |  MTK_SCPD_IRQ_SAFE,
+	},
+	[MT8196_POWER_DOMAIN_MM_INFRA1] = {
+		.name = "mm-infra1",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_MM_INFRA1_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS |  MTK_SCPD_IRQ_SAFE,
+	},
+	[MT8196_POWER_DOMAIN_MM_INFRA_AO] = {
+		.name = "mm-infra-ao",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_MM_INFRA_AO_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS |  MTK_SCPD_IRQ_SAFE,
+	},
+	[MT8196_POWER_DOMAIN_CSI_BS_RX] = {
+		.name = "csi-bs-rx",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_CSI_BS_RX_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_CSI_LS_RX] = {
+		.name = "csi-ls-rx",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_CSI_LS_RX_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DSI_PHY0] = {
+		.name = "dsi-phy0",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_DSI_PHY0_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DSI_PHY1] = {
+		.name = "dsi-phy1",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_DSI_PHY1_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+	[MT8196_POWER_DOMAIN_DSI_PHY2] = {
+		.name = "dsi-phy2",
+		.vote_comp = "mm-vote-regmap",
+		.vote_set_ofs = MT8196_MM_VOTE_MTCMOS_SET1,
+		.vote_clr_ofs = MT8196_MM_VOTE_MTCMOS_CLR1,
+		.vote_done_ofs = MT8196_MM_VOTE_MTCMOS_DONE1,
+		.vote_en_ofs = MT8196_MM_VOTE_MTCMOS_ENABLE1,
+		.vote_set_sta_ofs = MT8196_MM_VOTE_MTCMOS_SET_STATUS1,
+		.vote_clr_sta_ofs = MT8196_MM_VOTE_MTCMOS_CLR_STATUS1,
+		.vote_ack_ofs = MT8196_MM_VOTE_MTCMOS_PM_ACK1,
+		.vote_shift = MT8196_MM_VOTE_DSI_PHY2_SHIFT,
+		.caps = MTK_SCPD_VOTE_OPS,
+	},
+};
+
+static const struct scp_subdomain scp_subdomain_mt8196_mmpc[] = {
+	{MT8196_POWER_DOMAIN_VDE_VCORE0, MT8196_POWER_DOMAIN_VDE0},
+	{MT8196_POWER_DOMAIN_VDE_VCORE0, MT8196_POWER_DOMAIN_VDE1},
+	{MT8196_POWER_DOMAIN_VEN0, MT8196_POWER_DOMAIN_VEN1},
+	{MT8196_POWER_DOMAIN_VEN1, MT8196_POWER_DOMAIN_VEN2},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DIS0_DORMANT},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DIS1_DORMANT},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_OVL0_DORMANT},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_OVL1_DORMANT},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DISP_EDPTX_DORMANT},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_DISP_DPTX_DORMANT},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_MML0_SHUTDOWN},
+	{MT8196_POWER_DOMAIN_DISP_VCORE, MT8196_POWER_DOMAIN_MML1_SHUTDOWN},
+	{MT8196_POWER_DOMAIN_MM_INFRA1, MT8196_POWER_DOMAIN_DISP_VCORE},
+	{MT8196_POWER_DOMAIN_MM_INFRA1, MT8196_POWER_DOMAIN_VDE_VCORE0},
+	{MT8196_POWER_DOMAIN_MM_INFRA1, MT8196_POWER_DOMAIN_VEN0},
+	{MT8196_POWER_DOMAIN_MM_INFRA0, MT8196_POWER_DOMAIN_MM_INFRA1},
+	{MT8196_POWER_DOMAIN_MM_INFRA_AO, MT8196_POWER_DOMAIN_MM_INFRA0},
+};
+
+static int mt8196_mmpc_post_probe(struct platform_device *pdev, struct scp *scp)
+{
+	int ret, i;
+	int subdomain[] = {
+		MT8196_POWER_DOMAIN_MM_INFRA_AO,
+		MT8196_POWER_DOMAIN_CSI_BS_RX,
+		MT8196_POWER_DOMAIN_CSI_LS_RX,
+		MT8196_POWER_DOMAIN_DSI_PHY0,
+		MT8196_POWER_DOMAIN_DSI_PHY1,
+		MT8196_POWER_DOMAIN_DSI_PHY2
+	};
+
+	for (i = 0; i < ARRAY_SIZE(subdomain); i++) {
+		ret = pm_genpd_add_subdomain(mt8196_mm_proc_domain, scp->pd_data.domains[subdomain[i]]);
+		if (ret && IS_ENABLED(CONFIG_PM)) {
+			dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
 static const struct scp_soc_data mt2701_data = {
 	.domains = scp_domain_data_mt2701,
 	.num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
@@ -1641,6 +2236,34 @@ static const struct scp_soc_data mt8173_data = {
 	.bus_prot_reg_update = true,
 };
 
+static const struct scp_soc_data mt8196_spm_vote_data = {
+	.domains = scp_domain_mt8196_spm_vote_data,
+	.num_domains = MT8196_SPM_POWER_DOMAIN_NR,
+	.subdomains = scp_subdomain_mt8196_spm,
+	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8196_spm),
+	.regs = {
+		.pwr_sta_offs = MT8196_SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = MT8196_SPM_PWR_STATUS_2ND,
+	},
+	.bp_list = mt8196_spm_bp_list,
+	.num_bp = MT8196_SPM_BP_NR,
+	.post_probe = mt8196_spm_post_probe,
+};
+
+static const struct scp_soc_data mt8196_mmpc_vote_data = {
+	.domains = scp_domain_mt8196_mmpc_vote_data,
+	.num_domains = MT8196_MMPC_POWER_DOMAIN_NR,
+	.subdomains = scp_subdomain_mt8196_mmpc,
+	.num_subdomains = ARRAY_SIZE(scp_subdomain_mt8196_mmpc),
+	.regs = {
+		.pwr_sta_offs = MT8196_MM_PWR_STATUS,
+		.pwr_sta2nd_offs = MT8196_MM_PWR_STATUS_2ND,
+	},
+	.bp_list = mt8196_mmpc_bp_list,
+	.num_bp = MT8196_MMPC_BP_NR,
+	.post_probe = mt8196_mmpc_post_probe,
+};
+
 /*
  * scpsys driver init
  */
@@ -1664,6 +2287,12 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
 	}, {
 		.compatible = "mediatek,mt8173-scpsys",
 		.data = &mt8173_data,
+	}, {
+		.compatible = "mediatek,mt8196-scpsys",
+		.data = &mt8196_spm_vote_data,
+	}, {
+		.compatible = "mediatek,mt8196-hfrpsys",
+		.data = &mt8196_mmpc_vote_data,
 	}, {
 		/* sentinel */
 	}
-- 
2.45.2



^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain
  2025-03-07  3:44 ` [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain Guangjie Song
@ 2025-03-07  5:42   ` Rob Herring (Arm)
  2025-03-07  7:41   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 17+ messages in thread
From: Rob Herring (Arm) @ 2025-03-07  5:42 UTC (permalink / raw)
  To: Guangjie Song
  Cc: Krzysztof Kozlowski, linux-kernel, Matthias Brugger,
	linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, Conor Dooley, linux-pm,
	AngeloGioacchino Del Regno, devicetree, Ulf Hansson


On Fri, 07 Mar 2025 11:44:36 +0800, Guangjie Song wrote:
> Add the binding documentation for power domain on MediaTek MT8196.
> 
> Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
> ---
>  .../mediatek,mt8196-power-controller.yaml     | 74 +++++++++++++++++++
>  include/dt-bindings/power/mt8196-power.h      | 57 ++++++++++++++
>  2 files changed, 131 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
>  create mode 100644 include/dt-bindings/power/mt8196-power.h
> 

My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.example.dtb: power-controller@1c004000: compatible: ['mediatek,mt8196-scpsys', 'syscon'] is too long
	from schema $id: http://devicetree.org/schemas/power/mediatek,mt8196-power-controller.yaml#
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.example.dtb: power-controller@1c004000: reg: [[0, 469778432], [0, 4096]] is too long
	from schema $id: http://devicetree.org/schemas/mfd/syscon-common.yaml#

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20250307034454.12243-13-guangjie.song@mediatek.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain
  2025-03-07  3:44 ` [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain Guangjie Song
  2025-03-07  5:42   ` Rob Herring (Arm)
@ 2025-03-07  7:41   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 17+ messages in thread
From: Krzysztof Kozlowski @ 2025-03-07  7:41 UTC (permalink / raw)
  To: Guangjie Song
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
	AngeloGioacchino Del Regno, Ulf Hansson, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-pm,
	Project_Global_Chrome_Upstream_Group

On Fri, Mar 07, 2025 at 11:44:36AM +0800, Guangjie Song wrote:
> Add the binding documentation for power domain on MediaTek MT8196.
> 
> Signed-off-by: Guangjie Song <guangjie.song@mediatek.com>
> ---
>  .../mediatek,mt8196-power-controller.yaml     | 74 +++++++++++++++++++
>  include/dt-bindings/power/mt8196-power.h      | 57 ++++++++++++++


You keep sending multiple patchsets and none of them are tested.


>  2 files changed, 131 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
>  create mode 100644 include/dt-bindings/power/mt8196-power.h

Comments from other patches apply.

> 
> diff --git a/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
> new file mode 100644
> index 000000000000..6c2867b25967
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
> @@ -0,0 +1,74 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/power/mediatek,mt8196-power-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek MT8196 Power Domains Controller
> +
> +maintainers:
> +  - Guangjie Song <guangjie.song@mediatek.com>
> +
> +description: |
> +  Mediatek processors include support for multiple power domains which can be
> +  powered up/down by software based on different application scenes to save power.
> +
> +properties:
> +  $nodename:
> +    pattern: '^power-controller(@[0-9a-f]+)?$'


How unit address can be optional?

> +
> +  compatible:
> +    enum:
> +      - mediatek,mt8196-scpsys
> +      - mediatek,mt8196-hfrpsys
> +
> +  '#power-domain-cells':
> +    const: 1
> +
> +  reg:
> +    description: Address range of the power controller.

No, look how other bindings do it.

> +
> +  clocks:
> +    description: |

Look at other bindings.

> +      A number of phandles to clocks that need to be enabled during domain
> +      power-up sequencing.

Look at other bindings.

> +
> +  clock-names:
> +    description: |
> +      List of names of clock.
> +
> +  domain-supply:
> +    description: domain regulator supply.
> +
> +  spm:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: phandle to the device containing the spm register range.
> +
> +  mmpc:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: phandle to the device containing the mmpc register range.
> +
> +  vote-regmap:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: phandle to the device containing the vote register range.
> +
> +  mm-vote-regmap:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description: phandle to the device containing the mm-vote register range.

None of these are correct.

> +
> +required:
> +  - compatible

That's just incomplete.

This binding is really incomplete and with multiple issues. Considering
this was never tested, please first consult some internal folks to do
proper internal review.

> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/power/mt8196-power.h>
> +
> +    scpsys: power-controller@1c004000 {
> +      compatible = "mediatek,mt8196-scpsys", "syscon";
> +      reg = <0 0x1c004000 0 0x1000>;
> +      #power-domain-cells = <1>;
> +      spm = <&scpsys_bus>;
> +      vote-regmap = <&vote>;
> +    };
> diff --git a/include/dt-bindings/power/mt8196-power.h b/include/dt-bindings/power/mt8196-power.h
> new file mode 100644
> index 000000000000..b0db89cc435d
> --- /dev/null
> +++ b/include/dt-bindings/power/mt8196-power.h
> @@ -0,0 +1,57 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright (c) 2023 MediaTek Inc.

We have 2025.

Best regards,
Krzysztof



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain
  2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
                   ` (12 preceding siblings ...)
  2025-03-07  3:44 ` [PATCH 13/13] pmdomain: mediatek: Add MT8196 power domain support Guangjie Song
@ 2025-03-10 13:08 ` AngeloGioacchino Del Regno
  13 siblings, 0 replies; 17+ messages in thread
From: AngeloGioacchino Del Regno @ 2025-03-10 13:08 UTC (permalink / raw)
  To: Guangjie Song, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Matthias Brugger, Ulf Hansson
  Cc: devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-pm, Project_Global_Chrome_Upstream_Group

Il 07/03/25 04:44, Guangjie Song ha scritto:
> This series is based on linux-next, tag: next-20250306.
> 
> Changes:
> - Update mtk-scpsys driver for MT8196
> - Add MT8196 power domain support

The mtk-scpsys driver is deprecated since ... 2 years ago, and I have no idea why
MediaTek folks still use it downstream.

Please refactor this and use the mtk-pm-domains driver for any new MTCMOS
implementation.

Thanks,
Angelo

> 
> Guangjie Song (13):
>    pmdomain: mediatek: Support sram isolation
>    pmdomain: mediatek: Support sram low power
>    pmdomain: mediatek: Support power on bypass
>    pmdomain: mediatek: Support check power on/off ack
>    pmdomain: mediatek: Support voting for power domain
>    pmdomain: mediatek: Support trigger subsys save/restore regesters
>    pmdomain: mediatek: Support power domain irq safe
>    pmdomain: mediatek: Support power domain always on
>    pmdomain: mediatek: Refactor parameters of init_scp
>    pmdomain: mediatek: Support bus protect with table
>    pmdomain: mediatek: Add post init callback
>    dt-bindings: power: mediatek: Add new MT8196 power domain
>    pmdomain: mediatek: Add MT8196 power domain support
> 
>   .../mediatek,mt8196-power-controller.yaml     |   74 +
>   drivers/pmdomain/mediatek/mt8196-scpsys.h     |  114 ++
>   drivers/pmdomain/mediatek/mtk-scpsys.c        | 1276 ++++++++++++++++-
>   include/dt-bindings/power/mt8196-power.h      |   57 +
>   4 files changed, 1483 insertions(+), 38 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/power/mediatek,mt8196-power-controller.yaml
>   create mode 100644 drivers/pmdomain/mediatek/mt8196-scpsys.h
>   create mode 100644 include/dt-bindings/power/mt8196-power.h
> 





^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2025-03-10 14:45 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-07  3:44 [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain Guangjie Song
2025-03-07  3:44 ` [PATCH 01/13] pmdomain: mediatek: Support sram isolation Guangjie Song
2025-03-07  3:44 ` [PATCH 02/13] pmdomain: mediatek: Support sram low power Guangjie Song
2025-03-07  3:44 ` [PATCH 03/13] pmdomain: mediatek: Support power on bypass Guangjie Song
2025-03-07  3:44 ` [PATCH 04/13] pmdomain: mediatek: Support check power on/off ack Guangjie Song
2025-03-07  3:44 ` [PATCH 05/13] pmdomain: mediatek: Support voting for power domain Guangjie Song
2025-03-07  3:44 ` [PATCH 06/13] pmdomain: mediatek: Support trigger subsys save/restore regesters Guangjie Song
2025-03-07  3:44 ` [PATCH 07/13] pmdomain: mediatek: Support power domain irq safe Guangjie Song
2025-03-07  3:44 ` [PATCH 08/13] pmdomain: mediatek: Support power domain always on Guangjie Song
2025-03-07  3:44 ` [PATCH 09/13] pmdomain: mediatek: Refactor parameters of init_scp Guangjie Song
2025-03-07  3:44 ` [PATCH 10/13] pmdomain: mediatek: Support bus protect with table Guangjie Song
2025-03-07  3:44 ` [PATCH 11/13] pmdomain: mediatek: Add post init callback Guangjie Song
2025-03-07  3:44 ` [PATCH 12/13] dt-bindings: power: mediatek: Add new MT8196 power domain Guangjie Song
2025-03-07  5:42   ` Rob Herring (Arm)
2025-03-07  7:41   ` Krzysztof Kozlowski
2025-03-07  3:44 ` [PATCH 13/13] pmdomain: mediatek: Add MT8196 power domain support Guangjie Song
2025-03-10 13:08 ` [PATCH 00/13] pmdomain: mediatek: Add MT8196 power domain AngeloGioacchino Del Regno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox