usb: dwc3: gadget: Report isoc transfer frame number
authorThinh Nguyen <thinh.nguyen@synopsys.com>
Fri, 16 Nov 2018 03:03:27 +0000 (19:03 -0800)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Wed, 5 Dec 2018 09:14:15 +0000 (11:14 +0200)
Implement the new frame_number API to report the isochronous interval
frame number. This patch checks and reports the interval in which the
isoc transfer was transmitted or received via the Isoc-First TRB SOF
number field.

Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/core.h
drivers/usb/dwc3/gadget.c

index 15c07b2..df87641 100644 (file)
@@ -784,6 +784,7 @@ enum dwc3_link_state {
 #define DWC3_TRB_CTRL_ISP_IMI          BIT(10)
 #define DWC3_TRB_CTRL_IOC              BIT(11)
 #define DWC3_TRB_CTRL_SID_SOFN(n)      (((n) & 0xffff) << 14)
+#define DWC3_TRB_CTRL_GET_SID_SOFN(n)  (((n) & (0xffff << 14)) >> 14)
 
 #define DWC3_TRBCTL_TYPE(n)            ((n) & (0x3f << 4))
 #define DWC3_TRBCTL_NORMAL             DWC3_TRB_CTRL_TRBCTL(1)
index 38d6df9..e2caf9e 100644 (file)
@@ -2340,6 +2340,19 @@ static int dwc3_gadget_ep_reclaim_completed_trb(struct dwc3_ep *dep,
                trb->ctrl &= ~DWC3_TRB_CTRL_HWO;
 
        /*
+        * For isochronous transfers, the first TRB in a service interval must
+        * have the Isoc-First type. Track and report its interval frame number.
+        */
+       if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+           (trb->ctrl & DWC3_TRBCTL_ISOCHRONOUS_FIRST)) {
+               unsigned int frame_number;
+
+               frame_number = DWC3_TRB_CTRL_GET_SID_SOFN(trb->ctrl);
+               frame_number &= ~(dep->interval - 1);
+               req->request.frame_number = frame_number;
+       }
+
+       /*
         * If we're dealing with unaligned size OUT transfer, we will be left
         * with one TRB pending in the ring. We need to manually clear HWO bit
         * from that TRB.