xref: /titanic_52/usr/src/uts/common/sys/pcie_pwr.h (revision e762302f03f5529f83d98085b915143b08d3ae1b)
1d4bc0535SKrishna Elango /*
2d4bc0535SKrishna Elango  * CDDL HEADER START
3d4bc0535SKrishna Elango  *
4d4bc0535SKrishna Elango  * The contents of this file are subject to the terms of the
5d4bc0535SKrishna Elango  * Common Development and Distribution License (the "License").
6d4bc0535SKrishna Elango  * You may not use this file except in compliance with the License.
7d4bc0535SKrishna Elango  *
8d4bc0535SKrishna Elango  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d4bc0535SKrishna Elango  * or http://www.opensolaris.org/os/licensing.
10d4bc0535SKrishna Elango  * See the License for the specific language governing permissions
11d4bc0535SKrishna Elango  * and limitations under the License.
12d4bc0535SKrishna Elango  *
13d4bc0535SKrishna Elango  * When distributing Covered Code, include this CDDL HEADER in each
14d4bc0535SKrishna Elango  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d4bc0535SKrishna Elango  * If applicable, add the following below this CDDL HEADER, with the
16d4bc0535SKrishna Elango  * fields enclosed by brackets "[]" replaced with your own identifying
17d4bc0535SKrishna Elango  * information: Portions Copyright [yyyy] [name of copyright owner]
18d4bc0535SKrishna Elango  *
19d4bc0535SKrishna Elango  * CDDL HEADER END
20d4bc0535SKrishna Elango  */
21d4bc0535SKrishna Elango /*
22d4bc0535SKrishna Elango  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23d4bc0535SKrishna Elango  * Use is subject to license terms.
24d4bc0535SKrishna Elango  */
25d4bc0535SKrishna Elango 
26d4bc0535SKrishna Elango #ifndef _SYS_PCIE_PWR_H
27d4bc0535SKrishna Elango #define	_SYS_PCIE_PWR_H
28d4bc0535SKrishna Elango 
29d4bc0535SKrishna Elango #ifdef	__cplusplus
30d4bc0535SKrishna Elango extern "C" {
31d4bc0535SKrishna Elango #endif
32d4bc0535SKrishna Elango 
33d4bc0535SKrishna Elango /* index of counters for each level */
34d4bc0535SKrishna Elango #define	PCIE_D3_INDEX		PM_LEVEL_D3
35d4bc0535SKrishna Elango #define	PCIE_D2_INDEX 		PM_LEVEL_D2
36d4bc0535SKrishna Elango #define	PCIE_D1_INDEX		PM_LEVEL_D1
37d4bc0535SKrishna Elango #define	PCIE_D0_INDEX		PM_LEVEL_D0
38d4bc0535SKrishna Elango #define	PCIE_UNKNOWN_INDEX	PM_LEVEL_D0 + 1
39d4bc0535SKrishna Elango #define	PCIE_MAX_PWR_LEVELS 	5
40d4bc0535SKrishna Elango 
41d4bc0535SKrishna Elango /*
42d4bc0535SKrishna Elango  * PCIe nexus power management data structure
43d4bc0535SKrishna Elango  */
44d4bc0535SKrishna Elango typedef struct pcie_pwr {
45d4bc0535SKrishna Elango 	/*
46d4bc0535SKrishna Elango 	 * general data structure fields
47d4bc0535SKrishna Elango 	 */
48d4bc0535SKrishna Elango 	kmutex_t	pwr_lock;	/* to protect the counters and  */
49d4bc0535SKrishna Elango 					/* power level change		*/
50d4bc0535SKrishna Elango 	int		pwr_pmcaps;	/* pm capability */
51d4bc0535SKrishna Elango 	ddi_acc_handle_t pwr_conf_hdl;	/* for config access */
52d4bc0535SKrishna Elango 	uint8_t		pwr_pmcsr_offset; /* PMCSR offset */
53d4bc0535SKrishna Elango 	int		pwr_link_lvl;	/* link level. Currently not used */
54d4bc0535SKrishna Elango 	int		pwr_func_lvl;	/* function power level */
55d4bc0535SKrishna Elango 	int		pwr_flags;	/* flags */
56d4bc0535SKrishna Elango 	int		pwr_hold;	/* for temporarily keeping busy */
57d4bc0535SKrishna Elango 	/*
58d4bc0535SKrishna Elango 	 * counters to keep track of child's power level.
59d4bc0535SKrishna Elango 	 * D3,D2,D1,D0 and unknown respectively.
60d4bc0535SKrishna Elango 	 */
61d4bc0535SKrishna Elango 	int		pwr_counters[PCIE_MAX_PWR_LEVELS];
62d4bc0535SKrishna Elango 
63d4bc0535SKrishna Elango } pcie_pwr_t;
64d4bc0535SKrishna Elango 
65d4bc0535SKrishna Elango typedef struct pcie_pwr_child {
66d4bc0535SKrishna Elango 	/*
67d4bc0535SKrishna Elango 	 * Per child dip counters decsribing
68d4bc0535SKrishna Elango 	 * a child's components
69d4bc0535SKrishna Elango 	 */
70d4bc0535SKrishna Elango 	int	pwr_child_counters[PCIE_MAX_PWR_LEVELS];
71d4bc0535SKrishna Elango } pcie_pwr_child_t;
72d4bc0535SKrishna Elango 
73d4bc0535SKrishna Elango typedef struct pcie_pm {
74d4bc0535SKrishna Elango 	pcie_pwr_t	*pcie_pwr_p;	/* nexus PM info */
75d4bc0535SKrishna Elango 	pcie_pwr_child_t *pcie_par_pminfo; /* PM info created by the parent */
76d4bc0535SKrishna Elango } pcie_pm_t;
77d4bc0535SKrishna Elango 
78d4bc0535SKrishna Elango #define	PCIE_PMINFO(dip)	\
79d4bc0535SKrishna Elango 	((pcie_pm_t *)(DEVI(dip)->devi_nex_pm))
80d4bc0535SKrishna Elango 
81d4bc0535SKrishna Elango #define	PCIE_NEXUS_PMINFO(dip)	\
82d4bc0535SKrishna Elango 	(PCIE_PMINFO(dip)->pcie_pwr_p)
83d4bc0535SKrishna Elango 
84d4bc0535SKrishna Elango #define	PCIE_PAR_PMINFO(dip)	\
85d4bc0535SKrishna Elango 	(PCIE_PMINFO(dip)->pcie_par_pminfo)
86d4bc0535SKrishna Elango 
87d4bc0535SKrishna Elango #define	PCIE_CHILD_COUNTERS(cdip)	\
88d4bc0535SKrishna Elango 	(PCIE_PAR_PMINFO(cdip)->pwr_child_counters)
89d4bc0535SKrishna Elango 
90d4bc0535SKrishna Elango #define	PCIE_SET_PMINFO(dip, pminfo_p)	\
91d4bc0535SKrishna Elango 	(DEVI(dip)->devi_nex_pm = (pminfo_p))
92d4bc0535SKrishna Elango 
93d4bc0535SKrishna Elango #define	PCIE_RESET_PMINFO(dip)	\
94d4bc0535SKrishna Elango 	(DEVI(dip)->devi_nex_pm = NULL)
95d4bc0535SKrishna Elango 
96d4bc0535SKrishna Elango #define	PCIE_IS_COMPS_COUNTED(cdip)	\
97d4bc0535SKrishna Elango 	(PCIE_PMINFO(cdip) && PCIE_PAR_PMINFO(cdip))
98d4bc0535SKrishna Elango 
99d4bc0535SKrishna Elango /*
100d4bc0535SKrishna Elango  * pmcap field: device power management capability.
101d4bc0535SKrishna Elango  * First 4 bits must indicate support for D3, D2, D1 and D0
102d4bc0535SKrishna Elango  * respectively. Their bit position matches with their index
103d4bc0535SKrishna Elango  * into the counters array.
104d4bc0535SKrishna Elango  */
105d4bc0535SKrishna Elango #define	PCIE_SUPPORTS_D3	0x01 /* Supports D1 */
106d4bc0535SKrishna Elango #define	PCIE_SUPPORTS_D2	0x02 /* Supports D2 */
107d4bc0535SKrishna Elango #define	PCIE_SUPPORTS_D1	0x04 /* Supports D2 */
108d4bc0535SKrishna Elango #define	PCIE_SUPPORTS_D0	0x08 /* Supports D2 */
109d4bc0535SKrishna Elango #define	PCIE_L2_CAP		0x10 /* if with Vaux, optional */
110d4bc0535SKrishna Elango #define	PCIE_L0s_L1_CAP		0x20 /* ASPM, L0s must, L1 optional */
111d4bc0535SKrishna Elango 
112d4bc0535SKrishna Elango #define	PCIE_DEFAULT_LEVEL_SUPPORTED	(PCIE_SUPPORTS_D3 | PCIE_SUPPORTS_D0)
113d4bc0535SKrishna Elango 
114d4bc0535SKrishna Elango #define	PCIE_LEVEL_SUPPORTED(pmcaps, level)	\
115d4bc0535SKrishna Elango 	((pmcaps) & (1 << (level)))
116d4bc0535SKrishna Elango 
117d4bc0535SKrishna Elango #define	PCIE_SUPPORTS_DEVICE_PM(dip)	\
118d4bc0535SKrishna Elango 	(ddi_prop_exists(DDI_DEV_T_ANY, (dip),	\
119d4bc0535SKrishna Elango 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pm-components") == 1)
120d4bc0535SKrishna Elango /*
121d4bc0535SKrishna Elango  * flags field
122d4bc0535SKrishna Elango  */
123d4bc0535SKrishna Elango #define	PCIE_ASPM_ENABLED		0x01
124d4bc0535SKrishna Elango #define	PCIE_SLOT_LOADED		0x02
125d4bc0535SKrishna Elango #define	PCIE_PM_BUSY			0x04
126d4bc0535SKrishna Elango #define	PCIE_NO_CHILD_PM		0x08
127d4bc0535SKrishna Elango 
128d4bc0535SKrishna Elango #define	PM_LEVEL_L3	0
129d4bc0535SKrishna Elango #define	PM_LEVEL_L2	1
130d4bc0535SKrishna Elango #define	PM_LEVEL_L1	2
131d4bc0535SKrishna Elango #define	PM_LEVEL_L0	3
132d4bc0535SKrishna Elango 
133d4bc0535SKrishna Elango /* ioctl definitions for ppm drivers */
134d4bc0535SKrishna Elango #define	PPMREQ			(('P' << 24) | ('M' << 16))
135d4bc0535SKrishna Elango #define	PPMREQ_MASK		0xffff
136d4bc0535SKrishna Elango #define	PPMREQ_PRE_PWR_OFF	(PPMREQ | 1)
137d4bc0535SKrishna Elango #define	PPMREQ_PRE_PWR_ON	(PPMREQ | 2)
138d4bc0535SKrishna Elango #define	PPMREQ_POST_PWR_ON	(PPMREQ | 3)
139d4bc0535SKrishna Elango 
140d4bc0535SKrishna Elango /* settle time in microseconds before PCI operation */
141d4bc0535SKrishna Elango #define	PCI_CLK_SETTLE_TIME	10000
142d4bc0535SKrishna Elango 
143d4bc0535SKrishna Elango /*
144d4bc0535SKrishna Elango  * Interface with other parts of the driver(s) code
145d4bc0535SKrishna Elango  */
146d4bc0535SKrishna Elango 
147d4bc0535SKrishna Elango /*
148d4bc0535SKrishna Elango  * We link pcie_pwr.o into several drivers (px, pcieb, pcieb_bcm, pcieb_plx),
149d4bc0535SKrishna Elango  * which causes the symbols below to be duplicated.  This isn't an issue in
150d4bc0535SKrishna Elango  * practice, since they aren't used from outside the module that they're
151d4bc0535SKrishna Elango  * part of.  However, lint does not know this, and when it does global
152d4bc0535SKrishna Elango  * crosschecks for the kernel, it complains.  To prevent this, we rename the
153d4bc0535SKrishna Elango  * symbols to driver-specific names when we're doing a lint run.
154d4bc0535SKrishna Elango  */
155d4bc0535SKrishna Elango 
156d4bc0535SKrishna Elango #if defined(lint)
157d4bc0535SKrishna Elango #if defined(PX_MOD_NAME)
158d4bc0535SKrishna Elango #define	pwr_common_setup	PX_MOD_NAME##_pwr_common_setup
159d4bc0535SKrishna Elango #define	pwr_common_teardown	PX_MOD_NAME##_pwr_common_teardown
160d4bc0535SKrishna Elango #define	pcie_bus_power		PX_MOD_NAME##_pcie_bus_power
161d4bc0535SKrishna Elango #define	pcie_power		PX_MOD_NAME##_pcie_power
162d4bc0535SKrishna Elango #define	pcie_pm_add_child	PX_MOD_NAME##_pcie_pm_add_child
163d4bc0535SKrishna Elango #define	pcie_pm_remove_child	PX_MOD_NAME##_pcie_pm_remove_child
164d4bc0535SKrishna Elango #define	pcie_pwr_suspend	PX_MOD_NAME##_pcie_pwr_suspend
165d4bc0535SKrishna Elango #define	pcie_pwr_resume		PX_MOD_NAME##_pcie_pwr_resume
166d4bc0535SKrishna Elango #define	pcie_pm_hold		PX_MOD_NAME##_pcie_pm_hold
167d4bc0535SKrishna Elango #define	pcie_pm_release		PX_MOD_NAME##_pcie_pm_release
168d4bc0535SKrishna Elango #endif /* PX_MOD_NAME */
169d4bc0535SKrishna Elango 
170d4bc0535SKrishna Elango #if defined(PX_PLX)
171d4bc0535SKrishna Elango #define	pwr_common_setup	PX_PLX##_pwr_common_setup
172d4bc0535SKrishna Elango #define	pwr_common_teardown	PX_PLX##_pwr_common_teardown
173d4bc0535SKrishna Elango #define	pcie_bus_power		PX_PLX##_pcie_bus_power
174d4bc0535SKrishna Elango #define	pcie_power		PX_PLX##_pcie_power
175d4bc0535SKrishna Elango #define	pcie_pm_add_child	PX_PLX##_pcie_pm_add_child
176d4bc0535SKrishna Elango #define	pcie_pm_remove_child	PX_PLX##_pcie_pm_remove_child
177d4bc0535SKrishna Elango #define	pcie_pwr_suspend	PX_PLX##_pcie_pwr_suspend
178d4bc0535SKrishna Elango #define	pcie_pwr_resume		PX_PLX##_pcie_pwr_resume
179d4bc0535SKrishna Elango #define	pcie_pm_hold		PX_PLX##_pcie_pm_hold
180d4bc0535SKrishna Elango #define	pcie_pm_release		PX_PLX##_pcie_pm_release
181d4bc0535SKrishna Elango #endif /* PX_PLX */
182d4bc0535SKrishna Elango #endif /* lint */
183d4bc0535SKrishna Elango 
184*e762302fSShesha Sreenivasamurthy extern int pcie_plat_pwr_setup(dev_info_t *dip);
185*e762302fSShesha Sreenivasamurthy extern void pcie_plat_pwr_teardown(dev_info_t *dip);
186d4bc0535SKrishna Elango extern int pwr_common_setup(dev_info_t *dip);
187d4bc0535SKrishna Elango extern void pwr_common_teardown(dev_info_t *dip);
188d4bc0535SKrishna Elango extern int pcie_bus_power(dev_info_t *dip, void *impl_arg, pm_bus_power_op_t op,
189d4bc0535SKrishna Elango     void *arg, void *result);
190d4bc0535SKrishna Elango extern int pcie_power(dev_info_t *dip, int component, int level);
191d4bc0535SKrishna Elango 
192d4bc0535SKrishna Elango extern int pcie_pm_add_child(dev_info_t *dip, dev_info_t *cdip);
193d4bc0535SKrishna Elango extern int pcie_pm_remove_child(dev_info_t *dip, dev_info_t *cdip);
194d4bc0535SKrishna Elango extern int pcie_pwr_suspend(dev_info_t *dip);
195d4bc0535SKrishna Elango extern int pcie_pwr_resume(dev_info_t *dip);
196d4bc0535SKrishna Elango extern int pcie_pm_hold(dev_info_t *dip);
197d4bc0535SKrishna Elango extern void pcie_pm_release(dev_info_t *dip);
198d4bc0535SKrishna Elango 
199d4bc0535SKrishna Elango #ifdef	__cplusplus
200d4bc0535SKrishna Elango }
201d4bc0535SKrishna Elango #endif
202d4bc0535SKrishna Elango 
203d4bc0535SKrishna Elango #endif	/* _SYS_PCIE_PWR_H */
204