1. 02 Oct, 2020 7 commits
  2. 01 Oct, 2020 7 commits
  3. 29 Sep, 2020 21 commits
    • Mark Brown's avatar
      Merge series "spi: dw: Add full Baikal-T1 SPI Controllers support" from Serge... · 9d362152
      Mark Brown authored
      Merge series "spi: dw: Add full Baikal-T1 SPI Controllers support" from Serge Semin <Sergey.Semin@baikalelectronics.ru>:
      
      Originally I intended to merge a dedicated Baikal-T1 System Boot SPI
      Controller driver into the kernel and leave the DW APB SSI driver
      untouched. But after a long discussion (see the link at the bottom of the
      letter) Mark and Andy persuaded me to integrate what we developed there
      into the DW APB SSI core driver to be useful for another controllers,
      which may have got the same peculiarities/problems as ours:
      - No IRQ.
      - No DMA.
      - No GPIO CS, so a native CS is utilized.
      - small Tx/Rx FIFO depth.
      - Automatic CS assertion/de-assertion.
      - Slow system bus.
      All of them have been fixed in the framework of this patchset in some
      extent at least for the SPI memory operations. As I expected it wasn't
      that easy and the integration took that many patches as you can see from
      the subject. Though some of them are mere cleanups or weakly related with
      the subject fixes, but we just couldn't leave the code as is at some
      places since we were working with the DW APB SSI driver anyway. Here is
      what we did to fix the original DW APB SSI driver, to make it less messy.
      
      First two patches are just cleanups to simplify the DW APB SSI device
      initialization a bit. We suggest to discard the IRQ threshold macro as
      unused and use a ternary operator to initialize the set_cs callback
      instead of assigning-and-updating it.
      
      Then we've discovered that the n_bytes field of the driver private data is
      used by the DW APB SSI IRQ handler, which requires it to be initialized
      before the SMP memory barrier and to be visible from another CPUs. Speaking
      about the SMP memory barrier. Having one right after the shared resources
      initialization is enough and there is no point in using the spin-lock to
      protect the Tx/Rx buffer pointers. The protection functionality is
      redundant there by the driver design. (Though I have a doubt whether the
      SMP memory barrier is also required there because the normal IO-methods
      like readl/writel implies a full memory barrier. So any memory operations
      performed before them are supposed to be seen by devices and another CPUs.
      See the patch log for details of my concern.)
      
      Thirdly we've found out that there is some confusion in the IRQs
      masking/unmasking/clearing in the SPI-transfer procedure. Multiple interrupts
      are unmasked on the SPI-transfer initialization, but just TXEI is only
      masked back on completion. Similarly IRQ status isn't cleared on the
      controller reset, which actually makes the reset being not full and errors
      prone in the controller probe procedure.
      
      Another very important optimization is using the IO-relaxed accessors in
      the dw_read_io_reg()/dw_write_io_reg() methods. Since the Tx/Rx FIFO data
      registers are the most frequently accessible controller resource, using
      relaxed accessors there will significantly improve the data read/write
      performance. At least on Baikal-T1 SoC such modification opens up a way to
      have the DW APB SSI controller working with higher SPI bus speeds, than
      without it.
      
      Fifthly we've made an effort to cleanup the code using the SPI-device
      private data - chip_data. We suggest to remove the chip type from there
      since it isn't used and isn't implemented right anyway. Then instead of
      having a bus speed, clock divider, transfer mode preserved there, and
      recalculating the CR0 fields of the SPI-device-specific phase, polarity
      and frame format each time the SPI transfer is requested, we can save it
      in the chip_data instance. By doing so we'll make that structure finally
      used as it was supposed to by design (see the spi-fsl-dspi.c, spi-pl022.c,
      spi-pxa2xx.c drivers for examples).
      
      Sixthly instead of having the SPI-transfer specific CR0-update callback,
      we suggest to implement the DW APB SSI controller capabilities approach.
      By doing so we can now inject the vendor-specific peculiarities in
      different parts of the DW APB SSI core driver (which is required to
      implement both SPI-transfers and the SPI memory operations). This will
      also make the code less confusing like defining a callback in the core
      driver, setting it up in the glue layer, then calling it from the core
      driver again. Seeing the small capabilities implementation embedded
      in-situ is more readable than tracking the callbacks assignments. This
      will concern the CS-override, Keembay master setup, DW SSI-specific CR0
      registers layout capabilities.
      
      Seventhly since there are going to be two types of the transfers
      implemented in the DW APB SSI core driver, we need a common method to set
      the controller configuration like, Tx/Rx-mode, bus speed, data frame size
      and number of data frames to read in case of the memory operations. So we
      just detached the corresponding code from the SPI-transfer-one method and
      made it to be a part of the new dw_spi_update_config() function, which is
      former update_cr0(). Note that the new method will be also useful for the
      glue drivers, which due to the hardware design need to create their own
      memory operations (for instance, for the dirmap-operations provided in the
      Baikal-T System Boot SPI controller driver).
      
      Eighthly it is the data IO procedure and IRQ-based SPI-transfer
      implementation refactoring. The former one will look much simpler if the
      buffers initial pointers and the buffers length data utilized instead of
      the Tx/Rx buffers start and end pointers. The later one currently lacks of
      valid execution at the final stage of the SPI-transfer. So if there is no
      data left to send, but there is still data which needs to be received, the
      Tx FIFO Empty IRQ will constantly happen until all of the requested
      inbound data is received. So we suggest to fix that by taking the Rx FIFO
      Empty IRQ into account.
      
      Ninthly it's potentially errors prone to enable the DW APB SSI interrupts
      before enabling the chip. It specifically concerns a case if for some
      reason the DW APB SSI IRQs handler is executed before the controller is
      enabled. That will cause a part of the outbound data loss. So we suggest
      to reverse the order.
      
      Tenthly in order to be able to pre-initialize the Tx FIFO with data and
      only the start the SPI memory operations we need to have any CS
      de-activated. We'll fulfil that requirement by explicitly clearing the CS
      on the SPI transfer completion and at the explicit controller reset.
      
      Then seeing all the currently available and potentially being created
      types of the SPI transfers need to perform the DW APB SSI controller
      status register check and the errors handler procedure, we've created a
      common method for all of them.
      
      Eleventhly if before we've mostly had a series of fixups, cleanups and
      refactorings, here we've finally come to the new functionality
      implementation. It concerns the poll-based transfer (as Baikal-T1 System
      Boot SPI controller lacks a dedicated IRQ lane connected) and the SPI
      memory operations implementation. If the former feature is pretty much
      straightforward (see the patch log for details), the later one is a bit
      tricky. It's based on the EEPROM-read (write-then-read) and the Tx-only
      modes of the DW APB SSI controller, which as performing the automatic data
      read and write let's us to implement the faster IO procedure than using
      the Tx-Rx-mode-based approach. Having the memory-operations implemented
      that way is the best thing we can currently do to provide the errors-less
      SPI transfers to SPI devices with native CS attached.
      
      Note the approach utilized here to develop the SPI memory operations can
      be also used to create the "automatic CS toggle problem"-free(ish) SPI
      transfers (combine SPI-message transfers into two buffers, disable
      interrupts, push-pull the combined data). But we don't provide a solution
      in the framework of this patchset. It is a matter of a dedicated one,
      which we currently don't intend to spend our time on.
      
      Finally at the closure of the this patchset you'll find patches, which
      provide the Baikal-T1-specific DW APB SSI controllers support. The SoC has
      got three SPI controllers. Two of them are pretty much normal DW APB SSI
      interfaces: with IRQ, DMA, FIFOs of 64 words depth, 4x CSs. But the third
      one as being a part of the Baikal-T1 System Boot Controller has got a very
      limited resources: no IRQ, no DMA, only a single native chip-select and
      Tx/Rx FIFOs with just 8 words depth available. In order to provide a
      transparent initial boot code execution the System Boot SPI Controller is
      also utilized by an vendor-specific IP-block, which exposes an SPI flash
      memory direct mapping interface. Please see the corresponding patch for
      details.
      
      Link: https://lore.kernel.org/linux-spi/20200508093621.31619-1-Sergey.Semin@baikalelectronics.ru/
      
      [1] "LINUX KERNEL MEMORY BARRIERS", Documentation/memory-barriers.txt,
          Section "KERNEL I/O BARRIER EFFECTS"
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Cc: Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>
      Cc: Ramil Zaripov <Ramil.Zaripov@baikalelectronics.ru>
      Cc: Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>
      Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
      Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
      Cc: Lars Povlsen <lars.povlsen@microchip.com>
      Cc: wuxu.wu <wuxu.wu@huawei.com>
      Cc: Feng Tang <feng.tang@intel.com>
      Cc: Rob Herring <robh+dt@kernel.org>
      Cc: linux-spi@vger.kernel.org
      Cc: devicetree@vger.kernel.org
      Cc: linux-kernel@vger.kernel.org
      
      Serge Semin (30):
        spi: dw: Discard IRQ threshold macro
        spi: dw: Use ternary op to init set_cs callback
        spi: dw: Initialize n_bytes before the memory barrier
        Revert: spi: spi-dw: Add lock protect dw_spi rx/tx to prevent
          concurrent calls
        spi: dw: Clear IRQ status on DW SPI controller reset
        spi: dw: Disable all IRQs when controller is unused
        spi: dw: Use relaxed IO-methods to access FIFOs
        spi: dw: Discard DW SSI chip type storages
        spi: dw: Convert CS-override to DW SPI capabilities
        spi: dw: Add KeemBay Master capability
        spi: dw: Add DWC SSI capability
        spi: dw: Detach SPI device specific CR0 config method
        spi: dw: Update SPI bus speed in a config function
        spi: dw: Simplify the SPI bus speed config procedure
        spi: dw: Update Rx sample delay in the config function
        spi: dw: Add DW SPI controller config structure
        spi: dw: Refactor data IO procedure
        spi: dw: Refactor IRQ-based SPI transfer procedure
        spi: dw: Perform IRQ setup in a dedicated function
        spi: dw: Unmask IRQs after enabling the chip
        spi: dw: Discard chip enabling on DMA setup error
        spi: dw: De-assert chip-select on reset
        spi: dw: Explicitly de-assert CS on SPI transfer completion
        spi: dw: Move num-of retries parameter to the header file
        spi: dw: Add generic DW SSI status-check method
        spi: dw: Add memory operations support
        spi: dw: Introduce max mem-ops SPI bus frequency setting
        spi: dw: Add poll-based SPI transfers support
        dt-bindings: spi: dw: Add Baikal-T1 SPI Controllers
        spi: dw: Add Baikal-T1 SPI Controller glue driver
      
       .../bindings/spi/snps,dw-apb-ssi.yaml         |  33 +-
       drivers/spi/Kconfig                           |  29 +
       drivers/spi/Makefile                          |   1 +
       drivers/spi/spi-dw-bt1.c                      | 339 +++++++++
       drivers/spi/spi-dw-core.c                     | 642 ++++++++++++++----
       drivers/spi/spi-dw-dma.c                      |  16 +-
       drivers/spi/spi-dw-mmio.c                     |  36 +-
       drivers/spi/spi-dw.h                          |  85 ++-
       8 files changed, 960 insertions(+), 221 deletions(-)
       create mode 100644 drivers/spi/spi-dw-bt1.c
      
      --
      2.27.0
      9d362152
    • Serge Semin's avatar
      spi: spi-dw: Remove extraneous locking · 0b6bfad4
      Serge Semin authored
      There is no point in having the commit 19b61392 ("spi: spi-dw: Add
      lock protect dw_spi rx/tx to prevent concurrent calls") applied. The
      commit author made an assumption that the problem with the rx data
      mismatch was due to the lack of the data protection. While most likely it
      was caused by the lack of the memory barrier. So having the
      commit bfda0445 ("spi: dw: use "smp_mb()" to avoid sending spi data
      error") applied would be enough to fix the problem.
      
      Indeed the spin unlock operation makes sure each memory operation issued
      before the release will be completed before it's completed. In other words
      it works as an implicit one way memory barrier. So having both smp_mb()
      and the spin_unlock_irqrestore() here is just redundant. One of them would
      be enough. It's better to leave the smp_mb() since the Tx/Rx buffers
      consistency is provided by the data transfer algorithm implementation:
      first we initialize the buffers pointers, then make sure the assignments
      are visible by the other CPUs by calling the smp_mb(), only after that
      enable the interrupt, which handler uses the buffers.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-5-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      0b6bfad4
    • Serge Semin's avatar
      spi: dw: Add KeemBay Master capability · ffb7ca54
      Serge Semin authored
      In a further commit we'll have to get rid of the update_cr0() callback and
      define a DW SSI capability instead. Since Keem Bay master/slave
      functionality is controller by the CTRL0 register bitfield, we need to
      first move the master mode selection into the internal corresponding
      update_cr0 method, which would be activated by means of the dedicated
      DW_SPI_CAP_KEEMBAY_MST capability setup.
      
      Note this will be also useful if the driver will be ever altered to
      support the DW SPI slave interface.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-11-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      ffb7ca54
    • Serge Semin's avatar
      spi: dw: Convert CS-override to DW SPI capabilities · cc760f31
      Serge Semin authored
      There are several vendor-specific versions of the DW SPI controllers,
      each of which may have some peculiarities with respect to the original
      IP-core. Seeing it has already caused adding flags and a callback into the
      DW SPI private data, let's introduce a generic capabilities interface to
      tune the generic DW SPI controller driver up in accordance with the
      particular controller specifics. It's done by converting a simple
      Alpine-specific CS-override capability into the DW SPI controller
      capability activated by setting the DW_SPI_CAP_CS_OVERRIDE flag.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-10-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      cc760f31
    • Serge Semin's avatar
      spi: dw: Discard DW SSI chip type storages · 675e7c9d
      Serge Semin authored
      Keeping SPI peripheral devices type is pointless since first it hasn't
      been functionally utilized by any of the client drivers/code and second it
      won't work for Microwire type at the very least. Moreover there is no
      point in setting up the type by means of the chip-data in the modern
      kernel. The peripheral devices with specific interface type need to be
      detected in order to activate the corresponding frame format. It most
      likely will require some peripheral device specific DT property or
      whatever to find out the interface protocol. So let's remove the serial
      interface type fields from the DW APB SSI controller and the SPI
      peripheral device private data.
      
      Note we'll preserve the explicit SSI_MOTO_SPI interface type setting up to
      signify the only currently supported interface protocol.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-9-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      675e7c9d
    • Serge Semin's avatar
      spi: dw: Use relaxed IO-methods to access FIFOs · 7e31cea7
      Serge Semin authored
      In accordance with [1] the relaxed methods are guaranteed to be ordered
      with respect to other accesses from the same CPU thread to the same
      peripheral.  This is what we need during the data read/write from/to the
      controller FIFOs being executed within a single IRQ handler or a kernel
      task.
      
      Such optimization shall significantly speed the data reader and writer up.
      For instance, the relaxed IO-accessors utilization on Baikal-T1 lets the
      driver to support the SPI memory operations with bus frequency three-fold
      faster than if normal IO-accessors would be used.
      
      [1] "LINUX KERNEL MEMORY BARRIERS", Documentation/memory-barriers.txt,
          Section "KERNEL I/O BARRIER EFFECTS"
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-8-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7e31cea7
    • Serge Semin's avatar
      spi: dw: Disable all IRQs when controller is unused · a1d5aa6f
      Serge Semin authored
      It's a good practice to disable all IRQs if a device is fully unused. In
      our case it is supposed to be done before requesting the IRQ and after the
      last byte of an SPI transfer is received. In the former case it's required
      to prevent the IRQ handler invocation before the driver data is fully
      initialized (which may happen if the IRQs status has been left uncleared
      before the device is probed). So we just moved the spi_hw_init() method
      invocation to the earlier stage before requesting the IRQ. In the later
      case there is just no point in having any of the IRQs enabled between SPI
      transfers and when there is no SPI message currently being processed.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-7-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      a1d5aa6f
    • Serge Semin's avatar
      spi: dw: Clear IRQ status on DW SPI controller reset · a128f6ec
      Serge Semin authored
      It turns out the IRQ status isn't cleared after switching the controller
      off and getting it back on, which may cause raising false error interrupts
      if controller has been unsuccessfully used by, for instance, a bootloader
      before the driver is loaded. Let's explicitly clear the interrupts status
      in the dedicated controller reset method.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-6-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      a128f6ec
    • Serge Semin's avatar
      spi: dw: Initialize n_bytes before the memory barrier · 8225c1c9
      Serge Semin authored
      Since n_bytes field of the DW SPI private data is also utilized by the
      IRQ handler, we need to make sure it' initialization is done before the
      memory barrier.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-4-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      8225c1c9
    • Serge Semin's avatar
      spi: dw: Discard IRQ threshold macro · 07918df7
      Serge Semin authored
      The macro has been unused since a half of FIFO length was defined to be a
      marker of the IRQ. Let's remove it definition.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112914.26501-2-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      07918df7
    • Serge Semin's avatar
      spi: dw-dma: Add one-by-one SG list entries transfer · ad4fe126
      Serge Semin authored
      In case if at least one of the requested DMA engine channels doesn't
      support the hardware accelerated SG list entries traverse, the DMA driver
      will most likely work that around by performing the IRQ-based SG list
      entries resubmission. That might and will cause a problem if the DMA Tx
      channel is recharged and re-executed before the Rx DMA channel. Due to
      non-deterministic IRQ-handler execution latency the DMA Tx channel will
      start pushing data to the SPI bus before the Rx DMA channel is even
      reinitialized with the next inbound SG list entry. By doing so the DMA
      Tx channel will implicitly start filling the DW APB SSI Rx FIFO up, which
      while the DMA Rx channel being recharged and re-executed will eventually
      be overflown.
      
      In order to solve the problem we have to feed the DMA engine with SG
      list entries one-by-one. It shall keep the DW APB SSI Tx and Rx FIFOs
      synchronized and prevent the Rx FIFO overflow. Since in general the SPI
      tx_sg and rx_sg lists may have different number of entries of different
      lengths (though total length should match) we virtually split the
      SG-lists to the set of DMA transfers, which length is a minimum of the
      ordered SG-entries lengths.
      
      The solution described above is only executed if a full-duplex SPI
      transfer is requested and the DMA engine hasn't provided channels with
      hardware accelerated SG list traverse capability to handle both SG
      lists at once.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Suggested-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
      Link: https://lore.kernel.org/r/20200920112322.24585-12-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      ad4fe126
    • Serge Semin's avatar
      spi: dw-dma: Pass exact data to the DMA submit and wait methods · 917ce29e
      Serge Semin authored
      In order to use the DMA submission and waiting methods in both generic
      DMA-based SPI transfer and one-by-one DMA SG entries transmission
      functions, we need to modify the dw_spi_dma_wait() and
      dw_spi_dma_submit_tx()/dw_spi_dma_submit_rx() prototypes. So instead of
      getting the SPI transfer object as the second argument they must accept
      the exact data structure instances they imply to use. Those are the
      current transfer length and the SPI bus frequency in case of
      dw_spi_dma_wait(), and SG list together with number of list entries in
      case of the DMA Tx/Rx submission methods.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-11-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      917ce29e
    • Serge Semin's avatar
      spi: dw-dma: Move DMAC register cleanup to DMA transfer method · 945b5b60
      Serge Semin authored
      DW APB SSI DMA driver doesn't use the native SPI core wait API since
      commit bdbdf0f0 ("spi: dw: Locally wait for the DMA transfers
      completion"). Due to that the driver can now clear the DMAC register
      in a single place synchronously with the DMA transactions completion
      or failure. After that all the possible code paths are still covered:
      1) DMA completion callbacks are executed in case if the corresponding DMA
      transactions are finished. When they are, one of them will eventually wake
      the SPI messages pump kernel thread and dw_spi_dma_transfer_all() method
      will clean the DMAC register as implied by this patch.
      2) dma_stop is called when the SPI core detects an error either returned
      from the transfer_one() callback or set in the SPI message status field.
      Both types of errors will be noticed by the dw_spi_dma_transfer_all()
      method.
      3) dma_exit is called when either SPI controller driver or the
      corresponding device is removed. In any case the SPI core will first
      flush the SPI messages pump kernel thread, so any pending or in-fly
      SPI transfers will be finished before that.
      
      Due to all of that let's simplify the DW APB SSI DMA driver a bit and
      move the DMAC register cleanup to a single place in the
      dw_spi_dma_transfer_all() method.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-10-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      945b5b60
    • Serge Semin's avatar
      spi: dw-dma: Detach DMA transfer into a dedicated method · b86fed12
      Serge Semin authored
      In order to add an alternative method of DMA-based SPI transfer first we
      need to detach the currently available one from the common code. Here we
      move the normal DMA-based SPI transfer execution functionality into a
      dedicated method. It will be utilized if either the DMA engine supports
      an unlimited number SG entries or Tx-only SPI transfer is requested. But
      currently just use it for any SPI transfer.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-9-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      b86fed12
    • Serge Semin's avatar
      spi: dw-dma: Remove DMA Tx-desc passing around · 7a4d61f1
      Serge Semin authored
      It's pointless to pass the Rx and Tx transfers DMA Tx-descriptors, since
      they are used in the Tx/Rx submit method only. Instead just return the
      submission status from these methods. This alteration will make the code
      less complex.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-8-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7a4d61f1
    • Serge Semin's avatar
      spi: dw-dma: Check DMA Tx-desc submission status · 9a6471a1
      Serge Semin authored
      We suggest to add the dmaengine_submit() return value test for errors.  It
      has been unnecessary while the driver was expected to be utilized in pair
      with DW DMAC. But since now the driver can be used with any DMA engine, it
      might be useful to track the errors on DMA submissions so not miss them
      and get into an unpredictable driver behaviour.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-7-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      9a6471a1
    • Serge Semin's avatar
      spi: dw-dma: Move DMA transfers submission to the channels prep methods · ab7a4d75
      Serge Semin authored
      Indeed we can freely move the dmaengine_submit() method invocation and the
      Tx and Rx busy flag setting into the DMA Tx/Rx prepare methods. Since the
      Tx/Rx preparation method is now mainly used for the DMA transfers
      submission, here we suggest to rename it to have the _submit_{r,t}x suffix
      instead.
      
      By having this alteration applied first we implement another code
      preparation before adding the one-by-one DMA SG entries transmission,
      second we now have the dma_async_tx_descriptor descriptor used locally
      only in the new DMA transfers submission methods (this will be cleaned up
      a bit later), third we make the generic transfer method more readable,
      where now the functionality of submission, execution and wait procedures
      is transparently split up instead of having a preparation, intermixed
      submission/execution and wait procedures.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-6-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      ab7a4d75
    • Serge Semin's avatar
      spi: dw-dma: Check rx_buf availability in the xfer method · be3034d9
      Serge Semin authored
      Checking rx_buf for being NULL and returning NULL from the Rx-channel
      preparation method doesn't let us to distinguish that situation from
      errors happening during the Rx SG-list preparation. So it's better to make
      sure that the rx_buf not-NULL and full-duplex communication is requested
      prior calling the Rx preparation method.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-5-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      be3034d9
    • Serge Semin's avatar
      spi: dw-dma: Configure the DMA channels in dma_setup · a874d811
      Serge Semin authored
      Mainly this is a preparation patch before adding one-by-one DMA SG entries
      transmission. But logically the Tx and Rx DMA channels setup should be
      performed in the dma_setup() callback anyway. So we'll move the DMA slave
      channels src/dst burst lengths, address and address width configuration
      from the Tx/Rx channels preparation methods to the dedicated functions and
      then make sure it's called at the DMA setup stage.
      
      Note we now make sure the return value of the dmaengine_slave_config()
      method doesn't indicate an error. It has been unnecessary in case if Dw
      DMAC is utilized as a DMA engine, since its device_config() callback
      always returns zero (though it might change in future). But since DW APB
      SSI driver now supports any DMA back-end we must make sure the DMA device
      configuration has been successful before proceeding with further setups.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-4-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      a874d811
    • Serge Semin's avatar
      spi: dw-dma: Fail DMA-based transfer if no Tx-buffer specified · 7ef30385
      Serge Semin authored
      Since commit 46164fde ("spi: dw: Fix Rx-only DMA transfers") if DMA
      interface is enabled, then Tx-buffer must be available in each SPI
      transfer. It's required since in order to activate the incoming data
      reception either DMA or CPU must be pushing data out to the SPI bus.
      But the DW APB SSI DMA driver code is still left in state as if Tx-buffer
      might be optional, which is no longer true. Let's fix it so an error would
      be returned if no Tx-buffer detected and DMA Tx would be always
      enabled.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-3-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      7ef30385
    • Serge Semin's avatar
      spi: dw-dma: Set DMA Level registers on init · 01ddbbb0
      Serge Semin authored
      Indeed the registers content doesn't get cleared when the SPI controller
      is disabled and enabled. Max burst lengths aren't changed since the Rx and
      Tx DMA channels are requested on init stage and are kept acquired until
      the device is removed. Obviously SPI controller FIFO depth can't be
      changed. Due to all of that we can safely move the DMA Transmit and
      Receive data level registers initialization to the SPI controller DMA init
      stage (when the SPI controller is being probed) instead of doing it for
      each SPI transfer when dma_setup is called. This shall speed the DMA-based
      SPI transfer initialization up a bit, particularly if the APB bus is
      relatively slow.
      Signed-off-by: default avatarSerge Semin <Sergey.Semin@baikalelectronics.ru>
      Link: https://lore.kernel.org/r/20200920112322.24585-2-Sergey.Semin@baikalelectronics.ruSigned-off-by: default avatarMark Brown <broonie@kernel.org>
      01ddbbb0
  4. 28 Sep, 2020 1 commit
  5. 25 Sep, 2020 4 commits