[U-Boot] [PATCH 0/9] split tegra arm7 code into separate SPL

This patch series fixes a long standing problem with the tegra2 u-boot build. Tegra2 contains an ARM7TDMI boot processor and a Cortex A9 main processor. Prior to this patch series this was accomplished by #ifdefing out any armv7 code from the early boot sequence and creating a single binary that runs on both both the ARM7TDMI and A9. This was very fragile as changes to compiler options or any additions or rearranging of the early boot code could add additional armv7 specific code causing it to fail on the ARM7TDMI.
This patch series pulls all the armv4t code out into a separate SPL that does nothing more than initialize the A9 and transfer control to it. The resultint SPL and armv7 u-boot are concatenated together into a single image.
[PATCH 1/9] tegra2: move tegra2 SoC code to arch/arm/cpu/tegra2-common [PATCH 2/9] mkconfig: add support for SPL CPU [PATCH 3/9] ARM: Fix arm720t SPL build [PATCH 4/9] tegra: Add SPL build support to tegra boards [PATCH 5/9] ARM: add tegra support to arm720t [PATCH 6/9] tegra: enable SPL build for seaboard [PATCH 7/9] tegra: add u-boot.t2 target [PATCH 8/9] tegra2: Remove CPU init code from tegra2 u-boot [PATCH 9/9] tegra2: Remove USE_PRIVATE_LIBGCC and armv4t build flags
Makefile | 9 + arch/arm/cpu/arm720t/cpu.c | 3 +- arch/arm/cpu/arm720t/interrupts.c | 5 +- arch/arm/cpu/arm720t/start.S | 19 +- arch/arm/cpu/arm720t/tegra2/Makefile | 48 ++ arch/arm/cpu/arm720t/tegra2/board.h | 25 + arch/arm/cpu/arm720t/tegra2/cpu.c | 259 +++++++ arch/arm/cpu/arm720t/tegra2/cpu.h | 99 +++ arch/arm/cpu/arm720t/tegra2/spl.c | 133 ++++ arch/arm/cpu/armv7/start.S | 2 - arch/arm/cpu/armv7/tegra2/Makefile | 12 +- arch/arm/cpu/armv7/tegra2/ap20.c | 324 --------- arch/arm/cpu/armv7/tegra2/ap20.h | 102 --- arch/arm/cpu/armv7/tegra2/board.c | 151 ---- arch/arm/cpu/armv7/tegra2/clock.c | 1052 --------------------------- arch/arm/cpu/armv7/tegra2/config.mk | 8 - arch/arm/cpu/armv7/tegra2/funcmux.c | 184 ----- arch/arm/cpu/armv7/tegra2/lowlevel_init.S | 41 -- arch/arm/cpu/armv7/tegra2/pinmux.c | 572 --------------- arch/arm/cpu/armv7/tegra2/sys_info.c | 35 - arch/arm/cpu/armv7/tegra2/timer.c | 111 --- arch/arm/cpu/tegra2-common/Makefile | 56 ++ arch/arm/cpu/tegra2-common/ap20.c | 73 ++ arch/arm/cpu/tegra2-common/board.c | 129 ++++ arch/arm/cpu/tegra2-common/clock.c | 1052 +++++++++++++++++++++++++++ arch/arm/cpu/tegra2-common/funcmux.c | 184 +++++ arch/arm/cpu/tegra2-common/lowlevel_init.S | 41 ++ arch/arm/cpu/tegra2-common/pinmux.c | 572 +++++++++++++++ arch/arm/cpu/tegra2-common/sys_info.c | 35 + arch/arm/cpu/tegra2-common/timer.c | 111 +++ arch/arm/include/asm/arch-tegra2/hardware.h | 29 + board/nvidia/common/Makefile | 2 +- board/nvidia/common/board.c | 2 + board/nvidia/seaboard/config.mk | 1 + boards.cfg | 7 +- doc/README.SPL | 12 + include/configs/seaboard.h | 9 + include/configs/tegra2-common.h | 23 +- mkconfig | 15 +- spl/Makefile | 4 + 40 files changed, 2949 insertions(+), 2602 deletions(-)
-- nvpublic

In preparation for splitting out the armv4t code from tegra2, move the tegra2 SoC code to arch/arm/cpu/tegra2-common. This code will be compiled armv4t for the arm7tdmi and armv7 for the cortex A9.
Signed-off-by: Allen Martin amartin@nvidia.com --- Makefile | 3 ++ arch/arm/cpu/armv7/tegra2/Makefile | 12 +---- arch/arm/cpu/tegra2-common/Makefile | 56 ++++++++++++++++++++ .../arm/cpu/{armv7/tegra2 => tegra2-common}/ap20.c | 0 .../arm/cpu/{armv7/tegra2 => tegra2-common}/ap20.h | 0 .../cpu/{armv7/tegra2 => tegra2-common}/board.c | 0 .../cpu/{armv7/tegra2 => tegra2-common}/clock.c | 0 .../cpu/{armv7/tegra2 => tegra2-common}/funcmux.c | 0 .../tegra2 => tegra2-common}/lowlevel_init.S | 0 .../cpu/{armv7/tegra2 => tegra2-common}/pinmux.c | 0 .../cpu/{armv7/tegra2 => tegra2-common}/sys_info.c | 0 .../cpu/{armv7/tegra2 => tegra2-common}/timer.c | 0 spl/Makefile | 4 ++ 13 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 arch/arm/cpu/tegra2-common/Makefile rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/ap20.c (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/ap20.h (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/board.c (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/clock.c (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/funcmux.c (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/lowlevel_init.S (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/pinmux.c (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/sys_info.c (100%) rename arch/arm/cpu/{armv7/tegra2 => tegra2-common}/timer.c (100%)
diff --git a/Makefile b/Makefile index 023ea23..8e587f4 100644 --- a/Makefile +++ b/Makefile @@ -319,6 +319,9 @@ endif ifeq ($(SOC),exynos) LIBS += $(CPUDIR)/s5p-common/libs5p-common.o endif +ifeq ($(SOC),tegra2) +LIBS += $(OBJTREE)/arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o +endif
LIBS := $(addprefix $(obj),$(sort $(LIBS))) .PHONY : $(LIBS) diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index e9ac6c9..34452c4 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -22,23 +22,15 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, # 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
-SOBJS := lowlevel_init.o -COBJS-y := ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o COBJS-$(CONFIG_USB_EHCI_TEGRA) += usb.o
COBJS := $(COBJS-y) -SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) -OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS))
all: $(obj).depend $(LIB)
diff --git a/arch/arm/cpu/tegra2-common/Makefile b/arch/arm/cpu/tegra2-common/Makefile new file mode 100644 index 0000000..8de59cf --- /dev/null +++ b/arch/arm/cpu/tegra2-common/Makefile @@ -0,0 +1,56 @@ +# +# (C) Copyright 2010,2011 Nvidia Corporation. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +# The AVP is ARMv4T architecture so we must use special compiler +# flags for any startup files it might use. +CFLAGS_arch/arm/cpu/tegra2-common/ap20.o += -march=armv4t +CFLAGS_arch/arm/cpu/tegra2-common/clock.o += -march=armv4t + +LIB = $(obj)lib$(SOC)-common.o + +SOBJS += lowlevel_init.o +COBJS-y += ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o + +SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +$(obj).depend: + echo wtf + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/tegra2-common/ap20.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/ap20.c rename to arch/arm/cpu/tegra2-common/ap20.c diff --git a/arch/arm/cpu/armv7/tegra2/ap20.h b/arch/arm/cpu/tegra2-common/ap20.h similarity index 100% rename from arch/arm/cpu/armv7/tegra2/ap20.h rename to arch/arm/cpu/tegra2-common/ap20.h diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/tegra2-common/board.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/board.c rename to arch/arm/cpu/tegra2-common/board.c diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/tegra2-common/clock.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/clock.c rename to arch/arm/cpu/tegra2-common/clock.c diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/tegra2-common/funcmux.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/funcmux.c rename to arch/arm/cpu/tegra2-common/funcmux.c diff --git a/arch/arm/cpu/armv7/tegra2/lowlevel_init.S b/arch/arm/cpu/tegra2-common/lowlevel_init.S similarity index 100% rename from arch/arm/cpu/armv7/tegra2/lowlevel_init.S rename to arch/arm/cpu/tegra2-common/lowlevel_init.S diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/tegra2-common/pinmux.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/pinmux.c rename to arch/arm/cpu/tegra2-common/pinmux.c diff --git a/arch/arm/cpu/armv7/tegra2/sys_info.c b/arch/arm/cpu/tegra2-common/sys_info.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/sys_info.c rename to arch/arm/cpu/tegra2-common/sys_info.c diff --git a/arch/arm/cpu/armv7/tegra2/timer.c b/arch/arm/cpu/tegra2-common/timer.c similarity index 100% rename from arch/arm/cpu/armv7/tegra2/timer.c rename to arch/arm/cpu/tegra2-common/timer.c diff --git a/spl/Makefile b/spl/Makefile index ea7d475..6d3241f 100644 --- a/spl/Makefile +++ b/spl/Makefile @@ -62,6 +62,10 @@ ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),) LIBS-y += $(CPUDIR)/omap-common/libomap-common.o endif
+ifneq ($(CONFIG_TEGRA2),) +LIBS-y += arch/$(ARCH)/cpu/$(SOC)-common/lib$(SOC)-common.o +endif + START := $(addprefix $(SPLTREE)/,$(START)) LIBS := $(addprefix $(SPLTREE)/,$(sort $(LIBS-y)))

Add support for specifying a differnt CPU for main u-boot and SPL u-boot builds. This is done by adding an optional SPL CPU after the main CPU in boards.cfg as follows:
normal_cpu:spl_cpu
This this case CPU will be set to "normal_cpu" during the main u-boot build and "spl_cpu" during the SPL build.
Signed-off-by: Allen Martin amartin@nvidia.com --- boards.cfg | 5 +++++ doc/README.SPL | 12 ++++++++++++ mkconfig | 15 ++++++++++++++- 3 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/boards.cfg b/boards.cfg index 5f328b5..4436053 100644 --- a/boards.cfg +++ b/boards.cfg @@ -11,6 +11,11 @@ # Lines starting with '#' are comments. # Blank lines are ignored. # +# The CPU field takes the form: +# cpu[:spl_cpu] +# If spl_cpu is specified the make variable CPU will be set to this +# during the SPL build. +# # The options field takes the form: # <board config name>[:comma separated config options] # Each config option has the form (value defaults to "1"): diff --git a/doc/README.SPL b/doc/README.SPL index 0276953..e4a5ac3 100644 --- a/doc/README.SPL +++ b/doc/README.SPL @@ -66,3 +66,15 @@ CONFIG_SPL_DMA_SUPPORT (drivers/dma/libdma.o) CONFIG_SPL_POST_MEM_SUPPORT (post/drivers/memory.o) CONFIG_SPL_NAND_LOAD (drivers/mtd/nand/nand_spl_load.o) CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o) + + +Normally CPU is assumed to be the same between the SPL and normal +u-boot build. However it is possible to specify a different CPU for +the SPL build for cases where the SPL is expected to run on a +different CPU model from the main u-boot. This is done by specifying +an SPL CPU in boards.cfg as follows: + + normal_cpu:spl_cpu + +This this case CPU will be set to "normal_cpu" during the main u-boot +build and "spl_cpu" during the SPL build. diff --git a/mkconfig b/mkconfig index 438530b..82660a6 100755 --- a/mkconfig +++ b/mkconfig @@ -60,6 +60,11 @@ CONFIG_NAME="${1%_config}"
arch="$2" cpu="$3" +tmp="${cpu#*:}" +if [ "$tmp" != "$cpu" ] ; then + spl_cpu=$tmp + cpu="${cpu%:*}" +fi if [ "$4" = "-" ] ; then board=${BOARD_NAME} else @@ -131,7 +136,15 @@ fi # Create include file for Make # echo "ARCH = ${arch}" > config.mk -echo "CPU = ${cpu}" >> config.mk +if [ ! -z "$spl_cpu" ] ; then + echo 'ifeq ($(CONFIG_SPL_BUILD),y)' >> config.mk + echo "CPU = ${spl_cpu}" >> config.mk + echo "else" >> config.mk + echo "CPU = ${cpu}" >> config.mk + echo "endif" >> config.mk +else + echo "CPU = ${cpu}" >> config.mk +fi echo "BOARD = ${board}" >> config.mk
[ "${vendor}" ] && echo "VENDOR = ${vendor}" >> config.mk

Take a few SPL fixes from armv7 and apply them to arm720t: -Use dummy exception handlers for SPL build -Initialize relocation register r9 to 0 for the case of no relocation -ifdef out interrupt handler code
Signed-off-by: Allen Martin amartin@nvidia.com --- arch/arm/cpu/arm720t/start.S | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index 540e3c2..df66946 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -51,6 +51,15 @@ _start: b reset ldr pc, _irq ldr pc, _fiq
+#ifdef CONFIG_SPL_BUILD +_undefined_instruction: .word _undefined_instruction +_software_interrupt: .word _software_interrupt +_prefetch_abort: .word _prefetch_abort +_data_abort: .word _data_abort +_not_used: .word _not_used +_irq: .word _irq +_fiq: .word _fiq +#else _undefined_instruction: .word undefined_instruction _software_interrupt: .word software_interrupt _prefetch_abort: .word prefetch_abort @@ -58,6 +67,7 @@ _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq +#endif /* CONFIG_SPL_BUILD */
.balignl 16,0xdeadbeef
@@ -167,6 +177,7 @@ stack_setup:
adr r0, _start cmp r0, r6 + moveq r9, #0 /* no relocation. relocation offset(r9) = 0 */ beq clear_bss /* skip relocation */ mov r1, r6 /* r1 <- scratch for copy_loop */ ldr r3, _bss_start_ofs @@ -425,6 +436,7 @@ lock_loop: mov pc, lr
+#ifndef CONFIG_SPL_BUILD /* ************************************************************************* * @@ -587,6 +599,7 @@ fiq: bl do_fiq
#endif +#endif /* CONFIG_SPL_BUILD */
#if defined(CONFIG_NETARM) .align 5

Include board.c for both SPL and non-SPL build. Don't use timer_init from board.c for SPL build.
Signed-off-by: Allen Martin amartin@nvidia.com --- board/nvidia/common/Makefile | 2 +- board/nvidia/common/board.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/board/nvidia/common/Makefile b/board/nvidia/common/Makefile index 3e748fd..ac3b9cd 100644 --- a/board/nvidia/common/Makefile +++ b/board/nvidia/common/Makefile @@ -25,7 +25,7 @@ endif
LIB = $(obj)lib$(VENDOR).o
-COBJS-y += board.o +COBJS-$(CONFIG_ARMCORTEXA9) += board.o COBJS-$(CONFIG_SPI_UART_SWITCH) += uart-spi-switch.o
COBJS := $(COBJS-y) diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c index 85dd359..678a986 100644 --- a/board/nvidia/common/board.c +++ b/board/nvidia/common/board.c @@ -43,6 +43,7 @@ const struct tegra2_sysinfo sysinfo = { CONFIG_TEGRA2_BOARD_STRING };
+#ifndef CONFIG_SPL_BUILD /* * Routine: timer_init * Description: init the timestamp and lastinc value @@ -51,6 +52,7 @@ int timer_init(void) { return 0; } +#endif
void __pin_mux_usb(void) {

On 05/10/2012 01:02 AM, Allen Martin wrote:
Include board.c for both SPL and non-SPL build. Don't use timer_init from board.c for SPL build.
Signed-off-by: Allen Martin amartin@nvidia.com
diff --git a/board/nvidia/common/Makefile b/board/nvidia/common/Makefile
If we're already not building board.c for non-Cortex A9 (so not for SPL)
-COBJS-y += board.o +COBJS-$(CONFIG_ARMCORTEXA9) += board.o
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifndef CONFIG_SPL_BUILD
I'm not sure that this ifdef is necessary since !CONFIG_SPL_BUILD any time this file is compiled?

On Mon, May 14, 2012 at 09:55:20PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
Include board.c for both SPL and non-SPL build. Don't use timer_init from board.c for SPL build.
Signed-off-by: Allen Martin amartin@nvidia.com
diff --git a/board/nvidia/common/Makefile b/board/nvidia/common/Makefile
If we're already not building board.c for non-Cortex A9 (so not for SPL)
-COBJS-y += board.o +COBJS-$(CONFIG_ARMCORTEXA9) += board.o
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
+#ifndef CONFIG_SPL_BUILD
I'm not sure that this ifdef is necessary since !CONFIG_SPL_BUILD any time this file is compiled?
Oh you're right, looks like my commit message is wrong too, I'll take another look.
-Allen

Add support for tegra arm7 boot processor. This processor is used to power on the Cortex A9 and transfer control to it.
Signed-off-by: Allen Martin amartin@nvidia.com --- arch/arm/cpu/arm720t/cpu.c | 3 +- arch/arm/cpu/arm720t/interrupts.c | 5 +- arch/arm/cpu/arm720t/start.S | 6 +- arch/arm/cpu/arm720t/tegra2/Makefile | 48 +++++ arch/arm/cpu/arm720t/tegra2/board.h | 25 +++ arch/arm/cpu/arm720t/tegra2/cpu.c | 259 +++++++++++++++++++++++++++ arch/arm/cpu/arm720t/tegra2/cpu.h | 99 ++++++++++ arch/arm/cpu/arm720t/tegra2/spl.c | 133 ++++++++++++++ arch/arm/include/asm/arch-tegra2/hardware.h | 29 +++ 9 files changed, 604 insertions(+), 3 deletions(-) create mode 100644 arch/arm/cpu/arm720t/tegra2/Makefile create mode 100644 arch/arm/cpu/arm720t/tegra2/board.h create mode 100644 arch/arm/cpu/arm720t/tegra2/cpu.c create mode 100644 arch/arm/cpu/arm720t/tegra2/cpu.h create mode 100644 arch/arm/cpu/arm720t/tegra2/spl.c create mode 100644 arch/arm/include/asm/arch-tegra2/hardware.h
diff --git a/arch/arm/cpu/arm720t/cpu.c b/arch/arm/cpu/arm720t/cpu.c index 974f288..cfbfa3d 100644 --- a/arch/arm/cpu/arm720t/cpu.c +++ b/arch/arm/cpu/arm720t/cpu.c @@ -33,7 +33,6 @@ #include <common.h> #include <command.h> #include <clps7111.h> -#include <asm/hardware.h> #include <asm/system.h>
int cleanup_before_linux (void) @@ -51,6 +50,8 @@ int cleanup_before_linux (void) /* Nothing more needed */ #elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) /* No cleanup before linux for IntegratorAP/CM720T as yet */ +#elif defined (CONFIG_MACH_TEGRA_GENERIC) + /* No cleanup before linux for tegra as yet */ #else #error No cleanup_before_linux() defined for this CPU type #endif diff --git a/arch/arm/cpu/arm720t/interrupts.c b/arch/arm/cpu/arm720t/interrupts.c index 464dd30..aa909ef 100644 --- a/arch/arm/cpu/arm720t/interrupts.c +++ b/arch/arm/cpu/arm720t/interrupts.c @@ -29,7 +29,6 @@ #include <common.h> #include <clps7111.h> #include <asm/proc-armv/ptrace.h> -#include <asm/hardware.h>
#ifndef CONFIG_NETARM /* we always count down the max. */ @@ -180,6 +179,8 @@ int timer_init (void) PUT32(T0TC, 0); PUT32(T0TCR, 1); /* enable timer0 */
+#elif defined(CONFIG_MACH_TEGRA_GENERIC) + /* No timer routines for tegra as yet */ #else #error No timer_init() defined for this CPU type #endif @@ -282,6 +283,8 @@ void __udelay (unsigned long usec)
#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR) /* No timer routines for IntegratorAP/CM720T as yet */ +#elif defined(CONFIG_MACH_TEGRA_GENERIC) + /* No timer routines for tegra as yet */ #else #error Timer routines not defined for this CPU type #endif diff --git a/arch/arm/cpu/arm720t/start.S b/arch/arm/cpu/arm720t/start.S index df66946..e79b1be 100644 --- a/arch/arm/cpu/arm720t/start.S +++ b/arch/arm/cpu/arm720t/start.S @@ -407,6 +407,8 @@ lock_loop: ldr r0, VPBDIV_ADR mov r1, #0x01 /* VPB clock is same as process clock */ str r1, [r0] +#elif defined(CONFIG_MACH_TEGRA_GENERIC) + /* No cpu_init_crit for tegra as yet */ #else #error No cpu_init_crit() defined for current CPU type #endif @@ -422,7 +424,7 @@ lock_loop: str r1, [r0] #endif
-#ifndef CONFIG_LPC2292 +#if !defined(CONFIG_LPC2292) && !defined(CONFIG_MACH_TEGRA_GENERIC) mov ip, lr /* * before relocating, we have to setup RAM timing @@ -631,6 +633,8 @@ reset_cpu: .globl reset_cpu reset_cpu: mov pc, r0 +#elif defined(CONFIG_MACH_TEGRA_GENERIC) + /* No specific reset actions for tegra as yet */ #else #error No reset_cpu() defined for current CPU type #endif diff --git a/arch/arm/cpu/arm720t/tegra2/Makefile b/arch/arm/cpu/arm720t/tegra2/Makefile new file mode 100644 index 0000000..6e48475 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra2/Makefile @@ -0,0 +1,48 @@ +# +# (C) Copyright 2010,2011 Nvidia Corporation. +# +# (C) Copyright 2000-2008 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +COBJS-y += cpu.o +COBJS-$(CONFIG_SPL_BUILD) += spl.o + +SRCS := $(COBJS-y:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/arm720t/tegra2/board.h b/arch/arm/cpu/arm720t/tegra2/board.h new file mode 100644 index 0000000..61b91c0 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra2/board.h @@ -0,0 +1,25 @@ +/* + * (C) Copyright 2010-2011 + * NVIDIA Corporation <www.nvidia.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +void board_init_uart_f(void); +void gpio_config_uart(void); diff --git a/arch/arm/cpu/arm720t/tegra2/cpu.c b/arch/arm/cpu/arm720t/tegra2/cpu.c new file mode 100644 index 0000000..00a82b1 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra2/cpu.c @@ -0,0 +1,259 @@ +/* +* (C) Copyright 2010-2011 +* NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#include <asm/io.h> +#include <asm/arch/tegra2.h> +#include <asm/arch/clk_rst.h> +#include <asm/arch/clock.h> +#include <asm/arch/pmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/scu.h> +#include <common.h> +#include "cpu.h" + +/* Returns 1 if the current CPU executing is a Cortex-A9, else 0 */ +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) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU]; + u32 reg; + + /* If PLLX is already enabled, just return */ + if (readl(&pll->pll_base) & PLL_ENABLE_MASK) + return; + + /* Set PLLX_MISC */ + writel(1 << PLL_CPCON_SHIFT, &pll->pll_misc); + + /* Use 12MHz clock here */ + reg = PLL_BYPASS_MASK | (12 << PLL_DIVM_SHIFT); + reg |= 1000 << PLL_DIVN_SHIFT; + writel(reg, &pll->pll_base); + + reg |= PLL_ENABLE_MASK; + writel(reg, &pll->pll_base); + + reg &= ~PLL_BYPASS_MASK; + writel(reg, &pll->pll_base); +} + +static void enable_cpu_clock(int enable) +{ + struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + u32 clk; + + /* + * NOTE: + * Regardless of whether the request is to enable or disable the CPU + * clock, every processor in the CPU complex except the master (CPU 0) + * will have it's clock stopped because the AVP only talks to the + * master. The AVP does not know (nor does it need to know) that there + * are multiple processors in the CPU complex. + */ + + if (enable) { + /* Initialize PLLX */ + init_pllx(); + + /* Wait until all clocks are stable */ + udelay(PLL_STABILIZATION_DELAY); + + writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); + writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); + } + + /* + * Read the register containing the individual CPU clock enables and + * always stop the clock to CPU 1. + */ + clk = readl(&clkrst->crc_clk_cpu_cmplx); + clk |= 1 << CPU1_CLK_STP_SHIFT; + + /* Stop/Unstop the CPU clock */ + clk &= ~CPU0_CLK_STP_MASK; + clk |= !enable << CPU0_CLK_STP_SHIFT; + writel(clk, &clkrst->crc_clk_cpu_cmplx); + + clock_enable(PERIPH_ID_CPU); +} + +static int is_cpu_powered(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + + return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; +} + +static void remove_cpu_io_clamps(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + u32 reg; + + /* Remove the clamps on the CPU I/O signals */ + reg = readl(&pmc->pmc_remove_clamping); + reg |= CPU_CLMP; + writel(reg, &pmc->pmc_remove_clamping); + + /* Give I/O signals time to stabilize */ + udelay(IO_STABILIZATION_DELAY); +} + +static void powerup_cpu(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + u32 reg; + int timeout = IO_STABILIZATION_DELAY; + + if (!is_cpu_powered()) { + /* Toggle the CPU power state (OFF -> ON) */ + reg = readl(&pmc->pmc_pwrgate_toggle); + reg &= PARTID_CP; + reg |= START_CP; + writel(reg, &pmc->pmc_pwrgate_toggle); + + /* Wait for the power to come up */ + while (!is_cpu_powered()) { + if (timeout-- == 0) + printf("CPU failed to power up!\n"); + else + udelay(10); + } + + /* + * Remove the I/O clamps from CPU power partition. + * Recommended only on a Warm boot, if the CPU partition gets + * power gated. Shouldn't cause any harm when called after a + * cold boot according to HW, probably just redundant. + */ + remove_cpu_io_clamps(); + } +} + +static void enable_cpu_power_rail(void) +{ + struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; + u32 reg; + + reg = readl(&pmc->pmc_cntrl); + reg |= CPUPWRREQ_OE; + writel(reg, &pmc->pmc_cntrl); + + /* + * The TI PMU65861C needs a 3.75ms delay between enabling + * the power rail and enabling the CPU clock. This delay + * between SM1EN and SM1 is for switching time + the ramp + * up of the voltage to the CPU (VDD_CPU from PMU). + */ + udelay(3750); +} + +static void reset_A9_cpu(int reset) +{ + /* + * NOTE: Regardless of whether the request is to hold the CPU in reset + * or take it out of reset, every processor in the CPU complex + * except the master (CPU 0) will be held in reset because the + * AVP only talks to the master. The AVP does not know that there + * are multiple processors in the CPU complex. + */ + + /* Hold CPU 1 in reset, and CPU 0 if asked */ + reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1); + reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug, + reset); + + /* Enable/Disable master CPU reset */ + reset_set_enable(PERIPH_ID_CPU, reset); +} + +static void clock_enable_coresight(int enable) +{ + u32 rst, src; + + clock_set_enable(PERIPH_ID_CORESIGHT, enable); + reset_set_enable(PERIPH_ID_CORESIGHT, !enable); + + if (enable) { + /* + * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by + * 1.5, giving an effective frequency of 144MHz. + * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor + * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) + */ + src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); + clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); + + /* Unlock the CPU CoreSight interfaces */ + rst = 0xC5ACCE55; + writel(rst, CSITE_CPU_DBG0_LAR); + writel(rst, CSITE_CPU_DBG1_LAR); + } +} + +void start_cpu(u32 reset_vector) +{ + /* Enable VDD_CPU */ + enable_cpu_power_rail(); + + /* Hold the CPUs in reset */ + reset_A9_cpu(1); + + /* Disable the CPU clock */ + enable_cpu_clock(0); + + /* Enable CoreSight */ + clock_enable_coresight(1); + + /* + * Set the entry point for CPU execution from reset, + * if it's a non-zero value. + */ + if (reset_vector) + writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); + + /* Enable the CPU clock */ + enable_cpu_clock(1); + + /* If the CPU doesn't already have power, power it up */ + powerup_cpu(); + + /* Take the CPU out of reset */ + reset_A9_cpu(0); +} + + +void halt_avp(void) +{ + for (;;) { + writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \ + | HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)), + FLOW_CTLR_HALT_COP_EVENTS); + } +} + diff --git a/arch/arm/cpu/arm720t/tegra2/cpu.h b/arch/arm/cpu/arm720t/tegra2/cpu.h new file mode 100644 index 0000000..90857a8 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra2/cpu.h @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2010-2011 + * NVIDIA Corporation <www.nvidia.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <asm/types.h> + +/* Stabilization delays, in usec */ +#define PLL_STABILIZATION_DELAY (300) +#define IO_STABILIZATION_DELAY (1000) + +#define NVBL_PLLP_KHZ (216000) + +#define PLLX_ENABLED (1 << 30) +#define CCLK_BURST_POLICY 0x20008888 +#define SUPER_CCLK_DIVIDER 0x80000000 + +/* Calculate clock fractional divider value from ref and target frequencies */ +#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) + +/* Calculate clock frequency value from reference and clock divider value */ +#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) + +/* AVP/CPU ID */ +#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ +#define PG_UP_TAG_0 0x0 + +#define CORESIGHT_UNLOCK 0xC5ACCE55; + +/* AP20-Specific Base Addresses */ + +/* AP20 Base physical address of SDRAM. */ +#define AP20_BASE_PA_SDRAM 0x00000000 +/* AP20 Base physical address of internal SRAM. */ +#define AP20_BASE_PA_SRAM 0x40000000 +/* AP20 Size of internal SRAM (256KB). */ +#define AP20_BASE_PA_SRAM_SIZE 0x00040000 +/* AP20 Base physical address of flash. */ +#define AP20_BASE_PA_NOR_FLASH 0xD0000000 +/* AP20 Base physical address of boot information table. */ +#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM + +/* + * Super-temporary stacks for EXTREMELY early startup. The values chosen for + * these addresses must be valid on ALL SOCs because this value is used before + * we are able to differentiate between the SOC types. + * + * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its + * stack is placed below the AVP stack. Once the CPU stack has been moved, + * the AVP is free to use the IRAM the CPU stack previously occupied if + * it should need to do so. + * + * NOTE: In multi-processor CPU complex configurations, each processor will have + * its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a + * limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a + * stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous + * CPU. + */ + +/* Common AVP early boot stack limit */ +#define AVP_EARLY_BOOT_STACK_LIMIT \ + (AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2)) +/* Common AVP early boot stack size */ +#define AVP_EARLY_BOOT_STACK_SIZE 0x1000 +/* Common CPU early boot stack limit */ +#define CPU_EARLY_BOOT_STACK_LIMIT \ + (AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE) +/* Common CPU early boot stack size */ +#define CPU_EARLY_BOOT_STACK_SIZE 0x1000 + +#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) +#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) +#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) + +#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) +#define FLOW_MODE_STOP 2 +#define HALT_COP_EVENT_JTAG (1 << 28) +#define HALT_COP_EVENT_IRQ_1 (1 << 11) +#define HALT_COP_EVENT_FIQ_1 (1 << 9) + +void start_cpu(u32 reset_vector); +int ap20_cpu_is_cortexa9(void); diff --git a/arch/arm/cpu/arm720t/tegra2/spl.c b/arch/arm/cpu/arm720t/tegra2/spl.c new file mode 100644 index 0000000..d467ab2 --- /dev/null +++ b/arch/arm/cpu/arm720t/tegra2/spl.c @@ -0,0 +1,133 @@ +/* + * (C) Copyright 2012 + * NVIDIA Inc, <www.nvidia.com> + * + * Allen Martin amartin@nvidia.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <asm/u-boot.h> +#include <asm/utils.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/clock.h> +#include <nand.h> +#include <mmc.h> +#include <fat.h> +#include <version.h> +#include <i2c.h> +#include <image.h> +#include <malloc.h> +#include <linux/compiler.h> +#include "board.h" +#include "cpu.h" + +#include <asm/io.h> +#include <asm/arch/tegra2.h> +#include <asm/arch/clk_rst.h> +#include <asm/arch/clock.h> +#include <asm/arch/pmc.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/scu.h> +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Define global data structure pointer to it*/ +static gd_t gdata __attribute__ ((section(".data"))); +static bd_t bdata __attribute__ ((section(".data"))); + +inline void hang(void) +{ + puts("### ERROR ### Please RESET the board ###\n"); + for (;;) + ; +} + +void board_init_f(ulong dummy) +{ + board_init_uart_f(); + + /* Initialize periph GPIOs */ +#ifdef CONFIG_SPI_UART_SWITCH + gpio_early_init_uart(); +#else + gpio_config_uart(); +#endif + + /* + * We call relocate_code() with relocation target same as the + * CONFIG_SYS_SPL_TEXT_BASE. This will result in relocation getting + * skipped. Instead, only .bss initialization will happen. That's + * all we need + */ + debug(">>board_init_f()\n"); + relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE); +} + +/* This requires UART clocks to be enabled */ +static void preloader_console_init(void) +{ + const char *u_boot_rev = U_BOOT_VERSION; + + gd = &gdata; + gd->bd = &bdata; + gd->flags |= GD_FLG_RELOC; + gd->baudrate = CONFIG_BAUDRATE; + + serial_init(); /* serial communications setup */ + + gd->have_console = 1; + + /* Avoid a second "U-Boot" coming from this string */ + u_boot_rev = &u_boot_rev[7]; + + printf("\nU-Boot SPL %s (%s - %s)\n", u_boot_rev, U_BOOT_DATE, + U_BOOT_TIME); +} + +void board_init_r(gd_t *id, ulong dummy) +{ + u32 boot_device; + struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + debug(">>spl:board_init_r()\n"); + + mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, + CONFIG_SYS_SPL_MALLOC_SIZE); + +#ifdef CONFIG_SPL_BOARD_INIT + spl_board_init(); +#endif + + clock_early_init(); + serial_init(); + preloader_console_init(); + + /* enable JTAG */ + writel(0xC0, &pmt->pmt_cfg_ctl); + + start_cpu((u32)CONFIG_SYS_TEXT_BASE); + halt_avp(); + /* not reached */ +} + +int board_usb_init(const void *blob) +{ + return 0; +} diff --git a/arch/arm/include/asm/arch-tegra2/hardware.h b/arch/arm/include/asm/arch-tegra2/hardware.h new file mode 100644 index 0000000..8c47578 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra2/hardware.h @@ -0,0 +1,29 @@ +/* +* (C) Copyright 2010-2011 +* NVIDIA Corporation <www.nvidia.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#ifndef __TEGRA2_HW_H +#define __TEGRA2_HW_H + +/* include tegra specific hardware definitions */ + +#endif /* __TEGRA2_HW_H */

On 05/10/2012 01:02 AM, Allen Martin wrote:
Add support for tegra arm7 boot processor. This processor is used to power on the Cortex A9 and transfer control to it.
+static void enable_cpu_power_rail(void)
- /*
* The TI PMU65861C needs a 3.75ms delay between enabling
* the power rail and enabling the CPU clock. This delay
* between SM1EN and SM1 is for switching time + the ramp
* up of the voltage to the CPU (VDD_CPU from PMU).
*/
- udelay(3750);
Not all boards use that PMU. Can this be conditional on a define that enables that PMU, or part of the PMU diver or something?
diff --git a/arch/arm/cpu/arm720t/tegra2/cpu.h b/arch/arm/cpu/arm720t/tegra2/cpu.h
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
Is this new code you just wrote? If so, shouldn't it be GPL v2 not GPL v2+?

On Mon, May 14, 2012 at 10:03:24PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
Add support for tegra arm7 boot processor. This processor is used to power on the Cortex A9 and transfer control to it.
+static void enable_cpu_power_rail(void)
- /*
* The TI PMU65861C needs a 3.75ms delay between enabling
* the power rail and enabling the CPU clock. This delay
* between SM1EN and SM1 is for switching time + the ramp
* up of the voltage to the CPU (VDD_CPU from PMU).
*/
- udelay(3750);
Not all boards use that PMU. Can this be conditional on a define that enables that PMU, or part of the PMU diver or something?
Sounds reasonable, although I think it should be part of a separate patch. This code I just moved unmodified from ap20.c in the armv7 tegra2 directory.
diff --git a/arch/arm/cpu/arm720t/tegra2/cpu.h b/arch/arm/cpu/arm720t/tegra2/cpu.h
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
Is this new code you just wrote? If so, shouldn't it be GPL v2 not GPL v2+?
Again I just moved it unmodified (copyright and all) from ap20.h.
-Allen

On 05/18/2012 04:37 PM, Allen Martin wrote:
On Mon, May 14, 2012 at 10:03:24PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
Add support for tegra arm7 boot processor. This processor is used to power on the Cortex A9 and transfer control to it.
+static void enable_cpu_power_rail(void)
- /*
* The TI PMU65861C needs a 3.75ms delay between enabling
* the power rail and enabling the CPU clock. This delay
* between SM1EN and SM1 is for switching time + the ramp
* up of the voltage to the CPU (VDD_CPU from PMU).
*/
- udelay(3750);
Not all boards use that PMU. Can this be conditional on a define that enables that PMU, or part of the PMU diver or something?
Sounds reasonable, although I think it should be part of a separate patch. This code I just moved unmodified from ap20.c in the armv7 tegra2 directory.
diff --git a/arch/arm/cpu/arm720t/tegra2/cpu.h b/arch/arm/cpu/arm720t/tegra2/cpu.h
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
Is this new code you just wrote? If so, shouldn't it be GPL v2 not GPL v2+?
Again I just moved it unmodified (copyright and all) from ap20.h.
Oh right. I think if you pass "-M" or better "-C" to "git format-patch", it'll highlight that fact better; it should make the patch file indicate that the relevant files were moved or copied, and just show the diffs to the file during the move/copy (which may be zero or tiny), rather than showing the entire file as new code.

On Tue, May 22, 2012 at 10:10:48AM -0700, Stephen Warren wrote:
Oh right. I think if you pass "-M" or better "-C" to "git format-patch", it'll highlight that fact better; it should make the patch file indicate that the relevant files were moved or copied, and just show the diffs to the file during the move/copy (which may be zero or tiny), rather than showing the entire file as new code.
Sorry about that, I did it correctly in my earlier posting of this patch, but incorrectly when I posted the entire patch series. I'll use -C when I post V2.
-Allen

Signed-off-by: Allen Martin amartin@nvidia.com --- boards.cfg | 2 +- include/configs/seaboard.h | 9 +++++++++ include/configs/tegra2-common.h | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/boards.cfg b/boards.cfg index 4436053..30ceddc 100644 --- a/boards.cfg +++ b/boards.cfg @@ -230,7 +230,7 @@ smdk5250 arm armv7 smdk5250 samsung exynos smdkv310 arm armv7 smdkv310 samsung exynos trats arm armv7 trats samsung exynos harmony arm armv7 harmony nvidia tegra2 -seaboard arm armv7 seaboard nvidia tegra2 +seaboard arm armv7:arm720t seaboard nvidia tegra2 ventana arm armv7 ventana nvidia tegra2 u8500_href arm armv7 u8500 st-ericsson u8500 actux1_4_16 arm ixp actux1 - - actux1:FLASH2X2 diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index ae075e7..8e3eee8 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -27,10 +27,12 @@ #include <asm/sizes.h> #include "tegra2-common.h"
+#ifndef CONFIG_SPL_BUILD /* Enable fdt support for Seaboard. Flash the image in u-boot-dtb.bin */ #define CONFIG_DEFAULT_DEVICE_TREE tegra2-seaboard #define CONFIG_OF_CONTROL #define CONFIG_OF_SEPARATE +#endif
/* High-level configuration options */ #define TEGRA2_SYSMEM "mem=384M@0M nvmem=128M@384M mem=512M@512M" @@ -38,7 +40,9 @@ #define CONFIG_TEGRA2_BOARD_STRING "NVIDIA Seaboard"
/* Board-specific serial config */ +#ifndef CONFIG_SPL_BUILD #define CONFIG_SERIAL_MULTI +#endif #define CONFIG_TEGRA2_ENABLE_UARTD #define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTD_BASE
@@ -59,6 +63,7 @@ #define CONFIG_CMD_SF #define CONFIG_SPI_FLASH_SIZE (4 << 20)
+#ifndef CONFIG_SPL_BUILD /* I2C */ #define CONFIG_TEGRA_I2C #define CONFIG_SYS_I2C_INIT_BOARD @@ -78,6 +83,8 @@ #define CONFIG_CMD_EXT2 #define CONFIG_CMD_FAT
+#endif + /* Environment in SPI */ #define CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_SPI_MAX_HZ 48000000 @@ -86,10 +93,12 @@ #define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE #define CONFIG_ENV_OFFSET (CONFIG_SPI_FLASH_SIZE - CONFIG_ENV_SECT_SIZE)
+#ifndef CONFIG_SPL_BUILD /* USB Host support */ #define CONFIG_USB_EHCI #define CONFIG_USB_EHCI_TEGRA #define CONFIG_USB_STORAGE #define CONFIG_CMD_USB +#endif
#endif /* __CONFIG_H */ diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h index 837f859..997887a 100644 --- a/include/configs/tegra2-common.h +++ b/include/configs/tegra2-common.h @@ -90,9 +90,11 @@ * parameter, the default (2) causes occasional Data Buffer Errors in OUT * packets depending on the buffer address and size. */ +#ifndef CONFIG_SPL_BUILD #define CONFIG_USB_EHCI_TXFIFO_THRESH 10 #define CONFIG_EHCI_IS_TDI #define CONFIG_EHCI_DCACHE +#endif
/* Total I2C ports on Tegra2 */ #define TEGRA_I2C_NUM_CONTROLLERS 4 @@ -175,4 +177,21 @@
#define CONFIG_TEGRA2_GPIO #define CONFIG_CMD_GPIO + +/* Defines for SPL */ +#define CONFIG_SPL +#define CONFIG_SPL_NAND_SIMPLE +#define CONFIG_SPL_TEXT_BASE 0x00008000 +#define CONFIG_SPL_MAX_SIZE 0x00078000 +#define CONFIG_SYS_SPL_MALLOC_START 0x00080000 +#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00010000 +#define CONFIG_SPL_STACK 0x0009fffc + +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_POWER_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/tegra2/u-boot-spl.lds" + #endif /* __TEGRA2_COMMON_H */

On 05/10/2012 01:02 AM, Allen Martin wrote:
Signed-off-by: Allen Martin amartin@nvidia.com
diff --git a/boards.cfg b/boards.cfg
-seaboard arm armv7 seaboard nvidia tegra2 +seaboard arm armv7:arm720t seaboard nvidia tegra2
Hmmm. We'll have to duplicate this change for all boards. Is there some way to do set up the SPL CPU for all Tegra boards so we don't have to do that?
diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
+#ifndef CONFIG_SPL_BUILD
And every Tegra board's config header will have to ifdef a bunch of stuff out for SPL.
Perhaps we can just create a new tegra_spl board for the SPL rather than having an SPL variant for each board. Still, I don't know how we'd represent the UART differences if we did that though.

On Mon, May 14, 2012 at 10:06:40PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
Signed-off-by: Allen Martin amartin@nvidia.com
diff --git a/boards.cfg b/boards.cfg
-seaboard arm armv7 seaboard nvidia tegra2 +seaboard arm armv7:arm720t seaboard nvidia tegra2
Hmmm. We'll have to duplicate this change for all boards. Is there some way to do set up the SPL CPU for all Tegra boards so we don't have to do that?
I would have to think what that would look like. The boards.cfg file has one entry per board and doesn't really have any place to store information on groups of boards or any type of per vendor or per architecture settings. This decision on the CPU needs to be made at mkconfig time or else I wouldn't have touched boards.cfg format at all and stuck it in some tegra specific config file or Makefile. I can't see any way to do what you're asking without making the change even more invasive.
diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h
+#ifndef CONFIG_SPL_BUILD
And every Tegra board's config header will have to ifdef a bunch of stuff out for SPL.
I'll take a pass at trying to pull some of that out into a common header.
Perhaps we can just create a new tegra_spl board for the SPL rather than having an SPL variant for each board. Still, I don't know how we'd represent the UART differences if we did that though.
I tossed out that idea as part of the discussion about using a separate toolchain for the SPL, but Wolfgang shot it down:
http://lists.denx.de/pipermail/u-boot/2012-April/122248.html
-Allen

On 05/18/2012 04:24 PM, Allen Martin wrote:
On Mon, May 14, 2012 at 10:06:40PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
...
Perhaps we can just create a new tegra_spl board for the SPL rather than having an SPL variant for each board. Still, I don't know how we'd represent the UART differences if we did that though.
I tossed out that idea as part of the discussion about using a separate toolchain for the SPL, but Wolfgang shot it down:
http://lists.denx.de/pipermail/u-boot/2012-April/122248.html
Is that the right link? That message seems to be talking about a CROSS_COMPILE_SPL variable rather than having a separate boards.cfg entry for a Tegra SPL.

On Tue, May 22, 2012 at 10:07:37AM -0700, Stephen Warren wrote:
On 05/18/2012 04:24 PM, Allen Martin wrote:
On Mon, May 14, 2012 at 10:06:40PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
...
Perhaps we can just create a new tegra_spl board for the SPL rather than having an SPL variant for each board. Still, I don't know how we'd represent the UART differences if we did that though.
I tossed out that idea as part of the discussion about using a separate toolchain for the SPL, but Wolfgang shot it down:
http://lists.denx.de/pipermail/u-boot/2012-April/122248.html
Is that the right link? That message seems to be talking about a CROSS_COMPILE_SPL variable rather than having a separate boards.cfg entry for a Tegra SPL.
This was the piece I was referring to, which was a conversation about exactly this topic (armv4 SPL and armv7 u-boot):
The architecture seems harder to fix. It seems like I really have to have two entries in boards.cfg, which means two passes of config/make.
This should be not needed; I also do not think this would be an acceptable approach.
-Allen

Add target for tegra2 u-boot image. This is a concatenation of tegra spl and normal u-boot binaries.
Signed-off-by: Allen Martin amartin@nvidia.com --- Makefile | 6 ++++++ board/nvidia/seaboard/config.mk | 1 + 2 files changed, 7 insertions(+) create mode 100644 board/nvidia/seaboard/config.mk
diff --git a/Makefile b/Makefile index 8e587f4..a7cf175 100644 --- a/Makefile +++ b/Makefile @@ -456,6 +456,11 @@ $(obj)u-boot.sb: $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin elftosb -zdf imx28 -c $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd \ -o $(obj)u-boot.sb
+$(obj)u-boot.t2: $(obj)spl/u-boot-spl.bin $(obj)u-boot-dtb.bin + $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin + cat $(obj)spl/u-boot-spl-pad.bin $(obj)u-boot-dtb.bin > $(obj)u-boot.t2 + rm $(obj)spl/u-boot-spl-pad.bin + ifeq ($(CONFIG_SANDBOX),y) GEN_UBOOT = \ cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ @@ -768,6 +773,7 @@ clobber: tidy @rm -f $(obj)u-boot.ais @rm -f $(obj)u-boot.dtb @rm -f $(obj)u-boot.sb + @rm -f $(obj)u-boot.t2 @rm -f $(obj)tools/inca-swap-bytes @rm -f $(obj)arch/powerpc/cpu/mpc824x/bedbug_603e.c @rm -f $(obj)arch/powerpc/cpu/mpc83xx/ddr-gen?.c diff --git a/board/nvidia/seaboard/config.mk b/board/nvidia/seaboard/config.mk new file mode 100644 index 0000000..1d6e878 --- /dev/null +++ b/board/nvidia/seaboard/config.mk @@ -0,0 +1 @@ +PAD_TO=0x00108000

On 05/10/2012 01:02 AM, Allen Martin wrote:
Add target for tegra2 u-boot image. This is a concatenation of tegra spl and normal u-boot binaries.
diff --git a/Makefile b/Makefile
+$(obj)u-boot.t2: $(obj)spl/u-boot-spl.bin $(obj)u-boot-dtb.bin
Hmmm. Only some boards boot using DT, so that second file is sometimes just u-boot.bin. Is there any way we can make this handle both cases? Perhaps we just need to convert all Tegra boards to DT to solve this.

On Mon, May 14, 2012 at 10:08:05PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
Add target for tegra2 u-boot image. This is a concatenation of tegra spl and normal u-boot binaries.
diff --git a/Makefile b/Makefile
+$(obj)u-boot.t2: $(obj)spl/u-boot-spl.bin $(obj)u-boot-dtb.bin
Hmmm. Only some boards boot using DT, so that second file is sometimes just u-boot.bin. Is there any way we can make this handle both cases? Perhaps we just need to convert all Tegra boards to DT to solve this.
I can make it handle both, shouldn't be a problem.
-Allen

This code is now included in the tegra2 SPL
Signed-off-by: Allen Martin amartin@nvidia.com --- arch/arm/cpu/armv7/start.S | 2 - arch/arm/cpu/tegra2-common/ap20.c | 257 +----------------------------------- arch/arm/cpu/tegra2-common/ap20.h | 102 -------------- arch/arm/cpu/tegra2-common/board.c | 22 --- include/configs/tegra2-common.h | 4 - 5 files changed, 3 insertions(+), 384 deletions(-) delete mode 100644 arch/arm/cpu/tegra2-common/ap20.h
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index ef08a55..6a77c71 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -132,7 +132,6 @@ reset: orr r0, r0, #0xd3 msr cpsr,r0
-#if !defined(CONFIG_TEGRA2) /* * Setup vector: * (OMAP4 spl TEXT_BASE is not 32 byte aligned. @@ -148,7 +147,6 @@ reset: ldr r0, =_start mcr p15, 0, r0, c12, c0, 0 @Set VBAR #endif -#endif /* !Tegra2 */
/* the mask ROM code should have PLL and others stable */ #ifndef CONFIG_SKIP_LOWLEVEL_INIT diff --git a/arch/arm/cpu/tegra2-common/ap20.c b/arch/arm/cpu/tegra2-common/ap20.c index b749821..cb8fcdf 100644 --- a/arch/arm/cpu/tegra2-common/ap20.c +++ b/arch/arm/cpu/tegra2-common/ap20.c @@ -20,244 +20,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ - -#include "ap20.h" #include <asm/io.h> -#include <asm/arch/tegra2.h> -#include <asm/arch/clk_rst.h> -#include <asm/arch/clock.h> #include <asm/arch/pmc.h> -#include <asm/arch/pinmux.h> #include <asm/arch/scu.h> #include <common.h>
-/* 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) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - struct clk_pll *pll = &clkrst->crc_pll[CLOCK_ID_XCPU]; - u32 reg; - - /* If PLLX is already enabled, just return */ - if (readl(&pll->pll_base) & PLL_ENABLE_MASK) - return; - - /* Set PLLX_MISC */ - writel(1 << PLL_CPCON_SHIFT, &pll->pll_misc); - - /* Use 12MHz clock here */ - reg = PLL_BYPASS_MASK | (12 << PLL_DIVM_SHIFT); - reg |= 1000 << PLL_DIVN_SHIFT; - writel(reg, &pll->pll_base); - - reg |= PLL_ENABLE_MASK; - writel(reg, &pll->pll_base); - - reg &= ~PLL_BYPASS_MASK; - writel(reg, &pll->pll_base); -} - -static void enable_cpu_clock(int enable) -{ - struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; - u32 clk; - - /* - * NOTE: - * Regardless of whether the request is to enable or disable the CPU - * clock, every processor in the CPU complex except the master (CPU 0) - * will have it's clock stopped because the AVP only talks to the - * master. The AVP does not know (nor does it need to know) that there - * are multiple processors in the CPU complex. - */ - - if (enable) { - /* Initialize PLLX */ - init_pllx(); - - /* Wait until all clocks are stable */ - udelay(PLL_STABILIZATION_DELAY); - - writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol); - writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div); - } - - /* - * Read the register containing the individual CPU clock enables and - * always stop the clock to CPU 1. - */ - clk = readl(&clkrst->crc_clk_cpu_cmplx); - clk |= 1 << CPU1_CLK_STP_SHIFT; - - /* Stop/Unstop the CPU clock */ - clk &= ~CPU0_CLK_STP_MASK; - clk |= !enable << CPU0_CLK_STP_SHIFT; - writel(clk, &clkrst->crc_clk_cpu_cmplx); - - clock_enable(PERIPH_ID_CPU); -} - -static int is_cpu_powered(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; - - return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0; -} - -static void remove_cpu_io_clamps(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; - u32 reg; - - /* Remove the clamps on the CPU I/O signals */ - reg = readl(&pmc->pmc_remove_clamping); - reg |= CPU_CLMP; - writel(reg, &pmc->pmc_remove_clamping); - - /* Give I/O signals time to stabilize */ - udelay(IO_STABILIZATION_DELAY); -} - -static void powerup_cpu(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; - u32 reg; - int timeout = IO_STABILIZATION_DELAY; - - if (!is_cpu_powered()) { - /* Toggle the CPU power state (OFF -> ON) */ - reg = readl(&pmc->pmc_pwrgate_toggle); - reg &= PARTID_CP; - reg |= START_CP; - writel(reg, &pmc->pmc_pwrgate_toggle); - - /* Wait for the power to come up */ - while (!is_cpu_powered()) { - if (timeout-- == 0) - printf("CPU failed to power up!\n"); - else - udelay(10); - } - - /* - * Remove the I/O clamps from CPU power partition. - * Recommended only on a Warm boot, if the CPU partition gets - * power gated. Shouldn't cause any harm when called after a - * cold boot according to HW, probably just redundant. - */ - remove_cpu_io_clamps(); - } -} - -static void enable_cpu_power_rail(void) -{ - struct pmc_ctlr *pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; - u32 reg; - - reg = readl(&pmc->pmc_cntrl); - reg |= CPUPWRREQ_OE; - writel(reg, &pmc->pmc_cntrl); - - /* - * The TI PMU65861C needs a 3.75ms delay between enabling - * the power rail and enabling the CPU clock. This delay - * between SM1EN and SM1 is for switching time + the ramp - * up of the voltage to the CPU (VDD_CPU from PMU). - */ - udelay(3750); -} - -static void reset_A9_cpu(int reset) -{ - /* - * NOTE: Regardless of whether the request is to hold the CPU in reset - * or take it out of reset, every processor in the CPU complex - * except the master (CPU 0) will be held in reset because the - * AVP only talks to the master. The AVP does not know that there - * are multiple processors in the CPU complex. - */ - - /* Hold CPU 1 in reset, and CPU 0 if asked */ - reset_cmplx_set_enable(1, crc_rst_cpu | crc_rst_de | crc_rst_debug, 1); - reset_cmplx_set_enable(0, crc_rst_cpu | crc_rst_de | crc_rst_debug, - reset); - - /* Enable/Disable master CPU reset */ - reset_set_enable(PERIPH_ID_CPU, reset); -} - -static void clock_enable_coresight(int enable) -{ - u32 rst, src; - - clock_set_enable(PERIPH_ID_CORESIGHT, enable); - reset_set_enable(PERIPH_ID_CORESIGHT, !enable); - - if (enable) { - /* - * Put CoreSight on PLLP_OUT0 (216 MHz) and divide it down by - * 1.5, giving an effective frequency of 144MHz. - * Set PLLP_OUT0 [bits31:30 = 00], and use a 7.1 divisor - * (bits 7:0), so 00000001b == 1.5 (n+1 + .5) - */ - src = CLK_DIVIDER(NVBL_PLLP_KHZ, 144000); - clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src); - - /* Unlock the CPU CoreSight interfaces */ - rst = 0xC5ACCE55; - writel(rst, CSITE_CPU_DBG0_LAR); - writel(rst, CSITE_CPU_DBG1_LAR); - } -} - -void start_cpu(u32 reset_vector) -{ - /* Enable VDD_CPU */ - enable_cpu_power_rail(); - - /* Hold the CPUs in reset */ - reset_A9_cpu(1); - - /* Disable the CPU clock */ - enable_cpu_clock(0); - - /* Enable CoreSight */ - clock_enable_coresight(1); - - /* - * Set the entry point for CPU execution from reset, - * if it's a non-zero value. - */ - if (reset_vector) - writel(reset_vector, EXCEP_VECTOR_CPU_RESET_VECTOR); - - /* Enable the CPU clock */ - enable_cpu_clock(1); - - /* If the CPU doesn't already have power, power it up */ - powerup_cpu(); - - /* Take the CPU out of reset */ - reset_A9_cpu(0); -} - - -void halt_avp(void) -{ - for (;;) { - writel((HALT_COP_EVENT_JTAG | HALT_COP_EVENT_IRQ_1 \ - | HALT_COP_EVENT_FIQ_1 | (FLOW_MODE_STOP<<29)), - FLOW_CTLR_HALT_COP_EVENTS); - } -} - -void enable_scu(void) +static void enable_scu(void) { struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; u32 reg; @@ -275,7 +43,7 @@ void enable_scu(void) writel(reg, &scu->scu_ctrl); }
-void init_pmc_scratch(void) +static void init_pmc_scratch(void) { struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE; int i; @@ -288,27 +56,8 @@ void init_pmc_scratch(void) writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20); }
-void tegra2_start(void) +void lowlevel_init(void) { - struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; - - /* 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 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("mov sp, %0\n" - : : "r"(AVP_EARLY_BOOT_STACK_LIMIT)); - - start_cpu((u32)_start); - halt_avp(); - /* not reached */ - } - /* Init PMC scratch memory */ init_pmc_scratch();
diff --git a/arch/arm/cpu/tegra2-common/ap20.h b/arch/arm/cpu/tegra2-common/ap20.h deleted file mode 100644 index a4b4d73..0000000 --- a/arch/arm/cpu/tegra2-common/ap20.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * (C) Copyright 2010-2011 - * NVIDIA Corporation <www.nvidia.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -#include <asm/types.h> - -/* Stabilization delays, in usec */ -#define PLL_STABILIZATION_DELAY (300) -#define IO_STABILIZATION_DELAY (1000) - -#define NVBL_PLLP_KHZ (216000) - -#define PLLX_ENABLED (1 << 30) -#define CCLK_BURST_POLICY 0x20008888 -#define SUPER_CCLK_DIVIDER 0x80000000 - -/* Calculate clock fractional divider value from ref and target frequencies */ -#define CLK_DIVIDER(REF, FREQ) ((((REF) * 2) / FREQ) - 2) - -/* Calculate clock frequency value from reference and clock divider value */ -#define CLK_FREQUENCY(REF, REG) (((REF) * 2) / (REG + 2)) - -/* AVP/CPU ID */ -#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */ -#define PG_UP_TAG_0 0x0 - -#define CORESIGHT_UNLOCK 0xC5ACCE55; - -/* AP20-Specific Base Addresses */ - -/* AP20 Base physical address of SDRAM. */ -#define AP20_BASE_PA_SDRAM 0x00000000 -/* AP20 Base physical address of internal SRAM. */ -#define AP20_BASE_PA_SRAM 0x40000000 -/* AP20 Size of internal SRAM (256KB). */ -#define AP20_BASE_PA_SRAM_SIZE 0x00040000 -/* AP20 Base physical address of flash. */ -#define AP20_BASE_PA_NOR_FLASH 0xD0000000 -/* AP20 Base physical address of boot information table. */ -#define AP20_BASE_PA_BOOT_INFO AP20_BASE_PA_SRAM - -/* - * Super-temporary stacks for EXTREMELY early startup. The values chosen for - * these addresses must be valid on ALL SOCs because this value is used before - * we are able to differentiate between the SOC types. - * - * NOTE: The since CPU's stack will eventually be moved from IRAM to SDRAM, its - * stack is placed below the AVP stack. Once the CPU stack has been moved, - * the AVP is free to use the IRAM the CPU stack previously occupied if - * it should need to do so. - * - * NOTE: In multi-processor CPU complex configurations, each processor will have - * its own stack of size CPU_EARLY_BOOT_STACK_SIZE. CPU 0 will have a - * limit of CPU_EARLY_BOOT_STACK_LIMIT. Each successive CPU will have a - * stack limit that is CPU_EARLY_BOOT_STACK_SIZE less then the previous - * CPU. - */ - -/* Common AVP early boot stack limit */ -#define AVP_EARLY_BOOT_STACK_LIMIT \ - (AP20_BASE_PA_SRAM + (AP20_BASE_PA_SRAM_SIZE/2)) -/* Common AVP early boot stack size */ -#define AVP_EARLY_BOOT_STACK_SIZE 0x1000 -/* Common CPU early boot stack limit */ -#define CPU_EARLY_BOOT_STACK_LIMIT \ - (AVP_EARLY_BOOT_STACK_LIMIT - AVP_EARLY_BOOT_STACK_SIZE) -/* Common CPU early boot stack size */ -#define CPU_EARLY_BOOT_STACK_SIZE 0x1000 - -#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100) -#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0) -#define CSITE_CPU_DBG1_LAR (NV_PA_CSITE_BASE + 0x12FB0) - -#define FLOW_CTLR_HALT_COP_EVENTS (NV_PA_FLOW_BASE + 4) -#define FLOW_MODE_STOP 2 -#define HALT_COP_EVENT_JTAG (1 << 28) -#define HALT_COP_EVENT_IRQ_1 (1 << 11) -#define HALT_COP_EVENT_FIQ_1 (1 << 9) - -/* Start up the tegra2 SOC */ -void tegra2_start(void); - -/* This is the main entry into U-Boot, used by the Cortex-A9 */ -extern void _start(void); diff --git a/arch/arm/cpu/tegra2-common/board.c b/arch/arm/cpu/tegra2-common/board.c index a797e6f..9874bb2 100644 --- a/arch/arm/cpu/tegra2-common/board.c +++ b/arch/arm/cpu/tegra2-common/board.c @@ -23,7 +23,6 @@
#include <common.h> #include <asm/io.h> -#include "ap20.h" #include <asm/arch/clock.h> #include <asm/arch/funcmux.h> #include <asm/arch/sys_proto.h> @@ -80,27 +79,6 @@ int checkboard(void) } #endif /* CONFIG_DISPLAY_BOARDINFO */
-#ifdef CONFIG_ARCH_CPU_INIT -/* - * Note this function is executed by the ARM7TDMI AVP. It does not return - * in this case. It is also called once the A9 starts up, but does nothing in - * that case. - */ -int arch_cpu_init(void) -{ - /* Fire up the Cortex A9 */ - tegra2_start(); - - /* We didn't do this init in start.S, so do it now */ - cpu_init_cp15(); - - /* Initialize essential common plls */ - clock_early_init(); - - return 0; -} -#endif - /** * Set up the specified uarts * diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h index 997887a..4828bfd 100644 --- a/include/configs/tegra2-common.h +++ b/include/configs/tegra2-common.h @@ -35,8 +35,6 @@
#define CONFIG_SYS_CACHELINE_SIZE 32
-#define CONFIG_ARCH_CPU_INIT /* Fire up the A9 core */ - #include <asm/arch/tegra2.h> /* get chip and board defs */
/* @@ -45,8 +43,6 @@ #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO
-#define CONFIG_SKIP_LOWLEVEL_INIT - #define CONFIG_CMDLINE_TAG /* enable passing of ATAGs */ #define CONFIG_OF_LIBFDT /* enable passing of devicetree */

