Commit 947c127b authored by Likun Gao's avatar Likun Gao Committed by Alex Deucher
Browse files

drm/amd/powerplay: move powerplay table operation out of smu_v11_0.c



move smu_v11_0_get_max_power_limit and smu_v11_0_set_thermal_range
function from smu_v11_0.c to asic specific _ppt.c to avoid powerplay
table conflict with different ASIC with smu11.

Signed-off-by: default avatarLikun Gao <Likun.Gao@amd.com>
Reviewed-by: default avatarKenneth Feng <kenneth.feng@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5278a159
Loading
Loading
Loading
Loading
+63 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#include "arcturus_ppsmc.h"
#include "nbio/nbio_7_4_offset.h"
#include "nbio/nbio_7_4_sh_mask.h"
#include "thm/thm_11_0_2_offset.h"
#include "thm/thm_11_0_2_sh_mask.h"
#include "amdgpu_xgmi.h"
#include <linux/i2c.h>
#include <linux/pci.h>
@@ -1350,7 +1352,7 @@ static int arcturus_get_power_limit(struct smu_context *smu,
	}

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

@@ -2428,6 +2430,64 @@ static void arcturus_log_thermal_throttling_event(struct smu_context *smu)
			log_buf);
}

static int arcturus_set_thermal_range(struct smu_context *smu,
				       struct smu_temperature_range range)
{
	struct amdgpu_device *adev = smu->adev;
	int low = SMU_THERMAL_MINIMUM_ALERT_TEMP;
	int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP;
	uint32_t val;
	struct smu_table_context *table_context = &smu->smu_table;
	struct smu_11_0_powerplay_table *powerplay_table = table_context->power_play_table;

	low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP,
			range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES);
	high = min((uint16_t)SMU_THERMAL_MAXIMUM_ALERT_TEMP, powerplay_table->software_shutdown_temp);

	if (low > high)
		return -EINVAL;

	val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff));
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff));
	val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);

	WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);

	return 0;
}

static uint32_t atcturus_get_max_power_limit(struct smu_context *smu) {
	uint32_t od_limit, max_power_limit;
	struct smu_11_0_powerplay_table *powerplay_table = NULL;
	struct smu_table_context *table_context = &smu->smu_table;
	powerplay_table = table_context->power_play_table;

	max_power_limit = smu_get_pptable_power_limit(smu);

	if (!max_power_limit) {
		// If we couldn't get the table limit, fall back on first-read value
		if (!smu->default_power_limit)
			smu->default_power_limit = smu->power_limit;
		max_power_limit = smu->default_power_limit;
	}

	if (smu->od_enabled) {
		od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);

		pr_debug("ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit);

		max_power_limit *= (100 + od_limit);
		max_power_limit /= 100;
	}

	return max_power_limit;
}

