drm/radeon/dpm: add debugfs support for RS780/RS880 (v3)
authorAlex Deucher <alexander.deucher@amd.com>
Tue, 2 Jul 2013 17:05:23 +0000 (13:05 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 17 Jul 2013 20:47:52 +0000 (16:47 -0400)
This allows you to look at the current DPM state via
debugfs.

Due to the way the hardware works on these asics, there's
no way to look up exactly what power state we are in, so
we make the best guess we can based on the current sclk.

v2: Anthoine's version
v3: fix ref div

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/radeon/radeon_asic.c
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/rs780_dpm.c
drivers/gpu/drm/radeon/rs780d.h

index fea997e247ba0e1de7d88515f9a45a6f93dd8adc..78bec1a58ed1a70be65e9bd11bc235fcded90df6 100644 (file)
@@ -1270,6 +1270,7 @@ static struct radeon_asic rs780_asic = {
                .get_sclk = &rs780_dpm_get_sclk,
                .get_mclk = &rs780_dpm_get_mclk,
                .print_power_state = &rs780_dpm_print_power_state,
+               .debugfs_print_current_performance_level = &rs780_dpm_debugfs_print_current_performance_level,
        },
        .pflip = {
                .pre_page_flip = &rs600_pre_page_flip,
index b04b5789f4a87bde7f83859134070d3441a7b27d..ca1895709908b428bdc078c36abc5e40a19e6d73 100644 (file)
@@ -433,6 +433,8 @@ u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low);
 u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low);
 void rs780_dpm_print_power_state(struct radeon_device *rdev,
                                 struct radeon_ps *ps);
+void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+                                                      struct seq_file *m);
 
 /* uvd */
 int r600_uvd_init(struct radeon_device *rdev);
index bef832a62fee54f04709e359e46becbe020b677f..d1a1ce73bd45548392deabbef5815e463a97dcd2 100644 (file)
@@ -28,6 +28,7 @@
 #include "r600_dpm.h"
 #include "rs780_dpm.h"
 #include "atom.h"
+#include <linux/seq_file.h>
 
 static struct igp_ps *rs780_get_ps(struct radeon_ps *rps)
 {
@@ -961,3 +962,27 @@ u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low)
 
        return pi->bootup_uma_clk;
 }
+
+void rs780_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
+                                                      struct seq_file *m)
+{
+       struct radeon_ps *rps = rdev->pm.dpm.current_ps;
+       struct igp_ps *ps = rs780_get_ps(rps);
+       u32 current_fb_div = RREG32(FVTHROT_STATUS_REG0) & CURRENT_FEEDBACK_DIV_MASK;
+       u32 func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
+       u32 ref_div = ((func_cntl & SPLL_REF_DIV_MASK) >> SPLL_REF_DIV_SHIFT) + 1;
+       u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >> SPLL_SW_HILEN_SHIFT) + 1 +
+               ((func_cntl & SPLL_SW_LOLEN_MASK) >> SPLL_SW_LOLEN_SHIFT) + 1;
+       u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
+               (post_div * ref_div);
+
+       seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
+
+       /* guess based on the current sclk */
+       if (sclk < (ps->sclk_low + 500))
+               seq_printf(m, "power level 0    sclk: %u vddc_index: %d\n",
+                          ps->sclk_low, ps->min_voltage);
+       else
+               seq_printf(m, "power level 1    sclk: %u vddc_index: %d\n",
+                          ps->sclk_high, ps->max_voltage);
+}
index b1142ed1c628cb585220ac9f1779a02161c6d764..cfbe9a43d97b4064022a0bcf36dfdeeecddbcb1b 100644 (file)
@@ -28,6 +28,7 @@
 #       define SPLL_SLEEP                                (1 << 1)
 #       define SPLL_REF_DIV(x)                           ((x) << 2)
 #       define SPLL_REF_DIV_MASK                         (7 << 2)
+#       define SPLL_REF_DIV_SHIFT                        2
 #       define SPLL_FB_DIV(x)                            ((x) << 5)
 #       define SPLL_FB_DIV_MASK                          (0xff << 2)
 #       define SPLL_FB_DIV_SHIFT                         2
 #       define SPLL_PULSENUM_MASK                        (3 << 14)
 #       define SPLL_SW_HILEN(x)                          ((x) << 16)
 #       define SPLL_SW_HILEN_MASK                        (0xf << 16)
+#       define SPLL_SW_HILEN_SHIFT                       16
 #       define SPLL_SW_LOLEN(x)                          ((x) << 20)
 #       define SPLL_SW_LOLEN_MASK                        (0xf << 20)
+#       define SPLL_SW_LOLEN_SHIFT                       20
 #       define SPLL_DIVEN                                (1 << 24)
 #       define SPLL_BYPASS_EN                            (1 << 25)
 #       define SPLL_CHG_STATUS                           (1 << 29)