drm/radeon: add UVD->DPM helper function (v5)
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 5 Aug 2013 16:41:20 +0000 (12:41 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 30 Aug 2013 20:29:58 +0000 (16:29 -0400)
Add a helper function for counting the number of open stream handles.

v2: fix copy-pasta in comments and whitespace error
v3: make function static since it's only used in radeon_uvd.c
at the moment
v4: make non-static again for future changes
v5: make static again for new rework of dpm uvd changes

Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_uvd.c

index 83be8fdceab17f529b2a9e78a279a10f2c70b1cf..fc8d03be933c65392dc9e9c33e839d6bfa3a8fd8 100644 (file)
@@ -1441,6 +1441,7 @@ struct radeon_uvd {
        void                    *saved_bo;
        atomic_t                handles[RADEON_MAX_UVD_HANDLES];
        struct drm_file         *filp[RADEON_MAX_UVD_HANDLES];
+       unsigned                img_size[RADEON_MAX_UVD_HANDLES];
        struct delayed_work     idle_work;
 };
 
index b79f4f5cdd626108c8790394cc6e57ddd9b27bce..2a4cff1acf0220c29b39ad33e0af8ec87c4e51a3 100644 (file)
@@ -147,6 +147,7 @@ int radeon_uvd_init(struct radeon_device *rdev)
        for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
                atomic_set(&rdev->uvd.handles[i], 0);
                rdev->uvd.filp[i] = NULL;
+               rdev->uvd.img_size[i] = 0;
        }
 
        return 0;
@@ -347,6 +348,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
                             unsigned offset, unsigned buf_sizes[])
 {
        int32_t *msg, msg_type, handle;
+       unsigned img_size = 0;
        void *ptr;
 
        int i, r;
@@ -383,6 +385,8 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
        if (msg_type == 1) {
                /* it's a decode msg, calc buffer sizes */
                r = radeon_uvd_cs_msg_decode(msg, buf_sizes);
+               /* calc image size (width * height) */
+               img_size = msg[6] * msg[7];
                radeon_bo_kunmap(bo);
                if (r)
                        return r;
@@ -394,6 +398,8 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
                radeon_bo_kunmap(bo);
                return 0;
        } else {
+               /* it's a create msg, calc image size (width * height) */
+               img_size = msg[7] * msg[8];
                radeon_bo_kunmap(bo);
 
                if (msg_type != 0) {
@@ -414,6 +420,7 @@ static int radeon_uvd_cs_msg(struct radeon_cs_parser *p, struct radeon_bo *bo,
        for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
                if (!atomic_cmpxchg(&p->rdev->uvd.handles[i], 0, handle)) {
                        p->rdev->uvd.filp[i] = p->filp;
+                       p->rdev->uvd.img_size[i] = img_size;
                        return 0;
                }
        }
@@ -733,6 +740,34 @@ int radeon_uvd_get_destroy_msg(struct radeon_device *rdev, int ring,
        return radeon_uvd_send_msg(rdev, ring, bo, fence);
 }
 
+/**
+ * radeon_uvd_count_handles - count number of open streams
+ *
+ * @rdev: radeon_device pointer
+ * @sd: number of SD streams
+ * @hd: number of HD streams
+ *
+ * Count the number of open SD/HD streams as a hint for power mangement
+ */
+static void radeon_uvd_count_handles(struct radeon_device *rdev,
+                                    unsigned *sd, unsigned *hd)
+{
+       unsigned i;
+
+       *sd = 0;
+       *hd = 0;
+
+       for (i = 0; i < RADEON_MAX_UVD_HANDLES; ++i) {
+               if (!atomic_read(&rdev->uvd.handles[i]))
+                       continue;
+
+               if (rdev->uvd.img_size[i] >= 720*576)
+                       ++(*hd);
+               else
+                       ++(*sd);
+       }
+}
+
 static void radeon_uvd_idle_work_handler(struct work_struct *work)
 {
        struct radeon_device *rdev =