1 /*
2 * Copyright (c) 2021-2023 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 "hdf_log.h"
10 #include "hdmi_core.h"
11 #include "securec.h"
12
13 #define HDF_LOG_TAG hdmi_edid_c
14
15 /*
16 * Address locations 0x00 and 0x07 contain data values 0x00 and locations 0x01 through 0x06 contain 0xFF as data
17 * values. CTA-861 requires this data. This header is used to determine the beginning of an EDID structure in a Sink.
18 */
19 uint8_t g_edidHeader[HDMI_EDID_BLOCK_HEADER_FIELD_LEN] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
20
HdmiEdidReset(struct HdmiEdid * edid)21 int32_t HdmiEdidReset(struct HdmiEdid *edid)
22 {
23 if (edid == NULL) {
24 return HDF_ERR_INVALID_PARAM;
25 }
26 if (memset_s(edid, sizeof(struct HdmiEdid), 0, sizeof(struct HdmiEdid)) != EOK) {
27 HDF_LOGE("memset_s fail.");
28 return HDF_ERR_IO;
29 }
30 return HDF_SUCCESS;
31 }
32
HdmiEdidGetRaw(struct HdmiEdid * edid,uint8_t * raw,uint32_t len)33 int32_t HdmiEdidGetRaw(struct HdmiEdid *edid, uint8_t *raw, uint32_t len)
34 {
35 uint32_t length;
36
37 if (edid == NULL || raw == NULL) {
38 return HDF_ERR_INVALID_PARAM;
39 }
40
41 length = ((len < edid->rawLen) ? len : edid->rawLen);
42 if (length == 0) {
43 HDF_LOGE("edid data not get.");
44 return (int32_t)length;
45 }
46 if (memcpy_s(raw, len, edid->raw, length) != EOK) {
47 HDF_LOGE("memcpy_s fail.");
48 return HDF_ERR_IO;
49 }
50 return (int32_t)length;
51 }
52
HdmiEdidHeaderPhase(struct HdmiEdid * edid)53 static int32_t HdmiEdidHeaderPhase(struct HdmiEdid *edid)
54 {
55 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
56 uint32_t i;
57
58 for (i = 0; i < HDMI_EDID_BLOCK_HEADER_FIELD_LEN; i++) {
59 if (block->header[i] != g_edidHeader[i]) {
60 HDF_LOGE("header[%u] = 0x%x, is error.", i, block->header[i]);
61 return HDF_ERR_INVALID_PARAM;
62 }
63 }
64 return HDF_SUCCESS;
65 }
66
HdmiEdidBlockCheckSum(uint8_t * data)67 static int32_t HdmiEdidBlockCheckSum(uint8_t *data)
68 {
69 uint32_t i;
70 uint32_t checkSum = 0;
71
72 HDF_LOGD("check sum is 0x%x", data[HDMI_EDID_CHECKSUM_ADDR]);
73 for (i = 0; i < HDMI_EDID_SINGLE_BLOCK_SIZE; i++) {
74 checkSum += data[i];
75 }
76 if ((checkSum & HDMI_EDID_CHECK_SUM_MARK) == 0) {
77 return HDF_SUCCESS;
78 }
79 HDF_LOGE("checksum = 0x%x, is invalid.", checkSum);
80 return HDF_FAILURE;
81 }
82
HdmiEdidVendorInfoPhase(struct HdmiEdid * edid)83 static int32_t HdmiEdidVendorInfoPhase(struct HdmiEdid *edid)
84 {
85 uint16_t data;
86 uint16_t i;
87 uint16_t tmpData;
88 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
89 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
90
91 /* Manufacturer Name */
92 data = (block->vendorName[UINT8_ARRAY_TELEMENT_0] <<
93 HDMI_EDID_MANUFACRURER_NAME_SHIFT) |
94 (block->vendorName[UINT8_ARRAY_TELEMENT_1]);
95 for (i = 0; i < HDMI_EDID_MANUFACRURER_NAME_MAX_LEN - 1; i++) {
96 tmpData = (data & (HDMI_EDID_MANUFACRURER_NAME_CHAR_MARK << (HDMI_EDID_MANUFACRURER_NAME_CHAR_SHIFT * i)));
97 tmpData = (tmpData >> (HDMI_EDID_MANUFACRURER_NAME_CHAR_SHIFT * i));
98 if (tmpData > HDMI_EDID_MANUFACRURER_NAME_LOW_INVALID &&
99 tmpData < HDMI_EDID_MANUFACRURER_NAME_HIGH_INVALID) {
100 sinkCap->vendorInfo.mfrName[HDMI_EDID_MANUFACRURER_NAME_EFFECTIVE_LEN - 1 - i] =
101 (char)('A' + tmpData - 1);
102 }
103 }
104
105 /* Product Code */
106 data = (block->productCode[UINT8_ARRAY_TELEMENT_1] <<
107 HDMI_EDID_PRODUCT_CODE_SHIFT) |
108 (block->productCode[UINT8_ARRAY_TELEMENT_0]);
109 sinkCap->vendorInfo.productCode = data;
110
111 /* Serial Number */
112 for (i = 0; i < HDMI_EDID_SERIAL_NUMBER_FIELD_LEN; i++) {
113 sinkCap->vendorInfo.serialNumber |= (uint32_t)(block->serialNumber[i] <<
114 (uint16_t)(HDMI_EDID_SERIAL_NUMBER_SHIFT * i));
115 }
116 sinkCap->vendorInfo.week = block->week;
117 sinkCap->vendorInfo.year = block->year + HDMI_EDID_YEAR_BASE;
118 return HDF_SUCCESS;
119 }
120
HdmiEdidVersionInfoPhase(struct HdmiEdid * edid)121 static int32_t HdmiEdidVersionInfoPhase(struct HdmiEdid *edid)
122 {
123 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
124 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
125
126 sinkCap->verInfo.version = block->version;
127 sinkCap->verInfo.revision = block->revision;
128 if (sinkCap->verInfo.version != HDMI_EDID_VERSION_NUM) {
129 HDF_LOGW("edid version is %hhu", sinkCap->verInfo.version);
130 }
131 if (sinkCap->verInfo.revision != HDMI_EDID_REVISION_NUM) {
132 HDF_LOGW("edid revision is %hhu", sinkCap->verInfo.revision);
133 }
134 return HDF_SUCCESS;
135 }
136
HdmiEdidBasicDispPhase(struct HdmiEdid * edid)137 static int32_t HdmiEdidBasicDispPhase(struct HdmiEdid *edid)
138 {
139 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
140 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
141
142 sinkCap->disp.width = block->width;
143 sinkCap->disp.height = block->height;
144 HDF_LOGI("width = %hhu, height = %hhu", block->width, block->height);
145 return HDF_SUCCESS;
146 }
147
HdmiEdidColorFeaturePhase(struct HdmiEdid * edid)148 static int32_t HdmiEdidColorFeaturePhase(struct HdmiEdid *edid)
149 {
150 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
151 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
152
153 /* red color phase */
154 sinkCap->colorInfo.redX = (block->redX << HDMI_EDID_COLOR_HIGH_OFFSET) |
155 ((block->redGreenLow >> HDMI_EDID_COLOR_RED_X_LOW_OFFSET) & HDMI_EDID_COLOR_LOW_BITS_MARK);
156 sinkCap->colorInfo.redY = (block->redY << HDMI_EDID_COLOR_HIGH_OFFSET) |
157 ((block->redGreenLow >> HDMI_EDID_COLOR_RED_Y_LOW_OFFSET) & HDMI_EDID_COLOR_LOW_BITS_MARK);
158 /* green color phase */
159 sinkCap->colorInfo.greenX = (block->greenX << HDMI_EDID_COLOR_HIGH_OFFSET) |
160 ((block->redGreenLow >> HDMI_EDID_COLOR_GREEN_X_LOW_OFFSET) & HDMI_EDID_COLOR_LOW_BITS_MARK);
161 sinkCap->colorInfo.greenY = (block->greenY << HDMI_EDID_COLOR_HIGH_OFFSET) |
162 (block->redGreenLow & HDMI_EDID_COLOR_LOW_BITS_MARK);
163 /* blue color phase */
164 sinkCap->colorInfo.blueX = (block->blueX << HDMI_EDID_COLOR_HIGH_OFFSET) |
165 ((block->blueWhiteLow >> HDMI_EDID_COLOR_BLUE_X_LOW_OFFSET) & HDMI_EDID_COLOR_LOW_BITS_MARK);
166 sinkCap->colorInfo.blueY = (block->blueY << HDMI_EDID_COLOR_HIGH_OFFSET) |
167 ((block->blueWhiteLow >> HDMI_EDID_COLOR_BLUE_Y_LOW_OFFSET) & HDMI_EDID_COLOR_LOW_BITS_MARK);
168 /* white color phase */
169 sinkCap->colorInfo.whiteX = (block->whiteX << HDMI_EDID_COLOR_HIGH_OFFSET) |
170 ((block->blueWhiteLow >> HDMI_EDID_COLOR_WHITE_X_LOW_OFFSET) & HDMI_EDID_COLOR_LOW_BITS_MARK);
171 sinkCap->colorInfo.whiteY = (block->whiteY << HDMI_EDID_COLOR_HIGH_OFFSET) |
172 (block->blueWhiteLow & HDMI_EDID_COLOR_LOW_BITS_MARK);
173 return HDF_SUCCESS;
174 }
175
HdmiEdidEstablisedTimingPhase(struct HdmiEdid * edid)176 static int32_t HdmiEdidEstablisedTimingPhase(struct HdmiEdid *edid)
177 {
178 uint32_t i;
179 uint32_t data = 0;
180 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
181 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
182
183 for (i = 0; i < HDMI_EDID_ESTABLISHED_TIMINGS_FIELD_LEN; i++) {
184 data |= (uint32_t)(block->estTimings[i] << (uint32_t)(i * HDMI_ONE_BYTE_SHIFT));
185 }
186
187 /*
188 * The established timing block is a field of one-bit flags, which are used to inducate support for established
189 * VESA and other common timing in a very compact form. A bit set to "1" indicate support for that timing.
190 */
191 for (i = 0; i < HDMI_EDID_ESTABLISHED_TIMING_BUTT; i++) {
192 if ((data & (1 << i)) > 0) {
193 sinkCap->establishedTimingsInfo.estTimings[i] = i;
194 sinkCap->establishedTimingsInfo.estTimingsNum++;
195 }
196 }
197 return HDF_SUCCESS;
198 }
199
HdmiEdidGetStandardTimingVertPixel(uint32_t aspectRatio,uint32_t horizPixel)200 static uint32_t HdmiEdidGetStandardTimingVertPixel(uint32_t aspectRatio, uint32_t horizPixel)
201 {
202 uint32_t vertPixel = 0;
203
204 switch (aspectRatio) {
205 case HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_16_10:
206 vertPixel = horizPixel * VIDEO_WIDTH_10 / VIDEO_LENGTH_16;
207 break;
208 case HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_5_4:
209 vertPixel = horizPixel * VIDEO_WIDTH_4 / VIDEO_LENGTH_5;
210 break;
211 case HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_4_3:
212 vertPixel = horizPixel * VIDEO_WIDTH_3 / VIDEO_LENGTH_4;
213 break;
214 case HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_16_9:
215 vertPixel = horizPixel * VIDEO_WIDTH_9 / VIDEO_LENGTH_16;
216 break;
217 default:
218 HDF_LOGE("aspectRatio %u is invalid.", aspectRatio);
219 break;
220 }
221 return vertPixel;
222 }
223
HdmiEdidStandardTimingPhase(struct HdmiEdid * edid)224 static int32_t HdmiEdidStandardTimingPhase(struct HdmiEdid *edid)
225 {
226 uint32_t i;
227 uint32_t aspectRatio;
228 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
229 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
230 uint8_t *data = block->stdTiming;
231
232 /*
233 * A 2-byte timing identifier identifies each timing mode.
234 * Unused fields in this section shall be set to 01h, 01h.
235 */
236 for (i = 0; i < HDMI_EDID_STANDARD_TIMING_COUNT; i++) {
237 if (data[UINT8_ARRAY_TELEMENT_0] != HDMI_EDID_STANDARD_TIMING_UNUSED_FLAG ||
238 data[UINT8_ARRAY_TELEMENT_1] != HDMI_EDID_STANDARD_TIMING_UNUSED_FLAG) {
239 sinkCap->stdTimingsInfo[i].horizPixel = (data[UINT8_ARRAY_TELEMENT_0] +
240 HDMI_EDID_STANDARD_TIMING_HORIZ_PIXEL_BASE) *
241 HDMI_EDID_STANDARD_TIMING_HORIZ_PIXEL_FACTOR;
242 sinkCap->stdTimingsInfo[i].refreshRate = (data[UINT8_ARRAY_TELEMENT_1] &
243 HDMI_EDID_STANDARD_TIMING_REFRESH_RATE_MARK) +
244 HDMI_EDID_STANDARD_TIMING_REFRESH_RATE_BASE;
245 aspectRatio = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_MARK) >>
246 HDMI_EDID_STANDARD_TIMING_ASPECT_RATE_SHIFT;
247 sinkCap->stdTimingsInfo[i].vertPixel =
248 HdmiEdidGetStandardTimingVertPixel(aspectRatio, sinkCap->stdTimingsInfo[i].horizPixel);
249 }
250 data += HDMI_EDID_PER_STANDARD_TIMING_BYTE_NUM;
251 }
252 return HDF_SUCCESS;
253 }
254
HdmiEdidMonitorDescriptorPhase(const struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint32_t len)255 static void HdmiEdidMonitorDescriptorPhase(const struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint32_t len)
256 {
257 struct HdmiEdidMonitorBlockInfo *block = (struct HdmiEdidMonitorBlockInfo *)data;
258
259 if (block->dataTag != HDMI_EDID_MONITOR_DATA_NAME) {
260 return;
261 }
262 if (memcpy_s((void *)(sinkCap->sinkDeviceName), HDMI_EDID_MAX_SINK_NAME_COUNT,
263 block->data, HDMI_EDID_MONITOR_DATA_FIELD_LEN) != EOK) {
264 HDF_LOGE("memcpy_s sink name fail");
265 }
266 }
267
HdmiEdidDigitalSyncSignal(struct HdmiEdidPreferredTimingInfo * perTiming,uint8_t flags)268 static void HdmiEdidDigitalSyncSignal(struct HdmiEdidPreferredTimingInfo *perTiming, uint8_t flags)
269 {
270 /* bit3/bit2/bit1 */
271 switch ((flags & HDMI_EDID_DETAILED_TIMING_SYNC_SIGNAL_TYPE_MARK) >> 1) {
272 case HDMI_EDID_DETAILED_TIMING_SYNC_DCS_WS_0:
273 case HDMI_EDID_DETAILED_TIMING_SYNC_DCS_WS_1:
274 case HDMI_EDID_DETAILED_TIMING_SYNC_DCS_DS_2:
275 case HDMI_EDID_DETAILED_TIMING_SYNC_DCS_DS_3:
276 perTiming->ihs = false;
277 perTiming->ivs = false;
278 break;
279 case HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VN_HN_4:
280 perTiming->ihs = false;
281 perTiming->ivs = false;
282 break;
283 case HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VN_HP_5:
284 perTiming->ihs = true;
285 perTiming->ivs = false;
286 break;
287 case HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VP_HN_6:
288 perTiming->ihs = false;
289 perTiming->ivs = true;
290 break;
291 case HDMI_EDID_DETAILED_TIMING_SYNC_DSS_VP_HP_7:
292 perTiming->ihs = true;
293 perTiming->ivs = true;
294 break;
295 default:
296 break;
297 }
298 }
299
HdmiEdidDetailedTimingDescriptorPhase(struct HdmiSinkDeviceCapability * cap,uint8_t * data,uint32_t len)300 static void HdmiEdidDetailedTimingDescriptorPhase(struct HdmiSinkDeviceCapability *cap, uint8_t *data, uint32_t len)
301 {
302 struct HdmiEdidDetailedTimingBlockInfo *block = (struct HdmiEdidDetailedTimingBlockInfo *)data;
303 struct HdmiEdidPreferredTimingInfo *perTiming = NULL;
304 uint32_t pixelClock;
305
306 if (cap->preTimingCnt >= HDMI_EDID_MAX_DETAILED_TIMING_COUNT) {
307 HDF_LOGE("preTimingCnt reach the maximum");
308 return;
309 }
310
311 perTiming = &cap->preTimingInfo[cap->preTimingCnt];
312 pixelClock = (block->pixelClk[UINT8_ARRAY_TELEMENT_1] <<
313 HDMI_ONE_BYTE_SHIFT) |
314 (block->pixelClk[UINT8_ARRAY_TELEMENT_0]);
315 if (pixelClock == 0) {
316 HDF_LOGD(" pixel clock is 0. preTimingCnt = %u", cap->preTimingCnt);
317 return;
318 }
319
320 perTiming->pixelClk = pixelClock * HDMI_EDID_DETAILED_TIMING_PIXEL_CLK_KHZ_FACTOR;
321 perTiming->hActive = (block->hActive) |
322 ((block->hActiveBlanking & HDMI_EDID_DETAILED_TIMING_UPPER_4BITS_MARK) << HDMI_NIBBLE_SHIFT);
323 perTiming->hBackBlank = (block->hBlanking) |
324 ((block->hActiveBlanking & HDMI_EDID_DETAILED_TIMING_LOWER_4BITS_MARK) << HDMI_ONE_BYTE_SHIFT);
325 perTiming->hFrontBlank = (block->hSyncOffset) |
326 ((block->hsOffsetVsOffset & HDMI_EDID_DETAILED_TIMING_HS_OFFSET_MARK) << HDMI_2_BITS_SHIFT);
327 perTiming->hSyncPluseWidth = (block->hSyncPulseWidth) |
328 ((block->hsOffsetVsOffset & HDMI_EDID_DETAILED_TIMING_HS_PULSE_WIDTH_MARK) << HDMI_NIBBLE_SHIFT);
329
330 perTiming->vActive = (block->vActive) |
331 ((block->vActiveBlanking & HDMI_EDID_DETAILED_TIMING_UPPER_4BITS_MARK) << HDMI_NIBBLE_SHIFT);
332 perTiming->vBackBlank = (block->vBlanking) |
333 ((block->vActiveBlanking & HDMI_EDID_DETAILED_TIMING_LOWER_4BITS_MARK) << HDMI_ONE_BYTE_SHIFT);
334 perTiming->vFrontBlank =
335 ((block->hsOffsetVsOffset & HDMI_EDID_DETAILED_TIMING_VS_OFFSET_MARK) << HDMI_2_BITS_SHIFT) |
336 ((block->vsOffesetPulseWidth & HDMI_EDID_DETAILED_TIMING_UPPER_4BITS_MARK) >> HDMI_NIBBLE_SHIFT);
337 perTiming->vSyncPluseWidth =
338 ((block->hsOffsetVsOffset & HDMI_EDID_DETAILED_TIMING_VS_PULSE_WIDTH_MARK) << HDMI_NIBBLE_SHIFT) |
339 (block->vsOffesetPulseWidth & HDMI_EDID_DETAILED_TIMING_LOWER_4BITS_MARK);
340
341 perTiming->imageWidth = (block->hImageSize) |
342 ((block->hvImageSize & HDMI_EDID_DETAILED_TIMING_UPPER_4BITS_MARK) << HDMI_NIBBLE_SHIFT);
343 perTiming->imageHeight = (block->vImageSize) |
344 ((block->hvImageSize & HDMI_EDID_DETAILED_TIMING_LOWER_4BITS_MARK) << HDMI_ONE_BYTE_SHIFT);
345 perTiming->interlaceFlag = (block->flags & HDMI_BIT7_MARK) ? true : false;
346 /* Digital composite/separate */
347 if ((block->flags & HDMI_BIT4_MARK) != 0) {
348 HdmiEdidDigitalSyncSignal(perTiming, block->flags);
349 }
350 cap->preTimingCnt++;
351 }
352
HdmiEdidDetailedTiming(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint32_t len)353 static void HdmiEdidDetailedTiming(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint32_t len)
354 {
355 /*
356 * Monitor Descriptor flag: data0/data1/data2 is 0x00.
357 */
358 if (data[UINT8_ARRAY_TELEMENT_0] == 0x00 &&
359 data[UINT8_ARRAY_TELEMENT_1] == 0x00 &&
360 data[UINT8_ARRAY_TELEMENT_2] == 0x00) {
361 HdmiEdidMonitorDescriptorPhase(sinkCap, data, len);
362 return;
363 }
364
365 /*
366 * Those 18-byte blocks not used for Monitor Descriptors shall be used for detailed timings.
367 */
368 HdmiEdidDetailedTimingDescriptorPhase(sinkCap, data, len);
369 }
370
HdmiEdidDetailedTimingPhase(struct HdmiEdid * edid)371 static int32_t HdmiEdidDetailedTimingPhase(struct HdmiEdid *edid)
372 {
373 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
374 struct HdmiEdidFirstBlockInfo *block = (struct HdmiEdidFirstBlockInfo *)edid->raw;
375
376 /*
377 * The detailed timing section is divided into four descriptor blocks, which are 18 bytes each.
378 * The first descriptor block shall be used to indicate the display's preferred timing mode.
379 * A Monitor Name Descriptor must be provided.
380 */
381 HdmiEdidDetailedTiming(sinkCap, block->detailedTiming1, HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN);
382 HdmiEdidDetailedTiming(sinkCap, block->detailedTiming2, HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN);
383 HdmiEdidDetailedTiming(sinkCap, block->detailedTiming3, HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN);
384 HdmiEdidDetailedTiming(sinkCap, block->detailedTiming4, HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN);
385 return HDF_SUCCESS;
386 }
387
HdmiEdidExtBlockNumPhase(struct HdmiEdid * edid)388 static int32_t HdmiEdidExtBlockNumPhase(struct HdmiEdid *edid)
389 {
390 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
391
392 sinkCap->extBlockNum = edid->raw[HDMI_EDID_EXTENSION_BLOCK_ADDR];
393 HDF_LOGD("edid extBlockNum = %hhu.", sinkCap->extBlockNum);
394 if (sinkCap->extBlockNum > (HDMI_EDID_MAX_BLOCK_NUM - 1)) {
395 HDF_LOGW("ext block number %hhu is invallid.", sinkCap->extBlockNum);
396 sinkCap->extBlockNum = HDMI_EDID_MAX_BLOCK_NUM - 1;
397 }
398 return HDF_SUCCESS;
399 }
400
HdmiEdidFirstBlockPhase(struct HdmiEdid * edid)401 static int32_t HdmiEdidFirstBlockPhase(struct HdmiEdid *edid)
402 {
403 uint32_t i;
404 uint32_t len;
405 int32_t ret;
406
407 HdmiEdidPhaseFunc func[] = {
408 HdmiEdidHeaderPhase,
409 HdmiEdidVendorInfoPhase,
410 HdmiEdidVersionInfoPhase,
411 HdmiEdidBasicDispPhase,
412 HdmiEdidColorFeaturePhase,
413 HdmiEdidEstablisedTimingPhase,
414 HdmiEdidStandardTimingPhase,
415 HdmiEdidDetailedTimingPhase,
416 HdmiEdidExtBlockNumPhase
417 };
418
419 ret = HdmiEdidBlockCheckSum(edid->raw);
420 if (ret != HDF_SUCCESS) {
421 HDF_LOGE("edid block0 check sum fail.");
422 return ret;
423 }
424
425 len = sizeof(func) / sizeof(func[UINT8_ARRAY_TELEMENT_0]);
426 for (i = 0; i < len; i++) {
427 if (func[i] == NULL) {
428 continue;
429 }
430 ret = (func[i])(edid);
431 if (ret != HDF_SUCCESS) {
432 HDF_LOGE("func[%u] exe fail.", i);
433 return ret;
434 }
435 }
436 return HDF_SUCCESS;
437 }
438
HdmiEdidExtAdbSampleRatePhase(struct HdmiEdidAudioInfo * audio,uint8_t data,uint8_t formatCode)439 static void HdmiEdidExtAdbSampleRatePhase(struct HdmiEdidAudioInfo *audio, uint8_t data, uint8_t formatCode)
440 {
441 if ((data & HDMI_BIT0_MARK) > 0 &&
442 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
443 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_32K;
444 audio->sampleRateNum++;
445 }
446 if ((data & HDMI_BIT1_MARK) > 0 &&
447 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
448 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_44K;
449 audio->sampleRateNum++;
450 }
451 if ((data & HDMI_BIT2_MARK) > 0 &&
452 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
453 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_48K;
454 audio->sampleRateNum++;
455 }
456 if ((data & HDMI_BIT3_MARK) > 0 &&
457 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
458 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_88K;
459 audio->sampleRateNum++;
460 }
461 if ((data & HDMI_BIT4_MARK) > 0 &&
462 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
463 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_96K;
464 audio->sampleRateNum++;
465 }
466
467 if (formatCode >= HDMI_AUDIO_CODING_TYPE_LPCM && formatCode <= HDMI_AUDIO_CODING_TYPE_WMA_PRO) {
468 if ((data & HDMI_BIT5_MARK) > 0 &&
469 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
470 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_176K;
471 audio->sampleRateNum++;
472 }
473 if ((data & HDMI_BIT6_MARK) > 0 &&
474 audio->sampleRateNum < HDMI_EDID_EXTENSION_AUDIO_MAX_SAMPLE_RATE_NUM) {
475 audio->sampleRate[audio->sampleRateNum] = HDMI_SAMPLE_RATE_192K;
476 audio->sampleRateNum++;
477 }
478 }
479 }
480
HdmiEdidExtAdbDepthAndMaxRatePhase(struct HdmiEdidAudioInfo * audio,uint8_t data,uint8_t formatCode)481 static void HdmiEdidExtAdbDepthAndMaxRatePhase(struct HdmiEdidAudioInfo *audio, uint8_t data, uint8_t formatCode)
482 {
483 /*
484 * Audio Format Code is 1, bit[2:0] bit depth;
485 * Audio Format Codes 2 to 8, Maximum bit rate divided by 8 kHz.
486 */
487 if (formatCode == HDMI_AUDIO_CODING_TYPE_LPCM) {
488 if ((data & HDMI_BIT0_MARK) > 0 &&
489 audio->bitDepthNum < HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM) {
490 audio->bitDepth[audio->bitDepthNum] = HDMI_ADIO_BIT_DEPTH_16;
491 audio->bitDepthNum++;
492 }
493 if ((data & HDMI_BIT1_MARK) > 0 &&
494 audio->bitDepthNum < HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM) {
495 audio->bitDepth[audio->bitDepthNum] = HDMI_ADIO_BIT_DEPTH_20;
496 audio->bitDepthNum++;
497 }
498 if ((data & HDMI_BIT2_MARK) > 0 &&
499 audio->bitDepthNum < HDMI_EDID_EXTENSION_AUDIO_MAX_BIT_DEPTH_NUM) {
500 audio->bitDepth[audio->bitDepthNum] = HDMI_ADIO_BIT_DEPTH_24;
501 audio->bitDepthNum++;
502 }
503 } else if (formatCode >= HDMI_AUDIO_CODING_TYPE_AC3 && formatCode <= HDMI_AUDIO_CODING_TYPE_ATRAC) {
504 audio->maxBitRate = data * HDMI_EDID_EXTENSION_AUDIO_BIT_RATE_FACTOR;
505 } else {
506 HDF_LOGI("formatCode %hhu reserved or not care", formatCode);
507 }
508 }
509
HdmiEdidExtAudioDataBlockPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)510 static int32_t HdmiEdidExtAudioDataBlockPhase(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint8_t len)
511 {
512 uint8_t i;
513 uint8_t formatCode;
514
515 /*
516 * Each Short Audio Descriptor is 3-bytes long. There can be up to 31 bytes following any tag,
517 * therefore there may be up to 10 Short Audio Descriptors in the Audio Data Block.
518 */
519 if (len > (HDMI_EDID_EXTENSION_SHORT_AUDIO_DESCRIPTOR_LEN * HDMI_EDID_EXTENSION_MAX_SHORT_AUDIO_DESCRIPTOR_NUM)) {
520 HDF_LOGE("Audio Data Block: len %hhu is invalid", len);
521 return HDF_ERR_INVALID_PARAM;
522 }
523
524 for (i = 0; i < (len / HDMI_EDID_EXTENSION_SHORT_AUDIO_DESCRIPTOR_LEN); i++) {
525 if (sinkCap->audioInfoCnt >= HDMI_EDID_EXTENSION_AUDIO_CAP_COUNT) {
526 HDF_LOGE("ADB: info cnt reach the maximum");
527 break;
528 }
529 data += (i * HDMI_EDID_EXTENSION_SHORT_AUDIO_DESCRIPTOR_LEN);
530 /* byte0: bit[6:3] Audio Format Code; bit[2:0] Max Number of channels - 1 */
531 formatCode = (data[UINT8_ARRAY_TELEMENT_0] & HDMI_EDID_EXTENSION_AUDIO_FORMAT_CODE_MARK) >>
532 HDMI_EDID_EXTENSION_AUDIO_FORMAT_CODE_SHIFT;
533 sinkCap->audioInfo[sinkCap->audioInfoCnt].formatCode = (enum HdmiAudioCodingType)formatCode;
534 sinkCap->audioInfo[sinkCap->audioInfoCnt].channels =
535 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_EDID_EXTENSION_AUDIO_MAX_CHANNEL_MARK) + 1;
536 /* byte1: Sample Rate */
537 HdmiEdidExtAdbSampleRatePhase(&(sinkCap->audioInfo[sinkCap->audioInfoCnt]),
538 data[UINT8_ARRAY_TELEMENT_1],
539 formatCode);
540 /* byte2: bit depth or maximum bit rate */
541 HdmiEdidExtAdbDepthAndMaxRatePhase(&(sinkCap->audioInfo[sinkCap->audioInfoCnt]),
542 data[UINT8_ARRAY_TELEMENT_2],
543 formatCode);
544 sinkCap->audioInfoCnt++;
545 }
546 return HDF_SUCCESS;
547 }
548
HdmiEdidExtVideoDataBlockPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)549 static int32_t HdmiEdidExtVideoDataBlockPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data,
550 uint8_t len)
551 {
552 uint8_t i;
553 uint32_t vicAll;
554 uint32_t vicLower;
555 uint32_t implicitNative = 0;
556
557 for (i = 0; i < len; i++) {
558 if (sinkCap->videoInfo.vicNum >= HDMI_EDID_EXTENSION_MAX_VIC_COUNT) {
559 HDF_LOGD("VDB: vicNum reach the maximum");
560 break;
561 }
562 vicAll = data[i];
563 vicLower = (vicAll & HDMI_EDID_EXTENSION_VIC_LOWER7_MARK);
564 if (vicAll == 0) {
565 continue;
566 }
567 /*
568 * For VICs 1 through 64, the lower 7-bits are an index associated with the Video Format supported.
569 * The most significant bit declares whether the format is a Native Video Format of the
570 * display (native =1, not native = 0). Typically, there is a single SVD, with its native bit set.
571 */
572 if ((vicAll & HDMI_BIT7_MARK) > 0 && vicLower < HDMI_EDID_EXTENSION_VIC_NATIVE_MAX) {
573 if (sinkCap->videoInfo.nativeFormat == 0) {
574 sinkCap->videoInfo.nativeFormat = vicLower;
575 }
576 }
577 /* set the first valid vic as implicit native */
578 if (implicitNative == 0) {
579 implicitNative = vicAll;
580 }
581 if ((vicAll & HDMI_BIT7_MARK) > 0 && vicLower < HDMI_EDID_EXTENSION_VIC_NATIVE_MAX) {
582 sinkCap->videoInfo.vic[sinkCap->videoInfo.vicNum] = vicLower;
583 } else {
584 sinkCap->videoInfo.vic[sinkCap->videoInfo.vicNum] = vicAll;
585 }
586 sinkCap->videoInfo.vicNum++;
587 }
588
589 if (sinkCap->videoInfo.nativeFormat == 0) {
590 sinkCap->videoInfo.nativeFormat = implicitNative;
591 }
592 return HDF_SUCCESS;
593 }
594
HdmiEdidVsdbCecPhyAddrPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)595 static void HdmiEdidVsdbCecPhyAddrPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data, uint8_t len)
596 {
597 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_CEC_PHY_ADDR) {
598 sinkCap->vsdbInfo.cecAddr.phyAddrA = (data[UINT8_ARRAY_TELEMENT_3] & HDMI_UPPER_NIBBLE_MARK) >>
599 HDMI_NIBBLE_SHIFT;
600 sinkCap->vsdbInfo.cecAddr.phyAddrB = (data[UINT8_ARRAY_TELEMENT_3] & HDMI_LOWER_NIBBLE_MARK);
601 sinkCap->vsdbInfo.cecAddr.phyAddrC = (data[UINT8_ARRAY_TELEMENT_4] & HDMI_UPPER_NIBBLE_MARK) >>
602 HDMI_NIBBLE_SHIFT;
603 sinkCap->vsdbInfo.cecAddr.phyAddrD = (data[UINT8_ARRAY_TELEMENT_4] & HDMI_LOWER_NIBBLE_MARK);
604 sinkCap->vsdbInfo.cecAddr.addrValid =
605 (sinkCap->vsdbInfo.cecAddr.phyAddrA != HDMI_EDID_EXTENSION_VSDB_CEC_INVALID_ADDR) &&
606 (sinkCap->vsdbInfo.cecAddr.phyAddrB != HDMI_EDID_EXTENSION_VSDB_CEC_INVALID_ADDR) &&
607 (sinkCap->vsdbInfo.cecAddr.phyAddrC != HDMI_EDID_EXTENSION_VSDB_CEC_INVALID_ADDR) &&
608 (sinkCap->vsdbInfo.cecAddr.phyAddrD != HDMI_EDID_EXTENSION_VSDB_CEC_INVALID_ADDR);
609 }
610 }
611
HdmiEdidVsdbColorDepthPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)612 static void HdmiEdidVsdbColorDepthPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data, uint8_t len)
613 {
614 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_COLOR_DEPTH) {
615 sinkCap->vsdbInfo.supportAi = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT7_MARK) ? true : false;
616 sinkCap->vsdbInfo.supportDviDual = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT0_MARK) ? true : false;
617 sinkCap->vsdbInfo.deepColor.dcY444 = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT3_MARK) ? true : false;
618 sinkCap->vsdbInfo.deepColor.dc30bit = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT4_MARK) ? true : false;
619 sinkCap->vsdbInfo.deepColor.dc36bit = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT5_MARK) ? true : false;
620 sinkCap->vsdbInfo.deepColor.dc48bit = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT6_MARK) ? true : false;
621 }
622 }
623
HdmiEdidVsdbMaxTmdsClockPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)624 static void HdmiEdidVsdbMaxTmdsClockPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data, uint8_t len)
625 {
626 /*
627 * This field shall be set cprrectly and non-zero if the sink support TMDS clock frequencies above 165MHz or
628 * supports ant Deep Color mode or supports DVI dual-link. A value of zeor means that no clock rate is indicated.
629 */
630 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_MAX_TMDS_CLOCK) {
631 sinkCap->maxTmdsClk = data[UINT8_ARRAY_TELEMENT_6] * HDMI_EDID_EXTENSION_TMDS_FACTOR;
632 sinkCap->supportHdmi20 = (sinkCap->maxTmdsClk > HDMI_EDID_EXTENSION_MAX_HDMI14_TMDS_RATE) ? true : false;
633 }
634 }
635
HdmiEdidVsdbSinkPresentPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)636 static void HdmiEdidVsdbSinkPresentPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data, uint8_t len)
637 {
638 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_SINK_PRESENT) {
639 sinkCap->vsdbInfo.latencyFieldsPresent = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT7_MARK) ? true : false;
640 sinkCap->vsdbInfo.iLatencyFieldsPresent = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT6_MARK) ? true : false;
641 sinkCap->vsdbInfo.hdmiVideoPresent = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT5_MARK) ? true : false;
642 }
643 }
644
HdmiEdidVsdbSinkLatencyPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)645 static void HdmiEdidVsdbSinkLatencyPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data, uint8_t len)
646 {
647 if (sinkCap->vsdbInfo.latencyFieldsPresent == true) {
648 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_VIDEO_LATENCY) {
649 sinkCap->vsdbInfo.videoLatency = data[UINT8_ARRAY_TELEMENT_8];
650 }
651 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_AUDIO_LATENCY) {
652 sinkCap->vsdbInfo.audioLatency = data[UINT8_ARRAY_TELEMENT_9];
653 }
654 }
655 if (sinkCap->vsdbInfo.iLatencyFieldsPresent == true) {
656 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_INTERLACED_VIDEO_LATENCY) {
657 sinkCap->vsdbInfo.interlacedVideoLatency = data[UINT8_ARRAY_TELEMENT_10];
658 }
659 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_INTERLACED_AUDIO_LATENCY) {
660 sinkCap->vsdbInfo.interlacedAudioLatency = data[UINT8_ARRAY_TELEMENT_11];
661 }
662 }
663 }
664
HdmiEdidVsdbVicInfoPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t vicLen,uint8_t * offset)665 static void HdmiEdidVsdbVicInfoPhase(struct HdmiSinkDeviceCapability *sinkCap,
666 const uint8_t *data, uint8_t vicLen, uint8_t *offset)
667 {
668 uint8_t i;
669 uint8_t index;
670 /* see hdmi spec 1.4 table 8-13. */
671 uint32_t hdmi4kVic[] = {
672 0,
673 HDMI_VIC_3840X2160P30_16_9,
674 HDMI_VIC_3840X2160P25_16_9,
675 HDMI_VIC_3840X2160P24_16_9,
676 HDMI_VIC_4096X2160P24_256_135
677 };
678
679 for (i = 0; i < vicLen; i++) {
680 if (sinkCap->videoInfo.vicNum >= HDMI_EDID_EXTENSION_MAX_VIC_COUNT) {
681 break;
682 }
683 index = data[(*offset)];
684 if (index != 0 && index < sizeof(hdmi4kVic) / sizeof(hdmi4kVic[UINT8_ARRAY_TELEMENT_0])) {
685 sinkCap->videoInfo.vic[sinkCap->videoInfo.vicNum] = hdmi4kVic[index];
686 sinkCap->videoInfo.vicNum++;
687 }
688 (*offset)++;
689 }
690 }
691
HdmiEdidVsdb3dStructureInfoPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len,uint8_t * offset)692 static void HdmiEdidVsdb3dStructureInfoPhase(struct HdmiSinkDeviceCapability *sinkCap,
693 const uint8_t *data, uint8_t len, uint8_t *offset)
694 {
695 /*
696 * If 3D_Multi_present is 1 or 2, 3D_Struct_ALL_15...0 is present and assigns 3D formats to
697 * all of the VICs listed in the first 16 entries in the EDID.
698 */
699 if (((sinkCap->vsdbInfo._3dMultiPresent) & HDMI_EDID_EXTENSION_VSDB_3D_STR_INVALID_MARK) == 0) {
700 return;
701 }
702 /* see hdmi spec 1.4 table H-8. */
703 if ((*offset) <= len) {
704 /*
705 * bit[15:9]: reserved.
706 * bit8: sinks support "Side-by-side(half) with all sub-sampling methods" 3D formats.
707 */
708 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_HALF] =
709 (data[(*offset)] & HDMI_BIT0_MARK) ? true : false;
710 (*offset)++;
711 }
712
713 if ((*offset) <= len) {
714 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_FRAME_PACKING] =
715 (data[(*offset)] & HDMI_BIT0_MARK) ? true : false;
716 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_FIELD_ALTERNATIVE] =
717 (data[(*offset)] & HDMI_BIT1_MARK) ? true : false;
718 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_LINE_ALTERNATIVE] =
719 (data[(*offset)] & HDMI_BIT2_MARK) ? true : false;
720 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_SIDE_BY_SIDE_FULL] =
721 (data[(*offset)] & HDMI_BIT3_MARK) ? true : false;
722 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_L_DEPTH] =
723 (data[(*offset)] & HDMI_BIT4_MARK) ? true : false;
724 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_L_DEPTH_GFX_GFX_DEPTH] =
725 (data[(*offset)] & HDMI_BIT5_MARK) ? true : false;
726 sinkCap->vsdbInfo.support3dType[HDMI_VS_VIDEO_3D_TOP_AND_BOTTOM] =
727 (data[(*offset)] & HDMI_BIT6_MARK) ? true : false;
728 (*offset)++;
729 }
730 }
731
HdmiEdidVsdbVicAnd3dInfoPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)732 static void HdmiEdidVsdbVicAnd3dInfoPhase(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint8_t len)
733 {
734 uint8_t hdmiVicLen = 0;
735 uint8_t hdmi3dLen = 0;
736 uint8_t offset;
737
738 if (len < HDMI_EDID_VSDB_MIN_LEN_FOR_3D_PRESENT_INFO) {
739 HDF_LOGD("vsdb: these is no vic/3d field.");
740 return;
741 }
742 sinkCap->vsdbInfo._3dPresent = (data[UINT8_ARRAY_TELEMENT_12] & HDMI_BIT7_MARK) ? true : false;
743 sinkCap->vsdbInfo._3dMultiPresent = (data[UINT8_ARRAY_TELEMENT_12] &
744 HDMI_EDID_EXTENSION_VSDB_3D_MULTI_PRESENT_MARK) >>
745 HDMI_EDID_EXTENSION_VSDB_3D_MULTI_PRESENT_SHIFT;
746
747 if (len >= HDMI_EDID_VSDB_MIN_LEN_FOR_VIC_INFO) {
748 hdmiVicLen = (data[UINT8_ARRAY_TELEMENT_13] &
749 HDMI_EDID_EXTENSION_VSDB_VIC_LEN_MARK) >>
750 HDMI_EDID_EXTENSION_VSDB_VIC_LEN_SHIFT;
751 hdmi3dLen = (data[UINT8_ARRAY_TELEMENT_13] & HDMI_EDID_EXTENSION_VSDB_3D_LEN_MARK);
752 }
753
754 /* byte14~byteN: Vic info/3D info */
755 offset = HDMI_EDID_VSDB_MIN_LEN_FOR_VIC_INFO;
756 if (hdmiVicLen > 0 && (hdmiVicLen + offset + 1) <= len) {
757 HdmiEdidVsdbVicInfoPhase(sinkCap, data, hdmiVicLen, &offset);
758 }
759
760 if (hdmi3dLen > 0 &&
761 sinkCap->vsdbInfo._3dPresent == true &&
762 (hdmi3dLen + offset + 1) <= len) {
763 HdmiEdidVsdb3dStructureInfoPhase(sinkCap, data, len, &offset);
764 }
765 }
766
HdmiEdidVsdbPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)767 static int32_t HdmiEdidVsdbPhase(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint8_t len)
768 {
769 /* byte3 byte4: cec addr */
770 if (len < HDMI_EDID_VSDB_MIN_LEN_FOR_CEC_PHY_ADDR) {
771 HDF_LOGD("vsdb: len = %d, too short.", len);
772 return HDF_SUCCESS;
773 }
774 HdmiEdidVsdbCecPhyAddrPhase(sinkCap, data, len);
775 /* byte 5: color depth flags */
776 HdmiEdidVsdbColorDepthPhase(sinkCap, data, len);
777 /* byte 6: max tmds clock. */
778 HdmiEdidVsdbMaxTmdsClockPhase(sinkCap, data, len);
779 /* byte7: some sink present */
780 HdmiEdidVsdbSinkPresentPhase(sinkCap, data, len);
781 /*
782 * byte8: Video_Latency
783 * byte9: Audio_Latency
784 * byte10: Interlaced_Video_Latency
785 * byte11: Interlaced_Audio_Latency
786 */
787 HdmiEdidVsdbSinkLatencyPhase(sinkCap, data, len);
788 /*
789 * byte12: 3D_Present, 3D_Multi_present
790 * byte13: HDMI_VIC_LEN/HDMI_3D_LEN
791 * byte14~byteN: Vic info/3D info
792 */
793 HdmiEdidVsdbVicAnd3dInfoPhase(sinkCap, data, len);
794 return HDF_SUCCESS;
795 }
796
HdmiEdidHfVsdb21Phase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)797 static void HdmiEdidHfVsdb21Phase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data, uint8_t len)
798 {
799 sinkCap->hfVsdbInfo.maxFrlRate = (data[UINT8_ARRAY_TELEMENT_6] & HDMI_UPPER_NIBBLE_MARK) >> HDMI_NIBBLE_SHIFT;
800
801 sinkCap->hfVsdbInfo.fapaStartLocation = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT0_MARK) ? true : false;
802 sinkCap->hfVsdbInfo.allm = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT1_MARK) ? true : false;
803 sinkCap->hfVsdbInfo.fva = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT2_MARK) ? true : false;
804 sinkCap->hfVsdbInfo.cnmVrr = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT3_MARK) ? true : false;
805 sinkCap->hfVsdbInfo.cinemaVrr = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT4_MARK) ? true : false;
806 sinkCap->hfVsdbInfo.mDelta = (data[UINT8_ARRAY_TELEMENT_7] & HDMI_BIT5_MARK) ? true : false;
807 sinkCap->hfVsdbInfo.vrrMin = (data[UINT8_ARRAY_TELEMENT_8] & HDMI_EDID_EXTENSION_HFVSDB_VRRMIN_MARK);
808 sinkCap->hfVsdbInfo.vrrMax = ((data[UINT8_ARRAY_TELEMENT_8] & HDMI_EDID_EXTENSION_HFVSDB_VRRMAX_MARK) <<
809 HDMI_EDID_EXTENSION_HFVSDB_VRRMAX_SHIFT) | data[UINT8_ARRAY_TELEMENT_9];
810
811 sinkCap->hfVsdbInfo.dscInfo.dsc1p2 = (data[UINT8_ARRAY_TELEMENT_10] & HDMI_BIT7_MARK) ? true : false;
812 sinkCap->hfVsdbInfo.dscInfo.dscNative420 = (data[UINT8_ARRAY_TELEMENT_10] & HDMI_BIT6_MARK) ? true : false;
813 sinkCap->hfVsdbInfo.dscInfo.dscAllBpp = (data[UINT8_ARRAY_TELEMENT_10] & HDMI_BIT3_MARK) ? true : false;
814 sinkCap->hfVsdbInfo.dscInfo.dsc10bpc = (data[UINT8_ARRAY_TELEMENT_10] & HDMI_BIT2_MARK) ? true : false;
815 sinkCap->hfVsdbInfo.dscInfo.dsc20bpc = (data[UINT8_ARRAY_TELEMENT_10] & HDMI_BIT1_MARK) ? true : false;
816 sinkCap->hfVsdbInfo.dscInfo.dsc16bpc = (data[UINT8_ARRAY_TELEMENT_10] & HDMI_BIT0_MARK) ? true : false;
817 sinkCap->hfVsdbInfo.dscInfo.dscMaxSlices = (data[UINT8_ARRAY_TELEMENT_11] & HDMI_LOWER_NIBBLE_MARK);
818 sinkCap->hfVsdbInfo.dscInfo.dscMaxFrlRate = (data[UINT8_ARRAY_TELEMENT_11] & HDMI_UPPER_NIBBLE_MARK) >>
819 HDMI_NIBBLE_SHIFT;
820 sinkCap->hfVsdbInfo.dscInfo.dscTotalChunkKBytes = (data[UINT8_ARRAY_TELEMENT_12] &
821 HDMI_EDID_EXTENSION_HFVSDB_DSC_TOTAL_CHUNK_MARK);
822 }
823
HdmiEdidHfVsdbPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)824 static int32_t HdmiEdidHfVsdbPhase(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint8_t len)
825 {
826 if (len < HDMI_EDID_EXTENSION_HFVSDB_MIN_INVALID_LEN) {
827 HDF_LOGD("vsdb: data len %hhu is too short.", len);
828 return HDF_SUCCESS;
829 }
830
831 /* byte3: Version */
832 if (data[UINT8_ARRAY_TELEMENT_3] != HDMI_EDID_EXTENSION_HFVSDB_VERSION) {
833 HDF_LOGD("vsdb: verdion %hhu is invalid.", data[UINT8_ARRAY_TELEMENT_3]);
834 }
835 /* byte4: Max_TMDS_Character_Rate */
836 sinkCap->maxTmdsClk = data[UINT8_ARRAY_TELEMENT_4] * HDMI_EDID_EXTENSION_TMDS_FACTOR;
837 sinkCap->supportHdmi20 = (sinkCap->maxTmdsClk > HDMI_EDID_EXTENSION_MAX_HDMI14_TMDS_RATE) ? true : false;
838 /* byte5: several sink present */
839 sinkCap->hfVsdbInfo.scdcPresent = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT7_MARK) ? true : false;
840 sinkCap->hfVsdbInfo.rrCapable = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT6_MARK) ? true : false;
841 sinkCap->hfVsdbInfo.lte340McscScramble = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT3_MARK) ? true : false;
842 sinkCap->hfVsdbInfo.independentView = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT2_MARK) ? true : false;
843 sinkCap->hfVsdbInfo.dualView = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT1_MARK) ? true : false;
844 sinkCap->hfVsdbInfo._3dOsdDisparity = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT0_MARK) ? true : false;
845 /* byte6: deep color */
846 sinkCap->hfVsdbInfo.dc.dc30bit = (data[UINT8_ARRAY_TELEMENT_6] & HDMI_BIT0_MARK) ? true : false;
847 sinkCap->hfVsdbInfo.dc.dc36bit = (data[UINT8_ARRAY_TELEMENT_6] & HDMI_BIT1_MARK) ? true : false;
848 sinkCap->hfVsdbInfo.dc.dc48bit = (data[UINT8_ARRAY_TELEMENT_6] & HDMI_BIT2_MARK) ? true : false;
849 if (len > HDMI_EDID_EXTENSION_HFVSDB_MIN_INVALID_LEN &&
850 len <= HDMI_EDID_EXTENSION_HFVSDB_MAX_INVALID_LEN) {
851 HdmiEdidHfVsdb21Phase(sinkCap, data, len);
852 }
853 return HDF_SUCCESS;
854 }
855
HdmiEdidExtVsDataBlockPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)856 static int32_t HdmiEdidExtVsDataBlockPhase(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint8_t len)
857 {
858 int32_t ret = HDF_SUCCESS;
859 bool vsdb = false;
860 bool hfVsdb = false;
861
862 if (len >= HDMI_EDID_EXTENSION_VSDB_LEN &&
863 data[UINT8_ARRAY_TELEMENT_0] == HDMI_EDID_EXTENSION_VSDB_IEEE_1ST &&
864 data[UINT8_ARRAY_TELEMENT_1] == HDMI_EDID_EXTENSION_VSDB_IEEE_2ND &&
865 data[UINT8_ARRAY_TELEMENT_2] == HDMI_EDID_EXTENSION_VSDB_IEEE_3RD) {
866 vsdb = true;
867 }
868
869 if (len >= HDMI_EDID_EXTENSION_VSDB_LEN &&
870 data[UINT8_ARRAY_TELEMENT_0] == HDMI_EDID_EXTENSION_HFVSDB_IEEE_1ST &&
871 data[UINT8_ARRAY_TELEMENT_1] == HDMI_EDID_EXTENSION_HFVSDB_IEEE_2ND &&
872 data[UINT8_ARRAY_TELEMENT_2] == HDMI_EDID_EXTENSION_HFVSDB_IEEE_3RD) {
873 hfVsdb = true;
874 }
875
876 if (vsdb == true) {
877 sinkCap->supportHdmi14 = true;
878 ret = HdmiEdidVsdbPhase(sinkCap, data, len);
879 } else if (hfVsdb == true) {
880 ret = HdmiEdidHfVsdbPhase(sinkCap, data, len);
881 }
882 return ret;
883 }
884
HdmiEdidExtSpeakerDataBlockPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)885 static int32_t HdmiEdidExtSpeakerDataBlockPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data,
886 uint8_t len)
887 {
888 if (len < HDMI_EDID_EXTENSION_SADB_MIN_INVALID_LEN) {
889 HDF_LOGD("SADB: len %hhu is too short", len);
890 return HDF_SUCCESS;
891 }
892
893 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_FL_FR] =
894 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT0_MARK) ? true : false;
895 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_LFE] =
896 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT1_MARK) ? true : false;
897 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_FC] =
898 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT2_MARK) ? true : false;
899 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_BL_BR] =
900 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT3_MARK) ? true : false;
901 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_BC] =
902 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT4_MARK) ? true : false;
903 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_FLC_FRC] =
904 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT5_MARK) ? true : false;
905 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_RLC_RRC] =
906 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT6_MARK) ? true : false;
907 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_FLW_FRW] =
908 (data[UINT8_ARRAY_TELEMENT_0] & HDMI_BIT7_MARK) ? true : false;
909 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_TPFL_TPFH] =
910 (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT0_MARK) ? true : false;
911 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_TPC] =
912 (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT1_MARK) ? true : false;
913 sinkCap->supportAudioSpeaker[HDMI_EDID_AUDIO_SPEAKER_TPFC] =
914 (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT2_MARK) ? true : false;
915 return HDF_SUCCESS;
916 }
917
HdmiEdidExtUseExtDataBlockVcdbPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)918 static void HdmiEdidExtUseExtDataBlockVcdbPhase(struct HdmiSinkDeviceCapability *sinkCap,
919 const uint8_t *data, uint8_t len)
920 {
921 if (len < HDMI_EDID_VCDB_LEN) {
922 HDF_LOGD("VCDB: len is too short");
923 return;
924 }
925
926 sinkCap->videoCap.qy = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT7_MARK) ? true : false;
927 sinkCap->videoCap.qs = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT6_MARK) ? true : false;
928 }
929
HdmiEdidExtUseExtDataBlockCdbPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)930 static void HdmiEdidExtUseExtDataBlockCdbPhase(struct HdmiSinkDeviceCapability *sinkCap,
931 const uint8_t *data, uint8_t len)
932 {
933 if (len < HDMI_EDID_CDB_LEN) {
934 HDF_LOGD("CDB: len is too short");
935 return;
936 }
937
938 sinkCap->colorimetry.xvYcc601 = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT0_MARK) ? true : false;
939 sinkCap->colorimetry.xvYcc709 = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT1_MARK) ? true : false;
940 sinkCap->colorimetry.sYcc601 = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT2_MARK) ? true : false;
941 sinkCap->colorimetry.opYcc601 = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT3_MARK) ? true : false;
942 sinkCap->colorimetry.opRgb = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT4_MARK) ? true : false;
943 sinkCap->colorimetry.bt2020cYcc = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT5_MARK) ? true : false;
944 sinkCap->colorimetry.bt2020Ycc = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT6_MARK) ? true : false;
945 sinkCap->colorimetry.bt2020Rgb = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT7_MARK) ? true : false;
946
947 sinkCap->colorimetry.dciP3 = (data[UINT8_ARRAY_TELEMENT_2] & HDMI_BIT7_MARK) ? true : false;
948 sinkCap->colorimetry.md = (data[UINT8_ARRAY_TELEMENT_2] & HDMI_LOWER_NIBBLE_MARK);
949 }
950
HdmiEdidExtUseExtDataBlockY420VdbPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)951 static void HdmiEdidExtUseExtDataBlockY420VdbPhase(struct HdmiSinkDeviceCapability *sinkCap,
952 const uint8_t *data, uint8_t len)
953 {
954 uint8_t i;
955 uint32_t vic;
956
957 for (i = 1; i < len; i++) {
958 if (sinkCap->y420Cap.onlySupportY420VicNum >= HDMI_EDID_EXTENSION_MAX_VIC_COUNT) {
959 HDF_LOGD("Y420Vdb: vic num reach to max.");
960 break;
961 }
962 vic = data[i];
963 if (vic == 0 ||
964 (vic >= HDMI_EDID_EXTENSION_VIC_INVALID_LOW && vic <= HDMI_EDID_EXTENSION_VIC_INVALID_HIGH)) {
965 continue;
966 }
967 sinkCap->y420Cap.onlySupportY420Format[sinkCap->y420Cap.onlySupportY420VicNum] = vic;
968 sinkCap->y420Cap.onlySupportY420VicNum++;
969 sinkCap->colorSpace.ycbcr420 = true;
970 }
971 }
972
HdmiEdidExtUseExtDataBlockY420CmdbPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)973 static void HdmiEdidExtUseExtDataBlockY420CmdbPhase(struct HdmiSinkDeviceCapability *sinkCap,
974 uint8_t *data, uint8_t len)
975 {
976 uint32_t i;
977 uint32_t loop;
978
979 /*
980 * When the Length field is set to 1, the Y420CMDB does not include a YCBCR 4:2:0 Capability Bit Map and
981 * all the SVDs in the regular Video Data Block(s) support YCBCR 4:2:0 sampling mode.
982 */
983 if (len == 1) {
984 for (i = 0; (i < sinkCap->videoInfo.vicNum) && (i < HDMI_EDID_EXTENSION_MAX_VIC_COUNT); i++) {
985 if (sinkCap->y420Cap.SupportY420VicNum >= HDMI_EDID_EXTENSION_MAX_VIC_COUNT) {
986 break;
987 }
988 sinkCap->y420Cap.SupportY420Format[sinkCap->y420Cap.SupportY420VicNum] = sinkCap->videoInfo.vic[i];
989 sinkCap->y420Cap.SupportY420VicNum++;
990 sinkCap->colorSpace.ycbcr420 = true;
991 }
992 return;
993 }
994
995 /*
996 * Bit 0 of data byte 3 is associated with the first sequential SVD listed in the regular Video Data Block(s)
997 * of the EDID, bit 1 the second SVD, bit 2 the third, and so on.
998 */
999 loop = len * HDMI_BITS_OF_ONE_BYTE;
1000 loop = (loop > HDMI_EDID_EXTENSION_MAX_VIC_COUNT) ? HDMI_EDID_EXTENSION_MAX_VIC_COUNT : loop;
1001 data++;
1002 for (i = 0; (i < loop) && (i < sinkCap->videoInfo.vicNum); i++) {
1003 if (sinkCap->y420Cap.SupportY420VicNum >= HDMI_EDID_EXTENSION_MAX_VIC_COUNT) {
1004 break;
1005 }
1006 if ((data[i / HDMI_BITS_OF_ONE_BYTE] & (0x01 << (i % HDMI_BITS_OF_ONE_BYTE))) > 0) {
1007 sinkCap->y420Cap.SupportY420Format[sinkCap->y420Cap.SupportY420VicNum] = sinkCap->videoInfo.vic[i];
1008 sinkCap->y420Cap.SupportY420VicNum++;
1009 sinkCap->colorSpace.ycbcr420 = true;
1010 }
1011 }
1012 }
1013
HdmiEdidExtUseExtDataBlockHdrSmdbPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data,uint8_t len)1014 static void HdmiEdidExtUseExtDataBlockHdrSmdbPhase(struct HdmiSinkDeviceCapability *sinkCap,
1015 const uint8_t *data, uint8_t len)
1016 {
1017 if (len < HDMI_EDID_HDR_SMDB_MIN_LEN) {
1018 HDF_LOGD("Hdr SMDB: len is too short");
1019 return;
1020 }
1021
1022 sinkCap->hdrCap.eotf.sdr = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT0_MARK) ? true : false;
1023 sinkCap->hdrCap.eotf.hdr = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT1_MARK) ? true : false;
1024 sinkCap->hdrCap.eotf.smpteSt2048 = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT2_MARK) ? true : false;
1025 sinkCap->hdrCap.eotf.hlg = (data[UINT8_ARRAY_TELEMENT_1] & HDMI_BIT2_MARK) ? true : false;
1026 sinkCap->hdrCap.smType1 = (data[UINT8_ARRAY_TELEMENT_2] & HDMI_BIT0_MARK) ? true : false;
1027
1028 /*
1029 * The length of the data block, n, in Byte 1 indicates which of the Bytes 5 to 7 are present. Bytes 5 to 7 are
1030 * optional to declare. When n is 3, Bytes 5 to 7 are not present. When n is 4, Byte 5 is present; when n is 5,
1031 * Bytes 5 and 6 are present; and when n is 6, Bytes 5 to 7 are present.
1032 */
1033 if (len >= HDMI_EDID_HDR_SMDB_MIN_LEN_FOR_MAX_LUMINANCE_DATA) {
1034 sinkCap->hdrCap.maxLuminancedata = data[UINT8_ARRAY_TELEMENT_3];
1035 }
1036 if (len >= HDMI_EDID_HDR_SMDB_MIN_LEN_FOR_MAX_FRAME_AVE_LUMINANCE_DATA) {
1037 sinkCap->hdrCap.maxFrameAverageLuminanceData = data[UINT8_ARRAY_TELEMENT_4];
1038 }
1039 if (len >= HDMI_EDID_HDR_SMDB_MIN_LEN_FOR_MIN_LUMINANCE_DATA) {
1040 sinkCap->hdrCap.minLuminanceData = data[UINT8_ARRAY_TELEMENT_5];
1041 }
1042 }
1043
HdmiEdidDolbyCapVersionZeroPhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data)1044 static void HdmiEdidDolbyCapVersionZeroPhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data)
1045 {
1046 sinkCap->dolbyCap.globalDimming = (data[UINT8_ARRAY_TELEMENT_4] & HDMI_BIT2_MARK) ? true : false;
1047 sinkCap->dolbyCap.redX = ((data[UINT8_ARRAY_TELEMENT_5] &
1048 HDMI_UPPER_NIBBLE_MARK) >>
1049 HDMI_NIBBLE_SHIFT) |
1050 (data[UINT8_ARRAY_TELEMENT_6] << HDMI_NIBBLE_SHIFT);
1051 sinkCap->dolbyCap.redY = (data[UINT8_ARRAY_TELEMENT_5] &
1052 HDMI_LOWER_NIBBLE_MARK) |
1053 (data[UINT8_ARRAY_TELEMENT_7] << HDMI_NIBBLE_SHIFT);
1054 sinkCap->dolbyCap.greenX = ((data[UINT8_ARRAY_TELEMENT_8] & HDMI_UPPER_NIBBLE_MARK) >>
1055 HDMI_NIBBLE_SHIFT) |
1056 (data[UINT8_ARRAY_TELEMENT_9] << HDMI_NIBBLE_SHIFT);
1057 sinkCap->dolbyCap.greenY = (data[UINT8_ARRAY_TELEMENT_8] &
1058 HDMI_LOWER_NIBBLE_MARK) |
1059 (data[UINT8_ARRAY_TELEMENT_10] << HDMI_NIBBLE_SHIFT);
1060 sinkCap->dolbyCap.blueX = ((data[UINT8_ARRAY_TELEMENT_11] & HDMI_UPPER_NIBBLE_MARK) >>
1061 HDMI_NIBBLE_SHIFT) |
1062 (data[UINT8_ARRAY_TELEMENT_12] << HDMI_NIBBLE_SHIFT);
1063 sinkCap->dolbyCap.blueY = (data[UINT8_ARRAY_TELEMENT_11] &
1064 HDMI_LOWER_NIBBLE_MARK) |
1065 (data[UINT8_ARRAY_TELEMENT_13] << HDMI_NIBBLE_SHIFT);
1066 sinkCap->dolbyCap.whiteX = ((data[UINT8_ARRAY_TELEMENT_14] & HDMI_UPPER_NIBBLE_MARK) >>
1067 HDMI_NIBBLE_SHIFT) |
1068 (data[UINT8_ARRAY_TELEMENT_15] << HDMI_NIBBLE_SHIFT);
1069 sinkCap->dolbyCap.whiteY = (data[UINT8_ARRAY_TELEMENT_14] & HDMI_LOWER_NIBBLE_MARK) |
1070 (data[UINT8_ARRAY_TELEMENT_16] << HDMI_NIBBLE_SHIFT);
1071 sinkCap->dolbyCap.minLuminance = ((data[UINT8_ARRAY_TELEMENT_17] & HDMI_UPPER_NIBBLE_MARK) >>
1072 HDMI_NIBBLE_SHIFT) |
1073 (data[UINT8_ARRAY_TELEMENT_18] << HDMI_NIBBLE_SHIFT);
1074 sinkCap->dolbyCap.maxLuminance = (data[UINT8_ARRAY_TELEMENT_17] & HDMI_LOWER_NIBBLE_MARK) |
1075 (data[UINT8_ARRAY_TELEMENT_19] << HDMI_NIBBLE_SHIFT);
1076 sinkCap->dolbyCap.dMajorVer = (data[UINT8_ARRAY_TELEMENT_20] & HDMI_UPPER_NIBBLE_MARK) >>
1077 HDMI_NIBBLE_SHIFT;
1078 sinkCap->dolbyCap.dMinorVer = (data[UINT8_ARRAY_TELEMENT_20] & HDMI_LOWER_NIBBLE_MARK);
1079 }
1080
HdmiEdidDolbyCapVersionOnePhase(struct HdmiSinkDeviceCapability * sinkCap,const uint8_t * data)1081 static void HdmiEdidDolbyCapVersionOnePhase(struct HdmiSinkDeviceCapability *sinkCap, const uint8_t *data)
1082 {
1083 sinkCap->dolbyCap.dmVer = (data[UINT8_ARRAY_TELEMENT_4] & HDMI_EDID_VSVDB_DOLBY_DM_VER_MARK) >>
1084 HDMI_EDID_VSVDB_DOLBY_DM_VER_SHIFT;
1085 sinkCap->dolbyCap.globalDimming = (data[UINT8_ARRAY_TELEMENT_5] & HDMI_BIT0_MARK) ? true : false;
1086 sinkCap->dolbyCap.maxLuminance = ((data[UINT8_ARRAY_TELEMENT_5] >> 1) & HDMI_EDID_VSVDB_DOLBY_LOWER_7BIT_MARK);
1087 sinkCap->dolbyCap.colorimetry = (data[UINT8_ARRAY_TELEMENT_6] & HDMI_BIT0_MARK) ? true : false;
1088 sinkCap->dolbyCap.minLuminance = ((data[UINT8_ARRAY_TELEMENT_6] >> 1) & HDMI_EDID_VSVDB_DOLBY_LOWER_7BIT_MARK);
1089 sinkCap->dolbyCap.redX = data[UINT8_ARRAY_TELEMENT_8];
1090 sinkCap->dolbyCap.redY = data[UINT8_ARRAY_TELEMENT_9];
1091 sinkCap->dolbyCap.greenX = data[UINT8_ARRAY_TELEMENT_10];
1092 sinkCap->dolbyCap.greenY = data[UINT8_ARRAY_TELEMENT_11];
1093 sinkCap->dolbyCap.blueX = data[UINT8_ARRAY_TELEMENT_12];
1094 sinkCap->dolbyCap.blueY = data[UINT8_ARRAY_TELEMENT_13];
1095 }
1096
1097 #define SHIFT_8_BIT 8
1098 #define SHIFT_16_BIT 16
1099
HdmiEdidExtUseExtDataBlockVsvdbPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)1100 static void HdmiEdidExtUseExtDataBlockVsvdbPhase(struct HdmiSinkDeviceCapability *sinkCap,
1101 uint8_t *data,
1102 uint8_t len)
1103 {
1104 uint32_t oui;
1105
1106 if (len != HDMI_EDID_VSVDB_DOLBY_VERSION_0_LEN &&
1107 len != HDMI_EDID_VSVDB_DOLBY_VERSION_1_LEN) {
1108 HDF_LOGD("Vsvdb: invalid dolby len");
1109 return;
1110 }
1111
1112 oui = (data[UINT8_ARRAY_TELEMENT_1]) | (data[UINT8_ARRAY_TELEMENT_2] << SHIFT_8_BIT) |
1113 (data[UINT8_ARRAY_TELEMENT_3] << SHIFT_16_BIT);
1114 if (oui != HDMI_EDID_VSVDB_DOLBY_OUI) {
1115 return;
1116 }
1117 sinkCap->dolbyCap.oui = oui;
1118 sinkCap->dolbyCap.version = (data[UINT8_ARRAY_TELEMENT_4] &
1119 HDMI_EDID_VSVDB_DOLBY_VERSION_MARK) >> HDMI_EDID_VSVDB_DOLBY_VERSION_SHIFT;
1120 sinkCap->dolbyCap.yuv422 = (data[UINT8_ARRAY_TELEMENT_4] & HDMI_BIT0_MARK) ? true : false;
1121 sinkCap->dolbyCap.b2160p60 = (data[UINT8_ARRAY_TELEMENT_4] & HDMI_BIT1_MARK) ? true : false;
1122 if (sinkCap->dolbyCap.version == HDMI_EDID_VSVDB_DOLBY_VERSION_0) {
1123 HdmiEdidDolbyCapVersionZeroPhase(sinkCap, data);
1124 return;
1125 }
1126 if (sinkCap->dolbyCap.version == HDMI_EDID_VSVDB_DOLBY_VERSION_1) {
1127 HdmiEdidDolbyCapVersionOnePhase(sinkCap, data);
1128 }
1129 }
1130
HdmiEdidExtUseExtDataBlockPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len)1131 static int32_t HdmiEdidExtUseExtDataBlockPhase(struct HdmiSinkDeviceCapability *sinkCap, uint8_t *data, uint8_t len)
1132 {
1133 uint8_t extTagCode = data[UINT8_ARRAY_TELEMENT_0];
1134
1135 switch (extTagCode) {
1136 case HDMI_EDID_EXT_VCDB:
1137 HdmiEdidExtUseExtDataBlockVcdbPhase(sinkCap, data, len);
1138 break;
1139 case HDMI_EDID_EXT_VSVDB:
1140 HdmiEdidExtUseExtDataBlockVsvdbPhase(sinkCap, data, len);
1141 break;
1142 case HDMI_EDID_EXT_CDB:
1143 HdmiEdidExtUseExtDataBlockCdbPhase(sinkCap, data, len);
1144 break;
1145 case HDMI_EDID_EXT_HDR_SMDB:
1146 HdmiEdidExtUseExtDataBlockHdrSmdbPhase(sinkCap, data, len);
1147 break;
1148 case HDMI_EDID_EXT_YCBCR420_VDB:
1149 HdmiEdidExtUseExtDataBlockY420VdbPhase(sinkCap, data, len);
1150 break;
1151 case HDMI_EDID_EXT_YCBCR420_CMDB:
1152 HdmiEdidExtUseExtDataBlockY420CmdbPhase(sinkCap, data, len);
1153 break;
1154 default:
1155 HDF_LOGD("ext use ext DB: tag code %hhu unphase", extTagCode);
1156 break;
1157 }
1158 return HDF_SUCCESS;
1159 }
1160
HdmiEdidExtDataBlockPhase(struct HdmiSinkDeviceCapability * sinkCap,uint8_t * data,uint8_t len,uint8_t tag)1161 static int32_t HdmiEdidExtDataBlockPhase(struct HdmiSinkDeviceCapability *sinkCap,
1162 uint8_t *data, uint8_t len, uint8_t tag)
1163 {
1164 int32_t ret = HDF_SUCCESS;
1165
1166 if (len == 0) {
1167 HDF_LOGD("ext DB: len is 0");
1168 return ret;
1169 }
1170
1171 switch (tag) {
1172 case HDMI_EDID_AUDIO_DATA_BLOCK:
1173 /* Audio Data Block (includes one or more Short Audio Descriptors) */
1174 ret = HdmiEdidExtAudioDataBlockPhase(sinkCap, data, len);
1175 break;
1176 case HDMI_EDID_VIDEO_DATA_BLOCK:
1177 /* Video Data Block (includes one or more Short Video Descriptors) */
1178 ret = HdmiEdidExtVideoDataBlockPhase(sinkCap, data, len);
1179 break;
1180 case HDMI_EDID_VENDOR_SPECIFIC_DATA_BLOCK:
1181 ret = HdmiEdidExtVsDataBlockPhase(sinkCap, data, len);
1182 break;
1183 case HDMI_EDID_SPEAKER_ALLOCATION_DATA_BLOCK:
1184 ret = HdmiEdidExtSpeakerDataBlockPhase(sinkCap, data, len);
1185 break;
1186 case HDMI_EDID_USE_EXT_DATA_BLOCK:
1187 ret = HdmiEdidExtUseExtDataBlockPhase(sinkCap, data, len);
1188 break;
1189 default:
1190 HDF_LOGD("tag = %hhu is reserved or unphase block", tag);
1191 break;
1192 }
1193 return ret;
1194 }
1195
HdmiEdidExtSeveralDataBlockPhase(struct HdmiEdid * edid,uint8_t blockNum)1196 static void HdmiEdidExtSeveralDataBlockPhase(struct HdmiEdid *edid, uint8_t blockNum)
1197 {
1198 uint8_t *data = edid->raw + (blockNum * HDMI_EDID_SINGLE_BLOCK_SIZE);
1199 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
1200 uint8_t blkOffset = HDMI_EDID_EXTENSION_BLOCK_OFFSET;
1201 uint8_t dtdOffset = data[UINT8_ARRAY_TELEMENT_2];
1202 uint8_t dbTagCode;
1203 uint8_t blkLen;
1204 int32_t ret;
1205
1206 data += blkOffset;
1207 /* phase data block */
1208 for (blkLen = 0; (blkOffset < dtdOffset) && (data != NULL); blkOffset += (blkLen + 1)) {
1209 data += blkLen;
1210 blkLen = (data[UINT8_ARRAY_TELEMENT_0] & HDMI_EDID_EXTENSION_DATA_BLOCK_LEN_MARK);
1211 dbTagCode = (data[UINT8_ARRAY_TELEMENT_0] & HDMI_EDID_EXTENSION_DATA_BLOCK_TAG_CODE_MARK) >>
1212 HDMI_EDID_EXTENSION_DATA_BLOCK_TAG_CODE_SHIFT;
1213 data++;
1214 ret = HdmiEdidExtDataBlockPhase(sinkCap, data, blkLen, dbTagCode);
1215 if (ret != HDF_SUCCESS) {
1216 HDF_LOGE("data block %hhu phase fail", dbTagCode);
1217 return;
1218 }
1219 }
1220
1221 data += blkLen;
1222 /* phase detialed timing descriptors */
1223 while ((HDMI_EDID_SINGLE_BLOCK_SIZE - 1 - blkOffset) >= HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN) {
1224 HdmiEdidDetailedTiming(sinkCap, data, HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN);
1225 blkOffset += HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN;
1226 data += HDMI_EDID_DETAILED_TIMING_DESCRIPTOR_FIELD_LEN;
1227 }
1228 }
1229
HdmiEdidExtBlockPhase(struct HdmiEdid * edid,uint8_t blockNum)1230 static int32_t HdmiEdidExtBlockPhase(struct HdmiEdid *edid, uint8_t blockNum)
1231 {
1232 uint8_t *data = edid->raw;
1233 struct HdmiSinkDeviceCapability *sinkCap = &(edid->sinkCap);
1234 int32_t ret;
1235
1236 if (blockNum >= HDMI_EDID_MAX_BLOCK_NUM) {
1237 HDF_LOGE("blockNum %hhu is invalid", blockNum);
1238 return HDF_ERR_INVALID_PARAM;
1239 }
1240
1241 data += (blockNum * HDMI_EDID_SINGLE_BLOCK_SIZE);
1242 ret = HdmiEdidBlockCheckSum(data);
1243 if (ret != HDF_SUCCESS) {
1244 HDF_LOGE("edid block%hhu check sum fail.", blockNum);
1245 return ret;
1246 }
1247
1248 /* byte0: Extension Tag */
1249 if (data[UINT8_ARRAY_TELEMENT_0] != HDMI_EDID_CTA_EXTENSION_TAG) {
1250 HDF_LOGD("ext tag is %hhu", data[UINT8_ARRAY_TELEMENT_0]);
1251 }
1252 /* byte1: Extension Revision Number */
1253 if (data[UINT8_ARRAY_TELEMENT_1] != HDMI_EDID_CTA_EXTENSION3_REVISION) {
1254 HDF_LOGD("revision number is %hhu", data[UINT8_ARRAY_TELEMENT_1]);
1255 }
1256 /*
1257 * byte2: Byte number offset d where 18-byte descriptors begin (typically Detailed Timing Descriptors).
1258 * If no data is provided in the reserved data block, then d is 4. If d is 0, then no detailed timing
1259 * descriptors are provided and no data is provided in the reserved data block collection.
1260 */
1261 if (data[UINT8_ARRAY_TELEMENT_2] < HDMI_EDID_EXTENSION_D_INVALID_MIN_VAL) {
1262 HDF_LOGD("ext block%hhu no dtd", blockNum);
1263 return HDF_SUCCESS;
1264 }
1265 /* byte3: indication of underscan support, audio support, support of YCBCR and total number of native DTDs. */
1266 sinkCap->colorSpace.rgb444 = true;
1267 sinkCap->colorSpace.ycbcr422 = (data[UINT8_ARRAY_TELEMENT_3] & HDMI_BIT4_MARK) ? true : false;
1268 sinkCap->colorSpace.ycbcr444 = (data[UINT8_ARRAY_TELEMENT_3] & HDMI_BIT5_MARK) ? true : false;
1269 sinkCap->supportAudio = (data[UINT8_ARRAY_TELEMENT_3] & HDMI_BIT6_MARK) ? true : false;
1270 /*
1271 * Video Data Block, Audio Data Block, Speaker Allocation Data Block,
1272 * Vendor Specific Data Block and Video Capability Data Block phase.
1273 */
1274 HdmiEdidExtSeveralDataBlockPhase(edid, blockNum);
1275 return HDF_SUCCESS;
1276 }
1277
HdmiEdidPhase(struct HdmiEdid * edid)1278 int32_t HdmiEdidPhase(struct HdmiEdid *edid)
1279 {
1280 uint8_t blockNum;
1281 int32_t ret;
1282 struct HdmiSinkDeviceCapability *sinkCap = NULL;
1283
1284 if (edid == NULL) {
1285 return HDF_ERR_INVALID_PARAM;
1286 }
1287
1288 ret = HdmiEdidFirstBlockPhase(edid);
1289 if (ret != HDF_SUCCESS) {
1290 HDF_LOGE("edid first block phase fail.");
1291 return ret;
1292 }
1293
1294 sinkCap = &(edid->sinkCap);
1295 for (blockNum = 1; blockNum <= sinkCap->extBlockNum; blockNum++) {
1296 ret = HdmiEdidExtBlockPhase(edid, blockNum);
1297 if (ret != HDF_SUCCESS) {
1298 HDF_LOGE("edid ext block%hhu phase fail.", blockNum);
1299 return ret;
1300 }
1301 }
1302 return HDF_SUCCESS;
1303 }
1304
HdmiEdidRawDataRead(struct HdmiEdid * edid,struct HdmiDdc * ddc)1305 int32_t HdmiEdidRawDataRead(struct HdmiEdid *edid, struct HdmiDdc *ddc)
1306 {
1307 struct HdmiDdcCfg cfg = {0};
1308 int32_t ret;
1309 uint8_t extBlkNum;
1310
1311 if (edid == NULL || ddc == NULL) {
1312 return HDF_ERR_INVALID_PARAM;
1313 }
1314
1315 /* read block0 */
1316 cfg.type = HDMI_DDC_DEV_EDID;
1317 cfg.mode = HDMI_DDC_MODE_READ_MUTIL_NO_ACK;
1318 cfg.data = edid->raw;
1319 cfg.dataLen = HDMI_EDID_SINGLE_BLOCK_SIZE;
1320 cfg.readFlag = true;
1321 cfg.devAddr = HDMI_DDC_EDID_DEV_ADDRESS;
1322 ret = HdmiDdcTransfer(ddc, &cfg);
1323 if (ret != HDF_SUCCESS) {
1324 HDF_LOGE("edid block0 read fail");
1325 return ret;
1326 }
1327 edid->rawLen += HDMI_EDID_SINGLE_BLOCK_SIZE;
1328
1329 extBlkNum = edid->raw[HDMI_EDID_EXTENSION_BLOCK_ADDR];
1330 if (extBlkNum > (HDMI_EDID_MAX_BLOCK_NUM - 1)) {
1331 extBlkNum = (HDMI_EDID_MAX_BLOCK_NUM - 1);
1332 HDF_LOGD("extBlkNum > max, use max.");
1333 }
1334 if (extBlkNum == 0) {
1335 HDF_LOGD("edid only has block0");
1336 return HDF_SUCCESS;
1337 }
1338
1339 /* read block1 */
1340 cfg.data += HDMI_EDID_SINGLE_BLOCK_SIZE;
1341 ret = HdmiDdcTransfer(ddc, &cfg);
1342 if (ret != HDF_SUCCESS) {
1343 HDF_LOGE("edid block1 read fail");
1344 return ret;
1345 }
1346 edid->rawLen += HDMI_EDID_SINGLE_BLOCK_SIZE;
1347
1348 if (extBlkNum == 1) {
1349 HDF_LOGD("edid only has block0~1");
1350 return HDF_SUCCESS;
1351 }
1352 /* read block2~3 */
1353 cfg.data += HDMI_EDID_SINGLE_BLOCK_SIZE;
1354 cfg.dataLen = (extBlkNum - 1) * HDMI_EDID_SINGLE_BLOCK_SIZE;
1355 cfg.mode = HDMI_DDC_MODE_READ_SEGMENT_NO_ACK;
1356 cfg.segment = 1;
1357 ret = HdmiDdcTransfer(ddc, &cfg);
1358 if (ret != HDF_SUCCESS) {
1359 HDF_LOGE("edid block2~3 read fail");
1360 return ret;
1361 }
1362 edid->rawLen += (extBlkNum - 1) * HDMI_EDID_SINGLE_BLOCK_SIZE;
1363 return HDF_SUCCESS;
1364 }
1365
HdmiEdidSupportFrl(struct HdmiDevice * hdmi)1366 bool HdmiEdidSupportFrl(struct HdmiDevice *hdmi)
1367 {
1368 if (hdmi == NULL) {
1369 HDF_LOGD("no hdmi sink.");
1370 return false;
1371 }
1372
1373 if (hdmi->edid.sinkCap.hfVsdbInfo.scdcPresent == true &&
1374 hdmi->edid.sinkCap.hfVsdbInfo.maxFrlRate > 0) {
1375 return true;
1376 }
1377 return false;
1378 }
1379
HdmiEdidGetMaxFrlRate(struct HdmiDevice * hdmi)1380 uint8_t HdmiEdidGetMaxFrlRate(struct HdmiDevice *hdmi)
1381 {
1382 if (hdmi == NULL) {
1383 HDF_LOGD("no hdmi sink.");
1384 return 0;
1385 }
1386 return hdmi->edid.sinkCap.hfVsdbInfo.maxFrlRate;
1387 }
1388
HdmiEdidScdcSupport(struct HdmiDevice * hdmi)1389 bool HdmiEdidScdcSupport(struct HdmiDevice *hdmi)
1390 {
1391 if (hdmi == NULL) {
1392 HDF_LOGD("no hdmi sink.");
1393 return false;
1394 }
1395 return hdmi->edid.sinkCap.hfVsdbInfo.scdcPresent;
1396 }
1397