• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 Allwinnertech Co.Ltd
3  * Authors: zhengwanyu
4  *
5  * This program is free software; you can redistribute  it and/or modify it
6  * under  the terms of  the GNU General  Public License as published by the
7  * Free Software Foundation;  either version 2 of the  License, or (at your
8  * option) any later version.
9  *
10  */
11 #include <drm/drmP.h>
12 #include <drm/drm_edid.h>
13 #include <drm/drm_modes.h>
14 
15 #include "hdmi_core/api/core_api.h"
16 #include "sunxi_drm_connector.h"
17 
18 #if defined(CONFIG_AW_DRM_HDMI14)
19 #include "sunxi_device/sunxi_hdmi14.h"
20 #elif defined(CONFIG_AW_DRM_HDMI20)
21 #include "sunxi_device/sunxi_hdmi20.h"
22 #endif
23 
24 //static unsigned char sunxi_edid[1024];
25 
26 extern struct sunxi_drm_hdmi_connector *
27 to_sunxi_hdmi_connector(struct drm_connector *conn);
28 
29 extern void
30 sunxi_drm_hdmi_set_working_mode(
31 		struct sunxi_drm_connector *sconn,
32 		struct sunxi_hdmi_work_mode *work_mode);
33 
edid_bit_field(const u16 data,u8 shift,u8 width)34 static u8 edid_bit_field(const u16 data, u8 shift, u8 width)
35 {
36 	return (data >> shift) & ((((u16) 1) << width) - 1);
37 }
38 
edid_concat_bits(u8 bHi,u8 oHi,u8 nHi,u8 bLo,u8 oLo,u8 nLo)39 static u16 edid_concat_bits(u8 bHi, u8 oHi, u8 nHi, u8 bLo, u8 oLo, u8 nLo)
40 {
41 	return (edid_bit_field(bHi, oHi, nHi) << nLo) | edid_bit_field(bLo, oLo, nLo);
42 }
43 
edid_byte_to_word(const u8 hi,const u8 lo)44 static u16 edid_byte_to_word(const u8 hi, const u8 lo)
45 {
46 	return edid_concat_bits(hi, 0, 8, lo, 0, 8);
47 }
48 
edid_byte_to_dword(u8 b3,u8 b2,u8 b1,u8 b0)49 static u32 edid_byte_to_dword(u8 b3, u8 b2, u8 b1, u8 b0)
50 {
51 	u32 retval = 0;
52 
53 	retval |= b0 << (0 * 8);
54 	retval |= b1 << (1 * 8);
55 	retval |= b2 << (2 * 8);
56 	retval |= b3 << (3 * 8);
57 	return retval;
58 }
59 
60 static void speaker_alloc_data_block_reset(
61 			speakerAllocationDataBlock_t *sadb);
62 static void video_cap_data_block_reset(
63 			videoCapabilityDataBlock_t *vcdb);
64 
dtd_parse(dtd_t * dtd,u8 data[18])65 static int dtd_parse(dtd_t *dtd, u8 data[18])
66 {
67 	/*  */
68 
69 	dtd->mCode = -1;
70 	dtd->mPixelRepetitionInput = 0;
71 	dtd->mLimitedToYcc420 = 0;
72 	dtd->mYcc420 = 0;
73 
74 	dtd->mPixelClock = 1000 * edid_byte_to_word(data[1], data[0]);/*[10000Hz]*/
75 	if (dtd->mPixelClock < 0x01) {	/* 0x0000 is defined as reserved */
76 		return false;
77 	}
78 
79 	dtd->mHActive = edid_concat_bits(data[4], 4, 4, data[2], 0, 8);
80 	dtd->mHBlanking = edid_concat_bits(data[4], 0, 4, data[3], 0, 8);
81 	dtd->mHSyncOffset = edid_concat_bits(data[11], 6, 2, data[8], 0, 8);
82 	dtd->mHSyncPulseWidth = edid_concat_bits(data[11], 4, 2, data[9], 0, 8);
83 	dtd->mHImageSize = edid_concat_bits(data[14], 4, 4, data[12], 0, 8);
84 	dtd->mHBorder = data[15];
85 
86 	dtd->mVActive = edid_concat_bits(data[7], 4, 4, data[5], 0, 8);
87 	dtd->mVBlanking = edid_concat_bits(data[7], 0, 4, data[6], 0, 8);
88 	dtd->mVSyncOffset = edid_concat_bits(data[11], 2, 2, data[10], 4, 4);
89 	dtd->mVSyncPulseWidth = edid_concat_bits(data[11], 0, 2, data[10], 0, 4);
90 	dtd->mVImageSize = edid_concat_bits(data[14], 0, 4, data[13], 0, 8);
91 	dtd->mVBorder = data[16];
92 
93 	if (edid_bit_field(data[17], 4, 1) != 1) {/*if not DIGITAL SYNC SIGNAL DEF*/
94 		DRM_ERROR("Error:Invalid DTD Parameters\n");
95 		return false;
96 	}
97 	if (edid_bit_field(data[17], 3, 1) != 1) {/*if not DIGITAL SEPATATE SYNC*/
98 		DRM_ERROR("Error:Invalid DTD Parameters\n");
99 		return false;
100 	}
101 	/* no stereo viewing support in HDMI */
102 	dtd->mInterlaced = edid_bit_field(data[17], 7, 1) == 1;
103 	dtd->mVSyncPolarity = edid_bit_field(data[17], 2, 1) == 1;
104 	dtd->mHSyncPolarity = edid_bit_field(data[17], 1, 1) == 1;
105 	return true;
106 }
107 
monitor_range_limits_reset(monitorRangeLimits_t * mrl)108 static void monitor_range_limits_reset(monitorRangeLimits_t *mrl)
109 {
110 	mrl->mMinVerticalRate = 0;
111 	mrl->mMaxVerticalRate = 0;
112 	mrl->mMinHorizontalRate = 0;
113 	mrl->mMaxHorizontalRate = 0;
114 	mrl->mMaxPixelClock = 0;
115 	mrl->mValid = false;
116 }
117 
colorimetry_data_block_reset(colorimetryDataBlock_t * cdb)118 static void colorimetry_data_block_reset(colorimetryDataBlock_t *cdb)
119 {
120 	cdb->mByte3 = 0;
121 	cdb->mByte4 = 0;
122 	cdb->mValid = false;
123 }
124 
125 
colorimetry_data_block_parse(colorimetryDataBlock_t * cdb,u8 * data)126 static int colorimetry_data_block_parse(colorimetryDataBlock_t *cdb, u8 *data)
127 {
128 	colorimetry_data_block_reset(cdb);
129 	if ((data != 0) && (edid_bit_field(data[0], 0, 5) == 0x03) &&
130 		(edid_bit_field(data[0], 5, 3) == 0x07)
131 			&& (edid_bit_field(data[1], 0, 7) == 0x05)) {
132 		cdb->mByte3 = data[2];
133 		cdb->mByte4 = data[3];
134 		cdb->mValid = true;
135 		return true;
136 	}
137 	return false;
138 }
139 
hdr_metadata_data_block_reset(struct hdr_static_metadata_data_block * hdr_metadata)140 static void hdr_metadata_data_block_reset(
141 		struct hdr_static_metadata_data_block *hdr_metadata)
142 {
143 	memset(hdr_metadata, 0, sizeof(struct hdr_static_metadata_data_block));
144 }
145 
hdr_static_metadata_block_parse(struct hdr_static_metadata_data_block * hdr_metadata,u8 * data)146 static int hdr_static_metadata_block_parse(
147 		struct hdr_static_metadata_data_block *hdr_metadata, u8 *data)
148 {
149 	hdr_metadata_data_block_reset(hdr_metadata);
150 	if ((data != 0) && (edid_bit_field(data[0], 0, 5) > 1)
151 		&& (edid_bit_field(data[0], 5, 3) == 0x07)
152 		&& (data[1] == 0x06)) {
153 		hdr_metadata->et_n = edid_bit_field(data[2], 0, 5);
154 		hdr_metadata->sm_n = data[3];
155 
156 		if (edid_bit_field(data[0], 0, 5) > 3)
157 			hdr_metadata->dc_max_lum_data = data[4];
158 		if (edid_bit_field(data[0], 0, 5) > 4)
159 			hdr_metadata->dc_max_fa_lum_data = data[5];
160 		if (edid_bit_field(data[0], 0, 5) > 5)
161 			hdr_metadata->dc_min_lum_data = data[6];
162 
163 		return true;
164 	}
165 	return false;
166 }
167 
hdmiforumvsdb_reset(hdmiforumvsdb_t * forumvsdb)168 static void hdmiforumvsdb_reset(hdmiforumvsdb_t *forumvsdb)
169 {
170 	forumvsdb->mValid = false;
171 	forumvsdb->mIeee_Oui = 0;
172 	forumvsdb->mVersion = 0;
173 	forumvsdb->mMaxTmdsCharRate = 0;
174 	forumvsdb->mSCDC_Present = false;
175 	forumvsdb->mRR_Capable = false;
176 	forumvsdb->mLTS_340Mcs_scramble = false;
177 	forumvsdb->mIndependentView = false;
178 	forumvsdb->mDualView = false;
179 	forumvsdb->m3D_OSD_Disparity = false;
180 	forumvsdb->mDC_30bit_420 = false;
181 	forumvsdb->mDC_36bit_420 = false;
182 	forumvsdb->mDC_48bit_420 = false;
183 }
184 
hdmiforumvsdb_parse(hdmiforumvsdb_t * forumvsdb,u8 * data)185 static int hdmiforumvsdb_parse(hdmiforumvsdb_t *forumvsdb,
186 					u8 *data)
187 {
188 	u16 blockLength;
189 
190 	hdmiforumvsdb_reset(forumvsdb);
191 	if (data == 0)
192 		return false;
193 
194 	if (edid_bit_field(data[0], 5, 3) != 0x3) {
195 		DRM_ERROR("Error:Invalid datablock tag\n");
196 		return false;
197 	}
198 	blockLength = edid_bit_field(data[0], 0, 5);
199 	if (blockLength < 7) {
200 		DRM_ERROR("Error:Invalid minimum length\n");
201 		return false;
202 	}
203 	if (edid_byte_to_dword(0x00, data[3], data[2], data[1]) !=
204 	    0xC45DD8) {
205 		DRM_ERROR("Error:HDMI IEEE registration identifier not valid\n");
206 		return false;
207 	}
208 	forumvsdb->mVersion = edid_bit_field(data[4], 0, 7);
209 	forumvsdb->mMaxTmdsCharRate = edid_bit_field(data[5], 0, 7);
210 	forumvsdb->mSCDC_Present = edid_bit_field(data[6], 7, 1);
211 	forumvsdb->mRR_Capable = edid_bit_field(data[6], 6, 1);
212 	forumvsdb->mLTS_340Mcs_scramble = edid_bit_field(data[6], 3, 1);
213 	forumvsdb->mIndependentView = edid_bit_field(data[6], 2, 1);
214 	forumvsdb->mDualView = edid_bit_field(data[6], 1, 1);
215 	forumvsdb->m3D_OSD_Disparity = edid_bit_field(data[6], 0, 1);
216 	forumvsdb->mDC_30bit_420 = edid_bit_field(data[7], 2, 1);
217 	forumvsdb->mDC_36bit_420 = edid_bit_field(data[7], 1, 1);
218 	forumvsdb->mDC_48bit_420 = edid_bit_field(data[7], 0, 1);
219 	forumvsdb->mValid = true;
220 
221 #if 0
222 	DRM_DEBUG_DRIVER("version %d\n", edid_bit_field(data[4], 0, 7));
223 	DRM_DEBUG_DRIVER("Max_TMDS_Charater_rate %d\n",
224 		    edid_bit_field(data[5], 0, 7));
225 	DRM_DEBUG_DRIVER("SCDC_Present %d\n", edid_bit_field(data[6], 7, 1));
226 	DRM_DEBUG_DRIVER("RR_Capable %d\n", edid_bit_field(data[6], 6, 1));
227 	DRM_DEBUG_DRIVER("LTE_340Mcsc_scramble %d\n",
228 		    edid_bit_field(data[6], 3, 1));
229 	DRM_DEBUG_DRIVER("Independent_View %d\n", edid_bit_field(data[6], 2, 1));
230 	DRM_DEBUG_DRIVER("Dual_View %d\n", edid_bit_field(data[6], 1, 1));
231 	DRM_DEBUG_DRIVER("3D_OSD_Disparity %d\n", edid_bit_field(data[6], 0, 1));
232 	DRM_DEBUG_DRIVER("DC_48bit_420 %d\n", edid_bit_field(data[7], 2, 1));
233 	DRM_DEBUG_DRIVER("DC_36bit_420 %d\n", edid_bit_field(data[7], 1, 1));
234 	DRM_DEBUG_DRIVER("DC_30bit_420 %d\n", edid_bit_field(data[7], 0, 1));
235 #endif
236 	return true;
237 }
238 
hdmivsdb_reset(hdmivsdb_t * vsdb)239 static void hdmivsdb_reset(hdmivsdb_t *vsdb)
240 {
241 	int i, j = 0;
242 
243 	vsdb->mPhysicalAddress = 0;
244 	vsdb->mSupportsAi = false;
245 	vsdb->mDeepColor30 = false;
246 	vsdb->mDeepColor36 = false;
247 	vsdb->mDeepColor48 = false;
248 	vsdb->mDeepColorY444 = false;
249 	vsdb->mDviDual = false;
250 	vsdb->mMaxTmdsClk = 0;
251 	vsdb->mVideoLatency = 0;
252 	vsdb->mAudioLatency = 0;
253 	vsdb->mInterlacedVideoLatency = 0;
254 	vsdb->mInterlacedAudioLatency = 0;
255 	vsdb->mId = 0;
256 	vsdb->mContentTypeSupport = 0;
257 	vsdb->mHdmiVicCount = 0;
258 	for (i = 0; i < MAX_HDMI_VIC; i++)
259 		vsdb->mHdmiVic[i] = 0;
260 
261 	vsdb->m3dPresent = false;
262 	for (i = 0; i < MAX_VIC_WITH_3D; i++) {
263 		for (j = 0; j < MAX_HDMI_3DSTRUCT; j++)
264 			vsdb->mVideo3dStruct[i][j] = 0;
265 	}
266 	for (i = 0; i < MAX_VIC_WITH_3D; i++) {
267 		for (j = 0; j < MAX_HDMI_3DSTRUCT; j++)
268 			vsdb->mDetail3d[i][j] = ~0;
269 	}
270 	vsdb->mValid = false;
271 }
272 
edid_parser_CeaExtReset(sink_edid_t * edidExt)273 static int edid_parser_CeaExtReset(sink_edid_t *edidExt)
274 {
275 	unsigned i = 0;
276 
277 	edidExt->edid_m20Sink = false;
278 #if 1
279 	for (i = 0; i < sizeof(edidExt->edid_mMonitorName); i++)
280 		edidExt->edid_mMonitorName[i] = 0;
281 
282 	edidExt->edid_mBasicAudioSupport = false;
283 	edidExt->edid_mUnderscanSupport = false;
284 	edidExt->edid_mYcc422Support = false;
285 	edidExt->edid_mYcc444Support = false;
286 	edidExt->edid_mYcc420Support = false;
287 	edidExt->edid_mDtdIndex = 0;
288 	edidExt->edid_mSadIndex = 0;
289 	edidExt->edid_mSvdIndex = 0;
290 #endif
291 	hdmivsdb_reset(&edidExt->edid_mHdmivsdb);
292 	hdmiforumvsdb_reset(&edidExt->edid_mHdmiForumvsdb);
293 	monitor_range_limits_reset(&edidExt->edid_mMonitorRangeLimits);
294 	video_cap_data_block_reset(&edidExt->edid_mVideoCapabilityDataBlock);
295 	colorimetry_data_block_reset(&edidExt->edid_mColorimetryDataBlock);
296 	hdr_metadata_data_block_reset(&edidExt->edid_hdr_static_metadata_data_block);
297 	speaker_alloc_data_block_reset(
298 				&edidExt->edid_mSpeakerAllocationDataBlock);
299 	return true;
300 }
301 
302 
hdmivsdb_parse(hdmivsdb_t * vsdb,u8 * data)303 static int hdmivsdb_parse(hdmivsdb_t *vsdb, u8 *data)
304 {
305 	u8 blockLength = 0;
306 	unsigned videoInfoStart = 0;
307 	unsigned hdmi3dStart = 0;
308 	unsigned hdmiVicLen = 0;
309 	unsigned hdmi3dLen = 0;
310 	unsigned spanned3d = 0;
311 	unsigned i = 0;
312 	unsigned j = 0;
313 
314 	hdmivsdb_reset(vsdb);
315 	if (data == 0)
316 		return false;
317 
318 	if (edid_bit_field(data[0], 5, 3) != 0x3) {
319 		DRM_ERROR("Error:Invalid datablock tag\n");
320 		return false;
321 	}
322 	blockLength = edid_bit_field(data[0], 0, 5);
323 	if (blockLength < 5) {
324 		DRM_ERROR("Error:Invalid minimum length\n");
325 		return false;
326 	}
327 	if (edid_byte_to_dword(0x00, data[3], data[2], data[1]) != 0x000C03) {
328 		DRM_ERROR("Error:HDMI IEEE registration identifier not valid\n");
329 		return false;
330 	}
331 	hdmivsdb_reset(vsdb);
332 	vsdb->mId = 0x000C03;
333 	vsdb->mPhysicalAddress = edid_byte_to_word(data[4], data[5]);
334 	/* parse extension fields if they exist */
335 	if (blockLength > 5) {
336 		vsdb->mSupportsAi = edid_bit_field(data[6], 7, 1) == 1;
337 		vsdb->mDeepColor48 = edid_bit_field(data[6], 6, 1) == 1;
338 		vsdb->mDeepColor36 = edid_bit_field(data[6], 5, 1) == 1;
339 		vsdb->mDeepColor30 = edid_bit_field(data[6], 4, 1) == 1;
340 		vsdb->mDeepColorY444 = edid_bit_field(data[6], 3, 1) == 1;
341 		vsdb->mDviDual = edid_bit_field(data[6], 0, 1) == 1;
342 	} else {
343 		vsdb->mSupportsAi = false;
344 		vsdb->mDeepColor48 = false;
345 		vsdb->mDeepColor36 = false;
346 		vsdb->mDeepColor30 = false;
347 		vsdb->mDeepColorY444 = false;
348 		vsdb->mDviDual = false;
349 	}
350 	vsdb->mMaxTmdsClk = (blockLength > 6) ? data[7] : 0;
351 	vsdb->mVideoLatency = 0;
352 	vsdb->mAudioLatency = 0;
353 	vsdb->mInterlacedVideoLatency = 0;
354 	vsdb->mInterlacedAudioLatency = 0;
355 	if (blockLength > 7) {
356 		if (edid_bit_field(data[8], 7, 1) == 1) {
357 			if (blockLength < 10) {
358 				DRM_ERROR("Error:Invalid length - latencies are not valid\n");
359 				return false;
360 			}
361 			if (edid_bit_field(data[8], 6, 1) == 1) {
362 				if (blockLength < 12) {
363 					DRM_ERROR("Error:Invalid length - Interlaced latencies are not valid\n");
364 					return false;
365 				} else {
366 					vsdb->mVideoLatency = data[9];
367 					vsdb->mAudioLatency = data[10];
368 					vsdb->mInterlacedVideoLatency
369 								= data[11];
370 					vsdb->mInterlacedAudioLatency
371 								= data[12];
372 					videoInfoStart = 13;
373 				}
374 			} else {
375 				vsdb->mVideoLatency = data[9];
376 				vsdb->mAudioLatency = data[10];
377 				vsdb->mInterlacedVideoLatency = 0;
378 				vsdb->mInterlacedAudioLatency = 0;
379 				videoInfoStart = 11;
380 			}
381 		} else {	/* no latency data */
382 			vsdb->mVideoLatency = 0;
383 			vsdb->mAudioLatency = 0;
384 			vsdb->mInterlacedVideoLatency = 0;
385 			vsdb->mInterlacedAudioLatency = 0;
386 			videoInfoStart = 9;
387 		}
388 		vsdb->mContentTypeSupport = edid_bit_field(data[8], 0, 4);
389 	}
390 	/* additional video format capabilities are described */
391 	if (edid_bit_field(data[8], 5, 1) == 1) {
392 		vsdb->mImageSize = edid_bit_field(data[videoInfoStart], 3, 2);
393 		hdmiVicLen = edid_bit_field(data[videoInfoStart + 1], 5, 3);
394 		hdmi3dLen = edid_bit_field(data[videoInfoStart + 1], 0, 5);
395 		for (i = 0; i < hdmiVicLen; i++)
396 			vsdb->mHdmiVic[i] = data[videoInfoStart + 2 + i];
397 
398 		vsdb->mHdmiVicCount = hdmiVicLen;
399 		if (edid_bit_field(data[videoInfoStart], 7, 1) == 1) {/*3d present*/
400 			vsdb->m3dPresent = true;
401 			hdmi3dStart = videoInfoStart + hdmiVicLen + 2;
402 			/* 3d multi 00 -> both 3d_structure_all
403 			and 3d_mask_15 are NOT present */
404 			/* 3d mutli 11 -> reserved */
405 			if (edid_bit_field(data[videoInfoStart], 5, 2) == 1) {
406 				/* 3d multi 01 */
407 				/* 3d_structure_all is present but 3d_mask_15 not present */
408 				for (j = 0; j < 16; j++) {
409 					/* j spans 3d structures */
410 					if (edid_bit_field(data[hdmi3dStart
411 						+ (j / 8)], (j % 8), 1) == 1) {
412 						for (i = 0; i < 16; i++)
413 							vsdb->mVideo3dStruct[i][(j < 8)	? j+8 : j - 8] = 1;
414 					}
415 				}
416 				spanned3d = 2;
417 				/*hdmi3dStart += 2;
418 				   hdmi3dLen -= 2; */
419 			} else if (edid_bit_field(data[videoInfoStart], 5, 2) == 2) {
420 				/* 3d multi 10 */
421 				/* 3d_structure_all and 3d_mask_15 are present */
422 				for (j = 0; j < 16; j++) {
423 					for (i = 0; i < 16; i++) {
424 						if (edid_bit_field(data[hdmi3dStart + 2 + (i / 8)], (i % 8), 1) == 1)
425 							vsdb->mVideo3dStruct[(i < 8) ? i + 8 : i - 8][(j < 8) ? j + 8 : j - 8] = edid_bit_field(data[hdmi3dStart + (j / 8)], (j % 8), 1);
426 					}
427 				}
428 				spanned3d = 4;
429 			}
430 			if (hdmi3dLen > spanned3d) {
431 				hdmi3dStart += spanned3d;
432 				for (i = 0, j = 0; i < (hdmi3dLen - spanned3d); i++) {
433 					vsdb->mVideo3dStruct[edid_bit_field(data[hdmi3dStart + i + j], 4, 4)][edid_bit_field(data[hdmi3dStart + i + j], 0, 4)] = 1;
434 					if (edid_bit_field(data[hdmi3dStart + i + j], 4, 4) > 7) {
435 						j++;
436 						vsdb->mDetail3d[edid_bit_field(data[hdmi3dStart + i + j], 4, 4)][edid_bit_field(data[hdmi3dStart + i + j], 4, 4)] = edid_bit_field(data[hdmi3dStart + i + j], 4, 4);
437 					}
438 				}
439 			}
440 		} else {	/* 3d NOT present */
441 			vsdb->m3dPresent = false;
442 		}
443 	}
444 	vsdb->mValid = true;
445 	return true;
446 }
447 
sad_reset(shortAudioDesc_t * sad)448 static void sad_reset(shortAudioDesc_t *sad)
449 {
450 	sad->mFormat = 0;
451 	sad->mMaxChannels = 0;
452 	sad->mSampleRates = 0;
453 	sad->mByte3 = 0;
454 }
455 
sad_parse(shortAudioDesc_t * sad,u8 * data)456 static int sad_parse(shortAudioDesc_t *sad, u8 *data)
457 {
458 	sad_reset(sad);
459 	if (data != 0) {
460 		sad->mFormat = edid_bit_field(data[0], 3, 4);
461 		sad->mMaxChannels = edid_bit_field(data[0], 0, 3) + 1;
462 		sad->mSampleRates = edid_bit_field(data[1], 0, 7);
463 		sad->mByte3 = data[2];
464 		return true;
465 	}
466 	return false;
467 }
468 
469 #if 0
470 static int sad_support32k(shortAudioDesc_t *sad)
471 {
472 	return (edid_bit_field(sad->mSampleRates, 0, 1) == 1) ? true : false;
473 }
474 
475 static int sad_support44k1(shortAudioDesc_t *sad)
476 {
477 	return (edid_bit_field(sad->mSampleRates, 1, 1) == 1) ? true : false;
478 }
479 
480 static int sad_support48k(shortAudioDesc_t *sad)
481 {
482 	return (edid_bit_field(sad->mSampleRates, 2, 1) == 1) ? true : false;
483 }
484 
485 static int sad_support88k2(shortAudioDesc_t *sad)
486 {
487 	return (edid_bit_field(sad->mSampleRates, 3, 1) ==
488 		1) ? true : false;
489 }
490 
491 static int sad_support96k(shortAudioDesc_t *sad)
492 {
493 	return (edid_bit_field(sad->mSampleRates, 4, 1) == 1) ? true : false;
494 }
495 
496 static int sad_support176k4(shortAudioDesc_t *sad)
497 {
498 	return (edid_bit_field(sad->mSampleRates, 5, 1) == 1) ? true : false;
499 }
500 
501 static int sad_support192k(shortAudioDesc_t *sad)
502 {
503 	return (edid_bit_field(sad->mSampleRates, 6, 1) == 1) ? true : false;
504 }
505 
506 static int sad_support16bit(shortAudioDesc_t *sad)
507 {
508 	if (sad->mFormat == 1)
509 		return (edid_bit_field(sad->mByte3, 0, 1) == 1) ? true : false;
510 
511 	DRM_DEBUG_DRIVER("%s:Information is not valid for this format\n", __func__);
512 	return false;
513 }
514 
515 static int sad_support20bit(shortAudioDesc_t *sad)
516 {
517 	if (sad->mFormat == 1)
518 		return (edid_bit_field(sad->mByte3, 1, 1) == 1) ? true : false;
519 	DRM_DEBUG_DRIVER("%s:Information is not valid for this format\n", __func__);
520 	return false;
521 }
522 
523 static int sad_support24bit(shortAudioDesc_t *sad)
524 {
525 	if (sad->mFormat == 1)
526 		return (edid_bit_field(sad->mByte3, 2, 1) == 1) ? true : false;
527 	DRM_DEBUG_DRIVER("%s:Information is not valid for this format\n", __func__);
528 	return false;
529 }
530 #endif
531 
svd_reset(shortVideoDesc_t * svd)532 static void svd_reset(shortVideoDesc_t *svd)
533 {
534 	svd->mNative = false;
535 	svd->mCode = 0;
536 }
537 
svd_parse(shortVideoDesc_t * svd,u8 data)538 static int svd_parse(shortVideoDesc_t *svd, u8 data)
539 {
540 	svd_reset(svd);
541 	svd->mNative = (edid_bit_field(data, 7, 1) == 1) ? true : false;
542 	svd->mCode = edid_bit_field(data, 0, 7);
543 	svd->mLimitedToYcc420 = 0;
544 	svd->mYcc420 = 0;
545 	return true;
546 }
547 
548 
speaker_alloc_data_block_reset(speakerAllocationDataBlock_t * sadb)549 static void speaker_alloc_data_block_reset(
550 				speakerAllocationDataBlock_t *sadb)
551 {
552 	sadb->mByte1 = 0;
553 	sadb->mValid = false;
554 }
555 
speaker_alloc_data_block_parse(speakerAllocationDataBlock_t * sadb,u8 * data)556 static int speaker_alloc_data_block_parse(
557 				speakerAllocationDataBlock_t *sadb, u8 *data)
558 {
559 	speaker_alloc_data_block_reset(sadb);
560 	if ((data != 0) && (edid_bit_field(data[0], 0, 5) == 0x03) &&
561 				(edid_bit_field(data[0], 5, 3) == 0x04)) {
562 		sadb->mByte1 = data[1];
563 		sadb->mValid = true;
564 		return true;
565 	}
566 	return false;
567 }
568 
video_cap_data_block_reset(videoCapabilityDataBlock_t * vcdb)569 static void video_cap_data_block_reset(videoCapabilityDataBlock_t *vcdb)
570 {
571 	vcdb->mQuantizationRangeSelectable = false;
572 	vcdb->mPreferredTimingScanInfo = 0;
573 	vcdb->mItScanInfo = 0;
574 	vcdb->mCeScanInfo = 0;
575 	vcdb->mValid = false;
576 }
577 
video_cap_data_block_parse(videoCapabilityDataBlock_t * vcdb,u8 * data)578 static int video_cap_data_block_parse(videoCapabilityDataBlock_t *vcdb, u8 *data)
579 {
580 	video_cap_data_block_reset(vcdb);
581 	/* check tag code and extended tag */
582 	if ((data != 0) && (edid_bit_field(data[0], 5, 3) == 0x7) &&
583 		(edid_bit_field(data[1], 0, 8) == 0x0) &&
584 			(edid_bit_field(data[0], 0, 5) == 0x2)) {
585 		/* so far VCDB is 2 bytes long */
586 		vcdb->mCeScanInfo = edid_bit_field(data[2], 0, 2);
587 		vcdb->mItScanInfo = edid_bit_field(data[2], 2, 2);
588 		vcdb->mPreferredTimingScanInfo = edid_bit_field(data[2], 4, 2);
589 		vcdb->mQuantizationRangeSelectable =
590 				(edid_bit_field(data[2], 6, 1) == 1) ? true : false;
591 		vcdb->mValid = true;
592 		return true;
593 	}
594 	return false;
595 }
596 
597 #if 0
598 static int _edid_checksum(u8 *edid)
599 {
600 	int i, checksum = 0;
601 
602 	for (i = 0; i < EDID_LENGTH; i++)
603 		checksum += edid[i];
604 
605 	return checksum % 256; /* CEA-861 Spec */
606 }
607 #endif
608 
edid_parser_updateYcc420(sink_edid_t * edidExt,u8 Ycc420All,u8 LimitedToYcc420All)609 static void edid_parser_updateYcc420(sink_edid_t *edidExt,
610 					u8 Ycc420All, u8 LimitedToYcc420All)
611 {
612 	u16 edid_cnt = 0;
613 
614 	for (edid_cnt = 0; edid_cnt < edidExt->edid_mSvdIndex; edid_cnt++) {
615 		switch (edidExt->edid_mSvd[edid_cnt].mCode) {
616 		case 96:
617 		case 97:
618 		case 101:
619 		case 102:
620 		case 106:
621 		case 107:
622 			Ycc420All == 1 ?
623 				edidExt->edid_mSvd[edid_cnt].mYcc420 = Ycc420All : 0;
624 			LimitedToYcc420All == 1 ?
625 				edidExt->edid_mSvd[edid_cnt].mLimitedToYcc420 =
626 							LimitedToYcc420All : 0;
627 			break;
628 		}
629 	}
630 }
631 
632 
_edid_struture_parser(struct edid * edid,sink_edid_t * sink)633 static int _edid_struture_parser(struct edid *edid,
634 					sink_edid_t *sink)
635 {
636 	int i;
637 	char *monitorName;
638 
639 	if (edid->header[0] != 0) {
640 		DRM_ERROR(":Error:Invalid Header\n");
641 		return -1;
642 	}
643 
644 	DRM_DEBUG_DRIVER("\n\nEDID Block0 detailed discriptor:\n");
645 	for (i = 0; i < 4; i++) {
646 		struct detailed_timing *detailed_timing = &(edid->detailed_timings[i]);
647 
648 		if (detailed_timing->pixel_clock == 0) {
649 			struct detailed_non_pixel *npixel = &(detailed_timing->data.other_data);
650 
651 			switch (npixel->type) {
652 			case EDID_DETAIL_MONITOR_NAME:
653 				monitorName = (char *) &(npixel->data.str.str);
654 				DRM_DEBUG_DRIVER("Monitor name: %s\n", monitorName);
655 				break;
656 			case EDID_DETAIL_MONITOR_RANGE:
657 				break;
658 
659 			}
660 		} else { /* Detailed Timing Definition */
661 			struct detailed_pixel_timing *ptiming = &(detailed_timing->data.pixel_data);
662 			DRM_DEBUG_DRIVER("\npixel_clock:%d\n", detailed_timing->pixel_clock * 10000);
663 			DRM_DEBUG_DRIVER("hactive * vactive: %d * %d\n",
664 			(((ptiming->hactive_hblank_hi >> 4) & 0x0f) << 8)
665 			| ptiming->hactive_lo,
666 			(((ptiming->vactive_vblank_hi >> 4) & 0x0f) << 8)
667 			| ptiming->vactive_lo);
668 		}
669 	}
670 	return true;
671 }
672 
edid_parser_ParseDataBlock(u8 * data,sink_edid_t * edidExt)673 static int edid_parser_ParseDataBlock(u8 *data, sink_edid_t *edidExt)
674 {
675 	u8 c = 0;
676 	shortAudioDesc_t tmpSad;
677 	shortVideoDesc_t tmpSvd;
678 	u8 tmpYcc420All = 0;
679 	u8 tmpLimitedYcc420All = 0;
680 	u32 ieeeId = 0;
681 	u8 extendedTag = 0;
682 	int i = 0;
683 	int edid_cnt = 0;
684 	int svdNr = 0;
685 	int icnt = 0;
686 	u8 tag = edid_bit_field(data[0], 5, 3);
687 	u8 length = edid_bit_field(data[0], 0, 5);
688 
689 	tmpSvd.mLimitedToYcc420 = 0;
690 	tmpSvd.mYcc420 = 0;
691 
692 
693 	switch (tag) {
694 	case 0x1:		/* Audio Data Block */
695 		DRM_DEBUG_DRIVER("EDID: Audio datablock parsing\n");
696 		for (c = 1; c < (length + 1); c += 3) {
697 			sad_parse(&tmpSad, data + c);
698 			if (edidExt->edid_mSadIndex < (sizeof(edidExt->edid_mSad) / sizeof(shortAudioDesc_t)))
699 				edidExt->edid_mSad[edidExt->edid_mSadIndex++] = tmpSad;
700 			else
701 				DRM_ERROR("buffer full - SAD ignored\n");
702 		}
703 		break;
704 	case 0x2:		/* Video Data Block */
705 		DRM_DEBUG_DRIVER("EDID: Video datablock parsing\n");
706 		for (c = 1; c < (length + 1); c++) {
707 			svd_parse(&tmpSvd, data[c]);
708 			if (edidExt->edid_mSvdIndex < (sizeof(edidExt->edid_mSvd) / sizeof(shortVideoDesc_t)))
709 				edidExt->edid_mSvd[edidExt->edid_mSvdIndex++] = tmpSvd;
710 			else
711 				DRM_ERROR("buffer full - SVD ignored\n");
712 		}
713 		break;
714 	case 0x3:		/* Vendor Specific Data Block HDMI or HF */
715 		DRM_DEBUG_DRIVER("\nEDID: VSDB HDMI and HDMI-F\n ");
716 		ieeeId = edid_byte_to_dword(0x00, data[3], data[2], data[1]);
717 		if (ieeeId == 0x000C03) {	/* HDMI */
718 			if (hdmivsdb_parse(&edidExt->edid_mHdmivsdb, data) != true) {
719 				DRM_ERROR("Error:HDMI Vendor Specific Data Block corrupt\n");
720 				break;
721 			}
722 			DRM_DEBUG_DRIVER("EDID HDMI VSDB parsed\n");
723 		} else {
724 			if (ieeeId == 0xC45DD8) {	/* HDMI-F */
725 				DRM_DEBUG_DRIVER("Sink is HDMI 2.0 because haves HF-VSDB\n");
726 				edidExt->edid_m20Sink = true;
727 				if (hdmiforumvsdb_parse(&edidExt->edid_mHdmiForumvsdb, data) != true) {
728 					DRM_ERROR("Error:HDMI Vendor Specific Data Block corrupt\n");
729 					break;
730 				}
731 			} else {
732 				DRM_DEBUG_DRIVER("Vendor Specific Data Block not parsed ieeeId: 0x%x\n",
733 						ieeeId);
734 			}
735 		}
736 		DRM_DEBUG_DRIVER("\n");
737 		break;
738 	case 0x4:		/* Speaker Allocation Data Block */
739 		DRM_DEBUG_DRIVER("SAD block parsing\n");
740 		if (speaker_alloc_data_block_parse(&edidExt->edid_mSpeakerAllocationDataBlock, data) != true)
741 			DRM_ERROR("Error:Speaker Allocation Data Block corrupt\n");
742 		break;
743 	case 0x7:{
744 		DRM_DEBUG_DRIVER("EDID CEA Extended field 0x07\n");
745 		extendedTag = data[1];
746 		switch (extendedTag) {
747 		case 0x00:	/* Video Capability Data Block */
748 			DRM_DEBUG_DRIVER("Video Capability Data Block\n");
749 			if (video_cap_data_block_parse(&edidExt->edid_mVideoCapabilityDataBlock, data) != true)
750 				DRM_DEBUG_DRIVER("Error:Video Capability Data Block corrupt\n");
751 			break;
752 		case 0x04:	/* HDMI Video Data Block */
753 			DRM_DEBUG_DRIVER("HDMI Video Data Block\n");
754 			break;
755 		case 0x05:	/* Colorimetry Data Block */
756 			DRM_DEBUG_DRIVER("Colorimetry Data Block\n");
757 			if (colorimetry_data_block_parse(&edidExt->edid_mColorimetryDataBlock, data) != true)
758 				DRM_DEBUG_DRIVER("Error:Colorimetry Data Block corrupt\n");
759 			break;
760 		case 0x06:	/* HDR Static Metadata Data Block */
761 			DRM_DEBUG_DRIVER("HDR Static Metadata Data Block\n");
762 			if (hdr_static_metadata_block_parse(&edidExt->edid_hdr_static_metadata_data_block, data) != true)
763 				DRM_DEBUG_DRIVER("HDR Static Metadata Data Block corrupt\n");
764 			break;
765 		case 0x12:	/* HDMI Audio Data Block */
766 			DRM_DEBUG_DRIVER("HDMI Audio Data Block\n");
767 			break;
768 		case 0xe:
769 			/** If it is a YCC420 VDB then VICs can ONLY be displayed in YCC 4:2:0 */
770 			DRM_DEBUG_DRIVER("YCBCR 4:2:0 Video Data Block\n");
771 			/** If Sink has YCC Datablocks it is HDMI 2.0 */
772 			edidExt->edid_m20Sink = true;
773 			tmpLimitedYcc420All = (edid_bit_field(data[0], 0, 5) == 1 ? 1 : 0);
774 			edid_parser_updateYcc420(edidExt, tmpYcc420All, tmpLimitedYcc420All);
775 			for (i = 0; i < (edid_bit_field(data[0], 0, 5) - 1); i++) {
776 				/** Length includes the tag byte*/
777 				tmpSvd.mCode = data[2 + i];
778 				tmpSvd.mNative = 0;
779 				tmpSvd.mLimitedToYcc420 = 1;
780 				for (edid_cnt = 0; edid_cnt < edidExt->edid_mSvdIndex; edid_cnt++) {
781 					if (edidExt->edid_mSvd[edid_cnt].mCode == tmpSvd.mCode) {
782 						edidExt->edid_mSvd[edid_cnt] =	tmpSvd;
783 						goto concluded;
784 					}
785 				}
786 				if (edidExt->edid_mSvdIndex <
787 					(sizeof(edidExt->edid_mSvd) /  sizeof(shortVideoDesc_t))) {
788 					edidExt->edid_mSvd[edidExt->edid_mSvdIndex] = tmpSvd;
789 					edidExt->edid_mSvdIndex++;
790 				} else {
791 					DRM_DEBUG_DRIVER("buffer full - YCC 420 DTD ignored\n");
792 				}
793 concluded:;
794 			}
795 			break;
796 		case 0x0f:
797 			/** If it is a YCC420 CDB then VIC can ALSO be displayed in YCC 4:2:0 */
798 			edidExt->edid_m20Sink = true;
799 			DRM_DEBUG_DRIVER("YCBCR 4:2:0 Capability Map Data Block\n");
800 			/* If YCC420 CMDB is bigger than 1, then there is SVD info to parse */
801 			if (edid_bit_field(data[0], 0, 5) > 1) {
802 				for (icnt = 0; icnt < 8; icnt++) {
803 					/** Lenght includes the tag byte*/
804 					if ((edid_bit_field(data[2], 1 >> icnt, 1) & 0x01)) {
805 						svdNr = icnt;
806 						tmpSvd.mCode = edidExt->edid_mSvd[svdNr - 1].mCode;
807 						tmpSvd.mYcc420 = 1;
808 						edidExt->edid_mSvd[svdNr - 1] = tmpSvd;
809 					}
810 				}
811 				/* Otherwise, all SVDs present at the Video Data Block support YCC420*/
812 			} else {
813 				tmpYcc420All = (edid_bit_field(data[0], 0, 5) == 1 ? 1 : 0);
814 				edid_parser_updateYcc420(edidExt, tmpYcc420All, tmpLimitedYcc420All);
815 			}
816 			break;
817 		default:
818 			DRM_ERROR("Error:Extended Data Block not parsed %d\n",
819 					extendedTag);
820 			break;
821 		}
822 		break;
823 	}
824 	default:
825 		DRM_ERROR("Error:Data Block not parsed %d\n", tag);
826 		break;
827 	}
828 	return length + 1;
829 }
830 
831 
_edid_cea_extension_parser(u8 * buffer,sink_edid_t * edidExt)832 static int _edid_cea_extension_parser(u8 *buffer, sink_edid_t *edidExt)
833 {
834 	int i = 0;
835 	int c = 0;
836 	dtd_t tmpDtd;
837 	u8 offset = buffer[2];
838 
839 	if (buffer[1] < 0x03) {
840 		DRM_ERROR("Error:Invalid version for CEA Extension block,only rev 3 or higher is supported");
841 		return -1;
842 	}
843 
844 	edidExt->edid_mYcc422Support = edid_bit_field(buffer[3], 4, 1) == 1;
845 	edidExt->edid_mYcc444Support = edid_bit_field(buffer[3], 5, 1) == 1;
846 	edidExt->edid_mBasicAudioSupport = edid_bit_field(buffer[3], 6, 1) == 1;
847 	edidExt->edid_mUnderscanSupport = edid_bit_field(buffer[3], 7, 1) == 1;
848 	if (offset != 4) {
849 		for (i = 4; i < offset; i += edid_parser_ParseDataBlock(buffer + i, edidExt))
850 			;
851 	}
852 
853 	memcpy(edidExt->detailed_timings, buffer + 84, sizeof(edidExt->detailed_timings));
854 
855 	/* last is checksum */
856 	for (i = offset, c = 0; i < (sizeof(buffer) - 1) && c < 6; i += 12, c++) {
857 		if (dtd_parse(&tmpDtd, buffer + i) == true) {
858 			if (edidExt->edid_mDtdIndex < ((sizeof(edidExt->edid_mDtd) / sizeof(dtd_t)))) {
859 				edidExt->edid_mDtd[edidExt->edid_mDtdIndex++] = tmpDtd;
860 				DRM_DEBUG_DRIVER("edid_mDtd code %d\n", edidExt->edid_mDtd[edidExt->edid_mDtdIndex].mCode);
861 				DRM_DEBUG_DRIVER("edid_mDtd limited to Ycc420? %d\n", edidExt->edid_mDtd[edidExt->edid_mDtdIndex].mLimitedToYcc420);
862 				DRM_DEBUG_DRIVER("edid_mDtd supports Ycc420? %d\n", edidExt->edid_mDtd[edidExt->edid_mDtdIndex].mYcc420);
863 			} else {
864 				DRM_DEBUG_DRIVER("buffer full - DTD ignored\n");
865 			}
866 		}
867 	}
868 	return true;
869 }
870 
edid_parser(u8 * buffer,sink_edid_t * edidExt,u16 edid_size)871 static int edid_parser(u8 *buffer, sink_edid_t *edidExt,
872 							u16 edid_size)
873 {
874 	int ret = 0;
875 
876 	switch (buffer[0]) {
877 	case 0x00:
878 		ret = _edid_struture_parser((struct edid *) buffer,
879 								edidExt);
880 		break;
881 	case CEA_EXT:
882 		ret = _edid_cea_extension_parser(buffer, edidExt);
883 		break;
884 	case VTB_EXT:
885 	case DI_EXT:
886 	case LS_EXT:
887 	case MI_EXT:
888 	default:
889 		DRM_DEBUG_DRIVER("Block 0x%02x not supported\n", buffer[0]);
890 	}
891 	if (ret == true)
892 		return true;
893 
894 	return false;
895 }
896 
sunxi_edid_parse_cap(struct edid * edid,sink_edid_t * sink)897 void sunxi_edid_parse_cap(struct edid *edid, sink_edid_t *sink)
898 {
899 	memset(sink, 0, sizeof(sink_edid_t));
900 
901 	edid_parser_CeaExtReset(sink);
902 
903 	if (edid_parser((u8 *)edid, sink, 128) == false) {
904 		DRM_ERROR("Error:Could not parse EDID\n");
905 		return;
906 	}
907 
908 
909 	if (edid->extensions) {
910 		int edid_ext_cnt = 1;
911 
912 		while (edid_ext_cnt <= edid->extensions) {
913 			DRM_DEBUG_DRIVER("EDID Extension %d\n", edid_ext_cnt);
914 			if (edid_ext_cnt < 2) {
915 				if (edid_parser((u8 *)&edid[edid_ext_cnt], sink, 128) == false)
916 					DRM_ERROR("Could not parse EDID EXTENSIONS:%d\n", edid_ext_cnt);
917 			}
918 
919 			edid_ext_cnt++;
920 		}
921 	}
922 }
923 
sunixi_hdmi_edid_is_zero(const u8 * in_edid,int length)924 static bool sunixi_hdmi_edid_is_zero(const u8 *in_edid, int length)
925 {
926 	if (memchr_inv(in_edid, 0, length))
927 		return false;
928 
929 	return true;
930 }
931 
sunxi_drm_do_get_edid(struct drm_connector * connector)932 struct edid *sunxi_drm_do_get_edid(struct drm_connector *connector)
933 {
934 	int i, j = 0, valid_extensions = 0;
935 	u8 *block, *new;
936 	struct sunxi_drm_connector *sunxi_con = to_sunxi_connector(connector);
937 	struct sunxi_hdmi_funcs *hdmi_funcs = sunxi_con->hw_funcs;
938 	bool print_bad_edid = !connector->bad_edid_counter || (drm_debug & DRM_UT_KMS);
939 
940 	block = kmalloc(EDID_LENGTH, GFP_KERNEL | __GFP_ZERO);
941 	if (block == NULL)
942 		return NULL;
943 	//block =  sunxi_edid;
944 
945 	/* base block fetch, try maximun 4 times agin */
946 	for (i = 0; i < 4; i++) {
947 		if (hdmi_funcs->get_edid_block(NULL, block, 0, EDID_LENGTH)) {
948 			DRM_ERROR("get_edid_block:0 failed\n");
949 			goto out;
950 		}
951 
952 		if (drm_edid_block_valid(block, 0, print_bad_edid,
953 					 &connector->edid_corrupt))
954 			break;
955 
956 		DRM_ERROR("drm_edid_block0 is INVALID!!!\n");
957 
958 		if (i == 0 && sunixi_hdmi_edid_is_zero(block, EDID_LENGTH)) {
959 			connector->null_edid_counter++;
960 			goto carp;
961 		}
962 	}
963 
964 	if (i == 4) {
965 		DRM_ERROR("read EDID Failed!!!\n");
966 		goto carp;
967 	}
968 
969 	/* if there's no extensions, we're done */
970 	if (block[0x7e] == 0) {
971 		DRM_DEBUG_DRIVER("WARN: Sink's EDID has NO extension block");
972 		return (struct edid *)block;
973 	}
974 	DRM_DEBUG_DRIVER("EDID EXT BLOCK NUM:%d\n", block[0x7e]);
975 
976 	new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH,
977 				GFP_KERNEL | __GFP_ZERO);
978 	if (!new)
979 		goto out;
980 	block = new;
981 
982 	for (j = 1; j <= block[0x7e]; j++) {
983 		for (i = 0; i < 4; i++) {
984 			if (hdmi_funcs->get_edid_block(NULL,
985 				  block + (valid_extensions + 1) * EDID_LENGTH,
986 				  j, EDID_LENGTH))
987 				goto out;
988 			if (drm_edid_block_valid(block + (valid_extensions + 1)
989 						 * EDID_LENGTH, j,
990 						 print_bad_edid,
991 						 NULL)) {
992 				valid_extensions++;
993 				break;
994 			}
995 		}
996 
997 		if (i == 4 && print_bad_edid) {
998 			dev_warn(connector->dev->dev,
999 			 "%s: Ignoring invalid EDID block %d.\n",
1000 			 connector->name, j);
1001 
1002 			connector->bad_edid_counter++;
1003 		}
1004 	}
1005 
1006 	if (valid_extensions != block[0x7e]) {
1007 		block[EDID_LENGTH-1] += block[0x7e] - valid_extensions;
1008 		block[0x7e] = valid_extensions;
1009 		new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL);
1010 		if (!new)
1011 			goto out;
1012 		block = new;
1013 	}
1014 
1015 	return (struct edid *)block;
1016 
1017 carp:
1018 	if (print_bad_edid) {
1019 		dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
1020 			 connector->name, j);
1021 	}
1022 	connector->bad_edid_counter++;
1023 
1024 out:
1025 	kfree(block);
1026 	return NULL;
1027 }
1028 
sunxi_drm_hdmi_edid_get_modes(struct drm_connector * connector,sink_edid_t * sink)1029 int sunxi_drm_hdmi_edid_get_modes(
1030 	struct drm_connector *connector, sink_edid_t *sink)
1031 {
1032 	int ret = 0;
1033 	struct edid *edid = NULL;
1034 
1035 	/*read edid*/
1036 	edid = sunxi_drm_do_get_edid(connector);
1037 	if (edid) {
1038 		/*parse or check edid*/
1039 		drm_get_displayid(connector, edid);
1040 		drm_connector_update_edid_property(connector, edid);
1041 		ret = drm_add_edid_modes(connector, edid);
1042 		//drm_edid_to_eld(connector, edid);
1043 
1044 		sunxi_edid_parse_cap(edid, sink);
1045 	}
1046 
1047 	kfree(edid);
1048 
1049 	return ret;
1050 }
1051