--- a/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c +++ b/sys/dev/drm/amd/powerplay/hwmgr/vega20_processpptables.c @@ -685,13 +685,14 @@ struct pp_hwmgr *hwmgr, uint8_t **pptable_info_array, const uint8_t *pptable_array, - uint8_t od_feature_count) + uint8_t od_feature_count, /* entries the VBIOS provides */ + uint8_t od_feature_alloc) /* entries the driver indexes */ { uint32_t array_size, i; uint8_t *table; bool od_supported = false; - array_size = sizeof(uint8_t) * od_feature_count; + array_size = sizeof(uint8_t) * od_feature_alloc; table = kzalloc(array_size, GFP_KERNEL); if (NULL == table) return -ENOMEM; @@ -711,6 +712,28 @@ return 0; } +/* DF-4544: phm_copy_overdrive_settings_limits_array() (smu_helper.c:64) + * sizes the allocation from the count we pass it, while the driver-side + * OD8_SETTING_ID enum (vega20_hwmgr.h:398-417) indexes up to entry 13 -- + * the allocation must never be smaller than ATOM_VEGA20_ODSETTING_COUNT. + */ +static int vega20_copy_od_settings_limits_array( + uint32_t **pptable_info_array, + const uint32_t *pptable_array, + uint32_t table_count) +{ + uint32_t i, *table; + + table = kzalloc(sizeof(uint32_t) * ATOM_VEGA20_ODSETTING_COUNT, + GFP_KERNEL); + if (table == NULL) + return -ENOMEM; + for (i = 0; i < table_count && i < ATOM_VEGA20_ODSETTING_COUNT; i++) + table[i] = le32_to_cpu(pptable_array[i]); + *pptable_info_array = table; + return 0; +} + static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable) { struct atom_smc_dpm_info_v4_4 *smc_dpm_table; @@ -835,12 +858,13 @@ copy_overdrive_feature_capabilities_array(hwmgr, &pptable_information->od_feature_capabilities, powerplay_table->OverDrive8Table.ODFeatureCapabilities, - od_feature_count); - phm_copy_overdrive_settings_limits_array(hwmgr, + od_feature_count, + ATOM_VEGA20_ODFEATURE_COUNT); + vega20_copy_od_settings_limits_array( &pptable_information->od_settings_max, powerplay_table->OverDrive8Table.ODSettingsMax, od_setting_count); - phm_copy_overdrive_settings_limits_array(hwmgr, + vega20_copy_od_settings_limits_array( &pptable_information->od_settings_min, powerplay_table->OverDrive8Table.ODSettingsMin, od_setting_count);