aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2011-08-31 04:12:40 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2011-09-30 09:16:46 -0400
commit937fce138ff295df6f3bbb3b07464e3902b6bc0f (patch)
tree21bce8b3607a0b8abb55f7b9f95de815f449a023 /drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
parent032b8ea508dd0c641785f338b87c342337419ed6 (diff)
OMAP: DSS2: HDMI: clean up edid reading & fix checksum
Clean up reading of EDID by passing direct address to the block being read, instead of start address of the whole EDID memory area. Rewrite the loop which reads the EDID. This also fixes the checksum calculation, which used to calculate the checksum only for the first block. Cc: Mythri P K <mythripk@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c')
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c67
1 files changed, 34 insertions, 33 deletions
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index ecf854e2596c..e9885dcc4122 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -310,8 +310,8 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
310 u8 *pedid, int ext) 310 u8 *pedid, int ext)
311{ 311{
312 void __iomem *base = hdmi_core_sys_base(ip_data); 312 void __iomem *base = hdmi_core_sys_base(ip_data);
313 u32 i, j; 313 u32 i;
314 char checksum = 0; 314 char checksum;
315 u32 offset = 0; 315 u32 offset = 0;
316 316
317 /* HDMI_CORE_DDC_STATUS_IN_PROG */ 317 /* HDMI_CORE_DDC_STATUS_IN_PROG */
@@ -354,21 +354,31 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
354 return -EIO; 354 return -EIO;
355 } 355 }
356 356
357 i = ext * 128; 357 for (i = 0; i < 0x80; ++i) {
358 j = 0; 358 int t;
359 while (((REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
360 (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
361 j < 128) {
362 359
363 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0) { 360 /* IN_PROG */
364 /* FIFO not empty */ 361 if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) {
365 pedid[i++] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0); 362 DSSERR("operation stopped when reading edid\n");
366 j++; 363 return -EIO;
364 }
365
366 t = 0;
367 /* FIFO_EMPTY */
368 while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) {
369 if (t++ > 10000) {
370 DSSERR("timeout reading edid\n");
371 return -ETIMEDOUT;
372 }
373 udelay(1);
367 } 374 }
375
376 pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
368 } 377 }
369 378
370 for (j = 0; j < 128; j++) 379 checksum = 0;
371 checksum += pedid[j]; 380 for (i = 0; i < 0x80; ++i)
381 checksum += pedid[i];
372 382
373 if (checksum != 0) { 383 if (checksum != 0) {
374 pr_err("E-EDID checksum failed!!\n"); 384 pr_err("E-EDID checksum failed!!\n");
@@ -379,40 +389,31 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
379} 389}
380 390
381int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, 391int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
382 u8 *pedid, u16 max_length) 392 u8 *edid, int len)
383{ 393{
384 int r = 0, n = 0, i = 0; 394 int r, l;
385 int max_ext_blocks = (max_length / 128) - 1; 395
386 int len; 396 if (len < 128)
397 return -EINVAL;
387 398
388 r = hdmi_core_ddc_init(ip_data); 399 r = hdmi_core_ddc_init(ip_data);
389 if (r) 400 if (r)
390 return r; 401 return r;
391 402
392 r = hdmi_core_ddc_edid(ip_data, pedid, 0); 403 r = hdmi_core_ddc_edid(ip_data, edid, 0);
393 if (r) 404 if (r)
394 return r; 405 return r;
395 406
396 len = 128; 407 l = 128;
397 n = pedid[0x7e];
398
399 /*
400 * README: need to comply with max_length set by the caller.
401 * Better implementation should be to allocate necessary
402 * memory to store EDID according to nb_block field found
403 * in first block
404 */
405 if (n > max_ext_blocks)
406 n = max_ext_blocks;
407 408
408 for (i = 1; i <= n; i++) { 409 if (len >= 128 * 2 && edid[0x7e] > 0) {
409 r = hdmi_core_ddc_edid(ip_data, pedid, i); 410 r = hdmi_core_ddc_edid(ip_data, edid + 0x80, 1);
410 if (r) 411 if (r)
411 return r; 412 return r;
412 len += 128; 413 l += 128;
413 } 414 }
414 415
415 return len; 416 return l;
416} 417}
417 418
418static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, 419static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,