#ifndef __AMDGPU_DM_ISM_H__
#define __AMDGPU_DM_ISM_H__
#include <linux/workqueue.h>
struct amdgpu_crtc;
struct amdgpu_display_manager;
#define AMDGPU_DM_IDLE_HIST_LEN 16
enum amdgpu_dm_ism_state {
DM_ISM_STATE_FULL_POWER_RUNNING,
DM_ISM_STATE_FULL_POWER_BUSY,
DM_ISM_STATE_HYSTERESIS_WAITING,
DM_ISM_STATE_HYSTERESIS_BUSY,
DM_ISM_STATE_OPTIMIZED_IDLE,
DM_ISM_STATE_OPTIMIZED_IDLE_SSO,
DM_ISM_STATE_TIMER_ABORTED,
DM_ISM_NUM_STATES,
};
enum amdgpu_dm_ism_event {
DM_ISM_EVENT_IMMEDIATE,
DM_ISM_EVENT_ENTER_IDLE_REQUESTED,
DM_ISM_EVENT_EXIT_IDLE_REQUESTED,
DM_ISM_EVENT_BEGIN_CURSOR_UPDATE,
DM_ISM_EVENT_END_CURSOR_UPDATE,
DM_ISM_EVENT_TIMER_ELAPSED,
DM_ISM_EVENT_SSO_TIMER_ELAPSED,
DM_ISM_NUM_EVENTS,
};
#define STATE_EVENT(state, event) (((state) << 8) | (event))
struct amdgpu_dm_ism_config {
unsigned int filter_num_frames;
unsigned int filter_history_size;
unsigned int filter_entry_count;
unsigned int activation_num_delay_frames;
unsigned int filter_old_history_threshold;
unsigned int sso_num_frames;
};
struct amdgpu_dm_ism_record {
unsigned long long timestamp_ns;
unsigned long long duration_ns;
};
struct amdgpu_dm_ism {
struct amdgpu_dm_ism_config config;
unsigned long long last_idle_timestamp_ns;
enum amdgpu_dm_ism_state current_state;
enum amdgpu_dm_ism_state previous_state;
struct amdgpu_dm_ism_record records[AMDGPU_DM_IDLE_HIST_LEN];
int next_record_idx;
struct delayed_work delayed_work;
struct delayed_work sso_delayed_work;
};
#define ism_to_amdgpu_crtc(ism_ptr) \
container_of(ism_ptr, struct amdgpu_crtc, ism)
void amdgpu_dm_ism_init(struct amdgpu_dm_ism *ism,
struct amdgpu_dm_ism_config *config);
void amdgpu_dm_ism_fini(struct amdgpu_dm_ism *ism);
void amdgpu_dm_ism_commit_event(struct amdgpu_dm_ism *ism,
enum amdgpu_dm_ism_event event);
void amdgpu_dm_ism_disable(struct amdgpu_display_manager *dm);
void amdgpu_dm_ism_force_full_power(struct amdgpu_display_manager *dm);
void amdgpu_dm_ism_enable(struct amdgpu_display_manager *dm);
#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
bool dm_ism_next_state(enum amdgpu_dm_ism_state current_state,
enum amdgpu_dm_ism_event event,
enum amdgpu_dm_ism_state *next_state);
uint64_t dm_ism_get_sso_delay(const struct amdgpu_dm_ism *ism,
const struct dc_stream_state *stream);
uint64_t dm_ism_get_idle_allow_delay(const struct amdgpu_dm_ism *ism,
const struct dc_stream_state *stream);
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