From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 83894C433FE for ; Mon, 18 Oct 2021 06:33:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 66F02610A6 for ; Mon, 18 Oct 2021 06:33:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230181AbhJRGgC (ORCPT ); Mon, 18 Oct 2021 02:36:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:38462 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhJRGf6 (ORCPT ); Mon, 18 Oct 2021 02:35:58 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id C7DC2610E8; Mon, 18 Oct 2021 06:33:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1634538827; bh=8Duvbt7Tr+2iGsTsmx8skOoyJai429Qy3uMCGXSBySA=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=e4FZ1PWQO/Uip/YT4S6mgAiC8jjEugYD0gkMGyxz5gPLfmy8aojycaQPpuQJbCVjQ 3hzirrqdt6pKz4WtdJOkRn8xFEfx2cn7kSpdWFpUJ3KVusBmKQwR0uXpoKbouE7S25 lzdReyNtBEoMjgTudnjeK7hE7lFQ1q84rtmB5W05uySFMWn6sKXDm0uxqm9xbNvDws fLf4guJxmEjyvXk3LogtJrnLRAzuLkoQ8WX2dI0hFB0n3KxKajZJ0DUEl2aofMG15C VeEf26DEHz/OaMw8rAYA01soKQylUZLJm5K7PfytpMClgd0vwCw847s4V6NFRhVGIl 7B6/1e9RqlvoQ== Date: Mon, 18 Oct 2021 12:03:42 +0530 From: Vinod Koul To: Paul Cercueil Cc: Rob Herring , list@opendingux.net, dmaengine@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org Subject: Re: [PATCH 5/5] dmaengine: jz4780: Support bidirectional I/O on one channel Message-ID: References: <20211011143652.51976-1-paul@crapouillou.net> <20211011143652.51976-6-paul@crapouillou.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20211011143652.51976-6-paul@crapouillou.net> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 11-10-21, 16:36, Paul Cercueil wrote: > For some devices with only half-duplex capabilities, it doesn't make > much sense to use one DMA channel per direction, as both channels will > never be active at the same time. > > Add support for bidirectional I/O on DMA channels. The client drivers > can then request a "tx-rx" DMA channel which will be used for both > directions. > > Signed-off-by: Paul Cercueil > --- > drivers/dma/dma-jz4780.c | 48 ++++++++++++++++++++++++++-------------- > 1 file changed, 32 insertions(+), 16 deletions(-) > > diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c > index 4d62e24ebff9..ee1d50792c32 100644 > --- a/drivers/dma/dma-jz4780.c > +++ b/drivers/dma/dma-jz4780.c > @@ -122,6 +122,7 @@ struct jz4780_dma_desc { > dma_addr_t desc_phys; > unsigned int count; > enum dma_transaction_type type; > + uint32_t transfer_type; why not u32? > uint32_t status; > }; > > @@ -130,7 +131,7 @@ struct jz4780_dma_chan { > unsigned int id; > struct dma_pool *desc_pool; > > - uint32_t transfer_type; > + uint32_t transfer_type_tx, transfer_type_rx; > uint32_t transfer_shift; > struct dma_slave_config config; > > @@ -157,7 +158,7 @@ struct jz4780_dma_dev { > }; > > struct jz4780_dma_filter_data { > - uint32_t transfer_type; > + uint32_t transfer_type_tx, transfer_type_rx; > int channel; > }; > > @@ -226,9 +227,10 @@ static inline void jz4780_dma_chan_disable(struct jz4780_dma_dev *jzdma, > jz4780_dma_ctrl_writel(jzdma, JZ_DMA_REG_DCKEC, BIT(chn)); > } > > -static struct jz4780_dma_desc *jz4780_dma_desc_alloc( > - struct jz4780_dma_chan *jzchan, unsigned int count, > - enum dma_transaction_type type) > +static struct jz4780_dma_desc * > +jz4780_dma_desc_alloc(struct jz4780_dma_chan *jzchan, unsigned int count, > + enum dma_transaction_type type, > + enum dma_transfer_direction direction) > { > struct jz4780_dma_desc *desc; > > @@ -248,6 +250,12 @@ static struct jz4780_dma_desc *jz4780_dma_desc_alloc( > > desc->count = count; > desc->type = type; > + > + if (direction == DMA_DEV_TO_MEM) > + desc->transfer_type = jzchan->transfer_type_rx; > + else > + desc->transfer_type = jzchan->transfer_type_tx; > + > return desc; > } > > @@ -361,7 +369,7 @@ static struct dma_async_tx_descriptor *jz4780_dma_prep_slave_sg( > unsigned int i; > int err; > > - desc = jz4780_dma_desc_alloc(jzchan, sg_len, DMA_SLAVE); > + desc = jz4780_dma_desc_alloc(jzchan, sg_len, DMA_SLAVE, direction); > if (!desc) > return NULL; > > @@ -410,7 +418,7 @@ static struct dma_async_tx_descriptor *jz4780_dma_prep_dma_cyclic( > > periods = buf_len / period_len; > > - desc = jz4780_dma_desc_alloc(jzchan, periods, DMA_CYCLIC); > + desc = jz4780_dma_desc_alloc(jzchan, periods, DMA_CYCLIC, direction); > if (!desc) > return NULL; > > @@ -455,14 +463,14 @@ static struct dma_async_tx_descriptor *jz4780_dma_prep_dma_memcpy( > struct jz4780_dma_desc *desc; > uint32_t tsz; > > - desc = jz4780_dma_desc_alloc(jzchan, 1, DMA_MEMCPY); > + desc = jz4780_dma_desc_alloc(jzchan, 1, DMA_MEMCPY, 0); > if (!desc) > return NULL; > > tsz = jz4780_dma_transfer_size(jzchan, dest | src | len, > &jzchan->transfer_shift); > > - jzchan->transfer_type = JZ_DMA_DRT_AUTO; > + desc->transfer_type = JZ_DMA_DRT_AUTO; > > desc->desc[0].dsa = src; > desc->desc[0].dta = dest; > @@ -528,7 +536,7 @@ static void jz4780_dma_begin(struct jz4780_dma_chan *jzchan) > > /* Set transfer type. */ > jz4780_dma_chn_writel(jzdma, jzchan->id, JZ_DMA_REG_DRT, > - jzchan->transfer_type); > + jzchan->desc->transfer_type); > > /* > * Set the transfer count. This is redundant for a descriptor-driven > @@ -788,7 +796,8 @@ static bool jz4780_dma_filter_fn(struct dma_chan *chan, void *param) > return false; > } > > - jzchan->transfer_type = data->transfer_type; > + jzchan->transfer_type_tx = data->transfer_type_tx; > + jzchan->transfer_type_rx = data->transfer_type_rx; > > return true; > } > @@ -800,11 +809,17 @@ static struct dma_chan *jz4780_of_dma_xlate(struct of_phandle_args *dma_spec, > dma_cap_mask_t mask = jzdma->dma_device.cap_mask; > struct jz4780_dma_filter_data data; > > - if (dma_spec->args_count != 2) > + if (dma_spec->args_count == 2) { > + data.transfer_type_tx = dma_spec->args[0]; > + data.transfer_type_rx = dma_spec->args[0]; > + data.channel = dma_spec->args[1]; > + } else if (dma_spec->args_count == 3) { > + data.transfer_type_tx = dma_spec->args[0]; > + data.transfer_type_rx = dma_spec->args[1]; aha so you have a different values for tx and rx, that seems okay. Maybe word a better in binding and also add examples in binding for this > + data.channel = dma_spec->args[2]; > + } else { > return NULL; > - > - data.transfer_type = dma_spec->args[0]; > - data.channel = dma_spec->args[1]; > + } > > if (data.channel > -1) { > if (data.channel >= jzdma->soc_data->nb_channels) { > @@ -822,7 +837,8 @@ static struct dma_chan *jz4780_of_dma_xlate(struct of_phandle_args *dma_spec, > return NULL; > } > > - jzdma->chan[data.channel].transfer_type = data.transfer_type; > + jzdma->chan[data.channel].transfer_type_tx = data.transfer_type_tx; > + jzdma->chan[data.channel].transfer_type_rx = data.transfer_type_rx; > > return dma_get_slave_channel( > &jzdma->chan[data.channel].vchan.chan); > -- > 2.33.0 -- ~Vinod