Merge "sdm: Add support for vsync enable/disable"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index d41181f..46ab782 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -39,6 +39,9 @@
 #include "xf86drmMode.h"
 
 namespace sde_drm {
+
+typedef std::map<std::pair<uint32_t, uint64_t>, float> CompRatioMap;
+
 /*
  * Drm Atomic Operation Codes
  */
@@ -141,6 +144,24 @@
    */
   CRTC_SET_OUTPUT_FENCE_OFFSET,
   /*
+   * Op: Sets overall SDE core clock
+   * Arg: uint32_t - CRTC ID
+   *      uint32_t - core_clk
+   */
+  CRTC_SET_CORE_CLK,
+   /*
+   * Op: Sets overall SDE core average bandwidth
+   * Arg: uint32_t - CRTC ID
+   *      uint32_t - core_ab
+   */
+  CRTC_SET_CORE_AB,
+   /*
+   * Op: Sets overall SDE core instantaneous bandwidth
+   * Arg: uint32_t - CRTC ID
+   *      uint32_t - core_ib
+   */
+  CRTC_SET_CORE_IB,
+  /*
    * Op: Returns release fence for this frame. Should be called after Commit() on
    * DRMAtomicReqInterface.
    * Arg: uint32_t - CRTC ID
@@ -154,6 +175,13 @@
    */
   CRTC_SET_POST_PROC,
   /*
+   * Op: Sets CRTC ROIs.
+   * Arg: uint32_t - CRTC ID
+   *      uint32_t - number of ROIs
+   *      DRMRect * - Array of CRTC ROIs
+   */
+  CRTC_SET_ROI,
+  /*
    * Op: Returns retire fence for this commit. Should be called after Commit() on
    * DRMAtomicReqInterface.
    * Arg: uint32_t - Connector ID
@@ -178,6 +206,13 @@
    *      uint32_t - Power Mode
    */
   CONNECTOR_SET_POWER_MODE,
+  /*
+   * Op: Sets panel ROIs.
+   * Arg: uint32_t - Connector ID
+   *      uint32_t - number of ROIs
+   *      DRMRect * - Array of Connector ROIs
+   */
+  CONNECTOR_SET_ROI,
 };
 
 enum struct DRMRotation {
@@ -239,6 +274,21 @@
   uint32_t max_blend_stages;
   QSEEDVersion qseed_version;
   SmartDMARevision smart_dma_rev;
+  float ib_fudge_factor;
+  float clk_fudge_factor;
+  uint32_t dest_scale_prefill_lines;
+  uint32_t undersized_prefill_lines;
+  uint32_t macrotile_prefill_lines;
+  uint32_t nv12_prefill_lines;
+  uint32_t linear_prefill_lines;
+  uint32_t downscale_prefill_lines;
+  uint32_t extra_prefill_lines;
+  uint32_t amortized_threshold;
+  uint64_t max_bandwidth_low;
+  uint64_t max_bandwidth_high;
+  uint32_t max_sde_clk;
+  CompRatioMap comp_ratio_rt_map;
+  CompRatioMap comp_ratio_nrt_map;
 };
 
 enum struct DRMPlaneType {
@@ -263,6 +313,7 @@
   uint32_t max_downscale;
   uint32_t max_horizontal_deci;
   uint32_t max_vertical_deci;
+  uint64_t max_pipe_bandwidth;
 };
 
 // All DRM Planes as map<Plane_id , plane_type_info> listed from highest to lowest priority
@@ -298,6 +349,15 @@
   std::vector<std::pair<uint32_t, uint64_t>> formats_supported;
   // Valid only if type is DRM_MODE_CONNECTOR_VIRTUAL
   uint32_t max_linewidth;
+  // Valid only if mode is command
+  int num_roi;
+  int xstart;
+  int ystart;
+  int walign;
+  int halign;
+  int wmin;
+  int hmin;
+  bool roi_merge;
 };
 
 /* Identifier token for a display */
@@ -414,7 +474,7 @@
    * Will query post propcessing feature info of a CRTC.
    * [output]: DRMPPFeatureInfo: CRTC post processing feature info
    */
