summaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
diff options
context:
space:
mode:
authorTomi Valkeinen2011-08-31 10:12:40 +0200
committerTomi Valkeinen2011-09-30 15:16:46 +0200
commit937fce138ff295df6f3bbb3b07464e3902b6bc0f (patch)
tree21bce8b3607a0b8abb55f7b9f95de815f449a023 /drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
parentOMAP: DSS2: HDMI: split hdmi_core_ddc_edid (diff)
downloadkernel-qcow2-linux-937fce138ff295df6f3bbb3b07464e3902b6bc0f.tar.gz
kernel-qcow2-linux-937fce138ff295df6f3bbb3b07464e3902b6bc0f.tar.xz
kernel-qcow2-linux-937fce138ff295df6f3bbb3b07464e3902b6bc0f.zip
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,
u8 *pedid, int ext)
{
void __iomem *base = hdmi_core_sys_base(ip_data);
- u32 i, j;
- char checksum = 0;
+ u32 i;
+ char checksum;
u32 offset = 0;
/* HDMI_CORE_DDC_STATUS_IN_PROG */
@@ -354,21 +354,31 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
return -EIO;
}
- i = ext * 128;
- j = 0;
- while (((REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
- (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
- j < 128) {
+ for (i = 0; i < 0x80; ++i) {
+ int t;
- if (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
- /* FIFO not empty */
- pedid[i++] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
- j++;
+ /* IN_PROG */
+ if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 0) {
+ DSSERR("operation stopped when reading edid\n");
+ return -EIO;
+ }
+
+ t = 0;
+ /* FIFO_EMPTY */
+ while (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 1) {
+ if (t++ > 10000) {
+ DSSERR("timeout reading edid\n");
+ return -ETIMEDOUT;
+ }
+ udelay(1);
}
+
+ pedid[i] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
}
- for (j = 0; j < 128; j++)
- checksum += pedid[j];
+ checksum = 0;
+ for (i = 0; i < 0x80; ++i)
+ checksum += pedid[i];
if (checksum != 0) {
pr_err("E-EDID checksum failed!!\n");
@@ -379,40 +389,31 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
}
int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
- u8 *pedid, u16 max_length)
+ u8 *edid, int len)
{
- int r = 0, n = 0, i = 0;
- int max_ext_blocks = (max_length / 128) - 1;
- int len;
+ int r, l;
+
+ if (len < 128)
+ return -EINVAL;
r = hdmi_core_ddc_init(ip_data);
if (r)
return r;
- r = hdmi_core_ddc_edid(ip_data, pedid, 0);
+ r = hdmi_core_ddc_edid(ip_data, edid, 0);
if (r)
return r;
- len = 128;
- n = pedid[0x7e];
-
- /*
- * README: need to comply with max_length set by the caller.
- * Better implementation should be to allocate necessary
- * memory to store EDID according to nb_block field found
- * in first block
- */
- if (n > max_ext_blocks)
- n = max_ext_blocks;
+ l = 128;
- for (i = 1; i <= n; i++) {
- r = hdmi_core_ddc_edid(ip_data, pedid, i);
+ if (len >= 128 * 2 && edid[0x7e] > 0) {
+ r = hdmi_core_ddc_edid(ip_data, edid + 0x80, 1);
if (r)
return r;
- len += 128;
+ l += 128;
}
- return len;
+ return l;
}
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,