summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-01-20 20:23:58 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-01-20 20:23:58 +0000
commitc46ae44564992ec1fafca7eff36efd91f0849593 (patch)
tree68963adb1fcc92a0b700cf7e6a3cfea4c28e084b /sys
parentb861f9f3fbe15a4432a4d54b195d2c85b1ee596c (diff)
Add workaround for broken ATI southbridges; inspired by how Linux handles this.
Fixes PR 5916 & 5959. ok toby@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpihpet.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/sys/dev/acpi/acpihpet.c b/sys/dev/acpi/acpihpet.c
index 1a44c1812d3..087fc29a62e 100644
--- a/sys/dev/acpi/acpihpet.c
+++ b/sys/dev/acpi/acpihpet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpihpet.c,v 1.6 2008/06/11 04:42:09 marco Exp $ */
+/* $OpenBSD: acpihpet.c,v 1.7 2009/01/20 20:23:57 kettenis Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -91,6 +91,7 @@ acpihpet_attach(struct device *parent, struct device *self, void *aux)
struct acpi_hpet *hpet = (struct acpi_hpet *)aaa->aaa_table;
u_int64_t period, freq; /* timer period in femtoseconds (10^-15) */
u_int32_t v1, v2;
+ int timeout;
if (acpi_map_address(psc, &hpet->base_address, 0, HPET_REG_SIZE,
&sc->sc_ioh, &sc->sc_iot)) {
@@ -98,6 +99,26 @@ acpihpet_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ /*
+ * Revisions 0x30 through 0x3a of the AMD SB700, with spread
+ * spectrum enabled, have an SMM based HPET emulation that's
+ * subtly broken. The hardware is initialized upon first
+ * access of the configuration register. Initialization takes
+ * some time during which the configuration register returns
+ * 0xffffffff.
+ */
+ timeout = 1000;
+ do {
+ if (bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+ HPET_CONFIGURATION) != 0xffffffff)
+ break;
+ } while(--timeout > 0);
+
+ if (timeout == 0) {
+ printf(": disabled\n");
+ return;
+ }
+
/* enable hpet */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 1);