sdm: drm: Defer first null commit

Defer first null commit to the first actual draw cycle. This reduces
the duration of blank screen between splash and boot animation.

Change-Id: I192465ba213e19d1abae1128ddbe5ccfab20b217
CRs-fixed: 2106859
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 5051bed..c870597 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -292,6 +292,12 @@
    *      uint32_t - FB Secure mode
    */
   CONNECTOR_SET_FB_SECURE_MODE,
+  /*
+   * Op: Sets a crtc id to this connector
+   * Arg: uint32_t - Connector ID
+   *      uint32_t - CRTC ID
+   */
+  CONNECTOR_SET_CRTC,
 };
 
 enum struct DRMRotation {
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index bb3b71d..aba66c6 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -49,6 +49,7 @@
 ifneq ($(TARGET_IS_HEADLESS), true)
     LOCAL_SRC_FILES           += $(LOCAL_HW_INTF_PATH_2)/hw_info_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
+                                 $(LOCAL_HW_INTF_PATH_2)/hw_peripheral_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_tv_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_scale_drm.cpp \
diff --git a/sdm/libs/core/color_manager.cpp b/sdm/libs/core/color_manager.cpp
index 938ab99..4c33a25 100644
--- a/sdm/libs/core/color_manager.cpp
+++ b/sdm/libs/core/color_manager.cpp
@@ -180,6 +180,12 @@
 }
 
 DisplayError ColorManagerProxy::Commit() {
+  static bool first_cycle = true;
+  if (first_cycle) {
+    first_cycle = false;
+    return kErrorNone;
+  }
+
   Locker &locker(pp_features_.GetLocker());
   SCOPE_LOCK(locker);
 
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index d530052..d67d781 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -329,8 +329,6 @@
                          HWInfoInterface *hw_info_intf)
     : hw_info_intf_(hw_info_intf), buffer_sync_handler_(buffer_sync_handler),
       registry_(buffer_allocator) {
-  disp_type_ = DRMDisplayType::PERIPHERAL;
-  device_name_ = "Peripheral Display";
   hw_info_intf_ = hw_info_intf;
 }
 
@@ -346,31 +344,15 @@
       DLOGE("RegisterDisplay failed for %s", device_name_);
       return kErrorResources;
     }
+
     drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
     drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-    // Commit to setup pipeline with mode, which then tells us the topology etc
-    if (!deferred_initialize_) {
-      drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id,
-                                &connector_info_.modes[current_mode_index_]);
-      drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
-      if (drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/)) {
-        DRM_LOGI("Setting up CRTC %d, Connector %d for %s failed", token_.crtc_id,
-          token_.conn_id, device_name_);
-        return kErrorResources;
-      }
-      // Reload connector info for updated info after 1st commit
-      drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-    }
-    InitializeConfigs();
   } else {
     display_attributes_.push_back(HWDisplayAttributes());
     PopulateDisplayAttributes(current_mode_index_);
   }
-  PopulateHWPanelInfo();
-  UpdateMixerAttributes();
 
   hw_info_intf_->GetHWResourceInfo(&hw_resource_);
-
   // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
   if (hw_resource_.has_qseed3) {
     hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
@@ -714,6 +696,7 @@
     DLOGE("Failed with error: %d", ret);
     return kErrorHardware;
   }
+
   return kErrorNone;
 }
 
@@ -731,6 +714,7 @@
     DLOGE("Failed with error: %d", ret);
     return kErrorHardware;
   }
+
   return kErrorNone;
 }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 67646df..fac9a2e 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -161,7 +161,6 @@
 
  protected:
   const char *device_name_ = {};
-  bool deferred_initialize_ = false;
   bool default_mode_ = false;
   sde_drm::DRMDisplayType disp_type_ = {};
   HWInfoInterface *hw_info_intf_ = {};
@@ -177,6 +176,7 @@
   std::vector<HWDisplayAttributes> display_attributes_ = {};
   uint32_t current_mode_index_ = 0;
   sde_drm::DRMConnectorInfo connector_info_ = {};
