[U-Boot] [PATCH v2] usb: dwc3: Allocate and flush dwc->ep0_trb in a cache aligned manner
Marek Vasut
marex at denx.de
Mon Oct 16 10:12:33 UTC 2017
On 10/16/2017 07:21 AM, Faiz Abbas wrote:
> A flush of the cache is required before any outbound DMA access can
> take place. 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 <faiz_abbas at ti.com>
SGTM, Felipe, can you review this please ?
> ---
>
> v2:
> 1. Fixed the subject line tags
> 2. Shifted the flush cache statements to below the check on chain
>
> drivers/usb/dwc3/ep0.c | 11 ++++++-----
> drivers/usb/dwc3/gadget.c | 3 ++-
> 2 files changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> index e61d980..d4cc725 100644
> --- a/drivers/usb/dwc3/ep0.c
> +++ b/drivers/usb/dwc3/ep0.c
> @@ -81,12 +81,12 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
> trb->ctrl |= (DWC3_TRB_CTRL_IOC
> | DWC3_TRB_CTRL_LST);
>
> - dwc3_flush_cache((uintptr_t)buf_dma, len);
> - dwc3_flush_cache((uintptr_t)trb, sizeof(*trb));
> -
> if (chain)
> return 0;
>
> + dwc3_flush_cache((uintptr_t)buf_dma, len);
> + dwc3_flush_cache((uintptr_t)dwc->ep0_trb_addr, sizeof(*trb) * 2);
> +
> memset(¶ms, 0, sizeof(params));
> params.param0 = upper_32_bits(dwc->ep0_trb_addr);
> params.param1 = lower_32_bits(dwc->ep0_trb_addr);
> @@ -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);
>
> 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),
> (unsigned long *)&dwc->ep0_trb_addr);
> if (!dwc->ep0_trb) {
> dev_err(dwc->dev, "failed to allocate ep0 trb\n");
>
--
Best regards,
Marek Vasut
More information about the U-Boot
mailing list