Merge "sde: resource: rotator yuv downscaling output alignment"
diff --git a/Android.mk b/Android.mk
index 5070911..6baef4a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,4 +1,4 @@
-ifeq ($(call is-board-platform-in-list, thulium),true)
+ifeq ($(call is-board-platform-in-list, msm8996),true)
     TARGET_USES_SDE = true
 else
     TARGET_USES_SDE = false
diff --git a/displayengine/include/private/hw_info_types.h b/displayengine/include/private/hw_info_types.h
new file mode 100644
index 0000000..d842167
--- /dev/null
+++ b/displayengine/include/private/hw_info_types.h
@@ -0,0 +1,134 @@
+/*
+* Copyright (c) 2015, 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.
+*/
+
+/*! @file hw_info_types.h
+    @brief Definitions for types that contain information pertaining to hardware devices.
+*/
+
+#ifndef __HW_INFO_TYPES_H__
+#define __HW_INFO_TYPES_H__
+
+#include <stdint.h>
+#include <core/sde_types.h>
+
+namespace sde {
+
+/*! @brief This enumeration holds the possible hardware device types. */
+enum HWDeviceType {
+  kDevicePrimary,
+  kDeviceHDMI,
+  kDeviceVirtual,
+  kDeviceRotator,
+  kDeviceMax,
+};
+
+/*! @brief This structure is a representation of hardware capabilities of the target device display
+  driver.
+*/
+struct HWResourceInfo {
+  uint32_t hw_version;
+  uint32_t hw_revision;
+  uint32_t num_dma_pipe;
+  uint32_t num_vig_pipe;
+  uint32_t num_rgb_pipe;
+  uint32_t num_cursor_pipe;
+  uint32_t num_blending_stages;
+  uint32_t num_rotator;
+  uint32_t num_control;
+  uint32_t num_mixer_to_disp;
+  uint32_t smp_total;
+  uint32_t smp_size;
+  uint32_t num_smp_per_pipe;
+  uint32_t max_scale_up;
+  uint32_t max_scale_down;
+  uint64_t max_bandwidth_low;
+  uint64_t max_bandwidth_high;
+  uint32_t max_mixer_width;
+  uint32_t max_pipe_bw;
+  uint32_t max_sde_clk;
+  float clk_fudge_factor;
+  bool has_bwc;
+  bool has_decimation;
+  bool has_macrotile;
+  bool has_rotator_downscale;
+  bool has_non_scalar_rgb;
+  bool is_src_split;
+
+  HWResourceInfo()
+    : hw_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0), num_rgb_pipe(0),
+      num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
+      num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
+      max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
+      max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
+      has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
+      has_non_scalar_rgb(false), is_src_split(false) { }
+
+  void Reset() { *this = HWResourceInfo(); }
+};
+
+/*! @brief This enumeration holds the all possible panel types. */
+enum HWPanelType {
+  kNoPanel,
+  kCommandModePanel,
+  kVideoModePanel,
+  kDTvPanel,
+  kWriteBackPanel,
+  kLVDSPanel,
+  kEDPPanel,
+};
+
+/*! @brief This structure describes the split configuration of a display panel. */
+struct HWSplitInfo {
+  uint32_t left_split;
+  uint32_t right_split;
+  bool always_src_split;
+  HWSplitInfo() : left_split(0), right_split(0), always_src_split(false) { }
+};
+
+/*! @brief This structure describes properties of a display panel. */
+struct HWPanelInfo {
+  HWPanelType type;        //!< Panel type
+  bool partial_update;     //!< Partial update feature
+  int left_align;          //!< ROI left alignment restriction
+  int width_align;         //!< ROI width alignment restriction
+  int top_align;;          //!< ROI top alignment restriction
+  int height_align;        //!< ROI height alignment restriction
+  int min_roi_width;       //!< Min width needed for ROI
+  int min_roi_height;      //!< Min height needed for ROI
+  bool needs_roi_merge;    //!< Merge ROI's of both the DSI's
+  bool dynamic_fps;        //!< Panel Supports dynamic fps
+  uint32_t min_fps;        //!< Min fps supported by panel
+  uint32_t max_fps;        //!< Max fps supported by panel
+  bool is_primary_panel;   //!< Panel is primary display
+  HWSplitInfo split_info;  //!< Panel split configuration
+
+  HWPanelInfo() : type(kNoPanel), partial_update(false), left_align(false), width_align(false),
+    top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
+    needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
+};
+
+}  // namespace sde
+
+#endif  // __HW_INFO_TYPES_H__
+
diff --git a/displayengine/libs/core/Android.mk b/displayengine/libs/core/Android.mk
index b7d2478..5623283 100644
--- a/displayengine/libs/core/Android.mk
+++ b/displayengine/libs/core/Android.mk
@@ -12,6 +12,7 @@
   LOCAL_C_INCLUDES  += $(TARGET_OUT_HEADERS)/scalar/inc
   LOCAL_CFLAGS      += -DUSES_SCALAR
 endif
+LOCAL_HW_INTF_PATH := fb
 LOCAL_SHARED_LIBRARIES        := libdl libsdeutils libcutils
 LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
 LOCAL_SRC_FILES               := core_interface.cpp \
@@ -25,10 +26,14 @@
                                  res_manager.cpp \
                                  res_config.cpp \
                                  offline_ctrl.cpp \
-                                 hw_interface.cpp \
-                                 hw_framebuffer.cpp \
                                  dump_impl.cpp \
                                  buffer_manager.cpp \
-                                 scalar_helper.cpp
+                                 scalar_helper.cpp \
+                                 $(LOCAL_HW_INTF_PATH)/hw_info.cpp \
+                                 $(LOCAL_HW_INTF_PATH)/hw_device.cpp \
+                                 $(LOCAL_HW_INTF_PATH)/hw_primary.cpp \
+                                 $(LOCAL_HW_INTF_PATH)/hw_rotator.cpp \
+                                 $(LOCAL_HW_INTF_PATH)/hw_hdmi.cpp \
+                                 $(LOCAL_HW_INTF_PATH)/hw_virtual.cpp
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/displayengine/libs/core/core_impl.cpp b/displayengine/libs/core/core_impl.cpp
index bd6ab9a..2732889 100644
--- a/displayengine/libs/core/core_impl.cpp
+++ b/displayengine/libs/core/core_impl.cpp
@@ -30,6 +30,7 @@
 #include "display_primary.h"
 #include "display_hdmi.h"
 #include "display_virtual.h"
+#include "hw_info_interface.h"
 
 #define __CLASS__ "CoreImpl"
 
@@ -38,40 +39,50 @@
 CoreImpl::CoreImpl(CoreEventHandler *event_handler, BufferAllocator *buffer_allocator,
                    BufferSyncHandler *buffer_sync_handler)
   : event_handler_(event_handler), buffer_allocator_(buffer_allocator),