-   virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
+  virtual void GetCrtcPPInfo(uint32_t crtc_id, DRMPPFeatureInfo &info) = 0;
   /*
    * Register a logical display to receive a token.
    * Each display pipeline in DRM is identified by its CRTC and Connector(s).
diff --git a/sdm/include/core/debug_interface.h b/sdm/include/core/debug_interface.h
index f4e3fc3..da21944 100644
--- a/sdm/include/core/debug_interface.h
+++ b/sdm/include/core/debug_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015 - 2017, 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
@@ -49,6 +49,7 @@
   kTagRotator,          //!< Debug log is tagged for rotator.
   kTagScalar,           //!< Debug log is tagged for Scalar Helper.
   kTagQDCM,             //!< Debug log is tagged for display QDCM color managing.
+  kTagQOSClient,        //!< Debug log is tagged for Qos client
 };
 
 /*! @brief Display debug handler class.
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index f12e5c1..b8977e2 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -85,8 +85,8 @@
   kCompositionSDE,          //!< This layer will be composed by SDE. It must not be composed by
                             //!< GPU or Blit.
 
-  kCompositionHWCursor,     //!< This layer will be composed by SDE using HW Cursor. It must not be
-                            //!< composed by GPU or Blit.
+  kCompositionCursor,       // This cursor layer can receive async position updates irrespective of
+                            // dedicated h/w cursor usage. It must not be composed by GPU or Blit
 
   kCompositionHybrid,       //!< This layer will be drawn by a blit engine and SDE together.
                             //!< Display device will split the layer, update the blit rectangle
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 68e953e..cdfec2e 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -111,11 +111,12 @@
 };
 
 typedef std::map<HWSubBlockType, std::vector<LayerBufferFormat>> FormatsMap;
+typedef std::map<LayerBufferFormat, float> CompRatioMap;
 
 struct HWDynBwLimitInfo {
   uint32_t cur_mode = kBwDefault;
-  uint32_t total_bw_limit[kBwModeMax] = { 0 };
-  uint32_t pipe_bw_limit[kBwModeMax] = { 0 };
+  uint64_t total_bw_limit[kBwModeMax] = { 0 };
+  uint64_t pipe_bw_limit[kBwModeMax] = { 0 };
 };
 
 struct HWPipeCaps {
@@ -142,6 +143,7 @@
   uint32_t max_input_width = 0;
   uint32_t max_output_width = 0;
   uint32_t max_scale_up = 1;
+  uint32_t prefill_lines = 4;
 };
 
 enum SmartDMARevision {
@@ -169,7 +171,7 @@
   uint32_t max_mixer_width = 2048;
   uint32_t max_pipe_width = 2048;
   uint32_t max_cursor_size = 0;
-  uint32_t max_pipe_bw =  0;
+  uint64_t max_pipe_bw =  0;
   uint32_t max_sde_clk = 0;
   float clk_fudge_factor = 1.0f;
   uint32_t macrotile_nv12_factor = 0;
@@ -185,7 +187,6 @@
   bool has_macrotile = false;
   bool has_non_scalar_rgb = false;
   bool is_src_split = false;
-  bool perf_calc = false;
   bool has_dyn_bw_support = false;
   bool separate_rotator = false;
   bool has_qseed3 = false;
@@ -200,6 +201,11 @@
   bool has_avr = false;
   bool has_hdr = false;
   SmartDMARevision smart_dma_rev = SmartDMARevision::V1;
+  float ib_fudge_factor = 1.0f;
+  uint32_t undersized_prefill_lines = 0;
+  CompRatioMap comp_ratio_rt_map;
+  CompRatioMap comp_ratio_nrt_map;
+
   void Reset() { *this = HWResourceInfo(); }
 };
 
@@ -432,6 +438,7 @@
 };
 
 struct HWPipeInfo {
+  HWPipeInfo *pair = NULL;
   uint8_t rect = 255;
   uint32_t pipe_id = 0;
   HWSubBlockType sub_block_type = kHWSubBlockMax;
@@ -485,10 +492,8 @@
   std::vector<LayerRect> left_frame_roi = {};   // Left ROI.
   std::vector<LayerRect> right_frame_roi = {};  // Right ROI.
   LayerRect partial_fb_roi = {};   // Damaged area in framebuffer.
-
   bool roi_split = false;          // Indicates separated left and right ROI
-
-  bool use_hw_cursor = false;      // Indicates that HWCursor pipe needs to be used for cursor layer
+  bool async_cursor_updates = false;  // Cursor layer allowed to have async updates
   DestScaleInfoMap dest_scale_info_map = {};
   HWHDRLayerInfo hdr_layer_info = {};
   Handle pvt_data = NULL;   // Private data used by sdm extension only.
@@ -498,8 +503,9 @@
   HWLayersInfo info;
   HWLayerConfig config[kMaxSDELayers];
   float output_compression = 1.0f;
-  uint32_t bandwidth = 0;
-  uint32_t clock = 0;
+  uint64_t ab_bps = 0;
+  uint64_t ib_bps = 0;
+  uint32_t clock_hz = 0;
   HWAVRInfo hw_avr_info = {};
 };
 
diff --git a/sdm/include/private/partial_update_interface.h b/sdm/include/private/partial_update_interface.h
index b753587..a1c2382 100644
--- a/sdm/include/private/partial_update_interface.h
+++ b/sdm/include/private/partial_update_interface.h
@@ -35,8 +35,6 @@
 
 struct PUConstraints {
   bool enable = true;             //!< If this is set, PU will be enabled or it will be disabled
-  bool enable_cursor_pu = false;  //!< If this is set, PU will consider cursor layer in the layer
-                                   //!< stack for cursor partial update
 };
 
 class PartialUpdateInterface {
diff --git a/sdm/include/private/resource_interface.h b/sdm/include/private/resource_interface.h
index e7df7a5..e140c33 100644
--- a/sdm/include/private/resource_interface.h
+++ b/sdm/include/private/resource_interface.h
@@ -58,8 +58,6 @@
   virtual DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst,
                                        bool rotate90, BufferLayout layout,
                                        bool use_rotator_downscale) = 0;
-  virtual DisplayError ValidateCursorConfig(Handle display_ctx, const Layer *layer,
-                                            bool is_top) = 0;
   virtual DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
                                               int x, int y) = 0;
   virtual DisplayError SetMaxBandwidthMode(HWBwModes mode) = 0;
diff --git a/sdm/include/private/strategy_interface.h b/sdm/include/private/strategy_interface.h
index f903d5f..1174e7f 100644
--- a/sdm/include/private/strategy_interface.h
+++ b/sdm/include/private/strategy_interface.h
@@ -36,9 +36,6 @@
                             //!< that requires minimum number of pipe for the current frame. i.e.,
                             //!< video only composition, secure only composition or GPU composition
 
-  bool use_cursor = false;  //!< If this is set, strategy manager will configure cursor layer in the
-                            //!< layer stack as hw cursor else it will be treated as a normal layer
-
   uint32_t max_layers = kMaxSDELayers;  //!< Maximum number of layers that shall be programmed
                                         //!< on hardware for the given layer stack.
 };
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 2b9fa92..d18b5b8 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -33,12 +33,6 @@
 
 namespace sdm {
 
-static bool NeedsScaledComposition(const DisplayConfigVariableInfo &fb_config,
-                                   const HWMixerAttributes &mixer_attributes) {
-  return ((fb_config.x_pixels != mixer_attributes.width) ||
-          (fb_config.y_pixels != mixer_attributes.height));
-}
-
 DisplayError CompManager::Init(const HWResourceInfo &hw_res_info,
                                ExtensionInterface *extension_intf,
                                BufferAllocator *buffer_allocator,
@@ -135,7 +129,6 @@
     max_sde_ext_layers_ = UINT32(Debug::GetExtMaxlayers());
   }
 
-  display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
   DLOGV_IF(kTagCompManager, "registered display bit mask 0x%x, configured display bit mask 0x%x, " \
            "display type %d", registered_displays_.to_ulong(), configured_displays_.to_ulong(),
            display_comp_ctx->display_type);
@@ -214,8 +207,6 @@
     }
   }
 
-  display_comp_ctx->scaled_composition = NeedsScaledComposition(fb_config, mixer_attributes);
-
   return error;
 }
 
@@ -225,7 +216,6 @@
   StrategyConstraints *constraints = &display_comp_ctx->constraints;
 
   constraints->safe_mode = safe_mode_;
-  constraints->use_cursor = false;
   constraints->max_layers = max_layers_;
 
   // Limit 2 layer SDE Comp if its not a Primary Display.
@@ -242,9 +232,6 @@
     constraints->safe_mode = true;
   }
 
-  // Set use_cursor constraint to Strategy
-  constraints->use_cursor = display_comp_ctx->valid_cursor;
-
   // TODO(user): App layer count will change for hybrid composition
   uint32_t app_layer_count = UINT32(hw_layers->info.stack->layers.size()) - 1;
   if (display_comp_ctx->idle_fallback || display_comp_ctx->thermal_fallback_) {
@@ -262,11 +249,6 @@
   SCOPE_LOCK(locker_);
   DisplayCompositionContext *display_comp_ctx =
                              reinterpret_cast<DisplayCompositionContext *>(display_ctx);
-  display_comp_ctx->valid_cursor = SupportLayerAsCursor(display_comp_ctx, hw_layers);
-
-  // pu constraints
-  display_comp_ctx->pu_constraints.enable_cursor_pu = display_comp_ctx->valid_cursor;
-
   display_comp_ctx->strategy->Start(&hw_layers->info, &display_comp_ctx->max_strategies,
                                     display_comp_ctx->pu_constraints);
   display_comp_ctx->remaining_strategies = display_comp_ctx->max_strategies;
@@ -486,39 +468,6 @@
   return resource_intf_->ValidateCursorPosition(display_resource_ctx, hw_layers, x, y);
 }
 
-bool CompManager::SupportLayerAsCursor(Handle comp_handle, HWLayers *hw_layers) {
-  DisplayCompositionContext *display_comp_ctx =
-                             reinterpret_cast<DisplayCompositionContext *>(comp_handle);
-  Handle &display_resource_ctx = display_comp_ctx->display_resource_ctx;
-  LayerStack *layer_stack = hw_layers->info.stack;
-  bool supported = false;
-  int32_t gpu_index = -1;
-
-  // HW Cursor cannot be used, if Display configuration needs scaled composition.
-  if (display_comp_ctx->scaled_composition || !layer_stack->flags.cursor_present) {
-    return supported;
-  }
-
-  for (int32_t i = INT32(layer_stack->layers.size() - 1); i >= 0; i--) {
-    Layer *layer = layer_stack->layers.at(UINT32(i));
-    if (layer->composition == kCompositionGPUTarget) {
-      gpu_index = i;
-      break;
-    }
-  }
-  if (gpu_index <= 0) {
-    return supported;
-  }
-  Layer *cursor_layer = layer_stack->layers.at(UINT32(gpu_index) - 1);
-  if (cursor_layer->flags.cursor && !cursor_layer->flags.skip &&
-      resource_intf_->ValidateCursorConfig(display_resource_ctx,
-                                           cursor_layer, true) == kErrorNone) {
-    supported = true;
-  }
-
-  return supported;
-}
-
 DisplayError CompManager::SetMaxBandwidthMode(HWBwModes mode) {
   if ((hw_res_info_.has_dyn_bw_support == false) || (mode >= kBwModeMax)) {
     return kErrorNotSupported;
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index c8646fe..c6b8972 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -67,7 +67,6 @@
   void ControlPartialUpdate(Handle display_ctx, bool enable);
   DisplayError ValidateScaling(const LayerRect &crop, const LayerRect &dst, bool rotate90);
   DisplayError ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers, int x, int y);
-  bool SupportLayerAsCursor(Handle display_ctx, HWLayers *hw_layers);
   bool SetDisplayState(Handle display_ctx, DisplayState state, DisplayType display_type);
   DisplayError SetMaxBandwidthMode(HWBwModes mode);
   DisplayError GetScaleLutConfig(HWScaleLutInfo *lut_info);
@@ -97,9 +96,7 @@
     // Using primary panel flag of hw panel to configure Constraints. We do not need other hw
     // panel parameters for now.
     bool is_primary_panel = false;
-    bool valid_cursor = false;
     PUConstraints pu_constraints = {};
-    bool scaled_composition = false;
   };
 
   Locker locker_;
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index da19398..618dd2e 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -664,7 +664,7 @@
   switch (composition) {
   case kCompositionGPU:         return "GPU";
   case kCompositionSDE:         return "SDE";
-  case kCompositionHWCursor:    return "CURSOR";
+  case kCompositionCursor:      return "CURSOR";
   case kCompositionHybrid:      return "HYBRID";
   case kCompositionBlit:        return "BLIT";
   case kCompositionGPUTarget:   return "GPU_TARGET";
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index e866cd0..6bc4434 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -429,24 +429,22 @@
         display_attributes_.x_pixels / 2;
   }
 
-  hw_panel_info_.partial_update = 0;
-  hw_panel_info_.left_align = 0;
-  hw_panel_info_.width_align = 0;
-  hw_panel_info_.top_align = 0;
-  hw_panel_info_.height_align = 0;
-  hw_panel_info_.min_roi_width = 0;
-  hw_panel_info_.min_roi_height = 0;
-  hw_panel_info_.needs_roi_merge = 0;
+  hw_panel_info_.partial_update = connector_info_.num_roi;
+  hw_panel_info_.left_roi_count = UINT32(connector_info_.num_roi);
+  hw_panel_info_.right_roi_count = UINT32(connector_info_.num_roi);
+  hw_panel_info_.left_align = connector_info_.xstart;
+  hw_panel_info_.top_align = connector_info_.ystart;
+  hw_panel_info_.width_align = connector_info_.walign;
+  hw_panel_info_.height_align = connector_info_.halign;
+  hw_panel_info_.min_roi_width = connector_info_.wmin;
+  hw_panel_info_.min_roi_height = connector_info_.hmin;
+  hw_panel_info_.needs_roi_merge = connector_info_.roi_merge;
   hw_panel_info_.dynamic_fps = connector_info_.dynamic_fps;
   hw_panel_info_.min_fps = 60;
   hw_panel_info_.max_fps = 60;
   hw_panel_info_.is_primary_panel = connector_info_.is_primary;
   hw_panel_info_.is_pluggable = 0;
 
-  if (!default_mode_) {
-    hw_panel_info_.needs_roi_merge = (connector_info_.topology == DRMTopology::DUAL_LM_MERGE);
-  }
-
   GetHWDisplayPortAndMode();
   GetHWPanelMaxBrightness();
 
@@ -562,14 +560,18 @@
 
 DisplayError HWDeviceDRM::PowerOn() {
   DTRACE_SCOPED();
+/*
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 1);
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::ON);
+*/
   return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::PowerOff() {
+/*
   drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POWER_MODE, token_.conn_id, DRMPowerMode::OFF);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ACTIVE, token_.crtc_id, 0);
+*/
   int ret = drm_atomic_intf_->Commit(false /* synchronous */);
   if (ret) {
     DLOGE("%s failed with error %d", __FUNCTION__, ret);
@@ -601,6 +603,34 @@
   HWLayersInfo &hw_layer_info = hw_layers->info;
   uint32_t hw_layer_count = UINT32(hw_layer_info.hw_layers.size());
 
+  // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
+  if (hw_panel_info_.partial_update) {
+    const int kNumMaxROIs = 4;
+    DRMRect crtc_rects[kNumMaxROIs] = {{0, 0, mixer_attributes_.width, mixer_attributes_.height}};
+    DRMRect conn_rects[kNumMaxROIs] = {{0, 0, display_attributes_.x_pixels,
+                                        display_attributes_.y_pixels}};
+
+    for (uint32_t i = 0; i < hw_layer_info.left_frame_roi.size(); i++) {
+      auto &roi = hw_layer_info.left_frame_roi.at(i);
+      // TODO(user): In multi PU, stitch ROIs vertically adjacent and upate plane destination
+      crtc_rects[i].left = UINT32(roi.left);
+      crtc_rects[i].right = UINT32(roi.right);
+      crtc_rects[i].top = UINT32(roi.top);
+      crtc_rects[i].bottom = UINT32(roi.bottom);
+      // TODO(user): In Dest scaler + PU, populate from HWDestScaleInfo->panel_roi
+      conn_rects[i].left = UINT32(roi.left);
+      conn_rects[i].right = UINT32(roi.right);
+      conn_rects[i].top = UINT32(roi.top);
+      conn_rects[i].bottom = UINT32(roi.bottom);
+    }
+
+    uint32_t num_rects = std::max(1u, static_cast<uint32_t>(hw_layer_info.left_frame_roi.size()));
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_ROI, token_.crtc_id,
+                              num_rects, crtc_rects);
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_ROI, token_.conn_id,
+                              num_rects, conn_rects);
+  }
+
   for (uint32_t i = 0; i < hw_layer_count; i++) {
     Layer &layer = hw_layer_info.hw_layers.at(i);
     LayerBuffer *input_buffer = &layer.input_buffer;
@@ -669,6 +699,13 @@
         }
       }
     }
+
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, hw_layers->clock_hz);
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, hw_layers->ab_bps);
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, hw_layers->ib_bps);
+
+    DLOGI_IF(kTagDriverConfig, "System: clock=%d Hz, ab=%llu Bps ib=%llu Bps", hw_layers->clock_hz,
+             hw_layers->ab_bps, hw_layers->ib_bps);
   }
 }
 
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index a2ba960..6258d73 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -135,7 +135,7 @@
 DisplayError HWInfoDRM::GetDynamicBWLimits(HWResourceInfo *hw_resource) {
   HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
   for (int index = 0; index < kBwModeMax; index++) {
-    bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low);
+    bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
     bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
   }
 
@@ -164,14 +164,13 @@
   hw_resource->linear_factor = 1;
   hw_resource->scale_factor = 1;
   hw_resource->extra_fudge_factor = 2;
-  hw_resource->amortizable_threshold = 0;
+  hw_resource->amortizable_threshold = 25;
   hw_resource->system_overhead_lines = 0;
   hw_resource->hw_dest_scalar_info.count = 0;
   hw_resource->hw_dest_scalar_info.max_scale_up = 0;
   hw_resource->hw_dest_scalar_info.max_input_width = 0;
   hw_resource->hw_dest_scalar_info.max_output_width = 0;
   hw_resource->is_src_split = true;
-  hw_resource->perf_calc = false;
   hw_resource->has_dyn_bw_support = false;
   hw_resource->has_qseed3 = false;
   hw_resource->has_concurrent_writeback = false;
@@ -254,6 +253,33 @@
   hw_resource->num_blending_stages = info.max_blend_stages;
   hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ?
     SmartDMARevision::V2 : SmartDMARevision::V1;
+  hw_resource->ib_fudge_factor = info.ib_fudge_factor;
+  hw_resource->hw_dest_scalar_info.prefill_lines = info.dest_scale_prefill_lines;
+  hw_resource->undersized_prefill_lines = info.undersized_prefill_lines;
+  hw_resource->macrotile_factor = info.macrotile_prefill_lines;
+  hw_resource->macrotile_nv12_factor = info.nv12_prefill_lines;
+  hw_resource->linear_factor = info.linear_prefill_lines;
+  hw_resource->scale_factor = info.downscale_prefill_lines;
+  hw_resource->extra_fudge_factor = info.extra_prefill_lines;
+  hw_resource->amortizable_threshold = info.amortized_threshold;
+  hw_resource->max_bandwidth_low = info.max_bandwidth_low / kKiloUnit;
+  hw_resource->max_bandwidth_high = info.max_bandwidth_high / kKiloUnit;
+  hw_resource->max_sde_clk = info.max_sde_clk;
+
+  std::vector<LayerBufferFormat> sdm_format;
+  for (auto &it : info.comp_ratio_rt_map) {
+    std::pair<uint32_t, uint64_t> drm_format = it.first;
+    GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
+    hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
+    sdm_format.clear();
+  }
+
+  for (auto &it : info.comp_ratio_nrt_map) {
+    std::pair<uint32_t, uint64_t> drm_format = it.first;
+    GetSDMFormat(drm_format.first, drm_format.second, &sdm_format);
+    hw_resource->comp_ratio_rt_map.insert(std::make_pair(sdm_format[0], it.second));
+    sdm_format.clear();
+  }
 }
 
 void HWInfoDRM::GetHWPlanesInfo(HWResourceInfo *hw_resource) {
@@ -305,6 +331,7 @@
   hw_resource->max_scale_down = info.max_downscale;
   hw_resource->max_scale_up = info.max_upscale;
   hw_resource->has_decimation = info.max_horizontal_deci > 1 && info.max_vertical_deci > 1;
+  hw_resource->max_pipe_bw = info.max_pipe_bandwidth / kKiloUnit;
 }
 
 void HWInfoDRM::PopulateSupportedFmts(HWSubBlockType sub_blk_type,
diff --git a/sdm/libs/core/drm/hw_info_drm.h b/sdm/libs/core/drm/hw_info_drm.h
index 91829cb..5d92c41 100644
--- a/sdm/libs/core/drm/hw_info_drm.h
+++ b/sdm/libs/core/drm/hw_info_drm.h
@@ -71,6 +71,8 @@
   // TODO(user): Read Mdss version from the driver
   static const int kHWMdssVersion5 = 500;  // MDSS_V5
   static const int kMaxStringLength = 1024;
+  static const int kKiloUnit = 1000;
+
   static HWResourceInfo *hw_resource_;
 };
 
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 95ac9b0..773845b 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -208,7 +208,6 @@
     HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
     bool is_rotator_used = (hw_rotator_session->hw_block_count != 0);
