On 01/19/11 23:19, Tom Warren wrote: > Signed-off-by: Tom Warren <twar...@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. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot