Commit a51d1856 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge tag 'linux-cpupower-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux

Pull cpupower utility update for v5.12-rc1 from Shuah Khan:

"This cpupower update for Linux 5.12-rc1 consists of:

 - Updates to the cpupower command to add support for AMD family 0x19
   and cleanup the code to remove many of the family checks to make
   future family updates easier.

 - Adding Makefile dependencies for install targets to allow building
   cpupower in parallel rather than serially."

* tag 'linux-cpupower-5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux:
  cpupower: Add cpuid cap flag for MSR_AMD_HWCR support
  cpupower: Remove family arg to decode_pstates()
  cpupower: Condense pstate enabled bit checks in decode_pstates()
  cpupower: Update family checks when decoding HW pstates
  cpupower: Remove unused pscur variable.
  cpupower: Add CPUPOWER_CAP_AMD_HW_PSTATE cpuid caps flag
  cpupower: Correct macro name for CPB caps flag
  cpupower: Update msr_pstate union struct naming
  cpupower: add Makefile dependencies for install targets
parents 92bf2261 3a3ecfdb
......@@ -270,14 +270,14 @@ clean:
$(MAKE) -C bench O=$(OUTPUT) clean
install-lib:
install-lib: libcpupower
$(INSTALL) -d $(DESTDIR)${libdir}
$(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
$(INSTALL) -d $(DESTDIR)${includedir}
$(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
$(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h
install-tools:
install-tools: $(OUTPUT)cpupower
$(INSTALL) -d $(DESTDIR)${bindir}
$(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
$(INSTALL) -d $(DESTDIR)${bash_completion_dir}
......@@ -293,14 +293,14 @@ install-man:
$(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1
$(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1
install-gmo:
install-gmo: create-gmo
$(INSTALL) -d $(DESTDIR)${localedir}
for HLANG in $(LANGUAGES); do \
echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
done;
install-bench:
install-bench: compile-bench
@#DESTDIR must be set from outside to survive
@sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install
......
......@@ -27,7 +27,7 @@ $(OUTPUT)cpufreq-bench: $(OBJS)
all: $(OUTPUT)cpufreq-bench
install:
install: $(OUTPUT)cpufreq-bench
mkdir -p $(DESTDIR)/$(sbindir)
mkdir -p $(DESTDIR)/$(bindir)
mkdir -p $(DESTDIR)/$(docdir)
......
......@@ -186,8 +186,7 @@ static int get_boost_mode_x86(unsigned int cpu)
if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
cpupower_cpu_info.family >= 0x10) ||
cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
pstates, &pstate_no);
ret = decode_pstates(cpu, b_states, pstates, &pstate_no);
if (ret)
return ret;
......
......@@ -13,7 +13,8 @@
#define MSR_AMD_PSTATE 0xc0010064
#define MSR_AMD_PSTATE_LIMIT 0xc0010061
union msr_pstate {
union core_pstate {
/* pre fam 17h: */
struct {
unsigned fid:6;
unsigned did:3;
......@@ -26,7 +27,8 @@ union msr_pstate {
unsigned idddiv:2;
unsigned res3:21;
unsigned en:1;
} bits;
} pstate;
/* since fam 17h: */
struct {
unsigned fid:8;
unsigned did:6;
......@@ -35,37 +37,37 @@ union msr_pstate {
unsigned idddiv:2;
unsigned res1:31;
unsigned en:1;
} fam17h_bits;
} pstatedef;
unsigned long long val;
};
static int get_did(int family, union msr_pstate pstate)
static int get_did(union core_pstate pstate)
{
int t;
if (family == 0x12)
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF)
t = pstate.pstatedef.did;
else if (cpupower_cpu_info.family == 0x12)
t = pstate.val & 0xf;
else if (family == 0x17 || family == 0x18)
t = pstate.fam17h_bits.did;
else
t = pstate.bits.did;
t = pstate.pstate.did;
return t;
}
static int get_cof(int family, union msr_pstate pstate)
static int get_cof(union core_pstate pstate)
{
int t;
int fid, did, cof;
did = get_did(family, pstate);
if (family == 0x17 || family == 0x18) {
fid = pstate.fam17h_bits.fid;
did = get_did(pstate);
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) {
fid = pstate.pstatedef.fid;
cof = 200 * fid / did;
} else {
t = 0x10;
fid = pstate.bits.fid;
if (family == 0x11)
fid = pstate.pstate.fid;
if (cpupower_cpu_info.family == 0x11)
t = 0x8;
cof = (100 * (fid + t)) >> did;
}
......@@ -74,8 +76,7 @@ static int get_cof(int family, union msr_pstate pstate)
/* Needs:
* cpu -> the cpu that gets evaluated
* cpu_family -> The cpu's family (0x10, 0x12,...)
* boots_states -> how much boost states the machines support
* boost_states -> how much boost states the machines support
*
* Fills up:
* pstates -> a pointer to an array of size MAX_HW_PSTATES
......@@ -85,31 +86,23 @@ static int get_cof(int family, union msr_pstate pstate)
*
* returns zero on success, -1 on failure
*/
int decode_pstates(unsigned int cpu, unsigned int cpu_family,
int boost_states, unsigned long *pstates, int *no)
int decode_pstates(unsigned int cpu, int boost_states,
unsigned long *pstates, int *no)
{
int i, psmax, pscur;
union msr_pstate pstate;
int i, psmax;
union core_pstate pstate;
unsigned long long val;
/* Only read out frequencies from HW when CPU might be boostable
to keep the code as short and clean as possible.
Otherwise frequencies are exported via ACPI tables.
/* Only read out frequencies from HW if HW Pstate is supported,
* otherwise frequencies are exported via ACPI tables.
*/
if (cpu_family < 0x10 || cpu_family == 0x14)
if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_HW_PSTATE))
return -1;
if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val))
return -1;
psmax = (val >> 4) & 0x7;
if (read_msr(cpu, MSR_AMD_PSTATE_STATUS, &val))
return -1;
pscur = val & 0x7;
pscur += boost_states;
psmax += boost_states;
for (i = 0; i <= psmax; i++) {
if (i >= MAX_HW_PSTATES) {
......@@ -119,12 +112,12 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family,
}
if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val))
return -1;
if ((cpu_family == 0x17) && (!pstate.fam17h_bits.en))
continue;
else if (!pstate.bits.en)
/* The enabled bit (bit 63) is common for all families */
if (!pstate.pstatedef.en)
continue;
pstates[i] = get_cof(cpu_family, pstate);
pstates[i] = get_cof(pstate);
}
*no = i;
return 0;
......
......@@ -128,9 +128,23 @@ int get_cpu_info(struct cpupower_cpu_info *cpu_info)
/* AMD or Hygon Boost state enable/disable register */
if (cpu_info->vendor == X86_VENDOR_AMD ||
cpu_info->vendor == X86_VENDOR_HYGON) {
if (ext_cpuid_level >= 0x80000007 &&
(cpuid_edx(0x80000007) & (1 << 9)))
cpu_info->caps |= CPUPOWER_CAP_AMD_CBP;
if (ext_cpuid_level >= 0x80000007) {
if (cpuid_edx(0x80000007) & (1 << 9)) {
cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;
if (cpu_info->family >= 0x17)
cpu_info->caps |= CPUPOWER_CAP_AMD_CPB_MSR;
}
if ((cpuid_edx(0x80000007) & (1 << 7)) &&
cpu_info->family != 0x14) {
/* HW pstate was not implemented in family 0x14 */
cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE;
if (cpu_info->family >= 0x17)
cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATEDEF;
}
}
if (ext_cpuid_level >= 0x80000008 &&
cpuid_ebx(0x80000008) & (1 << 4))
......
......@@ -64,12 +64,15 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
#define CPUPOWER_CAP_INV_TSC 0x00000001
#define CPUPOWER_CAP_APERF 0x00000002
#define CPUPOWER_CAP_AMD_CBP 0x00000004
#define CPUPOWER_CAP_AMD_CPB 0x00000004
#define CPUPOWER_CAP_PERF_BIAS 0x00000008
#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010
#define CPUPOWER_CAP_IS_SNB 0x00000020
#define CPUPOWER_CAP_INTEL_IDA 0x00000040
#define CPUPOWER_CAP_AMD_RDPRU 0x00000080
#define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100
#define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200
#define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400
#define CPUPOWER_AMD_CPBDIS 0x02000000
......@@ -125,8 +128,8 @@ extern struct pci_dev *pci_slot_func_init(struct pci_access **pacc,
/* AMD HW pstate decoding **************************/
extern int decode_pstates(unsigned int cpu, unsigned int cpu_family,
int boost_states, unsigned long *pstates, int *no);
extern int decode_pstates(unsigned int cpu, int boost_states,
unsigned long *pstates, int *no);
/* AMD HW pstate decoding **************************/
......@@ -143,9 +146,8 @@ unsigned int cpuid_edx(unsigned int op);
/* cpuid and cpuinfo helpers **************************/
/* X86 ONLY ********************************************/
#else
static inline int decode_pstates(unsigned int cpu, unsigned int cpu_family,
int boost_states, unsigned long *pstates,
int *no)
static inline int decode_pstates(unsigned int cpu, int boost_states,
unsigned long *pstates, int *no)
{ return -1; };
static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val)
......
......@@ -16,17 +16,12 @@
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;
ret = get_cpu_info(&cpu_info);
if (ret)
return ret;
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) {
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB) {
*support = 1;
/* AMD Family 0x17 does not utilize PCI D18F4 like prior
......@@ -34,7 +29,7 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
* has Hardware determined variable increments instead.
*/
if (cpu_info.family == 0x17 || cpu_info.family == 0x18) {
if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB_MSR) {
if (!read_msr(cpu, MSR_AMD_HWCR, &val)) {
if (!(val & CPUPOWER_AMD_CPBDIS))
*active = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment