Need to adjust the pll up for deep color modes.
Additionally, the atom bpc defines were wrong in certain
cases.

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/radeon/atombios_crtc.c | 36 ++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c 
b/drivers/gpu/drm/radeon/atombios_crtc.c
index c96d1d5..82ee6b0 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,
        u32 adjusted_clock = mode->clock;
        int encoder_mode = atombios_get_encoder_mode(encoder);
        u32 dp_clock = mode->clock;
+       u32 clock = mode->clock;
        int bpc = radeon_crtc->bpc;
        bool is_duallink = radeon_dig_monitor_is_duallink(encoder, mode->clock);

@@ -634,6 +635,24 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV;
        }

+       /* adjust pll for deep color modes */
+       if (encoder_mode == ATOM_ENCODER_MODE_HDMI) {
+               switch (bpc) {
+               case 8:
+               default:
+                       break;
+               case 10:
+                       clock = (clock * 5) / 4;
+                       break;
+               case 12:
+                       clock = (clock * 3) / 2;
+                       break;
+               case 16:
+                       clock = clock * 2;
+                       break;
+               }
+       }
+
        /* DCE3+ has an AdjustDisplayPll that will adjust the pixel clock
         * accordingly based on the encoder/transmitter to work around
         * special hw requirements.
@@ -655,7 +674,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                        switch (crev) {
                        case 1:
                        case 2:
-                               args.v1.usPixelClock = cpu_to_le16(mode->clock 
/ 10);
+                               args.v1.usPixelClock = cpu_to_le16(clock / 10);
                                args.v1.ucTransmitterID = 
radeon_encoder->encoder_id;
                                args.v1.ucEncodeMode = encoder_mode;
                                if (radeon_crtc->ss_enabled && 
radeon_crtc->ss.percentage)
@@ -667,7 +686,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                adjusted_clock = 
le16_to_cpu(args.v1.usPixelClock) * 10;
                                break;
                        case 3:
-                               args.v3.sInput.usPixelClock = 
cpu_to_le16(mode->clock / 10);
+                               args.v3.sInput.usPixelClock = cpu_to_le16(clock 
/ 10);
                                args.v3.sInput.ucTransmitterID = 
radeon_encoder->encoder_id;
                                args.v3.sInput.ucEncodeMode = encoder_mode;
                                args.v3.sInput.ucDispPllConfig = 0;
@@ -681,10 +700,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                        args.v3.sInput.usPixelClock = 
cpu_to_le16(dp_clock / 10);
                                } else if (radeon_encoder->devices & 
(ATOM_DEVICE_DFP_SUPPORT)) {
                                        struct radeon_encoder_atom_dig *dig = 
radeon_encoder->enc_priv;
-                                       if (encoder_mode == 
ATOM_ENCODER_MODE_HDMI)
-                                               /* deep color support */
-                                               args.v3.sInput.usPixelClock =
-                                                       
cpu_to_le16((mode->clock * bpc / 8) / 10);
                                        if (dig->coherent_mode)
                                                args.v3.sInput.ucDispPllConfig 
|=
                                                        
DISPPLL_CONFIG_COHERENT_MODE;
@@ -871,6 +886,11 @@ static void atombios_crtc_program_pll(struct drm_crtc 
*crtc,
                                        args.v5.ucMiscInfo |= 
PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
                                        break;
                                case 10:
+                                       /* yes this is correct, the atom define 
is wrong */
+                                       args.v5.ucMiscInfo |= 
PIXEL_CLOCK_V5_MISC_HDMI_32BPP;
+                                       break;
+                               case 12:
+                                       /* yes this is correct, the atom define 
is wrong */
                                        args.v5.ucMiscInfo |= 
PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
                                        break;
                                }
@@ -895,10 +915,10 @@ static void atombios_crtc_program_pll(struct drm_crtc 
*crtc,
                                        args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
                                        break;
                                case 10:
-                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
+                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_30BPP_V6;
                                        break;
                                case 12:
-                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
+                                       args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_36BPP_V6;
                                        break;
                                case 16:
                                        args.v6.ucMiscInfo |= 
PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
-- 
1.8.3.1

Reply via email to