Commit 2c34c960 authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher
Browse files

drm/amd/powerplay: update swSMU VCN/JPEG PG logics



Add lock protections and avoid unnecessary actions
if the PG state is already the same as required.

Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Tested-by: default avatarMatt Coffin <mcoffin13@gmail.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f2e2573c
Loading
Loading
Loading
Loading
+56 −1
Original line number Diff line number Diff line
@@ -133,6 +133,56 @@ int smu_get_dpm_freq_range(struct smu_context *smu,
	return ret;
}

static int smu_dpm_set_vcn_enable(struct smu_context *smu,
				  bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (!smu->ppt_funcs->dpm_set_vcn_enable)
		return 0;

	mutex_lock(&power_gate->vcn_gate_lock);

	if (atomic_read(&power_gate->vcn_gated) ^ enable)
		goto out;

	ret = smu->ppt_funcs->dpm_set_vcn_enable(smu, enable);
	if (!ret)
		atomic_set(&power_gate->vcn_gated, !enable);

out:
	mutex_unlock(&power_gate->vcn_gate_lock);

	return ret;
}

static int smu_dpm_set_jpeg_enable(struct smu_context *smu,
				   bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (!smu->ppt_funcs->dpm_set_jpeg_enable)
		return 0;

	mutex_lock(&power_gate->jpeg_gate_lock);

	if (atomic_read(&power_gate->jpeg_gated) ^ enable)
		goto out;

	ret = smu->ppt_funcs->dpm_set_jpeg_enable(smu, enable);
	if (!ret)
		atomic_set(&power_gate->jpeg_gated, !enable);

out:
	mutex_unlock(&power_gate->jpeg_gate_lock);

	return ret;
}

/**
 * smu_dpm_set_power_gate - power gate/ungate the specific IP block
 *
@@ -649,6 +699,11 @@ static int smu_sw_init(void *handle)
	smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
	smu->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;

	atomic_set(&smu->smu_power.power_gate.vcn_gated, 1);
	atomic_set(&smu->smu_power.power_gate.jpeg_gated, 1);
	mutex_init(&smu->smu_power.power_gate.vcn_gate_lock);
	mutex_init(&smu->smu_power.power_gate.jpeg_gate_lock);

	smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
	smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
	smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
@@ -1973,7 +2028,7 @@ int smu_read_sensor(struct smu_context *smu,
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_VCN_POWER_STATE:
		*(uint32_t *)data = smu->smu_power.power_gate.vcn_gated ? 0 : 1;
		*(uint32_t *)data = atomic_read(&smu->smu_power.power_gate.vcn_gated) ? 0: 1;
		*size = 4;
		break;
	case AMDGPU_PP_SENSOR_MIN_FAN_RPM:
+0 −4
Original line number Diff line number Diff line
@@ -1849,8 +1849,6 @@ static bool arcturus_is_dpm_running(struct smu_context *smu)

static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (enable) {
@@ -1861,7 +1859,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
				return ret;
			}
		}
		power_gate->vcn_gated = false;
	} else {
		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
			ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0);
@@ -1870,7 +1867,6 @@ static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
				return ret;
			}
		}
		power_gate->vcn_gated = true;
	}

	return ret;
+4 −2
Original line number Diff line number Diff line
@@ -292,8 +292,10 @@ struct smu_dpm_context {
struct smu_power_gate {
	bool uvd_gated;
	bool vce_gated;
	bool vcn_gated;
	bool jpeg_gated;
	atomic_t vcn_gated;
	atomic_t jpeg_gated;
	struct mutex vcn_gate_lock;
	struct mutex jpeg_gate_lock;
};

struct smu_power_context {
+0 −8
Original line number Diff line number Diff line
@@ -785,8 +785,6 @@ static int navi10_set_default_dpm_table(struct smu_context *smu)

static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (enable) {
@@ -796,14 +794,12 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
			if (ret)
				return ret;
		}
		power_gate->vcn_gated = false;
	} else {
		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
			if (ret)
				return ret;
		}
		power_gate->vcn_gated = true;
	}

	return ret;
@@ -811,8 +807,6 @@ static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)

static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (enable) {
@@ -821,14 +815,12 @@ static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
			if (ret)
				return ret;
		}
		power_gate->jpeg_gated = false;
	} else {
		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL);
			if (ret)
				return ret;
		}
		power_gate->jpeg_gated = true;
	}

	return ret;
+0 −8
Original line number Diff line number Diff line
@@ -459,8 +459,6 @@ static enum amd_pm_state_type renoir_get_current_power_state(struct smu_context

static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (enable) {
@@ -470,14 +468,12 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
			if (ret)
				return ret;
		}
		power_gate->vcn_gated = false;
	} else {
		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
			if (ret)
				return ret;
		}
		power_gate->vcn_gated = true;
	}

	return ret;
@@ -485,8 +481,6 @@ static int renoir_dpm_set_vcn_enable(struct smu_context *smu, bool enable)

static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
{
	struct smu_power_context *smu_power = &smu->smu_power;
	struct smu_power_gate *power_gate = &smu_power->power_gate;
	int ret = 0;

	if (enable) {
@@ -495,14 +489,12 @@ static int renoir_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
			if (ret)
				return ret;
		}
		power_gate->jpeg_gated = false;
	} else {
		if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerDownJpeg, 0, NULL);
			if (ret)
				return ret;
		}
		power_gate->jpeg_gated = true;
	}

	return ret;
Loading