| @@ -78,8 +78,8 @@ · 77 unmodified lines |
| 78 | 78 | #define DP_DSC_MAX_ENC_THROUGHPUT_0 340000 |
| 79 | 79 | #define DP_DSC_MAX_ENC_THROUGHPUT_1 400000 |
| 80 | 80 | |
| 81 | | −/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */ |
| 82 | | −#define DP_DSC_FEC_OVERHEAD_FACTOR 976 |
| 81 | +/* DP DSC FEC Overhead factor = 1/(0.972261) */ |
| 82 | +#define DP_DSC_FEC_OVERHEAD_FACTOR 972261 |
| 83 | 83 | |
| 84 | 84 | /* Compliance test status bits */ |
| 85 | 85 | #define INTEL_DP_RESOLUTION_SHIFT_MASK 0 |
| @@ -494,6 +494,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp, · 408 unmodified lines |
| 494 | 494 | return 0; |
| 495 | 495 | } |
| 496 | 496 | |
| 497 | +u32 intel_dp_mode_to_fec_clock(u32 mode_clock) |
| 498 | +{ |
| 499 | + return div_u64(mul_u32_u32(mode_clock, 1000000U), |
| 500 | + DP_DSC_FEC_OVERHEAD_FACTOR); |
| 501 | +} |
| 502 | + |
| 503 | +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count, |
| 504 | + u32 mode_clock, u32 mode_hdisplay) |
| 505 | +{ |
| 506 | + u32 bits_per_pixel, max_bpp_small_joiner_ram; |
| 507 | + int i; |
| 508 | + |
| 509 | + /* |
| 510 | + * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* |
| 511 | + * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP) |
| 512 | + * for SST -> TimeSlotsPerMTP is 1, |
| 513 | + * for MST -> TimeSlotsPerMTP has to be calculated |
| 514 | + */ |
| 515 | + bits_per_pixel = (link_clock * lane_count * 8) / |
| 516 | + intel_dp_mode_to_fec_clock(mode_clock); |
| 517 | + DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel); |
| 518 | + |
| 519 | + /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ |
| 520 | + max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay; |
| 521 | + DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram); |
| 522 | + |
| 523 | + /* |
| 524 | + * Greatest allowed DSC BPP = MIN (output BPP from available Link BW |
| 525 | + * check, output bpp from small joiner RAM check) |
| 526 | + */ |
| 527 | + bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram); |
| 528 | + |
| 529 | + /* Error out if the max bpp is less than smallest allowed valid bpp */ |
| 530 | + if (bits_per_pixel < valid_dsc_bpp[0]) { |
| 531 | + DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n", |
| 532 | + bits_per_pixel, valid_dsc_bpp[0]); |
| 533 | + return 0; |
| 534 | + } |
| 535 | + |
| 536 | + /* Find the nearest match in the array of known BPPs from VESA */ |
| 537 | + for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { |
| 538 | + if (bits_per_pixel < valid_dsc_bpp[i + 1]) |
| 539 | + break; |
| 540 | + } |
| 541 | + bits_per_pixel = valid_dsc_bpp[i]; |
| 542 | + |
| 543 | + /* |
| 544 | + * Compressed BPP in U6.4 format so multiply by 16, for Gen 11, |
| 545 | + * fractional part is 0 |
| 546 | + */ |
| 547 | + return bits_per_pixel << 4; |
| 548 | +} |
| 549 | + |
| 550 | +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, |
| 551 | + int mode_clock, int mode_hdisplay) |
| 552 | +{ |
| 553 | + u8 min_slice_count, i; |
| 554 | + int max_slice_width; |
| 555 | + |
| 556 | + if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE) |
| 557 | + min_slice_count = DIV_ROUND_UP(mode_clock, |
| 558 | + DP_DSC_MAX_ENC_THROUGHPUT_0); |
| 559 | + else |
| 560 | + min_slice_count = DIV_ROUND_UP(mode_clock, |
| 561 | + DP_DSC_MAX_ENC_THROUGHPUT_1); |
| 562 | + |
| 563 | + max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd); |
| 564 | + if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) { |
| 565 | + DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n", |
| 566 | + max_slice_width); |
| 567 | + return 0; |
| 568 | + } |
| 569 | + /* Also take into account max slice width */ |
| 570 | + min_slice_count = min_t(u8, min_slice_count, |
| 571 | + DIV_ROUND_UP(mode_hdisplay, |
| 572 | + max_slice_width)); |
| 573 | + |
| 574 | + /* Find the closest match to the valid slice count values */ |
| 575 | + for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) { |
| 576 | + if (valid_dsc_slicecount[i] > |
| 577 | + drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, |
| 578 | + false)) |
| 579 | + break; |
| 580 | + if (min_slice_count <= valid_dsc_slicecount[i]) |
| 581 | + return valid_dsc_slicecount[i]; |
| 582 | + } |
| 583 | + |
| 584 | + DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count); |
| 585 | + return 0; |
| 586 | +} |
| 587 | + |
| 497 | 588 | static enum drm_mode_status |
| 498 | 589 | intel_dp_mode_valid(struct drm_connector *connector, |
| 499 | 590 | struct drm_display_mode *mode) |
| @@ -2226,7 +2317,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, · 1726 unmodified lines |
| 2226 | 2317 | adjusted_mode->crtc_clock, |
| 2227 | 2318 | pipe_config->port_clock, |
| 2228 | 2319 | &pipe_config->dp_m_n, |
| 2229 | | − constant_n); |
| 2320 | + constant_n, pipe_config->fec_enable); |
| 2230 | 2321 | |
| 2231 | 2322 | if (intel_connector->panel.downclock_mode != NULL && |
| 2232 | 2323 | dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { |
| @@ -2236,7 +2327,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, · 3 unmodified lines |
| 2236 | 2327 | intel_connector->panel.downclock_mode->clock, |
| 2237 | 2328 | pipe_config->port_clock, |
| 2238 | 2329 | &pipe_config->dp_m2_n2, |
| 2239 | | − constant_n); |
| 2330 | + constant_n, pipe_config->fec_enable); |
| 2240 | 2331 | } |
| 2241 | 2332 | |
| 2242 | 2333 | if (!HAS_DDI(dev_priv)) |
| @@ -4323,91 +4414,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) · 2080 unmodified lines |
| 4323 | 4414 | DP_DPRX_ESI_LEN; |
| 4324 | 4415 | } |
| 4325 | 4416 | |
| 4326 | | −u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count, |
| 4327 | | − int mode_clock, int mode_hdisplay) |
| 4328 | | −{ |
| 4329 | | − u16 bits_per_pixel, max_bpp_small_joiner_ram; |
| 4330 | | − int i; |
| 4331 | | − |
| 4332 | | − /* |
| 4333 | | − * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)* |
| 4334 | | − * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP) |
| 4335 | | − * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1, |
| 4336 | | − * for MST -> TimeSlotsPerMTP has to be calculated |
| 4337 | | − */ |
| 4338 | | − bits_per_pixel = (link_clock * lane_count * 8 * |
| 4339 | | − DP_DSC_FEC_OVERHEAD_FACTOR) / |
| 4340 | | − mode_clock; |
| 4341 | | − |
| 4342 | | − /* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */ |
| 4343 | | − max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / |
| 4344 | | − mode_hdisplay; |
| 4345 | | − |
| 4346 | | − /* |
| 4347 | | − * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW |
| 4348 | | − * check, output bpp from small joiner RAM check) |
| 4349 | | − */ |
| 4350 | | − bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram); |
| 4351 | | − |
| 4352 | | − /* Error out if the max bpp is less than smallest allowed valid bpp */ |
| 4353 | | − if (bits_per_pixel < valid_dsc_bpp[0]) { |
| 4354 | | − DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel); |
| 4355 | | − return 0; |
| 4356 | | − } |
| 4357 | | − |
| 4358 | | − /* Find the nearest match in the array of known BPPs from VESA */ |
| 4359 | | − for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) { |
| 4360 | | − if (bits_per_pixel < valid_dsc_bpp[i + 1]) |
| 4361 | | − break; |
| 4362 | | − } |
| 4363 | | − bits_per_pixel = valid_dsc_bpp[i]; |
| 4364 | | − |
| 4365 | | − /* |
| 4366 | | − * Compressed BPP in U6.4 format so multiply by 16, for Gen 11, |
| 4367 | | − * fractional part is 0 |
| 4368 | | − */ |
| 4369 | | − return bits_per_pixel << 4; |
| 4370 | | −} |
| 4371 | | − |
| 4372 | | −u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, |
| 4373 | | − int mode_clock, |
| 4374 | | − int mode_hdisplay) |
| 4375 | | −{ |
| 4376 | | − u8 min_slice_count, i; |
| 4377 | | − int max_slice_width; |
| 4378 | | − |
| 4379 | | − if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE) |
| 4380 | | − min_slice_count = DIV_ROUND_UP(mode_clock, |
| 4381 | | − DP_DSC_MAX_ENC_THROUGHPUT_0); |
| 4382 | | − else |
| 4383 | | − min_slice_count = DIV_ROUND_UP(mode_clock, |
| 4384 | | − DP_DSC_MAX_ENC_THROUGHPUT_1); |
| 4385 | | − |
| 4386 | | − max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd); |
| 4387 | | − if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) { |
| 4388 | | − DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n", |
| 4389 | | − max_slice_width); |
| 4390 | | − return 0; |
| 4391 | | − } |
| 4392 | | − /* Also take into account max slice width */ |
| 4393 | | − min_slice_count = min_t(u8, min_slice_count, |
| 4394 | | − DIV_ROUND_UP(mode_hdisplay, |
| 4395 | | − max_slice_width)); |
| 4396 | | − |
| 4397 | | − /* Find the closest match to the valid slice count values */ |
| 4398 | | − for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) { |
| 4399 | | − if (valid_dsc_slicecount[i] > |
| 4400 | | − drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, |
| 4401 | | − false)) |
| 4402 | | − break; |
| 4403 | | − if (min_slice_count <= valid_dsc_slicecount[i]) |
| 4404 | | − return valid_dsc_slicecount[i]; |
| 4405 | | − } |
| 4406 | | − |
| 4407 | | − DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count); |
| 4408 | | − return 0; |
| 4409 | | −} |
| 4410 | | − |
| 4411 | 4417 | static void |
| 4412 | 4418 | intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp, |
| 4413 | 4419 | const struct intel_crtc_state *crtc_state) |