From patchwork Thu Jun 29 07:15:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Abhishek Sahu X-Patchwork-Id: 782080 X-Patchwork-Delegate: boris.brezillon@free-electrons.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.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 3wyrbd6jKNz9s75 for ; Thu, 29 Jun 2017 17:18:05 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="BzA02Qq2"; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=codeaurora.org header.i=@codeaurora.org header.b="O31uEU+8"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="WwVRoK/5"; dkim-atps=neutral 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:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version: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=o6XB+w3XhlxhtC6rBHcm+l+zicgrqlmBtCecGRx3uwk=; b=BzA02Qq2zmvQXq VXrxOZvsiL/yPZ3vhss7+W3t792My5/mBipa2q5uJlXHOXhJ3Q7u8Y6rJZwX+ON8WPJ7PnhHG4e89 XTX48uo9daEaptzN/MYiFFJO0HtFfaZOEvukmKCzk74w1sSWdBN48oW0IVhFgiEuG4HKpMGBTa18w BOUM5YBSrNYlo+50seiFTcvzBS0bhQbcr9vJtgRa3ggTMVcxwnb6T/BsgssCVub5L4CaeSXdlHa4U Z+qwA3r+YOG8KNKBlp6l8871s4WN2WrUV/n9jqVfFac6KCm0dQ9AI6WUQFDQ8yDYnkNXmHRe0p7NN 65ZlF10cJDOl3nDY7dOw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dQTi7-0008IJ-TV; Thu, 29 Jun 2017 07:17:55 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dQThU-00073y-DS for linux-mtd@lists.infradead.org; Thu, 29 Jun 2017 07:17:28 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 6A05C609C3; Thu, 29 Jun 2017 07:16:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1498720616; bh=hbztIdwwarf/dACY3AeSPsnL+3ciQwhxNuDFUzdYLog=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O31uEU+829vpKck0w9A8jKiCw26BPbvL+5pWN/Jdn/x939WuQyvFj9bpASchYdfFm 88bJ6OgM4uhIGu3BPN6boGCdHSXwhkKV01v8fKWFo1Dg97HZeHynKRC2XoCQ8hkOSv K1BqHbYJs8CC8q9d2IHrknSGg0hy/ZLrhvYLjfUc= 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 6276360A96; Thu, 29 Jun 2017 07:16:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1498720615; bh=hbztIdwwarf/dACY3AeSPsnL+3ciQwhxNuDFUzdYLog=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WwVRoK/5IpS7cIYH4d2glS2BIWCPP0jAidE5g6tFoNAb4xc0mT5Y78VfDObDW3heo Fl9R2MixSVwPdWwedyEmpCqP1xE/5vccJqVV4MAHB60jrAQ+bmeWAlZMlqvR/1yF1t TPUxOIM5gppx/T4l7XCXZGJ7lwCf7CXLVryuSHpU= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 6276360A96 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: dwmw2@infradead.org, computersforpeace@gmail.com, boris.brezillon@free-electrons.com, marek.vasut@gmail.com, richard@nod.at, cyrille.pitchen@wedev4u.fr, robh+dt@kernel.org, mark.rutland@arm.com Subject: [PATCH 06/14] qcom: mtd: nand: add bam dma descriptor handling Date: Thu, 29 Jun 2017 12:45:58 +0530 Message-Id: <1498720566-20782-7-git-send-email-absahu@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1498720566-20782-1-git-send-email-absahu@codeaurora.org> References: <1498720566-20782-1-git-send-email-absahu@codeaurora.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170629_001717_188992_3614D009 X-CRM114-Status: GOOD ( 18.71 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [198.145.29.96 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 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 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: devicetree@vger.kernel.org, architt@codeaurora.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, Abhishek Sahu , linux-mtd@lists.infradead.org, andy.gross@linaro.org, sricharan@codeaurora.org Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org 1. prepare_bam_async_desc is the function which will call all the DMA API’s. It will fetch the outstanding scatter gather list for passed channel and will do the DMA descriptor formation. The DMA flag is dependent upon the type of channel. 2. For ADM DMA, the descriptor is being formed for every DMA request so its sgl count will be always 1 while in BAM DMA, the clubbing of descriptor is being done to increase throughput. 3. ADM uses only one channel while in BAM, data descriptors will be submitted to tx channel (for write) or rx channel (for read) and all the registers read/write descriptors in command channel. Signed-off-by: Abhishek Sahu --- drivers/mtd/nand/qcom_nandc.c | 119 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c index f8d0bde..7042a65 100644 --- a/drivers/mtd/nand/qcom_nandc.c +++ b/drivers/mtd/nand/qcom_nandc.c @@ -206,14 +206,22 @@ struct bam_transaction { * This data type corresponds to the nand dma descriptor * @list - list for desc_info * @dir - DMA transfer direction - * @sgl - sgl which will be used for single sgl dma descriptor + * @sgl - sgl which will be used for single sgl dma descriptor. Only used by ADM + * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM + * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM * @dma_desc - low level dma engine descriptor */ struct desc_info { struct list_head node; enum dma_data_direction dir; - struct scatterlist sgl; + union { + struct scatterlist sgl; + struct { + struct scatterlist *bam_sgl; + int sgl_cnt; + }; + }; struct dma_async_tx_descriptor *dma_desc; }; @@ -564,6 +572,68 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read) nandc_set_reg(nandc, NAND_EXEC_CMD, 1); } +/* + * Maps the scatter gather list for DMA transfer and forms the DMA descriptor + * for BAM. This descriptor will be added in the NAND DMA descriptor queue + * which will be submitted to DMA engine. + */ +static int prepare_bam_async_desc(struct qcom_nand_controller *nandc, + struct dma_chan *chan, + unsigned long flags) +{ + struct desc_info *desc; + struct scatterlist *sgl; + unsigned int sgl_cnt; + struct bam_transaction *bam_txn = nandc->bam_txn; + enum dma_transfer_direction dir_eng; + struct dma_async_tx_descriptor *dma_desc; + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + if (chan == nandc->cmd_chan) { + sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start]; + sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start; + bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos; + dir_eng = DMA_MEM_TO_DEV; + desc->dir = DMA_TO_DEVICE; + } else if (chan == nandc->tx_chan) { + sgl = &bam_txn->data_sg[bam_txn->tx_sgl_start]; + sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start; + bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos; + dir_eng = DMA_MEM_TO_DEV; + desc->dir = DMA_TO_DEVICE; + } else { + sgl = &bam_txn->data_sg[bam_txn->rx_sgl_start]; + sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start; + bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos; + desc->dir = DMA_FROM_DEVICE; + dir_eng = DMA_DEV_TO_MEM; + } + + sg_mark_end(sgl + sgl_cnt - 1); + dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir); + + desc->sgl_cnt = sgl_cnt; + desc->bam_sgl = sgl; + + dma_desc = dmaengine_prep_slave_sg(chan, sgl, sgl_cnt, dir_eng, + flags); + + if (!dma_desc) { + dev_err(nandc->dev, "failure in prep desc\n"); + kfree(desc); + return -EINVAL; + } + + desc->dma_desc = dma_desc; + + list_add_tail(&desc->node, &nandc->desc_list); + + return 0; +} + static int prep_dma_desc(struct qcom_nand_controller *nandc, bool read, int reg_off, const void *vaddr, int size, bool flow_control) @@ -891,12 +961,44 @@ static int submit_descs(struct qcom_nand_controller *nandc) { struct desc_info *desc; dma_cookie_t cookie = 0; + struct bam_transaction *bam_txn = nandc->bam_txn; + int r; + + if (nandc->dma_bam_enabled) { + if (bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start) { + r = prepare_bam_async_desc(nandc, nandc->rx_chan, 0); + if (r) + return r; + } + + if (bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start) { + r = prepare_bam_async_desc(nandc, nandc->tx_chan, + DMA_PREP_INTERRUPT); + if (r) + return r; + } + + if (bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start) { + r = prepare_bam_async_desc(nandc, nandc->cmd_chan, + DMA_PREP_CMD); + if (r) + return r; + } + } list_for_each_entry(desc, &nandc->desc_list, node) cookie = dmaengine_submit(desc->dma_desc); - if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE) - return -ETIMEDOUT; + if (nandc->dma_bam_enabled) { + dma_async_issue_pending(nandc->tx_chan); + dma_async_issue_pending(nandc->rx_chan); + + if (dma_sync_wait(nandc->cmd_chan, cookie) != DMA_COMPLETE) + return -ETIMEDOUT; + } else { + if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE) + return -ETIMEDOUT; + } return 0; } @@ -907,7 +1009,14 @@ static void free_descs(struct qcom_nand_controller *nandc) list_for_each_entry_safe(desc, n, &nandc->desc_list, node) { list_del(&desc->node); - dma_unmap_sg(nandc->dev, &desc->sgl, 1, desc->dir); + + if (nandc->dma_bam_enabled) + dma_unmap_sg(nandc->dev, desc->bam_sgl, + desc->sgl_cnt, desc->dir); + else + dma_unmap_sg(nandc->dev, &desc->sgl, 1, + desc->dir); + kfree(desc); } }