diff options
Diffstat (limited to 'sys/contrib/dev/iwlwifi/mvm/tt.c')
| -rw-r--r-- | sys/contrib/dev/iwlwifi/mvm/tt.c | 97 | 
1 files changed, 64 insertions, 33 deletions
| diff --git a/sys/contrib/dev/iwlwifi/mvm/tt.c b/sys/contrib/dev/iwlwifi/mvm/tt.c index 95a5856cd239..1958f4ca4773 100644 --- a/sys/contrib/dev/iwlwifi/mvm/tt.c +++ b/sys/contrib/dev/iwlwifi/mvm/tt.c @@ -1,6 +1,6 @@  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause  /* - * Copyright (C) 2012-2014, 2019-2022, 2024 Intel Corporation + * Copyright (C) 2012-2014, 2019-2022, 2024-2025 Intel Corporation   * Copyright (C) 2013-2014 Intel Mobile Communications GmbH   * Copyright (C) 2015-2016 Intel Deutschland GmbH   */ @@ -10,6 +10,9 @@  #include "mvm.h" +#define IWL_MVM_NUM_CTDP_STEPS		20 +#define IWL_MVM_MIN_CTDP_BUDGET_MW	150 +  #define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT	HZ  void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) @@ -107,7 +110,7 @@ static bool iwl_mvm_temp_notif_wait(struct iwl_notif_wait_data *notif_wait,  void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)  {  	struct iwl_rx_packet *pkt = rxb_addr(rxb); -	struct iwl_dts_measurement_notif_v2 *notif_v2; +	struct iwl_dts_measurement_notif *notif_v2;  	int len = iwl_rx_packet_payload_len(pkt);  	int temp;  	u32 ths_crossed; @@ -481,43 +484,28 @@ static const struct iwl_tt_params iwl_mvm_default_tt_params = {  	.support_tx_backoff = true,  }; -/* budget in mWatt */ -static const u32 iwl_mvm_cdev_budgets[] = { -	2400,	/* cooling state 0 */ -	2000,	/* cooling state 1 */ -	1800,	/* cooling state 2 */ -	1600,	/* cooling state 3 */ -	1400,	/* cooling state 4 */ -	1200,	/* cooling state 5 */ -	1000,	/* cooling state 6 */ -	900,	/* cooling state 7 */ -	800,	/* cooling state 8 */ -	700,	/* cooling state 9 */ -	650,	/* cooling state 10 */ -	600,	/* cooling state 11 */ -	550,	/* cooling state 12 */ -	500,	/* cooling state 13 */ -	450,	/* cooling state 14 */ -	400,	/* cooling state 15 */ -	350,	/* cooling state 16 */ -	300,	/* cooling state 17 */ -	250,	/* cooling state 18 */ -	200,	/* cooling state 19 */ -	150,	/* cooling state 20 */ -}; -  int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state)  { -	struct iwl_mvm_ctdp_cmd cmd = { +	struct iwl_ctdp_cmd cmd = {  		.operation = cpu_to_le32(op), -		.budget = cpu_to_le32(iwl_mvm_cdev_budgets[state]),  		.window_size = 0,  	}; +	u32 budget;  	int ret;  	u32 status;  	lockdep_assert_held(&mvm->mutex); +	/* Do a linear scale from IWL_MVM_MIN_CTDP_BUDGET_MW to the configured +	 * maximum in the predefined number of steps. +	 */ +	budget = ((mvm->thermal_throttle.power_budget_mw - +		   IWL_MVM_MIN_CTDP_BUDGET_MW) * +		  (IWL_MVM_NUM_CTDP_STEPS - 1 - state)) / +		 (IWL_MVM_NUM_CTDP_STEPS - 1) + +		 IWL_MVM_MIN_CTDP_BUDGET_MW; +	cmd.budget = cpu_to_le32(budget); +  	status = 0;  	ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP,  						       CTDP_CONFIG_CMD), @@ -554,8 +542,8 @@ int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 state)  #ifdef CONFIG_THERMAL  static int compare_temps(const void *a, const void *b)  { -	return ((s16)le16_to_cpu(*(__le16 *)a) - -		(s16)le16_to_cpu(*(__le16 *)b)); +	return ((s16)le16_to_cpu(*(const __le16 *)a) - +		(s16)le16_to_cpu(*(const __le16 *)b));  }  struct iwl_trip_walk_data { @@ -709,7 +697,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)  static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,  				       unsigned long *state)  { -	*state = ARRAY_SIZE(iwl_mvm_cdev_budgets) - 1; +	*state = IWL_MVM_NUM_CTDP_STEPS - 1;  	return 0;  } @@ -735,7 +723,7 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev,  	    mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR)  		return -EIO; -	if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) +	if (new_state >= IWL_MVM_NUM_CTDP_STEPS)  		return -EINVAL;  	return iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START, @@ -796,6 +784,47 @@ static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm)  }  #endif /* CONFIG_THERMAL */ +static u32 iwl_mvm_ctdp_get_max_budget(struct iwl_mvm *mvm) +{ +	u64 bios_power_budget = 0; +	u32 default_power_budget; + +	switch (CSR_HW_RFID_TYPE(mvm->trans->info.hw_rf_id)) { +	case IWL_CFG_RF_TYPE_JF2: +	case IWL_CFG_RF_TYPE_JF1: +		default_power_budget = 2000; +		break; +	case IWL_CFG_RF_TYPE_HR2: +	case IWL_CFG_RF_TYPE_HR1: +		default_power_budget = 2400; +		break; +	case IWL_CFG_RF_TYPE_GF: +		/* dual-radio devices have a higher budget */ +		if (CSR_HW_RFID_IS_CDB(mvm->trans->info.hw_rf_id)) +			default_power_budget = 5200; +		else +			default_power_budget = 2880; +		break; +	case IWL_CFG_RF_TYPE_FM: +		default_power_budget = 3450; +		break; +	default: +		default_power_budget = 5550; +		break; +	} + +	iwl_bios_get_pwr_limit(&mvm->fwrt, &bios_power_budget); + +	/* 32bit in UEFI, 16bit in ACPI; use BIOS value if it is in range */ +	if (bios_power_budget && +	    bios_power_budget != 0xffff && bios_power_budget != 0xffffffff && +	    bios_power_budget >= IWL_MVM_MIN_CTDP_BUDGET_MW && +	    bios_power_budget <= default_power_budget) +		return (u32)bios_power_budget; + +	return default_power_budget; +} +  void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff)  {  	struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; @@ -807,6 +836,8 @@ void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff)  	else  		tt->params = iwl_mvm_default_tt_params; +	tt->power_budget_mw = iwl_mvm_ctdp_get_max_budget(mvm); +	IWL_DEBUG_TEMP(mvm, "cTDP power budget: %d mW\n", tt->power_budget_mw);  	tt->throttle = false;  	tt->dynamic_smps = false;  	tt->min_backoff = min_backoff; | 
