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

Mike Rapoport mike at compulab.co.il
Mon Jan 24 12:55:21 CET 2011


On 01/19/11 23:19, Tom Warren wrote:
> Signed-off-by: Tom Warren <twarren at 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_ */


-- 
Sincerely yours,
Mike.


More information about the U-Boot mailing list