]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/pci/drvApplePCI/AppleMacRiscPCI.cpp
01a1a65ba3de52078769e0a9d4ded3135498a4ee
[apple/xnu.git] / iokit / Drivers / pci / drvApplePCI / AppleMacRiscPCI.cpp
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) 1998 Apple Computer, Inc. All rights reserved.
24 *
25 * HISTORY
26 * 23 Nov 98 sdouglas created from objc version.
27 * 05 Nov 99 sdouglas added UniNorth AGP based on UniNorthAGPDriver.c
28 * by Fernando Urbina, Kent Miller.
29 *
30 */
31
32 #include <IOKit/system.h>
33 #include <ppc/proc_reg.h>
34
35 #include <libkern/c++/OSContainers.h>
36 #include <libkern/OSByteOrder.h>
37
38 #include <IOKit/IODeviceMemory.h>
39 #include <IOKit/IORangeAllocator.h>
40 #include <IOKit/IODeviceTreeSupport.h>
41 #include <IOKit/IOPlatformExpert.h>
42 #include <IOKit/IOLib.h>
43 #include <IOKit/assert.h>
44
45 #include "AppleMacRiscPCI.h"
46
47 #define ALLOC_AGP_RANGE 0
48
49 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
50
51 #define super IOPCIBridge
52
53 OSDefineMetaClassAndStructors(AppleMacRiscPCI, IOPCIBridge)
54
55 OSDefineMetaClassAndStructors(AppleMacRiscVCI, AppleMacRiscPCI)
56
57 OSDefineMetaClassAndStructors(AppleMacRiscAGP, AppleMacRiscPCI)
58
59 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
60
61 bool AppleMacRiscPCI::start( IOService * provider )
62 {
63 IOPCIPhysicalAddress ioAddrCell;
64 IOPhysicalAddress ioPhys;
65 IOPhysicalAddress ioPhysLen;
66 OSArray * array;
67 IODeviceMemory::InitElement rangeList[ 3 ];
68 IORegistryEntry * bridge;
69 OSData * busProp;
70
71 if( !IODTMatchNubWithKeys(provider, "('pci', 'vci')"))
72 return( false);
73
74 if( IODTMatchNubWithKeys(provider, "'uni-north'"))
75 configDataOffsetMask = 0x7;
76 else
77 configDataOffsetMask = 0x3;
78
79 if( 0 == (lock = IOSimpleLockAlloc()))
80 return( false );
81
82 ioAddrCell.physHi.bits = 0;
83 ioAddrCell.physHi.s.space = kIOPCIIOSpace;
84 ioAddrCell.physMid = 0;
85 ioAddrCell.physLo = 0;
86 ioAddrCell.lengthHi = 0;
87 ioAddrCell.lengthLo = 0x10000;
88
89 bridge = provider;
90
91 if( ! IODTResolveAddressCell( bridge, (UInt32 *) &ioAddrCell,
92 &ioPhys, &ioPhysLen) ) {
93
94 IOLog("%s: couldn't find my base\n", getName());
95 return( false);
96 }
97
98 /* define more explicit ranges */
99
100 rangeList[0].start = ioPhys;
101 rangeList[0].length = ioPhysLen;
102 rangeList[1].start = ioPhys + 0x00800000;
103 rangeList[1].length = 4;
104 rangeList[2].start = ioPhys + 0x00c00000;
105 rangeList[2].length = 4;
106
107 IORangeAllocator * platformRanges;
108 platformRanges = IOService::getPlatform()->getPhysicalRangeAllocator();
109 assert( platformRanges );
110 platformRanges->allocateRange( ioPhys, 0x01000000 );
111
112 array = IODeviceMemory::arrayFromList( rangeList, 3 );
113 if( !array)
114 return( false);
115
116 provider->setDeviceMemory( array );
117 array->release();
118 ioMemory = (IODeviceMemory *) array->getObject( 0 );
119
120 /* map registers */
121
122 if( (configAddrMap = provider->mapDeviceMemoryWithIndex( 1 )))
123 configAddr = (volatile UInt32 *) configAddrMap->getVirtualAddress();
124 if( (configDataMap = provider->mapDeviceMemoryWithIndex( 2 )))
125 configData = (volatile UInt8 *) configDataMap->getVirtualAddress();
126
127 if( !configAddr || !configData)
128 return( false);
129
130 busProp = (OSData *) bridge->getProperty("bus-range");
131 if( busProp)
132 primaryBus = *((UInt32 *) busProp->getBytesNoCopy());
133
134 return( super::start( provider));
135 }
136
137 bool AppleMacRiscPCI::configure( IOService * provider )
138 {
139 UInt32 addressSelects;
140 UInt32 index;
141 bool ok;
142
143 addressSelects = configRead32( getBridgeSpace(), kMacRISCAddressSelect );
144
145 coarseAddressMask = addressSelects >> 16;
146 fineAddressMask = addressSelects & 0xffff;
147
148 for( index = 0; index < 15; index++ ) {
149 if( coarseAddressMask & (1 << index)) {
150 ok = addBridgeMemoryRange( index << 28, 0x10000000, true );
151 }
152 }
153
154 // if( coarseAddressMask & (1 << 15)) // F segment
155 for( index = 0; index < 15; index++ ) {
156 if( fineAddressMask & (1 << index)) {
157 ok = addBridgeMemoryRange( (0xf0 | index) << 24,
158 0x01000000, true );
159 }
160 }
161
162 ok = addBridgeIORange( 0, 0x10000 );
163
164 return( super::configure( provider));
165 }
166
167 void AppleMacRiscPCI::free()
168 {
169 if( configAddrMap)
170 configAddrMap->release();
171 if( configDataMap)
172 configDataMap->release();
173 if( lock)
174 IOSimpleLockFree( lock);
175
176 super::free();
177 }
178
179 IODeviceMemory * AppleMacRiscPCI::ioDeviceMemory( void )
180 {
181 return( ioMemory);
182 }
183
184 IODeviceMemory * AppleMacRiscVCI::ioDeviceMemory( void )
185 {
186 return( 0 );
187 }
188
189 bool AppleMacRiscVCI::configure( IOService * provider )
190 {
191 addBridgeMemoryRange( 0x90000000, 0x10000000, true );
192
193 return( AppleMacRiscPCI::configure( provider));
194 }
195
196 UInt8 AppleMacRiscPCI::firstBusNum( void )
197 {
198 return( primaryBus );
199 }
200
201 UInt8 AppleMacRiscPCI::lastBusNum( void )
202 {
203 return( firstBusNum() );
204 }
205
206 IOPCIAddressSpace AppleMacRiscPCI::getBridgeSpace( void )
207 {
208 IOPCIAddressSpace space;
209
210 space.bits = 0;
211 space.s.busNum = primaryBus;
212 space.s.deviceNum = kBridgeSelfDevice;
213
214 return( space );
215 }
216
217 inline bool AppleMacRiscPCI::setConfigSpace( IOPCIAddressSpace space,
218 UInt8 offset )
219 {
220 UInt32 addrCycle;
221
222 offset &= 0xfc;
223 if( space.s.busNum == primaryBus) {
224
225 if( space.s.deviceNum < kBridgeSelfDevice)
226 return( false);
227
228 // primary config cycle
229 addrCycle = ( (1 << space.s.deviceNum)
230 | (space.s.functionNum << 8)
231 | offset );
232
233 } else {
234 // pass thru config cycle
235 addrCycle = ( (space.bits)
236 | offset
237 | 1 );
238 }
239
240 do {
241 OSWriteSwapInt32( configAddr, 0, addrCycle);
242 eieio();
243 } while( addrCycle != OSReadSwapInt32( configAddr, 0 ));
244 eieio();
245
246 return( true );
247 }
248
249
250 UInt32 AppleMacRiscPCI::configRead32( IOPCIAddressSpace space,
251 UInt8 offset )
252 {
253 UInt32 data;
254 IOInterruptState ints;
255
256 ints = IOSimpleLockLockDisableInterrupt( lock );
257
258 if( setConfigSpace( space, offset )) {
259
260 offset = offset & configDataOffsetMask & 4;
261
262 data = OSReadSwapInt32( configData, offset );
263 eieio();
264
265 } else
266 data = 0xffffffff;
267
268 IOSimpleLockUnlockEnableInterrupt( lock, ints );
269
270 return( data );
271 }
272
273 void AppleMacRiscPCI::configWrite32( IOPCIAddressSpace space,
274 UInt8 offset, UInt32 data )
275 {
276 IOInterruptState ints;
277
278 ints = IOSimpleLockLockDisableInterrupt( lock );
279
280 if( setConfigSpace( space, offset )) {
281
282 offset = offset & configDataOffsetMask & 4;
283
284 OSWriteSwapInt32( configData, offset, data );
285 eieio();
286 /* read to sync */
287 (void) OSReadSwapInt32( configData, offset );
288 eieio();
289 sync();
290 isync();
291 }
292
293 IOSimpleLockUnlockEnableInterrupt( lock, ints );
294 }
295
296 UInt16 AppleMacRiscPCI::configRead16( IOPCIAddressSpace space,
297 UInt8 offset )
298 {
299 UInt16 data;
300 IOInterruptState ints;
301
302 ints = IOSimpleLockLockDisableInterrupt( lock );
303
304 if( setConfigSpace( space, offset )) {
305
306 offset = offset & configDataOffsetMask & 6;
307
308 data = OSReadSwapInt16( configData, offset );
309 eieio();
310
311 } else
312 data = 0xffff;
313
314 IOSimpleLockUnlockEnableInterrupt( lock, ints );
315
316 return( data );
317 }
318
319 void AppleMacRiscPCI::configWrite16( IOPCIAddressSpace space,
320 UInt8 offset, UInt16 data )
321 {
322 IOInterruptState ints;
323
324 ints = IOSimpleLockLockDisableInterrupt( lock );
325
326 if( setConfigSpace( space, offset )) {
327
328 offset = offset & configDataOffsetMask & 6;
329
330 OSWriteSwapInt16( configData, offset, data );
331 eieio();
332 /* read to sync */
333 (void) OSReadSwapInt16( configData, offset );
334 eieio();
335 sync();
336 isync();
337 }
338
339 IOSimpleLockUnlockEnableInterrupt( lock, ints );
340 }
341
342 UInt8 AppleMacRiscPCI::configRead8( IOPCIAddressSpace space,
343 UInt8 offset )
344 {
345 UInt16 data;
346 IOInterruptState ints;
347
348 ints = IOSimpleLockLockDisableInterrupt( lock );
349
350 if( setConfigSpace( space, offset )) {
351
352 offset = offset & configDataOffsetMask;
353
354 data = configData[ offset ];
355 eieio();
356
357 } else
358 data = 0xff;
359
360 IOSimpleLockUnlockEnableInterrupt( lock, ints );
361
362 return( data );
363 }
364
365 void AppleMacRiscPCI::configWrite8( IOPCIAddressSpace space,
366 UInt8 offset, UInt8 data )
367 {
368 IOInterruptState ints;
369
370 ints = IOSimpleLockLockDisableInterrupt( lock );
371
372 if( setConfigSpace( space, offset )) {
373
374 offset = offset & configDataOffsetMask;
375
376 configData[ offset ] = data;
377 eieio();
378 /* read to sync */
379 data = configData[ offset ];
380 eieio();
381 sync();
382 isync();
383 }
384
385 IOSimpleLockUnlockEnableInterrupt( lock, ints );
386 }
387
388 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
389
390 #undef super
391 #define super AppleMacRiscPCI
392
393 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
394
395 bool AppleMacRiscAGP::configure( IOService * provider )
396 {
397 if( !findPCICapability( getBridgeSpace(), kIOPCIAGPCapability, &targetAGPRegisters ))
398 return( false );
399
400 return( super::configure( provider));
401 }
402
403 IOPCIDevice * AppleMacRiscAGP::createNub( OSDictionary * from )
404 {
405 IOPCIDevice * nub;
406 IOPCIAddressSpace space;
407 bool isAGP;
408 UInt8 masterAGPRegisters;
409
410 spaceFromProperties( from, &space);
411
412 isAGP = ( (space.s.deviceNum != getBridgeSpace().s.deviceNum)
413 && findPCICapability( space, kIOPCIAGPCapability, &masterAGPRegisters ));
414
415 if( isAGP) {
416 nub = new IOAGPDevice;
417 if( nub)
418 ((IOAGPDevice *)nub)->masterAGPRegisters = masterAGPRegisters;
419 from->setObject( kIOAGPBusFlagsKey, getProperty(kIOAGPBusFlagsKey));
420 } else
421 nub = super::createNub( from );
422
423 return( nub );
424 }
425
426 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
427
428 IOReturn AppleMacRiscAGP::createAGPSpace( IOAGPDevice * master,
429 IOOptionBits options,
430 IOPhysicalAddress * address,
431 IOPhysicalLength * length )
432 {
433 IOReturn err;
434 IOPCIAddressSpace target = getBridgeSpace();
435 IOPhysicalLength agpLength;
436 IOPhysicalAddress gartPhys;
437
438 enum { agpSpacePerPage = 4 * 1024 * 1024 };
439 enum { agpBytesPerGartByte = 1024 };
440 enum { alignLen = 4 * 1024 * 1024 - 1 };
441
442 destroyAGPSpace( master );
443
444 agpLength = *length;
445 if( !agpLength)
446 agpLength = 32 * 1024 * 1024;
447
448 agpLength = (agpLength + alignLen) & ~alignLen;
449
450 err = kIOReturnVMError;
451 do {
452
453 gartLength = agpLength / agpBytesPerGartByte;
454 gartArray = (volatile UInt32 *) IOMallocContiguous(
455 gartLength, 4096, &gartPhys );
456 if( !gartArray)
457 continue;
458 // IOMapPages( kernel_map, gartArray, gartPhys, gartLength, kIOMapInhibitCache );
459 bzero( (void *) gartArray, gartLength);
460
461 #if ALLOC_AGP_RANGE
462 IORangeAllocator * platformRanges
463 = getPlatform()->getPhysicalRangeAllocator();
464 for( agpBaseIndex = 0xf; agpBaseIndex > 0; agpBaseIndex--) {
465 systemBase = agpBaseIndex * 0x10000000;
466 if( platformRanges->allocateRange( systemBase, agpLength )) {
467 systemLength = agpLength;
468 break;
469 }
470 }
471 #else
472 agpBaseIndex = 0;
473 systemBase = 0;
474 systemLength = agpLength;
475 #endif
476 if( !systemLength)
477 continue;
478
479 agpRange = IORangeAllocator::withRange( agpLength, 4096 );
480 if( !agpRange)
481 continue;
482
483 *address = systemBase;
484 *length = systemLength;
485 #if 0
486 coarseAddressMask |= (1 << agpBaseIndex);
487 configWrite32( target, kMacRISCAddressSelect,
488 (coarseAddressMask << 16) | fineAddressMask );
489 #endif
490 configWrite32( target, kUniNAGP_BASE, agpBaseIndex << 28 );
491
492 assert( 0 == (gartPhys & 0xfff));
493 configWrite32( target, kUniNGART_BASE,
494 gartPhys | (agpLength / agpSpacePerPage));
495
496 err = kIOReturnSuccess;
497
498 } while( false );
499
500 if( kIOReturnSuccess == err)
501 setAGPEnable( master, true, 0 );
502 else
503 destroyAGPSpace( master );
504
505 return( err );
506 }
507
508 IOReturn AppleMacRiscAGP::getAGPSpace( IOAGPDevice * master,
509 IOPhysicalAddress * address,
510 IOPhysicalLength * length )
511 {
512 if( systemLength) {
513
514 if( address)
515 *address = systemBase;
516 if( length)
517 *length = systemLength;
518 return( kIOReturnSuccess );
519
520 } else
521 return( kIOReturnNotReady );
522 }
523
524 IOReturn AppleMacRiscAGP::destroyAGPSpace( IOAGPDevice * master )
525 {
526
527 setAGPEnable( master, false, 0 );
528
529 if( gartArray) {
530 IOFreeContiguous( (void *) gartArray, gartLength);
531 gartArray = 0;
532 }
533 if( agpRange) {
534 agpRange->release();
535 agpRange = 0;
536 }
537 if( systemLength) {
538 #if ALLOC_AGP_RANGE
539 IORangeAllocator * platformRanges
540 = getPlatform()->getPhysicalRangeAllocator();
541 platformRanges->deallocate( systemBase, systemLength);
542 #endif
543 systemLength = 0;
544 }
545
546 return( kIOReturnSuccess );
547 }
548
549 IORangeAllocator * AppleMacRiscAGP::getAGPRangeAllocator(
550 IOAGPDevice * master )
551 {
552 // if( agpRange) agpRange->retain();
553 return( agpRange );
554 }
555
556 IOOptionBits AppleMacRiscAGP::getAGPStatus( IOAGPDevice * master,
557 IOOptionBits options = 0 )
558 {
559 IOPCIAddressSpace target = getBridgeSpace();
560
561 return( configRead32( target, kUniNINTERNAL_STATUS ) );
562 }
563
564 IOReturn AppleMacRiscAGP::resetAGPDevice( IOAGPDevice * master,
565 IOOptionBits options = 0 )
566 {
567 IOReturn ret;
568
569 if( master->masterState & kIOAGPStateEnablePending) {
570 ret = setAGPEnable( master, true, 0 );
571 master->masterState &= ~kIOAGPStateEnablePending;
572 } else
573 ret = kIOReturnSuccess;
574
575 return( ret );
576 }
577
578 IOReturn AppleMacRiscAGP::commitAGPMemory( IOAGPDevice * master,
579 IOMemoryDescriptor * memory,
580 IOByteCount agpOffset,
581 IOOptionBits options = 0 )
582 {
583 IOPCIAddressSpace target = getBridgeSpace();
584 IOReturn err = kIOReturnSuccess;
585 UInt32 offset = 0;
586 IOPhysicalAddress physAddr;
587 IOByteCount len;
588
589 // ok = agpRange->allocate( memory->getLength(), &agpOffset );
590
591 assert( agpOffset < systemLength );
592 agpOffset /= (page_size / 4);
593 while( (physAddr = memory->getPhysicalSegment( offset, &len ))) {
594
595 offset += len;
596 len = (len + 0xfff) & ~0xfff;
597 while( len > 0) {
598 OSWriteLittleInt32( gartArray, agpOffset,
599 ((physAddr & ~0xfff) | 1));
600 agpOffset += 4;
601 physAddr += page_size;
602 len -= page_size;
603 }
604 }
605 #if 1
606 flush_dcache( (vm_offset_t) gartArray, gartLength, false);
607 len = OSReadLittleInt32( gartArray, agpOffset - 4 );
608 sync();
609 isync();
610 #endif
611
612 if( kIOAGPGartInvalidate & options) {
613 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV );
614 configWrite32( target, kUniNGART_CTRL, kGART_EN );
615 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET);
616 configWrite32( target, kUniNGART_CTRL, kGART_EN );
617 }
618
619 return( err );
620 }
621
622 IOReturn AppleMacRiscAGP::releaseAGPMemory( IOAGPDevice * master,
623 IOMemoryDescriptor * memory,
624 IOByteCount agpOffset,
625 IOOptionBits options )
626 {
627 IOPCIAddressSpace target = getBridgeSpace();
628 IOReturn err = kIOReturnSuccess;
629 IOByteCount length;
630
631 if( !memory)
632 return( kIOReturnBadArgument );
633
634 length = memory->getLength();
635
636 if( (agpOffset + length) > systemLength)
637 return( kIOReturnBadArgument );
638
639 // agpRange->deallocate( agpOffset, length );
640
641 length = (length + 0xfff) & ~0xfff;
642 agpOffset /= page_size;
643 while( length > 0) {
644 gartArray[ agpOffset++ ] = 0;
645 length -= page_size;
646 }
647 #if 1
648 flush_dcache( (vm_offset_t) gartArray, gartLength, false);
649 length = OSReadLittleInt32( gartArray, 4 * (agpOffset - 1) );
650 sync();
651 isync();
652 #endif
653
654 if( kIOAGPGartInvalidate & options) {
655 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV );
656 configWrite32( target, kUniNGART_CTRL, kGART_EN );
657 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET);
658 configWrite32( target, kUniNGART_CTRL, kGART_EN );
659 }
660
661 return( err );
662 }
663
664 IOReturn AppleMacRiscAGP::setAGPEnable( IOAGPDevice * _master,
665 bool enable, IOOptionBits options )
666 {
667 IOReturn err = kIOReturnSuccess;
668 IOPCIAddressSpace target = getBridgeSpace();
669 IOPCIAddressSpace master = _master->space;
670 UInt32 command;
671 UInt32 targetStatus, masterStatus;
672 UInt8 masterAGPRegisters = _master->masterAGPRegisters;
673
674 if( enable) {
675
676 targetStatus = configRead32( target,
677 targetAGPRegisters + kIOPCIConfigAGPStatusOffset );
678 masterStatus = configRead32( master,
679 masterAGPRegisters + kIOPCIConfigAGPStatusOffset );
680
681 command = kIOAGPSideBandAddresssing
682 | kIOAGP4xDataRate | kIOAGP2xDataRate | kIOAGP1xDataRate;
683 command &= targetStatus;
684 command &= masterStatus;
685
686 if( command & kIOAGP4xDataRate)
687 command &= ~(kIOAGP2xDataRate | kIOAGP1xDataRate);
688 else if( command & kIOAGP2xDataRate)
689 command &= ~(kIOAGP1xDataRate);
690 else if( 0 == (command & kIOAGP1xDataRate))
691 return( kIOReturnUnsupported );
692
693 command |= kIOAGPEnable;
694
695 if( targetStatus > masterStatus)
696 targetStatus = masterStatus;
697 command |= (targetStatus & kIOAGPRequestQueueMask);
698
699 #if 1
700 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV );
701 configWrite32( target, kUniNGART_CTRL, kGART_EN );
702 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET);
703 configWrite32( target, kUniNGART_CTRL, kGART_EN );
704 #endif
705 do {
706 configWrite32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset, command );
707 } while( (command & kIOAGPEnable) !=
708 (kIOAGPEnable & configRead32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset)));
709
710 do {
711 configWrite32( master,
712 masterAGPRegisters + kIOPCIConfigAGPCommandOffset, command );
713 } while( (command & kIOAGPEnable) !=
714 (kIOAGPEnable & configRead32( master,
715 masterAGPRegisters + kIOPCIConfigAGPCommandOffset)));
716
717 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV );
718 configWrite32( target, kUniNGART_CTRL, kGART_EN );
719 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_2xRESET);
720 configWrite32( target, kUniNGART_CTRL, kGART_EN );
721
722 _master->masterState |= kIOAGPStateEnabled;
723
724 } else {
725
726 while( 0 == (kIOAGPIdle & configRead32( getBridgeSpace(),
727 kUniNINTERNAL_STATUS )))
728 {}
729
730 configWrite32( master, masterAGPRegisters + kIOPCIConfigAGPCommandOffset, 0 );
731 configWrite32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset, 0 );
732 #if 0
733 configWrite32( target, kUniNGART_CTRL, kGART_EN | kGART_INV );
734 configWrite32( target, kUniNGART_CTRL, 0 );
735 configWrite32( target, kUniNGART_CTRL, kGART_2xRESET);
736 configWrite32( target, kUniNGART_CTRL, 0 );
737 #endif
738 _master->masterState &= ~kIOAGPStateEnabled;
739 }
740
741 return( err );
742 }
743
744 IOReturn AppleMacRiscAGP::saveDeviceState( IOPCIDevice * device,
745 IOOptionBits options = 0 )
746 {
747 IOReturn ret;
748 IOAGPDevice * agpDev;
749 UInt32 agpSave[3];
750 IOPCIAddressSpace target = getBridgeSpace();
751
752 if( (agpDev = OSDynamicCast( IOAGPDevice, device))) {
753 agpSave[0] = configRead32( target, kUniNAGP_BASE );
754 agpSave[1] = configRead32( target, kUniNGART_BASE );
755 agpSave[2] = configRead32( target, targetAGPRegisters + kIOPCIConfigAGPCommandOffset );
756 setAGPEnable( agpDev, false, 0 );
757 }
758
759 ret = super::saveDeviceState( device, options);
760
761 if( agpDev && (ret == kIOReturnSuccess)) {
762 agpDev->savedConfig[ kUniNAGP_BASE / 4 ] = agpSave[0];
763 agpDev->savedConfig[ kUniNGART_BASE / 4 ] = agpSave[1];
764 agpDev->savedConfig[ (targetAGPRegisters + kIOPCIConfigAGPCommandOffset) / 4 ] = agpSave[2];
765 }
766
767 return( ret );
768 }
769
770 IOReturn AppleMacRiscAGP::restoreDeviceState( IOPCIDevice * device,
771 IOOptionBits options = 0 )
772 {
773 IOReturn ret;
774 IOAGPDevice * agpDev;
775 UInt32 agpSave[3];
776 IOPCIAddressSpace target = getBridgeSpace();
777
778 agpDev = OSDynamicCast( IOAGPDevice, device);
779 if( agpDev && device->savedConfig) {
780 agpSave[0] = agpDev->savedConfig[ kUniNAGP_BASE / 4 ];
781 agpSave[1] = agpDev->savedConfig[ kUniNGART_BASE / 4 ];
782 agpSave[2] = agpDev->savedConfig[ (targetAGPRegisters + kIOPCIConfigAGPCommandOffset) / 4 ];
783 }
784
785 ret = super::restoreDeviceState( device, options);
786
787 if( agpDev && (kIOReturnSuccess == ret)) {
788 configWrite32( target, kUniNAGP_BASE, agpSave[0] );
789 configWrite32( target, kUniNGART_BASE, agpSave[1] );
790 // soon, grasshopper
791 if( kIOAGPEnable & agpSave[2])
792 agpDev->masterState |= kIOAGPStateEnablePending;
793 else
794 agpDev->masterState &= ~kIOAGPStateEnablePending;
795 }
796
797 return( ret );
798 }
799
800 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */