From: Alex Hung Date: Fri, 15 May 2026 19:27:56 +0000 (-0600) Subject: drm/amd/display: Extract dm_ism_dispatch_next_event X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f84c48048b491941af8caaa65d4260123cab7257;p=thirdparty%2Flinux.git drm/amd/display: Extract dm_ism_dispatch_next_event [Why & How] Separate the "should we emit IMMEDIATE?" decision into a pure, side-effect-free helper so it can be tested in isolation without a full DRM context. - dm_ism_dispatch_next_event(current_state, delay_ns, sso_delay_ns) returns DM_ISM_EVENT_IMMEDIATE when the state requires an immediate follow-up (HYSTERESIS_WAITING with zero delay, OPTIMIZED_IDLE with zero SSO delay, or TIMER_ABORTED), and DM_ISM_NUM_EVENTS otherwise. - Removes the passthrough event parameter that was always DM_ISM_NUM_EVENTS at the call site, making the sentinel explicit. - Drops the now-unused event parameter from dm_ism_dispatch_power_state. Assisted-by: Copilot:Claude-Sonnet-4.6 Reviewed-by: Ray Wu Signed-off-by: Alex Hung Signed-off-by: Ray Wu Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c index 0a010802540d6..5c08417286719 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.c @@ -332,15 +332,36 @@ static void dm_ism_commit_idle_optimization_state(struct amdgpu_dm_ism *ism, } } +STATIC_IFN_KUNIT +enum amdgpu_dm_ism_event dm_ism_dispatch_next_event( + enum amdgpu_dm_ism_state current_state, + uint64_t delay_ns, + uint64_t sso_delay_ns) +{ + switch (current_state) { + case DM_ISM_STATE_HYSTERESIS_WAITING: + if (delay_ns == 0) + return DM_ISM_EVENT_IMMEDIATE; + break; + case DM_ISM_STATE_OPTIMIZED_IDLE: + if (sso_delay_ns == 0) + return DM_ISM_EVENT_IMMEDIATE; + break; + case DM_ISM_STATE_TIMER_ABORTED: + return DM_ISM_EVENT_IMMEDIATE; + default: + break; + } + return DM_ISM_NUM_EVENTS; +} +EXPORT_IF_KUNIT(dm_ism_dispatch_next_event); static enum amdgpu_dm_ism_event dm_ism_dispatch_power_state( struct amdgpu_dm_ism *ism, - struct dm_crtc_state *acrtc_state, - enum amdgpu_dm_ism_event event) + struct dm_crtc_state *acrtc_state) { - enum amdgpu_dm_ism_event ret = event; const struct amdgpu_dm_ism_config *config = &ism->config; - uint64_t delay_ns, sso_delay_ns; + uint64_t delay_ns = 0, sso_delay_ns = 0; switch (ism->previous_state) { case DM_ISM_STATE_HYSTERESIS_WAITING: @@ -374,30 +395,15 @@ static enum amdgpu_dm_ism_event dm_ism_dispatch_power_state( switch (ism->current_state) { case DM_ISM_STATE_HYSTERESIS_WAITING: dm_ism_set_last_idle_ts(ism); - - /* CRTC can be disabled; allow immediate idle */ - if (!acrtc_state->stream) { - ret = DM_ISM_EVENT_IMMEDIATE; - break; - } - - delay_ns = dm_ism_get_idle_allow_delay(ism, - acrtc_state->stream); - if (delay_ns == 0) { - ret = DM_ISM_EVENT_IMMEDIATE; - break; - } - + delay_ns = dm_ism_get_idle_allow_delay(ism, acrtc_state->stream); /* Schedule worker */ - mod_delayed_work(system_dfl_wq, &ism->delayed_work, - nsecs_to_jiffies(delay_ns)); - + if (delay_ns > 0) + mod_delayed_work(system_dfl_wq, &ism->delayed_work, + nsecs_to_jiffies(delay_ns)); break; case DM_ISM_STATE_OPTIMIZED_IDLE: sso_delay_ns = dm_ism_get_sso_delay(ism, acrtc_state->stream); - if (sso_delay_ns == 0) - ret = DM_ISM_EVENT_IMMEDIATE; - else if (config->sso_num_frames < config->filter_num_frames) { + if (sso_delay_ns > 0) { /* * If sso_num_frames is less than hysteresis frames, it * indicates that allowing idle here, then disallowing @@ -405,13 +411,10 @@ static enum amdgpu_dm_ism_event dm_ism_dispatch_power_state( * have a negative power impact. Skip idle allow here, * and let the sso_delayed_work handle it. */ - mod_delayed_work(system_dfl_wq, - &ism->sso_delayed_work, - nsecs_to_jiffies(sso_delay_ns)); - } else { - /* Enable idle optimization without SSO */ - dm_ism_commit_idle_optimization_state( - ism, acrtc_state->stream, false, false); + if (config->sso_num_frames >= config->filter_num_frames) + dm_ism_commit_idle_optimization_state(ism, acrtc_state->stream, + false, false); + mod_delayed_work(system_dfl_wq, &ism->sso_delayed_work, nsecs_to_jiffies(sso_delay_ns)); @@ -426,13 +429,12 @@ static enum amdgpu_dm_ism_event dm_ism_dispatch_power_state( dm_ism_insert_record(ism); dm_ism_commit_idle_optimization_state(ism, acrtc_state->stream, true, false); - ret = DM_ISM_EVENT_IMMEDIATE; break; default: break; } - return ret; + return dm_ism_dispatch_next_event(ism->current_state, delay_ns, sso_delay_ns); } static char *dm_ism_events_str[DM_ISM_NUM_EVENTS] = { @@ -487,8 +489,7 @@ void amdgpu_dm_ism_commit_event(struct amdgpu_dm_ism *ism, dm_ism_states_str[ism->previous_state], dm_ism_states_str[ism->current_state], dm_ism_events_str[event]); - next_event = dm_ism_dispatch_power_state( - ism, acrtc_state, next_event); + next_event = dm_ism_dispatch_power_state(ism, acrtc_state); } else { trace_amdgpu_dm_ism_event( acrtc->crtc_id, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.h index da3e192e8d25f..afce16f7085a9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_ism.h @@ -161,6 +161,9 @@ void dm_ism_insert_record(struct amdgpu_dm_ism *ism); void dm_ism_set_last_idle_ts(struct amdgpu_dm_ism *ism); bool dm_ism_trigger_event(struct amdgpu_dm_ism *ism, enum amdgpu_dm_ism_event event); +enum amdgpu_dm_ism_event dm_ism_dispatch_next_event(enum amdgpu_dm_ism_state current_state, + uint64_t delay_ns, + uint64_t sso_delay_ns); #endif #endif