/*
* 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;
  }

  if (!blob->data) {
    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(),
           static_cast<const char *>(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);
  delete[] fmt_str;
}

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
