linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register
@ 2018-12-17 15:31 Lucas Stach
  2018-12-17 15:31 ` [PATCH 2/2] soc: imx: gpcv2: handle reset clocks Lucas Stach
  2019-01-11  7:13 ` [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register Shawn Guo
  0 siblings, 2 replies; 4+ messages in thread
From: Lucas Stach @ 2018-12-17 15:31 UTC (permalink / raw)
  To: Shawn Guo, Rob Herring
  Cc: devicetree, patchwork-lst, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel

Some of the i.MX8MQ domains have an additional control bit in the PU
handshake (HSK) register. Documentation about this bit is a bit sparse
at the moment, but it seems that it controls a power-down request to
the AMBA domain bridge (ADB-400) attached to those domains.

As the documentation doesn't desribe the usage of this bit yet, handle
it in the same way as done in the ATF implementation.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
https://source.codeaurora.org/external/imx/imx-atf/tree/plat/freescale/imx8mq/gpc.c?h=imx_4.9.51_imx8m_ga
---
 drivers/soc/imx/gpcv2.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 8b4f48a2ca57..a8dd0cddb3d2 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -65,6 +65,12 @@
 
 #define GPC_M4_PU_PDN_FLG		0x1bc
 
+#define GPC_PU_PWRHSK			0x1fc
+
+#define IMX8M_GPU_HSK_PWRDNREQN			BIT(6)
+#define IMX8M_VPU_HSK_PWRDNREQN			BIT(5)
+#define IMX8M_DISP_HSK_PWRDNREQN		BIT(4)
+
 /*
  * The PGC offset values in Reference Manual
  * (Rev. 1, 01/2018 and the older ones) GPC chapter's
@@ -102,6 +108,7 @@ struct imx_pgc_domain {
 	const struct {
 		u32 pxx;
 		u32 map;
+		u32 hsk;
 	} bits;
 
 	const int voltage;
@@ -142,6 +149,10 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
 		regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
 				   GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
 
+	if (domain->bits.hsk)
+		regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
+				   domain->bits.hsk, on ? domain->bits.hsk : 0);
+
 	regmap_update_bits(domain->regmap, offset,
 			   domain->bits.pxx, domain->bits.pxx);
 
@@ -328,6 +339,7 @@ static const struct imx_pgc_domain imx8m_pgc_domains[] = {
 		.bits  = {
 			.pxx = IMX8M_GPU_SW_Pxx_REQ,
 			.map = IMX8M_GPU_A53_DOMAIN,
+			.hsk = IMX8M_GPU_HSK_PWRDNREQN,
 		},
 		.pgc   = IMX8M_PGC_GPU,
 	},
@@ -339,6 +351,7 @@ static const struct imx_pgc_domain imx8m_pgc_domains[] = {
 		.bits  = {
 			.pxx = IMX8M_VPU_SW_Pxx_REQ,
 			.map = IMX8M_VPU_A53_DOMAIN,
+			.hsk = IMX8M_VPU_HSK_PWRDNREQN,
 		},
 		.pgc   = IMX8M_PGC_VPU,
 	},
@@ -350,6 +363,7 @@ static const struct imx_pgc_domain imx8m_pgc_domains[] = {
 		.bits  = {
 			.pxx = IMX8M_DISP_SW_Pxx_REQ,
 			.map = IMX8M_DISP_A53_DOMAIN,
+			.hsk = IMX8M_DISP_HSK_PWRDNREQN,
 		},
 		.pgc   = IMX8M_PGC_DISP,
 	},
@@ -390,7 +404,7 @@ static const struct imx_pgc_domain imx8m_pgc_domains[] = {
 
 static const struct regmap_range imx8m_yes_ranges[] = {
 		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
-				 GPC_M4_PU_PDN_FLG),
+				 GPC_PU_PWRHSK),
 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
 				 GPC_PGC_SR(IMX8M_PGC_MIPI)),
 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
-- 
2.19.1


_______________________________________________
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] 4+ messages in thread

* [PATCH 2/2] soc: imx: gpcv2: handle reset clocks
  2018-12-17 15:31 [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register Lucas Stach
@ 2018-12-17 15:31 ` Lucas Stach
  2018-12-20 21:43   ` Rob Herring
  2019-01-11  7:13 ` [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register Shawn Guo
  1 sibling, 1 reply; 4+ messages in thread
From: Lucas Stach @ 2018-12-17 15:31 UTC (permalink / raw)
  To: Shawn Guo, Rob Herring
  Cc: devicetree, patchwork-lst, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel

Some power domains handled by the GPCv2 driver need to enable the clocks
for devies inside the domain, so that the reset propagation and proper
power-up sequencing happens. Handle them in the same way as on GPCv1.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 .../bindings/power/fsl,imx-gpcv2.txt          |  3 +
 drivers/soc/imx/gpcv2.c                       | 60 ++++++++++++++++++-
 2 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
index 7c947a996df1..7c7e972aaa42 100644
--- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
+++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
@@ -32,6 +32,9 @@ Required properties:
 Optional properties:
 
 - power-supply: Power supply used to power the domain
+- clocks: a number of phandles to clocks that need to be enabled during
+  domain power-up sequencing to ensure reset propagation into devices
+  located inside this power domain
 
 Example:
 
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index a8dd0cddb3d2..176f473127b6 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -8,6 +8,7 @@
  * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
  */
 
+#include <linux/clk.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
@@ -98,10 +99,14 @@
 
 #define GPC_PGC_CTRL_PCR		BIT(0)
 
+#define GPC_CLK_MAX		6
+
 struct imx_pgc_domain {
 	struct generic_pm_domain genpd;
 	struct regmap *regmap;
 	struct regulator *regulator;
+	struct clk *clk[GPC_CLK_MAX];
+	int num_clks;
 
 	unsigned int pgc;
 
@@ -132,7 +137,7 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
 	const bool enable_power_control = !on;
 	const bool has_regulator = !IS_ERR(domain->regulator);
 	unsigned long deadline;
-	int ret = 0;
+	int i, ret = 0;
 
 	regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
 			   domain->bits.map, domain->bits.map);
@@ -145,6 +150,10 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
 		}
 	}
 
+	/* Enable reset clocks for all devices in the domain */
+	for (i = 0; i < domain->num_clks; i++)
+		clk_prepare_enable(domain->clk[i]);
+
 	if (enable_power_control)
 		regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
 				   GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
@@ -190,6 +199,10 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
 		regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
 				   GPC_PGC_CTRL_PCR, 0);
 
+	/* Disable reset clocks for all devices in the domain */
+	for (i = 0; i < domain->num_clks; i++)
+		clk_disable_unprepare(domain->clk[i]);
+
 	if (has_regulator && !on) {
 		int err;
 
@@ -440,6 +453,41 @@ static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
 	.reg_access_table = &imx8m_access_table,
 };
 
+static int imx_pgc_get_clocks(struct imx_pgc_domain *domain)
+{
+	int i, ret;
+
+	for (i = 0; ; i++) {
+		struct clk *clk = of_clk_get(domain->dev->of_node, i);
+		if (IS_ERR(clk))
+			break;
+		if (i >= GPC_CLK_MAX) {
+			dev_err(domain->dev, "more than %d clocks\n",
+				GPC_CLK_MAX);
+			ret = -EINVAL;
+			goto clk_err;
+		}
+		domain->clk[i] = clk;
+	}
+	domain->num_clks = i;
+
+	return 0;
+
+clk_err:
+	while (i--)
+		clk_put(domain->clk[i]);
+
+	return ret;
+}
+
+static void imx_pgc_put_clocks(struct imx_pgc_domain *domain)
+{
+	int i;
+
+	for (i = domain->num_clks - 1; i >= 0; i--)
+		clk_put(domain->clk[i]);
+}
+
 static int imx_pgc_domain_probe(struct platform_device *pdev)
 {
 	struct imx_pgc_domain *domain = pdev->dev.platform_data;
@@ -459,9 +507,17 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
 				      domain->voltage, domain->voltage);
 	}
 
