diff mbox

[U-Boot,v3,1/4] arm: Tegra2: Add basic NVIDIA Tegra2 SoC support

Message ID 1295471986-2395-2-git-send-email-twarren@nvidia.com
State Superseded
Headers show

Commit Message

Tom Warren Jan. 19, 2011, 9:19 p.m. UTC
Signed-off-by: Tom Warren <twarren@nvidia.com>
---
Changes for V2:
        - Coding style cleanup
        - Move serial driver changes to separate patch
        - Use board/nvidia/ instead of /board/tegra
        - Remove TRUE/FALSE defines
        - Use standard NS16550 register/bit defines in UART init

Changes for V3:
        - Use I/O accessors for Tegra2 HW MMIO register access
        - Allow conditional compile of UARTA/UARTD code to save space

 arch/arm/cpu/armv7/tegra2/Makefile           |   48 +++++
 arch/arm/cpu/armv7/tegra2/board.c            |   91 ++++++++++
 arch/arm/cpu/armv7/tegra2/config.mk          |   28 +++
 arch/arm/cpu/armv7/tegra2/lowlevel_init.S    |   66 +++++++
 arch/arm/cpu/armv7/tegra2/sys_info.c         |   35 ++++
 arch/arm/cpu/armv7/tegra2/timer.c            |  122 +++++++++++++
 arch/arm/include/asm/arch-tegra2/clk_rst.h   |  155 ++++++++++++++++
 arch/arm/include/asm/arch-tegra2/pinmux.h    |   52 ++++++
 arch/arm/include/asm/arch-tegra2/pmc.h       |  125 +++++++++++++
 arch/arm/include/asm/arch-tegra2/sys_proto.h |   33 ++++
 arch/arm/include/asm/arch-tegra2/tegra2.h    |   49 +++++
 arch/arm/include/asm/arch-tegra2/uart.h      |   45 +++++
 board/nvidia/common/board.c                  |  249 ++++++++++++++++++++++++++
 board/nvidia/common/board.h                  |   57 ++++++
 14 files changed, 1155 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/tegra2/Makefile
 create mode 100644 arch/arm/cpu/armv7/tegra2/board.c
 create mode 100644 arch/arm/cpu/armv7/tegra2/config.mk
 create mode 100644 arch/arm/cpu/armv7/tegra2/lowlevel_init.S
 create mode 100644 arch/arm/cpu/armv7/tegra2/sys_info.c
 create mode 100644 arch/arm/cpu/armv7/tegra2/timer.c
 create mode 100644 arch/arm/include/asm/arch-tegra2/clk_rst.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/pinmux.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/pmc.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/tegra2.h
 create mode 100644 arch/arm/include/asm/arch-tegra2/uart.h
 create mode 100644 board/nvidia/common/board.c
 create mode 100644 board/nvidia/common/board.h

Comments

Peter Tyser Jan. 20, 2011, 12:04 a.m. UTC | #1
Hi Tom,
Some last minutes nits:

It looks like some of the new functions can be declared statically.
It'd be nice to do so where possible.

<snip>

> --- /dev/null
> +++ b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S
> @@ -0,0 +1,66 @@
> +/*
> + * Board specific setup info

This is CPU-specific code, correct?

> + *
> + * (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>
> +
> +_TEXT_BASE:
> +	.word	CONFIG_SYS_TEXT_BASE	@ sdram load addr from config file
> +
> +.global invalidate_dcache
> +invalidate_dcache:
> +	mov pc, lr
> +
> +
> +	.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
> +
> +.globl lowlevel_init
> +lowlevel_init:
> +	ldr	sp, SRAM_STACK
> +	str	ip, [sp]
> +	mov	ip, lr
> +	bl	s_init				@ go setup pll, mux & memory
> +	ldr	ip, [sp]
> +	mov	lr, ip
> +
> +	mov	pc, lr				@ back to arch calling code
> +
> +	@ the literal pools origin
> +	.ltorg
> +
> +SRAM_STACK:
> +	.word LOW_LEVEL_SRAM_STACK
> diff --git a/arch/arm/cpu/armv7/tegra2/sys_info.c b/arch/arm/cpu/armv7/tegra2/sys_info.c
> new file mode 100644
> index 0000000..6d11dc1
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/tegra2/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/armv7/tegra2/timer.c b/arch/arm/cpu/armv7/tegra2/timer.c
> new file mode 100644
> index 0000000..858af0f
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/tegra2/timer.c
> @@ -0,0 +1,122 @@
> +/*
> + * (C) Copyright 2010,2011
> + * NVIDIA Corporation <www.nvidia.com>
> + *
> + * (C) Copyright 2008
> + * Texas Instruments
> + *
> + * Richard Woodruff <r-woodruff2@ti.com>
> + * Syed Moahmmed Khasim <khasim@ti.com>
> + *
> + * (C) Copyright 2002
> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
> + * Marius Groeger <mgroeger@sysgo.de>
> + * Alex Zuepke <azu@sysgo.de>
> + *
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering, <garyj@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>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static timerus_t *timer_base = (timerus_t *)NV_PA_TMRUS_BASE;
> +
> +/* counter runs at 1MHz */
> +#define TIMER_CLK	(1000000)
> +#define TIMER_LOAD_VAL	0xffffffff
> +
> +/* timer without interrupts */
> +void reset_timer(void)
> +{
> +	reset_timer_masked();
> +}
> +
> +ulong get_timer(ulong base)
> +{
> +	return get_timer_masked() - base;
> +}
> +
> +void set_timer(ulong t)
> +{
> +	gd->tbl = t;
> +}
> +
> +/* delay x useconds */
> +void __udelay(unsigned long usec)
> +{
> +	long tmo = usec * (TIMER_CLK / 1000) / 1000;
> +	unsigned long now, last = readl(&timer_base->cntr_1us);
> +
> +	while (tmo > 0) {
> +		now = readl(&timer_base->cntr_1us);
> +		if (last > now) /* count up timer overflow */
> +			tmo -= TIMER_LOAD_VAL - last + now;
> +		else
> +			tmo -= now - last;
> +		last = now;
> +	}
> +}
> +
> +void reset_timer_masked(void)
> +{
> +	/* reset time, capture current incrementer value time */
> +	gd->lastinc = readl(&timer_base->cntr_1us) / (TIMER_CLK/CONFIG_SYS_HZ);
> +	gd->tbl = 0;		/* start "advancing" time stamp from 0 */
> +}
> +
> +ulong get_timer_masked(void)
> +{
> +	ulong now;
> +
> +	/* current tick value */
> +	now = readl(&timer_base->cntr_1us) / (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;
> +}
> diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h
> new file mode 100644
> index 0000000..52a7269
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h
> @@ -0,0 +1,155 @@
> +/*
> + *  (C) Copyright 2010,2011
> + *  NVIDIA Corporation <www.nvidia.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _CLK_RST_H_
> +#define _CLK_RST_H_
> +
> +/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
> +

There are a mixture of lower and upper case hex digits in the comments
below - it'd be good to be consistent.  And there should be a space
before each '*/'.  The newline above should be remove too.

> +typedef volatile struct clk_rst_ctlr {
> +	uint crc_rst_src;		/* _RST_SOURCE_0,	0x00*/
> +	uint crc_rst_dev_l;		/* _RST_DEVICES_L_0,	0x04*/
> +	uint crc_rst_dev_h;		/* _RST_DEVICES_H_0,	0x08*/
> +	uint crc_rst_dev_u;		/* _RST_DEVICES_U_0,	0x0C*/
> +	uint crc_clk_out_enb_l;		/* _CLK_OUT_ENB_L_0,	0x10*/
> +	uint crc_clk_out_enb_h;		/* _CLK_OUT_ENB_H_0,	0x14*/
> +	uint crc_clk_out_enb_u;		/* _CLK_OUT_ENB_U_0,	0x18*/
> +	uint crc_reserved0;		/* reserved_0,		0x1c*/
> +	uint crc_cclk_brst_pol;		/* _CCLK_BURST_POLICY_0,0x20*/
> +	uint crc_super_cclk_div;	/* _SUPER_CCLK_DIVIDER_0,0x24*/
> +	uint crc_sclk_brst_pol;		/* _SCLK_BURST_POLICY_0, 0x28*/
> +	uint crc_super_sclk_div;	/* _SUPER_SCLK_DIVIDER_0,0x2C*/
> +	uint crc_clk_sys_rate;		/* _CLK_SYSTEM_RATE_0,	0x30*/
> +	uint crc_prog_dly_clk;		/* _PROG_DLY_CLK_0,	0x34*/
> +	uint crc_aud_sync_clk_rate;	/* _AUDIO_SYNC_CLK_RATE_0,0x38*/
> +	uint crc_reserved1;		/* reserved_1,		0x3c*/
> +	uint crc_cop_clk_skip_plcy;	/* _COP_CLK_SKIP_POLICY_0,0x40*/
> +	uint crc_clk_mask_arm;		/* _CLK_MASK_ARM_0,	0x44*/
> +	uint crc_misc_clk_enb;		/* _MISC_CLK_ENB_0,	0x48*/
> +	uint crc_clk_cpu_cmplx;		/* _CLK_CPU_CMPLX_0,	0x4C*/
> +	uint crc_osc_ctrl;		/* _OSC_CTRL_0,		0x50*/
> +	uint crc_pll_lfsr;		/* _PLL_LFSR_0,		0x54*/
> +	uint crc_osc_freq_det;		/* _OSC_FREQ_DET_0,	0x58*/
> +	uint crc_osc_freq_det_stat;	/* _OSC_FREQ_DET_STATUS_0,0x5C*/
> +	uint crc_reserved2[8];		/* reserved_2[8],	0x60-7C*/
> +
> +	uint crc_pllc_base;		/* _PLLC_BASE_0,	0x80*/
> +	uint crc_pllc_out;		/* _PLLC_OUT_0,		0x84*/
> +	uint crc_reserved3;		/* reserved_3,		0x88*/
> +	uint crc_pllc_misc;		/* _PLLC_MISC_0,	0x8C*/
> +
> +	uint crc_pllm_base;		/* _PLLM_BASE_0,	0x90*/
> +	uint crc_pllm_out;		/* _PLLM_OUT_0,		0x94*/
> +	uint crc_reserved4;		/* reserved_4,		0x98*/
> +	uint crc_pllm_misc;		/* _PLLM_MISC_0,	0x9C*/
> +
> +	uint crc_pllp_base;		/* _PLLP_BASE_0,	0xA0*/
> +	uint crc_pllp_outa;		/* _PLLP_OUTA_0,	0xA4*/
> +	uint crc_pllp_outb;		/* _PLLP_OUTB_0,	0xA8*/
> +	uint crc_pllp_misc;		/* _PLLP_MISC_0,	0xAC*/
> +
> +	uint crc_plla_base;		/* _PLLA_BASE_0,	0xB0*/
> +	uint crc_plla_out;		/* _PLLA_OUT_0,		0xB4*/
> +	uint crc_reserved5;		/* reserved_5,		0xB8*/
> +	uint crc_plla_misc;		/* _PLLA_MISC_0,	0xBC*/
> +
> +	uint crc_pllu_base;		/* _PLLU_BASE_0,	0xC0*/
> +	uint crc_reserved6;		/* _reserved_6,		0xC4*/
> +	uint crc_reserved7;		/* _reserved_7,		0xC8*/
> +	uint crc_pllu_misc;		/* _PLLU_MISC_0,	0xCC*/
> +
> +	uint crc_plld_base;		/* _PLLD_BASE_0,	0xD0*/
> +	uint crc_reserved8;		/* _reserved_8,		0xD4*/
> +	uint crc_reserved9;		/* _reserved_9,		0xD8*/
> +	uint crc_plld_misc;		/* _PLLD_MISC_0,	0xDC*/
> +
> +	uint crc_pllx_base;		/* _PLLX_BASE_0,	0xE0*/
> +	uint crc_pllx_misc;		/* _PLLX_MISC_0,	0xE4*/
> +
> +	uint crc_plle_base;		/* _PLLE_BASE_0,	0xE8*/
> +	uint crc_plle_misc;		/* _PLLE_MISC_0,	0xEC*/
> +
> +	uint crc_plls_base;		/* _PLLS_BASE_0,	0xF0*/
> +	uint crc_plls_misc;		/* _PLLS_MISC_0,	0xF4*/
> +	uint crc_reserved10;		/* _reserved_10,	0xF8*/
> +	uint crc_reserved11;		/* _reserved_11,	0xFC*/
> +
> +	uint crc_clk_src_i2s1;		/*_I2S1_0,		0x100*/
> +	uint crc_clk_src_i2s2;		/*_I2S2_0,		0x104*/
> +	uint crc_clk_src_spdif_out;	/*_SPDIF_OUT_0,		0x108*/
> +	uint crc_clk_src_spdif_in;	/*_SPDIF_IN_0,		0x10C*/
> +	uint crc_clk_src_pwm;		/*_PWM_0,		0x110*/
> +	uint crc_clk_src_spi1;		/*_SPI1_0,		0x114*/
> +	uint crc_clk_src_sbc2;		/*_SBC2_0,		0x118*/
> +	uint crc_clk_src_sbc3;		/*_SBC3_0,		0x11C*/
> +	uint crc_clk_src_xio;		/*_XIO_0,		0x120*/
> +	uint crc_clk_src_i2c1;		/*_I2C1_0,		0x124*/
> +	uint crc_clk_src_dvc_i2c;	/*_DVC_I2C_0,		0x128*/
> +	uint crc_clk_src_twc;		/*_TWC_0,		0x12C*/
> +	uint crc_reserved12;		/*			0x130*/
> +	uint crc_clk_src_sbc1;		/*_SBC1_0,		0x134*/
> +	uint crc_clk_src_disp1;		/*_DISP1_0,		0x138*/
> +	uint crc_clk_src_disp2;		/*_DISP2_0,		0x13C*/
> +	uint crc_clk_src_cve;		/*_CVE_0,		0x140*/
> +	uint crc_clk_src_ide;		/*_IDE_0,		0x144*/
> +	uint crc_clk_src_vi;		/*_VI_0,		0x148*/
> +	uint crc_reserved13;		/*			0x14C*/
> +	uint crc_clk_src_sdmmc1;	/*_SDMMC1_0,		0x150*/
> +	uint crc_clk_src_sdmmc2;	/*_SDMMC2_0,		0x154*/
> +	uint crc_clk_src_g3d;		/*_G3D_0,		0x158*/
> +	uint crc_clk_src_g2d;		/*_G2D_0,		0x15C*/
> +	uint crc_clk_src_ndflash;	/*_NDFLASH_0,		0x160*/
> +	uint crc_clk_src_sdmmc4;	/*_SDMMC4_0,		0x164*/
> +	uint crc_clk_src_vfir;		/*_VFIR_0,		0x168*/
> +	uint crc_clk_src_epp;		/*_EPP_0,		0x16C*/
> +	uint crc_clk_src_mp3;		/*_MPE_0,		0x170*/
> +	uint crc_clk_src_mipi;		/*_MIPI_0,		0x174*/
> +	uint crc_clk_src_uarta;		/*_UARTA_0,		0x178*/
> +	uint crc_clk_src_uartb;		/*_UARTB_0,		0x17C*/
> +	uint crc_clk_src_host1x;	/*_HOST1X_0,		0x180*/
> +	uint crc_reserved14;		/*			0x184*/
> +	uint crc_clk_src_tvo;		/*_TVO_0,		0x188*/
> +	uint crc_clk_src_hdmi;		/*_HDMI_0,		0x18C*/
> +	uint crc_reserved15;		/*			0x190*/
> +	uint crc_clk_src_tvdac;		/*_TVDAC_0,		0x194*/
> +	uint crc_clk_src_i2c2;		/*_I2C2_0,		0x198*/
> +	uint crc_clk_src_emc;		/*_EMC_0,		0x19C*/
> +	uint crc_clk_src_uartc;		/*_UARTC_0,		0x1A0*/
> +	uint crc_reserved16;		/*			0x1A4*/
> +	uint crc_clk_src_vi_sensor;	/*_VI_SENSOR_0,		0x1A8*/
> +	uint crc_reserved17;		/*			0x1AC*/
> +	uint crc_reserved18;		/*			0x1B0*/
> +	uint crc_clk_src_sbc4;		/*_SBC4_0,		0x1B4*/
> +	uint crc_clk_src_i2c3;		/*_I2C3_0,		0x1B8*/
> +	uint crc_clk_src_sdmmc3;	/*_SDMMC3_0,		0x1BC*/
> +	uint crc_clk_src_uartd;		/*_UARTD_0,		0x1C0*/
> +	uint crc_clk_src_uarte;		/*_UARTE_0,		0x1C4*/
> +	uint crc_clk_src_vde;		/*_VDE_0,		0x1C8*/
> +	uint crc_clk_src_owr;		/*_OWR_0,		0x1CC*/
> +	uint crc_clk_src_nor;		/*_NOR_0,		0x1D0*/
> +	uint crc_clk_src_csite;		/*_CSITE_0,		0x1D4*/
> +	uint crc_reserved19[9];		/*			0x1D8-1F8*/
> +	uint crc_clk_src_osc;		/*_OSC_0,		0x1FC*/
> +} clk_rst_ctlr;
> +
> +#endif	/* CLK_RST_H */

<snip>

> diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
> new file mode 100644
> index 0000000..876facb
> --- /dev/null
> +++ b/board/nvidia/common/board.c
> @@ -0,0 +1,249 @@
> +/*
> + *  (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 <ns16550.h>
> +#include <asm/io.h>
> +#include <asm/mach-types.h>
> +#include <asm/arch/tegra2.h>
> +#include <asm/arch/sys_proto.h>
> +#include "board.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +const tegra2_sysinfo sysinfo = {
> +	CONFIG_TEGRA2_BOARD_STRING
> +};
> +
> +/*
> + * Routine: board_init
> + * Description: Early hardware init.
> + */
> +int board_init(void)
> +{
> +	/* boot param addr */
> +	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
> +	/* board id for Linux */
> +	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
> +
> +	return 0;
> +}
> +
> +/*
> + * Routine: timer_init
> + * Description: init the timestamp and lastinc value
> + */
> +int timer_init(void)
> +{
> +	reset_timer();
> +	return 0;
> +}
> +
> +/*
> + * Routine: uart_clock_init
> + * Description: init the PLL and clock for the UART in uart_num
> + */
> +void uart_clock_init(int uart_num)
> +{

Are all these uart functions board-specific?  They look more
CPU-specific.  If that's the case they should be moved somewhere in
arch/arm/*.  Other boards that use the Tegra2 don't want to duplicate
this code or link into Nvidia's board/nvidia directory.

> +	clk_rst_ctlr *const clkrst = (clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
> +	static int pllp_init_done;
> +	u32 reg;
> +
> +	if (!pllp_init_done) {
> +

Remove newline above.

> +		/* Override pllp setup for 216MHz operation. */
> +		reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
> +		reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
> +		writel(reg, clkrst->crc_pllp_base);
> +
> +		reg |= PLL_ENABLE;
> +		writel(reg, clkrst->crc_pllp_base);
> +
> +		reg &= ~PLL_BYPASS;
> +		writel(reg, clkrst->crc_pllp_base);
> +
> +		pllp_init_done++;
> +	}
> +
> +	/* Now do the UART reset/clock enable based on uart_num */
> +#if CONFIG_TEGRA2_ENABLE_UARTA
> +	if (uart_num == UART_A) {
> +		/* Assert Reset to UART */
> +		reg = readl(clkrst->crc_rst_dev_l);
> +		reg |= SWR_UARTA_RST;		/* SWR_UARTA_RST = 1 */
> +		writel(reg, clkrst->crc_rst_dev_l);
> +
> +		/* Enable clk to UART */
> +		reg = readl(clkrst->crc_clk_out_enb_l);
> +		reg |= CLK_ENB_UARTA;		/* CLK_ENB_UARTA = 1 */
> +		writel(reg, clkrst->crc_clk_out_enb_l);
> +
> +		/* Enable pllp_out0 to UART */
> +		reg = readl(clkrst->crc_clk_src_uarta);
> +		reg &= 0x3FFFFFFF;	/* UARTA_CLK_SRC = 00, PLLP_OUT0 */
> +		writel(reg, clkrst->crc_clk_src_uarta);
> +
> +		/* wait for 2us */
> +		udelay(2);
> +
> +		/* De-assert reset to UART */
> +		reg = readl(clkrst->crc_rst_dev_l);
> +		reg &= ~SWR_UARTA_RST;		/* SWR_UARTA_RST = 0 */
> +		writel(reg, clkrst->crc_rst_dev_l);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTA */
> +#if CONFIG_TEGRA2_ENABLE_UARTD
> +	if (uart_num == UART_D) {
> +		/* Assert Reset to UART */
> +		reg = readl(clkrst->crc_rst_dev_u);
> +		reg |= SWR_UARTD_RST;		/* SWR_UARTD_RST = 1 */
> +		writel(reg, clkrst->crc_rst_dev_u);
> +
> +		/* Enable clk to UART */
> +		reg = readl(clkrst->crc_clk_out_enb_u);
> +		reg |= CLK_ENB_UARTD;		/* CLK_ENB_UARTD = 1 */
> +		writel(reg, clkrst->crc_clk_out_enb_u);
> +
> +		/* Enable pllp_out0 to UART */
> +		reg = readl(clkrst->crc_clk_src_uartd);
> +		reg &= 0x3FFFFFFF;	/* UARTD_CLK_SRC = 00, PLLP_OUT0 */
> +		writel(reg, clkrst->crc_clk_src_uartd);
> +
> +		/* wait for 2us */
> +		udelay(2);
> +
> +		/* De-assert reset to UART */
> +		reg = readl(clkrst->crc_rst_dev_u);
> +		reg &= ~SWR_UARTD_RST;		/* SWR_UARTD_RST = 0 */
> +		writel(reg, clkrst->crc_rst_dev_u);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +}
> +
> +/*
> + * Routine: pin_mux_uart
> + * Description: setup the pin muxes/tristate values for UART based on uart_num
> + */
> +void pin_mux_uart(int uart_num)
> +{
> +	pinmux_tri_ctlr *const pmt = (pinmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
> +	u32 reg;
> +
> +#if CONFIG_TEGRA2_ENABLE_UARTA
> +	if (uart_num  == UART_A) {
> +		reg = readl(pmt->pmt_ctl_c);
> +		reg &= 0xFFF0FFFF;	/* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
> +		writel(reg, pmt->pmt_ctl_c);
> +
> +		reg = readl(pmt->pmt_tri_a);
> +		reg &= ~Z_IRRX;		/* Z_IRRX = normal (0) */
> +		reg &= ~Z_IRTX;		/* Z_IRTX = normal (0) */
> +		writel(reg, pmt->pmt_tri_a);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTA */
> +#if CONFIG_TEGRA2_ENABLE_UARTD
> +	if (uart_num == UART_D) {
> +		reg = readl(pmt->pmt_ctl_b);
> +		reg &= 0xFFFFFFF3;	/* GMC_SEL [3:2] = 00, UARTD */
> +		writel(reg, pmt->pmt_ctl_b);
> +
> +		reg = readl(pmt->pmt_tri_a);
> +		reg &= ~Z_GMC;		/* Z_GMC = normal (0) */
> +		writel(reg, pmt->pmt_tri_a);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +}
> +
> +void setup_uart(uart_ctlr *u)
> +{
> +	u32 reg;
> +
> +	/* Prepare the divisor value */
> +	reg = NVRM_PLLP_FIXED_FREQ_KHZ * 1000 / NV_DEFAULT_DEBUG_BAUD / 16;
> +
> +	/* Set up UART parameters */
> +	writel(UART_LCR_DLAB, u->uart_lcr);
> +	writel(reg, u->uart_thr_dlab_0);
> +	writel(0, u->uart_ier_dlab_0);
> +	writel(0, u->uart_lcr);			/* clear DLAB */
> +	writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN | \
> +		UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR), u->uart_iir_fcr);
> +	writel(0, u->uart_ier_dlab_0);
> +	writel(UART_LCR_WLS_8, u->uart_lcr);	/* 8N1 */
> +	writel(UART_MCR_RTS, u->uart_mcr);
> +	writel(0, u->uart_msr);
> +	writel(0, u->uart_spr);
> +	writel(0, u->uart_irda_csr);
> +	writel(0, u->uart_asr);
> +	writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN), u->uart_iir_fcr);
> +
> +	/* Flush any old characters out of the RX FIFO */
> +	reg = readl(u->uart_lsr);
> +
> +	while (reg & UART_LSR_DR) {
> +		reg = readl(u->uart_thr_dlab_0);
> +		reg = readl(u->uart_lsr);
> +	}
> +}
> +
> +/*
> + * Routine: init_uart
> + * Description: init the UART clocks, muxes, and baudrate/parity/etc.
> + */
> +void init_uart(int uart_num)
> +{
> +#if CONFIG_TEGRA2_ENABLE_UARTA
> +	if (uart_num == UART_A) {
> +		uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTA_BASE;
> +
> +		uart_clock_init(UART_A);
> +
> +		/* Enable UARTA - uses config 0 */
> +		pin_mux_uart(UART_A);
> +
> +		setup_uart(uart);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +#if CONFIG_TEGRA2_ENABLE_UARTD
> +	if (uart_num == UART_D) {
> +		uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTD_BASE;
> +
> +		uart_clock_init(UART_D);
> +
> +		/* Enable UARTD - uses config 0 */
> +		pin_mux_uart(UART_D);
> +
> +		setup_uart(uart);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +}
> +
> +void uart_init(void)
> +{
> +#if (CONFIG_TEGRA2_ENABLE_UARTA)
> +	init_uart(UART_A);
> +#endif
> +#if (CONFIG_TEGRA2_ENABLE_UARTD)
> +	init_uart(UART_D);
> +#endif
> +}
> diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
> new file mode 100644
> index 0000000..d49e978
> --- /dev/null
> +++ b/board/nvidia/common/board.h
> @@ -0,0 +1,57 @@
> +/*
> + *  (C) Copyright 2010,2011
> + *  NVIDIA Corporation <www.nvidia.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _COMMON_BOARD_H_
> +#define _COMMON_BOARD_H_
> +
> +#include <asm/arch/clk_rst.h>
> +#include <asm/arch/pinmux.h>
> +#include <asm/arch/uart.h>
> +
> +#define NVRM_PLLP_FIXED_FREQ_KHZ	216000
> +#define NV_DEFAULT_DEBUG_BAUD		115200
> +
> +#define PLL_BYPASS		(1 << 31)
> +#define PLL_ENABLE		(1 << 30)
> +#define PLL_BASE_OVRRIDE	(1 << 28)
> +#define PLL_DIVP		(1 << 20)	/* post divider, b22:20 */
> +#define PLL_DIVM		0x0C		/* input divider, b4:0 */
> +
> +#define SWR_UARTD_RST		(1 << 2)
> +#define CLK_ENB_UARTD		(1 << 2)
> +#define SWR_UARTA_RST		(1 << 6)
> +#define CLK_ENB_UARTA		(1 << 6)
> +
> +#define Z_GMC			(1 << 29)
> +#define Z_IRRX			(1 << 20)
> +#define Z_IRTX			(1 << 19)
> +
> +enum {
> +	UART_A = 1,
> +	UART_B,
> +	UART_C,
> +	UART_D,
> +	UART_E
> +};
> +
> +#endif /* _COMMON_BOARD_H_ */

Same comment about this header.  It looks CPU-specific?  If so, it
should be moved to somewhere in arch/arm.

Lastly, its generally good to CC people that have commented on your
previous patches (eg Wolfgang and myself) as they are likely to provide
more feedback and CC-ing them directly helps to ensure your
re-submission doesn't get lost in their inboxes.  I promise those are my
last comments:)

Best,
Peter
Graeme Russ Jan. 20, 2011, 12:20 a.m. UTC | #2
On Thu, Jan 20, 2011 at 8:19 AM, Tom Warren <twarren.nvidia@gmail.com> wrote:

> +
> +/*
> + * Routine: uart_clock_init
> + * Description: init the PLL and clock for the UART in uart_num
> + */
> +void uart_clock_init(int uart_num)
> +{
> +       clk_rst_ctlr *const clkrst = (clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
> +       static int pllp_init_done;
> +       u32 reg;
> +
> +       if (!pllp_init_done) {
> +
> +               /* Override pllp setup for 216MHz operation. */
> +               reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
> +               reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
> +               writel(reg, clkrst->crc_pllp_base);
> +
> +               reg |= PLL_ENABLE;
> +               writel(reg, clkrst->crc_pllp_base);

Is this correct? Should it not be writel(reg, &clkrst->crc_pllp_base);

Similarly for other readl()'s and writel()'s

Regards,

Graeme
Wolfgang Denk Jan. 20, 2011, 8:40 a.m. UTC | #3
Dear Tom Warren,

In message <1295471986-2395-2-git-send-email-twarren@nvidia.com> you wrote:
> Signed-off-by: Tom Warren <twarren@nvidia.com>

checkpatch.pl reports:

	total: 6 errors, 12 warnings, 1155 lines checked

	/tmp/patch has style problems, please review. 

Please clean up.

Best regards,

Wolfgang Denk
Tom Warren Jan. 20, 2011, 4:41 p.m. UTC | #4
On Wed, Jan 19, 2011 at 5:04 PM, Peter Tyser <ptyser@xes-inc.com> wrote:
> Hi Tom,
> Some last minutes nits:
>
> It looks like some of the new functions can be declared statically.
> It'd be nice to do so where possible.
Which functions, Peter? Please point them out specifically, thanks.

>
> <snip>
>
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S
>> @@ -0,0 +1,66 @@
>> +/*
>> + * Board specific setup info
>
> This is CPU-specific code, correct?
Yes - I'll change the comment.

>
>> + *
>> + * (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>
>> +
>> +_TEXT_BASE:
>> +     .word   CONFIG_SYS_TEXT_BASE    @ sdram load addr from config file
>> +
>> +.global invalidate_dcache
>> +invalidate_dcache:
>> +     mov pc, lr
>> +
>> +
>> +     .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
>> +
>> +.globl lowlevel_init
>> +lowlevel_init:
>> +     ldr     sp, SRAM_STACK
>> +     str     ip, [sp]
>> +     mov     ip, lr
>> +     bl      s_init                          @ go setup pll, mux & memory
>> +     ldr     ip, [sp]
>> +     mov     lr, ip
>> +
>> +     mov     pc, lr                          @ back to arch calling code
>> +
>> +     @ the literal pools origin
>> +     .ltorg
>> +
>> +SRAM_STACK:
>> +     .word LOW_LEVEL_SRAM_STACK
>> diff --git a/arch/arm/cpu/armv7/tegra2/sys_info.c b/arch/arm/cpu/armv7/tegra2/sys_info.c
>> new file mode 100644
>> index 0000000..6d11dc1
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv7/tegra2/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/armv7/tegra2/timer.c b/arch/arm/cpu/armv7/tegra2/timer.c
>> new file mode 100644
>> index 0000000..858af0f
>> --- /dev/null
>> +++ b/arch/arm/cpu/armv7/tegra2/timer.c
>> @@ -0,0 +1,122 @@
>> +/*
>> + * (C) Copyright 2010,2011
>> + * NVIDIA Corporation <www.nvidia.com>
>> + *
>> + * (C) Copyright 2008
>> + * Texas Instruments
>> + *
>> + * Richard Woodruff <r-woodruff2@ti.com>
>> + * Syed Moahmmed Khasim <khasim@ti.com>
>> + *
>> + * (C) Copyright 2002
>> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
>> + * Marius Groeger <mgroeger@sysgo.de>
>> + * Alex Zuepke <azu@sysgo.de>
>> + *
>> + * (C) Copyright 2002
>> + * Gary Jennejohn, DENX Software Engineering, <garyj@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>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +static timerus_t *timer_base = (timerus_t *)NV_PA_TMRUS_BASE;
>> +
>> +/* counter runs at 1MHz */
>> +#define TIMER_CLK    (1000000)
>> +#define TIMER_LOAD_VAL       0xffffffff
>> +
>> +/* timer without interrupts */
>> +void reset_timer(void)
>> +{
>> +     reset_timer_masked();
>> +}
>> +
>> +ulong get_timer(ulong base)
>> +{
>> +     return get_timer_masked() - base;
>> +}
>> +
>> +void set_timer(ulong t)
>> +{
>> +     gd->tbl = t;
>> +}
>> +
>> +/* delay x useconds */
>> +void __udelay(unsigned long usec)
>> +{
>> +     long tmo = usec * (TIMER_CLK / 1000) / 1000;
>> +     unsigned long now, last = readl(&timer_base->cntr_1us);
>> +
>> +     while (tmo > 0) {
>> +             now = readl(&timer_base->cntr_1us);
>> +             if (last > now) /* count up timer overflow */
>> +                     tmo -= TIMER_LOAD_VAL - last + now;
>> +             else
>> +                     tmo -= now - last;
>> +             last = now;
>> +     }
>> +}
>> +
>> +void reset_timer_masked(void)
>> +{
>> +     /* reset time, capture current incrementer value time */
>> +     gd->lastinc = readl(&timer_base->cntr_1us) / (TIMER_CLK/CONFIG_SYS_HZ);
>> +     gd->tbl = 0;            /* start "advancing" time stamp from 0 */
>> +}
>> +
>> +ulong get_timer_masked(void)
>> +{
>> +     ulong now;
>> +
>> +     /* current tick value */
>> +     now = readl(&timer_base->cntr_1us) / (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;
>> +}
>> diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h
>> new file mode 100644
>> index 0000000..52a7269
>> --- /dev/null
>> +++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h
>> @@ -0,0 +1,155 @@
>> +/*
>> + *  (C) Copyright 2010,2011
>> + *  NVIDIA Corporation <www.nvidia.com>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +#ifndef _CLK_RST_H_
>> +#define _CLK_RST_H_
>> +
>> +/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
>> +
>
> There are a mixture of lower and upper case hex digits in the comments
> below - it'd be good to be consistent.  And there should be a space
> before each '*/'.  The newline above should be remove too.
>
Will do. I had changed this once already as per your previous comments, but
it must have gotten lost in the V3 patching.

>> +typedef volatile struct clk_rst_ctlr {
>> +     uint crc_rst_src;               /* _RST_SOURCE_0,       0x00*/
>> +     uint crc_rst_dev_l;             /* _RST_DEVICES_L_0,    0x04*/
>> +     uint crc_rst_dev_h;             /* _RST_DEVICES_H_0,    0x08*/
>> +     uint crc_rst_dev_u;             /* _RST_DEVICES_U_0,    0x0C*/
>> +     uint crc_clk_out_enb_l;         /* _CLK_OUT_ENB_L_0,    0x10*/
>> +     uint crc_clk_out_enb_h;         /* _CLK_OUT_ENB_H_0,    0x14*/
>> +     uint crc_clk_out_enb_u;         /* _CLK_OUT_ENB_U_0,    0x18*/
>> +     uint crc_reserved0;             /* reserved_0,          0x1c*/
>> +     uint crc_cclk_brst_pol;         /* _CCLK_BURST_POLICY_0,0x20*/
>> +     uint crc_super_cclk_div;        /* _SUPER_CCLK_DIVIDER_0,0x24*/
>> +     uint crc_sclk_brst_pol;         /* _SCLK_BURST_POLICY_0, 0x28*/
>> +     uint crc_super_sclk_div;        /* _SUPER_SCLK_DIVIDER_0,0x2C*/
>> +     uint crc_clk_sys_rate;          /* _CLK_SYSTEM_RATE_0,  0x30*/
>> +     uint crc_prog_dly_clk;          /* _PROG_DLY_CLK_0,     0x34*/
>> +     uint crc_aud_sync_clk_rate;     /* _AUDIO_SYNC_CLK_RATE_0,0x38*/
>> +     uint crc_reserved1;             /* reserved_1,          0x3c*/
>> +     uint crc_cop_clk_skip_plcy;     /* _COP_CLK_SKIP_POLICY_0,0x40*/
>> +     uint crc_clk_mask_arm;          /* _CLK_MASK_ARM_0,     0x44*/
>> +     uint crc_misc_clk_enb;          /* _MISC_CLK_ENB_0,     0x48*/
>> +     uint crc_clk_cpu_cmplx;         /* _CLK_CPU_CMPLX_0,    0x4C*/
>> +     uint crc_osc_ctrl;              /* _OSC_CTRL_0,         0x50*/
>> +     uint crc_pll_lfsr;              /* _PLL_LFSR_0,         0x54*/
>> +     uint crc_osc_freq_det;          /* _OSC_FREQ_DET_0,     0x58*/
>> +     uint crc_osc_freq_det_stat;     /* _OSC_FREQ_DET_STATUS_0,0x5C*/
>> +     uint crc_reserved2[8];          /* reserved_2[8],       0x60-7C*/
>> +
>> +     uint crc_pllc_base;             /* _PLLC_BASE_0,        0x80*/
>> +     uint crc_pllc_out;              /* _PLLC_OUT_0,         0x84*/
>> +     uint crc_reserved3;             /* reserved_3,          0x88*/
>> +     uint crc_pllc_misc;             /* _PLLC_MISC_0,        0x8C*/
>> +
>> +     uint crc_pllm_base;             /* _PLLM_BASE_0,        0x90*/
>> +     uint crc_pllm_out;              /* _PLLM_OUT_0,         0x94*/
>> +     uint crc_reserved4;             /* reserved_4,          0x98*/
>> +     uint crc_pllm_misc;             /* _PLLM_MISC_0,        0x9C*/
>> +
>> +     uint crc_pllp_base;             /* _PLLP_BASE_0,        0xA0*/
>> +     uint crc_pllp_outa;             /* _PLLP_OUTA_0,        0xA4*/
>> +     uint crc_pllp_outb;             /* _PLLP_OUTB_0,        0xA8*/
>> +     uint crc_pllp_misc;             /* _PLLP_MISC_0,        0xAC*/
>> +
>> +     uint crc_plla_base;             /* _PLLA_BASE_0,        0xB0*/
>> +     uint crc_plla_out;              /* _PLLA_OUT_0,         0xB4*/
>> +     uint crc_reserved5;             /* reserved_5,          0xB8*/
>> +     uint crc_plla_misc;             /* _PLLA_MISC_0,        0xBC*/
>> +
>> +     uint crc_pllu_base;             /* _PLLU_BASE_0,        0xC0*/
>> +     uint crc_reserved6;             /* _reserved_6,         0xC4*/
>> +     uint crc_reserved7;             /* _reserved_7,         0xC8*/
>> +     uint crc_pllu_misc;             /* _PLLU_MISC_0,        0xCC*/
>> +
>> +     uint crc_plld_base;             /* _PLLD_BASE_0,        0xD0*/
>> +     uint crc_reserved8;             /* _reserved_8,         0xD4*/
>> +     uint crc_reserved9;             /* _reserved_9,         0xD8*/
>> +     uint crc_plld_misc;             /* _PLLD_MISC_0,        0xDC*/
>> +
>> +     uint crc_pllx_base;             /* _PLLX_BASE_0,        0xE0*/
>> +     uint crc_pllx_misc;             /* _PLLX_MISC_0,        0xE4*/
>> +
>> +     uint crc_plle_base;             /* _PLLE_BASE_0,        0xE8*/
>> +     uint crc_plle_misc;             /* _PLLE_MISC_0,        0xEC*/
>> +
>> +     uint crc_plls_base;             /* _PLLS_BASE_0,        0xF0*/
>> +     uint crc_plls_misc;             /* _PLLS_MISC_0,        0xF4*/
>> +     uint crc_reserved10;            /* _reserved_10,        0xF8*/
>> +     uint crc_reserved11;            /* _reserved_11,        0xFC*/
>> +
>> +     uint crc_clk_src_i2s1;          /*_I2S1_0,              0x100*/
>> +     uint crc_clk_src_i2s2;          /*_I2S2_0,              0x104*/
>> +     uint crc_clk_src_spdif_out;     /*_SPDIF_OUT_0,         0x108*/
>> +     uint crc_clk_src_spdif_in;      /*_SPDIF_IN_0,          0x10C*/
>> +     uint crc_clk_src_pwm;           /*_PWM_0,               0x110*/
>> +     uint crc_clk_src_spi1;          /*_SPI1_0,              0x114*/
>> +     uint crc_clk_src_sbc2;          /*_SBC2_0,              0x118*/
>> +     uint crc_clk_src_sbc3;          /*_SBC3_0,              0x11C*/
>> +     uint crc_clk_src_xio;           /*_XIO_0,               0x120*/
>> +     uint crc_clk_src_i2c1;          /*_I2C1_0,              0x124*/
>> +     uint crc_clk_src_dvc_i2c;       /*_DVC_I2C_0,           0x128*/
>> +     uint crc_clk_src_twc;           /*_TWC_0,               0x12C*/
>> +     uint crc_reserved12;            /*                      0x130*/
>> +     uint crc_clk_src_sbc1;          /*_SBC1_0,              0x134*/
>> +     uint crc_clk_src_disp1;         /*_DISP1_0,             0x138*/
>> +     uint crc_clk_src_disp2;         /*_DISP2_0,             0x13C*/
>> +     uint crc_clk_src_cve;           /*_CVE_0,               0x140*/
>> +     uint crc_clk_src_ide;           /*_IDE_0,               0x144*/
>> +     uint crc_clk_src_vi;            /*_VI_0,                0x148*/
>> +     uint crc_reserved13;            /*                      0x14C*/
>> +     uint crc_clk_src_sdmmc1;        /*_SDMMC1_0,            0x150*/
>> +     uint crc_clk_src_sdmmc2;        /*_SDMMC2_0,            0x154*/
>> +     uint crc_clk_src_g3d;           /*_G3D_0,               0x158*/
>> +     uint crc_clk_src_g2d;           /*_G2D_0,               0x15C*/
>> +     uint crc_clk_src_ndflash;       /*_NDFLASH_0,           0x160*/
>> +     uint crc_clk_src_sdmmc4;        /*_SDMMC4_0,            0x164*/
>> +     uint crc_clk_src_vfir;          /*_VFIR_0,              0x168*/
>> +     uint crc_clk_src_epp;           /*_EPP_0,               0x16C*/
>> +     uint crc_clk_src_mp3;           /*_MPE_0,               0x170*/
>> +     uint crc_clk_src_mipi;          /*_MIPI_0,              0x174*/
>> +     uint crc_clk_src_uarta;         /*_UARTA_0,             0x178*/
>> +     uint crc_clk_src_uartb;         /*_UARTB_0,             0x17C*/
>> +     uint crc_clk_src_host1x;        /*_HOST1X_0,            0x180*/
>> +     uint crc_reserved14;            /*                      0x184*/
>> +     uint crc_clk_src_tvo;           /*_TVO_0,               0x188*/
>> +     uint crc_clk_src_hdmi;          /*_HDMI_0,              0x18C*/
>> +     uint crc_reserved15;            /*                      0x190*/
>> +     uint crc_clk_src_tvdac;         /*_TVDAC_0,             0x194*/
>> +     uint crc_clk_src_i2c2;          /*_I2C2_0,              0x198*/
>> +     uint crc_clk_src_emc;           /*_EMC_0,               0x19C*/
>> +     uint crc_clk_src_uartc;         /*_UARTC_0,             0x1A0*/
>> +     uint crc_reserved16;            /*                      0x1A4*/
>> +     uint crc_clk_src_vi_sensor;     /*_VI_SENSOR_0,         0x1A8*/
>> +     uint crc_reserved17;            /*                      0x1AC*/
>> +     uint crc_reserved18;            /*                      0x1B0*/
>> +     uint crc_clk_src_sbc4;          /*_SBC4_0,              0x1B4*/
>> +     uint crc_clk_src_i2c3;          /*_I2C3_0,              0x1B8*/
>> +     uint crc_clk_src_sdmmc3;        /*_SDMMC3_0,            0x1BC*/
>> +     uint crc_clk_src_uartd;         /*_UARTD_0,             0x1C0*/
>> +     uint crc_clk_src_uarte;         /*_UARTE_0,             0x1C4*/
>> +     uint crc_clk_src_vde;           /*_VDE_0,               0x1C8*/
>> +     uint crc_clk_src_owr;           /*_OWR_0,               0x1CC*/
>> +     uint crc_clk_src_nor;           /*_NOR_0,               0x1D0*/
>> +     uint crc_clk_src_csite;         /*_CSITE_0,             0x1D4*/
>> +     uint crc_reserved19[9];         /*                      0x1D8-1F8*/
>> +     uint crc_clk_src_osc;           /*_OSC_0,               0x1FC*/
>> +} clk_rst_ctlr;
>> +
>> +#endif       /* CLK_RST_H */
>
> <snip>
>
>> diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
>> new file mode 100644
>> index 0000000..876facb
>> --- /dev/null
>> +++ b/board/nvidia/common/board.c
>> @@ -0,0 +1,249 @@
>> +/*
>> + *  (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 <ns16550.h>
>> +#include <asm/io.h>
>> +#include <asm/mach-types.h>
>> +#include <asm/arch/tegra2.h>
>> +#include <asm/arch/sys_proto.h>
>> +#include "board.h"
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +const tegra2_sysinfo sysinfo = {
>> +     CONFIG_TEGRA2_BOARD_STRING
>> +};
>> +
>> +/*
>> + * Routine: board_init
>> + * Description: Early hardware init.
>> + */
>> +int board_init(void)
>> +{
>> +     /* boot param addr */
>> +     gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
>> +     /* board id for Linux */
>> +     gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
>> +
>> +     return 0;
>> +}
>> +
>> +/*
>> + * Routine: timer_init
>> + * Description: init the timestamp and lastinc value
>> + */
>> +int timer_init(void)
>> +{
>> +     reset_timer();
>> +     return 0;
>> +}
>> +
>> +/*
>> + * Routine: uart_clock_init
>> + * Description: init the PLL and clock for the UART in uart_num
>> + */
>> +void uart_clock_init(int uart_num)
>> +{
>
> Are all these uart functions board-specific?  They look more
> CPU-specific.  If that's the case they should be moved somewhere in
> arch/arm/*.  Other boards that use the Tegra2 don't want to duplicate
> this code or link into Nvidia's board/nvidia directory.
It's Tegra2 SoC-specific - that's not the CPU, per se.  I guess I could move
it to arch/arm/cpu/armv7/tegra2, if you think it's important enough.

>
>> +     clk_rst_ctlr *const clkrst = (clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
>> +     static int pllp_init_done;
>> +     u32 reg;
>> +
>> +     if (!pllp_init_done) {
>> +
>
> Remove newline above.
OK.
>
>> +             /* Override pllp setup for 216MHz operation. */
>> +             reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
>> +             reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
>> +             writel(reg, clkrst->crc_pllp_base);
>> +
>> +             reg |= PLL_ENABLE;
>> +             writel(reg, clkrst->crc_pllp_base);
>> +
>> +             reg &= ~PLL_BYPASS;
>> +             writel(reg, clkrst->crc_pllp_base);
>> +
>> +             pllp_init_done++;
>> +     }
>> +
>> +     /* Now do the UART reset/clock enable based on uart_num */
>> +#if CONFIG_TEGRA2_ENABLE_UARTA
>> +     if (uart_num == UART_A) {
>> +             /* Assert Reset to UART */
>> +             reg = readl(clkrst->crc_rst_dev_l);
>> +             reg |= SWR_UARTA_RST;           /* SWR_UARTA_RST = 1 */
>> +             writel(reg, clkrst->crc_rst_dev_l);
>> +
>> +             /* Enable clk to UART */
>> +             reg = readl(clkrst->crc_clk_out_enb_l);
>> +             reg |= CLK_ENB_UARTA;           /* CLK_ENB_UARTA = 1 */
>> +             writel(reg, clkrst->crc_clk_out_enb_l);
>> +
>> +             /* Enable pllp_out0 to UART */
>> +             reg = readl(clkrst->crc_clk_src_uarta);
>> +             reg &= 0x3FFFFFFF;      /* UARTA_CLK_SRC = 00, PLLP_OUT0 */
>> +             writel(reg, clkrst->crc_clk_src_uarta);
>> +
>> +             /* wait for 2us */
>> +             udelay(2);
>> +
>> +             /* De-assert reset to UART */
>> +             reg = readl(clkrst->crc_rst_dev_l);
>> +             reg &= ~SWR_UARTA_RST;          /* SWR_UARTA_RST = 0 */
>> +             writel(reg, clkrst->crc_rst_dev_l);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTA */
>> +#if CONFIG_TEGRA2_ENABLE_UARTD
>> +     if (uart_num == UART_D) {
>> +             /* Assert Reset to UART */
>> +             reg = readl(clkrst->crc_rst_dev_u);
>> +             reg |= SWR_UARTD_RST;           /* SWR_UARTD_RST = 1 */
>> +             writel(reg, clkrst->crc_rst_dev_u);
>> +
>> +             /* Enable clk to UART */
>> +             reg = readl(clkrst->crc_clk_out_enb_u);
>> +             reg |= CLK_ENB_UARTD;           /* CLK_ENB_UARTD = 1 */
>> +             writel(reg, clkrst->crc_clk_out_enb_u);
>> +
>> +             /* Enable pllp_out0 to UART */
>> +             reg = readl(clkrst->crc_clk_src_uartd);
>> +             reg &= 0x3FFFFFFF;      /* UARTD_CLK_SRC = 00, PLLP_OUT0 */
>> +             writel(reg, clkrst->crc_clk_src_uartd);
>> +
>> +             /* wait for 2us */
>> +             udelay(2);
>> +
>> +             /* De-assert reset to UART */
>> +             reg = readl(clkrst->crc_rst_dev_u);
>> +             reg &= ~SWR_UARTD_RST;          /* SWR_UARTD_RST = 0 */
>> +             writel(reg, clkrst->crc_rst_dev_u);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +}
>> +
>> +/*
>> + * Routine: pin_mux_uart
>> + * Description: setup the pin muxes/tristate values for UART based on uart_num
>> + */
>> +void pin_mux_uart(int uart_num)
>> +{
>> +     pinmux_tri_ctlr *const pmt = (pinmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
>> +     u32 reg;
>> +
>> +#if CONFIG_TEGRA2_ENABLE_UARTA
>> +     if (uart_num  == UART_A) {
>> +             reg = readl(pmt->pmt_ctl_c);
>> +             reg &= 0xFFF0FFFF;      /* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
>> +             writel(reg, pmt->pmt_ctl_c);
>> +
>> +             reg = readl(pmt->pmt_tri_a);
>> +             reg &= ~Z_IRRX;         /* Z_IRRX = normal (0) */
>> +             reg &= ~Z_IRTX;         /* Z_IRTX = normal (0) */
>> +             writel(reg, pmt->pmt_tri_a);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTA */
>> +#if CONFIG_TEGRA2_ENABLE_UARTD
>> +     if (uart_num == UART_D) {
>> +             reg = readl(pmt->pmt_ctl_b);
>> +             reg &= 0xFFFFFFF3;      /* GMC_SEL [3:2] = 00, UARTD */
>> +             writel(reg, pmt->pmt_ctl_b);
>> +
>> +             reg = readl(pmt->pmt_tri_a);
>> +             reg &= ~Z_GMC;          /* Z_GMC = normal (0) */
>> +             writel(reg, pmt->pmt_tri_a);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +}
>> +
>> +void setup_uart(uart_ctlr *u)
>> +{
>> +     u32 reg;
>> +
>> +     /* Prepare the divisor value */
>> +     reg = NVRM_PLLP_FIXED_FREQ_KHZ * 1000 / NV_DEFAULT_DEBUG_BAUD / 16;
>> +
>> +     /* Set up UART parameters */
>> +     writel(UART_LCR_DLAB, u->uart_lcr);
>> +     writel(reg, u->uart_thr_dlab_0);
>> +     writel(0, u->uart_ier_dlab_0);
>> +     writel(0, u->uart_lcr);                 /* clear DLAB */
>> +     writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN | \
>> +             UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR), u->uart_iir_fcr);
>> +     writel(0, u->uart_ier_dlab_0);
>> +     writel(UART_LCR_WLS_8, u->uart_lcr);    /* 8N1 */
>> +     writel(UART_MCR_RTS, u->uart_mcr);
>> +     writel(0, u->uart_msr);
>> +     writel(0, u->uart_spr);
>> +     writel(0, u->uart_irda_csr);
>> +     writel(0, u->uart_asr);
>> +     writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN), u->uart_iir_fcr);
>> +
>> +     /* Flush any old characters out of the RX FIFO */
>> +     reg = readl(u->uart_lsr);
>> +
>> +     while (reg & UART_LSR_DR) {
>> +             reg = readl(u->uart_thr_dlab_0);
>> +             reg = readl(u->uart_lsr);
>> +     }
>> +}
>> +
>> +/*
>> + * Routine: init_uart
>> + * Description: init the UART clocks, muxes, and baudrate/parity/etc.
>> + */
>> +void init_uart(int uart_num)
>> +{
>> +#if CONFIG_TEGRA2_ENABLE_UARTA
>> +     if (uart_num == UART_A) {
>> +             uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTA_BASE;
>> +
>> +             uart_clock_init(UART_A);
>> +
>> +             /* Enable UARTA - uses config 0 */
>> +             pin_mux_uart(UART_A);
>> +
>> +             setup_uart(uart);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +#if CONFIG_TEGRA2_ENABLE_UARTD
>> +     if (uart_num == UART_D) {
>> +             uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTD_BASE;
>> +
>> +             uart_clock_init(UART_D);
>> +
>> +             /* Enable UARTD - uses config 0 */
>> +             pin_mux_uart(UART_D);
>> +
>> +             setup_uart(uart);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +}
>> +
>> +void uart_init(void)
>> +{
>> +#if (CONFIG_TEGRA2_ENABLE_UARTA)
>> +     init_uart(UART_A);
>> +#endif
>> +#if (CONFIG_TEGRA2_ENABLE_UARTD)
>> +     init_uart(UART_D);
>> +#endif
>> +}
>> diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
>> new file mode 100644
>> index 0000000..d49e978
>> --- /dev/null
>> +++ b/board/nvidia/common/board.h
>> @@ -0,0 +1,57 @@
>> +/*
>> + *  (C) Copyright 2010,2011
>> + *  NVIDIA Corporation <www.nvidia.com>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +#ifndef _COMMON_BOARD_H_
>> +#define _COMMON_BOARD_H_
>> +
>> +#include <asm/arch/clk_rst.h>
>> +#include <asm/arch/pinmux.h>
>> +#include <asm/arch/uart.h>
>> +
>> +#define NVRM_PLLP_FIXED_FREQ_KHZ     216000
>> +#define NV_DEFAULT_DEBUG_BAUD                115200
>> +
>> +#define PLL_BYPASS           (1 << 31)
>> +#define PLL_ENABLE           (1 << 30)
>> +#define PLL_BASE_OVRRIDE     (1 << 28)
>> +#define PLL_DIVP             (1 << 20)       /* post divider, b22:20 */
>> +#define PLL_DIVM             0x0C            /* input divider, b4:0 */
>> +
>> +#define SWR_UARTD_RST                (1 << 2)
>> +#define CLK_ENB_UARTD                (1 << 2)
>> +#define SWR_UARTA_RST                (1 << 6)
>> +#define CLK_ENB_UARTA                (1 << 6)
>> +
>> +#define Z_GMC                        (1 << 29)
>> +#define Z_IRRX                       (1 << 20)
>> +#define Z_IRTX                       (1 << 19)
>> +
>> +enum {
>> +     UART_A = 1,
>> +     UART_B,
>> +     UART_C,
>> +     UART_D,
>> +     UART_E
>> +};
>> +
>> +#endif /* _COMMON_BOARD_H_ */
>
> Same comment about this header.  It looks CPU-specific?  If so, it
> should be moved to somewhere in arch/arm.
If /nvidia/common/board.c moves, then I'll move this one, too.

>
> Lastly, its generally good to CC people that have commented on your
> previous patches (eg Wolfgang and myself) as they are likely to provide
> more feedback and CC-ing them directly helps to ensure your
> re-submission doesn't get lost in their inboxes.  I promise those are my
> last comments:)
>
I've added Wolfgang and Sandeep to the CC list. I'll try to keep it updated.

> Best,
> Peter
>
Thanks for all the feedback,

Tom
>
>
Tom Warren Jan. 20, 2011, 4:44 p.m. UTC | #5
Graeme,

On Wed, Jan 19, 2011 at 5:20 PM, Graeme Russ <graeme.russ@gmail.com> wrote:
> On Thu, Jan 20, 2011 at 8:19 AM, Tom Warren <twarren.nvidia@gmail.com> wrote:
>
>> +
>> +/*
>> + * Routine: uart_clock_init
>> + * Description: init the PLL and clock for the UART in uart_num
>> + */
>> +void uart_clock_init(int uart_num)
>> +{
>> +       clk_rst_ctlr *const clkrst = (clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
>> +       static int pllp_init_done;
>> +       u32 reg;
>> +
>> +       if (!pllp_init_done) {
>> +
>> +               /* Override pllp setup for 216MHz operation. */
>> +               reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
>> +               reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
>> +               writel(reg, clkrst->crc_pllp_base);
>> +
>> +               reg |= PLL_ENABLE;
>> +               writel(reg, clkrst->crc_pllp_base);
>
> Is this correct? Should it not be writel(reg, &clkrst->crc_pllp_base);
Well, the PLLs, UART and device clocks that I'm writing all seem to work OK.

I'll take a look at the ARM asm code generated, but you are probably right.
But shouldn't the compiler have complained if I wasn't passing the
struct address?

>
> Similarly for other readl()'s and writel()'s
>
> Regards,
>
> Graeme
>
Tom Warren Jan. 20, 2011, 4:49 p.m. UTC | #6
Wolfgang,

On Thu, Jan 20, 2011 at 1:40 AM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Tom Warren,
>
> In message <1295471986-2395-2-git-send-email-twarren@nvidia.com> you wrote:
>> Signed-off-by: Tom Warren <twarren@nvidia.com>
>
> checkpatch.pl reports:
>
>        total: 6 errors, 12 warnings, 1155 lines checked
>
>        /tmp/patch has style problems, please review.
>
> Please clean up.
I run checkpatch.pl (v 0.31) on every patch before I submit it, and I
did see 12 warnings but
no errors.  The warnings were minor - new typedefs and volatile
structs.  Could you please
provide the text of the checkpatch.pl output so I can see what the
errors might be?

Thanks.
>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> "Where shall I begin, please your Majesty?" he asked. "Begin  at  the
> beginning,"  the  King said, gravely, "and go on till you come to the
> end: then stop."    - Alice's Adventures in Wonderland, Lewis Carroll
>
Peter Tyser Jan. 20, 2011, 5:15 p.m. UTC | #7
On Thu, 2011-01-20 at 09:41 -0700, Tom Warren wrote:
> On Wed, Jan 19, 2011 at 5:04 PM, Peter Tyser <ptyser@xes-inc.com> wrote:
> > Hi Tom,
> > Some last minutes nits:
> >
> > It looks like some of the new functions can be declared statically.
> > It'd be nice to do so where possible.
> Which functions, Peter? Please point them out specifically, thanks.

Any function that won't be called from outside the scope of the file.
Eg it looks like init_uart() and setup_uart() are local functions and
should be static.  Those are the 2 that jumped out initially, but you
should review to see if there are others.

<snip>

> >> +/*
> >> + * Routine: uart_clock_init
> >> + * Description: init the PLL and clock for the UART in uart_num
> >> + */
> >> +void uart_clock_init(int uart_num)
> >> +{
> >
> > Are all these uart functions board-specific?  They look more
> > CPU-specific.  If that's the case they should be moved somewhere in
> > arch/arm/*.  Other boards that use the Tegra2 don't want to duplicate
> > this code or link into Nvidia's board/nvidia directory.
> It's Tegra2 SoC-specific - that's not the CPU, per se.  I guess I could move
> it to arch/arm/cpu/armv7/tegra2, if you think it's important enough.

I think they should be moved.  If they aren't, the next board vendor (eg
my company) that uses the Tegra2 will copy your board.[ch] into their
board/<vendor> directory and use them as a starting point, which is a
large duplication of code.  Moving it somewhere in arch/arm is the
"right" thing to do and will make every future tegra2 board port cleaner
and easier.

Best,
Peter
Wolfgang Denk Jan. 20, 2011, 10:47 p.m. UTC | #8
Dear Tom Warren,

In message <AANLkTi=yMzEztQ5p=doSj4ukKfvx8gMRZOAxjBwbJmkT@mail.gmail.com> you wrote:
...
> > Are all these uart functions board-specific?  They look more
> > CPU-specific.  If that's the case they should be moved somewhere in
> > arch/arm/*.  Other boards that use the Tegra2 don't want to duplicate
> > this code or link into Nvidia's board/nvidia directory.
> It's Tegra2 SoC-specific - that's not the CPU, per se.  I guess I could move
> it to arch/arm/cpu/armv7/tegra2, if you think it's important enough.

Yes, please do.

Best regards,

Wolfgang Denk
Wolfgang Denk Jan. 20, 2011, 10:50 p.m. UTC | #9
Dear Tom Warren,

In message <AANLkTimcTq74=jz0HJcMSUMYe3Tf2zeUY9R9f7QVtVBV@mail.gmail.com> you wrote:
> 
> I'll take a look at the ARM asm code generated, but you are probably right.
> But shouldn't the compiler have complained if I wasn't passing the
> struct address?

I'm surprised about this, too.  But then, current mainline code still
has the horrible "(*(volatile unsigned int *)(a) = (v))" definition,
so the cast will eat all potential warnings :-(

Best regards,

Wolfgang Denk
Wolfgang Denk Jan. 20, 2011, 10:51 p.m. UTC | #10
Dear Tom Warren,

In message <AANLkTi=UjJ5teeYQQ8q4Rw7QaicJvAv4XS83pDCxhPOZ@mail.gmail.com> you wrote:
> 
> I run checkpatch.pl (v 0.31) on every patch before I submit it, and I
> did see 12 warnings but
> no errors.  The warnings were minor - new typedefs and volatile
> structs.  Could you please
> provide the text of the checkpatch.pl output so I can see what the
> errors might be?

Sorry for the false alarms, I was using an older version of checkpatch.

Best regards,

Wolfgang Denk
Graeme Russ Jan. 21, 2011, 12:13 a.m. UTC | #11
On Fri, Jan 21, 2011 at 9:50 AM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Tom Warren,
>
> In message <AANLkTimcTq74=jz0HJcMSUMYe3Tf2zeUY9R9f7QVtVBV@mail.gmail.com> you wrote:
>>
>> I'll take a look at the ARM asm code generated, but you are probably right.
>> But shouldn't the compiler have complained if I wasn't passing the
>> struct address?
>
> I'm surprised about this, too.  But then, current mainline code still
> has the horrible "(*(volatile unsigned int *)(a) = (v))" definition,
> so the cast will eat all potential warnings :-(
>

Yes, I noticed this with x86 - I can do something like the following
without the compiler warning me:

typdef struct blah {
  u32 foo;
  u16 bar;
} blah_t;

blah_t *fred = 0x00001000;

writel(1, &fred->foo);
writel(1, &fred->bar);
writew(1, &fred->foo);
writew(1, &fred->bar);



This is particularly nasty with the sc520's Memory Mapped Control
Registers - I have found a few here and there where longs were being
written to words and visa-versa

Regards,

Graeme
Mike Rapoport Jan. 24, 2011, 11:55 a.m. UTC | #12
On 01/19/11 23:19, Tom Warren wrote:
> Signed-off-by: Tom Warren <twarren@nvidia.com>
> ---
> Changes for V2:
>         - Coding style cleanup
>         - Move serial driver changes to separate patch
>         - Use board/nvidia/ instead of /board/tegra
>         - Remove TRUE/FALSE defines
>         - Use standard NS16550 register/bit defines in UART init
> 
> Changes for V3:
>         - Use I/O accessors for Tegra2 HW MMIO register access
>         - Allow conditional compile of UARTA/UARTD code to save space
> 
>  arch/arm/cpu/armv7/tegra2/Makefile           |   48 +++++
>  arch/arm/cpu/armv7/tegra2/board.c            |   91 ++++++++++
>  arch/arm/cpu/armv7/tegra2/config.mk          |   28 +++
>  arch/arm/cpu/armv7/tegra2/lowlevel_init.S    |   66 +++++++
>  arch/arm/cpu/armv7/tegra2/sys_info.c         |   35 ++++
>  arch/arm/cpu/armv7/tegra2/timer.c            |  122 +++++++++++++
>  arch/arm/include/asm/arch-tegra2/clk_rst.h   |  155 ++++++++++++++++
>  arch/arm/include/asm/arch-tegra2/pinmux.h    |   52 ++++++
>  arch/arm/include/asm/arch-tegra2/pmc.h       |  125 +++++++++++++
>  arch/arm/include/asm/arch-tegra2/sys_proto.h |   33 ++++
>  arch/arm/include/asm/arch-tegra2/tegra2.h    |   49 +++++
>  arch/arm/include/asm/arch-tegra2/uart.h      |   45 +++++
>  board/nvidia/common/board.c                  |  249 ++++++++++++++++++++++++++
>  board/nvidia/common/board.h                  |   57 ++++++
>  14 files changed, 1155 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/tegra2/Makefile
>  create mode 100644 arch/arm/cpu/armv7/tegra2/board.c
>  create mode 100644 arch/arm/cpu/armv7/tegra2/config.mk
>  create mode 100644 arch/arm/cpu/armv7/tegra2/lowlevel_init.S
>  create mode 100644 arch/arm/cpu/armv7/tegra2/sys_info.c
>  create mode 100644 arch/arm/cpu/armv7/tegra2/timer.c
>  create mode 100644 arch/arm/include/asm/arch-tegra2/clk_rst.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/pinmux.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/pmc.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/sys_proto.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/tegra2.h
>  create mode 100644 arch/arm/include/asm/arch-tegra2/uart.h
>  create mode 100644 board/nvidia/common/board.c
>  create mode 100644 board/nvidia/common/board.h

[ snip ]

> + */
> +
> +#ifndef _CLK_RST_H_
> +#define _CLK_RST_H_
> +
> +/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
> +
> +typedef volatile struct clk_rst_ctlr {

Is it necessary to use the structure to map the clocks and reset controller?
Wouldn't be better to port Linux implementation of Tegra2 clocks to U-Boot as well?
Besides, since you're using I/O accessors anyway, the struct can replaces with
base address and offset definitions.

> +	uint crc_rst_src;		/* _RST_SOURCE_0,	0x00*/
> +	uint crc_rst_dev_l;		/* _RST_DEVICES_L_0,	0x04*/
> +	uint crc_rst_dev_h;		/* _RST_DEVICES_H_0,	0x08*/
> +	uint crc_rst_dev_u;		/* _RST_DEVICES_U_0,	0x0C*/
> +	uint crc_clk_out_enb_l;		/* _CLK_OUT_ENB_L_0,	0x10*/
> +	uint crc_clk_out_enb_h;		/* _CLK_OUT_ENB_H_0,	0x14*/

[ snip ]

> +
> +#ifndef _PINMUX_H_
> +#define _PINMUX_H_
> +
> +/* APB MISC Pin Mux and Tristate (APB_MISC_PP_) registers */
> +
> +typedef volatile struct pinmux_tri_ctlr {

The same comment is valid also for the pin multiplexing registers...

> +	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */
> +	uint pmt_reserved1;		/* ABP_MISC_PP_ reserved offset 04 */
> +	uint pmt_strap_opt_a;		/* _STRAPPING_OPT_A_0, offset 08 */
> +
> +#ifndef _PMC_H_
> +#define _PMC_H_
> +
> +/* Power Management Controller (APBDEV_PMC_) registers */
> +
> +typedef volatile struct pmc_ctlr {

And for the PMC registers as well.

> +	uint pmc_cntrl;			/* _CNTRL_0, offset 00 */
> +	uint pmc_sec_disable;		/* _SEC_DISABLE_0, offset 04 */
> +	uint pmc_pmc_swrst;		/* _PMC_SWRST_0, offset 08 */
> +	uint pmc_wake_mask;		/* _WAKE_MASK_0, offset 0C */
> +	uint pmc_wake_lvl;		/* _WAKE_LVL_0, offset 10 */

[ snip ]

> +#ifndef _TEGRA2_H_
> +#define _TEGRA2_H_
> +
> +#define NV_PA_SDRAM_BASE	0x00000000
> +#define NV_PA_TMRUS_BASE	0x60005010
> +#define NV_PA_CLK_RST_BASE	0x60006000
> +#define NV_PA_APB_MISC_BASE	0x70000000
> +#define NV_PA_APB_UARTA_BASE	(NV_PA_APB_MISC_BASE + 0x6000)
> +#define NV_PA_APB_UARTB_BASE	(NV_PA_APB_MISC_BASE + 0x6040)
> +#define NV_PA_APB_UARTC_BASE	(NV_PA_APB_MISC_BASE + 0x6200)
> +#define NV_PA_APB_UARTD_BASE	(NV_PA_APB_MISC_BASE + 0x6300)
> +#define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
> +#define NV_PA_PMC_BASE		0x7000E400

what is the purpose of NV_PA prefix here?

> +#define TEGRA2_SDRC_CS0		NV_PA_SDRAM_BASE
> +#define LOW_LEVEL_SRAM_STACK	0x4000FFFC
> +
> +#ifndef __ASSEMBLY__
> +typedef volatile struct timerus {
> +	unsigned int cntr_1us;

[ snip ]

> +#ifndef _UART_H_
> +#define _UART_H_
> +
> +/* UART registers */
> +
> +typedef volatile struct uart_ctlr {

The same comment as for the other struct *_ctrl...

> +	uint uart_thr_dlab_0;		/* UART_THR_DLAB_0_0, offset 00 */
> +	uint uart_ier_dlab_0;		/* UART_IER_DLAB_0_0, offset 04 */
> +	uint uart_iir_fcr;		/* UART_IIR_FCR_0, offset 08 */
> +	uint uart_lcr;			/* UART_LCR_0, offset 0C */
> +	uint uart_mcr;			/* UART_MCR_0, offset 10 */
> +	uint uart_lsr;			/* UART_LSR_0, offset 14 */
> +	uint uart_msr;			/* UART_MSR_0, offset 18 */
> +	uint uart_spr;			/* UART_SPR_0, offset 1C */
> +	uint uart_irda_csr;		/* UART_IRDA_CSR_0, offset 20 */
> +	uint uart_reserved[6];		/* Reserved, unused */
> +	uint uart_asr;			/* UART_ASR_0, offset 3C */
> +} uart_ctlr;
> +
> +#define UART_FCR_TRIGGER_3	0x30	/* Mask for trigger set at 3 */
> +
> +#endif	/* UART_H */
> diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
> new file mode 100644
> index 0000000..876facb
> --- /dev/null
> +++ b/board/nvidia/common/board.c

It seems that this file is supposed to include code common to all Tegra2 based
boards and not only NVidia boards. I'd suggest moving its contents to the
arch/arm/cpu/armv7/tegra2/board.c

> @@ -0,0 +1,249 @@
> +/*
> + *  (C) Copyright 2010,2011
> + *  NVIDIA Corporation <www.nvidia.com>
> + *

[ snip ]

> +/*
> + * Routine: pin_mux_uart
> + * Description: setup the pin muxes/tristate values for UART based on uart_num
> + */
> +void pin_mux_uart(int uart_num)
> +{
> +	pinmux_tri_ctlr *const pmt = (pinmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
> +	u32 reg;
> +
> +#if CONFIG_TEGRA2_ENABLE_UARTA
> +	if (uart_num  == UART_A) {
> +		reg = readl(pmt->pmt_ctl_c);
> +		reg &= 0xFFF0FFFF;	/* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
> +		writel(reg, pmt->pmt_ctl_c);
> +
> +		reg = readl(pmt->pmt_tri_a);
> +		reg &= ~Z_IRRX;		/* Z_IRRX = normal (0) */
> +		reg &= ~Z_IRTX;		/* Z_IRTX = normal (0) */
> +		writel(reg, pmt->pmt_tri_a);

This covers only one possiblity of UART-A pin muxing options

> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTA */
> +#if CONFIG_TEGRA2_ENABLE_UARTD
> +	if (uart_num == UART_D) {
> +		reg = readl(pmt->pmt_ctl_b);
> +		reg &= 0xFFFFFFF3;	/* GMC_SEL [3:2] = 00, UARTD */
> +		writel(reg, pmt->pmt_ctl_b);
> +
> +		reg = readl(pmt->pmt_tri_a);
> +		reg &= ~Z_GMC;		/* Z_GMC = normal (0) */
> +		writel(reg, pmt->pmt_tri_a);
> +	}

ditto for UART-D

> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +}
> +
> +void setup_uart(uart_ctlr *u)
> +{
> +	u32 reg;
> +
> +	/* Prepare the divisor value */
> +	reg = NVRM_PLLP_FIXED_FREQ_KHZ * 1000 / NV_DEFAULT_DEBUG_BAUD / 16;
> +
> +	/* Set up UART parameters */
> +	writel(UART_LCR_DLAB, u->uart_lcr);
> +	writel(reg, u->uart_thr_dlab_0);
> +	writel(0, u->uart_ier_dlab_0);
> +	writel(0, u->uart_lcr);			/* clear DLAB */
> +	writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN | \
> +		UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR), u->uart_iir_fcr);
> +	writel(0, u->uart_ier_dlab_0);
> +	writel(UART_LCR_WLS_8, u->uart_lcr);	/* 8N1 */
> +	writel(UART_MCR_RTS, u->uart_mcr);
> +	writel(0, u->uart_msr);
> +	writel(0, u->uart_spr);
> +	writel(0, u->uart_irda_csr);
> +	writel(0, u->uart_asr);
> +	writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN), u->uart_iir_fcr);
> +
> +	/* Flush any old characters out of the RX FIFO */
> +	reg = readl(u->uart_lsr);
> +
> +	while (reg & UART_LSR_DR) {
> +		reg = readl(u->uart_thr_dlab_0);
> +		reg = readl(u->uart_lsr);
> +	}
> +}
> +
> +/*
> + * Routine: init_uart
> + * Description: init the UART clocks, muxes, and baudrate/parity/etc.
> + */
> +void init_uart(int uart_num)
> +{
> +#if CONFIG_TEGRA2_ENABLE_UARTA
> +	if (uart_num == UART_A) {
> +		uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTA_BASE;
> +
> +		uart_clock_init(UART_A);
> +
> +		/* Enable UARTA - uses config 0 */
> +		pin_mux_uart(UART_A);
> +
> +		setup_uart(uart);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +#if CONFIG_TEGRA2_ENABLE_UARTD
> +	if (uart_num == UART_D) {
> +		uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTD_BASE;
> +
> +		uart_clock_init(UART_D);
> +
> +		/* Enable UARTD - uses config 0 */
> +		pin_mux_uart(UART_D);
> +
> +		setup_uart(uart);
> +	}
> +#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
> +}
> +
> +void uart_init(void)
> +{
> +#if (CONFIG_TEGRA2_ENABLE_UARTA)
> +	init_uart(UART_A);
> +#endif
> +#if (CONFIG_TEGRA2_ENABLE_UARTD)
> +	init_uart(UART_D);
> +#endif
> +}
> diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
> new file mode 100644
> index 0000000..d49e978
> --- /dev/null
> +++ b/board/nvidia/common/board.h
> @@ -0,0 +1,57 @@
> +/*
> + *  (C) Copyright 2010,2011
> + *  NVIDIA Corporation <www.nvidia.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _COMMON_BOARD_H_
> +#define _COMMON_BOARD_H_
> +
> +#include <asm/arch/clk_rst.h>
> +#include <asm/arch/pinmux.h>
> +#include <asm/arch/uart.h>
> +
> +#define NVRM_PLLP_FIXED_FREQ_KHZ	216000
> +#define NV_DEFAULT_DEBUG_BAUD		115200
> +
> +#define PLL_BYPASS		(1 << 31)
> +#define PLL_ENABLE		(1 << 30)
> +#define PLL_BASE_OVRRIDE	(1 << 28)
> +#define PLL_DIVP		(1 << 20)	/* post divider, b22:20 */
> +#define PLL_DIVM		0x0C		/* input divider, b4:0 */
> +
> +#define SWR_UARTD_RST		(1 << 2)
> +#define CLK_ENB_UARTD		(1 << 2)
> +#define SWR_UARTA_RST		(1 << 6)
> +#define CLK_ENB_UARTA		(1 << 6)
> +
> +#define Z_GMC			(1 << 29)
> +#define Z_IRRX			(1 << 20)
> +#define Z_IRTX			(1 << 19)
> +
> +enum {
> +	UART_A = 1,
> +	UART_B,
> +	UART_C,
> +	UART_D,
> +	UART_E
> +};
> +
> +#endif /* _COMMON_BOARD_H_ */
Tom Warren Jan. 24, 2011, 5:26 p.m. UTC | #13
Mike,

On Mon, Jan 24, 2011 at 4:55 AM, Mike Rapoport <mike@compulab.co.il> wrote:
> On 01/19/11 23:19, Tom Warren wrote:
>> Signed-off-by: Tom Warren <twarren@nvidia.com>
>> ---
>> Changes for V2:
>>         - Coding style cleanup
>>         - Move serial driver changes to separate patch
>>         - Use board/nvidia/ instead of /board/tegra
>>         - Remove TRUE/FALSE defines
>>         - Use standard NS16550 register/bit defines in UART init
>>
>> Changes for V3:
>>         - Use I/O accessors for Tegra2 HW MMIO register access
>>         - Allow conditional compile of UARTA/UARTD code to save space
>>
>>  arch/arm/cpu/armv7/tegra2/Makefile           |   48 +++++
>>  arch/arm/cpu/armv7/tegra2/board.c            |   91 ++++++++++
>>  arch/arm/cpu/armv7/tegra2/config.mk          |   28 +++
>>  arch/arm/cpu/armv7/tegra2/lowlevel_init.S    |   66 +++++++
>>  arch/arm/cpu/armv7/tegra2/sys_info.c         |   35 ++++
>>  arch/arm/cpu/armv7/tegra2/timer.c            |  122 +++++++++++++
>>  arch/arm/include/asm/arch-tegra2/clk_rst.h   |  155 ++++++++++++++++
>>  arch/arm/include/asm/arch-tegra2/pinmux.h    |   52 ++++++
>>  arch/arm/include/asm/arch-tegra2/pmc.h       |  125 +++++++++++++
>>  arch/arm/include/asm/arch-tegra2/sys_proto.h |   33 ++++
>>  arch/arm/include/asm/arch-tegra2/tegra2.h    |   49 +++++
>>  arch/arm/include/asm/arch-tegra2/uart.h      |   45 +++++
>>  board/nvidia/common/board.c                  |  249 ++++++++++++++++++++++++++
>>  board/nvidia/common/board.h                  |   57 ++++++
>>  14 files changed, 1155 insertions(+), 0 deletions(-)
>>  create mode 100644 arch/arm/cpu/armv7/tegra2/Makefile
>>  create mode 100644 arch/arm/cpu/armv7/tegra2/board.c
>>  create mode 100644 arch/arm/cpu/armv7/tegra2/config.mk
>>  create mode 100644 arch/arm/cpu/armv7/tegra2/lowlevel_init.S
>>  create mode 100644 arch/arm/cpu/armv7/tegra2/sys_info.c
>>  create mode 100644 arch/arm/cpu/armv7/tegra2/timer.c
>>  create mode 100644 arch/arm/include/asm/arch-tegra2/clk_rst.h
>>  create mode 100644 arch/arm/include/asm/arch-tegra2/pinmux.h
>>  create mode 100644 arch/arm/include/asm/arch-tegra2/pmc.h
>>  create mode 100644 arch/arm/include/asm/arch-tegra2/sys_proto.h
>>  create mode 100644 arch/arm/include/asm/arch-tegra2/tegra2.h
>>  create mode 100644 arch/arm/include/asm/arch-tegra2/uart.h
>>  create mode 100644 board/nvidia/common/board.c
>>  create mode 100644 board/nvidia/common/board.h
>
> [ snip ]
>
>> + */
>> +
>> +#ifndef _CLK_RST_H_
>> +#define _CLK_RST_H_
>> +
>> +/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
>> +
>> +typedef volatile struct clk_rst_ctlr {
>
> Is it necessary to use the structure to map the clocks and reset controller?
> Wouldn't be better to port Linux implementation of Tegra2 clocks to U-Boot as well?
> Besides, since you're using I/O accessors anyway, the struct can replaces with
> base address and offset definitions.
I asked Wolfgang to pre-review the original patch, and this is what he
said about original
base+offset register access code:
Wolfgang> We do not allow this in U-Boot.  Please turn all offset
tables into C structs, and
Wolfgang> create a set of I/O accessor functions (or macros) as needed
to provide the needed
Wolfgang> memory barriers on your architecture.

Using structs seems like a natural way to map HW MMIO regs, and is
done throughout U-Boot.
The structs are already written, contain just the members needed for
U-Boot (to a large degree),
and as Wolfgang has said in the past, U-Boot is not Linux, so I see no
reason to bring in the
Linux Tegra2 structs for any of these HW blocks. When I start posting
the drivers (SPI, USB,
etc.), then it might make sense to use (copy w/edits) the Linux data
structs, etc.

>
>> +     uint crc_rst_src;               /* _RST_SOURCE_0,       0x00*/
>> +     uint crc_rst_dev_l;             /* _RST_DEVICES_L_0,    0x04*/
>> +     uint crc_rst_dev_h;             /* _RST_DEVICES_H_0,    0x08*/
>> +     uint crc_rst_dev_u;             /* _RST_DEVICES_U_0,    0x0C*/
>> +     uint crc_clk_out_enb_l;         /* _CLK_OUT_ENB_L_0,    0x10*/
>> +     uint crc_clk_out_enb_h;         /* _CLK_OUT_ENB_H_0,    0x14*/
>
> [ snip ]
>
>> +
>> +#ifndef _PINMUX_H_
>> +#define _PINMUX_H_
>> +
>> +/* APB MISC Pin Mux and Tristate (APB_MISC_PP_) registers */
>> +
>> +typedef volatile struct pinmux_tri_ctlr {
>
> The same comment is valid also for the pin multiplexing registers...
>
>> +     uint pmt_reserved0;             /* ABP_MISC_PP_ reserved offset 00 */
>> +     uint pmt_reserved1;             /* ABP_MISC_PP_ reserved offset 04 */
>> +     uint pmt_strap_opt_a;           /* _STRAPPING_OPT_A_0, offset 08 */
>> +
>> +#ifndef _PMC_H_
>> +#define _PMC_H_
>> +
>> +/* Power Management Controller (APBDEV_PMC_) registers */
>> +
>> +typedef volatile struct pmc_ctlr {
>
> And for the PMC registers as well.
>
>> +     uint pmc_cntrl;                 /* _CNTRL_0, offset 00 */
>> +     uint pmc_sec_disable;           /* _SEC_DISABLE_0, offset 04 */
>> +     uint pmc_pmc_swrst;             /* _PMC_SWRST_0, offset 08 */
>> +     uint pmc_wake_mask;             /* _WAKE_MASK_0, offset 0C */
>> +     uint pmc_wake_lvl;              /* _WAKE_LVL_0, offset 10 */
>
> [ snip ]
>
>> +#ifndef _TEGRA2_H_
>> +#define _TEGRA2_H_
>> +
>> +#define NV_PA_SDRAM_BASE     0x00000000
>> +#define NV_PA_TMRUS_BASE     0x60005010
>> +#define NV_PA_CLK_RST_BASE   0x60006000
>> +#define NV_PA_APB_MISC_BASE  0x70000000
>> +#define NV_PA_APB_UARTA_BASE (NV_PA_APB_MISC_BASE + 0x6000)
>> +#define NV_PA_APB_UARTB_BASE (NV_PA_APB_MISC_BASE + 0x6040)
>> +#define NV_PA_APB_UARTC_BASE (NV_PA_APB_MISC_BASE + 0x6200)
>> +#define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300)
>> +#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400)
>> +#define NV_PA_PMC_BASE               0x7000E400
>
> what is the purpose of NV_PA prefix here?
NV_Physical_Address - a base address of a HW block (Power Management
Cntrlr, etc.)

>> +#define TEGRA2_SDRC_CS0              NV_PA_SDRAM_BASE
>> +#define LOW_LEVEL_SRAM_STACK 0x4000FFFC
>> +
>> +#ifndef __ASSEMBLY__
>> +typedef volatile struct timerus {
>> +     unsigned int cntr_1us;
>
> [ snip ]
>
>> +#ifndef _UART_H_
>> +#define _UART_H_
>> +
>> +/* UART registers */
>> +
>> +typedef volatile struct uart_ctlr {
>
> The same comment as for the other struct *_ctrl...
>
>> +     uint uart_thr_dlab_0;           /* UART_THR_DLAB_0_0, offset 00 */
>> +     uint uart_ier_dlab_0;           /* UART_IER_DLAB_0_0, offset 04 */
>> +     uint uart_iir_fcr;              /* UART_IIR_FCR_0, offset 08 */
>> +     uint uart_lcr;                  /* UART_LCR_0, offset 0C */
>> +     uint uart_mcr;                  /* UART_MCR_0, offset 10 */
>> +     uint uart_lsr;                  /* UART_LSR_0, offset 14 */
>> +     uint uart_msr;                  /* UART_MSR_0, offset 18 */
>> +     uint uart_spr;                  /* UART_SPR_0, offset 1C */
>> +     uint uart_irda_csr;             /* UART_IRDA_CSR_0, offset 20 */
>> +     uint uart_reserved[6];          /* Reserved, unused */
>> +     uint uart_asr;                  /* UART_ASR_0, offset 3C */
>> +} uart_ctlr;
>> +
>> +#define UART_FCR_TRIGGER_3   0x30    /* Mask for trigger set at 3 */
>> +
>> +#endif       /* UART_H */
>> diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
>> new file mode 100644
>> index 0000000..876facb
>> --- /dev/null
>> +++ b/board/nvidia/common/board.c
>
> It seems that this file is supposed to include code common to all Tegra2 based
> boards and not only NVidia boards. I'd suggest moving its contents to the
> arch/arm/cpu/armv7/tegra2/board.c
board_init and timer_init funcs are found mostly in board/xxxx files
in U-Boot, with
a few instances (mostly timer_init) in arch/arm/cpu/xxx files.  I'd
prefe to leave this file
where it is.

>
>> @@ -0,0 +1,249 @@
>> +/*
>> + *  (C) Copyright 2010,2011
>> + *  NVIDIA Corporation <www.nvidia.com>
>> + *
>
> [ snip ]
>
>> +/*
>> + * Routine: pin_mux_uart
>> + * Description: setup the pin muxes/tristate values for UART based on uart_num
>> + */
>> +void pin_mux_uart(int uart_num)
>> +{
>> +     pinmux_tri_ctlr *const pmt = (pinmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
>> +     u32 reg;
>> +
>> +#if CONFIG_TEGRA2_ENABLE_UARTA
>> +     if (uart_num  == UART_A) {
>> +             reg = readl(pmt->pmt_ctl_c);
>> +             reg &= 0xFFF0FFFF;      /* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
>> +             writel(reg, pmt->pmt_ctl_c);
>> +
>> +             reg = readl(pmt->pmt_tri_a);
>> +             reg &= ~Z_IRRX;         /* Z_IRRX = normal (0) */
>> +             reg &= ~Z_IRTX;         /* Z_IRTX = normal (0) */
>> +             writel(reg, pmt->pmt_tri_a);
>
> This covers only one possiblity of UART-A pin muxing options
True, and when this code was in the board/nvidia/xxx area it made sense.
To date, all of our Tegra boards use these pinmux options for both UARTs.
If a board vendor chooses to use different pinmuxes, then they can override
these funcs in their board files, or use their own code triggered by their own
defines. But according to our HW guys, the vast majority will use these pins.

>
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTA */
>> +#if CONFIG_TEGRA2_ENABLE_UARTD
>> +     if (uart_num == UART_D) {
>> +             reg = readl(pmt->pmt_ctl_b);
>> +             reg &= 0xFFFFFFF3;      /* GMC_SEL [3:2] = 00, UARTD */
>> +             writel(reg, pmt->pmt_ctl_b);
>> +
>> +             reg = readl(pmt->pmt_tri_a);
>> +             reg &= ~Z_GMC;          /* Z_GMC = normal (0) */
>> +             writel(reg, pmt->pmt_tri_a);
>> +     }
>
> ditto for UART-D
See my comment above.
>
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +}
>> +
>> +void setup_uart(uart_ctlr *u)
>> +{
>> +     u32 reg;
>> +
>> +     /* Prepare the divisor value */
>> +     reg = NVRM_PLLP_FIXED_FREQ_KHZ * 1000 / NV_DEFAULT_DEBUG_BAUD / 16;
>> +
>> +     /* Set up UART parameters */
>> +     writel(UART_LCR_DLAB, u->uart_lcr);
>> +     writel(reg, u->uart_thr_dlab_0);
>> +     writel(0, u->uart_ier_dlab_0);
>> +     writel(0, u->uart_lcr);                 /* clear DLAB */
>> +     writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN | \
>> +             UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR), u->uart_iir_fcr);
>> +     writel(0, u->uart_ier_dlab_0);
>> +     writel(UART_LCR_WLS_8, u->uart_lcr);    /* 8N1 */
>> +     writel(UART_MCR_RTS, u->uart_mcr);
>> +     writel(0, u->uart_msr);
>> +     writel(0, u->uart_spr);
>> +     writel(0, u->uart_irda_csr);
>> +     writel(0, u->uart_asr);
>> +     writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN), u->uart_iir_fcr);
>> +
>> +     /* Flush any old characters out of the RX FIFO */
>> +     reg = readl(u->uart_lsr);
>> +
>> +     while (reg & UART_LSR_DR) {
>> +             reg = readl(u->uart_thr_dlab_0);
>> +             reg = readl(u->uart_lsr);
>> +     }
>> +}
>> +
>> +/*
>> + * Routine: init_uart
>> + * Description: init the UART clocks, muxes, and baudrate/parity/etc.
>> + */
>> +void init_uart(int uart_num)
>> +{
>> +#if CONFIG_TEGRA2_ENABLE_UARTA
>> +     if (uart_num == UART_A) {
>> +             uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTA_BASE;
>> +
>> +             uart_clock_init(UART_A);
>> +
>> +             /* Enable UARTA - uses config 0 */
>> +             pin_mux_uart(UART_A);
>> +
>> +             setup_uart(uart);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +#if CONFIG_TEGRA2_ENABLE_UARTD
>> +     if (uart_num == UART_D) {
>> +             uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTD_BASE;
>> +
>> +             uart_clock_init(UART_D);
>> +
>> +             /* Enable UARTD - uses config 0 */
>> +             pin_mux_uart(UART_D);
>> +
>> +             setup_uart(uart);
>> +     }
>> +#endif       /* CONFIG_TEGRA2_ENABLE_UARTD */
>> +}
>> +
>> +void uart_init(void)
>> +{
>> +#if (CONFIG_TEGRA2_ENABLE_UARTA)
>> +     init_uart(UART_A);
>> +#endif
>> +#if (CONFIG_TEGRA2_ENABLE_UARTD)
>> +     init_uart(UART_D);
>> +#endif
>> +}
>> diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
>> new file mode 100644
>> index 0000000..d49e978
>> --- /dev/null
>> +++ b/board/nvidia/common/board.h
>> @@ -0,0 +1,57 @@
>> +/*
>> + *  (C) Copyright 2010,2011
>> + *  NVIDIA Corporation <www.nvidia.com>
>> + *
>> + * See file CREDITS for list of people who contributed to this
>> + * project.
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
>> + * MA 02111-1307 USA
>> + */
>> +
>> +#ifndef _COMMON_BOARD_H_
>> +#define _COMMON_BOARD_H_
>> +
>> +#include <asm/arch/clk_rst.h>
>> +#include <asm/arch/pinmux.h>
>> +#include <asm/arch/uart.h>
>> +
>> +#define NVRM_PLLP_FIXED_FREQ_KHZ     216000
>> +#define NV_DEFAULT_DEBUG_BAUD                115200
>> +
>> +#define PLL_BYPASS           (1 << 31)
>> +#define PLL_ENABLE           (1 << 30)
>> +#define PLL_BASE_OVRRIDE     (1 << 28)
>> +#define PLL_DIVP             (1 << 20)       /* post divider, b22:20 */
>> +#define PLL_DIVM             0x0C            /* input divider, b4:0 */
>> +
>> +#define SWR_UARTD_RST                (1 << 2)
>> +#define CLK_ENB_UARTD                (1 << 2)
>> +#define SWR_UARTA_RST                (1 << 6)
>> +#define CLK_ENB_UARTA                (1 << 6)
>> +
>> +#define Z_GMC                        (1 << 29)
>> +#define Z_IRRX                       (1 << 20)
>> +#define Z_IRTX                       (1 << 19)
>> +
>> +enum {
>> +     UART_A = 1,
>> +     UART_B,
>> +     UART_C,
>> +     UART_D,
>> +     UART_E
>> +};
>> +
>> +#endif /* _COMMON_BOARD_H_ */
>
>
> --
> Sincerely yours,
> Mike.
Thanks,
Tom
>
Wolfgang Denk Jan. 24, 2011, 6:53 p.m. UTC | #14
Dear Mike Rapoport,

In message <4D3D68A9.4040702@compulab.co.il> you wrote:
>
> Besides, since you're using I/O accessors anyway, the struct can replaces with
> base address and offset definitions.

We do not allow such construtcs in U-Boot. With C structs, you can
have proper type checking by the compiler (well, at least assuming
you have proper I/O accessors in place).

> > +#define NV_PA_APB_UARTC_BASE	(NV_PA_APB_MISC_BASE + 0x6200)
> > +#define NV_PA_APB_UARTD_BASE	(NV_PA_APB_MISC_BASE + 0x6300)
> > +#define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
> > +#define NV_PA_PMC_BASE		0x7000E400
> 
> what is the purpose of NV_PA prefix here?

Good catch.


Best regards,

Wolfgang Denk
Wolfgang Denk Jan. 24, 2011, 7 p.m. UTC | #15
Dear Tom Warren,

In message <AANLkTinoK+s5OivHAyLg10Z=GWzKCCuJWJDykSSFGc0W@mail.gmail.com> you wrote:
> 
...
> >> +#define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300)
> >> +#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400)
> >> +#define NV_PA_PMC_BASE               0x7000E400
> >
> > what is the purpose of NV_PA prefix here?
> NV_Physical_Address - a base address of a HW block (Power Management
> Cntrlr, etc.)

Well, the NV_ part is not needed, right?


Best regards,

Wolfgang Denk
Tom Warren Jan. 24, 2011, 8:11 p.m. UTC | #16
Wolfgang (& Mike),

On Mon, Jan 24, 2011 at 12:00 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Tom Warren,
>
> In message <AANLkTinoK+s5OivHAyLg10Z=GWzKCCuJWJDykSSFGc0W@mail.gmail.com> you wrote:
>>
> ...
>> >> +#define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300)
>> >> +#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400)
>> >> +#define NV_PA_PMC_BASE               0x7000E400
>> >
>> > what is the purpose of NV_PA prefix here?
>> NV_Physical_Address - a base address of a HW block (Power Management
>> Cntrlr, etc.)
>
> Well, the NV_ part is not needed, right?
True. I can remove it, but why? It designates this as a
NVIDIA-specific define. I see the same thing
in AT91, OMAP, NetARM, DaVinci, IMX files, etc. etc.

>
>
> Best regards,
>
> Wolfgang Denk
Thanks,

Tom
>
> --
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> Writing a book is like washing an elephant: there's no good place  to
> begin  or  end,  and  it's  hard to keep track of what you've already
> covered.
>
Wolfgang Denk Jan. 24, 2011, 9:23 p.m. UTC | #17
Dear Tom Warren,

In message <AANLkTimN6c5DUFXWte4z8u6rRAB84KgC30STwj8NE3J1@mail.gmail.com> you wrote:
> 
> >> >> +#define NV_PA_APB_UARTD_BASE (NV_PA_APB_MISC_BASE + 0x6300)
> >> >> +#define NV_PA_APB_UARTE_BASE (NV_PA_APB_MISC_BASE + 0x6400)
> >> >> +#define NV_PA_PMC_BASE               0x7000E400
> >> >
> >> > what is the purpose of NV_PA prefix here?
> >> NV_Physical_Address - a base address of a HW block (Power Management
> >> Cntrlr, etc.)
> >
> > Well, the NV_ part is not needed, right?
> True. I can remove it, but why? It designates this as a
> NVIDIA-specific define. I see the same thing
> in AT91, OMAP, NetARM, DaVinci, IMX files, etc. etc.

OK, I don't insist.

Best regards,

Wolfgang Denk
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile
new file mode 100644
index 0000000..75fba0b
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/Makefile
@@ -0,0 +1,48 @@ 
+#
+# (C) Copyright 2010,2011 Nvidia Corporation.
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	=  $(obj)lib$(SOC).o
+
+SOBJS	:= lowlevel_init.o
+COBJS	:= sys_info.o board.o timer.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:	 $(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c
new file mode 100644
index 0000000..1e92d98
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/board.c
@@ -0,0 +1,91 @@ 
+/*
+ *  (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 <asm/arch/sys_proto.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/pmc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * 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)
+{
+	pmc_ctlr *const pmc = (pmc_ctlr *)NV_PA_PMC_BASE;
+	u32 reg;
+
+	reg = readl(&pmc->pmc_scratch20);
+	debug("pmc->pmc_scratch20 (ODMData) = 0x%08lX\n", reg);
+
+	/* bits 31:28 in OdmData are used for RAM size  */
+	switch ((reg) >> 28) {
+	case 1:
+		return 0x10000000;	/* 256 MB */
+	case 2:
+		return 0x20000000;	/* 512 MB */
+	case 3:
+	default:
+		return 0x40000000;	/* 1GB */
+	}
+}
+
+void s_init(void)
+{
+#ifndef CONFIG_ICACHE_OFF
+	icache_enable();
+#endif
+	invalidate_dcache();
+}
+
+int dram_init(void)
+{
+	unsigned long rs;
+
+	/* We do not initialise DRAM here. We just query the size */
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = gd->ram_size = query_sdram_size();
+
+	/* Now check it dynamically */
+	rs = get_ram_size(CONFIG_SYS_SDRAM_BASE, gd->ram_size);
+	if (rs) {
+		printf("dynamic ram_size = %lu\n", rs);
+		gd->bd->bi_dram[0].size = gd->ram_size = rs;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+
+extern tegra2_sysinfo sysinfo;
+
+int checkboard(void)
+{
+	printf("Board: %s\n", sysinfo.board_string);
+	return 0;
+}
+#endif	/* CONFIG_DISPLAY_BOARDINFO */
diff --git a/arch/arm/cpu/armv7/tegra2/config.mk b/arch/arm/cpu/armv7/tegra2/config.mk
new file mode 100644
index 0000000..96c0795
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/config.mk
@@ -0,0 +1,28 @@ 
+#
+# (C) Copyright 2010,2011
+# NVIDIA Corporation <www.nvidia.com>
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@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
+#
+
+# Use ARMv4 for Tegra2 - initial code runs on the AVP, which is an ARM7TDI.
+PLATFORM_CPPFLAGS += -march=armv4
diff --git a/arch/arm/cpu/armv7/tegra2/lowlevel_init.S b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S
new file mode 100644
index 0000000..c0e3aa1
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/lowlevel_init.S
@@ -0,0 +1,66 @@ 
+/*
+ * Board 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>
+
+_TEXT_BASE:
+	.word	CONFIG_SYS_TEXT_BASE	@ sdram load addr from config file
+
+.global invalidate_dcache
+invalidate_dcache:
+	mov pc, lr
+
+
+	.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
+
+.globl lowlevel_init
+lowlevel_init:
+	ldr	sp, SRAM_STACK
+	str	ip, [sp]
+	mov	ip, lr
+	bl	s_init				@ go setup pll, mux & memory
+	ldr	ip, [sp]
+	mov	lr, ip
+
+	mov	pc, lr				@ back to arch calling code
+
+	@ the literal pools origin
+	.ltorg
+
+SRAM_STACK:
+	.word LOW_LEVEL_SRAM_STACK
diff --git a/arch/arm/cpu/armv7/tegra2/sys_info.c b/arch/arm/cpu/armv7/tegra2/sys_info.c
new file mode 100644
index 0000000..6d11dc1
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/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/armv7/tegra2/timer.c b/arch/arm/cpu/armv7/tegra2/timer.c
new file mode 100644
index 0000000..858af0f
--- /dev/null
+++ b/arch/arm/cpu/armv7/tegra2/timer.c
@@ -0,0 +1,122 @@ 
+/*
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2008
+ * Texas Instruments
+ *
+ * Richard Woodruff <r-woodruff2@ti.com>
+ * Syed Moahmmed Khasim <khasim@ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@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>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static timerus_t *timer_base = (timerus_t *)NV_PA_TMRUS_BASE;
+
+/* counter runs at 1MHz */
+#define TIMER_CLK	(1000000)
+#define TIMER_LOAD_VAL	0xffffffff
+
+/* timer without interrupts */
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	gd->tbl = t;
+}
+
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+	long tmo = usec * (TIMER_CLK / 1000) / 1000;
+	unsigned long now, last = readl(&timer_base->cntr_1us);
+
+	while (tmo > 0) {
+		now = readl(&timer_base->cntr_1us);
+		if (last > now) /* count up timer overflow */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		else
+			tmo -= now - last;
+		last = now;
+	}
+}
+
+void reset_timer_masked(void)
+{
+	/* reset time, capture current incrementer value time */
+	gd->lastinc = readl(&timer_base->cntr_1us) / (TIMER_CLK/CONFIG_SYS_HZ);
+	gd->tbl = 0;		/* start "advancing" time stamp from 0 */
+}
+
+ulong get_timer_masked(void)
+{
+	ulong now;
+
+	/* current tick value */
+	now = readl(&timer_base->cntr_1us) / (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;
+}
diff --git a/arch/arm/include/asm/arch-tegra2/clk_rst.h b/arch/arm/include/asm/arch-tegra2/clk_rst.h
new file mode 100644
index 0000000..52a7269
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/clk_rst.h
@@ -0,0 +1,155 @@ 
+/*
+ *  (C) Copyright 2010,2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _CLK_RST_H_
+#define _CLK_RST_H_
+
+/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
+
+typedef volatile struct clk_rst_ctlr {
+	uint crc_rst_src;		/* _RST_SOURCE_0,	0x00*/
+	uint crc_rst_dev_l;		/* _RST_DEVICES_L_0,	0x04*/
+	uint crc_rst_dev_h;		/* _RST_DEVICES_H_0,	0x08*/
+	uint crc_rst_dev_u;		/* _RST_DEVICES_U_0,	0x0C*/
+	uint crc_clk_out_enb_l;		/* _CLK_OUT_ENB_L_0,	0x10*/
+	uint crc_clk_out_enb_h;		/* _CLK_OUT_ENB_H_0,	0x14*/
+	uint crc_clk_out_enb_u;		/* _CLK_OUT_ENB_U_0,	0x18*/
+	uint crc_reserved0;		/* reserved_0,		0x1c*/
+	uint crc_cclk_brst_pol;		/* _CCLK_BURST_POLICY_0,0x20*/
+	uint crc_super_cclk_div;	/* _SUPER_CCLK_DIVIDER_0,0x24*/
+	uint crc_sclk_brst_pol;		/* _SCLK_BURST_POLICY_0, 0x28*/
+	uint crc_super_sclk_div;	/* _SUPER_SCLK_DIVIDER_0,0x2C*/
+	uint crc_clk_sys_rate;		/* _CLK_SYSTEM_RATE_0,	0x30*/
+	uint crc_prog_dly_clk;		/* _PROG_DLY_CLK_0,	0x34*/
+	uint crc_aud_sync_clk_rate;	/* _AUDIO_SYNC_CLK_RATE_0,0x38*/
+	uint crc_reserved1;		/* reserved_1,		0x3c*/
+	uint crc_cop_clk_skip_plcy;	/* _COP_CLK_SKIP_POLICY_0,0x40*/
+	uint crc_clk_mask_arm;		/* _CLK_MASK_ARM_0,	0x44*/
+	uint crc_misc_clk_enb;		/* _MISC_CLK_ENB_0,	0x48*/
+	uint crc_clk_cpu_cmplx;		/* _CLK_CPU_CMPLX_0,	0x4C*/
+	uint crc_osc_ctrl;		/* _OSC_CTRL_0,		0x50*/
+	uint crc_pll_lfsr;		/* _PLL_LFSR_0,		0x54*/
+	uint crc_osc_freq_det;		/* _OSC_FREQ_DET_0,	0x58*/
+	uint crc_osc_freq_det_stat;	/* _OSC_FREQ_DET_STATUS_0,0x5C*/
+	uint crc_reserved2[8];		/* reserved_2[8],	0x60-7C*/
+
+	uint crc_pllc_base;		/* _PLLC_BASE_0,	0x80*/
+	uint crc_pllc_out;		/* _PLLC_OUT_0,		0x84*/
+	uint crc_reserved3;		/* reserved_3,		0x88*/
+	uint crc_pllc_misc;		/* _PLLC_MISC_0,	0x8C*/
+
+	uint crc_pllm_base;		/* _PLLM_BASE_0,	0x90*/
+	uint crc_pllm_out;		/* _PLLM_OUT_0,		0x94*/
+	uint crc_reserved4;		/* reserved_4,		0x98*/
+	uint crc_pllm_misc;		/* _PLLM_MISC_0,	0x9C*/
+
+	uint crc_pllp_base;		/* _PLLP_BASE_0,	0xA0*/
+	uint crc_pllp_outa;		/* _PLLP_OUTA_0,	0xA4*/
+	uint crc_pllp_outb;		/* _PLLP_OUTB_0,	0xA8*/
+	uint crc_pllp_misc;		/* _PLLP_MISC_0,	0xAC*/
+
+	uint crc_plla_base;		/* _PLLA_BASE_0,	0xB0*/
+	uint crc_plla_out;		/* _PLLA_OUT_0,		0xB4*/
+	uint crc_reserved5;		/* reserved_5,		0xB8*/
+	uint crc_plla_misc;		/* _PLLA_MISC_0,	0xBC*/
+
+	uint crc_pllu_base;		/* _PLLU_BASE_0,	0xC0*/
+	uint crc_reserved6;		/* _reserved_6,		0xC4*/
+	uint crc_reserved7;		/* _reserved_7,		0xC8*/
+	uint crc_pllu_misc;		/* _PLLU_MISC_0,	0xCC*/
+
+	uint crc_plld_base;		/* _PLLD_BASE_0,	0xD0*/
+	uint crc_reserved8;		/* _reserved_8,		0xD4*/
+	uint crc_reserved9;		/* _reserved_9,		0xD8*/
+	uint crc_plld_misc;		/* _PLLD_MISC_0,	0xDC*/
+
+	uint crc_pllx_base;		/* _PLLX_BASE_0,	0xE0*/
+	uint crc_pllx_misc;		/* _PLLX_MISC_0,	0xE4*/
+
+	uint crc_plle_base;		/* _PLLE_BASE_0,	0xE8*/
+	uint crc_plle_misc;		/* _PLLE_MISC_0,	0xEC*/
+
+	uint crc_plls_base;		/* _PLLS_BASE_0,	0xF0*/
+	uint crc_plls_misc;		/* _PLLS_MISC_0,	0xF4*/
+	uint crc_reserved10;		/* _reserved_10,	0xF8*/
+	uint crc_reserved11;		/* _reserved_11,	0xFC*/
+
+	uint crc_clk_src_i2s1;		/*_I2S1_0,		0x100*/
+	uint crc_clk_src_i2s2;		/*_I2S2_0,		0x104*/
+	uint crc_clk_src_spdif_out;	/*_SPDIF_OUT_0,		0x108*/
+	uint crc_clk_src_spdif_in;	/*_SPDIF_IN_0,		0x10C*/
+	uint crc_clk_src_pwm;		/*_PWM_0,		0x110*/
+	uint crc_clk_src_spi1;		/*_SPI1_0,		0x114*/
+	uint crc_clk_src_sbc2;		/*_SBC2_0,		0x118*/
+	uint crc_clk_src_sbc3;		/*_SBC3_0,		0x11C*/
+	uint crc_clk_src_xio;		/*_XIO_0,		0x120*/
+	uint crc_clk_src_i2c1;		/*_I2C1_0,		0x124*/
+	uint crc_clk_src_dvc_i2c;	/*_DVC_I2C_0,		0x128*/
+	uint crc_clk_src_twc;		/*_TWC_0,		0x12C*/
+	uint crc_reserved12;		/*			0x130*/
+	uint crc_clk_src_sbc1;		/*_SBC1_0,		0x134*/
+	uint crc_clk_src_disp1;		/*_DISP1_0,		0x138*/
+	uint crc_clk_src_disp2;		/*_DISP2_0,		0x13C*/
+	uint crc_clk_src_cve;		/*_CVE_0,		0x140*/
+	uint crc_clk_src_ide;		/*_IDE_0,		0x144*/
+	uint crc_clk_src_vi;		/*_VI_0,		0x148*/
+	uint crc_reserved13;		/*			0x14C*/
+	uint crc_clk_src_sdmmc1;	/*_SDMMC1_0,		0x150*/
+	uint crc_clk_src_sdmmc2;	/*_SDMMC2_0,		0x154*/
+	uint crc_clk_src_g3d;		/*_G3D_0,		0x158*/
+	uint crc_clk_src_g2d;		/*_G2D_0,		0x15C*/
+	uint crc_clk_src_ndflash;	/*_NDFLASH_0,		0x160*/
+	uint crc_clk_src_sdmmc4;	/*_SDMMC4_0,		0x164*/
+	uint crc_clk_src_vfir;		/*_VFIR_0,		0x168*/
+	uint crc_clk_src_epp;		/*_EPP_0,		0x16C*/
+	uint crc_clk_src_mp3;		/*_MPE_0,		0x170*/
+	uint crc_clk_src_mipi;		/*_MIPI_0,		0x174*/
+	uint crc_clk_src_uarta;		/*_UARTA_0,		0x178*/
+	uint crc_clk_src_uartb;		/*_UARTB_0,		0x17C*/
+	uint crc_clk_src_host1x;	/*_HOST1X_0,		0x180*/
+	uint crc_reserved14;		/*			0x184*/
+	uint crc_clk_src_tvo;		/*_TVO_0,		0x188*/
+	uint crc_clk_src_hdmi;		/*_HDMI_0,		0x18C*/
+	uint crc_reserved15;		/*			0x190*/
+	uint crc_clk_src_tvdac;		/*_TVDAC_0,		0x194*/
+	uint crc_clk_src_i2c2;		/*_I2C2_0,		0x198*/
+	uint crc_clk_src_emc;		/*_EMC_0,		0x19C*/
+	uint crc_clk_src_uartc;		/*_UARTC_0,		0x1A0*/
+	uint crc_reserved16;		/*			0x1A4*/
+	uint crc_clk_src_vi_sensor;	/*_VI_SENSOR_0,		0x1A8*/
+	uint crc_reserved17;		/*			0x1AC*/
+	uint crc_reserved18;		/*			0x1B0*/
+	uint crc_clk_src_sbc4;		/*_SBC4_0,		0x1B4*/
+	uint crc_clk_src_i2c3;		/*_I2C3_0,		0x1B8*/
+	uint crc_clk_src_sdmmc3;	/*_SDMMC3_0,		0x1BC*/
+	uint crc_clk_src_uartd;		/*_UARTD_0,		0x1C0*/
+	uint crc_clk_src_uarte;		/*_UARTE_0,		0x1C4*/
+	uint crc_clk_src_vde;		/*_VDE_0,		0x1C8*/
+	uint crc_clk_src_owr;		/*_OWR_0,		0x1CC*/
+	uint crc_clk_src_nor;		/*_NOR_0,		0x1D0*/
+	uint crc_clk_src_csite;		/*_CSITE_0,		0x1D4*/
+	uint crc_reserved19[9];		/*			0x1D8-1F8*/
+	uint crc_clk_src_osc;		/*_OSC_0,		0x1FC*/
+} clk_rst_ctlr;
+
+#endif	/* CLK_RST_H */
diff --git a/arch/arm/include/asm/arch-tegra2/pinmux.h b/arch/arm/include/asm/arch-tegra2/pinmux.h
new file mode 100644
index 0000000..f56ddee
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/pinmux.h
@@ -0,0 +1,52 @@ 
+/*
+ *  (C) Copyright 2010,2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _PINMUX_H_
+#define _PINMUX_H_
+
+/* APB MISC Pin Mux and Tristate (APB_MISC_PP_) registers */
+
+typedef volatile struct pinmux_tri_ctlr {
+	uint pmt_reserved0;		/* ABP_MISC_PP_ reserved offset 00 */
+	uint pmt_reserved1;		/* ABP_MISC_PP_ reserved offset 04 */
+	uint pmt_strap_opt_a;		/* _STRAPPING_OPT_A_0, offset 08 */
+	uint pmt_reserved2;		/* ABP_MISC_PP_ reserved offset 0C */
+	uint pmt_reserved3;		/* ABP_MISC_PP_ reserved offset 10 */
+	uint pmt_tri_a;			/* _TRI_STATE_REG_A_0, offset 14 */
+	uint pmt_tri_b;			/* _TRI_STATE_REG_B_0, offset 18 */
+	uint pmt_tri_c;			/* _TRI_STATE_REG_C_0, offset 1C */
+	uint pmt_tri_d;			/* _TRI_STATE_REG_D_0, offset 20 */
+	uint pmt_cfg_ctl;		/* _CONFIG_CTL_0, offset 24 */
+
+	uint pmt_reserved[22];		/* ABP_MISC_PP_ reserved offs 28-7C */
+
+	uint pmt_ctl_a;			/* _PIN_MUX_CTL_A_0, offset 80 */
+	uint pmt_ctl_b;			/* _PIN_MUX_CTL_B_0, offset 84 */
+	uint pmt_ctl_c;			/* _PIN_MUX_CTL_C_0, offset 88 */
+	uint pmt_ctl_d;			/* _PIN_MUX_CTL_D_0, offset 8C */
+	uint pmt_ctl_e;			/* _PIN_MUX_CTL_E_0, offset 90 */
+	uint pmt_ctl_f;			/* _PIN_MUX_CTL_F_0, offset 94 */
+	uint pmt_ctl_g;			/* _PIN_MUX_CTL_G_0, offset 98 */
+} pinmux_tri_ctlr;
+
+#endif	/* PINMUX_H */
diff --git a/arch/arm/include/asm/arch-tegra2/pmc.h b/arch/arm/include/asm/arch-tegra2/pmc.h
new file mode 100644
index 0000000..a2112a3
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/pmc.h
@@ -0,0 +1,125 @@ 
+/*
+ *  (C) Copyright 2010,2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _PMC_H_
+#define _PMC_H_
+
+/* Power Management Controller (APBDEV_PMC_) registers */
+
+typedef volatile struct pmc_ctlr {
+	uint pmc_cntrl;			/* _CNTRL_0, offset 00 */
+	uint pmc_sec_disable;		/* _SEC_DISABLE_0, offset 04 */
+	uint pmc_pmc_swrst;		/* _PMC_SWRST_0, offset 08 */
+	uint pmc_wake_mask;		/* _WAKE_MASK_0, offset 0C */
+	uint pmc_wake_lvl;		/* _WAKE_LVL_0, offset 10 */
+	uint pmc_wake_status;		/* _WAKE_STATUS_0, offset 14 */
+	uint pmc_sw_wake_status;	/* _SW_WAKE_STATUS_0, offset 18 */
+	uint pmc_dpd_pads_oride;	/* _DPD_PADS_ORIDE_0, offset 1C */
+	uint pmc_dpd_sample;		/* _DPD_PADS_SAMPLE_0, offset 20 */
+	uint pmc_dpd_enable;		/* _DPD_PADS_ENABLE_0, offset 24 */
+	uint pmc_pwrgate_timer_off;	/* _PWRGATE_TIMER_OFF_0, offset 28 */
+	uint pmc_pwrgate_timer_on;	/* _PWRGATE_TIMER_ON_0, offset 2C */
+	uint pmc_pwrgate_toggle;	/* _PWRGATE_TOGGLE_0, offset 30 */
+	uint pmc_remove_clamping;	/* _REMOVE_CLAMPING_CMD_0, offset 34 */
+	uint pmc_pwrgate_status;	/* _PWRGATE_STATUS_0, offset 38 */
+	uint pmc_pwrgood_timer;		/* _PWRGOOD_TIMER_0, offset 3C */
+	uint pmc_blink_timer;		/* _BLINK_TIMER_0, offset 40 */
+	uint pmc_no_iopower;		/* _NO_IOPOWER_0, offset 44 */
+	uint pmc_pwr_det;		/* _PWR_DET_0, offset 48 */
+	uint pmc_pwr_det_latch;		/* _PWR_DET_LATCH_0, offset 4C */
+
+	uint pmc_scratch0;		/* _SCRATCH0_0, offset 50 */
+	uint pmc_scratch1;		/* _SCRATCH1_0, offset 54 */
+	uint pmc_scratch2;		/* _SCRATCH2_0, offset 58 */
+	uint pmc_scratch3;		/* _SCRATCH3_0, offset 5C */
+	uint pmc_scratch4;		/* _SCRATCH4_0, offset 60 */
+	uint pmc_scratch5;		/* _SCRATCH5_0, offset 64 */
+	uint pmc_scratch6;		/* _SCRATCH6_0, offset 68 */
+	uint pmc_scratch7;		/* _SCRATCH7_0, offset 6C */
+	uint pmc_scratch8;		/* _SCRATCH8_0, offset 70 */
+	uint pmc_scratch9;		/* _SCRATCH9_0, offset 74 */
+	uint pmc_scratch10;		/* _SCRATCH10_0, offset 78 */
+	uint pmc_scratch11;		/* _SCRATCH11_0, offset 7C */
+	uint pmc_scratch12;		/* _SCRATCH12_0, offset 80 */
+	uint pmc_scratch13;		/* _SCRATCH13_0, offset 84 */
+	uint pmc_scratch14;		/* _SCRATCH14_0, offset 88 */
+	uint pmc_scratch15;		/* _SCRATCH15_0, offset 8C */
+	uint pmc_scratch16;		/* _SCRATCH16_0, offset 90 */
+	uint pmc_scratch17;		/* _SCRATCH17_0, offset 94 */
+	uint pmc_scratch18;		/* _SCRATCH18_0, offset 98 */
+	uint pmc_scratch19;		/* _SCRATCH19_0, offset 9C */
+	uint pmc_scratch20;		/* _SCRATCH20_0, offset A0 */
+	uint pmc_scratch21;		/* _SCRATCH21_0, offset A4 */
+	uint pmc_scratch22;		/* _SCRATCH22_0, offset A8 */
+	uint pmc_scratch23;		/* _SCRATCH23_0, offset AC */
+
+	uint pmc_secure_scratch0;	/* _SECURE_SCRATCH0_0, offset B0 */
+	uint pmc_secure_scratch1;	/* _SECURE_SCRATCH1_0, offset B4 */
+	uint pmc_secure_scratch2;	/* _SECURE_SCRATCH2_0, offset B8 */
+	uint pmc_secure_scratch3;	/* _SECURE_SCRATCH3_0, offset BC */
+	uint pmc_secure_scratch4;	/* _SECURE_SCRATCH4_0, offset C0 */
+	uint pmc_secure_scratch5;	/* _SECURE_SCRATCH5_0, offset C4 */
+
+	uint pmc_cpupwrgood_timer;	/* _CPUPWRGOOD_TIMER_0, offset C8 */
+	uint pmc_cpupwroff_timer;	/* _CPUPWROFF_TIMER_0, offset CC */
+	uint pmc_pg_mask;		/* _PG_MASK_0, offset D0 */
+	uint pmc_pg_mask_1;		/* _PG_MASK_1_0, offset D4 */
+	uint pmc_auto_wake_lvl;		/* _AUTO_WAKE_LVL_0, offset D8 */
+	uint pmc_auto_wake_lvl_mask; 	/* _AUTO_WAKE_LVL_MASK_0, offset DC */
+	uint pmc_wake_delay;		/* _WAKE_DELAY_0, offset E0 */
+	uint pmc_pwr_det_val;		/* _PWR_DET_VAL_0, offset E4 */
+	uint pmc_ddr_pwr;		/* _DDR_PWR_0, offset E8 */
+	uint pmc_usb_debounce_del;	/* _USB_DEBOUNCE_DEL_0, offset EC */
+	uint pmc_usb_ao;		/* _USB_AO_0, offset F0 */
+	uint pmc_crypto_op;		/* _CRYPTO_OP__0, offset F4 */
+	uint pmc_pllp_wb0_override;	/* _PLLP_WB0_OVERRIDE_0, offset F8 */
+
+	uint pmc_scratch24;		/* _SCRATCH24_0, offset FC */
+	uint pmc_scratch25;		/* _SCRATCH24_0, offset 100 */
+	uint pmc_scratch26;		/* _SCRATCH24_0, offset 104 */
+	uint pmc_scratch27;		/* _SCRATCH24_0, offset 108 */
+	uint pmc_scratch28;		/* _SCRATCH24_0, offset 10C */
+	uint pmc_scratch29;		/* _SCRATCH24_0, offset 110 */
+	uint pmc_scratch30;		/* _SCRATCH24_0, offset 114 */
+	uint pmc_scratch31;		/* _SCRATCH24_0, offset 118 */
+	uint pmc_scratch32;		/* _SCRATCH24_0, offset 11C */
+	uint pmc_scratch33;		/* _SCRATCH24_0, offset 120 */
+	uint pmc_scratch34;		/* _SCRATCH24_0, offset 124 */
+	uint pmc_scratch35;		/* _SCRATCH24_0, offset 128 */
+	uint pmc_scratch36;		/* _SCRATCH24_0, offset 12C */
+	uint pmc_scratch37;		/* _SCRATCH24_0, offset 130 */
+	uint pmc_scratch38;		/* _SCRATCH24_0, offset 134 */
+	uint pmc_scratch39;		/* _SCRATCH24_0, offset 138 */
+	uint pmc_scratch40;		/* _SCRATCH24_0, offset 13C */
+	uint pmc_scratch41;		/* _SCRATCH24_0, offset 140 */
+	uint pmc_scratch42;		/* _SCRATCH24_0, offset 144 */
+
+	uint pmc_bo_mirror0;		/* _BOUNDOUT_MIRROR0_0, offset 148 */
+	uint pmc_bo_mirror1;		/* _BOUNDOUT_MIRROR1_0, offset 14C */
+	uint pmc_bo_mirror2;		/* _BOUNDOUT_MIRROR2_0, offset 150 */
+	uint pmc_sys_33v_en;		/* _SYS_33V_EN_0, offset 154 */
+	uint pmc_bo_mirror_access;	/* _BOUNDOUT_MIRROR_ACCESS_0, off158 */
+	uint pmc_gate;			/* _GATE_0, offset 15C */
+} pmc_ctlr;
+
+#endif	/* PMC_H */
diff --git a/arch/arm/include/asm/arch-tegra2/sys_proto.h b/arch/arm/include/asm/arch-tegra2/sys_proto.h
new file mode 100644
index 0000000..70e63a8
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/sys_proto.h
@@ -0,0 +1,33 @@ 
+/*
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+typedef struct {
+	char *board_string;
+} tegra2_sysinfo;
+
+void invalidate_dcache(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-tegra2/tegra2.h b/arch/arm/include/asm/arch-tegra2/tegra2.h
new file mode 100644
index 0000000..3bd0212
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/tegra2.h
@@ -0,0 +1,49 @@ 
+/*
+ * (C) Copyright 2010,2011
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _TEGRA2_H_
+#define _TEGRA2_H_
+
+#define NV_PA_SDRAM_BASE	0x00000000
+#define NV_PA_TMRUS_BASE	0x60005010
+#define NV_PA_CLK_RST_BASE	0x60006000
+#define NV_PA_APB_MISC_BASE	0x70000000
+#define NV_PA_APB_UARTA_BASE	(NV_PA_APB_MISC_BASE + 0x6000)
+#define NV_PA_APB_UARTB_BASE	(NV_PA_APB_MISC_BASE + 0x6040)
+#define NV_PA_APB_UARTC_BASE	(NV_PA_APB_MISC_BASE + 0x6200)
+#define NV_PA_APB_UARTD_BASE	(NV_PA_APB_MISC_BASE + 0x6300)
+#define NV_PA_APB_UARTE_BASE	(NV_PA_APB_MISC_BASE + 0x6400)
+#define NV_PA_PMC_BASE		0x7000E400
+
+#define TEGRA2_SDRC_CS0		NV_PA_SDRAM_BASE
+#define LOW_LEVEL_SRAM_STACK	0x4000FFFC
+
+#ifndef __ASSEMBLY__
+typedef volatile struct timerus {
+	unsigned int cntr_1us;
+} timerus_t;
+#else  /* __ASSEMBLY__ */
+#define PRM_RSTCTRL		NV_PA_PMC_BASE
+#endif
+
+#endif	/* TEGRA2_H */
diff --git a/arch/arm/include/asm/arch-tegra2/uart.h b/arch/arm/include/asm/arch-tegra2/uart.h
new file mode 100644
index 0000000..918f9b7
--- /dev/null
+++ b/arch/arm/include/asm/arch-tegra2/uart.h
@@ -0,0 +1,45 @@ 
+/*
+ *  (C) Copyright 2010,2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _UART_H_
+#define _UART_H_
+
+/* UART registers */
+
+typedef volatile struct uart_ctlr {
+	uint uart_thr_dlab_0;		/* UART_THR_DLAB_0_0, offset 00 */
+	uint uart_ier_dlab_0;		/* UART_IER_DLAB_0_0, offset 04 */
+	uint uart_iir_fcr;		/* UART_IIR_FCR_0, offset 08 */
+	uint uart_lcr;			/* UART_LCR_0, offset 0C */
+	uint uart_mcr;			/* UART_MCR_0, offset 10 */
+	uint uart_lsr;			/* UART_LSR_0, offset 14 */
+	uint uart_msr;			/* UART_MSR_0, offset 18 */
+	uint uart_spr;			/* UART_SPR_0, offset 1C */
+	uint uart_irda_csr;		/* UART_IRDA_CSR_0, offset 20 */
+	uint uart_reserved[6];		/* Reserved, unused */
+	uint uart_asr;			/* UART_ASR_0, offset 3C */
+} uart_ctlr;
+
+#define UART_FCR_TRIGGER_3	0x30	/* Mask for trigger set at 3 */
+
+#endif	/* UART_H */
diff --git a/board/nvidia/common/board.c b/board/nvidia/common/board.c
new file mode 100644
index 0000000..876facb
--- /dev/null
+++ b/board/nvidia/common/board.c
@@ -0,0 +1,249 @@ 
+/*
+ *  (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 <ns16550.h>
+#include <asm/io.h>
+#include <asm/mach-types.h>
+#include <asm/arch/tegra2.h>
+#include <asm/arch/sys_proto.h>
+#include "board.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+const tegra2_sysinfo sysinfo = {
+	CONFIG_TEGRA2_BOARD_STRING
+};
+
+/*
+ * Routine: board_init
+ * Description: Early hardware init.
+ */
+int board_init(void)
+{
+	/* boot param addr */
+	gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
+	/* board id for Linux */
+	gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+
+	return 0;
+}
+
+/*
+ * Routine: timer_init
+ * Description: init the timestamp and lastinc value
+ */
+int timer_init(void)
+{
+	reset_timer();
+	return 0;
+}
+
+/*
+ * Routine: uart_clock_init
+ * Description: init the PLL and clock for the UART in uart_num
+ */
+void uart_clock_init(int uart_num)
+{
+	clk_rst_ctlr *const clkrst = (clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+	static int pllp_init_done;
+	u32 reg;
+
+	if (!pllp_init_done) {
+
+		/* Override pllp setup for 216MHz operation. */
+		reg = (PLL_BYPASS | PLL_BASE_OVRRIDE | PLL_DIVP);
+		reg |= (((NVRM_PLLP_FIXED_FREQ_KHZ/500) << 8) | PLL_DIVM);
+		writel(reg, clkrst->crc_pllp_base);
+
+		reg |= PLL_ENABLE;
+		writel(reg, clkrst->crc_pllp_base);
+
+		reg &= ~PLL_BYPASS;
+		writel(reg, clkrst->crc_pllp_base);
+
+		pllp_init_done++;
+	}
+
+	/* Now do the UART reset/clock enable based on uart_num */
+#if CONFIG_TEGRA2_ENABLE_UARTA
+	if (uart_num == UART_A) {
+		/* Assert Reset to UART */
+		reg = readl(clkrst->crc_rst_dev_l);
+		reg |= SWR_UARTA_RST;		/* SWR_UARTA_RST = 1 */
+		writel(reg, clkrst->crc_rst_dev_l);
+
+		/* Enable clk to UART */
+		reg = readl(clkrst->crc_clk_out_enb_l);
+		reg |= CLK_ENB_UARTA;		/* CLK_ENB_UARTA = 1 */
+		writel(reg, clkrst->crc_clk_out_enb_l);
+
+		/* Enable pllp_out0 to UART */
+		reg = readl(clkrst->crc_clk_src_uarta);
+		reg &= 0x3FFFFFFF;	/* UARTA_CLK_SRC = 00, PLLP_OUT0 */
+		writel(reg, clkrst->crc_clk_src_uarta);
+
+		/* wait for 2us */
+		udelay(2);
+
+		/* De-assert reset to UART */
+		reg = readl(clkrst->crc_rst_dev_l);
+		reg &= ~SWR_UARTA_RST;		/* SWR_UARTA_RST = 0 */
+		writel(reg, clkrst->crc_rst_dev_l);
+	}
+#endif	/* CONFIG_TEGRA2_ENABLE_UARTA */
+#if CONFIG_TEGRA2_ENABLE_UARTD
+	if (uart_num == UART_D) {
+		/* Assert Reset to UART */
+		reg = readl(clkrst->crc_rst_dev_u);
+		reg |= SWR_UARTD_RST;		/* SWR_UARTD_RST = 1 */
+		writel(reg, clkrst->crc_rst_dev_u);
+
+		/* Enable clk to UART */
+		reg = readl(clkrst->crc_clk_out_enb_u);
+		reg |= CLK_ENB_UARTD;		/* CLK_ENB_UARTD = 1 */
+		writel(reg, clkrst->crc_clk_out_enb_u);
+
+		/* Enable pllp_out0 to UART */
+		reg = readl(clkrst->crc_clk_src_uartd);
+		reg &= 0x3FFFFFFF;	/* UARTD_CLK_SRC = 00, PLLP_OUT0 */
+		writel(reg, clkrst->crc_clk_src_uartd);
+
+		/* wait for 2us */
+		udelay(2);
+
+		/* De-assert reset to UART */
+		reg = readl(clkrst->crc_rst_dev_u);
+		reg &= ~SWR_UARTD_RST;		/* SWR_UARTD_RST = 0 */
+		writel(reg, clkrst->crc_rst_dev_u);
+	}
+#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
+}
+
+/*
+ * Routine: pin_mux_uart
+ * Description: setup the pin muxes/tristate values for UART based on uart_num
+ */
+void pin_mux_uart(int uart_num)
+{
+	pinmux_tri_ctlr *const pmt = (pinmux_tri_ctlr *)NV_PA_APB_MISC_BASE;
+	u32 reg;
+
+#if CONFIG_TEGRA2_ENABLE_UARTA
+	if (uart_num  == UART_A) {
+		reg = readl(pmt->pmt_ctl_c);
+		reg &= 0xFFF0FFFF;	/* IRRX_/IRTX_SEL [19:16] = 00 UARTA */
+		writel(reg, pmt->pmt_ctl_c);
+
+		reg = readl(pmt->pmt_tri_a);
+		reg &= ~Z_IRRX;		/* Z_IRRX = normal (0) */
+		reg &= ~Z_IRTX;		/* Z_IRTX = normal (0) */
+		writel(reg, pmt->pmt_tri_a);
+	}
+#endif	/* CONFIG_TEGRA2_ENABLE_UARTA */
+#if CONFIG_TEGRA2_ENABLE_UARTD
+	if (uart_num == UART_D) {
+		reg = readl(pmt->pmt_ctl_b);
+		reg &= 0xFFFFFFF3;	/* GMC_SEL [3:2] = 00, UARTD */
+		writel(reg, pmt->pmt_ctl_b);
+
+		reg = readl(pmt->pmt_tri_a);
+		reg &= ~Z_GMC;		/* Z_GMC = normal (0) */
+		writel(reg, pmt->pmt_tri_a);
+	}
+#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
+}
+
+void setup_uart(uart_ctlr *u)
+{
+	u32 reg;
+
+	/* Prepare the divisor value */
+	reg = NVRM_PLLP_FIXED_FREQ_KHZ * 1000 / NV_DEFAULT_DEBUG_BAUD / 16;
+
+	/* Set up UART parameters */
+	writel(UART_LCR_DLAB, u->uart_lcr);
+	writel(reg, u->uart_thr_dlab_0);
+	writel(0, u->uart_ier_dlab_0);
+	writel(0, u->uart_lcr);			/* clear DLAB */
+	writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN | \
+		UART_FCR_CLEAR_XMIT | UART_FCR_CLEAR_RCVR), u->uart_iir_fcr);
+	writel(0, u->uart_ier_dlab_0);
+	writel(UART_LCR_WLS_8, u->uart_lcr);	/* 8N1 */
+	writel(UART_MCR_RTS, u->uart_mcr);
+	writel(0, u->uart_msr);
+	writel(0, u->uart_spr);
+	writel(0, u->uart_irda_csr);
+	writel(0, u->uart_asr);
+	writel((UART_FCR_TRIGGER_3 | UART_FCR_FIFO_EN), u->uart_iir_fcr);
+
+	/* Flush any old characters out of the RX FIFO */
+	reg = readl(u->uart_lsr);
+
+	while (reg & UART_LSR_DR) {
+		reg = readl(u->uart_thr_dlab_0);
+		reg = readl(u->uart_lsr);
+	}
+}
+
+/*
+ * Routine: init_uart
+ * Description: init the UART clocks, muxes, and baudrate/parity/etc.
+ */
+void init_uart(int uart_num)
+{
+#if CONFIG_TEGRA2_ENABLE_UARTA
+	if (uart_num == UART_A) {
+		uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTA_BASE;
+
+		uart_clock_init(UART_A);
+
+		/* Enable UARTA - uses config 0 */
+		pin_mux_uart(UART_A);
+
+		setup_uart(uart);
+	}
+#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
+#if CONFIG_TEGRA2_ENABLE_UARTD
+	if (uart_num == UART_D) {
+		uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTD_BASE;
+
+		uart_clock_init(UART_D);
+
+		/* Enable UARTD - uses config 0 */
+		pin_mux_uart(UART_D);
+
+		setup_uart(uart);
+	}
+#endif	/* CONFIG_TEGRA2_ENABLE_UARTD */
+}
+
+void uart_init(void)
+{
+#if (CONFIG_TEGRA2_ENABLE_UARTA)
+	init_uart(UART_A);
+#endif
+#if (CONFIG_TEGRA2_ENABLE_UARTD)
+	init_uart(UART_D);
+#endif
+}
diff --git a/board/nvidia/common/board.h b/board/nvidia/common/board.h
new file mode 100644
index 0000000..d49e978
--- /dev/null
+++ b/board/nvidia/common/board.h
@@ -0,0 +1,57 @@ 
+/*
+ *  (C) Copyright 2010,2011
+ *  NVIDIA Corporation <www.nvidia.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _COMMON_BOARD_H_
+#define _COMMON_BOARD_H_
+
+#include <asm/arch/clk_rst.h>
+#include <asm/arch/pinmux.h>
+#include <asm/arch/uart.h>
+
+#define NVRM_PLLP_FIXED_FREQ_KHZ	216000
+#define NV_DEFAULT_DEBUG_BAUD		115200
+
+#define PLL_BYPASS		(1 << 31)
+#define PLL_ENABLE		(1 << 30)
+#define PLL_BASE_OVRRIDE	(1 << 28)
+#define PLL_DIVP		(1 << 20)	/* post divider, b22:20 */
+#define PLL_DIVM		0x0C		/* input divider, b4:0 */
+
+#define SWR_UARTD_RST		(1 << 2)
+#define CLK_ENB_UARTD		(1 << 2)
+#define SWR_UARTA_RST		(1 << 6)
+#define CLK_ENB_UARTA		(1 << 6)
+
+#define Z_GMC			(1 << 29)
+#define Z_IRRX			(1 << 20)
+#define Z_IRTX			(1 << 19)
+
+enum {
+	UART_A = 1,
+	UART_B,
+	UART_C,
+	UART_D,
+	UART_E
+};
+
+#endif /* _COMMON_BOARD_H_ */