Annotation of XNU/iokit/Families/IOGraphics/IODisplay.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1997-1998 Apple Computer, Inc.
                     24:  *
                     25:  *
                     26:  * HISTORY
                     27:  *
                     28:  * sdouglas  22 Oct 97 - first checked in.
                     29:  * sdouglas  18 May 98 - make loadable.
                     30:  * sdouglas  23 Jul 98 - start IOKit
                     31:  * sdouglas  08 Dec 98 - start cpp
                     32:  */
                     33: 
                     34: 
                     35: #include <IOKit/graphics/IODisplay.h>
                     36: #include <IOKit/IOLib.h>
                     37: #include <IOKit/assert.h>
                     38: 
                     39: 
                     40: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     41: 
                     42: #undef super
                     43: #define super IOService
                     44: 
                     45: OSDefineMetaClass( IODisplay, IOService )
                     46: OSDefineAbstractStructors( IODisplay, IOService )
                     47: 
                     48: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     49: 
                     50: IOService * IODisplay::probe(  IOService *     provider,
                     51:                                SInt32 *        score )
                     52: {
                     53:     connection = OSDynamicCast(IODisplayConnect, provider);
                     54: 
                     55:     return( this );
                     56: }
                     57: 
                     58: IODisplayConnect * IODisplay::getConnection( void )
                     59: {
                     60:     return( connection );
                     61: }
                     62: 
                     63: 
                     64: IOReturn IODisplay::getGammaTableByIndex(
                     65:        UInt32 * /* channelCount */, UInt32 * /* dataCount */,
                     66:        UInt32 * /* dataWidth */, void ** /* data */ )
                     67: {
                     68:     return( kIOReturnUnsupported);
                     69: }
                     70: 
                     71: 
                     72: bool IODisplay::start( IOService * provider )
                     73: {
                     74:     if ( super::start(provider) ) {
                     75:         if ( connection != NULL ) {
                     76:             displayPMVars =  (DisplayPMVars *)IOMalloc(sizeof(DisplayPMVars)); // make space for our variables
                     77:             assert( displayPMVars );
                     78:             displayPMVars->displayIdle = false;                                        // initialize some
                     79:             initForPM(provider);                                                       // initialize power management of the device
                     80:             registerService();
                     81:         }
                     82:         return true;
                     83:     }
                     84:     return false;
                     85: }
                     86: 
                     87: 
                     88: /*
                     89: This is the power-controlling driver for a display.  It also acts as an agent of the policy-maker for display power
                     90:  which is the DisplayWrangler.  The Display Wrangler calls here to lower power by one state when it senses
                     91:  no user activity.  It also calls here to make the display usable after it has been idled down, and it also calls
                     92:  here to make the display barely usable if it senses a power emergency (e.g. low battery).
                     93: 
                     94:  This driver assumes a video display, and it calls the framebuffer driver to control the sync signals.  Non-video
                     95:  display drivers (e.g. flat panels) subclass IODisplay and override this and other  appropriate methods.
                     96:  */
                     97: 
                     98: static IOPMPowerState ourPowerStates[kIODisplayMaxPowerStates] = {
                     99:   {1,0,0,0,0,0,0,0,0,0,0,0},
                    100:   {1,0,0,IOPMPowerOn,0,0,0,0,0,0,0,0},
                    101:   {1,0,0,IOPMPowerOn,0,0,0,0,0,0,0,0},
                    102:   {1,IOPMDeviceUsable+IOPMMaxPerformance,0,IOPMPowerOn,0,0,0,0,0,0,0,0}
                    103: };
                    104: 
                    105: 
                    106: void IODisplay::initForPM ( IOService * provider )
                    107: {
                    108:     UInt32             capabilities = 0;
                    109:     unsigned long number_of_power_states;
                    110:     UInt32             currentSyncs = 0;
                    111:     IOReturn   err;
                    112: 
                    113:     displayPMVars->connectIndex = connection->getConnection();         // find out our index in the nub
                    114:     
                    115:     // what are the sync-controlling capabilities of the framebuffer?
                    116:     err = connection->getAttributeForConnection(  displayPMVars->connectIndex,
                    117:                                kConnectionSyncEnable, &capabilities );
                    118: 
                    119:     // find out current state of sync lines
                    120:     err = connection->getAttributeForConnection(  displayPMVars->connectIndex,
                    121:                                kConnectionSyncFlags, &currentSyncs );
                    122: 
                    123:     displayPMVars->currentSyncs = currentSyncs;
                    124:     displayPMVars->powerControllable = true;
                    125: 
                    126:     if ( (capabilities & kIOHSyncDisable) &&
                    127:          (capabilities & kIOVSyncDisable) &&
                    128:          !(capabilities & kIONoSeparateSyncControl ) ) {               // four power states
                    129:         number_of_power_states = 4;
                    130:         displayPMVars->syncControls[0] = 0 | kIOHSyncDisable | kIOVSyncDisable | kIOCSyncDisable;
                    131:         displayPMVars->syncControls[1] = 0 | kIOVSyncDisable | kIOCSyncDisable;
                    132:         displayPMVars->syncControls[2] = 0 | kIOHSyncDisable | kIOCSyncDisable;
                    133:         displayPMVars->syncControls[3] = 0;
                    134:         displayPMVars->syncMask = capabilities & (kIOHSyncDisable | kIOVSyncDisable | kIOCSyncDisable);
                    135:     }
                    136:     else {
                    137:         if ( capabilities & kIOCSyncDisable ) {                // two power states
                    138:             number_of_power_states = 2;
                    139:             ourPowerStates[1].capabilityFlags = ourPowerStates[3].capabilityFlags;
                    140:             displayPMVars->syncControls[0] = 0 | kIOCSyncDisable;
                    141:             displayPMVars->syncControls[1] = 0;
                    142:             displayPMVars->syncMask = 0 | kIOCSyncDisable;
                    143:         }
                    144:         else {                                         // two power states and not controllable
                    145:             number_of_power_states = 2;
                    146:             ourPowerStates[1].capabilityFlags = ourPowerStates[3].capabilityFlags;
                    147:             ourPowerStates[0].capabilityFlags |= IOPMNotAttainable;
                    148:             ourPowerStates[1].capabilityFlags |= IOPMNotAttainable;
                    149:             displayPMVars->syncControls[0] = displayPMVars->currentSyncs;
                    150:             displayPMVars->syncControls[1] = displayPMVars->currentSyncs;
                    151:             displayPMVars->syncMask = displayPMVars->currentSyncs;
                    152:             displayPMVars->powerControllable = false;
                    153:         }
                    154:     }
                    155: 
                    156:     PMinit();                                                  // initialize superclass variables
                    157:     provider->joinPMtree(this);                                        // attach into the power management hierarchy
                    158: 
                    159:     registerControllingDriver(this,ourPowerStates,number_of_power_states);     // register ourselves with policy-maker (us)
                    160: 
                    161: }
                    162: 
                    163: 
                    164: //*********************************************************************************
                    165: // registerControllingDriver
                    166: //
                    167: // We intercept this call to our superclass just to snoop early on
                    168: // the number of power states.
                    169: //*********************************************************************************
                    170: 
                    171: IOReturn IODisplay::registerControllingDriver ( IOService* x, IOPMPowerState*y, unsigned long numberOfStates )
                    172: {
                    173:     displayPMVars->max_display_state = numberOfStates - 1;
                    174:     return super::registerControllingDriver(x,y,numberOfStates);
                    175: }
                    176: 
                    177: 
                    178: //*********************************************************************************
                    179: // setAggressiveness
                    180: //
                    181: // We are informed by our power domain parent of a new level of "power management
                    182: // aggressiveness".  Our only interest is if it implies a power management
                    183: // emergency, in which case we keep the display brightness low.
                    184: //*********************************************************************************
                    185: 
                    186: IOReturn IODisplay::setAggressiveness ( unsigned long type, unsigned long newLevel )
                    187: {
                    188:     unsigned long i;
                    189: 
                    190:     if ( type == kPMGeneralAggressiveness  ) {
                    191:         if ( newLevel >= kIOPowerEmergencyLevel ) {                            // emergency level
                    192:             for ( i = 0; i < pm_vars->theNumberOfPowerStates; i++ ) {                  // find lowest usable state
                    193:                 if ( pm_vars->thePowerStates[i].capabilityFlags & IOPMDeviceUsable ) {
                    194:                     break;
                    195:                 }
                    196:             }
                    197:             displayPMVars->max_display_state = i;
                    198:             if ( pm_vars->myCurrentState > i ) {                                       // if we are currently above that,
                    199:                 changeStateToPriv(i);                                          // drop to emergency level
                    200:             }
                    201:         }
                    202:         else {                                                         // not emergency level
                    203:             if ( pm_vars->aggressiveness >= kIOPowerEmergencyLevel ) {                 // but it was emergency level
                    204:                 displayPMVars->max_display_state =  pm_vars->theNumberOfPowerStates - 1;
                    205:                 if ( ! displayPMVars->displayIdle ) {
                    206:                     changeStateToPriv(displayPMVars->max_display_state);               // return to normal usable level
                    207:                 }
                    208:             }
                    209:         }
                    210:     }
                    211:     super::setAggressiveness(type, newLevel);
                    212:     return IOPMNoErr;
                    213: }
                    214: 
                    215: 
                    216: // **********************************************************************************
                    217: // dropOneLevel
                    218: //
                    219: // Called by the display wrangler when it decides there hasn't been user
                    220: // activity for a while.  We drop one power level.  This can be called by the
                    221: // display wrangler before we have been completely initialized.
                    222: // **********************************************************************************
                    223: void IODisplay::dropOneLevel ( void )
                    224: {
                    225:     if ( initialized && displayPMVars->powerControllable) {
                    226:         displayPMVars->displayIdle = true;
                    227:         if ( pm_vars != NULL ) {
                    228:             if ( pm_vars->myCurrentState > 0 ) {
                    229:                 changeStateToPriv(pm_vars->myCurrentState - 1);        // drop a level
                    230:             }
                    231:             else {
                    232:                 changeStateToPriv(0);  // this may rescind previous request for domain power
                    233:             }
                    234:         }
                    235:     }
                    236: }
                    237: 
                    238: 
                    239: //*********************************************************************************
                    240: // makeDisplayUsable
                    241: //
                    242: // The DisplayWrangler has sensed user activity after we have idled the
                    243: // display and wants us to make it usable again.  We are running on its
                    244: // workloop thread.  This can be called before we are completely
                    245: // initialized.
                    246: //*********************************************************************************
                    247: void IODisplay::makeDisplayUsable ( void )
                    248: {
                    249:     if ( initialized && displayPMVars->powerControllable) {
                    250:         displayPMVars->displayIdle = false;
                    251:         if ( pm_vars != NULL ) {
                    252:             changeStateToPriv(displayPMVars->max_display_state);
                    253:         }
                    254:     }
                    255: }
                    256: 
                    257: 
                    258: // **********************************************************************************
                    259: // setPowerState
                    260: //
                    261: // Called by the superclass to change the display power state.
                    262: // **********************************************************************************
                    263: IOReturn IODisplay::setPowerState ( unsigned long powerStateOrdinal, IOService* whatDevice )
                    264: {
                    265:     UInt32 flags;
                    266:     
                    267:     flags =(displayPMVars->syncControls[powerStateOrdinal])<<8;
                    268:     flags |= displayPMVars->syncMask;
                    269:     displayPMVars->currentSyncs = displayPMVars->syncControls[powerStateOrdinal];
                    270:     connection->setAttributeForConnection( displayPMVars->connectIndex, kConnectionSyncEnable, flags );
                    271: 
                    272:     return IOPMAckImplied;
                    273: }
                    274: 
                    275: 
                    276: // **********************************************************************************
                    277: // maxCapabilityForDomainState
                    278: //
                    279: // This simple device needs only power.  If the power domain is supplying
                    280: // power, the display can go to its highest state.  If there is no power
                    281: // it can only be in its lowest state, which is off.
                    282: // **********************************************************************************
                    283: unsigned long  IODisplay::maxCapabilityForDomainState ( IOPMPowerFlags domainState )
                    284: {
                    285:    if ( domainState &  IOPMPowerOn ) {
                    286:        return pm_vars->theNumberOfPowerStates-1;
                    287:    }
                    288:    else {
                    289:        return 0;
                    290:    }
                    291: }
                    292: 
                    293: 
                    294: // **********************************************************************************
                    295: // initialPowerStateForDomainState
                    296: //
                    297: // The power domain may be changing state.  If power is on in the new
                    298: // state, that will not affect our state at all.  In that case ask the ndrv
                    299: // what our current state is.  If domain power is off, we can attain
                    300: // only our lowest state, which is off.
                    301: // **********************************************************************************
                    302: unsigned long  IODisplay::initialPowerStateForDomainState ( IOPMPowerFlags domainState )
                    303: {
                    304:    long unsigned i;
                    305: 
                    306:    if ( domainState &  IOPMPowerOn ) {                 // domain has power
                    307:        for ( i =  pm_vars->theNumberOfPowerStates-1; i > 0; i-- ) {    // compare to our table to find current power state
                    308:            if ( (displayPMVars->syncControls[i] & displayPMVars->syncMask)
                    309:                == (displayPMVars->currentSyncs & displayPMVars->syncMask) ) {
                    310:                break;
                    311:            }
                    312:        }
                    313:        return i;
                    314:    }
                    315:    else {
                    316:        return 0;                                               // domain is down, so display is off
                    317:    }
                    318: }
                    319: 
                    320: 
                    321: // **********************************************************************************
                    322: // powerStateForDomainState
                    323: //
                    324: // The power domain may be changing state.  If power is on in the new
                    325: // state, that will not affect our state at all.  In that case ask the ndrv
                    326: // what our current state is.  If domain power is off, we can attain
                    327: // only our lowest state, which is off.
                    328: // **********************************************************************************
                    329: unsigned long  IODisplay::powerStateForDomainState ( IOPMPowerFlags domainState )
                    330: {
                    331:    long unsigned i;
                    332: 
                    333:    if ( domainState &  IOPMPowerOn ) {                 // domain has power
                    334:        for ( i =  pm_vars->theNumberOfPowerStates-1; i > 0; i-- ) {    // compare to our table to find current power state
                    335:            if ( (displayPMVars->syncControls[i] & displayPMVars->syncMask)
                    336:                == (displayPMVars->currentSyncs & displayPMVars->syncMask) ) {
                    337:                break;
                    338:            }
                    339:        }
                    340:        return i;
                    341:    }
                    342:    else {
                    343:        return 0;                                               // domain is down, so display is off
                    344:    }
                    345: }
                    346: 
                    347: 
                    348: 
                    349: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    350: 
                    351: #undef super
                    352: #define super IODisplay
                    353: 
                    354: OSDefineMetaClassAndStructors(AppleSenseDisplay, IODisplay)
                    355: 
                    356: 
                    357: IOService * AppleSenseDisplay::probe(  IOService *     provider,
                    358:                                        SInt32 *        score )
                    359: {
                    360:     IODisplayConnect * connect;
                    361:     IOFramebuffer *    framebuffer;
                    362:     IOService *                ret = 0;
                    363: 
                    364:     do {
                    365: 
                    366:        if( 0 == super::probe( provider, score ))
                    367:             continue;
                    368: 
                    369:        connect = getConnection();
                    370:        if( !connect)
                    371:             continue;
                    372: 
                    373:        framebuffer = connect->getFramebuffer();
                    374:        assert( framebuffer );
                    375: 
                    376:         if( kIOReturnSuccess != framebuffer->getAttributeForConnection(
                    377:                                connect->getConnection(),
                    378:                                kConnectionSupportsAppleSense, NULL ))
                    379:             continue;
                    380: 
                    381:        ret = this;
                    382: 
                    383:     } while( false);
                    384: 
                    385:     return( ret );
                    386: }
                    387: 
                    388: IOReturn AppleSenseDisplay::getConnectFlagsForDisplayMode(
                    389:                IODisplayModeID mode, UInt32 * flags )
                    390: {
                    391:     IOFramebuffer *    framebuffer;
                    392:     IODisplayConnect * connect;
                    393: 
                    394:     connect = getConnection();
                    395:     framebuffer = connect->getFramebuffer();
                    396: 
                    397:     return( framebuffer->connectFlags(
                    398:                             connect->getConnection(),
                    399:                             mode, flags ));
                    400: }
                    401: 
                    402: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    403: 
                    404: 
                    405: #undef super
                    406: #define super IODisplay
                    407: 
                    408: OSDefineMetaClassAndStructors(AppleNoSenseDisplay, IODisplay)
                    409: 
                    410: 
                    411: IOReturn AppleNoSenseDisplay::getConnectFlagsForDisplayMode(
                    412:                IODisplayModeID /* mode */, UInt32 * flags)
                    413: {
                    414: 
                    415:     *flags = kDisplayModeValidFlag | kDisplayModeSafeFlag;
                    416: 
                    417:     return( kIOReturnSuccess );
                    418: }
                    419: 
                    420: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.