From patchwork Thu Oct 10 04:10:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 13829461 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 F1CA9CF045C for ; Thu, 10 Oct 2024 04:08:42 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 70FA310E84B; Thu, 10 Oct 2024 04:08:42 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="LLaeNuNs"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 68D4310E84B; Thu, 10 Oct 2024 04:08:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728533322; x=1760069322; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=b34LO3VR/D/PSEKSRqeY3bK3mQyf2ahlP3F6BQajjWE=; b=LLaeNuNsiUmn6MZ8J3hB7+Pm0XWh/Q2I1RgfoQIH9Ocz16MvQSSM5FTt C3kXdbVi49lDU/xA4ONvEyA1lFSQODFz7GMPCVBNsmOsz4X2iKET3Gx/b l41tIPKsR1hGoJa85pcXEff/N7L/ZqWyJuUuUr0C7dvmjqzel+En2KanS 2YLXSr7qCRlCMY92m/DEBxfNxVqHrMDiTakj+ahTo7Y9JNtG7VKFao/WI +kMhnHHf1KVGCLFsn040q4B42+2od46FbGEbjl/J2ZRIi2ttE5ab9NOwx 0GJFHBMG+hJoqBMDT+kAp6KTn8sDD0Y0lrHmkaY+e77PSV/6aVxbwF0p/ g==; X-CSE-ConnectionGUID: o1A0cja/S1eIfEOxi3ZStQ== X-CSE-MsgGUID: o8fRdzRLTS+krz+R9t3sbg== X-IronPort-AV: E=McAfee;i="6700,10204,11220"; a="27986952" X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="27986952" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:42 -0700 X-CSE-ConnectionGUID: iWgTpzK5RcGw/qvMEe4hVg== X-CSE-MsgGUID: 7BcPhhHQQle4Fa1d9q9VYA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="99782642" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:40 -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: Thu, 10 Oct 2024 09:40:42 +0530 Message-ID: <20241010041045.2014069-2-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241010041045.2014069-1-ankit.k.nautiyal@intel.com> References: <20241010041045.2014069-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. v2: Drop extra link_n_ext member. (Jani) v3: Avoid link_n_ext in set_m_n helper. (Jani) Signed-off-by: Ankit Nautiyal --- drivers/gpu/drm/i915/display/intel_display.c | 17 +++++++++++++++-- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e1f6255e918b..2a7fa0013b44 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2721,14 +2721,21 @@ void intel_set_m_n(struct drm_i915_private *i915, 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(i915, data_m_reg, TU_SIZE(m_n->tu) | m_n->data_m); intel_de_write(i915, data_n_reg, m_n->data_n); intel_de_write(i915, link_m_reg, m_n->link_m); + + if (DISPLAY_VER(i915) >= 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(i915, link_n_reg, m_n->link_n); + intel_de_write(i915, link_n_reg, link_n); } bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv, @@ -3438,7 +3445,13 @@ void intel_get_m_n(struct drm_i915_private *i915, i915_reg_t link_m_reg, i915_reg_t link_n_reg) { m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK; - m_n->link_n = intel_de_read(i915, link_n_reg) & DATA_LINK_M_N_MASK; + m_n->link_n = intel_de_read(i915, link_n_reg); + + if (DISPLAY_VER(i915) >= 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(i915, data_m_reg) & DATA_LINK_M_N_MASK; m_n->data_n = intel_de_read(i915, data_n_reg) & DATA_LINK_M_N_MASK; m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, data_m_reg)) + 1; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 818142f5a10c..c605642ffc3e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2167,6 +2167,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 Thu Oct 10 04:10:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 13829462 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 D161ACF07A3 for ; Thu, 10 Oct 2024 04:08:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 7A92910E850; Thu, 10 Oct 2024 04:08:44 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="TEAXFHNZ"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3F3F510E84D; Thu, 10 Oct 2024 04:08: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=1728533324; x=1760069324; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=VR4IpKht+W4IRFrycEMKUUPqrXWc3vLJ9dLVJauqJ2E=; b=TEAXFHNZvyRgw9PoFx0mwFd6B7fetI/KP5Z1WE+J/vgjgeUeq3HIRJAm DPaG/IXJwUuPjMJAujwCO+NthDAScVekokkZAMKgTzWDD+/+9kLSZD1S+ bJQnCio2EMVfO3BwqcFgP1/qkIoerLY94ejpbAbqlcrTNEzXcpLhUMKoD Jo6DcvjgPTiNXtpU7MdLbBiOIjcGpaTbQ5RFmvODR3s+2ylQkxwa/Gets ehTBiwL4vsPcPybdh8OEdV2GmUIkMmKvhCFQ71lxEeuyblNlm4shgDRY6 s7WL2eXdHsqOnnv2AFtnPK0drh6E9szH8h/Yk6KRLrvzL3ZOfhpbFkpIU A==; X-CSE-ConnectionGUID: I0HpwKDGR0W/sB9MDShDkA== X-CSE-MsgGUID: Wg5Fzv0DQ5+oas5uIPywxQ== X-IronPort-AV: E=McAfee;i="6700,10204,11220"; a="27986955" X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="27986955" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:44 -0700 X-CSE-ConnectionGUID: XSqC3RUgSGKWPMgNWy8gww== X-CSE-MsgGUID: qPsyY6ZhRAiYhI28srX88A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="99782652" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:41 -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: Thu, 10 Oct 2024 09:40:43 +0530 Message-ID: <20241010041045.2014069-3-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241010041045.2014069-1-ankit.k.nautiyal@intel.com> References: <20241010041045.2014069-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 | 39 +++++++++++++------- drivers/gpu/drm/i915/display/intel_dp_mst.c | 34 ++++++++++------- drivers/gpu/drm/i915/display/intel_fdi.c | 15 ++++---- 5 files changed, 89 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 2a7fa0013b44..9407eebf731b 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2658,8 +2658,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) @@ -2668,6 +2675,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. @@ -2684,6 +2692,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 drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 61e1df878de9..61f6943443a7 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -420,10 +420,11 @@ int intel_atomic_add_affected_planes(struct intel_atomic_state *state, struct intel_crtc *crtc); 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); +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); u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv, u32 pixel_format, u64 modifier); enum drm_mode_status diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index fbb096be02ad..45ab903a31b2 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2890,15 +2890,17 @@ 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) { struct drm_i915_private *i915 = to_i915(connector->base.dev); + 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); int pixel_clock; + int ret; /* * FIXME all joined pipes share the same transcoder. @@ -2910,7 +2912,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(i915, pipe_config->cpu_transcoder)) intel_zero_m_n(&pipe_config->dp_m2_n2); - return; + return 0; } if (IS_IRONLAKE(i915) || IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) @@ -2922,14 +2924,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, @@ -3052,6 +3058,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, struct drm_connector_state *conn_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + struct intel_display *display = to_intel_display(encoder); struct intel_atomic_state *state = to_intel_atomic_state(conn_state->state); struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -3133,12 +3140,14 @@ intel_dp_compute_config(struct intel_encoder *encoder, intel_dp_audio_compute_config(encoder, pipe_config, conn_state); - 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 */ if (pipe_config->splitter.enable) @@ -3151,7 +3160,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 4765bda154c1..915cf3a5cdc0 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -125,23 +125,28 @@ 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, - const struct intel_connector *connector, - 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, + const struct intel_connector *connector, + 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(connector); + 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) @@ -223,10 +228,11 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, true, dsc, link_bpp_x16); - intel_dp_mst_compute_m_n(crtc_state, connector, - local_bw_overhead, - link_bpp_x16, - &crtc_state->dp_m_n); + if (!intel_dp_mst_compute_m_n(crtc_state, connector, + local_bw_overhead, + link_bpp_x16, + &crtc_state->dp_m_n)) + continue; /* * The TU size programmed to the HW determines which slots in diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index 0168894e9cd1..0b39773a4a85 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -325,8 +325,9 @@ int ilk_fdi_compute_config(struct intel_crtc *crtc, { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *i915 = to_i915(dev); + struct intel_display *display = to_intel_display(pipe_config); 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 @@ -344,13 +345,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 Thu Oct 10 04:10:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 13829463 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 C2A40CF07A1 for ; Thu, 10 Oct 2024 04:08:46 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6AA7C10E851; Thu, 10 Oct 2024 04:08:46 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="cpaduf1s"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 70E3910E852; Thu, 10 Oct 2024 04:08:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728533326; x=1760069326; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=uc+eCdFZnIk770ZN0fVHMopXYjK4yi/+oe0LroQLr/M=; b=cpaduf1sNmfZOrIYEGTWmbZYqyy3B7TmOVTFF1P9Vv/lt68DUJJNbCd4 ymI8uD7AnUMV+3M+99qmrLy7URvkXe4zE6Qd1ZrVD0msYTUps50F5H3/3 1E79f3WvRXkVEIq3Zghb19WBNWcS+Rh01XLEAorA1St5Xy2HIM5hYlaX2 Z/IVr4ICKtcpjYhoL6en+TNuGLL8hKKuGPUcQvC0DA7Euxag8sTo8D4I/ sIBuOnevQwBkSErCBXAoSRq/MFO0fCkonwzrIaqGWaLl8izlF067I8VXp cFtV/0zouGMVGAUdmo5TnMhyW33K4KqRz1uXTGkJOMD7C07ON+uKOMKRZ Q==; X-CSE-ConnectionGUID: FU1peS28TMyyJKF/AQ/Reg== X-CSE-MsgGUID: g+69Da8+QSWSe491/v5KEw== X-IronPort-AV: E=McAfee;i="6700,10204,11220"; a="27986964" X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="27986964" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:46 -0700 X-CSE-ConnectionGUID: +6kVqckqQ0uK51WhbrROig== X-CSE-MsgGUID: P25cWc8rSYu7EhUubU7u0w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="99782659" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:43 -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: Thu, 10 Oct 2024 09:40:44 +0530 Message-ID: <20241010041045.2014069-4-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241010041045.2014069-1-ankit.k.nautiyal@intel.com> References: <20241010041045.2014069-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 | 119 +++++++++++++++++- .../drm/i915/display/intel_display_types.h | 2 + drivers/gpu/drm/i915/i915_reg.h | 5 + 3 files changed, 120 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 9407eebf731b..75274f567ee6 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -2744,6 +2744,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 drm_i915_private *i915, const struct intel_link_m_n *m_n, i915_reg_t data_m_reg, i915_reg_t data_n_reg, @@ -2755,7 +2769,9 @@ void intel_set_m_n(struct drm_i915_private *i915, intel_de_write(i915, data_n_reg, m_n->data_n); intel_de_write(i915, link_m_reg, m_n->link_m); - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(i915) >= 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(i915) >= 14) link_n &= ~PIPE_LINK_N1_EXTENDED_MASK; else link_n &= DATA_LINK_M_N_MASK; @@ -2775,6 +2791,24 @@ bool intel_cpu_transcoder_has_m2_n2(struct drm_i915_private *dev_priv, return IS_DISPLAY_VER(dev_priv, 5, 7) || IS_CHERRYVIEW(dev_priv); } +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, MTL_CHICKEN_TRANS(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) @@ -2792,6 +2826,9 @@ void intel_cpu_transcoder_set_m1_n1(struct intel_crtc *crtc, intel_set_m_n(dev_priv, 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, @@ -2808,6 +2845,9 @@ void intel_cpu_transcoder_set_m2_n2(struct intel_crtc *crtc, PIPE_DATA_N2(dev_priv, transcoder), PIPE_LINK_M2(dev_priv, transcoder), PIPE_LINK_N2(dev_priv, 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) @@ -3475,22 +3515,68 @@ void intel_get_m_n(struct drm_i915_private *i915, m_n->link_m = intel_de_read(i915, link_m_reg) & DATA_LINK_M_N_MASK; m_n->link_n = intel_de_read(i915, link_n_reg); - if (DISPLAY_VER(i915) >= 14) + if (DISPLAY_VER(i915) >= 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(&i915->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(i915, data_m_reg) & DATA_LINK_M_N_MASK; m_n->data_n = intel_de_read(i915, data_n_reg) & DATA_LINK_M_N_MASK; m_n->tu = REG_FIELD_GET(TU_SIZE_MASK, intel_de_read(i915, 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, MTL_CHICKEN_TRANS(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 drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); enum pipe pipe = crtc->pipe; + int m_n_ratio; if (DISPLAY_VER(dev_priv) >= 5) intel_get_m_n(dev_priv, m_n, @@ -3502,6 +3588,14 @@ void intel_cpu_transcoder_get_m1_n1(struct intel_crtc *crtc, intel_get_m_n(dev_priv, 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, @@ -3509,6 +3603,9 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct intel_display *display = to_intel_display(crtc); + enum pipe pipe = crtc->pipe; + int m_n_ratio; if (!intel_cpu_transcoder_has_m2_n2(dev_priv, transcoder)) return; @@ -3518,6 +3615,14 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc, PIPE_DATA_N2(dev_priv, transcoder), PIPE_LINK_M2(dev_priv, transcoder), PIPE_LINK_N2(dev_priv, 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 void ilk_get_pfit_config(struct intel_crtc_state *crtc_state) @@ -5426,18 +5531,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 2bb1fa64da2f..20be908581c7 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -901,6 +901,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 c605642ffc3e..2b964821a334 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1147,6 +1147,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) + /* VGA port control */ #define ADPA _MMIO(0x61100) #define PCH_ADPA _MMIO(0xe1100) @@ -2836,6 +2840,7 @@ #define PSR2_ADD_VERTICAL_LINE_COUNT REG_BIT(15) #define DP_FEC_BS_JITTER_WA REG_BIT(15) #define PSR2_VSC_ENABLE_PROG_HEADER REG_BIT(12) +#define BMG_DP_BYPASS_M_N_LIMIT REG_BIT(11) #define DP_DSC_INSERT_SF_AT_EOL_WA REG_BIT(4) #define HDCP_LINE_REKEY_DISABLE REG_BIT(0) From patchwork Thu Oct 10 04:10:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ankit Nautiyal X-Patchwork-Id: 13829464 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 07376CF07A0 for ; Thu, 10 Oct 2024 04:08:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9E6E210E854; Thu, 10 Oct 2024 04:08:47 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.b="DXyfX2J3"; dkim-atps=neutral Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5AC1A10E854; Thu, 10 Oct 2024 04:08:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1728533328; x=1760069328; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SVwpd9z3PVy3AxktdlvMOgPP2cSyRHjeo+RHXGSeV0E=; b=DXyfX2J3FZF3zqMnzsd8O4Dt2djyj+kumcvkWNPS2N658DnV5mulYzcW UZub0GbYjzxQQRxDKZhCTO10z+76aOhy/3Llg2hQipd9+XrMrHZ8YQPX9 FuEJ43m96Jl4i+nHyJVp4FPp8MarNbeCRrimapBUnKdsiqwMY27HbyE3P rVO1iTWilQA+3++q/7OZCFfCtleqNApgWR/gXFF4Y6JnVHEHwdD6kn9DZ D508ixSoAC/QdmNDF/4bhjw8brvG/M1QqdiKWn2R+6vCkx32CZANT+z6D Qo/zGvND9hu/33R5ONIa/1PwMUlD7Vy4RzNc7V7MfJBBzqEwc0CE0aBa3 w==; X-CSE-ConnectionGUID: 72I+N0qITN6j/7zm0D25FA== X-CSE-MsgGUID: Bi1vJyvRSTawj+EIU+w7jw== X-IronPort-AV: E=McAfee;i="6700,10204,11220"; a="27986968" X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="27986968" Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:48 -0700 X-CSE-ConnectionGUID: VCkCn3aCSEq80q86ssP9Dw== X-CSE-MsgGUID: BXZ5y8RIRL2BTNjAvq21Og== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.11,191,1725346800"; d="scan'208";a="99782674" Received: from srr4-3-linux-103-aknautiy.iind.intel.com ([10.223.34.160]) by fmviesa002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 09 Oct 2024 21:08:45 -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: Thu, 10 Oct 2024 09:40:45 +0530 Message-ID: <20241010041045.2014069-5-ankit.k.nautiyal@intel.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20241010041045.2014069-1-ankit.k.nautiyal@intel.com> References: <20241010041045.2014069-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 | 5 ++++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 5 +++- 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 75274f567ee6..563eaee68cd4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3549,7 +3549,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 61f6943443a7..4eb0456fde85 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -603,5 +603,8 @@ bool assert_port_valid(struct drm_i915_private *i915, enum port port); bool intel_scanout_needs_vtd_wa(struct drm_i915_private *i915); int intel_crtc_num_joined_pipes(const struct intel_crtc_state *crtc_state); +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 45ab903a31b2..150375ff9d5d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2890,6 +2890,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, @@ -2899,6 +2920,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; @@ -2928,7 +2951,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 */ @@ -3064,6 +3088,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; if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && encoder->port != PORT_A) @@ -3146,7 +3172,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->port_clock, intel_dp_bw_fec_overhead(pipe_config->fec_enable), &pipe_config->dp_m_n); - if (ret) + + if (ret && !intel_dp_bmg_bypass_m_n_limit(display, &pipe_config->dp_m_n, pipe)) return ret; /* FIXME: abstract this better */ diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h index 60baf4072dc9..b09b088cdfc8 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.h +++ b/drivers/gpu/drm/i915/display/intel_dp.h @@ -20,8 +20,10 @@ struct intel_atomic_state; struct intel_connector; struct intel_crtc_state; 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; @@ -204,5 +206,8 @@ bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate, u8 lane_count); bool intel_dp_has_connector(struct intel_dp *intel_dp, const struct drm_connector_state *conn_state); +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 915cf3a5cdc0..b04418a009ae 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -134,6 +134,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(connector); + 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. */ @@ -141,7 +143,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);