All of lore.kernel.org
 help / color / mirror / Atom feed
From: Imre Deak <imre.deak@intel.com>
To: <intel-gfx@lists.freedesktop.org>, <intel-xe@lists.freedesktop.org>
Cc: <dri-devel@lists.freedesktop.org>,
	Luca Coelho <luciano.coelho@intel.com>
Subject: [PATCH 02/16] drm/dp: Add drm_dp_dsc_sink_slice_count_mask()
Date: Mon, 15 Dec 2025 21:23:42 +0200	[thread overview]
Message-ID: <20251215192357.172201-3-imre.deak@intel.com> (raw)
In-Reply-To: <20251215192357.172201-1-imre.deak@intel.com>

A DSC sink supporting DSC slice count N, not necessarily supports slice
counts less than N. Hence the driver should check the sink's support for
a particular slice count before using that slice count. Add the helper
functions required for this.

Cc: dri-devel@lists.freedesktop.org
Reviewed-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/display/drm_dp_helper.c | 82 +++++++++++++++++--------
 include/drm/display/drm_dp_helper.h     |  3 +
 2 files changed, 61 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 19564c1afba6c..a697cc227e289 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2705,56 +2705,90 @@ u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
 EXPORT_SYMBOL(drm_dp_dsc_sink_bpp_incr);
 
 /**
- * drm_dp_dsc_sink_max_slice_count() - Get the max slice count
- * supported by the DSC sink.
- * @dsc_dpcd: DSC capabilities from DPCD
- * @is_edp: true if its eDP, false for DP
+ * drm_dp_dsc_slice_count_to_mask() - Convert a slice count to a slice count mask
+ * @slice_count: slice count
  *
- * Read the slice capabilities DPCD register from DSC sink to get
- * the maximum slice count supported. This is used to populate
- * the DSC parameters in the &struct drm_dsc_config by the driver.
- * Driver creates an infoframe using these parameters to populate
- * &struct drm_dsc_pps_infoframe. These are sent to the sink using DSC
- * infoframe using the helper function drm_dsc_pps_infoframe_pack()
+ * Convert @slice_count to a slice count mask.
+ *
+ * Returns the slice count mask.
+ */
+u32 drm_dp_dsc_slice_count_to_mask(int slice_count)
+{
+	return BIT(slice_count - 1);
+}
+EXPORT_SYMBOL(drm_dp_dsc_slice_count_to_mask);
+
+/**
+ * drm_dp_dsc_sink_slice_count_mask() - Get the mask of valid DSC sink slice counts
+ * @dsc_dpcd: the sink's DSC DPCD capabilities
+ * @is_edp: %true for an eDP sink
+ *
+ * Get the mask of supported slice counts from the sink's DSC DPCD register.
  *
  * Returns:
- * Maximum slice count supported by DSC sink or 0 its invalid
+ * Mask of slice counts supported by the DSC sink:
+ * - > 0: bit#0,1,3,5..,23 set if the sink supports 1,2,4,6..,24 slices
+ * - 0:   if the sink doesn't support any slices
  */
-u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
-				   bool is_edp)
+u32 drm_dp_dsc_sink_slice_count_mask(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
+				     bool is_edp)
 {
 	u8 slice_cap1 = dsc_dpcd[DP_DSC_SLICE_CAP_1 - DP_DSC_SUPPORT];
+	u32 mask = 0;
 
 	if (!is_edp) {
 		/* For DP, use values from DSC_SLICE_CAP_1 and DSC_SLICE_CAP2 */
 		u8 slice_cap2 = dsc_dpcd[DP_DSC_SLICE_CAP_2 - DP_DSC_SUPPORT];
 
 		if (slice_cap2 & DP_DSC_24_PER_DP_DSC_SINK)
-			return 24;
+			mask |= drm_dp_dsc_slice_count_to_mask(24);
 		if (slice_cap2 & DP_DSC_20_PER_DP_DSC_SINK)
-			return 20;
+			mask |= drm_dp_dsc_slice_count_to_mask(20);
 		if (slice_cap2 & DP_DSC_16_PER_DP_DSC_SINK)
-			return 16;
+			mask |= drm_dp_dsc_slice_count_to_mask(16);
 	}
 
 	/* DP, eDP v1.5+ */
 	if (slice_cap1 & DP_DSC_12_PER_DP_DSC_SINK)
-		return 12;
+		mask |= drm_dp_dsc_slice_count_to_mask(12);
 	if (slice_cap1 & DP_DSC_10_PER_DP_DSC_SINK)
-		return 10;
+		mask |= drm_dp_dsc_slice_count_to_mask(10);
 	if (slice_cap1 & DP_DSC_8_PER_DP_DSC_SINK)
-		return 8;
+		mask |= drm_dp_dsc_slice_count_to_mask(8);
 	if (slice_cap1 & DP_DSC_6_PER_DP_DSC_SINK)
-		return 6;
+		mask |= drm_dp_dsc_slice_count_to_mask(6);
 	/* DP, eDP v1.4+ */
 	if (slice_cap1 & DP_DSC_4_PER_DP_DSC_SINK)
-		return 4;
+		mask |= drm_dp_dsc_slice_count_to_mask(4);
 	if (slice_cap1 & DP_DSC_2_PER_DP_DSC_SINK)
-		return 2;
+		mask |= drm_dp_dsc_slice_count_to_mask(2);
 	if (slice_cap1 & DP_DSC_1_PER_DP_DSC_SINK)
-		return 1;
+		mask |= drm_dp_dsc_slice_count_to_mask(1);
 
-	return 0;
+	return mask;
+}
+EXPORT_SYMBOL(drm_dp_dsc_sink_slice_count_mask);
+
+/**
+ * drm_dp_dsc_sink_max_slice_count() - Get the max slice count
+ * supported by the DSC sink.
+ * @dsc_dpcd: DSC capabilities from DPCD
+ * @is_edp: true if its eDP, false for DP
+ *
+ * Read the slice capabilities DPCD register from DSC sink to get
+ * the maximum slice count supported. This is used to populate
+ * the DSC parameters in the &struct drm_dsc_config by the driver.
+ * Driver creates an infoframe using these parameters to populate
+ * &struct drm_dsc_pps_infoframe. These are sent to the sink using DSC
+ * infoframe using the helper function drm_dsc_pps_infoframe_pack()
+ *
+ * Returns:
+ * Maximum slice count supported by DSC sink or 0 its invalid
+ */
+u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
+				   bool is_edp)
+{
+	return fls(drm_dp_dsc_sink_slice_count_mask(dsc_dpcd, is_edp));
 }
 EXPORT_SYMBOL(drm_dp_dsc_sink_max_slice_count);
 
diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h
index df2f24b950e4c..85e868238e287 100644
--- a/include/drm/display/drm_dp_helper.h
+++ b/include/drm/display/drm_dp_helper.h
@@ -206,6 +206,9 @@ drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 
 /* DP/eDP DSC support */
 u8 drm_dp_dsc_sink_bpp_incr(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]);
+u32 drm_dp_dsc_slice_count_to_mask(int slice_count);
+u32 drm_dp_dsc_sink_slice_count_mask(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
+				     bool is_edp);
 u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
 				   bool is_edp);
 u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]);
-- 
2.49.1


  parent reply	other threads:[~2025-12-15 19:24 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-15 19:23 [PATCH 00/16] drm/i915/dp: Clean up link BW/DSC slice config computation (fixes) Imre Deak
2025-12-15 19:23 ` [PATCH 01/16] drm/dp: Parse all DSC slice count caps for eDP 1.5 Imre Deak
2025-12-15 19:23 ` Imre Deak [this message]
2025-12-15 19:23 ` [PATCH 03/16] drm/i915/dp: Fix DSC sink's slice count capability check Imre Deak
2025-12-15 19:23 ` [PATCH 04/16] drm/i915/dp: Return a fixed point BPP value from intel_dp_output_bpp() Imre Deak
2025-12-15 19:23 ` [PATCH 05/16] drm/i915/dp: Use a mode's crtc_clock vs. clock during state computation Imre Deak
2025-12-15 19:23 ` [PATCH 06/16] drm/i915/dp: Factor out intel_dp_link_bw_overhead() Imre Deak
2025-12-15 19:23 ` [PATCH 07/16] drm/i915/dp: Fix BW check in is_bw_sufficient_for_dsc_config() Imre Deak
2025-12-15 19:23 ` [PATCH 08/16] drm/i915/dp: Use the effective data rate for DP BW calculation Imre Deak
2025-12-15 19:23 ` [PATCH 09/16] drm/i915/dp: Use the effective data rate for DP compressed " Imre Deak
2025-12-15 19:23 ` [PATCH 10/16] drm/i915/dp: Account with MST, SSC BW overhead for uncompressed DP-MST stream BW Imre Deak
2025-12-15 19:23 ` [PATCH 11/16] drm/i915/dp: Account with DSC BW overhead for compressed DP-SST " Imre Deak
2025-12-15 19:23 ` [PATCH 12/16] drm/i915/dp: Account with pipe joiner max compressed BPP limit for DP-MST and eDP Imre Deak
2025-12-15 19:23 ` [PATCH 13/16] drm/i915/dp: Fail state computation for invalid min/max link BPP values Imre Deak
2025-12-15 19:23 ` [PATCH 14/16] drm/i915/dp: Fail state computation for invalid max throughput BPP value Imre Deak
2025-12-15 19:23 ` [PATCH 15/16] drm/i915/dp: Fail state computation for invalid max sink compressed " Imre Deak
2025-12-15 19:23 ` [PATCH 16/16] drm/i915/dp: Fail state computation for invalid DSC source input BPP values Imre Deak
2025-12-15 20:21 ` ✓ i915.CI.BAT: success for drm/i915/dp: Clean up link BW/DSC slice config computation (fixes) Patchwork
2025-12-15 22:16 ` ✗ CI.checkpatch: warning " Patchwork
2025-12-15 22:17 ` ✓ CI.KUnit: success " Patchwork
2025-12-15 22:36 ` ✗ CI.checksparse: warning " Patchwork
2025-12-15 23:31 ` ✓ Xe.CI.BAT: success " Patchwork
2025-12-16  2:20 ` ✓ i915.CI.Full: " Patchwork
2025-12-19 15:21   ` Imre Deak
2025-12-16  9:27 ` ✗ Xe.CI.Full: failure " Patchwork
2025-12-16 17:30 ` [PATCH 00/16] " Imre Deak
2025-12-18 12:00   ` Imre Deak
2025-12-19 13:28     ` Maarten Lankhorst

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251215192357.172201-3-imre.deak@intel.com \
    --to=imre.deak@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=luciano.coelho@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.