Merge remote-tracking branch 'goog/qcom/release/LA.UM.9.12.C10.11.00.00.840.415'

 Conflicts:
	composer/hwc_display_builtin.cpp
	gralloc/gr_buf_mgr.cpp
	gralloc/gr_utils.cpp
	libqservice/IQService.h
	sde-drm/drm_plane.cpp

Bug: 253163588
Bug: 255678025
Change-Id: I493a1d61e700e4e137582574c06aeadfed8a260d
diff --git a/Android.bp b/Android.bp
index db696fb..0702d95 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,5 +1,42 @@
+soong_namespace {
+}
+
+package {
+    default_applicable_licenses: ["hardware_qcom_sm7250_display_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
+license {
+    name: "hardware_qcom_sm7250_display_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "legacy_not_a_contribution",
+    ],
+    // large-scale-change unable to identify any license_text files
+}
+
+display_go_defaults_sm7250 {
+    name: "display_go_defaults",
+}
+
 cc_defaults {
     name: "display_defaults",
+    defaults: ["display_go_defaults"],
     cflags: [
         "-Wno-missing-field-initializers",
         "-Wconversion",
@@ -12,11 +49,12 @@
         "libutils",
     ],
     header_libs: ["display_headers"],
-    clang: true,
+
 }
 
 cc_library_headers {
     name: "debug_headers",
+    defaults: ["display_go_defaults"],
     vendor: true,
     export_include_dirs: [
         "libdebug",
@@ -25,6 +63,7 @@
 
 cc_library_headers {
     name: "display_headers",
+    defaults: ["display_go_defaults"],
     vendor: true,
     export_include_dirs: [
         "include",
@@ -37,8 +76,16 @@
         "gralloc",
         "libhistogram",
     ],
-    header_libs: ["libhardware_headers", "display_intf_headers", "debug_headers"],
-    export_header_lib_headers: ["libhardware_headers", "display_intf_headers", "debug_headers"],
+    header_libs: [
+        "libhardware_headers",
+        "//vendor/qcom/sm7250:display_intf_headers",
+        "debug_headers",
+    ],
+    export_header_lib_headers: [
+        "libhardware_headers",
+        "//vendor/qcom/sm7250:display_intf_headers",
+        "debug_headers",
+    ],
 }
 
 subdirs = [
diff --git a/Android.mk b/Android.mk
index 0a53f2a..3551e77 100644
--- a/Android.mk
+++ b/Android.mk
@@ -11,7 +11,7 @@
 display-hals += composer
 display-hals += init
 
-ifeq ($(call is-vendor-board-platform,QCOM),true)
+ifneq (,$(call is-vendor-board-qcom))
     include $(call all-named-subdir-makefiles,$(display-hals))
 else
 ifneq ($(filter msm% apq%,$(TARGET_BOARD_PLATFORM)),)
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: NOTICE
+}
diff --git a/common.mk b/common.mk
index 16b0574..1bf2e2d 100644
--- a/common.mk
+++ b/common.mk
@@ -25,7 +25,7 @@
     common_flags += -D__ARM_HAVE_NEON
 endif
 
-ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)), true)
+ifneq (,$(call is-board-platform-in-list2, $(MASTER_SIDE_CP_TARGET_LIST)))
     common_flags += -DMASTER_SIDE_CP
 endif
 
@@ -43,7 +43,7 @@
     common_flags += --compile-and-analyze --analyzer-perf --analyzer-Werror
 endif
 
-common_includes := system/core/base/include
+common_includes := system/libbase/include
 CHECK_VERSION_LE = $(shell if [ $(1) -le $(2) ] ; then echo true ; else echo false ; fi)
 PLATFORM_SDK_NOUGAT = 25
 ifeq "REL" "$(PLATFORM_VERSION_CODENAME)"
diff --git a/composer/Android.mk b/composer/Android.mk
index 461396c..fbee622 100644
--- a/composer/Android.mk
+++ b/composer/Android.mk
@@ -1,9 +1,10 @@
 LOCAL_PATH := $(call my-dir)
-
 include $(LOCAL_PATH)/../common.mk
 include $(CLEAR_VARS)
 
 LOCAL_MODULE                  := vendor.qti.hardware.display.composer-service
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS      := by_exception_only not_allowed notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_RELATIVE_PATH    := hw
@@ -36,6 +37,10 @@
                                  libdisplayconfig.qti \
                                  libdrm libthermalclient
 
+LOCAL_SHARED_LIBRARIES        += com.google.hardware.pixel.display-V1-ndk \
+                                 libbinder_ndk \
+                                 libbase
+
 LOCAL_SRC_FILES               := QtiComposer.cpp QtiComposerClient.cpp service.cpp \
                                  QtiComposerHandleImporter.cpp \
                                  hwc_session.cpp \
@@ -63,7 +68,8 @@
                                  gl_color_convert.cpp \
                                  gl_color_convert_impl.cpp \
                                  gl_layer_stitch.cpp \
-                                 gl_layer_stitch_impl.cpp
+                                 gl_layer_stitch_impl.cpp \
+                                 pixel-display.cpp
 
 LOCAL_INIT_RC                 := vendor.qti.hardware.display.composer-service.rc
 ifneq ($(TARGET_HAS_LOW_RAM),true)
@@ -76,4 +82,6 @@
 LOCAL_VINTF_FRAGMENTS         := vendor.qti.hardware.display.composer-service-low-ram.xml
 endif
 
+LOCAL_VINTF_FRAGMENTS         += pixel-display-default.xml
+
 include $(BUILD_EXECUTABLE)
diff --git a/composer/QtiComposerClient.cpp b/composer/QtiComposerClient.cpp
index aee1326..234ba7c 100644
--- a/composer/QtiComposerClient.cpp
+++ b/composer/QtiComposerClient.cpp
@@ -653,7 +653,7 @@
   }
 
   const native_handle_t* readbackBuffer;
-  getDisplayReadbackBuffer(display, buffer.getNativeHandle(), &readbackBuffer);
+  error = getDisplayReadbackBuffer(display, buffer.getNativeHandle(), &readbackBuffer);
   if (error != Error::NONE) {
     return error;
   }
@@ -963,30 +963,22 @@
 
 Return<void> QtiComposerClient::getDisplayCapabilities(uint64_t display,
                                                        getDisplayCapabilities_cb _hidl_cb) {
-  // We only care about passing VTS for older composer versions
-  // Not returning any capabilities that are optional
-
-  hidl_vec<DisplayCapability_V2_3> capabilities;
-
+  hidl_vec<composer_V2_3::IComposerClient::DisplayCapability> capabilities;
   uint32_t count = 0;
-  auto error = hwc_session_->GetDisplayCapabilities2_3(display, &count, nullptr);
+  auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
   if (error != HWC2_ERROR_NONE) {
     _hidl_cb(static_cast<Error>(error), capabilities);
     return Void();
   }
 
   capabilities.resize(count);
-  error = hwc_session_->GetDisplayCapabilities2_3(display, &count,
-                 reinterpret_cast<std::underlying_type<DisplayCapability_V2_3>::type*>(
-                 capabilities.data()));
-   if (error != HWC2_ERROR_NONE) {
-     capabilities = hidl_vec<DisplayCapability_V2_3>();
-     _hidl_cb(static_cast<Error>(error), capabilities);
-     return Void();
-   }
+  error = hwc_session_->GetDisplayCapabilities(
+      display, &count,
+      reinterpret_cast<std::underlying_type<composer_V2_3::IComposerClient::DisplayCapability>::type
+                           *>(capabilities.data()));
 
-   _hidl_cb(static_cast<Error>(error), capabilities);
-   return Void();
+  _hidl_cb(static_cast<Error>(error), capabilities);
+  return Void();
 }
 
 Return<void> QtiComposerClient::getPerFrameMetadataKeys_2_3(uint64_t display,
@@ -1059,10 +1051,42 @@
   enableCallback(callback != nullptr);
   return Void();
 }
+
 Return<void> QtiComposerClient::getDisplayCapabilities_2_4(uint64_t display,
                                                            getDisplayCapabilities_2_4_cb _hidl_cb) {
-  hidl_vec<composer_V2_4::IComposerClient::DisplayCapability> capabilities;
-  auto error = hwc_session_->GetDisplayCapabilities(display, &capabilities);
+  hidl_vec<HwcDisplayCapability> capabilities;
+  uint32_t count = 0;
+  auto error = hwc_session_->GetDisplayCapabilities(display, &count, nullptr);
+  if (error != HWC2_ERROR_NONE) {
+    _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
+    return Void();
+  }
+
+  uint32_t count_2_4 = 0;
+  error = hwc_session_->GetDisplayCapabilities_2_4(display, &count_2_4, nullptr);
+  if (error != HWC2_ERROR_NONE) {
+    _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
+    return Void();
+  }
+
+  capabilities.resize(count + count_2_4);
+  error = hwc_session_->GetDisplayCapabilities(
+      display, &count,
+      reinterpret_cast<std::underlying_type<HwcDisplayCapability>::type *>(capabilities.data()));
+  if (error != HWC2_ERROR_NONE) {
+    _hidl_cb(static_cast<composer_V2_4::Error>(error), {});
+    return Void();
+  }
+
+  error = hwc_session_->GetDisplayCapabilities_2_4(
+      display, &count_2_4,
+      reinterpret_cast<std::underlying_type<HwcDisplayCapability>::type *>(capabilities.data() +
+                                                                           count));
+  if (error != HWC2_ERROR_NONE) {
+    _hidl_cb(static_cast<composer_V2_4::Error>(error), {});
+    return Void();
+  }
+
   _hidl_cb(static_cast<composer_V2_4::Error>(error), capabilities);
   return Void();
 }
@@ -1111,17 +1135,21 @@
   if (mDisplayData.find(display) == mDisplayData.end()) {
     return composer_V2_4::Error::BAD_DISPLAY;
   }
-  return composer_V2_4::Error::UNSUPPORTED;
+
+  auto error = hwc_session_->SetAutoLowLatencyMode(display, on);
+
+  return static_cast<composer_V2_4::Error>(error);
 }
 
 Return<void> QtiComposerClient::getSupportedContentTypes(uint64_t display,
                                                          getSupportedContentTypes_cb _hidl_cb) {
-  hidl_vec<composer_V2_4::IComposerClient::ContentType> types = {};
+  hidl_vec<composer_V2_4::IComposerClient::ContentType> types;
   if (mDisplayData.find(display) == mDisplayData.end()) {
     _hidl_cb(composer_V2_4::Error::BAD_DISPLAY, types);
     return Void();
   }
-  _hidl_cb(composer_V2_4::Error::NONE, types);
+  auto error = hwc_session_->GetSupportedContentTypes(display, &types);
+  _hidl_cb(static_cast<composer_V2_4::Error>(error), types);
   return Void();
 }
 
@@ -1133,7 +1161,9 @@
   if (type == composer_V2_4::IComposerClient::ContentType::NONE) {
     return composer_V2_4::Error::NONE;
   }
-  return composer_V2_4::Error::UNSUPPORTED;
+  auto error = hwc_session_->SetContentType(display, type);
+
+  return static_cast<composer_V2_4::Error>(error);
 }
 
 Return<void> QtiComposerClient::getLayerGenericMetadataKeys(
diff --git a/composer/QtiComposerClient.h b/composer/QtiComposerClient.h
index 468f12a..7fbe26e 100644
--- a/composer/QtiComposerClient.h
+++ b/composer/QtiComposerClient.h
@@ -49,7 +49,6 @@
 namespace composer_V2_3 = ::android::hardware::graphics::composer::V2_3;
 namespace composer_V2_4 = ::android::hardware::graphics::composer::V2_4;
 
-using DisplayCapability_V2_3 = composer_V2_3::IComposerClient::DisplayCapability;
 using PerFrameMetadataKey_V2 = composer_V2_2::IComposerClient::PerFrameMetadataKey;
 using PerFrameMetadataKey = composer_V2_3::IComposerClient::PerFrameMetadataKey;
 
diff --git a/composer/hwc_display.cpp b/composer/hwc_display.cpp
index 080f2da..216d442 100644
--- a/composer/hwc_display.cpp
+++ b/composer/hwc_display.cpp
@@ -550,7 +550,9 @@
 
   game_supported_ = display_intf_->GameEnhanceSupported();
 
-  DLOGI("Display created with id: %d, game_supported_: %d", UINT32(id_), game_supported_);
+  SetCurrentPanelGammaSource(kGammaCalibration);
+
+  DLOGI("Display created with id: %" PRIu64 ", game_supported_: %d", id_, game_supported_);
 
   return 0;
 }
@@ -682,6 +684,7 @@
   metadata_refresh_rate_ = 0;
   layer_stack_.flags.animating = animating_;
   layer_stack_.flags.fast_path = fast_path_enabled_ && fast_path_composition_;
+  hdr_largest_layer_px_ = 0.0f;
 
   DTRACE_SCOPED();
   // Add one layer for fb target
@@ -703,6 +706,10 @@
       layer->flags.skip = true;
     }
 
+    if (hwc_layer->IsColorTransformSet()) {
+      layer->flags.skip = true;
+    }
+
     // set default composition as GPU for SDM
     layer->composition = kCompositionGPU;
 
@@ -754,6 +761,11 @@
       // Dont honor HDR when its handling is disabled
       layer->input_buffer.flags.hdr = true;
       layer_stack_.flags.hdr_present = true;
+
+      // HDR area
+      auto hdr_layer_area = (layer->dst_rect.right - layer->dst_rect.left) *
+                            (layer->dst_rect.bottom - layer->dst_rect.top);
+      hdr_largest_layer_px_ = std::max(hdr_largest_layer_px_, hdr_layer_area);
     }
 
     if (game_supported_ && (hwc_layer->GetType() == kLayerGame)) {
@@ -902,7 +914,7 @@
 }
 
 HWC2::Error HWCDisplay::SetVsyncEnabled(HWC2::Vsync enabled) {
-  DLOGV("Display ID: %" PRId64 " enabled: %s", id_, to_string(enabled).c_str());
+  DLOGV("Display ID: %" PRIu64 " enabled: %s", id_, to_string(enabled).c_str());
   ATRACE_INT("SetVsyncState ", enabled == HWC2::Vsync::Enable ? 1 : 0);
   DisplayError error = kErrorNone;
 
@@ -955,7 +967,7 @@
 }
 
 HWC2::Error HWCDisplay::SetPowerMode(HWC2::PowerMode mode, bool teardown) {
-  DLOGV("display = %" PRId64 ", mode = %s", id_, to_string(mode).c_str());
+  DLOGV("display = %" PRIu64 ", mode = %s", id_, to_string(mode).c_str());
   DisplayState state = kStateOff;
   bool flush_on_error = flush_on_error_;
 
@@ -1380,7 +1392,7 @@
       if (event_handler_) {
         event_handler_->DisplayPowerReset();
       } else {
-        DLOGW("Cannot execute DisplayPowerReset (client_id = %" PRId64 "), event_handler_ is null",
+        DLOGW("Cannot execute DisplayPowerReset (client_id = %" PRIu64 "), event_handler_ is null",
               id_);
       }
     } break;
@@ -2367,6 +2379,8 @@
         << std::endl;
   }
 
+  *os << "\npanel gamma source: " << GetCurrentPanelGammaSource() << std::endl;
+
   if (layer_stack_invalid_) {
     *os << "\n Layers added or removed but not reflected to SDM's layer stack yet\n";
     return;
@@ -2813,7 +2827,6 @@
 
   validated_ = false;
   SetActiveConfigIndex(config);
-  DLOGI("Active configuration changed to: %d", config);
 
   return HWC2::Error::None;
 }
@@ -2838,6 +2851,20 @@
   return active_config_index_;
 }
 
+HWC2::Error HWCDisplay::GetSupportedContentTypes(hidl_vec<HwcContentType> *types) {
+  types = {};
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplay::SetContentType(HwcContentType type) {
+  if (type == HwcContentType::NONE) {
+    return HWC2::Error::None;
+  }
+
+  return HWC2::Error::Unsupported;
+}
+
 HWC2::Error HWCDisplay::GetClientTargetProperty(ClientTargetProperty *out_client_target_property) {
 
   Layer *client_layer = client_target_->GetSDMLayer();
@@ -2868,4 +2895,4 @@
   return HWC2::Error::None;
 }
 
-} //namespace sdm
+}  // namespace sdm
diff --git a/composer/hwc_display.h b/composer/hwc_display.h
index 1172453..e55dde8 100644
--- a/composer/hwc_display.h
+++ b/composer/hwc_display.h
@@ -57,6 +57,7 @@
 #define __HWC_DISPLAY_H__
 
 #include <QService.h>
+#include <aidl/com/google/hardware/pixel/display/BnDisplay.h>
 #include <android/hardware/graphics/common/1.2/types.h>
 #include <core/core_interface.h>
 #include <hardware/hwcomposer.h>
@@ -79,6 +80,7 @@
 #include "hwc_layers.h"
 #include "hwc_buffer_sync_handler.h"
 
+using android::hardware::hidl_vec;
 using android::hardware::graphics::common::V1_2::ColorMode;
 using android::hardware::graphics::common::V1_2::Dataspace;
 using android::hardware::graphics::common::V1_1::RenderIntent;
@@ -88,6 +90,9 @@
 using VsyncPeriodChangeConstraints = composer_V2_4::IComposerClient::VsyncPeriodChangeConstraints;
 using VsyncPeriodChangeTimeline = composer_V2_4::VsyncPeriodChangeTimeline;
 using VsyncPeriodNanos = composer_V2_4::VsyncPeriodNanos;
+using HwcContentType = composer_V2_4::IComposerClient::ContentType;
+using HbmState = ::aidl::com::google::hardware::pixel::display::HbmState;
+using LbeState = ::aidl::com::google::hardware::pixel::display::LbeState;
 using ClientTargetProperty = composer_V2_4::IComposerClient::ClientTargetProperty;
 
 namespace sdm {
@@ -193,6 +198,17 @@
     kSkipValidate,
   };
 
