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

#ifndef __DRM_CRTC_H__
#define __DRM_CRTC_H__

#include <xf86drm.h>
#include <xf86drmMode.h>
#include <map>
#include <memory>
#include <vector>
#include <string>
#include <set>
#include <mutex>

#include "drm_interface.h"
#include "drm_utils.h"
#include "drm_pp_manager.h"
#include "drm_property.h"

namespace sde_drm {

class DRMCrtc {
 public:
  DRMCrtc(int fd, uint32_t crtc_index) : fd_(fd), crtc_index_(crtc_index) {}
  void InitAndParse(drmModeCrtc *crtc);
  DRMStatus GetStatus() { return status_; }
  void GetInfo(DRMCrtcInfo *info);
  void SetModeBlobID(uint64_t blob_id);
  bool ConfigureScalerLUT(drmModeAtomicReq *req, uint32_t dir_lut_blob_id,
                          uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id);
  void PostValidate(bool success);
  void PostCommit(bool success);
  void Perform(DRMOps code, drmModeAtomicReq *req, va_list args);
  int GetIndex() { return crtc_index_; }
  void Dump();
  void Lock();
  void Unlock();
  void GetPPInfo(DRMPPFeatureInfo *info) {
    if (pp_mgr_)
      pp_mgr_->GetPPInfo(info);
  }
  ~DRMCrtc();

 private:
  void ParseProperties();
  void ParseCapabilities(uint64_t blob_id);
  void ParseCompRatio(std::string line, bool real_time);
  void SetROI(drmModeAtomicReq *req, uint32_t obj_id, uint32_t num_roi,
              DRMRect *crtc_rois);
  void SetSolidfillStages(drmModeAtomicReq *req, uint32_t obj_id,
                          const std::vector<DRMSolidfillStage> *solid_fills);
  void ClearVotesCache();

  // Currently hardcoded to 10. In future we need to query bit depth from driver.
  static const int kSolidFillHwBitDepth = 10;

  int fd_ = -1;
  uint32_t crtc_index_ = {};
  uint64_t mode_blob_id_ = 0;
  drmModeCrtc *drm_crtc_ = {};
  DRMStatus status_ = DRMStatus::FREE;
  DRMCrtcInfo crtc_info_ = {};
  DRMPropertyManager prop_mgr_ {};
  bool is_lut_configured_ = false;
  bool is_lut_validated_ = false;
  bool is_lut_validation_in_progress_ = false;
  std::unique_ptr<DRMPPManager> pp_mgr_{};
  std::unordered_map<uint32_t, uint64_t> tmp_prop_val_map_ {};
  std::unordered_map<uint32_t, uint64_t> committed_prop_val_map_ {};
};

class DRMCrtcManager {
 public:
  explicit DRMCrtcManager(int fd) : fd_(fd) {}
  void Init(drmModeRes *res);
  void DeInit() {}
  void DumpAll();
  void DumpByID(uint32_t id);
  int Reserve(const std::set<uint32_t> &possible_crtc_indices, DRMDisplayToken *token);
  void Free(DRMDisplayToken *token);
  void Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req, va_list args);
  int GetCrtcInfo(uint32_t crtc_id, DRMCrtcInfo *info);
  void SetScalerLUT(const DRMScalerLUTInfo &lut_info);
  void UnsetScalerLUT();
  void GetPPInfo(uint32_t crtc_id, DRMPPFeatureInfo *info);
  void PostValidate(uint32_t crtc_id, bool success);
  void PostCommit(uint32_t crtc_id, bool success);

 private:
  int fd_ = -1;
  std::map<uint32_t, std::unique_ptr<DRMCrtc>> crtc_pool_{};
    // GLobal Scaler LUT blobs
  uint32_t dir_lut_blob_id_ = 0;
  uint32_t cir_lut_blob_id_ = 0;
  uint32_t sep_lut_blob_id_ = 0;
  std::mutex lock_;
};

}  // namespace sde_drm

#endif  // __DRM_CRTC_H__