-    buffer_sync_handler_(buffer_sync_handler), hw_intf_(NULL) {
+    buffer_sync_handler_(buffer_sync_handler), hw_resource_(NULL) {
 }
 
 DisplayError CoreImpl::Init() {
   SCOPE_LOCK(locker_);
-
   DisplayError error = kErrorNone;
 
-  error = HWInterface::Create(&hw_intf_, buffer_sync_handler_);
-  if (UNLIKELY(error != kErrorNone)) {
+  error = HWInfoInterface::Create(&hw_info_intf_);
+  if (error != kErrorNone) {
     return error;
   }
 
-  HWResourceInfo hw_res_info;
-  error = hw_intf_->GetHWCapabilities(&hw_res_info);
-  if (UNLIKELY(error != kErrorNone)) {
-    HWInterface::Destroy(hw_intf_);
-    return error;
+  hw_resource_ = new HWResourceInfo();
+  if (!hw_resource_) {
+    error = kErrorMemory;
+    goto CleanUpOnError;
   }
 
-  error = comp_mgr_.Init(hw_res_info, buffer_allocator_, buffer_sync_handler_);
-  if (UNLIKELY(error != kErrorNone)) {
-    HWInterface::Destroy(hw_intf_);
-    return error;
+  error = hw_info_intf_->GetHWResourceInfo(hw_resource_);
+  if (error != kErrorNone) {
+    goto CleanUpOnError;
   }
 
-  error = offline_ctrl_.Init(hw_intf_, hw_res_info);
-  if (UNLIKELY(error != kErrorNone)) {
+  error = comp_mgr_.Init(*hw_resource_, buffer_allocator_, buffer_sync_handler_);
+  if (error != kErrorNone) {
     comp_mgr_.Deinit();
-    HWInterface::Destroy(hw_intf_);
-    return error;
+    goto CleanUpOnError;
   }
 
+  error = offline_ctrl_.Init(buffer_sync_handler_);
+  if (error != kErrorNone) {
+    goto CleanUpOnError;
+  }
   return kErrorNone;
+
+CleanUpOnError:
+  if (hw_resource_) {
+    delete hw_resource_;
+    hw_resource_ = NULL;
+  }
+
+  HWInfoInterface::Destroy(hw_info_intf_);
+
+  return error;
 }
 
 DisplayError CoreImpl::Deinit() {
@@ -79,7 +90,7 @@
 
   offline_ctrl_.Deinit();
   comp_mgr_.Deinit();
-  HWInterface::Destroy(hw_intf_);
+  HWInfoInterface::Destroy(hw_info_intf_);
 
   return kErrorNone;
 }
@@ -88,24 +99,25 @@
                                      DisplayInterface **intf) {
   SCOPE_LOCK(locker_);
 
-  if (UNLIKELY(!event_handler || !intf)) {
+  if (!event_handler || !intf) {
     return kErrorParameters;
   }
 
   DisplayBase *display_base = NULL;
+
   switch (type) {
   case kPrimary:
-    display_base = new DisplayPrimary(event_handler, hw_intf_, &comp_mgr_, &offline_ctrl_);
+    display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
+                                      &comp_mgr_, &offline_ctrl_);
     break;
-
   case kHDMI:
-    display_base = new DisplayHDMI(event_handler, hw_intf_, &comp_mgr_, &offline_ctrl_);
+    display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
+                                   &comp_mgr_, &offline_ctrl_);
     break;
-
   case kVirtual:
-    display_base = new DisplayVirtual(event_handler, hw_intf_, &comp_mgr_, &offline_ctrl_);
+    display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
+                                      &comp_mgr_, &offline_ctrl_);
     break;
-
   default:
     DLOGE("Spurious display type %d", type);
     return kErrorParameters;
@@ -116,7 +128,8 @@
   }
 
   DisplayError error = display_base->Init();
-  if (UNLIKELY(error != kErrorNone)) {
+  if (error != kErrorNone) {
+    display_base->Deinit();
     delete display_base;
     display_base = NULL;
     return error;
@@ -129,7 +142,7 @@
 DisplayError CoreImpl::DestroyDisplay(DisplayInterface *intf) {
   SCOPE_LOCK(locker_);
 
-  if (UNLIKELY(!intf)) {
+  if (!intf) {
     return kErrorParameters;
   }
 
diff --git a/displayengine/libs/core/core_impl.h b/displayengine/libs/core/core_impl.h
index e289a23..03733a8 100644
--- a/displayengine/libs/core/core_impl.h
+++ b/displayengine/libs/core/core_impl.h
@@ -37,6 +37,8 @@
 
 namespace sde {
 
+class HWInfoInterface;
+
 class CoreImpl : public CoreInterface {
  public:
   // This class implements display core interface revision 1.0.
@@ -62,9 +64,10 @@
   CoreEventHandler *event_handler_;
   BufferAllocator *buffer_allocator_;
   BufferSyncHandler *buffer_sync_handler_;
-  HWInterface *hw_intf_;
+  HWResourceInfo *hw_resource_;
   CompManager comp_mgr_;
   OfflineCtrl offline_ctrl_;
+  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index 8bfc6dd..b61d3a6 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -34,28 +34,30 @@
 
 // TODO(user): Have a single structure handle carries all the interface pointers and variables.
 DisplayBase::DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
-                         HWDeviceType hw_device_type, HWInterface *hw_intf,
+                         HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
                          CompManager *comp_manager, OfflineCtrl *offline_ctrl)
   : display_type_(display_type), event_handler_(event_handler), hw_device_type_(hw_device_type),
-    hw_intf_(hw_intf), comp_manager_(comp_manager), offline_ctrl_(offline_ctrl), state_(kStateOff),
-    hw_device_(0), display_comp_ctx_(0), display_attributes_(NULL), num_modes_(0),
-    active_mode_index_(0), pending_commit_(false), vsync_enable_(false) {
+    buffer_sync_handler_(buffer_sync_handler), comp_manager_(comp_manager),
+    offline_ctrl_(offline_ctrl), state_(kStateOff), hw_device_(0), display_comp_ctx_(0),
+    display_attributes_(NULL), num_modes_(0), active_mode_index_(0), pending_commit_(false),
+    vsync_enable_(false) {
 }
 
 DisplayError DisplayBase::Init() {
-  SCOPE_LOCK(locker_);
-
   DisplayError error = kErrorNone;
 
-  error = hw_intf_->Open(hw_device_type_, &hw_device_, this);
+  error = hw_intf_->Open(this);
   if (error != kErrorNone) {
     return error;
   }
 
-  // Set the idle timeout value to driver through sysfs node
-  hw_intf_->SetIdleTimeoutMs(hw_device_, Debug::GetIdleTimeoutMs());
+  panel_info_ = HWPanelInfo();
+  hw_intf_->GetHWPanelInfo(&panel_info_);
 
-  error = hw_intf_->GetNumDisplayAttributes(hw_device_, &num_modes_);
+  // Set the idle timeout value to driver through sysfs node
+  SetIdleTimeoutMs(Debug::GetIdleTimeoutMs());
+
+  error = hw_intf_->GetNumDisplayAttributes(&num_modes_);
   if (error != kErrorNone) {
     goto CleanupOnError;
   }
@@ -67,7 +69,7 @@
   }
 
   for (uint32_t i = 0; i < num_modes_; i++) {
-    error = hw_intf_->GetDisplayAttributes(hw_device_, &display_attributes_[i], i);
+    error = hw_intf_->GetDisplayAttributes(&display_attributes_[i], i);
     if (error != kErrorNone) {
       goto CleanupOnError;
     }
@@ -75,7 +77,7 @@
 
   active_mode_index_ = GetBestConfig();
 
-  error = hw_intf_->SetDisplayAttributes(hw_device_, active_mode_index_);
+  error = hw_intf_->SetDisplayAttributes(active_mode_index_);
   if (error != kErrorNone) {
     goto CleanupOnError;
   }
@@ -103,14 +105,12 @@
     display_attributes_ = NULL;
   }
 
-  hw_intf_->Close(hw_device_);
+  hw_intf_->Close();
 
   return error;
 }
 
 DisplayError DisplayBase::Deinit() {
-  SCOPE_LOCK(locker_);
-
   offline_ctrl_->UnregisterDisplay(display_offline_ctx_);
 
   comp_manager_->UnregisterDisplay(display_comp_ctx_);
@@ -120,7 +120,7 @@
     display_attributes_ = NULL;
   }
 
-  hw_intf_->Close(hw_device_);
+  hw_intf_->Close();
 
   return kErrorNone;
 }
@@ -150,7 +150,7 @@
 
       error = offline_ctrl_->Prepare(display_offline_ctx_, &hw_layers_);
       if (error == kErrorNone) {
-        error = hw_intf_->Validate(hw_device_, &hw_layers_);
+        error = hw_intf_->Validate(&hw_layers_);
         if (error == kErrorNone) {
           // Strategy is successful now, wait for Commit().
           pending_commit_ = true;
@@ -183,7 +183,7 @@
 
     error = offline_ctrl_->Commit(display_offline_ctx_, &hw_layers_);
     if (error == kErrorNone) {
-      error = hw_intf_->Commit(hw_device_, &hw_layers_);
+      error = hw_intf_->Commit(&hw_layers_);
       if (error == kErrorNone) {
         error = comp_manager_->PostCommit(display_comp_ctx_, &hw_layers_);
         if (error != kErrorNone) {
@@ -212,7 +212,7 @@
   }
 
   hw_layers_.info.count = 0;
-  error = hw_intf_->Flush(hw_device_);
+  error = hw_intf_->Flush();
   if (error == kErrorNone) {
     comp_manager_->Purge(display_comp_ctx_);
     pending_commit_ = false;
@@ -305,24 +305,24 @@
   switch (state) {
   case kStateOff:
     hw_layers_.info.count = 0;
-    error = hw_intf_->Flush(hw_device_);
+    error = hw_intf_->Flush();
     if (error == kErrorNone) {
       comp_manager_->Purge(display_comp_ctx_);
 
-      error = hw_intf_->PowerOff(hw_device_);
+      error = hw_intf_->PowerOff();
     }
     break;
 
   case kStateOn:
-    error = hw_intf_->PowerOn(hw_device_);
+    error = hw_intf_->PowerOn();
     break;
 
   case kStateDoze:
-    error = hw_intf_->Doze(hw_device_);
+    error = hw_intf_->Doze();
     break;
 
   case kStateStandby:
-    error = hw_intf_->Standby(hw_device_);
+    error = hw_intf_->Standby();
     break;
 
   default:
@@ -375,7 +375,7 @@
     return kErrorParameters;
   }
 
-  error = hw_intf_->SetDisplayAttributes(hw_device_, index);
+  error = hw_intf_->SetDisplayAttributes(index);
   if (error != kErrorNone) {
     return error;
   }
@@ -393,21 +393,10 @@
 }
 
 DisplayError DisplayBase::SetVSyncState(bool enable) {
-  SCOPE_LOCK(locker_);
-  DisplayError error = kErrorNone;
-  if (vsync_enable_ != enable) {
-    error = hw_intf_->SetVSyncState(hw_device_, enable);
-    if (error == kErrorNone) {
-      vsync_enable_ = enable;
-    }
-  }
-
-  return error;
+  return kErrorNotSupported;
 }
 
-void DisplayBase::SetIdleTimeoutMs(uint32_t timeout_ms) {
-  hw_intf_->SetIdleTimeoutMs(hw_device_, timeout_ms);
-}
+void DisplayBase::SetIdleTimeoutMs(uint32_t timeout_ms) { }
 
 DisplayError DisplayBase::SetMaxMixerStages(uint32_t max_mixer_stages) {
   SCOPE_LOCK(locker_);
diff --git a/displayengine/libs/core/display_base.h b/displayengine/libs/core/display_base.h
index 10e11f8..51b0ac3 100644
--- a/displayengine/libs/core/display_base.h
+++ b/displayengine/libs/core/display_base.h
@@ -41,8 +41,8 @@
 class DisplayBase : public DisplayInterface, HWEventHandler, DumpImpl {
  public:
   DisplayBase(DisplayType display_type, DisplayEventHandler *event_handler,
-              HWDeviceType hw_device_type, HWInterface *hw_intf, CompManager *comp_manager,
-              OfflineCtrl *offline_ctrl);
+              HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
+              CompManager *comp_manager, OfflineCtrl *offline_ctrl);
   virtual ~DisplayBase() { }
   virtual DisplayError Init();
   virtual DisplayError Deinit();
@@ -79,6 +79,8 @@
   DisplayEventHandler *event_handler_;
   HWDeviceType hw_device_type_;
   HWInterface *hw_intf_;
+  HWPanelInfo panel_info_;
+  BufferSyncHandler *buffer_sync_handler_;
   CompManager *comp_manager_;
   OfflineCtrl *offline_ctrl_;
   DisplayState state_;
diff --git a/displayengine/libs/core/display_hdmi.cpp b/displayengine/libs/core/display_hdmi.cpp
index ed2a859..045c06c 100644
--- a/displayengine/libs/core/display_hdmi.cpp
+++ b/displayengine/libs/core/display_hdmi.cpp
@@ -26,14 +26,49 @@
 #include <utils/debug.h>
 
 #include "display_hdmi.h"
+#include "hw_hdmi_interface.h"
+#include "hw_info_interface.h"
 
 #define __CLASS__ "DisplayHDMI"
 
 namespace sde {
 
-DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInterface *hw_intf,
-                         CompManager *comp_manager, OfflineCtrl *offline_ctrl)
-  : DisplayBase(kHDMI, event_handler, kDeviceHDMI, hw_intf, comp_manager, offline_ctrl) { }
+DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+                         BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
+                         OfflineCtrl *offline_ctrl)
+  : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, comp_manager,
+                offline_ctrl), hw_info_intf_(hw_info_intf) {
+}
+
+DisplayError DisplayHDMI::Init() {
+  SCOPE_LOCK(locker_);
+
+  DisplayError error = HWHDMIInterface::Create(&hw_hdmi_intf_, hw_info_intf_,
+                                               DisplayBase::buffer_sync_handler_);
+  if (error != kErrorNone) {
+    return error;
+  }
+  DisplayBase::hw_intf_ = hw_hdmi_intf_;
+
+  error = DisplayBase::Init();
+  if (error != kErrorNone) {
+    HWHDMIInterface::Destroy(hw_hdmi_intf_);
+  }
+
+  return error;
+}
+
+DisplayError DisplayHDMI::Deinit() {
+  SCOPE_LOCK(locker_);
+
+  DisplayError error = DisplayBase::Deinit();
+  if (error != kErrorNone) {
+    return error;
+  }
+  HWHDMIInterface::Destroy(hw_hdmi_intf_);
+
+  return error;
+}
 
 int DisplayHDMI::GetBestConfig() {
   uint32_t best_config_mode = 0;
@@ -68,7 +103,7 @@
   if (user_config) {
     uint32_t config_index = -1;
     // For the config, get the corresponding index
-    DisplayError error = hw_intf_->GetConfigIndex(hw_device_, user_config, &config_index);
+    DisplayError error = hw_intf_->GetConfigIndex(user_config, &config_index);
     if (error == kErrorNone)
       return config_index;
   }
diff --git a/displayengine/libs/core/display_hdmi.h b/displayengine/libs/core/display_hdmi.h
index 91e4797..506329b 100644
--- a/displayengine/libs/core/display_hdmi.h
+++ b/displayengine/libs/core/display_hdmi.h
@@ -29,11 +29,21 @@
 
 namespace sde {
 
+class HWHDMIInterface;
+class HWInfoInterface;
+
 class DisplayHDMI : public DisplayBase {
  public:
-  DisplayHDMI(DisplayEventHandler *event_handler, HWInterface *hw_intf, CompManager *comp_manager,
+  DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+              BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
               OfflineCtrl *offline_ctrl);
+  virtual DisplayError Init();
+  virtual DisplayError Deinit();
   virtual int GetBestConfig();
+
+ private:
+  HWHDMIInterface *hw_hdmi_intf_;
+  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/core/display_primary.cpp b/displayengine/libs/core/display_primary.cpp
index 8eed8ee..55e927c 100644
--- a/displayengine/libs/core/display_primary.cpp
+++ b/displayengine/libs/core/display_primary.cpp
@@ -26,14 +26,71 @@
 #include <utils/debug.h>
 
 #include "display_primary.h"
+#include "hw_primary_interface.h"
+#include "hw_info_interface.h"
 
 #define __CLASS__ "DisplayPrimary"
 
 namespace sde {
 
-DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInterface *hw_intf,
-                               CompManager *comp_manager, OfflineCtrl *offline_ctrl)
-  : DisplayBase(kPrimary, event_handler, kDevicePrimary, hw_intf, comp_manager, offline_ctrl) { }
+DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+                               BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
+                               OfflineCtrl *offline_ctrl)
+  : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, comp_manager,
+    offline_ctrl), hw_info_intf_(hw_info_intf) {
+}
+
+DisplayError DisplayPrimary::Init() {
+  SCOPE_LOCK(locker_);
+
+  DisplayError error = HWPrimaryInterface::Create(&hw_primary_intf_, hw_info_intf_,
+                                                  DisplayBase::buffer_sync_handler_);
+  if (error != kErrorNone) {
+    return error;
+  }
+  DisplayBase::hw_intf_ = hw_primary_intf_;
+
+  error = DisplayBase::Init();
+  if (error != kErrorNone) {
+    HWPrimaryInterface::Destroy(hw_primary_intf_);
+  }
+
+  return error;
+}
+
+DisplayError DisplayPrimary::Deinit() {
+  SCOPE_LOCK(locker_);
+
+  DisplayError error = DisplayBase::Deinit();
+  if (error != kErrorNone) {
+    return error;
+  }
+  HWPrimaryInterface::Destroy(hw_primary_intf_);
+
+  return error;
+}
+
+DisplayError DisplayPrimary::SetVSyncState(bool enable) {
+  SCOPE_LOCK(locker_);
+  DisplayError error = kErrorNone;
+  if (vsync_enable_ != enable) {
+    error = hw_primary_intf_->SetVSyncState(enable);
+    if (error == kErrorNone) {
+      vsync_enable_ = enable;
+    }
+  }
+
+  return error;
+}
+
+void DisplayPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
+  // Idle fallback feature is supported only for video mode panel.
+  if (panel_info_.type == kCommandModePanel) {
+    return;
+  }
+
+  hw_primary_intf_->SetIdleTimeoutMs(timeout_ms);
+}
 
 }  // namespace sde
 
diff --git a/displayengine/libs/core/display_primary.h b/displayengine/libs/core/display_primary.h
index ea4cf2b..76fbb06 100644
--- a/displayengine/libs/core/display_primary.h
+++ b/displayengine/libs/core/display_primary.h
@@ -29,10 +29,22 @@
 
 namespace sde {
 
+class HWPrimaryInterface;
+class HWInfoInterface;
+
 class DisplayPrimary : public DisplayBase {
  public:
-  DisplayPrimary(DisplayEventHandler *event_handler, HWInterface *hw_intf,
-                 CompManager *comp_manager, OfflineCtrl *offline_ctrl);
+  DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+                 BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
+                 OfflineCtrl *offline_ctrl);
+  virtual DisplayError Init();
+  virtual DisplayError Deinit();
+  virtual DisplayError SetVSyncState(bool enable);
+  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+
+ private:
+  HWPrimaryInterface *hw_primary_intf_;
+  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/core/display_virtual.cpp b/displayengine/libs/core/display_virtual.cpp
index 84a825f..359e6a3 100644
--- a/displayengine/libs/core/display_virtual.cpp
+++ b/displayengine/libs/core/display_virtual.cpp
@@ -26,14 +26,49 @@
 #include <utils/debug.h>
 
 #include "display_virtual.h"
+#include "hw_virtual_interface.h"
+#include "hw_info_interface.h"
 
 #define __CLASS__ "DisplayVirtual"
 
 namespace sde {
 
-DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInterface *hw_intf,
-                               CompManager *comp_manager, OfflineCtrl *offline_ctrl)
-  : DisplayBase(kVirtual, event_handler, kDeviceVirtual, hw_intf, comp_manager, offline_ctrl) { }
+DisplayVirtual::DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+                               BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
+                               OfflineCtrl *offline_ctrl)
+  : DisplayBase(kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler, comp_manager,
+                offline_ctrl), hw_info_intf_(hw_info_intf) {
+}
+
+DisplayError DisplayVirtual::Init() {
+  SCOPE_LOCK(locker_);
+
+  DisplayError error = HWVirtualInterface::Create(&hw_virtual_intf_, hw_info_intf_,
+                                                  DisplayBase::buffer_sync_handler_);
+  if (error != kErrorNone) {
+    return error;
+  }
+  DisplayBase::hw_intf_ = hw_virtual_intf_;
+
+  error = DisplayBase::Init();
+  if (error != kErrorNone) {
+    HWVirtualInterface::Destroy(hw_virtual_intf_);
+  }
+
+  return error;
+}
+
+DisplayError DisplayVirtual::Deinit() {
+  SCOPE_LOCK(locker_);
+
+  DisplayError error = DisplayBase::Deinit();
+  if (error != kErrorNone) {
+    return error;
+  }
+  HWVirtualInterface::Destroy(hw_virtual_intf_);
+
+  return error;
+}
 
 }  // namespace sde
 
diff --git a/displayengine/libs/core/display_virtual.h b/displayengine/libs/core/display_virtual.h
index 9697702..7dee9fa 100644
--- a/displayengine/libs/core/display_virtual.h
+++ b/displayengine/libs/core/display_virtual.h
@@ -29,10 +29,20 @@
 
 namespace sde {
 
+class HWVirtualInterface;
+class HWInfoInterface;
+
 class DisplayVirtual : public DisplayBase {
  public:
-  DisplayVirtual(DisplayEventHandler *event_handler, HWInterface *hw_intf,
-                 CompManager *comp_manager, OfflineCtrl *offline_ctrl);
+  DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+                 BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
+                 OfflineCtrl *offline_ctrl);
+  virtual DisplayError Init();
+  virtual DisplayError Deinit();
+
+ private:
+  HWVirtualInterface *hw_virtual_intf_;
+  HWInfoInterface *hw_info_intf_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/core/fb/hw_device.cpp b/displayengine/libs/core/fb/hw_device.cpp
new file mode 100644
index 0000000..ed19d80
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_device.cpp
@@ -0,0 +1,817 @@
+/*
+* Copyright (c) 2014 - 2015, 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.
+*/
+
+#define __STDC_FORMAT_MACROS
+#include <ctype.h>
+#include <math.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+
+#include "hw_device.h"
+#include "scalar_helper.h"
+
+#define __CLASS__ "HWDevice"
+
+#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
+extern int virtual_ioctl(int fd, int cmd, ...);
+extern int virtual_open(const char *file_name, int access, ...);
+extern int virtual_close(int fd);
+extern int virtual_poll(struct pollfd *fds,  nfds_t num, int timeout);
+extern ssize_t virtual_pread(int fd, void *data, size_t count, off_t offset);
+extern ssize_t virtual_pwrite(int fd, const void *data, size_t count, off_t offset);
+extern FILE* virtual_fopen(const char *fname, const char *mode);
+extern int virtual_fclose(FILE* fileptr);
+extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
+
+#endif
+
+namespace sde {
+
+HWDevice::HWDevice(BufferSyncHandler *buffer_sync_handler)
+  : fb_node_index_(-1), fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false),
+    buffer_sync_handler_(buffer_sync_handler) {
+  // Pointer to actual driver interfaces.
+  ioctl_ = ::ioctl;
+  open_ = ::open;
+  close_ = ::close;
+  poll_ = ::poll;
+  pread_ = ::pread;
+  pwrite_ = ::pwrite;
+  fopen_ = ::fopen;
+  fclose_ = ::fclose;
+  getline_ = ::getline;
+
+#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
+  // If debug property to use virtual driver is set, point to virtual driver interfaces.
+  if (Debug::IsVirtualDriver()) {
+    ioctl_ = virtual_ioctl;
+    open_ = virtual_open;
+    close_ = virtual_close;
+    poll_ = virtual_poll;
+    pread_ = virtual_pread;
+    pwrite_ = virtual_pwrite;
+    fopen_ = virtual_fopen;
+    fclose_ = virtual_fclose;
+    getline_ = virtual_getline;
+  }
+#endif
+}
+
+DisplayError HWDevice::Init() {
+  DisplayError error = kErrorNone;
+
+  // Read the fb node index
+  fb_node_index_ = GetFBNodeIndex(device_type_);
+  if (fb_node_index_ == -1) {
+    DLOGE("%s should be present", device_name_);
+    return kErrorHardware;
+  }
+
+  // Populate Panel Info (Used for Partial Update)
+  PopulateHWPanelInfo();
+  // Populate HW Capabilities
+  hw_resource_ = HWResourceInfo();
+  hw_info_intf_->GetHWResourceInfo(&hw_resource_);
+
+  return error;
+}
+
+DisplayError HWDevice::Open(HWEventHandler *eventhandler) {
+  DisplayError error = kErrorNone;
+
+  char device_name[64] = {0};
+
+  // Store EventHandlers for two Physical displays, i.e., Primary and HDMI
+  // TODO(user): Need to revisit for HDMI as Primary usecase
+  event_handler_ = eventhandler;
+  snprintf(device_name, sizeof(device_name), "%s%d", "/dev/graphics/fb", fb_node_index_);
+
+  device_fd_ = open_(device_name, O_RDWR);
+  if (device_fd_ < 0) {
+    DLOGE("open %s failed err = %d errstr = %s", device_name, errno,  strerror(errno));
+    return kErrorResources;
+  }
+
+  return error;
+}
+
+DisplayError HWDevice::Close() {
+  if (device_fd_ > 0) {
+    close_(device_fd_);
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWDevice::GetNumDisplayAttributes(uint32_t *count) {
+  *count = 1;
+  return kErrorNone;
+}
+
+DisplayError HWDevice::GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                                 uint32_t index) {
+  return kErrorNone;
+}
+
+DisplayError HWDevice::GetHWPanelInfo(HWPanelInfo *panel_info) {
+  *panel_info = panel_info_;
+  return kErrorNone;
+}
+
+DisplayError HWDevice::SetDisplayAttributes(uint32_t index) {
+  return kErrorNone;
+}
+
+DisplayError HWDevice::GetConfigIndex(uint32_t mode, uint32_t *index) {
+  return kErrorNone;
+}
+
+
+DisplayError HWDevice::PowerOn() {
+  DTRACE_SCOPED();
+
+  if (ioctl_(device_fd_, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
+    IOCTL_LOGE(FB_BLANK_UNBLANK, device_type_);
+    return kErrorHardware;
+  }
+
+  // Need to turn on HPD
+  if (!hotplug_enabled_) {
+    hotplug_enabled_ = EnableHotPlugDetection(1);
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWDevice::PowerOff() {
+  return kErrorNone;
+}
+
+DisplayError HWDevice::Doze() {
+  return kErrorNone;
+}
+
+DisplayError HWDevice::Standby() {
+  return kErrorNone;
+}
+
+DisplayError HWDevice::Validate(HWLayers *hw_layers) {
+  DTRACE_SCOPED();
+
+  DisplayError error = kErrorNone;
+  ResetDisplayParams();
+
+  HWLayersInfo &hw_layer_info = hw_layers->info;
+  LayerStack *stack = hw_layer_info.stack;
+
+  DLOGV_IF(kTagDriverConfig, "************************** %s Validate Input ***********************",
+           device_name_);
+  DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_info.count);
+
+  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+  uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
+
+  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+    uint32_t layer_index = hw_layer_info.index[i];
+    Layer &layer = stack->layers[layer_index];
+    LayerBuffer *input_buffer = layer.input_buffer;
+    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
+    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
+    mdp_input_layer mdp_layer;
+
+    for (uint32_t count = 0; count < 2; count++) {
+      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
+      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
+
+      if (rotate_info->valid) {
+        input_buffer = &rotate_info->hw_buffer_info.output_buffer;
+      }
+
+      if (pipe_info->valid) {
+        mdp_input_layer &mdp_layer = mdp_in_layers_[mdp_layer_count];
+        mdp_layer_buffer &mdp_buffer = mdp_layer.buffer;
+
+        mdp_buffer.width = input_buffer->width;
+        mdp_buffer.height = input_buffer->height;
+
+        error = SetFormat(input_buffer->format, &mdp_buffer.format);
+        if (error != kErrorNone) {
+          return error;
+        }
+
+        mdp_layer.alpha = layer.plane_alpha;
+        mdp_layer.z_order = UINT16(pipe_info->z_order);
+        mdp_layer.transp_mask = 0xffffffff;
+        SetBlending(layer.blending, &mdp_layer.blend_op);
+        mdp_layer.pipe_ndx = pipe_info->pipe_id;
+        mdp_layer.horz_deci = pipe_info->horizontal_decimation;
+        mdp_layer.vert_deci = pipe_info->vertical_decimation;
+
+        SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
+        SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
+
+        // Flips will be taken care by rotator, if layer requires 90 rotation. So Dont use MDP for
+        // flip operation, if layer transform is 90.
+        if (!layer.transform.rotation) {
+          if (layer.transform.flip_vertical) {
+            mdp_layer.flags |= MDP_LAYER_FLIP_UD;
+          }
+
+          if (layer.transform.flip_horizontal) {
+            mdp_layer.flags |= MDP_LAYER_FLIP_LR;
+          }
+        }
+
+        mdp_scale_data* mdp_scale = GetScaleDataRef(mdp_layer_count);
+#ifdef USES_SCALAR
+        // Set the configured scale data for MDP driver
+        ScalarHelper::GetInstance()->SetScaleData(i, !count, mdp_scale);
+        if (mdp_scale->enable_pxl_ext) {
+          if ((mdp_layer.flags & MDP_LAYER_DEINTERLACE) && (layer.transform.rotation == 90.0f))
+            ScalarHelper::GetInstance()->UpdateSrcWidth(i, !count, &mdp_buffer.width);
+        }
+#endif
+        mdp_layer.scale = mdp_scale;
+
+        mdp_layer_count++;
+
+        DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
+                 i, count ? "Right" : "Left");
+        DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d", mdp_buffer.width, mdp_buffer.height,
+                 mdp_buffer.format);
+        DLOGV_IF(kTagDriverConfig, "plane_alpha %d, zorder %d, blending %d, horz_deci %d, "
+                 "vert_deci %d", mdp_layer.alpha, mdp_layer.z_order, mdp_layer.blend_op,
+                 mdp_layer.horz_deci, mdp_layer.vert_deci);
+        DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_layer.src_rect.x,
+                 mdp_layer.src_rect.y, mdp_layer.src_rect.w, mdp_layer.src_rect.h);
+        DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_layer.dst_rect.x,
+                 mdp_layer.dst_rect.y, mdp_layer.dst_rect.w, mdp_layer.dst_rect.h);
+        for (int j = 0; j < MAX_PLANES; j++) {
+          DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
+                 j, mdp_layer.scale->init_phase_x[j], mdp_layer.scale->phase_step_x[j],
+                 mdp_layer.scale->init_phase_y[j], mdp_layer.scale->phase_step_y[j],
+                 mdp_layer.scale->num_ext_pxls_left[j], mdp_layer.scale->num_ext_pxls_top[j],
+                 mdp_layer.scale->num_ext_pxls_right[j], mdp_layer.scale->num_ext_pxls_btm[j]);
+          DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d]  Repeat=[%d %d %d %d]  roi_width = %d",
+                 mdp_layer.scale->left_ftch[j], mdp_layer.scale->top_ftch[j],
+                 mdp_layer.scale->right_ftch[j], mdp_layer.scale->btm_ftch[j],
+                 mdp_layer.scale->left_rpt[j], mdp_layer.scale->top_rpt[j],
+                 mdp_layer.scale->right_rpt[j], mdp_layer.scale->btm_rpt[j],
+                 mdp_layer.scale->roi_w[j]);
+        }
+        DLOGV_IF(kTagDriverConfig, "*************************************************************");
+      }
+    }
+  }
+
+  if (device_type_ == kDeviceVirtual) {
+    LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
+    // TODO(user): Need to assign the writeback id from the resource manager, since the support
+    // has not been added hard coding it to 2 for now.
+    mdp_out_layer_.writeback_ndx = 2;
+    mdp_out_layer_.buffer.width = output_buffer->width;
+    mdp_out_layer_.buffer.height = output_buffer->height;
+    SetFormat(output_buffer->format, &mdp_out_layer_.buffer.format);
+
+    DLOGI_IF(kTagDriverConfig, "******************* Output buffer Info **********************");
+    DLOGI_IF(kTagDriverConfig, "out_w %d, out_h %d, out_f %d, wb_id %d",
+             mdp_out_layer_.buffer.width, mdp_out_layer_.buffer.height,
+             mdp_out_layer_.buffer.format, mdp_out_layer_.writeback_ndx);
+    DLOGI_IF(kTagDriverConfig, "*************************************************************");
+  }
+
+  mdp_commit.flags |= MDP_VALIDATE_LAYER;
+  if (ioctl_(device_fd_, MSMFB_ATOMIC_COMMIT, &mdp_disp_commit_) < 0) {
+    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
+    DumpLayerCommit(mdp_disp_commit_);
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+void HWDevice::DumpLayerCommit(mdp_layer_commit &layer_commit) {
+  mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
+  mdp_input_layer *mdp_layers = mdp_commit.input_layers;
+
+  DLOGE("mdp_commt: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
+  DLOGE("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
+         mdp_commit.left_roi.w, mdp_commit.left_roi.h);
+  DLOGE("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
+         mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
+  for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
+    DLOGE("mdp_commt: layer_cnt = %d, pipe_ndx = %x, zorder = %d, flags = %x",
+          i, mdp_layers[i].pipe_ndx, mdp_layers[i].z_order, mdp_layers[i].flags);
+    mdp_rect &src_rect = mdp_layers[i].src_rect;
+    DLOGE("src rect: x = %d, y = %d, w = %d, h = %d",
+          src_rect.x, src_rect.y, src_rect.w, src_rect.h);
+    mdp_rect &dst_rect = mdp_layers[i].dst_rect;
+    DLOGE("dst rect: x = %d, y = %d, w = %d, h = %d",
+          dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
+  }
+}
+
+DisplayError HWDevice::Commit(HWLayers *hw_layers) {
+  DTRACE_SCOPED();
+
+  HWLayersInfo &hw_layer_info = hw_layers->info;
+  LayerStack *stack = hw_layer_info.stack;
+
+  DLOGV_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
+           device_name_);
+  DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_info.count);
+
+  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+  uint32_t mdp_layer_index = 0;
+
+  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+    uint32_t layer_index = hw_layer_info.index[i];
+    LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
+    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
+    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
+
+    for (uint32_t count = 0; count < 2; count++) {
+      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
+      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
+
+      if (rotate_info->valid) {
+        input_buffer = &rotate_info->hw_buffer_info.output_buffer;
+      }
+
+      if (pipe_info->valid) {
+        mdp_layer_buffer &mdp_buffer = mdp_in_layers_[mdp_layer_index].buffer;
+        mdp_input_layer &mdp_layer = mdp_in_layers_[mdp_layer_index];
+        if (input_buffer->planes[0].fd >= 0) {
+          mdp_buffer.plane_count = 1;
+          mdp_buffer.planes[0].fd = input_buffer->planes[0].fd;
+          mdp_buffer.planes[0].offset = input_buffer->planes[0].offset;
+          SetStride(device_type_, input_buffer->format, input_buffer->planes[0].stride,
+                    &mdp_buffer.planes[0].stride);
+        } else {
+          DLOGW("Invalid buffer fd, setting plane count to 0");
+          mdp_buffer.plane_count = 0;
+        }
+
+        mdp_buffer.fence = input_buffer->acquire_fence_fd;
+        mdp_layer_index++;
+
+        DLOGV_IF(kTagDriverConfig, "****************** Layer[%d] %s pipe Input *******************",
+                 i, count ? "Right" : "Left");
+        DLOGI_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d, horz_deci %d, vert_deci %d",
+                 mdp_buffer.width, mdp_buffer.height, mdp_buffer.format, mdp_layer.horz_deci,
+                 mdp_layer.vert_deci);
+        DLOGI_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_buf_stride %d, " \
+                 "in_plane_count %d, in_fence %d, layer count %d", mdp_buffer.planes[0].fd,
+                 mdp_buffer.planes[0].offset, mdp_buffer.planes[0].stride, mdp_buffer.plane_count,
+                 mdp_buffer.fence, mdp_commit.input_layer_cnt);
+        DLOGV_IF(kTagDriverConfig, "*************************************************************");
+      }
+    }
+  }
+  if (device_type_ == kDeviceVirtual) {
+    LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
+
+    if (output_buffer->planes[0].fd >= 0) {
+      mdp_out_layer_.buffer.planes[0].fd = output_buffer->planes[0].fd;
+      mdp_out_layer_.buffer.planes[0].offset = output_buffer->planes[0].offset;
+      SetStride(device_type_, output_buffer->format, output_buffer->planes[0].stride,
+                &mdp_out_layer_.buffer.planes[0].stride);
+      mdp_out_layer_.buffer.plane_count = 1;
+    } else {
+      DLOGW("Invalid output buffer fd, setting plane count to 0");
+      mdp_out_layer_.buffer.plane_count = 0;
+    }
+
+    mdp_out_layer_.buffer.fence = output_buffer->acquire_fence_fd;
+
+    DLOGI_IF(kTagDriverConfig, "******************* Output buffer Info **********************");
+    DLOGI_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, acquire_fence %d",
+             mdp_out_layer_.buffer.planes[0].fd, mdp_out_layer_.buffer.planes[0].offset,
+             mdp_out_layer_.buffer.planes[0].stride,  mdp_out_layer_.buffer.fence);
+    DLOGI_IF(kTagDriverConfig, "*************************************************************");
+  }
+
+  mdp_commit.release_fence = -1;
+  mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
+  if (ioctl_(device_fd_, MSMFB_ATOMIC_COMMIT, &mdp_disp_commit_) < 0) {
+    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
+    DumpLayerCommit(mdp_disp_commit_);
+    return kErrorHardware;
+  }
+
+  stack->retire_fence_fd = mdp_commit.retire_fence;
+
+  // MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
+  // layers being composed by MDP.
+  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+    uint32_t layer_index = hw_layer_info.index[i];
+    LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
+    HWRotateInfo *left_rotate = &hw_layers->config[i].rotates[0];
+    HWRotateInfo *right_rotate = &hw_layers->config[i].rotates[1];
+
+    if (!left_rotate->valid && !right_rotate->valid) {
+      input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
+      continue;
+    }
+
+    for (uint32_t count = 0; count < 2; count++) {
+      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
+      if (rotate_info->valid) {
+        input_buffer = &rotate_info->hw_buffer_info.output_buffer;
+        input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
+        close_(input_buffer->acquire_fence_fd);
+        input_buffer->acquire_fence_fd = -1;
+      }
+    }
+  }
+  DLOGI_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
+           device_name_);
+  DLOGI_IF(kTagDriverConfig, "retire_fence_fd %d", stack->retire_fence_fd);
+  DLOGI_IF(kTagDriverConfig, "*************************************************************");
+
+  close_(mdp_commit.release_fence);
+
+  return kErrorNone;
+}
+
+DisplayError HWDevice::Flush() {
+  ResetDisplayParams();
+  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+  mdp_commit.input_layer_cnt = 0;
+  mdp_commit.output_layer = NULL;
+
+  mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
+  if (ioctl_(device_fd_, MSMFB_ATOMIC_COMMIT, &mdp_disp_commit_) < 0) {
+    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, device_type_);
+    DumpLayerCommit(mdp_disp_commit_);
+    return kErrorHardware;
+  }
+  return kErrorNone;
+}
+
+DisplayError HWDevice::SetFormat(const LayerBufferFormat &source, uint32_t *target) {
+  switch (source) {
+  case kFormatARGB8888:                 *target = MDP_ARGB_8888;         break;
+  case kFormatRGBA8888:                 *target = MDP_RGBA_8888;         break;
+  case kFormatBGRA8888:                 *target = MDP_BGRA_8888;         break;
+  case kFormatRGBX8888:                 *target = MDP_RGBX_8888;         break;
+  case kFormatBGRX8888:                 *target = MDP_BGRX_8888;         break;
+  case kFormatRGB888:                   *target = MDP_RGB_888;           break;
+  case kFormatRGB565:                   *target = MDP_RGB_565;           break;
+  case kFormatYCbCr420Planar:           *target = MDP_Y_CB_CR_H2V2;      break;
+  case kFormatYCrCb420Planar:           *target = MDP_Y_CR_CB_H2V2;      break;
+  case kFormatYCbCr420SemiPlanar:       *target = MDP_Y_CBCR_H2V2;       break;
+  case kFormatYCrCb420SemiPlanar:       *target = MDP_Y_CRCB_H2V2;       break;
+  case kFormatYCbCr422Packed:           *target = MDP_YCBYCR_H2V1;       break;
+  case kFormatYCbCr420SemiPlanarVenus:  *target = MDP_Y_CBCR_H2V2_VENUS; break;
+  case kFormatRGBA8888Ubwc:             *target = MDP_RGBA_8888_UBWC;    break;
+  case kFormatRGB565Ubwc:               *target = MDP_RGB_565_UBWC;      break;
+  case kFormatYCbCr420SPVenusUbwc:      *target = MDP_Y_CBCR_H2V2_UBWC;  break;
+  default:
+    DLOGE("Unsupported format type %d", source);
+    return kErrorParameters;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWDevice::SetStride(HWDeviceType device_type, LayerBufferFormat format,
+                                      uint32_t width, uint32_t *target) {
+  // TODO(user): This SetStride function is an workaround to satisfy the driver expectation for
+  // rotator and virtual devices. Eventually this will be taken care in the driver.
+  if (device_type != kDeviceRotator && device_type != kDeviceVirtual) {
+    *target = width;
+    return kErrorNone;
+  }
+
+  switch (format) {
+  case kFormatARGB8888:
+  case kFormatRGBA8888:
+  case kFormatBGRA8888:
+  case kFormatRGBX8888:
+  case kFormatBGRX8888:
+    *target = width * 4;
+    break;
+  case kFormatRGB888:
+    *target = width * 3;
+    break;
+  case kFormatRGB565:
+    *target = width * 3;
+    break;
+  case kFormatYCbCr420SemiPlanarVenus:
+  case kFormatYCbCr420SPVenusUbwc:
+  case kFormatYCbCr420Planar:
+  case kFormatYCrCb420Planar:
+  case kFormatYCbCr420SemiPlanar:
+  case kFormatYCrCb420SemiPlanar:
+    *target = width;
+    break;
+  case kFormatYCbCr422Packed:
+    *target = width * 2;
+    break;
+  default:
+    DLOGE("Unsupported format type %d", format);
+    return kErrorParameters;
+  }
+
+  return kErrorNone;
+}
+
+void HWDevice::SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target) {
+  switch (source) {
+  case kBlendingPremultiplied:  *target = BLEND_OP_PREMULTIPLIED;   break;
+  case kBlendingCoverage:       *target = BLEND_OP_COVERAGE;        break;
+  default:                      *target = BLEND_OP_NOT_DEFINED;     break;
+  }
+}
+
+void HWDevice::SetRect(const LayerRect &source, mdp_rect *target) {
+  target->x = UINT32(source.left);
+  target->y = UINT32(source.top);
+  target->w = UINT32(source.right) - target->x;
+  target->h = UINT32(source.bottom) - target->y;
+}
+
+void HWDevice::SyncMerge(const int &fd1, const int &fd2, int *target) {
+  if (fd1 >= 0 && fd2 >= 0) {
+    buffer_sync_handler_->SyncMerge(fd1, fd2, target);
+  } else if (fd1 >= 0) {
+    *target = fd1;
+  } else if (fd2 >= 0) {
+    *target = fd2;
+  }
+}
+
+int HWDevice::GetFBNodeIndex(HWDeviceType device_type) {
+  int fb_node_index = -1;
+  for (int i = 0; i < kDeviceMax; i++) {
+    HWPanelInfo *panel_info = new HWPanelInfo();
+    GetHWPanelInfoByNode(i, panel_info);
+    switch (device_type) {
+    case kDevicePrimary:
+      if (panel_info->is_primary_panel) {
+        fb_node_index = i;
+      }
+      break;
+    case kDeviceHDMI:
+      if (panel_info->type == kDTvPanel) {
+        fb_node_index = i;
+      }
+      break;
+    case kDeviceVirtual:
+      if (panel_info->type == kWriteBackPanel) {
+        fb_node_index = i;
+      }
+      break;
+    default:
+      break;
+    }
+  }
+  return fb_node_index;
+}
+
+void HWDevice::PopulateHWPanelInfo() {
+  panel_info_ = HWPanelInfo();
+  GetHWPanelInfoByNode(fb_node_index_, &panel_info_);
+  DLOGI("Device type = %d, Panel Type = %d, Device Node = %d, Is Primary = %d",
+        device_type_, panel_info_.type, fb_node_index_, panel_info_.is_primary_panel);
+  DLOGI("Partial Update = %d, Dynamic FPS = %d",
+        panel_info_.partial_update, panel_info_.dynamic_fps);
+  DLOGI("Align: left = %d, width = %d, top = %d, height = %d",
+        panel_info_.left_align, panel_info_.width_align,
+        panel_info_.top_align, panel_info_.height_align);
+  DLOGI("ROI: min_width = %d, min_height = %d, need_merge = %d",
+        panel_info_.min_roi_width, panel_info_.min_roi_height, panel_info_.needs_roi_merge);
+  DLOGI("FPS: min = %d, max =%d", panel_info_.min_fps, panel_info_.max_fps);
+  DLOGI("Left Split = %d, Right Split = %d", panel_info_.split_info.left_split,
+        panel_info_.split_info.right_split);
+  DLOGI("Source Split Always = %d", panel_info_.split_info.always_src_split);
+}
+
+void HWDevice::GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info) {
+  if (!panel_info) {
+    DLOGE("PanelInfo pointer in invalid.");
+    return;
+  }
+  char stringbuffer[kMaxStringLength];
+  FILE *fileptr = NULL;
+  snprintf(stringbuffer, sizeof(stringbuffer), "%s%d/msm_fb_panel_info", fb_path_, device_node);
+  fileptr = fopen(stringbuffer, "r");
+  if (!fileptr) {
+    DLOGW("Failed to open msm_fb_panel_info node device node %d", device_node);
+    return;
+  }
+
+  size_t len = kMaxStringLength;
+  ssize_t read;
+  char *line = stringbuffer;
+  while ((read = getline(&line, &len, fileptr)) != -1) {
+    uint32_t token_count = 0;
+    const uint32_t max_count = 10;
+    char *tokens[max_count] = { NULL };
+    if (!ParseLine(line, tokens, max_count, &token_count)) {
+      if (!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
+        panel_info->partial_update = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "xstart", strlen("xstart"))) {
+        panel_info->left_align = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "walign", strlen("walign"))) {
+        panel_info->width_align = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "ystart", strlen("ystart"))) {
+        panel_info->top_align = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "halign", strlen("halign"))) {
+        panel_info->height_align = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "min_w", strlen("min_w"))) {
+        panel_info->min_roi_width = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "min_h", strlen("min_h"))) {
+        panel_info->min_roi_height = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "roi_merge", strlen("roi_merge"))) {
+        panel_info->needs_roi_merge = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
+        panel_info->dynamic_fps = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
+        panel_info->min_fps = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
+        panel_info->max_fps= atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "primary_panel", strlen("primary_panel"))) {
+        panel_info->is_primary_panel = atoi(tokens[1]);
+      }
+    }
+  }
+  fclose(fileptr);
+  panel_info->type = GetHWPanelType(device_node);
+  GetSplitInfo(device_node, panel_info);
+}
+
+HWPanelType HWDevice::GetHWPanelType(int device_node) {
+  char stringbuffer[kMaxStringLength];
+  DisplayError error = kErrorNone;
+  char *line = stringbuffer;
+  size_t len = kMaxStringLength;
+  ssize_t read;
+  HWPanelType panel_type = kNoPanel;
+
+  snprintf(stringbuffer, sizeof(stringbuffer), "%s%d/msm_fb_type", fb_path_, device_node);
+  FILE *fileptr = fopen(stringbuffer, "r");
+  if (!fileptr) {
+    DLOGW("File not found %s", stringbuffer);
+    return panel_type;
+  }
+  read = getline(&line, &len, fileptr);
+  if (read == -1) {
+    fclose(fileptr);
+    return panel_type;
+  }
+  if ((strncmp(line, "mipi dsi cmd panel", strlen("mipi dsi cmd panel")) == 0)) {
+    panel_type = kCommandModePanel;
+  } else if ((strncmp(line, "mipi dsi video panel", strlen("mipi dsi video panel")) == 0)) {
+    panel_type = kVideoModePanel;
+  } else if ((strncmp(line, "lvds panel", strlen("lvds panel")) == 0)) {
+    panel_type = kLVDSPanel;
+  } else if ((strncmp(line, "edp panel", strlen("edp panel")) == 0)) {
+    panel_type = kEDPPanel;
+  } else if ((strncmp(line, "dtv panel", strlen("dtv panel")) == 0)) {
+    panel_type = kDTvPanel;
+  } else if ((strncmp(line, "writeback panel", strlen("writeback panel")) == 0)) {
+    panel_type = kWriteBackPanel;
+  }
+  fclose(fileptr);
+
+  return panel_type;
+}
+
+void HWDevice::GetSplitInfo(int device_node, HWPanelInfo *panel_info) {
+  char stringbuffer[kMaxStringLength];
+  FILE *fileptr = NULL;
+  size_t len = kMaxStringLength;
+  ssize_t read;
+  char *line = stringbuffer;
+  uint32_t token_count = 0;
+  const uint32_t max_count = 10;
+  char *tokens[max_count] = { NULL };
+
+  // Split info - for MDSS Version 5 - No need to check version here
+  snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/msm_fb_split", fb_path_, device_node);
+  fileptr = fopen(stringbuffer, "r");
+  if (!fileptr) {
+    DLOGW("File not found %s", stringbuffer);
+    return;
+  }
+
+  // Format "left right" space as delimiter
+  read = getline(&line, &len, fileptr);
+  if (read != -1) {
+    if (!ParseLine(line, tokens, max_count, &token_count)) {
+      panel_info->split_info.left_split = atoi(tokens[0]);
+      panel_info->split_info.right_split = atoi(tokens[1]);
+    }
+  }
+  fclose(fileptr);
+
+  // SourceSplit enabled - Get More information
+  snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/msm_fb_src_split_info", fb_path_,
+           device_node);
+  fileptr = fopen(stringbuffer, "r");
+  if (!fileptr) {
+    DLOGW("File not found %s", stringbuffer);
+    return;
+  }
+
+  read = getline(&line, &len, fileptr);
+  if (read != -1) {
+    if (!strncmp(line, "src_split_always", strlen("src_split_always"))) {
+      panel_info->split_info.always_src_split = true;
+    }
+  }
+  fclose(fileptr);
+}
+
+int HWDevice::ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
+  char *tmp_token = NULL;
+  char *temp_ptr;
+  uint32_t index = 0;
+  const char *delim = ", =\n";
+  if (!input) {
+    return -1;
+  }
+  tmp_token = strtok_r(input, delim, &temp_ptr);
+  while (tmp_token && index < max_token) {
+    tokens[index++] = tmp_token;
+    tmp_token = strtok_r(NULL, delim, &temp_ptr);
+  }
+  *count = index;
+
+  return 0;
+}
+
+bool HWDevice::EnableHotPlugDetection(int enable) {
+  bool ret_value = true;
+  char hpdpath[kMaxStringLength];
+  int hdmi_node_index = GetFBNodeIndex(kDeviceHDMI);
+  snprintf(hpdpath , sizeof(hpdpath), "%s%d/hpd", fb_path_, hdmi_node_index);
+  int hpdfd = open_(hpdpath, O_RDWR, 0);
+  if (hpdfd < 0) {
+    DLOGE("Open failed = %s", hpdpath);
+    return kErrorHardware;
+  }
+  char value = enable ? '1' : '0';
+  ssize_t length = pwrite_(hpdfd, &value, 1, 0);
+  if (length <= 0) {
+    DLOGE("Write failed 'hpd' = %d", enable);
+    ret_value = false;
+  }
+  close_(hpdfd);
+
+  return ret_value;
+}
+
+void HWDevice::ResetDisplayParams() {
+  memset(&mdp_disp_commit_, 0, sizeof(mdp_disp_commit_));
+  memset(&mdp_in_layers_, 0, sizeof(mdp_in_layers_));
+  memset(&mdp_out_layer_, 0, sizeof(mdp_out_layer_));
+  memset(&scale_data_, 0, sizeof(scale_data_));
+
+  for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
+    mdp_in_layers_[i].buffer.fence = -1;
+  }
+
+  mdp_disp_commit_.version = MDP_COMMIT_VERSION_1_0;
+  mdp_disp_commit_.commit_v1.input_layers = mdp_in_layers_;
+  mdp_disp_commit_.commit_v1.output_layer = &mdp_out_layer_;
+  mdp_disp_commit_.commit_v1.release_fence = -1;
+  mdp_disp_commit_.commit_v1.retire_fence = -1;
+}
+
+}  // namespace sde
+
diff --git a/displayengine/libs/core/fb/hw_device.h b/displayengine/libs/core/fb/hw_device.h
new file mode 100644
index 0000000..2a240c6
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_device.h
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2014 - 2015, 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_DEVICE_H__
+#define __HW_DEVICE_H__
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/msm_mdp_ext.h>
+#include <video/msm_hdmi_modes.h>
+#include <linux/mdss_rotator.h>
+#include <poll.h>
+#include <pthread.h>
+
+#include "hw_interface.h"
+#include "hw_info_interface.h"
+
+#define IOCTL_LOGE(ioctl, type) DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, \
+                                      type, errno, strerror(errno))
+
+namespace sde {
+
+class HWDevice {
+ protected:
+  explicit HWDevice(BufferSyncHandler *buffer_sync_handler);
+  DisplayError Init();
+  DisplayError Open(HWEventHandler *eventhandler);
+  DisplayError Close();
+  DisplayError GetNumDisplayAttributes(uint32_t *count);
+  DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                    uint32_t index);
+  DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
+  DisplayError SetDisplayAttributes(uint32_t index);
+  DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  DisplayError PowerOn();
+  DisplayError PowerOff();
+  DisplayError Doze();
+  DisplayError Standby();
+  DisplayError Validate(HWLayers *hw_layers);
+  DisplayError Commit(HWLayers *hw_layers);
+  DisplayError Flush();
+
+  enum {
+    kHWEventVSync,
+    kHWEventBlank,
+  };
+
+  static const int kMaxStringLength = 1024;
+  static const int kNumPhysicalDisplays = 2;
+  static const int kNumDisplayEvents = 3;
+
+  void DumpLayerCommit(mdp_layer_commit &layer_commit);
+  DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
+  DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format,
+                         uint32_t width, uint32_t *target);
+  void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
+  void SetRect(const LayerRect &source, mdp_rect *target);
+  void SyncMerge(const int &fd1, const int &fd2, int *target);
+
+  // Retrieves HW FrameBuffer Node Index
+  int GetFBNodeIndex(HWDeviceType device_type);
+  // Populates HWPanelInfo based on node index
+  void PopulateHWPanelInfo();
+  void GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info);
+  HWPanelType GetHWPanelType(int device_node);
+  void GetSplitInfo(int device_node, HWPanelInfo *panel_info);
+  int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
+  mdp_scale_data* GetScaleDataRef(uint32_t index) { return &scale_data_[index]; }
+  void ResetDisplayParams();
+
+  bool EnableHotPlugDetection(int enable);
+
+  // Pointers to system calls which are either mapped to actual system call or virtual driver.
+  int (*ioctl_)(int, int, ...);
+  int (*open_)(const char *, int, ...);
+  int (*close_)(int);
+  int (*poll_)(struct pollfd *, nfds_t, int);
+  ssize_t (*pread_)(int, void *, size_t, off_t);
+  ssize_t (*pwrite_)(int, const void *, size_t, off_t);
+  FILE* (*fopen_)( const char *fname, const char *mode);
+  int (*fclose_)(FILE* fileptr);
+  ssize_t (*getline_)(char **lineptr, size_t *linelen, FILE *stream);
+
+  // Store the Device EventHandler - used for callback
+  HWEventHandler *event_handler_;
+  HWResourceInfo hw_resource_;
+  HWPanelInfo panel_info_;
+  HWInfoInterface *hw_info_intf_;
+  int fb_node_index_;
+  const char *fb_path_;
+  bool hotplug_enabled_;
+  BufferSyncHandler *buffer_sync_handler_;
+  int device_fd_;
+  HWDeviceType device_type_;
+  mdp_layer_commit mdp_disp_commit_;
+  mdp_input_layer mdp_in_layers_[kMaxSDELayers * 2];   // split panel (left + right)
+  mdp_scale_data scale_data_[kMaxSDELayers * 2];
+  mdp_output_layer mdp_out_layer_;
+  const char *device_name_;
+};
+
+}  // namespace sde
+
+#endif  // __HW_DEVICE_H__
+
diff --git a/displayengine/libs/core/fb/hw_hdmi.cpp b/displayengine/libs/core/fb/hw_hdmi.cpp
new file mode 100644
index 0000000..bc97cf6
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_hdmi.cpp
@@ -0,0 +1,336 @@
+/*
+* Copyright (c) 2015, 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 <sys/ioctl.h>
+#include <ctype.h>
+#include <utils/debug.h>
+#include <fcntl.h>
+#include "hw_hdmi.h"
+
+#define __CLASS__ "HWHDMI"
+
+namespace sde {
+
+static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
+  char *tmp_token = NULL;
+  char *temp_ptr;
+  uint32_t index = 0;
+  const char *delim = ", =\n";
+  if (!input) {
+    return -1;
+  }
+  tmp_token = strtok_r(input, delim, &temp_ptr);
+  while (tmp_token && index < max_token) {
+    tokens[index++] = tmp_token;
+    tmp_token = strtok_r(NULL, delim, &temp_ptr);
+  }
+  *count = index;
+
+  return 0;
+}
+
+static bool MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode,
+                                 fb_var_screeninfo *info) {
+  if (!mode || !info) {
+    return false;
+  }
+
+  info->reserved[0] = 0;
+  info->reserved[1] = 0;
+  info->reserved[2] = 0;
+  info->reserved[3] = (info->reserved[3] & 0xFFFF) | (mode->video_format << 16);
+  info->xoffset = 0;
+  info->yoffset = 0;
+  info->xres = mode->active_h;
+  info->yres = mode->active_v;
+  info->pixclock = (mode->pixel_freq) * 1000;
+  info->vmode = mode->interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
+  info->right_margin = mode->front_porch_h;
+  info->hsync_len = mode->pulse_width_h;
+  info->left_margin = mode->back_porch_h;
+  info->lower_margin = mode->front_porch_v;
+  info->vsync_len = mode->pulse_width_v;
+  info->upper_margin = mode->back_porch_v;
+
+  return true;
+}
+
+DisplayError HWHDMIInterface::Create(HWHDMIInterface **intf, HWInfoInterface *hw_info_intf,
+                                     BufferSyncHandler *buffer_sync_handler) {
+  DisplayError error = kErrorNone;
+  HWHDMI *hw_fb_hdmi = NULL;
+
+  hw_fb_hdmi = new HWHDMI(buffer_sync_handler, hw_info_intf);
+  error = hw_fb_hdmi->Init();
+  if (error != kErrorNone) {
+    delete hw_fb_hdmi;
+  } else {
+    *intf = hw_fb_hdmi;
+  }
+  return error;
+}
+
+DisplayError HWHDMIInterface::Destroy(HWHDMIInterface *intf) {
+  HWHDMI *hw_fb_hdmi = static_cast<HWHDMI *>(intf);
+  hw_fb_hdmi->Deinit();
+  delete hw_fb_hdmi;
+
+  return kErrorNone;
+}
+
+HWHDMI::HWHDMI(BufferSyncHandler *buffer_sync_handler,  HWInfoInterface *hw_info_intf)
+  : HWDevice(buffer_sync_handler) {
+  HWDevice::device_type_ = kDeviceHDMI;
+  HWDevice::device_name_ = "HDMI Display Device";
+  HWDevice::hw_info_intf_ = hw_info_intf;
+}
+
+DisplayError HWHDMI::Init() {
+  DisplayError error = kErrorNone;
+
+  error = HWDevice::Init();
+  if (error != kErrorNone) {
+    goto CleanupOnError;
+  }
+
+  // Mode look-up table for HDMI
+  supported_video_modes_ = new msm_hdmi_mode_timing_info[HDMI_VFRMT_MAX];
+  if (!supported_video_modes_) {
+    error = kErrorMemory;
+    goto CleanupOnError;
+  }
+  // Populate the mode table for supported modes
+  MSM_HDMI_MODES_INIT_TIMINGS(supported_video_modes_);
+  MSM_HDMI_MODES_SET_SUPP_TIMINGS(supported_video_modes_, MSM_HDMI_MODES_ALL);
+
+  return kErrorNone;
+
+CleanupOnError:
+  if (supported_video_modes_) {
+    delete supported_video_modes_;
+  }
+
+  return error;
+}
+
+DisplayError HWHDMI::Deinit() {
+  hdmi_mode_count_ = 0;
+  if (supported_video_modes_) {
+    delete supported_video_modes_;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWHDMI::Open(HWEventHandler *eventhandler) {
+  return HWDevice::Open(eventhandler);
+}
+
+DisplayError HWHDMI::Close() {
+  return HWDevice::Close();
+}
+
+DisplayError HWHDMI::GetNumDisplayAttributes(uint32_t *count) {
+  *count = GetHDMIModeCount();
+  if (*count <= 0) {
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+int HWHDMI::GetHDMIModeCount() {
+  ssize_t length = -1;
+  char edid_str[256] = {'\0'};
+  char edid_path[kMaxStringLength] = {'\0'};
+  snprintf(edid_path, sizeof(edid_path), "%s%d/edid_modes", fb_path_, fb_node_index_);
+  int edid_file = open_(edid_path, O_RDONLY);
+  if (edid_file < 0) {
+    DLOGE("EDID file open failed.");
+    return -1;
+  }
+
+  length = pread_(edid_file, edid_str, sizeof(edid_str)-1, 0);
+  if (length <= 0) {
+    DLOGE("%s: edid_modes file empty");
+    edid_str[0] = '\0';
+  } else {
+    DLOGI("EDID mode string: %s", edid_str);
+    while (length > 1 && isspace(edid_str[length-1])) {
+      --length;
+    }
+    edid_str[length] = '\0';
+  }
+  close_(edid_file);
+
+  if (length > 0) {
+    // Get EDID modes from the EDID string
+    char *ptr = edid_str;
+    const uint32_t edid_count_max = 128;
+    char *tokens[edid_count_max] = { NULL };
+    ParseLine(ptr, tokens, edid_count_max, &hdmi_mode_count_);
+    for (uint32_t i = 0; i < hdmi_mode_count_; i++) {
+      hdmi_modes_[i] = atoi(tokens[i]);
+    }
+  }
+  return (hdmi_mode_count_ > 0) ? hdmi_mode_count_ : 0;
+}
+
+DisplayError HWHDMI::GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                                     uint32_t index) {
+  DTRACE_SCOPED();
+
+  // Variable screen info
+  STRUCT_VAR(fb_var_screeninfo, var_screeninfo);
+
+  // Get the resolution info from the look up table
+  msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
+  for (int i = 0; i < HDMI_VFRMT_MAX; i++) {
+    msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
+    if (cur->video_format == hdmi_modes_[index]) {
+      timing_mode = cur;
+      break;
+    }
+  }
+  display_attributes->x_pixels = timing_mode->active_h;
+  display_attributes->y_pixels = timing_mode->active_v;
+  display_attributes->v_total = timing_mode->active_v + timing_mode->front_porch_v +
+      timing_mode->back_porch_v + timing_mode->pulse_width_v;
+  display_attributes->x_dpi = 0;
+  display_attributes->y_dpi = 0;
+  display_attributes->fps = FLOAT(timing_mode->refresh_rate) / 1000.0f;
+  display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
+  display_attributes->split_left = display_attributes->x_pixels;
+  if (display_attributes->x_pixels > hw_resource_.max_mixer_width) {
+    display_attributes->is_device_split = true;
+    display_attributes->split_left = display_attributes->x_pixels / 2;
+  }
+  return kErrorNone;
+}
+
+DisplayError HWHDMI::SetDisplayAttributes(uint32_t index) {
+  DTRACE_SCOPED();
+
+  DisplayError error = kErrorNone;
+
+  // Variable screen info
+  STRUCT_VAR(fb_var_screeninfo, vscreeninfo);
+  if (ioctl_(device_fd_, FBIOGET_VSCREENINFO, &vscreeninfo) < 0) {
+    IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_);
+    return kErrorHardware;
+  }
+
+  DLOGI("GetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3],
+        vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
+        vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
+        vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
+
+  msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
+  for (int i = 0; i < HDMI_VFRMT_MAX; i++) {
+    msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
+    if (cur->video_format == hdmi_modes_[index]) {
+      timing_mode = cur;
+      break;
+    }
+  }
+
+  if (MapHDMIDisplayTiming(timing_mode, &vscreeninfo) == false) {
+    return kErrorParameters;
+  }
+
+  STRUCT_VAR(msmfb_metadata, metadata);
+  metadata.op = metadata_op_vic;
+  metadata.data.video_info_code = timing_mode->video_format;
+  if (ioctl(device_fd_, MSMFB_METADATA_SET, &metadata) < 0) {
+    IOCTL_LOGE(MSMFB_METADATA_SET, device_type_);
+    return kErrorHardware;
+  }
+
+  DLOGI("SetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3] & 0xFF00,
+        vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
+        vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
+        vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
+
+  vscreeninfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
+  if (ioctl_(device_fd_, FBIOPUT_VSCREENINFO, &vscreeninfo) < 0) {
+    IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_);
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWHDMI::GetConfigIndex(uint32_t mode, uint32_t *index) {
+  // Check if the mode is valid and return corresponding index
+  for (uint32_t i = 0; i < hdmi_mode_count_; i++) {
+    if (hdmi_modes_[i] == mode) {
+      *index = i;
+      DLOGI("Index = %d for config = %d", *index, mode);
+      return kErrorNone;
+    }
+  }
+
+  DLOGE("Config = %d not supported", mode);
+  return kErrorNotSupported;
+}
+
+DisplayError HWHDMI::PowerOn() {
+  return HWDevice::PowerOn();
+}
+
+DisplayError HWHDMI::PowerOff() {
+  return HWDevice::PowerOff();
+}
+
+DisplayError HWHDMI::Doze() {
+  return HWDevice::Doze();
+}
+
+DisplayError HWHDMI::Standby() {
+  return HWDevice::Standby();
+}
+
+DisplayError HWHDMI::Validate(HWLayers *hw_layers) {
+  return HWDevice::Validate(hw_layers);
+}
+
+DisplayError HWHDMI::Commit(HWLayers *hw_layers) {
+  return HWDevice::Commit(hw_layers);
+}
+
+DisplayError HWHDMI::Flush() {
+  return HWDevice::Flush();
+}
+
+DisplayError HWHDMI::GetHWPanelInfo(HWPanelInfo *panel_info) {
+  return HWDevice::GetHWPanelInfo(panel_info);
+}
+
+}  // namespace sde
+
diff --git a/displayengine/libs/core/fb/hw_hdmi.h b/displayengine/libs/core/fb/hw_hdmi.h
new file mode 100644
index 0000000..8fc3c47
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_hdmi.h
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2015, 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_HDMI_H__
+#define __HW_HDMI_H__
+
+#include "hw_device.h"
+#include "hw_hdmi_interface.h"
+
+namespace sde {
+
+class HWHDMI : public HWDevice, public HWHDMIInterface {
+ public:
+  HWHDMI(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+  virtual DisplayError Init();
+  virtual DisplayError Deinit();
+  virtual DisplayError Open(HWEventHandler *eventhandler);
+  virtual DisplayError Close();
+  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
+  virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                            uint32_t index);
+  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
+  virtual DisplayError SetDisplayAttributes(uint32_t index);
+  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  virtual DisplayError PowerOn();
+  virtual DisplayError PowerOff();
+  virtual DisplayError Doze();
+  virtual DisplayError Standby();
+  virtual DisplayError Validate(HWLayers *hw_layers);
+  virtual DisplayError Commit(HWLayers *hw_layers);
+  virtual DisplayError Flush();
+
+ private:
+  int GetHDMIModeCount();
+
+  uint32_t hdmi_mode_count_;
+  uint32_t hdmi_modes_[256];
+  // Holds the hdmi timing information. Ex: resolution, fps etc.,
+  msm_hdmi_mode_timing_info *supported_video_modes_;
+};
+
+}  // namespace sde
+
+#endif  // __HW_HDMI_H__
+
diff --git a/displayengine/libs/core/fb/hw_info.cpp b/displayengine/libs/core/fb/hw_info.cpp
new file mode 100644
index 0000000..cddb590
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_info.cpp
@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2015, 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 "hw_info.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
+
+#define __CLASS__ "HWInfo"
+
+namespace sde {
+
+int HWInfo::ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count) {
+  char *tmp_token = NULL;
+  char *temp_ptr;
+  uint32_t index = 0;
+  const char *delim = ", =\n";
+  if (!input) {
+    return -1;
+  }
+  tmp_token = strtok_r(input, delim, &temp_ptr);
+  while (tmp_token && index < max_token) {
+    tokens[index++] = tmp_token;
+    tmp_token = strtok_r(NULL, delim, &temp_ptr);
+  }
+  *count = index;
+
+  return 0;
+}
+
+DisplayError HWInfoInterface::Create(HWInfoInterface **intf) {
+  DisplayError error = kErrorNone;
+  HWInfo *hw_info = NULL;
+
+  hw_info = new HWInfo();
+  if (!hw_info) {
+    error = kErrorMemory;
+  } else {
+    *intf = hw_info;
+  }
+
+  return error;
+}
+
+DisplayError HWInfoInterface::Destroy(HWInfoInterface *intf) {
+  HWInfo *hw_info = static_cast<HWInfo *>(intf);
+  delete hw_info;
+
+  return kErrorNone;
+}
+
+DisplayError HWInfo::GetHWResourceInfo(HWResourceInfo *hw_resource) {
+  if (!hw_resource) {
+    DLOGE("HWResourceInfo pointer in invalid.");
+    return kErrorParameters;
+  }
+  const char *kHWCapabilitiesPath = "/sys/devices/virtual/graphics/fb";
+  FILE *fileptr = NULL;
+  char stringbuffer[kMaxStringLength];
+  uint32_t token_count = 0;
+  const uint32_t max_count = 10;
+  char *tokens[max_count] = { NULL };
+  snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/mdp/caps",
+           kHWCapabilitiesPath, kHWCapabilitiesNode);
+  fileptr = fopen(stringbuffer, "rb");
+
+  if (!fileptr) {
+    DLOGE("File '%s' not found", stringbuffer);
+    return kErrorHardware;
+  }
+
+  size_t len = kMaxStringLength;
+  ssize_t read;
+  char *line = stringbuffer;
+  hw_resource->hw_version = kHWMdssVersion5;
+  while ((read = getline(&line, &len, fileptr)) != -1) {
+    // parse the line and update information accordingly
+    if (!ParseLine(line, tokens, max_count, &token_count)) {
+      if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
+        hw_resource->hw_revision = atoi(tokens[1]);  // HW Rev, v1/v2
+      } else if (!strncmp(tokens[0], "rgb_pipes", strlen("rgb_pipes"))) {
+        hw_resource->num_rgb_pipe = UINT8(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "vig_pipes", strlen("vig_pipes"))) {
+        hw_resource->num_vig_pipe = UINT8(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
+        hw_resource->num_dma_pipe = UINT8(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "cursor_pipes", strlen("cursor_pipes"))) {
+        hw_resource->num_cursor_pipe = UINT8(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "blending_stages", strlen("blending_stages"))) {
+        hw_resource->num_blending_stages = UINT8(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "max_downscale_ratio", strlen("max_downscale_ratio"))) {
+        hw_resource->max_scale_down = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
+        hw_resource->max_scale_up = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
+        hw_resource->max_bandwidth_low = atol(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
+        hw_resource->max_bandwidth_high = atol(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
+        hw_resource->max_mixer_width = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
+        hw_resource->max_pipe_bw = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
+        hw_resource->max_sde_clk = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
+        hw_resource->clk_fudge_factor = FLOAT(atoi(tokens[1])) / FLOAT(atoi(tokens[2]));
+      } else if (!strncmp(tokens[0], "features", strlen("features"))) {
+        for (uint32_t i = 0; i < token_count; i++) {
+          if (!strncmp(tokens[i], "bwc", strlen("bwc"))) {
+            hw_resource->has_bwc = true;
+          } else if (!strncmp(tokens[i], "decimation", strlen("decimation"))) {
+            hw_resource->has_decimation = true;
+          } else if (!strncmp(tokens[i], "tile_format", strlen("tile_format"))) {
+            hw_resource->has_macrotile = true;
+          } else if (!strncmp(tokens[i], "src_split", strlen("src_split"))) {
+            hw_resource->is_src_split = true;
+          } else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
+            hw_resource->has_non_scalar_rgb = true;
+          } else if (!strncmp(tokens[i], "rotator_downscale", strlen("rotator_downscale"))) {
+            hw_resource->has_rotator_downscale = true;
+          }
+        }
+      }
+    }
+  }
+  fclose(fileptr);
+
+  DLOGI("SDE Version = %d, SDE Revision = %x, RGB = %d, VIG = %d, DMA = %d, Cursor = %d",
+        hw_resource->hw_version, hw_resource->hw_revision, hw_resource->num_rgb_pipe,
+        hw_resource->num_vig_pipe, hw_resource->num_dma_pipe, hw_resource->num_cursor_pipe);
+  DLOGI("Upscale Ratio = %d, Downscale Ratio = %d, Blending Stages = %d", hw_resource->max_scale_up,
+        hw_resource->max_scale_down, hw_resource->num_blending_stages);
+  DLOGI("BWC = %d, Decimation = %d, Tile Format = %d, Rotator Downscale = %d", hw_resource->has_bwc,
+        hw_resource->has_decimation, hw_resource->has_macrotile,
+        hw_resource->has_rotator_downscale);
+  DLOGI("SourceSplit = %d", hw_resource->is_src_split);
+  DLOGI("MaxLowBw = %"PRIu64", MaxHighBw = %"PRIu64"", hw_resource->max_bandwidth_low,
+        hw_resource->max_bandwidth_high);
+  DLOGI("MaxPipeBw = %"PRIu64" KBps, MaxSDEClock = %"PRIu64" Hz, ClockFudgeFactor = %f",
+        hw_resource->max_pipe_bw, hw_resource->max_sde_clk, hw_resource->clk_fudge_factor);
+
+  return kErrorNone;
+}
+
+}  // namespace sde
+
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/fb/hw_info.h
similarity index 63%
copy from displayengine/libs/core/hw_interface.cpp
copy to displayengine/libs/core/fb/hw_info.h
index 6b99a73..31667ae 100644
--- a/displayengine/libs/core/hw_interface.cpp
+++ b/displayengine/libs/core/fb/hw_info.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015, 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:
@@ -22,34 +22,33 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <utils/constants.h>
+#ifndef __HW_INFO_H__
+#define __HW_INFO_H__
 
-#include "hw_interface.h"
-#include "hw_framebuffer.h"
+#include <inttypes.h>
+#include <core/sde_types.h>
+#include <private/hw_info_types.h>
+#include "hw_info_interface.h"
 
 namespace sde {
 
-DisplayError HWInterface::Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler) {
-  DisplayError error = kErrorNone;
-  HWFrameBuffer *hw_frame_buffer = NULL;
+class HWInfo: public HWInfoInterface {
+ public:
+  virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource);
 
-  hw_frame_buffer = new HWFrameBuffer(buffer_sync_handler);
-  error = hw_frame_buffer->Init();
-  if (UNLIKELY(error != kErrorNone)) {
-    delete hw_frame_buffer;
-  } else {
-    *intf = hw_frame_buffer;
-  }
+ private:
+  // TODO(user): Read Mdss version from the driver
+  static const int kHWMdssVersion5 = 500;  // MDSS_V5
+  static const int kMaxStringLength = 1024;
+  // MDP Capabilities are replicated across all frame buffer devices.
+  // However, we rely on reading the capabalities from fbO since this
+  // is guaranteed to be available.
+  static const int kHWCapabilitiesNode = 0;
 
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
-  hw_frame_buffer->Deinit();
-  delete hw_frame_buffer;
-  return kErrorNone;
-}
+  static int ParseLine(char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
+};
 
 }  // namespace sde
 
+#endif  // __HW_INFO_H__
+
diff --git a/displayengine/libs/core/fb/hw_primary.cpp b/displayengine/libs/core/fb/hw_primary.cpp
new file mode 100644
index 0000000..0dd0db2
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_primary.cpp
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 2015, 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 <sys/prctl.h>
+#include <sys/ioctl.h>
+#include <pthread.h>
+#include <sys/resource.h>
+#include <fcntl.h>
+#include <utils/debug.h>
+#include "hw_primary.h"
+
+#define __CLASS__ "HWPrimary"
+
+namespace sde {
+
+DisplayError HWPrimaryInterface::Create(HWPrimaryInterface **intf, HWInfoInterface *hw_info_intf,
+                                        BufferSyncHandler *buffer_sync_handler) {
+  DisplayError error = kErrorNone;
+  HWPrimary *hw_primary = NULL;
+
+  hw_primary = new HWPrimary(buffer_sync_handler, hw_info_intf);
+  error = hw_primary->Init();
+  if (error != kErrorNone) {
+    delete hw_primary;
+  } else {
+    *intf = hw_primary;
+  }
+
+  return error;
+}
+
+DisplayError HWPrimaryInterface::Destroy(HWPrimaryInterface *intf) {
+  HWPrimary *hw_primary = static_cast<HWPrimary *>(intf);
+  hw_primary->Deinit();
+  delete hw_primary;
+
+  return kErrorNone;
+}
+
+HWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
+  : HWDevice(buffer_sync_handler), event_thread_name_("SDE_EventThread"), fake_vsync_(false),
+    exit_threads_(false) {
+  HWDevice::device_type_ = kDevicePrimary;
+  HWDevice::device_name_ = "Primary Display Device";
+  HWDevice::hw_info_intf_ = hw_info_intf;
+}
+
+DisplayError HWPrimary::Init() {
+  DisplayError error = kErrorNone;
+  char node_path[kMaxStringLength] = {0};
+  char data[kMaxStringLength] = {0};
+  const char* event_name[kNumDisplayEvents] = {"vsync_event", "show_blank_event", "idle_notify"};
+
+  error = HWDevice::Init();
+  if (error != kErrorNone) {
+    goto CleanupOnError;
+  }
+
+  // Open nodes for polling
+  for (int event = 0; event < kNumDisplayEvents; event++) {
+    poll_fds_[event].fd = -1;
+  }
+
+  if (!fake_vsync_) {
+    for (int event = 0; event < kNumDisplayEvents; event++) {
+      pollfd &poll_fd = poll_fds_[event];
+
+      if ((panel_info_.type == kCommandModePanel) &&
+          (!strncmp(event_name[event], "idle_notify", strlen("idle_notify")))) {
+        continue;
+      }
+
+      snprintf(node_path, sizeof(node_path), "%s%d/%s", fb_path_, fb_node_index_,
+               event_name[event]);
+
+      poll_fd.fd = open_(node_path, O_RDONLY);
+      if (poll_fd.fd < 0) {
+        DLOGE("open failed for event=%d, error=%s", event, strerror(errno));
+        error = kErrorHardware;
+        goto CleanupOnError;
+      }
+
+      // Read once on all fds to clear data on all fds.
+      pread_(poll_fd.fd, data , kMaxStringLength, 0);
+      poll_fd.events = POLLPRI | POLLERR;
+    }
+  }
+
+  // Start the Event thread
+  if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) {
+    DLOGE("Failed to start %s, error = %s", event_thread_name_);
+    error = kErrorResources;
+    goto CleanupOnError;
+  }
+
+  // Disable HPD at start if HDMI is external, it will be enabled later when the display powers on
+  // This helps for framework reboot or adb shell stop/start
+  EnableHotPlugDetection(0);
+
+  return kErrorNone;
+
+CleanupOnError:
+  // Close all poll fds
+  for (int event = 0; event < kNumDisplayEvents; event++) {
+    int &fd = poll_fds_[event].fd;
+    if (fd >= 0) {
+      close_(fd);
+    }
+  }
+
+  return error;
+}
+
+DisplayError HWPrimary::Deinit() {
+  exit_threads_ = true;
+  pthread_join(event_thread_, NULL);
+
+  for (int event = 0; event < kNumDisplayEvents; event++) {
+    close_(poll_fds_[event].fd);
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWPrimary::Open(HWEventHandler *eventhandler) {
+  return HWDevice::Open(eventhandler);
+}
+
+DisplayError HWPrimary::Close() {
+  return HWDevice::Close();
+}
+
+DisplayError HWPrimary::GetNumDisplayAttributes(uint32_t *count) {
+  return HWDevice::GetNumDisplayAttributes(count);
+}
+
+DisplayError HWPrimary::GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                             uint32_t index) {
+  DTRACE_SCOPED();
+
+  // Variable screen info
+  STRUCT_VAR(fb_var_screeninfo, var_screeninfo);
+
+  if (ioctl_(device_fd_, FBIOGET_VSCREENINFO, &var_screeninfo) < 0) {
+    IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_);
+    return kErrorHardware;
+  }
+
+  // Frame rate
+  STRUCT_VAR(msmfb_metadata, meta_data);
+  meta_data.op = metadata_op_frame_rate;
+  if (ioctl_(device_fd_, MSMFB_METADATA_GET, &meta_data) < 0) {
+    IOCTL_LOGE(MSMFB_METADATA_GET, device_type_);
+    return kErrorHardware;
+  }
+
+  // If driver doesn't return width/height information, default to 160 dpi
+  if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) {
+    var_screeninfo.width  = INT(((FLOAT(var_screeninfo.xres) * 25.4f)/160.0f) + 0.5f);
+    var_screeninfo.height = INT(((FLOAT(var_screeninfo.yres) * 25.4f)/160.0f) + 0.5f);
+  }
+
+  display_attributes->x_pixels = var_screeninfo.xres;
+  display_attributes->y_pixels = var_screeninfo.yres;
+  display_attributes->v_total = var_screeninfo.yres + var_screeninfo.lower_margin +
+      var_screeninfo.upper_margin + var_screeninfo.vsync_len;
+  display_attributes->x_dpi =
+      (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width);
+  display_attributes->y_dpi =
+      (FLOAT(var_screeninfo.yres) * 25.4f) / FLOAT(var_screeninfo.height);
+  display_attributes->fps = FLOAT(meta_data.data.panel_frame_rate);
+  display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
+  display_attributes->is_device_split = (panel_info_.split_info.left_split ||
+      (var_screeninfo.xres > hw_resource_.max_mixer_width)) ? true : false;
+  display_attributes->split_left = panel_info_.split_info.left_split ?
+      panel_info_.split_info.left_split : display_attributes->x_pixels / 2;
+  display_attributes->always_src_split = panel_info_.split_info.always_src_split;
+
+  return kErrorNone;
+}
+
+DisplayError HWPrimary::SetDisplayAttributes(uint32_t index) {
+  return HWDevice::SetDisplayAttributes(index);
+}
+
+DisplayError HWPrimary::GetConfigIndex(uint32_t mode, uint32_t *index) {
+  return HWDevice::GetConfigIndex(mode, index);
+}
+
+DisplayError HWPrimary::PowerOn() {
+  return HWDevice::PowerOn();
+}
+
+DisplayError HWPrimary::PowerOff() {
+  if (ioctl_(device_fd_, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
+    IOCTL_LOGE(FB_BLANK_POWERDOWN, device_type_);
+    return kErrorHardware;
+  }
+  return kErrorNone;
+}
+
+DisplayError HWPrimary::Doze() {
+  return HWDevice::Doze();
+}
+
+DisplayError HWPrimary::Standby() {
+  return HWDevice::Standby();
+}
+
+DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
+  return HWDevice::Validate(hw_layers);
+}
+
+DisplayError HWPrimary::Commit(HWLayers *hw_layers) {
+  return HWDevice::Commit(hw_layers);
+}
+
+DisplayError HWPrimary::Flush() {
+  return HWDevice::Flush();
+}
+
+DisplayError HWPrimary::GetHWPanelInfo(HWPanelInfo *panel_info) {
+  return HWDevice::GetHWPanelInfo(panel_info);
+}
+
+void* HWPrimary::DisplayEventThread(void *context) {
+  if (context) {
+    return reinterpret_cast<HWPrimary *>(context)->DisplayEventThreadHandler();
+  }
+
+  return NULL;
+}
+
+void* HWPrimary::DisplayEventThreadHandler() {
+  char data[kMaxStringLength] = {0};
+
+  prctl(PR_SET_NAME, event_thread_name_, 0, 0, 0);
+  setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
+
+  if (fake_vsync_) {
+    while (!exit_threads_) {
+      // Fake vsync is used only when set explicitly through a property(todo) or when
+      // the vsync timestamp node cannot be opened at bootup. There is no
+      // fallback to fake vsync from the true vsync loop, ever, as the
+      // condition can easily escape detection.
+      // Also, fake vsync is delivered only for the primary display.
+      usleep(16666);
+      STRUCT_VAR(timeval, time_now);
+      gettimeofday(&time_now, NULL);
+      uint64_t ts = uint64_t(time_now.tv_sec)*1000000000LL +uint64_t(time_now.tv_usec)*1000LL;
+
+      // Send Vsync event for primary display(0)
+      event_handler_->VSync(ts);
+    }
+
+    pthread_exit(0);
+  }
+
+  typedef void (HWPrimary::*EventHandler)(char*);
+  EventHandler event_handler[kNumDisplayEvents] = { &HWPrimary::HandleVSync,
+                                                    &HWPrimary::HandleBlank,
+                                                    &HWPrimary::HandleIdleTimeout };
+
+  while (!exit_threads_) {
+    int error = poll_(poll_fds_, kNumDisplayEvents, -1);
+    if (error < 0) {
+      DLOGW("poll failed. error = %s", strerror(errno));
+      continue;
+    }
+    for (int event = 0; event < kNumDisplayEvents; event++) {
+      pollfd &poll_fd = poll_fds_[event];
+
+      if (poll_fd.revents & POLLPRI) {
+        ssize_t length = pread_(poll_fd.fd, data, kMaxStringLength, 0);
+        if (length < 0) {
+          // If the read was interrupted - it is not a fatal error, just continue.
+          DLOGW("pread failed. event = %d, error = %s", event, strerror(errno));
+          continue;
+        }
+
+        (this->*event_handler[event])(data);
+      }
+    }
+  }
+
+  pthread_exit(0);
+
+  return NULL;
+}
+
+void HWPrimary::HandleVSync(char *data) {
+  int64_t timestamp = 0;
+  if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
+    timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
+  }
+  event_handler_->VSync(timestamp);
+}
+
+void HWPrimary::HandleBlank(char *data) {
+  // TODO(user): Need to send blank Event
+}
+
+void HWPrimary::HandleIdleTimeout(char *data) {
+  event_handler_->IdleTimeout();
+}
+
+void HWPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) {
+  char node_path[kMaxStringLength] = {0};
+
+  DLOGI("Setting idle timeout to = %d ms", timeout_ms);
+
+  snprintf(node_path, sizeof(node_path), "%s%d/idle_time", fb_path_, fb_node_index_);
+
+  // Open a sysfs node to send the timeout value to driver.
+  int fd = open_(node_path, O_WRONLY);
+  if (fd < 0) {
+    DLOGE("Unable to open %s, node %s", node_path, strerror(errno));
+    return;
+  }
+
+  char timeout_string[64];
+  snprintf(timeout_string, sizeof(timeout_string), "%d", timeout_ms);
+
+  // Notify driver about the timeout value
+  ssize_t length = pwrite_(fd, timeout_string, strlen(timeout_string), 0);
+  if (length < -1) {
+    DLOGE("Unable to write into %s, node %s", node_path, strerror(errno));
+  }
+
+  close_(fd);
+}
+
+DisplayError HWPrimary::SetVSyncState(bool enable) {
+  DTRACE_SCOPED();
+
+  int vsync_on = enable ? 1 : 0;
+  if (ioctl_(device_fd_, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_on) < 0) {
+    IOCTL_LOGE(MSMFB_OVERLAY_VSYNC_CTRL, device_type_);
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+}  // namespace sde
+
diff --git a/displayengine/libs/core/fb/hw_primary.h b/displayengine/libs/core/fb/hw_primary.h
new file mode 100644
index 0000000..8ede12d
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_primary.h
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2015, 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_PRIMARY_H__
+#define __HW_PRIMARY_H__
+
+#include "hw_device.h"
+#include "hw_primary_interface.h"
+
+namespace sde {
+
+class HWPrimary : public HWDevice, public HWPrimaryInterface {
+ public:
+  HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+  virtual DisplayError Init();
+  virtual DisplayError Deinit();
+  virtual DisplayError Open(HWEventHandler *eventhandler);
+  virtual DisplayError Close();
+  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
+  virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                            uint32_t index);
+  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
+  virtual DisplayError SetDisplayAttributes(uint32_t index);
+  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  virtual DisplayError PowerOn();
+  virtual DisplayError PowerOff();
+  virtual DisplayError Doze();
+  virtual DisplayError Standby();
+  virtual DisplayError Validate(HWLayers *hw_layers);
+  virtual DisplayError Commit(HWLayers *hw_layers);
+  virtual DisplayError Flush();
+  virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
+  virtual DisplayError SetVSyncState(bool enable);
+
+ private:
+  // Event Thread to receive vsync/blank events
+  static void* DisplayEventThread(void *context);
+  void* DisplayEventThreadHandler();
+
+  void HandleVSync(char *data);
+  void HandleBlank(char *data);
+  void HandleIdleTimeout(char *data);
+
+  pollfd poll_fds_[kNumDisplayEvents];
+  pthread_t event_thread_;
+  const char *event_thread_name_;
+  bool fake_vsync_;
+  bool exit_threads_;
+};
+
+}  // namespace sde
+
+#endif  // __HW_PRIMARY_H__
+
diff --git a/displayengine/libs/core/fb/hw_rotator.cpp b/displayengine/libs/core/fb/hw_rotator.cpp
new file mode 100644
index 0000000..cc9caa5
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_rotator.cpp
@@ -0,0 +1,311 @@
+/*
+* Copyright (c) 2015, 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 <sys/ioctl.h>
+#include <fcntl.h>
+#include "hw_rotator.h"
+
+#define __CLASS__ "HWRotator"
+
+namespace sde {
+
+DisplayError HWRotatorInterface::Create(HWRotatorInterface **intf,
+                                        BufferSyncHandler *buffer_sync_handler) {
+  DisplayError error = kErrorNone;
+  HWRotator *hw_rotator = NULL;
+
+  hw_rotator = new HWRotator(buffer_sync_handler);
+  if (!hw_rotator) {
+    error = kErrorMemory;
+  } else {
+    *intf = hw_rotator;
+  }
+  return error;
+}
+
+DisplayError HWRotatorInterface::Destroy(HWRotatorInterface *intf) {
+  delete intf;
+  intf = NULL;
+
+  return kErrorNone;
+}
+
+HWRotator::HWRotator(BufferSyncHandler *buffer_sync_handler) : HWDevice(buffer_sync_handler) {
+  HWDevice::device_type_ = kDeviceRotator;
+  HWDevice::device_name_ = "Rotator Device";
+}
+
+DisplayError HWRotator::Open() {
+  DisplayError error = kErrorNone;
+
+  char device_name[64] = {0};
+  snprintf(device_name, sizeof(device_name), "%s", "/dev/mdss_rotator");
+
+  HWDevice::device_fd_ = open_(device_name, O_RDWR);
+  if (HWDevice::device_fd_ < 0) {
+    DLOGE("open %s failed err = %d errstr = %s", device_name, errno,  strerror(errno));
+    return kErrorResources;
+  }
+
+  return error;
+}
+
+DisplayError HWRotator::Close() {
+  if (HWDevice::device_fd_ > 0) {
+    close_(HWDevice::device_fd_);
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWRotator::OpenSession(HWRotateInfo *rotate_info) {
+  LayerBuffer *input_buffer = rotate_info->input_buffer;
+  HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
+
+  ResetRotatorParams();
+
+  STRUCT_VAR(mdp_rotation_config, mdp_rot_config);
+  mdp_rot_config.version = MDP_ROTATION_REQUEST_VERSION_1_0;
+  mdp_rot_config.input.width = input_buffer->width;
+  mdp_rot_config.input.height = input_buffer->height;
+  HWDevice::SetFormat(input_buffer->format, &mdp_rot_config.input.format);
+  mdp_rot_config.output.width = rot_buf_info->output_buffer.width;
+  mdp_rot_config.output.height = rot_buf_info->output_buffer.height;
+  HWDevice::SetFormat(rot_buf_info->output_buffer.format, &mdp_rot_config.output.format);
+  mdp_rot_config.frame_rate = rotate_info->frame_rate;
+
+  if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_OPEN, &mdp_rot_config) < 0) {
+    IOCTL_LOGE(MDSS_ROTATION_OPEN, HWDevice::device_type_);
+    return kErrorHardware;
+  }
+
+  rot_buf_info->session_id = mdp_rot_config.session_id;
+
+  DLOGV_IF(kTagDriverConfig, "session_id %d", rot_buf_info->session_id);
+
+  return kErrorNone;
+}
+
+DisplayError HWRotator::CloseSession(int32_t session_id) {
+  if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_CLOSE, (uint32_t)session_id) < 0) {
+    IOCTL_LOGE(MDSS_ROTATION_CLOSE, HWDevice::device_type_);
+    return kErrorHardware;
+  }
+
+  DLOGV_IF(kTagDriverConfig, "session_id %d", session_id);
+
+  return kErrorNone;
+}
+
+void HWRotator::SetRotatorCtrlParams(HWLayers *hw_layers) {
+  DLOGV_IF(kTagDriverConfig, "************************* %s Validate Input ************************",
+           HWDevice::device_name_);
+
+  ResetRotatorParams();
+
+  HWLayersInfo &hw_layer_info = hw_layers->info;
+
+  uint32_t &rot_count = mdp_rot_request_.count;
+  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+    Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
+
+    for (uint32_t count = 0; count < 2; count++) {
+      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
+
+      if (rotate_info->valid) {
+        HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
+        mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
+        bool rot90 = (layer.transform.rotation == 90.0f);
+
+        if (rot90) {
+          mdp_rot_item->flags |= MDP_ROTATION_90;
+        }
+
+        if (layer.transform.flip_horizontal) {
+          mdp_rot_item->flags |= MDP_ROTATION_FLIP_LR;
+        }
+
+        if (layer.transform.flip_vertical) {
+          mdp_rot_item->flags |= MDP_ROTATION_FLIP_UD;
+        }
+
+        HWDevice::SetRect(rotate_info->src_roi, &mdp_rot_item->src_rect);
+        HWDevice::SetRect(rotate_info->dst_roi, &mdp_rot_item->dst_rect);
+
+        // TODO(user): Need to assign the writeback id and pipe id  returned from resource manager.
+        mdp_rot_item->pipe_idx = 0;
+        mdp_rot_item->wb_idx = 0;
+
+        mdp_rot_item->input.width = layer.input_buffer->width;
+        mdp_rot_item->input.height = layer.input_buffer->height;
+        HWDevice::SetFormat(layer.input_buffer->format, &mdp_rot_item->input.format);
+
+        mdp_rot_item->output.width = rot_buf_info->output_buffer.width;
+        mdp_rot_item->output.height = rot_buf_info->output_buffer.height;
+        HWDevice::SetFormat(rot_buf_info->output_buffer.format, &mdp_rot_item->output.format);
+
+        rot_count++;
+
+        DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
+                 i, count ? "Right" : "Left");
+        DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d,\t out_w %d, out_h %d, out_f %d",
+                 mdp_rot_item->input.width, mdp_rot_item->input.height, mdp_rot_item->input.format,
+                 mdp_rot_item->output.width, mdp_rot_item->output.height,
+                 mdp_rot_item->output.format);
+        DLOGV_IF(kTagDriverConfig, "pipe_id %d, wb_id %d, rot_flag %d", mdp_rot_item->pipe_idx,
+                 mdp_rot_item->wb_idx, mdp_rot_item->flags);
+        DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_rot_item->src_rect.x,
+                 mdp_rot_item->src_rect.y, mdp_rot_item->src_rect.w, mdp_rot_item->src_rect.h);
+        DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_rot_item->dst_rect.x,
+                 mdp_rot_item->dst_rect.y, mdp_rot_item->dst_rect.w, mdp_rot_item->dst_rect.h);
+        DLOGV_IF(kTagDriverConfig, "*************************************************************");
+      }
+    }
+  }
+}
+
+void HWRotator::SetRotatorBufferParams(HWLayers *hw_layers) {
+  HWLayersInfo &hw_layer_info = hw_layers->info;
+  uint32_t rot_count = 0;
+
+  DLOGV_IF(kTagDriverConfig, "************************* %s Commit Input **************************",
+           HWDevice::device_name_);
+  DLOGV_IF(kTagDriverConfig, "Rotate layer count is %d", mdp_rot_request_.count);
+
+  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+    Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
+
+    for (uint32_t count = 0; count < 2; count++) {
+      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
+
+      if (rotate_info->valid) {
+        HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
+        mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
+
+        mdp_rot_item->input.planes[0].fd = layer.input_buffer->planes[0].fd;
+        mdp_rot_item->input.planes[0].offset = layer.input_buffer->planes[0].offset;
+        HWDevice::SetStride(HWDevice::device_type_, layer.input_buffer->format,
+                            layer.input_buffer->width, &mdp_rot_item->input.planes[0].stride);
+        mdp_rot_item->input.plane_count = 1;
+        mdp_rot_item->input.fence = layer.input_buffer->acquire_fence_fd;
+
+        mdp_rot_item->output.planes[0].fd = rot_buf_info->output_buffer.planes[0].fd;
+        mdp_rot_item->output.planes[0].offset = rot_buf_info->output_buffer.planes[0].offset;
+        HWDevice::SetStride(HWDevice::device_type_, rot_buf_info->output_buffer.format,
+                            rot_buf_info->output_buffer.planes[0].stride,
+                            &mdp_rot_item->output.planes[0].stride);
+        mdp_rot_item->output.plane_count = 1;
+        mdp_rot_item->output.fence = -1;
+
+        rot_count++;
+
+        DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
+                 i, count ? "Right" : "Left");
+        DLOGV_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_stride %d, " \
+                 "in_plane_count %d, in_fence %d", mdp_rot_item->input.planes[0].fd,
+                 mdp_rot_item->input.planes[0].offset, mdp_rot_item->input.planes[0].stride,
+                 mdp_rot_item->input.plane_count, mdp_rot_item->input.fence);
+        DLOGV_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, out_plane_count %d, " \
+                 "out_fence %d", mdp_rot_item->output.planes[0].fd,
+                 mdp_rot_item->output.planes[0].offset, mdp_rot_item->output.planes[0].stride,
+                 mdp_rot_item->output.plane_count, mdp_rot_item->output.fence);
+        DLOGV_IF(kTagDriverConfig, "*************************************************************");
+      }
+    }
+  }
+}
+
+DisplayError HWRotator::Validate(HWLayers *hw_layers) {
+  SetRotatorCtrlParams(hw_layers);
+
+  mdp_rot_request_.flags = MDSS_ROTATION_REQUEST_VALIDATE;
+  if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_REQUEST, &mdp_rot_request_) < 0) {
+    IOCTL_LOGE(MDSS_ROTATION_REQUEST, HWDevice::device_type_);
+    return kErrorHardware;
+  }
+
+  return kErrorNone;
+}
+
+DisplayError HWRotator::Commit(HWLayers *hw_layers) {
+  HWLayersInfo &hw_layer_info = hw_layers->info;
+  uint32_t rot_count = 0;
+
+  SetRotatorCtrlParams(hw_layers);
+
+  SetRotatorBufferParams(hw_layers);
+
+  mdp_rot_request_.flags &= ~MDSS_ROTATION_REQUEST_VALIDATE;
+  if (ioctl_(HWDevice::device_fd_, MDSS_ROTATION_REQUEST, &mdp_rot_request_) < 0) {
+    IOCTL_LOGE(MDSS_ROTATION_REQUEST, HWDevice::device_type_);
+    return kErrorHardware;
+  }
+
+  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
+    Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
+
+    layer.input_buffer->release_fence_fd = -1;
+
+    for (uint32_t count = 0; count < 2; count++) {
+      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
+
+      if (rotate_info->valid) {
+        HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
+        mdp_rotation_item *mdp_rot_item = &mdp_rot_request_.list[rot_count];
+
+        HWDevice::SyncMerge(layer.input_buffer->release_fence_fd, dup(mdp_rot_item->output.fence),
+                            &layer.input_buffer->release_fence_fd);
+
+        rot_buf_info->output_buffer.acquire_fence_fd = dup(mdp_rot_item->output.fence);
+
+        close_(mdp_rot_item->output.fence);
+        rot_count++;
+      }
+    }
+  }
+
+  return kErrorNone;
+}
+
+void HWRotator::ResetRotatorParams() {
+  memset(&mdp_rot_request_, 0, sizeof(mdp_rot_request_));
+  memset(&mdp_rot_layers_, 0, sizeof(mdp_rot_layers_));
+
+  for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
+    mdp_rot_layers_[i].input.fence = -1;
+    mdp_rot_layers_[i].output.fence = -1;
+  }
+
+  mdp_rot_request_.version = MDP_ROTATION_REQUEST_VERSION_1_0;
+  mdp_rot_request_.list = mdp_rot_layers_;
+}
+
+}  // namespace sde
+
diff --git a/displayengine/libs/core/fb/hw_rotator.h b/displayengine/libs/core/fb/hw_rotator.h
new file mode 100644
index 0000000..6e7727d
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_rotator.h
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 2015, 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_ROTATOR_H__
+#define __HW_ROTATOR_H__
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/msm_mdp_ext.h>
+#include <video/msm_hdmi_modes.h>
+#include <linux/mdss_rotator.h>
+#include <poll.h>
+#include <pthread.h>
+
+#include "hw_device.h"
+#include "hw_rotator_interface.h"
+
+namespace sde {
+
+class HWRotator : public HWDevice, public HWRotatorInterface {
+ public:
+  explicit HWRotator(BufferSyncHandler *buffer_sync_handler);
+  virtual DisplayError Open();
+  virtual DisplayError Close();
+  virtual DisplayError OpenSession(HWRotateInfo *hw_layers);
+  virtual DisplayError CloseSession(int32_t session_id);
+  virtual DisplayError Validate(HWLayers *hw_layers);
+  virtual DisplayError Commit(HWLayers *hw_layers);
+
+ private:
+  void ResetRotatorParams();
+  void SetRotatorCtrlParams(HWLayers *hw_layers);
+  void SetRotatorBufferParams(HWLayers *hw_layers);
+
+  struct mdp_rotation_request mdp_rot_request_;
+  struct mdp_rotation_item mdp_rot_layers_[kMaxSDELayers * 2];  // split panel (left + right)
+};
+
+}  // namespace sde
+
+#endif  // __HW_ROTATOR_H__
+
diff --git a/displayengine/libs/core/fb/hw_virtual.cpp b/displayengine/libs/core/fb/hw_virtual.cpp
new file mode 100644
index 0000000..2d7cd3e
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_virtual.cpp
@@ -0,0 +1,134 @@
+/*
+* Copyright (c) 2015, 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_virtual.h"
+
+#define __CLASS__ "HWVirtual"
+
+namespace sde {
+
+DisplayError HWVirtualInterface::Create(HWVirtualInterface **intf, HWInfoInterface *hw_info_intf,
+                                        BufferSyncHandler *buffer_sync_handler) {
+  DisplayError error = kErrorNone;
+  HWVirtual *hw_virtual = NULL;
+
+  hw_virtual = new HWVirtual(buffer_sync_handler, hw_info_intf);
+  error = hw_virtual->Init();
+  if (UNLIKELY(error != kErrorNone)) {
+    delete hw_virtual;
+  } else {
+    *intf = hw_virtual;
+  }
+
+  return error;
+}
+
+DisplayError HWVirtualInterface::Destroy(HWVirtualInterface *intf) {
+  HWVirtual *hw_virtual = static_cast<HWVirtual *>(intf);
+  hw_virtual->Deinit();
+  delete hw_virtual;
+
+  return kErrorNone;
+}
+
+HWVirtual::HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
+  : HWDevice(buffer_sync_handler) {
+  HWDevice::device_type_ = kDeviceVirtual;
+  HWDevice::device_name_ = "Virtual Display Device";
+  HWDevice::hw_info_intf_ = hw_info_intf;
+}
+
+DisplayError HWVirtual::Init() {
+  return HWDevice::Init();
+}
+
+DisplayError HWVirtual::Deinit() {
+  return kErrorNone;
+}
+
+DisplayError HWVirtual::Open(HWEventHandler *eventhandler) {
+  return HWDevice::Open(eventhandler);
+}
+
+DisplayError HWVirtual::Close() {
+  return HWDevice::Close();
+}
+
+DisplayError HWVirtual::GetNumDisplayAttributes(uint32_t *count) {
+  return HWDevice::GetNumDisplayAttributes(count);
+}
+
+DisplayError HWVirtual::GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                             uint32_t index) {
+  return HWDevice::GetDisplayAttributes(display_attributes, index);
+}
+
+DisplayError HWVirtual::SetDisplayAttributes(uint32_t index) {
+  return HWDevice::SetDisplayAttributes(index);
+}
+
+DisplayError HWVirtual::GetConfigIndex(uint32_t mode, uint32_t *index) {
+  return HWDevice::GetConfigIndex(mode, index);
+}
+
+DisplayError HWVirtual::PowerOn() {
+  return HWDevice::PowerOn();
+}
+
+DisplayError HWVirtual::PowerOff() {
+  return HWDevice::PowerOff();
+}
+
+DisplayError HWVirtual::Doze() {
+  return HWDevice::Doze();
+}
+
+DisplayError HWVirtual::Standby() {
+  return HWDevice::Standby();
+}
+
+DisplayError HWVirtual::Validate(HWLayers *hw_layers) {
+  return HWDevice::Validate(hw_layers);
+}
+
+DisplayError HWVirtual::Commit(HWLayers *hw_layers) {
+  return HWDevice::Commit(hw_layers);
+}
+
+DisplayError HWVirtual::Flush() {
+  return HWDevice::Flush();
+}
+
+DisplayError HWVirtual::GetHWPanelInfo(HWPanelInfo *panel_info) {
+  return HWDevice::GetHWPanelInfo(panel_info);
+}
+
+}  // namespace sde
+
diff --git a/displayengine/libs/core/fb/hw_virtual.h b/displayengine/libs/core/fb/hw_virtual.h
new file mode 100644
index 0000000..fb7c784
--- /dev/null
+++ b/displayengine/libs/core/fb/hw_virtual.h
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2015, 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_VIRTUAL_H__
+#define __HW_VIRTUAL_H__
+
+#include "hw_device.h"
+#include "hw_virtual_interface.h"
+
+namespace sde {
+
+class HWVirtual : public HWDevice, public HWVirtualInterface {
+ public:
+  HWVirtual(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf);
+  virtual DisplayError Init();
+  virtual DisplayError Deinit();
+  virtual DisplayError Open(HWEventHandler *eventhandler);
+  virtual DisplayError Close();
+  virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
+  virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                            uint32_t index);
+  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info);
+  virtual DisplayError SetDisplayAttributes(uint32_t index);
+  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index);
+  virtual DisplayError PowerOn();
+  virtual DisplayError PowerOff();
+  virtual DisplayError Doze();
+  virtual DisplayError Standby();
+  virtual DisplayError Validate(HWLayers *hw_layers);
+  virtual DisplayError Commit(HWLayers *hw_layers);
+  virtual DisplayError Flush();
+};
+
+}  // namespace sde
+
+#endif  // __HW_VIRTUAL_H__
+
diff --git a/displayengine/libs/core/hw_framebuffer.cpp b/displayengine/libs/core/hw_framebuffer.cpp
deleted file mode 100644
index f3cdb8b..0000000
--- a/displayengine/libs/core/hw_framebuffer.cpp
+++ /dev/null
@@ -1,1683 +0,0 @@
-/*
-* Copyright (c) 2014 - 2015, 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.
-*/
-
-#define __STDC_FORMAT_MACROS
-#include <ctype.h>
-#include <math.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <linux/fb.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <pthread.h>
-#include <utils/constants.h>
-#include <utils/debug.h>
-
-#include "hw_framebuffer.h"
-#include "scalar_helper.h"
-
-#define __CLASS__ "HWFrameBuffer"
-
-#define IOCTL_LOGE(ioctl, type) DLOGE("ioctl %s, device = %d errno = %d, desc = %s", #ioctl, \
-                                      type, errno, strerror(errno))
-
-#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
-extern int virtual_ioctl(int fd, int cmd, ...);
-extern int virtual_open(const char *file_name, int access, ...);
-extern int virtual_close(int fd);
-extern int virtual_poll(struct pollfd *fds,  nfds_t num, int timeout);
-extern ssize_t virtual_pread(int fd, void *data, size_t count, off_t offset);
-extern ssize_t virtual_pwrite(int fd, const void *data, size_t count, off_t offset);
-extern FILE* virtual_fopen(const char *fname, const char *mode);
-extern int virtual_fclose(FILE* fileptr);
-extern ssize_t virtual_getline(char **lineptr, size_t *linelen, FILE *stream);
-
-#endif
-
-namespace sde {
-
-HWFrameBuffer::HWFrameBuffer(BufferSyncHandler *buffer_sync_handler)
-  : event_thread_name_("SDE_EventThread"), fake_vsync_(false), exit_threads_(false),
-    fb_path_("/sys/devices/virtual/graphics/fb"), hotplug_enabled_(false),
-    buffer_sync_handler_(buffer_sync_handler) {
-  // Pointer to actual driver interfaces.
-  ioctl_ = ::ioctl;
-  open_ = ::open;
-  close_ = ::close;
-  poll_ = ::poll;
-  pread_ = ::pread;
-  pwrite_ = ::pwrite;
-  fopen_ = ::fopen;
-  fclose_ = ::fclose;
-  getline_ = ::getline;
-
-#ifdef DISPLAY_CORE_VIRTUAL_DRIVER
-  // If debug property to use virtual driver is set, point to virtual driver interfaces.
-  if (Debug::IsVirtualDriver()) {
-    ioctl_ = virtual_ioctl;
-    open_ = virtual_open;
-    close_ = virtual_close;
-    poll_ = virtual_poll;
-    pread_ = virtual_pread;
-    pwrite_ = virtual_pwrite;
-    fopen_ = virtual_fopen;
-    fclose_ = virtual_fclose;
-    getline_ = virtual_getline;
-  }
-#endif
-  for (int i = 0; i < kDeviceMax; i++) {
-    fb_node_index_[i] = -1;
-  }
-}
-
-DisplayError HWFrameBuffer::Init() {
-  DisplayError error = kErrorNone;
-  char node_path[kMaxStringLength] = {0};
-  char data[kMaxStringLength] = {0};
-  const char* event_name[kNumDisplayEvents] = {"vsync_event", "show_blank_event", "idle_notify"};
-
-  // Read the fb node index
-  PopulateFBNodeIndex();
-  if (fb_node_index_[kHWPrimary] == -1) {
-    DLOGE("HW Display Device Primary should be present");
-    error = kErrorHardware;
-    goto CleanupOnError;
-  }
-
-  // Populate Primary Panel Info(Used for Partial Update)
-  PopulatePanelInfo(fb_node_index_[kHWPrimary]);
-  // Populate HW Capabilities
-  error = PopulateHWCapabilities();
-  if (error != kErrorNone) {
-    goto CleanupOnError;
-  }
-
-  // Open nodes for polling
-  for (int display = 0; display < kNumPhysicalDisplays; display++) {
-    for (int event = 0; event < kNumDisplayEvents; event++) {
-      poll_fds_[display][event].fd = -1;
-    }
-  }
-
-  if (!fake_vsync_) {
-    for (int display = 0; display < kNumPhysicalDisplays; display++) {
-      for (int event = 0; event < kNumDisplayEvents; event++) {
-        pollfd &poll_fd = poll_fds_[display][event];
-
-        if ((primary_panel_info_.type == kCommandModePanel) && (display == kDevicePrimary) &&
-            (!strncmp(event_name[event], "idle_notify", strlen("idle_notify")))) {
-          continue;
-        }
-
-        snprintf(node_path, sizeof(node_path), "%s%d/%s", fb_path_, fb_node_index_[display],
-                 event_name[event]);
-
-        poll_fd.fd = open_(node_path, O_RDONLY);
-        if (poll_fd.fd < 0) {
-          DLOGE("open failed for display=%d event=%d, error=%s", display, event, strerror(errno));
-          error = kErrorHardware;
-          goto CleanupOnError;
-        }
-
-        // Read once on all fds to clear data on all fds.
-        pread_(poll_fd.fd, data , kMaxStringLength, 0);
-        poll_fd.events = POLLPRI | POLLERR;
-      }
-    }
-  }
-
-  // Mode look-up table for HDMI
-  supported_video_modes_ = new msm_hdmi_mode_timing_info[HDMI_VFRMT_MAX];
-  if (!supported_video_modes_) {
-    error = kErrorMemory;
-    goto CleanupOnError;
-  }
-  // Populate the mode table for supported modes
-  MSM_HDMI_MODES_INIT_TIMINGS(supported_video_modes_);
-  MSM_HDMI_MODES_SET_SUPP_TIMINGS(supported_video_modes_, MSM_HDMI_MODES_ALL);
-
-  // Start the Event thread
-  if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) {
-    DLOGE("Failed to start %s, error = %s", event_thread_name_);
-    error = kErrorResources;
-    goto CleanupOnError;
-  }
-
-  // Disable HPD at start if HDMI is external, it will be enabled later when the display powers on
-  // This helps for framework reboot or adb shell stop/start
-  EnableHotPlugDetection(0);
-
-  return kErrorNone;
-
-CleanupOnError:
-  // Close all poll fds
-  for (int display = 0; display < kNumPhysicalDisplays; display++) {
-    for (int event = 0; event < kNumDisplayEvents; event++) {
-      int &fd = poll_fds_[display][event].fd;
-      if (fd >= 0) {
-        close_(fd);
-      }
-    }
-  }
-  if (supported_video_modes_) {
-    delete supported_video_modes_;
-  }
-
-  return error;
-}
-
-DisplayError HWFrameBuffer::Deinit() {
-  exit_threads_ = true;
-  pthread_join(event_thread_, NULL);
-
-  for (int display = 0; display < kNumPhysicalDisplays; display++) {
-    for (int event = 0; event < kNumDisplayEvents; event++) {
-      close_(poll_fds_[display][event].fd);
-    }
-  }
-  if (supported_video_modes_) {
-    delete supported_video_modes_;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::GetHWCapabilities(HWResourceInfo *hw_res_info) {
-  *hw_res_info = hw_resource_;
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::Open(HWDeviceType type, Handle *device, HWEventHandler* eventhandler) {
-  DisplayError error = kErrorNone;
-
-  HWContext *hw_context = new HWContext();
-  if (!hw_context) {
-    return kErrorMemory;
-  }
-
-  char device_name[64] = {0};
-
-  switch (type) {
-  case kDevicePrimary:
-  case kDeviceHDMI:
-    // Store EventHandlers for two Physical displays, i.e., Primary and HDMI
-    // TODO(user): Need to revisit for HDMI as Primary usecase
-    event_handler_[type] = eventhandler;
-  case kDeviceVirtual:
-    snprintf(device_name, sizeof(device_name), "%s%d", "/dev/graphics/fb", fb_node_index_[type]);
-    break;
-  case kDeviceRotator:
-    snprintf(device_name, sizeof(device_name), "%s", "/dev/mdss_rotator");
-    break;
-  default:
-    break;
-  }
-
-  hw_context->device_fd = open_(device_name, O_RDWR);
-  if (hw_context->device_fd < 0) {
-    DLOGE("open %s failed err = %d errstr = %s", device_name, errno,  strerror(errno));
-    delete hw_context;
-    return kErrorResources;
-  }
-
-  hw_context->type = type;
-
-  *device = hw_context;
-
-  return error;
-}
-
-DisplayError HWFrameBuffer::Close(Handle device) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-  case kDeviceVirtual:
-    break;
-  case kDeviceHDMI:
-    hdmi_mode_count_ = 0;
-    break;
-  default:
-    break;
-  }
-
-  if (hw_context->device_fd > 0) {
-    close_(hw_context->device_fd);
-  }
-  delete hw_context;
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::GetNumDisplayAttributes(Handle device, uint32_t *count) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-  case kDeviceVirtual:
-    *count = 1;
-    break;
-  case kDeviceHDMI:
-    *count = GetHDMIModeCount();
-    if (*count <= 0) {
-      return kErrorHardware;
-    }
-    break;
-  default:
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::GetDisplayAttributes(Handle device,
-                                                 HWDisplayAttributes *display_attributes,
-                                                 uint32_t index) {
-  DTRACE_SCOPED();
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  int &device_fd = hw_context->device_fd;
-  // Variable screen info
-  STRUCT_VAR(fb_var_screeninfo, var_screeninfo);
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-    {
-      if (ioctl_(device_fd, FBIOGET_VSCREENINFO, &var_screeninfo) < 0) {
-        IOCTL_LOGE(FBIOGET_VSCREENINFO, hw_context->type);
-        return kErrorHardware;
-      }
-
-      // Frame rate
-      STRUCT_VAR(msmfb_metadata, meta_data);
-      meta_data.op = metadata_op_frame_rate;
-      if (ioctl_(device_fd, MSMFB_METADATA_GET, &meta_data) < 0) {
-        IOCTL_LOGE(MSMFB_METADATA_GET, hw_context->type);
-        return kErrorHardware;
-      }
-
-      // If driver doesn't return width/height information, default to 160 dpi
-      if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) {
-        var_screeninfo.width  = INT(((FLOAT(var_screeninfo.xres) * 25.4f)/160.0f) + 0.5f);
-        var_screeninfo.height = INT(((FLOAT(var_screeninfo.yres) * 25.4f)/160.0f) + 0.5f);
-      }
-
-      display_attributes->x_pixels = var_screeninfo.xres;
-      display_attributes->y_pixels = var_screeninfo.yres;
-      display_attributes->v_total = var_screeninfo.yres + var_screeninfo.lower_margin +
-          var_screeninfo.upper_margin + var_screeninfo.vsync_len;
-      display_attributes->x_dpi =
-          (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width);
-      display_attributes->y_dpi =
-          (FLOAT(var_screeninfo.yres) * 25.4f) / FLOAT(var_screeninfo.height);
-      display_attributes->fps = FLOAT(meta_data.data.panel_frame_rate);
-      display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
-      display_attributes->is_device_split = (hw_resource_.split_info.left_split ||
-          (var_screeninfo.xres > hw_resource_.max_mixer_width)) ? true : false;
-      display_attributes->split_left = hw_resource_.split_info.left_split ?
-          hw_resource_.split_info.left_split : display_attributes->x_pixels / 2;
-    }
-    break;
-
-  case kDeviceHDMI:
-    {
-      // Get the resolution info from the look up table
-      msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
-      for (int i = 0; i < HDMI_VFRMT_MAX; i++) {
-        msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
-        if (cur->video_format == hdmi_modes_[index]) {
-          timing_mode = cur;
-          break;
-        }
-      }
-      display_attributes->x_pixels = timing_mode->active_h;
-      display_attributes->y_pixels = timing_mode->active_v;
-      display_attributes->v_total = timing_mode->active_v + timing_mode->front_porch_v +
-          timing_mode->back_porch_v + timing_mode->pulse_width_v;
-      display_attributes->x_dpi = 0;
-      display_attributes->y_dpi = 0;
-      display_attributes->fps = FLOAT(timing_mode->refresh_rate) / 1000.0f;
-      display_attributes->vsync_period_ns = UINT32(1000000000L / display_attributes->fps);
-      display_attributes->split_left = display_attributes->x_pixels;
-      if (display_attributes->x_pixels > hw_resource_.max_mixer_width) {
-        display_attributes->is_device_split = true;
-        display_attributes->split_left = display_attributes->x_pixels / 2;
-      }
-    }
-    break;
-
-  case kDeviceVirtual:
-    break;
-
-  default:
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::SetDisplayAttributes(Handle device, uint32_t index) {
-  DTRACE_SCOPED();
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  DisplayError error = kErrorNone;
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-  case kDeviceVirtual:
-    break;
-
-  case kDeviceHDMI:
-    {
-      // Variable screen info
-      STRUCT_VAR(fb_var_screeninfo, vscreeninfo);
-      if (ioctl_(hw_context->device_fd, FBIOGET_VSCREENINFO, &vscreeninfo) < 0) {
-        IOCTL_LOGE(FBIOGET_VSCREENINFO, hw_context->type);
-        return kErrorHardware;
-      }
-
-      DLOGI("GetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3],
-            vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
-            vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
-            vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
-
-      msm_hdmi_mode_timing_info *timing_mode = &supported_video_modes_[0];
-      for (int i = 0; i < HDMI_VFRMT_MAX; i++) {
-        msm_hdmi_mode_timing_info *cur = &supported_video_modes_[i];
-        if (cur->video_format == hdmi_modes_[index]) {
-          timing_mode = cur;
-          break;
-        }
-      }
-
-      if (MapHDMIDisplayTiming(timing_mode, &vscreeninfo) == false) {
-        return kErrorParameters;
-      }
-
-      STRUCT_VAR(msmfb_metadata, metadata);
-      metadata.op = metadata_op_vic;
-      metadata.data.video_info_code = timing_mode->video_format;
-      if (ioctl(hw_context->device_fd, MSMFB_METADATA_SET, &metadata) < 0) {
-        IOCTL_LOGE(MSMFB_METADATA_SET, hw_context->type);
-        return kErrorHardware;
-      }
-
-      DLOGI("SetInfo<Mode=%d %dx%d (%d,%d,%d),(%d,%d,%d) %dMHz>", vscreeninfo.reserved[3] & 0xFF00,
-            vscreeninfo.xres, vscreeninfo.yres, vscreeninfo.right_margin, vscreeninfo.hsync_len,
-            vscreeninfo.left_margin, vscreeninfo.lower_margin, vscreeninfo.vsync_len,
-            vscreeninfo.upper_margin, vscreeninfo.pixclock/1000000);
-
-      vscreeninfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
-      if (ioctl_(hw_context->device_fd, FBIOPUT_VSCREENINFO, &vscreeninfo) < 0) {
-        IOCTL_LOGE(FBIOGET_VSCREENINFO, hw_context->type);
-        return kErrorHardware;
-      }
-    }
-    break;
-
-  default:
-    return kErrorParameters;
-  }
-
-  return error;
-}
-
-DisplayError HWFrameBuffer::GetConfigIndex(Handle device, uint32_t mode, uint32_t *index) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-  case kDeviceVirtual:
-    return kErrorNone;
-    break;
-  case kDeviceHDMI:
-    // Check if the mode is valid and return corresponding index
-    for (uint32_t i = 0; i < hdmi_mode_count_; i++) {
-      if (hdmi_modes_[i] == mode) {
-        *index = i;
-        DLOGI("Index = %d for config = %d", *index, mode);
-        return kErrorNone;
-      }
-    }
-    break;
-  default:
-    return kErrorParameters;
-  }
-
-  DLOGE("Config = %d not supported", mode);
-  return kErrorNotSupported;
-}
-
-
-DisplayError HWFrameBuffer::PowerOn(Handle device) {
-  DTRACE_SCOPED();
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  if (ioctl_(hw_context->device_fd, FBIOBLANK, FB_BLANK_UNBLANK) < 0) {
-    IOCTL_LOGE(FB_BLANK_UNBLANK, hw_context->type);
-    return kErrorHardware;
-  }
-
-  // Need to turn on HPD
-  if (!hotplug_enabled_) {
-    hotplug_enabled_ = EnableHotPlugDetection(1);
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::PowerOff(Handle device) {
-  DTRACE_SCOPED();
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  HWDisplay *hw_display = &hw_context->hw_display;
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-    if (ioctl_(hw_context->device_fd, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) {
-      IOCTL_LOGE(FB_BLANK_POWERDOWN, hw_context->type);
-      return kErrorHardware;
-    }
-    break;
-  default:
-    break;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::Doze(Handle device) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::Standby(Handle device) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::SetVSyncState(Handle device, bool enable) {
-  DTRACE_SCOPED();
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  int vsync_on = enable ? 1 : 0;
-  if (ioctl_(hw_context->device_fd, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_on) < 0) {
-    IOCTL_LOGE(MSMFB_OVERLAY_VSYNC_CTRL, hw_context->type);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::OpenRotatorSession(Handle device, HWRotateInfo *rotate_info) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  HWRotator *hw_rotator = &hw_context->hw_rotator;
-  LayerBuffer *input_buffer = rotate_info->input_buffer;
-  HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
-
-  hw_rotator->Reset();
-
-  STRUCT_VAR(mdp_rotation_config, mdp_rot_config);
-  mdp_rot_config.version = MDP_ROTATION_REQUEST_VERSION_1_0;
-  mdp_rot_config.input.width = input_buffer->width;
-  mdp_rot_config.input.height = input_buffer->height;
-  SetFormat(input_buffer->format, &mdp_rot_config.input.format);
-  mdp_rot_config.output.width = rot_buf_info->output_buffer.width;
-  mdp_rot_config.output.height = rot_buf_info->output_buffer.height;
-  SetFormat(rot_buf_info->output_buffer.format, &mdp_rot_config.output.format);
-  mdp_rot_config.frame_rate = rotate_info->frame_rate;
-
-  if (ioctl_(hw_context->device_fd, MDSS_ROTATION_OPEN, &mdp_rot_config) < 0) {
-    IOCTL_LOGE(MDSS_ROTATION_OPEN, hw_context->type);
-    return kErrorHardware;
-  }
-
-  rot_buf_info->session_id = mdp_rot_config.session_id;
-
-  DLOGV_IF(kTagDriverConfig, "session_id %d", rot_buf_info->session_id);
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::CloseRotatorSession(Handle device, int32_t session_id) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  if (ioctl_(hw_context->device_fd, MDSS_ROTATION_CLOSE, (uint32_t)session_id) < 0) {
-    IOCTL_LOGE(MDSS_ROTATION_CLOSE, hw_context->type);
-    return kErrorHardware;
-  }
-
-  DLOGV_IF(kTagDriverConfig, "session_id %d", session_id);
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::Validate(Handle device, HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  DisplayError error = kErrorNone;
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  switch (hw_context->type) {
-    case kDevicePrimary:
-    case kDeviceHDMI:
-    case kDeviceVirtual:
-      error = DisplayValidate(hw_context, hw_layers);
-      if (error != kErrorNone) {
-        return error;
-      }
-      break;
-    case kDeviceRotator:
-      error = RotatorValidate(hw_context, hw_layers);
-      if (error != kErrorNone) {
-        return error;
-      }
-      break;
-    default:
-      break;
-  }
-  return error;
-}
-
-DisplayError HWFrameBuffer::Commit(Handle device, HWLayers *hw_layers) {
-  DisplayError error = kErrorNone;
-
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  switch (hw_context->type) {
-    case kDevicePrimary:
-    case kDeviceHDMI:
-    case kDeviceVirtual:
-      error = DisplayCommit(hw_context, hw_layers);
-      if (error != kErrorNone) {
-        return error;
-      }
-      break;
-    case kDeviceRotator:
-      error = RotatorCommit(hw_context, hw_layers);
-      if (error != kErrorNone) {
-        return error;
-      }
-      break;
-    default:
-      break;
-  }
-  return error;
-}
-
-DisplayError HWFrameBuffer::DisplayValidate(HWContext *hw_context, HWLayers *hw_layers) {
-  DisplayError error = kErrorNone;
-  HWDisplay *hw_display = &hw_context->hw_display;
-
-  hw_display->Reset();
-
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  LayerStack *stack = hw_layer_info.stack;
-
-  DLOGV_IF(kTagDriverConfig, "************************** %s Validate Input ***********************",
-           GetDeviceString(hw_context->type));
-  DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_info.count);
-
-  mdp_layer_commit_v1 &mdp_commit = hw_display->mdp_disp_commit.commit_v1;
-  mdp_input_layer *mdp_layers = hw_display->mdp_in_layers;
-  mdp_output_layer *mdp_out_layer = &hw_display->mdp_out_layer;
-  uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
-
-  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
-    uint32_t layer_index = hw_layer_info.index[i];
-    Layer &layer = stack->layers[layer_index];
-    LayerBuffer *input_buffer = layer.input_buffer;
-    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
-    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
-    mdp_input_layer mdp_layer;
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
-      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
-
-      if (rotate_info->valid) {
-        input_buffer = &rotate_info->hw_buffer_info.output_buffer;
-      }
-
-      if (pipe_info->valid) {
-        mdp_input_layer &mdp_layer = mdp_layers[mdp_layer_count];
-        mdp_layer_buffer &mdp_buffer = mdp_layer.buffer;
-
-        mdp_buffer.width = input_buffer->width;
-        mdp_buffer.height = input_buffer->height;
-
-        error = SetFormat(input_buffer->format, &mdp_buffer.format);
-        if (error != kErrorNone) {
-          return error;
-        }
-
-        mdp_layer.alpha = layer.plane_alpha;
-        mdp_layer.z_order = UINT16(pipe_info->z_order);
-        mdp_layer.transp_mask = 0xffffffff;
-        SetBlending(layer.blending, &mdp_layer.blend_op);
-        mdp_layer.pipe_ndx = pipe_info->pipe_id;
-        mdp_layer.horz_deci = pipe_info->horizontal_decimation;
-        mdp_layer.vert_deci = pipe_info->vertical_decimation;
-
-        SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
-        SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
-
-        // Flips will be taken care by rotator, if layer requires 90 rotation. So Dont use MDP for
-        // flip operation, if layer transform is 90.
-        if (!layer.transform.rotation) {
-          if (layer.transform.flip_vertical) {
-            mdp_layer.flags |= MDP_LAYER_FLIP_UD;
-          }
-
-          if (layer.transform.flip_horizontal) {
-            mdp_layer.flags |= MDP_LAYER_FLIP_LR;
-          }
-        }
-
-        mdp_scale_data* mdp_scale = hw_display->GetScaleDataRef(mdp_layer_count);
-#ifdef USES_SCALAR
-        // Set the configured scale data for MDP driver
-        ScalarHelper::GetInstance()->SetScaleData(i, !count, mdp_scale);
-        if (mdp_scale->enable_pxl_ext) {
-          if ((mdp_layer.flags & MDP_LAYER_DEINTERLACE) && (layer.transform.rotation == 90.0f))
-            ScalarHelper::GetInstance()->UpdateSrcWidth(i, !count, &mdp_buffer.width);
-        }
-#endif
-        mdp_layer.scale = mdp_scale;
-        mdp_layer_count++;
-
-        DLOGV_IF(kTagDriverConfig, "******************* Layer[%d] %s pipe Input ******************",
-                 i, count ? "Right" : "Left");
-        DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d", mdp_buffer.width, mdp_buffer.height,
-                 mdp_buffer.format);
-        DLOGV_IF(kTagDriverConfig, "plane_alpha %d, zorder %d, blending %d, horz_deci %d, "
-                 "vert_deci %d", mdp_layer.alpha, mdp_layer.z_order, mdp_layer.blend_op,
-                 mdp_layer.horz_deci, mdp_layer.vert_deci);
-        DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_layer.src_rect.x,
-                 mdp_layer.src_rect.y, mdp_layer.src_rect.w, mdp_layer.src_rect.h);
-        DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_layer.dst_rect.x,
-                 mdp_layer.dst_rect.y, mdp_layer.dst_rect.w, mdp_layer.dst_rect.h);
-        for (int j = 0; j < MAX_PLANES; j++) {
-          DLOGV_IF(kTagDriverConfig, "Scale Data[%d]: Phase=[%x %x %x %x] Pixel_Ext=[%d %d %d %d]",
-                 j, mdp_layer.scale->init_phase_x[j], mdp_layer.scale->phase_step_x[j],
-                 mdp_layer.scale->init_phase_y[j], mdp_layer.scale->phase_step_y[j],
-                 mdp_layer.scale->num_ext_pxls_left[j], mdp_layer.scale->num_ext_pxls_top[j],
-                 mdp_layer.scale->num_ext_pxls_right[j], mdp_layer.scale->num_ext_pxls_btm[j]);
-          DLOGV_IF(kTagDriverConfig, "Fetch=[%d %d %d %d]  Repeat=[%d %d %d %d]  roi_width = %d",
-                 mdp_layer.scale->left_ftch[j], mdp_layer.scale->top_ftch[j],
-                 mdp_layer.scale->right_ftch[j], mdp_layer.scale->btm_ftch[j],
-                 mdp_layer.scale->left_rpt[j], mdp_layer.scale->top_rpt[j],
-                 mdp_layer.scale->right_rpt[j], mdp_layer.scale->btm_rpt[j],
-                 mdp_layer.scale->roi_w[j]);
-        }
-        DLOGV_IF(kTagDriverConfig, "*************************************************************");
-      }
-    }
-  }
-
-  if (hw_context->type == kDeviceVirtual) {
-    LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-    // TODO(user): Need to assign the writeback id from the resource manager, since the support
-    // has not been added hard coding it to 2 for now.
-    mdp_out_layer->writeback_ndx = 2;
-    mdp_out_layer->buffer.width = output_buffer->width;
-    mdp_out_layer->buffer.height = output_buffer->height;
-    SetFormat(output_buffer->format, &mdp_out_layer->buffer.format);
-
-    DLOGI_IF(kTagDriverConfig, "******************* Output buffer Info **********************");
-    DLOGI_IF(kTagDriverConfig, "out_w %d, out_h %d, out_f %d, wb_id %d",
-             mdp_out_layer->buffer.width, mdp_out_layer->buffer.height,
-             mdp_out_layer->buffer.format, mdp_out_layer->writeback_ndx);
-    DLOGI_IF(kTagDriverConfig, "*************************************************************");
-  }
-
-  mdp_commit.flags |= MDP_VALIDATE_LAYER;
-  if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_display->mdp_disp_commit) < 0) {
-    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
-    DumpLayerCommit(hw_display->mdp_disp_commit);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-void HWFrameBuffer::DumpLayerCommit(mdp_layer_commit &layer_commit) {
-  mdp_layer_commit_v1 &mdp_commit = layer_commit.commit_v1;
-  mdp_input_layer *mdp_layers = mdp_commit.input_layers;
-
-  DLOGE("mdp_commt: flags = %x, release fence = %x", mdp_commit.flags, mdp_commit.release_fence);
-  DLOGE("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
-         mdp_commit.left_roi.w, mdp_commit.left_roi.h);
-  DLOGE("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
-         mdp_commit.right_roi.y, mdp_commit.right_roi.w, mdp_commit.right_roi.h);
-  for (uint32_t i = 0; i < mdp_commit.input_layer_cnt; i++) {
-    DLOGE("mdp_commt: layer_cnt = %d, pipe_ndx = %x, zorder = %d, flags = %x",
-          i, mdp_layers[i].pipe_ndx, mdp_layers[i].z_order, mdp_layers[i].flags);
-    mdp_rect &src_rect = mdp_layers[i].src_rect;
-    DLOGE("src rect: x = %d, y = %d, w = %d, h = %d",
-          src_rect.x, src_rect.y, src_rect.w, src_rect.h);
-    mdp_rect &dst_rect = mdp_layers[i].dst_rect;
-    DLOGE("dst rect: x = %d, y = %d, w = %d, h = %d",
-          dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
-  }
-}
-
-DisplayError HWFrameBuffer::DisplayCommit(HWContext *hw_context, HWLayers *hw_layers) {
-  DTRACE_SCOPED();
-
-  HWDisplay *hw_display = &hw_context->hw_display;
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  LayerStack *stack = hw_layer_info.stack;
-
-  DLOGV_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
-           GetDeviceString(hw_context->type));
-  DLOGV_IF(kTagDriverConfig, "SDE layer count is %d", hw_layer_info.count);
-
-  mdp_layer_commit_v1 &mdp_commit = hw_display->mdp_disp_commit.commit_v1;
-  mdp_input_layer *mdp_layers = hw_display->mdp_in_layers;
-  mdp_output_layer *mdp_out_layer = &hw_display->mdp_out_layer;
-  uint32_t mdp_layer_index = 0;
-
-  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
-    uint32_t layer_index = hw_layer_info.index[i];
-    LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
-    HWPipeInfo *left_pipe = &hw_layers->config[i].left_pipe;
-    HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
-      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
-
-      if (rotate_info->valid) {
-        input_buffer = &rotate_info->hw_buffer_info.output_buffer;
-      }
-
-      if (pipe_info->valid) {
-        mdp_layer_buffer &mdp_buffer = mdp_layers[mdp_layer_index].buffer;
-        mdp_input_layer &mdp_layer = mdp_layers[mdp_layer_index];
-        if (input_buffer->planes[0].fd >= 0) {
-          mdp_buffer.plane_count = 1;
-          mdp_buffer.planes[0].fd = input_buffer->planes[0].fd;
-          mdp_buffer.planes[0].offset = input_buffer->planes[0].offset;
-          SetStride(hw_context->type, input_buffer->format, input_buffer->planes[0].stride,
-                    &mdp_buffer.planes[0].stride);
-        } else {
-          DLOGW("Invalid buffer fd, setting plane count to 0");
-          mdp_buffer.plane_count = 0;
-        }
-
-        mdp_buffer.fence = input_buffer->acquire_fence_fd;
-        mdp_layer_index++;
-
-        DLOGV_IF(kTagDriverConfig, "****************** Layer[%d] %s pipe Input *******************",
-                 i, count ? "Right" : "Left");
-        DLOGI_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d, horz_deci %d, vert_deci %d",
-                 mdp_buffer.width, mdp_buffer.height, mdp_buffer.format, mdp_layer.horz_deci,
-                 mdp_layer.vert_deci);
-        DLOGI_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_buf_stride %d, " \
-                 "in_plane_count %d, in_fence %d, layer count %d", mdp_buffer.planes[0].fd,
-                 mdp_buffer.planes[0].offset, mdp_buffer.planes[0].stride, mdp_buffer.plane_count,
-                 mdp_buffer.fence, mdp_commit.input_layer_cnt);
-        DLOGV_IF(kTagDriverConfig, "*************************************************************");
-      }
-    }
-  }
-  if (hw_context->type == kDeviceVirtual) {
-    LayerBuffer *output_buffer = hw_layers->info.stack->output_buffer;
-
-    if (output_buffer->planes[0].fd >= 0) {
-      mdp_out_layer->buffer.planes[0].fd = output_buffer->planes[0].fd;
-      mdp_out_layer->buffer.planes[0].offset = output_buffer->planes[0].offset;
-      SetStride(hw_context->type, output_buffer->format, output_buffer->planes[0].stride,
-                &mdp_out_layer->buffer.planes[0].stride);
-      mdp_out_layer->buffer.plane_count = 1;
-    } else {
-      DLOGW("Invalid output buffer fd, setting plane count to 0");
-      mdp_out_layer->buffer.plane_count = 0;
-    }
-
-    mdp_out_layer->buffer.fence = output_buffer->acquire_fence_fd;
-
-    DLOGI_IF(kTagDriverConfig, "******************* Output buffer Info **********************");
-    DLOGI_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, acquire_fence %d",
-             mdp_out_layer->buffer.planes[0].fd, mdp_out_layer->buffer.planes[0].offset,
-             mdp_out_layer->buffer.planes[0].stride,  mdp_out_layer->buffer.fence);
-    DLOGI_IF(kTagDriverConfig, "*************************************************************");
-  }
-
-  mdp_commit.release_fence = -1;
-  mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
-  if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_display->mdp_disp_commit) < 0) {
-    IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
-    DumpLayerCommit(hw_display->mdp_disp_commit);
-    return kErrorHardware;
-  }
-
-  stack->retire_fence_fd = mdp_commit.retire_fence;
-
-  // MDP returns only one release fence for the entire layer stack. Duplicate this fence into all
-  // layers being composed by MDP.
-  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
-    uint32_t layer_index = hw_layer_info.index[i];
-    LayerBuffer *input_buffer = stack->layers[layer_index].input_buffer;
-    HWRotateInfo *left_rotate = &hw_layers->config[i].rotates[0];
-    HWRotateInfo *right_rotate = &hw_layers->config[i].rotates[1];
-
-    if (!left_rotate->valid && !right_rotate->valid) {
-      input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
-      continue;
-    }
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
-      if (rotate_info->valid) {
-        input_buffer = &rotate_info->hw_buffer_info.output_buffer;
-        input_buffer->release_fence_fd = dup(mdp_commit.release_fence);
-        close_(input_buffer->acquire_fence_fd);
-        input_buffer->acquire_fence_fd = -1;
-      }
-    }
-  }
-  DLOGI_IF(kTagDriverConfig, "*************************** %s Commit Input ************************",
-           GetDeviceString(hw_context->type));
-  DLOGI_IF(kTagDriverConfig, "retire_fence_fd %d", stack->retire_fence_fd);
-  DLOGI_IF(kTagDriverConfig, "*************************************************************");
-
-  close_(mdp_commit.release_fence);
-
-  return kErrorNone;
-}
-
-void HWFrameBuffer::SetRotatorCtrlParams(HWContext *hw_context, HWLayers *hw_layers) {
-  HWRotator *hw_rotator = &hw_context->hw_rotator;
-  DLOGV_IF(kTagDriverConfig, "************************* %s Validate Input ************************",
-           GetDeviceString(hw_context->type));
-
-  hw_rotator->Reset();
-
-  mdp_rotation_request *mdp_rot_request = &hw_rotator->mdp_rot_req;
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-
-  uint32_t &rot_count = mdp_rot_request->count;
-  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
-    Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
-
-      if (rotate_info->valid) {
-        HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
-        mdp_rotation_item *mdp_rot_item = &mdp_rot_request->list[rot_count];
-        bool rot90 = (layer.transform.rotation == 90.0f);
-
-        if (rot90) {
-          mdp_rot_item->flags |= MDP_ROTATION_90;
-        }
-
-        if (layer.transform.flip_horizontal) {
-          mdp_rot_item->flags |= MDP_ROTATION_FLIP_LR;
-        }
-
-        if (layer.transform.flip_vertical) {
-          mdp_rot_item->flags |= MDP_ROTATION_FLIP_UD;
-        }
-
-        SetRect(rotate_info->src_roi, &mdp_rot_item->src_rect);
-        SetRect(rotate_info->dst_roi, &mdp_rot_item->dst_rect);
-
-        // TODO(user): Need to assign the writeback id and pipe id  returned from resource manager.
-        mdp_rot_item->pipe_idx = 0;
-        mdp_rot_item->wb_idx = 0;
-
-        mdp_rot_item->input.width = layer.input_buffer->width;
-        mdp_rot_item->input.height = layer.input_buffer->height;
-        SetFormat(layer.input_buffer->format, &mdp_rot_item->input.format);
-
-        mdp_rot_item->output.width = rot_buf_info->output_buffer.width;
-        mdp_rot_item->output.height = rot_buf_info->output_buffer.height;
-        SetFormat(rot_buf_info->output_buffer.format, &mdp_rot_item->output.format);
-
-        rot_count++;
-
-        DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
-                 i, count ? "Right" : "Left");
-        DLOGV_IF(kTagDriverConfig, "in_w %d, in_h %d, in_f %d,\t out_w %d, out_h %d, out_f %d",
-                 mdp_rot_item->input.width, mdp_rot_item->input.height, mdp_rot_item->input.format,
-                 mdp_rot_item->output.width, mdp_rot_item->output.height,
-                 mdp_rot_item->output.format);
-        DLOGV_IF(kTagDriverConfig, "pipe_id %d, wb_id %d, rot_flag %d", mdp_rot_item->pipe_idx,
-                 mdp_rot_item->wb_idx, mdp_rot_item->flags);
-        DLOGV_IF(kTagDriverConfig, "src_rect [%d, %d, %d, %d]", mdp_rot_item->src_rect.x,
-                 mdp_rot_item->src_rect.y, mdp_rot_item->src_rect.w, mdp_rot_item->src_rect.h);
-        DLOGV_IF(kTagDriverConfig, "dst_rect [%d, %d, %d, %d]", mdp_rot_item->dst_rect.x,
-                 mdp_rot_item->dst_rect.y, mdp_rot_item->dst_rect.w, mdp_rot_item->dst_rect.h);
-        DLOGV_IF(kTagDriverConfig, "*************************************************************");
-      }
-    }
-  }
-}
-
-void HWFrameBuffer::SetRotatorBufferParams(HWContext *hw_context, HWLayers *hw_layers) {
-  HWRotator *hw_rotator = &hw_context->hw_rotator;
-  mdp_rotation_request *mdp_rot_request = &hw_rotator->mdp_rot_req;
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t rot_count = 0;
-
-  DLOGV_IF(kTagDriverConfig, "************************* %s Commit Input **************************",
-           GetDeviceString(hw_context->type));
-  DLOGV_IF(kTagDriverConfig, "Rotate layer count is %d", mdp_rot_request->count);
-
-  mdp_rot_request->list = hw_rotator->mdp_rot_layers;
-
-  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
-    Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
-
-      if (rotate_info->valid) {
-        HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
-        mdp_rotation_item *mdp_rot_item = &mdp_rot_request->list[rot_count];
-
-        mdp_rot_item->input.planes[0].fd = layer.input_buffer->planes[0].fd;
-        mdp_rot_item->input.planes[0].offset = layer.input_buffer->planes[0].offset;
-        SetStride(hw_context->type, layer.input_buffer->format, layer.input_buffer->width,
-                  &mdp_rot_item->input.planes[0].stride);
-        mdp_rot_item->input.plane_count = 1;
-        mdp_rot_item->input.fence = layer.input_buffer->acquire_fence_fd;
-
-        mdp_rot_item->output.planes[0].fd = rot_buf_info->output_buffer.planes[0].fd;
-        mdp_rot_item->output.planes[0].offset = rot_buf_info->output_buffer.planes[0].offset;
-        SetStride(hw_context->type, rot_buf_info->output_buffer.format,
-                  rot_buf_info->output_buffer.planes[0].stride,
-                  &mdp_rot_item->output.planes[0].stride);
-        mdp_rot_item->output.plane_count = 1;
-        mdp_rot_item->output.fence = -1;
-
-        rot_count++;
-
-        DLOGV_IF(kTagDriverConfig, "******************** Layer[%d] %s rotate ********************",
-                 i, count ? "Right" : "Left");
-        DLOGV_IF(kTagDriverConfig, "in_buf_fd %d, in_buf_offset %d, in_stride %d, " \
-                 "in_plane_count %d, in_fence %d", mdp_rot_item->input.planes[0].fd,
-                 mdp_rot_item->input.planes[0].offset, mdp_rot_item->input.planes[0].stride,
-                 mdp_rot_item->input.plane_count, mdp_rot_item->input.fence);
-        DLOGV_IF(kTagDriverConfig, "out_fd %d, out_offset %d, out_stride %d, out_plane_count %d, " \
-                 "out_fence %d", mdp_rot_item->output.planes[0].fd,
-                 mdp_rot_item->output.planes[0].offset, mdp_rot_item->output.planes[0].stride,
-                 mdp_rot_item->output.plane_count, mdp_rot_item->output.fence);
-        DLOGV_IF(kTagDriverConfig, "*************************************************************");
-      }
-    }
-  }
-}
-
-DisplayError HWFrameBuffer::RotatorValidate(HWContext *hw_context, HWLayers *hw_layers) {
-  HWRotator *hw_rotator = &hw_context->hw_rotator;
-  SetRotatorCtrlParams(hw_context, hw_layers);
-
-  hw_rotator->mdp_rot_req.flags = MDSS_ROTATION_REQUEST_VALIDATE;
-  if (ioctl_(hw_context->device_fd, MDSS_ROTATION_REQUEST, &hw_rotator->mdp_rot_req) < 0) {
-    IOCTL_LOGE(MDSS_ROTATION_REQUEST, hw_context->type);
-    return kErrorHardware;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::RotatorCommit(HWContext *hw_context, HWLayers *hw_layers) {
-  HWRotator *hw_rotator = &hw_context->hw_rotator;
-  HWLayersInfo &hw_layer_info = hw_layers->info;
-  uint32_t rot_count = 0;
-
-  SetRotatorCtrlParams(hw_context, hw_layers);
-
-  SetRotatorBufferParams(hw_context, hw_layers);
-
-  hw_rotator->mdp_rot_req.flags &= ~MDSS_ROTATION_REQUEST_VALIDATE;
-  if (ioctl_(hw_context->device_fd, MDSS_ROTATION_REQUEST, &hw_rotator->mdp_rot_req) < 0) {
-    IOCTL_LOGE(MDSS_ROTATION_REQUEST, hw_context->type);
-    return kErrorHardware;
-  }
-
-  for (uint32_t i = 0; i < hw_layer_info.count; i++) {
-    Layer& layer = hw_layer_info.stack->layers[hw_layer_info.index[i]];
-
-    layer.input_buffer->release_fence_fd = -1;
-
-    for (uint32_t count = 0; count < 2; count++) {
-      HWRotateInfo *rotate_info = &hw_layers->config[i].rotates[count];
-
-      if (rotate_info->valid) {
-        HWBufferInfo *rot_buf_info = &rotate_info->hw_buffer_info;
-        mdp_rotation_item *mdp_rot_item = &hw_rotator->mdp_rot_req.list[rot_count];
-
-        SyncMerge(layer.input_buffer->release_fence_fd, dup(mdp_rot_item->output.fence),
-                  &layer.input_buffer->release_fence_fd);
-
-        rot_buf_info->output_buffer.acquire_fence_fd = dup(mdp_rot_item->output.fence);
-
-        close_(mdp_rot_item->output.fence);
-        rot_count++;
-      }
-    }
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::Flush(Handle device) {
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-  HWDisplay *hw_display = &hw_context->hw_display;
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-  case kDeviceHDMI:
-  case kDeviceVirtual:
-    {
-      hw_display->Reset();
-      mdp_layer_commit_v1 &mdp_commit = hw_display->mdp_disp_commit.commit_v1;
-      mdp_commit.input_layer_cnt = 0;
-      mdp_commit.output_layer = NULL;
-
-      mdp_commit.flags &= ~MDP_VALIDATE_LAYER;
-      if (ioctl_(hw_context->device_fd, MSMFB_ATOMIC_COMMIT, &hw_display->mdp_disp_commit) < 0) {
-        IOCTL_LOGE(MSMFB_ATOMIC_COMMIT, hw_context->type);
-        DumpLayerCommit(hw_display->mdp_disp_commit);
-        return kErrorHardware;
-      }
-    }
-    break;
-  default:
-    DLOGE("Flush is not supported for the device %s", GetDeviceString(hw_context->type));
-    return kErrorNotSupported;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::SetFormat(const LayerBufferFormat &source, uint32_t *target) {
-  switch (source) {
-  case kFormatARGB8888:                 *target = MDP_ARGB_8888;         break;
-  case kFormatRGBA8888:                 *target = MDP_RGBA_8888;         break;
-  case kFormatBGRA8888:                 *target = MDP_BGRA_8888;         break;
-  case kFormatRGBX8888:                 *target = MDP_RGBX_8888;         break;
-  case kFormatBGRX8888:                 *target = MDP_BGRX_8888;         break;
-  case kFormatRGB888:                   *target = MDP_RGB_888;           break;
-  case kFormatRGB565:                   *target = MDP_RGB_565;           break;
-  case kFormatYCbCr420Planar:           *target = MDP_Y_CB_CR_H2V2;      break;
-  case kFormatYCrCb420Planar:           *target = MDP_Y_CR_CB_H2V2;      break;
-  case kFormatYCbCr420SemiPlanar:       *target = MDP_Y_CBCR_H2V2;       break;
-  case kFormatYCrCb420SemiPlanar:       *target = MDP_Y_CRCB_H2V2;       break;
-  case kFormatYCbCr422Packed:           *target = MDP_YCBYCR_H2V1;       break;
-  case kFormatYCbCr420SemiPlanarVenus:  *target = MDP_Y_CBCR_H2V2_VENUS; break;
-  case kFormatRGBA8888Ubwc:             *target = MDP_RGBA_8888_UBWC;    break;
-  case kFormatRGB565Ubwc:               *target = MDP_RGB_565_UBWC;      break;
-  case kFormatYCbCr420SPVenusUbwc:      *target = MDP_Y_CBCR_H2V2_UBWC;  break;
-  default:
-    DLOGE("Unsupported format type %d", source);
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-DisplayError HWFrameBuffer::SetStride(HWDeviceType device_type, LayerBufferFormat format,
-                                      uint32_t width, uint32_t *target) {
-  // TODO(user): This SetStride function is an workaround to satisfy the driver expectation for
-  // rotator and virtual devices. Eventually this will be taken care in the driver.
-  if (device_type != kDeviceRotator && device_type != kDeviceVirtual) {
-    *target = width;
-    return kErrorNone;
-  }
-
-  switch (format) {
-  case kFormatARGB8888:
-  case kFormatRGBA8888:
-  case kFormatBGRA8888:
-  case kFormatRGBX8888:
-  case kFormatBGRX8888:
-    *target = width * 4;
-    break;
-  case kFormatRGB888:
-    *target = width * 3;
-    break;
-  case kFormatRGB565:
-    *target = width * 3;
-    break;
-  case kFormatYCbCr420SemiPlanarVenus:
-  case kFormatYCbCr420SPVenusUbwc:
-  case kFormatYCbCr420Planar:
-  case kFormatYCrCb420Planar:
-  case kFormatYCbCr420SemiPlanar:
-  case kFormatYCrCb420SemiPlanar:
-    *target = width;
-    break;
-  case kFormatYCbCr422Packed:
-    *target = width * 2;
-    break;
-  default:
-    DLOGE("Unsupported format type %d", format);
-    return kErrorParameters;
-  }
-
-  return kErrorNone;
-}
-
-void HWFrameBuffer::SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target) {
-  switch (source) {
-  case kBlendingPremultiplied:  *target = BLEND_OP_PREMULTIPLIED;   break;
-  case kBlendingCoverage:       *target = BLEND_OP_COVERAGE;        break;
-  default:                      *target = BLEND_OP_NOT_DEFINED;     break;
-  }
-}
-
-void HWFrameBuffer::SetRect(const LayerRect &source, mdp_rect *target) {
-  target->x = UINT32(source.left);
-  target->y = UINT32(source.top);
-  target->w = UINT32(source.right) - target->x;
-  target->h = UINT32(source.bottom) - target->y;
-}
-
-void HWFrameBuffer::SyncMerge(const int &fd1, const int &fd2, int *target) {
-  if (fd1 >= 0 && fd2 >= 0) {
-    buffer_sync_handler_->SyncMerge(fd1, fd2, target);
-  } else if (fd1 >= 0) {
-    *target = fd1;
-  } else if (fd2 >= 0) {
-    *target = fd2;
-  }
-}
-
-const char *HWFrameBuffer::GetDeviceString(HWDeviceType type) {
-  switch (type) {
-  case kDevicePrimary:
-    return "Primary Display Device";
-  case kDeviceHDMI:
-    return "HDMI Display Device";
-  case kDeviceVirtual:
-    return "Virtual Display Device";
-  case kDeviceRotator:
-    return "Rotator Device";
-  default:
-    return "Invalid Device";
-  }
-}
-
-void* HWFrameBuffer::DisplayEventThread(void *context) {
-  if (context) {
-    return reinterpret_cast<HWFrameBuffer *>(context)->DisplayEventThreadHandler();
-  }
-
-  return NULL;
-}
-
-void* HWFrameBuffer::DisplayEventThreadHandler() {
-  char data[kMaxStringLength] = {0};
-
-  prctl(PR_SET_NAME, event_thread_name_, 0, 0, 0);
-  setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
-
-  if (fake_vsync_) {
-    while (!exit_threads_) {
-      // Fake vsync is used only when set explicitly through a property(todo) or when
-      // the vsync timestamp node cannot be opened at bootup. There is no
-      // fallback to fake vsync from the true vsync loop, ever, as the
-      // condition can easily escape detection.
-      // Also, fake vsync is delivered only for the primary display.
-      usleep(16666);
-      STRUCT_VAR(timeval, time_now);
-      gettimeofday(&time_now, NULL);
-      uint64_t ts = uint64_t(time_now.tv_sec)*1000000000LL +uint64_t(time_now.tv_usec)*1000LL;
-
-      // Send Vsync event for primary display(0)
-      event_handler_[kDevicePrimary]->VSync(ts);
-    }
-
-    pthread_exit(0);
-  }
-
-  typedef void (HWFrameBuffer::*EventHandler)(int, char*);
-  EventHandler event_handler[kNumDisplayEvents] = { &HWFrameBuffer::HandleVSync,
-                                                    &HWFrameBuffer::HandleBlank,
-                                                    &HWFrameBuffer::HandleIdleTimeout };
-
-  while (!exit_threads_) {
-    int error = poll_(poll_fds_[0], kNumPhysicalDisplays * kNumDisplayEvents, -1);
-    if (error < 0) {
-      DLOGW("poll failed. error = %s", strerror(errno));
-      continue;
-    }
-
-    for (int display = 0; display < kNumPhysicalDisplays; display++) {
-      for (int event = 0; event < kNumDisplayEvents; event++) {
-        pollfd &poll_fd = poll_fds_[display][event];
-
-        if (poll_fd.revents & POLLPRI) {
-          ssize_t length = pread_(poll_fd.fd, data, kMaxStringLength, 0);
-          if (length < 0) {
-            // If the read was interrupted - it is not a fatal error, just continue.
-            DLOGW("pread failed. event = %d, display = %d, error = %s",
-                                                      event, display, strerror(errno));
-            continue;
-          }
-
-          (this->*event_handler[event])(display, data);
-        }
-      }
-    }
-  }
-
-  pthread_exit(0);
-
-  return NULL;
-}
-
-void HWFrameBuffer::HandleVSync(int display_id, char *data) {
-  int64_t timestamp = 0;
-  if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) {
-    timestamp = strtoull(data + strlen("VSYNC="), NULL, 0);
-  }
-  event_handler_[display_id]->VSync(timestamp);
-}
-
-void HWFrameBuffer::HandleBlank(int display_id, char *data) {
-  // TODO(user): Need to send blank Event
-}
-
-void HWFrameBuffer::HandleIdleTimeout(int display_id, char *data) {
-  event_handler_[display_id]->IdleTimeout();
-}
-
-void HWFrameBuffer::PopulateFBNodeIndex() {
-  char stringbuffer[kMaxStringLength];
-  DisplayError error = kErrorNone;
-  char *line = stringbuffer;
-  size_t len = kMaxStringLength;
-  ssize_t read;
-
-
-  for (int i = 0; i < kDeviceMax; i++) {
-    snprintf(stringbuffer, sizeof(stringbuffer), "%s%d/msm_fb_type", fb_path_, i);
-    FILE* fileptr = fopen_(stringbuffer, "r");
-    if (fileptr == NULL) {
-      DLOGW("File not found %s", stringbuffer);
-      continue;
-    }
-    read = getline_(&line, &len, fileptr);
-    if (read ==-1) {
-      fclose_(fileptr);
-      continue;
-    }
-    // TODO(user): For now, assume primary to be cmd/video/lvds/edp mode panel only
-    // Need more concrete info from driver
-    if ((strncmp(line, "mipi dsi cmd panel", strlen("mipi dsi cmd panel")) == 0)) {
-      primary_panel_info_.type = kCommandModePanel;
-      fb_node_index_[kDevicePrimary] = i;
-    } else if ((strncmp(line, "mipi dsi video panel", strlen("mipi dsi video panel")) == 0))  {
-      primary_panel_info_.type = kVideoModePanel;
-      fb_node_index_[kDevicePrimary] = i;
-    } else if ((strncmp(line, "lvds panel", strlen("lvds panel")) == 0)) {
-      primary_panel_info_.type = kLVDSPanel;
-      fb_node_index_[kDevicePrimary] = i;
-    } else if ((strncmp(line, "edp panel", strlen("edp panel")) == 0)) {
-      primary_panel_info_.type = kEDPPanel;
-      fb_node_index_[kDevicePrimary] = i;
-    } else if ((strncmp(line, "dtv panel", strlen("dtv panel")) == 0)) {
-      fb_node_index_[kDeviceHDMI] = i;
-    } else if ((strncmp(line, "writeback panel", strlen("writeback panel")) == 0)) {
-      fb_node_index_[kDeviceVirtual] = i;
-    } else {
-      DLOGW("Unknown panel type = %s index = %d", line, i);
-    }
-    fclose_(fileptr);
-  }
-}
-
-void HWFrameBuffer::PopulatePanelInfo(int fb_index) {
-  char stringbuffer[kMaxStringLength];
-  FILE* fileptr = NULL;
-  snprintf(stringbuffer, sizeof(stringbuffer), "%s%d/msm_fb_panel_info", fb_path_, fb_index);
-  fileptr = fopen_(stringbuffer, "r");
-  if (fileptr == NULL) {
-    DLOGW("Failed to open msm_fb_panel_info node");
-    return;
-  }
-
-  size_t len = kMaxStringLength;
-  ssize_t read;
-  char *line = stringbuffer;
-  while ((read = getline_(&line, &len, fileptr)) != -1) {
-    uint32_t token_count = 0;
-    const uint32_t max_count = 10;
-    char *tokens[max_count] = { NULL };
-    if (!ParseLine(line, tokens, max_count, &token_count)) {
-      if (!strncmp(tokens[0], "pu_en", strlen("pu_en"))) {
-        primary_panel_info_.partial_update = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "xstart", strlen("xstart"))) {
-        primary_panel_info_.left_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "walign", strlen("walign"))) {
-        primary_panel_info_.width_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "ystart", strlen("ystart"))) {
-        primary_panel_info_.top_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "halign", strlen("halign"))) {
-        primary_panel_info_.height_align = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "min_w", strlen("min_w"))) {
-        primary_panel_info_.min_roi_width = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "min_h", strlen("min_h"))) {
-        primary_panel_info_.min_roi_height = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "roi_merge", strlen("roi_merge"))) {
-        primary_panel_info_.needs_roi_merge = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "dynamic_fps_en", strlen("dyn_fps_en"))) {
-        primary_panel_info_.dynamic_fps = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
-        primary_panel_info_.min_fps = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
-        primary_panel_info_.max_fps= atoi(tokens[1]);
-      }
-    }
-  }
-  fclose_(fileptr);
-}
-
-// Get SDE HWCapabalities from the sysfs
-DisplayError HWFrameBuffer::PopulateHWCapabilities() {
-  DisplayError error = kErrorNone;
-  FILE *fileptr = NULL;
-  char stringbuffer[kMaxStringLength];
-  uint32_t token_count = 0;
-  const uint32_t max_count = 10;
-  char *tokens[max_count] = { NULL };
-  snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/mdp/caps", fb_path_,
-           fb_node_index_[kHWPrimary]);
-  fileptr = fopen_(stringbuffer, "rb");
-
-  if (fileptr == NULL) {
-    DLOGE("File '%s' not found", stringbuffer);
-    return kErrorHardware;
-  }
-
-  size_t len = kMaxStringLength;
-  ssize_t read;
-  char *line = stringbuffer;
-  hw_resource_.hw_version = kHWMdssVersion5;
-  while ((read = getline_(&line, &len, fileptr)) != -1) {
-    // parse the line and update information accordingly
-    if (!ParseLine(line, tokens, max_count, &token_count)) {
-      if (!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
-        hw_resource_.hw_revision = atoi(tokens[1]);  // HW Rev, v1/v2
-      } else if (!strncmp(tokens[0], "rgb_pipes", strlen("rgb_pipes"))) {
-        hw_resource_.num_rgb_pipe = (uint8_t)atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "vig_pipes", strlen("vig_pipes"))) {
-        hw_resource_.num_vig_pipe = (uint8_t)atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
-        hw_resource_.num_dma_pipe = (uint8_t)atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "cursor_pipes", strlen("cursor_pipes"))) {
-        hw_resource_.num_cursor_pipe = (uint8_t)atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "blending_stages", strlen("blending_stages"))) {
-        hw_resource_.num_blending_stages = (uint8_t)atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_downscale_ratio", strlen("max_downscale_ratio"))) {
-        hw_resource_.max_scale_down = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
-        hw_resource_.max_scale_up = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
-        hw_resource_.max_bandwidth_low = atol(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
-        hw_resource_.max_bandwidth_high = atol(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
-        hw_resource_.max_mixer_width = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
-        hw_resource_.max_pipe_bw = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
-        hw_resource_.max_sde_clk = atoi(tokens[1]);
-      } else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
-        hw_resource_.clk_fudge_factor = FLOAT(atoi(tokens[1])) / FLOAT(atoi(tokens[2]));
-      } else if (!strncmp(tokens[0], "features", strlen("features"))) {
-        for (uint32_t i = 0; i < token_count; i++) {
-          if (!strncmp(tokens[i], "bwc", strlen("bwc"))) {
-            hw_resource_.has_bwc = true;
-          } else if (!strncmp(tokens[i], "decimation", strlen("decimation"))) {
-            hw_resource_.has_decimation = true;
-          } else if (!strncmp(tokens[i], "tile_format", strlen("tile_format"))) {
-            hw_resource_.has_macrotile = true;
-          } else if (!strncmp(tokens[i], "src_split", strlen("src_split"))) {
-            hw_resource_.is_src_split = true;
-          } else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
-            hw_resource_.has_non_scalar_rgb = true;
-          } else if (!strncmp(tokens[i], "rotator_downscale", strlen("rotator_downscale"))) {
-            hw_resource_.has_rotator_downscale = true;
-          }
-        }
-      }
-    }
-  }
-  fclose_(fileptr);
-
-  // Split info - for MDSS Version 5 - No need to check version here
-  snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/msm_fb_split", fb_path_,
-           fb_node_index_[kHWPrimary]);
-  fileptr = fopen_(stringbuffer, "r");
-  if (fileptr) {
-    // Format "left right" space as delimiter
-    read = getline_(&line, &len, fileptr);
-    if (read != -1) {
-      if (!ParseLine(line, tokens, max_count, &token_count)) {
-        hw_resource_.split_info.left_split = atoi(tokens[0]);
-        hw_resource_.split_info.right_split = atoi(tokens[1]);
-      }
-    }
-    fclose_(fileptr);
-  }
-
-  // SourceSplit enabled - Get More information
-  if (hw_resource_.is_src_split) {
-    snprintf(stringbuffer , sizeof(stringbuffer), "%s%d/msm_fb_src_split_info", fb_path_,
-             fb_node_index_[kHWPrimary]);
-    fileptr = fopen_(stringbuffer, "r");
-    if (fileptr) {
-      read = getline_(&line, &len, fileptr);
-      if (read != -1) {
-        if (!strncmp(line, "src_split_always", strlen("src_split_always"))) {
-          hw_resource_.always_src_split = true;
-        }
-      }
-      fclose_(fileptr);
-    }
-  }
-
-  DLOGI("SDE Version = %d, SDE Revision = %x, RGB = %d, VIG = %d, DMA = %d, Cursor = %d",
-        hw_resource_.hw_version, hw_resource_.hw_revision, hw_resource_.num_rgb_pipe,
-        hw_resource_.num_vig_pipe, hw_resource_.num_dma_pipe, hw_resource_.num_cursor_pipe);
-  DLOGI("Upscale Ratio = %d, Downscale Ratio = %d, Blending Stages = %d", hw_resource_.max_scale_up,
-        hw_resource_.max_scale_down, hw_resource_.num_blending_stages);
-  DLOGI("BWC = %d, Decimation = %d, Tile Format = %d, Rotator Downscale = %d", hw_resource_.has_bwc,
-        hw_resource_.has_decimation, hw_resource_.has_macrotile,
-        hw_resource_.has_rotator_downscale);
-  DLOGI("Left Split = %d, Right Split = %d", hw_resource_.split_info.left_split,
-        hw_resource_.split_info.right_split);
-  DLOGI("SourceSplit = %d, Always = %d", hw_resource_.is_src_split, hw_resource_.always_src_split);
-  DLOGI("MaxLowBw = %"PRIu64", MaxHighBw = %"PRIu64"", hw_resource_.max_bandwidth_low,
-        hw_resource_.max_bandwidth_high);
-  DLOGI("MaxPipeBw = %"PRIu64" KBps, MaxSDEClock = %"PRIu64" Hz, ClockFudgeFactor = %f",
-        hw_resource_.max_pipe_bw, hw_resource_.max_sde_clk, hw_resource_.clk_fudge_factor);
-
-  return error;
-}
-
-int HWFrameBuffer::ParseLine(char *input, char *tokens[], const uint32_t max_token,
-                             uint32_t *count) {
-  char *tmp_token = NULL;
-  char *temp_ptr;
-  uint32_t index = 0;
-  const char *delim = ", =\n";
-  if (!input) {
-    return -1;
-  }
-  tmp_token = strtok_r(input, delim, &temp_ptr);
-  while (tmp_token && index < max_token) {
-    tokens[index++] = tmp_token;
-    tmp_token = strtok_r(NULL, delim, &temp_ptr);
-  }
-  *count = index;
-
-  return 0;
-}
-
-bool HWFrameBuffer::EnableHotPlugDetection(int enable) {
-  bool ret_value = true;
-  char hpdpath[kMaxStringLength];
-  snprintf(hpdpath , sizeof(hpdpath), "%s%d/hpd", fb_path_, fb_node_index_[kDeviceHDMI]);
-  int hpdfd = open_(hpdpath, O_RDWR, 0);
-  if (hpdfd < 0) {
-    DLOGE("Open failed = %s", hpdpath);
-    return kErrorHardware;
-  }
-  char value = enable ? '1' : '0';
-  ssize_t length = pwrite_(hpdfd, &value, 1, 0);
-  if (length <= 0) {
-    DLOGE("Write failed 'hpd' = %d", enable);
-    ret_value = false;
-  }
-  close_(hpdfd);
-
-  return ret_value;
-}
-
-int HWFrameBuffer::GetHDMIModeCount() {
-  ssize_t length = -1;
-  char edid_str[256] = {'\0'};
-  char edid_path[kMaxStringLength] = {'\0'};
-  snprintf(edid_path, sizeof(edid_path), "%s%d/edid_modes", fb_path_, fb_node_index_[kHWHDMI]);
-  int edid_file = open_(edid_path, O_RDONLY);
-  if (edid_file < 0) {
-    DLOGE("EDID file open failed.");
-    return -1;
-  }
-
-  length = pread_(edid_file, edid_str, sizeof(edid_str)-1, 0);
-  if (length <= 0) {
-    DLOGE("%s: edid_modes file empty");
-    edid_str[0] = '\0';
-  } else {
-    DLOGI("EDID mode string: %s", edid_str);
-    while (length > 1 && isspace(edid_str[length-1])) {
-      --length;
-    }
-    edid_str[length] = '\0';
-  }
-  close_(edid_file);
-
-  if (length > 0) {
-    // Get EDID modes from the EDID string
-    char *ptr = edid_str;
-    const uint32_t edid_count_max = 128;
-    char *tokens[edid_count_max] = { NULL };
-    ParseLine(ptr, tokens, edid_count_max, &hdmi_mode_count_);
-    for (uint32_t i = 0; i < hdmi_mode_count_; i++) {
-      hdmi_modes_[i] = atoi(tokens[i]);
-    }
-  }
-  return (hdmi_mode_count_ > 0) ? hdmi_mode_count_ : 0;
-}
-
-bool HWFrameBuffer::MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode,
-                                         fb_var_screeninfo *info) {
-  if (!mode || !info) {
-    return false;
-  }
-
-  info->reserved[0] = 0;
-  info->reserved[1] = 0;
-  info->reserved[2] = 0;
-  info->reserved[3] = (info->reserved[3] & 0xFFFF) | (mode->video_format << 16);
-  info->xoffset = 0;
-  info->yoffset = 0;
-  info->xres = mode->active_h;
-  info->yres = mode->active_v;
-  info->pixclock = (mode->pixel_freq) * 1000;
-  info->vmode = mode->interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
-  info->right_margin = mode->front_porch_h;
-  info->hsync_len = mode->pulse_width_h;
-  info->left_margin = mode->back_porch_h;
-  info->lower_margin = mode->front_porch_v;
-  info->vsync_len = mode->pulse_width_v;
-  info->upper_margin = mode->back_porch_v;
-
-  return true;
-}
-
-void HWFrameBuffer::SetIdleTimeoutMs(Handle device, uint32_t timeout_ms) {
-  char node_path[kMaxStringLength] = {0};
-  HWContext *hw_context = reinterpret_cast<HWContext *>(device);
-
-  DLOGI("idle timeout = %d ms", timeout_ms);
-
-  switch (hw_context->type) {
-  case kDevicePrimary:
-    {
-      // Idle fallback feature is supported only for video mode panel.
-      if (primary_panel_info_.type == kCommandModePanel) {
-        return;
-      }
-
-      snprintf(node_path, sizeof(node_path), "%s%d/idle_time", fb_path_,
-               fb_node_index_[hw_context->type]);
-
-      // Open a sysfs node to send the timeout value to driver.
-      int fd = open_(node_path, O_WRONLY);
-      if (fd < 0) {
-        DLOGE("Unable to open %s, node %s", node_path, strerror(errno));
-        return;
-      }
-
-      char timeout_string[64];
-      snprintf(timeout_string, sizeof(timeout_string), "%d", timeout_ms);
-
-      // Notify driver about the timeout value
-      ssize_t length = pwrite_(fd, timeout_string, strlen(timeout_string), 0);
-      if (length < -1) {
-        DLOGE("Unable to write into %s, node %s", node_path, strerror(errno));
-      }
-
-      close_(fd);
-    }
-    break;
-  default:
-    break;
-  }
-}
-
-}  // namespace sde
-
diff --git a/displayengine/libs/core/hw_framebuffer.h b/displayengine/libs/core/hw_framebuffer.h
deleted file mode 100644
index b2a37ab..0000000
--- a/displayengine/libs/core/hw_framebuffer.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-* Copyright (c) 2014 - 2015, 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_FRAMEBUFFER_H__
-#define __HW_FRAMEBUFFER_H__
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <linux/msm_mdp_ext.h>
-#include <video/msm_hdmi_modes.h>
-#include <linux/mdss_rotator.h>
-#include <poll.h>
-#include <pthread.h>
-
-#include "hw_interface.h"
-
-namespace sde {
-
-class HWFrameBuffer : public HWInterface {
- public:
-  explicit HWFrameBuffer(BufferSyncHandler *buffer_sync_handler);
-  DisplayError Init();
-  DisplayError Deinit();
-  virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info);
-  virtual DisplayError Open(HWDeviceType type, Handle *device, HWEventHandler *eventhandler);
-  virtual DisplayError Close(Handle device);
-  virtual DisplayError GetNumDisplayAttributes(Handle device, uint32_t *count);
-  virtual DisplayError GetDisplayAttributes(Handle device, HWDisplayAttributes *display_attributes,
-                                            uint32_t index);
-  virtual DisplayError SetDisplayAttributes(Handle device, uint32_t index);
-  virtual DisplayError GetConfigIndex(Handle device, uint32_t mode, uint32_t *index);
-  virtual DisplayError PowerOn(Handle device);
-  virtual DisplayError PowerOff(Handle device);
-  virtual DisplayError Doze(Handle device);
-  virtual DisplayError SetVSyncState(Handle device, bool enable);
-  virtual DisplayError Standby(Handle device);
-  virtual DisplayError OpenRotatorSession(Handle device, HWRotateInfo *rotate_info);
-  virtual DisplayError CloseRotatorSession(Handle device, int32_t session_id);
-  virtual DisplayError Validate(Handle device, HWLayers *hw_layers);
-  virtual DisplayError Commit(Handle device, HWLayers *hw_layers);
-  virtual DisplayError Flush(Handle device);
-  virtual void SetIdleTimeoutMs(Handle device, uint32_t timeout_ms);
-
- private:
-  struct HWDisplay {
-    mdp_layer_commit mdp_disp_commit;
-    mdp_input_layer mdp_in_layers[kMaxSDELayers * 2];   // split panel (left + right)
-    mdp_scale_data scale_data[kMaxSDELayers * 2];
-    mdp_output_layer mdp_out_layer;
-
-    HWDisplay() { Reset(); }
-
-    void Reset() {
-      memset(&mdp_disp_commit, 0, sizeof(mdp_disp_commit));
-      memset(&mdp_in_layers, 0, sizeof(mdp_in_layers));
-      memset(&mdp_out_layer, 0, sizeof(mdp_out_layer));
-      memset(&scale_data, 0, sizeof(scale_data));
-
-      for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
-        mdp_in_layers[i].buffer.fence = -1;
-      }
-
-      mdp_disp_commit.version = MDP_COMMIT_VERSION_1_0;
-      mdp_disp_commit.commit_v1.input_layers = mdp_in_layers;
-      mdp_disp_commit.commit_v1.output_layer = &mdp_out_layer;
-      mdp_disp_commit.commit_v1.release_fence = -1;
-      mdp_disp_commit.commit_v1.retire_fence = -1;
-    }
-
-    mdp_scale_data* GetScaleDataRef(uint32_t index) { return &scale_data[index]; }
-  };
-
-  struct HWRotator {
-    struct mdp_rotation_request mdp_rot_req;
-    struct mdp_rotation_item mdp_rot_layers[kMaxSDELayers * 2];  // split panel (left + right)
-
-    HWRotator() { Reset(); }
-
-    void Reset() {
-      memset(&mdp_rot_req, 0, sizeof(mdp_rot_req));
-      memset(&mdp_rot_layers, 0, sizeof(mdp_rot_layers));
-
-      for (uint32_t i = 0; i < kMaxSDELayers * 2; i++) {
-        mdp_rot_layers[i].input.fence = -1;
-        mdp_rot_layers[i].output.fence = -1;
-      }
-
-      mdp_rot_req.version = MDP_ROTATION_REQUEST_VERSION_1_0;
-      mdp_rot_req.list = mdp_rot_layers;
-    }
-  };
-
-  struct HWContext {
-    HWDeviceType type;
-    int device_fd;
-    HWRotator hw_rotator;
-    HWDisplay hw_display;
-
-    HWContext() : type(kDeviceMax), device_fd(-1) { }
-  };
-
-  enum PanelType {
-    kNoPanel,
-    kCommandModePanel,
-    kVideoModePanel,
-    kDTvPanel,
-    kWriteBackPanel,
-    kLVDSPanel,
-    kEDPPanel,
-  };
-
-  enum {
-    kHWEventVSync,
-    kHWEventBlank,
-  };
-
-  // Maps to the msm_fb_panel_info
-  struct PanelInfo {
-    PanelType type;        // Smart or Dumb
-    bool partial_update;   // Partial update feature
-    int left_align;        // ROI left alignment restriction
-    int width_align;       // ROI width alignment restriction
-    int top_align;;        // ROI top alignment restriction
-    int height_align;      // ROI height alignment restriction
-    int min_roi_width;     // Min width needed for ROI
-    int min_roi_height;    // Min height needed for ROI
-    bool needs_roi_merge;  // Merge ROI's of both the DSI's
-    bool dynamic_fps;      // Panel Supports dynamic fps
-    uint32_t min_fps;      // Min fps supported by panel
-    uint32_t max_fps;      // Max fps supported by panel
-
-    PanelInfo() : type(kNoPanel), partial_update(false), left_align(false), width_align(false),
-      top_align(false), height_align(false), min_roi_width(0), min_roi_height(0),
-      needs_roi_merge(false), dynamic_fps(false), min_fps(0), max_fps(0) { }
-  };
-
-  static const int kMaxStringLength = 1024;
-  static const int kNumPhysicalDisplays = 2;
-  static const int kNumDisplayEvents = 3;
-  static const int kHWMdssVersion5 = 500;  // MDSS_V5
-
-  DisplayError DisplayValidate(HWContext *device_ctx, HWLayers *hw_layers);
-  DisplayError DisplayCommit(HWContext *device_ctx, HWLayers *hw_layers);
-
-  void SetRotatorCtrlParams(HWContext *device_ctx, HWLayers *hw_layers);
-  void SetRotatorBufferParams(HWContext *device_ctx, HWLayers *hw_layers);
-
-  DisplayError RotatorValidate(HWContext *device_ctx, HWLayers *hw_layers);
-  DisplayError RotatorCommit(HWContext *device_ctx, HWLayers *hw_layers);
-  void DumpLayerCommit(mdp_layer_commit &layer_commit);
-  inline DisplayError SetFormat(const LayerBufferFormat &source, uint32_t *target);
-  inline DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format,
-                                uint32_t width, uint32_t *target);
-  inline void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
-  inline void SetRect(const LayerRect &source, mdp_rect *target);
-  inline void SyncMerge(const int &fd1, const int &fd2, int *target);
-
-  inline const char *GetDeviceString(HWDeviceType type);
-
-  // Event Thread to receive vsync/blank events
-  static void* DisplayEventThread(void *context);
-  void* DisplayEventThreadHandler();
-
-  void HandleVSync(int display_id, char *data);
-  void HandleBlank(int display_id, char *data);
-  void HandleIdleTimeout(int display_id, char *data);
-
-  // Populates HW FrameBuffer Node Index
-  void PopulateFBNodeIndex();
-  // Populates the Panel Info based on node index
-  void PopulatePanelInfo(int fb_index);
-  // Populates HW Capabilities
-  DisplayError PopulateHWCapabilities();
-  int ParseLine(char *input, char *token[], const uint32_t max_token, uint32_t *count);
-
-  // HDMI Related Functions
-  bool EnableHotPlugDetection(int enable);
-  int GetHDMIModeCount();
-  bool MapHDMIDisplayTiming(const msm_hdmi_mode_timing_info *mode, fb_var_screeninfo *info);
-
-  // Pointers to system calls which are either mapped to actual system call or virtual driver.
-  int (*ioctl_)(int, int, ...);
-  int (*open_)(const char *, int, ...);
-  int (*close_)(int);
-  int (*poll_)(struct pollfd *, nfds_t, int);
-  ssize_t (*pread_)(int, void *, size_t, off_t);
-  ssize_t (*pwrite_)(int, const void *, size_t, off_t);
-  FILE* (*fopen_)( const char *fname, const char *mode);
-  int (*fclose_)(FILE* fileptr);
-  ssize_t (*getline_)(char **lineptr, size_t *linelen, FILE *stream);
-
-  // Store the Device EventHandlers - used for callback
-  HWEventHandler *event_handler_[kNumPhysicalDisplays];
-  pollfd poll_fds_[kNumPhysicalDisplays][kNumDisplayEvents];
-  pthread_t event_thread_;
-  const char *event_thread_name_;
-  bool fake_vsync_;
-  bool exit_threads_;
-  HWResourceInfo hw_resource_;
-  int fb_node_index_[kDeviceMax];
-  const char* fb_path_;
-  PanelInfo primary_panel_info_;
-  bool hotplug_enabled_;
-  uint32_t hdmi_mode_count_;
-  uint32_t hdmi_modes_[256];
-  // Holds the hdmi timing information. Ex: resolution, fps etc.,
-  msm_hdmi_mode_timing_info *supported_video_modes_;
-  BufferSyncHandler *buffer_sync_handler_;
-};
-
-}  // namespace sde
-
-#endif  // __HW_FRAMEBUFFER_H__
-
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/hw_hdmi_interface.h
similarity index 67%
copy from displayengine/libs/core/hw_interface.cpp
copy to displayengine/libs/core/hw_hdmi_interface.h
index 6b99a73..36ca991 100644
--- a/displayengine/libs/core/hw_interface.cpp
+++ b/displayengine/libs/core/hw_hdmi_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015, 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:
@@ -22,34 +22,26 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <utils/constants.h>
+#ifndef __HW_HDMI_INTERFACE_H__
+#define __HW_HDMI_INTERFACE_H__
 
 #include "hw_interface.h"
