From patchwork Fri Jun 16 05:09:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 9790553 X-Patchwork-Delegate: agross@codeaurora.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 2831B60231 for ; Fri, 16 Jun 2017 05:09:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2076B285B3 for ; Fri, 16 Jun 2017 05:09:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 154732863B; Fri, 16 Jun 2017 05:09:55 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID 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 A3B2D285B3 for ; Fri, 16 Jun 2017 05:09:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751144AbdFPFJy (ORCPT ); Fri, 16 Jun 2017 01:09:54 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:50500 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750947AbdFPFJx (ORCPT ); Fri, 16 Jun 2017 01:09:53 -0400 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id C212260350; Fri, 16 Jun 2017 05:09:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1497589792; bh=G87zTjF5Z23P7DDlbDSWHIc2ta7WXQ9bKo/VGIfVb6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mKxkH3e1s6CdIfdms5BbYp9gWn+f/iaxcEvDqA80cs3YKVv8fFd2EVry8kBk8ntyt 1SKe123jm/vHk6lsL/kbRn8/ovjj7ObABJwyEfebB67ZFbkOCNOGiA1fXkU/R3lBGt yiRCfI+VRiPe55r7XJjotWZvK1A0hiMNyJ9qtBwA= Received: from localhost (blr-bdr-fw-01_globalnat_allzones-outside.qualcomm.com [103.229.18.19]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: architt@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id E368060D3A; Fri, 16 Jun 2017 05:09:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1497589791; bh=G87zTjF5Z23P7DDlbDSWHIc2ta7WXQ9bKo/VGIfVb6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B0LpMnEDDEKyd0/2xJDcNp2emkjzTFPX7qKAc9gF70VDSD3xumf04n4bwwUgBuBR3 C9cx+7iXEMETDRh21LlneCnutxSwc0yztwaKzp6GIeW3whkY6IiknG034E+SeQheTb dSkg9eYZQerPfmfic2Wbw7JDSWydqPfnriuxCbwU= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org E368060D3A Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=architt@codeaurora.org From: Archit Taneja To: robdclark@gmail.com Cc: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, Archit Taneja Subject: [PATCH 3/3] drm/msm/hdmi: Fix HDMI pink strip issue seen on 8x96 Date: Fri, 16 Jun 2017 10:39:36 +0530 Message-Id: <20170616050936.1280-4-architt@codeaurora.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170616050936.1280-1-architt@codeaurora.org> References: <20170616050936.1280-1-architt@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A 2 pixel wide pink strip was observed on the left end of some HDMI monitors configured in a HDMI mode. It turned out that we were missing out on configuring AVI infoframes, and unlike APQ8064, the 8x96 HDMI H/W seems to be sensitive to that. Add configuration of AVI infoframes. While at it, make sure that hdmi_audio_update is only called when we've detected that the monitor supports HDMI. Signed-off-by: Archit Taneja --- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 70 ++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 4e6d1bf27474..ae40e7179d4f 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -86,6 +86,65 @@ static void power_off(struct drm_bridge *bridge) } } +#define AVI_IFRAME_LINE_NUMBER 1 + +static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi) +{ + struct drm_crtc *crtc = hdmi->encoder->crtc; + const struct drm_display_mode *mode = &crtc->state->adjusted_mode; + union hdmi_infoframe frame; + u8 buffer[HDMI_INFOFRAME_SIZE(AVI)]; + u32 val; + int len; + + drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, mode); + + len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); + if (len < 0) { + dev_err(&hdmi->pdev->dev, + "failed to configure avi infoframe\n"); + return; + } + + /* + * the AVI_INFOx registers don't map exactly to how the AVI infoframes + * are packed according to the spec. The checksum from the header is + * written to the LSB byte of AVI_INFO0 and the version is written to + * the third byte from the LSB of AVI_INFO3 + */ + hdmi_write(hdmi, REG_HDMI_AVI_INFO(0), + buffer[3] | + buffer[4] << 8 | + buffer[5] << 16 | + buffer[6] << 24); + + hdmi_write(hdmi, REG_HDMI_AVI_INFO(1), + buffer[7] | + buffer[8] << 8 | + buffer[9] << 16 | + buffer[10] << 24); + + hdmi_write(hdmi, REG_HDMI_AVI_INFO(2), + buffer[11] | + buffer[12] << 8 | + buffer[13] << 16 | + buffer[14] << 24); + + hdmi_write(hdmi, REG_HDMI_AVI_INFO(3), + buffer[15] | + buffer[16] << 8 | + buffer[1] << 24); + + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, + HDMI_INFOFRAME_CTRL0_AVI_SEND | + HDMI_INFOFRAME_CTRL0_AVI_CONT); + + val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1); + val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK; + val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER); + hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); +} + static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); @@ -98,7 +157,10 @@ static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) msm_hdmi_phy_resource_enable(phy); msm_hdmi_power_on(bridge); hdmi->power_on = true; - msm_hdmi_audio_update(hdmi); + if (hdmi->hdmi_mode) { + msm_hdmi_config_avi_infoframe(hdmi); + msm_hdmi_audio_update(hdmi); + } } msm_hdmi_phy_powerup(phy, hdmi->pixclock); @@ -134,7 +196,8 @@ static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge) if (hdmi->power_on) { power_off(bridge); hdmi->power_on = false; - msm_hdmi_audio_update(hdmi); + if (hdmi->hdmi_mode) + msm_hdmi_audio_update(hdmi); msm_hdmi_phy_resource_disable(phy); } } @@ -196,7 +259,8 @@ static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge, DBG("frame_ctrl=%08x", frame_ctrl); hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl); - msm_hdmi_audio_update(hdmi); + if (hdmi->hdmi_mode) + msm_hdmi_audio_update(hdmi); } static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {