summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorMatthias Brugger <mbrugger@suse.com>2020-10-30 14:36:11 +0300
committerMatthias Brugger <matthias.bgg@gmail.com>2020-11-27 14:04:42 +0300
commit928296ea5da37838d7127de4b10f47cd97401b13 (patch)
treed82527227ad2f41557fc2c8a7a13748ea2934978 /drivers/soc
parent916d6d71ba56cfc19a0bfd8a0e181443a13cb865 (diff)
downloadlinux-928296ea5da37838d7127de4b10f47cd97401b13.tar.xz
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')
-rw-r--r--drivers/soc/mediatek/Kconfig1
-rw-r--r--drivers/soc/mediatek/mtk-infracfg.c5
-rw-r--r--drivers/soc/mediatek/mtk-pm-domains.c57
3 files changed, 44 insertions, 19 deletions
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 68d800f9e4a5..67cef12dc585 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -48,7 +48,6 @@ config MTK_SCPSYS_PM_DOMAINS
bool "MediaTek SCPSYS generic power domain"
default ARCH_MEDIATEK
depends on PM
- depends on MTK_INFRACFG
select PM_GENERIC_DOMAINS
select REGMAP
help
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c
index 4a123796aad3..0590b68e0d78 100644
--- a/drivers/soc/mediatek/mtk-infracfg.c
+++ b/drivers/soc/mediatek/mtk-infracfg.c
@@ -12,11 +12,6 @@
#define MTK_POLL_DELAY_US 10
#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
-#define INFRA_TOPAXI_PROTECTEN 0x0220
-#define INFRA_TOPAXI_PROTECTSTA1 0x0228
-#define INFRA_TOPAXI_PROTECTEN_SET 0x0260
-#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
-
/**
* mtk_infracfg_set_bus_protection - enable bus protection
* @infracfg: The infracfg regmap
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);