+	ret = imx_pgc_get_clocks(domain);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			dev_err(domain->dev, "Failed to get domain's clocks\n");
+		return ret;
+	}
+
 	ret = pm_genpd_init(&domain->genpd, NULL, true);
 	if (ret) {
 		dev_err(domain->dev, "Failed to init power domain\n");
+		imx_pgc_put_clocks(domain);
 		return ret;
 	}
 
@@ -470,6 +526,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
 	if (ret) {
 		dev_err(domain->dev, "Failed to add genpd provider\n");
 		pm_genpd_remove(&domain->genpd);
+		imx_pgc_put_clocks(domain);
 	}
 
 	return ret;
@@ -481,6 +538,7 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)
 
 	of_genpd_del_provider(domain->dev->of_node);
 	pm_genpd_remove(&domain->genpd);
+	imx_pgc_put_clocks(domain);
 
 	return 0;
 }
-- 
2.19.1


_______________________________________________
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] 4+ messages in thread

* Re: [PATCH 2/2] soc: imx: gpcv2: handle reset clocks
  2018-12-17 15:31 ` [PATCH 2/2] soc: imx: gpcv2: handle reset clocks Lucas Stach
@ 2018-12-20 21:43   ` Rob Herring
  0 siblings, 0 replies; 4+ messages in thread
From: Rob Herring @ 2018-12-20 21:43 UTC (permalink / raw)
  To: Lucas Stach
  Cc: devicetree, patchwork-lst, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, Shawn Guo,
	linux-arm-kernel

On Mon, Dec 17, 2018 at 04:31:52PM +0100, Lucas Stach wrote:
> Some power domains handled by the GPCv2 driver need to enable the clocks
> for devies inside the domain, so that the reset propagation and proper
> power-up sequencing happens. Handle them in the same way as on GPCv1.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  .../bindings/power/fsl,imx-gpcv2.txt          |  3 +

Acked-by: Rob Herring <robh@kernel.org>

>  drivers/soc/imx/gpcv2.c                       | 60 ++++++++++++++++++-
>  2 files changed, 62 insertions(+), 1 deletion(-)

_______________________________________________
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] 4+ messages in thread

* Re: [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register
  2018-12-17 15:31 [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register Lucas Stach
  2018-12-17 15:31 ` [PATCH 2/2] soc: imx: gpcv2: handle reset clocks Lucas Stach
@ 2019-01-11  7:13 ` Shawn Guo
  1 sibling, 0 replies; 4+ messages in thread
From: Shawn Guo @ 2019-01-11  7:13 UTC (permalink / raw)
  To: Lucas Stach
  Cc: devicetree, patchwork-lst, Rob Herring, NXP Linux Team,
	Pengutronix Kernel Team, Fabio Estevam, linux-arm-kernel

On Mon, Dec 17, 2018 at 04:31:51PM +0100, Lucas Stach wrote:
> Some of the i.MX8MQ domains have an additional control bit in the PU
> handshake (HSK) register. Documentation about this bit is a bit sparse
> at the moment, but it seems that it controls a power-down request to
> the AMBA domain bridge (ADB-400) attached to those domains.
> 
> As the documentation doesn't desribe the usage of this bit yet, handle
> it in the same way as done in the ATF implementation.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>

Applied both, thanks.

_______________________________________________
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] 4+ messages in thread

end of thread, other threads:[~2019-01-11  7:14 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-17 15:31 [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register Lucas Stach
2018-12-17 15:31 ` [PATCH 2/2] soc: imx: gpcv2: handle reset clocks Lucas Stach
2018-12-20 21:43   ` Rob Herring
2019-01-11  7:13 ` [PATCH 1/2] soc: imx: gpcv2: handle additional power-down bits in handshake register Shawn Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).