/*
* Copyright (c) 2019-2020, 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.
*/

#include <stdint.h>
#include <stdlib.h>
#include <drm.h>
#include <drm/sde_drm.h>
#include <drm_logger.h>
#include <drm/drm_fourcc.h>
#include <string.h>

#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <utility>

#include "drm_utils.h"
#include "drm_crtc.h"
#include "drm_property.h"

namespace sde_drm {

using std::string;
using std::stringstream;
using std::unique_ptr;
using std::mutex;
using std::lock_guard;
using std::pair;
using std::vector;

// CRTC Security Levels
static uint8_t SECURE_NON_SECURE = 0;
static uint8_t SECURE_ONLY = 1;

// CWB Capture Modes
static uint8_t CAPTURE_MIXER_OUT = 0;
static uint8_t CAPTURE_DSPP_OUT = 1;

// Idle PC states
static uint8_t IDLE_PC_STATE_NONE = 0;
static uint8_t IDLE_PC_STATE_ENABLE = 1;
static uint8_t IDLE_PC_STATE_DISABLE = 2;

static void PopulateSecurityLevels(drmModePropertyRes *prop) {
  static bool security_levels_populated = false;
  if (!security_levels_populated) {
    for (auto i = 0; i < prop->count_enums; i++) {
      string enum_name(prop->enums[i].name);
      if (enum_name == "sec_and_non_sec") {
        SECURE_NON_SECURE = prop->enums[i].value;
      } else if (enum_name == "sec_only") {
        SECURE_ONLY = prop->enums[i].value;
      }
    }
    security_levels_populated = true;
  }
}

static void PopulateCWbCaptureModes(drmModePropertyRes *prop) {
  static bool capture_modes_populated = false;
  if (!capture_modes_populated) {
    for (auto i = 0; i < prop->count_enums; i++) {
      string enum_name(prop->enums[i].name);
      if (enum_name == "capture_mixer_out") {
        CAPTURE_MIXER_OUT = prop->enums[i].value;
      } else if (enum_name == "capture_pp_out") {
        CAPTURE_DSPP_OUT = prop->enums[i].value;
      }
    }
    capture_modes_populated = true;
  }
}

static void PopulateIdlePCStates(drmModePropertyRes *prop) {
  static bool idle_pc_state_populated = false;
  if (!idle_pc_state_populated) {
    for (auto i = 0; i < prop->count_enums; i++) {
      string enum_name(prop->enums[i].name);
      if (enum_name == "idle_pc_none") {
        IDLE_PC_STATE_NONE = prop->enums[i].value;
      } else if (enum_name == "idle_pc_enable") {
        IDLE_PC_STATE_ENABLE = prop->enums[i].value;
      } else if (enum_name == "idle_pc_disable") {
        IDLE_PC_STATE_DISABLE = prop->enums[i].value;
      }
    }
    idle_pc_state_populated = true;
  }
}

#define __CLASS__ "DRMCrtcManager"

void DRMCrtcManager::Init(drmModeRes *resource) {
  for (int i = 0; i < resource->count_crtcs; i++) {
    unique_ptr<DRMCrtc> crtc(new DRMCrtc(fd_, i));
    drmModeCrtc *libdrm_crtc = drmModeGetCrtc(fd_, resource->crtcs[i]);
    if (libdrm_crtc) {
      crtc->InitAndParse(libdrm_crtc);
      object_pool_[resource->crtcs[i]] = std::move(crtc);
    } else {
      DRM_LOGE("Critical error: drmModeGetCrtc() failed for crtc %d.", resource->crtcs[i]);
    }
  }
}

void DRMCrtcManager::Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req,
                             va_list args) {
  lock_guard<mutex> lock(lock_);
  auto crtc = GetObject(obj_id);
  if (crtc == nullptr) {
    DRM_LOGE("Invalid crtc id %d", obj_id);
    return;
  }

  if (code == DRMOps::CRTC_SET_DEST_SCALER_CONFIG) {
    if (crtc->ConfigureScalerLUT(dir_lut_blob_id_, cir_lut_blob_id_,
                                 sep_lut_blob_id_)) {
      DRM_LOGD("CRTC %d: Configuring scaler LUTs", obj_id);
    }
  }

  crtc->Perform(code, req, args);
}

