From patchwork Fri May 3 05:12:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Bendebury X-Patchwork-Id: 241147 X-Patchwork-Delegate: jagannadh.teki@gmail.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 3E33C2C00AD for ; Fri, 3 May 2013 15:13:12 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 92C224A343; Fri, 3 May 2013 07:13:09 +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 x22w5vGDQZ6h; Fri, 3 May 2013 07:13:07 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A23624A332; Fri, 3 May 2013 07:13:07 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 31F2F4A332 for ; Fri, 3 May 2013 07:13:05 +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 61gwDUvcjSVP for ; Fri, 3 May 2013 07:13:00 +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-la0-f50.google.com (mail-la0-f50.google.com [209.85.215.50]) by theia.denx.de (Postfix) with ESMTPS id ACC7D4A32C for ; Fri, 3 May 2013 07:12:54 +0200 (CEST) Received: by mail-la0-f50.google.com with SMTP id fl20so1211911lab.9 for ; Thu, 02 May 2013 22:12:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type; bh=aD/E3yzGrHL01oCmkSwPu6cPBbeIx1jg3j89uOpYXwQ=; b=tYePJZjdJtCe6H8ujkokGbGtluJQQQ3yoss26uG0/TpmbKwu4rz04F7G82Ro0TBU0Q JyLG3t3p3V9GAnG+iOJ7Sei03p6W2hfc/X7DUjHAKFB4by5fM/1dIQTe2J/4T90Axv/b dOeUHj44sDmLsIdFDHjwT9RX11pJ3EO1VPRzA2wMcHSz7abamIVikQdaNJEvfVtX7JYV HVtbsyIQymkojEF5ZVs3K5hcdOBEErJQ5HoslRiRZYxUBIh9ofLhT0K8PIUWgy4NG+R9 SeAwg7DKIvp4QYK9wA2LnZlU/ywB9syJdOCgnrWcRWn1TmQ4ga88+BdIZCBYv0+FQFil dfUQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=x-received:mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type; bh=aD/E3yzGrHL01oCmkSwPu6cPBbeIx1jg3j89uOpYXwQ=; b=gQMYJ41EpCHLEkTdmpQSjE6uM6jTne4pgFeDQdVHD+35RabOhCpPn3Hornw8BSZNU2 LxSr/ykX8Sjd1UVDjRWCTi0u1F67emyW0KxACEFxHcmisvw82rMQoGIObG6WgkrP5jLs it0Pf/y5KQCjovKs7SC+5oo/8p6Ozh59Y+In4= X-Received: by 10.112.128.135 with SMTP id no7mr3743853lbb.79.1367557973237; Thu, 02 May 2013 22:12:53 -0700 (PDT) MIME-Version: 1.0 Received: by 10.114.71.138 with HTTP; Thu, 2 May 2013 22:12:33 -0700 (PDT) In-Reply-To: References: From: Vadim Bendebury Date: Thu, 2 May 2013 22:12:33 -0700 X-Google-Sender-Auth: J-Dr1sUn3_t4WZ9PJ7Ujz-JMs84 Message-ID: To: Rajeshwari Shinde , Simon Glass Cc: uboot , patches@linaro.org Subject: Re: [U-Boot] [PATCH 2/2] EXYNOS: SPI: Support SPI_PREAMBLE mode 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: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de [the original patch removed, re-sending from a registered address] So, I spent some more time debugging a system which requires this patch: a system, where on a SPI interface a response to a command could come way later then the command data transmission completes. The original patch was trying to address many corner cases, but come to think of it, in this situation the slave does not care about extra data sent on the transmit interface, as otherwise there is no clock and no data could be transferred from the slave. Then, for this SPI interface we do not need to set the counter of clocks, and do not need to keep adding more clocks if the data has not been received yet, the clocks could be just free running. And then the patch becomes much simpler, what do you think: * Bytes are transmitted/received in pairs. Wait to receive all the @@ -243,13 +249,23 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, /* Keep the fifos full/empty. */ spi_get_fifo_levels(regs, &rx_lvl, &tx_lvl); - if (tx_lvl < spi_slave->fifo_size && out_bytes) { - temp = txp ? *txp++ : 0xff; + if (tx_lvl < spi_slave->fifo_size) { + if (txp && out_bytes) { + temp = *txp++; + out_bytes--; + } else { + temp = 0xff; + } writel(temp, ®s->tx_data); - out_bytes--; } if (rx_lvl > 0 && in_bytes) { temp = readl(®s->rx_data); + if (hunting) { + if ((temp & 0xff) != PREAMBLE_VALUE) + continue; + else + hunting = 0; + } if (rxp) *rxp++ = temp; in_bytes--; diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c index c697db8..fff8310 100644 --- a/drivers/spi/exynos_spi.c +++ b/drivers/spi/exynos_spi.c @@ -211,10 +211,10 @@ static void spi_get_fifo_levels(struct exynos_spi *regs, */ static void spi_request_bytes(struct exynos_spi *regs, int count) { - assert(count && count < (1 << 16)); setbits_le32(®s->ch_cfg, SPI_CH_RST); clrbits_le32(®s->ch_cfg, SPI_CH_RST); - writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); + if (count) + writel(count | SPI_PACKET_CNT_EN, ®s->pkt_cnt); } static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, @@ -225,14 +225,20 @@ static void spi_rx_tx(struct exynos_spi_slave *spi_slave, int todo, const uchar *txp = *doutp; int rx_lvl, tx_lvl; uint out_bytes, in_bytes; - + int hunting; + + if (spi_slave->free_running_mode) { + spi_request_bytes(regs, 0); + hunting = 1; + } else { + hunting = 0; + spi_request_bytes(regs, todo); + } out_bytes = in_bytes = todo; - /* - * If there's something to send, do a software reset and set a - * transaction size. - */ - spi_request_bytes(regs, todo); + /* Software reset the channel. */ + setbits_le32(®s->ch_cfg, SPI_CH_RST); + clrbits_le32(®s->ch_cfg, SPI_CH_RST); /*