Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp495423imm; Wed, 20 Jun 2018 01:38:38 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLEUJ3oI464e7h6W4XCeX5+pZnDXQPntbe6+Gj7/RxgSmaAcW6ELWaF6/RErbS5YQ1OEDBC X-Received: by 2002:a17:902:1e4:: with SMTP id b91-v6mr22572006plb.155.1529483918596; Wed, 20 Jun 2018 01:38:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1529483918; cv=none; d=google.com; s=arc-20160816; b=MHJcJCmMgvXdoDMirX1QhuiFVDk4rJSjlwDBWPslbCiFCpIkrmLtr+0VZSpvTsNkQH xWL/nTc8/GYghx9Plv5bWsENalDWCi84DzabglPALBu9cFrMeZMWyhruMBLsLRctsFxm POSJz3FF1H6ao/zoM4umP41tF3MnyQfCOGVYWttPneBl9iIpo4C3qH3BKkbRIND2BM9M 4HC8j1pVtb2GrhRgTVikDlSDktODjUwac7iOSz8uA+pS1R3eJGR3S+jO2RPXg8RUXaRK K1P1IiToukQLnXt6lXmAWBRi+aEKpwQ6gFl1LaAGVE2W26QXyjZP8oYvyWnw4F38Sh3m JnRg== 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:dkim-signature:arc-authentication-results; bh=4IjFTxxF8E/v5DFdSlTutseiCp+RfCzXVe2zCSSu9XY=; b=o71Pzogz8zCi4vga/y09ATNPPsbtDH+UrhZJ4HGVzTrpPloqpUHFLdgtEPzE4eZ77+ HVo59f7HbxxZzZPf5Hx13vkU4SaMiBB/uTB7apjo1PUXO7aFYwXago0BIel3isIQ9bOL f3mHTveegck272znJa0Ashcb06u3uRBrLaA4RHUEe9hNFqxHDs7YSpUwr3qre4bzlyRp UgeO7V1Z65dIEBWCPBy60jcCOshrgqZkV/SI8FdCWtuKoQSCeKkq5aOT+EdKM/7TZMUb Qldl+IqPS/z2hz91dHz5AC/ArcKGtks1upFlkvroeoqOebTae7i3T9t3aulnMS2THKXE czrA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=giK4wPdk; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n22-v6si1736835pff.370.2018.06.20.01.38.24; Wed, 20 Jun 2018 01:38:38 -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=@gmail.com header.s=20161025 header.b=giK4wPdk; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932293AbeFTIhU (ORCPT + 99 others); Wed, 20 Jun 2018 04:37:20 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:40061 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754774AbeFTIhK (ORCPT ); Wed, 20 Jun 2018 04:37:10 -0400 Received: by mail-wm0-f67.google.com with SMTP id n5-v6so5181856wmc.5; Wed, 20 Jun 2018 01:37:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4IjFTxxF8E/v5DFdSlTutseiCp+RfCzXVe2zCSSu9XY=; b=giK4wPdkduoxWVHLJuDuv7pVuEz6fuUrQ8md3BwwGFDbhrvxjS804Gccp7Sghynt0m v+QOsWuOev5nzwgHI3ZCFnLFqWOfgZag85A6G/oQ6L6PGUXjfZrPy24v04TWaKpxJHHR 1L8GrVLMGkquJav/CcbUuZFp9IRHrorRGEmnisB+0rnN0FVRx6RtlbEOwQZ/r5a3s4Yd 5aipVubVktl0DOnY2voiAmoD1JLLDoM+KjJvyLA1Mw1eywruE/5qWGfJikbRJK7jA1xX px36NUF3l6b/mIVkW8dOcst/CZjZDjHvWHxG47nDzgH3o+MUV4OrBqhM4ydYxBvPVZLj yADA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=4IjFTxxF8E/v5DFdSlTutseiCp+RfCzXVe2zCSSu9XY=; b=NBoWjF0suNfiFHQqJ4TONTvEPa6uc63iLzogrzLD7UbKa2ZHJZCErs4Yo8lMBqxcCa AAqFmPWzk20r7+qdcLNMBAwSTv3t63Gmq6wWE55iDMmpaLxVbnbJ90D4HMv4SLa9sKr0 V8N/UWyUA457Ynz+bil5AmAh3K/t3fwB78UhWnvfIkw4Ji/s9iqT4DVAmn1gpL0Po5C1 c3zpXa4LpCXZNHObSiVysBLR50kPLmdNF1JPJpIY2tMDEffwgzDSTj5mPW8m10WQJtUd UNTPZTfcZi24efSLF4V7zcWzdo8kvoWAxT43+X2q3ldXAySeWqkxZQbcH99J7XSe8vZE mDQg== X-Gm-Message-State: APt69E0aUP9sC9rYmHId1qNYWoBQSLQOquuUS4FmUMfeBFaYwXt0XRBq FZDW/TgA7Fz5obdRf0Ll0rc= X-Received: by 2002:a1c:78b:: with SMTP id 133-v6mr984647wmh.59.1529483829337; Wed, 20 Jun 2018 01:37:09 -0700 (PDT) Received: from NewMoon.iit.local ([90.147.180.254]) by smtp.gmail.com with ESMTPSA id f24-v6sm1615933wmc.0.2018.06.20.01.37.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Jun 2018 01:37:08 -0700 (PDT) From: Andrea Merello To: vkoul@kernel.org, dan.j.williams@intel.com, michal.simek@xilinx.com, appana.durga.rao@xilinx.com, dmaengine@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Andrea Merello Subject: [PATCH 2/6] dmaengine: xilinx_dma: fix completion callback is not invoked for each DMA operation Date: Wed, 20 Jun 2018 10:36:49 +0200 Message-Id: <20180620083653.17010-2-andrea.merello@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180620083653.17010-1-andrea.merello@gmail.com> References: <20180620083653.17010-1-andrea.merello@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org API specification says: "On completion of each DMA operation, the next in queue is started and a tasklet triggered. The tasklet will then call the client driver completion callback routine for notification, if set." Currently the driver keeps a "desc_pendingcount" counter of the total descriptor pending, and it uses as IRQ coalesce threshold, as result it only calls the CBs after ALL pending operations are completed, which is wrong. This patch uses disable IRQ coalesce and checks for the completion flag for the descriptors (which is further divided in segments). Possibly a better optimization could be using proper IRQ coalesce threshold to get an IRQ after all segments of the descriptors are done. But we don't do that yet.. NOTE: for now we do this only for AXI DMA, other DMA flavors are untested/untouched. This is loosely based on commit 65df81a6dc74 ("xilinx_dma: IrqThreshold set incorrectly, unreliable.") in my linux-4.6-zynq tree From: Jeremy Trimble [original patch] Signed-off-by: Andrea Merello --- drivers/dma/xilinx/xilinx_dma.c | 39 +++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index a516e7ffef21..cf12f7147f07 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -164,6 +164,7 @@ #define XILINX_DMA_CR_COALESCE_SHIFT 16 #define XILINX_DMA_BD_SOP BIT(27) #define XILINX_DMA_BD_EOP BIT(26) +#define XILINX_DMA_BD_CMPLT BIT(31) #define XILINX_DMA_COALESCE_MAX 255 #define XILINX_DMA_NUM_DESCS 255 #define XILINX_DMA_NUM_APP_WORDS 5 @@ -1274,12 +1275,9 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR); - if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) { - reg &= ~XILINX_DMA_CR_COALESCE_MAX; - reg |= chan->desc_pendingcount << - XILINX_DMA_CR_COALESCE_SHIFT; - dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg); - } + reg &= ~XILINX_DMA_CR_COALESCE_MAX; + reg |= 1 << XILINX_DMA_CR_COALESCE_SHIFT; + dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg); if (chan->has_sg && !chan->xdev->mcdma) xilinx_write(chan, XILINX_DMA_REG_CURDESC, @@ -1378,6 +1376,20 @@ static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan) return; list_for_each_entry_safe(desc, next, &chan->active_list, node) { + if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { + /* + * Check whether the last segment in this descriptor + * has been completed. + */ + const struct xilinx_axidma_tx_segment *const tail_seg = + list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, + node); + + /* we've processed all the completed descriptors */ + if (!(tail_seg->hw.status & XILINX_DMA_BD_CMPLT)) + break; + } list_del(&desc->node); if (!desc->cyclic) dma_cookie_complete(&desc->async_tx); @@ -1826,14 +1838,13 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( struct xilinx_axidma_tx_segment, node); desc->async_tx.phys = segment->phys; - /* For the last DMA_MEM_TO_DEV transfer, set EOP */ - if (chan->direction == DMA_MEM_TO_DEV) { - segment->hw.control |= XILINX_DMA_BD_SOP; - segment = list_last_entry(&desc->segments, - struct xilinx_axidma_tx_segment, - node); - segment->hw.control |= XILINX_DMA_BD_EOP; - } + /* For the first transfer, set SOP */ + segment->hw.control |= XILINX_DMA_BD_SOP; + /* For the last transfer, set EOP */ + segment = list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, + node); + segment->hw.control |= XILINX_DMA_BD_EOP; return &desc->async_tx; -- 2.17.1