From patchwork Sun Nov 18 07:10:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajoy Kumar Das X-Patchwork-Id: 199895 X-Patchwork-Delegate: trini@ti.com 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 E8E6A2C0086 for ; Sun, 18 Nov 2012 18:16:43 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4CCC14A041; Sun, 18 Nov 2012 08:16:39 +0100 (CET) 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 yRh8QAr96A0K; Sun, 18 Nov 2012 08:16:39 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E24DA4A03A; Sun, 18 Nov 2012 08:16:36 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 940744A03A for ; Sun, 18 Nov 2012 08:16:34 +0100 (CET) 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 4aAh015p1vXl for ; Sun, 18 Nov 2012 08:16:33 +0100 (CET) X-Greylist: delayed 335 seconds by postgrey-1.27 at theia; Sun, 18 Nov 2012 08:16:30 CET 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 nm21-vm3.bullet.mail.sg3.yahoo.com (nm21-vm3.bullet.mail.sg3.yahoo.com [106.10.151.34]) by theia.denx.de (Postfix) with ESMTPS id 7965D4A039 for ; Sun, 18 Nov 2012 08:16:30 +0100 (CET) Received: from [106.10.166.117] by nm21.bullet.mail.sg3.yahoo.com with NNFMP; 18 Nov 2012 07:10:50 -0000 Received: from [106.10.167.233] by tm6.bullet.mail.sg3.yahoo.com with NNFMP; 18 Nov 2012 07:10:50 -0000 Received: from [127.0.0.1] by smtp206.mail.sg3.yahoo.com with NNFMP; 18 Nov 2012 07:10:50 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.in; s=s1024; t=1353222650; bh=QTZqgm41bSHxpPjRRo1E8VHTjt5jJJ5HzDbtQEfNf9g=; h=X-Yahoo-Newman-Id:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:Received:From:To:Cc:Subject:Date:Message-Id:X-Mailer; b=ehAwxJq7wDRYO5BBwfF9v9Erp3gKgGrRuAD+3dwVhGJ/fO/HVFPZjzisDKxloP3De66n58pJii3fFceEfP4lXlmSMZ668YK5718FoCN+Cd9Oll6cXSYf/PCYPGnFua+htdvoyRvI93v30sz32FLW6n0azD3UARGVzOni06MrrGA= X-Yahoo-Newman-Id: 500470.23079.bm@smtp206.mail.sg3.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: 9Ki.MwQVM1k8D.NSgxIqp7OgvgARU9dn21pHq4uGJZj42Kt h05tdwrbgpUF1Bm1N.SwnKAEN1fPDmT_mfhaNEIXHw0wLpyUj9099I2lTaNB KoLMO3usy1xNjSdjXMiqugOCMZwqBG2NRBdrt4mmp24YNg8zS9gqFEwYxl_r _4A4XA9VUIz0NM80qft1377qzTkq.2WxSywxfoGxfmPCkaCWh6WNNo.NgAgX QBi3ssHJmA9MzcUz48a1hK3xpxm5S2Uq5Mc5wdYx4oSX45m3UdRNJoDrup2S EWOi0Ue4bmPZPSOCBOqzXcgNWFtQJ02zGNJFe2mJy7kJptfgqBZOorGN8P98 OIjKAgfbFqBO1JgZ25ZaQhoInlOzfZp2fce4IplkBlfGw1fdb6UyO9xxFmiI AEvwU1yHR_ksJ0rmxKgYJYIMTdFf.YS2Lg4zFjQSOSbF6X.X_ATmwnIurFll 80yLPN1guhfrzyFVSN7RjXr3qF6qG6fwpBeQbeFI- X-Yahoo-SMTP: eccvvfqswBD3l85NhBqqO0HW7lU- Received: from localhost.localdomain (akdas75@122.167.100.98 with login) by smtp206.mail.sg3.yahoo.com with SMTP; 17 Nov 2012 23:10:50 -0800 PST From: Ajoy Kumar Das To: u-boot@lists.denx.de Date: Sat, 17 Nov 2012 23:10:15 -0800 Message-Id: <1353222615-11255-1-git-send-email-akdas75@yahoo.in> X-Mailer: git-send-email 1.7.0.4 Cc: Tom Rini , jacopo mondi Subject: [U-Boot] [PATCH] OMAP3 SPI : Fixed bugs related to SPI transfer 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 From: ajoy Added posted writes (read after writes) to effect the change immediately for channel confiuration and channel enable register Disable the channel to purge receieve data in TX_ONLY mode transfer otherwise rx data will get affected by the next immediate RX_ONLY mode transfer Wait for the EOT bit to be set after last byte has been loaded to TX shift register in the the TX_ONLY mode.This ensures TX data has been completely shifted out Disable the channel in RX_ONLY mode before reading the last data from RXX register to prevent the SPI slave to transmit next word Signed-off-by: Ajoy Kumar Das Cc: Tom Rini Cc: jacopo mondi --- drivers/spi/omap3_spi.c | 84 +++++++++++++++++++++++++++-------------------- drivers/spi/omap3_spi.h | 1 + 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 6791a7e..dd4ae7c 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -57,6 +57,20 @@ static void spi_reset(struct omap3_spi_slave *ds) writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable); } +static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val) +{ + writel(val, &ds->regs->channel[ds->slave.cs].chconf); + /* Flash post writes to make immediate effect */ + readl(&ds->regs->channel[ds->slave.cs].chconf); +} + +static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable) +{ + writel(enable, &ds->regs->channel[ds->slave.cs].chctrl); + /* Flash post writes to make immediate effect */ + readl(&ds->regs->channel[ds->slave.cs].chctrl); +} + void spi_init() { /* do nothing */ @@ -211,8 +225,8 @@ int spi_claim_bus(struct spi_slave *slave) /* Transmit & receive mode */ conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; - - writel(conf, &ds->regs->channel[ds->slave.cs].chconf); + + omap3_spi_write_chconf(ds,conf); return 0; } @@ -233,14 +247,13 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp, int timeout = SPI_WAIT_TIMEOUT; int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); - if (flags & SPI_XFER_BEGIN) - writel(OMAP3_MCSPI_CHCTRL_EN, - &ds->regs->channel[ds->slave.cs].chctrl); + /* Enable the channel */ + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; chconf |= OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); + omap3_spi_write_chconf(ds,chconf); for (i = 0; i < len; i++) { /* wait till TX register is empty (TXS == 1) */ @@ -256,15 +269,17 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp, writel(txp[i], &ds->regs->channel[ds->slave.cs].tx); } + /* wait to finish of transfer */ + while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & + OMAP3_MCSPI_CHSTAT_EOT)); + + /* Disable the channel otherwise the next immediate RX will get affected */ + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); + if (flags & SPI_XFER_END) { - /* wait to finish of transfer */ - while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & - OMAP3_MCSPI_CHSTAT_EOT)); chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); - - writel(0, &ds->regs->channel[ds->slave.cs].chctrl); + omap3_spi_write_chconf(ds,chconf); } return 0; } @@ -277,15 +292,14 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp, int timeout = SPI_WAIT_TIMEOUT; int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); - if (flags & SPI_XFER_BEGIN) - writel(OMAP3_MCSPI_CHCTRL_EN, - &ds->regs->channel[ds->slave.cs].chctrl); + /* Enable the channel */ + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; chconf |= OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); - + omap3_spi_write_chconf(ds,chconf); + writel(0, &ds->regs->channel[ds->slave.cs].tx); for (i = 0; i < len; i++) { @@ -298,15 +312,18 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp, return -1; } } + + /* Disable the channel to prevent furher receiving */ + if(i == (len - 1)) + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); + /* Read the data */ rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx); } if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); - - writel(0, &ds->regs->channel[ds->slave.cs].chctrl); + omap3_spi_write_chconf(ds,chconf); } return 0; @@ -323,15 +340,13 @@ int omap3_spi_txrx(struct spi_slave *slave, int i=0; /*Enable SPI channel*/ - if (flags & SPI_XFER_BEGIN) - writel(OMAP3_MCSPI_CHCTRL_EN, - &ds->regs->channel[ds->slave.cs].chctrl); - + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); + /*set TRANSMIT-RECEIVE Mode*/ chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; chconf |= OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); - + omap3_spi_write_chconf(ds,chconf); + /*Shift in and out 1 byte at time*/ for (i=0; i < len; i++){ /* Write: wait for TX empty (TXS == 1)*/ @@ -359,13 +374,13 @@ int omap3_spi_txrx(struct spi_slave *slave, /* Read the data */ rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx); } + /* Disable the channel */ + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); /*if transfer must be terminated disable the channel*/ if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, &ds->regs->channel[ds->slave.cs].chconf); - - writel(0, &ds->regs->channel[ds->slave.cs].chctrl); + omap3_spi_write_chconf(ds,chconf); } return 0; @@ -389,17 +404,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); if (flags & SPI_XFER_BEGIN) { - writel(OMAP3_MCSPI_CHCTRL_EN, - &ds->regs->channel[ds->slave.cs].chctrl); + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN); chconf |= OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, - &ds->regs->channel[ds->slave.cs].chconf); + omap3_spi_write_chconf(ds,chconf); } if (flags & SPI_XFER_END) { chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; - writel(chconf, - &ds->regs->channel[ds->slave.cs].chconf); - writel(0, &ds->regs->channel[ds->slave.cs].chctrl); + omap3_spi_write_chconf(ds,chconf); + omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS); } ret = 0; } else { diff --git a/drivers/spi/omap3_spi.h b/drivers/spi/omap3_spi.h index bffa43c..5e00208 100644 --- a/drivers/spi/omap3_spi.h +++ b/drivers/spi/omap3_spi.h @@ -99,6 +99,7 @@ struct mcspi { #define OMAP3_MCSPI_CHSTAT_EOT (1 << 2) #define OMAP3_MCSPI_CHCTRL_EN (1 << 0) +#define OMAP3_MCSPI_CHCTRL_DIS (0 << 0) #define OMAP3_MCSPI_WAKEUPENABLE_WKEN (1 << 0)