summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Stein <alexanders83@web.de>2015-07-24 09:22:14 +0200
committerTom Rini <trini@konsulko.com>2015-08-12 20:47:43 -0400
commitdb402e005a7db7c60811deb199e0df3eec479601 (patch)
tree0ce73a198b257c93814435968de67f6b1b4999d2
parent4342557fad308dd4ca8f9c2e74ea4f2dbddd5685 (diff)
dwc2: Add dcache support
This adds dcache support for dwc2. The DMA buffers must be DMA aligned and is flushed for outgoing transactions before starting transfer. For ingoing transactions it is invalidated after the transfer has finished. Signed-off-by: Alexander Stein <alexanders83@web.de> Acked-by: Stephen Warren <swarren@wwwdotorg.org> [trini: Update to apply again on top of DM patches] Signed-off-by: Tom Rini <trini@konsulko.com>
-rw-r--r--drivers/usb/host/dwc2.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 702ef63f87..09f91f190a 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -27,8 +27,8 @@
struct dwc2_priv {
#ifdef CONFIG_DM_USB
- uint8_t aligned_buffer[DWC2_DATA_BUF_SIZE] __aligned(8);
- uint8_t status_buffer[DWC2_STATUS_BUF_SIZE] __aligned(8);
+ uint8_t aligned_buffer[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 *status_buffer;
@@ -39,9 +39,11 @@ struct dwc2_priv {
};
#ifndef CONFIG_DM_USB
-/* We need doubleword-aligned buffers for DMA transfers */
-DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer_addr, DWC2_DATA_BUF_SIZE, 8);
-DEFINE_ALIGN_BUFFER(uint8_t, status_buffer_addr, DWC2_STATUS_BUF_SIZE, 8);
+/* We need cacheline-aligned buffers for DMA transfers and dcache support */
+DEFINE_ALIGN_BUFFER(uint8_t, aligned_buffer_addr, DWC2_DATA_BUF_SIZE,
+ ARCH_DMA_MINALIGN);
+DEFINE_ALIGN_BUFFER(uint8_t, status_buffer_addr, DWC2_STATUS_BUF_SIZE,
+ ARCH_DMA_MINALIGN);
static struct dwc2_priv local;
#endif
@@ -821,8 +823,11 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev,
&hc_regs->hctsiz);
if (!in) {
- memcpy(priv->aligned_buffer, (char *)buffer + done,
- len);
+ memcpy(priv->aligned_buffer, (char *)buffer + done, len);
+
+ flush_dcache_range((unsigned long)priv->aligned_buffer,
+ (unsigned long)((void *)priv->aligned_buffer +
+ roundup(len, ARCH_DMA_MINALIGN)));
}
writel(phys_to_bus((unsigned long)priv->aligned_buffer),
@@ -840,6 +845,11 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device *dev,
if (in) {
xfer_len -= sub;
+
+ invalidate_dcache_range((unsigned long)priv->aligned_buffer,
+ (unsigned long)((void *)priv->aligned_buffer +
+ roundup(xfer_len, ARCH_DMA_MINALIGN)));
+
memcpy(buffer + done, priv->aligned_buffer, xfer_len);
if (sub)
stop_transfer = 1;