From patchwork Thu Sep 5 10:37:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Lisovskiy X-Patchwork-Id: 11132711 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 07A35112C for ; Thu, 5 Sep 2019 10:40:13 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E350722CF7 for ; Thu, 5 Sep 2019 10:40:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E350722CF7 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=intel-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DAEA46E041; Thu, 5 Sep 2019 10:40:11 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTPS id B89136E03D; Thu, 5 Sep 2019 10:40:08 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Sep 2019 03:40:08 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,470,1559545200"; d="scan'208";a="195053718" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.72.89]) by orsmga002.jf.intel.com with ESMTP; 05 Sep 2019 03:40:04 -0700 From: Stanislav Lisovskiy To: dri-devel@lists.freedesktop.org Date: Thu, 5 Sep 2019 13:37:46 +0300 Message-Id: <20190905103746.32326-4-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190905103746.32326-1-stanislav.lisovskiy@intel.com> References: <20190905103746.32326-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v4 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, intel-gfx@lists.freedesktop.org, martin.peres@intel.com MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" 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. v2: Renamed change counter to epoch counter. Fixed type name. v3: Fixed rebase conflict v4: Remove duplicate drm_edid_equal checks from hdmi and dp, lets use only once edid property is getting updated and increment epoch counter from there. Also lets now call drm_connector_update_edid_property right after we get edid always to make sure there is a unified way to handle edid change, without having to change tons of source code as currently drm_connector_update_edid_property is called only in certain cases like reprobing and not right after edid is actually updated. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=105540 Signed-off-by: Stanislav Lisovskiy --- drivers/gpu/drm/drm_connector.c | 16 +++++++++++++++ drivers/gpu/drm/drm_edid.c | 3 +++ drivers/gpu/drm/drm_probe_helper.c | 2 +- drivers/gpu/drm/i915/display/intel_hotplug.c | 21 +++++++++++++++----- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 18b1ad2a4eee..828e57a740d7 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -1867,6 +1867,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector, struct drm_device *dev = connector->dev; size_t size = 0; int ret; + const struct edid *old_edid; /* ignore requests to set edid when overridden */ if (connector->override_edid) @@ -1888,6 +1889,20 @@ int drm_connector_update_edid_property(struct drm_connector *connector, else drm_reset_display_info(connector); + if (connector->edid_blob_ptr) { + old_edid = (struct edid *)connector->edid_blob_ptr->data; + if (old_edid) { + if (!drm_edid_are_equal(edid, old_edid)) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Edid was changed.\n", + connector->base.id, connector->name); + + connector->epoch_counter += 1; + DRM_DEBUG_KMS("Updating change counter to %llu\n", + connector->epoch_counter); + } + } + } + drm_object_property_set_value(&connector->base, dev->mode_config.non_desktop_property, connector->display_info.non_desktop); @@ -1898,6 +1913,7 @@ int drm_connector_update_edid_property(struct drm_connector *connector, edid, &connector->base, dev->mode_config.edid_property); + if (ret) return ret; return drm_connector_set_tile_property(connector); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 6cd086ea6253..7a327aec00d7 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -1803,6 +1803,9 @@ struct edid *drm_get_edid(struct drm_connector *connector, edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter); if (edid) drm_get_displayid(connector, edid); + + drm_connector_update_edid_property(connector, edid); + return edid; } EXPORT_SYMBOL(drm_get_edid); diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 5131ae56e676..d896d6b5d3b4 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -813,7 +813,7 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) changed = true; } - /* Check changing of edid when a connector status still remains + /* Check changing of epoch counter when a connector status still remains * as "connector_status_connected". */ if (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 fc29046d48ea..5fc1d54b3e6a 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -280,23 +280,34 @@ intel_encoder_hotplug(struct intel_encoder *encoder, { struct drm_device *dev = connector->base.dev; enum drm_connector_status old_status; + u64 old_epoch_counter; + bool ret = false; WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); old_status = connector->base.status; + old_epoch_counter = connector->base.epoch_counter; + connector->base.status = drm_helper_probe_detect(&connector->base, NULL, false); - if (old_status == connector->base.status) - return INTEL_HOTPLUG_UNCHANGED; + if (old_status != connector->base.status) + ret = true; + + if (old_epoch_counter != connector->base.epoch_counter) + ret = true; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", + 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.epoch_counter); + return INTEL_HOTPLUG_CHANGED; + } - return INTEL_HOTPLUG_CHANGED; + return INTEL_HOTPLUG_UNCHANGED; } static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder)