Linux SPI subsystem development
 help / color / mirror / Atom feed
From: Serge Semin <fancer.lancer@gmail.com>
To: Damien Le Moal <Damien.LeMoal@wdc.com>
Cc: "linux-spi@vger.kernel.org" <linux-spi@vger.kernel.org>,
	"palmer@dabbelt.com" <palmer@dabbelt.com>,
	"linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>,
	"broonie@kernel.org" <broonie@kernel.org>,
	"seanga2@gmail.com" <seanga2@gmail.com>
Subject: Re: [PATCH 04/32] spi: dw: Introduce polling device tree property
Date: Sun, 15 Nov 2020 19:01:46 +0300	[thread overview]
Message-ID: <20201115160146.efxcdjhm7f2nmivo@mobilestation> (raw)
In-Reply-To: <58943f7988706497040cac6f6108336286e9d15f.camel@wdc.com>

On Fri, Nov 13, 2020 at 09:22:54AM +0000, Damien Le Moal wrote:
> On Mon, 2020-11-09 at 22:59 +0300, Serge Semin wrote:
> > On Sat, Nov 07, 2020 at 05:13:52PM +0900, Damien Le Moal wrote:
> > > With boards that have slow interrupts context switch, and a fast device
> > > connected to a spi master, e.g. an SD card through mmc-spi,
> > 
> > > using
> > > dw_spi_poll_transfer() intead of the regular interrupt based
> > > dw_spi_transfer_handler() function is more efficient and
> > 
> > I can believe in that. But the next part seems questionable:
> > 
> > > can avoid a lot
> > > of RX FIFO overflow errors while keeping the device SPI frequency
> > > reasonnably high (for speed).
> > 
> > No matter whether it's an IRQ-based or poll-based transfer, as long as a
> > client SPI-device is connected with a GPIO-based chip-select (or the
> > DW APB SSI-controller feature of the automatic chip-select toggling is
> > fixed), the Rx FIFO should never overrun. It's ensured by the transfer
> > algorithm design by calculating the rxtx_gap in the dw_writer()
> > method. If the error still happens then there must be some bug in
> > the code.
> > 
> > It's also strange to hear that the polling-based transfer helps
> > to avoid the Rx FIFO overflow errors, while the IRQ-based transfer
> > causes them. Both of those methods are based on the same dw_writer()
> > and dw_reader() methods. So basically they both should either work
> > well or cause the errors at same time.
> > 
> > So to speak could you more through debug your case?
> 
> I did. And I have much better results now. Let me explain:

> 1) The device tree was setting up the SPI controller using the controller
> internal chip select, not a GPIO-based chip select. Until now, I could never
> get the GPIO-based chip select to work. I finally found out why: I simply
> needed to add the "spi-cs-high" property to the mmc-slot node. With that, the
> CS gpio is correctly driven active-high instead of the default active-low and
> the SD card works.

Yeap, that's the main problem of the standard DW APB SSI controller
released by Synopsys. Currently SPI-flash'es are the only SPI
peripheral devices which are capable to work with native DW APB SSI
chip-selects. I've fixed that for flashes recently by atomizing the
SPI memory operations (executing them with the local IRQs disabled)
and performing them on the poll-based basis. Alas the normal
SPI-transfers still can't be properly executed with native
chip-selects.

> 2) With this change using the GPIO-based CS, the patch "spi: dw: Fix driving
> MOSI low while receiving" became completely unnecessary. The SD card works
> without it.

Hm, that's weird. MOSI level has nothing todo with the chip-selects.
Are you sure the original problem has been connected with the Tx lane
level? On the other hand are you sure the problem has gone away after
all?

Moreover I've just taken alook at the MMC SPI driver. Turns out it
has already been fixed to send ones to the MMC port when it's
required. So If you still experience the MOSI-level problem
then that fix might have been done incorrect at some extent...

> 
> Now for testing, I also removed this polling change. Results are these:
> 1) With the same SPI frequency as before (4MHz), I can run the SD card at about
> 300 KB/s (read) but I am still seeing some RX FIFO overflow errors. Not a lot,
> but enough to be annoying, especially on boot as the partition scan sometimes
> fails because of these errors. In most cases, the block layer retry of failed
> read/writes cover and no bad errors happen, but the RX FIFO overflow error
> messages still pop up.
> 2) Looking into the code further, I realized that RXFLTR is set to half the
> fifo size minus 1. That sound reasonable, but as that delays interrupt
> generation until the RX fifo is almost full, I decided to try a value of 0 to
> get the interrupt as soon as data is available rather than waiting for a chunk.
> With that, all RX FIFO overflow errors go away, and I could even double the SPI
> frequency to 8MHz, getting a solid 650KB/s from the SD card without any error
> at all.
> 

