Commit dc59990e authored by Ankit Nautiyal's avatar Ankit Nautiyal

drm/i915/dp: Iterate over output bpp with fractional step size

This patch adds support to iterate over compressed output bpp as per the
fractional step, supported by DP sink.

v2:
-Avoid ending up with compressed bpp, same as pipe bpp. (Stan)
Signed-off-by: default avatarAnkit Nautiyal <ankit.k.nautiyal@intel.com>
Reviewed-by: default avatarSuraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: default avatarSui Jingfeng <suijingfeng@loongson.cn>
Link: https://patchwork.freedesktop.org/patch/msgid/20231110101020.4067342-7-ankit.k.nautiyal@intel.com
parent 2df50cb4
...@@ -1737,15 +1737,15 @@ static bool intel_dp_dsc_supports_format(const struct intel_connector *connector ...@@ -1737,15 +1737,15 @@ static bool intel_dp_dsc_supports_format(const struct intel_connector *connector
return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, sink_dsc_format); return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, sink_dsc_format);
} }
static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock, static bool is_bw_sufficient_for_dsc_config(u16 compressed_bppx16, u32 link_clock,
u32 lane_count, u32 mode_clock, u32 lane_count, u32 mode_clock,
enum intel_output_format output_format, enum intel_output_format output_format,
int timeslots) int timeslots)
{ {
u32 available_bw, required_bw; u32 available_bw, required_bw;
available_bw = (link_clock * lane_count * timeslots) / 8; available_bw = (link_clock * lane_count * timeslots * 16) / 8;
required_bw = compressed_bpp * (intel_dp_mode_to_fec_clock(mode_clock)); required_bw = compressed_bppx16 * (intel_dp_mode_to_fec_clock(mode_clock));
return available_bw > required_bw; return available_bw > required_bw;
} }
...@@ -1753,7 +1753,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock, ...@@ -1753,7 +1753,7 @@ static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
static int dsc_compute_link_config(struct intel_dp *intel_dp, static int dsc_compute_link_config(struct intel_dp *intel_dp,
struct intel_crtc_state *pipe_config, struct intel_crtc_state *pipe_config,
struct link_config_limits *limits, struct link_config_limits *limits,
u16 compressed_bpp, u16 compressed_bppx16,
int timeslots) int timeslots)
{ {
const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
...@@ -1768,8 +1768,8 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp, ...@@ -1768,8 +1768,8 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
for (lane_count = limits->min_lane_count; for (lane_count = limits->min_lane_count;
lane_count <= limits->max_lane_count; lane_count <= limits->max_lane_count;
lane_count <<= 1) { lane_count <<= 1) {
if (!is_bw_sufficient_for_dsc_config(compressed_bpp, link_rate, lane_count, if (!is_bw_sufficient_for_dsc_config(compressed_bppx16, link_rate,
adjusted_mode->clock, lane_count, adjusted_mode->clock,
pipe_config->output_format, pipe_config->output_format,
timeslots)) timeslots))
continue; continue;
...@@ -1882,7 +1882,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, ...@@ -1882,7 +1882,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
ret = dsc_compute_link_config(intel_dp, ret = dsc_compute_link_config(intel_dp,
pipe_config, pipe_config,
limits, limits,
valid_dsc_bpp[i], valid_dsc_bpp[i] << 4,
timeslots); timeslots);
if (ret == 0) { if (ret == 0) {
pipe_config->dsc.compressed_bpp_x16 = pipe_config->dsc.compressed_bpp_x16 =
...@@ -1902,6 +1902,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp, ...@@ -1902,6 +1902,7 @@ icl_dsc_compute_link_config(struct intel_dp *intel_dp,
*/ */
static int static int
xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
const struct intel_connector *connector,
struct intel_crtc_state *pipe_config, struct intel_crtc_state *pipe_config,
struct link_config_limits *limits, struct link_config_limits *limits,
int dsc_max_bpp, int dsc_max_bpp,
...@@ -1909,23 +1910,31 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp, ...@@ -1909,23 +1910,31 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
int pipe_bpp, int pipe_bpp,
int timeslots) int timeslots)
{ {
u16 compressed_bpp; u8 bppx16_incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u16 compressed_bppx16;
u8 bppx16_step;
int ret; int ret;
if (DISPLAY_VER(i915) < 14 || bppx16_incr <= 1)
bppx16_step = 16;
else
bppx16_step = 16 / bppx16_incr;
/* Compressed BPP should be less than the Input DSC bpp */ /* Compressed BPP should be less than the Input DSC bpp */
dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1); dsc_max_bpp = min(dsc_max_bpp << 4, (pipe_bpp << 4) - bppx16_step);
dsc_min_bpp = dsc_min_bpp << 4;
for (compressed_bpp = dsc_max_bpp; for (compressed_bppx16 = dsc_max_bpp;
compressed_bpp >= dsc_min_bpp; compressed_bppx16 >= dsc_min_bpp;
compressed_bpp--) { compressed_bppx16 -= bppx16_step) {
ret = dsc_compute_link_config(intel_dp, ret = dsc_compute_link_config(intel_dp,
pipe_config, pipe_config,
limits, limits,
compressed_bpp, compressed_bppx16,
timeslots); timeslots);
if (ret == 0) { if (ret == 0) {
pipe_config->dsc.compressed_bpp_x16 = pipe_config->dsc.compressed_bpp_x16 = compressed_bppx16;
to_bpp_x16(compressed_bpp);
return 0; return 0;
} }
} }
...@@ -1963,7 +1972,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp, ...@@ -1963,7 +1972,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16)); dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
if (DISPLAY_VER(i915) >= 13) if (DISPLAY_VER(i915) >= 13)
return xelpd_dsc_compute_link_config(intel_dp, pipe_config, limits, return xelpd_dsc_compute_link_config(intel_dp, connector, pipe_config, limits,
dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots); dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
return icl_dsc_compute_link_config(intel_dp, pipe_config, limits, return icl_dsc_compute_link_config(intel_dp, pipe_config, limits,
dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots); dsc_max_bpp, dsc_min_bpp, pipe_bpp, timeslots);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment