[U-Boot] [PATCH 1/1] tegra2: move tegra2 SoC code to arch/arm/cpu/tegra2-common

Allen Martin amartin at nvidia.com
Wed Apr 18 20:17:01 CEST 2012


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 at nvidia.com>
---
 Makefile                                   |    3 +
 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/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          |  324 +++++++++
 arch/arm/cpu/tegra2-common/ap20.h          |  102 +++
 arch/arm/cpu/tegra2-common/board.c         |  151 ++++
 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 +++
 spl/Makefile                               |    4 +
 22 files changed, 2637 insertions(+), 2582 deletions(-)
 delete mode 100644 arch/arm/cpu/armv7/tegra2/ap20.c
 delete mode 100644 arch/arm/cpu/armv7/tegra2/ap20.h
 delete mode 100644 arch/arm/cpu/armv7/tegra2/board.c
 delete mode 100644 arch/arm/cpu/armv7/tegra2/clock.c
 delete mode 100644 arch/arm/cpu/armv7/tegra2/funcmux.c
 delete mode 100644 arch/arm/cpu/armv7/tegra2/lowlevel_init.S
 delete mode 100644 arch/arm/cpu/armv7/tegra2/pinmux.c
 delete mode 100644 arch/arm/cpu/armv7/tegra2/sys_info.c
 delete mode 100644 arch/arm/cpu/armv7/tegra2/timer.c
 create mode 100644 arch/arm/cpu/tegra2-common/Makefile
 create mode 100644 arch/arm/cpu/tegra2-common/ap20.c
 create mode 100644 arch/arm/cpu/tegra2-common/ap20.h
 create mode 100644 arch/arm/cpu/tegra2-common/board.c
 create mode 100644 arch/arm/cpu/tegra2-common/clock.c
 create mode 100644 arch/arm/cpu/tegra2-common/funcmux.c
 create mode 100644 arch/arm/cpu/tegra2-common/lowlevel_init.S
 create mode 100644 arch/arm/cpu/tegra2-common/pinmux.c
 create mode 100644 arch/arm/cpu/tegra2-common/sys_info.c
 create mode 100644 arch/arm/cpu/tegra2-common/timer.c

