sdm: drm: Add pa hsic feature support

Add dspp pa hsic feature support to hw_color_mgr for drm.

Change-Id: I4525ddd80f82ee73bed57dac04cccd353281df46
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 1d9d85a..1052c9d 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -462,6 +462,9 @@
   kFeatureDither,
   kFeatureGamut,
   kFeaturePADither,
+  kFeaturePAHsic,
+  kFeaturePASixZone,
+  kFeaturePAMemColor,
   kPPFeaturesMax,
 };
 
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.cpp b/sdm/libs/core/drm/hw_color_manager_drm.cpp
index 2000f9a..b40a3b0 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.cpp
+++ b/sdm/libs/core/drm/hw_color_manager_drm.cpp
@@ -35,35 +35,35 @@
 #include <utils/debug.h>
 #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;
-
 #ifdef PP_DRM_ENABLE
 static const uint32_t kPgcDataMask = 0x3FF;
 static const uint32_t kPgcShift = 16;
 
 static const uint32_t kIgcDataMask = 0xFFF;
 static const uint32_t kIgcShift = 16;
+
+#ifdef DRM_MSM_PA_HSIC
+static const uint32_t kPAHueMask = (1 << 12);
+static const uint32_t kPASatMask = (1 << 13);
+static const uint32_t kPAValMask = (1 << 14);
+static const uint32_t kPAContrastMask = (1 << 15);
+#endif
 #endif
 
 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,
+        [kFeaturePcc] = &HWColorManagerDrm::GetDrmPCC,
+        [kFeatureIgc] = &HWColorManagerDrm::GetDrmIGC,
+        [kFeaturePgc] = &HWColorManagerDrm::GetDrmPGC,
+        [kFeatureMixerGc] = &HWColorManagerDrm::GetDrmMixerGC,
+        [kFeaturePaV2] = NULL,
+        [kFeatureDither] = &HWColorManagerDrm::GetDrmDither,
+        [kFeatureGamut] = &HWColorManagerDrm::GetDrmGamut,
+        [kFeaturePADither] = &HWColorManagerDrm::GetDrmPADither,
+        [kFeaturePAHsic] = &HWColorManagerDrm::GetDrmPAHsic,
+        [kFeaturePASixZone] = &HWColorManagerDrm::GetDrmPASixZone,
+        [kFeaturePAMemColor] = &HWColorManagerDrm::GetDrmPAMemColor,
 };
 
 void HWColorManagerDrm::FreeDrmFeatureData(DRMPPFeatureInfo *feature) {
@@ -94,7 +94,10 @@
     case kFeatureMixerGc:
         version = PPFeatureVersion::kSDEPgcV17;
       break;
-    case kFeaturePaV2:
+    case kFeaturePAHsic:
+    case kFeaturePASixZone:
+    case kFeaturePAMemColor:
+      if (feature.version == 1)
         version = PPFeatureVersion::kSDEPaV17;
       break;
     case kFeatureDither:
@@ -132,7 +135,7 @@
       ret = kFeatureMixerGc;
       break;
     case kGlobalColorFeaturePaV2:
-      ret = kFeaturePaV2;
+      ret = kFeaturePAHsic;
       break;
     case kGlobalColorFeatureDither:
       ret = kFeatureDither;
@@ -366,23 +369,87 @@
   return ret;
 }
 
