Merge "Revert "Revert "hwc2: Remove debug.sf.enable_hwc_vds definition."""
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..74fce80
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,6 @@
+# Clean old composer
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/bin/hw/android.hardware.graphics.composer@2.1-service)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/etc/init/android.hardware.graphics.composer@2.1-service.rc)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/lib64/hw/android.hardware.graphics.composer@2.1-impl.so)
+#Clean display includes
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/include/qcom/display)
diff --git a/config/msmnile.mk b/config/msmnile.mk
index b35133e..286e8a3 100644
--- a/config/msmnile.mk
+++ b/config/msmnile.mk
@@ -61,8 +61,8 @@
     vendor.display.enable_default_color_mode=1
 
 # This matrix should be in column major order, per SurfaceFlinger requirement
-#  1.16868   -0.16868    0.00000
-# -0.03155    1.03155    0.00000
-# -0.01473   -0.05899    1.07372
+#  1.0   0.0   0.0
+#  0.0   1.0   0.0
+#  0.0   0.0   1.0
 PRODUCT_PROPERTY_OVERRIDES += \
-    vendor.display.dataspace_saturation_matrix=1.16868,-0.03155,-0.01473,-0.16868,1.03155,-0.05899,0.00000,0.00000,1.07372
+    vendor.display.dataspace_saturation_matrix=1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0
diff --git a/config/talos.mk b/config/talos.mk
index 8d81797..67196dc 100644
--- a/config/talos.mk
+++ b/config/talos.mk
@@ -65,8 +65,8 @@
     vendor.display.enable_default_color_mode=1
 
 # This matrix should be in column major order, per SurfaceFlinger requirement
-#  1.16868   -0.16868    0.00000
-# -0.03155    1.03155    0.00000
-# -0.01473   -0.05899    1.07372
+#  1.0   0.0   0.0
+#  0.0   1.0   0.0
+#  0.0   0.0   1.0
 PRODUCT_PROPERTY_OVERRIDES += \
-    vendor.display.dataspace_saturation_matrix=1.16868,-0.03155,-0.01473,-0.16868,1.03155,-0.05899,0.00000,0.00000,1.07372
+    vendor.display.dataspace_saturation_matrix=1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0
diff --git a/config/trinket.mk b/config/trinket.mk
index 8dfc945..6b3526f 100644
--- a/config/trinket.mk
+++ b/config/trinket.mk
@@ -53,8 +53,8 @@
     vendor.display.enable_default_color_mode=1
 
 # This matrix should be in column major order, per SurfaceFlinger requirement
-#  1.16868   -0.16868    0.00000
-# -0.03155    1.03155    0.00000
-# -0.01473   -0.05899    1.07372
+#  1.0   0.0   0.0
+#  0.0   1.0   0.0
+#  0.0   0.0   1.0
 PRODUCT_PROPERTY_OVERRIDES += \
-    vendor.display.dataspace_saturation_matrix=1.16868,-0.03155,-0.01473,-0.16868,1.03155,-0.05899,0.00000,0.00000,1.07372
+    vendor.display.dataspace_saturation_matrix=1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0
diff --git a/gralloc/gr_adreno_info.cpp b/gralloc/gr_adreno_info.cpp
index c89f555..64c74c6 100644
--- a/gralloc/gr_adreno_info.cpp
+++ b/gralloc/gr_adreno_info.cpp
@@ -233,6 +233,62 @@
       return ADRENO_PIXELFORMAT_D32_FLOAT;
     case HAL_PIXEL_FORMAT_STENCIL_8:
       return ADRENO_PIXELFORMAT_S8_UINT;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_4X4;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_4X4_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_5X4;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_5X4_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_5X5;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_5X5_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_6X5;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
+       return ADRENO_PIXELFORMAT_ASTC_6X5_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_6X6;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_6X6_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_8X5;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_8X5_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_8X6;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_8X6_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_8X8;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_8X8_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X5;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X5_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X6;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X6_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X8;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X8_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X10;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_10X10_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_12X10;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_12X10_SRGB;
+    case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_12X12;
+    case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
+      return ADRENO_PIXELFORMAT_ASTC_12X12_SRGB;
     default:
       ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
       break;
diff --git a/gralloc/gr_adreno_info.h b/gralloc/gr_adreno_info.h
index bb8fdd6..436e0c0 100644
--- a/gralloc/gr_adreno_info.h
+++ b/gralloc/gr_adreno_info.h
@@ -67,6 +67,34 @@
   ADRENO_PIXELFORMAT_D24_UNORM = 549,
   ADRENO_PIXELFORMAT_D32_FLOAT_X24S8_UINT = 551,
   ADRENO_PIXELFORMAT_S8_UINT = 552,
+  ADRENO_PIXELFORMAT_ASTC_4X4 = 568,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_5X4 = 569,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_5X5 = 570,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_6X5 = 571,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_6X6 = 572,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_8X5 = 573,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_8X6 = 574,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_8X8 = 575,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X5 = 576,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X6 = 577,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X8 = 578,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X10 = 579,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_12X10 = 580,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_12X12 = 581,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_4X4_SRGB = 582,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_5X4_SRGB = 583,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_5X5_SRGB = 584,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_6X5_SRGB = 585,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_6X6_SRGB = 586,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_8X5_SRGB = 587,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_8X6_SRGB = 588,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_8X8_SRGB = 589,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X5_SRGB = 590,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X6_SRGB = 591,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X8_SRGB = 592,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_10X10_SRGB = 593,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_12X10_SRGB = 594,  // ASTC Compressed
+  ADRENO_PIXELFORMAT_ASTC_12X12_SRGB = 595,  // ASTC Compressed
   // Vertex, Normalized GL_UNSIGNED_INT_10_10_10_2_OES
   ADRENO_PIXELFORMAT_R5G6B5 = 610,    //  RGBA version of B5G6R5
   ADRENO_PIXELFORMAT_R5G5B5A1 = 611,  //  RGBA version of B5G5R5A1
diff --git a/gralloc/gr_allocator.cpp b/gralloc/gr_allocator.cpp
index 4c16b62..fc53168 100644
--- a/gralloc/gr_allocator.cpp
+++ b/gralloc/gr_allocator.cpp
@@ -54,6 +54,10 @@
 #define ION_SECURE ION_FLAG_SECURE
 #endif
 
+#ifndef ION_FLAG_CP_CDSP
+#define ION_FLAG_CP_CDSP 0
+#endif
+
 #ifdef SLAVE_SIDE_CP
 #define CP_HEAP_ID ION_CP_MM_HEAP_ID
 #define SD_HEAP_ID CP_HEAP_ID
