Add intel_dsc_get_slice_config() and move the logic to select a given slice configuration to that function from the configuration loop in intel_dp_dsc_get_slice_count(). The same functionality can be used by other outputs like DSI as well, done as a follow-up.
Signed-off-by: Imre Deak <[email protected]> --- drivers/gpu/drm/i915/display/intel_dp.c | 22 ++++------- drivers/gpu/drm/i915/display/intel_vdsc.c | 48 +++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_vdsc.h | 4 ++ 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index a4ff1ffc8f7d4..461f80bd54cbf 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1029,28 +1029,20 @@ u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector, * TGL+: 2x4 (TODO: Add support for this) */ for (slices_per_pipe = 1; slices_per_pipe <= 4; slices_per_pipe++) { - int slices_per_line = slices_per_pipe * num_joined_pipes; + struct intel_dsc_slice_config config; + int slices_per_line; - /* - * 3 DSC Slices per pipe need 3 DSC engines, which is supported only - * with Ultrajoiner only for some platforms. - */ - if (slices_per_pipe == 3 && - (!HAS_DSC_3ENGINES(display) || num_joined_pipes != 4)) + if (!intel_dsc_get_slice_config(display, + num_joined_pipes, slices_per_pipe, + &config)) continue; + slices_per_line = intel_dsc_line_slice_count(&config); + if (!(drm_dp_dsc_slice_count_to_mask(slices_per_line) & sink_slice_count_mask)) continue; - /* - * Bigjoiner needs small joiner to be enabled. - * So there should be at least 2 dsc slices per pipe, - * whenever bigjoiner is enabled. - */ - if (num_joined_pipes > 1 && slices_per_pipe < 2) - continue; - if (mode_hdisplay % slices_per_line) continue; diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 190ce567bc7fa..9910134d52653 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -40,6 +40,54 @@ int intel_dsc_line_slice_count(const struct intel_dsc_slice_config *config) return config->pipes_per_line * config->streams_per_pipe * config->slices_per_stream; } +bool intel_dsc_get_slice_config(struct intel_display *display, + int pipes_per_line, int slices_per_pipe, + struct intel_dsc_slice_config *config) +{ + int streams_per_pipe; + + /* TODO: Add support for 8 slices per pipe on TGL+. */ + switch (slices_per_pipe) { + case 3: + /* + * 3 DSC Slices per pipe need 3 DSC engines, which is supported only + * with Ultrajoiner only for some platforms. + */ + if (!HAS_DSC_3ENGINES(display) || pipes_per_line != 4) + return false; + + streams_per_pipe = 3; + break; + case 4: + /* TODO: Consider using 1 DSC engine stream x 4 slices instead. */ + case 2: + /* TODO: Consider using 1 DSC engine stream x 2 slices instead. */ + streams_per_pipe = 2; + break; + case 1: + /* + * Bigjoiner needs small joiner to be enabled. + * So there should be at least 2 dsc slices per pipe, + * whenever bigjoiner is enabled. + */ + if (pipes_per_line > 1) + return false; + + streams_per_pipe = 1; + break; + default: + MISSING_CASE(slices_per_pipe); + return false; + } + + config->pipes_per_line = pipes_per_line; + config->streams_per_pipe = streams_per_pipe; + config->slices_per_stream = slices_per_pipe / streams_per_pipe; + + return true; +} + + static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { struct intel_display *display = to_intel_display(crtc); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h index e61116d5297c8..aeb17670307b1 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h @@ -13,11 +13,15 @@ struct drm_printer; enum transcoder; struct intel_crtc; struct intel_crtc_state; +struct intel_display; struct intel_dsc_slice_config; struct intel_encoder; bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state); int intel_dsc_line_slice_count(const struct intel_dsc_slice_config *config); +bool intel_dsc_get_slice_config(struct intel_display *display, + int num_joined_pipes, int slice_per_pipe, + struct intel_dsc_slice_config *config); void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state); void intel_dsc_enable(const struct intel_crtc_state *crtc_state); void intel_dsc_disable(const struct intel_crtc_state *crtc_state); -- 2.49.1
