[U-Boot] [PATCH v3 07/14] ARM: add tegra20 support to arm720t

Allen Martin
2012-06-08T21:16:00Z

Add support for tegra20 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 | 2 +
arch/arm/cpu/arm720t/interrupts.c | 4 +
arch/arm/cpu/arm720t/start.S | 6 +-
.../{tegra20-common => arm720t/tegra20}/Makefile | 22 +-
arch/arm/cpu/arm720t/tegra20/board.h | 25 ++
arch/arm/cpu/arm720t/tegra20/cpu.c | 259 ++++++++++++++++++++
arch/arm/cpu/arm720t/tegra20/cpu.h | 99 ++++++++
arch/arm/cpu/arm720t/tegra20/spl.c | 133 ++++++++++
arch/arm/cpu/tegra20-common/Makefile | 2 +-
arch/arm/include/asm/arch-tegra20/hardware.h | 29 +++
10 files changed, 562 insertions(+), 19 deletions(-)
copy arch/arm/cpu/{tegra20-common => arm720t/tegra20}/Makefile (64%)
create mode 100644 arch/arm/cpu/arm720t/tegra20/board.h
create mode 100644 arch/arm/cpu/arm720t/tegra20/cpu.c
create mode 100644 arch/arm/cpu/arm720t/tegra20/cpu.h
create mode 100644 arch/arm/cpu/arm720t/tegra20/spl.c
create mode 100644 arch/arm/include/asm/arch-tegra20/hardware.h

diff --git a/arch/arm/cpu/arm720t/cpu.c b/arch/arm/cpu/arm720t/cpu.c
index 974f288..b6eee7e 100644
--- a/arch/arm/cpu/arm720t/cpu.c
+++ b/arch/arm/cpu/arm720t/cpu.c
@@ -51,6 +51,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_TEGRA)
+ /* 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..e64e6f2 100644
--- a/arch/arm/cpu/arm720t/interrupts.c
+++ b/arch/arm/cpu/arm720t/interrupts.c
@@ -180,6 +180,8 @@ int timer_init (void)
PUT32(T0TC, 0);
PUT32(T0TCR, 1); /* enable timer0 */

+#elif defined(CONFIG_TEGRA)
+ /* No timer routines for tegra as yet */
#else
#error No timer_init() defined for this CPU type
#endif
@@ -282,6 +284,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_TEGRA)
+ /* 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..3371d3d 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_TEGRA)
+ /* 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_TEGRA)
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_TEGRA)
+ /* 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/tegra20-common/Makefile b/arch/arm/cpu/arm720t/tegra20/Makefile
similarity index 64%
copy from arch/arm/cpu/tegra20-common/Makefile
copy to arch/arm/cpu/arm720t/tegra20/Makefile
index 28a4c81..6e48475 100644
--- a/arch/arm/cpu/tegra20-common/Makefile
+++ b/arch/arm/cpu/arm720t/tegra20/Makefile
@@ -25,31 +25,19 @@

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/tegra20-common/ap20.o += -march=armv4t
-CFLAGS_arch/arm/cpu/tegra20-common/clock.o += -march=armv4t
-CFLAGS_arch/arm/cpu/tegra20-common/warmboot_avp.o += -march=armv4t
+LIB = $(obj)lib$(SOC).o

-LIB = $(obj)lib$(SOC)-common.o
+COBJS-y += cpu.o
+COBJS-$(CONFIG_SPL_BUILD) += spl.o

-SOBJS += lowlevel_init.o
-COBJS-y += ap20.o board.o clock.o funcmux.o pinmux.o sys_info.o timer.o
-COBJS-$(CONFIG_TEGRA2_LP0) += warmboot.o crypto.o warmboot_avp.o
-COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
-COBJS-$(CONFIG_TEGRA_PMU) += pmu.o
-
-SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
-OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+SRCS := $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS-y))

all: $(obj).depend $(LIB)

$(LIB): $(OBJS)
$(call cmd_link_o_target, $(OBJS))

-$(obj).depend:
- echo wtf
-
#########################################################################

# defines $(obj).depend target
diff --git a/arch/arm/cpu/arm720t/tegra20/board.h b/arch/arm/cpu/arm720t/tegra20/board.h
new file mode 100644
index 0000000..61b91c0
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra20/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/tegra20/cpu.c b/arch/arm/cpu/arm720t/tegra20/cpu.c
new file mode 100644
index 0000000..cdf417d
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra20/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/tegra20.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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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 *)TEGRA20_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/tegra20/cpu.h b/arch/arm/cpu/arm720t/tegra20/cpu.h
new file mode 100644
index 0000000..90857a8
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra20/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/tegra20/spl.c b/arch/arm/cpu/arm720t/tegra20/spl.c
new file mode 100644
index 0000000..e3d4dcc
--- /dev/null
+++ b/arch/arm/cpu/arm720t/tegra20/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/tegra20.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/cpu/tegra20-common/Makefile b/arch/arm/cpu/tegra20-common/Makefile
index 28a4c81..572538b 100644
--- a/arch/arm/cpu/tegra20-common/Makefile
+++ b/arch/arm/cpu/tegra20-common/Makefile
@@ -35,7 +35,7 @@ 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
-COBJS-$(CONFIG_TEGRA2_LP0) += warmboot.o crypto.o warmboot_avp.o
+COBJS-$(CONFIG_TEGRA20_LP0) += warmboot.o crypto.o warmboot_avp.o
COBJS-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
COBJS-$(CONFIG_TEGRA_PMU) += pmu.o

diff --git a/arch/arm/include/asm/arch-tegra20/hardware.h b/arch/arm/include/asm/arch-tegra20/hardware.h
new file mode 100644
index 0000000..8c47578
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra20/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 */
--
1.7.9.5