sdm: Initial change for Dpps interface

Support DppsInterface in SDM to create and destroy Dpps server.
And DppsPropIntf provides functions to set and get Dpps properties.

CRs-Fixed: 2232100
Change-Id: I0ecf93ef994ba94ae1baf4f97031e257d30d3dcd
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 2aeb337..b552a57 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -351,13 +351,20 @@
    * Arg: uint32_t - Connector ID
    * DRMPPFeatureInfo * - PP feature data pointer
    */
-   CONNECTOR_SET_POST_PROC,
+  CONNECTOR_SET_POST_PROC,
   /*
    * Op: Sets connector hdr metadata
    * Arg: uint32_t - Connector ID
    *      drm_msm_ext_hdr_metadata - hdr_metadata
    */
   CONNECTOR_SET_HDR_METADATA,
+  /*
+   * Op: Cache Dpps features.
+   * Arg: uint32_t - Object ID
+          uint32_t - Feature ID
+   *      uint64_t - Pointer to feature config data
+   */
+  DPPS_CACHE_FEATURE,
 };
 
 enum struct DRMRotation {
@@ -601,6 +608,56 @@
   uint32_t object_type;
 };
 
+enum DRMDPPSFeatureID {
+  // Ad4 properties
+  kFeatureAd4Mode,
+  kFeatureAd4Init,
+  kFeatureAd4Cfg,
+  kFeatureAd4Input,
+  kFeatureAd4Backlight,
+  kFeatureAd4Assertiveness,
+  kFeatureAd4ManualStrength,
+  // ABA properties
+  kFeatureAbaHistCtrl,
+  kFeatureAbaHistIRQ,
+  kFeatureAbaLut,
+  // BL scale properties
+  kFeatureAd4BlScale,
+  kFeatureBacklightScale,
+  // Events
+  kFeaturePowerEvent,
+  kFeatureAbaHistEvent,
+  kFeatureBackLightEvent,
+  kFeatureAdAttBlEvent,
+  // Insert features above
+  kDppsFeaturesMax,
+};
+
+struct DRMDppsFeatureInfo {
+  DRMDPPSFeatureID id;
+  uint32_t version;
+};
+
+enum AD4Modes {
+  kAd4Off,
+  kAd4AutoStrength,
+  kAd4Calibration,
+  kAd4Manual,
+  kAd4ModeMax,
+};
+
+enum HistModes {
+  kHistDisabled,
+  kHistEnabled,
+};
+
+struct DRMDppsEventInfo {
+  uint32_t object_type;
+  uint32_t event_type;
+  int drm_fd;
+  bool enable;
+};
+
 enum DRMCscType {
   kCscYuv2Rgb601L,
   kCscYuv2Rgb601FR,
@@ -638,16 +695,16 @@
 };
 
 struct DRMSolidfillStage {
- DRMRect bounding_rect {};
- bool is_exclusion_rect = false;
- uint32_t color = 0xff000000; // in 8bit argb
- uint32_t red = 0;
- uint32_t blue = 0;
- uint32_t green = 0;
- uint32_t alpha = 0xff;
- uint32_t color_bit_depth = 0;
- uint32_t z_order = 0;
- uint32_t plane_alpha = 0xff;
+  DRMRect bounding_rect {};
+  bool is_exclusion_rect = false;
+  uint32_t color = 0xff000000;  // in 8bit argb
+  uint32_t red = 0;
+  uint32_t blue = 0;
+  uint32_t green = 0;
+  uint32_t alpha = 0xff;
+  uint32_t color_bit_depth = 0;
+  uint32_t z_order = 0;
+  uint32_t plane_alpha = 0xff;
 };
 
 /* DRM Atomic Request Property Set.
@@ -767,6 +824,13 @@
    * [return]: Error code if the API fails, 0 on success.
    */
   virtual int SetScalerLUT(const DRMScalerLUTInfo &lut_info) = 0;
