Signed-off-by: Tom Warren twar...@nvidia.com
---
Changes for V2:
- Remove returns in void functions
- Move inline assembly code to .S file
- Simplify some if/else code, break out common code
- Minimize the use of local vars
- Inline some single-instance functions
- Remove TRUE/FALSE define, use 1/0 instead
- Replace memset of mem-mapped regs w/loop of writel's
Changes for V3:
- Fix C-style comments in lowlevel_init.S cache_configure
Changes for V4:
- Move cold_boot() from C to assembly
- Fix spacing in cache_configure
Changes for V5:
- Add a timeout and printf msg if CPU never powers up
- Remove redundant is_cpu_powered in start_cpu
arch/arm/cpu/armv7/start.S | 12 +
arch/arm/cpu/armv7/tegra2/Makefile |2 +-
arch/arm/cpu/armv7/tegra2/ap20.c | 329
arch/arm/cpu/armv7/tegra2/ap20.h | 104 +
arch/arm/cpu/armv7/tegra2/lowlevel_init.S | 94
arch/arm/include/asm/arch-tegra2/clk_rst.h | 27 +++
arch/arm/include/asm/arch-tegra2/pmc.h |8 +
arch/arm/include/asm/arch-tegra2/scu.h | 43
arch/arm/include/asm/arch-tegra2/tegra2.h |8 +
board/nvidia/common/board.c| 10 +
board/nvidia/common/board.h| 29 +++
include/configs/harmony.h |1 +
include/configs/seaboard.h |1 +
include/configs/tegra2-common.h|2 +
14 files changed, 669 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/cpu/armv7/tegra2/ap20.c
create mode 100644 arch/arm/cpu/armv7/tegra2/ap20.h
create mode 100644 arch/arm/include/asm/arch-tegra2/scu.h
create mode 100644 board/nvidia/common/board.h
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index d83d501..bef0a6d 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -70,6 +70,18 @@ _end_vect:
_TEXT_BASE:
.word CONFIG_SYS_TEXT_BASE
+#ifdef CONFIG_TEGRA2
+/*
+ * Tegra2 uses 2 separate CPUs - the AVP (ARM7TDMI) and the CPU (dual A9s).
+ * U-Boot runs on the AVP first, setting things up for the CPU (PLLs,
+ * muxes, clocks, clamps, etc.). Then the AVP halts, and expects the CPU
+ * to pick up its reset vector, which points here.
+ */
+.globl _armboot_start
+_armboot_start:
+.word _start
+#endif
+
/*
* These are defined in the board-specific linker script.
*/
diff --git a/arch/arm/cpu/armv7/tegra2/Makefile
b/arch/arm/cpu/armv7/tegra2/Makefile
index 687c887..f1ea915 100644
--- a/arch/arm/cpu/armv7/tegra2/Makefile
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk
LIB= $(obj)lib$(SOC).o
SOBJS := lowlevel_init.o
-COBJS := board.o sys_info.o timer.o
+COBJS := ap20.o board.o sys_info.o timer.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
new file mode 100644
index 000..d3e6797
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/ap20.c
@@ -0,0 +1,329 @@
+/*
+* (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 ap20.h
+#include asm/io.h
+#include asm/arch/tegra2.h
+#include asm/arch/clk_rst.h
+#include asm/arch/pmc.h
+#include asm/arch/pinmux.h
+#include asm/arch/scu.h
+#include common.h
+
+u32 s_first_boot = 1;
+
+static void enable_cpu_clock(int enable)
+{
+ struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 reg, 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) {
+ /* Wait until all clocks are stable */
+ udelay(PLL_STABILIZATION_DELAY);
+
+ writel(CCLK_BURST_POLICY, clkrst-crc_cclk_brst_pol);