From patchwork Tue Dec 3 23:56:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alban Browaeys X-Patchwork-Id: 3279911 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 343389F37A for ; Wed, 4 Dec 2013 00:02:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F34AC20494 for ; Wed, 4 Dec 2013 00:02:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9626320260 for ; Wed, 4 Dec 2013 00:02:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754744Ab3LDACu (ORCPT ); Tue, 3 Dec 2013 19:02:50 -0500 Received: from nm26-vm3.bullet.mail.ir2.yahoo.com ([212.82.97.45]:48148 "HELO nm26-vm3.bullet.mail.ir2.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1754710Ab3LDACt convert rfc822-to-8bit (ORCPT ); Tue, 3 Dec 2013 19:02:49 -0500 X-Greylist: delayed 401 seconds by postgrey-1.27 at vger.kernel.org; Tue, 03 Dec 2013 19:02:48 EST Received: from [212.82.98.57] by nm26.bullet.mail.ir2.yahoo.com with NNFMP; 03 Dec 2013 23:56:05 -0000 Received: from [46.228.39.104] by tm10.bullet.mail.ir2.yahoo.com with NNFMP; 03 Dec 2013 23:56:05 -0000 Received: from [127.0.0.1] by smtp141.mail.ir2.yahoo.com with NNFMP; 03 Dec 2013 23:56:05 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1386114965; bh=auNCBYTeBWEZx/jfQKBNYp2qFT/ReaTytzfyVy4u1Lk=; h=X-Yahoo-Newman-Id:X-Yahoo-Newman-Property:X-YMail-OSG:X-Yahoo-SMTP:X-Rocket-Received:Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References:Content-Type:X-Mailer:Mime-Version:Content-Transfer-Encoding; b=DSdJOOIFR3LmWyp2QVsyQYwdScvzslgpT5ZtpaNgPn3M035l7Cj6X7f1+t8vVDGPEy9uwAM1MZ25NrdC5zGDBQWQYIVWHUGpl8SfI2WK7QMSyldAY7+SI/s3FZO/oi+5itw3FP8sAaHxywwNRjuivOZkXaWLrNyNDGyv6o4Qf7s= X-Yahoo-Newman-Id: 938777.68609.bm@smtp141.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: SN2faFkVM1nfum4Ff_s13mfeenG4.ZuM1D4o3ZHVBwk3uuW txCaMNMZlkp_fC8g4aMSdzt_381CclIBNJhmP.1IM1FH3s6fEu6ltfiZ.9YR TH8my1BPx9kxl_nWm2mbUnIq4hdtuTjjf6M28PcJIpSuuIy1VNTRgWqVomTm EDL2BxaH.GTu1NU2rqsjVWM7d7NfIsnaKltyr08hc.0EHejx_Ovr81v1qerh L9FqSZnwvKjFKHs5P8h0C_TaWvV1FKZtPBr32FOcCwUVmRy0vpsTGW7eQefY VrnsjFfe5ZEUP0Vkv448LtHCstPUc5gGVS20Ft3DAkv9_PQZ537104O7gN.T b5qmREtIGXr6x0DS_E7NdphH8v_2h1wtqfZDbsFZcf0oakH1DPJIbfeF80c0 Yfr5H58GwsaLqOh90.KLhB5yuAbDmGhynVwWB14vUQUlH6vTix.ElHFgKGJy smiKYKQQfVN5oDhWhQ3I2Mev2Hfj1ssHMqzO.WT1uo0UnUWXRzSs5MLnYN_t 6oFEYrKfPfEBETIlWL2zsu6Ces89qIckI4yNX.59B X-Yahoo-SMTP: GQBZFNiswBBj4d3U4mCBvx.xTw-- X-Rocket-Received: from penelope-wifi.intranet.maison (prahal@90.23.242.130 with ) by smtp141.mail.ir2.yahoo.com with SMTP; 03 Dec 2013 23:56:05 +0000 UTC Message-ID: <1386114963.20933.10.camel@penelope> Subject: Re: [PATCH 1/3] dmaengine: pl330: Set residue in tx_status callback. From: Alban Browaeys To: Dylan Reid Cc: Chanho Park , kgene.kim@samsung.com, arnd@arndb.de, Padmavathi Venna , Sangbeom Kim , Mark Brown , vinod.koul@intel.com, linux-samsung-soc@vger.kernel.org, padma.kvr@gmail.com, Olof Johansson , linux-arm-kernel@lists.infradead.org Date: Wed, 04 Dec 2013 00:56:03 +0100 In-Reply-To: References: <1378879685-5352-1-git-send-email-padma.v@samsung.com> <1378879685-5352-2-git-send-email-padma.v@samsung.com> <00b401ceafac$e3a88170$aaf98450$@samsung.com> X-Mailer: Evolution 3.11.3 Mime-Version: 1.0 Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FORGED_YAHOO_RCVD, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham 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 Hi Dylan, Le mardi 01 octobre 2013 à 21:33 -0700, Dylan Reid a écrit : > On Thu, Sep 12, 2013 at 4:40 AM, Chanho Park wrote: > > Hi Padmavathi, > > > >> -----Original Message----- > >> From: linux-arm-kernel [mailto:linux-arm-kernel- > >> bounces@lists.infradead.org] On Behalf Of Padmavathi Venna > >> Sent: Wednesday, September 11, 2013 3:08 PM > >> To: linux-samsung-soc@vger.kernel.org; linux-arm- > >> kernel@lists.infradead.org; padma.v@samsung.com; padma.kvr@gmail.com > >> Cc: kgene.kim@samsung.com; arnd@arndb.de; sbkim73@samsung.com; > >> vinod.koul@intel.com; broonie@kernel.org; dgreid@chromium.org; > >> olofj@chromium.org > >> Subject: [PATCH 1/3] dmaengine: pl330: Set residue in tx_status callback. > >> > >> From: Dylan Reid > >> > >> Fill txstate.residue with the amount of bytes remaining in the current > >> transfer if the transfer is not complete. This will be of particular use > >> to i2s DMA transfers, providing more accurate hw_ptr values to ASoC. > >> > >> Signed-off-by: Dylan Reid > >> Reviewed-by: Olof Johansson > >> Signed-off-by: Padmavathi Venna > >> --- > >> drivers/dma/pl330.c | 55 > >> ++++++++++++++++++++++++++++++++++++++++++++++++++- > >> 1 files changed, 54 insertions(+), 1 deletions(-) > >> > >> diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index > >> 593827b..7ab9136 100644 > >> --- a/drivers/dma/pl330.c > >> +++ b/drivers/dma/pl330.c > >> @@ -2476,11 +2476,64 @@ static void pl330_free_chan_resources(struct > >> dma_chan *chan) > >> spin_unlock_irqrestore(&pch->lock, flags); } > >> > >> +static inline int > >> +pl330_src_addr_in_desc(struct dma_pl330_desc *desc, unsigned int sar) { > >> + return ((desc->px.src_addr <= sar) && > >> + (sar <= (desc->px.src_addr + desc->px.bytes))); } > >> + > >> +static inline int > >> +pl330_dst_addr_in_desc(struct dma_pl330_desc *desc, unsigned int dar) { > >> + return ((desc->px.dst_addr <= dar) && > >> + (dar <= (desc->px.dst_addr + desc->px.bytes))); } > >> + > >> +static unsigned int pl330_tx_residue(struct dma_chan *chan) { > >> + struct dma_pl330_chan *pch = to_pchan(chan); > >> + void __iomem *regs = pch->dmac->pif.base; > >> + struct pl330_thread *thrd = pch->pl330_chid; > >> + struct dma_pl330_desc *desc; > >> + unsigned int sar, dar; > >> + unsigned int residue = 0; > >> + unsigned long flags; > >> + > >> + sar = readl(regs + SA(thrd->id)); > >> + dar = readl(regs + DA(thrd->id)); > >> + > >> + spin_lock_irqsave(&pch->lock, flags); > >> + > >> + /* Find the desc related to the current buffer. */ > >> + list_for_each_entry(desc, &pch->work_list, node) { > >> + if (desc->rqcfg.src_inc && pl330_src_addr_in_desc(desc, > >> sar)) { > >> + residue = desc->px.bytes - (sar - > > desc->px.src_addr); > >> + goto found_unlock; > >> + } > >> + if (desc->rqcfg.dst_inc && pl330_dst_addr_in_desc(desc, > >> dar)) { > >> + residue = desc->px.bytes - (dar - > > desc->px.dst_addr); > >> + goto found_unlock; > >> + } > >> + } > >> + > >> +found_unlock: > >> + spin_unlock_irqrestore(&pch->lock, flags); > >> + > >> + return residue; > >> +} > >> + > >> 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; > >> + > >> + ret = dma_cookie_status(chan, cookie, txstate); > >> + if (ret != DMA_SUCCESS) /* Not complete, check amount left. */ > >> + dma_set_residue(txstate, pl330_tx_residue(chan)); > >> + > >> + return ret; > > > > Why didn't you use a cookie value to track the request? > > The cookie is assigned when each transfer is submitted. > > If you save the value in the desc, we can find the request easily. > > If there are several cyclic desc in the work list, is there a better > way to find the "current" one? The chan struct tracks the last > completed and last submitted cookies, but these will be the first and > last respectively as long as the cyclic transfer is active. Is there > an "active" cookie stored somewhere that I missed? > > Looking for the first buffer with status == BUSY is an improvement > I'll make. Any way to avoid looking through the list? > > Thanks, > > Dylan > > > > > Thanks, > > > > Best Regards, > > Chanho Park > > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > > !DSPAM:524ba462143697141112574! > I phased out following hack to get asoc working (using a driver not yet submitted but derived from hardkernel tree driver hkdk-max98090) with dmaengine pcm. Highly likely it will only work for cyclic; it is aimed at raising awareness of the current asoc dmaengine + pl330 breakage. I had to include the transfer up to "used" to compute the residue to the end of the buffer : From 1199129e9a067e32f5aa4e9bc63f9527590b4c92 Mon Sep 17 00:00:00 2001 From: Dylan Reid Date: Wed, 11 Sep 2013 11:38:03 +0530 Subject: [PATCH] dmaengine: pl330: Set residue in tx_status callback. Fill txstate.residue with the amount of bytes remaining in the transfers. This is required by alsa core dmaengine pcm pointer. Based on patch from Dylan Reid but compute the the residue in all transfers instead of the current one. Signed-off-by: Alban Browaeys --- drivers/dma/pl330.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) static void pl330_issue_pending(struct dma_chan *chan) diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index ada7650..58df9ec 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2447,11 +2447,100 @@ static void pl330_free_chan_resources(struct dma_chan *chan) spin_unlock_irqrestore(&pch->lock, flags); } +static inline int +pl330_src_addr_in_desc(struct dma_pl330_desc *desc, unsigned int sar) +{ + return (desc->px.src_addr <= sar) && + (sar <= (desc->px.src_addr + desc->px.bytes)); +} + +static inline int +pl330_dst_addr_in_desc(struct dma_pl330_desc *desc, unsigned int dar) +{ + return (desc->px.dst_addr <= dar) && + (dar <= (desc->px.dst_addr + desc->px.bytes)); +} + + 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); + struct dma_pl330_chan *pch = to_pchan(chan); + void __iomem *regs = pch->dmac->pif.base; + struct pl330_thread *thrd = pch->pl330_chid; + struct dma_pl330_desc *desc; + unsigned int sar, dar; + unsigned int residue = 0; + unsigned long flags; + bool first = true; + bool running = false; + dma_cookie_t last; + dma_cookie_t used; + enum dma_status ret; + + ret = dma_cookie_status(chan, cookie, txstate); + if (ret == DMA_COMPLETE) + return ret; + + /* + * There's no point calculating the residue if there's + * no txstate to store the value. + */ + if (!txstate) + return ret; + + spin_lock_irqsave(&pch->lock, flags); + ret = dma_cookie_status(chan, cookie, txstate); + last = txstate->last; + used = txstate->used; + sar = readl(regs + SA(thrd->id)); + dar = readl(regs + DA(thrd->id)); + + if (ret == DMA_COMPLETE) { + spin_unlock_irqrestore(&pch->lock, flags); + return ret; + } + + list_for_each_entry(desc, &pch->work_list, node) { + if (desc->status == BUSY) { + if (first) { + first = false; + running = true; + } + + if (!running) { + residue += desc->px.bytes; + continue; + } + + if (desc->rqcfg.src_inc + && pl330_src_addr_in_desc(desc, sar)) { + residue += desc->px.bytes; + residue -= sar - desc->px.src_addr; + } else if (desc->rqcfg.dst_inc + && pl330_dst_addr_in_desc(desc, dar)) { + residue += desc->px.bytes; + residue -= dar - desc->px.dst_addr; + } else + WARN_ON(1); + + running = false; + } else if (desc->status == PREP) + residue += desc->px.bytes; + + if (desc->txd.cookie == used) + break; + } + spin_unlock_irqrestore(&pch->lock, flags); + + /* + * This cookie not complete yet + * Get number of bytes left in the active transactions and queue + */ + dma_set_residue(txstate, residue); + + return ret; }