Skip to content

Commit 78015e2

Browse files
committed
drm/i915/dp: Update the link bpp limits for DSC mode
In non-DSC mode the link bpp can be set in 2*3 bpp steps in the pipe bpp range, while in DSC mode it can be set in 1/16 bpp steps to any value up to the maximum pipe bpp. Update the limits accordingly in both modes to prepare for a follow-up patch which may need to reduce the max link bpp value and starts to check the link bpp limits in DSC mode as well. While at it add more detail to the link limit debug print and print it also for DSC mode. v2: - Add to_bpp_frac_dec() instead of open coding it. (Jani) v3: (Ville) - Add BPP_X16_FMT / BPP_X16_ARG. - Add TODO: comment about initializing the DSC link bpp limits earlier. Cc: Jani Nikula <jani.nikula@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230921195159.2646027-5-imre.deak@intel.com
1 parent 7d0f2f6 commit 78015e2

4 files changed

Lines changed: 108 additions & 22 deletions

File tree

drivers/gpu/drm/i915/display/intel_display_types.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,6 +2120,14 @@ static inline int to_bpp_int(int bpp_x16)
21202120
return bpp_x16 >> 4;
21212121
}
21222122

2123+
static inline int to_bpp_frac(int bpp_x16)
2124+
{
2125+
return bpp_x16 & 0xf;
2126+
}
2127+
2128+
#define BPP_X16_FMT "%d.%04d"
2129+
#define BPP_X16_ARGS(bpp_x16) to_bpp_int(bpp_x16), (to_bpp_frac(bpp_x16) * 625)
2130+
21232131
static inline int to_bpp_x16(int bpp)
21242132
{
21252133
return bpp << 4;

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,16 +2190,72 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
21902190
return 0;
21912191
}
21922192

2193-
static void
2193+
/**
2194+
* intel_dp_compute_config_link_bpp_limits - compute output link bpp limits
2195+
* @intel_dp: intel DP
2196+
* @crtc_state: crtc state
2197+
* @dsc: DSC compression mode
2198+
* @limits: link configuration limits
2199+
*
2200+
* Calculates the output link min, max bpp values in @limits based on the
2201+
* pipe bpp range, @crtc_state and @dsc mode.
2202+
*
2203+
* Returns %true in case of success.
2204+
*/
2205+
bool
2206+
intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
2207+
const struct intel_crtc_state *crtc_state,
2208+
bool dsc,
2209+
struct link_config_limits *limits)
2210+
{
2211+
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2212+
const struct drm_display_mode *adjusted_mode =
2213+
&crtc_state->hw.adjusted_mode;
2214+
const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2215+
const struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
2216+
int max_link_bpp_x16;
2217+
2218+
max_link_bpp_x16 = to_bpp_x16(limits->pipe.max_bpp);
2219+
2220+
if (!dsc) {
2221+
max_link_bpp_x16 = rounddown(max_link_bpp_x16, to_bpp_x16(2 * 3));
2222+
2223+
if (max_link_bpp_x16 < to_bpp_x16(limits->pipe.min_bpp))
2224+
return false;
2225+
2226+
limits->link.min_bpp_x16 = to_bpp_x16(limits->pipe.min_bpp);
2227+
} else {
2228+
/*
2229+
* TODO: set the DSC link limits already here, atm these are
2230+
* initialized only later in intel_edp_dsc_compute_pipe_bpp() /
2231+
* intel_dp_dsc_compute_pipe_bpp()
2232+
*/
2233+
limits->link.min_bpp_x16 = 0;
2234+
}
2235+
2236+
limits->link.max_bpp_x16 = max_link_bpp_x16;
2237+
2238+
drm_dbg_kms(&i915->drm,
2239+
"[ENCODER:%d:%s][CRTC:%d:%s] DP link limits: pixel clock %d kHz DSC %s max lanes %d max rate %d max pipe_bpp %d max link_bpp " BPP_X16_FMT "\n",
2240+
encoder->base.base.id, encoder->base.name,
2241+
crtc->base.base.id, crtc->base.name,
2242+
adjusted_mode->crtc_clock,
2243+
dsc ? "on" : "off",
2244+
limits->max_lane_count,
2245+
limits->max_rate,
2246+
limits->pipe.max_bpp,
2247+
BPP_X16_ARGS(limits->link.max_bpp_x16));
2248+
2249+
return true;
2250+
}
2251+
2252+
static bool
21942253
intel_dp_compute_config_limits(struct intel_dp *intel_dp,
21952254
struct intel_crtc_state *crtc_state,
21962255
bool respect_downstream_limits,
2256+
bool dsc,
21972257
struct link_config_limits *limits)
21982258
{
2199-
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
2200-
const struct drm_display_mode *adjusted_mode =
2201-
&crtc_state->hw.adjusted_mode;
2202-
22032259
limits->min_rate = intel_dp_common_rate(intel_dp, 0);
22042260
limits->max_rate = intel_dp_max_link_rate(intel_dp);
22052261

@@ -2225,13 +2281,10 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp,
22252281

22262282
intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
22272283

2228-
limits->link.min_bpp_x16 = to_bpp_x16(limits->pipe.min_bpp);
2229-
limits->link.max_bpp_x16 = to_bpp_x16(limits->pipe.max_bpp);
2230-
2231-
drm_dbg_kms(&i915->drm, "DP link computation with max lane count %i "
2232-
"max rate %d max bpp %d pixel clock %iKHz\n",
2233-
limits->max_lane_count, limits->max_rate,
2234-
to_bpp_int(limits->link.max_bpp_x16), adjusted_mode->crtc_clock);
2284+
return intel_dp_compute_config_link_bpp_limits(intel_dp,
2285+
crtc_state,
2286+
dsc,
2287+
limits);
22352288
}
22362289

22372290
static int
@@ -2250,9 +2303,6 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
22502303
bool dsc_needed;
22512304
int ret = 0;
22522305

2253-
intel_dp_compute_config_limits(intel_dp, pipe_config,
2254-
respect_downstream_limits, &limits);
2255-
22562306
if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,
22572307
adjusted_mode->crtc_clock))
22582308
pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);
@@ -2264,7 +2314,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
22642314
*/
22652315
joiner_needs_dsc = DISPLAY_VER(i915) < 13 && pipe_config->bigjoiner_pipes;
22662316

2267-
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en;
2317+
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
2318+
!intel_dp_compute_config_limits(intel_dp, pipe_config,
2319+
respect_downstream_limits,
2320+
false,
2321+
&limits);
22682322

22692323
if (!dsc_needed) {
22702324
/*
@@ -2281,6 +2335,13 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
22812335
drm_dbg_kms(&i915->drm, "Try DSC (fallback=%s, joiner=%s, force=%s)\n",
22822336
str_yes_no(ret), str_yes_no(joiner_needs_dsc),
22832337
str_yes_no(intel_dp->force_dsc_en));
2338+
2339+
if (!intel_dp_compute_config_limits(intel_dp, pipe_config,
2340+
respect_downstream_limits,
2341+
true,
2342+
&limits))
2343+
return -EINVAL;
2344+
22842345
ret = intel_dp_dsc_compute_config(intel_dp, pipe_config,
22852346
conn_state, &limits, 64, true);
22862347
if (ret < 0)

drivers/gpu/drm/i915/display/intel_dp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,10 @@ void intel_dp_phy_test(struct intel_encoder *encoder);
156156
void intel_dp_wait_source_oui(struct intel_dp *intel_dp);
157157
int intel_dp_output_bpp(enum intel_output_format output_format, int bpp);
158158

159+
bool
160+
intel_dp_compute_config_link_bpp_limits(struct intel_dp *intel_dp,
161+
const struct intel_crtc_state *crtc_state,
162+
bool dsc,
163+
struct link_config_limits *limits);
164+
159165
#endif /* __INTEL_DP_H__ */

drivers/gpu/drm/i915/display/intel_dp_mst.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,10 @@ static int intel_dp_mst_update_slots(struct intel_encoder *encoder,
295295
return 0;
296296
}
297297

298-
static void
298+
static bool
299299
intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
300300
struct intel_crtc_state *crtc_state,
301+
bool dsc,
301302
struct link_config_limits *limits)
302303
{
303304
/*
@@ -323,8 +324,10 @@ intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
323324

324325
intel_dp_adjust_compliance_config(intel_dp, crtc_state, limits);
325326

326-
limits->link.min_bpp_x16 = to_bpp_x16(limits->pipe.min_bpp);
327-
limits->link.max_bpp_x16 = to_bpp_x16(limits->pipe.max_bpp);
327+
return intel_dp_compute_config_link_bpp_limits(intel_dp,
328+
crtc_state,
329+
dsc,
330+
limits);
328331
}
329332

330333
static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
@@ -347,9 +350,11 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
347350
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
348351
pipe_config->has_pch_encoder = false;
349352

350-
intel_dp_mst_compute_config_limits(intel_dp, pipe_config, &limits);
351-
352-
dsc_needed = intel_dp->force_dsc_en;
353+
dsc_needed = intel_dp->force_dsc_en ||
354+
!intel_dp_mst_compute_config_limits(intel_dp,
355+
pipe_config,
356+
false,
357+
&limits);
353358

354359
if (!dsc_needed) {
355360
ret = intel_dp_mst_compute_link_config(encoder, pipe_config,
@@ -368,6 +373,12 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
368373
str_yes_no(ret),
369374
str_yes_no(intel_dp->force_dsc_en));
370375

376+
if (!intel_dp_mst_compute_config_limits(intel_dp,
377+
pipe_config,
378+
true,
379+
&limits))
380+
return -EINVAL;
381+
371382
/*
372383
* FIXME: As bpc is hardcoded to 8, as mentioned above,
373384
* WARN and ignore the debug flag force_dsc_bpc for now.

0 commit comments

Comments
 (0)