summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2004-05-06 19:47:04 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2004-05-06 19:47:04 +0000
commit3fdbaafa99642aed27b9964bb75af56dfdf6075b (patch)
tree1ec5ae2a3c8dd6222bb2d3e4c16ffb5828b3a66b /sys/arch/i386
parentf6d35be389dbb13c5f8ff1b75b1f4d1ee54dcce7 (diff)
Move speedstep code to a separate ichpcib(4) driver.
It attaches instead of pcib(4) and provides its usual functionality (attaching isa bus) by calling pcibattach() in the attach routine. ok miod deraadt
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/conf/files.i3869
-rw-r--r--sys/arch/i386/pci/ichpcib.c222
-rw-r--r--sys/arch/i386/pci/pcib.c140
3 files changed, 231 insertions, 140 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386
index ae614753b5a..6634d08dff2 100644
--- a/sys/arch/i386/conf/files.i386
+++ b/sys/arch/i386/conf/files.i386
@@ -1,4 +1,4 @@
-# $OpenBSD: files.i386,v 1.113 2004/04/11 18:12:10 deraadt Exp $
+# $OpenBSD: files.i386,v 1.114 2004/05/06 19:47:03 grange Exp $
# $NetBSD: files.i386,v 1.73 1996/05/07 00:58:36 thorpej Exp $
#
# new style config file for i386 architecture
@@ -122,7 +122,12 @@ file arch/i386/pci/geodesc.c geodesc
# PCI-ISA bridge chipsets
device pcib: isabus
attach pcib at pci
-file arch/i386/pci/pcib.c pcib
+file arch/i386/pci/pcib.c pcib | ichpcib
+
+# Intel ICHx/ICHx-M LPC bridges
+device ichpcib: isabus
+attach ichpcib at pci
+file arch/i386/pci/ichpcib.c ichpcib
device hme: ether, ifnet, mii, ifmedia
file dev/ic/hme.c hme
diff --git a/sys/arch/i386/pci/ichpcib.c b/sys/arch/i386/pci/ichpcib.c
new file mode 100644
index 00000000000..7e2aaa69bd4
--- /dev/null
+++ b/sys/arch/i386/pci/ichpcib.c
@@ -0,0 +1,222 @@
+/* $OpenBSD: ichpcib.c,v 1.1 2004/05/06 19:47:03 grange Exp $ */
+/*
+ * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Special driver for the Intel ICHx/ICHx-M LPC bridges that attaches
+ * instead of pcib(4). In addition to the core pcib(4) functionality this
+ * driver provides support for the Intel SpeedStep technology.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/pci/ichreg.h>
+
+struct ichpcib_softc {
+ struct device sc_dev;
+
+ bus_space_tag_t sc_pm_iot;
+ bus_space_handle_t sc_pm_ioh;
+};
+
+int ichpcib_match(struct device *, void *, void *);
+void ichpcib_attach(struct device *, struct device *, void *);
+
+int ichss_present(struct pci_attach_args *);
+int ichss_setperf(int);
+
+/* arch/i386/pci/pcib.c */
+void pcibattach(struct device *, struct device *, void *);
+
+struct cfattach ichpcib_ca = {
+ sizeof(struct ichpcib_softc),
+ ichpcib_match,
+ ichpcib_attach
+};
+
+struct cfdriver ichpcib_cd = {
+ NULL, "ichpcib", DV_DULL
+};
+
+#ifndef SMALL_KERNEL
+static void *ichss_cookie; /* XXX */
+extern int setperf_prio;
+#endif /* !SMALL_KERNEL */
+
+int
+ichpcib_match(struct device *parent, void *match, void *aux)
+{
+ struct pci_attach_args *pa = aux;
+
+ if (PCI_CLASS(pa->pa_class) != PCI_CLASS_BRIDGE ||
+ PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_BRIDGE_ISA) {
+ return (0);
+ }
+
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) {
+ switch (PCI_PRODUCT(pa->pa_id)) {
+ case PCI_PRODUCT_INTEL_82801AA_LPC: /* ICH */
+ case PCI_PRODUCT_INTEL_82801AB_LPC: /* ICH0 */
+ case PCI_PRODUCT_INTEL_82801BA_LPC: /* ICH2 */
+ case PCI_PRODUCT_INTEL_82801BAM_LPC: /* ICH2-M */
+ case PCI_PRODUCT_INTEL_82801CA_LPC: /* ICH3-S */
+ case PCI_PRODUCT_INTEL_82801CAM_LPC: /* ICH3-M */
+ case PCI_PRODUCT_INTEL_82801DB_LPC: /* ICH4 */
+ case PCI_PRODUCT_INTEL_82801DBM_LPC: /* ICH4-M */
+ case PCI_PRODUCT_INTEL_82801EB_LPC: /* ICH5 */
+ return (2); /* supersede pcib(4) */
+ }
+ }
+
+ return (0);
+}
+
+void
+ichpcib_attach(struct device *parent, struct device *self, void *aux)
+{
+#ifndef SMALL_KERNEL
+ struct ichpcib_softc *sc = (struct ichpcib_softc *)self;
+ struct pci_attach_args *pa = aux;
+ pcireg_t pmbase;
+
+ /* Map power management I/O space */
+ sc->sc_pm_iot = pa->pa_iot;
+ pmbase = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_PMBASE);
+ if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(pmbase),
+ ICH_PMSIZE, 0, &sc->sc_pm_ioh) != 0) {
+ printf(": failed to map I/O space");
+ goto corepcib;
+ }
+
+ /* Check for SpeedStep */
+ if (ichss_present(pa)) {
+ printf(": SpeedStep");
+
+ /* Enable SpeedStep */
+ pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1,
+ pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1) |
+ ICH_GEN_PMCON1_SS_EN);
+
+ /* Hook into hw.setperf sysctl */
+ ichss_cookie = sc;
+ cpu_setperf = ichss_setperf;
+ setperf_prio = 2;
+ }
+
+corepcib:
+#endif /* !SMALL_KERNEL */
+ /* Provide core pcib(4) functionality */
+ pcibattach(parent, self, aux);
+}
+
+#ifndef SMALL_KERNEL
+int
+ichss_present(struct pci_attach_args *pa)
+{
+ pcitag_t br_tag;
+ pcireg_t br_id, br_class;
+
+ if (setperf_prio > 2)
+ return (0);
+
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DBM_LPC ||
+ PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC)
+ return (1);
+ if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC) {
+ /*
+ * Old revisions of the 82815 hostbridge found on
+ * Dell Inspirons 8000 and 8100 don't support
+ * SpeedStep.
+ */
+ /*
+ * XXX: dev 0 func 0 is not always a hostbridge,
+ * should be converted to use pchb(4) hook.
+ */
+ br_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, 0, 0);
+ br_id = pci_conf_read(pa->pa_pc, br_tag, PCI_ID_REG);
+ br_class = pci_conf_read(pa->pa_pc, br_tag, PCI_CLASS_REG);
+
+ if (PCI_PRODUCT(br_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB &&
+ PCI_REVISION(br_class) < 5)
+ return (0);
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+ichss_setperf(int level)
+{
+ struct ichpcib_softc *sc = ichss_cookie;
+ u_int8_t state, ostate, cntl;
+ int s;
+
+#ifdef DIAGNOSTIC
+ if (sc == NULL) {
+ printf("%s: no cookie", __func__);
+ return (EFAULT);
+ }
+#endif
+
+ s = splhigh();
+ state = bus_space_read_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_SS_CNTL);
+ ostate = state;
+
+ /* Only two states are available */
+ if (level <= 50)
+ state |= ICH_PM_SS_STATE_LOW;
+ else
+ state &= ~ICH_PM_SS_STATE_LOW;
+
+ /*
+ * An Intel SpeedStep technology transition _always_ occur on
+ * writes to the ICH_PM_SS_CNTL register, even if the value
+ * written is the same as the previous value. So do the write
+ * only if the state has changed.
+ */
+ if (state != ostate) {
+ /* Disable bus mastering arbitration */
+ cntl = bus_space_read_1(sc->sc_pm_iot, sc->sc_pm_ioh,
+ ICH_PM_CNTL);
+ bus_space_write_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_CNTL,
+ cntl | ICH_PM_ARB_DIS);
+
+ /* Do the transition */
+ bus_space_write_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_SS_CNTL,
+ state);
+
+ /* Restore bus mastering arbitration state */
+ bus_space_write_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_CNTL,
+ cntl);
+
+ if (update_cpuspeed != NULL)
+ update_cpuspeed();
+ }
+ splx(s);
+
+ return (0);
+}
+#endif /* !SMALL_KERNEL */
diff --git a/sys/arch/i386/pci/pcib.c b/sys/arch/i386/pci/pcib.c
index 38a13ed68a6..6e4dd57e669 100644
--- a/sys/arch/i386/pci/pcib.c
+++ b/sys/arch/i386/pci/pcib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pcib.c,v 1.14 2004/02/27 21:46:44 grange Exp $ */
+/* $OpenBSD: pcib.c,v 1.15 2004/05/06 19:47:03 grange Exp $ */
/* $NetBSD: pcib.c,v 1.6 1997/06/06 23:29:16 thorpej Exp $ */
/*-
@@ -41,7 +41,6 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
-#include <sys/sysctl.h>
#include <machine/bus.h>
#include <dev/isa/isavar.h>
@@ -51,8 +50,6 @@
#include <dev/pci/pcidevs.h>
-#include <dev/pci/ichreg.h>
-
#include "isa.h"
#include "pcibios.h"
#if NPCIBIOS > 0
@@ -64,28 +61,14 @@ void pcibattach(struct device *, struct device *, void *);
void pcib_callback(struct device *);
int pcib_print(void *, const char *);
-int ichss_match(void *);
-int ichss_attach(struct device *, void *);
-int ichss_setperf(int);
-
-struct pcib_softc {
- struct device sc_dev;
-
- /* For power management capable bridges */
- bus_space_tag_t sc_pmt;
- bus_space_handle_t sc_pmh;
-};
-
struct cfattach pcib_ca = {
- sizeof(struct pcib_softc), pcibmatch, pcibattach
+ sizeof(struct device), pcibmatch, pcibattach
};
struct cfdriver pcib_cd = {
NULL, "pcib", DV_DULL
};
-extern int setperf_prio;
-
int
pcibmatch(parent, match, aux)
struct device *parent;
@@ -123,15 +106,6 @@ pcibattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
-#ifndef SMALL_KERNEL
- /*
- * Detect and activate SpeedStep on ICHx-M chipsets.
- */
- if (setperf_prio < 2 && ichss_match(aux) &&
- ichss_attach(self, aux) == 0)
- printf(": SpeedStep");
-#endif
-
/*
* Cannot attach isa bus now; must postpone for various reasons
*/
@@ -173,113 +147,3 @@ pcib_print(aux, pnp)
printf("isa at %s", pnp);
return (UNCONF);
}
-
-#ifndef SMALL_KERNEL
-static void *ichss_cookie; /* XXX */
-
-int
-ichss_match(void *aux)
-{
- struct pci_attach_args *pa = aux;
- pcitag_t br_tag;
- pcireg_t br_id, br_class;
-
- if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DBM_LPC ||
- PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC)
- return (1);
- if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC) {
- /*
- * Old revisions of the 82815 hostbridge found on
- * Dell Inspirons 8000 and 8100 don't support
- * SpeedStep.
- */
- /* XXX: dev 0 func 0 is not always a hostbridge */
- br_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, 0, 0);
- br_id = pci_conf_read(pa->pa_pc, br_tag, PCI_ID_REG);
- br_class = pci_conf_read(pa->pa_pc, br_tag, PCI_CLASS_REG);
-
- if (PCI_PRODUCT(br_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB &&
- PCI_REVISION(br_class) < 5)
- return (0);
- return (1);
- }
-
- return (0);
-}
-
-int
-ichss_attach(struct device *self, void *aux)
-{
- struct pcib_softc *sc = (struct pcib_softc *)self;
- struct pci_attach_args *pa = aux;
- pcireg_t pmbase;
-
- /* Map power management I/O space */
- sc->sc_pmt = pa->pa_iot;
- pmbase = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_PMBASE);
- if (bus_space_map(sc->sc_pmt, PCI_MAPREG_IO_ADDR(pmbase),
- ICH_PMSIZE, 0, &sc->sc_pmh) != 0)
- return (1);
-
- /* Enable SpeedStep */
- pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1,
- pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1) |
- ICH_GEN_PMCON1_SS_EN);
-
- /* Hook into hw.setperf sysctl */
- ichss_cookie = sc;
- cpu_setperf = ichss_setperf;
- setperf_prio = 2;
-
- return (0);
-}
-
-int
-ichss_setperf(int level)
-{
- struct pcib_softc *sc = ichss_cookie;
- u_int8_t state, ostate, cntl;
- int s;
-
-#ifdef DIAGNOSTIC
- if (sc == NULL) {
- printf("%s: no cookie", __func__);
- return (EFAULT);
- }
-#endif
-
- s = splhigh();
- state = bus_space_read_1(sc->sc_pmt, sc->sc_pmh, ICH_PM_SS_CNTL);
- ostate = state;
-
- /* Only two states are available */
- if (level <= 50)
- state |= ICH_PM_SS_STATE_LOW;
- else
- state &= ~ICH_PM_SS_STATE_LOW;
-
- /*
- * An Intel SpeedStep technology transition _always_ occur on
- * writes to the ICH_PM_SS_CNTL register, even if the value
- * written is the same as the previous value. So do the write
- * only if the state has changed.
- */
- if (state != ostate) {
- /* Disable bus mastering arbitration */
- cntl = bus_space_read_1(sc->sc_pmt, sc->sc_pmh, ICH_PM_CNTL);
- bus_space_write_1(sc->sc_pmt, sc->sc_pmh, ICH_PM_CNTL,
- cntl | ICH_PM_ARB_DIS);
-
- /* Do the transition */
- bus_space_write_1(sc->sc_pmt, sc->sc_pmh, ICH_PM_SS_CNTL,
- state);
-
- /* Restore bus mastering arbitration state */
- bus_space_write_1(sc->sc_pmt, sc->sc_pmh, ICH_PM_CNTL,
- cntl);
- }
- splx(s);
-
- return (0);
-}
-#endif /* !SMALL_KERNEL */