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