sdm: Fix to defer the first power on to first commit

Defer the first power on to first commit and enable the pending vsync
after the cirst commit.

Change-Id: Ic45951d1983a088e71e4eb82db86032f94df137d
diff --git a/include/display_properties.h b/include/display_properties.h
index cd3fbf2..d0868a2 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2018 - 2020 The Linux Foundation. All rights reserved.
+* Copyright (c) 2018 - 2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -121,7 +121,6 @@
 #define VIRTUAL_BASEID_AND_SIZE_PROP         DISPLAY_PROP("virtual_baseid_and_size")
 #define ENABLE_QDCM_DIAG                     DISPLAY_PROP("enable_qdcm_diag")
 #define QDCM_DISABLE_FACTORY_MODE_PROP       DISPLAY_PROP("qdcm.disable_factory_mode")
-#define DISABLE_DEFER_POWER_STATE            DISPLAY_PROP("disable_defer_power_state")
 
 #define ZERO_SWAP_INTERVAL                   "vendor.debug.egl.swapinterval"
 #define ENABLE_OPTIMIZE_REFRESH              DISPLAY_PROP("enable_optimize_refresh")
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index bbc7fd5..75f6136 100755
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -283,17 +283,10 @@
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   needs_validate_ = true;
-  if (defer_power_state_ && power_state_pending_ != kStateOff) {
-    defer_power_state_ = false;
-    error = SetDisplayState(power_state_pending_, false, NULL);
-    if (error != kErrorNone) {
-      return error;
-    }
-    power_state_pending_ = kStateOff;
-  }
 
   DTRACE_SCOPED();
-  if (!active_) {
+  // Allow prepare as pending doze/pending_power_on is handled as a part of draw cycle
+  if (!active_ && !pending_doze_ && !pending_power_on_) {
     return kErrorPermission;
   }
 
@@ -357,7 +350,8 @@
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
 
-  if (!active_) {
+  // Allow commit as pending doze/pending_power_on is handled as a part of draw cycle
+  if (!active_ && !pending_doze_ && !pending_power_on_) {
     needs_validate_ = true;
     return kErrorPermission;
   }
@@ -433,8 +427,8 @@
     safe_mode_in_fast_path_ = false;
   }
 
-  // Reset pending doze if any after the commit
-  error = ResetPendingDoze(layer_stack->retire_fence_fd);
+  // Reset pending power state if any after the commit
+  error = HandlePendingPowerState(layer_stack->retire_fence_fd);
   if (error != kErrorNone) {
     return error;
   }
@@ -545,14 +539,6 @@
 DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown,
                                           int *release_fence) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
-  if (defer_power_state_) {
-    if (state == kStateOff) {
-      DLOGE("State cannot be PowerOff on first cycle");
-      return kErrorParameters;
-    }
-    power_state_pending_ = state;
-    return kErrorNone;
-  }
   DisplayError error = kErrorNone;
   bool active = false;
 
@@ -584,7 +570,12 @@
   case kStateOn:
     error = hw_intf_->PowerOn(default_qos_data_, release_fence);
     if (error != kErrorNone) {
-      return error;
+      if (error == kErrorDeferred) {
+        pending_power_on_ = true;
+        error = kErrorNone;
+      } else {
+        return error;
+      }
     }
 
     error = comp_manager_->ReconfigureDisplay(display_comp_ctx_, display_attributes_,
@@ -599,9 +590,13 @@
 
   case kStateDoze:
     error = hw_intf_->Doze(default_qos_data_, release_fence);
-    if (error == kErrorDeferred) {
-      pending_doze_ = true;
-      error = kErrorNone;
+    if (error != kErrorNone) {
+      if (error == kErrorDeferred) {
+        pending_doze_ = true;
+        error = kErrorNone;
+      } else {
+        return error;
+      }
     }
     active = true;
     break;
@@ -625,9 +620,21 @@
   DisablePartialUpdateOneFrame();
 
   if (error == kErrorNone) {
-    active_ = active;
-    state_ = state;
+    if (!pending_doze_ && !pending_power_on_) {
+      active_ = active;
+      state_ = state;
+    }
     comp_manager_->SetDisplayState(display_comp_ctx_, state, release_fence ? *release_fence : -1);
+    // If previously requested doze state is still pending reset it on any new display state request
+    // and handle the new request.
+    if (state != kStateDoze) {
+      pending_doze_ = false;
+    }
+    // If previously requested power on state is still pending reset it on any new display state
+    // request and handle the new request.
+    if (state != kStateOn) {
+      pending_power_on_ = false;
+    }
   }
 
   // Handle vsync pending on resume, Since the power on commit is synchronous we pass -1 as retire
@@ -1167,10 +1174,9 @@
 DisplayError DisplayBase::SetVSyncState(bool enable) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
-  if ((state_ == kStateOff || pending_doze_) && enable) {
-    DLOGW("Can't enable vsync when power state is off or doze pending for display %d-%d," \
-          "Defer it when display is active state %d pending_doze_ %d", display_id_, display_type_,
-          state_, pending_doze_);
+  if (state_ == kStateOff && enable) {
+    DLOGW("Can't enable vsync when display %d-%d is powered off!! Defer it when display is active",
+          display_id_, display_type_);
     vsync_enable_pending_ = true;
     return kErrorNone;
   }
@@ -1992,13 +1998,22 @@
   return;
 }
 
-DisplayError DisplayBase::ResetPendingDoze(int32_t retire_fence) {
-  if (pending_doze_) {
+DisplayError DisplayBase::HandlePendingPowerState(int32_t retire_fence) {
+  if (pending_doze_ || pending_power_on_) {
     // Retire fence signalling confirms that CRTC enabled, hence wait for retire fence before
     // we enable vsync
     buffer_sync_handler_->SyncWait(retire_fence);
 
+    if (pending_doze_) {
+      state_ = kStateDoze;
+    }
+    if (pending_power_on_) {
+      state_ = kStateOn;
+    }
+    active_ = true;
+
     pending_doze_ = false;
+    pending_power_on_ = false;
   }
   return kErrorNone;
 }
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 8f3172d..d18d4a4 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -184,7 +184,7 @@
   bool IsHdrMode(const AttrVal &attr);
   void InsertBT2020PqHlgModes();
   DisplayError HandlePendingVSyncEnable(int32_t retire_fence);
-  DisplayError ResetPendingDoze(int32_t retire_fence);
+  DisplayError HandlePendingPowerState(int32_t retire_fence);
 
   recursive_mutex recursive_mutex_;
   int32_t display_id_ = -1;
@@ -234,13 +234,12 @@
   uint32_t current_refresh_rate_ = 0;
   bool drop_skewed_vsync_ = false;
   bool custom_mixer_resolution_ = false;
-  DisplayState power_state_pending_ = kStateOff;
   bool vsync_enable_pending_ = false;
-  bool defer_power_state_ = false;
   QSyncMode qsync_mode_ = kQSyncModeNone;
   bool needs_avr_update_ = false;
   bool safe_mode_in_fast_path_ = false;
   bool pending_doze_ = false;
+  bool pending_power_on_ = false;
 
   static Locker display_power_reset_lock_;
   static bool display_power_reset_pending_;
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 07030da..5ab5e51 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -60,7 +60,6 @@
 
 DisplayError DisplayBuiltIn::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
-  int32_t disable_defer_power_state = 0;
 
   DisplayError error = HWInterface::Create(display_id_, kBuiltIn, hw_info_intf_,
                                            buffer_sync_handler_, buffer_allocator_, &hw_intf_);
@@ -116,10 +115,6 @@
 
   current_refresh_rate_ = hw_panel_info_.max_fps;
 
-  Debug::GetProperty(DISABLE_DEFER_POWER_STATE, &disable_defer_power_state);
-  defer_power_state_ = !disable_defer_power_state;
-  DLOGI("defer_power_state %d", defer_power_state_);
-
   int value = 0;
   Debug::Get()->GetProperty(DEFER_FPS_FRAME_COUNT, &value);
   deferred_config_.frame_count = (value > 0) ? UINT32(value) : 0;
@@ -296,6 +291,10 @@
     vsync_enable_ = false;
   }
 
+  if (pending_doze_ || pending_power_on_) {
+    event_handler_->Refresh();
+  }
+
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/display_pluggable.cpp b/sdm/libs/core/display_pluggable.cpp
index 4e184e8..06a34ac 100644
--- a/sdm/libs/core/display_pluggable.cpp
+++ b/sdm/libs/core/display_pluggable.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -130,12 +130,6 @@
 
   current_refresh_rate_ = hw_panel_info_.max_fps;
 
-  if (IsPrimaryDisplay()) {
-    int32_t disable_defer_power_state = 0;
-    Debug::GetProperty(DISABLE_DEFER_POWER_STATE, &disable_defer_power_state);
-    defer_power_state_ = !disable_defer_power_state;
-  }
-
   return error;
 }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index b0c3e91..e8cea73 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -909,13 +909,7 @@
   SetQOSData(qos_data);
 
   int64_t release_fence_t = -1;
-  update_mode_ = true;
 
-  if (first_cycle_) {
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
-    drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
-    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
-  }
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
   if (release_fence) {
@@ -1290,19 +1284,17 @@
                               topology_control_);
     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
-    DRMPowerMode power_mode = pending_doze_ ? DRMPowerMode::DOZE : DRMPowerMode::ON;
-    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, power_mode);
-    last_power_mode_ = power_mode;
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
+    last_power_mode_ = DRMPowerMode::ON;
   } else if (pending_doze_ && !validate) {
     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
     drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::DOZE);
-    pending_doze_ = false;
     synchronous_commit_ = true;
     last_power_mode_ = DRMPowerMode::DOZE;
   }
 
   // Set CRTC mode, only if display config changes
-  if (vrefresh_ || update_mode_ || panel_mode_changed_) {
+  if (first_cycle_ || vrefresh_ || update_mode_ || panel_mode_changed_) {
     drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
   }
 
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index faee43b..64109ec 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -460,8 +460,9 @@
   }
 
   if (first_cycle_) {
-    return kErrorNone;
+    return kErrorDeferred;
   }
+
   if (!idle_pc_enabled_) {
     drm_atomic_intf_->Perform(sde_drm::DRMOps::CRTC_SET_IDLE_PC_STATE, token_.crtc_id,
                               sde_drm::DRMIdlePCState::ENABLE);
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 94a0810..dfe481f 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -360,6 +360,12 @@
     return kErrorUndefined;
   }
 
+  if (first_cycle_) {
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
+    drmModeModeInfo current_mode = connector_info_.modes[current_mode_index_].mode;
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &current_mode);
+  }
+
   return HWDeviceDRM::PowerOn(qos_data, release_fence);
 }
 
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index ed21fee..45bce77 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1098,9 +1098,7 @@
 
   hwc_session->UpdateThrottlingRate();
 
-  // Trigger refresh for doze mode to take effect.
   if (mode == HWC2::PowerMode::Doze) {
-    hwc_session->Refresh(display);
     // Trigger one more refresh for PP features to take effect.
     hwc_session->pending_refresh_.set(UINT32(display));
   } else {