spi: imx: mx51-ecspi: Move some initialisation to prepare_message hook.
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Fri, 30 Nov 2018 06:47:06 +0000 (07:47 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 11 Dec 2018 11:59:33 +0000 (11:59 +0000)
The relevant difference between prepare_message and config is that the
former is run before the CS signal is asserted. So the polarity of the
CLK line must be configured in prepare_message as an edge generated by
config might already result in a latch of the MOSI line.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-imx.c

index c7db42d6b3bc566ca9af3357756b76b98f1bbba8..d3a1e71045567e902908424fa7104fb61361d229 100644 (file)
@@ -490,14 +490,9 @@ static void mx51_ecspi_disable(struct spi_imx_data *spi_imx)
 static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx,
                                      struct spi_message *msg)
 {
-       return 0;
-}
-
-static int mx51_ecspi_config(struct spi_device *spi)
-{
-       struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+       struct spi_device *spi = msg->spi;
        u32 ctrl = MX51_ECSPI_CTRL_ENABLE;
-       u32 clk = spi_imx->speed_hz, delay, reg;
+       u32 testreg;
        u32 cfg = readl(spi_imx->base + MX51_ECSPI_CONFIG);
 
        /* set Master or Slave mode */
@@ -512,19 +507,21 @@ static int mx51_ecspi_config(struct spi_device *spi)
        if (spi->mode & SPI_READY)
                ctrl |= MX51_ECSPI_CTRL_DRCTL(spi_imx->spi_drctl);
 
-       /* set clock speed */
-       ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk);
-       spi_imx->spi_bus_clk = clk;
-
        /* set chip select to use */
        ctrl |= MX51_ECSPI_CTRL_CS(spi->chip_select);
 
-       if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
-               ctrl |= (spi_imx->slave_burst * 8 - 1)
-                       << MX51_ECSPI_CTRL_BL_OFFSET;
+       /*
+        * The ctrl register must be written first, with the EN bit set other
+        * registers must not be written to.
+        */
+       writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
+
+       testreg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
+       if (spi->mode & SPI_LOOP)
+               testreg |= MX51_ECSPI_TESTREG_LBC;
        else
-               ctrl |= (spi_imx->bits_per_word - 1)
-                       << MX51_ECSPI_CTRL_BL_OFFSET;
+               testreg &= ~MX51_ECSPI_TESTREG_LBC;
+       writel(testreg, spi_imx->base + MX51_ECSPI_TESTREG);
 
        /*
         * eCSPI burst completion by Chip Select signal in Slave mode
@@ -548,25 +545,42 @@ static int mx51_ecspi_config(struct spi_device *spi)
                cfg &= ~MX51_ECSPI_CONFIG_SCLKPOL(spi->chip_select);
                cfg &= ~MX51_ECSPI_CONFIG_SCLKCTL(spi->chip_select);
        }
+
        if (spi->mode & SPI_CS_HIGH)
                cfg |= MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
        else
                cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(spi->chip_select);
 
-       if (spi_imx->usedma)
-               ctrl |= MX51_ECSPI_CTRL_SMC;
+       writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
 
-       /* CTRL register always go first to bring out controller from reset */
-       writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
+       return 0;
+}
 
-       reg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
-       if (spi->mode & SPI_LOOP)
-               reg |= MX51_ECSPI_TESTREG_LBC;
+static int mx51_ecspi_config(struct spi_device *spi)
+{
+       struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
+       u32 ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL);
+       u32 clk = spi_imx->speed_hz, delay;
+
+       /* Clear BL field and set the right value */
+       ctrl &= ~MX51_ECSPI_CTRL_BL_MASK;
+       if (spi_imx->slave_mode && is_imx53_ecspi(spi_imx))
+               ctrl |= (spi_imx->slave_burst * 8 - 1)
+                       << MX51_ECSPI_CTRL_BL_OFFSET;
        else
-               reg &= ~MX51_ECSPI_TESTREG_LBC;
-       writel(reg, spi_imx->base + MX51_ECSPI_TESTREG);
+               ctrl |= (spi_imx->bits_per_word - 1)
+                       << MX51_ECSPI_CTRL_BL_OFFSET;
 
-       writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
+       /* set clock speed */
+       ctrl &= ~(0xf << MX51_ECSPI_CTRL_POSTDIV_OFFSET |
+                 0xf << MX51_ECSPI_CTRL_PREDIV_OFFSET);
+       ctrl |= mx51_ecspi_clkdiv(spi_imx, spi_imx->speed_hz, &clk);
+       spi_imx->spi_bus_clk = clk;
+
+       if (spi_imx->usedma)
+               ctrl |= MX51_ECSPI_CTRL_SMC;
+
+       writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
 
        /*
         * Wait until the changes in the configuration register CONFIGREG
@@ -594,7 +608,6 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx)
         * 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_RXT_WML(spi_imx->wml) |