From patchwork Thu Feb 26 12:49:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomi Valkeinen X-Patchwork-Id: 5891931 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 04FBABF440 for ; Thu, 26 Feb 2015 12:50:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id F27F420395 for ; Thu, 26 Feb 2015 12:50:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 50EF42039E for ; Thu, 26 Feb 2015 12:50:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752983AbbBZMtw (ORCPT ); Thu, 26 Feb 2015 07:49:52 -0500 Received: from bear.ext.ti.com ([192.94.94.41]:49925 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932243AbbBZMtv (ORCPT ); Thu, 26 Feb 2015 07:49:51 -0500 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id t1QCnoSZ027259; Thu, 26 Feb 2015 06:49:50 -0600 Received: from DLEE70.ent.ti.com (dlee70.ent.ti.com [157.170.170.113]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id t1QCnnPg016733; Thu, 26 Feb 2015 06:49:49 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.3.224.2; Thu, 26 Feb 2015 06:49:49 -0600 Received: from deskari.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id t1QCnUhV030427; Thu, 26 Feb 2015 06:49:48 -0600 From: Tomi Valkeinen To: , CC: Tomi Valkeinen Subject: [PATCH 14/15] OMAPDSS: HDMI: hdmi synclost work-around Date: Thu, 26 Feb 2015 14:49:08 +0200 Message-ID: <1424954949-12801-14-git-send-email-tomi.valkeinen@ti.com> X-Mailer: git-send-email 2.3.0 In-Reply-To: <1424954949-12801-1-git-send-email-tomi.valkeinen@ti.com> References: <1424954949-12801-1-git-send-email-tomi.valkeinen@ti.com> MIME-Version: 1.0 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP DISPC and HDMI have synchronization issues when enabling or disabling the output. The symptoms are a lot of sync-lost errors and occasionally dispc gets "stuck" and we never get FRAMEDONE when disabling. Testing has shown that this is somehow related to the time when DISPC's output gets enabled: - If DISPC is disabled when HDMI is in vertical blanking area, DISPC often gets stuck. - If DISPC is disabled after vertical blanking area, no sync lost errors are seen. - If DISPC is enabled right after HDMI VSYNC event, no sync lost errors are seen. This patch is a simple work-around for the above issues: - Before enabling DISPC output, we wait for HDMI VSYNC. - Before disabling DISPC output, we wait for HDMI VSYNC and VSW+VBP. This is not perfect WA, as it relies on the enable/disable of DISPC happening relatively soon after the wait has ended. In practice I presume there is at least ~10ms timewindow to accomplish the DISPC enable/disable, which I hope is enough. Signed-off-by: Tomi Valkeinen --- drivers/video/fbdev/omap2/dss/hdmi4.c | 50 +++++++++++++++++++++++++++++++++++ drivers/video/fbdev/omap2/dss/hdmi5.c | 50 +++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 916d47978f41..39cdd164d2ae 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -217,6 +217,26 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) if (r) goto err_vid_enable; + /* + * XXX Seems that on we easily get a flood of sync-lost errors when + * enabling the output. This seems to be related to the time between + * HDMI VSYNC and enabling the DISPC output. + * + * Testing shows that the sync-lost errors do not happen if we enable + * the DISPC output very soon after HDMI VBLANK. So wait here for + * VBLANK to reduce the chances of sync-losts. + */ + hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC); + + while (true) { + u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW); + + if (v & HDMI_IRQ_VIDEO_VSYNC) + break; + + usleep_range(500, 1000); + } + r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; @@ -242,9 +262,39 @@ err_pll_enable: static void hdmi_power_off_full(struct omap_dss_device *dssdev) { struct omap_overlay_manager *mgr = hdmi.output.manager; + const struct omap_video_timings *t; + unsigned vblank; hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); + /* + * XXX Seems that on we easily get a flood of sync-lost errors when + * disabling the output, and sometimes the DISPC seems to get stuck and + * we never get FRAMEDONE. This seems to happen if we disable DISPC + * output during HDMI VBLANK. + * + * To reduce the possibility for sync-lost errors, calculate the time + * for the vertical blanking, wait for VBLANK, then wait until VBLANK + * ends. + */ + t = &hdmi.cfg.timings; + vblank = t->hfp + t->hsw + t->hbp + t->x_res; + vblank *= t->vsw + t->vbp; + vblank = (vblank * 1000) / (t->pixelclock / 1000); + + hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC); + + while (true) { + u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW); + + if (v & HDMI_IRQ_VIDEO_VSYNC) + break; + + usleep_range(500, 1000); + } + + usleep_range(vblank, vblank + 1000); + dss_mgr_disable(mgr); hdmi_wp_video_stop(&hdmi.wp); diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index 3f0b34a7031a..65a91ac87a6a 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -234,6 +234,26 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) if (r) goto err_vid_enable; + /* + * XXX Seems that on we easily get a flood of sync-lost errors when + * enabling the output. This seems to be related to the time between + * HDMI VSYNC and enabling the DISPC output. + * + * Testing shows that the sync-lost errors do not happen if we enable + * the DISPC output very soon after HDMI VBLANK. So wait here for + * VBLANK to reduce the chances of sync-losts. + */ + hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC); + + while (true) { + u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW); + + if (v & HDMI_IRQ_VIDEO_VSYNC) + break; + + usleep_range(500, 1000); + } + r = dss_mgr_enable(mgr); if (r) goto err_mgr_enable; @@ -259,9 +279,39 @@ err_pll_enable: static void hdmi_power_off_full(struct omap_dss_device *dssdev) { struct omap_overlay_manager *mgr = hdmi.output.manager; + const struct omap_video_timings *t; + unsigned vblank; hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); + /* + * XXX Seems that on we easily get a flood of sync-lost errors when + * disabling the output, and sometimes the DISPC seems to get stuck and + * we never get FRAMEDONE. This seems to happen if we disable DISPC + * output during HDMI VBLANK. + * + * To reduce the possibility for sync-lost errors, calculate the time + * for the vertical blanking, wait for VBLANK, then wait until VBLANK + * ends. + */ + t = &hdmi.cfg.timings; + vblank = t->hfp + t->hsw + t->hbp + t->x_res; + vblank *= t->vsw + t->vbp; + vblank = (vblank * 1000) / (t->pixelclock / 1000); + + hdmi_write_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_VSYNC); + + while (true) { + u32 v = hdmi_read_reg(hdmi.wp.base, HDMI_WP_IRQSTATUS_RAW); + + if (v & HDMI_IRQ_VIDEO_VSYNC) + break; + + usleep_range(500, 1000); + } + + usleep_range(vblank, vblank + 1000); + dss_mgr_disable(mgr); hdmi_wp_video_stop(&hdmi.wp);