mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
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 <ray.wu@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Ray Wu <ray.wu@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
a3142b13fe
commit
f84c48048b
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user