@@ -206,11 +210,17 @@
       flags |= UINT(ION_SD_FLAGS);
     } else if (usage & BufferUsage::CAMERA_OUTPUT) {
       heap_id = ION_HEAP(SD_HEAP_ID);
+      if (usage & GRALLOC_USAGE_PRIVATE_CDSP) {
+        flags |= UINT(ION_SECURE | ION_FLAG_CP_CDSP);
+      }
       if (usage & BufferUsage::COMPOSER_OVERLAY) {
         flags |= UINT(ION_SC_PREVIEW_FLAGS);
       } else {
         flags |= UINT(ION_SC_FLAGS);
       }
+    } else if (usage & GRALLOC_USAGE_PRIVATE_CDSP) {
+      heap_id = ION_HEAP(ION_SECURE_CARVEOUT_HEAP_ID);
+      flags |= UINT(ION_SECURE | ION_FLAG_CP_CDSP);
     } else {
       heap_id = ION_HEAP(CP_HEAP_ID);
       flags |= UINT(ION_CP_FLAGS);
diff --git a/gralloc/gr_buf_mgr.cpp b/gralloc/gr_buf_mgr.cpp
index 9a25a8e..61e31d6 100644
--- a/gralloc/gr_buf_mgr.cpp
+++ b/gralloc/gr_buf_mgr.cpp
@@ -86,7 +86,10 @@
 Error BufferManager::ValidateBufferSize(private_handle_t const *hnd, BufferInfo info) {
   unsigned int size, alignedw, alignedh;
   info.format = GetImplDefinedFormat(info.usage, info.format);
-  GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
+  int ret = GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
+  if (ret < 0) {
+    return Error::BAD_BUFFER;
+  }
   auto ion_fd_size = static_cast<unsigned int>(lseek(hnd->fd, 0, SEEK_END));
   if (size != ion_fd_size) {
     return Error::BAD_VALUE;
@@ -270,6 +273,7 @@
 
   unsigned int size;
   unsigned int alignedw, alignedh;
+  int err = 0;
 
   int buffer_type = GetBufferType(format);
   BufferInfo info = GetBufferInfo(descriptor);
@@ -277,10 +281,12 @@
   info.layer_count = layer_count;
 
   GraphicsMetadata graphics_metadata = {};
-  GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh, &graphics_metadata);
+  err = GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh, &graphics_metadata);
+  if (err < 0) {
+    return Error::BAD_DESCRIPTOR;
+  }
 
   size = (bufferSize >= size) ? bufferSize : size;
-  int err = 0;
   uint64_t flags = 0;
   auto page_size = UINT(getpagesize());
   AllocData data;
@@ -292,7 +298,8 @@
   // Allocate buffer memory
   err = allocator_->AllocateMem(&data, usage, format);
   if (err) {
-    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
+    ALOGE("gralloc failed to allocate err=%s format %d size %d WxH %dx%d usage %" PRIu64,
+          strerror(-err), format, size, alignedw, alignedh, usage);
     return Error::NO_RESOURCES;
   }
 
diff --git a/gralloc/gr_ion_alloc.cpp b/gralloc/gr_ion_alloc.cpp
index 2c7a90b..a9e06da 100644
--- a/gralloc/gr_ion_alloc.cpp
+++ b/gralloc/gr_ion_alloc.cpp
@@ -95,7 +95,8 @@
   err = ion_alloc_fd(ion_dev_fd_, data->size, data->align, data->heap_id, flags, &fd);
   ATRACE_END();
   if (err) {
-    ALOGE("libion alloc failed");
+    ALOGE("libion alloc failed ion_fd %d size %d align %d heap_id %x flags %x",
+          ion_dev_fd_, data->size, data->align, data->heap_id, flags);
     return err;
   }
 
diff --git a/gralloc/gr_utils.cpp b/gralloc/gr_utils.cpp
index 7c825bd..3ba38c7 100644
--- a/gralloc/gr_utils.cpp
+++ b/gralloc/gr_utils.cpp
@@ -67,6 +67,7 @@
     case HAL_PIXEL_FORMAT_BLOB:
     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
     case HAL_PIXEL_FORMAT_NV12_HEIF:
+    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
       return true;
     default:
       return false;
@@ -341,21 +342,22 @@
   return size;
 }
 
-void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
-                                unsigned int *alignedh) {
+int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
+                               unsigned int *alignedh) {
   GraphicsMetadata graphics_metadata = {};
-  GetBufferSizeAndDimensions(info, size, alignedw, alignedh, &graphics_metadata);
+  return GetBufferSizeAndDimensions(info, size, alignedw, alignedh, &graphics_metadata);
 }
 
-void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
-                                unsigned int *alignedh, GraphicsMetadata *graphics_metadata) {
+int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
+                               unsigned int *alignedh, GraphicsMetadata *graphics_metadata) {
   int buffer_type = GetBufferType(info.format);
   if (CanUseAdrenoForSize(buffer_type, info.usage)) {
-    GetGpuResourceSizeAndDimensions(info, size, alignedw, alignedh, graphics_metadata);
+    return GetGpuResourceSizeAndDimensions(info, size, alignedw, alignedh, graphics_metadata);
   } else {
     GetAlignedWidthAndHeight(info, alignedw, alignedh);
     *size = GetSize(info, *alignedw, *alignedh);
   }
+  return 0;
 }
 
 void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
@@ -1002,6 +1004,9 @@
       offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
       (*num_planes)++;
       break;
+    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
+      *num_planes = 1;
+      break;
     default:
       ALOGW("%s: Unsupported format", __FUNCTION__);
       ret = -EINVAL;
@@ -1014,9 +1019,9 @@
   return 0;
 }
 
-void GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
-                                     unsigned int *alignedw, unsigned int *alignedh,
-                                     GraphicsMetadata *graphics_metadata) {
+int GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
+                                    unsigned int *alignedw, unsigned int *alignedh,
+                                    GraphicsMetadata *graphics_metadata) {
   GetAlignedWidthAndHeight(info, alignedw, alignedh);
   AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
   graphics_metadata->size = adreno_mem_info->AdrenoGetMetadataBlobSize();
@@ -1038,10 +1043,11 @@
   if (ret != 0) {
     ALOGE("%s Graphics metadata init failed", __FUNCTION__);
     *size = 0;
-    return;
+    return -EINVAL;
   }
   // Call adreno api with the metadata blob to get buffer size
   *size = adreno_mem_info->AdrenoGetAlignedGpuBufferSize(graphics_metadata->data);
+  return 0;
 }
 
 bool CanUseAdrenoForSize(int buffer_type, uint64_t usage) {
diff --git a/gralloc/gr_utils.h b/gralloc/gr_utils.h
index c955619..309b8a7 100644
--- a/gralloc/gr_utils.h
+++ b/gralloc/gr_utils.h
@@ -76,10 +76,10 @@
 bool CpuCanRead(uint64_t usage);
 bool CpuCanWrite(uint64_t usage);
 unsigned int GetSize(const BufferInfo &d, unsigned int alignedw, unsigned int alignedh);
-void GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size, unsigned int *alignedw,
-                                unsigned int *alignedh);
-void GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size, unsigned int *alignedw,
-                                unsigned int *alignedh, GraphicsMetadata *graphics_metadata);
+int GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size, unsigned int *alignedw,
+                               unsigned int *alignedh);
+int GetBufferSizeAndDimensions(const BufferInfo &d, unsigned int *size, unsigned int *alignedw,
+                               unsigned int *alignedh, GraphicsMetadata *graphics_metadata);
 void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height);
 void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space);
 void GetAlignedWidthAndHeight(const BufferInfo &d, unsigned int *aligned_w,
@@ -105,9 +105,9 @@
 int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
                     uint32_t *num_planes);
 uint32_t GetDataAlignment(int format, uint64_t usage);
