aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-07-20 10:53:36 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-07-29 14:37:03 -0400
commitebff485e9314f8c53f6b22eba0dfbec7228ab268 (patch)
treebfe32720f5ef21855af1db8274142491716959ba
parentc4120d55ffa44746584a8a1e5b00cb7eafc006ff (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.h1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c37
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v2_0.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/vce_v3_0.c2
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 */
324static void amdgpu_vce_note_usage(struct amdgpu_device *adev) 326void 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 */
350void 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);
41int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring); 41int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring);
42int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring); 42int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring);
43void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring);
44void 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
599static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev) 601static 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
772static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev) 774static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)