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