-void GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
-                                     unsigned int *alignedw, unsigned int *alignedh,
-                                     GraphicsMetadata *graphics_metadata);
+int GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
+                                    unsigned int *alignedw, unsigned int *alignedh,
+                                    GraphicsMetadata *graphics_metadata);
 bool CanUseAdrenoForSize(int buffer_type, uint64_t usage);
 bool GetAdrenoSizeAPIStatus();
 bool UseUncached(int format, uint64_t usage);
diff --git a/gralloc/gralloc_priv.h b/gralloc/gralloc_priv.h
index 075a6e4..f9338d6 100644
--- a/gralloc/gralloc_priv.h
+++ b/gralloc/gralloc_priv.h
@@ -83,6 +83,9 @@
 /* This flag indicates PI format is being used */
 #define GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI 1ULL << 49
 
+/* This flag is set while CDSP accesses the buffer */
+#define GRALLOC_USAGE_PRIVATE_CDSP 1ULL << 50
+
 /* Legacy gralloc1 definitions */
 /* Some clients may still be using the old flags */
 #define GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP GRALLOC_USAGE_PRIVATE_ADSP_HEAP
diff --git a/libmemtrack/kgsl.c b/libmemtrack/kgsl.c
index 69ee901..a292d45 100644
--- a/libmemtrack/kgsl.c
+++ b/libmemtrack/kgsl.c
@@ -45,100 +45,75 @@
                              size_t *num_records)
 {
     size_t allocated_records = min(*num_records, ARRAY_SIZE(record_templates));
-    FILE *fp;
-    char line[1024];
-    char tmp[128];
+    char syspath[128];
     size_t accounted_size = 0;
     size_t unaccounted_size = 0;
+    FILE *fp;
+    int ret;
 
     *num_records = ARRAY_SIZE(record_templates);
 
     /* fastpath to return the necessary number of records */
-    if (allocated_records == 0) {
+    if (allocated_records == 0)
         return 0;
-    }
 
     memcpy(records, record_templates,
-           sizeof(struct memtrack_record) * allocated_records);
+            sizeof(struct memtrack_record) * allocated_records);
 
-    snprintf(tmp, sizeof(tmp), "/d/kgsl/proc/%d/mem", pid);
-    fp = fopen(tmp, "r");
-    if (fp == NULL) {
-        return -errno;
-    }
+    if (type == MEMTRACK_TYPE_GL) {
 
-    /* Go through each line of <pid>/mem file and for every entry of type "gpumem"
-     * check if the gpubuffer entry is usermapped or not. If the entry is usermapped
-     * count the entry as accounted else count the entry as unaccounted.
-     */
-    while (1) {
-        unsigned long size, mapsize;
-        char line_type[7];
-        char flags[10];
-        char line_usage[19];
-        int ret, egl_surface_count = 0, egl_image_count = 0;
+        snprintf(syspath, sizeof(syspath),
+                 "/sys/class/kgsl/kgsl/proc/%d/gpumem_mapped", pid);
 
-        if (fgets(line, sizeof(line), fp) == NULL) {
-            break;
-        }
+        fp = fopen(syspath, "r");
+        if (fp == NULL)
+            return -errno;
 
-        /* Format:
-         *  gpuaddr useraddr     size    id flags       type            usage sglen mapsize eglsrf eglimg
-         * 545ba000 545ba000     4096     1 -----pY     gpumem      arraybuffer     1  4096      0      0
-         */
-        ret = sscanf(line, "%*x %*x %lu %*d %9s %6s %18s %*d %lu %6d %6d\n",
-                       &size, flags, line_type, line_usage, &mapsize,
-                       &egl_surface_count, &egl_image_count);
-        if (ret != 7) {
-            continue;
-        }
-
-        if (size == 0) {
+        ret = fscanf(fp, "%zu", &accounted_size);
+        if (ret != 1) {
             fclose(fp);
             return -EINVAL;
         }
+        fclose(fp);
 
-        if (unaccounted_size + size < size) {
+        snprintf(syspath, sizeof(syspath),
+                 "/sys/class/kgsl/kgsl/proc/%d/gpumem_unmapped", pid);
+
+        fp = fopen(syspath, "r");
+        if (fp == NULL) {
             fclose(fp);
-            return -ERANGE;
+            return -errno;
         }
 
-        if (type == MEMTRACK_TYPE_GL && strcmp(line_type, "gpumem") == 0) {
-
-            if (flags[6] == 'Y') {
-                if (accounted_size + mapsize < accounted_size) {
-                    fclose(fp);
-                    return -ERANGE;
-                }
-
-                accounted_size += mapsize;
-
-                if (mapsize > size) {
-                    fclose(fp);
-                    return -EINVAL;
-                }
-                unaccounted_size += size - mapsize;
-            } else {
-                unaccounted_size += size;
-            }
-        } else if (type == MEMTRACK_TYPE_GRAPHICS && strcmp(line_type, "ion") == 0) {
-            if (strcmp(line_usage, "egl_surface") == 0) {
-                unaccounted_size += size;
-            }
-            else if (egl_surface_count == 0) {
-                unaccounted_size += size / (egl_image_count ? egl_image_count : 1);
-            }
+        ret = fscanf(fp, "%zu", &unaccounted_size);
+        if (ret != 1) {
+            fclose(fp);
+            return -EINVAL;
         }
+        fclose(fp);
+
+    } else if (type == MEMTRACK_TYPE_GRAPHICS) {
+
+        snprintf(syspath, sizeof(syspath),
+                 "/sys/class/kgsl/kgsl/proc/%d/imported_mem", pid);
+
+        fp = fopen(syspath, "r");
+        if (fp == NULL)
+            return -errno;
+
+        ret = fscanf(fp, "%zu", &unaccounted_size);
+        if (ret != 1) {
+            fclose(fp);
+            return -EINVAL;
+        }
+        fclose(fp);
     }
 
-    if (allocated_records > 0) {
-        records[0].size_in_bytes = accounted_size;
-    }
-    if (allocated_records > 1) {
-        records[1].size_in_bytes = unaccounted_size;
-    }
+    if (allocated_records > 0)
+    records[0].size_in_bytes = accounted_size;
 
-    fclose(fp);
+    if (allocated_records > 1)
+    records[1].size_in_bytes = unaccounted_size;
 
     return 0;
 }
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 39ab20b..89d00c8 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -215,6 +215,7 @@
   std::string device_path = "";
   float min_downscale = 2.0f;
   bool downscale_compression = false;
+  uint64_t max_line_width = 0;
 };
 
 enum HWQseedStepVersion {
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index a68c708..6b5b065 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -491,10 +491,6 @@
   return kErrorNone;
 }
 
-DisplayState DisplayBase::GetLastPowerMode() {
-  return last_power_mode_;
-}
-
 DisplayError DisplayBase::SetDisplayState(DisplayState state, bool teardown,
                                           int *release_fence) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
@@ -532,13 +528,11 @@
     }
 
     active = true;
-    last_power_mode_ = kStateOn;
     break;
 
   case kStateDoze:
     error = hw_intf_->Doze(default_qos_data_, release_fence);
     active = true;
-    last_power_mode_ = kStateDoze;
     break;
 
   case kStateDozeSuspend:
@@ -546,12 +540,10 @@
     if (display_type_ != kBuiltIn) {
       active = true;
     }
-    last_power_mode_ = kStateDozeSuspend;
     break;
 
   case kStateStandby:
     error = hw_intf_->Standby();
-    last_power_mode_ = kStateStandby;
     break;
 
   default:
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 609eeab..35c07a4 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -157,7 +157,6 @@
   DisplayError GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
                                        std::string *value);
   bool IsSupportColorModeAttribute(const std::string &color_mode);