-#include "hw_framebuffer.h"
 
 namespace sde {
 
-DisplayError HWInterface::Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler) {
-  DisplayError error = kErrorNone;
-  HWFrameBuffer *hw_frame_buffer = NULL;
+class HWInfoInterface;
 
-  hw_frame_buffer = new HWFrameBuffer(buffer_sync_handler);
-  error = hw_frame_buffer->Init();
-  if (UNLIKELY(error != kErrorNone)) {
-    delete hw_frame_buffer;
-  } else {
-    *intf = hw_frame_buffer;
-  }
+class HWHDMIInterface: virtual public HWInterface {
+ public:
+  static DisplayError Create(HWHDMIInterface **intf, HWInfoInterface *hw_info_intf,
+                             BufferSyncHandler *buffer_sync_handler);
+  static DisplayError Destroy(HWHDMIInterface *intf);
 
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
-  hw_frame_buffer->Deinit();
-  delete hw_frame_buffer;
-  return kErrorNone;
-}
+ protected:
+  virtual ~HWHDMIInterface() { }
+};
 
 }  // namespace sde
 
+#endif  // __HW_HDMI_INTERFACE_H__
+
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/hw_info_interface.h
similarity index 69%
rename from displayengine/libs/core/hw_interface.cpp
rename to displayengine/libs/core/hw_info_interface.h
index 6b99a73..035db40 100644
--- a/displayengine/libs/core/hw_interface.cpp
+++ b/displayengine/libs/core/hw_info_interface.h
@@ -22,34 +22,25 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <utils/constants.h>
+#ifndef __HW_INFO_INTERFACE_H__
+#define __HW_INFO_INTERFACE_H__
 