+  bool first_cycle_ = true;
 
  private:
   void SetDestScalarData(HWLayersInfo hw_layer_info);
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 6f933eb..c98817a 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -236,7 +236,7 @@
   DLOGI("\tLinear = %d", hw_resource->linear_factor);
   DLOGI("\tScale = %d", hw_resource->scale_factor);
   DLOGI("\tFudge_factor = %d", hw_resource->extra_fudge_factor);
-  DLOGI("\tib_fudge_factor = %d", hw_resource->ib_fudge_factor);
+  DLOGI("\tib_fudge_factor = %f", hw_resource->ib_fudge_factor);
 
   if (hw_resource->separate_rotator || hw_resource->num_dma_pipe) {
     GetHWRotatorInfo(hw_resource);
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
new file mode 100644
index 0000000..95f1524
--- /dev/null
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -0,0 +1,100 @@
+/*
+Copyright (c) 2017, 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:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <utils/debug.h>
+
+#include "hw_peripheral_drm.h"
+
+#define __CLASS__ "HWPeripheralDRM"
+
+using sde_drm::DRMDisplayType;
+using sde_drm::DRMOps;
+using sde_drm::DRMTopology;
+using sde_drm::DRMPowerMode;
+
+namespace sdm {
+
+HWPeripheralDRM::HWPeripheralDRM(BufferSyncHandler *buffer_sync_handler,
+                                 BufferAllocator *buffer_allocator,
+                                 HWInfoInterface *hw_info_intf)
+  : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
+  disp_type_ = DRMDisplayType::PERIPHERAL;
+  device_name_ = "Peripheral Display";
+}
+
+DisplayError HWPeripheralDRM::Init() {
+  DisplayError ret = HWDeviceDRM::Init();
+  if (ret != kErrorNone) {
+    DLOGE("Init failed for %s", device_name_);
+    return ret;
+  }
+
+  if (connector_info_.topology == DRMTopology::UNKNOWN) {
+    connector_info_.topology = DRMTopology::DUAL_LM;
+  }
+
+  InitializeConfigs();
+  PopulateHWPanelInfo();
+  UpdateMixerAttributes();
+
+  return kErrorNone;
+}
+
+DisplayError HWPeripheralDRM::Validate(HWLayers *hw_layers) {
+  // Hijack the first validate to setup pipeline. This is a stopgap solution
+  if (first_cycle_) {
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id,
+                              &connector_info_.modes[current_mode_index_]);
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
+    if (drm_atomic_intf_->Commit(true /* synchronous */, false /* retain pipes*/)) {
+      DLOGE("Setting up CRTC %d, Connector %d for %s failed",
+            token_.crtc_id, token_.conn_id, device_name_);
+      return kErrorResources;
+    }
+    // Reload connector info for updated info after 1st commit
+    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
+    PopulateDisplayAttributes(current_mode_index_);
+    UpdatePanelSplitInfo();
+    first_cycle_ = false;
+  }
+
+  return HWDeviceDRM::Validate(hw_layers);
+}
+
+DisplayError HWPeripheralDRM::PowerOn() {
+  if (first_cycle_) {
+    return kErrorNone;
+  }
+
+  return HWDeviceDRM::PowerOn();
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
new file mode 100644
index 0000000..142580f
--- /dev/null
+++ b/sdm/libs/core/drm/hw_peripheral_drm.h
@@ -0,0 +1,52 @@
+/*
+Copyright (c) 2017, 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:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_PERIPHERAL_DRM_H__
+#define __HW_PERIPHERAL_DRM_H__
+
+#include "hw_device_drm.h"
+
+namespace sdm {
+
+class HWPeripheralDRM : public HWDeviceDRM {
+ public:
+  explicit HWPeripheralDRM(BufferSyncHandler *buffer_sync_handler,
+                           BufferAllocator *buffer_allocator,
+                           HWInfoInterface *hw_info_intf);
+  virtual ~HWPeripheralDRM() {}
+
+ protected:
+  virtual DisplayError Init();
+  virtual DisplayError Validate(HWLayers *hw_layers);
+  virtual DisplayError PowerOn();
+};
+
+}  // namespace sdm
+
+#endif  // __HW_PERIPHERAL_DRM_H__
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index bd9ddc2..e93f065 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -67,35 +67,14 @@
   device_name_ = "TV Display Device";
 }
 
-// TODO(user) : split function in base class and avoid code duplicacy
-// by using base implementation for this basic stuff
 DisplayError HWTVDRM::Init() {
-  DisplayError error = kErrorNone;
-
-  default_mode_ = (DRMLibLoader::GetInstance()->IsLoaded() == false);
-
-  if (!default_mode_) {
-    DRMMaster *drm_master = {};
-    int dev_fd = -1;
-    DRMMaster::GetInstance(&drm_master);
-    drm_master->GetHandle(&dev_fd);
-    DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd, &drm_mgr_intf_);
-    if (drm_mgr_intf_->RegisterDisplay(DRMDisplayType::TV, &token_)) {
-      DLOGE("RegisterDisplay failed");
-      return kErrorResources;
-    }
-
-    drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
-    drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
-    InitializeConfigs();
+  DisplayError error = HWDeviceDRM::Init();
+  if (error != kErrorNone) {
+    DLOGE("Init failed for %s", device_name_);
+    return error;
   }
 
-  hw_info_intf_->GetHWResourceInfo(&hw_resource_);
-
-  // TODO(user): In future, remove has_qseed3 member, add version and pass version to constructor
-  if (hw_resource_.has_qseed3) {
-    hw_scale_ = new HWScaleDRM(HWScaleDRM::Version::V2);
-  }
+  InitializeConfigs();
 
   return error;
 }
@@ -106,6 +85,10 @@
     return kErrorNotSupported;
   }
 
+  if (first_cycle_) {
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
+  }
+
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_MODE, token_.crtc_id, &connector_info_.modes[index]);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
 
@@ -116,15 +99,16 @@
     return kErrorResources;
   }
 
-  // Reload connector info for updated info after 1st commit and validate
+  DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
+  first_cycle_ = false;
+
+  // Reload connector info for updated info after 1st commit
   drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
   if (index >= connector_info_.modes.size()) {
     DLOGE("Invalid mode index %d mode size %d", index, UINT32(connector_info_.modes.size()));
     return kErrorNotSupported;
   }
 
-  DLOGI("Setup CRTC %d, Connector %d for %s", token_.crtc_id, token_.conn_id, device_name_);
-
   current_mode_index_ = index;
   PopulateDisplayAttributes(index);
   PopulateHWPanelInfo();
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
index 176d4ec..8f81f68 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -49,24 +49,15 @@
                            BufferAllocator *buffer_allocator,
                            HWInfoInterface *hw_info_intf)
                            : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
-  HWDeviceDRM::deferred_initialize_ = true;
   HWDeviceDRM::device_name_ = "Virtual Display Device";
-  HWDeviceDRM::hw_info_intf_ = hw_info_intf;
   HWDeviceDRM::disp_type_ = DRMDisplayType::VIRTUAL;
 }
 
 DisplayError HWVirtualDRM::Init() {
   display_attributes_.push_back(HWDisplayAttributes());
-  return kErrorNone;
-}
-
-DisplayError HWVirtualDRM::DeferredInit() {
-  if (HWDeviceDRM::Init() != kErrorNone)
+  if (HWDeviceDRM::Init() != kErrorNone) {
     return kErrorResources;
-
-  drm_mgr_intf_->SetScalerLUT(drm_lut_info_);
-  DLOGI_IF(kTagDriverConfig, "Setup CRTC %d, Connector %d for %s",
-            token_.crtc_id, token_.conn_id, device_name_);
+  }
 
   return kErrorNone;
 }
@@ -79,9 +70,9 @@
 void HWVirtualDRM::ConfigureWbConnectorDestRect() {
   DRMRect dst = {};
   dst.left = 0;
-  dst.bottom = height_;
+  dst.bottom = display_attributes_[0].y_pixels;
   dst.top = 0;
-  dst.right = width_;
+  dst.right = display_attributes_[0].x_pixels;
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_OUTPUT_RECT, token_.conn_id, dst);
   return;
 }
@@ -91,13 +82,13 @@
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_FB_SECURE_MODE, token_.conn_id, secure_mode);
 }
 
-void HWVirtualDRM::InitializeConfigs() {
+DisplayError HWVirtualDRM::InitializeConfig(const HWDisplayAttributes &display_attributes) {
   drmModeModeInfo mode = {};
-  mode.hdisplay = mode.hsync_start = mode.hsync_end = mode.htotal = (uint16_t) width_;
-  mode.vdisplay = mode.vsync_start = mode.vsync_end = mode.vtotal = (uint16_t) height_;
-  // Not sure SF has a way to configure refresh rate. Hardcoding to 60 fps for now.
-  // TODO(user): Make this configurable.
-  mode.vrefresh = 60;
+  mode.hdisplay = mode.hsync_start = mode.hsync_end = mode.htotal =
+    (uint16_t) display_attributes.x_pixels;
+  mode.vdisplay = mode.vsync_start = mode.vsync_end = mode.vtotal =
+    (uint16_t) display_attributes.y_pixels;
+  mode.vrefresh = display_attributes.fps;
   mode.clock = (mode.htotal * mode.vtotal * mode.vrefresh) / 1000;
 
   struct sde_drm_wb_cfg wb_cfg;
@@ -105,11 +96,13 @@
   wb_cfg.flags |= SDE_DRM_WB_CFG_FLAGS_CONNECTED;
   wb_cfg.count_modes = 1;
   wb_cfg.modes = (uint64_t)&mode;
+  int ret = 0;
   #ifdef DRM_IOCTL_SDE_WB_CONFIG
-  int ret = drmIoctl(dev_fd_, DRM_IOCTL_SDE_WB_CONFIG, &wb_cfg);
+  ret = drmIoctl(dev_fd_, DRM_IOCTL_SDE_WB_CONFIG, &wb_cfg);
   #endif
   if (ret) {
     DLOGE("WB config failed\n");
+    return kErrorHardware;
   } else {
     drm_mgr_intf_->GetConnectorInfo(token_.conn_id, &connector_info_);
     DumpConfigs();
@@ -119,11 +112,14 @@
   // display configuration
   if (connector_info_.topology == sde_drm::DRMTopology::UNKNOWN) {
     connector_info_.topology = sde_drm::DRMTopology::SINGLE_LM;
-    if (width_ > hw_resource_.max_mixer_width) {
+    if (display_attributes.x_pixels > hw_resource_.max_mixer_width) {
       connector_info_.topology = sde_drm::DRMTopology::DUAL_LM_MERGE;
     }
   }
-  PopulateDisplayAttributes(current_mode_index_);
+
+  PopulateDisplayAttributes(0);
+
+  return kErrorNone;
 }
 
 void HWVirtualDRM::DumpConfigs() {
@@ -144,6 +140,12 @@
   LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
   DisplayError err = kErrorNone;
 
+  if (first_cycle_) {
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_CRTC, token_.conn_id, token_.crtc_id);
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
+    first_cycle_ = false;
+  }
+
   registry_.RegisterCurrent(hw_layers);
   registry_.MapBufferToFbId(output_buffer);
   uint32_t fb_id = registry_.GetFbId(output_buffer->planes[0].fd);
@@ -167,56 +169,29 @@
     return kErrorParameters;
   }
 
-  uint32_t index = current_mode_index_;
-  width_ = display_attributes.x_pixels;
-  height_ = display_attributes.y_pixels;
-
-  DisplayError error = DeferredInit();
-  if (error != kErrorNone) {
-    width_ = display_attributes_[index].x_pixels;
-    height_ = display_attributes_[index].y_pixels;
-    return error;
+  DisplayError ret = InitializeConfig(display_attributes);
+  if (ret != kErrorNone) {
+    DLOGE("InitializeConfig failed");
+    return ret;
   }
 
-  display_attributes_[index] = display_attributes;
-  if (display_attributes_[index].x_pixels > hw_resource_.max_mixer_width) {
-    display_attributes_[index].is_device_split = true;
-  }
+  PopulateHWPanelInfo();
   UpdateMixerAttributes();
 
   return kErrorNone;
 }
 
 DisplayError HWVirtualDRM::PowerOn() {
-  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);
-  return kErrorNone;
-}
+  if (first_cycle_) {
+    return kErrorNone;
+  }
 
-DisplayError HWVirtualDRM::PowerOff() {
-  drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
-  drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
-  return kErrorNone;
+  return HWDeviceDRM::PowerOn();
 }
 
 DisplayError HWVirtualDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
   return kErrorNone;
 }
 
-DisplayError HWVirtualDRM::SetScaleLutConfig(HWScaleLutInfo *lut_info) {
-  drm_lut_info_.cir_lut = lut_info->cir_lut;
-  drm_lut_info_.dir_lut = lut_info->dir_lut;
-  drm_lut_info_.sep_lut = lut_info->sep_lut;
-  drm_lut_info_.cir_lut_size = lut_info->cir_lut_size;
-  drm_lut_info_.dir_lut_size = lut_info->dir_lut_size;
-  drm_lut_info_.sep_lut_size = lut_info->sep_lut_size;
-
-  // Due to differed Init in WB case, we cannot set scaler config immediately as we
-  // won't have SDE DRM initialized at this point. Hence have to cache LUT info here
-  // and set it in ::DeferredInit
-
-  return kErrorNone;
-}
-
 }  // namespace sdm
 
diff --git a/sdm/libs/core/drm/hw_virtual_drm.h b/sdm/libs/core/drm/hw_virtual_drm.h
index 7fa6c54..5140d12 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.h
+++ b/sdm/libs/core/drm/hw_virtual_drm.h
@@ -46,26 +46,20 @@
     return kErrorNotSupported;
   }
   virtual DisplayError SetDisplayAttributes(const HWDisplayAttributes &display_attributes);
+  virtual DisplayError PowerOn();
 
  protected:
   virtual DisplayError Init();
   virtual DisplayError Validate(HWLayers *hw_layers);
-  virtual DisplayError DeferredInit();
-  virtual void InitializeConfigs();
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
-  virtual DisplayError SetScaleLutConfig(HWScaleLutInfo *lut_info);
-  virtual DisplayError PowerOn();
-  virtual DisplayError PowerOff();
   void ConfigureWbConnectorFbId(uint32_t fb_id);
   void ConfigureWbConnectorDestRect();
   void ConfigureWbConnectorSecureMode(bool secure);
   void DumpConfigs();
 
  private:
-  uint32_t width_ = 0;
-  uint32_t height_ = 0;
-  sde_drm::DRMScalerLUTInfo drm_lut_info_ = {};
+  DisplayError InitializeConfig(const HWDisplayAttributes &display_attributes);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index 2d8d41e..902dcbc 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -35,7 +35,7 @@
 #include "fb/hw_primary.h"
 #include "fb/hw_hdmi.h"
 #include "fb/hw_virtual.h"
-#include "drm/hw_device_drm.h"
+#include "drm/hw_peripheral_drm.h"
 #include "drm/hw_virtual_drm.h"
 #include "drm/hw_tv_drm.h"
 
@@ -55,7 +55,7 @@
       if (driver_type == DriverType::FB) {
         hw = new HWPrimary(buffer_sync_handler, hw_info_intf);
       } else {
-        hw = new HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
+        hw = new HWPeripheralDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
       }
       break;
     case kHDMI: