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