From patchwork Tue Dec 8 06:43:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Bondarenko X-Patchwork-Id: 7794731 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BEF95BEEE1 for ; Tue, 8 Dec 2015 06:44:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BB8E4202E9 for ; Tue, 8 Dec 2015 06:44:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A37D820462 for ; Tue, 8 Dec 2015 06:44:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933194AbbLHGoE (ORCPT ); Tue, 8 Dec 2015 01:44:04 -0500 Received: from mail-lf0-f48.google.com ([209.85.215.48]:34689 "EHLO mail-lf0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933136AbbLHGoB (ORCPT ); Tue, 8 Dec 2015 01:44:01 -0500 Received: by lffu14 with SMTP id u14so6381236lff.1; Mon, 07 Dec 2015 22:43:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CJx4wPJD4jrD5h5jjEvepqSZFPt2SzAo1QX8ztAatnY=; b=YVfpWV5HdMh1SiyGK6QK4UvTFkiDHMIKN4F7Wf26lPNiYIZWPcKL+WCkA5Hk6DAzJ7 Od+9p8fEAGTWcdNi+XM8ib0PDPoliCc2H3HXKITX9XDMyJ/t4Hmj7OqxIaZvf8bJ6EPk I8fVk2qReZXzGBz43ayeGidPFHzibZdobCY0TmQYLpp9mUqWhJ8qCFn2jdJ9+rWLQ7PP 3JlrBgfTJ7R9M6A6+ujv0lfxL31Q8msvMyEqe+iGi+G+M4rJ8iVF1ZiOvLXUlaFt15tC rwTdm5aL8A0v85+fJSZ6OrRrUwPgyNezL63xA9T3ksqSy3oylwqfoD9XxBE1R3mI8TwQ nTRQ== X-Received: by 10.25.145.81 with SMTP id t78mr786564lfd.86.1449557039606; Mon, 07 Dec 2015 22:43:59 -0800 (PST) Received: from localhost.localdomain (c-89-233-200-205.cust.bredband2.com. [89.233.200.205]) by smtp.gmail.com with ESMTPSA id d2sm286875lbc.11.2015.12.07.22.43.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 07 Dec 2015 22:43:59 -0800 (PST) From: Anton Bondarenko To: broonie@kernel.org, b38343@freescale.com, s.hauer@pengutronix.de Cc: linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, vladimir_zapolskiy@mentor.com, jiada_wang@mentor.com Subject: [PATCH v6 7/8] spi: imx: replace fixed timeout with calculated Date: Tue, 8 Dec 2015 07:43:49 +0100 Message-Id: <1449557030-27525-8-git-send-email-anton.bondarenko.sama@gmail.com> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1449557030-27525-1-git-send-email-anton.bondarenko.sama@gmail.com> References: <1449557030-27525-1-git-send-email-anton.bondarenko.sama@gmail.com> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Fixed timeout value can fire while transaction is ongoing. This may happen because there are no strict requirements on SPI transaction duration. Dynamic timeout value is generated based on SCLK and transaction size. There is also 4 * SCLK delay between TX bursts related to HW internal CS change. Signed-off-by: Anton Bondarenko --- drivers/spi/spi-imx.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 08492d6..d74d809 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -56,7 +56,6 @@ /* The maximum bytes that a sdma BD can transfer.*/ #define MAX_SDMA_BD_BYTES (1 << 15) -#define IMX_DMA_TIMEOUT (msecs_to_jiffies(3000)) struct spi_imx_config { unsigned int speed_hz; unsigned int bpw; @@ -92,6 +91,7 @@ struct spi_imx_data { struct clk *clk_per; struct clk *clk_ipg; unsigned long spi_clk; + unsigned int spi_bus_clk; unsigned int count; void (*tx)(struct spi_imx_data *); @@ -331,6 +331,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, /* set clock speed */ ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz, &clk); + spi_imx->spi_bus_clk = clk; /* set chip select to use */ ctrl |= MX51_ECSPI_CTRL_CS(config->cs); @@ -913,11 +914,26 @@ static void spi_imx_dma_tx_callback(void *cookie) complete(&spi_imx->dma_tx_completion); } +static int spi_imx_calculate_timeout(struct spi_imx_data *spi_imx, int size) +{ + unsigned long timeout = 0; + + /* Time with actual data transfer and CS change delay related to HW */ + timeout = (8 + 4) * size / spi_imx->spi_bus_clk; + + /* Add extra second for scheduler related activities */ + timeout += 1; + + /* Double calculated timeout */ + return msecs_to_jiffies(2 * timeout * MSEC_PER_SEC); +} + static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, struct spi_transfer *transfer) { struct dma_async_tx_descriptor *desc_tx = NULL, *desc_rx = NULL; int ret; + unsigned long transfer_timeout; unsigned long timeout; struct spi_master *master = spi_imx->bitbang.master; struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg; @@ -964,9 +980,11 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, dma_async_issue_pending(master->dma_tx); spi_imx->devtype_data->trigger(spi_imx); + transfer_timeout = spi_imx_calculate_timeout(spi_imx, transfer->len); + /* Wait SDMA to finish the data transfer.*/ timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion, - IMX_DMA_TIMEOUT); + transfer_timeout); if (!timeout) { pr_warn("%s %s: I/O Error in DMA TX\n", dev_driver_string(&master->dev), @@ -974,8 +992,10 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, dmaengine_terminate_all(master->dma_tx); dmaengine_terminate_all(master->dma_rx); } else { + transfer_timeout = spi_imx_calculate_timeout(spi_imx, + spi_imx->wml); timeout = wait_for_completion_timeout( - &spi_imx->dma_rx_completion, IMX_DMA_TIMEOUT); + &spi_imx->dma_rx_completion, transfer_timeout); if (!timeout) { pr_warn("%s %s: I/O Error in DMA RX\n", dev_driver_string(&master->dev),