From patchwork Thu May 3 12:20:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhishek Sahu X-Patchwork-Id: 908007 X-Patchwork-Delegate: miquel.raynal@bootlin.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Zrl2D8Pp"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=codeaurora.org header.i=@codeaurora.org header.b="TJ8PQcbf"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="lmwZz6cg"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40cDr45tycz9s35 for ; Thu, 3 May 2018 22:25:24 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=yKLoISSl7wH2KwxgdUgQ15ss5QIj7361fAoP8ld5/wc=; b=Zrl2D8PpQ+AwttgqspZ01YKVxJ AZ+6xMHeycmRb9Ol10fbhWPUTpEBTP4qNnbwp8hhtzdzWvpI28DesV+YwndeY6vbeStVvgJqUyOzR SNVaGvnYe1DmAeU67iBr9ZdxPMTh6btF3sOqjRouXi168U17NISdkehB3Ca9eJkiCLjl+Fo12bKfA 4tseZQ8Chsyw4W2Eu4ZPmKkTfafjfeWOcjdhesvvwgpY3DgowQjzIxxCHgObug8HFtvYBo+3RZ8lk ntKOvIzx4qH3S8J+Ds6fInr5iFp00Uegj0/6uCEt6z7/woCTlq0Q302F/hgrK3ejJmsv3CXFY1Vep CR1irhuA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1fEDIO-00013x-Uk; Thu, 03 May 2018 12:25:13 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1fEDEd-0007fQ-02 for linux-mtd@lists.infradead.org; Thu, 03 May 2018 12:21:25 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id B944460B23; Thu, 3 May 2018 12:21:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525350077; bh=g7VTAVTKHrvFt33Na0dCEByRdv9tGU7oucyNXSTALpM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TJ8PQcbfGmsaZed9QnbKYf3I+0Rz1XJXNsnPsI1nUMbtaLVmlLWtswz3aaKyGzSQV +KPp33qYgzzgY84sEz2vLgEEmCJV+cE4NlPZAtJFEN5i4ZwNtJq/55xzry5q56JCuB 2hO677mxaHbHlSA/uXu3GpjpWzlY1O67VV19Y4g8= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED, T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from absahu-linux.qualcomm.com (blr-c-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.19.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: absahu@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 6E32D60807; Thu, 3 May 2018 12:21:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1525350076; bh=g7VTAVTKHrvFt33Na0dCEByRdv9tGU7oucyNXSTALpM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lmwZz6cgqzCv4wz7rhzoWTivQL6nGBL67zlTFtDDOg4SE55R5MZmjbpkP3VKZtJ9G vIXI/bjJRk7zwACBPPhBP8iUQjDVHrkDeTWxUVAPlG5wDrFQHR0dHYtm9xtFv4VYu+ 8eKNO8katq/uiuv9TRm4u1P2biNiPhw3F5yxxNMo= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 6E32D60807 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=absahu@codeaurora.org From: Abhishek Sahu To: Boris Brezillon Subject: [PATCH v2 05/14] mtd: rawnand: qcom: wait for desc completion in all BAM channels Date: Thu, 3 May 2018 17:50:32 +0530 Message-Id: <1525350041-22995-6-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1525350041-22995-1-git-send-email-absahu@codeaurora.org> References: <1525350041-22995-1-git-send-email-absahu@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180503_052119_320566_AF2E79ED X-CRM114-Status: GOOD ( 21.57 ) X-Spam-Score: -2.4 (--) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-2.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [198.145.29.96 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Archit Taneja , Richard Weinberger , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Marek Vasut , Abhishek Sahu , linux-mtd@lists.infradead.org, Miquel Raynal , Andy Gross , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The BAM has 3 channels - tx, rx and command. command channel is used for register read/writes, tx channel for data writes and rx channel for data reads. Currently, the driver assumes the transfer completion once it gets all the command descriptor completed. Sometimes, there is race condition in data channel (tx/rx) and command channel completion and in these cases, the data in buffer is not valid during the small window between command descriptor completion and data descriptor completion. Now, the changes have been made to assign the callback for channel's final descriptor. The DMA will generate the callback when all the descriptors have completed in that channel. The NAND transfer will be completed only when all required DMA channels have generated the completion callback. Signed-off-by: Abhishek Sahu --- * Changes from v1: NONE 1. Removed the custom logic and used the helper fuction. drivers/mtd/nand/raw/qcom_nandc.c | 55 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index a8d71ce..3d1ff54 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c @@ -213,6 +213,8 @@ #define QPIC_PER_CW_CMD_SGL 32 #define QPIC_PER_CW_DATA_SGL 8 +#define QPIC_NAND_COMPLETION_TIMEOUT msecs_to_jiffies(2000) + /* * Flags used in DMA descriptor preparation helper functions * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma) @@ -245,6 +247,11 @@ * @tx_sgl_start - start index in data sgl for tx. * @rx_sgl_pos - current index in data sgl for rx. * @rx_sgl_start - start index in data sgl for rx. + * @first_chan_done - if current transfer already has got first channel + * DMA desc completion. + * @txn_done - completion for nand transfer. + * @last_data_desc - last DMA desc in data channel (tx/rx). + * @last_cmd_desc - last DMA desc in command channel. */ struct bam_transaction { struct bam_cmd_element *bam_ce; @@ -258,6 +265,10 @@ struct bam_transaction { u32 tx_sgl_start; u32 rx_sgl_pos; u32 rx_sgl_start; + bool first_chan_done; + struct completion txn_done; + struct dma_async_tx_descriptor *last_data_desc; + struct dma_async_tx_descriptor *last_cmd_desc; }; /* @@ -504,6 +515,8 @@ static void free_bam_transaction(struct qcom_nand_controller *nandc) bam_txn->data_sgl = bam_txn_buf; + init_completion(&bam_txn->txn_done); + return bam_txn; } @@ -523,11 +536,36 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc) bam_txn->tx_sgl_start = 0; bam_txn->rx_sgl_pos = 0; bam_txn->rx_sgl_start = 0; + bam_txn->last_data_desc = NULL; + bam_txn->first_chan_done = false; sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage * QPIC_PER_CW_CMD_SGL); sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage * QPIC_PER_CW_DATA_SGL); + + reinit_completion(&bam_txn->txn_done); +} + +/* Callback for DMA descriptor completion */ +static void qpic_bam_dma_done(void *data) +{ + struct bam_transaction *bam_txn = data; + + /* + * In case of data transfer with NAND, 2 callbacks will be generated. + * One for command channel and another one for data channel. + * If current transaction has data descriptors then check if its + * already got one DMA channel completion callback. In this case + * make the NAND transfer complete otherwise mark first_chan_done true + * and wait for next channel DMA completion callback. + */ + if (bam_txn->last_data_desc && !bam_txn->first_chan_done) { + bam_txn->first_chan_done = true; + return; + } + + complete(&bam_txn->txn_done); } static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) @@ -756,6 +794,12 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc, desc->dma_desc = dma_desc; + /* update last data/command descriptor */ + if (chan == nandc->cmd_chan) + bam_txn->last_cmd_desc = dma_desc; + else + bam_txn->last_data_desc = dma_desc; + list_add_tail(&desc->node, &nandc->desc_list); return 0; @@ -1273,10 +1317,19 @@ static int submit_descs(struct qcom_nand_controller *nandc) cookie = dmaengine_submit(desc->dma_desc); if (nandc->props->is_bam) { + bam_txn->last_cmd_desc->callback = qpic_bam_dma_done; + bam_txn->last_cmd_desc->callback_param = bam_txn; + if (bam_txn->last_data_desc) { + bam_txn->last_data_desc->callback = qpic_bam_dma_done; + bam_txn->last_data_desc->callback_param = bam_txn; + } + dma_async_issue_pending(nandc->tx_chan); dma_async_issue_pending(nandc->rx_chan); + dma_async_issue_pending(nandc->cmd_chan); - if (dma_sync_wait(nandc->cmd_chan, cookie) != DMA_COMPLETE) + if (!wait_for_completion_timeout(&bam_txn->txn_done, + QPIC_NAND_COMPLETION_TIMEOUT)) return -ETIMEDOUT; } else { if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE)