usb: dwc2: gadget: Update for new usb_endpoint_maxp()
authorVardan Mikayelyan <mvardan@synopsys.com>
Tue, 8 Nov 2016 18:57:00 +0000 (10:57 -0800)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 18 Nov 2016 11:54:15 +0000 (13:54 +0200)
Update the dwc2 driver for the new behavior of the usb_endpoint_maxp()
and also use the new usb_endpoint_maxp_mult() helper function.

This commit fixes failures in high-badwith ISOC transfer tests.

Signed-off-by: Vardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: John Youn <johnyoun@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc2/gadget.c

index 8a7fd73721d73ffa2fc583f753359363544a6bd7..1ba0bfc9e5815d22e7991ab524e2f7737a4936f9 100644 (file)
@@ -1812,17 +1812,17 @@ static u32 dwc2_hsotg_ep0_mps(unsigned int mps)
  * @hsotg: The driver state.
  * @ep: The index number of the endpoint
  * @mps: The maximum packet size in bytes
+ * @mc: The multicount value
  *
  * Configure the maximum packet size for the given endpoint, updating
  * the hardware control registers to reflect this.
  */
 static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
-                       unsigned int ep, unsigned int mps, unsigned int dir_in)
+                                       unsigned int ep, unsigned int mps,
+                                       unsigned int mc, unsigned int dir_in)
 {
        struct dwc2_hsotg_ep *hs_ep;
        void __iomem *regs = hsotg->regs;
-       u32 mpsval;
-       u32 mcval;
        u32 reg;
 
        hs_ep = index_to_ep(hsotg, ep, dir_in);
@@ -1830,32 +1830,32 @@ static void dwc2_hsotg_set_ep_maxpacket(struct dwc2_hsotg *hsotg,
                return;
 
        if (ep == 0) {
+               u32 mps_bytes = mps;
+
                /* EP0 is a special case */
-               mpsval = dwc2_hsotg_ep0_mps(mps);
-               if (mpsval > 3)
+               mps = dwc2_hsotg_ep0_mps(mps_bytes);
+               if (mps > 3)
                        goto bad_mps;
-               hs_ep->ep.maxpacket = mps;
+               hs_ep->ep.maxpacket = mps_bytes;
                hs_ep->mc = 1;
        } else {
-               mpsval = mps & DXEPCTL_MPS_MASK;
-               if (mpsval > 1024)
+               if (mps > 1024)
                        goto bad_mps;
-               mcval = ((mps >> 11) & 0x3) + 1;
-               hs_ep->mc = mcval;
-               if (mcval > 3)
+               hs_ep->mc = mc;
+               if (mc > 3)
                        goto bad_mps;
-               hs_ep->ep.maxpacket = mpsval;
+               hs_ep->ep.maxpacket = mps;
        }
 
        if (dir_in) {
                reg = dwc2_readl(regs + DIEPCTL(ep));
                reg &= ~DXEPCTL_MPS_MASK;
-               reg |= mpsval;
+               reg |= mps;
                dwc2_writel(reg, regs + DIEPCTL(ep));
        } else {
                reg = dwc2_readl(regs + DOEPCTL(ep));
                reg &= ~DXEPCTL_MPS_MASK;
-               reg |= mpsval;
+               reg |= mps;
                dwc2_writel(reg, regs + DOEPCTL(ep));
        }
 
@@ -2390,13 +2390,15 @@ static void dwc2_hsotg_irq_enumdone(struct dwc2_hsotg *hsotg)
        if (ep0_mps) {
                int i;
                /* Initialize ep0 for both in and out directions */
-               dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 1);
-               dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0);
+               dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0, 1);
+               dwc2_hsotg_set_ep_maxpacket(hsotg, 0, ep0_mps, 0, 0);
                for (i = 1; i < hsotg->num_of_eps; i++) {
                        if (hsotg->eps_in[i])
-                               dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 1);
+                               dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps,
+                                                           0, 1);
                        if (hsotg->eps_out[i])
-                               dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps, 0);
+                               dwc2_hsotg_set_ep_maxpacket(hsotg, i, ep_mps,
+                                                           0, 0);
                }
        }
 
@@ -2952,6 +2954,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
        u32 epctrl_reg;
        u32 epctrl;
        u32 mps;
+       u32 mc;
        u32 mask;
        unsigned int dir_in;
        unsigned int i, val, size;
@@ -2975,6 +2978,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
        }
 
        mps = usb_endpoint_maxp(desc);
+       mc = usb_endpoint_maxp_mult(desc);
 
        /* note, we handle this here instead of dwc2_hsotg_set_ep_maxpacket */
 
@@ -2996,7 +3000,7 @@ static int dwc2_hsotg_ep_enable(struct usb_ep *ep,
        epctrl |= DXEPCTL_USBACTEP;
 
        /* update the endpoint state */
-       dwc2_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, dir_in);
+       dwc2_hsotg_set_ep_maxpacket(hsotg, hs_ep->index, mps, mc, dir_in);
 
        /* default, set to non-periodic */
        hs_ep->isochronous = 0;