diff options
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/powernow-k8.c | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/sys/arch/i386/i386/powernow-k8.c b/sys/arch/i386/i386/powernow-k8.c index af296e02fc3..d2889b9d5e8 100644 --- a/sys/arch/i386/i386/powernow-k8.c +++ b/sys/arch/i386/i386/powernow-k8.c @@ -1,4 +1,4 @@ -/* $OpenBSD: powernow-k8.c,v 1.24 2008/06/15 00:10:47 gwk Exp $ */ +/* $OpenBSD: powernow-k8.c,v 1.25 2008/06/29 03:50:49 gwk Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -88,6 +88,9 @@ #define PN8_ACPI_CTRL_TO_RVO(x) (((x) >> 28) & 0x03) #define PN8_ACPI_CTRL_TO_IRT(x) (((x) >> 30) & 0x03) +#define PN8_PSS_CFID(x) ((x) & 0x3f) +#define PN8_PSS_CVID(x) (((x) >> 6) & 0x1f) + #define PN8_PLL_LOCK(x) ((x) * 1000/5) #define WRITE_FIDVID(fid, vid, ctrl) \ wrmsr(MSR_AMDK7_FIDVID_CTL, \ @@ -138,11 +141,12 @@ struct pst_s { struct k8pnow_cpu_state *k8pnow_current_state = NULL; extern int setperf_prio; +extern int perflevel; int k8pnow_read_pending_wait(uint64_t *); int k8pnow_decode_pst(struct k8pnow_cpu_state *, uint8_t *); -int k8pnow_states(struct k8pnow_cpu_state *, uint32_t, unsigned int, - unsigned int); +int k8pnow_states(struct k8pnow_cpu_state *, uint32_t, unsigned int, unsigned int); +void k8pnow_transition(struct k8pnow_cpu_state *e, int); #if NACPICPU > 0 int k8pnow_acpi_init(struct k8pnow_cpu_state *, uint64_t); @@ -170,10 +174,24 @@ void k8_powernow_setperf(int level) { unsigned int i; + struct k8pnow_cpu_state *cstate; + + cstate = k8pnow_current_state; + + i = ((level * cstate->n_states) + 1) / 101; + if (i >= cstate->n_states) + i = cstate->n_states - 1; + + k8pnow_transition(cstate, i); +} + +void +k8pnow_transition(struct k8pnow_cpu_state *cstate, int level) +{ uint64_t status; - int cfid, cvid, fid = 0, vid = 0, rvo; + int cfid, cvid, fid = 0, vid = 0; + int rvo; u_int val; - struct k8pnow_cpu_state *cstate; /* * We dont do a k8pnow_read_pending_wait here, need to ensure that the @@ -185,13 +203,8 @@ k8_powernow_setperf(int level) cfid = PN8_STA_CFID(status); cvid = PN8_STA_CVID(status); - cstate = k8pnow_current_state; - - i = ((level * cstate->n_states) + 1) / 101; - if (i >= cstate->n_states) - i = cstate->n_states - 1; - fid = cstate->state_table[i].fid; - vid = cstate->state_table[i].vid; + fid = cstate->state_table[level].fid; + vid = cstate->state_table[level].vid; if (fid == cfid && vid == cvid) return; @@ -236,8 +249,7 @@ k8_powernow_setperf(int level) val = FID_TO_VCO_FID(cfid) + 2; } else val = cfid - 2; - WRITE_FIDVID(val, cvid, (uint64_t) - PN8_PLL_LOCK(cstate->pll)); + WRITE_FIDVID(val, cvid, (uint64_t)cstate->pll * 1000 / 5); if (k8pnow_read_pending_wait(&status)) return; @@ -247,7 +259,7 @@ k8_powernow_setperf(int level) vco_cfid = FID_TO_VCO_FID(cfid); } - WRITE_FIDVID(fid, cvid, (uint64_t) PN8_PLL_LOCK(cstate->pll)); + WRITE_FIDVID(fid, cvid, (uint64_t) cstate->pll * 1000 / 5); if (k8pnow_read_pending_wait(&status)) return; cfid = PN8_STA_CFID(status); @@ -264,7 +276,7 @@ k8_powernow_setperf(int level) } if (cfid == fid || cvid == vid) - cpuspeed = cstate->state_table[i].freq; + cpuspeed = cstate->state_table[level].freq; } /* @@ -357,7 +369,8 @@ k8pnow_acpi_states(struct k8pnow_cpu_state * cstate, struct acpicpu_pss * pss, k = -1; for (n = 0; n < cstate->n_states; n++) { - if (status == pss[n].pss_status) + if ((PN8_STA_CFID(status) == PN8_PSS_CFID(pss[n].pss_status)) && + (PN8_STA_CVID(status) == PN8_PSS_CVID(pss[n].pss_status))) k = n; ctrl = pss[n].pss_ctrl; state.fid = PN8_ACPI_CTRL_TO_FID(ctrl); |