If an EST frequency table isn't found, fake one up by interpolating
values from the high/low voltages and frequencies. Replaces the old method of using the lower and upper frequencies only.
This commit is contained in:
parent
0e5ca3d77c
commit
3696d5ed67
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: est.c,v 1.2 2007/07/01 20:12:35 xtraeme Exp $ */
|
/* $NetBSD: est.c,v 1.3 2007/08/06 03:38:49 simonb Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003 Michael Eriksson.
|
* Copyright (c) 2003 Michael Eriksson.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -86,7 +86,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.2 2007/07/01 20:12:35 xtraeme Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: est.c,v 1.3 2007/08/06 03:38:49 simonb Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -999,8 +999,8 @@ static const struct fqlist est_cpus[] = {
|
||||||
#define MSR2MHZ(msr, bus) ((MSR2FREQINC((msr)) * (bus) + 50) / 100)
|
#define MSR2MHZ(msr, bus) ((MSR2FREQINC((msr)) * (bus) + 50) / 100)
|
||||||
#define MSR2MV(msr) (MSR2VOLTINC(msr) * 16 + 700)
|
#define MSR2MV(msr) (MSR2VOLTINC(msr) * 16 + 700)
|
||||||
|
|
||||||
static const struct fqlist *est_fqlist; /* not NULL if functional */
|
static const struct fqlist *est_fqlist; /* not NULL if functional */
|
||||||
static uint16_t fake_table[3]; /* guessed est_cpu table */
|
static uint16_t *fake_table; /* guessed est_cpu table */
|
||||||
static struct fqlist fake_fqlist;
|
static struct fqlist fake_fqlist;
|
||||||
static int est_node_target, est_node_current;
|
static int est_node_target, est_node_current;
|
||||||
static const char est_desc[] = "Enhanced SpeedStep";
|
static const char est_desc[] = "Enhanced SpeedStep";
|
||||||
|
@ -1159,6 +1159,9 @@ est_init_main(int vendor)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (est_fqlist == NULL) {
|
if (est_fqlist == NULL) {
|
||||||
|
int j, tablesize, freq, volt;
|
||||||
|
int minfreq, minvolt, maxfreq, maxvolt, freqinc, voltinc;
|
||||||
|
|
||||||
aprint_normal("%s: unknown Enhanced SpeedStep CPU.\n",
|
aprint_normal("%s: unknown Enhanced SpeedStep CPU.\n",
|
||||||
cpuname);
|
cpuname);
|
||||||
|
|
||||||
|
@ -1168,24 +1171,64 @@ est_init_main(int vendor)
|
||||||
*/
|
*/
|
||||||
if (idhi == idlo)
|
if (idhi == idlo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef EST_DEBUG
|
||||||
|
printf("%s: bus_clock = %d\n", __FUNCTION__, bus_clock);
|
||||||
|
printf("%s: idlo = 0x%x\n", __FUNCTION__, idlo);
|
||||||
|
printf("%s: lo %4d mV, %4d MHz\n", __FUNCTION__,
|
||||||
|
MSR2MV(idlo), MSR2MHZ(idlo, bus_clock));
|
||||||
|
printf("%s: raw %4d , %4d \n", __FUNCTION__,
|
||||||
|
(idlo & 0xff), ((idlo >> 8) & 0xff));
|
||||||
|
printf("%s: idhi = 0x%x\n", __FUNCTION__, idhi);
|
||||||
|
printf("%s: hi %4d mV, %4d MHz\n", __FUNCTION__,
|
||||||
|
MSR2MV(idhi), MSR2MHZ(idhi, bus_clock));
|
||||||
|
printf("%s: raw %4d , %4d \n", __FUNCTION__,
|
||||||
|
(idhi & 0xff), ((idhi >> 8) & 0xff));
|
||||||
|
printf("%s: cur = 0x%x\n", __FUNCTION__, cur);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a fake table with the power states we know.
|
* Generate a fake table with the power states we know,
|
||||||
|
* interpolating the voltages and frequencies between the
|
||||||
|
* high and low values. The (milli)voltages are always
|
||||||
|
* rounded up when computing the table.
|
||||||
*/
|
*/
|
||||||
fake_table[0] = idhi;
|
minfreq = MSR2FREQINC(idlo);
|
||||||
if (cur == idhi || cur == idlo) {
|
maxfreq = MSR2FREQINC(idhi);
|
||||||
aprint_normal("%s: using only highest and lowest "
|
minvolt = MSR2VOLTINC(idlo);
|
||||||
"power states.\n", cpuname);
|
maxvolt = MSR2VOLTINC(idhi);
|
||||||
|
freqinc = maxfreq - minfreq;
|
||||||
|
voltinc = maxvolt - minvolt;
|
||||||
|
if (freqinc < voltinc) {
|
||||||
|
tablesize = maxfreq - minfreq + 1;
|
||||||
|
voltinc = voltinc * 100 / freqinc - 1;
|
||||||
|
freqinc = 100;
|
||||||
|
} else {
|
||||||
|
tablesize = maxvolt - minvolt + 1;
|
||||||
|
freqinc = freqinc * 100 / voltinc - 1;
|
||||||
|
voltinc = 100;
|
||||||
|
}
|
||||||
|
|
||||||
fake_table[1] = idlo;
|
fake_table = malloc(tablesize * sizeof(uint16_t), M_DEVBUF,
|
||||||
fake_fqlist.n = 2;
|
M_WAITOK);
|
||||||
} else {
|
fake_fqlist.n = tablesize;
|
||||||
aprint_normal("%s: using only highest, current "
|
|
||||||
"and lowest power states.\n", cpuname);
|
|
||||||
|
|
||||||
fake_table[1] = cur;
|
/* The frequency/voltage table is highest frequency first */
|
||||||
fake_table[2] = idlo;
|
freq = maxfreq * 100;
|
||||||
fake_fqlist.n = 3;
|
volt = maxvolt * 100;
|
||||||
}
|
for (j = 0; j < tablesize; j++) {
|
||||||
|
fake_table[j] = (((freq + 99) / 100) << 8) +
|
||||||
|
(volt + 99) / 100;
|
||||||
|
#ifdef EST_DEBUG
|
||||||
|
printf("%s: fake entry %d: %4d mV, %4d MHz "
|
||||||
|
"MSR*100 mV = %4d freq = %4d\n",
|
||||||
|
__FUNCTION__, j, MSR2MV(fake_table[j]),
|
||||||
|
MSR2MHZ(fake_table[j], bus_clock),
|
||||||
|
freq, volt);
|
||||||
|
#endif /* EST_DEBUG */
|
||||||
|
freq -= freqinc;
|
||||||
|
volt -= voltinc;
|
||||||
|
}
|
||||||
fake_fqlist.vendor = vendor;
|
fake_fqlist.vendor = vendor;
|
||||||
fake_fqlist.table = fake_table;
|
fake_fqlist.table = fake_table;
|
||||||
est_fqlist = &fake_fqlist;
|
est_fqlist = &fake_fqlist;
|
||||||
|
|
Loading…
Reference in New Issue