1
2
3
4
5
6
7
8
9#include <common.h>
10#include <dm.h>
11#include <malloc.h>
12#include <timer.h>
13#include <asm/cpu.h>
14#include <asm/io.h>
15#include <asm/i8254.h>
16#include <asm/ibmpc.h>
17#include <asm/msr.h>
18#include <asm/u-boot-x86.h>
19
20#define MAX_NUM_FREQS 9
21
22#define INTEL_FAM6_SKYLAKE_MOBILE 0x4E
23#define INTEL_FAM6_ATOM_GOLDMONT 0x5C
24#define INTEL_FAM6_SKYLAKE_DESKTOP 0x5E
25#define INTEL_FAM6_ATOM_GOLDMONT_X 0x5F
26#define INTEL_FAM6_KABYLAKE_MOBILE 0x8E
27#define INTEL_FAM6_KABYLAKE_DESKTOP 0x9E
28
29DECLARE_GLOBAL_DATA_PTR;
30
31
32
33
34
35static unsigned long native_calibrate_tsc(void)
36{
37 struct cpuid_result tsc_info;
38 unsigned int crystal_freq;
39
40 if (gd->arch.x86_vendor != X86_VENDOR_INTEL)
41 return 0;
42
43 if (cpuid_eax(0) < 0x15)
44 return 0;
45
46 tsc_info = cpuid(0x15);
47
48 if (tsc_info.ebx == 0 || tsc_info.eax == 0)
49 return 0;
50
51 crystal_freq = tsc_info.ecx / 1000;
52
53 if (!crystal_freq) {
54 switch (gd->arch.x86_model) {
55 case INTEL_FAM6_SKYLAKE_MOBILE:
56 case INTEL_FAM6_SKYLAKE_DESKTOP:
57 case INTEL_FAM6_KABYLAKE_MOBILE:
58 case INTEL_FAM6_KABYLAKE_DESKTOP:
59 crystal_freq = 24000;
60 break;
61 case INTEL_FAM6_ATOM_GOLDMONT_X:
62 crystal_freq = 25000;
63 break;
64 case INTEL_FAM6_ATOM_GOLDMONT:
65 crystal_freq = 19200;
66 break;
67 default:
68 return 0;
69 }
70 }
71
72 return (crystal_freq * tsc_info.ebx / tsc_info.eax) / 1000;
73}
74
75static unsigned long cpu_mhz_from_cpuid(void)
76{
77 if (gd->arch.x86_vendor != X86_VENDOR_INTEL)
78 return 0;
79
80 if (cpuid_eax(0) < 0x16)
81 return 0;
82
83 return cpuid_eax(0x16);
84}
85
86
87
88
89
90
91
92
93
94struct freq_desc {
95 u8 x86_family;
96 u8 x86_model;
97
98 u8 msr_plat;
99 u32 freqs[MAX_NUM_FREQS];
100};
101
102static struct freq_desc freq_desc_tables[] = {
103
104 { 6, 0x27, 0, { 0, 0, 0, 0, 0, 99840, 0, 83200, 0 } },
105
106 { 6, 0x35, 0, { 0, 133200, 0, 0, 0, 99840, 0, 83200, 0 } },
107
108 { 6, 0x4a, 1, { 0, 100000, 133300, 0, 0, 0, 0, 0, 0 } },
109
110 { 6, 0x37, 1, { 83300, 100000, 133300, 116700, 80000, 0, 0, 0, 0 } },
111
112 { 6, 0x5a, 1, { 83300, 100000, 133300, 100000, 0, 0, 0, 0, 0 } },
113
114 { 6, 0x4c, 1, { 83300, 100000, 133300, 116700,
115 80000, 93300, 90000, 88900, 87500 } },
116
117 { 6, 0x3a, 2, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
118};
119
120static int match_cpu(u8 family, u8 model)
121{
122 int i;
123
124 for (i = 0; i < ARRAY_SIZE(freq_desc_tables); i++) {
125 if ((family == freq_desc_tables[i].x86_family) &&
126 (model == freq_desc_tables[i].x86_model))
127 return i;
128 }
129
130 return -1;
131}
132
133
134#define id_to_freq(cpu_index, freq_id) \
135 (freq_desc_tables[cpu_index].freqs[freq_id])
136
137
138
139
140
141
142
143
144
145
146
147static unsigned long __maybe_unused cpu_mhz_from_msr(void)
148{
149 u32 lo, hi, ratio, freq_id, freq;
150 unsigned long res;
151 int cpu_index;
152
153 if (gd->arch.x86_vendor != X86_VENDOR_INTEL)
154 return 0;
155
156 cpu_index = match_cpu(gd->arch.x86, gd->arch.x86_model);
157 if (cpu_index < 0)
158 return 0;
159
160 if (freq_desc_tables[cpu_index].msr_plat) {
161 rdmsr(MSR_PLATFORM_INFO, lo, hi);
162 ratio = (lo >> 8) & 0xff;
163 } else {
164 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
165 ratio = (hi >> 8) & 0x1f;
166 }
167 debug("Maximum core-clock to bus-clock ratio: 0x%x\n", ratio);
168
169 if (freq_desc_tables[cpu_index].msr_plat == 2) {
170
171 freq = 100000;
172 debug("Using frequency: %u KHz\n", freq);
173 } else {
174
175 rdmsr(MSR_FSB_FREQ, lo, hi);
176 freq_id = lo & 0x7;
177 freq = id_to_freq(cpu_index, freq_id);
178 debug("Resolved frequency ID: %u, frequency: %u KHz\n",
179 freq_id, freq);
180 }
181
182
183 res = freq * ratio / 1000;
184 debug("TSC runs at %lu MHz\n", res);
185
186 return res;
187}
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224static inline int pit_verify_msb(unsigned char val)
225{
226
227 inb(0x42);
228 return inb(0x42) == val;
229}
230
231static inline int pit_expect_msb(unsigned char val, u64 *tscp,
232 unsigned long *deltap)
233{
234 int count;
235 u64 tsc = 0, prev_tsc = 0;
236
237 for (count = 0; count < 50000; count++) {
238 if (!pit_verify_msb(val))
239 break;
240 prev_tsc = tsc;
241 tsc = rdtsc();
242 }
243 *deltap = rdtsc() - prev_tsc;
244 *tscp = tsc;
245
246
247
248
249
250 return count > 5;
251}
252
253
254
255
256
257
258
259#define MAX_QUICK_PIT_MS 50
260#define MAX_QUICK_PIT_ITERATIONS (MAX_QUICK_PIT_MS * PIT_TICK_RATE / 1000 / 256)
261
262static unsigned long __maybe_unused quick_pit_calibrate(void)
263{
264 int i;
265 u64 tsc, delta;
266 unsigned long d1, d2;
267
268
269 outb((inb(0x61) & ~0x02) | 0x01, 0x61);
270
271
272
273
274
275
276
277
278
279
280 outb(0xb0, 0x43);
281
282
283 outb(0xff, 0x42);
284 outb(0xff, 0x42);
285
286
287
288
289
290
291
292 pit_verify_msb(0);
293
294 if (pit_expect_msb(0xff, &tsc, &d1)) {
295 for (i = 1; i <= MAX_QUICK_PIT_ITERATIONS; i++) {
296 if (!pit_expect_msb(0xff-i, &delta, &d2))
297 break;
298
299
300
301
302 delta -= tsc;
303 if (d1+d2 >= delta >> 11)
304 continue;
305
306
307
308
309
310
311
312
313 if (!pit_verify_msb(0xfe - i))
314 break;
315 goto success;
316 }
317 }
318 debug("Fast TSC calibration failed\n");
319 return 0;
320
321success:
322
323
324
325
326
327
328
329
330
331
332
333
334
335 delta *= PIT_TICK_RATE;
336 delta /= (i*256*1000);
337 debug("Fast TSC calibration using PIT\n");
338 return delta / 1000;
339}
340
341
342unsigned notrace long get_tbclk_mhz(void)
343{
344 return get_tbclk() / 1000000;
345}
346
347static ulong get_ms_timer(void)
348{
349 return (get_ticks() * 1000) / get_tbclk();
350}
351
352ulong get_timer(ulong base)
353{
354 return get_ms_timer() - base;
355}
356
357ulong notrace timer_get_us(void)
358{
359 return get_ticks() / get_tbclk_mhz();
360}
361
362ulong timer_get_boot_us(void)
363{
364 return timer_get_us();
365}
366
367void __udelay(unsigned long usec)
368{
369 u64 now = get_ticks();
370 u64 stop;
371
372 stop = now + usec * get_tbclk_mhz();
373
374 while ((int64_t)(stop - get_ticks()) > 0)
375#if defined(CONFIG_QEMU) && defined(CONFIG_SMP)
376
377
378
379
380 asm volatile("pause");
381#else
382 ;
383#endif
384}
385
386static int tsc_timer_get_count(struct udevice *dev, u64 *count)
387{
388 u64 now_tick = rdtsc();
389
390 *count = now_tick - gd->arch.tsc_base;
391
392 return 0;
393}
394
395static void tsc_timer_ensure_setup(bool early)
396{
397 if (gd->arch.tsc_base)
398 return;
399 gd->arch.tsc_base = rdtsc();
400
401 if (!gd->arch.clock_rate) {
402 unsigned long fast_calibrate;
403
404 fast_calibrate = native_calibrate_tsc();
405 if (fast_calibrate)
406 goto done;
407
408 fast_calibrate = cpu_mhz_from_cpuid();
409 if (fast_calibrate)
410 goto done;
411
412 fast_calibrate = cpu_mhz_from_msr();
413 if (fast_calibrate)
414 goto done;
415
416 fast_calibrate = quick_pit_calibrate();
417 if (fast_calibrate)
418 goto done;
419
420 if (early)
421 fast_calibrate = CONFIG_X86_TSC_TIMER_EARLY_FREQ;
422 else
423 return;
424
425done:
426 gd->arch.clock_rate = fast_calibrate * 1000000;
427 }
428}
429
430static int tsc_timer_probe(struct udevice *dev)
431{
432 struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
433
434
435 tsc_timer_ensure_setup(false);
436 if (!gd->arch.clock_rate) {
437
438
439
440
441 if (!uc_priv->clock_rate)
442 panic("TSC frequency is ZERO");
443 } else {
444 uc_priv->clock_rate = gd->arch.clock_rate;
445 }
446
447 return 0;
448}
449
450unsigned long notrace timer_early_get_rate(void)
451{
452
453
454
455
456
457 tsc_timer_ensure_setup(true);
458
459 return gd->arch.clock_rate;
460}
461
462u64 notrace timer_early_get_count(void)
463{
464 return rdtsc() - gd->arch.tsc_base;
465}
466
467static const struct timer_ops tsc_timer_ops = {
468 .get_count = tsc_timer_get_count,
469};
470
471static const struct udevice_id tsc_timer_ids[] = {
472 { .compatible = "x86,tsc-timer", },
473 { }
474};
475
476U_BOOT_DRIVER(tsc_timer) = {
477 .name = "tsc_timer",
478 .id = UCLASS_TIMER,
479 .of_match = tsc_timer_ids,
480 .probe = tsc_timer_probe,
481 .ops = &tsc_timer_ops,
482};
483