display: DCI-P3 support in colorimetry

- Add COLORSPACE, SUPPORTED_COLORSPACES properties.
- SUPPORTED_COLORSPACES: each bit specifies supported colorspace.
- COLORSPACE: set one of the colorspace based on the input content.
- Populate DCIP3, DISPLAY_BT2020 color modes based on supported
  color spaces.
- For P3 color gamut, set blend space as dcip3 srgb.
- For Bt2020 color gamut set Bt2020_srgb irresepctive of gamma transfer.
- If external DP supports colorspace, based on input layers, set
  colorspace on DP.

CRs-Fixed: 2450712
Change-Id: I704003bd23df29e462189d4316cb935f8cdebf05
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index bebc23a..40999e0 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -396,6 +396,12 @@
    *      uint32_t - Frame trigger mode
    */
   CONNECTOR_SET_FRAME_TRIGGER,
+  /*
+   * Op: Sets colorspace on DP connector
+   * Arg: uint32_t - Connector ID
+   *      uint32_t - colorspace value bit-mask
+   */
+  CONNECTOR_SET_COLORSPACE,
 };
 
 enum struct DRMRotation {
@@ -620,6 +626,7 @@
   uint32_t topology_control;
   bool dyn_bitclk_support;
   std::vector<uint8_t> edid;
+  uint32_t supported_colorspaces;
 };
 
 // All DRM Connectors as map<Connector_id , connector_info>
@@ -835,6 +842,23 @@
   FRAME_DONE_WAIT_POSTED_START,
 };
 
