[Sound-open-firmware] [PATCH 23/25] dai: add R/W pointer check for dai copy

Jie, Yang yang.jie at intel.com
Thu Feb 9 03:30:25 CET 2017


> -----Original Message-----
> From: Liam Girdwood [mailto:liam.r.girdwood at linux.intel.com]
> Sent: Wednesday, February 8, 2017 8:14 PM
> To: Keyon Jie <yang.jie at linux.intel.com>
> Cc: sound-open-firmware at alsa-project.org; Jie, Yang <yang.jie at intel.com>;
> Ingalsuo, Seppo <seppo.ingalsuo at intel.com>
> Subject: Re: [Sound-open-firmware] [PATCH 23/25] dai: add R/W pointer check
> for dai copy
> 
> On Tue, 2017-02-07 at 22:03 +0800, Keyon Jie wrote:
> > We should only copy when there is data, after copied the last bytes or
> > period, we will stop the dai and ssp, and trigger the pipeline finish,
> > which will notify host side the last read pointer and let host side
> > send trigger stop ipc.
> >
> > Signed-off-by: Keyon Jie <yang.jie at linux.intel.com>
> > ---
> >  src/audio/dai.c | 44 +++++++++++++++++++++++++++++++++++++++-----
> >  1 file changed, 39 insertions(+), 5 deletions(-)
> >
> > diff --git a/src/audio/dai.c b/src/audio/dai.c index 3b2ea30..a9b46a5
> > 100644
> > --- a/src/audio/dai.c
> > +++ b/src/audio/dai.c
> > @@ -69,6 +69,7 @@ struct dai_data {
> >  	volatile uint64_t *dai_pos; /* host can read back this value without
> > IPC */  };
> >
> > +static int dai_cmd(struct comp_dev *dev, int cmd, void *data);
> >  /* this is called by DMA driver every time descriptor has completed
> > */  static void dai_dma_cb(void *data, uint32_t type, struct
> > dma_sg_elem *next)  { @@ -76,17 +77,22 @@ static void dai_dma_cb(void
> > *data, uint32_t type, struct dma_sg_elem *next)
> >  	struct dai_data *dd = comp_get_drvdata(dev);
> >  	struct period_desc *dma_period_desc;
> >  	struct comp_buffer *dma_buffer;
> > +	uint32_t copied_size;
> >
> >  	if (dd->direction == STREAM_DIRECTION_PLAYBACK) {
> >  		dma_buffer = list_first_item(&dev->bsource_list,
> >  			struct comp_buffer, sink_list);
> >
> >  		dma_period_desc = &dma_buffer->desc.sink_period;
> > -		dma_buffer->r_ptr += dma_period_desc->size;
> > +		copied_size = dd->last_bytes ? dd->last_bytes :
> dma_period_desc->size;
> > +		dma_buffer->r_ptr += copied_size;
> >
> >  		/* check for end of buffer */
> > -		if (dma_buffer->r_ptr >= dma_buffer->end_addr)
> > +		if (dma_buffer->r_ptr >= dma_buffer->end_addr) {
> >  			dma_buffer->r_ptr = dma_buffer->addr;
> > +			/* update host position(in bytes offset) for drivers */
> > +			dd->dai_pos_blks += dma_buffer->desc.size;
> > +		}
> >
> >  #if 0
> >  		// TODO: move this to new trace mechanism @@ -109,16
> +115,17 @@
> > static void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
> >  		dma_buffer->w_ptr += dma_period_desc->size;
> >
> >  		/* check for end of buffer */
> > -		if (dma_buffer->w_ptr >= dma_buffer->end_addr)
> > +		if (dma_buffer->w_ptr >= dma_buffer->end_addr) {
> >  			dma_buffer->w_ptr = dma_buffer->addr;
> > +			/* update host position(in bytes offset) for drivers */
> > +			dd->dai_pos_blks += dma_buffer->desc.size;
> > +		}
> >
> >  #if 0
> >  		// TODO: move this to new trace mechanism
> >  		trace_value((uint32_t)(dma_buffer->w_ptr - dma_buffer-
> >addr));
> > #endif
> >
> > -		/* update host position(in bytes offset) for drivers */
> > -		dd->dai_pos_blks += dma_period_desc->size;
> >  		if (dd->dai_pos)
> >  			*dd->dai_pos = dd->dai_pos_blks +
> >  				dma_buffer->w_ptr - dma_buffer->addr; @@ -
> 127,9 +134,36 @@ static
> > void dai_dma_cb(void *data, uint32_t type, struct dma_sg_elem *next)
> >  		comp_update_buffer_produce(dma_buffer);
> >  	}
> >
> > +	if (dd->direction == STREAM_DIRECTION_PLAYBACK &&
> > +				dma_buffer->avail < dma_period_desc->size) {
> > +		/* end of stream, finish */
> > +		if (dma_buffer->avail == 0) {
> > +			dai_cmd(dev, COMP_CMD_STOP, NULL);
> 
> newline

OK.

> 
> > +			/* stop dma immediatly */
> > +			next->size = 0xFFFFFFFF;
> 
> magic number

It is a little strange that this is rolled back to non-magic number version.
Will fix it.

Thanks,
~Keyon

> 
> > +			/* let any waiters know we have completed */
> > +			wait_completed(&dev->pipeline->complete);
> > +			return;
> > +		} else {
> > +			/* drain the last bytes */
> > +			next->src = (uint32_t)dma_buffer->r_ptr;
> > +			next->dest = dai_fifo(dd->ssp, dd->direction);
> > +			next->size = dma_buffer->avail;
> > +
> > +			dd->last_bytes = next->size;
> > +
> > +			goto next_copy;
> > +
> > +		}
> > +
> > +	}
> >  	/* notify pipeline that DAI needs it's buffer filled */
> >  //	if (dev->state == COMP_STATE_RUNNING)
> >  		pipeline_schedule_copy(dev->pipeline, dev);
> > +
> > +next_copy:
> > +
> > +	return;
> >  }
> >
> >  static struct comp_dev *dai_new_ssp(uint32_t type, uint32_t index,
> 



More information about the Sound-open-firmware mailing list