Annotation of sys/arch/i386/pci/gscpm.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: gscpm.c,v 1.6 2006/12/12 23:14:27 dim Exp $ */
! 2: /*
! 3: * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
! 4: *
! 5: * Permission to use, copy, modify, and distribute this software for any
! 6: * purpose with or without fee is hereby granted, provided that the above
! 7: * copyright notice and this permission notice appear in all copies.
! 8: *
! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
! 16: */
! 17:
! 18: /*
! 19: * National Semiconductor Geode SC1100 SMI/ACPI module.
! 20: */
! 21:
! 22: #include <sys/param.h>
! 23: #include <sys/systm.h>
! 24: #include <sys/device.h>
! 25: #include <sys/kernel.h>
! 26: #include <sys/sysctl.h>
! 27: #ifdef __HAVE_TIMECOUNTER
! 28: #include <sys/timetc.h>
! 29: #endif
! 30:
! 31: #include <machine/bus.h>
! 32:
! 33: #include <dev/pci/pcireg.h>
! 34: #include <dev/pci/pcivar.h>
! 35: #include <dev/pci/pcidevs.h>
! 36:
! 37: #include <i386/pci/gscpmreg.h>
! 38:
! 39: struct gscpm_softc {
! 40: struct device sc_dev;
! 41:
! 42: pci_chipset_tag_t sc_pc;
! 43: pcitag_t sc_tag;
! 44: bus_space_tag_t sc_iot;
! 45: bus_space_handle_t sc_acpi_ioh;
! 46: };
! 47:
! 48: int gscpm_match(struct device *, void *, void *);
! 49: void gscpm_attach(struct device *, struct device *, void *);
! 50:
! 51: void gscpm_setperf(int);
! 52:
! 53: #ifdef __HAVE_TIMECOUNTER
! 54: u_int gscpm_get_timecount(struct timecounter *tc);
! 55:
! 56: struct timecounter gscpm_timecounter = {
! 57: gscpm_get_timecount, /* get_timecount */
! 58: 0, /* no poll_pps */
! 59: 0xffffff, /* counter_mask */
! 60: 3579545, /* frequency */
! 61: "GSCPM", /* name */
! 62: 1000 /* quality */
! 63: };
! 64: #endif /* __HAVE_TIMECOUNTER */
! 65:
! 66: struct cfattach gscpm_ca = {
! 67: sizeof (struct gscpm_softc),
! 68: gscpm_match,
! 69: gscpm_attach
! 70: };
! 71:
! 72: struct cfdriver gscpm_cd = {
! 73: NULL, "gscpm", DV_DULL
! 74: };
! 75:
! 76: #if 0
! 77: static void *gscpm_cookie; /* XXX */
! 78: #endif
! 79:
! 80: int
! 81: gscpm_match(struct device *parent, void *match, void *aux)
! 82: {
! 83: struct pci_attach_args *pa = aux;
! 84:
! 85: if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS &&
! 86: PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_SC1100_SMI)
! 87: return (1);
! 88:
! 89: return (0);
! 90: }
! 91:
! 92: void
! 93: gscpm_attach(struct device *parent, struct device *self, void *aux)
! 94: {
! 95: struct gscpm_softc *sc = (struct gscpm_softc *)self;
! 96: struct pci_attach_args *pa = aux;
! 97: pcireg_t csr, acpibase;
! 98:
! 99: sc->sc_pc = pa->pa_pc;
! 100: sc->sc_tag = pa->pa_tag;
! 101: sc->sc_iot = pa->pa_iot;
! 102:
! 103: /* Enable I/O space */
! 104: csr = pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG);
! 105: pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG,
! 106: csr | PCI_COMMAND_IO_ENABLE);
! 107:
! 108: /* Map ACPI registers */
! 109: acpibase = pci_conf_read(sc->sc_pc, sc->sc_tag, GSCPM_ACPIBASE);
! 110: if (PCI_MAPREG_IO_ADDR(acpibase) == 0 ||
! 111: bus_space_map(sc->sc_iot, PCI_MAPREG_IO_ADDR(acpibase),
! 112: GSCPM_ACPISIZE, 0, &sc->sc_acpi_ioh)) {
! 113: printf(": failed to map ACPI registers\n");
! 114: return;
! 115: }
! 116:
! 117: printf("\n");
! 118:
! 119: #ifdef __HAVE_TIMECOUNTER
! 120: /* Hook into the kern_tc */
! 121: gscpm_timecounter.tc_priv = sc;
! 122: tc_init(&gscpm_timecounter);
! 123: #endif /* __HAVE_TIMECOUNTER */
! 124:
! 125: /* XXX: disabled due to unresolved yet hardware errata */
! 126: #if 0
! 127: /* Hook into the hw.setperf sysctl */
! 128: gscpm_cookie = sc;
! 129: cpu_setperf = gscpm_setperf;
! 130: #endif
! 131:
! 132: }
! 133:
! 134: #ifdef __HAVE_TIMECOUNTER
! 135: u_int
! 136: gscpm_get_timecount(struct timecounter *tc)
! 137: {
! 138: struct gscpm_softc *sc = tc->tc_priv;
! 139:
! 140: return (bus_space_read_4(sc->sc_iot, sc->sc_acpi_ioh, GSCPM_PM_TMR));
! 141: }
! 142: #endif /* __HAVE_TIMECOUNTER */
! 143:
! 144: #if 0
! 145: void
! 146: gscpm_setperf(int level)
! 147: {
! 148: struct gscpm_softc *sc = gscpm_cookie;
! 149: int i;
! 150: u_int32_t pctl;
! 151:
! 152: pctl = bus_space_read_4(sc->sc_iot, sc->sc_acpi_ioh, GSCPM_P_CNT);
! 153:
! 154: if (level == 100) {
! 155: /* 100 is a maximum perfomance, disable throttling */
! 156: pctl &= ~GSCPM_P_CNT_THTEN;
! 157: } else {
! 158: for (i = 0; i < GSCPM_THT_LEVELS; i++)
! 159: if (level >= gscpm_tht[i].level)
! 160: break;
! 161: pctl = (0xf0 | GSCPM_P_CNT_THTEN |
! 162: GSCPM_P_CNT_CLK(gscpm_tht[i].value));
! 163: }
! 164:
! 165: /* Update processor control register */
! 166: bus_space_write_4(sc->sc_iot, sc->sc_acpi_ioh, GSCPM_P_CNT, pctl);
! 167: }
! 168: #endif
CVSweb