[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210429073050.21039-6-peng.fan@oss.nxp.com>
Date: Thu, 29 Apr 2021 15:30:39 +0800
From: "Peng Fan (OSS)" <peng.fan@....nxp.com>
To: robh+dt@...nel.org, shawnguo@...nel.org, s.hauer@...gutronix.de
Cc: kernel@...gutronix.de, festevam@...il.com, linux-imx@....com,
p.zabel@...gutronix.de, l.stach@...gutronix.de, krzk@...nel.org,
agx@...xcpu.org, marex@...x.de, andrew.smirnov@...il.com,
devicetree@...r.kernel.org, linux-arm-kernel@...ts.infradead.org,
linux-kernel@...r.kernel.org, ping.bai@....com,
frieder.schrempf@...tron.de, aford173@...il.com, abel.vesa@....com
Subject: [PATCH 05/16] soc: imx: gpcv2: wait for ADB400 handshake
From: Lucas Stach <l.stach@...gutronix.de>
New reference manuals show that there is actually a status bit for
the ADB400 handshake. Add a poll loop to wait for the ADB400 to
acknowledge our request.
Signed-off-by: Lucas Stach <l.stach@...gutronix.de>
---
drivers/soc/imx/gpcv2.c | 43 +++++++++++++++++++++++++++++++++--------
1 file changed, 35 insertions(+), 8 deletions(-)
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 7356e48ebdad..d27025e37a9e 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -69,6 +69,9 @@
#define GPC_PU_PWRHSK 0x1fc
+#define IMX8M_GPU_HSK_PWRDNACKN BIT(26)
+#define IMX8M_VPU_HSK_PWRDNACKN BIT(25)
+#define IMX8M_DISP_HSK_PWRDNACKN BIT(24)
#define IMX8M_GPU_HSK_PWRDNREQN BIT(6)
#define IMX8M_VPU_HSK_PWRDNREQN BIT(5)
#define IMX8M_DISP_HSK_PWRDNREQN BIT(4)
@@ -112,7 +115,8 @@ struct imx_pgc_domain {
const struct {
u32 pxx;
u32 map;
- u32 hsk;
+ u32 hskreq;
+ u32 hskack;
} bits;
const int voltage;
@@ -172,9 +176,19 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
GPC_PGC_CTRL_PCR, 0);
/* request the ADB400 to power up */
- if (domain->bits.hsk)
+ if (domain->bits.hskreq) {
regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
- domain->bits.hsk, domain->bits.hsk);
+ domain->bits.hskreq, domain->bits.hskreq);
+
+ ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK,
+ reg_val,
+ (reg_val & domain->bits.hskack),
+ 0, USEC_PER_MSEC);
+ if (ret) {
+ dev_err(domain->dev, "failed to power up ADB400\n");
+ goto out_clk_disable;
+ }
+ }
/* Disable reset clocks for all devices in the domain */
clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
@@ -204,9 +218,19 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
}
/* request the ADB400 to power down */
- if (domain->bits.hsk)
+ if (domain->bits.hskreq) {
regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
- domain->bits.hsk, 0);
+ domain->bits.hskreq, 0);
+
+ ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK,
+ reg_val,
+ !(reg_val & domain->bits.hskack),
+ 0, USEC_PER_MSEC);
+ if (ret) {
+ dev_err(domain->dev, "failed to power down ADB400\n");
+ goto out_clk_disable;
+ }
+ }
/* enable power control */
regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
@@ -369,7 +393,8 @@ 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,
+ .hskreq = IMX8M_GPU_HSK_PWRDNREQN,
+ .hskack = IMX8M_GPU_HSK_PWRDNACKN,
},
.pgc = IMX8M_PGC_GPU,
},
@@ -381,7 +406,8 @@ 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,
+ .hskreq = IMX8M_VPU_HSK_PWRDNREQN,
+ .hskack = IMX8M_VPU_HSK_PWRDNACKN,
},
.pgc = IMX8M_PGC_VPU,
},
@@ -393,7 +419,8 @@ 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,
+ .hskreq = IMX8M_DISP_HSK_PWRDNREQN,
+ .hskack = IMX8M_DISP_HSK_PWRDNACKN,
},
.pgc = IMX8M_PGC_DISP,
},
--
2.30.0
Powered by blists - more mailing lists