Re: [PATCH v2 1/2] dmaengine: dw-edma: Fix unmasking STOP and ABORT interrupts for HDMA

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
> > > > > 




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux