• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hdmi_core.h"
10 #include "device_resource_if.h"
11 #include "hdf_log.h"
12 #include "hdmi_dispatch.h"
13 #include "osal_mem.h"
14 #include "osal_time.h"
15 #include "securec.h"
16 
17 #define HDF_LOG_TAG hdmi_core_c
18 
HdmiCntlrAllocDev(struct HdmiCntlr * cntlr)19 int32_t HdmiCntlrAllocDev(struct HdmiCntlr *cntlr)
20 {
21     struct HdmiDevice *dev = (struct HdmiDevice *)OsalMemCalloc(sizeof(struct HdmiDevice));
22 
23     if (dev == NULL) {
24         HDF_LOGE("Hdmi alloc dev fail");
25         return HDF_ERR_MALLOC_FAIL;
26     }
27 
28     dev->cntlr = cntlr;
29     cntlr->hdmi = dev;
30     return HDF_SUCCESS;
31 }
32 
HdmiCntlrFreeDev(struct HdmiCntlr * cntlr)33 void HdmiCntlrFreeDev(struct HdmiCntlr *cntlr)
34 {
35     if (cntlr == NULL || cntlr->hdmi == NULL) {
36         return;
37     }
38 
39     OsalMemFree(cntlr->hdmi);
40     cntlr->hdmi = NULL;
41 }
42 
HdmiCecInit(struct HdmiCntlr * cntlr)43 static void HdmiCecInit(struct HdmiCntlr *cntlr)
44 {
45     if (cntlr == NULL) {
46         return;
47     }
48     if (cntlr->cap.baseCap.bits.cec == 0) {
49         HDF_LOGD("not support cec");
50         return;
51     }
52 
53     if (cntlr->cec == NULL) {
54         cntlr->cec = (struct HdmiCec *)OsalMemCalloc(sizeof(struct HdmiCec));
55         if (cntlr->cec == NULL) {
56             HDF_LOGE("cec malloc fail");
57             return;
58         }
59     }
60     HDF_LOGE("HdmiCecInit, success.");
61     cntlr->cec->priv = (void *)cntlr;
62 }
63 
HdmiCecDeinit(struct HdmiCntlr * cntlr)64 static void HdmiCecDeinit(struct HdmiCntlr *cntlr)
65 {
66     if (cntlr == NULL) {
67         return;
68     }
69     if (cntlr->cec != NULL) {
70         OsalMemFree(cntlr->cec);
71         cntlr->cec = NULL;
72     }
73 }
74 
HdmiDdcInit(struct HdmiCntlr * cntlr)75 static void HdmiDdcInit(struct HdmiCntlr *cntlr)
76 {
77     int32_t ret;
78 
79     if (cntlr == NULL) {
80         HDF_LOGE("ddc init: param is invalid");
81         return;
82     }
83     cntlr->ddc.priv = (void *)cntlr;
84     if (cntlr->ddc.init == true) {
85         return;
86     }
87     ret = OsalMutexInit(&(cntlr->ddc.ddcMutex));
88     if (ret != HDF_SUCCESS) {
89         HDF_LOGE("HdmiDdcInit: mutex init fail!");
90         return;
91     }
92     HDF_LOGE("HdmiDdcInit, success.");
93     cntlr->ddc.init = true;
94 }
95 
HdmiDdcDeinit(struct HdmiCntlr * cntlr)96 static void HdmiDdcDeinit(struct HdmiCntlr *cntlr)
97 {
98     if (cntlr == NULL) {
99         HDF_LOGE("ddc init: param is invalid");
100         return;
101     }
102 
103     (void)OsalMutexDestroy(&(cntlr->ddc.ddcMutex));
104     if (memset_s(&(cntlr->ddc), sizeof(struct HdmiDdc), 0, sizeof(struct HdmiDdc)) != EOK) {
105         HDF_LOGE("deinit ddc, memset_s fail.");
106     }
107     cntlr->ddc.priv = NULL;
108     cntlr->ddc.init = false;
109 }
110 
HdmiFrlInit(struct HdmiCntlr * cntlr)111 static void HdmiFrlInit(struct HdmiCntlr *cntlr)
112 {
113     if (cntlr == NULL) {
114         return;
115     }
116     if (cntlr->cap.baseCap.bits.frl == 0) {
117         HDF_LOGD("not support frl");
118         return;
119     }
120 
121     if (cntlr->frl == NULL) {
122         cntlr->frl = (struct HdmiFrl *)OsalMemCalloc(sizeof(struct HdmiFrl));
123         if (cntlr->frl == NULL) {
124             HDF_LOGE("frl malloc fail");
125             return;
126         }
127     }
128     HDF_LOGE("HdmiFrlInit, success.");
129     cntlr->frl->priv = (void *)cntlr;
130 }
131 
HdmiFrlDeinit(struct HdmiCntlr * cntlr)132 static void HdmiFrlDeinit(struct HdmiCntlr *cntlr)
133 {
134     if (cntlr == NULL) {
135         return;
136     }
137     if (cntlr->frl != NULL) {
138         OsalMemFree(cntlr->frl);
139         cntlr->frl = NULL;
140     }
141 }
142 
HdmiHdcpInit(struct HdmiCntlr * cntlr)143 static void HdmiHdcpInit(struct HdmiCntlr *cntlr)
144 {
145     int32_t ret;
146 
147     if (cntlr == NULL) {
148         return;
149     }
150     if (cntlr->cap.baseCap.bits.hdcp == 0) {
151         HDF_LOGD("not support hdcp");
152         return;
153     }
154 
155     if (cntlr->hdcp == NULL) {
156         cntlr->hdcp = (struct HdmiHdcp *)OsalMemCalloc(sizeof(struct HdmiHdcp));
157         if (cntlr->hdcp == NULL) {
158             HDF_LOGE("hdcp malloc fail");
159             return;
160         }
161         ret = OsalMutexInit(&(cntlr->hdcp->hdcpMutex));
162         if (ret != HDF_SUCCESS) {
163             HDF_LOGE("HdmiHdcpInit: mutex init fail!");
164             return;
165         }
166     }
167     HDF_LOGE("HdmiHdcpInit, success.");
168     cntlr->hdcp->priv = (void *)cntlr;
169 }
170 
HdmiHdcpDeinit(struct HdmiCntlr * cntlr)171 static void HdmiHdcpDeinit(struct HdmiCntlr *cntlr)
172 {
173     if (cntlr == NULL) {
174         return;
175     }
176     if (cntlr->hdcp != NULL) {
177         HdmiHdcpClose(cntlr->hdcp);
178         OsalMemFree(cntlr->hdcp);
179         cntlr->hdcp = NULL;
180     }
181 }
182 
HdmiHdrInit(struct HdmiCntlr * cntlr)183 static void HdmiHdrInit(struct HdmiCntlr *cntlr)
184 {
185     if (cntlr == NULL) {
186         return;
187     }
188     if (cntlr->cap.baseCap.bits.hdr == 0) {
189         HDF_LOGD("not support hdr");
190         return;
191     }
192 
193     if (cntlr->hdr == NULL) {
194         cntlr->hdr = (struct HdmiHdr *)OsalMemCalloc(sizeof(struct HdmiHdr));
195         if (cntlr->hdr == NULL) {
196             HDF_LOGE("hdr malloc fail");
197             return;
198         }
199     }
200     HDF_LOGE("HdmiHdrInit, success.");
201     cntlr->hdr->priv = (void *)cntlr;
202 }
203 
HdmiHdrDeinit(struct HdmiCntlr * cntlr)204 static void HdmiHdrDeinit(struct HdmiCntlr *cntlr)
205 {
206     if (cntlr == NULL) {
207         return;
208     }
209     if (cntlr->hdr != NULL) {
210         OsalMemFree(cntlr->hdr);
211         cntlr->hdr = NULL;
212     }
213 }
214 
HdmiInfoFrameInit(struct HdmiCntlr * cntlr)215 static void HdmiInfoFrameInit(struct HdmiCntlr *cntlr)
216 {
217     if (cntlr == NULL) {
218         return;
219     }
220     HDF_LOGE("HdmiInfoFrameInit, success.");
221     cntlr->infoFrame.priv = (void *)cntlr;
222 }
223 
HdmiInfoFrameDeInit(struct HdmiCntlr * cntlr)224 static void HdmiInfoFrameDeInit(struct HdmiCntlr *cntlr)
225 {
226     if (cntlr == NULL) {
227         return;
228     }
229 
230     if (memset_s(&(cntlr->infoFrame), sizeof(struct HdmiInfoFrame), 0, sizeof(struct HdmiInfoFrame)) != EOK) {
231         HDF_LOGE("deinit infoFrame, memset_s fail.");
232     }
233     cntlr->infoFrame.priv = NULL;
234 }
235 
HdmiScdcInit(struct HdmiCntlr * cntlr)236 static void HdmiScdcInit(struct HdmiCntlr *cntlr)
237 {
238     if (cntlr == NULL) {
239         return;
240     }
241     if (cntlr->cap.baseCap.bits.scdc == 0) {
242         HDF_LOGD("not support scdc");
243         return;
244     }
245 
246     if (cntlr->scdc == NULL) {
247         cntlr->scdc = (struct HdmiScdc *)OsalMemCalloc(sizeof(struct HdmiScdc));
248         if (cntlr->scdc == NULL) {
249             HDF_LOGE("scdc malloc fail");
250             return;
251         }
252     }
253     HDF_LOGE("HdmiScdcInit, success.");
254     cntlr->scdc->priv = (void *)cntlr;
255 }
256 
HdmiScdcDeinit(struct HdmiCntlr * cntlr)257 static void HdmiScdcDeinit(struct HdmiCntlr *cntlr)
258 {
259     if (cntlr == NULL) {
260         return;
261     }
262     if (cntlr->scdc != NULL) {
263         OsalMemFree(cntlr->scdc);
264         cntlr->scdc = NULL;
265     }
266 }
267 
HdmiCntlrInit(struct HdmiCntlr * cntlr)268 static int32_t HdmiCntlrInit(struct HdmiCntlr *cntlr)
269 {
270     int32_t ret;
271 
272     if (cntlr == NULL) {
273         return HDF_ERR_INVALID_OBJECT;
274     }
275 
276     if (cntlr->hdfDevObj == NULL) {
277         HDF_LOGE("HdmiCntlrInit: no HdfDeviceObject attached!");
278         return HDF_ERR_INVALID_OBJECT;
279     }
280 
281     ret = OsalMutexInit(&cntlr->mutex);
282     if (ret != HDF_SUCCESS) {
283         HDF_LOGE("HdmiCntlrInit: mutex init fail!");
284         return ret;
285     }
286 
287     cntlr->msgQueue = PlatformQueueCreate(HdmiEventMsgHandleDefault, "PlatformHdmiWorkerThread", cntlr);
288     if (cntlr->msgQueue == NULL) {
289         HDF_LOGE("HdmiCntlrInit: failed to create msg queue!");
290         return HDF_PLT_ERR_OS_API;
291     }
292     ret = PlatformQueueStart(cntlr->msgQueue);
293     if (ret != HDF_SUCCESS) {
294         HDF_LOGE("HdmiCntlrInit: failed to start msg queue!");
295         PlatformQueueDestroy(cntlr->msgQueue);
296         return ret;
297     }
298 
299     cntlr->service.Dispatch = HdmiIoDispatch;
300     cntlr->hdfDevObj->service = &(cntlr->service);
301     cntlr->device.number = (int32_t)cntlr->deviceIndex;
302     cntlr->device.hdfDev = cntlr->hdfDevObj;
303     HdmiInfoFrameInit(cntlr);
304     HdmiDdcInit(cntlr);
305     return HDF_SUCCESS;
306 }
307 
HdmiCntlrUninit(struct HdmiCntlr * cntlr)308 static void HdmiCntlrUninit(struct HdmiCntlr *cntlr)
309 {
310     if (cntlr != NULL) {
311         HdmiInfoFrameDeInit(cntlr);
312         HdmiScdcDeinit(cntlr);
313         HdmiDdcDeinit(cntlr);
314         HdmiCecDeinit(cntlr);
315         HdmiFrlDeinit(cntlr);
316         HdmiHdcpDeinit(cntlr);
317         HdmiCntlrFreeDev(cntlr);
318         (void)OsalMutexDestroy(&cntlr->mutex);
319     }
320 }
321 
HdmiCntlrAdd(struct HdmiCntlr * cntlr)322 int32_t HdmiCntlrAdd(struct HdmiCntlr *cntlr)
323 {
324     int32_t ret;
325 
326     if (cntlr == NULL) {
327         return HDF_ERR_INVALID_OBJECT;
328     }
329 
330     ret = HdmiCntlrInit(cntlr);
331     if (ret != HDF_SUCCESS) {
332         return ret;
333     }
334 
335     cntlr->device.manager = PlatformManagerGet(PLATFORM_MODULE_HDMI);
336     ret = PlatformDeviceAdd(&cntlr->device);
337     if (ret != HDF_SUCCESS) {
338         HDF_LOGE("HdmiCntlrAdd: device add fail!");
339         HdmiCntlrUninit(cntlr);
340         return ret;
341     }
342     return HDF_SUCCESS;
343 }
344 
HdmiCntlrRemove(struct HdmiCntlr * cntlr)345 void HdmiCntlrRemove(struct HdmiCntlr *cntlr)
346 {
347     if (cntlr != NULL) {
348         HdmiCntlrUninit(cntlr);
349         PlatformDeviceDel(&cntlr->device);
350     }
351 }
352 
HdmiCntlrParseVideoCaps(struct HdmiCntlr * cntlr,struct DeviceResourceIface * drsOps,const struct DeviceResourceNode * node)353 static int32_t HdmiCntlrParseVideoCaps(struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps,
354     const struct DeviceResourceNode *node)
355 {
356     int32_t ret;
357 
358     ret = drsOps->GetUint32(node, "maxTmdsClock", &(cntlr->cap.maxTmdsClock), 0);
359     if (ret != HDF_SUCCESS) {
360         HDF_LOGE("HdmiCntlrParseVideoCaps: read maxTmdsClock fail!");
361         return ret;
362     }
363 
364     ret = drsOps->GetUint32(node, "defTmdsClock", &(cntlr->cap.defTmdsClock), 0);
365     if (ret != HDF_SUCCESS) {
366         HDF_LOGE("HdmiCntlrParseVideoCaps: read defTmdsClock fail!");
367         return ret;
368     }
369 
370     ret = drsOps->GetUint32(node, "maxFrlRate", &(cntlr->cap.maxFrlRate), 0);
371     if (ret != HDF_SUCCESS) {
372         HDF_LOGE("HdmiCntlrParseVideoCaps: read maxFrlRate fail!");
373         return ret;
374     }
375 
376     ret = drsOps->GetUint32(node, "videoTiming", &(cntlr->cap.videoTiming), 0);
377     if (ret != HDF_SUCCESS) {
378         HDF_LOGE("HdmiCntlrParseVideoCaps: read videoTiming fail!");
379         return ret;
380     }
381 
382     ret = drsOps->GetUint32(node, "quantization", &(cntlr->cap.quantization), 0);
383     if (ret != HDF_SUCCESS) {
384         HDF_LOGE("HdmiCntlrParseVideoCaps: read quantization fail!");
385         return ret;
386     }
387 
388     ret = drsOps->GetUint32(node, "colorSpace", &(cntlr->cap.colorSpace), 0);
389     if (ret != HDF_SUCCESS) {
390         HDF_LOGE("HdmiCntlrParseVideoCaps: read colorSpace fail!");
391         return ret;
392     }
393 
394     ret = drsOps->GetUint32(node, "colorimetry", &(cntlr->cap.colorimetry), 0);
395     if (ret != HDF_SUCCESS) {
396         HDF_LOGE("HdmiCntlrParseVideoCaps: read colorimetry fail!");
397         return ret;
398     }
399     return HDF_SUCCESS;
400 }
401 
HdmiCntlrParseAudioCaps(struct HdmiCntlr * cntlr,struct DeviceResourceIface * drsOps,const struct DeviceResourceNode * node)402 static int32_t HdmiCntlrParseAudioCaps(struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps,
403     const struct DeviceResourceNode *node)
404 {
405     int32_t ret;
406 
407     ret = drsOps->GetUint32(node, "audioIfType", &(cntlr->cap.audioIfType), 0);
408     if (ret != HDF_SUCCESS) {
409         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioIfType fail!");
410         return ret;
411     }
412     HDF_LOGD("HdmiCntlrParseAudioCaps: audioIfType = %d", cntlr->cap.audioIfType);
413 
414     ret = drsOps->GetUint32(node, "audioBitDepth", &(cntlr->cap.audioBitDepth), 0);
415     if (ret != HDF_SUCCESS) {
416         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioBitDepth fail!");
417         return ret;
418     }
419     HDF_LOGD("HdmiCntlrParseAudioCaps: audioBitDepth = %d", cntlr->cap.audioBitDepth);
420 
421     ret = drsOps->GetUint32(node, "audioSampleRate", &(cntlr->cap.audioSampleRate), 0);
422     if (ret != HDF_SUCCESS) {
423         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioSampleRate fail!");
424         return ret;
425     }
426     HDF_LOGD("HdmiCntlrParseAudioCaps: audioSampleRate = %d", cntlr->cap.audioSampleRate);
427 
428     ret = drsOps->GetUint32(node, "audioChannels", &(cntlr->cap.audioChannels), 0);
429     if (ret != HDF_SUCCESS) {
430         HDF_LOGE("HdmiCntlrParseAudioCaps: read audioChannels fail!");
431         return ret;
432     }
433     HDF_LOGD("HdmiCntlrParseAudioCaps: audioChannels = %d", cntlr->cap.audioChannels);
434     return HDF_SUCCESS;
435 }
436 
HdmiCntlrParseHdrCaps(struct HdmiCntlr * cntlr,struct DeviceResourceIface * drsOps,const struct DeviceResourceNode * node)437 static int32_t HdmiCntlrParseHdrCaps(struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps,
438     const struct DeviceResourceNode *node)
439 {
440     int32_t ret;
441 
442     ret = drsOps->GetUint32(node, "hdrColorimetry", &(cntlr->cap.hdrColorimetry), 0);
443     if (ret != HDF_SUCCESS) {
444         HDF_LOGE("HdmiCntlrParseAudioCaps: read hdrColorimetry fail!");
445         return ret;
446     }
447     HDF_LOGD("HdmiCntlrParseAudioCaps: hdrColorimetry = %d", cntlr->cap.hdrColorimetry);
448 
449     ret = drsOps->GetUint32(node, "hdrUserMode", &(cntlr->cap.hdrUserMode), 0);
450     if (ret != HDF_SUCCESS) {
451         HDF_LOGE("HdmiCntlrParseAudioCaps: read hdrUserMode fail!");
452         return ret;
453     }
454     HDF_LOGD("HdmiCntlrParseAudioCaps: hdrUserMode = %d", cntlr->cap.hdrUserMode);
455     return HDF_SUCCESS;
456 }
457 
HdmiCntlrParse(struct HdmiCntlr * cntlr,struct HdfDeviceObject * obj)458 int32_t HdmiCntlrParse(struct HdmiCntlr *cntlr, struct HdfDeviceObject *obj)
459 {
460     const struct DeviceResourceNode *node = NULL;
461     struct DeviceResourceIface *drsOps = NULL;
462     int32_t ret;
463 
464     if (obj == NULL || cntlr == NULL) {
465         HDF_LOGE("HdmiCntlrParse: input param is NULL.");
466         return HDF_FAILURE;
467     }
468 
469     node = obj->property;
470     if (node == NULL) {
471         HDF_LOGE("HdmiCntlrParse: drs node is NULL.");
472         return HDF_FAILURE;
473     }
474     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
475     if (drsOps == NULL || drsOps->GetUint32 == NULL) {
476         HDF_LOGE("HdmiCntlrParse: invalid drs ops fail!");
477         return HDF_FAILURE;
478     }
479 
480     ret = drsOps->GetUint32(node, "index", &(cntlr->deviceIndex), 0);
481     if (ret != HDF_SUCCESS) {
482         HDF_LOGE("HdmiCntlrParse: read hostId fail!");
483         return ret;
484     }
485 
486     ret = drsOps->GetUint32(node, "cap", &(cntlr->cap.baseCap.data), 0);
487     if (ret != HDF_SUCCESS) {
488         HDF_LOGE("HdmiCntlrParse: read baseCap fail!");
489         return ret;
490     }
491 
492     ret = HdmiCntlrParseVideoCaps(cntlr, drsOps, node);
493     if (ret != HDF_SUCCESS) {
494         HDF_LOGE("HdmiCntlrParse: read video caps fail!");
495         return ret;
496     }
497 
498     ret = HdmiCntlrParseAudioCaps(cntlr, drsOps, node);
499     if (ret != HDF_SUCCESS) {
500         HDF_LOGE("HdmiCntlrParse: read audio caps fail!");
501         return ret;
502     }
503 
504     ret = HdmiCntlrParseHdrCaps(cntlr, drsOps, node);
505     if (ret != HDF_SUCCESS) {
506         HDF_LOGE("HdmiCntlrParse: read hdr caps fail!");
507         return ret;
508     }
509     return HDF_SUCCESS;
510 }
511 
HdmiGetSinkCapability(struct HdmiDevice * hdmi)512 static struct HdmiSinkDeviceCapability *HdmiGetSinkCapability(struct HdmiDevice *hdmi)
513 {
514     if (hdmi == NULL) {
515         return NULL;
516     }
517 
518     if (hdmi->edid.edidPhase == false) {
519         return NULL;
520     }
521     return &(hdmi->edid.sinkCap);
522 }
523 
HdmiCntlrGetSinkEdid(struct HdmiCntlr * cntlr,uint8_t * buffer,uint32_t len)524 int32_t HdmiCntlrGetSinkEdid(struct HdmiCntlr *cntlr, uint8_t *buffer, uint32_t len)
525 {
526     int32_t ret;
527 
528     if (cntlr == NULL) {
529         return HDF_ERR_INVALID_OBJECT;
530     }
531     if (HdmiHpdStatusDelayGet(cntlr) == false) {
532         HDF_LOGE("no hdmi sink device");
533         HdmiCntlrFreeDev(cntlr);
534         return HDF_DEV_ERR_NO_DEVICE;
535     }
536     if (cntlr->hdmi != NULL) {
537         return HdmiEdidGetRaw(&(cntlr->hdmi->edid), buffer, len);
538     }
539 
540     ret  = HdmiCntlrAllocDev(cntlr);
541     if (ret != HDF_SUCCESS) {
542         return ret;
543     }
544 
545     ret = HdmiEdidRawDataRead(&(cntlr->hdmi->edid), &(cntlr->ddc));
546     if (ret != HDF_SUCCESS) {
547         HdmiCntlrFreeDev(cntlr);
548         return ret;
549     }
550 
551     if (cntlr->hdmi->edid.edidPhase != true) {
552         (void)HdmiEdidPhase(&(cntlr->hdmi->edid));
553         cntlr->hdmi->edid.edidPhase = true;
554     }
555     return HdmiEdidGetRaw(&(cntlr->hdmi->edid), buffer, len);
556 }
557 
HdmiCntlrModeSelect(struct HdmiCntlr * cntlr)558 static void HdmiCntlrModeSelect(struct HdmiCntlr *cntlr)
559 {
560     enum HdmiTmdsModeType tmdsMode;
561     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
562     struct HdmiScdcScrambleCap scramble = {0};
563     struct HdmiScdcScrambleCap curScramble = {0};
564     int32_t ret;
565 
566     /* support FRL. */
567     if (HdmiFrlSupport(cntlr->frl) == true &&
568         cntlr->cap.baseCap.bits.frl > 0) {
569         return;
570     }
571 
572     if (cntlr->cap.baseCap.bits.scdc > 0) {
573         ret = HdmiScdcFillScrambleCap(cntlr->scdc, &scramble, &tmdsMode);
574         if (ret != HDF_SUCCESS) {
575             return;
576         }
577     } else {
578         tmdsMode = (commAttr->enableHdmi == true) ? HDMI_TMDS_MODE_HDMI_1_4 : HDMI_TMDS_MODE_DVI;
579     }
580 
581     cntlr->tmdsMode = tmdsMode;
582     HdmiCntlrTmdsModeSet(cntlr, tmdsMode);
583     HdmiCntlrReset(cntlr);
584 
585     if (cntlr->cap.baseCap.bits.scdc > 0 &&
586         HdmiEdidScdcSupport(cntlr->hdmi) == true) {
587         ret = HdmiScdcScrambleGet(cntlr->scdc, &curScramble);
588         if (ret != HDF_SUCCESS) {
589             return;
590         }
591         if (scramble.sinkScramble != curScramble.sinkScramble ||
592             scramble.sourceScramble != curScramble.sourceScramble ||
593             scramble.tmdsBitClockRatio40 != curScramble.tmdsBitClockRatio40) {
594             (void)HdmiScdcScrambleSet(cntlr->scdc, &scramble);
595         }
596     }
597 }
598 
HdmiCommonAttrInit(struct HdmiCntlr * cntlr)599 static void HdmiCommonAttrInit(struct HdmiCntlr *cntlr)
600 {
601     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
602 
603     commAttr->enableHdmi = true;
604     commAttr->enableVideo = true;
605     commAttr->enableAudio = true;
606     commAttr->audio = true;
607     commAttr->avi = true;
608     commAttr->hdcpMode = HDMI_HDCP_MODE_1_4;
609     commAttr->colorSpace = (enum HdmiColorSpace)cntlr->cap.colorSpace;
610     commAttr->quantization = (enum HdmiQuantizationRange)cntlr->cap.quantization;
611 }
612 
HdmiVideoAttrInit(struct HdmiCntlr * cntlr)613 static void HdmiVideoAttrInit(struct HdmiCntlr *cntlr)
614 {
615     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
616     bool colorimetry601;
617 
618     videoAttr->colorSpace = (enum HdmiColorSpace)cntlr->cap.colorSpace;
619     videoAttr->colorimetry = (enum HdmiColorimetry)cntlr->cap.colorimetry;
620     videoAttr->timing = (enum HdmiVideoTiming)cntlr->cap.videoTiming;
621     colorimetry601 = ((videoAttr->timing == HDMI_VIDEO_TIMING_720X480P60) ||
622         (videoAttr->timing == HDMI_VIDEO_TIMING_720X576P50) ||
623         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X240P60) ||
624         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60) ||
625         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) ||
626         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576P50) ||
627         (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I60));
628 
629     if (videoAttr->timing == HDMI_VIDEO_TIMING_640X480P60) {
630         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
631         videoAttr->aspect = HDMI_PICTURE_ASPECT_4_3;
632     } else if (colorimetry601 == true) {
633         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU601;
634         videoAttr->aspect = HDMI_PICTURE_ASPECT_4_3;
635     } else if (videoAttr->timing <= HDMI_VIDEO_TIMING_4096X2160P120 &&
636         videoAttr->timing >= HDMI_VIDEO_TIMING_4096X2160P24) {
637         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
638         videoAttr->aspect = HDMI_PICTURE_ASPECT_256_135;
639     } else {
640         videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
641         videoAttr->aspect = HDMI_PICTURE_ASPECT_16_9;
642     }
643 
644     videoAttr->pixelRepeat = 1;
645     if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 ||
646         videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
647         videoAttr->pixelRepeat = 2;
648     }
649 
650     if (videoAttr->timing <= HDMI_VIDEO_TIMING_640X480P60) {
651         videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
652     } else {
653         videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
654     }
655 
656     if (videoAttr->timing != HDMI_VIDEO_TIMING_NONE &&
657         videoAttr->timing != HDMI_VIDEO_TIMING_640X480P60) {
658         videoAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
659     } else {
660         videoAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
661     }
662 
663     videoAttr->_3dStruct = HDMI_VS_VIDEO_3D_BUTT;
664     videoAttr->activeAspect = HDMI_ACTIVE_FORMAT_ASPECT_PICTURE;
665 }
666 
HdmiAudioAttrInit(struct HdmiCntlr * cntlr)667 static void HdmiAudioAttrInit(struct HdmiCntlr *cntlr)
668 {
669     struct HdmiAudioAttr *audioAttr = &(cntlr->attr.audioAttr);
670 
671     audioAttr->ifType = (enum HdmiAudioInterfaceType)cntlr->cap.audioIfType;
672     audioAttr->bitDepth = (enum HdmiAudioBitDepth)cntlr->cap.audioBitDepth;
673     audioAttr->sampleRate = (enum HdmiSampleRate)cntlr->cap.audioSampleRate;
674     audioAttr->channels = (enum HdmiAudioFormatChannel)cntlr->cap.audioChannels;
675 }
676 
HdmiHdrAttrInit(struct HdmiCntlr * cntlr)677 static void HdmiHdrAttrInit(struct HdmiCntlr *cntlr)
678 {
679     struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
680 
681     hdrAttr->userMode = (enum HdmiHdrUserMode)cntlr->cap.hdrUserMode;
682     hdrAttr->colorimetry = (enum HdmiHdrColormetry)cntlr->cap.hdrColorimetry;
683 }
684 
HdmiAttrInit(struct HdmiCntlr * cntlr)685 static void HdmiAttrInit(struct HdmiCntlr *cntlr)
686 {
687     HdmiCommonAttrInit(cntlr);
688     HdmiVideoAttrInit(cntlr);
689     HdmiAudioAttrInit(cntlr);
690     HdmiHdrAttrInit(cntlr);
691 }
692 
HdmiCntlrOpen(struct HdmiCntlr * cntlr)693 int32_t HdmiCntlrOpen(struct HdmiCntlr *cntlr)
694 {
695     int32_t ret;
696 
697     if (cntlr == NULL) {
698         return HDF_ERR_INVALID_OBJECT;
699     }
700     HdmiInfoFrameInit(cntlr);
701     HdmiDdcInit(cntlr);
702     HdmiScdcInit(cntlr);
703     HdmiFrlInit(cntlr);
704     HdmiHdcpInit(cntlr);
705     HdmiCecInit(cntlr);
706     HdmiHdrInit(cntlr);
707     HdmiAttrInit(cntlr);
708     HdmiCntlrHardWareInit(cntlr);
709      /* HDCP on. */
710     if ((cntlr->cap.baseCap.data & HDMI_CAP_HDCP_MARK) > 0) {
711         ret = HdmiHdcpOpen(cntlr->hdcp);
712         if (ret != HDF_SUCCESS) {
713             HdmiHdcpClose(cntlr->hdcp);
714         }
715     }
716     cntlr->state |= HDMI_CNTLR_STATE_OPEN;
717     return HDF_SUCCESS;
718 }
719 
HdmiCntlrStart(struct HdmiCntlr * cntlr)720 int32_t HdmiCntlrStart(struct HdmiCntlr *cntlr)
721 {
722     if (cntlr == NULL || cntlr->ops == NULL) {
723         return HDF_ERR_INVALID_OBJECT;
724     }
725 
726     HdmiCntlrLowPowerSet(cntlr, false);
727     /* select mode */
728     HdmiCntlrModeSelect(cntlr);
729     HdmiCntlrAvmuteSet(cntlr, false);
730 
731     if (cntlr->cap.baseCap.bits.hdr > 0 &&
732         cntlr->cap.baseCap.bits.frl > 0) {
733         HdmiFrlEnable(cntlr->frl, true);
734     } else {
735         /* TMDS Transfer. */
736         if (cntlr->ops->phyOutputEnable != NULL) {
737             HdmiCntlrLock(cntlr);
738             cntlr->ops->phyOutputEnable(cntlr, true);
739             HdmiCntlrUnlock(cntlr);
740         }
741     }
742 
743     HdmiCntlrAudioPathEnable(cntlr, true);
744     HdmiCntlrBlackDataSet(cntlr, false);
745 
746     cntlr->state |= HDMI_CNTLR_STATE_START;
747     return HDF_SUCCESS;
748 }
749 
HdmiCntlrStop(struct HdmiCntlr * cntlr)750 int32_t HdmiCntlrStop(struct HdmiCntlr *cntlr)
751 {
752     if (cntlr == NULL || cntlr->ops == NULL) {
753         return HDF_ERR_INVALID_OBJECT;
754     }
755 
756     HdmiCntlrLock(cntlr);
757     if (cntlr->ops->audioPathEnable != NULL) {
758         cntlr->ops->audioPathEnable(cntlr, false);
759     }
760     if (cntlr->ops->avmuteSet != NULL) {
761         cntlr->ops->avmuteSet(cntlr, true);
762     }
763     if (cntlr->ops->blackDataSet != NULL) {
764         cntlr->ops->blackDataSet(cntlr, true);
765     }
766     HdmiFrlEnable(cntlr->frl, false);
767     if (cntlr->ops->phyOutputEnable != NULL) {
768         cntlr->ops->phyOutputEnable(cntlr, false);
769     }
770     HdmiCntlrUnlock(cntlr);
771 
772     HdmiCntlrLowPowerSet(cntlr, true);
773     cntlr->state = HDMI_CNTLR_STATE_STOP;
774     return HDF_SUCCESS;
775 }
776 
HdmiTmdsClockUpdate(struct HdmiVideoAttr * videoAttr,struct HdmiCommonAttr * commAttr)777 static void HdmiTmdsClockUpdate(struct HdmiVideoAttr *videoAttr, struct HdmiCommonAttr *commAttr)
778 {
779     /*
780      * Video at the default 24-bit color depth is carried at a TMDS clock rate equal to the pixel clock rate.
781      * YCBCB 4:2:0 video is carried at a TMDS clock rate equal to the 1/2 pixel clock rate.
782      */
783     if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR420) {
784         videoAttr->tmdsClock = HDMI_MULTIPLE_0P5(videoAttr->pixelClock);
785         return;
786     }
787 
788     /*
789      * The TMDS clock rate is ibcreased by the ratio of the pixel size to 24-bits:
790      * 24-bit mode: TMDS clock is 1.0 X pixel clock;
791      * 30-bit mode: TMDS clock is 1.25 X pixel clock;
792      * 36-bit mode: TMDS clock is 1.5 X pixel clock;
793      * 48-bit mode: TMDS clock is 2.0 X pixel clock;
794      */
795     videoAttr->tmdsClock = videoAttr->pixelClock;
796     if (commAttr->colorSpace != HDMI_COLOR_SPACE_YCBCR422) {
797         if (commAttr->deepColor == HDMI_DEEP_COLOR_30BITS) {
798             videoAttr->tmdsClock = HDMI_MULTIPLE_1P25(videoAttr->pixelClock);
799         } else if (commAttr->deepColor == HDMI_DEEP_COLOR_36BITS) {
800             videoAttr->tmdsClock = HDMI_MULTIPLE_1P5(videoAttr->pixelClock);
801         } else if (commAttr->deepColor == HDMI_DEEP_COLOR_48BITS) {
802             videoAttr->tmdsClock = HDMI_MULTIPLE_2P0(videoAttr->pixelClock);
803         }
804     } else {
805         if ((commAttr->deepColor != HDMI_DEEP_COLOR_OFF) &&
806             (commAttr->deepColor != HDMI_DEEP_COLOR_24BITS)) {
807             HDF_LOGD("Y422 foce deepcolor 8bit");
808             commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
809         }
810         if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 ||
811             videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
812             HDF_LOGD("Y422 is not support at pal and ntsc, force adapt to rgb!");
813             commAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
814         }
815     }
816 }
817 
HdmiYcbcr420FormatCheck(struct HdmiSinkDeviceCapability * sinkCap,struct HdmiVideoAttr * videoAttr)818 static bool HdmiYcbcr420FormatCheck(struct HdmiSinkDeviceCapability *sinkCap, struct HdmiVideoAttr *videoAttr)
819 {
820     uint32_t i;
821     enum HdmiVic vic;
822 
823     vic =  HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, false);
824     if (vic == HDMI_VIC_NONE) {
825         HDF_LOGD("Y420 not have supported vic.");
826         return false;
827     }
828 
829     for (i = 0; i < sinkCap->y420Cap.SupportY420VicNum; i++) {
830         if (vic == sinkCap->y420Cap.SupportY420Format[i]) {
831             HDF_LOGD("Y420 supported vic is %d.", vic);
832             return true;
833         }
834     }
835 
836     for (i = 0; i < sinkCap->y420Cap.onlySupportY420VicNum; i++) {
837         if (vic == sinkCap->y420Cap.onlySupportY420Format[i]) {
838             HDF_LOGD("Y420 supported vic is %d.", vic);
839             return true;
840         }
841     }
842 
843     HDF_LOGD("Y420 have no supported vic.");
844     return false;
845 }
846 
HdmiColorSpaceCheck(struct HdmiCntlr * cntlr,struct HdmiSinkDeviceCapability * sinkCap,uint32_t maxTmdsClk)847 static int32_t HdmiColorSpaceCheck(struct HdmiCntlr *cntlr, struct HdmiSinkDeviceCapability *sinkCap,
848     uint32_t maxTmdsClk)
849 {
850     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
851     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
852     union HdmiCap *cap = &(cntlr->cap.baseCap);
853     bool supportColorSpace = false;
854 
855     if (videoAttr->pixelClock > maxTmdsClk &&
856         commAttr->colorSpace != HDMI_COLOR_SPACE_YCBCR420) {
857         return HDF_ERR_INVALID_PARAM;
858     }
859 
860     switch (commAttr->colorSpace) {
861         case HDMI_COLOR_SPACE_RGB:
862             supportColorSpace = true;
863             if ((sinkCap->colorSpace.rgb444 && cap->bits.rgb444) == false) {
864                 HDF_LOGD("sink or source not support RGB!");
865             }
866             break;
867         case HDMI_COLOR_SPACE_YCBCR422:
868             supportColorSpace = sinkCap->colorSpace.ycbcr422 && cap->bits.ycbcr422;
869             break;
870         case HDMI_COLOR_SPACE_YCBCR444:
871             supportColorSpace = sinkCap->colorSpace.ycbcr444 && cap->bits.ycbcr444;
872             break;
873         case HDMI_COLOR_SPACE_YCBCR420:
874             supportColorSpace = cap->bits.ycbcr420 && HdmiYcbcr420FormatCheck(sinkCap, videoAttr);
875             break;
876         default:
877             HDF_LOGE("unknow color_space = %u!\n", commAttr->colorSpace);
878             break;
879     }
880 
881     if (supportColorSpace != true) {
882         return HDF_ERR_INVALID_PARAM;
883     }
884     return HDF_SUCCESS;
885 }
886 
HdmiDeepColor10bitsCheck(struct HdmiSinkDeviceCapability * sinkCap,struct HdmiCommonAttr * commAttr,union HdmiCap * cap,uint32_t * tmdsClock,bool * supportDeepColor)887 static void HdmiDeepColor10bitsCheck(struct HdmiSinkDeviceCapability *sinkCap, struct HdmiCommonAttr *commAttr,
888     union HdmiCap *cap, uint32_t *tmdsClock, bool *supportDeepColor)
889 {
890     uint32_t tmpTmdsClk = *tmdsClock;
891 
892     switch (commAttr->colorSpace) {
893         case HDMI_COLOR_SPACE_RGB:
894             tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
895             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc30bit && cap->bits.deepColor10bits) ? true : false;
896             break;
897         case HDMI_COLOR_SPACE_YCBCR444:
898             tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
899             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc30bit && cap->bits.deepColor10bits &&
900                 sinkCap->vsdbInfo.deepColor.dcY444) ? true : false;
901             break;
902         case HDMI_COLOR_SPACE_YCBCR420:
903             tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
904             *supportDeepColor = (sinkCap->hfVsdbInfo.dc.dc30bit && cap->bits.deepColor10bits) ? true : false;
905             break;
906         default:
907             /* Y422, ignore deepclr */
908             *supportDeepColor = true;
909             break;
910     }
911     *tmdsClock = tmpTmdsClk;
912 }
913 
HdmiDeepColor12bitsCheck(struct HdmiSinkDeviceCapability * sinkCap,struct HdmiCommonAttr * commAttr,union HdmiCap * cap,uint32_t * tmdsClock,bool * supportDeepColor)914 static void HdmiDeepColor12bitsCheck(struct HdmiSinkDeviceCapability *sinkCap, struct HdmiCommonAttr *commAttr,
915     union HdmiCap *cap, uint32_t *tmdsClock, bool *supportDeepColor)
916 {
917     uint32_t tmpTmdsClk = *tmdsClock;
918 
919     switch (commAttr->colorSpace) {
920         case HDMI_COLOR_SPACE_RGB:
921             tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
922             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc36bit && cap->bits.deepColor12bits) ? true : false;
923             break;
924         case HDMI_COLOR_SPACE_YCBCR444:
925             tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
926             *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc36bit && cap->bits.deepColor12bits &&
927                 sinkCap->vsdbInfo.deepColor.dcY444) ? true : false;
928             break;
929         case HDMI_COLOR_SPACE_YCBCR420:
930             tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
931             *supportDeepColor = (sinkCap->hfVsdbInfo.dc.dc36bit && cap->bits.deepColor12bits) ? true : false;
932             break;
933         default:
934             /* Y422, ignore deepclr */
935             *supportDeepColor = true;
936             break;
937     }
938     *tmdsClock = tmpTmdsClk;
939 }
940 
HdmiDeepColorCheck(struct HdmiCntlr * cntlr,struct HdmiSinkDeviceCapability * sinkCap,uint32_t maxTmdsClk)941 static int32_t HdmiDeepColorCheck(struct HdmiCntlr *cntlr, struct HdmiSinkDeviceCapability *sinkCap,
942     uint32_t maxTmdsClk)
943 {
944     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
945     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
946     union HdmiCap *cap = &(cntlr->cap.baseCap);
947     uint32_t tmdsClock = videoAttr->pixelClock;
948     bool supportDeepColor = false;
949 
950     if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR420) {
951         tmdsClock = HDMI_MULTIPLE_0P5(tmdsClock);
952     }
953 
954     switch (commAttr->deepColor) {
955         case HDMI_DEEP_COLOR_30BITS:
956             HdmiDeepColor10bitsCheck(sinkCap, commAttr, cap, &tmdsClock, &supportDeepColor);
957             break;
958         case HDMI_DEEP_COLOR_36BITS:
959             HdmiDeepColor12bitsCheck(sinkCap, commAttr, cap, &tmdsClock, &supportDeepColor);
960             break;
961         default:
962             commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
963             supportDeepColor = true;
964             break;
965     }
966 
967     if (supportDeepColor == false || tmdsClock > maxTmdsClk) {
968         return HDF_ERR_INVALID_PARAM;
969     }
970     videoAttr->tmdsClock = tmdsClock;
971     /* Y422 default 12bit output, deep_color force adapt to 8bit(24bit). */
972     if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR422) {
973         if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 ||
974             videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
975             HDF_LOGD("force change colorspace to RGB!");
976             commAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
977         }
978         if ((videoAttr->deepColor != HDMI_DEEP_COLOR_24BITS) &&
979             (videoAttr->deepColor != HDMI_DEEP_COLOR_OFF)) {
980             videoAttr->deepColor = HDMI_DEEP_COLOR_OFF;
981             HDF_LOGD("when Y422, deep_color not support 10/12bit!");
982         }
983     }
984     return HDF_SUCCESS;
985 }
986 
HdmiColorBitSelect(struct HdmiCntlr * cntlr)987 static int32_t HdmiColorBitSelect(struct HdmiCntlr *cntlr)
988 {
989     struct HdmiSinkDeviceCapability *sinkCap = NULL;
990     uint32_t maxTmdsClk = 0;
991 
992     /* DVI mode, must set RGB and DEEP_COLOR_OFF */
993     if (cntlr->attr.commAttr.enableHdmi == false) {
994         if (cntlr->attr.commAttr.colorSpace != HDMI_COLOR_SPACE_RGB) {
995             HDF_LOGE("DVI mode, the color space is not RGB!");
996             return HDF_ERR_INVALID_PARAM;
997         }
998         cntlr->attr.commAttr.deepColor = HDMI_DEEP_COLOR_OFF;
999         cntlr->attr.videoAttr.tmdsClock = cntlr->attr.videoAttr.pixelClock;
1000         return HDF_SUCCESS;
1001     }
1002 
1003     /* FRL mode. */
1004     if (cntlr->cap.baseCap.bits.hdr > 0) {
1005         HdmiTmdsClockUpdate(&(cntlr->attr.videoAttr), &(cntlr->attr.commAttr));
1006         if (cntlr->attr.videoAttr.tmdsClock > HDMI_HDMI20_MAX_TMDS_RATE) {
1007             HDF_LOGD("HDMI2.1, tmds clock exceed max.");
1008             return HDF_SUCCESS;
1009         }
1010     }
1011 
1012     sinkCap = HdmiGetSinkCapability(cntlr->hdmi);
1013     if (sinkCap == NULL) {
1014         HdmiTmdsClockUpdate(&(cntlr->attr.videoAttr), &(cntlr->attr.commAttr));
1015         return HDF_SUCCESS;
1016     }
1017 
1018     if (sinkCap->maxTmdsClk == 0) {
1019         /* use default clock. */
1020         maxTmdsClk = cntlr->cap.defTmdsClock;
1021     } else {
1022         maxTmdsClk = (sinkCap->maxTmdsClk < cntlr->cap.maxTmdsClock) ?
1023             sinkCap->maxTmdsClk : cntlr->cap.maxTmdsClock;
1024     }
1025     /* MHz is converted to KHz */
1026     maxTmdsClk *= 1000;
1027 
1028     if (HdmiColorSpaceCheck(cntlr, sinkCap, maxTmdsClk) != HDF_SUCCESS) {
1029         return HDF_ERR_INVALID_PARAM;
1030     }
1031     if (HdmiDeepColorCheck(cntlr, sinkCap, maxTmdsClk) != HDF_SUCCESS) {
1032         return HDF_ERR_INVALID_PARAM;
1033     }
1034     return HDF_SUCCESS;
1035 }
1036 
HdmiAudioAttrHandle(struct HdmiCntlr * cntlr)1037 static int32_t HdmiAudioAttrHandle(struct HdmiCntlr *cntlr)
1038 {
1039     struct HdmiAudioConfigInfo audioCfg  = {0};
1040     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
1041     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
1042     struct HdmiAudioAttr *audioAttr = &(cntlr->attr.audioAttr);
1043     int32_t ret;
1044 
1045     audioCfg.downSample = audioAttr->downSample;
1046     audioCfg.channels = audioAttr->channels;
1047     audioCfg.bitDepth = audioAttr->bitDepth;
1048     audioCfg.sampleRate = audioAttr->sampleRate;
1049     audioCfg.ifType = audioAttr->ifType;
1050     audioCfg.enable = (commAttr->enableAudio) && (commAttr->enableHdmi);
1051     audioCfg.tmdsClock = videoAttr->tmdsClock;
1052     audioCfg.pixelRepeat = videoAttr->pixelRepeat;
1053 
1054     HdmiCntlrAudioPathEnable(cntlr, false);
1055     HdmiCntlrAudioPathSet(cntlr, &audioCfg);
1056     ret = HdmiAudioInfoFrameSend(&(cntlr->infoFrame), ((commAttr->enableAudio) && (commAttr->audio)));
1057     HdmiCntlrAudioPathEnable(cntlr, true);
1058     return ret;
1059 }
1060 
HdmiHdrModeCheck(struct HdmiCommonAttr * commAttr,struct HdmiVideoAttr * videoAttr,struct HdmiHdrAttr * hdrAttr)1061 static void HdmiHdrModeCheck(struct HdmiCommonAttr *commAttr,
1062     struct HdmiVideoAttr *videoAttr, struct HdmiHdrAttr *hdrAttr)
1063 {
1064     switch (hdrAttr->userMode) {
1065         case HDMI_HDR_USERMODE_DOLBY:
1066             videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
1067             commAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
1068             videoAttr->tmdsClock = videoAttr->pixelClock;
1069             commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
1070             videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
1071             break;
1072         case HDMI_HDR_USERMODE_HDR10:
1073             if (hdrAttr->mode == HDMI_HDR_MODE_CEA_861_3) {
1074                 if (hdrAttr->colorimetry > HDMI_HDR_COLORIMETRY_EXTENDED) {
1075                     videoAttr->colorimetry = HDMI_COLORIMETRY_EXTENDED;
1076                     videoAttr->extColorimetry = (enum HdmiExtendedColorimetry)(hdrAttr->colorimetry -
1077                         HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601);
1078                 } else {
1079                     videoAttr->colorimetry = (enum HdmiColorimetry)(hdrAttr->colorimetry);
1080                     videoAttr->extColorimetry = HDMI_EXTENDED_COLORIMETRY_BUTT;
1081                 }
1082                 commAttr->xvyccMode = false;
1083             }
1084             break;
1085         default:
1086             break;
1087     }
1088 }
1089 
HdmiFillVideoAttrFromHardwareStatus(struct HdmiVideoAttr * videoAttr,struct HdmiHardwareStatus * hwStatus,struct HdmiCommonAttr * commAttr)1090 static void HdmiFillVideoAttrFromHardwareStatus(struct HdmiVideoAttr *videoAttr,
1091     struct HdmiHardwareStatus *hwStatus, struct HdmiCommonAttr *commAttr)
1092 {
1093     bool rgb = false;
1094     bool aspectIs256 = false;
1095     uint8_t vic;
1096     enum HdmiVsVideoFormat format;
1097     enum Hdmi4kVic vic4k;
1098 
1099     rgb = ((hwStatus->videoStatus.rgb2Ycbcr) ||
1100         ((!hwStatus->videoStatus.ycbcr2Rgb) && (hwStatus->videoStatus.outColorSpace == HDMI_COLOR_SPACE_RGB)));
1101     videoAttr->colorSpace = (rgb == true) ? HDMI_COLOR_SPACE_RGB : HDMI_COLOR_SPACE_YCBCR444;
1102 
1103     if (hwStatus->infoFrameStatus.aviEnable) {
1104         vic = hwStatus->infoFrameStatus.avi[7];
1105         /*
1106          * when the timing is 4096*2160, the aspect ratio in AVI infoFrame is 0
1107          * (but the real aspect ratio is 256:135<0x04>, the video_code is 0)
1108          */
1109         aspectIs256 = (((vic == 0) && (hwStatus->infoFrameStatus.vsif[8] == 0x04)) ||
1110             ((vic >= HDMI_VIC_4096X2160P25_256_135) && (vic <= HDMI_VIC_4096X2160P60_256_135)));
1111         videoAttr->aspect = (aspectIs256 == true) ? HDMI_PICTURE_ASPECT_256_135 :
1112             ((hwStatus->infoFrameStatus.avi[5] >> 4) & 0x3);  /* 4'b, BIT[2:1] */
1113         videoAttr->activeAspect = hwStatus->infoFrameStatus.avi[5] & 0xf;
1114         videoAttr->colorimetry = (hwStatus->infoFrameStatus.avi[5] >> 6) & 0x3; /* 6'b, BIT[2:1] */
1115         videoAttr->quantization = (hwStatus->infoFrameStatus.avi[6] >> 2) & 0x3; /* 2'b, BIT[2:1] */
1116         videoAttr->extColorimetry = (hwStatus->infoFrameStatus.avi[6] >> 4) & 0x07; /* 4'b, BIT[3:1] */
1117         videoAttr->yccQuantization = (hwStatus->infoFrameStatus.avi[8] >> 6) & 0x3; /* 6'b, BIT[2:1] */
1118         videoAttr->pixelRepeat = (hwStatus->infoFrameStatus.avi[8] & 0xf) + 1;
1119         videoAttr->timing = HdmiCommonGetVideoTiming(vic, videoAttr->aspect);
1120         if ((!hwStatus->infoFrameStatus.vsifEnable) && (!vic)) {
1121             videoAttr->timing = HDMI_VIDEO_TIMING_NONE;
1122         }
1123         commAttr->quantization = (commAttr->colorSpace == HDMI_COLOR_SPACE_RGB) ?
1124             videoAttr->quantization : (videoAttr->yccQuantization + 1);
1125     }
1126 
1127     videoAttr->_3dStruct = HDMI_VS_VIDEO_3D_BUTT;
1128     if (hwStatus->infoFrameStatus.vsifEnable) {
1129         format = (hwStatus->infoFrameStatus.vsif[7] >> 5) & 0x3; /* 5'b, BIT[2:1] */
1130         if (format == HDMI_VS_VIDEO_FORMAT_4K) {
1131             vic4k = hwStatus->infoFrameStatus.vsif[8];
1132             videoAttr->timing = HdmiCommonGetVideo4kTiming(vic4k);
1133         } else if (format == HDMI_VS_VIDEO_FORMAT_3D) {
1134             videoAttr->_3dStruct = (hwStatus->infoFrameStatus.vsif[8] >> 4) & 0xf; /* 4'b, BIT[4:1] */
1135         }
1136     }
1137 }
1138 
HdmiFillCommonAttrFromHardwareStatus(struct HdmiCommonAttr * commAttr,struct HdmiHardwareStatus * hwStatus,struct HdmiAttr * attr)1139 static void HdmiFillCommonAttrFromHardwareStatus(struct HdmiCommonAttr *commAttr,
1140     struct HdmiHardwareStatus *hwStatus, struct HdmiAttr *attr)
1141 {
1142     bool dolby = false;
1143 
1144     switch (hwStatus->commonStatus.tmdsMode) {
1145         case HDMI_TMDS_MODE_HDMI_1_4:
1146         case HDMI_TMDS_MODE_HDMI_2_0:
1147             commAttr->enableHdmi = true;
1148             commAttr->enableVideo = true;
1149             break;
1150         case HDMI_TMDS_MODE_DVI:
1151             commAttr->enableHdmi = false;
1152             commAttr->enableVideo = true;
1153             break;
1154         default:
1155             commAttr->enableHdmi = false;
1156             commAttr->enableVideo = false;
1157             break;
1158     }
1159 
1160     commAttr->enableAudio = (hwStatus->audioStatus.enable && hwStatus->infoFrameStatus.audioEnable);
1161     commAttr->avi = hwStatus->infoFrameStatus.aviEnable;
1162     commAttr->audio = hwStatus->infoFrameStatus.audioEnable;
1163     commAttr->xvyccMode = hwStatus->infoFrameStatus.gdbEnable;
1164     commAttr->deepColor = HdmiCommonColorDepthConvertToDeepClolor(hwStatus->videoStatus.outBitDepth);
1165 
1166     /* color space is ycbcr444 when the hdr mode is dolby. */
1167     dolby = ((attr->hdrAttr.userMode == HDMI_HDR_USERMODE_DOLBY) &&
1168         (!hwStatus->videoStatus.rgb2Ycbcr) &&
1169         (!hwStatus->videoStatus.ycbcr2Rgb) &&
1170         (!hwStatus->videoStatus.ycbcr444422) &&
1171         (!hwStatus->videoStatus.ycbcr422420) &&
1172         (!hwStatus->videoStatus.ycbcr422444) &&
1173         (!hwStatus->videoStatus.ycbcr420422));
1174     commAttr->colorSpace = (dolby == true) ? HDMI_COLOR_SPACE_YCBCR444 : hwStatus->videoStatus.outColorSpace;
1175 }
1176 
HdmiCommonAttrChanged(struct HdmiCommonAttr * curCommAttr,struct HdmiCommonAttr * commAttr)1177 static bool HdmiCommonAttrChanged(struct HdmiCommonAttr *curCommAttr, struct HdmiCommonAttr *commAttr)
1178 {
1179     bool change;
1180 
1181     change = (commAttr->enableHdmi != curCommAttr->enableHdmi) ||
1182         (commAttr->colorSpace != curCommAttr->colorSpace) ||
1183         (commAttr->xvyccMode != curCommAttr->xvyccMode) ||
1184         (commAttr->avi != curCommAttr->avi) ||
1185         (commAttr->quantization != curCommAttr->quantization);
1186 
1187     if (change == true) {
1188         return true;
1189     }
1190 
1191     if (((commAttr->deepColor == HDMI_DEEP_COLOR_OFF) ||
1192         (commAttr->deepColor == HDMI_DEEP_COLOR_24BITS)) &&
1193         ((curCommAttr->deepColor == HDMI_DEEP_COLOR_OFF) ||
1194         (curCommAttr->deepColor == HDMI_DEEP_COLOR_24BITS))) {
1195         HDF_LOGI("deep color not change: %u", curCommAttr->deepColor);
1196     } else if (commAttr->deepColor != curCommAttr->deepColor) {
1197         return true;
1198     }
1199     return false;
1200 }
1201 
HdmiVideoAttrChanged(struct HdmiVideoAttr * curVideoAttr,struct HdmiVideoAttr * videoAttr)1202 static bool HdmiVideoAttrChanged(struct HdmiVideoAttr *curVideoAttr, struct HdmiVideoAttr *videoAttr)
1203 {
1204     bool change;
1205 
1206     change = (videoAttr->timing != curVideoAttr->timing) ||
1207         (videoAttr->colorSpace != curVideoAttr->colorSpace) ||
1208         (videoAttr->_3dStruct != curVideoAttr->_3dStruct) ||
1209         (videoAttr->pixelRepeat != curVideoAttr->pixelRepeat) ||
1210         (videoAttr->colorimetry != curVideoAttr->colorimetry) ||
1211         (videoAttr->extColorimetry != curVideoAttr->extColorimetry) ||
1212         (videoAttr->quantization != curVideoAttr->quantization) ||
1213         (videoAttr->yccQuantization != curVideoAttr->yccQuantization) ||
1214         (videoAttr->aspect != curVideoAttr->aspect);
1215     return change;
1216 }
1217 
HdmiVedioAttrHandle(struct HdmiCntlr * cntlr,struct HdmiHardwareStatus * hwStatus)1218 static int32_t HdmiVedioAttrHandle(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *hwStatus)
1219 {
1220     struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
1221     struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
1222     struct HdmiCommonAttr curCommAttr = {0};
1223     struct HdmiVideoAttr curVideoAttr = {0};
1224     int32_t ret;
1225 
1226     /* support HDR. */
1227     if (cntlr->cap.baseCap.bits.hdr > 0) {
1228         HdmiHdrModeCheck(commAttr, videoAttr, &(cntlr->attr.hdrAttr));
1229     }
1230 
1231     /* support FRL. */
1232     if (cntlr->cap.baseCap.bits.frl > 0) {
1233         ret = HdmiFrlModeSelect(cntlr->frl);
1234         if (ret != HDF_SUCCESS) {
1235             return ret;
1236         }
1237     }
1238 
1239     HdmiFillCommonAttrFromHardwareStatus(&curCommAttr, hwStatus, &(cntlr->attr));
1240     HdmiFillVideoAttrFromHardwareStatus(&curVideoAttr, hwStatus, &curCommAttr);
1241     if (HdmiCommonAttrChanged(&curCommAttr, commAttr) == false &&
1242         HdmiVideoAttrChanged(&curVideoAttr, videoAttr) == false &&
1243         HdmiFrlModeChanged(cntlr->frl) == false) {
1244         HDF_LOGI("video and common attr is not changed.");
1245         return HDF_SUCCESS;
1246     }
1247 
1248     if (commAttr->enableVideo == true) {
1249         HdmiCntlrVideoPathSet(cntlr, videoAttr);
1250     }
1251 
1252     (void)HdmiAviInfoFrameSend(&(cntlr->infoFrame), (commAttr->enableHdmi && commAttr->avi));
1253     (void)HdmiVsInfoFrameSend(&(cntlr->infoFrame), commAttr->enableHdmi, commAttr->vsifDolby);
1254     /* the drm infoFrame is stop because software was reset in videopath, so re-enable it if the mode is HDR10. */
1255     if (cntlr->cap.baseCap.bits.hdr > 0) {
1256         if (cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_CEA_861_3) {
1257             (void)HdmiDrmInfoFrameSend(&(cntlr->infoFrame), false);
1258             (void)HdmiDrmInfoFrameSend(&(cntlr->infoFrame), true);
1259         }
1260     }
1261     return HDF_SUCCESS;
1262 }
1263 
HdmiAttrUpdate(struct HdmiCntlr * cntlr)1264 static void HdmiAttrUpdate(struct HdmiCntlr *cntlr)
1265 {
1266     struct HdmiHardwareStatus hwStatus = {0};
1267 
1268     if (HdmiColorBitSelect(cntlr) != HDF_SUCCESS) {
1269         HDF_LOGD("attr update: color bit select fail.");
1270         return;
1271     }
1272 
1273     if (cntlr->ops->hardWareStatusGet == NULL) {
1274         return;
1275     }
1276 
1277     HdmiCntlrLock(cntlr);
1278     cntlr->ops->hardWareStatusGet(cntlr, &hwStatus);
1279     HdmiCntlrUnlock(cntlr);
1280 
1281     if (HdmiAudioAttrHandle(cntlr) != HDF_SUCCESS) {
1282         HDF_LOGD("audio attr check fail");
1283         return;
1284     }
1285     if (HdmiVedioAttrHandle(cntlr, &hwStatus) != HDF_SUCCESS) {
1286         HDF_LOGD("vedio attr check fail");
1287     }
1288 }
1289 
HdmiCntlrDeepColorSet(struct HdmiCntlr * cntlr,enum HdmiDeepColor color)1290 int32_t HdmiCntlrDeepColorSet(struct HdmiCntlr *cntlr, enum HdmiDeepColor color)
1291 {
1292     if (cntlr == NULL || cntlr->ops == NULL) {
1293         return HDF_ERR_INVALID_OBJECT;
1294     }
1295 
1296     if (cntlr->attr.commAttr.colorSpace == HDMI_COLOR_SPACE_YCBCR422) {
1297         if (color != HDMI_DEEP_COLOR_24BITS && color != HDMI_DEEP_COLOR_OFF) {
1298             HDF_LOGE("not support deepcolor %u when colorspace is ycbcr422.", color);
1299             return HDF_ERR_INVALID_PARAM;
1300         }
1301     }
1302 
1303     /* if the current hdmi mode is dolby, deep color set is invalid. */
1304     if (cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_DOLBY_NORMAL ||
1305         cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_DOLBY_TUNNELING) {
1306         HDF_LOGD("don't change deepcolor when dolby mode is %u.", cntlr->attr.hdrAttr.mode);
1307         return HDF_ERR_NOT_SUPPORT;
1308     }
1309 
1310     cntlr->attr.commAttr.deepColor = color;
1311     HdmiCntlrAvmuteSet(cntlr, true);
1312     HdmiAttrUpdate(cntlr);
1313     HdmiCntlrAvmuteSet(cntlr, false);
1314     return HDF_SUCCESS;
1315 }
1316 
HdmiCntlrDeepColorGet(struct HdmiCntlr * cntlr,enum HdmiDeepColor * color)1317 int32_t HdmiCntlrDeepColorGet(struct HdmiCntlr *cntlr, enum HdmiDeepColor *color)
1318 {
1319     if (cntlr == NULL || cntlr->ops == NULL) {
1320         return HDF_ERR_INVALID_OBJECT;
1321     }
1322     if (color == NULL) {
1323         return HDF_ERR_INVALID_PARAM;
1324     }
1325 
1326     *color = cntlr->attr.commAttr.deepColor;
1327     return HDF_SUCCESS;
1328 }
1329 
HdmiCntlrSetVideoAttribute(struct HdmiCntlr * cntlr,struct HdmiVideoAttr * attr)1330 int32_t HdmiCntlrSetVideoAttribute(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr)
1331 {
1332     struct HdmiHardwareStatus hwStatus = {0};
1333 
1334     if (cntlr == NULL || cntlr->ops == NULL) {
1335         return HDF_ERR_INVALID_OBJECT;
1336     }
1337     if (attr == NULL) {
1338         return HDF_ERR_INVALID_PARAM;
1339     }
1340 
1341     cntlr->attr.videoAttr = *attr;
1342 
1343     if (cntlr->ops->hardWareStatusGet == NULL) {
1344         return HDF_ERR_NOT_SUPPORT;
1345     }
1346 
1347     HdmiCntlrLock(cntlr);
1348     cntlr->ops->hardWareStatusGet(cntlr, &hwStatus);
1349     HdmiCntlrUnlock(cntlr);
1350     return HdmiVedioAttrHandle(cntlr, &hwStatus);
1351 }
1352 
HdmiCntlrSetAudioAttribute(struct HdmiCntlr * cntlr,struct HdmiAudioAttr * attr)1353 int32_t HdmiCntlrSetAudioAttribute(struct HdmiCntlr *cntlr, struct HdmiAudioAttr *attr)
1354 {
1355     if (cntlr == NULL || cntlr->ops == NULL) {
1356         return HDF_ERR_INVALID_OBJECT;
1357     }
1358     if (attr == NULL) {
1359         return HDF_ERR_INVALID_PARAM;
1360     }
1361 
1362     cntlr->attr.audioAttr = *attr;
1363     return HdmiAudioAttrHandle(cntlr);
1364 }
1365 
HdmiCntlrSetHdrAttribute(struct HdmiCntlr * cntlr,struct HdmiHdrAttr * attr)1366 int32_t HdmiCntlrSetHdrAttribute(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *attr)
1367 {
1368     if (cntlr == NULL || cntlr->ops == NULL) {
1369         return HDF_ERR_INVALID_OBJECT;
1370     }
1371     if (attr == NULL) {
1372         return HDF_ERR_INVALID_PARAM;
1373     }
1374 
1375     return HdmiHdrAttrHandle(cntlr->hdr, attr);
1376 }
1377 
HdmiCntlrInfoFrameGet(struct HdmiCntlr * cntlr,enum HdmiPacketType type,union HdmiInfoFrameInfo * frame)1378 int32_t HdmiCntlrInfoFrameGet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame)
1379 {
1380     if (cntlr == NULL) {
1381         return HDF_ERR_INVALID_OBJECT;
1382     }
1383     return HdmiInfoFrameGetInfo(&(cntlr->infoFrame), type, frame);
1384 }
1385 
HdmiCntlrInfoFrameSet(struct HdmiCntlr * cntlr,enum HdmiPacketType type,union HdmiInfoFrameInfo * frame)1386 int32_t HdmiCntlrInfoFrameSet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame)
1387 {
1388     if (cntlr == NULL || cntlr->ops == NULL) {
1389         return HDF_ERR_INVALID_OBJECT;
1390     }
1391     if (frame == NULL) {
1392         return HDF_ERR_INVALID_PARAM;
1393     }
1394     return HdmiInfoFrameSetInfo(&(cntlr->infoFrame), type, frame);
1395 }
1396 
HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdmiHpdCallbackInfo * callback)1397 int32_t HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdmiHpdCallbackInfo *callback)
1398 {
1399     if (cntlr == NULL) {
1400         return HDF_ERR_INVALID_OBJECT;
1401     }
1402     if (callback == NULL) {
1403         return HDF_ERR_INVALID_PARAM;
1404     }
1405 
1406     cntlr->event.callback.data = callback->data;
1407     cntlr->event.callback.callbackFunc = callback->callbackFunc;
1408     return HDF_SUCCESS;
1409 }
1410 
HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr * cntlr)1411 int32_t HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr *cntlr)
1412 {
1413     if (cntlr == NULL) {
1414         return HDF_ERR_INVALID_OBJECT;
1415     }
1416     cntlr->event.callback.data = NULL;
1417     cntlr->event.callback.callbackFunc = NULL;
1418     return HDF_SUCCESS;
1419 }
1420 
HdmiCntlrClose(struct HdmiCntlr * cntlr)1421 void HdmiCntlrClose(struct HdmiCntlr *cntlr)
1422 {
1423     if (cntlr == NULL || cntlr->ops == NULL) {
1424         return;
1425     }
1426 
1427     if ((cntlr->state & HDMI_CNTLR_STATE_START) > 0) {
1428         HdmiCntlrStop(cntlr);
1429     }
1430 
1431     HdmiInfoFrameDeInit(cntlr);
1432     HdmiDdcDeinit(cntlr);
1433     HdmiScdcDeinit(cntlr);
1434     HdmiFrlDeinit(cntlr);
1435     HdmiHdcpDeinit(cntlr);
1436     HdmiCecDeinit(cntlr);
1437     HdmiHdrDeinit(cntlr);
1438     cntlr->state = HDMI_CNTLR_STATE_CLOSE;
1439 }
1440