Merge "sdm: color-manager: Frame capture interface."
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 24a0aa1..142586b 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 The Android Open Source Project
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -55,27 +55,6 @@
     return memalloc;
 }
 
-static int gralloc_map_metadata(buffer_handle_t handle) {
-    private_handle_t* hnd = (private_handle_t*)handle;
-    hnd->base_metadata = 0;
-    IMemAlloc* memalloc = getAllocator(hnd->flags) ;
-    void *mappedAddress = MAP_FAILED;
-    unsigned int size = 0;
-    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
-        mappedAddress = MAP_FAILED;
-        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
-        int ret = memalloc->map_buffer(&mappedAddress, size,
-                                       hnd->offset_metadata, hnd->fd_metadata);
-        if(ret || mappedAddress == MAP_FAILED) {
-            ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)",
-                  hnd, hnd->fd_metadata, strerror(errno));
-            return -errno;
-        }
-        hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
-    }
-    return 0;
-}
-
 static int gralloc_map(gralloc_module_t const* module,
                        buffer_handle_t handle)
 {
@@ -89,6 +68,7 @@
     IMemAlloc* memalloc = getAllocator(hnd->flags) ;
     void *mappedAddress = MAP_FAILED;
     hnd->base = 0;
+    hnd->base_metadata = 0;
 
     // Dont map framebuffer and secure buffers
     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
@@ -103,21 +83,23 @@
         }
 
         hnd->base = uint64_t(mappedAddress) + hnd->offset;
-    } else {
-        // Cannot map secure buffers or framebuffers, but still need to map
-        // metadata for secure buffers.
-        // If mapping a secure buffers fails, the framework needs to get
-        // an error code.
-        err = -EINVAL;
     }
 
     //Allow mapping of metadata for all buffers including secure ones, but not
     //of framebuffer
-    int metadata_err = gralloc_map_metadata(handle);
-    if (!err) {
-        err = metadata_err;
+    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
+        mappedAddress = MAP_FAILED;
+        size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
+        err = memalloc->map_buffer(&mappedAddress, size,
+                                       hnd->offset_metadata, hnd->fd_metadata);
+        if(err || mappedAddress == MAP_FAILED) {
+            ALOGE("Could not mmap handle %p, fd=%d (%s)",
+                  handle, hnd->fd_metadata, strerror(errno));
+            return -errno;
+        }
+        hnd->base_metadata = uint64_t(mappedAddress) + hnd->offset_metadata;
     }
-    return err;
+    return 0;
 }
 
 static int gralloc_unmap(gralloc_module_t const* module,
@@ -170,11 +152,21 @@
     ATRACE_CALL();
     if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
-    // The base address received via IPC is invalid in this process
-    // Reset it to 0 here since it will be mapped in lock()
-    private_handle_t* hnd = (private_handle_t*)handle;
-    hnd->base = 0;
-    return gralloc_map_metadata(handle);
+
+    /* NOTE: we need to initialize the buffer as not mapped/not locked
+     * because it shouldn't when this function is called the first time
+     * in a new process. Ideally these flags shouldn't be part of the
+     * handle, but instead maintained in the kernel or at least
+     * out-of-line
+     */
+
+    int err = gralloc_map(module, handle);
+    if (err) {
+        ALOGE("%s: gralloc_map failed", __FUNCTION__);
+        return err;
+    }
+
+    return 0;
 }
 
 int gralloc_unregister_buffer(gralloc_module_t const* module,
diff --git a/libqdutils/display_config.cpp b/libqdutils/display_config.cpp
index 3415ac6..c1335b1 100644
--- a/libqdutils/display_config.cpp
+++ b/libqdutils/display_config.cpp
@@ -78,7 +78,7 @@
         dpyattr.yres = outParcel.readInt32();
         dpyattr.xdpi = outParcel.readFloat();
         dpyattr.ydpi = outParcel.readFloat();
-        dpyattr.panel_type = (char) outParcel.readInt32();
+        dpyattr.panel_type = outParcel.readInt32();
     } else {
         ALOGE("%s() failed with err %d", __FUNCTION__, err);
     }
