From patchwork Thu Jan 2 15:09:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell King X-Patchwork-Id: 3425661 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 045CB9F2E9 for ; Thu, 2 Jan 2014 15:16:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C2C9E2015A for ; Thu, 2 Jan 2014 15:16:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 72A3C20145 for ; Thu, 2 Jan 2014 15:16:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751443AbaABPPn (ORCPT ); Thu, 2 Jan 2014 10:15:43 -0500 Received: from gw-1.arm.linux.org.uk ([78.32.30.217]:54168 "EHLO pandora.arm.linux.org.uk" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752142AbaABPPQ (ORCPT ); Thu, 2 Jan 2014 10:15:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=arm.linux.org.uk; s=pandora; h=Date:Sender:Message-Id:Subject:Cc:To:From:References:In-Reply-To; bh=0MKpbFOHcDZFv8Q6VOE4VaqZPqAhqXsemtKS41AAU0g=; b=lFRYKeAisl0IO1Em+LLwLInl1U++r46CWXbUh5a5K8znHDmcFCkNNprWzkAuiRzGXZ15bOVM10i8vL9PMdAxYRkZlHtaPg4B9ufjBhr18ZJXHp7GQCYd3HQRCa3jBuPgjAajd+2I3jVVTLNAiUpogE8DlTRSdBRR4UcbRWSM0R4=; Received: from [2001:4d48:ad52:3201:222:68ff:fe15:37dd] (port=56285 helo=rmk-PC.arm.linux.org.uk) by pandora.arm.linux.org.uk with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.76) (envelope-from ) id 1Vyjtg-0003aa-BK; Thu, 02 Jan 2014 15:09:20 +0000 Received: from rmk by rmk-PC.arm.linux.org.uk with local (Exim 4.76) (envelope-from ) id 1Vyjtf-0005E5-Vw; Thu, 02 Jan 2014 15:09:20 +0000 In-Reply-To: <20140102150836.GA3826@n2100.arm.linux.org.uk> References: <20140102150836.GA3826@n2100.arm.linux.org.uk> From: Russell King To: dmaengine@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-omap@vger.kernel.org Cc: Vinod Koul , Dan Williams Subject: [PATCH RFC 03/26] dmaengine: omap-dma: program hardware directly Message-Id: Date: Thu, 02 Jan 2014 15:09:19 +0000 Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,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 Program the transfer parameters directly into the hardware, rather than using the functions in arch/arm/plat-omap/dma.c. Signed-off-by: Russell King --- drivers/dma/omap-dma.c | 144 ++++++++++++++++++++++++++++++++++++++++----- include/linux/omap-dma.h | 6 +- 2 files changed, 132 insertions(+), 18 deletions(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 3c1bb34aad0a..dd233ca2cf5a 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -99,16 +99,96 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d, unsigned idx) { struct omap_sg *sg = d->sg + idx; + uint32_t val; + + if (d->dir == DMA_DEV_TO_MEM) { + if (dma_omap1()) { + val = c->plat->dma_read(CSDP, c->dma_ch); + val &= ~(0x1f << 9); + val |= OMAP_DMA_PORT_EMIFF << 9; + c->plat->dma_write(val, CSDP, c->dma_ch); + } - if (d->dir == DMA_DEV_TO_MEM) - omap_set_dma_dest_params(c->dma_ch, OMAP_DMA_PORT_EMIFF, - OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0); - else - omap_set_dma_src_params(c->dma_ch, OMAP_DMA_PORT_EMIFF, - OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0); + val = c->plat->dma_read(CCR, c->dma_ch); + val &= ~(0x03 << 14); + val |= OMAP_DMA_AMODE_POST_INC << 14; + c->plat->dma_write(val, CCR, c->dma_ch); + + c->plat->dma_write(sg->addr, CDSA, c->dma_ch); + c->plat->dma_write(0, CDEI, c->dma_ch); + c->plat->dma_write(0, CDFI, c->dma_ch); + } else { + if (dma_omap1()) { + val = c->plat->dma_read(CSDP, c->dma_ch); + val &= ~(0x1f << 2); + val |= OMAP_DMA_PORT_EMIFF << 2; + c->plat->dma_write(val, CSDP, c->dma_ch); + } + + val = c->plat->dma_read(CCR, c->dma_ch); + val &= ~(0x03 << 12); + val |= OMAP_DMA_AMODE_POST_INC << 12; + c->plat->dma_write(val, CCR, c->dma_ch); + + c->plat->dma_write(sg->addr, CSSA, c->dma_ch); + c->plat->dma_write(0, CSEI, c->dma_ch); + c->plat->dma_write(0, CSFI, c->dma_ch); + } + + val = c->plat->dma_read(CSDP, c->dma_ch); + val &= ~0x03; + val |= d->es; + c->plat->dma_write(val, CSDP, c->dma_ch); + + if (dma_omap1()) { + val = c->plat->dma_read(CCR, c->dma_ch); + val &= ~(1 << 5); + if (d->sync_mode == OMAP_DMA_SYNC_FRAME) + val |= 1 << 5; + c->plat->dma_write(val, CCR, c->dma_ch); + + val = c->plat->dma_read(CCR2, c->dma_ch); + val &= ~(1 << 2); + if (d->sync_mode == OMAP_DMA_SYNC_BLOCK) + val |= 1 << 2; + c->plat->dma_write(val, CCR2, c->dma_ch); + } + + if (dma_omap2plus() && c->dma_sig) { + val = c->plat->dma_read(CCR, c->dma_ch); + + /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */ + val &= ~((1 << 23) | (3 << 19) | 0x1f); + val |= (c->dma_sig & ~0x1f) << 14; + val |= c->dma_sig & 0x1f; + + if (d->sync_mode & OMAP_DMA_SYNC_FRAME) + val |= 1 << 5; + else + val &= ~(1 << 5); - omap_set_dma_transfer_params(c->dma_ch, d->es, sg->en, sg->fn, - d->sync_mode, c->dma_sig, d->sync_type); + if (d->sync_mode & OMAP_DMA_SYNC_BLOCK) + val |= 1 << 18; + else + val &= ~(1 << 18); + + switch (d->sync_type) { + case OMAP_DMA_DST_SYNC_PREFETCH: + val &= ~(1 << 24); /* dest synch */ + val |= 1 << 23; /* Prefetch */ + break; + case 0: + val &= ~(1 << 24); /* dest synch */ + break; + default: + val |= 1 << 24; /* source synch */ + break; + } + c->plat->dma_write(val, CCR, c->dma_ch); + } + + c->plat->dma_write(sg->en, CEN, c->dma_ch); + c->plat->dma_write(sg->fn, CFN, c->dma_ch); omap_start_dma(c->dma_ch); } @@ -117,6 +197,7 @@ static void omap_dma_start_desc(struct omap_chan *c) { struct virt_dma_desc *vd = vchan_next_desc(&c->vc); struct omap_desc *d; + uint32_t val; if (!vd) { c->desc = NULL; @@ -128,12 +209,39 @@ static void omap_dma_start_desc(struct omap_chan *c) c->desc = d = to_omap_dma_desc(&vd->tx); c->sgidx = 0; - if (d->dir == DMA_DEV_TO_MEM) - omap_set_dma_src_params(c->dma_ch, d->periph_port, - OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi); - else - omap_set_dma_dest_params(c->dma_ch, d->periph_port, - OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi); + if (d->dir == DMA_DEV_TO_MEM) { + if (dma_omap1()) { + val = c->plat->dma_read(CSDP, c->dma_ch); + val &= ~(0x1f << 2); + val |= d->periph_port << 2; + c->plat->dma_write(val, CSDP, c->dma_ch); + } + + val = c->plat->dma_read(CCR, c->dma_ch); + val &= ~(0x03 << 12); + val |= OMAP_DMA_AMODE_CONSTANT << 12; + c->plat->dma_write(val, CCR, c->dma_ch); + + c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch); + c->plat->dma_write(0, CSEI, c->dma_ch); + c->plat->dma_write(d->fi, CSFI, c->dma_ch); + } else { + if (dma_omap1()) { + val = c->plat->dma_read(CSDP, c->dma_ch); + val &= ~(0x1f << 9); + val |= d->periph_port << 9; + c->plat->dma_write(val, CSDP, c->dma_ch); + } + + val = c->plat->dma_read(CCR, c->dma_ch); + val &= ~(0x03 << 14); + val |= OMAP_DMA_AMODE_CONSTANT << 14; + c->plat->dma_write(val, CCR, c->dma_ch); + + c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch); + c->plat->dma_write(0, CDEI, c->dma_ch); + c->plat->dma_write(d->fi, CDFI, c->dma_ch); + } omap_dma_start_sg(c, d, 0); } @@ -452,8 +560,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic( } if (dma_omap2plus()) { - omap_set_dma_src_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); - omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); + uint32_t val; + + val = c->plat->dma_read(CSDP, c->dma_ch); + val |= 0x03 << 7; /* src burst mode 16 */ + val |= 0x03 << 14; /* dst burst mode 16 */ + c->plat->dma_write(val, CSDP, c->dma_ch); } return vchan_tx_prep(&c->vc, &d->vd, flags); diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h index 14742fc2aefe..d631658e2237 100644 --- a/include/linux/omap-dma.h +++ b/include/linux/omap-dma.h @@ -289,8 +289,10 @@ struct omap_system_dma_plat_info { #define dma_omap2plus() 0 #endif #define dma_omap1() (!dma_omap2plus()) -#define dma_omap15xx() ((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE))) -#define dma_omap16xx() ((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE))) +#define __dma_omap15xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_1510_MODE) +#define __dma_omap16xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_16XX_MODE) +#define dma_omap15xx() __dma_omap15xx(d) +#define dma_omap16xx() __dma_omap16xx(d) extern struct omap_system_dma_plat_info *omap_get_plat_info(void);