From patchwork Tue May 15 22:32:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Warren X-Patchwork-Id: 159466 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 B1688B6FAF for ; Wed, 16 May 2012 08:33:02 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E941D280B3; Wed, 16 May 2012 00:32:55 +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 70B53cATOy9u; Wed, 16 May 2012 00:32:55 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 00F40280CB; Wed, 16 May 2012 00:32:51 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9452D280BC for ; Wed, 16 May 2012 00:32:47 +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 bekrJnXPXUzl for ; Wed, 16 May 2012 00:32:44 +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 mail-pb0-f44.google.com (mail-pb0-f44.google.com [209.85.160.44]) by theia.denx.de (Postfix) with ESMTPS id 5308228090 for ; Wed, 16 May 2012 00:32:42 +0200 (CEST) Received: by pbcwy7 with SMTP id wy7so212405pbc.3 for ; Tue, 15 May 2012 15:32:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-nvconfidentiality; bh=WH7TeX9HLW0M7OM2ZMGzONGJRQUq/omfiPjuqFL868M=; b=0aRk0TgCD4We+gc96l1j24P9IOzfQzXJBF8yHX4zcxL89WyWE0cVrLmzedthwLsfNE fCQ58RjgOUrOLZ9x3D0Mw0TVJqaybxadYckYwqvH6bTPWqcGYE1GMLIZUdAje5r1F2vQ asYDIwBqbfvHR8kviBOAUYDoXizHy6WHXZc4KEVVByPfDskBibyKL9u0GNOj40qTCUhB RxWquukA6GAW2JxFwJ9XsZza4FgqGO5v1qdLl4DxQ8NGOkQI2ElTWMcq9+UHTt8l8mlK c5cXnHfUJmjojEUXuuFCoiYOdNjvmCesvLCQWXQqG7DaWsGfNt1/vNSfBi7kn56RiUfV LbIg== Received: by 10.68.211.234 with SMTP id nf10mr9796495pbc.121.1337121160170; Tue, 15 May 2012 15:32:40 -0700 (PDT) Received: from localhost.localdomain (ip68-106-253-43.ph.ph.cox.net. [68.106.253.43]) by mx.google.com with ESMTPS id rv5sm3147330pbc.56.2012.05.15.15.32.37 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 15 May 2012 15:32:39 -0700 (PDT) From: Tom Warren To: u-boot@lists.denx.de Date: Tue, 15 May 2012 15:32:36 -0700 Message-Id: <1337121157-15284-1-git-send-email-twarren@nvidia.com> X-Mailer: git-send-email 1.7.0.4 X-NVConfidentiality: public Cc: twarren.nvidia@gmail.com, Tom Warren , jimmzhang@nvidia.com Subject: [U-Boot] [PATCH V2 1/2] spi: Tegra2: Seaboard: fix UART corruption during SPI transactions X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 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 Simon Glass's proposal to fix this on Seaboard was NAK'd, so I removed his NS16550 references and added a small delay before SPI/UART muxing. Tested on my Seaboard with large SPI reads/writes and saw no corruption (crc's matched) and no spurious comm chars. Signed-off-by: Tom Warren Acked-by: Simon Glass Tested-by: Jimmy Zhang --- v2: Split config file changes into separate commit arch/arm/include/asm/arch-tegra2/uart-spi-switch.h | 4 +- board/nvidia/common/uart-spi-switch.c | 27 +++++-------------- drivers/spi/tegra2_spi.c | 13 +++++++++- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h b/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h index e4503b1..82ac180 100644 --- a/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h +++ b/arch/arm/include/asm/arch-tegra2/uart-spi-switch.h @@ -29,7 +29,7 @@ * time! If the board file provides this, the board config will declare it. * Let this be a lesson for others. */ -void pinmux_select_uart(NS16550_t regs); +void pinmux_select_uart(void); /* * Signal that we are about the use the SPI bus. @@ -38,7 +38,7 @@ void pinmux_select_spi(void); #else /* not CONFIG_SPI_UART_SWITCH */ -static inline void pinmux_select_uart(NS16550_t regs) {} +static inline void pinmux_select_uart(void) {} static inline void pinmux_select_spi(void) {} #endif diff --git a/board/nvidia/common/uart-spi-switch.c b/board/nvidia/common/uart-spi-switch.c index 23aa0b9..1ba1afd 100644 --- a/board/nvidia/common/uart-spi-switch.c +++ b/board/nvidia/common/uart-spi-switch.c @@ -21,7 +21,6 @@ */ #include -#include #include #include #include @@ -40,7 +39,6 @@ enum spi_uart_switch { /* 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 */ }; @@ -52,7 +50,6 @@ static void get_config(struct spi_uart *config) { #if defined CONFIG_SPI_CORRUPTS_UART config->gpio = CONFIG_UART_DISABLE_GPIO; - config->regs = (NS16550_t)CONFIG_SPI_CORRUPTS_UART; config->port = CONFIG_SPI_CORRUPTS_UART_NR; #else config->gpio = -1; @@ -101,34 +98,24 @@ static void spi_uart_switch(struct spi_uart *config, 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); + /* pre-delay, allow SPI/UART to settle, FIFO to empty, etc. */ + udelay(CONFIG_SPI_CORRUPTS_UART_DLY); /* 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. - */ + * 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 pinmux_select_uart(NS16550_t regs) +void pinmux_select_uart(void) { - /* Also prevents calling spi_uart_switch() before relocation */ - if (regs == local.regs) spi_uart_switch(&local, SWITCH_UART); } diff --git a/drivers/spi/tegra2_spi.c b/drivers/spi/tegra2_spi.c index 56cb229..fe7b405 100644 --- a/drivers/spi/tegra2_spi.c +++ b/drivers/spi/tegra2_spi.c @@ -28,13 +28,18 @@ #include #include #include -#include #include #include #include #include #include +#if defined(CONFIG_SPI_CORRUPTS_UART) + #define corrupt_delay() udelay(CONFIG_SPI_CORRUPTS_UART_DLY); +#else + #define corrupt_delay() +#endif + struct tegra_spi_slave { struct spi_slave slave; struct spi_tegra *regs; @@ -161,14 +166,20 @@ void spi_cs_activate(struct spi_slave *slave) /* CS is negated on Tegra, so drive a 1 to get a 0 */ setbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); + + corrupt_delay(); /* Let UART settle */ } void spi_cs_deactivate(struct spi_slave *slave) { struct tegra_spi_slave *spi = to_tegra_spi(slave); + pinmux_select_uart(); + /* CS is negated on Tegra, so drive a 0 to get a 1 */ clrbits_le32(&spi->regs->command, SPI_CMD_CS_VAL); + + corrupt_delay(); /* Let SPI settle */ } int spi_xfer(struct spi_slave *slave, unsigned int bitlen,