-#include "hw_interface.h"
-#include "hw_framebuffer.h"
+#include <inttypes.h>
+#include <private/hw_info_types.h>
 
 namespace sde {
 
-DisplayError HWInterface::Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler) {
-  DisplayError error = kErrorNone;
-  HWFrameBuffer *hw_frame_buffer = NULL;
+class HWInfoInterface {
+ public:
+  static DisplayError Create(HWInfoInterface **intf);
+  static DisplayError Destroy(HWInfoInterface *intf);
+  virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource) = 0;
 
-  hw_frame_buffer = new HWFrameBuffer(buffer_sync_handler);
-  error = hw_frame_buffer->Init();
-  if (UNLIKELY(error != kErrorNone)) {
-    delete hw_frame_buffer;
-  } else {
-    *intf = hw_frame_buffer;
-  }
-
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
-  hw_frame_buffer->Deinit();
-  delete hw_frame_buffer;
-  return kErrorNone;
-}
+ protected:
+  virtual ~HWInfoInterface() { }
+};
 
 }  // namespace sde
 
+#endif  // __HW_INFO_INTERFACE_H__
+
diff --git a/displayengine/libs/core/hw_interface.h b/displayengine/libs/core/hw_interface.h
index 0d1634c..e8e0c63 100644
--- a/displayengine/libs/core/hw_interface.h
+++ b/displayengine/libs/core/hw_interface.h
@@ -27,6 +27,7 @@
 
 #include <core/display_interface.h>
 #include <private/strategy_interface.h>
