Commit 7e01a2ec authored by Evan Quan's avatar Evan Quan Committed by Alex Deucher
Browse files

drm/amd/powerplay: correct SW SMU valid mapping check



Current implementation is not actually able to detect
invalid message/table/workload mapping.

Signed-off-by: default avatarEvan Quan <evan.quan@amd.com>
Reviewed-by: default avatarFeifei Xu <Feifei.Xu@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent a08a4dae
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ enum PP_SMC_POWER_PROFILE {
	PP_SMC_POWER_PROFILE_VR           = 0x4,
	PP_SMC_POWER_PROFILE_COMPUTE      = 0x5,
	PP_SMC_POWER_PROFILE_CUSTOM       = 0x6,
	PP_SMC_POWER_PROFILE_COUNT,
};

enum {
+8 −6
Original line number Diff line number Diff line
@@ -37,9 +37,9 @@
#include "nbio/nbio_7_4_sh_mask.h"

#define MSG_MAP(msg, index) \
	[SMU_MSG_##msg] = index
	[SMU_MSG_##msg] = {1, (index)}

static int arcturus_message_map[SMU_MSG_MAX_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping arcturus_message_map[SMU_MSG_MAX_COUNT] = {
	MSG_MAP(TestMessage,			     PPSMC_MSG_TestMessage),
	MSG_MAP(GetSmuVersion,			     PPSMC_MSG_GetSmuVersion),
	MSG_MAP(GetDriverIfVersion,		     PPSMC_MSG_GetDriverIfVersion),
@@ -101,16 +101,18 @@ static int arcturus_message_map[SMU_MSG_MAX_COUNT] = {

static int arcturus_get_smu_msg_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_MSG_MAX_COUNT)
		return -EINVAL;

	val = arcturus_message_map[index];
	if (val > PPSMC_Message_Count)
	mapping = arcturus_message_map[index];
	if (!(mapping.valid_mapping)) {
		pr_warn("Unsupported SMU message: %d\n", index);
		return -EINVAL;
	}

	return val;
	return mapping.map_to;
}

static const struct pptable_funcs arcturus_ppt_funcs = {
+10 −5
Original line number Diff line number Diff line
@@ -43,19 +43,24 @@
#define SMU11_TOOL_SIZE			0x19000

#define CLK_MAP(clk, index) \
	[SMU_##clk] = index
	[SMU_##clk] = {1, (index)}

#define FEA_MAP(fea) \
	[SMU_FEATURE_##fea##_BIT] = FEATURE_##fea##_BIT
	[SMU_FEATURE_##fea##_BIT] = {1, FEATURE_##fea##_BIT}

#define TAB_MAP(tab) \
	[SMU_TABLE_##tab] = TABLE_##tab
	[SMU_TABLE_##tab] = {1, TABLE_##tab}

#define PWR_MAP(tab) \
	[SMU_POWER_SOURCE_##tab] = POWER_SOURCE_##tab
	[SMU_POWER_SOURCE_##tab] = {1, POWER_SOURCE_##tab}

#define WORKLOAD_MAP(profile, workload) \
	[profile] = workload
	[profile] = {1, (workload)}

struct smu_11_0_cmn2aisc_mapping {
	int	valid_mapping;
	int	map_to;
};

struct smu_11_0_max_sustainable_clocks {
	uint32_t display_clock;
+38 −30
Original line number Diff line number Diff line
@@ -49,9 +49,9 @@
	FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT))

#define MSG_MAP(msg, index) \
	[SMU_MSG_##msg] = index
	[SMU_MSG_##msg] = {1, (index)}

static int navi10_message_map[SMU_MSG_MAX_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = {
	MSG_MAP(TestMessage,			PPSMC_MSG_TestMessage),
	MSG_MAP(GetSmuVersion,			PPSMC_MSG_GetSmuVersion),
	MSG_MAP(GetDriverIfVersion,		PPSMC_MSG_GetDriverIfVersion),
@@ -118,7 +118,7 @@ static int navi10_message_map[SMU_MSG_MAX_COUNT] = {
	MSG_MAP(ArmD3,			PPSMC_MSG_ArmD3),
};

static int navi10_clk_map[SMU_CLK_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping navi10_clk_map[SMU_CLK_COUNT] = {
	CLK_MAP(GFXCLK, PPCLK_GFXCLK),
	CLK_MAP(SCLK,	PPCLK_GFXCLK),
	CLK_MAP(SOCCLK, PPCLK_SOCCLK),
@@ -133,7 +133,7 @@ static int navi10_clk_map[SMU_CLK_COUNT] = {
	CLK_MAP(PHYCLK, PPCLK_PHYCLK),
};

static int navi10_feature_mask_map[SMU_FEATURE_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping navi10_feature_mask_map[SMU_FEATURE_COUNT] = {
	FEA_MAP(DPM_PREFETCHER),
	FEA_MAP(DPM_GFXCLK),
	FEA_MAP(DPM_GFX_PACE),
@@ -178,7 +178,7 @@ static int navi10_feature_mask_map[SMU_FEATURE_COUNT] = {
	FEA_MAP(ATHUB_PG),
};

static int navi10_table_map[SMU_TABLE_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping navi10_table_map[SMU_TABLE_COUNT] = {
	TAB_MAP(PPTABLE),
	TAB_MAP(WATERMARKS),
	TAB_MAP(AVFS),
@@ -193,12 +193,12 @@ static int navi10_table_map[SMU_TABLE_COUNT] = {
	TAB_MAP(PACE),
};

static int navi10_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping navi10_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
	PWR_MAP(AC),
	PWR_MAP(DC),
};

static int navi10_workload_map[] = {
static struct smu_11_0_cmn2aisc_mapping navi10_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT,	WORKLOAD_PPLIB_DEFAULT_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,		WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,		WORKLOAD_PPLIB_POWER_SAVING_BIT),
@@ -210,79 +210,87 @@ static int navi10_workload_map[] = {

static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index > SMU_MSG_MAX_COUNT)
		return -EINVAL;

	val = navi10_message_map[index];
	if (val > PPSMC_Message_Count)
	mapping = navi10_message_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_CLK_COUNT)
		return -EINVAL;

	val = navi10_clk_map[index];
	if (val >= PPCLK_COUNT)
	mapping = navi10_clk_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int navi10_get_smu_feature_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_FEATURE_COUNT)
		return -EINVAL;

	val = navi10_feature_mask_map[index];
	if (val > 64)
	mapping = navi10_feature_mask_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int navi10_get_smu_table_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_TABLE_COUNT)
		return -EINVAL;

	val = navi10_table_map[index];
	if (val >= TABLE_COUNT)
	mapping = navi10_table_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int navi10_get_pwr_src_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_POWER_SOURCE_COUNT)
		return -EINVAL;

	val = navi10_pwr_src_map[index];
	if (val >= POWER_SOURCE_COUNT)
	mapping = navi10_pwr_src_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}


static int navi10_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
		return -EINVAL;

	val = navi10_workload_map[profile];
	mapping = navi10_workload_map[profile];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static bool is_asic_secure(struct smu_context *smu)
+37 −30
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@
#define CTF_OFFSET_HBM			5

#define MSG_MAP(msg) \
	[SMU_MSG_##msg] = PPSMC_MSG_##msg
	[SMU_MSG_##msg] = {1, PPSMC_MSG_##msg}

#define SMC_DPM_FEATURE (FEATURE_DPM_PREFETCHER_MASK | \
			 FEATURE_DPM_GFXCLK_MASK | \
@@ -59,7 +59,7 @@
			 FEATURE_DPM_LINK_MASK | \
			 FEATURE_DPM_DCEFCLK_MASK)

static int vega20_message_map[SMU_MSG_MAX_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping vega20_message_map[SMU_MSG_MAX_COUNT] = {
	MSG_MAP(TestMessage),
	MSG_MAP(GetSmuVersion),
	MSG_MAP(GetDriverIfVersion),
@@ -145,7 +145,7 @@ static int vega20_message_map[SMU_MSG_MAX_COUNT] = {
	MSG_MAP(GetAVFSVoltageByDpm),
};

static int vega20_clk_map[SMU_CLK_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping vega20_clk_map[SMU_CLK_COUNT] = {
	CLK_MAP(GFXCLK, PPCLK_GFXCLK),
	CLK_MAP(VCLK, PPCLK_VCLK),
	CLK_MAP(DCLK, PPCLK_DCLK),
@@ -159,7 +159,7 @@ static int vega20_clk_map[SMU_CLK_COUNT] = {
	CLK_MAP(FCLK, PPCLK_FCLK),
};

static int vega20_feature_mask_map[SMU_FEATURE_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping vega20_feature_mask_map[SMU_FEATURE_COUNT] = {
	FEA_MAP(DPM_PREFETCHER),
	FEA_MAP(DPM_GFXCLK),
	FEA_MAP(DPM_UCLK),
@@ -195,7 +195,7 @@ static int vega20_feature_mask_map[SMU_FEATURE_COUNT] = {
	FEA_MAP(XGMI),
};

static int vega20_table_map[SMU_TABLE_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping vega20_table_map[SMU_TABLE_COUNT] = {
	TAB_MAP(PPTABLE),
	TAB_MAP(WATERMARKS),
	TAB_MAP(AVFS),
@@ -208,12 +208,12 @@ static int vega20_table_map[SMU_TABLE_COUNT] = {
	TAB_MAP(OVERDRIVE),
};

static int vega20_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
static struct smu_11_0_cmn2aisc_mapping vega20_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
	PWR_MAP(AC),
	PWR_MAP(DC),
};

static int vega20_workload_map[] = {
static struct smu_11_0_cmn2aisc_mapping vega20_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT,	WORKLOAD_DEFAULT_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D,		WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
	WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,		WORKLOAD_PPLIB_POWER_SAVING_BIT),
@@ -225,79 +225,86 @@ static int vega20_workload_map[] = {

static int vega20_get_smu_table_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_TABLE_COUNT)
		return -EINVAL;

	val = vega20_table_map[index];
	if (val >= TABLE_COUNT)
	mapping = vega20_table_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int vega20_get_pwr_src_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_POWER_SOURCE_COUNT)
		return -EINVAL;

	val = vega20_pwr_src_map[index];
	if (val >= POWER_SOURCE_COUNT)
	mapping = vega20_pwr_src_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int vega20_get_smu_feature_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_FEATURE_COUNT)
		return -EINVAL;

	val = vega20_feature_mask_map[index];
	if (val > 64)
	mapping = vega20_feature_mask_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_CLK_COUNT)
		return -EINVAL;

	val = vega20_clk_map[index];
	if (val >= PPCLK_COUNT)
	mapping = vega20_clk_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (index >= SMU_MSG_MAX_COUNT)
		return -EINVAL;

	val = vega20_message_map[index];
	if (val > PPSMC_Message_Count)
	mapping = vega20_message_map[index];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int vega20_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile)
{
	int val;
	struct smu_11_0_cmn2aisc_mapping mapping;

	if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
		return -EINVAL;

	val = vega20_workload_map[profile];
	mapping = vega20_workload_map[profile];
	if (!(mapping.valid_mapping))
		return -EINVAL;

	return val;
	return mapping.map_to;
}

static int vega20_tables_init(struct smu_context *smu, struct smu_table *tables)