aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-06 22:29:02 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-07 19:17:40 -0500
commit183d020258dfd08178a05c6793dae10409db8abb (patch)
tree5b20bc62709c94bd63e17d800544140213eaf0f5 /include
parent4350147a816b9c5b40fa59e4fa23f17490630b79 (diff)
[PATCH] ppc64: SMU partition recovery
This patch adds the ability to the SMU driver to recover missing calibration partitions from the SMU chip itself. It also adds some dynamic mecanism to /proc/device-tree so that new properties are visible to userland. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'include')
-rw-r--r--include/asm-powerpc/prom.h2
-rw-r--r--include/asm-powerpc/smu.h153
-rw-r--r--include/asm-ppc/prom.h2
-rw-r--r--include/asm-ppc64/prom.h2
-rw-r--r--include/linux/proc_fs.h9
5 files changed, 149 insertions, 19 deletions
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 7587bf5f38c6..f999df1c5c90 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -203,7 +203,7 @@ extern int prom_n_addr_cells(struct device_node* np);
203extern int prom_n_size_cells(struct device_node* np); 203extern int prom_n_size_cells(struct device_node* np);
204extern int prom_n_intr_cells(struct device_node* np); 204extern int prom_n_intr_cells(struct device_node* np);
205extern void prom_get_irq_senses(unsigned char *senses, int off, int max); 205extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
206extern void prom_add_property(struct device_node* np, struct property* prop); 206extern int prom_add_property(struct device_node* np, struct property* prop);
207 207
208#ifdef CONFIG_PPC32 208#ifdef CONFIG_PPC32
209/* 209/*
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index 959bad660233..76c29a9784dd 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -20,16 +20,52 @@
20/* 20/*
21 * Partition info commands 21 * Partition info commands
22 * 22 *
23 * I do not know what those are for at this point 23 * These commands are used to retreive the sdb-partition-XX datas from
24 * the SMU. The lenght is always 2. First byte is the subcommand code
25 * and second byte is the partition ID.
26 *
27 * The reply is 6 bytes:
28 *
29 * - 0..1 : partition address
30 * - 2 : a byte containing the partition ID
31 * - 3 : length (maybe other bits are rest of header ?)
32 *
33 * The data must then be obtained with calls to another command:
34 * SMU_CMD_MISC_ee_GET_DATABLOCK_REC (described below).
24 */ 35 */
25#define SMU_CMD_PARTITION_COMMAND 0x3e 36#define SMU_CMD_PARTITION_COMMAND 0x3e
37#define SMU_CMD_PARTITION_LATEST 0x01
38#define SMU_CMD_PARTITION_BASE 0x02
39#define SMU_CMD_PARTITION_UPDATE 0x03
26 40
27 41
28/* 42/*
29 * Fan control 43 * Fan control
30 * 44 *
31 * This is a "mux" for fan control commands, first byte is the 45 * This is a "mux" for fan control commands. The command seem to
32 * "sub" command. 46 * act differently based on the number of arguments. With 1 byte
47 * of argument, this seem to be queries for fans status, setpoint,
48 * etc..., while with 0xe arguments, we will set the fans speeds.
49 *
50 * Queries (1 byte arg):
51 * ---------------------
52 *
53 * arg=0x01: read RPM fans status
54 * arg=0x02: read RPM fans setpoint
55 * arg=0x11: read PWM fans status
56 * arg=0x12: read PWM fans setpoint
57 *
58 * the "status" queries return the current speed while the "setpoint" ones
59 * return the programmed/target speed. It _seems_ that the result is a bit
60 * mask in the first byte of active/available fans, followed by 6 words (16
61 * bits) containing the requested speed.
62 *
63 * Setpoint (14 bytes arg):
64 * ------------------------
65 *
66 * first arg byte is 0 for RPM fans and 0x10 for PWM. Second arg byte is the
67 * mask of fans affected by the command. Followed by 6 words containing the
68 * setpoint value for selected fans in the mask (or 0 if mask value is 0)
33 */ 69 */
34#define SMU_CMD_FAN_COMMAND 0x4a 70#define SMU_CMD_FAN_COMMAND 0x4a
35 71
@@ -156,6 +192,14 @@
156#define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN" 192#define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN"
157#define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW" 193#define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW"
158 194
195/*
196 * Read ADC sensors
197 *
198 * This command takes one byte of parameter: the sensor ID (or "reg"
199 * value in the device-tree) and returns a 16 bits value
200 */
201#define SMU_CMD_READ_ADC 0xd8
202
159/* Misc commands 203/* Misc commands
160 * 204 *
161 * This command seem to be a grab bag of various things 205 * This command seem to be a grab bag of various things
@@ -176,6 +220,25 @@
176 * Misc commands 220 * Misc commands
177 * 221 *
178 * This command seem to be a grab bag of various things 222 * This command seem to be a grab bag of various things
223 *
224 * SMU_CMD_MISC_ee_GET_DATABLOCK_REC is used, among others, to
225 * transfer blocks of data from the SMU. So far, I've decrypted it's
226 * usage to retreive partition data. In order to do that, you have to
227 * break your transfer in "chunks" since that command cannot transfer
228 * more than a chunk at a time. The chunk size used by OF is 0xe bytes,
229 * but it seems that the darwin driver will let you do 0x1e bytes if
230 * your "PMU" version is >= 0x30. You can get the "PMU" version apparently
231 * either in the last 16 bits of property "smu-version-pmu" or as the 16
232 * bytes at offset 1 of "smu-version-info"
233 *
234 * For each chunk, the command takes 7 bytes of arguments:
235 * byte 0: subcommand code (0x02)
236 * byte 1: 0x04 (always, I don't know what it means, maybe the address
237 * space to use or some other nicety. It's hard coded in OF)
238 * byte 2..5: SMU address of the chunk (big endian 32 bits)
239 * byte 6: size to transfer (up to max chunk size)
240 *
241 * The data is returned directly
179 */ 242 */
180#define SMU_CMD_MISC_ee_COMMAND 0xee 243#define SMU_CMD_MISC_ee_COMMAND 0xee
181#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02 244#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02
@@ -353,21 +416,26 @@ struct smu_sdbp_header {
353 __u8 flags; 416 __u8 flags;
354}; 417};
355 418
356/* 419
357 * 32 bits integers are usually encoded with 2x16 bits swapped, 420 /*
358 * this demangles them 421 * demangle 16 and 32 bits integer in some SMU partitions
422 * (currently, afaik, this concerns only the FVT partition
423 * (0x12)
359 */ 424 */
360#define SMU_U32_MIX(x) ((((x) << 16) & 0xffff0000u) | (((x) >> 16) & 0xffffu)) 425#define SMU_U16_MIX(x) le16_to_cpu(x);
426#define SMU_U32_MIX(x) ((((x) & 0xff00ff00u) >> 8)|(((x) & 0x00ff00ffu) << 8))
427
361 428
362/* This is the definition of the SMU sdb-partition-0x12 table (called 429/* This is the definition of the SMU sdb-partition-0x12 table (called
363 * CPU F/V/T operating points in Darwin). The definition for all those 430 * CPU F/V/T operating points in Darwin). The definition for all those
364 * SMU tables should be moved to some separate file 431 * SMU tables should be moved to some separate file
365 */ 432 */
366#define SMU_SDB_FVT_ID 0x12 433#define SMU_SDB_FVT_ID 0x12
367 434
368struct smu_sdbp_fvt { 435struct smu_sdbp_fvt {
369 __u32 sysclk; /* Base SysClk frequency in Hz for 436 __u32 sysclk; /* Base SysClk frequency in Hz for
370 * this operating point 437 * this operating point. Value need to
438 * be unmixed with SMU_U32_MIX()
371 */ 439 */
372 __u8 pad; 440 __u8 pad;
373 __u8 maxtemp; /* Max temp. supported by this 441 __u8 maxtemp; /* Max temp. supported by this
@@ -376,10 +444,73 @@ struct smu_sdbp_fvt {
376 444
377 __u16 volts[3]; /* CPU core voltage for the 3 445 __u16 volts[3]; /* CPU core voltage for the 3
378 * PowerTune modes, a mode with 446 * PowerTune modes, a mode with
379 * 0V = not supported. 447 * 0V = not supported. Value need
448 * to be unmixed with SMU_U16_MIX()
380 */ 449 */
381}; 450};
382 451
452/* This partition contains voltage & current sensor calibration
453 * informations
454 */
455#define SMU_SDB_CPUVCP_ID 0x21
456
457struct smu_sdbp_cpuvcp {
458 __u16 volt_scale; /* u4.12 fixed point */
459 __s16 volt_offset; /* s4.12 fixed point */
460 __u16 curr_scale; /* u4.12 fixed point */
461 __s16 curr_offset; /* s4.12 fixed point */
462 __s32 power_quads[3]; /* s4.28 fixed point */
463};
464
465/* This partition contains CPU thermal diode calibration
466 */
467#define SMU_SDB_CPUDIODE_ID 0x18
468
469struct smu_sdbp_cpudiode {
470 __u16 m_value; /* u1.15 fixed point */
471 __s16 b_value; /* s10.6 fixed point */
472
473};
474
475/* This partition contains Slots power calibration
476 */
477#define SMU_SDB_SLOTSPOW_ID 0x78
478
479struct smu_sdbp_slotspow {
480 __u16 pow_scale; /* u4.12 fixed point */
481 __s16 pow_offset; /* s4.12 fixed point */
482};
483
484/* This partition contains machine specific version information about
485 * the sensor/control layout
486 */
487#define SMU_SDB_SENSORTREE_ID 0x25
488
489struct smu_sdbp_sensortree {
490 u8 model_id;
491 u8 unknown[3];
492};
493
494/* This partition contains CPU thermal control PID informations. So far
495 * only single CPU machines have been seen with an SMU, so we assume this
496 * carries only informations for those
497 */
498#define SMU_SDB_CPUPIDDATA_ID 0x17
499
500struct smu_sdbp_cpupiddata {
501 u8 unknown1;
502 u8 target_temp_delta;
503 u8 unknown2;
504 u8 history_len;
505 s16 power_adj;
506 u16 max_power;
507 s32 gp,gr,gd;
508};
509
510
511/* Other partitions without known structures */
512#define SMU_SDB_DEBUG_SWITCHES_ID 0x05
513
383#ifdef __KERNEL__ 514#ifdef __KERNEL__
384/* 515/*
385 * This returns the pointer to an SMU "sdb" partition data or NULL 516 * This returns the pointer to an SMU "sdb" partition data or NULL
@@ -423,8 +554,10 @@ struct smu_user_cmd_hdr
423 __u32 cmdtype; 554 __u32 cmdtype;
424#define SMU_CMDTYPE_SMU 0 /* SMU command */ 555#define SMU_CMDTYPE_SMU 0 /* SMU command */
425#define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */ 556#define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */
557#define SMU_CMDTYPE_GET_PARTITION 2 /* retreive an sdb partition */
426 558
427 __u8 cmd; /* SMU command byte */ 559 __u8 cmd; /* SMU command byte */
560 __u8 pad[3]; /* padding */
428 __u32 data_len; /* Lenght of data following */ 561 __u32 data_len; /* Lenght of data following */
429}; 562};
430 563
diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h
index 75c0637acdc8..3e39827ed566 100644
--- a/include/asm-ppc/prom.h
+++ b/include/asm-ppc/prom.h
@@ -93,7 +93,7 @@ extern int device_is_compatible(struct device_node *device, const char *);
93extern int machine_is_compatible(const char *compat); 93extern int machine_is_compatible(const char *compat);
94extern unsigned char *get_property(struct device_node *node, const char *name, 94extern unsigned char *get_property(struct device_node *node, const char *name,
95 int *lenp); 95 int *lenp);
96extern void prom_add_property(struct device_node* np, struct property* prop); 96extern int prom_add_property(struct device_node* np, struct property* prop);
97extern void prom_get_irq_senses(unsigned char *, int, int); 97extern void prom_get_irq_senses(unsigned char *, int, int);
98extern int prom_n_addr_cells(struct device_node* np); 98extern int prom_n_addr_cells(struct device_node* np);
99extern int prom_n_size_cells(struct device_node* np); 99extern int prom_n_size_cells(struct device_node* np);
diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h
index bdb47174ff0e..76bb0266d67c 100644
--- a/include/asm-ppc64/prom.h
+++ b/include/asm-ppc64/prom.h
@@ -213,6 +213,6 @@ extern int prom_n_addr_cells(struct device_node* np);
213extern int prom_n_size_cells(struct device_node* np); 213extern int prom_n_size_cells(struct device_node* np);
214extern int prom_n_intr_cells(struct device_node* np); 214extern int prom_n_intr_cells(struct device_node* np);
215extern void prom_get_irq_senses(unsigned char *senses, int off, int max); 215extern void prom_get_irq_senses(unsigned char *senses, int off, int max);
216extern void prom_add_property(struct device_node* np, struct property* prop); 216extern int prom_add_property(struct device_node* np, struct property* prop);
217 217
218#endif /* _PPC64_PROM_H */ 218#endif /* _PPC64_PROM_H */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 0563581e3a02..65ceeaa30652 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -139,15 +139,12 @@ extern void proc_tty_unregister_driver(struct tty_driver *driver);
139/* 139/*
140 * proc_devtree.c 140 * proc_devtree.c
141 */ 141 */
142#ifdef CONFIG_PROC_DEVICETREE
142struct device_node; 143struct device_node;
144struct property;
143extern void proc_device_tree_init(void); 145extern void proc_device_tree_init(void);
144#ifdef CONFIG_PROC_DEVICETREE
145extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *); 146extern void proc_device_tree_add_node(struct device_node *, struct proc_dir_entry *);
146#else /* !CONFIG_PROC_DEVICETREE */ 147extern void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop);
147static inline void proc_device_tree_add_node(struct device_node *np, struct proc_dir_entry *pde)
148{
149 return;
150}
151#endif /* CONFIG_PROC_DEVICETREE */ 148#endif /* CONFIG_PROC_DEVICETREE */
152 149
153extern struct proc_dir_entry *proc_symlink(const char *, 150extern struct proc_dir_entry *proc_symlink(const char *,