diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 32c38f71f874..38597a32cb20 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -882,6 +882,39 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc)
 	dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg);
 }
 
+/**
+ * dwc3_enable_refclk_sof - Enable frame number tracking based on ref_clk
+ * @dwc: Pointer to our controller context structure
+ *
+ * Returns 0 on success, otherwise negative errno.
+ */
+static int dwc3_enable_refclk_sof(struct dwc3 *dwc)
+{
+	u8		refclk_period_ns;
+	u32		reg;
+
+	reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+	refclk_period_ns = DWC3_GUCTL_GET_REFCLKPER(reg);
+
+	/* Only valid for the following reference clock periods */
+	switch (refclk_period_ns) {
+	case DWC3_GUCTL_REFCLKPER_25NS:
+	case DWC3_GUCTL_REFCLKPER_41NS:
+	case DWC3_GUCTL_REFCLKPER_50NS:
+	case DWC3_GUCTL_REFCLKPER_52NS:
+	case DWC3_GUCTL_REFCLKPER_58NS:
+	case DWC3_GUCTL_REFCLKPER_62NS:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+	reg |= DWC3_GFLADJ_REFCLK_FLADJ;
+	dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+	return 0;
+}
+
 /**
  * dwc3_core_init - Low-level initialization of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -969,6 +1002,22 @@ static int dwc3_core_init(struct dwc3 *dwc)
 		dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
 	}
 
+	/*
+	 * For peripheral controller, frame number tracking based on reference
+	 * clock is only introduced after DWC_usb31 version 1.80a.
+	 */
+	if (dwc->enable_refclk_sof &&
+	    (dwc->dr_mode != USB_DR_MODE_PERIPHERAL ||
+	     (dwc->dr_mode == USB_DR_MODE_PERIPHERAL &&
+	      dwc->revision >= DWC3_USB31_REVISION_180A))) {
+		ret = dwc3_enable_refclk_sof(dwc);
+		if (ret) {
+			dev_err(dwc->dev,
+				"can't enable ref_clk frame tracking\n");
+			goto err4;
+		}
+	}
+
 	/*
 	 * ENDXFER polling is available on version 3.10a and later of
 	 * the DWC_usb3 controller. It is NOT available in the
@@ -1261,6 +1310,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
 				"snps,usb3_lpm_capable");
 	dwc->usb2_lpm_disable = device_property_read_bool(dev,
 				"snps,usb2-lpm-disable");
+	dwc->enable_refclk_sof = device_property_read_bool(dev,
+				"snps,enable-refclk-sof");
 	device_property_read_u8(dev, "snps,refclk-period-ns",
 				&dwc->refclk_period_ns);
 	device_property_read_u8(dev, "snps,rx-thr-num-pkt-prd",
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index e190728104e0..dae2f918a932 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -248,6 +248,14 @@
 /* Global User Control Register */
 #define DWC3_GUCTL_HSTINAUTORETRY	BIT(14)
 #define DWC3_GUCTL_REFCLKPER(n)		(((n) & 0x3ff) << 22)
+#define DWC3_GUCTL_GET_REFCLKPER(n)	(((n) & (0x3ff << 22)) >> 22)
+
+#define DWC3_GUCTL_REFCLKPER_25NS	25
+#define DWC3_GUCTL_REFCLKPER_41NS	41
+#define DWC3_GUCTL_REFCLKPER_50NS	50
+#define DWC3_GUCTL_REFCLKPER_52NS	52
+#define DWC3_GUCTL_REFCLKPER_58NS	58
+#define DWC3_GUCTL_REFCLKPER_62NS	62
 
 /* Global User Control 1 Register */
 #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS	BIT(28)
@@ -365,6 +373,7 @@
 #define DWC3_GHWPARAMS7_RAM2_DEPTH(n)	(((n) >> 16) & 0xffff)
 
 /* Global Frame Length Adjustment Register */
+#define DWC3_GFLADJ_REFCLK_FLADJ		BIT(23)
 #define DWC3_GFLADJ_30MHZ_SDBND_SEL		BIT(7)
 #define DWC3_GFLADJ_30MHZ_MASK			0x3f
 
@@ -1020,6 +1029,7 @@ struct dwc3_scratchpad_array {
  *			check during HS transmit.
  * @refclk_period_ns: if set, inform the controller this value as the reference
  *			clock period in nanoseconds.
+ * @enable_refclk_sof: set to enable frame number tracking based on the ref_clk
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 	0	- -6dB de-emphasis
@@ -1135,6 +1145,7 @@ struct dwc3 {
 #define DWC3_USB31_REVISION_120A	(0x3132302a | DWC3_REVISION_IS_DWC31)
 #define DWC3_USB31_REVISION_160A	(0x3136302a | DWC3_REVISION_IS_DWC31)
 #define DWC3_USB31_REVISION_170A	(0x3137302a | DWC3_REVISION_IS_DWC31)
+#define DWC3_USB31_REVISION_180A	(0x3138302a | DWC3_REVISION_IS_DWC31)
 
 	u32			version_type;
 
@@ -1192,6 +1203,7 @@ struct dwc3 {
 	unsigned		dis_start_transfer_quirk:1;
 	unsigned		usb3_lpm_capable:1;
 	unsigned		usb2_lpm_disable:1;
+	unsigned		enable_refclk_sof:1;
 
 	unsigned		disable_scramble_quirk:1;
 	unsigned		u2exit_lfps_quirk:1;
