Commit 73abde4d authored by Matt Coffin's avatar Matt Coffin Committed by Alex Deucher
Browse files

drm/amdgpu/smu_v11: Unify and fix power limits



[Why]
On Navi10, and presumably arcterus, updating pp_table via sysfs would
not re-scale the maximum possible power limit one can set. On navi10,
the SMU code ignored the power percentage overdrive setting entirely,
and would not allow you to exceed the default power limit at all.

[How]
Adding a function to the SMU interface to get the pptable version of the
default power limit allows ASIC-specific code to provide the correct
maximum-settable power limit for the current pptable.

v3: fix spelling (Alex)

Reviewed-by: default avatarEvan Quan <evan.quan@amd.com>
Signed-off-by: default avatarMatt Coffin <mcoffin13@gmail.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7f3353f6
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -1109,7 +1109,7 @@ static int smu_smc_table_hw_init(struct smu_context *smu,
		if (ret)
			return ret;

		ret = smu_get_power_limit(smu, &smu->default_power_limit, true, false);
		ret = smu_get_power_limit(smu, &smu->default_power_limit, false, false);
		if (ret)
			return ret;
	}
@@ -2511,3 +2511,13 @@ int smu_get_dpm_clock_table(struct smu_context *smu,

	return ret;
}

uint32_t smu_get_pptable_power_limit(struct smu_context *smu)
{
	uint32_t ret = 0;

	if (smu->ppt_funcs->get_pptable_power_limit)
		ret = smu->ppt_funcs->get_pptable_power_limit(smu);

	return ret;
}
+12 −11
Original line number Diff line number Diff line
@@ -1261,15 +1261,14 @@ arcturus_get_profiling_clk_mask(struct smu_context *smu,

static int arcturus_get_power_limit(struct smu_context *smu,
				     uint32_t *limit,
				     bool asic_default)
				     bool cap)
{
	PPTable_t *pptable = smu->smu_table.driver_pptable;
	uint32_t asic_default_power_limit = 0;
	int ret = 0;
	int power_src;

	if (!smu->default_power_limit ||
	    !smu->power_limit) {
	if (!smu->power_limit) {
		if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
			power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC);
			if (power_src < 0)
@@ -1292,17 +1291,11 @@ static int arcturus_get_power_limit(struct smu_context *smu,
				pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
		}

		if (smu->od_enabled) {
			asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit);
			asic_default_power_limit /= 100;
		}

		smu->default_power_limit = asic_default_power_limit;
		smu->power_limit = asic_default_power_limit;
	}

	if (asic_default)
		*limit = smu->default_power_limit;
	if (cap)
		*limit = smu_v11_0_get_max_power_limit(smu);
	else
		*limit = smu->power_limit;

@@ -2070,6 +2063,13 @@ static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter *control)
	i2c_del_adapter(control);
}

static uint32_t arcturus_get_pptable_power_limit(struct smu_context *smu)
{
	PPTable_t *pptable = smu->smu_table.driver_pptable;

	return pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
}

static const struct pptable_funcs arcturus_ppt_funcs = {
	/* translate smu index into arcturus specific index */
	.get_smu_msg_index = arcturus_get_smu_msg_index,
@@ -2160,6 +2160,7 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
	.get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
	.set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
	.override_pcie_parameters = smu_v11_0_override_pcie_parameters,
	.get_pptable_power_limit = arcturus_get_pptable_power_limit,
};

void arcturus_set_ppt_funcs(struct smu_context *smu)
+3 −1
Original line number Diff line number Diff line
@@ -261,7 +261,6 @@ struct smu_table_context
	struct smu_table		*tables;
	struct smu_table		memory_pool;
	uint8_t                         thermal_controller_type;
	uint16_t			TDPODLimit;

	void				*overdrive_table;
};
@@ -548,6 +547,7 @@ struct pptable_funcs {
	int (*get_dpm_ultimate_freq)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t *min, uint32_t *max);
	int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);
	int (*override_pcie_parameters)(struct smu_context *smu);
	uint32_t (*get_pptable_power_limit)(struct smu_context *smu);
};

int smu_load_microcode(struct smu_context *smu);
@@ -717,4 +717,6 @@ int smu_get_uclk_dpm_states(struct smu_context *smu,
int smu_get_dpm_clock_table(struct smu_context *smu,
			    struct dpm_clocks *clock_table);

uint32_t smu_get_pptable_power_limit(struct smu_context *smu);

#endif
+2 −0
Original line number Diff line number Diff line
@@ -252,4 +252,6 @@ int smu_v11_0_override_pcie_parameters(struct smu_context *smu);

int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize, size_t overdrive_table_size);

uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu);

#endif
+2 −0
Original line number Diff line number Diff line
@@ -141,7 +141,9 @@ struct smu_11_0_powerplay_table
      struct smu_11_0_power_saving_clock_table      power_saving_clock;
      struct smu_11_0_overdrive_table               overdrive_table;

#ifndef SMU_11_0_PARTIAL_PPTABLE
      PPTable_t smc_pptable;                        //PPTable_t in smu11_driver_if.h
#endif
} __attribute__((packed));

#endif
Loading