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