linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/12] usb: dwc2: Add device clock gating support functions
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
@ 2021-04-13  7:16 ` Artur Petrosyan
  2021-04-13  7:16 ` [PATCH 02/12] usb: dwc2: Add host " Artur Petrosyan
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:16 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Added device clock gating support functions according
programming guide.

Moved "bus_suspended" flag to "dwc2_hsotg" struct because
we need to set that flag while entering to clock gating
in case when the driver is built in peripheral mode.

Added function names:
dwc2_gadget_enter_clock_gating()
dwc2_gadget_exit_clock_gating()

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.h   | 10 ++++--
 drivers/usb/dwc2/gadget.c | 71 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 5a7850482e57..e5597796dca4 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -866,6 +866,7 @@ struct dwc2_hregs_backup {
  * @ll_hw_enabled:	Status of low-level hardware resources.
  * @hibernated:		True if core is hibernated
  * @in_ppd:		True if core is partial power down mode.
+ * @bus_suspended:	True if bus is suspended
  * @reset_phy_on_wake:	Quirk saying that we should assert PHY reset on a
  *			remote wakeup.
  * @phy_off_for_suspend: Status of whether we turned the PHY off at suspend.
@@ -1023,7 +1024,6 @@ struct dwc2_hregs_backup {
  *			a pointer to an array of register definitions, the
  *			array size and the base address where the register bank
  *			is to be found.
- * @bus_suspended:	True if bus is suspended
  * @last_frame_num:	Number of last frame. Range from 0 to  32768
  * @frame_num_array:    Used only  if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is
  *			defined, for missed SOFs tracking. Array holds that
@@ -1062,6 +1062,7 @@ struct dwc2_hsotg {
 	unsigned int ll_hw_enabled:1;
 	unsigned int hibernated:1;
 	unsigned int in_ppd:1;
+	bool bus_suspended;
 	unsigned int reset_phy_on_wake:1;
 	unsigned int need_phy_for_wake:1;
 	unsigned int phy_off_for_suspend:1;
@@ -1145,7 +1146,6 @@ struct dwc2_hsotg {
 	unsigned long hs_periodic_bitmap[
 		DIV_ROUND_UP(DWC2_HS_SCHEDULE_US, BITS_PER_LONG)];
 	u16 periodic_qh_count;
-	bool bus_suspended;
 	bool new_connection;
 
 	u16 last_frame_num;
@@ -1415,6 +1415,9 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
 int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg);
 int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 					bool restore);
+void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg);
+void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg,
+				   int rem_wakeup);
 int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
@@ -1453,6 +1456,9 @@ static inline int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg)
 static inline int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 						      bool restore)
 { return 0; }
+static inline void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg,
+						 int rem_wakeup) {}
 static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index e08baee4987b..2f50f3e62caa 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -5483,3 +5483,74 @@ int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 	dev_dbg(hsotg->dev, "Exiting device partial Power Down completed.\n");
 	return ret;
 }
