diff options
Diffstat (limited to 'usr/src/uts/sun4u/sys/ppmvar.h')
| -rw-r--r-- | usr/src/uts/sun4u/sys/ppmvar.h | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/usr/src/uts/sun4u/sys/ppmvar.h b/usr/src/uts/sun4u/sys/ppmvar.h new file mode 100644 index 0000000000..9b5a2ae1ae --- /dev/null +++ b/usr/src/uts/sun4u/sys/ppmvar.h @@ -0,0 +1,378 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _SYS_PPMVAR_H +#define _SYS_PPMVAR_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/epm.h> +#include <sys/sunldi.h> + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct ppm_unit { + dev_info_t *dip; /* node dev info */ + kmutex_t lock; /* global driver lock */ + uint_t states; /* driver states */ + timeout_id_t led_tid; /* timeout id for LED */ +} ppm_unit_t; + +/* + * driver states + */ +#define PPM_STATE_SUSPENDED 0x1 /* driver is suspended */ + +/* + * Check for domain operational + */ +#define PPM_DOMAIN_UP(domp) (!(domp->dflags & PPMD_OFFLINE)) + +/* + * LED constants + */ +#define PPM_LED_PULSE (drv_usectohz(250000)) /* 0.25 seconds */ +#define PPM_LEDON_INTERVAL (1 * PPM_LED_PULSE) +#define PPM_LEDOFF_INTERVAL (8 * PPM_LED_PULSE) +#define PPM_LEDON 1 /* (s10) */ +#define PPM_LEDOFF 0 /* (s10) */ + +/* + * internal form of "ppm.conf" data + */ +struct ppm_db { + struct ppm_db *next; + char *name; /* device name */ + int plen; /* strlen before wildcard(s10) */ + int wccnt; /* upto 2 '*' allowed */ + int wcpos[2]; /* '*' location in pathname */ +}; +typedef struct ppm_db ppm_db_t; + +struct ppm_cdata { + char *name; /* property name */ + char **strings; /* string array */ + uint_t cnt; /* property count */ +}; + +/* + * ppm device info + */ +struct ppm_dev { + struct ppm_dev *next; + struct ppm_domain *domp; + dev_info_t *dip; + char *path; /* OBP device pathname */ + int cmpt; /* component number */ + int rplvl; /* last requested power level */ + int level; /* actual current power level */ + int lowest; /* lowest power level for device */ + int highest; /* highest power level for device */ + uint_t flags; +}; +typedef struct ppm_dev ppm_dev_t; + +/* + * ppm_dev.flags field + */ +#define PPMDEV_PCI66_D2 0x1 /* device support D2 at pci 66mhz */ +#define PPMDEV_PCI_PROP_CLKPM 0x2 /* clock can be power managed */ +#define PPM_PM_POWEROP 0x10 /* power level change, initiated */ + /* from PM is in progress. */ +#define PPM_PHC_WHILE_SET_POWER 0x20 /* power level of a device is */ + /* changed through */ + /* pm_power_has_changed path */ + /* while power level change, */ + /* initiated from PM is in */ + /* progress. */ + + +/* + * per domain record of device _ever_ managed by ppm + */ +struct ppm_owned { + struct ppm_owned *next; + char *path; /* device pathname */ + int initializing; /* initializing flag */ +}; +typedef struct ppm_owned ppm_owned_t; + + +/* + * domain control data structure - + * when you need to do an op for a domain, look up the op in the + * cmd member of the struct, and then perform the method on the + * path using iowr cmd with the args specified in val or val and + * mask or the speed index. + */ +struct ppm_dc { + struct ppm_dc *next; + ldi_handle_t lh; /* layered (ldi) handle */ + char *path; /* control device prom pathname */ + uint_t cmd; /* search key: op to be performed */ + uint_t method; /* control method / union selector */ + /* one of PPMDC_KIO, PPMDC_I2CKIO, */ + /* PPMDC_CPUSPEEDKIO */ + + union { + /* In each sub struct in union, the first three fields */ + /* must be .iord, .iowr and .val and in such order. */ + /* The .method field above selects a union sub struct */ + /* for a particular .cmd operation. */ + /* The association between .method and .cmd is platform */ + /* specific, therefore described in ppm.conf file. */ + + /* PPMDC_KIO: simple KIO */ + struct m_kio { + uint_t iord; /* IOCTL read cmd */ + uint_t iowr; /* IOCTL write cmd */ + uint_t val; /* ioctl arg */ + uint_t delay; /* total delay before this */ + /* operation can be carried out */ + uint_t post_delay; /* post delay, if any */ + } kio; + + /* PPMDC_I2CKIO: KIO requires 'arg' as struct i2c_gpio */ + /* (defined in i2c_client.h) */ + struct m_i2ckio { + uint_t iord; /* IOCTL read cmd */ + uint_t iowr; /* IOCTL write cmd */ + uint_t val; /* register content */ + uint_t mask; /* mask to select relevant bits */ + /* of register content */ + uint_t delay; /* total delay before this */ + /* operation can be carried out */ + uint_t post_delay; /* post delay, if any */ + } i2c; + + /* PPMDC_CPUSPEEDKIO, PPMDC_VCORE: cpu estar related */ + /* simple KIO */ + struct m_cpu { + uint_t iord; /* IOCTL read cmd */ + uint_t iowr; /* IOCTL write cmd */ + int val; /* new register value */ + uint_t speeds; /* number of speeds cpu supports */ + uint_t delay; /* microseconds post op delay */ + } cpu; + } m_un; +}; +typedef struct ppm_dc ppm_dc_t; + +/* + * ppm_dc.cmd field - + */ +#define PPMDC_CPU_NEXT 2 +#define PPMDC_PRE_CHNG 3 +#define PPMDC_CPU_GO 4 +#define PPMDC_POST_CHNG 5 +#define PPMDC_FET_ON 6 +#define PPMDC_FET_OFF 7 +#define PPMDC_LED_ON 8 +#define PPMDC_LED_OFF 9 +#define PPMDC_CLK_ON 10 +#define PPMDC_CLK_OFF 11 +#define PPMDC_PRE_PWR_OFF 12 +#define PPMDC_PRE_PWR_ON 13 +#define PPMDC_POST_PWR_ON 14 +#define PPMDC_PWR_OFF 15 +#define PPMDC_PWR_ON 16 +#define PPMDC_RESET_OFF 17 +#define PPMDC_RESET_ON 18 + +/* + * ppm_dc.method field - select union element + */ +#define PPMDC_KIO 1 /* simple ioctl with val as arg */ +#define PPMDC_CPUSPEEDKIO 2 /* ioctl with speed index arg */ +#define PPMDC_VCORE 3 /* CPU Vcore change operation */ +#define PPMDC_I2CKIO 4 /* ioctl with i2c_gpio_t as arg */ + +/* + * devices that are powered by the same source + * are grouped by this struct as a "power domain" + */ +struct ppm_domain { + char *name; /* domain name */ + int dflags; /* domain flags */ + int pwr_cnt; /* number of powered up devices */ + ppm_db_t *conflist; /* all devices from ppm.conf file */ + ppm_dev_t *devlist; /* current attached devices */ + char *propname; /* domain property name */ + kmutex_t lock; /* domain lock */ + int refcnt; /* domain lock ref count */ + int model; /* pm model, CPU, FET or LED */ + int status; /* domain specific status */ + ppm_dc_t *dc; /* domain control method */ + ppm_owned_t *owned; /* list of ever owned devices */ + struct ppm_domain *next; /* a linked list */ + clock_t last_off_time; /* last time domain was off */ + +}; +typedef struct ppm_domain ppm_domain_t; + + +/* + * ppm_domain.model field - + */ +#define PPMD_CPU 1 /* cpu PM model */ +#define PPMD_FET 2 /* power FET pm model */ +#define PPMD_LED 3 /* LED pm model */ +#define PPMD_PCI 4 /* PCI pm model */ +#define PPMD_PCI_PROP 5 /* PCI_PROP pm model */ +#define PPMD_PCIE 6 /* PCI Express pm model */ + +#define PPMD_IS_PCI(model) \ + ((model) == PPMD_PCI || (model) == PPMD_PCI_PROP) + +/* + * ppm_domain.status field - + */ +#define PPMD_OFF 0x0 /* FET/LED/PCI clock: off */ +#define PPMD_ON 0x1 /* FET/LED/PCI clock: on */ + +/* + * ppm_domain.dflags field - + */ +#define PPMD_LOCK_ONE 0x1 +#define PPMD_LOCK_ALL 0x4 +#define PPMD_PCI33MHZ 0x1000 /* 33mhz PCI slot */ +#define PPMD_PCI66MHZ 0x2000 /* 66mhz PCI slot */ +#define PPMD_INITCHILD_CLKON 0x4000 /* clk turned on in init_child */ +#define PPMD_OFFLINE 0x10000 /* domain is not functional */ + +/* + * XXppm driver-specific routines called from common code (s10) + */ +struct ppm_funcs { + void (*dev_init)(ppm_dev_t *); + void (*dev_fini)(ppm_dev_t *); + void (*iocset)(uint8_t); + uint8_t (*iocget)(void); +}; + +extern ppm_domain_t *ppm_domain_p; +extern void *ppm_statep; +extern int ppm_inst; +extern ppm_domain_t *ppm_domains[]; /* (s10) */ +extern struct ppm_funcs ppmf; /* (s10) */ + +extern void ppm_dev_init(ppm_dev_t *); +extern void ppm_dev_fini(ppm_dev_t *); +extern int ppm_create_db(dev_info_t *); +extern int ppm_claim_dev(dev_info_t *); +extern void ppm_rem_dev(dev_info_t *); +extern ppm_dev_t *ppm_get_dev(dev_info_t *, ppm_domain_t *); +extern void ppm_init_cb(dev_info_t *); +extern int ppm_init_lyr(ppm_dc_t *, dev_info_t *); +extern ppm_domain_t *ppm_lookup_dev(dev_info_t *); +extern ppm_domain_t *ppm_lookup_domain(char *); +extern ppm_dc_t *ppm_lookup_dc(ppm_domain_t *, int); +extern ppm_dc_t *ppm_lookup_hndl(int, ppm_dc_t *); +extern ppm_domain_t *ppm_get_domain_by_dev(const char *); +extern boolean_t ppm_none_else_holds_power(ppm_domain_t *); +extern ppm_owned_t *ppm_add_owned(dev_info_t *, ppm_domain_t *); +extern void ppm_lock_one(ppm_dev_t *, power_req_t *, int *); +extern void ppm_lock_all(ppm_domain_t *, power_req_t *, int *); + +#define PPM_GET_PRIVATE(dip) \ + DEVI(dip)->devi_pm_ppm_private +#define PPM_SET_PRIVATE(dip, datap) \ + DEVI(dip)->devi_pm_ppm_private = datap + +#define PPM_LOCK_DOMAIN(domp) { \ + if (!MUTEX_HELD(&(domp)->lock)) \ + mutex_enter(&(domp)->lock); \ + (domp)->refcnt++; \ +} + +#define PPM_UNLOCK_DOMAIN(domp) { \ + ASSERT(MUTEX_HELD(&(domp)->lock) && \ + (domp)->refcnt > 0); \ + if (--(domp)->refcnt == 0) \ + mutex_exit(&(domp)->lock); \ +} + +/* + * debug support + */ +#ifdef DEBUG +#include <sys/promif.h> + +extern char *ppm_get_ctlstr(int, uint_t); +extern void ppm_print_dc(struct ppm_dc *); + +extern uint_t ppm_debug; + +#define D_CREATEDB 0x00000001 +#define D_CLAIMDEV 0x00000002 +#define D_ADDDEV 0x00000004 +#define D_REMDEV 0x00000008 +#define D_LOWEST 0x00000010 +#define D_SETLVL 0x00000020 +#define D_GPIO 0x00000040 +#define D_CPU 0x00000080 +#define D_FET 0x00000100 +#define D_PCIUPA 0x00000200 +#define D_1394 0x00000400 +#define D_CTLOPS1 0x00000800 +#define D_CTLOPS2 0x00001000 +#define D_SOME 0x00002000 +#define D_LOCKS 0x00004000 +#define D_IOCTL 0x00008000 +#define D_ATTACH 0x00010000 +#define D_DETACH 0x00020000 +#define D_OPEN 0x00040000 +#define D_CLOSE 0x00080000 +#define D_INIT 0x00100000 +#define D_FINI 0x00200000 +#define D_ERROR 0x00400000 +#define D_SETPWR 0x00800000 +#define D_LED 0x01000000 +#define D_PCI 0x02000000 +#define D_PPMDC 0x04000000 +#define D_CPR 0x08000000 + +#define PPMD(level, arglist) { \ + if (ppm_debug & (level)) { \ + pm_log arglist; \ + } \ +} +/* (s10) */ +#define DPRINTF PPMD + +#else /* DEBUG */ +#define PPMD(level, arglist) +#define DPRINTF(flag, args) /* (s10) */ +#endif /* DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_PPMVAR_H */ |
