[PATCH] SPI: bcm2835: move to the transfer_one driver model

Martin Sperl kernel at martin.sperl.org
Fri Apr 3 03:17:31 PDT 2015


> On 01.04.2015, at 17:20, Stephen Warren <swarren at wwwdotorg.org> wrote:
> 
> Does that change cause the SDHCI core to use vs. not-use any of the SDHCI DMA modes? If so, I wonder if this is because the upstream kernel doesn't deal with the bcm2835's ARM physical address <-> SoC bus address conversions, which in turn can cause DMA and CPU access to not use the same caching settings and become incoherent, which in turn can cause DMA data corruption. See the following link for some background:
> 
> https://www.mail-archive.com/u-boot@lists.denx.de/msg167376.html
> [PATCH 2/3] ARM: bcm2835: implement phys_to_bus/bus_to_phys
> 
> (you'll want to read all of patches 1-3 for the complete background I think, but patch 2 describes the HW issue)

I can also just patch out the assignement to dev_dma here and it works as well:
	if (spi->master->dev.parent->dma_mask) {
		struct device   *dev = spi->master->dev.parent;

		host->dma_dev = dev;
		host->ones_dma = dma_map_single(dev, ones,
				MMC_SPI_BLOCKSIZE, DMA_TO_DEVICE);
		host->data_dma = dma_map_single(dev, host->data,
				sizeof(*host->data), DMA_BIDIRECTIONAL);
So DMA there is not an issue with SDHCI - it is just when using the
"normal" spi-bcm2835 that I can reproduce it.

If you read the mmc_spi driver there is a lot of places where we have 
constructs like this:
        if (host->dma_dev) {
                host->m.is_dma_mapped = 1;
                dma_sync_single_for_device(host->dma_dev,
                                host->data_dma, sizeof(*host->data),
                                DMA_BIDIRECTIONAL);
        }
        status = spi_sync_locked(host->spi, &host->m);

        if (host->dma_dev)
                dma_sync_single_for_cpu(host->dma_dev,
                                host->data_dma, sizeof(*host->data),
                                DMA_BIDIRECTIONAL);

Similar constructs exist for: dma_map_page and dma_unmap_page.

As far as I can tell these are the "typical" dma-related calls.

But the point is that the spi-bcm2835 driver does not implement DMA (yet),
so some things may not be fully set up for mapping inside 
spi->master->dev.parent and some mapping options may fail/not work as
expected. This may results in possibly "bad" behavior, just because dma_mask
 is set.

So i am not sure if this "mapping" issue you are mentioning is really the
root-cause - also I test on a RPI1, but have also tried on a RPI2 with the 
foundation kernel.

On top my reading/experience with DMA on the bcm2835 is that I was always
using 0xC0000000 as the bus-address, as the L1/L2 addresses in the
documentation are only related to VideoCore caches - and that is I guess
why the "L2 preload" is explicitly mentioned in the documentation - probably
to speed up the GPU by  prefetching the necessary data via DMA and thus 
avoiding to wait for data to get read from SRAM.

Unfortunately I can not test if the the mmc_spi issue exists on a
beaglebone, as the mmc_spi driver can not even get compiled there because
of CONFIG_HIGHMEM being set which conflicts with KConfig portion for
mmc_spi...


Ciao,
	Martin





More information about the linux-rpi-kernel mailing list