[U-Boot] [PATCH V4 1/4] arm: Tegra2: Add basic NVIDIA Tegra2 SoC support
seedshope
bocui107 at gmail.com
Fri Jan 21 17:35:54 CET 2011
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<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
> + */
> +
> +#include<common.h>
> +#include<ns16550.h>
> +#include<asm/io.h>
> +#include<asm/arch/tegra2.h>
> +#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
> +}
>
More information about the U-Boot
mailing list