Annotation of XNU/iokit/Families/IONDRVSupport/IONDRVFramebuffer.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  24 Jul 98 - start IOKit.
                     30:  * sdouglas  15 Dec 98 - cpp.
                     31:  *
                     32:  */
                     33: 
                     34: #include <IOKit/IOLib.h>
                     35: #include <IOKit/IOPlatformExpert.h>
                     36: #include <IOKit/IODeviceTreeSupport.h>
                     37: #include <IOKit/IOLocks.h>
                     38: #include <IOKit/ndrvsupport/IONDRVFramebuffer.h>
                     39: #include <IOKit/assert.h>
                     40: 
                     41: #include <libkern/c++/OSContainers.h>
                     42: 
                     43: #include "IONDRV.h"
                     44: 
                     45: #include <string.h>
                     46: 
                     47: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     48: 
                     49: class IOATINDRV : public IONDRVFramebuffer
                     50: {
                     51:     OSDeclareDefaultStructors(IOATINDRV)
                     52: 
                     53: public:
                     54:     virtual IOReturn getStartupDisplayMode( IODisplayModeID * displayMode,
                     55:                             IOIndex * depth );
                     56:     virtual IODeviceMemory * findVRAM( void );
                     57: 
                     58: };
                     59: 
                     60: class IOATI128NDRV : public IOATINDRV
                     61: {
                     62:     OSDeclareDefaultStructors(IOATI128NDRV)
                     63: 
                     64: public:
                     65:     virtual void flushCursor( void );
                     66: };
                     67: 
                     68: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     69: 
                     70: struct _VSLService {
                     71:     class IONDRVFramebuffer *  framebuffer;
                     72:     IOSelect                   type;
                     73:     IOFBInterruptProc                  handler;
                     74:     OSObject *                 target;
                     75:     void *                     ref;
                     76:     _VSLService *              next;
                     77: };
                     78: 
                     79: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     80: 
                     81: // frame buffer has two power states, off and on
                     82: #define number_of_power_states 2
                     83: 
                     84: static IOPMPowerState ourPowerStates[number_of_power_states] = {
                     85:   {1,0,0,0,0,0,0,0,0,0,0,0},
                     86:   {1,IOPMDeviceUsable,IOPMPowerOn,IOPMPowerOn,0,0,0,0,0,0,0,0}
                     87: };
                     88: 
                     89: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     90: 
                     91: #define super IOFramebuffer
                     92: 
                     93: OSDefineMetaClassAndStructors(IONDRVFramebuffer, IOFramebuffer)
                     94: 
                     95: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     96: 
                     97: //============
                     98: //= External =
                     99: //============
                    100: 
                    101: IOService * IONDRVFramebuffer::probe( IOService *      provider,
                    102:                                         SInt32 *       score )
                    103: {
                    104:     IOService *                inst = this;
                    105:     IOService *                newInst = 0;
                    106:     const char *       name;
                    107: 
                    108:     if( !super::probe( provider, score ))
                    109:        return( 0 );
                    110: 
                    111:     if( IONDRV::fromRegistryEntry( provider )) {
                    112: 
                    113:         // temporary for in-kernel acceleration
                    114:         name = provider->getName();
                    115:         if( 0 == strncmp("ATY,Rage128", name, strlen("ATY,Rage128")))
                    116:             newInst = new IOATI128NDRV;
                    117:         else if( 0 == strncmp("ATY,", name, strlen("ATY,")))
                    118:             newInst = new IOATINDRV;
                    119: 
                    120:        if( newInst) {
                    121:             if( ! newInst->init( inst->getPropertyTable())) {
                    122:                 newInst->release();
                    123:                 newInst = 0;
                    124:             }
                    125:            inst = newInst;
                    126:        }
                    127:     } else
                    128:        inst = 0;
                    129: 
                    130:     return( inst );
                    131: }
                    132: 
                    133: bool IONDRVFramebuffer::start( IOService * provider )
                    134: {
                    135:     bool               ok = false;
                    136:     IOService *                parent;
                    137:     
                    138:     do {
                    139:        nub = provider;
                    140:         ndrv = IONDRV::fromRegistryEntry( provider );
                    141:        if( 0 == ndrv)
                    142:            continue;
                    143: 
                    144:        setName( ndrv->driverName());
                    145:        startAt8 = 3;
                    146:         consoleDevice = (0 != provider->getProperty("AAPL,boot-display"));
                    147: 
                    148:         if( 0 == nub->getDeviceMemoryCount()) {
                    149:             parent = OSDynamicCast( IOService, nub->getParentEntry(gIODTPlane));
                    150:             if( parent) {
                    151:                 parent->getResources();
                    152:                 OSArray * array = parent->getDeviceMemory();
                    153:                 array->retain();
                    154:                 nub->setDeviceMemory( array);
                    155:                 array->release();
                    156:             }
                    157:         }
                    158: 
                    159:         if( false == super::start( nub ))
                    160:            continue;
                    161: 
                    162:        ok = true;                      // Success
                    163: 
                    164:     } while( false);
                    165:     
                    166:     return( ok);
                    167: }
                    168: 
                    169: bool IONDRVFramebuffer::isConsoleDevice( void )
                    170: {
                    171:     return( consoleDevice );
                    172: }
                    173: 
                    174: // osfmk/ppc/mappings.h
                    175: extern "C" { extern void ignore_zero_fault(boolean_t); }
                    176: 
                    177: IOReturn IONDRVFramebuffer::enableController( void )
                    178: {
                    179:     IOReturn           err;
                    180:     const char *       logname;
                    181:     
                    182:     logname = getProvider()->getName();
                    183: 
                    184:     if( 0 == strcmp( "control", logname))
                    185:         waitForService( resourceMatching( "IOiic0" ));
                    186: 
                    187:     err = IONDRVLibrariesInitialize( getProvider() );
                    188: 
                    189:     if( kIOReturnSuccess == err) do {
                    190: 
                    191:         ignore_zero_fault( true );
                    192:        err = checkDriver();
                    193:         ignore_zero_fault( false );
                    194: 
                    195:         if( err) {
                    196:             IOLog("%s: Not usable\n", logname );
                    197:             if( err == -999)
                    198:                 IOLog("%s: driver incompatible.\n", logname );
                    199:             continue;
                    200:         }
                    201:         getCurrentConfiguration();
                    202:         vramMemory = findVRAM();
                    203: 
                    204:     } while( false);
                    205: 
                    206:     // initialize power management of the device
                    207:     initForPM();
                    208:     
                    209:     return( err);
                    210: }
                    211: 
                    212: IODeviceMemory * IONDRVFramebuffer::getVRAMRange( void )
                    213: {
                    214:     if( vramMemory)
                    215:        vramMemory->retain();
                    216: 
                    217:     return( vramMemory );
                    218: }
                    219: 
                    220: void IONDRVFramebuffer::free( void )
                    221: {
                    222:     super::free();
                    223: }
                    224: 
                    225: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    226: 
                    227: IOReturn IONDRVFramebuffer::registerForInterruptType( IOSelect interruptType,
                    228:                         IOFBInterruptProc proc, OSObject * target, void * ref,
                    229:                        void ** interruptRef )
                    230: 
                    231: {
                    232:     _VSLService *      service;
                    233:     IOReturn           err;
                    234: 
                    235:     if( (interruptType == kIOFBVBLInterruptType)
                    236:         && (getProvider()->getProperty("Ignore VBL")))
                    237:        return( kIOReturnUnsupported );
                    238: 
                    239:     for( service = vslServices;
                    240:         service && (service->type != interruptType);
                    241:         service = service->next ) {}
                    242: 
                    243:     if( service) {
                    244: 
                    245:        if( service->handler)
                    246:            err = kIOReturnBusy;
                    247: 
                    248:        else {
                    249:            service->target     = target;
                    250:            service->ref        = ref;
                    251:            service->handler    = proc;
                    252:            *interruptRef = service;
                    253:            err = kIOReturnSuccess;
                    254:        }
                    255: 
                    256:     } else
                    257:        err = kIOReturnNoResources;
                    258: 
                    259:     return( err );
                    260: }
                    261: 
                    262: IOReturn IONDRVFramebuffer::unregisterInterrupt( void * interruptRef )
                    263: {
                    264:     _VSLService *      service = (_VSLService *) interruptRef;
                    265: 
                    266:     service->handler = 0;
                    267: 
                    268:     return( kIOReturnSuccess );
                    269: }
                    270: 
                    271: IOReturn IONDRVFramebuffer::setInterruptState( void * interruptRef, 
                    272:                                                UInt32 state )
                    273: {
                    274:     return( kIOReturnUnsupported );
                    275: }
                    276: 
                    277: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    278: 
                    279: //// VSL calls
                    280: 
                    281: OSStatus IONDRVFramebuffer::VSLNewInterruptService(
                    282:                                         void * entryID,
                    283:                                         IOSelect serviceType,
                    284:                                         _VSLService ** vslService )
                    285: {
                    286:     IORegistryEntry *  regEntry;
                    287:     IONDRVFramebuffer *        fb;
                    288:     _VSLService *      service;
                    289:     IOReturn           err = kIOReturnSuccess;
                    290: 
                    291:     REG_ENTRY_TO_OBJ( (const RegEntryID *) entryID, regEntry)
                    292: 
                    293:     fb = OSDynamicCast( IONDRVFramebuffer,
                    294:                regEntry->getChildEntry( gIOServicePlane ));
                    295:     assert( fb );
                    296: 
                    297:     if( fb) {
                    298:        service = IONew( _VSLService, 1 );
                    299: 
                    300:        if( service) {
                    301:             service->framebuffer       = fb;
                    302:             service->type              = serviceType;
                    303:            service->handler            = 0;
                    304:             service->next = fb->vslServices;
                    305:             fb->vslServices = service;
                    306: 
                    307:             *vslService = service;
                    308: 
                    309:        } else
                    310:            err = kIOReturnNoMemory;
                    311: 
                    312:     } else
                    313:        err = kIOReturnBadArgument;
                    314: 
                    315:     return( err );
                    316: }
                    317: 
                    318: OSStatus IONDRVFramebuffer::VSLDisposeInterruptService(_VSLService * vslService)
                    319: {
                    320:     IONDRVFramebuffer *        fb;
                    321:     _VSLService *      next;
                    322:     _VSLService *      prev;
                    323: 
                    324:     if( vslService) {
                    325: 
                    326:        fb = vslService->framebuffer;
                    327: 
                    328:         prev = fb->vslServices;
                    329:        if( prev == vslService)
                    330:            fb->vslServices = vslService->next;
                    331:        else {
                    332:            while( ((next = prev->next) != vslService) && next)
                    333:                prev = next;
                    334:            if( next)
                    335:                prev->next = vslService->next;
                    336:        }
                    337: 
                    338:        IODelete( vslService, _VSLService, 1 );
                    339:     }
                    340: 
                    341:     return( kIOReturnSuccess );
                    342: }
                    343: 
                    344: OSStatus IONDRVFramebuffer::VSLDoInterruptService( _VSLService * vslService )
                    345: {
                    346:     IOFBInterruptProc  proc;
                    347: 
                    348:     if( vslService) {
                    349:        if( (proc = vslService->handler))
                    350:            (*proc) (vslService->target, vslService->ref);
                    351:     }
                    352: 
                    353:     return( kIOReturnSuccess );
                    354: }
                    355: 
                    356: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    357: 
                    358: struct _VSLCursorRef {
                    359:     IOFramebuffer *    framebuffer;
                    360:     void *             cursorImage;
                    361: };
                    362: 
                    363: Boolean IONDRVFramebuffer::VSLPrepareCursorForHardwareCursor(
                    364:                                         void * cursorRef,
                    365:                                         IOHardwareCursorDescriptor * hwDesc,
                    366:                                         IOHardwareCursorInfo * hwCursorInfo )
                    367: {
                    368:     _VSLCursorRef *    cursor = (_VSLCursorRef *) cursorRef;
                    369:     bool               ok;
                    370: 
                    371:     if( hwCursorInfo->colorMap)
                    372:         hwCursorInfo->colorMap += 1;
                    373:     ok = cursor->framebuffer->convertCursorImage(
                    374:                cursor->cursorImage, hwDesc, hwCursorInfo );
                    375:     if( hwCursorInfo->colorMap)
                    376:         hwCursorInfo->colorMap -= 1;
                    377: 
                    378:     return( ok );
                    379: }
                    380: 
                    381: IOReturn IONDRVFramebuffer::setCursorImage( void * cursorImage )
                    382: {
                    383:     _VSLCursorRef              cursorRef;
                    384:     VDSetHardwareCursorRec     setCursor;
                    385:     IOReturn                   err;
                    386: 
                    387:     cursorRef.framebuffer = this;
                    388:     cursorRef.cursorImage = cursorImage;
                    389: 
                    390:     setCursor.csCursorRef = (void *) &cursorRef;
                    391:     setCursor.csReserved1 = 0;
                    392:     setCursor.csReserved2 = 0;
                    393: 
                    394:     err = doControl( cscSetHardwareCursor, &setCursor );
                    395: 
                    396:     return( err );
                    397: }
                    398: 
                    399: IOReturn IONDRVFramebuffer::setCursorState( SInt32 x, SInt32 y, bool visible )
                    400: {
                    401:     VDDrawHardwareCursorRec    drawCursor;
                    402:     IOReturn                   err;
                    403: 
                    404:     if( 0 == OSIncrementAtomic( &ndrvEnter))
                    405:     {
                    406: 
                    407:         drawCursor.csCursorX   = x;
                    408:         drawCursor.csCursorY   = y;
                    409:         drawCursor.csCursorVisible     = visible;
                    410:         drawCursor.csReserved1         = 0;
                    411:         drawCursor.csReserved2         = 0;
                    412: 
                    413:         err = doControl( cscDrawHardwareCursor, &drawCursor );
                    414: 
                    415:     } else
                    416:        err = kIOReturnBusy;
                    417: 
                    418:     OSDecrementAtomic( &ndrvEnter );
                    419: 
                    420:     return( err );
                    421: }
                    422: 
                    423: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    424: 
                    425: //============
                    426: //= Internal =
                    427: //============
                    428: 
                    429: IOReturn IONDRVFramebuffer::doControl( UInt32 code, void * params )
                    430: {
                    431:     IOReturn   err;
                    432:     CntrlParam pb;
                    433: 
                    434:     if( ndrvState == 0)
                    435:        return( kIOReturnNotOpen);
                    436: 
                    437:     pb.qLink = 0;
                    438:     pb.csCode = code;
                    439:     pb.csParams = params;
                    440: 
                    441:     OSIncrementAtomic( &ndrvEnter );
                    442:     err = ndrv->doDriverIO( /*ID*/ (UInt32) &pb, &pb,
                    443:                             kControlCommand, kImmediateIOCommandKind );
                    444:     OSDecrementAtomic( &ndrvEnter );
                    445: 
                    446:     return( err);
                    447: }
                    448: 
                    449: IOReturn IONDRVFramebuffer::doStatus( UInt32 code, void * params )
                    450: {
                    451:     IOReturn   err;
                    452:     CntrlParam pb;
                    453: 
                    454:     if( ndrvState == 0)
                    455:        return( kIOReturnNotOpen);
                    456: 
                    457:     pb.qLink = 0;
                    458:     pb.csCode = code;
                    459:     pb.csParams = params;
                    460: 
                    461:     OSIncrementAtomic( &ndrvEnter );
                    462:     err = ndrv->doDriverIO( /*ID*/ (UInt32) &pb, &pb,
                    463:                             kStatusCommand, kImmediateIOCommandKind );
                    464:     OSDecrementAtomic( &ndrvEnter );
                    465: 
                    466:     return( err);
                    467: }
                    468: 
                    469: 
                    470: IOReturn IONDRVFramebuffer::checkDriver( void )
                    471: {
                    472:     OSStatus                   err = noErr;
                    473:     struct DriverInitInfo      initInfo;
                    474:     CntrlParam                 pb;
                    475:     VDClutBehavior             clutSetting;
                    476:     VDGammaRecord              gammaRec;
                    477:     VDSwitchInfoRec            switchInfo;
                    478:     IOTimingInformation        info;
                    479:     VDPageInfo                 pageInfo;
                    480: 
                    481:     if( ndrvState == 0) {
                    482:        do {
                    483:            initInfo.refNum = 0xffcd;                   // ...sure.
                    484:            MAKE_REG_ENTRY(initInfo.deviceEntry, nub )
                    485:     
                    486:            err = ndrv->doDriverIO( 0, &initInfo,
                    487:                                kInitializeCommand, kImmediateIOCommandKind );
                    488:            if( err) continue;
                    489: 
                    490:            err = ndrv->doDriverIO( 0, &pb,
                    491:                                kOpenCommand, kImmediateIOCommandKind );
                    492: 
                    493:        } while( false);
                    494: 
                    495:        if( err)
                    496:            return( err);
                    497: 
                    498:         // allow calls to ndrv
                    499:         ndrvState = 1;
                    500: 
                    501:         if( (noErr == doStatus( cscGetCurMode, &switchInfo ))
                    502:             && (noErr == getTimingInfoForDisplayMode( switchInfo.csData, &info))
                    503:             && (timingApple_0x0_0hz_Offline == info.appleTimingID)) {
                    504: 
                    505:             IOLog("%s: display offline\n", getName());
                    506:             err = kIOReturnOffline;
                    507:             return( err);
                    508:         } else
                    509:             ndrvState = 2;
                    510: 
                    511:         // duplicate QD InitGDevice
                    512:         pageInfo.csMode = switchInfo.csMode;
                    513:         pageInfo.csData = 0;
                    514:         pageInfo.csPage = 0;
                    515:         doControl( cscGrayPage, &pageInfo);
                    516: 
                    517:         clutSetting = kSetClutAtSetEntries;
                    518:         lastClutSetting = clutSetting;
                    519:         doControl( cscSetClutBehavior, &clutSetting);
                    520: 
                    521: #if 1
                    522:        // bogus for ROM control
                    523:        do {
                    524: 
                    525:            VDGetGammaListRec   scan;
                    526:            VDRetrieveGammaRec  get;
                    527:            GammaTbl *          table;
                    528:            char                name[ 64 ];
                    529: 
                    530:            scan.csPreviousGammaTableID = kGammaTableIDFindFirst;
                    531:            scan.csGammaTableName = name;
                    532:            err = doStatus( cscGetGammaInfoList, &scan);
                    533:            if( err || (scan.csGammaTableID == kGammaTableIDNoMoreTables))
                    534:                continue;
                    535: 
                    536:            table = (GammaTbl *)IOMalloc( scan.csGammaTableSize);
                    537:            if( 0 == table)
                    538:                continue;
                    539:            get.csGammaTableID = scan.csGammaTableID;
                    540:            get.csGammaTablePtr = table;
                    541:            
                    542:            err = doStatus( cscRetrieveGammaTable, &get );
                    543:            if( noErr == err) {
                    544:                kprintf("Setting gamma %s\n", scan.csGammaTableName);
                    545:                gammaRec.csGTable = (Ptr) table;
                    546:                doControl( cscSetGamma, &gammaRec );
                    547:            }
                    548: 
                    549:            IOFree( table, scan.csGammaTableSize);
                    550: 
                    551:        } while( false);
                    552: #endif
                    553:     }
                    554:     return( noErr);
                    555: }
                    556: 
                    557: 
                    558: UInt32 IONDRVFramebuffer::iterateAllModes( IODisplayModeID * displayModeIDs )
                    559: {
                    560:     VDResolutionInfoRec        info;
                    561:     UInt32             num = 0;
                    562: 
                    563:     info.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution;
                    564: 
                    565:     while( 
                    566:           (noErr == doStatus( cscGetNextResolution, &info))
                    567:        && ((SInt32) info.csDisplayModeID > 0) ) {
                    568: 
                    569:            if( displayModeIDs)
                    570:                displayModeIDs[ num ] = info.csDisplayModeID;
                    571: 
                    572:            info.csPreviousDisplayModeID = info.csDisplayModeID;
                    573:            num++;
                    574:     }
                    575:     return( num);
                    576: }
                    577: 
                    578: 
                    579: IOReturn IONDRVFramebuffer::getResInfoForMode( IODisplayModeID modeID,
                    580:                                VDResolutionInfoRec ** theInfo )
                    581: {
                    582:     // unfortunately, there is no "kDisplayModeIDFindSpecific"
                    583: 
                    584:     if( (SInt32) modeID <= 0)
                    585:         return( kIOReturnUnsupportedMode);
                    586: 
                    587:     *theInfo = &cachedVDResolution;
                    588: 
                    589:     if( cachedVDResolution.csDisplayModeID == (UInt32) modeID)
                    590:        return( noErr);
                    591: 
                    592:     // try the next after cached mode
                    593:     cachedVDResolution.csPreviousDisplayModeID = cachedVDResolution.csDisplayModeID;
                    594: 
                    595:     if( (noErr == doStatus( cscGetNextResolution, &cachedVDResolution))
                    596:     && (cachedVDResolution.csDisplayModeID == (UInt32) modeID) )
                    597:        return( noErr);
                    598: 
                    599:     // full blown iterate
                    600:     cachedVDResolution.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution;
                    601: 
                    602:     while(
                    603:        (noErr == doStatus( cscGetNextResolution, &cachedVDResolution))
                    604:     && (cachedVDResolution.csDisplayModeID != (UInt32) modeID) 
                    605:     && ((SInt32) cachedVDResolution.csDisplayModeID > 0)) {
                    606: 
                    607:        cachedVDResolution.csPreviousDisplayModeID = cachedVDResolution.csDisplayModeID;
                    608:     }
                    609: 
                    610:     if( cachedVDResolution.csDisplayModeID == (UInt32) modeID)
                    611:        return( noErr);
                    612: 
                    613:     cachedVDResolution.csDisplayModeID = 0xffffffff;
                    614:     return( kIOReturnUnsupportedMode);
                    615: }
                    616: 
                    617: void IONDRVFramebuffer::getCurrentConfiguration( void )
                    618: {
                    619:     IOReturn           err;
                    620:     VDSwitchInfoRec    switchInfo;
                    621:     VDGrayRecord       grayRec;
                    622: 
                    623:     grayRec.csMode = 0;                        // turn off luminance map
                    624:     err = doControl( cscSetGray, &grayRec );
                    625:     // driver refused => mono display
                    626:     grayMode = ((noErr == err) && (0 != grayRec.csMode));
                    627: 
                    628:     err = doStatus( cscGetCurMode, &switchInfo );
                    629:     if( err == noErr) {
                    630:         currentDisplayMode     = switchInfo.csData;
                    631:         currentDepth           = switchInfo.csMode - kDepthMode1;
                    632:         currentPage            = switchInfo.csPage;
                    633:        if( 0 == (physicalFramebuffer = pmap_extract( kernel_pmap,
                    634:                ((vm_address_t) switchInfo.csBaseAddr) )))
                    635:            physicalFramebuffer = (UInt32) switchInfo.csBaseAddr;
                    636:     } else
                    637:        IOLog("%s: cscGetCurMode failed\n", nub->getName());
                    638: }
                    639: 
                    640: IODeviceMemory * IONDRVFramebuffer::makeSubRange( 
                    641:        IOPhysicalAddress       start,
                    642:        IOPhysicalLength        length ) 
                    643: {
                    644:     IODeviceMemory *   mem = 0;
                    645:     UInt32             numMaps, i;
                    646:     IOService *                device;
                    647: 
                    648:     device = nub;
                    649:     numMaps = device->getDeviceMemoryCount();
                    650: 
                    651:     for( i = 0; (!mem) && (i < numMaps); i++) {
                    652:        mem = device->getDeviceMemoryWithIndex(i);
                    653:        if( !mem)
                    654:            continue;
                    655:        mem = IODeviceMemory::withSubRange( mem,
                    656:                        start - mem->getPhysicalAddress(), length );
                    657:     }
                    658:     if( !mem)
                    659:        mem = IODeviceMemory::withRange( start, length );
                    660: 
                    661:     return( mem );
                    662: }
                    663: 
                    664: IODeviceMemory * IONDRVFramebuffer::getApertureRange( IOPixelAperture aper )
                    665: {
                    666:     IOReturn                   err;
                    667:     IOPixelInformation         info;
                    668:     IOByteCount                        bytes;
                    669: 
                    670:     err = getPixelInformation( currentDisplayMode, currentDepth, aper,
                    671:                                 &info );
                    672:     if( err)
                    673:        return( 0 );
                    674: 
                    675:     bytes = (info.bytesPerRow * info.activeHeight) + 128;
                    676: 
                    677:     return( makeSubRange( physicalFramebuffer, bytes ));
                    678: }
                    679: 
                    680: IODeviceMemory * IONDRVFramebuffer::findVRAM( void )
                    681: {
                    682:     VDVideoParametersInfoRec   pixelParams;
                    683:     VPBlock                    pixelInfo;
                    684:     VDResolutionInfoRec                vdRes;
                    685:     UInt32                     size;
                    686:     IOPhysicalAddress          vramBase;
                    687:     IOByteCount                        vramLength;
                    688:     IOReturn                   err;
                    689: 
                    690:     vramLength = 0;
                    691:     vdRes.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution;
                    692:     while(
                    693:         (noErr == doStatus( cscGetNextResolution, &vdRes))
                    694:     && ((SInt32) vdRes.csDisplayModeID > 0) )
                    695:     {
                    696:         pixelParams.csDisplayModeID = vdRes.csDisplayModeID;
                    697:         pixelParams.csDepthMode = vdRes.csMaxDepthMode;
                    698:         pixelParams.csVPBlockPtr = &pixelInfo;
                    699:         err = doStatus( cscGetVideoParameters, &pixelParams);
                    700:         if( err)
                    701:             continue;
                    702: 
                    703:         // Control hangs its framebuffer off the end of the aperture to support
                    704:         // 832 x 624 @ 32bpp. The commented out version will correctly calculate
                    705:         // the vram length, but DPS needs the full extent to be mapped, so we'll
                    706:         // end up mapping an extra page that will address vram through the
                    707:         // little endian aperture. No other drivers like this known.
                    708: #if 1
                    709:         size = 0x40 + pixelInfo.vpBounds.bottom *
                    710:                        (pixelInfo.vpRowBytes & 0x7fff);
                    711: #else
                    712:         size = ( (pixelInfo.vpBounds.right * pixelInfo.vpPixelSize) / 8)       // last line
                    713:                 + (pixelInfo.vpBounds.bottom - 1) *
                    714:                (pixelInfo.vpRowBytes & 0x7fff);
                    715: #endif
                    716:         if( size > vramLength)
                    717:             vramLength = size;
                    718: 
                    719:         vdRes.csPreviousDisplayModeID = vdRes.csDisplayModeID;
                    720:     }
                    721: 
                    722:     vramBase = physicalFramebuffer;
                    723:     vramLength = (vramLength + (vramBase & 0xffff) + 0xffff) & 0xffff0000;
                    724:     vramBase &= 0xffff0000;
                    725: 
                    726:     return( makeSubRange( vramBase, vramLength ));
                    727: }
                    728: 
                    729: //============
                    730: //= External =
                    731: //============
                    732: 
                    733: const char * IONDRVFramebuffer::getPixelFormats( void )
                    734: {
                    735:     static const char * ndrvPixelFormats =
                    736:         IO1BitIndexedPixels "\0"
                    737:         IO2BitIndexedPixels "\0"
                    738:         IO4BitIndexedPixels "\0"
                    739:         IO8BitIndexedPixels "\0"
                    740:         IO16BitDirectPixels "\0"
                    741:         IO32BitDirectPixels "\0"
                    742:         "\0";
                    743: 
                    744:     return( ndrvPixelFormats);
                    745: }
                    746: 
                    747: IOItemCount IONDRVFramebuffer::getDisplayModeCount( void )
                    748: {
                    749:     return( iterateAllModes( 0 ));
                    750: }
                    751: 
                    752: IOReturn IONDRVFramebuffer::getDisplayModes( IODisplayModeID * allDisplayModes )
                    753: {
                    754:     iterateAllModes( allDisplayModes );
                    755:     return( kIOReturnSuccess );
                    756: }
                    757: 
                    758: IOReturn IONDRVFramebuffer::getInformationForDisplayMode(
                    759:                IODisplayModeID displayMode, IODisplayModeInformation * info )
                    760: {
                    761:     IOReturn                   err;
                    762:     VDResolutionInfoRec        *       resInfo;
                    763: 
                    764:     bzero( info, sizeof( *info));
                    765:     do {
                    766:        err = getResInfoForMode( displayMode, &resInfo );
                    767:        if( err)
                    768:            continue;
                    769:        info->maxDepthIndex     = resInfo->csMaxDepthMode - kDepthMode1;
                    770:        info->nominalWidth      = resInfo->csHorizontalPixels;
                    771:        info->nominalHeight     = resInfo->csVerticalLines;
                    772:        info->refreshRate       = resInfo->csRefreshRate;
                    773:        return( noErr);
                    774:     } while( false);
                    775: 
                    776:     return( kIOReturnUnsupportedMode);
                    777: }
                    778: 
                    779: 
                    780: UInt64 IONDRVFramebuffer::getPixelFormatsForDisplayMode(
                    781:                IODisplayModeID /* displayMode */, IOIndex depthIndex )
                    782: {
                    783:     return( 1 << (depthIndex + startAt8));
                    784: }
                    785: 
                    786: IOReturn IONDRVFramebuffer::getPixelInformation(
                    787:        IODisplayModeID displayMode, IOIndex depth,
                    788:        IOPixelAperture aperture, IOPixelInformation * info )
                    789: {
                    790:     SInt32                     err;
                    791:     VDVideoParametersInfoRec   pixelParams;
                    792:     VPBlock                    pixelInfo;
                    793:     const char *               formats;
                    794:     UInt32                     mask;
                    795:     int                                index;
                    796: 
                    797:     bzero( info, sizeof( *info));
                    798: 
                    799:     if( aperture)
                    800:         return( kIOReturnUnsupportedMode);
                    801: 
                    802:     do {
                    803:        pixelParams.csDisplayModeID = displayMode;
                    804:        pixelParams.csDepthMode = depth + kDepthMode1;
                    805:        pixelParams.csVPBlockPtr = &pixelInfo;
                    806:        err = doStatus( cscGetVideoParameters, &pixelParams );
                    807:        if( err)
                    808:            continue;
                    809: 
                    810:        //info->flags = kFramebufferSupportsCopybackCache;    
                    811: 
                    812:        info->activeWidth       = pixelInfo.vpBounds.right;
                    813:        info->activeHeight      = pixelInfo.vpBounds.bottom;
                    814:        info->bytesPerRow       = pixelInfo.vpRowBytes & 0x7fff;
                    815:        info->bytesPerPlane     = pixelInfo.vpPlaneBytes;
                    816:        info->bitsPerPixel      = pixelInfo.vpPixelSize;
                    817: 
                    818:         formats = getPixelFormats();
                    819:         mask = getPixelFormatsForDisplayMode( displayMode, depth );
                    820: 
                    821:         for( index = 0; index < 32; index++) {
                    822:             if( (mask & (1 << index)) && ((aperture--) == 0)) {
                    823:                 strcpy( info->pixelFormat, formats);
                    824:                 break;
                    825:             }
                    826:             formats += strlen( formats) + 1;
                    827:         }
                    828: 
                    829:         if( 0 == strcmp("PPPPPPPP", info->pixelFormat)) {
                    830:             info->pixelType = kIOCLUTPixels;
                    831:             info->componentMasks[0] = 0xff;
                    832:             info->bitsPerPixel = 8;
                    833:             info->componentCount = 1;
                    834:             info->bitsPerComponent = 8;
                    835: 
                    836:         } else if( 0 == strcmp("-RRRRRGGGGGBBBBB", info->pixelFormat)) {
                    837:             info->pixelType = kIORGBDirectPixels;
                    838:             info->componentMasks[0] = 0x7c00;
                    839:             info->componentMasks[1] = 0x03e0;
                    840:             info->componentMasks[2] = 0x001f;
                    841:             info->bitsPerPixel = 16;
                    842:             info->componentCount = 3;
                    843:             info->bitsPerComponent = 5;
                    844: 
                    845:         } else if( 0 == strcmp("--------RRRRRRRRGGGGGGGGBBBBBBBB",
                    846:                                         info->pixelFormat)) {
                    847:             info->pixelType = kIORGBDirectPixels;
                    848:             info->componentMasks[0] = 0x00ff0000;
                    849:             info->componentMasks[1] = 0x0000ff00;
                    850:             info->componentMasks[2] = 0x000000ff;
                    851:             info->bitsPerPixel = 32;
                    852:             info->componentCount = 3;
                    853:             info->bitsPerComponent = 8;
                    854:         }
                    855: 
                    856:     } while( false);
                    857: 
                    858:     return( err);
                    859: }
                    860: 
                    861: IOReturn IONDRVFramebuffer::getTimingInfoForDisplayMode(
                    862:                IODisplayModeID displayMode, IOTimingInformation * info )
                    863: {
                    864:     VDTimingInfoRec            timingInfo;
                    865:     OSStatus                   err;
                    866: 
                    867:     timingInfo.csTimingMode = displayMode;
                    868:     // in case the driver doesn't do it:
                    869:     timingInfo.csTimingFormat = kDeclROMtables;
                    870:     err = doStatus( cscGetModeTiming, &timingInfo);
                    871:     if( err == noErr) {
                    872:        if( timingInfo.csTimingFormat == kDeclROMtables)
                    873:            info->appleTimingID = timingInfo.csTimingData;
                    874:        else
                    875:            info->appleTimingID = timingInvalid;
                    876: 
                    877:        return( kIOReturnSuccess);
                    878:     }
                    879: 
                    880:     return( kIOReturnUnsupportedMode);
                    881: }
                    882: 
                    883: IOReturn IONDRVFramebuffer::getCurrentDisplayMode( 
                    884:                                IODisplayModeID * displayMode, IOIndex * depth )
                    885: {
                    886:     if( displayMode)
                    887:        *displayMode = currentDisplayMode;
                    888:     if( depth)
                    889:        *depth = currentDepth;
                    890: 
                    891:     return( kIOReturnSuccess);
                    892: }
                    893: 
                    894: IOReturn IONDRVFramebuffer::setDisplayMode( IODisplayModeID displayMode, IOIndex depth )
                    895: {
                    896:     SInt32             err;
                    897:     VDSwitchInfoRec    switchInfo;
                    898:     VDPageInfo         pageInfo;
                    899: 
                    900:     switchInfo.csData = displayMode;
                    901:     switchInfo.csMode = depth + kDepthMode1;
                    902:     switchInfo.csPage = 0;
                    903:     err = doControl( cscSwitchMode, &switchInfo);
                    904:     if(err)
                    905:        IOLog("%s: cscSwitchMode:%d\n", nub->getName(), (int)err);
                    906: 
                    907:     // duplicate QD InitGDevice
                    908:     pageInfo.csMode = switchInfo.csMode;
                    909:     pageInfo.csData = 0;
                    910:     pageInfo.csPage = 0;
                    911:     doControl( cscSetMode, &pageInfo);
                    912:     doControl( cscGrayPage, &pageInfo);
                    913: 
                    914:     getCurrentConfiguration();
                    915: 
                    916:     return( err);
                    917: }
                    918: 
                    919: IOReturn IONDRVFramebuffer::setStartupDisplayMode(
                    920:                        IODisplayModeID displayMode, IOIndex depth )
                    921: {
                    922:     SInt32             err;
                    923:     VDSwitchInfoRec    switchInfo;
                    924: 
                    925:     switchInfo.csData = displayMode;
                    926:     switchInfo.csMode = depth + kDepthMode1;
                    927:     err = doControl( cscSavePreferredConfiguration, &switchInfo);
                    928:     return( err);
                    929: }
                    930: 
                    931: IOReturn IONDRVFramebuffer::getStartupDisplayMode(
                    932:                                IODisplayModeID * displayMode, IOIndex * depth )
                    933: {
                    934:     SInt32             err;
                    935:     VDSwitchInfoRec    switchInfo;
                    936: 
                    937:     err = doStatus( cscGetPreferredConfiguration, &switchInfo);
                    938:     if( err == noErr) {
                    939:        *displayMode    = switchInfo.csData;
                    940:        *depth          = switchInfo.csMode - kDepthMode1;
                    941:     }
                    942:     return( err);
                    943: }
                    944: 
                    945: IOReturn IONDRVFramebuffer::setApertureEnable( IOPixelAperture /* aperture */,
                    946:                                                IOOptionBits /* enable */ )
                    947: {
                    948:     return( kIOReturnSuccess);
                    949: }
                    950: 
                    951: IOReturn IONDRVFramebuffer::setCLUTWithEntries(
                    952:                        IOColorEntry * colors, UInt32 index, UInt32 numEntries,
                    953:                        IOOptionBits options )
                    954: {
                    955:     IOReturn           err;
                    956:     UInt32             code;
                    957:     VDSetEntryRecord   setEntryRec;
                    958:     VDClutBehavior     clutSetting;
                    959:     VDGrayRecord       grayRec;
                    960: 
                    961:     if( options & kSetCLUTWithLuminance)
                    962:         grayRec.csMode = 1;            // turn on luminance map
                    963:     else
                    964:         grayRec.csMode = 0;            // turn off luminance map
                    965: 
                    966:     if( grayRec.csMode != lastGrayMode) {
                    967:        doControl( cscSetGray, &grayRec);
                    968:        lastGrayMode = grayRec.csMode;
                    969:     }
                    970: 
                    971:     if( options & kSetCLUTImmediately)
                    972:         clutSetting = kSetClutAtSetEntries;
                    973:     else
                    974:         clutSetting = kSetClutAtVBL;
                    975: 
                    976:     if( clutSetting != lastClutSetting) {
                    977:        doControl( cscSetClutBehavior, &clutSetting);
                    978:        lastClutSetting = clutSetting;
                    979:     }
                    980: 
                    981:     if( options & kSetCLUTByValue)
                    982:         setEntryRec.csStart = -1;
                    983:     else
                    984:         setEntryRec.csStart = index;
                    985: 
                    986:     setEntryRec.csTable = (ColorSpec *) colors;
                    987:     setEntryRec.csCount = numEntries - 1;
                    988:     if( directMode)
                    989:         code = cscDirectSetEntries;
                    990:     else
                    991:         code = cscSetEntries;
                    992:     err = doControl( code, &setEntryRec);
                    993: 
                    994:     return( err);
                    995: }
                    996: 
                    997: IOReturn IONDRVFramebuffer::setGammaTable( UInt32 channelCount, UInt32 dataCount,
                    998:                                             UInt32 dataWidth, void * data )
                    999: {
                   1000:     IOReturn           err;
                   1001:     VDGammaRecord      gammaRec;
                   1002:     struct GammaTbl {
                   1003:         short gVersion;                /*gamma version number*/
                   1004:         short gType;           /*gamma data type*/
                   1005:         short gFormulaSize;    /*Formula data size*/
                   1006:         short gChanCnt;                /*number of channels of data*/
                   1007:         short gDataCnt;                /*number of values/channel*/
                   1008:         short gDataWidth;      /*bits/corrected value */
                   1009:                                /* (data packed to next larger byte size)*/
                   1010:         UInt8 gFormulaData[0]; /*data for formulas followed by gamma values*/
                   1011:     };
                   1012:     GammaTbl *         table = NULL;
                   1013:     IOByteCount        dataLen = 0;
                   1014: 
                   1015:     if( data) {
                   1016:         dataLen = (dataWidth + 7) / 8;
                   1017:         dataLen *= dataCount * channelCount;
                   1018:         table = (GammaTbl *) IOMalloc( dataLen + sizeof( struct GammaTbl));
                   1019:         if( NULL == table)
                   1020:             return( kIOReturnNoMemory);
                   1021: 
                   1022:        table->gVersion         = 0;
                   1023:        table->gType            = 0;
                   1024:        table->gFormulaSize     = 0;
                   1025:        table->gChanCnt         = channelCount;
                   1026:        table-> gDataCnt        = dataCount;
                   1027:        table->gDataWidth       = dataWidth;
                   1028:        bcopy( data, table->gFormulaData, dataLen);
                   1029:     }
                   1030: 
                   1031:     gammaRec.csGTable = (Ptr) table;
                   1032:     err = doControl( cscSetGamma, &gammaRec);
                   1033:     if( table)
                   1034:         IOFree( table, dataLen + sizeof( struct GammaTbl));
                   1035: 
                   1036:     return( err);
                   1037: }
                   1038: 
                   1039: IOReturn IONDRVFramebuffer::getAttribute( IOSelect attribute, UInt32 * value )
                   1040: {
                   1041:     IOReturn                   err = kIOReturnSuccess;
                   1042:     VDSupportsHardwareCursorRec        hwCrsrSupport;
                   1043: 
                   1044:     switch( attribute ) {
                   1045: 
                   1046:        case kIOHardwareCursorAttribute:
                   1047: 
                   1048:            *value = ((kIOReturnSuccess ==
                   1049:                        doStatus( cscSupportsHardwareCursor, &hwCrsrSupport))
                   1050:                     && (hwCrsrSupport.csSupportsHardwareCursor));
                   1051:            break;
                   1052: 
                   1053:        default:
                   1054:            err = super::getAttribute( attribute, value );
                   1055:     }
                   1056: 
                   1057:     return( err );
                   1058: }
                   1059: 
                   1060: UInt32 IONDRVFramebuffer::getConnectionCount( void )
                   1061: {
                   1062:     VDMultiConnectInfoRec      theRecord;
                   1063: 
                   1064:     if( doStatus(cscGetMultiConnect,&theRecord) == 0 ) {
                   1065:         return theRecord.csDisplayCountOrNumber;
                   1066:     }
                   1067:     return 1;
                   1068: }
                   1069: 
                   1070: IOReturn IONDRVFramebuffer::setAttributeForConnection( IOIndex connectIndex,
                   1071:                                          IOSelect attribute, UInt32  info )
                   1072: {
                   1073:     IOReturn   ret;
                   1074:     VDSyncInfoRec      theVDSyncInfoRec;
                   1075: 
                   1076:     switch( attribute ) {
                   1077: 
                   1078:         case kConnectionSyncEnable:
                   1079:             theVDSyncInfoRec.csMode = (unsigned char)(info>>8);
                   1080:             theVDSyncInfoRec.csFlags = (unsigned char)(info & 0xFF);
                   1081:             doControl(cscSetSync,&theVDSyncInfoRec);
                   1082:             ret = kIOReturnSuccess;
                   1083:             break;
                   1084:         default:
                   1085:             ret = super::setAttributeForConnection( connectIndex,
                   1086:                                        attribute, info );
                   1087:             break;
                   1088:     }
                   1089:     return( ret );
                   1090: }
                   1091: 
                   1092:             
                   1093: IOReturn IONDRVFramebuffer::getAttributeForConnection( IOIndex connectIndex,
                   1094:                                          IOSelect attribute, UInt32  * value )
                   1095: {
                   1096:     IOReturn   ret;
                   1097:     VDSyncInfoRec      theVDSyncInfoRec;
                   1098:     
                   1099:     switch( attribute ) {
                   1100: 
                   1101:         case kConnectionSyncFlags:
                   1102:             // find out current state of sync lines
                   1103:             theVDSyncInfoRec.csMode = 0x00;
                   1104:             doStatus(cscGetSync,&theVDSyncInfoRec);
                   1105:             * value = theVDSyncInfoRec.csMode;
                   1106:             ret = kIOReturnSuccess;
                   1107:             break;
                   1108:         case kConnectionSyncEnable:
                   1109:             // what are the sync-controlling capabilities of the ndrv?
                   1110:             theVDSyncInfoRec.csMode = 0xFF;
                   1111:             doStatus(cscGetSync,&theVDSyncInfoRec);
                   1112:             * value = (UInt32)theVDSyncInfoRec.csMode;
                   1113:             ret = kIOReturnSuccess;
                   1114:             break;
                   1115:         case kConnectionSupportsHLDDCSense:
                   1116:         case kConnectionSupportsAppleSense:
                   1117:             ret = kIOReturnSuccess;
                   1118:             break;
                   1119:         default:
                   1120:             ret = super::getAttributeForConnection( connectIndex,
                   1121:                                attribute, value );
                   1122:             break;
                   1123:     }
                   1124: 
                   1125:     return( ret );
                   1126: }
                   1127: 
                   1128: IOReturn IONDRVFramebuffer::getAppleSense( IOIndex  connectIndex,
                   1129:                                             UInt32 * senseType,
                   1130:                                             UInt32 * primary,
                   1131:                                             UInt32 * extended,
                   1132:                                             UInt32 * displayType )
                   1133: {
                   1134:     OSStatus           err;
                   1135:     VDMultiConnectInfoRec      multiConnect;
                   1136:     UInt32                     sense, extSense;
                   1137: 
                   1138:     if( connectIndex == 0 )
                   1139:         err = doStatus( cscGetConnection, &multiConnect.csConnectInfo);
                   1140: 
                   1141:     else {
                   1142:         multiConnect.csDisplayCountOrNumber = connectIndex;
                   1143:         err = doControl( cscSetMultiConnect, &multiConnect);
                   1144:     }
                   1145:     if( err)
                   1146:        return( err);
                   1147: 
                   1148:     if( multiConnect.csConnectInfo.csConnectFlags 
                   1149:       & ((1<<kReportsTagging) | (1<<kTaggingInfoNonStandard))
                   1150:        != ((1<<kReportsTagging)) )
                   1151: 
                   1152:        err = kIOReturnUnsupported;
                   1153: 
                   1154:     else {
                   1155: 
                   1156:         sense          = multiConnect.csConnectInfo.csConnectTaggedType;
                   1157:         extSense       = multiConnect.csConnectInfo.csConnectTaggedData;
                   1158:        // bug fixes for really old ATI driver
                   1159:         if( sense == 0) {
                   1160:             if( extSense == 6) {
                   1161:                 sense                  = kRSCSix;
                   1162:                 extSense        = kESCSixStandard;
                   1163:             }
                   1164:             else
                   1165:                 if( extSense == 4) {
                   1166:                 sense          = kRSCFour;
                   1167:                 extSense        = kESCFourNTSC;
                   1168:                 }
                   1169:             }
                   1170:         if( primary)
                   1171:             *primary = sense;
                   1172:         if( extended)
                   1173:             *extended = extSense;
                   1174:         if( displayType)
                   1175:             *displayType = multiConnect.csConnectInfo.csDisplayType;
                   1176:         if( senseType)
                   1177:             *senseType = 0;
                   1178:     }
                   1179:     return( err);
                   1180: }
                   1181: 
                   1182: IOReturn IONDRVFramebuffer::connectFlags( IOIndex /* connectIndex */,
                   1183:                              IODisplayModeID displayMode, IOOptionBits * flags )
                   1184: {
                   1185:     VDTimingInfoRec            timingInfo;
                   1186:     OSStatus                   err;
                   1187: 
                   1188:     timingInfo.csTimingMode = displayMode;
                   1189:     // in case the driver doesn't do it:
                   1190:     timingInfo.csTimingFormat = kDeclROMtables;
                   1191:     err = doStatus( cscGetModeTiming, &timingInfo);
                   1192:     *flags = timingInfo.csTimingFlags;
                   1193:     return( err );
                   1194: }
                   1195: 
                   1196: 
                   1197: bool IONDRVFramebuffer::hasDDCConnect( IOIndex  connectIndex )
                   1198: {
                   1199:     OSStatus           err;
                   1200:     VDMultiConnectInfoRec      multiConnect;
                   1201:     enum               {       kNeedFlags = (1<<kReportsDDCConnection)
                   1202:                                           | (1<<kHasDDCConnection) };
                   1203:     if( connectIndex == 0 )
                   1204:         err = doStatus( cscGetConnection, &multiConnect.csConnectInfo);
                   1205:     else {
                   1206:         multiConnect.csDisplayCountOrNumber = connectIndex;
                   1207:         err = doControl( cscSetMultiConnect, &multiConnect);
                   1208:     }
                   1209:     if( err)
                   1210:         return( err);
                   1211: 
                   1212:     return( (multiConnect.csConnectInfo.csConnectFlags & kNeedFlags)
                   1213:                == kNeedFlags );
                   1214: }
                   1215: 
                   1216: IOReturn IONDRVFramebuffer::getDDCBlock( IOIndex /* connectIndex */, 
                   1217:                                        UInt32 blockNumber,
                   1218:                                         IOSelect blockType,
                   1219:                                        IOOptionBits options,
                   1220:                                         UInt8 * data, IOByteCount * length )
                   1221: 
                   1222: {
                   1223:     OSStatus           err = 0;
                   1224:     VDDDCBlockRec      ddcRec;
                   1225:     ByteCount          actualLength = *length;
                   1226: 
                   1227:     ddcRec.ddcBlockNumber      = blockNumber;
                   1228:     ddcRec.ddcBlockType        = blockType;
                   1229:     ddcRec.ddcFlags            = options;
                   1230: 
                   1231:     err = doStatus( cscGetDDCBlock, &ddcRec);
                   1232: 
                   1233:     if( err == noErr) {
                   1234: 
                   1235:        if( actualLength < kDDCBlockSize)
                   1236:             actualLength = actualLength;
                   1237:        else
                   1238:             actualLength = kDDCBlockSize;
                   1239:         bcopy( ddcRec.ddcBlockData, data, actualLength);
                   1240:        *length = actualLength;
                   1241:     }
                   1242:     return( err);
                   1243: }
                   1244: 
                   1245: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1246: // initForPM
                   1247: //
                   1248: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1249: void IONDRVFramebuffer::initForPM ( void )
                   1250: {
                   1251:     // register ourselves with superclass policy-maker
                   1252:     registerControllingDriver(this,ourPowerStates,number_of_power_states);
                   1253: }
                   1254: 
                   1255: 
                   1256: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1257: // maxCapabilityForDomainState
                   1258: //
                   1259: // This simple device needs only power.  If the power domain is supplying
                   1260: // power, the frame buffer can be on.  If there is no power it can only be off.
                   1261: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1262: 
                   1263: unsigned long  IONDRVFramebuffer::maxCapabilityForDomainState(
                   1264:                                        IOPMPowerFlags domainState )
                   1265: {
                   1266:    if( domainState &  IOPMPowerOn )
                   1267:        return number_of_power_states-1;
                   1268:    else
                   1269:        return 0;
                   1270: }
                   1271: 
                   1272: 
                   1273: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1274: // initialPowerStateForDomainState
                   1275: //
                   1276: // The power domain may be changing state.  If power is on in the new
                   1277: // state, that will not affect our state at all.  If domain power is off,
                   1278: // we can attain only our lowest state, which is off.
                   1279: //
                   1280: // This implementation is incomplete.  It only works in a system where
                   1281: // the frame buffer is never turned off.  When we cross that bridge,
                   1282: // instead of returning 1, it should return 1 if the frame buffer
                   1283: // is on, or 0 if it is off.
                   1284: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1285: unsigned long IONDRVFramebuffer::initialPowerStateForDomainState(
                   1286:                                         IOPMPowerFlags domainState )
                   1287: {
                   1288:    if( domainState &  IOPMPowerOn )
                   1289:        return number_of_power_states-1;
                   1290:    else
                   1291:        return 0;
                   1292: }
                   1293: 
                   1294: 
                   1295: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1296: // powerStateForDomainState
                   1297: //
                   1298: // The power domain may be changing state.  If power is on in the new
                   1299: // state, that will not affect our state at all.  If domain power is off,
                   1300: // we can attain only our lowest state, which is off.
                   1301: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1302: unsigned long  IONDRVFramebuffer::powerStateForDomainState(
                   1303:                                        IOPMPowerFlags domainState )
                   1304: {
                   1305:    if( domainState &  IOPMPowerOn )
                   1306:        return pm_vars->myCurrentState;
                   1307:    else
                   1308:        return 0;
                   1309: }
                   1310: 
                   1311: 
                   1312: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1313: // setPowerState
                   1314: //
                   1315: // Called by the superclass to turn the frame buffer on and off.
                   1316: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1317: IOReturn IONDRVFramebuffer::setPowerState( unsigned long powerStateOrdinal,
                   1318:                                                IOService* whatDevice )
                   1319: {
                   1320:     if ( powerStateOrdinal == 0 ) {
                   1321:         kprintf("frame buffer would be powered off here\n");
                   1322:     }
                   1323:     if ( powerStateOrdinal == 1 ) {
                   1324:         kprintf("frame buffer would be powered on here\n");
                   1325:     }
                   1326:     return IOPMAckImplied;
                   1327: }
                   1328: 
                   1329: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1330: 
                   1331: // ATI patches.
                   1332: // Real problem : getStartupMode doesn't.
                   1333: 
                   1334: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1335: 
                   1336: #undef super
                   1337: #define super IONDRVFramebuffer
                   1338: 
                   1339: OSDefineMetaClassAndStructors(IOATINDRV, IONDRVFramebuffer)
                   1340: OSDefineMetaClassAndStructors(IOATI128NDRV, IOATINDRV)
                   1341: 
                   1342: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1343: 
                   1344: IOReturn IOATINDRV::getStartupDisplayMode(
                   1345:                                IODisplayModeID * displayMode, IOIndex * depth )
                   1346: {
                   1347:     UInt16 *           nvram;
                   1348:     OSData *           prop;
                   1349: 
                   1350:     prop = OSDynamicCast( OSData, nub->getProperty("Sime"));
                   1351:     if( prop) {
                   1352:        nvram = (UInt16 *) prop->getBytesNoCopy();
                   1353:        *displayMode = nvram[ 0 ];      // 1 is physDisplayMode
                   1354:        *depth = nvram[ 2 ] - kDepthMode1;
                   1355:         return( kIOReturnSuccess);
                   1356:     } else
                   1357:         return(super::getStartupDisplayMode( displayMode, depth));
                   1358: }
                   1359: 
                   1360: IODeviceMemory * IOATINDRV::findVRAM( void )
                   1361: {
                   1362:     OSData *           prop;
                   1363:     IOPhysicalAddress  vramBase;
                   1364:     IOByteCount                vramLength;
                   1365: 
                   1366:     prop = OSDynamicCast( OSData, nub->getProperty("APPL,VRAMSize"));
                   1367:     if( !prop)
                   1368:        prop = OSDynamicCast( OSData, nub->getProperty("ATY,memsize"));
                   1369:     if( !prop)
                   1370:        return( super::findVRAM());
                   1371: 
                   1372:     vramBase = physicalFramebuffer;
                   1373:     vramLength = *((IOByteCount *)prop->getBytesNoCopy());
                   1374:     if( !vramLength)
                   1375:         return( super::findVRAM());
                   1376:     vramLength = (vramLength + (vramBase & 0xffff)) & 0xffff0000;
                   1377:     vramBase &= 0xffff0000;
                   1378: 
                   1379:     return( makeSubRange( vramBase, vramLength ));
                   1380: }
                   1381: 
                   1382: static int g128ExtraCurs = 8;
                   1383: static int g128DeltaCurs = 0x25c0;
                   1384: 
                   1385: void IOATI128NDRV::flushCursor( void )
                   1386: {
                   1387:     volatile UInt32 *  fb;
                   1388:     UInt32             x;
                   1389:     int                        i;
                   1390: 
                   1391:     fb = (volatile UInt32 *) frameBuffer;
                   1392:     for( i = 0; i < g128ExtraCurs; i++) {
                   1393:        x += *(fb++);
                   1394:        fb += g128DeltaCurs;
                   1395:     }
                   1396: }
                   1397: 
                   1398: 
                   1399:     

unix.superglobalmegacorp.com

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