From patchwork Mon Feb 24 19:31:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13988853 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 8E697C18E7C for ; Mon, 24 Feb 2025 19:30:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3BC7E10E4EC; Mon, 24 Feb 2025 19:30:19 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="lbr9yT7P"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by gabe.freedesktop.org (Postfix) with ESMTPS id 86E3610E4E8; Mon, 24 Feb 2025 19:30:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740425418; x=1771961418; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=UsoOSQ9UnimLc0OGCZNwu0W5ODgw7bM5EGb0ZKXBZOE=; b=lbr9yT7PxdcKmxLRfI7vz8QQpq9BCQ1hKGFwhQZZnXtXMgAorujPGkWz 11mf2CqWknNgq9yGSMzNB+NdaDNPN8WK3WMexzNP+bPJgRHY49s7wLaC/ wdIisjqwMGzNC6nOGaffl56zggFuIhj6Xzx3S65UNqbEn10PfTqdOsG1Z ogIACzX7oVQDLqJN/xaz8CxKZ0XfKwlZXEk56L5mdiV5AkC3QRzTAS6/L LGVjpISW4dGiZ+CZvJMn0hrEMfef4UQzv8RZoXRtoBYWvDOcLltwV87EH sWOXnMJWXDtIPb3+gHFHMIuug9+V15UdVxkNE0jcrhB9u1J4sAHebW0S9 w==; X-CSE-ConnectionGUID: 5ceb7bziTz2Cfmazy7i7qw== X-CSE-MsgGUID: VEgDnLhGRq+dpmbd6v47cg== X-IronPort-AV: E=McAfee;i="6700,10204,11355"; a="40388252" X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="40388252" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:16 -0800 X-CSE-ConnectionGUID: LGa7ZASRRwyamjp85mToYw== X-CSE-MsgGUID: tzgsMkUZTDCpxOB5F+FbUA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="116169045" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:14 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 1/5] drm/i915/hpd: Let an HPD pin be in the disabled state when handling missed IRQs Date: Mon, 24 Feb 2025 21:31:11 +0200 Message-ID: <20250224193115.2058512-2-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20250224193115.2058512-1-imre.deak@intel.com> References: <20250224193115.2058512-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" After suspending and resuming the detection on connectors, HPD IRQs that arrived while the detection was suspended, are handled by scheduling the intel_hotplug::hotplug work for them. All HPD pins must be at this point in either the HPD_ENABLED (set for all pins during driver loading/system resuming) or HPD_MARK_DISABLED (set by IRQ storm detection) state: the HPD_DISABLED state for a pin can be set only from the HPD_MARK_DISABLED state by the hotplug work after a storm detection (enabling polling on the given pin/connector), however the hotplug work won't be scheduled while the detection is suspended. A follow-up change will add support for suspending the HPD IRQ handling on a given HPD pin (without disabling the IRQ generation on it), after which it becomes possible to see a pin in the HPD_DISABLED state when resuming the IRQ handling (since the suspending could've happened for an already disabled pin). Adjust queue_work_for_missed_irqs() accordingly, so that this function can be reused for resuming the IRQ handling. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_hotplug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 00d7b1ccf1900..ab8e71c4b0f86 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -980,6 +980,7 @@ static void queue_work_for_missed_irqs(struct drm_i915_private *i915) case HPD_MARK_DISABLED: queue_work = true; break; + case HPD_DISABLED: case HPD_ENABLED: break; default: From patchwork Mon Feb 24 19:31:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13988851 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id BC639C021A4 for ; Mon, 24 Feb 2025 19:30:18 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6014110E4E5; Mon, 24 Feb 2025 19:30:18 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="i/FO8WKd"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by gabe.freedesktop.org (Postfix) with ESMTPS id A8FE710E4EA; Mon, 24 Feb 2025 19:30:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740425418; x=1771961418; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=etvC0flQy7VdOAl8ptgvcHYbsX6IxO8738WGJym2lrU=; b=i/FO8WKd5VQlT2D/JnMELu5xtZf7ImtjxFUGAJfGVYnHyxrT3LICvZ+F 3I8jyKoU843/SR6VY4pO9CbYr5yEf7iMXFh572dw7a+vVMyhgLXARPo2Z vmFDhZ7lNanu9d2lfJ4ztIzxayYh1YK1hbLeK0kBQ8OMXmxCfjgYtTT44 LSeTlgHoimEO9VmgN6/GG5HPyemB39Y1GP5KHRh3VR6WOQGYgxk7R2XnN hOY1F0/X7NRwLggKPCtI8lkoB8hYhefB5hHB5PRdqb9CKwGcIR/K3orGG fr4MqkhB4QdpnGALAKn8HWYFyt8kUiAIbVxbX3SrUJJLnxPXOQNZiEmF8 w==; X-CSE-ConnectionGUID: hJghOXmqSDmumX2V1SxZOg== X-CSE-MsgGUID: 9LexQjxvSbuqQxdtzymxYw== X-IronPort-AV: E=McAfee;i="6700,10204,11355"; a="40388254" X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="40388254" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:17 -0800 X-CSE-ConnectionGUID: 0vfA8V9VSDixD1CoGTcfzw== X-CSE-MsgGUID: P8JMm/YoTWSLJ7k6O3+Oeg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="116169050" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:16 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 2/5] drm/i915/hpd: Add support for suspending the IRQ handling on an HPD pin Date: Mon, 24 Feb 2025 21:31:12 +0200 Message-ID: <20250224193115.2058512-3-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20250224193115.2058512-1-imre.deak@intel.com> References: <20250224193115.2058512-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Add support for suspending the IRQ handling on the HPD pin of a given encoder, handling IRQs that arrived while in the suspended state after resuming the IRQ handling. This will be used by a follow-up change, which suspends/resumes the IRQ handling around DP link training. This is similar to the intel_hpd_disable/enable() functionality, by also handling encoders/ports with a pulse handler (i.e. also suspending/resuming the short/long pulse handling) and handling the IRQs arrived in the suspended state after the handling is resumed (vs. just dropping such IRQs). Signed-off-by: Imre Deak --- .../gpu/drm/i915/display/intel_display_core.h | 2 + drivers/gpu/drm/i915/display/intel_hotplug.c | 206 +++++++++++++++--- drivers/gpu/drm/i915/display/intel_hotplug.h | 2 + 3 files changed, 185 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 554870d2494b3..9b338d8c9f26e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -173,6 +173,8 @@ struct intel_hotplug { u32 short_port_mask; struct work_struct dig_port_work; + u32 suspended_port_mask; + struct work_struct poll_init_work; bool poll_enabled; diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index ab8e71c4b0f86..81f2be06bc2a1 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -349,19 +349,71 @@ static bool intel_encoder_has_hpd_pulse(struct intel_encoder *encoder) enc_to_dig_port(encoder)->hpd_pulse != NULL; } +static u32 port_mask_to_hpds(struct intel_display *display, u32 port_mask) +{ + struct intel_encoder *encoder; + u32 hpds = 0; + + for_each_intel_encoder(display->drm, encoder) { + if (BIT(encoder->port) & port_mask) + hpds |= BIT(encoder->hpd_pin); + } + + return hpds; +} + +static u32 hpd_mask_to_ports(struct intel_display *display, u32 hpd_mask) +{ + struct intel_encoder *encoder; + u32 ports = 0; + + for_each_intel_encoder(display->drm, encoder) { + if (BIT(encoder->hpd_pin) & hpd_mask) + ports |= BIT(encoder->port); + } + + return ports; +} + +static u32 get_suspended_hpds(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + lockdep_assert_held(&i915->irq_lock); + return port_mask_to_hpds(display, display->hotplug.suspended_port_mask); +} + +/* + * Get the mask of all the ports using a suspended HPD pin, accounting for + * ports sharing their - suspended - HPD pin with another port. + */ +static u32 get_suspended_hpd_ports(struct intel_display *display) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + lockdep_assert_held(&i915->irq_lock); + return hpd_mask_to_ports(display, get_suspended_hpds(display)); +} + static void i915_digport_work_func(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, display.hotplug.dig_port_work); + struct intel_display *display = + container_of(work, struct intel_display, hotplug.dig_port_work); + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; u32 long_port_mask, short_port_mask; struct intel_encoder *encoder; + u32 suspended_ports; u32 old_bits = 0; spin_lock_irq(&dev_priv->irq_lock); - long_port_mask = dev_priv->display.hotplug.long_port_mask; - dev_priv->display.hotplug.long_port_mask = 0; - short_port_mask = dev_priv->display.hotplug.short_port_mask; - dev_priv->display.hotplug.short_port_mask = 0; + + suspended_ports = get_suspended_hpd_ports(display); + long_port_mask = hotplug->long_port_mask & ~suspended_ports; + hotplug->long_port_mask &= ~long_port_mask; + short_port_mask = hotplug->short_port_mask & ~suspended_ports; + hotplug->short_port_mask = ~short_port_mask; + spin_unlock_irq(&dev_priv->irq_lock); for_each_intel_encoder(&dev_priv->drm, encoder) { @@ -406,13 +458,17 @@ static void i915_digport_work_func(struct work_struct *work) */ void intel_hpd_trigger_irq(struct intel_digital_port *dig_port) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_display *display = to_intel_display(dig_port); + struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; spin_lock_irq(&i915->irq_lock); - i915->display.hotplug.short_port_mask |= BIT(dig_port->base.port); - spin_unlock_irq(&i915->irq_lock); - queue_work(i915->display.hotplug.dp_wq, &i915->display.hotplug.dig_port_work); + hotplug->short_port_mask |= BIT(dig_port->base.port); + if (!(BIT(dig_port->base.port) & get_suspended_hpd_ports(display))) + queue_work(hotplug->dp_wq, &hotplug->dig_port_work); + + spin_unlock_irq(&i915->irq_lock); } /* @@ -420,9 +476,10 @@ void intel_hpd_trigger_irq(struct intel_digital_port *dig_port) */ static void i915_hotplug_work_func(struct work_struct *work) { - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, - display.hotplug.hotplug_work.work); + struct intel_display *display = + container_of(work, struct intel_display, hotplug.hotplug_work.work); + struct drm_i915_private *dev_priv = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; struct drm_connector_list_iter conn_iter; struct intel_connector *connector; u32 changed = 0, retry = 0; @@ -430,16 +487,18 @@ static void i915_hotplug_work_func(struct work_struct *work) u32 hpd_retry_bits; struct drm_connector *first_changed_connector = NULL; int changed_connectors = 0; + u32 suspended_hpds; mutex_lock(&dev_priv->drm.mode_config.mutex); drm_dbg_kms(&dev_priv->drm, "running encoder hotplug functions\n"); spin_lock_irq(&dev_priv->irq_lock); - hpd_event_bits = dev_priv->display.hotplug.event_bits; - dev_priv->display.hotplug.event_bits = 0; - hpd_retry_bits = dev_priv->display.hotplug.retry_bits; - dev_priv->display.hotplug.retry_bits = 0; + suspended_hpds = get_suspended_hpds(display); + hpd_event_bits = hotplug->event_bits & ~suspended_hpds; + hotplug->event_bits &= ~hpd_event_bits; + hpd_retry_bits = hotplug->retry_bits & ~suspended_hpds; + hotplug->retry_bits &= ~hpd_retry_bits; /* Enable polling for connectors which had HPD IRQ storms */ intel_hpd_irq_storm_switch_to_polling(dev_priv); @@ -538,11 +597,13 @@ static void i915_hotplug_work_func(struct work_struct *work) void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, u32 pin_mask, u32 long_mask) { + struct intel_display *display = to_intel_display(&dev_priv->drm); struct intel_encoder *encoder; bool storm_detected = false; bool queue_dig = false, queue_hp = false; u32 long_hpd_pulse_mask = 0; u32 short_hpd_pulse_mask = 0; + u32 suspended_hpds; enum hpd_pin pin; if (!pin_mask) @@ -550,6 +611,8 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, spin_lock(&dev_priv->irq_lock); + suspended_hpds = get_suspended_hpds(display); + /* * Determine whether ->hpd_pulse() exists for each pin, and * whether we have a short or a long pulse. This is needed @@ -573,7 +636,9 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, "digital hpd on [ENCODER:%d:%s] - %s\n", encoder->base.base.id, encoder->base.name, long_hpd ? "long" : "short"); - queue_dig = true; + + if (!(BIT(pin) & suspended_hpds)) + queue_dig = true; if (long_hpd) { long_hpd_pulse_mask |= BIT(pin); @@ -617,7 +682,9 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv, } else { dev_priv->display.hotplug.event_bits |= BIT(pin); long_hpd = true; - queue_hp = true; + + if (!(BIT(pin) & suspended_hpds)) + queue_hp = true; } if (intel_hpd_irq_storm_detect(dev_priv, pin, long_hpd)) { @@ -915,11 +982,15 @@ static bool cancel_all_detection_work(struct drm_i915_private *i915) void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) { + struct intel_display *display = to_intel_display(&dev_priv->drm); + if (!HAS_DISPLAY(dev_priv)) return; spin_lock_irq(&dev_priv->irq_lock); + drm_WARN_ON(display->drm, display->hotplug.suspended_port_mask); + dev_priv->display.hotplug.long_port_mask = 0; dev_priv->display.hotplug.short_port_mask = 0; dev_priv->display.hotplug.event_bits = 0; @@ -966,19 +1037,22 @@ void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin) static void queue_work_for_missed_irqs(struct drm_i915_private *i915) { - bool queue_work = false; + struct intel_display *display = to_intel_display(&i915->drm); + struct intel_hotplug *hotplug = &display->hotplug; + bool queue_hp_work = false; + u32 suspended_hpds; enum hpd_pin pin; lockdep_assert_held(&i915->irq_lock); - if (i915->display.hotplug.event_bits || - i915->display.hotplug.retry_bits) - queue_work = true; + suspended_hpds = get_suspended_hpds(display); + if ((hotplug->event_bits | hotplug->retry_bits) & ~suspended_hpds) + queue_hp_work = true; for_each_hpd_pin(pin) { switch (i915->display.hotplug.stats[pin].state) { case HPD_MARK_DISABLED: - queue_work = true; + queue_hp_work = true; break; case HPD_DISABLED: case HPD_ENABLED: @@ -988,10 +1062,92 @@ static void queue_work_for_missed_irqs(struct drm_i915_private *i915) } } - if (queue_work) + if ((hotplug->long_port_mask | hotplug->short_port_mask) & + ~hpd_mask_to_ports(display, suspended_hpds)) + queue_work(hotplug->dp_wq, &hotplug->dig_port_work); + + if (queue_hp_work) queue_delayed_detection_work(i915, &i915->display.hotplug.hotplug_work, 0); } +/** + * intel_hpd_suspend - Suspend handling of HPD IRQs on an HPD pin + * @encoder: Encoder to suspend the HPD handling for + * + * Suspends the handling of HPD IRQs on the HPD pin of @encoder. + * + * On return: + * - It's guaranteed that the suspended encoders' HPD pulse handler + * (via intel_digital_port::hpd_pulse()) is not running. + * - The hotplug event handling (via intel_encoder::hotplug()) of an + * HPD IRQ pending at the time this function is called may be still + * running. + * - Detection on the encoder's connector (via + * drm_connector_helper_funcs::detect_ctx(), + * drm_connector_funcs::detect()) remains allowed, for instance as part of + * userspace connector probing, or DRM core's connector polling. + * + * A nested call of this function on the same encoder is not allowed. The call + * must be followed by calling intel_hpd_resume(). + * + * Note that the handling of HPD IRQs for another encoder using the same HPD + * pin as that of @encoder will be also suspended. + */ +void intel_hpd_suspend(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; + + if (encoder->hpd_pin == HPD_NONE) + return; + + spin_lock_irq(&i915->irq_lock); + + drm_WARN_ON(display->drm, BIT(encoder->port) & hotplug->suspended_port_mask); + hotplug->suspended_port_mask |= BIT(encoder->port); + + spin_unlock_irq(&i915->irq_lock); + + flush_work(&hotplug->dig_port_work); +} + +static void resume_hpd(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; + + lockdep_assert_held(&i915->irq_lock); + + drm_WARN_ON(display->drm, !(BIT(encoder->port) & hotplug->suspended_port_mask)); + hotplug->suspended_port_mask &= ~BIT(encoder->port); + + queue_work_for_missed_irqs(i915); +} + +/** + * intel_hpd_resume - Resume handling of HPD IRQs on an HPD pin + * @encoder: Encoder to resume the HPD handling for + * + * Resume the handling of HPD IRQs on the HPD pin of @encoder, which was + * previously suspended by intel_hpd_suspend(). Any HPD IRQ raised on the + * HPD pin while it was suspended will be handled for @encoder and for any + * other encoder sharing the same HPD pin. + */ +void intel_hpd_resume(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *i915 = to_i915(display->drm); + + if (encoder->hpd_pin == HPD_NONE) + return; + + spin_lock_irq(&i915->irq_lock); + resume_hpd(encoder); + spin_unlock_irq(&i915->irq_lock); +} + void intel_hpd_enable_detection_work(struct drm_i915_private *i915) { spin_lock_irq(&i915->irq_lock); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h index d6986902b0545..5180731def7cc 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug.h @@ -28,6 +28,8 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); enum hpd_pin intel_hpd_pin_default(enum port port); bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin); void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin); +void intel_hpd_suspend(struct intel_encoder *encoder); +void intel_hpd_resume(struct intel_encoder *encoder); void intel_hpd_debugfs_register(struct drm_i915_private *i915); void intel_hpd_enable_detection_work(struct drm_i915_private *i915); From patchwork Mon Feb 24 19:31:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13988855 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 9BBC5C021BB for ; Mon, 24 Feb 2025 19:30:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E7D010E4F9; Mon, 24 Feb 2025 19:30:23 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="GNPS++R2"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by gabe.freedesktop.org (Postfix) with ESMTPS id AE59510E4EA; Mon, 24 Feb 2025 19:30:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740425419; x=1771961419; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=xtfe5dSg+191jdDRD6P50pmjKSOz/8RHFr7XhIfTA9A=; b=GNPS++R2VbjbJl8vVHyuFa51OziJTAh17vzJWipYOq0D9yZhsDn86D3Q pqscjg1ZfFZfAawfYXP4EgVG85baPy/Geqd/hyElXkH5OTH5F8m+QeEEi 9VNuZMS0saF8hZPBz8f/6LhavCxpEgrCYV+fxldu1EtdQbbplNa5Uguna taO8doOkxS/0B/GsEOBNZ6HAD+94M5j4AXIk4wkFqzH8Hd/dI8FUGhsPj ANBOBLnJyznEEhOcz6dWL4RZY5M0Ka1p2CCXEkznEvY1aMxYVy+/vhCjt Fqi6lPrnPNwvGNMHfiUEqIEEmC66cVwhhohVTvzqhK14neCxz5cyM+yXY w==; X-CSE-ConnectionGUID: dXQVvVA0SA+zvEE9p4fR9w== X-CSE-MsgGUID: G7E5yw9YSfKcd0acN2f2ZQ== X-IronPort-AV: E=McAfee;i="6700,10204,11355"; a="40388255" X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="40388255" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:18 -0800 X-CSE-ConnectionGUID: ujh0qLnvQl21JbHumuZVDw== X-CSE-MsgGUID: DasQsEZsT0en5lyLyLrW1g== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="116169056" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:17 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 3/5] drm/i915/dp: Fix link training interrupted by a short HPD pulse Date: Mon, 24 Feb 2025 21:31:13 +0200 Message-ID: <20250224193115.2058512-4-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20250224193115.2058512-1-imre.deak@intel.com> References: <20250224193115.2058512-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" During Display Port link training the handling of HPD pulses should be prevented, as that handling can interfere with the link training: - Accessing DPCD registers outside the range of link training registers are not allowed by the Standard (see DP Standard v2.1, 3.5.2.16.1, 3.6.6.1). The pulse handler reads the DPRX capability registers, which are outside of the allowed range. - Switching of the LTTPR transparent/non-transparent mode may reset the LTTPRs on the link, thus aborting any ongoing link training. The pulse handler does set the LTTPR mode, thus it could unexpectedly abort the ongoing link training. Suspend/resume the HPD pulse handling for the duration of the link training to prevent the above DPCD register accesses / LTTPR mode change. Apart from the above scenarios, there are other ways a non-link training DPCD register could be accessed during link training: via the DRM AUX device node, or via DPCD register probing (as performed by drm_dp_dpcd_probe()). These will be addressed by a follow-up change. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 11953b03bb6aa..1519c202bf8c1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1123,6 +1123,8 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp, void intel_dp_stop_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + intel_dp->link_trained = true; intel_dp_disable_dpcd_training_pattern(intel_dp, DP_PHY_DPRX); @@ -1133,6 +1135,8 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, wait_for(intel_dp_128b132b_intra_hop(intel_dp, crtc_state) == 0, 500)) { lt_dbg(intel_dp, DP_PHY_DPRX, "128b/132b intra-hop not clearing\n"); } + + intel_hpd_resume(encoder); } static bool @@ -1615,7 +1619,11 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, * non-transparent mode. During an earlier LTTPR detection this * could've been prevented by an active link. */ - int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); + int lttpr_count; + + intel_hpd_suspend(encoder); + + lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp); if (lttpr_count < 0) /* Still continue with enabling the port and link training. */ From patchwork Mon Feb 24 19:31:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13988856 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 4F408C021BE for ; Mon, 24 Feb 2025 19:30:24 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 48EFD10E4FA; Mon, 24 Feb 2025 19:30:23 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="hZHd3C4Z"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by gabe.freedesktop.org (Postfix) with ESMTPS id B075110E4F0; Mon, 24 Feb 2025 19:30:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740425420; x=1771961420; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=F2ndRzzv9RdxqB4+mjAP/ULX7oQx30cTeJS9NGvP7H8=; b=hZHd3C4ZtWuPqv9czM5FQ5K0p4eeTPvYfyoWOiQRTE6yum+Ndbi+4XS3 XUk0vM810fUIIkADZQlql27sUfMVHUGvarmywbK41tu2MFzlNOvTqJ1TI 3EEPzK4yWPv6saZiGUJoJJ3PTevZd3GqQSMYr3UYeiNKEPgt1gutZJS4o TDSI/ltzQws6CiVWiaoJ1XFolpaHr6pTPYw0Yzfr95OISSnsDzopaPpO4 +YjrmpNwoCoCyHfELZyIywJBBvMdausYqpWpJaEx57bg3PmHN3tu4ZAo7 U3eDH9kuifxkklKO59+fCGFIfkunKMEy2sIM/jq/xi6lQE69/4PN1vZOB Q==; X-CSE-ConnectionGUID: abMpEObWTH+yo0zYmwsfiQ== X-CSE-MsgGUID: 7jx1pzH+SvO/8hC/YiV/5Q== X-IronPort-AV: E=McAfee;i="6700,10204,11355"; a="40388257" X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="40388257" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:20 -0800 X-CSE-ConnectionGUID: f0L/E0/8TEKCyojPNkJf1Q== X-CSE-MsgGUID: tjN55mGjSJGrrCCsFnqXGQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="116169062" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:18 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 4/5] drm/i915/dp: Queue a link check after link training is complete Date: Mon, 24 Feb 2025 21:31:14 +0200 Message-ID: <20250224193115.2058512-5-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20250224193115.2058512-1-imre.deak@intel.com> References: <20250224193115.2058512-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" After link training - both in case of a passing and failing LT result - a work is scheduled to check the link state. This check should take place after the link training is completed by disabling the link training pattern and setting intel_dp::link_trained=true. Atm, the work is scheduled before these steps, which may result in checking the link state too early (and thus not retraining the link as expected). Fix the above by scheduling the link check work after link training is complete. Signed-off-by: Imre Deak --- .../gpu/drm/i915/display/intel_dp_link_training.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 1519c202bf8c1..75bc7cde8165e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1123,6 +1123,7 @@ intel_dp_128b132b_intra_hop(struct intel_dp *intel_dp, void intel_dp_stop_link_train(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct intel_display *display = to_intel_display(intel_dp); struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; intel_dp->link_trained = true; @@ -1137,6 +1138,13 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp, } intel_hpd_resume(encoder); + + if (!display->hotplug.ignore_long_hpd && + intel_dp->link.seq_train_failures < 2) { + int delay_ms = intel_dp->link.seq_train_failures ? 0 : 2000; + + intel_encoder_link_check_queue_work(encoder, delay_ms); + } } static bool @@ -1641,7 +1649,6 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, lt_dbg(intel_dp, DP_PHY_DPRX, "Forcing link training failure\n"); } else if (passed) { intel_dp->link.seq_train_failures = 0; - intel_encoder_link_check_queue_work(encoder, 2000); return; } @@ -1664,10 +1671,8 @@ void intel_dp_start_link_train(struct intel_atomic_state *state, return; } - if (intel_dp->link.seq_train_failures < 2) { - intel_encoder_link_check_queue_work(encoder, 0); + if (intel_dp->link.seq_train_failures < 2) return; - } if (intel_dp_schedule_fallback_link_training(state, intel_dp, crtc_state)) return; From patchwork Mon Feb 24 19:31:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Imre Deak X-Patchwork-Id: 13988854 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 13D3EC19778 for ; Mon, 24 Feb 2025 19:30:23 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ACEB710E4F5; Mon, 24 Feb 2025 19:30:22 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="cjvV5B15"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.19]) by gabe.freedesktop.org (Postfix) with ESMTPS id C77A210E4F0; Mon, 24 Feb 2025 19:30:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1740425421; x=1771961421; h=from:to:subject:date:message-id:in-reply-to:references: mime-version:content-transfer-encoding; bh=3gcIcvRn2Sv0EOGAD5LxzInHy74eMpMhxMlAs9dfYN8=; b=cjvV5B151cX2bajpv65HQ3P91WUSJt12Edp90bGogOILJu9aKiyV+z61 905RSLcgK1MUrB8ONzkOZZT6bPXxCaXaTurTJPQ4sWnxPJcI/T9493rAH 0iqN7Z2tv9USeGu+NSO5sRnCjDOIjn26jbSF/GxCGrju/rwTwsUpvK8Wh eMEd32Lak2rntQ5p8jv7fToyK77PmM5QdpUyr13RSbVnUq3fqjHWoIsA/ iCbO6lwrKJD5BV0nJ1srTypy6/LS+4CkNeVIPK6x5lKKLK1yfGCLrv2xt IqCmzz5WEI0oOp+MECMTlPZSSCW03Cz1nDr7mNFgm740LH1SiHcucLcxp g==; X-CSE-ConnectionGUID: otrD6Ni7TSW5HxQwK0JDug== X-CSE-MsgGUID: TG8ExbzaQr2MpLwcBEEyKQ== X-IronPort-AV: E=McAfee;i="6700,10204,11355"; a="40388259" X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="40388259" Received: from fmviesa007.fm.intel.com ([10.60.135.147]) by fmvoesa113.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:21 -0800 X-CSE-ConnectionGUID: rDPKIb2TSVq9kojPC4Q6eg== X-CSE-MsgGUID: UGkQSsDiQnC9m4b1sYrUGw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.13,312,1732608000"; d="scan'208";a="116169066" Received: from ideak-desk.fi.intel.com ([10.237.72.78]) by fmviesa007-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Feb 2025 11:30:19 -0800 From: Imre Deak To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Subject: [PATCH 5/5] drm/i915/crt: Use intel_hpd_suspend/resume() instead of intel_hpd_disable/enable() Date: Mon, 24 Feb 2025 21:31:15 +0200 Message-ID: <20250224193115.2058512-6-imre.deak@intel.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20250224193115.2058512-1-imre.deak@intel.com> References: <20250224193115.2058512-1-imre.deak@intel.com> MIME-Version: 1.0 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" intel_hpd_disable/enable() have the same purpose as intel_hpd_suspend/resume(), except that disable/enable will drop any HPD IRQs which were triggered while the HPD was disabled, while suspend/resume will handle such IRQs after the IRQ handling is resumed. Use intel_hpd_suspend/resume() for crt as well, by adding a helper to explicitly clear any pending IRQs before resuming. Signed-off-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_crt.c | 7 +-- drivers/gpu/drm/i915/display/intel_hotplug.c | 59 ++++++++++---------- drivers/gpu/drm/i915/display/intel_hotplug.h | 3 +- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 321580b095e7d..67b6731d7cdd2 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -531,8 +531,6 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) { struct intel_display *display = to_intel_display(connector->dev); struct intel_crt *crt = intel_attached_crt(to_intel_connector(connector)); - struct drm_i915_private *dev_priv = to_i915(connector->dev); - bool reenable_hpd; u32 adpa; bool ret; u32 save_adpa; @@ -549,7 +547,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) * * Just disable HPD interrupts here to prevent this */ - reenable_hpd = intel_hpd_disable(dev_priv, crt->base.hpd_pin); + intel_hpd_suspend(&crt->base); save_adpa = adpa = intel_de_read(display, crt->adpa_reg); drm_dbg_kms(display->drm, @@ -576,8 +574,7 @@ static bool valleyview_crt_detect_hotplug(struct drm_connector *connector) drm_dbg_kms(display->drm, "valleyview hotplug adpa=0x%x, result %d\n", adpa, ret); - if (reenable_hpd) - intel_hpd_enable(dev_priv, crt->base.hpd_pin); + intel_hpd_clear_and_resume(&crt->base); return ret; } diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c b/drivers/gpu/drm/i915/display/intel_hotplug.c index 81f2be06bc2a1..501d9ff588355 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.c +++ b/drivers/gpu/drm/i915/display/intel_hotplug.c @@ -1008,33 +1008,6 @@ void intel_hpd_cancel_work(struct drm_i915_private *dev_priv) drm_dbg_kms(&dev_priv->drm, "Hotplug detection work still active\n"); } -bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin) -{ - bool ret = false; - - if (pin == HPD_NONE) - return false; - - spin_lock_irq(&dev_priv->irq_lock); - if (dev_priv->display.hotplug.stats[pin].state == HPD_ENABLED) { - dev_priv->display.hotplug.stats[pin].state = HPD_DISABLED; - ret = true; - } - spin_unlock_irq(&dev_priv->irq_lock); - - return ret; -} - -void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin) -{ - if (pin == HPD_NONE) - return; - - spin_lock_irq(&dev_priv->irq_lock); - dev_priv->display.hotplug.stats[pin].state = HPD_ENABLED; - spin_unlock_irq(&dev_priv->irq_lock); -} - static void queue_work_for_missed_irqs(struct drm_i915_private *i915) { struct intel_display *display = to_intel_display(&i915->drm); @@ -1088,7 +1061,8 @@ static void queue_work_for_missed_irqs(struct drm_i915_private *i915) * userspace connector probing, or DRM core's connector polling. * * A nested call of this function on the same encoder is not allowed. The call - * must be followed by calling intel_hpd_resume(). + * must be followed by calling intel_hpd_resume(), or + * intel_hpd_clear_and_resume(). * * Note that the handling of HPD IRQs for another encoder using the same HPD * pin as that of @encoder will be also suspended. @@ -1148,6 +1122,35 @@ void intel_hpd_resume(struct intel_encoder *encoder) spin_unlock_irq(&i915->irq_lock); } +/** + * intel_hpd_clear_and_resume - Resume handling of new HPD IRQs on an HPD pin + * @encoder: Encoder to resume the HPD handling for + * + * Resume the handling of HPD IRQs on the HPD pin of @encoder, which was + * previously suspended by intel_hpd_suspend(). Any HPD IRQ raised on the + * HPD pin while it was suspended will be cleared, handling only new IRQs. + */ +void intel_hpd_clear_and_resume(struct intel_encoder *encoder) +{ + struct intel_display *display = to_intel_display(encoder); + struct drm_i915_private *i915 = to_i915(display->drm); + struct intel_hotplug *hotplug = &display->hotplug; + + if (encoder->hpd_pin == HPD_NONE) + return; + + spin_lock_irq(&i915->irq_lock); + + hotplug->event_bits &= ~BIT(encoder->hpd_pin); + hotplug->retry_bits &= ~BIT(encoder->hpd_pin); + hotplug->short_port_mask &= ~BIT(encoder->port); + hotplug->long_port_mask &= ~BIT(encoder->port); + + resume_hpd(encoder); + + spin_unlock_irq(&i915->irq_lock); +} + void intel_hpd_enable_detection_work(struct drm_i915_private *i915) { spin_lock_irq(&i915->irq_lock); diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h b/drivers/gpu/drm/i915/display/intel_hotplug.h index 5180731def7cc..0a4d1af0e42f1 100644 --- a/drivers/gpu/drm/i915/display/intel_hotplug.h +++ b/drivers/gpu/drm/i915/display/intel_hotplug.h @@ -26,10 +26,9 @@ void intel_hpd_init(struct drm_i915_private *dev_priv); void intel_hpd_init_early(struct drm_i915_private *i915); void intel_hpd_cancel_work(struct drm_i915_private *dev_priv); enum hpd_pin intel_hpd_pin_default(enum port port); -bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin); -void intel_hpd_enable(struct drm_i915_private *dev_priv, enum hpd_pin pin); void intel_hpd_suspend(struct intel_encoder *encoder); void intel_hpd_resume(struct intel_encoder *encoder); +void intel_hpd_clear_and_resume(struct intel_encoder *encoder); void intel_hpd_debugfs_register(struct drm_i915_private *i915); void intel_hpd_enable_detection_work(struct drm_i915_private *i915);