u-boot/board/nvidia/common/board.c
Simon Glass a04eba99f5 tegra2: Plumb in SPI/UART switch code
On Seaboard the UART and SPI interfere with each other. This causes the UART
to receive spurious zero bytes after SPI transactions and also means that
SPI can corrupt a few output characters when it starts up if they are still
in the UART buffer.

This updates the board to use the SPI/UART switch to avoid the problem.

For now this feature is turned off since it needs changes to the NS16550
UART to operate.

Signed-off-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Tom Warren <twarren@nvidia.com>
2011-12-24 10:23:31 +01:00

166 lines
3.6 KiB
C

/*
* (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 <asm/arch/sys_proto.h>
#include <asm/arch/clk_rst.h>
#include <asm/arch/clock.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/uart.h>
#include <spi.h>
#include "board.h"
DECLARE_GLOBAL_DATA_PTR;
enum {
/* UARTs which we can enable */
UARTA = 1 << 0,
UARTB = 1 << 1,
UARTD = 1 << 3,
};
const struct tegra2_sysinfo sysinfo = {
CONFIG_TEGRA2_BOARD_STRING
};
/*
* Routine: timer_init
* Description: init the timestamp and lastinc value
*/
int timer_init(void)
{
return 0;
}
static void enable_uart(enum periph_id pid)
{
/* Assert UART reset and enable clock */
reset_set_enable(pid, 1);
clock_enable(pid);
clock_ll_set_source(pid, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
/* wait for 2us */
udelay(2);
/* De-assert reset to UART */
reset_set_enable(pid, 0);
}
/*
* Routine: clock_init_uart
* Description: init clock for the UART(s)
*/
static void clock_init_uart(int uart_ids)
{
if (uart_ids & UARTA)
enable_uart(PERIPH_ID_UART1);
if (uart_ids & UARTB)
enable_uart(PERIPH_ID_UART2);
if (uart_ids & UARTD)
enable_uart(PERIPH_ID_UART4);
}
/*
* Routine: pin_mux_uart
* Description: setup the pin muxes/tristate values for the UART(s)
*/
static void pin_mux_uart(int uart_ids)
{
if (uart_ids & UARTA) {
pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA);
pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA);
pinmux_tristate_disable(PINGRP_IRRX);
pinmux_tristate_disable(PINGRP_IRTX);
}
if (uart_ids & UARTB) {
pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA);
pinmux_tristate_disable(PINGRP_UAD);
}
if (uart_ids & UARTD) {
pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD);
pinmux_tristate_disable(PINGRP_GMC);
}
}
/*
* Routine: board_init
* Description: Early hardware init.
*/
int board_init(void)
{
/* Do clocks and UART first so that printf() works */
clock_init();
clock_verify();
#ifdef CONFIG_SPI_UART_SWITCH
gpio_config_uart();
#endif
#ifdef CONFIG_TEGRA2_SPI
spi_init();
#endif
/* boot param addr */
gd->bd->bi_boot_params = (NV_PA_SDRAM_BASE + 0x100);
return 0;
}
#ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void)
{
int uart_ids = 0; /* bit mask of which UART ids to enable */
#ifdef CONFIG_TEGRA2_ENABLE_UARTA
uart_ids |= UARTA;
#endif
#ifdef CONFIG_TEGRA2_ENABLE_UARTB
uart_ids |= UARTB;
#endif
#ifdef CONFIG_TEGRA2_ENABLE_UARTD
uart_ids |= UARTD;
#endif
/* We didn't do this init in start.S, so do it now */
cpu_init_cp15();
/* Initialize essential common plls */
clock_early_init();
/* Initialize UART clocks */
clock_init_uart(uart_ids);
/* Initialize periph pinmuxes */
pin_mux_uart(uart_ids);
/* Initialize periph GPIOs */
#ifdef CONFIG_SPI_UART_SWITCH
gpio_early_init_uart();
#else
gpio_config_uart();
#endif
return 0;
}
#endif /* EARLY_INIT */