Chameleon

Chameleon Svn Source Tree

Root/branches/zenith432/i386/libsaio/hpet.c

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
23void force_enable_hpet_intel(pci_dt_t *lpc_dev);
24void force_enable_hpet_nvidia(pci_dt_t *lpc_dev);
25void 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
33static 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
274static 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
290static 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 */
309void force_enable_hpet_nvidia(pci_dt_t *lpc_dev)
310{
311uint32_tval, hpet_address = 0xFED00000;
312int i;
313void*rcba;
314
315for(i = 1; i < sizeof(lpc_controllers_nvidia) / sizeof(lpc_controllers_nvidia[0]); i++)
316{
317if ((lpc_controllers_nvidia[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_nvidia[i].device == lpc_dev->device_id))
318{
319
320rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
321
322DBG("\tnVidia(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
323lpc_controllers_nvidia[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
324
325if (rcba == 0)
326{
327printf("\tRCBA disabled; cannot force enable HPET\n");
328}
329else
330{
331val = REG32(rcba, 0x3404);
332if (val & 0x80)
333{
334// HPET is enabled in HPTC. Just not reported by BIOS
335DBG("\tHPET is enabled in HPTC, just not reported by BIOS\n");
336hpet_address |= (val & 3) << 12 ;
337DBG("\tHPET MMIO @ 0x%lx\n", hpet_address);
338}
339else
340{
341// HPET disabled in HPTC. Trying to enable
342DBG("\tHPET is disabled in HPTC, trying to enable\n");
343REG32(rcba, 0x3404) = val | 0x80;
344hpet_address |= (val & 3) << 12 ;
345DBG("\tForce enabled HPET, MMIO @ 0x%lx\n", hpet_address);
346}
347
348// verify if the job is done
349val = REG32(rcba, 0x3404);
350if (!(val & 0x80))
351{
352printf("\tFailed to force enable HPET\n");
353}
354}
355break;
356}
357}
358}
359
360void force_enable_hpet_via(pci_dt_t *lpc_dev)
361{
362uint32_tval, hpet_address = 0xFED00000;
363int i;
364
365for(i = 1; i < sizeof(lpc_controllers_via) / sizeof(lpc_controllers_via[0]); i++)
366{
367if ((lpc_controllers_via[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_via[i].device == lpc_dev->device_id))
368{
369val = pci_config_read32(lpc_dev->dev.addr, 0x68);
370
371DBG("\tVIA %s LPC Interface [%04x:%04x], MMIO\n",
372lpc_controllers_via[i].name, lpc_dev->vendor_id, lpc_dev->device_id);
373
374if (val & 0x80)
375{
376hpet_address = (val & ~0x3ff);
377DBG("HPET at 0x%lx\n", hpet_address);
378}
379else
380{
381val = 0xfed00000 | 0x80;
382pci_config_write32(lpc_dev->dev.addr, 0x68, val);
383val = pci_config_read32(lpc_dev->dev.addr, 0x68);
384if (val & 0x80)
385{
386hpet_address = (val & ~0x3ff);
387DBG("\tForce enabled HPET at 0x%lx\n", hpet_address);
388}
389else
390{
391DBG("\tUnable to enable HPET");
392}
393}
394}
395}
396}
397
398void force_enable_hpet_intel(pci_dt_t *lpc_dev)
399{
400uint32_tval, hpet_address = 0xFED00000;
401int i;
402void*rcba;
403
404/* LPC on Intel ICH is always (?) at 00:1f.0 */
405for(i = 1; i < sizeof(lpc_controllers_intel) / sizeof(lpc_controllers_intel[0]); i++)
406{
407if ((lpc_controllers_intel[i].vendor == lpc_dev->vendor_id) && (lpc_controllers_intel[i].device == lpc_dev->device_id))
408{
409
410rcba = (void *)(pci_config_read32(lpc_dev->dev.addr, 0xF0) & 0xFFFFC000);
411
412DBG("\tIntel(R) %s LPC Interface [%04x:%04x], MMIO @ 0x%lx\n",
413lpc_controllers_intel[i].name, lpc_dev->vendor_id, lpc_dev->device_id, rcba);
414
415if (rcba == 0)
416{
417printf("\tRCBA disabled; cannot force enable HPET\n");
418}
419else
420{
421val = REG32(rcba, 0x3404);
422if (val & 0x80)
423{
424// HPET is enabled in HPTC. Just not reported by BIOS
425DBG("\tHPET is enabled in HPTC, just not reported by BIOS\n");
426hpet_address |= (val & 3) << 12 ;
427DBG("\tHPET MMIO @ 0x%lx\n", hpet_address);
428}
429else
430{
431// HPET disabled in HPTC. Trying to enable
432DBG("\tHPET is disabled in HPTC, trying to enable\n");
433REG32(rcba, 0x3404) = val | 0x80;
434hpet_address |= (val & 3) << 12 ;
435DBG("\tForce enabled HPET, MMIO @ 0x%lx\n", hpet_address);
436}
437
438// verify if the job is done
439val = REG32(rcba, 0x3404);
440if (!(val & 0x80))
441{
442printf("\tFailed to force enable HPET\n");
443}
444}
445break;
446}
447}
448}
449
450void force_enable_hpet(pci_dt_t *lpc_dev)
451{
452switch(lpc_dev->vendor_id)
453{
454case 0x8086:
455force_enable_hpet_intel(lpc_dev);
456break;
457
458case 0x10de:
459force_enable_hpet_nvidia(lpc_dev);
460break;
461
462case 0x1106:
463force_enable_hpet_via(lpc_dev);
464break;
465}
466
467#if DEBUG_HPET
468printf("Press [Enter] to continue...\n");
469getchar();
470#endif
471
472}
473

Archive Download this file

Revision: 2805