Re: [PATCH/RFC] Enable HPET on VIA8237 southbridge

From: Clemens Ladisch
Date: Wed Sep 28 2005 - 02:03:58 EST


Karsten Wiese wrote:
> Am Montag, 26. September 2005 17:49 schrieb Clemens Ladisch:
> > Karsten Wiese wrote:
> > > if you have that chip on your mainboard and want to play with it's
> > > hpet, this might get you going.
> >
> > I'm using similar code for my ICH5 southbridge, but I patched
> > arch/i386/kernel/acpi/boot.c instead so that the kernel can use it
> > for its own purposes.
>
> The kernel uses the hpet here too with my patch.

Uh, yes. I wasn't sure where I could add a hook to be called early
enough so that the assignment to hpet_address still takes effect, so I
just unconditionally replaced acpi_parse_hpet.

> Please send me your acpi/boot.c patch.

Attached.

> I guess you setup an ACPI_HPET entry, if none has been found?

This would be a good idea for a patch that would have any chance of
being applied to the kernel.

> Maybe your approach is safer/better,

You didn't yet see it ... ;-)


Regards,
Clemens
Index: linux-2.6.13/arch/i386/kernel/acpi/boot.c
===================================================================
--- linux-2.6.13.orig/arch/i386/kernel/acpi/boot.c 2005-08-30 19:21:00.000000000 +0200
+++ linux-2.6.13/arch/i386/kernel/acpi/boot.c 2005-09-27 21:18:03.000000000 +0200
@@ -591,6 +591,7 @@ static int __init acpi_parse_sbf(unsigne

#ifdef CONFIG_HPET_TIMER

+#if 0
static int __init acpi_parse_hpet(unsigned long phys, unsigned long size)
{
struct acpi_table_hpet *hpet_tbl;
@@ -628,8 +629,41 @@ static int __init acpi_parse_hpet(unsign

return 0;
}
+#endif
+
+static u32 __init read_pci_config_32(u32 address)
+{
+ outl(address, 0xcf8);
+ return inl(0xcfc);
+}
+
+static void __init write_pci_config_32(u32 address, u32 value)
+{
+ outl(address, 0xcf8);
+ outl(value, 0xcfc);
+}
+
+#define PCIADDR(bus, dev, fn, reg) (0x80000000 | (bus << 16) | (dev << 11) | (fn << 8) | reg)
+
+static void __init hack_hpet(void)
+{
+ extern unsigned long hpet_address;
+ void __iomem *hpet;
+
+ u32 cfg = read_pci_config_32(PCIADDR(0, 31, 0, 0xd0));
+ cfg &= ~0x00018000; /* set address */
+ cfg |= 0x00020000; /* enable */
+ write_pci_config_32(PCIADDR(0, 31, 0, 0xd0), cfg);
+
+ hpet = __acpi_map_table(0xfed00000, 0x400);
+ writel(0x00000002, hpet + 0x10); /* legacy routing */
+ writel(0x00001600, hpet + 0x140); /* timer 2: interrupt 11 */
+ hpet_address = 0xfed00000;
+ printk(KERN_INFO PREFIX "HPET hack enabled, base: %#lx\n", hpet_address);
+}
#else
#define acpi_parse_hpet NULL
+#define hack_hpet()
#endif

#ifdef CONFIG_X86_PM_TIMER
@@ -1164,7 +1198,7 @@ int __init acpi_boot_init(void)
*/
acpi_process_madt();

- acpi_table_parse(ACPI_HPET, acpi_parse_hpet);
+ hack_hpet();

return 0;
}