On 04/01/2017 08:05 PM, Simon Glass wrote:
> On Raspberry Pi 2 and 3 a problem was noticed when enabling driver model
> for USB: the cache invalidate after an incoming transfer does not seem to
> work correctly.
> 
> This may be a problem with the underlying caching implementation on armv7
> and armv8 but this seems very unlikely. As a work-around, use separate
> buffers for input and output. This ensures that the input buffer will not
> hold dirty cache data.

What do you think of this patch:
[U-Boot] usb: dwc2: invalidate the dcache before starting the DMA

> Signed-off-by: Simon Glass <s...@chromium.org>
> ---
> 
> Changes in v5:
> - Add new patch for dwc2 to se separate input and output buffers
> 
> Changes in v4: None
> Changes in v3: None
> 
>  drivers/usb/host/dwc2.c | 27 ++++++++++++++++++++-------
>  1 file changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
> index d253b946f3..a65ed4f66c 100644
> --- a/drivers/usb/host/dwc2.c
> +++ b/drivers/usb/host/dwc2.c
> @@ -31,10 +31,14 @@ DECLARE_GLOBAL_DATA_PTR;
>  
>  struct dwc2_priv {
>  #ifdef CONFIG_DM_USB
> -     uint8_t aligned_buffer[DWC2_DATA_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
> +     uint8_t aligned_buffer_in[DWC2_DATA_BUF_SIZE]
> +                     __aligned(ARCH_DMA_MINALIGN);
> +     uint8_t aligned_buffer_out[DWC2_DATA_BUF_SIZE]
> +                     __aligned(ARCH_DMA_MINALIGN);
>       uint8_t status_buffer[DWC2_STATUS_BUF_SIZE] 
> __aligned(ARCH_DMA_MINALIGN);
>  #else
> -     uint8_t *aligned_buffer;
> +     uint8_t *aligned_buffer_in;
> +     uint8_t *aligned_buffer_out;
>       uint8_t *status_buffer;
>  #endif
>       u8 in_data_toggle[MAX_DEVICE][MAX_ENDPOINT];
> @@ -769,10 +773,12 @@ static int dwc2_eptype[] = {
>       DWC2_HCCHAR_EPTYPE_BULK,
>  };
>  
> -static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void *aligned_buffer,
> -                       u8 *pid, int in, void *buffer, int num_packets,
> -                       int xfer_len, int *actual_len, int odd_frame)
> +static int transfer_chunk(struct dwc2_hc_regs *hc_regs, void 
> *aligned_buffer_in,
> +                       void *aligned_buffer_out, u8 *pid, int in,
> +                       void *buffer, int num_packets, int xfer_len,
> +                       int *actual_len, int odd_frame)
>  {
> +     void *aligned_buffer;
>       int ret = 0;
>       uint32_t sub;
>  
> @@ -785,11 +791,14 @@ static int transfer_chunk(struct dwc2_hc_regs *hc_regs, 
> void *aligned_buffer,
>              &hc_regs->hctsiz);
>  
>       if (!in && xfer_len) {
> +             aligned_buffer = aligned_buffer_in;
>               memcpy(aligned_buffer, buffer, xfer_len);
>  
>               flush_dcache_range((unsigned long)aligned_buffer,
>                                  (unsigned long)aligned_buffer +
>                                  roundup(xfer_len, ARCH_DMA_MINALIGN));
> +     } else {
> +             aligned_buffer = aligned_buffer_out;
>       }
>  
>       writel(phys_to_bus((unsigned long)aligned_buffer), &hc_regs->hcdma);
> @@ -901,7 +910,8 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device 
> *dev,
>                               odd_frame = 1;
>               }
>  
> -             ret = transfer_chunk(hc_regs, priv->aligned_buffer, pid,
> +             ret = transfer_chunk(hc_regs, priv->aligned_buffer_in,
> +                                  priv->aligned_buffer_out, pid,
>                                    in, (char *)buffer + done, num_packets,
>                                    xfer_len, &actual_len, odd_frame);
>  
> @@ -1136,7 +1146,10 @@ int usb_lowlevel_init(int index, enum usb_init_type 
> init, void **controller)
>       memset(priv, '\0', sizeof(*priv));
>       priv->root_hub_devnum = 0;
>       priv->regs = (struct dwc2_core_regs *)CONFIG_USB_DWC2_REG_ADDR;
> -     priv->aligned_buffer = aligned_buffer_addr;
> +
> +     /* We can use the same buffer for input and output */
> +     priv->aligned_buffer_in = aligned_buffer_addr;
> +     priv->aligned_buffer_out = aligned_buffer_addr;
>       priv->status_buffer = status_buffer_addr;
>  
>       /* board-dependant init */
> 


-- 
Best regards,
Marek Vasut
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to