aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Krafft <krafft@de.ibm.com>2007-04-23 15:35:41 -0400
committerArnd Bergmann <arnd@klappe.arndb.de>2007-04-23 15:44:39 -0400
commit5f7bdaee2aaf7dfdf18c735dee62401fd26c8d72 (patch)
tree579067e1c368bfb7888e1c51fbdfb8d77d8ba6aa
parent24d560d7b9cf90451c6ef6248c09fb4cee1c76e6 (diff)
[POWERPC] cbe_thermal: add throttling attributes to cpu and spu nodes
This patch adds some attributes the cpu and spu nodes: /sys/devices/system/[c|s]pu/[c|s]pu*/thermal/throttle_begin /sys/devices/system/[c|s]pu/[c|s]pu*/thermal/throttle_end /sys/devices/system/[c|s]pu/[c|s]pu*/thermal/throttle_full_stop Signed-off-by: Christian Krafft <krafft@de.ibm.com> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
-rw-r--r--arch/powerpc/platforms/cell/cbe_thermal.c155
1 files changed, 154 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c
index 0d486fd424a9..f370f0fa6f4c 100644
--- a/arch/powerpc/platforms/cell/cbe_thermal.c
+++ b/arch/powerpc/platforms/cell/cbe_thermal.c
@@ -1,6 +1,31 @@
1/* 1/*
2 * thermal support for the cell processor 2 * thermal support for the cell processor
3 * 3 *
4 * This module adds some sysfs attributes to cpu and spu nodes.
5 * Base for measurements are the digital thermal sensors (DTS)
6 * located on the chip.
7 * The accuracy is 2 degrees, starting from 65 up to 125 degrees celsius
8 * The attributes can be found under
9 * /sys/devices/system/cpu/cpuX/thermal
10 * /sys/devices/system/spu/spuX/thermal
11 *
12 * The following attributes are added for each node:
13 * temperature:
14 * contains the current temperature measured by the DTS
15 * throttle_begin:
16 * throttling begins when temperature is greater or equal to
17 * throttle_begin. Setting this value to 125 prevents throttling.
18 * throttle_end:
19 * throttling is being ceased, if the temperature is lower than
20 * throttle_end. Due to a delay between applying throttling and
21 * a reduced temperature this value should be less than throttle_begin.
22 * A value equal to throttle_begin provides only a very little hysteresis.
23 * throttle_full_stop:
24 * If the temperatrue is greater or equal to throttle_full_stop,
25 * full throttling is applied to the cpu or spu. This value should be
26 * greater than throttle_begin and throttle_end. Setting this value to
27 * 65 prevents the unit from running code at all.
28 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 29 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 * 30 *
6 * Author: Christian Krafft <krafft@de.ibm.com> 31 * Author: Christian Krafft <krafft@de.ibm.com>
@@ -31,9 +56,24 @@
31#include "cbe_regs.h" 56#include "cbe_regs.h"
32#include "spu_priv1_mmio.h" 57#include "spu_priv1_mmio.h"
33 58
59#define TEMP_MIN 65
60#define TEMP_MAX 125
61
62#define SYSDEV_PREFIX_ATTR(_prefix,_name,_mode) \
63struct sysdev_attribute attr_ ## _prefix ## _ ## _name = { \
64 .attr = { .name = __stringify(_name), .mode = _mode }, \
65 .show = _prefix ## _show_ ## _name, \
66 .store = _prefix ## _store_ ## _name, \
67};
68
34static inline u8 reg_to_temp(u8 reg_value) 69static inline u8 reg_to_temp(u8 reg_value)
35{ 70{
36 return ((reg_value & 0x3f) << 1) + 65; 71 return ((reg_value & 0x3f) << 1) + TEMP_MIN;
72}
73
74static inline u8 temp_to_reg(u8 temp)
75{
76 return ((temp - TEMP_MIN) >> 1) & 0x3f;
37} 77}
38 78
39static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev) 79static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev)
@@ -73,6 +113,73 @@ static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf)
73 return sprintf(buf, "%d\n", reg_to_temp(value)); 113 return sprintf(buf, "%d\n", reg_to_temp(value));
74} 114}
75 115
116static ssize_t show_throttle(struct cbe_pmd_regs __iomem *pmd_regs, char *buf, int pos)
117{
118 u64 value;
119
120 value = in_be64(&pmd_regs->tm_tpr.val);
121 /* access the corresponding byte */
122 value >>= pos;
123 value &= 0x3F;
124
125 return sprintf(buf, "%d\n", reg_to_temp(value));
126}
127
128static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char *buf, size_t size, int pos)
129{
130 u64 reg_value;
131 int temp;
132 u64 new_value;
133 int ret;
134
135 ret = sscanf(buf, "%u", &temp);
136
137 if (ret != 1 || temp < TEMP_MIN || temp > TEMP_MAX)
138 return -EINVAL;
139
140 new_value = temp_to_reg(temp);
141
142 reg_value = in_be64(&pmd_regs->tm_tpr.val);
143
144 /* zero out bits for new value */
145 reg_value &= ~(0xffull << pos);
146 /* set bits to new value */
147 reg_value |= new_value << pos;
148
149 out_be64(&pmd_regs->tm_tpr.val, reg_value);
150 return size;
151}
152
153static ssize_t spu_show_throttle_end(struct sys_device *sysdev, char *buf)
154{
155 return show_throttle(get_pmd_regs(sysdev), buf, 0);
156}
157
158static ssize_t spu_show_throttle_begin(struct sys_device *sysdev, char *buf)
159{
160 return show_throttle(get_pmd_regs(sysdev), buf, 8);
161}
162
163static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
164{
165 return show_throttle(get_pmd_regs(sysdev), buf, 16);
166}
167
168static ssize_t spu_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
169{
170 return store_throttle(get_pmd_regs(sysdev), buf, size, 0);
171}
172
173static ssize_t spu_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
174{
175 return store_throttle(get_pmd_regs(sysdev), buf, size, 8);
176}
177
178static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
179{
180 return store_throttle(get_pmd_regs(sysdev), buf, size, 16);
181}
182
76static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos) 183static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
77{ 184{
78 struct cbe_pmd_regs __iomem *pmd_regs; 185 struct cbe_pmd_regs __iomem *pmd_regs;
@@ -100,13 +207,52 @@ static ssize_t ppe_show_temp1(struct sys_device *sysdev, char *buf)
100 return ppe_show_temp(sysdev, buf, 0); 207 return ppe_show_temp(sysdev, buf, 0);
101} 208}
102 209
210static ssize_t ppe_show_throttle_end(struct sys_device *sysdev, char *buf)
211{
212 return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 32);
213}
214
215static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev, char *buf)
216{
217 return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 40);
218}
219
220static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
221{
222 return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 48);
223}
224
225static ssize_t ppe_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
226{
227 return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 32);
228}
229
230static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
231{
232 return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 40);
233}
234
235static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
236{
237 return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 48);
238}
239
240
103static struct sysdev_attribute attr_spu_temperature = { 241static struct sysdev_attribute attr_spu_temperature = {
104 .attr = {.name = "temperature", .mode = 0400 }, 242 .attr = {.name = "temperature", .mode = 0400 },
105 .show = spu_show_temp, 243 .show = spu_show_temp,
106}; 244};
107 245
246static SYSDEV_PREFIX_ATTR(spu, throttle_end, 0600);
247static SYSDEV_PREFIX_ATTR(spu, throttle_begin, 0600);
248static SYSDEV_PREFIX_ATTR(spu, throttle_full_stop, 0600);
249
250
108static struct attribute *spu_attributes[] = { 251static struct attribute *spu_attributes[] = {
109 &attr_spu_temperature.attr, 252 &attr_spu_temperature.attr,
253 &attr_spu_throttle_end.attr,
254 &attr_spu_throttle_begin.attr,
255 &attr_spu_throttle_full_stop.attr,
110 NULL, 256 NULL,
111}; 257};
112 258
@@ -125,9 +271,16 @@ static struct sysdev_attribute attr_ppe_temperature1 = {
125 .show = ppe_show_temp1, 271 .show = ppe_show_temp1,
126}; 272};
127 273
274static SYSDEV_PREFIX_ATTR(ppe, throttle_end, 0600);
275static SYSDEV_PREFIX_ATTR(ppe, throttle_begin, 0600);
276static SYSDEV_PREFIX_ATTR(ppe, throttle_full_stop, 0600);
277
128static struct attribute *ppe_attributes[] = { 278static struct attribute *ppe_attributes[] = {
129 &attr_ppe_temperature0.attr, 279 &attr_ppe_temperature0.attr,
130 &attr_ppe_temperature1.attr, 280 &attr_ppe_temperature1.attr,
281 &attr_ppe_throttle_end.attr,
282 &attr_ppe_throttle_begin.attr,
283 &attr_ppe_throttle_full_stop.attr,
131 NULL, 284 NULL,
132}; 285};
133 286