All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Ujfalusi <peter.ujfalusi@ti.com>
To: Vinod Koul <vkoul@kernel.org>
Cc: <robh+dt@kernel.org>, <nm@ti.com>, <ssantosh@kernel.org>,
	<dan.j.williams@intel.com>, <dmaengine@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<grygorii.strashko@ti.com>, <lokeshvutla@ti.com>,
	<t-kristo@ti.com>, <tony@atomide.com>, <j-keerthy@ti.com>,
	<vigneshr@ti.com>
Subject: Re: [PATCH v7 09/12] dmaengine: ti: New driver for K3 UDMA
Date: Mon, 23 Dec 2019 10:59:06 +0200	[thread overview]
Message-ID: <ea473fed-276f-6b71-070b-02ab1f51ed89@ti.com> (raw)
In-Reply-To: <20191223073425.GV2536@vkoul-mobl>



On 23/12/2019 9.34, Vinod Koul wrote:
> On 09-12-19, 11:43, Peter Ujfalusi wrote:
> 
>> +#include <linux/kernel.h>
>> +#include <linux/dmaengine.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/dmapool.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/list.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/of.h>
>> +#include <linux/of_dma.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_irq.h>
> 
> to many of headers, do we need all!

I'll try to cut them back.

>> +static char *udma_get_dir_text(enum dma_transfer_direction dir)
>> +{
>> +	switch (dir) {
>> +	case DMA_DEV_TO_MEM:
>> +		return "DEV_TO_MEM";
>> +	case DMA_MEM_TO_DEV:
>> +		return "MEM_TO_DEV";
>> +	case DMA_MEM_TO_MEM:
>> +		return "MEM_TO_MEM";
>> +	case DMA_DEV_TO_DEV:
>> +		return "DEV_TO_DEV";
>> +	default:
>> +		break;
>> +	}
>> +
>> +	return "invalid";
>> +}
> 
> this seems generic which other ppl may need, can we move it to core.

dmaengine_get_direction_text() to include/linux/dmaengine.h
This way client drivers can use it if they need it?

>> +static void udma_reset_uchan(struct udma_chan *uc)
>> +{
>> +	uc->state = UDMA_CHAN_IS_IDLE;
>> +	uc->remote_thread_id = -1;
>> +	uc->dir = DMA_MEM_TO_MEM;
>> +	uc->pkt_mode = false;
>> +	uc->ep_type = PSIL_EP_NATIVE;
>> +	uc->enable_acc32 = 0;
>> +	uc->enable_burst = 0;
>> +	uc->channel_tpl = 0;
>> +	uc->psd_size = 0;
>> +	uc->metadata_size = 0;
>> +	uc->hdesc_size = 0;
>> +	uc->notdpkt = 0;
> 
> rather than do setting zero, why note memset and then set the nonzero
> members only?

I have lots of other things in udma_chan which can not be memset, vchan
struct, tasklet, name (for irq), etc.

to use memset, I think I could move parameters under a new struct
(udma_chan_params) keeping only the state in udma_chan.


>> +static void udma_reset_counters(struct udma_chan *uc)
>> +{
>> +	u32 val;
>> +
>> +	if (uc->tchan) {
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_BCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_BCNT_REG, val);
> 
> so you read back from UDMA_TCHAN_RT_BCNT_REG and write same value to
> it??

Yes, that's correct. This is how we can reset it. The counter is
decremented with the value you have written to the register.

>> +
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG, val);
>> +
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PCNT_REG, val);
>> +
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG, val);
>> +	}
>> +
>> +	if (uc->rchan) {
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_BCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_BCNT_REG, val);
>> +
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG, val);
>> +
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PCNT_REG, val);
>> +
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG, val);
> 
> True for all of these, what am I missing :)

Decrement on write.

