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