]>
git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - tools/power/cpupower/utils/helpers/amd.c
1 #if defined(__i386__) || defined(__x86_64__)
9 #include "helpers/helpers.h"
11 #define MSR_AMD_PSTATE_STATUS 0xc0010063
12 #define MSR_AMD_PSTATE 0xc0010064
13 #define MSR_AMD_PSTATE_LIMIT 0xc0010061
38 unsigned long long val
;
41 static int get_did(int family
, union msr_pstate pstate
)
47 else if (family
== 0x17)
48 t
= pstate
.fam17h_bits
.did
;
55 static int get_cof(int family
, union msr_pstate pstate
)
60 did
= get_did(family
, pstate
);
62 fid
= pstate
.fam17h_bits
.fid
;
63 cof
= 200 * fid
/ did
;
66 fid
= pstate
.bits
.fid
;
69 cof
= (100 * (fid
+ t
)) >> did
;
75 * cpu -> the cpu that gets evaluated
76 * cpu_family -> The cpu's family (0x10, 0x12,...)
77 * boots_states -> how much boost states the machines support
80 * pstates -> a pointer to an array of size MAX_HW_PSTATES
81 * must be initialized with zeros.
82 * All available HW pstates (including boost states)
83 * no -> amount of pstates above array got filled up with
85 * returns zero on success, -1 on failure
87 int decode_pstates(unsigned int cpu
, unsigned int cpu_family
,
88 int boost_states
, unsigned long *pstates
, int *no
)
91 union msr_pstate pstate
;
92 unsigned long long val
;
94 /* Only read out frequencies from HW when CPU might be boostable
95 to keep the code as short and clean as possible.
96 Otherwise frequencies are exported via ACPI tables.
98 if (cpu_family
< 0x10 || cpu_family
== 0x14)
101 if (read_msr(cpu
, MSR_AMD_PSTATE_LIMIT
, &val
))
104 psmax
= (val
>> 4) & 0x7;
106 if (read_msr(cpu
, MSR_AMD_PSTATE_STATUS
, &val
))
111 pscur
+= boost_states
;
112 psmax
+= boost_states
;
113 for (i
= 0; i
<= psmax
; i
++) {
114 if (i
>= MAX_HW_PSTATES
) {
115 fprintf(stderr
, "HW pstates [%d] exceeding max [%d]\n",
116 psmax
, MAX_HW_PSTATES
);
119 if (read_msr(cpu
, MSR_AMD_PSTATE
+ i
, &pstate
.val
))
121 pstates
[i
] = get_cof(cpu_family
, pstate
);
127 int amd_pci_get_num_boost_states(int *active
, int *states
)
129 struct pci_access
*pci_acc
;
130 struct pci_dev
*device
;
133 *active
= *states
= 0;
135 device
= pci_slot_func_init(&pci_acc
, 0x18, 4);
140 val
= pci_read_byte(device
, 0x15c);
145 *states
= (val
>> 2) & 7;
147 pci_cleanup(pci_acc
);
150 #endif /* defined(__i386__) || defined(__x86_64__) */