This is caused by two different bugs in the 4.1.15 2.0.0 GA BSP release.
If you're a NXP person reading this, please feel free to pass along my contact info to the responsible engineers. I would be glad to help feed back my fixes into the NXP mainline.
The issue is twofold.
1) The TX DMA watermark is being forced to zero, so the SDMA only refills the TX FIFO when it has already been emptied. This means that there will always be a gap in the SPI transactions, as you see above.
if (spi_imx->dma_is_inited) {
if (spi_imx->devtype_data->devtype != IMX6UL_ECSPI)
spi_imx->tx_wml = 1; // **** THIS IS BAD ****
dma = (spi_imx->rx_wml - 1) << MX51_ECSPI_DMA_RX_WML_OFFSET
| (spi_imx->tx_wml - 1) << MX51_ECSPI_DMA_TX_WML_OFFSET
| (1 << MX51_ECSPI_DMA_TEDEN_OFFSET)
| (1 << MX51_ECSPI_DMA_RXDEN_OFFSET);
writel(dma, spi_imx->base + MX51_ECSPI_DMA);
}(from linux-fslc/spi-imx.c at 4.1-2.0.x-imx · Freescale/linux-fslc · GitHub )
2) The SDMA driver recently (ok, in 2015) introduced a flag on sdmacs called "context_loaded", which (if true) causes sdma_load_context() to exit early. This breaks the IMX SPI driver, which calls sdma_load_context() first in probe(), and then later (with different parameters) in its setup_transfer function. I just deleted the early return in sdma_load_context(). Perhaps it is there for some reason, but to my eyes, the code is broken.
I wanted to leave these breadcrumbs here for future engineers' benefit. I spent nearly two weeks tracking down these bugs.