@@ -237,7 +237,7 @@
 }
 
 DisplayAttributes getDisplayAttributes(int configIndex, int /*dpy*/) {
-    DisplayAttributes dpyattr;
+    DisplayAttributes dpyattr = {};
     sp<IQService> binder = getBinder();
     if(binder != NULL) {
         Parcel inParcel, outParcel;
@@ -252,7 +252,7 @@
             dpyattr.yres = outParcel.readInt32();
             dpyattr.xdpi = outParcel.readFloat();
             dpyattr.ydpi = outParcel.readFloat();
-            dpyattr.panel_type = (char) outParcel.readInt32();
+            dpyattr.panel_type = outParcel.readInt32();
             dpyattr.is_yuv = outParcel.readInt32();
             ALOGI("%s() Received attrs for index %d: xres %d, yres %d",
                     __FUNCTION__, configIndex, dpyattr.xres, dpyattr.yres);
diff --git a/libqdutils/display_config.h b/libqdutils/display_config.h
index 15aba94..6512bf5 100644
--- a/libqdutils/display_config.h
+++ b/libqdutils/display_config.h
@@ -76,18 +76,26 @@
     COMMAND_MODE,
 };
 
+enum {
+    DISPLAY_PORT_DEFAULT = 0,
+    DISPLAY_PORT_DSI,
+    DISPLAY_PORT_DTV,
+    DISPLAY_PORT_WRITEBACK,
+    DISPLAY_PORT_LVDS,
+    DISPLAY_PORT_EDP,
+    DISPLAY_PORT_DP,
+};
+
 // Display Attributes that are available to clients of this library
 // Not to be confused with a similar struct in hwc_utils (in the hwc namespace)
 typedef struct DisplayAttributes {
-    uint32_t vsync_period; //nanoseconds
-    uint32_t xres;
-    uint32_t yres;
-    float xdpi;
-    float ydpi;
-    char panel_type;
-    bool is_yuv;
-    DisplayAttributes() : vsync_period(0), xres(0), yres(0), xdpi(0.0f),
-            ydpi(0.0f), panel_type(0), is_yuv(false) {}
+    uint32_t vsync_period = 0; //nanoseconds
+    uint32_t xres = 0;
+    uint32_t yres = 0;
+    float xdpi = 0.0f;
+    float ydpi = 0.0f;
+    int panel_type = DISPLAY_PORT_DEFAULT;
+    bool is_yuv = false;
 } DisplayAttributes_t;
 
 //=============================================================================
diff --git a/libqservice/IQService.cpp b/libqservice/IQService.cpp
index d47f2e9..e1c5219 100644
--- a/libqservice/IQService.cpp
+++ b/libqservice/IQService.cpp
@@ -92,6 +92,7 @@
             callerUid == AID_GRAPHICS ||
             callerUid == AID_ROOT ||
             callerUid == AID_CAMERASERVER ||
+            callerUid == AID_AUDIO ||
             callerUid == AID_SYSTEM);
 
     if (code == CONNECT_HWC_CLIENT) {
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index bb89d1d..ebb16d5 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -118,6 +118,20 @@
   kContentQualityMax,
 };
 
+/*! @brief This enum represents the display port.
+
+  @sa DisplayInterface::GetDisplayPort
+*/
+enum DisplayPort {
+  kPortDefault,
+  kPortDSI,        // Display is connected to DSI port.
+  kPortDTV,        // Display is connected to DTV port
+  kPortWriteBack,  // Display is connected to writeback port
+  kPortLVDS,       // Display is connected to LVDS port
+  kPortEDP,        // Display is connected to EDP port
+  kPortDP,         // Display is connected to DP port.
+};
+
 /*! @brief This structure defines configuration for fixed properties of a display device.
 
   @sa DisplayInterface::GetConfig
@@ -573,6 +587,14 @@
   */
   virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data) = 0;
 
+  /*! @brief Method to get display port information.
+
+    @param[out] port \link DisplayPort \endlink
+
+    @return \link DisplayError \endlink
+  */
+  virtual DisplayError GetDisplayPort(DisplayPort *port) = 0;
+
  protected:
   virtual ~DisplayInterface() { }
 };
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index e806d92..fd84fc1 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -34,6 +34,8 @@
 #include <bitset>
 
 namespace sdm {
+using std::string;
+
 const int kMaxSDELayers = 16;   // Maximum number of layers that can be handled by hardware in a
                                 // given layer stack.
 #define MAX_PLANES 4
@@ -63,15 +65,6 @@
   kModeCommand,
 };
 
-enum HWDisplayPort {
-  kPortDefault,
-  kPortDSI,
-  kPortDTv,
-  kPortWriteBack,
-  kPortLVDS,
-  kPortEDP,
-};
-
 enum PipeType {
   kPipeTypeUnused,
   kPipeTypeVIG,
@@ -110,6 +103,11 @@
   kMultiRectParallelMode = 0x04,
 };
 
+enum HWAVRModes {
+  kContinuousMode,  // Mode to enable AVR feature for every frame.
+  kOneShotMode,     // Mode to enable AVR feature for particular frame.
+};
+
 typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
 
 struct HWDynBwLimitInfo {
@@ -188,6 +186,7 @@
   FormatsMap supported_formats_map;
   HWRotatorInfo hw_rot_info;
   HWDestScalarInfo hw_dest_scalar_info;
+  bool has_avr = false;
 
   void Reset() { *this = HWResourceInfo(); }
 };
@@ -215,7 +214,7 @@
 };
 
 struct HWPanelInfo {
-  HWDisplayPort port = kPortDefault;  // Display port
+  DisplayPort port = kPortDefault;    // Display port
   HWDisplayMode mode = kModeDefault;  // Display mode
   bool partial_update = false;        // Partial update feature
   int left_align = 0;                 // ROI left alignment restriction
@@ -226,6 +225,7 @@
   int min_roi_height = 0;             // Min height needed for ROI
   bool needs_roi_merge = false;       // Merge ROI's of both the DSI's
   bool dynamic_fps = false;           // Panel Supports dynamic fps
+  bool dfps_porch_mode = false;       // dynamic fps VFP or HFP mode
   uint32_t min_fps = 0;               // Min fps supported by panel
   uint32_t max_fps = 0;               // Max fps supported by panel
   bool is_primary_panel = false;      // Panel is primary display
@@ -244,6 +244,7 @@
             (min_roi_height != panel_info.min_roi_height) ||
             (needs_roi_merge != panel_info.needs_roi_merge) ||
             (dynamic_fps != panel_info.dynamic_fps) || (min_fps != panel_info.min_fps) ||
+            (dfps_porch_mode != panel_info.dfps_porch_mode) ||
             (max_fps != panel_info.max_fps) || (is_primary_panel != panel_info.is_primary_panel) ||
             (split_info != panel_info.split_info) ||
             (s3d_mode != panel_info.s3d_mode));
@@ -386,6 +387,11 @@
 
 typedef std::map<uint32_t, HWDestScaleInfo *> DestScaleInfoMap;
 
