]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drm/radeon/kms: DCE5 atom SetPixelClock updates
authorAlex Deucher <alexdeucher@gmail.com>
Fri, 7 Jan 2011 02:19:15 +0000 (21:19 -0500)
committerDave Airlie <airlied@redhat.com>
Fri, 7 Jan 2011 04:11:22 +0000 (14:11 +1000)
Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/radeon_atombios.c

index 9fbabaa6ee448bb665766a34dc944c694e69eaa3..b3e5e7549008238dc48ad486212373687056d64b 100644 (file)
@@ -673,9 +673,14 @@ union set_pixel_clock {
        PIXEL_CLOCK_PARAMETERS_V2 v2;
        PIXEL_CLOCK_PARAMETERS_V3 v3;
        PIXEL_CLOCK_PARAMETERS_V5 v5;
+       PIXEL_CLOCK_PARAMETERS_V6 v6;
 };
 
-static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
+/* on DCE5, make sure the voltage is high enough to support the
+ * required disp clk.
+ */
+static void atombios_crtc_set_dcpll(struct drm_crtc *crtc,
+                                   u32 dispclk)
 {
        struct drm_device *dev = crtc->dev;
        struct radeon_device *rdev = dev->dev_private;
@@ -698,9 +703,16 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
                         * SetPixelClock provides the dividers
                         */
                        args.v5.ucCRTC = ATOM_CRTC_INVALID;
-                       args.v5.usPixelClock = rdev->clock.default_dispclk;
+                       args.v5.usPixelClock = dispclk;
                        args.v5.ucPpll = ATOM_DCPLL;
                        break;
+               case 6:
+                       /* if the default dcpll clock is specified,
+                        * SetPixelClock provides the dividers
+                        */
+                       args.v6.ulDispEngClkFreq = dispclk;
+                       args.v6.ucPpll = ATOM_DCPLL;
+                       break;
                default:
                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
                        return;
@@ -784,6 +796,18 @@ static void atombios_crtc_program_pll(struct drm_crtc *crtc,
                        args.v5.ucEncoderMode = encoder_mode;
                        args.v5.ucPpll = pll_id;
                        break;
+               case 6:
+                       args.v6.ulCrtcPclkFreq.ucCRTC = crtc_id;
+                       args.v6.ulCrtcPclkFreq.ulPixelClock = cpu_to_le32(clock / 10);
+                       args.v6.ucRefDiv = ref_div;
+                       args.v6.usFbDiv = cpu_to_le16(fb_div);
+                       args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
+                       args.v6.ucPostDiv = post_div;
+                       args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
+                       args.v6.ucTransmitterID = encoder_id;
+                       args.v6.ucEncoderMode = encoder_mode;
+                       args.v6.ucPpll = pll_id;
+                       break;
                default:
                        DRM_ERROR("Unknown table version %d %d\n", frev, crev);
                        return;
@@ -1377,7 +1401,8 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
                                                                   rdev->clock.default_dispclk);
                if (ss_enabled)
                        atombios_crtc_program_ss(crtc, ATOM_DISABLE, ATOM_DCPLL, &ss);
-               atombios_crtc_set_dcpll(crtc);
+               /* XXX: DCE5, make sure voltage, dispclk is high enough */
+               atombios_crtc_set_dcpll(crtc, rdev->clock.default_dispclk);
                if (ss_enabled)
                        atombios_crtc_program_ss(crtc, ATOM_ENABLE, ATOM_DCPLL, &ss);
        }
index e4f7e3e82a5088fce4c3ca0797e8276657600faf..11573d085e618e24375ecfe29b4440466f3e2559 100644 (file)
@@ -1086,6 +1086,7 @@ union firmware_info {
        ATOM_FIRMWARE_INFO_V1_3 info_13;
        ATOM_FIRMWARE_INFO_V1_4 info_14;
        ATOM_FIRMWARE_INFO_V2_1 info_21;
+       ATOM_FIRMWARE_INFO_V2_2 info_22;
 };
 
 bool radeon_atom_get_clock_info(struct drm_device *dev)
@@ -1160,8 +1161,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                *p2pll = *p1pll;
 
                /* system clock */
-               spll->reference_freq =
-                   le16_to_cpu(firmware_info->info.usReferenceClock);
+               if (ASIC_IS_DCE4(rdev))
+                       spll->reference_freq =
+                               le16_to_cpu(firmware_info->info_21.usCoreReferenceClock);
+               else
+                       spll->reference_freq =
+                               le16_to_cpu(firmware_info->info.usReferenceClock);
                spll->reference_div = 0;
 
                spll->pll_out_min =
@@ -1183,8 +1188,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                    le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input);
 
                /* memory clock */
-               mpll->reference_freq =
-                   le16_to_cpu(firmware_info->info.usReferenceClock);
+               if (ASIC_IS_DCE4(rdev))
+                       mpll->reference_freq =
+                               le16_to_cpu(firmware_info->info_21.usMemoryReferenceClock);
+               else
+                       mpll->reference_freq =
+                               le16_to_cpu(firmware_info->info.usReferenceClock);
                mpll->reference_div = 0;
 
                mpll->pll_out_min =
@@ -1213,8 +1222,12 @@ bool radeon_atom_get_clock_info(struct drm_device *dev)
                if (ASIC_IS_DCE4(rdev)) {
                        rdev->clock.default_dispclk =
                                le32_to_cpu(firmware_info->info_21.ulDefaultDispEngineClkFreq);
-                       if (rdev->clock.default_dispclk == 0)
-                               rdev->clock.default_dispclk = 60000; /* 600 Mhz */
+                       if (rdev->clock.default_dispclk == 0) {
+                               if (ASIC_IS_DCE5(rdev))
+                                       rdev->clock.default_dispclk = 54000; /* 540 Mhz */
+                               else
+                                       rdev->clock.default_dispclk = 60000; /* 600 Mhz */
+                       }
                        rdev->clock.dp_extclk =
                                le16_to_cpu(firmware_info->info_21.usUniphyDPModeExtClkFreq);
                }