mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
PCI: tegra194: Ring doorbell If DMA is not running
Issue: During multi threaded testing, there are cases where EDMA HW enters stopped state even through there are pending descriptors to process. This happens even when doorbell is rung after updating descriptors and barriers places. Fix: After processing channel interrupt, ring doorbell, if there are pending descriptors and for that channel is not running. Bug 4111305 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2905177 Change-Id: I9d1bd391f690abc58cf262f62606c42504150b13 Signed-off-by: Nagarjuna Kristam <nkristam@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2910921 Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
37956be9b4
commit
55e4803b61
@@ -326,6 +326,24 @@ static irqreturn_t edma_irq(int irq, void *cookie)
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
||||
static void edma_check_and_ring_db(struct edma_prv *prv, u8 bit, u32 ctrl_off, u32 db_off)
|
||||
{
|
||||
u32 reg = dma_channel_rd(prv->edma_base, bit, ctrl_off);
|
||||
|
||||
#define CS_POS 5U
|
||||
#define CS_MASK (OSI_BIT(5) | OSI_BIT(6))
|
||||
#define CS_RUNNING 2U
|
||||
reg &= CS_MASK;
|
||||
reg >>= CS_POS;
|
||||
/*
|
||||
* There are pending descriptors to process, but
|
||||
* EDMA HW is not running. Ring the doorbell again
|
||||
* to ensure that descriptors are processed.
|
||||
*/
|
||||
if (reg != CS_RUNNING)
|
||||
dma_common_wr(prv->edma_base, bit, db_off);
|
||||
}
|
||||
|
||||
static irqreturn_t edma_irq_handler(int irq, void *cookie)
|
||||
{
|
||||
struct edma_prv *prv = (struct edma_prv *)cookie;
|
||||
@@ -336,6 +354,8 @@ static irqreturn_t edma_irq_handler(int irq, void *cookie)
|
||||
u32 int_status_off[2] = {DMA_WRITE_INT_STATUS_OFF, DMA_READ_INT_STATUS_OFF};
|
||||
u32 int_clear_off[2] = {DMA_WRITE_INT_CLEAR_OFF, DMA_READ_INT_CLEAR_OFF};
|
||||
u32 mode_cnt[2] = {DMA_WR_CHNL_NUM, DMA_RD_CHNL_NUM};
|
||||
u32 ctrl_off[2] = {DMA_CH_CONTROL1_OFF_WRCH, DMA_CH_CONTROL1_OFF_RDCH};
|
||||
u32 db_off[2] = {DMA_WRITE_DOORBELL_OFF, DMA_READ_DOORBELL_OFF};
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!(prv->ch_init & OSI_BIT(i)))
|
||||
@@ -383,6 +403,10 @@ static irqreturn_t edma_irq_handler(int irq, void *cookie)
|
||||
dma_common_wr(prv->edma_base, OSI_BIT(bit),
|
||||
int_clear_off[i]);
|
||||
process_ch_irq(prv, bit, ch, i);
|
||||
/* Check if there are pending descriptors */
|
||||
if (ch->w_idx != ch->r_idx)
|
||||
edma_check_and_ring_db(prv, (u8)(bit & 0xFF),
|
||||
ctrl_off[i], db_off[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user