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