+
+/**
+ * dwc2_gadget_enter_clock_gating() - Put controller in clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ *
+ * Return: non-zero if failed to enter device partial power down.
+ *
+ * This function is for entering device mode clock gating.
+ */
+void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg)
+{
+	u32 pcgctl;
+
+	dev_dbg(hsotg->dev, "Entering device clock gating.\n");
+
+	/* Set the Phy Clock bit as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Set the Gate hclk as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	hsotg->lx_state = DWC2_L2;
+	hsotg->bus_suspended = true;
+}
+
+/*
+ * dwc2_gadget_exit_clock_gating() - Exit controller from device clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rem_wakeup: indicates whether remote wake up is enabled.
+ *
+ * This function is for exiting from device mode clock gating.
+ */
+void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup)
+{
+	u32 pcgctl;
+	u32 dctl;
+
+	dev_dbg(hsotg->dev, "Exiting device clock gating.\n");
+
+	/* Clear the Gate hclk. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Phy Clock bit. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	if (rem_wakeup) {
+		/* Set Remote Wakeup Signaling */
+		dctl = dwc2_readl(hsotg, DCTL);
+		dctl |= DCTL_RMTWKUPSIG;
+		dwc2_writel(hsotg, dctl, DCTL);
+	}
+
+	/* Change to L0 state */
+	call_gadget(hsotg, resume);
+	hsotg->lx_state = DWC2_L0;
+	hsotg->bus_suspended = false;
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/12] usb: dwc2: Add host clock gating support functions
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
  2021-04-13  7:16 ` [PATCH 01/12] usb: dwc2: Add device clock gating support functions Artur Petrosyan
@ 2021-04-13  7:16 ` Artur Petrosyan
  2021-04-13  7:16 ` [PATCH 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:16 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Added host clock gating support functions according
programming guide.

Added function names:
dwc2_host_enter_clock_gating()
dwc2_host_exit_clock_gating()

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.h |  5 +++
 drivers/usb/dwc2/hcd.c  | 86 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index e5597796dca4..8c12b3061f7f 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1486,6 +1486,8 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg,
 int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg);
 int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 				      int rem_wakeup, bool restore);
+void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg);
+void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup);
 bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2);
 static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg)
 { schedule_work(&hsotg->phy_reset_work); }
@@ -1521,6 +1523,9 @@ static inline int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg)
 static inline int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 						    int rem_wakeup, bool restore)
 { return 0; }
+static inline void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg,
+					       int rem_wakeup) {}
 static inline bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2)
 { return false; }
 static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) {}
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f096006df96f..f1c24c15d185 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5821,3 +5821,89 @@ int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 	dev_dbg(hsotg->dev, "Exiting host partial power down completed.\n");
 	return ret;
 }
+
+/**
+ * dwc2_host_enter_clock_gating() - Put controller in clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ *
+ * This function is for entering Host mode clock gating.
+ */
+void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg)
+{
+	u32 hprt0;
+	u32 pcgctl;
+
+	dev_dbg(hsotg->dev, "Entering host clock gating.\n");
+
+	/* Put this port in suspend mode. */
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 |= HPRT0_SUSP;
+	dwc2_writel(hsotg, hprt0, HPRT0);
+
+	/* Set the Phy Clock bit as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Set the Gate hclk as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	hsotg->bus_suspended = true;
+	hsotg->lx_state = DWC2_L2;
+}
+
+/**
+ * dwc2_host_exit_clock_gating() - Exit controller from clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rem_wakeup: indicates whether resume is initiated by remote wakeup
+ *
+ * This function is for exiting Host mode clock gating.
+ */
+void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup)
+{
+	u32 hprt0;
+	u32 pcgctl;
+
+	dev_dbg(hsotg->dev, "Exiting host clock gating.\n");
+
+	/* Clear the Gate hclk. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Phy Clock bit. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Drive resume signaling and exit suspend mode on the port. */
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 |= HPRT0_RES;
+	hprt0 &= ~HPRT0_SUSP;
+	dwc2_writel(hsotg, hprt0, HPRT0);
+	udelay(5);
+
+	if (!rem_wakeup) {
+		/* In case of port resume need to wait for 40 ms */
+		msleep(USB_RESUME_TIMEOUT);
+
+		/* Stop driveing resume signaling on the port. */
+		hprt0 = dwc2_read_hprt0(hsotg);
+		hprt0 &= ~HPRT0_RES;
+		dwc2_writel(hsotg, hprt0, HPRT0);
+
+		hsotg->bus_suspended = false;
+		hsotg->lx_state = DWC2_L0;
+	} else {
+		mod_timer(&hsotg->wkp_timer,
+			  jiffies + msecs_to_jiffies(71));
+	}
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
  2021-04-13  7:16 ` [PATCH 01/12] usb: dwc2: Add device clock gating support functions Artur Petrosyan
  2021-04-13  7:16 ` [PATCH 02/12] usb: dwc2: Add host " Artur Petrosyan
@ 2021-04-13  7:16 ` Artur Petrosyan
  2021-04-13  9:25   ` Sergei Shtylyov
  2021-04-13  7:16 ` [PATCH 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt Artur Petrosyan
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:16 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

If core doesn't support hibernation or partial power
down power saving options, power can still be saved
using clock gating on all the clocks.

- Added entering clock gating state from USB_SUSPEND
  interrupt.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 8c0152b514be..ab7fe303c0f9 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -529,14 +529,18 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 				/* Ask phy to be suspended */
 				if (!IS_ERR_OR_NULL(hsotg->uphy))
 					usb_phy_set_suspend(hsotg->uphy, true);
-			}
-
-			if (hsotg->hw_params.hibernation) {
+			} else if (hsotg->hw_params.hibernation) {
 				ret = dwc2_enter_hibernation(hsotg, 0);
 				if (ret && ret != -ENOTSUPP)
 					dev_err(hsotg->dev,
 						"%s: enter hibernation failed\n",
 						__func__);
+			} else {
+				/*
+				 * If not hibernation nor partial power down are supported,
+				 * clock gating is used to save power.
+				 */
+				dwc2_gadget_enter_clock_gating(hsotg);
 			}
 skip_power_saving:
 			/*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (2 preceding siblings ...)
  2021-04-13  7:16 ` [PATCH 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
@ 2021-04-13  7:16 ` Artur Petrosyan
  2021-04-13  7:16 ` [PATCH 05/12] usb: dwc2: Add exit clock gating from session request interrupt Artur Petrosyan
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:16 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Added exit from clock gating mode when wakeup interrupt
is detected. To exit from the clock gating
in device mode "dwc2_gadget_exit_clock_gating()"
function is used with rem_wakeup parameter 0. To exit
clock gating in host mode "dwc2_host_exit_clock_gating()"
with rem_wakeup parameter 1.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index ab7fe303c0f9..c764407e7633 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -415,17 +415,24 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 	if (dwc2_is_device_mode(hsotg)) {
 		dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
 			dwc2_readl(hsotg, DSTS));
-		if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) {
-			u32 dctl = dwc2_readl(hsotg, DCTL);
-			/* Clear Remote Wakeup Signaling */
-			dctl &= ~DCTL_RMTWKUPSIG;
-			dwc2_writel(hsotg, dctl, DCTL);
-			ret = dwc2_exit_partial_power_down(hsotg, 1,
-							   true);
-			if (ret)
-				dev_err(hsotg->dev,
-					"exit partial_power_down failed\n");
-			call_gadget(hsotg, resume);
+		if (hsotg->lx_state == DWC2_L2) {
+			if (hsotg->in_ppd) {
+				u32 dctl = dwc2_readl(hsotg, DCTL);
+				/* Clear Remote Wakeup Signaling */
+				dctl &= ~DCTL_RMTWKUPSIG;
+				dwc2_writel(hsotg, dctl, DCTL);
+				ret = dwc2_exit_partial_power_down(hsotg, 1,
+								   true);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit partial_power_down failed\n");
+				call_gadget(hsotg, resume);
+			}
+
+			/* Exit gadget mode clock gating. */
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_gadget_exit_clock_gating(hsotg, 0);
 		} else {
 			/* Change to L0 state */
 			hsotg->lx_state = DWC2_L0;
@@ -440,6 +447,10 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 						"exit partial_power_down failed\n");
 			}
 
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_host_exit_clock_gating(hsotg, 1);
+
 			/*
 			 * If we've got this quirk then the PHY is stuck upon
 			 * wakeup.  Assert reset.  This will propagate out and
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/12] usb: dwc2: Add exit clock gating from session request interrupt
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (3 preceding siblings ...)
  2021-04-13  7:16 ` [PATCH 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt Artur Petrosyan
@ 2021-04-13  7:16 ` Artur Petrosyan
  2021-04-13  7:16 ` [PATCH 06/12] usb: dwc2: Add exit clock gating when port reset is asserted Artur Petrosyan
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:16 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Added clock gating exit flow from session
request interrupt handler according programming guide.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index c764407e7633..550c52c1a0c7 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -316,12 +316,19 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 		hsotg->lx_state);
 
 	if (dwc2_is_device_mode(hsotg)) {
-		if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) {
-			ret = dwc2_exit_partial_power_down(hsotg, 0,
-							   true);
-			if (ret)
-				dev_err(hsotg->dev,
-					"exit power_down failed\n");
+		if (hsotg->lx_state == DWC2_L2) {
+			if (hsotg->in_ppd) {
+				ret = dwc2_exit_partial_power_down(hsotg, 0,
+								   true);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit power_down failed\n");
+			}
+
+			/* Exit gadget mode clock gating. */
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_gadget_exit_clock_gating(hsotg, 0);
 		}
 
 		/*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/12] usb: dwc2: Add exit clock gating when port reset is asserted
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (4 preceding siblings ...)
  2021-04-13  7:16 ` [PATCH 05/12] usb: dwc2: Add exit clock gating from session request interrupt Artur Petrosyan
@ 2021-04-13  7:16 ` Artur Petrosyan
  2021-04-13  7:17 ` [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:16 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Adds clock gating exit flow when set port feature
reset is received in suspended state.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f1c24c15d185..27f030d5de54 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3712,6 +3712,10 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 						"exit partial_power_down failed\n");
 			}
 
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_host_exit_clock_gating(hsotg, 0);
+
 			hprt0 = dwc2_read_hprt0(hsotg);
 			dev_dbg(hsotg->dev,
 				"SetPortFeature - USB_PORT_FEAT_RESET\n");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (5 preceding siblings ...)
  2021-04-13  7:16 ` [PATCH 06/12] usb: dwc2: Add exit clock gating when port reset is asserted Artur Petrosyan
@ 2021-04-13  7:17 ` Artur Petrosyan
  2021-04-13  9:22   ` Sergei Shtylyov
  2021-04-13  7:17 ` [PATCH 08/12] usb: dwc2: Update exit clock gating when port is resumed Artur Petrosyan
                   ` (17 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:17 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Updates the implementation of entering clock gating mode
when core receives port suspend.
Instead of setting the required bit fields of the registers
inline, called the "dwc2_host_enter_clock_gating()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 27f030d5de54..e1225fe6c61a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3298,7 +3298,6 @@ static int dwc2_host_is_b_hnp_enabled(struct dwc2_hsotg *hsotg)
 int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 {
 	unsigned long flags;
-	u32 hprt0;
 	u32 pcgctl;
 	u32 gotgctl;
 	int ret = 0;
@@ -3323,22 +3322,12 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
-	default:
-		hprt0 = dwc2_read_hprt0(hsotg);
-		hprt0 |= HPRT0_SUSP;
-		dwc2_writel(hsotg, hprt0, HPRT0);
-		hsotg->bus_suspended = true;
 		/*
-		 * If power_down is supported, Phy clock will be suspended
-		 * after registers are backuped.
+		 * If not hibernation nor partial power down are supported,
+		 * clock gating is used to save power.
 		 */
