From patchwork Wed Jan 21 20:43:16 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 5680461 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id F13DC9F358 for ; Wed, 21 Jan 2015 20:43:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 14DB820480 for ; Wed, 21 Jan 2015 20:43:38 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id E83362047D for ; Wed, 21 Jan 2015 20:43:35 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ED6D36E28E; Wed, 21 Jan 2015 12:43:33 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qg0-f53.google.com (mail-qg0-f53.google.com [209.85.192.53]) by gabe.freedesktop.org (Postfix) with ESMTP id E46DD6E28E for ; Wed, 21 Jan 2015 12:43:32 -0800 (PST) Received: by mail-qg0-f53.google.com with SMTP id a108so28279922qge.12 for ; Wed, 21 Jan 2015 12:43:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=x0T5i48dQb5nwoR5ZuAocjBSn3yunnRJvQincbWQIog=; b=SGUrF+mDnORS4dR0bIzRWQdJ+q2Ttwxp9timMGJNvd8eHJt2+cijSq2DlILPNWjQMc jwEnuUZqyLg0OyyXLQSZsypjDdhrPmbdnK6nzVLqJKzeYlPM0Bw7IonhNkioXTPQ3uYz 968tpCsouNyr9TfShkmYgl3oUQgf2LDqZYZ3TrbOY3ek7OAFlQNhTC+c3DaxzEzugyog C/45TUIsThTPDXu6ZE4sqLvR4rXlrBUTbMYGB4QrGh1NZCrEwH4MqyHrha7bFf0b4AmQ baypcF1PK/+MkBKKSmR8Gi4h4/xg+EzAIjTEWMmo2bjQ3ObJcR68O+fotTBOiFz86tWC aNrg== X-Received: by 10.140.92.33 with SMTP id a30mr41736935qge.30.1421873008589; Wed, 21 Jan 2015 12:43:28 -0800 (PST) Received: from localhost ([2601:6:2c00:943:eab1:fcff:fe75:3f91]) by mx.google.com with ESMTPSA id l3sm2950405qaf.36.2015.01.21.12.43.26 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Jan 2015 12:43:27 -0800 (PST) From: Rob Clark To: dri-devel@lists.freedesktop.org Subject: [RFC] drm/msm/hdmi: spurious hpd disconnect workaround Date: Wed, 21 Jan 2015 15:43:16 -0500 Message-Id: <1421872996-28215-1-git-send-email-robdclark@gmail.com> X-Mailer: git-send-email 2.1.0 Cc: Jilai Wang X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, 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 On some (well, maybe just one) HDMI monitor I get a spurious disconnect in the process of lighting up the display. A low-pass filter on HPD events, in the form of leaving the HPD irq disabled for 100ms after the previous HPD irq, seems to do a good job of working around the issue. A somewhat simpler solution is just msleep(100) in the hotplug worker. But AFAIU that will interfere with the pending HDCP support, if HDCP requires guarantees about detecting disconnect in a timely fashion. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index bc20e9b..f481f54 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -24,6 +24,7 @@ struct hdmi_connector { struct drm_connector base; struct hdmi *hdmi; struct work_struct hpd_work; + struct timer_list hotplug_timer; }; #define to_hdmi_connector(x) container_of(x, struct hdmi_connector, base) @@ -228,11 +229,25 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector) } static void +hotplug_timer(unsigned long data) +{ + struct hdmi *hdmi = (struct hdmi *)data; + uint32_t hpd_int_ctrl; + + /* re-enable HPD irq: */ + hpd_int_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL); + hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_EN; + hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl); +} + +static void hotplug_work(struct work_struct *work) { struct hdmi_connector *hdmi_connector = container_of(work, struct hdmi_connector, hpd_work); struct drm_connector *connector = &hdmi_connector->base; + mod_timer(&hdmi_connector->hotplug_timer, + round_jiffies_up(jiffies + msecs_to_jiffies(100))); drm_helper_hpd_irq_event(connector->dev); } @@ -258,7 +273,7 @@ void hdmi_connector_irq(struct drm_connector *connector) DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl); /* detect disconnect if we are connected or visa versa: */ - hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN; + hpd_int_ctrl = 0; if (!detected) hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT; hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl); @@ -416,6 +431,8 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) hdmi_connector->hdmi = hdmi; INIT_WORK(&hdmi_connector->hpd_work, hotplug_work); + setup_timer(&hdmi_connector->hotplug_timer, hotplug_timer, + (unsigned long)hdmi); connector = &hdmi_connector->base;