/* * With Single pipe configuration, HW is capable of supporting maximum of: * 2 slices per line for ICL, BMG * 4 slices per line for other platforms. * For now consider a max of 2 slices per line, which works for all platforms. * With this we can have max of 4 DSC Slices per pipe. * * For higher resolutions where 12 slice support is required with * ultrajoiner, only then each pipe can support 3 slices. * * #TODO Split this better to use 4 slices/dsc engine where supported.
*/ staticconst u8 valid_dsc_slicecount[] = {1, 2, 3, 4};
/** * intel_dp_is_edp - is the given port attached to an eDP panel (either CPU or PCH) * @intel_dp: DP struct * * If a CPU or PCH DP output is attached to an eDP panel, this function * will return true, and false otherwise. * * This function is not safe to use prior to encoder type being set.
*/ bool intel_dp_is_edp(struct intel_dp *intel_dp)
{ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
/* Is link rate UHBR and thus 128b/132b? */ bool intel_dp_is_uhbr(conststruct intel_crtc_state *crtc_state)
{ return drm_dp_is_uhbr_rate(crtc_state->port_clock);
}
/** * intel_dp_link_symbol_size - get the link symbol size for a given link rate * @rate: link rate in 10kbit/s units * * Returns the link symbol size in bits/symbol units depending on the link * rate -> channel coding.
*/ int intel_dp_link_symbol_size(int rate)
{ return drm_dp_is_uhbr_rate(rate) ? 32 : 10;
}
/** * intel_dp_link_symbol_clock - convert link rate to link symbol clock * @rate: link rate in 10kbit/s units * * Returns the link symbol clock frequency in kHz units depending on the * link rate and channel coding.
*/ int intel_dp_link_symbol_clock(int rate)
{ return DIV_ROUND_CLOSEST(rate * 10, intel_dp_link_symbol_size(rate));
}
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
max_rate = drm_dp_tunnel_max_dprx_rate(intel_dp->tunnel); else
max_rate = drm_dp_bw_code_to_link_rate(intel_dp->dpcd[DP_MAX_LINK_RATE]);
/* * Some broken eDP sinks illegally declare support for * HBR3 without TPS4, and are unable to produce a stable * output. Reject HBR3 when TPS4 is not available.
*/ if (max_rate >= 810000 && !drm_dp_tps4_supported(intel_dp->dpcd)) {
drm_dbg_kms(display->drm, "[ENCODER:%d:%s] Rejecting HBR3 due to missing TPS4 support\n",
encoder->base.base.id, encoder->base.name);
max_rate = 540000;
}
return max_rate;
}
staticint max_dprx_lane_count(struct intel_dp *intel_dp)
{ if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp)) return drm_dp_tunnel_max_dprx_lane_count(intel_dp->tunnel);
/* * Sink rates for 8b/10b.
*/
max_rate = max_dprx_rate(intel_dp);
max_lttpr_rate = drm_dp_lttpr_max_link_rate(intel_dp->lttpr_common_caps); if (max_lttpr_rate)
max_rate = min(max_rate, max_lttpr_rate);
for (i = 0; i < ARRAY_SIZE(dp_rates); i++) { if (dp_rates[i] > max_rate) break;
intel_dp->sink_rates[i] = dp_rates[i];
}
/* * Sink rates for 128b/132b. If set, sink should support all 8b/10b * rates and 10 Gbps.
*/ if (drm_dp_128b132b_supported(intel_dp->dpcd)) {
u8 uhbr_rates = 0;
drm_err(display->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD with no link rates, using defaults\n",
connector->base.base.id, connector->base.name,
encoder->base.base.id, encoder->base.name);
switch (intel_dp->max_sink_lane_count) { case 1: case 2: case 4: return;
}
drm_err(display->drm, "[CONNECTOR:%d:%s][ENCODER:%d:%s] Invalid DPCD max lane count (%d), using default\n",
connector->base.base.id, connector->base.name,
encoder->base.base.id, encoder->base.name,
intel_dp->max_sink_lane_count);
/* Get length of rates array potentially limited by max_rate. */ staticint intel_dp_rate_limit_len(constint *rates, int len, int max_rate)
{ int i;
/* Limit results by potentially reduced max rate */ for (i = 0; i < len; i++) { if (rates[len - i - 1] <= max_rate) return len - i;
}
return 0;
}
/* Get length of common rates array potentially limited by max_rate. */ staticint intel_dp_common_len_rate_limit(conststruct intel_dp *intel_dp, int max_rate)
{ return intel_dp_rate_limit_len(intel_dp->common_rates,
intel_dp->num_common_rates, max_rate);
}
int intel_dp_common_rate(struct intel_dp *intel_dp, int index)
{ struct intel_display *display = to_intel_display(intel_dp);
if (drm_WARN_ON(display->drm,
index < 0 || index >= intel_dp->num_common_rates)) return 162000;
return intel_dp->common_rates[index];
}
/* Theoretical max between source and sink */ int intel_dp_max_common_rate(struct intel_dp *intel_dp)
{ return intel_dp_common_rate(intel_dp, intel_dp->num_common_rates - 1);
}
int intel_dp_max_source_lane_count(struct intel_digital_port *dig_port)
{ int vbt_max_lanes = intel_bios_dp_max_lane_count(dig_port->base.devdata); int max_lanes = dig_port->max_lanes;
if (vbt_max_lanes)
max_lanes = min(max_lanes, vbt_max_lanes);
return max_lanes;
}
/* Theoretical max between source and sink */ int intel_dp_max_common_lane_count(struct intel_dp *intel_dp)
{ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); int source_max = intel_dp_max_source_lane_count(dig_port); int sink_max = intel_dp->max_sink_lane_count; int lane_max = intel_tc_port_max_lane_count(dig_port); int lttpr_max = drm_dp_lttpr_max_lane_count(intel_dp->lttpr_common_caps);
if (lttpr_max)
sink_max = min(sink_max, lttpr_max);
int intel_dp_max_lane_count(struct intel_dp *intel_dp)
{ int lane_count;
if (intel_dp->link.force_lane_count)
lane_count = forced_lane_count(intel_dp); else
lane_count = intel_dp->link.max_lane_count;
switch (lane_count) { case 1: case 2: case 4: return lane_count; default:
MISSING_CASE(lane_count); return 1;
}
}
staticint intel_dp_min_lane_count(struct intel_dp *intel_dp)
{ if (intel_dp->link.force_lane_count) return forced_lane_count(intel_dp);
return 1;
}
/* * The required data bandwidth for a mode with given pixel clock and bpp. This * is the required net bandwidth independent of the data bandwidth efficiency. * * TODO: check if callers of this functions should use * intel_dp_effective_data_rate() instead.
*/ int
intel_dp_link_required(int pixel_clock, int bpp)
{ /* pixel_clock is in kHz, divide bpp by 8 for bit to Byte conversion */ return DIV_ROUND_UP(pixel_clock * bpp, 8);
}
/** * intel_dp_effective_data_rate - Return the pixel data rate accounting for BW allocation overhead * @pixel_clock: pixel clock in kHz * @bpp_x16: bits per pixel .4 fixed point format * @bw_overhead: BW allocation overhead in 1ppm units * * Return the effective pixel data rate in kB/sec units taking into account * the provided SSC, FEC, DSC BW allocation overhead.
*/ int intel_dp_effective_data_rate(int pixel_clock, int bpp_x16, int bw_overhead)
{ return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_clock * bpp_x16, bw_overhead),
1000000 * 16 * 8);
}
/** * intel_dp_max_link_data_rate: Calculate the maximum rate for the given link params * @intel_dp: Intel DP object * @max_dprx_rate: Maximum data rate of the DPRX * @max_dprx_lanes: Maximum lane count of the DPRX * * Calculate the maximum data rate for the provided link parameters taking into * account any BW limitations by a DP tunnel attached to @intel_dp. * * Returns the maximum data rate in kBps units.
*/ int intel_dp_max_link_data_rate(struct intel_dp *intel_dp, int max_dprx_rate, int max_dprx_lanes)
{ int max_rate = drm_dp_max_dprx_data_rate(max_dprx_rate, max_dprx_lanes);
if (intel_dp_tunnel_bw_alloc_is_enabled(intel_dp))
max_rate = min(max_rate,
drm_dp_tunnel_available_bw(intel_dp->tunnel));
int intel_dp_link_config_index(struct intel_dp *intel_dp, int link_rate, int lane_count)
{ int link_rate_idx = intel_dp_rate_index(intel_dp->common_rates, intel_dp->num_common_rates,
link_rate); int lane_count_exp = ilog2(lane_count); int i;
for (i = 0; i < intel_dp->link.num_configs; i++) { conststruct intel_dp_link_config *lc = &intel_dp->link.configs[i];
/* Paranoia, there should always be something in common. */ if (drm_WARN_ON(display->drm, intel_dp->num_common_rates == 0)) {
intel_dp->common_rates[0] = 162000;
intel_dp->num_common_rates = 1;
}
intel_dp_link_config_init(intel_dp);
}
bool intel_dp_link_params_valid(struct intel_dp *intel_dp, int link_rate,
u8 lane_count)
{ /* * FIXME: we need to synchronize the current link parameters with * hardware readout. Currently fast link training doesn't work on * boot-up.
*/ if (link_rate == 0 ||
link_rate > intel_dp->link.max_rate) returnfalse;
if (lane_count == 0 ||
lane_count > intel_dp_max_lane_count(intel_dp)) returnfalse;
int intel_dp_bw_fec_overhead(bool fec_enabled)
{ /* * TODO: Calculate the actual overhead for a given mode. * The hard-coded 1/0.972261=2.853% overhead factor * corresponds (for instance) to the 8b/10b DP FEC 2.4% + * 0.453% DSC overhead. This is enough for a 3840 width mode, * which has a DSC overhead of up to ~0.2%, but may not be * enough for a 1024 width mode where this is ~0.8% (on a 4 * lane DP link, with 2 DSC slices and 8 bpp color depth).
*/ return fec_enabled ? DP_DSC_FEC_OVERHEAD_FACTOR : 1000000;
}
/* Error out if the max bpp is less than smallest allowed valid bpp */ if (bits_per_pixel < valid_dsc_bpp[0]) {
drm_dbg_kms(display->drm, "Unsupported BPP %u, min %u\n",
bits_per_pixel, valid_dsc_bpp[0]); return 0;
}
/* From XE_LPD onwards we support from bpc upto uncompressed bpp-1 BPPs */ if (DISPLAY_VER(display) >= 13) {
bits_per_pixel = min(bits_per_pixel, pipe_bpp - 1);
/* * According to BSpec, 27 is the max DSC output bpp, * 8 is the min DSC output bpp. * While we can still clamp higher bpp values to 27, saving bandwidth, * if it is required to oompress up to bpp < 8, means we can't do * that and probably means we can't fit the required mode, even with * DSC enabled.
*/ if (bits_per_pixel < 8) {
drm_dbg_kms(display->drm, "Unsupported BPP %u, min 8\n",
bits_per_pixel); return 0;
}
bits_per_pixel = min_t(u32, bits_per_pixel, 27);
} else { /* Find the nearest match in the array of known BPPs from VESA */ for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { if (bits_per_pixel < valid_dsc_bpp[i + 1]) break;
}
drm_dbg_kms(display->drm, "Set dsc bpp from %d to VESA %d\n",
bits_per_pixel, valid_dsc_bpp[i]);
static u32 bigjoiner_bw_max_bpp(struct intel_display *display, u32 mode_clock, int num_joined_pipes)
{
u32 max_bpp; /* With bigjoiner multiple dsc engines are used in parallel so PPC is 2 */ int ppc = 2; int num_big_joiners = num_joined_pipes / 2;
/* * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* * (LinkSymbolClock)* 8 * (TimeSlots / 64) * for SST -> TimeSlots is 64(i.e all TimeSlots that are available) * for MST -> TimeSlots has to be calculated, based on mode requirements * * Due to FEC overhead, the available bw is reduced to 97.2261%. * To support the given mode: * Bandwidth required should be <= Available link Bandwidth * FEC Overhead * =>ModeClock * bits_per_pixel <= Available Link Bandwidth * FEC Overhead * =>bits_per_pixel <= Available link Bandwidth * FEC Overhead / ModeClock * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock) * 8 (TimeSlots / 64) / * (ModeClock / FEC Overhead) * =>bits_per_pixel <= (NumberOfLanes * LinkSymbolClock * TimeSlots) / * (ModeClock / FEC Overhead * 8)
*/
bits_per_pixel = ((link_clock * lane_count) * timeslots) /
(intel_dp_mode_to_fec_clock(mode_clock) * 8);
/* Bandwidth required for 420 is half, that of 444 format */ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bits_per_pixel *= 2;
/* * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum * supported PPS value can be 63.9375 and with the further * mention that for 420, 422 formats, bpp should be programmed double * the target bpp restricting our target bpp to be 31.9375 at max.
*/ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bits_per_pixel = min_t(u32, bits_per_pixel, 31);
drm_dbg_kms(display->drm, "Max link bpp is %u for %u timeslots " "total bw %u pixel clock %u\n",
bits_per_pixel, timeslots,
(link_clock * lane_count * 8),
intel_dp_mode_to_fec_clock(mode_clock));
/* * Due to some DSC engine BW limitations, we need to enable second * slice and VDSC engine, whenever we approach close enough to max CDCLK
*/ if (mode_clock >= ((display->cdclk.max_cdclk_freq * 85) / 100))
min_slice_count = max_t(u8, min_slice_count, 2);
max_slice_width = drm_dp_dsc_sink_max_slice_width(connector->dp.dsc_dpcd); if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
drm_dbg_kms(display->drm, "Unsupported slice width %d by DP DSC Sink device\n",
max_slice_width); return 0;
} /* Also take into account max slice width */
min_slice_count = max_t(u8, min_slice_count,
DIV_ROUND_UP(mode_hdisplay,
max_slice_width));
/* Find the closest match to the valid slice count values */ for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
u8 test_slice_count = valid_dsc_slicecount[i] * num_joined_pipes;
/* * 3 DSC Slices per pipe need 3 DSC engines, which is supported only * with Ultrajoiner only for some platforms.
*/ if (valid_dsc_slicecount[i] == 3 &&
(!HAS_DSC_3ENGINES(display) || num_joined_pipes != 4)) continue;
if (test_slice_count >
drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, false)) break;
/* * 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 && valid_dsc_slicecount[i] < 2) continue;
if (mode_hdisplay % test_slice_count) continue;
if (min_slice_count <= test_slice_count) return test_slice_count;
}
switch (format) { case INTEL_OUTPUT_FORMAT_RGB: returntrue;
case INTEL_OUTPUT_FORMAT_YCBCR444: /* * No YCbCr output support on gmch platforms. * Also, ILK doesn't seem capable of DP YCbCr output. * The displayed image is severely corrupted. SNB+ is fine.
*/ return !HAS_GMCH(display) && !display->platform.ironlake;
case INTEL_OUTPUT_FORMAT_YCBCR420: /* Platform < Gen 11 cannot output YCbCr420 format */ return DISPLAY_VER(display) >= 11;
int intel_dp_min_bpp(enum intel_output_format output_format)
{ if (output_format == INTEL_OUTPUT_FORMAT_RGB) return intel_display_min_pipe_bpp(); else return 8 * 3;
}
int intel_dp_output_bpp(enum intel_output_format output_format, int bpp)
{ /* * bpp value was assumed to RGB format. And YCbCr 4:2:0 output * format of the number of bytes per pixel will be half the number * of bytes of RGB pixel.
*/ if (output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
bpp /= 2;
staticbool intel_dp_hdisplay_bad(struct intel_display *display, int hdisplay)
{ /* * Older platforms don't like hdisplay==4096 with DP. * * On ILK/SNB/IVB the pipe seems to be somewhat running (scanline * and frame counter increment), but we don't get vblank interrupts, * and the pipe underruns immediately. The link also doesn't seem * to get trained properly. * * On CHV the vblank interrupts don't seem to disappear but * otherwise the symptoms are similar. * * TODO: confirm the behaviour on HSW+
*/ return hdisplay == 4096 && !HAS_DDI(display);
}
/* Only consider the sink's max TMDS clock if we know this is a HDMI DFP */ if (max_tmds_clock && info->max_tmds_clock)
max_tmds_clock = min(max_tmds_clock, info->max_tmds_clock);
return max_tmds_clock;
}
staticenum drm_mode_status
intel_dp_tmds_clock_valid(struct intel_dp *intel_dp, int clock, int bpc, enum intel_output_format sink_format, bool respect_downstream_limits)
{ int tmds_clock, min_tmds_clock, max_tmds_clock;
/* If PCON supports FRL MODE, check FRL bandwidth constraints */ if (intel_dp->dfp.pcon_max_frl_bw) { int target_bw; int max_frl_bw; int bpp = intel_dp_mode_min_output_bpp(connector, mode);
target_bw = bpp * target_clock;
max_frl_bw = intel_dp->dfp.pcon_max_frl_bw;
/* converting bw from Gbps to Kbps*/
max_frl_bw = max_frl_bw * 1000000;
if (target_bw > max_frl_bw) return MODE_CLOCK_HIGH;
return MODE_OK;
}
if (intel_dp->dfp.max_dotclock &&
target_clock > intel_dp->dfp.max_dotclock) return MODE_CLOCK_HIGH;
if (intel_dp_has_dsc(connector)) { enum intel_output_format sink_format, output_format; int pipe_bpp;
sink_format = intel_dp_sink_format(connector, mode);
output_format = intel_dp_output_format(connector, sink_format); /* * TBD pass the connector BPC, * for now U8_MAX so that max BPC on that platform would be picked
*/
pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX);
/* * Output bpp is stored in 6.4 format so right shift by 4 to get the * integer value since we support only integer values of bpp.
*/ if (intel_dp_is_edp(intel_dp)) {
dsc_max_compressed_bpp =
drm_edp_dsc_sink_output_bpp(connector->dp.dsc_dpcd) >> 4;
dsc_slice_count =
drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, true);
} elseif (drm_dp_sink_supports_fec(connector->dp.fec_capability)) {
dsc_max_compressed_bpp =
intel_dp_dsc_get_max_compressed_bpp(display,
max_link_clock,
max_lanes,
target_clock,
mode->hdisplay,
num_joined_pipes,
output_format,
pipe_bpp, 64);
dsc_slice_count =
intel_dp_dsc_get_slice_count(connector,
target_clock,
mode->hdisplay,
num_joined_pipes);
}
staticint forced_link_rate(struct intel_dp *intel_dp)
{ int len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.force_rate);
if (len == 0) return intel_dp_common_rate(intel_dp, 0);
return intel_dp_common_rate(intel_dp, len - 1);
}
int
intel_dp_max_link_rate(struct intel_dp *intel_dp)
{ int len;
if (intel_dp->link.force_rate) return forced_link_rate(intel_dp);
len = intel_dp_common_len_rate_limit(intel_dp, intel_dp->link.max_rate);
return intel_dp_common_rate(intel_dp, len - 1);
}
staticint
intel_dp_min_link_rate(struct intel_dp *intel_dp)
{ if (intel_dp->link.force_rate) return forced_link_rate(intel_dp);
return intel_dp_common_rate(intel_dp, 0);
}
int intel_dp_rate_select(struct intel_dp *intel_dp, int rate)
{ struct intel_display *display = to_intel_display(intel_dp); int i = intel_dp_rate_index(intel_dp->sink_rates,
intel_dp->num_sink_rates, rate);
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) &&
!intel_dp_supports_fec(intel_dp, connector, crtc_state)) returnfalse;
return intel_dsc_source_support(crtc_state);
}
staticint intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp, conststruct intel_crtc_state *crtc_state, int bpc, bool respect_downstream_limits)
{ int clock = crtc_state->hw.adjusted_mode.crtc_clock;
/* * Current bpc could already be below 8bpc due to * FDI bandwidth constraints or other limits. * HDMI minimum is 8bpc however.
*/
bpc = max(bpc, 8);
/* * We will never exceed downstream TMDS clock limits while * attempting deep color. If the user insists on forcing an * out of spec mode they will have to be satisfied with 8bpc.
*/ if (!respect_downstream_limits)
bpc = 8;
bpp = bpc * 3; if (intel_dp_is_edp(intel_dp)) { /* Get bpp from vbt only for panels that dont have bpp in edid */ if (connector->base.display_info.bpc == 0 &&
connector->panel.vbt.edp.bpp &&
connector->panel.vbt.edp.bpp < bpp) {
drm_dbg_kms(display->drm, "clamping bpp for eDP panel to BIOS-provided %i\n",
connector->panel.vbt.edp.bpp);
bpp = connector->panel.vbt.edp.bpp;
}
}
/* FIXME a bit of a mess wrt clock vs. crtc_clock */ if (has_seamless_m_n(connector)) return intel_panel_highest_mode(connector, adjusted_mode)->clock; else return adjusted_mode->crtc_clock;
}
/* Optimize link config in order: max bpp, min clock, min lanes */ staticint
intel_dp_compute_link_config_wide(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, conststruct drm_connector_state *conn_state, conststruct link_config_limits *limits)
{ int bpp, i, lane_count, clock = intel_dp_mode_clock(pipe_config, conn_state); int mode_rate, link_rate, link_avail;
for (bpp = fxp_q4_to_int(limits->link.max_bpp_x16);
bpp >= fxp_q4_to_int(limits->link.min_bpp_x16);
bpp -= 2 * 3) { int link_bpp = intel_dp_output_bpp(pipe_config->output_format, bpp);
int intel_dp_dsc_max_src_input_bpc(struct intel_display *display)
{ /* Max DSC Input BPC for ICL is 10 and for TGL+ is 12 */ if (DISPLAY_VER(display) >= 12) return 12; if (DISPLAY_VER(display) == 11) return 10;
return intel_dp_dsc_min_src_input_bpc();
}
int intel_dp_dsc_compute_max_bpp(conststruct intel_connector *connector,
u8 max_req_bpc)
{ struct intel_display *display = to_intel_display(connector); int i, num_bpc;
u8 dsc_bpc[3] = {}; int dsc_max_bpc;
staticint intel_dp_get_slice_height(int vactive)
{ int slice_height;
/* * VDSC 1.2a spec in Section 3.8 Options for Slices implies that 108 * lines is an optimal slice height, but any size can be used as long as * vertical active integer multiple and maximum vertical slice count * requirements are met.
*/ for (slice_height = 108; slice_height <= vactive; slice_height += 2) if (vactive % slice_height == 0) return slice_height;
/* * Highly unlikely we reach here as most of the resolutions will end up * finding appropriate slice_height in above loop but returning * slice_height as 2 here as it should work with all resolutions.
*/ return 2;
}
/* * RC_MODEL_SIZE is currently a constant across all configurations. * * FIXME: Look into using sink defined DPCD DP_DSC_RC_BUF_BLK_SIZE and * DP_DSC_RC_BUF_SIZE for this.
*/
vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
vdsc_cfg->pic_height = crtc_state->hw.adjusted_mode.crtc_vdisplay;
/* * FIXME: intel_dp_mtp_tu_compute_config() requires * ->lane_count and ->port_clock set before we know * they'll work. If we end up failing altogether, * they'll remain in crtc state. This shouldn't matter, * as we'd then bail out from compute config, but it's * just ugly.
*/
pipe_config->lane_count = lane_count;
pipe_config->port_clock = link_rate;
if (drm_dp_is_uhbr_rate(link_rate)) { int ret;
ret = intel_dp_mtp_tu_compute_config(intel_dp,
pipe_config,
conn_state,
dsc_bpp_x16,
dsc_bpp_x16,
0, true); if (ret) continue;
} else { if (!is_bw_sufficient_for_dsc_config(dsc_bpp_x16, link_rate,
lane_count, adjusted_mode->clock,
pipe_config->output_format,
timeslots)) continue;
}
if (max_bppx16) return max_bppx16; /* * If support not given in DPCD 67h, 68h use the Maximum Allowed bit rate * values as given in spec Table 2-157 DP v2.0
*/ switch (pipe_config->output_format) { case INTEL_OUTPUT_FORMAT_RGB: case INTEL_OUTPUT_FORMAT_YCBCR444: return (3 * bpc) << 4; case INTEL_OUTPUT_FORMAT_YCBCR420: return (3 * (bpc / 2)) << 4; default:
MISSING_CASE(pipe_config->output_format); break;
}
return 0;
}
int intel_dp_dsc_sink_min_compressed_bpp(conststruct intel_crtc_state *pipe_config)
{ /* From Mandatory bit rate range Support Table 2-157 (DP v2.0) */ switch (pipe_config->output_format) { case INTEL_OUTPUT_FORMAT_RGB: case INTEL_OUTPUT_FORMAT_YCBCR444: return 8; case INTEL_OUTPUT_FORMAT_YCBCR420: return 6; default:
MISSING_CASE(pipe_config->output_format); break;
}
return 0;
}
int intel_dp_dsc_sink_max_compressed_bpp(conststruct intel_connector *connector, conststruct intel_crtc_state *pipe_config, int bpc)
{ return intel_dp_dsc_max_sink_compressed_bppx16(connector,
pipe_config, bpc) >> 4;
}
int intel_dp_dsc_min_src_compressed_bpp(void)
{ /* Min Compressed bpp supported by source is 8 */ return 8;
}
/* * Forcing DSC and using the platform's max compressed bpp is seen to cause * underruns. Since DSC isn't needed in these cases, limit the * max compressed bpp to 18, which is a safe value across platforms with different * pipe bpps.
*/ if (intel_dp->force_dsc_en) return 18;
/* * Max Compressed bpp for Gen 13+ is 27bpp. * For earlier platform is 23bpp. (Bspec:49259).
*/ if (DISPLAY_VER(display) < 13) return 23; else return 27;
}
/* * Note: for pre-13 display you still need to check the validity of each step.
*/ int intel_dp_dsc_bpp_step_x16(conststruct intel_connector *connector)
{ struct intel_display *display = to_intel_display(connector);
u8 incr = drm_dp_dsc_sink_bpp_incr(connector->dp.dsc_dpcd);
if (DISPLAY_VER(display) < 14 || !incr) return fxp_q4_from_int(1);
if (connector->mst.dp &&
!connector->link.force_bpp_x16 && !connector->mst.dp->force_dsc_fractional_bpp_en) return fxp_q4_from_int(1);
/* fxp q4 */ return fxp_q4_from_int(1) / incr;
}
/* * Note: for bpp_x16 to be valid it must be also within the source/sink's * min..max bpp capability range.
*/ bool intel_dp_dsc_valid_compressed_bpp(struct intel_dp *intel_dp, int bpp_x16)
{ struct intel_display *display = to_intel_display(intel_dp); int i;
if (DISPLAY_VER(display) >= 13) { if (intel_dp->force_dsc_fractional_bpp_en && !fxp_q4_to_frac(bpp_x16)) returnfalse;
returntrue;
}
if (fxp_q4_to_frac(bpp_x16)) returnfalse;
for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) { if (fxp_q4_to_int(bpp_x16) == valid_dsc_bpp[i]) returntrue;
}
returnfalse;
}
/* * Find the max compressed BPP we can find a link configuration for. The BPPs to * try depend on the source (platform) and sink.
*/ staticint dsc_compute_compressed_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, conststruct link_config_limits *limits, int pipe_bpp, int timeslots)
{ struct intel_display *display = to_intel_display(intel_dp); conststruct intel_connector *connector = to_intel_connector(conn_state->connector); conststruct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; int output_bpp; int min_bpp_x16, max_bpp_x16, bpp_step_x16; int dsc_joiner_max_bpp; int num_joined_pipes = intel_crtc_num_joined_pipes(pipe_config); int bpp_x16; int ret;
/* Compressed BPP should be less than the Input DSC bpp */
output_bpp = intel_dp_output_bpp(pipe_config->output_format, pipe_bpp);
max_bpp_x16 = min(max_bpp_x16, fxp_q4_from_int(output_bpp) - bpp_step_x16);
if (forced_bpp) {
ret = dsc_compute_compressed_bpp(intel_dp, pipe_config, conn_state,
limits, forced_bpp, timeslots); if (ret == 0) {
pipe_config->pipe_bpp = forced_bpp; return 0;
}
}
/* * Get the maximum DSC bpc that will be supported by any valid * link configuration and compressed bpp.
*/
num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc); for (i = 0; i < num_bpc; i++) {
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.24 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.