aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_uvd.c30
3 files changed, 34 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 5020c7c9b7cb..7935370f01af 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1143,6 +1143,7 @@ struct radeon_uvd {
1143 uint64_t gpu_addr; 1143 uint64_t gpu_addr;
1144 atomic_t handles[RADEON_MAX_UVD_HANDLES]; 1144 atomic_t handles[RADEON_MAX_UVD_HANDLES];
1145 struct drm_file *filp[RADEON_MAX_UVD_HANDLES]; 1145 struct drm_file *filp[RADEON_MAX_UVD_HANDLES];
1146 struct delayed_work idle_work;
1146}; 1147};
1147 1148
1148int radeon_uvd_init(struct radeon_device *rdev); 1149int radeon_uvd_init(struct radeon_device *rdev);
@@ -1157,6 +1158,7 @@ void radeon_uvd_force_into_uvd_segment(struct radeon_bo *rbo);
1157void radeon_uvd_free_handles(struct radeon_device *rdev, 1158void radeon_uvd_free_handles(struct radeon_device *rdev,
1158 struct drm_file *filp); 1159 struct drm_file *filp);
1159int radeon_uvd_cs_parse(struct radeon_cs_parser *parser); 1160int radeon_uvd_cs_parse(struct radeon_cs_parser *parser);
1161void radeon_uvd_note_usage(struct radeon_device *rdev);
1160 1162
1161struct r600_audio { 1163struct r600_audio {
1162 int channels; 1164 int channels;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index c7407074c09b..7e265a58141f 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -549,6 +549,10 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
549 r = radeon_cs_handle_lockup(rdev, r); 549 r = radeon_cs_handle_lockup(rdev, r);
550 return r; 550 return r;
551 } 551 }
552
553 if (parser.ring == R600_RING_TYPE_UVD_INDEX)
554 radeon_uvd_note_usage(rdev);
555
552 r = radeon_cs_ib_chunk(rdev, &parser); 556 r = radeon_cs_ib_chunk(rdev, &parser);
553 if (r) { 557 if (r) {
554 goto out; 558 goto out;
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c
index 15580fb8546e..0312a7f4d768 100644
--- a/drivers/gpu/drm/radeon/radeon_uvd.c
+++ b/drivers/gpu/drm/radeon/radeon_uvd.c
@@ -36,6 +36,9 @@
36#include "radeon.h" 36#include "radeon.h"
37#include "r600d.h" 37#include "r600d.h"
38 38
39/* 1 second timeout */
40#define UVD_IDLE_TIMEOUT_MS 1000
41
39/* Firmware Names */ 42/* Firmware Names */
40#define FIRMWARE_RV710 "radeon/RV710_uvd.bin" 43#define FIRMWARE_RV710 "radeon/RV710_uvd.bin"
41#define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin" 44#define FIRMWARE_CYPRESS "radeon/CYPRESS_uvd.bin"
@@ -47,6 +50,8 @@ MODULE_FIRMWARE(FIRMWARE_CYPRESS);
47MODULE_FIRMWARE(FIRMWARE_SUMO); 50MODULE_FIRMWARE(FIRMWARE_SUMO);
48MODULE_FIRMWARE(FIRMWARE_TAHITI); 51MODULE_FIRMWARE(FIRMWARE_TAHITI);
49 52
53static void radeon_uvd_idle_work_handler(struct work_struct *work);
54
50int radeon_uvd_init(struct radeon_device *rdev) 55int radeon_uvd_init(struct radeon_device *rdev)
51{ 56{
52 struct platform_device *pdev; 57 struct platform_device *pdev;
@@ -54,6 +59,8 @@ int radeon_uvd_init(struct radeon_device *rdev)
54 const char *fw_name; 59 const char *fw_name;
55 int i, r; 60 int i, r;
56 61
62 INIT_DELAYED_WORK(&rdev->uvd.idle_work, radeon_uvd_idle_work_handler);
63
57 pdev = platform_device_register_simple("radeon_uvd", 0, NULL, 0); 64 pdev = platform_device_register_simple("radeon_uvd", 0, NULL, 0);
58 r = IS_ERR(pdev); 65 r = IS_ERR(pdev);
59 if (r) { 66 if (r) {
@@ -188,8 +195,6 @@ int radeon_uvd_resume(struct radeon_device *rdev)
188 195
189 radeon_bo_unreserve(rdev->uvd.vcpu_bo); 196 radeon_bo_unreserve(rdev->uvd.vcpu_bo);
190 197
191 radeon_set_uvd_clocks(rdev, 53300, 40000);
192
193 return 0; 198 return 0;
194} 199}
195 200
@@ -666,3 +671,24 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring,
666 671
667 return radeon_uvd_send_msg(rdev, ring, bo, fence); 672 return radeon_uvd_send_msg(rdev, ring, bo, fence);
668} 673}
674
675static void radeon_uvd_idle_work_handler(struct work_struct *work)
676{
677 struct radeon_device *rdev =
678 container_of(work, struct radeon_device, uvd.idle_work.work);
679
680 if (radeon_fence_count_emitted(rdev, R600_RING_TYPE_UVD_INDEX) == 0)
681 radeon_set_uvd_clocks(rdev, 0, 0);
682 else
683 schedule_delayed_work(&rdev->uvd.idle_work,
684 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
685}
686
687void radeon_uvd_note_usage(struct radeon_device *rdev)
688{
689 bool set_clocks = !cancel_delayed_work_sync(&rdev->uvd.idle_work);
690 set_clocks &= schedule_delayed_work(&rdev->uvd.idle_work,
691 msecs_to_jiffies(UVD_IDLE_TIMEOUT_MS));
692 if (set_clocks)
693 radeon_set_uvd_clocks(rdev, 53300, 40000);
694}