From patchwork Mon Apr 14 07:00:47 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Howard X-Patchwork-Id: 3976841 Return-Path: X-Original-To: patchwork-davinci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5B6A7BFF02 for ; Mon, 14 Apr 2014 07:02:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 42C84201B9 for ; Mon, 14 Apr 2014 07:02:12 +0000 (UTC) Received: from arroyo.ext.ti.com (arroyo.ext.ti.com [192.94.94.40]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C44532017A for ; Mon, 14 Apr 2014 07:02:10 +0000 (UTC) Received: from dflxv15.itg.ti.com ([128.247.5.124]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id s3E713Hv029108; Mon, 14 Apr 2014 02:01:03 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s3E712ft012507; Mon, 14 Apr 2014 02:01:02 -0500 Received: from dlep32.itg.ti.com (157.170.170.100) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.3.174.1; Mon, 14 Apr 2014 02:01:02 -0500 Received: from linux.omap.com (dlelxs01.itg.ti.com [157.170.227.31]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s3E711YB012167; Mon, 14 Apr 2014 02:01:01 -0500 Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 1401880627; Mon, 14 Apr 2014 02:01:01 -0500 (CDT) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dlelxv84.itg.ti.com (dlelxv84.itg.ti.com [172.17.0.246]) by linux.omap.com (Postfix) with ESMTP id 017BA80626 for ; Mon, 14 Apr 2014 02:00:59 -0500 (CDT) Received: from medina.ext.ti.com (medina.ext.ti.com [192.91.81.31]) by dlelxv84.itg.ti.com (8.14.3/8.13.8) with ESMTP id s3E70xMG025246 for ; Mon, 14 Apr 2014 02:00:59 -0500 Received: from mail6.bemta12.messagelabs.com (mail6.bemta12.messagelabs.com [216.82.250.247]) by medina.ext.ti.com (8.13.7/8.13.7) with ESMTP id s3E70xHI023383 for ; Mon, 14 Apr 2014 02:00:59 -0500 Received: from [216.82.250.99:17650] by server-13.bemta-12.messagelabs.com id 2C/41-10030-BA78B435; Mon, 14 Apr 2014 07:00:59 +0000 X-Env-Sender: pjh@northern-ridge.com.au X-Msg-Ref: server-14.tower-126.messagelabs.com!1397458855!14124856!1 X-Originating-IP: [119.15.76.149] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 6.11.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 8992 invoked from network); 14 Apr 2014 07:00:55 -0000 Received: from 76.15.119-149.static.idl.com.au (HELO mail.northern-ridge.com.au) (119.15.76.149) by server-14.tower-126.messagelabs.com with SMTP; 14 Apr 2014 07:00:55 -0000 Received: from [192.168.0.99] (stan978120.lnk.telstra.net [139.130.72.114]) by mail.northern-ridge.com.au (Postfix) with ESMTP id 3F0B14001A6C for ; Mon, 14 Apr 2014 17:00:53 +1000 (EST) Message-ID: <1397458847.3064.15.camel@localhost.localdomain> Subject: DA850 - SD detection broken by edma change (but only on mainline) From: Peter Howard To: Date: Mon, 14 Apr 2014 17:00:47 +1000 X-Mailer: Evolution 3.10.4 (3.10.4-2.fc20) MIME-Version: 1.0 X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 For the DA850, I've found that trying to detection of a card in the SD slot during boot is broken as of 3.12 on mainline. You end up like this (from a 3.14 kernel.org kernel): ... davinci_mdio davinci_mdio.0: davinci mdio revision 1.5 davinci_mdio davinci_mdio.0: detected phy mask fffffffe libphy: davinci_mdio.0: probed davinci_mdio davinci_mdio.0: phy[0]: device davinci_mdio-0:00, driver unknown input: gpio-keys-polled as /devices/platform/gpio-keys-polled.1/input/input0 i2c /dev entries driver davinci_mmc da830-mmc.0: Using DMA, 4-bit mode TCP: cubic registered NET: Registered protocol family 17 console [netcon0] enabled netconsole: network logging started davinci_emac davinci_emac.1: using random MAC addr: ba:64:c2:e7:17:f9 Waiting for root device /dev/mmcblk0p2... random: nonblocking pool is initialized and then nothing . . . as opposed to previously: libphy: davinci_mdio.0: probed davinci_mdio davinci_mdio.0: phy[0]: device davinci_mdio-0:00, driver unknown input: gpio-keys-polled as /devices/platform/gpio-keys-polled.1/input/input0 i2c /dev entries driver edma-dma-engine edma-dma-engine.0: allocated channel for 0:17 edma-dma-engine edma-dma-engine.0: allocated channel for 0:16 davinci_mmc da830-mmc.0: Using DMA, 4-bit mode TCP: cubic registered NET: Registered protocol family 17 console [netcon0] enabled netconsole: network logging started davinci_emac davinci_emac.1: using random MAC addr: 2a:e7:9f:05:6c:c9 Waiting for root device /dev/mmcblk0p2... mmc0: new high speed SDHC card at address e624 mmcblk0: mmc0:e624 SU08G 7.40 GiB mmcblk0: p1 p2 kjournald starting. Commit interval 5 seconds ... I traced the problem to the following commit. Interestingly, it is _not_ in the linux-davinci repo yet. Joel Fernandes - given the commit is yours, any ideas why it breaks the DA850? (Note: although in that failure you don't see channel allocation messages for the edma engine, I have seen failures building immediately around the commit below where those allocation messages do appear (but the card isn't detected) commit 534070622d2c7fbc5cc929aa93541ccd0ae52ab1 Author: Joel Fernandes Date: Tue Sep 3 10:02:46 2013 -0500 dma: edma: Write out and handle MAX_NR_SG at a given time Process SG-elements in batches of MAX_NR_SG if they are greater than MAX_NR_SG. Due to this, at any given time only those many slots will be used in the given channel no matter how long the scatter list is. We keep track of how much has been written inorder to process the next batch of elements in the scatter-list and detect completion. For such intermediate transfer completions (one batch of MAX_NR_SG), make use of pause and resume functions instead of start and stop when such intermediate transfer is in progress or completed as we donot want to clear any pending events. Signed-off-by: Joel Fernandes Signed-off-by: Vinod Koul diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index f907512..4c1c258 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -56,6 +56,7 @@ struct edma_desc { struct list_head node; int absync; int pset_nr; + int processed; struct edmacc_param pset[0]; }; @@ -104,22 +105,34 @@ static void edma_desc_free(struct virt_dma_desc *vdesc) /* Dispatch a queued descriptor to the controller (caller holds lock) */ static void edma_execute(struct edma_chan *echan) { - struct virt_dma_desc *vdesc = vchan_next_desc(&echan->vchan); + struct virt_dma_desc *vdesc; struct edma_desc *edesc; - int i; - - if (!vdesc) { - echan->edesc = NULL; - return; + struct device *dev = echan->vchan.chan.device->dev; + int i, j, left, nslots; + + /* If either we processed all psets or we're still not started */ + if (!echan->edesc || + echan->edesc->pset_nr == echan->edesc->processed) { + /* Get next vdesc */ + vdesc = vchan_next_desc(&echan->vchan); + if (!vdesc) { + echan->edesc = NULL; + return; + } + list_del(&vdesc->node); + echan->edesc = to_edma_desc(&vdesc->tx); } - list_del(&vdesc->node); + edesc = echan->edesc; - echan->edesc = edesc = to_edma_desc(&vdesc->tx); + /* Find out how many left */ + left = edesc->pset_nr - edesc->processed; + nslots = min(MAX_NR_SG, left); /* Write descriptor PaRAM set(s) */ - for (i = 0; i < edesc->pset_nr; i++) { - edma_write_slot(echan->slot[i], &edesc->pset[i]); + for (i = 0; i < nslots; i++) { + j = i + edesc->processed; + edma_write_slot(echan->slot[i], &edesc->pset[j]); dev_dbg(echan->vchan.chan.device->dev, "\n pset[%d]:\n" " chnum\t%d\n" @@ -132,24 +145,31 @@ static void edma_execute(struct edma_chan *echan) " bidx\t%08x\n" " cidx\t%08x\n" " lkrld\t%08x\n", - i, echan->ch_num, echan->slot[i], - edesc->pset[i].opt, - edesc->pset[i].src, - edesc->pset[i].dst, - edesc->pset[i].a_b_cnt, - edesc->pset[i].ccnt, - edesc->pset[i].src_dst_bidx, - edesc->pset[i].src_dst_cidx, - edesc->pset[i].link_bcntrld); + j, echan->ch_num, echan->slot[i], + edesc->pset[j].opt, + edesc->pset[j].src, + edesc->pset[j].dst, + edesc->pset[j].a_b_cnt, + edesc->pset[j].ccnt, + edesc->pset[j].src_dst_bidx, + edesc->pset[j].src_dst_cidx, + edesc->pset[j].link_bcntrld); /* Link to the previous slot if not the last set */ - if (i != (edesc->pset_nr - 1)) + if (i != (nslots - 1)) edma_link(echan->slot[i], echan->slot[i+1]); /* Final pset links to the dummy pset */ else edma_link(echan->slot[i], echan->ecc->dummy_slot); } - edma_start(echan->ch_num); + edesc->processed += nslots; + + edma_resume(echan->ch_num); + + if (edesc->processed <= MAX_NR_SG) { + dev_dbg(dev, "first transfer starting %d\n", echan->ch_num); + edma_start(echan->ch_num); + } } static int edma_terminate_all(struct edma_chan *echan) @@ -368,19 +388,24 @@ static void edma_callback(unsigned ch_num, u16 ch_status, void *data) struct edma_desc *edesc; unsigned long flags; - /* Stop the channel */ - edma_stop(echan->ch_num); + /* Pause the channel */ + edma_pause(echan->ch_num); switch (ch_status) { case DMA_COMPLETE: - dev_dbg(dev, "transfer complete on channel %d\n", ch_num); - spin_lock_irqsave(&echan->vchan.lock, flags); edesc = echan->edesc; if (edesc) { + if (edesc->processed == edesc->pset_nr) { + dev_dbg(dev, "Transfer complete, stopping channel %d\n", ch_num); + edma_stop(echan->ch_num); + vchan_cookie_complete(&edesc->vdesc); + } else { + dev_dbg(dev, "Intermediate transfer complete on channel %d\n", ch_num); + } + edma_execute(echan); - vchan_cookie_complete(&edesc->vdesc); } spin_unlock_irqrestore(&echan->vchan.lock, flags);