All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] soc: mediatek: pm-domains: solve power domain glitch issue
@ 2024-03-25 12:19 ` yu-chang.lee
  0 siblings, 0 replies; 16+ messages in thread
From: yu-chang.lee @ 2024-03-25 12:19 UTC (permalink / raw)
  To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li, yu-chang.lee

Hi,

This series aims to solve power-off failures and occasional SMI hang issues that
occur during camera stress tests. The issue arises because, when MTCMOS powers on
or off, signal glitches are sometimes produced. This is fairly normal, but the 
software must address it to avoid mistaking the glitch for a transaction signal.

The solutions in these patches can be summarized as follows:

1. Disable the sub-common port after turning off the Larb CG and before turning 
   off the Larb MTCMOS.
2. Use CLAMP to disable/enable the SMI common port.
3. Implement an AXI reset.
For previous discussion on the direction of the code modifications, please refer
to: https://lore.kernel.org/linux-arm-kernel/c476cc48-17ec-4e14-98d8-35bdffb5d296@collabora.com/


yu-chang.lee (2):
  soc: mediatek: pm-domains: add smi_larb_reset function when power on
  soc: mediatek: pm-domains: support smi clamp protection

 drivers/pmdomain/mediatek/mt8188-pm-domains.h |  69 +++++-
 drivers/pmdomain/mediatek/mtk-pm-domains.c    | 206 +++++++++++++++---
 drivers/pmdomain/mediatek/mtk-pm-domains.h    |  13 ++
 3 files changed, 255 insertions(+), 33 deletions(-)

-- 
2.18.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 0/2] soc: mediatek: pm-domains: solve power domain glitch issue
@ 2024-03-25 12:19 ` yu-chang.lee
  0 siblings, 0 replies; 16+ messages in thread
From: yu-chang.lee @ 2024-03-25 12:19 UTC (permalink / raw)
  To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li, yu-chang.lee

Hi,

This series aims to solve power-off failures and occasional SMI hang issues that
occur during camera stress tests. The issue arises because, when MTCMOS powers on
or off, signal glitches are sometimes produced. This is fairly normal, but the 
software must address it to avoid mistaking the glitch for a transaction signal.

The solutions in these patches can be summarized as follows:

1. Disable the sub-common port after turning off the Larb CG and before turning 
   off the Larb MTCMOS.
2. Use CLAMP to disable/enable the SMI common port.
3. Implement an AXI reset.
For previous discussion on the direction of the code modifications, please refer
to: https://lore.kernel.org/linux-arm-kernel/c476cc48-17ec-4e14-98d8-35bdffb5d296@collabora.com/


yu-chang.lee (2):
  soc: mediatek: pm-domains: add smi_larb_reset function when power on
  soc: mediatek: pm-domains: support smi clamp protection

 drivers/pmdomain/mediatek/mt8188-pm-domains.h |  69 +++++-
 drivers/pmdomain/mediatek/mtk-pm-domains.c    | 206 +++++++++++++++---
 drivers/pmdomain/mediatek/mtk-pm-domains.h    |  13 ++
 3 files changed, 255 insertions(+), 33 deletions(-)

-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/2] soc: mediatek: pm-domains: add smi_larb_reset function when power on
  2024-03-25 12:19 ` yu-chang.lee
@ 2024-03-25 12:19   ` yu-chang.lee
  -1 siblings, 0 replies; 16+ messages in thread
From: yu-chang.lee @ 2024-03-25 12:19 UTC (permalink / raw)
  To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li, yu-chang.lee

This patch avoid mtcmos power glitch from happening by set and clear
smi larb reset.

Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
---
 drivers/pmdomain/mediatek/mt8188-pm-domains.h | 28 +++++++++
 drivers/pmdomain/mediatek/mtk-pm-domains.c    | 59 +++++++++++++++++++
 drivers/pmdomain/mediatek/mtk-pm-domains.h    | 12 ++++
 3 files changed, 99 insertions(+)

diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
index 06834ab6597c..7bbba4d56a77 100644
--- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
@@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
+				     MT8188_SMI_LARB10_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB11A_RESET,
+				     MT8188_SMI_LARB11A_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB11C_RESET,
+				     MT8188_SMI_LARB11C_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB11B_RESET,
+				     MT8188_SMI_LARB11B_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
+				     MT8188_SMI_LARB15_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 	[MT8188_POWER_DOMAIN_IPE] = {
@@ -583,6 +595,10 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
+				     MT8188_SMI_LARB12_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
@@ -660,6 +676,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
+				     MT8188_SMI_LARB16A_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
+				     MT8188_SMI_LARB17A_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
@@ -670,6 +692,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
+				     MT8188_SMI_LARB16B_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
+				     MT8188_SMI_LARB17B_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 };
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
index e274e3315fe7..9ab6fa105c8c 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
@@ -48,6 +48,8 @@ struct scpsys_domain {
 	struct regmap *infracfg_nao;
 	struct regmap *infracfg;
 	struct regmap *smi;
+	struct regmap **larb;
+	int num_larb;
 	struct regulator *supply;
 };
 
@@ -230,6 +232,39 @@ static int scpsys_regulator_disable(struct regulator *supply)
 	return supply ? regulator_disable(supply) : 0;
 }
 
+static int _scpsys_smi_larb_reset(const struct smi_reset_data bpd,
+				  struct regmap *regmap)
+{
+	int ret;
+	u32 mask = bpd.smi_reset_mask;
+
+	if (!mask)
+		return 0;
+
+	ret = regmap_set_bits(regmap, bpd.smi_reset_addr, mask);
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(regmap, bpd.smi_reset_addr, mask);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_smi_larb_reset(struct scpsys_domain *pd)
+{
+	int ret, i;
+
+	for (i = 0; i < pd->num_larb; i++) {
+		ret = _scpsys_smi_larb_reset(pd->data->reset_smi[i], pd->larb[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int scpsys_power_on(struct generic_pm_domain *genpd)
 {
 	struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
@@ -279,6 +314,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	if (ret < 0)
 		goto err_disable_subsys_clks;
 
+	ret = scpsys_smi_larb_reset(pd);
+	if (ret < 0)
+		goto err_disable_subsys_clks;
+
 	ret = scpsys_bus_protect_disable(pd);
 	if (ret < 0)
 		goto err_disable_sram;
@@ -355,6 +394,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 	struct scpsys_domain *pd;
 	struct device_node *root_node = scpsys->dev->of_node;
 	struct device_node *smi_node;
+	struct device_node *larb_node;
 	struct property *prop;
 	const char *clk_name;
 	int i, ret, num_clks;
@@ -418,6 +458,25 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 			return ERR_CAST(pd->smi);
 	}
 
+	pd->num_larb = of_count_phandle_with_args(node, "mediatek,larb", NULL);
+	if (pd->num_larb > 0) {
+		pd->larb = devm_kcalloc(scpsys->dev, pd->num_larb, sizeof(*pd->larb), GFP_KERNEL);
+		if (!pd->larb)
+			return ERR_PTR(-ENOMEM);
+
+		for (i = 0; i < pd->num_larb; i++) {
+			larb_node = of_parse_phandle(node, "mediatek,larb", i);
+			if (!larb_node)
+				return ERR_PTR(-EINVAL);
+
+			pd->larb[i] = device_node_to_regmap(larb_node);
+			if (IS_ERR(pd->larb[i]))
+				return ERR_CAST(pd->larb[i]);
+		}
+	} else {
+		pd->num_larb = 0;
+	}
+
 	if (MTK_SCPD_CAPS(pd, MTK_SCPD_HAS_INFRA_NAO)) {
 		pd->infracfg_nao = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao");
 		if (IS_ERR(pd->infracfg_nao))
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h
index aaba5e6b0536..31c2a1bb500f 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h
@@ -43,6 +43,7 @@
 #define PWR_STATUS_USB			BIT(25)
 
 #define SPM_MAX_BUS_PROT_DATA		6
+#define SPM_MAX_SMI_RESET_DATA		6
 
 enum scpsys_bus_prot_flags {
 	BUS_PROT_REG_UPDATE = BIT(1),
@@ -79,6 +80,16 @@ enum scpsys_bus_prot_flags {
 				INFRA_TOPAXI_PROTECTEN,		\
 				INFRA_TOPAXI_PROTECTSTA1)
 
+#define SMI_RESET_WR(_mask, _addr) {		\
+		.smi_reset_mask = (_mask),	\
+		.smi_reset_addr = _addr,	\
+	}
+
+struct smi_reset_data {
+	u32 smi_reset_mask;
+	u32 smi_reset_addr;
+};
+
 struct scpsys_bus_prot_data {
 	u32 bus_prot_set_clr_mask;
 	u32 bus_prot_set;
@@ -110,6 +121,7 @@ struct scpsys_domain_data {
 	u32 ext_buck_iso_mask;
 	u16 caps;
 	const struct scpsys_bus_prot_data bp_cfg[SPM_MAX_BUS_PROT_DATA];
+	const struct smi_reset_data reset_smi[SPM_MAX_SMI_RESET_DATA];
 	int pwr_sta_offs;
 	int pwr_sta2nd_offs;
 };
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 1/2] soc: mediatek: pm-domains: add smi_larb_reset function when power on
@ 2024-03-25 12:19   ` yu-chang.lee
  0 siblings, 0 replies; 16+ messages in thread
From: yu-chang.lee @ 2024-03-25 12:19 UTC (permalink / raw)
  To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li, yu-chang.lee

This patch avoid mtcmos power glitch from happening by set and clear
smi larb reset.

Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
---
 drivers/pmdomain/mediatek/mt8188-pm-domains.h | 28 +++++++++
 drivers/pmdomain/mediatek/mtk-pm-domains.c    | 59 +++++++++++++++++++
 drivers/pmdomain/mediatek/mtk-pm-domains.h    | 12 ++++
 3 files changed, 99 insertions(+)

diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
index 06834ab6597c..7bbba4d56a77 100644
--- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
@@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
+				     MT8188_SMI_LARB10_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB11A_RESET,
+				     MT8188_SMI_LARB11A_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB11C_RESET,
+				     MT8188_SMI_LARB11C_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB11B_RESET,
+				     MT8188_SMI_LARB11B_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
+				     MT8188_SMI_LARB15_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 	[MT8188_POWER_DOMAIN_IPE] = {
@@ -583,6 +595,10 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
+				     MT8188_SMI_LARB12_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
@@ -660,6 +676,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
+				     MT8188_SMI_LARB16A_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
+				     MT8188_SMI_LARB17A_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
@@ -670,6 +692,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.reset_smi = {
+			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
+				     MT8188_SMI_LARB16B_RESET_ADDR),
+			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
+				     MT8188_SMI_LARB17B_RESET_ADDR),
+		},
 		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
 	},
 };
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
index e274e3315fe7..9ab6fa105c8c 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
@@ -48,6 +48,8 @@ struct scpsys_domain {
 	struct regmap *infracfg_nao;
 	struct regmap *infracfg;
 	struct regmap *smi;
+	struct regmap **larb;
+	int num_larb;
 	struct regulator *supply;
 };
 
@@ -230,6 +232,39 @@ static int scpsys_regulator_disable(struct regulator *supply)
 	return supply ? regulator_disable(supply) : 0;
 }
 
+static int _scpsys_smi_larb_reset(const struct smi_reset_data bpd,
+				  struct regmap *regmap)
+{
+	int ret;
+	u32 mask = bpd.smi_reset_mask;
+
+	if (!mask)
+		return 0;
+
+	ret = regmap_set_bits(regmap, bpd.smi_reset_addr, mask);
+	if (ret)
+		return ret;
+
+	ret = regmap_clear_bits(regmap, bpd.smi_reset_addr, mask);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_smi_larb_reset(struct scpsys_domain *pd)
+{
+	int ret, i;
+
+	for (i = 0; i < pd->num_larb; i++) {
+		ret = _scpsys_smi_larb_reset(pd->data->reset_smi[i], pd->larb[i]);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static int scpsys_power_on(struct generic_pm_domain *genpd)
 {
 	struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
@@ -279,6 +314,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	if (ret < 0)
 		goto err_disable_subsys_clks;
 
+	ret = scpsys_smi_larb_reset(pd);
+	if (ret < 0)
+		goto err_disable_subsys_clks;
+
 	ret = scpsys_bus_protect_disable(pd);
 	if (ret < 0)
 		goto err_disable_sram;
@@ -355,6 +394,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 	struct scpsys_domain *pd;
 	struct device_node *root_node = scpsys->dev->of_node;
 	struct device_node *smi_node;
+	struct device_node *larb_node;
 	struct property *prop;
 	const char *clk_name;
 	int i, ret, num_clks;
@@ -418,6 +458,25 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 			return ERR_CAST(pd->smi);
 	}
 
+	pd->num_larb = of_count_phandle_with_args(node, "mediatek,larb", NULL);
+	if (pd->num_larb > 0) {
+		pd->larb = devm_kcalloc(scpsys->dev, pd->num_larb, sizeof(*pd->larb), GFP_KERNEL);
+		if (!pd->larb)
+			return ERR_PTR(-ENOMEM);
+
+		for (i = 0; i < pd->num_larb; i++) {
+			larb_node = of_parse_phandle(node, "mediatek,larb", i);
+			if (!larb_node)
+				return ERR_PTR(-EINVAL);
+
+			pd->larb[i] = device_node_to_regmap(larb_node);
+			if (IS_ERR(pd->larb[i]))
+				return ERR_CAST(pd->larb[i]);
+		}
+	} else {
+		pd->num_larb = 0;
+	}
+
 	if (MTK_SCPD_CAPS(pd, MTK_SCPD_HAS_INFRA_NAO)) {
 		pd->infracfg_nao = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao");
 		if (IS_ERR(pd->infracfg_nao))
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h
index aaba5e6b0536..31c2a1bb500f 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h
@@ -43,6 +43,7 @@
 #define PWR_STATUS_USB			BIT(25)
 
 #define SPM_MAX_BUS_PROT_DATA		6
+#define SPM_MAX_SMI_RESET_DATA		6
 
 enum scpsys_bus_prot_flags {
 	BUS_PROT_REG_UPDATE = BIT(1),
@@ -79,6 +80,16 @@ enum scpsys_bus_prot_flags {
 				INFRA_TOPAXI_PROTECTEN,		\
 				INFRA_TOPAXI_PROTECTSTA1)
 
+#define SMI_RESET_WR(_mask, _addr) {		\
+		.smi_reset_mask = (_mask),	\
+		.smi_reset_addr = _addr,	\
+	}
+
+struct smi_reset_data {
+	u32 smi_reset_mask;
+	u32 smi_reset_addr;
+};
+
 struct scpsys_bus_prot_data {
 	u32 bus_prot_set_clr_mask;
 	u32 bus_prot_set;
@@ -110,6 +121,7 @@ struct scpsys_domain_data {
 	u32 ext_buck_iso_mask;
 	u16 caps;
 	const struct scpsys_bus_prot_data bp_cfg[SPM_MAX_BUS_PROT_DATA];
+	const struct smi_reset_data reset_smi[SPM_MAX_SMI_RESET_DATA];
 	int pwr_sta_offs;
 	int pwr_sta2nd_offs;
 };
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
  2024-03-25 12:19 ` yu-chang.lee
@ 2024-03-25 12:19   ` yu-chang.lee
  -1 siblings, 0 replies; 16+ messages in thread
From: yu-chang.lee @ 2024-03-25 12:19 UTC (permalink / raw)
  To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li, yu-chang.lee

In order to avoid power glitch, this patch use smi clamp
to disable/enable smi common port.

Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
---
 drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
 drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147 ++++++++++++++----
 drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
 3 files changed, 156 insertions(+), 33 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
index 7bbba4d56a77..39f057dca92c 100644
--- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
@@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VDO0,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VPP1,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
 				     MT8188_SMI_LARB10_RESET_ADDR),
@@ -585,7 +597,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
 				     MT8188_SMI_LARB15_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 	[MT8188_POWER_DOMAIN_IPE] = {
 		.name = "ipe",
@@ -595,11 +607,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
 				     MT8188_SMI_LARB12_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
 		.name = "cam_vcore",
@@ -676,13 +695,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
 				     MT8188_SMI_LARB16A_RESET_ADDR),
 			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
 				     MT8188_SMI_LARB17A_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
 		.name = "cam_subb",
@@ -692,13 +718,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUBB_TO_VDO0,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
 				     MT8188_SMI_LARB16B_RESET_ADDR),
 			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
 				     MT8188_SMI_LARB17B_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 };
 
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
index 9ab6fa105c8c..3c797e136c0e 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
@@ -47,9 +47,10 @@ struct scpsys_domain {
 	struct clk_bulk_data *subsys_clks;
 	struct regmap *infracfg_nao;
 	struct regmap *infracfg;
-	struct regmap *smi;
+	struct regmap **smi;
 	struct regmap **larb;
 	int num_larb;
+	int num_smi;
 	struct regulator *supply;
 };
 
@@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct scpsys_domain *pd)
 					MTK_POLL_TIMEOUT);
 }
 
-static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd,
-						    const struct scpsys_bus_prot_data *bpd)
-{
-	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
-		return pd->smi;
-	else
-		return pd->infracfg;
-}
-
 static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd,
 							const struct scpsys_bus_prot_data *bpd)
 {
 	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
 		return pd->infracfg_nao;
 	else
-		return scpsys_bus_protect_get_regmap(pd, bpd);
+		return pd->infracfg;
 }
 
 static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
-				    const struct scpsys_bus_prot_data *bpd)
+				    const struct scpsys_bus_prot_data *bpd,
+					struct regmap *sta_regmap, struct regmap *regmap)
 {
-	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
-	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
 	u32 sta_mask = bpd->bus_prot_sta_mask;
 	u32 expected_ack;
 	u32 val;
@@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
 }
 
 static int scpsys_bus_protect_set(struct scpsys_domain *pd,
-				  const struct scpsys_bus_prot_data *bpd)
+				  const struct scpsys_bus_prot_data *bpd,
+				  struct regmap *sta_regmap, struct regmap *regmap)
 {
-	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
-	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
 	u32 sta_mask = bpd->bus_prot_sta_mask;
 	u32 val;
 
@@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct scpsys_domain *pd,
 					MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 }
 
-static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
+static int _scpsys_clamp_bus_protection_enable(struct scpsys_domain *pd, bool is_smi)
 {
+	int smi_count = 0;
+
 	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
 		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
+		struct regmap *sta_regmap, *regmap;
+		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
 		int ret;
 
 		if (!bpd->bus_prot_set_clr_mask)
 			break;
 
+		if (is_smi) {
+			sta_regmap = pd->smi[smi_count];
+			regmap = pd->smi[smi_count];
+			smi_count++;
+		} else {
+			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
+			regmap = pd->infracfg;
+		}
+
 		if (bpd->flags & BUS_PROT_INVERTED)
-			ret = scpsys_bus_protect_clear(pd, bpd);
+			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
 		else
-			ret = scpsys_bus_protect_set(pd, bpd);
+			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
 		if (ret)
 			return ret;
 	}
@@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct scpsys_domain *pd, bool is_smi)
 {
+	int smi_count = pd->num_smi - 1;
+
 	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
 		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
+		struct regmap *sta_regmap, *regmap;
+		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
 		int ret;
 
 		if (!bpd->bus_prot_set_clr_mask)
 			continue;
 
+		if (is_smi) {
+			sta_regmap = pd->smi[smi_count];
+			regmap = pd->smi[smi_count];
+			smi_count--;
+		} else {
+			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
+			regmap = pd->infracfg;
+		}
+
 		if (bpd->flags & BUS_PROT_INVERTED)
-			ret = scpsys_bus_protect_set(pd, bpd);
+			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
 		else
-			ret = scpsys_bus_protect_clear(pd, bpd);
+			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
 		if (ret)
 			return ret;
 	}
@@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
 	return 0;
 }
 
+static int scpsys_clamp_protection(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_enable(pd, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_clamp_protection_disable(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_disable(pd, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_enable(pd, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_disable(pd, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int scpsys_regulator_enable(struct regulator *supply)
 {
 	return supply ? regulator_enable(supply) : 0;
@@ -272,6 +332,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	bool tmp;
 	int ret;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
+		ret = scpsys_clamp_protection(pd);
+		if (ret)
+			return ret;
+	}
+
 	ret = scpsys_regulator_enable(pd->supply);
 	if (ret)
 		return ret;
@@ -318,6 +384,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	if (ret < 0)
 		goto err_disable_subsys_clks;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
+		ret = scpsys_clamp_protection_disable(pd);
+		if (ret)
+			return ret;
+	}
+
 	ret = scpsys_bus_protect_disable(pd);
 	if (ret < 0)
 		goto err_disable_sram;
@@ -353,6 +425,12 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	bool tmp;
 	int ret;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
+		ret = scpsys_clamp_protection(pd);
+		if (ret)
+			return ret;
+	}
+
 	ret = scpsys_bus_protect_enable(pd);
 	if (ret < 0)
 		return ret;
@@ -450,12 +528,23 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 	if (IS_ERR(pd->infracfg))
 		return ERR_CAST(pd->infracfg);
 
-	smi_node = of_parse_phandle(node, "mediatek,smi", 0);
-	if (smi_node) {
-		pd->smi = device_node_to_regmap(smi_node);
-		of_node_put(smi_node);
-		if (IS_ERR(pd->smi))
-			return ERR_CAST(pd->smi);
+	pd->num_smi = of_count_phandle_with_args(node, "mediatek,smi", NULL);
+	if (pd->num_smi > 0) {
+		pd->smi = devm_kcalloc(scpsys->dev, pd->num_smi, sizeof(*pd->smi), GFP_KERNEL);
+		if (!pd->smi)
+			return ERR_PTR(-ENOMEM);
+
+		for (i = 0; i < pd->num_smi; i++) {
+			smi_node = of_parse_phandle(node, "mediatek,smi", i);
+			if (!smi_node)
+				return ERR_PTR(-EINVAL);
+
+			pd->smi[i] = device_node_to_regmap(smi_node);
+			if (IS_ERR(pd->smi[i]))
+				return ERR_CAST(pd->smi[i]);
+		}
+	} else {
+		pd->num_smi = 0;
 	}
 
 	pd->num_larb = of_count_phandle_with_args(node, "mediatek,larb", NULL);
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h
index 31c2a1bb500f..e0eb7214719e 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h
@@ -13,6 +13,7 @@
 #define MTK_SCPD_EXT_BUCK_ISO		BIT(6)
 #define MTK_SCPD_HAS_INFRA_NAO		BIT(7)
 #define MTK_SCPD_STRICT_BUS_PROTECTION	BIT(8)
+#define MTK_SCPD_CLAMP_PROTECTION	BIT(9)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
-- 
2.18.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
@ 2024-03-25 12:19   ` yu-chang.lee
  0 siblings, 0 replies; 16+ messages in thread
From: yu-chang.lee @ 2024-03-25 12:19 UTC (permalink / raw)
  To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li, yu-chang.lee

In order to avoid power glitch, this patch use smi clamp
to disable/enable smi common port.

Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
---
 drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
 drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147 ++++++++++++++----
 drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
 3 files changed, 156 insertions(+), 33 deletions(-)

diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
index 7bbba4d56a77..39f057dca92c 100644
--- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
@@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VDO0,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VPP1,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
 				     MT8188_SMI_LARB10_RESET_ADDR),
@@ -585,7 +597,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
 				     MT8188_SMI_LARB15_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 	[MT8188_POWER_DOMAIN_IPE] = {
 		.name = "ipe",
@@ -595,11 +607,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
 				     MT8188_SMI_LARB12_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
 		.name = "cam_vcore",
@@ -676,13 +695,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
 				     MT8188_SMI_LARB16A_RESET_ADDR),
 			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
 				     MT8188_SMI_LARB17A_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
 		.name = "cam_subb",
@@ -692,13 +718,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
 		.pwr_sta2nd_offs = 0x170,
 		.sram_pdn_bits = BIT(8),
 		.sram_pdn_ack_bits = BIT(12),
+		.bp_cfg = {
+			BUS_PROT_WR(SMI,
+				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUBB_TO_VDO0,
+				    MT8188_SMI_COMMON_CLAMP_EN_SET,
+				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
+				    MT8188_SMI_COMMON_CLAMP_EN_STA),
+		},
 		.reset_smi = {
 			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
 				     MT8188_SMI_LARB16B_RESET_ADDR),
 			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
 				     MT8188_SMI_LARB17B_RESET_ADDR),
 		},
-		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
 	},
 };
 
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
index 9ab6fa105c8c..3c797e136c0e 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
@@ -47,9 +47,10 @@ struct scpsys_domain {
 	struct clk_bulk_data *subsys_clks;
 	struct regmap *infracfg_nao;
 	struct regmap *infracfg;
-	struct regmap *smi;
+	struct regmap **smi;
 	struct regmap **larb;
 	int num_larb;
+	int num_smi;
 	struct regulator *supply;
 };
 
@@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct scpsys_domain *pd)
 					MTK_POLL_TIMEOUT);
 }
 
-static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd,
-						    const struct scpsys_bus_prot_data *bpd)
-{
-	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
-		return pd->smi;
-	else
-		return pd->infracfg;
-}
-
 static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd,
 							const struct scpsys_bus_prot_data *bpd)
 {
 	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
 		return pd->infracfg_nao;
 	else
-		return scpsys_bus_protect_get_regmap(pd, bpd);
+		return pd->infracfg;
 }
 
 static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
-				    const struct scpsys_bus_prot_data *bpd)
+				    const struct scpsys_bus_prot_data *bpd,
+					struct regmap *sta_regmap, struct regmap *regmap)
 {
-	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
-	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
 	u32 sta_mask = bpd->bus_prot_sta_mask;
 	u32 expected_ack;
 	u32 val;
@@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
 }
 
 static int scpsys_bus_protect_set(struct scpsys_domain *pd,
-				  const struct scpsys_bus_prot_data *bpd)
+				  const struct scpsys_bus_prot_data *bpd,
+				  struct regmap *sta_regmap, struct regmap *regmap)
 {
-	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
-	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
 	u32 sta_mask = bpd->bus_prot_sta_mask;
 	u32 val;
 
@@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct scpsys_domain *pd,
 					MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
 }
 
-static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
+static int _scpsys_clamp_bus_protection_enable(struct scpsys_domain *pd, bool is_smi)
 {
+	int smi_count = 0;
+
 	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
 		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
+		struct regmap *sta_regmap, *regmap;
+		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
 		int ret;
 
 		if (!bpd->bus_prot_set_clr_mask)
 			break;
 
+		if (is_smi) {
+			sta_regmap = pd->smi[smi_count];
+			regmap = pd->smi[smi_count];
+			smi_count++;
+		} else {
+			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
+			regmap = pd->infracfg;
+		}
+
 		if (bpd->flags & BUS_PROT_INVERTED)
-			ret = scpsys_bus_protect_clear(pd, bpd);
+			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
 		else
-			ret = scpsys_bus_protect_set(pd, bpd);
+			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
 		if (ret)
 			return ret;
 	}
@@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct scpsys_domain *pd, bool is_smi)
 {
+	int smi_count = pd->num_smi - 1;
+
 	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
 		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
+		struct regmap *sta_regmap, *regmap;
+		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
 		int ret;
 
 		if (!bpd->bus_prot_set_clr_mask)
 			continue;
 
+		if (is_smi) {
+			sta_regmap = pd->smi[smi_count];
+			regmap = pd->smi[smi_count];
+			smi_count--;
+		} else {
+			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
+			regmap = pd->infracfg;
+		}
+
 		if (bpd->flags & BUS_PROT_INVERTED)
-			ret = scpsys_bus_protect_set(pd, bpd);
+			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
 		else
-			ret = scpsys_bus_protect_clear(pd, bpd);
+			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
 		if (ret)
 			return ret;
 	}
@@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
 	return 0;
 }
 
+static int scpsys_clamp_protection(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_enable(pd, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_clamp_protection_disable(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_disable(pd, true);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_enable(pd, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
+{
+	int ret;
+
+	ret = _scpsys_clamp_bus_protection_disable(pd, false);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static int scpsys_regulator_enable(struct regulator *supply)
 {
 	return supply ? regulator_enable(supply) : 0;
@@ -272,6 +332,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	bool tmp;
 	int ret;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
+		ret = scpsys_clamp_protection(pd);
+		if (ret)
+			return ret;
+	}
+
 	ret = scpsys_regulator_enable(pd->supply);
 	if (ret)
 		return ret;
@@ -318,6 +384,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
 	if (ret < 0)
 		goto err_disable_subsys_clks;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
+		ret = scpsys_clamp_protection_disable(pd);
+		if (ret)
+			return ret;
+	}
+
 	ret = scpsys_bus_protect_disable(pd);
 	if (ret < 0)
 		goto err_disable_sram;
@@ -353,6 +425,12 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
 	bool tmp;
 	int ret;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
+		ret = scpsys_clamp_protection(pd);
+		if (ret)
+			return ret;
+	}
+
 	ret = scpsys_bus_protect_enable(pd);
 	if (ret < 0)
 		return ret;
@@ -450,12 +528,23 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 	if (IS_ERR(pd->infracfg))
 		return ERR_CAST(pd->infracfg);
 
-	smi_node = of_parse_phandle(node, "mediatek,smi", 0);
-	if (smi_node) {
-		pd->smi = device_node_to_regmap(smi_node);
-		of_node_put(smi_node);
-		if (IS_ERR(pd->smi))
-			return ERR_CAST(pd->smi);
+	pd->num_smi = of_count_phandle_with_args(node, "mediatek,smi", NULL);
+	if (pd->num_smi > 0) {
+		pd->smi = devm_kcalloc(scpsys->dev, pd->num_smi, sizeof(*pd->smi), GFP_KERNEL);
+		if (!pd->smi)
+			return ERR_PTR(-ENOMEM);
+
+		for (i = 0; i < pd->num_smi; i++) {
+			smi_node = of_parse_phandle(node, "mediatek,smi", i);
+			if (!smi_node)
+				return ERR_PTR(-EINVAL);
+
+			pd->smi[i] = device_node_to_regmap(smi_node);
+			if (IS_ERR(pd->smi[i]))
+				return ERR_CAST(pd->smi[i]);
+		}
+	} else {
+		pd->num_smi = 0;
 	}
 
 	pd->num_larb = of_count_phandle_with_args(node, "mediatek,larb", NULL);
diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.h b/drivers/pmdomain/mediatek/mtk-pm-domains.h
index 31c2a1bb500f..e0eb7214719e 100644
--- a/drivers/pmdomain/mediatek/mtk-pm-domains.h
+++ b/drivers/pmdomain/mediatek/mtk-pm-domains.h
@@ -13,6 +13,7 @@
 #define MTK_SCPD_EXT_BUCK_ISO		BIT(6)
 #define MTK_SCPD_HAS_INFRA_NAO		BIT(7)
 #define MTK_SCPD_STRICT_BUS_PROTECTION	BIT(8)
+#define MTK_SCPD_CLAMP_PROTECTION	BIT(9)
 #define MTK_SCPD_CAPS(_scpd, _x)	((_scpd)->data->caps & (_x))
 
 #define SPM_VDE_PWR_CON			0x0210
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] soc: mediatek: pm-domains: add smi_larb_reset function when power on
  2024-03-25 12:19   ` yu-chang.lee
@ 2024-03-25 12:58     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-25 12:58 UTC (permalink / raw)
  To: yu-chang.lee, Ulf Hansson, Matthias Brugger
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li

Il 25/03/24 13:19, yu-chang.lee ha scritto:
> This patch avoid mtcmos power glitch from happening by set and clear
> smi larb reset.
> 
> Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
> ---
>   drivers/pmdomain/mediatek/mt8188-pm-domains.h | 28 +++++++++
>   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 59 +++++++++++++++++++
>   drivers/pmdomain/mediatek/mtk-pm-domains.h    | 12 ++++
>   3 files changed, 99 insertions(+)
> 
> diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> index 06834ab6597c..7bbba4d56a77 100644
> --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> @@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
> +				     MT8188_SMI_LARB10_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB11A_RESET,
> +				     MT8188_SMI_LARB11A_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB11C_RESET,
> +				     MT8188_SMI_LARB11C_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB11B_RESET,
> +				     MT8188_SMI_LARB11B_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
> +				     MT8188_SMI_LARB15_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   	[MT8188_POWER_DOMAIN_IPE] = {
> @@ -583,6 +595,10 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
> +				     MT8188_SMI_LARB12_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
> @@ -660,6 +676,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
> +				     MT8188_SMI_LARB16A_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
> +				     MT8188_SMI_LARB17A_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
> @@ -670,6 +692,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
> +				     MT8188_SMI_LARB16B_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
> +				     MT8188_SMI_LARB17B_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   };
> diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> index e274e3315fe7..9ab6fa105c8c 100644
> --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> @@ -48,6 +48,8 @@ struct scpsys_domain {
>   	struct regmap *infracfg_nao;
>   	struct regmap *infracfg;
>   	struct regmap *smi;
> +	struct regmap **larb;
> +	int num_larb;
>   	struct regulator *supply;
>   };
>   
> @@ -230,6 +232,39 @@ static int scpsys_regulator_disable(struct regulator *supply)
>   	return supply ? regulator_disable(supply) : 0;
>   }
>   
> +static int _scpsys_smi_larb_reset(const struct smi_reset_data bpd,
> +				  struct regmap *regmap)
> +{
> +	int ret;
> +	u32 mask = bpd.smi_reset_mask;
> +
> +	if (!mask)
> +		return 0;
> +
> +	ret = regmap_set_bits(regmap, bpd.smi_reset_addr, mask);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_clear_bits(regmap, bpd.smi_reset_addr, mask);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_smi_larb_reset(struct scpsys_domain *pd)
> +{
> +	int ret, i;
> +
> +	for (i = 0; i < pd->num_larb; i++) {
> +		ret = _scpsys_smi_larb_reset(pd->data->reset_smi[i], pd->larb[i]);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
>   static int scpsys_power_on(struct generic_pm_domain *genpd)
>   {
>   	struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
> @@ -279,6 +314,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>   	if (ret < 0)
>   		goto err_disable_subsys_clks;
>   
> +	ret = scpsys_smi_larb_reset(pd);
> +	if (ret < 0)
> +		goto err_disable_subsys_clks;
> +
>   	ret = scpsys_bus_protect_disable(pd);
>   	if (ret < 0)
>   		goto err_disable_sram;
> @@ -355,6 +394,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
>   	struct scpsys_domain *pd;
>   	struct device_node *root_node = scpsys->dev->of_node;
>   	struct device_node *smi_node;
> +	struct device_node *larb_node;
>   	struct property *prop;
>   	const char *clk_name;
>   	int i, ret, num_clks;
> @@ -418,6 +458,25 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
>   			return ERR_CAST(pd->smi);
>   	}
>   
> +	pd->num_larb = of_count_phandle_with_args(node, "mediatek,larb", NULL);

You must update bindings/power/mediatek,power-controller.yaml to allow the
mediatek,larb property in the power controller binding, otherwise this will
be unusable. Please do so.

Cheers,
Angelo


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] soc: mediatek: pm-domains: add smi_larb_reset function when power on
@ 2024-03-25 12:58     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-25 12:58 UTC (permalink / raw)
  To: yu-chang.lee, Ulf Hansson, Matthias Brugger
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li

Il 25/03/24 13:19, yu-chang.lee ha scritto:
> This patch avoid mtcmos power glitch from happening by set and clear
> smi larb reset.
> 
> Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
> ---
>   drivers/pmdomain/mediatek/mt8188-pm-domains.h | 28 +++++++++
>   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 59 +++++++++++++++++++
>   drivers/pmdomain/mediatek/mtk-pm-domains.h    | 12 ++++
>   3 files changed, 99 insertions(+)
> 
> diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> index 06834ab6597c..7bbba4d56a77 100644
> --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> @@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
> +				     MT8188_SMI_LARB10_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB11A_RESET,
> +				     MT8188_SMI_LARB11A_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB11C_RESET,
> +				     MT8188_SMI_LARB11C_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB11B_RESET,
> +				     MT8188_SMI_LARB11B_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
> +				     MT8188_SMI_LARB15_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   	[MT8188_POWER_DOMAIN_IPE] = {
> @@ -583,6 +595,10 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
> +				     MT8188_SMI_LARB12_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
> @@ -660,6 +676,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
> +				     MT8188_SMI_LARB16A_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
> +				     MT8188_SMI_LARB17A_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
> @@ -670,6 +692,12 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.reset_smi = {
> +			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
> +				     MT8188_SMI_LARB16B_RESET_ADDR),
> +			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
> +				     MT8188_SMI_LARB17B_RESET_ADDR),
> +		},
>   		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>   	},
>   };
> diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> index e274e3315fe7..9ab6fa105c8c 100644
> --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> @@ -48,6 +48,8 @@ struct scpsys_domain {
>   	struct regmap *infracfg_nao;
>   	struct regmap *infracfg;
>   	struct regmap *smi;
> +	struct regmap **larb;
> +	int num_larb;
>   	struct regulator *supply;
>   };
>   
> @@ -230,6 +232,39 @@ static int scpsys_regulator_disable(struct regulator *supply)
>   	return supply ? regulator_disable(supply) : 0;
>   }
>   
> +static int _scpsys_smi_larb_reset(const struct smi_reset_data bpd,
> +				  struct regmap *regmap)
> +{
> +	int ret;
> +	u32 mask = bpd.smi_reset_mask;
> +
> +	if (!mask)
> +		return 0;
> +
> +	ret = regmap_set_bits(regmap, bpd.smi_reset_addr, mask);
> +	if (ret)
> +		return ret;
> +
> +	ret = regmap_clear_bits(regmap, bpd.smi_reset_addr, mask);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_smi_larb_reset(struct scpsys_domain *pd)
> +{
> +	int ret, i;
> +
> +	for (i = 0; i < pd->num_larb; i++) {
> +		ret = _scpsys_smi_larb_reset(pd->data->reset_smi[i], pd->larb[i]);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
>   static int scpsys_power_on(struct generic_pm_domain *genpd)
>   {
>   	struct scpsys_domain *pd = container_of(genpd, struct scpsys_domain, genpd);
> @@ -279,6 +314,10 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>   	if (ret < 0)
>   		goto err_disable_subsys_clks;
>   
> +	ret = scpsys_smi_larb_reset(pd);
> +	if (ret < 0)
> +		goto err_disable_subsys_clks;
> +
>   	ret = scpsys_bus_protect_disable(pd);
>   	if (ret < 0)
>   		goto err_disable_sram;
> @@ -355,6 +394,7 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
>   	struct scpsys_domain *pd;
>   	struct device_node *root_node = scpsys->dev->of_node;
>   	struct device_node *smi_node;
> +	struct device_node *larb_node;
>   	struct property *prop;
>   	const char *clk_name;
>   	int i, ret, num_clks;
> @@ -418,6 +458,25 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
>   			return ERR_CAST(pd->smi);
>   	}
>   
> +	pd->num_larb = of_count_phandle_with_args(node, "mediatek,larb", NULL);

You must update bindings/power/mediatek,power-controller.yaml to allow the
mediatek,larb property in the power controller binding, otherwise this will
be unusable. Please do so.

Cheers,
Angelo


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
  2024-03-25 12:19   ` yu-chang.lee
@ 2024-03-25 13:05     ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-25 13:05 UTC (permalink / raw)
  To: yu-chang.lee, Ulf Hansson, Matthias Brugger
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li

Il 25/03/24 13:19, yu-chang.lee ha scritto:
> In order to avoid power glitch, this patch use smi clamp
> to disable/enable smi common port.
> 
> Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
> ---
>   drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
>   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147 ++++++++++++++----
>   drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
>   3 files changed, 156 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> index 7bbba4d56a77..39f057dca92c 100644
> --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> @@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VDO0,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VPP1,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
>   				     MT8188_SMI_LARB10_RESET_ADDR),
> @@ -585,7 +597,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
>   				     MT8188_SMI_LARB15_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   	[MT8188_POWER_DOMAIN_IPE] = {
>   		.name = "ipe",
> @@ -595,11 +607,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
>   				     MT8188_SMI_LARB12_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
>   		.name = "cam_vcore",
> @@ -676,13 +695,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
>   				     MT8188_SMI_LARB16A_RESET_ADDR),
>   			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
>   				     MT8188_SMI_LARB17A_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
>   		.name = "cam_subb",
> @@ -692,13 +718,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUBB_TO_VDO0,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
>   				     MT8188_SMI_LARB16B_RESET_ADDR),
>   			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
>   				     MT8188_SMI_LARB17B_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   };
>   
> diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> index 9ab6fa105c8c..3c797e136c0e 100644
> --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> @@ -47,9 +47,10 @@ struct scpsys_domain {
>   	struct clk_bulk_data *subsys_clks;
>   	struct regmap *infracfg_nao;
>   	struct regmap *infracfg;
> -	struct regmap *smi;
> +	struct regmap **smi;
>   	struct regmap **larb;
>   	int num_larb;
> +	int num_smi;
>   	struct regulator *supply;
>   };
>   
> @@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct scpsys_domain *pd)
>   					MTK_POLL_TIMEOUT);
>   }
>   
> -static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd,
> -						    const struct scpsys_bus_prot_data *bpd)
> -{
> -	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
> -		return pd->smi;
> -	else
> -		return pd->infracfg;
> -}
> -
>   static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd,
>   							const struct scpsys_bus_prot_data *bpd)
>   {
>   	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
>   		return pd->infracfg_nao;
>   	else
> -		return scpsys_bus_protect_get_regmap(pd, bpd);
> +		return pd->infracfg;
>   }
>   
>   static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
> -				    const struct scpsys_bus_prot_data *bpd)
> +				    const struct scpsys_bus_prot_data *bpd,
> +					struct regmap *sta_regmap, struct regmap *regmap)
>   {
> -	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>   	u32 sta_mask = bpd->bus_prot_sta_mask;
>   	u32 expected_ack;
>   	u32 val;
> @@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
>   }
>   
>   static int scpsys_bus_protect_set(struct scpsys_domain *pd,
> -				  const struct scpsys_bus_prot_data *bpd)
> +				  const struct scpsys_bus_prot_data *bpd,
> +				  struct regmap *sta_regmap, struct regmap *regmap)
>   {
> -	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>   	u32 sta_mask = bpd->bus_prot_sta_mask;
>   	u32 val;
>   
> @@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct scpsys_domain *pd,
>   					MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
>   }
>   
> -static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
> +static int _scpsys_clamp_bus_protection_enable(struct scpsys_domain *pd, bool is_smi)
>   {
> +	int smi_count = 0;
> +
>   	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
>   		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
> +		struct regmap *sta_regmap, *regmap;
> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>   		int ret;
>   
>   		if (!bpd->bus_prot_set_clr_mask)
>   			break;
>   
> +		if (is_smi) {
> +			sta_regmap = pd->smi[smi_count];
> +			regmap = pd->smi[smi_count];
> +			smi_count++;
> +		} else {
> +			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> +			regmap = pd->infracfg;
> +		}
> +
>   		if (bpd->flags & BUS_PROT_INVERTED)
> -			ret = scpsys_bus_protect_clear(pd, bpd);
> +			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
>   		else
> -			ret = scpsys_bus_protect_set(pd, bpd);
> +			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
>   		if (ret)
>   			return ret;
>   	}
> @@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct scpsys_domain *pd, bool is_smi)
>   {
> +	int smi_count = pd->num_smi - 1;
> +
>   	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
>   		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
> +		struct regmap *sta_regmap, *regmap;
> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>   		int ret;
>   
>   		if (!bpd->bus_prot_set_clr_mask)
>   			continue;
>   
> +		if (is_smi) {
> +			sta_regmap = pd->smi[smi_count];
> +			regmap = pd->smi[smi_count];
> +			smi_count--;
> +		} else {
> +			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> +			regmap = pd->infracfg;
> +		}
> +
>   		if (bpd->flags & BUS_PROT_INVERTED)
> -			ret = scpsys_bus_protect_set(pd, bpd);
> +			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
>   		else
> -			ret = scpsys_bus_protect_clear(pd, bpd);
> +			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
>   		if (ret)
>   			return ret;
>   	}
> @@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
>   	return 0;
>   }
>   
> +static int scpsys_clamp_protection(struct scpsys_domain *pd)
> +{
> +	int ret;
> +

You can directly call _scpsys_clamp_bus_protection_enable(), no need for a helper.

> +	ret = _scpsys_clamp_bus_protection_enable(pd, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_clamp_protection_disable(struct scpsys_domain *pd)
> +{
> +	int ret;
> +
> +	ret = _scpsys_clamp_bus_protection_disable(pd, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_bus_protect_enable(struct scpsys_domain *pd)

Unused function, please remove.

> +{
> +	int ret;
> +
> +	ret = _scpsys_clamp_bus_protection_enable(pd, false);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
> +{

Unused function, please remove.

> +	int ret;
> +
> +	ret = _scpsys_clamp_bus_protection_disable(pd, false);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
>   static int scpsys_regulator_enable(struct regulator *supply)
>   {
>   	return supply ? regulator_enable(supply) : 0;
> @@ -272,6 +332,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>   	bool tmp;
>   	int ret;
>   
> +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> +		ret = scpsys_clamp_protection(pd);

		ret = scpsys_clamp_bus_protection_enable(pd, true);

> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = scpsys_regulator_enable(pd->supply);
>   	if (ret)
>   		return ret;
> @@ -318,6 +384,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>   	if (ret < 0)
>   		goto err_disable_subsys_clks;
>   
> +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> +		ret = scpsys_clamp_protection_disable(pd);

		ret = scpsys_clamp_bus_protection_disable(pd, true);

> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = scpsys_bus_protect_disable(pd);
>   	if (ret < 0)
>   		goto err_disable_sram;
> @@ -353,6 +425,12 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
>   	bool tmp;
>   	int ret;
>   
> +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> +		ret = scpsys_clamp_protection(pd);

ret = scpsys_clamp_bus_protection_enable(pd, true);

> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = scpsys_bus_protect_enable(pd);
>   	if (ret < 0)
>   		return ret;

Regards,
Angelo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
@ 2024-03-25 13:05     ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-25 13:05 UTC (permalink / raw)
  To: yu-chang.lee, Ulf Hansson, Matthias Brugger
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li

Il 25/03/24 13:19, yu-chang.lee ha scritto:
> In order to avoid power glitch, this patch use smi clamp
> to disable/enable smi common port.
> 
> Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
> ---
>   drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
>   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147 ++++++++++++++----
>   drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
>   3 files changed, 156 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> index 7bbba4d56a77..39f057dca92c 100644
> --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> @@ -573,6 +573,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VDO0,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_VPP1,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
>   				     MT8188_SMI_LARB10_RESET_ADDR),
> @@ -585,7 +597,7 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
>   				     MT8188_SMI_LARB15_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   	[MT8188_POWER_DOMAIN_IPE] = {
>   		.name = "ipe",
> @@ -595,11 +607,18 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
>   				     MT8188_SMI_LARB12_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
>   		.name = "cam_vcore",
> @@ -676,13 +695,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_VPP1,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
>   				     MT8188_SMI_LARB16A_RESET_ADDR),
>   			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
>   				     MT8188_SMI_LARB17A_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
>   		.name = "cam_subb",
> @@ -692,13 +718,20 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8188[] = {
>   		.pwr_sta2nd_offs = 0x170,
>   		.sram_pdn_bits = BIT(8),
>   		.sram_pdn_ack_bits = BIT(12),
> +		.bp_cfg = {
> +			BUS_PROT_WR(SMI,
> +				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUBB_TO_VDO0,
> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> +		},
>   		.reset_smi = {
>   			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
>   				     MT8188_SMI_LARB16B_RESET_ADDR),
>   			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
>   				     MT8188_SMI_LARB17B_RESET_ADDR),
>   		},
> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_CLAMP_PROTECTION,
>   	},
>   };
>   
> diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> index 9ab6fa105c8c..3c797e136c0e 100644
> --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> @@ -47,9 +47,10 @@ struct scpsys_domain {
>   	struct clk_bulk_data *subsys_clks;
>   	struct regmap *infracfg_nao;
>   	struct regmap *infracfg;
> -	struct regmap *smi;
> +	struct regmap **smi;
>   	struct regmap **larb;
>   	int num_larb;
> +	int num_smi;
>   	struct regulator *supply;
>   };
>   
> @@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct scpsys_domain *pd)
>   					MTK_POLL_TIMEOUT);
>   }
>   
> -static struct regmap *scpsys_bus_protect_get_regmap(struct scpsys_domain *pd,
> -						    const struct scpsys_bus_prot_data *bpd)
> -{
> -	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
> -		return pd->smi;
> -	else
> -		return pd->infracfg;
> -}
> -
>   static struct regmap *scpsys_bus_protect_get_sta_regmap(struct scpsys_domain *pd,
>   							const struct scpsys_bus_prot_data *bpd)
>   {
>   	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
>   		return pd->infracfg_nao;
>   	else
> -		return scpsys_bus_protect_get_regmap(pd, bpd);
> +		return pd->infracfg;
>   }
>   
>   static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
> -				    const struct scpsys_bus_prot_data *bpd)
> +				    const struct scpsys_bus_prot_data *bpd,
> +					struct regmap *sta_regmap, struct regmap *regmap)
>   {
> -	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>   	u32 sta_mask = bpd->bus_prot_sta_mask;
>   	u32 expected_ack;
>   	u32 val;
> @@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
>   }
>   
>   static int scpsys_bus_protect_set(struct scpsys_domain *pd,
> -				  const struct scpsys_bus_prot_data *bpd)
> +				  const struct scpsys_bus_prot_data *bpd,
> +				  struct regmap *sta_regmap, struct regmap *regmap)
>   {
> -	struct regmap *sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>   	u32 sta_mask = bpd->bus_prot_sta_mask;
>   	u32 val;
>   
> @@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct scpsys_domain *pd,
>   					MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
>   }
>   
> -static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
> +static int _scpsys_clamp_bus_protection_enable(struct scpsys_domain *pd, bool is_smi)
>   {
> +	int smi_count = 0;
> +
>   	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
>   		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
> +		struct regmap *sta_regmap, *regmap;
> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>   		int ret;
>   
>   		if (!bpd->bus_prot_set_clr_mask)
>   			break;
>   
> +		if (is_smi) {
> +			sta_regmap = pd->smi[smi_count];
> +			regmap = pd->smi[smi_count];
> +			smi_count++;
> +		} else {
> +			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> +			regmap = pd->infracfg;
> +		}
> +
>   		if (bpd->flags & BUS_PROT_INVERTED)
> -			ret = scpsys_bus_protect_clear(pd, bpd);
> +			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
>   		else
> -			ret = scpsys_bus_protect_set(pd, bpd);
> +			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
>   		if (ret)
>   			return ret;
>   	}
> @@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct scpsys_domain *pd, bool is_smi)
>   {
> +	int smi_count = pd->num_smi - 1;
> +
>   	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
>   		const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i];
> +		struct regmap *sta_regmap, *regmap;
> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>   		int ret;
>   
>   		if (!bpd->bus_prot_set_clr_mask)
>   			continue;
>   
> +		if (is_smi) {
> +			sta_regmap = pd->smi[smi_count];
> +			regmap = pd->smi[smi_count];
> +			smi_count--;
> +		} else {
> +			sta_regmap = scpsys_bus_protect_get_sta_regmap(pd, bpd);
> +			regmap = pd->infracfg;
> +		}
> +
>   		if (bpd->flags & BUS_PROT_INVERTED)
> -			ret = scpsys_bus_protect_set(pd, bpd);
> +			ret = scpsys_bus_protect_set(pd, bpd, sta_regmap, regmap);
>   		else
> -			ret = scpsys_bus_protect_clear(pd, bpd);
> +			ret = scpsys_bus_protect_clear(pd, bpd, sta_regmap, regmap);
>   		if (ret)
>   			return ret;
>   	}
> @@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
>   	return 0;
>   }
>   
> +static int scpsys_clamp_protection(struct scpsys_domain *pd)
> +{
> +	int ret;
> +

You can directly call _scpsys_clamp_bus_protection_enable(), no need for a helper.

> +	ret = _scpsys_clamp_bus_protection_enable(pd, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_clamp_protection_disable(struct scpsys_domain *pd)
> +{
> +	int ret;
> +
> +	ret = _scpsys_clamp_bus_protection_disable(pd, true);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_bus_protect_enable(struct scpsys_domain *pd)

Unused function, please remove.

> +{
> +	int ret;
> +
> +	ret = _scpsys_clamp_bus_protection_enable(pd, false);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
> +{

Unused function, please remove.

> +	int ret;
> +
> +	ret = _scpsys_clamp_bus_protection_disable(pd, false);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
>   static int scpsys_regulator_enable(struct regulator *supply)
>   {
>   	return supply ? regulator_enable(supply) : 0;
> @@ -272,6 +332,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>   	bool tmp;
>   	int ret;
>   
> +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> +		ret = scpsys_clamp_protection(pd);

		ret = scpsys_clamp_bus_protection_enable(pd, true);

> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = scpsys_regulator_enable(pd->supply);
>   	if (ret)
>   		return ret;
> @@ -318,6 +384,12 @@ static int scpsys_power_on(struct generic_pm_domain *genpd)
>   	if (ret < 0)
>   		goto err_disable_subsys_clks;
>   
> +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> +		ret = scpsys_clamp_protection_disable(pd);

		ret = scpsys_clamp_bus_protection_disable(pd, true);

> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = scpsys_bus_protect_disable(pd);
>   	if (ret < 0)
>   		goto err_disable_sram;
> @@ -353,6 +425,12 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
>   	bool tmp;
>   	int ret;
>   
> +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> +		ret = scpsys_clamp_protection(pd);

ret = scpsys_clamp_bus_protection_enable(pd, true);

> +		if (ret)
> +			return ret;
> +	}
> +
>   	ret = scpsys_bus_protect_enable(pd);
>   	if (ret < 0)
>   		return ret;

Regards,
Angelo



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/2] soc: mediatek: pm-domains: solve power domain glitch issue
  2024-03-25 12:19 ` yu-chang.lee
@ 2024-03-25 13:06   ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-25 13:06 UTC (permalink / raw)
  To: yu-chang.lee, Ulf Hansson, Matthias Brugger
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li

Il 25/03/24 13:19, yu-chang.lee ha scritto:
> Hi,
> 
> This series aims to solve power-off failures and occasional SMI hang issues that
> occur during camera stress tests. The issue arises because, when MTCMOS powers on
> or off, signal glitches are sometimes produced. This is fairly normal, but the
> software must address it to avoid mistaking the glitch for a transaction signal.
> 
> The solutions in these patches can be summarized as follows:
> 
> 1. Disable the sub-common port after turning off the Larb CG and before turning
>     off the Larb MTCMOS.
> 2. Use CLAMP to disable/enable the SMI common port.
> 3. Implement an AXI reset.
> For previous discussion on the direction of the code modifications, please refer
> to: https://lore.kernel.org/linux-arm-kernel/c476cc48-17ec-4e14-98d8-35bdffb5d296@collabora.com/
> 
> 
> yu-chang.lee (2):
>    soc: mediatek: pm-domains: add smi_larb_reset function when power on
>    soc: mediatek: pm-domains: support smi clamp protection

Can you please change both commit titles to use "pmdomain: mediatek:" instead of
"soc: mediatek:"?

Thanks
Angelo

> 
>   drivers/pmdomain/mediatek/mt8188-pm-domains.h |  69 +++++-
>   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 206 +++++++++++++++---
>   drivers/pmdomain/mediatek/mtk-pm-domains.h    |  13 ++
>   3 files changed, 255 insertions(+), 33 deletions(-)
> 


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/2] soc: mediatek: pm-domains: solve power domain glitch issue
@ 2024-03-25 13:06   ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-25 13:06 UTC (permalink / raw)
  To: yu-chang.lee, Ulf Hansson, Matthias Brugger
  Cc: linux-pm, linux-kernel, linux-arm-kernel, linux-mediatek,
	Project_Global_Chrome_Upstream_Group, mandyjh.liu, fan.chen,
	xiufeng.li

Il 25/03/24 13:19, yu-chang.lee ha scritto:
> Hi,
> 
> This series aims to solve power-off failures and occasional SMI hang issues that
> occur during camera stress tests. The issue arises because, when MTCMOS powers on
> or off, signal glitches are sometimes produced. This is fairly normal, but the
> software must address it to avoid mistaking the glitch for a transaction signal.
> 
> The solutions in these patches can be summarized as follows:
> 
> 1. Disable the sub-common port after turning off the Larb CG and before turning
>     off the Larb MTCMOS.
> 2. Use CLAMP to disable/enable the SMI common port.
> 3. Implement an AXI reset.
> For previous discussion on the direction of the code modifications, please refer
> to: https://lore.kernel.org/linux-arm-kernel/c476cc48-17ec-4e14-98d8-35bdffb5d296@collabora.com/
> 
> 
> yu-chang.lee (2):
>    soc: mediatek: pm-domains: add smi_larb_reset function when power on
>    soc: mediatek: pm-domains: support smi clamp protection

Can you please change both commit titles to use "pmdomain: mediatek:" instead of
"soc: mediatek:"?

Thanks
Angelo

> 
>   drivers/pmdomain/mediatek/mt8188-pm-domains.h |  69 +++++-
>   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 206 +++++++++++++++---
>   drivers/pmdomain/mediatek/mtk-pm-domains.h    |  13 ++
>   3 files changed, 255 insertions(+), 33 deletions(-)
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
  2024-03-25 13:05     ` AngeloGioacchino Del Regno
@ 2024-03-26  2:00       ` Yu-chang Lee (李禹璋)
  -1 siblings, 0 replies; 16+ messages in thread
From: Yu-chang Lee (李禹璋) @ 2024-03-26  2:00 UTC (permalink / raw)
  To: ulf.hansson, matthias.bgg, angelogioacchino.delregno
  Cc: linux-kernel, linux-mediatek, linux-pm,
	MandyJH Liu (劉人僖),
	Project_Global_Chrome_Upstream_Group,
	Xiufeng Li (李秀峰),
	linux-arm-kernel, Fan Chen (陳凡)

On Mon, 2024-03-25 at 14:05 +0100, AngeloGioacchino Del Regno wrote:
> Il 25/03/24 13:19, yu-chang.lee ha scritto:
> > In order to avoid power glitch, this patch use smi clamp
> > to disable/enable smi common port.
> > 
> > Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
> > ---
> >   drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
> >   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147
> > ++++++++++++++----
> >   drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
> >   3 files changed, 156 insertions(+), 33 deletions(-)
> > 
> > diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > index 7bbba4d56a77..39f057dca92c 100644
> > --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > @@ -573,6 +573,18 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
> > VDO0,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
> > VPP1,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
> >   				     MT8188_SMI_LARB10_RESET_ADDR),
> > @@ -585,7 +597,7 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
> >   				     MT8188_SMI_LARB15_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   	[MT8188_POWER_DOMAIN_IPE] = {
> >   		.name = "ipe",
> > @@ -595,11 +607,18 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
> > VPP1,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
> >   				     MT8188_SMI_LARB12_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
> >   		.name = "cam_vcore",
> > @@ -676,13 +695,20 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
> > VPP1,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
> >   				     MT8188_SMI_LARB16A_RESET_ADDR),
> >   			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
> >   				     MT8188_SMI_LARB17A_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
> >   		.name = "cam_subb",
> > @@ -692,13 +718,20 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUB
> > B_TO_VDO0,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
> >   				     MT8188_SMI_LARB16B_RESET_ADDR),
> >   			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
> >   				     MT8188_SMI_LARB17B_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   };
> >   
> > diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > index 9ab6fa105c8c..3c797e136c0e 100644
> > --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > @@ -47,9 +47,10 @@ struct scpsys_domain {
> >   	struct clk_bulk_data *subsys_clks;
> >   	struct regmap *infracfg_nao;
> >   	struct regmap *infracfg;
> > -	struct regmap *smi;
> > +	struct regmap **smi;
> >   	struct regmap **larb;
> >   	int num_larb;
> > +	int num_smi;
> >   	struct regulator *supply;
> >   };
> >   
> > @@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct
> > scpsys_domain *pd)
> >   					MTK_POLL_TIMEOUT);
> >   }
> >   
> > -static struct regmap *scpsys_bus_protect_get_regmap(struct
> > scpsys_domain *pd,
> > -						    const struct
> > scpsys_bus_prot_data *bpd)
> > -{
> > -	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
> > -		return pd->smi;
> > -	else
> > -		return pd->infracfg;
> > -}
> > -
> >   static struct regmap *scpsys_bus_protect_get_sta_regmap(struct
> > scpsys_domain *pd,
> >   							const struct
> > scpsys_bus_prot_data *bpd)
> >   {
> >   	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
> >   		return pd->infracfg_nao;
> >   	else
> > -		return scpsys_bus_protect_get_regmap(pd, bpd);
> > +		return pd->infracfg;
> >   }
> >   
> >   static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
> > -				    const struct scpsys_bus_prot_data
> > *bpd)
> > +				    const struct scpsys_bus_prot_data
> > *bpd,
> > +					struct regmap *sta_regmap,
> > struct regmap *regmap)
> >   {
> > -	struct regmap *sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
> >   	u32 sta_mask = bpd->bus_prot_sta_mask;
> >   	u32 expected_ack;
> >   	u32 val;
> > @@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct
> > scpsys_domain *pd,
> >   }
> >   
> >   static int scpsys_bus_protect_set(struct scpsys_domain *pd,
> > -				  const struct scpsys_bus_prot_data
> > *bpd)
> > +				  const struct scpsys_bus_prot_data
> > *bpd,
> > +				  struct regmap *sta_regmap, struct
> > regmap *regmap)
> >   {
> > -	struct regmap *sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
> >   	u32 sta_mask = bpd->bus_prot_sta_mask;
> >   	u32 val;
> >   
> > @@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct
> > scpsys_domain *pd,
> >   					MTK_POLL_DELAY_US,
> > MTK_POLL_TIMEOUT);
> >   }
> >   
> > -static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
> > +static int _scpsys_clamp_bus_protection_enable(struct
> > scpsys_domain *pd, bool is_smi)
> >   {
> > +	int smi_count = 0;
> > +
> >   	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
> >   		const struct scpsys_bus_prot_data *bpd = &pd->data-
> > >bp_cfg[i];
> > +		struct regmap *sta_regmap, *regmap;
> > +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
> >   		int ret;
> >   
> >   		if (!bpd->bus_prot_set_clr_mask)
> >   			break;
> >   
> > +		if (is_smi) {
> > +			sta_regmap = pd->smi[smi_count];
> > +			regmap = pd->smi[smi_count];
> > +			smi_count++;
> > +		} else {
> > +			sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > +			regmap = pd->infracfg;
> > +		}
> > +
> >   		if (bpd->flags & BUS_PROT_INVERTED)
> > -			ret = scpsys_bus_protect_clear(pd, bpd);
> > +			ret = scpsys_bus_protect_clear(pd, bpd,
> > sta_regmap, regmap);
> >   		else
> > -			ret = scpsys_bus_protect_set(pd, bpd);
> > +			ret = scpsys_bus_protect_set(pd, bpd,
> > sta_regmap, regmap);
> >   		if (ret)
> >   			return ret;
> >   	}
> > @@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct
> > scpsys_domain *pd, bool is_smi)
> >   {
> > +	int smi_count = pd->num_smi - 1;
> > +
> >   	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
> >   		const struct scpsys_bus_prot_data *bpd = &pd->data-
> > >bp_cfg[i];
> > +		struct regmap *sta_regmap, *regmap;
> > +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
> >   		int ret;
> >   
> >   		if (!bpd->bus_prot_set_clr_mask)
> >   			continue;
> >   
> > +		if (is_smi) {
> > +			sta_regmap = pd->smi[smi_count];
> > +			regmap = pd->smi[smi_count];
> > +			smi_count--;
> > +		} else {
> > +			sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > +			regmap = pd->infracfg;
> > +		}
> > +
> >   		if (bpd->flags & BUS_PROT_INVERTED)
> > -			ret = scpsys_bus_protect_set(pd, bpd);
> > +			ret = scpsys_bus_protect_set(pd, bpd,
> > sta_regmap, regmap);
> >   		else
> > -			ret = scpsys_bus_protect_clear(pd, bpd);
> > +			ret = scpsys_bus_protect_clear(pd, bpd,
> > sta_regmap, regmap);
> >   		if (ret)
> >   			return ret;
> >   	}
> > @@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct
> > scpsys_domain *pd)
> >   	return 0;
> >   }
> >   
> > +static int scpsys_clamp_protection(struct scpsys_domain *pd)
> > +{
> > +	int ret;
> > +
> 
> You can directly call _scpsys_clamp_bus_protection_enable(), no need
> for a helper.
> 
> > +	ret = _scpsys_clamp_bus_protection_enable(pd, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int scpsys_clamp_protection_disable(struct scpsys_domain
> > *pd)
> > +{
> > +	int ret;
> > +
> > +	ret = _scpsys_clamp_bus_protection_disable(pd, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
> 
> Unused function, please remove.

I think this is used in scpsys_power_off function. Do you mean I
should directly call _scpsys_clamp_bus_protection_disable?

> 
> > +{
> > +	int ret;
> > +
> > +	ret = _scpsys_clamp_bus_protection_enable(pd, false);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
> > +{
> 
> Unused function, please remove.

Same here, I think this is used in scpsys_power_on function.

> 
> > +	int ret;
> > +
> > +	ret = _scpsys_clamp_bus_protection_disable(pd, false);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> >   static int scpsys_regulator_enable(struct regulator *supply)
> >   {
> >   	return supply ? regulator_enable(supply) : 0;
> > @@ -272,6 +332,12 @@ static int scpsys_power_on(struct
> > generic_pm_domain *genpd)
> >   	bool tmp;
> >   	int ret;
> >   
> > +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> > +		ret = scpsys_clamp_protection(pd);
> 
> 		ret = scpsys_clamp_bus_protection_enable(pd, true);
> 
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = scpsys_regulator_enable(pd->supply);
> >   	if (ret)
> >   		return ret;
> > @@ -318,6 +384,12 @@ static int scpsys_power_on(struct
> > generic_pm_domain *genpd)
> >   	if (ret < 0)
> >   		goto err_disable_subsys_clks;
> >   
> > +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> > +		ret = scpsys_clamp_protection_disable(pd);
> 
> 		ret = scpsys_clamp_bus_protection_disable(pd, true);
> 
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = scpsys_bus_protect_disable(pd);
> >   	if (ret < 0)
> >   		goto err_disable_sram;
> > @@ -353,6 +425,12 @@ static int scpsys_power_off(struct
> > generic_pm_domain *genpd)
> >   	bool tmp;
> >   	int ret;
> >   
> > +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> > +		ret = scpsys_clamp_protection(pd);
> 
> ret = scpsys_clamp_bus_protection_enable(pd, true);
> 
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = scpsys_bus_protect_enable(pd);
> >   	if (ret < 0)
> >   		return ret;
> 
> Regards,
> Angelo
> 
Best Regards,
yu-chang.lee

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
@ 2024-03-26  2:00       ` Yu-chang Lee (李禹璋)
  0 siblings, 0 replies; 16+ messages in thread
From: Yu-chang Lee (李禹璋) @ 2024-03-26  2:00 UTC (permalink / raw)
  To: ulf.hansson, matthias.bgg, angelogioacchino.delregno
  Cc: linux-kernel, linux-mediatek, linux-pm,
	MandyJH Liu (劉人僖),
	Project_Global_Chrome_Upstream_Group,
	Xiufeng Li (李秀峰),
	linux-arm-kernel, Fan Chen (陳凡)

On Mon, 2024-03-25 at 14:05 +0100, AngeloGioacchino Del Regno wrote:
> Il 25/03/24 13:19, yu-chang.lee ha scritto:
> > In order to avoid power glitch, this patch use smi clamp
> > to disable/enable smi common port.
> > 
> > Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
> > ---
> >   drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
> >   drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147
> > ++++++++++++++----
> >   drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
> >   3 files changed, 156 insertions(+), 33 deletions(-)
> > 
> > diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > index 7bbba4d56a77..39f057dca92c 100644
> > --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
> > @@ -573,6 +573,18 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
> > VDO0,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
> > VPP1,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
> >   				     MT8188_SMI_LARB10_RESET_ADDR),
> > @@ -585,7 +597,7 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
> >   				     MT8188_SMI_LARB15_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   	[MT8188_POWER_DOMAIN_IPE] = {
> >   		.name = "ipe",
> > @@ -595,11 +607,18 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
> > VPP1,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
> >   				     MT8188_SMI_LARB12_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
> >   		.name = "cam_vcore",
> > @@ -676,13 +695,20 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
> > VPP1,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
> >   				     MT8188_SMI_LARB16A_RESET_ADDR),
> >   			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
> >   				     MT8188_SMI_LARB17A_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
> >   		.name = "cam_subb",
> > @@ -692,13 +718,20 @@ static const struct scpsys_domain_data
> > scpsys_domain_data_mt8188[] = {
> >   		.pwr_sta2nd_offs = 0x170,
> >   		.sram_pdn_bits = BIT(8),
> >   		.sram_pdn_ack_bits = BIT(12),
> > +		.bp_cfg = {
> > +			BUS_PROT_WR(SMI,
> > +				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUB
> > B_TO_VDO0,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
> > +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
> > +		},
> >   		.reset_smi = {
> >   			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
> >   				     MT8188_SMI_LARB16B_RESET_ADDR),
> >   			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
> >   				     MT8188_SMI_LARB17B_RESET_ADDR),
> >   		},
> > -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
> > +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
> > MTK_SCPD_CLAMP_PROTECTION,
> >   	},
> >   };
> >   
> > diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > index 9ab6fa105c8c..3c797e136c0e 100644
> > --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
> > @@ -47,9 +47,10 @@ struct scpsys_domain {
> >   	struct clk_bulk_data *subsys_clks;
> >   	struct regmap *infracfg_nao;
> >   	struct regmap *infracfg;
> > -	struct regmap *smi;
> > +	struct regmap **smi;
> >   	struct regmap **larb;
> >   	int num_larb;
> > +	int num_smi;
> >   	struct regulator *supply;
> >   };
> >   
> > @@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct
> > scpsys_domain *pd)
> >   					MTK_POLL_TIMEOUT);
> >   }
> >   
> > -static struct regmap *scpsys_bus_protect_get_regmap(struct
> > scpsys_domain *pd,
> > -						    const struct
> > scpsys_bus_prot_data *bpd)
> > -{
> > -	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
> > -		return pd->smi;
> > -	else
> > -		return pd->infracfg;
> > -}
> > -
> >   static struct regmap *scpsys_bus_protect_get_sta_regmap(struct
> > scpsys_domain *pd,
> >   							const struct
> > scpsys_bus_prot_data *bpd)
> >   {
> >   	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
> >   		return pd->infracfg_nao;
> >   	else
> > -		return scpsys_bus_protect_get_regmap(pd, bpd);
> > +		return pd->infracfg;
> >   }
> >   
> >   static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
> > -				    const struct scpsys_bus_prot_data
> > *bpd)
> > +				    const struct scpsys_bus_prot_data
> > *bpd,
> > +					struct regmap *sta_regmap,
> > struct regmap *regmap)
> >   {
> > -	struct regmap *sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
> >   	u32 sta_mask = bpd->bus_prot_sta_mask;
> >   	u32 expected_ack;
> >   	u32 val;
> > @@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct
> > scpsys_domain *pd,
> >   }
> >   
> >   static int scpsys_bus_protect_set(struct scpsys_domain *pd,
> > -				  const struct scpsys_bus_prot_data
> > *bpd)
> > +				  const struct scpsys_bus_prot_data
> > *bpd,
> > +				  struct regmap *sta_regmap, struct
> > regmap *regmap)
> >   {
> > -	struct regmap *sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
> >   	u32 sta_mask = bpd->bus_prot_sta_mask;
> >   	u32 val;
> >   
> > @@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct
> > scpsys_domain *pd,
> >   					MTK_POLL_DELAY_US,
> > MTK_POLL_TIMEOUT);
> >   }
> >   
> > -static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
> > +static int _scpsys_clamp_bus_protection_enable(struct
> > scpsys_domain *pd, bool is_smi)
> >   {
> > +	int smi_count = 0;
> > +
> >   	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
> >   		const struct scpsys_bus_prot_data *bpd = &pd->data-
> > >bp_cfg[i];
> > +		struct regmap *sta_regmap, *regmap;
> > +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
> >   		int ret;
> >   
> >   		if (!bpd->bus_prot_set_clr_mask)
> >   			break;
> >   
> > +		if (is_smi) {
> > +			sta_regmap = pd->smi[smi_count];
> > +			regmap = pd->smi[smi_count];
> > +			smi_count++;
> > +		} else {
> > +			sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > +			regmap = pd->infracfg;
> > +		}
> > +
> >   		if (bpd->flags & BUS_PROT_INVERTED)
> > -			ret = scpsys_bus_protect_clear(pd, bpd);
> > +			ret = scpsys_bus_protect_clear(pd, bpd,
> > sta_regmap, regmap);
> >   		else
> > -			ret = scpsys_bus_protect_set(pd, bpd);
> > +			ret = scpsys_bus_protect_set(pd, bpd,
> > sta_regmap, regmap);
> >   		if (ret)
> >   			return ret;
> >   	}
> > @@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct
> > scpsys_domain *pd, bool is_smi)
> >   {
> > +	int smi_count = pd->num_smi - 1;
> > +
> >   	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
> >   		const struct scpsys_bus_prot_data *bpd = &pd->data-
> > >bp_cfg[i];
> > +		struct regmap *sta_regmap, *regmap;
> > +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
> >   		int ret;
> >   
> >   		if (!bpd->bus_prot_set_clr_mask)
> >   			continue;
> >   
> > +		if (is_smi) {
> > +			sta_regmap = pd->smi[smi_count];
> > +			regmap = pd->smi[smi_count];
> > +			smi_count--;
> > +		} else {
> > +			sta_regmap =
> > scpsys_bus_protect_get_sta_regmap(pd, bpd);
> > +			regmap = pd->infracfg;
> > +		}
> > +
> >   		if (bpd->flags & BUS_PROT_INVERTED)
> > -			ret = scpsys_bus_protect_set(pd, bpd);
> > +			ret = scpsys_bus_protect_set(pd, bpd,
> > sta_regmap, regmap);
> >   		else
> > -			ret = scpsys_bus_protect_clear(pd, bpd);
> > +			ret = scpsys_bus_protect_clear(pd, bpd,
> > sta_regmap, regmap);
> >   		if (ret)
> >   			return ret;
> >   	}
> > @@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct
> > scpsys_domain *pd)
> >   	return 0;
> >   }
> >   
> > +static int scpsys_clamp_protection(struct scpsys_domain *pd)
> > +{
> > +	int ret;
> > +
> 
> You can directly call _scpsys_clamp_bus_protection_enable(), no need
> for a helper.
> 
> > +	ret = _scpsys_clamp_bus_protection_enable(pd, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int scpsys_clamp_protection_disable(struct scpsys_domain
> > *pd)
> > +{
> > +	int ret;
> > +
> > +	ret = _scpsys_clamp_bus_protection_disable(pd, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
> 
> Unused function, please remove.

I think this is used in scpsys_power_off function. Do you mean I
should directly call _scpsys_clamp_bus_protection_disable?

> 
> > +{
> > +	int ret;
> > +
> > +	ret = _scpsys_clamp_bus_protection_enable(pd, false);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> > +static int scpsys_bus_protect_disable(struct scpsys_domain *pd)
> > +{
> 
> Unused function, please remove.

Same here, I think this is used in scpsys_power_on function.

> 
> > +	int ret;
> > +
> > +	ret = _scpsys_clamp_bus_protection_disable(pd, false);
> > +	if (ret)
> > +		return ret;
> > +
> > +	return 0;
> > +}
> > +
> >   static int scpsys_regulator_enable(struct regulator *supply)
> >   {
> >   	return supply ? regulator_enable(supply) : 0;
> > @@ -272,6 +332,12 @@ static int scpsys_power_on(struct
> > generic_pm_domain *genpd)
> >   	bool tmp;
> >   	int ret;
> >   
> > +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> > +		ret = scpsys_clamp_protection(pd);
> 
> 		ret = scpsys_clamp_bus_protection_enable(pd, true);
> 
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = scpsys_regulator_enable(pd->supply);
> >   	if (ret)
> >   		return ret;
> > @@ -318,6 +384,12 @@ static int scpsys_power_on(struct
> > generic_pm_domain *genpd)
> >   	if (ret < 0)
> >   		goto err_disable_subsys_clks;
> >   
> > +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> > +		ret = scpsys_clamp_protection_disable(pd);
> 
> 		ret = scpsys_clamp_bus_protection_disable(pd, true);
> 
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = scpsys_bus_protect_disable(pd);
> >   	if (ret < 0)
> >   		goto err_disable_sram;
> > @@ -353,6 +425,12 @@ static int scpsys_power_off(struct
> > generic_pm_domain *genpd)
> >   	bool tmp;
> >   	int ret;
> >   
> > +	if (MTK_SCPD_CAPS(pd, MTK_SCPD_CLAMP_PROTECTION)) {
> > +		ret = scpsys_clamp_protection(pd);
> 
> ret = scpsys_clamp_bus_protection_enable(pd, true);
> 
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> >   	ret = scpsys_bus_protect_enable(pd);
> >   	if (ret < 0)
> >   		return ret;
> 
> Regards,
> Angelo
> 
Best Regards,
yu-chang.lee
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
  2024-03-26  2:00       ` Yu-chang Lee (李禹璋)
@ 2024-03-26 13:57         ` AngeloGioacchino Del Regno
  -1 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-26 13:57 UTC (permalink / raw)
  To: Yu-chang Lee (李禹璋), ulf.hansson, matthias.bgg
  Cc: linux-kernel, linux-mediatek, linux-pm,
	MandyJH Liu (劉人僖),
	Project_Global_Chrome_Upstream_Group,
	Xiufeng Li (李秀峰),
	linux-arm-kernel, Fan Chen (陳凡)

Il 26/03/24 03:00, Yu-chang Lee (李禹璋) ha scritto:
> On Mon, 2024-03-25 at 14:05 +0100, AngeloGioacchino Del Regno wrote:
>> Il 25/03/24 13:19, yu-chang.lee ha scritto:
>>> In order to avoid power glitch, this patch use smi clamp
>>> to disable/enable smi common port.
>>>
>>> Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
>>> ---
>>>    drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
>>>    drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147
>>> ++++++++++++++----
>>>    drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
>>>    3 files changed, 156 insertions(+), 33 deletions(-)
>>>
>>> diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> index 7bbba4d56a77..39f057dca92c 100644
>>> --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> @@ -573,6 +573,18 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
>>> VDO0,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
>>> VPP1,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
>>>    				     MT8188_SMI_LARB10_RESET_ADDR),
>>> @@ -585,7 +597,7 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
>>>    				     MT8188_SMI_LARB15_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    	[MT8188_POWER_DOMAIN_IPE] = {
>>>    		.name = "ipe",
>>> @@ -595,11 +607,18 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
>>> VPP1,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
>>>    				     MT8188_SMI_LARB12_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
>>>    		.name = "cam_vcore",
>>> @@ -676,13 +695,20 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
>>> VPP1,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
>>>    				     MT8188_SMI_LARB16A_RESET_ADDR),
>>>    			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
>>>    				     MT8188_SMI_LARB17A_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
>>>    		.name = "cam_subb",
>>> @@ -692,13 +718,20 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUB
>>> B_TO_VDO0,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
>>>    				     MT8188_SMI_LARB16B_RESET_ADDR),
>>>    			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
>>>    				     MT8188_SMI_LARB17B_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    };
>>>    
>>> diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> b/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> index 9ab6fa105c8c..3c797e136c0e 100644
>>> --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> @@ -47,9 +47,10 @@ struct scpsys_domain {
>>>    	struct clk_bulk_data *subsys_clks;
>>>    	struct regmap *infracfg_nao;
>>>    	struct regmap *infracfg;
>>> -	struct regmap *smi;
>>> +	struct regmap **smi;
>>>    	struct regmap **larb;
>>>    	int num_larb;
>>> +	int num_smi;
>>>    	struct regulator *supply;
>>>    };
>>>    
>>> @@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct
>>> scpsys_domain *pd)
>>>    					MTK_POLL_TIMEOUT);
>>>    }
>>>    
>>> -static struct regmap *scpsys_bus_protect_get_regmap(struct
>>> scpsys_domain *pd,
>>> -						    const struct
>>> scpsys_bus_prot_data *bpd)
>>> -{
>>> -	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
>>> -		return pd->smi;
>>> -	else
>>> -		return pd->infracfg;
>>> -}
>>> -
>>>    static struct regmap *scpsys_bus_protect_get_sta_regmap(struct
>>> scpsys_domain *pd,
>>>    							const struct
>>> scpsys_bus_prot_data *bpd)
>>>    {
>>>    	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
>>>    		return pd->infracfg_nao;
>>>    	else
>>> -		return scpsys_bus_protect_get_regmap(pd, bpd);
>>> +		return pd->infracfg;
>>>    }
>>>    
>>>    static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
>>> -				    const struct scpsys_bus_prot_data
>>> *bpd)
>>> +				    const struct scpsys_bus_prot_data
>>> *bpd,
>>> +					struct regmap *sta_regmap,
>>> struct regmap *regmap)
>>>    {
>>> -	struct regmap *sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>>>    	u32 sta_mask = bpd->bus_prot_sta_mask;
>>>    	u32 expected_ack;
>>>    	u32 val;
>>> @@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct
>>> scpsys_domain *pd,
>>>    }
>>>    
>>>    static int scpsys_bus_protect_set(struct scpsys_domain *pd,
>>> -				  const struct scpsys_bus_prot_data
>>> *bpd)
>>> +				  const struct scpsys_bus_prot_data
>>> *bpd,
>>> +				  struct regmap *sta_regmap, struct
>>> regmap *regmap)
>>>    {
>>> -	struct regmap *sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>>>    	u32 sta_mask = bpd->bus_prot_sta_mask;
>>>    	u32 val;
>>>    
>>> @@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct
>>> scpsys_domain *pd,
>>>    					MTK_POLL_DELAY_US,
>>> MTK_POLL_TIMEOUT);
>>>    }
>>>    
>>> -static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
>>> +static int _scpsys_clamp_bus_protection_enable(struct
>>> scpsys_domain *pd, bool is_smi)
>>>    {
>>> +	int smi_count = 0;
>>> +
>>>    	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
>>>    		const struct scpsys_bus_prot_data *bpd = &pd->data-
>>>> bp_cfg[i];
>>> +		struct regmap *sta_regmap, *regmap;
>>> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>>>    		int ret;
>>>    
>>>    		if (!bpd->bus_prot_set_clr_mask)
>>>    			break;
>>>    
>>> +		if (is_smi) {
>>> +			sta_regmap = pd->smi[smi_count];
>>> +			regmap = pd->smi[smi_count];
>>> +			smi_count++;
>>> +		} else {
>>> +			sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> +			regmap = pd->infracfg;
>>> +		}
>>> +
>>>    		if (bpd->flags & BUS_PROT_INVERTED)
>>> -			ret = scpsys_bus_protect_clear(pd, bpd);
>>> +			ret = scpsys_bus_protect_clear(pd, bpd,
>>> sta_regmap, regmap);
>>>    		else
>>> -			ret = scpsys_bus_protect_set(pd, bpd);
>>> +			ret = scpsys_bus_protect_set(pd, bpd,
>>> sta_regmap, regmap);
>>>    		if (ret)
>>>    			return ret;
>>>    	}
>>> @@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct
>>> scpsys_domain *pd, bool is_smi)
>>>    {
>>> +	int smi_count = pd->num_smi - 1;
>>> +
>>>    	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
>>>    		const struct scpsys_bus_prot_data *bpd = &pd->data-
>>>> bp_cfg[i];
>>> +		struct regmap *sta_regmap, *regmap;
>>> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>>>    		int ret;
>>>    
>>>    		if (!bpd->bus_prot_set_clr_mask)
>>>    			continue;
>>>    
>>> +		if (is_smi) {
>>> +			sta_regmap = pd->smi[smi_count];
>>> +			regmap = pd->smi[smi_count];
>>> +			smi_count--;
>>> +		} else {
>>> +			sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> +			regmap = pd->infracfg;
>>> +		}
>>> +
>>>    		if (bpd->flags & BUS_PROT_INVERTED)
>>> -			ret = scpsys_bus_protect_set(pd, bpd);
>>> +			ret = scpsys_bus_protect_set(pd, bpd,
>>> sta_regmap, regmap);
>>>    		else
>>> -			ret = scpsys_bus_protect_clear(pd, bpd);
>>> +			ret = scpsys_bus_protect_clear(pd, bpd,
>>> sta_regmap, regmap);
>>>    		if (ret)
>>>    			return ret;
>>>    	}
>>> @@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct
>>> scpsys_domain *pd)
>>>    	return 0;
>>>    }
>>>    
>>> +static int scpsys_clamp_protection(struct scpsys_domain *pd)
>>> +{
>>> +	int ret;
>>> +
>>
>> You can directly call _scpsys_clamp_bus_protection_enable(), no need
>> for a helper.
>>
>>> +	ret = _scpsys_clamp_bus_protection_enable(pd, true);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int scpsys_clamp_protection_disable(struct scpsys_domain
>>> *pd)
>>> +{
>>> +	int ret;
>>> +
>>> +	ret = _scpsys_clamp_bus_protection_disable(pd, true);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
>>
>> Unused function, please remove.
> 
> I think this is used in scpsys_power_off function. Do you mean I
> should directly call _scpsys_clamp_bus_protection_disable?
> 

Yes, please.

Cheers,
Angelo



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection
@ 2024-03-26 13:57         ` AngeloGioacchino Del Regno
  0 siblings, 0 replies; 16+ messages in thread
From: AngeloGioacchino Del Regno @ 2024-03-26 13:57 UTC (permalink / raw)
  To: Yu-chang Lee (李禹璋), ulf.hansson, matthias.bgg
  Cc: linux-kernel, linux-mediatek, linux-pm,
	MandyJH Liu (劉人僖),
	Project_Global_Chrome_Upstream_Group,
	Xiufeng Li (李秀峰),
	linux-arm-kernel, Fan Chen (陳凡)

Il 26/03/24 03:00, Yu-chang Lee (李禹璋) ha scritto:
> On Mon, 2024-03-25 at 14:05 +0100, AngeloGioacchino Del Regno wrote:
>> Il 25/03/24 13:19, yu-chang.lee ha scritto:
>>> In order to avoid power glitch, this patch use smi clamp
>>> to disable/enable smi common port.
>>>
>>> Signed-off-by: yu-chang.lee <yu-chang.lee@mediatek.com>
>>> ---
>>>    drivers/pmdomain/mediatek/mt8188-pm-domains.h |  41 ++++-
>>>    drivers/pmdomain/mediatek/mtk-pm-domains.c    | 147
>>> ++++++++++++++----
>>>    drivers/pmdomain/mediatek/mtk-pm-domains.h    |   1 +
>>>    3 files changed, 156 insertions(+), 33 deletions(-)
>>>
>>> diff --git a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> index 7bbba4d56a77..39f057dca92c 100644
>>> --- a/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> +++ b/drivers/pmdomain/mediatek/mt8188-pm-domains.h
>>> @@ -573,6 +573,18 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
>>> VDO0,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_DIP_TO_
>>> VPP1,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB10_RESET,
>>>    				     MT8188_SMI_LARB10_RESET_ADDR),
>>> @@ -585,7 +597,7 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB15_RESET,
>>>    				     MT8188_SMI_LARB15_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    	[MT8188_POWER_DOMAIN_IPE] = {
>>>    		.name = "ipe",
>>> @@ -595,11 +607,18 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
>>> VPP1,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB12_RESET,
>>>    				     MT8188_SMI_LARB12_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    	[MT8188_POWER_DOMAIN_CAM_VCORE] = {
>>>    		.name = "cam_vcore",
>>> @@ -676,13 +695,20 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_IPE_TO_
>>> VPP1,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB16A_RESET,
>>>    				     MT8188_SMI_LARB16A_RESET_ADDR),
>>>    			SMI_RESET_WR(MT8188_SMI_LARB17A_RESET,
>>>    				     MT8188_SMI_LARB17A_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    	[MT8188_POWER_DOMAIN_CAM_SUBB] = {
>>>    		.name = "cam_subb",
>>> @@ -692,13 +718,20 @@ static const struct scpsys_domain_data
>>> scpsys_domain_data_mt8188[] = {
>>>    		.pwr_sta2nd_offs = 0x170,
>>>    		.sram_pdn_bits = BIT(8),
>>>    		.sram_pdn_ack_bits = BIT(12),
>>> +		.bp_cfg = {
>>> +			BUS_PROT_WR(SMI,
>>> +				    MT8188_SMI_COMMON_SMI_CLAMP_CAM_SUB
>>> B_TO_VDO0,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_SET,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_CLR,
>>> +				    MT8188_SMI_COMMON_CLAMP_EN_STA),
>>> +		},
>>>    		.reset_smi = {
>>>    			SMI_RESET_WR(MT8188_SMI_LARB16B_RESET,
>>>    				     MT8188_SMI_LARB16B_RESET_ADDR),
>>>    			SMI_RESET_WR(MT8188_SMI_LARB17B_RESET,
>>>    				     MT8188_SMI_LARB17B_RESET_ADDR),
>>>    		},
>>> -		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
>>> +		.caps = MTK_SCPD_KEEP_DEFAULT_OFF |
>>> MTK_SCPD_CLAMP_PROTECTION,
>>>    	},
>>>    };
>>>    
>>> diff --git a/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> b/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> index 9ab6fa105c8c..3c797e136c0e 100644
>>> --- a/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> +++ b/drivers/pmdomain/mediatek/mtk-pm-domains.c
>>> @@ -47,9 +47,10 @@ struct scpsys_domain {
>>>    	struct clk_bulk_data *subsys_clks;
>>>    	struct regmap *infracfg_nao;
>>>    	struct regmap *infracfg;
>>> -	struct regmap *smi;
>>> +	struct regmap **smi;
>>>    	struct regmap **larb;
>>>    	int num_larb;
>>> +	int num_smi;
>>>    	struct regulator *supply;
>>>    };
>>>    
>>> @@ -122,29 +123,19 @@ static int scpsys_sram_disable(struct
>>> scpsys_domain *pd)
>>>    					MTK_POLL_TIMEOUT);
>>>    }
>>>    
>>> -static struct regmap *scpsys_bus_protect_get_regmap(struct
>>> scpsys_domain *pd,
>>> -						    const struct
>>> scpsys_bus_prot_data *bpd)
>>> -{
>>> -	if (bpd->flags & BUS_PROT_COMPONENT_SMI)
>>> -		return pd->smi;
>>> -	else
>>> -		return pd->infracfg;
>>> -}
>>> -
>>>    static struct regmap *scpsys_bus_protect_get_sta_regmap(struct
>>> scpsys_domain *pd,
>>>    							const struct
>>> scpsys_bus_prot_data *bpd)
>>>    {
>>>    	if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO)
>>>    		return pd->infracfg_nao;
>>>    	else
>>> -		return scpsys_bus_protect_get_regmap(pd, bpd);
>>> +		return pd->infracfg;
>>>    }
>>>    
>>>    static int scpsys_bus_protect_clear(struct scpsys_domain *pd,
>>> -				    const struct scpsys_bus_prot_data
>>> *bpd)
>>> +				    const struct scpsys_bus_prot_data
>>> *bpd,
>>> +					struct regmap *sta_regmap,
>>> struct regmap *regmap)
>>>    {
>>> -	struct regmap *sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>>>    	u32 sta_mask = bpd->bus_prot_sta_mask;
>>>    	u32 expected_ack;
>>>    	u32 val;
>>> @@ -165,10 +156,9 @@ static int scpsys_bus_protect_clear(struct
>>> scpsys_domain *pd,
>>>    }
>>>    
>>>    static int scpsys_bus_protect_set(struct scpsys_domain *pd,
>>> -				  const struct scpsys_bus_prot_data
>>> *bpd)
>>> +				  const struct scpsys_bus_prot_data
>>> *bpd,
>>> +				  struct regmap *sta_regmap, struct
>>> regmap *regmap)
>>>    {
>>> -	struct regmap *sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> -	struct regmap *regmap = scpsys_bus_protect_get_regmap(pd, bpd);
>>>    	u32 sta_mask = bpd->bus_prot_sta_mask;
>>>    	u32 val;
>>>    
>>> @@ -182,19 +172,32 @@ static int scpsys_bus_protect_set(struct
>>> scpsys_domain *pd,
>>>    					MTK_POLL_DELAY_US,
>>> MTK_POLL_TIMEOUT);
>>>    }
>>>    
>>> -static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
>>> +static int _scpsys_clamp_bus_protection_enable(struct
>>> scpsys_domain *pd, bool is_smi)
>>>    {
>>> +	int smi_count = 0;
>>> +
>>>    	for (int i = 0; i < SPM_MAX_BUS_PROT_DATA; i++) {
>>>    		const struct scpsys_bus_prot_data *bpd = &pd->data-
>>>> bp_cfg[i];
>>> +		struct regmap *sta_regmap, *regmap;
>>> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>>>    		int ret;
>>>    
>>>    		if (!bpd->bus_prot_set_clr_mask)
>>>    			break;
>>>    
>>> +		if (is_smi) {
>>> +			sta_regmap = pd->smi[smi_count];
>>> +			regmap = pd->smi[smi_count];
>>> +			smi_count++;
>>> +		} else {
>>> +			sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> +			regmap = pd->infracfg;
>>> +		}
>>> +
>>>    		if (bpd->flags & BUS_PROT_INVERTED)
>>> -			ret = scpsys_bus_protect_clear(pd, bpd);
>>> +			ret = scpsys_bus_protect_clear(pd, bpd,
>>> sta_regmap, regmap);
>>>    		else
>>> -			ret = scpsys_bus_protect_set(pd, bpd);
>>> +			ret = scpsys_bus_protect_set(pd, bpd,
>>> sta_regmap, regmap);
>>>    		if (ret)
>>>    			return ret;
>>>    	}
>>> @@ -202,19 +205,32 @@ 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_clamp_bus_protection_disable(struct
>>> scpsys_domain *pd, bool is_smi)
>>>    {
>>> +	int smi_count = pd->num_smi - 1;
>>> +
>>>    	for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) {
>>>    		const struct scpsys_bus_prot_data *bpd = &pd->data-
>>>> bp_cfg[i];
>>> +		struct regmap *sta_regmap, *regmap;
>>> +		bool is_smi = bpd->flags & BUS_PROT_COMPONENT_SMI;
>>>    		int ret;
>>>    
>>>    		if (!bpd->bus_prot_set_clr_mask)
>>>    			continue;
>>>    
>>> +		if (is_smi) {
>>> +			sta_regmap = pd->smi[smi_count];
>>> +			regmap = pd->smi[smi_count];
>>> +			smi_count--;
>>> +		} else {
>>> +			sta_regmap =
>>> scpsys_bus_protect_get_sta_regmap(pd, bpd);
>>> +			regmap = pd->infracfg;
>>> +		}
>>> +
>>>    		if (bpd->flags & BUS_PROT_INVERTED)
>>> -			ret = scpsys_bus_protect_set(pd, bpd);
>>> +			ret = scpsys_bus_protect_set(pd, bpd,
>>> sta_regmap, regmap);
>>>    		else
>>> -			ret = scpsys_bus_protect_clear(pd, bpd);
>>> +			ret = scpsys_bus_protect_clear(pd, bpd,
>>> sta_regmap, regmap);
>>>    		if (ret)
>>>    			return ret;
>>>    	}
>>> @@ -222,6 +238,50 @@ static int scpsys_bus_protect_disable(struct
>>> scpsys_domain *pd)
>>>    	return 0;
>>>    }
>>>    
>>> +static int scpsys_clamp_protection(struct scpsys_domain *pd)
>>> +{
>>> +	int ret;
>>> +
>>
>> You can directly call _scpsys_clamp_bus_protection_enable(), no need
>> for a helper.
>>
>>> +	ret = _scpsys_clamp_bus_protection_enable(pd, true);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int scpsys_clamp_protection_disable(struct scpsys_domain
>>> *pd)
>>> +{
>>> +	int ret;
>>> +
>>> +	ret = _scpsys_clamp_bus_protection_disable(pd, true);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int scpsys_bus_protect_enable(struct scpsys_domain *pd)
>>
>> Unused function, please remove.
> 
> I think this is used in scpsys_power_off function. Do you mean I
> should directly call _scpsys_clamp_bus_protection_disable?
> 

Yes, please.

Cheers,
Angelo



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2024-03-26 13:57 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-25 12:19 [PATCH 0/2] soc: mediatek: pm-domains: solve power domain glitch issue yu-chang.lee
2024-03-25 12:19 ` yu-chang.lee
2024-03-25 12:19 ` [PATCH 1/2] soc: mediatek: pm-domains: add smi_larb_reset function when power on yu-chang.lee
2024-03-25 12:19   ` yu-chang.lee
2024-03-25 12:58   ` AngeloGioacchino Del Regno
2024-03-25 12:58     ` AngeloGioacchino Del Regno
2024-03-25 12:19 ` [PATCH 2/2] soc: mediatek: pm-domains: support smi clamp protection yu-chang.lee
2024-03-25 12:19   ` yu-chang.lee
2024-03-25 13:05   ` AngeloGioacchino Del Regno
2024-03-25 13:05     ` AngeloGioacchino Del Regno
2024-03-26  2:00     ` Yu-chang Lee (李禹璋)
2024-03-26  2:00       ` Yu-chang Lee (李禹璋)
2024-03-26 13:57       ` AngeloGioacchino Del Regno
2024-03-26 13:57         ` AngeloGioacchino Del Regno
2024-03-25 13:06 ` [PATCH 0/2] soc: mediatek: pm-domains: solve power domain glitch issue AngeloGioacchino Del Regno
2024-03-25 13:06   ` AngeloGioacchino Del Regno

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.