* Given a set of pair of fid/vid, and number of performance states, * compute powernow_states via an insertion sort. */
| 557 | * compute powernow_states via an insertion sort. |
| 558 | */ |
| 559 | static int |
| 560 | decode_pst(struct pn_softc *sc, uint8_t *p, int npstates) |
| 561 | { |
| 562 | int i, j, n; |
| 563 | struct powernow_state state; |
| 564 | |
| 565 | for (i = 0; i < POWERNOW_MAX_STATES; ++i) |
| 566 | sc->powernow_states[i].freq = CPUFREQ_VAL_UNKNOWN; |
| 567 | |
| 568 | for (n = 0, i = 0; i < npstates; ++i) { |
| 569 | state.fid = *p++; |
| 570 | state.vid = *p++; |
| 571 | state.power = CPUFREQ_VAL_UNKNOWN; |
| 572 | |
| 573 | switch (sc->pn_type) { |
| 574 | case PN7_TYPE: |
| 575 | state.freq = 100 * pn7_fid_to_mult[state.fid] * sc->fsb; |
| 576 | if ((sc->errata & A0_ERRATA) && |
| 577 | (pn7_fid_to_mult[state.fid] % 10) == 5) |
| 578 | continue; |
| 579 | break; |
| 580 | case PN8_TYPE: |
| 581 | state.freq = 100 * pn8_fid_to_mult[state.fid] * sc->fsb; |
| 582 | break; |
| 583 | } |
| 584 | |
| 585 | j = n; |
| 586 | while (j > 0 && sc->powernow_states[j - 1].freq < state.freq) { |
| 587 | memcpy(&sc->powernow_states[j], |
| 588 | &sc->powernow_states[j - 1], |
| 589 | sizeof(struct powernow_state)); |
| 590 | --j; |
| 591 | } |
| 592 | memcpy(&sc->powernow_states[j], &state, |
| 593 | sizeof(struct powernow_state)); |
| 594 | ++n; |
| 595 | } |
| 596 | |
| 597 | /* |
| 598 | * Fix powernow_max_states, if errata a0 give us less states |
| 599 | * than expected. |
| 600 | */ |
| 601 | sc->powernow_max_states = n; |
| 602 | |
| 603 | if (bootverbose) |
| 604 | for (i = 0; i < sc->powernow_max_states; ++i) { |
| 605 | int fid = sc->powernow_states[i].fid; |
| 606 | int vid = sc->powernow_states[i].vid; |
| 607 | |
| 608 | printf("powernow: %2i %8dkHz FID %02x VID %02x\n", |
| 609 | i, |
| 610 | sc->powernow_states[i].freq, |
| 611 | fid, |
| 612 | vid); |
| 613 | } |
| 614 | |
| 615 | return (0); |
| 616 | } |
no test coverage detected