/*
* 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 <drm_logger.h>

#include "drm_atomic_req.h"
#include "drm_connector.h"
#include "drm_crtc.h"
#include "drm_manager.h"
#include "drm_plane.h"
#include "string.h"

#define __CLASS__ "DRMAtomicReq"

namespace sde_drm {

DRMAtomicReq::DRMAtomicReq(int fd, DRMManager *drm_mgr) : drm_mgr_(drm_mgr), fd_(fd) {}

DRMAtomicReq::~DRMAtomicReq() {
  if (drm_atomic_req_) {
    drmModeAtomicFree(drm_atomic_req_);
    drm_atomic_req_ = nullptr;
  }
}

int DRMAtomicReq::Init(const DRMDisplayToken &tok) {
  token_ = tok;
  drm_atomic_req_ = drmModeAtomicAlloc();
  if (!drm_atomic_req_) {
    return -ENOMEM;
  }

  return 0;
}

int DRMAtomicReq::Perform(DRMOps opcode, uint32_t obj_id, ...) {
  va_list args;
  va_start(args, obj_id);
  switch (opcode) {
    case DRMOps::PLANE_SET_SRC_RECT:
    case DRMOps::PLANE_SET_DST_RECT:
    case DRMOps::PLANE_SET_ZORDER:
    case DRMOps::PLANE_SET_ROTATION:
    case DRMOps::PLANE_SET_ALPHA:
    case DRMOps::PLANE_SET_BLEND_TYPE:
    case DRMOps::PLANE_SET_H_DECIMATION:
    case DRMOps::PLANE_SET_V_DECIMATION:
    case DRMOps::PLANE_SET_FB_ID:
    case DRMOps::PLANE_SET_ROT_FB_ID:
    case DRMOps::PLANE_SET_CRTC:
    case DRMOps::PLANE_SET_SRC_CONFIG:
    case DRMOps::PLANE_SET_INPUT_FENCE:
    case DRMOps::PLANE_SET_SCALER_CONFIG:
    case DRMOps::PLANE_SET_FB_SECURE_MODE:
    case DRMOps::PLANE_SET_CSC_CONFIG:
    case DRMOps::PLANE_SET_MULTIRECT_MODE:
    case DRMOps::PLANE_SET_EXCL_RECT:
    case DRMOps::PLANE_SET_INVERSE_PMA:
    case DRMOps::PLANE_SET_DGM_CSC_CONFIG:
    case DRMOps::PLANE_SET_POST_PROC: {
      drm_mgr_->GetPlaneMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
    } break;
    case DRMOps::CRTC_SET_POST_PROC:
    case DRMOps::CRTC_SET_MODE:
    case DRMOps::CRTC_SET_ACTIVE:
    case DRMOps::CRTC_SET_OUTPUT_FENCE_OFFSET:
    case DRMOps::CRTC_SET_CORE_CLK:
    case DRMOps::CRTC_SET_CORE_AB:
    case DRMOps::CRTC_SET_CORE_IB:
    case DRMOps::CRTC_SET_LLCC_AB:
    case DRMOps::CRTC_SET_LLCC_IB:
    case DRMOps::CRTC_SET_DRAM_AB:
    case DRMOps::CRTC_SET_DRAM_IB:
    case DRMOps::CRTC_SET_ROT_PREFILL_BW:
    case DRMOps::CRTC_SET_ROT_CLK:
    case DRMOps::CRTC_GET_RELEASE_FENCE:
    case DRMOps::CRTC_SET_ROI:
    case DRMOps::CRTC_SET_SECURITY_LEVEL:
    case DRMOps::CRTC_SET_SOLIDFILL_STAGES:
    case DRMOps::CRTC_SET_IDLE_TIMEOUT:
    case DRMOps::CRTC_SET_DEST_SCALER_CONFIG:
    case DRMOps::CRTC_SET_CAPTURE_MODE:
    case DRMOps::CRTC_SET_IDLE_PC_STATE: {
      drm_mgr_->GetCrtcMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
    } break;
    case DRMOps::CONNECTOR_SET_CRTC:
    case DRMOps::CONNECTOR_GET_RETIRE_FENCE:
    case DRMOps::CONNECTOR_SET_OUTPUT_RECT:
    case DRMOps::CONNECTOR_SET_OUTPUT_FB_ID:
    case DRMOps::CONNECTOR_SET_POWER_MODE:
    case DRMOps::CONNECTOR_SET_ROI:
    case DRMOps::CONNECTOR_SET_AUTOREFRESH:
    case DRMOps::CONNECTOR_SET_FB_SECURE_MODE:
    case DRMOps::CONNECTOR_SET_POST_PROC:
    case DRMOps::CONNECTOR_SET_HDR_METADATA:
    case DRMOps::CONNECTOR_SET_QSYNC_MODE:
    case DRMOps::CONNECTOR_SET_TOPOLOGY_CONTROL:
    case DRMOps::CONNECTOR_SET_FRAME_TRIGGER:
    case DRMOps::CONNECTOR_SET_COLORSPACE: {
      drm_mgr_->GetConnectorMgr()->Perform(opcode, obj_id, drm_atomic_req_, args);
    } break;
    case DRMOps::DPPS_CACHE_FEATURE: {
      drm_mgr_->GetDppsMgrIntf()->CacheDppsFeature(obj_id, args);
    } break;
    case DRMOps::DPPS_COMMIT_FEATURE: {
      drm_mgr_->GetDppsMgrIntf()->CommitDppsFeatures(drm_atomic_req_, token_);
    } break;
    default:
      DRM_LOGE("Invalid opcode %d", opcode);
  }
  va_end(args);
  return 0;
}

int DRMAtomicReq::Validate() {
  // Call UnsetUnusedPlanes to find planes that need to be unset. Do not call CommitPlaneState,
  // because we just want to validate, not actually mark planes as removed
  drm_mgr_->GetPlaneMgr()->UnsetUnusedResources(token_.crtc_id, false/*is_commit*/,
                                                drm_atomic_req_);

  int ret = drmModeAtomicCommit(fd_, drm_atomic_req_,
                                DRM_MODE_ATOMIC_ALLOW_MODESET | DRM_MODE_ATOMIC_TEST_ONLY, nullptr);
  if (ret) {
    DRM_LOGE("drmModeAtomicCommit failed with error %d (%s).", errno, strerror(errno));
  }

  drm_mgr_->GetPlaneMgr()->PostValidate(token_.crtc_id, !ret);
  drm_mgr_->GetCrtcMgr()->PostValidate(token_.crtc_id, !ret);
  drmModeAtomicSetCursor(drm_atomic_req_, 0);

  return ret;
}

