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
Kirill Smelkov
linux
Commits
259cf59f
Commit
259cf59f
authored
Jan 04, 2004
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge centrino speedstep duplicate patches
parents
48818fe1
b8645a8e
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
191 additions
and
69 deletions
+191
-69
arch/arm/mach-integrator/cpu.c
arch/arm/mach-integrator/cpu.c
+1
-1
arch/i386/kernel/cpu/cpufreq/acpi.c
arch/i386/kernel/cpu/cpufreq/acpi.c
+2
-2
arch/i386/kernel/cpu/cpufreq/longhaul.c
arch/i386/kernel/cpu/cpufreq/longhaul.c
+9
-2
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
+54
-14
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+7
-2
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+8
-8
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+8
-8
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
+34
-3
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
+1
-1
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
+34
-12
arch/i386/kernel/timers/timer_tsc.c
arch/i386/kernel/timers/timer_tsc.c
+27
-8
drivers/cpufreq/Kconfig
drivers/cpufreq/Kconfig
+1
-1
include/linux/cpufreq.h
include/linux/cpufreq.h
+5
-7
No files found.
arch/arm/mach-integrator/cpu.c
View file @
259cf59f
...
@@ -172,7 +172,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
...
@@ -172,7 +172,7 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
max_freq
=
160000
;
policy
->
cpuinfo
.
max_freq
=
160000
;
policy
->
cpuinfo
.
min_freq
=
12000
;
policy
->
cpuinfo
.
min_freq
=
12000
;
policy
->
cpuinfo
.
transition_latency
=
1000
;
/* 1 ms, assumed */
policy
->
cpuinfo
.
transition_latency
=
1000
000
;
/* 1 ms, assumed */
policy
->
cur
=
policy
->
min
=
policy
->
max
=
policy
->
cur
=
policy
->
min
=
policy
->
max
=
icst525_khz
(
&
cclk_params
,
vco
);
/* current freq */
icst525_khz
(
&
cclk_params
,
vco
);
/* current freq */
...
...
arch/i386/kernel/cpu/cpufreq/acpi.c
View file @
259cf59f
...
@@ -578,8 +578,8 @@ acpi_cpufreq_cpu_init (
...
@@ -578,8 +578,8 @@ acpi_cpufreq_cpu_init (
/* detect transition latency */
/* detect transition latency */
policy
->
cpuinfo
.
transition_latency
=
0
;
policy
->
cpuinfo
.
transition_latency
=
0
;
for
(
i
=
0
;
i
<
perf
->
state_count
;
i
++
)
{
for
(
i
=
0
;
i
<
perf
->
state_count
;
i
++
)
{
if
(
perf
->
states
[
i
].
transition_latency
>
policy
->
cpuinfo
.
transition_latency
)
if
(
(
perf
->
states
[
i
].
transition_latency
*
1000
)
>
policy
->
cpuinfo
.
transition_latency
)
policy
->
cpuinfo
.
transition_latency
=
perf
->
states
[
i
].
transition_latency
;
policy
->
cpuinfo
.
transition_latency
=
perf
->
states
[
i
].
transition_latency
*
1000
;
}
}
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cur
=
perf
->
states
[
pr
->
limit
.
state
.
px
].
core_frequency
*
1000
;
policy
->
cur
=
perf
->
states
[
pr
->
limit
.
state
.
px
].
core_frequency
*
1000
;
...
...
arch/i386/kernel/cpu/cpufreq/longhaul.c
View file @
259cf59f
...
@@ -170,6 +170,9 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
...
@@ -170,6 +170,9 @@ static void longhaul_setstate (unsigned int clock_ratio_index)
* between that value multiplied by possible FSBs and cpu_mhz which
* between that value multiplied by possible FSBs and cpu_mhz which
* was calculated at boot time. Really ugly, but no other way to do this.
* was calculated at boot time. Really ugly, but no other way to do this.
*/
*/
#define ROUNDING 0xf
static
int
_guess
(
int
guess
,
int
maxmult
)
static
int
_guess
(
int
guess
,
int
maxmult
)
{
{
int
target
;
int
target
;
...
@@ -177,16 +180,20 @@ static int _guess (int guess, int maxmult)
...
@@ -177,16 +180,20 @@ static int _guess (int guess, int maxmult)
target
=
((
maxmult
/
10
)
*
guess
);
target
=
((
maxmult
/
10
)
*
guess
);
if
(
maxmult
%
10
!=
0
)
if
(
maxmult
%
10
!=
0
)
target
+=
(
guess
/
2
);
target
+=
(
guess
/
2
);
target
&=
~
0xf
;
target
+=
ROUNDING
/
2
;
target
&=
~
ROUNDING
;
return
target
;
return
target
;
}
}
static
int
guess_fsb
(
int
maxmult
)
static
int
guess_fsb
(
int
maxmult
)
{
{
int
speed
=
(
cpu_khz
/
1000
)
&
~
0xf
;
int
speed
=
(
cpu_khz
/
1000
);
int
i
;
int
i
;
int
speeds
[
3
]
=
{
66
,
100
,
133
};
int
speeds
[
3
]
=
{
66
,
100
,
133
};
speed
+=
ROUNDING
/
2
;
speed
&=
~
ROUNDING
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
_guess
(
speeds
[
i
],
maxmult
)
==
speed
)
if
(
_guess
(
speeds
[
i
],
maxmult
)
==
speed
)
return
speeds
[
i
];
return
speeds
[
i
];
...
...
arch/i386/kernel/cpu/cpufreq/p4-clockmod.c
View file @
259cf59f
...
@@ -48,8 +48,7 @@ enum {
...
@@ -48,8 +48,7 @@ enum {
static
int
has_N44_O17_errata
[
NR_CPUS
];
static
int
has_N44_O17_errata
[
NR_CPUS
];
static
int
stock_freq
;
static
unsigned
int
stock_freq
;
static
int
cpufreq_p4_setdc
(
unsigned
int
cpu
,
unsigned
int
newstate
)
static
int
cpufreq_p4_setdc
(
unsigned
int
cpu
,
unsigned
int
newstate
)
{
{
...
@@ -175,6 +174,54 @@ static int cpufreq_p4_verify(struct cpufreq_policy *policy)
...
@@ -175,6 +174,54 @@ static int cpufreq_p4_verify(struct cpufreq_policy *policy)
return
cpufreq_frequency_table_verify
(
policy
,
&
p4clockmod_table
[
0
]);
return
cpufreq_frequency_table_verify
(
policy
,
&
p4clockmod_table
[
0
]);
}
}
/* copied from speedstep_lib, made SMP-compatible */
static
unsigned
int
cpufreq_p4_get_frequency
(
struct
cpuinfo_x86
*
c
)
{
u32
msr_lo
,
msr_hi
,
mult
;
unsigned
int
fsb
=
0
;
if
(
c
->
x86
!=
0xF
)
{
printk
(
KERN_DEBUG
PFX
"Unknown P4. Please send an e-mail to <linux@brodo.de>
\n
"
);
return
0
;
}
rdmsr
(
0x2c
,
msr_lo
,
msr_hi
);
/* printk(KERN_DEBUG PFX "P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi); */
/* decode the FSB: see IA-32 Intel (C) Architecture Software
* Developer's Manual, Volume 3: System Prgramming Guide,
* revision #12 in Table B-1: MSRs in the Pentium 4 and
* Intel Xeon Processors, on page B-4 and B-5.
*/
if
(
c
->
x86_model
<
2
)
fsb
=
100
*
1000
;
else
{
u8
fsb_code
=
(
msr_lo
>>
16
)
&
0x7
;
switch
(
fsb_code
)
{
case
0
:
fsb
=
100
*
1000
;
break
;
case
1
:
fsb
=
13333
*
10
;
break
;
case
2
:
fsb
=
200
*
1000
;
break
;
}
}
if
(
!
fsb
)
{
printk
(
KERN_DEBUG
PFX
"couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>
\n
"
);
printk
(
KERN_DEBUG
PFX
"P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x
\n
"
,
msr_lo
,
msr_hi
);
}
/* Multiplier. */
mult
=
msr_lo
>>
24
;
return
(
fsb
*
mult
);
}
static
int
cpufreq_p4_cpu_init
(
struct
cpufreq_policy
*
policy
)
static
int
cpufreq_p4_cpu_init
(
struct
cpufreq_policy
*
policy
)
{
{
...
@@ -192,15 +239,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
...
@@ -192,15 +239,10 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
has_N44_O17_errata
[
policy
->
cpu
]
=
1
;
has_N44_O17_errata
[
policy
->
cpu
]
=
1
;
}
}
/* get frequency */
/* get max frequency */
if
(
!
stock_freq
)
{
stock_freq
=
cpufreq_p4_get_frequency
(
c
);
if
(
cpu_khz
)
if
(
!
stock_freq
)
stock_freq
=
cpu_khz
;
else
{
printk
(
KERN_INFO
PFX
"unknown core frequency - please use module parameter 'stock_freq'
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
/* table init */
/* table init */
for
(
i
=
1
;
(
p4clockmod_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
);
i
++
)
{
for
(
i
=
1
;
(
p4clockmod_table
[
i
].
frequency
!=
CPUFREQ_TABLE_END
);
i
++
)
{
...
@@ -213,7 +255,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
...
@@ -213,7 +255,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
/* cpuinfo and default policy values */
/* cpuinfo and default policy values */
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
transition_latency
=
1000
;
policy
->
cpuinfo
.
transition_latency
=
1000
000
;
/* assumed */
policy
->
cur
=
stock_freq
;
policy
->
cur
=
stock_freq
;
return
cpufreq_frequency_table_cpuinfo
(
policy
,
&
p4clockmod_table
[
0
]);
return
cpufreq_frequency_table_cpuinfo
(
policy
,
&
p4clockmod_table
[
0
]);
...
@@ -269,8 +311,6 @@ static void __exit cpufreq_p4_exit(void)
...
@@ -269,8 +311,6 @@ static void __exit cpufreq_p4_exit(void)
}
}
MODULE_PARM
(
stock_freq
,
"i"
);
MODULE_AUTHOR
(
"Zwane Mwaikambo <zwane@commfireservices.com>"
);
MODULE_AUTHOR
(
"Zwane Mwaikambo <zwane@commfireservices.com>"
);
MODULE_DESCRIPTION
(
"cpufreq driver for Pentium(TM) 4/Xeon(TM)"
);
MODULE_DESCRIPTION
(
"cpufreq driver for Pentium(TM) 4/Xeon(TM)"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k7.c
View file @
259cf59f
...
@@ -337,7 +337,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
...
@@ -337,7 +337,8 @@ static int powernow_decode_bios (int maxfid, int startvid)
}
}
}
}
printk
(
KERN_INFO
PFX
"No PST tables match this cpuid (0x%x)
\n
"
,
etuple
);
printk
(
KERN_INFO
PFX
"No PST tables match this cpuid (0x%x)
\n
"
,
etuple
);
printk
(
"This is indicative of a broken BIOS. Email davej@redhat.com
\n
"
);
printk
(
KERN_INFO
PFX
"This is indicative of a broken BIOS.
\n
"
);
printk
(
KERN_INFO
PFX
"See http://www.codemonkey.org.uk/projects/cpufreq/powernow-k7.shtml
\n
"
);
return
-
EINVAL
;
return
-
EINVAL
;
}
}
p
++
;
p
++
;
...
@@ -386,7 +387,11 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
...
@@ -386,7 +387,11 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
minimum_speed
,
maximum_speed
);
minimum_speed
,
maximum_speed
);
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
policy
->
cpuinfo
.
transition_latency
=
latency
;
/* latency is in 10 ns (look for SGTC above) for each VID
* and FID transition, so multiply that value with 20 */
policy
->
cpuinfo
.
transition_latency
=
latency
*
20
;
policy
->
cur
=
maximum_speed
;
policy
->
cur
=
maximum_speed
;
return
cpufreq_frequency_table_cpuinfo
(
policy
,
powernow_table
);
return
cpufreq_frequency_table_cpuinfo
(
policy
,
powernow_table
);
...
...
arch/i386/kernel/cpu/cpufreq/powernow-k8.c
View file @
259cf59f
...
@@ -687,11 +687,13 @@ find_psb_table(void)
...
@@ -687,11 +687,13 @@ find_psb_table(void)
if
(
ppst
[
j
].
vid
<
rvo
)
{
/* vid+rvo >= 0 */
if
(
ppst
[
j
].
vid
<
rvo
)
{
/* vid+rvo >= 0 */
printk
(
KERN_ERR
BFX
printk
(
KERN_ERR
BFX
"0 vid exceeded with pstate %d
\n
"
,
j
);
"0 vid exceeded with pstate %d
\n
"
,
j
);
kfree
(
ppst
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
if
(
ppst
[
j
].
vid
<
maxvid
+
rvo
)
{
/* vid+rvo >= maxvid */
if
(
ppst
[
j
].
vid
<
maxvid
+
rvo
)
{
/* vid+rvo >= maxvid */
printk
(
KERN_ERR
BFX
printk
(
KERN_ERR
BFX
"maxvid exceeded with pstate %d
\n
"
,
j
);
"maxvid exceeded with pstate %d
\n
"
,
j
);
kfree
(
ppst
);
return
-
ENODEV
;
return
-
ENODEV
;
}
}
}
}
...
@@ -706,7 +708,7 @@ find_psb_table(void)
...
@@ -706,7 +708,7 @@ find_psb_table(void)
for
(
j
=
0
;
j
<
numps
;
j
++
)
for
(
j
=
0
;
j
<
numps
;
j
++
)
if
((
ppst
[
j
].
fid
==
currfid
)
&&
(
ppst
[
j
].
vid
==
currvid
))
if
((
ppst
[
j
].
fid
==
currfid
)
&&
(
ppst
[
j
].
vid
==
currvid
))
return
(
0
)
;
return
0
;
printk
(
KERN_ERR
BFX
"currfid/vid do not match PST, ignoring
\n
"
);
printk
(
KERN_ERR
BFX
"currfid/vid do not match PST, ignoring
\n
"
);
return
0
;
return
0
;
...
@@ -935,10 +937,7 @@ powernowk8_verify(struct cpufreq_policy *pol)
...
@@ -935,10 +937,7 @@ powernowk8_verify(struct cpufreq_policy *pol)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
#warning pol->policy is in undefined state here
res
=
find_match
(
&
targ
,
&
min
,
&
max
,
SEARCH_DOWN
,
0
,
0
);
res
=
find_match
(
&
targ
,
&
min
,
&
max
,
pol
->
policy
==
CPUFREQ_POLICY_POWERSAVE
?
SEARCH_DOWN
:
SEARCH_UP
,
0
,
0
);
if
(
!
res
)
{
if
(
!
res
)
{
pol
->
min
=
min
*
1000
;
pol
->
min
=
min
*
1000
;
pol
->
max
=
max
*
1000
;
pol
->
max
=
max
*
1000
;
...
@@ -957,9 +956,10 @@ powernowk8_cpu_init(struct cpufreq_policy *pol)
...
@@ -957,9 +956,10 @@ powernowk8_cpu_init(struct cpufreq_policy *pol)
pol
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
pol
->
governor
=
CPUFREQ_DEFAULT_GOVERNOR
;
/* Take a crude guess here. */
/* Take a crude guess here.
pol
->
cpuinfo
.
transition_latency
=
((
rvo
+
8
)
*
vstable
*
VST_UNITS_20US
)
* That guess was in microseconds, so multply with 1000 */
+
(
3
*
(
1
<<
irt
)
*
10
);
pol
->
cpuinfo
.
transition_latency
=
(((
rvo
+
8
)
*
vstable
*
VST_UNITS_20US
)
+
(
3
*
(
1
<<
irt
)
*
10
))
*
1000
;
if
(
query_current_values_with_pending_wait
())
if
(
query_current_values_with_pending_wait
())
return
-
EIO
;
return
-
EIO
;
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
View file @
259cf59f
...
@@ -75,13 +75,13 @@ static struct cpufreq_frequency_table op_900[] =
...
@@ -75,13 +75,13 @@ static struct cpufreq_frequency_table op_900[] =
/* Ultra Low Voltage Intel Pentium M processor 1000MHz */
/* Ultra Low Voltage Intel Pentium M processor 1000MHz */
static
struct
cpufreq_frequency_table
op_1000
[]
=
static
struct
cpufreq_frequency_table
op_1000
[]
=
{
{
OP
(
600
,
844
),
OP
(
600
,
844
),
OP
(
800
,
972
),
OP
(
800
,
972
),
OP
(
900
,
988
),
OP
(
900
,
988
),
OP
(
1000
,
1004
),
OP
(
1000
,
1004
),
{
.
frequency
=
CPUFREQ_TABLE_END
}
{
.
frequency
=
CPUFREQ_TABLE_END
}
};
};
/* Low Voltage Intel Pentium M processor 1.10GHz */
/* Low Voltage Intel Pentium M processor 1.10GHz */
static
struct
cpufreq_frequency_table
op_1100
[]
=
static
struct
cpufreq_frequency_table
op_1100
[]
=
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
View file @
259cf59f
...
@@ -106,14 +106,45 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
...
@@ -106,14 +106,45 @@ static unsigned int pentium3_get_frequency (unsigned int processor)
static
unsigned
int
pentium4_get_frequency
(
void
)
static
unsigned
int
pentium4_get_frequency
(
void
)
{
{
u32
msr_lo
,
msr_hi
;
struct
cpuinfo_x86
*
c
=
&
boot_cpu_data
;
u32
msr_lo
,
msr_hi
,
mult
;
unsigned
int
fsb
=
0
;
rdmsr
(
0x2c
,
msr_lo
,
msr_hi
);
rdmsr
(
0x2c
,
msr_lo
,
msr_hi
);
dprintk
(
KERN_DEBUG
"speedstep-lib: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x
\n
"
,
msr_lo
,
msr_hi
);
dprintk
(
KERN_DEBUG
"speedstep-lib: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x
\n
"
,
msr_lo
,
msr_hi
);
msr_lo
>>=
24
;
/* decode the FSB: see IA-32 Intel (C) Architecture Software
return
(
msr_lo
*
100000
);
* Developer's Manual, Volume 3: System Prgramming Guide,
* revision #12 in Table B-1: MSRs in the Pentium 4 and
* Intel Xeon Processors, on page B-4 and B-5.
*/
if
(
c
->
x86_model
<
2
)
fsb
=
100
*
1000
;
else
{
u8
fsb_code
=
(
msr_lo
>>
16
)
&
0x7
;
switch
(
fsb_code
)
{
case
0
:
fsb
=
100
*
1000
;
break
;
case
1
:
fsb
=
13333
*
10
;
break
;
case
2
:
fsb
=
200
*
1000
;
break
;
}
}
if
(
!
fsb
)
printk
(
KERN_DEBUG
"speedstep-lib: couldn't detect FSB speed. Please send an e-mail to <linux@brodo.de>
\n
"
);
/* Multiplier. */
mult
=
msr_lo
>>
24
;
dprintk
(
KERN_DEBUG
"speedstep-lib: P4 - FSB %u kHz; Multiplier %u
\n
"
,
fsb
,
mult
);
return
(
fsb
*
mult
);
}
}
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-lib.h
View file @
259cf59f
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
#define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001
/* Coppermine core */
#define SPEEDSTEP_PROCESSOR_PIII_C_EARLY 0x00000001
/* Coppermine core */
#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002
/* Coppermine core */
#define SPEEDSTEP_PROCESSOR_PIII_C 0x00000002
/* Coppermine core */
#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003
/* Tualatin core */
#define SPEEDSTEP_PROCESSOR_PIII_T 0x00000003
/* Tualatin core */
#define SPEEDSTEP_PROCESSOR_P4M 0x00000004
/* P4-M
with 100 MHz FSB
*/
#define SPEEDSTEP_PROCESSOR_P4M 0x00000004
/* P4-M */
/* speedstep states -- only two of them */
/* speedstep states -- only two of them */
...
...
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
View file @
259cf59f
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
#include <linux/cpufreq.h>
#include <linux/cpufreq.h>
#include <linux/pci.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/ist.h>
#include <asm/ist.h>
#include "speedstep-lib.h"
#include "speedstep-lib.h"
...
@@ -51,10 +52,14 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
...
@@ -51,10 +52,14 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
#define SET_SPEEDSTEP_STATE 2
#define SET_SPEEDSTEP_STATE 2
#define GET_SPEEDSTEP_FREQS 4
#define GET_SPEEDSTEP_FREQS 4
/* how often shall the SMI call be tried if it failed, e.g. because
* of DMA activity going on? */
#define SMI_TRIES 5
/* DEBUG
/* DEBUG
* Define it if you want verbose debug output, e.g. for bug reporting
* Define it if you want verbose debug output, e.g. for bug reporting
*/
*/
#define SPEEDSTEP_DEBUG
//
#define SPEEDSTEP_DEBUG
#ifdef SPEEDSTEP_DEBUG
#ifdef SPEEDSTEP_DEBUG
#define dprintk(msg...) printk(msg)
#define dprintk(msg...) printk(msg)
...
@@ -85,6 +90,9 @@ static int speedstep_smi_ownership (void)
...
@@ -85,6 +90,9 @@ static int speedstep_smi_ownership (void)
/**
/**
* speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
* speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
* Only available on later SpeedStep-enabled systems, returns false results or
* even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
* shows that the latter occurs if !(ist_info.event & 0xFFFF).
*
*
*/
*/
static
int
speedstep_smi_get_freqs
(
unsigned
int
*
low
,
unsigned
int
*
high
)
static
int
speedstep_smi_get_freqs
(
unsigned
int
*
low
,
unsigned
int
*
high
)
...
@@ -93,6 +101,9 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
...
@@ -93,6 +101,9 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
u32
state
=
0
;
u32
state
=
0
;
u32
function
=
GET_SPEEDSTEP_FREQS
;
u32
function
=
GET_SPEEDSTEP_FREQS
;
if
(
!
(
ist_info
.
event
&
0xFFFF
))
return
-
ENODEV
;
command
=
(
smi_sig
&
0xffffff00
)
|
(
smi_cmd
&
0xff
);
command
=
(
smi_sig
&
0xffffff00
)
|
(
smi_cmd
&
0xff
);
__asm__
__volatile__
(
"movl $0, %%edi
\n
"
__asm__
__volatile__
(
"movl $0, %%edi
\n
"
...
@@ -134,10 +145,11 @@ static int speedstep_get_state (void)
...
@@ -134,10 +145,11 @@ static int speedstep_get_state (void)
*/
*/
static
void
speedstep_set_state
(
unsigned
int
state
,
unsigned
int
notify
)
static
void
speedstep_set_state
(
unsigned
int
state
,
unsigned
int
notify
)
{
{
unsigned
int
old_state
,
result
,
command
,
new_state
;
unsigned
int
old_state
,
result
=
0
,
command
,
new_state
;
unsigned
long
flags
;
unsigned
long
flags
;
struct
cpufreq_freqs
freqs
;
struct
cpufreq_freqs
freqs
;
unsigned
int
function
=
SET_SPEEDSTEP_STATE
;
unsigned
int
function
=
SET_SPEEDSTEP_STATE
;
unsigned
int
retry
=
0
;
if
(
state
>
0x1
)
if
(
state
>
0x1
)
return
;
return
;
...
@@ -157,20 +169,28 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
...
@@ -157,20 +169,28 @@ static void speedstep_set_state (unsigned int state, unsigned int notify)
local_irq_save
(
flags
);
local_irq_save
(
flags
);
command
=
(
smi_sig
&
0xffffff00
)
|
(
smi_cmd
&
0xff
);
command
=
(
smi_sig
&
0xffffff00
)
|
(
smi_cmd
&
0xff
);
do
{
if
(
retry
)
{
dprintk
(
KERN_INFO
"cpufreq: retry %u, previous result %u
\n
"
,
retry
,
result
);
mdelay
(
retry
*
50
);
}
retry
++
;
__asm__
__volatile__
(
__asm__
__volatile__
(
"movl $0, %%edi
\n
"
"movl $0, %%edi
\n
"
"out %%al, (%%dx)
\n
"
"out %%al, (%%dx)
\n
"
:
"=b"
(
new_state
),
"=D"
(
result
)
:
"=b"
(
new_state
),
"=D"
(
result
)
:
"a"
(
command
),
"b"
(
function
),
"c"
(
state
),
"d"
(
smi_port
),
"S"
(
0
)
:
"a"
(
command
),
"b"
(
function
),
"c"
(
state
),
"d"
(
smi_port
),
"S"
(
0
)
);
);
}
while
((
new_state
!=
state
)
&&
(
retry
<=
SMI_TRIES
));
/* enable IRQs */
/* enable IRQs */
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
if
(
new_state
==
state
)
{
if
(
new_state
==
state
)
{
dprintk
(
KERN_INFO
"cpufreq: change to %u MHz succe
ded
\n
"
,
(
freqs
.
new
/
1000
)
);
dprintk
(
KERN_INFO
"cpufreq: change to %u MHz succe
eded after %u tries with result %u
\n
"
,
(
freqs
.
new
/
1000
),
retry
,
result
);
}
else
{
}
else
{
printk
(
KERN_ERR
"cpufreq: change failed
\n
"
);
printk
(
KERN_ERR
"cpufreq: change failed
with new_state %u and result %u
\n
"
,
new_state
,
result
);
}
}
if
(
notify
)
if
(
notify
)
...
@@ -225,9 +245,10 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
...
@@ -225,9 +245,10 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
return
-
ENODEV
;
return
-
ENODEV
;
result
=
speedstep_smi_ownership
();
result
=
speedstep_smi_ownership
();
if
(
result
)
{
if
(
result
)
dprintk
(
KERN_INFO
"cpufreq: fails an aquiring ownership of a SMI interface.
\n
"
);
dprintk
(
KERN_INFO
"cpufreq: fails an aquiring ownership of a SMI interface.
\n
"
);
return
-
EINVAL
;
}
/* detect low and high frequency */
/* detect low and high frequency */
result
=
speedstep_smi_get_freqs
(
&
speedstep_freqs
[
SPEEDSTEP_LOW
].
frequency
,
result
=
speedstep_smi_get_freqs
(
&
speedstep_freqs
[
SPEEDSTEP_LOW
].
frequency
,
...
@@ -286,6 +307,7 @@ static struct cpufreq_driver speedstep_driver = {
...
@@ -286,6 +307,7 @@ static struct cpufreq_driver speedstep_driver = {
.
target
=
speedstep_target
,
.
target
=
speedstep_target
,
.
init
=
speedstep_cpu_init
,
.
init
=
speedstep_cpu_init
,
.
resume
=
speedstep_resume
,
.
resume
=
speedstep_resume
,
.
owner
=
THIS_MODULE
,
};
};
/**
/**
...
...
arch/i386/kernel/timers/timer_tsc.c
View file @
259cf59f
...
@@ -317,9 +317,17 @@ static void mark_offset_tsc_hpet(void)
...
@@ -317,9 +317,17 @@ static void mark_offset_tsc_hpet(void)
}
}
#endif
#endif
#ifdef CONFIG_CPU_FREQ
#ifdef CONFIG_CPU_FREQ
/* If the CPU frequency is scaled, TSC-based delays will need a different
* loops_per_jiffy value to function properly. An exception to this
* are modern Intel Pentium 4 processors, where the TSC runs at a constant
* speed independent of frequency scaling.
*/
static
unsigned
int
ref_freq
=
0
;
static
unsigned
int
ref_freq
=
0
;
static
unsigned
long
loops_per_jiffy_ref
=
0
;
static
unsigned
long
loops_per_jiffy_ref
=
0
;
static
unsigned
int
variable_tsc
=
1
;
#ifndef CONFIG_SMP
#ifndef CONFIG_SMP
static
unsigned
long
fast_gettimeoffset_ref
=
0
;
static
unsigned
long
fast_gettimeoffset_ref
=
0
;
...
@@ -344,13 +352,16 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
...
@@ -344,13 +352,16 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
if
((
val
==
CPUFREQ_PRECHANGE
&&
freq
->
old
<
freq
->
new
)
||
if
((
val
==
CPUFREQ_PRECHANGE
&&
freq
->
old
<
freq
->
new
)
||
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
))
{
(
val
==
CPUFREQ_POSTCHANGE
&&
freq
->
old
>
freq
->
new
))
{
if
(
variable_tsc
)
cpu_data
[
freq
->
cpu
].
loops_per_jiffy
=
cpufreq_scale
(
loops_per_jiffy_ref
,
ref_freq
,
freq
->
new
);
cpu_data
[
freq
->
cpu
].
loops_per_jiffy
=
cpufreq_scale
(
loops_per_jiffy_ref
,
ref_freq
,
freq
->
new
);
#ifndef CONFIG_SMP
#ifndef CONFIG_SMP
if
(
use_tsc
)
{
if
(
use_tsc
)
{
fast_gettimeoffset_quotient
=
cpufreq_scale
(
fast_gettimeoffset_ref
,
freq
->
new
,
ref_freq
);
cpu_khz
=
cpufreq_scale
(
cpu_khz_ref
,
ref_freq
,
freq
->
new
);
cpu_khz
=
cpufreq_scale
(
cpu_khz_ref
,
ref_freq
,
freq
->
new
);
if
(
variable_tsc
)
{
fast_gettimeoffset_quotient
=
cpufreq_scale
(
fast_gettimeoffset_ref
,
freq
->
new
,
ref_freq
);
set_cyc2ns_scale
(
cpu_khz
/
1000
);
set_cyc2ns_scale
(
cpu_khz
/
1000
);
}
}
}
#endif
#endif
}
}
write_sequnlock_irq
(
&
xtime_lock
);
write_sequnlock_irq
(
&
xtime_lock
);
...
@@ -361,6 +372,18 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
...
@@ -361,6 +372,18 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
static
struct
notifier_block
time_cpufreq_notifier_block
=
{
static
struct
notifier_block
time_cpufreq_notifier_block
=
{
.
notifier_call
=
time_cpufreq_notifier
.
notifier_call
=
time_cpufreq_notifier
};
};
static
int
__init
cpufreq_tsc
(
void
)
{
/* P4 and above CPU TSC freq doesn't change when CPU frequency changes*/
if
((
boot_cpu_data
.
x86
>=
15
)
&&
(
boot_cpu_data
.
x86_vendor
==
X86_VENDOR_INTEL
))
variable_tsc
=
0
;
return
cpufreq_register_notifier
(
&
time_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
}
core_initcall
(
cpufreq_tsc
);
#endif
#endif
...
@@ -404,10 +427,6 @@ static int __init init_tsc(char* override)
...
@@ -404,10 +427,6 @@ static int __init init_tsc(char* override)
* moaned if you have the only one in the world - you fix it!
* moaned if you have the only one in the world - you fix it!
*/
*/
#ifdef CONFIG_CPU_FREQ
cpufreq_register_notifier
(
&
time_cpufreq_notifier_block
,
CPUFREQ_TRANSITION_NOTIFIER
);
#endif
count2
=
LATCH
;
/* initialize counter for mark_offset_tsc() */
count2
=
LATCH
;
/* initialize counter for mark_offset_tsc() */
if
(
cpu_has_tsc
)
{
if
(
cpu_has_tsc
)
{
...
...
drivers/cpufreq/Kconfig
View file @
259cf59f
...
@@ -74,7 +74,7 @@ config CPU_FREQ_24_API
...
@@ -74,7 +74,7 @@ config CPU_FREQ_24_API
help
help
This enables the /proc/sys/cpu/ sysctl interface for controlling
This enables the /proc/sys/cpu/ sysctl interface for controlling
the CPUFreq,"userspace" governor. This is the same interface
the CPUFreq,"userspace" governor. This is the same interface
as known from the.4.-kernel patches for CPUFreq, and offers
as known from the
2
.4.-kernel patches for CPUFreq, and offers
the same functionality as long as "userspace" is the
the same functionality as long as "userspace" is the
selected governor for the specified CPU.
selected governor for the specified CPU.
...
...
include/linux/cpufreq.h
View file @
259cf59f
...
@@ -57,7 +57,7 @@ struct cpufreq_governor;
...
@@ -57,7 +57,7 @@ struct cpufreq_governor;
struct
cpufreq_cpuinfo
{
struct
cpufreq_cpuinfo
{
unsigned
int
max_freq
;
unsigned
int
max_freq
;
unsigned
int
min_freq
;
unsigned
int
min_freq
;
unsigned
int
transition_latency
;
/* in 10^(-9) s */
unsigned
int
transition_latency
;
/* in 10^(-9) s
= nanoseconds
*/
};
};
struct
cpufreq_real_policy
{
struct
cpufreq_real_policy
{
...
@@ -231,17 +231,18 @@ int cpufreq_update_policy(unsigned int cpu);
...
@@ -231,17 +231,18 @@ int cpufreq_update_policy(unsigned int cpu);
/* the proc_intf.c needs this */
/* the proc_intf.c needs this */
int
cpufreq_parse_governor
(
char
*
str_governor
,
unsigned
int
*
policy
,
struct
cpufreq_governor
**
governor
);
int
cpufreq_parse_governor
(
char
*
str_governor
,
unsigned
int
*
policy
,
struct
cpufreq_governor
**
governor
);
#if defined(CONFIG_CPU_FREQ_GOV_USERSPACE) || defined(CONFIG_CPU_FREQ_GOV_USERSPACE_MODULE)
/*********************************************************************
/*********************************************************************
* CPUFREQ USERSPACE GOVERNOR *
* CPUFREQ USERSPACE GOVERNOR *
*********************************************************************/
*********************************************************************/
int
cpufreq_gov_userspace_init
(
void
);
int
cpufreq_gov_userspace_init
(
void
);
#ifdef CONFIG_CPU_FREQ_24_API
int
cpufreq_setmax
(
unsigned
int
cpu
);
int
cpufreq_setmax
(
unsigned
int
cpu
);
int
cpufreq_set
(
unsigned
int
kHz
,
unsigned
int
cpu
);
int
cpufreq_set
(
unsigned
int
kHz
,
unsigned
int
cpu
);
unsigned
int
cpufreq_get
(
unsigned
int
cpu
);
unsigned
int
cpufreq_get
(
unsigned
int
cpu
);
#ifdef CONFIG_CPU_FREQ_24_API
/* /proc/sys/cpu */
/* /proc/sys/cpu */
enum
{
enum
{
...
@@ -289,8 +290,6 @@ enum {
...
@@ -289,8 +290,6 @@ enum {
#endif
/* CONFIG_CPU_FREQ_24_API */
#endif
/* CONFIG_CPU_FREQ_24_API */
#endif
/* CONFIG_CPU_FREQ_GOV_USERSPACE */
/*********************************************************************
/*********************************************************************
* CPUFREQ DEFAULT GOVERNOR *
* CPUFREQ DEFAULT GOVERNOR *
...
@@ -305,6 +304,7 @@ extern struct cpufreq_governor cpufreq_gov_userspace;
...
@@ -305,6 +304,7 @@ extern struct cpufreq_governor cpufreq_gov_userspace;
#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
#define CPUFREQ_DEFAULT_GOVERNOR &cpufreq_gov_userspace
#endif
#endif
/*********************************************************************
/*********************************************************************
* FREQUENCY TABLE HELPERS *
* FREQUENCY TABLE HELPERS *
*********************************************************************/
*********************************************************************/
...
@@ -318,7 +318,6 @@ struct cpufreq_frequency_table {
...
@@ -318,7 +318,6 @@ struct cpufreq_frequency_table {
* order */
* order */
};
};
#if defined(CONFIG_CPU_FREQ_TABLE) || defined(CONFIG_CPU_FREQ_TABLE_MODULE)
int
cpufreq_frequency_table_cpuinfo
(
struct
cpufreq_policy
*
policy
,
int
cpufreq_frequency_table_cpuinfo
(
struct
cpufreq_policy
*
policy
,
struct
cpufreq_frequency_table
*
table
);
struct
cpufreq_frequency_table
*
table
);
...
@@ -340,5 +339,4 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
...
@@ -340,5 +339,4 @@ void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
void
cpufreq_frequency_table_put_attr
(
unsigned
int
cpu
);
void
cpufreq_frequency_table_put_attr
(
unsigned
int
cpu
);
#endif
/* CONFIG_CPU_FREQ_TABLE */
#endif
/* _LINUX_CPUFREQ_H */
#endif
/* _LINUX_CPUFREQ_H */
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