Commit f414854c authored by Matthias Brugger's avatar Matthias Brugger Committed by Matthias Brugger

soc: mediatek: pm-domains: Add SMI block as bus protection block

Apart from the infracfg block, the SMI block is used to enable the bus
protection for some power domains. Add support for this block.
Signed-off-by: default avatarMatthias Brugger <mbrugger@suse.com>
Signed-off-by: default avatarEnric Balletbo i Serra <enric.balletbo@collabora.com>
Link: https://lore.kernel.org/r/20201030113622.201188-7-enric.balletbo@collabora.comSigned-off-by: default avatarMatthias Brugger <matthias.bgg@gmail.com>
parent 928296ea
......@@ -34,10 +34,9 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
.ctl_offs = SPM_DIS_PWR_CON,
.sram_pdn_bits = GENMASK(11, 8),
.sram_pdn_ack_bits = GENMASK(12, 12),
.bp_infracfg[0] = {
.bus_prot_reg_update = true,
.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
MT8173_TOP_AXI_PROT_EN_MM_M1,
.bp_infracfg = {
BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MM_M0 |
MT8173_TOP_AXI_PROT_EN_MM_M1),
},
},
[MT8173_POWER_DOMAIN_VENC_LT] = {
......@@ -76,12 +75,11 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
.ctl_offs = SPM_MFG_PWR_CON,
.sram_pdn_bits = GENMASK(13, 8),
.sram_pdn_ack_bits = GENMASK(21, 16),
.bp_infracfg[0] = {
.bus_prot_reg_update = true,
.bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
MT8173_TOP_AXI_PROT_EN_MFG_M0 |
MT8173_TOP_AXI_PROT_EN_MFG_M1 |
MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
.bp_infracfg = {
BUS_PROT_UPDATE_TOPAXI(MT8173_TOP_AXI_PROT_EN_MFG_S |
MT8173_TOP_AXI_PROT_EN_MFG_M0 |
MT8173_TOP_AXI_PROT_EN_MFG_M1 |
MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT),
},
},
};
......
......@@ -32,6 +32,7 @@ struct scpsys_domain {
int num_clks;
struct clk_bulk_data *clks;
struct regmap *infracfg;
struct regmap *smi;
};
struct scpsys {
......@@ -99,9 +100,9 @@ static int _scpsys_bus_protect_enable(const struct scpsys_bus_prot_data *bpd, st
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);
regmap_write(regmap, bpd[i].bus_prot_set, mask);
ret = regmap_read_poll_timeout(regmap, INFRA_TOPAXI_PROTECTSTA1,
ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
val, (val & mask) == mask,
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
if (ret)
......@@ -116,8 +117,10 @@ static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
int ret;
ret = _scpsys_bus_protect_enable(pd->data->bp_infracfg, pd->infracfg);
if (ret)
return ret;
return ret;
return _scpsys_bus_protect_enable(pd->data->bp_smi, pd->smi);
}
static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd,
......@@ -134,9 +137,9 @@ static int _scpsys_bus_protect_disable(const struct scpsys_bus_prot_data *bpd,
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);
regmap_write(regmap, bpd[i].bus_prot_clr, mask);
ret = regmap_read_poll_timeout(regmap, INFRA_TOPAXI_PROTECTSTA1,
ret = regmap_read_poll_timeout(regmap, bpd[i].bus_prot_sta,
val, !(val & mask),
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
if (ret)
......@@ -150,9 +153,11 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
{
int ret;
ret = _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg);
ret = _scpsys_bus_protect_disable(pd->data->bp_smi, pd->smi);
if (ret)
return ret;
return ret;
return _scpsys_bus_protect_disable(pd->data->bp_infracfg, pd->infracfg);
}
static int scpsys_power_on(struct generic_pm_domain *genpd)
......@@ -267,6 +272,10 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
if (IS_ERR(pd->infracfg))
return ERR_CAST(pd->infracfg);
pd->smi = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,smi");
if (IS_ERR(pd->smi))
return ERR_CAST(pd->smi);
pd->num_clks = of_clk_get_parent_count(node);
if (pd->num_clks > 0) {
pd->clks = devm_kcalloc(scpsys->dev, pd->num_clks, sizeof(*pd->clks), GFP_KERNEL);
......
......@@ -34,8 +34,31 @@
#define SPM_MAX_BUS_PROT_DATA 5
#define _BUS_PROT(_mask, _set, _clr, _sta, _update) { \
.bus_prot_mask = (_mask), \
.bus_prot_set = _set, \
.bus_prot_clr = _clr, \
.bus_prot_sta = _sta, \
.bus_prot_reg_update = _update, \
}
#define BUS_PROT_WR(_mask, _set, _clr, _sta) \
_BUS_PROT(_mask, _set, _clr, _sta, false)
#define BUS_PROT_UPDATE(_mask, _set, _clr, _sta) \
_BUS_PROT(_mask, _set, _clr, _sta, true)
#define BUS_PROT_UPDATE_TOPAXI(_mask) \
BUS_PROT_UPDATE(_mask, \
INFRA_TOPAXI_PROTECTEN, \
INFRA_TOPAXI_PROTECTEN_CLR, \
INFRA_TOPAXI_PROTECTSTA1)
struct scpsys_bus_prot_data {
u32 bus_prot_mask;
u32 bus_prot_set;
u32 bus_prot_clr;
u32 bus_prot_sta;
bool bus_prot_reg_update;
};
......@@ -47,6 +70,7 @@ struct scpsys_bus_prot_data {
* @sram_pdn_ack_bits: The mask for sram power control acked bits.
* @caps: The flag for active wake-up action.
* @bp_infracfg: bus protection for infracfg subsystem
* @bp_smi: bus protection for smi subsystem
*/
struct scpsys_domain_data {
u32 sta_mask;
......@@ -55,6 +79,7 @@ struct scpsys_domain_data {
u32 sram_pdn_ack_bits;
u8 caps;
const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
};
struct scpsys_soc_data {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment