On Mon, 2 Dec 2019 22:41:04 +0800 Jun Nie wrote: > > > DMA memory cannot cross specific boundary for some SDHCI controller, > such as DesignWare SDHCI controller. Add DMA memory boundary dt > property and workaround the limitation. IMHO, the workaround could be implemented in each SDHCI host driver. eg. drivers/mmc/host/sdhci-of-dwcmshc.c thanks > > Signed-off-by: Jun Nie <jun.nie@xxxxxxxxxx> > --- > drivers/mmc/host/sdhci.c | 20 +++++++++++++++++++- > drivers/mmc/host/sdhci.h | 1 + > 2 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c > index d8a6c1c91448..56c53fbadd9d 100644 > --- a/drivers/mmc/host/sdhci.c > +++ b/drivers/mmc/host/sdhci.c > @@ -763,9 +763,25 @@ static void sdhci_adma_table_pre(struct sdhci_host *host, > BUG_ON(len > 65536); > > /* tran, valid */ > - if (len) > + if (len) { > + unsigned int boundary = host->dma_mem_boundary; > + /* > + * work around for buffer across mem boundary, split > + * the buffer. > + */ > + if (boundary && > + ((addr & (boundary - 1)) + len) > boundary) { > + offset = boundary - (addr & (boundary - 1)); > + __sdhci_adma_write_desc(host, &desc, > + addr, offset, > + ADMA2_TRAN_VALID); > + addr += offset; > + len -= offset; > + } > + > __sdhci_adma_write_desc(host, &desc, addr, len, > ADMA2_TRAN_VALID); > + } > > /* > * If this triggers then we have a calculation bug > @@ -3634,6 +3650,8 @@ void __sdhci_read_caps(struct sdhci_host *host, const u16 *ver, > "sdhci-caps-mask", &dt_caps_mask); > of_property_read_u64(mmc_dev(host->mmc)->of_node, > "sdhci-caps", &dt_caps); > + of_property_read_u32(mmc_dev(host->mmc)->of_node, > + "sdhci-dma-mem-boundary", &host->dma_mem_boundary); > > if (of_property_read_u32(mmc_dev(host->mmc)->of_node, > "sdhci-ctrl-hs400", &host->sdhci_ctrl_hs400)) > diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h > index cac4d819f62c..954ac08c4fb0 100644 > --- a/drivers/mmc/host/sdhci.h > +++ b/drivers/mmc/host/sdhci.h > @@ -608,6 +608,7 @@ struct sdhci_host { > > /* SDHCI_CTRL_HS400 value */ > u32 sdhci_ctrl_hs400; > + u32 dma_mem_boundary; > > unsigned long private[0] ____cacheline_aligned; > }; > -- > 2.17.1 >