xref: /illumos-gate/usr/src/uts/common/sys/pcie_pwr.h (revision e762302f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5d85c7355Scjj  * Common Development and Distribution License (the "License").
6d85c7355Scjj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22d4bc0535SKrishna Elango  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_PCIE_PWR_H
277c478bd9Sstevel@tonic-gate #define	_SYS_PCIE_PWR_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
307c478bd9Sstevel@tonic-gate extern "C" {
317c478bd9Sstevel@tonic-gate #endif
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /* index of counters for each level */
347c478bd9Sstevel@tonic-gate #define	PCIE_D3_INDEX		PM_LEVEL_D3
357c478bd9Sstevel@tonic-gate #define	PCIE_D2_INDEX 		PM_LEVEL_D2
367c478bd9Sstevel@tonic-gate #define	PCIE_D1_INDEX		PM_LEVEL_D1
377c478bd9Sstevel@tonic-gate #define	PCIE_D0_INDEX		PM_LEVEL_D0
387c478bd9Sstevel@tonic-gate #define	PCIE_UNKNOWN_INDEX	PM_LEVEL_D0 + 1
397c478bd9Sstevel@tonic-gate #define	PCIE_MAX_PWR_LEVELS 	5
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * PCIe nexus power management data structure
437c478bd9Sstevel@tonic-gate  */
447c478bd9Sstevel@tonic-gate typedef struct pcie_pwr {
457c478bd9Sstevel@tonic-gate 	/*
467c478bd9Sstevel@tonic-gate 	 * general data structure fields
477c478bd9Sstevel@tonic-gate 	 */
487c478bd9Sstevel@tonic-gate 	kmutex_t	pwr_lock;	/* to protect the counters and  */
497c478bd9Sstevel@tonic-gate 					/* power level change		*/
507c478bd9Sstevel@tonic-gate 	int		pwr_pmcaps;	/* pm capability */
517c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t pwr_conf_hdl;	/* for config access */
527c478bd9Sstevel@tonic-gate 	uint8_t		pwr_pmcsr_offset; /* PMCSR offset */
537c478bd9Sstevel@tonic-gate 	int		pwr_link_lvl;	/* link level. Currently not used */
547c478bd9Sstevel@tonic-gate 	int		pwr_func_lvl;	/* function power level */
557c478bd9Sstevel@tonic-gate 	int		pwr_flags;	/* flags */
567c478bd9Sstevel@tonic-gate 	int		pwr_hold;	/* for temporarily keeping busy */
577c478bd9Sstevel@tonic-gate 	/*
587c478bd9Sstevel@tonic-gate 	 * counters to keep track of child's power level.
597c478bd9Sstevel@tonic-gate 	 * D3,D2,D1,D0 and unknown respectively.
607c478bd9Sstevel@tonic-gate 	 */
617c478bd9Sstevel@tonic-gate 	int		pwr_counters[PCIE_MAX_PWR_LEVELS];
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate } pcie_pwr_t;
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate typedef struct pcie_pwr_child {
667c478bd9Sstevel@tonic-gate 	/*
677c478bd9Sstevel@tonic-gate 	 * Per child dip counters decsribing
687c478bd9Sstevel@tonic-gate 	 * a child's components
697c478bd9Sstevel@tonic-gate 	 */
707c478bd9Sstevel@tonic-gate 	int	pwr_child_counters[PCIE_MAX_PWR_LEVELS];
717c478bd9Sstevel@tonic-gate } pcie_pwr_child_t;
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate typedef struct pcie_pm {
747c478bd9Sstevel@tonic-gate 	pcie_pwr_t	*pcie_pwr_p;	/* nexus PM info */
757c478bd9Sstevel@tonic-gate 	pcie_pwr_child_t *pcie_par_pminfo; /* PM info created by the parent */
767c478bd9Sstevel@tonic-gate } pcie_pm_t;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #define	PCIE_PMINFO(dip)	\
797c478bd9Sstevel@tonic-gate 	((pcie_pm_t *)(DEVI(dip)->devi_nex_pm))
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate #define	PCIE_NEXUS_PMINFO(dip)	\
827c478bd9Sstevel@tonic-gate 	(PCIE_PMINFO(dip)->pcie_pwr_p)
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate #define	PCIE_PAR_PMINFO(dip)	\
857c478bd9Sstevel@tonic-gate 	(PCIE_PMINFO(dip)->pcie_par_pminfo)
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate #define	PCIE_CHILD_COUNTERS(cdip)	\
887c478bd9Sstevel@tonic-gate 	(PCIE_PAR_PMINFO(cdip)->pwr_child_counters)
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate #define	PCIE_SET_PMINFO(dip, pminfo_p)	\
917c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_nex_pm = (pminfo_p))
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate #define	PCIE_RESET_PMINFO(dip)	\
947c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_nex_pm = NULL)
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate #define	PCIE_IS_COMPS_COUNTED(cdip)	\
977c478bd9Sstevel@tonic-gate 	(PCIE_PMINFO(cdip) && PCIE_PAR_PMINFO(cdip))
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate /*
1007c478bd9Sstevel@tonic-gate  * pmcap field: device power management capability.
1017c478bd9Sstevel@tonic-gate  * First 4 bits must indicate support for D3, D2, D1 and D0
1027c478bd9Sstevel@tonic-gate  * respectively. Their bit position matches with their index
1037c478bd9Sstevel@tonic-gate  * into the counters array.
1047c478bd9Sstevel@tonic-gate  */
1057c478bd9Sstevel@tonic-gate #define	PCIE_SUPPORTS_D3	0x01 /* Supports D1 */
1067c478bd9Sstevel@tonic-gate #define	PCIE_SUPPORTS_D2	0x02 /* Supports D2 */
1077c478bd9Sstevel@tonic-gate #define	PCIE_SUPPORTS_D1	0x04 /* Supports D2 */
1087c478bd9Sstevel@tonic-gate #define	PCIE_SUPPORTS_D0	0x08 /* Supports D2 */
1097c478bd9Sstevel@tonic-gate #define	PCIE_L2_CAP		0x10 /* if with Vaux, optional */
1107c478bd9Sstevel@tonic-gate #define	PCIE_L0s_L1_CAP		0x20 /* ASPM, L0s must, L1 optional */
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate #define	PCIE_DEFAULT_LEVEL_SUPPORTED	(PCIE_SUPPORTS_D3 | PCIE_SUPPORTS_D0)
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate #define	PCIE_LEVEL_SUPPORTED(pmcaps, level)	\
1157c478bd9Sstevel@tonic-gate 	((pmcaps) & (1 << (level)))
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate #define	PCIE_SUPPORTS_DEVICE_PM(dip)	\
1187c478bd9Sstevel@tonic-gate 	(ddi_prop_exists(DDI_DEV_T_ANY, (dip),	\
1197c478bd9Sstevel@tonic-gate 	    DDI_PROP_DONTPASS | DDI_PROP_NOTPROM, "pm-components") == 1)
1207c478bd9Sstevel@tonic-gate /*
1217c478bd9Sstevel@tonic-gate  * flags field
1227c478bd9Sstevel@tonic-gate  */
1237c478bd9Sstevel@tonic-gate #define	PCIE_ASPM_ENABLED		0x01
1247c478bd9Sstevel@tonic-gate #define	PCIE_SLOT_LOADED		0x02
1251a887b2eSjchu #define	PCIE_PM_BUSY			0x04
1268a1b8da3Smg #define	PCIE_NO_CHILD_PM		0x08
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate #define	PM_LEVEL_L3	0
1297c478bd9Sstevel@tonic-gate #define	PM_LEVEL_L2	1
1307c478bd9Sstevel@tonic-gate #define	PM_LEVEL_L1	2
1317c478bd9Sstevel@tonic-gate #define	PM_LEVEL_L0	3
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate /* ioctl definitions for ppm drivers */
1347c478bd9Sstevel@tonic-gate #define	PPMREQ			(('P' << 24) | ('M' << 16))
1357c478bd9Sstevel@tonic-gate #define	PPMREQ_MASK		0xffff
1367c478bd9Sstevel@tonic-gate #define	PPMREQ_PRE_PWR_OFF	(PPMREQ | 1)
1377c478bd9Sstevel@tonic-gate #define	PPMREQ_PRE_PWR_ON	(PPMREQ | 2)
1387c478bd9Sstevel@tonic-gate #define	PPMREQ_POST_PWR_ON	(PPMREQ | 3)
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate /* settle time in microseconds before PCI operation */
1417c478bd9Sstevel@tonic-gate #define	PCI_CLK_SETTLE_TIME	10000
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate /*
1447c478bd9Sstevel@tonic-gate  * Interface with other parts of the driver(s) code
1457c478bd9Sstevel@tonic-gate  */
146d85c7355Scjj 
147d85c7355Scjj /*
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
150d85c7355Scjj  * practice, since they aren't used from outside the module that they're
151d85c7355Scjj  * part of.  However, lint does not know this, and when it does global
152d85c7355Scjj  * crosschecks for the kernel, it complains.  To prevent this, we rename the
153d85c7355Scjj  * symbols to driver-specific names when we're doing a lint run.
154d85c7355Scjj  */
155d85c7355Scjj 
15613683ea2Skrishnae #if defined(lint)
15713683ea2Skrishnae #if defined(PX_MOD_NAME)
158d85c7355Scjj #define	pwr_common_setup	PX_MOD_NAME##_pwr_common_setup
159d85c7355Scjj #define	pwr_common_teardown	PX_MOD_NAME##_pwr_common_teardown
160d85c7355Scjj #define	pcie_bus_power		PX_MOD_NAME##_pcie_bus_power
161d85c7355Scjj #define	pcie_power		PX_MOD_NAME##_pcie_power
162d85c7355Scjj #define	pcie_pm_add_child	PX_MOD_NAME##_pcie_pm_add_child
163d85c7355Scjj #define	pcie_pm_remove_child	PX_MOD_NAME##_pcie_pm_remove_child
164d85c7355Scjj #define	pcie_pwr_suspend	PX_MOD_NAME##_pcie_pwr_suspend
165d85c7355Scjj #define	pcie_pwr_resume		PX_MOD_NAME##_pcie_pwr_resume
166d85c7355Scjj #define	pcie_pm_hold		PX_MOD_NAME##_pcie_pm_hold
167d85c7355Scjj #define	pcie_pm_release		PX_MOD_NAME##_pcie_pm_release
16813683ea2Skrishnae #endif /* PX_MOD_NAME */
16913683ea2Skrishnae 
17013683ea2Skrishnae #if defined(PX_PLX)
17113683ea2Skrishnae #define	pwr_common_setup	PX_PLX##_pwr_common_setup
17213683ea2Skrishnae #define	pwr_common_teardown	PX_PLX##_pwr_common_teardown
17313683ea2Skrishnae #define	pcie_bus_power		PX_PLX##_pcie_bus_power
17413683ea2Skrishnae #define	pcie_power		PX_PLX##_pcie_power
17513683ea2Skrishnae #define	pcie_pm_add_child	PX_PLX##_pcie_pm_add_child
17613683ea2Skrishnae #define	pcie_pm_remove_child	PX_PLX##_pcie_pm_remove_child
17713683ea2Skrishnae #define	pcie_pwr_suspend	PX_PLX##_pcie_pwr_suspend
17813683ea2Skrishnae #define	pcie_pwr_resume		PX_PLX##_pcie_pwr_resume
17913683ea2Skrishnae #define	pcie_pm_hold		PX_PLX##_pcie_pm_hold
18013683ea2Skrishnae #define	pcie_pm_release		PX_PLX##_pcie_pm_release
18113683ea2Skrishnae #endif /* PX_PLX */
18213683ea2Skrishnae #endif /* lint */
183d85c7355Scjj 
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);
1867c478bd9Sstevel@tonic-gate extern int pwr_common_setup(dev_info_t *dip);
1877c478bd9Sstevel@tonic-gate extern void pwr_common_teardown(dev_info_t *dip);
1887c478bd9Sstevel@tonic-gate extern int pcie_bus_power(dev_info_t *dip, void *impl_arg, pm_bus_power_op_t op,
1897c478bd9Sstevel@tonic-gate     void *arg, void *result);
1907c478bd9Sstevel@tonic-gate extern int pcie_power(dev_info_t *dip, int component, int level);
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate extern int pcie_pm_add_child(dev_info_t *dip, dev_info_t *cdip);
1937c478bd9Sstevel@tonic-gate extern int pcie_pm_remove_child(dev_info_t *dip, dev_info_t *cdip);
1947c478bd9Sstevel@tonic-gate extern int pcie_pwr_suspend(dev_info_t *dip);
1957c478bd9Sstevel@tonic-gate extern int pcie_pwr_resume(dev_info_t *dip);
1967c478bd9Sstevel@tonic-gate extern int pcie_pm_hold(dev_info_t *dip);
1977c478bd9Sstevel@tonic-gate extern void pcie_pm_release(dev_info_t *dip);
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2007c478bd9Sstevel@tonic-gate }
2017c478bd9Sstevel@tonic-gate #endif
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate #endif	/* _SYS_PCIE_PWR_H */
204