Commit 631a2310 authored by Vardan Mikayelyan's avatar Vardan Mikayelyan Committed by Felipe Balbi

usb: dwc2: Add hibernation field into dwc2_hw_params

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: default avatarVardan Mikayelyan <mvardan@synopsys.com>
Signed-off-by: default avatarJohn Youn <johnyoun@synopsys.com>
Signed-off-by: default avatarGrigor Tovmasyan <tovmasya@synopsys.com>
Signed-off-by: default avatarFelipe Balbi <felipe.balbi@linux.intel.com>
parent 41ba9b9b
...@@ -138,7 +138,7 @@ int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore) ...@@ -138,7 +138,7 @@ int dwc2_exit_partial_power_down(struct dwc2_hsotg *hsotg, bool restore)
u32 pcgcctl; u32 pcgcctl;
int ret = 0; int ret = 0;
if (!hsotg->params.power_down) if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
return -ENOTSUPP; return -ENOTSUPP;
pcgcctl = dwc2_readl(hsotg->regs + PCGCTL); pcgcctl = dwc2_readl(hsotg->regs + PCGCTL);
......
...@@ -426,7 +426,8 @@ enum dwc2_ep0_state { ...@@ -426,7 +426,8 @@ enum dwc2_ep0_state {
* power_down in both peripheral and host mode when * power_down in both peripheral and host mode when
* needed. * needed.
* 0 - No (default) * 0 - No (default)
* 1 - Yes * 1 - Partial power down
* 2 - Hibernation
* @lpm: Enable LPM support. * @lpm: Enable LPM support.
* 0 - No * 0 - No
* 1 - Yes * 1 - Yes
...@@ -498,7 +499,12 @@ struct dwc2_core_params { ...@@ -498,7 +499,12 @@ struct dwc2_core_params {
bool reload_ctl; bool reload_ctl;
bool uframe_sched; bool uframe_sched;
bool external_id_pin_ctl; 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;
bool lpm_clock_gating; bool lpm_clock_gating;
bool besl; bool besl;
...@@ -579,6 +585,7 @@ struct dwc2_core_params { ...@@ -579,6 +585,7 @@ struct dwc2_core_params {
* 2 - FS pins shared with UTMI+ pins * 2 - FS pins shared with UTMI+ pins
* 3 - FS pins shared with ULPI pins * 3 - FS pins shared with ULPI pins
* @total_fifo_size: Total internal RAM for FIFOs (bytes) * @total_fifo_size: Total internal RAM for FIFOs (bytes)
* @hibernation Is hibernation enabled?
* @utmi_phy_data_width UTMI+ PHY data width * @utmi_phy_data_width UTMI+ PHY data width
* 0 - 8 bits * 0 - 8 bits
* 1 - 16 bits * 1 - 16 bits
...@@ -612,6 +619,7 @@ struct dwc2_hw_params { ...@@ -612,6 +619,7 @@ struct dwc2_hw_params {
unsigned num_dev_perio_in_ep:4; unsigned num_dev_perio_in_ep:4;
unsigned total_fifo_size:16; unsigned total_fifo_size:16;
unsigned power_optimized:1; unsigned power_optimized:1;
unsigned hibernation:1;
unsigned utmi_phy_data_width:2; unsigned utmi_phy_data_width:2;
unsigned lpm_mode:1; unsigned lpm_mode:1;
u32 snpsid; u32 snpsid;
......
...@@ -4364,7 +4364,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) ...@@ -4364,7 +4364,7 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd)
if (hsotg->op_state == OTG_STATE_B_PERIPHERAL) if (hsotg->op_state == OTG_STATE_B_PERIPHERAL)
goto unlock; goto unlock;
if (!hsotg->params.power_down) if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL)
goto skip_power_saving; goto skip_power_saving;
/* /*
...@@ -4419,7 +4419,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd) ...@@ -4419,7 +4419,7 @@ static int _dwc2_hcd_resume(struct usb_hcd *hcd)
if (hsotg->lx_state != DWC2_L2) if (hsotg->lx_state != DWC2_L2)
goto unlock; goto unlock;
if (!hsotg->params.power_down) { if (hsotg->params.power_down != DWC2_POWER_DOWN_PARAM_PARTIAL) {
hsotg->lx_state = DWC2_L0; hsotg->lx_state = DWC2_L0;
goto unlock; goto unlock;
} }
......
...@@ -469,6 +469,38 @@ static void dwc2_check_param_phy_utmi_width(struct dwc2_hsotg *hsotg) ...@@ -469,6 +469,38 @@ static void dwc2_check_param_phy_utmi_width(struct dwc2_hsotg *hsotg)
dwc2_set_param_phy_utmi_width(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) static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
{ {
int fifo_count; int fifo_count;
...@@ -529,6 +561,7 @@ static void dwc2_check_params(struct dwc2_hsotg *hsotg) ...@@ -529,6 +561,7 @@ static void dwc2_check_params(struct dwc2_hsotg *hsotg)
dwc2_check_param_phy_type(hsotg); dwc2_check_param_phy_type(hsotg);
dwc2_check_param_speed(hsotg); dwc2_check_param_speed(hsotg);
dwc2_check_param_phy_utmi_width(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(enable_dynamic_fifo, hw->enable_dynamic_fifo);
CHECK_BOOL(en_multiple_tx_fifo, hw->en_multiple_tx_fifo); CHECK_BOOL(en_multiple_tx_fifo, hw->en_multiple_tx_fifo);
CHECK_BOOL(i2c_enable, hw->i2c_enable); CHECK_BOOL(i2c_enable, hw->i2c_enable);
...@@ -729,6 +762,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) ...@@ -729,6 +762,7 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
GHWCFG4_NUM_IN_EPS_SHIFT; GHWCFG4_NUM_IN_EPS_SHIFT;
hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA); hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ); hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
hw->hibernation = !!(hwcfg4 & GHWCFG4_HIBER);
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >> hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT; GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED); hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment