mirror of https://gitee.com/openkylin/linux.git
drm/amdgpu: Put enable gfx off feature to a delay thread
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>
This commit is contained in:
parent
d23ee13fba
commit
1e317b99f0
|
@ -954,6 +954,8 @@ struct amdgpu_gfx {
|
||||||
bool gfx_off_state; /* true: enabled, false: disabled */
|
bool gfx_off_state; /* true: enabled, false: disabled */
|
||||||
struct mutex gfx_off_mutex;
|
struct mutex gfx_off_mutex;
|
||||||
uint32_t gfx_off_req_count; /* default 1, enable gfx off: dec 1, disable gfx off: add 1 */
|
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 */
|
/* pipe reservation */
|
||||||
struct mutex pipe_reserve_mutex;
|
struct mutex pipe_reserve_mutex;
|
||||||
DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
|
DECLARE_BITMAP (pipe_reserve_bitmap, AMDGPU_MAX_COMPUTE_QUEUES);
|
||||||
|
|
|
@ -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);
|
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)
|
* 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,
|
INIT_DELAYED_WORK(&adev->late_init_work,
|
||||||
amdgpu_device_ip_late_init_func_handler);
|
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->gfx.gfx_off_req_count = 1;
|
||||||
adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false;
|
adev->pm.ac_power = power_supply_is_system_supplied() > 0 ? true : false;
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
#include "amdgpu.h"
|
#include "amdgpu.h"
|
||||||
#include "amdgpu_gfx.h"
|
#include "amdgpu_gfx.h"
|
||||||
|
|
||||||
|
/* 0.5 second timeout */
|
||||||
|
#define GFX_OFF_DELAY_ENABLE msecs_to_jiffies(500)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPU scratch registers helpers function.
|
* 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)
|
if (!adev->powerplay.pp_funcs->set_powergating_by_smu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
mutex_lock(&adev->gfx.gfx_off_mutex);
|
mutex_lock(&adev->gfx.gfx_off_mutex);
|
||||||
|
|
||||||
if (!enable)
|
if (!enable)
|
||||||
|
@ -368,11 +372,11 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable)
|
||||||
adev->gfx.gfx_off_req_count--;
|
adev->gfx.gfx_off_req_count--;
|
||||||
|
|
||||||
if (enable && !adev->gfx.gfx_off_state && !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))
|
schedule_delayed_work(&adev->gfx.gfx_off_delay_work, GFX_OFF_DELAY_ENABLE);
|
||||||
adev->gfx.gfx_off_state = true;
|
|
||||||
} else if (!enable && adev->gfx.gfx_off_state) {
|
} else if (!enable && adev->gfx.gfx_off_state) {
|
||||||
if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false))
|
if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, false))
|
||||||
adev->gfx.gfx_off_state = false;
|
adev->gfx.gfx_off_state = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
mutex_unlock(&adev->gfx.gfx_off_mutex);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue