summaryrefslogtreecommitdiff
path: root/sys/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386')
-rw-r--r--sys/arch/i386/i386/powernow-k8.c47
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);