-  DisplayState GetLastPowerMode();
   void SetPUonDestScaler();
   void ClearColorInfo();
   void GetColorPrimaryTransferFromAttributes(const AttrVal &attr,
@@ -209,7 +208,6 @@
   uint32_t req_mixer_height_ = 0;
   std::string current_color_mode_ = "hal_native";
   int disable_hdr_lut_gen_ = 0;
-  DisplayState last_power_mode_ = kStateOff;
   bool hw_recovery_logs_captured_ = false;
   int disable_hw_recovery_dump_ = 0;
   HWQosData default_qos_data_;
diff --git a/sdm/libs/core/display_builtin.cpp b/sdm/libs/core/display_builtin.cpp
index 7503321..a28c57b 100644
--- a/sdm/libs/core/display_builtin.cpp
+++ b/sdm/libs/core/display_builtin.cpp
@@ -128,12 +128,6 @@
   uint32_t display_width = display_attributes_.x_pixels;
   uint32_t display_height = display_attributes_.y_pixels;
 
-  if (reset_panel_) {
-    DLOGW("panel is in bad state, resetting the panel");
-    ResetPanel();
-    reset_panel_ = false;
-  }
-
   if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
     error = ReconfigureMixer(new_mixer_width, new_mixer_height);
     if (error != kErrorNone) {
@@ -354,13 +348,6 @@
 
 void DisplayBuiltIn::PanelDead() {
   event_handler_->HandleEvent(kPanelDeadEvent);
-  event_handler_->Refresh();
-  {
-    lock_guard<recursive_mutex> obj(recursive_mutex_);
-    reset_panel_ = true;
-    // Handle IPC is clearing scalar and sspp luts, call same here.
-    comp_manager_->ProcessIdlePowerCollapse(display_comp_ctx_);
-  }
 }
 
 // HWEventHandler overload, not DisplayBase
@@ -423,39 +410,6 @@
            (!hw_panel_info_.dynamic_fps && hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
 }
 
-void DisplayBuiltIn::ResetPanel() {
-  DisplayError status = kErrorNone;
-  int release_fence = -1;
-
-  DLOGI("Powering off built-in/primary %d", display_id_);
-  status = SetDisplayState(kStateOff, true /* teardown */, &release_fence);
-  if (status != kErrorNone) {
-    DLOGE("power-off on built-in/primary %d failed with error = %d", display_id_, status);
-  }
-  CloseFd(&release_fence);
-
-  DLOGI("Restoring power mode on built-in/primary %d", display_id_);
-  DisplayState mode = GetLastPowerMode();
-  status = SetDisplayState(mode, false /* teardown */, &release_fence);
-  if (status != kErrorNone) {
-    DLOGE("Setting power mode = %d on built-in/primary %d failed with error = %d", mode,
-          display_id_, status);
-  }
-  CloseFd(&release_fence);
-
-  DLOGI("Enabling HWVsync");
-  status = SetVSyncState(true);
-  if (status != kErrorNone) {
-    DLOGE("enabling vsync failed for built-in/primary %d with error = %d", display_id_, status);
-  }
-
-  DLOGI("Set Color Mode %s", current_color_mode_.c_str());
-  status = SetColorMode(current_color_mode_);
-  if (status != kErrorNone) {
-    DLOGE("set color mode failed for display id %d with error = %d", display_id_, status);
-  }
-}
-
 DisplayError DisplayBuiltIn::DppsProcessOps(enum DppsOps op, void *payload, size_t size) {
   DisplayError error = kErrorNone;
   uint32_t pending;
diff --git a/sdm/libs/core/display_builtin.h b/sdm/libs/core/display_builtin.h
index 8ae7426..76aedae 100644
--- a/sdm/libs/core/display_builtin.h
+++ b/sdm/libs/core/display_builtin.h
@@ -91,13 +91,11 @@
 
  private:
   bool NeedsAVREnable();
-  void ResetPanel();
 
   std::vector<HWEvent> event_list_;
   bool avr_prop_disabled_ = false;
   bool switch_to_cmd_ = false;
   bool handle_idle_timeout_ = false;
-  bool reset_panel_ = false;
   bool commit_event_enabled_ = false;
   DppsInfo dpps_info_ = {};
   QSyncMode qsync_mode_ = kQSyncModeNone;
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 7592f36..fb949cc 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -1171,6 +1171,11 @@
   }
 }
 
+void HWDeviceDRM::ClearSolidfillStages() {
+  solid_fills_.clear();
+  SetSolidfillStages();
+}
+
 DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
   DTRACE_SCOPED();
 
@@ -1310,6 +1315,7 @@
 }
 
 DisplayError HWDeviceDRM::Flush(HWLayers *hw_layers) {
+  ClearSolidfillStages();
   int ret = NullCommit(secure_display_active_ /* synchronous */, false /* retain_planes*/);
   if (ret) {
     DLOGE("failed with error %d", ret);
@@ -1512,6 +1518,9 @@
         (refresh_rate == connector_info_.modes[mode_index].mode.vrefresh)) {
       vrefresh_ = refresh_rate;
       DLOGV_IF(kTagDriverConfig, "Set refresh rate to %d", refresh_rate);
+      SetDisplayAttributes(mode_index);
+      UpdateMixerAttributes();
+
       return kErrorNone;
     }
   }
@@ -1612,10 +1621,6 @@
 }
 
 DisplayError HWDeviceDRM::SetMixerAttributes(const HWMixerAttributes &mixer_attributes) {
-  if (IsResolutionSwitchEnabled()) {
-    return kErrorNotSupported;
-  }
-
   if (!hw_resource_.hw_dest_scalar_info.count) {
     return kErrorNotSupported;
   }
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 054ff31..ecc92b5 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -141,6 +141,7 @@
   void UpdateMixerAttributes();
   void SetSolidfillStages();
   void AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha);
