From patchwork Tue Dec 20 01:33:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 9480955 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 28FDC607FF for ; Tue, 20 Dec 2016 01:33:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1AA4926AE3 for ; Tue, 20 Dec 2016 01:33:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0F5B52835E; Tue, 20 Dec 2016 01:33:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A73B726AE3 for ; Tue, 20 Dec 2016 01:33:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754628AbcLTBdr (ORCPT ); Mon, 19 Dec 2016 20:33:47 -0500 Received: from galahad.ideasonboard.com ([185.26.127.97]:41472 "EHLO galahad.ideasonboard.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754596AbcLTBdq (ORCPT ); Mon, 19 Dec 2016 20:33:46 -0500 Received: from avalon.bb.dnainternet.fi (dfj612ybrt5fhg77mgycy-3.rev.dnainternet.fi [IPv6:2001:14ba:21f5:5b00:2e86:4862:ef6a:2804]) by galahad.ideasonboard.com (Postfix) with ESMTPSA id 9B7DB20BCA; Tue, 20 Dec 2016 02:33:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1482197609; bh=jL/8u8xj/q/8NQQdbI8IXoBbwE1JfGREsvr8lxqRTlY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=H8NjMDe74mCHGEG2VTGGQvMA7SLcT3dy5ffXmrjnQBPRiUmoLvvkdsYIXZ96NqHqO G9z0IS8zq1AK2eA6qE3DLWqiIls3TvbcvSFDXAMWEMV7EQG5ClbsW9H2Zaucj1mlYk lzOW2Q3VO02/Rb+nYvw5vryF2pBvtIAcyCVSRrdo= From: Laurent Pinchart To: dri-devel@lists.freedesktop.org Cc: Andy Yan , Fabio Estevam , Jose Abreu , Kieran Bingham , Russell King , Ulrich Hecht , Vladimir Zapolskiy , linux-renesas-soc@vger.kernel.org Subject: [PATCH v2 15/29] drm: bridge: dw-hdmi: Handle overflow workaround based on device version Date: Tue, 20 Dec 2016 03:33:46 +0200 Message-Id: <20161220013400.28317-16-laurent.pinchart+renesas@ideasonboard.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161220013400.28317-1-laurent.pinchart+renesas@ideasonboard.com> References: <20161220013400.28317-1-laurent.pinchart+renesas@ideasonboard.com> Sender: linux-renesas-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-renesas-soc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Use the device version queried at runtime instead of the device type provided through platform data to handle the overflow workaround. This will make support of other SoCs integrating the same HDMI TX controller version easier. Among the supported platforms only i.MX6DL and i.MX6Q have been identified as needing the workaround. Disabling it on Rockchip RK3288 (which integrates a v2.00a controller) didn't produce any error or artifact. Signed-off-by: Laurent Pinchart Reviewed-by: Jose Abreu --- drivers/gpu/drm/bridge/dw-hdmi.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw-hdmi.c b/drivers/gpu/drm/bridge/dw-hdmi.c index 730a7558d4d4..f4faa14213e5 100644 --- a/drivers/gpu/drm/bridge/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/dw-hdmi.c @@ -117,8 +117,10 @@ struct dw_hdmi { struct drm_connector connector; struct drm_bridge bridge; - struct platform_device *audio; enum dw_hdmi_devtype dev_type; + unsigned int version; + + struct platform_device *audio; struct device *dev; struct clk *isfr_clk; struct clk *iahb_clk; @@ -1323,19 +1325,38 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi) /* Workaround to clear the overflow condition */ static void dw_hdmi_clear_overflow(struct dw_hdmi *hdmi) { - int count; + unsigned int count; + unsigned int i; u8 val; - /* TMDS software reset */ - hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); + /* + * Under some circumstances the Frame Composer arithmetic unit can miss + * an FC register write due to being busy processing the previous one. + * The issue can be worked around by issuing a TMDS software reset and + * then write one of the FC registers several times. + * + * The number of iterations matters and depends on the HDMI TX revision + * (and possibly on the platform). So far only i.MX6Q (v1.30a) and + * i.MX6DL (v1.31a) have been identified as needing the workaround, with + * 4 and 1 iterations respectively. + */ - val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); - if (hdmi->dev_type == IMX6DL_HDMI) { - hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); + switch (hdmi->version) { + case 0x130a: + count = 4; + break; + case 0x131a: + count = 1; + break; + default: return; } - for (count = 0; count < 4; count++) + /* TMDS software reset */ + hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, HDMI_MC_SWRSTZ); + + val = hdmi_readb(hdmi, HDMI_FC_INVIDCONF); + for (i = 0; i < count; i++) hdmi_writeb(hdmi, val, HDMI_FC_INVIDCONF); } @@ -1832,7 +1853,6 @@ __dw_hdmi_probe(struct platform_device *pdev, int irq; int ret; u32 val = 1; - u16 version; u8 prod_id0; u8 prod_id1; u8 config0; @@ -1917,21 +1937,21 @@ __dw_hdmi_probe(struct platform_device *pdev, } /* Product and revision IDs */ - version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) - | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); + hdmi->version = (hdmi_readb(hdmi, HDMI_DESIGN_ID) << 8) + | (hdmi_readb(hdmi, HDMI_REVISION_ID) << 0); prod_id0 = hdmi_readb(hdmi, HDMI_PRODUCT_ID0); prod_id1 = hdmi_readb(hdmi, HDMI_PRODUCT_ID1); if (prod_id0 != HDMI_PRODUCT_ID0_HDMI_TX || (prod_id1 & ~HDMI_PRODUCT_ID1_HDCP) != HDMI_PRODUCT_ID1_HDMI_TX) { dev_err(dev, "Unsupported HDMI controller (%04x:%02x:%02x)\n", - version, prod_id0, prod_id1); + hdmi->version, prod_id0, prod_id1); ret = -ENODEV; goto err_iahb; } dev_info(dev, "Detected HDMI TX controller v%x.%03x %s HDCP\n", - version >> 12, version & 0xfff, + hdmi->version >> 12, hdmi->version & 0xfff, prod_id1 & HDMI_PRODUCT_ID1_HDCP ? "with" : "without"); initialize_hdmi_ih_mutes(hdmi);