-    bool is_cursor_pipe_used = (hw_layer_info.use_hw_cursor & layer.flags.cursor);
 
     for (uint32_t count = 0; count < 2; count++) {
       HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
@@ -247,7 +246,7 @@
 #endif
         SetRect(pipe_info->src_roi, &mdp_layer.src_rect);
         SetRect(pipe_info->dst_roi, &mdp_layer.dst_rect);
-        SetMDPFlags(&layer, is_rotator_used, is_cursor_pipe_used, &mdp_layer.flags);
+        SetMDPFlags(&layer, is_rotator_used, hw_layer_info.async_cursor_updates, &mdp_layer.flags);
         SetCSC(layer.input_buffer.color_metadata, &mdp_layer.color_space);
         if (pipe_info->flags & kIGC) {
           SetIGC(&layer.input_buffer, mdp_layer_count);
@@ -710,7 +709,7 @@
 }
 
 void HWDevice::SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
-                           bool is_cursor_pipe_used, uint32_t *mdp_flags) {
+                           bool async_cursor_updates, uint32_t *mdp_flags) {
   const LayerBuffer &input_buffer = layer->input_buffer;
 
   // Flips will be taken care by rotator, if layer uses rotator for downscale/rotation. So ignore
@@ -743,7 +742,7 @@
     *mdp_flags |= MDP_LAYER_SOLID_FILL;
   }
 
