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