diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2014-04-21 22:09:19 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2014-06-02 18:37:32 -0400 |
commit | f71d9ebd92437faf8dd1ada32ab5ddac4c6e5e67 (patch) | |
tree | 2a5e88b71832121303720fcd1bbf845bd036eec0 /drivers/gpu/drm/radeon/atombios_crtc.c | |
parent | 79766915d91f0dc20ae44484ec0febb0281caa2a (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.c | 45 |
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 | ||