aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/atombios_crtc.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2014-04-21 22:09:19 -0400
committerAlex Deucher <alexander.deucher@amd.com>2014-06-02 18:37:32 -0400
commitf71d9ebd92437faf8dd1ada32ab5ddac4c6e5e67 (patch)
tree2a5e88b71832121303720fcd1bbf845bd036eec0 /drivers/gpu/drm/radeon/atombios_crtc.c
parent79766915d91f0dc20ae44484ec0febb0281caa2a (diff)
drm/radeon: fix pll setup for hdmi deep color (v7)
Need to adjust the pll up for deep color modes. Additionally, the atom bpc defines were wrong in certain cases. v2: set the adjusted clock to the pll clock for hdmi deep color. This fixes display and audio issues with deep color as reported by Andy Furniss <adf.lists@gmail.com> v3: set crtc_clock as well v4: setcrtcinfo on the adjusted mode v5: just use the adjusted clock for setting the pll v6: only use the adjusted clock for hdmi v7: only DCE5 and DCE6 and bpc > 8 Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/atombios_crtc.c')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c45
1 files changed, 36 insertions, 9 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index c96d1d56bc4a..967d193d36d0 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -559,6 +559,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
559 u32 adjusted_clock = mode->clock; 559 u32 adjusted_clock = mode->clock;
560 int encoder_mode = atombios_get_encoder_mode(encoder); 560 int encoder_mode = atombios_get_encoder_mode(encoder);
561 u32 dp_clock = mode->clock; 561 u32 dp_clock = mode->clock;
562 u32 clock = mode->clock;
562 int bpc = radeon_crtc->bpc; 563 int bpc = radeon_crtc->bpc;
563 bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock); 564 bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);
564 565
@@ -634,6 +635,24 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
634 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; 635 radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
635 } 636 }
636 637
638 /* adjust pll for deep color modes */
639 if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
640 switch (bpc) {
641 case 8:
642 default:
643 break;
644 case 10:
645 clock = (clock * 5) / 4;
646 break;
647 case 12:
648 clock = (clock * 3) / 2;
649 break;
650 case 16:
651 clock = clock * 2;
652 break;
653 }
654 }
655
637 /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock 656 /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
638 * accordingly based on the encoder/transmitter to work around 657 * accordingly based on the encoder/transmitter to work around
639 * special hw requirements. 658 * special hw requirements.
@@ -655,7 +674,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
655 switch (crev) { 674 switch (crev) {
656 case 1: 675 case 1:
657 case 2: 676 case 2:
658 args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); 677 args.v1.usPixelClock = cpu_to_le16(clock / 10);
659 args.v1.ucTransmitterID = radeon_encoder->encoder_id; 678 args.v1.ucTransmitterID = radeon_encoder->encoder_id;
660 args.v1.ucEncodeMode = encoder_mode; 679 args.v1.ucEncodeMode = encoder_mode;
661 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage) 680 if (radeon_crtc->ss_enabled && radeon_crtc->ss.percentage)
@@ -667,7 +686,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
667 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10; 686 adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
668 break; 687 break;
669 case 3: 688 case 3:
670 args.v3.sInput.usPixelClock = cpu_to_le16(mode->clock / 10); 689 args.v3.sInput.usPixelClock = cpu_to_le16(clock / 10);
671 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id; 690 args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
672 args.v3.sInput.ucEncodeMode = encoder_mode; 691 args.v3.sInput.ucEncodeMode = encoder_mode;
673 args.v3.sInput.ucDispPllConfig = 0; 692 args.v3.sInput.ucDispPllConfig = 0;
@@ -681,10 +700,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
681 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); 700 args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
682 } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { 701 } else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
683 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; 702 struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
684 if (encoder_mode == ATOM_ENCODER_MODE_HDMI)
685 /* deep color support */
686 args.v3.sInput.usPixelClock =
687 cpu_to_le16((mode->clock * bpc / 8) / 10);
688 if (dig->coherent_mode) 703 if (dig->coherent_mode)
689 args.v3.sInput.ucDispPllConfig |= 704 args.v3.sInput.ucDispPllConfig |=
690 DISPPLL_CONFIG_COHERENT_MODE; 705 DISPPLL_CONFIG_COHERENT_MODE;
@@ -871,6 +886,11 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
871 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP; 886 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
872 break; 887 break;
873 case 10: 888 case 10:
889 /* yes this is correct, the atom define is wrong */
890 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
891 break;
892 case 12:
893 /* yes this is correct, the atom define is wrong */
874 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP; 894 args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
875 break; 895 break;
876 } 896 }
@@ -895,10 +915,10 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
895 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP; 915 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
896 break; 916 break;
897 case 10: 917 case 10:
898 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP; 918 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
899 break; 919 break;
900 case 12: 920 case 12:
901 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP; 921 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
902 break; 922 break;
903 case 16: 923 case 16:
904 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP; 924 args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
@@ -1025,10 +1045,17 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
1025 struct radeon_encoder *radeon_encoder = 1045 struct radeon_encoder *radeon_encoder =
1026 to_radeon_encoder(radeon_crtc->encoder); 1046 to_radeon_encoder(radeon_crtc->encoder);
1027 u32 pll_clock = mode->clock; 1047 u32 pll_clock = mode->clock;
1048 u32 clock = mode->clock;
1028 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0; 1049 u32 ref_div = 0, fb_div = 0, frac_fb_div = 0, post_div = 0;
1029 struct radeon_pll *pll; 1050 struct radeon_pll *pll;
1030 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); 1051 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
1031 1052
1053 /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */
1054 if (ASIC_IS_DCE5(rdev) && !ASIC_IS_DCE8(rdev) &&
1055 (encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
1056 (radeon_crtc->bpc > 8))
1057 clock = radeon_crtc->adjusted_clock;
1058
1032 switch (radeon_crtc->pll_id) { 1059 switch (radeon_crtc->pll_id) {
1033 case ATOM_PPLL1: 1060 case ATOM_PPLL1:
1034 pll = &rdev->clock.p1pll; 1061 pll = &rdev->clock.p1pll;
@@ -1063,7 +1090,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
1063 radeon_crtc->crtc_id, &radeon_crtc->ss); 1090 radeon_crtc->crtc_id, &radeon_crtc->ss);
1064 1091
1065 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, 1092 atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
1066 encoder_mode, radeon_encoder->encoder_id, mode->clock, 1093 encoder_mode, radeon_encoder->encoder_id, clock,
1067 ref_div, fb_div, frac_fb_div, post_div, 1094 ref_div, fb_div, frac_fb_div, post_div,
1068 radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss); 1095 radeon_crtc->bpc, radeon_crtc->ss_enabled, &radeon_crtc->ss);
1069 1096