From patchwork Tue Nov 22 07:01:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sanchayan X-Patchwork-Id: 9440563 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8853B600BA for ; Tue, 22 Nov 2016 07:11:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BCD428462 for ; Tue, 22 Nov 2016 07:11:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 704422844B; Tue, 22 Nov 2016 07:11:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 301452844B for ; Tue, 22 Nov 2016 07:11:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754480AbcKVHKj (ORCPT ); Tue, 22 Nov 2016 02:10:39 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:35603 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754413AbcKVHKh (ORCPT ); Tue, 22 Nov 2016 02:10:37 -0500 Received: by mail-pg0-f65.google.com with SMTP id p66so1245795pga.2; Mon, 21 Nov 2016 23:10:36 -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 :in-reply-to:references; bh=lx9GB7I+hWLoqut5+VNIv7qwE5boYzEY6FNrxcZqfGc=; b=0CuUdlntv6yFJ2NHqo30+ZmJMZATB138N1IcHid2G9o3QdoT+rtSyBpAM3FC2k+qTV xX1S/DumAh0fbqkAWwG2s8vwkib4KsJiYes5S1mcBFE0qwJsqOGf4sCYLMtCTH0JNCsd I4qkRyQ5Y8QmGhUc2r4gv7YZmVCCvxxfoeJYlVBsdhVw7XbUmEocQ2DEgePwTZBziN8J TQHPMaqu/jCQBhSMuGmtPwvI3o1eSEuKO2VjtLs0yBQxfSTc05n19eH2AvWrVbObZ1jK s0qL8iHLvggPjoXICKbtgo/q2+b7ymEmrCxeseDvf3GYmVsb98pmWz9DWOz9ei0qft5v W+OA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=lx9GB7I+hWLoqut5+VNIv7qwE5boYzEY6FNrxcZqfGc=; b=cqDszlUhfduqeDv9RupVF+aNjO2P1ISyNrKr+KOKBoPw40biOjaFqTZQoi+B9ogo0/ cEluU8xXwFRrcg8ZvZ9D/FNmaDOpX9lrbcf5oWIO5i9/0YmqQaSFEpUCoeQywfi6l505 rUvR7g4AZjZZXpHayh5mdROqaKj9a/7SJX7N5z8pG6aAHG49PbvJHtj4ig2o8fiWb0ga brny0sVk9gT2/hg91lcNEr1SZdlF1j22575l1F5PXRnUwTEcJKr0vUq1Qg9RXX/8kHcK 8KhpRrXFxuHqD0R6DiD/rZzfRJb/96tVubLAzaSfII1fFw5CCjY4QOCltX0cndh05A+R 31Lg== X-Gm-Message-State: AKaTC034oytz2u44U0RDTMPu4oJLpMelI+fCPIaObV1Jbwf+yf4F9tSdnxZpwm4cBmURjg== X-Received: by 10.99.109.6 with SMTP id i6mr40625813pgc.139.1479798636450; Mon, 21 Nov 2016 23:10:36 -0800 (PST) Received: from localhost ([115.115.243.34]) by smtp.gmail.com with ESMTPSA id 1sm14661766pgp.1.2016.11.21.23.10.35 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Nov 2016 23:10:35 -0800 (PST) From: Sanchayan Maity To: broonie@kernel.org Cc: stefan@agner.ch, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, Sanchayan Maity Subject: [PATCH v3 1/3] spi: spi-fsl-dspi: Fix incorrect DMA setup Date: Tue, 22 Nov 2016 12:31:30 +0530 Message-Id: X-Mailer: git-send-email 2.10.2 In-Reply-To: References: In-Reply-To: References: Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently dmaengine_prep_slave_single was being called with length set to the complete DMA buffer size. This resulted in unwanted bytes being transferred to the SPI register leading to clock and MOSI lines having unwanted data even after chip select got deasserted and the required bytes having been transferred. While at it also clean up the use of curr_xfer_len which is central to the DMA setup, from bytes to DMA transfers for every use. Signed-off-by: Sanchayan Maity Reviewed-by: Stefan Agner --- drivers/spi/spi-fsl-dspi.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index b1ee1f5..911aadb 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -151,6 +151,7 @@ static const struct fsl_dspi_devtype_data ls2085a_data = { }; struct fsl_dspi_dma { + /* Length of transfer in words of DSPI_FIFO_SIZE */ u32 curr_xfer_len; u32 *tx_dma_buf; @@ -217,15 +218,13 @@ static void dspi_rx_dma_callback(void *arg) struct fsl_dspi *dspi = arg; struct fsl_dspi_dma *dma = dspi->dma; int rx_word; - int i, len; + int i; u16 d; rx_word = is_double_byte_mode(dspi); - len = rx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len; - if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) { - for (i = 0; i < len; i++) { + for (i = 0; i < dma->curr_xfer_len; i++) { d = dspi->dma->rx_dma_buf[i]; rx_word ? (*(u16 *)dspi->rx = d) : (*(u8 *)dspi->rx = d); @@ -242,14 +241,12 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) struct device *dev = &dspi->pdev->dev; int time_left; int tx_word; - int i, len; + int i; u16 val; tx_word = is_double_byte_mode(dspi); - len = tx_word ? (dma->curr_xfer_len / 2) : dma->curr_xfer_len; - - for (i = 0; i < len - 1; i++) { + for (i = 0; i < dma->curr_xfer_len - 1; i++) { val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx; dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) | @@ -265,7 +262,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, dma->tx_dma_phys, - DSPI_DMA_BUFSIZE, DMA_MEM_TO_DEV, + dma->curr_xfer_len * + DMA_SLAVE_BUSWIDTH_4_BYTES, + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!dma->tx_desc) { dev_err(dev, "Not able to get desc for DMA xfer\n"); @@ -281,7 +280,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi) dma->rx_desc = dmaengine_prep_slave_single(dma->chan_rx, dma->rx_dma_phys, - DSPI_DMA_BUFSIZE, DMA_DEV_TO_MEM, + dma->curr_xfer_len * + DMA_SLAVE_BUSWIDTH_4_BYTES, + DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!dma->rx_desc) { dev_err(dev, "Not able to get desc for DMA xfer\n"); @@ -328,17 +329,17 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi) struct device *dev = &dspi->pdev->dev; int curr_remaining_bytes; int bytes_per_buffer; - int tx_word; + int word = 1; int ret = 0; - tx_word = is_double_byte_mode(dspi); + if (is_double_byte_mode(dspi)) + word = 2; curr_remaining_bytes = dspi->len; + bytes_per_buffer = DSPI_DMA_BUFSIZE / DSPI_FIFO_SIZE; while (curr_remaining_bytes) { /* Check if current transfer fits the DMA buffer */ - dma->curr_xfer_len = curr_remaining_bytes; - bytes_per_buffer = DSPI_DMA_BUFSIZE / - (DSPI_FIFO_SIZE / (tx_word ? 2 : 1)); - if (curr_remaining_bytes > bytes_per_buffer) + dma->curr_xfer_len = curr_remaining_bytes / word; + if (dma->curr_xfer_len > bytes_per_buffer) dma->curr_xfer_len = bytes_per_buffer; ret = dspi_next_xfer_dma_submit(dspi); @@ -347,7 +348,7 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi) goto exit; } else { - curr_remaining_bytes -= dma->curr_xfer_len; + curr_remaining_bytes -= dma->curr_xfer_len * word; if (curr_remaining_bytes < 0) curr_remaining_bytes = 0; dspi->len = curr_remaining_bytes;