+#include <private/hw_info_types.h>
 #include <utils/constants.h>
 #include <core/buffer_allocator.h>
 #include <core/buffer_sync_handler.h>
@@ -42,61 +43,6 @@
   kHWBlockMax
 };
 
-enum HWDeviceType {
-  kDevicePrimary,
-  kDeviceHDMI,
-  kDeviceVirtual,
-  kDeviceRotator,
-  kDeviceMax,
-};
-
-struct HWResourceInfo {
-  uint32_t hw_version;
-  uint32_t hw_revision;
-  uint32_t num_dma_pipe;
-  uint32_t num_vig_pipe;
-  uint32_t num_rgb_pipe;
-  uint32_t num_cursor_pipe;
-  uint32_t num_blending_stages;
-  uint32_t num_rotator;
-  uint32_t num_control;
-  uint32_t num_mixer_to_disp;
-  uint32_t smp_total;
-  uint32_t smp_size;
-  uint32_t num_smp_per_pipe;
-  uint32_t max_scale_up;
-  uint32_t max_scale_down;
-  uint64_t max_bandwidth_low;
-  uint64_t max_bandwidth_high;
-  uint32_t max_mixer_width;
-  uint32_t max_pipe_bw;
-  uint32_t max_sde_clk;
-  float clk_fudge_factor;
-  struct SplitInfo {
-    uint32_t left_split;
-    uint32_t right_split;
-    SplitInfo() : left_split(0), right_split(0) { }
-  } split_info;
-  bool has_bwc;
-  bool has_decimation;
-  bool has_macrotile;
-  bool has_rotator_downscale;
-  bool has_non_scalar_rgb;
-  bool is_src_split;
-  bool always_src_split;
-
-  HWResourceInfo()
-    : hw_version(0), hw_revision(0), num_dma_pipe(0), num_vig_pipe(0), num_rgb_pipe(0),
-      num_cursor_pipe(0), num_blending_stages(0), num_rotator(0), num_control(0),
-      num_mixer_to_disp(0), smp_total(0), smp_size(0), num_smp_per_pipe(0), max_scale_up(1),
-      max_scale_down(1), max_bandwidth_low(0), max_bandwidth_high(0), max_mixer_width(2048),
-      max_pipe_bw(0), max_sde_clk(0), clk_fudge_factor(1.0f), has_bwc(false),
-      has_decimation(false), has_macrotile(false), has_rotator_downscale(false),
-      has_non_scalar_rgb(false), is_src_split(false), always_src_split(false) { }
-
-  void Reset() { *this = HWResourceInfo(); }
-};
-
 struct HWBufferInfo : public BufferInfo {
   LayerBuffer output_buffer;
   int session_id;
@@ -164,8 +110,9 @@
 struct HWDisplayAttributes : DisplayConfigVariableInfo {
   bool is_device_split;
   uint32_t split_left;
+  bool always_src_split;
 
-  HWDisplayAttributes() : is_device_split(false), split_left(0) { }
+  HWDisplayAttributes() : is_device_split(false), split_left(0), always_src_split(false) { }
 
   void Reset() { *this = HWDisplayAttributes(); }
 };
@@ -182,27 +129,21 @@
 
 class HWInterface {
  public:
-  static DisplayError Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler);
-  static DisplayError Destroy(HWInterface *intf);
-  virtual DisplayError GetHWCapabilities(HWResourceInfo *hw_res_info) = 0;
-  virtual DisplayError Open(HWDeviceType type, Handle *device, HWEventHandler *eventhandler) = 0;
-  virtual DisplayError Close(Handle device) = 0;
-  virtual DisplayError GetNumDisplayAttributes(Handle device, uint32_t *count) = 0;
-  virtual DisplayError GetDisplayAttributes(Handle device,
-                            HWDisplayAttributes *display_attributes, uint32_t index) = 0;
-  virtual DisplayError SetDisplayAttributes(Handle device, uint32_t index) = 0;
-  virtual DisplayError GetConfigIndex(Handle device, uint32_t mode, uint32_t *index) = 0;
-  virtual DisplayError PowerOn(Handle device) = 0;
-  virtual DisplayError PowerOff(Handle device) = 0;
-  virtual DisplayError Doze(Handle device) = 0;
-  virtual DisplayError SetVSyncState(Handle device, bool enable) = 0;
-  virtual DisplayError Standby(Handle device) = 0;
-  virtual DisplayError OpenRotatorSession(Handle device, HWRotateInfo *rotate_info) = 0;
-  virtual DisplayError CloseRotatorSession(Handle device, int32_t session_id) = 0;
-  virtual DisplayError Validate(Handle device, HWLayers *hw_layers) = 0;
-  virtual DisplayError Commit(Handle device, HWLayers *hw_layers) = 0;
-  virtual DisplayError Flush(Handle device) = 0;
-  virtual void SetIdleTimeoutMs(Handle device, uint32_t timeout_ms) = 0;
+  virtual DisplayError Open(HWEventHandler *eventhandler) = 0;
+  virtual DisplayError Close() = 0;
+  virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
+  virtual DisplayError GetDisplayAttributes(HWDisplayAttributes *display_attributes,
+                                            uint32_t index) = 0;
+  virtual DisplayError GetHWPanelInfo(HWPanelInfo *panel_info) = 0;
+  virtual DisplayError SetDisplayAttributes(uint32_t index) = 0;
+  virtual DisplayError GetConfigIndex(uint32_t mode, uint32_t *index) = 0;
+  virtual DisplayError PowerOn() = 0;
+  virtual DisplayError PowerOff() = 0;
+  virtual DisplayError Doze() = 0;
+  virtual DisplayError Standby() = 0;
+  virtual DisplayError Validate(HWLayers *hw_layers) = 0;
+  virtual DisplayError Commit(HWLayers *hw_layers) = 0;
+  virtual DisplayError Flush() = 0;
 
  protected:
   virtual ~HWInterface() { }
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/hw_primary_interface.h
similarity index 66%
copy from displayengine/libs/core/hw_interface.cpp
copy to displayengine/libs/core/hw_primary_interface.h
index 6b99a73..31df694 100644
--- a/displayengine/libs/core/hw_interface.cpp
+++ b/displayengine/libs/core/hw_primary_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015, 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:
@@ -22,34 +22,27 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <utils/constants.h>
-
-#include "hw_interface.h"
-#include "hw_framebuffer.h"
+#ifndef __HW_PRIMARY_INTERFACE_H__
+#define __HW_PRIMARY_INTERFACE_H__
 
 namespace sde {
 
-DisplayError HWInterface::Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler) {
-  DisplayError error = kErrorNone;
-  HWFrameBuffer *hw_frame_buffer = NULL;
+class BufferSyncHandler;
+class HWInfoInterface;
 
-  hw_frame_buffer = new HWFrameBuffer(buffer_sync_handler);
-  error = hw_frame_buffer->Init();
-  if (UNLIKELY(error != kErrorNone)) {
-    delete hw_frame_buffer;
-  } else {
-    *intf = hw_frame_buffer;
-  }
+class HWPrimaryInterface: virtual public HWInterface {
+ public:
+  static DisplayError Create(HWPrimaryInterface **intf, HWInfoInterface *hw_info_intf,
+                             BufferSyncHandler *buffer_sync_handler);
+  static DisplayError Destroy(HWPrimaryInterface *intf);
+  virtual DisplayError SetVSyncState(bool enable) = 0;
+  virtual void SetIdleTimeoutMs(uint32_t timeout_ms) = 0;
 
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
-  hw_frame_buffer->Deinit();
-  delete hw_frame_buffer;
-  return kErrorNone;
-}
+ protected:
+  virtual ~HWPrimaryInterface() { }
+};
 
 }  // namespace sde
 
