linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 3/4] usb: dwc2: Add dwc2_enable_acg function
@ 2017-05-10 12:26 Razmik Karapetyan
  0 siblings, 0 replies; only message in thread
From: Razmik Karapetyan @ 2017-05-10 12:26 UTC (permalink / raw)
  To: John Youn, Felipe Balbi, Greg Kroah-Hartman, linux-usb, linux-kernel
  Cc: Razmik Karapetyan

Added function for supporting Active Clock Gating functionality.
This function checks GHWCFG4 register and if ACG supported,
it sets GATEEN bit in PCGCCTL1 register and enables ACG.

According to ACG functional specification, enabling of ACG feature
in host mode done in host initialization, before turning Vbus on,
specifically in dwc2_core_host_init function.

Enabling of ACG feature in device mode done in device initialization,
before clearing the SftDiscon bit in DCTL.
This bit was cleared in dwc2_hsotg_core_connect() function.So
dwc2_enable_acg() called before dwc2_core_connect() calls.

Signed-off-by: Razmik Karapetyan <razmik@synopsys.com>
---
 drivers/usb/dwc2/core.c   | 16 ++++++++++++++++
 drivers/usb/dwc2/core.h   |  2 ++
 drivers/usb/dwc2/gadget.c | 12 ++++++++++--
 drivers/usb/dwc2/hcd.c    |  5 +++++
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index 42ac47f85bb4..21fa39eada5b 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -491,6 +491,22 @@ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg)
 	}
 }
 
+/*
+ * dwc2_enable_acg - enable active clock gating feature
+ */
+void dwc2_enable_acg(struct dwc2_hsotg *hsotg)
+{
+	u32 hwcfg4 = dwc2_readl(hsotg->regs + GHWCFG4);
+
+	if (hwcfg4 & GHWCFG4_ACG_SUPPORTED) {
+		u32 pcgcctl1 = dwc2_readl(hsotg->regs + PCGCCTL1);
+
+		dev_dbg(hsotg->dev, "Enabling Active Clock Gating\n");
+		pcgcctl1 |= PCGCCTL1_GATEEN;
+		dwc2_writel(pcgcctl1, hsotg->regs + PCGCCTL1);
+	}
+}
+
 /**
  * dwc2_dump_host_registers() - Prints the host registers
  *
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 67ca7575a940..a20d1665c68f 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -1115,6 +1115,8 @@ void dwc2_flush_rx_fifo(struct dwc2_hsotg *hsotg);
 void dwc2_enable_global_interrupts(struct dwc2_hsotg *hcd);
 void dwc2_disable_global_interrupts(struct dwc2_hsotg *hcd);
 
+void dwc2_enable_acg(struct dwc2_hsotg *hsotg);
+
 /* This function should be called on every hardware interrupt. */
 irqreturn_t dwc2_handle_common_intr(int irq, void *dev);
 
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c
index 98a4a79e7f6e..7c772f199b89 100644
--- a/drivers/usb/dwc2/gadget.c
+++ b/drivers/usb/dwc2/gadget.c
@@ -4357,6 +4357,8 @@ static int dwc2_hsotg_pullup(struct usb_gadget *gadget, int is_on)
 	if (is_on) {
 		hsotg->enabled = 1;
 		dwc2_hsotg_core_init_disconnected(hsotg, false);
+		/* Enable ACG feature in device mode,if supported */
+		dwc2_enable_acg(hsotg);
 		dwc2_hsotg_core_connect(hsotg);
 	} else {
 		dwc2_hsotg_core_disconnect(hsotg);
@@ -4389,8 +4391,11 @@ static int dwc2_hsotg_vbus_session(struct usb_gadget *gadget, int is_active)
 		hsotg->op_state = OTG_STATE_B_PERIPHERAL;
 
 		dwc2_hsotg_core_init_disconnected(hsotg, false);
-		if (hsotg->enabled)
+		if (hsotg->enabled) {
+			/* Enable ACG feature in device mode,if supported */
+			dwc2_enable_acg(hsotg);
 			dwc2_hsotg_core_connect(hsotg);
+		}
 	} else {
 		dwc2_hsotg_core_disconnect(hsotg);
 		dwc2_hsotg_disconnect(hsotg);
@@ -4755,8 +4760,11 @@ int dwc2_hsotg_resume(struct dwc2_hsotg *hsotg)
 
 		spin_lock_irqsave(&hsotg->lock, flags);
 		dwc2_hsotg_core_init_disconnected(hsotg, false);
-		if (hsotg->enabled)
+		if (hsotg->enabled) {
+			/* Enable ACG feature in device mode,if supported */
+			dwc2_enable_acg(hsotg);
 			dwc2_hsotg_core_connect(hsotg);
+		}
 		spin_unlock_irqrestore(&hsotg->lock, flags);
 	}
 
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 4fedc0cc584b..d60545eb4e47 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -2413,6 +2413,9 @@ static void dwc2_core_host_init(struct dwc2_hsotg *hsotg)
 		}
 	}
 
+	/* Enable ACG feature in host mode, if supported */
+	dwc2_enable_acg(hsotg);
+
 	/* Turn on the vbus power */
 	dev_dbg(hsotg->dev, "Init: Port Power? op_state=%d\n", hsotg->op_state);
 	if (hsotg->op_state == OTG_STATE_A_HOST) {
@@ -3279,6 +3282,8 @@ static void dwc2_conn_id_status_change(struct work_struct *work)
 		spin_lock_irqsave(&hsotg->lock, flags);
 		dwc2_hsotg_core_init_disconnected(hsotg, false);
 		spin_unlock_irqrestore(&hsotg->lock, flags);
+		/* Enable ACG feature in device mode,if supported */
+		dwc2_enable_acg(hsotg);
 		dwc2_hsotg_core_connect(hsotg);
 	} else {
 host:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2017-05-10 12:27 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10 12:26 [PATCH v3 3/4] usb: dwc2: Add dwc2_enable_acg function Razmik Karapetyan

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).