Commit ed0022da authored by Johannes Berg's avatar Johannes Berg Committed by Kalle Valo
Browse files

iwlwifi: pcie: set LTR on more devices



To avoid completion timeouts during device boot, set up the
LTR timeouts on more devices - similar to what we had before
for AX210.

This also corrects the AX210 workaround to be done only on
discrete (non-integrated) devices, otherwise the registers
have no effect.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Fixes: edb62520 ("iwlwifi: pcie: set LTR to avoid completion timeout")
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/iwlwifi.20210115130252.fb819e19530b.I0396f82922db66426f52fbb70d32a29c8fd66951@changeid
parent 0f8d5656
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -301,6 +301,12 @@
#define RADIO_RSP_ADDR_POS		(6)
#define RADIO_RSP_RD_CMD		(3)

/* LTR control (Qu only) */
#define HPM_MAC_LTR_CSR			0xa0348c
#define HPM_MAC_LRT_ENABLE_ALL		0xf
/* also uses CSR_LTR_* for values */
#define HPM_UMAC_LTR			0xa03480

/* FW monitor */
#define MON_BUFF_SAMPLE_CTL		(0xa03c00)
#define MON_BUFF_BASE_ADDR		(0xa03c1c)
+22 −17
Original line number Diff line number Diff line
@@ -75,6 +75,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
				 const struct fw_img *fw)
{
	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
	u32 ltr_val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
		      u32_encode_bits(250,
				      CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
		      CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
		      u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
				      CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
		      u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);
	struct iwl_context_info_gen3 *ctxt_info_gen3;
	struct iwl_prph_scratch *prph_scratch;
	struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl;
@@ -206,23 +215,19 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
	iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
		    CSR_AUTO_FUNC_BOOT_ENA);

	if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210) {
	/*
		 * The firmware initializes this again later (to a smaller
		 * value), but for the boot process initialize the LTR to
		 * ~250 usec.
	 * To workaround hardware latency issues during the boot process,
	 * initialize the LTR to ~250 usec (see ltr_val above).
	 * The firmware initializes this again later (to a smaller value).
	 */
		u32 val = CSR_LTR_LONG_VAL_AD_NO_SNOOP_REQ |
			  u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
					  CSR_LTR_LONG_VAL_AD_NO_SNOOP_SCALE) |
			  u32_encode_bits(250,
					  CSR_LTR_LONG_VAL_AD_NO_SNOOP_VAL) |
			  CSR_LTR_LONG_VAL_AD_SNOOP_REQ |
			  u32_encode_bits(CSR_LTR_LONG_VAL_AD_SCALE_USEC,
					  CSR_LTR_LONG_VAL_AD_SNOOP_SCALE) |
			  u32_encode_bits(250, CSR_LTR_LONG_VAL_AD_SNOOP_VAL);

		iwl_write32(trans, CSR_LTR_LONG_VAL_AD, val);
	if ((trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_AX210 ||
	     trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) &&
	    !trans->trans_cfg->integrated) {
		iwl_write32(trans, CSR_LTR_LONG_VAL_AD, ltr_val);
	} else if (trans->trans_cfg->integrated &&
		   trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_22000) {
		iwl_write_prph(trans, HPM_MAC_LTR_CSR, HPM_MAC_LRT_ENABLE_ALL);
		iwl_write_prph(trans, HPM_UMAC_LTR, ltr_val);
	}

	if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)