+struct HWAVRInfo {
+  bool enable = false;                // Flag to Enable AVR feature
+  HWAVRModes mode = kContinuousMode;  // Specifies the AVR mode
+};
+
 struct HWPipeInfo {
   uint32_t pipe_id = 0;
   HWSubBlockType sub_block_type = kHWSubBlockMax;
@@ -436,6 +442,7 @@
   float output_compression = 1.0f;
   uint32_t bandwidth = 0;
   uint32_t clock = 0;
+  HWAVRInfo hw_avr_info = {};
 };
 
 struct HWDisplayAttributes : DisplayConfigVariableInfo {
diff --git a/sdm/include/utils/debug.h b/sdm/include/utils/debug.h
index 23ba181..415a010 100644
--- a/sdm/include/utils/debug.h
+++ b/sdm/include/utils/debug.h
@@ -69,11 +69,13 @@
   static bool IsRotatorDownScaleDisabled();
   static bool IsDecimationDisabled();
   static int GetMaxPipesPerMixer(DisplayType display_type);
+  static int GetMaxVideoUpscale();
   static bool IsVideoModeEnabled();
   static bool IsRotatorUbwcDisabled();
   static bool IsRotatorSplitDisabled();
   static bool IsScalarDisabled();
   static bool IsUbwcTiledFrameBuffer();
+  static bool IsAVRDisabled();
   static bool GetProperty(const char *property_name, char *value);
   static bool SetProperty(const char *property_name, const char *value);
 
diff --git a/sdm/include/utils/locker.h b/sdm/include/utils/locker.h
index fffe634..0096098 100644
--- a/sdm/include/utils/locker.h
+++ b/sdm/include/utils/locker.h
@@ -146,7 +146,7 @@
     ts.tv_sec = tv.tv_sec + ms/1000;
     ts.tv_nsec = tv.tv_usec*1000 + (ms%1000)*1000000;
     ts.tv_sec += ts.tv_nsec/1000000000L;
-    ts.tv_nsec += ts.tv_nsec%1000000000L;
+    ts.tv_nsec %= 1000000000L;
     return pthread_cond_timedwait(&condition_, &mutex_, &ts);
   }
 
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 1f28e6e..948e261 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -219,8 +219,6 @@
     disable_pu_one_frame_ = false;
   }
 
-  // Clean hw layers for reuse.
-  hw_layers_ = HWLayers();
   hw_layers_.info.stack = layer_stack;
   hw_layers_.output_compression = 1.0f;
 
@@ -1038,4 +1036,16 @@
   return kErrorNone;
 }
 
+DisplayError DisplayBase::GetDisplayPort(DisplayPort *port) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+  if (!port) {
+    return kErrorParameters;
+  }
+
+  *port = hw_panel_info_.port;
+
+  return kErrorNone;
+}
+
 }  // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index 7fdb714..2ef6eb5 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -109,6 +109,7 @@
   virtual DisplayError SetFrameBufferConfig(const DisplayConfigVariableInfo &variable_info);
   virtual DisplayError GetFrameBufferConfig(DisplayConfigVariableInfo *variable_info);
   virtual DisplayError SetDetailEnhancerData(const DisplayDetailEnhancerData &de_data);
+  virtual DisplayError GetDisplayPort(DisplayPort *port);
 
  protected:
   // DumpImpl method
diff --git a/sdm/libs/core/display_hdmi.cpp b/sdm/libs/core/display_hdmi.cpp
index 6e2a7b5..3c3d9f4 100644
--- a/sdm/libs/core/display_hdmi.cpp
+++ b/sdm/libs/core/display_hdmi.cpp
@@ -114,6 +114,9 @@
 
   SetS3DMode(layer_stack);
 
+  // Clean hw layers for reuse.
+  hw_layers_ = HWLayers();
+
   return DisplayBase::Prepare(layer_stack);
 }
 
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index 05e5dc3..e8689ea 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -70,6 +70,8 @@
     }
   }
 
+  avr_prop_disabled_ = Debug::IsAVRDisabled();
+
   error = HWEventsInterface::Create(INT(display_type_), this, &event_list_, &hw_events_intf_);
   if (error != kErrorNone) {
     DLOGE("Failed to create hardware events interface. Error = %d", error);
@@ -95,6 +97,10 @@
     }
   }
 
+  // Clean hw layers for reuse.
+  hw_layers_ = HWLayers();
+  hw_layers_.hw_avr_info.enable = NeedsAVREnable();
+
   return DisplayBase::Prepare(layer_stack);
 }
 
@@ -294,5 +300,15 @@
   return kErrorNone;
 }
 
+bool DisplayPrimary::NeedsAVREnable() {
+  if (avr_prop_disabled_) {
+    return false;
+  }
+
+  return (hw_panel_info_.mode == kModeVideo && ((hw_panel_info_.dynamic_fps &&
+          hw_panel_info_.dfps_porch_mode) || (!hw_panel_info_.dynamic_fps &&
+          hw_panel_info_.min_fps != hw_panel_info_.max_fps)));
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index c20ff09..7a03005 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -60,9 +60,12 @@
   virtual void CECMessage(char *message) { }
 
  private:
+  bool NeedsAVREnable();
+
   uint32_t idle_timeout_ms_ = 0;
   std::vector<const char *> event_list_ = {"vsync_event", "show_blank_event", "idle_notify",
                                            "msm_fb_thermal_level", "thread_exit"};
+  bool avr_prop_disabled_ = false;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/display_virtual.cpp b/sdm/libs/core/display_virtual.cpp
index 783cacd..6beea5c 100644
--- a/sdm/libs/core/display_virtual.cpp
+++ b/sdm/libs/core/display_virtual.cpp
@@ -130,5 +130,15 @@
   return kErrorNone;
 }
 
+DisplayError DisplayVirtual::Prepare(LayerStack *layer_stack) {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+  // Clean hw layers for reuse.
+  hw_layers_ = HWLayers();
+
+  return DisplayBase::Prepare(layer_stack);
+}
+
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_virtual.h b/sdm/libs/core/display_virtual.h
index 20ccc6e..3207ec1 100644
--- a/sdm/libs/core/display_virtual.h
+++ b/sdm/libs/core/display_virtual.h
@@ -39,6 +39,7 @@
                  BufferSyncHandler *buffer_sync_handler, CompManager *comp_manager,
                  RotatorInterface *rotator_intf);
   virtual DisplayError Init();
+  virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError GetNumVariableInfoConfigs(uint32_t *count);
   virtual DisplayError GetConfig(uint32_t index, DisplayConfigVariableInfo *variable_info);
   virtual DisplayError GetActiveConfig(uint32_t *index);
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 0a72c17..c0c76b4 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -836,6 +836,8 @@
         panel_info->needs_roi_merge = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "dyn_fps_en", strlen("dyn_fps_en"))) {
         panel_info->dynamic_fps = atoi(tokens[1]);
+      } else if (!strncmp(tokens[0], "dfps_porch_mode", strlen("dfps_porch_mode"))) {
+        panel_info->dfps_porch_mode = atoi(tokens[1]);
       } else if (!strncmp(tokens[0], "min_fps", strlen("min_fps"))) {
         panel_info->min_fps = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "max_fps", strlen("max_fps"))) {
@@ -848,13 +850,16 @@
     }
   }
 
-  GetHWDisplayPortAndMode(device_node, &panel_info->port, &panel_info->mode);
+  GetHWDisplayPortAndMode(device_node, panel_info);
   GetSplitInfo(device_node, panel_info);
   GetHWPanelNameByNode(device_node, panel_info);
   GetHWPanelMaxBrightnessFromNode(panel_info);
 }
 