+  enum PanelGammaSource {
+    kGammaDefault,      // Resotre gamma table to default
+    kGammaCalibration,  // Update gamma table from calibration file
+  };
+
+  enum HbmClient {
+    HWC = 0,
+    APP,
+    CLIENT_MAX,
+  };
+
   struct HWCLayerStack {
     HWCLayer *client_target = nullptr;                   // Also known as framebuffer target
     std::map<hwc2_layer_t, HWCLayer *> layer_map;        // Look up by Id - TODO
@@ -223,6 +239,8 @@
   virtual DisplayError SetMixerResolution(uint32_t width, uint32_t height);
   virtual DisplayError GetMixerResolution(uint32_t *width, uint32_t *height);
   virtual void GetPanelResolution(uint32_t *width, uint32_t *height);
+  virtual DisplayError SetCurrentPanelGammaSource(enum PanelGammaSource /*source*/) { return kErrorNotSupported; }
+  virtual PanelGammaSource GetCurrentPanelGammaSource() const { return kGammaDefault; };
   virtual void Dump(std::ostringstream *os);
   virtual DisplayError TeardownConcurrentWriteback(void) {
     return kErrorNotSupported;
@@ -471,12 +489,19 @@
   virtual HWC2::Error SetActiveConfigWithConstraints(
       hwc2_config_t config, const VsyncPeriodChangeConstraints *vsync_period_change_constraints,
       VsyncPeriodChangeTimeline *out_timeline);
+  virtual HWC2::Error SetAutoLowLatencyMode(bool on) { return HWC2::Error::Unsupported; }
+  virtual HWC2::Error GetSupportedContentTypes(hidl_vec<HwcContentType> *types);
+  virtual HWC2::Error SetContentType(HwcContentType type);
 
   HWC2::Error SetDisplayElapseTime(uint64_t time);
   virtual bool HasReadBackBufferSupport() { return false; }
   virtual bool IsDisplayIdle() { return false; };
   virtual HWC2::Error GetClientTargetProperty(ClientTargetProperty *out_client_target_property);
 
+  virtual bool IsHbmSupported() { return false; }
+  virtual HWC2::Error SetHbm(HbmState state, HbmClient client) { return HWC2::Error::None; }
+  virtual HbmState GetHbm() { return HbmState::OFF; }
+
  protected:
   static uint32_t throttling_refresh_rate_;
   // Maximum number of layers supported by display manager.
@@ -592,6 +617,7 @@
   std::mutex transient_refresh_rate_lock_;
   std::mutex active_config_lock_;
   int active_config_index_ = -1;
+  float hdr_largest_layer_px_ = 0.0f;
   LayerRect window_rect_ = {};
   bool windowed_display_ = false;
   uint32_t active_refresh_rate_ = 0;
diff --git a/composer/hwc_display_builtin.cpp b/composer/hwc_display_builtin.cpp
index 5c29416..69e8a04 100644
--- a/composer/hwc_display_builtin.cpp
+++ b/composer/hwc_display_builtin.cpp
@@ -63,15 +63,18 @@
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <android-base/file.h>
 #include <cutils/properties.h>
-#include <sync/sync.h>
+#include <cutils/sockets.h>
 #include <utils/constants.h>
 #include <utils/debug.h>
 #include <utils/utils.h>
 #include <stdarg.h>
+#include <sync/sync.h>
 #include <sys/mman.h>
 
 #include <map>
+#include <iostream>
 #include <string>
 #include <vector>
 
@@ -90,6 +93,77 @@
   target->bottom = src_rect.bottom;
 }
 
+static std::string LoadPanelGammaCalibration() {
+  constexpr char file[] = "/mnt/vendor/persist/display/gamma_calib_data.cal";
+  std::ifstream ifs(file);
+
+  if (!ifs.is_open()) {
+    DLOGW("Unable to open gamma calibration '%s', error = %s", file, strerror(errno));
+    return {};
+  }
+
+  std::string raw_data, gamma;
+  while (std::getline(ifs, raw_data, '\r')) {
+    gamma.append(raw_data.c_str());
+    gamma.append(" ");
+    std::getline(ifs, raw_data);
+  }
+  ifs.close();
+
+  /* eliminate space character in the last byte */
+  if (!gamma.empty()) {
+    gamma.pop_back();
+  }
+
+  return gamma;
+}
+
+static DisplayError WritePanelGammaTableToDriver(const std::string &gamma_data) {
+  constexpr char gamma_path[] = "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/gamma";
+  int fd = open(gamma_path, O_WRONLY);
+  if (fd < 0) {
+    DLOGW("Unable to open gamma node '%s', error = %s", gamma_path, strerror(errno));
+    return kErrorFileDescriptor;
+  }
+
+  constexpr int max_retries = 5;
+  ssize_t len;
+  int retry_count = 0;
+  DisplayError error = kErrorNone;
+  while ((len = pwrite(fd, gamma_data.c_str(), gamma_data.size(), 0)) != gamma_data.size()) {
+    if ((len == -1 && errno != EINTR && errno != EAGAIN) || (++retry_count > max_retries)) {
+      DLOGE("Failed to write gamma calibration(retry %d), error = %s", retry_count,
+            strerror(errno));
+      break;
+    }
+  }
+  close(fd);
+
+  if (len != gamma_data.size()) {
+    error = kErrorResources;
+  }
+
+  return error;
+}
+
+static DisplayError UpdatePanelGammaTable(enum HWCDisplay::PanelGammaSource source) {
+  std::string gamma_data = {};
+  DisplayError error;
+  if (source == HWCDisplay::kGammaDefault) {
+    gamma_data = "default";
+  } else if (source == HWCDisplay::kGammaCalibration) {
+    gamma_data = LoadPanelGammaCalibration();
+  }
+
+  if (!gamma_data.empty()) {
+    error = WritePanelGammaTableToDriver(gamma_data);
+  } else {
+    error = kErrorParameters;
+  }
+
+  return error;
+}
+
 int HWCDisplayBuiltIn::Create(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
                               HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
                               qService::QService *qservice, hwc2_display_t id, int32_t sdm_id,
@@ -194,6 +268,7 @@
   value = 0;
   DebugHandler::Get()->GetProperty(DISABLE_DYNAMIC_FPS, &value);
   disable_dyn_fps_ = (value == 1);
+  DLOGI("disable_dyn_fps_: %d", disable_dyn_fps_);
 
   uint32_t config_index = 0;
   GetActiveDisplayConfig(&config_index);
@@ -203,10 +278,10 @@
 
   DLOGI("active_refresh_rate: %d", active_refresh_rate_);
 
-  int enhance_idle_time = 0;
-  HWCDebugHandler::Get()->GetProperty(ENHANCE_IDLE_TIME, &enhance_idle_time);
-  enhance_idle_time_ = (enhance_idle_time == 1);
-  DLOGI("enhance_idle_time: %d", enhance_idle_time);
+  value = 0;
+  HWCDebugHandler::Get()->GetProperty(ENHANCE_IDLE_TIME, &value);
+  enhance_idle_time_ = (value == 1);
+  DLOGI("enhance_idle_time: %d", enhance_idle_time_);
 
   HWCDebugHandler::Get()->GetProperty(PERF_HINT_WINDOW_PROP, &perf_hint_window_);
   HWCDebugHandler::Get()->GetProperty(ENABLE_PERF_HINT_LARGE_COMP_CYCLE,
@@ -568,6 +643,26 @@
     }
   }
 
+  if (CC_UNLIKELY(!has_config_hbm_threshold_)) {
+    uint32_t panel_x, panel_y;
+    GetPanelResolution(&panel_x, &panel_y);
+    hbm_threshold_px_ = float(panel_x * panel_y) * hbm_threshold_pct_;
+    DLOGI("Configure hbm_threshold_px_ to %f", hbm_threshold_px_);
+
+    has_config_hbm_threshold_ = true;
+  }
+
+  const bool enable_hbm(hdr_largest_layer_px_ > hbm_threshold_px_);
+  if (high_brightness_mode_ != enable_hbm) {
+    HbmState state = enable_hbm ? HbmState::HDR : HbmState::OFF;
+    auto status = SetHbm(state, HWC);
+    if (status == HWC2::Error::None) {
+      high_brightness_mode_ = enable_hbm;
+    } else {
+      DLOGE("failed to setHbm to %d", enable_hbm);
+    }
+  }
+
   pending_commit_ = false;
 
   // In case of scaling UI layer for command mode, reset validate
@@ -1466,6 +1561,15 @@
   return HWC2::Error::None;
 }
 
