diff options
author | Simon Glass <sjg@chromium.org> | 2011-11-05 03:56:50 +0000 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2011-12-09 17:30:09 +0100 |
commit | 210576fc5e5d323c8039f95c7b5b2c7512a550e4 (patch) | |
tree | 5e2998868cd26796a8e25f0fbee25bd248db2f59 | |
parent | e43d6ed932a4fbeb4c53a66bd2b7fc1f802a810e (diff) |
tegra2: Simplify tegra_start() boot path
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>
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/ap20.c | 54 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/tegra2/ap20.h | 3 |
3 files changed, 37 insertions, 25 deletions
diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index f0dc2ffa83b..955c3b6dc41 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -23,6 +23,11 @@ # 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 diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c index 5cb4b1b6a0e..4c44bb36377 100644 --- a/arch/arm/cpu/armv7/tegra2/ap20.c +++ b/arch/arm/cpu/armv7/tegra2/ap20.c @@ -31,7 +31,12 @@ #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? */ } diff --git a/arch/arm/cpu/armv7/tegra2/ap20.h b/arch/arm/cpu/armv7/tegra2/ap20.h index 49fe340a28d..1bb48d6a00a 100644 --- a/arch/arm/cpu/armv7/tegra2/ap20.h +++ b/arch/arm/cpu/armv7/tegra2/ap20.h @@ -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); |