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

Carl Philipp Klemm philipp at uvos.xyz
Tue Dec 8 15:48:14 EST 2020


On Tue,  8 Dec 2020 16:08:02 +0200
Tony Lindgren <tony at 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 at uvos.xyz>
> Cc: Philipp Zabel <p.zabel at pengutronix.de>
> Cc: Santosh Shilimkar <ssantosh at kernel.org>
> Cc: Suman Anna <s-anna at ti.com>
> Cc: Tero Kristo <t-kristo at ti.com>
> Signed-off-by: Tony Lindgren <tony at 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 at uvos.xyz>



More information about the linux-arm-kernel mailing list