From: Vardan Mikayelyan <mvar...@synopsys.com>

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 <mvar...@synopsys.com>
Signed-off-by: John Youn <johny...@synopsys.com>
Signed-off-by: Grigor Tovmasyan <tovma...@synopsys.com>
---
 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 e26aeda29bba..ebe5a291f1a3 100644
--- a/drivers/usb/dwc2/core.c
+++ b/drivers/usb/dwc2/core.c
@@ -138,7 +138,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 93c58a4175c3..aab080bf8ef5 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -426,7 +426,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
  * @lpm:               Enable LPM support.
  *                     0 - No
  *                     1 - Yes
@@ -498,7 +499,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 lpm;
        bool lpm_clock_gating;
        bool besl;
@@ -578,6 +584,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
@@ -609,6 +616,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;
        unsigned lpm_mode:1;
        u32 snpsid;
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index 96a751d927d1..050e01e193c8 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -4359,7 +4359,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;
 
        /*
@@ -4414,7 +4414,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 c472e93de350..8c4ede8a4eea 100644
--- a/drivers/usb/dwc2/params.c
+++ b/drivers/usb/dwc2/params.c
@@ -469,6 +469,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;
@@ -530,6 +562,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);
@@ -719,6 +752,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;
        hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
-- 
2.11.0

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

Reply via email to