Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/powerplay: initialize vega20 overdrive settings

The initialized overdrive settings are taken from vbios and SMU(
by PPSMC_MSG_TransferTableSmu2Dram).

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Evan Quan and committed by
Alex Deucher
7dd67c0d bc9b8c45

+403 -49
+274 -19
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
··· 103 103 data->registry_data.quick_transition_support = 0; 104 104 data->registry_data.zrpm_start_temp = 0xffff; 105 105 data->registry_data.zrpm_stop_temp = 0xffff; 106 - data->registry_data.odn_feature_enable = 1; 106 + data->registry_data.od8_feature_enable = 1; 107 107 data->registry_data.disable_water_mark = 0; 108 108 data->registry_data.disable_pp_tuning = 0; 109 109 data->registry_data.disable_xlpp_tuning = 0; ··· 150 150 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 151 151 PHM_PlatformCaps_UnTabledHardwareInterface); 152 152 153 - if (data->registry_data.odn_feature_enable) 153 + if (data->registry_data.od8_feature_enable) 154 154 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 155 - PHM_PlatformCaps_ODNinACSupport); 156 - else { 157 - phm_cap_set(hwmgr->platform_descriptor.platformCaps, 158 - PHM_PlatformCaps_OD6inACSupport); 159 - phm_cap_set(hwmgr->platform_descriptor.platformCaps, 160 - PHM_PlatformCaps_OD6PlusinACSupport); 161 - } 155 + PHM_PlatformCaps_OD8inACSupport); 162 156 163 157 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 164 158 PHM_PlatformCaps_ActivityReporting); ··· 160 166 PHM_PlatformCaps_FanSpeedInTableIsRPM); 161 167 162 168 if (data->registry_data.od_state_in_dc_support) { 163 - if (data->registry_data.odn_feature_enable) 169 + if (data->registry_data.od8_feature_enable) 164 170 phm_cap_set(hwmgr->platform_descriptor.platformCaps, 165 - PHM_PlatformCaps_ODNinDCSupport); 166 - else { 167 - phm_cap_set(hwmgr->platform_descriptor.platformCaps, 168 - PHM_PlatformCaps_OD6inDCSupport); 169 - phm_cap_set(hwmgr->platform_descriptor.platformCaps, 170 - PHM_PlatformCaps_OD6PlusinDCSupport); 171 - } 171 + PHM_PlatformCaps_OD8inDCSupport); 172 172 } 173 173 174 174 if (data->registry_data.thermal_support && ··· 828 840 return 0; 829 841 } 830 842 831 - static int vega20_odn_initialize_default_settings( 843 + static int vega20_od8_set_feature_capabilities( 832 844 struct pp_hwmgr *hwmgr) 833 845 { 846 + struct phm_ppt_v3_information *pptable_information = 847 + (struct phm_ppt_v3_information *)hwmgr->pptable; 848 + struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); 849 + struct vega20_od8_settings *od_settings = &(data->od8_settings); 850 + 851 + od_settings->overdrive8_capabilities = 0; 852 + 853 + if (data->smu_features[GNLD_DPM_GFXCLK].enabled) { 854 + if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > 0 && 855 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > 0 && 856 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_GFXCLKFMIN] > 0 && 857 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_GFXCLKFMIN] > 0) 858 + od_settings->overdrive8_capabilities |= OD8_GFXCLK_LIMITS; 859 + 860 + if (pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P1] > 0 && 861 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P2] > 0 && 862 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P3] > 0 && 863 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P1] > 0 && 864 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P2] > 0 && 865 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEFREQ_P3] > 0 && 866 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P1] > 0 && 867 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P2] > 0 && 868 + pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P3] > 0 && 869 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P1] > 0 && 870 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P2] > 0 && 871 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_VDDGFXCURVEVOLTAGEOFFSET_P3] > 0) 872 + od_settings->overdrive8_capabilities |= OD8_GFXCLK_CURVE; 873 + } 874 + 875 + if (data->smu_features[GNLD_DPM_UCLK].enabled) { 876 + if (pptable_information->od_settings_min[ATOM_VEGA20_ODSETTING_UCLKFMAX] > 0 && 877 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_UCLKFMAX] > 0) 878 + od_settings->overdrive8_capabilities |= OD8_UCLK_MAX; 879 + } 880 + 881 + if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE] > 0 && 882 + pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE] <= 100) 883 + od_settings->overdrive8_capabilities |= OD8_POWER_LIMIT; 884 + 885 + if (data->smu_features[GNLD_FAN_CONTROL].enabled) { 886 + if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_FANRPMMIN] > 0) 887 + od_settings->overdrive8_capabilities |= OD8_FAN_SPEED_MIN; 888 + 889 + if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_FANRPMACOUSTICLIMIT] > 0) 890 + od_settings->overdrive8_capabilities |= OD8_ACOUSTIC_LIMIT_SCLK; 891 + } 892 + 893 + if (data->smu_features[GNLD_THERMAL].enabled) { 894 + if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_FANTARGETTEMPERATURE] > 0) 895 + od_settings->overdrive8_capabilities |= OD8_TEMPERATURE_FAN; 896 + 897 + if (pptable_information->od_settings_max[ATOM_VEGA20_ODSETTING_OPERATINGTEMPMAX] > 0) 898 + od_settings->overdrive8_capabilities |= OD8_TEMPERATURE_SYSTEM; 899 + } 900 + 901 + return 0; 902 + } 903 + 904 + static int vega20_od8_set_feature_id( 905 + struct pp_hwmgr *hwmgr) 906 + { 907 + struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); 908 + struct vega20_od8_settings *od_settings = &(data->od8_settings); 909 + 910 + if (od_settings->overdrive8_capabilities & OD8_GFXCLK_LIMITS) { 911 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].feature_id = 912 + OD8_GFXCLK_LIMITS; 913 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].feature_id = 914 + OD8_GFXCLK_LIMITS; 915 + } else { 916 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].feature_id = 917 + 0; 918 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].feature_id = 919 + 0; 920 + } 921 + 922 + if (od_settings->overdrive8_capabilities & OD8_GFXCLK_CURVE) { 923 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].feature_id = 924 + OD8_GFXCLK_CURVE; 925 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id = 926 + OD8_GFXCLK_CURVE; 927 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].feature_id = 928 + OD8_GFXCLK_CURVE; 929 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id = 930 + OD8_GFXCLK_CURVE; 931 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].feature_id = 932 + OD8_GFXCLK_CURVE; 933 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id = 934 + OD8_GFXCLK_CURVE; 935 + } else { 936 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].feature_id = 937 + 0; 938 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id = 939 + 0; 940 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].feature_id = 941 + 0; 942 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id = 943 + 0; 944 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].feature_id = 945 + 0; 946 + od_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id = 947 + 0; 948 + } 949 + 950 + if (od_settings->overdrive8_capabilities & OD8_UCLK_MAX) 951 + od_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].feature_id = OD8_UCLK_MAX; 952 + else 953 + od_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].feature_id = 0; 954 + 955 + if (od_settings->overdrive8_capabilities & OD8_POWER_LIMIT) 956 + od_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].feature_id = OD8_POWER_LIMIT; 957 + else 958 + od_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].feature_id = 0; 959 + 960 + if (od_settings->overdrive8_capabilities & OD8_ACOUSTIC_LIMIT_SCLK) 961 + od_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].feature_id = 962 + OD8_ACOUSTIC_LIMIT_SCLK; 963 + else 964 + od_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].feature_id = 965 + 0; 966 + 967 + if (od_settings->overdrive8_capabilities & OD8_FAN_SPEED_MIN) 968 + od_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].feature_id = 969 + OD8_FAN_SPEED_MIN; 970 + else 971 + od_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].feature_id = 972 + 0; 973 + 974 + if (od_settings->overdrive8_capabilities & OD8_TEMPERATURE_FAN) 975 + od_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].feature_id = 976 + OD8_TEMPERATURE_FAN; 977 + else 978 + od_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].feature_id = 979 + 0; 980 + 981 + if (od_settings->overdrive8_capabilities & OD8_TEMPERATURE_SYSTEM) 982 + od_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].feature_id = 983 + OD8_TEMPERATURE_SYSTEM; 984 + else 985 + od_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].feature_id = 986 + 0; 987 + 988 + return 0; 989 + } 990 + 991 + static int vega20_od8_initialize_default_settings( 992 + struct pp_hwmgr *hwmgr) 993 + { 994 + struct phm_ppt_v3_information *pptable_information = 995 + (struct phm_ppt_v3_information *)hwmgr->pptable; 996 + struct vega20_hwmgr *data = (struct vega20_hwmgr *)(hwmgr->backend); 997 + struct vega20_od8_settings *od8_settings = &(data->od8_settings); 998 + OverDriveTable_t *od_table = &(data->smc_state_table.overdrive_table); 999 + int i, ret = 0; 1000 + 1001 + /* Set Feature Capabilities */ 1002 + vega20_od8_set_feature_capabilities(hwmgr); 1003 + 1004 + /* Map FeatureID to individual settings */ 1005 + vega20_od8_set_feature_id(hwmgr); 1006 + 1007 + /* Set default values */ 1008 + ret = vega20_copy_table_from_smc(hwmgr, (uint8_t *)od_table, TABLE_OVERDRIVE); 1009 + PP_ASSERT_WITH_CODE(!ret, 1010 + "Failed to export over drive table!", 1011 + return ret); 1012 + 1013 + if (od8_settings->overdrive8_capabilities & OD8_GFXCLK_LIMITS) { 1014 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].default_value = 1015 + od_table->GfxclkFmin; 1016 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].default_value = 1017 + od_table->GfxclkFmax; 1018 + } else { 1019 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].default_value = 1020 + 0; 1021 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].default_value = 1022 + 0; 1023 + } 1024 + 1025 + if (od8_settings->overdrive8_capabilities & OD8_GFXCLK_CURVE) { 1026 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].default_value = 1027 + od_table->GfxclkFreq1; 1028 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value = 1029 + od_table->GfxclkOffsetVolt1; 1030 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].default_value = 1031 + od_table->GfxclkFreq2; 1032 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value = 1033 + od_table->GfxclkOffsetVolt2; 1034 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].default_value = 1035 + od_table->GfxclkFreq3; 1036 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value = 1037 + od_table->GfxclkOffsetVolt3; 1038 + } else { 1039 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].default_value = 1040 + 0; 1041 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value = 1042 + 0; 1043 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].default_value = 1044 + 0; 1045 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value = 1046 + 0; 1047 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].default_value = 1048 + 0; 1049 + od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value = 1050 + 0; 1051 + } 1052 + 1053 + if (od8_settings->overdrive8_capabilities & OD8_UCLK_MAX) 1054 + od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].default_value = 1055 + od_table->UclkFmax; 1056 + else 1057 + od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].default_value = 1058 + 0; 1059 + 1060 + if (od8_settings->overdrive8_capabilities & OD8_POWER_LIMIT) 1061 + od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].default_value = 1062 + od_table->OverDrivePct; 1063 + else 1064 + od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].default_value = 1065 + 0; 1066 + 1067 + if (od8_settings->overdrive8_capabilities & OD8_ACOUSTIC_LIMIT_SCLK) 1068 + od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].default_value = 1069 + od_table->FanMaximumRpm; 1070 + else 1071 + od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].default_value = 1072 + 0; 1073 + 1074 + if (od8_settings->overdrive8_capabilities & OD8_FAN_SPEED_MIN) 1075 + od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].default_value = 1076 + od_table->FanMinimumPwm; 1077 + else 1078 + od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].default_value = 1079 + 0; 1080 + 1081 + if (od8_settings->overdrive8_capabilities & OD8_TEMPERATURE_FAN) 1082 + od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].default_value = 1083 + od_table->FanTargetTemperature; 1084 + else 1085 + od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].default_value = 1086 + 0; 1087 + 1088 + if (od8_settings->overdrive8_capabilities & OD8_TEMPERATURE_SYSTEM) 1089 + od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].default_value = 1090 + od_table->MaxOpTemp; 1091 + else 1092 + od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].default_value = 1093 + 0; 1094 + 1095 + for (i = 0; i < OD8_SETTING_COUNT; i++) { 1096 + if (od8_settings->od8_settings_array[i].feature_id) { 1097 + od8_settings->od8_settings_array[i].min_value = 1098 + pptable_information->od_settings_min[i]; 1099 + od8_settings->od8_settings_array[i].max_value = 1100 + pptable_information->od_settings_max[i]; 1101 + od8_settings->od8_settings_array[i].current_value = 1102 + od8_settings->od8_settings_array[i].default_value; 1103 + } else { 1104 + od8_settings->od8_settings_array[i].min_value = 1105 + 0; 1106 + od8_settings->od8_settings_array[i].max_value = 1107 + 0; 1108 + od8_settings->od8_settings_array[i].current_value = 1109 + 0; 1110 + } 1111 + } 1112 + 834 1113 return 0; 835 1114 } 836 1115 ··· 1264 1009 "[EnableDPMTasks] Failed to power control set level!", 1265 1010 return result); 1266 1011 1267 - result = vega20_odn_initialize_default_settings(hwmgr); 1012 + result = vega20_od8_initialize_default_settings(hwmgr); 1268 1013 PP_ASSERT_WITH_CODE(!result, 1269 1014 "[EnableDPMTasks] Failed to initialize odn settings!", 1270 1015 return result);
+52 -1
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.h
··· 306 306 uint8_t led_dpm_enabled; 307 307 uint8_t fan_control_support; 308 308 uint8_t ulv_support; 309 - uint8_t odn_feature_enable; 309 + uint8_t od8_feature_enable; 310 310 uint8_t disable_water_mark; 311 311 uint8_t disable_workload_policy; 312 312 uint32_t force_workload_policy_mask; ··· 375 375 struct vega20_odn_dpm_table odn_dpm_table; 376 376 struct vega20_odn_fan_table odn_fan_table; 377 377 struct vega20_odn_temp_table odn_temp_table; 378 + }; 379 + 380 + enum OD8_FEATURE_ID 381 + { 382 + OD8_GFXCLK_LIMITS = 1 << 0, 383 + OD8_GFXCLK_CURVE = 1 << 1, 384 + OD8_UCLK_MAX = 1 << 2, 385 + OD8_POWER_LIMIT = 1 << 3, 386 + OD8_ACOUSTIC_LIMIT_SCLK = 1 << 4, //FanMaximumRpm 387 + OD8_FAN_SPEED_MIN = 1 << 5, //FanMinimumPwm 388 + OD8_TEMPERATURE_FAN = 1 << 6, //FanTargetTemperature 389 + OD8_TEMPERATURE_SYSTEM = 1 << 7, //MaxOpTemp 390 + OD8_MEMORY_TIMING_TUNE = 1 << 8, 391 + OD8_FAN_ZERO_RPM_CONTROL = 1 << 9 392 + }; 393 + 394 + enum OD8_SETTING_ID 395 + { 396 + OD8_SETTING_GFXCLK_FMIN = 0, 397 + OD8_SETTING_GFXCLK_FMAX, 398 + OD8_SETTING_GFXCLK_FREQ1, 399 + OD8_SETTING_GFXCLK_VOLTAGE1, 400 + OD8_SETTING_GFXCLK_FREQ2, 401 + OD8_SETTING_GFXCLK_VOLTAGE2, 402 + OD8_SETTING_GFXCLK_FREQ3, 403 + OD8_SETTING_GFXCLK_VOLTAGE3, 404 + OD8_SETTING_UCLK_FMAX, 405 + OD8_SETTING_POWER_PERCENTAGE, 406 + OD8_SETTING_FAN_ACOUSTIC_LIMIT, 407 + OD8_SETTING_FAN_MIN_SPEED, 408 + OD8_SETTING_FAN_TARGET_TEMP, 409 + OD8_SETTING_OPERATING_TEMP_MAX, 410 + OD8_SETTING_AC_TIMING, 411 + OD8_SETTING_FAN_ZERO_RPM_CONTROL, 412 + OD8_SETTING_COUNT 413 + }; 414 + 415 + struct vega20_od8_single_setting { 416 + uint32_t feature_id; 417 + int32_t min_value; 418 + int32_t max_value; 419 + int32_t current_value; 420 + int32_t default_value; 421 + }; 422 + 423 + struct vega20_od8_settings { 424 + uint32_t overdrive8_capabilities; 425 + struct vega20_od8_single_setting od8_settings_array[OD8_SETTING_COUNT]; 378 426 }; 379 427 380 428 struct vega20_hwmgr { ··· 499 451 500 452 /* ---- Overdrive next setting ---- */ 501 453 struct vega20_odn_data odn_data; 454 + 455 + /* ---- Overdrive8 Setting ---- */ 456 + struct vega20_od8_settings od8_settings; 502 457 503 458 /* ---- Workload Mask ---- */ 504 459 uint32_t workload_mask;
+74 -29
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_processpptables.c
··· 664 664 static int copy_clock_limits_array( 665 665 struct pp_hwmgr *hwmgr, 666 666 uint32_t **pptable_info_array, 667 - const uint32_t *pptable_array) 667 + const uint32_t *pptable_array, 668 + uint32_t power_saving_clock_count) 668 669 { 669 670 uint32_t array_size, i; 670 671 uint32_t *table; 671 672 672 - array_size = sizeof(uint32_t) * ATOM_VEGA20_PPCLOCK_COUNT; 673 - 673 + array_size = sizeof(uint32_t) * power_saving_clock_count; 674 674 table = kzalloc(array_size, GFP_KERNEL); 675 675 if (NULL == table) 676 676 return -ENOMEM; 677 677 678 - for (i = 0; i < ATOM_VEGA20_PPCLOCK_COUNT; i++) 678 + for (i = 0; i < power_saving_clock_count; i++) 679 679 table[i] = pptable_array[i]; 680 680 681 681 *pptable_info_array = table; ··· 686 686 static int copy_overdrive_settings_limits_array( 687 687 struct pp_hwmgr *hwmgr, 688 688 uint32_t **pptable_info_array, 689 - const uint32_t *pptable_array) 689 + const uint32_t *pptable_array, 690 + uint32_t od_setting_count) 690 691 { 691 692 uint32_t array_size, i; 692 693 uint32_t *table; 693 694 694 - array_size = sizeof(uint32_t) * ATOM_VEGA20_ODSETTING_COUNT; 695 - 695 + array_size = sizeof(uint32_t) * od_setting_count; 696 696 table = kzalloc(array_size, GFP_KERNEL); 697 697 if (NULL == table) 698 698 return -ENOMEM; 699 699 700 - for (i = 0; i < ATOM_VEGA20_ODSETTING_COUNT; i++) 700 + for (i = 0; i < od_setting_count; i++) 701 701 table[i] = pptable_array[i]; 702 702 703 703 *pptable_info_array = table; 704 + 705 + return 0; 706 + } 707 + 708 + static int copy_overdrive_feature_capabilities_array( 709 + struct pp_hwmgr *hwmgr, 710 + uint8_t **pptable_info_array, 711 + const uint8_t *pptable_array, 712 + uint8_t od_feature_count) 713 + { 714 + uint32_t array_size, i; 715 + uint8_t *table; 716 + bool od_supported = false; 717 + 718 + array_size = sizeof(uint8_t) * od_feature_count; 719 + table = kzalloc(array_size, GFP_KERNEL); 720 + if (NULL == table) 721 + return -ENOMEM; 722 + 723 + for (i = 0; i < od_feature_count; i++) { 724 + table[i] = pptable_array[i]; 725 + if (table[i]) 726 + od_supported = true; 727 + } 728 + 729 + *pptable_info_array = table; 730 + 731 + if (od_supported) 732 + phm_cap_set(hwmgr->platform_descriptor.platformCaps, 733 + PHM_PlatformCaps_ACOverdriveSupport); 704 734 705 735 return 0; 706 736 } ··· 829 799 struct phm_ppt_v3_information *pptable_information = 830 800 (struct phm_ppt_v3_information *)hwmgr->pptable; 831 801 uint32_t disable_power_control = 0; 802 + uint32_t od_feature_count, od_setting_count, power_saving_clock_count; 832 803 int result; 833 804 834 805 hwmgr->thermal_controller.ucType = powerplay_table->ucThermalControllerType; ··· 841 810 842 811 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl); 843 812 844 - if (powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_GFXCLKFMAX] > VEGA20_ENGINECLOCK_HARDMAX) 845 - hwmgr->platform_descriptor.overdriveLimit.engineClock = VEGA20_ENGINECLOCK_HARDMAX; 846 - else 847 - hwmgr->platform_descriptor.overdriveLimit.engineClock = powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_GFXCLKFMAX]; 848 - hwmgr->platform_descriptor.overdriveLimit.memoryClock = powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_UCLKFMAX]; 813 + if (powerplay_table->OverDrive8Table.ucODTableRevision == 1) { 814 + od_feature_count = (powerplay_table->OverDrive8Table.ODFeatureCount > ATOM_VEGA20_ODFEATURE_COUNT) ? 815 + ATOM_VEGA20_ODFEATURE_COUNT : powerplay_table->OverDrive8Table.ODFeatureCount; 816 + od_setting_count = (powerplay_table->OverDrive8Table.ODSettingCount > ATOM_VEGA20_ODSETTING_COUNT) ? 817 + ATOM_VEGA20_ODSETTING_COUNT : powerplay_table->OverDrive8Table.ODSettingCount; 849 818 850 - copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_max, powerplay_table->OverDrive8Table.ODSettingsMax); 851 - copy_overdrive_settings_limits_array(hwmgr, &pptable_information->od_settings_min, powerplay_table->OverDrive8Table.ODSettingsMin); 852 - 853 - /* hwmgr->platformDescriptor.minOverdriveVDDC = 0; 854 - hwmgr->platformDescriptor.maxOverdriveVDDC = 0; 855 - hwmgr->platformDescriptor.overdriveVDDCStep = 0; */ 856 - 857 - if (hwmgr->platform_descriptor.overdriveLimit.engineClock > 0 858 - && hwmgr->platform_descriptor.overdriveLimit.memoryClock > 0) 859 - phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_ACOverdriveSupport); 819 + copy_overdrive_feature_capabilities_array(hwmgr, 820 + &pptable_information->od_feature_capabilities, 821 + powerplay_table->OverDrive8Table.ODFeatureCapabilities, 822 + od_feature_count); 823 + copy_overdrive_settings_limits_array(hwmgr, 824 + &pptable_information->od_settings_max, 825 + powerplay_table->OverDrive8Table.ODSettingsMax, 826 + od_setting_count); 827 + copy_overdrive_settings_limits_array(hwmgr, 828 + &pptable_information->od_settings_min, 829 + powerplay_table->OverDrive8Table.ODSettingsMin, 830 + od_setting_count); 831 + } 860 832 861 833 pptable_information->us_small_power_limit1 = powerplay_table->usSmallPowerLimit1; 862 834 pptable_information->us_small_power_limit2 = powerplay_table->usSmallPowerLimit2; ··· 872 838 hwmgr->platform_descriptor.TDPODLimit = (uint16_t)powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE]; 873 839 874 840 disable_power_control = 0; 875 - if (!disable_power_control && hwmgr->platform_descriptor.TDPODLimit) { 841 + if (!disable_power_control && hwmgr->platform_descriptor.TDPODLimit) 876 842 /* enable TDP overdrive (PowerControl) feature as well if supported */ 877 - phm_cap_set(hwmgr->platform_descriptor.platformCaps, 878 - PHM_PlatformCaps_PowerControl); 879 - } 843 + phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerControl); 880 844 881 - copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_max, powerplay_table->PowerSavingClockTable.PowerSavingClockMax); 882 - copy_clock_limits_array(hwmgr, &pptable_information->power_saving_clock_min, powerplay_table->PowerSavingClockTable.PowerSavingClockMin); 845 + if (powerplay_table->PowerSavingClockTable.ucTableRevision == 1) { 846 + power_saving_clock_count = (powerplay_table->PowerSavingClockTable.PowerSavingClockCount >= ATOM_VEGA20_PPCLOCK_COUNT) ? 847 + ATOM_VEGA20_PPCLOCK_COUNT : powerplay_table->PowerSavingClockTable.PowerSavingClockCount; 848 + copy_clock_limits_array(hwmgr, 849 + &pptable_information->power_saving_clock_max, 850 + powerplay_table->PowerSavingClockTable.PowerSavingClockMax, 851 + power_saving_clock_count); 852 + copy_clock_limits_array(hwmgr, 853 + &pptable_information->power_saving_clock_min, 854 + powerplay_table->PowerSavingClockTable.PowerSavingClockMin, 855 + power_saving_clock_count); 856 + } 883 857 884 858 pptable_information->smc_pptable = (PPTable_t *)kmalloc(sizeof(PPTable_t), GFP_KERNEL); 885 859 if (pptable_information->smc_pptable == NULL) ··· 939 897 940 898 kfree(pp_table_info->power_saving_clock_min); 941 899 pp_table_info->power_saving_clock_min = NULL; 900 + 901 + kfree(pp_table_info->od_feature_capabilities); 902 + pp_table_info->od_feature_capabilities = NULL; 942 903 943 904 kfree(pp_table_info->od_settings_max); 944 905 pp_table_info->od_settings_max = NULL;
+2
drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h
··· 232 232 PHM_PlatformCaps_UVDClientMCTuning, 233 233 PHM_PlatformCaps_ODNinACSupport, 234 234 PHM_PlatformCaps_ODNinDCSupport, 235 + PHM_PlatformCaps_OD8inACSupport, 236 + PHM_PlatformCaps_OD8inDCSupport, 235 237 PHM_PlatformCaps_UMDPState, 236 238 PHM_PlatformCaps_AutoWattmanSupport, 237 239 PHM_PlatformCaps_AutoWattmanEnable_CCCState,
+1
drivers/gpu/drm/amd/powerplay/inc/hwmgr.h
··· 583 583 uint32_t *power_saving_clock_max; 584 584 uint32_t *power_saving_clock_min; 585 585 586 + uint8_t *od_feature_capabilities; 586 587 uint32_t *od_settings_max; 587 588 uint32_t *od_settings_min; 588 589