[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