From: Vardan Mikayelyan <mvardan@xxxxxxxxxxxx> 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> Signed-off-by: Grigor Tovmasyan <tovmasya@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, 48 insertions(+), 4 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 6946f699e64e..35bd0bb101f7 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 a3413fc4cfd6..50fb68e49b52 100644 --- a/drivers/usb/dwc2/core.h +++ b/drivers/usb/dwc2/core.h @@ -426,6 +426,8 @@ enum dwc2_ep0_state { * power_down in both peripheral and host mode when * needed. * 0 - No (default) + * 1 - Partial power down + * 2 - Hibernation * 1 - Yes * @lpm: Enable LPM support. * 0 - No (default) @@ -440,6 +442,7 @@ enum dwc2_ep0_state { * 0 - No (default) * 1 - Yes * @hird_threshold: Value of BESL or HIRD Threshold. + * * @activate_stm_fs_transceiver: Activate internal transceiver using GGPIO * register. * 0 - Deactivate the transceiver (default) @@ -498,7 +501,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 +586,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 +618,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 41c3126bbe58..b81db01c2bb8 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -4335,7 +4335,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; /* @@ -4390,7 +4390,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 c5002321bdf2..443d03de5e2d 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) hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA); hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED); 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; -- 2.11.0 -- 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