[PATCH] drm/radeon/dpm: add debugfs support for RS780/RS880 (v2)

Anthoine Bourgeois anthoine.bourgeois at gmail.com
Wed Jul 17 14:23:13 PDT 2013


On Wed, Jul 17, 2013 at 08:54:33PM +0000, Deucher, Alexander wrote:
>Good catch, I screwed up the ref divider calculation.  How about the attached patch?

It works too. But here was my logic, tell me if I'm wrong:

The output frequency of the PLL is equal to the VCO frequency (FVCO)
divided by the post-scale counter (C).
Fout = FVCO / C
And VCO frequency is equal to feedback (M) times the reference frequency
(FREF).
FVCO = FREF x M
Where reference clock (FREF) is equal to the input clock (Fin) divided
by the pre-scale counter (N)
FREF = Fin / N
then
FVCO = Fin x M / N
and
Fout = (Fin x M) / (N x C) = FREF x M / C

where:
FVCO = VCO frequency
Fin = input frequency
Fout = output frequency
FREF = reference frequency (rdev->clock.spll.reference_freq in the code)
M = counter (multiplier), part of the clock feedback path (current_fb_div)
N = counter (divider), part of the clock reference path (ref_div)
C = post-scale counter (divider) (post_div)

No need to ref_div. Or reference_freq == Fin and the varname confuses me ?

In my test:
# cat /sys/kernel/debug/dri/0/radeon_pm_info
uvd    vclk: 0 dclk: 0
power level 0    sclk: 20000 vddc_index: 2

when my system is idle and sclk == 19690 and:
# cat /sys/kernel/debug/dri/0/radeon_pm_info
uvd    vclk: 0 dclk: 0
power level 1    sclk: 50000 vddc_index: 2

when I play supertuxkart with sclk == 49762.

Thanks for yesturday, I was in a wrong way,
Anthoine

>
>Alex
>
>> -----Original Message-----
>> From: Anthoine Bourgeois [mailto:anthoine.bourgeois at gmail.com]
>> Sent: Wednesday, July 17, 2013 4:43 PM
>> To: Deucher, Alexander; Koenig, Christian; Jerome Glisse; Anthoine
>> Bourgeois
>> Cc: dri-devel at lists.freedesktop.org
>> Subject: [PATCH] drm/radeon/dpm: add debugfs support for RS780/RS880
>> (v2)
>>
>> 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: fix sclk equation
>>
>> Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
>> Signed-off-by: Anthoine Bourgeois <anthoine.bourgeois at gmail.com>
>> ---
>>  drivers/gpu/drm/radeon/radeon_asic.c |  1 +
>>  drivers/gpu/drm/radeon/radeon_asic.h |  2 ++
>>  drivers/gpu/drm/radeon/rs780_dpm.c   | 23 +++++++++++++++++++++++
>>  drivers/gpu/drm/radeon/rs780d.h      |  3 +++
>>  4 files changed, 29 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon_asic.c
>> b/drivers/gpu/drm/radeon/radeon_asic.c
>> index fea997e..78bec1a 100644
>> --- a/drivers/gpu/drm/radeon/radeon_asic.c
>> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
>> @@ -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,
>> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h
>> b/drivers/gpu/drm/radeon/radeon_asic.h
>> index b04b578..ca18957 100644
>> --- a/drivers/gpu/drm/radeon/radeon_asic.h
>> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
>> @@ -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);
>> diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c
>> b/drivers/gpu/drm/radeon/rs780_dpm.c
>> index bef832a..7f128c2 100644
>> --- a/drivers/gpu/drm/radeon/rs780_dpm.c
>> +++ b/drivers/gpu/drm/radeon/rs780_dpm.c
>> @@ -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,25 @@ 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 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;
>> +
>> +	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);
>> +}
>> diff --git a/drivers/gpu/drm/radeon/rs780d.h
>> b/drivers/gpu/drm/radeon/rs780d.h
>> index b1142ed..cfbe9a4 100644
>> --- a/drivers/gpu/drm/radeon/rs780d.h
>> +++ b/drivers/gpu/drm/radeon/rs780d.h
>> @@ -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
>> @@ -36,8 +37,10 @@
>>  #       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)
>> --
>> 1.8.1.5
>>
>




More information about the dri-devel mailing list