mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-02-16 00:58:42 -05:00
drm/dp: Add drm_dp_dsc_sink_slice_count_mask()
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> Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patch.msgid.link/20251215192357.172201-3-imre.deak@intel.com
This commit is contained in:
@@ -2704,6 +2704,71 @@ 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_slice_count_to_mask() - Convert a slice count to a slice count mask
|
||||
* @slice_count: slice count
|
||||
*
|
||||
* 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:
|
||||
* 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
|
||||
*/
|
||||
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)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(24);
|
||||
if (slice_cap2 & DP_DSC_20_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(20);
|
||||
if (slice_cap2 & DP_DSC_16_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(16);
|
||||
}
|
||||
|
||||
/* DP, eDP v1.5+ */
|
||||
if (slice_cap1 & DP_DSC_12_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(12);
|
||||
if (slice_cap1 & DP_DSC_10_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(10);
|
||||
if (slice_cap1 & DP_DSC_8_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(8);
|
||||
if (slice_cap1 & DP_DSC_6_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(6);
|
||||
/* DP, eDP v1.4+ */
|
||||
if (slice_cap1 & DP_DSC_4_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(4);
|
||||
if (slice_cap1 & DP_DSC_2_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(2);
|
||||
if (slice_cap1 & DP_DSC_1_PER_DP_DSC_SINK)
|
||||
mask |= drm_dp_dsc_slice_count_to_mask(1);
|
||||
|
||||
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.
|
||||
@@ -2723,38 +2788,7 @@ EXPORT_SYMBOL(drm_dp_dsc_sink_bpp_incr);
|
||||
u8 drm_dp_dsc_sink_max_slice_count(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];
|
||||
|
||||
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;
|
||||
if (slice_cap2 & DP_DSC_20_PER_DP_DSC_SINK)
|
||||
return 20;
|
||||
if (slice_cap2 & DP_DSC_16_PER_DP_DSC_SINK)
|
||||
return 16;
|
||||
}
|
||||
|
||||
/* DP, eDP v1.5+ */
|
||||
if (slice_cap1 & DP_DSC_12_PER_DP_DSC_SINK)
|
||||
return 12;
|
||||
if (slice_cap1 & DP_DSC_10_PER_DP_DSC_SINK)
|
||||
return 10;
|
||||
if (slice_cap1 & DP_DSC_8_PER_DP_DSC_SINK)
|
||||
return 8;
|
||||
if (slice_cap1 & DP_DSC_6_PER_DP_DSC_SINK)
|
||||
return 6;
|
||||
/* DP, eDP v1.4+ */
|
||||
if (slice_cap1 & DP_DSC_4_PER_DP_DSC_SINK)
|
||||
return 4;
|
||||
if (slice_cap1 & DP_DSC_2_PER_DP_DSC_SINK)
|
||||
return 2;
|
||||
if (slice_cap1 & DP_DSC_1_PER_DP_DSC_SINK)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return fls(drm_dp_dsc_sink_slice_count_mask(dsc_dpcd, is_edp));
|
||||
}
|
||||
EXPORT_SYMBOL(drm_dp_dsc_sink_max_slice_count);
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user