diff options
Diffstat (limited to 'board/nvidia/seaboard/seaboard.c')
-rw-r--r-- | board/nvidia/seaboard/seaboard.c | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/board/nvidia/seaboard/seaboard.c b/board/nvidia/seaboard/seaboard.c index 4b9a8f33e89..86655098faa 100644 --- a/board/nvidia/seaboard/seaboard.c +++ b/board/nvidia/seaboard/seaboard.c @@ -23,8 +23,14 @@ #include <common.h> #include <asm/io.h> -#include <asm/arch/tegra2.h> +#include <ns16550.h> +#include <asm/arch/bitfield.h> #include <asm/arch/gpio.h> +#include <asm/arch/pinmux.h> +#include <asm/arch/tegra2.h> +#include <asm/arch/tegra2_spi.h> + +static enum spi_uart_switch switch_pos; /* * Routine: gpio_config_uart @@ -32,21 +38,48 @@ */ void gpio_config_uart(void) { - int gp = GPIO_PI3; - struct gpio_ctlr *gpio = (struct gpio_ctlr *)NV_PA_GPIO_BASE; - struct gpio_ctlr_bank *bank = &gpio->gpio_bank[GPIO_BANK(gp)]; - u32 val; - - /* Enable UART via GPIO_PI3 (port 8, bit 3) so serial console works */ - val = readl(&bank->gpio_config[GPIO_PORT(gp)]); - val |= 1 << GPIO_BIT(gp); - writel(val, &bank->gpio_config[GPIO_PORT(gp)]); - - val = readl(&bank->gpio_out[GPIO_PORT(gp)]); - val &= ~(1 << GPIO_BIT(gp)); - writel(val, &bank->gpio_out[GPIO_PORT(gp)]); - - val = readl(&bank->gpio_dir_out[GPIO_PORT(gp)]); - val |= 1 << GPIO_BIT(gp); - writel(val, &bank->gpio_dir_out[GPIO_PORT(gp)]); + gpio_direction_output(UART_DISABLE_GPIO, 0); + switch_pos = SWITCH_UART; +} + +#ifdef CONFIG_SPI_CORRUPTS_UART + +void seaboard_switch_spi_uart(enum spi_uart_switch new_pos) +{ + struct pmux_tri_ctlr *pmt = (struct pmux_tri_ctlr *)NV_PA_APB_MISC_BASE; + + if (new_pos == switch_pos) + return; + + /* if the UART was selected, allow it to drain */ + if (switch_pos == SWITCH_UART) + NS16550_drain((NS16550_t)CONFIG_SPI_CORRUPTS_UART, + CONFIG_SPI_CORRUPTS_UART_NR); + + /* We need to dynamically change the pinmux, shared w/UART RXD/CTS */ + bf_writel(GMC_SEL_SFLASH, new_pos == SWITCH_SPI ? 3 : 0, + &pmt->pmt_ctl_b); + + /* + * On Seaboard, MOSI/MISO are shared w/UART. + * Use GPIO I3 (UART_DISABLE) to tristate UART during SPI activity. + * Enable UART later (cs_deactivate) so we can use it for U-Boot comms. + */ + gpio_direction_output(UART_DISABLE_GPIO, new_pos == SWITCH_SPI); + switch_pos = new_pos; + + /* if the SPI was selected, clear any junk bytes in the UART */ + if (switch_pos == SWITCH_UART) { + /* TODO: What if it is part-way through clocking in junk? */ + udelay(100); + NS16550_clear((NS16550_t)CONFIG_SPI_CORRUPTS_UART, + CONFIG_SPI_CORRUPTS_UART_NR); + } +} + +void enable_uart(void) +{ + seaboard_switch_spi_uart(SWITCH_UART); } + +#endif |