+DisplayError HWCDisplayBuiltIn::SetCurrentPanelGammaSource(enum PanelGammaSource source) {
+  DisplayError error = UpdatePanelGammaTable(source);
+  if (error == kErrorNone) {
+    current_panel_gamma_source_ = source;
+  }
+
+  return error;
+}
+
 HWC2::Error HWCDisplayBuiltIn::SetBLScale(uint32_t level) {
   DisplayError ret = display_intf_->SetBLScale(level);
   if (ret != kErrorNone) {
@@ -1702,8 +1806,7 @@
 uint32_t HWCDisplayBuiltIn::GetUpdatingAppLayersCount() {
   uint32_t updating_count = 0;
 
-  for (uint i = 0; i < layer_stack_.layers.size(); i++) {
-    auto layer = layer_stack_.layers.at(i);
+  for (auto layer:layer_stack_.layers) {
     if (layer->composition == kCompositionGPUTarget) {
       break;
     }
@@ -1745,4 +1848,73 @@
   }
 }
 
+HWC2::Error HWCDisplayBuiltIn::ApplyHbmLocked() {
+  if (!mHasHbmNode)
+    return HWC2::Error::Unsupported;
+
+  HbmState state = HbmState::OFF;
+  for (auto req : mHbmSates) {
+    if (req == HbmState::SUNLIGHT) {
+      state = HbmState::SUNLIGHT;
+      break;
+    } else if (req == HbmState::HDR) {
+      state = HbmState::HDR;
+    }
+  }
+
+  if (state == mCurHbmState)
+    return HWC2::Error::None;
+
+  std::string action = std::to_string(static_cast<int>(state));
+  if (!android::base::WriteStringToFile(action, kHighBrightnessModeNode)) {
+    DLOGE("Failed to write hbm node = %s, error = %s ", kHighBrightnessModeNode, strerror(errno));
+  } else {
+    DLOGI("write %s to HBM sysfs file succeeded", action.c_str());
+  }
+
+  mCurHbmState = state;
+
+  return HWC2::Error::None;
+}
+
+bool HWCDisplayBuiltIn::IsHbmSupported() {
+  if (!mHasHbmNode)
+    return false;
+
+  bool is_hbm_supported = false;
+  std::string buffer;
+  if (!android::base::ReadFileToString(kHighBrightnessModeNode, &buffer)) {
+    DLOGE("Failed to read hbm node = %s, error = %s ", kHighBrightnessModeNode, strerror(errno));
+  } else if (buffer == "unsupported") {
+    DLOGI("kernel driver does not support hbm");
+  } else {
+    is_hbm_supported = true;
+  }
+
+  return is_hbm_supported;
+}
+
+HWC2::Error HWCDisplayBuiltIn::SetHbm(HbmState state, HbmClient client) {
+  auto status = HWC2::Error::None;
+  if (client >= CLIENT_MAX)
+    return HWC2::Error::BadParameter;
+
+  std::unique_lock<decltype(hbm_mutex)> lk(hbm_mutex);
+
+  /* save and apply the request state */
+  if (mHbmSates[client] != state) {
+    mHbmSates[client] = state;
+
+    status = ApplyHbmLocked();
+    if (INT32(status) != HWC2_ERROR_NONE)
+      DLOGE("Failed to apply hbm node, error = %d", status);
+  }
+
+  return status;
+}
+
+HbmState HWCDisplayBuiltIn::GetHbm() {
+  return mCurHbmState;
+}
+
 }  // namespace sdm
diff --git a/composer/hwc_display_builtin.h b/composer/hwc_display_builtin.h
index 47ab9c7..e71de42 100644
--- a/composer/hwc_display_builtin.h
+++ b/composer/hwc_display_builtin.h
@@ -68,6 +68,7 @@
 
 #include <thermal_client.h>
 #include <mutex>
+#include <limits>
 #include <string>
 #include <vector>
 
@@ -157,6 +158,8 @@
   virtual HWC2::Error SetPanelBrightness(float brightness);
   virtual HWC2::Error GetPanelBrightness(float *brightness);
   virtual HWC2::Error GetPanelMaxBrightness(uint32_t *max_brightness_level);
+  virtual DisplayError SetCurrentPanelGammaSource(enum PanelGammaSource source) override;
+  virtual PanelGammaSource GetCurrentPanelGammaSource() const override { return current_panel_gamma_source_; };
   virtual DisplayError TeardownConcurrentWriteback(void);
   virtual void SetFastPathComposition(bool enable) {
     fast_path_composition_ = enable && !readback_buffer_queued_;
@@ -187,6 +190,10 @@
   virtual bool HasReadBackBufferSupport();
   virtual bool IsDisplayIdle();
 
+  virtual bool IsHbmSupported() override;
+  virtual HWC2::Error SetHbm(HbmState state, HbmClient client) override;
+  virtual HbmState GetHbm() override;
+
  private:
   HWCDisplayBuiltIn(CoreInterface *core_intf, BufferAllocator *buffer_allocator,
                     HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
@@ -218,6 +225,7 @@
   void SetPartialUpdate(DisplayConfigFixedInfo fixed_info);
   uint32_t GetUpdatingAppLayersCount();
   void ValidateUiScaling();
+  HWC2::Error ApplyHbmLocked() REQUIRES(hbm_mutex);
 
   // SyncTask methods.
   void OnTask(const LayerStitchTaskCode &task_code,
@@ -255,6 +263,8 @@
   BufferInfo buffer_info_ = {};
   DisplayConfigVariableInfo fb_config_ = {};
 
+  enum PanelGammaSource current_panel_gamma_source_ = kGammaDefault;
+
   bool qsync_enabled_ = false;
   bool qsync_reconfigured_ = false;
   // Members for Color sampling feature
@@ -278,6 +288,18 @@
   // NULL display
   DisplayNull display_null_;
   DisplayInterface *stored_display_intf_ = NULL;
+
+  // Members for HBM feature
+  static constexpr const char kHighBrightnessModeNode[] =
+      "/sys/class/backlight/panel0-backlight/hbm_mode";
+  static constexpr float hbm_threshold_pct_ = 0.5f;
+  const bool mHasHbmNode = !access(kHighBrightnessModeNode, F_OK);
+  std::mutex hbm_mutex;
+  float hbm_threshold_px_ = std::numeric_limits<float>::max();
+  bool has_config_hbm_threshold_ = false;
+  bool high_brightness_mode_ = false;
+  HbmState mHbmSates[CLIENT_MAX] GUARDED_BY(hbm_mutex) = {HbmState::OFF};
+  HbmState mCurHbmState GUARDED_BY(hbm_mutex) = HbmState::OFF;
 };
 
 }  // namespace sdm
diff --git a/composer/hwc_layers.cpp b/composer/hwc_layers.cpp
index a2c4227..ca13df4 100644
--- a/composer/hwc_layers.cpp
+++ b/composer/hwc_layers.cpp
@@ -324,8 +324,8 @@
   if (!buffer) {
     if (client_requested_ == HWC2::Composition::Device ||
         client_requested_ == HWC2::Composition::Cursor) {
-      DLOGW("Invalid buffer handle: %p on layer: %d client requested comp type %d", buffer,
-            UINT32(id_), client_requested_);
+      DLOGW("Invalid buffer handle: %p on layer: %" PRIu64 " client requested comp type %d", buffer,
+            id_, client_requested_);
       return HWC2::Error::BadParameter;
     } else {
       return HWC2::Error::None;
@@ -868,6 +868,7 @@
       format = kFormatYCrCb420PlanarStride16;
       break;
     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_NV21_ZSL:
       format = kFormatYCrCb420SemiPlanar;
       break;
     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
@@ -1068,8 +1069,8 @@
         layer_buffer->color_metadata.matrixCoefficients = new_metadata.matrixCoefficients;
         layer_->update_mask.set(kMetadataUpdate);
       }
-      DLOGV_IF(kTagClient, "Layer id = %d ColorVolEnabled = %d ContentLightLevelEnabled = %d "
-               "cRIEnabled = %d Dynamic Metadata valid = %d size = %d", UINT32(id_),
+      DLOGV_IF(kTagClient, "Layer id = %" PRIu64 " ColorVolEnabled = %d ContentLightLevelEnabled = %d "
+               "cRIEnabled = %d Dynamic Metadata valid = %d size = %d", id_,
                new_metadata.masteringDisplayInfo.colorVolumeSEIEnabled,
                new_metadata.contentLightLevel.lightLevelSEIEnabled,
                new_metadata.cRI.criEnabled, new_metadata.dynamicMetaDataValid,
diff --git a/composer/hwc_session.cpp b/composer/hwc_session.cpp
index fc50018..3895dec 100644
--- a/composer/hwc_session.cpp
+++ b/composer/hwc_session.cpp
@@ -77,6 +77,7 @@
 #include <string>
 #include <thread>
 #include <vector>
+#include <cutils/sockets.h>
 
 #include "hwc_buffer_allocator.h"
 #include "hwc_session.h"
@@ -88,6 +89,7 @@
 #define HWC_UEVENT_DRM_EXT_HOTPLUG "mdss_mdp/drm/card"
 
 using HwcAttribute = composer_V2_4::IComposerClient::Attribute;
+extern void DisplayInit(sdm::HWCSession *hwc_session);
 
 namespace sdm {
 
@@ -134,7 +136,7 @@
   if (!status) {
     std::unique_lock<std::mutex> caller_lock(hwc_uevent->mutex_);
     hwc_uevent->caller_cv_.notify_one();
-    DLOGE("Failed to init uevent with err %d", status);
+    ALOGE("Failed to init uevent with err %d", status);
     return;
   }
 
@@ -210,9 +212,12 @@
     return -EINVAL;
   }
 
+  DisplayInit(this);
+
   HWCDebugHandler::Get()->GetProperty(ENABLE_NULL_DISPLAY_PROP, &null_display_mode_);
   HWCDebugHandler::Get()->GetProperty(DISABLE_HOTPLUG_BWCHECK, &disable_hotplug_bwcheck_);
   HWCDebugHandler::Get()->GetProperty(DISABLE_MASK_LAYER_HINT, &disable_mask_layer_hint_);
+  HWCDebugHandler::Get()->GetProperty(LBE_SUPPORTED, &is_lbe_supported_);
 
   if (!null_display_mode_) {
     g_hwc_uevent_.Register(this);
@@ -257,6 +262,9 @@
 }
 
 int HWCSession::Deinit() {
+  if (pps_socket_ >= 0)
+    close(pps_socket_);
+
   // Destroy all connected displays
   DestroyDisplay(&map_info_primary_);
 
@@ -864,8 +872,8 @@
   for (size_t i = 0; i < pending_refresh_.size(); i++) {
     if (pending_refresh_.test(i)) {
       callbacks_.Refresh(i);
+      break;
     }
-    break;
   }
 
   pending_refresh_.reset();
@@ -1683,6 +1691,23 @@
       status = SetIdlePC(input_parcel);
       break;
 
+    case qService::IQService::SET_DISPLAY_DEVICE_STATUS:
+      if (!input_parcel) {
+        DLOGE("QService command = %d: input_parcel needed.", command);
+        break;
+      }
+      status = SetDisplayDeviceStatus(input_parcel);
+      break;
+
+    case qService::IQService::SET_PANEL_GAMMA_TABLE_SOURCE:
+      if (!input_parcel || !output_parcel) {
+        DLOGE("QService command = %d: input_parcel and output_parcel needed.", command);
+        break;
+      }
+      status = SetPanelGammaTableSource(input_parcel);
+      output_parcel->writeInt32(status);
+      break;
+
     case qService::IQService::SET_DPPS_AD4_ROI_CONFIG:
       if (!input_parcel) {
         DLOGE("QService command = %d: input_parcel needed.", command);
@@ -1775,6 +1800,52 @@
   return status;
 }
 
+android::status_t HWCSession::SetDisplayDeviceStatus(const android::Parcel *input_parcel) {
+  int dpy = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+  auto disp_status = static_cast<HWCDisplay::DisplayStatus>(input_parcel->readInt32());
+
+  int disp_idx = GetDisplayIndex(dpy);
+  if (disp_idx == -1) {
+    DLOGE("Invalid display = %d", dpy);
+    return android::BAD_VALUE;
+  }
+
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
+  if (hwc_display_[disp_idx]) {
+    error = hwc_display_[disp_idx]->SetDisplayStatus(disp_status);
+    if (error != android::OK)
+      DLOGW("Set display %d status to %d failed with error %d", dpy, disp_status, error);
+  } else {
+    DLOGW("No display %d active", dpy);
+  }
+
+  return error;
+}
+
+android::status_t HWCSession::SetPanelGammaTableSource(const android::Parcel *input_parcel) {
+  int dpy = input_parcel->readInt32();
+  int error = android::BAD_VALUE;
+  auto source = static_cast<HWCDisplay::PanelGammaSource>(input_parcel->readInt32());
+
+  int disp_idx = GetDisplayIndex(dpy);
+  if (disp_idx == -1) {
+    DLOGE("Invalid display = %d", dpy);
+    return android::BAD_VALUE;
+  }
+
+  SEQUENCE_WAIT_SCOPE_LOCK(locker_[disp_idx]);
+  if (hwc_display_[disp_idx]) {
+    error = hwc_display_[disp_idx]->SetCurrentPanelGammaSource(source);
+    if (error != android::OK)
+      DLOGW("Set display %d gamma source to %d failed with error %d", dpy, source, error);
+  } else {
+    DLOGW("No display %d active", dpy);
+  }
+
+  return error;
+}
+
 android::status_t HWCSession::getComposerStatus() {
   return is_composer_up_;
 }
@@ -3419,42 +3490,8 @@
                              outDataSize, outData);
 }
 
-int32_t HWCSession::GetDisplayCapabilities(hwc2_display_t display,
-                                           hidl_vec<HwcDisplayCapability> *capabilities) {
-  if (!capabilities) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  if (display >= HWCCallbacks::kNumDisplays) {
-    return HWC2_ERROR_BAD_DISPLAY;
-  }
-
-  if (!hwc_display_[display]) {
-    DLOGE("Expected valid hwc_display");
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  bool isBuiltin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
-  if (isBuiltin) {
-    int32_t has_doze_support = 0;
-    GetDozeSupport(display, &has_doze_support);
-
-    // TODO(user): Handle SKIP_CLIENT_COLOR_TRANSFORM based on DSPP availability
-    if (has_doze_support) {
-      *capabilities = {HwcDisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM,
-                       HwcDisplayCapability::DOZE,
-                       HwcDisplayCapability::BRIGHTNESS, HwcDisplayCapability::PROTECTED_CONTENTS};
-    } else {
-      *capabilities = {HwcDisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM,
-                       HwcDisplayCapability::BRIGHTNESS, HwcDisplayCapability::PROTECTED_CONTENTS};
-    }
-  }
-
-  return HWC2_ERROR_NONE;
-}
-
-int32_t HWCSession::GetDisplayCapabilities2_3(hwc2_display_t display, uint32_t *outNumCapabilities,
-                                              uint32_t *outCapabilities) {
+int32_t HWCSession::GetDisplayCapabilities(hwc2_display_t display, uint32_t *outNumCapabilities,
+                                           uint32_t *outCapabilities) {
   if (!outNumCapabilities) {
     return HWC2_ERROR_BAD_PARAMETER;
   }
@@ -3467,27 +3504,49 @@
     DLOGE("Expected valid hwc_display");
     return HWC2_ERROR_BAD_PARAMETER;
   }
+
   bool isBuiltin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
-  if (!outCapabilities) {
-    *outNumCapabilities = 0;
-    if (isBuiltin) {
-      *outNumCapabilities = 2;
-    }
-    return HWC2_ERROR_NONE;
-  } else {
-    if (isBuiltin) {
-      uint32_t index = 0;
-      int32_t has_doze_support = 0;
-      GetDozeSupport(display, &has_doze_support);
-      if (has_doze_support) {
-        outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_DOZE;
-      }
-      outCapabilities[index++] = HWC2_DISPLAY_CAPABILITY_BRIGHTNESS;
-      *outNumCapabilities = index;
+  *outNumCapabilities = 0;
+  if (isBuiltin) {
+    *outNumCapabilities = 3;
+    if (outCapabilities != nullptr) {
+      // TODO(user): Handle SKIP_CLIENT_COLOR_TRANSFORM based on DSPP availability
+      outCapabilities[0] = static_cast<uint32_t>(HwcDisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
+      outCapabilities[1] = static_cast<uint32_t>(HwcDisplayCapability::DOZE);
+      outCapabilities[2] = static_cast<uint32_t>(HwcDisplayCapability::BRIGHTNESS);
     }
   }
+
   return HWC2_ERROR_NONE;
 }
+
+int32_t HWCSession::GetDisplayCapabilities_2_4(hwc2_display_t display, uint32_t *outNumCapabilities,
+                                               uint32_t *outCapabilities) {
+  if (!outNumCapabilities) {
+    return HWC2_ERROR_BAD_PARAMETER;
+  }
+
+  if (display >= HWCCallbacks::kNumDisplays) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  if (!hwc_display_[display]) {
+    DLOGE("Expected valid hwc_display");
+    return HWC2_ERROR_BAD_PARAMETER;
+  }
+
+  bool isBuiltin = (hwc_display_[display]->GetDisplayClass() == DISPLAY_CLASS_BUILTIN);
+  *outNumCapabilities = 0;
+  if (isBuiltin) {
+    *outNumCapabilities = 1;
+    if (outCapabilities != nullptr) {
+      outCapabilities[0] = static_cast<uint32_t>(HwcDisplayCapability::PROTECTED_CONTENTS);
+    }
+  }
+
+  return HWC2_ERROR_NONE;
+}
+
 int32_t HWCSession::GetDisplayConnectionType(hwc2_display_t display,
                                              HwcDisplayConnectionType *type) {
   if (display >= HWCCallbacks::kNumDisplays) {
@@ -3713,6 +3772,142 @@
                              vsync_period_change_constraints, out_timeline);
 }
 
+int32_t HWCSession::SetAutoLowLatencyMode(hwc2_display_t display, bool on) {
+  if (display >= HWCCallbacks::kNumDisplays) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  return CallDisplayFunction(display, &HWCDisplay::SetAutoLowLatencyMode, on);
+}
+
+int32_t HWCSession::GetSupportedContentTypes(hwc2_display_t display,
+                                             hidl_vec<HwcContentType> *types) {
+  if (display >= HWCCallbacks::kNumDisplays) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  return CallDisplayFunction(display, &HWCDisplay::GetSupportedContentTypes, types);
+}
+
+int32_t HWCSession::SetContentType(hwc2_display_t display, HwcContentType type) {
+  if (display >= HWCCallbacks::kNumDisplays) {
+    return HWC2_ERROR_BAD_DISPLAY;
+  }
+
+  return CallDisplayFunction(display, &HWCDisplay::SetContentType, type);
+}
+
+bool HWCSession::IsHbmSupported() {
+  auto hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
+  if (hwc_display)
+    return hwc_display->IsHbmSupported();
+
+  return 0;
+}
+
+void HWCSession::SetHbmState(HbmState state) {
+  CallDisplayFunction(HWC_DISPLAY_PRIMARY, &HWCDisplay::SetHbm, state, HWCDisplay::APP);
+}
+
+HbmState HWCSession::GetHbmState() {
+  auto hwc_display = hwc_display_[HWC_DISPLAY_PRIMARY];
+
+  if (hwc_display)
+    return hwc_display->GetHbm();
+
+  return HbmState::OFF;
+}
+
+bool HWCSession::IsLbeSupported() {
+  return (is_lbe_supported_ != 0);
+}
+
+void HWCSession::SetLbeState(LbeState state) {
+  std::string_view state_cmd;
+  int ret = 0;
+
+  if (!is_lbe_supported_) {
+    DLOGE("lbe is not supported");
+    return;
+  }
+
+  if (lbe_cur_state_ == state)
+    return;
+
+  switch (state) {
+    case LbeState::OFF:
+      state_cmd = ltm_off_cmd_;
+      break;
+    case LbeState::NORMAL:
+      state_cmd = ltm_default_mode_cmd_;
+      break;
+    case LbeState::HIGH_BRIGHTNESS:
+      state_cmd = ltm_hbm_mode_cmd_;
+      break;
+    case LbeState::POWER_SAVE:
+      state_cmd = ltm_power_save_mode_cmd_;
+      break;
+    default:
+      DLOGE("lbe mode not support");
+      return;
+  }
+
+  if (lbe_cur_state_ == LbeState::OFF) {
+    std::string_view on_cmd = ltm_on_cmd_;
+    ret = SendLTMCommand(on_cmd.data());
+    if (ret) {
+      DLOGE("failed to enable lbe");
+      return;
+    }
+  }
+
+  ret = SendLTMCommand(state_cmd.data());
+  if (!ret)
+    lbe_cur_state_ = state;
+}
+
+void HWCSession::SetLbeAmbientLight(int value) {
+  if (!is_lbe_supported_ || value < 0 || (lbe_cur_state_ == LbeState::OFF))
+    return;
+
+  std::string cmd = ltm_lux_cmd_;
+  std::string val = std::to_string(value);
+
+  cmd += val;
+
+  SendLTMCommand(cmd.c_str());
+}
+
+LbeState HWCSession::GetLbeState() {
+  return lbe_cur_state_;
+}
+
+int HWCSession::SendLTMCommand(const char *cmd) {
+  if (!cmd || !pps_retry)
+    return -EINVAL;
+
+  while ((pps_retry > 0) && (pps_socket_ < 0)) {
+    pps_socket_ = socket_local_client("pps", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
+    if (pps_socket_ < 0) {
+      pps_retry--;
+      if (pps_retry == 0) {
+        DLOGE("Connecting to pps socket failed, error = %s", strerror(errno));
+        return -ETIMEDOUT;
+      }
+    }
+  }
+
+  int ret = write(pps_socket_, cmd, strlen(cmd));
+  if (ret < 0) {
+    DLOGE("Failed to send LTM cmd, error = %s", strerror(errno));
+    return -EINVAL;
+  }
+  usleep(1000);
+
+  return 0;
+}
+
 void HWCSession::SetCpuPerfHintLargeCompCycle() {
   bool found_non_primary_active_display = false;
 
diff --git a/composer/hwc_session.h b/composer/hwc_session.h
index bbe6c75..9355c82 100644
--- a/composer/hwc_session.h
+++ b/composer/hwc_session.h
@@ -88,13 +88,10 @@
 using ::android::hardware::Return;
 using ::android::hardware::hidl_string;
 using android::hardware::hidl_handle;
-using ::android::hardware::hidl_vec;
 using ::android::sp;
 using ::android::hardware::Void;
 namespace composer_V2_4 = ::android::hardware::graphics::composer::V2_4;
-namespace composer_V2_3 = ::android::hardware::graphics::composer::V2_3;
 using HwcDisplayCapability = composer_V2_4::IComposerClient::DisplayCapability;
-using HwcDisplayCapability_2_3 = composer_V2_3::IComposerClient::DisplayCapability;
 using HwcDisplayConnectionType = composer_V2_4::IComposerClient::DisplayConnectionType;
 using HwcClientTargetProperty = composer_V2_4::IComposerClient::ClientTargetProperty;
 
@@ -238,6 +235,10 @@
   uint32_t GetMaxVirtualDisplayCount();
   int32_t GetDisplayIdentificationData(hwc2_display_t display, uint8_t *outPort,
                                        uint32_t *outDataSize, uint8_t *outData);
+  int32_t GetDisplayCapabilities(hwc2_display_t display, uint32_t *outNumCapabilities,
+                                 uint32_t *capabilities);
+  int32_t GetDisplayCapabilities_2_4(hwc2_display_t display, uint32_t *outNumCapabilities,
+                                     uint32_t *capabilities);
   int32_t GetDisplayCapabilities(hwc2_display_t display,
                                  hidl_vec<HwcDisplayCapability> *capabilities);
   int32_t GetDisplayCapabilities2_3(hwc2_display_t display,
@@ -336,12 +337,25 @@
       const VsyncPeriodChangeConstraints *vsync_period_change_constraints,
       VsyncPeriodChangeTimeline *out_timeline);
 
+  int32_t SetAutoLowLatencyMode(hwc2_display_t display, bool on);
+  int32_t GetSupportedContentTypes(hwc2_display_t display, hidl_vec<HwcContentType> *types);
+  int32_t SetContentType(hwc2_display_t display, HwcContentType type);
+
   static Locker locker_[HWCCallbacks::kNumDisplays];
   static Locker power_state_[HWCCallbacks::kNumDisplays];
   static Locker hdr_locker_[HWCCallbacks::kNumDisplays];
   static Locker display_config_locker_;
   static Locker system_locker_;
 
+  void RegisterDisplayCallback();
+  bool IsHbmSupported();
+  void SetHbmState(HbmState state);
+  HbmState GetHbmState();
+  bool IsLbeSupported();
+  void SetLbeState(LbeState state);
+  void SetLbeAmbientLight(int value);
+  LbeState GetLbeState();
+
  private:
   class CWB {
    public:
@@ -533,6 +547,8 @@
   android::status_t DelayFirstCommit();
   android::status_t SetQSyncMode(const android::Parcel *input_parcel);
   android::status_t SetIdlePC(const android::Parcel *input_parcel);
+  android::status_t SetDisplayDeviceStatus(const android::Parcel *input_parcel);
+  android::status_t SetPanelGammaTableSource(const android::Parcel *input_parcel);
   android::status_t RefreshScreen(const android::Parcel *input_parcel);
   android::status_t SetAd4RoiConfig(const android::Parcel *input_parcel);
   android::status_t SetDsiClk(const android::Parcel *input_parcel);
@@ -560,6 +576,8 @@
   bool isSmartPanelConfig(uint32_t disp_id, uint32_t config_id);
   void PerformIdleStatusCallback(hwc2_display_t display);
 
+  int SendLTMCommand(const char *cmd);
+
   CoreInterface *core_intf_ = nullptr;
   HWCDisplay *hwc_display_[HWCCallbacks::kNumDisplays] = {nullptr};
   HWCCallbacks callbacks_;
@@ -610,6 +628,18 @@
   bool power_state_transition_[HWCCallbacks::kNumDisplays] = {};
   std::bitset<HWCCallbacks::kNumDisplays> display_ready_;
   bool secure_session_active_ = false;
+
+  int32_t is_lbe_supported_ = 0;
+  LbeState lbe_cur_state_ = LbeState::OFF;
+  int pps_socket_ = -1;
+  int8_t pps_retry = 5;
+  static constexpr const char *ltm_on_cmd_ = "Ltm:On:Primary:Auto";
+  static constexpr const char *ltm_off_cmd_ = "Ltm:Off:Primary";
+  static constexpr const char *ltm_lux_cmd_ = "Ltm:Als:Primary:";
+  static constexpr const char *ltm_default_mode_cmd_ = "Ltm:UserMode:Primary:default";
+  static constexpr const char *ltm_hbm_mode_cmd_ = "Ltm:UserMode:Primary:hbm";
+  static constexpr const char *ltm_power_save_mode_cmd_ = "Ltm:UserMode:Primary:power_save";
+  static constexpr const char *ltm_get_mode_cmd_ = "Ltm:GetUserMode:Primary";
   bool is_idle_time_up_ = false;
 };
 }  // namespace sdm
diff --git a/composer/pixel-display-default.xml b/composer/pixel-display-default.xml
new file mode 100644
index 0000000..e426172
--- /dev/null
+++ b/composer/pixel-display-default.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>com.google.hardware.pixel.display</name>
+        <fqname>IDisplay/default</fqname>
+    </hal>
+</manifest>
diff --git a/composer/pixel-display.cpp b/composer/pixel-display.cpp
new file mode 100644
index 0000000..04867da
--- /dev/null
+++ b/composer/pixel-display.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pixel-display.h"
+
+#include <utils/Errors.h>
+#include <sys/types.h>
+#include <hwc_session.h>
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+using ::aidl::com::google::hardware::pixel::display::Display;
+
+void DisplayInit(sdm::HWCSession *hwc_session) {
+    ABinderProcess_setThreadPoolMaxThreadCount(0);
+
+    std::shared_ptr<::aidl::com::google::hardware::pixel::display::Display> display =
+        ndk::SharedRefBase::make<Display>(hwc_session);
+    LOG(INFO) << "pixel display service start...";
+    const std::string instance = std::string() + Display::descriptor + "/default";
+    binder_status_t status =
+        AServiceManager_addService(display->asBinder().get(), instance.c_str());
+    CHECK(status == STATUS_OK);
+
+    ABinderProcess_startThreadPool();
+}
+
+namespace aidl {
+namespace com {
+namespace google {
+namespace hardware {
+namespace pixel {
+namespace display {
+
+// ----------------------------------------------------------------------------
+Display::Display(HWCSession *hwc_session):mHWCSession(hwc_session) {
+}
+
+ndk::ScopedAStatus Display::isHbmSupported(bool *_aidl_return) {
+    if (mHWCSession) {
+        *_aidl_return = mHWCSession->IsHbmSupported();
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::setHbmState(HbmState state) {
+    if (mHWCSession) {
+        mHWCSession->SetHbmState(state);
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::getHbmState(HbmState *_aidl_return) {
+    if (mHWCSession) {
+        *_aidl_return = mHWCSession->GetHbmState();
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::isLbeSupported(bool *_aidl_return) {
+    if (mHWCSession) {
+        *_aidl_return = mHWCSession->IsLbeSupported();
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::setLbeState(LbeState  state) {
+    if (mHWCSession) {
+        mHWCSession->SetLbeState(state);
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::setLbeAmbientLight(int ambientLux) {
+    if (mHWCSession) {
+        mHWCSession->SetLbeAmbientLight(ambientLux);
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+
+ndk::ScopedAStatus Display::getLbeState(LbeState* _aidl_return) {
+    if (mHWCSession) {
+        *_aidl_return = mHWCSession->GetLbeState();
+
+        return ndk::ScopedAStatus::ok();
+    }
+
+    return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
+}
+}  // namespace display
+}  // namespace pixel
+}  // namespace hardware
+}  // namespace google
+}  // namespace com
+}  // namespace aidl
diff --git a/composer/pixel-display.h b/composer/pixel-display.h
new file mode 100644
index 0000000..d7f5bc3
--- /dev/null
+++ b/composer/pixel-display.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <aidl/com/google/hardware/pixel/display/BnDisplay.h>
+#include <hwc_session.h>
+
+namespace aidl {
+namespace com {
+namespace google {
+namespace hardware {
+namespace pixel {
+namespace display {
+
+using sdm::HWCSession;
+
+// Default implementation
+class Display : public BnDisplay {
+  public:
+    Display(HWCSession *hwc_session);
+
+    ndk::ScopedAStatus isHbmSupported(bool *_aidl_return) override;
+    ndk::ScopedAStatus setHbmState(HbmState state) override;
+    ndk::ScopedAStatus getHbmState(HbmState *_aidl_return) override;
+    ndk::ScopedAStatus isLbeSupported(bool *_aidl_return) override;
+    ndk::ScopedAStatus setLbeState(LbeState state) override;
+    ndk::ScopedAStatus setLbeAmbientLight(int ambientLux) override;
+    ndk::ScopedAStatus getLbeState(LbeState *_aidl_return) override;
+  private:
+    HWCSession *mHWCSession = nullptr;
+};
+}  // namespace display
+}  // namespace pixel
+}  // namespace hardware
+}  // namespace google
+}  // namespace com
+}  // namespace aidl
diff --git a/composer/vendor.qti.hardware.display.composer-service.rc b/composer/vendor.qti.hardware.display.composer-service.rc
index 96e080d..55b0112 100644
--- a/composer/vendor.qti.hardware.display.composer-service.rc
+++ b/composer/vendor.qti.hardware.display.composer-service.rc
@@ -5,4 +5,4 @@
     capabilities SYS_NICE
     onrestart restart surfaceflinger
     socket pps stream 0660 system system
-    writepid /dev/cpuset/system-background/tasks
+    task_profiles ServiceCapacityLow
diff --git a/config/display-product.mk b/config/display-product.mk
index 979a17e..398a36c 100644
--- a/config/display-product.mk
+++ b/config/display-product.mk
@@ -21,58 +21,15 @@
     vendor.qti.hardware.display.mapper@2.0.vendor \
     vendor.qti.hardware.display.mapper@3.0.vendor \
     vendor.qti.hardware.display.mapper@4.0.vendor \
-    init.qti.display_boot.sh \
-    init.qti.display_boot.rc \
+    #init.qti.display_boot.sh \
+    #init.qti.display_boot.rc \
     modetest
 
-ifneq ($(TARGET_HAS_LOW_RAM),true)
-#QDCM calibration xml file for 2k panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_nt35597_cmd_mode_dsi_truly_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35597_video_mode_dsi_truly_panel_with_DSC.xml
-#QDCM calibration xml file for 4k panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_Sharp_4k_cmd_mode_dsc_dsi_panel.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_4k_cmd_mode_dsc_dsi_panel.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_Sharp_4k_cmd_mode_dsc_dsi_panel.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_4k_video_mode_dsc_dsi_panel.xml
-#QDCM calibration xml file for amoled panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_video_mode_dsi_boe_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_sw43404_amoled_cmd_mode_dsi_boe_panel_with_DSC.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sw43404_amoled_boe_fhd+_panel_with_DSC.xml
-#QDCM calibration xml file for dual panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_sharp_1080p_cmd_mode_dsi_panel.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt35695b_truly_fhd_command_mode_dsi_panel.xml
-#QDCM calibration xml file for Sharp fhd panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_fhd_cmd_mode_qsync_dsi_panel.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_fhd_video_mode_qsync_dsi_panel.xml
-#QDCM calibration xml file for Sharp 2k panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_2k_cmd_mode_qsync_dsi_panel.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_Sharp_2k_video_mode_qsync_dsi_panel.xml
-#QDCM calibration xml file for r66451 amoled panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_cmd_mode_dsi_visionox_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_cmd_mode_dsi_visionox_60HZ_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_cmd_mode_dsi_visionox_90HZ_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_cmd_mode_dsi_visionox_120HZ_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_video_mode_dsi_visionox_60HZ_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_video_mode_dsi_visionox_90HZ_panel_with_DSC.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_r66451_amoled_video_mode_dsi_visionox_120HZ_panel_with_DSC.xml
-#QDCM calibration xml file for rm69299 amoled fhd+ panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_rm69299_amoled_fhd+_video_mode_dsi_visionox_panel.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_rm69299_amoled_fhd+_cmd_mode_dsi_visionox_panel.xml
-#QDCM calibration xml file for nt36525 truly panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt36525_video_mode_dsi_truly_panel.xml
-#QDCM calibration xml file for nt36672e LCD video mode single dsi with DSC panel.
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_nt36672e_90Hz_fhd_plus_video_mode_panel_with_DSC.xml
-endif
-#QDCM calibration xml file for td4330 panel
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_v2_cmd_mode_dsi_truly_panel.xml
-PRODUCT_COPY_FILES += $(BOARD_DISPLAY_HAL)/config/qdcm_calib_data_bengal_default.xml:$(TARGET_COPY_OUT_VENDOR)/etc/qdcm_calib_data_td4330_v2_video_mode_dsi_truly_panel.xml
-
 PRODUCT_PROPERTY_OVERRIDES += \
-    persist.demo.hdmirotationlock=false \
     persist.sys.sf.color_saturation=1.0 \
     persist.sys.sf.color_mode=9 \
     debug.sf.hw=0 \
     debug.egl.hw=0 \
-    debug.sf.latch_unsignaled=1 \
-    debug.sf.high_fps_late_app_phase_offset_ns=1000000 \
     debug.mdpcomp.logs=0 \
     vendor.gralloc.disable_ubwc=0 \
     vendor.display.disable_scaler=0 \
@@ -83,9 +40,6 @@
     vendor.display.enable_optimize_refresh=1 \
     vendor.display.use_smooth_motion=1 \
     vendor.display.enable_camera_smooth=1 \
-    vendor.display.enable_allow_idle_fallback=1 \
-    vendor.display.disable_idle_time_video=1 \
-    vendor.display.disable_idle_time_hdr=1
 
 # Enable offline rotator for Bengal, Monaco, Khaje.
 ifneq ($(filter bengal monaco khaje, $(TARGET_BOARD_PLATFORM)),$(TARGET_BOARD_PLATFORM))
@@ -98,11 +52,7 @@
     vendor.display.camera_noc_efficiency_factor=0.70 \
     vendor.display.disable_layer_stitch=0 \
     vendor.display.secure_preview_buffer_format=420_sp \
-    vendor.gralloc.secure_preview_buffer_format=420_sp \
-    debug.sf.enable_advanced_sf_phase_offset=1 \
-    debug.sf.high_fps_late_sf_phase_offset_ns=-5000000 \
-    debug.sf.high_fps_early_phase_offset_ns=-5000000 \
-    debug.sf.high_fps_early_gl_phase_offset_ns=-5000000
+    vendor.gralloc.secure_preview_buffer_format=420_sp
 endif
 
 ifeq ($(TARGET_BOARD_PLATFORM),monaco)
@@ -112,22 +62,7 @@
 
 ifeq ($(TARGET_BOARD_PLATFORM),kona)
 PRODUCT_PROPERTY_OVERRIDES += \
-    debug.sf.enable_gl_backpressure=1 \
-    debug.sf.enable_advanced_sf_phase_offset=1 \
-    debug.sf.high_fps_late_sf_phase_offset_ns=-4000000 \
-    debug.sf.high_fps_early_phase_offset_ns=-4000000 \
-    debug.sf.high_fps_early_gl_phase_offset_ns=-4000000
-endif
-
-ifeq ($(TARGET_BOARD_PLATFORM),lito)
-PRODUCT_PROPERTY_OVERRIDES += \
-    debug.sf.high_fps_late_sf_phase_offset_ns=-4000000 \
-    debug.sf.high_fps_early_phase_offset_ns=-4000000 \
-    debug.sf.high_fps_early_gl_phase_offset_ns=-4000000 \
-    debug.sf.perf_fps_late_sf_phase_offset_ns=-5000000 \
-    debug.sf.perf_fps_early_phase_offset_ns=-5000000 \
-    debug.sf.perf_fps_early_gl_phase_offset_ns=-5000000 \
-    debug.sf.enable_advanced_sf_phase_offset=1
+    debug.sf.enable_gl_backpressure=1
 endif
 
 ifeq ($(TARGET_FWK_SUPPORTS_FULL_VALUEADDS), true)
@@ -143,7 +78,6 @@
 PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.use_color_management=true
 PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.wcg_composition_dataspace=143261696
 PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.protected_contents=true
-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.set_touch_timer_ms=200
 PRODUCT_DEFAULT_PROPERTY_OVERRIDES += ro.surface_flinger.force_hwc_copy_for_virtual_displays=true
 
 ifneq (,$(filter userdebug eng, $(TARGET_BUILD_VARIANT)))
@@ -157,7 +91,7 @@
 endif
 
 # Enable power async mode
-PRODUCT_PROPERTY_OVERRIDES +=  vendor.display.enable_async_powermode=1
+#PRODUCT_PROPERTY_OVERRIDES +=  vendor.display.enable_async_powermode=1
 
 QMAA_ENABLED_HAL_MODULES += display
 ifeq ($(TARGET_USES_QMAA),true)
diff --git a/display_defaults.go b/display_defaults.go
new file mode 100644
index 0000000..71320ad
--- /dev/null
+++ b/display_defaults.go
@@ -0,0 +1,37 @@
+package display
+
+import (
+	"android/soong/android"
+	"android/soong/cc"
+
+	"github.com/google/blueprint/proptools"
+)
+
+func init() {
+	android.RegisterModuleType("display_go_defaults_sm7250", display_DefaultsFactory)
+}
+
+func display_DefaultsFactory() android.Module {
+	module := cc.DefaultsFactory()
+	android.AddLoadHook(module, display_Defaults)
+	return module
+}
+
+func display_Defaults(ctx android.LoadHookContext) {
+	type props struct {
+		Enabled *bool
+	}
+	p := &props{}
+	p.Enabled = display_globalDefaults(ctx)
+	ctx.AppendProperties(p)
+}
+
+func display_globalDefaults(ctx android.LoadHookContext) *bool {
+	var module_enabled *bool
+
+	if android.ExistentPathForSource(ctx, "vendor/qcom/sm7250/codeaurora/commonsys-intf/display/Android.bp").Valid() == false {
+		module_enabled = proptools.BoolPtr(false)
+	}
+
+	return module_enabled
+}
diff --git a/gpu_tonemapper/Android.mk b/gpu_tonemapper/Android.mk
index ac0eb60..a0ff383 100644
--- a/gpu_tonemapper/Android.mk
+++ b/gpu_tonemapper/Android.mk
@@ -9,6 +9,8 @@
 
 include $(CLEAR_VARS)
 LOCAL_MODULE              := libgpu_tonemapper
+LOCAL_LICENSE_KINDS       := SPDX-license-identifier-Apache-2.0 legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS  := by_exception_only not_allowed notice
 LOCAL_SANITIZE            := integer_overflow
 LOCAL_VENDOR_MODULE       := true
 LOCAL_MODULE_TAGS         := optional
diff --git a/gpu_tonemapper/glengine.cpp b/gpu_tonemapper/glengine.cpp
index 35e1932..0f2d30c 100644
--- a/gpu_tonemapper/glengine.cpp
+++ b/gpu_tonemapper/glengine.cpp
@@ -314,102 +314,84 @@
 void checkGlError(const char *file, int line)
 //-----------------------------------------------------------------------------
 {
-  for (GLint error = glGetError(); error; error = glGetError()) {
-    char *pError;
+  for (GLint error = glGetError(); error != GL_NO_ERROR; error = glGetError()) {
+    const char *pError = "<unknown error>";
     switch (error) {
-      case GL_NO_ERROR:
-        pError = (char *)"GL_NO_ERROR";
-        break;
       case GL_INVALID_ENUM:
-        pError = (char *)"GL_INVALID_ENUM";
+        pError = "GL_INVALID_ENUM";
         break;
       case GL_INVALID_VALUE:
-        pError = (char *)"GL_INVALID_VALUE";
+        pError = "GL_INVALID_VALUE";
         break;
       case GL_INVALID_OPERATION:
-        pError = (char *)"GL_INVALID_OPERATION";
+        pError = "GL_INVALID_OPERATION";
         break;
       case GL_OUT_OF_MEMORY:
-        pError = (char *)"GL_OUT_OF_MEMORY";
+        pError = "GL_OUT_OF_MEMORY";
         break;
       case GL_INVALID_FRAMEBUFFER_OPERATION:
-        pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
+        pError = "GL_INVALID_FRAMEBUFFER_OPERATION";
         break;
-
-      default:
-        ALOGE("glError (0x%x) %s:%d\n", error, file, line);
-        return;
     }
 
-    ALOGE("glError (%s) %s:%d\n", pError, file, line);
-    return;
+    ALOGE("glError %d (%s) %s:%d\n", error, pError, file, line);
   }
-  return;
 }
 
 //-----------------------------------------------------------------------------
 void checkEglError(const char *file, int line)
 //-----------------------------------------------------------------------------
 {
-  for (int i = 0; i < 5; i++) {
-    const EGLint error = eglGetError();
-    if (error == EGL_SUCCESS) {
+  const EGLint error = eglGetError();
+  if (error == EGL_SUCCESS) {
+    return;
+  }
+
+  const char *pError = "<unknown error>";
+  switch (error) {
+    case EGL_NOT_INITIALIZED:
+      pError = "EGL_NOT_INITIALIZED";
+      break;
+    case EGL_BAD_ACCESS:
+      pError = "EGL_BAD_ACCESS";
+      break;
+    case EGL_BAD_ALLOC:
+      pError = "EGL_BAD_ALLOC";
+      break;
+    case EGL_BAD_ATTRIBUTE:
+      pError = "EGL_BAD_ATTRIBUTE";
+      break;
+    case EGL_BAD_CONTEXT:
+      pError = "EGL_BAD_CONTEXT";
+      break;
+    case EGL_BAD_CONFIG:
+      pError = "EGL_BAD_CONFIG";
+      break;
+    case EGL_BAD_CURRENT_SURFACE:
+      pError = "EGL_BAD_CURRENT_SURFACE";
+      break;
+    case EGL_BAD_DISPLAY:
+      pError = "EGL_BAD_DISPLAY";
+      break;
+    case EGL_BAD_SURFACE:
+      pError = "EGL_BAD_SURFACE";
+      break;
+    case EGL_BAD_MATCH:
+      pError = "EGL_BAD_MATCH";
+      break;
+    case EGL_BAD_PARAMETER:
+      pError = "EGL_BAD_PARAMETER";
+      break;
+    case EGL_BAD_NATIVE_PIXMAP:
+      pError = "EGL_BAD_NATIVE_PIXMAP";
+      break;
+    case EGL_BAD_NATIVE_WINDOW:
+      pError = "EGL_BAD_NATIVE_WINDOW";
+      break;
+    case EGL_CONTEXT_LOST:
+      pError = "EGL_CONTEXT_LOST";
       break;
     }
 
-    char *pError;
-    switch (error) {
-      case EGL_SUCCESS:
-        pError = (char *)"EGL_SUCCESS";
-        break;
-      case EGL_NOT_INITIALIZED:
-        pError = (char *)"EGL_NOT_INITIALIZED";
-        break;
-      case EGL_BAD_ACCESS:
-        pError = (char *)"EGL_BAD_ACCESS";
-        break;
-      case EGL_BAD_ALLOC:
-        pError = (char *)"EGL_BAD_ALLOC";
-        break;
-      case EGL_BAD_ATTRIBUTE:
-        pError = (char *)"EGL_BAD_ATTRIBUTE";
-        break;
-      case EGL_BAD_CONTEXT:
-        pError = (char *)"EGL_BAD_CONTEXT";
-        break;
-      case EGL_BAD_CONFIG:
-        pError = (char *)"EGL_BAD_CONFIG";
-        break;
-      case EGL_BAD_CURRENT_SURFACE:
-        pError = (char *)"EGL_BAD_CURRENT_SURFACE";
-        break;
-      case EGL_BAD_DISPLAY:
-        pError = (char *)"EGL_BAD_DISPLAY";
-        break;
-      case EGL_BAD_SURFACE:
-        pError = (char *)"EGL_BAD_SURFACE";
-        break;
-      case EGL_BAD_MATCH:
-        pError = (char *)"EGL_BAD_MATCH";
-        break;
-      case EGL_BAD_PARAMETER:
-        pError = (char *)"EGL_BAD_PARAMETER";
-        break;
-      case EGL_BAD_NATIVE_PIXMAP:
-        pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
-        break;
-      case EGL_BAD_NATIVE_WINDOW:
-        pError = (char *)"EGL_BAD_NATIVE_WINDOW";
-        break;
-      case EGL_CONTEXT_LOST:
-        pError = (char *)"EGL_CONTEXT_LOST";
-        break;
-      default:
-        ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
-        return;
-    }
-    ALOGE("eglError (%s) %s:%d\n", pError, file, line);
-    return;
-  }
-  return;
+    ALOGE("eglError %d (%s) %s:%d\n", error, pError, file, line);
 }
diff --git a/gralloc/Android.bp b/gralloc/Android.bp
new file mode 100644
index 0000000..8a185b8
--- /dev/null
+++ b/gralloc/Android.bp
@@ -0,0 +1,40 @@
+package {
+    default_applicable_licenses: ["hardware_qcom_sm7250_display_license"],
+}
+
+cc_library_shared {
+    name: "libgrallocutils",
+    vendor: true,
+    defaults: ["display_go_defaults"],
+    srcs: [
+        "gr_adreno_info.cpp",
+        "gr_camera_info.cpp",
+        "gr_utils.cpp",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"qdgralloc\"",
+        "-D__QTI_DISPLAY_GRALLOC__",
+        "-Wno-sign-conversion",
+    ],
+    shared_libs: [
+        "android.hardware.graphics.mapper@2.0",
+        "android.hardware.graphics.mapper@2.1",
+        "android.hardware.graphics.mapper@3.0",
+        "android.hardware.graphics.mapper@4.0",
+        "libcutils",
+        "libdl",
+        "liblog",
+        "//vendor/qcom/sm7250:libqdMetaData",
+    ],
+    header_libs: [
+        "display_headers",
+        "device_kernel_headers",
+    ],
+    export_header_lib_headers: [
+        "device_kernel_headers",
+    ],
+    export_include_dirs: ["."],
+    sanitize: {
+        integer_overflow: true,
+    },
+}
diff --git a/gralloc/Android.mk b/gralloc/Android.mk
index 8b9fb3e..f38c872 100644
--- a/gralloc/Android.mk
+++ b/gralloc/Android.mk
@@ -14,6 +14,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE                  := gralloc.$(TARGET_BOARD_PLATFORM)
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS      := by_exception_only not_allowed notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_RELATIVE_PATH    := hw
@@ -34,34 +36,17 @@
 LOCAL_SRC_FILES               := gr_device_impl.cpp
 include $(BUILD_SHARED_LIBRARY)
 
-#libgrallocutils
-include $(CLEAR_VARS)
-LOCAL_MODULE                  := libgrallocutils
-LOCAL_VENDOR_MODULE           := true
-LOCAL_SANITIZE                := integer_overflow
-LOCAL_MODULE_TAGS             := optional
-LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_HEADER_LIBRARIES        := display_headers
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libqdMetaData libdl  \
-                                  android.hardware.graphics.common@1.2 \
-                                  android.hardware.graphics.mapper@2.0 \
-                                  android.hardware.graphics.mapper@2.1 \
-                                  android.hardware.graphics.mapper@3.0 \
-                                  android.hardware.graphics.mapper@4.0
-LOCAL_CFLAGS                  := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \
-                                 -D__QTI_DISPLAY_GRALLOC__
-LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
-LOCAL_SRC_FILES               := gr_utils.cpp gr_adreno_info.cpp gr_camera_info.cpp
-include $(BUILD_SHARED_LIBRARY)
-
 #libgralloccore
 include $(CLEAR_VARS)
 LOCAL_MODULE                  := libgralloccore
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS      := by_exception_only not_allowed notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) \
-                                 $(LIBION_HEADER_PATHS) \
+                                 system/memory/libion/include \
+                                 system/memory/libion/kernel-headers \
                                  $(kernel_includes)
 
 LOCAL_HEADER_LIBRARIES        := display_headers
@@ -72,9 +57,6 @@
                                   android.hardware.graphics.mapper@4.0
 LOCAL_CFLAGS                  := $(common_flags) $(qmaa_flags) -DLOG_TAG=\"qdgralloc\" -Wno-sign-conversion \
                                  -D__QTI_DISPLAY_GRALLOC__
-ifneq ($(TARGET_USES_GRALLOC4),false)
-LOCAL_CFLAGS                  += -DTARGET_USES_GRALLOC4
-endif
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := gr_allocator.cpp gr_buf_mgr.cpp gr_ion_alloc.cpp
 include $(BUILD_SHARED_LIBRARY)
@@ -82,6 +64,8 @@
 #mapper
 include $(CLEAR_VARS)
 LOCAL_MODULE                  := android.hardware.graphics.mapper@3.0-impl-qti-display
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS      := by_exception_only not_allowed notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_RELATIVE_PATH    := hw
@@ -110,6 +94,8 @@
 ifneq ($(TARGET_USES_GRALLOC4),false)
 include $(CLEAR_VARS)
 LOCAL_MODULE                  := android.hardware.graphics.mapper@4.0-impl-qti-display
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS      := by_exception_only not_allowed notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_RELATIVE_PATH    := hw
@@ -146,6 +132,8 @@
 #allocator
 include $(CLEAR_VARS)
 LOCAL_MODULE                  := vendor.qti.hardware.display.allocator-service
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-Apache-2.0 SPDX-license-identifier-BSD legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS      := by_exception_only not_allowed notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_RELATIVE_PATH    := hw
diff --git a/gralloc/QtiMapper.cpp b/gralloc/QtiMapper.cpp
index d8dd675..0b9b42a 100644
--- a/gralloc/QtiMapper.cpp
+++ b/gralloc/QtiMapper.cpp
@@ -185,8 +185,8 @@
 
   auto hnd = PRIV_HANDLE_CONST(buffer);
   auto *out_data = reinterpret_cast<void *>(hnd->base);
-  hidl_cb(err, out_data, gralloc::GetBpp(hnd->format),
-          (hnd->width) * (gralloc::GetBpp(hnd->format)));
+  auto bytes_per_pixel = gralloc::GetBpp(hnd->format);
+  hidl_cb(err, out_data, bytes_per_pixel, hnd->width * bytes_per_pixel);
   return Void();
 }
 
diff --git a/gralloc/gr_adreno_info.cpp b/gralloc/gr_adreno_info.cpp
index 63b03d7..6e4db91 100644
--- a/gralloc/gr_adreno_info.cpp
+++ b/gralloc/gr_adreno_info.cpp
@@ -199,6 +199,10 @@
       return ADRENO_PIXELFORMAT_R5G5B5A1;
     case HAL_PIXEL_FORMAT_RGBA_4444:
       return ADRENO_PIXELFORMAT_R4G4B4A4;
+    case HAL_PIXEL_FORMAT_R_8:
+      return ADRENO_PIXELFORMAT_R8_UNORM;
+    case HAL_PIXEL_FORMAT_RG_88:
+      return ADRENO_PIXELFORMAT_R8G8_UNORM;
     case HAL_PIXEL_FORMAT_RGBA_1010102:
        return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
     case HAL_PIXEL_FORMAT_RGBX_1010102:
diff --git a/gralloc/gr_adreno_info.h b/gralloc/gr_adreno_info.h
index 76fa68a..87c9b51 100644
--- a/gralloc/gr_adreno_info.h
+++ b/gralloc/gr_adreno_info.h
@@ -56,7 +56,9 @@
   ADRENO_PIXELFORMAT_R8G8B8A8_SRGB = 29,
   ADRENO_PIXELFORMAT_D32_FLOAT = 40,
   ADRENO_PIXELFORMAT_D24_UNORM_S8_UINT = 45,
+  ADRENO_PIXELFORMAT_R8G8_UNORM = 49,
   ADRENO_PIXELFORMAT_D16_UNORM = 55,
+  ADRENO_PIXELFORMAT_R8_UNORM = 61,
   ADRENO_PIXELFORMAT_B5G6R5 = 85,
   ADRENO_PIXELFORMAT_B5G5R5A1 = 86,
   ADRENO_PIXELFORMAT_B8G8R8A8_UNORM = 87,
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index 46c12ed..0e05953 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, 2020, 2022 The Linux Foundation. All rights reserved.
  * Not a Contribution
  *
  * Copyright (C) 2010 The Android Open Source Project
@@ -601,6 +601,7 @@
       break;
     case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW12):
     case static_cast<int32_t>(HAL_PIXEL_FORMAT_RAW10):
+    case static_cast<int32_t>(HAL_PIXEL_FORMAT_BLOB):
       if (comp.type.value == android::gralloc4::PlaneLayoutComponentType_RAW.value) {
         comp.offsetInBits = 0;
         comp.sizeInBits = -1;
@@ -617,7 +618,7 @@
       }
       break;
     default:
-      ALOGI_IF(DEBUG, "Offset and size in bits unknown for format %d", format);
+      ALOGE("Offset and size in bits unknown for format %d", format);
       return Error::UNSUPPORTED;
   }
   return Error::NONE;
@@ -1391,6 +1392,20 @@
       }
       break;
     }
+    case (int64_t)StandardMetadataType::SMPTE2094_10: {
+      if (metadata->color.dynamicMetaDataValid &&
+          metadata->color.dynamicMetaDataLen <= HDR_DYNAMIC_META_DATA_SZ) {
+        std::vector<uint8_t> dynamic_metadata_payload;
+        dynamic_metadata_payload.resize(metadata->color.dynamicMetaDataLen);
+        dynamic_metadata_payload.assign(
+            metadata->color.dynamicMetaDataPayload,
+            metadata->color.dynamicMetaDataPayload + metadata->color.dynamicMetaDataLen);
+        android::gralloc4::encodeSmpte2094_10(dynamic_metadata_payload, out);
+      } else {
+        android::gralloc4::encodeSmpte2094_10(std::nullopt, out);
+      }
+      break;
+    }
     case (int64_t)StandardMetadataType::CROP: {
       // Crop is the same for all planes
       std::vector<Rect> out_crop = {{metadata->crop.left, metadata->crop.top, metadata->crop.right,
@@ -1607,7 +1622,8 @@
         return Error::UNSUPPORTED;
       }
       if (dynamic_metadata_payload != std::nullopt) {
-        if (dynamic_metadata_payload->size() > HDR_DYNAMIC_META_DATA_SZ)
+        if (dynamic_metadata_payload->size() > HDR_DYNAMIC_META_DATA_SZ ||
+            dynamic_metadata_payload->size() == 0)
           return Error::BAD_VALUE;
 
         metadata->color.dynamicMetaDataLen = dynamic_metadata_payload->size();
@@ -1624,6 +1640,27 @@
       }
       break;
     }
+    case (int64_t)StandardMetadataType::SMPTE2094_10: {
+      std::optional<std::vector<uint8_t>> dynamic_metadata_payload;
+      android::gralloc4::decodeSmpte2094_10(in, &dynamic_metadata_payload);
+      if (dynamic_metadata_payload != std::nullopt) {
+        if (dynamic_metadata_payload->size() > HDR_DYNAMIC_META_DATA_SZ)
+          return Error::BAD_VALUE;
+
+        metadata->color.dynamicMetaDataLen = static_cast<uint32_t>(dynamic_metadata_payload->size());
+        std::copy(dynamic_metadata_payload->begin(), dynamic_metadata_payload->end(),
+                  metadata->color.dynamicMetaDataPayload);
+        metadata->color.dynamicMetaDataValid = true;
+      } else {
+        // Reset metadata by passing in std::nullopt
+#ifdef METADATA_V2
+        metadata->isStandardMetadataSet[GET_STANDARD_METADATA_STATUS_INDEX(metadatatype_value)] =
+            false;
+#endif
+        metadata->color.dynamicMetaDataValid = false;
+      }
+      break;
+    }
     case (int64_t)StandardMetadataType::CROP: {
       std::vector<Rect> in_crop;
       if (android::gralloc4::decodeCrop(in, &in_crop)) {
diff --git a/gralloc/gr_buf_mgr.h b/gralloc/gr_buf_mgr.h
index 80120fd..3e36db3 100644
--- a/gralloc/gr_buf_mgr.h
+++ b/gralloc/gr_buf_mgr.h
@@ -61,6 +61,7 @@
 
  private:
   BufferManager();
+
   Error MapBuffer(private_handle_t const *hnd);
 
   // Imports the ion fds into the current process. Returns an error for invalid handles
@@ -102,7 +103,7 @@
   std::atomic<uint64_t> next_id_;
   uint64_t allocated_ = 0;
   uint64_t kAllocThreshold = (uint64_t)2*1024*1024*1024;
-  uint64_t kMemoryOffset = 50*1024*1024;
+  const uint64_t kMemoryOffset = 50*1024*1024;
   struct {
     const char *kDumpFile = "/data/misc/wmtrace/bufferdump.txt";
     uint64_t position = 0;
diff --git a/gralloc/gr_camera_info.cpp b/gralloc/gr_camera_info.cpp
index a57e05b..12ec3db 100644
--- a/gralloc/gr_camera_info.cpp
+++ b/gralloc/gr_camera_info.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -103,6 +103,9 @@
     case HAL_PIXEL_FORMAT_NV21_ZSL:
       format = CAMERA_PIXEL_FORMAT_NV21_ZSL;
       break;
+    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
+      format = CAMERA_PIXEL_FORMAT_YUV_FLEX;
+      break;
     case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX:
       format = CAMERA_PIXEL_FORMAT_UBWC_FLEX;
       break;
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index d4734a7..2aab557 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2022, 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
@@ -197,6 +197,7 @@
         return false;
       }
       [[fallthrough]];
+    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
     case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX:
     case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX_2_BATCH:
     case HAL_PIXEL_FORMAT_NV12_UBWC_FLEX_4_BATCH:
@@ -241,8 +242,12 @@
     case HAL_PIXEL_FORMAT_BGR_565:
     case HAL_PIXEL_FORMAT_RGBA_5551:
     case HAL_PIXEL_FORMAT_RGBA_4444:
+    case HAL_PIXEL_FORMAT_RG_88:
       bpp = 2;
       break;
+    case HAL_PIXEL_FORMAT_R_8:
+      bpp = 1;
+      break;
     default:
       ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
       break;
@@ -414,9 +419,6 @@
         }
         size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
         break;
-      case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
-        size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_128, width, height);
-        break;
       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
       case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
         size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
@@ -579,10 +581,6 @@
       c_height = height;
       break;
 #ifndef QMAA
-    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
-      c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_128, height);
-      c_size = c_stride * c_height;
-      break;
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
       c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height);
@@ -720,6 +718,7 @@
       break;
     case HAL_PIXEL_FORMAT_RAW12:
     case HAL_PIXEL_FORMAT_RAW10:
+    case HAL_PIXEL_FORMAT_BLOB:
       step = 0;
       break;
     default:
@@ -1144,7 +1143,13 @@
       aligned_w = ALIGN(width * 12 / 8, 16);
       break;
     case HAL_PIXEL_FORMAT_RAW10:
-      aligned_w = ALIGN(width * 10 / 8, 16);
+      {
+        const unsigned int gpu_alignment =
+            AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
+        // gpu_alignment can return 1. Make sure it's at least 64.
+        const unsigned int raw10_alignment = std::max(gpu_alignment, 64u);
+        aligned_w = ALIGN(width * 10 / 8, raw10_alignment);
+      }
       break;
     case HAL_PIXEL_FORMAT_RAW8:
       aligned_w = ALIGN(width, 16);
@@ -1175,10 +1180,6 @@
       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
       break;
-    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
-      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12_128, width));
-      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12_128, height));
-      break;
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
@@ -1238,7 +1239,6 @@
   switch (hnd->format) {
     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
@@ -1449,8 +1449,8 @@
       gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
     } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
       // If no other usage flags are detected, default the
-      // flexible YUV format to NV21_ZSL
-      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
+      // flexible YUV format to YCrCb_420_SP
+      gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
     }
   }
 
@@ -1498,7 +1498,6 @@
     // Semiplanar
     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:  // Same as YCbCr_420_SP_VENUS
     case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
@@ -1521,6 +1520,7 @@
     case HAL_PIXEL_FORMAT_RAW12:
     case HAL_PIXEL_FORMAT_RAW10:
     case HAL_PIXEL_FORMAT_RAW8:
+    case HAL_PIXEL_FORMAT_BLOB:
       *plane_count = 1;
       GetRawPlaneInfo(format, info.width, info.height, plane_info);
       break;
@@ -1734,7 +1734,6 @@
     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
-    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
@@ -1905,7 +1904,6 @@
     case HAL_PIXEL_FORMAT_XBGR_2101010:
       *drm_format = DRM_FORMAT_RGBX1010102;
       break;
-    case HAL_PIXEL_FORMAT_NV12_LINEAR_FLEX:
     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
       *drm_format = DRM_FORMAT_NV12;
       break;
diff --git a/gralloc/service.cpp b/gralloc/service.cpp
index 2b890ff..f66ec05 100644
--- a/gralloc/service.cpp
+++ b/gralloc/service.cpp
@@ -40,6 +40,7 @@
       new vendor::qti::hardware::display::allocator::V3_0::implementation::QtiAllocator();
 
   configureRpcThreadpool(4, true /*callerWillJoin*/);
+  android::hardware::setMinSchedulerPolicy(service3, SCHED_NORMAL, -20);
   if (service3->registerAsService() != android::OK) {
     ALOGE("Cannot register QTI Allocator 3 service");
     return -EINVAL;
@@ -49,6 +50,7 @@
 #ifdef TARGET_USES_GRALLOC4
   android::sp<IQtiAllocator4> service4 =
       new vendor::qti::hardware::display::allocator::V4_0::implementation::QtiAllocator();
+  android::hardware::setMinSchedulerPolicy(service4, SCHED_NORMAL, -20);
   if (service4->registerAsService() != android::OK) {
     ALOGE("Cannot register QTI Allocator 4 service");
     return -EINVAL;
diff --git a/hdmi_cec/Android.mk b/hdmi_cec/Android.mk
index a035ea4..e092ef6 100644
--- a/hdmi_cec/Android.mk
+++ b/hdmi_cec/Android.mk
@@ -3,6 +3,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE                  := hdmi_cec.$(TARGET_BOARD_PLATFORM)
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS      := notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_RELATIVE_PATH    := hw
diff --git a/include/display_properties.h b/include/display_properties.h
index 874521f..8095714 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -147,6 +147,7 @@
 #define WINDOW_RECT_PROP                     DISPLAY_PROP("window_rect")
 #define DISABLE_IDLE_TIME_HDR                DISPLAY_PROP("disable_idle_time_hdr")
 #define DISABLE_IDLE_TIME_VIDEO              DISPLAY_PROP("disable_idle_time_video")
+#define LBE_SUPPORTED                        DISPLAY_PROP("lbe.supported")
 // Add all other.properties above
 // End of property
 #endif  // __DISPLAY_PROPERTIES_H__
diff --git a/init/Android.mk b/init/Android.mk
index ccca9ff..4421d99 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -6,4 +6,6 @@
 LOCAL_SRC_FILES    := init.qti.display_boot.sh
 LOCAL_INIT_RC      := init.qti.display_boot.rc
 LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_EXECUTABLES)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS := notice
 include $(BUILD_PREBUILT)
diff --git a/libdebug/Android.mk b/libdebug/Android.mk
index 4d18804..63e75f4 100644
--- a/libdebug/Android.mk
+++ b/libdebug/Android.mk
@@ -2,6 +2,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE                  := libdisplaydebug
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS      := notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_TAGS             := optional
diff --git a/libdrmutils/Android.mk b/libdrmutils/Android.mk
index 4b49783..297fdaf 100644
--- a/libdrmutils/Android.mk
+++ b/libdrmutils/Android.mk
@@ -4,6 +4,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE                  := libdrmutils
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS      := notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_TAGS             := optional
diff --git a/libhistogram/Android.mk b/libhistogram/Android.mk
index d76cdd8..6dccb5f 100644
--- a/libhistogram/Android.mk
+++ b/libhistogram/Android.mk
@@ -17,6 +17,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := libhistogram
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_TAGS := optional
 LOCAL_HEADER_LIBRARIES := display_headers
@@ -36,6 +38,8 @@
 
 LOCAL_HEADER_LIBRARIES := display_headers
 LOCAL_MODULE := color_sampling_tool
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_SRC_FILES := color_sampling_tool.cpp
 LOCAL_SHARED_LIBRARIES := libhistogram libdrm liblog libcutils libutils libbase
 LOCAL_C_INCLUDES          := $(kernel_includes) \
@@ -53,6 +57,8 @@
 
 LOCAL_HEADER_LIBRARIES := display_headers
 LOCAL_MODULE := color_sampling_test
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
 LOCAL_SRC_FILES := ringbuffer_test.cpp
 LOCAL_STATIC_LIBRARIES := libgtest libgmock
 LOCAL_SHARED_LIBRARIES := libhistogram libdrm liblog libcutils libutils libbase
diff --git a/liblight/Android.mk b/liblight/Android.mk
index d7060c8..03fb67e 100644
--- a/liblight/Android.mk
+++ b/liblight/Android.mk
@@ -27,6 +27,9 @@
 endif
 LOCAL_CLANG  := true
 LOCAL_MODULE := lights.$(TARGET_BOARD_PLATFORM)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0 legacy_not_a_contribution
+LOCAL_LICENSE_CONDITIONS := by_exception_only not_allowed notice
+LOCAL_NOTICE_FILE := $(LOCAL_PATH)/NOTICE
 LOCAL_MODULE_TAGS := optional
 LOCAL_VENDOR_MODULE := true
 
diff --git a/libmemtrack/Android.mk b/libmemtrack/Android.mk
index 48aed70..169ab1d 100644
--- a/libmemtrack/Android.mk
+++ b/libmemtrack/Android.mk
@@ -36,5 +36,7 @@
 LOCAL_HEADER_LIBRARIES := libhardware_headers
 LOCAL_SRC_FILES := memtrack_msm.c kgsl.c
 LOCAL_MODULE := memtrack.$(TARGET_BOARD_PLATFORM)
+LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
+LOCAL_LICENSE_CONDITIONS := notice
 include $(BUILD_SHARED_LIBRARY)
 endif
diff --git a/libqdutils/Android.bp b/libqdutils/Android.bp
index 16056c8..4df24a8 100644
--- a/libqdutils/Android.bp
+++ b/libqdutils/Android.bp
@@ -1,7 +1,19 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_qcom_sm7250_display_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-BSD
+    default_applicable_licenses: ["hardware_qcom_sm7250_display_license"],
+}
+
 cc_library_shared {
     name: "libqdutils",
     vendor: true,
-    defaults: ["display_defaults"],
+    defaults: [
+        "display_defaults",
+        "display_go_defaults",
+    ],
     header_libs: [
         "libhardware_headers",
         "libutils_headers",
diff --git a/libqservice/Android.bp b/libqservice/Android.bp
index baf34fa..b3eb4fe 100644
--- a/libqservice/Android.bp
+++ b/libqservice/Android.bp
@@ -1,7 +1,21 @@
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "hardware_qcom_sm7250_display_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    //   legacy_not_a_contribution
+    default_applicable_licenses: ["hardware_qcom_sm7250_display_license"],
+}
+
 cc_library_shared {
     name: "libqservice",
     vendor: true,
-    defaults: ["display_defaults"],
+    defaults: [
+        "display_defaults",
+        "display_go_defaults",
+    ],
     shared_libs: ["libbinder"],
     cflags: [
         "-DLOG_TAG=\"qdqservice\"",
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index 00a48ae..77dc2cf 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -118,6 +118,8 @@
       SET_STAND_BY_MODE = 50,                  // Set stand by mode for MDP hardware
       GET_PANEL_RESOLUTION = 51,               // Get Panel Resolution
       DELAY_FIRST_COMMIT = 52,                 // Delay first commit when PowerOn
+      SET_DISPLAY_DEVICE_STATUS = 100,         // Set display device status
+      SET_PANEL_GAMMA_TABLE_SOURCE = 101,      // Update panel gamma table
       COMMAND_LIST_END = 400,
     };
 
diff --git a/sde-drm/Android.mk b/sde-drm/Android.mk
index a39d25c..baea82d 100644
--- a/sde-drm/Android.mk
+++ b/sde-drm/Android.mk
@@ -6,9 +6,11 @@
 common_header_export_path := qcom/display
 
 LOCAL_MODULE              := libsdedrm
+LOCAL_LICENSE_KINDS       := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS  := notice
 LOCAL_SANITIZE            := integer_overflow
 LOCAL_MODULE_TAGS         := optional
-LOCAL_SHARED_LIBRARIES    := libdrm libdrmutils libdisplaydebug
+LOCAL_SHARED_LIBRARIES    := libdrm libdrmutils libdisplaydebug libcutils
 LOCAL_HEADER_LIBRARIES    := display_headers
 LOCAL_C_INCLUDES          := $(kernel_includes) \
                              -isystem external/libdrm
diff --git a/sde-drm/drm_atomic_req.cpp b/sde-drm/drm_atomic_req.cpp
index 6a485c0..78ba8b2 100644
--- a/sde-drm/drm_atomic_req.cpp
+++ b/sde-drm/drm_atomic_req.cpp
@@ -26,7 +26,9 @@
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
+#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
 
+#include <cutils/trace.h>
 #include <drm_logger.h>
 
 #include "drm_atomic_req.h"
@@ -142,34 +144,66 @@
   return 0;
 }
 
-int DRMAtomicReq::Validate() {
-  // Call UnsetUnusedPlanes to find planes that need to be unset. Do not call CommitPlaneState,
-  // because we just want to validate, not actually mark planes as removed
-  drm_mgr_->GetPlaneMgr()->UnsetUnusedResources(token_.crtc_id, false/*is_commit*/,
-                                                drm_atomic_req_);
+int DRMAtomicReq::CallAtomic(DRMCrtc *crtc, uint32_t flags)
+{
+  auto plane_mgr = drm_mgr_->GetPlaneMgr();
+  size_t cnt;
 
-  int ret = drmModeAtomicCommit(fd_, drm_atomic_req_,
-                                DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY, nullptr);
+  cnt = plane_mgr->ApplyDirtyProperties(drm_atomic_req_);
+  ATRACE_INT("dirtyPlaneProps", cnt);
+  cnt = crtc->ApplyDirtyProperties(drm_atomic_req_);
+  ATRACE_INT("dirtyCrtcProps", cnt);
+
+  int ret = drmModeAtomicCommit(fd_, drm_atomic_req_, flags, nullptr);
   if (ret) {
     DRM_LOGE("drmModeAtomicCommit failed with error %d (%s).", errno, strerror(errno));
+    /* reset all properties so next atomic commit applies all values */
+    crtc->ClearProperties();
+    plane_mgr->ClearProperties();
   }
 
-  drm_mgr_->GetPlaneMgr()->PostValidate(token_.crtc_id, !ret);
-  drm_mgr_->GetCrtcMgr()->PostValidate(token_.crtc_id, !ret);
+  // reset the drm_atomic_req_ for next call
   drmModeAtomicSetCursor(drm_atomic_req_, 0);
 
   return ret;
 }
 
+int DRMAtomicReq::Validate() {
+  auto crtc = drm_mgr_->GetCrtcMgr()->GetObject(token_.crtc_id);
+  if (crtc == nullptr) {
+    DRM_LOGE("Invalid crtc %d", token_.crtc_id);
+    return -EINVAL;
+  }
+
+  drm_mgr_->GetPlaneMgr()->UnsetUnusedResources(token_.crtc_id, false /*is_commit*/,
+                                                drm_atomic_req_);
+  int ret = CallAtomic(crtc, DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY);
+  if (!ret)
+    crtc->PostValidate();
+
+  // reset any dirty properties, all properties should be set again before Commit
+  crtc->DiscardDirtyProperties();
+  drm_mgr_->GetPlaneMgr()->PostValidate(token_.crtc_id);
+
+  return ret;
+}
+
 int DRMAtomicReq::Commit(bool synchronous, bool retain_planes) {
   DTRACE_SCOPED();
+  auto crtc = drm_mgr_->GetCrtcMgr()->GetObject(token_.crtc_id);
+  if (crtc == nullptr) {
+    DRM_LOGE("Invalid crtc %d", token_.crtc_id);
+    return -EINVAL;
+  }
+
   if (retain_planes) {
     // It is not enough to simply avoid calling UnsetUnusedPlanes, since state transitons have to
     // be correct when CommitPlaneState is called
     drm_mgr_->GetPlaneMgr()->RetainPlanes(token_.crtc_id);
   }
 
-  drm_mgr_->GetPlaneMgr()->UnsetUnusedResources(token_.crtc_id, true/*is_commit*/, drm_atomic_req_);
+  drm_mgr_->GetPlaneMgr()->UnsetUnusedResources(token_.crtc_id, true /*is_commit*/,
+                                                drm_atomic_req_);
 
   uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;
 
@@ -177,14 +211,13 @@
     flags |= DRM_MODE_ATOMIC_NONBLOCK;
   }
 
-  int ret = drmModeAtomicCommit(fd_, drm_atomic_req_, flags, nullptr);
-  if (ret) {
-    DRM_LOGE("drmModeAtomicCommit failed with error %d (%s).", errno, strerror(errno));
-  }
+  int ret = CallAtomic(crtc, flags);
 
   drm_mgr_->GetPlaneMgr()->PostCommit(token_.crtc_id, !ret);
-  drm_mgr_->GetCrtcMgr()->PostCommit(token_.crtc_id, !ret);
-  drmModeAtomicSetCursor(drm_atomic_req_, 0);
+  crtc->PostCommit(!ret);
+
+  ATRACE_INT("dirtyPlaneProps", 0);
+  ATRACE_INT("dirtyCrtcProps", 0);
 
   return ret;
 }
diff --git a/sde-drm/drm_atomic_req.h b/sde-drm/drm_atomic_req.h
index f0a3dce..eae0e2e 100644
--- a/sde-drm/drm_atomic_req.h
+++ b/sde-drm/drm_atomic_req.h
@@ -39,6 +39,7 @@
 namespace sde_drm {
 
 class DRMManager;
+class DRMCrtc;
 
 class DRMAtomicReq : public DRMAtomicReqInterface {
  public:
@@ -50,6 +51,8 @@
   int Init(const DRMDisplayToken &tok);
 
  private:
+  int CallAtomic(DRMCrtc *crtc, uint32_t flags);
+
   drmModeAtomicReq *drm_atomic_req_ = {};
   DRMManager *drm_mgr_ = {};
   int fd_ = -1;
diff --git a/sde-drm/drm_connector.cpp b/sde-drm/drm_connector.cpp
index 4e8d565..6323c80 100644
--- a/sde-drm/drm_connector.cpp
+++ b/sde-drm/drm_connector.cpp
@@ -502,7 +502,7 @@
   fmt_str[blob->length] = '\0';
   stringstream stream(fmt_str);
   DRM_LOGI("stream str %s len %zu blob str %s len %d", stream.str().c_str(), stream.str().length(),
-           blob->data, blob->length);
+           static_cast<const char *>(blob->data), blob->length);
   string line = {};
   const string display_type = "display type=";
   const string panel_name = "panel name=";
@@ -590,7 +590,7 @@
   fmt_str[blob->length] = '\0';
   stringstream stream(fmt_str);
   DRM_LOGI("stream str %s len %zu blob str %s len %d", stream.str().c_str(), stream.str().length(),
-           blob->data, blob->length);
+           static_cast<const char *>(blob->data), blob->length);
 
   string line = {};
   const string mode_name = "mode_name=";
diff --git a/sde-drm/drm_crtc.cpp b/sde-drm/drm_crtc.cpp
index 1c53082..79b41ed 100644
--- a/sde-drm/drm_crtc.cpp
+++ b/sde-drm/drm_crtc.cpp
@@ -36,7 +36,6 @@
 #include <string.h>
 
 #include <algorithm>
-#include <map>
 #include <sstream>
 #include <string>
 #include <vector>
@@ -51,7 +50,6 @@
 using std::string;
 using std::stringstream;
 using std::unique_ptr;
-using std::map;
 using std::mutex;
 using std::lock_guard;
 using std::pair;
@@ -125,46 +123,36 @@
     drmModeCrtc *libdrm_crtc = drmModeGetCrtc(fd_, resource->crtcs[i]);
     if (libdrm_crtc) {
       crtc->InitAndParse(libdrm_crtc);
-      crtc_pool_[resource->crtcs[i]] = std::move(crtc);
+      object_pool_[resource->crtcs[i]] = std::move(crtc);
     } else {
       DRM_LOGE("Critical error: drmModeGetCrtc() failed for crtc %d.", resource->crtcs[i]);
     }
   }
 }
 
-void DRMCrtcManager::DumpByID(uint32_t id) {
-  crtc_pool_.at(id)->Dump();
-}
-
-void DRMCrtcManager::DumpAll() {
-  for (auto &crtc : crtc_pool_) {
-    crtc.second->Dump();
-  }
-}
-
 void DRMCrtcManager::Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req,
                              va_list args) {
   lock_guard<mutex> lock(lock_);
-  auto it = crtc_pool_.find(obj_id);
-  if (it == crtc_pool_.end()) {
+  auto crtc = GetObject(obj_id);
+  if (crtc == nullptr) {
     DRM_LOGE("Invalid crtc id %d", obj_id);
     return;
   }
 
   if (code == DRMOps::CRTC_SET_DEST_SCALER_CONFIG) {
-    if (crtc_pool_.at(obj_id)->ConfigureScalerLUT(req, dir_lut_blob_id_, cir_lut_blob_id_,
-                                                  sep_lut_blob_id_)) {
+    if (crtc->ConfigureScalerLUT(dir_lut_blob_id_, cir_lut_blob_id_,
+                                 sep_lut_blob_id_)) {
       DRM_LOGD("CRTC %d: Configuring scaler LUTs", obj_id);
     }
   }
 
-  it->second->Perform(code, req, args);
+  crtc->Perform(code, req, args);
 }
 
 void DRMCrtcManager::SetScalerLUT(const DRMScalerLUTInfo &lut_info) {
   // qseed3lite lut is hardcoded in HW. No need to program from sw.
   DRMCrtcInfo info;
-  crtc_pool_.begin()->second->GetInfo(&info);
+  object_pool_.begin()->second->GetInfo(&info);
   if (info.qseed_version == QSEEDVersion::V3LITE) {
     return;
   }
@@ -200,14 +188,14 @@
 
 int DRMCrtcManager::GetCrtcInfo(uint32_t crtc_id, DRMCrtcInfo *info) {
   if (crtc_id == 0) {
-    crtc_pool_.begin()->second->GetInfo(info);
+    object_pool_.begin()->second->GetInfo(info);
   } else {
-    auto iter = crtc_pool_.find(crtc_id);
-    if (iter ==  crtc_pool_.end()) {
+    auto crtc = GetObject(crtc_id);
+    if (crtc == nullptr)  {
       DRM_LOGE("Invalid crtc id %d", crtc_id);
       return -ENODEV;
     } else {
-      iter->second->GetInfo(info);
+      crtc->GetInfo(info);
     }
   }
 
@@ -215,18 +203,18 @@
 }
 
 void DRMCrtcManager::GetPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info) {
-  auto it = crtc_pool_.find(crtc_id);
-  if (it == crtc_pool_.end()) {
+  auto crtc = GetObject(crtc_id);
+  if (crtc == nullptr) {
     DRM_LOGE("Invalid crtc id %d", crtc_id);
     return;
   }
 
-  it->second->GetPPInfo(info);
+  crtc->GetPPInfo(info);
 }
 
 int DRMCrtcManager::Reserve(const std::set<uint32_t> &possible_crtc_indices,
                              DRMDisplayToken *token) {
-  for (auto &item : crtc_pool_) {
+  for (auto &item : object_pool_) {
     if (item.second->GetStatus() == DRMStatus::FREE) {
       if (possible_crtc_indices.find(item.second->GetIndex()) != possible_crtc_indices.end()) {
         item.second->Lock();
@@ -242,26 +230,19 @@
 
 void DRMCrtcManager::Free(DRMDisplayToken *token) {
   lock_guard<mutex> lock(lock_);
-  crtc_pool_.at(token->crtc_id)->Unlock();
+  object_pool_.at(token->crtc_id)->Unlock();
   token->crtc_id = 0;
   token->crtc_index = 0;
 }
 
-void DRMCrtcManager::PostValidate(uint32_t crtc_id, bool success) {
-  lock_guard<mutex> lock(lock_);
-  crtc_pool_.at(crtc_id)->PostValidate(success);
-}
-
-void DRMCrtcManager::PostCommit(uint32_t crtc_id, bool success) {
-  lock_guard<mutex> lock(lock_);
-  crtc_pool_.at(crtc_id)->PostCommit(success);
-}
-
 // ==============================================================================================//
 
 #undef __CLASS__
 #define __CLASS__ "DRMCrtc"
 
+DRMCrtc::DRMCrtc(int fd, uint32_t crtc_index)
+    : DRMObject(prop_mgr_), fd_(fd), crtc_index_(crtc_index) {}
+
 DRMCrtc::~DRMCrtc() {
   if (drm_crtc_) {
     drmModeFreeCrtc(drm_crtc_);
@@ -328,7 +309,7 @@
   fmt_str[blob->length] = '\0';
   stringstream stream(fmt_str);
   DRM_LOGI("stream str %s len %zu blob str %s len %d", stream.str().c_str(), stream.str().length(),
-           blob->data, blob->length);
+           static_cast<const char *>(blob->data), blob->length);
   string line = {};
   string max_blendstages = "max_blendstages=";
   string qseed_type = "qseed_type=";
@@ -539,8 +520,7 @@
     mode_blob_id_ = 0;
   }
 
-  tmp_prop_val_map_.clear();
-  committed_prop_val_map_.clear();
+  ClearProperties();
   status_ = DRMStatus::FREE;
 }
 
@@ -565,7 +545,6 @@
   switch (code) {
     case DRMOps::CRTC_SET_MODE: {
       drmModeModeInfo *mode = va_arg(args, drmModeModeInfo *);
-      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::MODE_ID);
       uint32_t blob_id = 0;
 
       if (mode) {
@@ -575,92 +554,71 @@
         }
       }
 
-      AddProperty(req, obj_id, prop_id, blob_id, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::MODE_ID, blob_id, true);
       SetModeBlobID(blob_id);
       DRM_LOGD("CRTC %d: Set mode %s", obj_id, mode ? mode->name : "null");
     } break;
 
     case DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET: {
       uint32_t offset = va_arg(args, uint32_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::OUTPUT_FENCE_OFFSET),
-                  offset, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::OUTPUT_FENCE_OFFSET, offset);
     }; break;
 
     case DRMOps::CRTC_SET_CORE_CLK: {
       uint32_t core_clk = va_arg(args, uint32_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::CORE_CLK), core_clk, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::CORE_CLK, core_clk);
     }; break;
 
     case DRMOps::CRTC_SET_CORE_AB: {
       uint64_t core_ab = va_arg(args, uint64_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::CORE_AB), core_ab, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::CORE_AB, core_ab);
     }; break;
 
     case DRMOps::CRTC_SET_CORE_IB: {
       uint64_t core_ib = va_arg(args, uint64_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::CORE_IB), core_ib, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::CORE_IB, core_ib);
     }; break;
 
     case DRMOps::CRTC_SET_LLCC_AB: {
       uint64_t llcc_ab = va_arg(args, uint64_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::LLCC_AB), llcc_ab, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::LLCC_AB, llcc_ab);
     }; break;
 
     case DRMOps::CRTC_SET_LLCC_IB: {
       uint64_t llcc_ib = va_arg(args, uint64_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::LLCC_IB), llcc_ib, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::LLCC_IB, llcc_ib);
     }; break;
 
     case DRMOps::CRTC_SET_DRAM_AB: {
       uint64_t dram_ab = va_arg(args, uint64_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::DRAM_AB), dram_ab, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::DRAM_AB, dram_ab);
     }; break;
 
     case DRMOps::CRTC_SET_DRAM_IB: {
       uint64_t dram_ib = va_arg(args, uint64_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::DRAM_IB), dram_ib, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::DRAM_IB, dram_ib);
     }; break;
 
     case DRMOps::CRTC_SET_ROT_PREFILL_BW: {
       uint64_t rot_bw = va_arg(args, uint64_t);
-      drmModeAtomicAddProperty(req, obj_id,
-                               prop_mgr_.GetPropertyId(DRMProperty::ROT_PREFILL_BW), rot_bw);
+      AddProperty(DRMProperty::ROT_PREFILL_BW, rot_bw);
     }; break;
 
     case DRMOps::CRTC_SET_ROT_CLK: {
       uint32_t rot_clk = va_arg(args, uint32_t);
-      AddProperty(req, obj_id,
-                  prop_mgr_.GetPropertyId(DRMProperty::ROT_CLK), rot_clk, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::ROT_CLK, rot_clk);
     }; break;
 
     case DRMOps::CRTC_GET_RELEASE_FENCE: {
       int64_t *fence = va_arg(args, int64_t *);
       *fence = -1;
-      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::OUTPUT_FENCE);
-      AddProperty(req, obj_id, prop_id, reinterpret_cast<uint64_t>(fence), false /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::OUTPUT_FENCE,
+                  reinterpret_cast<uint64_t>(fence), true);
     } break;
 
     case DRMOps::CRTC_SET_ACTIVE: {
       uint32_t enable = va_arg(args, uint32_t);
-      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::ACTIVE), enable,
-                  true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::ACTIVE, enable);
       DRM_LOGD("CRTC %d: Set active %d", obj_id, enable);
       if (enable == 0) {
         ClearVotesCache();
@@ -677,7 +635,7 @@
     case DRMOps::CRTC_SET_ROI: {
       uint32_t num_roi = va_arg(args, uint32_t);
       DRMRect *crtc_rois = va_arg(args, DRMRect*);
-      SetROI(req, obj_id, num_roi, crtc_rois);
+      SetROI(num_roi, crtc_rois);
     } break;
 
     case DRMOps::CRTC_SET_SECURITY_LEVEL: {
@@ -686,33 +644,29 @@
       if (security_level == (int)DRMSecurityLevel::SECURE_ONLY) {
         crtc_security_level = SECURE_ONLY;
       }
-      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::SECURITY_LEVEL),
-                  crtc_security_level, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::SECURITY_LEVEL, crtc_security_level);
     } break;
 
     case DRMOps::CRTC_SET_SOLIDFILL_STAGES: {
       uint64_t dim_stages = va_arg(args, uint64_t);
       const std::vector<DRMSolidfillStage> *solid_fills =
         reinterpret_cast <std::vector <DRMSolidfillStage> *> (dim_stages);
-      SetSolidfillStages(req, obj_id, solid_fills);
+      SetSolidfillStages(solid_fills);
     } break;
 
     case DRMOps::CRTC_SET_IDLE_TIMEOUT: {
       uint32_t timeout_ms = va_arg(args, uint32_t);
-      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::IDLE_TIME),
-                  timeout_ms, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::IDLE_TIME, timeout_ms);
     } break;
 
     case DRMOps::CRTC_SET_DEST_SCALER_CONFIG: {
-      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::DEST_SCALER);
       uint64_t dest_scaler = va_arg(args, uint64_t);
       static sde_drm_dest_scaler_data dest_scale_copy = {};
       sde_drm_dest_scaler_data *ds_data = reinterpret_cast<sde_drm_dest_scaler_data *>
                                            (dest_scaler);
       dest_scale_copy = *ds_data;
-      AddProperty(req, obj_id, prop_id,
-                  reinterpret_cast<uint64_t>(&dest_scale_copy), false /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::DEST_SCALER,
+                  reinterpret_cast<uint64_t>(&dest_scale_copy), true);
     } break;
 
     case DRMOps::CRTC_SET_CAPTURE_MODE: {
@@ -721,8 +675,7 @@
       if (capture_mode == (int)DRMCWbCaptureMode::DSPP_OUT) {
         cwb_capture_mode = CAPTURE_DSPP_OUT;
       }
-      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::CAPTURE_MODE);
-      AddProperty(req, obj_id, prop_id, cwb_capture_mode, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::CAPTURE_MODE, cwb_capture_mode);
     } break;
 
     case DRMOps::CRTC_SET_IDLE_PC_STATE: {
@@ -742,8 +695,7 @@
           idle_pc_state = IDLE_PC_STATE_NONE;
           break;
       }
-      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::IDLE_PC_STATE), idle_pc_state,
-                  true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::IDLE_PC_STATE, idle_pc_state);
       DRM_LOGD("CRTC %d: Set idle_pc_state %d", obj_id, idle_pc_state);
     }; break;
 
@@ -753,68 +705,62 @@
   }
 }
 
-void DRMCrtc::SetROI(drmModeAtomicReq *req, uint32_t obj_id, uint32_t num_roi,
-                     DRMRect *crtc_rois) {
+void DRMCrtc::SetROI(uint32_t num_roi, DRMRect *crtc_rois) {
 #ifdef SDE_MAX_ROI_V1
   if (num_roi > SDE_MAX_ROI_V1 || !prop_mgr_.IsPropertyAvailable(DRMProperty::ROI_V1)) {
     return;
   }
   if (!num_roi || !crtc_rois) {
-    AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::ROI_V1),
-                0, false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::ROI_V1, 0, true);
     DRM_LOGD("CRTC ROI is set to NULL to indicate full frame update");
     return;
   }
-  static struct sde_drm_roi_v1 roi_v1 {};
-  memset(&roi_v1, 0, sizeof(roi_v1));
-  roi_v1.num_rects = num_roi;
+  memset(&roi_v1_, 0, sizeof(roi_v1_));
+  roi_v1_.num_rects = num_roi;
 
   for (uint32_t i = 0; i < num_roi; i++) {
-    roi_v1.roi[i].x1 = crtc_rois[i].left;
-    roi_v1.roi[i].x2 = crtc_rois[i].right;
-    roi_v1.roi[i].y1 = crtc_rois[i].top;
-    roi_v1.roi[i].y2 = crtc_rois[i].bottom;
-    DRM_LOGD("CRTC %d, ROI[l,t,b,r][%d %d %d %d]", obj_id,
-             roi_v1.roi[i].x1, roi_v1.roi[i].y1, roi_v1.roi[i].x2, roi_v1.roi[i].y2);
+    roi_v1_.roi[i].x1 = crtc_rois[i].left;
+    roi_v1_.roi[i].x2 = crtc_rois[i].right;
+    roi_v1_.roi[i].y1 = crtc_rois[i].top;
+    roi_v1_.roi[i].y2 = crtc_rois[i].bottom;
+    DRM_LOGD("CRTC %d, ROI[l,t,b,r][%d %d %d %d]", GetObjectId(),
+             roi_v1_.roi[i].x1, roi_v1_.roi[i].y1, roi_v1_.roi[i].x2, roi_v1_.roi[i].y2);
   }
