mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-13 23:34:05 +08:00
[CPUFREQ] powernow-k8: determine exact CPU frequency for HW Pstates
Slightly modified by trenn@suse.de -> only do this on fam 10h and fam 11h. Currently powernow-k8 determines CPU frequency from ACPI PSS objects, but according to AMD family 11h BKDG this frequency is just a rounded value: "CoreFreq (MHz) = The CPU COF specified by MSRC001_00[6B:64][CpuFid] rounded to the nearest 100 Mhz." As a consequnce powernow-k8 reports wrong CPU frequency on some systems, e.g. on Turion X2 Ultra: powernow-k8: Found 1 AMD Turion(tm)X2 Ultra DualCore Mobile ZM-82 processors (2 cpu cores) (version 2.20.00) powernow-k8: 0 : pstate 0 (2200 MHz) powernow-k8: 1 : pstate 1 (1100 MHz) powernow-k8: 2 : pstate 2 (600 MHz) But this is wrong as frequency for Pstate2 is 550 MHz. x86info reports it correctly: #x86info -a |grep Pstate ... Pstate-0: fid=e, did=0, vid=24 (2200MHz) Pstate-1: fid=e, did=1, vid=30 (1100MHz) Pstate-2: fid=e, did=2, vid=3c (550MHz) (current) Solution is to determine the frequency directly from Pstate MSRs instead of using rounded values from ACPI table. Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com> Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Dave Jones <davej@redhat.com>
This commit is contained in:
parent
df1829770d
commit
ca446d0635
@ -649,6 +649,20 @@ static void print_basics(struct powernow_k8_data *data)
|
||||
data->batps);
|
||||
}
|
||||
|
||||
static u32 freq_from_fid_did(u32 fid, u32 did)
|
||||
{
|
||||
u32 mhz = 0;
|
||||
|
||||
if (boot_cpu_data.x86 == 0x10)
|
||||
mhz = (100 * (fid + 0x10)) >> did;
|
||||
else if (boot_cpu_data.x86 == 0x11)
|
||||
mhz = (100 * (fid + 8)) >> did;
|
||||
else
|
||||
BUG();
|
||||
|
||||
return mhz * 1000;
|
||||
}
|
||||
|
||||
static int fill_powernow_table(struct powernow_k8_data *data,
|
||||
struct pst_s *pst, u8 maxvid)
|
||||
{
|
||||
@ -923,8 +937,13 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data,
|
||||
|
||||
powernow_table[i].index = index;
|
||||
|
||||
powernow_table[i].frequency =
|
||||
data->acpi_data.states[i].core_frequency * 1000;
|
||||
/* Frequency may be rounded for these */
|
||||
if (boot_cpu_data.x86 == 0x10 || boot_cpu_data.x86 == 0x11) {
|
||||
powernow_table[i].frequency =
|
||||
freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
|
||||
} else
|
||||
powernow_table[i].frequency =
|
||||
data->acpi_data.states[i].core_frequency * 1000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user