Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp1909361imm; Thu, 9 Aug 2018 04:15:04 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzOHf5XXkcQ/MD58xz9Pn/QOmwwHWxbpMcRAPEjawU8RmrBJumr303Gg/KdrPkD0h+e8v81 X-Received: by 2002:a62:c699:: with SMTP id x25-v6mr1984688pfk.16.1533813304504; Thu, 09 Aug 2018 04:15:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533813304; cv=none; d=google.com; s=arc-20160816; b=gKV5L43DovDXBWFcDA2ML9VMwuMAyhqxarORPwGBe9AaHt2/kLLlZk/gxKjyKTpmIp GalhpeGjntwanEwmNmp9sLuPODnjkj5UpG5CDa2+BBPRnPjrNk1Bj+/TiKwbkGXqqy74 gHROES3Hwe36FQv5rAn6an+51T8bxXqFjloyugNRRxZAs+DfV2lcRHBs1Uab1mPLRRQP ewUQ0qfS8nOAicoqfg61U0zXo1idHOszJYu+KA+/aTd6bIT2M3SsTW6JcEU0bVQ/Tp33 VOg52o6h8qifSGCXw86i7wF7NT2Sk5+hSYTc3G4vVhsQsDJTyZ983YkHOVaucSGnPm8V r9LA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=IMrlP9mDUpqm0In6SF9C+ieoZOKRxRc9b2IPNni0JXE=; b=gQaFiWxbXWx8W8gM1bj3zd1b+hL2i0qxGIHOq9PhB9t41eY8/UzBeUzrm39KqDPCqR qLHOb8naGDthSQY6WULj7qqRLYGD2GfQVdOBSPLzerQLpoOEuxj/F24F7A4mZQt7HnDi CUc/1TjQ51TsMCZl7ZZ64tIVOkvdkVmkjpaL4g7Jv83hxSnD4wocEhwN1/q8lsZkA/j9 WDTyGlVh/QqeCsbFZCk2WRQli1e11tlKkdiPAKRlFuIOmF0jKEQVrFKyqtljYLy3JVJA YduAmPbr9JqISZaIee8sJ8o8aHJHHpC7Dh9I/EShsEP7DyLqi+m3WhqCZpPY3JaPLRLI juDA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 61-v6si166779plz.447.2018.08.09.04.14.49; Thu, 09 Aug 2018 04:15:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730862AbeHINiD (ORCPT + 99 others); Thu, 9 Aug 2018 09:38:03 -0400 Received: from mga07.intel.com ([134.134.136.100]:9712 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730334AbeHINiC (ORCPT ); Thu, 9 Aug 2018 09:38:02 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Aug 2018 04:13:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,214,1531810800"; d="scan'208";a="61850463" Received: from espoo.fi.intel.com ([10.237.66.147]) by fmsmga008.fm.intel.com with ESMTP; 09 Aug 2018 04:13:31 -0700 From: Gwan-gyeong Mun To: Jani Nikula Cc: Joonas Lahtinen , Rodrigo Vivi , David Airlie , intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Subject: [v3] drm/i915: Add detection of changing of edid on between suspend and resume Date: Thu, 9 Aug 2018 14:13:30 +0300 Message-Id: <20180809111330.5113-1-gwan-gyeong.mun@intel.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180803163453.7760-1-gwan-gyeong.mun@intel.com> References: <20180803163453.7760-1-gwan-gyeong.mun@intel.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The hotplug detection routine of i915 uses drm_helper_hpd_irq_event(). This helper can detect changing of status of connector, but it can not detect changing of edid. Following scenario requires detection of changing of edid. 1) plug display device to a connector 2) system suspend 3) unplug 1)'s display device and plug the other display device to a connector 4) system resume It adds edid check routine when a connector status still remains as "connector_status_connected". v2: Add NULL check before comparing of EDIDs. Testcase: igt/kms_chamelium/hdmi-edid-change-during-hibernate Testcase: igt/kms_chamelium/hdmi-edid-change-during-suspend Testcase: igt/kms_chamelium/dp-edid-change-during-hibernate Testcase: igt/kms_chamelium/dp-edid-change-during-suspend Signed-off-by: Gwan-gyeong Mun --- drivers/gpu/drm/i915/intel_hotplug.c | 84 +++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_hotplug.c b/drivers/gpu/drm/i915/intel_hotplug.c index 648a13c6043c..965f2d771fc0 100644 --- a/drivers/gpu/drm/i915/intel_hotplug.c +++ b/drivers/gpu/drm/i915/intel_hotplug.c @@ -507,6 +507,88 @@ void intel_hpd_init(struct drm_i915_private *dev_priv) } } +/** + * intel_hpd_irq_event - hotplug processing + * @dev: drm_device + * + * Drivers can use this function to run a detect cycle on all connectors which + * have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All other + * connectors are ignored, which is useful to avoid reprobing fixed panels. + * + * This function is useful for drivers which can't or don't track hotplug interrupts + * for each connector. This function is based on drm_helper_hpd_irq_event() helper + * function and besides it adds edid check routine when a connector status still + * remains as "connector_status_connected". + * + * Following scenario requires detection of changing of edid. + * 1) plug display device to a connector + * 2) system suspend + * 3) unplug 1)'s display device and plug the other display device to a connector + * 4) system resume + + * This function must be called from process context with no mode + * setting locks held. + * + * Note that a connector can be both polled and probed from the hotplug handler, + * in case the hotplug interrupt is known to be unreliable. + */ +static bool intel_hpd_irq_event(struct drm_device *dev) +{ + struct drm_connector *connector; + struct drm_connector_list_iter conn_iter; + enum drm_connector_status old_status, cur_status; + struct edid *old_edid; + bool changed = false; + + if (!dev->mode_config.poll_enabled) + return false; + + mutex_lock(&dev->mode_config.mutex); + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + /* Only handle HPD capable connectors. */ + if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) + continue; + + old_status = connector->status; + old_edid = to_intel_connector(connector)->detect_edid; + + cur_status = drm_helper_probe_detect(connector, NULL, false); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", + connector->base.id, connector->name, + drm_get_connector_status_name(old_status), + drm_get_connector_status_name(cur_status)); + + if (old_status != cur_status) + changed = true; + + /* Check changing of edid when a connector status still remains + * as "connector_status_connected". + */ + if (old_status == cur_status && + cur_status == connector_status_connected) { + struct edid *cur_edid = to_intel_connector(connector)->detect_edid; + + if (!old_edid || !cur_edid) + continue; + + if (memcmp(old_edid, cur_edid, sizeof(*cur_edid))) { + changed = true; + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] edid updated\n", + connector->base.id, + connector->name); + } + } + } + drm_connector_list_iter_end(&conn_iter); + mutex_unlock(&dev->mode_config.mutex); + + if (changed) + drm_kms_helper_hotplug_event(dev); + + return changed; +} + static void i915_hpd_poll_init_work(struct work_struct *work) { struct drm_i915_private *dev_priv = @@ -552,7 +634,7 @@ static void i915_hpd_poll_init_work(struct work_struct *work) * in the middle of disabling polling */ if (!enabled) - drm_helper_hpd_irq_event(dev); + intel_hpd_irq_event(dev); } /** -- 2.18.0