
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_ */