x86: Force enable HPET for CK804 (nForce 4) chipsets

This patch adds a quirk from LinuxBIOS to force enable HPET on
the nVidia CK804 (nForce 4) chipset.

This quirk can very likely support more than just nForce 4
(LinuxBIOS use the same code for nForce 5), and possibly nForce 3,
but I don't have those chipsets, so cannot add and test them.

Tested on an Abit KN9 (CK804).

Signed-off-by: Carlos Corbacho <cathectic@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

Documentation/kernel-parameters.txt | 3 +-
arch/x86/kernel/quirks.c | 37 +++++++++++++++++++++++++++++++++++-
2 files changed, 38 insertions(+), 2 deletions(-)

authored by Carlos Corbacho and committed by Thomas Gleixner d79a5f80 fa76dab9

+38 -2
+2 -1
Documentation/kernel-parameters.txt
··· 422 hpet= [X86-32,HPET] option to control HPET usage 423 Format: { enable (default) | disable | force } 424 disable: disable HPET and use PIT instead 425 - force: allow force enabled of undocumented chips (ICH4, VIA) 426 427 com20020= [HW,NET] ARCnet - COM20020 chipset 428 Format:
··· 422 hpet= [X86-32,HPET] option to control HPET usage 423 Format: { enable (default) | disable | force } 424 disable: disable HPET and use PIT instead 425 + force: allow force enabled of undocumented chips (ICH4, 426 + VIA, nVidia) 427 428 com20020= [HW,NET] ARCnet - COM20020 chipset 429 Format:
+36 -1
arch/x86/kernel/quirks.c
··· 60 NONE_FORCE_HPET_RESUME, 61 OLD_ICH_FORCE_HPET_RESUME, 62 ICH_FORCE_HPET_RESUME, 63 - VT8237_FORCE_HPET_RESUME 64 } force_hpet_resume_type; 65 66 static void __iomem *rcba_base; ··· 322 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, 323 vt8237_force_enable_hpet); 324 325 326 void force_hpet_resume(void) 327 { ··· 365 366 case VT8237_FORCE_HPET_RESUME: 367 return vt8237_force_hpet_resume(); 368 369 default: 370 break;
··· 60 NONE_FORCE_HPET_RESUME, 61 OLD_ICH_FORCE_HPET_RESUME, 62 ICH_FORCE_HPET_RESUME, 63 + VT8237_FORCE_HPET_RESUME, 64 + NVIDIA_FORCE_HPET_RESUME, 65 } force_hpet_resume_type; 66 67 static void __iomem *rcba_base; ··· 321 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, 322 vt8237_force_enable_hpet); 323 324 + /* 325 + * Undocumented chipset feature taken from LinuxBIOS. 326 + */ 327 + static void nvidia_force_hpet_resume(void) 328 + { 329 + pci_write_config_dword(cached_dev, 0x44, 0xfed00001); 330 + printk(KERN_DEBUG "Force enabled HPET at resume\n"); 331 + } 332 + 333 + static void nvidia_force_enable_hpet(struct pci_dev *dev) 334 + { 335 + u32 uninitialized_var(val); 336 + 337 + if (!hpet_force_user || hpet_address || force_hpet_address) 338 + return; 339 + 340 + pci_write_config_dword(dev, 0x44, 0xfed00001); 341 + pci_read_config_dword(dev, 0x44, &val); 342 + force_hpet_address = val & 0xfffffffe; 343 + force_hpet_resume_type = NVIDIA_FORCE_HPET_RESUME; 344 + printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n", 345 + force_hpet_address); 346 + cached_dev = dev; 347 + return; 348 + } 349 + 350 + /* ISA Bridges */ 351 + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0050, 352 + nvidia_force_enable_hpet); 353 + DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, 0x0051, 354 + nvidia_force_enable_hpet); 355 356 void force_hpet_resume(void) 357 { ··· 333 334 case VT8237_FORCE_HPET_RESUME: 335 return vt8237_force_hpet_resume(); 336 + 337 + case NVIDIA_FORCE_HPET_RESUME: 338 + return nvidia_force_hpet_resume(); 339 340 default: 341 break;