+/* DRM Color spaces exposed by the DP connector */
+enum struct DRMColorspace {
+  DEFAULT = 0,
+  SMPTE_170M_YCC,
+  BT709_YCC,
+  XVYCC_601,
+  XVYCC_709,
+  SYCC_601,
+  OPYCC_601,
+  OPRGB,
+  BT2020_CYCC,
+  BT2020_RGB,
+  BT2020_YCC,
+  DCI_P3_RGB_D65,
+  DCI_P3_RGB_THEATER,
+};
+
 /* DRM Atomic Request Property Set.
  *
  * Helper class to create and populate atomic properties of DRM components
diff --git a/sde-drm/drm_atomic_req.cpp b/sde-drm/drm_atomic_req.cpp
index b565603..f3caca7 100644
--- a/sde-drm/drm_atomic_req.cpp
+++ b/sde-drm/drm_atomic_req.cpp
@@ -121,7 +121,8 @@
     case DRMOps::CONNECTOR_SET_HDR_METADATA:
     case DRMOps::CONNECTOR_SET_QSYNC_MODE:
     case DRMOps::CONNECTOR_SET_TOPOLOGY_CONTROL:
-    case DRMOps::CONNECTOR_SET_FRAME_TRIGGER: {
+    case DRMOps::CONNECTOR_SET_FRAME_TRIGGER:
+    case DRMOps::CONNECTOR_SET_COLORSPACE: {
       drm_mgr_->GetConnectorMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
     } break;
     case DRMOps::DPPS_CACHE_FEATURE: {
diff --git a/sde-drm/drm_connector.cpp b/sde-drm/drm_connector.cpp
index 6eab006..6a5f10c 100644
--- a/sde-drm/drm_connector.cpp
+++ b/sde-drm/drm_connector.cpp
@@ -77,6 +77,20 @@
 static uint8_t FRAME_TRIGGER_SERIALIZE = 1;
 static uint8_t FRAME_TRIGGER_POSTED_START = 2;
 
+static uint8_t DRM_MODE_COLORIMETRY_DEFAULT            = 0;
+static uint8_t DRM_MODE_COLORIMETRY_SMPTE_170M_YCC     = 1;
+static uint8_t DRM_MODE_COLORIMETRY_BT709_YCC          = 2;
+static uint8_t DRM_MODE_COLORIMETRY_XVYCC_601          = 3;
+static uint8_t DRM_MODE_COLORIMETRY_XVYCC_709          = 4;
+static uint8_t DRM_MODE_COLORIMETRY_SYCC_601           = 5;
+static uint8_t DRM_MODE_COLORIMETRY_OPYCC_601          = 6;
+static uint8_t DRM_MODE_COLORIMETRY_OPRGB              = 7;
+static uint8_t DRM_MODE_COLORIMETRY_BT2020_CYCC        = 8;
+static uint8_t DRM_MODE_COLORIMETRY_BT2020_RGB         = 9;
+static uint8_t DRM_MODE_COLORIMETRY_BT2020_YCC         = 10;
+static uint8_t DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65     = 11;
+static uint8_t DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER = 12;
+
 static void PopulatePowerModes(drmModePropertyRes *prop) {
   for (auto i = 0; i < prop->count_enums; i++) {
     string enum_name(prop->enums[i].name);
@@ -103,6 +117,39 @@
   }
 }
 
+static void PopulateSupportedColorspaces(drmModePropertyRes *prop) {
+  for (auto i = 0; i < prop->count_enums; i++) {
+    string enum_name(prop->enums[i].name);
+    if (enum_name == "Default") {
+      DRM_MODE_COLORIMETRY_DEFAULT = prop->enums[i].value;
+    } else if (enum_name == "SMPTE_170M_YCC") {
+      DRM_MODE_COLORIMETRY_SMPTE_170M_YCC = prop->enums[i].value;
+    } else if (enum_name == "BT709_YCC") {
+      DRM_MODE_COLORIMETRY_BT709_YCC = prop->enums[i].value;
+    } else if (enum_name == "XVYCC_601") {
+      DRM_MODE_COLORIMETRY_XVYCC_601 = prop->enums[i].value;
+    } else if (enum_name == "XVYCC_709") {
+      DRM_MODE_COLORIMETRY_XVYCC_709 = prop->enums[i].value;
+    } else if (enum_name == "SYCC_601") {
+      DRM_MODE_COLORIMETRY_SYCC_601 = prop->enums[i].value;
+    } else if (enum_name == "opYCC_601") {
+      DRM_MODE_COLORIMETRY_OPYCC_601 = prop->enums[i].value;
+    } else if (enum_name == "opRGB") {
+      DRM_MODE_COLORIMETRY_OPRGB = prop->enums[i].value;
+    } else if (enum_name == "BT2020_CYCC") {
+      DRM_MODE_COLORIMETRY_BT2020_CYCC = prop->enums[i].value;
+    } else if (enum_name == "BT2020_RGB") {
+      DRM_MODE_COLORIMETRY_BT2020_RGB = prop->enums[i].value;
+    } else if (enum_name == "BT2020_YCC") {
+      DRM_MODE_COLORIMETRY_BT2020_YCC = prop->enums[i].value;
+    } else if (enum_name == "DCI_P3_RGB_D65") {
+      DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65 = prop->enums[i].value;
+    } else if (enum_name == "DCI_P3_RGB_Theater") {
+      DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER = prop->enums[i].value;
+    }
+  }
+}
+
 static DRMTopology GetTopologyEnum(const string &topology) {
   if (topology == "sde_singlepipe") return DRMTopology::SINGLE_LM;
   if (topology == "sde_singlepipe_dsc") return DRMTopology::SINGLE_LM_DSC;
@@ -139,6 +186,55 @@
   }
 }
 
+static int32_t GetColorspace(DRMColorspace drm_colorspace) {
+  uint32_t colorspace = 0;
+  switch (drm_colorspace) {
+    case (DRMColorspace::DEFAULT):
+      colorspace = DRM_MODE_COLORIMETRY_DEFAULT;
+      break;
+    case (DRMColorspace::SMPTE_170M_YCC):
+      colorspace = DRM_MODE_COLORIMETRY_SMPTE_170M_YCC;
+      break;
+    case (DRMColorspace::BT709_YCC):
+      colorspace = DRM_MODE_COLORIMETRY_BT709_YCC;
+      break;
+    case (DRMColorspace::XVYCC_601):
+      colorspace = DRM_MODE_COLORIMETRY_XVYCC_601;
+      break;
+    case (DRMColorspace::XVYCC_709):
+      colorspace = DRM_MODE_COLORIMETRY_XVYCC_709;
+      break;
+     case (DRMColorspace::SYCC_601):
+      colorspace = DRM_MODE_COLORIMETRY_SYCC_601;
+      break;
+    case (DRMColorspace::OPYCC_601):
+      colorspace = DRM_MODE_COLORIMETRY_OPYCC_601;
+      break;
+    case (DRMColorspace::OPRGB):
+      colorspace = DRM_MODE_COLORIMETRY_OPRGB;
+      break;
+    case (DRMColorspace::BT2020_CYCC):
+      colorspace = DRM_MODE_COLORIMETRY_BT2020_CYCC;
+      break;
+    case (DRMColorspace::BT2020_RGB):
+      colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
+      break;
+    case (DRMColorspace::BT2020_YCC):
+      colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
+      break;
+    case (DRMColorspace::DCI_P3_RGB_D65):
+      colorspace = DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65;
+      break;
+    case (DRMColorspace::DCI_P3_RGB_THEATER):
+      colorspace = DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER;
+      break;
+    default:
+      colorspace = -1;
+      break;
+  }
+  return colorspace;
+}
+
 #define __CLASS__ "DRMConnectorManager"
 
 void DRMConnectorManager::Init(drmModeRes *resource) {
@@ -371,6 +467,8 @@
       PopulateQsyncModes(info);
     } else if (prop_enum == DRMProperty::FRAME_TRIGGER) {
       PopulateFrameTriggerModes(info);
+    } else if (prop_enum == DRMProperty::COLORSPACE) {
+      PopulateSupportedColorspaces(info);
     }
 
     prop_mgr_.SetPropertyId(prop_enum, info->prop_id);
@@ -538,20 +636,20 @@
 
   struct drm_msm_ext_hdr_properties *hdr_cdata = (struct drm_msm_ext_hdr_properties*)(blob->data);
 
-  if(hdr_cdata) {
-   hdr_info->hdr_supported = hdr_cdata->hdr_supported;
-   hdr_info->hdr_plus_supported = hdr_cdata->hdr_plus_supported;
-   hdr_info->hdr_eotf = hdr_cdata->hdr_eotf;
-   hdr_info->hdr_metadata_type_one = hdr_cdata->hdr_metadata_type_one;
-   hdr_info->hdr_max_luminance = hdr_cdata->hdr_max_luminance;
-   hdr_info->hdr_avg_luminance = hdr_cdata->hdr_avg_luminance;
-   hdr_info->hdr_min_luminance = hdr_cdata->hdr_min_luminance;
-   DRM_LOGI("hdr_supported = %d, hdr_plus_supported = %d, hdr_eotf = %d, "
-            "hdr_metadata_type_one = %d, hdr_max_luminance = %d, hdr_avg_luminance = %d, "
-            "hdr_min_luminance = %d\n", hdr_info->hdr_supported,
-            hdr_info->hdr_plus_supported,
-            hdr_info->hdr_eotf, hdr_info->hdr_metadata_type_one, hdr_info->hdr_max_luminance,
-            hdr_info->hdr_avg_luminance, hdr_info->hdr_min_luminance);
+  if (hdr_cdata) {
+    hdr_info->hdr_supported = hdr_cdata->hdr_supported;
+    hdr_info->hdr_plus_supported = hdr_cdata->hdr_plus_supported;
+    hdr_info->hdr_eotf = hdr_cdata->hdr_eotf;
+    hdr_info->hdr_metadata_type_one = hdr_cdata->hdr_metadata_type_one;
+    hdr_info->hdr_max_luminance = hdr_cdata->hdr_max_luminance;
+    hdr_info->hdr_avg_luminance = hdr_cdata->hdr_avg_luminance;
+    hdr_info->hdr_min_luminance = hdr_cdata->hdr_min_luminance;
+    DRM_LOGI("hdr_supported = %d, hdr_plus_supported = %d, hdr_eotf = %d, "
+             "hdr_metadata_type_one = %d, hdr_max_luminance = %d, hdr_avg_luminance = %d, "
+             "hdr_min_luminance = %d\n", hdr_info->hdr_supported,
+             hdr_info->hdr_plus_supported,
+             hdr_info->hdr_eotf, hdr_info->hdr_metadata_type_one, hdr_info->hdr_max_luminance,
+             hdr_info->hdr_avg_luminance, hdr_info->hdr_min_luminance);
   }
   drmModeFreePropertyBlob(blob);
 }
@@ -660,6 +758,13 @@
     ParseCapabilities(props->prop_values[index], &info->edid);
   }
 
+  if (prop_mgr_.IsPropertyAvailable(DRMProperty::SUPPORTED_COLORSPACES)) {
+    index = std::distance(props->props,
+                          std::find(props->props, props->props + props->count_props,
+                                    prop_mgr_.GetPropertyId(DRMProperty::SUPPORTED_COLORSPACES)));
+    info->supported_colorspaces = props->prop_values[index];
+  }
+
   drmModeFreeObjectProperties(props);
 
   return 0;
@@ -819,6 +924,27 @@
       }
     } break;
 
+    case DRMOps::CONNECTOR_SET_COLORSPACE: {
+      if (!prop_mgr_.IsPropertyAvailable(DRMProperty::COLORSPACE)) {
+        return;
+      }
+      DRMColorspace drm_colorspace = static_cast<DRMColorspace>(va_arg(args, uint32_t));
+      int32_t colorspace = 0;
+      colorspace = GetColorspace(drm_colorspace);
+      if (colorspace >= 0) {
+        uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::COLORSPACE);
+        int ret = drmModeAtomicAddProperty(req, obj_id, prop_id, colorspace);
+        if (ret < 0) {
+          DRM_LOGE("AtomicAddProperty failed obj_id 0x%x, prop_id %d mode %d ret %d",
+                   obj_id, prop_id, colorspace, ret);
+        } else {
+          DRM_LOGD("Connector %d: Setting colorspace %d", obj_id, colorspace);
+        }
+      } else {
+        DRM_LOGE("Invalid colorspace %d", colorspace);
+      }
+    } break;
+
     default:
       DRM_LOGE("Invalid opcode %d to set on connector %d", code, obj_id);
       break;
diff --git a/sde-drm/drm_property.cpp b/sde-drm/drm_property.cpp
index 0269f89..c144aad 100644
--- a/sde-drm/drm_property.cpp
+++ b/sde-drm/drm_property.cpp
@@ -160,6 +160,8 @@
   if (name == "SDE_VIG_1D_LUT_IGC_V6") { return DRMProperty::SDE_VIG_1D_LUT_IGC_V6; }
   if (name == "SDE_VIG_3D_LUT_GAMUT_V6") { return DRMProperty::SDE_VIG_3D_LUT_GAMUT_V6; }
   if (name == "frame_trigger_mode") { return DRMProperty::FRAME_TRIGGER; }
+  if (name == "Colorspace") { return DRMProperty::COLORSPACE; }
+  if (name == "supported_colorspaces") { return DRMProperty::SUPPORTED_COLORSPACES; }
 
   return DRMProperty::INVALID;
 }
diff --git a/sde-drm/drm_property.h b/sde-drm/drm_property.h
index 32fe817..dcda7aa 100644
--- a/sde-drm/drm_property.h
+++ b/sde-drm/drm_property.h
@@ -165,6 +165,8 @@
   SDE_LTM_QUEUE_BUFFER3,
   SDE_LTM_VLUT,
   FRAME_TRIGGER,
+  COLORSPACE,
+  SUPPORTED_COLORSPACES,
 
   // Insert above
   MAX
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 0f5f94c..d182269 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -152,6 +152,18 @@
   kHdrEOTFHLG = 0x8,
 };
 
+enum HwColorspace {
+  kColorspaceXvycc601     = (1 << 0),
+  kColorspaceXvycc709     = (1 << 1),
+  kColorspaceSycc601      = (1 << 2),
+  kColorspaceAdobeycc601  = (1 << 3),
+  kColorspaceAdobergb     = (1 << 4),
+  kColorspaceBt2020cycc   = (1 << 5),
+  kColorspaceBt2020ycc    = (1 << 6),
+  kColorspaceBt2020rgb    = (1 << 7),
+  kColorspaceDcip3        = (1 << 15)
+};
+
 enum HWSrcTonemap {
   kSrcTonemapNone,
   kSrcTonemap1d,  // DMA
@@ -373,6 +385,7 @@
   bool qsync_support = false;          // Specifies panel supports qsync feature or not.
   bool dyn_bitclk_support = false;     // Bit clk can be updated to avoid RF interference.
   std::vector<uint64_t> bitclk_rates;  // Supported bit clk levels.
+  uint32_t supported_colorspaces = 0;  // supported_colorspaces for DP displays.
 
   bool operator !=(const HWPanelInfo &panel_info) {
     return ((port != panel_info.port) || (mode != panel_info.mode) ||
diff --git a/sdm/libs/core/display_pluggable.cpp b/sdm/libs/core/display_pluggable.cpp
index e34f155..820457f 100644
--- a/sdm/libs/core/display_pluggable.cpp
+++ b/sdm/libs/core/display_pluggable.cpp
@@ -269,7 +269,11 @@
 
 DisplayError DisplayPluggable::InitializeColorModes() {
   PrimariesTransfer pt = {};
-  AttrVal var;
+  AttrVal var = {};
+  if (hw_panel_info_.supported_colorspaces) {
+    InitializeColorModesFromColorspace();
+  }
+
   if (!hw_panel_info_.hdr_enabled) {
     return kErrorNone;
   } else {
@@ -284,16 +288,6 @@
     color_modes_cs_.push_back(pt);
     var.clear();
     color_mode_attr_map_.insert(std::make_pair("hal_native", var));
-
-    pt.primaries = ColorPrimaries_BT2020;
-    pt.transfer = Transfer_sRGB;
-    color_modes_cs_.push_back(pt);
-    var.clear();
-    var.push_back(std::make_pair(kColorGamutAttribute, kBt2020));
-    var.push_back(std::make_pair(kGammaTransferAttribute, kSrgb));
-    var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
-    var.push_back(std::make_pair(kRenderIntentAttribute, "0"));
-    color_mode_attr_map_.insert(std::make_pair(kDisplayBt2020, var));
   }
 
   var.clear();
@@ -319,6 +313,33 @@
   return kErrorNone;
 }
 
+void DisplayPluggable::InitializeColorModesFromColorspace() {
+  PrimariesTransfer pt = {};
+  AttrVal var = {};
+  if (hw_panel_info_.supported_colorspaces & kColorspaceDcip3) {
+    pt.primaries = ColorPrimaries_DCIP3;
+    pt.transfer = Transfer_sRGB;
+    var.clear();
+    var.push_back(std::make_pair(kColorGamutAttribute, kDcip3));
+    var.push_back(std::make_pair(kGammaTransferAttribute, kSrgb));
+    var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
+    var.push_back(std::make_pair(kRenderIntentAttribute, "0"));
+    color_modes_cs_.push_back(pt);
+    color_mode_attr_map_.insert(std::make_pair(kDisplayP3, var));
+  }
+  if (hw_panel_info_.supported_colorspaces & kColorspaceBt2020rgb) {
+    pt.primaries = ColorPrimaries_BT2020;
+    pt.transfer = Transfer_sRGB;
+    var.clear();
+    var.push_back(std::make_pair(kColorGamutAttribute, kBt2020));
+    var.push_back(std::make_pair(kGammaTransferAttribute, kSrgb));
+    var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
+    var.push_back(std::make_pair(kRenderIntentAttribute, "0"));
+    color_modes_cs_.push_back(pt);
+    color_mode_attr_map_.insert(std::make_pair(kDisplayBt2020, var));
+  }
+}
+
 static PrimariesTransfer GetBlendSpaceFromAttributes(const std::string &color_gamut,
                                                      const std::string &transfer) {
   PrimariesTransfer blend_space_ = {};
@@ -331,6 +352,9 @@
     } else if (transfer == kGamma2_2) {
       blend_space_.transfer = Transfer_Gamma2_2;
     }
+  } else if (color_gamut == kDcip3) {
+    blend_space_.primaries = ColorPrimaries_DCIP3;
+    blend_space_.transfer = Transfer_sRGB;
   } else if (color_gamut == kSrgb) {
     blend_space_.primaries = ColorPrimaries_BT709_5;
     blend_space_.transfer = Transfer_sRGB;
diff --git a/sdm/libs/core/display_pluggable.h b/sdm/libs/core/display_pluggable.h
index e61107b..2e7bd09 100644
--- a/sdm/libs/core/display_pluggable.h
+++ b/sdm/libs/core/display_pluggable.h
@@ -70,6 +70,7 @@
   virtual void HwRecovery(const HWRecoveryEvent sdm_event_code);
 
   void UpdateColorModes();
+  void InitializeColorModesFromColorspace();
 
  private:
   DisplayError GetOverrideConfig(uint32_t *mode_index);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index ead4586..617145f 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -792,7 +792,7 @@
       interface_str_ = "Virtual";
       break;
     case DRM_MODE_CONNECTOR_DisplayPort:
-      // TODO(user): Add when available
+      hw_panel_info_.port = kPortDP;
       interface_str_ = "DisplayPort";
       break;
   }
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 4e76872..a1a2fff 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -70,6 +70,7 @@
 using sde_drm::DRMOps;
 using sde_drm::DRMTopology;
 using sde_drm::DRMPowerMode;
+using sde_drm::DRMColorspace;
 
 namespace sdm {
 
@@ -223,6 +224,7 @@
   hw_panel_info_.hdr_plus_enabled = connector_info_.ext_hdr_prop.hdr_plus_supported;
   hw_panel_info_.hdr_metadata_type_one = connector_info_.ext_hdr_prop.hdr_metadata_type_one;
   hw_panel_info_.hdr_eotf = connector_info_.ext_hdr_prop.hdr_eotf;
+  hw_panel_info_.supported_colorspaces = connector_info_.supported_colorspaces;
 
   // Convert the raw luminance values from driver to Candela per meter^2 unit.
   float max_luminance = FLOAT(connector_info_.ext_hdr_prop.hdr_max_luminance);
@@ -279,6 +281,23 @@
   const MasteringDisplay &mastering_display = layer_buffer->color_metadata.masteringDisplayInfo;
   const ContentLightLevel &light_level = layer_buffer->color_metadata.contentLightLevel;
   const Primaries &primaries = mastering_display.primaries;
+  // Set colorspace on external displays.
+  if (hw_panel_info_.port == kPortDP && hw_panel_info_.supported_colorspaces) {
+    LayerStack *stack = hw_layers->info.stack;
+    sde_drm::DRMColorspace colorspace = sde_drm::DRMColorspace::DEFAULT;
+    if (stack->blend_cs.primaries == ColorPrimaries_DCIP3 &&
+        stack->blend_cs.transfer == Transfer_sRGB) {
+      colorspace = sde_drm::DRMColorspace::DCI_P3_RGB_D65;
+    /* In case of BT2020_YCC, BT2020_RGB is not set based on the layer format. We set it based on
+       the final output of display port controller. Here even though the layer as YUV , it will be
+       color converted to RGB using SSPP and the format going out of DP will be RGB. Hence we
+       should set BT2020_RGB. */
+    } else if (stack->blend_cs.primaries == ColorPrimaries_BT2020) {
+      colorspace = sde_drm::DRMColorspace::BT2020_RGB;
+    }
+    DLOGV_IF(kTagDriverConfig, "Set colorspace = %d", colorspace);
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_COLORSPACE, token_.conn_id, colorspace);
+  }
 
   if (hdr_op == HWHDRLayerInfo::kSet && hdr_layer_info.hdr_layers.size() == 1) {
     // Reset reset_hdr_flag_ to handle where there are two consecutive HDR video playbacks with not