/*
* Copyright (c) 2019, 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 <cstring>
#include <errno.h>
#include <drm_logger.h>

#include "libdrm_macros.h"
#include "drm/drm_fourcc.h"
#include "drm_dpps_mgr_imp.h"

#define __CLASS__ "DRMDppsManagerImp"
namespace sde_drm {

static DRMDppsManagerImp dpps_mgr;
static DRMDppsManagerDummyImp dpps_dummy_mgr;

DRMDppsManagerIntf* GetDppsManagerIntf()
{
#if (defined(__ANDROID__))
    return &dpps_mgr;
#else
    return &dpps_dummy_mgr;
#endif
}

DRMDppsManagerImp::~DRMDppsManagerImp() {
  /* clean up the ION buffers for LTM */
  DeInitLtmBuffers();

  conn_id_ = -1;
  crtc_id_ = -1;
  drm_fd_ = -1;
}

int DRMDppsManagerImp::GetDrmResources(drmModeRes* res) {
  int enc_id = -1;
  drmModeConnector *conn = NULL;
  drmModeEncoder *enc = NULL;
  drmModeCrtc *crtc = NULL;

  if (drm_fd_ < 0 ) {
    DRM_LOGE("Invalid drm_fd_ %d", drm_fd_);
    return -EINVAL;
  }

  for (auto i = 0; i < res->count_connectors; i++) {
    conn = drmModeGetConnector(drm_fd_, res->connectors[i]);
    if (conn && conn->connector_type == DRM_MODE_CONNECTOR_DSI &&
        conn->count_modes && conn->connection == DRM_MODE_CONNECTED) {
      DRM_LOGI("Found connector %d", conn->connector_id);
      conn_id_ = conn->connector_id;
      break;
    }
    drmModeFreeConnector(conn);
    conn = NULL;
  }
  if (conn_id_ < 0 || !conn) {
    DRM_LOGE("Cannot find valid connector");
    conn_id_ = -1;
    return -EINVAL;
  }

  for (auto i = 0; i < conn->count_encoders; i++) {
    enc = drmModeGetEncoder(drm_fd_, conn->encoders[i]);
    if (enc && enc->encoder_type == DRM_MODE_ENCODER_DSI) {
      DRM_LOGI("Found encoder %d", enc->encoder_id);
      enc_id = enc->encoder_id;
      break;
    }
    drmModeFreeEncoder(enc);
    enc = NULL;
  }
  if (enc_id < 0 || !enc) {
    DRM_LOGE("Cannot find valid encoder");
    drmModeFreeConnector(conn);
    conn = NULL;
    res = NULL;
    conn_id_ = -1;
    return -EINVAL;
  }

  for (auto i = 0; i < res->count_crtcs; i++) {
    if (enc->possible_crtcs & (1 << i)) {
      crtc = drmModeGetCrtc(drm_fd_, res->crtcs[i]);
      if (crtc) {
        DRM_LOGI("Found crtc %d", crtc->crtc_id);
        crtc_id_ = crtc->crtc_id;
        break;
      }
      drmModeFreeCrtc(crtc);
      crtc = NULL;
    }
  }
  if (crtc_id_ < 0 || !crtc) {
    DRM_LOGE("Cannot find valid crtc");
    drmModeFreeEncoder(enc);
    drmModeFreeConnector(conn);
    enc = NULL;
    conn = NULL;
    conn_id_ = -1;
    crtc_id_ = -1;
    return -EINVAL;
  }
  return 0;
}

int DRMDppsManagerImp::InitCrtcProps() {
  if (drm_fd_ < 0 || crtc_id_ < 0) {
    DRM_LOGE("Invalid drm_fd_ %d or crtc_id_ %d", drm_fd_, crtc_id_);
    return -EINVAL;
  }

  drmModeObjectProperties *props =
    drmModeObjectGetProperties(drm_fd_, crtc_id_, DRM_MODE_OBJECT_CRTC);
  if (!props || !props->props || !props->prop_values) {
    drmModeFreeObjectProperties(props);
    return -EINVAL;
  }

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

    std::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;
    }

    prop_mgr_.SetPropertyId(prop_enum, info->prop_id);
    drmModeFreeProperty(info);
  }

  drmModeFreeObjectProperties(props);
  return 0;
}

