AnsweredAssumed Answered

spi more than 4 chipselects on imx6

Question asked by Joshua Clayton on Dec 29, 2014
Latest reply on Dec 31, 2014 by Joshua Clayton

I have an imx6q based board, which was designed with 6 devices connected to ecspi4.

conencting these to a different spi bus would be problematic for various reasons, and since we are using gpio chipselects, it seems like more than 4 spi devices ought to be supportable.


I have made an attempt that mostly works. I let cs0, cs1, and cs2 work the same as they always have, and reuse cs3 for cs3, cs4 and cs5:

The only problem is this shared cs3 arrangement make the spi master unreliable. calls to write to spi sometimes work and sometimes don't.

I am also observing that the CLK line for the spi seems to be active when it should not be, (possibly the source of instability). One of the devices sharing cs3 is a cs-active-high device, so this might contribute to the problem if there is some internal hardware state that think the same device is being accessed when it is not.

I also (less successfully) tried to reset the spi control register at the beginning of mx51_ecspi_config


Here is my patch:

diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c

index 3637847..751574c 100644

--- a/drivers/spi/spi-imx.c

+++ b/drivers/spi/spi-imx.c

@@ -314,6 +314,12 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,

        u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0;

        u32 tx_wml_cfg, rx_wml_cfg, rxt_wml_cfg;

        u32 clk = config->speed_hz, delay;

+       u8 cs;


+       if (config->cs < 3)

+               cs = config->cs;

+       else

+               cs = 3;



         * The hardware seems to have a race condition when changing modes. The

@@ -328,21 +334,21 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,

        ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz, &clk);


        /* set chip select to use */

-       ctrl |= MX51_ECSPI_CTRL_CS(config->cs);

+       ctrl |= MX51_ECSPI_CTRL_CS(cs);


        ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET;


-       cfg |= MX51_ECSPI_CONFIG_SBBCTRL(config->cs);

+       cfg |= MX51_ECSPI_CONFIG_SBBCTRL(cs);


        if (config->mode & SPI_CPHA)

-               cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs);

+               cfg |= MX51_ECSPI_CONFIG_SCLKPHA(cs);


        if (config->mode & SPI_CPOL) {

-               cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs);

-               cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs);

+               cfg |= MX51_ECSPI_CONFIG_SCLKPOL(cs);

+               cfg |= MX51_ECSPI_CONFIG_SCLKCTL(cs);


        if (config->mode & SPI_CS_HIGH)

-               cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs);

+               cfg |= MX51_ECSPI_CONFIG_SSBPOL(cs);


        writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);

        writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);


Any thoughts on what I might try next would be appreciated.