-void HWDevice::GetHWDisplayPortAndMode(int device_node, HWDisplayPort *port, HWDisplayMode *mode) {
+void HWDevice::GetHWDisplayPortAndMode(int device_node, HWPanelInfo *panel_info) {
+  DisplayPort *port = &panel_info->port;
+  HWDisplayMode *mode = &panel_info->mode;
+
   *port = kPortDefault;
   *mode = kModeDefault;
 
@@ -884,11 +889,14 @@
     *port = kPortEDP;
     *mode = kModeVideo;
   } else if ((strncmp(line.c_str(), "dtv panel", strlen("dtv panel")) == 0)) {
-    *port = kPortDTv;
+    *port = kPortDTV;
     *mode = kModeVideo;
   } else if ((strncmp(line.c_str(), "writeback panel", strlen("writeback panel")) == 0)) {
     *port = kPortWriteBack;
     *mode = kModeCommand;
+  } else if ((strncmp(line.c_str(), "dp panel", strlen("dp panel")) == 0)) {
+    *port = kPortDP;
+    *mode = kModeVideo;
   }
 
   return;
@@ -1095,6 +1103,10 @@
 DisplayError HWDevice::SetVSyncState(bool enable) {
   int vsync_on = enable ? 1 : 0;
   if (Sys::ioctl_(device_fd_, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_on) < 0) {
+    if (errno == ESHUTDOWN) {
+      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
+      return kErrorShutDown;
+    }
     IOCTL_LOGE(MSMFB_OVERLAY_VSYNC_CTRL, device_type_);
     return kErrorHardware;
   }
@@ -1183,6 +1195,10 @@
   cfg.payload = reinterpret_cast<uint64_t>(&mdp_lut_info);
 
   if (Sys::ioctl_(device_fd_, MSMFB_MDP_SET_CFG, &cfg) < 0) {
+    if (errno == ESHUTDOWN) {
+      DLOGI_IF(kTagDriverConfig, "Driver is processing shutdown sequence");
+      return kErrorShutDown;
+    }
     IOCTL_LOGE(MSMFB_MDP_SET_CFG, device_type_);
     return kErrorHardware;
   }
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 7e85e26..8916dc4 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -115,7 +115,7 @@
   void PopulateHWPanelInfo();
   void GetHWPanelInfoByNode(int device_node, HWPanelInfo *panel_info);
   void GetHWPanelNameByNode(int device_node, HWPanelInfo *panel_info);
-  void GetHWDisplayPortAndMode(int device_node, HWDisplayPort *port, HWDisplayMode *mode);
+  void GetHWDisplayPortAndMode(int device_node, HWPanelInfo *panel_info);
   void GetSplitInfo(int device_node, HWPanelInfo *panel_info);
   void GetHWPanelMaxBrightnessFromNode(HWPanelInfo *panel_info);
   int ParseLine(const char *input, char *tokens[], const uint32_t max_token, uint32_t *count);
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index dc01e39..81d81a3 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -249,6 +249,8 @@
             hw_resource->has_qseed3 = true;
           } else if (!strncmp(tokens[i], "concurrent_writeback", strlen("concurrent_writeback"))) {
             hw_resource->has_concurrent_writeback = true;
+          } else if (!strncmp(tokens[i], "avr", strlen("avr"))) {
+            hw_resource->has_avr = true;
           }
         }
       } else if (!strncmp(tokens[0], "pipe_count", strlen("pipe_count"))) {
diff --git a/sdm/libs/core/fb/hw_primary.cpp b/sdm/libs/core/fb/hw_primary.cpp
index 4a8cc1f..1659625 100644
--- a/sdm/libs/core/fb/hw_primary.cpp
+++ b/sdm/libs/core/fb/hw_primary.cpp
@@ -57,6 +57,14 @@
 #define MDP_COMMIT_CWB_DSPP 0x1000
 #endif
 
+#ifndef MDP_COMMIT_AVR_EN
+#define MDP_COMMIT_AVR_EN 0x08
+#endif
+
+#ifndef MDP_COMMIT_AVR_ONE_SHOT_MODE
+#define MDP_COMMIT_AVR_ONE_SHOT_MODE 0x10
+#endif
+
 namespace sdm {
 
 using std::string;
@@ -391,6 +399,10 @@
     DLOGI_IF(kTagDriverConfig, "****************************************************************");
   }
 
+  if (hw_resource_.has_avr) {
+    SetAVRFlags(hw_layers->hw_avr_info, &mdp_commit.flags);
+  }
+
   return HWDevice::Validate(hw_layers);
 }
 
@@ -627,5 +639,15 @@
       hw_panel_info_.split_info.left_split : mixer_attributes_.width;
 }
 
+void HWPrimary::SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags) {
+  if (hw_avr_info.enable) {
+    *avr_flags |= MDP_COMMIT_AVR_EN;
+  }
+
+  if (hw_avr_info.mode == kOneShotMode) {
+    *avr_flags |= MDP_COMMIT_AVR_ONE_SHOT_MODE;
+  }
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/fb/hw_primary.h b/sdm/libs/core/fb/hw_primary.h
index a517b06..ae45318 100644
--- a/sdm/libs/core/fb/hw_primary.h
+++ b/sdm/libs/core/fb/hw_primary.h
@@ -77,6 +77,7 @@
   bool IsResolutionSwitchEnabled() { return !display_configs_.empty(); }
   bool GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels);
   void UpdateMixerAttributes();