> 
>> +static int udma_start(struct udma_chan *uc)
>> +{
>> +	struct virt_dma_desc *vd = vchan_next_desc(&uc->vc);
>> +
>> +	if (!vd) {
>> +		uc->desc = NULL;
>> +		return -ENOENT;
>> +	}
>> +
>> +	list_del(&vd->node);
>> +
>> +	uc->desc = to_udma_desc(&vd->tx);
>> +
>> +	/* Channel is already running and does not need reconfiguration */
>> +	if (udma_is_chan_running(uc) && !udma_chan_needs_reconfiguration(uc)) {
>> +		udma_start_desc(uc);
>> +		goto out;
> 
> How about the case where settings are different than the current one?

udma_chan_needs_reconfiguration() is checking that. I only need to
reconfigure UDMAP/PDMA if the settings have changed.

>> +static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc,
>> +					    size_t tr_size, int tr_count,
>> +					    enum dma_transfer_direction dir)
>> +{
>> +	struct udma_hwdesc *hwdesc;
>> +	struct cppi5_desc_hdr_t *tr_desc;
>> +	struct udma_desc *d;
>> +	u32 reload_count = 0;
>> +	u32 ring_id;
>> +
>> +	switch (tr_size) {
>> +	case 16:
>> +	case 32:
>> +	case 64:
>> +	case 128:
>> +		break;
>> +	default:
>> +		dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size);
>> +		return NULL;
>> +	}
>> +
>> +	/* We have only one descriptor containing multiple TRs */
>> +	d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_ATOMIC);
> 
> this is invoked from prep_ so should use GFP_NOWAIT, we dont use
> GFP_ATOMIC :)

Ok. btw: EDMA and sDMA driver is using GFP_ATOMIC :o

> 
>> +static struct udma_desc *
>> +udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl,
>> +		      unsigned int sglen, enum dma_transfer_direction dir,
>> +		      unsigned long tx_flags, void *context)
>> +{
>> +	enum dma_slave_buswidth dev_width;
>> +	struct scatterlist *sgent;
>> +	struct udma_desc *d;
>> +	size_t tr_size;
>> +	struct cppi5_tr_type1_t *tr_req = NULL;
>> +	unsigned int i;
>> +	u32 burst;
>> +
>> +	if (dir == DMA_DEV_TO_MEM) {
>> +		dev_width = uc->cfg.src_addr_width;
>> +		burst = uc->cfg.src_maxburst;
>> +	} else if (dir == DMA_MEM_TO_DEV) {
>> +		dev_width = uc->cfg.dst_addr_width;
>> +		burst = uc->cfg.dst_maxburst;
>> +	} else {
>> +		dev_err(uc->ud->dev, "%s: bad direction?\n", __func__);
>> +		return NULL;
>> +	}
>> +
>> +	if (!burst)
>> +		burst = 1;
>> +
>> +	/* Now allocate and setup the descriptor. */
>> +	tr_size = sizeof(struct cppi5_tr_type1_t);
>> +	d = udma_alloc_tr_desc(uc, tr_size, sglen, dir);
>> +	if (!d)
>> +		return NULL;
>> +
>> +	d->sglen = sglen;
>> +
>> +	tr_req = (struct cppi5_tr_type1_t *)d->hwdesc[0].tr_req_base;
> 
> cast away from void *?

True, it is not needed.

>> +static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
>> +				   enum dma_slave_buswidth dev_width,
>> +				   u16 elcnt)
>> +{
>> +	if (uc->ep_type != PSIL_EP_PDMA_XY)
>> +		return 0;
>> +
>> +	/* Bus width translates to the element size (ES) */
>> +	switch (dev_width) {
>> +	case DMA_SLAVE_BUSWIDTH_1_BYTE:
>> +		d->static_tr.elsize = 0;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_2_BYTES:
>> +		d->static_tr.elsize = 1;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_3_BYTES:
>> +		d->static_tr.elsize = 2;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_4_BYTES:
>> +		d->static_tr.elsize = 3;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_8_BYTES:
>> +		d->static_tr.elsize = 4;
> 
> seems like ffs(dev_width) to me?

Not really:
ffs(DMA_SLAVE_BUSWIDTH_1_BYTE) = 1
ffs(DMA_SLAVE_BUSWIDTH_2_BYTES) = 2
ffs(DMA_SLAVE_BUSWIDTH_3_BYTES) = 1
ffs(DMA_SLAVE_BUSWIDTH_4_BYTES) = 3
ffs(DMA_SLAVE_BUSWIDTH_8_BYTES) = 4

> 
>> +static struct udma_desc *
>> +udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl,
>> +		       unsigned int sglen, enum dma_transfer_direction dir,
>> +		       unsigned long tx_flags, void *context)
>> +{
>> +	struct scatterlist *sgent;
>> +	struct cppi5_host_desc_t *h_desc = NULL;
>> +	struct udma_desc *d;
>> +	u32 ring_id;
>> +	unsigned int i;
>> +
>> +	d = kzalloc(sizeof(*d) + sglen * sizeof(d->hwdesc[0]), GFP_ATOMIC);
> 
> GFP_NOWAIT here and few other places

Yes, I have fixed them up by this time.

> 
>> +static struct udma_desc *
>> +udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr,
>> +			 size_t buf_len, size_t period_len,
>> +			 enum dma_transfer_direction dir, unsigned long flags)
>> +{
>> +	struct udma_desc *d;
>> +	u32 ring_id;
>> +	int i;
>> +	int periods = buf_len / period_len;
>> +
>> +	if (periods > (K3_UDMA_DEFAULT_RING_SIZE - 1))
>> +		return NULL;
>> +
>> +	if (period_len > 0x3FFFFF)
> 
> Magic?

I'll add a define to cppi5. It is the packet length limit.

> 
>> +static enum dma_status udma_tx_status(struct dma_chan *chan,
>> +				      dma_cookie_t cookie,
>> +				      struct dma_tx_state *txstate)
>> +{
>> +	struct udma_chan *uc = to_udma_chan(chan);
>> +	enum dma_status ret;
>> +	unsigned long flags;
>> +
>> +	spin_lock_irqsave(&uc->vc.lock, flags);
>> +
>> +	ret = dma_cookie_status(chan, cookie, txstate);
>> +
>> +	if (!udma_is_chan_running(uc))
>> +		ret = DMA_COMPLETE;
> 
> Even for paused, not started channel? Not sure what will be return on those cases

Hrm, if the channel is not started yet, then I think it should be still
DMA_IN_PROGRESS, right?
The udma_is_chan_running() can be dropped from here.
I did missed the DMA_PAUSED state.

-	if (!udma_is_chan_running(uc))
-		ret = DMA_COMPLETE;
+	if (ret == DMA_IN_PROGRESS && udma_is_chan_paused(uc))
+		ret = DMA_PAUSED;


- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

WARNING: multiple messages have this Message-ID (diff)
From: Peter Ujfalusi <peter.ujfalusi@ti.com>
To: Vinod Koul <vkoul@kernel.org>
Cc: nm@ti.com, devicetree@vger.kernel.org, grygorii.strashko@ti.com,
	vigneshr@ti.com, lokeshvutla@ti.com, j-keerthy@ti.com,
	linux-kernel@vger.kernel.org, t-kristo@ti.com, tony@atomide.com,
	robh+dt@kernel.org, ssantosh@kernel.org,
	dmaengine@vger.kernel.org, dan.j.williams@intel.com,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v7 09/12] dmaengine: ti: New driver for K3 UDMA
Date: Mon, 23 Dec 2019 10:59:06 +0200	[thread overview]
Message-ID: <ea473fed-276f-6b71-070b-02ab1f51ed89@ti.com> (raw)
In-Reply-To: <20191223073425.GV2536@vkoul-mobl>



On 23/12/2019 9.34, Vinod Koul wrote:
> On 09-12-19, 11:43, Peter Ujfalusi wrote:
> 
>> +#include <linux/kernel.h>
>> +#include <linux/dmaengine.h>
>> +#include <linux/dma-mapping.h>
>> +#include <linux/dmapool.h>
>> +#include <linux/err.h>
>> +#include <linux/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/list.h>
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/spinlock.h>
>> +#include <linux/of.h>
>> +#include <linux/of_dma.h>
>> +#include <linux/of_device.h>
>> +#include <linux/of_irq.h>
> 
> to many of headers, do we need all!

I'll try to cut them back.

>> +static char *udma_get_dir_text(enum dma_transfer_direction dir)
>> +{
>> +	switch (dir) {
>> +	case DMA_DEV_TO_MEM:
>> +		return "DEV_TO_MEM";
>> +	case DMA_MEM_TO_DEV:
>> +		return "MEM_TO_DEV";
>> +	case DMA_MEM_TO_MEM:
>> +		return "MEM_TO_MEM";
>> +	case DMA_DEV_TO_DEV:
>> +		return "DEV_TO_DEV";
>> +	default:
>> +		break;
>> +	}
>> +
>> +	return "invalid";
>> +}
> 
> this seems generic which other ppl may need, can we move it to core.

dmaengine_get_direction_text() to include/linux/dmaengine.h
This way client drivers can use it if they need it?

>> +static void udma_reset_uchan(struct udma_chan *uc)
>> +{
>> +	uc->state = UDMA_CHAN_IS_IDLE;
>> +	uc->remote_thread_id = -1;
>> +	uc->dir = DMA_MEM_TO_MEM;
>> +	uc->pkt_mode = false;
>> +	uc->ep_type = PSIL_EP_NATIVE;
>> +	uc->enable_acc32 = 0;
>> +	uc->enable_burst = 0;
>> +	uc->channel_tpl = 0;
>> +	uc->psd_size = 0;
>> +	uc->metadata_size = 0;
>> +	uc->hdesc_size = 0;
>> +	uc->notdpkt = 0;
> 
> rather than do setting zero, why note memset and then set the nonzero
> members only?

I have lots of other things in udma_chan which can not be memset, vchan
struct, tasklet, name (for irq), etc.

to use memset, I think I could move parameters under a new struct
(udma_chan_params) keeping only the state in udma_chan.


>> +static void udma_reset_counters(struct udma_chan *uc)
>> +{
>> +	u32 val;
>> +
>> +	if (uc->tchan) {
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_BCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_BCNT_REG, val);
> 
> so you read back from UDMA_TCHAN_RT_BCNT_REG and write same value to
> it??

Yes, that's correct. This is how we can reset it. The counter is
decremented with the value you have written to the register.

>> +
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_SBCNT_REG, val);
>> +
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PCNT_REG, val);
>> +
>> +		val = udma_tchanrt_read(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG);
>> +		udma_tchanrt_write(uc->tchan, UDMA_TCHAN_RT_PEER_BCNT_REG, val);
>> +	}
>> +
>> +	if (uc->rchan) {
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_BCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_BCNT_REG, val);
>> +
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_SBCNT_REG, val);
>> +
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PCNT_REG, val);
>> +
>> +		val = udma_rchanrt_read(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG);
>> +		udma_rchanrt_write(uc->rchan, UDMA_RCHAN_RT_PEER_BCNT_REG, val);
> 
> True for all of these, what am I missing :)