+  void ClearSolidfillStages();
   void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
   void SetSrcConfig(const LayerBuffer &input_buffer, const HWRotatorMode &mode, uint32_t *config);
   void SelectCscType(const LayerBuffer &input_buffer, sde_drm::DRMCscType *type);
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index e6245a8..c700684 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -626,12 +626,16 @@
         while (Sys::getline_(caps_fs, caps)) {
           const string downscale_compression = "downscale_compression=";
           const string min_downscale = "min_downscale=";
+          const string max_line_width = "max_line_width=";
           if (caps.find(downscale_compression) != string::npos) {
             hw_resource->hw_rot_info.downscale_compression =
               std::stoi(string(caps, downscale_compression.length()));
           } else if (caps.find(min_downscale) != string::npos) {
             hw_resource->hw_rot_info.min_downscale =
               std::stof(string(caps, min_downscale.length()));
+          } else if (caps.find(max_line_width) != string::npos) {
+            hw_resource->hw_rot_info.max_line_width =
+              std::stoul(string(caps, max_line_width.length()));
           }
         }
       }
@@ -641,9 +645,10 @@
     }
   }
 
-  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f, Downscale_compression = %d",
-        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
-        hw_resource->hw_rot_info.min_downscale, hw_resource->hw_rot_info.downscale_compression);
+  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f," \
+        "Downscale_compression = %d, Max_line_width = %d", hw_resource->hw_rot_info.num_rotator,
+        hw_resource->hw_rot_info.has_downscale, hw_resource->hw_rot_info.min_downscale,
+        hw_resource->hw_rot_info.downscale_compression, hw_resource->hw_rot_info.max_line_width);
 
   return kErrorNone;
 }
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index 65b17cd..87bf9e5 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -370,13 +370,15 @@
         hw_resource->hw_rot_info.device_path = "/dev/mdss_rotator";
       } else if (!strncmp(tokens[0], "downscale", strlen("downscale"))) {
         hw_resource->hw_rot_info.has_downscale = UINT8(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "max_line_width", strlen("max_line_width"))) {
+        hw_resource->hw_rot_info.max_line_width = UINT64(atoi(tokens[1]));
       }
     }
   }
 
-  DLOGI("MDSS Rotator: Count = %d, Downscale = %d, Min_downscale = %f",
+  DLOGI("MDSS Rotator: Count = %d, Downscale = %d, Min_downscale = %f Max_line_width= %d",
         hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
-        hw_resource->hw_rot_info.min_downscale);
+        hw_resource->hw_rot_info.min_downscale, hw_resource->hw_rot_info.max_line_width);
 
   return kErrorNone;
 }
@@ -416,6 +418,8 @@
                  hw_resource->hw_rot_info.downscale_compression = UINT8(atoi(tokens[1]));
                } else if (!strncmp(tokens[0], "min_downscale", strlen("min_downscale"))) {
                  hw_resource->hw_rot_info.min_downscale = FLOAT(atof(tokens[1]));
+               } else if (!strncmp(tokens[0], "max_line_width", strlen("max_line_width"))) {
+                 hw_resource->hw_rot_info.max_line_width = UINT64(atoi(tokens[1]));
                }
              }
            }
@@ -427,9 +431,10 @@
     }
   }
 
-  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f, Downscale_compression = %d",
-        hw_resource->hw_rot_info.num_rotator, hw_resource->hw_rot_info.has_downscale,
-        hw_resource->hw_rot_info.min_downscale, hw_resource->hw_rot_info.downscale_compression);
+  DLOGI("V4L2 Rotator: Count = %d, Downscale = %d, Min_downscale = %f, Downscale_compression =%d", \
+        "Max_line_width = %d", hw_resource->hw_rot_info.num_rotator,
+        hw_resource->hw_rot_info.has_downscale, hw_resource->hw_rot_info.min_downscale,
+        hw_resource->hw_rot_info.downscale_compression, hw_resource->hw_rot_info.max_line_width);
 
   return kErrorNone;
 }
diff --git a/sdm/libs/hwc2/hwc_buffer_allocator.cpp b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
index 34db732..896c527 100644
--- a/sdm/libs/hwc2/hwc_buffer_allocator.cpp
+++ b/sdm/libs/hwc2/hwc_buffer_allocator.cpp
@@ -211,7 +211,10 @@
 
   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
   gralloc::BufferInfo info(width, height, format, alloc_flags);
-  GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
+  int ret = GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
+  if (ret < 0) {
+    return 0;
+  }
   return buffer_size;
 }
 
@@ -365,7 +368,10 @@
 
   uint32_t aligned_width = 0, aligned_height = 0, buffer_size = 0;
   gralloc::BufferInfo info(width, height, format, alloc_flags);
-  GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
+  int ret = GetBufferSizeAndDimensions(info, &buffer_size, &aligned_width, &aligned_height);
+  if (ret < 0) {
+    return kErrorParameters;
+  }
   allocated_buffer_info->stride = UINT32(aligned_width);
   allocated_buffer_info->aligned_width = UINT32(aligned_width);
   allocated_buffer_info->aligned_height = UINT32(aligned_height);
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 59cae00..665dc7d 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -435,7 +435,7 @@
   DisplayConfigFixedInfo fixed_info = {};
   display_intf_->GetConfig(&fixed_info);
   is_cmd_mode_ = fixed_info.is_cmdmode;
-  partial_update_enabled_ = fixed_info.partial_update;
+  partial_update_enabled_ = fixed_info.partial_update || (!fixed_info.is_cmdmode);
   client_target_->SetPartialUpdate(partial_update_enabled_);
 
   DLOGI("Display created with id: %d", id_);
@@ -592,12 +592,8 @@
     bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
                      (layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
                      layer->input_buffer.color_metadata.transfer == Transfer_HLG);
-    if (hdr_layer && !disable_hdr_handling_  &&
-        GetCurrentColorMode() != ColorMode::NATIVE) {
+    if (hdr_layer && !disable_hdr_handling_) {
       // Dont honor HDR when its handling is disabled
-      // Also, when the color mode is native, it implies that
-      // SF has not correctly set the mode to BT2100_PQ in the presence of an HDR layer
-      // In such cases, we should not handle HDR as the HDR mode isn't applied
       layer->input_buffer.flags.hdr = true;
       layer_stack_.flags.hdr_present = true;
     }
@@ -763,19 +759,15 @@
       if (tone_mapper_) {
         tone_mapper_->Terminate();
       }
-      last_power_mode_ = HWC2::PowerMode::Off;
       break;
     case HWC2::PowerMode::On:
       state = kStateOn;
-      last_power_mode_ = HWC2::PowerMode::On;
       break;
     case HWC2::PowerMode::Doze:
       state = kStateDoze;
-      last_power_mode_ = HWC2::PowerMode::Doze;
       break;
     case HWC2::PowerMode::DozeSuspend:
       state = kStateDozeSuspend;
-      last_power_mode_ = HWC2::PowerMode::DozeSuspend;
       break;
     default:
       return HWC2::Error::BadParameter;
@@ -811,6 +803,7 @@
     }
     ::close(release_fence);
   }
+  current_power_mode_ = mode;
   return HWC2::Error::None;
 }
 
@@ -1045,8 +1038,8 @@
   return HWC2::Error::None;
 }
 