-		if (!hsotg->params.power_down) {
-			/* Suspend the Phy Clock */
-			pcgctl = dwc2_readl(hsotg, PCGCTL);
-			pcgctl |= PCGCTL_STOPPCLK;
-			dwc2_writel(hsotg, pcgctl, PCGCTL);
-			udelay(10);
-		}
+		dwc2_host_enter_clock_gating(hsotg);
+		break;
 	}
 
 	/* For HNP the bus must be suspended for at least 200ms */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/12] usb: dwc2: Update exit clock gating when port is resumed
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (6 preceding siblings ...)
  2021-04-13  7:17 ` [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
@ 2021-04-13  7:17 ` Artur Petrosyan
  2021-04-13  7:17 ` [PATCH 09/12] usb: dwc2: Allow exit clock gating in urb enqueue Artur Petrosyan
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:17 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Updates the implementation of exiting clock gating mode
when core receives port resume.
Instead of setting the required bit fields of the registers
inline, called the "dwc2_host_exit_clock_gating()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 29 ++++-------------------------
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index e1225fe6c61a..8a42675ab94e 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3359,8 +3359,6 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 int dwc2_port_resume(struct dwc2_hsotg *hsotg)
 {
 	unsigned long flags;
-	u32 hprt0;
-	u32 pcgctl;
 	int ret = 0;
 
 	spin_lock_irqsave(&hsotg->lock, flags);
@@ -3374,33 +3372,14 @@ int dwc2_port_resume(struct dwc2_hsotg *hsotg)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
-	default:
 		/*
-		 * If power_down is supported, Phy clock is already resumed
-		 * after registers restore.
+		 * If not hibernation nor partial power down are supported,
+		 * port resume is done using the clock gating programming flow.
 		 */
-		if (!hsotg->params.power_down) {
-			pcgctl = dwc2_readl(hsotg, PCGCTL);
-			pcgctl &= ~PCGCTL_STOPPCLK;
-			dwc2_writel(hsotg, pcgctl, PCGCTL);
-			spin_unlock_irqrestore(&hsotg->lock, flags);
-			msleep(20);
-			spin_lock_irqsave(&hsotg->lock, flags);
-		}
-
-		hprt0 = dwc2_read_hprt0(hsotg);
-		hprt0 |= HPRT0_RES;
-		hprt0 &= ~HPRT0_SUSP;
-		dwc2_writel(hsotg, hprt0, HPRT0);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
-
-		msleep(USB_RESUME_TIMEOUT);
-
+		dwc2_host_exit_clock_gating(hsotg, 0);
 		spin_lock_irqsave(&hsotg->lock, flags);
-		hprt0 = dwc2_read_hprt0(hsotg);
-		hprt0 &= ~(HPRT0_RES | HPRT0_SUSP);
-		dwc2_writel(hsotg, hprt0, HPRT0);
-		hsotg->bus_suspended = false;
+		break;
 	}
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/12] usb: dwc2: Allow exit clock gating in urb enqueue
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (7 preceding siblings ...)
  2021-04-13  7:17 ` [PATCH 08/12] usb: dwc2: Update exit clock gating when port is resumed Artur Petrosyan
@ 2021-04-13  7:17 ` Artur Petrosyan
  2021-04-13  7:17 ` [PATCH 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:17 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When core is in clock gating state and an external
hub is connected, upper layer sends URB enqueue request,
which results in port reset issue.

Added exit from clock gating state to avoid port
reset issue and process upper layer request properly.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 8a42675ab94e..31d6a1b87228 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4597,6 +4597,14 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 				"exit partial_power_down failed\n");
 	}
 
+	if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
+	    hsotg->bus_suspended) {
+		if (dwc2_is_device_mode(hsotg))
+			dwc2_gadget_exit_clock_gating(hsotg, 0);
+		else
+			dwc2_host_exit_clock_gating(hsotg, 0);
+	}
+
 	if (!ep)
 		return -EINVAL;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/12] usb: dwc2: Add clock gating entering flow by system suspend
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (8 preceding siblings ...)
  2021-04-13  7:17 ` [PATCH 09/12] usb: dwc2: Allow exit clock gating in urb enqueue Artur Petrosyan
@ 2021-04-13  7:17 ` Artur Petrosyan
  2021-04-13  7:17 ` [PATCH 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:17 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

If not hibernation nor partial power down are supported,
clock gating is used to save power.

Adds a new flow of entering clock gating when PC is
suspended.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 31d6a1b87228..09dcd37b9ef8 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4372,6 +4372,15 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
+		/*
+		 * If not hibernation nor partial power down are supported,
+		 * clock gating is used to save power.
+		 */
+		dwc2_host_enter_clock_gating(hsotg);
+
+		/* After entering suspend, hardware is not accessible */
+		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	default:
 		goto skip_power_saving;
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/12] usb: dwc2: Add clock gating exiting flow by system resume
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (9 preceding siblings ...)
  2021-04-13  7:17 ` [PATCH 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
@ 2021-04-13  7:17 ` Artur Petrosyan
  2021-04-13  7:17 ` [PATCH 12/12] usb: dwc2: Add exit clock gating before removing driver Artur Petrosyan
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:17 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

If not hibernation nor partial power down are supported,
port resume is done using the clock gating programming flow.

Adds a new flow of exiting clock gating when PC is
resumed.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/hcd.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 09dcd37b9ef8..04a1b53d65af 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4445,6 +4445,28 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
+		/*
+		 * If not hibernation nor partial power down are supported,
+		 * port resume is done using the clock gating programming flow.
+		 */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		dwc2_host_exit_clock_gating(hsotg, 0);
+
+		/*
+		 * Initialize the Core for Host mode, as after system resume
+		 * the global interrupts are disabled.
+		 */
+		dwc2_core_init(hsotg, false);
+		dwc2_enable_global_interrupts(hsotg);
+		dwc2_hcd_reinit(hsotg);
+		spin_lock_irqsave(&hsotg->lock, flags);
+
+		/*
+		 * Set HW accessible bit before powering on the controller
+		 * since an interrupt may rise.
+		 */
+		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	default:
 		hsotg->lx_state = DWC2_L0;
 		goto unlock;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/12] usb: dwc2: Add exit clock gating before removing driver
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (10 preceding siblings ...)
  2021-04-13  7:17 ` [PATCH 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
@ 2021-04-13  7:17 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 01/12] usb: dwc2: Add device clock gating support functions Artur Petrosyan
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:17 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When dwc2 core is in clock gating mode loading driver
again causes driver fail. Because in that mode
registers are not accessible.

Added a flow of exiting clock gating mode
to avoid the driver reload failure.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 drivers/usb/dwc2/platform.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index b28b8cd45799..f8b819cfa80e 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -326,6 +326,15 @@ static int dwc2_driver_remove(struct platform_device *dev)
 				"exit partial_power_down failed\n");
 	}
 
+	/* Exit clock gating when driver is removed. */
+	if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
+	    hsotg->bus_suspended) {
+		if (dwc2_is_device_mode(hsotg))
+			dwc2_gadget_exit_clock_gating(hsotg, 0);
+		else
+			dwc2_host_exit_clock_gating(hsotg, 0);
+	}
+
 	dwc2_debugfs_exit(hsotg);
 	if (hsotg->hcd_enabled)
 		dwc2_hcd_remove(hsotg);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 01/12] usb: dwc2: Add device clock gating support functions
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (11 preceding siblings ...)
  2021-04-13  7:17 ` [PATCH 12/12] usb: dwc2: Add exit clock gating before removing driver Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 02/12] usb: dwc2: Add host " Artur Petrosyan
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Added device clock gating support functions according
programming guide.

Moved "bus_suspended" flag to "dwc2_hsotg" struct because
we need to set that flag while entering to clock gating
in case when the driver is built in peripheral mode.

Added function names:
dwc2_gadget_enter_clock_gating()
dwc2_gadget_exit_clock_gating()

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.h   | 10 ++++--
 drivers/usb/dwc2/gadget.c | 71 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 5a7850482e57..e5597796dca4 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -866,6 +866,7 @@ struct dwc2_hregs_backup {
  * @ll_hw_enabled:	Status of low-level hardware resources.
  * @hibernated:		True if core is hibernated
  * @in_ppd:		True if core is partial power down mode.
+ * @bus_suspended:	True if bus is suspended
  * @reset_phy_on_wake:	Quirk saying that we should assert PHY reset on a
  *			remote wakeup.
  * @phy_off_for_suspend: Status of whether we turned the PHY off at suspend.
@@ -1023,7 +1024,6 @@ struct dwc2_hregs_backup {
  *			a pointer to an array of register definitions, the
  *			array size and the base address where the register bank
  *			is to be found.
- * @bus_suspended:	True if bus is suspended
  * @last_frame_num:	Number of last frame. Range from 0 to  32768
  * @frame_num_array:    Used only  if CONFIG_USB_DWC2_TRACK_MISSED_SOFS is
  *			defined, for missed SOFs tracking. Array holds that
@@ -1062,6 +1062,7 @@ struct dwc2_hsotg {
 	unsigned int ll_hw_enabled:1;
 	unsigned int hibernated:1;
 	unsigned int in_ppd:1;
+	bool bus_suspended;
 	unsigned int reset_phy_on_wake:1;
 	unsigned int need_phy_for_wake:1;
 	unsigned int phy_off_for_suspend:1;
@@ -1145,7 +1146,6 @@ struct dwc2_hsotg {
 	unsigned long hs_periodic_bitmap[
 		DIV_ROUND_UP(DWC2_HS_SCHEDULE_US, BITS_PER_LONG)];
 	u16 periodic_qh_count;
-	bool bus_suspended;
 	bool new_connection;
 
 	u16 last_frame_num;
@@ -1415,6 +1415,9 @@ int dwc2_gadget_exit_hibernation(struct dwc2_hsotg *hsotg,
 int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg);
 int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 					bool restore);
+void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg);
+void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg,
+				   int rem_wakeup);
 int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg);
 int dwc2_hsotg_tx_fifo_average_depth(struct dwc2_hsotg *hsotg);
