drm/amdgpu: Put enable gfx off feature to a delay thread
authorRex Zhu <Rex.Zhu@amd.com>
Fri, 27 Jul 2018 13:06:30 +0000 (21:06 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 27 Aug 2018 16:09:52 +0000 (11:09 -0500)
delay to enable gfx off feature to avoid gfx on/off frequently
suggested by Alex and Evan.

Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c

index 47fbe8f..6a8ed9b 100644 (file)
@@ -954,6 +954,8 @@ struct amdgpu_gfx {
        bool                            gfx_off_state; /* true: enabled, false: disabled */
        struct mutex                    gfx_off_mutex;
        uint32_t                        gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
+       struct delayed_work             gfx_off_delay_work;
+
        /* pipe reservation */
        struct mutex                    pipe_reserve_mutex;
        DECLARE_BITMAP                  (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
index 2068b7f..82bc329 100644 (file)
@@ -1925,6 +1925,19 @@ static void amdgpu_device_ip_late_init_func_handler(struct work_struct *work)
                DRM_ERROR("ib ring test failed (%d).\n", r);
 }
 
+static void amdgpu_device_delay_enable_gfx_off(struct work_struct *work)
+{
+       struct amdgpu_device *adev =
+               container_of(work, struct amdgpu_device, gfx.gfx_off_delay_work.work);
+
+       mutex_lock(&adev->gfx.gfx_off_mutex);
+       if (!adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) {
+               if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true))
+                       adev->gfx.gfx_off_state = true;
+       }
+       mutex_unlock(&adev->gfx.gfx_off_mutex);
+}
+
 /**
  * amdgpu_device_ip_suspend_phase1 - run suspend for hardware IPs (phase 1)
  *
@@ -2394,6 +2407,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
 
        INIT_DELAYED_WORK(&adev->late_init_work,
                          amdgpu_device_ip_late_init_func_handler);
+       INIT_DELAYED_WORK(&adev->gfx.gfx_off_delay_work,
+                         amdgpu_device_delay_enable_gfx_off);
 
        adev->gfx.gfx_off_req_count = 1;
        adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false;
index 1cdb264..11d4d9f 100644 (file)
@@ -26,6 +26,9 @@
 #include "amdgpu.h"
 #include "amdgpu_gfx.h"
 
+/* 0.5 second timeout */
+#define GFX_OFF_DELAY_ENABLE         msecs_to_jiffies(500)
+
 /*
  * GPU scratch registers helpers function.
  */
@@ -360,6 +363,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
        if (!adev->powerplay.pp_funcs->set_powergating_by_smu)
                return;
 
+
        mutex_lock(&adev->gfx.gfx_off_mutex);
 
        if (!enable)
@@ -368,11 +372,11 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
                adev->gfx.gfx_off_req_count--;
 
        if (enable && !adev->gfx.gfx_off_state && !adev->gfx.gfx_off_req_count) {
-               if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true))
-                       adev->gfx.gfx_off_state = true;
+               schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
        } else if (!enable && adev->gfx.gfx_off_state) {
                if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false))
                        adev->gfx.gfx_off_state = false;
        }
+
        mutex_unlock(&adev->gfx.gfx_off_mutex);
 }