void DRMCrtcManager::SetScalerLUT(const DRMScalerLUTInfo &lut_info) {
  // qseed3lite lut is hardcoded in HW. No need to program from sw.
  DRMCrtcInfo info;
  object_pool_.begin()->second->GetInfo(&info);
  if (info.qseed_version == QSEEDVersion::V3LITE) {
    return;
  }

  if (lut_info.dir_lut_size) {
    drmModeCreatePropertyBlob(fd_, reinterpret_cast<void *>(lut_info.dir_lut),
                              lut_info.dir_lut_size, &dir_lut_blob_id_);
  }
  if (lut_info.cir_lut_size) {
    drmModeCreatePropertyBlob(fd_, reinterpret_cast<void *>(lut_info.cir_lut),
                              lut_info.cir_lut_size, &cir_lut_blob_id_);
  }
  if (lut_info.sep_lut_size) {
    drmModeCreatePropertyBlob(fd_, reinterpret_cast<void *>(lut_info.sep_lut),
                              lut_info.sep_lut_size, &sep_lut_blob_id_);
  }
}

void DRMCrtcManager::UnsetScalerLUT() {
  if (dir_lut_blob_id_) {
    drmModeDestroyPropertyBlob(fd_, dir_lut_blob_id_);
    dir_lut_blob_id_ = 0;
  }
  if (cir_lut_blob_id_) {
    drmModeDestroyPropertyBlob(fd_, cir_lut_blob_id_);
    cir_lut_blob_id_ = 0;
  }
  if (sep_lut_blob_id_) {
    drmModeDestroyPropertyBlob(fd_, sep_lut_blob_id_);
    sep_lut_blob_id_ = 0;
  }
}

int DRMCrtcManager::GetCrtcInfo(uint32_t crtc_id, DRMCrtcInfo *info) {
  if (crtc_id == 0) {
    object_pool_.begin()->second->GetInfo(info);
  } else {
    auto crtc = GetObject(crtc_id);
    if (crtc == nullptr)  {
      DRM_LOGE("Invalid crtc id %d", crtc_id);
      return -ENODEV;
    } else {
      crtc->GetInfo(info);
    }
  }

  return 0;
}

void DRMCrtcManager::GetPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info) {
  auto crtc = GetObject(crtc_id);
  if (crtc == nullptr) {
    DRM_LOGE("Invalid crtc id %d", crtc_id);
    return;
  }

  crtc->GetPPInfo(info);
}

int DRMCrtcManager::Reserve(const std::set<uint32_t> &possible_crtc_indices,
                             DRMDisplayToken *token) {
  for (auto &item : object_pool_) {
    if (item.second->GetStatus() == DRMStatus::FREE) {
      if (possible_crtc_indices.find(item.second->GetIndex()) != possible_crtc_indices.end()) {
        item.second->Lock();
        token->crtc_id = item.first;
        token->crtc_index = item.second->GetIndex();
        return 0;
      }
    }
  }

  return -ENODEV;
}

void DRMCrtcManager::Free(DRMDisplayToken *token) {
  lock_guard<mutex> lock(lock_);
  object_pool_.at(token->crtc_id)->Unlock();
  token->crtc_id = 0;
  token->crtc_index = 0;
}

// ==============================================================================================//

#undef __CLASS__
#define __CLASS__ "DRMCrtc"

DRMCrtc::DRMCrtc(int fd, uint32_t crtc_index)
    : DRMObject(prop_mgr_), fd_(fd), crtc_index_(crtc_index) {}

DRMCrtc::~DRMCrtc() {
  if (drm_crtc_) {
    drmModeFreeCrtc(drm_crtc_);
  }
}

void DRMCrtc::ParseProperties() {
  drmModeObjectProperties *props =
    drmModeObjectGetProperties(fd_, drm_crtc_->crtc_id, DRM_MODE_OBJECT_CRTC);
  if (!props || !props->props || !props->prop_values) {
    drmModeFreeObjectProperties(props);
    return;
  }

  for (uint32_t j = 0; j < props->count_props; j++) {
    drmModePropertyRes *info = drmModeGetProperty(fd_, props->props[j]);
    if (!info) {
      continue;
    }

    string property_name(info->name);
    DRMProperty prop_enum = prop_mgr_.GetPropertyEnum(property_name);
    if (prop_enum == DRMProperty::INVALID) {
      DRM_LOGD("DRMProperty %s missing from global property mapping", info->name);
      drmModeFreeProperty(info);
      continue;
    }

    if (prop_enum == DRMProperty::SECURITY_LEVEL) {
      PopulateSecurityLevels(info);
    }

    if (prop_enum == DRMProperty::CAPTURE_MODE) {
      crtc_info_.concurrent_writeback = true;
      PopulateCWbCaptureModes(info);
    }

    if (prop_enum == DRMProperty::IDLE_PC_STATE) {
      PopulateIdlePCStates(info);
    }

    prop_mgr_.SetPropertyId(prop_enum, info->prop_id);
    if (prop_enum == DRMProperty::CAPABILITIES) {
      ParseCapabilities(props->prop_values[j]);
    }
    drmModeFreeProperty(info);
  }

  drmModeFreeObjectProperties(props);
}

