Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
macintosh
windfarm_pid.c
Go to the documentation of this file.
1
/*
2
* Windfarm PowerMac thermal control. Generic PID helpers
3
*
4
* (c) Copyright 2005 Benjamin Herrenschmidt, IBM Corp.
5
* <
[email protected]
>
6
*
7
* Released under the term of the GNU GPL v2.
8
*/
9
10
#include <linux/types.h>
11
#include <linux/errno.h>
12
#include <linux/kernel.h>
13
#include <linux/string.h>
14
#include <linux/module.h>
15
16
#include "
windfarm_pid.h
"
17
18
#undef DEBUG
19
20
#ifdef DEBUG
21
#define DBG(args...) printk(args)
22
#else
23
#define DBG(args...) do { } while(0)
24
#endif
25
26
void
wf_pid_init
(
struct
wf_pid_state
*
st
,
struct
wf_pid_param
*
param
)
27
{
28
memset
(st, 0,
sizeof
(
struct
wf_pid_state
));
29
st->
param
= *
param
;
30
st->
first
= 1;
31
}
32
EXPORT_SYMBOL_GPL
(
wf_pid_init
);
33
34
s32
wf_pid_run
(
struct
wf_pid_state
*
st
,
s32
new_sample)
35
{
36
s64
error
,
integ
, deriv;
37
s32
target
;
38
int
i
, hlen = st->
param
.history_len;
39
40
/* Calculate error term */
41
error = new_sample - st->
param
.itarget;
42
43
/* Get samples into our history buffer */
44
if
(st->
first
) {
45
for
(i = 0; i < hlen; i++) {
46
st->
samples
[
i
] = new_sample;
47
st->
errors
[
i
] =
error
;
48
}
49
st->
first
= 0;
50
st->
index
= 0;
51
}
else
{
52
st->
index
= (st->
index
+ 1) % hlen;
53
st->
samples
[st->
index
] = new_sample;
54
st->
errors
[st->
index
] =
error
;
55
}
56
57
/* Calculate integral term */
58
for
(i = 0, integ = 0; i < hlen; i++)
59
integ += st->
errors
[(st->
index
+ hlen - i) % hlen];
60
integ *= st->
param
.interval;
61
62
/* Calculate derivative term */
63
deriv = st->
errors
[st->
index
] -
64
st->
errors
[(st->
index
+ hlen - 1) % hlen];
65
deriv /= st->
param
.interval;
66
67
/* Calculate target */
68
target = (
s32
)((integ * (
s64
)st->
param
.gr + deriv * (
s64
)st->
param
.gd +
69
error * (
s64
)st->
param
.gp) >> 36);
70
if
(st->
param
.additive)
71
target += st->
target
;
72
target =
max
(target, st->
param
.min);
73
target =
min
(target, st->
param
.max);
74
st->
target
=
target
;
75
76
return
st->
target
;
77
}
78
EXPORT_SYMBOL_GPL
(
wf_pid_run
);
79
80
void
wf_cpu_pid_init
(
struct
wf_cpu_pid_state
*
st
,
81
struct
wf_cpu_pid_param
*
param
)
82
{
83
memset
(st, 0,
sizeof
(
struct
wf_cpu_pid_state
));
84
st->
param
= *
param
;
85
st->
first
= 1;
86
}
87
EXPORT_SYMBOL_GPL
(
wf_cpu_pid_init
);
88
89
s32
wf_cpu_pid_run
(
struct
wf_cpu_pid_state
*
st
,
s32
new_power,
s32
new_temp)
90
{
91
s64
integ
, deriv, prop;
92
s32
error
,
target
, sval, adj;
93
int
i
, hlen = st->
param
.history_len;
94
95
/* Calculate error term */
96
error = st->
param
.pmaxadj - new_power;
97
98
/* Get samples into our history buffer */
99
if
(st->
first
) {
100
for
(i = 0; i < hlen; i++) {
101
st->
powers
[
i
] = new_power;
102
st->
errors
[
i
] =
error
;
103
}
104
st->
temps
[0] = st->
temps
[1] = new_temp;
105
st->
first
= 0;
106
st->
index
= st->
tindex
= 0;
107
}
else
{
108
st->
index
= (st->
index
+ 1) % hlen;
109
st->
powers
[st->
index
] = new_power;
110
st->
errors
[st->
index
] =
error
;
111
st->
tindex
= (st->
tindex
+ 1) % 2;
112
st->
temps
[st->
tindex
] = new_temp;
113
}
114
115
/* Calculate integral term */
116
for
(i = 0, integ = 0; i < hlen; i++)
117
integ += st->
errors
[(st->
index
+ hlen - i) % hlen];
118
integ *= st->
param
.interval;
119
integ *= st->
param
.gr;
120
sval = st->
param
.tmax - (
s32
)(integ >> 20);
121
adj =
min
(st->
param
.ttarget, sval);
122
123
DBG
(
"integ: %lx, sval: %lx, adj: %lx\n"
, integ, sval, adj);
124
125
/* Calculate derivative term */
126
deriv = st->
temps
[st->
tindex
] -
127
st->
temps
[(st->
tindex
+ 2 - 1) % 2];
128
deriv /= st->
param
.interval;
129
deriv *= st->
param
.gd;
130
131
/* Calculate proportional term */
132
prop = st->
last_delta
= (new_temp - adj);
133
prop *= st->
param
.gp;
134
135
DBG
(
"deriv: %lx, prop: %lx\n"
, deriv, prop);
136
137
/* Calculate target */
138
target = st->
target
+ (
s32
)((deriv + prop) >> 36);
139
target =
max
(target, st->
param
.min);
140
target =
min
(target, st->
param
.max);
141
st->
target
=
target
;
142
143
return
st->
target
;
144
}
145
EXPORT_SYMBOL_GPL
(
wf_cpu_pid_run
);
146
147
MODULE_AUTHOR
(
"Benjamin Herrenschmidt <
[email protected]
>"
);
148
MODULE_DESCRIPTION
(
"PID algorithm for PowerMacs thermal control"
);
149
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 13:43:32 for Linux Kernel by
1.8.2