From patchwork Thu Jun 27 07:00:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Lisovskiy X-Patchwork-Id: 11018931 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3CEDC14C0 for ; Thu, 27 Jun 2019 07:01:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2F63A28A07 for ; Thu, 27 Jun 2019 07:01:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 237AD28A18; Thu, 27 Jun 2019 07:01:19 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D4E6528A07 for ; Thu, 27 Jun 2019 07:01:18 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 248A46E5B6; Thu, 27 Jun 2019 07:01:16 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 56E466E5B6; Thu, 27 Jun 2019 07:01:14 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jun 2019 00:01:14 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,422,1557212400"; d="scan'208";a="167333007" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.66.154]) by orsmga006.jf.intel.com with ESMTP; 27 Jun 2019 00:01:10 -0700 From: Stanislav Lisovskiy To: dri-devel@lists.freedesktop.org Date: Thu, 27 Jun 2019 10:00:15 +0300 Message-Id: <20190627070016.7047-2-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190627070016.7047-1-stanislav.lisovskiy@intel.com> References: <20190627070016.7047-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v1 1/3] drm: Add helper to compare edids. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, martin.peres@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Many drivers would benefit from using drm helper to compare edid, rather than bothering with own implementation. Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/drm_edid.c | 26 ++++++++++++++++++++++++++ include/drm/drm_edid.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 9d8f2b952004..5f0f5197924d 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1361,6 +1361,32 @@ static bool drm_edid_is_zero(const u8 *in_edid, int length) return true; } + +bool drm_edid_are_equal(struct edid *edid1, struct edid *edid2) +{ + int edid1_len, edid2_len; + bool edid1_present = edid1 != NULL; + bool edid2_present = edid2 != NULL; + + if (edid1_present != edid2_present) + return false; + + if (edid1) { + + edid1_len = EDID_LENGTH * (1 + edid1->extensions); + edid2_len = EDID_LENGTH * (1 + edid2->extensions); + + if (edid1_len != edid2_len) + return false; + + if (memcmp(edid1, edid2, edid1_len)) + return false; + } + + return true; +} + + /** * drm_edid_block_valid - Sanity check the EDID block (base or extension) * @raw_edid: pointer to raw EDID block diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index b9719418c3d2..8d28a6001287 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -354,6 +354,8 @@ drm_load_edid_firmware(struct drm_connector *connector) } #endif +bool drm_edid_are_equal(struct edid *edid1, struct edid *edid2); + int drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, struct drm_connector *connector, From patchwork Thu Jun 27 07:00:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Lisovskiy X-Patchwork-Id: 11018937 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D698E14C0 for ; Thu, 27 Jun 2019 07:01:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C7BCC28A07 for ; Thu, 27 Jun 2019 07:01:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BBC5428A18; Thu, 27 Jun 2019 07:01:24 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6F31928A07 for ; Thu, 27 Jun 2019 07:01:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 463D86E5BD; Thu, 27 Jun 2019 07:01:23 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0DFB06E5B7; Thu, 27 Jun 2019 07:01:18 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jun 2019 00:01:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,422,1557212400"; d="scan'208";a="167333022" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.66.154]) by orsmga006.jf.intel.com with ESMTP; 27 Jun 2019 00:01:14 -0700 From: Stanislav Lisovskiy To: dri-devel@lists.freedesktop.org Date: Thu, 27 Jun 2019 10:00:16 +0300 Message-Id: <20190627070016.7047-3-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190627070016.7047-1-stanislav.lisovskiy@intel.com> References: <20190627070016.7047-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v1 2/3] drm: Introduce change counter to drm_connector X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, intel-gfx@lists.freedesktop.org, martin.peres@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP This counter will be used by drm_helper_probe_detect caller to determine if something else had changed except connection status, like for example edid. Hardware specific drivers are responsible for updating this counter when some change is detected to notify the drm part, which can trigger for example hotplug event. Currently there is no way to propagate that to a calling layer, as we send only connection_status update, however as we see with edid the changes can be broader. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105540 Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/drm_connector.c | 1 + drivers/gpu/drm/drm_probe_helper.c | 29 +++++++++++++++++++++++++++-- include/drm/drm_connector.h | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 3ccdcf3dfcde..531983707d7f 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -245,6 +245,7 @@ int drm_connector_init(struct drm_device *dev, INIT_LIST_HEAD(&connector->modes); mutex_init(&connector->mutex); connector->edid_blob_ptr = NULL; + connector->change_counter = 0; connector->tile_blob_ptr = NULL; connector->status = connector_status_unknown; connector->display_info.panel_orientation = diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index ef2c468205a2..e8f41fa336c3 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -776,6 +776,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) struct drm_connector_list_iter conn_iter; enum drm_connector_status old_status; bool changed = false; + uint64_t old_change_counter; if (!dev->mode_config.poll_enabled) return false; @@ -789,20 +790,44 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) old_status = connector->status; + old_change_counter = connector->change_counter; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old change counter %llu\n", connector->base.id, + connector->name, + old_change_counter); + connector->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(connector->status)); - if (old_status != connector->status) + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] New change counter %llu\n", + connector->base.id, + connector->name, + connector->change_counter); + + if (old_status != connector->status) { changed = true; + } + + /* Check changing of edid when a connector status still remains + * as "connector_status_connected". + */ + if (connector->status == connector_status_connected && + old_status == connector_status_connected && + old_change_counter != connector->change_counter) { + changed = true; + } } drm_connector_list_iter_end(&conn_iter); mutex_unlock(&dev->mode_config.mutex); - if (changed) + if (changed) { drm_kms_helper_hotplug_event(dev); + DRM_DEBUG_KMS("Sent hotplug event\n"); + } return changed; } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index c6f8486d8b8f..feaa4eb673f6 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1155,6 +1155,8 @@ struct drm_connector { /** @override_edid: has the EDID been overwritten through debugfs for testing? */ bool override_edid; + uint64_t change_counter; + #define DRM_CONNECTOR_MAX_ENCODER 3 /** * @encoder_ids: Valid encoders for this connector. Please only use From patchwork Thu Jun 27 07:02:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Lisovskiy X-Patchwork-Id: 11018939 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CEBDE112C for ; Thu, 27 Jun 2019 07:03:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BC49328A07 for ; Thu, 27 Jun 2019 07:03:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AC2DC28A18; Thu, 27 Jun 2019 07:03:24 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3FA9F28A07 for ; Thu, 27 Jun 2019 07:03:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5A2656E5B3; Thu, 27 Jun 2019 07:03:23 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by gabe.freedesktop.org (Postfix) with ESMTPS id 773E66E5B3; Thu, 27 Jun 2019 07:03:22 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jun 2019 00:03:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,422,1557212400"; d="scan'208";a="313694626" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.66.154]) by orsmga004.jf.intel.com with ESMTP; 27 Jun 2019 00:03:19 -0700 From: Stanislav Lisovskiy To: intel-gfx@lists.freedesktop.org Date: Thu, 27 Jun 2019 10:02:28 +0300 Message-Id: <20190627070228.7195-1-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190627065945.6996-1-stanislav.lisovskiy@intel.com> References: <20190627065945.6996-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v1 3/3] drm/i915: Send hotplug event if edid had changed. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: daniel.vetter@ffwll.ch, martin.peres@intel.com, dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP Added edid checking to dp and hdmi edid setting functions, which are called from detect hooks. The result currently is propagated to calling layer using drm_connector->change_counter(proposed by Daniel Vetter). drm_helper_hpd_irq_event and intel_encoder_hotplug are currently both responsible for checking if this counter or connection status is changed. There are conflicting parts in drm and i915 which attempt to do the same job - drm_helper_hpd_irq_event attempts to check connector status changes and then call hotplug, just as i915_hotplug_work_func, which calls encoder->hotplug hook which in turn calls generic intel_encoder_hotplug function which attempts to probe if output has changed. Looks like both needs to be changed, so added edid checking also to intel_encoder_hotplug function which is called both for hdmi and dp. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105540 Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/i915/display/intel_dp.c | 16 +++++++++++++++- drivers/gpu/drm/i915/display/intel_hdmi.c | 16 +++++++++++++--- drivers/gpu/drm/i915/display/intel_hotplug.c | 20 +++++++++++++++----- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4336df46fe78..d259dd9ee7be 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -5510,10 +5510,24 @@ static void intel_dp_set_edid(struct intel_dp *intel_dp) { struct intel_connector *intel_connector = intel_dp->attached_connector; + struct drm_connector *connector = &intel_connector->base; struct edid *edid; + struct edid *old_edid; - intel_dp_unset_edid(intel_dp); edid = intel_dp_get_edid(intel_dp); + old_edid = intel_connector->detect_edid; + + if (!drm_edid_are_equal(edid, old_edid)) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was changed! Updating blob property.\n", + connector->base.id, connector->name); + + connector->change_counter += 1; + DRM_DEBUG_KMS("Updating change counter to %llu\n", connector->change_counter); + + intel_connector_update_modes(&intel_connector->base, edid); + } + + intel_dp_unset_edid(intel_dp); intel_connector->detect_edid = edid; intel_dp->has_audio = drm_detect_monitor_audio(edid); diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0ebec69bbbfc..6c851c360b35 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -2503,7 +2503,7 @@ intel_hdmi_set_edid(struct drm_connector *connector) struct drm_i915_private *dev_priv = to_i915(connector->dev); struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); intel_wakeref_t wakeref; - struct edid *edid; + struct edid *edid, *old_edid; bool connected = false; struct i2c_adapter *i2c; @@ -2524,11 +2524,22 @@ intel_hdmi_set_edid(struct drm_connector *connector) intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS, wakeref); + old_edid = to_intel_connector(connector)->detect_edid; + + if (!drm_edid_are_equal(edid, old_edid)) { + intel_connector_update_modes(connector, edid); + DRM_DEBUG_KMS("Updating change counter to %llu\n", connector->change_counter); + connector->change_counter += 1; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was changed! Updating blob property.\n", + connector->base.id, connector->name); + } + intel_hdmi_unset_edid(connector); to_intel_connector(connector)->detect_edid = edid; + if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) { intel_hdmi->has_audio = drm_detect_monitor_audio(edid); intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); - connected = true; } @@ -2555,7 +2566,6 @@ intel_hdmi_detect(struct drm_connector *connector, bool force) !intel_digital_port_connected(encoder)) goto out; - intel_hdmi_unset_edid(connector); if (intel_hdmi_set_edid(connector)) status = connector_status_connected; diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index ea3de4acc850..b976431f1ce5 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -271,23 +271,33 @@ bool intel_encoder_hotplug(struct intel_encoder *encoder, { struct drm_device *dev = connector->base.dev; enum drm_connector_status old_status; + uint64_t old_change_counter; + bool ret = false; WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); old_status = connector->base.status; + old_change_counter = connector->base.change_counter; + connector->base.status = drm_helper_probe_detect(&connector->base, NULL, false); - if (old_status == connector->base.status) - return false; + if (old_change_counter != connector->base.change_counter) + ret = true; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", + if (old_status != connector->base.status) + ret = true; + + if (ret) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s(change counter %llu)\n", connector->base.base.id, connector->base.name, drm_get_connector_status_name(old_status), - drm_get_connector_status_name(connector->base.status)); + drm_get_connector_status_name(connector->base.status), + connector->base.change_counter); + } - return true; + return ret; } static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder)