From patchwork Wed Aug 26 01:49:06 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: An Wu X-Patchwork-Id: 2292327 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4hV6yj634Sz1xtN for ; Wed, 26 Aug 2026 11:49:33 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1wz2la-0005YP-Qo; Wed, 26 Aug 2026 01:49:26 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1wz2lZ-0005XD-1e for kernel-team@lists.ubuntu.com; Wed, 26 Aug 2026 01:49:25 +0000 Received: from mail-pj1-f72.google.com (mail-pj1-f72.google.com [209.85.216.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id E3D3C3F131 for ; Wed, 26 Aug 2026 01:49:24 +0000 (UTC) Received: by mail-pj1-f72.google.com with SMTP id 98e67ed59e1d1-38ff2cd7b76so127330a91.2 for ; Tue, 25 Aug 2026 18:49:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787708963; x=1788313763; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Yn9trGHhzld3SPaKfmKGybaWw/EaolOK+m9crnd2Wfo=; b=s/WgdsU0KGuOkwkKKoOZvyv2saEJhDzcogJVDLR+KlfyTp3upPCZZtb+Neq4t8sCYt YAujxskWEgpIVu/pd8E03yxIKvx9FbymRv0dOnKbpN7nfGBdAQ61JRQzeMEHBF85BqFl i3y3SjOlTe8NJV7oUMWBe0BqBUDbYbdWH4CUlT+uaouCrE4WYWbqnMSH5HziGSB62YHn YqdkKv02+Vj4LxYepgLTUWljVx6nEtt5joGQcsBURKfR06ynJmgWV/au07rr3PUF0d3v do4scZAJV07CaE2yqje8SjOcnFe6USGH1qqkIKOdtERgCkQag5hvMknksO2c0gh+N7mQ C52w== X-Gm-Message-State: AFuF++mbiUKSYVNxLCN9Wqls6i5DrnpmUkNc7fNEm9Bsxpw7uZ9/6XnD jf+k8ShFFn16irD8IU4EuaJ7nqOHOjcKvVTXmmqYZkAnXjKUr//A7lxwxxTDSYRnQyoD2CIIhzo Qtt5hX8f2iOAozlTIm0X9KPEvvwpiLIhQBzwEP9bOzLuI36x09cU4T5tmLFFXzM7QkBpnDXDQTf V/T7I8syvBNxE3usNN X-Gm-Gg: AR+sD120vMrq8jwaUURzDsM/qOuezSLHOBXmYrliatiN5TbPsVvSyFvU1QE1Ecr6lYM zoP3g32as/K09KDX5od3tyrAnj1/yr7WzdYe8NLXTAliGCv9PAtuviT0UCp9n5BsqlftcCQtU+r DAJmooi3K0zL+adAidB+2OF8v6KeBrwEY5IdF4auLMF+v+Zfpa2L760cNVHMlnaE5/8Qj3ZNuN+ mi8B8IXhvvKDC+2fpz3tg3azOMFx+Cg/VZ8unDiwGIK6l4M/PdOJ4i6XgsqpuGWz5uwx5JiP8zN /8qU4lzySbOJLxzjrIqlbdBUMI9VyskEMjHvM6ehLq7yJna5kHHjOlLGZxG6CYNZ6t/xODn23PK s9rMBD0HEsb9RhX931zOB18eWZHG0ZDDUgK9vgeCHFfc/dcABS42hinqLGBDKLokUZYtd6xkPy3 6bOpmgfuKipIO+7G2ReAZBNFNzu5K04DIJwPl5Kjqitj/HnnopGByTHI1yFU9+HW0STwY/HsS6F Bmo2l9BHdvoTZs+m5RDmSFq7OHq9H5ZuWIC+QIQT2ze X-Received: by 2002:a17:903:3bd0:b0:2cc:f4d4:29a0 with SMTP id d9443c01a7336-2d707b6aa0bmr21255495ad.3.1787708963409; Tue, 25 Aug 2026 18:49:23 -0700 (PDT) X-Received: by 2002:a17:903:3bd0:b0:2cc:f4d4:29a0 with SMTP id d9443c01a7336-2d707b6aa0bmr21255225ad.3.1787708963030; Tue, 25 Aug 2026 18:49:23 -0700 (PDT) Received: from an-XPS-15-9520.buildd (2001-b011-2008-e559-5718-5b76-35fc-d292.dynamic-ip6.hinet.net. [2001:b011:2008:e559:5718:5b76:35fc:d292]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2d70493dfc0sm2961035ad.14.2026.08.25.18.49.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 25 Aug 2026 18:49:22 -0700 (PDT) To: kernel-team@lists.ubuntu.com Subject: [SRU][J:linux-hwe-6.8][PATCH v2 2/2] drm/i915/display: Handle dedicated external ports in intel_encoder_is_tc() Date: Wed, 26 Aug 2026 09:49:06 +0800 Message-Id: <20260826014906.1472193-3-an.wu@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260826014906.1472193-1-an.wu@canonical.com> References: <20260826014906.1472193-1-an.wu@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: ChunAn Wu via kernel-team From: An Wu Reply-To: ChunAn Wu Cc: paolo.gentili@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" BugLink: https://bugs.launchpad.net/bugs/2164507 Starting with Xe3p_LPD, the VBT has a new field, called in the driver "dedicated_external", which tells that a Type-C capable port is physically connected to a PHY outside of the Type-C subsystem. When that's the case, the driver must not do the extra Type-C programming for that port. Update intel_encoder_is_tc() to check for that case. While at it, add a note to intel_phy_is_tc() to remind us that it is about whether the respective port is a Type-C capable port rather than the PHY itself. (Maybe it would be a nice idea to rename intel_phy_is_tc()?) Note that this was handled with a new bool member added to struct intel_digital_port instead of having querying the VBT directly because VBT memory is freed (intel_bios_driver_remove) before encoder cleanup (intel_ddi_encoder_destroy), which would cause an oops to happen when the latter calls intel_encoder_is_tc(). This could be fixed by keeping VBT data around longer, but that's left for a follow-up work, if deemed necessary. v2: - Drop printing info about dedicated external, now that we are doing it when parsing the VBT. (Jani) - Add a FIXME comment on the code explaining why we need to store dedicated_external in struct intel_digital_port. (Jani) v3: - Simplify the code by using NULL check for dig_port to avoid using intel_encoder_is_dig_port(). (Imre) Cc: Imre Deak Cc: Jani Nikula Cc: Shekhar Chauhan Signed-off-by: Gustavo Sousa Reviewed-by: Imre Deak Link: https://patch.msgid.link/20251202012306.9315-4-matthew.s.atwood@intel.com Signed-off-by: Matt Roper (backported from commit df5dd52a6de486e32576ac5851b4e9429182274b) [an: adjusted context for Jammy 6.8 and added guards for the observed 6.8 shutdown panic path where intel_phy_is_tc() is true but dig_port->tc is NULL. Without these guards, fbcon restore during shutdown can still enter TC mode/DPLL handling and dereference dig_port->tc.] Signed-off-by: ChunAn Wu --- drivers/gpu/drm/i915/display/intel_ddi.c | 11 +++++++++++ drivers/gpu/drm/i915/display/intel_display.c | 4 ++++ .../gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 15 +++++++++++++-- drivers/gpu/drm/i915/display/intel_tc.c | 2 +- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 2a506489d030..8a5122f6e20d 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4951,6 +4951,17 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, encoder = &dig_port->base; encoder->devdata = devdata; + /* + * FIXME: We currently need to store dedicated_external because devdata + * does not live long enough for when intel_encoder_is_tc() is called on + * the unbind path. This needs to be fixed by making sure that the VBT + * data is kept long enough, so that + * intel_bios_encoder_is_dedicated_external() can be called directly + * from intel_encoder_is_tc(). + */ + if (intel_bios_encoder_is_dedicated_external(devdata)) + dig_port->dedicated_external = true; + if (DISPLAY_VER(dev_priv) >= 13 && port >= PORT_D_XELPD) { drm_encoder_init(&dev_priv->drm, &encoder->base, &intel_ddi_funcs, DRM_MODE_ENCODER_TMDS, diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index d50f4a170746..cb7ed0c2d121 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1940,6 +1940,10 @@ bool intel_encoder_is_snps(struct intel_encoder *encoder) bool intel_encoder_is_tc(struct intel_encoder *encoder) { struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + + if (dig_port && dig_port->dedicated_external) + return false; return intel_phy_is_tc(i915, intel_encoder_to_phy(encoder)); } diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 9910860c7eb1..ad09ad13f762 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1875,6 +1875,7 @@ struct intel_digital_port { struct intel_lspcon lspcon; enum irqreturn (*hpd_pulse)(struct intel_digital_port *, bool); bool release_cl2_override; + bool dedicated_external; u8 max_lanes; /* Used for DP and ICL+ TypeC/DP and TypeC/HDMI ports. */ enum aux_ch aux_ch; diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index fa4a142b4369..a50de7bb162b 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -3386,6 +3386,13 @@ static int icl_get_tc_phy_dplls(struct intel_atomic_state *state, return ret; } +static bool icl_encoder_has_tc_port(struct intel_encoder *encoder) +{ + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + + return dig_port && dig_port->tc; +} + static int icl_compute_dplls(struct intel_atomic_state *state, struct intel_crtc *crtc, struct intel_encoder *encoder) @@ -3395,8 +3402,10 @@ static int icl_compute_dplls(struct intel_atomic_state *state, if (intel_phy_is_combo(i915, phy)) return icl_compute_combo_phy_dpll(state, crtc); - else if (intel_phy_is_tc(i915, phy)) + else if (intel_phy_is_tc(i915, phy) && icl_encoder_has_tc_port(encoder)) return icl_compute_tc_phy_dplls(state, crtc); + else if (intel_phy_is_tc(i915, phy)) + return icl_compute_combo_phy_dpll(state, crtc); MISSING_CASE(phy); @@ -3412,8 +3421,10 @@ static int icl_get_dplls(struct intel_atomic_state *state, if (intel_phy_is_combo(i915, phy)) return icl_get_combo_phy_dpll(state, crtc, encoder); - else if (intel_phy_is_tc(i915, phy)) + else if (intel_phy_is_tc(i915, phy) && icl_encoder_has_tc_port(encoder)) return icl_get_tc_phy_dplls(state, crtc, encoder); + else if (intel_phy_is_tc(i915, phy)) + return icl_get_combo_phy_dpll(state, crtc, encoder); MISSING_CASE(phy); diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2fce14389787..de226e00fd08 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -105,7 +105,7 @@ static bool intel_tc_port_in_mode(struct intel_digital_port *dig_port, enum phy phy = intel_port_to_phy(i915, dig_port->base.port); struct intel_tc_port *tc = to_tc_port(dig_port); - return intel_phy_is_tc(i915, phy) && tc->mode == mode; + return intel_phy_is_tc(i915, phy) && tc && tc->mode == mode; } bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port)