Commit d347dfca authored by Dave Jones's avatar Dave Jones

[CPUFREQ] Make powernow-k7 leap big buildings^Wranges.

When scaling upwards, we need to change the voltage before the frequency.
When scaling downwards, the opposite.
This may fix some of the hangs people have been seeing when jumping
from a low frequency to a very high frequency.
parent 8a36b98f
......@@ -208,13 +208,38 @@ static int get_ranges (unsigned char *pst)
}
static void change_FID(int fid)
{
union msr_fidvidctl fidvidctl;
if (fidvidctl.bits.FID != fid) {
rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
fidvidctl.bits.SGTC = latency;
fidvidctl.bits.FID = fid;
fidvidctl.bits.FIDC = 1;
wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
}
}
static void change_VID(int vid)
{
union msr_fidvidctl fidvidctl;
if (fidvidctl.bits.VID != vid) {
rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
fidvidctl.bits.VID = vid;
fidvidctl.bits.VIDC = 1;
wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
}
}
static void change_speed (unsigned int index)
{
u8 fid, vid;
struct cpufreq_freqs freqs;
union msr_fidvidstatus fidvidstatus;
union msr_fidvidctl fidvidctl;
/* fid are the lower 8 bits of the index we stored into
* the cpufreq frequency table in powernow_decode_bios,
......@@ -228,7 +253,6 @@ static void change_speed (unsigned int index)
rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
freqs.old = fsb * fid_codes[fidvidstatus.bits.CFID] * 100;
freqs.new = powernow_table[index].frequency;
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
......@@ -238,22 +262,16 @@ static void change_speed (unsigned int index)
if (have_a0 == 1) /* A0 errata 5 */
__asm__("\tcli\n");
/* First change the frequency. */
if (fidvidctl.bits.FID != fid) {
rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
fidvidctl.bits.SGTC = latency; /* Stop grant timeout counter */
fidvidctl.bits.FID = fid;
fidvidctl.bits.FIDC = 1;
wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
if (freqs.old > freqs.new) {
/* Going down, so change FID first */
change_FID(fid);
change_VID(vid);
} else {
/* Going up, so change VID first */
change_VID(fid);
change_FID(vid);
}
/* Now change voltage. */
if (fidvidctl.bits.VID != vid) {
rdmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
fidvidctl.bits.VID = vid;
fidvidctl.bits.VIDC = 1;
wrmsrl (MSR_K7_FID_VID_CTL, fidvidctl.val);
}
if (have_a0 == 1)
__asm__("\tsti\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment