Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
b0727d49
Commit
b0727d49
authored
Aug 24, 2004
by
Dave Jones
Browse files
Options
Browse Files
Download
Plain Diff
Merge delerium.codemonkey.org.uk:/mnt/data/src/bk/bk-linus
into delerium.codemonkey.org.uk:/mnt/data/src/bk/cpufreq
parents
5a528e75
db44090b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
85 additions
and
63 deletions
+85
-63
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
+85
-63
No files found.
arch/i386/kernel/cpu/cpufreq/longhaul.c
View file @
b0727d49
...
@@ -38,6 +38,10 @@
...
@@ -38,6 +38,10 @@
#define PFX "longhaul: "
#define PFX "longhaul: "
#define TYPE_LONGHAUL_V1 1
#define TYPE_LONGHAUL_V2 2
#define TYPE_POWERSAVER 3
static
unsigned
int
numscales
=
16
,
numvscales
;
static
unsigned
int
numscales
=
16
,
numvscales
;
static
unsigned
int
fsb
;
static
unsigned
int
fsb
;
static
int
minvid
,
maxvid
;
static
int
minvid
,
maxvid
;
...
@@ -92,7 +96,7 @@ static int longhaul_get_cpu_mult(void)
...
@@ -92,7 +96,7 @@ static int longhaul_get_cpu_mult(void)
rdmsr
(
MSR_IA32_EBL_CR_POWERON
,
lo
,
hi
);
rdmsr
(
MSR_IA32_EBL_CR_POWERON
,
lo
,
hi
);
invalue
=
(
lo
&
(
1
<<
22
|
1
<<
23
|
1
<<
24
|
1
<<
25
))
>>
22
;
invalue
=
(
lo
&
(
1
<<
22
|
1
<<
23
|
1
<<
24
|
1
<<
25
))
>>
22
;
if
(
longhaul_version
==
2
||
longhaul_version
==
3
)
{
if
(
longhaul_version
==
TYPE_LONGHAUL_V2
||
longhaul_version
==
TYPE_POWERSAVER
)
{
if
(
lo
&
(
1
<<
27
))
if
(
lo
&
(
1
<<
27
))
invalue
+=
16
;
invalue
+=
16
;
}
}
...
@@ -101,8 +105,20 @@ static int longhaul_get_cpu_mult(void)
...
@@ -101,8 +105,20 @@ static int longhaul_get_cpu_mult(void)
static
void
do_powersaver
(
union
msr_longhaul
*
longhaul
,
static
void
do_powersaver
(
union
msr_longhaul
*
longhaul
,
unsigned
int
clock_ratio_index
,
int
version
)
unsigned
int
clock_ratio_index
)
{
{
struct
cpuinfo_x86
*
c
=
cpu_data
;
int
version
;
switch
(
c
->
x86_model
)
{
case
8
:
version
=
3
;
break
;
case
9
:
version
=
0xf
;
break
;
default:
return
;
}
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
->
val
);
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
->
val
);
longhaul
->
bits
.
SoftBusRatio
=
clock_ratio_index
&
0xf
;
longhaul
->
bits
.
SoftBusRatio
=
clock_ratio_index
&
0xf
;
longhaul
->
bits
.
SoftBusRatio4
=
(
clock_ratio_index
&
0x10
)
>>
4
;
longhaul
->
bits
.
SoftBusRatio4
=
(
clock_ratio_index
&
0x10
)
>>
4
;
...
@@ -160,7 +176,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
...
@@ -160,7 +176,8 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
* *NB* Until we get voltage scaling working v1 & v2 are the same code.
* *NB* Until we get voltage scaling working v1 & v2 are the same code.
* Longhaul v2 appears in Samuel2 Steppings 1->7 [C5b] and Ezra [C5C]
* Longhaul v2 appears in Samuel2 Steppings 1->7 [C5b] and Ezra [C5C]
*/
*/
case
1
:
case
TYPE_LONGHAUL_V1
:
case
TYPE_LONGHAUL_V2
:
rdmsrl
(
MSR_VIA_BCR2
,
bcr2
.
val
);
rdmsrl
(
MSR_VIA_BCR2
,
bcr2
.
val
);
/* Enable software clock multiplier */
/* Enable software clock multiplier */
bcr2
.
bits
.
ESOFTBF
=
1
;
bcr2
.
bits
.
ESOFTBF
=
1
;
...
@@ -180,26 +197,18 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
...
@@ -180,26 +197,18 @@ static void longhaul_setstate(unsigned int clock_ratio_index)
break
;
break
;
/*
/*
* Longhaul v3 (aka Powersaver). (Ezra-T [C5M])
* Longhaul v3 (aka Powersaver). (Ezra-T [C5M]
& Nehemiah [C5N]
)
* We can scale voltage with this too, but that's currently
* We can scale voltage with this too, but that's currently
* disabled until we come up with a decent 'match freq to voltage'
* disabled until we come up with a decent 'match freq to voltage'
* algorithm.
* algorithm.
* When we add voltage scaling, we will also need to do the
* When we add voltage scaling, we will also need to do the
* voltage/freq setting in order depending on the direction
* voltage/freq setting in order depending on the direction
* of scaling (like we do in powernow-k7.c)
* of scaling (like we do in powernow-k7.c)
*/
* Nehemiah can do FSB scaling too, but this has never been proven
case
2
:
do_powersaver
(
&
longhaul
,
clock_ratio_index
,
3
);
break
;
/*
* Powersaver. (Nehemiah [C5N])
* As for Ezra-T, we don't do voltage yet.
* This can do FSB scaling too, but it has never been proven
* to work in practice.
* to work in practice.
*/
*/
case
3
:
case
TYPE_POWERSAVER
:
do_powersaver
(
&
longhaul
,
clock_ratio_index
,
0xf
);
do_powersaver
(
&
longhaul
,
clock_ratio_index
);
break
;
break
;
}
}
...
@@ -261,7 +270,8 @@ static int __init longhaul_get_ranges(void)
...
@@ -261,7 +270,8 @@ static int __init longhaul_get_ranges(void)
unsigned
int
eblcr_fsb_table_v2
[]
=
{
133
,
100
,
-
1
,
66
};
unsigned
int
eblcr_fsb_table_v2
[]
=
{
133
,
100
,
-
1
,
66
};
switch
(
longhaul_version
)
{
switch
(
longhaul_version
)
{
case
1
:
case
TYPE_LONGHAUL_V1
:
case
TYPE_LONGHAUL_V2
:
/* Ugh, Longhaul v1 didn't have the min/max MSRs.
/* Ugh, Longhaul v1 didn't have the min/max MSRs.
Assume min=3.0x & max = whatever we booted at. */
Assume min=3.0x & max = whatever we booted at. */
minmult
=
30
;
minmult
=
30
;
...
@@ -274,46 +284,49 @@ static int __init longhaul_get_ranges(void)
...
@@ -274,46 +284,49 @@ static int __init longhaul_get_ranges(void)
fsb
=
guess_fsb
();
fsb
=
guess_fsb
();
break
;
break
;
case
2
:
case
TYPE_POWERSAVER
:
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
/* Ezra-T */
if
(
c
->
x86_model
==
8
)
{
invalue
=
longhaul
.
bits
.
MaxMHzBR
;
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
if
(
longhaul
.
bits
.
MaxMHzBR4
)
invalue
=
longhaul
.
bits
.
MaxMHzBR
;
invalue
+=
16
;
if
(
longhaul
.
bits
.
MaxMHzBR4
)
maxmult
=
multipliers
[
invalue
];
invalue
+=
16
;
maxmult
=
multipliers
[
invalue
];
invalue
=
longhaul
.
bits
.
MinMHzBR
;
if
(
longhaul
.
bits
.
MinMHzBR4
==
1
)
invalue
=
longhaul
.
bits
.
MinMHzBR
;
minmult
=
30
;
if
(
longhaul
.
bits
.
MinMHzBR4
==
1
)
else
minmult
=
30
;
minmult
=
multipliers
[
invalue
];
else
minmult
=
multipliers
[
invalue
];
fsb
=
eblcr_fsb_table_v2
[
longhaul
.
bits
.
MaxMHzFSB
];
break
;
case
3
:
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
/*
* TODO: This code works, but raises a lot of questions.
* - Some Nehemiah's seem to have broken Min/MaxMHzBR's.
* We get around this by using a hardcoded multiplier of 5.0x
* for the minimimum speed, and the speed we booted up at for the max.
* This is done in longhaul_get_cpu_mult() by reading the EBLCR register.
* - According to some VIA documentation EBLCR is only
* in pre-Nehemiah C3s. How this still works is a mystery.
* We're possibly using something undocumented and unsupported,
* But it works, so we don't grumble.
*/
minmult
=
50
;
maxmult
=
longhaul_get_cpu_mult
();
/* Starting with the 1.2GHz parts, theres a 200MHz bus. */
if
((
cpu_khz
/
1000
)
>
1200
)
fsb
=
200
;
else
fsb
=
eblcr_fsb_table_v2
[
longhaul
.
bits
.
MaxMHzFSB
];
fsb
=
eblcr_fsb_table_v2
[
longhaul
.
bits
.
MaxMHzFSB
];
break
;
break
;
}
/* Nehemiah */
if
(
c
->
x86_model
==
9
)
{
rdmsrl
(
MSR_VIA_LONGHAUL
,
longhaul
.
val
);
/*
* TODO: This code works, but raises a lot of questions.
* - Some Nehemiah's seem to have broken Min/MaxMHzBR's.
* We get around this by using a hardcoded multiplier of 4.0x
* for the minimimum speed, and the speed we booted up at for the max.
* This is done in longhaul_get_cpu_mult() by reading the EBLCR register.
* - According to some VIA documentation EBLCR is only
* in pre-Nehemiah C3s. How this still works is a mystery.
* We're possibly using something undocumented and unsupported,
* But it works, so we don't grumble.
*/
minmult
=
40
;
maxmult
=
longhaul_get_cpu_mult
();
/* Starting with the 1.2GHz parts, theres a 200MHz bus. */
if
((
cpu_khz
/
1000
)
>
1200
)
fsb
=
200
;
else
fsb
=
eblcr_fsb_table_v2
[
longhaul
.
bits
.
MaxMHzFSB
];
break
;
}
}
}
dprintk
(
KERN_INFO
PFX
"MinMult=%d.%dx MaxMult=%d.%dx
\n
"
,
dprintk
(
KERN_INFO
PFX
"MinMult=%d.%dx MaxMult=%d.%dx
\n
"
,
...
@@ -458,13 +471,13 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
...
@@ -458,13 +471,13 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
switch
(
c
->
x86_model
)
{
switch
(
c
->
x86_model
)
{
case
6
:
case
6
:
cpuname
=
"C3 'Samuel' [C5A]"
;
cpuname
=
"C3 'Samuel' [C5A]"
;
longhaul_version
=
1
;
longhaul_version
=
TYPE_LONGHAUL_V
1
;
memcpy
(
clock_ratio
,
samuel1_clock_ratio
,
sizeof
(
samuel1_clock_ratio
));
memcpy
(
clock_ratio
,
samuel1_clock_ratio
,
sizeof
(
samuel1_clock_ratio
));
memcpy
(
eblcr_table
,
samuel1_eblcr
,
sizeof
(
samuel1_eblcr
));
memcpy
(
eblcr_table
,
samuel1_eblcr
,
sizeof
(
samuel1_eblcr
));
break
;
break
;
case
7
:
/* C5B / C5C */
case
7
:
longhaul_version
=
1
;
longhaul_version
=
TYPE_LONGHAUL_V
1
;
switch
(
c
->
x86_mask
)
{
switch
(
c
->
x86_mask
)
{
case
0
:
case
0
:
cpuname
=
"C3 'Samuel 2' [C5B]"
;
cpuname
=
"C3 'Samuel 2' [C5B]"
;
...
@@ -485,14 +498,14 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
...
@@ -485,14 +498,14 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
case
8
:
case
8
:
cpuname
=
"C3 'Ezra-T' [C5M]"
;
cpuname
=
"C3 'Ezra-T' [C5M]"
;
longhaul_version
=
2
;
longhaul_version
=
TYPE_POWERSAVER
;
numscales
=
32
;
numscales
=
32
;
memcpy
(
clock_ratio
,
ezrat_clock_ratio
,
sizeof
(
ezrat_clock_ratio
));
memcpy
(
clock_ratio
,
ezrat_clock_ratio
,
sizeof
(
ezrat_clock_ratio
));
memcpy
(
eblcr_table
,
ezrat_eblcr
,
sizeof
(
ezrat_eblcr
));
memcpy
(
eblcr_table
,
ezrat_eblcr
,
sizeof
(
ezrat_eblcr
));
break
;
break
;
case
9
:
case
9
:
longhaul_version
=
3
;
longhaul_version
=
TYPE_POWERSAVER
;
numscales
=
32
;
numscales
=
32
;
switch
(
c
->
x86_mask
)
{
switch
(
c
->
x86_mask
)
{
case
0
...
1
:
case
0
...
1
:
...
@@ -518,14 +531,23 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
...
@@ -518,14 +531,23 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
break
;
break
;
}
}
printk
(
KERN_INFO
PFX
"VIA %s CPU detected. Longhaul v%d supported.
\n
"
,
printk
(
KERN_INFO
PFX
"VIA %s CPU detected."
,
cpuname
);
cpuname
,
longhaul_version
);
switch
(
longhaul_version
)
{
case
TYPE_LONGHAUL_V1
:
case
TYPE_LONGHAUL_V2
:
printk
(
"Longhaul v%d supported.
\n
"
,
longhaul_version
);
break
;
case
TYPE_POWERSAVER
:
printk
(
"Powersaver supported.
\n
"
);
break
;
};
ret
=
longhaul_get_ranges
();
ret
=
longhaul_get_ranges
();
if
(
ret
!=
0
)
if
(
ret
!=
0
)
return
ret
;
return
ret
;
if
((
longhaul_version
==
2
)
&&
(
dont_scale_voltage
==
0
))
if
((
longhaul_version
==
TYPE_LONGHAUL_V2
||
longhaul_version
==
TYPE_POWERSAVER
)
&&
(
dont_scale_voltage
==
0
))
longhaul_setup_voltagescaling
();
longhaul_setup_voltagescaling
();
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment