Home | History | Annotate | Download | only in core
      1 /*
      2 * Copyright (c) 2014 - 2015, 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 
     28 #include "display_primary.h"
     29 #include "hw_interface.h"
     30 #include "hw_info_interface.h"
     31 #include "fb/hw_primary.h"
     32 
     33 #define __CLASS__ "DisplayPrimary"
     34 
     35 namespace sdm {
     36 
     37 DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
     38                                BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
     39                                RotatorInterface *rotator_intf)
     40   : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
     41                 rotator_intf, hw_info_intf) {
     42 }
     43 
     44 DisplayError DisplayPrimary::Init() {
     45   SCOPE_LOCK(locker_);
     46 
     47   DisplayError error = HWPrimary::Create(&hw_intf_, hw_info_intf_,
     48                                          DisplayBase::buffer_sync_handler_, this);
     49 
     50   if (error != kErrorNone) {
     51     return error;
     52   }
     53 
     54   error = DisplayBase::Init();
     55   if (error != kErrorNone) {
     56     HWPrimary::Destroy(hw_intf_);
     57     return error;
     58   }
     59 
     60   idle_timeout_ms_ = Debug::GetIdleTimeoutMs();
     61 
     62   if (hw_panel_info_.mode == kModeCommand && Debug::IsVideoModeEnabled()) {
     63     error = hw_intf_->SetDisplayMode(kModeVideo);
     64     if (error != kErrorNone) {
     65       DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
     66             kModeVideo);
     67     }
     68   }
     69 
     70   return error;
     71 }
     72 
     73 DisplayError DisplayPrimary::Deinit() {
     74   SCOPE_LOCK(locker_);
     75 
     76   DisplayError error = DisplayBase::Deinit();
     77   HWPrimary::Destroy(hw_intf_);
     78 
     79   return error;
     80 }
     81 
     82 DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
     83   SCOPE_LOCK(locker_);
     84   return DisplayBase::Prepare(layer_stack);
     85 }
     86 
     87 DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
     88   SCOPE_LOCK(locker_);
     89   DisplayError error = kErrorNone;
     90   HWPanelInfo panel_info;
     91   HWDisplayAttributes display_attributes;
     92   uint32_t active_index = 0;
     93 
     94   // Enabling auto refresh is async and needs to happen before commit ioctl
     95   if (hw_panel_info_.mode == kModeCommand) {
     96     hw_intf_->SetAutoRefresh(layer_stack->flags.single_buffered_layer_present);
     97   }
     98 
     99   bool set_idle_timeout = comp_manager_->CanSetIdleTimeout(display_comp_ctx_);
    100 
    101   error = DisplayBase::Commit(layer_stack);
    102   if (error != kErrorNone) {
    103     return error;
    104   }
    105 
    106   hw_intf_->GetHWPanelInfo(&panel_info);
    107   hw_intf_->GetActiveConfig(&active_index);
    108   hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
    109 
    110   if (panel_info != hw_panel_info_) {
    111     error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, panel_info);
    112     hw_panel_info_ = panel_info;
    113   }
    114 
    115   if (hw_panel_info_.mode == kModeVideo) {
    116     if (set_idle_timeout && !layer_stack->flags.single_buffered_layer_present) {
    117       hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
    118     } else {
    119       hw_intf_->SetIdleTimeoutMs(0);
    120     }
    121   }
    122 
    123   return error;
    124 }
    125 
    126 DisplayError DisplayPrimary::Flush() {
    127   SCOPE_LOCK(locker_);
    128   return DisplayBase::Flush();
    129 }
    130 
    131 DisplayError DisplayPrimary::GetDisplayState(DisplayState *state) {
    132   SCOPE_LOCK(locker_);
    133   return DisplayBase::GetDisplayState(state);
    134 }
    135 
    136 DisplayError DisplayPrimary::GetNumVariableInfoConfigs(uint32_t *count) {
    137   SCOPE_LOCK(locker_);
    138   return DisplayBase::GetNumVariableInfoConfigs(count);
    139 }
    140 
    141 DisplayError DisplayPrimary::GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info) {
    142   SCOPE_LOCK(locker_);
    143   return DisplayBase::GetConfig(index, variable_info);
    144 }
    145 
    146 DisplayError DisplayPrimary::GetActiveConfig(uint32_t *index) {
    147   SCOPE_LOCK(locker_);
    148   return DisplayBase::GetActiveConfig(index);
    149 }
    150 
    151 DisplayError DisplayPrimary::GetVSyncState(bool *enabled) {
    152   SCOPE_LOCK(locker_);
    153   return DisplayBase::GetVSyncState(enabled);
    154 }
    155 
    156 bool DisplayPrimary::IsUnderscanSupported() {
    157   SCOPE_LOCK(locker_);
    158   return DisplayBase::IsUnderscanSupported();
    159 }
    160 
    161 DisplayError DisplayPrimary::SetDisplayState(DisplayState state) {
    162   SCOPE_LOCK(locker_);
    163   DisplayError error = kErrorNone;
    164   error = DisplayBase::SetDisplayState(state);
    165   if (error != kErrorNone) {
    166     return error;
    167   }
    168 
    169   // Set vsync enable state to false, as driver disables vsync during display power off.
    170   if (state == kStateOff) {
    171     vsync_enable_ = false;
    172   }
    173 
    174   return kErrorNone;
    175 }
    176 
    177 DisplayError DisplayPrimary::SetActiveConfig(DisplayConfigVariableInfo *variable_info) {
    178   SCOPE_LOCK(locker_);
    179   return kErrorNotSupported;
    180 }
    181 
    182 DisplayError DisplayPrimary::SetActiveConfig(uint32_t index) {
    183   SCOPE_LOCK(locker_);
    184   return DisplayBase::SetActiveConfig(index);
    185 }
    186 
    187 DisplayError DisplayPrimary::SetVSyncState(bool enable) {
    188   SCOPE_LOCK(locker_);
    189   DisplayError error = kErrorNone;
    190   if (vsync_enable_ != enable) {
    191     error = hw_intf_->SetVSyncState(enable);
    192     if (error == kErrorNone) {
    193       vsync_enable_ = enable;
    194     }
    195   }
    196 
    197   return error;
    198 }
    199 
    200 void DisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
    201   SCOPE_LOCK(locker_);
    202 
    203   // Idle fallback feature is supported only for video mode panel.
    204   if (hw_panel_info_.mode == kModeVideo) {
    205     hw_intf_->SetIdleTimeoutMs(timeout_ms);
    206   }
    207   idle_timeout_ms_ = timeout_ms;
    208 }
    209 
    210 DisplayError DisplayPrimary::SetMaxMixerStages(uint32_t max_mixer_stages) {
    211   SCOPE_LOCK(locker_);
    212   return DisplayBase::SetMaxMixerStages(max_mixer_stages);
    213 }
    214 
    215 DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
    216   SCOPE_LOCK(locker_);
    217   DisplayError error = kErrorNone;
    218   HWDisplayMode hw_display_mode = kModeDefault;
    219 
    220   if (!active_) {
    221     DLOGW("Invalid display state = %d. Panel must be on.", state_);
    222     return kErrorNotSupported;
    223   }
    224 
    225   switch (mode) {
    226   case kModeVideo:
    227     hw_display_mode = kModeVideo;
    228     break;
    229   case kModeCommand:
    230     hw_display_mode = kModeCommand;
    231     break;
    232   default:
    233     DLOGW("Invalid panel mode parameters. Requested = %d", mode);
    234     return kErrorParameters;
    235   }
    236 
    237   if (hw_display_mode == hw_panel_info_.mode) {
    238     DLOGW("Same display mode requested. Current = %d, Requested = %d", hw_panel_info_.mode,
    239           hw_display_mode);
    240     return kErrorNone;
    241   }
    242 
    243   error = hw_intf_->SetDisplayMode(hw_display_mode);
    244   if (error != kErrorNone) {
    245     DLOGW("Retaining current display mode. Current = %d, Requested = %d", hw_panel_info_.mode,
    246           hw_display_mode);
    247     return error;
    248   }
    249 
    250   // Disable PU if the previous PU state is on when switching to video mode, and re-enable PU when
    251   // switching back to command mode.
    252   bool toggle_partial_update = !(hw_display_mode == kModeVideo);
    253   if (partial_update_control_) {
    254     comp_manager_->ControlPartialUpdate(display_comp_ctx_, toggle_partial_update);
    255   }
    256 
    257   if (hw_display_mode == kModeVideo) {
    258     hw_intf_->SetIdleTimeoutMs(idle_timeout_ms_);
    259   } else if (hw_display_mode == kModeCommand) {
    260     hw_intf_->SetIdleTimeoutMs(0);
    261   }
    262 
    263   return error;
    264 }
    265 
    266 DisplayError DisplayPrimary::SetPanelBrightness(int level) {
    267   SCOPE_LOCK(locker_);
    268   return hw_intf_->SetPanelBrightness(level);
    269 }
    270 
    271 DisplayError DisplayPrimary::IsScalingValid(const LayerRect &crop, const LayerRect &dst,
    272                                             bool rotate90) {
    273   SCOPE_LOCK(locker_);
    274   return DisplayBase::IsScalingValid(crop, dst, rotate90);
    275 }
    276 
    277 DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
    278                                                  uint32_t *max_refresh_rate) {
    279   SCOPE_LOCK(locker_);
    280   DisplayError error = kErrorNone;
    281 
    282   if (hw_panel_info_.min_fps && hw_panel_info_.max_fps) {
    283     *min_refresh_rate = hw_panel_info_.min_fps;
    284     *max_refresh_rate = hw_panel_info_.max_fps;
    285   } else {
    286     error = DisplayBase::GetRefreshRateRange(min_refresh_rate, max_refresh_rate);
    287   }
    288 
    289   return error;
    290 }
    291 
    292 DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate) {
    293   SCOPE_LOCK(locker_);
    294 
    295   if (!active_ || !hw_panel_info_.dynamic_fps) {
    296     return kErrorNotSupported;
    297   }
    298 
    299   if (refresh_rate < hw_panel_info_.min_fps || refresh_rate > hw_panel_info_.max_fps) {
    300     DLOGE("Invalid Fps = %d request", refresh_rate);
    301     return kErrorParameters;
    302   }
    303 
    304   DisplayError error = hw_intf_->SetRefreshRate(refresh_rate);
    305   if (error != kErrorNone) {
    306     return error;
    307   }
    308 
    309   HWDisplayAttributes display_attributes;
    310   uint32_t active_index = 0;
    311   error = hw_intf_->GetActiveConfig(&active_index);
    312   if (error != kErrorNone) {
    313     return error;
    314   }
    315 
    316   error = hw_intf_->GetDisplayAttributes(active_index, &display_attributes);
    317   if (error != kErrorNone) {
    318     return error;
    319   }
    320 
    321   comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes, hw_panel_info_);
    322 
    323   return kErrorNone;
    324 }
    325 
    326 void DisplayPrimary::AppendDump(char *buffer, uint32_t length) {
    327   SCOPE_LOCK(locker_);
    328   DisplayBase::AppendDump(buffer, length);
    329 }
    330 
    331 DisplayError DisplayPrimary::VSync(int64_t timestamp) {
    332   if (vsync_enable_) {
    333     DisplayEventVSync vsync;
    334     vsync.timestamp = timestamp;
    335     event_handler_->VSync(vsync);
    336   }
    337 
    338   return kErrorNone;
    339 }
    340 
    341 DisplayError DisplayPrimary::SetCursorPosition(int x, int y) {
    342   SCOPE_LOCK(locker_);
    343   return DisplayBase::SetCursorPosition(x, y);
    344 }
    345 
    346 DisplayError DisplayPrimary::Blank(bool blank) {
    347   SCOPE_LOCK(locker_);
    348   return kErrorNone;
    349 }
    350 
    351 void DisplayPrimary::IdleTimeout() {
    352   event_handler_->Refresh();
    353   comp_manager_->ProcessIdleTimeout(display_comp_ctx_);
    354 }
    355 
    356 void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
    357   SCOPE_LOCK(locker_);
    358   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
    359 }
    360 
    361 DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
    362   SCOPE_LOCK(locker_);
    363   return hw_intf_->GetPanelBrightness(level);
    364 }
    365 
    366 }  // namespace sdm
    367 
    368