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.