From patchwork Fri Jan 21 23:06:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Warren X-Patchwork-Id: 79961 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 76EB3B70EA for ; Sat, 22 Jan 2011 10:07:53 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4D07F2817C; Sat, 22 Jan 2011 00:07:44 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id lvDyCyQREfHN; Sat, 22 Jan 2011 00:07:44 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 40D612820E; Sat, 22 Jan 2011 00:07:34 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 46813281C5 for ; Sat, 22 Jan 2011 00:07:31 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T20U-2efExXa for ; Sat, 22 Jan 2011 00:07:26 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pz0-f44.google.com (mail-pz0-f44.google.com [209.85.210.44]) by theia.denx.de (Postfix) with ESMTPS id 3ED072817A for ; Sat, 22 Jan 2011 00:07:24 +0100 (CET) Received: by pzk5 with SMTP id 5so406876pzk.3 for ; Fri, 21 Jan 2011 15:07:22 -0800 (PST) Received: by 10.142.125.16 with SMTP id x16mr1279008wfc.195.1295651241630; Fri, 21 Jan 2011 15:07:21 -0800 (PST) Received: from localhost.localdomain (ip70-190-110-83.ph.ph.cox.net [70.190.110.83]) by mx.google.com with ESMTPS id x35sm13284361wfd.13.2011.01.21.15.07.20 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 21 Jan 2011 15:07:21 -0800 (PST) From: Tom Warren To: u-boot@lists.denx.de Date: Fri, 21 Jan 2011 16:06:55 -0700 Message-Id: <1295651217-32421-3-git-send-email-twarren@nvidia.com> X-Mailer: git-send-email 1.7.3.5 In-Reply-To: <1295651217-32421-1-git-send-email-twarren@nvidia.com> References: <1295651217-32421-1-git-send-email-twarren@nvidia.com> Cc: ptyser@xes-inc.com, Tom Warren , twarren.nvidia@gmail.com Subject: [U-Boot] [PATCH V5 2/4] serial: Add Tegra2 serial port support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Signed-off-by: Tom Warren --- Changes for V2: - Move serial driver to separate patch Changes for V5: - Move arch/arm/cpu/armv7/uart.c & board.h to drivers/serial and rename to serial_tegra2.c - Remove use of uart_num & UART_A/D in serial_tegra2, simplify code arch/arm/cpu/armv7/tegra2/Makefile | 2 +- arch/arm/cpu/armv7/tegra2/board.c | 2 +- arch/arm/cpu/armv7/tegra2/board.h | 58 ---------- arch/arm/cpu/armv7/tegra2/uart.c | 216 ------------------------------------ common/serial.c | 3 +- drivers/serial/Makefile | 1 + drivers/serial/serial_tegra2.c | 205 ++++++++++++++++++++++++++++++++++ drivers/serial/serial_tegra2.h | 49 ++++++++ include/serial.h | 3 +- 9 files changed, 261 insertions(+), 278 deletions(-) delete mode 100644 arch/arm/cpu/armv7/tegra2/board.h delete mode 100644 arch/arm/cpu/armv7/tegra2/uart.c create mode 100644 drivers/serial/serial_tegra2.c create mode 100644 drivers/serial/serial_tegra2.h diff --git a/arch/arm/cpu/armv7/tegra2/Makefile b/arch/arm/cpu/armv7/tegra2/Makefile index f5b657b..687c887 100644 --- a/arch/arm/cpu/armv7/tegra2/Makefile +++ b/arch/arm/cpu/armv7/tegra2/Makefile @@ -28,7 +28,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).o SOBJS := lowlevel_init.o -COBJS := board.o sys_info.o timer.o uart.o +COBJS := board.o sys_info.o timer.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/arch/arm/cpu/armv7/tegra2/board.c b/arch/arm/cpu/armv7/tegra2/board.c index 816a8cd..1e92d98 100644 --- a/arch/arm/cpu/armv7/tegra2/board.c +++ b/arch/arm/cpu/armv7/tegra2/board.c @@ -25,7 +25,7 @@ #include #include #include -#include "board.h" +#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/arm/cpu/armv7/tegra2/board.h b/arch/arm/cpu/armv7/tegra2/board.h deleted file mode 100644 index f8f09c0..0000000 --- a/arch/arm/cpu/armv7/tegra2/board.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * (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 - */ - -#ifndef _BOARD_H_ -#define _BOARD_H_ - -#include -#include -#include -#include - -#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 /* _BOARD_H_ */ diff --git a/arch/arm/cpu/armv7/tegra2/uart.c b/arch/arm/cpu/armv7/tegra2/uart.c deleted file mode 100644 index 5e60bd8..0000000 --- a/arch/arm/cpu/armv7/tegra2/uart.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * (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) { - 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) { - 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/common/serial.c b/common/serial.c index 051ae4e..8ebf9a5 100644 --- a/common/serial.c +++ b/common/serial.c @@ -41,7 +41,8 @@ struct serial_device *__default_serial_console (void) #elif defined(CONFIG_4xx) \ || defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) \ || defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) \ - || defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) + || defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) \ + || defined(CONFIG_TEGRA2) #if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL) #if (CONFIG_CONS_INDEX==1) return &eserial1_device; diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 7d221fc..5a6011e 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -55,6 +55,7 @@ COBJS-$(CONFIG_S3C24X0_SERIAL) += serial_s3c24x0.o COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o +COBJS-$(CONFIG_TEGRA2) += serial_tegra2.o COBJS-$(CONFIG_USB_TTY) += usbtty.o COBJS := $(sort $(COBJS-y)) diff --git a/drivers/serial/serial_tegra2.c b/drivers/serial/serial_tegra2.c new file mode 100644 index 0000000..64dc6b4 --- /dev/null +++ b/drivers/serial/serial_tegra2.c @@ -0,0 +1,205 @@ +/* + * (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 "serial_tegra2.h" + +/* + * Routine: uart_clock_init + * Description: init the PLL and clock for the UART + */ +static void uart_clock_init(void) +{ + 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 */ +#if CONFIG_TEGRA2_ENABLE_UARTA + /* 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 + /* 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 a UART + */ +static void pin_mux_uart(void) +{ + pinmux_tri_ctlr *const pmt = (pinmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + u32 reg; + +#if CONFIG_TEGRA2_ENABLE_UARTA + 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 + 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(void) +{ +#if CONFIG_TEGRA2_ENABLE_UARTA + uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTA_BASE; + + uart_clock_init(); + + /* Enable UARTA - uses config 0 */ + pin_mux_uart(); + + setup_uart(uart); +#endif /* CONFIG_TEGRA2_ENABLE_UARTD */ +#if CONFIG_TEGRA2_ENABLE_UARTD + uart_ctlr *const uart = (uart_ctlr *)NV_PA_APB_UARTD_BASE; + + uart_clock_init(); + + /* Enable UARTD - uses config 0 */ + pin_mux_uart(); + + setup_uart(uart); +#endif /* CONFIG_TEGRA2_ENABLE_UARTD */ +} + +void uart_init(void) +{ + /* Init each UART - there may be more than 1 on a board/build */ +#if (CONFIG_TEGRA2_ENABLE_UARTA) + init_uart(); +#endif +#if (CONFIG_TEGRA2_ENABLE_UARTD) + init_uart(); +#endif +} diff --git a/drivers/serial/serial_tegra2.h b/drivers/serial/serial_tegra2.h new file mode 100644 index 0000000..a8ead9f --- /dev/null +++ b/drivers/serial/serial_tegra2.h @@ -0,0 +1,49 @@ +/* + * (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 + */ + +#ifndef _SERIAL_TEGRA_H_ +#define _SERIAL_TEGRA_H_ + +#include +#include +#include + +#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) + +#endif /* _SERIAL_TEGRA_H_ */ diff --git a/include/serial.h b/include/serial.h index 15ab73c..f21d961 100644 --- a/include/serial.h +++ b/include/serial.h @@ -27,7 +27,8 @@ extern struct serial_device * default_serial_console (void); defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) || \ defined(CONFIG_MB86R0x) || defined(CONFIG_MPC5xxx) || \ defined(CONFIG_MPC83xx) || defined(CONFIG_MPC85xx) || \ - defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) + defined(CONFIG_MPC86xx) || defined(CONFIG_SYS_SC520) || \ + defined(CONFIG_TEGRA2) extern struct serial_device serial0_device; extern struct serial_device serial1_device; #if defined(CONFIG_SYS_NS16550_SERIAL)