+
+  /*
+   * Get the DPPS feature info
+   * [input]: Dpps feature id, info->id
+   * [output]: Dpps feature version, info->version
+   */
+  virtual void GetDppsFeatureInfo(DRMDppsFeatureInfo *info) = 0;
 };
 
 }  // namespace sde_drm
diff --git a/sdm/include/core/dpps_interface.h b/sdm/include/core/dpps_interface.h
new file mode 100644
index 0000000..d3d3d02
--- /dev/null
+++ b/sdm/include/core/dpps_interface.h
@@ -0,0 +1,70 @@
+/*
+* Copyright (c) 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
+* 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 __DPPS_INTERFACE_H__
+#define __DPPS_INTERFACE_H__
+
+#include <core/sdm_types.h>
+
+namespace sdm {
+
+class DppsPropIntf {
+ public:
+  virtual DisplayError SetDppsFeature(uint32_t object_type,
+                                      uint32_t feature_id, uint64_t value) = 0;
+  virtual DisplayError GetDppsFeatureInfo(void *info) = 0;
+
+ protected:
+  virtual ~DppsPropIntf() { }
+};
+
+class DppsInterface {
+ public:
+  virtual int Init(DppsPropIntf* intf) = 0;
+  virtual int Deinit() = 0;
+
+ protected:
+  virtual ~DppsInterface() { }
+};
+
+class DppsDummyImpl : public DppsInterface {
+ public:
+  int Init(DppsPropIntf* intf) {
+    (void)intf;
+    return 0;
+  }
+  int Deinit() {
+    delete this;
+    return 0;
+  }
+};
+
+}  // namespace sdm
+
+#endif  // __DPPS_INTERFACE_H__
diff --git a/sdm/libs/core/Android.mk b/sdm/libs/core/Android.mk
index d4aa933..8256d2f 100644
--- a/sdm/libs/core/Android.mk
+++ b/sdm/libs/core/Android.mk
@@ -69,7 +69,8 @@
                                  $(SDM_HEADER_PATH)/core/layer_buffer.h \
                                  $(SDM_HEADER_PATH)/core/layer_stack.h \
                                  $(SDM_HEADER_PATH)/core/sdm_types.h \
-                                 $(SDM_HEADER_PATH)/core/socket_handler.h
+                                 $(SDM_HEADER_PATH)/core/socket_handler.h \
+                                 $(SDM_HEADER_PATH)/core/dpps_interface.h
 include $(BUILD_COPY_HEADERS)
 
 include $(CLEAR_VARS)
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index d9fef33..fe38fcd 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -101,6 +101,13 @@
   return error;
 }
 
+DisplayError DisplayPrimary::Deinit() {
+  lock_guard<recursive_mutex> obj(recursive_mutex_);
+
+  dpps_info_.Deinit();
+  return DisplayBase::Deinit();
+}
+
 DisplayError DisplayPrimary::Prepare(LayerStack *layer_stack) {
   lock_guard<recursive_mutex> obj(recursive_mutex_);
   DisplayError error = kErrorNone;
@@ -163,6 +170,8 @@
     ControlPartialUpdate(true /* enable */, &pending);
   }
 
+  dpps_info_.Init(this);
+
   return error;
 }
 
@@ -419,5 +428,61 @@
   }
 }
 
+DisplayError DisplayPrimary::SetDppsFeature(uint32_t object_type,
+                            uint32_t feature_id, uint64_t value) {
+    return hw_intf_->SetDppsFeature(object_type, feature_id, value);
+}
+
+DisplayError DisplayPrimary::GetDppsFeatureInfo(void *info) {
+    return hw_intf_->GetDppsFeatureInfo(info);
+}
+
+void DppsInfo::Init(DppsPropIntf* intf) {
+  int error = 0;
+
+  if (dpps_initialized_) {
+    return;
+  }
+
+  if (!dpps_impl_lib.Open(kDppsLib)) {
+    DLOGW("Failed to load Dpps lib %s", kDppsLib);
+    goto exit;
+  }
+
+  if (!dpps_impl_lib.Sym("GetDppsInterface",
+         reinterpret_cast<void **>(&GetDppsInterface))) {
+    DLOGE("GetDppsInterface not found!, err %s", dlerror());
+    goto exit;
+  }
+
+  dpps_intf = GetDppsInterface();
+  if (!dpps_intf) {
+    DLOGE("Failed to get Dpps Interface!");
+    goto exit;
+  }
+
+  error = dpps_intf->Init(intf);
+  if (!error) {
+    DLOGI("DPPS Interface init successfully");
+    dpps_initialized_ = true;
+    return;
+  } else {
+    DLOGE("DPPS Interface init failure with err %d", error);
+  }
+
+exit:
+  Deinit();
+  dpps_intf = new DppsDummyImpl();
+  dpps_initialized_ = true;
+}
+
+void DppsInfo::Deinit() {
+  if (dpps_intf) {
+    dpps_intf->Deinit();
+    dpps_intf = NULL;
+  }
+  dpps_impl_lib.~DynLib();
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/display_primary.h b/sdm/libs/core/display_primary.h
index e14c6d7..ff5ba69 100644
--- a/sdm/libs/core/display_primary.h
+++ b/sdm/libs/core/display_primary.h
@@ -25,6 +25,7 @@
 #ifndef __DISPLAY_PRIMARY_H__
 #define __DISPLAY_PRIMARY_H__
 
+#include <core/dpps_interface.h>
 #include <vector>
 
 #include "display_base.h"
@@ -34,12 +35,26 @@
 
 class HWPrimaryInterface;
 
-class DisplayPrimary : public DisplayBase, HWEventHandler {
+class DppsInfo {
+ public:
+  void Init(DppsPropIntf* intf);
+  void Deinit();
+
+ private:
+  const char *kDppsLib = "libdpps.so";
+  DynLib dpps_impl_lib;
+  DppsInterface* dpps_intf = NULL;
+  DppsInterface* (*GetDppsInterface)() = NULL;
+  bool dpps_initialized_ = false;
+};
+
+class DisplayPrimary : public DisplayBase, HWEventHandler, DppsPropIntf {
  public:
   DisplayPrimary(DisplayEventHandler *event_handler, HWInfoInterface *hw_info_intf,
                  BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
                  CompManager *comp_manager);
   virtual DisplayError Init();
+  virtual DisplayError Deinit();
   virtual DisplayError Prepare(LayerStack *layer_stack);
   virtual DisplayError Commit(LayerStack *layer_stack);
   virtual DisplayError ControlPartialUpdate(bool enable, uint32_t *pending);
@@ -63,6 +78,11 @@
   virtual void PingPongTimeout();
   virtual void PanelDead();
 
+  // Implement the DppsPropIntf
+  virtual DisplayError SetDppsFeature(uint32_t object_type,
+                                      uint32_t feature_id, uint64_t value);
+  virtual DisplayError GetDppsFeatureInfo(void *info);
+
  private:
   bool NeedsAVREnable();
   void ResetPanel();
@@ -73,6 +93,7 @@
   bool handle_idle_timeout_ = false;
   uint32_t current_refresh_rate_ = 0;
   bool reset_panel_ = false;
+  DppsInfo dpps_info_ = {};
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index a0782c4..809fd96 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -105,6 +105,9 @@
   virtual void InitializeConfigs();
   virtual DisplayError DumpDebugData() { return kErrorNone; }
   virtual void PopulateHWPanelInfo();
+  virtual DisplayError SetDppsFeature(uint32_t object_type, uint32_t feature_id,
+                                      uint64_t value) { return kErrorNotSupported; }
+  virtual DisplayError GetDppsFeatureInfo(void *info) { return kErrorNotSupported; }
 
   enum {
     kHWEventVSync,
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.cpp b/sdm/libs/core/drm/hw_peripheral_drm.cpp
index 44c22e7..35537a5 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.cpp
+++ b/sdm/libs/core/drm/hw_peripheral_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
@@ -36,6 +36,7 @@
 using sde_drm::DRMDisplayType;
 using sde_drm::DRMOps;
 using sde_drm::DRMPowerMode;
+using sde_drm::DRMDppsFeatureInfo;
 
 namespace sdm {
 
@@ -131,5 +132,27 @@
   return kErrorNone;
 }
 
+DisplayError HWPeripheralDRM::SetDppsFeature(uint32_t object_type,
+        uint32_t feature_id, uint64_t value) {
+  uint32_t obj_id;
+
+  if (object_type == DRM_MODE_OBJECT_CRTC) {
+    obj_id = token_.crtc_id;
+  } else if (object_type == DRM_MODE_OBJECT_CONNECTOR) {
+    obj_id = token_.conn_id;
+  } else {
+    DLOGE("invalid object type 0x%x", object_type);
+    return kErrorUndefined;
+  }
+
+  drm_atomic_intf_->Perform(DRMOps::DPPS_CACHE_FEATURE, obj_id, feature_id, value);
+  return kErrorNone;
+}
+
+DisplayError HWPeripheralDRM::GetDppsFeatureInfo(void *info) {
+  DRMDppsFeatureInfo *feature_info = reinterpret_cast<DRMDppsFeatureInfo *>(info);
+  drm_mgr_intf_->GetDppsFeatureInfo(feature_info);
+  return kErrorNone;
+}
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_peripheral_drm.h b/sdm/libs/core/drm/hw_peripheral_drm.h
index e4b33cf..6da6249 100644
--- a/sdm/libs/core/drm/hw_peripheral_drm.h
+++ b/sdm/libs/core/drm/hw_peripheral_drm.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
@@ -47,6 +47,9 @@
   virtual DisplayError Validate(HWLayers *hw_layers);
   virtual DisplayError Commit(HWLayers *hw_layers);
   virtual DisplayError Flush();
+  virtual DisplayError SetDppsFeature(uint32_t object_type, uint32_t feature_id,
+                                      uint64_t value);
+  virtual DisplayError GetDppsFeatureInfo(void *info);
  private:
   void SetDestScalarData(HWLayersInfo hw_layer_info);
   void ResetDisplayParams();
diff --git a/sdm/libs/core/fb/hw_device.h b/sdm/libs/core/fb/hw_device.h
index 353cce5..08f9230 100644
--- a/sdm/libs/core/fb/hw_device.h
+++ b/sdm/libs/core/fb/hw_device.h
@@ -98,6 +98,9 @@
   virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes);
   virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
   virtual DisplayError DumpDebugData();
+  virtual DisplayError SetDppsFeature(uint32_t object_type, uint32_t feature_id,
+                                      uint64_t value) { return kErrorNotSupported; }
+  virtual DisplayError GetDppsFeatureInfo(void *info) { return kErrorNotSupported; }
 
   enum {
     kHWEventVSync,
diff --git a/sdm/libs/core/hw_interface.h b/sdm/libs/core/hw_interface.h
index 483a4df..fdb901f 100644
--- a/sdm/libs/core/hw_interface.h
+++ b/sdm/libs/core/hw_interface.h
@@ -113,6 +113,9 @@
   virtual DisplayError SetMixerAttributes(const HWMixerAttributes &mixer_attributes) = 0;
   virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes) = 0;
   virtual DisplayError DumpDebugData() = 0;
+  virtual DisplayError SetDppsFeature(uint32_t object_type,
+                                      uint32_t feature_id, uint64_t value) = 0;
+  virtual DisplayError GetDppsFeatureInfo(void *info) = 0;
 
  protected:
   virtual ~HWInterface() { }