diff --git a/Makefile b/Makefile
index 4ddf8d6..6639de0 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/armv7/tegra2/ap20.c b/arch/arm/cpu/armv7/tegra2/ap20.c
deleted file mode 100644
index b749821..0000000
--- a/arch/arm/cpu/armv7/tegra2/ap20.c
+++ /dev/null
@@ -1,324 +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 "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)
-{
-	struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE;
-	u32 reg;
-
-	/* If SCU already setup/enabled, return */
-	if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE)
-		return;
-
-	/* Invalidate all ways for all processors */
-	writel(0xFFFF, &scu->scu_inv_all);
-
-	/* Enable SCU - bit 0 */
-	reg = readl(&scu->scu_ctrl);
-	reg |= SCU_CTRL_ENABLE;
-	writel(reg, &scu->scu_ctrl);
-}
-
-void init_pmc_scratch(void)
-{
-	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
-	int i;
-
-	/* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */
-	for (i = 0; i < 23; i++)
-		writel(0, &pmc->pmc_scratch1+i);
-
-	/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */
-	writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
-}
-
-void tegra2_start(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();
-
-	enable_scu();
-
-	/* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */
-	asm volatile(
-		"mrc	p15, 0, r0, c1, c0, 1\n"
-		"orr	r0, r0, #0x41\n"
-		"mcr	p15, 0, r0, c1, c0, 1\n");
-
-	/* FIXME: should have ap20's L2 disabled too? */
-}
diff --git a/arch/arm/cpu/armv7/tegra2/ap20.h b/arch/arm/cpu/armv7/tegra2/ap20.h
deleted file mode 100644
index a4b4d73..0000000
--- a/arch/arm/cpu/armv7/tegra2/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/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c
deleted file mode 100644
index a797e6f..0000000
--- a/arch/arm/cpu/armv7/tegra2/board.c
+++ /dev/null
@@ -1,151 +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 <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>
-#include <asm/arch/tegra2.h>
-#include <asm/arch/pmc.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-enum {
-	/* UARTs which we can enable */
-	UARTA	= 1 << 0,
-	UARTB	= 1 << 1,
-	UARTD	= 1 << 3,
-	UART_COUNT = 4,
-};
-
-/*
- * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0,
- * so we are using this value to identify memory size.
- */
-
-unsigned int query_sdram_size(void)
-{
-	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
-	u32 reg;
-
-	reg = readl(&pmc->pmc_scratch20);
-	debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
-
-	/* bits 31:28 in OdmData are used for RAM size  */
-	switch ((reg) >> 28) {
-	case 1:
-		return 0x10000000;	/* 256 MB */
-	case 2:
-	default:
-		return 0x20000000;	/* 512 MB */
-	case 3:
-		return 0x40000000;	/* 1GB */
-	}
-}
-
-int dram_init(void)
-{
-	/* We do not initialise DRAM here. We just query the size */
-	gd->ram_size = query_sdram_size();
-	return 0;
-}
-
-#ifdef CONFIG_DISPLAY_BOARDINFO
-int checkboard(void)
-{
-	printf("Board: %s\n", sysinfo.board_string);
-	return 0;
-}
-#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
- *
- * @param uarts_ids	Mask containing UARTs to init (UARTx)
- */
-static void setup_uarts(int uart_ids)
-{
-	static enum periph_id id_for_uart[] = {
-		PERIPH_ID_UART1,
-		PERIPH_ID_UART2,
-		PERIPH_ID_UART3,
-		PERIPH_ID_UART4,
-	};
-	size_t i;
-
-	for (i = 0; i < UART_COUNT; i++) {
-		if (uart_ids & (1 << i)) {
-			enum periph_id id = id_for_uart[i];
-
-			funcmux_select(id, FUNCMUX_DEFAULT);
-			clock_ll_start_uart(id);
-		}
-	}
-}
-
-void board_init_uart_f(void)
-{
-	int uart_ids = 0;	/* bit mask of which UART ids to enable */
-
-#ifdef CONFIG_TEGRA2_ENABLE_UARTA
-	uart_ids |= UARTA;
-#endif
-#ifdef CONFIG_TEGRA2_ENABLE_UARTB
-	uart_ids |= UARTB;
-#endif
-#ifdef CONFIG_TEGRA2_ENABLE_UARTD
-	uart_ids |= UARTD;
-#endif
-	setup_uarts(uart_ids);
-}
-
-#ifndef CONFIG_SYS_DCACHE_OFF
-void enable_caches(void)
-{
-	/* Enable D-cache. I-cache is already enabled in start.S */
-	dcache_enable();
-}
-#endif
diff --git a/arch/arm/cpu/armv7/tegra2/clock.c b/arch/arm/cpu/armv7/tegra2/clock.c
deleted file mode 100644
index 39376ab..0000000
--- a/arch/arm/cpu/armv7/tegra2/clock.c
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- * 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
- */
-
-/* Tegra2 Clock control functions */
-
-#include <asm/io.h>
-#include <asm/arch/clk_rst.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/timer.h>
-#include <asm/arch/tegra2.h>
-#include <common.h>
-#include <div64.h>
-#include <fdtdec.h>
-
-/*
- * This is our record of the current clock rate of each clock. We don't
- * fill all of these in since we are only really interested in clocks which
- * we use as parents.
- */
-static unsigned pll_rate[CLOCK_ID_COUNT];
-
-/*
- * The oscillator frequency is fixed to one of four set values. Based on this
- * the other clocks are set up appropriately.
- */
-static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
-	13000000,
-	19200000,
-	12000000,
-	26000000,
-};
-
-/*
- * Clock types that we can use as a source. The Tegra2 has muxes for the
- * peripheral clocks, and in most cases there are four options for the clock
- * source. This gives us a clock 'type' and exploits what commonality exists
- * in the device.
- *
- * Letters are obvious, except for T which means CLK_M, and S which means the
- * clock derived from 32KHz. Beware that CLK_M (also called OSC in the
- * datasheet) and PLL_M are different things. The former is the basic
- * clock supplied to the SOC from an external oscillator. The latter is the
- * memory clock PLL.
- *
- * See definitions in clock_id in the header file.
- */
-enum clock_type_id {
-	CLOCK_TYPE_AXPT,	/* PLL_A, PLL_X, PLL_P, CLK_M */
-	CLOCK_TYPE_MCPA,	/* and so on */
-	CLOCK_TYPE_MCPT,
-	CLOCK_TYPE_PCM,
-	CLOCK_TYPE_PCMT,
-	CLOCK_TYPE_PCMT16,	/* CLOCK_TYPE_PCMT with 16-bit divider */
-	CLOCK_TYPE_PCXTS,
-	CLOCK_TYPE_PDCT,
-
-	CLOCK_TYPE_COUNT,
-	CLOCK_TYPE_NONE = -1,	/* invalid clock type */
-};
-
-/* return 1 if a peripheral ID is in range */
-#define clock_type_id_isvalid(id) ((id) >= 0 && \
-		(id) < CLOCK_TYPE_COUNT)
-
-char pllp_valid = 1;	/* PLLP is set up correctly */
-
-enum {
-	CLOCK_MAX_MUX	= 4	/* number of source options for each clock */
-};
-
-/*
- * Clock source mux for each clock type. This just converts our enum into
- * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS
- * is special as it has 5 sources. Since it also has a different number of
- * bits in its register for the source, we just handle it with a special
- * case in the code.
- */
-#define CLK(x) CLOCK_ID_ ## x
-static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = {
-	{ CLK(AUDIO),	CLK(XCPU),	CLK(PERIPH),	CLK(OSC)	},
-	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(AUDIO)	},
-	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(NONE)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(XCPU),	CLK(OSC)	},
-	{ CLK(PERIPH),	CLK(DISPLAY),	CLK(CGENERAL),	CLK(OSC)	},
-};
-
-/*
- * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is
- * not in the header file since it is for purely internal use - we want
- * callers to use the PERIPH_ID for all access to peripheral clocks to avoid
- * confusion bewteen PERIPH_ID_... and PERIPHC_...
- *
- * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be
- * confusing.
- *
- * Note to SOC vendors: perhaps define a unified numbering for peripherals and
- * use it for reset, clock enable, clock source/divider and even pinmuxing
- * if you can.
- */
-enum periphc_internal_id {
-	/* 0x00 */
-	PERIPHC_I2S1,
-	PERIPHC_I2S2,
-	PERIPHC_SPDIF_OUT,
-	PERIPHC_SPDIF_IN,
-	PERIPHC_PWM,
-	PERIPHC_SPI1,
-	PERIPHC_SPI2,
-	PERIPHC_SPI3,
-
-	/* 0x08 */
-	PERIPHC_XIO,
-	PERIPHC_I2C1,
-	PERIPHC_DVC_I2C,
-	PERIPHC_TWC,
-	PERIPHC_0c,
-	PERIPHC_10,	/* PERIPHC_SPI1, what is this really? */
-	PERIPHC_DISP1,
-	PERIPHC_DISP2,
-
-	/* 0x10 */
-	PERIPHC_CVE,
-	PERIPHC_IDE0,
-	PERIPHC_VI,
-	PERIPHC_1c,
-	PERIPHC_SDMMC1,
-	PERIPHC_SDMMC2,
-	PERIPHC_G3D,
-	PERIPHC_G2D,
-
-	/* 0x18 */
-	PERIPHC_NDFLASH,
-	PERIPHC_SDMMC4,
-	PERIPHC_VFIR,
-	PERIPHC_EPP,
-	PERIPHC_MPE,
-	PERIPHC_MIPI,
-	PERIPHC_UART1,
-	PERIPHC_UART2,
-
-	/* 0x20 */
-	PERIPHC_HOST1X,
-	PERIPHC_21,
-	PERIPHC_TVO,
-	PERIPHC_HDMI,
-	PERIPHC_24,
-	PERIPHC_TVDAC,
-	PERIPHC_I2C2,
-	PERIPHC_EMC,
-
-	/* 0x28 */
-	PERIPHC_UART3,
-	PERIPHC_29,
-	PERIPHC_VI_SENSOR,
-	PERIPHC_2b,
-	PERIPHC_2c,
-	PERIPHC_SPI4,
-	PERIPHC_I2C3,
-	PERIPHC_SDMMC3,
-
-	/* 0x30 */
-	PERIPHC_UART4,
-	PERIPHC_UART5,
-	PERIPHC_VDE,
-	PERIPHC_OWR,
-	PERIPHC_NOR,
-	PERIPHC_CSITE,
-
-	PERIPHC_COUNT,
-
-	PERIPHC_NONE = -1,
-};
-
-/* return 1 if a periphc_internal_id is in range */
-#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
-		(id) < PERIPHC_COUNT)
-
-/*
- * Clock type for each peripheral clock source. We put the name in each
- * record just so it is easy to match things up
- */
-#define TYPE(name, type) type
-static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
-	/* 0x00 */
-	TYPE(PERIPHC_I2S1,	CLOCK_TYPE_AXPT),
-	TYPE(PERIPHC_I2S2,	CLOCK_TYPE_AXPT),
-	TYPE(PERIPHC_SPDIF_OUT,	CLOCK_TYPE_AXPT),
-	TYPE(PERIPHC_SPDIF_IN,	CLOCK_TYPE_PCM),
-	TYPE(PERIPHC_PWM,	CLOCK_TYPE_PCXTS),
-	TYPE(PERIPHC_SPI1,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_SPI22,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_SPI3,	CLOCK_TYPE_PCMT),
-
-	/* 0x08 */
-	TYPE(PERIPHC_XIO,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_I2C1,	CLOCK_TYPE_PCMT16),
-	TYPE(PERIPHC_DVC_I2C,	CLOCK_TYPE_PCMT16),
-	TYPE(PERIPHC_TWC,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_SPI1,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_DISP1,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_DISP2,	CLOCK_TYPE_PDCT),
-
-	/* 0x10 */
-	TYPE(PERIPHC_CVE,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_IDE0,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_SDMMC1,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_SDMMC2,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_G3D,	CLOCK_TYPE_MCPA),
-	TYPE(PERIPHC_G2D,	CLOCK_TYPE_MCPA),
-
-	/* 0x18 */
-	TYPE(PERIPHC_NDFLASH,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_SDMMC4,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_VFIR,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_EPP,	CLOCK_TYPE_MCPA),
-	TYPE(PERIPHC_MPE,	CLOCK_TYPE_MCPA),
-	TYPE(PERIPHC_MIPI,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_UART1,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_UART2,	CLOCK_TYPE_PCMT),
-
-	/* 0x20 */
-	TYPE(PERIPHC_HOST1X,	CLOCK_TYPE_MCPA),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_TVO,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_HDMI,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_TVDAC,	CLOCK_TYPE_PDCT),
-	TYPE(PERIPHC_I2C2,	CLOCK_TYPE_PCMT16),
-	TYPE(PERIPHC_EMC,	CLOCK_TYPE_MCPT),
-
-	/* 0x28 */
-	TYPE(PERIPHC_UART3,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
-	TYPE(PERIPHC_SPI4,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_I2C3,	CLOCK_TYPE_PCMT16),
-	TYPE(PERIPHC_SDMMC3,	CLOCK_TYPE_PCMT),
-
-	/* 0x30 */
-	TYPE(PERIPHC_UART4,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_UART5,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_VDE,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_OWR,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_NOR,	CLOCK_TYPE_PCMT),
-	TYPE(PERIPHC_CSITE,	CLOCK_TYPE_PCMT),
-};
-
-/*
- * This array translates a periph_id to a periphc_internal_id
- *
- * Not present/matched up:
- *	uint vi_sensor;	 _VI_SENSOR_0,		0x1A8
- *	SPDIF - which is both 0x08 and 0x0c
- *
- */
-#define NONE(name) (-1)
-#define OFFSET(name, value) PERIPHC_ ## name
-static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
-	/* Low word: 31:0 */
-	NONE(CPU),
-	NONE(RESERVED1),
-	NONE(RESERVED2),
-	NONE(AC97),
-	NONE(RTC),
-	NONE(TMR),
-	PERIPHC_UART1,
-	PERIPHC_UART2,	/* and vfir 0x68 */
-
-	/* 0x08 */
-	NONE(GPIO),
-	PERIPHC_SDMMC2,
-	NONE(SPDIF),		/* 0x08 and 0x0c, unclear which to use */
-	PERIPHC_I2S1,
-	PERIPHC_I2C1,
-	PERIPHC_NDFLASH,
-	PERIPHC_SDMMC1,
-	PERIPHC_SDMMC4,
-
-	/* 0x10 */
-	PERIPHC_TWC,
-	PERIPHC_PWM,
-	PERIPHC_I2S2,
-	PERIPHC_EPP,
-	PERIPHC_VI,
-	PERIPHC_G2D,
-	NONE(USBD),
-	NONE(ISP),
-
-	/* 0x18 */
-	PERIPHC_G3D,
-	PERIPHC_IDE0,
-	PERIPHC_DISP2,
-	PERIPHC_DISP1,
-	PERIPHC_HOST1X,
-	NONE(VCP),
-	NONE(RESERVED30),
-	NONE(CACHE2),
-
-	/* Middle word: 63:32 */
-	NONE(MEM),
-	NONE(AHBDMA),
-	NONE(APBDMA),
-	NONE(RESERVED35),
-	NONE(KBC),
-	NONE(STAT_MON),
-	NONE(PMC),
-	NONE(FUSE),
-
-	/* 0x28 */
-	NONE(KFUSE),
-	NONE(SBC1),	/* SBC1, 0x34, is this SPI1? */
-	PERIPHC_NOR,
-	PERIPHC_SPI1,
-	PERIPHC_SPI2,
-	PERIPHC_XIO,
-	PERIPHC_SPI3,
-	PERIPHC_DVC_I2C,
-
-	/* 0x30 */
-	NONE(DSI),
-	PERIPHC_TVO,	/* also CVE 0x40 */
-	PERIPHC_MIPI,
-	PERIPHC_HDMI,
-	PERIPHC_CSITE,
-	PERIPHC_TVDAC,
-	PERIPHC_I2C2,
-	PERIPHC_UART3,
-
-	/* 0x38 */
-	NONE(RESERVED56),
-	PERIPHC_EMC,
-	NONE(USB2),
-	NONE(USB3),
-	PERIPHC_MPE,
-	PERIPHC_VDE,
-	NONE(BSEA),
-	NONE(BSEV),
-
-	/* Upper word 95:64 */
-	NONE(SPEEDO),
-	PERIPHC_UART4,
-	PERIPHC_UART5,
-	PERIPHC_I2C3,
-	PERIPHC_SPI4,
-	PERIPHC_SDMMC3,
-	NONE(PCIE),
-	PERIPHC_OWR,
-
-	/* 0x48 */
-	NONE(AFI),
-	NONE(CORESIGHT),
-	NONE(RESERVED74),
-	NONE(AVPUCQ),
-	NONE(RESERVED76),
-	NONE(RESERVED77),
-	NONE(RESERVED78),
-	NONE(RESERVED79),
-
-	/* 0x50 */
-	NONE(RESERVED80),
-	NONE(RESERVED81),
-	NONE(RESERVED82),
-	NONE(RESERVED83),
-	NONE(IRAMA),
-	NONE(IRAMB),
-	NONE(IRAMC),
-	NONE(IRAMD),
-
-	/* 0x58 */
-	NONE(CRAM2),
-};
-
-/*
- * Get the oscillator frequency, from the corresponding hardware configuration
- * field.
- */
-enum clock_osc_freq clock_get_osc_freq(void)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 reg;
-
-	reg = readl(&clkrst->crc_osc_ctrl);
-	return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
-}
-
-/* Returns a pointer to the registers of the given pll */
-static struct clk_pll *get_pll(enum clock_id clkid)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-
-	assert(clock_id_isvalid(clkid));
-	return &clkrst->crc_pll[clkid];
-}
-
-unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
-		u32 divp, u32 cpcon, u32 lfcon)
-{
-	struct clk_pll *pll = get_pll(clkid);
-	u32 data;
-
-	/*
-	 * We cheat by treating all PLL (except PLLU) in the same fashion.
-	 * This works only because:
-	 * - same fields are always mapped at same offsets, except DCCON
-	 * - DCCON is always 0, doesn't conflict
-	 * - M,N, P of PLLP values are ignored for PLLP
-	 */
-	data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
-	writel(data, &pll->pll_misc);
-
-	data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
-			(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
-
-	if (clkid == CLOCK_ID_USB)
-		data |= divp << PLLU_VCO_FREQ_SHIFT;
-	else
-		data |= divp << PLL_DIVP_SHIFT;
-	writel(data, &pll->pll_base);
-
-	/* calculate the stable time */
-	return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
-}
-
-/* return 1 if a peripheral ID is in range and valid */
-static int clock_periph_id_isvalid(enum periph_id id)
-{
-	if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT)
-		printf("Peripheral id %d out of range\n", id);
-	else {
-		switch (id) {
-		case PERIPH_ID_RESERVED1:
-		case PERIPH_ID_RESERVED2:
-		case PERIPH_ID_RESERVED30:
-		case PERIPH_ID_RESERVED35:
-		case PERIPH_ID_RESERVED56:
-		case PERIPH_ID_RESERVED74:
-		case PERIPH_ID_RESERVED76:
-		case PERIPH_ID_RESERVED77:
-		case PERIPH_ID_RESERVED78:
-		case PERIPH_ID_RESERVED79:
-		case PERIPH_ID_RESERVED80:
-		case PERIPH_ID_RESERVED81:
-		case PERIPH_ID_RESERVED82:
-		case PERIPH_ID_RESERVED83:
-			printf("Peripheral id %d is reserved\n", id);
-			break;
-		default:
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/* Returns a pointer to the clock source register for a peripheral */
-static u32 *get_periph_source_reg(enum periph_id periph_id)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	enum periphc_internal_id internal_id;
-
-	assert(clock_periph_id_isvalid(periph_id));
-	internal_id = periph_id_to_internal_id[periph_id];
-	assert(internal_id != -1);
-	return &clkrst->crc_clk_src[internal_id];
-}
-
-void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
-			      unsigned divisor)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-	u32 value;
-
-	value = readl(reg);
-
-	value &= ~OUT_CLK_SOURCE_MASK;
-	value |= source << OUT_CLK_SOURCE_SHIFT;
-
-	value &= ~OUT_CLK_DIVISOR_MASK;
-	value |= divisor << OUT_CLK_DIVISOR_SHIFT;
-
-	writel(value, reg);
-}
-
-void clock_ll_set_source(enum periph_id periph_id, unsigned source)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-
-	clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
-			source << OUT_CLK_SOURCE_SHIFT);
-}
-
-/**
- * Given the parent's rate and the required rate for the children, this works
- * out the peripheral clock divider to use, in 7.1 binary format.
- *
- * @param divider_bits	number of divider bits (8 or 16)
- * @param parent_rate	clock rate of parent clock in Hz
- * @param rate		required clock rate for this clock
- * @return divider which should be used
- */
-static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
-			   unsigned long rate)
-{
-	u64 divider = parent_rate * 2;
-	unsigned max_divider = 1 << divider_bits;
-
-	divider += rate - 1;
-	do_div(divider, rate);
-
-	if ((s64)divider - 2 < 0)
-		return 0;
-
-	if ((s64)divider - 2 >= max_divider)
-		return -1;
-
-	return divider - 2;
-}
-
-/**
- * Given the parent's rate and the divider in 7.1 format, this works out the
- * resulting peripheral clock rate.
- *
- * @param parent_rate	clock rate of parent clock in Hz
- * @param divider which should be used in 7.1 format
- * @return effective clock rate of peripheral
- */
-static unsigned long get_rate_from_divider(unsigned long parent_rate,
-					   int divider)
-{
-	u64 rate;
-
-	rate = (u64)parent_rate * 2;
-	do_div(rate, divider + 2);
-	return rate;
-}
-
-unsigned long clock_get_periph_rate(enum periph_id periph_id,
-		enum clock_id parent)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-
-	return get_rate_from_divider(pll_rate[parent],
-		(readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
-}
-
-/**
- * Find the best available 7.1 format divisor given a parent clock rate and
- * required child clock rate. This function assumes that a second-stage
- * divisor is available which can divide by powers of 2 from 1 to 256.
- *
- * @param divider_bits	number of divider bits (8 or 16)
- * @param parent_rate	clock rate of parent clock in Hz
- * @param rate		required clock rate for this clock
- * @param extra_div	value for the second-stage divisor (not set if this
- *			function returns -1.
- * @return divider which should be used, or -1 if nothing is valid
- *
- */
-static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
-			     unsigned long rate, int *extra_div)
-{
-	int shift;
-	int best_divider = -1;
-	int best_error = rate;
-
-	/* try dividers from 1 to 256 and find closest match */
-	for (shift = 0; shift <= 8 && best_error > 0; shift++) {
-		unsigned divided_parent = parent_rate >> shift;
-		int divider = clk_get_divider(divider_bits, divided_parent,
-					      rate);
-		unsigned effective_rate = get_rate_from_divider(divided_parent,
-						       divider);
-		int error = rate - effective_rate;
-
-		/* Given a valid divider, look for the lowest error */
-		if (divider != -1 && error < best_error) {
-			best_error = error;
-			*extra_div = 1 << shift;
-			best_divider = divider;
-		}
-	}
-
-	/* return what we found - *extra_div will already be set */
-	return best_divider;
-}
-
-/**
- * Given a peripheral ID and the required source clock, this returns which
- * value should be programmed into the source mux for that peripheral.
- *
- * There is special code here to handle the one source type with 5 sources.
- *
- * @param periph_id	peripheral to start
- * @param source	PLL id of required parent clock
- * @param mux_bits	Set to number of bits in mux register: 2 or 4
- * @param divider_bits	Set to number of divider bits (8 or 16)
- * @return mux value (0-4, or -1 if not found)
- */
-static int get_periph_clock_source(enum periph_id periph_id,
-		enum clock_id parent, int *mux_bits, int *divider_bits)
-{
-	enum clock_type_id type;
-	enum periphc_internal_id internal_id;
-	int mux;
-
-	assert(clock_periph_id_isvalid(periph_id));
-
-	internal_id = periph_id_to_internal_id[periph_id];
-	assert(periphc_internal_id_isvalid(internal_id));
-
-	type = clock_periph_type[internal_id];
-	assert(clock_type_id_isvalid(type));
-
-	/*
-	 * Special cases here for the clock with a 4-bit source mux and I2C
-	 * with its 16-bit divisor
-	 */
-	if (type == CLOCK_TYPE_PCXTS)
-		*mux_bits = 4;
-	else
-		*mux_bits = 2;
-	if (type == CLOCK_TYPE_PCMT16)
-		*divider_bits = 16;
-	else
-		*divider_bits = 8;
-
-	for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
-		if (clock_source[type][mux] == parent)
-			return mux;
-
-	/*
-	 * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS
-	 * which is not in our table. If not, then they are asking for a
-	 * source which this peripheral can't access through its mux.
-	 */
-	assert(type == CLOCK_TYPE_PCXTS);
-	assert(parent == CLOCK_ID_SFROM32KHZ);
-	if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ)
-		return 4;	/* mux value for this clock */
-
-	/* if we get here, either us or the caller has made a mistake */
-	printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
-		parent);
-	return -1;
-}
-
-/**
- * Adjust peripheral PLL to use the given divider and source.
- *
- * @param periph_id	peripheral to adjust
- * @param source	Source number (0-3 or 0-7)
- * @param mux_bits	Number of mux bits (2 or 4)
- * @param divider	Required divider in 7.1 or 15.1 format
- * @return 0 if ok, -1 on error (requesting a parent clock which is not valid
- *		for this peripheral)
- */
-static int adjust_periph_pll(enum periph_id periph_id, int source,
-			     int mux_bits, unsigned divider)
-{
-	u32 *reg = get_periph_source_reg(periph_id);
-
-	clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
-			divider << OUT_CLK_DIVISOR_SHIFT);
-	udelay(1);
-
-	/* work out the source clock and set it */
-	if (source < 0)
-		return -1;
-	if (mux_bits == 4) {
-		clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK,
-			source << OUT_CLK_SOURCE4_SHIFT);
-	} else {
-		clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
-			source << OUT_CLK_SOURCE_SHIFT);
-	}
-	udelay(2);
-	return 0;
-}
-
-unsigned clock_adjust_periph_pll_div(enum periph_id periph_id,
-		enum clock_id parent, unsigned rate, int *extra_div)
-{
-	unsigned effective_rate;
-	int mux_bits, divider_bits, source;
-	int divider;
-
-	/* work out the source clock and set it */
-	source = get_periph_clock_source(periph_id, parent, &mux_bits,
-					 &divider_bits);
-
-	if (extra_div)
-		divider = find_best_divider(divider_bits, pll_rate[parent],
-					    rate, extra_div);
-	else
-		divider = clk_get_divider(divider_bits, pll_rate[parent],
-					  rate);
-	assert(divider >= 0);
-	if (adjust_periph_pll(periph_id, source, mux_bits, divider))
-		return -1U;
-	debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
-		get_periph_source_reg(periph_id),
-		readl(get_periph_source_reg(periph_id)));
-
-	/* Check what we ended up with. This shouldn't matter though */
-	effective_rate = clock_get_periph_rate(periph_id, parent);
-	if (extra_div)
-		effective_rate /= *extra_div;
-	if (rate != effective_rate)
-		debug("Requested clock rate %u not honored (got %u)\n",
-		       rate, effective_rate);
-	return effective_rate;
-}
-
-unsigned clock_start_periph_pll(enum periph_id periph_id,
-		enum clock_id parent, unsigned rate)
-{
-	unsigned effective_rate;
-
-	reset_set_enable(periph_id, 1);
-	clock_enable(periph_id);
-
-	effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate,
-						 NULL);
-
-	reset_set_enable(periph_id, 0);
-	return effective_rate;
-}
-
-void clock_set_enable(enum periph_id periph_id, int enable)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
-	u32 reg;
-
-	/* Enable/disable the clock to this peripheral */
-	assert(clock_periph_id_isvalid(periph_id));
-	reg = readl(clk);
-	if (enable)
-		reg |= PERIPH_MASK(periph_id);
-	else
-		reg &= ~PERIPH_MASK(periph_id);
-	writel(reg, clk);
-}
-
-void clock_enable(enum periph_id clkid)
-{
-	clock_set_enable(clkid, 1);
-}
-
-void clock_disable(enum periph_id clkid)
-{
-	clock_set_enable(clkid, 0);
-}
-
-void reset_set_enable(enum periph_id periph_id, int enable)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
-	u32 reg;
-
-	/* Enable/disable reset to the peripheral */
-	assert(clock_periph_id_isvalid(periph_id));
-	reg = readl(reset);
-	if (enable)
-		reg |= PERIPH_MASK(periph_id);
-	else
-		reg &= ~PERIPH_MASK(periph_id);
-	writel(reg, reset);
-}
-
-void reset_periph(enum periph_id periph_id, int us_delay)
-{
-	/* Put peripheral into reset */
-	reset_set_enable(periph_id, 1);
-	udelay(us_delay);
-
-	/* Remove reset */
-	reset_set_enable(periph_id, 0);
-
-	udelay(us_delay);
-}
-
-void reset_cmplx_set_enable(int cpu, int which, int reset)
-{
-	struct clk_rst_ctlr *clkrst =
-			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
-	u32 mask;
-
-	/* Form the mask, which depends on the cpu chosen. Tegra2 has 2 */
-	assert(cpu >= 0 && cpu < 2);
-	mask = which << cpu;
-
-	/* either enable or disable those reset for that CPU */
-	if (reset)
-		writel(mask, &clkrst->crc_cpu_cmplx_set);
-	else
-		writel(mask, &clkrst->crc_cpu_cmplx_clr);
-}
-
-unsigned clock_get_rate(enum clock_id clkid)
-{
-	struct clk_pll *pll;
-	u32 base;
-	u32 divm;
-	u64 parent_rate;
-	u64 rate;
-
-	parent_rate = osc_freq[clock_get_osc_freq()];
-	if (clkid == CLOCK_ID_OSC)
-		return parent_rate;
-
-	pll = get_pll(clkid);
-	base = readl(&pll->pll_base);
-
-	/* Oh for bf_unpack()... */
-	rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT);
-	divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
-	if (clkid == CLOCK_ID_USB)
-		divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT;
-	else
-		divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
-	do_div(rate, divm);
-	return rate;
-}
-
-/**
- * Set the output frequency you want for each PLL clock.
- * PLL output frequencies are programmed by setting their N, M and P values.
- * The governing equations are:
- *     VCO = (Fi / m) * n, Fo = VCO / (2^p)
- *     where Fo is the output frequency from the PLL.
- * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
- *     216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
- * Please see Tegra TRM section 5.3 to get the detail for PLL Programming
- *
- * @param n PLL feedback divider(DIVN)
- * @param m PLL input divider(DIVN)
- * @param p post divider(DIVP)
- * @param cpcon base PLL charge pump(CPCON)
- * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
- *		be overriden), 1 if PLL is already correct
- */
-static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
-{
-	u32 base_reg;
-	u32 misc_reg;
-	struct clk_pll *pll;
-
-	pll = get_pll(clkid);
-
-	base_reg = readl(&pll->pll_base);
-
-	/* Set BYPASS, m, n and p to PLL_BASE */
-	base_reg &= ~PLL_DIVM_MASK;
-	base_reg |= m << PLL_DIVM_SHIFT;
-
-	base_reg &= ~PLL_DIVN_MASK;
-	base_reg |= n << PLL_DIVN_SHIFT;
-
-	base_reg &= ~PLL_DIVP_MASK;
-	base_reg |= p << PLL_DIVP_SHIFT;
-
-	if (clkid == CLOCK_ID_PERIPH) {
-		/*
-		 * If the PLL is already set up, check that it is correct
-		 * and record this info for clock_verify() to check.
-		 */
-		if (base_reg & PLL_BASE_OVRRIDE_MASK) {
-			base_reg |= PLL_ENABLE_MASK;
-			if (base_reg != readl(&pll->pll_base))
-				pllp_valid = 0;
-			return pllp_valid ? 1 : -1;
-		}
-		base_reg |= PLL_BASE_OVRRIDE_MASK;
-	}
-
-	base_reg |= PLL_BYPASS_MASK;
-	writel(base_reg, &pll->pll_base);
-
-	/* Set cpcon to PLL_MISC */
-	misc_reg = readl(&pll->pll_misc);
-	misc_reg &= ~PLL_CPCON_MASK;
-	misc_reg |= cpcon << PLL_CPCON_SHIFT;
-	writel(misc_reg, &pll->pll_misc);
-
-	/* Enable PLL */
-	base_reg |= PLL_ENABLE_MASK;
-	writel(base_reg, &pll->pll_base);
-
-	/* Disable BYPASS */
-	base_reg &= ~PLL_BYPASS_MASK;
-	writel(base_reg, &pll->pll_base);
-
-	return 0;
-}
-
-void clock_ll_start_uart(enum periph_id periph_id)
-{
-	/* Assert UART reset and enable clock */
-	reset_set_enable(periph_id, 1);
-	clock_enable(periph_id);
-	clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
-
-	/* wait for 2us */
-	udelay(2);
-
-	/* De-assert reset to UART */
-	reset_set_enable(periph_id, 0);
-}
-
-#ifdef CONFIG_OF_CONTROL
-/*
- * Convert a device tree clock ID to our peripheral ID. They are mostly
- * the same but we are very cautious so we check that a valid clock ID is
- * provided.
- *
- * @param clk_id	Clock ID according to tegra2 device tree binding
- * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
- */
-static enum periph_id clk_id_to_periph_id(int clk_id)
-{
-	if (clk_id > 95)
-		return PERIPH_ID_NONE;
-
-	switch (clk_id) {
-	case 1:
-	case 2:
-	case 7:
-	case 10:
-	case 20:
-	case 30:
-	case 35:
-	case 49:
-	case 56:
-	case 74:
-	case 76:
-	case 77:
-	case 78:
-	case 79:
-	case 80:
-	case 81:
-	case 82:
-	case 83:
-	case 91:
-	case 95:
-		return PERIPH_ID_NONE;
-	default:
-		return clk_id;
-	}
-}
-
-int clock_decode_periph_id(const void *blob, int node)
-{
-	enum periph_id id;
-	u32 cell[2];
-	int err;
-
-	err = fdtdec_get_int_array(blob, node, "clocks", cell,
-				   ARRAY_SIZE(cell));
-	if (err)
-		return -1;
-	id = clk_id_to_periph_id(cell[1]);
-	assert(clock_periph_id_isvalid(id));
-	return id;
-}
-#endif /* CONFIG_OF_CONTROL */
-
-int clock_verify(void)
-{
-	struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
-	u32 reg = readl(&pll->pll_base);
-
-	if (!pllp_valid) {
-		printf("Warning: PLLP %x is not correct\n", reg);
-		return -1;
-	}
-	debug("PLLX %x is correct\n", reg);
-	return 0;
-}
-
-void clock_early_init(void)
-{
-	/*
-	 * PLLP output frequency set to 216MHz
-	 * PLLC output frequency set to 600Mhz
-	 *
-	 * TODO: Can we calculate these values instead of hard-coding?
-	 */
-	switch (clock_get_osc_freq()) {
-	case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
-		clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8);
-		clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
-		break;
-
-	case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
-		clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8);
-		clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
-		break;
-
-	case CLOCK_OSC_FREQ_13_0:
-	case CLOCK_OSC_FREQ_19_2:
-	default:
-		/*
-		 * These are not supported. It is too early to print a
-		 * message and the UART likely won't work anyway due to the
-		 * oscillator being wrong.
-		 */
-		break;
-	}
-}
-
-void clock_init(void)
-{
-	pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY);
-	pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH);
-	pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL);
-	pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
-	pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
-	debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
-	debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
-	debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
-}
diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c
deleted file mode 100644
index c1d2dfe..0000000
--- a/arch/arm/cpu/armv7/tegra2/funcmux.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- * 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
- */
-
-/* Tegra2 high-level function multiplexing */
-#include <common.h>
-#include <asm/arch/clock.h>
-#include <asm/arch/funcmux.h>
-#include <asm/arch/pinmux.h>
-
-int funcmux_select(enum periph_id id, int config)
-{
-	int bad_config = config != FUNCMUX_DEFAULT;
-
-	switch (id) {
-	case PERIPH_ID_UART1:
-		if (config == FUNCMUX_UART1_IRRX_IRTX) {
-			pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA);
-			pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA);
-			pinmux_tristate_disable(PINGRP_IRRX);
-			pinmux_tristate_disable(PINGRP_IRTX);
-			/*
-			 * Tegra appears to boot with function UARTA pre-
-			 * selected on mux group SDB. If two mux groups are
-			 * both set to the same function, it's unclear which
-			 * group's pins drive the RX signals into the HW.
-			 * For UARTA, SDB certainly overrides group IRTX in
-			 * practice. To solve this, configure some alternative
-			 * function on SDB to avoid the conflict. Also, tri-
-			 * state the group to avoid driving any signal onto it
-			 * until we know what's connected.
-			 */
-			pinmux_tristate_enable(PINGRP_SDB);
-			pinmux_set_func(PINGRP_SDB,  PMUX_FUNC_SDIO3);
-		}
-		break;
-
-	case PERIPH_ID_UART2:
-		if (config == FUNCMUX_UART2_IRDA) {
-			pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA);
-			pinmux_tristate_disable(PINGRP_UAD);
-		}
-		break;
-
-	case PERIPH_ID_UART4:
-		if (config == FUNCMUX_UART4_GMC) {
-			pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD);
-			pinmux_tristate_disable(PINGRP_GMC);
-		}
-		break;
-
-	case PERIPH_ID_DVC_I2C:
-		/* there is only one selection, pinmux_config is ignored */
-		if (config == FUNCMUX_DVC_I2CP) {
-			pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C);
-			pinmux_tristate_disable(PINGRP_I2CP);
-		}
-		break;
-
-	case PERIPH_ID_I2C1:
-		/* support pinmux_config of 0 for now, */
-		if (config == FUNCMUX_I2C1_RM) {
-			pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C);
-			pinmux_tristate_disable(PINGRP_RM);
-		}
-		break;
-	case PERIPH_ID_I2C2: /* I2C2 */
-		switch (config) {
-		case FUNCMUX_I2C2_DDC:	/* DDC pin group, select I2C2 */
-			pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2);
-			/* PTA to HDMI */
-			pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI);
-			pinmux_tristate_disable(PINGRP_DDC);
-			break;
-		case FUNCMUX_I2C2_PTA:	/* PTA pin group, select I2C2 */
-			pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2);
-			/* set DDC_SEL to RSVDx (RSVD2 works for now) */
-			pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2);
-			pinmux_tristate_disable(PINGRP_PTA);
-			bad_config = 0;
-			break;
-		}
-		break;
-	case PERIPH_ID_I2C3: /* I2C3 */
-		/* support pinmux_config of 0 for now */
-		if (config == FUNCMUX_I2C3_DTF) {
-			pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3);
-			pinmux_tristate_disable(PINGRP_DTF);
-		}
-		break;
-
-	case PERIPH_ID_SDMMC2:
-		if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) {
-			pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2);
-			pinmux_set_func(PINGRP_DTD, PMUX_FUNC_SDIO2);
-
-			pinmux_tristate_disable(PINGRP_DTA);
-			pinmux_tristate_disable(PINGRP_DTD);
-		}
-		break;
-
-	case PERIPH_ID_SDMMC3:
-		switch (config) {
-		case FUNCMUX_SDMMC3_SDB_SLXA_8BIT:
-			pinmux_set_func(PINGRP_SLXA, PMUX_FUNC_SDIO3);
-			pinmux_set_func(PINGRP_SLXC, PMUX_FUNC_SDIO3);
-			pinmux_set_func(PINGRP_SLXD, PMUX_FUNC_SDIO3);
-			pinmux_set_func(PINGRP_SLXK, PMUX_FUNC_SDIO3);
-
-			pinmux_tristate_disable(PINGRP_SLXA);
-			pinmux_tristate_disable(PINGRP_SLXC);
-			pinmux_tristate_disable(PINGRP_SLXD);
-			pinmux_tristate_disable(PINGRP_SLXK);
-			/* fall through */
-
-		case FUNCMUX_SDMMC3_SDB_4BIT:
-			pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3);
-			pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3);
-			pinmux_set_func(PINGRP_SDD, PMUX_FUNC_SDIO3);
-
-			pinmux_tristate_disable(PINGRP_SDB);
-			pinmux_tristate_disable(PINGRP_SDC);
-			pinmux_tristate_disable(PINGRP_SDD);
-			bad_config = 0;
-			break;
-		}
-		break;
-
-	case PERIPH_ID_SDMMC4:
-		switch (config) {
-		case FUNCMUX_SDMMC4_ATC_ATD_8BIT:
-			pinmux_set_func(PINGRP_ATC, PMUX_FUNC_SDIO4);
-			pinmux_set_func(PINGRP_ATD, PMUX_FUNC_SDIO4);
-
-			pinmux_tristate_disable(PINGRP_ATC);
-			pinmux_tristate_disable(PINGRP_ATD);
-			break;
-
-		case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT:
-			pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4);
-			pinmux_tristate_disable(PINGRP_GME);
-			/* fall through */
-
-		case FUNCMUX_SDMMC4_ATB_GMA_4_BIT:
-			pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4);
-			pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4);
-
-			pinmux_tristate_disable(PINGRP_ATB);
-			pinmux_tristate_disable(PINGRP_GMA);
-			bad_config = 0;
-			break;
-		}
-		break;
-
-	default:
-		debug("%s: invalid periph_id %d", __func__, id);
-		return -1;
-	}
-
-	if (bad_config) {
-		debug("%s: invalid config %d for periph_id %d", __func__,
-		      config, id);
-		return -1;
-	}
-
-	return 0;
-}
diff --git a/arch/arm/cpu/armv7/tegra2/lowlevel_init.S b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S
deleted file mode 100644
index 6b86647..0000000
--- a/arch/arm/cpu/armv7/tegra2/lowlevel_init.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * SoC-specific setup info
- *
- * (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 <config.h>
-#include <version.h>
-
-	.align	5
-.global reset_cpu
-reset_cpu:
-	ldr	r1, rstctl			@ get addr for global reset
-						@ reg
-	ldr	r3, [r1]
-	orr	r3, r3, #0x10
-	str	r3, [r1]			@ force reset
-	mov	r0, r0
-_loop_forever:
-	b	_loop_forever
-rstctl:
-	.word	PRM_RSTCTRL
diff --git a/arch/arm/cpu/armv7/tegra2/pinmux.c b/arch/arm/cpu/armv7/tegra2/pinmux.c
deleted file mode 100644
index b053f90..0000000
--- a/arch/arm/cpu/armv7/tegra2/pinmux.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- * 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
- */
-
-/* Tegra2 pin multiplexing functions */
-
-#include <asm/io.h>
-#include <asm/arch/tegra2.h>
-#include <asm/arch/pinmux.h>
-#include <common.h>
-
-
-/*
- * This defines the order of the pin mux control bits in the registers. For
- * some reason there is no correspendence between the tristate, pin mux and
- * pullup/pulldown registers.
- */
-enum pmux_ctlid {
-	/* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */
-	MUXCTL_UAA,
-	MUXCTL_UAB,
-	MUXCTL_UAC,
-	MUXCTL_UAD,
-	MUXCTL_UDA,
-	MUXCTL_RESERVED5,
-	MUXCTL_ATE,
-	MUXCTL_RM,
-
-	MUXCTL_ATB,
-	MUXCTL_RESERVED9,
-	MUXCTL_ATD,
-	MUXCTL_ATC,
-	MUXCTL_ATA,
-	MUXCTL_KBCF,
-	MUXCTL_KBCE,
-	MUXCTL_SDMMC1,
-
-	/* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */
-	MUXCTL_GMA,
-	MUXCTL_GMC,
-	MUXCTL_HDINT,
-	MUXCTL_SLXA,
-	MUXCTL_OWC,
-	MUXCTL_SLXC,
-	MUXCTL_SLXD,
-	MUXCTL_SLXK,
-
-	MUXCTL_UCA,
-	MUXCTL_UCB,
-	MUXCTL_DTA,
-	MUXCTL_DTB,
-	MUXCTL_RESERVED28,
-	MUXCTL_DTC,
-	MUXCTL_DTD,
-	MUXCTL_DTE,
-
-	/* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */
-	MUXCTL_DDC,
-	MUXCTL_CDEV1,
-	MUXCTL_CDEV2,
-	MUXCTL_CSUS,
-	MUXCTL_I2CP,
-	MUXCTL_KBCA,
-	MUXCTL_KBCB,
-	MUXCTL_KBCC,
-
-	MUXCTL_IRTX,
-	MUXCTL_IRRX,
-	MUXCTL_DAP1,
-	MUXCTL_DAP2,
-	MUXCTL_DAP3,
-	MUXCTL_DAP4,
-	MUXCTL_GMB,
-	MUXCTL_GMD,
-
-	/* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */
-	MUXCTL_GME,
-	MUXCTL_GPV,
-	MUXCTL_GPU,
-	MUXCTL_SPDO,
-	MUXCTL_SPDI,
-	MUXCTL_SDB,
-	MUXCTL_SDC,
-	MUXCTL_SDD,
-
-	MUXCTL_SPIH,
-	MUXCTL_SPIG,
-	MUXCTL_SPIF,
-	MUXCTL_SPIE,
-	MUXCTL_SPID,
-	MUXCTL_SPIC,
-	MUXCTL_SPIB,
-	MUXCTL_SPIA,
-
-	/* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */
-	MUXCTL_LPW0,
-	MUXCTL_LPW1,
-	MUXCTL_LPW2,
-	MUXCTL_LSDI,
-	MUXCTL_LSDA,
-	MUXCTL_LSPI,
-	MUXCTL_LCSN,
-	MUXCTL_LDC,
-
-	MUXCTL_LSCK,
-	MUXCTL_LSC0,
-	MUXCTL_LSC1,
-	MUXCTL_LHS,
-	MUXCTL_LVS,
-	MUXCTL_LM0,
-	MUXCTL_LM1,
-	MUXCTL_LVP0,
-
-	/* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */
-	MUXCTL_LD0,
-	MUXCTL_LD1,
-	MUXCTL_LD2,
-	MUXCTL_LD3,
-	MUXCTL_LD4,
-	MUXCTL_LD5,
-	MUXCTL_LD6,
-	MUXCTL_LD7,
-
-	MUXCTL_LD8,
-	MUXCTL_LD9,
-	MUXCTL_LD10,
-	MUXCTL_LD11,
-	MUXCTL_LD12,
-	MUXCTL_LD13,
-	MUXCTL_LD14,
-	MUXCTL_LD15,
-
-	/* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */
-	MUXCTL_LD16,
-	MUXCTL_LD17,
-	MUXCTL_LHP1,
-	MUXCTL_LHP2,
-	MUXCTL_LVP1,
-	MUXCTL_LHP0,
-	MUXCTL_RESERVED102,
-	MUXCTL_LPP,
-
-	MUXCTL_LDI,
-	MUXCTL_PMC,
-	MUXCTL_CRTP,
-	MUXCTL_PTA,
-	MUXCTL_RESERVED108,
-	MUXCTL_KBCD,
-	MUXCTL_GPU7,
-	MUXCTL_DTF,
-
-	MUXCTL_NONE = -1,
-};
-
-/*
- * And this defines the order of the pullup/pulldown controls which are again
- * in a different order
- */
-enum pmux_pullid {
-	/* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */
-	PUCTL_ATA,
-	PUCTL_ATB,
-	PUCTL_ATC,
-	PUCTL_ATD,
-	PUCTL_ATE,
-	PUCTL_DAP1,
-	PUCTL_DAP2,
-	PUCTL_DAP3,
-
-	PUCTL_DAP4,
-	PUCTL_DTA,
-	PUCTL_DTB,
-	PUCTL_DTC,
-	PUCTL_DTD,
-	PUCTL_DTE,
-	PUCTL_DTF,
-	PUCTL_GPV,
-
-	/* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */
-	PUCTL_RM,
-	PUCTL_I2CP,
-	PUCTL_PTA,
-	PUCTL_GPU7,
-	PUCTL_KBCA,
-	PUCTL_KBCB,
-	PUCTL_KBCC,
-	PUCTL_KBCD,
-
-	PUCTL_SPDI,
-	PUCTL_SPDO,
-	PUCTL_GPSLXAU,
-	PUCTL_CRTP,
-	PUCTL_SLXC,
-	PUCTL_SLXD,
-	PUCTL_SLXK,
-
-	/* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */
-	PUCTL_CDEV1,
-	PUCTL_CDEV2,
-	PUCTL_SPIA,
-	PUCTL_SPIB,
-	PUCTL_SPIC,
-	PUCTL_SPID,
-	PUCTL_SPIE,
-	PUCTL_SPIF,
-
-	PUCTL_SPIG,
-	PUCTL_SPIH,
-	PUCTL_IRTX,
-	PUCTL_IRRX,
-	PUCTL_GME,
-	PUCTL_RESERVED45,
-	PUCTL_XM2D,
-	PUCTL_XM2C,
-
-	/* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */
-	PUCTL_UAA,
-	PUCTL_UAB,
-	PUCTL_UAC,
-	PUCTL_UAD,
-	PUCTL_UCA,
-	PUCTL_UCB,
-	PUCTL_LD17,
-	PUCTL_LD19_18,
-
-	PUCTL_LD21_20,
-	PUCTL_LD23_22,
-	PUCTL_LS,
-	PUCTL_LC,
-	PUCTL_CSUS,
-	PUCTL_DDRC,
-	PUCTL_SDC,
-	PUCTL_SDD,
-
-	/* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */
-	PUCTL_KBCF,
-	PUCTL_KBCE,
-	PUCTL_PMCA,
-	PUCTL_PMCB,
-	PUCTL_PMCC,
-	PUCTL_PMCD,
-	PUCTL_PMCE,
-	PUCTL_CK32,
-
-	PUCTL_UDA,
-	PUCTL_SDMMC1,
-	PUCTL_GMA,
-	PUCTL_GMB,
-	PUCTL_GMC,
-	PUCTL_GMD,
-	PUCTL_DDC,
-	PUCTL_OWC,
-
-	PUCTL_NONE = -1
-};
-
-struct tegra_pingroup_desc {
-	const char *name;
-	enum pmux_func funcs[4];
-	enum pmux_func func_safe;
-	enum pmux_vddio vddio;
-	enum pmux_ctlid ctl_id;
-	enum pmux_pullid pull_id;
-};
-
-
-/* Converts a pmux_pingrp number to a tristate register: 0=A, 1=B, 2=C, 3=D */
-#define TRISTATE_REG(pmux_pingrp) ((pmux_pingrp) >> 5)
-
-/* Mask value for a tristate (within TRISTATE_REG(id)) */
-#define TRISTATE_MASK(pmux_pingrp) (1 << ((pmux_pingrp) & 0x1f))
-
-/* Converts a PUCTL id to a pull register: 0=A, 1=B...4=E */
-#define PULL_REG(pmux_pullid) ((pmux_pullid) >> 4)
-
-/* Converts a PUCTL id to a shift position */
-#define PULL_SHIFT(pmux_pullid) ((pmux_pullid << 1) & 0x1f)
-
-/* Converts a MUXCTL id to a ctl register: 0=A, 1=B...6=G */
-#define MUXCTL_REG(pmux_ctlid) ((pmux_ctlid) >> 4)
-
-/* Converts a MUXCTL id to a shift position */
-#define MUXCTL_SHIFT(pmux_ctlid) ((pmux_ctlid << 1) & 0x1f)
-
-/* Convenient macro for defining pin group properties */
-#define PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, mux, pupd)		\
-	{						\
-		.vddio = PMUX_VDDIO_ ## vdd,		\
-		.funcs = {				\
-			PMUX_FUNC_ ## f0,			\
-			PMUX_FUNC_ ## f1,			\
-			PMUX_FUNC_ ## f2,			\
-			PMUX_FUNC_ ## f3,			\
-		},					\
-		.func_safe = PMUX_FUNC_ ## f_safe,		\
-		.ctl_id = mux,				\
-		.pull_id = pupd				\
-	}
-
-/* A normal pin group where the mux name and pull-up name match */
-#define PIN(pg_name, vdd, f0, f1, f2, f3, f_safe)		\
-		PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe,	\
-			MUXCTL_ ## pg_name, PUCTL_ ## pg_name)
-
-/* A pin group where the pull-up name doesn't have a 1-1 mapping */
-#define PINP(pg_name, vdd, f0, f1, f2, f3, f_safe, pupd)		\
-		PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe,	\
-			MUXCTL_ ## pg_name, PUCTL_ ## pupd)
-
-/* A pin group number which is not used */
-#define PIN_RESERVED \
-	PIN(NONE, NONE, NONE, NONE, NONE, NONE, NONE)
-
-const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
-	PIN(ATA,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
-	PIN(ATB,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
-	PIN(ATC,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
-	PIN(ATD,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
-	PIN(CDEV1, AUDIO, OSC,   PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC),
-	PIN(CDEV2, AUDIO, OSC,   AHB_CLK, APB_CLK, PLLP_OUT4,    OSC),
-	PIN(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK,
-		PLLC_OUT1),
-	PIN(DAP1, AUDIO, DAP1,   RSVD,   GMI,       SDIO2,       DAP1),
-
-	PIN(DAP2, AUDIO, DAP2,   TWC,    RSVD,      GMI,         DAP2),
-	PIN(DAP3, BB,    DAP3,   RSVD,   RSVD,      RSVD,        DAP3),
-	PIN(DAP4, UART,  DAP4,   RSVD,   GMI,       RSVD,        DAP4),
-	PIN(DTA,  VI,    RSVD,   SDIO2,  VI,        RSVD,        RSVD4),
-	PIN(DTB,  VI,    RSVD,   RSVD,   VI,        SPI1,        RSVD1),
-	PIN(DTC,  VI,    RSVD,   RSVD,   VI,        RSVD,        RSVD1),
-	PIN(DTD,  VI,    RSVD,   SDIO2,  VI,        RSVD,        RSVD1),
-	PIN(DTE,  VI,    RSVD,   RSVD,   VI,        SPI1,        RSVD1),
-
-	PINP(GPU, UART,  PWM,    UARTA,  GMI,       RSVD,        RSVD4,
-		GPSLXAU),
-	PIN(GPV,  SD,    PCIE,   RSVD,   RSVD,      RSVD,        PCIE),
-	PIN(I2CP, SYS,   I2C,    RSVD,   RSVD,      RSVD,        RSVD4),
-	PIN(IRTX, UART,  UARTA,  UARTB,  GMI,       SPI4,        UARTB),
-	PIN(IRRX, UART,  UARTA,  UARTB,  GMI,       SPI4,        UARTB),
-	PIN(KBCB, SYS,   KBC,    NAND,   SDIO2,     MIO,         KBC),
-	PIN(KBCA, SYS,   KBC,    NAND,   SDIO2,     EMC_TEST0_DLL, KBC),
-	PINP(PMC, SYS,   PWR_ON, PWR_INTR, RSVD,    RSVD,        PWR_ON, NONE),
-
-	PIN(PTA,  NAND,  I2C2,   HDMI,   GMI,       RSVD,        RSVD4),
-	PIN(RM,   UART,  I2C,    RSVD,   RSVD,      RSVD,        RSVD4),
-	PIN(KBCE, SYS,   KBC,    NAND,   OWR,       RSVD,        KBC),
-	PIN(KBCF, SYS,   KBC,    NAND,   TRACE,     MIO,         KBC),
-	PIN(GMA,  NAND,  UARTE,  SPI3,   GMI,       SDIO4,       SPI3),
-	PIN(GMC,  NAND,  UARTD,  SPI4,   GMI,       SFLASH,      SPI4),
-	PIN(SDMMC1, BB,  SDIO1,  RSVD,   UARTE,     UARTA,       RSVD2),
-	PIN(OWC,  SYS,   OWR,    RSVD,   RSVD,      RSVD,        OWR),
-
-	PIN(GME,  NAND,  RSVD,   DAP5,   GMI,       SDIO4,       GMI),
-	PIN(SDC,  SD,    PWM,    TWC,    SDIO3,     SPI3,        TWC),
-	PIN(SDD,  SD,    UARTA,  PWM,    SDIO3,     SPI3,        PWM),
-	PIN_RESERVED,
-	PINP(SLXA, SD,   PCIE,   SPI4,   SDIO3,     SPI2,        PCIE, CRTP),
-	PIN(SLXC, SD,    SPDIF,  SPI4,   SDIO3,     SPI2,        SPI4),
-	PIN(SLXD, SD,    SPDIF,  SPI4,   SDIO3,     SPI2,        SPI4),
-	PIN(SLXK, SD,    PCIE,   SPI4,   SDIO3,     SPI2,        PCIE),
-
-	PIN(SPDI, AUDIO, SPDIF,  RSVD,   I2C,       SDIO2,       RSVD2),
-	PIN(SPDO, AUDIO, SPDIF,  RSVD,   I2C,       SDIO2,       RSVD2),
-	PIN(SPIA, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
-	PIN(SPIB, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
-	PIN(SPIC, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
-	PIN(SPID, AUDIO, SPI2,   SPI1,   SPI2_ALT,  GMI,         GMI),
-	PIN(SPIE, AUDIO, SPI2,   SPI1,   SPI2_ALT,  GMI,         GMI),
-	PIN(SPIF, AUDIO, SPI3,   SPI1,   SPI2,      RSVD,        RSVD4),
-
-	PIN(SPIG, AUDIO, SPI3,   SPI2,   SPI2_ALT,  I2C,         SPI2_ALT),
-	PIN(SPIH, AUDIO, SPI3,   SPI2,   SPI2_ALT,  I2C,         SPI2_ALT),
-	PIN(UAA,  BB,    SPI3,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
-	PIN(UAB,  BB,    SPI2,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
-	PIN(UAC,  BB,    OWR,    RSVD,   RSVD,      RSVD,        RSVD4),
-	PIN(UAD,  UART,  IRDA,   SPDIF,  UARTA,     SPI4,        SPDIF),
-	PIN(UCA,  UART,  UARTC,  RSVD,   GMI,       RSVD,        RSVD4),
-	PIN(UCB,  UART,  UARTC,  PWM,    GMI,       RSVD,        RSVD4),
-
-	PIN_RESERVED,
-	PIN(ATE,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
-	PIN(KBCC, SYS,   KBC,    NAND,   TRACE,     EMC_TEST1_DLL, KBC),
-	PIN_RESERVED,
-	PIN_RESERVED,
-	PIN(GMB,  NAND,  IDE,    NAND,   GMI,       GMI_INT,     GMI),
-	PIN(GMD,  NAND,  RSVD,   NAND,   GMI,       SFLASH,      GMI),
-	PIN(DDC,  LCD,   I2C2,   RSVD,   RSVD,      RSVD,        RSVD4),
-
-	/* 64 */
-	PINP(LD0,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD1,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD2,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD3,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD4,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD5,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD6,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD7,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-
-	PINP(LD8,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD9,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD10, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD11, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD12, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD13, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD14, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD15, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-
-	PINP(LD16, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
-	PINP(LD17, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD17),
-	PINP(LHP0, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD21_20),
-	PINP(LHP1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD19_18),
-	PINP(LHP2, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD19_18),
-	PINP(LVP0, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LC),
-	PINP(LVP1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD21_20),
-	PINP(HDINT, LCD, HDMI,   RSVD,   RSVD,      RSVD,     HDMI , LC),
-
-	PINP(LM0,  LCD,  DISPA,  DISPB,  SPI3,      RSVD,     RSVD4, LC),
-	PINP(LM1,  LCD,  DISPA,  DISPB,  RSVD,      CRT,      RSVD3, LC),
-	PINP(LVS,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
-	PINP(LSC0, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
-	PINP(LSC1, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
-	PINP(LSCK, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
-	PINP(LDC,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LS),
-	PINP(LCSN, LCD,  DISPA,  DISPB,  SPI3,      RSVD,     RSVD4, LS),
-
-	/* 96 */
-	PINP(LSPI, LCD,  DISPA,  DISPB,  XIO,       HDMI,     DISPA, LC),
-	PINP(LSDA, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
-	PINP(LSDI, LCD,  DISPA,  DISPB,  SPI3,      RSVD,     DISPA, LS),
-	PINP(LPW0, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
-	PINP(LPW1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LS),
-	PINP(LPW2, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
-	PINP(LDI,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD23_22),
-	PINP(LHS,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
-
-	PINP(LPP,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD23_22),
-	PIN_RESERVED,
-	PIN(KBCD,  SYS,  KBC,    NAND,   SDIO2,     MIO,      KBC),
-	PIN(GPU7,  SYS,  RTCK,   RSVD,   RSVD,      RSVD,     RTCK),
-	PIN(DTF,   VI,   I2C3,   RSVD,   VI,        RSVD,     RSVD4),
-	PIN(UDA,   BB,   SPI1,   RSVD,   UARTD,     ULPI,     RSVD2),
-	PIN(CRTP,  LCD,  CRT,    RSVD,   RSVD,      RSVD,     RSVD),
-	PINP(SDB,  SD,   UARTA,  PWM,    SDIO3,     SPI2,     PWM,   NONE),
-
-	/* these pin groups only have pullup and pull down control */
-	PINALL(CK32,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(DDRC,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(PMCA,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(PMCB,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(PMCC,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(PMCD,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(PMCE,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(XM2C,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-	PINALL(XM2D,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
-		PUCTL_NONE),
-};
-
-void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	u32 *tri = &pmt->pmt_tri[TRISTATE_REG(pin)];
-	u32 reg;
-
-	reg = readl(tri);
-	if (enable)
-		reg |= TRISTATE_MASK(pin);
-	else
-		reg &= ~TRISTATE_MASK(pin);
-	writel(reg, tri);
-}
-
-void pinmux_tristate_enable(enum pmux_pingrp pin)
-{
-	pinmux_set_tristate(pin, 1);
-}
-
-void pinmux_tristate_disable(enum pmux_pingrp pin)
-{
-	pinmux_set_tristate(pin, 0);
-}
-
-void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	enum pmux_pullid pull_id = tegra_soc_pingroups[pin].pull_id;
-	u32 *pull = &pmt->pmt_pull[PULL_REG(pull_id)];
-	u32 mask_bit;
-	u32 reg;
-	mask_bit = PULL_SHIFT(pull_id);
-
-	reg = readl(pull);
-	reg &= ~(0x3 << mask_bit);
-	reg |= pupd << mask_bit;
-	writel(reg, pull);
-}
-
-void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
-{
-	struct pmux_tri_ctlr *pmt =
-			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
-	enum pmux_ctlid mux_id = tegra_soc_pingroups[pin].ctl_id;
-	u32 *muxctl = &pmt->pmt_ctl[MUXCTL_REG(mux_id)];
-	u32 mask_bit;
-	int i, mux = -1;
-	u32 reg;
-
-	assert(pmux_func_isvalid(func));
-
-	/* Handle special values */
-	if (func >= PMUX_FUNC_RSVD1) {
-		mux = (func - PMUX_FUNC_RSVD1) & 0x3;
-	} else {
-		/* Search for the appropriate function */
-		for (i = 0; i < 4; i++) {
-			if (tegra_soc_pingroups[pin].funcs[i] == func) {
-				mux = i;
-				break;
-			}
-		}
-	}
-	assert(mux != -1);
-
-	mask_bit = MUXCTL_SHIFT(mux_id);
-	reg = readl(muxctl);
-	reg &= ~(0x3 << mask_bit);
-	reg |= mux << mask_bit;
-	writel(reg, muxctl);
-}
-
-void pinmux_config_pingroup(struct pingroup_config *config)
-{
-	enum pmux_pingrp pin = config->pingroup;
-
-	pinmux_set_func(pin, config->func);
-	pinmux_set_pullupdown(pin, config->pull);
-	pinmux_set_tristate(pin, config->tristate);
-}
-
-void pinmux_config_table(struct pingroup_config *config, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		pinmux_config_pingroup(&config[i]);
-}
diff --git a/arch/arm/cpu/armv7/tegra2/sys_info.c b/arch/arm/cpu/armv7/tegra2/sys_info.c
deleted file mode 100644
index 6d11dc1..0000000
--- a/arch/arm/cpu/armv7/tegra2/sys_info.c
+++ /dev/null
@@ -1,35 +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 <common.h>
-
-#ifdef CONFIG_DISPLAY_CPUINFO
-/* Print CPU information */
-int print_cpuinfo(void)
-{
-	puts("TEGRA2\n");
-
-	/* TBD: Add printf of major/minor rev info, stepping, etc. */
-	return 0;
-}
-#endif	/* CONFIG_DISPLAY_CPUINFO */
diff --git a/arch/arm/cpu/armv7/tegra2/timer.c b/arch/arm/cpu/armv7/tegra2/timer.c
deleted file mode 100644
index b12b12c..0000000
--- a/arch/arm/cpu/armv7/tegra2/timer.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * (C) Copyright 2010,2011
- * NVIDIA Corporation <www.nvidia.com>
- *
- * (C) Copyright 2008
- * Texas Instruments
- *
- * Richard Woodruff <r-woodruff2 at ti.com>
- * Syed Moahmmed Khasim <khasim at ti.com>
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger at sysgo.de>
- * Alex Zuepke <azu at sysgo.de>
- *
- * (C) Copyright 2002
- * Gary Jennejohn, DENX Software Engineering, <garyj at 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 <common.h>
-#include <asm/io.h>
-#include <asm/arch/tegra2.h>
-#include <asm/arch/timer.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/* counter runs at 1MHz */
-#define TIMER_CLK	1000000
-#define TIMER_LOAD_VAL	0xffffffff
-
-/* timer without interrupts */
-ulong get_timer(ulong base)
-{
-	return get_timer_masked() - base;
-}
-
-/* delay x useconds */
-void __udelay(unsigned long usec)
-{
-	long tmo = usec * (TIMER_CLK / 1000) / 1000;
-	unsigned long now, last = timer_get_us();
-
-	while (tmo > 0) {
-		now = timer_get_us();
-		if (last > now) /* count up timer overflow */
-			tmo -= TIMER_LOAD_VAL - last + now;
-		else
-			tmo -= now - last;
-		last = now;
-	}
-}
-
-ulong get_timer_masked(void)
-{
-	ulong now;
-
-	/* current tick value */
-	now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ);
-
-	if (now >= gd->lastinc)	/* normal mode (non roll) */
-		/* move stamp forward with absolute diff ticks */
-		gd->tbl += (now - gd->lastinc);
-	else	/* we have rollover of incrementer */
-		gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ))
-				- gd->lastinc) + now;
-	gd->lastinc = now;
-	return gd->tbl;
-}
-
-/*
- * This function is derived from PowerPC code (read timebase as long long).
- * On ARM it just returns the timer value.
- */
-unsigned long long get_ticks(void)
-{
-	return get_timer(0);
-}
-
-/*
- * This function is derived from PowerPC code (timebase clock frequency).
- * On ARM it returns the number of timer ticks per second.
- */
-ulong get_tbclk(void)
-{
-	return CONFIG_SYS_HZ;
-}
-
-unsigned long timer_get_us(void)
-{
-	struct timerus *timer_base = (struct timerus *)NV_PA_TMRUS_BASE;
-
-	return readl(&timer_base->cntr_1us);
-}
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 at 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/tegra2-common/ap20.c b/arch/arm/cpu/tegra2-common/ap20.c
new file mode 100644
index 0000000..b749821
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/ap20.c
@@ -0,0 +1,324 @@
+/*
+* (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/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)
+{
+	struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE;
+	u32 reg;
+
+	/* If SCU already setup/enabled, return */
+	if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE)
+		return;
+
+	/* Invalidate all ways for all processors */
+	writel(0xFFFF, &scu->scu_inv_all);
+
+	/* Enable SCU - bit 0 */
+	reg = readl(&scu->scu_ctrl);
+	reg |= SCU_CTRL_ENABLE;
+	writel(reg, &scu->scu_ctrl);
+}
+
+void init_pmc_scratch(void)
+{
+	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
+	int i;
+
+	/* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */
+	for (i = 0; i < 23; i++)
+		writel(0, &pmc->pmc_scratch1+i);
+
+	/* ODMDATA is for kernel use to determine RAM size, LP config, etc. */
+	writel(CONFIG_SYS_BOARD_ODMDATA, &pmc->pmc_scratch20);
+}
+
+void tegra2_start(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();
+
+	enable_scu();
+
+	/* enable SMP mode and FW for CPU0, by writing to Auxiliary Ctl reg */
+	asm volatile(
+		"mrc	p15, 0, r0, c1, c0, 1\n"
+		"orr	r0, r0, #0x41\n"
+		"mcr	p15, 0, r0, c1, c0, 1\n");
+
+	/* FIXME: should have ap20's L2 disabled too? */
+}
diff --git a/arch/arm/cpu/tegra2-common/ap20.h b/arch/arm/cpu/tegra2-common/ap20.h
new file mode 100644
index 0000000..a4b4d73
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/ap20.h
@@ -0,0 +1,102 @@
+/*
+ * (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
new file mode 100644
index 0000000..a797e6f
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/board.c
@@ -0,0 +1,151 @@
+/*
+ *  (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 <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>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/pmc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+	/* UARTs which we can enable */
+	UARTA	= 1 << 0,
+	UARTB	= 1 << 1,
+	UARTD	= 1 << 3,
+	UART_COUNT = 4,
+};
+
+/*
+ * Boot ROM initializes the odmdata in APBDEV_PMC_SCRATCH20_0,
+ * so we are using this value to identify memory size.
+ */
+
+unsigned int query_sdram_size(void)
+{
+	struct pmc_ctlr *const pmc = (struct pmc_ctlr *)TEGRA2_PMC_BASE;
+	u32 reg;
+
+	reg = readl(&pmc->pmc_scratch20);
+	debug("pmc->pmc_scratch20 (ODMData) = 0x%08x\n", reg);
+
+	/* bits 31:28 in OdmData are used for RAM size  */
+	switch ((reg) >> 28) {
+	case 1:
+		return 0x10000000;	/* 256 MB */
+	case 2:
+	default:
+		return 0x20000000;	/* 512 MB */
+	case 3:
+		return 0x40000000;	/* 1GB */
+	}
+}
+
+int dram_init(void)
+{
+	/* We do not initialise DRAM here. We just query the size */
+	gd->ram_size = query_sdram_size();
+	return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+	printf("Board: %s\n", sysinfo.board_string);
+	return 0;
+}
+#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
+ *
+ * @param uarts_ids	Mask containing UARTs to init (UARTx)
+ */
+static void setup_uarts(int uart_ids)
+{
+	static enum periph_id id_for_uart[] = {
+		PERIPH_ID_UART1,
+		PERIPH_ID_UART2,
+		PERIPH_ID_UART3,
+		PERIPH_ID_UART4,
+	};
+	size_t i;
+
+	for (i = 0; i < UART_COUNT; i++) {
+		if (uart_ids & (1 << i)) {
+			enum periph_id id = id_for_uart[i];
+
+			funcmux_select(id, FUNCMUX_DEFAULT);
+			clock_ll_start_uart(id);
+		}
+	}
+}
+
+void board_init_uart_f(void)
+{
+	int uart_ids = 0;	/* bit mask of which UART ids to enable */
+
+#ifdef CONFIG_TEGRA2_ENABLE_UARTA
+	uart_ids |= UARTA;
+#endif
+#ifdef CONFIG_TEGRA2_ENABLE_UARTB
+	uart_ids |= UARTB;
+#endif
+#ifdef CONFIG_TEGRA2_ENABLE_UARTD
+	uart_ids |= UARTD;
+#endif
+	setup_uarts(uart_ids);
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+}
+#endif
diff --git a/arch/arm/cpu/tegra2-common/clock.c b/arch/arm/cpu/tegra2-common/clock.c
new file mode 100644
index 0000000..39376ab
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/clock.c
@@ -0,0 +1,1052 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+/* Tegra2 Clock control functions */
+
+#include <asm/io.h>
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/tegra2.h>
+#include <common.h>
+#include <div64.h>
+#include <fdtdec.h>
+
+/*
+ * This is our record of the current clock rate of each clock. We don't
+ * fill all of these in since we are only really interested in clocks which
+ * we use as parents.
+ */
+static unsigned pll_rate[CLOCK_ID_COUNT];
+
+/*
+ * The oscillator frequency is fixed to one of four set values. Based on this
+ * the other clocks are set up appropriately.
+ */
+static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = {
+	13000000,
+	19200000,
+	12000000,
+	26000000,
+};
+
+/*
+ * Clock types that we can use as a source. The Tegra2 has muxes for the
+ * peripheral clocks, and in most cases there are four options for the clock
+ * source. This gives us a clock 'type' and exploits what commonality exists
+ * in the device.
+ *
+ * Letters are obvious, except for T which means CLK_M, and S which means the
+ * clock derived from 32KHz. Beware that CLK_M (also called OSC in the
+ * datasheet) and PLL_M are different things. The former is the basic
+ * clock supplied to the SOC from an external oscillator. The latter is the
+ * memory clock PLL.
+ *
+ * See definitions in clock_id in the header file.
+ */
+enum clock_type_id {
+	CLOCK_TYPE_AXPT,	/* PLL_A, PLL_X, PLL_P, CLK_M */
+	CLOCK_TYPE_MCPA,	/* and so on */
+	CLOCK_TYPE_MCPT,
+	CLOCK_TYPE_PCM,
+	CLOCK_TYPE_PCMT,
+	CLOCK_TYPE_PCMT16,	/* CLOCK_TYPE_PCMT with 16-bit divider */
+	CLOCK_TYPE_PCXTS,
+	CLOCK_TYPE_PDCT,
+
+	CLOCK_TYPE_COUNT,
+	CLOCK_TYPE_NONE = -1,	/* invalid clock type */
+};
+
+/* return 1 if a peripheral ID is in range */
+#define clock_type_id_isvalid(id) ((id) >= 0 && \
+		(id) < CLOCK_TYPE_COUNT)
+
+char pllp_valid = 1;	/* PLLP is set up correctly */
+
+enum {
+	CLOCK_MAX_MUX	= 4	/* number of source options for each clock */
+};
+
+/*
+ * Clock source mux for each clock type. This just converts our enum into
+ * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS
+ * is special as it has 5 sources. Since it also has a different number of
+ * bits in its register for the source, we just handle it with a special
+ * case in the code.
+ */
+#define CLK(x) CLOCK_ID_ ## x
+static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = {
+	{ CLK(AUDIO),	CLK(XCPU),	CLK(PERIPH),	CLK(OSC)	},
+	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(AUDIO)	},
+	{ CLK(MEMORY),	CLK(CGENERAL),	CLK(PERIPH),	CLK(OSC)	},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(NONE)	},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC)	},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(MEMORY),	CLK(OSC)	},
+	{ CLK(PERIPH),	CLK(CGENERAL),	CLK(XCPU),	CLK(OSC)	},
+	{ CLK(PERIPH),	CLK(DISPLAY),	CLK(CGENERAL),	CLK(OSC)	},
+};
+
+/*
+ * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is
+ * not in the header file since it is for purely internal use - we want
+ * callers to use the PERIPH_ID for all access to peripheral clocks to avoid
+ * confusion bewteen PERIPH_ID_... and PERIPHC_...
+ *
+ * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be
+ * confusing.
+ *
+ * Note to SOC vendors: perhaps define a unified numbering for peripherals and
+ * use it for reset, clock enable, clock source/divider and even pinmuxing
+ * if you can.
+ */
+enum periphc_internal_id {
+	/* 0x00 */
+	PERIPHC_I2S1,
+	PERIPHC_I2S2,
+	PERIPHC_SPDIF_OUT,
+	PERIPHC_SPDIF_IN,
+	PERIPHC_PWM,
+	PERIPHC_SPI1,
+	PERIPHC_SPI2,
+	PERIPHC_SPI3,
+
+	/* 0x08 */
+	PERIPHC_XIO,
+	PERIPHC_I2C1,
+	PERIPHC_DVC_I2C,
+	PERIPHC_TWC,
+	PERIPHC_0c,
+	PERIPHC_10,	/* PERIPHC_SPI1, what is this really? */
+	PERIPHC_DISP1,
+	PERIPHC_DISP2,
+
+	/* 0x10 */
+	PERIPHC_CVE,
+	PERIPHC_IDE0,
+	PERIPHC_VI,
+	PERIPHC_1c,
+	PERIPHC_SDMMC1,
+	PERIPHC_SDMMC2,
+	PERIPHC_G3D,
+	PERIPHC_G2D,
+
+	/* 0x18 */
+	PERIPHC_NDFLASH,
+	PERIPHC_SDMMC4,
+	PERIPHC_VFIR,
+	PERIPHC_EPP,
+	PERIPHC_MPE,
+	PERIPHC_MIPI,
+	PERIPHC_UART1,
+	PERIPHC_UART2,
+
+	/* 0x20 */
+	PERIPHC_HOST1X,
+	PERIPHC_21,
+	PERIPHC_TVO,
+	PERIPHC_HDMI,
+	PERIPHC_24,
+	PERIPHC_TVDAC,
+	PERIPHC_I2C2,
+	PERIPHC_EMC,
+
+	/* 0x28 */
+	PERIPHC_UART3,
+	PERIPHC_29,
+	PERIPHC_VI_SENSOR,
+	PERIPHC_2b,
+	PERIPHC_2c,
+	PERIPHC_SPI4,
+	PERIPHC_I2C3,
+	PERIPHC_SDMMC3,
+
+	/* 0x30 */
+	PERIPHC_UART4,
+	PERIPHC_UART5,
+	PERIPHC_VDE,
+	PERIPHC_OWR,
+	PERIPHC_NOR,
+	PERIPHC_CSITE,
+
+	PERIPHC_COUNT,
+
+	PERIPHC_NONE = -1,
+};
+
+/* return 1 if a periphc_internal_id is in range */
+#define periphc_internal_id_isvalid(id) ((id) >= 0 && \
+		(id) < PERIPHC_COUNT)
+
+/*
+ * Clock type for each peripheral clock source. We put the name in each
+ * record just so it is easy to match things up
+ */
+#define TYPE(name, type) type
+static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
+	/* 0x00 */
+	TYPE(PERIPHC_I2S1,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_I2S2,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_SPDIF_OUT,	CLOCK_TYPE_AXPT),
+	TYPE(PERIPHC_SPDIF_IN,	CLOCK_TYPE_PCM),
+	TYPE(PERIPHC_PWM,	CLOCK_TYPE_PCXTS),
+	TYPE(PERIPHC_SPI1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SPI22,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SPI3,	CLOCK_TYPE_PCMT),
+
+	/* 0x08 */
+	TYPE(PERIPHC_XIO,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2C1,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_DVC_I2C,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_TWC,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SPI1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_DISP1,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_DISP2,	CLOCK_TYPE_PDCT),
+
+	/* 0x10 */
+	TYPE(PERIPHC_CVE,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_IDE0,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SDMMC1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SDMMC2,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_G3D,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_G2D,	CLOCK_TYPE_MCPA),
+
+	/* 0x18 */
+	TYPE(PERIPHC_NDFLASH,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_SDMMC4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VFIR,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_EPP,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MPE,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_MIPI,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART1,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART2,	CLOCK_TYPE_PCMT),
+
+	/* 0x20 */
+	TYPE(PERIPHC_HOST1X,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_TVO,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_HDMI,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_TVDAC,	CLOCK_TYPE_PDCT),
+	TYPE(PERIPHC_I2C2,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_EMC,	CLOCK_TYPE_MCPT),
+
+	/* 0x28 */
+	TYPE(PERIPHC_UART3,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_VI,	CLOCK_TYPE_MCPA),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_NONE,	CLOCK_TYPE_NONE),
+	TYPE(PERIPHC_SPI4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_I2C3,	CLOCK_TYPE_PCMT16),
+	TYPE(PERIPHC_SDMMC3,	CLOCK_TYPE_PCMT),
+
+	/* 0x30 */
+	TYPE(PERIPHC_UART4,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_UART5,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_VDE,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_OWR,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_NOR,	CLOCK_TYPE_PCMT),
+	TYPE(PERIPHC_CSITE,	CLOCK_TYPE_PCMT),
+};
+
+/*
+ * This array translates a periph_id to a periphc_internal_id
+ *
+ * Not present/matched up:
+ *	uint vi_sensor;	 _VI_SENSOR_0,		0x1A8
+ *	SPDIF - which is both 0x08 and 0x0c
+ *
+ */
+#define NONE(name) (-1)
+#define OFFSET(name, value) PERIPHC_ ## name
+static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
+	/* Low word: 31:0 */
+	NONE(CPU),
+	NONE(RESERVED1),
+	NONE(RESERVED2),
+	NONE(AC97),
+	NONE(RTC),
+	NONE(TMR),
+	PERIPHC_UART1,
+	PERIPHC_UART2,	/* and vfir 0x68 */
+
+	/* 0x08 */
+	NONE(GPIO),
+	PERIPHC_SDMMC2,
+	NONE(SPDIF),		/* 0x08 and 0x0c, unclear which to use */
+	PERIPHC_I2S1,
+	PERIPHC_I2C1,
+	PERIPHC_NDFLASH,
+	PERIPHC_SDMMC1,
+	PERIPHC_SDMMC4,
+
+	/* 0x10 */
+	PERIPHC_TWC,
+	PERIPHC_PWM,
+	PERIPHC_I2S2,
+	PERIPHC_EPP,
+	PERIPHC_VI,
+	PERIPHC_G2D,
+	NONE(USBD),
+	NONE(ISP),
+
+	/* 0x18 */
+	PERIPHC_G3D,
+	PERIPHC_IDE0,
+	PERIPHC_DISP2,
+	PERIPHC_DISP1,
+	PERIPHC_HOST1X,
+	NONE(VCP),
+	NONE(RESERVED30),
+	NONE(CACHE2),
+
+	/* Middle word: 63:32 */
+	NONE(MEM),
+	NONE(AHBDMA),
+	NONE(APBDMA),
+	NONE(RESERVED35),
+	NONE(KBC),
+	NONE(STAT_MON),
+	NONE(PMC),
+	NONE(FUSE),
+
+	/* 0x28 */
+	NONE(KFUSE),
+	NONE(SBC1),	/* SBC1, 0x34, is this SPI1? */
+	PERIPHC_NOR,
+	PERIPHC_SPI1,
+	PERIPHC_SPI2,
+	PERIPHC_XIO,
+	PERIPHC_SPI3,
+	PERIPHC_DVC_I2C,
+
+	/* 0x30 */
+	NONE(DSI),
+	PERIPHC_TVO,	/* also CVE 0x40 */
+	PERIPHC_MIPI,
+	PERIPHC_HDMI,
+	PERIPHC_CSITE,
+	PERIPHC_TVDAC,
+	PERIPHC_I2C2,
+	PERIPHC_UART3,
+
+	/* 0x38 */
+	NONE(RESERVED56),
+	PERIPHC_EMC,
+	NONE(USB2),
+	NONE(USB3),
+	PERIPHC_MPE,
+	PERIPHC_VDE,
+	NONE(BSEA),
+	NONE(BSEV),
+
+	/* Upper word 95:64 */
+	NONE(SPEEDO),
+	PERIPHC_UART4,
+	PERIPHC_UART5,
+	PERIPHC_I2C3,
+	PERIPHC_SPI4,
+	PERIPHC_SDMMC3,
+	NONE(PCIE),
+	PERIPHC_OWR,
+
+	/* 0x48 */
+	NONE(AFI),
+	NONE(CORESIGHT),
+	NONE(RESERVED74),
+	NONE(AVPUCQ),
+	NONE(RESERVED76),
+	NONE(RESERVED77),
+	NONE(RESERVED78),
+	NONE(RESERVED79),
+
+	/* 0x50 */
+	NONE(RESERVED80),
+	NONE(RESERVED81),
+	NONE(RESERVED82),
+	NONE(RESERVED83),
+	NONE(IRAMA),
+	NONE(IRAMB),
+	NONE(IRAMC),
+	NONE(IRAMD),
+
+	/* 0x58 */
+	NONE(CRAM2),
+};
+
+/*
+ * Get the oscillator frequency, from the corresponding hardware configuration
+ * field.
+ */
+enum clock_osc_freq clock_get_osc_freq(void)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 reg;
+
+	reg = readl(&clkrst->crc_osc_ctrl);
+	return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
+}
+
+/* Returns a pointer to the registers of the given pll */
+static struct clk_pll *get_pll(enum clock_id clkid)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+
+	assert(clock_id_isvalid(clkid));
+	return &clkrst->crc_pll[clkid];
+}
+
+unsigned long clock_start_pll(enum clock_id clkid, u32 divm, u32 divn,
+		u32 divp, u32 cpcon, u32 lfcon)
+{
+	struct clk_pll *pll = get_pll(clkid);
+	u32 data;
+
+	/*
+	 * We cheat by treating all PLL (except PLLU) in the same fashion.
+	 * This works only because:
+	 * - same fields are always mapped at same offsets, except DCCON
+	 * - DCCON is always 0, doesn't conflict
+	 * - M,N, P of PLLP values are ignored for PLLP
+	 */
+	data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
+	writel(data, &pll->pll_misc);
+
+	data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
+			(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
+
+	if (clkid == CLOCK_ID_USB)
+		data |= divp << PLLU_VCO_FREQ_SHIFT;
+	else
+		data |= divp << PLL_DIVP_SHIFT;
+	writel(data, &pll->pll_base);
+
+	/* calculate the stable time */
+	return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US;
+}
+
+/* return 1 if a peripheral ID is in range and valid */
+static int clock_periph_id_isvalid(enum periph_id id)
+{
+	if (id < PERIPH_ID_FIRST || id >= PERIPH_ID_COUNT)
+		printf("Peripheral id %d out of range\n", id);
+	else {
+		switch (id) {
+		case PERIPH_ID_RESERVED1:
+		case PERIPH_ID_RESERVED2:
+		case PERIPH_ID_RESERVED30:
+		case PERIPH_ID_RESERVED35:
+		case PERIPH_ID_RESERVED56:
+		case PERIPH_ID_RESERVED74:
+		case PERIPH_ID_RESERVED76:
+		case PERIPH_ID_RESERVED77:
+		case PERIPH_ID_RESERVED78:
+		case PERIPH_ID_RESERVED79:
+		case PERIPH_ID_RESERVED80:
+		case PERIPH_ID_RESERVED81:
+		case PERIPH_ID_RESERVED82:
+		case PERIPH_ID_RESERVED83:
+			printf("Peripheral id %d is reserved\n", id);
+			break;
+		default:
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/* Returns a pointer to the clock source register for a peripheral */
+static u32 *get_periph_source_reg(enum periph_id periph_id)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	enum periphc_internal_id internal_id;
+
+	assert(clock_periph_id_isvalid(periph_id));
+	internal_id = periph_id_to_internal_id[periph_id];
+	assert(internal_id != -1);
+	return &clkrst->crc_clk_src[internal_id];
+}
+
+void clock_ll_set_source_divisor(enum periph_id periph_id, unsigned source,
+			      unsigned divisor)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+	u32 value;
+
+	value = readl(reg);
+
+	value &= ~OUT_CLK_SOURCE_MASK;
+	value |= source << OUT_CLK_SOURCE_SHIFT;
+
+	value &= ~OUT_CLK_DIVISOR_MASK;
+	value |= divisor << OUT_CLK_DIVISOR_SHIFT;
+
+	writel(value, reg);
+}
+
+void clock_ll_set_source(enum periph_id periph_id, unsigned source)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+
+	clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
+			source << OUT_CLK_SOURCE_SHIFT);
+}
+
+/**
+ * Given the parent's rate and the required rate for the children, this works
+ * out the peripheral clock divider to use, in 7.1 binary format.
+ *
+ * @param divider_bits	number of divider bits (8 or 16)
+ * @param parent_rate	clock rate of parent clock in Hz
+ * @param rate		required clock rate for this clock
+ * @return divider which should be used
+ */
+static int clk_get_divider(unsigned divider_bits, unsigned long parent_rate,
+			   unsigned long rate)
+{
+	u64 divider = parent_rate * 2;
+	unsigned max_divider = 1 << divider_bits;
+
+	divider += rate - 1;
+	do_div(divider, rate);
+
+	if ((s64)divider - 2 < 0)
+		return 0;
+
+	if ((s64)divider - 2 >= max_divider)
+		return -1;
+
+	return divider - 2;
+}
+
+/**
+ * Given the parent's rate and the divider in 7.1 format, this works out the
+ * resulting peripheral clock rate.
+ *
+ * @param parent_rate	clock rate of parent clock in Hz
+ * @param divider which should be used in 7.1 format
+ * @return effective clock rate of peripheral
+ */
+static unsigned long get_rate_from_divider(unsigned long parent_rate,
+					   int divider)
+{
+	u64 rate;
+
+	rate = (u64)parent_rate * 2;
+	do_div(rate, divider + 2);
+	return rate;
+}
+
+unsigned long clock_get_periph_rate(enum periph_id periph_id,
+		enum clock_id parent)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+
+	return get_rate_from_divider(pll_rate[parent],
+		(readl(reg) & OUT_CLK_DIVISOR_MASK) >> OUT_CLK_DIVISOR_SHIFT);
+}
+
+/**
+ * Find the best available 7.1 format divisor given a parent clock rate and
+ * required child clock rate. This function assumes that a second-stage
+ * divisor is available which can divide by powers of 2 from 1 to 256.
+ *
+ * @param divider_bits	number of divider bits (8 or 16)
+ * @param parent_rate	clock rate of parent clock in Hz
+ * @param rate		required clock rate for this clock
+ * @param extra_div	value for the second-stage divisor (not set if this
+ *			function returns -1.
+ * @return divider which should be used, or -1 if nothing is valid
+ *
+ */
+static int find_best_divider(unsigned divider_bits, unsigned long parent_rate,
+			     unsigned long rate, int *extra_div)
+{
+	int shift;
+	int best_divider = -1;
+	int best_error = rate;
+
+	/* try dividers from 1 to 256 and find closest match */
+	for (shift = 0; shift <= 8 && best_error > 0; shift++) {
+		unsigned divided_parent = parent_rate >> shift;
+		int divider = clk_get_divider(divider_bits, divided_parent,
+					      rate);
+		unsigned effective_rate = get_rate_from_divider(divided_parent,
+						       divider);
+		int error = rate - effective_rate;
+
+		/* Given a valid divider, look for the lowest error */
+		if (divider != -1 && error < best_error) {
+			best_error = error;
+			*extra_div = 1 << shift;
+			best_divider = divider;
+		}
+	}
+
+	/* return what we found - *extra_div will already be set */
+	return best_divider;
+}
+
+/**
+ * Given a peripheral ID and the required source clock, this returns which
+ * value should be programmed into the source mux for that peripheral.
+ *
+ * There is special code here to handle the one source type with 5 sources.
+ *
+ * @param periph_id	peripheral to start
+ * @param source	PLL id of required parent clock
+ * @param mux_bits	Set to number of bits in mux register: 2 or 4
+ * @param divider_bits	Set to number of divider bits (8 or 16)
+ * @return mux value (0-4, or -1 if not found)
+ */
+static int get_periph_clock_source(enum periph_id periph_id,
+		enum clock_id parent, int *mux_bits, int *divider_bits)
+{
+	enum clock_type_id type;
+	enum periphc_internal_id internal_id;
+	int mux;
+
+	assert(clock_periph_id_isvalid(periph_id));
+
+	internal_id = periph_id_to_internal_id[periph_id];
+	assert(periphc_internal_id_isvalid(internal_id));
+
+	type = clock_periph_type[internal_id];
+	assert(clock_type_id_isvalid(type));
+
+	/*
+	 * Special cases here for the clock with a 4-bit source mux and I2C
+	 * with its 16-bit divisor
+	 */
+	if (type == CLOCK_TYPE_PCXTS)
+		*mux_bits = 4;
+	else
+		*mux_bits = 2;
+	if (type == CLOCK_TYPE_PCMT16)
+		*divider_bits = 16;
+	else
+		*divider_bits = 8;
+
+	for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
+		if (clock_source[type][mux] == parent)
+			return mux;
+
+	/*
+	 * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS
+	 * which is not in our table. If not, then they are asking for a
+	 * source which this peripheral can't access through its mux.
+	 */
+	assert(type == CLOCK_TYPE_PCXTS);
+	assert(parent == CLOCK_ID_SFROM32KHZ);
+	if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ)
+		return 4;	/* mux value for this clock */
+
+	/* if we get here, either us or the caller has made a mistake */
+	printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
+		parent);
+	return -1;
+}
+
+/**
+ * Adjust peripheral PLL to use the given divider and source.
+ *
+ * @param periph_id	peripheral to adjust
+ * @param source	Source number (0-3 or 0-7)
+ * @param mux_bits	Number of mux bits (2 or 4)
+ * @param divider	Required divider in 7.1 or 15.1 format
+ * @return 0 if ok, -1 on error (requesting a parent clock which is not valid
+ *		for this peripheral)
+ */
+static int adjust_periph_pll(enum periph_id periph_id, int source,
+			     int mux_bits, unsigned divider)
+{
+	u32 *reg = get_periph_source_reg(periph_id);
+
+	clrsetbits_le32(reg, OUT_CLK_DIVISOR_MASK,
+			divider << OUT_CLK_DIVISOR_SHIFT);
+	udelay(1);
+
+	/* work out the source clock and set it */
+	if (source < 0)
+		return -1;
+	if (mux_bits == 4) {
+		clrsetbits_le32(reg, OUT_CLK_SOURCE4_MASK,
+			source << OUT_CLK_SOURCE4_SHIFT);
+	} else {
+		clrsetbits_le32(reg, OUT_CLK_SOURCE_MASK,
+			source << OUT_CLK_SOURCE_SHIFT);
+	}
+	udelay(2);
+	return 0;
+}
+
+unsigned clock_adjust_periph_pll_div(enum periph_id periph_id,
+		enum clock_id parent, unsigned rate, int *extra_div)
+{
+	unsigned effective_rate;
+	int mux_bits, divider_bits, source;
+	int divider;
+
+	/* work out the source clock and set it */
+	source = get_periph_clock_source(periph_id, parent, &mux_bits,
+					 &divider_bits);
+
+	if (extra_div)
+		divider = find_best_divider(divider_bits, pll_rate[parent],
+					    rate, extra_div);
+	else
+		divider = clk_get_divider(divider_bits, pll_rate[parent],
+					  rate);
+	assert(divider >= 0);
+	if (adjust_periph_pll(periph_id, source, mux_bits, divider))
+		return -1U;
+	debug("periph %d, rate=%d, reg=%p = %x\n", periph_id, rate,
+		get_periph_source_reg(periph_id),
+		readl(get_periph_source_reg(periph_id)));
+
+	/* Check what we ended up with. This shouldn't matter though */
+	effective_rate = clock_get_periph_rate(periph_id, parent);
+	if (extra_div)
+		effective_rate /= *extra_div;
+	if (rate != effective_rate)
+		debug("Requested clock rate %u not honored (got %u)\n",
+		       rate, effective_rate);
+	return effective_rate;
+}
+
+unsigned clock_start_periph_pll(enum periph_id periph_id,
+		enum clock_id parent, unsigned rate)
+{
+	unsigned effective_rate;
+
+	reset_set_enable(periph_id, 1);
+	clock_enable(periph_id);
+
+	effective_rate = clock_adjust_periph_pll_div(periph_id, parent, rate,
+						 NULL);
+
+	reset_set_enable(periph_id, 0);
+	return effective_rate;
+}
+
+void clock_set_enable(enum periph_id periph_id, int enable)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
+	u32 reg;
+
+	/* Enable/disable the clock to this peripheral */
+	assert(clock_periph_id_isvalid(periph_id));
+	reg = readl(clk);
+	if (enable)
+		reg |= PERIPH_MASK(periph_id);
+	else
+		reg &= ~PERIPH_MASK(periph_id);
+	writel(reg, clk);
+}
+
+void clock_enable(enum periph_id clkid)
+{
+	clock_set_enable(clkid, 1);
+}
+
+void clock_disable(enum periph_id clkid)
+{
+	clock_set_enable(clkid, 0);
+}
+
+void reset_set_enable(enum periph_id periph_id, int enable)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
+	u32 reg;
+
+	/* Enable/disable reset to the peripheral */
+	assert(clock_periph_id_isvalid(periph_id));
+	reg = readl(reset);
+	if (enable)
+		reg |= PERIPH_MASK(periph_id);
+	else
+		reg &= ~PERIPH_MASK(periph_id);
+	writel(reg, reset);
+}
+
+void reset_periph(enum periph_id periph_id, int us_delay)
+{
+	/* Put peripheral into reset */
+	reset_set_enable(periph_id, 1);
+	udelay(us_delay);
+
+	/* Remove reset */
+	reset_set_enable(periph_id, 0);
+
+	udelay(us_delay);
+}
+
+void reset_cmplx_set_enable(int cpu, int which, int reset)
+{
+	struct clk_rst_ctlr *clkrst =
+			(struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	u32 mask;
+
+	/* Form the mask, which depends on the cpu chosen. Tegra2 has 2 */
+	assert(cpu >= 0 && cpu < 2);
+	mask = which << cpu;
+
+	/* either enable or disable those reset for that CPU */
+	if (reset)
+		writel(mask, &clkrst->crc_cpu_cmplx_set);
+	else
+		writel(mask, &clkrst->crc_cpu_cmplx_clr);
+}
+
+unsigned clock_get_rate(enum clock_id clkid)
+{
+	struct clk_pll *pll;
+	u32 base;
+	u32 divm;
+	u64 parent_rate;
+	u64 rate;
+
+	parent_rate = osc_freq[clock_get_osc_freq()];
+	if (clkid == CLOCK_ID_OSC)
+		return parent_rate;
+
+	pll = get_pll(clkid);
+	base = readl(&pll->pll_base);
+
+	/* Oh for bf_unpack()... */
+	rate = parent_rate * ((base & PLL_DIVN_MASK) >> PLL_DIVN_SHIFT);
+	divm = (base & PLL_DIVM_MASK) >> PLL_DIVM_SHIFT;
+	if (clkid == CLOCK_ID_USB)
+		divm <<= (base & PLLU_VCO_FREQ_MASK) >> PLLU_VCO_FREQ_SHIFT;
+	else
+		divm <<= (base & PLL_DIVP_MASK) >> PLL_DIVP_SHIFT;
+	do_div(rate, divm);
+	return rate;
+}
+
+/**
+ * Set the output frequency you want for each PLL clock.
+ * PLL output frequencies are programmed by setting their N, M and P values.
+ * The governing equations are:
+ *     VCO = (Fi / m) * n, Fo = VCO / (2^p)
+ *     where Fo is the output frequency from the PLL.
+ * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
+ *     216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
+ * Please see Tegra TRM section 5.3 to get the detail for PLL Programming
+ *
+ * @param n PLL feedback divider(DIVN)
+ * @param m PLL input divider(DIVN)
+ * @param p post divider(DIVP)
+ * @param cpcon base PLL charge pump(CPCON)
+ * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
+ *		be overriden), 1 if PLL is already correct
+ */
+static int clock_set_rate(enum clock_id clkid, u32 n, u32 m, u32 p, u32 cpcon)
+{
+	u32 base_reg;
+	u32 misc_reg;
+	struct clk_pll *pll;
+
+	pll = get_pll(clkid);
+
+	base_reg = readl(&pll->pll_base);
+
+	/* Set BYPASS, m, n and p to PLL_BASE */
+	base_reg &= ~PLL_DIVM_MASK;
+	base_reg |= m << PLL_DIVM_SHIFT;
+
+	base_reg &= ~PLL_DIVN_MASK;
+	base_reg |= n << PLL_DIVN_SHIFT;
+
+	base_reg &= ~PLL_DIVP_MASK;
+	base_reg |= p << PLL_DIVP_SHIFT;
+
+	if (clkid == CLOCK_ID_PERIPH) {
+		/*
+		 * If the PLL is already set up, check that it is correct
+		 * and record this info for clock_verify() to check.
+		 */
+		if (base_reg & PLL_BASE_OVRRIDE_MASK) {
+			base_reg |= PLL_ENABLE_MASK;
+			if (base_reg != readl(&pll->pll_base))
+				pllp_valid = 0;
+			return pllp_valid ? 1 : -1;
+		}
+		base_reg |= PLL_BASE_OVRRIDE_MASK;
+	}
+
+	base_reg |= PLL_BYPASS_MASK;
+	writel(base_reg, &pll->pll_base);
+
+	/* Set cpcon to PLL_MISC */
+	misc_reg = readl(&pll->pll_misc);
+	misc_reg &= ~PLL_CPCON_MASK;
+	misc_reg |= cpcon << PLL_CPCON_SHIFT;
+	writel(misc_reg, &pll->pll_misc);
+
+	/* Enable PLL */
+	base_reg |= PLL_ENABLE_MASK;
+	writel(base_reg, &pll->pll_base);
+
+	/* Disable BYPASS */
+	base_reg &= ~PLL_BYPASS_MASK;
+	writel(base_reg, &pll->pll_base);
+
+	return 0;
+}
+
+void clock_ll_start_uart(enum periph_id periph_id)
+{
+	/* Assert UART reset and enable clock */
+	reset_set_enable(periph_id, 1);
+	clock_enable(periph_id);
+	clock_ll_set_source(periph_id, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
+
+	/* wait for 2us */
+	udelay(2);
+
+	/* De-assert reset to UART */
+	reset_set_enable(periph_id, 0);
+}
+
+#ifdef CONFIG_OF_CONTROL
+/*
+ * Convert a device tree clock ID to our peripheral ID. They are mostly
+ * the same but we are very cautious so we check that a valid clock ID is
+ * provided.
+ *
+ * @param clk_id	Clock ID according to tegra2 device tree binding
+ * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
+ */
+static enum periph_id clk_id_to_periph_id(int clk_id)
+{
+	if (clk_id > 95)
+		return PERIPH_ID_NONE;
+
+	switch (clk_id) {
+	case 1:
+	case 2:
+	case 7:
+	case 10:
+	case 20:
+	case 30:
+	case 35:
+	case 49:
+	case 56:
+	case 74:
+	case 76:
+	case 77:
+	case 78:
+	case 79:
+	case 80:
+	case 81:
+	case 82:
+	case 83:
+	case 91:
+	case 95:
+		return PERIPH_ID_NONE;
+	default:
+		return clk_id;
+	}
+}
+
+int clock_decode_periph_id(const void *blob, int node)
+{
+	enum periph_id id;
+	u32 cell[2];
+	int err;
+
+	err = fdtdec_get_int_array(blob, node, "clocks", cell,
+				   ARRAY_SIZE(cell));
+	if (err)
+		return -1;
+	id = clk_id_to_periph_id(cell[1]);
+	assert(clock_periph_id_isvalid(id));
+	return id;
+}
+#endif /* CONFIG_OF_CONTROL */
+
+int clock_verify(void)
+{
+	struct clk_pll *pll = get_pll(CLOCK_ID_PERIPH);
+	u32 reg = readl(&pll->pll_base);
+
+	if (!pllp_valid) {
+		printf("Warning: PLLP %x is not correct\n", reg);
+		return -1;
+	}
+	debug("PLLX %x is correct\n", reg);
+	return 0;
+}
+
+void clock_early_init(void)
+{
+	/*
+	 * PLLP output frequency set to 216MHz
+	 * PLLC output frequency set to 600Mhz
+	 *
+	 * TODO: Can we calculate these values instead of hard-coding?
+	 */
+	switch (clock_get_osc_freq()) {
+	case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
+		break;
+
+	case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
+		clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8);
+		clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
+		break;
+
+	case CLOCK_OSC_FREQ_13_0:
+	case CLOCK_OSC_FREQ_19_2:
+	default:
+		/*
+		 * These are not supported. It is too early to print a
+		 * message and the UART likely won't work anyway due to the
+		 * oscillator being wrong.
+		 */
+		break;
+	}
+}
+
+void clock_init(void)
+{
+	pll_rate[CLOCK_ID_MEMORY] = clock_get_rate(CLOCK_ID_MEMORY);
+	pll_rate[CLOCK_ID_PERIPH] = clock_get_rate(CLOCK_ID_PERIPH);
+	pll_rate[CLOCK_ID_CGENERAL] = clock_get_rate(CLOCK_ID_CGENERAL);
+	pll_rate[CLOCK_ID_OSC] = clock_get_rate(CLOCK_ID_OSC);
+	pll_rate[CLOCK_ID_SFROM32KHZ] = 32768;
+	debug("Osc = %d\n", pll_rate[CLOCK_ID_OSC]);
+	debug("PLLM = %d\n", pll_rate[CLOCK_ID_MEMORY]);
+	debug("PLLP = %d\n", pll_rate[CLOCK_ID_PERIPH]);
+}
diff --git a/arch/arm/cpu/tegra2-common/funcmux.c b/arch/arm/cpu/tegra2-common/funcmux.c
new file mode 100644
index 0000000..c1d2dfe
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/funcmux.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+/* Tegra2 high-level function multiplexing */
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/pinmux.h>
+
+int funcmux_select(enum periph_id id, int config)
+{
+	int bad_config = config != FUNCMUX_DEFAULT;
+
+	switch (id) {
+	case PERIPH_ID_UART1:
+		if (config == FUNCMUX_UART1_IRRX_IRTX) {
+			pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA);
+			pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA);
+			pinmux_tristate_disable(PINGRP_IRRX);
+			pinmux_tristate_disable(PINGRP_IRTX);
+			/*
+			 * Tegra appears to boot with function UARTA pre-
+			 * selected on mux group SDB. If two mux groups are
+			 * both set to the same function, it's unclear which
+			 * group's pins drive the RX signals into the HW.
+			 * For UARTA, SDB certainly overrides group IRTX in
+			 * practice. To solve this, configure some alternative
+			 * function on SDB to avoid the conflict. Also, tri-
+			 * state the group to avoid driving any signal onto it
+			 * until we know what's connected.
+			 */
+			pinmux_tristate_enable(PINGRP_SDB);
+			pinmux_set_func(PINGRP_SDB,  PMUX_FUNC_SDIO3);
+		}
+		break;
+
+	case PERIPH_ID_UART2:
+		if (config == FUNCMUX_UART2_IRDA) {
+			pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA);
+			pinmux_tristate_disable(PINGRP_UAD);
+		}
+		break;
+
+	case PERIPH_ID_UART4:
+		if (config == FUNCMUX_UART4_GMC) {
+			pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD);
+			pinmux_tristate_disable(PINGRP_GMC);
+		}
+		break;
+
+	case PERIPH_ID_DVC_I2C:
+		/* there is only one selection, pinmux_config is ignored */
+		if (config == FUNCMUX_DVC_I2CP) {
+			pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C);
+			pinmux_tristate_disable(PINGRP_I2CP);
+		}
+		break;
+
+	case PERIPH_ID_I2C1:
+		/* support pinmux_config of 0 for now, */
+		if (config == FUNCMUX_I2C1_RM) {
+			pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C);
+			pinmux_tristate_disable(PINGRP_RM);
+		}
+		break;
+	case PERIPH_ID_I2C2: /* I2C2 */
+		switch (config) {
+		case FUNCMUX_I2C2_DDC:	/* DDC pin group, select I2C2 */
+			pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2);
+			/* PTA to HDMI */
+			pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI);
+			pinmux_tristate_disable(PINGRP_DDC);
+			break;
+		case FUNCMUX_I2C2_PTA:	/* PTA pin group, select I2C2 */
+			pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2);
+			/* set DDC_SEL to RSVDx (RSVD2 works for now) */
+			pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2);
+			pinmux_tristate_disable(PINGRP_PTA);
+			bad_config = 0;
+			break;
+		}
+		break;
+	case PERIPH_ID_I2C3: /* I2C3 */
+		/* support pinmux_config of 0 for now */
+		if (config == FUNCMUX_I2C3_DTF) {
+			pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3);
+			pinmux_tristate_disable(PINGRP_DTF);
+		}
+		break;
+
+	case PERIPH_ID_SDMMC2:
+		if (config == FUNCMUX_SDMMC2_DTA_DTD_8BIT) {
+			pinmux_set_func(PINGRP_DTA, PMUX_FUNC_SDIO2);
+			pinmux_set_func(PINGRP_DTD, PMUX_FUNC_SDIO2);
+
+			pinmux_tristate_disable(PINGRP_DTA);
+			pinmux_tristate_disable(PINGRP_DTD);
+		}
+		break;
+
+	case PERIPH_ID_SDMMC3:
+		switch (config) {
+		case FUNCMUX_SDMMC3_SDB_SLXA_8BIT:
+			pinmux_set_func(PINGRP_SLXA, PMUX_FUNC_SDIO3);
+			pinmux_set_func(PINGRP_SLXC, PMUX_FUNC_SDIO3);
+			pinmux_set_func(PINGRP_SLXD, PMUX_FUNC_SDIO3);
+			pinmux_set_func(PINGRP_SLXK, PMUX_FUNC_SDIO3);
+
+			pinmux_tristate_disable(PINGRP_SLXA);
+			pinmux_tristate_disable(PINGRP_SLXC);
+			pinmux_tristate_disable(PINGRP_SLXD);
+			pinmux_tristate_disable(PINGRP_SLXK);
+			/* fall through */
+
+		case FUNCMUX_SDMMC3_SDB_4BIT:
+			pinmux_set_func(PINGRP_SDB, PMUX_FUNC_SDIO3);
+			pinmux_set_func(PINGRP_SDC, PMUX_FUNC_SDIO3);
+			pinmux_set_func(PINGRP_SDD, PMUX_FUNC_SDIO3);
+
+			pinmux_tristate_disable(PINGRP_SDB);
+			pinmux_tristate_disable(PINGRP_SDC);
+			pinmux_tristate_disable(PINGRP_SDD);
+			bad_config = 0;
+			break;
+		}
+		break;
+
+	case PERIPH_ID_SDMMC4:
+		switch (config) {
+		case FUNCMUX_SDMMC4_ATC_ATD_8BIT:
+			pinmux_set_func(PINGRP_ATC, PMUX_FUNC_SDIO4);
+			pinmux_set_func(PINGRP_ATD, PMUX_FUNC_SDIO4);
+
+			pinmux_tristate_disable(PINGRP_ATC);
+			pinmux_tristate_disable(PINGRP_ATD);
+			break;
+
+		case FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT:
+			pinmux_set_func(PINGRP_GME, PMUX_FUNC_SDIO4);
+			pinmux_tristate_disable(PINGRP_GME);
+			/* fall through */
+
+		case FUNCMUX_SDMMC4_ATB_GMA_4_BIT:
+			pinmux_set_func(PINGRP_ATB, PMUX_FUNC_SDIO4);
+			pinmux_set_func(PINGRP_GMA, PMUX_FUNC_SDIO4);
+
+			pinmux_tristate_disable(PINGRP_ATB);
+			pinmux_tristate_disable(PINGRP_GMA);
+			bad_config = 0;
+			break;
+		}
+		break;
+
+	default:
+		debug("%s: invalid periph_id %d", __func__, id);
+		return -1;
+	}
+
+	if (bad_config) {
+		debug("%s: invalid config %d for periph_id %d", __func__,
+		      config, id);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/arch/arm/cpu/tegra2-common/lowlevel_init.S b/arch/arm/cpu/tegra2-common/lowlevel_init.S
new file mode 100644
index 0000000..6b86647
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/lowlevel_init.S
@@ -0,0 +1,41 @@
+/*
+ * SoC-specific setup info
+ *
+ * (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 <config.h>
+#include <version.h>
+
+	.align	5
+.global reset_cpu
+reset_cpu:
+	ldr	r1, rstctl			@ get addr for global reset
+						@ reg
+	ldr	r3, [r1]
+	orr	r3, r3, #0x10
+	str	r3, [r1]			@ force reset
+	mov	r0, r0
+_loop_forever:
+	b	_loop_forever
+rstctl:
+	.word	PRM_RSTCTRL
diff --git a/arch/arm/cpu/tegra2-common/pinmux.c b/arch/arm/cpu/tegra2-common/pinmux.c
new file mode 100644
index 0000000..b053f90
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/pinmux.c
@@ -0,0 +1,572 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * 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
+ */
+
+/* Tegra2 pin multiplexing functions */
+
+#include <asm/io.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/pinmux.h>
+#include <common.h>
+
+
+/*
+ * This defines the order of the pin mux control bits in the registers. For
+ * some reason there is no correspendence between the tristate, pin mux and
+ * pullup/pulldown registers.
+ */
+enum pmux_ctlid {
+	/* 0: APB_MISC_PP_PIN_MUX_CTL_A_0 */
+	MUXCTL_UAA,
+	MUXCTL_UAB,
+	MUXCTL_UAC,
+	MUXCTL_UAD,
+	MUXCTL_UDA,
+	MUXCTL_RESERVED5,
+	MUXCTL_ATE,
+	MUXCTL_RM,
+
+	MUXCTL_ATB,
+	MUXCTL_RESERVED9,
+	MUXCTL_ATD,
+	MUXCTL_ATC,
+	MUXCTL_ATA,
+	MUXCTL_KBCF,
+	MUXCTL_KBCE,
+	MUXCTL_SDMMC1,
+
+	/* 16: APB_MISC_PP_PIN_MUX_CTL_B_0 */
+	MUXCTL_GMA,
+	MUXCTL_GMC,
+	MUXCTL_HDINT,
+	MUXCTL_SLXA,
+	MUXCTL_OWC,
+	MUXCTL_SLXC,
+	MUXCTL_SLXD,
+	MUXCTL_SLXK,
+
+	MUXCTL_UCA,
+	MUXCTL_UCB,
+	MUXCTL_DTA,
+	MUXCTL_DTB,
+	MUXCTL_RESERVED28,
+	MUXCTL_DTC,
+	MUXCTL_DTD,
+	MUXCTL_DTE,
+
+	/* 32: APB_MISC_PP_PIN_MUX_CTL_C_0 */
+	MUXCTL_DDC,
+	MUXCTL_CDEV1,
+	MUXCTL_CDEV2,
+	MUXCTL_CSUS,
+	MUXCTL_I2CP,
+	MUXCTL_KBCA,
+	MUXCTL_KBCB,
+	MUXCTL_KBCC,
+
+	MUXCTL_IRTX,
+	MUXCTL_IRRX,
+	MUXCTL_DAP1,
+	MUXCTL_DAP2,
+	MUXCTL_DAP3,
+	MUXCTL_DAP4,
+	MUXCTL_GMB,
+	MUXCTL_GMD,
+
+	/* 48: APB_MISC_PP_PIN_MUX_CTL_D_0 */
+	MUXCTL_GME,
+	MUXCTL_GPV,
+	MUXCTL_GPU,
+	MUXCTL_SPDO,
+	MUXCTL_SPDI,
+	MUXCTL_SDB,
+	MUXCTL_SDC,
+	MUXCTL_SDD,
+
+	MUXCTL_SPIH,
+	MUXCTL_SPIG,
+	MUXCTL_SPIF,
+	MUXCTL_SPIE,
+	MUXCTL_SPID,
+	MUXCTL_SPIC,
+	MUXCTL_SPIB,
+	MUXCTL_SPIA,
+
+	/* 64: APB_MISC_PP_PIN_MUX_CTL_E_0 */
+	MUXCTL_LPW0,
+	MUXCTL_LPW1,
+	MUXCTL_LPW2,
+	MUXCTL_LSDI,
+	MUXCTL_LSDA,
+	MUXCTL_LSPI,
+	MUXCTL_LCSN,
+	MUXCTL_LDC,
+
+	MUXCTL_LSCK,
+	MUXCTL_LSC0,
+	MUXCTL_LSC1,
+	MUXCTL_LHS,
+	MUXCTL_LVS,
+	MUXCTL_LM0,
+	MUXCTL_LM1,
+	MUXCTL_LVP0,
+
+	/* 80: APB_MISC_PP_PIN_MUX_CTL_F_0 */
+	MUXCTL_LD0,
+	MUXCTL_LD1,
+	MUXCTL_LD2,
+	MUXCTL_LD3,
+	MUXCTL_LD4,
+	MUXCTL_LD5,
+	MUXCTL_LD6,
+	MUXCTL_LD7,
+
+	MUXCTL_LD8,
+	MUXCTL_LD9,
+	MUXCTL_LD10,
+	MUXCTL_LD11,
+	MUXCTL_LD12,
+	MUXCTL_LD13,
+	MUXCTL_LD14,
+	MUXCTL_LD15,
+
+	/* 96: APB_MISC_PP_PIN_MUX_CTL_G_0 */
+	MUXCTL_LD16,
+	MUXCTL_LD17,
+	MUXCTL_LHP1,
+	MUXCTL_LHP2,
+	MUXCTL_LVP1,
+	MUXCTL_LHP0,
+	MUXCTL_RESERVED102,
+	MUXCTL_LPP,
+
+	MUXCTL_LDI,
+	MUXCTL_PMC,
+	MUXCTL_CRTP,
+	MUXCTL_PTA,
+	MUXCTL_RESERVED108,
+	MUXCTL_KBCD,
+	MUXCTL_GPU7,
+	MUXCTL_DTF,
+
+	MUXCTL_NONE = -1,
+};
+
+/*
+ * And this defines the order of the pullup/pulldown controls which are again
+ * in a different order
+ */
+enum pmux_pullid {
+	/* 0: APB_MISC_PP_PULLUPDOWN_REG_A_0 */
+	PUCTL_ATA,
+	PUCTL_ATB,
+	PUCTL_ATC,
+	PUCTL_ATD,
+	PUCTL_ATE,
+	PUCTL_DAP1,
+	PUCTL_DAP2,
+	PUCTL_DAP3,
+
+	PUCTL_DAP4,
+	PUCTL_DTA,
+	PUCTL_DTB,
+	PUCTL_DTC,
+	PUCTL_DTD,
+	PUCTL_DTE,
+	PUCTL_DTF,
+	PUCTL_GPV,
+
+	/* 16: APB_MISC_PP_PULLUPDOWN_REG_B_0 */
+	PUCTL_RM,
+	PUCTL_I2CP,
+	PUCTL_PTA,
+	PUCTL_GPU7,
+	PUCTL_KBCA,
+	PUCTL_KBCB,
+	PUCTL_KBCC,
+	PUCTL_KBCD,
+
+	PUCTL_SPDI,
+	PUCTL_SPDO,
+	PUCTL_GPSLXAU,
+	PUCTL_CRTP,
+	PUCTL_SLXC,
+	PUCTL_SLXD,
+	PUCTL_SLXK,
+
+	/* 32: APB_MISC_PP_PULLUPDOWN_REG_C_0 */
+	PUCTL_CDEV1,
+	PUCTL_CDEV2,
+	PUCTL_SPIA,
+	PUCTL_SPIB,
+	PUCTL_SPIC,
+	PUCTL_SPID,
+	PUCTL_SPIE,
+	PUCTL_SPIF,
+
+	PUCTL_SPIG,
+	PUCTL_SPIH,
+	PUCTL_IRTX,
+	PUCTL_IRRX,
+	PUCTL_GME,
+	PUCTL_RESERVED45,
+	PUCTL_XM2D,
+	PUCTL_XM2C,
+
+	/* 48: APB_MISC_PP_PULLUPDOWN_REG_D_0 */
+	PUCTL_UAA,
+	PUCTL_UAB,
+	PUCTL_UAC,
+	PUCTL_UAD,
+	PUCTL_UCA,
+	PUCTL_UCB,
+	PUCTL_LD17,
+	PUCTL_LD19_18,
+
+	PUCTL_LD21_20,
+	PUCTL_LD23_22,
+	PUCTL_LS,
+	PUCTL_LC,
+	PUCTL_CSUS,
+	PUCTL_DDRC,
+	PUCTL_SDC,
+	PUCTL_SDD,
+
+	/* 64: APB_MISC_PP_PULLUPDOWN_REG_E_0 */
+	PUCTL_KBCF,
+	PUCTL_KBCE,
+	PUCTL_PMCA,
+	PUCTL_PMCB,
+	PUCTL_PMCC,
+	PUCTL_PMCD,
+	PUCTL_PMCE,
+	PUCTL_CK32,
+
+	PUCTL_UDA,
+	PUCTL_SDMMC1,
+	PUCTL_GMA,
+	PUCTL_GMB,
+	PUCTL_GMC,
+	PUCTL_GMD,
+	PUCTL_DDC,
+	PUCTL_OWC,
+
+	PUCTL_NONE = -1
+};
+
+struct tegra_pingroup_desc {
+	const char *name;
+	enum pmux_func funcs[4];
+	enum pmux_func func_safe;
+	enum pmux_vddio vddio;
+	enum pmux_ctlid ctl_id;
+	enum pmux_pullid pull_id;
+};
+
+
+/* Converts a pmux_pingrp number to a tristate register: 0=A, 1=B, 2=C, 3=D */
+#define TRISTATE_REG(pmux_pingrp) ((pmux_pingrp) >> 5)
+
+/* Mask value for a tristate (within TRISTATE_REG(id)) */
+#define TRISTATE_MASK(pmux_pingrp) (1 << ((pmux_pingrp) & 0x1f))
+
+/* Converts a PUCTL id to a pull register: 0=A, 1=B...4=E */
+#define PULL_REG(pmux_pullid) ((pmux_pullid) >> 4)
+
+/* Converts a PUCTL id to a shift position */
+#define PULL_SHIFT(pmux_pullid) ((pmux_pullid << 1) & 0x1f)
+
+/* Converts a MUXCTL id to a ctl register: 0=A, 1=B...6=G */
+#define MUXCTL_REG(pmux_ctlid) ((pmux_ctlid) >> 4)
+
+/* Converts a MUXCTL id to a shift position */
+#define MUXCTL_SHIFT(pmux_ctlid) ((pmux_ctlid << 1) & 0x1f)
+
+/* Convenient macro for defining pin group properties */
+#define PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe, mux, pupd)		\
+	{						\
+		.vddio = PMUX_VDDIO_ ## vdd,		\
+		.funcs = {				\
+			PMUX_FUNC_ ## f0,			\
+			PMUX_FUNC_ ## f1,			\
+			PMUX_FUNC_ ## f2,			\
+			PMUX_FUNC_ ## f3,			\
+		},					\
+		.func_safe = PMUX_FUNC_ ## f_safe,		\
+		.ctl_id = mux,				\
+		.pull_id = pupd				\
+	}
+
+/* A normal pin group where the mux name and pull-up name match */
+#define PIN(pg_name, vdd, f0, f1, f2, f3, f_safe)		\
+		PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe,	\
+			MUXCTL_ ## pg_name, PUCTL_ ## pg_name)
+
+/* A pin group where the pull-up name doesn't have a 1-1 mapping */
+#define PINP(pg_name, vdd, f0, f1, f2, f3, f_safe, pupd)		\
+		PINALL(pg_name, vdd, f0, f1, f2, f3, f_safe,	\
+			MUXCTL_ ## pg_name, PUCTL_ ## pupd)
+
+/* A pin group number which is not used */
+#define PIN_RESERVED \
+	PIN(NONE, NONE, NONE, NONE, NONE, NONE, NONE)
+
+const struct tegra_pingroup_desc tegra_soc_pingroups[PINGRP_COUNT] = {
+	PIN(ATA,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
+	PIN(ATB,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
+	PIN(ATC,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
+	PIN(ATD,  NAND,  IDE,    NAND,   GMI,       SDIO4,       IDE),
+	PIN(CDEV1, AUDIO, OSC,   PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC),
+	PIN(CDEV2, AUDIO, OSC,   AHB_CLK, APB_CLK, PLLP_OUT4,    OSC),
+	PIN(CSUS, VI, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK,
+		PLLC_OUT1),
+	PIN(DAP1, AUDIO, DAP1,   RSVD,   GMI,       SDIO2,       DAP1),
+
+	PIN(DAP2, AUDIO, DAP2,   TWC,    RSVD,      GMI,         DAP2),
+	PIN(DAP3, BB,    DAP3,   RSVD,   RSVD,      RSVD,        DAP3),
+	PIN(DAP4, UART,  DAP4,   RSVD,   GMI,       RSVD,        DAP4),
+	PIN(DTA,  VI,    RSVD,   SDIO2,  VI,        RSVD,        RSVD4),
+	PIN(DTB,  VI,    RSVD,   RSVD,   VI,        SPI1,        RSVD1),
+	PIN(DTC,  VI,    RSVD,   RSVD,   VI,        RSVD,        RSVD1),
+	PIN(DTD,  VI,    RSVD,   SDIO2,  VI,        RSVD,        RSVD1),
+	PIN(DTE,  VI,    RSVD,   RSVD,   VI,        SPI1,        RSVD1),
+
+	PINP(GPU, UART,  PWM,    UARTA,  GMI,       RSVD,        RSVD4,
+		GPSLXAU),
+	PIN(GPV,  SD,    PCIE,   RSVD,   RSVD,      RSVD,        PCIE),
+	PIN(I2CP, SYS,   I2C,    RSVD,   RSVD,      RSVD,        RSVD4),
+	PIN(IRTX, UART,  UARTA,  UARTB,  GMI,       SPI4,        UARTB),
+	PIN(IRRX, UART,  UARTA,  UARTB,  GMI,       SPI4,        UARTB),
+	PIN(KBCB, SYS,   KBC,    NAND,   SDIO2,     MIO,         KBC),
+	PIN(KBCA, SYS,   KBC,    NAND,   SDIO2,     EMC_TEST0_DLL, KBC),
+	PINP(PMC, SYS,   PWR_ON, PWR_INTR, RSVD,    RSVD,        PWR_ON, NONE),
+
+	PIN(PTA,  NAND,  I2C2,   HDMI,   GMI,       RSVD,        RSVD4),
+	PIN(RM,   UART,  I2C,    RSVD,   RSVD,      RSVD,        RSVD4),
+	PIN(KBCE, SYS,   KBC,    NAND,   OWR,       RSVD,        KBC),
+	PIN(KBCF, SYS,   KBC,    NAND,   TRACE,     MIO,         KBC),
+	PIN(GMA,  NAND,  UARTE,  SPI3,   GMI,       SDIO4,       SPI3),
+	PIN(GMC,  NAND,  UARTD,  SPI4,   GMI,       SFLASH,      SPI4),
+	PIN(SDMMC1, BB,  SDIO1,  RSVD,   UARTE,     UARTA,       RSVD2),
+	PIN(OWC,  SYS,   OWR,    RSVD,   RSVD,      RSVD,        OWR),
+
+	PIN(GME,  NAND,  RSVD,   DAP5,   GMI,       SDIO4,       GMI),
+	PIN(SDC,  SD,    PWM,    TWC,    SDIO3,     SPI3,        TWC),
+	PIN(SDD,  SD,    UARTA,  PWM,    SDIO3,     SPI3,        PWM),
+	PIN_RESERVED,
+	PINP(SLXA, SD,   PCIE,   SPI4,   SDIO3,     SPI2,        PCIE, CRTP),
+	PIN(SLXC, SD,    SPDIF,  SPI4,   SDIO3,     SPI2,        SPI4),
+	PIN(SLXD, SD,    SPDIF,  SPI4,   SDIO3,     SPI2,        SPI4),
+	PIN(SLXK, SD,    PCIE,   SPI4,   SDIO3,     SPI2,        PCIE),
+
+	PIN(SPDI, AUDIO, SPDIF,  RSVD,   I2C,       SDIO2,       RSVD2),
+	PIN(SPDO, AUDIO, SPDIF,  RSVD,   I2C,       SDIO2,       RSVD2),
+	PIN(SPIA, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
+	PIN(SPIB, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
+	PIN(SPIC, AUDIO, SPI1,   SPI2,   SPI3,      GMI,         GMI),
+	PIN(SPID, AUDIO, SPI2,   SPI1,   SPI2_ALT,  GMI,         GMI),
+	PIN(SPIE, AUDIO, SPI2,   SPI1,   SPI2_ALT,  GMI,         GMI),
+	PIN(SPIF, AUDIO, SPI3,   SPI1,   SPI2,      RSVD,        RSVD4),
+
+	PIN(SPIG, AUDIO, SPI3,   SPI2,   SPI2_ALT,  I2C,         SPI2_ALT),
+	PIN(SPIH, AUDIO, SPI3,   SPI2,   SPI2_ALT,  I2C,         SPI2_ALT),
+	PIN(UAA,  BB,    SPI3,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
+	PIN(UAB,  BB,    SPI2,   MIPI_HS, UARTA,    ULPI,        MIPI_HS),
+	PIN(UAC,  BB,    OWR,    RSVD,   RSVD,      RSVD,        RSVD4),
+	PIN(UAD,  UART,  IRDA,   SPDIF,  UARTA,     SPI4,        SPDIF),
+	PIN(UCA,  UART,  UARTC,  RSVD,   GMI,       RSVD,        RSVD4),
+	PIN(UCB,  UART,  UARTC,  PWM,    GMI,       RSVD,        RSVD4),
+
+	PIN_RESERVED,
+	PIN(ATE,  NAND,  IDE,    NAND,   GMI,       RSVD,        IDE),
+	PIN(KBCC, SYS,   KBC,    NAND,   TRACE,     EMC_TEST1_DLL, KBC),
+	PIN_RESERVED,
+	PIN_RESERVED,
+	PIN(GMB,  NAND,  IDE,    NAND,   GMI,       GMI_INT,     GMI),
+	PIN(GMD,  NAND,  RSVD,   NAND,   GMI,       SFLASH,      GMI),
+	PIN(DDC,  LCD,   I2C2,   RSVD,   RSVD,      RSVD,        RSVD4),
+
+	/* 64 */
+	PINP(LD0,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD1,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD2,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD3,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD4,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD5,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD6,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD7,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+
+	PINP(LD8,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD9,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD10, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD11, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD12, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD13, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD14, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD15, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+
+	PINP(LD16, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LD17),
+	PINP(LD17, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD17),
+	PINP(LHP0, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD21_20),
+	PINP(LHP1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD19_18),
+	PINP(LHP2, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD19_18),
+	PINP(LVP0, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LC),
+	PINP(LVP1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD21_20),
+	PINP(HDINT, LCD, HDMI,   RSVD,   RSVD,      RSVD,     HDMI , LC),
+
+	PINP(LM0,  LCD,  DISPA,  DISPB,  SPI3,      RSVD,     RSVD4, LC),
+	PINP(LM1,  LCD,  DISPA,  DISPB,  RSVD,      CRT,      RSVD3, LC),
+	PINP(LVS,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
+	PINP(LSC0, LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
+	PINP(LSC1, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+	PINP(LSCK, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+	PINP(LDC,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LS),
+	PINP(LCSN, LCD,  DISPA,  DISPB,  SPI3,      RSVD,     RSVD4, LS),
+
+	/* 96 */
+	PINP(LSPI, LCD,  DISPA,  DISPB,  XIO,       HDMI,     DISPA, LC),
+	PINP(LSDA, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+	PINP(LSDI, LCD,  DISPA,  DISPB,  SPI3,      RSVD,     DISPA, LS),
+	PINP(LPW0, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+	PINP(LPW1, LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LS),
+	PINP(LPW2, LCD,  DISPA,  DISPB,  SPI3,      HDMI,     DISPA, LS),
+	PINP(LDI,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD23_22),
+	PINP(LHS,  LCD,  DISPA,  DISPB,  XIO,       RSVD,     RSVD4, LC),
+
+	PINP(LPP,  LCD,  DISPA,  DISPB,  RSVD,      RSVD,     RSVD4, LD23_22),
+	PIN_RESERVED,
+	PIN(KBCD,  SYS,  KBC,    NAND,   SDIO2,     MIO,      KBC),
+	PIN(GPU7,  SYS,  RTCK,   RSVD,   RSVD,      RSVD,     RTCK),
+	PIN(DTF,   VI,   I2C3,   RSVD,   VI,        RSVD,     RSVD4),
+	PIN(UDA,   BB,   SPI1,   RSVD,   UARTD,     ULPI,     RSVD2),
+	PIN(CRTP,  LCD,  CRT,    RSVD,   RSVD,      RSVD,     RSVD),
+	PINP(SDB,  SD,   UARTA,  PWM,    SDIO3,     SPI2,     PWM,   NONE),
+
+	/* these pin groups only have pullup and pull down control */
+	PINALL(CK32,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(DDRC,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(PMCA,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(PMCB,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(PMCC,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(PMCD,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(PMCE,  SYS,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(XM2C,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+	PINALL(XM2D,  DDR,   RSVD, RSVD, RSVD, RSVD,  RSVD, MUXCTL_NONE,
+		PUCTL_NONE),
+};
+
+void pinmux_set_tristate(enum pmux_pingrp pin, int enable)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 *tri = &pmt->pmt_tri[TRISTATE_REG(pin)];
+	u32 reg;
+
+	reg = readl(tri);
+	if (enable)
+		reg |= TRISTATE_MASK(pin);
+	else
+		reg &= ~TRISTATE_MASK(pin);
+	writel(reg, tri);
+}
+
+void pinmux_tristate_enable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, 1);
+}
+
+void pinmux_tristate_disable(enum pmux_pingrp pin)
+{
+	pinmux_set_tristate(pin, 0);
+}
+
+void pinmux_set_pullupdown(enum pmux_pingrp pin, enum pmux_pull pupd)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	enum pmux_pullid pull_id = tegra_soc_pingroups[pin].pull_id;
+	u32 *pull = &pmt->pmt_pull[PULL_REG(pull_id)];
+	u32 mask_bit;
+	u32 reg;
+	mask_bit = PULL_SHIFT(pull_id);
+
+	reg = readl(pull);
+	reg &= ~(0x3 << mask_bit);
+	reg |= pupd << mask_bit;
+	writel(reg, pull);
+}
+
+void pinmux_set_func(enum pmux_pingrp pin, enum pmux_func func)
+{
+	struct pmux_tri_ctlr *pmt =
+			(struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	enum pmux_ctlid mux_id = tegra_soc_pingroups[pin].ctl_id;
+	u32 *muxctl = &pmt->pmt_ctl[MUXCTL_REG(mux_id)];
+	u32 mask_bit;
+	int i, mux = -1;
+	u32 reg;
+
+	assert(pmux_func_isvalid(func));
+
+	/* Handle special values */
+	if (func >= PMUX_FUNC_RSVD1) {
+		mux = (func - PMUX_FUNC_RSVD1) & 0x3;
+	} else {
+		/* Search for the appropriate function */
+		for (i = 0; i < 4; i++) {
+			if (tegra_soc_pingroups[pin].funcs[i] == func) {
+				mux = i;
+				break;
+			}
+		}
+	}
+	assert(mux != -1);
+
+	mask_bit = MUXCTL_SHIFT(mux_id);
+	reg = readl(muxctl);
+	reg &= ~(0x3 << mask_bit);
+	reg |= mux << mask_bit;
+	writel(reg, muxctl);
+}
+
+void pinmux_config_pingroup(struct pingroup_config *config)
+{
+	enum pmux_pingrp pin = config->pingroup;
+
+	pinmux_set_func(pin, config->func);
+	pinmux_set_pullupdown(pin, config->pull);
+	pinmux_set_tristate(pin, config->tristate);
+}
+
+void pinmux_config_table(struct pingroup_config *config, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		pinmux_config_pingroup(&config[i]);
+}
diff --git a/arch/arm/cpu/tegra2-common/sys_info.c b/arch/arm/cpu/tegra2-common/sys_info.c
new file mode 100644
index 0000000..6d11dc1
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/sys_info.c
@@ -0,0 +1,35 @@
+/*
+ * (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 <common.h>
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+/* Print CPU information */
+int print_cpuinfo(void)
+{
+	puts("TEGRA2\n");
+
+	/* TBD: Add printf of major/minor rev info, stepping, etc. */
+	return 0;
+}
+#endif	/* CONFIG_DISPLAY_CPUINFO */
diff --git a/arch/arm/cpu/tegra2-common/timer.c b/arch/arm/cpu/tegra2-common/timer.c
new file mode 100644
index 0000000..b12b12c
--- /dev/null
+++ b/arch/arm/cpu/tegra2-common/timer.c
@@ -0,0 +1,111 @@
+/*
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2 at ti.com>
+ * Syed Moahmmed Khasim <khasim at ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at sysgo.de>
+ * Alex Zuepke <azu at sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj at 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 <common.h>
+#include <asm/io.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* counter runs at 1MHz */
+#define TIMER_CLK	1000000
+#define TIMER_LOAD_VAL	0xffffffff
+
+/* timer without interrupts */
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+	long tmo = usec * (TIMER_CLK / 1000) / 1000;
+	unsigned long now, last = timer_get_us();
+
+	while (tmo > 0) {
+		now = timer_get_us();
+		if (last > now) /* count up timer overflow */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		else
+			tmo -= now - last;
+		last = now;
+	}
+}
+
+ulong get_timer_masked(void)
+{
+	ulong now;
+
+	/* current tick value */
+	now = timer_get_us() / (TIMER_CLK / CONFIG_SYS_HZ);
+
+	if (now >= gd->lastinc)	/* normal mode (non roll) */
+		/* move stamp forward with absolute diff ticks */
+		gd->tbl += (now - gd->lastinc);
+	else	/* we have rollover of incrementer */
+		gd->tbl += ((TIMER_LOAD_VAL / (TIMER_CLK / CONFIG_SYS_HZ))
+				- gd->lastinc) + now;
+	gd->lastinc = now;
+	return gd->tbl;
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
+
+unsigned long timer_get_us(void)
+{
+	struct timerus *timer_base = (struct timerus *)NV_PA_TMRUS_BASE;
+
+	return readl(&timer_base->cntr_1us);
+}
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)))
 
-- 
1.7.5.4



More information about the U-Boot mailing list