@@ -1453,6 +1456,9 @@ static inline int dwc2_gadget_enter_partial_power_down(struct dwc2_hsotg *hsotg)
 static inline int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 						      bool restore)
 { return 0; }
+static inline void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg,
+						 int rem_wakeup) {}
 static inline int dwc2_hsotg_tx_fifo_count(struct dwc2_hsotg *hsotg)
 { return 0; }
 static inline int dwc2_hsotg_tx_fifo_total_depth(struct dwc2_hsotg *hsotg)
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index e08baee4987b..2f50f3e62caa 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -5483,3 +5483,74 @@ int dwc2_gadget_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 	dev_dbg(hsotg->dev, "Exiting device partial Power Down completed.\n");
 	return ret;
 }
+
+/**
+ * dwc2_gadget_enter_clock_gating() - Put controller in clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ *
+ * Return: non-zero if failed to enter device partial power down.
+ *
+ * This function is for entering device mode clock gating.
+ */
+void dwc2_gadget_enter_clock_gating(struct dwc2_hsotg *hsotg)
+{
+	u32 pcgctl;
+
+	dev_dbg(hsotg->dev, "Entering device clock gating.\n");
+
+	/* Set the Phy Clock bit as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Set the Gate hclk as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	hsotg->lx_state = DWC2_L2;
+	hsotg->bus_suspended = true;
+}
+
+/*
+ * dwc2_gadget_exit_clock_gating() - Exit controller from device clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rem_wakeup: indicates whether remote wake up is enabled.
+ *
+ * This function is for exiting from device mode clock gating.
+ */
+void dwc2_gadget_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup)
+{
+	u32 pcgctl;
+	u32 dctl;
+
+	dev_dbg(hsotg->dev, "Exiting device clock gating.\n");
+
+	/* Clear the Gate hclk. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Phy Clock bit. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	if (rem_wakeup) {
+		/* Set Remote Wakeup Signaling */
+		dctl = dwc2_readl(hsotg, DCTL);
+		dctl |= DCTL_RMTWKUPSIG;
+		dwc2_writel(hsotg, dctl, DCTL);
+	}
+
+	/* Change to L0 state */
+	call_gadget(hsotg, resume);
+	hsotg->lx_state = DWC2_L0;
+	hsotg->bus_suspended = false;
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 02/12] usb: dwc2: Add host clock gating support functions
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (12 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 01/12] usb: dwc2: Add device clock gating support functions Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Added host clock gating support functions according
programming guide.

Added function names:
dwc2_host_enter_clock_gating()
dwc2_host_exit_clock_gating()

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core.h |  5 +++
 drivers/usb/dwc2/hcd.c  | 86 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+)

diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index e5597796dca4..8c12b3061f7f 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1486,6 +1486,8 @@ int dwc2_host_exit_hibernation(struct dwc2_hsotg *hsotg,
 int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg);
 int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 				      int rem_wakeup, bool restore);
+void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg);
+void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup);
 bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2);
 static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg)
 { schedule_work(&hsotg->phy_reset_work); }
@@ -1521,6 +1523,9 @@ static inline int dwc2_host_enter_partial_power_down(struct dwc2_hsotg *hsotg)
 static inline int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 						    int rem_wakeup, bool restore)
 { return 0; }
+static inline void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg) {}
+static inline void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg,
+					       int rem_wakeup) {}
 static inline bool dwc2_host_can_poweroff_phy(struct dwc2_hsotg *dwc2)
 { return false; }
 static inline void dwc2_host_schedule_phy_reset(struct dwc2_hsotg *hsotg) {}
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f096006df96f..f1c24c15d185 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -5821,3 +5821,89 @@ int dwc2_host_exit_partial_power_down(struct dwc2_hsotg *hsotg,
 	dev_dbg(hsotg->dev, "Exiting host partial power down completed.\n");
 	return ret;
 }