+#endif  // __HW_PRIMARY_INTERFACE_H__
+
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/hw_rotator_interface.h
similarity index 65%
copy from displayengine/libs/core/hw_interface.cpp
copy to displayengine/libs/core/hw_rotator_interface.h
index 6b99a73..35876d6 100644
--- a/displayengine/libs/core/hw_interface.cpp
+++ b/displayengine/libs/core/hw_rotator_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015, 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:
@@ -22,34 +22,31 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <utils/constants.h>
-
-#include "hw_interface.h"
-#include "hw_framebuffer.h"
+#ifndef __HW_ROTATOR_INTERFACE_H__
+#define __HW_ROTATOR_INTERFACE_H__
 
 namespace sde {
 
-DisplayError HWInterface::Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler) {
-  DisplayError error = kErrorNone;
-  HWFrameBuffer *hw_frame_buffer = NULL;
+class BufferSyncHandler;
+struct HWRotateInfo;
+struct HWLayers;
 
-  hw_frame_buffer = new HWFrameBuffer(buffer_sync_handler);
-  error = hw_frame_buffer->Init();
-  if (UNLIKELY(error != kErrorNone)) {
-    delete hw_frame_buffer;
-  } else {
-    *intf = hw_frame_buffer;
-  }
+class HWRotatorInterface {
+ public:
+  static DisplayError Create(HWRotatorInterface **intf, BufferSyncHandler *buffer_sync_handler);
+  static DisplayError Destroy(HWRotatorInterface *intf);
+  virtual DisplayError Open() = 0;
+  virtual DisplayError Close() = 0;
+  virtual DisplayError OpenSession(HWRotateInfo *rotate_info) = 0;
+  virtual DisplayError CloseSession(int32_t session_id) = 0;
+  virtual DisplayError Validate(HWLayers *hw_layers) = 0;
+  virtual DisplayError Commit(HWLayers *hw_layers) = 0;
 
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
-  hw_frame_buffer->Deinit();
-  delete hw_frame_buffer;
-  return kErrorNone;
-}
+ protected:
+  virtual ~HWRotatorInterface() { }
+};
 
 }  // namespace sde
 
