[PATCH v2 02/14] usb: dwc2: Add hibernation field into dwc2_hw_params

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add parameter and it's initialization, needed for hibernation.

Reimplement dwc2_set_param_power_down() to support hibernation too.
Now 'power_down' parameter can be initialized with 0, 1 or 2.
0 - No
1 - Partial power down
2 - Hibernation

Signed-off-by: Vardan Mikayelyan <mvardan@xxxxxxxxxxxx>
Signed-off-by: John Youn <johnyoun@xxxxxxxxxxxx>
---
 drivers/usb/dwc2/core.c   |  2 +-
 drivers/usb/dwc2/core.h   | 12 ++++++++++--
 drivers/usb/dwc2/hcd.c    |  4 ++--
 drivers/usb/dwc2/params.c | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c
index e8708fd..fe976eb 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -135,7 +135,7 @@ int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore)
 	u32 pcgcctl;
 	int ret = 0;
 
-	if (!hsotg->params.power_down)
+	if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
 		return -ENOTSUPP;
 
 	pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 61c5e56..526d870 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -422,7 +422,8 @@ enum dwc2_ep0_state {
  *			power_down in both peripheral and host mode when
  *			needed.
  *			0 - No (default)
- *			1 - Yes
+ *			1 - Partial power down
+ *			2 - Hibernation
  * @activate_stm_fs_transceiver: Activate internal transceiver using GGPIO
  *			register.
  *			0 - Deactivate the transceiver (default)
@@ -480,7 +481,12 @@ struct dwc2_core_params {
 	bool reload_ctl;
 	bool uframe_sched;
 	bool external_id_pin_ctl;
-	bool power_down;
+
+	int power_down;
+#define DWC2_POWER_DOWN_PARAM_NONE		0
+#define DWC2_POWER_DOWN_PARAM_PARTIAL		1
+#define DWC2_POWER_DOWN_PARAM_HIBERNATION	2
+
 	bool activate_stm_fs_transceiver;
 	u16 max_packet_count;
 	u32 max_transfer_size;
@@ -554,6 +560,7 @@ struct dwc2_core_params {
  *                       2 - FS pins shared with UTMI+ pins
  *                       3 - FS pins shared with ULPI pins
  * @total_fifo_size:    Total internal RAM for FIFOs (bytes)
+ * @hibernation		Is hibernation enabled?
  * @utmi_phy_data_width UTMI+ PHY data width
  *                       0 - 8 bits
  *                       1 - 16 bits
@@ -584,6 +591,7 @@ struct dwc2_hw_params {
 	unsigned num_dev_perio_in_ep:4;
 	unsigned total_fifo_size:16;
 	unsigned power_optimized:1;
+	unsigned hibernation:1;
 	unsigned utmi_phy_data_width:2;
 	u32 snpsid;
 	u32 dev_ep_dirs;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 604356c..53d580f 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4396,7 +4396,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
 	if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
 		goto unlock;
 
-	if (!hsotg->params.power_down)
+	if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
 		goto skip_power_saving;
 
 	/*
@@ -4448,7 +4448,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
 	if (hsotg->lx_state != DWC2_L2)
 		goto unlock;
 
-	if (!hsotg->params.power_down) {
+	if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) {
 		hsotg->lx_state = DWC2_L0;
 		goto unlock;
 	}
diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c
index 38336e5..baa76bf 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -446,6 +446,38 @@ static void dwc2_check_param_phy_utmi_width(struct dwc2_hsotg *hsotg)
 		dwc2_set_param_phy_utmi_width(hsotg);
 }
 
+static void dwc2_check_param_power_down(struct dwc2_hsotg *hsotg)
+{
+	int param = hsotg->params.power_down;
+
+	switch (param) {
+	case DWC2_POWER_DOWN_PARAM_NONE:
+		break;
+	case DWC2_POWER_DOWN_PARAM_PARTIAL:
+		if (hsotg->hw_params.power_optimized)
+			break;
+		dev_dbg(hsotg->dev,
+			"Partial power down isn't supported by HW\n");
+		param = DWC2_POWER_DOWN_PARAM_NONE;
+		break;
+	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
+		if (hsotg->hw_params.hibernation)
+			break;
+		dev_dbg(hsotg->dev,
+			"Hibernation isn't supported by HW\n");
+		param = DWC2_POWER_DOWN_PARAM_NONE;
+		break;
+	default:
+		dev_err(hsotg->dev,
+			"%s: Invalid parameter power_down=%d\n",
+			__func__, param);
+		param = DWC2_POWER_DOWN_PARAM_NONE;
+		break;
+	}
+
+	hsotg->params.power_down = param;
+}
+
 static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
 {
 	int fifo_count;
@@ -507,6 +539,7 @@ static void dwc2_check_params(struct dwc2_hsotg *hsotg)
 	dwc2_check_param_phy_type(hsotg);
 	dwc2_check_param_speed(hsotg);
 	dwc2_check_param_phy_utmi_width(hsotg);
+	dwc2_check_param_power_down(hsotg);
 	CHECK_BOOL(enable_dynamic_fifo, hw->enable_dynamic_fifo);
 	CHECK_BOOL(en_multiple_tx_fifo, hw->en_multiple_tx_fifo);
 	CHECK_BOOL(i2c_enable, hw->i2c_enable);
@@ -688,6 +721,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
 				  GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
 	hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
 	hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
+	hw->hibernation = !!(hwcfg4 & GHWCFG4_HIBER);
 	hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
 				  GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
 
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux