From mboxrd@z Thu Jan 1 00:00:00 1970 From: seedshope Date: Sat, 22 Jan 2011 00:35:54 +0800 Subject: [U-Boot] [PATCH V4 1/4] arm: Tegra2: Add basic NVIDIA Tegra2 SoC support In-Reply-To: <1295570542-10607-2-git-send-email-twarren@nvidia.com> References: <1295570542-10607-1-git-send-email-twarren@nvidia.com> <1295570542-10607-2-git-send-email-twarren@nvidia.com> Message-ID: <4D39B5EA.9080506@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On 01/21/2011 08:42 AM, Tom Warren wrote: > + > +enum { > + UART_A = 1, > + UART_B, > + UART_C, > + UART_D, > + UART_E > +}; > + > +#endif /* _BOARD_H_ */ > > > diff --git a/arch/arm/cpu/armv7/tegra2/uart.c b/arch/arm/cpu/armv7/tegra2/uart.c > new file mode 100644 > index 0000000..5e60bd8 > --- /dev/null > +++ b/arch/arm/cpu/armv7/tegra2/uart.c > @@ -0,0 +1,216 @@ > +/* > + * (C) Copyright 2010,2011 > + * NVIDIA Corporation > + * > + * 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 > +#include > +#include > +#include > +#include "board.h" > + > +/* > + * Routine: uart_clock_init > + * Description: init the PLL and clock for the UART in uart_num > + */ > +static 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 > + */ > +static 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) { Why you need get the parameters uart_num, I think if you want to use CONFIG_TEGRA2_ENABLE_UARTA, You only defined CONFIG_TEGRA2_ENABLE_UARTA in include/configs/seaboard.h or include/configs/tegra2-common.h. Here, The code formats may be as following: #ifdef CONFIG_SERIAL1 ...... #elif defined(CONFIG_SERIAL2) ...... #else ...... #endif > + 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 */ > +} > + > +static 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. > + */ > +static void init_uart(int uart_num) > +{ > +#if CONFIG_TEGRA2_ENABLE_UARTA > + if (uart_num == UART_A) { above. Thanks seedshope > + 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 > +} >