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 #ifdef PP_DRM_ENABLE
31 #include <xf86drm.h>
32 #include <xf86drmMode.h>
33 #include <drm/msm_drm_pp.h>
34 #endif
35 #include <drm_logger.h>
36 #include <cstring>
37 #include <algorithm>
38 #include <memory>
39 #include <map>
40 #include <string>
41
42 #include "drm_pp_manager.h"
43 #include "drm_property.h"
44
45 #define __CLASS__ "DRMPPManager"
46 namespace sde_drm {
47
DRMPPManager(int fd)48 DRMPPManager::DRMPPManager(int fd) : fd_(fd) {
49 }
50
~DRMPPManager()51 DRMPPManager::~DRMPPManager() {
52 #ifdef PP_DRM_ENABLE
53 DRMPPPropInfo prop_info = {};
54
55 /* free previously created blob to avoid memory leak */
56 for (int i = 0; i < kPPFeaturesMax; i++) {
57 prop_info = pp_prop_map_[i];
58 if (prop_info.blob_id > 0) {
59 drmModeDestroyPropertyBlob(fd_, prop_info.blob_id);
60 prop_info.blob_id = 0;
61 }
62 }
63 #endif
64 fd_ = -1;
65 }
66
Init(const DRMPropertyManager & pm,uint32_t object_type)67 void DRMPPManager::Init(const DRMPropertyManager &pm , uint32_t object_type) {
68 object_type_ = object_type;
69 for (uint32_t i = (uint32_t)DRMProperty::INVALID + 1; i < (uint32_t)DRMProperty::MAX; i++) {
70 /* parse all the object properties and store the PP properties
71 * into DRMPPManager class
72 */
73 if (!pm.IsPropertyAvailable((DRMProperty)i)) {
74 continue;
75 }
76
77 if (i >= (uint32_t)DRMProperty::SDE_DSPP_GAMUT_V3 && i <=
78 (uint32_t)DRMProperty::SDE_DSPP_GAMUT_V5) {
79 pp_prop_map_[kFeatureGamut].prop_enum = (DRMProperty)i;
80 pp_prop_map_[kFeatureGamut].prop_id = pm.GetPropertyId((DRMProperty)i);
81 pp_prop_map_[kFeatureGamut].version = i - (uint32_t)DRMProperty::SDE_DSPP_GAMUT_V3 + 3;
82 DRM_LOGI("Gamut version %d, prop_id %d", pp_prop_map_[kFeatureGamut].version,
83 pp_prop_map_[kFeatureGamut].prop_id);
84 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_GC_V1 && i <=
85 (uint32_t)DRMProperty::SDE_DSPP_GC_V2) {
86 pp_prop_map_[kFeaturePgc].prop_enum = (DRMProperty)i;
87 pp_prop_map_[kFeaturePgc].prop_id = pm.GetPropertyId((DRMProperty)i);
88 pp_prop_map_[kFeaturePgc].version = i - (uint32_t)DRMProperty::SDE_DSPP_GC_V1 + 1;
89 DRM_LOGI("Pgc version %d, prop_id %d", pp_prop_map_[kFeaturePgc].version,
90 pp_prop_map_[kFeaturePgc].prop_id);
91 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_IGC_V2 &&
92 i <= (uint32_t)DRMProperty::SDE_DSPP_IGC_V4) {
93 pp_prop_map_[kFeatureIgc].prop_enum = (DRMProperty)i;
94 pp_prop_map_[kFeatureIgc].prop_id = pm.GetPropertyId((DRMProperty)i);
95 pp_prop_map_[kFeatureIgc].version = i - (uint32_t)DRMProperty::SDE_DSPP_IGC_V2 + 2;
96 DRM_LOGI("Igc version %d, prop_id %d", pp_prop_map_[kFeatureIgc].version,
97 pp_prop_map_[kFeatureIgc].prop_id);
98 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PCC_V3 &&
99 i <= (uint32_t)DRMProperty::SDE_DSPP_PCC_V5) {
100 pp_prop_map_[kFeaturePcc].prop_enum = (DRMProperty)i;
101 pp_prop_map_[kFeaturePcc].prop_id = pm.GetPropertyId((DRMProperty)i);
102 pp_prop_map_[kFeaturePcc].version = i - (uint32_t)DRMProperty::SDE_DSPP_PCC_V3 + 3;
103 DRM_LOGI("Pcc version %d, prop_id %d", pp_prop_map_[kFeaturePcc].version,
104 pp_prop_map_[kFeaturePcc].prop_id);
105 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_HSIC_V1 &&
106 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_HSIC_V2) {
107 pp_prop_map_[kFeaturePAHsic].prop_enum = (DRMProperty)i;
108 pp_prop_map_[kFeaturePAHsic].prop_id = pm.GetPropertyId((DRMProperty)i);
109 pp_prop_map_[kFeaturePAHsic].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_HSIC_V1 + 1;
110 DRM_LOGI("PaHsic version %d, prop_id %d", pp_prop_map_[kFeaturePAHsic].version,
111 pp_prop_map_[kFeaturePAHsic].prop_id);
112 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_SIXZONE_V1 &&
113 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_SIXZONE_V2) {
114 pp_prop_map_[kFeaturePASixZone].prop_enum = (DRMProperty)i;
115 pp_prop_map_[kFeaturePASixZone].prop_id = pm.GetPropertyId((DRMProperty)i);
116 pp_prop_map_[kFeaturePASixZone].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_SIXZONE_V1 + 1;
117 DRM_LOGI("SixZone version %d, prop_id %d", pp_prop_map_[kFeaturePASixZone].version,
118 pp_prop_map_[kFeaturePASixZone].prop_id);
119 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_SKIN_V1 &&
120 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_SKIN_V2) {
121 pp_prop_map_[kFeaturePAMemColSkin].prop_enum = (DRMProperty)i;
122 pp_prop_map_[kFeaturePAMemColSkin].prop_id = pm.GetPropertyId((DRMProperty)i);
123 pp_prop_map_[kFeaturePAMemColSkin].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_SKIN_V1 + 1;
124 DRM_LOGI("MemColor skin version %d, prop_id %d", pp_prop_map_[kFeaturePAMemColSkin].version,
125 pp_prop_map_[kFeaturePAMemColSkin].prop_id);
126 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_SKY_V1 &&
127 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_SKY_V2) {
128 pp_prop_map_[kFeaturePAMemColSky].prop_enum = (DRMProperty)i;
129 pp_prop_map_[kFeaturePAMemColSky].prop_id = pm.GetPropertyId((DRMProperty)i);
130 pp_prop_map_[kFeaturePAMemColSky].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_SKY_V1 + 1;
131 DRM_LOGI("MemColor sky version %d, prop_id %d", pp_prop_map_[kFeaturePAMemColSky].version,
132 pp_prop_map_[kFeaturePAMemColSky].prop_id);
133 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_FOLIAGE_V1 &&
134 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_FOLIAGE_V2) {
135 pp_prop_map_[kFeaturePAMemColFoliage].prop_enum = (DRMProperty)i;
136 pp_prop_map_[kFeaturePAMemColFoliage].prop_id = pm.GetPropertyId((DRMProperty)i);
137 pp_prop_map_[kFeaturePAMemColFoliage].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_FOLIAGE_V1 + 1;
138 DRM_LOGI("MemColor foliage version %d, prop_id %d", pp_prop_map_[kFeaturePAMemColFoliage].version,
139 pp_prop_map_[kFeaturePAMemColFoliage].prop_id);
140 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_PROT_V1 &&
141 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_PROT_V2) {
142 pp_prop_map_[kFeaturePAMemColProt].prop_enum = (DRMProperty)i;
143 pp_prop_map_[kFeaturePAMemColProt].prop_id = pm.GetPropertyId((DRMProperty)i);
144 pp_prop_map_[kFeaturePAMemColProt].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_MEMCOL_PROT_V1 + 1;
145 DRM_LOGI("MemColor prot version %d, prop_id %d", pp_prop_map_[kFeaturePAMemColProt].version,
146 pp_prop_map_[kFeaturePAMemColProt].prop_id);
147 } else if (i >= (uint32_t)DRMProperty::SDE_DSPP_PA_DITHER_V1 &&
148 i <= (uint32_t)DRMProperty::SDE_DSPP_PA_DITHER_V2) {
149 pp_prop_map_[kFeaturePADither].prop_enum = (DRMProperty)i;
150 pp_prop_map_[kFeaturePADither].prop_id = pm.GetPropertyId((DRMProperty)i);
151 pp_prop_map_[kFeaturePADither].version = i - (uint32_t)DRMProperty::SDE_DSPP_PA_DITHER_V1 + 1;
152 DRM_LOGI("PA Dither version %d, prop_id %d", pp_prop_map_[kFeaturePADither].version,
153 pp_prop_map_[kFeaturePADither].prop_id);
154 } else if (i >= (uint32_t)DRMProperty::SDE_PP_DITHER_V1 &&
155 i <= (uint32_t)DRMProperty::SDE_PP_DITHER_V2) {
156 pp_prop_map_[kFeatureDither].prop_enum = (DRMProperty)i;
157 pp_prop_map_[kFeatureDither].prop_id = pm.GetPropertyId((DRMProperty)i);
158 pp_prop_map_[kFeatureDither].version = i - (uint32_t)DRMProperty::SDE_PP_DITHER_V1 + 1;
159 DRM_LOGI("PP dither version %d, prop_id %d", pp_prop_map_[kFeatureDither].version,
160 pp_prop_map_[kFeatureDither].prop_id);
161 } else if (i >= (uint32_t)DRMProperty::SDE_VIG_3D_LUT_GAMUT_V5 &&
162 i <= (uint32_t)DRMProperty::SDE_VIG_3D_LUT_GAMUT_V6) {
163 pp_prop_map_[kFeatureVigGamut].prop_enum = (DRMProperty)i;
164 pp_prop_map_[kFeatureVigGamut].prop_id = pm.GetPropertyId((DRMProperty)i);
165 pp_prop_map_[kFeatureVigGamut].version = i - (uint32_t)DRMProperty::SDE_VIG_3D_LUT_GAMUT_V5 + 5;
166 DRM_LOGI("Vig Gamut version %d, prop_id %d", pp_prop_map_[kFeatureVigGamut].version,
167 pp_prop_map_[kFeatureVigGamut].prop_id);
168 } else if (i >= (uint32_t)DRMProperty::SDE_VIG_1D_LUT_IGC_V5 &&
169 i <= (uint32_t)DRMProperty::SDE_VIG_1D_LUT_IGC_V6) {
170 pp_prop_map_[kFeatureVigIgc].prop_enum = (DRMProperty)i;
171 pp_prop_map_[kFeatureVigIgc].prop_id = pm.GetPropertyId((DRMProperty)i);
172 pp_prop_map_[kFeatureVigIgc].version = i - (uint32_t)DRMProperty::SDE_VIG_1D_LUT_IGC_V5 + 5;
173 DRM_LOGI("Vig Igc version %d, prop_id %d", pp_prop_map_[kFeatureVigIgc].version,
174 pp_prop_map_[kFeatureVigIgc].prop_id);
175 } else if (i >= (uint32_t)DRMProperty::SDE_DGM_1D_LUT_IGC_V5 &&
176 i <= (uint32_t)DRMProperty::SDE_DGM_1D_LUT_IGC_V5) {
177 pp_prop_map_[kFeatureDgmIgc].prop_enum = (DRMProperty)i;
178 pp_prop_map_[kFeatureDgmIgc].prop_id = pm.GetPropertyId((DRMProperty)i);
179 pp_prop_map_[kFeatureDgmIgc].version = i - (uint32_t)DRMProperty::SDE_DGM_1D_LUT_IGC_V5 + 5;
180 DRM_LOGI("Dgm Igc version %d, prop_id %d", pp_prop_map_[kFeatureDgmIgc].version,
181 pp_prop_map_[kFeatureDgmIgc].prop_id);
182 } else if (i >= (uint32_t)DRMProperty::SDE_DGM_1D_LUT_GC_V5 &&
183 i <= (uint32_t)DRMProperty::SDE_DGM_1D_LUT_GC_V5) {
184 pp_prop_map_[kFeatureDgmGc].prop_enum = (DRMProperty)i;
185 pp_prop_map_[kFeatureDgmGc].prop_id = pm.GetPropertyId((DRMProperty)i);
186 pp_prop_map_[kFeatureDgmGc].version = i - (uint32_t)DRMProperty::SDE_DGM_1D_LUT_GC_V5 + 5;
187 DRM_LOGI("Dgm Gc version %d, prop_id %d", pp_prop_map_[kFeatureDgmGc].version,
188 pp_prop_map_[kFeatureDgmGc].prop_id);
189 }
190 }
191 return;
192 }
193
GetPPInfo(DRMPPFeatureInfo * info)194 void DRMPPManager::GetPPInfo(DRMPPFeatureInfo *info) {
195 if (!info)
196 return;
197 if (info->id > kPPFeaturesMax)
198 return;
199
200 info->version = pp_prop_map_[info->id].version;
201 info->object_type = object_type_;
202 return;
203 }
204
SetPPFeature(drmModeAtomicReq * req,uint32_t obj_id,DRMPPFeatureInfo & feature)205 void DRMPPManager::SetPPFeature(drmModeAtomicReq *req, uint32_t obj_id, DRMPPFeatureInfo &feature) {
206 if (!req) {
207 DRM_LOGE("Invalid input param: req %p", req);
208 return;
209 }
210
211 if (feature.id >= kPPFeaturesMax)
212 return;
213
214 switch (feature.type) {
215 case kPropEnum:
216 break;
217 case kPropRange:
218 break;
219 case kPropBlob:
220 SetPPBlobProperty(req, obj_id, &pp_prop_map_[feature.id], feature);
221 break;
222 default:
223 DRM_LOGE("Unsupported feature type %d", feature.type);
224 break;
225 }
226
227 return;
228 }
229
SetPPBlobProperty(drmModeAtomicReq * req,uint32_t obj_id,struct DRMPPPropInfo * prop_info,DRMPPFeatureInfo & feature)230 int DRMPPManager::SetPPBlobProperty(drmModeAtomicReq *req, uint32_t obj_id,
231 struct DRMPPPropInfo *prop_info,
232 DRMPPFeatureInfo &feature) {
233 int ret = DRM_ERR_INVALID;
234 #ifdef PP_DRM_ENABLE
235 uint32_t blob_id = 0;
236
237 /* free previously created blob for this feature if exist */
238 if (prop_info->blob_id > 0) {
239 ret = drmModeDestroyPropertyBlob(fd_, prop_info->blob_id);
240 if (ret) {
241 DRM_LOGE("failed to destroy property blob for feature %d, ret = %d", feature.id, ret);
242 return ret;
243 } else {
244 prop_info->blob_id = 0;
245 }
246 }
247
248 if (!feature.payload) {
249 // feature disable case
250 drmModeAtomicAddProperty(req, obj_id, prop_info->prop_id, 0);
251 return 0;
252 }
253
254 ret = drmModeCreatePropertyBlob(fd_, feature.payload, feature.payload_size, &blob_id);
255 if (ret || blob_id == 0) {
256 DRM_LOGE("failed to create property blob ret %d, blob_id = %d", ret, blob_id);
257 return DRM_ERR_INVALID;
258 }
259
260 prop_info->blob_id = blob_id;
261 drmModeAtomicAddProperty(req, obj_id, prop_info->prop_id, blob_id);
262
263 #endif
264 return ret;
265 }
266
267 } // namespace sde_drm
268