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