diff mbox series

[07/11] soc: imx: gpcv2: add support for optional resets

Message ID 20200930155006.535712-8-l.stach@pengutronix.de (mailing list archive)
State New, archived
Headers show
Series i.MX8MM power domain support | expand

Commit Message

Lucas Stach Sept. 30, 2020, 3:50 p.m. UTC
Normally the reset for the devices inside the power domain is
triggered automatically from the PGC in the power-up sequencing,
however on i.MX8MM this doesn't work for the GPU power domains.

Add support for triggering the reset explicitly during the power
up sequencing.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
---
 .../devicetree/bindings/power/fsl,imx-gpcv2.yaml    |  6 ++++++
 drivers/soc/imx/gpcv2.c                             | 13 +++++++++++++
 2 files changed, 19 insertions(+)

Comments

Marek Vasut Sept. 30, 2020, 4:15 p.m. UTC | #1
On 9/30/20 5:50 PM, Lucas Stach wrote:
> Normally the reset for the devices inside the power domain is
> triggered automatically from the PGC in the power-up sequencing,
> however on i.MX8MM this doesn't work for the GPU power domains.

One has to wonder whether the VPU power domain has similar hardware bug
on the MX8MM ?

[...]

> @@ -112,6 +113,7 @@ struct imx_pgc_domain {
>  	struct regulator *regulator;
>  	struct clk *clk[GPC_CLK_MAX];
>  	int num_clks;
> +	struct reset_control *reset;

Keep this sorted as reverse xmas tree please.

>  	unsigned int pgc;

[...]
Lucas Stach Sept. 30, 2020, 4:23 p.m. UTC | #2
On Mi, 2020-09-30 at 18:15 +0200, Marek Vasut wrote:
> On 9/30/20 5:50 PM, Lucas Stach wrote:
> > Normally the reset for the devices inside the power domain is
> > triggered automatically from the PGC in the power-up sequencing,
> > however on i.MX8MM this doesn't work for the GPU power domains.
> 
> One has to wonder whether the VPU power domain has similar hardware bug
> on the MX8MM ?

Nope the VPUs have separate reset bits in the BLK_CTL. So after
powering up the VPUMIX domain one can assert/deassert reset to the
individual VPU cores.

Regards,
Lucas

> [...]
> 
> > @@ -112,6 +113,7 @@ struct imx_pgc_domain {
> >  	struct regulator *regulator;
> >  	struct clk *clk[GPC_CLK_MAX];
> >  	int num_clks;
> > +	struct reset_control *reset;
> 
> Keep this sorted as reverse xmas tree please.

Triggering some OCD, here? ;) Will do.

Regards,
Lucas
Marek Vasut Sept. 30, 2020, 4:30 p.m. UTC | #3
On 9/30/20 6:23 PM, Lucas Stach wrote:
> On Mi, 2020-09-30 at 18:15 +0200, Marek Vasut wrote:
>> On 9/30/20 5:50 PM, Lucas Stach wrote:
>>> Normally the reset for the devices inside the power domain is
>>> triggered automatically from the PGC in the power-up sequencing,
>>> however on i.MX8MM this doesn't work for the GPU power domains.
>>
>> One has to wonder whether the VPU power domain has similar hardware bug
>> on the MX8MM ?
> 
> Nope the VPUs have separate reset bits in the BLK_CTL. So after
> powering up the VPUMIX domain one can assert/deassert reset to the
> individual VPU cores.

Is there any documentation for the BLK_CTL on MX8MM ? I can't find any
in the official RM.

And also, the GPUs need to use SRC reset, does the BLK_CTL reset do the
same "degree" of reset to the VPU as the SRC reset does to the GPUs ?
Lucas Stach Sept. 30, 2020, 4:34 p.m. UTC | #4
On Mi, 2020-09-30 at 18:30 +0200, Marek Vasut wrote:
> On 9/30/20 6:23 PM, Lucas Stach wrote:
> > On Mi, 2020-09-30 at 18:15 +0200, Marek Vasut wrote:
> > > On 9/30/20 5:50 PM, Lucas Stach wrote:
> > > > Normally the reset for the devices inside the power domain is
> > > > triggered automatically from the PGC in the power-up sequencing,
> > > > however on i.MX8MM this doesn't work for the GPU power domains.
> > > 
> > > One has to wonder whether the VPU power domain has similar hardware bug
> > > on the MX8MM ?
> > 
> > Nope the VPUs have separate reset bits in the BLK_CTL. So after
> > powering up the VPUMIX domain one can assert/deassert reset to the
> > individual VPU cores.
> 
> Is there any documentation for the BLK_CTL on MX8MM ? I can't find any
> in the official RM.

I'm still waiting on some info from NXP about this. It is not
documented in the RM.

> And also, the GPUs need to use SRC reset, does the BLK_CTL reset do the
> same "degree" of reset to the VPU as the SRC reset does to the GPUs ?

At least that is what I'm assuming.

The fundamental issue with the GPU domain is that there is no BLK_CTL
in the GPUMIX domain and the resets are hooked up to the shared SRC
reset, instead of having GPU BLK_CTL level resets.

Regards,
Lucas
Marek Vasut Sept. 30, 2020, 4:38 p.m. UTC | #5
On 9/30/20 6:34 PM, Lucas Stach wrote:
> On Mi, 2020-09-30 at 18:30 +0200, Marek Vasut wrote:
>> On 9/30/20 6:23 PM, Lucas Stach wrote:
>>> On Mi, 2020-09-30 at 18:15 +0200, Marek Vasut wrote:
>>>> On 9/30/20 5:50 PM, Lucas Stach wrote:
>>>>> Normally the reset for the devices inside the power domain is
>>>>> triggered automatically from the PGC in the power-up sequencing,
>>>>> however on i.MX8MM this doesn't work for the GPU power domains.
>>>>
>>>> One has to wonder whether the VPU power domain has similar hardware bug
>>>> on the MX8MM ?
>>>
>>> Nope the VPUs have separate reset bits in the BLK_CTL. So after
>>> powering up the VPUMIX domain one can assert/deassert reset to the
>>> individual VPU cores.
>>
>> Is there any documentation for the BLK_CTL on MX8MM ? I can't find any
>> in the official RM.
> 
> I'm still waiting on some info from NXP about this. It is not
> documented in the RM.

Yes, I know.

>> And also, the GPUs need to use SRC reset, does the BLK_CTL reset do the
>> same "degree" of reset to the VPU as the SRC reset does to the GPUs ?
> 
> At least that is what I'm assuming.
> 
> The fundamental issue with the GPU domain is that there is no BLK_CTL
> in the GPUMIX domain and the resets are hooked up to the shared SRC
> reset, instead of having GPU BLK_CTL level resets.

Yep.

I'll CC Abel, maybe there is still undocumented way to reset the GPUs on
the MX8MM separately too.
Krzysztof Kozlowski Oct. 1, 2020, 8:59 a.m. UTC | #6
On Wed, 30 Sep 2020 at 17:52, Lucas Stach <l.stach@pengutronix.de> wrote:
>
> Normally the reset for the devices inside the power domain is
> triggered automatically from the PGC in the power-up sequencing,
> however on i.MX8MM this doesn't work for the GPU power domains.
>
> Add support for triggering the reset explicitly during the power
> up sequencing.
>
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  .../devicetree/bindings/power/fsl,imx-gpcv2.yaml    |  6 ++++++
>  drivers/soc/imx/gpcv2.c                             | 13 +++++++++++++
>  2 files changed, 19 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
> index bde09a0b2da3..9773771b9000 100644
> --- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
> +++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
> @@ -62,6 +62,12 @@ properties:
>
>            power-supply: true
>
> +          resets:
> +            description: |
> +              A number of phandles to resets that need to be asserted during
> +              power-up sequencing of the domain.
> +            minItems: 1
> +
>          required:
>            - '#power-domain-cells'
>            - reg

Separate patch for dt-bindings, please.

Best regards,
Krzysztof
Rob Herring Oct. 6, 2020, 7:42 p.m. UTC | #7
On Wed, Sep 30, 2020 at 05:50:02PM +0200, Lucas Stach wrote:
> Normally the reset for the devices inside the power domain is
> triggered automatically from the PGC in the power-up sequencing,
> however on i.MX8MM this doesn't work for the GPU power domains.
> 
> Add support for triggering the reset explicitly during the power
> up sequencing.
> 
> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> ---
>  .../devicetree/bindings/power/fsl,imx-gpcv2.yaml    |  6 ++++++
>  drivers/soc/imx/gpcv2.c                             | 13 +++++++++++++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
> index bde09a0b2da3..9773771b9000 100644
> --- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
> +++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
> @@ -62,6 +62,12 @@ properties:
>  
>            power-supply: true
>  
> +          resets:
> +            description: |
> +              A number of phandles to resets that need to be asserted during
> +              power-up sequencing of the domain.
> +            minItems: 1

What's the max? It's going to default to 1 if you don't say.

> +
>          required:
>            - '#power-domain-cells'
>            - reg
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
> index db93fef0c76b..76aa8a67d8a7 100644
> --- a/drivers/soc/imx/gpcv2.c
> +++ b/drivers/soc/imx/gpcv2.c
> @@ -15,6 +15,7 @@
>  #include <linux/pm_runtime.h>
>  #include <linux/regmap.h>
>  #include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
>  #include <linux/sizes.h>
>  #include <dt-bindings/power/imx7-power.h>
>  #include <dt-bindings/power/imx8mq-power.h>
> @@ -112,6 +113,7 @@ struct imx_pgc_domain {
>  	struct regulator *regulator;
>  	struct clk *clk[GPC_CLK_MAX];
>  	int num_clks;
> +	struct reset_control *reset;
>  
>  	unsigned int pgc;
>  
> @@ -167,6 +169,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
>  		}
>  	}
>  
> +	reset_control_assert(domain->reset);
> +
>  	if (domain->bits.pxx) {
>  		/* request the domain to power up */
>  		regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
> @@ -189,6 +193,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
>  				   GPC_PGC_CTRL_PCR, 0);
>  	}
>  
> +	reset_control_deassert(domain->reset);
> +
>  	/* request the ADB400 to power up */
>  	if (domain->bits.hskreq) {
>  		regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
> @@ -577,6 +583,13 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
>  				      domain->voltage, domain->voltage);
>  	}
>  
> +	domain->reset = devm_reset_control_array_get_optional_exclusive(domain->dev);
> +	if (IS_ERR(domain->reset)) {
> +		if (PTR_ERR(domain->reset) != -EPROBE_DEFER)
> +			dev_err(domain->dev, "Failed to get domain's reset\n");
> +		return PTR_ERR(domain->reset);
> +	}
> +
>  	ret = imx_pgc_get_clocks(domain);
>  	if (ret) {
>  		if (ret != -EPROBE_DEFER)
> -- 
> 2.20.1
>
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
index bde09a0b2da3..9773771b9000 100644
--- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
+++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
@@ -62,6 +62,12 @@  properties:
 
           power-supply: true
 
+          resets:
+            description: |
+              A number of phandles to resets that need to be asserted during
+              power-up sequencing of the domain.
+            minItems: 1
+
         required:
           - '#power-domain-cells'
           - reg
diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index db93fef0c76b..76aa8a67d8a7 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -15,6 +15,7 @@ 
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/sizes.h>
 #include <dt-bindings/power/imx7-power.h>
 #include <dt-bindings/power/imx8mq-power.h>
@@ -112,6 +113,7 @@  struct imx_pgc_domain {
 	struct regulator *regulator;
 	struct clk *clk[GPC_CLK_MAX];
 	int num_clks;
+	struct reset_control *reset;
 
 	unsigned int pgc;
 
@@ -167,6 +169,8 @@  static int imx_pgc_power_up(struct generic_pm_domain *genpd)
 		}
 	}
 
+	reset_control_assert(domain->reset);
+
 	if (domain->bits.pxx) {
 		/* request the domain to power up */
 		regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
@@ -189,6 +193,8 @@  static int imx_pgc_power_up(struct generic_pm_domain *genpd)
 				   GPC_PGC_CTRL_PCR, 0);
 	}
 
+	reset_control_deassert(domain->reset);
+
 	/* request the ADB400 to power up */
 	if (domain->bits.hskreq) {
 		regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
@@ -577,6 +583,13 @@  static int imx_pgc_domain_probe(struct platform_device *pdev)
 				      domain->voltage, domain->voltage);
 	}
 
+	domain->reset = devm_reset_control_array_get_optional_exclusive(domain->dev);
+	if (IS_ERR(domain->reset)) {
+		if (PTR_ERR(domain->reset) != -EPROBE_DEFER)
+			dev_err(domain->dev, "Failed to get domain's reset\n");
+		return PTR_ERR(domain->reset);
+	}
+
 	ret = imx_pgc_get_clocks(domain);
 	if (ret) {
 		if (ret != -EPROBE_DEFER)