diff options
author | Matthias Brugger <mbrugger@suse.com> | 2020-10-30 12:36:11 +0100 |
---|---|---|
committer | Matthias Brugger <matthias.bgg@gmail.com> | 2020-11-27 12:04:42 +0100 |
commit | 928296ea5da37838d7127de4b10f47cd97401b13 (patch) | |
tree | d82527227ad2f41557fc2c8a7a13748ea2934978 /drivers/soc/mediatek/mtk-pm-domains.c | |
parent | soc: mediatek: pm-domains: Add bus protection protocol (diff) | |
download | linux-dev-928296ea5da37838d7127de4b10f47cd97401b13.tar.xz linux-dev-928296ea5da37838d7127de4b10f47cd97401b13.zip |
soc: mediatek: pm_domains: Make bus protection generic
Bus protection is not exclusively done by calling the infracfg misc driver.
Make the calls for setting and clearing the bus protection generic so
that we can use other blocks for it as well.
Signed-off-by: Matthias Brugger <mbrugger@suse.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Link: https://lore.kernel.org/r/20201030113622.201188-6-enric.balletbo@collabora.com
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
Diffstat (limited to 'drivers/soc/mediatek/mtk-pm-domains.c')
-rw-r--r-- | drivers/soc/mediatek/mtk-pm-domains.c | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c index 06a16e45356a..6122701d018f 100644 --- a/drivers/soc/mediatek/mtk-pm-domains.c +++ b/drivers/soc/mediatek/mtk-pm-domains.c @@ -86,18 +86,24 @@ static int scpsys_sram_disable(struct scpsys_domain *pd) MTK_POLL_TIMEOUT); } -static int scpsys_bus_protect_enable(struct scpsys_domain *pd) +static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd, struct regmap *regmap) { - const struct scpsys_bus_prot_data *bpd = pd->data->bp_infracfg; int i, ret; for (i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) { - if (!bpd[i].bus_prot_mask) + u32 val, mask = bpd[i].bus_prot_mask; + + if (!mask) break; - ret = mtk_infracfg_set_bus_protection(pd->infracfg, - bpd[i].bus_prot_mask, - bpd[i].bus_prot_reg_update); + if (bpd[i].bus_prot_reg_update) + regmap_set_bits(regmap, bpd[i].bus_prot_set, mask); + else + regmap_write(regmap, INFRA_TOPAXI_PROTECTEN_SET, mask); + + ret = regmap_read_poll_timeout(regmap, INFRA_TOPAXI_PROTECTSTA1, + val, (val & mask) == mask, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret) return ret; } @@ -105,18 +111,34 @@ 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_enable(struct scpsys_domain *pd) +{ + int ret; + + ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg, pd->infracfg); + + return ret; +} + +static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd, + struct regmap *regmap) { - const struct scpsys_bus_prot_data *bpd = pd->data->bp_infracfg; int i, ret; - for (i = SPM_MAX_BUS_PROT_DATA; i > 0; i--) { - if (!bpd[i].bus_prot_mask) + for (i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) { + u32 val, mask = bpd[i].bus_prot_mask; + + if (!mask) continue; - ret = mtk_infracfg_clear_bus_protection(pd->infracfg, - bpd[i].bus_prot_mask, - bpd[i].bus_prot_reg_update); + if (bpd[i].bus_prot_reg_update) + regmap_clear_bits(regmap, bpd[i].bus_prot_clr, mask); + else + regmap_write(regmap, INFRA_TOPAXI_PROTECTEN_CLR, mask); + + ret = regmap_read_poll_timeout(regmap, INFRA_TOPAXI_PROTECTSTA1, + val, !(val & mask), + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); if (ret) return ret; } @@ -124,6 +146,15 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd) return 0; } +static int scpsys_bus_protect_disable(struct scpsys_domain *pd) +{ + int ret; + + ret = _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg); + + return ret; +} + static int scpsys_power_on(struct generic_pm_domain *genpd) { struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd); |