From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kever Yang Date: Wed, 5 Apr 2017 09:26:35 +0800 Subject: [U-Boot] usb: dwc2: invalidate the dcache before starting the DMA In-Reply-To: <20170401065139.12084-1-eddie.cai.linux@gmail.com> References: <20170401065139.12084-1-eddie.cai.linux@gmail.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Eddie, We should only need to do only one time cache operation for a buffer ready to do DMA transfer, so you need to remove another cache invalidate operation for the same buffer in the same function. Thanks, - Kever On 04/01/2017 02:51 PM, Eddie Cai wrote: > We should invalidate the dcache before starting the DMA. In case there are > any dirty lines from the DMA buffer in the cache, subsequent cache-line > replacements may corrupt the buffer in memory while the DMA is still going on. > Cache-line replacement can happen if the CPU tries to bring some other memory > locations into the cache while the DMA is going on. > > Signed-off-by: Eddie Cai > --- > drivers/usb/host/dwc2.c | 17 +++++++++++------ > 1 file changed, 11 insertions(+), 6 deletions(-) > > diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c > index 5ac602e..a151ba6 100644 > --- a/drivers/usb/host/dwc2.c > +++ b/drivers/usb/host/dwc2.c > @@ -811,12 +811,17 @@ static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer, > (*pid << DWC2_HCTSIZ_PID_OFFSET), > &hc_regs->hctsiz); > > - if (!in && xfer_len) { > - memcpy(aligned_buffer, buffer, xfer_len); > - > - flush_dcache_range((unsigned long)aligned_buffer, > - (unsigned long)aligned_buffer + > - roundup(xfer_len, ARCH_DMA_MINALIGN)); > + if (xfer_len) { > + if(in){ > + invalidate_dcache_range((unsigned long)aligned_buffer, > + (unsigned long)aligned_buffer + > + roundup(xfer_len, ARCH_DMA_MINALIGN)); > + }else{ > + memcpy(aligned_buffer, buffer, xfer_len); > + flush_dcache_range((unsigned long)aligned_buffer, > + (unsigned long)aligned_buffer + > + roundup(xfer_len, ARCH_DMA_MINALIGN)); > + } > } > > writel(phys_to_bus((unsigned long)aligned_buffer), &hc_regs->hcdma);