Re: [PATCH 4/4] mmc: sdhci: Add DMA memory boundary workaround

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
> 





[Index of Archives]     [Linux Memonry Technology]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux