1 /*
2 * Copyright (c) 2014 - 2019, 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 <utils/utils.h>
29 
30 #include <algorithm>
31 #include <functional>
32 #include <map>
33 #include <string>
34 #include <vector>
35 
36 #include "display_builtin.h"
37 #include "hw_info_interface.h"
38 #include "hw_interface.h"
39 #include "drm_interface.h"
40 #include "drm_master.h"
41 
42 #define __CLASS__ "DisplayBuiltIn"
43 
44 namespace sdm {
45 
DisplayBuiltIn(DisplayEventHandler * event_handler,HWInfoInterface * hw_info_intf,BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,CompManager * comp_manager)46 DisplayBuiltIn::DisplayBuiltIn(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
47                                BufferSyncHandler *buffer_sync_handler,
48                                BufferAllocator *buffer_allocator, CompManager *comp_manager)
49   : DisplayBase(kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler, buffer_allocator,
50                 comp_manager, hw_info_intf) {}
51 
DisplayBuiltIn(int32_t display_id,DisplayEventHandler * event_handler,HWInfoInterface * hw_info_intf,BufferSyncHandler * buffer_sync_handler,BufferAllocator * buffer_allocator,CompManager * comp_manager)52 DisplayBuiltIn::DisplayBuiltIn(int32_t display_id, DisplayEventHandler *event_handler,
53                                HWInfoInterface *hw_info_intf,
54                                BufferSyncHandler *buffer_sync_handler,
55                                BufferAllocator *buffer_allocator, CompManager *comp_manager)
56   : DisplayBase(display_id, kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler,
57                 buffer_allocator, comp_manager, hw_info_intf) {}
58 
~DisplayBuiltIn()59 DisplayBuiltIn::~DisplayBuiltIn() {
60   CloseFd(&previous_retire_fence_);
61 }
62 
Init()63 DisplayError DisplayBuiltIn::Init() {
64   lock_guard<recursive_mutex> obj(recursive_mutex_);
65   int32_t disable_defer_power_state = 0;
66 
67   DisplayError error = HWInterface::Create(display_id_, kBuiltIn, hw_info_intf_,
68                                            buffer_sync_handler_, buffer_allocator_, &hw_intf_);
69   if (error != kErrorNone) {
70     DLOGE("Failed to create hardware interface on. Error = %d", error);
71     return error;
72   }
73 
74   if (-1 == display_id_) {
75     hw_intf_->GetDisplayId(&display_id_);
76   }
77 
78   error = DisplayBase::Init();
79   if (error != kErrorNone) {
80     HWInterface::Destroy(hw_intf_);
81     return error;
82   }
83 
84   if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
85     error = hw_intf_->SetDisplayMode(kModeVideo);
86     if (error != kErrorNone) {
87       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
88             kModeVideo);
89     }
90   }
91 
92   if (hw_panel_info_.mode == kModeCommand) {
93     event_list_ = {HWEvent::VSYNC,
94                    HWEvent::EXIT,
95                    /* HWEvent::IDLE_NOTIFY, */
96                    /* HWEvent::CEC_READ_MESSAGE, */
97                    HWEvent::SHOW_BLANK_EVENT,
98                    HWEvent::THERMAL_LEVEL,
99                    HWEvent::IDLE_POWER_COLLAPSE,
100                    HWEvent::PINGPONG_TIMEOUT,
101                    HWEvent::PANEL_DEAD,
102                    HWEvent::HW_RECOVERY,
103                    HWEvent::HISTOGRAM};
104   } else {
105     event_list_ = {HWEvent::VSYNC,
106                    HWEvent::EXIT,
107                    HWEvent::IDLE_NOTIFY,
108                    /* HWEvent::CEC_READ_MESSAGE, */
109                    HWEvent::SHOW_BLANK_EVENT,
110                    HWEvent::THERMAL_LEVEL,
111                    HWEvent::PINGPONG_TIMEOUT,
112                    HWEvent::PANEL_DEAD,
113                    HWEvent::HW_RECOVERY,
114                    HWEvent::HISTOGRAM};
115   }
116 
117   avr_prop_disabled_ = Debug::IsAVRDisabled();
118 
119   error = HWEventsInterface::Create(display_id_, kBuiltIn, this, event_list_, hw_intf_,
120                                     &hw_events_intf_);
121   if (error != kErrorNone) {
122     DisplayBase::Deinit();
123     HWInterface::Destroy(hw_intf_);
124     DLOGE("Failed to create hardware events interface on. Error = %d", error);
125   }
126 
127   current_refresh_rate_ = hw_panel_info_.max_fps;
128 
129   initColorSamplingState();
130 
131   Debug::GetProperty(DISABLE_DEFER_POWER_STATE, &disable_defer_power_state);
132   defer_power_state_ = !disable_defer_power_state;
133   DLOGI("defer_power_state %d", defer_power_state_);
134 
135   int value = 0;
136   Debug::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &value);
137   deferred_config_.frame_count = (value > 0) ? UINT32(value) : 0;
138 
139   return error;
140 }
141 
Deinit()142 DisplayError DisplayBuiltIn::Deinit() {
143   lock_guard<recursive_mutex> obj(recursive_mutex_);
144 
145   dpps_info_.Deinit();
146   return DisplayBase::Deinit();
147 }
148 
Prepare(LayerStack * layer_stack)149 DisplayError DisplayBuiltIn::Prepare(LayerStack *layer_stack) {
150   lock_guard<recursive_mutex> obj(recursive_mutex_);
151   DisplayError error = kErrorNone;
152   uint32_t new_mixer_width = 0;
153   uint32_t new_mixer_height = 0;
154   uint32_t display_width = display_attributes_.x_pixels;
155   uint32_t display_height = display_attributes_.y_pixels;
156 
157   DTRACE_SCOPED();
158   if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
159     error = ReconfigureMixer(new_mixer_width, new_mixer_height);
160     if (error != kErrorNone) {
161       ReconfigureMixer(display_width, display_height);
162     }
163   } else {
164     if (CanSkipDisplayPrepare(layer_stack)) {
165       hw_layers_.hw_avr_info.update = needs_avr_update_;
166       hw_layers_.hw_avr_info.mode = GetAvrMode(qsync_mode_);
167       return kErrorNone;
168     }
169   }
170 
171   // Clean hw layers for reuse.
172   DTRACE_BEGIN("PrepareHWLayers");
173   hw_layers_ = HWLayers();
174   DTRACE_END();
175 
176   hw_layers_.hw_avr_info.update = needs_avr_update_;
177   hw_layers_.hw_avr_info.mode = GetAvrMode(qsync_mode_);
178 
179   left_frame_roi_ = {};
180   right_frame_roi_ = {};
181 
182   error = DisplayBase::Prepare(layer_stack);
183 
184   // Cache the Frame ROI.
185   if (error == kErrorNone) {
186     if (hw_layers_.info.left_frame_roi.size() && hw_layers_.info.right_frame_roi.size()) {
187       left_frame_roi_ = hw_layers_.info.left_frame_roi.at(0);
188       right_frame_roi_ = hw_layers_.info.right_frame_roi.at(0);
189     }
190   }
191 
192   return error;
193 }
194 
initColorSamplingState()195 void DisplayBuiltIn::initColorSamplingState() {
196   samplingState = SamplingState::Off;
197   histogramCtrl.object_type = DRM_MODE_OBJECT_CRTC;
198   histogramCtrl.feature_id = sde_drm::DRMDPPSFeatureID::kFeatureAbaHistCtrl;
199   histogramCtrl.value = sde_drm::HistModes::kHistDisabled;
200 
201   histogramIRQ.object_type = DRM_MODE_OBJECT_CRTC;
202   histogramIRQ.feature_id = sde_drm::DRMDPPSFeatureID::kFeatureAbaHistIRQ;
203   histogramIRQ.value = sde_drm::HistModes::kHistDisabled;
204   histogramSetup = true;
205 }
206 
setColorSamplingState(SamplingState state)207 DisplayError DisplayBuiltIn::setColorSamplingState(SamplingState state) {
208   samplingState = state;
209   if (samplingState == SamplingState::On) {
210     histogramCtrl.value = sde_drm::HistModes::kHistEnabled;
211     histogramIRQ.value = sde_drm::HistModes::kHistEnabled;
212   } else {
213     histogramCtrl.value = sde_drm::HistModes::kHistDisabled;
214     histogramIRQ.value = sde_drm::HistModes::kHistDisabled;
215   }
216 
217   //effectively drmModeAtomicAddProperty for the SDE_DSPP_HIST_CTRL_V1
218   return DppsProcessOps(kDppsSetFeature, &histogramCtrl, sizeof(histogramCtrl));
219 }
220 
colorSamplingOn()221 DisplayError DisplayBuiltIn::colorSamplingOn() {
222   if (!histogramSetup) {
223     return kErrorParameters;
224   }
225   return setColorSamplingState(SamplingState::On);
226 }
227 
colorSamplingOff()228 DisplayError DisplayBuiltIn::colorSamplingOff() {
229   if (!histogramSetup) {
230     return kErrorParameters;
231   }
232   return setColorSamplingState(SamplingState::Off);
233 }
234 
GetAvrMode(QSyncMode mode)235 HWAVRModes DisplayBuiltIn::GetAvrMode(QSyncMode mode) {
236   switch (mode) {
237      case kQSyncModeNone:
238        return kQsyncNone;
239      case kQSyncModeContinuous:
240        return kContinuousMode;
241      case kQsyncModeOneShot:
242      case kQsyncModeOneShotContinuous:
243        return kOneShotMode;
244      default:
245        return kQsyncNone;
246   }
247 }
248 
Commit(LayerStack * layer_stack)249 DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) {
250   lock_guard<recursive_mutex> obj(recursive_mutex_);
251   DisplayError error = kErrorNone;
252   uint32_t app_layer_count = hw_layers_.info.app_layer_count;
253 
254   DTRACE_SCOPED();
255 
256   // Enabling auto refresh is async and needs to happen before commit ioctl
257   if (hw_panel_info_.mode == kModeCommand) {
258     bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
259     bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
260 
261     hw_intf_->SetAutoRefresh(enable);
262     if (need_refresh) {
263       event_handler_->Refresh();
264     }
265   }
266 
267   //effectively drmModeAtomicAddProperty for SDE_DSPP_HIST_IRQ_V1
268   if (histogramSetup) {
269     DppsProcessOps(kDppsSetFeature, &histogramIRQ, sizeof(histogramIRQ));
270   }
271 
272   if (vsync_enable_) {
273     DTRACE_BEGIN("RegisterVsync");
274     // wait for previous frame's retire fence to signal.
275     buffer_sync_handler_->SyncWait(previous_retire_fence_);
276 
277     // Register for vsync and then commit the frame.
278     hw_events_intf_->SetEventState(HWEvent::VSYNC, true);
279     DTRACE_END();
280   }
281 
282   error = DisplayBase::Commit(layer_stack);
283   if (error != kErrorNone) {
284     return error;
285   }
286 
287   if (commit_event_enabled_) {
288     dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_, sizeof(display_type_));
289   }
290 
291   deferred_config_.UpdateDeferCount();
292 
293   ReconfigureDisplay();
294 
295   if (deferred_config_.CanApplyDeferredState()) {
296     event_handler_->HandleEvent(kInvalidateDisplay);
297     deferred_config_.Clear();
298   }
299 
300   int idle_time_ms = hw_layers_.info.set_idle_time_ms;
301   if (idle_time_ms >= 0) {
302     hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
303   }
304 
305   if (switch_to_cmd_) {
306     uint32_t pending;
307     switch_to_cmd_ = false;
308     ControlPartialUpdate(true /* enable */, &pending);
309   }
310 
311   dpps_info_.Init(this, hw_panel_info_.panel_name);
312 
313   if (qsync_mode_ == kQsyncModeOneShot) {
314     // Reset qsync mode.
315     SetQSyncMode(kQSyncModeNone);
316   } else if (qsync_mode_ == kQsyncModeOneShotContinuous) {
317     // No action needed.
318   } else if (qsync_mode_ == kQSyncModeContinuous) {
319     needs_avr_update_ = false;
320   } else if (qsync_mode_ == kQSyncModeNone) {
321     needs_avr_update_ = false;
322   }
323 
324   first_cycle_ = false;
325 
326   CloseFd(&previous_retire_fence_);
327   previous_retire_fence_ = Sys::dup_(layer_stack->retire_fence_fd);
328 
329   return error;
330 }
331 
SetDisplayState(DisplayState state,bool teardown,int * release_fence)332 DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, bool teardown,
333                                              int *release_fence) {
334   lock_guard<recursive_mutex> obj(recursive_mutex_);
335   DisplayError error = kErrorNone;
336 
337   if ((state == kStateOn) && deferred_config_.IsDeferredState()) {
338     SetDeferredFpsConfig();
339   }
340 
341   error = DisplayBase::SetDisplayState(state, teardown, release_fence);
342   if (error != kErrorNone) {
343     return error;
344   }
345 
346   // Set vsync enable state to false, as driver disables vsync during display power off.
347   if (state == kStateOff) {
348     vsync_enable_ = false;
349   } else if (state == kStateOn && pendingActiveConfig != UINT_MAX) {
350     deferred_config_.MarkDirty();
351     DisplayBase::SetActiveConfig(pendingActiveConfig);
352     pendingActiveConfig = UINT_MAX;
353   }
354 
355   return kErrorNone;
356 }
357 
SetActiveConfig(uint32_t index)358 DisplayError DisplayBuiltIn::SetActiveConfig(uint32_t index) {
359   lock_guard<recursive_mutex> obj(recursive_mutex_);
360   DisplayState state;
361 
362   if (DisplayBase::GetDisplayState(&state) == kErrorNone) {
363     if (state != kStateOn) {
364       pendingActiveConfig = index;
365       return kErrorNone;
366     }
367   }
368 
369   pendingActiveConfig = UINT_MAX;
370   deferred_config_.MarkDirty();
371   return DisplayBase::SetActiveConfig(index);
372 }
373 
GetActiveConfig(uint32_t * index)374 DisplayError DisplayBuiltIn::GetActiveConfig(uint32_t *index) {
375   lock_guard<recursive_mutex> obj(recursive_mutex_);
376   if (index && pendingActiveConfig != UINT_MAX) {
377     *index = pendingActiveConfig;
378     return kErrorNone;
379   }
380   return DisplayBase::GetActiveConfig(index);
381 }
382 
SetIdleTimeoutMs(uint32_t active_ms)383 void DisplayBuiltIn::SetIdleTimeoutMs(uint32_t active_ms) {
384   lock_guard<recursive_mutex> obj(recursive_mutex_);
385   comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms);
386 }
387 
SetDisplayMode(uint32_t mode)388 DisplayError DisplayBuiltIn::SetDisplayMode(uint32_t mode) {
389   DisplayError error = kErrorNone;
390 
391   // Limit scope of mutex to this block
392   {
393     lock_guard<recursive_mutex> obj(recursive_mutex_);
394     HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
395     uint32_t pending = 0;
396 
397     if (!active_) {
398       DLOGW("Invalid display state = %d. Panel must be on.", state_);
399       return kErrorNotSupported;
400     }
401 
402     if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
403       DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
404       return kErrorParameters;
405     }
406 
407     if (hw_display_mode == hw_panel_info_.mode) {
408       DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
409             hw_display_mode);
410       return kErrorNone;
411     }
412 
413     error = hw_intf_->SetDisplayMode(hw_display_mode);
414     if (error != kErrorNone) {
415       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
416             hw_display_mode);
417       return error;
418     }
419 
420     if (mode == kModeVideo) {
421       ControlPartialUpdate(false /* enable */, &pending);
422     } else if (mode == kModeCommand) {
423       // Flush idle timeout value currently set.
424       comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, 0);
425       switch_to_cmd_ = true;
426     }
427   }
428 
429   // Request for a new draw cycle. New display mode will get applied on next draw cycle.
430   // New idle time will get configured as part of this.
431   event_handler_->Refresh();
432 
433   return error;
434 }
435 
SetPanelBrightness(int32_t level)436 DisplayError DisplayBuiltIn::SetPanelBrightness(int32_t level) {
437   lock_guard<std::mutex> lock(brightness_lock_);
438 
439   if (state_ == kStateOff) {
440     return kErrorNone;
441   }
442 
443   DisplayError err = hw_intf_->SetPanelBrightness(level);
444 
445   DLOGI_IF(kTagDisplay, "Setting brightness to level %d, error %d", level, err);
446 
447   return err;
448 }
449 
GetRefreshRateRange(uint32_t * min_refresh_rate,uint32_t * max_refresh_rate)450 DisplayError DisplayBuiltIn::GetRefreshRateRange(uint32_t *min_refresh_rate,
451                                                  uint32_t *max_refresh_rate) {
452   lock_guard<recursive_mutex> obj(recursive_mutex_);
453   DisplayError error = kErrorNone;
454 
455   if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
456     *min_refresh_rate = hw_panel_info_.min_fps;
457     *max_refresh_rate = hw_panel_info_.max_fps;
458   } else {
459     error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
460   }
461 
462   return error;
463 }
464 
TeardownConcurrentWriteback(void)465 DisplayError DisplayBuiltIn::TeardownConcurrentWriteback(void) {
466   lock_guard<recursive_mutex> obj(recursive_mutex_);
467 
468   return hw_intf_->TeardownConcurrentWriteback();
469 }
470 
SetRefreshRate(uint32_t refresh_rate,bool final_rate)471 DisplayError DisplayBuiltIn::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
472   lock_guard<recursive_mutex> obj(recursive_mutex_);
473 
474   if (!active_ || !hw_panel_info_.dynamic_fps || qsync_mode_ != kQSyncModeNone) {
475     return kErrorNotSupported;
476   }
477 
478   if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
479     DLOGE("Invalid Fps = %d request", refresh_rate);
480     return kErrorParameters;
481   }
482 
483   if (handle_idle_timeout_ && !final_rate) {
484     refresh_rate = hw_panel_info_.min_fps;
485   }
486 
487   if ((current_refresh_rate_ != refresh_rate) || handle_idle_timeout_) {
488     DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
489     if (error != kErrorNone) {
490       // Attempt to update refresh rate can fail if rf interfenence is detected.
491       // Just drop min fps settting for now.
492       handle_idle_timeout_ = false;
493       return error;
494     }
495 
496     error = comp_manager_->CheckEnforceSplit(display_comp_ctx_, refresh_rate);
497     if (error != kErrorNone) {
498       return error;
499     }
500   }
501 
502   // On success, set current refresh rate to new refresh rate
503   current_refresh_rate_ = refresh_rate;
504   handle_idle_timeout_ = false;
505   deferred_config_.MarkDirty();
506 
507   return ReconfigureDisplay();
508 }
509 
VSync(int64_t timestamp)510 DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
511   if (vsync_enable_ && !drop_hw_vsync_) {
512     DisplayEventVSync vsync;
513     vsync.timestamp = timestamp;
514     event_handler_->VSync(vsync);
515   }
516 
517   return kErrorNone;
518 }
519 
IdleTimeout()520 void DisplayBuiltIn::IdleTimeout() {
521   if (hw_panel_info_.mode == kModeVideo) {
522     if (event_handler_->HandleEvent(kIdleTimeout) != kErrorNone) {
523       return;
524     }
525     handle_idle_timeout_ = true;
526     event_handler_->Refresh();
527     lock_guard<recursive_mutex> obj(recursive_mutex_);
528     comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
529   }
530 }
531 
PingPongTimeout()532 void DisplayBuiltIn::PingPongTimeout() {
533   lock_guard<recursive_mutex> obj(recursive_mutex_);
534   hw_intf_->DumpDebugData();
535 }
536 
ThermalEvent(int64_t thermal_level)537 void DisplayBuiltIn::ThermalEvent(int64_t thermal_level) {
538   event_handler_->HandleEvent(kThermalEvent);
539   lock_guard<recursive_mutex> obj(recursive_mutex_);
540   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
541 }
542 
IdlePowerCollapse()543 void DisplayBuiltIn::IdlePowerCollapse() {
544   if (hw_panel_info_.mode == kModeCommand) {
545     event_handler_->HandleEvent(kIdlePowerCollapse);
546     lock_guard<recursive_mutex> obj(recursive_mutex_);
547     comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
548   }
549 }
550 
PanelDead()551 void DisplayBuiltIn::PanelDead() {
552   event_handler_->HandleEvent(kPanelDeadEvent);
553 }
554 
555 // HWEventHandler overload, not DisplayBase
HwRecovery(const HWRecoveryEvent sdm_event_code)556 void DisplayBuiltIn::HwRecovery(const HWRecoveryEvent sdm_event_code) {
557   DisplayBase::HwRecovery(sdm_event_code);
558 }
559 
Histogram(int histogram_fd,uint32_t blob_id)560 void DisplayBuiltIn::Histogram(int histogram_fd, uint32_t blob_id) {
561     event_handler_->HistogramEvent(histogram_fd, blob_id);
562 }
563 
GetPanelBrightness(int32_t & level) const564 DisplayError DisplayBuiltIn::GetPanelBrightness(int32_t &level) const {
565   lock_guard<std::mutex> lock(brightness_lock_);
566 
567   DisplayError err = hw_intf_->GetPanelBrightness(level);
568 
569   DLOGI_IF(kTagDisplay, "Getting brightness level %d, error %d", level, err);
570 
571   return err;
572 }
573 
GetPanelMaxBrightness(int32_t & max_brightness_level) const574 DisplayError DisplayBuiltIn::GetPanelMaxBrightness(int32_t &max_brightness_level) const {
575   lock_guard<std::mutex> lock(brightness_lock_);
576 
577   max_brightness_level = static_cast<int32_t>(hw_panel_info_.panel_max_brightness);
578 
579   DLOGI_IF(kTagDisplay, "Get panel max brightness %u", max_brightness_level);
580   return kErrorNone;
581 }
582 
IsSupportPanelBrightnessControl()583 bool DisplayBuiltIn::IsSupportPanelBrightnessControl() {
584   lock_guard<recursive_mutex> obj(recursive_mutex_);
585 
586   return hw_intf_->IsSupportPanelBrightnessControl();
587 }
588 
ControlPartialUpdate(bool enable,uint32_t * pending)589 DisplayError DisplayBuiltIn::ControlPartialUpdate(bool enable, uint32_t *pending) {
590   lock_guard<recursive_mutex> obj(recursive_mutex_);
591   if (!pending) {
592     return kErrorParameters;
593   }
594 
595   if (!hw_panel_info_.partial_update) {
596     // Nothing to be done.
597     DLOGI("partial update is not applicable for display id = %d", display_id_);
598     return kErrorNotSupported;
599   }
600 
601   *pending = 0;
602   if (enable == partial_update_control_) {
603     DLOGI("Same state transition is requested.");
604     return kErrorNone;
605   }
606 
607   partial_update_control_ = enable;
608 
609   if (!enable) {
610     // If the request is to turn off feature, new draw call is required to have
611     // the new setting into effect.
612     *pending = 1;
613   }
614 
615   return kErrorNone;
616 }
617 
DisablePartialUpdateOneFrame()618 DisplayError DisplayBuiltIn::DisablePartialUpdateOneFrame() {
619   lock_guard<recursive_mutex> obj(recursive_mutex_);
620   disable_pu_one_frame_ = true;
621 
622   return kErrorNone;
623 }
624 
DppsProcessOps(enum DppsOps op,void * payload,size_t size)625 DisplayError DisplayBuiltIn::DppsProcessOps(enum DppsOps op, void *payload, size_t size) {
626   DisplayError error = kErrorNone;
627   uint32_t pending;
628   bool enable = false;
629 
630   switch (op) {
631     case kDppsSetFeature:
632       if (!payload) {
633         DLOGE("Invalid payload parameter for op %d", op);
634         error = kErrorParameters;
635         break;
636       }
637       {
638         lock_guard<recursive_mutex> obj(recursive_mutex_);
639         error = hw_intf_->SetDppsFeature(payload, size);
640       }
641       break;
642     case kDppsGetFeatureInfo:
643       if (!payload) {
644         DLOGE("Invalid payload parameter for op %d", op);
645         error = kErrorParameters;
646         break;
647       }
648       error = hw_intf_->GetDppsFeatureInfo(payload, size);
649       break;
650     case kDppsScreenRefresh:
651       event_handler_->Refresh();
652       break;
653     case kDppsPartialUpdate:
654       if (!payload) {
655         DLOGE("Invalid payload parameter for op %d", op);
656         error = kErrorParameters;
657         break;
658       }
659       enable = *(reinterpret_cast<bool *>(payload));
660       ControlPartialUpdate(enable, &pending);
661       break;
662     case kDppsRequestCommit:
663       if (!payload) {
664         DLOGE("Invalid payload parameter for op %d", op);
665         error = kErrorParameters;
666         break;
667       }
668       {
669         lock_guard<recursive_mutex> obj(recursive_mutex_);
670         commit_event_enabled_ = *(reinterpret_cast<bool *>(payload));
671       }
672       break;
673     default:
674       DLOGE("Invalid input op %d", op);
675       error = kErrorParameters;
676       break;
677   }
678   return error;
679 }
680 
SetDisplayDppsAdROI(void * payload)681 DisplayError DisplayBuiltIn::SetDisplayDppsAdROI(void *payload) {
682   lock_guard<recursive_mutex> obj(recursive_mutex_);
683   DisplayError err = kErrorNone;
684 
685   err = hw_intf_->SetDisplayDppsAdROI(payload);
686   if (err != kErrorNone)
687     DLOGE("Failed to set ad roi config, err %d", err);
688 
689   return err;
690 }
691 
Init(DppsPropIntf * intf,const std::string & panel_name)692 void DppsInfo::Init(DppsPropIntf *intf, const std::string &panel_name) {
693   int error = 0;
694 
695   if (dpps_initialized_) {
696     return;
697   }
698 
699   if (!dpps_impl_lib.Open(kDppsLib)) {
700     DLOGW("Failed to load Dpps lib %s", kDppsLib);
701     goto exit;
702   }
703 
704   if (!dpps_impl_lib.Sym("GetDppsInterface", reinterpret_cast<void **>(&GetDppsInterface))) {
705     DLOGE("GetDppsInterface not found!, err %s", dlerror());
706     goto exit;
707   }
708 
709   dpps_intf = GetDppsInterface();
710   if (!dpps_intf) {
711     DLOGE("Failed to get Dpps Interface!");
712     goto exit;
713   }
714 
715   error = dpps_intf->Init(intf, panel_name);
716   if (!error) {
717     DLOGI("DPPS Interface init successfully");
718     dpps_initialized_ = true;
719     return;
720   } else {
721     DLOGE("DPPS Interface init failure with err %d", error);
722   }
723 
724 exit:
725   Deinit();
726   dpps_intf = new DppsDummyImpl();
727   dpps_initialized_ = true;
728 }
729 
Deinit()730 void DppsInfo::Deinit() {
731   if (dpps_intf) {
732     dpps_intf->Deinit();
733     dpps_intf = NULL;
734   }
735   dpps_impl_lib.~DynLib();
736 }
737 
DppsNotifyOps(enum DppsNotifyOps op,void * payload,size_t size)738 void DppsInfo::DppsNotifyOps(enum DppsNotifyOps op, void *payload, size_t size) {
739   int ret = 0;
740   ret = dpps_intf->DppsNotifyOps(op, payload, size);
741   if (ret)
742     DLOGE("DppsNotifyOps op %d error %d", op, ret);
743 }
744 
HandleSecureEvent(SecureEvent secure_event,LayerStack * layer_stack)745 DisplayError DisplayBuiltIn::HandleSecureEvent(SecureEvent secure_event, LayerStack *layer_stack) {
746   hw_layers_.info.stack = layer_stack;
747   DisplayError err = hw_intf_->HandleSecureEvent(secure_event, &hw_layers_);
748   if (err != kErrorNone) {
749     return err;
750   }
751   comp_manager_->HandleSecureEvent(display_comp_ctx_, secure_event);
752 
753   return kErrorNone;
754 }
755 
SetQSyncMode(QSyncMode qsync_mode)756 DisplayError DisplayBuiltIn::SetQSyncMode(QSyncMode qsync_mode) {
757   lock_guard<recursive_mutex> obj(recursive_mutex_);
758   if (!hw_panel_info_.qsync_support || qsync_mode_ == qsync_mode || first_cycle_) {
759     DLOGE("Failed: qsync_support: %d first_cycle %d mode: %d -> %d", hw_panel_info_.qsync_support,
760           first_cycle_, qsync_mode_, qsync_mode);
761     return kErrorNotSupported;
762   }
763 
764   qsync_mode_ = qsync_mode;
765   needs_avr_update_ = true;
766   event_handler_->Refresh();
767 
768   return kErrorNone;
769 }
770 
ControlIdlePowerCollapse(bool enable,bool synchronous)771 DisplayError DisplayBuiltIn::ControlIdlePowerCollapse(bool enable, bool synchronous) {
772   lock_guard<recursive_mutex> obj(recursive_mutex_);
773   if (!active_) {
774     DLOGW("Invalid display state = %d. Panel must be on.", state_);
775     return kErrorPermission;
776   }
777   if (hw_panel_info_.mode == kModeVideo) {
778     DLOGW("Idle power collapse not supported for video mode panel.");
779     return kErrorNotSupported;
780   }
781   return hw_intf_->ControlIdlePowerCollapse(enable, synchronous);
782 }
783 
GetSupportedDSIClock(std::vector<uint64_t> * bitclk_rates)784 DisplayError DisplayBuiltIn::GetSupportedDSIClock(std::vector<uint64_t> *bitclk_rates) {
785   lock_guard<recursive_mutex> obj(recursive_mutex_);
786   if (!hw_panel_info_.dyn_bitclk_support) {
787     return kErrorNotSupported;
788   }
789 
790   *bitclk_rates = hw_panel_info_.bitclk_rates;
791   return kErrorNone;
792 }
793 
SetDynamicDSIClock(uint64_t bit_clk_rate)794 DisplayError DisplayBuiltIn::SetDynamicDSIClock(uint64_t bit_clk_rate) {
795   lock_guard<recursive_mutex> obj(recursive_mutex_);
796   if (!active_) {
797     DLOGW("Invalid display state = %d. Panel must be on.", state_);
798     return kErrorNotSupported;
799   }
800 
801   if (!hw_panel_info_.dyn_bitclk_support) {
802     return kErrorNotSupported;
803   }
804 
805   uint64_t current_clk = 0;
806   std::vector<uint64_t> &clk_rates = hw_panel_info_.bitclk_rates;
807   GetDynamicDSIClock(&current_clk);
808   bool valid = std::find(clk_rates.begin(), clk_rates.end(), bit_clk_rate) != clk_rates.end();
809   if (current_clk == bit_clk_rate || !valid) {
810     DLOGI("Invalid setting %d, Clk. already set %d", !valid, (current_clk == bit_clk_rate));
811     return kErrorNone;
812   }
813 
814   return hw_intf_->SetDynamicDSIClock(bit_clk_rate);
815 }
816 
GetDynamicDSIClock(uint64_t * bit_clk_rate)817 DisplayError DisplayBuiltIn::GetDynamicDSIClock(uint64_t *bit_clk_rate) {
818   lock_guard<recursive_mutex> obj(recursive_mutex_);
819   if (!hw_panel_info_.dyn_bitclk_support) {
820     return kErrorNotSupported;
821   }
822 
823   return hw_intf_->GetDynamicDSIClock(bit_clk_rate);
824 }
825 
CanCompareFrameROI(LayerStack * layer_stack)826 bool DisplayBuiltIn::CanCompareFrameROI(LayerStack *layer_stack) {
827   // Check Display validation and safe-mode states.
828   if (needs_validate_ || comp_manager_->IsSafeMode()) {
829     return false;
830   }
831 
832   // Check Panel and Layer Stack attributes.
833   if (!hw_panel_info_.partial_update || (hw_panel_info_.left_roi_count != 1) ||
834       layer_stack->flags.geometry_changed || layer_stack->flags.config_changed ||
835       (layer_stack->layers.size() != (hw_layers_.info.app_layer_count + 1))) {
836     return false;
837   }
838 
839   // Check for Partial Update disable requests/scenarios.
840   if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
841     DisablePartialUpdateOneFrame();
842   }
843 
844   if (!partial_update_control_ || disable_pu_one_frame_ || disable_pu_on_dest_scaler_) {
845     return false;
846   }
847 
848   bool surface_damage = false;
849   uint32_t surface_damage_mask_value = (1 << kSurfaceDamage);
850   for (uint32_t i = 0; i < layer_stack->layers.size(); i++) {
851     Layer *layer = layer_stack->layers.at(i);
852     if (layer->update_mask.none()) {
853       continue;
854     }
855     // Only kSurfaceDamage bit should be set in layer's update-mask.
856     if (layer->update_mask.to_ulong() == surface_damage_mask_value) {
857       surface_damage = true;
858     } else {
859       return false;
860     }
861   }
862 
863   return surface_damage;
864 }
865 
CanSkipDisplayPrepare(LayerStack * layer_stack)866 bool DisplayBuiltIn::CanSkipDisplayPrepare(LayerStack *layer_stack) {
867   if (!CanCompareFrameROI(layer_stack)) {
868     return false;
869   }
870 
871   DisplayError error = BuildLayerStackStats(layer_stack);
872   if (error != kErrorNone) {
873     return false;
874   }
875 
876   hw_layers_.info.left_frame_roi.clear();
877   hw_layers_.info.right_frame_roi.clear();
878   hw_layers_.info.dest_scale_info_map.clear();
879   comp_manager_->GenerateROI(display_comp_ctx_, &hw_layers_);
880 
881   if (!hw_layers_.info.left_frame_roi.size() || !hw_layers_.info.right_frame_roi.size()) {
882     return false;
883   }
884 
885   // Compare the cached and calculated Frame ROIs.
886   bool same_roi = IsCongruent(left_frame_roi_, hw_layers_.info.left_frame_roi.at(0)) &&
887                   IsCongruent(right_frame_roi_, hw_layers_.info.right_frame_roi.at(0));
888 
889   if (same_roi) {
890     // Update Surface Damage rectangle(s) in HW layers.
891     uint32_t hw_layer_count = UINT32(hw_layers_.info.hw_layers.size());
892     for (uint32_t j = 0; j < hw_layer_count; j++) {
893       Layer &hw_layer = hw_layers_.info.hw_layers.at(j);
894       Layer *sdm_layer = layer_stack->layers.at(hw_layers_.info.index.at(j));
895       if (hw_layer.dirty_regions.size() != sdm_layer->dirty_regions.size()) {
896         return false;
897       }
898       for (uint32_t k = 0; k < hw_layer.dirty_regions.size(); k++) {
899         hw_layer.dirty_regions.at(k) = sdm_layer->dirty_regions.at(k);
900       }
901     }
902 
903     // Set the composition type for SDM layers.
904     for (uint32_t i = 0; i < (layer_stack->layers.size() - 1); i++) {
905       layer_stack->layers.at(i)->composition = kCompositionSDE;
906     }
907   }
908 
909   return same_roi;
910 }
911 
ReconfigureDisplay()912 DisplayError DisplayBuiltIn::ReconfigureDisplay() {
913   lock_guard<recursive_mutex> obj(recursive_mutex_);
914   DisplayError error = kErrorNone;
915   HWDisplayAttributes display_attributes;
916   HWMixerAttributes mixer_attributes;
917   HWPanelInfo hw_panel_info;
918   uint32_t active_index = 0;
919 
920   DTRACE_SCOPED();
921 
922   error = hw_intf_->GetActiveConfig(&active_index);
923   if (error != kErrorNone) {
924     return error;
925   }
926 
927   error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
928   if (error != kErrorNone) {
929     return error;
930   }
931 
932   error = hw_intf_->GetMixerAttributes(&mixer_attributes);
933   if (error != kErrorNone) {
934     return error;
935   }
936 
937   error = hw_intf_->GetHWPanelInfo(&hw_panel_info);
938   if (error != kErrorNone) {
939     return error;
940   }
941 
942   const bool dirty = deferred_config_.IsDirty();
943   if (deferred_config_.IsDeferredState()) {
944     if (dirty) {
945       SetDeferredFpsConfig();
946     } else {
947       // In Deferred state, use current config for comparison.
948       GetFpsConfig(&display_attributes, &hw_panel_info);
949     }
950   }
951 
952   const bool display_unchanged = (display_attributes == display_attributes_);
953   const bool mixer_unchanged = (mixer_attributes == mixer_attributes_);
954   const bool panel_unchanged = (hw_panel_info == hw_panel_info_);
955   if (!dirty && display_unchanged && mixer_unchanged && panel_unchanged) {
956     return kErrorNone;
957   }
958 
959   if (CanDeferFpsConfig(display_attributes.fps)) {
960     deferred_config_.Init(display_attributes.fps, display_attributes.vsync_period_ns,
961                           hw_panel_info.transfer_time_us);
962 
963     // Apply current config until new Fps is deferred.
964     GetFpsConfig(&display_attributes, &hw_panel_info);
965   }
966 
967   error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info,
968                                             mixer_attributes, fb_config_,
969                                             &(default_qos_data_.clock_hz));
970   if (error != kErrorNone) {
971     return error;
972   }
973 
974   bool disble_pu = true;
975   if (mixer_unchanged && panel_unchanged) {
976     // Do not disable Partial Update for one frame, if only FPS has changed.
977     // Because if first frame after transition, has a partial Frame-ROI and
978     // is followed by Skip Validate frames, then it can benefit those frames.
979     disble_pu = !display_attributes_.OnlyFpsChanged(display_attributes);
980   }
981 
982   if (disble_pu) {
983     DisablePartialUpdateOneFrame();
984   }
985 
986   display_attributes_ = display_attributes;
987   mixer_attributes_ = mixer_attributes;
988   hw_panel_info_ = hw_panel_info;
989 
990   // TODO(user): Temporary changes, to be removed when DRM driver supports
991   // Partial update with Destination scaler enabled.
992   SetPUonDestScaler();
993 
994   return kErrorNone;
995 }
996 
CanDeferFpsConfig(uint32_t fps)997 bool DisplayBuiltIn::CanDeferFpsConfig(uint32_t fps) {
998   if (deferred_config_.CanApplyDeferredState()) {
999     // Deferred Fps Config needs to be applied.
1000     return false;
1001   }
1002 
1003   // In case of higher to lower Fps transition on a Builtin display, defer the Fps
1004   // (Transfer time) configuration, for the number of frames based on frame_count.
1005   return ((deferred_config_.frame_count != 0) && (display_attributes_.fps > fps));
1006 }
1007 
SetDeferredFpsConfig()1008 void DisplayBuiltIn::SetDeferredFpsConfig() {
1009   // Update with the deferred Fps Config.
1010   display_attributes_.fps = deferred_config_.fps;
1011   display_attributes_.vsync_period_ns = deferred_config_.vsync_period_ns;
1012   hw_panel_info_.transfer_time_us = deferred_config_.transfer_time_us;
1013   deferred_config_.Clear();
1014 }
1015 
GetFpsConfig(HWDisplayAttributes * display_attr,HWPanelInfo * panel_info)1016 void DisplayBuiltIn::GetFpsConfig(HWDisplayAttributes *display_attr, HWPanelInfo *panel_info) {
1017   display_attr->fps = display_attributes_.fps;
1018   display_attr->vsync_period_ns = display_attributes_.vsync_period_ns;
1019   panel_info->transfer_time_us = hw_panel_info_.transfer_time_us;
1020 }
1021 
GetRefreshRate(uint32_t * refresh_rate)1022 DisplayError DisplayBuiltIn::GetRefreshRate(uint32_t *refresh_rate) {
1023   *refresh_rate = current_refresh_rate_;
1024   return kErrorNone;
1025 }
1026 
1027 }  // namespace sdm
1028