From patchwork Mon Feb 10 15:56:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell King X-Patchwork-Id: 3619401 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 E3AE79F2D6 for ; Mon, 10 Feb 2014 15:56:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E641D201D3 for ; Mon, 10 Feb 2014 15:56:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EB2E5201DD for ; Mon, 10 Feb 2014 15:56:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752338AbaBJP4M (ORCPT ); Mon, 10 Feb 2014 10:56:12 -0500 Received: from gw-1.arm.linux.org.uk ([78.32.30.217]:59999 "EHLO pandora.arm.linux.org.uk" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752667AbaBJP4K (ORCPT ); Mon, 10 Feb 2014 10:56:10 -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=Zbd42F9iizNkcBkpm9lCmQPBMD5ieF4pQyV5jaU8M/g=; b=CF16y4MEJIz0EnX6PcxgIdLby9qDpirRyq+b3jh0tC0GtVIxkn23p0HVuf6HvAJVxyeYsjLXYoCd2iNxcGoVGfKYcEBqVq4u+3iQ43LiTLqKXw4goyKeX8DapTHpS20SnvZ31xQV42I/JYjCdxhFfRkxlwweA35swjSOAOQswuE=; Received: from e0022681537dd.dyn.arm.linux.org.uk ([fd8f:7570:feb6:1:222:68ff:fe15:37dd]:49371 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 1WCtDM-00052i-VY; Mon, 10 Feb 2014 15:56:09 +0000 Received: from rmk by rmk-PC.arm.linux.org.uk with local (Exim 4.76) (envelope-from ) id 1WCtDM-0006WE-JR; Mon, 10 Feb 2014 15:56:08 +0000 In-Reply-To: <20140210155531.GB26684@n2100.arm.linux.org.uk> References: <20140210155531.GB26684@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: Dan Williams , Vinod Koul Subject: [PATCH 03/26] dmaengine: omap-dma: program hardware directly Message-Id: Date: Mon, 10 Feb 2014 15:56:08 +0000 Sender: dmaengine-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dmaengine@vger.kernel.org X-Spam-Status: No, score=-7.4 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 | 142 +++++++++++++++++++++++++++++++++++++++++------ include/linux/omap-dma.h | 6 +- 2 files changed, 130 insertions(+), 18 deletions(-) diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 4ac26bf0ad30..47a3fa5bc38e 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -99,16 +99,94 @@ 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); + } else if (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); + + 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); + } - omap_set_dma_transfer_params(c->dma_ch, d->es, sg->en, sg->fn, - d->sync_mode, c->dma_sig, d->sync_type); + 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 +195,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 +207,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 +558,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);