root/arch/i386/pci/gscpm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gscpm_match
  2. gscpm_attach
  3. gscpm_get_timecount
  4. gscpm_setperf

    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

/* [<][>][^][v][top][bottom][index][help] */