Message ID | 20200930155006.535712-7-l.stach@pengutronix.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | i.MX8MM power domain support | expand |
> -----Original Message----- > From: Lucas Stach [mailto:l.stach@pengutronix.de] > Sent: Wednesday, September 30, 2020 11:50 PM > To: Shawn Guo <shawnguo@kernel.org>; Rob Herring <robh+dt@kernel.org> > Cc: dl-linux-imx <linux-imx@nxp.com>; Fabio Estevam > <festevam@gmail.com>; Frieder Schrempf <frieder.schrempf@kontron.de>; > Marek Vasut <marex@denx.de>; linux-arm-kernel@lists.infradead.org; > devicetree@vger.kernel.org; kernel@pengutronix.de; > patchwork-lst@pengutronix.de > Subject: [PATCH 06/11] soc: imx: gpcv2: allow domains without > power-sequence control > > Some of the PGC domains only control the handshake with the ADB400 and > don't have any power sequence controls. Make such domains work by > allowing the pxx and map bits to be empty and skip all actions using those > controls. > > Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > --- > drivers/soc/imx/gpcv2.c | 89 +++++++++++++++++++++++------------------ > 1 file changed, 49 insertions(+), 40 deletions(-) > > diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index > 5bb7b1cc7c10..db93fef0c76b 100644 > --- a/drivers/soc/imx/gpcv2.c > +++ b/drivers/soc/imx/gpcv2.c > @@ -167,24 +167,27 @@ static int imx_pgc_power_up(struct > generic_pm_domain *genpd) > } > } > > - /* request the domain to power up */ > - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, > - domain->bits.pxx, domain->bits.pxx); > - /* > - * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > - * for PUP_REQ/PDN_REQ bit to be cleared > - */ > - ret = regmap_read_poll_timeout(domain->regmap, > GPC_PU_PGC_SW_PUP_REQ, > - reg_val, !(reg_val & domain->bits.pxx), > - 0, USEC_PER_MSEC); > - if (ret) { > - dev_err(domain->dev, "failed to command PGC\n"); > - goto out_clk_disable; > - } > + if (domain->bits.pxx) { What if the power domain's PUP/PDN control bit define is zero, for example, IMX8M_MIPI_SW_Pxx_REQ? BR Jacky Bai > + /* request the domain to power up */ > + regmap_update_bits(domain->regmap, > GPC_PU_PGC_SW_PUP_REQ, > + domain->bits.pxx, domain->bits.pxx); > + /* > + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > + * for PUP_REQ/PDN_REQ bit to be cleared > + */ > + ret = regmap_read_poll_timeout(domain->regmap, > + GPC_PU_PGC_SW_PUP_REQ, reg_val, > + !(reg_val & domain->bits.pxx), > + 0, USEC_PER_MSEC); > + if (ret) { > + dev_err(domain->dev, "failed to command PGC\n"); > + goto out_clk_disable; > + } > > - /* disable power control */ > - regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), > - GPC_PGC_CTRL_PCR, 0); > + /* disable power control */ > + regmap_update_bits(domain->regmap, > GPC_PGC_CTRL(domain->pgc), > + GPC_PGC_CTRL_PCR, 0); > + } > > /* request the ADB400 to power up */ > if (domain->bits.hskreq) { > @@ -248,23 +251,26 @@ static int imx_pgc_power_down(struct > generic_pm_domain *genpd) > } > } > > - /* enable power control */ > - regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), > - GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); > - > - /* request the domain to power down */ > - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, > - domain->bits.pxx, domain->bits.pxx); > - /* > - * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > - * for PUP_REQ/PDN_REQ bit to be cleared > - */ > - ret = regmap_read_poll_timeout(domain->regmap, > GPC_PU_PGC_SW_PDN_REQ, > - reg_val, !(reg_val & domain->bits.pxx), > - 0, USEC_PER_MSEC); > - if (ret) { > - dev_err(domain->dev, "failed to command PGC\n"); > - goto out_clk_disable; > + if (domain->bits.pxx) { > + /* enable power control */ > + regmap_update_bits(domain->regmap, > GPC_PGC_CTRL(domain->pgc), > + GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); > + > + /* request the domain to power down */ > + regmap_update_bits(domain->regmap, > GPC_PU_PGC_SW_PDN_REQ, > + domain->bits.pxx, domain->bits.pxx); > + /* > + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > + * for PUP_REQ/PDN_REQ bit to be cleared > + */ > + ret = regmap_read_poll_timeout(domain->regmap, > + GPC_PU_PGC_SW_PDN_REQ, reg_val, > + !(reg_val & domain->bits.pxx), > + 0, USEC_PER_MSEC); > + if (ret) { > + dev_err(domain->dev, "failed to command PGC\n"); > + goto out_clk_disable; > + } > } > > /* Disable reset clocks for all devices in the domain */ @@ -580,8 > +586,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) > > pm_runtime_enable(domain->dev); > > - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > - domain->bits.map, domain->bits.map); > + if (domain->bits.map) > + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > + domain->bits.map, domain->bits.map); > > ret = pm_genpd_init(&domain->genpd, NULL, true); > if (ret) { > @@ -601,8 +608,9 @@ static int imx_pgc_domain_probe(struct > platform_device *pdev) > out_genpd_remove: > pm_genpd_remove(&domain->genpd); > out_domain_unmap: > - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > - domain->bits.map, 0); > + if (domain->bits.map) > + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > + domain->bits.map, 0); > pm_runtime_disable(domain->dev); > imx_pgc_put_clocks(domain); > > @@ -616,8 +624,9 @@ static int imx_pgc_domain_remove(struct > platform_device *pdev) > of_genpd_del_provider(domain->dev->of_node); > pm_genpd_remove(&domain->genpd); > > - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > - domain->bits.map, 0); > + if (domain->bits.map) > + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > + domain->bits.map, 0); > > pm_runtime_disable(domain->dev); > > -- > 2.20.1
Sorry, my fault, ignore this comment. BR Jacky Bai > -----Original Message----- > From: Jacky Bai > Sent: Friday, October 9, 2020 3:54 PM > To: Lucas Stach <l.stach@pengutronix.de>; Shawn Guo > <shawnguo@kernel.org>; Rob Herring <robh+dt@kernel.org> > Cc: dl-linux-imx <linux-imx@nxp.com>; Fabio Estevam > <festevam@gmail.com>; Frieder Schrempf <frieder.schrempf@kontron.de>; > Marek Vasut <marex@denx.de>; linux-arm-kernel@lists.infradead.org; > devicetree@vger.kernel.org; kernel@pengutronix.de; > patchwork-lst@pengutronix.de > Subject: RE: [PATCH 06/11] soc: imx: gpcv2: allow domains without > power-sequence control > > > -----Original Message----- > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > Sent: Wednesday, September 30, 2020 11:50 PM > > To: Shawn Guo <shawnguo@kernel.org>; Rob Herring > <robh+dt@kernel.org> > > Cc: dl-linux-imx <linux-imx@nxp.com>; Fabio Estevam > > <festevam@gmail.com>; Frieder Schrempf <frieder.schrempf@kontron.de>; > > Marek Vasut <marex@denx.de>; linux-arm-kernel@lists.infradead.org; > > devicetree@vger.kernel.org; kernel@pengutronix.de; > > patchwork-lst@pengutronix.de > > Subject: [PATCH 06/11] soc: imx: gpcv2: allow domains without > > power-sequence control > > > > Some of the PGC domains only control the handshake with the ADB400 and > > don't have any power sequence controls. Make such domains work by > > allowing the pxx and map bits to be empty and skip all actions using > > those controls. > > > > Signed-off-by: Lucas Stach <l.stach@pengutronix.de> > > --- > > drivers/soc/imx/gpcv2.c | 89 > > +++++++++++++++++++++++------------------ > > 1 file changed, 49 insertions(+), 40 deletions(-) > > > > diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index > > 5bb7b1cc7c10..db93fef0c76b 100644 > > --- a/drivers/soc/imx/gpcv2.c > > +++ b/drivers/soc/imx/gpcv2.c > > @@ -167,24 +167,27 @@ static int imx_pgc_power_up(struct > > generic_pm_domain *genpd) > > } > > } > > > > - /* request the domain to power up */ > > - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, > > - domain->bits.pxx, domain->bits.pxx); > > - /* > > - * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > > - * for PUP_REQ/PDN_REQ bit to be cleared > > - */ > > - ret = regmap_read_poll_timeout(domain->regmap, > > GPC_PU_PGC_SW_PUP_REQ, > > - reg_val, !(reg_val & domain->bits.pxx), > > - 0, USEC_PER_MSEC); > > - if (ret) { > > - dev_err(domain->dev, "failed to command PGC\n"); > > - goto out_clk_disable; > > - } > > + if (domain->bits.pxx) { > > What if the power domain's PUP/PDN control bit define is zero, for example, > IMX8M_MIPI_SW_Pxx_REQ? > > BR > Jacky Bai > > > + /* request the domain to power up */ > > + regmap_update_bits(domain->regmap, > > GPC_PU_PGC_SW_PUP_REQ, > > + domain->bits.pxx, domain->bits.pxx); > > + /* > > + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > > + * for PUP_REQ/PDN_REQ bit to be cleared > > + */ > > + ret = regmap_read_poll_timeout(domain->regmap, > > + GPC_PU_PGC_SW_PUP_REQ, reg_val, > > + !(reg_val & domain->bits.pxx), > > + 0, USEC_PER_MSEC); > > + if (ret) { > > + dev_err(domain->dev, "failed to command PGC\n"); > > + goto out_clk_disable; > > + } > > > > - /* disable power control */ > > - regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), > > - GPC_PGC_CTRL_PCR, 0); > > + /* disable power control */ > > + regmap_update_bits(domain->regmap, > > GPC_PGC_CTRL(domain->pgc), > > + GPC_PGC_CTRL_PCR, 0); > > + } > > > > /* request the ADB400 to power up */ > > if (domain->bits.hskreq) { > > @@ -248,23 +251,26 @@ static int imx_pgc_power_down(struct > > generic_pm_domain *genpd) > > } > > } > > > > - /* enable power control */ > > - regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), > > - GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); > > - > > - /* request the domain to power down */ > > - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, > > - domain->bits.pxx, domain->bits.pxx); > > - /* > > - * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > > - * for PUP_REQ/PDN_REQ bit to be cleared > > - */ > > - ret = regmap_read_poll_timeout(domain->regmap, > > GPC_PU_PGC_SW_PDN_REQ, > > - reg_val, !(reg_val & domain->bits.pxx), > > - 0, USEC_PER_MSEC); > > - if (ret) { > > - dev_err(domain->dev, "failed to command PGC\n"); > > - goto out_clk_disable; > > + if (domain->bits.pxx) { > > + /* enable power control */ > > + regmap_update_bits(domain->regmap, > > GPC_PGC_CTRL(domain->pgc), > > + GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); > > + > > + /* request the domain to power down */ > > + regmap_update_bits(domain->regmap, > > GPC_PU_PGC_SW_PDN_REQ, > > + domain->bits.pxx, domain->bits.pxx); > > + /* > > + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait > > + * for PUP_REQ/PDN_REQ bit to be cleared > > + */ > > + ret = regmap_read_poll_timeout(domain->regmap, > > + GPC_PU_PGC_SW_PDN_REQ, reg_val, > > + !(reg_val & domain->bits.pxx), > > + 0, USEC_PER_MSEC); > > + if (ret) { > > + dev_err(domain->dev, "failed to command PGC\n"); > > + goto out_clk_disable; > > + } > > } > > > > /* Disable reset clocks for all devices in the domain */ @@ -580,8 > > +586,9 @@ static int imx_pgc_domain_probe(struct platform_device > > +*pdev) > > > > pm_runtime_enable(domain->dev); > > > > - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > > - domain->bits.map, domain->bits.map); > > + if (domain->bits.map) > > + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > > + domain->bits.map, domain->bits.map); > > > > ret = pm_genpd_init(&domain->genpd, NULL, true); > > if (ret) { > > @@ -601,8 +608,9 @@ static int imx_pgc_domain_probe(struct > > platform_device *pdev) > > out_genpd_remove: > > pm_genpd_remove(&domain->genpd); > > out_domain_unmap: > > - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > > - domain->bits.map, 0); > > + if (domain->bits.map) > > + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > > + domain->bits.map, 0); > > pm_runtime_disable(domain->dev); > > imx_pgc_put_clocks(domain); > > > > @@ -616,8 +624,9 @@ static int imx_pgc_domain_remove(struct > > platform_device *pdev) > > of_genpd_del_provider(domain->dev->of_node); > > pm_genpd_remove(&domain->genpd); > > > > - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > > - domain->bits.map, 0); > > + if (domain->bits.map) > > + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, > > + domain->bits.map, 0); > > > > pm_runtime_disable(domain->dev); > > > > -- > > 2.20.1
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 5bb7b1cc7c10..db93fef0c76b 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -167,24 +167,27 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) } } - /* request the domain to power up */ - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, - domain->bits.pxx, domain->bits.pxx); - /* - * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait - * for PUP_REQ/PDN_REQ bit to be cleared - */ - ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, - reg_val, !(reg_val & domain->bits.pxx), - 0, USEC_PER_MSEC); - if (ret) { - dev_err(domain->dev, "failed to command PGC\n"); - goto out_clk_disable; - } + if (domain->bits.pxx) { + /* request the domain to power up */ + regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, + domain->bits.pxx, domain->bits.pxx); + /* + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait + * for PUP_REQ/PDN_REQ bit to be cleared + */ + ret = regmap_read_poll_timeout(domain->regmap, + GPC_PU_PGC_SW_PUP_REQ, reg_val, + !(reg_val & domain->bits.pxx), + 0, USEC_PER_MSEC); + if (ret) { + dev_err(domain->dev, "failed to command PGC\n"); + goto out_clk_disable; + } - /* disable power control */ - regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), - GPC_PGC_CTRL_PCR, 0); + /* disable power control */ + regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), + GPC_PGC_CTRL_PCR, 0); + } /* request the ADB400 to power up */ if (domain->bits.hskreq) { @@ -248,23 +251,26 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) } } - /* enable power control */ - regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), - GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); - - /* request the domain to power down */ - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, - domain->bits.pxx, domain->bits.pxx); - /* - * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait - * for PUP_REQ/PDN_REQ bit to be cleared - */ - ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, - reg_val, !(reg_val & domain->bits.pxx), - 0, USEC_PER_MSEC); - if (ret) { - dev_err(domain->dev, "failed to command PGC\n"); - goto out_clk_disable; + if (domain->bits.pxx) { + /* enable power control */ + regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), + GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); + + /* request the domain to power down */ + regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, + domain->bits.pxx, domain->bits.pxx); + /* + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait + * for PUP_REQ/PDN_REQ bit to be cleared + */ + ret = regmap_read_poll_timeout(domain->regmap, + GPC_PU_PGC_SW_PDN_REQ, reg_val, + !(reg_val & domain->bits.pxx), + 0, USEC_PER_MSEC); + if (ret) { + dev_err(domain->dev, "failed to command PGC\n"); + goto out_clk_disable; + } } /* Disable reset clocks for all devices in the domain */ @@ -580,8 +586,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) pm_runtime_enable(domain->dev); - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, - domain->bits.map, domain->bits.map); + if (domain->bits.map) + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, + domain->bits.map, domain->bits.map); ret = pm_genpd_init(&domain->genpd, NULL, true); if (ret) { @@ -601,8 +608,9 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) out_genpd_remove: pm_genpd_remove(&domain->genpd); out_domain_unmap: - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, - domain->bits.map, 0); + if (domain->bits.map) + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, + domain->bits.map, 0); pm_runtime_disable(domain->dev); imx_pgc_put_clocks(domain); @@ -616,8 +624,9 @@ static int imx_pgc_domain_remove(struct platform_device *pdev) of_genpd_del_provider(domain->dev->of_node); pm_genpd_remove(&domain->genpd); - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, - domain->bits.map, 0); + if (domain->bits.map) + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, + domain->bits.map, 0); pm_runtime_disable(domain->dev);
Some of the PGC domains only control the handshake with the ADB400 and don't have any power sequence controls. Make such domains work by allowing the pxx and map bits to be empty and skip all actions using those controls. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> --- drivers/soc/imx/gpcv2.c | 89 +++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 40 deletions(-)