1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

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: Dima Ruinskiy <dima.ruinskiy@intel.com>
Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
Tested-by: Dvora Fuxbrumer <dvorax.fuxbrumer@linux.intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Sasha Neftin 2021-06-24 11:18:27 +03:00 committed by Tony Nguyen
parent 8887ca5474
commit 3e55d23171
2 changed files with 176 additions and 154 deletions

View file

@ -47,6 +47,8 @@
#define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8)) #define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8))
#define E1000_H2ME 0x05B50 /* Host to ME */ #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_ULP 0x00000800 /* ULP Indication Bit */
#define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */ #define E1000_H2ME_ENFORCE_SETTINGS 0x00001000 /* Enforce Settings */

View file

@ -6343,6 +6343,14 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
u32 mac_data; u32 mac_data;
u16 phy_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, /* Disable the periodic inband message,
* don't request PCIe clock in K1 page770_17[10:9] = 10b * 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; mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
ew32(EXTCNF_CTRL, mac_data); 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 */ /* Enable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7); mac_data = er32(FEXTNVM7);
mac_data |= BIT(22); mac_data |= BIT(22);
ew32(FEXTNVM7, mac_data); 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 */ /* Disable disconnected cable conditioning for Power Gating */
mac_data = er32(DPGFR); mac_data = er32(DPGFR);
mac_data |= BIT(2); mac_data |= BIT(2);
@ -6467,6 +6429,53 @@ static void e1000e_s0ix_entry_flow(struct e1000_adapter *adapter)
mac_data = er32(FEXTNVM5); mac_data = er32(FEXTNVM5);
mac_data |= BIT(7); mac_data |= BIT(7);
ew32(FEXTNVM5, mac_data); 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) 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; u32 mac_data;
u16 phy_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 */ /* Disable the Dynamic Power Gating in the MAC */
mac_data = er32(FEXTNVM7); mac_data = er32(FEXTNVM7);
mac_data &= 0xFFBFFFFF; mac_data &= 0xFFBFFFFF;
ew32(FEXTNVM7, mac_data); 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 */ /* Disable mPHY power gating for any link and speed */
mac_data = er32(FEXTNVM8); mac_data = er32(FEXTNVM8);
mac_data &= ~BIT(9); mac_data &= ~BIT(9);
@ -6514,11 +6527,6 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data &= ~BIT(2); mac_data &= ~BIT(2);
ew32(DPGFR, mac_data); 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 */ /* Disable the Dynamic Clock Gating in the DMA and MAC */
mac_data = er32(CTRL_EXT); mac_data = er32(CTRL_EXT);
mac_data &= 0xFFF7FFFF; mac_data &= 0xFFF7FFFF;
@ -6556,6 +6564,18 @@ static void e1000e_s0ix_exit_flow(struct e1000_adapter *adapter)
mac_data = er32(CTRL_EXT); mac_data = er32(CTRL_EXT);
mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS; mac_data &= ~E1000_CTRL_EXT_FORCE_SMBUS;
ew32(CTRL_EXT, mac_data); 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) static int e1000e_pm_freeze(struct device *dev)