diff options
Diffstat (limited to 'sys/arch/i386')
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 26 | ||||
-rw-r--r-- | sys/arch/i386/i386/powernow-k7.c | 87 | ||||
-rw-r--r-- | sys/arch/i386/i386/powernow-k8.c | 49 |
3 files changed, 71 insertions, 91 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 2ffa73fe2bb..c2ea26e000f 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.349 2006/03/16 22:23:26 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.350 2006/03/20 12:08:59 dlg Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -1411,28 +1411,22 @@ amd_family6_setup(struct cpu_info *ci) extern void sse2_pagezero(void *, size_t); extern void i686_pagezero(void *, size_t); #if !defined(MULTIPROCESSOR) - u_int regs[4]; + int family = (ci->ci_signature >> 8) & 15; #endif if (cpu_feature & CPUID_SSE2) pagezero = sse2_pagezero; else pagezero = i686_pagezero; + #if !defined(MULTIPROCESSOR) - cpuid(0x80000000, regs); - if (regs[0] > 0x80000007) { - cpuid(0x80000007, regs); - - if (regs[3] & 0x06) { - switch (ci->ci_signature & 0xF00) { - case 0x600: - k7_powernow_init(); - break; - case 0xf00: - k8_powernow_init(); - break; - } - } + switch (family) { + case 6: + k7_powernow_init(); + break; + case 15: + k8_powernow_init(); + break; } #endif #endif diff --git a/sys/arch/i386/i386/powernow-k7.c b/sys/arch/i386/i386/powernow-k7.c index 706384f2005..8e109602803 100644 --- a/sys/arch/i386/i386/powernow-k7.c +++ b/sys/arch/i386/i386/powernow-k7.c @@ -1,4 +1,4 @@ -/* $OpenBSD: powernow-k7.c,v 1.10 2006/03/15 19:56:48 deraadt Exp $ */ +/* $OpenBSD: powernow-k7.c,v 1.11 2006/03/20 12:08:59 dlg Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -67,15 +67,17 @@ #define BIOS_START 0xe0000 #define BIOS_LEN 0x20000 +#define BIOS_STEP 0x16 /* * MSRs and bits used by Powernow technology */ #define MSR_AMDK7_FIDVID_CTL 0xc0010041 #define MSR_AMDK7_FIDVID_STATUS 0xc0010042 +#define AMD_PN_FID_VID 0x06 /* Bitfields used by K7 */ - +#define PN7_PSB_VERSION 0x12 #define PN7_CTR_FID(x) ((x) & 0x1f) #define PN7_CTR_VID(x) (((x) & 0x1f) << 8) #define PN7_CTR_FIDC 0x00010000 @@ -93,8 +95,8 @@ /* * ACPI ctr_val status register to powernow k7 configuration */ -#define ACPI_PN7_CTRL_TO_VID(x) (((x) >> 5) & 0x1f) -#define ACPI_PN7_CTRL_TO_SGTC(x) (((x) >> 10) & 0xffff) +#define PN7_ACPI_CTRL_TO_VID(x) (((x) >> 5) & 0x1f) +#define PN7_ACPI_CTRL_TO_SGTC(x) (((x) >> 10) & 0xffff) #define WRITE_FIDVID(fid, vid, ctrl) \ wrmsr(MSR_AMDK7_FIDVID_CTL, \ @@ -111,31 +113,6 @@ static int k7pnow_fid_to_mult[32] = { 150, 225, 160, 165, 170, 180, -1, -1 }; -/* - * Units are in mV. - */ - -/* - * Mobile VRM (K7) - */ -static int k7pnow_mobile_vid_to_volts[] = { - 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, - 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, - 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, - 1075, 1050, 1025, 1000, 975, 950, 925, 0, -}; - -/* - * Desktop VRM (K7) - */ - -static int k7pnow_desktop_vid_to_volts[] = { - 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, - 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, - 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, - 1075, 1050, 1025, 1000, 975, 950, 925, 0, -}; - #define POWERNOW_MAX_STATES 16 struct k7pnow_state { @@ -150,7 +127,6 @@ struct k7pnow_cpu_state { struct k7pnow_state state_table[POWERNOW_MAX_STATES]; unsigned int n_states; int errata_a0; - int *vid_to_volts; }; struct psb_s { @@ -255,7 +231,7 @@ k7pnow_decode_pst(struct k7pnow_cpu_state * cstate, uint8_t *p, int npst) for (n = 0, i = 0; i < npst; ++i) { state.fid = *p++; state.vid = *p++; - state.freq = 100 * k7pnow_fid_to_mult[state.fid] * cstate->fsb; + state.freq = k7pnow_fid_to_mult[state.fid]/10 * cstate->fsb; if (cstate->errata_a0 && (k7pnow_fid_to_mult[state.fid] % 10) == 5) continue; @@ -293,10 +269,11 @@ k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig, * range for the pst tables; 16 byte blocks */ for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START); - p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p+= 16) { + p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p+= + BIOS_STEP) { if (memcmp(p, "AMDK7PNOW!", 10) == 0) { psb = (struct psb_s *)p; - if (psb->version != 0x12) + if (psb->version != PN7_PSB_VERSION) return 0; cstate->sgtc = psb->ttime * cstate->fsb; @@ -310,20 +287,7 @@ k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig, if (cpusig == pst->signature && fid == pst->fid && vid == pst->vid) { - switch (pst->signature) { - case 0x760: - case 0x761: - case 0x762: - case 0x770: - case 0x771: - case 0x780: - case 0x781: - case 0x7a0: - break; - default: - return 0; - } - + if (abs(cstate->fsb - pst->fsb) > 5) continue; cstate->n_states = pst->n_states; @@ -357,6 +321,14 @@ k7_powernow_init(void) if (!cstate) return; + cpuid(0x80000000, regs); + if (regs[0] < 0x80000007) + return; + + cpuid(0x80000007, regs); + if (!(regs[3] & AMD_PN_FID_VID)) + return; + cpuid(0x80000001, regs); if ((regs[0] & 0xfff) == 0x760) cstate->errata_a0 = TRUE; @@ -368,32 +340,31 @@ k7_powernow_init(void) startvid = PN7_STA_SVID(status); currentfid = PN7_STA_CFID(status); - CPU_CLOCKUPDATE(); - cstate->fsb = pentium_base_tsc / 100000 / k7pnow_fid_to_mult[currentfid]; + cstate->fsb = pentium_mhz / (k7pnow_fid_to_mult[currentfid]/10); /* * If start FID is different to max FID, then it is a * mobile processor. If not, it is a low powered desktop * processor. */ if (maxfid != currentfid) { - cstate->vid_to_volts = k7pnow_mobile_vid_to_volts; techname = "PowerNow! K7"; } else { - cstate->vid_to_volts = k7pnow_desktop_vid_to_volts; techname = "Cool`n'Quiet K7"; } if (k7pnow_states(cstate, ci->ci_signature, maxfid, startvid)) { if (cstate->n_states) { - printf("%s: AMD %s: available states ", - ci->ci_dev.dv_xname, techname); - for (i = 0; i < cstate->n_states; i++) { - state = &cstate->state_table[i]; - printf("%c%d", i==0 ? '(' : ',', - ((state->freq / 100000)+1)*100); + printf("%s: %s %d Mhz: speeds:", + ci->ci_dev.dv_xname, techname, pentium_mhz); + for(i = cstate->n_states; i > 0; i--) { + state = &cstate->state_table[i-1]; + printf(" %d", state->freq); } - printf(")\n"); + printf(" Mhz\n"); + k7pnow_current_state[cpu_number()] = cstate; cpu_setperf = k7_powernow_setperf; + return; } } + free(cstate, M_DEVBUF); } diff --git a/sys/arch/i386/i386/powernow-k8.c b/sys/arch/i386/i386/powernow-k8.c index dd8231eebad..ce41f86bb21 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.7 2006/03/16 02:39:57 dlg Exp $ */ +/* $OpenBSD: powernow-k8.c,v 1.8 2006/03/20 12:08:59 dlg Exp $ */ /* * Copyright (c) 2004 Martin Végiard. @@ -66,12 +66,14 @@ #define BIOS_START 0xe0000 #define BIOS_LEN 0x20000 +#define BIOS_STEP 16 /* * MSRs and bits used by Powernow technology */ #define MSR_AMDK7_FIDVID_CTL 0xc0010041 #define MSR_AMDK7_FIDVID_STATUS 0xc0010042 +#define AMD_PN_FID_VID 0x06 /* Bitfields used by K8 */ @@ -88,29 +90,30 @@ #define PN8_STA_MVID(x) (((x) >> 48) & 0x1f) /* Reserved1 to powernow k8 configuration */ +#define PN8_PSB_VERSION 0x14 #define PN8_PSB_TO_RVO(x) ((x) & 0x03) #define PN8_PSB_TO_IRT(x) (((x) >> 2) & 0x03) #define PN8_PSB_TO_MVS(x) (((x) >> 4) & 0x03) #define PN8_PSB_TO_BATT(x) (((x) >> 6) & 0x03) /* ACPI ctr_val status register to powernow k8 configuration */ -#define ACPI_PN8_CTRL_TO_FID(x) ((x) & 0x3f) -#define ACPI_PN8_CTRL_TO_VID(x) (((x) >> 6) & 0x1f) -#define ACPI_PN8_CTRL_TO_VST(x) (((x) >> 11) & 0x1f) -#define ACPI_PN8_CTRL_TO_MVS(x) (((x) >> 18) & 0x03) -#define ACPI_PN8_CTRL_TO_PLL(x) (((x) >> 20) & 0x7f) -#define ACPI_PN8_CTRL_TO_RVO(x) (((x) >> 28) & 0x03) -#define ACPI_PN8_CTRL_TO_IRT(x) (((x) >> 30) & 0x03) - +#define PN8_ACPI_CTRL_TO_FID(x) ((x) & 0x3f) +#define PN8_ACPI_CTRL_TO_VID(x) (((x) >> 6) & 0x1f) +#define PN8_ACPI_CTRL_TO_VST(x) (((x) >> 11) & 0x1f) +#define PN8_ACPI_CTRL_TO_MVS(x) (((x) >> 18) & 0x03) +#define PN8_ACPI_CTRL_TO_PLL(x) (((x) >> 20) & 0x7f) +#define PN8_ACPI_CTRL_TO_RVO(x) (((x) >> 28) & 0x03) +#define PN8_ACPI_CTRL_TO_IRT(x) (((x) >> 30) & 0x03) + +#define PN8_PLL_LOCK(x) ((x) * 1000/5) #define WRITE_FIDVID(fid, vid, ctrl) \ wrmsr(MSR_AMDK7_FIDVID_CTL, \ (((ctrl) << 32) | (1ULL << 16) | ((vid) << 8) | (fid))) +#define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt))) +#define COUNT_OFF_VST(vst) DELAY(20 * (vst)) -#define COUNT_OFF_IRT(irt) DELAY(10 * (1 << (irt))) -#define COUNT_OFF_VST(vst) DELAY(20 * (vst)) - -#define FID_TO_VCO_FID(fid) \ +#define FID_TO_VCO_FID(fid) \ (((fid) < 8) ? (8 + ((fid) << 1)) : (fid)) #define POWERNOW_MAX_STATES 16 @@ -251,7 +254,8 @@ k8_powernow_setperf(int level) val = FID_TO_VCO_FID(cfid) + 2; } else val = cfid - 2; - WRITE_FIDVID(val, cvid, (uint64_t)cstate->pll * 1000 / 5); + WRITE_FIDVID(val, cvid, (uint64_t) + PN8_PLL_LOCK(cstate->pll)); if (k8pnow_read_pending_wait(&status)) return 1; @@ -261,7 +265,7 @@ k8_powernow_setperf(int level) vco_cfid = FID_TO_VCO_FID(cfid); } - WRITE_FIDVID(fid, cvid, (uint64_t) cstate->pll * 1000 / 5); + WRITE_FIDVID(fid, cvid, (uint64_t) PN8_PLL_LOCK(cstate->pll)); if (k8pnow_read_pending_wait(&status)) return 1; cfid = PN8_STA_CFID(status); @@ -328,10 +332,11 @@ k8pnow_states(struct k8pnow_cpu_state *cstate, uint32_t cpusig, int i; for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START); - p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p += 16) { + p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p += + BIOS_STEP) { if (memcmp(p, "AMDK7PNOW!", 10) == 0) { psb = (struct psb_s *)p; - if (psb->version != 0x14) + if (psb->version != PN8_PSB_VERSION) return 0; cstate->vst = psb->ttime; @@ -369,11 +374,21 @@ k8_powernow_init(void) struct k8pnow_state *state; struct cpu_info * ci; char * techname = NULL; + u_int32_t regs[4]; + ci = curcpu(); if (k8pnow_current_state) return; + cpuid(0x80000000, regs); + if (regs[0] < 0x80000007) + return; + + cpuid(0x80000007, regs); + if (!(regs[3] & AMD_PN_FID_VID)) + return; + cstate = malloc(sizeof(struct k8pnow_cpu_state), M_DEVBUF, M_NOWAIT); if (!cstate) return; |