-  AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::ROI_V1),
-              reinterpret_cast<uint64_t>(&roi_v1), false /* cache */, tmp_prop_val_map_);
+
+  AddProperty(DRMProperty::ROI_V1, reinterpret_cast<uint64_t>(&roi_v1_), true);
 #endif
 }
 
-void DRMCrtc::SetSolidfillStages(drmModeAtomicReq *req, uint32_t obj_id,
-                                 const std::vector<DRMSolidfillStage> *solid_fills) {
+void DRMCrtc::SetSolidfillStages(const std::vector<DRMSolidfillStage> *solid_fills) {
 #if defined  SDE_MAX_DIM_LAYERS
-  static struct sde_drm_dim_layer_v1  drm_dim_layer_v1 {};
-  memset(&drm_dim_layer_v1, 0, sizeof(drm_dim_layer_v1));
+  memset(&drm_dim_layer_v1_, 0, sizeof(drm_dim_layer_v1_));
   uint32_t shift;
 
-  drm_dim_layer_v1.num_layers = solid_fills->size();
+  drm_dim_layer_v1_.num_layers = static_cast<uint32_t> (solid_fills->size());
   for (uint32_t i = 0; i < solid_fills->size(); i++) {
     const DRMSolidfillStage &sf = solid_fills->at(i);
     float plane_alpha = (sf.plane_alpha / 255.0f);
-    drm_dim_layer_v1.layer_cfg[i].stage = sf.z_order;
-    drm_dim_layer_v1.layer_cfg[i].rect.x1 = (uint16_t)sf.bounding_rect.left;
-    drm_dim_layer_v1.layer_cfg[i].rect.y1 = (uint16_t)sf.bounding_rect.top;
-    drm_dim_layer_v1.layer_cfg[i].rect.x2 = (uint16_t)sf.bounding_rect.right;
-    drm_dim_layer_v1.layer_cfg[i].rect.y2 = (uint16_t)sf.bounding_rect.bottom;
-    drm_dim_layer_v1.layer_cfg[i].flags =
+    drm_dim_layer_v1_.layer_cfg[i].stage = sf.z_order;
+    drm_dim_layer_v1_.layer_cfg[i].rect.x1 = (uint16_t)sf.bounding_rect.left;
+    drm_dim_layer_v1_.layer_cfg[i].rect.y1 = (uint16_t)sf.bounding_rect.top;
+    drm_dim_layer_v1_.layer_cfg[i].rect.x2 = (uint16_t)sf.bounding_rect.right;
+    drm_dim_layer_v1_.layer_cfg[i].rect.y2 = (uint16_t)sf.bounding_rect.bottom;
+    drm_dim_layer_v1_.layer_cfg[i].flags =
       sf.is_exclusion_rect ? SDE_DRM_DIM_LAYER_EXCLUSIVE : SDE_DRM_DIM_LAYER_INCLUSIVE;
 
     // @sde_mdss_color: expects in [g b r a] order where as till now solidfill is in [a r g b].
     // As no support for passing plane alpha, Multiply Alpha color component with plane_alpa.
     shift = kSolidFillHwBitDepth - sf.color_bit_depth;
-    drm_dim_layer_v1.layer_cfg[i].color_fill.color_0 = (sf.green & 0x3FF) << shift;
-    drm_dim_layer_v1.layer_cfg[i].color_fill.color_1 = (sf.blue & 0x3FF) << shift;
-    drm_dim_layer_v1.layer_cfg[i].color_fill.color_2 = (sf.red & 0x3FF) << shift;
+    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_0 = (sf.green & 0x3FF) << shift;
+    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_1 = (sf.blue & 0x3FF) << shift;
+    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_2 = (sf.red & 0x3FF) << shift;
     // alpha is 8 bit
-    drm_dim_layer_v1.layer_cfg[i].color_fill.color_3 =
+    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_3 =
       ((uint32_t)((((sf.alpha & 0xFF)) * plane_alpha)));
   }
 
-  AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::DIM_STAGES_V1),
-              reinterpret_cast<uint64_t> (&drm_dim_layer_v1), false /* cache */,
-              tmp_prop_val_map_);
+  AddProperty(DRMProperty::DIM_STAGES_V1,
+              reinterpret_cast<uint64_t> (&drm_dim_layer_v1_), true);
 #endif
 }
 
