This source file includes following definitions.
- ichpcib_match
- ichpcib_attach
- ichss_present
- ichss_setperf
- ichpcib_get_timecount
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include <sys/param.h>
26 #include <sys/systm.h>
27 #include <sys/device.h>
28 #include <sys/sysctl.h>
29 #ifdef __HAVE_TIMECOUNTER
30 #include <sys/timetc.h>
31 #endif
32
33 #include <machine/bus.h>
34
35 #include <dev/pci/pcireg.h>
36 #include <dev/pci/pcivar.h>
37 #include <dev/pci/pcidevs.h>
38
39 #include <dev/pci/ichreg.h>
40
41 #include <machine/cpu.h>
42 #include <machine/cpufunc.h>
43
44 struct ichpcib_softc {
45 struct device sc_dev;
46
47 bus_space_tag_t sc_pm_iot;
48 bus_space_handle_t sc_pm_ioh;
49 };
50
51 int ichpcib_match(struct device *, void *, void *);
52 void ichpcib_attach(struct device *, struct device *, void *);
53
54 int ichss_present(struct pci_attach_args *);
55 void ichss_setperf(int);
56
57
58 void pcibattach(struct device *, struct device *, void *);
59
60 #ifdef __HAVE_TIMECOUNTER
61 u_int ichpcib_get_timecount(struct timecounter *tc);
62
63 struct timecounter ichpcib_timecounter = {
64 ichpcib_get_timecount,
65 0,
66 0xffffff,
67 3579545,
68 "ICHPM",
69 1000
70 };
71 #endif
72
73 struct cfattach ichpcib_ca = {
74 sizeof(struct ichpcib_softc),
75 ichpcib_match,
76 ichpcib_attach
77 };
78
79 struct cfdriver ichpcib_cd = {
80 NULL, "ichpcib", DV_DULL
81 };
82
83 #ifndef SMALL_KERNEL
84 static const char p4hint[] = "Mobile Intel(R) Pentium(R) 4";
85 struct ichpcib_softc *ichss_sc;
86 extern int setperf_prio;
87 #endif
88
89 const struct pci_matchid ichpcib_devices[] = {
90 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_6300ESB_LPC },
91 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_6321ESB_LPC },
92 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AA_LPC },
93 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801AB_LPC },
94 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BA_LPC },
95 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801BAM_LPC },
96 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CA_LPC },
97 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801CAM_LPC },
98 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DB_LPC },
99 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801DBM_LPC },
100 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801E_LPC },
101 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801EB_LPC },
102 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FB_LPC },
103 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801FBM_LPC },
104 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GB_LPC },
105 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GBM_LPC },
106 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GH_LPC },
107 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801GHM_LPC },
108 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801H_LPC },
109 { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801HBM_LPC }
110 };
111
112 int
113 ichpcib_match(struct device *parent, void *match, void *aux)
114 {
115 if (pci_matchbyid((struct pci_attach_args *)aux, ichpcib_devices,
116 sizeof(ichpcib_devices) / sizeof(ichpcib_devices[0])))
117 return (2);
118 return (0);
119 }
120
121 void
122 ichpcib_attach(struct device *parent, struct device *self, void *aux)
123 {
124 struct ichpcib_softc *sc = (struct ichpcib_softc *)self;
125 struct pci_attach_args *pa = aux;
126 pcireg_t cntl, pmbase;
127
128
129 cntl = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_ACPI_CNTL);
130 if ((cntl & ICH_ACPI_CNTL_ACPI_EN) == 0) {
131 printf(": PM disabled");
132 goto corepcib;
133 }
134
135
136 sc->sc_pm_iot = pa->pa_iot;
137 pmbase = pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_PMBASE);
138 if (bus_space_map(sc->sc_pm_iot, PCI_MAPREG_IO_ADDR(pmbase),
139 ICH_PMSIZE, 0, &sc->sc_pm_ioh) != 0)
140 goto corepcib;
141
142 #ifdef __HAVE_TIMECOUNTER
143
144 ichpcib_timecounter.tc_priv = sc;
145 tc_init(&ichpcib_timecounter);
146
147 printf(": %s-bit timer at %lluHz",
148 (ichpcib_timecounter.tc_counter_mask == 0xffffffff ? "32" : "24"),
149 (unsigned long long)ichpcib_timecounter.tc_frequency);
150 #endif
151
152 #ifndef SMALL_KERNEL
153
154 if (ichss_present(pa)) {
155 printf(": SpeedStep");
156
157
158 pci_conf_write(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1,
159 pci_conf_read(pa->pa_pc, pa->pa_tag, ICH_GEN_PMCON1) |
160 ICH_GEN_PMCON1_SS_EN);
161
162
163 ichss_sc = sc;
164 cpu_setperf = ichss_setperf;
165 setperf_prio = 2;
166 }
167 #endif
168
169 corepcib:
170
171 pcibattach(parent, self, aux);
172 }
173
174 #ifndef SMALL_KERNEL
175 int
176 ichss_present(struct pci_attach_args *pa)
177 {
178 pcitag_t br_tag;
179 pcireg_t br_id, br_class;
180 struct cpu_info *ci;
181 int family, model, stepping, brandid;
182
183 if (setperf_prio > 2)
184 return (0);
185
186 ci = curcpu();
187 family = (ci->ci_signature >> 8) & 15;
188 model = (ci->ci_signature >> 4) & 15;
189 stepping = ci->ci_signature & 15;
190 brandid = cpu_miscinfo & 0xff;
191
192
193
194
195
196
197
198
199
200 if (!(family == 15 && model == 2 &&
201 ((stepping == 4 && (brandid == 14 || brandid == 15)) ||
202 (stepping == 7 && brandid == 14) ||
203 (stepping == 9 && (brandid == 14 || strncasecmp(cpu_model, p4hint,
204 sizeof(p4hint) - 1) == 0)))))
205 return (0);
206
207 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801DBM_LPC ||
208 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801CAM_LPC)
209 return (1);
210 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_LPC) {
211
212
213
214
215
216
217
218
219
220 br_tag = pci_make_tag(pa->pa_pc, pa->pa_bus, 0, 0);
221 br_id = pci_conf_read(pa->pa_pc, br_tag, PCI_ID_REG);
222 br_class = pci_conf_read(pa->pa_pc, br_tag, PCI_CLASS_REG);
223
224 if (PCI_PRODUCT(br_id) == PCI_PRODUCT_INTEL_82815_FULL_HUB &&
225 PCI_REVISION(br_class) < 5)
226 return (0);
227 return (1);
228 }
229
230 return (0);
231 }
232
233 void
234 ichss_setperf(int level)
235 {
236 struct ichpcib_softc *sc = ichss_sc;
237 u_int8_t state, ostate, cntl;
238 int s;
239
240 #ifdef DIAGNOSTIC
241 if (sc == NULL) {
242 printf("%s: no ichss_sc", __func__);
243 return;
244 }
245 #endif
246
247 s = splhigh();
248 state = bus_space_read_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_SS_CNTL);
249 ostate = state;
250
251
252 if (level <= 50)
253 state |= ICH_PM_SS_STATE_LOW;
254 else
255 state &= ~ICH_PM_SS_STATE_LOW;
256
257
258
259
260
261
262
263 if (state != ostate) {
264
265 cntl = bus_space_read_1(sc->sc_pm_iot, sc->sc_pm_ioh,
266 ICH_PM_CNTL);
267 bus_space_write_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_CNTL,
268 cntl | ICH_PM_ARB_DIS);
269
270
271 bus_space_write_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_SS_CNTL,
272 state);
273
274
275 bus_space_write_1(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_CNTL,
276 cntl);
277
278 #ifdef I686_CPU
279 if (update_cpuspeed != NULL)
280 update_cpuspeed();
281 #endif
282 }
283 splx(s);
284 }
285 #endif
286
287 #ifdef __HAVE_TIMECOUNTER
288 u_int
289 ichpcib_get_timecount(struct timecounter *tc)
290 {
291 struct ichpcib_softc *sc = tc->tc_priv;
292 u_int u1, u2, u3;
293
294 u2 = bus_space_read_4(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_TMR);
295 u3 = bus_space_read_4(sc->sc_pm_iot, sc->sc_pm_ioh, ICH_PM_TMR);
296 do {
297 u1 = u2;
298 u2 = u3;
299 u3 = bus_space_read_4(sc->sc_pm_iot, sc->sc_pm_ioh,
300 ICH_PM_TMR);
301 } while (u1 > u2 || u2 > u3);
302
303 return (u2);
304 }
305 #endif