diff options
author | SivapiriyanKumarasamy <sivapiriyan.kumarasamy@amd.com> | 2018-08-30 09:37:22 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-09-26 22:09:05 -0400 |
commit | c2791297013e531d1b7d8e17722bebec69386ab2 (patch) | |
tree | 462c8201aca3a56f6bcbaaa6f4f142a070dde084 /drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |
parent | 5aa9935b6531dfe6ebdc1cacbc8d8a736620345f (diff) |
drm/amd/display: Add color bit info to freesync infoframe
Parse the native color bit and send it to freesync module for future
use
Signed-off-by: SivapiriyanKumarasamy <sivapiriyan.kumarasamy@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync/freesync.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 164 |
1 files changed, 144 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index e1688902a1b0..4018c7180d00 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |||
@@ -480,22 +480,11 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync, | |||
480 | return false; | 480 | return false; |
481 | } | 481 | } |
482 | 482 | ||
483 | void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | 483 | static void build_vrr_infopacket_header_v1(enum signal_type signal, |
484 | const struct dc_stream_state *stream, | 484 | struct dc_info_packet *infopacket, |
485 | const struct mod_vrr_params *vrr, | 485 | unsigned int *payload_size) |
486 | struct dc_info_packet *infopacket) | ||
487 | { | 486 | { |
488 | /* SPD info packet for FreeSync */ | 487 | if (dc_is_hdmi_signal(signal)) { |
489 | unsigned char checksum = 0; | ||
490 | unsigned int idx, payload_size = 0; | ||
491 | |||
492 | /* Check if Freesync is supported. Return if false. If true, | ||
493 | * set the corresponding bit in the info packet | ||
494 | */ | ||
495 | if (!vrr->supported || !vrr->send_vsif) | ||
496 | return; | ||
497 | |||
498 | if (dc_is_hdmi_signal(stream->signal)) { | ||
499 | 488 | ||
500 | /* HEADER */ | 489 | /* HEADER */ |
501 | 490 | ||
@@ -510,9 +499,9 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | |||
510 | /* HB2 = [Bits 7:5 = 0] [Bits 4:0 = Length = 0x08] */ | 499 | /* HB2 = [Bits 7:5 = 0] [Bits 4:0 = Length = 0x08] */ |
511 | infopacket->hb2 = 0x08; | 500 | infopacket->hb2 = 0x08; |
512 | 501 | ||
513 | payload_size = 0x08; | 502 | *payload_size = 0x08; |
514 | 503 | ||
515 | } else if (dc_is_dp_signal(stream->signal)) { | 504 | } else if (dc_is_dp_signal(signal)) { |
516 | 505 | ||
517 | /* HEADER */ | 506 | /* HEADER */ |
518 | 507 | ||
@@ -536,9 +525,62 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | |||
536 | */ | 525 | */ |
537 | infopacket->hb3 = 0x04; | 526 | infopacket->hb3 = 0x04; |
538 | 527 | ||
539 | payload_size = 0x1B; | 528 | *payload_size = 0x1B; |
540 | } | 529 | } |
530 | } | ||
531 | |||
532 | static void build_vrr_infopacket_header_v2(enum signal_type signal, | ||
533 | struct dc_info_packet *infopacket, | ||
534 | unsigned int *payload_size) | ||
535 | { | ||
536 | if (dc_is_hdmi_signal(signal)) { | ||
537 | |||
538 | /* HEADER */ | ||
539 | |||
540 | /* HB0 = Packet Type = 0x83 (Source Product | ||
541 | * Descriptor InfoFrame) | ||
542 | */ | ||
543 | infopacket->hb0 = DC_HDMI_INFOFRAME_TYPE_SPD; | ||
544 | |||
545 | /* HB1 = Version = 0x02 */ | ||
546 | infopacket->hb1 = 0x02; | ||
547 | |||
548 | /* HB2 = [Bits 7:5 = 0] [Bits 4:0 = Length = 0x09] */ | ||
549 | infopacket->hb2 = 0x09; | ||
550 | |||
551 | *payload_size = 0x0A; | ||
541 | 552 | ||
553 | } else if (dc_is_dp_signal(signal)) { | ||
554 | |||
555 | /* HEADER */ | ||
556 | |||
557 | /* HB0 = Secondary-data Packet ID = 0 - Only non-zero | ||
558 | * when used to associate audio related info packets | ||
559 | */ | ||
560 | infopacket->hb0 = 0x00; | ||
561 | |||
562 | /* HB1 = Packet Type = 0x83 (Source Product | ||
563 | * Descriptor InfoFrame) | ||
564 | */ | ||
565 | infopacket->hb1 = DC_HDMI_INFOFRAME_TYPE_SPD; | ||
566 | |||
567 | /* HB2 = [Bits 7:0 = Least significant eight bits - | ||
568 | * For INFOFRAME, the value must be 1Bh] | ||
569 | */ | ||
570 | infopacket->hb2 = 0x1B; | ||
571 | |||
572 | /* HB3 = [Bits 7:2 = INFOFRAME SDP Version Number = 0x2] | ||
573 | * [Bits 1:0 = Most significant two bits = 0x00] | ||
574 | */ | ||
575 | infopacket->hb3 = 0x08; | ||
576 | |||
577 | *payload_size = 0x1B; | ||
578 | } | ||
579 | } | ||
580 | |||
581 | static void build_vrr_infopacket_data(const struct mod_vrr_params *vrr, | ||
582 | struct dc_info_packet *infopacket) | ||
583 | { | ||
542 | /* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ | 584 | /* PB1 = 0x1A (24bit AMD IEEE OUI (0x00001A) - Byte 0) */ |
543 | infopacket->sb[1] = 0x1A; | 585 | infopacket->sb[1] = 0x1A; |
544 | 586 | ||
@@ -576,15 +618,39 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | |||
576 | */ | 618 | */ |
577 | infopacket->sb[8] = (unsigned char)(vrr->max_refresh_in_uhz / 1000000); | 619 | infopacket->sb[8] = (unsigned char)(vrr->max_refresh_in_uhz / 1000000); |
578 | 620 | ||
579 | /* PB9 - PB27 = Reserved */ | ||
580 | 621 | ||
622 | //FreeSync HDR | ||
623 | infopacket->sb[9] = 0; | ||
624 | infopacket->sb[10] = 0; | ||
625 | } | ||
626 | |||
627 | static void build_vrr_infopacket_fs2_data(enum color_transfer_func app_tf, | ||
628 | struct dc_info_packet *infopacket) | ||
629 | { | ||
630 | if (app_tf != transfer_func_unknown) { | ||
631 | infopacket->valid = true; | ||
632 | |||
633 | infopacket->sb[6] |= 0x08; // PB6 = [Bit 3 = Native Color Active] | ||
634 | |||
635 | if (app_tf == transfer_func_gamma_22) { | ||
636 | infopacket->sb[9] |= 0x04; // PB6 = [Bit 2 = Gamma 2.2 EOTF Active] | ||
637 | } | ||
638 | } | ||
639 | } | ||
640 | |||
641 | static void build_vrr_infopacket_checksum(unsigned int *payload_size, | ||
642 | struct dc_info_packet *infopacket) | ||
643 | { | ||
581 | /* Calculate checksum */ | 644 | /* Calculate checksum */ |
645 | unsigned int idx = 0; | ||
646 | unsigned char checksum = 0; | ||
647 | |||
582 | checksum += infopacket->hb0; | 648 | checksum += infopacket->hb0; |
583 | checksum += infopacket->hb1; | 649 | checksum += infopacket->hb1; |
584 | checksum += infopacket->hb2; | 650 | checksum += infopacket->hb2; |
585 | checksum += infopacket->hb3; | 651 | checksum += infopacket->hb3; |
586 | 652 | ||
587 | for (idx = 1; idx <= payload_size; idx++) | 653 | for (idx = 1; idx <= *payload_size; idx++) |
588 | checksum += infopacket->sb[idx]; | 654 | checksum += infopacket->sb[idx]; |
589 | 655 | ||
590 | /* PB0 = Checksum (one byte complement) */ | 656 | /* PB0 = Checksum (one byte complement) */ |
@@ -593,6 +659,64 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | |||
593 | infopacket->valid = true; | 659 | infopacket->valid = true; |
594 | } | 660 | } |
595 | 661 | ||
662 | static void build_vrr_infopacket_v1(enum signal_type signal, | ||
663 | const struct mod_vrr_params *vrr, | ||
664 | struct dc_info_packet *infopacket) | ||
665 | { | ||
666 | /* SPD info packet for FreeSync */ | ||
667 | unsigned int payload_size = 0; | ||
668 | |||
669 | build_vrr_infopacket_header_v1(signal, infopacket, &payload_size); | ||
670 | build_vrr_infopacket_data(vrr, infopacket); | ||
671 | build_vrr_infopacket_checksum(&payload_size, infopacket); | ||
672 | |||
673 | infopacket->valid = true; | ||
674 | } | ||
675 | |||
676 | static void build_vrr_infopacket_v2(enum signal_type signal, | ||
677 | const struct mod_vrr_params *vrr, | ||
678 | const enum color_transfer_func *app_tf, | ||
679 | struct dc_info_packet *infopacket) | ||
680 | { | ||
681 | unsigned int payload_size = 0; | ||
682 | |||
683 | build_vrr_infopacket_header_v2(signal, infopacket, &payload_size); | ||
684 | build_vrr_infopacket_data(vrr, infopacket); | ||
685 | |||
686 | if (app_tf != NULL) | ||
687 | build_vrr_infopacket_fs2_data(*app_tf, infopacket); | ||
688 | |||
689 | build_vrr_infopacket_checksum(&payload_size, infopacket); | ||
690 | |||
691 | infopacket->valid = true; | ||
692 | } | ||
693 | |||
694 | void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | ||
695 | const struct dc_stream_state *stream, | ||
696 | const struct mod_vrr_params *vrr, | ||
697 | enum vrr_packet_type packet_type, | ||
698 | const enum color_transfer_func *app_tf, | ||
699 | struct dc_info_packet *infopacket) | ||
700 | { | ||
701 | /* SPD info packet for FreeSync */ | ||
702 | |||
703 | /* Check if Freesync is supported. Return if false. If true, | ||
704 | * set the corresponding bit in the info packet | ||
705 | */ | ||
706 | if (!vrr->supported || !vrr->send_vsif) | ||
707 | return; | ||
708 | |||
709 | switch (packet_type) { | ||
710 | case packet_type_fs2: | ||
711 | build_vrr_infopacket_v2(stream->signal, vrr, app_tf, infopacket); | ||
712 | break; | ||
713 | case packet_type_vrr: | ||
714 | case packet_type_fs1: | ||
715 | default: | ||
716 | build_vrr_infopacket_v1(stream->signal, vrr, infopacket); | ||
717 | } | ||
718 | } | ||
719 | |||
596 | void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, | 720 | void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, |
597 | const struct dc_stream_state *stream, | 721 | const struct dc_stream_state *stream, |
598 | struct mod_freesync_config *in_config, | 722 | struct mod_freesync_config *in_config, |