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