From patchwork Thu Oct 20 19:03:27 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 120857 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 9B1701007D1 for ; Fri, 21 Oct 2011 06:05:30 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9A70B2914A; Thu, 20 Oct 2011 21:05:24 +0200 (CEST) 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 4wmCDwswoZmD; Thu, 20 Oct 2011 21:05:24 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 73110291D7; Thu, 20 Oct 2011 21:05:12 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E14112916F for ; Thu, 20 Oct 2011 21:05:08 +0200 (CEST) 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 nQp58CQs9Gby for ; Thu, 20 Oct 2011 21:05:08 +0200 (CEST) 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 smtp-out.google.com (smtp-out.google.com [74.125.121.67]) by theia.denx.de (Postfix) with ESMTPS id 7943928F65 for ; Thu, 20 Oct 2011 21:04:54 +0200 (CEST) Received: from wpaz29.hot.corp.google.com (wpaz29.hot.corp.google.com [172.24.198.93]) by smtp-out.google.com with ESMTP id p9KJ4met018506; Thu, 20 Oct 2011 12:04:48 -0700 Received: from sglass.mtv.corp.google.com (sglass.mtv.corp.google.com [172.22.72.144]) by wpaz29.hot.corp.google.com with ESMTP id p9KJ4kkb004870; Thu, 20 Oct 2011 12:04:47 -0700 Received: by sglass.mtv.corp.google.com (Postfix, from userid 121222) id 9F977140F2C; Thu, 20 Oct 2011 12:04:46 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Date: Thu, 20 Oct 2011 12:03:27 -0700 Message-Id: <1319137409-4132-7-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 1.7.3.1 In-Reply-To: <1319137409-4132-1-git-send-email-sjg@chromium.org> References: <1319137409-4132-1-git-send-email-sjg@chromium.org> X-System-Of-Record: true Cc: Tom Warren Subject: [U-Boot] [PATCH 6/8] tegra2: Implement SPI / UART GPIO switch 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 The Tegra2 Seaboard has the unfortunate feature that SPI and the console UART are multiplexed on the same pins. We need to switch between one and the other during SPI and console activity. This new file implements a switch and keeps track of which peripheral owns the pins. It also flips over the controlling GPIO as needed Signed-off-by: Simon Glass --- board/nvidia/common/Makefile | 53 ++++++++++++++ board/nvidia/common/uart-spi-fix.c | 140 ++++++++++++++++++++++++++++++++++++ board/nvidia/seaboard/Makefile | 1 - include/uart-spi-fix.h | 45 ++++++++++++ 4 files changed, 238 insertions(+), 1 deletions(-) create mode 100644 board/nvidia/common/Makefile create mode 100644 board/nvidia/common/uart-spi-fix.c create mode 100644 include/uart-spi-fix.h diff --git a/board/nvidia/common/Makefile b/board/nvidia/common/Makefile new file mode 100644 index 0000000..bf6d11a --- /dev/null +++ b/board/nvidia/common/Makefile @@ -0,0 +1,53 @@ +# Copyright (c) 2011 The Chromium OS Authors. +# 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 $(TOPDIR)/config.mk + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)board/$(VENDOR)/common) +endif + +LIB = $(obj)lib$(VENDOR).o + +COBJS-y += board.o +COBJS-$(CONFIG_SPI_UART_SWITCH) += uart-spi-fix.o + +COBJS := $(COBJS-y) +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) +SOBJS := $(addprefix $(obj),$(SOBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) $(SOBJS) + $(call cmd_link_o_target, $(OBJS) $(SOBJS)) + +clean: + rm -f $(SOBJS) $(OBJS) + +distclean: clean + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### +# This is for $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/nvidia/common/uart-spi-fix.c b/board/nvidia/common/uart-spi-fix.c new file mode 100644 index 0000000..e03857e --- /dev/null +++ b/board/nvidia/common/uart-spi-fix.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * + * 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 "uart-spi-fix.h" +#include +#include +#include +#include +#include +#include + + +/* position of the UART/SPI select switch */ +enum spi_uart_switch { + SWITCH_UNKNOWN, + SWITCH_SPI, + SWITCH_UART, + SWITCH_BOTH +}; + +/* Information about the spi/uart switch */ +struct spi_uart { + int gpio; /* GPIO to control switch */ + NS16550_t regs; /* Address of UART affected */ + u32 port; /* Port number of UART affected */ +}; + +static struct spi_uart local; +static enum spi_uart_switch switch_pos; /* Current switch position */ + + +static void get_config(struct spi_uart *config) +{ +#if defined CONFIG_SPI_CORRUPTS_UART + config->gpio = UART_DISABLE_GPIO; + config->regs = (NS16550_t)CONFIG_SPI_CORRUPTS_UART; + config->port = CONFIG_SPI_CORRUPTS_UART_NR; +#else + config->gpio = -1; +#endif +} + +/* + * Init the UART / SPI switch. This can be called before relocation so we must + * not access BSS. + */ +void gpio_early_init_uart(void) +{ + struct spi_uart config; + + get_config(&config); + if (config.gpio != -1) + gpio_direction_output(config.gpio, 0); + switch_pos = SWITCH_BOTH; +} + +/* + * Configure the UART / SPI switch. + */ +void gpio_config_uart(void) +{ + get_config(&local); + switch_pos = SWITCH_BOTH; + if (local.gpio != -1) { + gpio_direction_output(local.gpio, 0); + switch_pos = SWITCH_UART; + } else { + /* + * If we're here we don't have a SPI switch; go ahead and + * enable the SPI now. We didn't in spi_init() so we wouldn't + * kill the UART. + */ + pinmux_set_func(PINGRP_GMC, PMUX_FUNC_SFLASH); + switch_pos = SWITCH_BOTH; + } +} + +static void spi_uart_switch(struct spi_uart *config, + enum spi_uart_switch new_pos) +{ + if (switch_pos == SWITCH_BOTH || new_pos == switch_pos) + return; + + /* if the UART was selected, allow it to drain */ + if (switch_pos == SWITCH_UART) + NS16550_drain(config->regs, config->port); + + /* We need to dynamically change the pinmux, shared w/UART RXD/CTS */ + pinmux_set_func(PINGRP_GMC, new_pos == SWITCH_SPI ? + PMUX_FUNC_SFLASH : PMUX_FUNC_UARTD); + + /* + * 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(config->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(config->regs, config->port); + } +} + +void uart_enable(NS16550_t regs) +{ + /* Also prevents calling spi_uart_switch() before relocation */ + if (regs == local.regs) + spi_uart_switch(&local, SWITCH_UART); +} + +void spi_enable(void) +{ + spi_uart_switch(&local, SWITCH_SPI); +} diff --git a/board/nvidia/seaboard/Makefile b/board/nvidia/seaboard/Makefile index aab185e..7b67a26 100644 --- a/board/nvidia/seaboard/Makefile +++ b/board/nvidia/seaboard/Makefile @@ -31,7 +31,6 @@ endif LIB = $(obj)lib$(BOARD).o COBJS := $(BOARD).o -COBJS += ../common/board.o SRCS := $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/include/uart-spi-fix.h b/include/uart-spi-fix.h new file mode 100644 index 0000000..68a7eb1 --- /dev/null +++ b/include/uart-spi-fix.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * 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 + */ + + +#if defined(CONFIG_SPI_UART_SWITCH) + +#ifndef __ASSEMBLY__ +/* + * Signal that we are about to use the UART. This unfortunate hack is + * required by Seaboard, which cannot use its console and SPI at the same + * time! If the board file provides this, the board config will declare it. + * Let this be a lesson for others. + */ +void uart_enable(NS16550_t regs); + +/* + * Signal that we are about the use the SPI bus. + */ +void spi_enable(void); +#endif + +#else /* not CONFIG_SPI_UART_SWITCH */ + +static inline void uart_enable(NS16550_t regs) {} +static inline void spi_enable(void) {} + +#endif