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: 11018933 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 3497114C0 for ; Thu, 27 Jun 2019 07:01:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 259E928A07 for ; Thu, 27 Jun 2019 07:01:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1995328A18; Thu, 27 Jun 2019 07:01:21 +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 D53A328A07 for ; Thu, 27 Jun 2019 07:01:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 958D46E5B8; Thu, 27 Jun 2019 07:01:17 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@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 Subject: [PATCH v1 1/3] drm: Add helper to compare edids. 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> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - 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, Stanislav.Lisovskiy@intel.com, jani.saarinen@intel.com MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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: 11018935 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 7A6ED112C for ; Thu, 27 Jun 2019 07:01:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A06728A07 for ; Thu, 27 Jun 2019 07:01:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5DD6D28A18; Thu, 27 Jun 2019 07:01:23 +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 06CCC28A07 for ; Thu, 27 Jun 2019 07:01:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4E8566E5BC; Thu, 27 Jun 2019 07:01:20 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@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 Subject: [PATCH v1 2/3] drm: Introduce change counter to drm_connector 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> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - 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, Stanislav.Lisovskiy@intel.com, jani.saarinen@intel.com MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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: 11018941 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 40AFA14C0 for ; Thu, 27 Jun 2019 07:03:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 30DE928A07 for ; Thu, 27 Jun 2019 07:03:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2528628A18; Thu, 27 Jun 2019 07:03:26 +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 BF65628A07 for ; Thu, 27 Jun 2019 07:03:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9B51F6E5B7; Thu, 27 Jun 2019 07:03:23 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@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 Subject: [PATCH v1 3/3] drm/i915: Send hotplug event if edid had changed. 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> X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - 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, Stanislav.Lisovskiy@intel.com, jani.saarinen@intel.com MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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)