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(
354 struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps, 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(
403 struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps, 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(
438 struct HdmiCntlr *cntlr, struct DeviceResourceIface *drsOps, 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 && cntlr->cap.baseCap.bits.frl > 0) {
568 return;
569 }
570
571 if (cntlr->cap.baseCap.bits.scdc > 0) {
572 ret = HdmiScdcFillScrambleCap(cntlr->scdc, &scramble, &tmdsMode);
573 if (ret != HDF_SUCCESS) {
574 return;
575 }
576 } else {
577 tmdsMode = (commAttr->enableHdmi == true) ? HDMI_TMDS_MODE_HDMI_1_4 : HDMI_TMDS_MODE_DVI;
578 }
579
580 cntlr->tmdsMode = tmdsMode;
581 HdmiCntlrTmdsModeSet(cntlr, tmdsMode);
582 HdmiCntlrReset(cntlr);
583
584 if (cntlr->cap.baseCap.bits.scdc > 0 && HdmiEdidScdcSupport(cntlr->hdmi) == true) {
585 ret = HdmiScdcScrambleGet(cntlr->scdc, &curScramble);
586 if (ret != HDF_SUCCESS) {
587 return;
588 }
589 if (scramble.sinkScramble != curScramble.sinkScramble ||
590 scramble.sourceScramble != curScramble.sourceScramble ||
591 scramble.tmdsBitClockRatio40 != curScramble.tmdsBitClockRatio40) {
592 (void)HdmiScdcScrambleSet(cntlr->scdc, &scramble);
593 }
594 }
595 }
596
HdmiCommonAttrInit(struct HdmiCntlr * cntlr)597 static void HdmiCommonAttrInit(struct HdmiCntlr *cntlr)
598 {
599 struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
600
601 commAttr->enableHdmi = true;
602 commAttr->enableVideo = true;
603 commAttr->enableAudio = true;
604 commAttr->audio = true;
605 commAttr->avi = true;
606 commAttr->hdcpMode = HDMI_HDCP_MODE_1_4;
607 commAttr->colorSpace = (enum HdmiColorSpace)cntlr->cap.colorSpace;
608 commAttr->quantization = (enum HdmiQuantizationRange)cntlr->cap.quantization;
609 }
610
HdmiVideoAttrInit(struct HdmiCntlr * cntlr)611 static void HdmiVideoAttrInit(struct HdmiCntlr *cntlr)
612 {
613 struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
614 bool colorimetry601;
615
616 videoAttr->timing = (enum HdmiVideoTiming)cntlr->cap.videoTiming;
617 colorimetry601 = ((videoAttr->timing == HDMI_VIDEO_TIMING_720X480P60) ||
618 (videoAttr->timing == HDMI_VIDEO_TIMING_720X576P50) || (videoAttr->timing == HDMI_VIDEO_TIMING_1440X240P60) ||
619 (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60) || (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) ||
620 (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576P50) || (videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I60));
621
622 if (videoAttr->timing == HDMI_VIDEO_TIMING_640X480P60) {
623 videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
624 videoAttr->aspect = HDMI_PICTURE_ASPECT_4_3;
625 } else if (colorimetry601 == true) {
626 videoAttr->colorimetry = HDMI_COLORIMETRY_ITU601;
627 videoAttr->aspect = HDMI_PICTURE_ASPECT_4_3;
628 } else if (videoAttr->timing <= HDMI_VIDEO_TIMING_4096X2160P120 &&
629 videoAttr->timing >= HDMI_VIDEO_TIMING_4096X2160P24) {
630 videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
631 videoAttr->aspect = HDMI_PICTURE_ASPECT_256_135;
632 } else {
633 videoAttr->colorimetry = HDMI_COLORIMETRY_ITU709;
634 videoAttr->aspect = HDMI_PICTURE_ASPECT_16_9;
635 }
636
637 videoAttr->pixelRepeat = 1;
638 if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 || videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
639 videoAttr->pixelRepeat = 2; // 2 means the number of repetitions for each pixel
640 }
641
642 if (videoAttr->timing <= HDMI_VIDEO_TIMING_640X480P60) {
643 videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
644 } else {
645 videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
646 }
647
648 if (videoAttr->timing != HDMI_VIDEO_TIMING_NONE && videoAttr->timing != HDMI_VIDEO_TIMING_640X480P60) {
649 videoAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
650 } else {
651 videoAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
652 }
653
654 videoAttr->_3dStruct = HDMI_VS_VIDEO_3D_BUTT;
655 videoAttr->activeAspect = HDMI_ACTIVE_FORMAT_ASPECT_PICTURE;
656 }
657
HdmiAudioAttrInit(struct HdmiCntlr * cntlr)658 static void HdmiAudioAttrInit(struct HdmiCntlr *cntlr)
659 {
660 struct HdmiAudioAttr *audioAttr = &(cntlr->attr.audioAttr);
661
662 audioAttr->ifType = (enum HdmiAudioInterfaceType)cntlr->cap.audioIfType;
663 audioAttr->bitDepth = (enum HdmiAudioBitDepth)cntlr->cap.audioBitDepth;
664 audioAttr->sampleRate = (enum HdmiSampleRate)cntlr->cap.audioSampleRate;
665 audioAttr->channels = (enum HdmiAudioFormatChannel)cntlr->cap.audioChannels;
666 }
667
HdmiHdrAttrInit(struct HdmiCntlr * cntlr)668 static void HdmiHdrAttrInit(struct HdmiCntlr *cntlr)
669 {
670 struct HdmiHdrAttr *hdrAttr = &(cntlr->attr.hdrAttr);
671
672 hdrAttr->userMode = (enum HdmiHdrUserMode)cntlr->cap.hdrUserMode;
673 hdrAttr->colorimetry = (enum HdmiHdrColormetry)cntlr->cap.hdrColorimetry;
674 }
675
HdmiAttrInit(struct HdmiCntlr * cntlr)676 static void HdmiAttrInit(struct HdmiCntlr *cntlr)
677 {
678 HdmiCommonAttrInit(cntlr);
679 HdmiVideoAttrInit(cntlr);
680 HdmiAudioAttrInit(cntlr);
681 HdmiHdrAttrInit(cntlr);
682 }
683
HdmiCntlrOpen(struct HdmiCntlr * cntlr)684 int32_t HdmiCntlrOpen(struct HdmiCntlr *cntlr)
685 {
686 int32_t ret;
687
688 if (cntlr == NULL) {
689 return HDF_ERR_INVALID_OBJECT;
690 }
691 HdmiInfoFrameInit(cntlr);
692 HdmiDdcInit(cntlr);
693 HdmiScdcInit(cntlr);
694 HdmiFrlInit(cntlr);
695 HdmiHdcpInit(cntlr);
696 HdmiCecInit(cntlr);
697 HdmiHdrInit(cntlr);
698 HdmiAttrInit(cntlr);
699 HdmiCntlrHardWareInit(cntlr);
700 /* HDCP on. */
701 if ((cntlr->cap.baseCap.data & HDMI_CAP_HDCP_MARK) > 0) {
702 ret = HdmiHdcpOpen(cntlr->hdcp);
703 if (ret != HDF_SUCCESS) {
704 HdmiHdcpClose(cntlr->hdcp);
705 }
706 }
707 cntlr->state |= HDMI_CNTLR_STATE_OPEN;
708 return HDF_SUCCESS;
709 }
710
HdmiCntlrStart(struct HdmiCntlr * cntlr)711 int32_t HdmiCntlrStart(struct HdmiCntlr *cntlr)
712 {
713 if (cntlr == NULL || cntlr->ops == NULL) {
714 return HDF_ERR_INVALID_OBJECT;
715 }
716
717 HdmiCntlrLowPowerSet(cntlr, false);
718 /* select mode */
719 HdmiCntlrModeSelect(cntlr);
720 HdmiCntlrAvmuteSet(cntlr, false);
721
722 if (cntlr->cap.baseCap.bits.hdr > 0 && cntlr->cap.baseCap.bits.frl > 0) {
723 HdmiFrlEnable(cntlr->frl, true);
724 } else {
725 /* TMDS Transfer. */
726 if (cntlr->ops->phyOutputEnable != NULL) {
727 HdmiCntlrLock(cntlr);
728 cntlr->ops->phyOutputEnable(cntlr, true);
729 HdmiCntlrUnlock(cntlr);
730 }
731 }
732
733 HdmiCntlrAudioPathEnable(cntlr, true);
734 HdmiCntlrBlackDataSet(cntlr, false);
735
736 cntlr->state |= HDMI_CNTLR_STATE_START;
737 return HDF_SUCCESS;
738 }
739
HdmiCntlrStop(struct HdmiCntlr * cntlr)740 int32_t HdmiCntlrStop(struct HdmiCntlr *cntlr)
741 {
742 if (cntlr == NULL || cntlr->ops == NULL) {
743 return HDF_ERR_INVALID_OBJECT;
744 }
745
746 HdmiCntlrLock(cntlr);
747 if (cntlr->ops->audioPathEnable != NULL) {
748 cntlr->ops->audioPathEnable(cntlr, false);
749 }
750 if (cntlr->ops->avmuteSet != NULL) {
751 cntlr->ops->avmuteSet(cntlr, true);
752 }
753 if (cntlr->ops->blackDataSet != NULL) {
754 cntlr->ops->blackDataSet(cntlr, true);
755 }
756 HdmiFrlEnable(cntlr->frl, false);
757 if (cntlr->ops->phyOutputEnable != NULL) {
758 cntlr->ops->phyOutputEnable(cntlr, false);
759 }
760 HdmiCntlrUnlock(cntlr);
761
762 HdmiCntlrLowPowerSet(cntlr, true);
763 cntlr->state = HDMI_CNTLR_STATE_STOP;
764 return HDF_SUCCESS;
765 }
766
HdmiTmdsClockUpdate(struct HdmiVideoAttr * videoAttr,struct HdmiCommonAttr * commAttr)767 static void HdmiTmdsClockUpdate(struct HdmiVideoAttr *videoAttr, struct HdmiCommonAttr *commAttr)
768 {
769 /*
770 * Video at the default 24-bit color depth is carried at a TMDS clock rate equal to the pixel clock rate.
771 * YCBCB 4:2:0 video is carried at a TMDS clock rate equal to the 1/2 pixel clock rate.
772 */
773 if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR420) {
774 videoAttr->tmdsClock = HDMI_MULTIPLE_0P5(videoAttr->pixelClock);
775 return;
776 }
777
778 /*
779 * The TMDS clock rate is ibcreased by the ratio of the pixel size to 24-bits:
780 * 24-bit mode: TMDS clock is 1.0 X pixel clock;
781 * 30-bit mode: TMDS clock is 1.25 X pixel clock;
782 * 36-bit mode: TMDS clock is 1.5 X pixel clock;
783 * 48-bit mode: TMDS clock is 2.0 X pixel clock;
784 */
785 videoAttr->tmdsClock = videoAttr->pixelClock;
786 if (commAttr->colorSpace != HDMI_COLOR_SPACE_YCBCR422) {
787 if (commAttr->deepColor == HDMI_DEEP_COLOR_30BITS) {
788 videoAttr->tmdsClock = HDMI_MULTIPLE_1P25(videoAttr->pixelClock);
789 } else if (commAttr->deepColor == HDMI_DEEP_COLOR_36BITS) {
790 videoAttr->tmdsClock = HDMI_MULTIPLE_1P5(videoAttr->pixelClock);
791 } else if (commAttr->deepColor == HDMI_DEEP_COLOR_48BITS) {
792 videoAttr->tmdsClock = HDMI_MULTIPLE_2P0(videoAttr->pixelClock);
793 }
794 } else {
795 if ((commAttr->deepColor != HDMI_DEEP_COLOR_OFF) && (commAttr->deepColor != HDMI_DEEP_COLOR_24BITS)) {
796 HDF_LOGD("Y422 foce deepcolor 8bit");
797 commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
798 }
799 if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 || videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
800 HDF_LOGD("Y422 is not support at pal and ntsc, force adapt to rgb!");
801 commAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
802 }
803 }
804 }
805
HdmiYcbcr420FormatCheck(struct HdmiSinkDeviceCapability * sinkCap,struct HdmiVideoAttr * videoAttr)806 static bool HdmiYcbcr420FormatCheck(struct HdmiSinkDeviceCapability *sinkCap, struct HdmiVideoAttr *videoAttr)
807 {
808 uint32_t i;
809 enum HdmiVic vic;
810
811 vic = HdmiCommonGetVic(videoAttr->timing, videoAttr->aspect, false);
812 if (vic == HDMI_VIC_NONE) {
813 HDF_LOGD("Y420 not have supported vic.");
814 return false;
815 }
816
817 for (i = 0; i < sinkCap->y420Cap.SupportY420VicNum; i++) {
818 if (vic == sinkCap->y420Cap.SupportY420Format[i]) {
819 HDF_LOGD("Y420 supported vic is %d.", vic);
820 return true;
821 }
822 }
823
824 for (i = 0; i < sinkCap->y420Cap.onlySupportY420VicNum; i++) {
825 if (vic == sinkCap->y420Cap.onlySupportY420Format[i]) {
826 HDF_LOGD("Y420 supported vic is %d.", vic);
827 return true;
828 }
829 }
830
831 HDF_LOGD("Y420 have no supported vic.");
832 return false;
833 }
834
HdmiColorSpaceCheck(struct HdmiCntlr * cntlr,struct HdmiSinkDeviceCapability * sinkCap,uint32_t maxTmdsClk)835 static int32_t HdmiColorSpaceCheck(
836 struct HdmiCntlr *cntlr, struct HdmiSinkDeviceCapability *sinkCap, uint32_t maxTmdsClk)
837 {
838 struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
839 struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
840 union HdmiCap *cap = &(cntlr->cap.baseCap);
841 bool supportColorSpace = false;
842
843 if (videoAttr->pixelClock > maxTmdsClk && commAttr->colorSpace != HDMI_COLOR_SPACE_YCBCR420) {
844 return HDF_ERR_INVALID_PARAM;
845 }
846
847 switch (commAttr->colorSpace) {
848 case HDMI_COLOR_SPACE_RGB:
849 supportColorSpace = true;
850 if ((sinkCap->colorSpace.rgb444 && cap->bits.rgb444) == false) {
851 HDF_LOGD("sink or source not support RGB!");
852 }
853 break;
854 case HDMI_COLOR_SPACE_YCBCR422:
855 supportColorSpace = sinkCap->colorSpace.ycbcr422 && cap->bits.ycbcr422;
856 break;
857 case HDMI_COLOR_SPACE_YCBCR444:
858 supportColorSpace = sinkCap->colorSpace.ycbcr444 && cap->bits.ycbcr444;
859 break;
860 case HDMI_COLOR_SPACE_YCBCR420:
861 supportColorSpace = cap->bits.ycbcr420 && HdmiYcbcr420FormatCheck(sinkCap, videoAttr);
862 break;
863 default:
864 HDF_LOGE("unknow color_space = %u!\n", commAttr->colorSpace);
865 break;
866 }
867
868 if (supportColorSpace != true) {
869 return HDF_ERR_INVALID_PARAM;
870 }
871 return HDF_SUCCESS;
872 }
873
HdmiDeepColor10bitsCheck(const struct HdmiSinkDeviceCapability * sinkCap,const struct HdmiCommonAttr * commAttr,const union HdmiCap * cap,uint32_t * tmdsClock,bool * supportDeepColor)874 static void HdmiDeepColor10bitsCheck(const struct HdmiSinkDeviceCapability *sinkCap,
875 const struct HdmiCommonAttr *commAttr, const union HdmiCap *cap, uint32_t *tmdsClock, bool *supportDeepColor)
876 {
877 uint32_t tmpTmdsClk = *tmdsClock;
878
879 switch (commAttr->colorSpace) {
880 case HDMI_COLOR_SPACE_RGB:
881 tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
882 *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc30bit && cap->bits.deepColor10bits) ? true : false;
883 break;
884 case HDMI_COLOR_SPACE_YCBCR444:
885 tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
886 *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc30bit && cap->bits.deepColor10bits &&
887 sinkCap->vsdbInfo.deepColor.dcY444) ?
888 true :
889 false;
890 break;
891 case HDMI_COLOR_SPACE_YCBCR420:
892 tmpTmdsClk = HDMI_MULTIPLE_1P25(tmpTmdsClk);
893 *supportDeepColor = (sinkCap->hfVsdbInfo.dc.dc30bit && cap->bits.deepColor10bits) ? true : false;
894 break;
895 default:
896 /* Y422, ignore deepclr */
897 *supportDeepColor = true;
898 break;
899 }
900 *tmdsClock = tmpTmdsClk;
901 }
902
HdmiDeepColor12bitsCheck(const struct HdmiSinkDeviceCapability * sinkCap,const struct HdmiCommonAttr * commAttr,const union HdmiCap * cap,uint32_t * tmdsClock,bool * supportDeepColor)903 static void HdmiDeepColor12bitsCheck(const struct HdmiSinkDeviceCapability *sinkCap,
904 const struct HdmiCommonAttr *commAttr, const union HdmiCap *cap, uint32_t *tmdsClock, bool *supportDeepColor)
905 {
906 uint32_t tmpTmdsClk = *tmdsClock;
907
908 switch (commAttr->colorSpace) {
909 case HDMI_COLOR_SPACE_RGB:
910 tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
911 *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc36bit && cap->bits.deepColor12bits) ? true : false;
912 break;
913 case HDMI_COLOR_SPACE_YCBCR444:
914 tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
915 *supportDeepColor = (sinkCap->vsdbInfo.deepColor.dc36bit && cap->bits.deepColor12bits &&
916 sinkCap->vsdbInfo.deepColor.dcY444) ?
917 true :
918 false;
919 break;
920 case HDMI_COLOR_SPACE_YCBCR420:
921 tmpTmdsClk = HDMI_MULTIPLE_1P5(tmpTmdsClk);
922 *supportDeepColor = (sinkCap->hfVsdbInfo.dc.dc36bit && cap->bits.deepColor12bits) ? true : false;
923 break;
924 default:
925 /* Y422, ignore deepclr */
926 *supportDeepColor = true;
927 break;
928 }
929 *tmdsClock = tmpTmdsClk;
930 }
931
HdmiDeepColorCheck(struct HdmiCntlr * cntlr,struct HdmiSinkDeviceCapability * sinkCap,uint32_t maxTmdsClk)932 static int32_t HdmiDeepColorCheck(
933 struct HdmiCntlr *cntlr, struct HdmiSinkDeviceCapability *sinkCap, uint32_t maxTmdsClk)
934 {
935 struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
936 struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
937 union HdmiCap *cap = &(cntlr->cap.baseCap);
938 uint32_t tmdsClock = videoAttr->pixelClock;
939 bool supportDeepColor = false;
940
941 if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR420) {
942 tmdsClock = HDMI_MULTIPLE_0P5(tmdsClock);
943 }
944
945 switch (commAttr->deepColor) {
946 case HDMI_DEEP_COLOR_30BITS:
947 HdmiDeepColor10bitsCheck(sinkCap, commAttr, cap, &tmdsClock, &supportDeepColor);
948 break;
949 case HDMI_DEEP_COLOR_36BITS:
950 HdmiDeepColor12bitsCheck(sinkCap, commAttr, cap, &tmdsClock, &supportDeepColor);
951 break;
952 default:
953 commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
954 supportDeepColor = true;
955 break;
956 }
957
958 if (supportDeepColor == false || tmdsClock > maxTmdsClk) {
959 return HDF_ERR_INVALID_PARAM;
960 }
961 videoAttr->tmdsClock = tmdsClock;
962 /* Y422 default 12bit output, deep_color force adapt to 8bit(24bit). */
963 if (commAttr->colorSpace == HDMI_COLOR_SPACE_YCBCR422) {
964 if (videoAttr->timing == HDMI_VIDEO_TIMING_1440X480I60 || videoAttr->timing == HDMI_VIDEO_TIMING_1440X576I50) {
965 HDF_LOGD("force change colorspace to RGB!");
966 commAttr->colorSpace = HDMI_COLOR_SPACE_RGB;
967 }
968 if ((videoAttr->deepColor != HDMI_DEEP_COLOR_24BITS) && (videoAttr->deepColor != HDMI_DEEP_COLOR_OFF)) {
969 videoAttr->deepColor = HDMI_DEEP_COLOR_OFF;
970 HDF_LOGD("when Y422, deep_color not support 10/12bit!");
971 }
972 }
973 return HDF_SUCCESS;
974 }
975
HdmiColorBitSelect(struct HdmiCntlr * cntlr)976 static int32_t HdmiColorBitSelect(struct HdmiCntlr *cntlr)
977 {
978 struct HdmiSinkDeviceCapability *sinkCap = NULL;
979 uint32_t maxTmdsClk = 0;
980
981 /* DVI mode, must set RGB and DEEP_COLOR_OFF */
982 if (cntlr->attr.commAttr.enableHdmi == false) {
983 if (cntlr->attr.commAttr.colorSpace != HDMI_COLOR_SPACE_RGB) {
984 HDF_LOGE("DVI mode, the color space is not RGB!");
985 return HDF_ERR_INVALID_PARAM;
986 }
987 cntlr->attr.commAttr.deepColor = HDMI_DEEP_COLOR_OFF;
988 cntlr->attr.videoAttr.tmdsClock = cntlr->attr.videoAttr.pixelClock;
989 return HDF_SUCCESS;
990 }
991
992 /* FRL mode. */
993 if (cntlr->cap.baseCap.bits.hdr > 0) {
994 HdmiTmdsClockUpdate(&(cntlr->attr.videoAttr), &(cntlr->attr.commAttr));
995 if (cntlr->attr.videoAttr.tmdsClock > HDMI_HDMI20_MAX_TMDS_RATE) {
996 HDF_LOGD("HDMI2.1, tmds clock exceed max.");
997 return HDF_SUCCESS;
998 }
999 }
1000
1001 sinkCap = HdmiGetSinkCapability(cntlr->hdmi);
1002 if (sinkCap == NULL) {
1003 HdmiTmdsClockUpdate(&(cntlr->attr.videoAttr), &(cntlr->attr.commAttr));
1004 return HDF_SUCCESS;
1005 }
1006
1007 if (sinkCap->maxTmdsClk == 0) {
1008 /* use default clock. */
1009 maxTmdsClk = cntlr->cap.defTmdsClock;
1010 } else {
1011 maxTmdsClk = (sinkCap->maxTmdsClk < cntlr->cap.maxTmdsClock) ? sinkCap->maxTmdsClk : cntlr->cap.maxTmdsClock;
1012 }
1013 /* MHz is converted to KHz */
1014 maxTmdsClk *= 1000;
1015
1016 if (HdmiColorSpaceCheck(cntlr, sinkCap, maxTmdsClk) != HDF_SUCCESS) {
1017 return HDF_ERR_INVALID_PARAM;
1018 }
1019 if (HdmiDeepColorCheck(cntlr, sinkCap, maxTmdsClk) != HDF_SUCCESS) {
1020 return HDF_ERR_INVALID_PARAM;
1021 }
1022 return HDF_SUCCESS;
1023 }
1024
HdmiAudioAttrHandle(struct HdmiCntlr * cntlr)1025 static int32_t HdmiAudioAttrHandle(struct HdmiCntlr *cntlr)
1026 {
1027 struct HdmiAudioConfigInfo audioCfg = {0};
1028 struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
1029 struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
1030 struct HdmiAudioAttr *audioAttr = &(cntlr->attr.audioAttr);
1031 int32_t ret;
1032
1033 audioCfg.downSample = audioAttr->downSample;
1034 audioCfg.channels = audioAttr->channels;
1035 audioCfg.bitDepth = audioAttr->bitDepth;
1036 audioCfg.sampleRate = audioAttr->sampleRate;
1037 audioCfg.ifType = audioAttr->ifType;
1038 audioCfg.enable = (commAttr->enableAudio) && (commAttr->enableHdmi);
1039 audioCfg.tmdsClock = videoAttr->tmdsClock;
1040 audioCfg.pixelRepeat = videoAttr->pixelRepeat;
1041
1042 HdmiCntlrAudioPathEnable(cntlr, false);
1043 HdmiCntlrAudioPathSet(cntlr, &audioCfg);
1044 ret = HdmiAudioInfoFrameSend(&(cntlr->infoFrame), ((commAttr->enableAudio) && (commAttr->audio)));
1045 HdmiCntlrAudioPathEnable(cntlr, true);
1046 return ret;
1047 }
1048
HdmiHdrModeCheck(struct HdmiCommonAttr * commAttr,struct HdmiVideoAttr * videoAttr,const struct HdmiHdrAttr * hdrAttr)1049 static void HdmiHdrModeCheck(
1050 struct HdmiCommonAttr *commAttr, struct HdmiVideoAttr *videoAttr, const struct HdmiHdrAttr *hdrAttr)
1051 {
1052 switch (hdrAttr->userMode) {
1053 case HDMI_HDR_USERMODE_DOLBY:
1054 videoAttr->yccQuantization = HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
1055 commAttr->colorSpace = HDMI_COLOR_SPACE_YCBCR444;
1056 videoAttr->tmdsClock = videoAttr->pixelClock;
1057 commAttr->deepColor = HDMI_DEEP_COLOR_24BITS;
1058 videoAttr->quantization = HDMI_QUANTIZATION_RANGE_DEFAULT;
1059 break;
1060 case HDMI_HDR_USERMODE_HDR10:
1061 if (hdrAttr->mode == HDMI_HDR_MODE_CEA_861_3) {
1062 if (hdrAttr->colorimetry > HDMI_HDR_COLORIMETRY_EXTENDED) {
1063 videoAttr->colorimetry = HDMI_COLORIMETRY_EXTENDED;
1064 videoAttr->extColorimetry =
1065 (enum HdmiExtendedColorimetry)(hdrAttr->colorimetry - HDMI_HDR_EXTENDED_COLORIMETRY_XV_YCC_601);
1066 } else {
1067 videoAttr->colorimetry = (enum HdmiColorimetry)(hdrAttr->colorimetry);
1068 videoAttr->extColorimetry = HDMI_EXTENDED_COLORIMETRY_BUTT;
1069 }
1070 commAttr->xvyccMode = false;
1071 }
1072 break;
1073 default:
1074 break;
1075 }
1076 }
1077
HdmiFillVideoAttrFromHardwareStatus(struct HdmiVideoAttr * videoAttr,const struct HdmiHardwareStatus * hwStatus,struct HdmiCommonAttr * commAttr)1078 static void HdmiFillVideoAttrFromHardwareStatus(
1079 struct HdmiVideoAttr *videoAttr, const struct HdmiHardwareStatus *hwStatus, struct HdmiCommonAttr *commAttr)
1080 {
1081 bool rgb;
1082 bool aspectIs256;
1083 uint8_t vic;
1084 enum HdmiVsVideoFormat format;
1085 enum Hdmi4kVic vic4k;
1086
1087 rgb = ((hwStatus->videoStatus.rgb2Ycbcr) ||
1088 ((!hwStatus->videoStatus.ycbcr2Rgb) && (hwStatus->videoStatus.outColorSpace == HDMI_COLOR_SPACE_RGB)));
1089 videoAttr->colorSpace = (rgb == true) ? HDMI_COLOR_SPACE_RGB : HDMI_COLOR_SPACE_YCBCR444;
1090 /*
1091 * avi[0]: Packet Type = 0x82
1092 * avi[1]: Version = 0x02
1093 * avi[2]: BIT[7:5]: 0, BIT[4:0]: Length = 0x0D
1094 * avi[3]: CheckSum
1095 * avi[4]: BIT[7]: Reserved, BIT[6:5]: RGB or YCbCr indicator, BIT[4]: Active information present
1096 * BIT[3:2]: Bar info data valid, BIT[1:0]: Scan information
1097 * avi[5]: BIT[7:6]: Colorimetry, BIT[5:4]: Picture aspect ratio, BIT[3:0]: Active format aspect ratio
1098 * avi[6]: BIT[7]: IT content, BIT[6:4]: Extended colorimetry, BIT[3:2]: Quantization range,
1099 * BIT[1:0]: Non-uniform picture scaling
1100 * avi[7]: BIT[7]: Reserved, BIT[6:0]: Video format identification code
1101 * avi[8]: BIT[7:6]: YCC quantization range, BIT[5:4]: Content type, BIT[3:0]: Picture repetition factor
1102 * ...
1103 */
1104 if (hwStatus->infoFrameStatus.aviEnable) {
1105 vic = hwStatus->infoFrameStatus.avi[7];
1106 /*
1107 * when the timing is 4096*2160, the aspect ratio in AVI infoFrame is 0
1108 * (but the real aspect ratio is 256:135<0x04>, the video_code is 0)
1109 * vsif[0]: Packet Type = 0x81
1110 * vsif[1]: Version = 0x01
1111 * vsif[2]: BIT[7:5]: 0, Bit[4:0]: Length, defines the length of HDMI vendor specific infoFrame payload.
1112 * vsif[3]: Checksum.
1113 * vsif[4]--vsif[6]: 24bit IEEE Registration Identifier(0x000C03)(least significant byte first).
1114 * vsif[7]: BIT[7]: reserved for future, BIT[6:5]: HDMI_Video_Format, BIT[4:0]: reserved.
1115 * vsif[8]: HDMI_VIC, 0x04: 4K*2K @24Hz(SMPTE).
1116 */
1117 aspectIs256 = (((vic == 0) && (hwStatus->infoFrameStatus.vsif[8] == 0x04)) ||
1118 ((vic >= HDMI_VIC_4096X2160P25_256_135) && (vic <= HDMI_VIC_4096X2160P60_256_135)));
1119 videoAttr->aspect = (aspectIs256 == true) ? HDMI_PICTURE_ASPECT_256_135 :
1120 ((hwStatus->infoFrameStatus.avi[5] >> 4) & 0x3); /* 4'b, BIT[2:1] */
1121 videoAttr->activeAspect = hwStatus->infoFrameStatus.avi[5] & 0xf;
1122 videoAttr->colorimetry = (hwStatus->infoFrameStatus.avi[5] >> 6) & 0x3; /* 6'b, BIT[2:1] */
1123 videoAttr->quantization = (hwStatus->infoFrameStatus.avi[6] >> 2) & 0x3; /* 2'b, BIT[2:1] */
1124 videoAttr->extColorimetry = (hwStatus->infoFrameStatus.avi[6] >> 4) & 0x07; /* 4'b, BIT[3:1] */
1125 videoAttr->yccQuantization = (hwStatus->infoFrameStatus.avi[8] >> 6) & 0x3; /* 6'b, BIT[2:1] */
1126 videoAttr->pixelRepeat = (hwStatus->infoFrameStatus.avi[8] & 0xf) + 1;
1127 videoAttr->timing = HdmiCommonGetVideoTiming(vic, videoAttr->aspect);
1128 if ((!hwStatus->infoFrameStatus.vsifEnable) && (!vic)) {
1129 videoAttr->timing = HDMI_VIDEO_TIMING_NONE;
1130 }
1131 commAttr->quantization = (commAttr->colorSpace == HDMI_COLOR_SPACE_RGB) ?
1132 videoAttr->quantization : (videoAttr->yccQuantization + 1);
1133 }
1134
1135 videoAttr->_3dStruct = HDMI_VS_VIDEO_3D_BUTT;
1136 if (hwStatus->infoFrameStatus.vsifEnable) {
1137 format = (hwStatus->infoFrameStatus.vsif[7] >> 5) & 0x3; /* 5'b, BIT[2:1] */
1138 if (format == HDMI_VS_VIDEO_FORMAT_4K) {
1139 vic4k = hwStatus->infoFrameStatus.vsif[8];
1140 videoAttr->timing = HdmiCommonGetVideo4kTiming(vic4k);
1141 } else if (format == HDMI_VS_VIDEO_FORMAT_3D) {
1142 videoAttr->_3dStruct = (hwStatus->infoFrameStatus.vsif[8] >> 4) & 0xf; /* 4'b, BIT[4:1] */
1143 }
1144 }
1145 }
1146
HdmiFillCommonAttrFromHardwareStatus(struct HdmiCommonAttr * commAttr,const struct HdmiHardwareStatus * hwStatus,const struct HdmiAttr * attr)1147 static void HdmiFillCommonAttrFromHardwareStatus(
1148 struct HdmiCommonAttr *commAttr, const struct HdmiHardwareStatus *hwStatus, const struct HdmiAttr *attr)
1149 {
1150 bool dolby = false;
1151
1152 switch (hwStatus->commonStatus.tmdsMode) {
1153 case HDMI_TMDS_MODE_HDMI_1_4:
1154 case HDMI_TMDS_MODE_HDMI_2_0:
1155 commAttr->enableHdmi = true;
1156 commAttr->enableVideo = true;
1157 break;
1158 case HDMI_TMDS_MODE_DVI:
1159 commAttr->enableHdmi = false;
1160 commAttr->enableVideo = true;
1161 break;
1162 default:
1163 commAttr->enableHdmi = false;
1164 commAttr->enableVideo = false;
1165 break;
1166 }
1167
1168 commAttr->enableAudio = (hwStatus->audioStatus.enable && hwStatus->infoFrameStatus.audioEnable);
1169 commAttr->avi = hwStatus->infoFrameStatus.aviEnable;
1170 commAttr->audio = hwStatus->infoFrameStatus.audioEnable;
1171 commAttr->xvyccMode = hwStatus->infoFrameStatus.gdbEnable;
1172 commAttr->deepColor = HdmiCommonColorDepthConvertToDeepClolor(hwStatus->videoStatus.outBitDepth);
1173
1174 /* color space is ycbcr444 when the hdr mode is dolby. */
1175 dolby = ((attr->hdrAttr.userMode == HDMI_HDR_USERMODE_DOLBY) && (!hwStatus->videoStatus.rgb2Ycbcr) &&
1176 (!hwStatus->videoStatus.ycbcr2Rgb) && (!hwStatus->videoStatus.ycbcr444422) &&
1177 (!hwStatus->videoStatus.ycbcr422420) && (!hwStatus->videoStatus.ycbcr422444) &&
1178 (!hwStatus->videoStatus.ycbcr420422));
1179 commAttr->colorSpace = (dolby == true) ? HDMI_COLOR_SPACE_YCBCR444 : hwStatus->videoStatus.outColorSpace;
1180 }
1181
HdmiCommonAttrChanged(struct HdmiCommonAttr * curCommAttr,struct HdmiCommonAttr * commAttr)1182 static bool HdmiCommonAttrChanged(struct HdmiCommonAttr *curCommAttr, struct HdmiCommonAttr *commAttr)
1183 {
1184 bool change;
1185
1186 change = (commAttr->enableHdmi != curCommAttr->enableHdmi) || (commAttr->colorSpace != curCommAttr->colorSpace) ||
1187 (commAttr->xvyccMode != curCommAttr->xvyccMode) || (commAttr->avi != curCommAttr->avi) ||
1188 (commAttr->quantization != curCommAttr->quantization);
1189
1190 if (change == true) {
1191 return true;
1192 }
1193
1194 if (((commAttr->deepColor == HDMI_DEEP_COLOR_OFF) || (commAttr->deepColor == HDMI_DEEP_COLOR_24BITS)) &&
1195 ((curCommAttr->deepColor == HDMI_DEEP_COLOR_OFF) || (curCommAttr->deepColor == HDMI_DEEP_COLOR_24BITS))) {
1196 HDF_LOGI("deep color not change: %u", curCommAttr->deepColor);
1197 } else if (commAttr->deepColor != curCommAttr->deepColor) {
1198 return true;
1199 }
1200 return false;
1201 }
1202
HdmiVideoAttrChanged(struct HdmiVideoAttr * curVideoAttr,struct HdmiVideoAttr * videoAttr)1203 static bool HdmiVideoAttrChanged(struct HdmiVideoAttr *curVideoAttr, struct HdmiVideoAttr *videoAttr)
1204 {
1205 bool change;
1206
1207 change = (videoAttr->timing != curVideoAttr->timing) || (videoAttr->colorSpace != curVideoAttr->colorSpace) ||
1208 (videoAttr->_3dStruct != curVideoAttr->_3dStruct) || (videoAttr->pixelRepeat != curVideoAttr->pixelRepeat) ||
1209 (videoAttr->colorimetry != curVideoAttr->colorimetry) ||
1210 (videoAttr->extColorimetry != curVideoAttr->extColorimetry) ||
1211 (videoAttr->quantization != curVideoAttr->quantization) ||
1212 (videoAttr->yccQuantization != curVideoAttr->yccQuantization) || (videoAttr->aspect != curVideoAttr->aspect);
1213 return change;
1214 }
1215
HdmiVedioAttrHandle(struct HdmiCntlr * cntlr,struct HdmiHardwareStatus * hwStatus)1216 static int32_t HdmiVedioAttrHandle(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *hwStatus)
1217 {
1218 struct HdmiCommonAttr *commAttr = &(cntlr->attr.commAttr);
1219 struct HdmiVideoAttr *videoAttr = &(cntlr->attr.videoAttr);
1220 struct HdmiCommonAttr curCommAttr = {0};
1221 struct HdmiVideoAttr curVideoAttr = {0};
1222 int32_t ret;
1223
1224 /* support HDR. */
1225 if (cntlr->cap.baseCap.bits.hdr > 0) {
1226 HdmiHdrModeCheck(commAttr, videoAttr, &(cntlr->attr.hdrAttr));
1227 }
1228
1229 /* support FRL. */
1230 if (cntlr->cap.baseCap.bits.frl > 0) {
1231 ret = HdmiFrlModeSelect(cntlr->frl);
1232 if (ret != HDF_SUCCESS) {
1233 return ret;
1234 }
1235 }
1236
1237 HdmiFillCommonAttrFromHardwareStatus(&curCommAttr, hwStatus, &(cntlr->attr));
1238 HdmiFillVideoAttrFromHardwareStatus(&curVideoAttr, hwStatus, &curCommAttr);
1239 if (HdmiCommonAttrChanged(&curCommAttr, commAttr) == false &&
1240 HdmiVideoAttrChanged(&curVideoAttr, videoAttr) == false && HdmiFrlModeChanged(cntlr->frl) == false) {
1241 HDF_LOGI("video and common attr is not changed.");
1242 return HDF_SUCCESS;
1243 }
1244
1245 if (commAttr->enableVideo == true) {
1246 HdmiCntlrVideoPathSet(cntlr, videoAttr);
1247 }
1248
1249 (void)HdmiAviInfoFrameSend(&(cntlr->infoFrame), (commAttr->enableHdmi && commAttr->avi));
1250 (void)HdmiVsInfoFrameSend(&(cntlr->infoFrame), commAttr->enableHdmi, commAttr->vsifDolby);
1251 /* the drm infoFrame is stop because software was reset in videopath, so re-enable it if the mode is HDR10. */
1252 if (cntlr->cap.baseCap.bits.hdr > 0) {
1253 if (cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_CEA_861_3) {
1254 (void)HdmiDrmInfoFrameSend(&(cntlr->infoFrame), false);
1255 (void)HdmiDrmInfoFrameSend(&(cntlr->infoFrame), true);
1256 }
1257 }
1258 return HDF_SUCCESS;
1259 }
1260
HdmiAttrUpdate(struct HdmiCntlr * cntlr)1261 static void HdmiAttrUpdate(struct HdmiCntlr *cntlr)
1262 {
1263 struct HdmiHardwareStatus hwStatus = {0};
1264
1265 if (HdmiColorBitSelect(cntlr) != HDF_SUCCESS) {
1266 HDF_LOGD("attr update: color bit select fail.");
1267 return;
1268 }
1269
1270 if (cntlr->ops->hardWareStatusGet == NULL) {
1271 return;
1272 }
1273
1274 HdmiCntlrLock(cntlr);
1275 cntlr->ops->hardWareStatusGet(cntlr, &hwStatus);
1276 HdmiCntlrUnlock(cntlr);
1277
1278 if (HdmiAudioAttrHandle(cntlr) != HDF_SUCCESS) {
1279 HDF_LOGD("audio attr check fail");
1280 return;
1281 }
1282 if (HdmiVedioAttrHandle(cntlr, &hwStatus) != HDF_SUCCESS) {
1283 HDF_LOGD("vedio attr check fail");
1284 }
1285 }
1286
HdmiCntlrDeepColorSet(struct HdmiCntlr * cntlr,enum HdmiDeepColor color)1287 int32_t HdmiCntlrDeepColorSet(struct HdmiCntlr *cntlr, enum HdmiDeepColor color)
1288 {
1289 if (cntlr == NULL || cntlr->ops == NULL) {
1290 return HDF_ERR_INVALID_OBJECT;
1291 }
1292
1293 if (cntlr->attr.commAttr.colorSpace == HDMI_COLOR_SPACE_YCBCR422) {
1294 if (color != HDMI_DEEP_COLOR_24BITS && color != HDMI_DEEP_COLOR_OFF) {
1295 HDF_LOGE("not support deepcolor %u when colorspace is ycbcr422.", color);
1296 return HDF_ERR_INVALID_PARAM;
1297 }
1298 }
1299
1300 /* if the current hdmi mode is dolby, deep color set is invalid. */
1301 if (cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_DOLBY_NORMAL ||
1302 cntlr->attr.hdrAttr.mode == HDMI_HDR_MODE_DOLBY_TUNNELING) {
1303 HDF_LOGD("don't change deepcolor when dolby mode is %u.", cntlr->attr.hdrAttr.mode);
1304 return HDF_ERR_NOT_SUPPORT;
1305 }
1306
1307 cntlr->attr.commAttr.deepColor = color;
1308 HdmiCntlrAvmuteSet(cntlr, true);
1309 HdmiAttrUpdate(cntlr);
1310 HdmiCntlrAvmuteSet(cntlr, false);
1311 return HDF_SUCCESS;
1312 }
1313
HdmiCntlrDeepColorGet(struct HdmiCntlr * cntlr,enum HdmiDeepColor * color)1314 int32_t HdmiCntlrDeepColorGet(struct HdmiCntlr *cntlr, enum HdmiDeepColor *color)
1315 {
1316 if (cntlr == NULL || cntlr->ops == NULL) {
1317 return HDF_ERR_INVALID_OBJECT;
1318 }
1319 if (color == NULL) {
1320 return HDF_ERR_INVALID_PARAM;
1321 }
1322
1323 *color = cntlr->attr.commAttr.deepColor;
1324 return HDF_SUCCESS;
1325 }
1326
HdmiCntlrSetVideoAttribute(struct HdmiCntlr * cntlr,const struct HdmiVideoAttr * attr)1327 int32_t HdmiCntlrSetVideoAttribute(struct HdmiCntlr *cntlr, const struct HdmiVideoAttr *attr)
1328 {
1329 struct HdmiHardwareStatus hwStatus = {0};
1330
1331 if (cntlr == NULL || cntlr->ops == NULL) {
1332 return HDF_ERR_INVALID_OBJECT;
1333 }
1334 if (attr == NULL) {
1335 return HDF_ERR_INVALID_PARAM;
1336 }
1337
1338 cntlr->attr.videoAttr = *attr;
1339
1340 if (cntlr->ops->hardWareStatusGet == NULL) {
1341 return HDF_ERR_NOT_SUPPORT;
1342 }
1343
1344 HdmiCntlrLock(cntlr);
1345 cntlr->ops->hardWareStatusGet(cntlr, &hwStatus);
1346 HdmiCntlrUnlock(cntlr);
1347 return HdmiVedioAttrHandle(cntlr, &hwStatus);
1348 }
1349
HdmiCntlrSetAudioAttribute(struct HdmiCntlr * cntlr,const struct HdmiAudioAttr * attr)1350 int32_t HdmiCntlrSetAudioAttribute(struct HdmiCntlr *cntlr, const struct HdmiAudioAttr *attr)
1351 {
1352 if (cntlr == NULL || cntlr->ops == NULL) {
1353 return HDF_ERR_INVALID_OBJECT;
1354 }
1355 if (attr == NULL) {
1356 return HDF_ERR_INVALID_PARAM;
1357 }
1358
1359 cntlr->attr.audioAttr = *attr;
1360 return HdmiAudioAttrHandle(cntlr);
1361 }
1362
HdmiCntlrSetHdrAttribute(struct HdmiCntlr * cntlr,struct HdmiHdrAttr * attr)1363 int32_t HdmiCntlrSetHdrAttribute(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *attr)
1364 {
1365 if (cntlr == NULL || cntlr->ops == NULL) {
1366 return HDF_ERR_INVALID_OBJECT;
1367 }
1368 if (attr == NULL) {
1369 return HDF_ERR_INVALID_PARAM;
1370 }
1371
1372 return HdmiHdrAttrHandle(cntlr->hdr, attr);
1373 }
1374
HdmiCntlrInfoFrameGet(struct HdmiCntlr * cntlr,enum HdmiPacketType type,union HdmiInfoFrameInfo * frame)1375 int32_t HdmiCntlrInfoFrameGet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame)
1376 {
1377 if (cntlr == NULL) {
1378 return HDF_ERR_INVALID_OBJECT;
1379 }
1380 return HdmiInfoFrameGetInfo(&(cntlr->infoFrame), type, frame);
1381 }
1382
HdmiCntlrInfoFrameSet(struct HdmiCntlr * cntlr,enum HdmiPacketType type,union HdmiInfoFrameInfo * frame)1383 int32_t HdmiCntlrInfoFrameSet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame)
1384 {
1385 if (cntlr == NULL || cntlr->ops == NULL) {
1386 return HDF_ERR_INVALID_OBJECT;
1387 }
1388 if (frame == NULL) {
1389 return HDF_ERR_INVALID_PARAM;
1390 }
1391 return HdmiInfoFrameSetInfo(&(cntlr->infoFrame), type, frame);
1392 }
1393
HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr * cntlr,struct HdmiHpdCallbackInfo * callback)1394 int32_t HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdmiHpdCallbackInfo *callback)
1395 {
1396 if (cntlr == NULL) {
1397 return HDF_ERR_INVALID_OBJECT;
1398 }
1399 if (callback == NULL) {
1400 return HDF_ERR_INVALID_PARAM;
1401 }
1402
1403 cntlr->event.callback.data = callback->data;
1404 cntlr->event.callback.callbackFunc = callback->callbackFunc;
1405 return HDF_SUCCESS;
1406 }
1407
HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr * cntlr)1408 int32_t HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr *cntlr)
1409 {
1410 if (cntlr == NULL) {
1411 return HDF_ERR_INVALID_OBJECT;
1412 }
1413 cntlr->event.callback.data = NULL;
1414 cntlr->event.callback.callbackFunc = NULL;
1415 return HDF_SUCCESS;
1416 }
1417
HdmiCntlrClose(struct HdmiCntlr * cntlr)1418 void HdmiCntlrClose(struct HdmiCntlr *cntlr)
1419 {
1420 if (cntlr == NULL || cntlr->ops == NULL) {
1421 return;
1422 }
1423
1424 if ((cntlr->state & HDMI_CNTLR_STATE_START) > 0) {
1425 HdmiCntlrStop(cntlr);
1426 }
1427
1428 HdmiInfoFrameDeInit(cntlr);
1429 HdmiDdcDeinit(cntlr);
1430 HdmiScdcDeinit(cntlr);
1431 HdmiFrlDeinit(cntlr);
1432 HdmiHdcpDeinit(cntlr);
1433 HdmiCecDeinit(cntlr);
1434 HdmiHdrDeinit(cntlr);
1435 cntlr->state = HDMI_CNTLR_STATE_CLOSE;
1436 }
1437