-HWC2::PowerMode HWCDisplay::GetLastPowerMode() {
-  return last_power_mode_;
+HWC2::PowerMode HWCDisplay::GetCurrentPowerMode() {
+  return current_power_mode_;
 }
 
 HWC2::Vsync HWCDisplay::GetLastVsyncMode() {
@@ -1086,18 +1079,18 @@
       break;
     }
     case kThermalEvent:
-    case kIdlePowerCollapse:
-    case kPanelDeadEvent: {
+    case kIdlePowerCollapse: {
       SEQUENCE_WAIT_SCOPE_LOCK(HWCSession::locker_[type_]);
       validated_ = false;
     } break;
+    case kPanelDeadEvent:
     case kDisplayPowerResetEvent: {
       validated_ = false;
       if (event_handler_) {
         event_handler_->DisplayPowerReset();
       } else {
-        DLOGI("Cannot process kDisplayPowerEventReset (display = %d), event_handler_ is nullptr",
-              type_);
+        DLOGW("Cannot execute DisplayPowerReset (client_id = %d), event_handler_ is nullptr",
+              id_);
       }
     } break;
     default:
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index f931987..4fff369 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -138,7 +138,7 @@
   virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending) {
     return kErrorNotSupported;
   }
-  virtual HWC2::PowerMode GetLastPowerMode();
+  virtual HWC2::PowerMode GetCurrentPowerMode();
   virtual HWC2::Vsync GetLastVsyncMode();
   virtual int SetFrameBufferResolution(uint32_t x_pixels, uint32_t y_pixels);
   virtual void GetFrameBufferResolution(uint32_t *x_pixels, uint32_t *y_pixels);
@@ -281,8 +281,8 @@
   virtual HWC2::Error SetQSyncMode(QSyncMode qsync_mode) {
     return HWC2::Error::Unsupported;
   }
-  virtual HWC2::Error ControlIdlePowerCollapse(bool enable, bool synchronous) {
-    return HWC2::Error::Unsupported;
+  virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous) {
+    return kErrorNone;
   }
 
  protected:
@@ -341,7 +341,7 @@
   uint32_t dump_frame_count_ = 0;
   uint32_t dump_frame_index_ = 0;
   bool dump_input_layers_ = false;
-  HWC2::PowerMode last_power_mode_ = HWC2::PowerMode::Off;
+  HWC2::PowerMode current_power_mode_ = HWC2::PowerMode::Off;
   HWC2::Vsync last_vsync_mode_ = HWC2::Vsync::Invalid;
   bool swap_interval_zero_ = false;
   bool display_paused_ = false;
diff --git a/sdm/libs/hwc2/hwc_display_builtin.cpp b/sdm/libs/hwc2/hwc_display_builtin.cpp
index e242128..b368ca7 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.cpp
+++ b/sdm/libs/hwc2/hwc_display_builtin.cpp
@@ -755,15 +755,14 @@
   return HWC2::Error::None;
 }
 
-HWC2::Error HWCDisplayBuiltIn::ControlIdlePowerCollapse(bool enable, bool synchronous) {
+DisplayError HWCDisplayBuiltIn::ControlIdlePowerCollapse(bool enable, bool synchronous) {
   DisplayError error = kErrorNone;
 
   if (display_intf_) {
     error = display_intf_->ControlIdlePowerCollapse(enable, synchronous);
     validated_ = false;
   }
-
-  return (error != kErrorNone) ?  HWC2::Error::Unsupported : HWC2::Error::None;
+  return error;
 }
 
 }  // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_builtin.h b/sdm/libs/hwc2/hwc_display_builtin.h
index 6616255..d9eca1a 100644
--- a/sdm/libs/hwc2/hwc_display_builtin.h
+++ b/sdm/libs/hwc2/hwc_display_builtin.h
@@ -79,7 +79,7 @@
                                         bool post_processed_output);
   virtual HWC2::Error GetReadbackBufferFence(int32_t *release_fence);
   virtual HWC2::Error SetQSyncMode(QSyncMode qsync_mode);
-  virtual HWC2::Error ControlIdlePowerCollapse(bool enable, bool synchronous);
+  virtual DisplayError ControlIdlePowerCollapse(bool enable, bool synchronous);
   virtual HWC2::Error SetDisplayDppsAdROI(uint32_t h_start, uint32_t h_end, uint32_t v_start,
                                           uint32_t v_end, uint32_t factor_in, uint32_t factor_out);
 
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index c552137..7c48b24 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -73,6 +73,7 @@
 bool HWCSession::power_on_pending_[kNumDisplays];
 
 static const int kSolidFillDelay = 100 * 1000;
+int HWCSession::null_display_mode_ = 0;
 
 // Map the known color modes to dataspace.
 static int32_t GetDataspace(ColorMode mode) {
@@ -475,6 +476,14 @@
   }
 }
 
+uint32_t HWCSession::GetMaxVirtualDisplayCount(hwc2_device_t *device) {
+  if (device == nullptr) {
+    return HWC2_ERROR_BAD_PARAMETER;
+  }
+
+  return null_display_mode_ ? 0 : 1;
+}
+
 static int32_t GetActiveConfig(hwc2_device_t *device, hwc2_display_t display,
                                hwc2_config_t *out_config) {
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetActiveConfig, out_config);
@@ -632,13 +641,6 @@
                                          out_max_average_luminance, out_min_luminance);
 }
 
-static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device) {
-  if (device == nullptr) {
-    return HWC2_ERROR_BAD_PARAMETER;
-  }
-
-  return 1;
-}
 
 static int32_t GetReleaseFences(hwc2_device_t *device, hwc2_display_t display,
                                 uint32_t *out_num_elements, hwc2_layer_t *out_layers,
@@ -686,7 +688,7 @@
   // Handle pending builtin/pluggable display connections
   if (!hwc_session->primary_ready_ && (display == HWC_DISPLAY_PRIMARY)) {
     hwc_session->primary_ready_ = true;
-    hwc_session->CreateBuiltInDisplays();
+    hwc_session->HandleBuiltInDisplays();
     hwc_session->HandlePluggableDisplays(false);
   }
 
@@ -1023,7 +1025,7 @@
     case HWC2::FunctionDescriptor::GetDozeSupport:
       return AsFP<HWC2_PFN_GET_DOZE_SUPPORT>(GetDozeSupport);
     case HWC2::FunctionDescriptor::GetMaxVirtualDisplayCount:
-      return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(GetMaxVirtualDisplayCount);
+      return AsFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(HWCSession::GetMaxVirtualDisplayCount);
     case HWC2::FunctionDescriptor::GetReleaseFences:
       return AsFP<HWC2_PFN_GET_RELEASE_FENCES>(GetReleaseFences);
     case HWC2::FunctionDescriptor::PresentDisplay:
@@ -1101,6 +1103,12 @@
 
 HWC2::Error HWCSession::CreateVirtualDisplayObj(uint32_t width, uint32_t height, int32_t *format,
                                                 hwc2_display_t *out_display_id) {
+  if (null_display_mode_) {
+    DLOGW("Virtual display creation attempted. Not supported in null-display mode."
+          " display_id is not set, and no real display object was created");
+    return HWC2::Error::None;
+  }
+
   if (!client_connected_) {
     DLOGE("Client is not ready yet.");
     return HWC2::Error::BadDisplay;
@@ -1191,7 +1199,7 @@
   }
   auto &hwc_display = hwc_display_[builtin_id];
   if (hwc_display) {
-    return hwc_display->GetLastPowerMode() != HWC2::PowerMode::Off;
+    return hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off;
   }
   return false;
 }
@@ -2154,10 +2162,20 @@
   int status = -EINVAL;
   HWDisplaysInfo hw_displays_info = {};
 
-  DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
-  if (error != kErrorNone) {
-    DLOGE("Failed to get connected display list. Error = %d", error);
-    return status;
+  if (null_display_mode_) {
+    HWDisplayInfo hw_info = {};
+    hw_info.display_type = kBuiltIn;
+    hw_info.is_connected = 1;
+    hw_info.is_primary = 1;
+    hw_info.is_wb_ubwc_supported = 0;
+    hw_info.display_id = 1;
+    hw_displays_info[hw_info.display_id] = hw_info;
+  } else {
+    DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
+    if (error != kErrorNone) {
+      DLOGE("Failed to get connected display list. Error = %d", error);
+      return status;
+    }
   }
 
   for (auto &iter : hw_displays_info) {
@@ -2211,9 +2229,13 @@
   return status;
 }
 
-int HWCSession::CreateBuiltInDisplays() {
-  HWDisplaysInfo hw_displays_info = {};
+int HWCSession::HandleBuiltInDisplays() {
+  if (null_display_mode_) {
+    DLOGW("Skipped BuiltIn display handling in null-display mode");
+    return 0;
+  }
 
+  HWDisplaysInfo hw_displays_info = {};
   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
   if (error != kErrorNone) {
     DLOGE("Failed to get connected display list. Error = %d", error);
@@ -2263,13 +2285,17 @@
 }
 
 int HWCSession::HandlePluggableDisplays(bool delay_hotplug) {
+  if (null_display_mode_) {
+    DLOGW("Skipped pluggable display handling in null-display mode");
+    return 0;
+  }
+
   if (!primary_ready_) {
     DLOGI("Primary display is not ready. Connect displays later if any.");
     return 0;
   }
 
   HWDisplaysInfo hw_displays_info = {};
-
   DisplayError error = core_intf_->GetDisplaysStatus(&hw_displays_info);
   if (error != kErrorNone) {
     DLOGE("Failed to get connected display list. Error = %d", error);
@@ -2432,47 +2458,67 @@
 }
 
 void HWCSession::DestroyDisplay(DisplayMapInfo *map_info) {
-  hwc2_display_t client_id = map_info->client_id;
-  int notify_hotplug = false;
+  switch (map_info->disp_type) {
+    case kPluggable:
+      DestroyPluggableDisplay(map_info);
+      break;
+    default:
+      DestroyNonPluggableDisplay(map_info);
+      break;
+    }
+}
 
-  // Lock confined to this scope. Do not notify hotplug while holding a lock.
+void HWCSession::DestroyPluggableDisplay(DisplayMapInfo *map_info) {
+  hwc2_display_t client_id = map_info->client_id;
+
+  DLOGI("Notify hotplug display disconnected: client id = %d", client_id);
+  callbacks_.Hotplug(client_id, HWC2::Connection::Disconnected);
+  // wait for sufficient time to ensure sufficient resources are available to process
+  // connection.
+  usleep(UINT32(GetVsyncPeriod(HWC_DISPLAY_PRIMARY)) * 2 / 1000);
+
   {
     SCOPE_LOCK(locker_[client_id]);
-
     auto &hwc_display = hwc_display_[client_id];
     if (!hwc_display) {
       return;
     }
-
     DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type,
-          client_id);
-    switch (map_info->disp_type) {
-      case kBuiltIn:
-        HWCDisplayBuiltIn::Destroy(hwc_display);
-        break;
+         client_id);
 
-      case kPluggable:
-        if (!map_info->test_pattern) {
-          HWCDisplayPluggable::Destroy(hwc_display);
-        } else {
-          HWCDisplayPluggableTest::Destroy(hwc_display);
-        }
-        notify_hotplug = true;
-        break;
-
-      default:
-        HWCDisplayVirtual::Destroy(hwc_display);
-        break;
+    if (!map_info->test_pattern) {
+      HWCDisplayPluggable::Destroy(hwc_display);
+    } else {
+      HWCDisplayPluggableTest::Destroy(hwc_display);
     }
+
     hwc_display = nullptr;
     map_info->Reset();
     UpdateVsyncSource();
   }
+}
 
-  if (notify_hotplug) {
-    DLOGI("Notify hotplug display disconnected: client id = %d", client_id);
-    callbacks_.Hotplug(client_id, HWC2::Connection::Disconnected);
+void HWCSession::DestroyNonPluggableDisplay(DisplayMapInfo *map_info) {
+  hwc2_display_t client_id = map_info->client_id;
+
+  SCOPE_LOCK(locker_[client_id]);
+  auto &hwc_display = hwc_display_[client_id];
+  if (!hwc_display) {
+    return;
   }
+  DLOGI("Destroy display %d-%d, client id = %d", map_info->sdm_id, map_info->disp_type,
+        client_id);
+  switch (map_info->disp_type) {
+    case kBuiltIn:
+      HWCDisplayBuiltIn::Destroy(hwc_display);
+      break;
+    default:
+      HWCDisplayVirtual::Destroy(hwc_display);
+      break;
+    }
+
+    hwc_display = nullptr;
+    map_info->Reset();
 }
 
 HWC2::Error HWCSession::ValidateDisplayInternal(hwc2_display_t display, uint32_t *out_num_types,
@@ -2515,38 +2561,49 @@
 }
 
 void HWCSession::DisplayPowerReset() {
-  Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
-  Locker::ScopeLock lock_b2(locker_[HWC_DISPLAY_BUILTIN_2]);
-  Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
-  Locker::ScopeLock lock_e2(locker_[HWC_DISPLAY_EXTERNAL_2]);
-  Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
+  {
+    Locker::ScopeLock lock_p(locker_[HWC_DISPLAY_PRIMARY]);
+    Locker::ScopeLock lock_b2(locker_[HWC_DISPLAY_BUILTIN_2]);
+    Locker::ScopeLock lock_e(locker_[HWC_DISPLAY_EXTERNAL]);
+    Locker::ScopeLock lock_e2(locker_[HWC_DISPLAY_EXTERNAL_2]);
+    Locker::ScopeLock lock_v(locker_[HWC_DISPLAY_VIRTUAL]);
 
-  HWC2::Error status = HWC2::Error::None;
+    HWC2::Error status = HWC2::Error::None;
+    HWC2::PowerMode last_power_mode[HWC_NUM_DISPLAY_TYPES] = {};
 
-  for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < HWC_NUM_DISPLAY_TYPES; display++) {
-    if (hwc_display_[display] != NULL) {
-      DLOGI("Powering off display = %d", display);
-      status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::Off,
-                                                   true /* teardown */);
-      if (status != HWC2::Error::None) {
-        DLOGE("Power off for display = %d failed with error = %d", display, status);
+    for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < HWC_NUM_DISPLAY_TYPES; display++) {
+      if (hwc_display_[display] != NULL) {
+        last_power_mode[display] = hwc_display_[display]->GetCurrentPowerMode();
+        DLOGI("Powering off display = %d", display);
+        status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::Off,
+                                                     true /* teardown */);
+        if (status != HWC2::Error::None) {
+          DLOGE("Power off for display = %d failed with error = %d", display, status);
+        }
       }
     }
-  }
-  for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < HWC_NUM_DISPLAY_TYPES; display++) {
-    if (hwc_display_[display] != NULL) {
-      DLOGI("Powering on display = %d", display);
-      status = hwc_display_[display]->SetPowerMode(HWC2::PowerMode::On, false /* teardown */);
-      if (status != HWC2::Error::None) {
-        DLOGE("Power on for display = %d failed with error = %d", display, status);
+    for (hwc2_display_t display = HWC_DISPLAY_PRIMARY; display < HWC_NUM_DISPLAY_TYPES; display++) {
+      if (hwc_display_[display] != NULL) {
+        HWC2::PowerMode mode = last_power_mode[display];
+        DLOGI("Setting display %d to mode = %d", display, mode);
+        status = hwc_display_[display]->SetPowerMode(mode, false /* teardown */);
+        if (status != HWC2::Error::None) {
+          DLOGE("%d mode for display = %d failed with error = %d", mode, display, status);
+        }
+        ColorMode color_mode = hwc_display_[display]->GetCurrentColorMode();
+        status = hwc_display_[display]->SetColorMode(color_mode);
+        if (status != HWC2::Error::None) {
+          DLOGE("SetColorMode failed for display = %d error = %d", display, status);
+        }
       }
     }
-  }
 
-  status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
-  if (status != HWC2::Error::None) {
-    DLOGE("Enabling vsync failed for primary with error = %d", status);
+    status = hwc_display_[HWC_DISPLAY_PRIMARY]->SetVsyncEnabled(HWC2::Vsync::Enable);
+    if (status != HWC2::Error::None) {
+      DLOGE("Enabling vsync failed for primary with error = %d", status);
+    }
   }
+  Refresh(HWC_DISPLAY_PRIMARY);
 }
 
 void HWCSession::HandleSecureSession(hwc2_display_t disp_id) {
@@ -2740,7 +2797,7 @@
   }
 
   callbacks_.SetSwapVsync(next_vsync_source, HWC_DISPLAY_PRIMARY);
-  HWC2::PowerMode power_mode = hwc_display_[next_vsync_source]->GetLastPowerMode();
+  HWC2::PowerMode power_mode = hwc_display_[next_vsync_source]->GetCurrentPowerMode();
 
   // Skip enabling vsync if display is Off, happens only for default source ie; primary.
   if (power_mode == HWC2::PowerMode::Off) {
@@ -2768,7 +2825,7 @@
       continue;
     }
 
-    if (hwc_display->GetLastPowerMode() != HWC2::PowerMode::Off) {
+    if (hwc_display->GetCurrentPowerMode() != HWC2::PowerMode::Off) {
       return info.client_id;
     }
   }
@@ -2791,8 +2848,8 @@
       return -EINVAL;
     }
     auto error = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
-    if (error != HWC2::Error::None) {
-      return -EINVAL;
+    if (error != kErrorNone) {
+      return (error == kErrorNotSupported) ? 0 : -EINVAL;
     }
     if (!enable) {
       Refresh(HWC_DISPLAY_PRIMARY);
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 20c537b..b71bf3f 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -203,6 +203,7 @@
                                    const native_handle_t *buffer, int32_t acquire_fence);
   static int32_t GetReadbackBufferFence(hwc2_device_t *device, hwc2_display_t display,
                                         int32_t *release_fence);
+  static uint32_t GetMaxVirtualDisplayCount(hwc2_device_t *device);
 
   // HWCDisplayEventHandler
   virtual void DisplayPowerReset();
@@ -244,11 +245,13 @@
   void InitDisplaySlots();
   int GetDisplayIndex(int dpy);
   int CreatePrimaryDisplay();
-  int CreateBuiltInDisplays();
+  int HandleBuiltInDisplays();
   int HandlePluggableDisplays(bool delay_hotplug);
   int HandleConnectedDisplays(HWDisplaysInfo *hw_displays_info, bool delay_hotplug);
   int HandleDisconnectedDisplays(HWDisplaysInfo *hw_displays_info);
   void DestroyDisplay(DisplayMapInfo *map_info);
+  void DestroyPluggableDisplay(DisplayMapInfo *map_info);
+  void DestroyNonPluggableDisplay(DisplayMapInfo *map_info);
   int GetVsyncPeriod(int disp);
   int32_t GetConfigCount(int disp_id, uint32_t *count);
   int32_t GetActiveConfigIndex(int disp_id, uint32_t *config);
@@ -377,8 +380,8 @@
   Locker callbacks_lock_;
   int hpd_bpp_ = 0;
   int hpd_pattern_ = 0;
-  int null_display_mode_ = 0;
   static bool power_on_pending_[kNumDisplays];
+  static int null_display_mode_;
   HotPlugEvent hotplug_pending_event_ = kHotPlugNone;
   bool destroy_virtual_disp_pending_ = false;
   uint32_t idle_pc_ref_cnt_ = 0;
diff --git a/sdm/libs/hwc2/hwc_session_services.cpp b/sdm/libs/hwc2/hwc_session_services.cpp
index c00fc58..6fb1ec2 100644
--- a/sdm/libs/hwc2/hwc_session_services.cpp
+++ b/sdm/libs/hwc2/hwc_session_services.cpp
@@ -600,10 +600,9 @@
   if (hwc_display_[HWC_DISPLAY_PRIMARY]) {
     if (!enable) {
       if (!idle_pc_ref_cnt_) {
-        HWC2::Error err =
-            hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
-        if (err != HWC2::Error::None) {
-          return (err == HWC2::Error::Unsupported) ? 0 : -EINVAL;
+        auto err = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
+        if (err != kErrorNone) {
+          return (err == kErrorNotSupported) ? 0 : -EINVAL;
         }
         Refresh(HWC_DISPLAY_PRIMARY);
         int32_t error = locker_[HWC_DISPLAY_PRIMARY].WaitFinite(kCommitDoneTimeoutMs);
@@ -616,10 +615,9 @@
       idle_pc_ref_cnt_++;
     } else if (idle_pc_ref_cnt_ > 0) {
       if (!(idle_pc_ref_cnt_ - 1)) {
-        HWC2::Error err =
-            hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
-        if (err != HWC2::Error::None) {
-          return (err == HWC2::Error::Unsupported) ? 0 : -EINVAL;
+        auto err = hwc_display_[HWC_DISPLAY_PRIMARY]->ControlIdlePowerCollapse(enable, synchronous);
+        if (err != kErrorNone) {
+          return (err == kErrorNotSupported) ? 0 : -EINVAL;
         }
         DLOGI("Idle PC enabled!!");
       }