/*
* 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 <display/drm/sde_drm.h>
#include <drm_logger.h>
#include <drm/drm_fourcc.h>
#include <string.h>

#include <algorithm>
#include <map>
#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::map;
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;

// CRTC Cache States
static uint8_t CACHE_STATE_DISABLED = 0;
static uint8_t CACHE_STATE_ENABLED = 1;

// VM Request states
static uint8_t VM_REQ_STATE_NONE = 0;
static uint8_t VM_REQ_STATE_RELEASE = 1;
static uint8_t VM_REQ_STATE_ACQUIRE = 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;
  }
}

static void PopulateCacheStates(drmModePropertyRes *prop) {
  static bool cache_states_populated = false;
  if (!cache_states_populated) {
    for (auto i = 0; i < prop->count_enums; i++) {
      string enum_name(prop->enums[i].name);
      if (enum_name == "cache_state_disabled") {
        CACHE_STATE_DISABLED = prop->enums[i].value;
      } else if (enum_name == "cache_state_enabled") {
        CACHE_STATE_ENABLED = prop->enums[i].value;
      }
    }
    cache_states_populated = true;
  }
}

static void PopulateVMRequestStates(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 == "vm_req_none") {
        VM_REQ_STATE_NONE = prop->enums[i].value;
      } else if (enum_name == "vm_req_release") {
        VM_REQ_STATE_RELEASE = prop->enums[i].value;
      } else if (enum_name == "vm_req_acquire") {
        VM_REQ_STATE_ACQUIRE = 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);
      crtc_pool_[resource->crtcs[i]] = std::move(crtc);
    } else {
      DRM_LOGE("Critical error: drmModeGetCrtc() failed for crtc %d.", resource->crtcs[i]);
    }
  }
}

void DRMCrtcManager::DumpByID(uint32_t id) {
  crtc_pool_.at(id)->Dump();
}

void DRMCrtcManager::DumpAll() {
  for (auto &crtc : crtc_pool_) {
    crtc.second->Dump();
  }
}

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

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

  it->second->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;
  crtc_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) {
    crtc_pool_.begin()->second->GetInfo(info);
  } else {
    auto iter = crtc_pool_.find(crtc_id);
    if (iter ==  crtc_pool_.end()) {
      DRM_LOGE("Invalid crtc id %d", crtc_id);
      return -ENODEV;
    } else {
      iter->second->GetInfo(info);
    }
  }

  return 0;
}

void DRMCrtcManager::GetPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info) {
  auto it = crtc_pool_.find(crtc_id);
  if (it == crtc_pool_.end()) {
    DRM_LOGE("Invalid crtc id %d", crtc_id);
    return;
  }

  it->second->GetPPInfo(info);
}

int DRMCrtcManager::Reserve(const std::set<uint32_t> &possible_crtc_indices,
                             DRMDisplayToken *token) {
  for (auto &item : crtc_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_);
  crtc_pool_.at(token->crtc_id)->Unlock();
  token->crtc_id = 0;
  token->crtc_index = 0;
}

void DRMCrtcManager::PostValidate(uint32_t crtc_id, bool success) {
  lock_guard<mutex> lock(lock_);
  crtc_pool_.at(crtc_id)->PostValidate(success);
}

void DRMCrtcManager::PostCommit(uint32_t crtc_id, bool success) {
  lock_guard<mutex> lock(lock_);
  crtc_pool_.at(crtc_id)->PostCommit(success);
}

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

#undef __CLASS__
#define __CLASS__ "DRMCrtc"

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);
    }

    if (prop_enum == DRMProperty::CACHE_STATE) {
      PopulateCacheStates(info);
    }

    if (prop_enum == DRMProperty::VM_REQ_STATE) {
      PopulateVMRequestStates(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 %d 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=";
  string spr = "spr=";

  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;
    } else if (line.find(spr) != string::npos) {
      crtc_info_.has_spr = std::stoi(string(line, spr.length())) == -1 ? false: true;
    }
  }
  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;
  }

  tmp_prop_val_map_.clear();
  committed_prop_val_map_.clear();
  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 prop_id = prop_mgr_.GetPropertyId(DRMProperty::MODE_ID);
      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(req, obj_id, prop_id, blob_id, true /* cache */, tmp_prop_val_map_);
      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(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::OUTPUT_FENCE_OFFSET),
                  offset, true /* cache */, tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_CORE_CLK: {
      uint32_t core_clk = va_arg(args, uint32_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::CORE_CLK), core_clk, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_CORE_AB: {
      uint64_t core_ab = va_arg(args, uint64_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::CORE_AB), core_ab, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_CORE_IB: {
      uint64_t core_ib = va_arg(args, uint64_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::CORE_IB), core_ib, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_LLCC_AB: {
      uint64_t llcc_ab = va_arg(args, uint64_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::LLCC_AB), llcc_ab, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_LLCC_IB: {
      uint64_t llcc_ib = va_arg(args, uint64_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::LLCC_IB), llcc_ib, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_DRAM_AB: {
      uint64_t dram_ab = va_arg(args, uint64_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::DRAM_AB), dram_ab, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_DRAM_IB: {
      uint64_t dram_ib = va_arg(args, uint64_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::DRAM_IB), dram_ib, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_SET_ROT_PREFILL_BW: {
      uint64_t rot_bw = va_arg(args, uint64_t);
      drmModeAtomicAddProperty(req, obj_id,
                               prop_mgr_.GetPropertyId(DRMProperty::ROT_PREFILL_BW), rot_bw);
    }; break;

    case DRMOps::CRTC_SET_ROT_CLK: {
      uint32_t rot_clk = va_arg(args, uint32_t);
      AddProperty(req, obj_id,
                  prop_mgr_.GetPropertyId(DRMProperty::ROT_CLK), rot_clk, true /* cache */,
                  tmp_prop_val_map_);
    }; break;

    case DRMOps::CRTC_GET_RELEASE_FENCE: {
      int64_t *fence = va_arg(args, int64_t *);
      *fence = -1;
      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::OUTPUT_FENCE);
      AddProperty(req, obj_id, prop_id, reinterpret_cast<uint64_t>(fence), false /* cache */,
                  tmp_prop_val_map_);
    } break;

    case DRMOps::CRTC_SET_ACTIVE: {
      uint32_t enable = va_arg(args, uint32_t);
      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::ACTIVE), enable,
                  true /* cache */, tmp_prop_val_map_);
      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(req, obj_id, 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(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::SECURITY_LEVEL),
                  crtc_security_level, true /* cache */, tmp_prop_val_map_);
    } 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(req, obj_id, solid_fills);
    } break;

    case DRMOps::CRTC_SET_IDLE_TIMEOUT: {
      uint32_t timeout_ms = va_arg(args, uint32_t);
      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::IDLE_TIME),
                  timeout_ms, true /* cache */, tmp_prop_val_map_);
    } break;

    case DRMOps::CRTC_SET_DEST_SCALER_CONFIG: {
      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::DEST_SCALER);
      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(req, obj_id, prop_id,
                  reinterpret_cast<uint64_t>(&dest_scale_copy), false /* cache */,
                  tmp_prop_val_map_);
    } 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;
      }
      uint32_t prop_id = prop_mgr_.GetPropertyId(DRMProperty::CAPTURE_MODE);
      AddProperty(req, obj_id, prop_id, cwb_capture_mode, true /* cache */, tmp_prop_val_map_);
    } 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(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::IDLE_PC_STATE), idle_pc_state,
                  true /* cache */, tmp_prop_val_map_);
      DRM_LOGD("CRTC %d: Set idle_pc_state %d", obj_id, idle_pc_state);
    }; break;

    case DRMOps::CRTC_SET_CACHE_STATE: {
      int cache_state = va_arg(args, int);
      uint32_t crtc_cache_state = CACHE_STATE_DISABLED;
      if (cache_state == (int)DRMCacheState::ENABLED) {
        crtc_cache_state = CACHE_STATE_ENABLED;
      }
      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::CACHE_STATE),
                  crtc_cache_state, false /* cache */, tmp_prop_val_map_);
    } break;

    case DRMOps::CRTC_SET_VM_REQ_STATE: {
      if (!prop_mgr_.IsPropertyAvailable(DRMProperty::VM_REQ_STATE)) {
        return;
      }
      int drm_vm_req_state = va_arg(args, int);
      uint32_t vm_req_state = VM_REQ_STATE_NONE;
      switch (drm_vm_req_state) {
        case static_cast<int>(DRMVMRequestState::RELEASE):
          vm_req_state = VM_REQ_STATE_RELEASE;
          break;
        case static_cast<int>(DRMVMRequestState::ACQUIRE):
          vm_req_state = VM_REQ_STATE_ACQUIRE;
          break;
        default:
          vm_req_state = VM_REQ_STATE_NONE;
          break;
      }
      AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::VM_REQ_STATE), vm_req_state,
                  true /* cache */, tmp_prop_val_map_);
      DRM_LOGD("CRTC %d: Set vm_req_state %d", obj_id, vm_req_state);
    }; break;

    case DRMOps::CRTC_RESET_CACHE: {
      tmp_prop_val_map_.clear();
      committed_prop_val_map_.clear();
    } break;

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

