1 | /*␊ |
2 | * Copyright (c) 2009 Evan Lojewski. All rights reserved.␊ |
3 | */␊ |
4 | ␊ |
5 | /*␊ |
6 | * High Precision Event Timer (HPET)␊ |
7 | */␊ |
8 | ␊ |
9 | #include "libsaio.h"␊ |
10 | #include "pci.h"␊ |
11 | #include "hpet.h"␊ |
12 | ␊ |
13 | #ifndef DEBUG_HPET␊ |
14 | ␉#define DEBUG_HPET 0␊ |
15 | #endif␊ |
16 | ␊ |
17 | #if DEBUG_HPET␊ |
18 | ␉#define DBG(x...) printf(x)␊ |
19 | #else␊ |
20 | ␉#define DBG(x...)␊ |
21 | #endif␊ |
22 | ␊ |
23 | void force_enable_hpet_intel(pci_dt_t *lpc_dev);␊ |
24 | void force_enable_hpet_nvidia(pci_dt_t *lpc_dev);␊ |
25 | void force_enable_hpet_via(pci_dt_t *lpc_dev);␊ |
26 | ␊ |
27 | /*␊ |
28 | * Force HPET enabled␊ |
29 | *␊ |
30 | * VIA fix from http://forum.voodooprojects.org/index.php/topic,1596.0.html␊ |
31 | */␊ |
32 | ␊ |
33 | static struct lpc_controller_t lpc_controllers_intel[] = {␊ |
34 | ␊ |
35 | ␉// Default unknown chipset␊ |
36 | ␉{ 0, 0, "" },␊ |
37 | ␊ |
38 | ␉// Intel␊ |
39 | ␉{ 0x8086, 0x0f1c, "Bay Trail SoC" },␊ |
40 | ␊ |
41 | ␉{ 0x8086, 0x1c41, "Cougar Point" },␊ |
42 | ␉{ 0x8086, 0x1c42, "Cougar Point Desktop" },␊ |
43 | ␉{ 0x8086, 0x1c43, "Cougar Point Mobile" },␊ |
44 | ␉{ 0x8086, 0x1c44, "Cougar Point" },␊ |
45 | ␉{ 0x8086, 0x1c45, "Cougar Point" },␊ |
46 | ␉{ 0x8086, 0x1c46, "Cougar Point" },␊ |
47 | ␉{ 0x8086, 0x1c47, "Cougar Point" },␊ |
48 | ␉{ 0x8086, 0x1c48, "Cougar Point" },␊ |
49 | ␉{ 0x8086, 0x1c49, "Cougar Point" },␊ |
50 | ␉{ 0x8086, 0x1c4a, "Cougar Point" },␊ |
51 | ␉{ 0x8086, 0x1c4b, "Cougar Point" },␊ |
52 | ␉{ 0x8086, 0x1c4c, "Cougar Point" },␊ |
53 | ␉{ 0x8086, 0x1c4d, "Cougar Point" },␊ |
54 | ␉{ 0x8086, 0x1c4e, "Cougar Point" },␊ |
55 | ␉{ 0x8086, 0x1c4f, "Cougar Point" },␊ |
56 | ␉{ 0x8086, 0x1c50, "Cougar Point" },␊ |
57 | ␉{ 0x8086, 0x1c51, "Cougar Point" },␊ |
58 | ␉{ 0x8086, 0x1c52, "Cougar Point" },␊ |
59 | ␉{ 0x8086, 0x1c53, "Cougar Point" },␊ |
60 | ␉{ 0x8086, 0x1c54, "Cougar Point" },␊ |
61 | ␉{ 0x8086, 0x1c55, "Cougar Point" },␊ |
62 | ␉{ 0x8086, 0x1c56, "Cougar Point" },␊ |
63 | ␉{ 0x8086, 0x1c57, "Cougar Point" },␊ |
64 | ␉{ 0x8086, 0x1c58, "Cougar Point" },␊ |
65 | ␉{ 0x8086, 0x1c59, "Cougar Point" },␊ |
66 | ␉{ 0x8086, 0x1c5a, "Cougar Point" },␊ |
67 | ␉{ 0x8086, 0x1c5b, "Cougar Point" },␊ |
68 | ␉{ 0x8086, 0x1c5c, "Cougar Point" },␊ |
69 | ␉{ 0x8086, 0x1c5d, "Cougar Point" },␊ |
70 | ␉{ 0x8086, 0x1c5e, "Cougar Point" },␊ |
71 | ␉{ 0x8086, 0x1c5f, "Cougar Point" },␊ |
72 | ␉{ 0x8086, 0x1d40, "Patsburg" },␊ |
73 | ␉{ 0x8086, 0x1d41, "Patsburg" },␊ |
74 | ␉{ 0x8086, 0x1e40, "Panther Point" },␊ |
75 | ␉{ 0x8086, 0x1e41, "Panther Point" },␊ |
76 | ␉{ 0x8086, 0x1e42, "Panther Point" },␊ |
77 | ␉{ 0x8086, 0x1e43, "Panther Point" },␊ |
78 | ␉{ 0x8086, 0x1e44, "Panther Point" },␊ |
79 | ␉{ 0x8086, 0x1e45, "Panther Point" },␊ |
80 | ␉{ 0x8086, 0x1e46, "Panther Point" },␊ |
81 | ␉{ 0x8086, 0x1e47, "Panther Point" },␊ |
82 | ␉{ 0x8086, 0x1e48, "Panther Point" },␊ |
83 | ␉{ 0x8086, 0x1e49, "Panther Point" },␊ |
84 | ␉{ 0x8086, 0x1e4a, "Panther Point" },␊ |
85 | ␉{ 0x8086, 0x1e4b, "Panther Point" },␊ |
86 | ␉{ 0x8086, 0x1e4c, "Panther Point" },␊ |
87 | ␉{ 0x8086, 0x1e4d, "Panther Point" },␊ |
88 | ␉{ 0x8086, 0x1e4e, "Panther Point" },␊ |
89 | ␉{ 0x8086, 0x1e4f, "Panther Point" },␊ |
90 | ␉{ 0x8086, 0x1e50, "Panther Point" },␊ |
91 | ␉{ 0x8086, 0x1e51, "Panther Point" },␊ |
92 | ␉{ 0x8086, 0x1e52, "Panther Point" },␊ |
93 | ␉{ 0x8086, 0x1e53, "Panther Point" },␊ |
94 | ␉{ 0x8086, 0x1e54, "Panther Point" },␊ |
95 | ␉{ 0x8086, 0x1e55, "Panther Point" },␊ |
96 | ␉{ 0x8086, 0x1e56, "Panther Point" },␊ |
97 | ␉{ 0x8086, 0x1e57, "Panther Point" },␊ |
98 | ␉{ 0x8086, 0x1e58, "Panther Point" },␊ |
99 | ␉{ 0x8086, 0x1e59, "Panther Point" },␊ |
100 | ␉{ 0x8086, 0x1e5a, "Panther Point" },␊ |
101 | ␉{ 0x8086, 0x1e5b, "Panther Point" },␊ |
102 | ␉{ 0x8086, 0x1e5c, "Panther Point" },␊ |
103 | ␉{ 0x8086, 0x1e5d, "Panther Point" },␊ |
104 | ␉{ 0x8086, 0x1e5e, "Panther Point" },␊ |
105 | ␉{ 0x8086, 0x1e5f, "Panther Point" },␊ |
106 | ␉{ 0x8086, 0x1f38, "Avoton SoC" },␊ |
107 | ␉{ 0x8086, 0x1f39, "Avoton SoC" },␊ |
108 | ␉{ 0x8086, 0x1f3a, "Avoton SoC" },␊ |
109 | ␉{ 0x8086, 0x1f3b, "Avoton SoC" },␊ |
110 | ␊ |
111 | ␉{ 0x8086, 0x229c, "Braswell SoC" },␊ |
112 | ␉{ 0x8086, 0x2390, "Coleto Creek" },␊ |
113 | ␉{ 0x8086, 0x2310, "DH89xxCC" },␊ |
114 | ␉{ 0x8086, 0x2410, "ICH" },␊ |
115 | ␉{ 0x8086, 0x2420, "ICH0" },␊ |
116 | ␉{ 0x8086, 0x2440, "ICH2" },␊ |
117 | ␉{ 0x8086, 0x244c, "ICH2-M" },␊ |
118 | ␉{ 0x8086, 0x2480, "ICH3-S" },␊ |
119 | ␉{ 0x8086, 0x248c, "ICH3-M" },␊ |
120 | ␉{ 0x8086, 0x24c0, "ICH4" },␊ |
121 | ␉{ 0x8086, 0x24cc, "ICH4-M" },␊ |
122 | ␉{ 0x8086, 0x2450, "C-ICH" },␊ |
123 | ␉{ 0x8086, 0x24d0, "ICH5/ICH5R" },␊ |
124 | ␉{ 0x8086, 0x25a1, "6300ESB" },␊ |
125 | ␉{ 0x8086, 0x2640, "ICH6/ICH6R" },␊ |
126 | ␉{ 0x8086, 0x2641, "ICH6-M" },␊ |
127 | ␉{ 0x8086, 0x2642, "ICH6W/ICH6RW" },␊ |
128 | ␉{ 0x8086, 0x2670, "631xESB/632xESB" },␊ |
129 | ␉{ 0x8086, 0x2671, "631xESB/632xESB" },␊ |
130 | ␉{ 0x8086, 0x2672, "631xESB/632xESB" },␊ |
131 | ␉{ 0x8086, 0x2673, "631xESB/632xESB" },␊ |
132 | ␉{ 0x8086, 0x2674, "631xESB/632xESB" },␊ |
133 | ␉{ 0x8086, 0x2675, "631xESB/632xESB" },␊ |
134 | ␉{ 0x8086, 0x2676, "631xESB/632xESB" },␊ |
135 | ␉{ 0x8086, 0x2677, "631xESB/632xESB" },␊ |
136 | ␉{ 0x8086, 0x2678, "631xESB/632xESB" },␊ |
137 | ␉{ 0x8086, 0x2679, "631xESB/632xESB" },␊ |
138 | ␉{ 0x8086, 0x267a, "631xESB/632xESB" },␊ |
139 | ␉{ 0x8086, 0x267b, "631xESB/632xESB" },␊ |
140 | ␉{ 0x8086, 0x267c, "631xESB/632xESB" },␊ |
141 | ␉{ 0x8086, 0x267d, "631xESB/632xESB" },␊ |
142 | ␉{ 0x8086, 0x267e, "631xESB/632xESB" },␊ |
143 | ␉{ 0x8086, 0x267f, "631xESB/632xESB" },␊ |
144 | ␉{ 0x8086, 0x27b0, "ICH7DH" },␊ |
145 | ␉{ 0x8086, 0x27b8, "ICH7/ICH7R" },␊ |
146 | ␉{ 0x8086, 0x27b9, "ICH7-M/ICH7-U" },␊ |
147 | ␉{ 0x8086, 0x27bc, "NM10" },␊ |
148 | ␉{ 0x8086, 0x27bd, "ICH7-M DH" },␊ |
149 | ␊ |
150 | ␊ |
151 | ␉{ 0x8086, 0x2810, "ICH8/ICH8R" },␊ |
152 | ␉{ 0x8086, 0x2811, "ICH8M-E" },␊ |
153 | ␉{ 0x8086, 0x2812, "ICH8DH" },␊ |
154 | ␉{ 0x8086, 0x2814, "ICH8DO" },␊ |
155 | ␉{ 0x8086, 0x2815, "ICH8M" },␊ |
156 | ␊ |
157 | ␉{ 0x8086, 0x2912, "ICH9DH" },␊ |
158 | ␉{ 0x8086, 0x2914, "ICH9DO" },␊ |
159 | ␉{ 0x8086, 0x2916, "ICH9R" },␊ |
160 | ␉{ 0x8086, 0x2917, "ICH9M-E" },␊ |
161 | ␉{ 0x8086, 0x2918, "ICH9" },␊ |
162 | ␉{ 0x8086, 0x2919, "ICH9M" },␊ |
163 | ␊ |
164 | ␉{ 0x8086, 0x3a14, "ICH10DO" },␊ |
165 | ␉{ 0x8086, 0x3a16, "ICH10R" },␊ |
166 | ␉{ 0x8086, 0x3a18, "ICH10" },␊ |
167 | ␉{ 0x8086, 0x3a1a, "ICH10D" },␊ |
168 | ␉{ 0x8086, 0x3b00, "PCH Desktop Full Featured" },␊ |
169 | ␉{ 0x8086, 0x3b01, "PCH Mobile Full Featured" },␊ |
170 | ␉{ 0x8086, 0x3b02, "P55" },␊ |
171 | ␉{ 0x8086, 0x3b03, "PM55" },␊ |
172 | ␉{ 0x8086, 0x3b06, "H55" },␊ |
173 | ␉{ 0x8086, 0x3b07, "QM57" },␊ |
174 | ␉{ 0x8086, 0x3b08, "H57" },␊ |
175 | ␉{ 0x8086, 0x3b09, "HM55" },␊ |
176 | ␉{ 0x8086, 0x3b0a, "Q57" },␊ |
177 | ␉{ 0x8086, 0x3b0b, "HM57" },␊ |
178 | ␉{ 0x8086, 0x3b0d, "PCH Mobile SFF Full Featured" },␊ |
179 | ␉{ 0x8086, 0x3b0f, "QS57" },␊ |
180 | ␉{ 0x8086, 0x3b12, "3400" },␊ |
181 | ␉{ 0x8086, 0x3b14, "3420" },␊ |
182 | ␉{ 0x8086, 0x3b16, "3450" },␊ |
183 | ␊ |
184 | ␉{ 0x8086, 0x5031, "EP80579" },␊ |
185 | ␊ |
186 | ␉{ 0x8086, 0x8c40, "Lynx Point" },␊ |
187 | ␉{ 0x8086, 0x8c41, "Lynx Point" },␊ |
188 | ␉{ 0x8086, 0x8c42, "Lynx Point" },␊ |
189 | ␉{ 0x8086, 0x8c43, "Lynx Point" },␊ |
190 | ␉{ 0x8086, 0x8c44, "Lynx Point" },␊ |
191 | ␉{ 0x8086, 0x8c45, "Lynx Point" },␊ |
192 | ␉{ 0x8086, 0x8c46, "Lynx Point" },␊ |
193 | ␉{ 0x8086, 0x8c47, "Lynx Point" },␊ |
194 | ␉{ 0x8086, 0x8c48, "Lynx Point" },␊ |
195 | ␉{ 0x8086, 0x8c49, "Lynx Point" },␊ |
196 | ␉{ 0x8086, 0x8c4a, "Lynx Point" },␊ |
197 | ␉{ 0x8086, 0x8c4b, "Lynx Point" },␊ |
198 | ␉{ 0x8086, 0x8c4c, "Lynx Point" },␊ |
199 | ␉{ 0x8086, 0x8c4d, "Lynx Point" },␊ |
200 | ␉{ 0x8086, 0x8c4e, "Lynx Point" },␊ |
201 | ␉{ 0x8086, 0x8c4f, "Lynx Point" },␊ |
202 | ␉{ 0x8086, 0x8c50, "Lynx Point" },␊ |
203 | ␉{ 0x8086, 0x8c51, "Lynx Point" },␊ |
204 | ␉{ 0x8086, 0x8c52, "Lynx Point" },␊ |
205 | ␉{ 0x8086, 0x8c53, "Lynx Point" },␊ |
206 | ␉{ 0x8086, 0x8c54, "Lynx Point" },␊ |
207 | ␉{ 0x8086, 0x8c55, "Lynx Point" },␊ |
208 | ␉{ 0x8086, 0x8c56, "Lynx Point" },␊ |
209 | ␉{ 0x8086, 0x8c57, "Lynx Point" },␊ |
210 | ␉{ 0x8086, 0x8c58, "Lynx Point" },␊ |
211 | ␉{ 0x8086, 0x8c59, "Lynx Point" },␊ |
212 | ␉{ 0x8086, 0x8c5a, "Lynx Point" },␊ |
213 | ␉{ 0x8086, 0x8c5b, "Lynx Point" },␊ |
214 | ␉{ 0x8086, 0x8c5c, "Lynx Point" },␊ |
215 | ␉{ 0x8086, 0x8c5d, "Lynx Point" },␊ |
216 | ␉{ 0x8086, 0x8c5e, "Lynx Point" },␊ |
217 | ␉{ 0x8086, 0x8c5f, "Lynx Point" },␊ |
218 | ␉{ 0x8086, 0x8cc1, "9 Series" },␊ |
219 | ␉{ 0x8086, 0x8cc2, "9 Series" },␊ |
220 | ␉{ 0x8086, 0x8cc3, "9 Series" },␊ |
221 | ␉{ 0x8086, 0x8cc4, "9 Series" },␊ |
222 | ␉{ 0x8086, 0x8cc6, "9 Series" },␊ |
223 | ␉{ 0x8086, 0x8d40, "Wellsburg" },␊ |
224 | ␉{ 0x8086, 0x8d41, "Wellsburg" },␊ |
225 | ␉{ 0x8086, 0x8d42, "Wellsburg" },␊ |
226 | ␉{ 0x8086, 0x8d43, "Wellsburg" },␊ |
227 | ␉{ 0x8086, 0x8d44, "Wellsburg" },␊ |
228 | ␉{ 0x8086, 0x8d45, "Wellsburg" },␊ |
229 | ␉{ 0x8086, 0x8d46, "Wellsburg" },␊ |
230 | ␉{ 0x8086, 0x8d47, "Wellsburg" },␊ |
231 | ␉{ 0x8086, 0x8d48, "Wellsburg" },␊ |
232 | ␉{ 0x8086, 0x8d49, "Wellsburg" },␊ |
233 | ␉{ 0x8086, 0x8d4a, "Wellsburg" },␊ |
234 | ␉{ 0x8086, 0x8d4b, "Wellsburg" },␊ |
235 | ␉{ 0x8086, 0x8d4c, "Wellsburg" },␊ |
236 | ␉{ 0x8086, 0x8d4d, "Wellsburg" },␊ |
237 | ␉{ 0x8086, 0x8d4e, "Wellsburg" },␊ |
238 | ␉{ 0x8086, 0x8d4f, "Wellsburg" },␊ |
239 | ␉{ 0x8086, 0x8d50, "Wellsburg" },␊ |
240 | ␉{ 0x8086, 0x8d51, "Wellsburg" },␊ |
241 | ␉{ 0x8086, 0x8d52, "Wellsburg" },␊ |
242 | ␉{ 0x8086, 0x8d53, "Wellsburg" },␊ |
243 | ␉{ 0x8086, 0x8d54, "Wellsburg" },␊ |
244 | ␉{ 0x8086, 0x8d55, "Wellsburg" },␊ |
245 | ␉{ 0x8086, 0x8d56, "Wellsburg" },␊ |
246 | ␉{ 0x8086, 0x8d57, "Wellsburg" },␊ |
247 | ␉{ 0x8086, 0x8d58, "Wellsburg" },␊ |
248 | ␉{ 0x8086, 0x8d59, "Wellsburg" },␊ |
249 | ␉{ 0x8086, 0x8d5a, "Wellsburg" },␊ |
250 | ␉{ 0x8086, 0x8d5b, "Wellsburg" },␊ |
251 | ␉{ 0x8086, 0x8d5c, "Wellsburg" },␊ |
252 | ␉{ 0x8086, 0x8d5d, "Wellsburg" },␊ |
253 | ␉{ 0x8086, 0x8d5e, "Wellsburg" },␊ |
254 | ␉{ 0x8086, 0x8d5f, "Wellsburg" },␊ |
255 | ␊ |
256 | ␉{ 0x8086, 0x9c40, "Lynx Point_LP" },␊ |
257 | ␉{ 0x8086, 0x9c41, "Lynx Point_LP" },␊ |
258 | ␉{ 0x8086, 0x9c42, "Lynx Point_LP" },␊ |
259 | ␉{ 0x8086, 0x9c43, "Lynx Point_LP" },␊ |
260 | ␉{ 0x8086, 0x9c44, "Lynx Point_LP" },␊ |
261 | ␉{ 0x8086, 0x9c45, "Lynx Point_LP" },␊ |
262 | ␉{ 0x8086, 0x9c46, "Lynx Point_LP" },␊ |
263 | ␉{ 0x8086, 0x9c47, "Lynx Point_LP" },␊ |
264 | ␉{ 0x8086, 0x9cc1, "Wildcat Point_LP" },␊ |
265 | ␉{ 0x8086, 0x9cc2, "Wildcat Point_LP" },␊ |
266 | ␉{ 0x8086, 0x9cc3, "Wildcat Point_LP" },␊ |
267 | ␉{ 0x8086, 0x9cc5, "Wildcat Point_LP" },␊ |
268 | ␉{ 0x8086, 0x9cc6, "Wildcat Point_LP" },␊ |
269 | ␉{ 0x8086, 0x9cc7, "Wildcat Point_LP" },␊ |
270 | ␉{ 0x8086, 0x9cc9, "Wildcat Point_LP" },␊ |
271 | ␊ |
272 | };␊ |
273 | ␊ |
274 | static struct lpc_controller_t lpc_controllers_nvidia[] = {␊ |
275 | ␊ |
276 | ␉// Default unknown chipset␊ |
277 | ␉{ 0, 0, "" },␊ |
278 | ␊ |
279 | ␉// nVidia␊ |
280 | ␉{ 0x10de, 0x0aac, "MCP79" },␊ |
281 | ␉{ 0x10de, 0x0aae, "MCP79" },␊ |
282 | ␉{ 0x10de, 0x0aaf, "MCP79" },␊ |
283 | ␉{ 0x10de, 0x0d80, "MCP89" },␊ |
284 | ␉{ 0x10de, 0x0d81, "MCP89" },␊ |
285 | ␉{ 0x10de, 0x0d82, "MCP89" },␊ |
286 | ␉{ 0x10de, 0x0d83, "MCP89" },␊ |
287 | ␊ |
288 | };␊ |
289 | ␊ |
290 | static struct lpc_controller_t lpc_controllers_via[] = {␊ |
291 | ␉// Default unknown chipset␊ |
292 | ␉{ 0, 0, "" },␊ |
293 | ␉{ 0x1106, 0x3050, "VT82C596A" },␊ |
294 | ␉{ 0x1106, 0x3051, "VT82C596B" },␊ |
295 | ␉{ 0x1106, 0x8235, "VT8231" },␊ |
296 | ␉{ 0x1106, 0x3074, "VT8233" },␊ |
297 | ␉{ 0x1106, 0x3147, "VT8233A" },␊ |
298 | ␉{ 0x1106, 0x3177, "VT8235" },␊ |
299 | ␉{ 0x1106, 0x3227, "VT8237R" },␊ |
300 | ␉{ 0x1106, 0x3337, "VT8237A" },␊ |
301 | ␉{ 0x1106, 0x3372, "VT8237S" },␊ |
302 | ␉{ 0x1106, 0x3287, "VT8251" },␊ |
303 | ␉{ 0x1106, 0x8324, "CX700" },␊ |
304 | ␉{ 0x1106, 0x8353, "VX800/VX820" },␊ |
305 | ␉{ 0x1106, 0x8409, "VX855/VX875" },␊ |
306 | };␊ |
307 | ␊ |
308 | /* ErmaC add lpc for nVidia */␊ |
309 | void force_enable_hpet_nvidia(pci_dt_t *lpc_dev)␊ |
310 | {␊ |
311 | ␉uint32_t␉val, hpet_address = 0xFED00000;␊ |
312 | ␉int i;␊ |
313 | ␉void␉␉*rcba;␊ |
314 | ␊ |
315 | ␉for(i = 1; i < sizeof(lpc_controllers_nvidia) / sizeof(lpc_controllers_nvidia[0]); i++)␊ |
316 | ␉{␊ |
317 | ␉␉if ((lpc_controllers_nvidia[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_nvidia[i].device == lpc_dev->device_id))␊ |
318 | ␉␉{␊ |
319 | ␊ |
320 | ␉␉␉rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);␊ |
321 | ␊ |
322 | ␉␉␉DBG("\tnVidia(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n", ␊ |
323 | ␉␉␉␉lpc_controllers_nvidia[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);␊ |
324 | ␊ |
325 | ␉␉␉if (rcba == 0)␊ |
326 | ␉␉␉{␊ |
327 | ␉␉␉␉printf("\tRCBA disabled; cannot force enable HPET\n");␊ |
328 | ␉␉␉}␊ |
329 | ␉␉␉else␊ |
330 | ␉␉␉{␊ |
331 | ␉␉␉␉val = REG32(rcba, 0x3404);␊ |
332 | ␉␉␉␉if (val & 0x80)␊ |
333 | ␉␉␉␉{␊ |
334 | ␉␉␉␉␉// HPET is enabled in HPTC. Just not reported by BIOS␊ |
335 | ␉␉␉␉␉DBG("\tHPET is enabled in HPTC, just not reported by BIOS\n");␊ |
336 | ␉␉␉␉␉hpet_address |= (val & 3) << 12 ;␊ |
337 | ␉␉␉␉␉DBG("\tHPET MMIO @ 0x%lx\n", hpet_address);␊ |
338 | ␉␉␉␉}␊ |
339 | ␉␉␉␉else␊ |
340 | ␉␉␉␉{␊ |
341 | ␉␉␉␉␉// HPET disabled in HPTC. Trying to enable␊ |
342 | ␉␉␉␉␉DBG("\tHPET is disabled in HPTC, trying to enable\n");␉␉␉␉␉␉␉␉␉␊ |
343 | ␉␉␉␉␉REG32(rcba, 0x3404) = val | 0x80;␊ |
344 | ␉␉␉␉␉hpet_address |= (val & 3) << 12 ;␊ |
345 | ␉␉␉␉␉DBG("\tForce enabled HPET, MMIO @ 0x%lx\n", hpet_address);␊ |
346 | ␉␉␉␉}␊ |
347 | ␊ |
348 | ␉␉␉␉// verify if the job is done␊ |
349 | ␉␉␉␉val = REG32(rcba, 0x3404);␊ |
350 | ␉␉␉␉if (!(val & 0x80))␊ |
351 | ␉␉␉␉{␊ |
352 | ␉␉␉␉␉printf("\tFailed to force enable HPET\n");␊ |
353 | ␉␉␉␉}␊ |
354 | ␉␉␉}␊ |
355 | ␉␉␉break;␊ |
356 | ␉␉}␊ |
357 | ␉}␊ |
358 | }␊ |
359 | ␊ |
360 | void force_enable_hpet_via(pci_dt_t *lpc_dev)␊ |
361 | {␊ |
362 | ␉uint32_t␉val, hpet_address = 0xFED00000;␊ |
363 | ␉int i;␊ |
364 | ␊ |
365 | ␉for(i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)␊ |
366 | ␉{␊ |
367 | ␉␉if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_via[i].device == lpc_dev->device_id))␊ |
368 | ␉␉{␊ |
369 | ␉␉␉val = pci_config_read32(lpc_dev->dev.addr, 0x68);␊ |
370 | ␊ |
371 | ␉␉␉DBG("\tVIA %s LPC Interface [%04x:%04x], MMIO\n", ␊ |
372 | ␉␉␉␉lpc_controllers_via[i].name, lpc_dev->vendor_id, lpc_dev->device_id);␊ |
373 | ␊ |
374 | ␉␉␉if (val & 0x80)␊ |
375 | ␉␉␉{␊ |
376 | ␉␉␉␉hpet_address = (val & ~0x3ff);␊ |
377 | ␉␉␉␉DBG("HPET at 0x%lx\n", hpet_address);␊ |
378 | ␉␉␉}␊ |
379 | ␉␉␉else␊ |
380 | ␉␉␉{␊ |
381 | ␉␉␉␉val = 0xfed00000 | 0x80;␊ |
382 | ␉␉␉␉pci_config_write32(lpc_dev->dev.addr, 0x68, val);␊ |
383 | ␉␉␉␉val = pci_config_read32(lpc_dev->dev.addr, 0x68);␊ |
384 | ␉␉␉␉if (val & 0x80)␊ |
385 | ␉␉␉␉{␊ |
386 | ␉␉␉␉␉hpet_address = (val & ~0x3ff);␊ |
387 | ␉␉␉␉␉DBG("\tForce enabled HPET at 0x%lx\n", hpet_address);␊ |
388 | ␉␉␉␉}␊ |
389 | ␉␉␉␉else␊ |
390 | ␉␉␉␉{␊ |
391 | ␉␉␉␉␉DBG("\tUnable to enable HPET");␊ |
392 | ␉␉␉␉}␊ |
393 | ␉␉␉}␊ |
394 | ␉␉}␊ |
395 | ␉}␊ |
396 | }␊ |
397 | ␊ |
398 | void force_enable_hpet_intel(pci_dt_t *lpc_dev)␊ |
399 | {␊ |
400 | ␉uint32_t␉val, hpet_address = 0xFED00000;␊ |
401 | ␉int i;␊ |
402 | ␉void␉␉*rcba;␊ |
403 | ␊ |
404 | ␉/* LPC on Intel ICH is always (?) at 00:1f.0 */␊ |
405 | ␉for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)␊ |
406 | ␉{␊ |
407 | ␉␉if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_intel[i].device == lpc_dev->device_id))␊ |
408 | ␉␉{␊ |
409 | ␊ |
410 | ␉␉␉rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);␊ |
411 | ␊ |
412 | ␉␉␉DBG("\tIntel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n", ␊ |
413 | ␉␉␉␉lpc_controllers_intel[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);␊ |
414 | ␊ |
415 | ␉␉␉if (rcba == 0)␊ |
416 | ␉␉␉{␊ |
417 | ␉␉␉␉printf("\tRCBA disabled; cannot force enable HPET\n");␊ |
418 | ␉␉␉}␊ |
419 | ␉␉␉else␊ |
420 | ␉␉␉{␊ |
421 | ␉␉␉␉val = REG32(rcba, 0x3404);␊ |
422 | ␉␉␉␉if (val & 0x80)␊ |
423 | ␉␉␉␉{␊ |
424 | ␉␉␉␉␉// HPET is enabled in HPTC. Just not reported by BIOS␊ |
425 | ␉␉␉␉␉DBG("\tHPET is enabled in HPTC, just not reported by BIOS\n");␊ |
426 | ␉␉␉␉␉hpet_address |= (val & 3) << 12 ;␊ |
427 | ␉␉␉␉␉DBG("\tHPET MMIO @ 0x%lx\n", hpet_address);␊ |
428 | ␉␉␉␉}␊ |
429 | ␉␉␉␉else␊ |
430 | ␉␉␉␉{␊ |
431 | ␉␉␉␉␉// HPET disabled in HPTC. Trying to enable␊ |
432 | ␉␉␉␉␉DBG("\tHPET is disabled in HPTC, trying to enable\n");␉␉␉␉␉␉␉␉␉␊ |
433 | ␉␉␉␉␉REG32(rcba, 0x3404) = val | 0x80;␊ |
434 | ␉␉␉␉␉hpet_address |= (val & 3) << 12 ;␊ |
435 | ␉␉␉␉␉DBG("\tForce enabled HPET, MMIO @ 0x%lx\n", hpet_address);␊ |
436 | ␉␉␉␉}␊ |
437 | ␊ |
438 | ␉␉␉␉// verify if the job is done␊ |
439 | ␉␉␉␉val = REG32(rcba, 0x3404);␊ |
440 | ␉␉␉␉if (!(val & 0x80))␊ |
441 | ␉␉␉␉{␊ |
442 | ␉␉␉␉␉printf("\tFailed to force enable HPET\n");␊ |
443 | ␉␉␉␉}␊ |
444 | ␉␉␉}␊ |
445 | ␉␉␉break;␊ |
446 | ␉␉}␊ |
447 | ␉}␊ |
448 | }␊ |
449 | ␊ |
450 | void force_enable_hpet(pci_dt_t *lpc_dev)␊ |
451 | {␊ |
452 | ␉switch(lpc_dev->vendor_id)␊ |
453 | ␉{␊ |
454 | ␉␉case 0x8086:␊ |
455 | ␉␉␉force_enable_hpet_intel(lpc_dev);␊ |
456 | ␉␉␉break;␊ |
457 | ␊ |
458 | ␉␉case 0x10de:␊ |
459 | ␉␉␉force_enable_hpet_nvidia(lpc_dev);␊ |
460 | ␉␉␉break;␊ |
461 | ␊ |
462 | ␉␉case 0x1106:␊ |
463 | ␉␉␉force_enable_hpet_via(lpc_dev);␊ |
464 | ␉␉␉break;␊ |
465 | ␉}␊ |
466 | ␊ |
467 | #if DEBUG_HPET␊ |
468 | ␉printf("Press [Enter] to continue...\n");␊ |
469 | ␉getchar();␊ |
470 | #endif␊ |
471 | ␊ |
472 | }␊ |
473 | |