void DRMCrtc::ParseCapabilities(uint64_t blob_id) {
  drmModePropertyBlobRes *blob = drmModeGetPropertyBlob(fd_, blob_id);
  if (!blob) {
    return;
  }

  char *fmt_str = new char[blob->length + 1];
  memcpy (fmt_str, blob->data, blob->length);
  fmt_str[blob->length] = '\0';
  stringstream stream(fmt_str);
  DRM_LOGI("stream str %s len %zu blob str %s len %d", stream.str().c_str(), stream.str().length(),
           blob->data, blob->length);
  string line = {};
  string max_blendstages = "max_blendstages=";
  string qseed_type = "qseed_type=";
  string has_src_split = "has_src_split=";
  string sdma_rev = "smart_dma_rev=";
  string core_ib_ff = "core_ib_ff=";
  string dest_scale_prefill_lines = "dest_scale_prefill_lines=";
  string undersized_prefill_lines = "undersized_prefill_lines=";
  string macrotile_prefill_lines = "macrotile_prefill_lines=";
  string yuv_nv12_prefill_lines = "yuv_nv12_prefill_lines=";
  string linear_prefill_lines = "linear_prefill_lines=";
  string downscaling_prefill_lines = "downscaling_prefill_lines=";
  string xtra_prefill_lines = "xtra_prefill_lines=";
  string amortizable_threshold = "amortizable_threshold=";
  string max_bandwidth_low = "max_bandwidth_low=";
  string max_bandwidth_high = "max_bandwidth_high=";
  string max_mdp_clk = "max_mdp_clk=";
  string core_clk_ff = "core_clk_ff=";
  string comp_ratio_rt = "comp_ratio_rt=";
  string comp_ratio_nrt = "comp_ratio_nrt=";
  string hw_version = "hw_version=";
  string solidfill_stages = "dim_layer_v1_max_layers=";
  string has_hdr = "has_hdr=";
  string has_micro_idle = "has_uidle=";
  string min_prefill_lines = "min_prefill_lines=";
  string num_mnocports = "num_mnoc_ports=";
  string mnoc_bus_width = "axi_bus_width=";

  crtc_info_.max_solidfill_stages = 0;  // default _
  string dest_scaler_count = "dest_scaler_count=";
  string max_dest_scale_up = "max_dest_scale_up=";
  string max_dest_scaler_input_width = "max_dest_scaler_input_width=";
  string max_dest_scaler_output_width = "max_dest_scaler_output_width=";
  string sec_ui_blendstage = "sec_ui_blendstage=";
  string vig = "vig=";
  string dma = "dma=";
  string scaling = "scale=";
  string rotation = "inline_rot=";
  string linewidth_constraints = "sspp_linewidth_usecases=";
  string linewidth_values = "sspp_linewidth_values=";
  string limit_constraint = "limit_usecase=";
  string limit_value = "limit_value=";
  string use_baselayer_for_stage = "use_baselayer_for_stage=";
  string ubwc_version = "UBWC version=";

  while (std::getline(stream, line)) {
    if (line.find(max_blendstages) != string::npos) {
      crtc_info_.max_blend_stages = std::stoi(string(line, max_blendstages.length()));
    } else if (line.find(qseed_type) != string::npos) {
      if (string(line, qseed_type.length()) == "qseed2") {
        crtc_info_.qseed_version = QSEEDVersion::V2;
      } else if (string(line, qseed_type.length()) == "qseed3") {
        crtc_info_.qseed_version = QSEEDVersion::V3;
      } else if (string(line, qseed_type.length()) == "qseed3lite") {
        crtc_info_.qseed_version = QSEEDVersion::V3LITE;
      }
    } else if (line.find(has_src_split) != string::npos) {
      crtc_info_.has_src_split = std::stoi(string(line, has_src_split.length()));
    } else if (line.find(sdma_rev) != string::npos) {
      if (string(line, sdma_rev.length()) == "smart_dma_v2p5")
        crtc_info_.smart_dma_rev = SmartDMARevision::V2p5;
      else if (string(line, sdma_rev.length()) == "smart_dma_v2")
        crtc_info_.smart_dma_rev = SmartDMARevision::V2;
      else if (string(line, sdma_rev.length()) == "smart_dma_v1")
        crtc_info_.smart_dma_rev = SmartDMARevision::V1;
    } else if (line.find(core_ib_ff) != string::npos) {
      crtc_info_.ib_fudge_factor = std::stof(string(line, core_ib_ff.length()));
    } else if (line.find(dest_scale_prefill_lines) != string::npos) {
      crtc_info_.dest_scale_prefill_lines =
        std::stoi(string(line, dest_scale_prefill_lines.length()));
    } else if (line.find(undersized_prefill_lines) != string::npos) {
      crtc_info_.undersized_prefill_lines =
        std::stoi(string(line, undersized_prefill_lines.length()));
    } else if (line.find(macrotile_prefill_lines) != string::npos) {
      crtc_info_.macrotile_prefill_lines =
        std::stoi(string(line, macrotile_prefill_lines.length()));
    } else if (line.find(yuv_nv12_prefill_lines) != string::npos) {
      crtc_info_.nv12_prefill_lines = std::stoi(string(line, yuv_nv12_prefill_lines.length()));
    } else if (line.find(linear_prefill_lines) != string::npos) {
      crtc_info_.linear_prefill_lines = std::stoi(string(line, linear_prefill_lines.length()));
    } else if (line.find(downscaling_prefill_lines) != string::npos) {
      crtc_info_.downscale_prefill_lines =
        std::stoi(string(line, downscaling_prefill_lines.length()));
    } else if (line.find(xtra_prefill_lines) != string::npos) {
      crtc_info_.extra_prefill_lines = std::stoi(string(line, xtra_prefill_lines.length()));
    } else if (line.find(amortizable_threshold) != string::npos) {
      crtc_info_.amortized_threshold = std::stoi(string(line, amortizable_threshold.length()));
    } else if (line.find(max_bandwidth_low) != string::npos) {
      crtc_info_.max_bandwidth_low = std::stoull(string(line, max_bandwidth_low.length()));
    } else if (line.find(max_bandwidth_high) != string::npos) {
      crtc_info_.max_bandwidth_high = std::stoull(string(line, max_bandwidth_high.length()));
    } else if (line.find(max_mdp_clk) != string::npos) {
      crtc_info_.max_sde_clk = std::stoi(string(line, max_mdp_clk.length()));
    } else if (line.find(core_clk_ff) != string::npos) {
      crtc_info_.clk_fudge_factor = std::stof(string(line, core_clk_ff.length()));
    } else if (line.find(comp_ratio_rt) != string::npos) {
      ParseCompRatio(line.substr(comp_ratio_rt.length()), true);
    } else if (line.find(comp_ratio_nrt) != string::npos) {
      ParseCompRatio(line.substr(comp_ratio_nrt.length()), false);
    } else if (line.find(hw_version) != string::npos) {
      crtc_info_.hw_version = std::stoi(string(line, hw_version.length()));
    } else if (line.find(solidfill_stages) != string::npos) {
      crtc_info_.max_solidfill_stages =  std::stoi(string(line, solidfill_stages.length()));
    } else if (line.find(dest_scaler_count) != string::npos) {
      crtc_info_.dest_scaler_count = std::stoi(string(line, dest_scaler_count.length()));
    } else if (line.find(max_dest_scale_up) != string::npos) {
      crtc_info_.max_dest_scale_up = std::stoi(string(line, max_dest_scale_up.length()));
    } else if (line.find(max_dest_scaler_input_width) != string::npos) {
      crtc_info_.max_dest_scaler_input_width =
                          std::stoi(string(line, max_dest_scaler_input_width.length()));
    } else if (line.find(max_dest_scaler_output_width) != string::npos) {
      crtc_info_.max_dest_scaler_output_width =
                         std::stoi(string(line, max_dest_scaler_output_width.length()));
    } else if (line.find(has_hdr) != string::npos) {
      crtc_info_.has_hdr = std::stoi(string(line, has_hdr.length()));
    } else if (line.find(min_prefill_lines) != string::npos) {
      crtc_info_.min_prefill_lines = std::stoi(string(line, min_prefill_lines.length()));
    } else if (line.find(sec_ui_blendstage) != string::npos) {
      crtc_info_.secure_disp_blend_stage = std::stoi(string(line, (sec_ui_blendstage).length()));
    } else if (line.find(num_mnocports) != string::npos) {
      crtc_info_.num_mnocports = std::stoi(string(line, num_mnocports.length()));
    } else if (line.find(mnoc_bus_width) != string::npos) {
      crtc_info_.mnoc_bus_width = std::stoi(string(line, mnoc_bus_width.length()));
    } else if (line.find(linewidth_constraints) != string::npos) {
      crtc_info_.line_width_constraints_count =
                            std::stoi(string(line, (linewidth_constraints).length()));
    } else if (line.find(vig) != string::npos) {
      crtc_info_.vig_limit_index = std::stoi(string(line, (vig).length()));
    } else if (line.find(dma) != string::npos) {
      crtc_info_.dma_limit_index = std::stoi(string(line, (dma).length()));
    } else if (line.find(scaling) != string::npos) {
      crtc_info_.scaling_limit_index = std::stoi(string(line, (scaling).length()));
    } else if (line.find(rotation) != string::npos) {
      crtc_info_.rotation_limit_index = std::stoi(string(line, (rotation).length()));
    } else if (line.find(linewidth_values) != string::npos) {
      uint32_t num_linewidth_values = std::stoi(string(line, (linewidth_values).length()));
      vector< pair <uint32_t,uint32_t> > constraint_vector;
      for (uint32_t i = 0; i < num_linewidth_values; i++) {
        uint32_t constraint = 0;
        uint32_t value  = 0;
        std::getline(stream, line);
        if (line.find(limit_constraint) != string::npos) {
          constraint = std::stoi(string(line, (limit_constraint).length()));
        }
        std::getline(stream, line);
        if (line.find(limit_value) != string::npos) {
          value = std::stoi(string(line, (limit_value).length()));
        }
        if (value) {
          constraint_vector.push_back(std::make_pair(constraint,value));
        }
      }
      crtc_info_.line_width_limits = std::move(constraint_vector);
    } else if (line.find(has_micro_idle) != string::npos) {
      crtc_info_.has_micro_idle = std::stoi(string(line, (has_micro_idle).length()));
    } else if (line.find(use_baselayer_for_stage) != string::npos) {
      crtc_info_.use_baselayer_for_stage =
                         std::stoi(string(line, use_baselayer_for_stage.length()));
    } else if (line.find(ubwc_version) != string::npos) {
      crtc_info_.ubwc_version = (std::stoi(string(line, ubwc_version.length()))) >> 28;
    }
  }
  drmModeFreePropertyBlob(blob);
}

