sdm: drm: Add support for global dither feature

This change adds support for global dither v1 feature.

Change-Id: I8911e2c422e7a6b7c07276cda8fca0c3c8b5ce81
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 97660ea..b7bfb4c 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -311,6 +311,12 @@
    */
   CONNECTOR_SET_CRTC,
   /*
+   * Op: Sets PP feature
+   * Arg: uint32_t - Connector ID
+   * DRMPPFeatureInfo * - PP feature data pointer
+   */
+   CONNECTOR_SET_POST_PROC,
+  /*
    * Op: Sets connector hdr metadata
    * Arg: uint32_t - Connector ID
    *      drm_msm_ext_hdr_metadata - hdr_metadata
@@ -531,6 +537,7 @@
   uint32_t version;
   uint32_t payload_size;
   void *payload;
+  uint32_t object_type;
 };
 
 enum DRMCscType {
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
index 7563647..295dafd 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.cpp
+++ b/sdm/libs/core/drm/hw_color_manager_drm.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -797,14 +797,43 @@
                                              DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
 #ifdef PP_DRM_ENABLE
+  struct SDEDitherCfg *sde_dither = NULL;
+  struct drm_msm_dither *mdp_dither = NULL;
+
   if (!out_data) {
     DLOGE("Invalid input parameter for dither");
     return kErrorParameters;
   }
 
-  out_data->id = kPPFeaturesMax;
+  sde_dither = (struct SDEDitherCfg *)in_data.GetConfigData();
+  out_data->id = kFeatureDither;
   out_data->type = sde_drm::kPropBlob;
   out_data->version = in_data.feature_version_;
+  out_data->payload_size = sizeof(struct drm_msm_dither);
+
+  if (in_data.enable_flags_ & kOpsDisable) {
+    out_data->payload = NULL;
+    return ret;
+  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
+    out_data->payload = NULL;
+    return kErrorParameters;
+  }
+
+  mdp_dither = new drm_msm_dither();
+  if (!mdp_dither) {
+    DLOGE("Failed to allocate memory for dither");
+    return kErrorMemory;
+  }
+
+  mdp_dither->flags = 0;
+  std::memcpy(mdp_dither->matrix, sde_dither->dither_matrix,
+                sizeof(sde_dither->dither_matrix));
+  mdp_dither->temporal_en = sde_dither->temporal_en;
+  mdp_dither->c0_bitdepth = sde_dither->g_y_depth;
+  mdp_dither->c1_bitdepth = sde_dither->b_cb_depth;
+  mdp_dither->c2_bitdepth = sde_dither->r_cr_depth;
+  mdp_dither->c3_bitdepth = 0;
+  out_data->payload = mdp_dither;
 #endif
   return ret;
 }
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index c734f4c..1c8265b 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -57,6 +57,7 @@
 #include <unordered_map>
 #include <utility>
 #include <vector>
+#include <limits>
 
 #include "hw_device_drm.h"
 #include "hw_info_interface.h"
@@ -1258,13 +1259,18 @@
 DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
   int ret = 0;
   PPFeatureInfo *feature = NULL;
+  DRMPPFeatureInfo kernel_params = {};
+  bool crtc_feature = true;
 
   while (true) {
-    DRMPPFeatureInfo kernel_params = {};
+    crtc_feature = true;
     ret = feature_list->RetrieveNextFeature(&feature);
     if (ret)
       break;
-
+    kernel_params.id = HWColorManagerDrm::ToDrmFeatureId(feature->feature_id_);
+    drm_mgr_intf_->GetCrtcPPInfo(0, &kernel_params);
+    if (kernel_params.version == std::numeric_limits<uint32_t>::max())
+        crtc_feature = false;
     if (feature) {
       DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
       auto drm_features = DrmPPfeatureMap_.find(feature->feature_id_);
@@ -1279,9 +1285,11 @@
           continue;
         }
         ret = HWColorManagerDrm::GetDrmFeature[drm_feature](*feature, &kernel_params);
-        if (!ret)
-          drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
-        HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
+      if (!ret && crtc_feature)
+        drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
+      else if (!ret && !crtc_feature)
+        drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_POST_PROC, token_.conn_id, &kernel_params);
+      HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
       }
     }
   }