drm/radeon/dpm: add debugfs support for RS780/RS880 (v2)
Subsystems (2)
PATCH 1/1 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
---
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(+)
drivers/gpu/drm/radeon/radeon_asic.c +0 -0
@@ -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,drivers/gpu/drm/radeon/radeon_asic.h +0 -0
@@ -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);
drivers/gpu/drm/radeon/rs780_dpm.c +0 -0
@@ -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);
+}
drivers/gpu/drm/radeon/rs780d.h +0 -0
@@ -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)
Signature · 1 line
1.8.1.5
Deucher, Alexander
maintainerGood catch, I screwed up the ref divider calculation. How about the attached patch?
Alex
Quoted 127 lines
-----Original Message-----
From: Anthoine Bourgeois [mailto:[email protected]]
Sent: Wednesday, July 17, 2013 4:43 PM
To: Deucher, Alexander; Koenig, Christian; Jerome Glisse; Anthoine Bourgeois
Cc: [email protected]
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 <[email protected]>Signed-off-by Anthoine Bourgeois <[email protected]>--- 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(+)drivers/gpu/drm/radeon/radeon_asic.c +1
-0@@ -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 = {drivers/gpu/drm/radeon/radeon_asic.c +0
-0.pre_page_flip = &rs600_pre_page_flip,drivers/gpu/drm/radeon/radeon_asic.h +2
-0@@ -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 */
intr600_uvd_init(struct radeon_device *rdev);drivers/gpu/drm/radeon/rs780_dpm.c +3
-0@@ -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,drivers/gpu/drm/radeon/rs780_dpm.c +5
-0+ 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;drivers/gpu/drm/radeon/rs780_dpm.c +2
-0+u32 func_cntl =RREG32 (CG_SPLL_FUNC_CNTL ); + u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >>
SPLL_SW_HILEN_SHIFT) + 1 +drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ ((func_cntl & SPLL_SW_LOLEN_MASK) >>
SPLL_SW_LOLEN_SHIFT) + 1;drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
post_div;drivers/gpu/drm/radeon/rs780_dpm.c +11
-0+ +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); +}drivers/gpu/drm/radeon/rs780d.h +3
-1@@ -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) --
Quoted 2 lines
1.8.1.5
From 444bddc4b9b3313a562cd3ba40f780fb82570f7d Mon Sep 17 00:00:00 2001
From: Alex Deucher <[email protected]>
Date: Tue, 2 Jul 2013 13:05:23 -0400
Subject: [PATCH] drm/radeon/dpm: add debugfs support for RS780/RS880 (v3)
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
--- drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 2 ++ drivers/gpu/drm/radeon/rs780_dpm.c | 25 +++++++++++++++++++++++++ drivers/gpu/drm/radeon/rs780d.h | 3 +++ 4 files changed, 31 insertions(+), 0 deletions(-)
drivers/gpu/drm/radeon/radeon_asic.c +1 -0
@@ -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,
drivers/gpu/drm/radeon/radeon_asic.h +2 -0
@@ -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);
drivers/gpu/drm/radeon/rs780_dpm.c +25 -0
@@ -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); +}
drivers/gpu/drm/radeon/rs780d.h +3 -0
@@ -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)
Signature · 1 line
1.7.7.5
_______________________________________________
dri-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/dri-devel
Quoted 1 line · Alexander
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
Quoted 133 lines
Alex
Quoted 129 lines
-----Original Message-----
From: Anthoine Bourgeois [mailto:[email protected]]
Sent: Wednesday, July 17, 2013 4:43 PM
To: Deucher, Alexander; Koenig, Christian; Jerome Glisse; Anthoine Bourgeois
Cc: [email protected]
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 <[email protected]>Signed-off-by Anthoine Bourgeois <[email protected]>--- 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(+)drivers/gpu/drm/radeon/radeon_asic.c +1
-0@@ -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 = {drivers/gpu/drm/radeon/radeon_asic.c +0
-0.pre_page_flip = &rs600_pre_page_flip,drivers/gpu/drm/radeon/radeon_asic.h +2
-0@@ -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 */
intr600_uvd_init(struct radeon_device *rdev);drivers/gpu/drm/radeon/rs780_dpm.c +3
-0@@ -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,drivers/gpu/drm/radeon/rs780_dpm.c +5
-0+ 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;drivers/gpu/drm/radeon/rs780_dpm.c +2
-0+u32 func_cntl =RREG32 (CG_SPLL_FUNC_CNTL ); + u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >>
SPLL_SW_HILEN_SHIFT) + 1 +drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ ((func_cntl & SPLL_SW_LOLEN_MASK) >>
SPLL_SW_LOLEN_SHIFT) + 1;drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
post_div;drivers/gpu/drm/radeon/rs780_dpm.c +11
-0+ +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); +}drivers/gpu/drm/radeon/rs780d.h +3
-1@@ -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
Deucher, Alexander
maintainerQuoted 8 lines
-----Original Message-----
From: Anthoine Bourgeois [mailto:[email protected]]
Sent: Wednesday, July 17, 2013 5:23 PM
To: Deucher, Alexander; Koenig, Christian; Jerome Glisse
Cc: [email protected]
Subject: Re: [PATCH] drm/radeon/dpm: add debugfs support for RS780/RS880 (v2)
Quoted 5 lines
Quoted 1 line · Alexander
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:
Ok.
Quoted 24 lines
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 / Cwhere:
FVCO = VCO frequency
Fin = input frequency
Fout = output frequency
FREF = reference frequency (rdev->clock.spll.reference_freqin 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)
Quoted 2 lines
No need to
ref_div. Orreference_freq== Fin and the varname confuses me ?
I'm not sure exactly how the PLL is set up. The calculation looks like so:
Output frequency = (reference freq * feedback divider) / (reference divider * post divider);
I think FVCO = (FREF * M) / N to use your terms, but I'm not really a hw expert.
Alex
Quoted 154 lines
In my test:
# cat /sys/kernel/debug/dri/0/radeon_pm_info uvd vclk: 0 dclk: 0 power level 0 sclk: 20000 vddc_index: 2when 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: 2when I play supertuxkart with sclk == 49762.
Thanks for yesturday, I was in a wrong way,
AnthoineQuoted 10 lines
Alex
Quoted 7 lines
-----Original Message-----
From: Anthoine Bourgeois [mailto:[email protected]]
Sent: Wednesday, July 17, 2013 4:43 PM
To: Deucher, Alexander; Koenig, Christian; Jerome Glisse; Anthoine Bourgeois
Cc: [email protected]
Subject: [PATCH] drm/radeon/dpm: add debugfs support forRS780/RS880
Quoted 9 lines
Quoted 9 lines
(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.
Quoted 8 lines
Quoted 8 lines
v2: fix sclk equation
Signed-off-by Alex Deucher <[email protected]>Signed-off-by Anthoine Bourgeois <[email protected]>--- drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 2 ++ drivers/gpu/drm/radeon/rs780_dpm.c | 23+++++++++++++++++++++++
Quoted 15 lines
Quoted 15 lines
drivers/gpu/drm/radeon/rs780d.h | 3 +++ 4 files changed, 29 insertions(+)drivers/gpu/drm/radeon/radeon_asic.c +1
-0@@ -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, },Quoted 8 lines
drivers/gpu/drm/radeon/radeon_asic.h u32 rs780_dpm_get_sclk(struct radeon_device
Quoted 8 lines
drivers/gpu/drm/radeon/radeon_asic.c +0
-0.pflip = {drivers/gpu/drm/radeon/radeon_asic.c +0
-0.pre_page_flip = &rs600_pre_page_flip,drivers/gpu/drm/radeon/radeon_asic.h +0
-0@@ -433,6 +433,8 @@ u32 rs780_dpm_get_sclk(struct radeon_device*rdev,
Quoted 83 lines
Quoted 82 lines
drivers/gpu/drm/radeon/radeon_asic.h +2
-0bool 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 */
intr600_uvd_init(struct radeon_device *rdev);drivers/gpu/drm/radeon/rs780_dpm.c +3
-0@@ -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,drivers/gpu/drm/radeon/rs780_dpm.c +5
-0+ 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;drivers/gpu/drm/radeon/rs780_dpm.c +2
-0+u32 func_cntl =RREG32 (CG_SPLL_FUNC_CNTL ); + u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >>
SPLL_SW_HILEN_SHIFT) + 1 +drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ ((func_cntl & SPLL_SW_LOLEN_MASK) >>
SPLL_SW_LOLEN_SHIFT) + 1;drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
post_div;drivers/gpu/drm/radeon/rs780_dpm.c +11
-0+ +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); +}drivers/gpu/drm/radeon/rs780d.h +3
-1@@ -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
Quoted 40 lines · Alexander
Quoted 8 lines
-----Original Message-----
From: Anthoine Bourgeois [mailto:[email protected]]
Sent: Wednesday, July 17, 2013 5:23 PM
To: Deucher, Alexander; Koenig, Christian; Jerome Glisse
Cc: [email protected]
Subject: Re: [PATCH] drm/radeon/dpm: add debugfs support for RS780/RS880 (v2)Quoted 5 lines
Quoted 1 line · Alexander
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:
Ok.
Quoted 24 lines
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 / Cwhere:
FVCO = VCO frequency
Fin = input frequency
Fout = output frequency
FREF = reference frequency (rdev->clock.spll.reference_freqin 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)
Quoted 8 lines
Quoted 2 lines
No need to
ref_div. Orreference_freq== Fin and the varname confuses me ?I'm not sure exactly how the PLL is set up. The calculation looks like so:
Output frequency = (reference freq * feedback divider) / (reference divider * post divider);
I think FVCO = (FREF * M) / N to use your terms, but I'm not really a hw expert.
Neither me. I trust you, then :
on v3.
Anthoine
Quoted 159 lines
Alex
Quoted 154 lines
In my test:
# cat /sys/kernel/debug/dri/0/radeon_pm_info uvd vclk: 0 dclk: 0 power level 0 sclk: 20000 vddc_index: 2when 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: 2when I play supertuxkart with sclk == 49762.
Thanks for yesturday, I was in a wrong way,
AnthoineQuoted 10 lines
Alex
Quoted 7 lines
-----Original Message-----
From: Anthoine Bourgeois [mailto:[email protected]]
Sent: Wednesday, July 17, 2013 4:43 PM
To: Deucher, Alexander; Koenig, Christian; Jerome Glisse; Anthoine Bourgeois
Cc: [email protected]
Subject: [PATCH] drm/radeon/dpm: add debugfs support forRS780/RS880
Quoted 9 lines
Quoted 9 lines
(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.
Quoted 8 lines
Quoted 8 lines
v2: fix sclk equation
Signed-off-by Alex Deucher <[email protected]>Signed-off-by Anthoine Bourgeois <[email protected]>--- drivers/gpu/drm/radeon/radeon_asic.c | 1 + drivers/gpu/drm/radeon/radeon_asic.h | 2 ++ drivers/gpu/drm/radeon/rs780_dpm.c | 23+++++++++++++++++++++++
Quoted 15 lines
Quoted 15 lines
drivers/gpu/drm/radeon/rs780d.h | 3 +++ 4 files changed, 29 insertions(+)drivers/gpu/drm/radeon/radeon_asic.c +1
-0@@ -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, },Quoted 8 lines
drivers/gpu/drm/radeon/radeon_asic.h u32 rs780_dpm_get_sclk(struct radeon_device
Quoted 8 lines
drivers/gpu/drm/radeon/radeon_asic.c +0
-0.pflip = {drivers/gpu/drm/radeon/radeon_asic.c +0
-0.pre_page_flip = &rs600_pre_page_flip,drivers/gpu/drm/radeon/radeon_asic.h +0
-0@@ -433,6 +433,8 @@ u32 rs780_dpm_get_sclk(struct radeon_device*rdev,
Quoted 83 lines
Quoted 82 lines
drivers/gpu/drm/radeon/radeon_asic.h +2
-0bool 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 */
intr600_uvd_init(struct radeon_device *rdev);drivers/gpu/drm/radeon/rs780_dpm.c +3
-0@@ -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,drivers/gpu/drm/radeon/rs780_dpm.c +5
-0+ 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;drivers/gpu/drm/radeon/rs780_dpm.c +2
-0+u32 func_cntl =RREG32 (CG_SPLL_FUNC_CNTL ); + u32 post_div = ((func_cntl & SPLL_SW_HILEN_MASK) >>
SPLL_SW_HILEN_SHIFT) + 1 +drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ ((func_cntl & SPLL_SW_LOLEN_MASK) >>
SPLL_SW_LOLEN_SHIFT) + 1;drivers/gpu/drm/radeon/rs780_dpm.c +1
-0+ u32 sclk = (rdev->clock.spll.reference_freq * current_fb_div) /
post_div;drivers/gpu/drm/radeon/rs780_dpm.c +11
-0+ +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); +}drivers/gpu/drm/radeon/rs780d.h +3
-1@@ -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