@@ -823,25 +769,19 @@
            drm_crtc_->buffer_id, drm_crtc_->x, drm_crtc_->y, drm_crtc_->width, drm_crtc_->height);
 }
 
-bool DRMCrtc::ConfigureScalerLUT(drmModeAtomicReq *req, uint32_t dir_lut_blob_id,
+bool DRMCrtc::ConfigureScalerLUT(uint32_t dir_lut_blob_id,
                                  uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id) {
   if (is_lut_configured_ && is_lut_validated_) {
     return false;
   }
   if (dir_lut_blob_id) {
-    AddProperty(req, drm_crtc_->crtc_id,
-                prop_mgr_.GetPropertyId(DRMProperty::DS_LUT_ED), dir_lut_blob_id,
-                false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::DS_LUT_ED, dir_lut_blob_id, true);
   }
   if (cir_lut_blob_id) {
-    AddProperty(req, drm_crtc_->crtc_id,
-                prop_mgr_.GetPropertyId(DRMProperty::DS_LUT_CIR), cir_lut_blob_id,
-                false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::DS_LUT_CIR, cir_lut_blob_id, true);
   }
   if (sep_lut_blob_id) {
-    AddProperty(req, drm_crtc_->crtc_id,
-                prop_mgr_.GetPropertyId(DRMProperty::DS_LUT_SEP), sep_lut_blob_id,
-                false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::DS_LUT_SEP, sep_lut_blob_id, true);
   }
   is_lut_validation_in_progress_ = true;
   return true;
@@ -852,29 +792,24 @@
     if (is_lut_validated_) {
       is_lut_configured_ = true;
     }
-    committed_prop_val_map_ = tmp_prop_val_map_;
-  } else {
-    tmp_prop_val_map_ = committed_prop_val_map_;
+    CommitProperties();
   }
 }
 
-void DRMCrtc::PostValidate(bool success) {
-  if (success && is_lut_validation_in_progress_)  {
+void DRMCrtc::PostValidate() {
+  if (is_lut_validation_in_progress_)  {
     is_lut_validated_ = true;
   }
-
-  tmp_prop_val_map_ = committed_prop_val_map_;
 }
 
 void DRMCrtc::ClearVotesCache() {
-  // On subsequent SET_ACTIVE 1, commit these to MDP driver and re-add to cache automatically
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::CORE_CLK));
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::CORE_AB));
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::CORE_IB));
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::LLCC_AB));
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::LLCC_IB));
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::DRAM_AB));
-  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::DRAM_IB));
+  RemoveProperty(DRMProperty::CORE_CLK);
+  RemoveProperty(DRMProperty::CORE_AB);
+  RemoveProperty(DRMProperty::CORE_IB);
+  RemoveProperty(DRMProperty::LLCC_AB);
+  RemoveProperty(DRMProperty::LLCC_IB);
+  RemoveProperty(DRMProperty::DRAM_AB);
+  RemoveProperty(DRMProperty::DRAM_IB);
 }
 
 }  // namespace sde_drm
