sdm: drm: Add support to select CSC matrix type in DRM

Add support to select CSC matrix type based on color meta
data, and set CSC config.

CRs-Fixed: 2079944
Change-Id: I0b4cfc0c6a46c6a3997856d346f1c3efc1ac676c
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index ca2f6ff..4ecfcbf 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -138,6 +138,12 @@
    */
   PLANE_SET_FB_SECURE_MODE,
   /*
+   * Op: Sets csc config on this plane.
+   * Arg: uint32_t - Plane ID
+   *      uint32_t* - pointer to csc type
+   */
+  PLANE_SET_CSC_CONFIG,
+  /*
    * Op: Activate or deactivate a CRTC
    * Arg: uint32_t - CRTC ID
    *      uint32_t - 1 to enable, 0 to disable
@@ -465,6 +471,15 @@
   void *payload;
 };
 
+enum DRMCscType {
+  kCscYuv2Rgb601L,
+  kCscYuv2Rgb601FR,
+  kCscYuv2Rgb709L,
+  kCscYuv2Rgb2020L,
+  kCscYuv2Rgb2020FR,
+  kCscTypeMax,
+};
+
 struct DRMScalerLUTInfo {
   uint32_t dir_lut_size = 0;
   uint32_t cir_lut_size = 0;
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 5a9112e..050f7ae 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -97,6 +97,7 @@
 using sde_drm::DRMPowerMode;
 using sde_drm::DRMSecureMode;
 using sde_drm::DRMSecurityLevel;
+using sde_drm::DRMCscType;
 
 namespace sdm {
 
@@ -817,6 +818,10 @@
                                       reinterpret_cast<uint64_t>(&scaler_output.scaler_v2));
           }
         }
+
+        DRMCscType csc_type = DRMCscType::kCscTypeMax;
+        SelectCscType(layer.input_buffer, &csc_type);
+        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_CSC_CONFIG, pipe_id, &csc_type);
       }
     }
   }
@@ -1004,6 +1009,34 @@
   }
 }
 
+void HWDeviceDRM::SelectCscType(const LayerBuffer &input_buffer, DRMCscType *type) {
+  if (type == NULL) {
+    return;
+  }
+
+  *type = DRMCscType::kCscTypeMax;
+  if (input_buffer.format < kFormatYCbCr420Planar) {
+    return;
+  }
+
+  switch (input_buffer.color_metadata.colorPrimaries) {
+    case ColorPrimaries_BT601_6_525:
+    case ColorPrimaries_BT601_6_625:
+      *type = ((input_buffer.color_metadata.range == Range_Full) ?
+               DRMCscType::kCscYuv2Rgb601FR : DRMCscType::kCscYuv2Rgb601L);
+      break;
+    case ColorPrimaries_BT709_5:
+      *type = DRMCscType::kCscYuv2Rgb709L;
+      break;
+    case ColorPrimaries_BT2020:
+      *type = ((input_buffer.color_metadata.range == Range_Full) ?
+                DRMCscType::kCscYuv2Rgb2020FR : DRMCscType::kCscYuv2Rgb2020L);
+      break;
+    default:
+      break;
+  }
+}
+
 void HWDeviceDRM::SetRect(const LayerRect &source, DRMRect *target) {
   target->left = UINT32(source.left);
   target->top = UINT32(source.top);
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index ee5b6c7..883d605 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -123,6 +123,7 @@
   void AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha);
   void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
   void SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config);
+  void SelectCscType(const LayerBuffer &input_buffer, sde_drm::DRMCscType *type);
   void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
   void SetRotation(LayerTransform transform, const HWRotatorMode &mode, uint32_t* rot_bit_mask);
   DisplayError DefaultCommit(HWLayers *hw_layers);