All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miquel Raynal <miquel.raynal@bootlin.com>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Vinod Koul <vkoul@kernel.org>,
	dmaengine@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
	Magnus Damm <magnus.damm@gmail.com>,
	Gareth Williams <gareth.williams.jx@renesas.com>,
	Phil Edworthy <phil.edworthy@renesas.com>,
	Geert Uytterhoeven <geert@linux-m68k.org>,
	Stephen Boyd <sboyd@kernel.org>,
	Michael Turquette <mturquette@baylibre.com>,
	linux-clk@vger.kernel.org,
	Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
	Milan Stevanovic <milan.stevanovic@se.com>,
	Jimmy Lalande <jimmy.lalande@se.com>,
	Pascal Eberhard <pascal.eberhard@se.com>
Subject: Re: [PATCH v2 5/8] dma: dw: Avoid partial transfers
Date: Thu, 24 Feb 2022 17:30:09 +0100	[thread overview]
Message-ID: <20220224173009.0d37c12e@xps13> (raw)
In-Reply-To: <YhY4PqqOgYTLgpKr@smile.fi.intel.com>

Hi Andy, Phil,

andriy.shevchenko@linux.intel.com wrote on Wed, 23 Feb 2022 15:35:58
+0200:

> On Tue, Feb 22, 2022 at 11:34:34AM +0100, Miquel Raynal wrote:
> > From: Phil Edworthy <phil.edworthy@renesas.com>
> > 
> > Pausing a partial transfer only causes data to be written to memory that
> > is a multiple of the memory width setting.
> > 
> > However, when a DMA client driver finishes DMA early, e.g. due to UART
> > char timeout interrupt, all data read from the device must be written to
> > memory.
> > 
> > Therefore, allow the slave to limit the memory width to ensure all data
> > read from the device is written to memory when DMA is paused.  
> 
> (I have only 2.17d and 2.21a datasheets, so below based on the latter)
> 
> It seems you are referring to the chapter 7.7 "Disabling a Channel Prior
> to Transfer Completion" of the data sheet where it stays that it does not
> guarantee to have last burst to be completed in case of
> SRC_TR_WIDTH < DST_TR_WIDTH and the CH_SUSP bit is high, when the FIFO_EMPTY
> is asserted.
> 
> Okay, in iDMA 32-bit we have a specific bit (seems like a fix) that drains
> FIFO, but still it doesn't drain the FIFO fully (in case of misalignment)
> and the last piece of data (which is less than TR width) is lost when channel
> gets disabled.
> 
> Now, if we look at the implementation of the serial8250_rx_dma_flush() we
> may see that it does
>  1. Pause channel without draining FIFO
>  2. Moves data to TTY buffer
>  3. Terminates channel.
> 
> During termination it does pause channel again (with draining enabled),
> followed by disabling channel and resuming it again.
> 
> According to the 7.7 the resuming channel allows to finish the transfer
> normally.
> 
> It seems the logic in the ->terminate_all() is broken and we actually need
> to resume channel first (possibly conditionally, if it was suspended), then
> pause it and disable and resume again.
> 
> The problem with ->terminate_all() is that it has no knowledge if it has
> been called on paused channel (that's why it has to pause channel itself).
> The pause on termination is required due to some issues in early steppings
> of iDMA 32-bit hardware implementations.
> 
> If my theory is correct, the above change should fix the issues you see.

I don't have access to these datasheets so I will believe your words
and try to apply Andy's solution. I ended up with the following fix,
hopefully I got it right:

diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
index 48cdefe997f1..59822664d8ec 100644
--- a/drivers/dma/dw/core.c
+++ b/drivers/dma/dw/core.c
@@ -865,6 +865,10 @@ static int dwc_terminate_all(struct dma_chan *chan)
 
        clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
 
+       /* Ensure the last byte(s) are drained before disabling the channel */
+       if (test_bit(DW_DMA_IS_PAUSED, &dwc->flags))
+               dwc_chan_resume(dwc, true);
+
        dwc_chan_pause(dwc, true);
 
        dwc_chan_disable(dw, dwc);

Phil, I know it's been 3 years since you investigated this issue, but
do you still have access to the script reproducing the issue? Even
better, do you still have the hardware to test?

Thanks,
Miquèl

  reply	other threads:[~2022-02-24 16:30 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-22 10:34 [PATCH v2 0/8] RZN1 DMA support Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 1/8] dt-bindings: dma: Introduce RZN1 dmamux bindings Miquel Raynal
2022-02-23 11:27   ` Geert Uytterhoeven
2022-02-22 10:34 ` [PATCH v2 2/8] dt-bindings: dma: Introduce RZN1 DMA compatible Miquel Raynal
2022-02-23 12:21   ` Geert Uytterhoeven
2022-02-23 15:49     ` Miquel Raynal
2022-02-23 16:16       ` Geert Uytterhoeven
2022-02-23 17:10         ` Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 3/8] soc: renesas: rzn1-sysc: Export function to set dmamux Miquel Raynal
2022-02-23 12:28   ` Geert Uytterhoeven
2022-02-23 15:54     ` Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 4/8] dma: dmamux: Introduce RZN1 DMA router support Miquel Raynal
2022-02-22 20:27   ` kernel test robot
2022-02-23  8:26     ` Miquel Raynal
2022-02-23  8:26       ` Miquel Raynal
2022-02-23 10:31   ` Miquel Raynal
2022-02-23 12:46   ` Geert Uytterhoeven
2022-02-23 16:49     ` Miquel Raynal
2022-02-24  9:14       ` Geert Uytterhoeven
2022-02-24  9:27         ` Miquel Raynal
2022-02-24  9:52           ` Geert Uytterhoeven
2022-02-24 11:36             ` Miquel Raynal
2022-02-24 12:16               ` Geert Uytterhoeven
2022-02-24 15:56                 ` Miquel Raynal
2022-02-22 10:34 ` [PATCH v2 5/8] dma: dw: Avoid partial transfers Miquel Raynal
2022-02-23 13:35   ` Andy Shevchenko
2022-02-24 16:30     ` Miquel Raynal [this message]
2022-02-25 20:30       ` Andy Shevchenko
2022-02-22 10:34 ` [PATCH v2 6/8] dma: dw: Add RZN1 compatible Miquel Raynal
2022-02-23 12:50   ` Geert Uytterhoeven
2022-02-22 10:34 ` [PATCH v2 7/8] ARM: dts: r9a06g032: Add the two DMA nodes Miquel Raynal
2022-02-23 12:54   ` Geert Uytterhoeven
2022-02-23 17:14     ` Miquel Raynal
2022-02-24  9:17       ` Geert Uytterhoeven
2022-02-22 10:34 ` [PATCH v2 8/8] ARM: dts: r9a06g032: Describe the DMA router Miquel Raynal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220224173009.0d37c12e@xps13 \
    --to=miquel.raynal@bootlin.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dmaengine@vger.kernel.org \
    --cc=gareth.williams.jx@renesas.com \
    --cc=geert@linux-m68k.org \
    --cc=jimmy.lalande@se.com \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=magnus.damm@gmail.com \
    --cc=milan.stevanovic@se.com \
    --cc=mturquette@baylibre.com \
    --cc=pascal.eberhard@se.com \
    --cc=phil.edworthy@renesas.com \
    --cc=robh+dt@kernel.org \
    --cc=sboyd@kernel.org \
    --cc=thomas.petazzoni@bootlin.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.