[PATCH 04/11] soc: imx: gpcv2: wait for ADB400 handshake
Lucas Stach
l.stach at pengutronix.de
Wed Sep 30 11:49:59 EDT 2020
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 at pengutronix.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 f91063c9fb92..3cfb8b51c23e 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)
@@ -114,7 +117,8 @@ struct imx_pgc_domain {
const struct {
u32 pxx;
u32 map;
- u32 hsk;
+ u32 hskreq;
+ u32 hskack;
} bits;
const int voltage;
@@ -176,9 +180,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 */
for (i = 0; i < domain->num_clks; i++)
@@ -211,9 +225,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),
@@ -378,7 +402,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,
},
@@ -390,7 +415,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,
},
@@ -402,7 +428,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.20.1
More information about the linux-arm-kernel
mailing list