+  void SetAVRFlags(const HWAVRInfo &hw_avr_info, uint32_t *avr_flags);
 
   std::vector<DisplayConfigVariableInfo> display_configs_;
   std::vector<std::string> display_config_strings_;
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index dc66bc7..be02ac7 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -486,16 +486,24 @@
 
     // For dim layers, SurfaceFlinger
     //    - converts planeAlpha to per pixel alpha,
-    //    - sets RGB color to 000,
+    //    - sets appropriate RGB color,
     //    - sets planeAlpha to 0xff,
     //    - blending to Premultiplied.
     // This can be achieved at hardware by
-    //    - solid fill ARGB to 0xff000000,
+    //    - solid fill ARGB to appropriate value,
     //    - incoming planeAlpha,
     //    - blending to Coverage.
     if (hwc_layer.flags & kDimLayer) {
       layer->input_buffer->format = kFormatARGB8888;
       layer->solid_fill_color = 0xff000000;
+#ifdef QTI_BSP
+      // Get ARGB color from HWC Dim Layer color
+      uint32_t a = UINT32(hwc_layer.color.a) << 24;
+      uint32_t r = UINT32(hwc_layer.color.r) << 16;
+      uint32_t g = UINT32(hwc_layer.color.g) << 8;
+      uint32_t b = UINT32(hwc_layer.color.b);
+      layer->solid_fill_color = a | r | g | b;
+#endif
       SetBlending(HWC_BLENDING_COVERAGE, &layer->blending);
     } else {
       SetBlending(hwc_layer.blending, &layer->blending);
@@ -581,8 +589,9 @@
         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
         // so that previous buffer and fences are released, and override the error.
         flush_ = true;
+      } else {
+        DLOGI("Prepare failed for Display = %d Error = %d", type_, error);
       }
-
       return 0;
     }
   } else {
@@ -658,6 +667,8 @@
         // To prevent surfaceflinger infinite wait, flush the previous frame during Commit()
         // so that previous buffer and fences are released, and override the error.
         flush_ = true;
+      } else {
+        DLOGI("Commit failed for Display = %d Error = %d", type_, error);
       }
     }
   }
@@ -1386,4 +1397,9 @@
   return (dirty_regions.empty() || IsValid(dirty_regions.at(0)));
 }
 
+int HWCDisplay::GetDisplayPort(DisplayPort *port) {
+  return display_intf_->GetDisplayPort(port) == kErrorNone ? 0 : -1;
+}
+
+
 }  // namespace sdm
diff --git a/sdm/libs/hwc/hwc_display.h b/sdm/libs/hwc/hwc_display.h
index 3e519a6..014bd02 100644
--- a/sdm/libs/hwc/hwc_display.h
+++ b/sdm/libs/hwc/hwc_display.h
@@ -117,6 +117,7 @@
                            PPPendingParams *pending_action);
   int GetVisibleDisplayRect(hwc_rect_t* rect);
   DisplayClass GetDisplayClass();
+  int GetDisplayPort(DisplayPort *port);
 
  protected:
   enum DisplayStatus {
diff --git a/sdm/libs/hwc/hwc_session.cpp b/sdm/libs/hwc/hwc_session.cpp
index b00968c..a49417d 100644
--- a/sdm/libs/hwc/hwc_session.cpp
+++ b/sdm/libs/hwc/hwc_session.cpp
@@ -476,11 +476,6 @@
   if (hwc_session->hwc_display_[disp]) {
     status = hwc_session->hwc_display_[disp]->SetPowerMode(mode);
   }
-  if (disp == HWC_DISPLAY_PRIMARY && hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]) {
-    // Set the power mode for virtual display while setting power mode for primary, as SF
-    // does not invoke SetPowerMode() for virtual display.
-    status = hwc_session->hwc_display_[HWC_DISPLAY_VIRTUAL]->SetPowerMode(mode);
-  }
 
   return status;
 }
@@ -940,6 +935,41 @@
   return error;
 }
 