void DRMCrtc::SetROI(drmModeAtomicReq *req, uint32_t obj_id, 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(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::ROI_V1),
                0, false /* cache */, tmp_prop_val_map_);
    DRM_LOGD("CRTC ROI is set to NULL to indicate full frame update");
    return;
  }
  static struct sde_drm_roi_v1 roi_v1 {};
  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]", obj_id,
             roi_v1.roi[i].x1, roi_v1.roi[i].y1, roi_v1.roi[i].x2, roi_v1.roi[i].y2);
  }
  AddProperty(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::ROI_V1),
              reinterpret_cast<uint64_t>(&roi_v1), false /* cache */, tmp_prop_val_map_);
#endif
}

void DRMCrtc::SetSolidfillStages(drmModeAtomicReq *req, uint32_t obj_id,
                                 const std::vector<DRMSolidfillStage> *solid_fills) {
#if defined  SDE_MAX_DIM_LAYERS
  static struct sde_drm_dim_layer_v1  drm_dim_layer_v1 {};
  memset(&drm_dim_layer_v1, 0, sizeof(drm_dim_layer_v1));
  uint32_t shift;

  drm_dim_layer_v1.num_layers = 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;
    DLOGI("obj_id=%u, state=%u, x1=%u, y1=%u, x2=%u, y2=%u, flags=%d",
    obj_id,
    drm_dim_layer_v1.layer_cfg[i].stage,
    drm_dim_layer_v1.layer_cfg[i].rect.x1,
    drm_dim_layer_v1.layer_cfg[i].rect.y1,
    drm_dim_layer_v1.layer_cfg[i].rect.x2,
    drm_dim_layer_v1.layer_cfg[i].rect.y2,
    drm_dim_layer_v1.layer_cfg[i].flags);

    // @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(req, obj_id, prop_mgr_.GetPropertyId(DRMProperty::DIM_STAGES_V1),
              reinterpret_cast<uint64_t> (&drm_dim_layer_v1), false /* cache */,
              tmp_prop_val_map_);
#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(drmModeAtomicReq *req, 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(req, drm_crtc_->crtc_id,
                prop_mgr_.GetPropertyId(DRMProperty::DS_LUT_ED), dir_lut_blob_id,
                false /* cache */, tmp_prop_val_map_);
  }
  if (cir_lut_blob_id) {
    AddProperty(req, drm_crtc_->crtc_id,
                prop_mgr_.GetPropertyId(DRMProperty::DS_LUT_CIR), cir_lut_blob_id,
                false /* cache */, tmp_prop_val_map_);
  }
  if (sep_lut_blob_id) {
    AddProperty(req, drm_crtc_->crtc_id,
                prop_mgr_.GetPropertyId(DRMProperty::DS_LUT_SEP), sep_lut_blob_id,
                false /* cache */, tmp_prop_val_map_);
  }
  is_lut_validation_in_progress_ = true;
  return true;
}

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

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

  tmp_prop_val_map_ = committed_prop_val_map_;
}

void DRMCrtc::ClearVotesCache() {
  // On subsequent SET_ACTIVE 1, commit these to MDP driver and re-add to cache automatically
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::CORE_CLK));
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::CORE_AB));
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::CORE_IB));
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::LLCC_AB));
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::LLCC_IB));
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::DRAM_AB));
  tmp_prop_val_map_.erase(prop_mgr_.GetPropertyId(DRMProperty::DRAM_IB));
}

}  // namespace sde_drm