Please, see my last comment...

> My take:
> * This controller internal CS seems to be totally broken.

Native CS aren't broken, they just have been designed so it isn't that
easy to use them in the linux kernel. Linux kernel SPI-core expects
the chip-select being driven the way it needs at the certain moments,
while DW APB SSI toggles them automatically at the moment of the data
pushing/popping to/from the SPI bus. Some hardware vendors that bought
the DW APB SSI IP-core have fixed that by providing a way of direct
CS lane control (see spi-dw-mmio.c: Microsemi, Sparx5, Alpine
platforms).

> * This SoC has really slow interrupts, so generating these earlier rather than
> later gives time to the IRQ handler to kick in before the FIFO overflows.

I am pretty sure that's not the reason. See my next comment.

> 
> In the V2 series for SPI DW, I added a DW_SPI_CAP_RXFLTR_CLEAR capability flag
> to set RXFLTR to 0, always. That works well, but this is may be still similar
> to the "polling" hack in the sense that it is tuning for this SoC rather than a
> property of the controller. But I do not see any other simple way of removing
> these annoying RX FIFO overflow errors.

Alas no, RX-FIFO level value shouldn't affect the SPI-transfers
execution results. I'll try to explain it one more time. DW APB SSI
provides three modes of transfers (TMOD-es, see the chip manual for
details). One of them is TMOD=0x0 - Transmit and Receive. Simply
speaking the mode essence is if you push a byte of data to the Tx
FIFO you'll synchronously get a byte of data back in the Rx FIFO a bit
later from the internal shift register. The IRQ-based transfers have
been developed full based on that mode. So it's absolutely possible to
implement a stable algorithm, which would work without a risk of
getting the Rx FIFO overflow or the Tx FIFO overrun. Such algorithm
should just preserve a balance of sent data so the received data
wouldn't cause the Rx FIFO overrun. As you understand such algorithm
doesn't depend on the IRQes performance. No matter how slow the IRQs
handler is execute, as long as it's executed, the SPI transfers
procedure shall go on with no errors including the Rx FIFO overflows.
At least that's what the original DW APB SSI driver developer
implied when created the code and what I was trying to preserve in my
patches. If you still get the errors (you sure it's Rx FIFO overflows,
aren't you?), then something went wrong and either me or the original
author or someone else has broken the code.

What we currently need is to carefully analyze at what moment you get
the overflows, what really caused them and fix the problem in the
code. The capabilities flag isn't an option in this case. I've tried
to reproduce the errors by slowing the system down, executing the
SPI-transfers of various length, but with no lick. So it's only you
for now who observes and can try to debug the problem.

Anyway after we get to fix it, you'll be able to run the MMC port with
speed as fast as it's possible.

---
One more thing about MMC SPI. Please note, that using MMC SPI and
DMA-based DW APB SSI transfers might not work well. The thing is that
the DMA-part of the MMC SPI driver relies on the legacy
spi_message->is_dma_mapped interface. It performs some specific
DEV-to-MEM and MEM-to-DEV DMA-buffers splitting and synchronizations.
In its turn the DMA-part of the DW APB SSI driver uses the generic
SPI-core and the DMA-engine interface to execute the SPI-transfers.
Since the SPI-core performs the DMA buffers synchronizations
internally at the moment of the buffers mapping, in case if the DMA
accesses aren't coherent on your platform, the data buffers might get
synchronized/flushed with/by caches incorrectly corrupting a part of
actual data. At least that's what we observed in kernel 4.9... So for
now I'd suggest to use either the poll- or the IRQ-based DW APB SSI
transfers.

-Sergey

> 
> > On the other hand the errors (but not the Rx FIFO overflow) might be
> > caused by the DW APB SSI nasty feature of the native chip-select
> > automatic assertion/de-assertion. So if your MMC-spi port is handled
> > by the native DW APB SSI CS lane, then it won't work well for sure.
> > No matter whether you use the poll- or IRQ-based transfers.
> 
> Indeed. The GPIO-based CS does behave much more nicely, and it does not require
> that "drive MOSI line high" hack. But for reasons that I still do not clearly
> understand, occasional RX FIFO overflow errors still show up.
> 
> 
> Thanks for all the useful comments !
> 
> -- 
> Damien Le Moal
> Western Digital

  reply	other threads:[~2020-11-15 16:01 UTC|newest]

Thread overview: 132+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-07  8:13 [PATCH 00/32] RISC-V Kendryte K210 support improvments Damien Le Moal
2020-11-07  8:13 ` [PATCH 01/32] of: Fix property supplier parsing Damien Le Moal
2020-11-09 15:05   ` Serge Semin
2020-11-09 15:14   ` Andy Shevchenko
2020-11-09 17:44     ` Serge Semin
2020-11-09 20:52       ` Rob Herring
2020-11-07  8:13 ` [PATCH 02/32] spi: dw: Add support for 32-bits ctrlr0 layout Damien Le Moal
2020-11-07 13:28   ` Sean Anderson
2020-11-09 14:25   ` Serge Semin
2020-11-09 14:33     ` Sean Anderson
2020-11-09 14:35       ` Sean Anderson
2020-11-09 14:40       ` Andy Shevchenko
2020-11-09 14:41         ` Andy Shevchenko
2020-11-09 14:49           ` Sean Anderson
2020-11-09 15:10             ` Andy Shevchenko
2020-11-09 14:36     ` Andy Shevchenko
2020-11-09 17:56       ` Serge Semin
2020-11-07  8:13 ` [PATCH 03/32] spi: dw: Fix driving MOSI low while recieving Damien Le Moal
2020-11-07 13:30   ` Sean Anderson
2020-11-09 13:29   ` Mark Brown
2020-11-09 13:47     ` Sean Anderson
2020-11-09 14:14       ` Mark Brown
2020-11-09 14:48         ` Serge Semin
2020-11-09 16:45           ` Mark Brown
2020-11-09 19:19         ` Serge Semin
2020-11-09 19:40           ` Sean Anderson
2020-11-09 20:17             ` Serge Semin
2020-11-09 20:29               ` Mark Brown
2020-11-09 20:20           ` Mark Brown
2020-11-09 21:05             ` Serge Semin
2020-11-10 13:43               ` Mark Brown
2020-11-07  8:13 ` [PATCH 04/32] spi: dw: Introduce polling device tree property Damien Le Moal
2020-11-09 16:04   ` Mark Brown
2020-11-09 19:59   ` Serge Semin
2020-11-13  9:22     ` Damien Le Moal
2020-11-15 16:01       ` Serge Semin [this message]
2020-11-16  7:47         ` Damien Le Moal
2020-11-16 12:33           ` Mark Brown
2020-11-16 21:55           ` Serge Semin
2020-11-17 14:44             ` Damien Le Moal
2020-11-17 18:26               ` Serge Semin
2020-11-18  4:41                 ` Damien Le Moal
2020-11-18 15:16                   ` Serge Semin
2020-11-19  5:12                     ` Damien Le Moal
2020-11-19  8:51                       ` Serge Semin
2020-11-19  8:57                         ` Damien Le Moal
2020-11-07  8:13 ` [PATCH 05/32] spi: dw: Introduce DW_SPI_CAP_POLL_NODELAY Damien Le Moal
2020-11-09 14:03   ` Mark Brown
2020-11-09 20:45   ` Serge Semin
2020-11-07  8:13 ` [PATCH 06/32] spi: dw: Add support for the Kendryte K210 SoC Damien Le Moal
2020-11-07 13:31   ` Sean Anderson
2020-11-07 13:42     ` Damien Le Moal
2020-11-07 13:52       ` Sean Anderson
2020-11-09 14:15         ` Mark Brown
2020-11-13  8:00     ` Damien Le Moal
2020-11-09 21:21   ` Serge Semin
2020-11-09 21:39     ` Damien Le Moal
2020-11-09 21:55       ` Rob Herring
2020-11-09 22:00         ` Damien Le Moal
2020-11-09 23:07           ` Rob Herring
2020-11-10  0:35             ` Damien Le Moal
2020-11-07  8:13 ` [PATCH 07/32] dt-bindings: Update DW SPI device tree bindings Damien Le Moal
2020-11-07  8:13 ` [PATCH 08/32] riscv: Fix kernel time_init() Damien Le Moal
2020-11-12  7:21   ` Atish Patra
2020-11-13  7:31   ` Stephen Boyd
2020-11-07  8:13 ` [PATCH 09/32] riscv: Fix SiFive gpio probe Damien Le Moal
2020-11-10 14:39   ` Linus Walleij
2020-11-07  8:13 ` [PATCH 10/32] riscv: Fix sifive serial driver Damien Le Moal
2020-11-07  8:13 ` [PATCH 11/32] riscv: Enable interrupts during syscalls with M-Mode Damien Le Moal
2020-11-07  8:14 ` [PATCH 12/32] riscv: Automatically select sysctl config options Damien Le Moal
2020-11-07  8:14 ` [PATCH 13/32] riscv: Fix builtin DTB handling Damien Le Moal
2020-11-15  4:17   ` kernel test robot
2020-11-07  8:14 ` [PATCH 14/32] dt-bindings: Define all Kendryte K210 clock IDs Damien Le Moal
2020-11-07 13:33   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 15/32] dt-bindings: Define Kendryte K210 sysctl registers Damien Le Moal
2020-11-07 13:34   ` Sean Anderson
2020-11-09 21:59   ` Rob Herring
2020-11-09 22:10     ` Sean Anderson
2020-11-09 23:01       ` Rob Herring
2020-11-07  8:14 ` [PATCH 16/32] dt-bindings: Define Kendryte K210 pin functions Damien Le Moal
2020-11-07 13:38   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 17/32] dt-bindings: Define Kendryte K210 reset signals Damien Le Moal
2020-11-07 13:38   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 18/32] riscv: Add Kendryte K210 SoC clock driver Damien Le Moal
2020-11-07 13:48   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 19/32] riscv: Add Kendryte K210 SoC reset controller Damien Le Moal
2020-11-07 13:58   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 20/32] riscv: Add Kendryte K210 FPIOA pinctrl driver Damien Le Moal
2020-11-09 18:48   ` kernel test robot
2020-11-15  0:28   ` kernel test robot
2020-11-24  8:43   ` Linus Walleij
2020-11-24  8:53     ` Damien Le Moal
2020-11-29 21:33       ` Linus Walleij
2020-11-30  3:13         ` Damien Le Moal
2020-11-30  7:05           ` Serge Semin
2020-11-30  7:27             ` Damien Le Moal
2020-11-24  8:56     ` Damien Le Moal
2020-11-07  8:14 ` [PATCH 21/32] dt-bindings: Add Kendryte and Canaan vendor prefix Damien Le Moal
2020-11-07 14:03   ` Sean Anderson
2020-11-13  8:17     ` Damien Le Moal
2020-11-09 22:01   ` Rob Herring
2020-11-09 22:04     ` Damien Le Moal
2020-11-07  8:14 ` [PATCH 22/32] dt-binding: Document kendryte,k210-sysctl bindings Damien Le Moal
2020-11-07 14:05   ` Sean Anderson
2020-11-09 15:32   ` Rob Herring
2020-11-07  8:14 ` [PATCH 23/32] dt-binding: Document kendryte,k210-clk bindings Damien Le Moal
2020-11-07 14:05   ` Sean Anderson
2020-11-09 21:58   ` Rob Herring
2020-11-07  8:14 ` [PATCH 24/32] dt-bindings: Document kendryte,k210-fpioa bindings Damien Le Moal
2020-11-07 14:06   ` Sean Anderson
2020-11-09 15:32   ` Rob Herring
2020-11-09 15:36   ` Rob Herring
2020-11-09 15:45     ` Sean Anderson
2020-11-11 14:32       ` Rob Herring
2020-11-19 10:57       ` Geert Uytterhoeven
2020-11-19 11:22         ` Damien Le Moal
2020-11-07  8:14 ` [PATCH 25/32] dt-bindings: Document kendryte,k210-rst bindings Damien Le Moal
2020-11-07 14:07   ` Sean Anderson
2020-11-09 15:37   ` Rob Herring
2020-11-09 15:41   ` Rob Herring
2020-11-07  8:14 ` [PATCH 26/32] riscv: Update Kendryte K210 device tree Damien Le Moal
2020-11-07 14:08   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 27/32] riscv: Add SiPeed MAIX BiT board " Damien Le Moal
2020-11-07 14:13   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 28/32] riscv: Add SiPeed MAIX DOCK " Damien Le Moal
2020-11-07  8:14 ` [PATCH 29/32] riscv: Add SiPeed MAIX GO " Damien Le Moal
2020-11-07  8:14 ` [PATCH 30/32] riscv: Add SiPeed MAIXDUINO " Damien Le Moal
2020-11-07 14:14   ` Sean Anderson
2020-11-07  8:14 ` [PATCH 31/32] riscv: Add Kendryte KD233 " Damien Le Moal
2020-11-07  8:14 ` [PATCH 32/32] riscv: Update Kendryte K210 defconfig Damien Le Moal
2020-11-09 12:51 ` [PATCH 00/32] RISC-V Kendryte K210 support improvments Mark Brown
2020-11-09 12:55   ` Damien Le Moal

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=20201115160146.efxcdjhm7f2nmivo@mobilestation \
    --to=fancer.lancer@gmail.com \
    --cc=Damien.LeMoal@wdc.com \
    --cc=broonie@kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=palmer@dabbelt.com \
    --cc=seanga2@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox