1/*
2* Copyright (c) 2014 - 2017, 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
37#define __CLASS__ "DisplayPrimary"
38
39namespace sdm {
40
41DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
42                               BufferSyncHandler *buffer_sync_handler,
43                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
44  : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, buffer_allocator,
45                comp_manager, hw_info_intf) {
46}
47
48DisplayError DisplayPrimary::Init() {
49  lock_guard<recursive_mutex> obj(recursive_mutex_);
50
51  DisplayError error = HWInterface::Create(kPrimary, hw_info_intf_, buffer_sync_handler_,
52                                           buffer_allocator_, &hw_intf_);
53  if (error != kErrorNone) {
54    return error;
55  }
56
57  error = DisplayBase::Init();
58  if (error != kErrorNone) {
59    HWInterface::Destroy(hw_intf_);
60    return error;
61  }
62
63  if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
64    error = hw_intf_->SetDisplayMode(kModeVideo);
65    if (error != kErrorNone) {
66      DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
67            kModeVideo);
68    }
69  }
70
71  avr_prop_disabled_ = Debug::IsAVRDisabled();
72
73  error = HWEventsInterface::Create(INT(display_type_), this, event_list_, &hw_events_intf_);
74  if (error != kErrorNone) {
75    DLOGE("Failed to create hardware events interface. Error = %d", error);
76    DisplayBase::Deinit();
77    HWInterface::Destroy(hw_intf_);
78  }
79
80  return error;
81}
82
83DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
84  lock_guard<recursive_mutex> obj(recursive_mutex_);
85  DisplayError error = kErrorNone;
86  uint32_t new_mixer_width = 0;
87  uint32_t new_mixer_height = 0;
88  uint32_t display_width = display_attributes_.x_pixels;
89  uint32_t display_height = display_attributes_.y_pixels;
90
91  if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
92    error = ReconfigureMixer(new_mixer_width, new_mixer_height);
93    if (error != kErrorNone) {
94      ReconfigureMixer(display_width, display_height);
95    }
96  }
97
98  // Clean hw layers for reuse.
99  hw_layers_ = HWLayers();
100  hw_layers_.hw_avr_info.enable = NeedsAVREnable();
101
102  return DisplayBase::Prepare(layer_stack);
103}
104
105DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
106  lock_guard<recursive_mutex> obj(recursive_mutex_);
107  DisplayError error = kErrorNone;
108  uint32_t app_layer_count = hw_layers_.info.app_layer_count;
109
110  // Enabling auto refresh is async and needs to happen before commit ioctl
111  if (hw_panel_info_.mode == kModeCommand) {
112    bool enable = (app_layer_count == 1) && layer_stack->flags.single_buffered_layer_present;
113    bool need_refresh = layer_stack->flags.single_buffered_layer_present && (app_layer_count > 1);
114
115    hw_intf_->SetAutoRefresh(enable);
116    if (need_refresh) {
117      event_handler_->Refresh();
118    }
119  }
120
121  error = DisplayBase::Commit(layer_stack);
122  if (error != kErrorNone) {
123    return error;
124  }
125
126  DisplayBase::ReconfigureDisplay();
127
128  int idle_time_ms = hw_layers_.info.set_idle_time_ms;
129  if (idle_time_ms >= 0) {
130    hw_intf_->SetIdleTimeoutMs(UINT32(idle_time_ms));
131  }
132
133  if (switch_to_cmd_) {
134    uint32_t pending;
135    switch_to_cmd_ = false;
136    ControlPartialUpdate(true /* enable */, &pending);
137  }
138
139  return error;
140}
141
142DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
143  lock_guard<recursive_mutex> obj(recursive_mutex_);
144  DisplayError error = kErrorNone;
145  error = DisplayBase::SetDisplayState(state);
146  if (error != kErrorNone) {
147    return error;
148  }
149
150  // Set vsync enable state to false, as driver disables vsync during display power off.
151  if (state == kStateOff) {
152    vsync_enable_ = false;
153  }
154
155  return kErrorNone;
156}
157
158void DisplayPrimary::SetIdleTimeoutMs(uint32_t active_ms) {
159  lock_guard<recursive_mutex> obj(recursive_mutex_);
160
161  if (comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms) == kErrorNone) {
162    hw_intf_->SetIdleTimeoutMs(active_ms);
163  }
164}
165
166DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
167  DisplayError error = kErrorNone;
168
169  // Limit scope of mutex to this block
170  {
171    lock_guard<recursive_mutex> obj(recursive_mutex_);
172    HWDisplayMode hw_display_mode = static_cast<HWDisplayMode>(mode);
173    uint32_t pending = 0;
174
175    if (!active_) {
176      DLOGW("Invalid display state = %d. Panel must be on.", state_);
177      return kErrorNotSupported;
178    }
179
180    if (hw_display_mode != kModeCommand && hw_display_mode != kModeVideo) {
181      DLOGW("Invalid panel mode parameters. Requested = %d", hw_display_mode);
182      return kErrorParameters;
183    }
184
185    if (hw_display_mode == hw_panel_info_.mode) {
186      DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
187            hw_display_mode);
188      return kErrorNone;
189    }
190
191    error = hw_intf_->SetDisplayMode(hw_display_mode);
192    if (error != kErrorNone) {
193      DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
194            hw_display_mode);
195      return error;
196    }
197
198    if (mode == kModeVideo) {
199      ControlPartialUpdate(false /* enable */, &pending);
200    } else if (mode == kModeCommand) {
201      // Flush idle timeout value currently set.
202      hw_intf_->SetIdleTimeoutMs(0);
203      switch_to_cmd_ = true;
204    }
205  }
206
207  // Request for a new draw cycle. New display mode will get applied on next draw cycle.
208  // New idle time will get configured as part of this.
209  event_handler_->Refresh();
210
211  return error;
212}
213
214DisplayError DisplayPrimary::SetPanelBrightness(int level) {
215  lock_guard<recursive_mutex> obj(recursive_mutex_);
216  return hw_intf_->SetPanelBrightness(level);
217}
218
219DisplayError DisplayPrimary::CachePanelBrightness(int level) {
220  lock_guard<recursive_mutex> obj(recursive_mutex_);
221  return hw_intf_->CachePanelBrightness(level);
222}
223
224DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
225                                                 uint32_t *max_refresh_rate) {
226  lock_guard<recursive_mutex> obj(recursive_mutex_);
227  DisplayError error = kErrorNone;
228
229  if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
230    *min_refresh_rate = hw_panel_info_.min_fps;
231    *max_refresh_rate = hw_panel_info_.max_fps;
232  } else {
233    error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
234  }
235
236  return error;
237}
238
239DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
240  lock_guard<recursive_mutex> obj(recursive_mutex_);
241
242  if (!active_ || !hw_panel_info_.dynamic_fps) {
243    return kErrorNotSupported;
244  }
245
246  if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
247    DLOGE("Invalid Fps = %d request", refresh_rate);
248    return kErrorParameters;
249  }
250
251  DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
252  if (error != kErrorNone) {
253    return error;
254  }
255
256  return DisplayBase::ReconfigureDisplay();
257}
258
259DisplayError DisplayPrimary::VSync(int64_t timestamp) {
260  if (vsync_enable_) {
261    DisplayEventVSync vsync;
262    vsync.timestamp = timestamp;
263    event_handler_->VSync(vsync);
264  }
265
266  return kErrorNone;
267}
268
269void DisplayPrimary::IdleTimeout() {
270  event_handler_->Refresh();
271  comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
272  event_handler_->HandleEvent(kIdleTimeout);
273}
274
275void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
276  lock_guard<recursive_mutex> obj(recursive_mutex_);
277  comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
278  event_handler_->HandleEvent(kThermalEvent);
279}
280
281void DisplayPrimary::IdlePowerCollapse() {
282  lock_guard<recursive_mutex> obj(recursive_mutex_);
283  comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
284}
285
286DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
287  lock_guard<recursive_mutex> obj(recursive_mutex_);
288  return hw_intf_->GetPanelBrightness(level);
289}
290
291DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
292  lock_guard<recursive_mutex> obj(recursive_mutex_);
293  if (!pending) {
294    return kErrorParameters;
295  }
296
297  if (!hw_panel_info_.partial_update) {
298    // Nothing to be done.
299    DLOGI("partial update is not applicable for display=%d", display_type_);
300    return kErrorNotSupported;
301  }
302
303  *pending = 0;
304  if (enable == partial_update_control_) {
305    DLOGI("Same state transition is requested.");
306    return kErrorNone;
307  }
308
309  partial_update_control_ = enable;
310
311  if (!enable) {
312    // If the request is to turn off feature, new draw call is required to have
313    // the new setting into effect.
314    *pending = 1;
315  }
316
317  return kErrorNone;
318}
319
320DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
321  lock_guard<recursive_mutex> obj(recursive_mutex_);
322  disable_pu_one_frame_ = true;
323
324  return kErrorNone;
325}
326
327bool DisplayPrimary::NeedsAVREnable() {
328  if (avr_prop_disabled_) {
329    return false;
330  }
331
332  return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
333          hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
334          hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
335}
336
337}  // namespace sdm
338
339