• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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