OMAP: DSS2: HDMI: split hdmi_core_ddc_edid
authorTomi Valkeinen <tomi.valkeinen@ti.com>
Mon, 22 Aug 2011 14:47:56 +0000 (17:47 +0300)
committerTomi Valkeinen <tomi.valkeinen@ti.com>
Fri, 30 Sep 2011 13:16:46 +0000 (16:16 +0300)
Split the DDC initialization off from hdmi_core_ddc_edid() into a
separate function hdmi_core_ddc_init(). This cleans up the
implementation.

Cc: Mythri P K <mythripk@ti.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c

index d4cdfc2..ecf854e 100644 (file)
@@ -264,92 +264,105 @@ void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
        hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
 }
 
-static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,
-                                               u8 *pedid, int ext)
+static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)
 {
-       u32 i, j;
-       char checksum = 0;
-       u32 offset = 0;
-       void __iomem *core_sys_base = hdmi_core_sys_base(ip_data);
+       void __iomem *base = hdmi_core_sys_base(ip_data);
 
        /* Turn on CLK for DDC */
-       REG_FLD_MOD(hdmi_av_base(ip_data), HDMI_CORE_AV_DPD, 0x7, 2, 0);
+       REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0);
+
+       /* IN_PROG */
+       if (REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) {
+               /* Abort transaction */
+               REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xf, 3, 0);
+               /* IN_PROG */
+               if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+                                       4, 4, 0) != 0) {
+                       DSSERR("Timeout aborting DDC transaction\n");
+                       return -ETIMEDOUT;
+               }
+       }
 
-       /*
-        * SW HACK : Without the Delay DDC(i2c bus) reads 0 values /
-        * right shifted values( The behavior is not consistent and seen only
-        * with some TV's)
-        */
-       usleep_range(800, 1000);
+       /* Clk SCL Devices */
+       REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+
+       /* HDMI_CORE_DDC_STATUS_IN_PROG */
+       if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+                               4, 4, 0) != 0) {
+               DSSERR("Timeout starting SCL clock\n");
+               return -ETIMEDOUT;
+       }
 
-       if (!ext) {
-               /* Clk SCL Devices */
-               REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0xA, 3, 0);
+       /* Clear FIFO */
+       REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
 
-               /* HDMI_CORE_DDC_STATUS_IN_PROG */
-               if (hdmi_wait_for_bit_change(core_sys_base,
-                                       HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
-                       pr_err("Failed to program DDC\n");
-                       return -ETIMEDOUT;
-               }
+       /* HDMI_CORE_DDC_STATUS_IN_PROG */
+       if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+                               4, 4, 0) != 0) {
+               DSSERR("Timeout clearing DDC fifo\n");
+               return -ETIMEDOUT;
+       }
 
-               /* Clear FIFO */
-               REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x9, 3, 0);
+       return 0;
+}
 
-               /* HDMI_CORE_DDC_STATUS_IN_PROG */
-               if (hdmi_wait_for_bit_change(core_sys_base,
-                                       HDMI_CORE_DDC_STATUS, 4, 4, 0) != 0) {
-                       pr_err("Failed to program DDC\n");
-                       return -ETIMEDOUT;
-               }
+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 offset = 0;
 
-       } else {
-               if (ext % 2 != 0)
-                       offset = 0x80;
+       /* HDMI_CORE_DDC_STATUS_IN_PROG */
+       if (hdmi_wait_for_bit_change(base, HDMI_CORE_DDC_STATUS,
+                               4, 4, 0) != 0) {
+               DSSERR("Timeout waiting DDC to be ready\n");
+               return -ETIMEDOUT;
        }
 
+       if (ext % 2 != 0)
+               offset = 0x80;
+
        /* Load Segment Address Register */
-       REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_SEGM, ext/2, 7, 0);
+       REG_FLD_MOD(base, HDMI_CORE_DDC_SEGM, ext / 2, 7, 0);
 
        /* Load Slave Address Register */
-       REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
+       REG_FLD_MOD(base, HDMI_CORE_DDC_ADDR, 0xA0 >> 1, 7, 1);
 
        /* Load Offset Address Register */
-       REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
+       REG_FLD_MOD(base, HDMI_CORE_DDC_OFFSET, offset, 7, 0);
 
        /* Load Byte Count */
-       REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
-       REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
+       REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT1, 0x80, 7, 0);
+       REG_FLD_MOD(base, HDMI_CORE_DDC_COUNT2, 0x0, 1, 0);
 
        /* Set DDC_CMD */
        if (ext)
-               REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
+               REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x4, 3, 0);
        else
-               REG_FLD_MOD(core_sys_base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
+               REG_FLD_MOD(base, HDMI_CORE_DDC_CMD, 0x2, 3, 0);
 
        /* HDMI_CORE_DDC_STATUS_BUS_LOW */
-       if (REG_GET(core_sys_base,
-                                       HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
+       if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) {
                pr_err("I2C Bus Low?\n");
                return -EIO;
        }
        /* HDMI_CORE_DDC_STATUS_NO_ACK */
-       if (REG_GET(core_sys_base,
-                                       HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
+       if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) {
                pr_err("I2C No Ack\n");
                return -EIO;
        }
 
        i = ext * 128;
        j = 0;
-       while (((REG_GET(core_sys_base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
-                       (REG_GET(core_sys_base,
-                       HDMI_CORE_DDC_STATUS, 2, 2) == 0)) && j < 128) {
+       while (((REG_GET(base, HDMI_CORE_DDC_STATUS, 4, 4) == 1) ||
+               (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0)) &&
+                       j < 128) {
 
-               if (REG_GET(core_sys_base, HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
+               if (REG_GET(base, HDMI_CORE_DDC_STATUS, 2, 2) == 0) {
                        /* FIFO not empty */
-                       pedid[i++] = REG_GET(core_sys_base,
-                                               HDMI_CORE_DDC_DATA, 7, 0);
+                       pedid[i++] = REG_GET(base, HDMI_CORE_DDC_DATA, 7, 0);
                        j++;
                }
        }
@@ -372,6 +385,10 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
        int max_ext_blocks = (max_length / 128) - 1;
        int len;
 
+       r = hdmi_core_ddc_init(ip_data);
+       if (r)
+               return r;
+
        r = hdmi_core_ddc_edid(ip_data, pedid, 0);
        if (r)
                return r;