Misc fixes and refactoring in HDMI2.1 PCON helper functions. V2: Addressed review comments from Jani. Splitted the drm_helper addition and usage in separate patches.
Ankit Nautiyal (4): drm/i915/hdmi: Fix the definition of intel_hdmi_dsc_get_bpp drm/edid: Add helper to get max FRL rate for an HDMI sink drm/i915/dp: Use the drm helpers for getting max FRL rate drm/i915/display: Simplify helpers for getting DSC slices and bpp
drivers/gpu/drm/drm_edid.c | 38 +++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dp.c | 26 ++++++---------- drivers/gpu/drm/i915/display/intel_hdmi.c | 26 +++++++++------- drivers/gpu/drm/i915/display/intel_hdmi.h | 9 ++++-- include/drm/drm_edid.h | 2 ++ 5 files changed, 70 insertions(+), 31 deletions(-)
Fix the data-type of the argument output_format to enum, for the function intel_hdmi_dsc_get_bpp.
v2: Fixed formatting issues in commit message (Jani). Avoided including the header intel_display_types.h, instead used forward declaration for the appropriate enum. (Jani).
Fixes: 6e6cb758e035 ("drm/i915: Add helper functions for calculating DSC parameters for HDMI2.1") Cc: Uma Shankar uma.shankar@intel.com Cc: Jani Nikula jani.nikula@intel.com Signed-off-by: Ankit Nautiyal ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_hdmi.c | 4 ++-- drivers/gpu/drm/i915/display/intel_hdmi.h | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 45cf0ab04009..381a9de3a015 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -3126,8 +3126,8 @@ intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, */ int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int num_slices, - int output_format, bool hdmi_all_bpp, - int hdmi_max_chunk_bytes) + enum intel_output_format output_format, + bool hdmi_all_bpp, int hdmi_max_chunk_bytes) { int max_dsc_bpp, min_dsc_bpp; int target_bytes; diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h index b577c38fa90c..ea2a3456bd4b 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.h +++ b/drivers/gpu/drm/i915/display/intel_hdmi.h @@ -22,6 +22,7 @@ struct intel_hdmi; struct drm_connector_state; union hdmi_infoframe; enum port; +enum intel_output_format;
void intel_hdmi_init_connector(struct intel_digital_port *dig_port, struct intel_connector *intel_connector); @@ -49,8 +50,8 @@ bool intel_hdmi_limited_color_range(const struct intel_crtc_state *crtc_state, bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc, bool has_hdmi_sink, bool ycbcr420_output); int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, - int num_slices, int output_format, bool hdmi_all_bpp, - int hdmi_max_chunk_bytes); + int num_slices, enum intel_output_format output_format, + bool hdmi_all_bpp, int hdmi_max_chunk_bytes); int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, int src_max_slices, int src_max_slice_width, int hdmi_max_slices, int hdmi_throughput);
Add the helpers for getting the max FRL rate with and without DSC for an HDMI sink.
v2: Fix the subject line and documentation of the helpers (Jani). Split the helper definitions and usage into separate patches. (Jani).
Signed-off-by: Ankit Nautiyal ankit.k.nautiyal@intel.com --- drivers/gpu/drm/drm_edid.c | 38 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_edid.h | 2 ++ 2 files changed, 40 insertions(+)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index eb61a1a92dc0..c209fd6b24a2 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -6176,3 +6176,41 @@ void drm_update_tile_info(struct drm_connector *connector, connector->tile_group = NULL; } } + +/** + * drm_hdmi_sink_max_frl - get the max frl rate, if supported + * @connector - connector with HDMI sink + * + * RETURNS: + * max frl rate supported by the HDMI sink, 0 if FRL not supported + */ +int drm_hdmi_sink_max_frl(struct drm_connector *connector) +{ + int max_lanes = connector->display_info.hdmi.max_lanes; + int rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane; + + return max_lanes * rate_per_lane; +} +EXPORT_SYMBOL(drm_hdmi_sink_max_frl); + +/** + * drm_hdmi_sink_dsc_max_frl - get the max frl rate from HDMI sink with + * DSC1.2 compression. + * @connector - connector with HDMI sink + * + * RETURNS: + * max frl rate supported by the HDMI sink with DSC1.2, 0 if FRL not supported + */ +int drm_hdmi_sink_dsc_max_frl(struct drm_connector *connector) +{ + int max_dsc_lanes, dsc_rate_per_lane; + + if (!connector->display_info.hdmi.dsc_cap.v_1p2) + return 0; + + max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes; + dsc_rate_per_lane = connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane; + + return max_dsc_lanes * dsc_rate_per_lane; +} +EXPORT_SYMBOL(drm_hdmi_sink_dsc_max_frl); diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index 18f6c700f6d0..5003e1254c44 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h @@ -592,6 +592,8 @@ drm_display_mode_from_cea_vic(struct drm_device *dev, u8 video_code); const u8 *drm_find_edid_extension(const struct edid *edid, int ext_id, int *ext_index); +int drm_hdmi_sink_max_frl(struct drm_connector *connector); +int drm_hdmi_sink_dsc_max_frl(struct drm_connector *connector);
#endif /* __DRM_EDID_H__ */
Re-use the drm helpers for getting max FRL rate for an HDMI sink. This patch removes the duplicate code and calls the already defined drm helpers for the task.
Signed-off-by: Ankit Nautiyal ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4d4579a301f6..f7fe7de7e553 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2190,22 +2190,13 @@ static int intel_dp_hdmi_sink_max_frl(struct intel_dp *intel_dp) { struct intel_connector *intel_connector = intel_dp->attached_connector; struct drm_connector *connector = &intel_connector->base; - int max_frl_rate; - int max_lanes, rate_per_lane; - int max_dsc_lanes, dsc_rate_per_lane; + int max_frl = drm_hdmi_sink_max_frl(connector); + int dsc_max_frl = drm_hdmi_sink_dsc_max_frl(connector);
- max_lanes = connector->display_info.hdmi.max_lanes; - rate_per_lane = connector->display_info.hdmi.max_frl_rate_per_lane; - max_frl_rate = max_lanes * rate_per_lane; + if (dsc_max_frl) + return min(max_frl, dsc_max_frl);
- if (connector->display_info.hdmi.dsc_cap.v_1p2) { - max_dsc_lanes = connector->display_info.hdmi.dsc_cap.max_lanes; - dsc_rate_per_lane = connector->display_info.hdmi.dsc_cap.max_frl_rate_per_lane; - if (max_dsc_lanes && dsc_rate_per_lane) - max_frl_rate = min(max_frl_rate, max_dsc_lanes * dsc_rate_per_lane); - } - - return max_frl_rate; + return max_frl; }
static bool
Genralize the helper for getting DSC slice count and compressed bpp for HDMI sink supporting DSC. This patch: -Removes the assumption on the bpc and sends it as an argument for calculating compressed bpc. -Sends the resolution, and output format as parameters for which the DSC paremeters are to be calculated instead of crtc_state.
v2: Added forward declaration for struct drm_display_mode.
Signed-off-by: Ankit Nautiyal ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 7 +++++-- drivers/gpu/drm/i915/display/intel_hdmi.c | 24 ++++++++++++----------- drivers/gpu/drm/i915/display/intel_hdmi.h | 6 ++++-- 3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index f7fe7de7e553..17d08f06499b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2357,7 +2357,9 @@ intel_dp_pcon_dsc_enc_slices(struct intel_dp *intel_dp, int pcon_max_slices = drm_dp_pcon_dsc_max_slices(intel_dp->pcon_dsc_dpcd); int pcon_max_slice_width = drm_dp_pcon_dsc_max_slice_width(intel_dp->pcon_dsc_dpcd);
- return intel_hdmi_dsc_get_num_slices(crtc_state, pcon_max_slices, + return intel_hdmi_dsc_get_num_slices(&crtc_state->hw.adjusted_mode, + crtc_state->output_format, + pcon_max_slices, pcon_max_slice_width, hdmi_max_slices, hdmi_throughput); } @@ -2374,9 +2376,10 @@ intel_dp_pcon_dsc_enc_bpp(struct intel_dp *intel_dp, int pcon_fractional_bpp = drm_dp_pcon_dsc_bpp_incr(intel_dp->pcon_dsc_dpcd); int hdmi_max_chunk_bytes = connector->display_info.hdmi.dsc_cap.total_chunk_kbytes * 1024; + int bpc = crtc_state->pipe_bpp / 3;
return intel_hdmi_dsc_get_bpp(pcon_fractional_bpp, slice_width, - num_slices, output_format, hdmi_all_bpp, + num_slices, output_format, bpc, hdmi_all_bpp, hdmi_max_chunk_bytes); }
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 381a9de3a015..f75e2384da63 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -3004,7 +3004,8 @@ int intel_hdmi_dsc_get_slice_height(int vactive) * intel_hdmi_dsc_get_num_slices - get no. of dsc slices based on dsc encoder * and dsc decoder capabilities * - * @crtc_state: intel crtc_state + * @mode: drm_display_mode for which num of slices are needed + * @output_format : pipe output format * @src_max_slices: maximum slices supported by the DSC encoder * @src_max_slice_width: maximum slice width supported by DSC encoder * @hdmi_max_slices: maximum slices supported by sink DSC decoder @@ -3014,7 +3015,8 @@ int intel_hdmi_dsc_get_slice_height(int vactive) * and decoder. */ int -intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, +intel_hdmi_dsc_get_num_slices(const struct drm_display_mode *mode, + enum intel_output_format output_format, int src_max_slices, int src_max_slice_width, int hdmi_max_slices, int hdmi_throughput) { @@ -3036,7 +3038,7 @@ intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, int max_throughput; /* max clock freq. in khz per slice */ int max_slice_width; int slice_width; - int pixel_clock = crtc_state->hw.adjusted_mode.crtc_clock; + int pixel_clock = mode->crtc_clock;
if (!hdmi_throughput) return 0; @@ -3047,8 +3049,8 @@ intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, * for 4:4:4 is 1.0. Multiplying these factors by 10 and later * dividing adjusted clock value by 10. */ - if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444 || - crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) + if (output_format == INTEL_OUTPUT_FORMAT_YCBCR444 || + output_format == INTEL_OUTPUT_FORMAT_RGB) kslice_adjust = 10; else kslice_adjust = 5; @@ -3103,7 +3105,7 @@ intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, else return 0;
- slice_width = DIV_ROUND_UP(crtc_state->hw.adjusted_mode.hdisplay, target_slices); + slice_width = DIV_ROUND_UP(mode->hdisplay, target_slices); if (slice_width >= max_slice_width) min_slices = target_slices + 1; } while (slice_width >= max_slice_width); @@ -3119,6 +3121,7 @@ intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, * @slice_width: dsc slice width supported by the source and sink * @num_slices: num of slices supported by the source and sink * @output_format: video output format + * @bpc: bits per color * @hdmi_all_bpp: sink supports decoding of 1/16th bpp setting * @hdmi_max_chunk_bytes: max bytes in a line of chunks supported by sink * @@ -3126,7 +3129,7 @@ intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, */ int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int num_slices, - enum intel_output_format output_format, + enum intel_output_format output_format, int bpc, bool hdmi_all_bpp, int hdmi_max_chunk_bytes) { int max_dsc_bpp, min_dsc_bpp; @@ -3144,18 +3147,17 @@ intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int num_slices, * for each bpp we check if no of bytes can be supported by HDMI sink */
- /* Assuming: bpc as 8*/ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { min_dsc_bpp = 6; - max_dsc_bpp = 3 * 4; /* 3*bpc/2 */ + max_dsc_bpp = 3 * bpc / 2; } else if (output_format == INTEL_OUTPUT_FORMAT_YCBCR444 || output_format == INTEL_OUTPUT_FORMAT_RGB) { min_dsc_bpp = 8; - max_dsc_bpp = 3 * 8; /* 3*bpc */ + max_dsc_bpp = 3 * bpc; } else { /* Assuming 4:2:2 encoding */ min_dsc_bpp = 7; - max_dsc_bpp = 2 * 8; /* 2*bpc */ + max_dsc_bpp = 2 * bpc; }
/* diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.h b/drivers/gpu/drm/i915/display/intel_hdmi.h index ea2a3456bd4b..8a2941d285de 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.h +++ b/drivers/gpu/drm/i915/display/intel_hdmi.h @@ -12,6 +12,7 @@ #include "i915_reg.h"
struct drm_connector; +struct drm_display_mode; struct drm_encoder; struct drm_i915_private; struct intel_connector; @@ -51,8 +52,9 @@ bool intel_hdmi_bpc_possible(const struct intel_crtc_state *crtc_state, int bpc, bool has_hdmi_sink, bool ycbcr420_output); int intel_hdmi_dsc_get_bpp(int src_fractional_bpp, int slice_width, int num_slices, enum intel_output_format output_format, - bool hdmi_all_bpp, int hdmi_max_chunk_bytes); -int intel_hdmi_dsc_get_num_slices(const struct intel_crtc_state *crtc_state, + int bpc, bool hdmi_all_bpp, int hdmi_max_chunk_bytes); +int intel_hdmi_dsc_get_num_slices(const struct drm_display_mode *mode, + enum intel_output_format output_format, int src_max_slices, int src_max_slice_width, int hdmi_max_slices, int hdmi_throughput); int intel_hdmi_dsc_get_slice_height(int vactive);
dri-devel@lists.freedesktop.org