void DRMCrtc::ParseCompRatio(string line, bool real_time) {
  CompRatioMap &comp_ratio_map =
    real_time ? crtc_info_.comp_ratio_rt_map : crtc_info_.comp_ratio_nrt_map;
  std::vector<string> format_cr_list;

  Tokenize(line, &format_cr_list, ' ');

  for (uint32_t i = 0; i < format_cr_list.size(); i++) {
    std::vector<string> format_cr;
    Tokenize(format_cr_list.at(i), &format_cr, '/');
    std::string format = format_cr.at(0);
    uint64_t vendor_code = stoi(format_cr.at(1));
    uint64_t fmt_modifier = stoi(format_cr.at(2));
    float comp_ratio = std::stof(format_cr.at(3));
    uint64_t modifier = 0;

    if (vendor_code == DRM_FORMAT_MOD_VENDOR_QCOM) {
      // Macro from drm_fourcc.h to form modifier
      modifier = fourcc_mod_code(QCOM, fmt_modifier);
    }

    std::pair<uint32_t, uint64_t> drm_format =
      std::make_pair(fourcc_code(format[0], format[1], format[2], format[3]), modifier);
    comp_ratio_map.insert(std::make_pair(drm_format, comp_ratio));
  }
}

void DRMCrtc::GetInfo(DRMCrtcInfo *info) {
  *info = crtc_info_;
}

