[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