Commit e07c5a35 authored by Lijo Lazar's avatar Lijo Lazar Committed by Alex Deucher
Browse files

drm/amd/pm: Add support to select pstate policy



Add support to select pstate policy in SOCs with SMUv13.0.6

Signed-off-by: default avatarLijo Lazar <lijo.lazar@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: default avatarAsad Kamal <asad.kamal@amd.com>
Acked-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ec41bdd8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -531,10 +531,12 @@ int smu_v13_0_fini_smc_tables(struct smu_context *smu)
	smu_table->watermarks_table = NULL;
	smu_table->metrics_time = 0;

	kfree(smu_dpm->dpm_policies);
	kfree(smu_dpm->dpm_context);
	kfree(smu_dpm->golden_dpm_context);
	kfree(smu_dpm->dpm_current_power_state);
	kfree(smu_dpm->dpm_request_power_state);
	smu_dpm->dpm_policies = NULL;
	smu_dpm->dpm_context = NULL;
	smu_dpm->golden_dpm_context = NULL;
	smu_dpm->dpm_context_size = 0;
+71 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COU
	MSG_MAP(McaBankCeDumpDW,                     PPSMC_MSG_McaBankCeDumpDW,                 SMU_MSG_RAS_PRI),
	MSG_MAP(SelectPLPDMode,                      PPSMC_MSG_SelectPLPDMode,                  0),
	MSG_MAP(RmaDueToBadPageThreshold,            PPSMC_MSG_RmaDueToBadPageThreshold,        0),
	MSG_MAP(SelectPstatePolicy,                  PPSMC_MSG_SelectPstatePolicy,              0),
};

// clang-format on
@@ -369,6 +370,39 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu)
	return 0;
}

static int smu_v13_0_6_select_policy_soc_pstate(struct smu_context *smu,
						int policy)
{
	struct amdgpu_device *adev = smu->adev;
	int ret, param;

	switch (policy) {
	case SOC_PSTATE_DEFAULT:
		param = 0;
		break;
	case SOC_PSTATE_0:
		param = 1;
		break;
	case SOC_PSTATE_1:
		param = 2;
		break;
	case SOC_PSTATE_2:
		param = 3;
		break;
	default:
		return -EINVAL;
	}

	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SelectPstatePolicy,
					      param, NULL);

	if (ret)
		dev_err(adev->dev, "select soc pstate policy %d failed",
			policy);

	return ret;
}

static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu)
{
	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
@@ -379,6 +413,24 @@ static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu)
		return -ENOMEM;
	smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context);

	if (!(smu->adev->flags & AMD_IS_APU)) {
		struct smu_dpm_policy *policy;

		smu_dpm->dpm_policies =
			kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL);
		policy = &(smu_dpm->dpm_policies->policies[0]);

		policy->policy_type = PP_PM_POLICY_SOC_PSTATE;
		policy->level_mask = BIT(SOC_PSTATE_DEFAULT) |
				     BIT(SOC_PSTATE_0) | BIT(SOC_PSTATE_1) |
				     BIT(SOC_PSTATE_2);
		policy->current_level = SOC_PSTATE_DEFAULT;
		policy->set_policy = smu_v13_0_6_select_policy_soc_pstate;
		smu_cmn_generic_soc_policy_desc(policy);
		smu_dpm->dpm_policies->policy_mask |=
			BIT(PP_PM_POLICY_SOC_PSTATE);
	}

	return 0;
}

@@ -639,6 +691,15 @@ static int smu_v13_0_6_get_dpm_level_count(struct smu_context *smu,
	return ret;
}

static void smu_v13_0_6_pm_policy_init(struct smu_context *smu)
{
	struct smu_dpm_policy *policy;

	policy = smu_get_pm_policy(smu, PP_PM_POLICY_SOC_PSTATE);
	if (policy)
		policy->current_level = SOC_PSTATE_DEFAULT;
}

static int smu_v13_0_6_set_default_dpm_table(struct smu_context *smu)
{
	struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
@@ -668,6 +729,16 @@ static int smu_v13_0_6_set_default_dpm_table(struct smu_context *smu)

	smu_v13_0_6_setup_driver_pptable(smu);

	/* DPM policy not supported in older firmwares */
	if (!(smu->adev->flags & AMD_IS_APU) &&
	    (smu->smc_fw_version < 0x00556000)) {
		struct smu_dpm_context *smu_dpm = &smu->smu_dpm;

		smu_dpm->dpm_policies->policy_mask &=
			~BIT(PP_PM_POLICY_SOC_PSTATE);
	}

	smu_v13_0_6_pm_policy_init(smu);
	/* gfxclk dpm table setup */
	dpm_table = &dpm_context->dpm_tables.gfx_table;
	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
+30 −0
Original line number Diff line number Diff line
@@ -1135,3 +1135,33 @@ bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)

	return snd_driver_loaded;
}

static char *smu_soc_policy_get_desc(struct smu_dpm_policy *policy, int level)
{
	if (level < 0 || !(policy->level_mask & BIT(level)))
		return "Invalid";

	switch (level) {
	case SOC_PSTATE_DEFAULT:
		return "soc_pstate_default";
	case SOC_PSTATE_0:
		return "soc_pstate_0";
	case SOC_PSTATE_1:
		return "soc_pstate_1";
	case SOC_PSTATE_2:
		return "soc_pstate_2";
	}

	return "Invalid";
}

static struct smu_dpm_policy_desc pstate_policy_desc = {
	.name = STR_SOC_PSTATE_POLICY,
	.get_desc = smu_soc_policy_get_desc,
};

void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy)
{
	policy->desc = &pstate_policy_desc;
}
+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ static inline void smu_cmn_get_sysfs_buf(char **buf, int *offset)
}

bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev);
void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy);

#endif
#endif