-DisplayError HWColorManagerDrm::GetDrmPAV2(const PPFeatureInfo &in_data,
+DisplayError HWColorManagerDrm::GetDrmPAHsic(const PPFeatureInfo &in_data,
                                            DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
-#ifdef PP_DRM_ENABLE
+#if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_HSIC)
+  struct SDEPaData *sde_pa;
+  struct drm_msm_pa_hsic *mdp_hsic;
+
   if (!out_data) {
-    DLOGE("Invalid input parameter for PA V2");
+    DLOGE("Invalid input parameter for pa hsic");
     return kErrorParameters;
   }
 
-  out_data->id = kPPFeaturesMax;
+  sde_pa = (struct SDEPaData *) in_data.GetConfigData();
+
+  out_data->id = kFeaturePAHsic;
   out_data->type = sde_drm::kPropBlob;
   out_data->version = in_data.feature_version_;
+  out_data->payload_size = 0;
+  out_data->payload = NULL;
 
+  if (in_data.enable_flags_ & kOpsDisable) {
+    /* Complete PA features disable case */
+    return ret;
+  } else if (!(in_data.enable_flags_ & kOpsEnable)) {
+    DLOGE("Invalid ops for pa hsic");
+    return kErrorParameters;
+  }
+
+  if (!(sde_pa->mode & (kPAHueMask | kPASatMask |
+                        kPAValMask | kPAContrastMask))) {
+    /* PA HSIC feature disable case, but other PA features active */
+    return ret;
+  }
+
+  mdp_hsic = new drm_msm_pa_hsic();
+  if (!mdp_hsic) {
+    DLOGE("Failed to allocate memory for pa hsic");
+    return kErrorMemory;
+  }
+
+  mdp_hsic->flags = 0;
+
+  if (in_data.enable_flags_ & kPaHueEnable) {
+    mdp_hsic->flags |= PA_HSIC_HUE_ENABLE;
+    mdp_hsic->hue = sde_pa->hue_adj;
+  }
+  if (in_data.enable_flags_ & kPaSatEnable) {
+    mdp_hsic->flags |= PA_HSIC_SAT_ENABLE;
+    mdp_hsic->saturation = sde_pa->sat_adj;
+  }
+  if (in_data.enable_flags_ & kPaValEnable) {
+    mdp_hsic->flags |= PA_HSIC_VAL_ENABLE;
+    mdp_hsic->value = sde_pa->val_adj;
+  }
+  if (in_data.enable_flags_ & kPaContEnable) {
+    mdp_hsic->flags |= PA_HSIC_CONT_ENABLE;
+    mdp_hsic->contrast = sde_pa->cont_adj;
+  }
+
+  if (mdp_hsic->flags) {
+    out_data->payload = mdp_hsic;
+    out_data->payload_size = sizeof(struct drm_msm_pa_hsic);
+  } else {
+    /* PA HSIC configuration unchanged, no better return code available */
+    delete mdp_hsic;
+    ret = kErrorPermission;
+  }
 #endif
   return ret;
 }
 
+DisplayError HWColorManagerDrm::GetDrmPASixZone(const PPFeatureInfo &in_data,
+                                                DRMPPFeatureInfo *out_data) {
+  return kErrorNotSupported;
+}
+
+DisplayError HWColorManagerDrm::GetDrmPAMemColor(const PPFeatureInfo &in_data,
+                                                 DRMPPFeatureInfo *out_data) {
+  return kErrorNotSupported;
+}
+
 DisplayError HWColorManagerDrm::GetDrmDither(const PPFeatureInfo &in_data,
                                              DRMPPFeatureInfo *out_data) {
   DisplayError ret = kErrorNone;
diff --git a/sdm/libs/core/drm/hw_color_manager_drm.h b/sdm/libs/core/drm/hw_color_manager_drm.h
index 290c606..963be1a 100644
--- a/sdm/libs/core/drm/hw_color_manager_drm.h
+++ b/sdm/libs/core/drm/hw_color_manager_drm.h
@@ -32,17 +32,45 @@
 
 #include <drm_interface.h>
 #include <private/color_params.h>
+#include <vector>
+#include <map>
 
 using sde_drm::DRMPPFeatureID;
 using sde_drm::DRMPPFeatureInfo;
 
+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::kFeaturePAHsic;
+using sde_drm::kFeaturePASixZone;
+using sde_drm::kFeaturePAMemColor;
+using sde_drm::kPPFeaturesMax;
+
 namespace sdm {
 
+typedef std::map<uint32_t, std::vector<uint32_t>> DrmPPFeatureMap;
+
+static const DrmPPFeatureMap DrmPPfeatureMap_ = \
+  {{kGlobalColorFeaturePcc, {kFeaturePcc}},
+    {kGlobalColorFeatureIgc, {kFeatureIgc}},
+    {kGlobalColorFeaturePgc, {kFeaturePgc}},
+    {kMixerColorFeatureGc, {kMixerColorFeatureGc}},
+    {kGlobalColorFeaturePaV2, {kFeaturePAHsic, kFeaturePASixZone, kFeaturePAMemColor}},
+    {kGlobalColorFeatureDither, {kFeatureDither}},
+    {kGlobalColorFeatureGamut, {kFeatureGamut}},
+    {kGlobalColorFeaturePADither, {kFeaturePADither}},
+};
+
 static const uint32_t kMaxPCCChanel = 3;
 
 class HWColorManagerDrm {
  public:
-  static DisplayError (*GetDrmFeature[kMaxNumPPFeatures])(const PPFeatureInfo &in_data,
+  static DisplayError (*GetDrmFeature[kPPFeaturesMax])(const PPFeatureInfo &in_data,
                                                           DRMPPFeatureInfo *out_data);
   static void FreeDrmFeatureData(DRMPPFeatureInfo *feature);
   static uint32_t GetFeatureVersion(const DRMPPFeatureInfo &feature);
@@ -55,10 +83,12 @@
   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);
+  static DisplayError GetDrmPAHsic(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmPASixZone(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
+  static DisplayError GetDrmPAMemColor(const PPFeatureInfo &in_data, DRMPPFeatureInfo *out_data);
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index bd09a38..67b990b 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -1142,14 +1142,22 @@
 
     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_);
+      auto drm_features = DrmPPfeatureMap_.find(feature->feature_id_);
+      if (drm_features == DrmPPfeatureMap_.end()) {
+        DLOGE("DrmFeatures 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);
+
+      for (uint32_t drm_feature : drm_features->second) {
+        if (!HWColorManagerDrm::GetDrmFeature[drm_feature]) {
+          DLOGE("GetDrmFeature is not valid for DRM feature %d", drm_feature);
+          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);
+      }
     }
   }