+android::status_t HWCSession::SetDisplayPort(DisplayPort sdm_disp_port, int *hwc_disp_port) {
+  if (!hwc_disp_port) {
+    return -EINVAL;
+  }
+
+  switch (sdm_disp_port) {
+    case kPortDSI:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_DSI;
+      break;
+    case kPortDTV:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_DTV;
+      break;
+    case kPortLVDS:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_LVDS;
+      break;
+    case kPortEDP:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_EDP;
+      break;
+    case kPortWriteBack:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_WRITEBACK;
+      break;
+    case kPortDP:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_DP;
+      break;
+    case kPortDefault:
+      *hwc_disp_port = qdutils::DISPLAY_PORT_DEFAULT;
+      break;
+    default:
+      DLOGE("Invalid sdm display port %d", sdm_disp_port);
+      return -EINVAL;
+  }
+
+  return 0;
+}
+
 android::status_t HWCSession::HandleGetDisplayAttributesForConfig(const android::Parcel
                                                                   *input_parcel,
                                                                   android::Parcel *output_parcel) {
@@ -947,6 +977,8 @@
   int dpy = input_parcel->readInt32();
   int error = android::BAD_VALUE;
   DisplayConfigVariableInfo display_attributes;
+  DisplayPort sdm_disp_port = kPortDefault;
+  int hwc_disp_port = qdutils::DISPLAY_PORT_DEFAULT;
 
   if (dpy > HWC_DISPLAY_VIRTUAL) {
     return android::BAD_VALUE;
@@ -955,12 +987,16 @@
   if (hwc_display_[dpy]) {
     error = hwc_display_[dpy]->GetDisplayAttributesForConfig(config, &display_attributes);
     if (error == 0) {
+      hwc_display_[dpy]->GetDisplayPort(&sdm_disp_port);
+
+      SetDisplayPort(sdm_disp_port, &hwc_disp_port);
+
       output_parcel->writeInt32(INT(display_attributes.vsync_period_ns));
       output_parcel->writeInt32(INT(display_attributes.x_pixels));
       output_parcel->writeInt32(INT(display_attributes.y_pixels));
       output_parcel->writeFloat(display_attributes.x_dpi);
       output_parcel->writeFloat(display_attributes.y_dpi);
-      output_parcel->writeInt32(0);  // Panel type, unsupported.
+      output_parcel->writeInt32(hwc_disp_port);
       output_parcel->writeInt32(display_attributes.is_yuv);
     }
   }
diff --git a/sdm/libs/hwc/hwc_session.h b/sdm/libs/hwc/hwc_session.h
index 2a732b2..54b7260 100644
--- a/sdm/libs/hwc/hwc_session.h
+++ b/sdm/libs/hwc/hwc_session.h
@@ -124,6 +124,7 @@
   android::status_t GetBWTransactionStatus(const android::Parcel *input_parcel,
                                           android::Parcel *output_parcel);
   android::status_t SetMixerResolution(const android::Parcel *input_parcel);
+  android::status_t SetDisplayPort(DisplayPort sdm_disp_port, int *hwc_disp_port);
 
   static Locker locker_;
   CoreInterface *core_intf_ = NULL;
diff --git a/sdm/libs/utils/debug.cpp b/sdm/libs/utils/debug.cpp
index b91cdf4..62a8b70 100644
--- a/sdm/libs/utils/debug.cpp
+++ b/sdm/libs/utils/debug.cpp
@@ -99,6 +99,13 @@
   return value;
 }
 
+int Debug::GetMaxVideoUpscale() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.video_max_upscale", &value);
+
+  return value;
+}
+
 bool Debug::IsVideoModeEnabled() {
   int value = 0;
   debug_.debug_handler_->GetProperty("sdm.video_mode_panel", &value);
@@ -140,6 +147,13 @@
   return (ubwc_framebuffer == 1);
 }
 
+bool Debug::IsAVRDisabled() {
+  int value = 0;
+  debug_.debug_handler_->GetProperty("sdm.debug.disable_avr", &value);
+
+  return (value == 1);
+}
+
 bool Debug::GetProperty(const char* property_name, char* value) {
   if (debug_.debug_handler_->GetProperty(property_name, value) != kErrorNone) {
     return false;