Received: by 10.213.65.68 with SMTP id h4csp691391imn; Wed, 4 Apr 2018 05:46:42 -0700 (PDT) X-Google-Smtp-Source: AIpwx49qZVLBlJiO3rW/DZLgMS4WQ4fgsj+Caw042T0/5VWzQO+1rJ37ErH4uN3PLJnF1rGobaL5 X-Received: by 10.101.85.72 with SMTP id t8mr7492418pgr.347.1522846002852; Wed, 04 Apr 2018 05:46:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522846002; cv=none; d=google.com; s=arc-20160816; b=ZBjw3qd6R6PLFv/kKH+eB2wQKfUpeNAdvMjfxWR+2RcyK5i0bvb+e7E9krAsGwHDEy FGbsZw1WiP9JdFROGbqgWeqEHKRNVYHJB4d0gQzg5MBJlHCOA7hHo7VlL6KtCugo72A7 PFe1exYBsy2li87TagmXvZbcv1h7y4vP1Bo94oQz7qPx7go6rl1T+KSVFXR8S7610Bp+ 9Lp/lgsY+hBVkRd/m7WSnCNRu67m3yVqMl5dgG0JnohKssS3mqLejlr6b1YPLA0/4s0V DPzE0d6lGN6MsSD0EEazJKyW7cRVscb9xcg13XrJgd59p2px3OMi7J0XQjAk6keCmj/D BPdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dmarc-filter:dkim-signature:dkim-signature :arc-authentication-results; bh=naX8lyLpHRylzXAujF+RYG6EyDXoXPnwOYIparBQpY0=; b=QP/kFxz9RW+WEt/eM9g2a/SyAf2SC7sgXHKHfbx2yWPcFZkGl1fP80ieM7xVeoZgTA ZcvsA58GBoLgSfM6ClI81qPsQEei7LjM3l7BANB8j/xWK0V9EDq0BocuNYM2cl6CA9Mz 5P8k582qqQlx9Std3YKXJ2aunPt9gUO7jiQdWABa/oIRDinB7N7vOeT2txC2peQOIx0R BAco3rvzR/nFjFptAZOTgZ9Fq415we5tKsUD7Jwr+8r+QatceeP0vW0Zhk3TkMol/H+A rzkyxGF+fCA27IQYFaTz9cJSqB/HeWF0HHVAaOBz2XPH/syKUFur3kC0DbOoCbDQl/37 4XDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=WY8YPQz4; dkim=pass header.i=@codeaurora.org header.s=default header.b=LdCSWB2W; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 204si3612613pgf.771.2018.04.04.05.46.28; Wed, 04 Apr 2018 05:46:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=WY8YPQz4; dkim=pass header.i=@codeaurora.org header.s=default header.b=LdCSWB2W; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751384AbeDDMm7 (ORCPT + 99 others); Wed, 4 Apr 2018 08:42:59 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:40554 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751038AbeDDMmy (ORCPT ); Wed, 4 Apr 2018 08:42:54 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id E3DCF60F6B; Wed, 4 Apr 2018 12:42:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1522845773; bh=4NXg57UtRP5eA9kjNmS+mo4ghDjq9IXsBBSbWksuSO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WY8YPQz4TGzcMriWRphMLb68BvSJt8fBa3ntUO5WZ8Z7E4VexdeDXLBMZrSE65hmA ld1/Sk/UjQuED7XOajQpnZssM5VpydtBZQpv/PTyO/fIMrpHUdB0wDHYtHow98ryAa Hu2duvS91qVZmtA5o9PqFLWPYmWNuVNivTP/Loo8= 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 1566960C55; Wed, 4 Apr 2018 12:42:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1522845772; bh=4NXg57UtRP5eA9kjNmS+mo4ghDjq9IXsBBSbWksuSO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LdCSWB2WL6ZKSpwKKl6JqJtwqUvztrvBg0qhkr5LCgX4cZLB1QY1bJ0+B3ffk/oUe WmmFkITRjOmgmuj5z4XwXke91q/SMKaH81UltNxJZ2ljXy12/zk4Zsxt/3c6LmRuih dzRVGQ4lScuxm5cwUGl7+qcCqNhIvJh1MvybfTmo= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 1566960C55 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 Cc: David Woodhouse , Brian Norris , Marek Vasut , Richard Weinberger , Cyrille Pitchen , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, Andy Gross , Archit Taneja , Abhishek Sahu Subject: [PATCH 2/9] mtd: nand: qcom: wait for desc completion in all BAM channels Date: Wed, 4 Apr 2018 18:12:18 +0530 Message-Id: <1522845745-6624-3-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1522845745-6624-1-git-send-email-absahu@codeaurora.org> References: <1522845745-6624-1-git-send-email-absahu@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.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 descriptor 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 --- drivers/mtd/nand/qcom_nandc.c | 55 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c index 8dd40de..17321fc 100644 --- a/drivers/mtd/nand/qcom_nandc.c +++ b/drivers/mtd/nand/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) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation