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

Reply via email to