.. | .. |
---|
23 | 23 | * |
---|
24 | 24 | */ |
---|
25 | 25 | |
---|
| 26 | +#include <linux/delay.h> |
---|
| 27 | +#include <linux/slab.h> |
---|
| 28 | + |
---|
26 | 29 | #include "reg_helper.h" |
---|
27 | 30 | |
---|
28 | 31 | #include "core_types.h" |
---|
.. | .. |
---|
85 | 88 | .enable_hpd = dcn10_link_encoder_enable_hpd, |
---|
86 | 89 | .disable_hpd = dcn10_link_encoder_disable_hpd, |
---|
87 | 90 | .is_dig_enabled = dcn10_is_dig_enabled, |
---|
88 | | - .destroy = dcn10_link_encoder_destroy |
---|
| 91 | + .get_dig_frontend = dcn10_get_dig_frontend, |
---|
| 92 | + .get_dig_mode = dcn10_get_dig_mode, |
---|
| 93 | + .destroy = dcn10_link_encoder_destroy, |
---|
| 94 | + .get_max_link_cap = dcn10_link_encoder_get_max_link_cap, |
---|
89 | 95 | }; |
---|
90 | 96 | |
---|
91 | 97 | static enum bp_result link_transmitter_control( |
---|
.. | .. |
---|
228 | 234 | { |
---|
229 | 235 | uint32_t value; |
---|
230 | 236 | |
---|
231 | | - ASSERT(REG(DP_DPHY_INTERNAL_CTRL)); |
---|
| 237 | + if (!REG(DP_DPHY_INTERNAL_CTRL)) |
---|
| 238 | + return; |
---|
| 239 | + |
---|
232 | 240 | value = REG_READ(DP_DPHY_INTERNAL_CTRL); |
---|
233 | 241 | |
---|
234 | 242 | switch (panel_mode) { |
---|
.. | .. |
---|
440 | 448 | } |
---|
441 | 449 | } |
---|
442 | 450 | |
---|
443 | | -void configure_encoder( |
---|
| 451 | +unsigned int dcn10_get_dig_frontend(struct link_encoder *enc) |
---|
| 452 | +{ |
---|
| 453 | + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); |
---|
| 454 | + int32_t value; |
---|
| 455 | + enum engine_id result; |
---|
| 456 | + |
---|
| 457 | + REG_GET(DIG_BE_CNTL, DIG_FE_SOURCE_SELECT, &value); |
---|
| 458 | + |
---|
| 459 | + switch (value) { |
---|
| 460 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGA: |
---|
| 461 | + result = ENGINE_ID_DIGA; |
---|
| 462 | + break; |
---|
| 463 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGB: |
---|
| 464 | + result = ENGINE_ID_DIGB; |
---|
| 465 | + break; |
---|
| 466 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGC: |
---|
| 467 | + result = ENGINE_ID_DIGC; |
---|
| 468 | + break; |
---|
| 469 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGD: |
---|
| 470 | + result = ENGINE_ID_DIGD; |
---|
| 471 | + break; |
---|
| 472 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGE: |
---|
| 473 | + result = ENGINE_ID_DIGE; |
---|
| 474 | + break; |
---|
| 475 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGF: |
---|
| 476 | + result = ENGINE_ID_DIGF; |
---|
| 477 | + break; |
---|
| 478 | + case DCN10_DIG_FE_SOURCE_SELECT_DIGG: |
---|
| 479 | + result = ENGINE_ID_DIGG; |
---|
| 480 | + break; |
---|
| 481 | + default: |
---|
| 482 | + // invalid source select DIG |
---|
| 483 | + result = ENGINE_ID_UNKNOWN; |
---|
| 484 | + } |
---|
| 485 | + |
---|
| 486 | + return result; |
---|
| 487 | + |
---|
| 488 | +} |
---|
| 489 | + |
---|
| 490 | +void enc1_configure_encoder( |
---|
444 | 491 | struct dcn10_link_encoder *enc10, |
---|
445 | 492 | const struct dc_link_settings *link_settings) |
---|
446 | 493 | { |
---|
.. | .. |
---|
543 | 590 | if ((connector_signal == SIGNAL_TYPE_DVI_SINGLE_LINK || |
---|
544 | 591 | connector_signal == SIGNAL_TYPE_HDMI_TYPE_A) && |
---|
545 | 592 | signal != SIGNAL_TYPE_HDMI_TYPE_A && |
---|
546 | | - crtc_timing->pix_clk_khz > TMDS_MAX_PIXEL_CLOCK) |
---|
| 593 | + crtc_timing->pix_clk_100hz > (TMDS_MAX_PIXEL_CLOCK * 10)) |
---|
547 | 594 | return false; |
---|
548 | | - if (crtc_timing->pix_clk_khz < TMDS_MIN_PIXEL_CLOCK) |
---|
| 595 | + if (crtc_timing->pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10)) |
---|
549 | 596 | return false; |
---|
550 | 597 | |
---|
551 | | - if (crtc_timing->pix_clk_khz > max_pixel_clock) |
---|
| 598 | + if (crtc_timing->pix_clk_100hz > (max_pixel_clock * 10)) |
---|
552 | 599 | return false; |
---|
553 | 600 | |
---|
554 | 601 | /* DVI supports 6/8bpp single-link and 10/16bpp dual-link */ |
---|
.. | .. |
---|
571 | 618 | static bool dcn10_link_encoder_validate_hdmi_output( |
---|
572 | 619 | const struct dcn10_link_encoder *enc10, |
---|
573 | 620 | const struct dc_crtc_timing *crtc_timing, |
---|
574 | | - int adjusted_pix_clk_khz) |
---|
| 621 | + const struct dc_edid_caps *edid_caps, |
---|
| 622 | + int adjusted_pix_clk_100hz) |
---|
575 | 623 | { |
---|
576 | 624 | enum dc_color_depth max_deep_color = |
---|
577 | 625 | enc10->base.features.max_hdmi_deep_color; |
---|
| 626 | + |
---|
| 627 | + // check pixel clock against edid specified max TMDS clk |
---|
| 628 | + if (edid_caps->max_tmds_clk_mhz != 0 && |
---|
| 629 | + adjusted_pix_clk_100hz > edid_caps->max_tmds_clk_mhz * 10000) |
---|
| 630 | + return false; |
---|
578 | 631 | |
---|
579 | 632 | if (max_deep_color < crtc_timing->display_color_depth) |
---|
580 | 633 | return false; |
---|
581 | 634 | |
---|
582 | 635 | if (crtc_timing->display_color_depth < COLOR_DEPTH_888) |
---|
583 | 636 | return false; |
---|
584 | | - if (adjusted_pix_clk_khz < TMDS_MIN_PIXEL_CLOCK) |
---|
| 637 | + if (adjusted_pix_clk_100hz < (TMDS_MIN_PIXEL_CLOCK * 10)) |
---|
585 | 638 | return false; |
---|
586 | 639 | |
---|
587 | | - if ((adjusted_pix_clk_khz == 0) || |
---|
588 | | - (adjusted_pix_clk_khz > enc10->base.features.max_hdmi_pixel_clock)) |
---|
| 640 | + if ((adjusted_pix_clk_100hz == 0) || |
---|
| 641 | + (adjusted_pix_clk_100hz > (enc10->base.features.max_hdmi_pixel_clock * 10))) |
---|
589 | 642 | return false; |
---|
590 | 643 | |
---|
591 | 644 | /* DCE11 HW does not support 420 */ |
---|
592 | | - if (!enc10->base.features.ycbcr420_supported && |
---|
| 645 | + if (!enc10->base.features.hdmi_ycbcr420_supported && |
---|
593 | 646 | crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
---|
594 | 647 | return false; |
---|
595 | 648 | |
---|
596 | 649 | if (!enc10->base.features.flags.bits.HDMI_6GB_EN && |
---|
597 | | - adjusted_pix_clk_khz >= 300000) |
---|
| 650 | + adjusted_pix_clk_100hz >= 3000000) |
---|
598 | 651 | return false; |
---|
599 | 652 | if (enc10->base.ctx->dc->debug.hdmi20_disable && |
---|
600 | 653 | crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) |
---|
.. | .. |
---|
606 | 659 | const struct dcn10_link_encoder *enc10, |
---|
607 | 660 | const struct dc_crtc_timing *crtc_timing) |
---|
608 | 661 | { |
---|
609 | | - /* default RGB only */ |
---|
610 | | - if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) |
---|
611 | | - return true; |
---|
| 662 | + if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) { |
---|
| 663 | + if (!enc10->base.features.dp_ycbcr420_supported) |
---|
| 664 | + return false; |
---|
| 665 | + } |
---|
612 | 666 | |
---|
613 | | - if (enc10->base.features.flags.bits.IS_YCBCR_CAPABLE) |
---|
614 | | - return true; |
---|
615 | | - |
---|
616 | | - /* for DCE 8.x or later DP Y-only feature, |
---|
617 | | - * we need ASIC cap + FeatureSupportDPYonly, not support 666 |
---|
618 | | - */ |
---|
619 | | - if (crtc_timing->flags.Y_ONLY && |
---|
620 | | - enc10->base.features.flags.bits.IS_YCBCR_CAPABLE && |
---|
621 | | - crtc_timing->display_color_depth != COLOR_DEPTH_666) |
---|
622 | | - return true; |
---|
623 | | - |
---|
624 | | - return false; |
---|
| 667 | + return true; |
---|
625 | 668 | } |
---|
626 | 669 | |
---|
627 | 670 | void dcn10_link_encoder_construct( |
---|
.. | .. |
---|
726 | 769 | enc10->base.features.flags.bits.IS_HBR3_CAPABLE = |
---|
727 | 770 | bp_cap_info.DP_HBR3_EN; |
---|
728 | 771 | enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; |
---|
| 772 | + enc10->base.features.flags.bits.DP_IS_USB_C = |
---|
| 773 | + bp_cap_info.DP_IS_USB_C; |
---|
729 | 774 | } else { |
---|
730 | 775 | DC_LOG_WARNING("%s: Failed to get encoder_cap_info from VBIOS with error code %d!\n", |
---|
731 | 776 | __func__, |
---|
.. | .. |
---|
743 | 788 | struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); |
---|
744 | 789 | bool is_valid; |
---|
745 | 790 | |
---|
| 791 | + //if SCDC (340-600MHz) is disabled, set to HDMI 1.4 timing limit |
---|
| 792 | + if (stream->sink->edid_caps.panel_patch.skip_scdc_overwrite && |
---|
| 793 | + enc10->base.features.max_hdmi_pixel_clock > 300000) |
---|
| 794 | + enc10->base.features.max_hdmi_pixel_clock = 300000; |
---|
| 795 | + |
---|
746 | 796 | switch (stream->signal) { |
---|
747 | 797 | case SIGNAL_TYPE_DVI_SINGLE_LINK: |
---|
748 | 798 | case SIGNAL_TYPE_DVI_DUAL_LINK: |
---|
749 | 799 | is_valid = dcn10_link_encoder_validate_dvi_output( |
---|
750 | 800 | enc10, |
---|
751 | | - stream->sink->link->connector_signal, |
---|
| 801 | + stream->link->connector_signal, |
---|
752 | 802 | stream->signal, |
---|
753 | 803 | &stream->timing); |
---|
754 | 804 | break; |
---|
.. | .. |
---|
756 | 806 | is_valid = dcn10_link_encoder_validate_hdmi_output( |
---|
757 | 807 | enc10, |
---|
758 | 808 | &stream->timing, |
---|
759 | | - stream->phy_pix_clk); |
---|
| 809 | + &stream->sink->edid_caps, |
---|
| 810 | + stream->phy_pix_clk * 10); |
---|
760 | 811 | break; |
---|
761 | 812 | case SIGNAL_TYPE_DISPLAY_PORT: |
---|
762 | 813 | case SIGNAL_TYPE_DISPLAY_PORT_MST: |
---|
.. | .. |
---|
920 | 971 | * but it's not passed to asic_control. |
---|
921 | 972 | * We need to set number of lanes manually. |
---|
922 | 973 | */ |
---|
923 | | - configure_encoder(enc10, link_settings); |
---|
| 974 | + enc1_configure_encoder(enc10, link_settings); |
---|
924 | 975 | |
---|
925 | 976 | cntl.action = TRANSMITTER_CONTROL_ENABLE; |
---|
926 | 977 | cntl.engine_id = enc->preferred_engine; |
---|
.. | .. |
---|
959 | 1010 | * but it's not passed to asic_control. |
---|
960 | 1011 | * We need to set number of lanes manually. |
---|
961 | 1012 | */ |
---|
962 | | - configure_encoder(enc10, link_settings); |
---|
| 1013 | + enc1_configure_encoder(enc10, link_settings); |
---|
963 | 1014 | |
---|
964 | 1015 | cntl.action = TRANSMITTER_CONTROL_ENABLE; |
---|
965 | 1016 | cntl.engine_id = ENGINE_ID_UNKNOWN; |
---|
.. | .. |
---|
1304 | 1355 | #define HPD_REG_UPDATE_N(reg_name, n, ...) \ |
---|
1305 | 1356 | generic_reg_update_ex(CTX, \ |
---|
1306 | 1357 | HPD_REG(reg_name), \ |
---|
1307 | | - HPD_REG_READ(reg_name), \ |
---|
1308 | 1358 | n, __VA_ARGS__) |
---|
1309 | 1359 | |
---|
1310 | 1360 | #define HPD_REG_UPDATE(reg_name, field, val) \ |
---|
.. | .. |
---|
1327 | 1377 | DC_HPD_EN, 0); |
---|
1328 | 1378 | } |
---|
1329 | 1379 | |
---|
1330 | | - |
---|
1331 | 1380 | #define AUX_REG(reg)\ |
---|
1332 | 1381 | (enc10->aux_regs->reg) |
---|
1333 | 1382 | |
---|
.. | .. |
---|
1337 | 1386 | #define AUX_REG_UPDATE_N(reg_name, n, ...) \ |
---|
1338 | 1387 | generic_reg_update_ex(CTX, \ |
---|
1339 | 1388 | AUX_REG(reg_name), \ |
---|
1340 | | - AUX_REG_READ(reg_name), \ |
---|
1341 | 1389 | n, __VA_ARGS__) |
---|
1342 | 1390 | |
---|
1343 | 1391 | #define AUX_REG_UPDATE(reg_name, field, val) \ |
---|
.. | .. |
---|
1359 | 1407 | |
---|
1360 | 1408 | /* 1/4 window (the maximum allowed) */ |
---|
1361 | 1409 | AUX_REG_UPDATE(AUX_DPHY_RX_CONTROL0, |
---|
1362 | | - AUX_RX_RECEIVE_WINDOW, 1); |
---|
| 1410 | + AUX_RX_RECEIVE_WINDOW, 0); |
---|
| 1411 | +} |
---|
| 1412 | + |
---|
| 1413 | +enum signal_type dcn10_get_dig_mode( |
---|
| 1414 | + struct link_encoder *enc) |
---|
| 1415 | +{ |
---|
| 1416 | + struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc); |
---|
| 1417 | + uint32_t value; |
---|
| 1418 | + REG_GET(DIG_BE_CNTL, DIG_MODE, &value); |
---|
| 1419 | + switch (value) { |
---|
| 1420 | + case 1: |
---|
| 1421 | + return SIGNAL_TYPE_DISPLAY_PORT; |
---|
| 1422 | + case 2: |
---|
| 1423 | + return SIGNAL_TYPE_DVI_SINGLE_LINK; |
---|
| 1424 | + case 3: |
---|
| 1425 | + return SIGNAL_TYPE_HDMI_TYPE_A; |
---|
| 1426 | + case 5: |
---|
| 1427 | + return SIGNAL_TYPE_DISPLAY_PORT_MST; |
---|
| 1428 | + default: |
---|
| 1429 | + return SIGNAL_TYPE_NONE; |
---|
| 1430 | + } |
---|
| 1431 | + return SIGNAL_TYPE_NONE; |
---|
| 1432 | +} |
---|
| 1433 | + |
---|
| 1434 | +void dcn10_link_encoder_get_max_link_cap(struct link_encoder *enc, |
---|
| 1435 | + struct dc_link_settings *link_settings) |
---|
| 1436 | +{ |
---|
| 1437 | + /* Set Default link settings */ |
---|
| 1438 | + struct dc_link_settings max_link_cap = {LANE_COUNT_FOUR, LINK_RATE_HIGH, |
---|
| 1439 | + LINK_SPREAD_05_DOWNSPREAD_30KHZ, false, 0}; |
---|
| 1440 | + |
---|
| 1441 | + /* Higher link settings based on feature supported */ |
---|
| 1442 | + if (enc->features.flags.bits.IS_HBR2_CAPABLE) |
---|
| 1443 | + max_link_cap.link_rate = LINK_RATE_HIGH2; |
---|
| 1444 | + |
---|
| 1445 | + if (enc->features.flags.bits.IS_HBR3_CAPABLE) |
---|
| 1446 | + max_link_cap.link_rate = LINK_RATE_HIGH3; |
---|
| 1447 | + |
---|
| 1448 | + *link_settings = max_link_cap; |
---|
1363 | 1449 | } |
---|