i.MX7D ECSPI problems in PIO mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX7D ECSPI problems in PIO mode

846 Views
botondkardos
Contributor II

Hello,

while making a TPM2.0 SPI module work with i.MX7D I have encountered some problems. For some reason I'm not able to start DMA so everything below refers to PIO mode.

First I think there's either a problem with the ECSPI module or the i.MX7D reference manual (RM) isn't accurate. For TPM2.0 I would need longer bursts with a single contiguous CS impulse. The RM gives an example on this exact same use case (in 10.1.4.4.1.3) but elsewhere it is ambiguous. In 10.1.7.4 the comment for the SS_CTL[] states "0 - only one SPI burst will be transmitted". And this seems to be the reality: if I fill the FIFO, clear SS_CTL[0] and set XCH, I will see a single SPI burst on the oscilloscope, an interrupt will be triggered and XCH bit is already cleared when the interrupt hits. Using SMC instead of XCH results in multiple discrete SPI bursts but all with a separate pulse on SS0 (the chip-select line).

So it seems to me that it is not possible to generate multiple SPI bursts with a single SS0 pulse (at least not the way it is described in the RM).

So I went for a GPIO solution: I wanted to set and clear SS0 from SW and done automatically by the ECSPI module.

Here came another problem: spi-imx.c configures the cs_gpio pin as an output too early (before it has been requested for) so it doesn't give out any pulses. (I have properly modified the device tree.)

I needed to add this patch (to 4.9.88 BSP):

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 284a0de..7b46ba1 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -339,6 +339,10 @@ static void mx51_ecspi_trigger(struct spi_imx_data *spi_imx)
                reg |= MX51_ECSPI_CTRL_SMC;
        else
                reg &= ~MX51_ECSPI_CTRL_SMC;
+
+    reg &= ~MX51_ECSPI_CTRL_XCH;
+    reg |= MX51_ECSPI_CTRL_SMC;
+
        writel(reg, spi_imx->base + MX51_ECSPI_CTRL);
 }
 
@@ -1297,6 +1306,7 @@ static int spi_imx_probe(struct platform_device *pdev)
                goto out_clk_put;
        }
 
+    spi = to_spi_device( spi_imx->dev );
        for (i = 0; i < master->num_chipselect; i++) {
                if (!gpio_is_valid(master->cs_gpios[i]))
                        continue;
@@ -1308,6 +1318,13 @@ static int spi_imx_probe(struct platform_device *pdev)
                                master->cs_gpios[i]);
                        goto out_clk_put;
                }
+
+        if ( spi ) {
+            ret = gpio_direction_output(master->cs_gpios[i],
+                                        spi->mode & SPI_CS_HIGH ? 0 : 1);
+            printk( KERN_ALERT "**** gpio_direction_output: %i\n", ret );
+        } else
+            printk( KERN_ALERT "**** spi == NULL\n" );
        }
 
        dev_info(&pdev->dev, "probed\n");

(One may omit my "printk" messages.)

It seems to me that the latest stable kernel also has this issue. spi-imx.c configures cs_gpio as output in spi_imx_setup() but that will be called before devm_gpio_request() for the same pin.

As mentioned above all this applies to non-DMA case.

/Botond

Labels (3)
0 Kudos
1 Reply

650 Views
botondkardos
Contributor II

Oopsy, there was a typo.

Correction: "I wanted to set and clear SS0 from SW and NOT done automatically by the ECSPI module."

0 Kudos