tegra2: Simplify tegra_start() boot path
authorSimon Glass <sjg@chromium.org>
Sat, 5 Nov 2011 03:56:50 +0000 (03:56 +0000)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Fri, 9 Dec 2011 16:30:09 +0000 (17:30 +0100)
The Tegra2 boot path is more complicated than it needs to be. Since we want
to move to building most of U-Boot with ARMv7 and only a small part with
ARMv4T (for AVP) it should be as simple as possible.

This makes tegra2_start() into a simple function which either does AVP
init or A9 init depending on which core is running it. Both cores now
following the same init path, beginning at _start, and the special Tegra2
boot path code is no longer required.

Only two files need to be built for ARMv4T, and this is handled in the
Tegra2 CPU Makefile.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Warren <twarren@nvidia.com>
arch/arm/cpu/armv7/tegra2/Makefile
arch/arm/cpu/armv7/tegra2/ap20.c
arch/arm/cpu/armv7/tegra2/ap20.h

index f0dc2ffa83b36b42bc64afdd53e045265fce45bf..955c3b6dc414f497addd6bb491f7cf1cef67a29d 100644 (file)
 # MA 02111-1307 USA
 #
 
+# The AVP is ARMv4T architecture so we must use special compiler
+# flags for any startup files it might use.
+CFLAGS_arch/arm/cpu/armv7/tegra2/ap20.o += -march=armv4t
+CFLAGS_arch/arm/cpu/armv7/tegra2/clock.o += -march=armv4t
+
 include $(TOPDIR)/config.mk
 
 LIB    =  $(obj)lib$(SOC).o
index 5cb4b1b6a0e2a14e3ed2e17f3855c83cb1ce32a3..4c44bb3637736902970a72b207c350110455725a 100644 (file)
 #include <asm/arch/scu.h>
 #include <common.h>
 
-u32 s_first_boot = 1;
+/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */
+static int ap20_cpu_is_cortexa9(void)
+{
+       u32 id = readb(NV_PA_PG_UP_BASE + PG_UP_TAG_0);
+       return id == (PG_UP_TAG_0_PID_CPU & 0xff);
+}
 
 void init_pllx(void)
 {
@@ -283,38 +288,37 @@ void init_pmc_scratch(void)
        writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
 }
 
-void cpu_start(void)
+void tegra2_start(void)
 {
        struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
 
-       /* enable JTAG */
-       writel(0xC0, &pmt->pmt_cfg_ctl);
+       /* If we are the AVP, start up the first Cortex-A9 */
+       if (!ap20_cpu_is_cortexa9()) {
+               /* enable JTAG */
+               writel(0xC0, &pmt->pmt_cfg_ctl);
 
-       if (s_first_boot) {
                /*
-                * Need to set this before cold-booting,
-                *  otherwise we'll end up in an infinite loop.
-                */
-               s_first_boot = 0;
-               cold_boot();
+               * If we are ARM7 - give it a different stack. We are about to
+               * start up the A9 which will want to use this one.
+               */
+               asm volatile("ldr       sp, =%c0\n"
+                       : : "i"(AVP_EARLY_BOOT_STACK_LIMIT));
+
+               start_cpu((u32)_start);
+               halt_avp();
+               /* not reached */
        }
-}
 
-void tegra2_start()
-{
-       if (s_first_boot) {
-               /* Init Debug UART Port (115200 8n1) */
-               uart_init();
+       /* Init PMC scratch memory */
+       init_pmc_scratch();
 
-               /* Init PMC scratch memory */
-               init_pmc_scratch();
-       }
+       enable_scu();
 
-#ifdef CONFIG_ENABLE_CORTEXA9
-       /* take the mpcore out of reset */
-       cpu_start();
+       /* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */
+       asm volatile(
+               "mrc    p15, 0, r0, c1, c0, 1\n"
+               "orr    r0, r0, #0x41\n"
+               "mcr    p15, 0, r0, c1, c0, 1\n");
 
-       /* configure cache */
-       cache_configure();
-#endif
+       /* FIXME: should have ap20's L2 disabled too? */
 }
index 49fe340a28dc2b6c1f80cbe6d8ff15380bc70386..1bb48d6a00a9c4660b116706cc02683a0b8d737b 100644 (file)
@@ -102,3 +102,6 @@ void uart_init(void);
 void udelay(unsigned long);
 void cold_boot(void);
 void cache_configure(void);
+
+/* This is the main entry into U-Boot, used by the Cortex-A9 */
+extern void _start(void);