Account for DSC slice overhead bubbles and adjust the pixel rate while
checking the pixel rate against the max dotclock limits.

Signed-off-by: Ankit Nautiyal <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_dp.c     | 19 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dp.h     |  2 ++
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 13 +++++++++++++
 drivers/gpu/drm/i915/display/intel_vdsc.c   |  1 -
 drivers/gpu/drm/i915/display/intel_vdsc.h   |  3 +++
 5 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 9f73a1307b6c..a6a1a803d860 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1442,6 +1442,8 @@ bool intel_dp_has_dsc(const struct intel_connector 
*connector)
 
 bool intel_dp_pixel_rate_fits_dotclk(struct intel_display *display,
                                     int target_clock,
+                                    int htotal,
+                                    int dsc_slice_count,
                                     int num_joined_pipes)
 {
        int max_dotclk = display->cdclk.max_dotclk_freq;
@@ -1449,6 +1451,12 @@ bool intel_dp_pixel_rate_fits_dotclk(struct 
intel_display *display,
 
        effective_dotclk_limit = max_dotclk * num_joined_pipes;
 
+       if (dsc_slice_count)
+               target_clock = 
intel_dsc_get_pixel_rate_with_dsc_bubbles(display,
+                                                                        
target_clock,
+                                                                        htotal,
+                                                                        
dsc_slice_count);
+
        return target_clock <= effective_dotclk_limit;
 }
 
@@ -1579,8 +1587,13 @@ intel_dp_mode_valid(struct drm_connector *_connector,
                if (status != MODE_OK)
                        continue;
 
+               if (!dsc)
+                       dsc_slice_count = 0;
+
                if (intel_dp_pixel_rate_fits_dotclk(display,
                                                    target_clock,
+                                                   mode->htotal,
+                                                   dsc_slice_count,
                                                    num_joined_pipes)) {
                        status = MODE_OK;
                        break;
@@ -2898,6 +2911,7 @@ intel_dp_compute_link_config(struct intel_encoder 
*encoder,
 
        for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) {
                enum joiner_type joiner = joiner_candidates[i];
+               int dsc_slice_count = 0;
 
                if (joiner == FORCED_JOINER) {
                        if (!connector->force_joined_pipes)
@@ -2939,8 +2953,13 @@ intel_dp_compute_link_config(struct intel_encoder 
*encoder,
                if (ret)
                        continue;
 
+               if (crtc_state->dsc.compression_enable)
+                       dsc_slice_count = 
intel_dsc_line_slice_count(&crtc_state->dsc.slice_config);
+
                if (intel_dp_pixel_rate_fits_dotclk(display,
                                                    adjusted_mode->crtc_clock,
+                                                   adjusted_mode->crtc_htotal,
+                                                   dsc_slice_count,
                                                    num_joined_pipes)) {
                        ret = 0;
                        break;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 0c1cd843bd0a..78b457b11f07 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -235,6 +235,8 @@ int intel_dp_sdp_min_guardband(const struct 
intel_crtc_state *crtc_state,
 int intel_dp_hdisplay_limit(struct intel_display *display);
 bool intel_dp_pixel_rate_fits_dotclk(struct intel_display *display,
                                     int target_clock,
+                                    int htotal,
+                                    int dsc_slice_count,
                                     int num_joined_pipes);
 
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 7c957351467e..25d229843459 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -710,6 +710,7 @@ static int mst_stream_compute_config(struct intel_encoder 
*encoder,
 
        for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) {
                enum joiner_type joiner = joiner_candidates[i];
+               int dsc_slice_count = 0;
 
                ret = -EINVAL;
 
@@ -741,8 +742,12 @@ static int mst_stream_compute_config(struct intel_encoder 
*encoder,
                if (ret)
                        continue;
 
+               dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, 
pipe_config);
+
                if (intel_dp_pixel_rate_fits_dotclk(display,
                                                    adjusted_mode->clock,
+                                                   adjusted_mode->htotal,
+                                                   dsc_slice_count,
                                                    num_joined_pipes)) {
                        ret = 0;
                        break;
@@ -1542,6 +1547,7 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
 
        for (i = 0; i < ARRAY_SIZE(joiner_candidates); i++) {
                enum joiner_type joiner = joiner_candidates[i];
+               int dsc_slice_count = 0;
 
                *status = MODE_CLOCK_HIGH;
 
@@ -1569,6 +1575,11 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
                         */
                        int pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, 
U8_MAX);
 
+                       dsc_slice_count = 
intel_dp_dsc_get_slice_count(connector,
+                                                                      
mode->clock,
+                                                                      
mode->hdisplay,
+                                                                      
num_joined_pipes);
+
                        if (!drm_dp_is_uhbr_rate(max_link_clock))
                                bw_overhead_flags |= DRM_DP_BW_OVERHEAD_FEC;
 
@@ -1593,6 +1604,8 @@ mst_connector_mode_valid_ctx(struct drm_connector 
*_connector,
 
                if (intel_dp_pixel_rate_fits_dotclk(display,
                                                    mode->clock,
+                                                   mode->htotal,
+                                                   dsc_slice_count,
                                                    num_joined_pipes)) {
                        *status = MODE_OK;
                        break;
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c 
b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 642a89270d8e..7e53201b3cb1 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -1104,7 +1104,6 @@ void intel_vdsc_state_dump(struct drm_printer *p, int 
indent,
        drm_dsc_dump_config(p, indent, &crtc_state->dsc.config);
 }
 
-static
 int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display,
                                              int pixel_rate, int htotal,
                                              int dsc_horizontal_slices)
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h 
b/drivers/gpu/drm/i915/display/intel_vdsc.h
index aeb17670307b..f4d5b37293cf 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -41,5 +41,8 @@ void intel_vdsc_state_dump(struct drm_printer *p, int indent,
                           const struct intel_crtc_state *crtc_state);
 int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state);
 unsigned int intel_vdsc_prefill_lines(const struct intel_crtc_state 
*crtc_state);
+int intel_dsc_get_pixel_rate_with_dsc_bubbles(struct intel_display *display,
+                                             int pixel_rate, int htotal,
+                                             int dsc_horizontal_slices);
 
 #endif /* __INTEL_VDSC_H__ */
-- 
2.45.2

Reply via email to