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 | |
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')
4 files changed, 198 insertions, 21 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 6c849e055038..ca41d1fc51ba 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | |||
@@ -4797,6 +4797,8 @@ void set_freesync_on_stream(struct amdgpu_display_manager *dm, | |||
4797 | mod_freesync_build_vrr_infopacket(dm->freesync_module, | 4797 | mod_freesync_build_vrr_infopacket(dm->freesync_module, |
4798 | new_stream, | 4798 | new_stream, |
4799 | &vrr, | 4799 | &vrr, |
4800 | packet_type_fs1, | ||
4801 | NULL, | ||
4800 | &vrr_infopacket); | 4802 | &vrr_infopacket); |
4801 | 4803 | ||
4802 | new_crtc_state->adjust = vrr.adjust; | 4804 | new_crtc_state->adjust = vrr.adjust; |
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, |
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h index a0f32cde721c..949a8b62aa98 100644 --- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h | |||
@@ -54,7 +54,7 @@ | |||
54 | #ifndef MOD_FREESYNC_H_ | 54 | #ifndef MOD_FREESYNC_H_ |
55 | #define MOD_FREESYNC_H_ | 55 | #define MOD_FREESYNC_H_ |
56 | 56 | ||
57 | #include "dm_services.h" | 57 | #include "mod_shared.h" |
58 | 58 | ||
59 | // Access structures | 59 | // Access structures |
60 | struct mod_freesync { | 60 | struct mod_freesync { |
@@ -144,6 +144,8 @@ void mod_freesync_get_settings(struct mod_freesync *mod_freesync, | |||
144 | void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, | 144 | void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync, |
145 | const struct dc_stream_state *stream, | 145 | const struct dc_stream_state *stream, |
146 | const struct mod_vrr_params *vrr, | 146 | const struct mod_vrr_params *vrr, |
147 | enum vrr_packet_type packet_type, | ||
148 | const enum color_transfer_func *app_tf, | ||
147 | struct dc_info_packet *infopacket); | 149 | struct dc_info_packet *infopacket); |
148 | 150 | ||
149 | void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, | 151 | void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync, |
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h b/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h new file mode 100644 index 000000000000..238c431ae483 --- /dev/null +++ b/drivers/gpu/drm/amd/display/modules/inc/mod_shared.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Copyright 2016 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: AMD | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | |||
27 | #ifndef MOD_SHARED_H_ | ||
28 | #define MOD_SHARED_H_ | ||
29 | |||
30 | enum color_transfer_func { | ||
31 | transfer_func_unknown, | ||
32 | transfer_func_srgb, | ||
33 | transfer_func_bt709, | ||
34 | transfer_func_pq2084, | ||
35 | transfer_func_pq2084_interim, | ||
36 | transfer_func_linear_0_1, | ||
37 | transfer_func_linear_0_125, | ||
38 | transfer_func_dolbyvision, | ||
39 | transfer_func_gamma_22, | ||
40 | transfer_func_gamma_26 | ||
41 | }; | ||
42 | |||
43 | enum vrr_packet_type { | ||
44 | packet_type_vrr, | ||
45 | packet_type_fs1, | ||
46 | packet_type_fs2 | ||
47 | }; | ||
48 | |||
49 | #endif /* MOD_SHARED_H_ */ | ||