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