* [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