xref: /freebsd/sys/x86/cpufreq/powernow.c (revision c6989859ae9388eeb46a24fe88f9b8d07101c710)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2004-2005 Bruno Ducrot
5  * Copyright (c) 2004 FUKUDA Nobuhiko <nfukuda@spa.is.uec.ac.jp>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /*
29  * Many thanks to Nate Lawson for his helpful comments on this driver and
30  * to Jung-uk Kim for testing.
31  */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 #include <sys/param.h>
37 #include <sys/bus.h>
38 #include <sys/cpu.h>
39 #include <sys/kernel.h>
40 #include <sys/malloc.h>
41 #include <sys/module.h>
42 #include <sys/pcpu.h>
43 #include <sys/systm.h>
44 
45 #include <machine/pc/bios.h>
46 #include <machine/md_var.h>
47 #include <machine/specialreg.h>
48 #include <machine/cputypes.h>
49 #include <machine/vmparam.h>
50 #include <sys/rman.h>
51 
52 #include <vm/vm.h>
53 #include <vm/pmap.h>
54 
55 #include "cpufreq_if.h"
56 
57 #define PN7_TYPE	0
58 #define PN8_TYPE	1
59 
60 /* Flags for some hardware bugs. */
61 #define A0_ERRATA	0x1	/* Bugs for the rev. A0 of Athlon (K7):
62 				 * Interrupts must be disabled and no half
63 				 * multipliers are allowed */
64 #define PENDING_STUCK	0x2	/* With some buggy chipset and some newer AMD64
65 				 * processor (Rev. G?):
66 				 * the pending bit from the msr FIDVID_STATUS
67 				 * is set forever.  No workaround :( */
68 
69 /* Legacy configuration via BIOS table PSB. */
70 #define PSB_START	0
71 #define PSB_STEP	0x10
72 #define PSB_SIG		"AMDK7PNOW!"
73 #define PSB_LEN		10
74 #define PSB_OFF		0
75 
76 struct psb_header {
77 	char		 signature[10];
78 	uint8_t		 version;
79 	uint8_t		 flags;
80 	uint16_t	 settlingtime;
81 	uint8_t		 res1;
82 	uint8_t		 numpst;
83 } __packed;
84 
85 struct pst_header {
86 	uint32_t	 cpuid;
87 	uint8_t		 fsb;
88 	uint8_t		 maxfid;
89 	uint8_t		 startvid;
90 	uint8_t		 numpstates;
91 } __packed;
92 
93 /*
94  * MSRs and bits used by Powernow technology
95  */
96 #define MSR_AMDK7_FIDVID_CTL		0xc0010041
97 #define MSR_AMDK7_FIDVID_STATUS		0xc0010042
98 
99 /* Bitfields used by K7 */
100 
101 #define PN7_CTR_FID(x)			((x) & 0x1f)
102 #define PN7_CTR_VID(x)			(((x) & 0x1f) << 8)
103 #define PN7_CTR_FIDC			0x00010000
104 #define PN7_CTR_VIDC			0x00020000
105 #define PN7_CTR_FIDCHRATIO		0x00100000
106 #define PN7_CTR_SGTC(x)			(((uint64_t)(x) & 0x000fffff) << 32)
107 
108 #define PN7_STA_CFID(x)			((x) & 0x1f)
109 #define PN7_STA_SFID(x)			(((x) >> 8) & 0x1f)
110 #define PN7_STA_MFID(x)			(((x) >> 16) & 0x1f)
111 #define PN7_STA_CVID(x)			(((x) >> 32) & 0x1f)
112 #define PN7_STA_SVID(x)			(((x) >> 40) & 0x1f)
113 #define PN7_STA_MVID(x)			(((x) >> 48) & 0x1f)
114 
115 /* ACPI ctr_val status register to powernow k7 configuration */
116 #define ACPI_PN7_CTRL_TO_FID(x)		((x) & 0x1f)
117 #define ACPI_PN7_CTRL_TO_VID(x)		(((x) >> 5) & 0x1f)
118 #define ACPI_PN7_CTRL_TO_SGTC(x)	(((x) >> 10) & 0xffff)
119 
120 /* Bitfields used by K8 */
121 
122 #define PN8_CTR_FID(x)			((x) & 0x3f)
123 #define PN8_CTR_VID(x)			(((x) & 0x1f) << 8)
124 #define PN8_CTR_PENDING(x)		(((x) & 1) << 32)
125 
126 #define PN8_STA_CFID(x)			((x) & 0x3f)
127 #define PN8_STA_SFID(x)			(((x) >> 8) & 0x3f)
128 #define PN8_STA_MFID(x)			(((x) >> 16) & 0x3f)
129 #define PN8_STA_PENDING(x)		(((x) >> 31) & 0x01)
130 #define PN8_STA_CVID(x)			(((x) >> 32) & 0x1f)
131 #define PN8_STA_SVID(x)			(((x) >> 40) & 0x1f)
132 #define PN8_STA_MVID(x)			(((x) >> 48) & 0x1f)
133 
134 /* Reserved1 to powernow k8 configuration */
135 #define PN8_PSB_TO_RVO(x)		((x) & 0x03)
136 #define PN8_PSB_TO_IRT(x)		(((x) >> 2) & 0x03)
137 #define PN8_PSB_TO_MVS(x)		(((x) >> 4) & 0x03)
138 #define PN8_PSB_TO_BATT(x)		(((x) >> 6) & 0x03)
139 
140 /* ACPI ctr_val status register to powernow k8 configuration */
141 #define ACPI_PN8_CTRL_TO_FID(x)		((x) & 0x3f)
142 #define ACPI_PN8_CTRL_TO_VID(x)		(((x) >> 6) & 0x1f)
143 #define ACPI_PN8_CTRL_TO_VST(x)		(((x) >> 11) & 0x1f)
144 #define ACPI_PN8_CTRL_TO_MVS(x)		(((x) >> 18) & 0x03)
145 #define ACPI_PN8_CTRL_TO_PLL(x)		(((x) >> 20) & 0x7f)
146 #define ACPI_PN8_CTRL_TO_RVO(x)		(((x) >> 28) & 0x03)
147 #define ACPI_PN8_CTRL_TO_IRT(x)		(((x) >> 30) & 0x03)
148 
149 #define WRITE_FIDVID(fid, vid, ctrl)	\
150 	wrmsr(MSR_AMDK7_FIDVID_CTL,	\
151 	    (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid)))
152 
153 #define COUNT_OFF_IRT(irt)	DELAY(10 * (1 << (irt)))
154 #define COUNT_OFF_VST(vst)	DELAY(20 * (vst))
155 
156 #define FID_TO_VCO_FID(fid)	\
157 	(((fid) < 8) ? (8 + ((fid) << 1)) : (fid))
158 
159 /*
160  * Divide each value by 10 to get the processor multiplier.
161  * Some of those tables are the same as the Linux powernow-k7
162  * implementation by Dave Jones.
163  */
164 static int pn7_fid_to_mult[32] = {
165 	110, 115, 120, 125, 50, 55, 60, 65,
166 	70, 75, 80, 85, 90, 95, 100, 105,
167 	30, 190, 40, 200, 130, 135, 140, 210,
168 	150, 225, 160, 165, 170, 180, 0, 0,
169 };
170 
171 static int pn8_fid_to_mult[64] = {
172 	40, 45, 50, 55, 60, 65, 70, 75,
173 	80, 85, 90, 95, 100, 105, 110, 115,
174 	120, 125, 130, 135, 140, 145, 150, 155,
175 	160, 165, 170, 175, 180, 185, 190, 195,
176 	200, 205, 210, 215, 220, 225, 230, 235,
177 	240, 245, 250, 255, 260, 265, 270, 275,
178 	280, 285, 290, 295, 300, 305, 310, 315,
179 	320, 325, 330, 335, 340, 345, 350, 355,
180 };
181 
182 /*
183  * Units are in mV.
184  */
185 /* Mobile VRM (K7) */
186 static int pn7_mobile_vid_to_volts[] = {
187 	2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
188 	1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
189 	1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
190 	1075, 1050, 1025, 1000, 975, 950, 925, 0,
191 };
192 /* Desktop VRM (K7) */
193 static int pn7_desktop_vid_to_volts[] = {
194 	2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
195 	1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
196 	1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
197 	1075, 1050, 1025, 1000, 975, 950, 925, 0,
198 };
199 /* Desktop and Mobile VRM (K8) */
200 static int pn8_vid_to_volts[] = {
201 	1550, 1525, 1500, 1475, 1450, 1425, 1400, 1375,
202 	1350, 1325, 1300, 1275, 1250, 1225, 1200, 1175,
203 	1150, 1125, 1100, 1075, 1050, 1025, 1000, 975,
204 	950, 925, 900, 875, 850, 825, 800, 0,
205 };
206 
207 #define POWERNOW_MAX_STATES		16
208 
209 struct powernow_state {
210 	int freq;
211 	int power;
212 	int fid;
213 	int vid;
214 };
215 
216 struct pn_softc {
217 	device_t		 dev;
218 	int			 pn_type;
219 	struct powernow_state	 powernow_states[POWERNOW_MAX_STATES];
220 	u_int			 fsb;
221 	u_int			 sgtc;
222 	u_int			 vst;
223 	u_int			 mvs;
224 	u_int			 pll;
225 	u_int			 rvo;
226 	u_int			 irt;
227 	int			 low;
228 	int			 powernow_max_states;
229 	u_int			 powernow_state;
230 	u_int			 errata;
231 	int			*vid_to_volts;
232 };
233 
234 /*
235  * Offsets in struct cf_setting array for private values given by
236  * acpi_perf driver.
237  */
238 #define PX_SPEC_CONTROL		0
239 #define PX_SPEC_STATUS		1
240 
241 static void	pn_identify(driver_t *driver, device_t parent);
242 static int	pn_probe(device_t dev);
243 static int	pn_attach(device_t dev);
244 static int	pn_detach(device_t dev);
245 static int	pn_set(device_t dev, const struct cf_setting *cf);
246 static int	pn_get(device_t dev, struct cf_setting *cf);
247 static int	pn_settings(device_t dev, struct cf_setting *sets,
248 		    int *count);
249 static int	pn_type(device_t dev, int *type);
250 
251 static device_method_t pn_methods[] = {
252 	/* Device interface */
253 	DEVMETHOD(device_identify, pn_identify),
254 	DEVMETHOD(device_probe, pn_probe),
255 	DEVMETHOD(device_attach, pn_attach),
256 	DEVMETHOD(device_detach, pn_detach),
257 
258 	/* cpufreq interface */
259 	DEVMETHOD(cpufreq_drv_set, pn_set),
260 	DEVMETHOD(cpufreq_drv_get, pn_get),
261 	DEVMETHOD(cpufreq_drv_settings, pn_settings),
262 	DEVMETHOD(cpufreq_drv_type, pn_type),
263 	{0, 0}
264 };
265 
266 static devclass_t pn_devclass;
267 static driver_t pn_driver = {
268 	"powernow",
269 	pn_methods,
270 	sizeof(struct pn_softc),
271 };
272 
273 DRIVER_MODULE(powernow, cpu, pn_driver, pn_devclass, 0, 0);
274 
275 static int
276 pn7_setfidvid(struct pn_softc *sc, int fid, int vid)
277 {
278 	int cfid, cvid;
279 	uint64_t status, ctl;
280 
281 	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
282 	cfid = PN7_STA_CFID(status);
283 	cvid = PN7_STA_CVID(status);
284 
285 	/* We're already at the requested level. */
286 	if (fid == cfid && vid == cvid)
287 		return (0);
288 
289 	ctl = rdmsr(MSR_AMDK7_FIDVID_CTL) & PN7_CTR_FIDCHRATIO;
290 
291 	ctl |= PN7_CTR_FID(fid);
292 	ctl |= PN7_CTR_VID(vid);
293 	ctl |= PN7_CTR_SGTC(sc->sgtc);
294 
295 	if (sc->errata & A0_ERRATA)
296 		disable_intr();
297 
298 	if (pn7_fid_to_mult[fid] < pn7_fid_to_mult[cfid]) {
299 		wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC);
300 		if (vid != cvid)
301 			wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC);
302 	} else {
303 		wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC);
304 		if (fid != cfid)
305 			wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC);
306 	}
307 
308 	if (sc->errata & A0_ERRATA)
309 		enable_intr();
310 
311 	return (0);
312 }
313 
314 static int
315 pn8_read_pending_wait(uint64_t *status)
316 {
317 	int i = 10000;
318 
319 	do
320 		*status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
321 	while (PN8_STA_PENDING(*status) && --i);
322 
323 	return (i == 0 ? ENXIO : 0);
324 }
325 
326 static int
327 pn8_write_fidvid(u_int fid, u_int vid, uint64_t ctrl, uint64_t *status)
328 {
329 	int i = 100;
330 
331 	do
332 		WRITE_FIDVID(fid, vid, ctrl);
333 	while (pn8_read_pending_wait(status) && --i);
334 
335 	return (i == 0 ? ENXIO : 0);
336 }
337 
338 static int
339 pn8_setfidvid(struct pn_softc *sc, int fid, int vid)
340 {
341 	uint64_t status;
342 	int cfid, cvid;
343 	int rvo;
344 	int rv;
345 	u_int val;
346 
347 	rv = pn8_read_pending_wait(&status);
348 	if (rv)
349 		return (rv);
350 
351 	cfid = PN8_STA_CFID(status);
352 	cvid = PN8_STA_CVID(status);
353 
354 	if (fid == cfid && vid == cvid)
355 		return (0);
356 
357 	/*
358 	 * Phase 1: Raise core voltage to requested VID if frequency is
359 	 * going up.
360 	 */
361 	while (cvid > vid) {
362 		val = cvid - (1 << sc->mvs);
363 		rv = pn8_write_fidvid(cfid, (val > 0) ? val : 0, 1ULL, &status);
364 		if (rv) {
365 			sc->errata |= PENDING_STUCK;
366 			return (rv);
367 		}
368 		cvid = PN8_STA_CVID(status);
369 		COUNT_OFF_VST(sc->vst);
370 	}
371 
372 	/* ... then raise to voltage + RVO (if required) */
373 	for (rvo = sc->rvo; rvo > 0 && cvid > 0; --rvo) {
374 		/* XXX It's not clear from spec if we have to do that
375 		 * in 0.25 step or in MVS.  Therefore do it as it's done
376 		 * under Linux */
377 		rv = pn8_write_fidvid(cfid, cvid - 1, 1ULL, &status);
378 		if (rv) {
379 			sc->errata |= PENDING_STUCK;
380 			return (rv);
381 		}
382 		cvid = PN8_STA_CVID(status);
383 		COUNT_OFF_VST(sc->vst);
384 	}
385 
386 	/* Phase 2: change to requested core frequency */
387 	if (cfid != fid) {
388 		u_int vco_fid, vco_cfid, fid_delta;
389 
390 		vco_fid = FID_TO_VCO_FID(fid);
391 		vco_cfid = FID_TO_VCO_FID(cfid);
392 
393 		while (abs(vco_fid - vco_cfid) > 2) {
394 			fid_delta = (vco_cfid & 1) ? 1 : 2;
395 			if (fid > cfid) {
396 				if (cfid > 7)
397 					val = cfid + fid_delta;
398 				else
399 					val = FID_TO_VCO_FID(cfid) + fid_delta;
400 			} else
401 				val = cfid - fid_delta;
402 			rv = pn8_write_fidvid(val, cvid,
403 			    sc->pll * (uint64_t) sc->fsb,
404 			    &status);
405 			if (rv) {
406 				sc->errata |= PENDING_STUCK;
407 				return (rv);
408 			}
409 			cfid = PN8_STA_CFID(status);
410 			COUNT_OFF_IRT(sc->irt);
411 
412 			vco_cfid = FID_TO_VCO_FID(cfid);
413 		}
414 
415 		rv = pn8_write_fidvid(fid, cvid,
416 		    sc->pll * (uint64_t) sc->fsb,
417 		    &status);
418 		if (rv) {
419 			sc->errata |= PENDING_STUCK;
420 			return (rv);
421 		}
422 		cfid = PN8_STA_CFID(status);
423 		COUNT_OFF_IRT(sc->irt);
424 	}
425 
426 	/* Phase 3: change to requested voltage */
427 	if (cvid != vid) {
428 		rv = pn8_write_fidvid(cfid, vid, 1ULL, &status);
429 		cvid = PN8_STA_CVID(status);
430 		COUNT_OFF_VST(sc->vst);
431 	}
432 
433 	/* Check if transition failed. */
434 	if (cfid != fid || cvid != vid)
435 		rv = ENXIO;
436 
437 	return (rv);
438 }
439 
440 static int
441 pn_set(device_t dev, const struct cf_setting *cf)
442 {
443 	struct pn_softc *sc;
444 	int fid, vid;
445 	int i;
446 	int rv;
447 
448 	if (cf == NULL)
449 		return (EINVAL);
450 	sc = device_get_softc(dev);
451 
452 	if (sc->errata & PENDING_STUCK)
453 		return (ENXIO);
454 
455 	for (i = 0; i < sc->powernow_max_states; ++i)
456 		if (CPUFREQ_CMP(sc->powernow_states[i].freq / 1000, cf->freq))
457 			break;
458 
459 	fid = sc->powernow_states[i].fid;
460 	vid = sc->powernow_states[i].vid;
461 
462 	rv = ENODEV;
463 
464 	switch (sc->pn_type) {
465 	case PN7_TYPE:
466 		rv = pn7_setfidvid(sc, fid, vid);
467 		break;
468 	case PN8_TYPE:
469 		rv = pn8_setfidvid(sc, fid, vid);
470 		break;
471 	}
472 
473 	return (rv);
474 }
475 
476 static int
477 pn_get(device_t dev, struct cf_setting *cf)
478 {
479 	struct pn_softc *sc;
480 	u_int cfid = 0, cvid = 0;
481 	int i;
482 	uint64_t status;
483 
484 	if (cf == NULL)
485 		return (EINVAL);
486 	sc = device_get_softc(dev);
487 	if (sc->errata & PENDING_STUCK)
488 		return (ENXIO);
489 
490 	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
491 
492 	switch (sc->pn_type) {
493 	case PN7_TYPE:
494 		cfid = PN7_STA_CFID(status);
495 		cvid = PN7_STA_CVID(status);
496 		break;
497 	case PN8_TYPE:
498 		cfid = PN8_STA_CFID(status);
499 		cvid = PN8_STA_CVID(status);
500 		break;
501 	}
502 	for (i = 0; i < sc->powernow_max_states; ++i)
503 		if (cfid == sc->powernow_states[i].fid &&
504 		    cvid == sc->powernow_states[i].vid)
505 			break;
506 
507 	if (i < sc->powernow_max_states) {
508 		cf->freq = sc->powernow_states[i].freq / 1000;
509 		cf->power = sc->powernow_states[i].power;
510 		cf->lat = 200;
511 		cf->volts = sc->vid_to_volts[cvid];
512 		cf->dev = dev;
513 	} else {
514 		memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf));
515 		cf->dev = NULL;
516 	}
517 
518 	return (0);
519 }
520 
521 static int
522 pn_settings(device_t dev, struct cf_setting *sets, int *count)
523 {
524 	struct pn_softc *sc;
525 	int i;
526 
527 	if (sets == NULL|| count == NULL)
528 		return (EINVAL);
529 	sc = device_get_softc(dev);
530 	if (*count < sc->powernow_max_states)
531 		return (E2BIG);
532 	for (i = 0; i < sc->powernow_max_states; ++i) {
533 		sets[i].freq = sc->powernow_states[i].freq / 1000;
534 		sets[i].power = sc->powernow_states[i].power;
535 		sets[i].lat = 200;
536 		sets[i].volts = sc->vid_to_volts[sc->powernow_states[i].vid];
537 		sets[i].dev = dev;
538 	}
539 	*count = sc->powernow_max_states;
540 
541 	return (0);
542 }
543 
544 static int
545 pn_type(device_t dev, int *type)
546 {
547 	if (type == NULL)
548 		return (EINVAL);
549 
550 	*type = CPUFREQ_TYPE_ABSOLUTE;
551 
552 	return (0);
553 }
554 
555 /*
556  * Given a set of pair of fid/vid, and number of performance states,
557  * compute powernow_states via an insertion sort.
558  */
559 static int
560 decode_pst(struct pn_softc *sc, uint8_t *p, int npstates)
561 {
562 	int i, j, n;
563 	struct powernow_state state;
564 
565 	for (i = 0; i < POWERNOW_MAX_STATES; ++i)
566 		sc->powernow_states[i].freq = CPUFREQ_VAL_UNKNOWN;
567 
568 	for (n = 0, i = 0; i < npstates; ++i) {
569 		state.fid = *p++;
570 		state.vid = *p++;
571 		state.power = CPUFREQ_VAL_UNKNOWN;
572 
573 		switch (sc->pn_type) {
574 		case PN7_TYPE:
575 			state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb;
576 			if ((sc->errata & A0_ERRATA) &&
577 			    (pn7_fid_to_mult[state.fid] % 10) == 5)
578 				continue;
579 			break;
580 		case PN8_TYPE:
581 			state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb;
582 			break;
583 		}
584 
585 		j = n;
586 		while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) {
587 			memcpy(&sc->powernow_states[j],
588 			    &sc->powernow_states[j - 1],
589 			    sizeof(struct powernow_state));
590 			--j;
591 		}
592 		memcpy(&sc->powernow_states[j], &state,
593 		    sizeof(struct powernow_state));
594 		++n;
595 	}
596 
597 	/*
598 	 * Fix powernow_max_states, if errata a0 give us less states
599 	 * than expected.
600 	 */
601 	sc->powernow_max_states = n;
602 
603 	if (bootverbose)
604 		for (i = 0; i < sc->powernow_max_states; ++i) {
605 			int fid = sc->powernow_states[i].fid;
606 			int vid = sc->powernow_states[i].vid;
607 
608 			printf("powernow: %2i %8dkHz FID %02x VID %02x\n",
609 			    i,
610 			    sc->powernow_states[i].freq,
611 			    fid,
612 			    vid);
613 		}
614 
615 	return (0);
616 }
617 
618 static int
619 cpuid_is_k7(u_int cpuid)
620 {
621 
622 	switch (cpuid) {
623 	case 0x760:
624 	case 0x761:
625 	case 0x762:
626 	case 0x770:
627 	case 0x771:
628 	case 0x780:
629 	case 0x781:
630 	case 0x7a0:
631 		return (TRUE);
632 	}
633 	return (FALSE);
634 }
635 
636 static int
637 pn_decode_pst(device_t dev)
638 {
639 	int maxpst;
640 	struct pn_softc *sc;
641 	u_int cpuid, maxfid, startvid;
642 	u_long sig;
643 	struct psb_header *psb;
644 	uint8_t *p;
645 	u_int regs[4];
646 	uint64_t status;
647 
648 	sc = device_get_softc(dev);
649 
650 	do_cpuid(0x80000001, regs);
651 	cpuid = regs[0];
652 
653 	if ((cpuid & 0xfff) == 0x760)
654 		sc->errata |= A0_ERRATA;
655 
656 	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
657 
658 	switch (sc->pn_type) {
659 	case PN7_TYPE:
660 		maxfid = PN7_STA_MFID(status);
661 		startvid = PN7_STA_SVID(status);
662 		break;
663 	case PN8_TYPE:
664 		maxfid = PN8_STA_MFID(status);
665 		/*
666 		 * we should actually use a variable named 'maxvid' if K8,
667 		 * but why introducing a new variable for that?
668 		 */
669 		startvid = PN8_STA_MVID(status);
670 		break;
671 	default:
672 		return (ENODEV);
673 	}
674 
675 	if (bootverbose) {
676 		device_printf(dev, "STATUS: 0x%jx\n", status);
677 		device_printf(dev, "STATUS: maxfid: 0x%02x\n", maxfid);
678 		device_printf(dev, "STATUS: %s: 0x%02x\n",
679 		    sc->pn_type == PN7_TYPE ? "startvid" : "maxvid",
680 		    startvid);
681 	}
682 
683 	sig = bios_sigsearch(PSB_START, PSB_SIG, PSB_LEN, PSB_STEP, PSB_OFF);
684 	if (sig) {
685 		struct pst_header *pst;
686 
687 		psb = (struct psb_header*)(uintptr_t)BIOS_PADDRTOVADDR(sig);
688 
689 		switch (psb->version) {
690 		default:
691 			return (ENODEV);
692 		case 0x14:
693 			/*
694 			 * We can't be picky about numpst since at least
695 			 * some systems have a value of 1 and some have 2.
696 			 * We trust that cpuid_is_k7() will be better at
697 			 * catching that we're on a K8 anyway.
698 			 */
699 			if (sc->pn_type != PN8_TYPE)
700 				return (EINVAL);
701 			sc->vst = psb->settlingtime;
702 			sc->rvo = PN8_PSB_TO_RVO(psb->res1);
703 			sc->irt = PN8_PSB_TO_IRT(psb->res1);
704 			sc->mvs = PN8_PSB_TO_MVS(psb->res1);
705 			sc->low = PN8_PSB_TO_BATT(psb->res1);
706 			if (bootverbose) {
707 				device_printf(dev, "PSB: VST: %d\n",
708 				    psb->settlingtime);
709 				device_printf(dev, "PSB: RVO %x IRT %d "
710 				    "MVS %d BATT %d\n",
711 				    sc->rvo,
712 				    sc->irt,
713 				    sc->mvs,
714 				    sc->low);
715 			}
716 			break;
717 		case 0x12:
718 			if (sc->pn_type != PN7_TYPE)
719 				return (EINVAL);
720 			sc->sgtc = psb->settlingtime * sc->fsb;
721 			if (sc->sgtc < 100 * sc->fsb)
722 				sc->sgtc = 100 * sc->fsb;
723 			break;
724 		}
725 
726 		p = ((uint8_t *) psb) + sizeof(struct psb_header);
727 		pst = (struct pst_header*) p;
728 
729 		maxpst = 200;
730 
731 		do {
732 			struct pst_header *pst = (struct pst_header*) p;
733 
734 			if (cpuid == pst->cpuid &&
735 			    maxfid == pst->maxfid &&
736 			    startvid == pst->startvid) {
737 				sc->powernow_max_states = pst->numpstates;
738 				switch (sc->pn_type) {
739 				case PN7_TYPE:
740 					if (abs(sc->fsb - pst->fsb) > 5)
741 						continue;
742 					break;
743 				case PN8_TYPE:
744 					break;
745 				}
746 				return (decode_pst(sc,
747 				    p + sizeof(struct pst_header),
748 				    sc->powernow_max_states));
749 			}
750 
751 			p += sizeof(struct pst_header) + (2 * pst->numpstates);
752 		} while (cpuid_is_k7(pst->cpuid) && maxpst--);
753 
754 		device_printf(dev, "no match for extended cpuid %.3x\n", cpuid);
755 	}
756 
757 	return (ENODEV);
758 }
759 
760 static int
761 pn_decode_acpi(device_t dev, device_t perf_dev)
762 {
763 	int i, j, n;
764 	uint64_t status;
765 	uint32_t ctrl;
766 	u_int cpuid;
767 	u_int regs[4];
768 	struct pn_softc *sc;
769 	struct powernow_state state;
770 	struct cf_setting sets[POWERNOW_MAX_STATES];
771 	int count = POWERNOW_MAX_STATES;
772 	int type;
773 	int rv;
774 
775 	if (perf_dev == NULL)
776 		return (ENXIO);
777 
778 	rv = CPUFREQ_DRV_SETTINGS(perf_dev, sets, &count);
779 	if (rv)
780 		return (ENXIO);
781 	rv = CPUFREQ_DRV_TYPE(perf_dev, &type);
782 	if (rv || (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
783 		return (ENXIO);
784 
785 	sc = device_get_softc(dev);
786 
787 	do_cpuid(0x80000001, regs);
788 	cpuid = regs[0];
789 	if ((cpuid & 0xfff) == 0x760)
790 		sc->errata |= A0_ERRATA;
791 
792 	ctrl = 0;
793 	sc->sgtc = 0;
794 	for (n = 0, i = 0; i < count; ++i) {
795 		ctrl = sets[i].spec[PX_SPEC_CONTROL];
796 		switch (sc->pn_type) {
797 		case PN7_TYPE:
798 			state.fid = ACPI_PN7_CTRL_TO_FID(ctrl);
799 			state.vid = ACPI_PN7_CTRL_TO_VID(ctrl);
800 			if ((sc->errata & A0_ERRATA) &&
801 			    (pn7_fid_to_mult[state.fid] % 10) == 5)
802 				continue;
803 			break;
804 		case PN8_TYPE:
805 			state.fid = ACPI_PN8_CTRL_TO_FID(ctrl);
806 			state.vid = ACPI_PN8_CTRL_TO_VID(ctrl);
807 			break;
808 		}
809 		state.freq = sets[i].freq * 1000;
810 		state.power = sets[i].power;
811 
812 		j = n;
813 		while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) {
814 			memcpy(&sc->powernow_states[j],
815 			    &sc->powernow_states[j - 1],
816 			    sizeof(struct powernow_state));
817 			--j;
818 		}
819 		memcpy(&sc->powernow_states[j], &state,
820 		    sizeof(struct powernow_state));
821 		++n;
822 	}
823 
824 	sc->powernow_max_states = n;
825 	state = sc->powernow_states[0];
826 	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
827 
828 	switch (sc->pn_type) {
829 	case PN7_TYPE:
830 		sc->sgtc = ACPI_PN7_CTRL_TO_SGTC(ctrl);
831 		/*
832 		 * XXX Some bios forget the max frequency!
833 		 * This maybe indicates we have the wrong tables.  Therefore,
834 		 * don't implement a quirk, but fallback to BIOS legacy
835 		 * tables instead.
836 		 */
837 		if (PN7_STA_MFID(status) != state.fid) {
838 			device_printf(dev, "ACPI MAX frequency not found\n");
839 			return (EINVAL);
840 		}
841 		sc->fsb = state.freq / 100 / pn7_fid_to_mult[state.fid];
842 		break;
843 	case PN8_TYPE:
844 		sc->vst = ACPI_PN8_CTRL_TO_VST(ctrl),
845 		sc->mvs = ACPI_PN8_CTRL_TO_MVS(ctrl),
846 		sc->pll = ACPI_PN8_CTRL_TO_PLL(ctrl),
847 		sc->rvo = ACPI_PN8_CTRL_TO_RVO(ctrl),
848 		sc->irt = ACPI_PN8_CTRL_TO_IRT(ctrl);
849 		sc->low = 0; /* XXX */
850 
851 		/*
852 		 * powernow k8 supports only one low frequency.
853 		 */
854 		if (sc->powernow_max_states >= 2 &&
855 		    (sc->powernow_states[sc->powernow_max_states - 2].fid < 8))
856 			return (EINVAL);
857 		sc->fsb = state.freq / 100 / pn8_fid_to_mult[state.fid];
858 		break;
859 	}
860 
861 	return (0);
862 }
863 
864 static void
865 pn_identify(driver_t *driver, device_t parent)
866 {
867 
868 	if ((amd_pminfo & AMDPM_FID) == 0 || (amd_pminfo & AMDPM_VID) == 0)
869 		return;
870 	switch (cpu_id & 0xf00) {
871 	case 0x600:
872 	case 0xf00:
873 		break;
874 	default:
875 		return;
876 	}
877 	if (device_find_child(parent, "powernow", -1) != NULL)
878 		return;
879 	if (BUS_ADD_CHILD(parent, 10, "powernow", -1) == NULL)
880 		device_printf(parent, "powernow: add child failed\n");
881 }
882 
883 static int
884 pn_probe(device_t dev)
885 {
886 	struct pn_softc *sc;
887 	uint64_t status;
888 	uint64_t rate;
889 	struct pcpu *pc;
890 	u_int sfid, mfid, cfid;
891 
892 	sc = device_get_softc(dev);
893 	sc->errata = 0;
894 	status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
895 
896 	pc = cpu_get_pcpu(dev);
897 	if (pc == NULL)
898 		return (ENODEV);
899 
900 	cpu_est_clockrate(pc->pc_cpuid, &rate);
901 
902 	switch (cpu_id & 0xf00) {
903 	case 0x600:
904 		sfid = PN7_STA_SFID(status);
905 		mfid = PN7_STA_MFID(status);
906 		cfid = PN7_STA_CFID(status);
907 		sc->pn_type = PN7_TYPE;
908 		sc->fsb = rate / 100000 / pn7_fid_to_mult[cfid];
909 
910 		/*
911 		 * If start FID is different to max FID, then it is a
912 		 * mobile processor.  If not, it is a low powered desktop
913 		 * processor.
914 		 */
915 		if (PN7_STA_SFID(status) != PN7_STA_MFID(status)) {
916 			sc->vid_to_volts = pn7_mobile_vid_to_volts;
917 			device_set_desc(dev, "PowerNow! K7");
918 		} else {
919 			sc->vid_to_volts = pn7_desktop_vid_to_volts;
920 			device_set_desc(dev, "Cool`n'Quiet K7");
921 		}
922 		break;
923 
924 	case 0xf00:
925 		sfid = PN8_STA_SFID(status);
926 		mfid = PN8_STA_MFID(status);
927 		cfid = PN8_STA_CFID(status);
928 		sc->pn_type = PN8_TYPE;
929 		sc->vid_to_volts = pn8_vid_to_volts;
930 		sc->fsb = rate / 100000 / pn8_fid_to_mult[cfid];
931 
932 		if (PN8_STA_SFID(status) != PN8_STA_MFID(status))
933 			device_set_desc(dev, "PowerNow! K8");
934 		else
935 			device_set_desc(dev, "Cool`n'Quiet K8");
936 		break;
937 	default:
938 		return (ENODEV);
939 	}
940 
941 	return (0);
942 }
943 
944 static int
945 pn_attach(device_t dev)
946 {
947 	int rv;
948 	device_t child;
949 
950 	child = device_find_child(device_get_parent(dev), "acpi_perf", -1);
951 	if (child) {
952 		rv = pn_decode_acpi(dev, child);
953 		if (rv)
954 			rv = pn_decode_pst(dev);
955 	} else
956 		rv = pn_decode_pst(dev);
957 
958 	if (rv != 0)
959 		return (ENXIO);
960 	cpufreq_register(dev);
961 	return (0);
962 }
963 
964 static int
965 pn_detach(device_t dev)
966 {
967 
968 	return (cpufreq_unregister(dev));
969 }
970