diff options
author | Christian König <christian.koenig@amd.com> | 2016-07-20 10:53:36 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2016-07-29 14:37:03 -0400 |
commit | ebff485e9314f8c53f6b22eba0dfbec7228ab268 (patch) | |
tree | bfe32720f5ef21855af1db8274142491716959ba | |
parent | c4120d55ffa44746584a8a1e5b00cb7eafc006ff (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 2 |
5 files changed, 31 insertions, 13 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 51c4924b60b7..02a0d19ce54c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -1702,6 +1702,7 @@ struct amdgpu_vce { | |||
1702 | struct drm_file *filp[AMDGPU_MAX_VCE_HANDLES]; | 1702 | struct drm_file *filp[AMDGPU_MAX_VCE_HANDLES]; |
1703 | uint32_t img_size[AMDGPU_MAX_VCE_HANDLES]; | 1703 | uint32_t img_size[AMDGPU_MAX_VCE_HANDLES]; |
1704 | struct delayed_work idle_work; | 1704 | struct delayed_work idle_work; |
1705 | struct mutex idle_mutex; | ||
1705 | const struct firmware *fw; /* VCE firmware */ | 1706 | const struct firmware *fw; /* VCE firmware */ |
1706 | struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; | 1707 | struct amdgpu_ring ring[AMDGPU_MAX_VCE_RINGS]; |
1707 | struct amdgpu_irq_src irq; | 1708 | struct amdgpu_irq_src irq; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index aeeeb72ebbc4..6b49d406daf6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -85,8 +85,6 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) | |||
85 | unsigned ucode_version, version_major, version_minor, binary_id; | 85 | unsigned ucode_version, version_major, version_minor, binary_id; |
86 | int i, r; | 86 | int i, r; |
87 | 87 | ||
88 | INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler); | ||
89 | |||
90 | switch (adev->asic_type) { | 88 | switch (adev->asic_type) { |
91 | #ifdef CONFIG_DRM_AMDGPU_CIK | 89 | #ifdef CONFIG_DRM_AMDGPU_CIK |
92 | case CHIP_BONAIRE: | 90 | case CHIP_BONAIRE: |
@@ -197,6 +195,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size) | |||
197 | adev->vce.filp[i] = NULL; | 195 | adev->vce.filp[i] = NULL; |
198 | } | 196 | } |
199 | 197 | ||
198 | INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler); | ||
199 | mutex_init(&adev->vce.idle_mutex); | ||
200 | |||
200 | return 0; | 201 | return 0; |
201 | } | 202 | } |
202 | 203 | ||
@@ -220,6 +221,7 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) | |||
220 | amdgpu_ring_fini(&adev->vce.ring[1]); | 221 | amdgpu_ring_fini(&adev->vce.ring[1]); |
221 | 222 | ||
222 | release_firmware(adev->vce.fw); | 223 | release_firmware(adev->vce.fw); |
224 | mutex_destroy(&adev->vce.idle_mutex); | ||
223 | 225 | ||
224 | return 0; | 226 | return 0; |
225 | } | 227 | } |
@@ -315,19 +317,19 @@ static void amdgpu_vce_idle_work_handler(struct work_struct *work) | |||
315 | } | 317 | } |
316 | 318 | ||
317 | /** | 319 | /** |
318 | * amdgpu_vce_note_usage - power up VCE | 320 | * amdgpu_vce_ring_begin_use - power up VCE |
319 | * | 321 | * |
320 | * @adev: amdgpu_device pointer | 322 | * @ring: amdgpu ring |
321 | * | 323 | * |
322 | * Make sure VCE is powerd up when we want to use it | 324 | * Make sure VCE is powerd up when we want to use it |
323 | */ | 325 | */ |
324 | static void amdgpu_vce_note_usage(struct amdgpu_device *adev) | 326 | void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring) |
325 | { | 327 | { |
326 | bool set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work); | 328 | struct amdgpu_device *adev = ring->adev; |
327 | 329 | bool set_clocks; | |
328 | set_clocks &= schedule_delayed_work(&adev->vce.idle_work, | ||
329 | VCE_IDLE_TIMEOUT); | ||
330 | 330 | ||
331 | mutex_lock(&adev->vce.idle_mutex); | ||
332 | set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work); | ||
331 | if (set_clocks) { | 333 | if (set_clocks) { |
332 | if (adev->pm.dpm_enabled) { | 334 | if (adev->pm.dpm_enabled) { |
333 | amdgpu_dpm_enable_vce(adev, true); | 335 | amdgpu_dpm_enable_vce(adev, true); |
@@ -335,6 +337,19 @@ static void amdgpu_vce_note_usage(struct amdgpu_device *adev) | |||
335 | amdgpu_asic_set_vce_clocks(adev, 53300, 40000); | 337 | amdgpu_asic_set_vce_clocks(adev, 53300, 40000); |
336 | } | 338 | } |
337 | } | 339 | } |
340 | mutex_unlock(&adev->vce.idle_mutex); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * amdgpu_vce_ring_end_use - power VCE down | ||
345 | * | ||
346 | * @ring: amdgpu ring | ||
347 | * | ||
348 | * Schedule work to power VCE down again | ||
349 | */ | ||
350 | void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring) | ||
351 | { | ||
352 | schedule_delayed_work(&ring->adev->vce.idle_work, VCE_IDLE_TIMEOUT); | ||
338 | } | 353 | } |
339 | 354 | ||
340 | /** | 355 | /** |
@@ -355,8 +370,6 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp) | |||
355 | if (!handle || adev->vce.filp[i] != filp) | 370 | if (!handle || adev->vce.filp[i] != filp) |
356 | continue; | 371 | continue; |
357 | 372 | ||
358 | amdgpu_vce_note_usage(adev); | ||
359 | |||
360 | r = amdgpu_vce_get_destroy_msg(ring, handle, false, NULL); | 373 | r = amdgpu_vce_get_destroy_msg(ring, handle, false, NULL); |
361 | if (r) | 374 | if (r) |
362 | DRM_ERROR("Error destroying VCE handle (%d)!\n", r); | 375 | DRM_ERROR("Error destroying VCE handle (%d)!\n", r); |
@@ -622,8 +635,6 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx) | |||
622 | uint32_t *size = &tmp; | 635 | uint32_t *size = &tmp; |
623 | int i, r = 0, idx = 0; | 636 | int i, r = 0, idx = 0; |
624 | 637 | ||
625 | amdgpu_vce_note_usage(p->adev); | ||
626 | |||
627 | while (idx < ib->length_dw) { | 638 | while (idx < ib->length_dw) { |
628 | uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); | 639 | uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx); |
629 | uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1); | 640 | uint32_t cmd = amdgpu_get_ib_value(p, ib_idx, idx + 1); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index f40cf761c66f..fe84b80dbbed 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | |||
@@ -40,5 +40,7 @@ void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq, | |||
40 | unsigned flags); | 40 | unsigned flags); |
41 | int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); | 41 | int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); |
42 | int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring); | 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 | #endif | 46 | #endif |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index 45d92aceb485..80a37a602181 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | |||
@@ -594,6 +594,8 @@ static const struct amdgpu_ring_funcs vce_v2_0_ring_funcs = { | |||
594 | .test_ib = amdgpu_vce_ring_test_ib, | 594 | .test_ib = amdgpu_vce_ring_test_ib, |
595 | .insert_nop = amdgpu_ring_insert_nop, | 595 | .insert_nop = amdgpu_ring_insert_nop, |
596 | .pad_ib = amdgpu_ring_generic_pad_ib, | 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 | static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev) | 601 | static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev) |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 800c10bcb6cd..c271abffd8dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | |||
@@ -767,6 +767,8 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = { | |||
767 | .test_ib = amdgpu_vce_ring_test_ib, | 767 | .test_ib = amdgpu_vce_ring_test_ib, |
768 | .insert_nop = amdgpu_ring_insert_nop, | 768 | .insert_nop = amdgpu_ring_insert_nop, |
769 | .pad_ib = amdgpu_ring_generic_pad_ib, | 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 | static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) | 774 | static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) |