On Wed, Aug 07, 2024 at 10:49:42PM +0530, Mrinmay Sarkar wrote: > > On 8/7/2024 4:26 AM, Serge Semin wrote: > > On Mon, Aug 05, 2024 at 07:30:14PM +0530, Mrinmay Sarkar wrote: > > > On 8/2/2024 5:12 AM, Serge Semin wrote: > > > > On Tue, Jul 23, 2024 at 06:49:31PM +0530, Mrinmay Sarkar wrote: > > > > > The current logic is enabling both STOP_INT_MASK and ABORT_INT_MASK > > > > > bit. This is apparently masking those particular interrupts rather than > > > > > unmasking the same. If the interrupts are masked, they would never get > > > > > triggered. > > > > > > > > > > So fix the issue by unmasking the STOP and ABORT interrupts properly. > > > > > > > > > > Fixes: e74c39573d35 ("dmaengine: dw-edma: Add support for native HDMA") > > > > > cc: stable@xxxxxxxxxxxxxxx > > > > > Signed-off-by: Mrinmay Sarkar <quic_msarkar@xxxxxxxxxxx> > > > > > --- > > > > > drivers/dma/dw-edma/dw-hdma-v0-core.c | 9 +++++---- > > > > > 1 file changed, 5 insertions(+), 4 deletions(-) > > > > > > > > > > diff --git a/drivers/dma/dw-edma/dw-hdma-v0-core.c b/drivers/dma/dw-edma/dw-hdma-v0-core.c > > > > > index 10e8f07..fa89b3a 100644 > > > > > --- a/drivers/dma/dw-edma/dw-hdma-v0-core.c > > > > > +++ b/drivers/dma/dw-edma/dw-hdma-v0-core.c > > > > > @@ -247,10 +247,11 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) > > > > > if (first) { > > > > > /* Enable engine */ > > > > > SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0)); > > > > > - /* Interrupt enable&unmask - done, abort */ > > > > > - tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) | > > > > > - HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK | > > > > > - HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN; > > > > Just curious, if all the interrupts were actually masked, how has this > > > > been even working?.. In other words if it affected both local and > > > > remote interrupts, then the HDMA driver has never actually worked, > > > > right? > > > Agreed, it should not work as interrupts were masked. > > > > > > But as we are enabling LIE/RIE bits (LWIE/RWIE) that eventually enabling > > > watermark > > > interrupt in HDMA case and somehow on device I could see interrupt was > > > generating with watermark and stop bit set and it was working. > > > Since we were not clearing watermark interrupt, it was also causing storm of > > > interrupt. > > Is it possible that the HDMA_V0_STOP_INT_MASK and > > HDMA_V0_ABORT_INT_MASK masks affect the local IRQs only? If so than > > that shall explain why for instance Kory hasn't met the problem. > > > > Based on the "Interrupts and Error Handling" figures of the DW EDMA > > databook the DMA_READ_INT_MASK_OFF/DMA_WRITE_INT_MASK_OFF CSRs mask of > > the IRQ delivered via the edma_int[] wire. Meanwhile the IMWr TLPs > > generation depend on the RIE/LLRAIE flags state only. > Ideally HDMA_V0_STOP_INT_MASK and HDMA_V0_ABORT_INT_MASK masks affect > both local and remote IRQs. > > As per DW HDMA "Interrupts and Error Handling" figure > HDMA_INT_SETUP_OFF_[WR| > RD] mask of the IRQ delivered via the edma_int[] wire. So it means they indeed affect the Local IRQs only, since the edma_int[] wire is the line locally connected to the host IRQ controller. From that perspective the semantics is the same as of the DMA_READ_INT_MASK_OFF/DMA_WRITE_INT_MASK_OFF CSR masks. Thanks for clarification. > And IMWr TLPs generation depend on 3 flags i.e HDMA_INT_SETUP_OFF_[WR| > RD].RSIE flag for stop IMWr, RWIE flag for watermark IMWr and > HDMA_INT_SETUP_OFF_[WR|R > D].RAIE flag for abort IMWr generation. > > Thanks, > Mrinmay > > > > > + /* Interrupt unmask - STOP, ABORT */ > > > > > + tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) & > > > > > + ~HDMA_V0_STOP_INT_MASK & ~HDMA_V0_ABORT_INT_MASK; > > > > Please convert this to: > > > > + /* Interrupt unmask - stop, abort */ > > > > + tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup); > > > > + tmp &= ~(HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK); > > > > > > > > -Serge(y) > > > Sure. Will do I'll wait v3 to finish up the review. -Serge(y) > > Thanks. > > > > -Serge(y) > > > > > Thanks, > > > Mrinmay > > > > > > > > + /* Interrupt enable - STOP, ABORT */ > > > > > + tmp |= HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN; > > > > > if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL)) > > > > > tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN; > > > > > SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp); > > > > > -- > > > > > 2.7.4 > > > > >