aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Coelho <luciano.coelho@intel.com>2019-10-19 06:03:30 -0400
committerKalle Valo <kvalo@codeaurora.org>2019-10-23 06:31:33 -0400
commit9a47cb988338796b70c544919a8b6ba1f2245edb (patch)
tree4f8ace383f408f13f0a02f45f0e3c5584ab6462a
parent91cf5dede57f9c4030c1378745d612eec2075652 (diff)
iwlwifi: pcie: add workaround for power gating in integrated 22000
Add a workaround that forces power gating to be enabled on integrated 22000 devices. This improves power saving in certain situations. Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-csr.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-prph.h5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c25
3 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index cb4c5514a556..695bbaa86273 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -279,6 +279,7 @@
279 * Indicates MAC is entering a power-saving sleep power-down. 279 * Indicates MAC is entering a power-saving sleep power-down.
280 * Not a good time to access device-internal resources. 280 * Not a good time to access device-internal resources.
281 */ 281 */
282#define CSR_GP_CNTRL_REG_FLAG_INIT_DONE (0x00000004)
282#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010) 283#define CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP (0x00000010)
283#define CSR_GP_CNTRL_REG_FLAG_XTAL_ON (0x00000400) 284#define CSR_GP_CNTRL_REG_FLAG_XTAL_ON (0x00000400)
284 285
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index f47e0f97acf8..23c25a7665f2 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -449,6 +449,11 @@ enum {
449#define PERSISTENCE_BIT BIT(12) 449#define PERSISTENCE_BIT BIT(12)
450#define PREG_WFPM_ACCESS BIT(12) 450#define PREG_WFPM_ACCESS BIT(12)
451 451
452#define HPM_HIPM_GEN_CFG 0xA03458
453#define HPM_HIPM_GEN_CFG_CR_PG_EN BIT(0)
454#define HPM_HIPM_GEN_CFG_CR_SLP_EN BIT(1)
455#define HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE BIT(10)
456
452#define UREG_DOORBELL_TO_ISR6 0xA05C04 457#define UREG_DOORBELL_TO_ISR6 0xA05C04
453#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0) 458#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
454#define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18) 459#define UREG_DOORBELL_TO_ISR6_SUSPEND BIT(18)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
index df8455f14e4d..ca3bb4d65b00 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
@@ -57,6 +57,24 @@
57#include "internal.h" 57#include "internal.h"
58#include "fw/dbg.h" 58#include "fw/dbg.h"
59 59
60static int iwl_pcie_gen2_force_power_gating(struct iwl_trans *trans)
61{
62 iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG,
63 HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
64 udelay(20);
65 iwl_set_bits_prph(trans, HPM_HIPM_GEN_CFG,
66 HPM_HIPM_GEN_CFG_CR_PG_EN |
67 HPM_HIPM_GEN_CFG_CR_SLP_EN);
68 udelay(20);
69 iwl_clear_bits_prph(trans, HPM_HIPM_GEN_CFG,
70 HPM_HIPM_GEN_CFG_CR_FORCE_ACTIVE);
71
72 iwl_trans_sw_reset(trans);
73 iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
74
75 return 0;
76}
77
60/* 78/*
61 * Start up NIC's basic functionality after it has been reset 79 * Start up NIC's basic functionality after it has been reset
62 * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) 80 * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop())
@@ -92,6 +110,13 @@ int iwl_pcie_gen2_apm_init(struct iwl_trans *trans)
92 110
93 iwl_pcie_apm_config(trans); 111 iwl_pcie_apm_config(trans);
94 112
113 if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000 &&
114 trans->cfg->integrated) {
115 ret = iwl_pcie_gen2_force_power_gating(trans);
116 if (ret)
117 return ret;
118 }
119
95 ret = iwl_finish_nic_init(trans, trans->trans_cfg); 120 ret = iwl_finish_nic_init(trans, trans->trans_cfg);
96 if (ret) 121 if (ret)
97 return ret; 122 return ret;