summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/arm720t/tegra114/cpu.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/arch/arm/cpu/arm720t/tegra114/cpu.c b/arch/arm/cpu/arm720t/tegra114/cpu.c
index 0b2157a0df..6a94179d4a 100644
--- a/arch/arm/cpu/arm720t/tegra114/cpu.c
+++ b/arch/arm/cpu/arm720t/tegra114/cpu.c
@@ -270,6 +270,8 @@ void powerup_cpus(void)
void start_cpu(u32 reset_vector)
{
+ u32 imme, inst;
+
debug("start_cpu entry, reset_vector = %x\n", reset_vector);
t114_init_clocks();
@@ -286,12 +288,38 @@ void start_cpu(u32 reset_vector)
/* Take CPU(s) out of reset */
remove_cpu_resets();
+ /* Set the entry point for CPU execution from reset */
+
/*
- * Set the entry point for CPU execution from reset,
- * if it's a non-zero value.
+ * A01P with patched boot ROM; vector hard-coded to 0x4003fffc.
+ * See nvbug 1193357 for details.
*/
- if (reset_vector)
- writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
+
+ /* mov r0, #lsb(reset_vector) */
+ imme = reset_vector & 0xffff;
+ inst = imme & 0xfff;
+ inst |= ((imme >> 12) << 16);
+ inst |= 0xe3000000;
+ writel(inst, 0x4003fff0);
+
+ /* movt r0, #msb(reset_vector) */
+ imme = (reset_vector >> 16) & 0xffff;
+ inst = imme & 0xfff;
+ inst |= ((imme >> 12) << 16);
+ inst |= 0xe3400000;
+ writel(inst, 0x4003fff4);
+
+ /* bx r0 */
+ writel(0xe12fff10, 0x4003fff8);
+
+ /* b -12 */
+ imme = (u32)-20;
+ inst = (imme >> 2) & 0xffffff;
+ inst |= 0xea000000;
+ writel(inst, 0x4003fffc);
+
+ /* Write to orignal location for compatibility */
+ writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR);
/* If the CPU(s) don't already have power, power 'em up */
powerup_cpus();