tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / northbridge / intel / gm45 / delay.c
blobad2e5431751106c6954c1ce8af8a3a60120ccb7f
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2008 coresystems GmbH
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <stdint.h>
17 #include <cpu/x86/tsc.h>
18 #include <cpu/x86/msr.h>
19 #include <cpu/intel/speedstep.h>
20 #include "delay.h"
22 /**
23 * Intel Core(tm) CPUs always run the TSC at the maximum possible CPU clock
25 static void _udelay(const u32 us, const u32 numerator, const int total)
27 u32 dword;
28 tsc_t tsc, tsc1, tscd;
29 msr_t msr;
30 u32 fsb = 0, divisor;
31 u32 d; /* ticks per us */
33 msr = rdmsr(MSR_FSB_FREQ);
34 switch (msr.lo & 0x07) {
35 case 5:
36 fsb = 400;
37 break;
38 case 1:
39 fsb = 533;
40 break;
41 case 3:
42 fsb = 667;
43 break;
44 case 2:
45 fsb = 800;
46 break;
47 case 0:
48 fsb = 1067;
49 break;
50 case 4:
51 fsb = 1333;
52 break;
53 case 6:
54 fsb = 1600;
55 break;
58 msr = rdmsr(0x198);
59 divisor = (msr.hi >> 8) & 0x1f;
61 d = ((fsb * divisor) / numerator) / 4; /* CPU clock is always a quarter. */
63 multiply_to_tsc(&tscd, us, d);
65 if (!total) {
66 tsc1 = rdtsc();
67 dword = tsc1.lo + tscd.lo;
68 if ((dword < tsc1.lo) || (dword < tscd.lo)) {
69 tsc1.hi++;
71 tsc1.lo = dword;
72 tsc1.hi += tscd.hi;
73 } else {
74 tsc1 = tscd;
77 do {
78 tsc = rdtsc();
79 } while ((tsc.hi < tsc1.hi)
80 || ((tsc.hi == tsc1.hi) && (tsc.lo < tsc1.lo)));
83 void udelay(const u32 us)
85 _udelay(us, 1, 0);
88 void ns100delay(const u32 ns100)
90 _udelay(ns100, 10, 0);
93 void udelay_from_reset(const u32 us)
95 _udelay(us, 1, 1);