From patchwork Fri Sep 6 08:26:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stanislav Lisovskiy X-Patchwork-Id: 11134755 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 51384924 for ; Fri, 6 Sep 2019 08:29:05 +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 3BEA52082C for ; Fri, 6 Sep 2019 08:29:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3BEA52082C 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 02F116E1EC; Fri, 6 Sep 2019 08:29:03 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7D7596E1F1; Fri, 6 Sep 2019 08:29:01 +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 fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 06 Sep 2019 01:28:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,472,1559545200"; d="scan'208";a="195378406" Received: from slisovsk-lenovo-ideapad-720s-13ikb.fi.intel.com ([10.237.72.89]) by orsmga002.jf.intel.com with ESMTP; 06 Sep 2019 01:28:51 -0700 From: Stanislav Lisovskiy To: dri-devel@lists.freedesktop.org Date: Fri, 6 Sep 2019 11:26:35 +0300 Message-Id: <20190906082636.3103-3-stanislav.lisovskiy@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190906082636.3103-1-stanislav.lisovskiy@intel.com> References: <20190906082636.3103-1-stanislav.lisovskiy@intel.com> Subject: [Intel-gfx] [PATCH v6 2/3] drm: Introduce epoch 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" This counter will be used by drm_helper_probe_detect caller to determine if anything had changed(including edid, connection status and etc). Hardware specific driver detect hooks are responsible for updating this counter when some change is detected to notify the drm part, which can trigger for example hotplug event. Also 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. v2: Added documentation for the new counter. Rename change_counter to epoch_counter. 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 | 38 ++++++++++++++++++++++++++---- include/drm/drm_connector.h | 3 +++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4c766624b20d..98fd236acc57 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -246,6 +246,7 @@ int drm_connector_init(struct drm_device *dev, INIT_LIST_HEAD(&connector->modes); mutex_init(&connector->mutex); connector->edid_blob_ptr = NULL; + connector->epoch_counter = 0; connector->tile_blob_ptr = NULL; connector->status = connector_status_unknown; connector->display_info.panel_orientation = @@ -1866,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) @@ -1887,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 = (const 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); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 0639db9fd23f..48b716abc9ef 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 351cbc40f0f8..b2b6385cfed3 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -287,6 +287,9 @@ drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force) if (WARN_ON(ret < 0)) ret = connector_status_unknown; + if (ret != connector->status) + connector->epoch_counter += 1; + drm_modeset_drop_locks(&ctx); drm_modeset_acquire_fini(&ctx); @@ -320,11 +323,16 @@ drm_helper_probe_detect(struct drm_connector *connector, return ret; if (funcs->detect_ctx) - return funcs->detect_ctx(connector, ctx, force); + ret = funcs->detect_ctx(connector, ctx, force); else if (connector->funcs->detect) - return connector->funcs->detect(connector, force); + ret = connector->funcs->detect(connector, force); else - return connector_status_connected; + ret = connector_status_connected; + + if (ret != connector->status) + connector->epoch_counter += 1; + + return ret; } EXPORT_SYMBOL(drm_helper_probe_detect); @@ -777,6 +785,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_epoch_counter; if (!dev->mode_config.poll_enabled) return false; @@ -790,20 +799,39 @@ bool drm_helper_hpd_irq_event(struct drm_device *dev) old_status = connector->status; + old_epoch_counter = connector->epoch_counter; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] Old epoch counter %llu\n", connector->base.id, + connector->name, + old_epoch_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 epoch counter %llu\n", + connector->base.id, + connector->name, + connector->epoch_counter); + + /* + * Check if epoch counter had changed, meaning that we need + * to send a uevent. + */ + if (old_epoch_counter != connector->epoch_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 681cb590f952..a3cc7d0927d6 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1288,6 +1288,9 @@ struct drm_connector { /** @override_edid: has the EDID been overwritten through debugfs for testing? */ bool override_edid; + /** @epoch_counter: used to detect any other changes in connector, besides status */ + uint64_t epoch_counter; + #define DRM_CONNECTOR_MAX_ENCODER 3 /** * @encoder_ids: Valid encoders for this connector. Please only use