-  if (hw_panel_info_.mode != kModeCommand && layer->flags.cursor && is_cursor_pipe_used) {
+  if (layer->flags.cursor && async_cursor_updates) {
     // command mode panels does not support async position update
     *mdp_flags |= MDP_LAYER_ASYNC;
   }
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 374df56..2eea87b 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -116,7 +116,7 @@
   void SetBlending(const LayerBlending &source, mdss_mdp_blend_op *target);
   void SetRect(const LayerRect &source, mdp_rect *target);
   void SetMDPFlags(const Layer *layer, const bool &is_rotator_used,
-                   bool is_cursor_pipe_used, uint32_t *mdp_flags);
+                   bool async_cursor_updates, uint32_t *mdp_flags);
   // Retrieves HW FrameBuffer Node Index
   int GetFBNodeIndex(HWDeviceType device_type);
   // Populates HWPanelInfo based on node index
diff --git a/sdm/libs/core/fb/hw_info.cpp b/sdm/libs/core/fb/hw_info.cpp
index d898cd2..f2a13e3 100644
--- a/sdm/libs/core/fb/hw_info.cpp
+++ b/sdm/libs/core/fb/hw_info.cpp
@@ -95,7 +95,7 @@
 
   HWDynBwLimitInfo* bw_info = &hw_resource->dyn_bw_info;
   for (int index = 0; index < kBwModeMax; index++) {
-    bw_info->total_bw_limit[index] = UINT32(hw_resource->max_bandwidth_low);
+    bw_info->total_bw_limit[index] = hw_resource->max_bandwidth_low;
     bw_info->pipe_bw_limit[index] = hw_resource->max_pipe_bw;
   }
 
@@ -169,9 +169,9 @@
       } else if (!strncmp(tokens[0], "max_upscale_ratio", strlen("max_upscale_ratio"))) {
         hw_resource_->max_scale_up = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "max_bandwidth_low", strlen("max_bandwidth_low"))) {
-        hw_resource_->max_bandwidth_low = UINT64(atol(tokens[1]));
+        hw_resource_->max_bandwidth_low = std::stoull(tokens[1]);
       } else if (!strncmp(tokens[0], "max_bandwidth_high", strlen("max_bandwidth_high"))) {
-        hw_resource_->max_bandwidth_high = UINT64(atol(tokens[1]));
+        hw_resource_->max_bandwidth_high = std::stoull(tokens[1]);
       } else if (!strncmp(tokens[0], "max_mixer_width", strlen("max_mixer_width"))) {
         hw_resource_->max_mixer_width = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "max_pipe_width", strlen("max_pipe_width"))) {
@@ -179,7 +179,7 @@
       } else if (!strncmp(tokens[0], "max_cursor_size", strlen("max_cursor_size"))) {
         hw_resource_->max_cursor_size = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "max_pipe_bw", strlen("max_pipe_bw"))) {
-        hw_resource_->max_pipe_bw = UINT32(atoi(tokens[1]));
+        hw_resource_->max_pipe_bw = std::stoull(tokens[1]);
       } else if (!strncmp(tokens[0], "max_mdp_clk", strlen("max_mdp_clk"))) {
         hw_resource_->max_sde_clk = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "clk_fudge_factor", strlen("clk_fudge_factor"))) {
@@ -224,8 +224,6 @@
             hw_resource_->is_src_split = true;
           } else if (!strncmp(tokens[i], "non_scalar_rgb", strlen("non_scalar_rgb"))) {
             hw_resource_->has_non_scalar_rgb = true;
-          } else if (!strncmp(tokens[i], "perf_calc", strlen("perf_calc"))) {
-            hw_resource_->perf_calc = true;
           } else if (!strncmp(tokens[i], "dynamic_bw_limit", strlen("dynamic_bw_limit"))) {
             hw_resource_->has_dyn_bw_support = true;
           } else if (!strncmp(tokens[i], "separate_rotator", strlen("separate_rotator"))) {
diff --git a/sdm/libs/core/resource_default.cpp b/sdm/libs/core/resource_default.cpp
index 31d8704..2d74941 100644
--- a/sdm/libs/core/resource_default.cpp
+++ b/sdm/libs/core/resource_default.cpp
@@ -923,11 +923,6 @@
   return kErrorNone;
 }
 
-DisplayError ResourceDefault::ValidateCursorConfig(Handle display_ctx, const Layer *layer,
-                                                   bool is_top) {
-  return kErrorNotSupported;
-}
-
 DisplayError ResourceDefault::ValidateCursorPosition(Handle display_ctx, HWLayers *hw_layers,
                                                      int x, int y) {
   return kErrorNotSupported;
diff --git a/sdm/libs/hwc/hwc_display.cpp b/sdm/libs/hwc/hwc_display.cpp
index 6cba7f0..07ec2ce 100644
--- a/sdm/libs/hwc/hwc_display.cpp
+++ b/sdm/libs/hwc/hwc_display.cpp
@@ -953,7 +953,7 @@
   case kCompositionGPUTarget:   *target = HWC_FRAMEBUFFER_TARGET; break;
   case kCompositionGPU:         *target = HWC_FRAMEBUFFER;        break;
   case kCompositionGPUS3D:      *target = HWC_FRAMEBUFFER;        break;
-  case kCompositionHWCursor:    *target = HWC_CURSOR_OVERLAY;     break;
+  case kCompositionCursor:      *target = HWC_CURSOR_OVERLAY;     break;
   default:                      *target = HWC_OVERLAY;            break;
   }
 }
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 7756020..9446b6c 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -52,12 +52,23 @@
 
 namespace sdm {
 
-static void ApplyDeInterlaceAdjustment(Layer *layer) {
+static void ApplyDeInterlaceAdjustment(HWCLayer *hwc_layer, Layer *sdm_layer) {
   // De-interlacing adjustment
-  if (layer->input_buffer.flags.interlace) {
-    float height = (layer->src_rect.bottom - layer->src_rect.top) / 2.0f;
-    layer->src_rect.top = ROUND_UP_ALIGN_DOWN(layer->src_rect.top / 2.0f, 2);
-    layer->src_rect.bottom = layer->src_rect.top + floorf(height);
+  if (sdm_layer->input_buffer.flags.interlace) {
+    // Adjust src_rect only if new source crop was set
+    if (hwc_layer->GetGeometryChanges() & kSourceCrop) {
+      float height = (sdm_layer->src_rect.bottom - sdm_layer->src_rect.top) / 2.0f;
+      sdm_layer->src_rect.top = ROUND_UP_ALIGN_DOWN(sdm_layer->src_rect.top / 2.0f, 2);
+      sdm_layer->src_rect.bottom = sdm_layer->src_rect.top + floorf(height);
+    }
+
+    // Handle deinterlacing for UBWC Interlaced format.
+    if (IsUBWCFormat(sdm_layer->input_buffer.format)) {
+      sdm_layer->input_buffer.height /= 2;
+      sdm_layer->input_buffer.unaligned_height /= 2;
+      // After adjustments layer needs to be treated as UBWC progressive. Reset interlace flag.
+      sdm_layer->input_buffer.flags.interlace = 0;
+    }
   }
 }
 
@@ -156,10 +167,11 @@
   bool use_matrix = false;
   if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
     // if the mode + transfrom request from HWC matches one mode in SDM, set that
-    color_mode_transform = color_mode_transform_map_[mode][hint];
     if (color_mode_transform.empty()) {
       transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
       use_matrix = true;
+    } else {
+      color_mode_transform = color_mode_transform_map_[mode][hint];
     }
   } else {
     use_matrix = true;
@@ -503,7 +515,7 @@
                                        INT(layer->dst_rect.right), INT(layer->dst_rect.bottom)};
     ApplyScanAdjustment(&scaled_display_frame);
     hwc_layer->SetLayerDisplayFrame(scaled_display_frame);
-    ApplyDeInterlaceAdjustment(layer);
+    ApplyDeInterlaceAdjustment(hwc_layer, layer);
     // SDM requires these details even for solid fill
     if (layer->flags.solid_fill) {
       LayerBuffer *layer_buffer = &layer->input_buffer;
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 276bee8..c428ba2 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -83,7 +83,10 @@
   android_color_transform_t current_color_transform_ = HAL_COLOR_TRANSFORM_IDENTITY;
   typedef std::map<android_color_transform_t, std::string> TransformMap;
   std::map<android_color_mode_t, TransformMap> color_mode_transform_map_ = {};
-  double color_matrix_[kColorTransformMatrixCount] = {0};
+  double color_matrix_[kColorTransformMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
+                                                       0.0, 1.0, 0.0, 0.0, \
+                                                       0.0, 0.0, 1.0, 0.0, \
+                                                       0.0, 0.0, 0.0, 1.0 };
 };
 
 class HWCDisplay : public DisplayEventHandler {
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index f3404a3..d78207b 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, 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
@@ -112,8 +112,9 @@
     return status;
   }
   color_mode_ = new HWCColorMode(display_intf_);
+  color_mode_->Init();
 
-  return INT(color_mode_->Init());
+  return status;
 }
 
 void HWCDisplayPrimary::ProcessBootAnimCompleted() {
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index da8a1d8..51a8687 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -690,7 +690,7 @@
     case kCompositionGPU:
       hwc_composition = HWC2::Composition::Client;
       break;
-    case kCompositionHWCursor:
+    case kCompositionCursor:
       hwc_composition = HWC2::Composition::Cursor;
       break;
     default: