xref: /illumos-gate/usr/src/uts/sun4u/sys/pci/pci_pwr.h (revision 2aeafac3612e19716bf8164f89c3c9196342979c)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_PCI_PWR_H
28 #define	_SYS_PCI_PWR_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/epm.h>
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 /*
39  * An element of this structure type is allocated for
40  * each PCI child to track power info.
41  */
42 typedef struct pci_pwr_chld {
43 	dev_info_t		*dip;	/* node this struct represents */
44 	int			dev_cap;
45 					/* The clock capability the device */
46 					/* reports it  can operate. */
47 	int			bus_speed;
48 					/* the speed of the bus for this */
49 					/* device during E* */
50 	struct pci_pwr_chld	*next;	/* link to next item on list */
51 	int			flags;	/* State for entire device */
52 	int			*comp_pwr; /* state for each component */
53 	int			num_comps; /* size of comp_pwr */
54 	int			u01;	/* # comps in UNKNOWN, D0, D1 */
55 } pci_pwr_chld_t;
56 
57 /*
58  * For each PCI nexus instance that is PM capable, it will have
59  * the following structure allocated.
60  */
61 typedef struct pci_pwr {
62 	/*
63 	 * cpr and power management support:
64 	 */
65 	kmutex_t	pwr_mutex;
66 	int		current_lvl; /* power level of bus */
67 	dev_info_t	*pwr_dip;	/* dip of nexus */
68 	pci_pwr_chld_t	*pwr_info;	/* linked list of children */
69 	int		pwr_flags;	/* power management flags */
70 	int		pwr_fp;		/* # requiring full power */
71 	int		pwr_uk;		/* # at unknown PM state */
72 	int		pwr_d0;		/* # at d0 PM state */
73 	int		pwr_d1;		/* # at d1 PM state */
74 	int		pwr_d2;		/* # at d2 PM state */
75 	int		pwr_d3;		/* # at d3 PM state */
76 
77 } pci_pwr_t;
78 
79 #define	PCI_CLK_SETTLE_TIME	10000 /* settle time before PCI operation */
80 
81 /*
82  * ret this if unable to det slot speed while in slow mode
83  */
84 #define	INVALID_BUS_SPEED	-1
85 
86 /*
87  * XXX Number of components for dip.  This needs to be provided by DDI.
88  */
89 #define	PM_NUMCMPTS(dip)	(DEVI(dip)->devi_pm_num_components)
90 
91 /*
92  * Label for component 0
93  */
94 #define	PCI_PM_COMP_0	0
95 
96 /*
97  * Bus levels returned by pci_pwr_new_lvl(). In addition to
98  * PM_LEVEL_B[0-3], a level is needed for variable clock
99  * mode.  These levels MUST correspond to the levels specified
100  * in the pm-components property.
101  */
102 #define	PM_LEVEL_DYN	1
103 #define	PM_LEVEL_B3	0
104 #define	PM_LEVEL_B2	1
105 #define	PM_LEVEL_B1	2
106 #define	PM_LEVEL_B0	3
107 
108 /*
109  * PCI clock speeds for slow mode (expressed in KHz)
110  */
111 #define	PCI_1MHZ	1000
112 #define	PCI_4MHZ	(4 * PCI_1MHZ)
113 
114 /*
115  * Bit values for struct pci_pwr.pwr_flags
116  */
117 #define	PCI_PWR_PARKING		0x01 /* Need to re-enable parking */
118 #define	PCI_PWR_SLOW_CAPABLE	0x02 /* HW supports reduced clock speeds */
119 #define	PCI_PWR_B1_CAPABLE	0x04 /* HW supports B1 state */
120 #define	PCI_PWR_B2_CAPABLE	0x08 /* HW supports B2 state */
121 #define	PCI_PWR_B3_CAPABLE	0x10 /* HW supports B3 state */
122 #define	PCI_PWR_COMP_BUSY	0x20 /* component set busy */
123 
124 /*
125  * State flags for each device (struct pci_pwr_chld.flags)
126  */
127 #define	PWR_FP_HOLD		0x01	/* pwr_fp counted for this dev */
128 
129 /*
130  * Arbitrary level that pci_pwr_chld.comp_pwr is initialized
131  */
132 #define	PM_LEVEL_NOLEVEL	-2
133 
134 #define	PM_CAPABLE(pwr_p)	(pwr_p != NULL)
135 #define	SLOW_CAPABLE(pwr_p)	((pwr_p->pwr_flags &\
136 				PCI_PWR_SLOW_CAPABLE) ==\
137 				PCI_PWR_SLOW_CAPABLE)
138 
139 /*
140  * Binary prop used by suspend/resume if it saved config regs
141  */
142 #define	NEXUS_SAVED "nexus-saved-config-regs"
143 
144 extern void pci_pwr_component_busy(pci_pwr_t *pwr_p);
145 extern void pci_pwr_component_idle(pci_pwr_t *pwr_p);
146 extern int pci_pwr_current_lvl(pci_pwr_t *pwr_p);
147 extern int pci_pwr_new_lvl(pci_pwr_t *pwr_p);
148 extern int pci_pwr_ops(pci_pwr_t *pwr_p, dev_info_t *dip, void *impl_arg,
149     pm_bus_power_op_t op, void *arg, void *result);
150 extern pci_pwr_chld_t *pci_pwr_get_info(pci_pwr_t *pwr_p, dev_info_t *);
151 extern void pci_pwr_create_info(pci_pwr_t *pwr_p, dev_info_t *);
152 extern void pci_pwr_rm_info(pci_pwr_t *pwr_p, dev_info_t *);
153 extern void pci_pwr_add_components(pci_pwr_t *pwr_p, dev_info_t *dip,
154     pci_pwr_chld_t *p);
155 extern void pci_pwr_resume(dev_info_t *dip, pci_pwr_t *pwr_p);
156 extern void pci_pwr_suspend(dev_info_t *dip, pci_pwr_t *pwr_p);
157 extern void pci_pwr_component_busy(pci_pwr_t *p);
158 extern void pci_pwr_component_idle(pci_pwr_t *p);
159 extern void pci_pwr_change(pci_pwr_t *pwr_p, int current, int new);
160 
161 #ifdef	__cplusplus
162 }
163 #endif
164 
165 #endif	/* _SYS_PCI_PWR_H */
166