1 /*
2 * Copyright (c) 2017-2018, 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 #define __CLASS__ "HWColorManagerDRM"
31
32 #include <array>
33 #include <map>
34 #include <cstring>
35 #include <vector>
36
37 #ifdef PP_DRM_ENABLE
38 #include <drm/msm_drm_pp.h>
39 #endif
40 #include <utils/debug.h>
41 #include "hw_color_manager_drm.h"
42
43 #ifdef PP_DRM_ENABLE
44 static const uint32_t kPgcDataMask = 0x3FF;
45 static const uint32_t kPgcShift = 16;
46
47 static const uint32_t kIgcDataMask = 0xFFF;
48 static const uint32_t kIgcShift = 16;
49
50 #ifdef DRM_MSM_PA_HSIC
51 static const uint32_t kPAHueMask = (1 << 12);
52 static const uint32_t kPASatMask = (1 << 13);
53 static const uint32_t kPAValMask = (1 << 14);
54 static const uint32_t kPAContrastMask = (1 << 15);
55 #endif
56
57 #ifdef DRM_MSM_SIXZONE
58 static const uint32_t kSixZoneP0Mask = 0x0FFF;
59 static const uint32_t kSixZoneP1Mask = 0x0FFF0FFF;
60 static const uint32_t kSixZoneHueMask = (1 << 16);
61 static const uint32_t kSixZoneSatMask = (1 << 17);
62 static const uint32_t kSixZoneValMask = (1 << 18);
63 #endif
64
65 #ifdef DRM_MSM_MEMCOL
66 static const uint32_t kMemColorProtHueMask = (1 << 0);
67 static const uint32_t kMemColorProtSatMask = (1 << 1);
68 static const uint32_t kMemColorProtValMask = (1 << 2);
69 static const uint32_t kMemColorProtContMask = (1 << 3);
70 static const uint32_t kMemColorProtSixZoneMask = (1 << 4);
71 static const uint32_t kMemColorProtBlendMask = (1 << 5);
72
73 static const uint32_t kMemColorProtMask = \
74 (kMemColorProtHueMask | kMemColorProtSatMask | kMemColorProtValMask | \
75 kMemColorProtContMask | kMemColorProtSixZoneMask | kMemColorProtBlendMask);
76
77 static const uint32_t kMemColorSkinMask = (1 << 19);
78 static const uint32_t kMemColorSkyMask = (1 << 20);
79 static const uint32_t kMemColorFolMask = (1 << 21);
80
81 static const uint32_t kSourceFeatureV5 = 5;
82 #endif
83 #endif
84
85 namespace sdm {
86
87 typedef std::map<uint32_t, std::vector<DRMPPFeatureID>> DrmPPFeatureMap;
88
89 static const DrmPPFeatureMap g_dspp_map = {
90 {kGlobalColorFeaturePcc, {kFeaturePcc}},
91 {kGlobalColorFeatureIgc, {kFeatureIgc}},
92 {kGlobalColorFeaturePgc, {kFeaturePgc}},
93 {kMixerColorFeatureGc, {kFeatureMixerGc}},
94 {kGlobalColorFeaturePaV2, {kFeaturePAHsic,
95 kFeaturePASixZone,
96 kFeaturePAMemColSkin,
97 kFeaturePAMemColSky,
98 kFeaturePAMemColFoliage,
99 kFeaturePAMemColProt}},
100 {kGlobalColorFeatureDither, {kFeatureDither}},
101 {kGlobalColorFeatureGamut, {kFeatureGamut}},
102 {kGlobalColorFeaturePADither, {kFeaturePADither}},
103 };
104
105 static const DrmPPFeatureMap g_vig_map = {
106 {kSourceColorFeatureIgc, {kFeatureVigIgc}},
107 {kSourceColorFeatureGamut, {kFeatureVigGamut}},
108 };
109
110 static const DrmPPFeatureMap g_dgm_map = {
111 {kSourceColorFeatureIgc, {kFeatureDgmIgc}},
112 {kSourceColorFeatureGc, {kFeatureDgmGc}},
113 };
114
115 static const std::array<const DrmPPFeatureMap *,
116 static_cast<int>(kPPBlockMax)> feature_map_list = {
117 {&g_dspp_map, &g_vig_map, &g_dgm_map}
118 };
119
120 DisplayError (*HWColorManagerDrm::pp_features_[])(const PPFeatureInfo &,
121 DRMPPFeatureInfo *) = {
122 [kFeaturePcc] = &HWColorManagerDrm::GetDrmPCC,
123 [kFeatureIgc] = &HWColorManagerDrm::GetDrmIGC,
124 [kFeaturePgc] = &HWColorManagerDrm::GetDrmPGC,
125 [kFeatureMixerGc] = &HWColorManagerDrm::GetDrmMixerGC,
126 [kFeaturePaV2] = NULL,
127 [kFeatureDither] = &HWColorManagerDrm::GetDrmDither,
128 [kFeatureGamut] = &HWColorManagerDrm::GetDrmGamut,
129 [kFeaturePADither] = &HWColorManagerDrm::GetDrmPADither,
130 [kFeaturePAHsic] = &HWColorManagerDrm::GetDrmPAHsic,
131 [kFeaturePASixZone] = &HWColorManagerDrm::GetDrmPASixZone,
132 [kFeaturePAMemColSkin] = &HWColorManagerDrm::GetDrmPAMemColSkin,
133 [kFeaturePAMemColSky] = &HWColorManagerDrm::GetDrmPAMemColSky,
134 [kFeaturePAMemColFoliage] = &HWColorManagerDrm::GetDrmPAMemColFoliage,
135 [kFeaturePAMemColProt] = &HWColorManagerDrm::GetDrmPAMemColProt,
136 [kFeatureDgmIgc] = &HWColorManagerDrm::GetDrmIGC,
137 [kFeatureDgmGc] = &HWColorManagerDrm::GetDrmPGC,
138 [kFeatureVigIgc] = &HWColorManagerDrm::GetDrmIGC,
139 [kFeatureVigGamut] = &HWColorManagerDrm::GetDrmGamut,
140 };
141
GetFeatureVersion(const DRMPPFeatureInfo & feature)142 uint32_t HWColorManagerDrm::GetFeatureVersion(const DRMPPFeatureInfo &feature) {
143 uint32_t version = PPFeatureVersion::kSDEPpVersionInvalid;
144
145 switch (feature.id) {
146 case kFeaturePcc:
147 if (feature.version == 1) {
148 version = PPFeatureVersion::kSDEPccV17;
149 } else if (feature.version == 4) {
150 version = PPFeatureVersion::kSDEPccV4;
151 }
152 break;
153 case kFeatureIgc:
154 if (feature.version == 3)
155 version = PPFeatureVersion::kSDEIgcV30;
156 break;
157 case kFeaturePgc:
158 if (feature.version == 1)
159 version = PPFeatureVersion::kSDEPgcV17;
160 break;
161 case kFeatureMixerGc:
162 version = PPFeatureVersion::kSDEPgcV17;
163 break;
164 case kFeaturePAHsic:
165 case kFeaturePASixZone:
166 case kFeaturePAMemColSkin:
167 case kFeaturePAMemColSky:
168 case kFeaturePAMemColFoliage:
169 case kFeaturePAMemColProt:
170 if (feature.version == 1)
171 version = PPFeatureVersion::kSDEPaV17;
172 break;
173 case kFeatureDither:
174 version = PPFeatureVersion::kSDEDitherV17;
175 break;
176 case kFeatureGamut:
177 if (feature.version == 1)
178 version = PPFeatureVersion::kSDEGamutV17;
179 else if (feature.version == 4)
180 version = PPFeatureVersion::kSDEGamutV4;
181 break;
182 case kFeaturePADither:
183 version = PPFeatureVersion::kSDEPADitherV17;
184 break;
185 default:
186 break;
187 }
188 return version;
189 }
190
ToDrmFeatureId(PPBlock block,uint32_t id,std::vector<DRMPPFeatureID> * drm_id)191 DisplayError HWColorManagerDrm::ToDrmFeatureId(PPBlock block, uint32_t id,
192 std::vector<DRMPPFeatureID> *drm_id) {
193 if (block < kDSPP || block >= kPPBlockMax) {
194 DLOGE("Invalid input parameter, block = %d", (int) block);
195 return kErrorParameters;
196 }
197
198 if (!drm_id) {
199 DLOGE("Invalid output parameter, block = %d", (int) block);
200 return kErrorParameters;
201 }
202
203 auto map = feature_map_list[block];
204 auto drm_features = map->find(id);
205 if (drm_features == map->end()) {
206 return kErrorParameters;
207 }
208 for (DRMPPFeatureID fid : drm_features->second)
209 drm_id->push_back(fid);
210
211 return kErrorNone;
212 }
213
GetDrmFeature(PPFeatureInfo * in_data,DRMPPFeatureInfo * out_data,bool force_disable)214 DisplayError HWColorManagerDrm::GetDrmFeature(PPFeatureInfo *in_data,
215 DRMPPFeatureInfo *out_data,
216 bool force_disable) {
217 DisplayError ret = kErrorParameters;
218 uint32_t flags = 0;
219
220 if (!in_data || !out_data) {
221 DLOGE("Invalid input parameter, in_data or out_data is NULL");
222 return ret;
223 }
224
225 /* Cache and override the enable_flags_ if force_disable is requested */
226 if (force_disable) {
227 flags = in_data->enable_flags_;
228 in_data->enable_flags_ = kOpsDisable;
229 }
230
231 if (pp_features_[out_data->id])
232 ret = pp_features_[out_data->id](*in_data, out_data);
233
234
235 /* Restore the original enable_flags_ */
236 if (force_disable) {
237 in_data->enable_flags_ = flags;
238 }
239
240 return ret;
241 }
242
FreeDrmFeatureData(DRMPPFeatureInfo * feature)243 void HWColorManagerDrm::FreeDrmFeatureData(DRMPPFeatureInfo *feature) {
244 if (feature && feature->payload) {
245 #ifdef PP_DRM_ENABLE
246 void *ptr = feature->payload;
247 #endif
248
249 switch (feature->id) {
250 case kFeaturePcc: {
251 #ifdef PP_DRM_ENABLE
252 drm_msm_pcc *pcc = reinterpret_cast<drm_msm_pcc *>(ptr);
253 delete pcc;
254 #endif
255 break;
256 }
257 case kFeatureIgc:
258 case kFeatureDgmIgc:
259 case kFeatureVigIgc: {
260 #ifdef PP_DRM_ENABLE
261 drm_msm_igc_lut *igc = reinterpret_cast<drm_msm_igc_lut *>(ptr);
262 delete igc;
263 #endif
264 break;
265 }
266 case kFeaturePgc:
267 case kFeatureDgmGc: {
268 #ifdef PP_DRM_ENABLE
269 drm_msm_pgc_lut *pgc = reinterpret_cast<drm_msm_pgc_lut *>(ptr);
270 delete pgc;
271 #endif
272 break;
273 }
274 case kFeatureDither: {
275 #ifdef PP_DRM_ENABLE
276 drm_msm_dither *dither = reinterpret_cast<drm_msm_dither *>(ptr);
277 delete dither;
278 #endif
279 break;
280 }
281 case kFeatureGamut:
282 case kFeatureVigGamut: {
283 #ifdef PP_DRM_ENABLE
284 drm_msm_3d_gamut *gamut = reinterpret_cast<drm_msm_3d_gamut *>(ptr);
285 delete gamut;
286 #endif
287 break;
288 }
289 case kFeaturePADither: {
290 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_DITHER)
291 drm_msm_pa_dither *pa_dither = reinterpret_cast<drm_msm_pa_dither *>(ptr);
292 delete pa_dither;
293 #endif
294 break;
295 }
296 case kFeaturePAHsic: {
297 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_HSIC)
298 drm_msm_pa_hsic *hsic = reinterpret_cast<drm_msm_pa_hsic *>(ptr);
299 delete hsic;
300 #endif
301 break;
302 }
303 case kFeaturePASixZone: {
304 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_SIXZONE)
305 drm_msm_sixzone *sixzone = reinterpret_cast<drm_msm_sixzone *>(ptr);
306 delete sixzone;
307 #endif
308 break;
309 }
310 case kFeaturePAMemColSkin:
311 case kFeaturePAMemColSky:
312 case kFeaturePAMemColFoliage:
313 case kFeaturePAMemColProt: {
314 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
315 drm_msm_memcol *memcol = reinterpret_cast<drm_msm_memcol *>(ptr);
316 delete memcol;
317 #endif
318 break;
319 }
320 case kFeatureMixerGc:
321 case kFeaturePaV2:
322 default: {
323 DLOGE("Invalid feature: %d\n", feature->id);
324 return;
325 }
326 }
327 feature->payload = nullptr;
328 }
329 }
330
GetDrmPCC(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)331 DisplayError HWColorManagerDrm::GetDrmPCC(const PPFeatureInfo &in_data,
332 DRMPPFeatureInfo *out_data) {
333 DisplayError ret = kErrorNone;
334 #ifdef PP_DRM_ENABLE
335 struct SDEPccV4Cfg *sde_pcc = NULL;
336 struct SDEPccV4Coeff *sde_pcc_coeffs = NULL;
337 struct drm_msm_pcc *mdp_pcc = NULL;
338 struct drm_msm_pcc_coeff *mdp_pcc_coeffs = NULL;
339 uint32_t i = 0;
340
341 switch (in_data.feature_version_) {
342 case PPFeatureVersion::kSDEPccV4:
343 sde_pcc = (struct SDEPccV4Cfg *) in_data.GetConfigData();
344 break;
345 default:
346 DLOGE("Unsupported pcc feature version: %d", in_data.feature_version_);
347 return kErrorParameters;
348 }
349
350 out_data->type = sde_drm::kPropBlob;
351 out_data->version = in_data.feature_version_;
352 out_data->payload_size = sizeof(struct drm_msm_pcc);
353
354 if (in_data.enable_flags_ & kOpsDisable) {
355 /* feature disable case */
356 out_data->payload = NULL;
357 return ret;
358 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
359 out_data->payload = NULL;
360 return kErrorParameters;
361 }
362
363 mdp_pcc = new drm_msm_pcc();
364 if (!mdp_pcc) {
365 DLOGE("Failed to allocate memory for pcc");
366 return kErrorMemory;
367 }
368
369 mdp_pcc->flags = 0;
370
371 for (i = 0; i < kMaxPCCChanel; i++) {
372 switch (i) {
373 case 0:
374 sde_pcc_coeffs = &sde_pcc->red;
375 mdp_pcc_coeffs = &mdp_pcc->r;
376 mdp_pcc->r_rr = sde_pcc_coeffs->rr;
377 mdp_pcc->r_gg = sde_pcc_coeffs->gg;
378 mdp_pcc->r_bb = sde_pcc_coeffs->bb;
379 break;
380 case 1:
381 sde_pcc_coeffs = &sde_pcc->green;
382 mdp_pcc_coeffs = &mdp_pcc->g;
383 mdp_pcc->g_rr = sde_pcc_coeffs->rr;
384 mdp_pcc->g_gg = sde_pcc_coeffs->gg;
385 mdp_pcc->g_bb = sde_pcc_coeffs->bb;
386 break;
387 case 2:
388 sde_pcc_coeffs = &sde_pcc->blue;
389 mdp_pcc_coeffs = &mdp_pcc->b;
390 mdp_pcc->b_rr = sde_pcc_coeffs->rr;
391 mdp_pcc->b_gg = sde_pcc_coeffs->gg;
392 mdp_pcc->b_bb = sde_pcc_coeffs->bb;
393 break;
394 }
395 mdp_pcc_coeffs->c = sde_pcc_coeffs->c;
396 mdp_pcc_coeffs->r = sde_pcc_coeffs->r;
397 mdp_pcc_coeffs->g = sde_pcc_coeffs->g;
398 mdp_pcc_coeffs->b = sde_pcc_coeffs->b;
399 mdp_pcc_coeffs->rg = sde_pcc_coeffs->rg;
400 mdp_pcc_coeffs->gb = sde_pcc_coeffs->gb;
401 mdp_pcc_coeffs->rb = sde_pcc_coeffs->rb;
402 mdp_pcc_coeffs->rgb = sde_pcc_coeffs->rgb;
403 }
404 out_data->payload = mdp_pcc;
405 #endif
406 return ret;
407 }
408
GetDrmIGC(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)409 DisplayError HWColorManagerDrm::GetDrmIGC(const PPFeatureInfo &in_data,
410 DRMPPFeatureInfo *out_data) {
411 DisplayError ret = kErrorNone;
412 #ifdef PP_DRM_ENABLE
413 struct SDEIgcV30LUTData *sde_igc;
414 struct drm_msm_igc_lut *mdp_igc;
415 uint32_t *c0_c1_data_ptr = NULL;
416 uint32_t *c2_data_ptr = NULL;
417
418 switch (in_data.feature_version_) {
419 case PPFeatureVersion::kSDEIgcV30:
420 case kSourceFeatureV5:
421 sde_igc = (struct SDEIgcV30LUTData *) in_data.GetConfigData();
422 break;
423 default:
424 DLOGE("Unsupported igc feature version: %d", in_data.feature_version_);
425 return kErrorParameters;
426 }
427
428 out_data->type = sde_drm::kPropBlob;
429 out_data->version = in_data.feature_version_;
430 out_data->payload_size = sizeof(struct drm_msm_igc_lut);
431
432 if (in_data.enable_flags_ & kOpsDisable) {
433 /* feature disable case */
434 out_data->payload = NULL;
435 return ret;
436 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
437 out_data->payload = NULL;
438 return kErrorParameters;
439 }
440
441 mdp_igc = new drm_msm_igc_lut();
442 if (!mdp_igc) {
443 DLOGE("Failed to allocate memory for igc");
444 return kErrorMemory;
445 }
446
447 mdp_igc->flags = IGC_DITHER_ENABLE;
448 mdp_igc->strength = sde_igc->strength;
449
450 c0_c1_data_ptr = reinterpret_cast<uint32_t*>(sde_igc->c0_c1_data);
451 c2_data_ptr = reinterpret_cast<uint32_t*>(sde_igc->c2_data);
452
453 if (!c0_c1_data_ptr || !c2_data_ptr) {
454 DLOGE("Invaid igc data pointer");
455 delete mdp_igc;
456 out_data->payload = NULL;
457 return kErrorParameters;
458 }
459
460 for (int i = 0; i < IGC_TBL_LEN; i++) {
461 mdp_igc->c0[i] = c0_c1_data_ptr[i] & kIgcDataMask;
462 mdp_igc->c1[i] = (c0_c1_data_ptr[i] >> kIgcShift) & kIgcDataMask;
463 mdp_igc->c2[i] = c2_data_ptr[i] & kIgcDataMask;
464 }
465 out_data->payload = mdp_igc;
466 #endif
467 return ret;
468 }
469
GetDrmPGC(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)470 DisplayError HWColorManagerDrm::GetDrmPGC(const PPFeatureInfo &in_data,
471 DRMPPFeatureInfo *out_data) {
472 DisplayError ret = kErrorNone;
473 #ifdef PP_DRM_ENABLE
474 struct SDEPgcLUTData *sde_pgc;
475 struct drm_msm_pgc_lut *mdp_pgc;
476
477 sde_pgc = (struct SDEPgcLUTData *)in_data.GetConfigData();
478
479 out_data->type = sde_drm::kPropBlob;
480 out_data->version = in_data.feature_version_;
481 out_data->payload_size = sizeof(struct drm_msm_pgc_lut);
482
483 if (in_data.enable_flags_ & kOpsDisable) {
484 /* feature disable case */
485 out_data->payload = NULL;
486 return ret;
487 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
488 out_data->payload = NULL;
489 return kErrorParameters;
490 }
491
492 mdp_pgc = new drm_msm_pgc_lut();
493 if (!mdp_pgc) {
494 DLOGE("Failed to allocate memory for pgc");
495 return kErrorMemory;
496 }
497
498 if ((in_data.enable_flags_ & kOpsEnable) &&
499 (in_data.feature_id_ == kGlobalColorFeaturePgc))
500 mdp_pgc->flags = PGC_8B_ROUND;
501 else
502 mdp_pgc->flags = 0;
503
504 for (int i = 0, j = 0; i < PGC_TBL_LEN; i++, j += 2) {
505 mdp_pgc->c0[i] = (sde_pgc->c0_data[j] & kPgcDataMask) |
506 (sde_pgc->c0_data[j + 1] & kPgcDataMask) << kPgcShift;
507 mdp_pgc->c1[i] = (sde_pgc->c1_data[j] & kPgcDataMask) |
508 (sde_pgc->c1_data[j + 1] & kPgcDataMask) << kPgcShift;
509 mdp_pgc->c2[i] = (sde_pgc->c2_data[j] & kPgcDataMask) |
510 (sde_pgc->c2_data[j + 1] & kPgcDataMask) << kPgcShift;
511 }
512 out_data->payload = mdp_pgc;
513 #endif
514 return ret;
515 }
516
GetDrmMixerGC(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)517 DisplayError HWColorManagerDrm::GetDrmMixerGC(const PPFeatureInfo &in_data,
518 DRMPPFeatureInfo *out_data) {
519 DisplayError ret = kErrorNone;
520 #ifdef PP_DRM_ENABLE
521 out_data->id = kPPFeaturesMax;
522 out_data->type = sde_drm::kPropBlob;
523 out_data->version = in_data.feature_version_;
524 #endif
525 return ret;
526 }
527
GetDrmPAHsic(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)528 DisplayError HWColorManagerDrm::GetDrmPAHsic(const PPFeatureInfo &in_data,
529 DRMPPFeatureInfo *out_data) {
530 DisplayError ret = kErrorNone;
531 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_HSIC)
532 struct SDEPaData *sde_pa;
533 struct drm_msm_pa_hsic *mdp_hsic;
534
535 sde_pa = (struct SDEPaData *) in_data.GetConfigData();
536
537 out_data->type = sde_drm::kPropBlob;
538 out_data->version = in_data.feature_version_;
539 out_data->payload_size = 0;
540 out_data->payload = NULL;
541
542 if (in_data.enable_flags_ & kOpsDisable) {
543 /* Complete PA features disable case */
544 return ret;
545 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
546 DLOGE("Invalid ops for pa hsic");
547 return kErrorParameters;
548 }
549
550 if (!(sde_pa->mode & (kPAHueMask | kPASatMask |
551 kPAValMask | kPAContrastMask))) {
552 /* PA HSIC feature disable case, but other PA features active */
553 return ret;
554 }
555
556 mdp_hsic = new drm_msm_pa_hsic();
557 if (!mdp_hsic) {
558 DLOGE("Failed to allocate memory for pa hsic");
559 return kErrorMemory;
560 }
561
562 mdp_hsic->flags = 0;
563
564 if (in_data.enable_flags_ & kPaHueEnable) {
565 mdp_hsic->flags |= PA_HSIC_HUE_ENABLE;
566 mdp_hsic->hue = sde_pa->hue_adj;
567 }
568 if (in_data.enable_flags_ & kPaSatEnable) {
569 mdp_hsic->flags |= PA_HSIC_SAT_ENABLE;
570 mdp_hsic->saturation = sde_pa->sat_adj;
571 }
572 if (in_data.enable_flags_ & kPaValEnable) {
573 mdp_hsic->flags |= PA_HSIC_VAL_ENABLE;
574 mdp_hsic->value = sde_pa->val_adj;
575 }
576 if (in_data.enable_flags_ & kPaContEnable) {
577 mdp_hsic->flags |= PA_HSIC_CONT_ENABLE;
578 mdp_hsic->contrast = sde_pa->cont_adj;
579 }
580
581 if (mdp_hsic->flags) {
582 out_data->payload = mdp_hsic;
583 out_data->payload_size = sizeof(struct drm_msm_pa_hsic);
584 } else {
585 /* PA HSIC configuration unchanged, no better return code available */
586 delete mdp_hsic;
587 ret = kErrorPermission;
588 }
589 #endif
590 return ret;
591 }
592
GetDrmPASixZone(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)593 DisplayError HWColorManagerDrm::GetDrmPASixZone(const PPFeatureInfo &in_data,
594 DRMPPFeatureInfo *out_data) {
595 DisplayError ret = kErrorNone;
596 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_SIXZONE)
597 struct SDEPaData *sde_pa;
598
599 sde_pa = (struct SDEPaData *) in_data.GetConfigData();
600
601 out_data->type = sde_drm::kPropBlob;
602 out_data->version = in_data.feature_version_;
603 out_data->payload_size = 0;
604 out_data->payload = NULL;
605
606 if (in_data.enable_flags_ & kOpsDisable) {
607 /* Complete PA features disable case */
608 return ret;
609 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
610 DLOGE("Invalid ops for six zone");
611 return kErrorParameters;
612 }
613
614 if (!(sde_pa->mode & (kSixZoneHueMask | kSixZoneSatMask |
615 kSixZoneValMask))) {
616 /* PA SixZone feature disable case, but other PA features active */
617 return ret;
618 }
619
620 if (in_data.enable_flags_ & kPaSixZoneEnable) {
621 struct drm_msm_sixzone *mdp_sixzone = NULL;
622
623 if ((!sde_pa->six_zone_curve_p0 || !sde_pa->six_zone_curve_p1) ||
624 (sde_pa->six_zone_len != SIXZONE_LUT_SIZE)) {
625 DLOGE("Invaid sixzone curve");
626 return kErrorParameters;
627 }
628
629 mdp_sixzone = new drm_msm_sixzone();
630 if (!mdp_sixzone) {
631 DLOGE("Failed to allocate memory for six zone");
632 return kErrorMemory;
633 }
634
635 mdp_sixzone->flags = 0;
636
637 if (sde_pa->mode & kSixZoneHueMask) {
638 mdp_sixzone->flags |= SIXZONE_HUE_ENABLE;
639 }
640 if (sde_pa->mode & kSixZoneSatMask) {
641 mdp_sixzone->flags |= SIXZONE_SAT_ENABLE;
642 }
643 if (sde_pa->mode & kSixZoneValMask) {
644 mdp_sixzone->flags |= SIXZONE_VAL_ENABLE;
645 }
646
647 mdp_sixzone->threshold = sde_pa->six_zone_thresh;
648 mdp_sixzone->adjust_p0 = sde_pa->six_zone_adj_p0;
649 mdp_sixzone->adjust_p1 = sde_pa->six_zone_adj_p1;
650 mdp_sixzone->sat_hold = sde_pa->six_zone_sat_hold;
651 mdp_sixzone->val_hold = sde_pa->six_zone_val_hold;
652
653 for (int i = 0; i < SIXZONE_LUT_SIZE; i++) {
654 mdp_sixzone->curve[i].p0 = sde_pa->six_zone_curve_p0[i] & kSixZoneP0Mask;
655 mdp_sixzone->curve[i].p1 = sde_pa->six_zone_curve_p1[i] & kSixZoneP1Mask;
656 }
657 out_data->payload = mdp_sixzone;
658 out_data->payload_size = sizeof(struct drm_msm_sixzone);
659 } else {
660 /* PA SixZone configuration unchanged, no better return code available */
661 ret = kErrorPermission;
662 }
663
664 #endif
665 return ret;
666 }
667
GetDrmPAMemColSkin(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)668 DisplayError HWColorManagerDrm::GetDrmPAMemColSkin(const PPFeatureInfo &in_data,
669 DRMPPFeatureInfo *out_data) {
670 DisplayError ret = kErrorNone;
671 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
672 struct SDEPaData *sde_pa;
673
674 sde_pa = (struct SDEPaData *) in_data.GetConfigData();
675
676 out_data->type = sde_drm::kPropBlob;
677 out_data->version = in_data.feature_version_;
678 out_data->payload_size = 0;
679 out_data->payload = NULL;
680
681 if (in_data.enable_flags_ & kOpsDisable) {
682 /* Complete PA features disable case */
683 return ret;
684 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
685 DLOGE("Invalid ops for memory color skin");
686 return kErrorParameters;
687 }
688
689 if (!(sde_pa->mode & kMemColorSkinMask)) {
690 /* PA MemColSkin feature disable case, but other PA features active */
691 return ret;
692 }
693
694 if (in_data.enable_flags_ & kPaSkinEnable) {
695 struct drm_msm_memcol *mdp_memcol = NULL;
696 struct SDEPaMemColorData *pa_memcol = &sde_pa->skin;
697
698 mdp_memcol = new drm_msm_memcol();
699 if (!mdp_memcol) {
700 DLOGE("Failed to allocate memory for memory color skin");
701 return kErrorMemory;
702 }
703
704 mdp_memcol->prot_flags = 0;
705 mdp_memcol->color_adjust_p0 = pa_memcol->adjust_p0;
706 mdp_memcol->color_adjust_p1 = pa_memcol->adjust_p1;
707 mdp_memcol->color_adjust_p2 = pa_memcol->adjust_p2;
708 mdp_memcol->blend_gain = pa_memcol->blend_gain;
709 mdp_memcol->sat_hold = pa_memcol->sat_hold;
710 mdp_memcol->val_hold = pa_memcol->val_hold;
711 mdp_memcol->hue_region = pa_memcol->hue_region;
712 mdp_memcol->sat_region = pa_memcol->sat_region;
713 mdp_memcol->val_region = pa_memcol->val_region;
714
715 out_data->payload = mdp_memcol;
716 out_data->payload_size = sizeof(struct drm_msm_memcol);
717 } else {
718 /* PA MemColSkin configuration unchanged, no better return code available */
719 ret = kErrorPermission;
720 }
721 #endif
722 return ret;
723 }
724
GetDrmPAMemColSky(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)725 DisplayError HWColorManagerDrm::GetDrmPAMemColSky(const PPFeatureInfo &in_data,
726 DRMPPFeatureInfo *out_data) {
727 DisplayError ret = kErrorNone;
728 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
729 struct SDEPaData *sde_pa;
730
731 sde_pa = (struct SDEPaData *) in_data.GetConfigData();
732
733 out_data->type = sde_drm::kPropBlob;
734 out_data->version = in_data.feature_version_;
735 out_data->payload_size = 0;
736 out_data->payload = NULL;
737
738 if (in_data.enable_flags_ & kOpsDisable) {
739 /* Complete PA features disable case */
740 return ret;
741 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
742 DLOGE("Invalid ops for memory color sky");
743 return kErrorParameters;
744 }
745
746 if (!(sde_pa->mode & kMemColorSkyMask)) {
747 /* PA MemColSky feature disable case, but other PA features active */
748 return ret;
749 }
750
751 if (in_data.enable_flags_ & kPaSkyEnable) {
752 struct drm_msm_memcol *mdp_memcol = NULL;
753 struct SDEPaMemColorData *pa_memcol = &sde_pa->sky;
754
755 mdp_memcol = new drm_msm_memcol();
756 if (!mdp_memcol) {
757 DLOGE("Failed to allocate memory for memory color sky");
758 return kErrorMemory;
759 }
760
761 mdp_memcol->prot_flags = 0;
762 mdp_memcol->color_adjust_p0 = pa_memcol->adjust_p0;
763 mdp_memcol->color_adjust_p1 = pa_memcol->adjust_p1;
764 mdp_memcol->color_adjust_p2 = pa_memcol->adjust_p2;
765 mdp_memcol->blend_gain = pa_memcol->blend_gain;
766 mdp_memcol->sat_hold = pa_memcol->sat_hold;
767 mdp_memcol->val_hold = pa_memcol->val_hold;
768 mdp_memcol->hue_region = pa_memcol->hue_region;
769 mdp_memcol->sat_region = pa_memcol->sat_region;
770 mdp_memcol->val_region = pa_memcol->val_region;
771
772 out_data->payload = mdp_memcol;
773 out_data->payload_size = sizeof(struct drm_msm_memcol);
774 } else {
775 /* PA MemColSky configuration unchanged, no better return code available */
776 ret = kErrorPermission;
777 }
778 #endif
779 return ret;
780 }
781
GetDrmPAMemColFoliage(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)782 DisplayError HWColorManagerDrm::GetDrmPAMemColFoliage(const PPFeatureInfo &in_data,
783 DRMPPFeatureInfo *out_data) {
784 DisplayError ret = kErrorNone;
785 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
786 struct SDEPaData *sde_pa;
787
788 sde_pa = (struct SDEPaData *) in_data.GetConfigData();
789
790 out_data->type = sde_drm::kPropBlob;
791 out_data->version = in_data.feature_version_;
792 out_data->payload_size = 0;
793 out_data->payload = NULL;
794
795 if (in_data.enable_flags_ & kOpsDisable) {
796 /* Complete PA features disable case */
797 return ret;
798 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
799 DLOGE("Invalid ops for memory color foliage");
800 return kErrorParameters;
801 }
802
803 if (!(sde_pa->mode & kMemColorFolMask)) {
804 /* PA MemColFoliage feature disable case, but other PA features active */
805 return ret;
806 }
807
808 if (in_data.enable_flags_ & kPaFoliageEnable) {
809 struct drm_msm_memcol *mdp_memcol = NULL;
810 struct SDEPaMemColorData *pa_memcol = &sde_pa->foliage;
811
812 mdp_memcol = new drm_msm_memcol();
813 if (!mdp_memcol) {
814 DLOGE("Failed to allocate memory for memory color foliage");
815 return kErrorMemory;
816 }
817
818 mdp_memcol->prot_flags = 0;
819 mdp_memcol->color_adjust_p0 = pa_memcol->adjust_p0;
820 mdp_memcol->color_adjust_p1 = pa_memcol->adjust_p1;
821 mdp_memcol->color_adjust_p2 = pa_memcol->adjust_p2;
822 mdp_memcol->blend_gain = pa_memcol->blend_gain;
823 mdp_memcol->sat_hold = pa_memcol->sat_hold;
824 mdp_memcol->val_hold = pa_memcol->val_hold;
825 mdp_memcol->hue_region = pa_memcol->hue_region;
826 mdp_memcol->sat_region = pa_memcol->sat_region;
827 mdp_memcol->val_region = pa_memcol->val_region;
828
829 out_data->payload = mdp_memcol;
830 out_data->payload_size = sizeof(struct drm_msm_memcol);
831 } else {
832 /* PA MemColFoliage configuration unchanged, no better return code available */
833 ret = kErrorPermission;
834 }
835 #endif
836 return ret;
837 }
838
GetDrmPAMemColProt(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)839 DisplayError HWColorManagerDrm::GetDrmPAMemColProt(const PPFeatureInfo &in_data,
840 DRMPPFeatureInfo *out_data) {
841 DisplayError ret = kErrorNone;
842 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_MEMCOL)
843 struct SDEPaData *sde_pa;
844 struct drm_msm_memcol *mdp_memcol;
845
846 sde_pa = (struct SDEPaData *) in_data.GetConfigData();
847
848 out_data->type = sde_drm::kPropBlob;
849 out_data->version = in_data.feature_version_;
850 out_data->payload_size = sizeof(struct drm_msm_memcol);
851
852 if (in_data.enable_flags_ & kOpsDisable) {
853 /* Complete PA features disable case */
854 out_data->payload = NULL;
855 return ret;
856 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
857 out_data->payload = NULL;
858 return kErrorParameters;
859 }
860
861 out_data->payload = NULL;
862 if (!(sde_pa->mode & kMemColorProtMask)) {
863 /* PA MemColProt feature disable case, but other PA features active */
864 return ret;
865 }
866
867 mdp_memcol = new drm_msm_memcol();
868 if (!mdp_memcol) {
869 DLOGE("Failed to allocate memory for memory color prot");
870 return kErrorMemory;
871 }
872
873 mdp_memcol->prot_flags = 0;
874
875 if (sde_pa->mode & kMemColorProtMask) {
876 mdp_memcol->prot_flags |= (sde_pa->mode & kMemColorProtMask);
877 }
878
879 out_data->payload = mdp_memcol;
880
881 #endif
882 return ret;
883 }
884
GetDrmDither(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)885 DisplayError HWColorManagerDrm::GetDrmDither(const PPFeatureInfo &in_data,
886 DRMPPFeatureInfo *out_data) {
887 DisplayError ret = kErrorNone;
888 #ifdef PP_DRM_ENABLE
889 struct SDEDitherCfg *sde_dither = NULL;
890 struct drm_msm_dither *mdp_dither = NULL;
891
892 sde_dither = (struct SDEDitherCfg *)in_data.GetConfigData();
893 out_data->type = sde_drm::kPropBlob;
894 out_data->version = in_data.feature_version_;
895 out_data->payload_size = sizeof(struct drm_msm_dither);
896
897 if (in_data.enable_flags_ & kOpsDisable) {
898 out_data->payload = NULL;
899 return ret;
900 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
901 out_data->payload = NULL;
902 return kErrorParameters;
903 }
904
905 mdp_dither = new drm_msm_dither();
906 if (!mdp_dither) {
907 DLOGE("Failed to allocate memory for dither");
908 return kErrorMemory;
909 }
910
911 mdp_dither->flags = 0;
912 std::memcpy(mdp_dither->matrix, sde_dither->dither_matrix,
913 sizeof(sde_dither->dither_matrix));
914 mdp_dither->temporal_en = sde_dither->temporal_en;
915 mdp_dither->c0_bitdepth = sde_dither->g_y_depth;
916 mdp_dither->c1_bitdepth = sde_dither->b_cb_depth;
917 mdp_dither->c2_bitdepth = sde_dither->r_cr_depth;
918 mdp_dither->c3_bitdepth = 0;
919 out_data->payload = mdp_dither;
920 #endif
921 return ret;
922 }
923
GetDrmGamut(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)924 DisplayError HWColorManagerDrm::GetDrmGamut(const PPFeatureInfo &in_data,
925 DRMPPFeatureInfo *out_data) {
926 DisplayError ret = kErrorNone;
927 #ifdef PP_DRM_ENABLE
928 struct SDEGamutCfg *sde_gamut = NULL;
929 struct drm_msm_3d_gamut *mdp_gamut = NULL;
930 uint32_t size = 0;
931
932 sde_gamut = (struct SDEGamutCfg *)in_data.GetConfigData();
933
934 out_data->type = sde_drm::kPropBlob;
935 out_data->version = in_data.feature_version_;
936 out_data->payload_size = sizeof(struct drm_msm_3d_gamut);
937 if (in_data.enable_flags_ & kOpsDisable) {
938 /* feature disable case */
939 out_data->payload = NULL;
940 return ret;
941 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
942 out_data->payload = NULL;
943 return kErrorParameters;
944 }
945
946 mdp_gamut = new drm_msm_3d_gamut();
947 if (!mdp_gamut) {
948 DLOGE("Failed to allocate memory for gamut");
949 return kErrorMemory;
950 }
951
952 if (sde_gamut->map_en)
953 mdp_gamut->flags = GAMUT_3D_MAP_EN;
954 else
955 mdp_gamut->flags = 0;
956
957 switch (sde_gamut->mode) {
958 case SDEGamutCfgWrapper::GAMUT_FINE_MODE:
959 mdp_gamut->mode = GAMUT_3D_MODE_17;
960 size = GAMUT_3D_MODE17_TBL_SZ;
961 break;
962 case SDEGamutCfgWrapper::GAMUT_COARSE_MODE:
963 mdp_gamut->mode = GAMUT_3D_MODE_5;
964 size = GAMUT_3D_MODE5_TBL_SZ;
965 break;
966 case SDEGamutCfgWrapper::GAMUT_COARSE_MODE_13:
967 mdp_gamut->mode = GAMUT_3D_MODE_13;
968 size = GAMUT_3D_MODE13_TBL_SZ;
969 break;
970 default:
971 DLOGE("Invalid gamut mode %d", sde_gamut->mode);
972 delete mdp_gamut;
973 return kErrorParameters;
974 }
975
976 if (sde_gamut->map_en) {
977 std::memcpy(&mdp_gamut->scale_off[0][0], sde_gamut->scale_off_data[0],
978 sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
979 std::memcpy(&mdp_gamut->scale_off[1][0], sde_gamut->scale_off_data[1],
980 sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
981 std::memcpy(&mdp_gamut->scale_off[2][0], sde_gamut->scale_off_data[2],
982 sizeof(uint32_t) * GAMUT_3D_SCALE_OFF_SZ);
983 }
984
985 for (uint32_t row = 0; row < GAMUT_3D_TBL_NUM; row++) {
986 for (uint32_t col = 0; col < size; col++) {
987 mdp_gamut->col[row][col].c0 = sde_gamut->c0_data[row][col];
988 mdp_gamut->col[row][col].c2_c1 = sde_gamut->c1_c2_data[row][col];
989 }
990 }
991 out_data->payload = mdp_gamut;
992 #endif
993 return ret;
994 }
995
GetDrmPADither(const PPFeatureInfo & in_data,DRMPPFeatureInfo * out_data)996 DisplayError HWColorManagerDrm::GetDrmPADither(const PPFeatureInfo &in_data,
997 DRMPPFeatureInfo *out_data) {
998 DisplayError ret = kErrorNone;
999 #if defined(PP_DRM_ENABLE) && defined(DRM_MSM_PA_DITHER)
1000 struct SDEPADitherData* sde_dither;
1001 struct drm_msm_pa_dither* mdp_dither;
1002
1003 out_data->type = sde_drm::kPropBlob;
1004 out_data->version = in_data.feature_version_;
1005
1006 out_data->payload_size = sizeof(struct drm_msm_pa_dither);
1007 if (in_data.enable_flags_ & kOpsDisable) {
1008 /* feature disable case */
1009 out_data->payload = NULL;
1010 return ret;
1011 } else if (!(in_data.enable_flags_ & kOpsEnable)) {
1012 out_data->payload = NULL;
1013 return kErrorParameters;
1014 }
1015
1016 sde_dither = (struct SDEPADitherData *)in_data.GetConfigData();
1017 if (sde_dither->matrix_size != DITHER_MATRIX_SZ) {
1018 DLOGE("Invalid dither matrix size %d, exp sz %d",
1019 sde_dither->matrix_size, DITHER_MATRIX_SZ);
1020 return kErrorParameters;
1021 }
1022
1023 mdp_dither = new drm_msm_pa_dither();
1024 if (!mdp_dither) {
1025 DLOGE("Failed to allocate memory for dither");
1026 return kErrorMemory;
1027 }
1028
1029 mdp_dither->flags = 0;
1030 mdp_dither->strength = sde_dither->strength;
1031 mdp_dither->offset_en = sde_dither->offset_en;
1032 std::memcpy(&mdp_dither->matrix[0],
1033 reinterpret_cast<void*>(sde_dither->matrix_data_addr),
1034 sizeof(uint32_t) * DITHER_MATRIX_SZ);
1035 out_data->payload = mdp_dither;
1036 #endif
1037 return ret;
1038 }
1039
1040 } // namespace sdm
1041