tools/power/cpupower: Fix Pstate frequency reporting on AMD Family 1Ah CPUs
authorDhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
Tue, 30 Apr 2024 08:37:06 +0000 (14:07 +0530)
committerShuah Khan <skhan@linuxfoundation.org>
Tue, 28 May 2024 15:22:57 +0000 (09:22 -0600)
Update cpupower's P-State frequency calculation and reporting with AMD
Family 1Ah+ processors, when using the acpi-cpufreq driver. This is due
to a change in the PStateDef MSR layout in AMD Family 1Ah+.

Tested on 4th and 5th Gen AMD EPYC system

Signed-off-by: Ananth Narayan <Ananth.Narayan@amd.com>
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
tools/power/cpupower/utils/helpers/amd.c

index c519cc89c97f42a3849130aebdfcdfb14b44ebf6..0a56e22240fc8b8b026db7d72e0f5055cc420a1a 100644 (file)
@@ -41,6 +41,16 @@ union core_pstate {
                unsigned res1:31;
                unsigned en:1;
        } pstatedef;
+       /* since fam 1Ah: */
+       struct {
+               unsigned fid:12;
+               unsigned res1:2;
+               unsigned vid:8;
+               unsigned iddval:8;
+               unsigned idddiv:2;
+               unsigned res2:31;
+               unsigned en:1;
+       } pstatedef2;
        unsigned long long val;
 };
 
@@ -48,6 +58,10 @@ static int get_did(union core_pstate pstate)
 {
        int t;
 
+       /* Fam 1Ah onward do not use did */
+       if (cpupower_cpu_info.family >= 0x1A)
+               return 0;
+
        if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF)
                t = pstate.pstatedef.did;
        else if (cpupower_cpu_info.family == 0x12)
@@ -61,12 +75,18 @@ static int get_did(union core_pstate pstate)
 static int get_cof(union core_pstate pstate)
 {
        int t;
-       int fid, did, cof;
+       int fid, did, cof = 0;
 
        did = get_did(pstate);
        if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) {
-               fid = pstate.pstatedef.fid;
-               cof = 200 * fid / did;
+               if (cpupower_cpu_info.family >= 0x1A) {
+                       fid = pstate.pstatedef2.fid;
+                       if (fid > 0x0f)
+                               cof = (fid * 5);
+               } else {
+                       fid = pstate.pstatedef.fid;
+                       cof = 200 * fid / did;
+               }
        } else {
                t = 0x10;
                fid = pstate.pstate.fid;