int DRMAtomicReq::Commit(bool synchronous, bool retain_planes) {
  DTRACE_SCOPED();
  if (retain_planes) {
    // It is not enough to simply avoid calling UnsetUnusedPlanes, since state transitons have to
    // be correct when CommitPlaneState is called
    drm_mgr_->GetPlaneMgr()->RetainPlanes(token_.crtc_id);
  }

  drm_mgr_->GetPlaneMgr()->UnsetUnusedResources(token_.crtc_id, true/*is_commit*/, drm_atomic_req_);

  uint32_t flags = DRM_MODE_ATOMIC_ALLOW_MODESET;

  if (!synchronous) {
    flags |= DRM_MODE_ATOMIC_NONBLOCK;
  }

  int ret = drmModeAtomicCommit(fd_, drm_atomic_req_, flags, nullptr);
  if (ret) {
    DRM_LOGE("drmModeAtomicCommit failed with error %d (%s).", errno, strerror(errno));
  }

  drm_mgr_->GetPlaneMgr()->PostCommit(token_.crtc_id, !ret);
  drm_mgr_->GetCrtcMgr()->PostCommit(token_.crtc_id, !ret);
  drmModeAtomicSetCursor(drm_atomic_req_, 0);

  return ret;
}

}  // namespace sde_drm
