From: Alex Deucher <alexander.deuc...@amd.com>

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/sumo_dpm.c |   55 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/sumod.h    |   10 +++++++
 2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c 
b/drivers/gpu/drm/radeon/sumo_dpm.c
index f103880..cef25c4 100644
--- a/drivers/gpu/drm/radeon/sumo_dpm.c
+++ b/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -811,6 +811,40 @@ static void sumo_program_bootup_state(struct radeon_device 
*rdev)
                sumo_power_level_enable(rdev, i, false);
 }

+static void sumo_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev)
+{
+       struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+       struct sumo_ps *current_ps = sumo_get_ps(rdev->pm.dpm.current_ps);
+
+       if ((rdev->pm.dpm.requested_ps->vclk == rdev->pm.dpm.current_ps->vclk) 
&&
+           (rdev->pm.dpm.requested_ps->dclk == rdev->pm.dpm.current_ps->dclk))
+               return;
+
+       if (new_ps->levels[new_ps->num_levels - 1].sclk >=
+           current_ps->levels[current_ps->num_levels - 1].sclk)
+               return;
+
+       radeon_set_uvd_clocks(rdev, rdev->pm.dpm.requested_ps->vclk,
+                             rdev->pm.dpm.requested_ps->dclk);
+}
+
+static void sumo_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev)
+{
+       struct sumo_ps *new_ps = sumo_get_ps(rdev->pm.dpm.requested_ps);
+       struct sumo_ps *current_ps = sumo_get_ps(rdev->pm.dpm.current_ps);
+
+       if ((rdev->pm.dpm.requested_ps->vclk == rdev->pm.dpm.current_ps->vclk) 
&&
+           (rdev->pm.dpm.requested_ps->dclk == rdev->pm.dpm.current_ps->dclk))
+               return;
+
+       if (new_ps->levels[new_ps->num_levels - 1].sclk <
+           current_ps->levels[current_ps->num_levels - 1].sclk)
+               return;
+
+       radeon_set_uvd_clocks(rdev, rdev->pm.dpm.requested_ps->vclk,
+                             rdev->pm.dpm.requested_ps->dclk);
+}
+
 void sumo_take_smu_control(struct radeon_device *rdev, bool enable)
 {
 /* This bit selects who handles display phy powergating.
@@ -1096,6 +1130,22 @@ static void sumo_cleanup_asic(struct radeon_device *rdev)
        sumo_take_smu_control(rdev, false);
 }

+static void sumo_uvd_init(struct radeon_device *rdev)
+{
+       u32 tmp;
+
+       tmp = RREG32(CG_VCLK_CNTL);
+       tmp &= ~VCLK_DIR_CNTL_EN;
+       WREG32(CG_VCLK_CNTL, tmp);
+
+       tmp = RREG32(CG_DCLK_CNTL);
+       tmp &= ~DCLK_DIR_CNTL_EN;
+       WREG32(CG_DCLK_CNTL, tmp);
+
+       /* 100 Mhz */
+       radeon_set_uvd_clocks(rdev, 10000, 10000);
+}
+
 static int sumo_set_thermal_temperature_range(struct radeon_device *rdev,
                                              int min_temp, int max_temp)
 {
@@ -1188,6 +1238,8 @@ int sumo_dpm_set_power_state(struct radeon_device *rdev)

        if (pi->enable_dynamic_patch_ps)
                sumo_apply_state_adjust_rules(rdev);
+       if (pi->enable_dpm)
+               sumo_set_uvd_clock_before_set_eng_clock(rdev);
        sumo_update_current_power_levels(rdev);
        if (pi->enable_boost) {
                sumo_enable_boost(rdev, false);
@@ -1211,6 +1263,8 @@ int sumo_dpm_set_power_state(struct radeon_device *rdev)
        }
        if (pi->enable_boost)
                sumo_enable_boost(rdev, true);
+       if (pi->enable_dpm)
+               sumo_set_uvd_clock_after_set_eng_clock(rdev);

        return 0;
 }
@@ -1237,6 +1291,7 @@ void sumo_dpm_setup_asic(struct radeon_device *rdev)
        sumo_program_acpi_power_level(rdev);
        sumo_enable_acpi_pm(rdev);
        sumo_take_smu_control(rdev, true);
+       sumo_uvd_init(rdev);
 }

 void sumo_dpm_display_configuration_changed(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/sumod.h b/drivers/gpu/drm/radeon/sumod.h
index a5deba6..7c9c2d4 100644
--- a/drivers/gpu/drm/radeon/sumod.h
+++ b/drivers/gpu/drm/radeon/sumod.h
@@ -136,6 +136,16 @@
 #define CG_SCLK_STATUS                                  0x604
 #       define SCLK_OVERCLK_DETECT                      (1 << 2)

+#define CG_DCLK_CNTL                                    0x610
+#       define DCLK_DIVIDER_MASK                        0x7f
+#       define DCLK_DIR_CNTL_EN                         (1 << 8)
+#define CG_DCLK_STATUS                                  0x614
+#       define DCLK_STATUS                              (1 << 0)
+#define CG_VCLK_CNTL                                    0x618
+#       define VCLK_DIVIDER_MASK                        0x7f
+#       define VCLK_DIR_CNTL_EN                         (1 << 8)
+#define CG_VCLK_STATUS                                  0x61c
+
 #define GENERAL_PWRMGT                                  0x63c
 #       define STATIC_PM_EN                             (1 << 1)

-- 
1.7.7.5

Reply via email to