void (*phy_disable)(struct hdmi_ip_data *ip_data);
- int (*read_edid)(struct hdmi_ip_data *ip_data,
- u8 *pedid, u16 max_length);
+ int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
int (*pll_enable)(struct hdmi_ip_data *ip_data);
};
int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
-int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
- u8 *pedid, u16 max_length);
+int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start);
int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_pll_disable(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 */
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");
}
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,