diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2018-03-21 05:25:07 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-03-22 15:43:20 -0400 |
commit | bbfcc8af37577c7f8950a1442c398da64de5e5b7 (patch) | |
tree | a3929e4d295b29587b928bff9983be8893b83bcb | |
parent | 031ec948a8dd12c4848b045fe8a64db22b91684c (diff) |
drm/amd/pp: Clean up powerplay code on Vega12
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | 482 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h | 32 |
2 files changed, 1 insertions, 513 deletions
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c index da2053e10671..15ce1e825021 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include "pp_overdriver.h" | 48 | #include "pp_overdriver.h" |
49 | #include "pp_thermal.h" | 49 | #include "pp_thermal.h" |
50 | 50 | ||
51 | static const ULONG PhwVega12_Magic = (ULONG)(PHM_VIslands_Magic); | ||
52 | 51 | ||
53 | static int vega12_force_clock_level(struct pp_hwmgr *hwmgr, | 52 | static int vega12_force_clock_level(struct pp_hwmgr *hwmgr, |
54 | enum pp_clock_type type, uint32_t mask); | 53 | enum pp_clock_type type, uint32_t mask); |
@@ -57,26 +56,6 @@ static int vega12_get_clock_ranges(struct pp_hwmgr *hwmgr, | |||
57 | PPCLK_e clock_select, | 56 | PPCLK_e clock_select, |
58 | bool max); | 57 | bool max); |
59 | 58 | ||
60 | struct vega12_power_state *cast_phw_vega12_power_state( | ||
61 | struct pp_hw_power_state *hw_ps) | ||
62 | { | ||
63 | PP_ASSERT_WITH_CODE((PhwVega12_Magic == hw_ps->magic), | ||
64 | "Invalid Powerstate Type!", | ||
65 | return NULL;); | ||
66 | |||
67 | return (struct vega12_power_state *)hw_ps; | ||
68 | } | ||
69 | |||
70 | const struct vega12_power_state *cast_const_phw_vega12_power_state( | ||
71 | const struct pp_hw_power_state *hw_ps) | ||
72 | { | ||
73 | PP_ASSERT_WITH_CODE((PhwVega12_Magic == hw_ps->magic), | ||
74 | "Invalid Powerstate Type!", | ||
75 | return NULL;); | ||
76 | |||
77 | return (const struct vega12_power_state *)hw_ps; | ||
78 | } | ||
79 | |||
80 | static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr) | 59 | static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr) |
81 | { | 60 | { |
82 | struct vega12_hwmgr *data = | 61 | struct vega12_hwmgr *data = |
@@ -590,7 +569,7 @@ static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr) | |||
590 | } | 569 | } |
591 | 570 | ||
592 | vega12_init_dpm_state(&(dpm_table->dpm_state)); | 571 | vega12_init_dpm_state(&(dpm_table->dpm_state)); |
593 | /* Initialize Mclk DPM table based on allow Mclk values */ | 572 | /* Initialize Mclk DPM table based on allow Mclk values */ |
594 | dpm_table = &(data->dpm_table.mem_table); | 573 | dpm_table = &(data->dpm_table.mem_table); |
595 | 574 | ||
596 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_UCLK, | 575 | PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_UCLK, |
@@ -953,262 +932,12 @@ static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr) | |||
953 | return result; | 932 | return result; |
954 | } | 933 | } |
955 | 934 | ||
956 | static int vega12_get_power_state_size(struct pp_hwmgr *hwmgr) | ||
957 | { | ||
958 | return sizeof(struct vega12_power_state); | ||
959 | } | ||
960 | |||
961 | static int vega12_get_number_of_pp_table_entries(struct pp_hwmgr *hwmgr) | ||
962 | { | ||
963 | return 0; | ||
964 | } | ||
965 | |||
966 | static int vega12_patch_boot_state(struct pp_hwmgr *hwmgr, | 935 | static int vega12_patch_boot_state(struct pp_hwmgr *hwmgr, |
967 | struct pp_hw_power_state *hw_ps) | 936 | struct pp_hw_power_state *hw_ps) |
968 | { | 937 | { |
969 | return 0; | 938 | return 0; |
970 | } | 939 | } |
971 | 940 | ||
972 | static int vega12_apply_state_adjust_rules(struct pp_hwmgr *hwmgr, | ||
973 | struct pp_power_state *request_ps, | ||
974 | const struct pp_power_state *current_ps) | ||
975 | { | ||
976 | struct vega12_power_state *vega12_ps = | ||
977 | cast_phw_vega12_power_state(&request_ps->hardware); | ||
978 | uint32_t sclk; | ||
979 | uint32_t mclk; | ||
980 | struct PP_Clocks minimum_clocks = {0}; | ||
981 | bool disable_mclk_switching; | ||
982 | bool disable_mclk_switching_for_frame_lock; | ||
983 | bool disable_mclk_switching_for_vr; | ||
984 | bool force_mclk_high; | ||
985 | struct cgs_display_info info = {0}; | ||
986 | const struct phm_clock_and_voltage_limits *max_limits; | ||
987 | uint32_t i; | ||
988 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | ||
989 | struct phm_ppt_v2_information *table_info = | ||
990 | (struct phm_ppt_v2_information *)(hwmgr->pptable); | ||
991 | int32_t count; | ||
992 | uint32_t stable_pstate_sclk_dpm_percentage; | ||
993 | uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0; | ||
994 | uint32_t latency; | ||
995 | |||
996 | data->battery_state = (PP_StateUILabel_Battery == | ||
997 | request_ps->classification.ui_label); | ||
998 | |||
999 | if (vega12_ps->performance_level_count != 2) | ||
1000 | pr_info("VI should always have 2 performance levels"); | ||
1001 | |||
1002 | max_limits = (PP_PowerSource_AC == hwmgr->power_source) ? | ||
1003 | &(hwmgr->dyn_state.max_clock_voltage_on_ac) : | ||
1004 | &(hwmgr->dyn_state.max_clock_voltage_on_dc); | ||
1005 | |||
1006 | /* Cap clock DPM tables at DC MAX if it is in DC. */ | ||
1007 | if (PP_PowerSource_DC == hwmgr->power_source) { | ||
1008 | for (i = 0; i < vega12_ps->performance_level_count; i++) { | ||
1009 | if (vega12_ps->performance_levels[i].mem_clock > | ||
1010 | max_limits->mclk) | ||
1011 | vega12_ps->performance_levels[i].mem_clock = | ||
1012 | max_limits->mclk; | ||
1013 | if (vega12_ps->performance_levels[i].gfx_clock > | ||
1014 | max_limits->sclk) | ||
1015 | vega12_ps->performance_levels[i].gfx_clock = | ||
1016 | max_limits->sclk; | ||
1017 | } | ||
1018 | } | ||
1019 | |||
1020 | cgs_get_active_displays_info(hwmgr->device, &info); | ||
1021 | |||
1022 | /* result = PHM_CheckVBlankTime(hwmgr, &vblankTooShort);*/ | ||
1023 | minimum_clocks.engineClock = hwmgr->display_config.min_core_set_clock; | ||
1024 | minimum_clocks.memoryClock = hwmgr->display_config.min_mem_set_clock; | ||
1025 | |||
1026 | if (PP_CAP(PHM_PlatformCaps_StablePState)) { | ||
1027 | PP_ASSERT_WITH_CODE( | ||
1028 | data->registry_data.stable_pstate_sclk_dpm_percentage >= 1 && | ||
1029 | data->registry_data.stable_pstate_sclk_dpm_percentage <= 100, | ||
1030 | "percent sclk value must range from 1% to 100%, setting default value", | ||
1031 | stable_pstate_sclk_dpm_percentage = 75); | ||
1032 | |||
1033 | max_limits = &(hwmgr->dyn_state.max_clock_voltage_on_ac); | ||
1034 | stable_pstate_sclk = (max_limits->sclk * | ||
1035 | stable_pstate_sclk_dpm_percentage) / 100; | ||
1036 | |||
1037 | for (count = table_info->vdd_dep_on_sclk->count - 1; | ||
1038 | count >= 0; count--) { | ||
1039 | if (stable_pstate_sclk >= | ||
1040 | table_info->vdd_dep_on_sclk->entries[count].clk) { | ||
1041 | stable_pstate_sclk = | ||
1042 | table_info->vdd_dep_on_sclk->entries[count].clk; | ||
1043 | break; | ||
1044 | } | ||
1045 | } | ||
1046 | |||
1047 | if (count < 0) | ||
1048 | stable_pstate_sclk = table_info->vdd_dep_on_sclk->entries[0].clk; | ||
1049 | |||
1050 | stable_pstate_mclk = max_limits->mclk; | ||
1051 | |||
1052 | minimum_clocks.engineClock = stable_pstate_sclk; | ||
1053 | minimum_clocks.memoryClock = stable_pstate_mclk; | ||
1054 | } | ||
1055 | |||
1056 | disable_mclk_switching_for_frame_lock = phm_cap_enabled( | ||
1057 | hwmgr->platform_descriptor.platformCaps, | ||
1058 | PHM_PlatformCaps_DisableMclkSwitchingForFrameLock); | ||
1059 | disable_mclk_switching_for_vr = PP_CAP(PHM_PlatformCaps_DisableMclkSwitchForVR); | ||
1060 | force_mclk_high = PP_CAP(PHM_PlatformCaps_ForceMclkHigh); | ||
1061 | |||
1062 | if (info.display_count == 0) | ||
1063 | disable_mclk_switching = false; | ||
1064 | else | ||
1065 | disable_mclk_switching = (info.display_count > 1) || | ||
1066 | disable_mclk_switching_for_frame_lock || | ||
1067 | disable_mclk_switching_for_vr || | ||
1068 | force_mclk_high; | ||
1069 | |||
1070 | sclk = vega12_ps->performance_levels[0].gfx_clock; | ||
1071 | mclk = vega12_ps->performance_levels[0].mem_clock; | ||
1072 | |||
1073 | if (sclk < minimum_clocks.engineClock) | ||
1074 | sclk = (minimum_clocks.engineClock > max_limits->sclk) ? | ||
1075 | max_limits->sclk : minimum_clocks.engineClock; | ||
1076 | |||
1077 | if (mclk < minimum_clocks.memoryClock) | ||
1078 | mclk = (minimum_clocks.memoryClock > max_limits->mclk) ? | ||
1079 | max_limits->mclk : minimum_clocks.memoryClock; | ||
1080 | |||
1081 | vega12_ps->performance_levels[0].gfx_clock = sclk; | ||
1082 | vega12_ps->performance_levels[0].mem_clock = mclk; | ||
1083 | |||
1084 | if (vega12_ps->performance_levels[1].gfx_clock < | ||
1085 | vega12_ps->performance_levels[0].gfx_clock) | ||
1086 | vega12_ps->performance_levels[0].gfx_clock = | ||
1087 | vega12_ps->performance_levels[1].gfx_clock; | ||
1088 | |||
1089 | if (disable_mclk_switching) { | ||
1090 | /* Set Mclk the max of level 0 and level 1 */ | ||
1091 | if (mclk < vega12_ps->performance_levels[1].mem_clock) | ||
1092 | mclk = vega12_ps->performance_levels[1].mem_clock; | ||
1093 | /* Find the lowest MCLK frequency that is within | ||
1094 | * the tolerable latency defined in DAL | ||
1095 | */ | ||
1096 | latency = 0; | ||
1097 | for (i = 0; i < data->mclk_latency_table.count; i++) { | ||
1098 | if ((data->mclk_latency_table.entries[i].latency <= latency) && | ||
1099 | (data->mclk_latency_table.entries[i].frequency >= | ||
1100 | vega12_ps->performance_levels[0].mem_clock) && | ||
1101 | (data->mclk_latency_table.entries[i].frequency <= | ||
1102 | vega12_ps->performance_levels[1].mem_clock)) | ||
1103 | mclk = data->mclk_latency_table.entries[i].frequency; | ||
1104 | } | ||
1105 | vega12_ps->performance_levels[0].mem_clock = mclk; | ||
1106 | } else { | ||
1107 | if (vega12_ps->performance_levels[1].mem_clock < | ||
1108 | vega12_ps->performance_levels[0].mem_clock) | ||
1109 | vega12_ps->performance_levels[0].mem_clock = | ||
1110 | vega12_ps->performance_levels[1].mem_clock; | ||
1111 | } | ||
1112 | |||
1113 | if (PP_CAP(PHM_PlatformCaps_StablePState)) { | ||
1114 | for (i = 0; i < vega12_ps->performance_level_count; i++) { | ||
1115 | vega12_ps->performance_levels[i].gfx_clock = stable_pstate_sclk; | ||
1116 | vega12_ps->performance_levels[i].mem_clock = stable_pstate_mclk; | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | return 0; | ||
1121 | } | ||
1122 | |||
1123 | static int vega12_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input) | ||
1124 | { | ||
1125 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | ||
1126 | struct PP_Clocks min_clocks = {0}; | ||
1127 | struct cgs_display_info info = {0}; | ||
1128 | |||
1129 | data->need_update_dpm_table = 0; | ||
1130 | |||
1131 | min_clocks.engineClockInSR = hwmgr->display_config.min_core_set_clock_in_sr; | ||
1132 | if (data->display_timing.min_clock_in_sr != min_clocks.engineClockInSR && | ||
1133 | (min_clocks.engineClockInSR >= VEGA12_MINIMUM_ENGINE_CLOCK || | ||
1134 | data->display_timing.min_clock_in_sr >= VEGA12_MINIMUM_ENGINE_CLOCK)) | ||
1135 | data->need_update_dpm_table |= DPMTABLE_UPDATE_SCLK; | ||
1136 | |||
1137 | cgs_get_active_displays_info(hwmgr->device, &info); | ||
1138 | if (data->display_timing.num_existing_displays != info.display_count) | ||
1139 | data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK; | ||
1140 | |||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | static int vega12_trim_single_dpm_states(struct pp_hwmgr *hwmgr, | ||
1145 | struct vega12_single_dpm_table *dpm_table, | ||
1146 | uint32_t low_limit, uint32_t high_limit) | ||
1147 | { | ||
1148 | uint32_t i; | ||
1149 | |||
1150 | for (i = 0; i < dpm_table->count; i++) { | ||
1151 | if ((dpm_table->dpm_levels[i].value < low_limit) || | ||
1152 | (dpm_table->dpm_levels[i].value > high_limit)) | ||
1153 | dpm_table->dpm_levels[i].enabled = false; | ||
1154 | else | ||
1155 | dpm_table->dpm_levels[i].enabled = true; | ||
1156 | } | ||
1157 | return 0; | ||
1158 | } | ||
1159 | |||
1160 | static int vega12_trim_single_dpm_states_with_mask(struct pp_hwmgr *hwmgr, | ||
1161 | struct vega12_single_dpm_table *dpm_table, | ||
1162 | uint32_t low_limit, uint32_t high_limit, | ||
1163 | uint32_t disable_dpm_mask) | ||
1164 | { | ||
1165 | uint32_t i; | ||
1166 | |||
1167 | for (i = 0; i < dpm_table->count; i++) { | ||
1168 | if ((dpm_table->dpm_levels[i].value < low_limit) || | ||
1169 | (dpm_table->dpm_levels[i].value > high_limit)) | ||
1170 | dpm_table->dpm_levels[i].enabled = false; | ||
1171 | else if ((!((1 << i) & disable_dpm_mask)) && | ||
1172 | !(low_limit == high_limit)) | ||
1173 | dpm_table->dpm_levels[i].enabled = false; | ||
1174 | else | ||
1175 | dpm_table->dpm_levels[i].enabled = true; | ||
1176 | } | ||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | static int vega12_trim_dpm_states(struct pp_hwmgr *hwmgr, | ||
1181 | const struct vega12_power_state *vega12_ps) | ||
1182 | { | ||
1183 | struct vega12_hwmgr *data = | ||
1184 | (struct vega12_hwmgr *)(hwmgr->backend); | ||
1185 | uint32_t high_limit_count; | ||
1186 | |||
1187 | PP_ASSERT_WITH_CODE((vega12_ps->performance_level_count >= 1), | ||
1188 | "power state did not have any performance level", | ||
1189 | return -1); | ||
1190 | |||
1191 | high_limit_count = (vega12_ps->performance_level_count == 1) ? 0 : 1; | ||
1192 | |||
1193 | vega12_trim_single_dpm_states(hwmgr, | ||
1194 | &(data->dpm_table.soc_table), | ||
1195 | vega12_ps->performance_levels[0].soc_clock, | ||
1196 | vega12_ps->performance_levels[high_limit_count].soc_clock); | ||
1197 | |||
1198 | vega12_trim_single_dpm_states_with_mask(hwmgr, | ||
1199 | &(data->dpm_table.gfx_table), | ||
1200 | vega12_ps->performance_levels[0].gfx_clock, | ||
1201 | vega12_ps->performance_levels[high_limit_count].gfx_clock, | ||
1202 | data->disable_dpm_mask); | ||
1203 | |||
1204 | vega12_trim_single_dpm_states(hwmgr, | ||
1205 | &(data->dpm_table.mem_table), | ||
1206 | vega12_ps->performance_levels[0].mem_clock, | ||
1207 | vega12_ps->performance_levels[high_limit_count].mem_clock); | ||
1208 | |||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1212 | static uint32_t vega12_find_lowest_dpm_level( | 941 | static uint32_t vega12_find_lowest_dpm_level( |
1213 | struct vega12_single_dpm_table *table) | 942 | struct vega12_single_dpm_table *table) |
1214 | { | 943 | { |
@@ -1250,45 +979,6 @@ static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr) | |||
1250 | return 0; | 979 | return 0; |
1251 | } | 980 | } |
1252 | 981 | ||
1253 | static int vega12_generate_dpm_level_enable_mask( | ||
1254 | struct pp_hwmgr *hwmgr, const void *input) | ||
1255 | { | ||
1256 | struct vega12_hwmgr *data = | ||
1257 | (struct vega12_hwmgr *)(hwmgr->backend); | ||
1258 | const struct phm_set_power_state_input *states = | ||
1259 | (const struct phm_set_power_state_input *)input; | ||
1260 | const struct vega12_power_state *vega12_ps = | ||
1261 | cast_const_phw_vega12_power_state(states->pnew_state); | ||
1262 | int i; | ||
1263 | |||
1264 | PP_ASSERT_WITH_CODE(!vega12_trim_dpm_states(hwmgr, vega12_ps), | ||
1265 | "Attempt to Trim DPM States Failed!", | ||
1266 | return -1); | ||
1267 | |||
1268 | data->smc_state_table.gfx_boot_level = | ||
1269 | vega12_find_lowest_dpm_level(&(data->dpm_table.gfx_table)); | ||
1270 | data->smc_state_table.gfx_max_level = | ||
1271 | vega12_find_highest_dpm_level(&(data->dpm_table.gfx_table)); | ||
1272 | data->smc_state_table.mem_boot_level = | ||
1273 | vega12_find_lowest_dpm_level(&(data->dpm_table.mem_table)); | ||
1274 | data->smc_state_table.mem_max_level = | ||
1275 | vega12_find_highest_dpm_level(&(data->dpm_table.mem_table)); | ||
1276 | |||
1277 | PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr), | ||
1278 | "Attempt to upload DPM Bootup Levels Failed!", | ||
1279 | return -1); | ||
1280 | PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr), | ||
1281 | "Attempt to upload DPM Max Levels Failed!", | ||
1282 | return -1); | ||
1283 | for (i = data->smc_state_table.gfx_boot_level; i < data->smc_state_table.gfx_max_level; i++) | ||
1284 | data->dpm_table.gfx_table.dpm_levels[i].enabled = true; | ||
1285 | |||
1286 | |||
1287 | for (i = data->smc_state_table.mem_boot_level; i < data->smc_state_table.mem_max_level; i++) | ||
1288 | data->dpm_table.mem_table.dpm_levels[i].enabled = true; | ||
1289 | |||
1290 | return 0; | ||
1291 | } | ||
1292 | 982 | ||
1293 | int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) | 983 | int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) |
1294 | { | 984 | { |
@@ -1307,45 +997,6 @@ int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable) | |||
1307 | return 0; | 997 | return 0; |
1308 | } | 998 | } |
1309 | 999 | ||
1310 | static int vega12_update_sclk_threshold(struct pp_hwmgr *hwmgr) | ||
1311 | { | ||
1312 | return 0; | ||
1313 | } | ||
1314 | |||
1315 | static int vega12_set_power_state_tasks(struct pp_hwmgr *hwmgr, | ||
1316 | const void *input) | ||
1317 | { | ||
1318 | int tmp_result, result = 0; | ||
1319 | struct vega12_hwmgr *data = | ||
1320 | (struct vega12_hwmgr *)(hwmgr->backend); | ||
1321 | PPTable_t *pp_table = &(data->smc_state_table.pp_table); | ||
1322 | |||
1323 | tmp_result = vega12_find_dpm_states_clocks_in_dpm_table(hwmgr, input); | ||
1324 | PP_ASSERT_WITH_CODE(!tmp_result, | ||
1325 | "Failed to find DPM states clocks in DPM table!", | ||
1326 | result = tmp_result); | ||
1327 | |||
1328 | tmp_result = vega12_generate_dpm_level_enable_mask(hwmgr, input); | ||
1329 | PP_ASSERT_WITH_CODE(!tmp_result, | ||
1330 | "Failed to generate DPM level enabled mask!", | ||
1331 | result = tmp_result); | ||
1332 | |||
1333 | tmp_result = vega12_update_sclk_threshold(hwmgr); | ||
1334 | PP_ASSERT_WITH_CODE(!tmp_result, | ||
1335 | "Failed to update SCLK threshold!", | ||
1336 | result = tmp_result); | ||
1337 | |||
1338 | result = vega12_copy_table_to_smc(hwmgr, | ||
1339 | (uint8_t *)pp_table, TABLE_PPTABLE); | ||
1340 | PP_ASSERT_WITH_CODE(!result, | ||
1341 | "Failed to upload PPtable!", return result); | ||
1342 | |||
1343 | data->apply_optimized_settings = false; | ||
1344 | data->apply_overdrive_next_settings_mask = 0; | ||
1345 | |||
1346 | return 0; | ||
1347 | } | ||
1348 | |||
1349 | static uint32_t vega12_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low) | 1000 | static uint32_t vega12_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low) |
1350 | { | 1001 | { |
1351 | struct vega12_hwmgr *data = | 1002 | struct vega12_hwmgr *data = |
@@ -2217,50 +1868,6 @@ static void vega12_power_gate_uvd(struct pp_hwmgr *hwmgr, bool bgate) | |||
2217 | vega12_enable_disable_uvd_dpm(hwmgr, !bgate); | 1868 | vega12_enable_disable_uvd_dpm(hwmgr, !bgate); |
2218 | } | 1869 | } |
2219 | 1870 | ||
2220 | static inline bool vega12_are_power_levels_equal( | ||
2221 | const struct vega12_performance_level *pl1, | ||
2222 | const struct vega12_performance_level *pl2) | ||
2223 | { | ||
2224 | return ((pl1->soc_clock == pl2->soc_clock) && | ||
2225 | (pl1->gfx_clock == pl2->gfx_clock) && | ||
2226 | (pl1->mem_clock == pl2->mem_clock)); | ||
2227 | } | ||
2228 | |||
2229 | static int vega12_check_states_equal(struct pp_hwmgr *hwmgr, | ||
2230 | const struct pp_hw_power_state *pstate1, | ||
2231 | const struct pp_hw_power_state *pstate2, bool *equal) | ||
2232 | { | ||
2233 | const struct vega12_power_state *psa; | ||
2234 | const struct vega12_power_state *psb; | ||
2235 | int i; | ||
2236 | |||
2237 | if (pstate1 == NULL || pstate2 == NULL || equal == NULL) | ||
2238 | return -EINVAL; | ||
2239 | |||
2240 | psa = cast_const_phw_vega12_power_state(pstate1); | ||
2241 | psb = cast_const_phw_vega12_power_state(pstate2); | ||
2242 | /* If the two states don't even have the same number of performance levels they cannot be the same state. */ | ||
2243 | if (psa->performance_level_count != psb->performance_level_count) { | ||
2244 | *equal = false; | ||
2245 | return 0; | ||
2246 | } | ||
2247 | |||
2248 | for (i = 0; i < psa->performance_level_count; i++) { | ||
2249 | if (!vega12_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) { | ||
2250 | /* If we have found even one performance level pair that is different the states are different. */ | ||
2251 | *equal = false; | ||
2252 | return 0; | ||
2253 | } | ||
2254 | } | ||
2255 | |||
2256 | /* If all performance levels are the same try to use the UVD clocks to break the tie.*/ | ||
2257 | *equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk)); | ||
2258 | *equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk)); | ||
2259 | *equal &= (psa->sclk_threshold == psb->sclk_threshold); | ||
2260 | |||
2261 | return 0; | ||
2262 | } | ||
2263 | |||
2264 | static bool | 1871 | static bool |
2265 | vega12_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) | 1872 | vega12_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr) |
2266 | { | 1873 | { |
@@ -2337,37 +1944,6 @@ static void vega12_find_min_clock_index(struct pp_hwmgr *hwmgr, | |||
2337 | static int vega12_set_power_profile_state(struct pp_hwmgr *hwmgr, | 1944 | static int vega12_set_power_profile_state(struct pp_hwmgr *hwmgr, |
2338 | struct amd_pp_profile *request) | 1945 | struct amd_pp_profile *request) |
2339 | { | 1946 | { |
2340 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | ||
2341 | uint32_t sclk_idx = ~0, mclk_idx = ~0; | ||
2342 | |||
2343 | if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_AUTO) | ||
2344 | return -EINVAL; | ||
2345 | |||
2346 | vega12_find_min_clock_index(hwmgr, &sclk_idx, &mclk_idx, | ||
2347 | request->min_sclk, request->min_mclk); | ||
2348 | |||
2349 | if (sclk_idx != ~0) { | ||
2350 | if (!data->registry_data.sclk_dpm_key_disabled) | ||
2351 | PP_ASSERT_WITH_CODE( | ||
2352 | !smum_send_msg_to_smc_with_parameter( | ||
2353 | hwmgr, | ||
2354 | PPSMC_MSG_SetSoftMinGfxclkByIndex, | ||
2355 | sclk_idx), | ||
2356 | "Failed to set soft min sclk index!", | ||
2357 | return -EINVAL); | ||
2358 | } | ||
2359 | |||
2360 | if (mclk_idx != ~0) { | ||
2361 | if (!data->registry_data.mclk_dpm_key_disabled) | ||
2362 | PP_ASSERT_WITH_CODE( | ||
2363 | !smum_send_msg_to_smc_with_parameter( | ||
2364 | hwmgr, | ||
2365 | PPSMC_MSG_SetSoftMinUclkByIndex, | ||
2366 | mclk_idx), | ||
2367 | "Failed to set soft min mclk index!", | ||
2368 | return -EINVAL); | ||
2369 | } | ||
2370 | |||
2371 | return 0; | 1947 | return 0; |
2372 | } | 1948 | } |
2373 | 1949 | ||
@@ -2389,28 +1965,6 @@ static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr) | |||
2389 | 1965 | ||
2390 | static int vega12_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | 1966 | static int vega12_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value) |
2391 | { | 1967 | { |
2392 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | ||
2393 | struct vega12_single_dpm_table *golden_sclk_table = | ||
2394 | &(data->golden_dpm_table.gfx_table); | ||
2395 | struct pp_power_state *ps; | ||
2396 | struct vega12_power_state *vega12_ps; | ||
2397 | |||
2398 | ps = hwmgr->request_ps; | ||
2399 | |||
2400 | if (ps == NULL) | ||
2401 | return -EINVAL; | ||
2402 | |||
2403 | vega12_ps = cast_phw_vega12_power_state(&ps->hardware); | ||
2404 | |||
2405 | vega12_ps->performance_levels[vega12_ps->performance_level_count - 1].gfx_clock = | ||
2406 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * value / 100 + | ||
2407 | golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; | ||
2408 | |||
2409 | if (vega12_ps->performance_levels[vega12_ps->performance_level_count - 1].gfx_clock > | ||
2410 | hwmgr->platform_descriptor.overdriveLimit.engineClock) | ||
2411 | vega12_ps->performance_levels[vega12_ps->performance_level_count - 1].gfx_clock = | ||
2412 | hwmgr->platform_descriptor.overdriveLimit.engineClock; | ||
2413 | |||
2414 | return 0; | 1968 | return 0; |
2415 | } | 1969 | } |
2416 | 1970 | ||
@@ -2435,34 +1989,6 @@ static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr) | |||
2435 | 1989 | ||
2436 | static int vega12_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) | 1990 | static int vega12_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value) |
2437 | { | 1991 | { |
2438 | struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend); | ||
2439 | struct vega12_single_dpm_table *golden_mclk_table = | ||
2440 | &(data->golden_dpm_table.mem_table); | ||
2441 | struct pp_power_state *ps; | ||
2442 | struct vega12_power_state *vega12_ps; | ||
2443 | |||
2444 | ps = hwmgr->request_ps; | ||
2445 | |||
2446 | if (ps == NULL) | ||
2447 | return -EINVAL; | ||
2448 | |||
2449 | vega12_ps = cast_phw_vega12_power_state(&ps->hardware); | ||
2450 | |||
2451 | vega12_ps->performance_levels | ||
2452 | [vega12_ps->performance_level_count - 1].mem_clock = | ||
2453 | golden_mclk_table->dpm_levels | ||
2454 | [golden_mclk_table->count - 1].value * | ||
2455 | value / 100 + | ||
2456 | golden_mclk_table->dpm_levels | ||
2457 | [golden_mclk_table->count - 1].value; | ||
2458 | |||
2459 | if (vega12_ps->performance_levels | ||
2460 | [vega12_ps->performance_level_count - 1].mem_clock > | ||
2461 | hwmgr->platform_descriptor.overdriveLimit.memoryClock) | ||
2462 | vega12_ps->performance_levels | ||
2463 | [vega12_ps->performance_level_count - 1].mem_clock = | ||
2464 | hwmgr->platform_descriptor.overdriveLimit.memoryClock; | ||
2465 | |||
2466 | return 0; | 1992 | return 0; |
2467 | } | 1993 | } |
2468 | #endif | 1994 | #endif |
@@ -2514,12 +2040,7 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = { | |||
2514 | .asic_setup = vega12_setup_asic_task, | 2040 | .asic_setup = vega12_setup_asic_task, |
2515 | .dynamic_state_management_enable = vega12_enable_dpm_tasks, | 2041 | .dynamic_state_management_enable = vega12_enable_dpm_tasks, |
2516 | .dynamic_state_management_disable = vega12_disable_dpm_tasks, | 2042 | .dynamic_state_management_disable = vega12_disable_dpm_tasks, |
2517 | .get_num_of_pp_table_entries = | ||
2518 | vega12_get_number_of_pp_table_entries, | ||
2519 | .get_power_state_size = vega12_get_power_state_size, | ||
2520 | .patch_boot_state = vega12_patch_boot_state, | 2043 | .patch_boot_state = vega12_patch_boot_state, |
2521 | .apply_state_adjust_rules = vega12_apply_state_adjust_rules, | ||
2522 | .power_state_set = vega12_set_power_state_tasks, | ||
2523 | .get_sclk = vega12_dpm_get_sclk, | 2044 | .get_sclk = vega12_dpm_get_sclk, |
2524 | .get_mclk = vega12_dpm_get_mclk, | 2045 | .get_mclk = vega12_dpm_get_mclk, |
2525 | .notify_smc_display_config_after_ps_adjustment = | 2046 | .notify_smc_display_config_after_ps_adjustment = |
@@ -2543,7 +2064,6 @@ static const struct pp_hwmgr_func vega12_hwmgr_funcs = { | |||
2543 | .display_config_changed = vega12_display_configuration_changed_task, | 2064 | .display_config_changed = vega12_display_configuration_changed_task, |
2544 | .powergate_uvd = vega12_power_gate_uvd, | 2065 | .powergate_uvd = vega12_power_gate_uvd, |
2545 | .powergate_vce = vega12_power_gate_vce, | 2066 | .powergate_vce = vega12_power_gate_vce, |
2546 | .check_states_equal = vega12_check_states_equal, | ||
2547 | .check_smc_update_required_for_display_configuration = | 2067 | .check_smc_update_required_for_display_configuration = |
2548 | vega12_check_smc_update_required_for_display_configuration, | 2068 | vega12_check_smc_update_required_for_display_configuration, |
2549 | .power_off_asic = vega12_power_off_asic, | 2069 | .power_off_asic = vega12_power_off_asic, |
diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h index 644c7f0b7648..bc98b1df3b65 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega12_hwmgr.h | |||
@@ -86,37 +86,6 @@ struct smu_features { | |||
86 | uint64_t smu_feature_bitmap; | 86 | uint64_t smu_feature_bitmap; |
87 | }; | 87 | }; |
88 | 88 | ||
89 | struct vega12_performance_level { | ||
90 | uint32_t soc_clock; | ||
91 | uint32_t gfx_clock; | ||
92 | uint32_t mem_clock; | ||
93 | }; | ||
94 | |||
95 | struct vega12_bacos { | ||
96 | uint32_t baco_flags; | ||
97 | /* struct vega12_performance_level performance_level; */ | ||
98 | }; | ||
99 | |||
100 | struct vega12_uvd_clocks { | ||
101 | uint32_t vclk; | ||
102 | uint32_t dclk; | ||
103 | }; | ||
104 | |||
105 | struct vega12_vce_clocks { | ||
106 | uint32_t evclk; | ||
107 | uint32_t ecclk; | ||
108 | }; | ||
109 | |||
110 | struct vega12_power_state { | ||
111 | uint32_t magic; | ||
112 | struct vega12_uvd_clocks uvd_clks; | ||
113 | struct vega12_vce_clocks vce_clks; | ||
114 | uint16_t performance_level_count; | ||
115 | bool dc_compatible; | ||
116 | uint32_t sclk_threshold; | ||
117 | struct vega12_performance_level performance_levels[VEGA12_MAX_HARDWARE_POWERLEVELS]; | ||
118 | }; | ||
119 | |||
120 | struct vega12_dpm_level { | 89 | struct vega12_dpm_level { |
121 | bool enabled; | 90 | bool enabled; |
122 | uint32_t value; | 91 | uint32_t value; |
@@ -350,7 +319,6 @@ struct vega12_hwmgr { | |||
350 | 319 | ||
351 | uint32_t active_auto_throttle_sources; | 320 | uint32_t active_auto_throttle_sources; |
352 | uint32_t water_marks_bitmap; | 321 | uint32_t water_marks_bitmap; |
353 | struct vega12_bacos bacos; | ||
354 | 322 | ||
355 | struct vega12_odn_dpm_table odn_dpm_table; | 323 | struct vega12_odn_dpm_table odn_dpm_table; |
356 | struct vega12_odn_fan_table odn_fan_table; | 324 | struct vega12_odn_fan_table odn_fan_table; |