diff options
Diffstat (limited to 'drivers/dma/xilinx/xilinx_dpdma.c')
| -rw-r--r-- | drivers/dma/xilinx/xilinx_dpdma.c | 31 | 
1 files changed, 19 insertions, 12 deletions
| diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c index 55df63dead8d..70b29bd079c9 100644 --- a/drivers/dma/xilinx/xilinx_dpdma.c +++ b/drivers/dma/xilinx/xilinx_dpdma.c @@ -839,6 +839,7 @@ static void xilinx_dpdma_chan_queue_transfer(struct xilinx_dpdma_chan *chan)  	struct xilinx_dpdma_tx_desc *desc;  	struct virt_dma_desc *vdesc;  	u32 reg, channels; +	bool first_frame;  	lockdep_assert_held(&chan->lock); @@ -852,14 +853,6 @@ static void xilinx_dpdma_chan_queue_transfer(struct xilinx_dpdma_chan *chan)  		chan->running = true;  	} -	if (chan->video_group) -		channels = xilinx_dpdma_chan_video_group_ready(chan); -	else -		channels = BIT(chan->id); - -	if (!channels) -		return; -  	vdesc = vchan_next_desc(&chan->vchan);  	if (!vdesc)  		return; @@ -884,13 +877,26 @@ static void xilinx_dpdma_chan_queue_transfer(struct xilinx_dpdma_chan *chan)  			    FIELD_PREP(XILINX_DPDMA_CH_DESC_START_ADDRE_MASK,  				       upper_32_bits(sw_desc->dma_addr))); -	if (chan->first_frame) +	first_frame = chan->first_frame; +	chan->first_frame = false; + +	if (chan->video_group) { +		channels = xilinx_dpdma_chan_video_group_ready(chan); +		/* +		 * Trigger the transfer only when all channels in the group are +		 * ready. +		 */ +		if (!channels) +			return; +	} else { +		channels = BIT(chan->id); +	} + +	if (first_frame)  		reg = XILINX_DPDMA_GBL_TRIG_MASK(channels);  	else  		reg = XILINX_DPDMA_GBL_RETRIG_MASK(channels); -	chan->first_frame = false; -  	dpdma_write(xdev->reg, XILINX_DPDMA_GBL, reg);  } @@ -1042,13 +1048,14 @@ static int xilinx_dpdma_chan_stop(struct xilinx_dpdma_chan *chan)   */  static void xilinx_dpdma_chan_done_irq(struct xilinx_dpdma_chan *chan)  { -	struct xilinx_dpdma_tx_desc *active = chan->desc.active; +	struct xilinx_dpdma_tx_desc *active;  	unsigned long flags;  	spin_lock_irqsave(&chan->lock, flags);  	xilinx_dpdma_debugfs_desc_done_irq(chan); +	active = chan->desc.active;  	if (active)  		vchan_cyclic_callback(&active->vdesc);  	else | 
