From 8fdb3958e3965fcd11408e1cd5380895cdc96e06 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 8 Jan 2025 17:15:56 -0500 Subject: drm/amdgpu/gfx: add ring helpers for setting workload profile Add helpers to switch the workload profile dynamically when commands are submitted. This allows us to switch to the FULLSCREEN3D or COMPUTE profile when work is submitted. Add a delayed work handler to delay switching out of the selected profile if additional work comes in. This works the same as the VIDEO profile for VCN. This lets dynamically enable workload profiles on the fly and then move back to the default when there is no work. Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 57 +++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 784b03abb3a4..645efe002d06 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -2118,6 +2118,63 @@ void amdgpu_gfx_enforce_isolation_ring_end_use(struct amdgpu_ring *ring) amdgpu_gfx_kfd_sch_ctrl(adev, idx, true); } +void amdgpu_gfx_profile_idle_work_handler(struct work_struct *work) +{ + struct amdgpu_device *adev = + container_of(work, struct amdgpu_device, gfx.idle_work.work); + enum PP_SMC_POWER_PROFILE profile; + u32 i, fences = 0; + int r; + + if (adev->gfx.num_gfx_rings) + profile = PP_SMC_POWER_PROFILE_FULLSCREEN3D; + else + profile = PP_SMC_POWER_PROFILE_COMPUTE; + + for (i = 0; i < AMDGPU_MAX_GFX_RINGS; ++i) + fences += amdgpu_fence_count_emitted(&adev->gfx.gfx_ring[i]); + for (i = 0; i < (AMDGPU_MAX_COMPUTE_RINGS * AMDGPU_MAX_GC_INSTANCES); ++i) + fences += amdgpu_fence_count_emitted(&adev->gfx.compute_ring[i]); + if (!fences && !atomic_read(&adev->gfx.total_submission_cnt)) { + r = amdgpu_dpm_switch_power_profile(adev, profile, false); + if (r) + dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r, + profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? + "fullscreen 3D" : "compute"); + } else { + schedule_delayed_work(&adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT); + } +} + +void amdgpu_gfx_profile_ring_begin_use(struct amdgpu_ring *ring) +{ + struct amdgpu_device *adev = ring->adev; + enum PP_SMC_POWER_PROFILE profile; + int r; + + if (adev->gfx.num_gfx_rings) + profile = PP_SMC_POWER_PROFILE_FULLSCREEN3D; + else + profile = PP_SMC_POWER_PROFILE_COMPUTE; + + atomic_inc(&adev->gfx.total_submission_cnt); + + if (!cancel_delayed_work_sync(&adev->gfx.idle_work)) { + r = amdgpu_dpm_switch_power_profile(adev, profile, true); + if (r) + dev_warn(adev->dev, "(%d) failed to disable %s power profile mode\n", r, + profile == PP_SMC_POWER_PROFILE_FULLSCREEN3D ? + "fullscreen 3D" : "compute"); + } +} + +void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring) +{ + atomic_dec(&ring->adev->gfx.total_submission_cnt); + + schedule_delayed_work(&ring->adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT); +} + /* * debugfs for to enable/disable gfx job submission to specific core. */ -- cgit v1.2.3 From 250d9769eeee6cfebbafaca3e4f34a907b5b166f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 30 Jan 2025 21:20:57 -0500 Subject: drm/amdgpu/gfx: add amdgpu_gfx_off_ctrl_immediate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same as amdgpu_gfx_off_ctrl(), but without the delay for gfxoff disallow. Reviewed-by: Lijo Lazar Suggested-by: Błażej Szczygieł Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 53 +++++++++++++++++++++++++-------- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 1 + 2 files changed, 41 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 645efe002d06..27f5318c3a26 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -771,18 +771,8 @@ int amdgpu_gfx_enable_kgq(struct amdgpu_device *adev, int xcc_id) return r; } -/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable - * - * @adev: amdgpu_device pointer - * @bool enable true: enable gfx off feature, false: disable gfx off feature - * - * 1. gfx off feature will be enabled by gfx ip after gfx cg gp enabled. - * 2. other client can send request to disable gfx off feature, the request should be honored. - * 3. other client can cancel their request of disable gfx off feature - * 4. other client should not send request to enable gfx off feature before disable gfx off feature. - */ - -void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) +static void amdgpu_gfx_do_off_ctrl(struct amdgpu_device *adev, bool enable, + bool no_delay) { unsigned long delay = GFX_OFF_DELAY_ENABLE; @@ -804,7 +794,7 @@ void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) if (adev->gfx.gfx_off_req_count == 0 && !adev->gfx.gfx_off_state) { /* If going to s2idle, no need to wait */ - if (adev->in_s0ix) { + if (no_delay) { if (!amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_GFX, true, 0)) adev->gfx.gfx_off_state = true; @@ -836,6 +826,43 @@ unlock: mutex_unlock(&adev->gfx.gfx_off_mutex); } +/* amdgpu_gfx_off_ctrl - Handle gfx off feature enable/disable + * + * @adev: amdgpu_device pointer + * @bool enable true: enable gfx off feature, false: disable gfx off feature + * + * 1. gfx off feature will be enabled by gfx ip after gfx cg pg enabled. + * 2. other client can send request to disable gfx off feature, the request should be honored. + * 3. other client can cancel their request of disable gfx off feature + * 4. other client should not send request to enable gfx off feature before disable gfx off feature. + * + * gfx off allow will be delayed by GFX_OFF_DELAY_ENABLE ms. + */ +void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable) +{ + /* If going to s2idle, no need to wait */ + bool no_delay = adev->in_s0ix ? true : false; + + amdgpu_gfx_do_off_ctrl(adev, enable, no_delay); +} + +/* amdgpu_gfx_off_ctrl_immediate - Handle gfx off feature enable/disable + * + * @adev: amdgpu_device pointer + * @bool enable true: enable gfx off feature, false: disable gfx off feature + * + * 1. gfx off feature will be enabled by gfx ip after gfx cg pg enabled. + * 2. other client can send request to disable gfx off feature, the request should be honored. + * 3. other client can cancel their request of disable gfx off feature + * 4. other client should not send request to enable gfx off feature before disable gfx off feature. + * + * gfx off allow will be issued immediately. + */ +void amdgpu_gfx_off_ctrl_immediate(struct amdgpu_device *adev, bool enable) +{ + amdgpu_gfx_do_off_ctrl(adev, enable, true); +} + int amdgpu_set_gfx_off_residency(struct amdgpu_device *adev, bool value) { int r = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index 49ff91de14b2..4b1675f79caa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h @@ -553,6 +553,7 @@ int amdgpu_gfx_me_queue_to_bit(struct amdgpu_device *adev, int me, bool amdgpu_gfx_is_me_queue_enabled(struct amdgpu_device *adev, int me, int pipe, int queue); void amdgpu_gfx_off_ctrl(struct amdgpu_device *adev, bool enable); +void amdgpu_gfx_off_ctrl_immediate(struct amdgpu_device *adev, bool enable); int amdgpu_get_gfx_off_status(struct amdgpu_device *adev, uint32_t *value); int amdgpu_gfx_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block); void amdgpu_gfx_ras_fini(struct amdgpu_device *adev); -- cgit v1.2.3 From 80513e389765c8f9543b26d8fa4bbdf0e59ff8bc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 13 Feb 2025 13:37:01 -0500 Subject: drm/amdgpu/gfx: only call mes for enforce isolation if supported This should not be called on chips without MES so check if MES is enabled and if the cleaner shader is supported. Fixes: 8521e3c5f058 ("drm/amd/amdgpu: limit single process inside MES") Reviewed-by: Srinivasan Shanmugam Signed-off-by: Alex Deucher Cc: Shaoyun Liu Cc: Srinivasan Shanmugam --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 27f5318c3a26..b9bd6654f317 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -1670,11 +1670,13 @@ static ssize_t amdgpu_gfx_set_enforce_isolation(struct device *dev, if (adev->enforce_isolation[i] && !partition_values[i]) { /* Going from enabled to disabled */ amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(i)); - amdgpu_mes_set_enforce_isolation(adev, i, false); + if (adev->enable_mes && adev->gfx.enable_cleaner_shader) + amdgpu_mes_set_enforce_isolation(adev, i, false); } else if (!adev->enforce_isolation[i] && partition_values[i]) { /* Going from disabled to enabled */ amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(i)); - amdgpu_mes_set_enforce_isolation(adev, i, true); + if (adev->enable_mes && adev->gfx.enable_cleaner_shader) + amdgpu_mes_set_enforce_isolation(adev, i, true); } adev->enforce_isolation[i] = partition_values[i]; } -- cgit v1.2.3