sdm: drm: Add post-processing support in SDM

SDM added support for the DRM driver recently. This change
adds the similar support in the SDM to enable/disable
post-processing features via DRM driver for QDCM.

CRs-Fixed: 2007376
Change-Id: I39d8d2c76a28aac0675c559dceb6dcf74eb170fb
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 94a48e1..399972b 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -136,6 +136,12 @@
    */
   CRTC_GET_RELEASE_FENCE,
   /*
+   * Op: Sets PP feature
+   * Arg: uint32_t - CRTC ID
+   *      DRMPPFeatureInfo * - PP feature data pointer
+   */
+  CRTC_SET_POST_PROC,
+  /*
    * Op: Returns retire fence for this commit. Should be called after Commit() on
    * DRMAtomicReqInterface.
    * Arg: uint32_t - Connector ID
@@ -262,6 +268,33 @@
   uint32_t crtc_id;
 };
 
+enum DRMPPFeatureID {
+  kFeaturePcc,
+  kFeatureIgc,
+  kFeaturePgc,
+  kFeatureMixerGc,
+  kFeaturePaV2,
+  kFeatureDither,
+  kFeatureGamut,
+  kFeaturePADither,
+  kPPFeaturesMax,
+};
+
+enum DRMPPPropType {
+  kPropEnum,
+  kPropRange,
+  kPropBlob,
+  kPropTypeMax,
+};
+
+struct DRMPPFeatureInfo {
+  DRMPPFeatureID id;
+  DRMPPPropType type;
+  uint32_t version;
+  uint32_t payload_size;
+  void *payload;
+};
+
 /* DRM Atomic Request Property Set.
  *
  * Helper class to create and populate atomic properties of DRM components
@@ -331,6 +364,11 @@
   virtual void GetConnectorInfo(uint32_t conn_id, DRMConnectorInfo *info) = 0;
 
   /*
+   * 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;
+  /*
    * Register a logical display to receive a token.
    * Each display pipeline in DRM is identified by its CRTC and Connector(s).
    * On display connect(bootup or hotplug), clients should invoke this interface to
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index cdf8925..114fcaf 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -19,6 +19,10 @@
     LOCAL_HW_INTF_PATH_2      := drm
 endif
 
+ifeq ($(TARGET_USES_DRM_PP),true)
+    LOCAL_CFLAGS              += -DPP_DRM_ENABLE
+endif
+
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
 LOCAL_SRC_FILES               := core_interface.cpp \
                                  core_impl.cpp \
@@ -46,7 +50,8 @@
 ifneq ($(TARGET_IS_HEADLESS), true)
     LOCAL_SRC_FILES           += $(LOCAL_HW_INTF_PATH_2)/hw_info_drm.cpp \
                                  $(LOCAL_HW_INTF_PATH_2)/hw_device_drm.cpp \
-                                 $(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp
+                                 $(LOCAL_HW_INTF_PATH_2)/hw_events_drm.cpp \
+                                 $(LOCAL_HW_INTF_PATH_2)/hw_color_manager_drm.cpp
 endif
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
new file mode 100644
index 0000000..88e68aa
--- /dev/null
+++ b/sdm/libs/core/drm/hw_color_manager_drm.cpp
@@ -0,0 +1,173 @@
+/*
+* Copyright (c) 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
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define __CLASS__ "HWColorManagerDRM"
+
+#ifdef PP_DRM_ENABLE
+#include <drm/msm_drm_pp.h>
+#endif
+#include "hw_color_manager_drm.h"
+
+using sde_drm::kFeaturePcc;
+using sde_drm::kFeatureIgc;
+using sde_drm::kFeaturePgc;
+using sde_drm::kFeatureMixerGc;
+using sde_drm::kFeaturePaV2;
+using sde_drm::kFeatureDither;
+using sde_drm::kFeatureGamut;
+using sde_drm::kFeaturePADither;
+using sde_drm::kPPFeaturesMax;
+
+namespace sdm {
+
+DisplayError (*HWColorManagerDrm::GetDrmFeature[])(const PPFeatureInfo &, DRMPPFeatureInfo *) = {
+        [kGlobalColorFeaturePcc] = &HWColorManagerDrm::GetDrmPCC,
+        [kGlobalColorFeatureIgc] = &HWColorManagerDrm::GetDrmIGC,
+        [kGlobalColorFeaturePgc] = &HWColorManagerDrm::GetDrmPGC,
+        [kMixerColorFeatureGc] = &HWColorManagerDrm::GetDrmMixerGC,
+        [kGlobalColorFeaturePaV2] = &HWColorManagerDrm::GetDrmPAV2,
+        [kGlobalColorFeatureDither] = &HWColorManagerDrm::GetDrmDither,
+        [kGlobalColorFeatureGamut] = &HWColorManagerDrm::GetDrmGamut,
+        [kGlobalColorFeaturePADither] = &HWColorManagerDrm::GetDrmPADither,
+};
+
+void HWColorManagerDrm::FreeDrmFeatureData(DRMPPFeatureInfo *feature) {
+  if (feature->payload)
+    free(feature->payload);
+}
+
+uint32_t HWColorManagerDrm::GetFeatureVersion(DRMPPFeatureInfo &feature) {
+  uint32_t version = PPFeatureVersion::kSDEPpVersionInvalid;
+
+  switch (feature.id) {
+    case kFeaturePcc:
+      break;
+    case kFeatureIgc:
+      break;
+    case kFeaturePgc:
+      break;
+    case kFeatureMixerGc:
+      break;
+    case kFeaturePaV2:
+      break;
+    case kFeatureDither:
+      break;
+    case kFeatureGamut:
+      break;
+    case kFeaturePADither:
+      break;
+    default:
+      break;
+  }
+  return version;
+}
+
+DRMPPFeatureID HWColorManagerDrm::ToDrmFeatureId(uint32_t id) {
+  DRMPPFeatureID ret = kPPFeaturesMax;
+
+  switch (id) {
+    case kGlobalColorFeaturePcc:
+      ret = kFeaturePcc;
+      break;
+    case kGlobalColorFeatureIgc:
+      ret = kFeatureIgc;
+      break;
+    case kGlobalColorFeaturePgc:
+      ret = kFeaturePgc;
+      break;
+    case kMixerColorFeatureGc:
+      ret = kFeatureMixerGc;
+      break;
+    case kGlobalColorFeaturePaV2:
+      ret = kFeaturePaV2;
+      break;
+    case kGlobalColorFeatureDither:
+      ret = kFeatureDither;
+      break;
+    case kGlobalColorFeatureGamut:
+      ret = kFeatureGamut;
+      break;
+    case kGlobalColorFeaturePADither:
+      ret = kFeaturePADither;
+      break;
+    default:
+      break;
+  }
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmPCC(const PPFeatureInfo &in_data,
+                                          DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmIGC(const PPFeatureInfo &in_data,
+                                          DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmPGC(const PPFeatureInfo &in_data,
+                                          DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmMixerGC(const PPFeatureInfo &in_data,
+                                              DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmPAV2(const PPFeatureInfo &in_data,
+                                           DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmDither(const PPFeatureInfo &in_data,
+                                             DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmGamut(const PPFeatureInfo &in_data,
+                                            DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+DisplayError HWColorManagerDrm::GetDrmPADither(const PPFeatureInfo &in_data,
+                                               DRMPPFeatureInfo *out_data) {
+  DisplayError ret = kErrorNone;
+  return ret;
+}
+
+}  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.h b/sdm/libs/core/drm/hw_color_manager_drm.h
new file mode 100644
index 0000000..23b1dde
--- /dev/null
+++ b/sdm/libs/core/drm/hw_color_manager_drm.h
@@ -0,0 +1,64 @@
+/*
+* Copyright (c) 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
+* met:
+*     * Redistributions of source code must retain the above copyright
+*       notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+*       copyright notice, this list of conditions and the following
+*       disclaimer in the documentation and/or other materials provided
+*       with the distribution.
+*     * Neither the name of The Linux Foundation nor the names of its
+*       contributors may be used to endorse or promote products derived
+*       from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __HW_COLOR_MANAGER_DRM_H__
+#define __HW_COLOR_MANAGER_DRM_H__
+
+#include <drm_interface.h>
+#include <private/color_params.h>
+
+using sde_drm::DRMPPFeatureID;
+using sde_drm::DRMPPFeatureInfo;
+
+namespace sdm {
+
+class HWColorManagerDrm {
+ public:
+  static DisplayError (*GetDrmFeature[kMaxNumPPFeatures])(const PPFeatureInfo &in_data,
+                                                          DRMPPFeatureInfo *out_data);
+  static void FreeDrmFeatureData(DRMPPFeatureInfo *feature);
+  static uint32_t GetFeatureVersion(DRMPPFeatureInfo &feature);
+  static DRMPPFeatureID ToDrmFeatureId(uint32_t id);
+ protected:
+  HWColorManagerDrm() {}
+
+ private:
+  static DisplayError GetDrmPCC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmIGC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmPGC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmMixerGC(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmPAV2(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmDither(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmGamut(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmPADither(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+};
+
+}  // namespace sdm
+
+#endif  // __HW_COLOR_MANAGER_DRM_H__
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index a72aae7..b5d281b 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -46,6 +46,7 @@
 #include <utils/constants.h>
 #include <utils/debug.h>
 #include <utils/sys.h>
+#include <private/color_params.h>
 
 #include <algorithm>
 #include <string>
@@ -54,6 +55,7 @@
 
 #include "hw_device_drm.h"
 #include "hw_info_interface.h"
+#include "hw_color_manager_drm.h"
 
 #define __CLASS__ "HWDeviceDRM"
 
@@ -68,6 +70,7 @@
 using sde_drm::DRMDisplayType;
 using sde_drm::DRMDisplayToken;
 using sde_drm::DRMConnectorInfo;
+using sde_drm::DRMPPFeatureInfo;
 using sde_drm::DRMRect;
 using sde_drm::DRMBlendType;
 using sde_drm::DRMOps;
@@ -566,11 +569,47 @@
 }
 
 DisplayError HWDeviceDRM::GetPPFeaturesVersion(PPFeatureVersion *vers) {
-  return kErrorNotSupported;
+  struct DRMPPFeatureInfo info = {};
+
+  for (uint32_t i = 0; i < kMaxNumPPFeatures; i++) {
+    memset(&info, 0, sizeof(struct DRMPPFeatureInfo));
+    info.id = HWColorManagerDrm::ToDrmFeatureId(i);
+    if (info.id >= sde_drm::kPPFeaturesMax)
+      continue;
+    // use crtc_id_ = 0 since PP features are same across all CRTCs
+    drm_mgr_intf_->GetCrtcPPInfo(0, info);
+    vers->version[i] = HWColorManagerDrm::GetFeatureVersion(info);
+  }
+  return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::SetPPFeatures(PPFeaturesConfig *feature_list) {
-  return kErrorNotSupported;
+  int ret = 0;
+  PPFeatureInfo *feature = NULL;
+  DRMPPFeatureInfo kernel_params = {};
+
+  while (true) {
+    ret = feature_list->RetrieveNextFeature(&feature);
+    if (ret)
+      break;
+
+    if (feature) {
+      DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_);
+      if (!HWColorManagerDrm::GetDrmFeature[feature->feature_id_]) {
+        DLOGE("GetDrmFeature is not valid for feature %d", feature->feature_id_);
+        continue;
+      }
+      ret = HWColorManagerDrm::GetDrmFeature[feature->feature_id_](*feature, &kernel_params);
+      if (!ret)
+        drm_atomic_intf_->Perform(DRMOps::CRTC_SET_POST_PROC, token_.crtc_id, &kernel_params);
+      HWColorManagerDrm::FreeDrmFeatureData(&kernel_params);
+    }
+  }
+
+  // Once all features were consumed, then destroy all feature instance from feature_list,
+  feature_list->Reset();
+
+  return kErrorNone;
 }
 
 DisplayError HWDeviceDRM::SetVSyncState(bool enable) {