On 13/11/2019 08:53, Linus Walleij wrote: > The Ux500 (at least) can only deal with DMA transactions > starting and ending on an even 4-byte aligned address. > > The problem isn't in the DMA engine of the system as such: > the problem is in the state machine of the MMCI block that > has some features to handle single bytes but it seems like > it doesn't quite work. > > This problem is probably caused by most of the testing > being done on mass storage, which will be 512-bytes aligned > blocks placed neatly in pages and practically never run into > this situation. > > On SDIO (for example in WiFi adapters) this situation is > common. > > By avoiding any such transfers with a special vendor flag, > we can bail out to PIO when an odd transfer is detected > while keeping DMA for large transfers of evenly aligned > packages also for SDIO. > > Cc: Ludovic Barre <ludovic.barre@xxxxxx> > Cc: Brian Masney <masneyb@xxxxxxxxxxxxx> > Cc: Stephan Gerhold <stephan@xxxxxxxxxxx> > Cc: Niklas Cassel <niklas.cassel@xxxxxxxxxx> > Cc: Russell King <rmk+kernel@xxxxxxxxxxxxxxx> > Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> > --- > ChangeLog v1->v3: > - New patch in v3 after discussion with Ulf > --- > drivers/mmc/host/mmci.c | 21 +++++++++++++++++++++ > drivers/mmc/host/mmci.h | 10 ++++++++++ > 2 files changed, 31 insertions(+) > > diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c > index 3ffcdf78a428..a08cd845dddc 100644 > --- a/drivers/mmc/host/mmci.c > +++ b/drivers/mmc/host/mmci.c > @@ -185,6 +185,7 @@ static struct variant_data variant_ux500 = { > .irq_pio_mask = MCI_IRQ_PIO_MASK, > .start_err = MCI_STARTBITERR, > .opendrain = MCI_OD, > + .only_long_aligned_dma = true, > .init = mmci_variant_init, > }; > > @@ -219,6 +220,7 @@ static struct variant_data variant_ux500v2 = { > .irq_pio_mask = MCI_IRQ_PIO_MASK, > .start_err = MCI_STARTBITERR, > .opendrain = MCI_OD, > + .only_long_aligned_dma = true, > .init = ux500v2_variant_init, > }; > > @@ -829,6 +831,25 @@ static int _mmci_dmae_prep_data(struct mmci_host *host, struct mmc_data *data, > if (data->blksz * data->blocks <= variant->fifosize) > return -EINVAL; > > + /* > + * Handle the variants with DMA that is broken such that start and > + * end address must be aligned on a long (32bit) boundary for the DMA > + * to work. If this occurs, fall back to PIO. > + */ Nit: why use 'long' as a synonym for "32 bits" ? Why not name the field "only_32b_aligned_dma" ? (The size of C's long int is implementation-defined; most 64-bit platforms have a 64-bit long int.) Perhaps the ship has already sailed -- what with readl/writel... Regards.