+
+/**
+ * dwc2_host_enter_clock_gating() - Put controller in clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ *
+ * This function is for entering Host mode clock gating.
+ */
+void dwc2_host_enter_clock_gating(struct dwc2_hsotg *hsotg)
+{
+	u32 hprt0;
+	u32 pcgctl;
+
+	dev_dbg(hsotg->dev, "Entering host clock gating.\n");
+
+	/* Put this port in suspend mode. */
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 |= HPRT0_SUSP;
+	dwc2_writel(hsotg, hprt0, HPRT0);
+
+	/* Set the Phy Clock bit as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Set the Gate hclk as suspend is received. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl |= PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	hsotg->bus_suspended = true;
+	hsotg->lx_state = DWC2_L2;
+}
+
+/**
+ * dwc2_host_exit_clock_gating() - Exit controller from clock gating.
+ *
+ * @hsotg: Programming view of the DWC_otg controller
+ * @rem_wakeup: indicates whether resume is initiated by remote wakeup
+ *
+ * This function is for exiting Host mode clock gating.
+ */
+void dwc2_host_exit_clock_gating(struct dwc2_hsotg *hsotg, int rem_wakeup)
+{
+	u32 hprt0;
+	u32 pcgctl;
+
+	dev_dbg(hsotg->dev, "Exiting host clock gating.\n");
+
+	/* Clear the Gate hclk. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_GATEHCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Phy Clock bit. */
+	pcgctl = dwc2_readl(hsotg, PCGCTL);
+	pcgctl &= ~PCGCTL_STOPPCLK;
+	dwc2_writel(hsotg, pcgctl, PCGCTL);
+	udelay(5);
+
+	/* Drive resume signaling and exit suspend mode on the port. */
+	hprt0 = dwc2_read_hprt0(hsotg);
+	hprt0 |= HPRT0_RES;
+	hprt0 &= ~HPRT0_SUSP;
+	dwc2_writel(hsotg, hprt0, HPRT0);
+	udelay(5);
+
+	if (!rem_wakeup) {
+		/* In case of port resume need to wait for 40 ms */
+		msleep(USB_RESUME_TIMEOUT);
+
+		/* Stop driveing resume signaling on the port. */
+		hprt0 = dwc2_read_hprt0(hsotg);
+		hprt0 &= ~HPRT0_RES;
+		dwc2_writel(hsotg, hprt0, HPRT0);
+
+		hsotg->bus_suspended = false;
+		hsotg->lx_state = DWC2_L0;
+	} else {
+		mod_timer(&hsotg->wkp_timer,
+			  jiffies + msecs_to_jiffies(71));
+	}
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (13 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 02/12] usb: dwc2: Add host " Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt Artur Petrosyan
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

If core doesn't support hibernation or partial power
down power saving options, power can still be saved
using clock gating on all the clocks.

- Added entering clock gating state from USB_SUSPEND
  interrupt.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index 8c0152b514be..ab7fe303c0f9 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -529,14 +529,18 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
 				/* Ask phy to be suspended */
 				if (!IS_ERR_OR_NULL(hsotg->uphy))
 					usb_phy_set_suspend(hsotg->uphy, true);
-			}
-
-			if (hsotg->hw_params.hibernation) {
+			} else if (hsotg->hw_params.hibernation) {
 				ret = dwc2_enter_hibernation(hsotg, 0);
 				if (ret && ret != -ENOTSUPP)
 					dev_err(hsotg->dev,
 						"%s: enter hibernation failed\n",
 						__func__);
+			} else {
+				/*
+				 * If not hibernation nor partial power down are supported,
+				 * clock gating is used to save power.
+				 */
+				dwc2_gadget_enter_clock_gating(hsotg);
 			}
 skip_power_saving:
 			/*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (14 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 05/12] usb: dwc2: Add exit clock gating from session request interrupt Artur Petrosyan
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan, Minas Harutyunyan

Added exit from clock gating mode when wakeup interrupt
is detected. To exit from the clock gating
in device mode "dwc2_gadget_exit_clock_gating()"
function is used with rem_wakeup parameter 0. To exit
clock gating in host mode "dwc2_host_exit_clock_gating()"
with rem_wakeup parameter 1.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
---
 drivers/usb/dwc2/core_intr.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index ab7fe303c0f9..c764407e7633 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -415,17 +415,24 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 	if (dwc2_is_device_mode(hsotg)) {
 		dev_dbg(hsotg->dev, "DSTS=0x%0x\n",
 			dwc2_readl(hsotg, DSTS));
-		if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) {
-			u32 dctl = dwc2_readl(hsotg, DCTL);
-			/* Clear Remote Wakeup Signaling */
-			dctl &= ~DCTL_RMTWKUPSIG;
-			dwc2_writel(hsotg, dctl, DCTL);
-			ret = dwc2_exit_partial_power_down(hsotg, 1,
-							   true);
-			if (ret)
-				dev_err(hsotg->dev,
-					"exit partial_power_down failed\n");
-			call_gadget(hsotg, resume);
+		if (hsotg->lx_state == DWC2_L2) {
+			if (hsotg->in_ppd) {
+				u32 dctl = dwc2_readl(hsotg, DCTL);
+				/* Clear Remote Wakeup Signaling */
+				dctl &= ~DCTL_RMTWKUPSIG;
+				dwc2_writel(hsotg, dctl, DCTL);
+				ret = dwc2_exit_partial_power_down(hsotg, 1,
+								   true);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit partial_power_down failed\n");
+				call_gadget(hsotg, resume);
+			}
+
+			/* Exit gadget mode clock gating. */
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_gadget_exit_clock_gating(hsotg, 0);
 		} else {
 			/* Change to L0 state */
 			hsotg->lx_state = DWC2_L0;
@@ -440,6 +447,10 @@ static void dwc2_handle_wakeup_detected_intr(struct dwc2_hsotg *hsotg)
 						"exit partial_power_down failed\n");
 			}
 
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_host_exit_clock_gating(hsotg, 1);
+
 			/*
 			 * If we've got this quirk then the PHY is stuck upon
 			 * wakeup.  Assert reset.  This will propagate out and
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 05/12] usb: dwc2: Add exit clock gating from session request interrupt
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (15 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 06/12] usb: dwc2: Add exit clock gating when port reset is asserted Artur Petrosyan
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Added clock gating exit flow from session
request interrupt handler according programming guide.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/core_intr.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
index c764407e7633..550c52c1a0c7 100644
--- a/drivers/usb/dwc2/core_intr.c
+++ b/drivers/usb/dwc2/core_intr.c
@@ -316,12 +316,19 @@ static void dwc2_handle_session_req_intr(struct dwc2_hsotg *hsotg)
 		hsotg->lx_state);
 
 	if (dwc2_is_device_mode(hsotg)) {
-		if (hsotg->lx_state == DWC2_L2 && hsotg->in_ppd) {
-			ret = dwc2_exit_partial_power_down(hsotg, 0,
-							   true);
-			if (ret)
-				dev_err(hsotg->dev,
-					"exit power_down failed\n");
+		if (hsotg->lx_state == DWC2_L2) {
+			if (hsotg->in_ppd) {
+				ret = dwc2_exit_partial_power_down(hsotg, 0,
+								   true);
+				if (ret)
+					dev_err(hsotg->dev,
+						"exit power_down failed\n");
+			}
+
+			/* Exit gadget mode clock gating. */
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_gadget_exit_clock_gating(hsotg, 0);
 		}
 
 		/*
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 06/12] usb: dwc2: Add exit clock gating when port reset is asserted
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (16 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 05/12] usb: dwc2: Add exit clock gating from session request interrupt Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:36 ` [PATCH v2 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Adds clock gating exit flow when set port feature
reset is received in suspended state.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index f1c24c15d185..27f030d5de54 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3712,6 +3712,10 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
 						"exit partial_power_down failed\n");
 			}
 
+			if (hsotg->params.power_down ==
+			    DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended)
+				dwc2_host_exit_clock_gating(hsotg, 0);
+
 			hprt0 = dwc2_read_hprt0(hsotg);
 			dev_dbg(hsotg->dev,
 				"SetPortFeature - USB_PORT_FEAT_RESET\n");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 07/12] usb: dwc2: Update enter clock gating when port is suspended
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (17 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 06/12] usb: dwc2: Add exit clock gating when port reset is asserted Artur Petrosyan
@ 2021-04-13  7:36 ` Artur Petrosyan
  2021-04-13  7:37 ` [PATCH v2 08/12] usb: dwc2: Update exit clock gating when port is resumed Artur Petrosyan
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:36 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Updates the implementation of entering clock gating mode
when core receives port suspend.
Instead of setting the required bit fields of the registers
inline, called the "dwc2_host_enter_clock_gating()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 27f030d5de54..e1225fe6c61a 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3298,7 +3298,6 @@ static int dwc2_host_is_b_hnp_enabled(struct dwc2_hsotg *hsotg)
 int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 {
 	unsigned long flags;
-	u32 hprt0;
 	u32 pcgctl;
 	u32 gotgctl;
 	int ret = 0;
@@ -3323,22 +3322,12 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
-	default:
-		hprt0 = dwc2_read_hprt0(hsotg);
-		hprt0 |= HPRT0_SUSP;
-		dwc2_writel(hsotg, hprt0, HPRT0);
-		hsotg->bus_suspended = true;
 		/*
-		 * If power_down is supported, Phy clock will be suspended
-		 * after registers are backuped.
+		 * If not hibernation nor partial power down are supported,
+		 * clock gating is used to save power.
 		 */
-		if (!hsotg->params.power_down) {
-			/* Suspend the Phy Clock */
-			pcgctl = dwc2_readl(hsotg, PCGCTL);
-			pcgctl |= PCGCTL_STOPPCLK;
-			dwc2_writel(hsotg, pcgctl, PCGCTL);
-			udelay(10);
-		}
+		dwc2_host_enter_clock_gating(hsotg);
+		break;
 	}
 
 	/* For HNP the bus must be suspended for at least 200ms */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 08/12] usb: dwc2: Update exit clock gating when port is resumed
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (18 preceding siblings ...)
  2021-04-13  7:36 ` [PATCH v2 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
@ 2021-04-13  7:37 ` Artur Petrosyan
  2021-04-13  7:37 ` [PATCH v2 09/12] usb: dwc2: Allow exit clock gating in urb enqueue Artur Petrosyan
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:37 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

Updates the implementation of exiting clock gating mode
when core receives port resume.
Instead of setting the required bit fields of the registers
inline, called the "dwc2_host_exit_clock_gating()" function.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 29 ++++-------------------------
 1 file changed, 4 insertions(+), 25 deletions(-)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index e1225fe6c61a..8a42675ab94e 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -3359,8 +3359,6 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
 int dwc2_port_resume(struct dwc2_hsotg *hsotg)
 {
 	unsigned long flags;
-	u32 hprt0;
-	u32 pcgctl;
 	int ret = 0;
 
 	spin_lock_irqsave(&hsotg->lock, flags);
@@ -3374,33 +3372,14 @@ int dwc2_port_resume(struct dwc2_hsotg *hsotg)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
-	default:
 		/*
-		 * If power_down is supported, Phy clock is already resumed
-		 * after registers restore.
+		 * If not hibernation nor partial power down are supported,
+		 * port resume is done using the clock gating programming flow.
 		 */
-		if (!hsotg->params.power_down) {
-			pcgctl = dwc2_readl(hsotg, PCGCTL);
-			pcgctl &= ~PCGCTL_STOPPCLK;
-			dwc2_writel(hsotg, pcgctl, PCGCTL);
-			spin_unlock_irqrestore(&hsotg->lock, flags);
-			msleep(20);
-			spin_lock_irqsave(&hsotg->lock, flags);
-		}
-
-		hprt0 = dwc2_read_hprt0(hsotg);
-		hprt0 |= HPRT0_RES;
-		hprt0 &= ~HPRT0_SUSP;
-		dwc2_writel(hsotg, hprt0, HPRT0);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
-
-		msleep(USB_RESUME_TIMEOUT);
-
+		dwc2_host_exit_clock_gating(hsotg, 0);
 		spin_lock_irqsave(&hsotg->lock, flags);
-		hprt0 = dwc2_read_hprt0(hsotg);
-		hprt0 &= ~(HPRT0_RES | HPRT0_SUSP);
-		dwc2_writel(hsotg, hprt0, HPRT0);
-		hsotg->bus_suspended = false;
+		break;
 	}
 
 	spin_unlock_irqrestore(&hsotg->lock, flags);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 09/12] usb: dwc2: Allow exit clock gating in urb enqueue
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (19 preceding siblings ...)
  2021-04-13  7:37 ` [PATCH v2 08/12] usb: dwc2: Update exit clock gating when port is resumed Artur Petrosyan
@ 2021-04-13  7:37 ` Artur Petrosyan
  2021-04-13  7:37 ` [PATCH v2 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:37 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When core is in clock gating state and an external
hub is connected, upper layer sends URB enqueue request,
which results in port reset issue.

Added exit from clock gating state to avoid port
reset issue and process upper layer request properly.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 8a42675ab94e..31d6a1b87228 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4597,6 +4597,14 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
 				"exit partial_power_down failed\n");
 	}
 
+	if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
+	    hsotg->bus_suspended) {
+		if (dwc2_is_device_mode(hsotg))
+			dwc2_gadget_exit_clock_gating(hsotg, 0);
+		else
+			dwc2_host_exit_clock_gating(hsotg, 0);
+	}
+
 	if (!ep)
 		return -EINVAL;
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 10/12] usb: dwc2: Add clock gating entering flow by system suspend
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (20 preceding siblings ...)
  2021-04-13  7:37 ` [PATCH v2 09/12] usb: dwc2: Allow exit clock gating in urb enqueue Artur Petrosyan
@ 2021-04-13  7:37 ` Artur Petrosyan
  2021-04-13  9:29   ` Sergei Shtylyov
  2021-04-13  7:37 ` [PATCH v2 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
                   ` (2 subsequent siblings)
  24 siblings, 1 reply; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:37 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

If not hibernation nor partial power down are supported,
clock gating is used to save power.

Adds a new flow of entering clock gating when PC is
suspended.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 31d6a1b87228..09dcd37b9ef8 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4372,6 +4372,15 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
+		/*
+		 * If not hibernation nor partial power down are supported,
+		 * clock gating is used to save power.
+		 */
+		dwc2_host_enter_clock_gating(hsotg);
+
+		/* After entering suspend, hardware is not accessible */
+		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	default:
 		goto skip_power_saving;
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 11/12] usb: dwc2: Add clock gating exiting flow by system resume
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (21 preceding siblings ...)
  2021-04-13  7:37 ` [PATCH v2 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
@ 2021-04-13  7:37 ` Artur Petrosyan
  2021-04-13  9:30   ` Sergei Shtylyov
  2021-04-13  7:37 ` [PATCH v2 12/12] usb: dwc2: Add exit clock gating before removing driver Artur Petrosyan
       [not found] ` <20210413073600.57846A0094@mailhost.synopsys.com>
  24 siblings, 1 reply; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:37 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

If not hibernation nor partial power down are supported,
port resume is done using the clock gating programming flow.

Adds a new flow of exiting clock gating when PC is
resumed.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/hcd.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 09dcd37b9ef8..04a1b53d65af 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4445,6 +4445,28 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 		break;
 	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
 	case DWC2_POWER_DOWN_PARAM_NONE:
+		/*
+		 * If not hibernation nor partial power down are supported,
+		 * port resume is done using the clock gating programming flow.
+		 */
+		spin_unlock_irqrestore(&hsotg->lock, flags);
+		dwc2_host_exit_clock_gating(hsotg, 0);
+
+		/*
+		 * Initialize the Core for Host mode, as after system resume
+		 * the global interrupts are disabled.
+		 */
+		dwc2_core_init(hsotg, false);
+		dwc2_enable_global_interrupts(hsotg);
+		dwc2_hcd_reinit(hsotg);
+		spin_lock_irqsave(&hsotg->lock, flags);
+
+		/*
+		 * Set HW accessible bit before powering on the controller
+		 * since an interrupt may rise.
+		 */
+		set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+		break;
 	default:
 		hsotg->lx_state = DWC2_L0;
 		goto unlock;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 12/12] usb: dwc2: Add exit clock gating before removing driver
       [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
                   ` (22 preceding siblings ...)
  2021-04-13  7:37 ` [PATCH v2 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
@ 2021-04-13  7:37 ` Artur Petrosyan
       [not found] ` <20210413073600.57846A0094@mailhost.synopsys.com>
  24 siblings, 0 replies; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  7:37 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn, Artur Petrosyan

When dwc2 core is in clock gating mode loading driver
again causes driver fail. Because in that mode
registers are not accessible.

Added a flow of exiting clock gating mode
to avoid the driver reload failure.

Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
---
 Changes in v2:
 - None

 drivers/usb/dwc2/platform.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index b28b8cd45799..f8b819cfa80e 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -326,6 +326,15 @@ static int dwc2_driver_remove(struct platform_device *dev)
 				"exit partial_power_down failed\n");
 	}
 
+	/* Exit clock gating when driver is removed. */
+	if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE &&
+	    hsotg->bus_suspended) {
+		if (dwc2_is_device_mode(hsotg))
+			dwc2_gadget_exit_clock_gating(hsotg, 0);
+		else
+			dwc2_host_exit_clock_gating(hsotg, 0);
+	}
+
 	dwc2_debugfs_exit(hsotg);
 	if (hsotg->hcd_enabled)
 		dwc2_hcd_remove(hsotg);
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 00/12] usb: dwc2: Add clock gating support.
       [not found] ` <20210413073600.57846A0094@mailhost.synopsys.com>
@ 2021-04-13  8:03   ` Artur Petrosyan
  2021-04-13 10:26     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 31+ messages in thread
From: Artur Petrosyan @ 2021-04-13  8:03 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman, Minas Harutyunyan, linux-usb,
	linux-kernel
  Cc: John Youn

Hi Greg,

