Commit 3e55d231 authored by Sasha Neftin's avatar Sasha Neftin Committed by Tony Nguyen

e1000e: Add handshake with the CSME to support S0ix

On the corporate system, the driver will ask from the CSME
(manageability engine) to perform device settings are required
to allow S0ix residency.
This patch provides initial support.
Reviewed-by: default avatarDima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: default avatarSasha Neftin <sasha.neftin@intel.com>
Tested-by: default avatarDvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 8887ca54
......@@ -47,6 +47,8 @@
#define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8))
#define E1000_H2ME 0x05B50 /* Host to ME */
#define E1000_H2ME_START_DPG 0x00000001 /* indicate the ME of DPG */
#define E1000_H2ME_EXIT_DPG 0x00000002 /* indicate the ME exit DPG */
#define E1000_H2ME_ULP 0x00000800 /* ULP Indication Bit */
#define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */
......
......@@ -6343,6 +6343,14 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
u32 mac_data;
u16 phy_data;
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
/* Request ME configure the device for S0ix */
mac_data = er32(H2ME);
mac_data |= E1000_H2ME_START_DPG;
mac_data &= ~E1000_H2ME_EXIT_DPG;
ew32(H2ME, mac_data);
} else {
/* Request driver configure the device to S0ix */
/* Disable the periodic inband message,
* don't request PCIe clock in K1 page770_17[10:9] = 10b
*/
......@@ -6380,57 +6388,11 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
ew32(EXTCNF_CTRL, mac_data);
/* Check MAC Tx/Rx packet buffer pointers.
* Reset MAC Tx/Rx packet buffer pointers to suppress any
* pending traffic indication that would prevent power gating.
*/
mac_data = er32(TDFH);
if (mac_data)
ew32(TDFH, 0);
mac_data = er32(TDFT);
if (mac_data)
ew32(TDFT, 0);
mac_data = er32(TDFHS);
if (mac_data)
ew32(TDFHS, 0);
mac_data = er32(TDFTS);
if (mac_data)
ew32(TDFTS, 0);
mac_data = er32(TDFPC);
if (mac_data)
ew32(TDFPC, 0);
mac_data = er32(RDFH);
if (mac_data)
ew32(RDFH, 0);
mac_data = er32(RDFT);
if (mac_data)
ew32(RDFT, 0);
mac_data = er32(RDFHS);
if (mac_data)
ew32(RDFHS, 0);
mac_data = er32(RDFTS);
if (mac_data)
ew32(RDFTS, 0);
mac_data = er32(RDFPC);
if (mac_data)
ew32(RDFPC, 0);
/* Enable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(22);
ew32(FEXTNVM7, mac_data);
/* Disable the time synchronization clock */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(31);
mac_data &= ~BIT(0);
ew32(FEXTNVM7, mac_data);
/* Dynamic Power Gating Enable */
mac_data = er32(CTRL_EXT);
mac_data |= BIT(3);
ew32(CTRL_EXT, mac_data);
/* Disable disconnected cable conditioning for Power Gating */
mac_data = er32(DPGFR);
mac_data |= BIT(2);
......@@ -6467,6 +6429,53 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
mac_data = er32(FEXTNVM5);
mac_data |= BIT(7);
ew32(FEXTNVM5, mac_data);
}
/* Disable the time synchronization clock */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(31);
mac_data &= ~BIT(0);
ew32(FEXTNVM7, mac_data);
/* Dynamic Power Gating Enable */
mac_data = er32(CTRL_EXT);
mac_data |= BIT(3);
ew32(CTRL_EXT, mac_data);
/* Check MAC Tx/Rx packet buffer pointers.
* Reset MAC Tx/Rx packet buffer pointers to suppress any
* pending traffic indication that would prevent power gating.
*/
mac_data = er32(TDFH);
if (mac_data)
ew32(TDFH, 0);
mac_data = er32(TDFT);
if (mac_data)
ew32(TDFT, 0);
mac_data = er32(TDFHS);
if (mac_data)
ew32(TDFHS, 0);
mac_data = er32(TDFTS);
if (mac_data)
ew32(TDFTS, 0);
mac_data = er32(TDFPC);
if (mac_data)
ew32(TDFPC, 0);
mac_data = er32(RDFH);
if (mac_data)
ew32(RDFH, 0);
mac_data = er32(RDFT);
if (mac_data)
ew32(RDFT, 0);
mac_data = er32(RDFHS);
if (mac_data)
ew32(RDFHS, 0);
mac_data = er32(RDFTS);
if (mac_data)
ew32(RDFTS, 0);
mac_data = er32(RDFPC);
if (mac_data)
ew32(RDFPC, 0);
}
static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
......@@ -6475,16 +6484,20 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
u32 mac_data;
u16 phy_data;
if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID) {
/* Request ME unconfigure the device from S0ix */
mac_data = er32(H2ME);
mac_data &= ~E1000_H2ME_START_DPG;
mac_data |= E1000_H2ME_EXIT_DPG;
ew32(H2ME, mac_data);
} else {
/* Request driver unconfigure the device from S0ix */
/* Disable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7);
mac_data &= 0xFFBFFFFF;
ew32(FEXTNVM7, mac_data);
/* Enable the time synchronization clock */
mac_data = er32(FEXTNVM7);
mac_data |= BIT(0);
ew32(FEXTNVM7, mac_data);
/* Disable mPHY power gating for any link and speed */
mac_data = er32(FEXTNVM8);
mac_data &= ~BIT(9);
......@@ -6514,11 +6527,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data &= ~BIT(2);
ew32(DPGFR, mac_data);
/* Disable Dynamic Power Gating */
mac_data = er32(CTRL_EXT);
mac_data &= 0xFFFFFFF7;
ew32(CTRL_EXT, mac_data);
/* Disable the Dynamic Clock Gating in the DMA and MAC */
mac_data = er32(CTRL_EXT);
mac_data &= 0xFFF7FFFF;
......@@ -6556,6 +6564,18 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data = er32(CTRL_EXT);
mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_data);
}
/* Disable Dynamic Power Gating */
mac_data = er32(CTRL_EXT);
mac_data &= 0xFFFFFFF7;
ew32(CTRL_EXT, mac_data);
/* Enable the time synchronization clock */
mac_data = er32(FEXTNVM7);
mac_data &= ~BIT(31);
mac_data |= BIT(0);
ew32(FEXTNVM7, mac_data);
}
static int e1000e_pm_freeze(struct device *dev)
......
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