[U-Boot] [PATCH V4 1/4] arm: Tegra2: Add basic NVIDIA Tegra2 SoC support
seedshope
bocui107 at gmail.com
Fri Jan 21 17:49:11 CET 2011
On 01/22/2011 12:35 AM, seedshope wrote:
> 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
I am sorry, just see the tegra2-common.h file, UARTA is for keypad,
UARTB for debug.
But I feel the line of "if (uart_num == UART_A) " is not necessary.
Because CONFIG_TEGRA2_ENABLE_UARTA
have already represent UART_A.
You only use as following:
#ifdef CONFIG_TEGRA2_ENABLE_UARTA
#endif
Thanks,
seedshope
>
>> + 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