drm/dp_mst: Fix fractional DSC bpp handling
authorjsg <jsg@openbsd.org>
Mon, 29 Jan 2024 01:23:04 +0000 (01:23 +0000)
committerjsg <jsg@openbsd.org>
Mon, 29 Jan 2024 01:23:04 +0000 (01:23 +0000)
From Ville Syrjala
4e042f022255604c68ab5d5f73c8f437d24d651e in linux-6.6.y/6.6.14
7707dd6022593f3edd8e182e7935870cf326f874 in mainline linux

sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm.c
sys/dev/pci/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
sys/dev/pci/drm/display/drm_dp_mst_topology.c
sys/dev/pci/drm/i915/display/intel_dp_mst.c
sys/dev/pci/drm/include/drm/display/drm_dp_mst_helper.h

index 9400cd7..241bd61 100644 (file)
@@ -6886,7 +6886,7 @@ static int dm_encoder_helper_atomic_check(struct drm_encoder *encoder,
                                                                    max_bpc);
                bpp = convert_dc_color_depth_into_bpc(color_depth) * 3;
                clock = adjusted_mode->clock;
-               dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false);
+               dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp << 4);
        }
 
        dm_new_connector_state->vcpi_slots =
index 28f5eb9..10dd4cd 100644 (file)
@@ -1636,7 +1636,7 @@ enum dc_status dm_dp_mst_is_port_support_mode(
        } else {
                /* check if mode could be supported within full_pbn */
                bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3;
-               pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false);
+               pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp << 4);
                if (pbn > full_pbn)
                        return DC_FAIL_BANDWIDTH_VALIDATE;
        }
index 18a02f0..778b596 100644 (file)
@@ -4700,13 +4700,12 @@ EXPORT_SYMBOL(drm_dp_check_act_status);
 
 /**
  * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode.
- * @clock: dot clock for the mode
- * @bpp: bpp for the mode.
- * @dsc: DSC mode. If true, bpp has units of 1/16 of a bit per pixel
+ * @clock: dot clock
+ * @bpp: bpp as .4 binary fixed point
  *
  * This uses the formula in the spec to calculate the PBN value for a mode.
  */
-int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc)
+int drm_dp_calc_pbn_mode(int clock, int bpp)
 {
        /*
         * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
@@ -4717,18 +4716,9 @@ int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc)
         * peak_kbps *= (1006/1000)
         * peak_kbps *= (64/54)
         * peak_kbps *= 8    convert to bytes
-        *
-        * If the bpp is in units of 1/16, further divide by 16. Put this
-        * factor in the numerator rather than the denominator to avoid
-        * integer overflow
         */
-
-       if (dsc)
-               return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006),
-                                       8 * 54 * 1000 * 1000);
-
-       return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006),
-                               8 * 54 * 1000 * 1000);
+       return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006 >> 4),
+                               1000 * 8 * 54 * 1000);
 }
 EXPORT_SYMBOL(drm_dp_calc_pbn_mode);
 
index 77bd131..f104bd7 100644 (file)
@@ -109,8 +109,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
                        continue;
 
                crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock,
-                                                      dsc ? bpp << 4 : bpp,
-                                                      dsc);
+                                                      bpp << 4);
 
                slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr,
                                                      connector->port,
@@ -941,7 +940,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
                return ret;
 
        if (mode_rate > max_rate || mode->clock > max_dotclk ||
-           drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn) {
+           drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) {
                *status = MODE_CLOCK_HIGH;
                return 0;
        }
index 6c62607..06dc5d1 100644 (file)
@@ -832,7 +832,7 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector,
 int drm_dp_get_vc_payload_bw(const struct drm_dp_mst_topology_mgr *mgr,
                             int link_rate, int link_lane_count);
 
-int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc);
+int drm_dp_calc_pbn_mode(int clock, int bpp);
 
 void drm_dp_mst_update_slots(struct drm_dp_mst_topology_state *mst_state, uint8_t link_encoding_cap);