+#endif  // __HW_ROTATOR_INTERFACE_H__
+
diff --git a/displayengine/libs/core/hw_interface.cpp b/displayengine/libs/core/hw_virtual_interface.h
similarity index 67%
copy from displayengine/libs/core/hw_interface.cpp
copy to displayengine/libs/core/hw_virtual_interface.h
index 6b99a73..6976955 100644
--- a/displayengine/libs/core/hw_interface.cpp
+++ b/displayengine/libs/core/hw_virtual_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015, 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:
@@ -22,34 +22,26 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#include <utils/constants.h>
+#ifndef __HW_VIRTUAL_INTERFACE_H__
+#define __HW_VIRTUAL_INTERFACE_H__
 
 #include "hw_interface.h"
-#include "hw_framebuffer.h"
 
 namespace sde {
 
-DisplayError HWInterface::Create(HWInterface **intf, BufferSyncHandler *buffer_sync_handler) {
-  DisplayError error = kErrorNone;
-  HWFrameBuffer *hw_frame_buffer = NULL;
+class HWInfoInterface;
 
-  hw_frame_buffer = new HWFrameBuffer(buffer_sync_handler);
-  error = hw_frame_buffer->Init();
-  if (UNLIKELY(error != kErrorNone)) {
-    delete hw_frame_buffer;
-  } else {
-    *intf = hw_frame_buffer;
-  }
+class HWVirtualInterface: virtual public HWInterface {
+ public:
+  static DisplayError Create(HWVirtualInterface **intf, HWInfoInterface *hw_info_intf,
+                             BufferSyncHandler *buffer_sync_handler);
+  static DisplayError Destroy(HWVirtualInterface *intf);
 
-  return error;
-}
-
-DisplayError HWInterface::Destroy(HWInterface *intf) {
-  HWFrameBuffer *hw_frame_buffer = static_cast<HWFrameBuffer *>(intf);
-  hw_frame_buffer->Deinit();
-  delete hw_frame_buffer;
-  return kErrorNone;
-}
+ protected:
+  virtual ~HWVirtualInterface() { }
+};
 
 }  // namespace sde
 
+#endif  // __HW_VIRTUAL_INTERFACE_H__
+
diff --git a/displayengine/libs/core/offline_ctrl.cpp b/displayengine/libs/core/offline_ctrl.cpp
index 8794074..b7d5eef 100644
--- a/displayengine/libs/core/offline_ctrl.cpp
+++ b/displayengine/libs/core/offline_ctrl.cpp
@@ -26,6 +26,9 @@
 #include <utils/debug.h>
 
 #include "offline_ctrl.h"
+#include "hw_rotator_interface.h"
+#include <core/buffer_sync_handler.h>
+#include "hw_interface.h"
 
 #define __CLASS__ "OfflineCtrl"
 
@@ -33,16 +36,25 @@
 
 // TODO(user): Move this offline controller under composition manager like other modules
 // [resource manager]. Implement session management and buffer management in offline controller.
