From: Christian König <christian.koe...@amd.com>

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

Signed-off-by: Christian König <christian.koe...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h     |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 37 +++++++++++++++++++++------------
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h |  2 ++
 drivers/gpu/drm/amd/amdgpu/vce_v2_0.c   |  2 ++
 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 a086547..f724a87 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1708,6 +1708,7 @@ struct amdgpu_vce {
        struct drm_file         *filp[AMDGPU_MAX_VCE_HANDLES];
        uint32_t                img_size[AMDGPU_MAX_VCE_HANDLES];
        struct delayed_work     idle_work;
+       struct mutex            idle_mutex;
        const struct firmware   *fw;    /* VCE firmware */
        struct amdgpu_ring      ring[AMDGPU_MAX_VCE_RINGS];
        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 aeeeb72..6b49d40 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)
        unsigned ucode_version, version_major, version_minor, binary_id;
        int i, r;
 
-       INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler);
-
        switch (adev->asic_type) {
 #ifdef CONFIG_DRM_AMDGPU_CIK
        case CHIP_BONAIRE:
@@ -197,6 +195,9 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned 
long size)
                adev->vce.filp[i] = NULL;
        }
 
+       INIT_DELAYED_WORK(&adev->vce.idle_work, amdgpu_vce_idle_work_handler);
+       mutex_init(&adev->vce.idle_mutex);
+
        return 0;
 }
 
@@ -220,6 +221,7 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev)
        amdgpu_ring_fini(&adev->vce.ring[1]);
 
        release_firmware(adev->vce.fw);
+       mutex_destroy(&adev->vce.idle_mutex);
 
        return 0;
 }
@@ -315,19 +317,19 @@ static void amdgpu_vce_idle_work_handler(struct 
work_struct *work)
 }
 
 /**
- * amdgpu_vce_note_usage - power up VCE
+ * amdgpu_vce_ring_begin_use - power up VCE
  *
- * @adev: amdgpu_device pointer
+ * @ring: amdgpu ring
  *
  * Make sure VCE is powerd up when we want to use it
  */
-static void amdgpu_vce_note_usage(struct amdgpu_device *adev)
+void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring)
 {
-       bool set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work);
-
-       set_clocks &= schedule_delayed_work(&adev->vce.idle_work,
-                                           VCE_IDLE_TIMEOUT);
+       struct amdgpu_device *adev = ring->adev;
+       bool set_clocks;
 
+       mutex_lock(&adev->vce.idle_mutex);
+       set_clocks = !cancel_delayed_work_sync(&adev->vce.idle_work);
        if (set_clocks) {
                if (adev->pm.dpm_enabled) {
                        amdgpu_dpm_enable_vce(adev, true);
@@ -335,6 +337,19 @@ static void amdgpu_vce_note_usage(struct amdgpu_device 
*adev)
                        amdgpu_asic_set_vce_clocks(adev, 53300, 40000);
                }
        }
+       mutex_unlock(&adev->vce.idle_mutex);
+}
+
+/**
+ * amdgpu_vce_ring_end_use - power VCE down
+ *
+ * @ring: amdgpu ring
+ *
+ * Schedule work to power VCE down again
+ */
+void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring)
+{
+       schedule_delayed_work(&ring->adev->vce.idle_work, VCE_IDLE_TIMEOUT);
 }
 
 /**
@@ -355,8 +370,6 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, 
struct drm_file *filp)
                if (!handle || adev->vce.filp[i] != filp)
                        continue;
 
-               amdgpu_vce_note_usage(adev);
-
                r = amdgpu_vce_get_destroy_msg(ring, handle, false, NULL);
                if (r)
                        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)
        uint32_t *size = &tmp;
        int i, r = 0, idx = 0;
 
-       amdgpu_vce_note_usage(p->adev);
-
        while (idx < ib->length_dw) {
                uint32_t len = amdgpu_get_ib_value(p, ib_idx, idx);
                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 f40cf76..fe84b80 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,
                                unsigned flags);
 int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring);
 int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring);
+void amdgpu_vce_ring_begin_use(struct amdgpu_ring *ring);
+void amdgpu_vce_ring_end_use(struct amdgpu_ring *ring);
 
 #endif
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c 
b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c
index 45d92ac..80a37a6 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 = 
{
        .test_ib = amdgpu_vce_ring_test_ib,
        .insert_nop = amdgpu_ring_insert_nop,
        .pad_ib = amdgpu_ring_generic_pad_ib,
+       .begin_use = amdgpu_vce_ring_begin_use,
+       .end_use = amdgpu_vce_ring_end_use,
 };
 
 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 63d8169..6247513 100644
--- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
@@ -853,6 +853,8 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = 
{
        .test_ib = amdgpu_vce_ring_test_ib,
        .insert_nop = amdgpu_ring_insert_nop,
        .pad_ib = amdgpu_ring_generic_pad_ib,
+       .begin_use = amdgpu_vce_ring_begin_use,
+       .end_use = amdgpu_vce_ring_end_use,
 };
 
 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)
-- 
2.5.0

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to