]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
pmdomain: mediatek: Add bus protect control flow for MT8189
authorIrving-CH Lin <irving-ch.lin@mediatek.com>
Mon, 2 Feb 2026 06:48:14 +0000 (14:48 +0800)
committerUlf Hansson <ulf.hansson@linaro.org>
Wed, 1 Apr 2026 11:07:31 +0000 (13:07 +0200)
In MT8189 mminfra power domain, the bus protect policy separates
into two parts, one is set before subsys clocks enabled, and another
need to enable after subsys clocks enable.

Signed-off-by: Irving-CH Lin <irving-ch.lin@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.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 46b1869093b6d4aaeaf6bcd7eb4724ea68b86719..93827c611c4b6656d60c8ebc2c71611380a9bc9e 100644 (file)
@@ -250,7 +250,7 @@ static int scpsys_bus_protect_set(struct scpsys_domain *pd,
                                        MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 }
 
-static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
+static int scpsys_bus_protect_enable(struct scpsys_domain *pd, u8 flags)
 {
        for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
                const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
@@ -259,6 +259,10 @@ static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
                if (!bpd->bus_prot_set_clr_mask)
                        break;
 
+               if ((bpd->flags & BUS_PROT_IGNORE_SUBCLK) !=
+                   (flags & BUS_PROT_IGNORE_SUBCLK))
+                       continue;
+
                if (bpd->flags & BUS_PROT_INVERTED)
                        ret = scpsys_bus_protect_clear(pd, bpd);
                else
@@ -270,7 +274,7 @@ static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
        return 0;
 }
 
-static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
+static int scpsys_bus_protect_disable(struct scpsys_domain *pd, u8 flags)
 {
        for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
                const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
@@ -279,6 +283,10 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
                if (!bpd->bus_prot_set_clr_mask)
                        continue;
 
+               if ((bpd->flags & BUS_PROT_IGNORE_SUBCLK) !=
+                   (flags & BUS_PROT_IGNORE_SUBCLK))
+                       continue;
+
                if (bpd->flags & BUS_PROT_INVERTED)
                        ret = scpsys_bus_protect_set(pd, bpd);
                else
@@ -632,6 +640,15 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        if (ret)
                goto err_pwr_ack;
 
+       /*
+        * In MT8189 mminfra power domain, the bus protect policy separates
+        * into two parts, one is set before subsys clocks enabled, and another
+        * need to enable after subsys clocks enable.
+        */
+       ret = scpsys_bus_protect_disable(pd, BUS_PROT_IGNORE_SUBCLK);
+       if (ret < 0)
+               goto err_pwr_ack;
+
        /*
         * In few Mediatek platforms(e.g. MT6779), the bus protect policy is
         * stricter, which leads to bus protect release must be prior to bus
@@ -648,7 +665,7 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        if (ret < 0)
                goto err_disable_subsys_clks;
 
-       ret = scpsys_bus_protect_disable(pd);
+       ret = scpsys_bus_protect_disable(pd, 0);
        if (ret < 0)
                goto err_disable_sram;
 
@@ -662,7 +679,7 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
        return 0;
 
 err_enable_bus_protect:
-       scpsys_bus_protect_enable(pd);
+       scpsys_bus_protect_enable(pd, 0);
 err_disable_sram:
        scpsys_sram_disable(pd);
 err_disable_subsys_clks:
@@ -683,7 +700,7 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
        bool tmp;
        int ret;
 
-       ret = scpsys_bus_protect_enable(pd);
+       ret = scpsys_bus_protect_enable(pd, 0);
        if (ret < 0)
                return ret;
 
@@ -697,6 +714,10 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 
        clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks);
 
+       ret = scpsys_bus_protect_enable(pd, BUS_PROT_IGNORE_SUBCLK);
+       if (ret < 0)
+               return ret;
+
        if (MTK_SCPD_CAPS(pd, MTK_SCPD_MODEM_PWRSEQ))
                scpsys_modem_pwrseq_off(pd);
        else
index f608e6ec47446338dbc5371060353050fa11cfe2..a5dca24cbc2f5eb71115f579870bdd7314c441ac 100644 (file)
@@ -56,6 +56,7 @@ enum scpsys_bus_prot_flags {
        BUS_PROT_REG_UPDATE = BIT(1),
        BUS_PROT_IGNORE_CLR_ACK = BIT(2),
        BUS_PROT_INVERTED = BIT(3),
+       BUS_PROT_IGNORE_SUBCLK = BIT(4),
 };
 
 enum scpsys_bus_prot_block {
@@ -95,6 +96,10 @@ enum scpsys_bus_prot_block {
                _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta,        \
                          BUS_PROT_REG_UPDATE)
 
+#define BUS_PROT_WR_IGN_SUBCLK(_hwip, _mask, _set, _clr, _sta)         \
+               _BUS_PROT(_hwip, _mask, _set, _clr, _mask, _sta,        \
+                         BUS_PROT_IGNORE_CLR_ACK | BUS_PROT_IGNORE_SUBCLK)
+
 #define BUS_PROT_INFRA_UPDATE_TOPAXI(_mask)                    \
                BUS_PROT_UPDATE(INFRA, _mask,                   \
                                INFRA_TOPAXI_PROTECTEN,         \