Force detect and/or enable HPET on ICH chipsets. This patch just handles the
detection part and following patches use this information.
Signed-off-by: Venkatesh Pallipadi <[email protected]>
Index: linux-2.6.21-rc-mm-hpet/arch/i386/kernel/quirks.c
===================================================================
--- linux-2.6.21-rc-mm-hpet.orig/arch/i386/kernel/quirks.c 2007-02-04 10:44:54.000000000 -0800
+++ linux-2.6.21-rc-mm-hpet/arch/i386/kernel/quirks.c 2007-04-18 11:08:43.000000000 -0700
@@ -6,6 +6,7 @@
#include <asm/pci-direct.h>
#include <asm/genapic.h>
#include <asm/cpu.h>
+#include <asm/hpet.h>
#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI)
static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev)
@@ -97,3 +98,125 @@
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, verify_quirk_intel_irqbalance);
#endif
+
+#if defined(CONFIG_HPET_TIMER)
+unsigned long force_hpet_address;
+
+static void __iomem *rcba_base;
+
+#ifdef CONFIG_PM
+static int force_hpet_resume(struct sys_device *sys_device)
+{
+ u32 val;
+
+ if (!force_hpet_address)
+ return 0;
+
+ if (rcba_base == NULL)
+ BUG();
+
+ /* read the Function Disable register, dword mode only */
+ val = readl(rcba_base + 0x3404);
+ if (!(val & 0x80)) {
+ /* HPET disabled in HPTC. Trying to enable */
+ writel(val | 0x80, rcba_base + 0x3404);
+ }
+
+ val = readl(rcba_base + 0x3404);
+ if (!(val & 0x80))
+ BUG();
+ else
+ printk(KERN_DEBUG "Force enabled HPET at resume\n");
+
+ return 0;
+}
+
+static struct sysdev_class force_hpet_class = {
+ set_kset_name("force_hpet"),
+ .resume = force_hpet_resume,
+};
+
+static struct sys_device force_hpet_device = {
+ .id = 0,
+ .cls = &force_hpet_class,
+};
+#endif
+
+static void ich_force_enable_hpet(struct pci_dev *dev)
+{
+ u32 val, rcba;
+ int err = 0;
+
+ if (hpet_address || force_hpet_address)
+ return;
+
+ pci_read_config_dword(dev, 0xF0, &rcba);
+ rcba &= 0xFFFFC000;
+ if (rcba == 0) {
+ printk(KERN_DEBUG "RCBA disabled. Cannot force enable HPET\n");
+ return;
+ }
+
+ /* use bits 31:14, 16 kB aligned */
+ rcba_base = ioremap_nocache(rcba, 0x4000);
+ if (rcba_base == NULL) {
+ printk(KERN_DEBUG "ioremap failed. Cannot force enable HPET\n");
+ return;
+ }
+
+ /* read the Function Disable register, dword mode only */
+ val = readl(rcba_base + 0x3404);
+
+ if (val & 0x80) {
+ /* HPET is enabled in HPTC. Just not reported by BIOS */
+ val = val & 0x3;
+ force_hpet_address = 0xFED00000 | (val << 12);
+ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+ force_hpet_address);
+ iounmap(rcba_base);
+ return;
+ }
+
+ /* HPET disabled in HPTC. Trying to enable */
+ writel(val | 0x80, rcba_base + 0x3404);
+
+ val = readl(rcba_base + 0x3404);
+ if (!(val & 0x80)) {
+ err = 1;
+ } else {
+ val = val & 0x3;
+ force_hpet_address = 0xFED00000 | (val << 12);
+
+#ifdef CONFIG_PM
+ /* We need to rewrite the PCI space on S3 resume */
+ err = sysdev_class_register(&force_hpet_class);
+ if (!err) {
+ err = sysdev_register(&force_hpet_device);
+ if (err) {
+ sysdev_class_unregister(&force_hpet_class);
+ }
+ }
+#endif
+ }
+
+ if (err) {
+ force_hpet_address = 0;
+ iounmap(rcba_base);
+ printk(KERN_DEBUG "Failed to force enable HPET\n");
+ } else {
+ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+ force_hpet_address);
+ }
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
+ ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
+ ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
+ ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
+ ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
+ ich_force_enable_hpet);
+#endif
On Mon, 7 May 2007 13:31:28 -0700 Venki Pallipadi (VP) wrote:
VP> Force detect and/or enable HPET on ICH chipsets. This patch just handles the
VP> detection part and following patches use this information.
VP>
VP> Signed-off-by: Venkatesh Pallipadi <[email protected]>
Venki,
Is there any reason your patch only enables HPET on ICH6 and beyond? HPET can
be enabled on earlier ICH by setting bit 17 in GEN_CNTL on PCI dev 31, func 0,
offset d0. This seems to work for ICH3/4/5. Are there any errata affecting
these ICHs?
Cheers,
- Udo
--
Dipl.-Inf. Udo Steinberg
Technische Universit?t Dresden http://os.inf.tu-dresden.de/~us15
Institute for System Architecture Tel: +49 351 463 38401
D-01062 Dresden Fax: +49 351 463 38284
On Sunday, May 20, 2007, Udo A. Steinberg wrote:
> On Mon, 7 May 2007 13:31:28 -0700 Venki Pallipadi (VP) wrote:
>
> VP> Force detect and/or enable HPET on ICH chipsets. This patch just
> handles the VP> detection part and following patches use this
> information.
> VP>
> VP> Signed-off-by: Venkatesh Pallipadi <[email protected]>
>
> Venki,
>
> Is there any reason your patch only enables HPET on ICH6 and beyond?
> HPET can be enabled on earlier ICH by setting bit 17 in GEN_CNTL on PCI
> dev 31, func 0, offset d0. This seems to work for ICH3/4/5. Are there
> any errata affecting these ICHs?
I see it documented in the ICH5 datasheet, but that bit is marked reserved
in the ICH3 and ICH4 datasheets... Which docs are you looking at?
Jesse
>-----Original Message-----
>From: Jesse Barnes [mailto:[email protected]]
>Sent: Monday, May 21, 2007 8:46 AM
>To: Udo A. Steinberg
>Cc: Pallipadi, Venkatesh; linux-kernel; Andrew Morton; Thomas
>Gleixner; Andi Kleen; Ingo Molnar; Chris Wright
>Subject: Re: [PATCH 4/8] Force detect and enable HPET on ICH
>
>On Sunday, May 20, 2007, Udo A. Steinberg wrote:
>> On Mon, 7 May 2007 13:31:28 -0700 Venki Pallipadi (VP) wrote:
>>
>> VP> Force detect and/or enable HPET on ICH chipsets. This patch just
>> handles the VP> detection part and following patches use this
>> information.
>> VP>
>> VP> Signed-off-by: Venkatesh Pallipadi
><[email protected]>
>>
>> Venki,
>>
>> Is there any reason your patch only enables HPET on ICH6 and beyond?
>> HPET can be enabled on earlier ICH by setting bit 17 in
>GEN_CNTL on PCI
>> dev 31, func 0, offset d0. This seems to work for ICH3/4/5. Are there
>> any errata affecting these ICHs?
>
>I see it documented in the ICH5 datasheet, but that bit is
>marked reserved
>in the ICH3 and ICH4 datasheets... Which docs are you looking at?
>
>Jesse
The same bits are supported on ICH5 and ICH4M. I am about to
send a patch to add PCIIDs of ICH5 and ICH4M to force_detect.
These bits were reserved on ICH4 though.
Thanks,
Venki
On Mon, 21 May 2007 08:46:03 -0700 Jesse Barnes (JB) wrote:
JB> I see it documented in the ICH5 datasheet, but that bit is marked reserved
JB> in the ICH3 and ICH4 datasheets... Which docs are you looking at?
It's documented for ICH5 only. My experiments on IBM T30 (ICH3) and T41p (ICH4)
laptops show that HPET exists on these chipsets as well and can be enabled the
same way as described in the ICH5 datasheet.
Cheers,
- Udo
--
Dipl.-Inf. Udo Steinberg
Technische Universit?t Dresden http://os.inf.tu-dresden.de/~us15
Institute for System Architecture Tel: +49 351 463 38401
D-01062 Dresden Fax: +49 351 463 38284