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

drm/amdgpu: use begin/end_use for VCE power/clock gating

This fixes turning power and clock on when it is actually needed.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Edward O'Callaghan <funfunctor@folklore1984.net>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
ebff485e c4120d55

+31 -13
+1
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 1702 1702 struct drm_file *filp[AMDGPU_MAX_VCE_HANDLES]; 1703 1703 uint32_t img_size[AMDGPU_MAX_VCE_HANDLES]; 1704 1704 struct delayed_work idle_work; 1705 + struct mutex idle_mutex; 1705 1706 const struct firmware *fw; /* VCE firmware */ 1706 1707 struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; 1707 1708 struct amdgpu_irq_src irq;
+24 -13
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
··· 85 85 unsigned ucode_version, version_major, version_minor, binary_id; 86 86 int i, r; 87 87 88 - INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler); 89 - 90 88 switch (adev->asic_type) { 91 89 #ifdef CONFIG_DRM_AMDGPU_CIK 92 90 case CHIP_BONAIRE: ··· 195 197 adev->vce.filp[i] = NULL; 196 198 } 197 199 200 + INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler); 201 + mutex_init(&adev->vce.idle_mutex); 202 + 198 203 return 0; 199 204 } 200 205 ··· 221 220 amdgpu_ring_fini(&adev->vce.ring[1]); 222 221 223 222 release_firmware(adev->vce.fw); 223 + mutex_destroy(&adev->vce.idle_mutex); 224 224 225 225 return 0; 226 226 } ··· 317 315 } 318 316 319 317 /** 320 - * amdgpu_vce_note_usage - power up VCE 318 + * amdgpu_vce_ring_begin_use - power up VCE 321 319 * 322 - * @adev: amdgpu_device pointer 320 + * @ring: amdgpu ring 323 321 * 324 322 * Make sure VCE is powerd up when we want to use it 325 323 */ 326 - static void amdgpu_vce_note_usage(struct amdgpu_device *adev) 324 + void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring) 327 325 { 328 - bool set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work); 326 + struct amdgpu_device *adev = ring->adev; 327 + bool set_clocks; 329 328 330 - set_clocks &= schedule_delayed_work(&adev->vce.idle_work, 331 - VCE_IDLE_TIMEOUT); 332 - 329 + mutex_lock(&adev->vce.idle_mutex); 330 + set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work); 333 331 if (set_clocks) { 334 332 if (adev->pm.dpm_enabled) { 335 333 amdgpu_dpm_enable_vce(adev, true); ··· 337 335 amdgpu_asic_set_vce_clocks(adev, 53300, 40000); 338 336 } 339 337 } 338 + mutex_unlock(&adev->vce.idle_mutex); 339 + } 340 + 341 + /** 342 + * amdgpu_vce_ring_end_use - power VCE down 343 + * 344 + * @ring: amdgpu ring 345 + * 346 + * Schedule work to power VCE down again 347 + */ 348 + void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring) 349 + { 350 + schedule_delayed_work(&ring->adev->vce.idle_work, VCE_IDLE_TIMEOUT); 340 351 } 341 352 342 353 /** ··· 369 354 370 355 if (!handle || adev->vce.filp[i] != filp) 371 356 continue; 372 - 373 - amdgpu_vce_note_usage(adev); 374 357 375 358 r = amdgpu_vce_get_destroy_msg(ring, handle, false, NULL); 376 359 if (r) ··· 634 621 uint32_t tmp, handle = 0; 635 622 uint32_t *size = &tmp; 636 623 int i, r = 0, idx = 0; 637 - 638 - amdgpu_vce_note_usage(p->adev); 639 624 640 625 while (idx < ib->length_dw) { 641 626 uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
+2
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h
··· 40 40 unsigned flags); 41 41 int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); 42 42 int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring); 43 + void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring); 44 + void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring); 43 45 44 46 #endif
+2
drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
··· 594 594 .test_ib = amdgpu_vce_ring_test_ib, 595 595 .insert_nop = amdgpu_ring_insert_nop, 596 596 .pad_ib = amdgpu_ring_generic_pad_ib, 597 + .begin_use = amdgpu_vce_ring_begin_use, 598 + .end_use = amdgpu_vce_ring_end_use, 597 599 }; 598 600 599 601 static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev)
+2
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
··· 767 767 .test_ib = amdgpu_vce_ring_test_ib, 768 768 .insert_nop = amdgpu_ring_insert_nop, 769 769 .pad_ib = amdgpu_ring_generic_pad_ib, 770 + .begin_use = amdgpu_vce_ring_begin_use, 771 + .end_use = amdgpu_vce_ring_end_use, 770 772 }; 771 773 772 774 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)