Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Change infopacket type programming

[Why]
Certain displays may experience blanking if infopacket max range does
not equal nominal refresh rate.

[How]
Add additional infopacket versions to program range to full or forced
range in freesync states.
This does not change the vrr logic.

Signed-off-by: Haiyi Zhou <haiyi.zhou@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Haiyi Zhou and committed by
Alex Deucher
d2bacc38 f1029e7e

+99 -10
+93 -8
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
··· 443 443 return true; 444 444 } else if (in_vrr->state == VRR_STATE_ACTIVE_FIXED && 445 445 in_vrr->fixed.target_refresh_in_uhz != 446 - in_config->min_refresh_in_uhz) { 446 + in_config->fixed_refresh_in_uhz) { 447 447 return true; 448 448 } else if (in_vrr->min_refresh_in_uhz != min_refresh_in_uhz) { 449 449 return true; ··· 491 491 return false; 492 492 } 493 493 494 - static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr, 494 + static void build_vrr_infopacket_data_v1(const struct mod_vrr_params *vrr, 495 495 struct dc_info_packet *infopacket) 496 496 { 497 497 /* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ ··· 523 523 vrr->state == VRR_STATE_ACTIVE_FIXED) 524 524 infopacket->sb[6] |= 0x04; 525 525 526 + // For v1 & 2 infoframes program nominal if non-fs mode, otherwise full range 526 527 /* PB7 = FreeSync Minimum refresh rate (Hz) */ 527 - infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000); 528 + if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || 529 + vrr->state == VRR_STATE_ACTIVE_FIXED) { 530 + infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000); 531 + } else { 532 + infopacket->sb[7] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); 533 + } 528 534 529 535 /* PB8 = FreeSync Maximum refresh rate (Hz) 530 536 * Note: We should never go above the field rate of the mode timing set. 531 537 */ 532 538 infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); 533 539 540 + //FreeSync HDR 541 + infopacket->sb[9] = 0; 542 + infopacket->sb[10] = 0; 543 + } 544 + 545 + static void build_vrr_infopacket_data_v3(const struct mod_vrr_params *vrr, 546 + struct dc_info_packet *infopacket) 547 + { 548 + /* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ 549 + infopacket->sb[1] = 0x1A; 550 + 551 + /* PB2 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 1) */ 552 + infopacket->sb[2] = 0x00; 553 + 554 + /* PB3 = 0x00 (24bit AMD IEEE OUI (0x00001A) - Byte 2) */ 555 + infopacket->sb[3] = 0x00; 556 + 557 + /* PB4 = Reserved */ 558 + 559 + /* PB5 = Reserved */ 560 + 561 + /* PB6 = [Bits 7:3 = Reserved] */ 562 + 563 + /* PB6 = [Bit 0 = FreeSync Supported] */ 564 + if (vrr->state != VRR_STATE_UNSUPPORTED) 565 + infopacket->sb[6] |= 0x01; 566 + 567 + /* PB6 = [Bit 1 = FreeSync Enabled] */ 568 + if (vrr->state != VRR_STATE_DISABLED && 569 + vrr->state != VRR_STATE_UNSUPPORTED) 570 + infopacket->sb[6] |= 0x02; 571 + 572 + /* PB6 = [Bit 2 = FreeSync Active] */ 573 + if (vrr->state == VRR_STATE_ACTIVE_VARIABLE || 574 + vrr->state == VRR_STATE_ACTIVE_FIXED) 575 + infopacket->sb[6] |= 0x04; 576 + 577 + if (vrr->state == VRR_STATE_ACTIVE_FIXED) { 578 + /* PB7 = FreeSync Minimum refresh rate (Hz) */ 579 + infopacket->sb[7] = (unsigned char)((vrr->fixed_refresh_in_uhz + 500000) / 1000000); 580 + /* PB8 = FreeSync Maximum refresh rate (Hz) */ 581 + infopacket->sb[8] = (unsigned char)((vrr->fixed_refresh_in_uhz + 500000) / 1000000); 582 + } else if (vrr->state == VRR_STATE_ACTIVE_VARIABLE) { 583 + /* PB7 = FreeSync Minimum refresh rate (Hz) */ 584 + infopacket->sb[7] = (unsigned char)((vrr->min_refresh_in_uhz + 500000) / 1000000); 585 + /* PB8 = FreeSync Maximum refresh rate (Hz) */ 586 + infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); 587 + } else { 588 + // Non-fs case, program nominal range 589 + /* PB7 = FreeSync Minimum refresh rate (Hz) */ 590 + infopacket->sb[7] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); 591 + /* PB8 = FreeSync Maximum refresh rate (Hz) */ 592 + infopacket->sb[8] = (unsigned char)((vrr->max_refresh_in_uhz + 500000) / 1000000); 593 + } 534 594 535 595 //FreeSync HDR 536 596 infopacket->sb[9] = 0; ··· 738 678 unsigned int payload_size = 0; 739 679 740 680 build_vrr_infopacket_header_v1(signal, infopacket, &payload_size); 741 - build_vrr_infopacket_data(vrr, infopacket); 681 + build_vrr_infopacket_data_v1(vrr, infopacket); 742 682 build_vrr_infopacket_checksum(&payload_size, infopacket); 743 683 744 684 infopacket->valid = true; ··· 752 692 unsigned int payload_size = 0; 753 693 754 694 build_vrr_infopacket_header_v2(signal, infopacket, &payload_size); 755 - build_vrr_infopacket_data(vrr, infopacket); 695 + build_vrr_infopacket_data_v1(vrr, infopacket); 696 + 697 + build_vrr_infopacket_fs2_data(app_tf, infopacket); 698 + 699 + build_vrr_infopacket_checksum(&payload_size, infopacket); 700 + 701 + infopacket->valid = true; 702 + } 703 + 704 + static void build_vrr_infopacket_v3(enum signal_type signal, 705 + const struct mod_vrr_params *vrr, 706 + enum color_transfer_func app_tf, 707 + struct dc_info_packet *infopacket) 708 + { 709 + unsigned int payload_size = 0; 710 + 711 + build_vrr_infopacket_header_v2(signal, infopacket, &payload_size); 712 + build_vrr_infopacket_data_v3(vrr, infopacket); 756 713 757 714 build_vrr_infopacket_fs2_data(app_tf, infopacket); 758 715 ··· 794 717 return; 795 718 796 719 switch (packet_type) { 797 - case PACKET_TYPE_FS2: 720 + case PACKET_TYPE_FS_V3: 721 + build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket); 722 + break; 723 + case PACKET_TYPE_FS_V2: 798 724 build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket); 799 725 break; 800 726 case PACKET_TYPE_VRR: 801 - case PACKET_TYPE_FS1: 727 + case PACKET_TYPE_FS_V1: 802 728 default: 803 729 build_vrr_infopacket_v1(stream->signal, vrr, infopacket); 804 730 } ··· 873 793 calc_duration_in_us_from_refresh_in_uhz( 874 794 (unsigned int)max_refresh_in_uhz); 875 795 796 + if (in_config->state == VRR_STATE_ACTIVE_FIXED) 797 + in_out_vrr->fixed_refresh_in_uhz = in_config->fixed_refresh_in_uhz; 798 + else 799 + in_out_vrr->fixed_refresh_in_uhz = 0; 800 + 876 801 refresh_range = in_out_vrr->max_refresh_in_uhz - 877 802 in_out_vrr->min_refresh_in_uhz; 878 803 ··· 928 843 in_out_vrr->min_refresh_in_uhz); 929 844 } else if (in_out_vrr->state == VRR_STATE_ACTIVE_FIXED) { 930 845 in_out_vrr->fixed.target_refresh_in_uhz = 931 - in_out_vrr->min_refresh_in_uhz; 846 + in_out_vrr->fixed_refresh_in_uhz; 932 847 if (in_out_vrr->fixed.ramping_active && 933 848 in_out_vrr->fixed.fixed_active) { 934 849 /* Do not update vtotals if ramping is already active
+3
drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
··· 83 83 bool btr; 84 84 unsigned int min_refresh_in_uhz; 85 85 unsigned int max_refresh_in_uhz; 86 + unsigned int fixed_refresh_in_uhz; 87 + 86 88 }; 87 89 88 90 struct mod_vrr_params_btr { ··· 114 112 uint32_t max_duration_in_us; 115 113 uint32_t max_refresh_in_uhz; 116 114 uint32_t min_duration_in_us; 115 + uint32_t fixed_refresh_in_uhz; 117 116 118 117 struct dc_crtc_timing_adjust adjust; 119 118
+3 -2
drivers/gpu/drm/amd/display/modules/inc/mod_shared.h
··· 40 40 41 41 enum vrr_packet_type { 42 42 PACKET_TYPE_VRR, 43 - PACKET_TYPE_FS1, 44 - PACKET_TYPE_FS2, 43 + PACKET_TYPE_FS_V1, 44 + PACKET_TYPE_FS_V2, 45 + PACKET_TYPE_FS_V3, 45 46 PACKET_TYPE_VTEM 46 47 }; 47 48