Commit ca11b0a7 authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[CPUFREQ] Better handling of revisionKey bits on Longhaul.

We aren't supposed to blindly copy them from another part of the same
register, but instead, only program them with values we know about.
parent 0ad03924
/* /*
* $Id: longhaul.c,v 1.87 2003/02/22 10:23:46 db Exp $ * $Id: longhaul.c,v 1.87 2003/02/22 10:23:46 db Exp $
* *
* (C) 2001 Dave Jones. <davej@suse.de> * (C) 2001-2003 Dave Jones. <davej@suse.de>
* (C) 2002 Padraig Brady. <padraig@antefacto.com> * (C) 2002 Padraig Brady. <padraig@antefacto.com>
* *
* Licensed under the terms of the GNU GPL License version 2. * Licensed under the terms of the GNU GPL License version 2.
...@@ -294,7 +294,6 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -294,7 +294,6 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
{ {
unsigned long lo, hi; unsigned long lo, hi;
unsigned int bits; unsigned int bits;
int revkey;
int vidindex, i; int vidindex, i;
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
...@@ -321,11 +320,11 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -321,11 +320,11 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
switch (longhaul) { switch (longhaul) {
case 1: case 1:
rdmsr (MSR_VIA_BCR2, lo, hi); rdmsr (MSR_VIA_BCR2, lo, hi);
revkey = (lo & 0xf)<<4; /* Rev key. */ /* Enable software clock multiplier */
lo |= (1<<19);
/* desired multiplier */
lo &= ~(1<<23|1<<24|1<<25|1<<26); lo &= ~(1<<23|1<<24|1<<25|1<<26);
lo |= (1<<19); /* Enable software clock multiplier */ lo |= (bits<<23);
lo |= (bits<<23); /* desired multiplier */
lo |= revkey;
wrmsr (MSR_VIA_BCR2, lo, hi); wrmsr (MSR_VIA_BCR2, lo, hi);
__hlt(); __hlt();
...@@ -333,17 +332,17 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -333,17 +332,17 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
/* Disable software clock multiplier */ /* Disable software clock multiplier */
rdmsr (MSR_VIA_BCR2, lo, hi); rdmsr (MSR_VIA_BCR2, lo, hi);
lo &= ~(1<<19); lo &= ~(1<<19);
lo |= revkey;
wrmsr (MSR_VIA_BCR2, lo, hi); wrmsr (MSR_VIA_BCR2, lo, hi);
break; break;
case 2: case 2:
rdmsr (MSR_VIA_LONGHAUL, lo, hi); rdmsr (MSR_VIA_LONGHAUL, lo, hi);
revkey = (lo & 0xf)<<4; /* Rev key. */
lo &= 0xfff0bf0f; /* reset [19:16,14](bus ratio) and [7:4](rev key) to 0 */ lo &= 0xfff0bf0f; /* reset [19:16,14](bus ratio) and [7:4](rev key) to 0 */
lo |= (bits<<16); lo |= (bits<<16);
lo |= (1<<8); /* EnableSoftBusRatio */ lo |= (1<<8); /* EnableSoftBusRatio */
lo |= revkey; /* We must program the revision key only with values we
* know about, not blindly copy it from 0:3 */
lo |= 1;
if (can_scale_voltage) { if (can_scale_voltage) {
/* PB: TODO fix this up */ /* PB: TODO fix this up */
...@@ -374,24 +373,25 @@ static void longhaul_setstate (unsigned int clock_ratio_index) ...@@ -374,24 +373,25 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
lo &= ~(1<<8); lo &= ~(1<<8);
if (can_scale_voltage) if (can_scale_voltage)
lo &= ~(1<<9); lo &= ~(1<<9);
lo |= revkey; lo |= 1; /* Revision Key */
wrmsr (MSR_VIA_LONGHAUL, lo, hi); wrmsr (MSR_VIA_LONGHAUL, lo, hi);
break; break;
case 3: case 3:
rdmsr (MSR_VIA_LONGHAUL, lo, hi); rdmsr (MSR_VIA_LONGHAUL, lo, hi);
revkey = (lo & 0xf)<<4; /* Rev key. */
lo &= 0xfff0bf0f; /* reset longhaul[19:16,14] to 0 */ lo &= 0xfff0bf0f; /* reset longhaul[19:16,14] to 0 */
lo |= (bits<<16); lo |= (bits<<16);
lo |= (1<<8); /* EnableSoftBusRatio */ lo |= (1<<8); /* EnableSoftBusRatio */
lo |= revkey; /* We must program the revision key only with values we
* know about, not blindly copy it from 0:3 */
lo |= 3; /* SoftVID & SoftBSEL */
wrmsr (MSR_VIA_LONGHAUL, lo, hi); wrmsr (MSR_VIA_LONGHAUL, lo, hi);
__hlt(); __hlt();
rdmsr (MSR_VIA_LONGHAUL, lo, hi); rdmsr (MSR_VIA_LONGHAUL, lo, hi);
lo &= ~(1<<8); lo &= ~(1<<8);
lo |= revkey; lo |= 3;
wrmsr (MSR_VIA_LONGHAUL, lo, hi); wrmsr (MSR_VIA_LONGHAUL, lo, hi);
break; break;
} }
...@@ -471,7 +471,6 @@ static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned lon ...@@ -471,7 +471,6 @@ static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned lon
{ {
int revkey; int revkey;
minvid = (hi & (1<<20|1<<21|1<<22|1<<23|1<<24)) >> 20; /* 56:52 */ minvid = (hi & (1<<20|1<<21|1<<22|1<<23|1<<24)) >> 20; /* 56:52 */
maxvid = (hi & (1<<4|1<<5|1<<6|1<<7|1<<8)) >> 4; /* 40:36 */ maxvid = (hi & (1<<4|1<<5|1<<6|1<<7|1<<8)) >> 4; /* 40:36 */
vrmrev = (lo & (1<<15))>>15; vrmrev = (lo & (1<<15))>>15;
...@@ -503,9 +502,9 @@ static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned lon ...@@ -503,9 +502,9 @@ static void __init longhaul_setup_voltagescaling (unsigned long lo, unsigned lon
/* Current voltage isn't readable at first, so we need to /* Current voltage isn't readable at first, so we need to
set it to a known value. The spec says to use maxvid */ set it to a known value. The spec says to use maxvid */
revkey = (lo & 0xf)<<4; /* Rev key. */ revkey = (lo & 0xf)<<4; /* Rev key. */
lo |= revkey; /* Reinsert key FIXME: This is bad. */
lo &= 0xfe0fff0f; /* Mask unneeded bits */ lo &= 0xfe0fff0f; /* Mask unneeded bits */
lo |= (1<<9); /* EnableSoftVID */ lo |= (1<<9); /* EnableSoftVID */
lo |= revkey; /* Reinsert key */
lo |= maxvid << 20; lo |= maxvid << 20;
wrmsr (MSR_VIA_LONGHAUL, lo, hi); wrmsr (MSR_VIA_LONGHAUL, lo, hi);
minvid = voltage_table[minvid]; minvid = voltage_table[minvid];
......
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