diff mbox series

[3/3] usb: dwc3: Enable low power management using refclk

Message ID 3ae441abc5fc03ead9bdf62dd563f8b213082e04.1541208283.git.thinhn@synopsys.com (mailing list archive)
State Superseded
Headers show
Series usb: dwc3: Introduce refclk lpm | expand

Commit Message

Thinh Nguyen Nov. 3, 2018, 1:35 a.m. UTC
DWC_usb31 peripheral controller v1.80a introduced a new feature to
enhance low power scheduling for ADC devices. Set "snps,enable-refclk-lpm"
to enable this feature. It enables low power scheduling of isochronous
transfers by running SOF/ITP counters using the reference clock. Both
"snps,dis_u2_susphy_quirk" and "snps,dis_enblslpm_quirk" must not be set
for this feature to be enabled.

Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
---
 drivers/usb/dwc3/core.c | 12 ++++++++++++
 drivers/usb/dwc3/core.h |  4 ++++
 2 files changed, 16 insertions(+)
diff mbox series

Patch

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 4437db4a1e15..058decc17724 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1021,6 +1021,16 @@  static int dwc3_core_init(struct dwc3 *dwc)
 		}
 	}
 
+	/* Enable low power isoc transfer scheduling using reference clock */
+	if  (dwc->use_refclk_lpm &&
+	     dwc->dr_mode == USB_DR_MODE_PERIPHERAL &&
+	     dwc->revision >= DWC3_USB31_REVISION_180A &&
+	     !dwc->dis_enblslpm_quirk && !dwc->dis_u2_susphy_quirk) {
+		reg = dwc3_readl(dwc->regs, DWC3_GFLADJ);
+		reg |= DWC3_GFLADJ_REFCLK_FLADJ;
+		dwc3_writel(dwc->regs, DWC3_GFLADJ, reg);
+	}
+
 	/*
 	 * Must config both number of packets and max burst settings to enable
 	 * RX and/or TX threshold.
@@ -1266,6 +1276,8 @@  static void dwc3_get_properties(struct dwc3 *dwc)
 				&hird_threshold);
 	dwc->usb3_lpm_capable = device_property_read_bool(dev,
 				"snps,usb3_lpm_capable");
+	dwc->use_refclk_lpm = device_property_read_bool(dev,
+				"snps,enable-refclk-lpm");
 	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 5ce985b2e6c7..ad0706d2a0e2 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -361,6 +361,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
 
@@ -1000,6 +1001,7 @@  struct dwc3_scratchpad_array {
  * @dis_tx_ipgap_linecheck_quirk: set if we disable u2mac linestate
  *			check during HS transmit.
  * @refclk_period_ns: reference clock period in nanoseconds.
+ * @use_refclk_lpm: set to enable lower power reference clock support
  * @tx_de_emphasis_quirk: set if we enable Tx de-emphasis quirk
  * @tx_de_emphasis: Tx de-emphasis value
  * 	0	- -6dB de-emphasis
@@ -1112,6 +1114,7 @@  struct dwc3 {
 #define DWC3_REVISION_IS_DWC31		0x80000000
 #define DWC3_USB31_REVISION_110A	(0x3131302a | DWC3_REVISION_IS_DWC31)
 #define DWC3_USB31_REVISION_120A	(0x3132302a | DWC3_REVISION_IS_DWC31)
+#define DWC3_USB31_REVISION_180A	(0x3138302a | DWC3_REVISION_IS_DWC31)
 
 	enum dwc3_ep0_next	ep0_next_event;
 	enum dwc3_ep0_state	ep0state;
@@ -1156,6 +1159,7 @@  struct dwc3 {
 	unsigned		setup_packet_pending:1;
 	unsigned		three_stage_setup:1;
 	unsigned		usb3_lpm_capable:1;
+	unsigned		use_refclk_lpm:1;
 
 	unsigned		disable_scramble_quirk:1;
 	unsigned		u2exit_lfps_quirk:1;