xref: /xnu-8792.61.2/osfmk/kern/pms.h (revision 42e220869062b56f8d7d0726fd4c88954f87902c)
1 /*
2  * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifdef KERNEL_PRIVATE
30 
31 #ifndef _KERN_PMS_H_
32 #define _KERN_PMS_H_
33 
34 #define pmsMaxStates 64
35 #define HalfwayToForever 0x7FFFFFFFFFFFFFFFULL
36 #define century 790560000000000ULL
37 
38 typedef void (*pmsSetFunc_t)(uint32_t, uint32_t, uint32_t);     /* Function used to set hardware power state */
39 typedef uint32_t (*pmsQueryFunc_t)(uint32_t, uint32_t); /* Function used to query hardware power state */
40 
41 typedef struct pmsStat {
42 	uint64_t        stTime[2];                      /* Total time until switch to next step */
43 	uint32_t        stCnt[2];                       /* Number of times switched to next step */
44 } pmsStat;
45 
46 typedef struct pmsDef {
47 	uint64_t        pmsLimit;                       /* Max time in this state in microseconds */
48 	uint32_t        pmsStepID;                      /* Unique ID for this step */
49 	uint32_t        pmsSetCmd;                      /* Command to select power state */
50 #define pmsCngXClk  0x80000000          /* Change external clock */
51 #define pmsXUnk         0x7F                    /* External clock unknown  */
52 #define pmsXClk     0x7F000000          /* External clock frequency */
53 #define pmsCngCPU   0x00800000          /* Change CPU parameters */
54 #define pmsSync     0x00400000          /* Make changes synchronously, i.e., spin until delay finished */
55 #define pmsMustCmp  0x00200000          /* Delay must complete before next change */
56 #define pmsCPU      0x001F0000          /* CPU frequency */
57 #define pmsCPUUnk       0x1F                    /* CPU frequency unknown */
58 #define pmsCngVolt  0x00008000          /* Change voltage */
59 #define pmsVoltage  0x00007F00          /* Voltage */
60 #define pmsVoltUnk      0x7F                    /* Voltage unknown */
61 #define pmsPowerID  0x000000FF          /* Identify power state to HW */
62 
63 /*	Special commands - various things */
64 #define pmsDelay    0xFFFFFFFD          /* Delayed step, no processor or platform changes.  Timer expiration causes transition to pmsTDelay */
65 #define pmsParkIt       0xFFFFFFFF              /* Enters the parked state.  No processor or platform changes.  Timers cancelled */
66 #define pmsCInit        ((pmsXUnk << 24) | (pmsCPUUnk << 16) | (pmsVoltUnk << 8))       /* Initial current set command value */
67 /*	Note:  pmsSetFuncInd is an index into a table of function pointers and pmsSetFunc is the address
68  *	of a function.  Initially, when you create a step table, this field is set as an index into
69  *	a table of function addresses that gets passed as a parameter to pmsBuild.  When pmsBuild
70  *	internalizes the step and function tables, it converts the index to the function address.
71  */
72 	union sf {
73 		pmsSetFunc_t    pmsSetFunc;     /* Function used to set platform power state */
74 		uint32_t        pmsSetFuncInd;  /* Index to function in function table */
75 	} sf;
76 
77 	uint32_t        pmsDown;                        /* Next state if going lower */
78 	uint32_t        pmsNext;                        /* Normal next state */
79 	uint32_t        pmsTDelay;                      /* State if command was pmsDelay and timer expired */
80 } pmsDef;
81 
82 typedef struct pmsCtl {
83 	pmsStat(*pmsStats)[pmsMaxStates];               /* Pointer to statistics information, 0 if not enabled */
84 	pmsDef          *pmsDefs[pmsMaxStates]; /* Indexed pointers to steps */
85 } pmsCtl;
86 
87 /*
88  *	Note that this block is in the middle of the per_proc and the size (32 bytes)
89  *	can't be changed without moving it.
90  */
91 
92 typedef struct pmsd {
93 	uint32_t        pmsState;                       /* Current power management state */
94 	uint32_t        pmsCSetCmd;                     /* Current select command */
95 	uint64_t        pmsPop;                         /* Time of next step */
96 	uint64_t        pmsStamp;                       /* Time of transition to current state */
97 	uint64_t        pmsTime;                        /* Total time in this state */
98 } pmsd;
99 
100 /*
101  *	Required power management step programs
102  */
103 
104 enum {
105 	pmsIdle      = 0,                               /* Power state in idle loop */
106 	pmsNorm      = 1,                               /* Normal step - usually low power */
107 	pmsNormHigh  = 2,                               /* Highest power in normal step */
108 	pmsBoost     = 3,                               /* Boost/overdrive step */
109 	pmsLow       = 4,                               /* Lowest non-idle power state, no transitions */
110 	pmsHigh      = 5,                               /* Power step for full on, no transitions */
111 	pmsPrepCng   = 6,                               /* Prepare for step table change */
112 	pmsPrepSleep = 7,                               /* Prepare for sleep */
113 	pmsOverTemp  = 8,                               /* Machine is too hot */
114 	pmsEnterNorm = 9,                               /* Enter into the normal step program */
115 	pmsFree      = 10,                              /* First available empty step */
116 	pmsStartUp   = 0xFFFFFFFE,              /* Start stepping */
117 	pmsParked    = 0xFFFFFFFF               /* Power parked - used when changing stepping table */
118 };
119 
120 /*
121  *	Power Management Stepper Control requests
122  */
123 
124 enum {
125 	pmsCPark = 0,                                   /* Parks the stepper */
126 	pmsCStart = 1,                                  /* Starts normal steppping */
127 	pmsCFLow = 2,                                   /* Forces low power */
128 	pmsCFHigh = 3,                                  /* Forces high power */
129 	pmsCCnfg = 4,                                   /* Loads new stepper program */
130 	pmsCQuery = 5,                                  /* Query current step and state */
131 	pmsCExperimental = 6,                   /* Enter experimental mode */
132 	pmsGCtls = 7,
133 	pmsGStats = 8,
134 	pmsCVID = 9,
135 	pmsCFree = 10                                   /* Next control command to be assigned */
136 };
137 
138 /*
139  *	User request control structure passed to sysctl
140  */
141 typedef struct {
142 	uint32_t        request;                        /* stepper control request */
143 	uint32_t        reqsize;                        /* size of data */
144 	void            *reqaddr;                       /* read/write data buffer */
145 } pmsctl_t;
146 
147 extern pmsCtl pmsCtls;                          /* Power Management Stepper control */
148 extern uint32_t pmsBroadcastWait;       /* Number of outstanding broadcasts */
149 extern int pmsInstalled;
150 extern int pmsExperimental;
151 
152 #define pmsSetFuncMax 32
153 extern pmsSetFunc_t pmsFuncTab[pmsSetFuncMax];
154 extern pmsQueryFunc_t pmsQueryFunc;
155 extern uint32_t pmsPlatformData;
156 
157 extern kern_return_t pmsControl(uint32_t request, user_addr_t reqaddr, uint32_t reqsize);
158 extern void pmsInit(void);
159 extern void pmsStep(int timer);
160 extern void pmsDown(void);
161 extern void pmsSetStep(uint32_t nstep, int dir);
162 extern void pmsRunLocal(uint32_t nstep);
163 extern void pmsCPUSet(uint32_t sel);
164 extern uint32_t pmsCPUQuery(void);
165 extern uint32_t pmsCPUPackageQuery(void);
166 extern void pmsCPUConf(void);
167 extern void pmsCPUMachineInit(void);
168 extern void pmsCPUInit(void);
169 extern void pmsCPURun(uint32_t nstep);
170 
171 extern void pmsCPUYellowFlag(void);
172 extern void pmsCPUGreenFlag(void);
173 
174 #ifdef __cplusplus
175 extern "C" {
176 #endif
177 
178 extern kern_return_t pmsBuild(pmsDef *pd, uint32_t pdsize, pmsSetFunc_t *functab, uint32_t platformData, pmsQueryFunc_t queryFunc);
179 extern void pmsRun(uint32_t nstep);
180 extern void pmsPark(void);
181 extern void pmsStart(void);
182 extern kern_return_t pmsCPULoadVIDTable(uint16_t *tablep, int nstates); /* i386 only */
183 extern kern_return_t pmsCPUSetPStateLimit(uint32_t limit);
184 #ifdef __cplusplus
185 }
186 #endif
187 
188 #endif /* _KERN_PMS_H_ */
189 #endif /* KERNEL_PRIVATE */
190