static const struct pptable_funcs arcturus_ppt_funcs = {
	/* translate smu index into arcturus specific index */
	.get_smu_msg_index = arcturus_get_smu_msg_index,
@@ -2519,6 +2579,8 @@ static const struct pptable_funcs arcturus_ppt_funcs = {
	.set_df_cstate = arcturus_set_df_cstate,
	.allow_xgmi_power_down = arcturus_allow_xgmi_power_down,
	.log_thermal_throttling_event = arcturus_log_thermal_throttling_event,
	.set_thermal_range = arcturus_set_thermal_range,
	.get_max_power_limit = atcturus_get_max_power_limit,
};

void arcturus_set_ppt_funcs(struct smu_context *smu)
+2 −0
Original line number Diff line number Diff line
@@ -572,6 +572,8 @@ struct pptable_funcs {
	int (*disable_umc_cdr_12gbps_workaround)(struct smu_context *smu);
	int (*set_power_source)(struct smu_context *smu, enum smu_power_src_type power_src);
	void (*log_thermal_throttling_event)(struct smu_context *smu);
	int (*set_thermal_range)(struct smu_context *smu, struct smu_temperature_range range);
	uint32_t (*get_max_power_limit)(struct smu_context *smu);
};

int smu_load_microcode(struct smu_context *smu);
+0 −2
Original line number Diff line number Diff line
@@ -261,8 +261,6 @@ int smu_v11_0_set_soft_freq_limited_range(struct smu_context *smu, enum smu_clk_

int smu_v11_0_override_pcie_parameters(struct smu_context *smu);

uint32_t smu_v11_0_get_max_power_limit(struct smu_context *smu);

int smu_v11_0_set_performance_level(struct smu_context *smu,
				    enum amd_dpm_forced_level level);

+63 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@
#include "smu_v11_0_ppsmc.h"
#include "nbio/nbio_2_3_offset.h"
#include "nbio/nbio_2_3_sh_mask.h"
#include "thm/thm_11_0_2_offset.h"
#include "thm/thm_11_0_2_sh_mask.h"

#include "asic_reg/mp/mp_11_0_sh_mask.h"

@@ -1873,7 +1875,7 @@ static int navi10_get_power_limit(struct smu_context *smu,
	}

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

@@ -2271,6 +2273,64 @@ static int navi10_disable_umc_cdr_12gbps_workaround(struct smu_context *smu)
	return navi10_dummy_pstate_control(smu, true);
}

static int navi10_set_thermal_range(struct smu_context *smu,
				       struct smu_temperature_range range)
{
	struct amdgpu_device *adev = smu->adev;
	int low = SMU_THERMAL_MINIMUM_ALERT_TEMP;
	int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP;
	uint32_t val;
	struct smu_table_context *table_context = &smu->smu_table;
	struct smu_11_0_powerplay_table *powerplay_table = table_context->power_play_table;

	low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP,
			range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES);
	high = min((uint16_t)SMU_THERMAL_MAXIMUM_ALERT_TEMP, powerplay_table->software_shutdown_temp);

	if (low > high)
		return -EINVAL;

	val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0);
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff));
	val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff));
	val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);

	WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);

	return 0;
}

static uint32_t navi10_get_max_power_limit(struct smu_context *smu) {
	uint32_t od_limit, max_power_limit;
	struct smu_11_0_powerplay_table *powerplay_table = NULL;
	struct smu_table_context *table_context = &smu->smu_table;
	powerplay_table = table_context->power_play_table;

	max_power_limit = smu_get_pptable_power_limit(smu);

	if (!max_power_limit) {
		// If we couldn't get the table limit, fall back on first-read value
		if (!smu->default_power_limit)
			smu->default_power_limit = smu->power_limit;
		max_power_limit = smu->default_power_limit;
	}

	if (smu->od_enabled) {
		od_limit = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);

		pr_debug("ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_limit, smu->default_power_limit);

		max_power_limit *= (100 + od_limit);
		max_power_limit /= 100;
	}

	return max_power_limit;
}

static const struct pptable_funcs navi10_ppt_funcs = {
	.tables_init = navi10_tables_init,
	.alloc_dpm_context = navi10_allocate_dpm_context,
@@ -2361,6 +2421,8 @@ static const struct pptable_funcs navi10_ppt_funcs = {
	.run_btc = navi10_run_btc,
	.disable_umc_cdr_12gbps_workaround = navi10_disable_umc_cdr_12gbps_workaround,
	.set_power_source = smu_v11_0_set_power_source,
	.set_thermal_range = navi10_set_thermal_range,
	.get_max_power_limit = navi10_get_max_power_limit,
};

void navi10_set_ppt_funcs(struct smu_context *smu)
+5 −0
Original line number Diff line number Diff line
@@ -194,6 +194,11 @@ static inline int smu_send_smc_msg(struct smu_context *smu, enum smu_message_typ
#define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \
		((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0)

#define smu_set_thermal_range(smu, range) \
		((smu)->ppt_funcs->set_thermal_range ? (smu)->ppt_funcs->set_thermal_range((smu), (range)) : 0)
#define smu_get_max_power_limit(smu) \
		((smu)->ppt_funcs->get_max_power_limit ? (smu)->ppt_funcs->get_max_power_limit((smu)) : 0)

#define smu_disable_umc_cdr_12gbps_workaround(smu) \
	((smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround ? (smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround((smu)) : 0)

Loading