-OfflineCtrl::OfflineCtrl() : hw_intf_(NULL), hw_rotator_device_(NULL) {
+OfflineCtrl::OfflineCtrl() : hw_rotator_intf_(NULL), hw_rotator_present_(false) {
 }
 
-DisplayError OfflineCtrl::Init(HWInterface *hw_intf, HWResourceInfo hw_res_info) {
-  hw_intf_ = hw_intf;
+DisplayError OfflineCtrl::Init(BufferSyncHandler *buffer_sync_handler) {
   DisplayError error = kErrorNone;
 
-  error = hw_intf_->Open(kDeviceRotator, &hw_rotator_device_, NULL);
+  error = HWRotatorInterface::Create(&hw_rotator_intf_, buffer_sync_handler);
+  if (error != kErrorNone) {
+    if (hw_rotator_intf_) {
+      HWRotatorInterface::Destroy(hw_rotator_intf_);
+    }
+    return error;
+  }
+
+  error = hw_rotator_intf_->Open();
   if (error != kErrorNone) {
     DLOGW("Failed to open rotator device");
+  } else {
+    hw_rotator_present_ = true;
   }
 
   return kErrorNone;
@@ -51,11 +63,13 @@
 DisplayError OfflineCtrl::Deinit() {
   DisplayError error = kErrorNone;
 
-  error = hw_intf_->Close(hw_rotator_device_);
+  error = hw_rotator_intf_->Close();
   if (error != kErrorNone) {
     DLOGW("Failed to close rotator device");
     return error;
   }
+  hw_rotator_present_ = false;
+  HWRotatorInterface::Destroy(hw_rotator_intf_);
 
   return kErrorNone;
 }
@@ -87,13 +101,13 @@
 
   disp_offline_ctx->pending_rot_commit = false;
 
-  if (!hw_rotator_device_ && IsRotationRequired(hw_layers)) {
+  if (!hw_rotator_present_ && IsRotationRequired(hw_layers)) {
     DLOGV_IF(kTagOfflineCtrl, "No Rotator device found");
     return kErrorHardware;
   }
 
   error = CloseRotatorSession(hw_layers);
-  if (LIKELY(error != kErrorNone)) {
+  if (error != kErrorNone) {
     DLOGE("Close rotator session failed for display %d", disp_offline_ctx->display_type);
     return error;
   }
@@ -101,13 +115,13 @@
 
   if (IsRotationRequired(hw_layers)) {
     error = OpenRotatorSession(hw_layers);
-    if (LIKELY(error != kErrorNone)) {
+    if (error != kErrorNone) {
       DLOGE("Open rotator session failed for display %d", disp_offline_ctx->display_type);
       return error;
     }
 
-    error = hw_intf_->Validate(hw_rotator_device_, hw_layers);
-    if (LIKELY(error != kErrorNone)) {
+    error = hw_rotator_intf_->Validate(hw_layers);
+    if (error != kErrorNone) {
       DLOGE("Rotator validation failed for display %d", disp_offline_ctx->display_type);
       return error;
     }
@@ -123,7 +137,7 @@
   DisplayOfflineContext *disp_offline_ctx = reinterpret_cast<DisplayOfflineContext *>(display_ctx);
 
   if (disp_offline_ctx->pending_rot_commit) {
-    error = hw_intf_->Commit(hw_rotator_device_, hw_layers);
+    error = hw_rotator_intf_->Commit(hw_layers);
     if (error != kErrorNone) {
       DLOGE("Rotator commit failed for display %d", disp_offline_ctx->display_type);
       return error;
@@ -153,8 +167,8 @@
       rotate_info->input_buffer = layer.input_buffer;
       rotate_info->frame_rate = layer.frame_rate;
 
-      error = hw_intf_->OpenRotatorSession(hw_rotator_device_, rotate_info);
-      if (LIKELY(error != kErrorNone)) {
+      error = hw_rotator_intf_->OpenSession(rotate_info);
+      if (error != kErrorNone) {
         return error;
       }
     }
@@ -168,8 +182,8 @@
   uint32_t i = 0;
 
   while (hw_layers->closed_session_ids[i] >= 0) {
-    error = hw_intf_->CloseRotatorSession(hw_rotator_device_, hw_layers->closed_session_ids[i]);
-    if (LIKELY(error != kErrorNone)) {
+    error = hw_rotator_intf_->CloseSession(hw_layers->closed_session_ids[i]);
+    if (error != kErrorNone) {
       return error;
     }
     hw_layers->closed_session_ids[i++] = -1;
diff --git a/displayengine/libs/core/offline_ctrl.h b/displayengine/libs/core/offline_ctrl.h
index fa8b264..1525bb8 100644
--- a/displayengine/libs/core/offline_ctrl.h
+++ b/displayengine/libs/core/offline_ctrl.h
@@ -27,15 +27,18 @@
 
 #include <utils/locker.h>
 #include <utils/debug.h>
-
-#include "hw_interface.h"
+#include <core/display_interface.h>
 
 namespace sde {
 
+class HWRotatorInterface;
+class BufferSyncHandler;
+struct HWLayers;
+
 class OfflineCtrl {
  public:
   OfflineCtrl();
-  DisplayError Init(HWInterface *hw_intf, HWResourceInfo hw_res_info);
+  DisplayError Init(BufferSyncHandler *buffer_sync_handler);
   DisplayError Deinit();
   DisplayError RegisterDisplay(DisplayType type, Handle *display_ctx);
   void UnregisterDisplay(Handle display_ctx);
@@ -54,8 +57,8 @@
   DisplayError CloseRotatorSession(HWLayers *hw_layers);
   bool IsRotationRequired(HWLayers *hw_layers);
 
-  HWInterface *hw_intf_;
-  Handle hw_rotator_device_;
+  HWRotatorInterface *hw_rotator_intf_;
+  bool hw_rotator_present_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index d5d3c58..ea90dfb 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -125,8 +125,8 @@
   // 1. Source width is greater than split_left (left_mixer_width)
   // 2. Pipe clock exceeds the mixer clock
   if ((src_width > kMaxSourcePipeWidth) || (dst_width > kMaxSourcePipeWidth) ||
-      (hw_res_info_.always_src_split && ((src_width > left_mixer_width) ||
-      (pipe_clock > mixer_clock)))) {
+      (display_resource_ctx->display_attributes.always_src_split &&
+      ((src_width > left_mixer_width) || (pipe_clock > mixer_clock)))) {
     SplitRect(transform.flip_horizontal, src_rect, dst_rect, &left_pipe->src_roi,
               &left_pipe->dst_roi, &right_pipe->src_roi, &right_pipe->dst_roi, align_x);
     left_pipe->valid = true;
@@ -644,7 +644,7 @@
   return error;
 }
 
-DisplayError ResManager::CalculateDecimation(float downscale, uint8_t* decimation) {
+DisplayError ResManager::CalculateDecimation(float downscale, uint8_t *decimation) {
   float max_down_scale = FLOAT(hw_res_info_.max_scale_down);
 
   if (downscale <= max_down_scale) {
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index 3287224..7f78b29 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -26,6 +26,7 @@
 #define __RES_MANAGER_H__
 
 #include <core/display_interface.h>
+#include <private/hw_info_types.h>
 #include <utils/locker.h>
 
 #include "hw_interface.h"
diff --git a/displayengine/libs/hwc/hwc_display.cpp b/displayengine/libs/hwc/hwc_display.cpp
index 1be682d..4160054 100644
--- a/displayengine/libs/hwc/hwc_display.cpp
+++ b/displayengine/libs/hwc/hwc_display.cpp
@@ -105,10 +105,12 @@
     break;
   case HWC_POWER_MODE_NORMAL:
     state = kStateOn;
+    last_power_mode_ = HWC_POWER_MODE_NORMAL;
     break;
   case HWC_POWER_MODE_DOZE:
   case HWC_POWER_MODE_DOZE_SUSPEND:
     state = kStateDoze;
+    last_power_mode_ = HWC_POWER_MODE_DOZE;
     break;
   default:
     return -EINVAL;
@@ -208,6 +210,10 @@
   DLOGI("num_frame_dump %d, input_layer_dump_enable %d", dump_frame_count_, dump_input_layers_);
 }
 
+uint32_t HWCDisplay::GetLastPowerMode() {
+  return last_power_mode_;
+}
+
 DisplayError HWCDisplay::VSync(const DisplayEventVSync &vsync) {
   if (*hwc_procs_) {
     (*hwc_procs_)->vsync(*hwc_procs_, id_, vsync.timestamp);
diff --git a/displayengine/libs/hwc/hwc_display.h b/displayengine/libs/hwc/hwc_display.h
index 8feddf6..7ef8187 100644
--- a/displayengine/libs/hwc/hwc_display.h
+++ b/displayengine/libs/hwc/hwc_display.h
@@ -46,6 +46,7 @@
   virtual int SetActiveConfig(hwc_display_contents_1_t *content_list);
   virtual void SetFrameDumpConfig(uint32_t count, uint32_t bit_mask_layer_type);
   virtual DisplayError SetMaxMixerStages(uint32_t max_mixer_stages);
+  virtual uint32_t GetLastPowerMode();
 
  protected:
   // Maximum number of layers supported by display engine.
@@ -117,6 +118,7 @@
   uint32_t dump_frame_count_;
   uint32_t dump_frame_index_;
   bool dump_input_layers_;
+  uint32_t last_power_mode_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/hwc/hwc_session.cpp b/displayengine/libs/hwc/hwc_session.cpp
index b6d0c18..4498f18 100644
--- a/displayengine/libs/hwc/hwc_session.cpp
+++ b/displayengine/libs/hwc/hwc_session.cpp
@@ -44,6 +44,9 @@
 
 #define __CLASS__ "HWCSession"
 
+#define HWC_UEVENT_SWITCH_HDMI "change@/devices/virtual/switch/hdmi"
+#define HWC_UEVENT_GRAPHICS_FB0 "change@/devices/virtual/graphics/fb0"
+
 static sde::HWCSession::HWCModuleMethods g_hwc_module_methods;
 
 hwc_module_t HAL_MODULE_INFO_SYM = {
@@ -63,10 +66,11 @@
 namespace sde {
 
 Locker HWCSession::locker_;
+bool HWCSession::reset_panel_ = false;
 
 HWCSession::HWCSession(const hw_module_t *module) : core_intf_(NULL), hwc_procs_(NULL),
             display_primary_(NULL), display_external_(NULL), display_virtual_(NULL),
-            hotplug_thread_exit_(false), hotplug_thread_name_("HWC_HotPlugThread") {
+            uevent_thread_exit_(false), uevent_thread_name_("HWC_UeventThread") {
   hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
   hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4;
   hwc_composer_device_1_t::common.module = const_cast<hw_module_t*>(module);
@@ -141,8 +145,8 @@
     return status;
   }
 
-  if (pthread_create(&hotplug_thread_, NULL, &HWCHotPlugThread, this) < 0) {
-    DLOGE("Failed to start = %s, error = %s HDMI display Not supported", hotplug_thread_name_);
+  if (pthread_create(&uevent_thread_, NULL, &HWCUeventThread, this) < 0) {
+    DLOGE("Failed to start = %s, error = %s", uevent_thread_name_);
     display_primary_->Deinit();
     delete display_primary_;
     CoreInterface::DestroyCore();
@@ -156,8 +160,8 @@
   display_primary_->SetPowerMode(HWC_POWER_MODE_OFF);
   display_primary_->Deinit();
   delete display_primary_;
-  hotplug_thread_exit_ = true;
-  pthread_join(hotplug_thread_, NULL);
+  uevent_thread_exit_ = true;
+  pthread_join(uevent_thread_, NULL);
 
   DisplayError error = CoreInterface::DestroyCore();
   if (error != kErrorNone) {
@@ -218,6 +222,11 @@
 
   HWCSession *hwc_session = static_cast<HWCSession *>(device);
 
+  if (reset_panel_) {
+    DLOGW("panel is in bad state, resetting the panel");
+    hwc_session->ResetPanel();
+  }
+
   for (ssize_t i = (num_displays-1); i >= 0; i--) {
     hwc_display_contents_1_t *content_list = displays[i];
 
@@ -690,18 +699,18 @@
   }
 }
 
-void* HWCSession::HWCHotPlugThread(void *context) {
+void* HWCSession::HWCUeventThread(void *context) {
   if (context) {
-    return reinterpret_cast<HWCSession *>(context)->HWCHotPlugThreadHandler();
+    return reinterpret_cast<HWCSession *>(context)->HWCUeventThreadHandler();
   }
 
   return NULL;
 }
 
-void* HWCSession::HWCHotPlugThreadHandler() {
+void* HWCSession::HWCUeventThreadHandler() {
   static char uevent_data[PAGE_SIZE];
   int length = 0;
-  prctl(PR_SET_NAME, hotplug_thread_name_, 0, 0, 0);
+  prctl(PR_SET_NAME, uevent_thread_name_, 0, 0, 0);
   setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
   if (!uevent_init()) {
     DLOGE("Failed to init uevent");
@@ -709,19 +718,28 @@
     return NULL;
   }
 
-  while (!hotplug_thread_exit_) {
+  while (!uevent_thread_exit_) {
     // keep last 2 zeroes to ensure double 0 termination
     length = uevent_next_event(uevent_data, INT32(sizeof(uevent_data)) - 2);
 
-    if (!strcasestr("change@/devices/virtual/switch/hdmi", uevent_data)) {
-      continue;
-    }
-    DLOGI("Uevent HDMI = %s", uevent_data);
-    int connected = GetHDMIConnectedState(uevent_data, length);
-    if (connected >= 0) {
-      DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
-      if (HotPlugHandler(connected) == -1) {
-        DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
+    if (strcasestr(HWC_UEVENT_SWITCH_HDMI, uevent_data)) {
+      DLOGI("Uevent HDMI = %s", uevent_data);
+      int connected = GetEventValue(uevent_data, length, "SWITCH_STATE=");
+      if (connected >= 0) {
+        DLOGI("HDMI = %s", connected ? "connected" : "disconnected");
+        if (HotPlugHandler(connected) == -1) {
+          DLOGE("Failed handling Hotplug = %s", connected ? "connected" : "disconnected");
+        }
+      }
+    } else if (strcasestr(HWC_UEVENT_GRAPHICS_FB0, uevent_data)) {
+      DLOGI("Uevent FB0 = %s", uevent_data);
+      int panel_reset = GetEventValue(uevent_data, length, "PANEL_ALIVE=");
+      if (panel_reset == 0) {
+        if (hwc_procs_) {
+          reset_panel_ = true;
+          hwc_procs_->invalidate(hwc_procs_);
+        } else
+          DLOGW("Ignore resetpanel - hwc_proc not registered");
       }
     }
   }
@@ -730,18 +748,43 @@
   return NULL;
 }
 
-int HWCSession::GetHDMIConnectedState(const char *uevent_data, int length) {
-  const char* iterator_str = uevent_data;
+int HWCSession::GetEventValue(const char *uevent_data, int length, const char *event_info) {
+  const char *iterator_str = uevent_data;
   while (((iterator_str - uevent_data) <= length) && (*iterator_str)) {
-    char* pstr = strstr(iterator_str, "SWITCH_STATE=");
+    char *pstr = strstr(iterator_str, event_info);
     if (pstr != NULL) {
-      return (atoi(iterator_str + strlen("SWITCH_STATE=")));
+      return (atoi(iterator_str + strlen(event_info)));
     }
     iterator_str += strlen(iterator_str) + 1;
   }
+
   return -1;
 }
 
+void HWCSession::ResetPanel() {
+  int status = -EINVAL;
+
+  DLOGI("Powering off primary");
+  status = display_primary_->SetPowerMode(HWC_POWER_MODE_OFF);
+  if (status) {
+    DLOGE("power-off on primary failed with error = %d",status);
+  }
+
+  DLOGI("Restoring power mode on primary");
+  uint32_t mode = display_primary_->GetLastPowerMode();
+  status = display_primary_->SetPowerMode(mode);
+  if (status) {
+    DLOGE("Setting power mode = %d on primary failed with error = %d", mode,status);
+  }
+
+  status = display_primary_->EventControl(HWC_EVENT_VSYNC, 1);
+  if (status) {
+    DLOGE("enabling vsync failed for primary with error = %d",status);
+  }
+
+  reset_panel_ = false;
+}
+
 int HWCSession::HotPlugHandler(bool connected) {
   if (!hwc_procs_) {
      DLOGW("Ignore hotplug - hwc_proc not registered");
diff --git a/displayengine/libs/hwc/hwc_session.h b/displayengine/libs/hwc/hwc_session.h
index 1608ce5..3c5cc7f 100644
--- a/displayengine/libs/hwc/hwc_session.h
+++ b/displayengine/libs/hwc/hwc_session.h
@@ -68,11 +68,12 @@
   static int GetActiveConfig(hwc_composer_device_1 *device, int disp);
   static int SetActiveConfig(hwc_composer_device_1 *device, int disp, int index);
 
-  // Hotplug thread for HDMI connect/disconnect
-  static void* HWCHotPlugThread(void *context);
-  void* HWCHotPlugThreadHandler();
-  int GetHDMIConnectedState(const char *uevent_data, int length);
+  // Uevent thread
+  static void* HWCUeventThread(void *context);
+  void* HWCUeventThreadHandler();
+  int GetEventValue(const char *uevent_data, int length, const char *event_info);
   int HotPlugHandler(bool connected);
+  void ResetPanel();
   bool ValidateContentList(hwc_display_contents_1_t *content_list);
   int CreateVirtualDisplay(HWCSession *hwc_session, hwc_display_contents_1_t *content_list);
   int DestroyVirtualDisplay(HWCSession *hwc_session);
@@ -93,9 +94,10 @@
   HWCDisplayPrimary *display_primary_;
   HWCDisplayExternal *display_external_;
   HWCDisplayVirtual *display_virtual_;
-  pthread_t hotplug_thread_;
-  bool hotplug_thread_exit_;
-  const char *hotplug_thread_name_;
+  pthread_t uevent_thread_;
+  bool uevent_thread_exit_;
+  static bool reset_panel_;
+  const char *uevent_thread_name_;
   HWCBufferAllocator *buffer_allocator_;
   HWCBufferSyncHandler *buffer_sync_handler_;
 };
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 1d0a40a..4f342db 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, 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
@@ -143,6 +143,9 @@
         case HAL_PIXEL_FORMAT_RAW_SENSOR:
             aligned_w = ALIGN(width, 32);
             break;
+        case HAL_PIXEL_FORMAT_RAW10:
+            aligned_w = ALIGN(width * 10 /8, 16);
+            break;
         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
             aligned_w = ALIGN(width, 128);
             break;
@@ -451,6 +454,9 @@
         case HAL_PIXEL_FORMAT_RAW_SENSOR:
             size = alignedw * alignedh * 2;
             break;
+        case HAL_PIXEL_FORMAT_RAW10:
+            size = ALIGN(alignedw * alignedh, 4096);
+            break;
 
             // adreno formats
         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
@@ -656,6 +662,7 @@
         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
         case HAL_PIXEL_FORMAT_NV21_ZSL:
         case HAL_PIXEL_FORMAT_RAW_SENSOR:
+        case HAL_PIXEL_FORMAT_RAW10:
             ystride = cstride = width;
             ycbcr->y  = (void*)hnd->base;
             ycbcr->cr = (void*)(hnd->base + ystride * height);
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index c344045..5be5d00 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -8,6 +8,13 @@
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes) \
                                  $(TOP)/external/skia/include/core \
                                  $(TOP)/external/skia/include/images
+
+ifeq ($(strip $(TARGET_USES_QCOM_DISPLAY_PP)),true)
+LOCAL_C_INCLUDES              += $(TARGET_OUT_HEADERS)/qdcm/inc \
+                                 $(TARGET_OUT_HEADERS)/common/inc \
+                                 $(TARGET_OUT_HEADERS)/pp/inc
+endif
+
 LOCAL_SHARED_LIBRARIES        := $(common_libs) libEGL liboverlay \
                                  libhdmi libqdutils libhardware_legacy \
                                  libdl libmemalloc libqservice libsync \
@@ -38,4 +45,18 @@
                                  hwc_dump_layers.cpp \
                                  hwc_ad.cpp \
                                  hwc_virtual.cpp
+
+TARGET_MIGRATE_QDCM_LIST := msm8909
+TARGET_MIGRATE_QDCM := $(call is-board-platform-in-list,$(TARGET_MIGRATE_QDCM_LIST))
+
+ifeq ($(TARGET_MIGRATE_QDCM), true)
+ifeq ($(strip $(TARGET_USES_QCOM_DISPLAY_PP)),true)
+LOCAL_SRC_FILES += hwc_qdcm.cpp
+else
+LOCAL_SRC_FILES += hwc_qdcm_legacy.cpp
+endif
+else
+LOCAL_SRC_FILES += hwc_qdcm_legacy.cpp
+endif
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 3026d99..6acb663 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -39,9 +39,11 @@
 #include "hwc_ad.h"
 #include "profiler.h"
 #include "hwc_virtual.h"
+#include "hwc_qdcm.h"
 
 using namespace qhwc;
 using namespace overlay;
+using namespace qQdcm;
 
 #define VSYNC_DEBUG 0
 #define POWER_MODE_DEBUG 1
@@ -222,6 +224,7 @@
             ctx->mLayerRotMap[i]->reset();
     }
 
+    memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
     ctx->mAD->reset();
 
 }
@@ -277,6 +280,7 @@
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     const int dpy = HWC_DISPLAY_PRIMARY;
     bool fbComp = false;
+
     if (!ctx->mBootAnimCompleted)
         processBootAnimCompleted(ctx);
     if (LIKELY(list && list->numHwLayers > 1) && ctx->dpyAttr[dpy].connected &&
@@ -530,7 +534,7 @@
         }
         break;
     case HWC_DISPLAY_EXTERNAL:
-        if(mode == HWC_POWER_MODE_OFF) {
+        if(mode == HWC_POWER_MODE_OFF and ctx->dpyAttr[dpy].connected) {
             if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
                 ALOGE("%s: displayCommit failed for external", __FUNCTION__);
                 ret = -1;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index 7244562..5a9caec 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -453,6 +453,7 @@
     if(hnd && fbhnd && (hnd->size == fbhnd->size) &&
     (hnd->width == fbhnd->width) && (hnd->height == fbhnd->height)){
        if(tmpLayer->transform  ||
+        (list->flags & HWC_GEOMETRY_CHANGED) ||
        (!(hnd->format == HAL_PIXEL_FORMAT_RGBA_8888 ||
        hnd->format == HAL_PIXEL_FORMAT_RGBX_8888))  ||
                    (needsScaling(tmpLayer) == true)) {
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index fb69fdd..5572cc4 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -461,6 +461,13 @@
     if(mdpHw.hasMinCropWidthLimitation() and (crop_w < 5 or crop_h < 5))
         return false;
 
+    /* crop_w and crop_h should be even for yuv layer, so fallback to GPU for
+     * those cases
+     */
+    if(isYuvBuffer(hnd) && (crop_w < 2 || crop_h < 2)) {
+        return false;
+    }
+
     if((w_scale > 1.0f) || (h_scale > 1.0f)) {
         const uint32_t maxMDPDownscale = mdpHw.getMaxMDPDownscale();
         const float w_dscale = w_scale;
@@ -525,6 +532,14 @@
         ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round",
                 __FUNCTION__);
         ret = false;
+    } else if((qdutils::MDPVersion::getInstance().is8x26() ||
+               qdutils::MDPVersion::getInstance().is8x16() ||
+               qdutils::MDPVersion::getInstance().is8x39()) &&
+              !mDpy && isSecondaryAnimating(ctx) &&
+              isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) {
+        ALOGD_IF(isDebug(),"%s: Display animation in progress",
+                 __FUNCTION__);
+        ret = false;
     } else if(qdutils::MDPVersion::getInstance().getTotalPipes() < 8) {
        /* TODO: freeing up all the resources only for the targets having total
                 number of pipes < 8. Need to analyze number of VIG pipes used
@@ -818,6 +833,14 @@
         return false;
     }
 
+    if(!mDpy && isSecondaryAnimating(ctx) &&
+       (isYuvPresent(ctx,HWC_DISPLAY_EXTERNAL) ||
+       isYuvPresent(ctx,HWC_DISPLAY_VIRTUAL)) ) {
+        ALOGD_IF(isDebug(),"%s: Display animation in progress",
+                 __FUNCTION__);
+        return false;
+    }
+
     // if secondary is configuring or Padding round, fall back to video only
     // composition and release all assigned non VIG pipes from primary.
     if(isSecondaryConfiguring(ctx)) {
@@ -2024,9 +2047,6 @@
             }
         }
     }
-    // reset PTOR
-    if(!mDpy)
-        memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
 
     //reset old data
     mCurrentFrame.reset(numLayers);
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 34de2e6..f18ad36 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -37,6 +37,7 @@
 #include <display_config.h>
 #include <hdmi.h>
 #include <video/msm_hdmi_modes.h>
+#include <hwc_qdcm.h>
 
 #define QCLIENT_DEBUG 0
 
@@ -45,6 +46,7 @@
 using namespace qhwc;
 using namespace overlay;
 using namespace qdutils;
+using namespace qQdcm;
 
 namespace qClient {
 
@@ -554,6 +556,8 @@
         case IQService::GET_DISPLAY_ATTRIBUTES_FOR_CONFIG:
             ret = getDisplayAttributesForConfig(mHwcContext, inParcel,
                     outParcel);
+        case IQService::QDCM_SVC_CMDS:
+            qdcmCmdsHandler(mHwcContext, inParcel, outParcel);
             break;
         default:
             ret = NO_ERROR;
diff --git a/libhwcomposer/hwc_qdcm.cpp b/libhwcomposer/hwc_qdcm.cpp
new file mode 100644
index 0000000..9821e4e
--- /dev/null
+++ b/libhwcomposer/hwc_qdcm.cpp
@@ -0,0 +1,292 @@
+/*
+ *  Copyright (c) 2014, 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 <hwc_qdcm.h>
+#include <hwc_utils.h>
+#include <utils/String16.h>
+#include <mdp_version.h>
+#include "mode_manager.h"
+#include "libmm-disp-apis.h"
+#include "IQService.h"
+
+using namespace android;
+using namespace qService;
+using namespace qhwc;
+using namespace qmode;
+
+namespace qQdcm {
+//----------------------------------------------------------------------------
+void qdcmInitContext(hwc_context_t *ctx)
+{
+    loadQdcmLibrary(ctx);
+}
+
+void qdcmCloseContext(hwc_context_t *ctx)
+{
+    if (ctx->mQdcmInfo.mQdcmMode) {
+        unloadQdcmLibrary(ctx);
+    }
+}
+
+void qdcmApplyDefaultAfterBootAnimationDone(hwc_context_t *ctx)
+{
+    if (ctx->mQdcmInfo.mQdcmMode)
+        ctx->mQdcmInfo.mQdcmMode->applyDefaultMode(0);
+}
+
+static void qdcmSetActiveMode(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        struct SET_MODE_PROP_IN params =
+                           { (disp_id_type)in->readInt32(), in->readInt32()};
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_ACTIVE_MODE,
+                (void *)&params, (void *)NULL);
+
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmSetDefaultMode(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        struct SET_MODE_PROP_IN params =
+                          { (disp_id_type)in->readInt32(), in->readInt32()};
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_DEFAULT_MODE,
+                (void *)&params, (void *)NULL);
+
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmGetDefaultMode(hwc_context_t *ctx,
+                                            const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        int params = in->readInt32();
+        int modeid = 0;
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_DEFAULT_MODE,
+                (const void *)&params, (void *)&modeid);
+
+        out->writeInt32(modeid);
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmGetColorBalanceRange(hwc_context_t *ctx __unused,
+                const Parcel *in __unused, Parcel *out __unused)
+{
+}
+
+static void qdcmGetColorBalance(hwc_context_t *ctx,
+                                            const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        int params = in->readInt32();
+        int warmness = 0;
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_CB,
+                (const void *)&params, (void *)&warmness);
+
+        out->writeInt32(warmness);
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmSetColorBalance(hwc_context_t *ctx,
+                                            const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        struct SET_CB_IN params =
+                           { (disp_id_type)in->readInt32(), in->readInt32() };
+
+        ALOGD_IF(QDCM_DEBUG, "%s dispID = %d, warmness = %d\n",
+                __FUNCTION__, params.id, params.warmness);
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_CB,
+                (const void *)&params, NULL);
+
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmSaveModeV2(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        struct SAVE_DISPLAY_MODE_V2_IN params =
+                     { (disp_id_type)in->readInt32(),
+                                     in->readCString(),
+                           (uint32_t)in->readInt32(),
+                                     in->readInt32()
+                     };
+        int value = 0;
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SAVE_MODE_V2,
+                (const void *)&params, (void *)&value);
+
+        out->writeInt32(value);
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmSetPaConfig(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        struct SET_PA_CONFIG_IN params;
+
+        params.id = (disp_id_type)in->readInt32();
+        params.pa.ops = in->readInt32();
+        params.pa.data.hue = in->readInt32();
+        params.pa.data.saturation = in->readInt32();
+        params.pa.data.value = in->readInt32();
+        params.pa.data.contrast = in->readInt32();
+        params.pa.data.sat_thresh = in->readInt32();
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_SET_PA_CONFIG,
+                (const void *)&params, NULL);
+
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmGetPaConfig(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        int params = in->readInt32();
+        struct disp_pa_config value;
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_PA_CONFIG,
+                (const void *)&params, (void *)&value);
+
+        out->writeInt32(value.ops);
+        out->writeInt32(value.data.hue);
+        out->writeInt32(value.data.saturation);
+        out->writeInt32(value.data.value);
+        out->writeInt32(value.data.contrast);
+        out->writeInt32(value.data.sat_thresh);
+
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+static void qdcmGetPaRange(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int ret = 0;
+
+    if (ctx->mQdcmInfo.mQdcmMode && in && out) {
+
+        int params = in->readInt32();
+        struct disp_pa_range value;
+
+        ret = ctx->mQdcmInfo.mQdcmMode->requestRoute((int)CMD_GET_PA_RANGE,
+                (const void *)&params, (void *)&value);
+
+        out->writeInt32(value.max.hue);
+        out->writeInt32(value.max.saturation);
+        out->writeInt32(value.max.value);
+        out->writeInt32(value.max.contrast);
+        out->writeInt32(value.max.sat_thresh);
+        out->writeInt32(value.min.hue);
+        out->writeInt32(value.min.saturation);
+        out->writeInt32(value.min.value);
+        out->writeInt32(value.min.contrast);
+        out->writeInt32(value.min.sat_thresh);
+
+        out->writeInt32(ret);  //return operation status via binder.
+    }
+}
+
+void qdcmCmdsHandler(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+    int subcmd = in->readInt32();
+
+    ALOGD_IF(QDCM_DEBUG, "%s enter subcmd = %d\n", __FUNCTION__, subcmd);
+    switch (subcmd) {
+        case CMD_SET_ACTIVE_MODE:
+            qdcmSetActiveMode(ctx, in, out);
+            break;
+        case CMD_SET_DEFAULT_MODE:
+            qdcmSetDefaultMode(ctx, in, out);
+            break;
+        case CMD_GET_DEFAULT_MODE:
+            qdcmGetDefaultMode(ctx, in, out);
+            break;
+        case CMD_GET_CB_RANGE:
+            qdcmGetColorBalanceRange(ctx, in, out);
+            break;
+        case CMD_GET_CB:
+            qdcmGetColorBalance(ctx, in, out);
+            break;
+        case CMD_SET_CB:
+            qdcmSetColorBalance(ctx, in, out);
+            break;
+        case CMD_SAVE_MODE_V2:
+            qdcmSaveModeV2(ctx, in, out);
+            break;
+        case CMD_SET_PA_CONFIG:
+            qdcmSetPaConfig(ctx, in, out);
+            break;
+        case CMD_GET_PA_CONFIG:
+            qdcmGetPaConfig(ctx, in, out);
+            break;
+        case CMD_GET_PA_RANGE:
+            qdcmGetPaRange(ctx, in, out);
+            break;
+    }
+}
+
+
+} //namespace qQdcm
+
diff --git a/libhwcomposer/hwc_qdcm.h b/libhwcomposer/hwc_qdcm.h
new file mode 100644
index 0000000..6453159
--- /dev/null
+++ b/libhwcomposer/hwc_qdcm.h
@@ -0,0 +1,94 @@
+/*
+ *  Copyright (c) 2014, 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 ANDROID_QDCM_H
+#define ANDROID_QDCM_H
+
+#include <utils/Errors.h>
+#include <sys/types.h>
+#include <cutils/log.h>
+#include <hwc_utils.h>
+#include <dlfcn.h>
+#include <binder/Parcel.h>
+#include <cutils/properties.h>
+
+#define QDCM_DEBUG 0
+
+namespace qmode {
+class ModeManager;
+}
+
+using namespace android;
+
+namespace qQdcm {
+// ----------------------------------------------------------------------------
+
+//function prototypes used for QDCM library and service
+static inline void loadQdcmLibrary(hwc_context_t *ctx)
+{
+    ctx->mQdcmInfo.mQdcmLib = dlopen("libmm-qdcm.so", RTLD_NOW);
+    qmode::ModeManager* (*factory)() = NULL;
+
+    if (ctx->mQdcmInfo.mQdcmLib)
+        *(void **)&factory = dlsym(ctx->mQdcmInfo.mQdcmLib, "getObject");
+
+    if (factory) {
+        ctx->mQdcmInfo.mQdcmMode = factory();
+    } else {
+        ctx->mQdcmInfo.mQdcmMode = NULL;
+        ALOGE("QDCM LIbrary load failing!");
+    }
+
+    ALOGD_IF(QDCM_DEBUG, "QDCM LIbrary loaded successfully!");
+}
+
+static inline void unloadQdcmLibrary(hwc_context_t *ctx)
+{
+    void (*destroy)(qmode::ModeManager*) = NULL;
+
+    if (ctx->mQdcmInfo.mQdcmLib) {
+        *(void **)&destroy = dlsym(ctx->mQdcmInfo.mQdcmLib, "deleteObject");
+
+        if (destroy) {
+            destroy(ctx->mQdcmInfo.mQdcmMode);
+            ctx->mQdcmInfo.mQdcmMode = NULL;
+        }
+
+        dlclose(ctx->mQdcmInfo.mQdcmLib);
+        ctx->mQdcmInfo.mQdcmLib = NULL;
+    }
+}
+
+void qdcmInitContext(hwc_context_t *);
+void qdcmCloseContext(hwc_context_t *);
+void qdcmApplyDefaultAfterBootAnimationDone(hwc_context_t *);
+void qdcmCmdsHandler(hwc_context_t*, const Parcel*, Parcel*);
+
+}; // namespace qQdcm
+#endif // ANDROID_QDCM_H
diff --git a/libhwcomposer/hwc_qdcm_legacy.cpp b/libhwcomposer/hwc_qdcm_legacy.cpp
new file mode 100644
index 0000000..9c2c7b0
--- /dev/null
+++ b/libhwcomposer/hwc_qdcm_legacy.cpp
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2014, 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 <hwc_qdcm.h>
+#include <hwc_utils.h>
+#include <IQService.h>
+#include <mdp_version.h>
+#include <dlfcn.h>
+
+using namespace android;
+using namespace qService;
+using namespace qhwc;
+
+namespace qQdcm {
+//----------------------------------------------------------------------------
+void qdcmInitContext(hwc_context_t *ctx)
+{
+}
+
+void qdcmCloseContext(hwc_context_t *ctx)
+{
+}
+
+void qdcmApplyDefaultAfterBootAnimationDone(hwc_context_t *ctx)
+{
+    int ret = 0;
+    int (*applyMode)(int) = NULL;
+    void *modeHandle = NULL;
+
+    modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
+    if (modeHandle) {
+        *(void **)&applyMode = dlsym(modeHandle, "applyDefaults");
+        if (applyMode) {
+            ret = applyMode(HWC_DISPLAY_PRIMARY);
+            if (ret)
+                ALOGE("%s: Not able to apply default mode", __FUNCTION__);
+        } else {
+            ALOGE("%s: No symbol applyDefaults found", __FUNCTION__);
+        }
+        dlclose(modeHandle);
+    } else {
+        ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
+    }
+}
+
+//do nothing in case qdcm legacy implementation.
+void qdcmCmdsHandler(hwc_context_t *ctx, const Parcel *in, Parcel *out)
+{
+}
+
+
+} //namespace qQdcm
+
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 27243c4..db982db 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -43,6 +43,7 @@
 #include "comptype.h"
 #include "hwc_virtual.h"
 #include "qd_utils.h"
+#include "hwc_qdcm.h"
 #include <sys/sysinfo.h>
 #include <dlfcn.h>
 #include <video/msm_hdmi_modes.h>
@@ -52,6 +53,7 @@
 using namespace android;
 using namespace overlay;
 using namespace overlay::utils;
+using namespace qQdcm;
 namespace ovutils = overlay::utils;
 
 #ifdef QCOM_BSP
@@ -477,6 +479,10 @@
 
     memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
     ctx->mHPDEnabled = false;
+
+    //init qdcm service related context.
+    qdcmInitContext(ctx);
+
     ALOGI("Initializing Qualcomm Hardware Composer");
     ALOGI("MDP version: %d", ctx->mMDP.version);
 
@@ -490,6 +496,9 @@
 
 void closeContext(hwc_context_t *ctx)
 {
+    //close qdcm service related context.
+    qdcmCloseContext(ctx);
+
     if(ctx->mOverlay) {
         delete ctx->mOverlay;
         ctx->mOverlay = NULL;
@@ -2700,32 +2709,18 @@
 
 void processBootAnimCompleted(hwc_context_t *ctx) {
     char value[PROPERTY_VALUE_MAX];
-    int boot_finished = 0, ret = -1;
-    int (*applyMode)(int) = NULL;
-    void *modeHandle = NULL;
+    int ret = -1;
 
-    // Reading property set on boot finish in SF
-    property_get("service.bootanim.exit", value, "0");
-    boot_finished = atoi(value);
-    if (!boot_finished)
-        return;
+    // Applying default mode after bootanimation is finished
+    property_get("init.svc.bootanim", value, "running");
 
-    modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
-    if (modeHandle) {
-        *(void **)&applyMode = dlsym(modeHandle, "applyDefaults");
-        if (applyMode) {
-            ret = applyMode(HWC_DISPLAY_PRIMARY);
-            if (ret)
-                ALOGD("%s: Not able to apply default mode", __FUNCTION__);
-        } else {
-            ALOGE("%s: No symbol applyDefaults found", __FUNCTION__);
-        }
-        dlclose(modeHandle);
-    } else {
-        ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
+    if (!strncmp(value,"stopped",strlen("stopped"))) {
+        ctx->mBootAnimCompleted = true;
+
+        //one-shot action check if bootanimation completed then apply
+        //default display mode.
+        qdcmApplyDefaultAfterBootAnimationDone(ctx);
     }
-
-    ctx->mBootAnimCompleted = true;
 }
 
 void BwcPM::setBwc(const hwc_context_t *ctx, const int& dpy,
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index f290dc8..ac61e68 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -55,6 +55,10 @@
 
 namespace ovutils = overlay::utils;
 
+namespace qmode {
+class ModeManager;
+}
+
 namespace overlay {
 class Overlay;
 class Rotator;
@@ -611,6 +615,13 @@
     EGLDisplay mEGLDisplay;
 };
 
+//struct holds the information about libmm-qdcm.so
+struct qdcm_info {
+    qmode::ModeManager *mQdcmMode;
+    void *mQdcmLib;
+    bool  mBootAnimCompleted;
+};
+
 // -----------------------------------------------------------------------------
 // HWC context
 // This structure contains overall state
@@ -698,6 +709,8 @@
     bool mBootAnimCompleted;
     // Display binder service
     qService::QService* mQService;
+    //struct holds the information about display tuning service library.
+    struct qdcm_info mQdcmInfo;
 };
 
 namespace qhwc {
@@ -728,6 +741,16 @@
             ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected);
 }
 
+static inline bool isSecondaryAnimating(hwc_context_t* ctx) {
+    return (ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected &&
+            (!ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isPause) &&
+            ctx->listStats[HWC_DISPLAY_EXTERNAL].isDisplayAnimating)
+            ||
+           (ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected &&
+            (!ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) &&
+            ctx->listStats[HWC_DISPLAY_VIRTUAL].isDisplayAnimating);
+}
+
 /* Return Virtual Display connection status */
 static inline bool isVDConnected(hwc_context_t* ctx) {
     return ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected;
diff --git a/liboverlay/overlayMdp.cpp b/liboverlay/overlayMdp.cpp
index 0c31dd3..828f4fc 100644
--- a/liboverlay/overlayMdp.cpp
+++ b/liboverlay/overlayMdp.cpp
@@ -175,12 +175,15 @@
                 mOVInfo.src_rect.w = utils::aligndown(mOVInfo.src_rect.w, 4);
         }
     } else {
+        // On 8974 and 8x26, there is a limitation of 1-pixel down-scaling
         if (mdpVersion >= MDSS_V5) {
-            // Check for 1-pixel down-scaling
-            if (mOVInfo.src_rect.w - mOVInfo.dst_rect.w == 1)
-                mOVInfo.src_rect.w -= 1;
-            if (mOVInfo.src_rect.h - mOVInfo.dst_rect.h == 1)
-                mOVInfo.src_rect.h -= 1;
+            if(qdutils::MDPVersion::getInstance().is8x74v2() ||
+                    qdutils::MDPVersion::getInstance().is8x26()) {
+                if (mOVInfo.src_rect.w - mOVInfo.dst_rect.w == 1)
+                    mOVInfo.src_rect.w -= 1;
+                if (mOVInfo.src_rect.h - mOVInfo.dst_rect.h == 1)
+                    mOVInfo.src_rect.h -= 1;
+            }
         }
     }
 
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index e045918..a6a1b85 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -256,6 +256,7 @@
                 ALOGI("PartialUpdate disabled by property");
         }
         fclose(panelInfoNodeFP);
+        free(readLine);
     } else {
         ALOGE("Failed to open msm_fb_panel_info node");
     }
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 6a9d7f8..30578bc 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -63,6 +63,7 @@
         SET_FRAME_DUMP_CONFIG = 21,  // Provides ability to set the frame dump config
         SET_S3D_MODE = 22, // Set the 3D mode as specified in msm_hdmi_modes.h
         CONNECT_HDMI_CLIENT = 23,  // Connect HDMI CEC HAL Client
+        QDCM_SVC_CMDS = 24,        // request QDCM services.
         SET_ACTIVE_CONFIG = 25, //Set a specified display config
         GET_ACTIVE_CONFIG = 26, //Get the current config index
         GET_CONFIG_COUNT = 27, //Get the number of supported display configs