void DRMCrtc::Lock() {
  status_ = DRMStatus::BUSY;
}

void DRMCrtc::Unlock() {
  if (mode_blob_id_) {
    drmModeDestroyPropertyBlob(fd_, mode_blob_id_);
    mode_blob_id_ = 0;
  }

  ClearProperties();
  status_ = DRMStatus::FREE;
}

void DRMCrtc::SetModeBlobID(uint64_t blob_id) {
  if (mode_blob_id_) {
    drmModeDestroyPropertyBlob(fd_, mode_blob_id_);
  }

  mode_blob_id_ = blob_id;
}

void DRMCrtc::InitAndParse(drmModeCrtc *crtc) {
  drm_crtc_ = crtc;
  ParseProperties();
  pp_mgr_ = std::unique_ptr<DRMPPManager>(new DRMPPManager(fd_));
  pp_mgr_->Init(prop_mgr_, DRM_MODE_OBJECT_CRTC);
}

void DRMCrtc::Perform(DRMOps code, drmModeAtomicReq *req, va_list args) {
  uint32_t obj_id = drm_crtc_->crtc_id;

  switch (code) {
    case DRMOps::CRTC_SET_MODE: {
      drmModeModeInfo *mode = va_arg(args, drmModeModeInfo *);
      uint32_t blob_id = 0;

      if (mode) {
        if (drmModeCreatePropertyBlob(fd_, (const void *)mode, sizeof(drmModeModeInfo), &blob_id)) {
          DRM_LOGE("drmModeCreatePropertyBlob failed for CRTC_SET_MODE, crtc %d", obj_id);
          return;
        }
      }

      AddProperty(DRMProperty::MODE_ID, blob_id, true);
      SetModeBlobID(blob_id);
      DRM_LOGD("CRTC %d: Set mode %s", obj_id, mode ? mode->name : "null");
    } break;

    case DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET: {
      uint32_t offset = va_arg(args, uint32_t);
      AddProperty(DRMProperty::OUTPUT_FENCE_OFFSET, offset);
    }; break;

    case DRMOps::CRTC_SET_CORE_CLK: {
      uint32_t core_clk = va_arg(args, uint32_t);
      AddProperty(DRMProperty::CORE_CLK, core_clk);
    }; break;

    case DRMOps::CRTC_SET_CORE_AB: {
      uint64_t core_ab = va_arg(args, uint64_t);
      AddProperty(DRMProperty::CORE_AB, core_ab);
    }; break;

    case DRMOps::CRTC_SET_CORE_IB: {
      uint64_t core_ib = va_arg(args, uint64_t);
      AddProperty(DRMProperty::CORE_IB, core_ib);
    }; break;

    case DRMOps::CRTC_SET_LLCC_AB: {
      uint64_t llcc_ab = va_arg(args, uint64_t);
      AddProperty(DRMProperty::LLCC_AB, llcc_ab);
    }; break;

    case DRMOps::CRTC_SET_LLCC_IB: {
      uint64_t llcc_ib = va_arg(args, uint64_t);
      AddProperty(DRMProperty::LLCC_IB, llcc_ib);
    }; break;

    case DRMOps::CRTC_SET_DRAM_AB: {
      uint64_t dram_ab = va_arg(args, uint64_t);
      AddProperty(DRMProperty::DRAM_AB, dram_ab);
    }; break;

    case DRMOps::CRTC_SET_DRAM_IB: {
      uint64_t dram_ib = va_arg(args, uint64_t);
      AddProperty(DRMProperty::DRAM_IB, dram_ib);
    }; break;

    case DRMOps::CRTC_SET_ROT_PREFILL_BW: {
      uint64_t rot_bw = va_arg(args, uint64_t);
      AddProperty(DRMProperty::ROT_PREFILL_BW, rot_bw);
    }; break;

    case DRMOps::CRTC_SET_ROT_CLK: {
      uint32_t rot_clk = va_arg(args, uint32_t);
      AddProperty(DRMProperty::ROT_CLK, rot_clk);
    }; break;

    case DRMOps::CRTC_GET_RELEASE_FENCE: {
      int64_t *fence = va_arg(args, int64_t *);
      *fence = -1;
      AddProperty(DRMProperty::OUTPUT_FENCE,
                  reinterpret_cast<uint64_t>(fence), true);
    } break;

    case DRMOps::CRTC_SET_ACTIVE: {
      uint32_t enable = va_arg(args, uint32_t);
      AddProperty(DRMProperty::ACTIVE, enable);
      DRM_LOGD("CRTC %d: Set active %d", obj_id, enable);
      if (enable == 0) {
        ClearVotesCache();
      }
    } break;

    case DRMOps::CRTC_SET_POST_PROC: {
      DRMPPFeatureInfo *data = va_arg(args, DRMPPFeatureInfo*);
      if (data)
        pp_mgr_->SetPPFeature(req, obj_id, *data);
      DRM_LOGD("CRTC %d: Set post proc", obj_id);
    } break;

    case DRMOps::CRTC_SET_ROI: {
      uint32_t num_roi = va_arg(args, uint32_t);
      DRMRect *crtc_rois = va_arg(args, DRMRect*);
      SetROI(num_roi, crtc_rois);
    } break;

    case DRMOps::CRTC_SET_SECURITY_LEVEL: {
      int security_level = va_arg(args, int);
      uint32_t crtc_security_level = SECURE_NON_SECURE;
      if (security_level == (int)DRMSecurityLevel::SECURE_ONLY) {
        crtc_security_level = SECURE_ONLY;
      }
      AddProperty(DRMProperty::SECURITY_LEVEL, crtc_security_level);
    } break;

    case DRMOps::CRTC_SET_SOLIDFILL_STAGES: {
      uint64_t dim_stages = va_arg(args, uint64_t);
      const std::vector<DRMSolidfillStage> *solid_fills =
        reinterpret_cast <std::vector <DRMSolidfillStage> *> (dim_stages);
      SetSolidfillStages(solid_fills);
    } break;

    case DRMOps::CRTC_SET_IDLE_TIMEOUT: {
      uint32_t timeout_ms = va_arg(args, uint32_t);
      AddProperty(DRMProperty::IDLE_TIME, timeout_ms);
    } break;

    case DRMOps::CRTC_SET_DEST_SCALER_CONFIG: {
      uint64_t dest_scaler = va_arg(args, uint64_t);
      static sde_drm_dest_scaler_data dest_scale_copy = {};
      sde_drm_dest_scaler_data *ds_data = reinterpret_cast<sde_drm_dest_scaler_data *>
                                           (dest_scaler);
      dest_scale_copy = *ds_data;
      AddProperty(DRMProperty::DEST_SCALER,
                  reinterpret_cast<uint64_t>(&dest_scale_copy), true);
    } break;

    case DRMOps::CRTC_SET_CAPTURE_MODE: {
      int capture_mode = va_arg(args, int);
      uint32_t cwb_capture_mode = CAPTURE_MIXER_OUT;
      if (capture_mode == (int)DRMCWbCaptureMode::DSPP_OUT) {
        cwb_capture_mode = CAPTURE_DSPP_OUT;
      }
      AddProperty(DRMProperty::CAPTURE_MODE, cwb_capture_mode);
    } break;

    case DRMOps::CRTC_SET_IDLE_PC_STATE: {
      if (!prop_mgr_.IsPropertyAvailable(DRMProperty::IDLE_PC_STATE)) {
        return;
      }
      int drm_idle_pc_state = va_arg(args, int);
      uint32_t idle_pc_state = IDLE_PC_STATE_NONE;
      switch (drm_idle_pc_state) {
        case static_cast<int>(DRMIdlePCState::ENABLE):
          idle_pc_state = IDLE_PC_STATE_ENABLE;
          break;
        case static_cast<int>(DRMIdlePCState::DISABLE):
          idle_pc_state = IDLE_PC_STATE_DISABLE;
          break;
        default:
          idle_pc_state = IDLE_PC_STATE_NONE;
          break;
      }
      AddProperty(DRMProperty::IDLE_PC_STATE, idle_pc_state);
      DRM_LOGD("CRTC %d: Set idle_pc_state %d", obj_id, idle_pc_state);
    }; break;

    default:
      DRM_LOGE("Invalid opcode %d to set the property on crtc %d", code, obj_id);
      break;
  }
}

