From 06c10df889d4d935bc99792df860d93766ae44dd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 15 Nov 2013 16:29:07 -0800 Subject: [PATCH] tegra124: When leaving the bootblock/AVP, really stop the AVP. We'd been stopping the AVP by calling hlt, but this just puts it into a loop which it busily executes forever. If the memory the loop is in is replaced, however, the AVP will race off and do something random. It turns out that it was writing the early parts of the rom stage into memory on top of the kernel as it ran, either by coincidence or because it had rebooted and was actually reloading the stage into memory. Many thanks to Hung-Te for determining what was being overwritten by what which helped determine who was doing the overwriting. BUG=None TEST=Before this change, booting in normal mode would cause the kernel to behave strangely, often crashing. With this change, the kernel seems to boot fine in normal mode. BRANCH=None Change-Id: I292c039c28691387e72386d2a9321c29437076ed Signed-off-by: Gabe Black Reviewed-on: https://chromium-review.googlesource.com/177086 Reviewed-by: Julius Werner Tested-by: Gabe Black Commit-Queue: Gabe Black --- src/soc/nvidia/tegra124/bootblock.c | 2 +- src/soc/nvidia/tegra124/clock.c | 9 +++++++++ src/soc/nvidia/tegra124/include/soc/clock.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/soc/nvidia/tegra124/bootblock.c b/src/soc/nvidia/tegra124/bootblock.c index 2698611fba..3355ce34c2 100644 --- a/src/soc/nvidia/tegra124/bootblock.c +++ b/src/soc/nvidia/tegra124/bootblock.c @@ -63,5 +63,5 @@ void main(void) if (entry) clock_cpu0_config_and_reset(entry); - hlt(); + clock_halt_avp(); } diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c index e1494c80c9..2cf5b77c0a 100644 --- a/src/soc/nvidia/tegra124/clock.c +++ b/src/soc/nvidia/tegra124/clock.c @@ -372,6 +372,15 @@ void clock_cpu0_config_and_reset(void *entry) &clk_rst->rst_cpug_cmplx_clr); } +void clock_halt_avp(void) +{ + for (;;) { + write32(FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ | + FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT, + &flow->halt_cop_events); + } +} + void clock_init(void) { u32 osc = clock_get_osc_bits(); diff --git a/src/soc/nvidia/tegra124/include/soc/clock.h b/src/soc/nvidia/tegra124/include/soc/clock.h index 3eec82c733..3ec36080c7 100644 --- a/src/soc/nvidia/tegra124/include/soc/clock.h +++ b/src/soc/nvidia/tegra124/include/soc/clock.h @@ -248,6 +248,7 @@ int clock_get_osc_khz(void); void clock_early_uart(void); void clock_external_output(int clk_id); void clock_cpu0_config_and_reset(void * entry); +void clock_halt_avp(void); void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x); void clock_init(void); void clock_init_arm_generic_timer(void);