mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 20:10:23 +09:00
dmaengine: xilinx: dpdma: Fix descriptor issuing on video group
[ Upstream commit 1cbd446662 ]
When multiple channels are part of a video group, the transfer is
triggered only when all channels in the group are ready. The logic to do
so is incorrect, as it causes the descriptors for all channels but the
last one in a group to not being pushed to the hardware. Fix it.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://lore.kernel.org/r/20210307040629.29308-2-laurent.pinchart@ideasonboard.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
eb2c81ee76
commit
e8d9a93ec4
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user