Annotation of sys/arch/i386/pci/gscpm.c, Revision 1.1.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