int DRMDppsManagerImp::InitConnProps()
{
  if (drm_fd_ < 0 || conn_id_ < 0) {
    DRM_LOGE("Invalid drm_fd_ %d or conn_id_ %d", drm_fd_, conn_id_);
    return -EINVAL;
  }

  drmModeObjectProperties *props =
      drmModeObjectGetProperties(drm_fd_, conn_id_, DRM_MODE_OBJECT_CONNECTOR);
  if (!props || !props->props || !props->prop_values) {
    drmModeFreeObjectProperties(props);
    return -EINVAL;
  }

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

    std::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;
    }

    prop_mgr_.SetPropertyId(prop_enum, info->prop_id);
    drmModeFreeProperty(info);
  }

  drmModeFreeObjectProperties(props);
  return 0;
}

void DRMDppsManagerImp::Init(int fd, drmModeRes* res) {
  int ret = 0;

  if (fd < 0 || !res) {
    DRM_LOGE("Invalid drm fd %d or res %p", fd, res);
    return;
  }

  drm_fd_ = fd;
  ret = GetDrmResources(res);
  if (ret) {
    DRM_LOGE("Failed to get DRM resources %d", ret);
    return;
  } else {
    ret = InitCrtcProps();
    if (ret) {
      DRM_LOGE("Failed to initialize crtc properties %d", ret);
      return;
    }
    ret = InitConnProps();
    if (ret) {
      DRM_LOGE("Failed to initialize conn properties %d", ret);
      return;
    }
  }

  memset(&dpps_feature_, 0, sizeof(dpps_feature_));
  dpps_feature_[kFeatureAd4Mode] = DRMDppsPropInfo {
    (prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_MODE) == 0 ? 0U : 4U) /* version */,
    DRMProperty::SDE_DSPP_AD4_MODE, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_MODE),
    false /* is_event */};
  dpps_feature_[kFeatureAd4Init] = DRMDppsPropInfo {4 /* version */,
    DRMProperty::SDE_DSPP_AD4_INIT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_INIT),
    false /* is_event */};
  dpps_feature_[kFeatureAd4Cfg] = DRMDppsPropInfo { 4 /* version */,
    DRMProperty::SDE_DSPP_AD4_CFG, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_CFG),
    false /* is_event */};
  dpps_feature_[kFeatureAd4Input] = DRMDppsPropInfo {4 /* version */,
    DRMProperty::SDE_DSPP_AD4_INPUT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_INPUT),
    false /* is_event */};
  dpps_feature_[kFeatureAd4Backlight] = DRMDppsPropInfo {4 /* version */,
    DRMProperty::SDE_DSPP_AD4_BACKLIGHT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_BACKLIGHT),
    false /* is_event */};
  dpps_feature_[kFeatureAd4Assertiveness] = DRMDppsPropInfo {4 /* version */,
    DRMProperty::SDE_DSPP_AD4_ASSERTIVENESS, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_ASSERTIVENESS),
    false /* is_event */};
  dpps_feature_[kFeatureAd4Roi] = DRMDppsPropInfo {4 /* version */,
    DRMProperty::SDE_DSPP_AD4_ROI, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_ROI),
    false /* is_event */};
  dpps_feature_[kFeatureAd4ManualStrength] = DRMDppsPropInfo {4 /* version */,
    DRMProperty::SDE_DSPP_AD4_STRENGTH, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_AD4_STRENGTH),
    false /* is_event */};
  dpps_feature_[kFeatureAbaHistCtrl] = DRMDppsPropInfo {1 /* version */,
    DRMProperty::SDE_DSPP_ABA_HIST_CTRL, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_ABA_HIST_CTRL),
    false /* is_event */};
  dpps_feature_[kFeatureAbaHistIRQ] = DRMDppsPropInfo {1 /* version */,
    DRMProperty::SDE_DSPP_ABA_HIST_IRQ, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_ABA_HIST_IRQ),
    false /* is_event */};
  dpps_feature_[kFeatureAbaLut] = DRMDppsPropInfo {1 /* version */,
    DRMProperty::SDE_DSPP_ABA_LUT, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_ABA_LUT),
    false /* is_event */};
  dpps_feature_[kFeatureSvBlScale] = DRMDppsPropInfo {1 /* version */,
    DRMProperty::SDE_DSPP_SV_BL_SCALE, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_SV_BL_SCALE),
    false /* is_event */};
  dpps_feature_[kFeatureBacklightScale] = DRMDppsPropInfo {1 /* version */,
    DRMProperty::SDE_DSPP_BL_SCALE, prop_mgr_.GetPropertyId(DRMProperty::SDE_DSPP_BL_SCALE),
    false /* is_event */};

  if (prop_mgr_.IsPropertyAvailable(DRMProperty::SDE_LTM_VERSION)) {
    dpps_feature_[kFeatureLtm] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_VERSION, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_VERSION),
      false /* is_event */};
    dpps_feature_[kFeatureLtmInit] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_INIT, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_INIT),
      false /* is_event */};
    dpps_feature_[kFeatureLtmCfg] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_CFG, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_CFG),
      false /* is_event */};
    dpps_feature_[kFeatureLtmNoiseThresh] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_NOISE_THRESH, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_NOISE_THRESH),
      false /* is_event */};
    dpps_feature_[kFeatureLtmBufferCtrl] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_BUFFER_CTRL, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_BUFFER_CTRL),
      false /* is_event */};
    dpps_feature_[kFeatureLtmQueueBuffer] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_QUEUE_BUFFER, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_QUEUE_BUFFER),
      false /* is_event */};
    dpps_feature_[kFeatureLtmQueueBuffer2] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_QUEUE_BUFFER2, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_QUEUE_BUFFER2),
      false /* is_event */};
    dpps_feature_[kFeatureLtmQueueBuffer3] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_QUEUE_BUFFER3, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_QUEUE_BUFFER3),
      false /* is_event */};
    dpps_feature_[kFeatureLtmHistCtrl] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_HIST_CTRL, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_HIST_CTRL),
      false /* is_event */};
    dpps_feature_[kFeatureLtmVlut] = DRMDppsPropInfo {1 /* version */,
      DRMProperty::SDE_LTM_VLUT, prop_mgr_.GetPropertyId(DRMProperty::SDE_LTM_VLUT),
      false /* is_event */};
  } else {
    DRM_LOGI("LTM properties are not available");
  }

  dpps_feature_[kFeaturePowerEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
  dpps_feature_[kFeatureAbaHistEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
  dpps_feature_[kFeatureBackLightEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
  dpps_feature_[kFeatureAdAttBlEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
  dpps_feature_[kFeatureLtmHistEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
  dpps_feature_[kFeatureLtmWbPbEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
  dpps_feature_[kFeatureLtmOffEvent] = DRMDppsPropInfo{1, DRMProperty::INVALID, 0, true /* is_event */};
}

void DRMDppsManagerImp::CacheDppsFeature(uint32_t obj_id, va_list args) {
  uint32_t feature_id = va_arg(args, uint32_t);
  uint64_t value = va_arg(args, uint64_t);
  struct DRMDppsPropInfo* info;

  if (feature_id >= kDppsFeaturesMax) {
    DRM_LOGE("Invalid feature id %d for obj_id 0x%x", feature_id, obj_id);
    return;
  }

  info = &dpps_feature_[feature_id];
  info->obj_id = obj_id;
  info->value = value;
  if (info->is_event) {
    dpps_dirty_event_.push_back(*info);
  } else {
    for (auto &it : dpps_dirty_prop_) {
      if ((it.obj_id == info->obj_id) && (it.prop_id == info->prop_id)) {
        it.value = info->value;
        return;
      }
    }
    dpps_dirty_prop_.push_back(*info);
  }
}

void DRMDppsManagerImp::CommitDppsFeatures(drmModeAtomicReq *req, const DRMDisplayToken &tok) {
  int ret = 0;

  if (!req)
    return;

  // Set Dpps properties
  if (!dpps_dirty_prop_.empty()) {
    for (auto it = dpps_dirty_prop_.begin(); it != dpps_dirty_prop_.end();) {
      if (it->obj_id == tok.crtc_id || it->obj_id == tok.conn_id) {
        ret = drmModeAtomicAddProperty(req, it->obj_id, it->prop_id, it->value);
        if (ret < 0)
          DRM_LOGE("AtomicAddProperty failed obj_id 0x%x, prop_id %d ret %d ", it->obj_id,
                   it->prop_id, ret);
        else
          it = dpps_dirty_prop_.erase(it);
      } else {
        it++;
      }
    }
  }

  // Set Dpps events
  if (!dpps_dirty_event_.empty()) {
    for (auto it = dpps_dirty_event_.begin(); it != dpps_dirty_event_.end();) {
      if (!it->value)
        continue;

      struct DRMDppsEventInfo info = *(struct DRMDppsEventInfo*)it->value;
      struct drm_msm_event_req event_req = {};
      int ret;
      if (it->obj_id == tok.crtc_id || it->obj_id == tok.conn_id) {
        event_req.object_id = it->obj_id;
        event_req.object_type = info.object_type;
        event_req.event = info.event_type;
        if (info.enable)
          ret = drmIoctl(info.drm_fd, DRM_IOCTL_MSM_REGISTER_EVENT, &event_req);
        else
          ret = drmIoctl(info.drm_fd, DRM_IOCTL_MSM_DEREGISTER_EVENT, &event_req);
        if (ret) {
          if (ret == -EALREADY) {
            DRM_LOGI("Duplicated request to set event 0x%x, object_id %u, object_type 0x%x, enable %d",
                      event_req.event, event_req.object_id, info.object_type, info.enable);
          } else {
            DRM_LOGE("Failed to set event 0x%x, object_id %u, object_type 0x%x, enable %d, ret %d",
                      event_req.event, event_req.object_id, info.object_type, info.enable, ret);
          }
        }
        it = dpps_dirty_event_.erase(it);
      } else {
        it++;
      }
    }
  }
}

void DRMDppsManagerImp::GetDppsFeatureInfo(DRMDppsFeatureInfo *info)
{
  int ret = 0;
  struct DRMDppsPropInfo* prop_info;

  if (!info) {
    DRM_LOGE("Invalid info NULL");
    return;
  }

  DRMDPPSFeatureID id = info->id;
  if (id >= kDppsFeaturesMax) {
    DRM_LOGE("Invalid feature id %d", id);
    return;
  }
  info->version = dpps_feature_[id].version;

  if ((id == kFeatureLtmBufferCtrl) && (dpps_feature_[kFeatureLtm].prop_id != 0)) {
    /* setup ION buffers for LTM */
    ret = InitLtmBuffers(info);
    if (ret) {
      DRM_LOGE("Failed to init LTM buffers %d", ret);
      return;
    } else {
      prop_info = &dpps_feature_[kFeatureLtmBufferCtrl];
      prop_info->obj_id = info->obj_id;
      for (const auto& it : ltm_buffers_ctrl_map_) {
        if (it.first == info->obj_id)
          prop_info->value = (uint64_t)&(it.second);
      }
      dpps_dirty_prop_.push_back(*prop_info);
    }
  }
}

int DRMDppsManagerImp::InitLtmBuffers(struct DRMDppsFeatureInfo *info) {
  int ret = 0;
  uint32_t buffer_size, i = 0, bpp = 0;
  void* uva;
  struct DRMDppsLtmBuffers *buffers;
  DRMDppsLtmBuffers ltm_buffers = {};
  drm_msm_ltm_buffers_ctrl ltm_buffers_ctrl = {};
  struct drm_prime_handle prime_req;
  struct drm_mode_fb_cmd2 fb_obj;
  struct drm_gem_close gem_close;

  if (drm_fd_ < 0) {
    DRM_LOGE("Invalid drm_fd_ %d", drm_fd_);
    return -EINVAL;
  }

  for (const auto& it : ltm_buffers_map_) {
    if (it.first == info->obj_id) {
      DRM_LOGE("LTM buffer already initialized, obj id %d", info->obj_id);
      return -EALREADY;
    }
  }

  if (!info->payload || info->payload_size != sizeof(struct DRMDppsLtmBuffers)) {
    DRM_LOGE("Invalid payload %p size %d expected %d", info->payload, info->payload_size,
       sizeof(struct DRMDppsLtmBuffers));
    return -EINVAL;
  }

  buffers = (struct DRMDppsLtmBuffers *)info->payload;
  if (buffers->num_of_buffers <= 0 || buffers->num_of_buffers > LTM_BUFFER_SIZE) {
    DRM_LOGE("Invalid number of buffers %d", buffers->num_of_buffers);
    return -EINVAL;
  }

  std::memset(&ltm_buffers, 0, sizeof(ltm_buffers));
  std::memset(&ltm_buffers_ctrl, 0, sizeof(ltm_buffers_ctrl));

  ltm_buffers.num_of_buffers = buffers->num_of_buffers;

  buffer_size = sizeof(struct drm_msm_ltm_stats_data) + LTM_GUARD_BYTES;
  std::memset(&fb_obj, 0, sizeof(drm_mode_fb_cmd2));
  fb_obj.pixel_format = DRM_FORMAT_YVYU;
  /* YVYU gives us a bpp of 16 (2 bytes) so we must take that into account */
  fb_obj.height = 2;
  /* add extra one to compensate integer rounding */
  fb_obj.width = buffer_size / (2 * fb_obj.height) + 1;
  /* bpp for YVYU is 16 */
  bpp = 16;
  fb_obj.flags = DRM_MODE_FB_MODIFIERS;
  fb_obj.pitches[0] = fb_obj.width * bpp / 8;

  for (i = 0; i < buffers->num_of_buffers && !ret; i++) {
    std::memset(&prime_req, 0, sizeof(drm_prime_handle));
    prime_req.fd = buffers->ion_buffer_fd[i];
    ret = drmIoctl(drm_fd_, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_req);
    if (ret) {
      ret = -errno;
      DRM_LOGE("failed get prime handle: %d", ret);
      break;
    }
    ltm_buffers.ion_buffer_fd[i] = buffers->ion_buffer_fd[i];

    fb_obj.handles[0] = prime_req.handle;
    ret = drmIoctl(drm_fd_, DRM_IOCTL_MODE_ADDFB2, &fb_obj);
    if (ret) {
      ret = -errno;
      DRM_LOGE("return value from addFB2: %d", ret);
      break;
    }
    ltm_buffers.drm_fb_id[i] = buffers->drm_fb_id[i] = fb_obj.fb_id;
    ltm_buffers_ctrl.fds[i] = ltm_buffers.drm_fb_id[i];

    /**
     * ADDFB2 will take reference to GEM handles,
     * so drop reference taken by PrimeFDtoHandle now
     */
    std::memset(&gem_close, 0, sizeof(gem_close));
    gem_close.handle = prime_req.handle;
    ret = drmIoctl(drm_fd_, DRM_IOCTL_GEM_CLOSE, &gem_close);
    if(ret) {
      ret = -errno;
      DRM_LOGE("return value from GEM_CLOSE: %d\n", ret);
      break;
    }

    uva = drm_mmap(0, buffers->buffer_size, PROT_READ | PROT_WRITE, MAP_SHARED,
                   buffers->ion_buffer_fd[i], 0);
    if (uva == MAP_FAILED) {
      ret = -errno;
      DRM_LOGE("failed to get uva: %d", ret);
      break;
    }
    ltm_buffers.uva[i] = buffers->uva[i] = uva;
  }

  if (!ret) {
    buffers->status = 0;
    ltm_buffers.buffer_size = buffers->buffer_size;
    ltm_buffers_ctrl.num_of_buffers = ltm_buffers.num_of_buffers;
    DRM_LOGV("InitLtmBuffers return successful");
  } else {
    DeInitLtmBuffers();
    buffers->status = ret;
    return ret;
  }

  ltm_buffers_map_.push_back(std::make_pair(info->obj_id, std::move(ltm_buffers)));
  ltm_buffers_ctrl_map_.push_back(std::make_pair(info->obj_id, std::move(ltm_buffers_ctrl)));
  return ret;
}

int DRMDppsManagerImp::DeInitLtmBuffers() {
  int ret = 0;
  uint32_t i = 0;

  if (drm_fd_ < 0) {
    return -EINVAL;
  }

  for (auto& it : ltm_buffers_map_) {
    DRMDppsLtmBuffers& ltm_buffers = it.second;
    for (i = 0; i < ltm_buffers.num_of_buffers; i++) {
      if (ltm_buffers.uva[i]) {
        drm_munmap(ltm_buffers.uva[i], ltm_buffers.buffer_size);
        ltm_buffers.uva[i] = NULL;
      }

      if (ltm_buffers.drm_fb_id[i] >= 0) {
#ifdef DRM_IOCTL_MSM_RMFB2
        ret = drmIoctl(drm_fd_, DRM_IOCTL_MSM_RMFB2, &ltm_buffers.drm_fb_id[i]);
        if (ret) {
          ret = errno;
          DRM_LOGE("RMFB2 failed for fb_id %d with error %d", ltm_buffers.drm_fb_id[i], ret);
        }
#endif
        ltm_buffers.drm_fb_id[i] = -1;
      }
      ltm_buffers.ion_buffer_fd[i] = -1;
    }

    ltm_buffers.num_of_buffers = 0;
    ltm_buffers.buffer_size = 0;
  }

  for (auto& it : ltm_buffers_ctrl_map_) {
    drm_msm_ltm_buffers_ctrl& ltm_buffers_ctrl = it.second;
    std::memset(&ltm_buffers_ctrl, 0, sizeof(ltm_buffers_ctrl));
  }

  ltm_buffers_map_.clear();
  ltm_buffers_ctrl_map_.clear();
  return 0;
}

}  // namespace sde_drm