diff --git a/sde-drm/drm_crtc.h b/sde-drm/drm_crtc.h
index 2acb02a..402da98 100644
--- a/sde-drm/drm_crtc.h
+++ b/sde-drm/drm_crtc.h
@@ -46,16 +46,17 @@
 
 namespace sde_drm {
 
-class DRMCrtc {
+class DRMCrtc : public DRMObject {
  public:
-  DRMCrtc(int fd, uint32_t crtc_index) : fd_(fd), crtc_index_(crtc_index) {}
+  DRMCrtc(int fd, uint32_t crtc_index);
+  uint32_t GetObjectId() override { return drm_crtc_->crtc_id; }
   void InitAndParse(drmModeCrtc *crtc);
   DRMStatus GetStatus() { return status_; }
   void GetInfo(DRMCrtcInfo *info);
   void SetModeBlobID(uint64_t blob_id);
-  bool ConfigureScalerLUT(drmModeAtomicReq *req, uint32_t dir_lut_blob_id,
+  bool ConfigureScalerLUT(uint32_t dir_lut_blob_id,
                           uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id);
-  void PostValidate(bool success);
+  void PostValidate();
   void PostCommit(bool success);
   void Perform(DRMOps code, drmModeAtomicReq *req, va_list args);
   int GetIndex() { return crtc_index_; }
@@ -72,10 +73,8 @@
   void ParseProperties();
   void ParseCapabilities(uint64_t blob_id);
   void ParseCompRatio(std::string line, bool real_time);
-  void SetROI(drmModeAtomicReq *req, uint32_t obj_id, uint32_t num_roi,
-              DRMRect *crtc_rois);
-  void SetSolidfillStages(drmModeAtomicReq *req, uint32_t obj_id,
-                          const std::vector<DRMSolidfillStage> *solid_fills);
+  void SetROI(uint32_t num_roi, DRMRect *crtc_rois);
+  void SetSolidfillStages(const std::vector<DRMSolidfillStage> *solid_fills);
   void ClearVotesCache();
 
   // Currently hardcoded to 10. In future we need to query bit depth from driver.
@@ -91,18 +90,16 @@
   bool is_lut_configured_ = false;
   bool is_lut_validated_ = false;
   bool is_lut_validation_in_progress_ = false;
+  struct sde_drm_roi_v1 roi_v1_;
+  struct sde_drm_dim_layer_v1  drm_dim_layer_v1_;
   std::unique_ptr<DRMPPManager> pp_mgr_{};
-  std::unordered_map<uint32_t, uint64_t> tmp_prop_val_map_ {};
-  std::unordered_map<uint32_t, uint64_t> committed_prop_val_map_ {};
 };
 
-class DRMCrtcManager {
+class DRMCrtcManager : public DRMObjectManager<DRMCrtc> {
  public:
   explicit DRMCrtcManager(int fd) : fd_(fd) {}
   void Init(drmModeRes *res);
   void DeInit() {}
-  void DumpAll();
-  void DumpByID(uint32_t id);
   int Reserve(const std::set<uint32_t> &possible_crtc_indices, DRMDisplayToken *token);
   void Free(DRMDisplayToken *token);
   void Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req, va_list args);
@@ -110,13 +107,11 @@
   void SetScalerLUT(const DRMScalerLUTInfo &lut_info);
   void UnsetScalerLUT();
   void GetPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info);
-  void PostValidate(uint32_t crtc_id, bool success);
-  void PostCommit(uint32_t crtc_id, bool success);
+  size_t ApplyDirtyProperties(drmModeAtomicReq *req, uint32_t crtc_id);
 
  private:
   int fd_ = -1;
-  std::map<uint32_t, std::unique_ptr<DRMCrtc>> crtc_pool_{};
-    // GLobal Scaler LUT blobs
+  // GLobal Scaler LUT blobs
   uint32_t dir_lut_blob_id_ = 0;
   uint32_t cir_lut_blob_id_ = 0;
   uint32_t sep_lut_blob_id_ = 0;
diff --git a/sde-drm/drm_plane.cpp b/sde-drm/drm_plane.cpp
index d53322f..c54bc63 100644
--- a/sde-drm/drm_plane.cpp
+++ b/sde-drm/drm_plane.cpp
@@ -75,7 +75,6 @@
 #include <drm/sde_drm.h>
 
 #include <cstring>
-#include <map>
 #include <sstream>
 #include <string>
 #include <tuple>
@@ -89,9 +88,7 @@
 
 namespace sde_drm {
 
-using std::map;
 using std::string;
-using std::map;
 using std::pair;
 using std::vector;
 using std::unique_ptr;
@@ -315,7 +312,7 @@
     drmModePlane *libdrm_plane = drmModeGetPlane(fd_, resource->planes[i]);
     if (libdrm_plane) {
       plane->InitAndParse(libdrm_plane);
-      plane_pool_[resource->planes[i]] = std::move(plane);
+      object_pool_[resource->planes[i]] = std::move(plane);
     } else {
       DRM_LOGE("Critical error: drmModeGetPlane() failed for plane %d.", resource->planes[i]);
     }
@@ -324,36 +321,26 @@
   drmModeFreePlaneResources(resource);
 }
 
-void DRMPlaneManager::DumpByID(uint32_t id) {
-  plane_pool_.at(id)->Dump();
-}
-
 void DRMPlaneManager::Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req, va_list args) {
   lock_guard<mutex> lock(lock_);
-  auto it = plane_pool_.find(obj_id);
-  if (it == plane_pool_.end()) {
+  auto plane = GetObject(obj_id);
+  if (plane == nullptr) {
     DRM_LOGE("Invalid plane id %d", obj_id);
     return;
   }
 
   if (code == DRMOps::PLANE_SET_SCALER_CONFIG) {
-    if (it->second->ConfigureScalerLUT(req, dir_lut_blob_id_, cir_lut_blob_id_,
+    if (plane->ConfigureScalerLUT(dir_lut_blob_id_, cir_lut_blob_id_,
                                        sep_lut_blob_id_)) {
       DRM_LOGD("Plane %d: Configuring scaler LUTs", obj_id);
     }
   }
 
-  it->second->Perform(code, req, args);
-}
-
-void DRMPlaneManager::DumpAll() {
-  for (uint32_t i = 0; i < plane_pool_.size(); i++) {
-    plane_pool_[i]->Dump();
-  }
+  plane->Perform(code, req, args);
 }
 
 void DRMPlaneManager::GetPlanesInfo(DRMPlanesInfo *info) {
-  for (auto &plane : plane_pool_) {
+  for (auto &plane : object_pool_) {
     info->push_back(std::make_pair(plane.first, plane.second->GetPlaneTypeInfo()));
   }
 }
@@ -362,7 +349,7 @@
   // Unset planes that were assigned to the crtc referred to by crtc_id but are not requested
   // in this round
   lock_guard<mutex> lock(lock_);
-  for (auto &plane : plane_pool_) {
+  for (auto &plane : object_pool_) {
     uint32_t assigned_crtc = 0;
     uint32_t requested_crtc = 0;
     plane.second->GetAssignedCrtc(&assigned_crtc);
@@ -377,7 +364,7 @@
 }
 
 void DRMPlaneManager::RetainPlanes(uint32_t crtc_id) {
-  for (auto &plane : plane_pool_) {
+  for (auto &plane : object_pool_) {
     uint32_t assigned_crtc = 0;
     plane.second->GetAssignedCrtc(&assigned_crtc);
     if (assigned_crtc == crtc_id) {
@@ -389,17 +376,17 @@
   }
 }
 
-void DRMPlaneManager::PostValidate(uint32_t crtc_id, bool success) {
+void DRMPlaneManager::PostValidate(uint32_t crtc_id) {
   lock_guard<mutex> lock(lock_);
-  for (auto &plane : plane_pool_) {
-    plane.second->PostValidate(crtc_id, success);
+  for (auto &plane : object_pool_) {
+    plane.second->PostValidate(crtc_id);
   }
 }
 
 void DRMPlaneManager::PostCommit(uint32_t crtc_id, bool success) {
   lock_guard<mutex> lock(lock_);
   DRM_LOGD("crtc %d", crtc_id);
-  for (auto &plane : plane_pool_) {
+  for (auto &plane : object_pool_) {
     plane.second->PostCommit(crtc_id, success);
   }
 }
@@ -439,7 +426,8 @@
 #undef __CLASS__
 #define __CLASS__ "DRMPlane"
 
-DRMPlane::DRMPlane(int fd, uint32_t priority) : fd_(fd), priority_(priority) {}
+DRMPlane::DRMPlane(int fd, uint32_t priority)
+    : DRMObject(prop_mgr_), fd_(fd), priority_(priority) {}
 
 DRMPlane::~DRMPlane() {
   drmModeFreePlane(drm_plane_);
@@ -482,7 +470,7 @@
   // like formats etc
   stringstream stream(fmt_str);
   DRM_LOGI("stream str %s len %zu blob str %s len %d", stream.str().c_str(), stream.str().length(),
-           blob->data, blob->length);
+           static_cast<const char *>(blob->data), blob->length);
 
   string line = {};
   string pixel_formats = "pixel_formats=";
@@ -662,44 +650,37 @@
   pp_mgr_->Init(prop_mgr_, DRM_MODE_OBJECT_PLANE);
 }
 
-bool DRMPlane::ConfigureScalerLUT(drmModeAtomicReq *req, uint32_t dir_lut_blob_id,
+bool DRMPlane::ConfigureScalerLUT(uint32_t dir_lut_blob_id,
                                   uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id) {
   if (plane_type_info_.type != DRMPlaneType::VIG || is_lut_configured_) {
     return false;
   }
 
   if (dir_lut_blob_id) {
-    AddProperty(req, drm_plane_->plane_id,
-                prop_mgr_.GetPropertyId(DRMProperty::LUT_ED),
-                dir_lut_blob_id, false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::LUT_ED, dir_lut_blob_id, true);
   }
   if (cir_lut_blob_id) {
-    AddProperty(req, drm_plane_->plane_id,
-                prop_mgr_.GetPropertyId(DRMProperty::LUT_CIR),
-                cir_lut_blob_id, false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::LUT_CIR, cir_lut_blob_id, true);
   }
   if (sep_lut_blob_id) {
-    AddProperty(req, drm_plane_->plane_id,
-                prop_mgr_.GetPropertyId(DRMProperty::LUT_SEP),
-                sep_lut_blob_id, false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::LUT_SEP, sep_lut_blob_id, true);
   }
 
   return true;
 }
 
-void DRMPlane::SetExclRect(drmModeAtomicReq *req, DRMRect rect) {
-  auto prop_id = prop_mgr_.GetPropertyId(DRMProperty::EXCL_RECT);
+void DRMPlane::SetExclRect(DRMRect rect) {
   drm_clip_rect clip_rect;
   SetRect(rect, &clip_rect);
   excl_rect_copy_ = clip_rect;
-  AddProperty(req, drm_plane_->plane_id, prop_id, reinterpret_cast<uint64_t>
-              (&excl_rect_copy_), false /* cache */, tmp_prop_val_map_);
+  AddProperty(DRMProperty::EXCL_RECT,
+              reinterpret_cast<uint64_t>(&excl_rect_copy_), true);
   DRM_LOGD("Plane %d: Setting exclusion rect [x,y,w,h][%d,%d,%d,%d]", drm_plane_->plane_id,
            clip_rect.x1, clip_rect.y1, (clip_rect.x2 - clip_rect.x1),
            (clip_rect.y2 - clip_rect.y1));
 }
 
-bool DRMPlane::SetCscConfig(drmModeAtomicReq *req, DRMCscType csc_type) {
+bool DRMPlane::SetCscConfig(DRMCscType csc_type) {
   if (plane_type_info_.type != DRMPlaneType::VIG) {
     return false;
   }
@@ -712,26 +693,23 @@
     return false;
   }
 
-  auto prop_id = prop_mgr_.GetPropertyId(DRMProperty::CSC_V1);
   if (csc_type == kCscTypeMax) {
-    AddProperty(req, drm_plane_->plane_id, prop_id, 0, false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::CSC_V1, 0);
   } else {
     csc_config_copy_ = csc_10bit_convert[csc_type];
-    AddProperty(req, drm_plane_->plane_id, prop_id,
-                reinterpret_cast<uint64_t>(&csc_config_copy_), false /* cache */,
-                tmp_prop_val_map_);
+    AddProperty(DRMProperty::CSC_V1,
+                reinterpret_cast<uint64_t>(&csc_config_copy_), true);
   }
 
   return true;
 }
 
-bool DRMPlane::SetScalerConfig(drmModeAtomicReq *req, uint64_t handle) {
+bool DRMPlane::SetScalerConfig(uint64_t handle) {
   if (plane_type_info_.type != DRMPlaneType::VIG) {
     return false;
   }
 
   if (prop_mgr_.IsPropertyAvailable(DRMProperty::SCALER_V2)) {
-    auto prop_id = prop_mgr_.GetPropertyId(DRMProperty::SCALER_V2);
     sde_drm_scaler_v2 *scaler_v2_config = reinterpret_cast<sde_drm_scaler_v2 *>(handle);
     uint64_t scaler_data = 0;
     // The address needs to be valid even after async commit, since we are sending address to
@@ -741,15 +719,14 @@
     if (scaler_v2_config_copy_.enable) {
       scaler_data = reinterpret_cast<uint64_t>(&scaler_v2_config_copy_);
     }
-    AddProperty(req, drm_plane_->plane_id, prop_id, scaler_data, false /* cache */,
-                tmp_prop_val_map_);
+    AddProperty(DRMProperty::SCALER_V2, scaler_data, scaler_data != 0);
     return true;
   }
 
   return false;
 }
 
-void DRMPlane::SetDecimation(drmModeAtomicReq *req, uint32_t prop_id, uint32_t prop_value) {
+void DRMPlane::SetDecimation(DRMProperty prop, uint32_t prop_value) {
   if (plane_type_info_.type == DRMPlaneType::DMA || plane_type_info_.master_plane_id) {
     // if value is 0, client is just trying to clear previous decimation, so bail out silently
     if (prop_value > 0) {
@@ -761,14 +738,14 @@
 
   // TODO(user): Currently a ViG plane in smart DMA mode could receive a non-zero decimation value
   // but there is no good way to catch. In any case fix will be in client
-  AddProperty(req, drm_plane_->plane_id, prop_id, prop_value, true /* cache */, tmp_prop_val_map_);
+  AddProperty(prop, prop_value);
   DRM_LOGD("Plane %d: Setting decimation %d", drm_plane_->plane_id, prop_value);
 }
 
-void DRMPlane::PostValidate(uint32_t crtc_id, bool /*success*/) {
+void DRMPlane::PostValidate(uint32_t crtc_id) {
+  DiscardDirtyProperties();
   if (requested_crtc_id_ == crtc_id) {
     SetRequestedCrtc(0);
-    tmp_prop_val_map_ = committed_prop_val_map_;
   }
 }
 
@@ -776,13 +753,14 @@
   DRM_LOGD("crtc %d", crtc_id);
   if (!success) {
     // To reset
-    PostValidate(crtc_id, success);
+    PostValidate(crtc_id);
     return;
   }
 
   uint32_t assigned_crtc = 0;
   uint32_t requested_crtc = 0;
 
+  CommitProperties();
   GetAssignedCrtc(&assigned_crtc);
   GetRequestedCrtc(&requested_crtc);
 
@@ -801,14 +779,12 @@
 
   // If we have set a pipe OR unset a pipe during commit, update states
   if (requested_crtc == crtc_id || assigned_crtc == crtc_id) {
-    committed_prop_val_map_ = tmp_prop_val_map_;
     SetAssignedCrtc(requested_crtc);
     SetRequestedCrtc(0);
   }
 }
 
 void DRMPlane::Perform(DRMOps code, drmModeAtomicReq *req, va_list args) {
-  uint32_t prop_id = 0;
   uint32_t obj_id = drm_plane_->plane_id;
 
   switch (code) {
@@ -816,44 +792,31 @@
     case DRMOps::PLANE_SET_SRC_RECT: {
       DRMRect rect = va_arg(args, DRMRect);
       // source co-ordinates accepted by DRM are 16.16 fixed point
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::SRC_X);
-      AddProperty(req, obj_id, prop_id, rect.left << 16, true /* cache */, tmp_prop_val_map_);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::SRC_Y);
-      AddProperty(req, obj_id, prop_id, rect.top << 16, true /* cache */, tmp_prop_val_map_);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::SRC_W);
-      AddProperty(req, obj_id, prop_id, (rect.right - rect.left) << 16, true /* cache */,
-                  tmp_prop_val_map_);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::SRC_H);
-      AddProperty(req, obj_id, prop_id, (rect.bottom - rect.top) << 16, true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::SRC_X, rect.left << 16);
+      AddProperty(DRMProperty::SRC_Y, rect.top << 16);
+      AddProperty(DRMProperty::SRC_W, (rect.right - rect.left) << 16);
+      AddProperty(DRMProperty::SRC_H, (rect.bottom - rect.top) << 16);
       DRM_LOGV("Plane %d: Setting crop [x,y,w,h][%d,%d,%d,%d]", obj_id, rect.left,
                rect.top, (rect.right - rect.left), (rect.bottom - rect.top));
     } break;
 
     case DRMOps::PLANE_SET_DST_RECT: {
       DRMRect rect = va_arg(args, DRMRect);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::CRTC_X);
-      AddProperty(req, obj_id, prop_id, rect.left, true /* cache */, tmp_prop_val_map_);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::CRTC_Y);
-      AddProperty(req, obj_id, prop_id, rect.top, true /* cache */, tmp_prop_val_map_);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::CRTC_W);
-      AddProperty(req, obj_id, prop_id, (rect.right - rect.left), true /* cache */,
-                  tmp_prop_val_map_);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::CRTC_H);
-      AddProperty(req, obj_id, prop_id, (rect.bottom - rect.top), true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::CRTC_X, rect.left);
+      AddProperty(DRMProperty::CRTC_Y, rect.top);
+      AddProperty(DRMProperty::CRTC_W, (rect.right - rect.left));
+      AddProperty(DRMProperty::CRTC_H, (rect.bottom - rect.top));
       DRM_LOGV("Plane %d: Setting dst [x,y,w,h][%d,%d,%d,%d]", obj_id, rect.left,
                rect.top, (rect.right - rect.left), (rect.bottom - rect.top));
     } break;
     case DRMOps::PLANE_SET_EXCL_RECT: {
       DRMRect excl_rect = va_arg(args, DRMRect);
-      SetExclRect(req, excl_rect);
+      SetExclRect(excl_rect);
     } break;
 
     case DRMOps::PLANE_SET_ZORDER: {
       uint32_t zpos = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::ZPOS);
-      AddProperty(req, obj_id, prop_id, zpos, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::ZPOS, zpos);
       DRM_LOGD("Plane %d: Setting z %d", obj_id, zpos);
     } break;
 
@@ -871,76 +834,66 @@
       } else {
         drm_rot_bit_mask |= 1 << ROTATE_0;
       }
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::ROTATION);
-      AddProperty(req, obj_id, prop_id, drm_rot_bit_mask, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::ROTATION, drm_rot_bit_mask);
       DRM_LOGV("Plane %d: Setting rotation mask %x", obj_id, drm_rot_bit_mask);
     } break;
 
     case DRMOps::PLANE_SET_ALPHA: {
       uint32_t alpha = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::ALPHA);
-      AddProperty(req, obj_id, prop_id, alpha, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::ALPHA, alpha);
       DRM_LOGV("Plane %d: Setting alpha %d", obj_id, alpha);
     } break;
 
     case DRMOps::PLANE_SET_BLEND_TYPE: {
       uint32_t blending = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::BLEND_OP);
-      AddProperty(req, obj_id, prop_id, blending, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::BLEND_OP, blending);
       DRM_LOGV("Plane %d: Setting blending %d", obj_id, blending);
     } break;
 
     case DRMOps::PLANE_SET_H_DECIMATION: {
       uint32_t deci = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::H_DECIMATE);
-      SetDecimation(req, prop_id, deci);
+      SetDecimation(DRMProperty::H_DECIMATE, deci);
     } break;
 
     case DRMOps::PLANE_SET_V_DECIMATION: {
       uint32_t deci = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::V_DECIMATE);
-      SetDecimation(req, prop_id, deci);
+      SetDecimation(DRMProperty::V_DECIMATE, deci);
     } break;
 
     case DRMOps::PLANE_SET_SRC_CONFIG: {
       bool src_config = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::SRC_CONFIG);
-      AddProperty(req, obj_id, prop_id, src_config, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::SRC_CONFIG, src_config);
       DRM_LOGV("Plane %d: Setting src_config flags-%x", obj_id, src_config);
     } break;
 
     case DRMOps::PLANE_SET_CRTC: {
       uint32_t crtc_id = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::CRTC_ID);
-      AddProperty(req, obj_id, prop_id, crtc_id, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::CRTC_ID, crtc_id);
       SetRequestedCrtc(crtc_id);
       DRM_LOGV("Plane %d: Setting crtc %d", obj_id, crtc_id);
     } break;
 
     case DRMOps::PLANE_SET_FB_ID: {
       uint32_t fb_id = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::FB_ID);
-      AddProperty(req, obj_id, prop_id, fb_id, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::FB_ID, fb_id);
       DRM_LOGV("Plane %d: Setting fb_id %d", obj_id, fb_id);
     } break;
 
     case DRMOps::PLANE_SET_ROT_FB_ID: {
       uint32_t fb_id = va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::ROT_FB_ID);
-      drmModeAtomicAddProperty(req, obj_id, prop_id, fb_id);
+      AddProperty(DRMProperty::ROT_FB_ID, fb_id, true);
       DRM_LOGV("Plane %d: Setting rot_fb_id %d", obj_id, fb_id);
     } break;
 
     case DRMOps::PLANE_SET_INPUT_FENCE: {
       int fence = va_arg(args, int);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::INPUT_FENCE);
-      AddProperty(req, obj_id, prop_id, fence, false /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::INPUT_FENCE, fence, true);
       DRM_LOGV("Plane %d: Setting input fence %d", obj_id, fence);
     } break;
 
     case DRMOps::PLANE_SET_SCALER_CONFIG: {
       uint64_t handle = va_arg(args, uint64_t);
-      if (SetScalerConfig(req, handle)) {
+      if (SetScalerConfig(handle)) {
         DRM_LOGV("Plane %d: Setting scaler config", obj_id);
       }
     } break;
@@ -966,33 +919,31 @@
           break;
       }
 
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::FB_TRANSLATION_MODE);
-      AddProperty(req, obj_id, prop_id, fb_secure_mode, true /* cache */, tmp_prop_val_map_);
+      AddProperty(DRMProperty::FB_TRANSLATION_MODE, fb_secure_mode);
       DRM_LOGD("Plane %d: Setting FB secure mode %d", obj_id, fb_secure_mode);
     } break;
 
     case DRMOps::PLANE_SET_CSC_CONFIG: {
       uint32_t* csc_type = va_arg(args, uint32_t*);
       if (csc_type) {
-        SetCscConfig(req, (DRMCscType)*csc_type);
+        SetCscConfig((DRMCscType)*csc_type);
       }
     } break;
 
     case DRMOps::PLANE_SET_MULTIRECT_MODE: {
       DRMMultiRectMode drm_multirect_mode = (DRMMultiRectMode)va_arg(args, uint32_t);
-      SetMultiRectMode(req, drm_multirect_mode);
+      SetMultiRectMode(drm_multirect_mode);
     } break;
 
     case DRMOps::PLANE_SET_INVERSE_PMA: {
        uint32_t pma = va_arg(args, uint32_t);
-       prop_id = prop_mgr_.GetPropertyId(DRMProperty::INVERSE_PMA);
-       AddProperty(req, obj_id, prop_id, pma, true /* cache */, tmp_prop_val_map_);
+       AddProperty(DRMProperty::INVERSE_PMA, pma);
        DRM_LOGD("Plane %d: %s inverse pma", obj_id, pma ? "Setting" : "Resetting");
      } break;
 
     case DRMOps::PLANE_SET_DGM_CSC_CONFIG: {
       uint64_t handle = va_arg(args, uint64_t);
-      if (SetDgmCscConfig(req, handle)) {
+      if (SetDgmCscConfig(handle)) {
         DRM_LOGD("Plane %d: Setting Csc Lut config", obj_id);
       }
     } break;
@@ -1012,9 +963,7 @@
         break;
       }
       DRMSSPPLayoutIndex layout_index = (DRMSSPPLayoutIndex) va_arg(args, uint32_t);
-      prop_id = prop_mgr_.GetPropertyId(DRMProperty::SDE_SSPP_LAYOUT);
-      AddProperty(req, obj_id, prop_id, (uint32_t)layout_index , true /* cache */,
-                  tmp_prop_val_map_);
+      AddProperty(DRMProperty::SDE_SSPP_LAYOUT, (uint32_t)layout_index);
       DRM_LOGD("Plane %d: Setting SSPP Layout to %d", obj_id, layout_index);
     } break;
 
@@ -1071,7 +1020,7 @@
     DRM_LOGE(" %4.4s", (char *)&drm_plane_->formats[i]);
 }
 
