sdm: Add support for multiple displays

- Enable creation of display interfaces to an arbitrary number of
  displays.
- Enable discovery of available displays and their status.
- Enable querying of maximum concurrent display interfaces per display
  type.

CRs-Fixed: 2200594
Change-Id: Iee4594254abb5ca420d69d8ad65c9d4ff8a8f575
diff --git a/sdm/include/core/buffer_allocator.h b/sdm/include/core/buffer_allocator.h
index a6a3cac..54fcf97 100644
--- a/sdm/include/core/buffer_allocator.h
+++ b/sdm/include/core/buffer_allocator.h
@@ -36,6 +36,7 @@
 #ifndef __BUFFER_ALLOCATOR_H__
 #define __BUFFER_ALLOCATOR_H__
 
+#include <cstddef>
 #include "layer_buffer.h"
 
 namespace sdm {
diff --git a/sdm/include/core/core_interface.h b/sdm/include/core/core_interface.h
index d169956..ba01175 100644
--- a/sdm/include/core/core_interface.h
+++ b/sdm/include/core/core_interface.h
@@ -38,6 +38,8 @@
 #define __CORE_INTERFACE_H__
 
 #include <stdint.h>
+#include <map>
+#include <vector>
 
 #include "display_interface.h"
 #include "sdm_types.h"
@@ -85,18 +87,36 @@
   kBwModeMax,      //!< Limiter for maximum available bandwidth modes.
 };
 
-
 /*! @brief Information on hardware for the first display
 
   @details This structure returns the display type of the first display on the device
-  (internal display or HDMI etc) and whether it is currently connected,
-
+  (internal display or HDMI etc) and whether it is currently connected.
 */
 struct HWDisplayInterfaceInfo {
-  DisplayType type;
-  bool is_connected;
+  DisplayType type = kDisplayTypeMax;
+  bool is_connected = false;
 };
 
+/*! @brief Information about a single display/monitor/screen
+
+  @details This structure returns the display configuration and status of a single display. A
+  list of this structure type 'HWDisplaysInfo' is used to return information on all available
+  displays. See \link HWDisplaysInfo \endlink
+*/
+struct HWDisplayInfo {
+  int32_t display_id = -1;                     //!< ID of this display (Display ID).
+  DisplayType display_type = kDisplayTypeMax;  //!< Type of display: BuiltIn/Pluggable/Virtual
+  bool is_connected = false;                   //!< Connection status of the display.
+  bool is_primary = false;                     //!< True only if this is the main display of the
+                                               //!< device.
+};
+
+/*! @brief Information on all displays as a map with display_id as key.
+
+  @details This map returns the display configuration and status of all displays.
+*/
+typedef std::map<int32_t, HWDisplayInfo> HWDisplaysInfo;
+
 /*! @brief Display core interface.
 
   @details This class defines display core interfaces. It contains methods which client shall use
@@ -161,6 +181,24 @@
   virtual DisplayError CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
                                      DisplayInterface **interface) = 0;
 
+  /*! @brief Method to create a display device for a given display ID.
+
+    @details Client shall use this method to create a DisplayInterface to a discovered display
+    identified by its display ID. A handle to the DisplayInterface is returned via the 'interface'
+    output parameter which can be used to interact further with the display device. Displays and
+    their IDs must be discovered using GetDisplaysStatus().
+
+    @param[in] display_id A display ID got from \link GetDisplaysStatus() \endlink
+    @param[in] event_handler \link DisplayEventHandler \endlink
+    @param[out] interface \link DisplayInterface \endlink
+
+    @return \link DisplayError \endlink
+
+    @sa DestroyDisplay
+  */
+  virtual DisplayError CreateDisplay(int32_t display_id, DisplayEventHandler *event_handler,
+                                     DisplayInterface **interface) = 0;
+
   /*! @brief Method to destroy a display device.
 
     @details Client shall use this method to destroy each of the created display device objects.
@@ -178,9 +216,8 @@
     @param[in] mode indicate the mode or use case
 
     @return \link DisplayError \endlink
-
-   */
-    virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
+  */
+  virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
 
   /*! @brief Method to get characteristics of the first display.
 
@@ -190,10 +227,37 @@
     @param[in] hw_disp_info structure that this method will fill up with info.
 
     @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) = 0;
 
-   */
-    virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) = 0;
+  /*! @brief Method to get an up-to-date list of all available displays.
 
+    @details Client shall use this method to get the updated list of all available displays and
+    their properties, usually in response to a hot-plug event. Client must use one of the returned
+    HWDisplayInfo::display_ids when using CreateDisplay(int32_t display_id, ...) to create the
+    DisplayInterface to the display.
+
+    @param[out] hw_displays_info \link HWDisplaysInfo \endlink which is a map of \link HWDisplayInfo
+    \endlink structures with display_id as the key.
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetDisplaysStatus(HWDisplaysInfo *hw_displays_info) = 0;
+
+  /*! @brief Method to get the maximum supported number of concurrent displays of a particular type.
+
+    @details Client shall use this method to get the maximum number of DisplayInterface instances
+    that can be created for a particular \link DisplayType \endlink display. For the maximum
+    number of concurrent DisplayInterfaces supported of all types, call with type kDisplayTypeMax.
+
+    @param[in] type Type of display: BuiltIn/Pluggable/Virtual/kDisplayTypeMax
+    key.
+
+    @param[out] max_displays Maximum number of DisplayInterface instances possible.
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays) = 0;
 
  protected:
   virtual ~CoreInterface() { }
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index a6e3386..7b38d24 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -51,11 +51,16 @@
   @sa CoreInterface::IsDisplaySupported
 */
 enum DisplayType {
-  kPrimary,         //!< Main physical display which is attached to the handheld device.
-  kHDMI,            //!< HDMI physical display which is generally detachable.
-  kVirtual,         //!< Contents would be rendered into the output buffer provided by the client
-                    //!< e.g. wireless display.
+  kPrimary,             //!< Main physical display which is attached to the handheld device.
+  kBuiltIn = kPrimary,  //!< Type name for all non-detachable physical displays. Use kBuiltIn
+                        //!< instead of kPrimary.
+  kHDMI,                //!< HDMI physical display which is generally detachable.
+  kPluggable = kHDMI,   //!< Type name for all pluggable physical displays. Use kPluggable
+                        //!< instead of kHDMI.
+  kVirtual,             //!< Contents would be rendered into the output buffer provided by the
+                        //!< client e.g. wireless display.
   kDisplayMax,
+  kDisplayTypeMax = kDisplayMax
 };
 
 /*! @brief This enum represents states of a display device.
@@ -164,15 +169,15 @@
   @sa DisplayInterface::SetConfig
 */
 struct DisplayConfigFixedInfo {
-  bool underscan = false;   //!< If display support CE underscan.
-  bool secure = false;      //!< If this display is capable of handling secure content.
-  bool is_cmdmode = false;  //!< If panel is command mode panel.
-  bool hdr_supported = false;  //!< if HDR is enabled
+  bool underscan = false;              //!< If display support CE underscan.
+  bool secure = false;                 //!< If this display is capable of handling secure content.
+  bool is_cmdmode = false;             //!< If panel is command mode panel.
+  bool hdr_supported = false;          //!< if HDR is enabled
   bool hdr_metadata_type_one = false;  //!< Metadata type one obtained from HDR sink
-  uint32_t hdr_eotf = 0;  //!< Electro optical transfer function
-  uint32_t max_luminance = 0;  //!< From Panel's peak luminance
-  uint32_t average_luminance = 0;  //!< From Panel's average luminance
-  uint32_t min_luminance = 0;  //!< From Panel's blackness level
+  uint32_t hdr_eotf = 0;               //!< Electro optical transfer function
+  uint32_t max_luminance = 0;          //!< From Panel's peak luminance
+  uint32_t average_luminance = 0;      //!< From Panel's average luminance
+  uint32_t min_luminance = 0;          //!< From Panel's blackness level
 };
 
 /*! @brief This structure defines configuration for variable properties of a display device.
@@ -659,6 +664,23 @@
   */
   virtual DisplayError GetDisplayPort(DisplayPort *port) = 0;
 
