|
@@ -1947,6 +1947,35 @@ int dwc2_hcd_get_frame_number(struct dwc2_hsotg *hsotg)
|
|
|
return (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
|
|
|
}
|
|
|
|
|
|
+int dwc2_hcd_get_future_frame_number(struct dwc2_hsotg *hsotg, int us)
|
|
|
+{
|
|
|
+ u32 hprt = dwc2_readl(hsotg->regs + HPRT0);
|
|
|
+ u32 hfir = dwc2_readl(hsotg->regs + HFIR);
|
|
|
+ u32 hfnum = dwc2_readl(hsotg->regs + HFNUM);
|
|
|
+ unsigned int us_per_frame;
|
|
|
+ unsigned int frame_number;
|
|
|
+ unsigned int remaining;
|
|
|
+ unsigned int interval;
|
|
|
+ unsigned int phy_clks;
|
|
|
+
|
|
|
+ /* High speed has 125 us per (micro) frame; others are 1 ms per */
|
|
|
+ us_per_frame = (hprt & HPRT0_SPD_MASK) ? 1000 : 125;
|
|
|
+
|
|
|
+ /* Extract fields */
|
|
|
+ frame_number = (hfnum & HFNUM_FRNUM_MASK) >> HFNUM_FRNUM_SHIFT;
|
|
|
+ remaining = (hfnum & HFNUM_FRREM_MASK) >> HFNUM_FRREM_SHIFT;
|
|
|
+ interval = (hfir & HFIR_FRINT_MASK) >> HFIR_FRINT_SHIFT;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Number of phy clocks since the last tick of the frame number after
|
|
|
+ * "us" has passed.
|
|
|
+ */
|
|
|
+ phy_clks = (interval - remaining) +
|
|
|
+ DIV_ROUND_UP(interval * us, us_per_frame);
|
|
|
+
|
|
|
+ return dwc2_frame_num_inc(frame_number, phy_clks / interval);
|
|
|
+}
|
|
|
+
|
|
|
int dwc2_hcd_is_b_host(struct dwc2_hsotg *hsotg)
|
|
|
{
|
|
|
return hsotg->op_state == OTG_STATE_B_HOST;
|