Merge branch '2020-05-08-assorted-fixes'
[oweals/u-boot.git] / drivers / usb / gadget / dwc2_udc_otg_xfer_dma.c
index b6164afa9245a6c78775c65a7b90e4a76bf5000d..d4fbb75cc9bcb318ca9bcc05fd8afea17b652de0 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
  * Designware DWC2 on-chip full/high speed USB OTG 2.0 device controllers
  * Ported to u-boot:
  * Marek Szyprowski <m.szyprowski@samsung.com>
  * Lukasz Majewski <l.majewski@samsumg.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#include <common.h>
+#include <cpu_func.h>
+
 static u8 clear_feature_num;
 int clear_feature_flag;
 
@@ -29,7 +31,7 @@ static inline void dwc2_udc_ep0_zlp(struct dwc2_udc *dev)
 {
        u32 ep_ctrl;
 
-       writel(usb_ctrl_dma_addr, &reg->in_endp[EP0_CON].diepdma);
+       writel(phys_to_bus((unsigned long)usb_ctrl_dma_addr), &reg->in_endp[EP0_CON].diepdma);
        writel(DIEPT_SIZ_PKT_CNT(1), &reg->in_endp[EP0_CON].dieptsiz);
 
        ep_ctrl = readl(&reg->in_endp[EP0_CON].diepctl);
@@ -50,7 +52,7 @@ static void dwc2_udc_pre_setup(void)
 
        writel(DOEPT_SIZ_PKT_CNT(1) | sizeof(struct usb_ctrlrequest),
               &reg->out_endp[EP0_CON].doeptsiz);
-       writel(usb_ctrl_dma_addr, &reg->out_endp[EP0_CON].doepdma);
+       writel(phys_to_bus((unsigned long)usb_ctrl_dma_addr), &reg->out_endp[EP0_CON].doepdma);
 
        ep_ctrl = readl(&reg->out_endp[EP0_CON].doepctl);
        writel(ep_ctrl|DEPCTL_EPENA, &reg->out_endp[EP0_CON].doepctl);
@@ -76,7 +78,7 @@ static inline void dwc2_ep0_complete_out(void)
 
        writel(DOEPT_SIZ_PKT_CNT(1) | sizeof(struct usb_ctrlrequest),
               &reg->out_endp[EP0_CON].doeptsiz);
-       writel(usb_ctrl_dma_addr, &reg->out_endp[EP0_CON].doepdma);
+       writel(phys_to_bus((unsigned long)usb_ctrl_dma_addr), &reg->out_endp[EP0_CON].doepdma);
 
        ep_ctrl = readl(&reg->out_endp[EP0_CON].doepctl);
        writel(ep_ctrl|DEPCTL_EPENA|DEPCTL_CNAK,
@@ -114,7 +116,7 @@ static int setdma_rx(struct dwc2_ep *ep, struct dwc2_request *req)
                                (unsigned long) ep->dma_buf +
                                ROUND(ep->len, CONFIG_SYS_CACHELINE_SIZE));
 
-       writel((unsigned int) ep->dma_buf, &reg->out_endp[ep_num].doepdma);
+       writel(phys_to_bus((unsigned long)ep->dma_buf), &reg->out_endp[ep_num].doepdma);
        writel(DOEPT_SIZ_PKT_CNT(pktcnt) | DOEPT_SIZ_XFER_SIZE(length),
               &reg->out_endp[ep_num].doeptsiz);
        writel(DEPCTL_EPENA|DEPCTL_CNAK|ctrl, &reg->out_endp[ep_num].doepctl);
@@ -162,7 +164,7 @@ static int setdma_tx(struct dwc2_ep *ep, struct dwc2_request *req)
        while (readl(&reg->grstctl) & TX_FIFO_FLUSH)
                ;
 
-       writel((unsigned long) ep->dma_buf, &reg->in_endp[ep_num].diepdma);
+       writel(phys_to_bus((unsigned long)ep->dma_buf), &reg->in_endp[ep_num].diepdma);
        writel(DIEPT_SIZ_PKT_CNT(pktcnt) | DIEPT_SIZ_XFER_SIZE(length),
               &reg->in_endp[ep_num].dieptsiz);
 
@@ -468,7 +470,7 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
 static int dwc2_udc_irq(int irq, void *_dev)
 {
        struct dwc2_udc *dev = _dev;
-       u32 intr_status;
+       u32 intr_status, gotgint;
        u32 usb_status, gintmsk;
        unsigned long flags = 0;
 
@@ -522,14 +524,24 @@ static int dwc2_udc_irq(int irq, void *_dev)
                    && dev->driver) {
                        if (dev->driver->suspend)
                                dev->driver->suspend(&dev->gadget);
+               }
+       }
+
+       if (intr_status & INT_OTG) {
+               gotgint = readl(&reg->gotgint);
+               debug_cond(DEBUG_ISR,
+                          "\tOTG interrupt: (GOTGINT):0x%x\n", gotgint);
 
-                       /* HACK to let gadget detect disconnected state */
+               if (gotgint & GOTGINT_SES_END_DET) {
+                       debug_cond(DEBUG_ISR, "\t\tSession End Detected\n");
+                       /* Let gadget detect disconnected state */
                        if (dev->driver->disconnect) {
                                spin_unlock_irqrestore(&dev->lock, flags);
                                dev->driver->disconnect(&dev->gadget);
                                spin_lock_irqsave(&dev->lock, flags);
                        }
                }
+               writel(gotgint, &reg->gotgint);
        }
 
        if (intr_status & INT_RESUME) {
@@ -722,7 +734,7 @@ static int write_fifo_ep0(struct dwc2_ep *ep, struct dwc2_request *req)
        return 0;
 }
 
-static int dwc2_fifo_read(struct dwc2_ep *ep, u32 *cp, int max)
+static int dwc2_fifo_read(struct dwc2_ep *ep, void *cp, int max)
 {
        invalidate_dcache_range((unsigned long)cp, (unsigned long)cp +
                                ROUND(max, CONFIG_SYS_CACHELINE_SIZE));
@@ -912,7 +924,7 @@ static int dwc2_udc_get_status(struct dwc2_udc *dev,
                           (unsigned long) usb_ctrl +
                           ROUND(sizeof(g_status), CONFIG_SYS_CACHELINE_SIZE));
 
-       writel(usb_ctrl_dma_addr, &reg->in_endp[EP0_CON].diepdma);
+       writel(phys_to_bus(usb_ctrl_dma_addr), &reg->in_endp[EP0_CON].diepdma);
        writel(DIEPT_SIZ_PKT_CNT(1) | DIEPT_SIZ_XFER_SIZE(2),
               &reg->in_endp[EP0_CON].dieptsiz);
 
@@ -1276,7 +1288,7 @@ static void dwc2_ep0_setup(struct dwc2_udc *dev)
        nuke(ep, -EPROTO);
 
        /* read control req from fifo (8 bytes) */
-       dwc2_fifo_read(ep, (u32 *)usb_ctrl, 8);
+       dwc2_fifo_read(ep, usb_ctrl, 8);
 
        debug_cond(DEBUG_SETUP != 0,
                   "%s: bRequestType = 0x%x(%s), bRequest = 0x%x"