cpupower: Add support for new AMD family 0x17
authorSherry Hurwitz <sherry.hurwitz@amd.com>
Tue, 20 Jun 2017 07:08:42 +0000 (02:08 -0500)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Jun 2017 23:43:22 +0000 (01:43 +0200)
Add support for new AMD family 0x17
- Add bit field changes to the msr_pstate structure
- Add the new formula for the  calculation of cof
- Changed method to access to CpbDis

Signed-off-by: Sherry Hurwitz <sherry.hurwitz@amd.com>
Acked-by: Thomas Renninger <trenn@suse.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
tools/power/cpupower/utils/helpers/amd.c
tools/power/cpupower/utils/helpers/helpers.h
tools/power/cpupower/utils/helpers/misc.c

index 6437ef39aeea61fe592d11d5a022730a8b46a6dd..5fd5c5b8c7b8c1fc29597490abc827898f2fcb77 100644 (file)
@@ -26,6 +26,15 @@ union msr_pstate {
                unsigned res3:21;
                unsigned en:1;
        } bits;
+       struct {
+               unsigned fid:8;
+               unsigned did:6;
+               unsigned vid:8;
+               unsigned iddval:8;
+               unsigned idddiv:2;
+               unsigned res1:30;
+               unsigned en:1;
+       } fam17h_bits;
        unsigned long long val;
 };
 
@@ -35,6 +44,8 @@ static int get_did(int family, union msr_pstate pstate)
 
        if (family == 0x12)
                t = pstate.val & 0xf;
+       else if (family == 0x17)
+               t = pstate.fam17h_bits.did;
        else
                t = pstate.bits.did;
 
@@ -44,16 +55,20 @@ static int get_did(int family, union msr_pstate pstate)
 static int get_cof(int family, union msr_pstate pstate)
 {
        int t;
-       int fid, did;
+       int fid, did, cof;
 
        did = get_did(family, pstate);
-
-       t = 0x10;
-       fid = pstate.bits.fid;
-       if (family == 0x11)
-               t = 0x8;
-
-       return (100 * (fid + t)) >> did;
+       if (family == 0x17) {
+               fid = pstate.fam17h_bits.fid;
+               cof = 200 * fid / did;
+       } else {
+               t = 0x10;
+               fid = pstate.bits.fid;
+               if (family == 0x11)
+                       t = 0x8;
+               cof = (100 * (fid + t)) >> did;
+       }
+       return cof;
 }
 
 /* Needs:
index afb66f80554ecda25e139ddacb74d3a6443e8322..799a18be60aa4628b2dbaa47e8484a802769b558 100644 (file)
@@ -70,6 +70,8 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
 #define CPUPOWER_CAP_IS_SNB            0x00000020
 #define CPUPOWER_CAP_INTEL_IDA         0x00000040
 
+#define CPUPOWER_AMD_CPBDIS            0x02000000
+
 #define MAX_HW_PSTATES 10
 
 struct cpupower_cpu_info {
index 6952a6abd1e5900c84e690ab3ed99bbd71d9114e..601d719d4e60dfba6f4d104edbf4568691143cd5 100644 (file)
@@ -2,11 +2,14 @@
 
 #include "helpers/helpers.h"
 
+#define MSR_AMD_HWCR   0xc0010015
+
 int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
                        int *states)
 {
        struct cpupower_cpu_info cpu_info;
        int ret;
+       unsigned long long val;
 
        *support = *active = *states = 0;
 
@@ -16,9 +19,22 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
 
        if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) {
                *support = 1;
-               ret = amd_pci_get_num_boost_states(active, states);
-               if (ret)
-                       return ret;
+
+               /* AMD Family 0x17 does not utilize PCI D18F4 like prior
+                * families and has no fixed discrete boost states but
+                * has Hardware determined variable increments instead.
+                */
+
+               if (cpu_info.family == 0x17) {
+                       if (!read_msr(cpu, MSR_AMD_HWCR, &val)) {
+                               if (!(val & CPUPOWER_AMD_CPBDIS))
+                                       *active = 1;
+                       }
+               } else {
+                       ret = amd_pci_get_num_boost_states(active, states);
+                       if (ret)
+                               return ret;
+               }
        } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA)
                *support = *active = 1;
        return 0;