void DRMCrtc::SetROI(uint32_t num_roi, DRMRect *crtc_rois) {
#ifdef SDE_MAX_ROI_V1
  if (num_roi > SDE_MAX_ROI_V1 || !prop_mgr_.IsPropertyAvailable(DRMProperty::ROI_V1)) {
    return;
  }
  if (!num_roi || !crtc_rois) {
    AddProperty(DRMProperty::ROI_V1, 0, true);
    DRM_LOGD("CRTC ROI is set to NULL to indicate full frame update");
    return;
  }
  memset(&roi_v1_, 0, sizeof(roi_v1_));
  roi_v1_.num_rects = num_roi;

  for (uint32_t i = 0; i < num_roi; i++) {
    roi_v1_.roi[i].x1 = crtc_rois[i].left;
    roi_v1_.roi[i].x2 = crtc_rois[i].right;
    roi_v1_.roi[i].y1 = crtc_rois[i].top;
    roi_v1_.roi[i].y2 = crtc_rois[i].bottom;
    DRM_LOGD("CRTC %d, ROI[l,t,b,r][%d %d %d %d]", GetObjectId(),
             roi_v1_.roi[i].x1, roi_v1_.roi[i].y1, roi_v1_.roi[i].x2, roi_v1_.roi[i].y2);
  }

  AddProperty(DRMProperty::ROI_V1, reinterpret_cast<uint64_t>(&roi_v1_), true);
#endif
}