-void DRMPlane::SetMultiRectMode(drmModeAtomicReq *req, DRMMultiRectMode drm_multirect_mode) {
+void DRMPlane::SetMultiRectMode(DRMMultiRectMode drm_multirect_mode) {
     if (!plane_type_info_.multirect_prop_present) {
       return;
     }
@@ -1088,11 +1037,10 @@
         multirect_mode = MULTIRECT_SERIAL;
         break;
       default:
-        DRM_LOGE("Invalid multirect mode %d to set on plane %d", drm_multirect_mode, obj_id);
+        DRM_LOGE("Invalid multirect mode %d to set on plane %d", drm_multirect_mode, GetObjectId());
         break;
     }
-    auto prop_id = prop_mgr_.GetPropertyId(DRMProperty::MULTIRECT_MODE);
-    AddProperty(req, obj_id, prop_id, multirect_mode, true /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::MULTIRECT_MODE, multirect_mode);
     DRM_LOGD("Plane %d: Setting multirect_mode %d", obj_id, multirect_mode);
 }
 
@@ -1111,22 +1059,17 @@
   // Reset the sspp tonemap properties if they were set and update the in-use only if
   // its a Commit as Unset is called in Validate as well.
   if (dgm_csc_in_use_) {
-    auto prop_id = prop_mgr_.GetPropertyId(DRMProperty::CSC_DMA_V1);
     uint64_t csc_v1 = 0;
-    AddProperty(req, drm_plane_->plane_id, prop_id, csc_v1, false /* cache */, tmp_prop_val_map_);
+    AddProperty(DRMProperty::CSC_DMA_V1, csc_v1, true);
     DRM_LOGV("Plane %d Clearing DGM CSC", drm_plane_->plane_id);
     dgm_csc_in_use_ = !is_commit;
   }
   ResetColorLUTs(is_commit, req);
-
-  tmp_prop_val_map_.clear();
-  committed_prop_val_map_.clear();
 }
 
-bool DRMPlane::SetDgmCscConfig(drmModeAtomicReq *req, uint64_t handle) {
+bool DRMPlane::SetDgmCscConfig(uint64_t handle) {
   if (plane_type_info_.type == DRMPlaneType::DMA &&
       prop_mgr_.IsPropertyAvailable(DRMProperty::CSC_DMA_V1)) {
-    auto prop_id = prop_mgr_.GetPropertyId(DRMProperty::CSC_DMA_V1);
     sde_drm_csc_v1 *csc_v1 = reinterpret_cast<sde_drm_csc_v1 *>(handle);
     uint64_t csc_v1_data = 0;
     sde_drm_csc_v1 csc_v1_tmp = {};
@@ -1134,9 +1077,7 @@
     if (std::memcmp(&csc_config_copy_, &csc_v1_tmp, sizeof(sde_drm_csc_v1)) != 0) {
       csc_v1_data = reinterpret_cast<uint64_t>(&csc_config_copy_);
     }
-    AddProperty(req, drm_plane_->plane_id, prop_id,
-                reinterpret_cast<uint64_t>(csc_v1_data), false /* cache */,
-                tmp_prop_val_map_);
+    AddProperty(DRMProperty::CSC_DMA_V1, csc_v1_data, true);
     dgm_csc_in_use_ = (csc_v1_data != 0);
     DRM_LOGV("Plane %d in_use = %d", drm_plane_->plane_id, dgm_csc_in_use_);
 
@@ -1149,7 +1090,7 @@
 void DRMPlane::ResetColorLUTs(bool is_commit, drmModeAtomicReq *req) {
   // Reset the color luts if they were set and update the state only if its a Commit as Unset
   // is called in Validate as well.
-  for (int i = 0; i <= (int32_t)(DRMTonemapLutType::VIG_3D_GAMUT); i++) {
+  for (int i = 0; i <= static_cast<int>(DRMTonemapLutType::VIG_3D_GAMUT); i++) {
     auto itr = plane_type_info_.tonemap_lut_version_map.find(static_cast<DRMTonemapLutType>(i));
     if (itr != plane_type_info_.tonemap_lut_version_map.end()) {
       ResetColorLUTState(static_cast<DRMTonemapLutType>(i), is_commit, req);
diff --git a/sde-drm/drm_plane.h b/sde-drm/drm_plane.h
index b92ff74..a21be4d 100644
--- a/sde-drm/drm_plane.h
+++ b/sde-drm/drm_plane.h
@@ -91,32 +91,32 @@
               //  to make sure it's cleared the next time plane is used
 };
 
-class DRMPlane {
+class DRMPlane : public DRMObject {
  public:
   explicit DRMPlane(int fd, uint32_t priority);
   ~DRMPlane();
   void InitAndParse(drmModePlane *plane);
-  void GetId(uint32_t *id) { *id = drm_plane_->plane_id; }
+  uint32_t GetObjectId() override { return drm_plane_->plane_id; }
   void GetType(DRMPlaneType *type) { *type = plane_type_info_.type; }
   void GetPriority(uint32_t *priority) { *priority = priority_; }
   void GetAssignedCrtc(uint32_t *crtc_id) { *crtc_id = assigned_crtc_id_; }
   void GetRequestedCrtc(uint32_t *crtc_id) { *crtc_id = requested_crtc_id_; }
   void SetAssignedCrtc(uint32_t crtc_id) { assigned_crtc_id_ = crtc_id; }
   void SetRequestedCrtc(uint32_t crtc_id) { requested_crtc_id_ = crtc_id; }
-  bool SetScalerConfig(drmModeAtomicReq *req, uint64_t handle);
-  bool SetCscConfig(drmModeAtomicReq *req, DRMCscType csc_type);
-  bool ConfigureScalerLUT(drmModeAtomicReq *req, uint32_t dir_lut_blob_id,
+  bool SetScalerConfig(uint64_t handle);
+  bool SetCscConfig(DRMCscType csc_type);
+  bool ConfigureScalerLUT(uint32_t dir_lut_blob_id,
                           uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id);
   const DRMPlaneTypeInfo& GetPlaneTypeInfo() { return plane_type_info_; }
-  void SetDecimation(drmModeAtomicReq *req, uint32_t prop_id, uint32_t prop_value);
-  void SetExclRect(drmModeAtomicReq *req, DRMRect rect);
+  void SetDecimation(DRMProperty prop, uint32_t prop_value);
+  void SetExclRect(DRMRect rect);
   void Perform(DRMOps code, drmModeAtomicReq *req, va_list args);
   void Dump();
-  void SetMultiRectMode(drmModeAtomicReq *req, DRMMultiRectMode drm_multirect_mode);
+  void SetMultiRectMode(DRMMultiRectMode drm_multirect_mode);
   void Unset(bool is_commit, drmModeAtomicReq *req);
-  void PostValidate(uint32_t crtc_id, bool success);
+  void PostValidate(uint32_t crtc_id);
   void PostCommit(uint32_t crtc_id, bool success);
-  bool SetDgmCscConfig(drmModeAtomicReq *req, uint64_t handle);
+  bool SetDgmCscConfig(uint64_t handle);
   void UpdatePPLutFeatureInuse(DRMPPFeatureInfo *data);
   void ResetColorLUTs(bool is_commit, drmModeAtomicReq *req);
   void ResetColorLUTState(DRMTonemapLutType lut_type, bool is_commit, drmModeAtomicReq *req);
@@ -138,8 +138,6 @@
   bool has_excl_rect_ = false;
   drm_clip_rect excl_rect_copy_ = {};
   std::unique_ptr<DRMPPManager> pp_mgr_ {};
-  std::unordered_map<uint32_t, uint64_t> tmp_prop_val_map_ {};
-  std::unordered_map<uint32_t, uint64_t> committed_prop_val_map_ {};
 
   // Only applicable to planes that have scaler
   sde_drm_scaler_v2 scaler_v2_config_copy_ = {};
@@ -154,27 +152,23 @@
   DRMPlaneLutState vig_3d_lut_gamut_state_ = kInactive;
 };
 
-class DRMPlaneManager {
+class DRMPlaneManager : public DRMObjectManager<DRMPlane> {
  public:
   explicit DRMPlaneManager(int fd);
   void Init();
   void DeInit() {}
   void GetPlanesInfo(DRMPlanesInfo *info);
-  void DumpAll();
-  void DumpByID(uint32_t id);
   void Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req, va_list args);
   void UnsetUnusedResources(uint32_t crtc_id, bool is_commit, drmModeAtomicReq *req);
   void ResetColorLutsOnUsedPlanes(uint32_t crtc_id, bool is_commit, drmModeAtomicReq *req);
   void RetainPlanes(uint32_t crtc_id);
   void SetScalerLUT(const DRMScalerLUTInfo &lut_info);
   void UnsetScalerLUT();
-  void PostValidate(uint32_t crtc_id, bool success);
+  void PostValidate(uint32_t crtc_id);
   void PostCommit(uint32_t crtc_id, bool success);
 
  private:
   int fd_ = -1;
-  // Map of plane id to DRMPlane *
-  std::map<uint32_t, std::unique_ptr<DRMPlane>> plane_pool_{};
   // Global Scaler LUT blobs
   uint32_t dir_lut_blob_id_ = 0;
   uint32_t cir_lut_blob_id_ = 0;
diff --git a/sde-drm/drm_property.cpp b/sde-drm/drm_property.cpp
index 5984ceb..0b93cdf 100644
--- a/sde-drm/drm_property.cpp
+++ b/sde-drm/drm_property.cpp
@@ -27,7 +27,9 @@
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
+#include <drm_logger.h>
 #include "drm_property.h"
+#include "drm_utils.h"
 
 namespace sde_drm {
 
@@ -169,4 +171,49 @@
   return DRMProperty::INVALID;
 }
 
+#define __CLASS__ "DRMObject"
+
+DRMObject::DRMObject(DRMPropertyManager& pm) : property_manager_(pm) {}
+
+void DRMObject::AddProperty(DRMProperty prop, uint64_t value, bool force_dirty) {
+  const uint32_t prop_id = property_manager_.GetPropertyId(prop);
+
+  // bypass check if forced dirty or property is already dirty
+  if (!force_dirty && dirty_values_.find(prop_id) == dirty_values_.end()) {
+    auto it = property_values_.find(prop_id);
+
+    // skip update if value hasn't changed
+    if (it != property_values_.end() && it->second == value) {
+      return;
+    }
+  }
+
+  dirty_values_[prop_id] = value;
+}
+
+void DRMObject::RemoveProperty(DRMProperty prop) {
+  const uint32_t prop_id = property_manager_.GetPropertyId(prop);
+  dirty_values_.erase(prop_id);
+}
+
+size_t DRMObject::ApplyDirtyProperties(drmModeAtomicReq *req) {
+  const uint32_t obj_id = GetObjectId();
+
+  for (const auto& it : dirty_values_)
+    drmModeAtomicAddProperty(req, obj_id, it.first, it.second);
+
+  return dirty_values_.size();
+}
+
+void DRMObject::CommitProperties() {
+  for (const auto& it : dirty_values_)
+    property_values_[it.first] = it.second;
+  DiscardDirtyProperties();
+}
+
+void DRMObject::ClearProperties() {
+  property_values_.clear();
+  DiscardDirtyProperties();
+}
+
 }  // namespace sde_drm
diff --git a/sde-drm/drm_property.h b/sde-drm/drm_property.h
index 7c89488..c7c4535 100644
--- a/sde-drm/drm_property.h
+++ b/sde-drm/drm_property.h
@@ -32,6 +32,9 @@
 
 #include <stdint.h>
 #include <string>
+#include <map>
+#include <unordered_map>
+#include <xf86drmMode.h>
 
 namespace sde_drm {
 
@@ -194,6 +197,61 @@
   uint32_t properties_[(uint32_t)DRMProperty::MAX] {};
 };
 
+struct DRMObject {
+  virtual ~DRMObject() = default;
+  virtual uint32_t GetObjectId() = 0;
+  void Dump() {};
+
+  void AddProperty(DRMProperty prop, uint64_t value, bool force_dirty = false);
+  void RemoveProperty(DRMProperty prop);
+  size_t ApplyDirtyProperties(drmModeAtomicReq *req);
+  void DiscardDirtyProperties() { dirty_values_.clear(); }
+  void ClearProperties();
+  void CommitProperties();
+
+ protected:
+  explicit DRMObject(DRMPropertyManager &pm);
+
+ private:
+  std::unordered_map<uint32_t, uint64_t> property_values_ {};
+  // store properties ordered by prop_id to avoid re-sort in libdrm
+  std::map<uint32_t, uint64_t, std::greater<uint32_t>> dirty_values_ {};
+  DRMPropertyManager& property_manager_;
+};
+
+template<class T>
+struct DRMObjectManager {
+  virtual ~DRMObjectManager() = default;
+  void DumpById(uint32_t id) { object_pool_.at(id)->Dump(); }
+  void DumpAll() {
+    for (auto &obj : object_pool_)
+      obj.second->Dump();
+  }
+
+  size_t ApplyDirtyProperties(drmModeAtomicReq *req) {
+    size_t dirty_count = 0;
+    for (auto &obj : object_pool_)
+      dirty_count += obj.second->ApplyDirtyProperties(req);
+
+    return dirty_count;
+  }
+
+  void ClearProperties() {
+    for (auto &obj : object_pool_)
+      obj.second->ClearProperties();
+  }
+
+  T* GetObject(uint32_t obj_id) {
+    auto it = object_pool_.find(obj_id);
+    if (it == object_pool_.end())
+      return nullptr;
+    return it->second.get();
+  }
+ protected:
+  // store objects ordered by obj_id to avoid re-sort in libdrm
+  std::map<uint32_t, std::unique_ptr<T>> object_pool_{};
+};
+
 }  // namespace sde_drm
 
 #endif  // __DRM_PROPERTY_H__
diff --git a/sde-drm/drm_utils.cpp b/sde-drm/drm_utils.cpp
index b79c4c8..cdd8762 100644
--- a/sde-drm/drm_utils.cpp
+++ b/sde-drm/drm_utils.cpp
@@ -102,17 +102,4 @@
   }
 }
 
-void AddProperty(drmModeAtomicReqPtr req, uint32_t object_id, uint32_t property_id, uint64_t value,
-                 bool cache, std::unordered_map<uint32_t, uint64_t> &prop_val_map) {
-#ifndef SDM_VIRTUAL_DRIVER
-  auto it = prop_val_map.find(property_id);
-  if (it == prop_val_map.end() || it->second != value)
-#endif
-    drmModeAtomicAddProperty(req, object_id, property_id, value);
-#ifndef SDM_VIRTUAL_DRIVER
-  if (cache)
-    prop_val_map[property_id] = value;
-#endif
-}
-
 }  // namespace sde_drm
diff --git a/sde-drm/drm_utils.h b/sde-drm/drm_utils.h
index 2c6246d..f06d71e 100644
--- a/sde-drm/drm_utils.h
+++ b/sde-drm/drm_utils.h
@@ -30,13 +30,9 @@
 #ifndef __DRM_UTILS_H__
 #define __DRM_UTILS_H__
 
-#include <stdint.h>
-#include <stdlib.h>
-#include <xf86drmMode.h>
 #include <string>
 #include <utility>
 #include <vector>
-#include <unordered_map>
 
 namespace sde_drm {
 
@@ -47,8 +43,6 @@
 
 void ParseFormats(const std::string &line, std::vector<std::pair<uint32_t, uint64_t>> *formats);
 void Tokenize(const std::string &str, std::vector<std::string> *tokens, char delim);
-void AddProperty(drmModeAtomicReqPtr req, uint32_t object_id, uint32_t property_id, uint64_t value,
-                 bool cache, std::unordered_map<uint32_t, uint64_t> &prop_val_map);
 
 }  // namespace sde_drm
 
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index c6d6feb..07a9026 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -3,10 +3,13 @@
 include $(LOCAL_PATH)/../../../common.mk
 
 LOCAL_MODULE                  := libsdmcore
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS      := notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
+LOCAL_C_INCLUDES              += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
 LOCAL_HEADER_LIBRARIES        := display_headers
 LOCAL_CFLAGS                  := -fno-operator-names -Wno-unused-parameter -DLOG_TAG=\"SDM\" \
                                  $(common_flags)
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index c990bc0..8d6eb76 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -867,6 +867,8 @@
     return error;
   }
 
+  DLOGI("Active configuration changed to: %d", index);
+
   return ReconfigureDisplay();
 }
 
@@ -1225,13 +1227,7 @@
 }
 
 DisplayError DisplayBase::SetColorModeById(int32_t color_mode_id) {
-  for (auto it : color_mode_map_) {
-    if (it.second->id == color_mode_id) {
-      return SetColorMode(it.first);
-    }
-  }
-
-  return kErrorNotSupported;
+  return color_mgr_->ColorMgrSetMode(color_mode_id);
 }
 
 DisplayError DisplayBase::SetColorModeInternal(const std::string &color_mode,
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index a232a3a..6b49f65 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -516,6 +516,8 @@
   // Set vsync enable state to false, as driver disables vsync during display power off.
   if (state == kStateOff) {
     vsync_enable_ = false;
+  } else if (pendingActiveConfig != UINT_MAX) {
+    SetActiveConfig(pendingActiveConfig);
   }
 
   if (pending_doze_ || pending_power_on_) {
@@ -525,6 +527,30 @@
   return kErrorNone;
 }
 
+DisplayError DisplayBuiltIn::SetActiveConfig(uint32_t index) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+  DisplayState state;
+
+  if (DisplayBase::GetDisplayState(&state) == kErrorNone) {
+    if (state != kStateOn || pending_doze_ || pending_power_on_) {
+      pendingActiveConfig = index;
+      return kErrorNone;
+    }
+  }
+
+  pendingActiveConfig = UINT_MAX;
+  return DisplayBase::SetActiveConfig(index);
+}
+
+DisplayError DisplayBuiltIn::GetActiveConfig(uint32_t *index) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+  if (index && pendingActiveConfig != UINT_MAX) {
+    *index = pendingActiveConfig;
+    return kErrorNone;
+  }
+  return DisplayBase::GetActiveConfig(index);
+}
+
 void DisplayBuiltIn::SetIdleTimeoutMs(uint32_t active_ms, uint32_t inactive_ms) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   comp_manager_->SetIdleTimeoutMs(display_comp_ctx_, active_ms, inactive_ms);
@@ -588,7 +614,7 @@
     return kErrorParameters;
   }
 
-  if (state_ == kStateOff) {
+  if (state_ == kStateOff && !pending_doze_ && !pending_power_on_) {
     return kErrorNone;
   }
 
@@ -1287,11 +1313,6 @@
   return same_roi;
 }
 
-DisplayError DisplayBuiltIn::SetActiveConfig(uint32_t index) {
-  deferred_config_.MarkDirty();
-  return DisplayBase::SetActiveConfig(index);
-}
-
 DisplayError DisplayBuiltIn::ReconfigureDisplay() {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
@@ -1411,8 +1432,8 @@
   hw_info_intf_->GetHWResourceInfo(&hw_resource_info);
 
   fixed_info->hdr_supported = hw_resource_info.has_hdr;
-  // Built-in displays always support HDR10+ when the target supports HDR
-  fixed_info->hdr_plus_supported = hw_resource_info.has_hdr;
+  // Built-in displays not support HDR10+ even the target supports HDR to comply with spec
+  fixed_info->hdr_plus_supported = false;
   // Populate luminance values only if hdr will be supported on that display
   fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
   fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 32d666d..e206a19 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -151,6 +151,8 @@
   virtual DisplayError DisablePartialUpdateOneFrame();
   virtual DisplayError SetDisplayState(DisplayState state, bool teardown,
                                        shared_ptr<Fence> *release_fence);
+  virtual DisplayError SetActiveConfig(uint32_t index) override;
+  virtual DisplayError GetActiveConfig(uint32_t *index) override;
   virtual void SetIdleTimeoutMs(uint32_t active_ms, uint32_t inactive_ms);
   virtual DisplayError SetDisplayMode(uint32_t mode);
   virtual DisplayError GetRefreshRateRange(uint32_t *min_refresh_rate, uint32_t *max_refresh_rate);
@@ -190,7 +192,6 @@
   // Implement the DppsPropIntf
   virtual DisplayError DppsProcessOps(enum DppsOps op, void *payload, size_t size);
   void ResetPanel();
-  virtual DisplayError SetActiveConfig(uint32_t index);
   virtual DisplayError ReconfigureDisplay();
   DisplayError CreatePanelfeatures();
 
@@ -238,6 +239,8 @@
 #endif
   void initColorSamplingState();
   DeferFpsConfig deferred_config_ = {};
+
+  uint32_t pendingActiveConfig = UINT_MAX;
   GetPanelFeatureFactoryIntfType GetPanelFeatureFactoryIntfFunc_ = nullptr;
   bool enhance_idle_time_ = false;
   int idle_time_ms_ = 0;
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index d3b0129..43388c1 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -360,12 +360,12 @@
   char data[kMaxStringLength]{};
 
   prctl(PR_SET_NAME, event_thread_name_.c_str(), 0, 0, 0);
-  setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
 
-  // Real Time task with lowest priority.
   struct sched_param param = {0};
-  param.sched_priority = sched_get_priority_min(SCHED_FIFO);
-  sched_setscheduler(0, SCHED_FIFO, &param);
+  param.sched_priority = 2;
+  if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
+    DLOGE("Couldn't set SCHED_FIFO: %d", errno);
+  }
 
   while (!exit_threads_) {
     int error = Sys::poll_(poll_fds_.data(), UINT32(poll_fds_.size()), -1);
diff --git a/sdm/libs/utils/Android.mk b/sdm/libs/utils/Android.mk
index c474193..526bff5 100644
--- a/sdm/libs/utils/Android.mk
+++ b/sdm/libs/utils/Android.mk
@@ -3,6 +3,8 @@
 include $(LOCAL_PATH)/../../../common.mk
 
 LOCAL_MODULE                  := libsdmutils
+LOCAL_LICENSE_KINDS           := SPDX-license-identifier-BSD
+LOCAL_LICENSE_CONDITIONS      := notice
 LOCAL_SANITIZE                := integer_overflow
 LOCAL_VENDOR_MODULE           := true
 LOCAL_MODULE_TAGS             := optional