Message ID | 20180912005607.29522-5-manasi.d.navare@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Display Stream Compression enabling on eDP/DP | expand |
On 9/12/2018 6:25 AM, Manasi Navare wrote: > This patch adds inline functions and helpers for obtaining > DP sink's supported DSC parameters like DSC sink support, > eDP compressed BPP supported, maximum slice count supported > by the sink devices, DSC line buffer bit depth supported on DP sink, > DSC sink maximum color depth by parsing corresponding DPCD registers. > > v4: > * Add helper to give line buf bit depth (Manasi) > * Correct the bit masking in color depth helper (manasi) > v3: > * Use SLICE_CAP_2 for DP (Anusha) > v2: > * Add DSC sink support macro (Jani N) > > Cc: Gaurav K Singh <gaurav.k.singh@intel.com> > Cc: dri-devel@lists.freedesktop.org > Cc: Jani Nikula <jani.nikula@linux.intel.com> > Cc: Ville Syrjala <ville.syrjala@linux.intel.com> > Cc: Anusha Srivatsa <anusha.srivatsa@intel.com> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com> > Reviewed-by: Anusha Srivatsa <anusha.srivatsa@intel.com> This patch looks good to me. Reviewed-by: Gaurav K Singh <gaurav.k.singh@intel.com> > --- > drivers/gpu/drm/drm_dp_helper.c | 90 +++++++++++++++++++++++++++++++++ > include/drm/drm_dp_helper.h | 30 +++++++++++ > 2 files changed, 120 insertions(+) > > diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c > index 8c6b9fd89f8a..5d5879f115ce 100644 > --- a/drivers/gpu/drm/drm_dp_helper.c > +++ b/drivers/gpu/drm/drm_dp_helper.c > @@ -1337,3 +1337,93 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, > return 0; > } > EXPORT_SYMBOL(drm_dp_read_desc); > + > +/** > + * DRM DP Helpers for DSC > + */ > +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 eDP, register DSC_SLICE_CAPABILITIES_1 gives slice count */ > + 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; > + } else { > + /* 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; > + 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; > + 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; > +} > +EXPORT_SYMBOL(drm_dp_dsc_sink_max_slice_count); > + > +u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) > +{ > + u8 line_buf_depth = dsc_dpcd[DP_DSC_LINE_BUF_BIT_DEPTH - DP_DSC_SUPPORT]; > + > + switch (line_buf_depth & DP_DSC_LINE_BUF_BIT_DEPTH_MASK) { > + case DP_DSC_LINE_BUF_BIT_DEPTH_9: > + return 9; > + case DP_DSC_LINE_BUF_BIT_DEPTH_10: > + return 10; > + case DP_DSC_LINE_BUF_BIT_DEPTH_11: > + return 11; > + case DP_DSC_LINE_BUF_BIT_DEPTH_12: > + return 12; > + case DP_DSC_LINE_BUF_BIT_DEPTH_13: > + return 13; > + case DP_DSC_LINE_BUF_BIT_DEPTH_14: > + return 14; > + case DP_DSC_LINE_BUF_BIT_DEPTH_15: > + return 15; > + case DP_DSC_LINE_BUF_BIT_DEPTH_16: > + return 16; > + case DP_DSC_LINE_BUF_BIT_DEPTH_8: > + return 8; > + } > + > + return 0; > +} > +EXPORT_SYMBOL(drm_dp_dsc_sink_line_buf_depth); > + > +u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) > +{ > + u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; > + > + if (color_depth & DP_DSC_12_BPC) > + return 12; > + if (color_depth & DP_DSC_10_BPC) > + return 10; > + if (color_depth & DP_DSC_8_BPC) > + return 8; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_dp_dsc_sink_max_color_depth); > diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h > index 7f6237cad10d..ce6297908fd6 100644 > --- a/include/drm/drm_dp_helper.h > +++ b/include/drm/drm_dp_helper.h > @@ -1065,6 +1065,36 @@ drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) > return dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT; > } > > +/* DP/eDP DSC support */ > +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]); > +u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE]); > + > +static inline bool > +drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) > +{ > + return dsc_dpcd[DP_DSC_SUPPORT - DP_DSC_SUPPORT] & > + DP_DSC_DECOMPRESSION_IS_SUPPORTED; > +} > + > +static inline u16 > +drm_edp_dsc_sink_output_bpp(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) > +{ > + return dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] | > + (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] & > + DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK << > + DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT); > +} > + > +static inline u32 > +drm_dp_dsc_sink_max_slice_width(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) > +{ > + /* Max Slicewidth = Number of Pixels * 320 */ > + return dsc_dpcd[DP_DSC_MAX_SLICE_WIDTH - DP_DSC_SUPPORT] * > + DP_DSC_SLICE_WIDTH_MULTIPLIER; > +} > + > /* > * DisplayPort AUX channel > */
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 8c6b9fd89f8a..5d5879f115ce 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -1337,3 +1337,93 @@ int drm_dp_read_desc(struct drm_dp_aux *aux, struct drm_dp_desc *desc, return 0; } EXPORT_SYMBOL(drm_dp_read_desc); + +/** + * DRM DP Helpers for DSC + */ +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 eDP, register DSC_SLICE_CAPABILITIES_1 gives slice count */ + 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; + } else { + /* 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; + 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; + 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; +} +EXPORT_SYMBOL(drm_dp_dsc_sink_max_slice_count); + +u8 drm_dp_dsc_sink_line_buf_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) +{ + u8 line_buf_depth = dsc_dpcd[DP_DSC_LINE_BUF_BIT_DEPTH - DP_DSC_SUPPORT]; + + switch (line_buf_depth & DP_DSC_LINE_BUF_BIT_DEPTH_MASK) { + case DP_DSC_LINE_BUF_BIT_DEPTH_9: + return 9; + case DP_DSC_LINE_BUF_BIT_DEPTH_10: + return 10; + case DP_DSC_LINE_BUF_BIT_DEPTH_11: + return 11; + case DP_DSC_LINE_BUF_BIT_DEPTH_12: + return 12; + case DP_DSC_LINE_BUF_BIT_DEPTH_13: + return 13; + case DP_DSC_LINE_BUF_BIT_DEPTH_14: + return 14; + case DP_DSC_LINE_BUF_BIT_DEPTH_15: + return 15; + case DP_DSC_LINE_BUF_BIT_DEPTH_16: + return 16; + case DP_DSC_LINE_BUF_BIT_DEPTH_8: + return 8; + } + + return 0; +} +EXPORT_SYMBOL(drm_dp_dsc_sink_line_buf_depth); + +u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) +{ + u8 color_depth = dsc_dpcd[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; + + if (color_depth & DP_DSC_12_BPC) + return 12; + if (color_depth & DP_DSC_10_BPC) + return 10; + if (color_depth & DP_DSC_8_BPC) + return 8; + + return 0; +} +EXPORT_SYMBOL(drm_dp_dsc_sink_max_color_depth); diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 7f6237cad10d..ce6297908fd6 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -1065,6 +1065,36 @@ drm_dp_is_branch(const u8 dpcd[DP_RECEIVER_CAP_SIZE]) return dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT; } +/* DP/eDP DSC support */ +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]); +u8 drm_dp_dsc_sink_max_color_depth(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SIZE]); + +static inline bool +drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) +{ + return dsc_dpcd[DP_DSC_SUPPORT - DP_DSC_SUPPORT] & + DP_DSC_DECOMPRESSION_IS_SUPPORTED; +} + +static inline u16 +drm_edp_dsc_sink_output_bpp(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) +{ + return dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] | + (dsc_dpcd[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] & + DP_DSC_MAX_BITS_PER_PIXEL_HI_MASK << + DP_DSC_MAX_BITS_PER_PIXEL_HI_SHIFT); +} + +static inline u32 +drm_dp_dsc_sink_max_slice_width(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE]) +{ + /* Max Slicewidth = Number of Pixels * 320 */ + return dsc_dpcd[DP_DSC_MAX_SLICE_WIDTH - DP_DSC_SUPPORT] * + DP_DSC_SLICE_WIDTH_MULTIPLIER; +} + /* * DisplayPort AUX channel */