| 1 |
|
| 2 | |
| 3 | * Copyright 2026 Advanced Micro Devices, Inc.
|
| 4 | *
|
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a
|
| 6 | * copy of this software and associated documentation files (the "Software"),
|
| 7 | * to deal in the Software without restriction, including without limitation
|
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
| 9 | * and/or sell copies of the Software, and to permit persons to whom the
|
| 10 | * Software is furnished to do so, subject to the following conditions:
|
| 11 | *
|
| 12 | * The above copyright notice and this permission notice shall be included in
|
| 13 | * all copies or substantial portions of the Software.
|
| 14 | *
|
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
| 18 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
| 19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
| 20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
| 21 | * OTHER DEALINGS IN THE SOFTWARE.
|
| 22 | *
|
| 23 | * Authors: AMD
|
| 24 | *
|
| 25 |
|
| 26 |
|
| 27 | #ifndef __AMDGPU_DM_ISM_H__
|
| 28 | #define __AMDGPU_DM_ISM_H__
|
| 29 |
|
| 30 | #include <linux/workqueue.h>
|
| 31 |
|
| 32 | struct amdgpu_crtc;
|
| 33 | struct amdgpu_display_manager;
|
| 34 |
|
| 35 | #define AMDGPU_DM_IDLE_HIST_LEN 16
|
| 36 |
|
| 37 | enum amdgpu_dm_ism_state {
|
| 38 | DM_ISM_STATE_FULL_POWER_RUNNING,
|
| 39 | DM_ISM_STATE_FULL_POWER_BUSY,
|
| 40 | DM_ISM_STATE_HYSTERESIS_WAITING,
|
| 41 | DM_ISM_STATE_HYSTERESIS_BUSY,
|
| 42 | DM_ISM_STATE_OPTIMIZED_IDLE,
|
| 43 | DM_ISM_STATE_OPTIMIZED_IDLE_SSO,
|
| 44 | DM_ISM_STATE_TIMER_ABORTED,
|
| 45 | DM_ISM_NUM_STATES,
|
| 46 | };
|
| 47 |
|
| 48 | enum amdgpu_dm_ism_event {
|
| 49 | DM_ISM_EVENT_IMMEDIATE,
|
| 50 | DM_ISM_EVENT_ENTER_IDLE_REQUESTED,
|
| 51 | DM_ISM_EVENT_EXIT_IDLE_REQUESTED,
|
| 52 | DM_ISM_EVENT_BEGIN_CURSOR_UPDATE,
|
| 53 | DM_ISM_EVENT_END_CURSOR_UPDATE,
|
| 54 | DM_ISM_EVENT_TIMER_ELAPSED,
|
| 55 | DM_ISM_EVENT_SSO_TIMER_ELAPSED,
|
| 56 | DM_ISM_NUM_EVENTS,
|
| 57 | };
|
| 58 |
|
| 59 | #define STATE_EVENT(state, event) (((state) << 8) | (event))
|
| 60 |
|
| 61 | struct amdgpu_dm_ism_config {
|
| 62 |
|
| 63 | |
| 64 | * @filter_num_frames: Idle periods shorter than this number of frames
|
| 65 | * will be considered a "short idle period" for filtering.
|
| 66 | *
|
| 67 | * 0 indicates no filtering (i.e. no idle allow delay will be applied)
|
| 68 |
|
| 69 | unsigned int filter_num_frames;
|
| 70 |
|
| 71 | |
| 72 | * @filter_history_size: Number of recent idle periods to consider when
|
| 73 | * counting the number of short idle periods.
|
| 74 |
|
| 75 | unsigned int filter_history_size;
|
| 76 |
|
| 77 | |
| 78 | * @filter_entry_count: When the number of short idle periods within
|
| 79 | * recent &filter_history_size reaches this count, the idle allow delay
|
| 80 | * will be applied.
|
| 81 | *
|
| 82 | * 0 indicates no filtering (i.e. no idle allow delay will be applied)
|
| 83 |
|
| 84 | unsigned int filter_entry_count;
|
| 85 |
|
| 86 | |
| 87 | * @activation_num_delay_frames: Defines the number of frames to wait
|
| 88 | * for the idle allow delay.
|
| 89 | *
|
| 90 | * 0 indicates no filtering (i.e. no idle allow delay will be applied)
|
| 91 |
|
| 92 | unsigned int activation_num_delay_frames;
|
| 93 |
|
| 94 | |
| 95 | * @filter_old_history_threshold: A time-based restriction on top of
|
| 96 | * &filter_history_size. Idle periods older than this threshold (in
|
| 97 | * number of frames) will be ignored when counting the number of short
|
| 98 | * idle periods.
|
| 99 | *
|
| 100 | * 0 indicates no time-based restriction, i.e. history is limited only
|
| 101 | * by &filter_history_size.
|
| 102 |
|
| 103 | unsigned int filter_old_history_threshold;
|
| 104 |
|
| 105 | |
| 106 | * @sso_num_frames: Number of frames to delay before enabling static
|
| 107 | * screen optimizations, such as PSR1 and Replay low HZ idle mode.
|
| 108 | *
|
| 109 | * 0 indicates immediate SSO enable upon allowing idle.
|
| 110 |
|
| 111 | unsigned int sso_num_frames;
|
| 112 | };
|
| 113 |
|
| 114 | struct amdgpu_dm_ism_record {
|
| 115 | |
| 116 | * @timestamp_ns: When idle was allowed
|
| 117 |
|
| 118 | unsigned long long timestamp_ns;
|
| 119 |
|
| 120 | |
| 121 | * @duration_ns: How long idle was allowed
|
| 122 |
|
| 123 | unsigned long long duration_ns;
|
| 124 | };
|
| 125 |
|
| 126 | struct amdgpu_dm_ism {
|
| 127 | struct amdgpu_dm_ism_config config;
|
| 128 | unsigned long long last_idle_timestamp_ns;
|
| 129 |
|
| 130 | enum amdgpu_dm_ism_state current_state;
|
| 131 | enum amdgpu_dm_ism_state previous_state;
|
| 132 |
|
| 133 | struct amdgpu_dm_ism_record records[AMDGPU_DM_IDLE_HIST_LEN];
|
| 134 | int next_record_idx;
|
| 135 |
|
| 136 | struct delayed_work delayed_work;
|
| 137 | struct delayed_work sso_delayed_work;
|
| 138 | };
|
| 139 |
|
| 140 | #define ism_to_amdgpu_crtc(ism_ptr) \
|
| 141 | container_of(ism_ptr, struct amdgpu_crtc, ism)
|
| 142 |
|
| 143 | void amdgpu_dm_ism_init(struct amdgpu_dm_ism *ism,
|
| 144 | struct amdgpu_dm_ism_config *config);
|
| 145 | void amdgpu_dm_ism_fini(struct amdgpu_dm_ism *ism);
|
| 146 | void amdgpu_dm_ism_commit_event(struct amdgpu_dm_ism *ism,
|
| 147 | enum amdgpu_dm_ism_event event);
|
| 148 | void amdgpu_dm_ism_disable(struct amdgpu_display_manager *dm);
|
| 149 | void amdgpu_dm_ism_force_full_power(struct amdgpu_display_manager *dm);
|
| 150 | void amdgpu_dm_ism_enable(struct amdgpu_display_manager *dm);
|
| 151 |
|
| 152 | #if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
|
| 153 | bool dm_ism_next_state(enum amdgpu_dm_ism_state current_state,
|
| 154 | enum amdgpu_dm_ism_event event,
|
| 155 | enum amdgpu_dm_ism_state *next_state);
|
| 156 | uint64_t dm_ism_get_sso_delay(const struct amdgpu_dm_ism *ism,
|
| 157 | const struct dc_stream_state *stream);
|
| 158 | uint64_t dm_ism_get_idle_allow_delay(const struct amdgpu_dm_ism *ism,
|
| 159 | const struct dc_stream_state *stream);
|
| 160 | void dm_ism_insert_record(struct amdgpu_dm_ism *ism);
|
| 161 | void dm_ism_set_last_idle_ts(struct amdgpu_dm_ism *ism);
|
| 162 | bool dm_ism_trigger_event(struct amdgpu_dm_ism *ism,
|
| 163 | enum amdgpu_dm_ism_event event);
|
| 164 | enum amdgpu_dm_ism_event dm_ism_dispatch_next_event(enum amdgpu_dm_ism_state current_state,
|
| 165 | uint64_t delay_ns,
|
| 166 | uint64_t sso_delay_ns);
|
| 167 | #endif
|
| 168 |
|
| 169 | #endif
|