Messages in this thread Patch in this message | | | From | Matthew Leon <> | Date | Mon, 30 Jul 2018 02:56:20 +0000 | Subject | Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation |
| |
<div dir="ltr"><div>Hey Jisheng,</div><div><br></div><div>Shouldn't we be splitting until all DMA blocks are less than 128M boundary? I am a noob, but I think we should be prepared for boundaries that when split in two, will still be greater than 128M. Feel free to disagree but please explain why I may be wrong. Thank-you.<br></div><div><br></div><div>Sincerely,</div><div>Matthew Leon<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang <span dir="ltr"><<a href="mailto:Jisheng.Zhang@synaptics.com" target="_blank">Jisheng.Zhang@synaptics.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">When using DMA, if the DMA addr spans 128MB boundary, we have to split<br> the DMA transfer into two so that each one doesn't exceed the boundary.<br> <br> Signed-off-by: Jisheng Zhang <<a href="mailto:Jisheng.Zhang@synaptics.com">Jisheng.Zhang@synaptics.com</a>><br> ---<br> drivers/mmc/host/sdhci-of-<wbr>dwcmshc.c | 43 +++++++++++++++++++++++++++++<br> 1 file changed, 43 insertions(+)<br> <br> diff --git a/drivers/mmc/host/sdhci-of-<wbr>dwcmshc.c b/drivers/mmc/host/sdhci-of-<wbr>dwcmshc.c<br> index 1b7cd144fb01..e890fc8f5284 100644<br> --- a/drivers/mmc/host/sdhci-of-<wbr>dwcmshc.c<br> +++ b/drivers/mmc/host/sdhci-of-<wbr>dwcmshc.c<br> @@ -8,21 +8,52 @@<br> */<br> <br> #include <linux/clk.h><br> +#include <linux/mm.h><br> #include <linux/module.h><br> #include <linux/of.h><br> +#include <linux/sizes.h><br> <br> #include "sdhci-pltfm.h"<br> <br> +#define BOUNDARY_OK(addr, len) \<br> + ((addr | (SZ_128M - 1)) == ((addr + len - 1) | (SZ_128M - 1)))<br> +<br> struct dwcmshc_priv {<br> struct clk *bus_clk;<br> };<br> <br> +/*<br> + * if DMA addr spans 128MB boundary, we split the DMA transfer into two<br> + * so that the DMA transfer doesn't exceed the boundary.<br> + */<br> +static unsigned int dwcmshc_adma_write_desc(struct sdhci_host *host,<br> + void *desc, dma_addr_t addr,<br> + int len, unsigned int cmd)<br> +{<br> + int tmplen, offset;<br> +<br> + if (likely(!len || BOUNDARY_OK(addr, len)))<br> + return _sdhci_adma_write_desc(host, desc, addr, len, cmd);<br> +<br> + offset = addr & (SZ_128M - 1);<br> + tmplen = SZ_128M - offset;<br> + _sdhci_adma_write_desc(host, desc, addr, tmplen, cmd);<br> +<br> + addr += tmplen;<br> + len -= tmplen;<br> + desc += host->desc_sz;<br> + _sdhci_adma_write_desc(host, desc, addr, len, cmd);<br> +<br> + return host->desc_sz * 2;<br> +}<br> +<br> static const struct sdhci_ops sdhci_dwcmshc_ops = {<br> .set_clock = sdhci_set_clock,<br> .set_bus_width = sdhci_set_bus_width,<br> .set_uhs_signaling = sdhci_set_uhs_signaling,<br> .get_max_clock = sdhci_pltfm_clk_get_max_clock,<br> .reset = sdhci_reset,<br> + .adma_write_desc = dwcmshc_adma_write_desc,<br> };<br> <br> static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = {<br> @@ -36,12 +67,24 @@ static int dwcmshc_probe(struct platform_device *pdev)<br> struct sdhci_host *host;<br> struct dwcmshc_priv *priv;<br> int err;<br> + u32 extra;<br> <br> host = sdhci_pltfm_init(pdev, &sdhci_dwcmshc_pdata,<br> sizeof(struct dwcmshc_priv));<br> if (IS_ERR(host))<br> return PTR_ERR(host);<br> <br> + /*<br> + * The DMA descriptor table number is calculated as the maximum<br> + * number of segments times 2, to allow for an alignment<br> + * descriptor for each segment, plus 1 for a nop end descriptor,<br> + * plus extra number for cross 128M boundary handling.<br> + */<br> + extra = DIV_ROUND_UP(totalram_pages, SZ_128M / PAGE_SIZE);<br> + if (extra > SDHCI_MAX_SEGS)<br> + extra = SDHCI_MAX_SEGS;<br> + host->adma_table_num = SDHCI_MAX_SEGS * 2 + 1 + extra;<br> +<br> pltfm_host = sdhci_priv(host);<br> priv = sdhci_pltfm_priv(pltfm_host);<br> <span class="HOEnZb"><font color="#888888"> <br> -- <br> 2.18.0<br> <br> </font></span></blockquote></div><br></div>
| |