From patchwork Wed Aug 31 13:23:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 1116022 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p7VDMMJ4022786 for ; Wed, 31 Aug 2011 13:23:55 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755805Ab1HaNXv (ORCPT ); Wed, 31 Aug 2011 09:23:51 -0400 Received: from na3sys009aog124.obsmtp.com ([74.125.149.151]:38267 "EHLO na3sys009aog124.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755753Ab1HaNXs (ORCPT ); Wed, 31 Aug 2011 09:23:48 -0400 Received: from mail-wy0-f181.google.com ([74.125.82.181]) (using TLSv1) by na3sys009aob124.postini.com ([74.125.148.12]) with SMTP ID DSNKTl414hYpNC+QLg/na89QX7eXvqobF+G5@postini.com; Wed, 31 Aug 2011 06:23:48 PDT Received: by mail-wy0-f181.google.com with SMTP id 36so541350wyg.12 for ; Wed, 31 Aug 2011 06:23:46 -0700 (PDT) Received: by 10.216.134.33 with SMTP id r33mr394471wei.62.1314797026085; Wed, 31 Aug 2011 06:23:46 -0700 (PDT) Received: from localhost.localdomain (a62-248-128-208.elisa-laajakaista.fi [62.248.128.208]) by mx.google.com with ESMTPS id fm9sm5476855wbb.27.2011.08.31.06.23.43 (version=SSLv3 cipher=OTHER); Wed, 31 Aug 2011 06:23:45 -0700 (PDT) From: Tomi Valkeinen To: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org Cc: archit@ti.com, mythripk@ti.com, Tomi Valkeinen Subject: [PATCH 07/12] OMAP: DSS2: HDMI: clean up edid reading & fix checksum Date: Wed, 31 Aug 2011 16:23:18 +0300 Message-Id: <1314797003-17638-8-git-send-email-tomi.valkeinen@ti.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1314797003-17638-1-git-send-email-tomi.valkeinen@ti.com> References: <1314797003-17638-1-git-send-email-tomi.valkeinen@ti.com> Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 31 Aug 2011 13:23:55 +0000 (UTC) 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. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 67 ++++++++++++++++++++------------------- 1 files changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 04ce105..34e05ee 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -414,8 +414,8 @@ static int hdmi_core_ddc_init(void) static int hdmi_core_ddc_edid(u8 *pedid, int ext) { - u32 i, j; - char checksum = 0; + u32 i; + char checksum; u32 offset = 0; /* HDMI_CORE_DDC_STATUS_IN_PROG */ @@ -457,21 +457,31 @@ static int hdmi_core_ddc_edid(u8 *pedid, int ext) return -EIO; } - i = ext * 128; - j = 0; - while (((REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 1) || - (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0)) && - j < 128) { + for (i = 0; i < 0x80; ++i) { + int t; - if (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 0) { - /* FIFO not empty */ - pedid[i++] = REG_GET(HDMI_CORE_DDC_DATA, 7, 0); - j++; + /* IN_PROG */ + if (REG_GET(HDMI_CORE_DDC_STATUS, 4, 4) == 0) { + DSSERR("operation stopped when reading edid\n"); + return -EIO; + } + + t = 0; + /* FIFO_EMPTY */ + while (REG_GET(HDMI_CORE_DDC_STATUS, 2, 2) == 1) { + if (t++ > 10000) { + DSSERR("timeout reading edid\n"); + return -ETIMEDOUT; + } + udelay(1); } + + pedid[i] = REG_GET(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) { DSSERR("E-EDID checksum failed!!\n"); @@ -481,40 +491,31 @@ static int hdmi_core_ddc_edid(u8 *pedid, int ext) return 0; } -static int read_edid(u8 *pedid, u16 max_length) +static int read_edid(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(); if (r) return r; - r = hdmi_core_ddc_edid(pedid, 0); + r = hdmi_core_ddc_edid(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(pedid, i); + if (len >= 128 * 2 && edid[0x7e] > 0) { + r = hdmi_core_ddc_edid(edid + 0x80, 1); if (r) return r; - len += 128; + l += 128; } - return len; + return l; } static int get_timings_index(void)