1 /*
2 * Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are permitted
5 * provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright notice, this list of
7 * conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright notice, this list of
9 * conditions and the following disclaimer in the documentation and/or other materials provided
10 * with the distribution.
11 * * Neither the name of The Linux Foundation nor the names of its contributors may be used to
12 * endorse or promote products derived from this software without specific prior written
13 * permission.
14 *
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25 #include <utils/constants.h>
26 #include <utils/debug.h>
27 #include <utils/rect.h>
28 #include <map>
29 #include <algorithm>
30 #include <functional>
31 #include <vector>
32
33 #include "display_primary.h"
34 #include "hw_interface.h"
35 #include "hw_info_interface.h"
36 #include "fb/hw_primary.h"
37
38 #define __CLASS__ "DisplayPrimary"
39
40 namespace sdm {
41
DisplayPrimary(DisplayEventHandler * event_handler,HWInfoInterface * hw_info_intf,BufferSyncHandler * buffer_sync_handler,CompManager * comp_manager,RotatorInterface * rotator_intf)42 DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
43 BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
44 RotatorInterface *rotator_intf)
45 : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
46 rotator_intf, hw_info_intf) {
47 }
48
Init()49 DisplayError DisplayPrimary::Init() {
50 lock_guard<recursive_mutex> obj(recursive_mutex_);
51
52 DisplayError error = HWPrimary::Create(&hw_intf_, hw_info_intf_,
53 DisplayBase::buffer_sync_handler_);
54
55 if (error != kErrorNone) {
56 return error;
57 }
58
59 error = DisplayBase::Init();
60 if (error != kErrorNone) {
61 HWPrimary::Destroy(hw_intf_);
62 return error;
63 }
64
65 idle_timeout_ms_ = Debug::GetIdleTimeoutMs();
66
67 if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
68 error = hw_intf_->SetDisplayMode(kModeVideo);
69 if (error != kErrorNone) {
70 DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
71 kModeVideo);
72 }
73 }
74
75 error = HWEventsInterface::Create(INT(display_type_), this, &event_list_, &hw_events_intf_);
76 if (error != kErrorNone) {
77 DLOGE("Failed to create hardware events interface. Error = %d", error);
78 DisplayBase::Deinit();
79 HWPrimary::Destroy(hw_intf_);
80 }
81
82 return error;
83 }
84
Deinit()85 DisplayError DisplayPrimary::Deinit() {
86 lock_guard<recursive_mutex> obj(recursive_mutex_);
87
88 DisplayError error = DisplayBase::Deinit();
89 HWPrimary::Destroy(hw_intf_);
90
91 return error;
92 }
93
Prepare(LayerStack * layer_stack)94 DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
95 lock_guard<recursive_mutex> obj(recursive_mutex_);
96 DisplayError error = kErrorNone;
97 uint32_t new_mixer_width = 0;
98 uint32_t new_mixer_height = 0;
99 uint32_t display_width = display_attributes_.x_pixels;
100 uint32_t display_height = display_attributes_.y_pixels;
101
102 if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
103 error = ReconfigureMixer(new_mixer_width, new_mixer_height);
104 if (error != kErrorNone) {
105 ReconfigureMixer(display_width, display_height);
106 }
107 }
108
109 return DisplayBase::Prepare(layer_stack);
110 }
111
Commit(LayerStack * layer_stack)112 DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
113 lock_guard<recursive_mutex> obj(recursive_mutex_);
114 DisplayError error = kErrorNone;
115
116 // Enabling auto refresh is async and needs to happen before commit ioctl
117 if (hw_panel_info_.mode == kModeCommand) {
118 hw_intf_->SetAutoRefresh(layer_stack->flags.single_buffered_layer_present);
119 }
120
121 bool set_idle_timeout = comp_manager_->CanSetIdleTimeout(display_comp_ctx_);
122
123 error = DisplayBase::Commit(layer_stack);
124 if (error != kErrorNone) {
125 return error;
126 }
127
128 DisplayBase::ReconfigureDisplay();
129
130 if (hw_panel_info_.mode == kModeVideo) {
131 if (set_idle_timeout && !layer_stack->flags.single_buffered_layer_present) {
132 hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
133 } else {
134 hw_intf_->SetIdleTimeoutMs(0);
135 }
136 }
137
138 return error;
139 }
140
SetDisplayState(DisplayState state)141 DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
142 lock_guard<recursive_mutex> obj(recursive_mutex_);
143 DisplayError error = kErrorNone;
144 error = DisplayBase::SetDisplayState(state);
145 if (error != kErrorNone) {
146 return error;
147 }
148
149 // Set vsync enable state to false, as driver disables vsync during display power off.
150 if (state == kStateOff) {
151 vsync_enable_ = false;
152 }
153
154 return kErrorNone;
155 }
156
SetIdleTimeoutMs(uint32_t timeout_ms)157 void DisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
158 lock_guard<recursive_mutex> obj(recursive_mutex_);
159
160 // Idle fallback feature is supported only for video mode panel.
161 if (hw_panel_info_.mode == kModeVideo) {
162 hw_intf_->SetIdleTimeoutMs(timeout_ms);
163 }
164 idle_timeout_ms_ = timeout_ms;
165 }
166
SetDisplayMode(uint32_t mode)167 DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
168 lock_guard<recursive_mutex> obj(recursive_mutex_);
169 DisplayError error = kErrorNone;
170 HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
171 uint32_t pending = 0;
172
173 if (!active_) {
174 DLOGW("Invalid display state = %d. Panel must be on.", state_);
175 return kErrorNotSupported;
176 }
177
178 if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
179 DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
180 return kErrorParameters;
181 }
182
183 if (hw_display_mode == hw_panel_info_.mode) {
184 DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
185 hw_display_mode);
186 return kErrorNone;
187 }
188
189 error = hw_intf_->SetDisplayMode(hw_display_mode);
190 if (error != kErrorNone) {
191 DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
192 hw_display_mode);
193 return error;
194 }
195
196 if (mode == kModeVideo) {
197 ControlPartialUpdate(false /* enable */, &pending);
198 hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
199 } else if (mode == kModeCommand) {
200 ControlPartialUpdate(true /* enable */, &pending);
201 hw_intf_->SetIdleTimeoutMs(0);
202 }
203
204 return error;
205 }
206
SetPanelBrightness(int level)207 DisplayError DisplayPrimary::SetPanelBrightness(int level) {
208 lock_guard<recursive_mutex> obj(recursive_mutex_);
209 return hw_intf_->SetPanelBrightness(level);
210 }
211
GetRefreshRateRange(uint32_t * min_refresh_rate,uint32_t * max_refresh_rate)212 DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
213 uint32_t *max_refresh_rate) {
214 lock_guard<recursive_mutex> obj(recursive_mutex_);
215 DisplayError error = kErrorNone;
216
217 if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
218 *min_refresh_rate = hw_panel_info_.min_fps;
219 *max_refresh_rate = hw_panel_info_.max_fps;
220 } else {
221 error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
222 }
223
224 return error;
225 }
226
SetRefreshRate(uint32_t refresh_rate)227 DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
228 lock_guard<recursive_mutex> obj(recursive_mutex_);
229
230 if (!active_ || !hw_panel_info_.dynamic_fps) {
231 return kErrorNotSupported;
232 }
233
234 if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
235 DLOGE("Invalid Fps = %d request", refresh_rate);
236 return kErrorParameters;
237 }
238
239 DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
240 if (error != kErrorNone) {
241 return error;
242 }
243
244 return DisplayBase::ReconfigureDisplay();
245 }
246
VSync(int64_t timestamp)247 DisplayError DisplayPrimary::VSync(int64_t timestamp) {
248 if (vsync_enable_) {
249 DisplayEventVSync vsync;
250 vsync.timestamp = timestamp;
251 event_handler_->VSync(vsync);
252 }
253
254 return kErrorNone;
255 }
256
IdleTimeout()257 void DisplayPrimary::IdleTimeout() {
258 event_handler_->Refresh();
259 comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
260 }
261
ThermalEvent(int64_t thermal_level)262 void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
263 lock_guard<recursive_mutex> obj(recursive_mutex_);
264 comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
265 }
266
GetPanelBrightness(int * level)267 DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
268 lock_guard<recursive_mutex> obj(recursive_mutex_);
269 return hw_intf_->GetPanelBrightness(level);
270 }
271
ControlPartialUpdate(bool enable,uint32_t * pending)272 DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
273 lock_guard<recursive_mutex> obj(recursive_mutex_);
274 if (!pending) {
275 return kErrorParameters;
276 }
277
278 if (!hw_panel_info_.partial_update) {
279 // Nothing to be done.
280 DLOGI("partial update is not applicable for display=%d", display_type_);
281 return kErrorNotSupported;
282 }
283
284 *pending = 0;
285 if (enable == partial_update_control_) {
286 DLOGI("Same state transition is requested.");
287 return kErrorNone;
288 }
289
290 partial_update_control_ = enable;
291
292 if (!enable) {
293 // If the request is to turn off feature, new draw call is required to have
294 // the new setting into effect.
295 *pending = 1;
296 }
297
298 return kErrorNone;
299 }
300
DisablePartialUpdateOneFrame()301 DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
302 lock_guard<recursive_mutex> obj(recursive_mutex_);
303 disable_pu_one_frame_ = true;
304
305 return kErrorNone;
306 }
307
308 } // namespace sdm
309
310