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

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.com


Signed-off-by: default avatarMatthias Brugger <matthias.bgg@gmail.com>
parent 928296ea
Loading
Loading
Loading
Loading
+8 −10
Original line number Diff line number Diff line
@@ -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),
		},
	},
};
+16 −7
Original line number Diff line number Diff line
@@ -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);
+25 −0
Original line number Diff line number Diff line
@@ -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 {