]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
pmdomain: mediatek: Add support for modem power sequences
authorAngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tue, 5 Aug 2025 07:47:43 +0000 (09:47 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Tue, 19 Aug 2025 12:12:40 +0000 (14:12 +0200)
Add support for the modem power domains by adding its specific
power sequence in functions scpsys_modem_pwrseq_{on,off}() and
call them if the flag MTK_SCPD_MODEM_PWRSEQ is present.

While at it, since some SoC models need to skip setting/clearing
the PWR_RST_B_BIT, also add a MTK_SCPD_SKIP_RESET_B flag for that.

Reviewed-by: NĂ­colas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20250805074746.29457-8-angelogioacchino.delregno@collabora.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/pmdomain/mediatek/mtk-pm-domains.c
drivers/pmdomain/mediatek/mtk-pm-domains.h

index d84f0e7cde12f2d9be1b6297f722fc9a8e8cbaaa..cf749ba5c3c7aaa68a3727d38fc3c20a13b8e1ae 100644 (file)
@@ -279,6 +279,36 @@ static void scpsys_ctl_pwrseq_off(struct scpsys_domain *pd)
        regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
 }
 
+static int scpsys_modem_pwrseq_on(struct scpsys_domain *pd)
+{
+       struct scpsys *scpsys = pd->scpsys;
+       bool tmp;
+       int ret;
+
+       if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B))
+               regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
+
+       regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
+
+       /* wait until PWR_ACK = 1 */
+       ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, tmp, MTK_POLL_DELAY_US,
+                                MTK_POLL_TIMEOUT);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static void scpsys_modem_pwrseq_off(struct scpsys_domain *pd)
+{
+       struct scpsys *scpsys = pd->scpsys;
+
+       regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT);
+
+       if (!MTK_SCPD_CAPS(pd, MTK_SCPD_SKIP_RESET_B))
+               regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT);
+}
+
 static int scpsys_power_on(struct generic_pm_domain *genpd)
 {
        struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
@@ -297,7 +327,11 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
                regmap_clear_bits(scpsys->base, pd->data->ext_buck_iso_offs,
                                  pd->data->ext_buck_iso_mask);
 
-       ret = scpsys_ctl_pwrseq_on(pd);
+       if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
+               ret = scpsys_modem_pwrseq_on(pd);
+       else
+               ret = scpsys_ctl_pwrseq_on(pd);
+
        if (ret)
                goto err_pwr_ack;
 
@@ -366,7 +400,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 
        clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
 
-       scpsys_ctl_pwrseq_off(pd);
+       if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
+               scpsys_modem_pwrseq_off(pd);
+       else
+               scpsys_ctl_pwrseq_off(pd);
 
        /* wait until PWR_ACK = 0 */
        ret = readx_poll_timeout(scpsys_domain_is_on, pd, tmp, !tmp, MTK_POLL_DELAY_US,
index fbbfb23a87396882a3ba0692ab10668a5ad13342..931a54f1c5caf102d03364bfed98460eff45704e 100644 (file)
@@ -14,6 +14,8 @@
 #define MTK_SCPD_HAS_INFRA_NAO         BIT(7)
 #define MTK_SCPD_STRICT_BUS_PROTECTION BIT(8)
 #define MTK_SCPD_SRAM_PDN_INVERTED     BIT(9)
+#define MTK_SCPD_MODEM_PWRSEQ          BIT(10)
+#define MTK_SCPD_SKIP_RESET_B          BIT(11)
 #define MTK_SCPD_CAPS(_scpd, _x)       ((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON                        0x0210