From patchwork Wed Aug 27 13:52:50 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ezequiel Garcia X-Patchwork-Id: 4788461 Return-Path: X-Original-To: patchwork-dmaengine@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 CDC79C0338 for ; Wed, 27 Aug 2014 13:55:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6ECD22015E for ; Wed, 27 Aug 2014 13:55:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E4F3A2012D for ; Wed, 27 Aug 2014 13:54:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934569AbaH0Ny6 (ORCPT ); Wed, 27 Aug 2014 09:54:58 -0400 Received: from top.free-electrons.com ([176.31.233.9]:52378 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S934584AbaH0Ny6 (ORCPT ); Wed, 27 Aug 2014 09:54:58 -0400 Received: by mail.free-electrons.com (Postfix, from userid 106) id 17D0C504; Wed, 27 Aug 2014 15:54:59 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from localhost.localdomain (unknown [190.2.108.81]) by mail.free-electrons.com (Postfix) with ESMTPSA id 102266F8; Wed, 27 Aug 2014 15:54:41 +0200 (CEST) From: Ezequiel Garcia To: , Vinod Koul Cc: Thomas Petazzoni , Gregory Clement , Lior Amsalem , Tawfik Bayouk , Ezequiel Garcia Subject: [PATCH 2/7] dma: mv_xor: Simplify the DMA_MEMCPY operation Date: Wed, 27 Aug 2014 10:52:50 -0300 Message-Id: <1409147575-4860-3-git-send-email-ezequiel.garcia@free-electrons.com> X-Mailer: git-send-email 2.0.1 In-Reply-To: <1409147575-4860-1-git-send-email-ezequiel.garcia@free-electrons.com> References: <1409147575-4860-1-git-send-email-ezequiel.garcia@free-electrons.com> Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Lior Amsalem A memory copy operation can be expressed as an XOR operation with one source. This commit removes code duplication in the driver by reusing the XOR operation for the MEMCPY. As an added benefit, we can now put MEMCPY and XOR descriptors on the same chain, which improves performance. Signed-off-by: Lior Amsalem Signed-off-by: Ezequiel Garcia --- drivers/dma/mv_xor.c | 77 ++++++++-------------------------------------------- 1 file changed, 12 insertions(+), 65 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 7c38768..1e43f18 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -82,13 +82,6 @@ static void mv_desc_set_dest_addr(struct mv_xor_desc_slot *desc, hw_desc->phy_dest_addr = addr; } -static int mv_chan_memset_slot_count(size_t len) -{ - return 1; -} - -#define mv_chan_memcpy_slot_count(c) mv_chan_memset_slot_count(c) - static void mv_desc_set_src_addr(struct mv_xor_desc_slot *desc, int index, dma_addr_t addr) { @@ -144,17 +137,6 @@ static void mv_xor_device_clear_err_status(struct mv_xor_chan *chan) writel_relaxed(val, XOR_INTR_CAUSE(chan)); } -static int mv_can_chain(struct mv_xor_desc_slot *desc) -{ - struct mv_xor_desc_slot *chain_old_tail = list_entry( - desc->chain_node.prev, struct mv_xor_desc_slot, chain_node); - - if (chain_old_tail->type != desc->type) - return 0; - - return 1; -} - static void mv_set_mode(struct mv_xor_chan *chan, enum dma_transaction_type type) { @@ -236,8 +218,6 @@ static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan, { dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: sw_desc %p\n", __func__, __LINE__, sw_desc); - if (sw_desc->type != mv_chan->current_type) - mv_set_mode(mv_chan, sw_desc->type); /* set the hardware chain */ mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys); @@ -492,9 +472,6 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx) list_splice_init(&grp_start->tx_list, &old_chain_tail->chain_node); - if (!mv_can_chain(grp_start)) - goto submit_done; - dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %pa\n", &old_chain_tail->async_tx.phys); @@ -516,7 +493,6 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx) if (new_hw_chain) mv_xor_start_new_chain(mv_chan, grp_start); -submit_done: spin_unlock_bh(&mv_chan->lock); return cookie; @@ -573,45 +549,6 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) } static struct dma_async_tx_descriptor * -mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, - size_t len, unsigned long flags) -{ - struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); - struct mv_xor_desc_slot *sw_desc, *grp_start; - int slot_cnt; - - dev_dbg(mv_chan_to_devp(mv_chan), - "%s dest: %pad src %pad len: %u flags: %ld\n", - __func__, &dest, &src, len, flags); - if (unlikely(len < MV_XOR_MIN_BYTE_COUNT)) - return NULL; - - BUG_ON(len > MV_XOR_MAX_BYTE_COUNT); - - spin_lock_bh(&mv_chan->lock); - slot_cnt = mv_chan_memcpy_slot_count(len); - sw_desc = mv_xor_alloc_slots(mv_chan, slot_cnt, 1); - if (sw_desc) { - sw_desc->type = DMA_MEMCPY; - sw_desc->async_tx.flags = flags; - grp_start = sw_desc->group_head; - mv_desc_init(grp_start, flags); - mv_desc_set_byte_count(grp_start, len); - mv_desc_set_dest_addr(sw_desc->group_head, dest); - mv_desc_set_src_addr(grp_start, 0, src); - sw_desc->unmap_src_cnt = 1; - sw_desc->unmap_len = len; - } - spin_unlock_bh(&mv_chan->lock); - - dev_dbg(mv_chan_to_devp(mv_chan), - "%s sw_desc %p async_tx %p\n", - __func__, sw_desc, sw_desc ? &sw_desc->async_tx : NULL); - - return sw_desc ? &sw_desc->async_tx : NULL; -} - -static struct dma_async_tx_descriptor * mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, unsigned int src_cnt, size_t len, unsigned long flags) { @@ -636,7 +573,6 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, sw_desc->async_tx.flags = flags; grp_start = sw_desc->group_head; mv_desc_init(grp_start, flags); - /* the byte count field is the same as in memcpy desc*/ mv_desc_set_byte_count(grp_start, len); mv_desc_set_dest_addr(sw_desc->group_head, dest); sw_desc->unmap_src_cnt = src_cnt; @@ -651,6 +587,17 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, return sw_desc ? &sw_desc->async_tx : NULL; } +static struct dma_async_tx_descriptor * +mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + size_t len, unsigned long flags) +{ + /* + * A MEMCPY operation is identical to an XOR operation with only + * a single source address. + */ + return mv_xor_prep_dma_xor(chan, dest, &src, 1, len, flags); +} + static void mv_xor_free_chan_resources(struct dma_chan *chan) { struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan); @@ -1071,7 +1018,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, mv_chan_unmask_interrupts(mv_chan); - mv_set_mode(mv_chan, DMA_MEMCPY); + mv_set_mode(mv_chan, DMA_XOR); spin_lock_init(&mv_chan->lock); INIT_LIST_HEAD(&mv_chan->chain);