These flags were necessary when building tegra2 as a single binary that supported ARM7TDMI and Cortex A9. Now that the ARM7TDMI support is split into a separate SPL, this is no longer necessary.
Signed-off-by: Allen Martin amartin@nvidia.com --- arch/arm/cpu/armv7/tegra2/config.mk | 8 -------- 1 file changed, 8 deletions(-)
diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk index fe9ef5b..e1e21c7 100644 --- a/arch/arm/cpu/armv7/tegra2/config.mk +++ b/arch/arm/cpu/armv7/tegra2/config.mk @@ -24,12 +24,4 @@ # MA 02111-1307 USA #
-# Tegra has an ARMv4T CPU which runs board_init_f(), so we must build this -# file with compatible flags -ifdef CONFIG_TEGRA2 -CFLAGS_arch/arm/lib/board.o += -march=armv4t -endif - -USE_PRIVATE_LIBGCC = yes - CONFIG_ARCH_DEVICE_TREE := tegra20

On 05/10/2012 01:02 AM, Allen Martin wrote:
These flags were necessary when building tegra2 as a single binary that supported ARM7TDMI and Cortex A9. Now that the ARM7TDMI support is split into a separate SPL, this is no longer necessary.
diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk
-# Tegra has an ARMv4T CPU which runs board_init_f(), so we must build this -# file with compatible flags -ifdef CONFIG_TEGRA2 -CFLAGS_arch/arm/lib/board.o += -march=armv4t -endif
That makes sense since the CFLAGS for the SPL build will be set up appropriately for the AVP.
-USE_PRIVATE_LIBGCC = yes
However, we force this because the toolchains we typically use for U-Boot are targeted at the A9 CPUs, and hence the libgcc there contains ARMv7 instructions. Did I miss something in this series or earlier that uses a different toolchain for the SPL, which includes an ARMv4 build of libgcc?

On Mon, May 14, 2012 at 10:11:26PM -0700, Stephen Warren wrote:
On 05/10/2012 01:02 AM, Allen Martin wrote:
-USE_PRIVATE_LIBGCC = yes
However, we force this because the toolchains we typically use for U-Boot are targeted at the A9 CPUs, and hence the libgcc there contains ARMv7 instructions. Did I miss something in this series or earlier that uses a different toolchain for the SPL, which includes an ARMv4 build of libgcc?
You're right, that's a mistake, I'll revert that line. There is a problem right now where if you have both SPL and USE_PRIVATE_LIBGCC turned on, the SPL build of libgcc tries to link against the main u-boot libgcc, which in itself is probably fine, except on a clean build it hasn't been built yet. So I'll have to fix that.
-Allen
participants (2)
-
Allen Martin
-
Stephen Warren