From patchwork Mon Mar 7 09:59:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris BREZILLON X-Patchwork-Id: 8518381 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 00557C0554 for ; Mon, 7 Mar 2016 10:27:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0AB7820138 for ; Mon, 7 Mar 2016 10:27:58 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F1FE120117 for ; Mon, 7 Mar 2016 10:27:56 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1acsMb-0003vC-EJ; Mon, 07 Mar 2016 10:26:09 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1acsMX-0003ov-9W for linux-arm-kernel@lists.infradead.org; Mon, 07 Mar 2016 10:26:06 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id A827A21B9; Mon, 7 Mar 2016 11:25:43 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (AToulouse-657-1-1129-172.w92-156.abo.wanadoo.fr [92.156.51.172]) by mail.free-electrons.com (Postfix) with ESMTPSA id 812412862; Mon, 7 Mar 2016 10:59:33 +0100 (CET) From: Boris Brezillon To: Vinod Koul , Dan Williams , dmaengine@vger.kernel.org, Maxime Ripard , Chen-Yu Tsai , linux-sunxi@googlegroups.com, =?UTF-8?q?Emilio=20L=C3=B3pez?= Subject: [PATCH] dma: sun4i: expose block size and wait cycle configuration to DMA users Date: Mon, 7 Mar 2016 10:59:31 +0100 Message-Id: <1457344771-12946-1-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 2.1.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160307_022605_650382_32D57842 X-CRM114-Status: GOOD ( 20.83 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Some drivers might need to tweak the block size and wait cycles values to get better performances. Create and export the sun4i_dma_set_chan_config() to do that. Signed-off-by: Boris Brezillon --- drivers/dma/sun4i-dma.c | 44 ++++++++++++++++++++++++++++++------------- include/linux/dma/sun4i-dma.h | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 include/linux/dma/sun4i-dma.h diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c index 1661d518..e48f537 100644 --- a/drivers/dma/sun4i-dma.c +++ b/drivers/dma/sun4i-dma.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -138,6 +139,7 @@ struct sun4i_dma_pchan { struct sun4i_dma_vchan { struct virt_dma_chan vc; struct dma_slave_config cfg; + struct sun4i_dma_chan_config scfg; struct sun4i_dma_pchan *pchan; struct sun4i_dma_promise *processing; struct sun4i_dma_contract *contract; @@ -779,7 +781,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, u8 ram_type, io_mode, linear_mode; struct scatterlist *sg; dma_addr_t srcaddr, dstaddr; - u32 endpoints, para; + u32 endpoints; int i; if (!sgl) @@ -825,17 +827,6 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, dstaddr = sg_dma_address(sg); } - /* - * These are the magic DMA engine timings that keep SPI going. - * I haven't seen any interface on DMAEngine to configure - * timings, and so far they seem to work for everything we - * support, so I've kept them here. I don't know if other - * devices need different timings because, as usual, we only - * have the "para" bitfield meanings, but no comment on what - * the values should be when doing a certain operation :| - */ - para = SUN4I_DDMA_MAGIC_SPI_PARAMETERS; - /* And make a suitable promise */ if (vchan->is_dedicated) promise = generate_ddma_promise(chan, srcaddr, dstaddr, @@ -850,7 +841,7 @@ sun4i_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; /* TODO: should we free everything? */ promise->cfg |= endpoints; - promise->para = para; + promise->para = vchan->scfg.para; /* Then add it to the contract */ list_add_tail(&promise->list, &contract->demands); @@ -908,6 +899,21 @@ static int sun4i_dma_config(struct dma_chan *chan, return 0; } +int sun4i_dma_set_chan_config(struct dma_chan *dchan, + const struct sun4i_dma_chan_config *cfg) +{ + struct sun4i_dma_vchan *vchan = to_sun4i_dma_vchan(dchan); + + if (!vchan->is_dedicated) + return -ENOTSUPP; + + /* TODO: control cfg value */ + vchan->scfg = *cfg; + + return 0; +} +EXPORT_SYMBOL_GPL(sun4i_dma_set_chan_config); + static struct dma_chan *sun4i_dma_of_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { @@ -1206,6 +1212,18 @@ static int sun4i_dma_probe(struct platform_device *pdev) spin_lock_init(&vchan->vc.lock); vchan->vc.desc_free = sun4i_dma_free_contract; vchan_init(&vchan->vc, &priv->slave); + + /* + * These are the magic DMA engine timings that keep SPI going. + * I haven't seen any interface on DMAEngine to configure + * timings, and so far they seem to work for everything we + * support, so I've kept them here. I don't know if other + * devices need different timings because, as usual, we only + * have the "para" bitfield meanings, but no comment on what + * the values should be when doing a certain operation :| + */ + vchan->scfg.para = SUN4I_DDMA_MAGIC_SPI_PARAMETERS; + } ret = clk_prepare_enable(priv->clk); diff --git a/include/linux/dma/sun4i-dma.h b/include/linux/dma/sun4i-dma.h new file mode 100644 index 0000000..f643539 --- /dev/null +++ b/include/linux/dma/sun4i-dma.h @@ -0,0 +1,38 @@ +/* + * Sun4i DMA Engine drivers support header file + * + * Copyright (C) 2016 Free Electrons. All rights reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef _SUN4I_DMA_H +#define _SUN4I_DMA_H + +#include +#include + +/* Dedicated DMA parameter register layout */ +#define SUN4I_DDMA_PARA_DST_DATA_BLK_SIZE(n) (((n) - 1) << 24) +#define SUN4I_DDMA_PARA_DST_WAIT_CYCLES(n) (((n) - 1) << 16) +#define SUN4I_DDMA_PARA_SRC_DATA_BLK_SIZE(n) (((n) - 1) << 8) +#define SUN4I_DDMA_PARA_SRC_WAIT_CYCLES(n) (((n) - 1) << 0) + +/** + * struct sun4i_dma_chan_config - DMA channel config + * + * @para: contains information about block size and time before checking + * DRQ line. This is device specific and only applicable to dedicated + * DMA channels + */ +struct sun4i_dma_chan_config { + u32 para; +}; + +int sun4i_dma_set_chan_config(struct dma_chan *dchan, + const struct sun4i_dma_chan_config *cfg); + +#endif /* _SUN4I_DMA_H */