On 4/13/2021 11:35, Artur Petrosyan wrote:
> This patch set adds clock gating power saving support for
> dwc2 core.
> It adds support for the following cases described by programming guide.
>    1. Enter to clock gating from USB_SUSPEND interrupt.
>    2. Clock gating entering flow by system suspend.
>    3. Clock gating exiting flow by system resume.
>    4. Exit clock gating from wakeup interrupt.
>    5. Exit clock gating from session request interrupt.
>    6. Exit clock gating when port reset is asserted.
> 
> Additional cases to exit form clock gating were needed which are not
> described in clock gating programming guide.
>    1. Added clock gating exit flow before removing driver
>    2. Exit clock gating in urb enqueue.
> 
> It updates the implementation of dwc2 entering and exiting clock
> gating when a port is suspended or resumed.
> 
> The patch set also adds the implementation of function handlers
> for entering and exiting host or device clock gating.
> 
> NOTE: This is the third patch set in the power saving mode fixes
> series.
> This patch set is part of multiple series and is continuation
> of the "usb: dwc2: Fix and improve power saving modes" patch set.
> (Patch set link: https://marc.info/?l=linux-usb&m=160379622403975&w=2).
> The patches that were included in the "usb: dwc2:
> Fix and improve power saving modes" which was submitted
> earlier was too large and needed to be split up into
> smaller patch sets.
> 
> Changes since V1:
> Re sending the patch set as v1 because vger.kernel.org rejected
> the cover letter. With error code "550 5.7.1 Content-Policy"
> No changes in the patches or the source code.
> 
> 
> Artur Petrosyan (12):
>    usb: dwc2: Add device clock gating support functions
>    usb: dwc2: Add host clock gating support functions
>    usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt
>    usb: dwc2: Add exit clock gating from wakeup interrupt
>    usb: dwc2: Add exit clock gating from session request interrupt
>    usb: dwc2: Add exit clock gating when port reset is asserted
>    usb: dwc2: Update enter clock gating when port is suspended
>    usb: dwc2: Update exit clock gating when port is resumed
>    usb: dwc2: Allow exit clock gating in urb enqueue
>    usb: dwc2: Add clock gating entering flow by system suspend
>    usb: dwc2: Add clock gating exiting flow by system resume
>    usb: dwc2: Add exit clock gating before removing driver
> 
>   drivers/usb/dwc2/core.h      |  15 ++-
>   drivers/usb/dwc2/core_intr.c |  62 ++++++++----
>   drivers/usb/dwc2/gadget.c    |  71 ++++++++++++++
>   drivers/usb/dwc2/hcd.c       | 177 +++++++++++++++++++++++++++--------
>   drivers/usb/dwc2/platform.c  |   9 ++
>   5 files changed, 272 insertions(+), 62 deletions(-)
> 
> 
> base-commit: 9bc46a12c53d8268392774172742aa9e5dd6953d
> 
This cover letter for the clock gating patches is being rejected by 
"vger.kernel.org". I have tried to send one more time as v2 but again it 
is rejected.
The error message is "vger.kernel.org
Remote Server returned '554 5.7.1 <vger.kernel.org #5.7.1 smtp; 550 
5.7.1 Content-Policy accept-into-freezer-1"

Could you please suggest any solution to this?

Regards,
Artur


^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended
  2021-04-13  7:17 ` [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
@ 2021-04-13  9:22   ` Sergei Shtylyov
  2021-04-13 10:24     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 31+ messages in thread
From: Sergei Shtylyov @ 2021-04-13  9:22 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

Hello!

On 13.04.2021 10:17, Artur Petrosyan wrote:

> Updates the implementation of entering clock gating mode
> when core receives port suspend.
> Instead of setting the required bit fields of the registers
> inline, called the "dwc2_host_enter_clock_gating()" function.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> ---
>   drivers/usb/dwc2/hcd.c | 19 ++++---------------
>   1 file changed, 4 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 27f030d5de54..e1225fe6c61a 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
[...]
> @@ -3323,22 +3322,12 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>   	case DWC2_POWER_DOWN_PARAM_NONE:
> -	default:
> -		hprt0 = dwc2_read_hprt0(hsotg);
> -		hprt0 |= HPRT0_SUSP;
> -		dwc2_writel(hsotg, hprt0, HPRT0);
> -		hsotg->bus_suspended = true;
>   		/*
> -		 * If power_down is supported, Phy clock will be suspended
> -		 * after registers are backuped.
> +		 * If not hibernation nor partial power down are supported,

    s/not/neither/?

MBR, Sergei

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt
  2021-04-13  7:16 ` [PATCH 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
@ 2021-04-13  9:25   ` Sergei Shtylyov
  0 siblings, 0 replies; 31+ messages in thread
From: Sergei Shtylyov @ 2021-04-13  9:25 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

On 13.04.2021 10:16, Artur Petrosyan wrote:

> If core doesn't support hibernation or partial power
> down power saving options, power can still be saved
> using clock gating on all the clocks.
> 
> - Added entering clock gating state from USB_SUSPEND
>    interrupt.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> Acked-by: Minas Harutyunyan <Minas.Harutyunyan@synopsys.com>
> ---
>   drivers/usb/dwc2/core_intr.c | 10 +++++++---
>   1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/dwc2/core_intr.c b/drivers/usb/dwc2/core_intr.c
> index 8c0152b514be..ab7fe303c0f9 100644
> --- a/drivers/usb/dwc2/core_intr.c
> +++ b/drivers/usb/dwc2/core_intr.c
> @@ -529,14 +529,18 @@ static void dwc2_handle_usb_suspend_intr(struct dwc2_hsotg *hsotg)
>   				/* Ask phy to be suspended */
>   				if (!IS_ERR_OR_NULL(hsotg->uphy))
>   					usb_phy_set_suspend(hsotg->uphy, true);
> -			}
> -
> -			if (hsotg->hw_params.hibernation) {
> +			} else if (hsotg->hw_params.hibernation) {
>   				ret = dwc2_enter_hibernation(hsotg, 0);
>   				if (ret && ret != -ENOTSUPP)
>   					dev_err(hsotg->dev,
>   						"%s: enter hibernation failed\n",
>   						__func__);
> +			} else {
> +				/*
> +				 * If not hibernation nor partial power down are supported,

    s/not/neither/?

[...]

MBR, Sergei

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 10/12] usb: dwc2: Add clock gating entering flow by system suspend
  2021-04-13  7:37 ` [PATCH v2 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
@ 2021-04-13  9:29   ` Sergei Shtylyov
  0 siblings, 0 replies; 31+ messages in thread
From: Sergei Shtylyov @ 2021-04-13  9:29 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

On 13.04.2021 10:37, Artur Petrosyan wrote:

> If not hibernation nor partial power down are supported,

    s/not/neither/?

> clock gating is used to save power.
> 
> Adds a new flow of entering clock gating when PC is
> suspended.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 31d6a1b87228..09dcd37b9ef8 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4372,6 +4372,15 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>   	case DWC2_POWER_DOWN_PARAM_NONE:
> +		/*
> +		 * If not hibernation nor partial power down are supported,

    s/not/neither/?

> +		 * clock gating is used to save power.
> +		 */
> +		dwc2_host_enter_clock_gating(hsotg);
> +
> +		/* After entering suspend, hardware is not accessible */
> +		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
> +		break;
>   	default:
>   		goto skip_power_saving;
>   	}
MBR, Sergei

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 11/12] usb: dwc2: Add clock gating exiting flow by system resume
  2021-04-13  7:37 ` [PATCH v2 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
@ 2021-04-13  9:30   ` Sergei Shtylyov
  0 siblings, 0 replies; 31+ messages in thread
From: Sergei Shtylyov @ 2021-04-13  9:30 UTC (permalink / raw)
  To: Artur Petrosyan, Felipe Balbi, Greg Kroah-Hartman,
	Minas Harutyunyan, linux-usb, linux-kernel
  Cc: John Youn

On 13.04.2021 10:37, Artur Petrosyan wrote:

> If not hibernation nor partial power down are supported,

    s/not/neither/?

