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: Matthias Brugger <mbrugger@suse.com> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com> Link: https://lore.kernel.org/r/20201030113622.201188-7-enric.balletbo@collabora.com Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
This commit is contained in:
Родитель
928296ea5d
Коммит
f414854c88
|
@ -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 |
|
||||
.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,
|
||||
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 _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 _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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче