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