aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/quirks.c
diff options
context:
space:
mode:
authorUdo A. Steinberg <us15@os.inf.tu-dresden.de>2007-10-19 14:35:02 -0400
committerThomas Gleixner <tglx@linutronix.de>2007-10-19 14:35:02 -0400
commitb196884e2f5d45fb505b46011e41ca95e0859e34 (patch)
treeb5aca1366ca60abc4dd93ab4656a94876856e3f2 /arch/x86/kernel/quirks.c
parentb17530bda22e7ffbf08f7a8a50743256b1672f6a (diff)
x86: force enable HPET on VT8235/8237 chipsets
This patch adds quirks to force enable HPET on Via VT8235 and VT8237 chipsets. The datasheet for 8237 documents HPET functionality (although wrongly) whereas HPET is undocumented for 8235. Tested on A7V880 (8237) and K7VT4A+ (8235) boards. tglx: depends on the force_hept commandline option Signed-off-by: Udo A. Steinberg <us15@os.inf.tu-dresden.de> Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Cc: Andi Kleen <ak@suse.de> Cc: john stultz <johnstul@us.ibm.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/quirks.c')
-rw-r--r--arch/x86/kernel/quirks.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index 1fbc5380e27c..fbe32e7c3f5f 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -59,7 +59,8 @@ unsigned long force_hpet_address;
59static enum { 59static enum {
60 NONE_FORCE_HPET_RESUME, 60 NONE_FORCE_HPET_RESUME,
61 OLD_ICH_FORCE_HPET_RESUME, 61 OLD_ICH_FORCE_HPET_RESUME,
62 ICH_FORCE_HPET_RESUME 62 ICH_FORCE_HPET_RESUME,
63 VT8237_FORCE_HPET_RESUME
63} force_hpet_resume_type; 64} force_hpet_resume_type;
64 65
65static void __iomem *rcba_base; 66static void __iomem *rcba_base;
@@ -240,6 +241,69 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
240DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12, 241DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
241 old_ich_force_enable_hpet); 242 old_ich_force_enable_hpet);
242 243
244
245static void vt8237_force_hpet_resume(void)
246{
247 u32 val;
248
249 if (!force_hpet_address || !cached_dev)
250 return;
251
252 val = 0xfed00000 | 0x80;
253 pci_write_config_dword(cached_dev, 0x68, val);
254
255 pci_read_config_dword(cached_dev, 0x68, &val);
256 if (val & 0x80)
257 printk(KERN_DEBUG "Force enabled HPET at resume\n");
258 else
259 BUG();
260}
261
262static void vt8237_force_enable_hpet(struct pci_dev *dev)
263{
264 u32 uninitialized_var(val);
265
266 if (!hpet_force_user || hpet_address || force_hpet_address)
267 return;
268
269 pci_read_config_dword(dev, 0x68, &val);
270 /*
271 * Bit 7 is HPET enable bit.
272 * Bit 31:10 is HPET base address (contrary to what datasheet claims)
273 */
274 if (val & 0x80) {
275 force_hpet_address = (val & ~0x3ff);
276 printk(KERN_DEBUG "HPET at base address 0x%lx\n",
277 force_hpet_address);
278 return;
279 }
280
281 /*
282 * HPET is disabled. Trying enabling at FED00000 and check
283 * whether it sticks
284 */
285 val = 0xfed00000 | 0x80;
286 pci_write_config_dword(dev, 0x68, val);
287
288 pci_read_config_dword(dev, 0x68, &val);
289 if (val & 0x80) {
290 force_hpet_address = (val & ~0x3ff);
291 printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
292 force_hpet_address);
293 cached_dev = dev;
294 force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
295 return;
296 }
297
298 printk(KERN_DEBUG "Failed to force enable HPET\n");
299}
300
301DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
302 vt8237_force_enable_hpet);
303DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
304 vt8237_force_enable_hpet);
305
306
243void force_hpet_resume(void) 307void force_hpet_resume(void)
244{ 308{
245 switch (force_hpet_resume_type) { 309 switch (force_hpet_resume_type) {
@@ -249,6 +313,9 @@ void force_hpet_resume(void)
249 case OLD_ICH_FORCE_HPET_RESUME: 313 case OLD_ICH_FORCE_HPET_RESUME:
250 return old_ich_force_hpet_resume(); 314 return old_ich_force_hpet_resume();
251 315
316 case VT8237_FORCE_HPET_RESUME:
317 return vt8237_force_hpet_resume();
318
252 default: 319 default:
253 break; 320 break;
254 } 321 }