diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/si_dpm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/si_dpm.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/si_dpm.c b/drivers/gpu/drm/amd/amdgpu/si_dpm.c index 3de7bca5854b..917213396787 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dpm.c | |||
@@ -3171,6 +3171,7 @@ static void ni_update_current_ps(struct amdgpu_device *adev, | |||
3171 | eg_pi->current_rps = *rps; | 3171 | eg_pi->current_rps = *rps; |
3172 | ni_pi->current_ps = *new_ps; | 3172 | ni_pi->current_ps = *new_ps; |
3173 | eg_pi->current_rps.ps_priv = &ni_pi->current_ps; | 3173 | eg_pi->current_rps.ps_priv = &ni_pi->current_ps; |
3174 | adev->pm.dpm.current_ps = &eg_pi->current_rps; | ||
3174 | } | 3175 | } |
3175 | 3176 | ||
3176 | static void ni_update_requested_ps(struct amdgpu_device *adev, | 3177 | static void ni_update_requested_ps(struct amdgpu_device *adev, |
@@ -3183,6 +3184,7 @@ static void ni_update_requested_ps(struct amdgpu_device *adev, | |||
3183 | eg_pi->requested_rps = *rps; | 3184 | eg_pi->requested_rps = *rps; |
3184 | ni_pi->requested_ps = *new_ps; | 3185 | ni_pi->requested_ps = *new_ps; |
3185 | eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps; | 3186 | eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps; |
3187 | adev->pm.dpm.requested_ps = &eg_pi->requested_rps; | ||
3186 | } | 3188 | } |
3187 | 3189 | ||
3188 | static void ni_set_uvd_clock_before_set_eng_clock(struct amdgpu_device *adev, | 3190 | static void ni_set_uvd_clock_before_set_eng_clock(struct amdgpu_device *adev, |
@@ -7320,7 +7322,7 @@ static int si_parse_power_table(struct amdgpu_device *adev) | |||
7320 | adev->pm.dpm.num_ps = state_array->ucNumEntries; | 7322 | adev->pm.dpm.num_ps = state_array->ucNumEntries; |
7321 | 7323 | ||
7322 | /* fill in the vce power states */ | 7324 | /* fill in the vce power states */ |
7323 | for (i = 0; i < AMDGPU_MAX_VCE_LEVELS; i++) { | 7325 | for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) { |
7324 | u32 sclk, mclk; | 7326 | u32 sclk, mclk; |
7325 | clock_array_index = adev->pm.dpm.vce_states[i].clk_idx; | 7327 | clock_array_index = adev->pm.dpm.vce_states[i].clk_idx; |
7326 | clock_info = (union pplib_clock_info *) | 7328 | clock_info = (union pplib_clock_info *) |
@@ -7957,6 +7959,57 @@ static int si_dpm_early_init(void *handle) | |||
7957 | return 0; | 7959 | return 0; |
7958 | } | 7960 | } |
7959 | 7961 | ||
7962 | static inline bool si_are_power_levels_equal(const struct rv7xx_pl *si_cpl1, | ||
7963 | const struct rv7xx_pl *si_cpl2) | ||
7964 | { | ||
7965 | return ((si_cpl1->mclk == si_cpl2->mclk) && | ||
7966 | (si_cpl1->sclk == si_cpl2->sclk) && | ||
7967 | (si_cpl1->pcie_gen == si_cpl2->pcie_gen) && | ||
7968 | (si_cpl1->vddc == si_cpl2->vddc) && | ||
7969 | (si_cpl1->vddci == si_cpl2->vddci)); | ||
7970 | } | ||
7971 | |||
7972 | static int si_check_state_equal(struct amdgpu_device *adev, | ||
7973 | struct amdgpu_ps *cps, | ||
7974 | struct amdgpu_ps *rps, | ||
7975 | bool *equal) | ||
7976 | { | ||
7977 | struct si_ps *si_cps; | ||
7978 | struct si_ps *si_rps; | ||
7979 | int i; | ||
7980 | |||
7981 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) | ||
7982 | return -EINVAL; | ||
7983 | |||
7984 | si_cps = si_get_ps(cps); | ||
7985 | si_rps = si_get_ps(rps); | ||
7986 | |||
7987 | if (si_cps == NULL) { | ||
7988 | printk("si_cps is NULL\n"); | ||
7989 | *equal = false; | ||
7990 | return 0; | ||
7991 | } | ||
7992 | |||
7993 | if (si_cps->performance_level_count != si_rps->performance_level_count) { | ||
7994 | *equal = false; | ||
7995 | return 0; | ||
7996 | } | ||
7997 | |||
7998 | for (i = 0; i < si_cps->performance_level_count; i++) { | ||
7999 | if (!si_are_power_levels_equal(&(si_cps->performance_levels[i]), | ||
8000 | &(si_rps->performance_levels[i]))) { | ||
8001 | *equal = false; | ||
8002 | return 0; | ||
8003 | } | ||
8004 | } | ||
8005 | |||
8006 | /* If all performance levels are the same try to use the UVD clocks to break the tie.*/ | ||
8007 | *equal = ((cps->vclk == rps->vclk) && (cps->dclk == rps->dclk)); | ||
8008 | *equal &= ((cps->evclk == rps->evclk) && (cps->ecclk == rps->ecclk)); | ||
8009 | |||
8010 | return 0; | ||
8011 | } | ||
8012 | |||
7960 | 8013 | ||
7961 | const struct amd_ip_funcs si_dpm_ip_funcs = { | 8014 | const struct amd_ip_funcs si_dpm_ip_funcs = { |
7962 | .name = "si_dpm", | 8015 | .name = "si_dpm", |
@@ -7991,6 +8044,8 @@ static const struct amdgpu_dpm_funcs si_dpm_funcs = { | |||
7991 | .get_fan_control_mode = &si_dpm_get_fan_control_mode, | 8044 | .get_fan_control_mode = &si_dpm_get_fan_control_mode, |
7992 | .set_fan_speed_percent = &si_dpm_set_fan_speed_percent, | 8045 | .set_fan_speed_percent = &si_dpm_set_fan_speed_percent, |
7993 | .get_fan_speed_percent = &si_dpm_get_fan_speed_percent, | 8046 | .get_fan_speed_percent = &si_dpm_get_fan_speed_percent, |
8047 | .check_state_equal = &si_check_state_equal, | ||
8048 | .get_vce_clock_state = amdgpu_get_vce_clock_state, | ||
7994 | }; | 8049 | }; |
7995 | 8050 | ||
7996 | static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev) | 8051 | static void si_dpm_set_dpm_funcs(struct amdgpu_device *adev) |
@@ -8010,3 +8065,11 @@ static void si_dpm_set_irq_funcs(struct amdgpu_device *adev) | |||
8010 | adev->pm.dpm.thermal.irq.funcs = &si_dpm_irq_funcs; | 8065 | adev->pm.dpm.thermal.irq.funcs = &si_dpm_irq_funcs; |
8011 | } | 8066 | } |
8012 | 8067 | ||
8068 | const struct amdgpu_ip_block_version si_dpm_ip_block = | ||
8069 | { | ||
8070 | .type = AMD_IP_BLOCK_TYPE_SMC, | ||
8071 | .major = 6, | ||
8072 | .minor = 0, | ||
8073 | .rev = 0, | ||
8074 | .funcs = &si_dpm_ip_funcs, | ||
8075 | }; | ||