Merge tag 'imx-ecspi-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo...
authorArnd Bergmann <arnd@arndb.de>
Thu, 12 Aug 2021 20:34:44 +0000 (22:34 +0200)
committerArnd Bergmann <arnd@arndb.de>
Thu, 12 Aug 2021 20:34:45 +0000 (22:34 +0200)
i.MX eCSPI errata handling for 5.15:

It includes all required changes for handling i.MX6/7 eCSPI errata
ERR009165, which causes FIFO transfer to be sent twice in DMA mode.
Both SPI and DMA maintainers agree to merge it through arm-soc tree.

* tag 'imx-ecspi-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux:
  dmaengine: imx-sdma: add terminated list for freed descriptor in worker
  dmaengine: imx-sdma: add uart rom script
  dma: imx-sdma: add i.mx6ul compatible name
  dmaengine: imx-sdma: remove ERR009165 on i.mx6ul
  spi: imx: remove ERR009165 workaround on i.mx6ul
  spi: imx: fix ERR009165
  dmaengine: imx-sdma: add mcu_2_ecspi script
  dmaengine: dma: imx-sdma: add fw_loaded and is_ram_script
  dmaengine: imx-sdma: remove duplicated sdma_load_context
  Revert "dmaengine: imx-sdma: refine to load context only once"
  Revert "ARM: dts: imx6: Use correct SDMA script for SPI cores"
  Revert "ARM: dts: imx6q: Use correct SDMA script for SPI5 core"

Link: https://lore.kernel.org/r/20210809071838.GF30984@dragon
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
1  2 
drivers/spi/spi-imx.c

diff --combined drivers/spi/spi-imx.c
@@@ -77,6 -77,11 +77,11 @@@ struct spi_imx_devtype_data 
        bool has_slavemode;
        unsigned int fifo_size;
        bool dynamic_burst;
+       /*
+        * ERR009165 fixed or not:
+        * https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf
+        */
+       bool tx_glitch_fixed;
        enum spi_imx_devtype devtype;
  };
  
@@@ -506,7 -511,7 +511,7 @@@ static int mx51_ecspi_prepare_message(s
  {
        struct spi_device *spi = msg->spi;
        u32 ctrl = MX51_ECSPI_CTRL_ENABLE;
 -      u32 testreg;
 +      u32 testreg, delay;
        u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);
  
        /* set Master or Slave mode */
  
        writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
  
 +      /*
 +       * Wait until the changes in the configuration register CONFIGREG
 +       * propagate into the hardware. It takes exactly one tick of the
 +       * SCLK clock, but we will wait two SCLK clock just to be sure. The
 +       * effect of the delay it takes for the hardware to apply changes
 +       * is noticable if the SCLK clock run very slow. In such a case, if
 +       * the polarity of SCLK should be inverted, the GPIO ChipSelect might
 +       * be asserted before the SCLK polarity changes, which would disrupt
 +       * the SPI communication as the device on the other end would consider
 +       * the change of SCLK polarity as a clock tick already.
 +       */
 +      delay = (2 * 1000000) / spi_imx->spi_bus_clk;
 +      if (likely(delay < 10)) /* SCLK is faster than 100 kHz */
 +              udelay(delay);
 +      else                    /* SCLK is _very_ slow */
 +              usleep_range(delay, delay + 10);
 +
        return 0;
  }
  
@@@ -591,7 -579,7 +596,7 @@@ static int mx51_ecspi_prepare_transfer(
                                       struct spi_device *spi)
  {
        u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL);
 -      u32 clk, delay;
 +      u32 clk;
  
        /* Clear BL field and set the right value */
        ctrl &= ~MX51_ECSPI_CTRL_BL_MASK;
        ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->spi_bus_clk, &clk);
        spi_imx->spi_bus_clk = clk;
  
-       if (spi_imx->usedma)
+       /*
+        * ERR009165: work in XHC mode instead of SMC as PIO on the chips
+        * before i.mx6ul.
+        */
+       if (spi_imx->usedma && spi_imx->devtype_data->tx_glitch_fixed)
                ctrl |= MX51_ECSPI_CTRL_SMC;
+       else
+               ctrl &= ~MX51_ECSPI_CTRL_SMC;
  
        writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
  
 -      /*
 -       * Wait until the changes in the configuration register CONFIGREG
 -       * propagate into the hardware. It takes exactly one tick of the
 -       * SCLK clock, but we will wait two SCLK clock just to be sure. The
 -       * effect of the delay it takes for the hardware to apply changes
 -       * is noticable if the SCLK clock run very slow. In such a case, if
 -       * the polarity of SCLK should be inverted, the GPIO ChipSelect might
 -       * be asserted before the SCLK polarity changes, which would disrupt
 -       * the SPI communication as the device on the other end would consider
 -       * the change of SCLK polarity as a clock tick already.
 -       */
 -      delay = (2 * 1000000) / clk;
 -      if (likely(delay < 10)) /* SCLK is faster than 100 kHz */
 -              udelay(delay);
 -      else                    /* SCLK is _very_ slow */
 -              usleep_range(delay, delay + 10);
 -
        return 0;
  }
  
  static void mx51_setup_wml(struct spi_imx_data *spi_imx)
  {
+       u32 tx_wml = 0;
+       if (spi_imx->devtype_data->tx_glitch_fixed)
+               tx_wml = spi_imx->wml;
        /*
         * Configure the DMA register: setup the watermark
         * and enable DMA request.
         */
        writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
-               MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
+               MX51_ECSPI_DMA_TX_WML(tx_wml) |
                MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
                MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
                MX51_ECSPI_DMA_RXTDEN, spi_imx->base + MX51_ECSPI_DMA);
@@@ -1014,6 -1029,23 +1029,23 @@@ static struct spi_imx_devtype_data imx5
        .devtype = IMX53_ECSPI,
  };
  
+ static struct spi_imx_devtype_data imx6ul_ecspi_devtype_data = {
+       .intctrl = mx51_ecspi_intctrl,
+       .prepare_message = mx51_ecspi_prepare_message,
+       .prepare_transfer = mx51_ecspi_prepare_transfer,
+       .trigger = mx51_ecspi_trigger,
+       .rx_available = mx51_ecspi_rx_available,
+       .reset = mx51_ecspi_reset,
+       .setup_wml = mx51_setup_wml,
+       .fifo_size = 64,
+       .has_dmamode = true,
+       .dynamic_burst = true,
+       .has_slavemode = true,
+       .tx_glitch_fixed = true,
+       .disable = mx51_ecspi_disable,
+       .devtype = IMX51_ECSPI,
+ };
  static const struct of_device_id spi_imx_dt_ids[] = {
        { .compatible = "fsl,imx1-cspi", .data = &imx1_cspi_devtype_data, },
        { .compatible = "fsl,imx21-cspi", .data = &imx21_cspi_devtype_data, },
        { .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, },
        { .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, },
        { .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, },
+       { .compatible = "fsl,imx6ul-ecspi", .data = &imx6ul_ecspi_devtype_data, },
        { /* sentinel */ }
  };
  MODULE_DEVICE_TABLE(of, spi_imx_dt_ids);
@@@ -1239,10 -1272,6 +1272,6 @@@ static int spi_imx_sdma_init(struct dev
  {
        int ret;
  
-       /* use pio mode for i.mx6dl chip TKT238285 */
-       if (of_machine_is_compatible("fsl,imx6dl"))
-               return 0;
        spi_imx->wml = spi_imx->devtype_data->fifo_size / 2;
  
        /* Prepare for TX DMA: */