Deleted Added
full compact
powernow.c (158651) powernow.c (166197)
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

--- 15 unchanged lines hidden (view full) ---

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>
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

--- 15 unchanged lines hidden (view full) ---

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: head/sys/i386/cpufreq/powernow.c 158651 2006-05-16 14:37:58Z phk $");
32__FBSDID("$FreeBSD: head/sys/i386/cpufreq/powernow.c 166197 2007-01-23 19:20:30Z bruno $");
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>

--- 9 unchanged lines hidden (view full) ---

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
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>

--- 9 unchanged lines hidden (view full) ---

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
58/* Legacy configuration via BIOS table PSB. */
59#define PSB_START 0
60#define PSB_STEP 0x10
61#define PSB_SIG "AMDK7PNOW!"
62#define PSB_LEN 10
63#define PSB_OFF 0
64
65struct psb_header {

--- 69 unchanged lines hidden (view full) ---

135#define ACPI_PN8_CTRL_TO_RVO(x) (((x) >> 28) & 0x03)
136#define ACPI_PN8_CTRL_TO_IRT(x) (((x) >> 30) & 0x03)
137
138
139#define WRITE_FIDVID(fid, vid, ctrl) \
140 wrmsr(MSR_AMDK7_FIDVID_CTL, \
141 (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid)))
142
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
74struct psb_header {

--- 69 unchanged lines hidden (view full) ---

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
143#define READ_PENDING_WAIT(status) \
144 do { \
145 (status) = rdmsr(MSR_AMDK7_FIDVID_STATUS); \
146 } while (PN8_STA_PENDING(status))
147
148#define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt)))
149#define COUNT_OFF_VST(vst) DELAY(20 * (vst))
150
151#define FID_TO_VCO_FID(fid) \
152 (((fid) < 8) ? (8 + ((fid) << 1)) : (fid))
153
154/*
155 * Divide each value by 10 to get the processor multiplier.
156 * Some of those tables are the same as the Linux powernow-k7
157 * implementation by Dave Jones.
158 */
159static int pn7_fid_to_mult[32] = {
160 110, 115, 120, 125, 50, 55, 60, 65,
161 70, 75, 80, 85, 90, 95, 100, 105,
162 30, 190, 40, 200, 130, 135, 140, 210,
163 150, 225, 160, 165, 170, 180, 0, 0,
164};
165
166
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 */
163static 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
167static int pn8_fid_to_mult[32] = {
168 40, 50, 60, 70, 80, 90, 100, 110,
169 120, 130, 140, 150, 160, 170, 180, 190,
170 220, 230, 240, 250, 260, 270, 280, 290,
171 300, 310, 320, 330, 340, 350,
171static 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,
172};
173
174/*
175 * Units are in mV.
176 */
177/* Mobile VRM (K7) */
178static int pn7_mobile_vid_to_volts[] = {
179 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,

--- 34 unchanged lines hidden (view full) ---

214 u_int vst;
215 u_int mvs;
216 u_int pll;
217 u_int rvo;
218 u_int irt;
219 int low;
220 int powernow_max_states;
221 u_int powernow_state;
180};
181
182/*
183 * Units are in mV.
184 */
185/* Mobile VRM (K7) */
186static int pn7_mobile_vid_to_volts[] = {
187 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,

--- 34 unchanged lines hidden (view full) ---

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;
222 int errata_a0;
230 u_int errata;
223 int *vid_to_volts;
224};
225
226/*
227 * Offsets in struct cf_setting array for private values given by
228 * acpi_perf driver.
229 */
230#define PX_SPEC_CONTROL 0

--- 49 unchanged lines hidden (view full) ---

280 return (0);
281
282 ctl = rdmsr(MSR_AMDK7_FIDVID_CTL) & PN7_CTR_FIDCHRATIO;
283
284 ctl |= PN7_CTR_FID(fid);
285 ctl |= PN7_CTR_VID(vid);
286 ctl |= PN7_CTR_SGTC(sc->sgtc);
287
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

--- 49 unchanged lines hidden (view full) ---

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
288 if (sc->errata_a0)
296 if (sc->errata & A0_ERRATA)
289 disable_intr();
290
291 if (pn7_fid_to_mult[fid] < pn7_fid_to_mult[cfid]) {
292 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC);
293 if (vid != cvid)
294 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC);
295 } else {
296 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_VIDC);
297 if (fid != cfid)
298 wrmsr(MSR_AMDK7_FIDVID_CTL, ctl | PN7_CTR_FIDC);
299 }
300
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
301 if (sc->errata_a0)
309 if (sc->errata & A0_ERRATA)
302 enable_intr();
303
304 return (0);
305}
306
307static int
310 enable_intr();
311
312 return (0);
313}
314
315static int
316pn8_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
327static int
328pn8_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
339static int
308pn8_setfidvid(struct pn_softc *sc, int fid, int vid)
309{
310 uint64_t status;
311 int cfid, cvid;
312 int rvo;
340pn8_setfidvid(struct pn_softc *sc, int fid, int vid)
341{
342 uint64_t status;
343 int cfid, cvid;
344 int rvo;
345 int rv;
313 u_int val;
314
346 u_int val;
347
315 READ_PENDING_WAIT(status);
348 rv = pn8_read_pending_wait(&status);
349 if (rv)
350 return (rv);
351
316 cfid = PN8_STA_CFID(status);
317 cvid = PN8_STA_CVID(status);
318
319 if (fid == cfid && vid == cvid)
320 return (0);
321
322 /*
323 * Phase 1: Raise core voltage to requested VID if frequency is
324 * going up.
325 */
326 while (cvid > vid) {
327 val = cvid - (1 << sc->mvs);
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);
328 WRITE_FIDVID(cfid, (val > 0) ? val : 0, 1ULL);
329 READ_PENDING_WAIT(status);
364 rv = pn8_write_fidvid(cfid, (val > 0) ? val : 0, 1ULL, &status);
365 if (rv) {
366 sc->errata |= PENDING_STUCK;
367 return (rv);
368 }
330 cvid = PN8_STA_CVID(status);
331 COUNT_OFF_VST(sc->vst);
332 }
333
334 /* ... then raise to voltage + RVO (if required) */
335 for (rvo = sc->rvo; rvo > 0 && cvid > 0; --rvo) {
336 /* XXX It's not clear from spec if we have to do that
337 * in 0.25 step or in MVS. Therefore do it as it's done
338 * under Linux */
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 */
339 WRITE_FIDVID(cfid, cvid - 1, 1ULL);
340 READ_PENDING_WAIT(status);
378 rv = pn8_write_fidvid(cfid, cvid - 1, 1ULL, &status);
379 if (rv) {
380 sc->errata |= PENDING_STUCK;
381 return (rv);
382 }
341 cvid = PN8_STA_CVID(status);
342 COUNT_OFF_VST(sc->vst);
343 }
344
345 /* Phase 2: change to requested core frequency */
346 if (cfid != fid) {
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) {
347 u_int vco_fid, vco_cfid;
389 u_int vco_fid, vco_cfid, fid_delta;
348
349 vco_fid = FID_TO_VCO_FID(fid);
350 vco_cfid = FID_TO_VCO_FID(cfid);
351
352 while (abs(vco_fid - vco_cfid) > 2) {
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;
353 if (fid > cfid) {
396 if (fid > cfid) {
354 if (cfid > 6)
355 val = cfid + 2;
397 if (cfid > 7)
398 val = cfid + fid_delta;
356 else
399 else
357 val = FID_TO_VCO_FID(cfid) + 2;
400 val = FID_TO_VCO_FID(cfid) + fid_delta;
358 } else
401 } else
359 val = cfid - 2;
360 WRITE_FIDVID(val, cvid, sc->pll * (uint64_t) sc->fsb);
361 READ_PENDING_WAIT(status);
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 }
362 cfid = PN8_STA_CFID(status);
363 COUNT_OFF_IRT(sc->irt);
364
365 vco_cfid = FID_TO_VCO_FID(cfid);
366 }
367
410 cfid = PN8_STA_CFID(status);
411 COUNT_OFF_IRT(sc->irt);
412
413 vco_cfid = FID_TO_VCO_FID(cfid);
414 }
415
368 WRITE_FIDVID(fid, cvid, sc->pll * (uint64_t) sc->fsb);
369 READ_PENDING_WAIT(status);
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 }
370 cfid = PN8_STA_CFID(status);
371 COUNT_OFF_IRT(sc->irt);
372 }
373
374 /* Phase 3: change to requested voltage */
375 if (cvid != vid) {
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) {
376 WRITE_FIDVID(cfid, vid, 1ULL);
377 READ_PENDING_WAIT(status);
429 rv = pn8_write_fidvid(cfid, vid, 1ULL, &status);
378 cvid = PN8_STA_CVID(status);
379 COUNT_OFF_VST(sc->vst);
380 }
381
382 /* Check if transition failed. */
383 if (cfid != fid || cvid != vid)
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)
384 return (ENXIO);
436 rv = ENXIO;
385
437
386 return (0);
438 return (rv);
387}
388
389static int
390pn_set(device_t dev, const struct cf_setting *cf)
391{
392 struct pn_softc *sc;
393 int fid, vid;
394 int i;
395 int rv;
396
397 if (cf == NULL)
398 return (EINVAL);
399 sc = device_get_softc(dev);
400
439}
440
441static int
442pn_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
401 for (i = 0; i < sc->powernow_max_states; ++i)
402 if (CPUFREQ_CMP(sc->powernow_states[i].freq / 1000, cf->freq))
403 break;
404
405 fid = sc->powernow_states[i].fid;
406 vid = sc->powernow_states[i].vid;
407
408 rv = ENODEV;

--- 16 unchanged lines hidden (view full) ---

425 struct pn_softc *sc;
426 u_int cfid = 0, cvid = 0;
427 int i;
428 uint64_t status;
429
430 if (cf == NULL)
431 return (EINVAL);
432 sc = device_get_softc(dev);
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;

--- 16 unchanged lines hidden (view full) ---

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);
433
434 status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
435
436 switch (sc->pn_type) {
437 case PN7_TYPE:
438 cfid = PN7_STA_CFID(status);
439 cvid = PN7_STA_CVID(status);
440 break;

--- 71 unchanged lines hidden (view full) ---

512 for (n = 0, i = 0; i < npstates; ++i) {
513 state.fid = *p++;
514 state.vid = *p++;
515 state.power = CPUFREQ_VAL_UNKNOWN;
516
517 switch (sc->pn_type) {
518 case PN7_TYPE:
519 state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb;
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;

--- 71 unchanged lines hidden (view full) ---

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;
520 if (sc->errata_a0 &&
577 if ((sc->errata & A0_ERRATA) &&
521 (pn7_fid_to_mult[state.fid] % 10) == 5)
522 continue;
523 break;
524 case PN8_TYPE:
578 (pn7_fid_to_mult[state.fid] % 10) == 5)
579 continue;
580 break;
581 case PN8_TYPE:
525 state.freq = 100 * pn8_fid_to_mult[state.fid >> 1] *
526 sc->fsb;
582 state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb;
527 break;
528 }
529
530 j = n;
531 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) {
532 memcpy(&sc->powernow_states[j],
533 &sc->powernow_states[j - 1],
534 sizeof(struct powernow_state));
535 --j;
536 }
537 memcpy(&sc->powernow_states[j], &state,
538 sizeof(struct powernow_state));
539 ++n;
540 }
541
542 /*
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 /*
543 * Fix powernow_max_states, if errata_a0 give us less states
599 * Fix powernow_max_states, if errata a0 give us less states
544 * than expected.
545 */
546 sc->powernow_max_states = n;
547
548 if (bootverbose)
549 for (i = 0; i < sc->powernow_max_states; ++i) {
550 int fid = sc->powernow_states[i].fid;
551 int vid = sc->powernow_states[i].vid;

--- 39 unchanged lines hidden (view full) ---

591 uint64_t status;
592
593 sc = device_get_softc(dev);
594
595 do_cpuid(0x80000001, regs);
596 cpuid = regs[0];
597
598 if ((cpuid & 0xfff) == 0x760)
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;

--- 39 unchanged lines hidden (view full) ---

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)
599 sc->errata_a0 = TRUE;
655 sc->errata |= A0_ERRATA;
600
601 status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
602
603 switch (sc->pn_type) {
604 case PN7_TYPE:
605 maxfid = PN7_STA_MFID(status);
606 startvid = PN7_STA_SVID(status);
607 break;

--- 135 unchanged lines hidden (view full) ---

743 if (rv || (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
744 return (ENXIO);
745
746 sc = device_get_softc(dev);
747
748 do_cpuid(0x80000001, regs);
749 cpuid = regs[0];
750 if ((cpuid & 0xfff) == 0x760)
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;

--- 135 unchanged lines hidden (view full) ---

799 if (rv || (type & CPUFREQ_FLAG_INFO_ONLY) == 0)
800 return (ENXIO);
801
802 sc = device_get_softc(dev);
803
804 do_cpuid(0x80000001, regs);
805 cpuid = regs[0];
806 if ((cpuid & 0xfff) == 0x760)
751 sc->errata_a0 = TRUE;
807 sc->errata |= A0_ERRATA;
752
753 ctrl = 0;
754 sc->sgtc = 0;
755 for (n = 0, i = 0; i < count; ++i) {
756 ctrl = sets[i].spec[PX_SPEC_CONTROL];
757 switch (sc->pn_type) {
758 case PN7_TYPE:
759 state.fid = ACPI_PN7_CTRL_TO_FID(ctrl);
760 state.vid = ACPI_PN7_CTRL_TO_VID(ctrl);
808
809 ctrl = 0;
810 sc->sgtc = 0;
811 for (n = 0, i = 0; i < count; ++i) {
812 ctrl = sets[i].spec[PX_SPEC_CONTROL];
813 switch (sc->pn_type) {
814 case PN7_TYPE:
815 state.fid = ACPI_PN7_CTRL_TO_FID(ctrl);
816 state.vid = ACPI_PN7_CTRL_TO_VID(ctrl);
761 if (sc->errata_a0 &&
817 if ((sc->errata & A0_ERRATA) &&
762 (pn7_fid_to_mult[state.fid] % 10) == 5)
763 continue;
764 state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb;
765 break;
766 case PN8_TYPE:
767 state.fid = ACPI_PN8_CTRL_TO_FID(ctrl);
768 state.vid = ACPI_PN8_CTRL_TO_VID(ctrl);
818 (pn7_fid_to_mult[state.fid] % 10) == 5)
819 continue;
820 state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb;
821 break;
822 case PN8_TYPE:
823 state.fid = ACPI_PN8_CTRL_TO_FID(ctrl);
824 state.vid = ACPI_PN8_CTRL_TO_VID(ctrl);
769 state.freq = 100 * pn8_fid_to_mult[state.fid >> 1] *
770 sc->fsb;
825 state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb;
771 break;
772 }
773
774 state.power = sets[i].power;
775
776 j = n;
777 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) {
778 memcpy(&sc->powernow_states[j],

--- 69 unchanged lines hidden (view full) ---

848{
849 struct pn_softc *sc;
850 uint64_t status;
851 uint64_t rate;
852 struct pcpu *pc;
853 u_int sfid, mfid, cfid;
854
855 sc = device_get_softc(dev);
826 break;
827 }
828
829 state.power = sets[i].power;
830
831 j = n;
832 while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) {
833 memcpy(&sc->powernow_states[j],

--- 69 unchanged lines hidden (view full) ---

903{
904 struct pn_softc *sc;
905 uint64_t status;
906 uint64_t rate;
907 struct pcpu *pc;
908 u_int sfid, mfid, cfid;
909
910 sc = device_get_softc(dev);
856 sc->errata_a0 = FALSE;
911 sc->errata = 0;
857 status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
858
859 pc = cpu_get_pcpu(dev);
860 if (pc == NULL)
861 return (ENODEV);
862
863 cpu_est_clockrate(pc->pc_cpuid, &rate);
864

--- 20 unchanged lines hidden (view full) ---

885 break;
886
887 case 0xf00:
888 sfid = PN8_STA_SFID(status);
889 mfid = PN8_STA_MFID(status);
890 cfid = PN8_STA_CFID(status);
891 sc->pn_type = PN8_TYPE;
892 sc->vid_to_volts = pn8_vid_to_volts;
912 status = rdmsr(MSR_AMDK7_FIDVID_STATUS);
913
914 pc = cpu_get_pcpu(dev);
915 if (pc == NULL)
916 return (ENODEV);
917
918 cpu_est_clockrate(pc->pc_cpuid, &rate);
919

--- 20 unchanged lines hidden (view full) ---

940 break;
941
942 case 0xf00:
943 sfid = PN8_STA_SFID(status);
944 mfid = PN8_STA_MFID(status);
945 cfid = PN8_STA_CFID(status);
946 sc->pn_type = PN8_TYPE;
947 sc->vid_to_volts = pn8_vid_to_volts;
893 sc->fsb = rate / 100000 / pn8_fid_to_mult[cfid >> 1];
948 sc->fsb = rate / 100000 / pn8_fid_to_mult[cfid];
894
895 if (PN8_STA_SFID(status) != PN8_STA_MFID(status))
896 device_set_desc(dev, "PowerNow! K8");
897 else
898 device_set_desc(dev, "Cool`n'Quiet K8");
899 break;
900 default:
901 return (ENODEV);

--- 32 unchanged lines hidden ---
949
950 if (PN8_STA_SFID(status) != PN8_STA_MFID(status))
951 device_set_desc(dev, "PowerNow! K8");
952 else
953 device_set_desc(dev, "Cool`n'Quiet K8");
954 break;
955 default:
956 return (ENODEV);

--- 32 unchanged lines hidden ---