diff mbox series

soc: ti: omap-prm: Fix boot time errors for rst_map_012 bits 0 and 1

Message ID 20201208140802.38757-1-tony@atomide.com (mailing list archive)
State New, archived
Headers show
Series soc: ti: omap-prm: Fix boot time errors for rst_map_012 bits 0 and 1 | expand

Commit Message

Tony Lindgren Dec. 8, 2020, 2:08 p.m. UTC
We have rst_map_012 used for various accelerators like dsp, ipu and iva.
For these use cases, we have rstctrl bit 2 control the subsystem module
reset, and have and bits 0 and 1 control the accelerator specific
features.

If the bootloader, or kexec boot, has left any accelerator specific
reset bits deasserted, deasserting bit 2 reset will potentially enable
an accelerator with unconfigured MMU and no firmware. And we may get
spammed with a lot by warnings on boot with "Data Access in User mode
during Functional access", or depending on the accelerator, the system
can also just hang.

This issue can be quite easily reproduced by setting a rst_map_012 type
rstctrl register to 0 or 4 in the bootloader, and booting the system.

Let's just assert all reset bits for rst_map_012 type resets. So far
it looks like the other rstctrl types don't need this. If it turns out
that the other type rstctrl bits also need reset on init, we need to
add an instance specific reset mask for the bits to avoid resetting
unwanted bits.

Reported-by: Carl Philipp Klemm <philipp@uvos.xyz>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: Santosh Shilimkar <ssantosh@kernel.org>
Cc: Suman Anna <s-anna@ti.com>
Cc: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
 drivers/soc/ti/omap_prm.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Comments

Carl Philipp Klemm Dec. 8, 2020, 8:48 p.m. UTC | #1
On Tue,  8 Dec 2020 16:08:02 +0200
Tony Lindgren <tony@atomide.com> wrote:

> We have rst_map_012 used for various accelerators like dsp, ipu and iva.
> For these use cases, we have rstctrl bit 2 control the subsystem module
> reset, and have and bits 0 and 1 control the accelerator specific
> features.
> 
> If the bootloader, or kexec boot, has left any accelerator specific
> reset bits deasserted, deasserting bit 2 reset will potentially enable
> an accelerator with unconfigured MMU and no firmware. And we may get
> spammed with a lot by warnings on boot with "Data Access in User mode
> during Functional access", or depending on the accelerator, the system
> can also just hang.
> 
> This issue can be quite easily reproduced by setting a rst_map_012 type
> rstctrl register to 0 or 4 in the bootloader, and booting the system.
> 
> Let's just assert all reset bits for rst_map_012 type resets. So far
> it looks like the other rstctrl types don't need this. If it turns out
> that the other type rstctrl bits also need reset on init, we need to
> add an instance specific reset mask for the bits to avoid resetting
> unwanted bits.
> 
> Reported-by: Carl Philipp Klemm <philipp@uvos.xyz>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Santosh Shilimkar <ssantosh@kernel.org>
> Cc: Suman Anna <s-anna@ti.com>
> Cc: Tero Kristo <t-kristo@ti.com>
> Signed-off-by: Tony Lindgren <tony@atomide.com>
> ---
>  drivers/soc/ti/omap_prm.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
> --- a/drivers/soc/ti/omap_prm.c
> +++ b/drivers/soc/ti/omap_prm.c
> @@ -860,6 +860,7 @@ static int omap_prm_reset_init(struct platform_device *pdev,
>  	const struct omap_rst_map *map;
>  	struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev);
>  	char buf[32];
> +	u32 v;
>  
>  	/*
>  	 * Check if we have controllable resets. If either rstctrl is non-zero
> @@ -907,6 +908,16 @@ static int omap_prm_reset_init(struct platform_device *pdev,
>  		map++;
>  	}
>  
> +	/* Quirk handling to assert rst_map_012 bits on reset and avoid errors */
> +	if (prm->data->rstmap == rst_map_012) {
> +		v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
> +		if ((v & reset->mask) != reset->mask) {
> +			dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v);
> +			writel_relaxed(reset->mask, reset->prm->base +
> +				       reset->prm->data->rstctrl);
> +		}
> +	}
> +
>  	return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
>  }
>  
> -- 
> 2.29.2

Works for me on xt875, idle now also works without userspace hack.

Tested-by: Carl Philipp Klemm <philipp@uvos.xyz>
diff mbox series

Patch

diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
--- a/drivers/soc/ti/omap_prm.c
+++ b/drivers/soc/ti/omap_prm.c
@@ -860,6 +860,7 @@  static int omap_prm_reset_init(struct platform_device *pdev,
 	const struct omap_rst_map *map;
 	struct ti_prm_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	char buf[32];
+	u32 v;
 
 	/*
 	 * Check if we have controllable resets. If either rstctrl is non-zero
@@ -907,6 +908,16 @@  static int omap_prm_reset_init(struct platform_device *pdev,
 		map++;
 	}
 
+	/* Quirk handling to assert rst_map_012 bits on reset and avoid errors */
+	if (prm->data->rstmap == rst_map_012) {
+		v = readl_relaxed(reset->prm->base + reset->prm->data->rstctrl);
+		if ((v & reset->mask) != reset->mask) {
+			dev_dbg(&pdev->dev, "Asserting all resets: %08x\n", v);
+			writel_relaxed(reset->mask, reset->prm->base +
+				       reset->prm->data->rstctrl);
+		}
+	}
+
 	return devm_reset_controller_register(&pdev->dev, &reset->rcdev);
 }