From patchwork Wed May 9 17:34:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Warren X-Patchwork-Id: 158017 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 73CD6B6F6E for ; Thu, 10 May 2012 03:39:58 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AB65B28088; Wed, 9 May 2012 19:39:56 +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 75x-y4FcZUIk; Wed, 9 May 2012 19:39:56 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2F41728083; Wed, 9 May 2012 19:39:55 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F2DD828083 for ; Wed, 9 May 2012 19:39:52 +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 G2zMyQ5esRWn for ; Wed, 9 May 2012 19:39:52 +0200 (CEST) X-Greylist: delayed 325 seconds by postgrey-1.27 at theia; Wed, 09 May 2012 19:39:50 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-pz0-f44.google.com (mail-pz0-f44.google.com [209.85.210.44]) by theia.denx.de (Postfix) with ESMTPS id EB1D228082 for ; Wed, 9 May 2012 19:39:50 +0200 (CEST) Received: by dacx6 with SMTP id x6so542119dac.3 for ; Wed, 09 May 2012 10:39:48 -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=B+fRohsUtRpHCwUqM5NT7NvqKH2PHfsNg8UgzrtssQs=; b=BMoX4SDS5ST4qFLnLShpe8m0IyZBp54TEo7OdaL1bKOz56MBlKNCuKxa/atdobdu8q nSm8G3u+U7ZyCzBdWL2mCuL3cA1E048LbQapV+49kqnDoTz3mEK6gl0f9DkWWz3x1tGs YuifdWJZAnTOTJGUzvtDuzpancsJUXLIAyGMCO0FNixA4winQhTMzqmy20AJcNQi5lDn j2ttyZc7wVJPaT2VQYMOc792/0Ot1rGCQU5dJWzAn4B30L6o2GDcVrB4W7/1qptERC5A nJ+FDM9FpPg8F40eP16+P4RWvsefQOBtHgeq0F8o3Llm6E1j7xtCFjO9/nseDqmEZqMK UmyQ== Received: by 10.68.236.165 with SMTP id uv5mr11421439pbc.37.1336584863582; Wed, 09 May 2012 10:34:23 -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 qa9sm6737204pbb.26.2012.05.09.10.34.21 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 09 May 2012 10:34:22 -0700 (PDT) From: Tom Warren To: u-boot@lists.denx.de Date: Wed, 9 May 2012 10:34:16 -0700 Message-Id: <1336584856-30882-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] 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 Tested-by: Jimmy Zhang Acked-by: Simon Glass --- 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 +++++++++- include/configs/seaboard.h | 4 +++ 4 files changed, 25 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, diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index 46d4228..a9fd15e 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -52,6 +52,10 @@ /* On Seaboard: GPIO_PI3 = Port I = 8, bit = 3 */ #define CONFIG_UART_DISABLE_GPIO GPIO_PI3 +#define CONFIG_SPI_UART_SWITCH +#define CONFIG_SPI_CORRUPTS_UART NV_PA_APB_UARTD_BASE +#define CONFIG_SPI_CORRUPTS_UART_NR 3 +#define CONFIG_SPI_CORRUPTS_UART_DLY 2500 #define CONFIG_MACH_TYPE MACH_TYPE_SEABOARD #define CONFIG_SYS_BOARD_ODMDATA 0x300d8011 /* lp1, 1GB */