Messages in this thread Patch in this message | | | From | Matthew Leon <> | Date | Mon, 30 Jul 2018 03:11:59 +0000 | Subject | Re: [PATCH mmc-next v3 3/3] mmc: sdhci-of-dwcmshc: solve 128MB DMA boundary limitation |
| |
<div dir="ltr"> <span class="gmail-im">>> Hey Jisheng,<br> <br>>Hi,<br> <br> >> <br> <br> >In LKML, we'd better not top post.<br> <span class="gmail-m_8245690094374767092gmail-im"></span><div><br></div></span><div>Noted. My apologies.<br></div><span class="gmail-im"><div><br></div><span class="gmail-m_8245690094374767092gmail-im"> >> Shouldn't we be splitting until all DMA blocks are less than 128M boundary?<br> >> I am a noob, but I think we should be prepared for boundaries that when<br> >> split in two, will still be greater than 128M. Feel free to disagree but<br> >> please explain why I may be wrong. Thank-you.<br> <br> </span>>the limitation is "DMA addr can't span 128MB boundary" rather than "must be<br> >less than 128MB", they are different.<br> <br> >And the max transfer size of one DMA desc is 64KB.<br> <br><div> >thanks <br></div><div><br></div></span><div>I have misspoken. What if the DMA transfer size is 1024M? If we split in two, then we have 2 transfers, each of which span 512M. So wouldn't we need to split again to have 4 transfers, each of which span 128M?</div><div><br></div><div>Sincerely,<br></div><div>Matthew Leon</div>
<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 29, 2018 at 10:59 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">On Mon, 30 Jul 2018 02:56:20 +0000 Matthew Leon <<a href="mailto:matthewleon@linux.com">matthewleon@linux.com</a>> wrote:<br> <br> > Hey Jisheng,<br> <br> Hi,<br> <br> > <br> <br> In LKML, we'd better not top post.<br> <span class=""><br> > Shouldn't we be splitting until all DMA blocks are less than 128M boundary?<br> > I am a noob, but I think we should be prepared for boundaries that when<br> > split in two, will still be greater than 128M. Feel free to disagree but<br> > please explain why I may be wrong. Thank-you.<br> <br> </span>the limitation is "DMA addr can't span 128MB boundary" rather than "must be<br> less than 128MB", they are different.<br> <br> And the max transfer size of one DMA desc is 64KB.<br> <br> thanks<br> <div class="HOEnZb"><div class="h5"><br> > <br> > Sincerely,<br> > Matthew Leon<br> > <br> > On Sun, Jul 29, 2018 at 10:46 PM, Jisheng Zhang <<a href="mailto:Jisheng.Zhang@synaptics.com">Jisheng.Zhang@synaptics.com</a><br> > > wrote: <br> > <br> > > 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<br> > > 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> > ><br> > > --<br> > > 2.18.0<br> > ><br> > > <br> <br> </div></div></blockquote></div><br></div>
| |