diff options
author | Rex Zhu <Rex.Zhu@amd.com> | 2017-01-20 01:27:22 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-01-27 12:20:43 -0500 |
commit | 36a94a8ad74e83a135a4b0a2157dabe50b4562a6 (patch) | |
tree | 6c62b44bfc8615181b8ff43ce4aad2694f1961ef | |
parent | cb256cc383bddd5e5f135279ebb4112dfb991f37 (diff) |
drm/amdgpu: fix dpm bug on Kv.
1. current_ps/request_ps not update.
2. compare crrent_ps and request_ps, if same,
don't re-set power state.
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c index 90c2af381cbd..6b6476dae970 100644 --- a/drivers/gpu/drm/amd/amdgpu/kv_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/kv_dpm.c | |||
@@ -1230,6 +1230,7 @@ static void kv_update_current_ps(struct amdgpu_device *adev, | |||
1230 | pi->current_rps = *rps; | 1230 | pi->current_rps = *rps; |
1231 | pi->current_ps = *new_ps; | 1231 | pi->current_ps = *new_ps; |
1232 | pi->current_rps.ps_priv = &pi->current_ps; | 1232 | pi->current_rps.ps_priv = &pi->current_ps; |
1233 | adev->pm.dpm.current_ps = &pi->current_rps; | ||
1233 | } | 1234 | } |
1234 | 1235 | ||
1235 | static void kv_update_requested_ps(struct amdgpu_device *adev, | 1236 | static void kv_update_requested_ps(struct amdgpu_device *adev, |
@@ -1241,6 +1242,7 @@ static void kv_update_requested_ps(struct amdgpu_device *adev, | |||
1241 | pi->requested_rps = *rps; | 1242 | pi->requested_rps = *rps; |
1242 | pi->requested_ps = *new_ps; | 1243 | pi->requested_ps = *new_ps; |
1243 | pi->requested_rps.ps_priv = &pi->requested_ps; | 1244 | pi->requested_rps.ps_priv = &pi->requested_ps; |
1245 | adev->pm.dpm.requested_ps = &pi->requested_rps; | ||
1244 | } | 1246 | } |
1245 | 1247 | ||
1246 | static void kv_dpm_enable_bapm(struct amdgpu_device *adev, bool enable) | 1248 | static void kv_dpm_enable_bapm(struct amdgpu_device *adev, bool enable) |
@@ -3009,7 +3011,6 @@ static int kv_dpm_late_init(void *handle) | |||
3009 | kv_dpm_powergate_samu(adev, true); | 3011 | kv_dpm_powergate_samu(adev, true); |
3010 | kv_dpm_powergate_vce(adev, true); | 3012 | kv_dpm_powergate_vce(adev, true); |
3011 | kv_dpm_powergate_uvd(adev, true); | 3013 | kv_dpm_powergate_uvd(adev, true); |
3012 | |||
3013 | return 0; | 3014 | return 0; |
3014 | } | 3015 | } |
3015 | 3016 | ||
@@ -3245,15 +3246,52 @@ static int kv_dpm_set_powergating_state(void *handle, | |||
3245 | return 0; | 3246 | return 0; |
3246 | } | 3247 | } |
3247 | 3248 | ||
3249 | static inline bool kv_are_power_levels_equal(const struct kv_pl *kv_cpl1, | ||
3250 | const struct kv_pl *kv_cpl2) | ||
3251 | { | ||
3252 | return ((kv_cpl1->sclk == kv_cpl2->sclk) && | ||
3253 | (kv_cpl1->vddc_index == kv_cpl2->vddc_index) && | ||
3254 | (kv_cpl1->ds_divider_index == kv_cpl2->ds_divider_index) && | ||
3255 | (kv_cpl1->force_nbp_state == kv_cpl2->force_nbp_state)); | ||
3256 | } | ||
3257 | |||
3248 | static int kv_check_state_equal(struct amdgpu_device *adev, | 3258 | static int kv_check_state_equal(struct amdgpu_device *adev, |
3249 | struct amdgpu_ps *cps, | 3259 | struct amdgpu_ps *cps, |
3250 | struct amdgpu_ps *rps, | 3260 | struct amdgpu_ps *rps, |
3251 | bool *equal) | 3261 | bool *equal) |
3252 | { | 3262 | { |
3253 | if (equal == NULL) | 3263 | struct kv_ps *kv_cps; |
3264 | struct kv_ps *kv_rps; | ||
3265 | int i; | ||
3266 | |||
3267 | if (adev == NULL || cps == NULL || rps == NULL || equal == NULL) | ||
3254 | return -EINVAL; | 3268 | return -EINVAL; |
3255 | 3269 | ||
3256 | *equal = false; | 3270 | kv_cps = kv_get_ps(cps); |
3271 | kv_rps = kv_get_ps(rps); | ||
3272 | |||
3273 | if (kv_cps == NULL) { | ||
3274 | *equal = false; | ||
3275 | return 0; | ||
3276 | } | ||
3277 | |||
3278 | if (kv_cps->num_levels != kv_rps->num_levels) { | ||
3279 | *equal = false; | ||
3280 | return 0; | ||
3281 | } | ||
3282 | |||
3283 | for (i = 0; i < kv_cps->num_levels; i++) { | ||
3284 | if (!kv_are_power_levels_equal(&(kv_cps->levels[i]), | ||
3285 | &(kv_rps->levels[i]))) { | ||
3286 | *equal = false; | ||
3287 | return 0; | ||
3288 | } | ||
3289 | } | ||
3290 | |||
3291 | /* If all performance levels are the same try to use the UVD clocks to break the tie.*/ | ||
3292 | *equal = ((cps->vclk == rps->vclk) && (cps->dclk == rps->dclk)); | ||
3293 | *equal &= ((cps->evclk == rps->evclk) && (cps->ecclk == rps->ecclk)); | ||
3294 | |||
3257 | return 0; | 3295 | return 0; |
3258 | } | 3296 | } |
3259 | 3297 | ||