+  /*! @brief Method to get display ID information.
+
+    @param[out] display_id Current display's ID as can be discovered using
+    CoreInterface::GetDisplaysStatus().
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetDisplayId(int32_t *display_id) = 0;
+
+  /*! @brief Method to get the display's type.
+
+    @param[out] display_type Current display's type.
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetDisplayType(DisplayType *display_type) = 0;
+
   /*! @brief Method to query whether it is Primrary device.
 
     @return true if this interface is primary.
diff --git a/sdm/include/private/extension_interface.h b/sdm/include/private/extension_interface.h
index 2e5bd49..b889cab 100644
--- a/sdm/include/private/extension_interface.h
+++ b/sdm/include/private/extension_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2018, 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:
@@ -39,7 +39,7 @@
 #define CREATE_EXTENSION_INTERFACE_NAME "CreateExtensionInterface"
 #define DESTROY_EXTENSION_INTERFACE_NAME "DestroyExtensionInterface"
 
-#define EXTENSION_REVISION_MAJOR (1)
+#define EXTENSION_REVISION_MAJOR (2)
 #define EXTENSION_REVISION_MINOR (0)
 
 #define EXTENSION_VERSION_TAG ((uint16_t) ((EXTENSION_REVISION_MAJOR << 8) \
@@ -52,7 +52,8 @@
 
 class ExtensionInterface {
  public:
-  virtual DisplayError CreatePartialUpdate(DisplayType type, const HWResourceInfo &hw_resource_info,
+  virtual DisplayError CreatePartialUpdate(int32_t display_id, DisplayType type,
+                                           const HWResourceInfo &hw_resource_info,
                                            const HWPanelInfo &hw_panel_info,
                                            const HWMixerAttributes &mixer_attributes,
                                            const HWDisplayAttributes &display_attributes,
@@ -60,7 +61,8 @@
                                            PartialUpdateInterface **interface) = 0;
   virtual DisplayError DestroyPartialUpdate(PartialUpdateInterface *interface) = 0;
 
-  virtual DisplayError CreateStrategyExtn(DisplayType type, BufferAllocator *buffer_allocator,
+  virtual DisplayError CreateStrategyExtn(int32_t display_id, DisplayType type,
+                                          BufferAllocator *buffer_allocator,
                                           const HWResourceInfo &hw_resource_info,
                                           const HWPanelInfo &hw_panel_info,
                                           const HWMixerAttributes &mixer_attributes,
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index c142a05..220bbf3 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -53,16 +53,16 @@
 #define MAX_CSC_BIAS_SIZE           3
 
 enum HWDeviceType {
-  kDevicePrimary,
-  kDeviceHDMI,
+  kDeviceBuiltIn,
+  kDevicePluggable,
   kDeviceVirtual,
   kDeviceRotator,
   kDeviceMax,
 };
 
 enum HWBlockType {
-  kHWPrimary,
-  kHWHDMI,
+  kHWBuiltIn,
+  kHWPluggable,
   kHWWriteback0,
   kHWWriteback1,
   kHWWriteback2,
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index b9d047c..1d2ce89 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -37,7 +37,7 @@
     kCmdMax,
   };
 
-  virtual DisplayError RegisterDisplay(DisplayType type,
+  virtual DisplayError RegisterDisplay(int32_t display_id, DisplayType type,
                                        const HWDisplayAttributes &display_attributes,
                                        const HWPanelInfo &hw_panel_info,
                                        const HWMixerAttributes &mixer_attributes,
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index 8256d2f..09e76cd 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -26,8 +26,8 @@
 LOCAL_SRC_FILES               := core_interface.cpp \
                                  core_impl.cpp \
                                  display_base.cpp \
-                                 display_primary.cpp \
-                                 display_hdmi.cpp \
+                                 display_builtin.cpp \
+                                 display_pluggable.cpp \
                                  display_virtual.cpp \
                                  comp_manager.cpp \
                                  strategy.cpp \
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index e6eed76..14a31cd 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -22,9 +22,11 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <core/buffer_allocator.h>
 #include <utils/constants.h>
 #include <utils/debug.h>
-#include <core/buffer_allocator.h>
+#include <set>
+#include <string>
 #include <vector>
 
 #include "comp_manager.h"
@@ -78,7 +80,7 @@
   return kErrorNone;
 }
 
-DisplayError CompManager::RegisterDisplay(DisplayType type,
+DisplayError CompManager::RegisterDisplay(int32_t display_id, DisplayType type,
                                           const HWDisplayAttributes &display_attributes,
                                           const HWPanelInfo &hw_panel_info,
                                           const HWMixerAttributes &mixer_attributes,
@@ -94,8 +96,8 @@
   }
 
   Strategy *&strategy = display_comp_ctx->strategy;
-  strategy = new Strategy(extension_intf_, buffer_allocator_, type, hw_res_info_, hw_panel_info,
-                          mixer_attributes, display_attributes, fb_config);
+  strategy = new Strategy(extension_intf_, buffer_allocator_, display_id, type, hw_res_info_,
+                          hw_panel_info, mixer_attributes, display_attributes, fb_config);
   if (!strategy) {
     DLOGE("Unable to create strategy");
     delete display_comp_ctx;
@@ -109,8 +111,9 @@
     return error;
   }
 
-  error = resource_intf_->RegisterDisplay(type, display_attributes, hw_panel_info, mixer_attributes,
-                                          &display_comp_ctx->display_resource_ctx);
+  error =
+      resource_intf_->RegisterDisplay(display_id, type, display_attributes, hw_panel_info,
+                                      mixer_attributes, &display_comp_ctx->display_resource_ctx);
   if (error != kErrorNone) {
     strategy->Deinit();
     delete strategy;
@@ -119,8 +122,9 @@
     return error;
   }
 
-  registered_displays_[type] = 1;
+  registered_displays_.insert(display_id);
   display_comp_ctx->is_primary_panel = hw_panel_info.is_primary_panel;
+  display_comp_ctx->display_id = display_id;
   display_comp_ctx->display_type = type;
   display_comp_ctx->fb_config = fb_config;
   *display_ctx = display_comp_ctx;
@@ -131,9 +135,9 @@
     max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
   }
 
-  DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
-           "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
-           display_comp_ctx->display_type);
+  DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
+           StringDisplayList(registered_displays_), StringDisplayList(configured_displays_),
+           display_comp_ctx->display_id, display_comp_ctx->display_type);
 
   return kErrorNone;
 }
@@ -154,16 +158,16 @@
   strategy->Deinit();
   delete strategy;
 
-  registered_displays_[display_comp_ctx->display_type] = 0;
-  configured_displays_[display_comp_ctx->display_type] = 0;
+  registered_displays_.erase(display_comp_ctx->display_id);
+  configured_displays_.erase(display_comp_ctx->display_id);
 
-  if (display_comp_ctx->display_type == kHDMI) {
+  if (display_comp_ctx->display_type == kPluggable) {
     max_layers_ = kMaxSDELayers;
   }
 
-  DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
-           "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
-           display_comp_ctx->display_type);
+  DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
+           StringDisplayList(registered_displays_), StringDisplayList(configured_displays_),
+           display_comp_ctx->display_id, display_comp_ctx->display_type);
 
   delete display_comp_ctx;
   display_comp_ctx = NULL;
@@ -201,7 +205,7 @@
 
   // For HDMI S3D mode, set max_layers_ to 0 so that primary display would fall back
   // to GPU composition to release pipes for HDMI.
-  if (display_comp_ctx->display_type == kHDMI) {
+  if (display_comp_ctx->display_type == kPluggable) {
     if (hw_panel_info.s3d_mode != kS3DModeNone) {
       max_layers_ = 0;
     } else {
@@ -355,8 +359,10 @@
   DisplayError error = kErrorNone;
   DisplayCompositionContext *display_comp_ctx =
                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  configured_displays_[display_comp_ctx->display_type] = 1;
-  if (configured_displays_ == registered_displays_) {
+  configured_displays_.insert(display_comp_ctx->display_id);
+
+  // Check if all registered displays are in the configured display list.
+  if ((registered_displays_.size() == configured_displays_.size())) {
     safe_mode_ = false;
   }
 
@@ -367,9 +373,9 @@
 
   display_comp_ctx->idle_fallback = false;
 
-  DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
-           "display type %d", registered_displays_, configured_displays_,
-           display_comp_ctx->display_type);
+  DLOGV_IF(kTagCompManager, "Registered displays [%s], configured displays [%s], display %d-%d",
+           StringDisplayList(registered_displays_), StringDisplayList(configured_displays_),
+           display_comp_ctx->display_id, display_comp_ctx->display_type);
 
   return kErrorNone;
 }
@@ -515,19 +521,20 @@
   return kErrorNone;
 }
 
-bool CompManager::SetDisplayState(Handle display_ctx,
-                                  DisplayState state, DisplayType display_type) {
-  display_state_[display_type] = state;
+bool CompManager::SetDisplayState(Handle display_ctx, DisplayState state) {
+  DisplayCompositionContext *display_comp_ctx =
+      reinterpret_cast<DisplayCompositionContext *>(display_ctx);
 
   switch (state) {
   case kStateOff:
     Purge(display_ctx);
-    configured_displays_.reset(display_type);
-    DLOGV_IF(kTagCompManager, "configured_displays_ = 0x%x", configured_displays_);
+    configured_displays_.erase(display_comp_ctx->display_id);
+    DLOGV_IF(kTagCompManager, "Configured displays = [%s]",
+             StringDisplayList(configured_displays_));
     break;
 
   case kStateOn:
-    if (registered_displays_.count() > 1) {
+    if (registered_displays_.size() > 1) {
       safe_mode_ = true;
       DLOGV_IF(kTagCompManager, "safe_mode = %d", safe_mode_);
     }
@@ -550,4 +557,16 @@
   return kErrorNone;
 }
 
+const char *CompManager::StringDisplayList(const std::set<int32_t> &displays) {
+  std::string displays_str;
+  for (auto disps : displays) {
+    if (displays_str.empty()) {
+      displays_str = std::to_string(disps);
+    } else {
+      displays_str += ", " + std::to_string(disps);
+    }
+  }
+  return displays_str.c_str();
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index eb2b470..1d27b85 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -29,6 +29,7 @@
 #include <private/extension_interface.h>
 #include <utils/locker.h>
 #include <bitset>
+#include <set>
 #include <vector>
 
 #include "strategy.h"
@@ -43,7 +44,8 @@
                     BufferAllocator *buffer_allocator, BufferSyncHandler *buffer_sync_handler,
                     SocketHandler *socket_handler);
   DisplayError Deinit();
-  DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &display_attributes,
+  DisplayError RegisterDisplay(int32_t display_id, DisplayType type,
+                               const HWDisplayAttributes &display_attributes,
                                const HWPanelInfo &hw_panel_info,
                                const HWMixerAttributes &mixer_attributes,
                                const DisplayConfigVariableInfo &fb_config, Handle *display_ctx);
@@ -67,7 +69,7 @@
   void ControlPartialUpdate(Handle display_ctx, bool enable);
   DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   DisplayError ValidateAndSetCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
-  bool SetDisplayState(Handle display_ctx, DisplayState state, DisplayType display_type);
+  bool SetDisplayState(Handle display_ctx, DisplayState state);
   DisplayError SetMaxBandwidthMode(HWBwModes mode);
   DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
   DisplayError SetDetailEnhancerData(Handle display_ctx, const DisplayDetailEnhancerData &de_data);
@@ -82,12 +84,14 @@
   static const int kSafeModeThreshold = 4;
 
   void PrepareStrategyConstraints(Handle display_ctx, HWLayers *hw_layers);
+  const char *StringDisplayList(const std::set<int32_t> &displays);
 
   struct DisplayCompositionContext {
     Strategy *strategy = NULL;
     StrategyConstraints constraints;
     Handle display_resource_ctx = NULL;
-    DisplayType display_type = kPrimary;
+    int32_t display_id = -1;
+    DisplayType display_type = kBuiltIn;
     uint32_t max_strategies = 0;
     uint32_t remaining_strategies = 0;
     bool idle_fallback = false;
@@ -101,9 +105,8 @@
 
   Locker locker_;
   ResourceInterface *resource_intf_ = NULL;
-  std::bitset<kDisplayMax> registered_displays_;  // Bit mask of registered displays
-  std::bitset<kDisplayMax> configured_displays_;  // Bit mask of sucessfully configured displays
-  uint32_t display_state_[kDisplayMax] = {};
+  std::set<int32_t> registered_displays_;  // List of registered displays
+  std::set<int32_t> configured_displays_;  // List of sucessfully configured displays
   bool safe_mode_ = false;              // Flag to notify all displays to be in resource crunch
                                         // mode, where strategy manager chooses the best strategy
                                         // that uses optimal number of pipes for each display
diff --git a/sdm/libs/core/core_impl.cpp b/sdm/libs/core/core_impl.cpp
index 5532858..8aaac7c 100644
--- a/sdm/libs/core/core_impl.cpp
+++ b/sdm/libs/core/core_impl.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, 2018 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:
@@ -24,16 +24,17 @@
 
 #include <dlfcn.h>
 #include <signal.h>
-#include <utils/locker.h>
 #include <utils/constants.h>
 #include <utils/debug.h>
+#include <utils/locker.h>
+#include <utils/utils.h>
 
+#include "color_manager.h"
 #include "core_impl.h"
-#include "display_primary.h"
-#include "display_hdmi.h"
+#include "display_builtin.h"
+#include "display_pluggable.h"
 #include "display_virtual.h"
 #include "hw_info_interface.h"
-#include "color_manager.h"
 
 #define __CLASS__ "CoreImpl"
 
@@ -92,6 +93,12 @@
     DLOGW("Unable creating color manager and continue without it.");
   }
 
+  // Populate hw_displays_info_ once.
+  error = hw_info_intf_->GetDisplaysStatus(&hw_displays_info_);
+  if (error != kErrorNone) {
+    DLOGW("Failed getting displays status. Error = %d", error);
+  }
+
   signal(SIGPIPE, SIG_IGN);
   return kErrorNone;
 
@@ -125,21 +132,21 @@
   DisplayBase *display_base = NULL;
 
   switch (type) {
-  case kPrimary:
-    display_base = new DisplayPrimary(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                      buffer_allocator_, &comp_mgr_);
-    break;
-  case kHDMI:
-    display_base = new DisplayHDMI(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                   buffer_allocator_, &comp_mgr_);
-    break;
-  case kVirtual:
-    display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
-                                      buffer_allocator_, &comp_mgr_);
-    break;
-  default:
-    DLOGE("Spurious display type %d", type);
-    return kErrorParameters;
+    case kBuiltIn:
+      display_base = new DisplayBuiltIn(event_handler, hw_info_intf_, buffer_sync_handler_,
+                                        buffer_allocator_, &comp_mgr_);
+      break;
+    case kPluggable:
+      display_base = new DisplayPluggable(event_handler, hw_info_intf_, buffer_sync_handler_,
+                                          buffer_allocator_, &comp_mgr_);
+      break;
+    case kVirtual:
+      display_base = new DisplayVirtual(event_handler, hw_info_intf_, buffer_sync_handler_,
+                                        buffer_allocator_, &comp_mgr_);
+      break;
+    default:
+      DLOGE("Spurious display type %d", type);
+      return kErrorParameters;
   }
 
   if (!display_base) {
@@ -156,6 +163,57 @@
   return kErrorNone;
 }
 
+DisplayError CoreImpl::CreateDisplay(int32_t display_id, DisplayEventHandler *event_handler,
+                                     DisplayInterface **intf) {
+  SCOPE_LOCK(locker_);
+
+  if (!event_handler || !intf) {
+    return kErrorParameters;
+  }
+
+  auto iter = hw_displays_info_.find(display_id);
+
+  if (iter == hw_displays_info_.end()) {
+    DLOGE("Spurious display id %d", display_id);
+    return kErrorParameters;
+  }
+
+  DisplayBase *display_base = NULL;
+  DisplayType display_type = iter->second.display_type;
+
+  switch (display_type) {
+    case kBuiltIn:
+      display_base = new DisplayBuiltIn(display_id, event_handler, hw_info_intf_,
+                                        buffer_sync_handler_, buffer_allocator_, &comp_mgr_);
+      break;
+    case kPluggable:
+      display_base = new DisplayPluggable(display_id, event_handler, hw_info_intf_,
+                                          buffer_sync_handler_, buffer_allocator_, &comp_mgr_);
+      break;
+    case kVirtual:
+      display_base = new DisplayVirtual(display_id, event_handler, hw_info_intf_,
+                                        buffer_sync_handler_, buffer_allocator_, &comp_mgr_);
+      break;
+    default:
+      DLOGE("Spurious display type %d", display_type);
+      return kErrorParameters;
+  }
+
+  if (!display_base) {
+    return kErrorMemory;
+  }
+
+  DisplayError error = display_base->Init();
+  if (error != kErrorNone) {
+    delete display_base;
+    return error;
+  }
+
+  *intf = display_base;
+
+  return kErrorNone;
+}
+
 DisplayError CoreImpl::DestroyDisplay(DisplayInterface *intf) {
   SCOPE_LOCK(locker_);
 
@@ -177,8 +235,24 @@
 }
 
 DisplayError CoreImpl::GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) {
+  SCOPE_LOCK(locker_);
   return hw_info_intf_->GetFirstDisplayInterfaceType(hw_disp_info);
 }
 
+DisplayError CoreImpl::GetDisplaysStatus(HWDisplaysInfo *hw_displays_info) {
+  SCOPE_LOCK(locker_);
+  DisplayError error = hw_info_intf_->GetDisplaysStatus(hw_displays_info);
+  if (kErrorNone == error) {
+    // Needed for error-checking in CreateDisplay(int32_t display_id, ...) and getting display-type.
+    hw_displays_info_ = *hw_displays_info;
+  }
+  return error;
+}
+
+DisplayError CoreImpl::GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays) {
+  SCOPE_LOCK(locker_);
+  return hw_info_intf_->GetMaxDisplaysSupported(type, max_displays);
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/core_impl.h b/sdm/libs/core/core_impl.h
index 2647c78..94e61d7 100644
--- a/sdm/libs/core/core_impl.h
+++ b/sdm/libs/core/core_impl.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, 2018 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:
@@ -55,9 +55,13 @@
   // Methods from core interface
   virtual DisplayError CreateDisplay(DisplayType type, DisplayEventHandler *event_handler,
                                      DisplayInterface **intf);
+  virtual DisplayError CreateDisplay(int32_t display_id, DisplayEventHandler *event_handler,
+                                     DisplayInterface **intf);
   virtual DisplayError DestroyDisplay(DisplayInterface *intf);
   virtual DisplayError SetMaxBandwidthMode(HWBwModes mode);
   virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
+  virtual DisplayError GetDisplaysStatus(HWDisplaysInfo *hw_displays_info);
+  virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays);
 
  protected:
   Locker locker_;
@@ -71,6 +75,7 @@
   CreateExtensionInterface create_extension_intf_ = NULL;
   DestroyExtensionInterface destroy_extension_intf_ = NULL;
   SocketHandler *socket_handler_ = NULL;
+  HWDisplaysInfo hw_displays_info_ = {};
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 5b61523..b567cc8 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -73,6 +73,19 @@
     comp_manager_(comp_manager), hw_info_intf_(hw_info_intf) {
 }
 
+DisplayBase::DisplayBase(int32_t display_id, DisplayType display_type,
+                         DisplayEventHandler *event_handler, HWDeviceType hw_device_type,
+                         BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                         CompManager *comp_manager, HWInfoInterface *hw_info_intf)
+  : display_id_(display_id),
+    display_type_(display_type),
+    event_handler_(event_handler),
+    hw_device_type_(hw_device_type),
+    buffer_sync_handler_(buffer_sync_handler),
+    buffer_allocator_(buffer_allocator),
+    comp_manager_(comp_manager),
+    hw_info_intf_(hw_info_intf) {}
+
 DisplayError DisplayBase::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
@@ -107,17 +120,23 @@
     }
   }
 
-  color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
-                                                          display_attributes_, hw_panel_info_);
+  if (!color_mgr_exists_) {
+    color_mgr_ = ColorManagerProxy::CreateColorManagerProxy(display_type_, hw_intf_,
+                                                            display_attributes_, hw_panel_info_);
 
-  if (!color_mgr_) {
-    DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
-  } else if (InitializeColorModes() != kErrorNone) {
-    DLOGW("InitColorModes failed for display = %d", display_type_);
+    if (!color_mgr_) {
+      DLOGW("Unable to create ColorManagerProxy for display = %d", display_type_);
+    } else {
+      color_mgr_exists_ = true;
+      if (InitializeColorModes() != kErrorNone) {
+        DLOGW("InitColorModes failed for display = %d", display_type_);
+      }
+    }
   }
 
-  error = comp_manager_->RegisterDisplay(display_type_, display_attributes_, hw_panel_info_,
-                                         mixer_attributes_, fb_config_, &display_comp_ctx_);
+  error = comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes_,
+                                         hw_panel_info_, mixer_attributes_, fb_config_,
+                                         &display_comp_ctx_);
   if (error != kErrorNone) {
     goto CleanupOnError;
   }
@@ -194,9 +213,10 @@
     }
   }
 
-  DLOGD_IF(kTagDisplay, "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, "
-           "display type: %d", layers.size(), hw_layers_info.app_layer_count,
-           hw_layers_info.gpu_target_index, display_type_);
+  DLOGD_IF(kTagDisplay,
+           "LayerStack layer_count: %d, app_layer_count: %d, gpu_target_index: %d, display: %d-%d",
+           layers.size(), hw_layers_info.app_layer_count, hw_layers_info.gpu_target_index,
+           display_id_, display_type_);
 
   if (!hw_layers_info.app_layer_count) {
     DLOGW("Layer count is zero");
@@ -263,7 +283,7 @@
     return kErrorParameters;
   }
 
-  DLOGI_IF(kTagDisplay, "Entering Prepare for display type : %d", display_type_);
+  DLOGI_IF(kTagDisplay, "Entering Prepare for display: %d-%d", display_id_, display_type_);
   error = BuildLayerStackStats(layer_stack);
   if (error != kErrorNone) {
     return error;
@@ -316,7 +336,7 @@
     DLOGW("ValidateHDR failed");
   }
 
-  DLOGI_IF(kTagDisplay, "Exiting Prepare for display type : %d", display_type_);
+  DLOGI_IF(kTagDisplay, "Exiting Prepare for display: %d-%d", display_id_, display_type_);
   return error;
 }
 
@@ -334,7 +354,8 @@
   }
 
   if (needs_validate_) {
-    DLOGE("Commit: Corresponding Prepare() is not called for display = %d", display_type_);
+    DLOGE("Commit: Corresponding Prepare() is not called for display %d-%d", display_id_,
+          display_type_);
     return kErrorNotValidated;
   }
 
@@ -351,7 +372,7 @@
     }
   }
 
-  DLOGI_IF(kTagDisplay, "Entering commit for display type : %d", display_type_);
+  DLOGI_IF(kTagDisplay, "Entering commit for display: %d-%d", display_id_, display_type_);
   CommitLayerParams(layer_stack);
 
   error = comp_manager_->Commit(display_comp_ctx_, &hw_layers_);
@@ -383,7 +404,7 @@
     return error;
   }
 
-  DLOGI_IF(kTagDisplay, "Exiting commit for display type : %d", display_type_);
+  DLOGI_IF(kTagDisplay, "Exiting commit for display: %d-%d", display_id_, display_type_);
   return kErrorNone;
 }
 
@@ -400,7 +421,7 @@
     comp_manager_->Purge(display_comp_ctx_);
     needs_validate_ = true;
   } else {
-    DLOGW("Unable to flush display = %d", display_type_);
+    DLOGW("Unable to flush display %d-%d", display_id_, display_type_);
   }
 
   return error;
@@ -481,7 +502,7 @@
   DisplayError error = kErrorNone;
   bool active = false;
 
-  DLOGI("Set state = %d, display %d", state, display_type_);
+  DLOGI("Set state = %d, display %d-%d", state, display_id_, display_type_);
 
   if (state == state_) {
     DLOGI("Same state transition is requested.");
@@ -529,7 +550,7 @@
       return kErrorNone;
     }
     error = hw_intf_->DozeSuspend(release_fence);
-    if (display_type_ != kPrimary) {
+    if (display_type_ != kBuiltIn) {
       active = true;
     }
     last_power_mode_ = kStateDozeSuspend;
@@ -550,7 +571,7 @@
   if (error == kErrorNone) {
     active_ = active;
     state_ = state;
-    comp_manager_->SetDisplayState(display_comp_ctx_, state, display_type_);
+    comp_manager_->SetDisplayState(display_comp_ctx_, state);
   }
 
   return error;
@@ -1381,6 +1402,30 @@
   return kErrorNone;
 }
 
+DisplayError DisplayBase::GetDisplayId(int32_t *display_id) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+  if (!display_id) {
+    return kErrorParameters;
+  }
+
+  *display_id = display_id_;
+
+  return kErrorNone;
+}
+
+DisplayError DisplayBase::GetDisplayType(DisplayType *display_type) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+  if (!display_type) {
+    return kErrorParameters;
+  }
+
+  *display_type = display_type_;
+
+  return kErrorNone;
+}
+
 bool DisplayBase::IsPrimaryDisplay() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
@@ -1731,6 +1776,8 @@
                                 mixer_height != display_height);
 }
 
+bool DisplayBase::color_mgr_exists_ = false;
+
 void DisplayBase::ClearColorInfo() {
   color_modes_.clear();
   color_mode_map_.clear();
@@ -1740,6 +1787,7 @@
   if (color_mgr_) {
     delete color_mgr_;
     color_mgr_ = NULL;
+    color_mgr_exists_ = false;
   }
 }
 
@@ -1764,7 +1812,7 @@
 }
 
 bool DisplayBase::NeedsHdrHandling() {
-  if (display_type_ != kPrimary || !num_color_modes_ || gpu_fallback_) {
+  if (display_type_ != kBuiltIn || !num_color_modes_ || gpu_fallback_) {
     // No HDR Handling for non-primary displays or when color modes are not present or
     // if frame is falling back to GPU
     return false;
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 63504d2..65c3bc7 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -50,6 +50,10 @@
               HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
               BufferAllocator *buffer_allocator, CompManager *comp_manager,
               HWInfoInterface *hw_info_intf);
+  DisplayBase(int32_t display_id, DisplayType display_type, DisplayEventHandler *event_handler,
+              HWDeviceType hw_device_type, BufferSyncHandler *buffer_sync_handler,
+              BufferAllocator *buffer_allocator, CompManager *comp_manager,
+              HWInfoInterface *hw_info_intf);
   virtual ~DisplayBase() { }
   virtual DisplayError Init();
   virtual DisplayError Deinit();
@@ -110,6 +114,8 @@
   virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
   virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data);
   virtual DisplayError GetDisplayPort(DisplayPort *port);
+  virtual DisplayError GetDisplayId(int32_t *display_id);
+  virtual DisplayError GetDisplayType(DisplayType *display_type);
   virtual bool IsPrimaryDisplay();
   virtual DisplayError SetCompositionState(LayerComposition composition_type, bool enable);
   virtual DisplayError GetClientTargetSupport(uint32_t width, uint32_t height,
@@ -157,6 +163,7 @@
   bool SetHdrModeAtStart(LayerStack *layer_stack);
 
   recursive_mutex recursive_mutex_;
+  int32_t display_id_ = -1;
   DisplayType display_type_;
   DisplayEventHandler *event_handler_ = NULL;
   HWDeviceType hw_device_type_;
@@ -176,6 +183,8 @@
   uint32_t max_mixer_stages_ = 0;
   HWInfoInterface *hw_info_intf_ = NULL;
   ColorManagerProxy *color_mgr_ = NULL;  // each display object owns its ColorManagerProxy
+  // TODO(user): ColorManager supported only on a single built-in display.
+  static bool color_mgr_exists_;
   bool partial_update_control_ = true;
   HWEventsInterface *hw_events_intf_ = NULL;
   bool disable_pu_one_frame_ = false;
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_builtin.cpp
similarity index 71%
rename from sdm/libs/core/display_primary.cpp
rename to sdm/libs/core/display_builtin.cpp
index 9ec34aa..e666b13 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -27,37 +27,47 @@
 #include <utils/rect.h>
 #include <utils/utils.h>
 
-#include <map>
 #include <algorithm>
 #include <functional>
-#include <vector>
+#include <map>
 #include <string>
+#include <vector>
 
-#include "display_primary.h"
-#include "hw_interface.h"
+#include "display_builtin.h"
 #include "hw_info_interface.h"
+#include "hw_interface.h"
 
-#define __CLASS__ "DisplayPrimary"
+#define __CLASS__ "DisplayBuiltIn"
 
 namespace sdm {
 
-DisplayPrimary::DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+DisplayBuiltIn::DisplayBuiltIn(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
                                BufferSyncHandler *buffer_sync_handler,
                                BufferAllocator *buffer_allocator, CompManager *comp_manager)
-  : DisplayBase(kPrimary, event_handler, kDevicePrimary, buffer_sync_handler, buffer_allocator,
-                comp_manager, hw_info_intf) {
-}
+  : DisplayBase(kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler, buffer_allocator,
+                comp_manager, hw_info_intf) {}
 
-DisplayError DisplayPrimary::Init() {
+DisplayBuiltIn::DisplayBuiltIn(int32_t display_id, DisplayEventHandler *event_handler,
+                               HWInfoInterface *hw_info_intf,
+                               BufferSyncHandler *buffer_sync_handler,
+                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
+  : DisplayBase(display_id, kBuiltIn, event_handler, kDeviceBuiltIn, buffer_sync_handler,
+                buffer_allocator, comp_manager, hw_info_intf) {}
+
+DisplayError DisplayBuiltIn::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
-  DisplayError error = HWInterface::Create(kPrimary, hw_info_intf_, buffer_sync_handler_,
-                                           buffer_allocator_, &hw_intf_);
+  DisplayError error = HWInterface::Create(display_id_, kBuiltIn, hw_info_intf_,
+                                           buffer_sync_handler_, buffer_allocator_, &hw_intf_);
   if (error != kErrorNone) {
     DLOGE("Failed to create hardware interface on. Error = %d", error);
     return error;
   }
 
+  if (-1 == display_id_) {
+    hw_intf_->GetDisplayId(&display_id_);
+  }
+
   error = DisplayBase::Init();
   if (error != kErrorNone) {
     HWInterface::Destroy(hw_intf_);
@@ -73,28 +83,24 @@
   }
 
   if (hw_panel_info_.mode == kModeCommand) {
-    event_list_ = { HWEvent::VSYNC,
-                    HWEvent::EXIT,
-                    HWEvent::SHOW_BLANK_EVENT,
-                    HWEvent::THERMAL_LEVEL,
-                    HWEvent::IDLE_POWER_COLLAPSE,
-                    HWEvent::PINGPONG_TIMEOUT,
-                    HWEvent::PANEL_DEAD,
-                    HWEvent::HW_RECOVERY };
+    event_list_ = {HWEvent::VSYNC,
+                   HWEvent::EXIT,
+                   HWEvent::SHOW_BLANK_EVENT,
+                   HWEvent::THERMAL_LEVEL,
+                   HWEvent::IDLE_POWER_COLLAPSE,
+                   HWEvent::PINGPONG_TIMEOUT,
+                   HWEvent::PANEL_DEAD,
+                   HWEvent::HW_RECOVERY};
   } else {
-    event_list_ = { HWEvent::VSYNC,
-                    HWEvent::EXIT,
-                    HWEvent::IDLE_NOTIFY,
-                    HWEvent::SHOW_BLANK_EVENT,
-                    HWEvent::THERMAL_LEVEL,
-                    HWEvent::PINGPONG_TIMEOUT,
-                    HWEvent::PANEL_DEAD,
-                    HWEvent::HW_RECOVERY };
+    event_list_ = {HWEvent::VSYNC,         HWEvent::EXIT,
+                   HWEvent::IDLE_NOTIFY,   HWEvent::SHOW_BLANK_EVENT,
+                   HWEvent::THERMAL_LEVEL, HWEvent::PINGPONG_TIMEOUT,
+                   HWEvent::PANEL_DEAD,    HWEvent::HW_RECOVERY};
   }
 
   avr_prop_disabled_ = Debug::IsAVRDisabled();
 
-  error = HWEventsInterface::Create(INT(display_type_), this, event_list_, hw_intf_,
+  error = HWEventsInterface::Create(display_id_, kBuiltIn, this, event_list_, hw_intf_,
                                     &hw_events_intf_);
   if (error != kErrorNone) {
     DisplayBase::Deinit();
@@ -107,14 +113,14 @@
   return error;
 }
 
-DisplayError DisplayPrimary::Deinit() {
+DisplayError DisplayBuiltIn::Deinit() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
   dpps_info_.Deinit();
   return DisplayBase::Deinit();
 }
 
-DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
+DisplayError DisplayBuiltIn::Prepare(LayerStack *layer_stack) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   uint32_t new_mixer_width = 0;
@@ -142,7 +148,7 @@
   return DisplayBase::Prepare(layer_stack);
 }
 
-DisplayError DisplayPrimary::Commit(LayerStack *layer_stack) {
+DisplayError DisplayBuiltIn::Commit(LayerStack *layer_stack) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   uint32_t app_layer_count = hw_layers_.info.app_layer_count;
@@ -164,8 +170,7 @@
   }
 
   if (commit_event_enabled_) {
-    dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_,
-                                            sizeof(display_type_));
+    dpps_info_.DppsNotifyOps(kDppsCommitEvent, &display_type_, sizeof(display_type_));
   }
 
   DisplayBase::ReconfigureDisplay();
@@ -186,7 +191,7 @@
   return error;
 }
 
-DisplayError DisplayPrimary::SetDisplayState(DisplayState state, int *release_fence) {
+DisplayError DisplayBuiltIn::SetDisplayState(DisplayState state, int *release_fence) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   error = DisplayBase::SetDisplayState(state, release_fence);
@@ -202,12 +207,12 @@
   return kErrorNone;
 }
 
-void DisplayPrimary::SetIdleTimeoutMs(uint32_t active_ms) {
+void DisplayBuiltIn::SetIdleTimeoutMs(uint32_t active_ms) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms);
 }
 
-DisplayError DisplayPrimary::SetDisplayMode(uint32_t mode) {
+DisplayError DisplayBuiltIn::SetDisplayMode(uint32_t mode) {
   DisplayError error = kErrorNone;
 
   // Limit scope of mutex to this block
@@ -255,12 +260,12 @@
   return error;
 }
 
-DisplayError DisplayPrimary::SetPanelBrightness(int level) {
+DisplayError DisplayBuiltIn::SetPanelBrightness(int level) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   return hw_intf_->SetPanelBrightness(level);
 }
 
-DisplayError DisplayPrimary::GetRefreshRateRange(uint32_t *min_refresh_rate,
+DisplayError DisplayBuiltIn::GetRefreshRateRange(uint32_t *min_refresh_rate,
                                                  uint32_t *max_refresh_rate) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
@@ -275,7 +280,7 @@
   return error;
 }
 
-DisplayError DisplayPrimary::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayBuiltIn::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
   if (!active_ || !hw_panel_info_.dynamic_fps) {
@@ -305,7 +310,7 @@
   return DisplayBase::ReconfigureDisplay();
 }
 
-DisplayError DisplayPrimary::VSync(int64_t timestamp) {
+DisplayError DisplayBuiltIn::VSync(int64_t timestamp) {
   if (vsync_enable_) {
     DisplayEventVSync vsync;
     vsync.timestamp = timestamp;
@@ -315,7 +320,7 @@
   return kErrorNone;
 }
 
-void DisplayPrimary::IdleTimeout() {
+void DisplayBuiltIn::IdleTimeout() {
   if (hw_panel_info_.mode == kModeVideo) {
     event_handler_->HandleEvent(kIdleTimeout);
     handle_idle_timeout_ = true;
@@ -325,18 +330,18 @@
   }
 }
 
-void DisplayPrimary::PingPongTimeout() {
+void DisplayBuiltIn::PingPongTimeout() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   hw_intf_->DumpDebugData();
 }
 
-void DisplayPrimary::ThermalEvent(int64_t thermal_level) {
+void DisplayBuiltIn::ThermalEvent(int64_t thermal_level) {
   event_handler_->HandleEvent(kThermalEvent);
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   comp_manager_->ProcessThermalEvent(display_comp_ctx_, thermal_level);
 }
 
-void DisplayPrimary::IdlePowerCollapse() {
+void DisplayBuiltIn::IdlePowerCollapse() {
   if (hw_panel_info_.mode == kModeCommand) {
     event_handler_->HandleEvent(kIdlePowerCollapse);
     lock_guard<recursive_mutex> obj(recursive_mutex_);
@@ -344,7 +349,7 @@
   }
 }
 
-void DisplayPrimary::PanelDead() {
+void DisplayBuiltIn::PanelDead() {
   event_handler_->HandleEvent(kPanelDeadEvent);
   event_handler_->Refresh();
   {
@@ -354,16 +359,16 @@
 }
 
 // HWEventHandler overload, not DisplayBase
-void DisplayPrimary::HwRecovery(const HWRecoveryEvent sdm_event_code) {
+void DisplayBuiltIn::HwRecovery(const HWRecoveryEvent sdm_event_code) {
   DisplayBase::HwRecovery(sdm_event_code);
 }
 
-DisplayError DisplayPrimary::GetPanelBrightness(int *level) {
+DisplayError DisplayBuiltIn::GetPanelBrightness(int *level) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   return hw_intf_->GetPanelBrightness(level);
 }
 
-DisplayError DisplayPrimary::ControlPartialUpdate(bool enable, uint32_t *pending) {
+DisplayError DisplayBuiltIn::ControlPartialUpdate(bool enable, uint32_t *pending) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   if (!pending) {
     return kErrorParameters;
@@ -371,7 +376,7 @@
 
   if (!hw_panel_info_.partial_update) {
     // Nothing to be done.
-    DLOGI("partial update is not applicable for display=%d", display_type_);
+    DLOGI("partial update is not applicable for display id = %d", display_id_);
     return kErrorNotSupported;
   }
 
@@ -392,14 +397,14 @@
   return kErrorNone;
 }
 
-DisplayError DisplayPrimary::DisablePartialUpdateOneFrame() {
+DisplayError DisplayBuiltIn::DisablePartialUpdateOneFrame() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   disable_pu_one_frame_ = true;
 
   return kErrorNone;
 }
 
-bool DisplayPrimary::NeedsAVREnable() {
+bool DisplayBuiltIn::NeedsAVREnable() {
   if (avr_prop_disabled_ || qsync_mode_ == kQSyncModeNone) {
     return false;
   }
@@ -408,29 +413,30 @@
     return hw_panel_info_.qsync_support;
   }
 
-  return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
-          hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
-          hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
+  return (hw_panel_info_.mode == kModeVideo &&
+          ((hw_panel_info_.dynamic_fps && hw_panel_info_.dfps_porch_mode) ||
+           (!hw_panel_info_.dynamic_fps && hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
 }
 
-void DisplayPrimary::ResetPanel() {
+void DisplayBuiltIn::ResetPanel() {
   DisplayError status = kErrorNone;
   int release_fence = -1;
 
-  DLOGI("Powering off primary");
+  DLOGI("Powering off built-in/primary %d", display_id_);
   status = SetDisplayState(kStateOff, &release_fence);
   if (status != kErrorNone) {
-    DLOGE("power-off on primary failed with error = %d", status);
+    DLOGE("power-off on built-in/primary %d failed with error = %d", display_id_, status);
   }
   if (release_fence >= 0) {
     ::close(release_fence);
   }
 
-  DLOGI("Restoring power mode on primary");
+  DLOGI("Restoring power mode on built-in/primary %d", display_id_);
   DisplayState mode = GetLastPowerMode();
   status = SetDisplayState(mode, &release_fence);
   if (status != kErrorNone) {
-    DLOGE("Setting power mode = %d on primary failed with error = %d", mode, status);
+    DLOGE("Setting power mode = %d on built-in/primary %d failed with error = %d", mode,
+          display_id_, status);
   }
   if (release_fence >= 0) {
     ::close(release_fence);
@@ -439,61 +445,61 @@
   DLOGI("Enabling HWVsync");
   status = SetVSyncState(true);
   if (status != kErrorNone) {
-    DLOGE("enabling vsync failed for primary with error = %d", status);
+    DLOGE("enabling vsync failed for built-in/primary %d with error = %d", display_id_, status);
   }
 }
 
-DisplayError DisplayPrimary::DppsProcessOps(enum DppsOps op, void *payload, size_t size) {
+DisplayError DisplayBuiltIn::DppsProcessOps(enum DppsOps op, void *payload, size_t size) {
   DisplayError error = kErrorNone;
   uint32_t pending;
   bool enable = false;
 
   switch (op) {
-  case kDppsSetFeature:
-    if (!payload) {
-      DLOGE("Invalid payload parameter for op %d", op);
+    case kDppsSetFeature:
+      if (!payload) {
+        DLOGE("Invalid payload parameter for op %d", op);
+        error = kErrorParameters;
+        break;
+      }
+      error = hw_intf_->SetDppsFeature(payload, size);
+      break;
+    case kDppsGetFeatureInfo:
+      if (!payload) {
+        DLOGE("Invalid payload parameter for op %d", op);
+        error = kErrorParameters;
+        break;
+      }
+      error = hw_intf_->GetDppsFeatureInfo(payload, size);
+      break;
+    case kDppsScreenRefresh:
+      event_handler_->Refresh();
+      break;
+    case kDppsPartialUpdate:
+      if (!payload) {
+        DLOGE("Invalid payload parameter for op %d", op);
+        error = kErrorParameters;
+        break;
+      }
+      enable = *(reinterpret_cast<bool *>(payload));
+      ControlPartialUpdate(enable, &pending);
+      break;
+    case kDppsRequestCommit:
+      if (!payload) {
+        DLOGE("Invalid payload parameter for op %d", op);
+        error = kErrorParameters;
+        break;
+      }
+      commit_event_enabled_ = *(reinterpret_cast<bool *>(payload));
+      break;
+    default:
+      DLOGE("Invalid input op %d", op);
       error = kErrorParameters;
       break;
-    }
-    error = hw_intf_->SetDppsFeature(payload, size);
-    break;
-  case kDppsGetFeatureInfo:
-    if (!payload) {
-      DLOGE("Invalid payload parameter for op %d", op);
-      error = kErrorParameters;
-      break;
-    }
-    error = hw_intf_->GetDppsFeatureInfo(payload, size);
-    break;
-  case kDppsScreenRefresh:
-    event_handler_->Refresh();
-    break;
-  case kDppsPartialUpdate:
-    if (!payload) {
-      DLOGE("Invalid payload parameter for op %d", op);
-      error = kErrorParameters;
-      break;
-    }
-    enable = *(reinterpret_cast<bool *>(payload));
-    ControlPartialUpdate(enable, &pending);
-    break;
-  case kDppsRequestCommit:
-    if (!payload) {
-      DLOGE("Invalid payload parameter for op %d", op);
-      error = kErrorParameters;
-      break;
-    }
-    commit_event_enabled_ = *(reinterpret_cast<bool *>(payload));
-    break;
-  default:
-    DLOGE("Invalid input op %d", op);
-    error = kErrorParameters;
-    break;
   }
   return error;
 }
 
-void DppsInfo::Init(DppsPropIntf* intf, const std::string &panel_name) {
+void DppsInfo::Init(DppsPropIntf *intf, const std::string &panel_name) {
   int error = 0;
 
   if (dpps_initialized_) {
@@ -505,8 +511,7 @@
     goto exit;
   }
 
-  if (!dpps_impl_lib.Sym("GetDppsInterface",
-         reinterpret_cast<void **>(&GetDppsInterface))) {
+  if (!dpps_impl_lib.Sym("GetDppsInterface", reinterpret_cast<void **>(&GetDppsInterface))) {
     DLOGE("GetDppsInterface not found!, err %s", dlerror());
     goto exit;
   }
@@ -547,11 +552,11 @@
     DLOGE("DppsNotifyOps op %d error %d", op, ret);
 }
 
-DisplayError DisplayPrimary::HandleSecureEvent(SecureEvent secure_event) {
+DisplayError DisplayBuiltIn::HandleSecureEvent(SecureEvent secure_event) {
   return hw_intf_->HandleSecureEvent(secure_event);
 }
 
-DisplayError DisplayPrimary::SetQSyncMode(QSyncMode qsync_mode) {
+DisplayError DisplayBuiltIn::SetQSyncMode(QSyncMode qsync_mode) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   if (GetDriverType() == DriverType::DRM && qsync_mode == kQsyncModeOneShot) {
     return kErrorNotSupported;
@@ -562,4 +567,3 @@
 }
 
 }  // namespace sdm
-
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_builtin.h
similarity index 85%
rename from sdm/libs/core/display_primary.h
rename to sdm/libs/core/display_builtin.h
index 058e1a2..f1de42a 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_builtin.h
@@ -22,39 +22,40 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef __DISPLAY_PRIMARY_H__
-#define __DISPLAY_PRIMARY_H__
+#ifndef __DISPLAY_BUILTIN_H__
+#define __DISPLAY_BUILTIN_H__
 
 #include <core/dpps_interface.h>
-#include <vector>
 #include <string>
+#include <vector>
 
 #include "display_base.h"
 #include "hw_events_interface.h"
 
 namespace sdm {
 
-class HWPrimaryInterface;
-
 class DppsInfo {
  public:
-  void Init(DppsPropIntf* intf, const std::string &panel_name);
+  void Init(DppsPropIntf *intf, const std::string &panel_name);
   void Deinit();
   void DppsNotifyOps(enum DppsNotifyOps op, void *payload, size_t size);
 
  private:
   const char *kDppsLib = "libdpps.so";
   DynLib dpps_impl_lib;
-  DppsInterface* dpps_intf = NULL;
-  DppsInterface* (*GetDppsInterface)() = NULL;
+  DppsInterface *dpps_intf = NULL;
+  DppsInterface *(*GetDppsInterface)() = NULL;
   bool dpps_initialized_ = false;
 };
 
-class DisplayPrimary : public DisplayBase, HWEventHandler, DppsPropIntf {
+class DisplayBuiltIn : public DisplayBase, HWEventHandler, DppsPropIntf {
  public:
-  DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+  DisplayBuiltIn(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
                  BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
                  CompManager *comp_manager);
+  DisplayBuiltIn(int32_t display_id, DisplayEventHandler *event_handler,
+                 HWInfoInterface *hw_info_intf, BufferSyncHandler *buffer_sync_handler,
+                 BufferAllocator *buffer_allocator, CompManager *comp_manager);
   virtual DisplayError Init();
   virtual DisplayError Deinit();
   virtual DisplayError Prepare(LayerStack *layer_stack);
@@ -76,7 +77,7 @@
   virtual DisplayError Blank(bool blank) { return kErrorNone; }
   virtual void IdleTimeout();
   virtual void ThermalEvent(int64_t thermal_level);
-  virtual void CECMessage(char *message) { }
+  virtual void CECMessage(char *message) {}
   virtual void IdlePowerCollapse();
   virtual void PingPongTimeout();
   virtual void PanelDead();
@@ -102,5 +103,4 @@
 
 }  // namespace sdm
 
-#endif  // __DISPLAY_PRIMARY_H__
-
+#endif  // __DISPLAY_BUILTIN_H__
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_pluggable.cpp
similarity index 74%
rename from sdm/libs/core/display_hdmi.cpp
rename to sdm/libs/core/display_pluggable.cpp
index 3165f73..524d7c1 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_pluggable.cpp
@@ -28,31 +28,42 @@
 #include <utility>
 #include <vector>
 
-#include "display_hdmi.h"
-#include "hw_interface.h"
+#include "display_pluggable.h"
 #include "hw_info_interface.h"
+#include "hw_interface.h"
 
-#define __CLASS__ "DisplayHDMI"
+#define __CLASS__ "DisplayPluggable"
 
 namespace sdm {
 
-DisplayHDMI::DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-                         BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                         CompManager *comp_manager)
-  : DisplayBase(kHDMI, event_handler, kDeviceHDMI, buffer_sync_handler, buffer_allocator,
-                comp_manager, hw_info_intf) {
-}
+DisplayPluggable::DisplayPluggable(DisplayEventHandler *event_handler,
+                                   HWInfoInterface *hw_info_intf,
+                                   BufferSyncHandler *buffer_sync_handler,
+                                   BufferAllocator *buffer_allocator, CompManager *comp_manager)
+  : DisplayBase(kPluggable, event_handler, kDevicePluggable, buffer_sync_handler, buffer_allocator,
+                comp_manager, hw_info_intf) {}
 
-DisplayError DisplayHDMI::Init() {
+DisplayPluggable::DisplayPluggable(int32_t display_id, DisplayEventHandler *event_handler,
+                                   HWInfoInterface *hw_info_intf,
+                                   BufferSyncHandler *buffer_sync_handler,
+                                   BufferAllocator *buffer_allocator, CompManager *comp_manager)
+  : DisplayBase(display_id, kPluggable, event_handler, kDevicePluggable, buffer_sync_handler,
+                buffer_allocator, comp_manager, hw_info_intf) {}
+
+DisplayError DisplayPluggable::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
-  DisplayError error = HWInterface::Create(kHDMI, hw_info_intf_, buffer_sync_handler_,
-                                           buffer_allocator_, &hw_intf_);
+  DisplayError error = HWInterface::Create(display_id_, kPluggable, hw_info_intf_,
+                                           buffer_sync_handler_, buffer_allocator_, &hw_intf_);
   if (error != kErrorNone) {
     DLOGE("Failed to create hardware interface. Error = %d", error);
     return error;
   }
 
+  if (-1 == display_id_) {
+    hw_intf_->GetDisplayId(&display_id_);
+  }
+
   uint32_t active_mode_index;
   char value[64] = "0";
   Debug::GetProperty(HDMI_S3D_MODE_PROP, value);
@@ -78,18 +89,18 @@
   GetScanSupport();
   underscan_supported_ = (scan_support_ == kScanAlwaysUnderscanned) || (scan_support_ == kScanBoth);
 
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatNone, kS3DModeNone));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatLeftRight, kS3DModeLR));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatRightLeft, kS3DModeRL));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatTopBottom, kS3DModeTB));
-  s3d_format_to_mode_.insert(std::pair<LayerBufferS3DFormat, HWS3DMode>
-                            (kS3dFormatFramePacking, kS3DModeFP));
+  s3d_format_to_mode_.insert(
+      std::pair<LayerBufferS3DFormat, HWS3DMode>(kS3dFormatNone, kS3DModeNone));
+  s3d_format_to_mode_.insert(
+      std::pair<LayerBufferS3DFormat, HWS3DMode>(kS3dFormatLeftRight, kS3DModeLR));
+  s3d_format_to_mode_.insert(
+      std::pair<LayerBufferS3DFormat, HWS3DMode>(kS3dFormatRightLeft, kS3DModeRL));
+  s3d_format_to_mode_.insert(
+      std::pair<LayerBufferS3DFormat, HWS3DMode>(kS3dFormatTopBottom, kS3DModeTB));
+  s3d_format_to_mode_.insert(
+      std::pair<LayerBufferS3DFormat, HWS3DMode>(kS3dFormatFramePacking, kS3DModeFP));
 
-  error = HWEventsInterface::Create(INT(display_type_), this, event_list_, hw_intf_,
+  error = HWEventsInterface::Create(display_id_, kPluggable, this, event_list_, hw_intf_,
                                     &hw_events_intf_);
   if (error != kErrorNone) {
     DisplayBase::Deinit();
@@ -104,7 +115,7 @@
   return error;
 }
 
-DisplayError DisplayHDMI::Prepare(LayerStack *layer_stack) {
+DisplayError DisplayPluggable::Prepare(LayerStack *layer_stack) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   uint32_t new_mixer_width = 0;
@@ -127,8 +138,8 @@
   return DisplayBase::Prepare(layer_stack);
 }
 
-DisplayError DisplayHDMI::GetRefreshRateRange(uint32_t *min_refresh_rate,
-                                              uint32_t *max_refresh_rate) {
+DisplayError DisplayPluggable::GetRefreshRateRange(uint32_t *min_refresh_rate,
+                                                   uint32_t *max_refresh_rate) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
 
@@ -142,7 +153,7 @@
   return error;
 }
 
-DisplayError DisplayHDMI::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
+DisplayError DisplayPluggable::SetRefreshRate(uint32_t refresh_rate, bool final_rate) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
   if (!active_) {
@@ -160,17 +171,17 @@
   return DisplayBase::ReconfigureDisplay();
 }
 
-bool DisplayHDMI::IsUnderscanSupported() {
+bool DisplayPluggable::IsUnderscanSupported() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   return underscan_supported_;
 }
 
-DisplayError DisplayHDMI::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
+DisplayError DisplayPluggable::OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   return hw_intf_->OnMinHdcpEncryptionLevelChange(min_enc_level);
 }
 
-uint32_t DisplayHDMI::GetBestConfig(HWS3DMode s3d_mode) {
+uint32_t DisplayPluggable::GetBestConfig(HWS3DMode s3d_mode) {
   uint32_t best_index = 0, index;
   uint32_t num_modes = 0;
 
@@ -183,7 +194,7 @@
   }
 
   // Select best config for s3d_mode. If s3d is not enabled, s3d_mode is kS3DModeNone
-  for (index = 0; index < num_modes; index ++) {
+  for (index = 0; index < num_modes; index++) {
     if (attrib[index].s3d_config[s3d_mode]) {
       break;
     }
@@ -191,7 +202,7 @@
 
   index = 0;
   best_index = UINT32(index);
-  for (size_t index = best_index + 1; index < num_modes; index ++) {
+  for (size_t index = best_index + 1; index < num_modes; index++) {
     // TODO(user): Need to add support to S3D modes
     // From the available configs, select the best
     // Ex: 1920x1080@60Hz is better than 1920x1080@30 and 1920x1080@30 is better than 1280x720@60
@@ -207,7 +218,7 @@
       }
     }
   }
-  char val[kPropertyMax]={};
+  char val[kPropertyMax] = {};
   // Used for changing HDMI Resolution - override the best with user set config
   bool user_config = (Debug::GetExternalResolution(val));
 
@@ -222,7 +233,7 @@
   return best_index;
 }
 
-void DisplayHDMI::GetScanSupport() {
+void DisplayPluggable::GetScanSupport() {
   DisplayError error = kErrorNone;
   uint32_t video_format = 0;
   uint32_t max_cea_format = 0;
@@ -255,7 +266,7 @@
   }
 }
 
-void DisplayHDMI::SetS3DMode(LayerStack *layer_stack) {
+void DisplayPluggable::SetS3DMode(LayerStack *layer_stack) {
   uint32_t s3d_layer_count = 0;
   HWS3DMode s3d_mode = kS3DModeNone;
   uint32_t layer_count = UINT32(layer_stack->layers.size());
@@ -275,13 +286,13 @@
       }
 
       std::map<LayerBufferS3DFormat, HWS3DMode>::iterator it =
-                s3d_format_to_mode_.find(layer_buffer.s3d_format);
+          s3d_format_to_mode_.find(layer_buffer.s3d_format);
       if (it != s3d_format_to_mode_.end()) {
         s3d_mode = it->second;
       }
     } else if (layer_buffer.flags.secure && layer_count > 2) {
-        s3d_mode = kS3DModeNone;
-        break;
+      s3d_mode = kS3DModeNone;
+      break;
     }
   }
 
@@ -295,16 +306,16 @@
   DisplayBase::ReconfigureDisplay();
 }
 
-void DisplayHDMI::CECMessage(char *message) {
+void DisplayPluggable::CECMessage(char *message) {
   event_handler_->CECMessage(message);
 }
 
 // HWEventHandler overload, not DisplayBase
-void DisplayHDMI::HwRecovery(const HWRecoveryEvent sdm_event_code) {
+void DisplayPluggable::HwRecovery(const HWRecoveryEvent sdm_event_code) {
   DisplayBase::HwRecovery(sdm_event_code);
 }
 
-DisplayError DisplayHDMI::VSync(int64_t timestamp) {
+DisplayError DisplayPluggable::VSync(int64_t timestamp) {
   if (vsync_enable_) {
     DisplayEventVSync vsync;
     vsync.timestamp = timestamp;
@@ -314,7 +325,7 @@
   return kErrorNone;
 }
 
-DisplayError DisplayHDMI::InitializeColorModes() {
+DisplayError DisplayPluggable::InitializeColorModes() {
   PrimariesTransfer pt = {};
   color_modes_cs_.push_back(pt);
 
@@ -335,7 +346,7 @@
   return kErrorNone;
 }
 
-DisplayError DisplayHDMI::SetDisplayState(DisplayState state, int *release_fence) {
+DisplayError DisplayPluggable::SetDisplayState(DisplayState state, int *release_fence) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
   error = DisplayBase::SetDisplayState(state, release_fence);
@@ -347,4 +358,3 @@
 }
 
 }  // namespace sdm
-
diff --git a/sdm/libs/core/display_hdmi.h b/sdm/libs/core/display_pluggable.h
similarity index 73%
rename from sdm/libs/core/display_hdmi.h
rename to sdm/libs/core/display_pluggable.h
index a742f15..aba1305 100644
--- a/sdm/libs/core/display_hdmi.h
+++ b/sdm/libs/core/display_pluggable.h
@@ -22,24 +22,25 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-#ifndef __DISPLAY_HDMI_H__
-#define __DISPLAY_HDMI_H__
+#ifndef __DISPLAY_PLUGGABLE_H__
+#define __DISPLAY_PLUGGABLE_H__
 
-#include <vector>
 #include <map>
+#include <vector>
 
 #include "display_base.h"
 #include "hw_events_interface.h"
 
 namespace sdm {
 
-class HWHDMIInterface;
-
-class DisplayHDMI : public DisplayBase, HWEventHandler {
+class DisplayPluggable : public DisplayBase, HWEventHandler {
  public:
-  DisplayHDMI(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
-              BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-              CompManager *comp_manager);
+  DisplayPluggable(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
+                   BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
+                   CompManager *comp_manager);
+  DisplayPluggable(int32_t display_id, DisplayEventHandler *event_handler,
+                   HWInfoInterface *hw_info_intf, BufferSyncHandler *buffer_sync_handler,
+                   BufferAllocator *buffer_allocator, CompManager *comp_manager);
   virtual DisplayError Init();
   virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
@@ -52,12 +53,12 @@
   // Implement the HWEventHandlers
   virtual DisplayError VSync(int64_t timestamp);
   virtual DisplayError Blank(bool blank) { return kErrorNone; }
-  virtual void IdleTimeout() { }
-  virtual void ThermalEvent(int64_t thermal_level) { }
+  virtual void IdleTimeout() {}
+  virtual void ThermalEvent(int64_t thermal_level) {}
   virtual void CECMessage(char *message);
-  virtual void IdlePowerCollapse() { }
-  virtual void PingPongTimeout() { }
-  virtual void PanelDead() { }
+  virtual void IdlePowerCollapse() {}
+  virtual void PingPongTimeout() {}
+  virtual void PanelDead() {}
   virtual void HwRecovery(const HWRecoveryEvent sdm_event_code);
 
  private:
@@ -70,14 +71,11 @@
   bool underscan_supported_ = false;
   HWScanSupport scan_support_;
   std::map<LayerBufferS3DFormat, HWS3DMode> s3d_format_to_mode_;
-  std::vector<HWEvent> event_list_ = { HWEvent::VSYNC,
-                                       HWEvent::IDLE_NOTIFY,
-                                       HWEvent::EXIT,
-                                       HWEvent::CEC_READ_MESSAGE,
-                                       HWEvent::HW_RECOVERY };
+  std::vector<HWEvent> event_list_ = {HWEvent::VSYNC, HWEvent::IDLE_NOTIFY, HWEvent::EXIT,
+                                      HWEvent::CEC_READ_MESSAGE, HWEvent::HW_RECOVERY};
   uint32_t current_refresh_rate_ = 0;
 };
 
 }  // namespace sdm
 
-#endif  // __DISPLAY_HDMI_H__
+#endif  // __DISPLAY_PLUGGABLE_H__
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index dfe4fd3..6daa0e9 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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:
@@ -40,15 +40,27 @@
                 comp_manager, hw_info_intf) {
 }
 
+DisplayVirtual::DisplayVirtual(int32_t display_id, DisplayEventHandler *event_handler,
+                               HWInfoInterface *hw_info_intf,
+                               BufferSyncHandler *buffer_sync_handler,
+                               BufferAllocator *buffer_allocator, CompManager *comp_manager)
+  : DisplayBase(display_id, kVirtual, event_handler, kDeviceVirtual, buffer_sync_handler,
+                buffer_allocator, comp_manager, hw_info_intf) {}
+
 DisplayError DisplayVirtual::Init() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
 
-  DisplayError error = HWInterface::Create(kVirtual, hw_info_intf_, buffer_sync_handler_,
-                                           buffer_allocator_, &hw_intf_);
+  DisplayError error = HWInterface::Create(display_id_, kVirtual, hw_info_intf_,
+                                           buffer_sync_handler_, buffer_allocator_, &hw_intf_);
+
   if (error != kErrorNone) {
     return error;
   }
 
+  if (-1 == display_id_) {
+    hw_intf_->GetDisplayId(&display_id_);
+  }
+
   HWScaleLutInfo lut_info = {};
   error = comp_manager_->GetScaleLutConfig(&lut_info);
   if (error == kErrorNone) {
@@ -135,8 +147,9 @@
     comp_manager_->UnregisterDisplay(display_comp_ctx_);
   }
 
-  error = comp_manager_->RegisterDisplay(display_type_, display_attributes, hw_panel_info,
-                                         mixer_attributes, fb_config, &display_comp_ctx_);
+  error =
+      comp_manager_->RegisterDisplay(display_id_, display_type_, display_attributes, hw_panel_info,
+                                     mixer_attributes, fb_config, &display_comp_ctx_);
   if (error != kErrorNone) {
     return error;
   }
@@ -161,6 +174,5 @@
   return DisplayBase::Prepare(layer_stack);
 }
 
-
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index eeade9d..76290e1 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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:
@@ -37,6 +37,9 @@
   DisplayVirtual(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
                  BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
                  CompManager *comp_manager);
+  DisplayVirtual(int32_t display_id, DisplayEventHandler *event_handler,
+                 HWInfoInterface *hw_info_intf, BufferSyncHandler *buffer_sync_handler,
+                 BufferAllocator *buffer_allocator, CompManager *comp_manager);
   virtual DisplayError Init();
   virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index f81f6fd..9cf2ff7 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -431,8 +431,13 @@
   drm_master->GetHandle(&dev_fd_);
   DRMLibLoader::GetInstance()->FuncGetDRMManager()(dev_fd_, &drm_mgr_intf_);
 
-  if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
-    DLOGE("RegisterDisplay failed for %s", device_name_);
+  if (-1 == display_id_) {
+    if (drm_mgr_intf_->RegisterDisplay(disp_type_, &token_)) {
+      DLOGE("RegisterDisplay (by type) failed for %s", device_name_);
+      return kErrorResources;
+    }
+  } else if (drm_mgr_intf_->RegisterDisplay(display_id_, &token_)) {
+    DLOGE("RegisterDisplay (by id) failed for %s - %d", device_name_, display_id_);
     return kErrorResources;
   }
 
@@ -442,6 +447,8 @@
     return kErrorNotSupported;
   }
 
+  display_id_ = static_cast<int32_t>(token_.conn_id);
+
   ret = drm_mgr_intf_->CreateAtomicReq(token_, &drm_atomic_intf_);
   if (ret) {
     DLOGE("Failed creating atomic request for connector id %u. Error: %d.", token_.conn_id, ret);
@@ -504,6 +511,11 @@
   return err;
 }
 
+DisplayError HWDeviceDRM::GetDisplayId(int32_t *display_id) {
+  *display_id = display_id_;
+  return kErrorNone;
+}
+
 void HWDeviceDRM::InitializeConfigs() {
   current_mode_index_ = 0;
   // Update current mode with preferred mode
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index e619957..ff871a5 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -70,6 +70,7 @@
 
  protected:
   // From HWInterface
+  virtual DisplayError GetDisplayId(int32_t *display_id);
   virtual DisplayError GetActiveConfig(uint32_t *active_config);
   virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
   virtual DisplayError GetDisplayAttributes(uint32_t index,
@@ -183,6 +184,7 @@
  protected:
   const char *device_name_ = {};
   bool default_mode_ = false;
+  int32_t display_id_ = -1;
   sde_drm::DRMDisplayType disp_type_ = {};
   HWInfoInterface *hw_info_intf_ = {};
   BufferSyncHandler *buffer_sync_handler_ = {};
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 2693b9e..9af0deb 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -199,8 +199,8 @@
   InitializePollFd();
 }
 
-DisplayError HWEventsDRM::Init(int display_type, HWEventHandler *event_handler,
-                               const vector<HWEvent> &event_list,
+DisplayError HWEventsDRM::Init(int display_id, DisplayType display_type,
+                               HWEventHandler *event_handler, const vector<HWEvent> &event_list,
                                const HWInterface *hw_intf) {
   if (!event_handler)
     return kErrorParameters;
@@ -208,17 +208,17 @@
   static_cast<const HWDeviceDRM *>(hw_intf)->GetDRMDisplayToken(&token_);
   is_primary_ = static_cast<const HWDeviceDRM *>(hw_intf)->IsPrimaryDisplay();
 
-  DLOGI("Setup event handler for display %d, CRTC %d, Connector %d",
-        display_type, token_.crtc_id, token_.conn_id);
+  DLOGI("Setup event handler for display %d-%d, CRTC %d, Connector %d", display_id, display_type,
+        token_.crtc_id, token_.conn_id);
 
   event_handler_ = event_handler;
   poll_fds_.resize(event_list.size());
-  event_thread_name_ += " - " + std::to_string(display_type);
+  event_thread_name_ += " - " + std::to_string(display_id) + "-" + std::to_string(display_type);
 
   PopulateHWEventData(event_list);
 
   if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) {
-    DLOGE("Failed to start %s, error = %s", event_thread_name_.c_str());
+    DLOGE("Failed to start %s, error = %s", event_thread_name_.c_str(), strerror(errno));
     return kErrorResources;
   }
 
diff --git a/sdm/libs/core/drm/hw_events_drm.h b/sdm/libs/core/drm/hw_events_drm.h
index 82c1b44..fb4e65d 100644
--- a/sdm/libs/core/drm/hw_events_drm.h
+++ b/sdm/libs/core/drm/hw_events_drm.h
@@ -49,9 +49,8 @@
 
 class HWEventsDRM : public HWEventsInterface {
  public:
-  virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
-                            const vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf);
+  virtual DisplayError Init(int display_id, DisplayType display_type, HWEventHandler *event_handler,
+                            const vector<HWEvent> &event_list, const HWInterface *hw_intf);
   virtual DisplayError Deinit();
   virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr);
 
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index a3b6d4f..2305088 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -727,10 +727,143 @@
 }
 
 DisplayError HWInfoDRM::GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) {
-  hw_disp_info->type = kPrimary;
+  hw_disp_info->type = kBuiltIn;
   hw_disp_info->is_connected = true;
 
   return kErrorNone;
 }
 
+DisplayError HWInfoDRM::GetDisplaysStatus(HWDisplaysInfo *hw_displays_info) {
+  static DebugTag log_once = kTagNone;
+
+  if (!hw_displays_info) {
+    DLOGE("No output parameter provided!");
+    return kErrorParameters;
+  }
+
+  if (!drm_mgr_intf_) {
+    DLOGE("DRM Driver not initialized!");
+    return kErrorCriticalResource;
+  }
+
+  hw_displays_info->clear();
+  sde_drm::DRMConnectorsInfo conns_info = {};
+  int drm_err = drm_mgr_intf_->GetConnectorsInfo(&conns_info);
+  if (drm_err) {
+    DLOGE("DRM Driver error %d while getting displays' status!", drm_err);
+    return kErrorUndefined;
+  }
+
+  for (auto &iter : conns_info) {
+    HWDisplayInfo hw_info = {};
+    hw_info.display_id =
+        ((0 == iter.first) || (iter.first > INT32_MAX)) ? -1 : (int32_t)(iter.first);
+    switch (iter.second.type) {
+      case DRM_MODE_CONNECTOR_DSI:
+        hw_info.display_type = kBuiltIn;
+        break;
+      case DRM_MODE_CONNECTOR_TV:
+      case DRM_MODE_CONNECTOR_HDMIA:
+      case DRM_MODE_CONNECTOR_HDMIB:
+      case DRM_MODE_CONNECTOR_DisplayPort:
+      case DRM_MODE_CONNECTOR_VGA:
+        hw_info.display_type = kPluggable;
+        break;
+      case DRM_MODE_CONNECTOR_VIRTUAL:
+        hw_info.display_type = kVirtual;
+        break;
+    }
+    hw_info.is_connected = iter.second.is_connected ? 1 : 0;
+    hw_info.is_primary = iter.second.is_primary ? 1 : 0;
+    if (hw_info.display_id >= 0) {
+      (*hw_displays_info)[hw_info.display_id] = hw_info;
+    }
+
+    DLOGI_IF(log_once, "display: %4d-%d, connected: %s, primary: %s", hw_info.display_id,
+             hw_info.display_type, hw_info.is_connected ? "true" : "false",
+             hw_info.is_primary ? "true" : "false");
+  }
+
+  log_once = kTagDisplay;
+
+  return kErrorNone;
+}
+
+DisplayError HWInfoDRM::GetMaxDisplaysSupported(const DisplayType type, int32_t *max_displays) {
+  static DebugTag log_once = kTagNone;
+
+  if (!max_displays) {
+    DLOGE("No output parameter provided!");
+    return kErrorParameters;
+  }
+
+  if (!drm_mgr_intf_) {
+    DLOGE("DRM Driver not initialized!");
+    return kErrorCriticalResource;
+  }
+
+  sde_drm::DRMEncodersInfo encoders_info = {};
+  int drm_err = drm_mgr_intf_->GetEncodersInfo(&encoders_info);
+  if (drm_err) {
+    DLOGE("DRM Driver error %d while getting max displays supported!", drm_err);
+    return kErrorUndefined;
+  }
+
+  int32_t max_displays_builtin = 0;
+  int32_t max_displays_tmds = 0;
+  int32_t max_displays_virtual = 0;
+  int32_t max_displays_dpmst = 0;
+  for (auto &iter : encoders_info) {
+    switch (iter.second.type) {
+      case DRM_MODE_ENCODER_DSI:
+        max_displays_builtin++;
+        break;
+      case DRM_MODE_ENCODER_TMDS:
+        max_displays_tmds++;
+        break;
+      case DRM_MODE_ENCODER_VIRTUAL:
+        max_displays_virtual++;
+        break;
+      case DRM_MODE_ENCODER_DPMST:
+        max_displays_dpmst++;
+        break;
+      default:
+        break;
+    }
+  }
+
+  switch (type) {
+    case kBuiltIn:
+      *max_displays = max_displays_builtin;
+      break;
+    case kPluggable:
+      *max_displays = std::max(max_displays_tmds, max_displays_dpmst);
+      break;
+    case kVirtual:
+      *max_displays = max_displays_virtual;
+      break;
+    case kDisplayTypeMax:
+      *max_displays = max_displays_builtin + std::max(max_displays_tmds, max_displays_dpmst) +
+                      max_displays_virtual;
+      break;
+    default:
+      DLOGE("Unknown display type %d.", type);
+      return kErrorParameters;
+  }
+
+  DLOGI_IF(log_once, "Max %d concurrent displays.",
+           max_displays_builtin + std::max(max_displays_tmds, max_displays_dpmst) +
+               max_displays_virtual);
+  DLOGI_IF(log_once, "Max %d concurrent displays of type %d (BuiltIn).", max_displays_builtin,
+           kBuiltIn);
+  DLOGI_IF(log_once, "Max %d concurrent displays of type %d (Pluggable).",
+           std::max(max_displays_tmds, max_displays_dpmst), kPluggable);
+  DLOGI_IF(log_once, "Max %d concurrent displays of type %d (Virtual).", max_displays_virtual,
+           kVirtual);
+
+  log_once = kTagDisplay;
+
+  return kErrorNone;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_info_drm.h b/sdm/libs/core/drm/hw_info_drm.h
index 82fb175..518b23d 100644
--- a/sdm/libs/core/drm/hw_info_drm.h
+++ b/sdm/libs/core/drm/hw_info_drm.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, 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
@@ -47,6 +47,8 @@
   virtual ~HWInfoDRM();
   virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource);
   virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
+  virtual DisplayError GetDisplaysStatus(HWDisplaysInfo *hw_displays_info);
+  virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays);
 
  private:
   DisplayError GetHWRotatorInfo(HWResourceInfo *hw_resource);
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index e39abb8..0249396 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_drm.cpp
@@ -44,12 +44,12 @@
 
 namespace sdm {
 
-HWPeripheralDRM::HWPeripheralDRM(BufferSyncHandler *buffer_sync_handler,
-                                 BufferAllocator *buffer_allocator,
-                                 HWInfoInterface *hw_info_intf)
+HWPeripheralDRM::HWPeripheralDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
+                                 BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf)
   : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
   disp_type_ = DRMDisplayType::PERIPHERAL;
   device_name_ = "Peripheral";
+  display_id_ = display_id;
 }
 
 DisplayError HWPeripheralDRM::Init() {
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
index 86af571..923d805 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ b/sdm/libs/core/drm/hw_peripheral_drm.h
@@ -42,9 +42,8 @@
 
 class HWPeripheralDRM : public HWDeviceDRM {
  public:
-  explicit HWPeripheralDRM(BufferSyncHandler *buffer_sync_handler,
-                           BufferAllocator *buffer_allocator,
-                           HWInfoInterface *hw_info_intf);
+  explicit HWPeripheralDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
+                           BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf);
   virtual ~HWPeripheralDRM() {}
 
  protected:
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index fa5da50..40fc31c 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -88,11 +88,12 @@
   return hdr_transfer;
 }
 
-HWTVDRM::HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                     HWInfoInterface *hw_info_intf)
+HWTVDRM::HWTVDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
+                 BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf)
   : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
   disp_type_ = DRMDisplayType::TV;
   device_name_ = "TV";
+  display_id_ = display_id;
 }
 
 DisplayError HWTVDRM::SetDisplayAttributes(uint32_t index) {
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
index a87f33d..7ee05ea 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -36,8 +36,8 @@
 
 class HWTVDRM : public HWDeviceDRM {
  public:
-  explicit HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
-                     HWInfoInterface *hw_info_intf);
+  explicit HWTVDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
+                   BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf);
 
  protected:
   virtual DisplayError SetDisplayAttributes(uint32_t index);
diff --git a/sdm/libs/core/drm/hw_virtual_drm.cpp b/sdm/libs/core/drm/hw_virtual_drm.cpp
index a9c1c29..afbdc19 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.cpp
+++ b/sdm/libs/core/drm/hw_virtual_drm.cpp
@@ -50,12 +50,12 @@
 
 namespace sdm {
 
-HWVirtualDRM::HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
-                           BufferAllocator *buffer_allocator,
-                           HWInfoInterface *hw_info_intf)
-                           : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
+HWVirtualDRM::HWVirtualDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
+                           BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf)
+  : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
   HWDeviceDRM::device_name_ = "Virtual";
   HWDeviceDRM::disp_type_ = DRMDisplayType::VIRTUAL;
+  HWDeviceDRM::display_id_ = display_id;
 }
 
 void HWVirtualDRM::ConfigureWbConnectorFbId(uint32_t fb_id) {
diff --git a/sdm/libs/core/drm/hw_virtual_drm.h b/sdm/libs/core/drm/hw_virtual_drm.h
index d89737e..30ed84c 100644
--- a/sdm/libs/core/drm/hw_virtual_drm.h
+++ b/sdm/libs/core/drm/hw_virtual_drm.h
@@ -39,7 +39,7 @@
 
 class HWVirtualDRM : public HWDeviceDRM {
  public:
-  HWVirtualDRM(BufferSyncHandler *buffer_sync_handler,
+  HWVirtualDRM(int32_t display_id, BufferSyncHandler *buffer_sync_handler,
                BufferAllocator *buffer_allocator, HWInfoInterface *hw_info_intf);
   virtual ~HWVirtualDRM() {}
   virtual DisplayError SetVSyncState(bool enable) { return kErrorNotSupported; }
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 427cb89..fe1f1e9 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -130,6 +130,11 @@
   return kErrorNone;
 }
 
+DisplayError HWDevice::GetDisplayId(int32_t *display_id) {
+  *display_id = fb_node_index_;
+  return kErrorNone;
+}
+
 DisplayError HWDevice::GetActiveConfig(uint32_t *active_config) {
   *active_config = 0;
   return kErrorNone;
@@ -756,25 +761,25 @@
     HWPanelInfo panel_info;
     GetHWPanelInfoByNode(i, &panel_info);
     switch (device_type) {
-    case kDevicePrimary:
-      if (panel_info.is_primary_panel) {
-        return i;
-      }
-      break;
-    case kDeviceHDMI:
-      if (panel_info.is_pluggable == true) {
-        if (IsFBNodeConnected(i)) {
+      case kDeviceBuiltIn:
+        if (panel_info.is_primary_panel) {
           return i;
         }
-      }
-      break;
-    case kDeviceVirtual:
-      if (panel_info.port == kPortWriteBack) {
-        return i;
-      }
-      break;
-    default:
-      break;
+        break;
+      case kDevicePluggable:
+        if (panel_info.is_pluggable == true) {
+          if (IsFBNodeConnected(i)) {
+            return i;
+          }
+        }
+        break;
+      case kDeviceVirtual:
+        if (panel_info.port == kPortWriteBack) {
+          return i;
+        }
+        break;
+      default:
+        break;
     }
   }
   return -1;
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 39ceb2c..71f5002 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -62,6 +62,7 @@
   explicit HWDevice(BufferSyncHandler *buffer_sync_handler);
 
   // From HWInterface
+  virtual DisplayError GetDisplayId(int32_t *display_id);
   virtual DisplayError GetActiveConfig(uint32_t *active_config);
   virtual DisplayError GetNumDisplayAttributes(uint32_t *count);
   virtual DisplayError GetDisplayAttributes(uint32_t index,
diff --git a/sdm/libs/core/fb/hw_events.cpp b/sdm/libs/core/fb/hw_events.cpp
index d944624..2247a3b 100644
--- a/sdm/libs/core/fb/hw_events.cpp
+++ b/sdm/libs/core/fb/hw_events.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2018, 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
@@ -125,14 +125,13 @@
   }
 }
 
-DisplayError HWEvents::Init(int fb_num, HWEventHandler *event_handler,
-                            const vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf) {
+DisplayError HWEvents::Init(int fb_num, DisplayType display_type, HWEventHandler *event_handler,
+                            const vector<HWEvent> &event_list, const HWInterface *hw_intf) {
   if (!event_handler)
     return kErrorParameters;
 
   event_handler_ = event_handler;
-  fb_num_ = fb_num;
+  fb_num_ = display_type;
   event_list_ = event_list;
   poll_fds_.resize(event_list_.size());
   event_thread_name_ += " - " + std::to_string(fb_num_);
diff --git a/sdm/libs/core/fb/hw_events.h b/sdm/libs/core/fb/hw_events.h
index 8ffd6d5..55b2cac 100644
--- a/sdm/libs/core/fb/hw_events.h
+++ b/sdm/libs/core/fb/hw_events.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2018, 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:
@@ -41,9 +41,8 @@
 
 class HWEvents : public HWEventsInterface {
  public:
-  virtual DisplayError Init(int fb_num, HWEventHandler *event_handler,
-                            const vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf);
+  virtual DisplayError Init(int fb_num, DisplayType display_type, HWEventHandler *event_handler,
+                            const vector<HWEvent> &event_list, const HWInterface *hw_intf);
   virtual DisplayError Deinit();
   virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) {
     return kErrorNotSupported;
diff --git a/sdm/libs/core/fb/hw_hdmi.cpp b/sdm/libs/core/fb/hw_hdmi.cpp
index 532c3ba..efbd4fb 100644
--- a/sdm/libs/core/fb/hw_hdmi.cpp
+++ b/sdm/libs/core/fb/hw_hdmi.cpp
@@ -184,8 +184,8 @@
 
 HWHDMI::HWHDMI(BufferSyncHandler *buffer_sync_handler,  HWInfoInterface *hw_info_intf)
   : HWDevice(buffer_sync_handler), hw_scan_info_(), active_config_index_(0) {
-  HWDevice::device_type_ = kDeviceHDMI;
-  HWDevice::device_name_ = "HDMI Display Device";
+  HWDevice::device_type_ = kDevicePluggable;
+  HWDevice::device_name_ = "Pluggable Display Device";
   HWDevice::hw_info_intf_ = hw_info_intf;
   (void)hdr_reset_start_;
   (void)hdr_reset_end_;
@@ -669,7 +669,7 @@
 void HWHDMI::SetSourceProductInformation(const char *node, const char *name) {
   char property_value[kMaxStringLength];
   char sys_fs_path[kMaxStringLength];
-  int hdmi_node_index = GetFBNodeIndex(kDeviceHDMI);
+  int hdmi_node_index = GetFBNodeIndex(kDevicePluggable);
   if (hdmi_node_index < 0) {
     return;
   }
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index 2cdae06..65b17cd 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2018, 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:
@@ -533,10 +533,10 @@
 
   if (!strncmp(line.c_str(), "dtv panel", strlen("dtv panel")) ||
       !strncmp(line.c_str(), "dp panel", strlen("dp panel"))) {
-    hw_disp_info->type = kHDMI;
-    DLOGI("First display is HDMI");
+    hw_disp_info->type = kPluggable;
+    DLOGI("First display is HDMI/pluggable");
   } else {
-    hw_disp_info->type = kPrimary;
+    hw_disp_info->type = kBuiltIn;
     DLOGI("First display is internal display");
   }
 
@@ -556,5 +556,45 @@
   return kErrorNone;
 }
 
+DisplayError HWInfo::GetDisplaysStatus(HWDisplaysInfo *hw_displays_info) {
+  // TODO(user):
+  DLOGW("This operation is not supported on FB Driver.");
+
+  return kErrorNotSupported;
+}
+
+DisplayError HWInfo::GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays) {
+  static DebugTag log_once = kTagNone;
+
+  if (!max_displays) {
+    DLOGE("No output parameter provided!");
+    return kErrorParameters;
+  }
+
+  switch (type) {
+    case kBuiltIn:
+    case kPluggable:
+    case kVirtual:
+      *max_displays = 1;
+      break;
+    case kDisplayTypeMax:
+      *max_displays = 3;
+      break;
+    default:
+      *max_displays = 0;
+      DLOGE("Unknown display type %d.", type);
+      return kErrorParameters;
+  }
+
+  DLOGI_IF(log_once, "Max 3 concurrent displays.");
+  DLOGI_IF(log_once, "Max 1 concurrent display of type %d (BuiltIn).", kBuiltIn);
+  DLOGI_IF(log_once, "Max 1 concurrent display of type %d (Pluggable).", kPluggable);
+  DLOGI_IF(log_once, "Max 1 concurrent display of type %d (Virtual).", kVirtual);
+
+  log_once = kTagDisplay;
+
+  return kErrorNone;
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/fb/hw_info.h b/sdm/libs/core/fb/hw_info.h
index cbceba0..f1f8e80 100644
--- a/sdm/libs/core/fb/hw_info.h
+++ b/sdm/libs/core/fb/hw_info.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2018, 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:
@@ -44,6 +44,8 @@
   virtual ~HWInfo() { delete hw_resource_; }
   virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource);
   virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info);
+  virtual DisplayError GetDisplaysStatus(HWDisplaysInfo *hw_displays_info);
+  virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays);
 
  private:
   virtual DisplayError GetHWRotatorInfo(HWResourceInfo *hw_resource);
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 4c72402..4b3265d 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -77,8 +77,8 @@
 
 HWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf)
   : HWDevice(buffer_sync_handler) {
-  HWDevice::device_type_ = kDevicePrimary;
-  HWDevice::device_name_ = "Primary Display Device";
+  HWDevice::device_type_ = kDeviceBuiltIn;
+  HWDevice::device_name_ = "BuiltIn Display Device";
   HWDevice::hw_info_intf_ = hw_info_intf;
 }
 
diff --git a/sdm/libs/core/hw_events_interface.cpp b/sdm/libs/core/hw_events_interface.cpp
index 84a7dab..1a8f42f 100644
--- a/sdm/libs/core/hw_events_interface.cpp
+++ b/sdm/libs/core/hw_events_interface.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, 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
@@ -38,7 +38,8 @@
 
 namespace sdm {
 
-DisplayError HWEventsInterface::Create(int display_type, HWEventHandler *event_handler,
+DisplayError HWEventsInterface::Create(int display_id, DisplayType display_type,
+                                       HWEventHandler *event_handler,
                                        const std::vector<HWEvent> &event_list,
                                        const HWInterface *hw_intf, HWEventsInterface **intf) {
   DisplayError error = kErrorNone;
@@ -49,7 +50,7 @@
     hw_events = new HWEventsDRM();
   }
 
-  error = hw_events->Init(display_type, event_handler, event_list, hw_intf);
+  error = hw_events->Init(display_id, display_type, event_handler, event_list, hw_intf);
   if (error != kErrorNone) {
     delete hw_events;
   } else {
diff --git a/sdm/libs/core/hw_events_interface.h b/sdm/libs/core/hw_events_interface.h
index db0bc3d..81d9b04 100644
--- a/sdm/libs/core/hw_events_interface.h
+++ b/sdm/libs/core/hw_events_interface.h
@@ -50,14 +50,13 @@
 
 class HWEventsInterface {
  public:
-  virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
-                            const std::vector<HWEvent> &event_list,
-                            const HWInterface *hw_intf) = 0;
+  virtual DisplayError Init(int display_id, DisplayType display_type, HWEventHandler *event_handler,
+                            const std::vector<HWEvent> &event_list, const HWInterface *hw_intf) = 0;
   virtual DisplayError Deinit() = 0;
   virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) = 0;
 
-  static DisplayError Create(int display_type, HWEventHandler *event_handler,
-                             const std::vector<HWEvent> &event_list,
+  static DisplayError Create(int display_id, DisplayType display_type,
+                             HWEventHandler *event_handler, const std::vector<HWEvent> &event_list,
                              const HWInterface *hw_intf, HWEventsInterface **intf);
   static DisplayError Destroy(HWEventsInterface *intf);
 
diff --git a/sdm/libs/core/hw_info_interface.h b/sdm/libs/core/hw_info_interface.h
index 401c8bf..b16da10 100644
--- a/sdm/libs/core/hw_info_interface.h
+++ b/sdm/libs/core/hw_info_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2016, 2018 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:
@@ -37,6 +37,8 @@
   static DisplayError Destroy(HWInfoInterface *intf);
   virtual DisplayError GetHWResourceInfo(HWResourceInfo *hw_resource) = 0;
   virtual DisplayError GetFirstDisplayInterfaceType(HWDisplayInterfaceInfo *hw_disp_info) = 0;
+  virtual DisplayError GetDisplaysStatus(HWDisplaysInfo *hw_displays_info) = 0;
+  virtual DisplayError GetMaxDisplaysSupported(DisplayType type, int32_t *max_displays) = 0;
 
  protected:
   virtual ~HWInfoInterface() { }
diff --git a/sdm/libs/core/hw_interface.cpp b/sdm/libs/core/hw_interface.cpp
index 902dcbc..6a2deed 100644
--- a/sdm/libs/core/hw_interface.cpp
+++ b/sdm/libs/core/hw_interface.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, 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
@@ -43,7 +43,8 @@
 
 namespace sdm {
 
-DisplayError HWInterface::Create(DisplayType type, HWInfoInterface *hw_info_intf,
+DisplayError HWInterface::Create(int32_t display_id, DisplayType type,
+                                 HWInfoInterface *hw_info_intf,
                                  BufferSyncHandler *buffer_sync_handler,
                                  BufferAllocator *buffer_allocator, HWInterface **intf) {
   DisplayError error = kErrorNone;
@@ -51,25 +52,25 @@
   DriverType driver_type = GetDriverType();
 
   switch (type) {
-    case kPrimary:
+    case kBuiltIn:
       if (driver_type == DriverType::FB) {
         hw = new HWPrimary(buffer_sync_handler, hw_info_intf);
       } else {
-        hw = new HWPeripheralDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
+        hw = new HWPeripheralDRM(display_id, buffer_sync_handler, buffer_allocator, hw_info_intf);
       }
       break;
-    case kHDMI:
+    case kPluggable:
       if (driver_type == DriverType::FB) {
         hw = new HWHDMI(buffer_sync_handler, hw_info_intf);
       } else {
-        hw = new HWTVDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
+        hw = new HWTVDRM(display_id, buffer_sync_handler, buffer_allocator, hw_info_intf);
       }
       break;
     case kVirtual:
       if (driver_type == DriverType::FB) {
         hw = new HWVirtual(buffer_sync_handler, hw_info_intf);
       } else {
-        hw = new HWVirtualDRM(buffer_sync_handler, buffer_allocator, hw_info_intf);
+        hw = new HWVirtualDRM(display_id, buffer_sync_handler, buffer_allocator, hw_info_intf);
       }
       break;
     default:
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index d02b0ba..7f1bbe9 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -71,13 +71,14 @@
 
 class HWInterface {
  public:
-  static DisplayError Create(DisplayType type, HWInfoInterface *hw_info_intf,
+  static DisplayError Create(int32_t display_id, DisplayType type, HWInfoInterface *hw_info_intf,
                              BufferSyncHandler *buffer_sync_handler,
                              BufferAllocator *buffer_allocator, HWInterface **intf);
   static DisplayError Destroy(HWInterface *intf);
 
   virtual DisplayError Init() = 0;
   virtual DisplayError Deinit() = 0;
+  virtual DisplayError GetDisplayId(int32_t *display_id) = 0;
   virtual DisplayError GetActiveConfig(uint32_t *active_config) = 0;
   virtual DisplayError GetNumDisplayAttributes(uint32_t *count) = 0;
   virtual DisplayError GetDisplayAttributes(uint32_t index,
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
index 73a28a8..f44283b 100644
--- a/sdm/libs/core/resource_default.cpp
+++ b/sdm/libs/core/resource_default.cpp
@@ -134,33 +134,33 @@
   return kErrorNone;
 }
 
-DisplayError ResourceDefault::RegisterDisplay(DisplayType type,
+DisplayError ResourceDefault::RegisterDisplay(int32_t display_id, DisplayType type,
                                               const HWDisplayAttributes &display_attributes,
                                               const HWPanelInfo &hw_panel_info,
                                               const HWMixerAttributes &mixer_attributes,
                                               Handle *display_ctx) {
   DisplayError error = kErrorNone;
 
-  HWBlockType hw_block_id = kHWBlockMax;
+  HWBlockType hw_block_type = kHWBlockMax;
   switch (type) {
-  case kPrimary:
-    if (!hw_block_ctx_[kHWPrimary].is_in_use) {
-      hw_block_id = kHWPrimary;
-    }
-    break;
+    case kBuiltIn:
+      if (!hw_block_ctx_[kHWBuiltIn].is_in_use) {
+        hw_block_type = kHWBuiltIn;
+      }
+      break;
 
-  case kHDMI:
-    if (!hw_block_ctx_[kHWHDMI].is_in_use) {
-      hw_block_id = kHWHDMI;
-    }
-    break;
+    case kPluggable:
+      if (!hw_block_ctx_[kHWPluggable].is_in_use) {
+        hw_block_type = kHWPluggable;
+      }
+      break;
 
-  default:
-    DLOGW("RegisterDisplay, invalid type %d", type);
-    return kErrorParameters;
+    default:
+      DLOGW("RegisterDisplay, invalid type %d", type);
+      return kErrorParameters;
   }
 
-  if (hw_block_id == kHWBlockMax) {
+  if (hw_block_type == kHWBlockMax) {
     return kErrorResources;
   }
 
@@ -169,10 +169,10 @@
     return kErrorMemory;
   }
 
-  hw_block_ctx_[hw_block_id].is_in_use = true;
+  hw_block_ctx_[hw_block_type].is_in_use = true;
 
   display_resource_ctx->display_attributes = display_attributes;
-  display_resource_ctx->hw_block_id = hw_block_id;
+  display_resource_ctx->hw_block_type = hw_block_type;
   display_resource_ctx->mixer_attributes = mixer_attributes;
 
   *display_ctx = display_resource_ctx;
@@ -184,7 +184,7 @@
                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
   Purge(display_ctx);
 
-  hw_block_ctx_[display_resource_ctx->hw_block_id].is_in_use = false;
+  hw_block_ctx_[display_resource_ctx->hw_block_type].is_in_use = false;
 
   delete display_resource_ctx;
 
@@ -224,9 +224,9 @@
 
   DisplayError error = kErrorNone;
   const struct HWLayersInfo &layer_info = hw_layers->info;
-  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
+  HWBlockType hw_block_type = display_resource_ctx->hw_block_type;
 
-  DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block = %d ====", hw_block_id);
+  DLOGV_IF(kTagResources, "==== Resource reserving start: hw_block_type = %d ====", hw_block_type);
 
   if (layer_info.hw_layers.size() > 1) {
     DLOGV_IF(kTagResources, "More than one FB layers");
@@ -247,7 +247,7 @@
   }
 
   for (uint32_t i = 0; i < num_pipe_; i++) {
-    if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
+    if (src_pipes_[i].hw_block_type == hw_block_type && src_pipes_[i].owner == kPipeOwnerUserMode) {
       src_pipes_[i].ResetState();
     }
   }
@@ -264,10 +264,10 @@
   // left pipe is needed
   if (left_pipe->valid) {
     need_scale = IsScalingNeeded(left_pipe);
-    left_index = GetPipe(hw_block_id, need_scale);
+    left_index = GetPipe(hw_block_type, need_scale);
     if (left_index >= num_pipe_) {
-      DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_id = %d, need_scale = %d",
-               hw_block_id, need_scale);
+      DLOGV_IF(kTagResources, "Get left pipe failed: hw_block_type = %d, need_scale = %d",
+               hw_block_type, need_scale);
       ResourceStateLog();
       goto CleanupOnError;
     }
@@ -289,10 +289,10 @@
 
   need_scale = IsScalingNeeded(right_pipe);
 
-  right_index = GetPipe(hw_block_id, need_scale);
+  right_index = GetPipe(hw_block_type, need_scale);
   if (right_index >= num_pipe_) {
-    DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_id = %d, need_scale = %d", hw_block_id,
-             need_scale);
+    DLOGV_IF(kTagResources, "Get right pipe failed: hw_block_type = %d, need_scale = %d",
+             hw_block_type, need_scale);
     ResourceStateLog();
     goto CleanupOnError;
   }
@@ -317,7 +317,7 @@
   return kErrorNone;
 
 CleanupOnError:
-  DLOGV_IF(kTagResources, "Resource reserving failed! hw_block = %d", hw_block_id);
+  DLOGV_IF(kTagResources, "Resource reserving failed! hw_block_type = %d", hw_block_type);
 
   return kErrorResources;
 }
@@ -338,15 +338,17 @@
   SCOPE_LOCK(locker_);
   DisplayResourceContext *display_resource_ctx =
                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
-  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
+  HWBlockType hw_block_type = display_resource_ctx->hw_block_type;
   uint64_t frame_count = display_resource_ctx->frame_count;
 
-  DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %d", hw_block_id, frame_count);
+  DLOGV_IF(kTagResources, "Resource for hw_block = %d, frame_count = %d", hw_block_type,
+           frame_count);
 
   // handoff pipes which are used by splash screen
-  if ((frame_count == 0) && (hw_block_id == kHWPrimary)) {
+  if ((frame_count == 0) && (hw_block_type == kHWBuiltIn)) {
     for (uint32_t i = 0; i < num_pipe_; i++) {
-      if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerKernelMode) {
+      if (src_pipes_[i].hw_block_type == hw_block_type &&
+          src_pipes_[i].owner == kPipeOwnerKernelMode) {
         src_pipes_[i].owner = kPipeOwnerUserMode;
       }
     }
@@ -365,14 +367,14 @@
 
   DisplayResourceContext *display_resource_ctx =
                           reinterpret_cast<DisplayResourceContext *>(display_ctx);
-  HWBlockType hw_block_id = display_resource_ctx->hw_block_id;
+  HWBlockType hw_block_type = display_resource_ctx->hw_block_type;
 
   for (uint32_t i = 0; i < num_pipe_; i++) {
-    if (src_pipes_[i].hw_block_id == hw_block_id && src_pipes_[i].owner == kPipeOwnerUserMode) {
+    if (src_pipes_[i].hw_block_type == hw_block_type && src_pipes_[i].owner == kPipeOwnerUserMode) {
       src_pipes_[i].ResetState();
     }
   }
-  DLOGV_IF(kTagResources, "display id = %d", display_resource_ctx->hw_block_id);
+  DLOGV_IF(kTagResources, "display hw_block_type = %d", display_resource_ctx->hw_block_type);
 }
 
 DisplayError ResourceDefault::SetMaxMixerStages(Handle display_ctx, uint32_t max_mixer_stages) {
@@ -381,17 +383,17 @@
   return kErrorNone;
 }
 
-uint32_t ResourceDefault::SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes,
-                                uint32_t num_pipe) {
+uint32_t ResourceDefault::SearchPipe(HWBlockType hw_block_type, SourcePipe *src_pipes,
+                                     uint32_t num_pipe) {
   uint32_t index = num_pipe_;
   SourcePipe *src_pipe;
 
   // search the pipe being used
   for (uint32_t i = 0; i < num_pipe; i++) {
     src_pipe = &src_pipes[i];
-    if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_id == kHWBlockMax) {
+    if (src_pipe->owner == kPipeOwnerUserMode && src_pipe->hw_block_type == kHWBlockMax) {
       index = src_pipe->index;
-      src_pipe->hw_block_id = hw_block_id;
+      src_pipe->hw_block_type = hw_block_type;
       break;
     }
   }
@@ -399,7 +401,7 @@
   return index;
 }
 
-uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_id) {
+uint32_t ResourceDefault::NextPipe(PipeType type, HWBlockType hw_block_type) {
   uint32_t num_pipe = 0;
   SourcePipe *src_pipes = NULL;
 
@@ -419,23 +421,23 @@
     break;
   }
 
-  return SearchPipe(hw_block_id, src_pipes, num_pipe);
+  return SearchPipe(hw_block_type, src_pipes, num_pipe);
 }
 
-uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_id, bool need_scale) {
+uint32_t ResourceDefault::GetPipe(HWBlockType hw_block_type, bool need_scale) {
   uint32_t index = num_pipe_;
 
   // The default behavior is to assume RGB and VG pipes have scalars
   if (!need_scale) {
-    index = NextPipe(kPipeTypeDMA, hw_block_id);
+    index = NextPipe(kPipeTypeDMA, hw_block_type);
   }
 
   if ((index >= num_pipe_) && (!need_scale || !hw_res_info_.has_non_scalar_rgb)) {
-    index = NextPipe(kPipeTypeRGB, hw_block_id);
+    index = NextPipe(kPipeTypeRGB, hw_block_type);
   }
 
   if (index >= num_pipe_) {
-    index = NextPipe(kPipeTypeVIG, hw_block_id);
+    index = NextPipe(kPipeTypeVIG, hw_block_type);
   }
 
   return index;
@@ -454,9 +456,9 @@
   uint32_t i;
   for (i = 0; i < num_pipe_; i++) {
     SourcePipe *src_pipe = &src_pipes_[i];
-    DLOGV_IF(kTagResources, "index = %d, id = %x, hw_block = %d, owner = %s",
-                 src_pipe->index, src_pipe->mdss_pipe_id, src_pipe->hw_block_id,
-                 (src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
+    DLOGV_IF(kTagResources, "index = %d, id = %x, hw_block_type = %d, owner = %s", src_pipe->index,
+             src_pipe->mdss_pipe_id, src_pipe->hw_block_type,
+             (src_pipe->owner == kPipeOwnerUserMode) ? "user mode" : "kernel mode");
   }
 }
 
diff --git a/sdm/libs/core/resource_default.h b/sdm/libs/core/resource_default.h
index a67eb09..7b08761 100644
--- a/sdm/libs/core/resource_default.h
+++ b/sdm/libs/core/resource_default.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2018, 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:
@@ -39,7 +39,7 @@
   static DisplayError CreateResourceDefault(const HWResourceInfo &hw_resource_info,
                                             ResourceInterface **resource_intf);
   static DisplayError DestroyResourceDefault(ResourceInterface *resource_intf);
-  virtual DisplayError RegisterDisplay(DisplayType type,
+  virtual DisplayError RegisterDisplay(int32_t display_id, DisplayType type,
                                        const HWDisplayAttributes &display_attributes,
                                        const HWPanelInfo &hw_panel_info,
                                        const HWMixerAttributes &mixer_attributes,
@@ -83,22 +83,27 @@
     PipeOwner owner;
     uint32_t mdss_pipe_id;
     uint32_t index;
-    HWBlockType hw_block_id;
+    HWBlockType hw_block_type;
     int priority;
 
-    SourcePipe() : type(kPipeTypeUnused), owner(kPipeOwnerUserMode), mdss_pipe_id(0),
-                  index(0), hw_block_id(kHWBlockMax), priority(0) { }
+    SourcePipe()
+      : type(kPipeTypeUnused),
+        owner(kPipeOwnerUserMode),
+        mdss_pipe_id(0),
+        index(0),
+        hw_block_type(kHWBlockMax),
+        priority(0) {}
 
-    inline void ResetState() { hw_block_id = kHWBlockMax;}
+    inline void ResetState() { hw_block_type = kHWBlockMax; }
   };
 
   struct DisplayResourceContext {
     HWDisplayAttributes display_attributes;
-    HWBlockType hw_block_id;
+    HWBlockType hw_block_type;
     uint64_t frame_count;
     HWMixerAttributes mixer_attributes;
 
-    DisplayResourceContext() : hw_block_id(kHWBlockMax), frame_count(0) { }
+    DisplayResourceContext() : hw_block_type(kHWBlockMax), frame_count(0) {}
   };
 
   struct HWBlockContext {
@@ -109,9 +114,9 @@
   explicit ResourceDefault(const HWResourceInfo &hw_res_info);
   DisplayError Init();
   DisplayError Deinit();
-  uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_id);
-  uint32_t SearchPipe(HWBlockType hw_block_id, SourcePipe *src_pipes, uint32_t num_pipe);
-  uint32_t GetPipe(HWBlockType hw_block_id, bool need_scale);
+  uint32_t NextPipe(PipeType pipe_type, HWBlockType hw_block_type);
+  uint32_t SearchPipe(HWBlockType hw_block_type, SourcePipe *src_pipes, uint32_t num_pipe);
+  uint32_t GetPipe(HWBlockType hw_block_type, bool need_scale);
   bool IsScalingNeeded(const HWPipeInfo *pipe_info);
   DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers);
   DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
diff --git a/sdm/libs/core/strategy.cpp b/sdm/libs/core/strategy.cpp
index dd32d58..d96c103 100644
--- a/sdm/libs/core/strategy.cpp
+++ b/sdm/libs/core/strategy.cpp
@@ -34,32 +34,35 @@
 namespace sdm {
 
 Strategy::Strategy(ExtensionInterface *extension_intf, BufferAllocator *buffer_allocator,
-                   DisplayType type,
-                   const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
-                   const HWMixerAttributes &mixer_attributes,
+                   int32_t display_id, DisplayType type, const HWResourceInfo &hw_resource_info,
+                   const HWPanelInfo &hw_panel_info, const HWMixerAttributes &mixer_attributes,
                    const HWDisplayAttributes &display_attributes,
                    const DisplayConfigVariableInfo &fb_config)
-  : extension_intf_(extension_intf), display_type_(type), hw_resource_info_(hw_resource_info),
-    hw_panel_info_(hw_panel_info), mixer_attributes_(mixer_attributes),
-    display_attributes_(display_attributes), fb_config_(fb_config),
-    buffer_allocator_(buffer_allocator) {
-}
+  : extension_intf_(extension_intf),
+    display_id_(display_id),
+    display_type_(type),
+    hw_resource_info_(hw_resource_info),
+    hw_panel_info_(hw_panel_info),
+    mixer_attributes_(mixer_attributes),
+    display_attributes_(display_attributes),
+    fb_config_(fb_config),
+    buffer_allocator_(buffer_allocator) {}
 
 DisplayError Strategy::Init() {
   DisplayError error = kErrorNone;
 
   if (extension_intf_) {
-    error = extension_intf_->CreateStrategyExtn(display_type_, buffer_allocator_, hw_resource_info_,
-                                                hw_panel_info_, mixer_attributes_, fb_config_,
-                                                &strategy_intf_);
+    error = extension_intf_->CreateStrategyExtn(display_id_, display_type_, buffer_allocator_,
+                                                hw_resource_info_, hw_panel_info_,
+                                                mixer_attributes_, fb_config_, &strategy_intf_);
     if (error != kErrorNone) {
       DLOGE("Failed to create strategy");
       return error;
     }
 
-    error = extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info_,
-                                                 mixer_attributes_, display_attributes_, fb_config_,
-                                                 &partial_update_intf_);
+    error = extension_intf_->CreatePartialUpdate(
+        display_id_, display_type_, hw_resource_info_, hw_panel_info_, mixer_attributes_,
+        display_attributes_, fb_config_, &partial_update_intf_);
   }
 
   return kErrorNone;
@@ -200,7 +203,7 @@
     partial_update_intf_ = NULL;
   }
 
-  extension_intf_->CreatePartialUpdate(display_type_, hw_resource_info_, hw_panel_info,
+  extension_intf_->CreatePartialUpdate(display_id_, display_type_, hw_resource_info_, hw_panel_info,
                                        mixer_attributes, display_attributes, fb_config,
                                        &partial_update_intf_);
 
diff --git a/sdm/libs/core/strategy.h b/sdm/libs/core/strategy.h
index b52b187..c79dff6 100644
--- a/sdm/libs/core/strategy.h
+++ b/sdm/libs/core/strategy.h
@@ -35,9 +35,9 @@
 class Strategy {
  public:
   Strategy(ExtensionInterface *extension_intf, BufferAllocator *buffer_allocator,
-           DisplayType type,
-           const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
-           const HWMixerAttributes &mixer_attributes, const HWDisplayAttributes &display_attributes,
+           int32_t display_id, DisplayType type, const HWResourceInfo &hw_resource_info,
+           const HWPanelInfo &hw_panel_info, const HWMixerAttributes &mixer_attributes,
+           const HWDisplayAttributes &display_attributes,
            const DisplayConfigVariableInfo &fb_config);
 
   DisplayError Init();
@@ -62,6 +62,7 @@
   ExtensionInterface *extension_intf_ = NULL;
   StrategyInterface *strategy_intf_ = NULL;
   PartialUpdateInterface *partial_update_intf_ = NULL;
+  int32_t display_id_;
   DisplayType display_type_;
   HWResourceInfo hw_resource_info_;
   HWPanelInfo hw_panel_info_;
diff --git a/sdm/libs/hwc2/display_null.h b/sdm/libs/hwc2/display_null.h
index ddd9b27..3dc8761 100644
--- a/sdm/libs/hwc2/display_null.h
+++ b/sdm/libs/hwc2/display_null.h
@@ -89,6 +89,8 @@
   MAKE_NO_OP(SetMixerResolution(uint32_t, uint32_t))
   MAKE_NO_OP(SetDetailEnhancerData(const DisplayDetailEnhancerData &))
   MAKE_NO_OP(GetDisplayPort(DisplayPort *))
+  MAKE_NO_OP(GetDisplayId(int32_t *))
+  MAKE_NO_OP(GetDisplayType(DisplayType *))
   MAKE_NO_OP(SetCompositionState(LayerComposition, bool))
   MAKE_NO_OP(GetClientTargetSupport(uint32_t, uint32_t, LayerBufferFormat,
                                     const ColorMetaData &))
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index 05d5c7b..17e02e8 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -87,17 +87,17 @@
 int Debug::GetMaxPipesPerMixer(DisplayType display_type) {
   int value = -1;
   switch (display_type) {
-  case kPrimary:
-    DebugHandler::Get()->GetProperty(PRIMARY_MIXER_STAGES_PROP, &value);
-    break;
-  case kHDMI:
-    DebugHandler::Get()->GetProperty(EXTERNAL_MIXER_STAGES_PROP, &value);
-    break;
-  case kVirtual:
-    DebugHandler::Get()->GetProperty(VIRTUAL_MIXER_STAGES_PROP, &value);
-    break;
-  default:
-    break;
+    case kBuiltIn:
+      DebugHandler::Get()->GetProperty(PRIMARY_MIXER_STAGES_PROP, &value);
+      break;
+    case kPluggable:
+      DebugHandler::Get()->GetProperty(EXTERNAL_MIXER_STAGES_PROP, &value);
+      break;
+    case kVirtual:
+      DebugHandler::Get()->GetProperty(VIRTUAL_MIXER_STAGES_PROP, &value);
+      break;
+    default:
+      break;
   }
 
   return value;