|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.