/* * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ #ifdef KERNEL_PRIVATE #ifndef _KERN_PMS_H_ #define _KERN_PMS_H_ #define pmsMaxStates 64 #define HalfwayToForever 0x7FFFFFFFFFFFFFFFULL #define century 790560000000000ULL typedef void (*pmsSetFunc_t)(uint32_t, uint32_t, uint32_t); /* Function used to set hardware power state */ typedef uint32_t (*pmsQueryFunc_t)(uint32_t, uint32_t); /* Function used to query hardware power state */ typedef struct pmsStat { uint64_t stTime[2]; /* Total time until switch to next step */ uint32_t stCnt[2]; /* Number of times switched to next step */ } pmsStat; typedef struct pmsDef { uint64_t pmsLimit; /* Max time in this state in microseconds */ uint32_t pmsStepID; /* Unique ID for this step */ uint32_t pmsSetCmd; /* Command to select power state */ #define pmsCngXClk 0x80000000 /* Change external clock */ #define pmsXUnk 0x7F /* External clock unknown */ #define pmsXClk 0x7F000000 /* External clock frequency */ #define pmsCngCPU 0x00800000 /* Change CPU parameters */ #define pmsSync 0x00400000 /* Make changes synchronously, i.e., spin until delay finished */ #define pmsMustCmp 0x00200000 /* Delay must complete before next change */ #define pmsCPU 0x001F0000 /* CPU frequency */ #define pmsCPUUnk 0x1F /* CPU frequency unknown */ #define pmsCngVolt 0x00008000 /* Change voltage */ #define pmsVoltage 0x00007F00 /* Voltage */ #define pmsVoltUnk 0x7F /* Voltage unknown */ #define pmsPowerID 0x000000FF /* Identify power state to HW */ /* Special commands - various things */ #define pmsDelay 0xFFFFFFFD /* Delayed step, no processor or platform changes. Timer expiration causes transition to pmsTDelay */ #define pmsParkIt 0xFFFFFFFF /* Enters the parked state. No processor or platform changes. Timers cancelled */ #define pmsCInit ((pmsXUnk << 24) | (pmsCPUUnk << 16) | (pmsVoltUnk << 8)) /* Initial current set command value */ /* Note: pmsSetFuncInd is an index into a table of function pointers and pmsSetFunc is the address * of a function. Initially, when you create a step table, this field is set as an index into * a table of function addresses that gets passed as a parameter to pmsBuild. When pmsBuild * internalizes the step and function tables, it converts the index to the function address. */ union sf { pmsSetFunc_t pmsSetFunc; /* Function used to set platform power state */ uint32_t pmsSetFuncInd; /* Index to function in function table */ } sf; uint32_t pmsDown; /* Next state if going lower */ uint32_t pmsNext; /* Normal next state */ uint32_t pmsTDelay; /* State if command was pmsDelay and timer expired */ } pmsDef; typedef struct pmsCtl { pmsStat (*pmsStats)[pmsMaxStates]; /* Pointer to statistics information, 0 if not enabled */ pmsDef *pmsDefs[pmsMaxStates]; /* Indexed pointers to steps */ } pmsCtl; /* * Note that this block is in the middle of the per_proc and the size (32 bytes) * can't be changed without moving it. */ typedef struct pmsd { uint32_t pmsState; /* Current power management state */ uint32_t pmsCSetCmd; /* Current select command */ uint64_t pmsPop; /* Time of next step */ uint64_t pmsStamp; /* Time of transition to current state */ uint64_t pmsTime; /* Total time in this state */ } pmsd; /* * Required power management step programs */ enum { pmsIdle = 0, /* Power state in idle loop */ pmsNorm = 1, /* Normal step - usually low power */ pmsNormHigh = 2, /* Highest power in normal step */ pmsBoost = 3, /* Boost/overdrive step */ pmsLow = 4, /* Lowest non-idle power state, no transitions */ pmsHigh = 5, /* Power step for full on, no transitions */ pmsPrepCng = 6, /* Prepare for step table change */ pmsPrepSleep = 7, /* Prepare for sleep */ pmsOverTemp = 8, /* Machine is too hot */ pmsEnterNorm = 9, /* Enter into the normal step program */ pmsFree = 10, /* First available empty step */ pmsStartUp = 0xFFFFFFFE, /* Start stepping */ pmsParked = 0xFFFFFFFF /* Power parked - used when changing stepping table */ }; /* * Power Management Stepper Control requests */ enum { pmsCPark = 0, /* Parks the stepper */ pmsCStart = 1, /* Starts normal steppping */ pmsCFLow = 2, /* Forces low power */ pmsCFHigh = 3, /* Forces high power */ pmsCCnfg = 4, /* Loads new stepper program */ pmsCQuery = 5, /* Query current step and state */ pmsCExperimental = 6, /* Enter experimental mode */ pmsGCtls = 7, pmsGStats = 8, pmsCVID = 9, pmsCFree = 10 /* Next control command to be assigned */ }; /* * User request control structure passed to sysctl */ typedef struct { uint32_t request; /* stepper control request */ uint32_t reqsize; /* size of data */ void *reqaddr; /* read/write data buffer */ } pmsctl_t; extern pmsCtl pmsCtls; /* Power Management Stepper control */ extern uint32_t pmsBroadcastWait; /* Number of outstanding broadcasts */ extern int pmsInstalled; extern int pmsExperimental; #define pmsSetFuncMax 32 extern pmsSetFunc_t pmsFuncTab[pmsSetFuncMax]; extern pmsQueryFunc_t pmsQueryFunc; extern uint32_t pmsPlatformData; extern kern_return_t pmsControl(uint32_t request, user_addr_t reqaddr, uint32_t reqsize); extern void pmsInit(void); extern void pmsStep(int timer); extern void pmsDown(void); extern void pmsSetStep(uint32_t nstep, int dir); extern void pmsRunLocal(uint32_t nstep); extern void pmsCPUSet(uint32_t sel); extern uint32_t pmsCPUQuery(void); extern uint32_t pmsCPUPackageQuery(void); extern void pmsCPUConf(void); extern void pmsCPUMachineInit(void); extern void pmsCPUInit(void); extern void pmsCPURun(uint32_t nstep); extern void pmsCPUYellowFlag(void); extern void pmsCPUGreenFlag(void); #ifdef __cplusplus extern "C" { #endif extern kern_return_t pmsBuild(pmsDef *pd, uint32_t pdsize, pmsSetFunc_t *functab, uint32_t platformData, pmsQueryFunc_t queryFunc); extern void pmsRun(uint32_t nstep); extern void pmsPark(void); extern void pmsStart(void); extern kern_return_t pmsCPULoadVIDTable(uint16_t *tablep, int nstates); /* i386 only */ extern kern_return_t pmsCPUSetPStateLimit(uint32_t limit); #ifdef __cplusplus } #endif #endif /* _KERN_PMS_H_ */ #endif /* KERNEL_PRIVATE */