Decrement on write.

> 
>> +static int udma_start(struct udma_chan *uc)
>> +{
>> +	struct virt_dma_desc *vd = vchan_next_desc(&uc->vc);
>> +
>> +	if (!vd) {
>> +		uc->desc = NULL;
>> +		return -ENOENT;
>> +	}
>> +
>> +	list_del(&vd->node);
>> +
>> +	uc->desc = to_udma_desc(&vd->tx);
>> +
>> +	/* Channel is already running and does not need reconfiguration */
>> +	if (udma_is_chan_running(uc) && !udma_chan_needs_reconfiguration(uc)) {
>> +		udma_start_desc(uc);
>> +		goto out;
> 
> How about the case where settings are different than the current one?

udma_chan_needs_reconfiguration() is checking that. I only need to
reconfigure UDMAP/PDMA if the settings have changed.

>> +static struct udma_desc *udma_alloc_tr_desc(struct udma_chan *uc,
>> +					    size_t tr_size, int tr_count,
>> +					    enum dma_transfer_direction dir)
>> +{
>> +	struct udma_hwdesc *hwdesc;
>> +	struct cppi5_desc_hdr_t *tr_desc;
>> +	struct udma_desc *d;
>> +	u32 reload_count = 0;
>> +	u32 ring_id;
>> +
>> +	switch (tr_size) {
>> +	case 16:
>> +	case 32:
>> +	case 64:
>> +	case 128:
>> +		break;
>> +	default:
>> +		dev_err(uc->ud->dev, "Unsupported TR size of %zu\n", tr_size);
>> +		return NULL;
>> +	}
>> +
>> +	/* We have only one descriptor containing multiple TRs */
>> +	d = kzalloc(sizeof(*d) + sizeof(d->hwdesc[0]), GFP_ATOMIC);
> 
> this is invoked from prep_ so should use GFP_NOWAIT, we dont use
> GFP_ATOMIC :)

Ok. btw: EDMA and sDMA driver is using GFP_ATOMIC :o

> 
>> +static struct udma_desc *
>> +udma_prep_slave_sg_tr(struct udma_chan *uc, struct scatterlist *sgl,
>> +		      unsigned int sglen, enum dma_transfer_direction dir,
>> +		      unsigned long tx_flags, void *context)
>> +{
>> +	enum dma_slave_buswidth dev_width;
>> +	struct scatterlist *sgent;
>> +	struct udma_desc *d;
>> +	size_t tr_size;
>> +	struct cppi5_tr_type1_t *tr_req = NULL;
>> +	unsigned int i;
>> +	u32 burst;
>> +
>> +	if (dir == DMA_DEV_TO_MEM) {
>> +		dev_width = uc->cfg.src_addr_width;
>> +		burst = uc->cfg.src_maxburst;
>> +	} else if (dir == DMA_MEM_TO_DEV) {
>> +		dev_width = uc->cfg.dst_addr_width;
>> +		burst = uc->cfg.dst_maxburst;
>> +	} else {
>> +		dev_err(uc->ud->dev, "%s: bad direction?\n", __func__);
>> +		return NULL;
>> +	}
>> +
>> +	if (!burst)
>> +		burst = 1;
>> +
>> +	/* Now allocate and setup the descriptor. */
>> +	tr_size = sizeof(struct cppi5_tr_type1_t);
>> +	d = udma_alloc_tr_desc(uc, tr_size, sglen, dir);
>> +	if (!d)
>> +		return NULL;
>> +
>> +	d->sglen = sglen;
>> +
>> +	tr_req = (struct cppi5_tr_type1_t *)d->hwdesc[0].tr_req_base;
> 
> cast away from void *?

True, it is not needed.

>> +static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d,
>> +				   enum dma_slave_buswidth dev_width,
>> +				   u16 elcnt)
>> +{
>> +	if (uc->ep_type != PSIL_EP_PDMA_XY)
>> +		return 0;
>> +
>> +	/* Bus width translates to the element size (ES) */
>> +	switch (dev_width) {
>> +	case DMA_SLAVE_BUSWIDTH_1_BYTE:
>> +		d->static_tr.elsize = 0;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_2_BYTES:
>> +		d->static_tr.elsize = 1;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_3_BYTES:
>> +		d->static_tr.elsize = 2;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_4_BYTES:
>> +		d->static_tr.elsize = 3;
>> +		break;
>> +	case DMA_SLAVE_BUSWIDTH_8_BYTES:
>> +		d->static_tr.elsize = 4;
> 
> seems like ffs(dev_width) to me?

Not really:
ffs(DMA_SLAVE_BUSWIDTH_1_BYTE) = 1
ffs(DMA_SLAVE_BUSWIDTH_2_BYTES) = 2
ffs(DMA_SLAVE_BUSWIDTH_3_BYTES) = 1
ffs(DMA_SLAVE_BUSWIDTH_4_BYTES) = 3
ffs(DMA_SLAVE_BUSWIDTH_8_BYTES) = 4

> 
>> +static struct udma_desc *
>> +udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl,
>> +		       unsigned int sglen, enum dma_transfer_direction dir,
>> +		       unsigned long tx_flags, void *context)
>> +{
>> +	struct scatterlist *sgent;
>> +	struct cppi5_host_desc_t *h_desc = NULL;
>> +	struct udma_desc *d;
>> +	u32 ring_id;
>> +	unsigned int i;
>> +
>> +	d = kzalloc(sizeof(*d) + sglen * sizeof(d->hwdesc[0]), GFP_ATOMIC);
> 
> GFP_NOWAIT here and few other places

Yes, I have fixed them up by this time.

> 
>> +static struct udma_desc *
>> +udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr,
>> +			 size_t buf_len, size_t period_len,
>> +			 enum dma_transfer_direction dir, unsigned long flags)
>> +{
>> +	struct udma_desc *d;
>> +	u32 ring_id;
>> +	int i;
>> +	int periods = buf_len / period_len;
>> +
>> +	if (periods > (K3_UDMA_DEFAULT_RING_SIZE - 1))
>> +		return NULL;
>> +
>> +	if (period_len > 0x3FFFFF)
> 
> Magic?

I'll add a define to cppi5. It is the packet length limit.

> 
>> +static enum dma_status udma_tx_status(struct dma_chan *chan,
>> +				      dma_cookie_t cookie,
>> +				      struct dma_tx_state *txstate)
>> +{
>> +	struct udma_chan *uc = to_udma_chan(chan);
>> +	enum dma_status ret;
>> +	unsigned long flags;
>> +
>> +	spin_lock_irqsave(&uc->vc.lock, flags);
>> +
>> +	ret = dma_cookie_status(chan, cookie, txstate);
>> +
>> +	if (!udma_is_chan_running(uc))
>> +		ret = DMA_COMPLETE;
> 
> Even for paused, not started channel? Not sure what will be return on those cases

Hrm, if the channel is not started yet, then I think it should be still
DMA_IN_PROGRESS, right?
The udma_is_chan_running() can be dropped from here.
I did missed the DMA_PAUSED state.

-	if (!udma_is_chan_running(uc))
-		ret = DMA_COMPLETE;
+	if (ret == DMA_IN_PROGRESS && udma_is_chan_paused(uc))
+		ret = DMA_PAUSED;


- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-12-23  8:59 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-09  9:43 [PATCH v7 00/12] dmaengine/soc: Add Texas Instruments UDMA support Peter Ujfalusi
2019-12-09  9:43 ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 01/12] bindings: soc: ti: add documentation for k3 ringacc Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 02/12] soc: ti: k3: add navss ringacc driver Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 03/12] dmaengine: doc: Add sections for per descriptor metadata support Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-20  8:28   ` Vinod Koul
2019-12-20  8:28     ` Vinod Koul
2019-12-20  9:52     ` Peter Ujfalusi
2019-12-20  9:52       ` Peter Ujfalusi
2019-12-20 10:14       ` Vinod Koul
2019-12-20 10:14         ` Vinod Koul
2019-12-09  9:43 ` [PATCH v7 04/12] dmaengine: Add metadata_ops for dma_async_tx_descriptor Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-20  8:32   ` Vinod Koul
2019-12-20  8:32     ` Vinod Koul
2019-12-20  8:48     ` Peter Ujfalusi
2019-12-20  8:48       ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 05/12] dmaengine: Add support for reporting DMA cached data amount Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-20  8:37   ` Vinod Koul
2019-12-20  8:37     ` Vinod Koul
2019-12-20  8:49     ` Peter Ujfalusi
2019-12-20  8:49       ` Peter Ujfalusi
2019-12-20  9:57       ` Vinod Koul
2019-12-20  9:57         ` Vinod Koul
2019-12-20 10:13         ` Peter Ujfalusi
2019-12-20 10:13           ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 06/12] dmaengine: ti: Add cppi5 header for K3 NAVSS/UDMA Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-20  9:54   ` Vinod Koul
2019-12-20  9:54     ` Vinod Koul
2019-12-20 10:42     ` Peter Ujfalusi
2019-12-20 10:42       ` Peter Ujfalusi
2019-12-23  7:11       ` Peter Ujfalusi
2019-12-23  7:11         ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 07/12] dmaengine: ti: k3 PSI-L remote endpoint configuration Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 08/12] dt-bindings: dma: ti: Add document for K3 UDMA Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-23  6:53   ` Vinod Koul
2019-12-23  6:53     ` Vinod Koul
2019-12-09  9:43 ` [PATCH v7 09/12] dmaengine: ti: New driver " Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-23  7:34   ` Vinod Koul
2019-12-23  7:34     ` Vinod Koul
2019-12-23  8:59     ` Peter Ujfalusi [this message]
2019-12-23  8:59       ` Peter Ujfalusi
2019-12-23 11:26       ` Vinod Koul
2019-12-23 11:26         ` Vinod Koul
2019-12-09  9:43 ` [PATCH v7 10/12] dmaengine: ti: k3-udma: Add glue layer for non DMAengine users Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-09  9:43 ` [PATCH v7 11/12] firmware: ti_sci: rm: Add support for tx_tdtype parameter for tx channel Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-11 10:24   ` Tero Kristo
2019-12-11 10:24     ` Tero Kristo
2019-12-09  9:43 ` [PATCH v7 12/12] dmaengine: ti: k3-udma: Wait for peer teardown completion if supported Peter Ujfalusi
2019-12-09  9:43   ` Peter Ujfalusi
2019-12-11 10:43 ` [PATCH v7 00/12] dmaengine/soc: Add Texas Instruments UDMA support Keerthy
2019-12-11 10:43   ` Keerthy
2019-12-12  8:46 ` Peter Ujfalusi
2019-12-12  8:46   ` Peter Ujfalusi
2019-12-12 10:55   ` Tero Kristo
2019-12-12 10:55     ` Tero Kristo
2019-12-12 10:57     ` Tero Kristo
2019-12-12 10:57       ` Tero Kristo
2019-12-16 10:05   ` Peter Ujfalusi
2019-12-16 10:05     ` Peter Ujfalusi
2019-12-12 18:01 ` Grygorii Strashko
2019-12-12 18:01   ` Grygorii Strashko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ea473fed-276f-6b71-070b-02ab1f51ed89@ti.com \
    --to=peter.ujfalusi@ti.com \
    --cc=dan.j.williams@intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=grygorii.strashko@ti.com \
    --cc=j-keerthy@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lokeshvutla@ti.com \
    --cc=nm@ti.com \
    --cc=robh+dt@kernel.org \
    --cc=ssantosh@kernel.org \
    --cc=t-kristo@ti.com \
    --cc=tony@atomide.com \
    --cc=vigneshr@ti.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.