From patchwork Wed Feb 11 12:23:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Baldyga X-Patchwork-Id: 5812491 Return-Path: X-Original-To: patchwork-dmaengine@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 50C9A9F30C for ; Wed, 11 Feb 2015 12:24:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6B20C20218 for ; Wed, 11 Feb 2015 12:24:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6415620212 for ; Wed, 11 Feb 2015 12:24:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752723AbbBKMX6 (ORCPT ); Wed, 11 Feb 2015 07:23:58 -0500 Received: from mailout1.samsung.com ([203.254.224.24]:28884 "EHLO mailout1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752274AbbBKMX4 (ORCPT ); Wed, 11 Feb 2015 07:23:56 -0500 Received: from epcpsbgm2.samsung.com (epcpsbgm2 [203.254.230.27]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NJL00C8BX3U7170@mailout1.samsung.com>; Wed, 11 Feb 2015 21:23:54 +0900 (KST) X-AuditID: cbfee61b-f79d76d0000024d6-58-54db49da71af Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id DE.07.09430.AD94BD45; Wed, 11 Feb 2015 21:23:54 +0900 (KST) Received: from AMDC2122.DIGITAL.local ([106.120.53.17]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0NJL00ARIX2W0A70@mmp2.samsung.com>; Wed, 11 Feb 2015 21:23:54 +0900 (KST) From: Robert Baldyga To: vinod.koul@intel.com Cc: dan.j.williams@intel.com, lars@metafoo.de, dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org, m.szyprowski@samsung.com, k.kozlowski@samsung.com, Robert Baldyga , Lukasz Czerwinski Subject: [PATCH v4 1/2] dma: pl330: improve pl330_tx_status() function Date: Wed, 11 Feb 2015 13:23:17 +0100 Message-id: <1423657398-13876-2-git-send-email-r.baldyga@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1423657398-13876-1-git-send-email-r.baldyga@samsung.com> References: <1423657398-13876-1-git-send-email-r.baldyga@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFprJLMWRmVeSWpSXmKPExsVy+t9jQd1bnrdDDB7+M7SYPvUCo8XqqX9Z LV6/MLT4NW0Sm8WSyfNZLS7vmsNmsfbIXXaLB4d3slu87NvP4sDpsXjPSyaPJW8OsXr0bVnF 6PF5k1wASxSXTUpqTmZZapG+XQJXxvu5R5gKDilVfH4xj62BcadMFyMnh4SAicTztmksELaY xIV769m6GLk4hASmM0r8e/mHGcJpZ5JYcKODGaSKTUBHYsv3CYwgtoiAhMT2Z33sIEXMAl8Z JTbMeAI2SljATeLZrPfsIDaLgKrElhWPwGxeAVeJDVMPMkOsk5M4eWwyK4jNCVQ/ZdJNJhBb CKjm0uKXzBMYeRcwMqxiFE0tSC4oTkrPNdIrTswtLs1L10vOz93ECA6wZ9I7GFc1WBxiFOBg VOLh/bDpVogQa2JZcWXuIUYJDmYlEd5rrrdDhHhTEiurUovy44tKc1KLDzFKc7AoifMq2beF CAmkJ5akZqemFqQWwWSZODilGhhTf+/7ymuyy17iwdlbk2YdOqNpe/jAcsa9ChMUTVr/iCWe 4Db/NHF2XrDxDd4dvWu1VC7MtqpfeJc1xs+58sSkVTn3gplPafR8+rt20s1g9sPNvX81n0eF NB6flLxkbdCx8DvRb3/7/hHae/CQC9+dsvY9i1WrrI9Pzbj4T32zWkRGUb/g77UVSizFGYmG WsxFxYkAGMgcDiwCAAA= Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 This patch adds possibility to read residue of DMA transfer. It's useful when we want to know how many bytes have been transferred before we terminate channel. It can take place, for example, on timeout interrupt. Signed-off-by: Lukasz Czerwinski Signed-off-by: Robert Baldyga --- drivers/dma/pl330.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 027f1d7..517abd6 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -504,6 +504,9 @@ struct dma_pl330_desc { enum desc_status status; + int bytes_requested; + bool last; + /* The channel which currently holds this desc */ struct dma_pl330_chan *pchan; @@ -2167,11 +2170,74 @@ static void pl330_free_chan_resources(struct dma_chan *chan) pm_runtime_put_autosuspend(pch->dmac->ddma.dev); } +int pl330_get_current_xferred_count(struct dma_pl330_chan *pch, + struct dma_pl330_desc *desc) +{ + struct pl330_thread *thrd = pch->thread; + struct pl330_dmac *pl330 = pch->dmac; + void __iomem *regs = thrd->dmac->base; + u32 val, addr; + + pm_runtime_get_sync(pl330->ddma.dev); + val = addr = 0; + if (desc->rqcfg.src_inc) { + val = readl(regs + SA(thrd->id)); + addr = desc->px.src_addr; + } else { + val = readl(regs + DA(thrd->id)); + addr = desc->px.dst_addr; + } + pm_runtime_mark_last_busy(pch->dmac->ddma.dev); + pm_runtime_put_autosuspend(pl330->ddma.dev); + return val - addr; +} + static enum dma_status pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie, struct dma_tx_state *txstate) { - return dma_cookie_status(chan, cookie, txstate); + enum dma_status ret; + unsigned long flags; + struct dma_pl330_desc *desc, *running = NULL; + struct dma_pl330_chan *pch = to_pchan(chan); + unsigned int transferred, residual = 0; + + ret = dma_cookie_status(chan, cookie, txstate); + + if (!txstate) + return ret; + + if (ret == DMA_COMPLETE) + goto out; + + spin_lock_irqsave(&pch->lock, flags); + + if (pch->thread->req_running != -1) + running = pch->thread->req[pch->thread->req_running].desc; + + /* Check in pending list */ + list_for_each_entry(desc, &pch->work_list, node) { + if (desc->status == DONE) + transferred = desc->bytes_requested; + else if (running && desc == running) + transferred = + pl330_get_current_xferred_count(pch, desc); + else + transferred = 0; + residual += desc->bytes_requested - transferred; + if (desc->txd.cookie == cookie) { + ret = desc->status; + break; + } + if (desc->last) + residual = 0; + } + spin_unlock_irqrestore(&pch->lock, flags); + +out: + dma_set_residue(txstate, residual); + + return ret; } static void pl330_issue_pending(struct dma_chan *chan) @@ -2216,12 +2282,14 @@ static dma_cookie_t pl330_tx_submit(struct dma_async_tx_descriptor *tx) desc->txd.callback = last->txd.callback; desc->txd.callback_param = last->txd.callback_param; } + last->last = false; dma_cookie_assign(&desc->txd); list_move_tail(&desc->node, &pch->submitted_list); } + last->last = true; cookie = dma_cookie_assign(&last->txd); list_add_tail(&last->node, &pch->submitted_list); spin_unlock_irqrestore(&pch->lock, flags); @@ -2444,6 +2512,7 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic( desc->rqtype = direction; desc->rqcfg.brst_size = pch->burst_sz; desc->rqcfg.brst_len = 1; + desc->bytes_requested = period_len; fill_px(&desc->px, dst, src, period_len); if (!first) @@ -2586,6 +2655,7 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, desc->rqcfg.brst_size = pch->burst_sz; desc->rqcfg.brst_len = 1; desc->rqtype = direction; + desc->bytes_requested = sg_dma_len(sg); } /* Return the last desc in the chain */ @@ -2771,7 +2841,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pd->src_addr_widths = PL330_DMA_BUSWIDTHS; pd->dst_addr_widths = PL330_DMA_BUSWIDTHS; pd->directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); - pd->residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR; + pd->residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; ret = dma_async_device_register(pd); if (ret) {