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 38typedef void (*pmsSetFunc_t)(uint32_t, uint32_t, uint32_t); /* Function used to set hardware power state */ 39typedef uint32_t (*pmsQueryFunc_t)(uint32_t, uint32_t); /* Function used to query hardware power state */ 40 41typedef 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 46typedef 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 82typedef 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 92typedef 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 104enum { 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 124enum { 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 */ 141typedef 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 147extern pmsCtl pmsCtls; /* Power Management Stepper control */ 148#ifdef __ppc__ 149extern uint32_t pmsCtlp; 150#endif 151extern uint32_t pmsBroadcastWait; /* Number of outstanding broadcasts */ 152extern int pmsInstalled; 153extern int pmsExperimental; 154 155#define pmsSetFuncMax 32 156extern pmsSetFunc_t pmsFuncTab[pmsSetFuncMax]; 157extern pmsQueryFunc_t pmsQueryFunc; 158extern uint32_t pmsPlatformData; 159 160#ifdef __ppc__ 161# ifdef XNU_KERNEL_PRIVATE 162# include <ppc/savearea.h> 163# endif /* XNU_KERNEL_PRIVATE */ 164extern int pmsCntrl(struct savearea *save); 165#endif /* __ppc__ */ 166extern kern_return_t pmsControl(uint32_t request, user_addr_t reqaddr, uint32_t reqsize); 167extern void pmsInit(void); 168extern void pmsStep(int timer); 169extern void pmsDown(void); 170extern void pmsSetStep(uint32_t nstep, int dir); 171extern void pmsRunLocal(uint32_t nstep); 172extern void pmsCPUSet(uint32_t sel); 173extern uint32_t pmsCPUQuery(void); 174extern uint32_t pmsCPUPackageQuery(void); 175extern void pmsCPUConf(void); 176extern void pmsCPUMachineInit(void); 177extern void pmsCPUInit(void); 178extern void pmsCPURun(uint32_t nstep); 179 180extern void pmsCPUYellowFlag(void); 181extern void pmsCPUGreenFlag(void); 182 183#ifdef __cplusplus 184extern "C" { 185#endif 186 187extern kern_return_t pmsBuild(pmsDef *pd, uint32_t pdsize, pmsSetFunc_t *functab, uint32_t platformData, pmsQueryFunc_t queryFunc); 188extern void pmsRun(uint32_t nstep); 189extern void pmsPark(void); 190extern void pmsStart(void); 191# ifndef __ppc__ 192extern kern_return_t pmsCPULoadVIDTable(uint16_t *tablep, int nstates); /* i386 only */ 193extern kern_return_t pmsCPUSetPStateLimit(uint32_t limit); 194# endif 195#ifdef __cplusplus 196} 197#endif 198 199#endif /* _KERN_PMS_H_ */ 200#endif /* KERNEL_PRIVATE */ 201