From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Tue, 3 Oct 2017 14:04:26 +0200 Subject: [U-Boot] [PATCH] dwc: ep0: Allocate and flush dwc->ep0_trb in a cache aligned manner In-Reply-To: <1505819741-29843-1-git-send-email-faiz_abbas@ti.com> References: <1505819741-29843-1-git-send-email-faiz_abbas@ti.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 On 09/19/2017 01:15 PM, Faiz Abbas wrote: > A flush of the cache is required before any DMA access can take place. You mean invalidation for inbound DMA, flush for outbound DMA, right ? > The minimum size that can be flushed from the cache is one cache line > size. Therefore, any buffer allocated for DMA should be in multiples > of cache line size. > > Thus, allocate memory for ep0_trb in multiples of cache line size. > > Also, when local variable trb is assigned to dwc->ep0_trb[1] and used > to flush cache, it leads to cache misaligned messages as only the base > address dwc->ep0_trb is cache aligned. > > Therefore, flush cache using ep0_trb_addr which is always cache aligned. > > Signed-off-by: Faiz Abbas > --- > drivers/usb/dwc3/ep0.c | 7 ++++--- > drivers/usb/dwc3/gadget.c | 3 ++- > 2 files changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c > index e61d980..f3a17a1 100644 > --- a/drivers/usb/dwc3/ep0.c > +++ b/drivers/usb/dwc3/ep0.c > @@ -82,7 +82,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma, > | DWC3_TRB_CTRL_LST); > > dwc3_flush_cache((uintptr_t)buf_dma, len); > - dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); > + dwc3_flush_cache((uintptr_t)dwc->ep0_trb_addr, sizeof(*trb) * 2); > > if (chain) > return 0; > @@ -790,7 +790,7 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, > if (!r) > return; > > - dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); > + dwc3_flush_cache((uintptr_t)dwc->ep0_trb_addr, sizeof(*trb) * 2); Why *2 ? > status = DWC3_TRB_SIZE_TRBSTS(trb->size); > if (status == DWC3_TRBSTS_SETUP_PENDING) { > @@ -821,7 +821,8 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, > ur->actual += transferred; > > trb++; > - dwc3_flush_cache((uintptr_t)trb, sizeof(*trb)); > + dwc3_flush_cache((uintptr_t)dwc->ep0_trb_addr, > + sizeof(*trb) * 2); > length = trb->size & DWC3_TRB_SIZE_MASK; > > ep0->free_slot = 0; > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index e065c5a..895a5bc 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -2567,7 +2567,8 @@ int dwc3_gadget_init(struct dwc3 *dwc) > goto err0; > } > > - dwc->ep0_trb = dma_alloc_coherent(sizeof(*dwc->ep0_trb) * 2, > + dwc->ep0_trb = dma_alloc_coherent(ROUND(sizeof(*dwc->ep0_trb) * 2, > + CACHELINE_SIZE), AFAIU dma_alloc_coherent() should mark the memory area uncachable . > (unsigned long *)&dwc->ep0_trb_addr); > if (!dwc->ep0_trb) { > dev_err(dwc->dev, "failed to allocate ep0 trb\n"); > -- Best regards, Marek Vasut