1 /*
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *    * Redistributions of source code must retain the above copyright
8 *      notice, this list of conditions and the following disclaimer.
9 *    * Redistributions in binary form must reproduce the above
10 *      copyright notice, this list of conditions and the following
11 *      disclaimer in the documentation and/or other materials provided
12 *      with the distribution.
13 *    * Neither the name of The Linux Foundation nor the names of its
14 *      contributors may be used to endorse or promote products derived
15 *      from this software without specific prior written permission.
16 
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #ifndef __DRM_PLANE_H__
31 #define __DRM_PLANE_H__
32 
33 #include <drm/sde_drm.h>
34 #include <drm_interface.h>
35 #include <xf86drm.h>
36 #include <xf86drmMode.h>
37 #include <map>
38 #include <memory>
39 #include <string>
40 #include <tuple>
41 #include <mutex>
42 
43 #include "drm_property.h"
44 #include "drm_pp_manager.h"
45 
46 namespace sde_drm {
47 
48 class DRMPlaneManager;
49 
50 enum DRMPlaneLutState {
51   kInactive,  //  Lut is not in use, default
52   kActive,    //  Lut is in use
53   kDirty,     //  Plane was unset while being LUT was active, mark LUT as dirty
54               //  to make sure it's cleared the next time plane is used
55 };
56 
57 class DRMPlane : public DRMObject {
58  public:
59   explicit DRMPlane(int fd, uint32_t priority);
60   ~DRMPlane();
61   void InitAndParse(drmModePlane *plane);
GetObjectId()62   uint32_t GetObjectId() override { return drm_plane_->plane_id; }
GetType(DRMPlaneType * type)63   void GetType(DRMPlaneType *type) { *type = plane_type_info_.type; }
GetPriority(uint32_t * priority)64   void GetPriority(uint32_t *priority) { *priority = priority_; }
GetAssignedCrtc(uint32_t * crtc_id)65   void GetAssignedCrtc(uint32_t *crtc_id) { *crtc_id = assigned_crtc_id_; }
GetRequestedCrtc(uint32_t * crtc_id)66   void GetRequestedCrtc(uint32_t *crtc_id) { *crtc_id = requested_crtc_id_; }
SetAssignedCrtc(uint32_t crtc_id)67   void SetAssignedCrtc(uint32_t crtc_id) { assigned_crtc_id_ = crtc_id; }
SetRequestedCrtc(uint32_t crtc_id)68   void SetRequestedCrtc(uint32_t crtc_id) { requested_crtc_id_ = crtc_id; }
69   bool SetScalerConfig(uint64_t handle);
70   bool SetCscConfig(DRMCscType csc_type);
71   bool ConfigureScalerLUT(uint32_t dir_lut_blob_id,
72                           uint32_t cir_lut_blob_id, uint32_t sep_lut_blob_id);
GetPlaneTypeInfo()73   const DRMPlaneTypeInfo& GetPlaneTypeInfo() { return plane_type_info_; }
74   void SetDecimation(DRMProperty prop, uint32_t prop_value);
75   void SetExclRect(DRMRect rect);
76   void Perform(DRMOps code, drmModeAtomicReq *req, va_list args);
77   void Dump();
78   void SetMultiRectMode(DRMMultiRectMode drm_multirect_mode);
79   void Unset(bool is_commit, drmModeAtomicReq *req);
80   void PostValidate(uint32_t crtc_id);
81   void PostCommit(uint32_t crtc_id, bool success);
82   bool SetDgmCscConfig(uint64_t handle);
83   void UpdatePPLutFeatureInuse(DRMPPFeatureInfo *data);
84   void ResetColorLUTs(bool is_commit, drmModeAtomicReq *req);
85   void ResetColorLUTState(DRMTonemapLutType lut_type, bool is_commit, drmModeAtomicReq *req);
86   void ResetColorLUT(DRMPPFeatureID id, drmModeAtomicReq *req);
87 
88  private:
89   typedef std::map<DRMProperty, std::tuple<uint64_t, drmModePropertyRes *>> PropertyMap;
90   void ParseProperties();
91   void GetTypeInfo(const PropertyMap &props);
92   void PerformWrapper(DRMOps code, drmModeAtomicReq *req, ...);
93 
94   int fd_ = -1;
95   uint32_t priority_ = 0;
96   drmModePlane *drm_plane_ = {};
97   DRMPlaneTypeInfo plane_type_info_{};
98   uint32_t assigned_crtc_id_ = 0;
99   uint32_t requested_crtc_id_ = 0;
100   DRMPropertyManager prop_mgr_ {};
101   bool has_excl_rect_ = false;
102   drm_clip_rect excl_rect_copy_ = {};
103   std::unique_ptr<DRMPPManager> pp_mgr_ {};
104 
105   // Only applicable to planes that have scaler
106   sde_drm_scaler_v2 scaler_v2_config_copy_ = {};
107   sde_drm_csc_v1 csc_config_copy_ = {};
108   bool is_lut_configured_ = false;
109 
110   bool dgm_csc_in_use_ = false;
111   // Tone-mapping lut properties
112   DRMPlaneLutState dgm_1d_lut_igc_state_ = kInactive;
113   DRMPlaneLutState dgm_1d_lut_gc_state_ = kInactive;
114   DRMPlaneLutState vig_1d_lut_igc_state_ = kInactive;
115   DRMPlaneLutState vig_3d_lut_gamut_state_ = kInactive;
116 };
117 
118 class DRMPlaneManager : public DRMObjectManager<DRMPlane> {
119  public:
120   explicit DRMPlaneManager(int fd);
121   void Init();
DeInit()122   void DeInit() {}
123   void GetPlanesInfo(DRMPlanesInfo *info);
124   void Perform(DRMOps code, uint32_t obj_id, drmModeAtomicReq *req, va_list args);
125   void UnsetUnusedResources(uint32_t crtc_id, bool is_commit, drmModeAtomicReq *req);
126   void ResetColorLutsOnUsedPlanes(uint32_t crtc_id, bool is_commit, drmModeAtomicReq *req);
127   void RetainPlanes(uint32_t crtc_id);
128   void SetScalerLUT(const DRMScalerLUTInfo &lut_info);
129   void UnsetScalerLUT();
130   void PostValidate(uint32_t crtc_id);
131   void PostCommit(uint32_t crtc_id, bool success);
132 
133  private:
134   void Perform(DRMOps code, drmModeAtomicReq *req, uint32_t obj_id, ...);
135 
136   int fd_ = -1;
137   // Global Scaler LUT blobs
138   uint32_t dir_lut_blob_id_ = 0;
139   uint32_t cir_lut_blob_id_ = 0;
140   uint32_t sep_lut_blob_id_ = 0;
141   std::mutex lock_;
142 };
143 
144 }  // namespace sde_drm
145 
146 #endif  // __DRM_PLANE_H__
147