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

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
...@@ -141,6 +141,7 @@ enum PP_SMC_POWER_PROFILE { ...@@ -141,6 +141,7 @@ enum PP_SMC_POWER_PROFILE {
PP_SMC_POWER_PROFILE_VR = 0x4, PP_SMC_POWER_PROFILE_VR = 0x4,
PP_SMC_POWER_PROFILE_COMPUTE = 0x5, PP_SMC_POWER_PROFILE_COMPUTE = 0x5,
PP_SMC_POWER_PROFILE_CUSTOM = 0x6, PP_SMC_POWER_PROFILE_CUSTOM = 0x6,
PP_SMC_POWER_PROFILE_COUNT,
}; };
enum { enum {
......
...@@ -37,9 +37,9 @@ ...@@ -37,9 +37,9 @@
#include "nbio/nbio_7_4_sh_mask.h" #include "nbio/nbio_7_4_sh_mask.h"
#define MSG_MAP(msg, index) \ #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(TestMessage, PPSMC_MSG_TestMessage),
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion),
MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion), MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion),
...@@ -101,16 +101,18 @@ static int arcturus_message_map[SMU_MSG_MAX_COUNT] = { ...@@ -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) 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) if (index >= SMU_MSG_MAX_COUNT)
return -EINVAL; return -EINVAL;
val = arcturus_message_map[index]; mapping = arcturus_message_map[index];
if (val > PPSMC_Message_Count) if (!(mapping.valid_mapping)) {
pr_warn("Unsupported SMU message: %d\n", index);
return -EINVAL; return -EINVAL;
}
return val; return mapping.map_to;
} }
static const struct pptable_funcs arcturus_ppt_funcs = { static const struct pptable_funcs arcturus_ppt_funcs = {
......
...@@ -43,19 +43,24 @@ ...@@ -43,19 +43,24 @@
#define SMU11_TOOL_SIZE 0x19000 #define SMU11_TOOL_SIZE 0x19000
#define CLK_MAP(clk, index) \ #define CLK_MAP(clk, index) \
[SMU_##clk] = index [SMU_##clk] = {1, (index)}
#define FEA_MAP(fea) \ #define FEA_MAP(fea) \
[SMU_FEATURE_##fea##_BIT] = FEATURE_##fea##_BIT [SMU_FEATURE_##fea##_BIT] = {1, FEATURE_##fea##_BIT}
#define TAB_MAP(tab) \ #define TAB_MAP(tab) \
[SMU_TABLE_##tab] = TABLE_##tab [SMU_TABLE_##tab] = {1, TABLE_##tab}
#define PWR_MAP(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) \ #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 { struct smu_11_0_max_sustainable_clocks {
uint32_t display_clock; uint32_t display_clock;
......
...@@ -49,9 +49,9 @@ ...@@ -49,9 +49,9 @@
FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)) FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT))
#define MSG_MAP(msg, index) \ #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(TestMessage, PPSMC_MSG_TestMessage),
MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion),
MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion), MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion),
...@@ -118,7 +118,7 @@ static int navi10_message_map[SMU_MSG_MAX_COUNT] = { ...@@ -118,7 +118,7 @@ static int navi10_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(ArmD3, PPSMC_MSG_ArmD3), 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(GFXCLK, PPCLK_GFXCLK),
CLK_MAP(SCLK, PPCLK_GFXCLK), CLK_MAP(SCLK, PPCLK_GFXCLK),
CLK_MAP(SOCCLK, PPCLK_SOCCLK), CLK_MAP(SOCCLK, PPCLK_SOCCLK),
...@@ -133,7 +133,7 @@ static int navi10_clk_map[SMU_CLK_COUNT] = { ...@@ -133,7 +133,7 @@ static int navi10_clk_map[SMU_CLK_COUNT] = {
CLK_MAP(PHYCLK, PPCLK_PHYCLK), 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_PREFETCHER),
FEA_MAP(DPM_GFXCLK), FEA_MAP(DPM_GFXCLK),
FEA_MAP(DPM_GFX_PACE), FEA_MAP(DPM_GFX_PACE),
...@@ -178,7 +178,7 @@ static int navi10_feature_mask_map[SMU_FEATURE_COUNT] = { ...@@ -178,7 +178,7 @@ static int navi10_feature_mask_map[SMU_FEATURE_COUNT] = {
FEA_MAP(ATHUB_PG), 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(PPTABLE),
TAB_MAP(WATERMARKS), TAB_MAP(WATERMARKS),
TAB_MAP(AVFS), TAB_MAP(AVFS),
...@@ -193,12 +193,12 @@ static int navi10_table_map[SMU_TABLE_COUNT] = { ...@@ -193,12 +193,12 @@ static int navi10_table_map[SMU_TABLE_COUNT] = {
TAB_MAP(PACE), 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(AC),
PWR_MAP(DC), 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_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_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT), WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
...@@ -210,79 +210,87 @@ static int navi10_workload_map[] = { ...@@ -210,79 +210,87 @@ static int navi10_workload_map[] = {
static int navi10_get_smu_msg_index(struct smu_context *smc, uint32_t index) 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) if (index > SMU_MSG_MAX_COUNT)
return -EINVAL; return -EINVAL;
val = navi10_message_map[index]; mapping = navi10_message_map[index];
if (val > PPSMC_Message_Count) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int navi10_get_smu_clk_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_CLK_COUNT)
return -EINVAL; return -EINVAL;
val = navi10_clk_map[index]; mapping = navi10_clk_map[index];
if (val >= PPCLK_COUNT) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int navi10_get_smu_feature_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_FEATURE_COUNT)
return -EINVAL; return -EINVAL;
val = navi10_feature_mask_map[index]; mapping = navi10_feature_mask_map[index];
if (val > 64) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int navi10_get_smu_table_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_TABLE_COUNT)
return -EINVAL; return -EINVAL;
val = navi10_table_map[index]; mapping = navi10_table_map[index];
if (val >= TABLE_COUNT) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int navi10_get_pwr_src_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_POWER_SOURCE_COUNT)
return -EINVAL; return -EINVAL;
val = navi10_pwr_src_map[index]; mapping = navi10_pwr_src_map[index];
if (val >= POWER_SOURCE_COUNT) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int navi10_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile) 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) if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
return -EINVAL; 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) static bool is_asic_secure(struct smu_context *smu)
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
#define CTF_OFFSET_HBM 5 #define CTF_OFFSET_HBM 5
#define MSG_MAP(msg) \ #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 | \ #define SMC_DPM_FEATURE (FEATURE_DPM_PREFETCHER_MASK | \
FEATURE_DPM_GFXCLK_MASK | \ FEATURE_DPM_GFXCLK_MASK | \
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
FEATURE_DPM_LINK_MASK | \ FEATURE_DPM_LINK_MASK | \
FEATURE_DPM_DCEFCLK_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(TestMessage),
MSG_MAP(GetSmuVersion), MSG_MAP(GetSmuVersion),
MSG_MAP(GetDriverIfVersion), MSG_MAP(GetDriverIfVersion),
...@@ -145,7 +145,7 @@ static int vega20_message_map[SMU_MSG_MAX_COUNT] = { ...@@ -145,7 +145,7 @@ static int vega20_message_map[SMU_MSG_MAX_COUNT] = {
MSG_MAP(GetAVFSVoltageByDpm), 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(GFXCLK, PPCLK_GFXCLK),
CLK_MAP(VCLK, PPCLK_VCLK), CLK_MAP(VCLK, PPCLK_VCLK),
CLK_MAP(DCLK, PPCLK_DCLK), CLK_MAP(DCLK, PPCLK_DCLK),
...@@ -159,7 +159,7 @@ static int vega20_clk_map[SMU_CLK_COUNT] = { ...@@ -159,7 +159,7 @@ static int vega20_clk_map[SMU_CLK_COUNT] = {
CLK_MAP(FCLK, PPCLK_FCLK), 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_PREFETCHER),
FEA_MAP(DPM_GFXCLK), FEA_MAP(DPM_GFXCLK),
FEA_MAP(DPM_UCLK), FEA_MAP(DPM_UCLK),
...@@ -195,7 +195,7 @@ static int vega20_feature_mask_map[SMU_FEATURE_COUNT] = { ...@@ -195,7 +195,7 @@ static int vega20_feature_mask_map[SMU_FEATURE_COUNT] = {
FEA_MAP(XGMI), 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(PPTABLE),
TAB_MAP(WATERMARKS), TAB_MAP(WATERMARKS),
TAB_MAP(AVFS), TAB_MAP(AVFS),
...@@ -208,12 +208,12 @@ static int vega20_table_map[SMU_TABLE_COUNT] = { ...@@ -208,12 +208,12 @@ static int vega20_table_map[SMU_TABLE_COUNT] = {
TAB_MAP(OVERDRIVE), 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(AC),
PWR_MAP(DC), 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_BOOTUP_DEFAULT, WORKLOAD_DEFAULT_BIT),
WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_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), WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
...@@ -225,79 +225,86 @@ static int vega20_workload_map[] = { ...@@ -225,79 +225,86 @@ static int vega20_workload_map[] = {
static int vega20_get_smu_table_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_TABLE_COUNT)
return -EINVAL; return -EINVAL;
val = vega20_table_map[index]; mapping = vega20_table_map[index];
if (val >= TABLE_COUNT) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int vega20_get_pwr_src_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_POWER_SOURCE_COUNT)
return -EINVAL; return -EINVAL;
val = vega20_pwr_src_map[index]; mapping = vega20_pwr_src_map[index];
if (val >= POWER_SOURCE_COUNT) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int vega20_get_smu_feature_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_FEATURE_COUNT)
return -EINVAL; return -EINVAL;
val = vega20_feature_mask_map[index]; mapping = vega20_feature_mask_map[index];
if (val > 64) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int vega20_get_smu_clk_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_CLK_COUNT)
return -EINVAL; return -EINVAL;
val = vega20_clk_map[index]; mapping = vega20_clk_map[index];
if (val >= PPCLK_COUNT) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index) 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) if (index >= SMU_MSG_MAX_COUNT)
return -EINVAL; return -EINVAL;
val = vega20_message_map[index]; mapping = vega20_message_map[index];
if (val > PPSMC_Message_Count) if (!(mapping.valid_mapping))
return -EINVAL; return -EINVAL;
return val; return mapping.map_to;
} }
static int vega20_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile) 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) if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
return -EINVAL; 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) static int vega20_tables_init(struct smu_context *smu, struct smu_table *tables)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment