1
2
3
4
5
6
7
8
9
10#include <linux/kernel.h>
11#include <asm/processor.h>
12#include <asm/setup.h>
13#include <asm/apic.h>
14#include <asm/param.h>
15
16#define MAX_NUM_FREQS 9
17
18
19
20
21
22
23
24
25struct freq_desc {
26 u8 x86_family;
27 u8 x86_model;
28 u8 msr_plat;
29 u32 freqs[MAX_NUM_FREQS];
30};
31
32static struct freq_desc freq_desc_tables[] = {
33
34 { 6, 0x27, 0, { 0, 0, 0, 0, 0, 99840, 0, 83200 } },
35
36 { 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200 } },
37
38 { 6, 0x4a, 1, { 0, 100000, 133300, 0, 0, 0, 0, 0 } },
39
40 { 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0 } },
41
42 { 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0 } },
43
44 { 6, 0x4c, 1, { 83300, 100000, 133300, 116700,
45 80000, 93300, 90000, 88900, 87500 } },
46};
47
48static int match_cpu(u8 family, u8 model)
49{
50 int i;
51
52 for (i = 0; i < ARRAY_SIZE(freq_desc_tables); i++) {
53 if ((family == freq_desc_tables[i].x86_family) &&
54 (model == freq_desc_tables[i].x86_model))
55 return i;
56 }
57
58 return -1;
59}
60
61
62#define id_to_freq(cpu_index, freq_id) \
63 (freq_desc_tables[cpu_index].freqs[freq_id])
64
65
66
67
68
69
70
71unsigned long cpu_khz_from_msr(void)
72{
73 u32 lo, hi, ratio, freq_id, freq;
74 unsigned long res;
75 int cpu_index;
76
77 if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
78 return 0;
79
80 cpu_index = match_cpu(boot_cpu_data.x86, boot_cpu_data.x86_model);
81 if (cpu_index < 0)
82 return 0;
83
84 if (freq_desc_tables[cpu_index].msr_plat) {
85 rdmsr(MSR_PLATFORM_INFO, lo, hi);
86 ratio = (lo >> 8) & 0xff;
87 } else {
88 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
89 ratio = (hi >> 8) & 0x1f;
90 }
91
92
93 rdmsr(MSR_FSB_FREQ, lo, hi);
94 freq_id = lo & 0x7;
95 freq = id_to_freq(cpu_index, freq_id);
96
97
98 res = freq * ratio;
99
100#ifdef CONFIG_X86_LOCAL_APIC
101 lapic_timer_frequency = (freq * 1000) / HZ;
102#endif
103
104
105
106
107
108
109
110 setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
111
112
113
114
115
116
117
118
119
120 setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
121
122 return res;
123}
124