From patchwork Fri Mar 21 11:26:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nautiyal, Ankit K" X-Patchwork-Id: 14025304 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 3019BC36007 for ; Fri, 21 Mar 2025 11:38:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BD2AE10E7B1; Fri, 21 Mar 2025 11:38:44 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="GOioCtoF"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by gabe.freedesktop.org (Postfix) with ESMTPS id 017A510E7B1; Fri, 21 Mar 2025 11:38:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1742557124; x=1774093124; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=I5q478wa3OvyU7RMmiNhEeYg4gnk3EXQFENI6jGTgfU=; b=GOioCtoFSDvnD9PjsDrPWJ4S2OXft1Cx7NDJ4NIZTvmjlwSnLpyCwAAw Hn0q94ykSwp06+/xmvwrKNG5x2WgSsTDieekO3yI0ZP7wye/GQGNOd8kE FtyyZSwlG5xszGYn1Y0PsJa8VYGwVT9ylqkKoN/sg2B8PdDWKuP8bxn8l AqxSV7ZqmEmZOHn5eS96T41RofB9BRp7WkwqmixuVZFGw4uKExcptLvRe vsb8kvi1x5M+vncL7b7OmzARNanFeBQZk9eAIfkyRyzSitSsRo4KPQvtE q/cIyXy66G4IaghdrDDhm8Hvy3Ab/sdIQLhOQMuimeHHIMqNjmGM2zn6s g==; X-CSE-ConnectionGUID: UwXKgDkDSz+DQ4qyMAs0Yw== X-CSE-MsgGUID: shPEZk8xTg+3oGNkDXAuUw== X-IronPort-AV: E=McAfee;i="6700,10204,11379"; a="61216881" X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="61216881" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:44 -0700 X-CSE-ConnectionGUID: C29PEXnkS1mHbZhmz1Aa6Q== X-CSE-MsgGUID: By9oHiMNSTOpWcrhG1d9Rw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="128206569" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:42 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Cc: jani.nikula@linux.intel.com, uma.shankar@intel.com Subject: [PATCH 1/4] Add bits for link_n_exended for DISPLAY >= 14 Date: Fri, 21 Mar 2025 16:56:47 +0530 Message-ID: <20250321112650.3594298-2-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250321112650.3594298-1-ankit.k.nautiyal@intel.com> References: <20250321112650.3594298-1-ankit.k.nautiyal@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" LINK_N register has bits 31:24 for extended link N value used for HDMI2.1 and for an alternate mode of operation of DP TG DDA (Bspec:50488). Add support for these extra bits. For displays with version 14 or higher, the `PIPE_LINK_N1_EXTENDED_MASK` (bits 31:24) is used to handle the extended link N bits. For older platforms, the `DATA_LINK_M_N_MASK` (bits 23:0) is used to handle the standard link N bits. This distinction ensures clarity and maintains the semantics for platforms that support the extended bits. In subsequent changes the logic is updated to conditionally apply the extended link N bits. v2: Drop extra link_n_ext member. (Jani) v3: Avoid link_n_ext in set_m_n helper. (Jani) v4: Rebase, and update commit message. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 18 ++++++++++++++++-- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3afb85fe8536..8fb0df388571 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2583,14 +2583,22 @@ void intel_set_m_n(struct intel_display *display, i915_reg_t data_m_reg, i915_reg_t data_n_reg, i915_reg_t link_m_reg, i915_reg_t link_n_reg) { + u32 link_n = m_n->link_n; + intel_de_write(display, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m); intel_de_write(display, data_n_reg, m_n->data_n); intel_de_write(display, link_m_reg, m_n->link_m); + + if (DISPLAY_VER(display) >= 14) + link_n &= ~PIPE_LINK_N1_EXTENDED_MASK; + else + link_n &= DATA_LINK_M_N_MASK; + /* * On BDW+ writing LINK_N arms the double buffered update * of all the M/N registers, so it must be written last. */ - intel_de_write(display, link_n_reg, m_n->link_n); + intel_de_write(display, link_n_reg, link_n); } bool intel_cpu_transcoder_has_m2_n2(struct intel_display *display, @@ -3279,7 +3287,13 @@ void intel_get_m_n(struct intel_display *display, i915_reg_t link_m_reg, i915_reg_t link_n_reg) { m_n->link_m = intel_de_read(display, link_m_reg) & DATA_LINK_M_N_MASK; - m_n->link_n = intel_de_read(display, link_n_reg) & DATA_LINK_M_N_MASK; + m_n->link_n = intel_de_read(display, link_n_reg); + + if (DISPLAY_VER(display) >= 14) + m_n->link_n &= ~PIPE_LINK_N1_EXTENDED_MASK; + else + m_n->link_n &= DATA_LINK_M_N_MASK; + m_n->data_m = intel_de_read(display, data_m_reg) & DATA_LINK_M_N_MASK; m_n->data_n = intel_de_read(display, data_n_reg) & DATA_LINK_M_N_MASK; m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(display, data_m_reg)) + 1; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c5064eebe063..a2054aced4f8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1869,6 +1869,8 @@ #define _PIPEA_LINK_N1 0x60044 #define _PIPEB_LINK_N1 0x61044 +#define PIPE_LINK_N1_EXTENDED_MASK REG_GENMASK(31, 24) +#define PIPE_LINK_N1_EXTENDED(val) REG_FIELD_PREP(PIPE_LINK_N1_EXTENDED_MASK, (val)) #define PIPE_LINK_N1(dev_priv, tran) _MMIO_TRANS2(dev_priv, tran, _PIPEA_LINK_N1) #define _PIPEA_LINK_M2 0x60048 From patchwork Fri Mar 21 11:26:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nautiyal, Ankit K" X-Patchwork-Id: 14025305 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 00B7BC36002 for ; Fri, 21 Mar 2025 11:38:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 97E8310E7B3; Fri, 21 Mar 2025 11:38:48 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="kzeafuRV"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0DE0210E7B2; Fri, 21 Mar 2025 11:38:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1742557126; x=1774093126; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uDQB4LTiSXe5/Uyfxwuog28DxZlLLQ/q4vV4GYlrnVQ=; b=kzeafuRVC9HFH5oZfOvFkuMear9q1m8vQSO/jFBHLGuKadlVdnI4W3gU E2pY44QgPb6u7C24JXIEa9DJ4RV015RGZg5Cu/0BvUkV0MHxvqdnj237j OYBUPKp4CzFKqcgk2CmKwCB3Fv0lGOVGyG3+SWnGBRcQiNZFGaABLzdfX MP1OolM1QMgUcH9YoL3nH2sAdwt6aWBTVkxO/Y0iSRZLPqfZx2euIxGN1 gSi3ecp63buQbjoUWcOMgOIi65WnfqTFSKWc9kTf0UmGgfxYtFncbW/JW HZxa2z8zMWK58VePFcusyjqZ17JFSGHCfyK3mzZfPo3vB+YK7Pc7Hb+ct A==; X-CSE-ConnectionGUID: 5x0JjcWOQRe0a+SDJi5JUw== X-CSE-MsgGUID: MnKwwJ9WTb+9+N+XNaw+iA== X-IronPort-AV: E=McAfee;i="6700,10204,11379"; a="61216883" X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="61216883" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:46 -0700 X-CSE-ConnectionGUID: zjfwR0P2T1GGhCVKEGUG/g== X-CSE-MsgGUID: KPgWh+XYTeKCPRXAVKsK9w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="128206586" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:44 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Cc: jani.nikula@linux.intel.com, uma.shankar@intel.com Subject: [PATCH 2/4] drm/i915/display: Limit m/n ratio to 10 for display > 12 Date: Fri, 21 Mar 2025 16:56:48 +0530 Message-ID: <20250321112650.3594298-3-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250321112650.3594298-1-ankit.k.nautiyal@intel.com> References: <20250321112650.3594298-1-ankit.k.nautiyal@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" As per Bspec:49266 for DISPLAY > 12 which support higher link rates have a limitation: If the CEILING( Link M / Link N ) ratio is greater than 10.0, then hardware cannot support the given resolution / refresh rate at the given configuration. Modify the helper to compute m_n, to check for the max link_m/n ratio for the given platforms, and return error code in case the resolution/refresh rate is not supported. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 32 +++++++++++++++-- drivers/gpu/drm/i915/display/intel_display.h | 9 ++--- drivers/gpu/drm/i915/display/intel_dp.c | 37 +++++++++++++------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 32 ++++++++++------- drivers/gpu/drm/i915/display/intel_fdi.c | 14 ++++---- 5 files changed, 85 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8fb0df388571..c50dce9afd9b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2518,8 +2518,15 @@ static void compute_m_n(u32 *ret_m, u32 *ret_n, intel_reduce_m_n_ratio(ret_m, ret_n); } -void -intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes, +static int +get_max_link_m_n_ratio(void) +{ + return 10; +} + +int +intel_link_compute_m_n(struct intel_display *display, + u16 bits_per_pixel_x16, int nlanes, int pixel_clock, int link_clock, int bw_overhead, struct intel_link_m_n *m_n) @@ -2528,6 +2535,7 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes, u32 data_m = intel_dp_effective_data_rate(pixel_clock, bits_per_pixel_x16, bw_overhead); u32 data_n = drm_dp_max_dprx_data_rate(link_clock, nlanes); + int link_m_n_ratio, max_link_m_n_ratio; /* * Windows/BIOS uses fixed M/N values always. Follow suit. @@ -2544,6 +2552,26 @@ intel_link_compute_m_n(u16 bits_per_pixel_x16, int nlanes, compute_m_n(&m_n->link_m, &m_n->link_n, pixel_clock, link_symbol_clock, 0x80000); + + if (DISPLAY_VER(display) < 12) + return 0; + + /* Check for Link M/N ratio for Display >= 12 */ + max_link_m_n_ratio = get_max_link_m_n_ratio(); + + if (!m_n->link_n) + return -EINVAL; + + link_m_n_ratio = DIV_ROUND_UP(m_n->link_m, m_n->link_n); + + if (link_m_n_ratio > max_link_m_n_ratio) { + drm_dbg_kms(display->drm, + "Cannot support Link_m/Link_n ratio : %d > %d\n", + link_m_n_ratio, max_link_m_n_ratio); + return -EINVAL; + } + + return 0; } void intel_panel_sanitize_ssc(struct intel_display *display) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 3b54a62c290a..7a33c57d5abe 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -413,10 +413,6 @@ enum phy_fia { int intel_atomic_check(struct drm_device *dev, struct drm_atomic_state *state); u8 intel_calc_active_pipes(struct intel_atomic_state *state, u8 active_pipes); -void intel_link_compute_m_n(u16 bpp, int nlanes, - int pixel_clock, int link_clock, - int bw_overhead, - struct intel_link_m_n *m_n); u32 intel_plane_fb_max_stride(struct drm_device *drm, u32 pixel_format, u64 modifier); enum drm_mode_status @@ -573,5 +569,10 @@ bool assert_port_valid(struct intel_display *display, enum port port); bool intel_scanout_needs_vtd_wa(struct intel_display *display); int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state); +int intel_link_compute_m_n(struct intel_display *display, + u16 bpp, int nlanes, + int pixel_clock, int link_clock, + int bw_overhead, + struct intel_link_m_n *m_n); #endif diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a236b5fc7a3d..49a8f105ba26 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2937,7 +2937,7 @@ static bool can_enable_drrs(struct intel_connector *connector, intel_panel_drrs_type(connector) == DRRS_TYPE_SEAMLESS; } -static void +static int intel_dp_drrs_compute_config(struct intel_connector *connector, struct intel_crtc_state *pipe_config, int link_bpp_x16) @@ -2946,6 +2946,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, const struct drm_display_mode *downclock_mode = intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode); int pixel_clock; + int ret; /* * FIXME all joined pipes share the same transcoder. @@ -2957,7 +2958,7 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, if (!can_enable_drrs(connector, pipe_config, downclock_mode)) { if (intel_cpu_transcoder_has_m2_n2(display, pipe_config->cpu_transcoder)) intel_zero_m_n(&pipe_config->dp_m2_n2); - return; + return 0; } if (display->platform.ironlake || display->platform.sandybridge || @@ -2970,14 +2971,18 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, if (pipe_config->splitter.enable) pixel_clock /= pipe_config->splitter.link_count; - intel_link_compute_m_n(link_bpp_x16, pipe_config->lane_count, pixel_clock, - pipe_config->port_clock, - intel_dp_bw_fec_overhead(pipe_config->fec_enable), - &pipe_config->dp_m2_n2); + ret = intel_link_compute_m_n(display, link_bpp_x16, pipe_config->lane_count, pixel_clock, + pipe_config->port_clock, + intel_dp_bw_fec_overhead(pipe_config->fec_enable), + &pipe_config->dp_m2_n2); + if (ret) + return ret; /* FIXME: abstract this better */ if (pipe_config->splitter.enable) pipe_config->dp_m2_n2.data_m *= pipe_config->splitter.link_count; + + return 0; } static bool intel_dp_has_audio(struct intel_encoder *encoder, @@ -3176,12 +3181,14 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_dp_audio_compute_config(encoder, pipe_config, conn_state); if (!intel_dp_is_uhbr(pipe_config)) { - intel_link_compute_m_n(link_bpp_x16, - pipe_config->lane_count, - adjusted_mode->crtc_clock, - pipe_config->port_clock, - intel_dp_bw_fec_overhead(pipe_config->fec_enable), - &pipe_config->dp_m_n); + ret = intel_link_compute_m_n(display, link_bpp_x16, + pipe_config->lane_count, + adjusted_mode->crtc_clock, + pipe_config->port_clock, + intel_dp_bw_fec_overhead(pipe_config->fec_enable), + &pipe_config->dp_m_n); + if (ret) + return ret; } /* FIXME: abstract this better */ @@ -3192,7 +3199,11 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_dp_compute_as_sdp(intel_dp, pipe_config); intel_psr_compute_config(intel_dp, pipe_config, conn_state); intel_alpm_lobf_compute_config(intel_dp, pipe_config, conn_state); - intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16); + + ret = intel_dp_drrs_compute_config(connector, pipe_config, link_bpp_x16); + if (ret) + return ret; + intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state); intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, conn_state); diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 02f95108c637..18d75634f902 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -167,22 +167,27 @@ static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, return max(overhead, intel_dp_bw_fec_overhead(crtc_state->fec_enable)); } -static void intel_dp_mst_compute_m_n(const struct intel_crtc_state *crtc_state, - int overhead, - int bpp_x16, - struct intel_link_m_n *m_n) +static int intel_dp_mst_compute_m_n(const struct intel_crtc_state *crtc_state, + int overhead, + int bpp_x16, + struct intel_link_m_n *m_n) { const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; + struct intel_display *display = to_intel_display(crtc_state); + int ret; /* TODO: Check WA 14013163432 to set data M/N for full BW utilization. */ - intel_link_compute_m_n(bpp_x16, crtc_state->lane_count, - adjusted_mode->crtc_clock, - crtc_state->port_clock, - overhead, - m_n); + ret = intel_link_compute_m_n(display, bpp_x16, crtc_state->lane_count, + adjusted_mode->crtc_clock, + crtc_state->port_clock, + overhead, m_n); + if (ret) + return ret; m_n->tu = DIV_ROUND_UP_ULL(mul_u32_u32(m_n->data_m, 64), m_n->data_n); + + return ret; } static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead) @@ -302,10 +307,11 @@ int intel_dp_mtp_tu_compute_config(struct intel_dp *intel_dp, intel_dp_mst_compute_min_hblank(crtc_state, link_bpp_x16); - intel_dp_mst_compute_m_n(crtc_state, - local_bw_overhead, - link_bpp_x16, - &crtc_state->dp_m_n); + if (!intel_dp_mst_compute_m_n(crtc_state, + local_bw_overhead, + link_bpp_x16, + &crtc_state->dp_m_n)) + continue; if (is_mst) { int remote_bw_overhead; diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 40deee0769ae..e6b11a61f6a9 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -323,7 +323,7 @@ int ilk_fdi_compute_config(struct intel_crtc *crtc, { struct intel_display *display = to_intel_display(crtc); const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; - int lane, link_bw, fdi_dotclock; + int lane, link_bw, fdi_dotclock, ret; /* FDI is a binary signal running at ~2.7GHz, encoding * each output octet as 10 bits. The actual frequency @@ -341,13 +341,13 @@ int ilk_fdi_compute_config(struct intel_crtc *crtc, pipe_config->fdi_lanes = lane; - intel_link_compute_m_n(fxp_q4_from_int(pipe_config->pipe_bpp), - lane, fdi_dotclock, - link_bw, - intel_dp_bw_fec_overhead(false), - &pipe_config->fdi_m_n); + ret = intel_link_compute_m_n(display, fxp_q4_from_int(pipe_config->pipe_bpp), + lane, fdi_dotclock, + link_bw, + intel_dp_bw_fec_overhead(false), + &pipe_config->fdi_m_n); - return 0; + return ret; } static int intel_fdi_atomic_check_bw(struct intel_atomic_state *state, From patchwork Fri Mar 21 11:26:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nautiyal, Ankit K" X-Patchwork-Id: 14025306 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 8FC97C36008 for ; Fri, 21 Mar 2025 11:38:52 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 241FB10E7B7; Fri, 21 Mar 2025 11:38:52 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="jmafj0bS"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1255110E7B3; Fri, 21 Mar 2025 11:38:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1742557128; x=1774093128; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kPd36xyJyT1XoAuc2gQ0QgoUtMlMFlBnf5o+fxMl8jE=; b=jmafj0bSsWNaTDbfJpzUYOyWJl+lI8D8k6JbGuX65GJcGJjko0vG1rDc gp+nn550frfH8OATn7n1CM42YervoLSSvyi2mgGGn9TGQmVAqzNN2N9Nc kPAMMxqIdyhs75NxAbV739y/1gn45Su4gMllLYkxacgyN1vPkIOyskYke e/Ds1PdpRBft8zDr+DBHi5VXD5j0TPNQn0C8yr6mRGAThRN/Mwrzz8yGm IoVsR+K04+NxD1ZcBnKccfy44/Cd4i5G83FEb7R0ptwmpEoiZ/pI3L7ya CNOwb8fPgiW9DwwA6k46NwN6ELAlHcfnoMR+v9tiReHhhSVRSWbTgfU62 Q==; X-CSE-ConnectionGUID: Cgl0J16XR8esGr2xU/ZkoA== X-CSE-MsgGUID: Ti2/ck5eRNS37aprVyHpvQ== X-IronPort-AV: E=McAfee;i="6700,10204,11379"; a="61216884" X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="61216884" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:48 -0700 X-CSE-ConnectionGUID: jTjH7m3yS7iaIxBd7TVU+Q== X-CSE-MsgGUID: TzVQH7FZRB+3vkSG3guLYw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="128206602" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:46 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Cc: jani.nikula@linux.intel.com, uma.shankar@intel.com Subject: [PATCH 3/4] drm/i915/display: Add bits for Wa_14021768792 for linkm/n ratio > 10 Date: Fri, 21 Mar 2025 16:56:49 +0530 Message-ID: <20250321112650.3594298-4-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250321112650.3594298-1-ankit.k.nautiyal@intel.com> References: <20250321112650.3594298-1-ankit.k.nautiyal@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" To support Link M/N ratio between 10.0 and 15.0, for some BMG ultrajoiner cases we need Wa_14021768792. To bypass the hardware limitation within the Timing Generator DDA (TGDDA), we need to program the LINKM and LINKN registers as defined in the WA. Along with this we also need relvant bits in HDMI_EMP_DATA and CHICKEN_TRANS regs. Add the bits for the WA and a new member 'bmg_bypass_m_n_ratio_limit' to track if we need to bypass the Link M/N ratio limit in intel_link_m_n structure. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 117 +++++++++++++++++- .../drm/i915/display/intel_display_types.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 5 + 3 files changed, 118 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index c50dce9afd9b..8a6b9196ef9b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2606,6 +2606,20 @@ void intel_zero_m_n(struct intel_link_m_n *m_n) m_n->tu = 1; } +static +u8 bmg_get_link_n_ext(const struct intel_link_m_n *m_n) +{ + int m_n_ratio, m_n_frac; + + if (!m_n->link_n) + return 0; + + m_n_ratio = DIV_ROUND_UP(m_n->link_m, m_n->link_n); + m_n_frac = m_n->link_m % m_n->link_n; + + return m_n_ratio + (m_n_frac > 0 ? 1 : 0); +} + void intel_set_m_n(struct intel_display *display, const struct intel_link_m_n *m_n, i915_reg_t data_m_reg, i915_reg_t data_n_reg, @@ -2617,7 +2631,9 @@ void intel_set_m_n(struct intel_display *display, intel_de_write(display, data_n_reg, m_n->data_n); intel_de_write(display, link_m_reg, m_n->link_m); - if (DISPLAY_VER(display) >= 14) + if (DISPLAY_VER(display) >= 14 && m_n->bypass_m_n_ratio_limit) + link_n |= PIPE_LINK_N1_EXTENDED(bmg_get_link_n_ext(m_n)); + else if (DISPLAY_VER(display) >= 14) link_n &= ~PIPE_LINK_N1_EXTENDED_MASK; else link_n &= DATA_LINK_M_N_MASK; @@ -2638,6 +2654,24 @@ bool intel_cpu_transcoder_has_m2_n2(struct intel_display *display, return IS_DISPLAY_VER(display, 5, 7) || display->platform.cherryview; } +static +void bmg_bypass_m_n_limit_write(struct intel_crtc *crtc, + enum transcoder transcoder, + const struct intel_link_m_n *m_n) +{ + struct intel_display *display = to_intel_display(crtc); + int m_n_frac; + enum pipe pipe = crtc->pipe; + + if (!m_n->link_n) + return; + + m_n_frac = m_n->link_m % m_n->link_n; + + intel_de_rmw(display, CHICKEN_TRANS(display, transcoder), 0, BMG_DP_BYPASS_M_N_LIMIT); + intel_de_write(display, HDMI_EMP_DATA(pipe), m_n_frac); +} + void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, enum transcoder transcoder, const struct intel_link_m_n *m_n) @@ -2655,6 +2689,9 @@ void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, intel_set_m_n(display, m_n, PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe), PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe)); + + if (m_n->bypass_m_n_ratio_limit) + bmg_bypass_m_n_limit_write(crtc, transcoder, m_n); } void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, @@ -2671,6 +2708,9 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, PIPE_DATA_N2(display, transcoder), PIPE_LINK_M2(display, transcoder), PIPE_LINK_N2(display, transcoder)); + + if (m_n->bypass_m_n_ratio_limit) + bmg_bypass_m_n_limit_write(crtc, transcoder, m_n); } static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state) @@ -3317,22 +3357,67 @@ void intel_get_m_n(struct intel_display *display, m_n->link_m = intel_de_read(display, link_m_reg) & DATA_LINK_M_N_MASK; m_n->link_n = intel_de_read(display, link_n_reg); - if (DISPLAY_VER(display) >= 14) + if (DISPLAY_VER(display) >= 14) { + u8 link_n_ext = REG_FIELD_GET(PIPE_LINK_N1_EXTENDED_MASK, m_n->link_n); + m_n->link_n &= ~PIPE_LINK_N1_EXTENDED_MASK; - else + drm_WARN_ON(display->drm, link_n_ext && link_n_ext != bmg_get_link_n_ext(m_n)); + } else { m_n->link_n &= DATA_LINK_M_N_MASK; + } m_n->data_m = intel_de_read(display, data_m_reg) & DATA_LINK_M_N_MASK; m_n->data_n = intel_de_read(display, data_n_reg) & DATA_LINK_M_N_MASK; m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(display, data_m_reg)) + 1; } +static +void bmg_bypass_m_n_limit_read(struct intel_crtc *crtc, + enum transcoder transcoder, + struct intel_link_m_n *m_n) +{ + struct intel_display *display = to_intel_display(crtc); + enum pipe pipe = crtc->pipe; + u32 chicken_trans, m_n_frac; + + chicken_trans = intel_de_read(display, CHICKEN_TRANS(display, transcoder)); + m_n_frac = intel_de_read(display, HDMI_EMP_DATA(pipe)); + + if (!m_n->link_n) + return; + + if ((chicken_trans & BMG_DP_BYPASS_M_N_LIMIT) && + m_n_frac == (m_n->link_m % m_n->link_n)) + m_n->bypass_m_n_ratio_limit = true; +} + +static +int bmg_can_bypass_m_n_limit(struct intel_display *display, + int m_n_ratio, + enum pipe pipe) +{ + struct drm_i915_private *i915 = to_i915(display->drm); + + if (DISPLAY_VER(display) != 14 || !IS_DGFX(i915) || + !IS_DISPLAY_STEP(display, STEP_C0, STEP_FOREVER)) + return false; + + if (pipe != PIPE_A) + return false; + + if (m_n_ratio > 15) + return false; + + return true; +} + void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc, enum transcoder transcoder, struct intel_link_m_n *m_n) { struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; + int m_n_ratio; if (DISPLAY_VER(display) >= 5) intel_get_m_n(display, m_n, @@ -3344,6 +3429,14 @@ void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc, intel_get_m_n(display, m_n, PIPE_DATA_M_G4X(pipe), PIPE_DATA_N_G4X(pipe), PIPE_LINK_M_G4X(pipe), PIPE_LINK_N_G4X(pipe)); + if (!m_n->link_n) + return; + + m_n_ratio = DIV_ROUND_UP(m_n->link_m, m_n->link_n); + + if (bmg_can_bypass_m_n_limit(display, m_n_ratio, pipe)) + bmg_bypass_m_n_limit_read(crtc, transcoder, m_n); + } void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, @@ -3351,6 +3444,8 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { struct intel_display *display = to_intel_display(crtc); + enum pipe pipe = crtc->pipe; + int m_n_ratio; if (!intel_cpu_transcoder_has_m2_n2(display, transcoder)) return; @@ -3360,6 +3455,14 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, PIPE_DATA_N2(display, transcoder), PIPE_LINK_M2(display, transcoder), PIPE_LINK_N2(display, transcoder)); + + if (!m_n->link_n) + return; + + m_n_ratio = DIV_ROUND_UP(m_n->link_m, m_n->link_n); + + if (bmg_can_bypass_m_n_limit(display, m_n_ratio, pipe)) + bmg_bypass_m_n_limit_read(crtc, transcoder, m_n); } static bool ilk_get_pipe_config(struct intel_crtc *crtc, @@ -5087,18 +5190,20 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, if (!intel_compare_link_m_n(¤t_config->name, \ &pipe_config->name)) { \ pipe_config_mismatch(&p, fastset, crtc, __stringify(name), \ - "(expected tu %i data %i/%i link %i/%i, " \ - "found tu %i, data %i/%i link %i/%i)", \ + "(expected tu %i data %i/%i link %i/%i bypass_m_n_ratio_limit %s, " \ + "found tu %i, data %i/%i link %i/%i bypass_m_n_ratio_limit %s)", \ current_config->name.tu, \ current_config->name.data_m, \ current_config->name.data_n, \ current_config->name.link_m, \ current_config->name.link_n, \ + str_yes_no(current_config->name.bypass_m_n_ratio_limit), \ pipe_config->name.tu, \ pipe_config->name.data_m, \ pipe_config->name.data_n, \ pipe_config->name.link_m, \ - pipe_config->name.link_n); \ + pipe_config->name.link_n, \ + str_yes_no(pipe_config->name.bypass_m_n_ratio_limit)); \ ret = false; \ } \ } while (0) diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 99a6fd2900b9..6d02e206a6fa 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -923,6 +923,8 @@ struct intel_link_m_n { u32 data_n; u32 link_m; u32 link_n; + /* Wa_14021768792 for linkm/n ratio > 10 */ + bool bypass_m_n_ratio_limit; }; struct intel_csc_matrix { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a2054aced4f8..6c8e3717329f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1175,6 +1175,10 @@ #define _TRANS_MULT_B 0x6102c #define TRANS_MULT(dev_priv, trans) _MMIO_TRANS2(dev_priv, (trans), _TRANS_MULT_A) +#define _HDMI_EMP_DATA_A 0x600d8 +#define _HDMI_EMP_DATA_B 0x610d8 +#define HDMI_EMP_DATA(pipe) _MMIO_PIPE(pipe, _HDMI_EMP_DATA_A, _HDMI_EMP_DATA_B) + /* Hotplug control (945+ only) */ #define PORT_HOTPLUG_EN(dev_priv) _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61110) #define PORTB_HOTPLUG_INT_EN (1 << 29) @@ -2500,6 +2504,7 @@ #define DDIE_TRAINING_OVERRIDE_VALUE REG_BIT(16) /* CHICKEN_TRANS_A only */ #define PSR2_ADD_VERTICAL_LINE_COUNT REG_BIT(15) #define DP_FEC_BS_JITTER_WA REG_BIT(15) +#define BMG_DP_BYPASS_M_N_LIMIT REG_BIT(11) #define PSR2_VSC_ENABLE_PROG_HEADER REG_BIT(12) #define DP_DSC_INSERT_SF_AT_EOL_WA REG_BIT(4) #define HDCP_LINE_REKEY_DISABLE REG_BIT(0) From patchwork Fri Mar 21 11:26:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Nautiyal, Ankit K" X-Patchwork-Id: 14025307 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 4EFEFC36000 for ; Fri, 21 Mar 2025 11:38:52 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E593110E7B6; Fri, 21 Mar 2025 11:38:51 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="gMAb3FDB"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by gabe.freedesktop.org (Postfix) with ESMTPS id D84C910E7B6; Fri, 21 Mar 2025 11:38:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1742557130; x=1774093130; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AZluORa4fZNx1bE1iM2tlNxr1PDgvhoeRX02YfKfFug=; b=gMAb3FDBoJDqvxtoW9Y1CNh8CXkp5MX7dYNuW3ElMluANse17Btz/nSl q0R+15z9qK25x9sFQGHpeDMZQrrrGv6kGSsj31ApCRb1KbsQEtNEl8ySh tZrlmUYWEXLQ7MloMfoV5Jfh3JhUuS2B23BlyEVm1uvSqoPooAvxuoNeF Xb9CZq+xmcGB7xcIg0rNfSPp7iB2WHrDiBKUORZzh2xKOaPXGyuoBaqE3 jVW/z6BjgEEg6+yCpNeRJAEkbrFEqN7gkSBN7bhOwGnJCSVQ76RFkZltG UOS+ewww4X5HDJZ+mf9NY45Xda5LxYyfRLJiKV87gSe1+OLE/0kBseiz4 Q==; X-CSE-ConnectionGUID: rTgzfGIUQOKqgUCCoEGsow== X-CSE-MsgGUID: Df5fv/0/TtCJ16GUFIfI3Q== X-IronPort-AV: E=McAfee;i="6700,10204,11379"; a="61216885" X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="61216885" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:50 -0700 X-CSE-ConnectionGUID: BaEHoI0uQVWlxMOqOQkIQw== X-CSE-MsgGUID: 9payOdl+SEC41IwZacbdCw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.14,264,1736841600"; d="scan'208";a="128206611" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by ORVIESA003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Mar 2025 04:38:48 -0700 From: Ankit Nautiyal To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org Cc: jani.nikula@linux.intel.com, uma.shankar@intel.com Subject: [PATCH 4/4] drm/i915/display: Implement Wa_14021768792 for BMG DP for link_m/n ratio > 10 Date: Fri, 21 Mar 2025 16:56:50 +0530 Message-ID: <20250321112650.3594298-5-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20250321112650.3594298-1-ankit.k.nautiyal@intel.com> References: <20250321112650.3594298-1-ankit.k.nautiyal@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" Handle the bypass logic for the M/N ratio limit for DP. Calculate the M/N ratio, check if it can bypass the limit, and set the appropriate flags for the workaround. Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 1 - drivers/gpu/drm/i915/display/intel_display.h | 3 ++ drivers/gpu/drm/i915/display/intel_dp.c | 31 ++++++++++++++++++-- drivers/gpu/drm/i915/display/intel_dp.h | 4 +++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +++- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 8a6b9196ef9b..ede86012406b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3391,7 +3391,6 @@ void bmg_bypass_m_n_limit_read(struct intel_crtc *crtc, m_n->bypass_m_n_ratio_limit = true; } -static int bmg_can_bypass_m_n_limit(struct intel_display *display, int m_n_ratio, enum pipe pipe) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 7a33c57d5abe..651ec3eb8726 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -574,5 +574,8 @@ int intel_link_compute_m_n(struct intel_display *display, int pixel_clock, int link_clock, int bw_overhead, struct intel_link_m_n *m_n); +int bmg_can_bypass_m_n_limit(struct intel_display *display, + int m_n_ratio, + enum pipe pipe); #endif diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 49a8f105ba26..56aebb23d8ae 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2937,6 +2937,27 @@ static bool can_enable_drrs(struct intel_connector *connector, intel_panel_drrs_type(connector) == DRRS_TYPE_SEAMLESS; } +bool +intel_dp_bmg_bypass_m_n_limit(struct intel_display *display, + struct intel_link_m_n *m_n, + enum pipe pipe) +{ + int m_n_ratio; + + if (!m_n->link_n) + return false; + + m_n_ratio = DIV_ROUND_UP(m_n->link_m, m_n->link_n); + + if (!bmg_can_bypass_m_n_limit(display, m_n_ratio, pipe)) + return false; + + m_n->bypass_m_n_ratio_limit = true; + drm_dbg_kms(display->drm, "Bypassing Link_m/Link_n ratio limit\n"); + + return true; +} + static int intel_dp_drrs_compute_config(struct intel_connector *connector, struct intel_crtc_state *pipe_config, @@ -2945,6 +2966,8 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, struct intel_display *display = to_intel_display(connector); const struct drm_display_mode *downclock_mode = intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode); + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + enum pipe pipe = crtc->pipe; int pixel_clock; int ret; @@ -2975,7 +2998,8 @@ intel_dp_drrs_compute_config(struct intel_connector *connector, pipe_config->port_clock, intel_dp_bw_fec_overhead(pipe_config->fec_enable), &pipe_config->dp_m2_n2); - if (ret) + + if (ret && !intel_dp_bmg_bypass_m_n_limit(display, &pipe_config->dp_m2_n2, pipe)) return ret; /* FIXME: abstract this better */ @@ -3101,6 +3125,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct intel_dp *intel_dp = enc_to_intel_dp(encoder); const struct drm_display_mode *fixed_mode; struct intel_connector *connector = intel_dp->attached_connector; + struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); + enum pipe pipe = crtc->pipe; int ret = 0, link_bpp_x16; fixed_mode = intel_panel_fixed_mode(connector, adjusted_mode); @@ -3130,7 +3156,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, ret = intel_dp_compute_output_format(encoder, pipe_config, conn_state, true); if (ret) ret = intel_dp_compute_output_format(encoder, pipe_config, conn_state, false); - if (ret) + + if (ret && !intel_dp_bmg_bypass_m_n_limit(display, &pipe_config->dp_m_n, pipe)) return ret; if ((intel_dp_is_edp(intel_dp) && fixed_mode) || diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 9189db4c2594..16004a18b13e 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -22,6 +22,7 @@ struct intel_digital_port; struct intel_display; struct intel_dp; struct intel_encoder; +struct intel_link_m_n; struct link_config_limits { int min_rate, max_rate; @@ -208,5 +209,8 @@ bool intel_dp_has_connector(struct intel_dp *intel_dp, const struct drm_connector_state *conn_state); int intel_dp_dsc_max_src_input_bpc(struct intel_display *display); int intel_dp_dsc_min_src_input_bpc(void); +bool intel_dp_bmg_bypass_m_n_limit(struct intel_display *display, + struct intel_link_m_n *m_n, + enum pipe pipe); #endif /* __INTEL_DP_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 18d75634f902..f03a1c97cdcf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -175,6 +175,8 @@ static int intel_dp_mst_compute_m_n(const struct intel_crtc_state *crtc_state, const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode; struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + enum pipe pipe = crtc->pipe; int ret; /* TODO: Check WA 14013163432 to set data M/N for full BW utilization. */ @@ -182,7 +184,8 @@ static int intel_dp_mst_compute_m_n(const struct intel_crtc_state *crtc_state, adjusted_mode->crtc_clock, crtc_state->port_clock, overhead, m_n); - if (ret) + + if (ret && !intel_dp_bmg_bypass_m_n_limit(display, m_n, pipe)) return ret; m_n->tu = DIV_ROUND_UP_ULL(mul_u32_u32(m_n->data_m, 64), m_n->data_n);