Merge commit '7e3488dc6cdcb0c04e1ce167a1a3bfef83b5f2e0'
[unleashed.git] / include / sys / ppmvar.h
blob4e7f0a6b2afdebf1b2c566f0c403a0afb0177868
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright (c) 2009, Intel Corporation.
27 * All Rights Reserved.
30 #ifndef _SYS_PPMVAR_H
31 #define _SYS_PPMVAR_H
33 #include <sys/epm.h>
34 #include <sys/sunldi.h>
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
41 typedef struct ppm_unit {
42 dev_info_t *dip; /* node dev info */
43 kmutex_t lock; /* global driver lock */
44 uint_t states; /* driver states */
45 timeout_id_t led_tid; /* timeout id for LED */
46 } ppm_unit_t;
49 * driver states
51 #define PPM_STATE_SUSPENDED 0x1 /* driver is suspended */
54 * Check for domain operational
56 #define PPM_DOMAIN_UP(domp) (!(domp->dflags & PPMD_OFFLINE))
59 * LED constants
61 #define PPM_LED_PULSE (drv_usectohz(250000)) /* 0.25 seconds */
62 #define PPM_LEDON_INTERVAL (1 * PPM_LED_PULSE)
63 #define PPM_LEDOFF_INTERVAL (8 * PPM_LED_PULSE)
64 #define PPM_LEDON 1 /* (s10) */
65 #define PPM_LEDOFF 0 /* (s10) */
68 * internal form of "ppm.conf" data
70 struct ppm_db {
71 struct ppm_db *next;
72 char *name; /* device name */
73 int plen; /* strlen before wildcard(s10) */
74 int wccnt; /* upto 2 '*' allowed */
75 int wcpos[2]; /* '*' location in pathname */
77 typedef struct ppm_db ppm_db_t;
79 struct ppm_cdata {
80 char *name; /* property name */
81 char **strings; /* string array */
82 uint_t cnt; /* property count */
86 * ppm device info
88 struct ppm_dev {
89 struct ppm_dev *next;
90 struct ppm_domain *domp;
91 dev_info_t *dip;
92 char *path; /* OBP device pathname */
93 int cmpt; /* component number */
94 int rplvl; /* last requested power level */
95 int level; /* actual current power level */
96 int lowest; /* lowest power level for device */
97 int highest; /* highest power level for device */
98 uint_t flags;
100 typedef struct ppm_dev ppm_dev_t;
103 * ppm_dev.flags field
105 #define PPMDEV_PCI66_D2 0x1 /* device support D2 at pci 66mhz */
106 #define PPMDEV_PCI_PROP_CLKPM 0x2 /* clock can be power managed */
107 #define PPM_PM_POWEROP 0x10 /* power level change, initiated */
108 /* from PM is in progress. */
109 #define PPM_PHC_WHILE_SET_POWER 0x20 /* power level of a device is */
110 /* changed through */
111 /* pm_power_has_changed path */
112 /* while power level change, */
113 /* initiated from PM is in */
114 /* progress. */
118 * per domain record of device _ever_ managed by ppm
120 struct ppm_owned {
121 struct ppm_owned *next;
122 char *path; /* device pathname */
123 int initializing; /* initializing flag */
125 typedef struct ppm_owned ppm_owned_t;
129 * domain control data structure -
130 * when you need to do an op for a domain, look up the op in the
131 * cmd member of the struct, and then perform the method on the
132 * path using iowr cmd with the args specified in val or val and
133 * mask or the speed index.
135 struct ppm_dc {
136 struct ppm_dc *next;
137 ldi_handle_t lh; /* layered (ldi) handle */
138 char *path; /* control device prom pathname */
139 uint_t cmd; /* search key: op to be performed */
140 /* one of: PPMDC_CPU_NEXT */
141 /* PPMDC_CPU_GO, PPMDC_FET_ON, */
142 /* PPMDC_FET_OFF, PPMDC_LED_ON, */
143 /* PPMDC_LED_OFF, PPMDC_PCI_ON, */
144 /* PPMDC_ENTER_S3, PPMDC_PCI_OFF */
145 /* PPMDC_EXIT_S3 commands */
146 uint_t method; /* control method / union selector */
147 /* one of PPMDC_KIO, PPMDC_I2CKIO, */
148 /* PPMDC_CPUSPEEDKIO */
150 union {
151 /* In each sub struct in union, the first three fields */
152 /* must be .iord, .iowr and .val and in such order. */
153 /* The .method field above selects a union sub struct */
154 /* for a particular .cmd operation. */
155 /* The association between .method and .cmd is platform */
156 /* specific, therefore described in ppm.conf file. */
158 /* PPMDC_KIO: simple KIO */
159 struct m_kio {
160 uint_t iord; /* IOCTL read cmd */
161 uint_t iowr; /* IOCTL write cmd */
162 uint_t val; /* ioctl arg */
163 uint_t delay; /* total delay before this */
164 /* operation can be carried out */
165 uint_t post_delay; /* post delay, if any */
166 } kio;
168 #ifdef sun4u
169 /* PPMDC_I2CKIO: KIO requires 'arg' as struct i2c_gpio */
170 /* (defined in i2c_client.h) */
171 struct m_i2ckio {
172 uint_t iord; /* IOCTL read cmd */
173 uint_t iowr; /* IOCTL write cmd */
174 uint_t val; /* register content */
175 uint_t mask; /* mask to select relevant bits */
176 /* of register content */
177 uint_t delay; /* total delay before this */
178 /* operation can be carried out */
179 uint_t post_delay; /* post delay, if any */
180 } i2c;
181 #endif
183 /* PPMDC_CPUSPEEDKIO, PPMDC_VCORE: cpu estar related */
184 /* simple KIO */
185 struct m_cpu {
186 uint_t iord; /* IOCTL read cmd */
187 uint_t iowr; /* IOCTL write cmd */
188 int val; /* new register value */
189 uint_t speeds; /* number of speeds cpu supports */
190 uint_t delay; /* microseconds post op delay */
191 } cpu;
192 } m_un;
194 typedef struct ppm_dc ppm_dc_t;
197 * ppm_dc.cmd field -
199 #define PPMDC_CPU_NEXT 2
200 #define PPMDC_PRE_CHNG 3
201 #define PPMDC_CPU_GO 4
202 #define PPMDC_POST_CHNG 5
203 #define PPMDC_FET_ON 6
204 #define PPMDC_FET_OFF 7
205 #define PPMDC_LED_ON 8
206 #define PPMDC_LED_OFF 9
207 #define PPMDC_CLK_ON 10
208 #define PPMDC_CLK_OFF 11
209 #define PPMDC_PRE_PWR_OFF 12
210 #define PPMDC_PRE_PWR_ON 13
211 #define PPMDC_POST_PWR_ON 14
212 #define PPMDC_PWR_OFF 15
213 #define PPMDC_PWR_ON 16
214 #define PPMDC_RESET_OFF 17
215 #define PPMDC_RESET_ON 18
216 #define PPMDC_ENTER_S3 19
217 #define PPMDC_EXIT_S3 20
220 * ppm_dc.method field - select union element
222 #define PPMDC_KIO 1 /* simple ioctl with val as arg */
223 #define PPMDC_CPUSPEEDKIO 2 /* ioctl with speed index arg */
224 #define PPMDC_VCORE 3 /* CPU Vcore change operation */
225 #ifdef sun4u
226 #define PPMDC_I2CKIO 4 /* ioctl with i2c_gpio_t as arg */
227 #endif
230 * devices that are powered by the same source
231 * are grouped by this struct as a "power domain"
233 struct ppm_domain {
234 char *name; /* domain name */
235 int dflags; /* domain flags */
236 int pwr_cnt; /* number of powered up devices */
237 ppm_db_t *conflist; /* all devices from ppm.conf file */
238 ppm_dev_t *devlist; /* current attached devices */
239 char *propname; /* domain property name */
240 kmutex_t lock; /* domain lock */
241 int refcnt; /* domain lock ref count */
242 int model; /* pm model, CPU, FET or LED */
243 int status; /* domain specific status */
244 int sub_domain; /* sub-domain */
245 ppm_dc_t *dc; /* domain control method */
246 ppm_owned_t *owned; /* list of ever owned devices */
247 struct ppm_domain *next; /* a linked list */
248 clock_t last_off_time; /* last time domain was off */
251 typedef struct ppm_domain ppm_domain_t;
255 * ppm_domain.model field -
257 #define PPMD_CPU 1 /* cpu PM model */
258 #define PPMD_FET 2 /* power FET pm model */
259 #define PPMD_LED 3 /* LED pm model */
260 #define PPMD_PCI 4 /* PCI pm model */
261 #define PPMD_PCI_PROP 5 /* PCI_PROP pm model */
262 #define PPMD_PCIE 6 /* PCI Express pm model */
263 #define PPMD_SX 7 /* ACPI Sx pm model */
265 #define PPMD_IS_PCI(model) \
266 ((model) == PPMD_PCI || (model) == PPMD_PCI_PROP)
269 * ppm_domain.status field -
271 #define PPMD_OFF 0x0 /* FET/LED/PCI clock: off */
272 #define PPMD_ON 0x1 /* FET/LED/PCI clock: on */
275 * ppm_domain.dflags field -
277 #define PPMD_LOCK_ONE 0x1
278 #define PPMD_LOCK_ALL 0x4
279 #define PPMD_PCI33MHZ 0x1000 /* 33mhz PCI slot */
280 #define PPMD_PCI66MHZ 0x2000 /* 66mhz PCI slot */
281 #define PPMD_INITCHILD_CLKON 0x4000 /* clk turned on in init_child */
282 #define PPMD_OFFLINE 0x10000 /* domain is not functional */
283 #define PPMD_CPU_READY 0x20000 /* CPU domain can process power call */
285 struct ppm_domit {
286 char *name;
287 int model;
288 int dflags;
289 int status;
291 extern struct ppm_domit ppm_domit_data[];
294 * XXppm driver-specific routines called from common code (s10)
296 struct ppm_funcs {
297 void (*dev_init)(ppm_dev_t *);
298 void (*dev_fini)(ppm_dev_t *);
299 void (*iocset)(uint8_t);
300 uint8_t (*iocget)(void);
303 extern ppm_domain_t *ppm_domain_p;
304 extern void *ppm_statep;
305 extern int ppm_inst;
306 extern ppm_domain_t *ppm_domains[]; /* (s10) */
307 extern struct ppm_funcs ppmf; /* (s10) */
309 extern void ppm_dev_init(ppm_dev_t *);
310 extern void ppm_dev_fini(ppm_dev_t *);
311 extern int ppm_create_db(dev_info_t *);
312 extern int ppm_claim_dev(dev_info_t *);
313 extern void ppm_rem_dev(dev_info_t *);
314 extern ppm_dev_t *ppm_get_dev(dev_info_t *, ppm_domain_t *);
315 extern void ppm_init_cb(dev_info_t *);
316 extern int ppm_init_lyr(ppm_dc_t *, dev_info_t *);
317 extern ppm_domain_t *ppm_lookup_dev(dev_info_t *);
318 extern ppm_domain_t *ppm_lookup_domain(char *);
319 extern ppm_dc_t *ppm_lookup_dc(ppm_domain_t *, int);
320 extern ppm_dc_t *ppm_lookup_hndl(int, ppm_dc_t *);
321 extern ppm_domain_t *ppm_get_domain_by_dev(const char *);
322 extern boolean_t ppm_none_else_holds_power(ppm_domain_t *);
323 extern ppm_owned_t *ppm_add_owned(dev_info_t *, ppm_domain_t *);
324 extern void ppm_lock_one(ppm_dev_t *, power_req_t *, int *);
325 extern void ppm_lock_all(ppm_domain_t *, power_req_t *, int *);
326 extern boolean_t ppm_manage_early_cpus(dev_info_t *, int, int *);
327 extern int ppm_change_cpu_power(ppm_dev_t *, int);
328 extern int ppm_revert_cpu_power(ppm_dev_t *, int);
329 extern ppm_dev_t *ppm_add_dev(dev_info_t *, ppm_domain_t *);
331 #define PPM_GET_PRIVATE(dip) \
332 DEVI(dip)->devi_pm_ppm_private
333 #define PPM_SET_PRIVATE(dip, datap) \
334 DEVI(dip)->devi_pm_ppm_private = datap
336 #define PPM_LOCK_DOMAIN(domp) { \
337 if (!MUTEX_HELD(&(domp)->lock)) \
338 mutex_enter(&(domp)->lock); \
339 (domp)->refcnt++; \
342 #define PPM_UNLOCK_DOMAIN(domp) { \
343 ASSERT(MUTEX_HELD(&(domp)->lock) && \
344 (domp)->refcnt > 0); \
345 if (--(domp)->refcnt == 0) \
346 mutex_exit(&(domp)->lock); \
350 * debug support
352 #ifdef DEBUG
353 #include <sys/promif.h>
355 extern char *ppm_get_ctlstr(int, uint_t);
356 extern void ppm_print_dc(struct ppm_dc *);
358 extern uint_t ppm_debug;
360 #define D_CREATEDB 0x00000001
361 #define D_CLAIMDEV 0x00000002
362 #define D_ADDDEV 0x00000004
363 #define D_REMDEV 0x00000008
364 #define D_LOWEST 0x00000010
365 #define D_SETLVL 0x00000020
366 #define D_GPIO 0x00000040
367 #define D_CPU 0x00000080
368 #define D_FET 0x00000100
369 #define D_PCIUPA 0x00000200
370 #define D_1394 0x00000400
371 #define D_CTLOPS1 0x00000800
372 #define D_CTLOPS2 0x00001000
373 #define D_SOME 0x00002000
374 #define D_LOCKS 0x00004000
375 #define D_IOCTL 0x00008000
376 #define D_ATTACH 0x00010000
377 #define D_DETACH 0x00020000
378 #define D_OPEN 0x00040000
379 #define D_CLOSE 0x00080000
380 #define D_INIT 0x00100000
381 #define D_FINI 0x00200000
382 #define D_ERROR 0x00400000
383 #define D_SETPWR 0x00800000
384 #define D_LED 0x01000000
385 #define D_PCI 0x02000000
386 #define D_PPMDC 0x04000000
387 #define D_CPR 0x08000000
389 #define PPMD(level, arglist) { \
390 if (ppm_debug & (level)) { \
391 pm_log arglist; \
394 /* (s10) */
395 #define DPRINTF PPMD
397 #else /* DEBUG */
398 #define PPMD(level, arglist)
399 #define DPRINTF(flag, args) /* (s10) */
400 #endif /* DEBUG */
402 #ifdef __cplusplus
404 #endif
406 #endif /* _SYS_PPMVAR_H */