void DRMCrtc::SetSolidfillStages(const std::vector<DRMSolidfillStage> *solid_fills) {
#if defined  SDE_MAX_DIM_LAYERS
  memset(&drm_dim_layer_v1_, 0, sizeof(drm_dim_layer_v1_));
  uint32_t shift;

  drm_dim_layer_v1_.num_layers = static_cast<uint32_t> (solid_fills->size());
  for (uint32_t i = 0; i < solid_fills->size(); i++) {
    const DRMSolidfillStage &sf = solid_fills->at(i);
    float plane_alpha = (sf.plane_alpha / 255.0f);
    drm_dim_layer_v1_.layer_cfg[i].stage = sf.z_order;
    drm_dim_layer_v1_.layer_cfg[i].rect.x1 = (uint16_t)sf.bounding_rect.left;
    drm_dim_layer_v1_.layer_cfg[i].rect.y1 = (uint16_t)sf.bounding_rect.top;
    drm_dim_layer_v1_.layer_cfg[i].rect.x2 = (uint16_t)sf.bounding_rect.right;
    drm_dim_layer_v1_.layer_cfg[i].rect.y2 = (uint16_t)sf.bounding_rect.bottom;
    drm_dim_layer_v1_.layer_cfg[i].flags =
      sf.is_exclusion_rect ? SDE_DRM_DIM_LAYER_EXCLUSIVE : SDE_DRM_DIM_LAYER_INCLUSIVE;

    // @sde_mdss_color: expects in [g b r a] order where as till now solidfill is in [a r g b].
    // As no support for passing plane alpha, Multiply Alpha color component with plane_alpa.
    shift = kSolidFillHwBitDepth - sf.color_bit_depth;
    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_0 = (sf.green & 0x3FF) << shift;
    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_1 = (sf.blue & 0x3FF) << shift;
    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_2 = (sf.red & 0x3FF) << shift;
    // alpha is 8 bit
    drm_dim_layer_v1_.layer_cfg[i].color_fill.color_3 =
      ((uint32_t)((((sf.alpha & 0xFF)) * plane_alpha)));
  }

  AddProperty(DRMProperty::DIM_STAGES_V1,
              reinterpret_cast<uint64_t> (&drm_dim_layer_v1_), true);
#endif
}

void DRMCrtc::Dump() {
  DRM_LOGE("id: %d\tbuffer_id: %d\tpos:(%d, %d)\tsize:(%dx%d)\n", drm_crtc_->crtc_id,
           drm_crtc_->buffer_id, drm_crtc_->x, drm_crtc_->y, drm_crtc_->width, drm_crtc_->height);
}

bool DRMCrtc::ConfigureScalerLUT(uint32_t dir_lut_blob_id,
                                 uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id) {
  if (is_lut_configured_ && is_lut_validated_) {
    return false;
  }
  if (dir_lut_blob_id) {
    AddProperty(DRMProperty::DS_LUT_ED, dir_lut_blob_id, true);
  }
  if (cir_lut_blob_id) {
    AddProperty(DRMProperty::DS_LUT_CIR, cir_lut_blob_id, true);
  }
  if (sep_lut_blob_id) {
    AddProperty(DRMProperty::DS_LUT_SEP, sep_lut_blob_id, true);
  }
  is_lut_validation_in_progress_ = true;
  return true;
}

void DRMCrtc::PostCommit(bool success) {
  if (success) {
    if (is_lut_validated_) {
      is_lut_configured_ = true;
    }
    CommitProperties();
  }
}

void DRMCrtc::PostValidate() {
  if (is_lut_validation_in_progress_)  {
    is_lut_validated_ = true;
  }
}

void DRMCrtc::ClearVotesCache() {
  RemoveProperty(DRMProperty::CORE_CLK);
  RemoveProperty(DRMProperty::CORE_AB);
  RemoveProperty(DRMProperty::CORE_IB);
  RemoveProperty(DRMProperty::LLCC_AB);
  RemoveProperty(DRMProperty::LLCC_IB);
  RemoveProperty(DRMProperty::DRAM_AB);
  RemoveProperty(DRMProperty::DRAM_IB);
}

}  // namespace sde_drm
