aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h6
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c67
2 files changed, 36 insertions, 37 deletions
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index acf102267700..390cd85b122f 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -92,8 +92,7 @@ struct ti_hdmi_ip_ops {
92 92
93 void (*phy_disable)(struct hdmi_ip_data *ip_data); 93 void (*phy_disable)(struct hdmi_ip_data *ip_data);
94 94
95 int (*read_edid)(struct hdmi_ip_data *ip_data, 95 int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
96 u8 *pedid, u16 max_length);
97 96
98 int (*pll_enable)(struct hdmi_ip_data *ip_data); 97 int (*pll_enable)(struct hdmi_ip_data *ip_data);
99 98
@@ -114,8 +113,7 @@ struct hdmi_ip_data {
114}; 113};
115int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); 114int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
116void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 115void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
117int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, 116int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
118 u8 *pedid, u16 max_length);
119void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start); 117void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
120int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); 118int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
121void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); 119void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data);
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,