> port resume is done using the clock gating programming flow.
> 
> Adds a new flow of exiting clock gating when PC is
> resumed.
> 
> Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> ---
>   Changes in v2:
>   - None
> 
>   drivers/usb/dwc2/hcd.c | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> index 09dcd37b9ef8..04a1b53d65af 100644
> --- a/drivers/usb/dwc2/hcd.c
> +++ b/drivers/usb/dwc2/hcd.c
> @@ -4445,6 +4445,28 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
>   		break;
>   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
>   	case DWC2_POWER_DOWN_PARAM_NONE:
> +		/*
> +		 * If not hibernation nor partial power down are supported,

    s/not/neither/?

[...]

MBR, Sergei

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended
  2021-04-13  9:22   ` Sergei Shtylyov
@ 2021-04-13 10:24     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 31+ messages in thread
From: Greg Kroah-Hartman @ 2021-04-13 10:24 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Artur Petrosyan, Felipe Balbi, Minas Harutyunyan, linux-usb,
	linux-kernel, John Youn

On Tue, Apr 13, 2021 at 12:22:35PM +0300, Sergei Shtylyov wrote:
> Hello!
> 
> On 13.04.2021 10:17, Artur Petrosyan wrote:
> 
> > Updates the implementation of entering clock gating mode
> > when core receives port suspend.
> > Instead of setting the required bit fields of the registers
> > inline, called the "dwc2_host_enter_clock_gating()" function.
> > 
> > Signed-off-by: Artur Petrosyan <Arthur.Petrosyan@synopsys.com>
> > ---
> >   drivers/usb/dwc2/hcd.c | 19 ++++---------------
> >   1 file changed, 4 insertions(+), 15 deletions(-)
> > 
> > diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
> > index 27f030d5de54..e1225fe6c61a 100644
> > --- a/drivers/usb/dwc2/hcd.c
> > +++ b/drivers/usb/dwc2/hcd.c
> [...]
> > @@ -3323,22 +3322,12 @@ int dwc2_port_suspend(struct dwc2_hsotg *hsotg, u16 windex)
> >   		break;
> >   	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
> >   	case DWC2_POWER_DOWN_PARAM_NONE:
> > -	default:
> > -		hprt0 = dwc2_read_hprt0(hsotg);
> > -		hprt0 |= HPRT0_SUSP;
> > -		dwc2_writel(hsotg, hprt0, HPRT0);
> > -		hsotg->bus_suspended = true;
> >   		/*
> > -		 * If power_down is supported, Phy clock will be suspended
> > -		 * after registers are backuped.
> > +		 * If not hibernation nor partial power down are supported,
> 
>    s/not/neither/?

It's fine, not a big deal at all.

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 00/12] usb: dwc2: Add clock gating support.
  2021-04-13  8:03   ` [PATCH v2 00/12] usb: dwc2: Add clock gating support Artur Petrosyan
@ 2021-04-13 10:26     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 31+ messages in thread
From: Greg Kroah-Hartman @ 2021-04-13 10:26 UTC (permalink / raw)
  To: Artur Petrosyan
  Cc: Felipe Balbi, Minas Harutyunyan, linux-usb, linux-kernel, John Youn

On Tue, Apr 13, 2021 at 08:03:23AM +0000, Artur Petrosyan wrote:
> Hi Greg,
> 
> On 4/13/2021 11:35, Artur Petrosyan wrote:
> > This patch set adds clock gating power saving support for
> > dwc2 core.
> > It adds support for the following cases described by programming guide.
> >    1. Enter to clock gating from USB_SUSPEND interrupt.
> >    2. Clock gating entering flow by system suspend.
> >    3. Clock gating exiting flow by system resume.
> >    4. Exit clock gating from wakeup interrupt.
> >    5. Exit clock gating from session request interrupt.
> >    6. Exit clock gating when port reset is asserted.
> > 
> > Additional cases to exit form clock gating were needed which are not
> > described in clock gating programming guide.
> >    1. Added clock gating exit flow before removing driver
> >    2. Exit clock gating in urb enqueue.
> > 
> > It updates the implementation of dwc2 entering and exiting clock
> > gating when a port is suspended or resumed.
> > 
> > The patch set also adds the implementation of function handlers
> > for entering and exiting host or device clock gating.
> > 
> > NOTE: This is the third patch set in the power saving mode fixes
> > series.
> > This patch set is part of multiple series and is continuation
> > of the "usb: dwc2: Fix and improve power saving modes" patch set.
> > (Patch set link: https://marc.info/?l=linux-usb&m=160379622403975&w=2).
> > The patches that were included in the "usb: dwc2:
> > Fix and improve power saving modes" which was submitted
> > earlier was too large and needed to be split up into
> > smaller patch sets.
> > 
> > Changes since V1:
> > Re sending the patch set as v1 because vger.kernel.org rejected
> > the cover letter. With error code "550 5.7.1 Content-Policy"
> > No changes in the patches or the source code.
> > 
> > 
> > Artur Petrosyan (12):
> >    usb: dwc2: Add device clock gating support functions
> >    usb: dwc2: Add host clock gating support functions
> >    usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt
> >    usb: dwc2: Add exit clock gating from wakeup interrupt
> >    usb: dwc2: Add exit clock gating from session request interrupt
> >    usb: dwc2: Add exit clock gating when port reset is asserted
> >    usb: dwc2: Update enter clock gating when port is suspended
> >    usb: dwc2: Update exit clock gating when port is resumed
> >    usb: dwc2: Allow exit clock gating in urb enqueue
> >    usb: dwc2: Add clock gating entering flow by system suspend
> >    usb: dwc2: Add clock gating exiting flow by system resume
> >    usb: dwc2: Add exit clock gating before removing driver
> > 
> >   drivers/usb/dwc2/core.h      |  15 ++-
> >   drivers/usb/dwc2/core_intr.c |  62 ++++++++----
> >   drivers/usb/dwc2/gadget.c    |  71 ++++++++++++++
> >   drivers/usb/dwc2/hcd.c       | 177 +++++++++++++++++++++++++++--------
> >   drivers/usb/dwc2/platform.c  |   9 ++
> >   5 files changed, 272 insertions(+), 62 deletions(-)
> > 
> > 
> > base-commit: 9bc46a12c53d8268392774172742aa9e5dd6953d
> > 
> This cover letter for the clock gating patches is being rejected by 
> "vger.kernel.org". I have tried to send one more time as v2 but again it 
> is rejected.
> The error message is "vger.kernel.org
> Remote Server returned '554 5.7.1 <vger.kernel.org #5.7.1 smtp; 550 
> 5.7.1 Content-Policy accept-into-freezer-1"
> 
> Could you please suggest any solution to this?

No idea, sorry, vger is fickle when it comes to odd rules it has for
things it has to deal with.  Looks like your patches came through just
fine, so all is good.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2021-04-13 10:26 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1618297800.git.Arthur.Petrosyan@synopsys.com>
2021-04-13  7:16 ` [PATCH 01/12] usb: dwc2: Add device clock gating support functions Artur Petrosyan
2021-04-13  7:16 ` [PATCH 02/12] usb: dwc2: Add host " Artur Petrosyan
2021-04-13  7:16 ` [PATCH 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
2021-04-13  9:25   ` Sergei Shtylyov
2021-04-13  7:16 ` [PATCH 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt Artur Petrosyan
2021-04-13  7:16 ` [PATCH 05/12] usb: dwc2: Add exit clock gating from session request interrupt Artur Petrosyan
2021-04-13  7:16 ` [PATCH 06/12] usb: dwc2: Add exit clock gating when port reset is asserted Artur Petrosyan
2021-04-13  7:17 ` [PATCH 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
2021-04-13  9:22   ` Sergei Shtylyov
2021-04-13 10:24     ` Greg Kroah-Hartman
2021-04-13  7:17 ` [PATCH 08/12] usb: dwc2: Update exit clock gating when port is resumed Artur Petrosyan
2021-04-13  7:17 ` [PATCH 09/12] usb: dwc2: Allow exit clock gating in urb enqueue Artur Petrosyan
2021-04-13  7:17 ` [PATCH 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
2021-04-13  7:17 ` [PATCH 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
2021-04-13  7:17 ` [PATCH 12/12] usb: dwc2: Add exit clock gating before removing driver Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 01/12] usb: dwc2: Add device clock gating support functions Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 02/12] usb: dwc2: Add host " Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 03/12] usb: dwc2: Allow entering clock gating from USB_SUSPEND interrupt Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 04/12] usb: dwc2: Add exit clock gating from wakeup interrupt Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 05/12] usb: dwc2: Add exit clock gating from session request interrupt Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 06/12] usb: dwc2: Add exit clock gating when port reset is asserted Artur Petrosyan
2021-04-13  7:36 ` [PATCH v2 07/12] usb: dwc2: Update enter clock gating when port is suspended Artur Petrosyan
2021-04-13  7:37 ` [PATCH v2 08/12] usb: dwc2: Update exit clock gating when port is resumed Artur Petrosyan
2021-04-13  7:37 ` [PATCH v2 09/12] usb: dwc2: Allow exit clock gating in urb enqueue Artur Petrosyan
2021-04-13  7:37 ` [PATCH v2 10/12] usb: dwc2: Add clock gating entering flow by system suspend Artur Petrosyan
2021-04-13  9:29   ` Sergei Shtylyov
2021-04-13  7:37 ` [PATCH v2 11/12] usb: dwc2: Add clock gating exiting flow by system resume Artur Petrosyan
2021-04-13  9:30   ` Sergei Shtylyov
2021-04-13  7:37 ` [PATCH v2 12/12] usb: dwc2: Add exit clock gating before removing driver Artur Petrosyan
     [not found] ` <20210413073600.57846A0094@mailhost.synopsys.com>
2021-04-13  8:03   ` [PATCH v2 00/12] usb: dwc2: Add clock gating support Artur Petrosyan
2021-04-13 10:26     ` Greg Kroah-Hartman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).