1 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_dri.c,v 1.28 2003/02/08 21:26:58 dawes Exp $ */
4 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES
22 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keith@tungstengraphics.com>
28 * Gareth Hughes <gareth@valinux.com>
42 #include "mga_macros.h"
44 #include "mga_sarea.h"
47 /* Quiescence, locking
49 #define MGA_TIMEOUT 2048
51 static void MGAWaitForIdleDMA( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
57 memset( &lock
, 0, sizeof(drmMGALock
) );
61 /* first ask for quiescent and flush */
62 lock
.flags
= DRM_MGA_LOCK_QUIESCENT
| DRM_MGA_LOCK_FLUSH
;
64 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_FLUSH
,
65 &lock
, sizeof( drmMGALock
) );
66 } while ( ret
== -EBUSY
&& i
++ < DRM_MGA_IDLE_RETRY
);
68 /* if it's still busy just try quiescent */
69 if ( ret
== -EBUSY
) {
70 lock
.flags
= DRM_MGA_LOCK_QUIESCENT
;
72 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_FLUSH
,
73 &lock
, sizeof( drmMGALock
) );
74 } while ( ret
== -EBUSY
&& i
++ < DRM_MGA_IDLE_RETRY
);
76 } while ( ( ret
== -EBUSY
) && ( i
++ < MGA_TIMEOUT
) );
82 "[dri] Idle timed out, resetting engine...\n" );
84 drmCommandNone( ctx
->drmFD
, DRM_MGA_RESET
);
88 static unsigned int mylog2( unsigned int n
)
90 unsigned int log2
= 1;
91 while ( n
> 1 ) n
>>= 1, log2
++;
95 static int MGADRIAgpInit(struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
98 unsigned int vendor
, device
;
101 if(pMga
->agpSize
< 12)pMga
->agpSize
= 12;
102 if(pMga
->agpSize
> 64)pMga
->agpSize
= 64; /* cap */
104 /* FIXME: Make these configurable...
106 pMga
->agp
.size
= pMga
->agpSize
* 1024 * 1024;
108 pMga
->warp
.offset
= 0;
109 pMga
->warp
.size
= MGA_WARP_UCODE_SIZE
;
111 pMga
->primary
.offset
= (pMga
->warp
.offset
+
113 pMga
->primary
.size
= 1024 * 1024;
115 pMga
->buffers
.offset
= (pMga
->primary
.offset
+
117 pMga
->buffers
.size
= MGA_NUM_BUFFERS
* MGA_BUFFER_SIZE
;
120 pMga
->agpTextures
.offset
= (pMga
->buffers
.offset
+
123 pMga
->agpTextures
.size
= pMga
->agp
.size
-
124 pMga
->agpTextures
.offset
;
126 if ( drmAgpAcquire( ctx
->drmFD
) < 0 ) {
127 fprintf( stderr
, "[agp] AGP not available\n" );
131 mode
= drmAgpGetMode( ctx
->drmFD
); /* Default mode */
132 vendor
= drmAgpVendorId( ctx
->drmFD
);
133 device
= drmAgpDeviceId( ctx
->drmFD
);
135 mode
&= ~MGA_AGP_MODE_MASK
;
136 switch ( pMga
->agpMode
) {
138 mode
|= MGA_AGP_4X_MODE
;
140 mode
|= MGA_AGP_2X_MODE
;
143 mode
|= MGA_AGP_1X_MODE
;
148 "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
149 mode
, vendor
, device
,
154 if ( drmAgpEnable( ctx
->drmFD
, mode
) < 0 ) {
155 fprintf( stderr
, "[agp] AGP not enabled\n" );
156 drmAgpRelease( ctx
->drmFD
);
160 if ( pMga
->Chipset
== PCI_CHIP_MGAG200
) {
161 switch ( pMga
->agpMode
) {
164 "[drm] Enabling AGP 2x PLL encoding\n" );
165 OUTREG( MGAREG_AGP_PLL
, MGA_AGP2XPLL_ENABLE
);
171 "[drm] Disabling AGP 2x PLL encoding\n" );
172 OUTREG( MGAREG_AGP_PLL
, MGA_AGP2XPLL_DISABLE
);
178 ret
= drmAgpAlloc( ctx
->drmFD
, pMga
->agp
.size
,
179 0, NULL
, &pMga
->agp
.handle
);
181 fprintf( stderr
, "[agp] Out of memory (%d)\n", ret
);
182 drmAgpRelease( ctx
->drmFD
);
186 "[agp] %d kB allocated with handle 0x%08x\n",
187 pMga
->agp
.size
/1024, (unsigned int)pMga
->agp
.handle
);
189 if ( drmAgpBind( ctx
->drmFD
, pMga
->agp
.handle
, 0 ) < 0 ) {
190 fprintf( stderr
, "[agp] Could not bind memory\n" );
191 drmAgpFree( ctx
->drmFD
, pMga
->agp
.handle
);
192 drmAgpRelease( ctx
->drmFD
);
196 /* WARP microcode space
198 if ( drmAddMap( ctx
->drmFD
,
201 DRM_AGP
, DRM_READ_ONLY
,
202 &pMga
->warp
.handle
) < 0 ) {
204 "[agp] Could not add WARP microcode mapping\n" );
208 "[agp] WARP microcode handle = 0x%08lx\n",
211 if ( drmMap( ctx
->drmFD
,
214 &pMga
->warp
.map
) < 0 ) {
216 "[agp] Could not map WARP microcode\n" );
220 "[agp] WARP microcode mapped at 0x%08lx\n",
221 (unsigned long)pMga
->warp
.map
);
225 if ( drmAddMap( ctx
->drmFD
,
226 pMga
->primary
.offset
,
228 DRM_AGP
, DRM_READ_ONLY
,
229 &pMga
->primary
.handle
) < 0 ) {
231 "[agp] Could not add primary DMA mapping\n" );
235 "[agp] Primary DMA handle = 0x%08lx\n",
236 pMga
->primary
.handle
);
238 if ( drmMap( ctx
->drmFD
,
239 pMga
->primary
.handle
,
241 &pMga
->primary
.map
) < 0 ) {
243 "[agp] Could not map primary DMA\n" );
247 "[agp] Primary DMA mapped at 0x%08lx\n",
248 (unsigned long)pMga
->primary
.map
);
252 if ( drmAddMap( ctx
->drmFD
,
253 pMga
->buffers
.offset
,
256 &pMga
->buffers
.handle
) < 0 ) {
258 "[agp] Could not add DMA buffers mapping\n" );
262 "[agp] DMA buffers handle = 0x%08lx\n",
263 pMga
->buffers
.handle
);
265 if ( drmMap( ctx
->drmFD
,
266 pMga
->buffers
.handle
,
268 &pMga
->buffers
.map
) < 0 ) {
270 "[agp] Could not map DMA buffers\n" );
274 "[agp] DMA buffers mapped at 0x%08lx\n",
275 (unsigned long)pMga
->buffers
.map
);
277 count
= drmAddBufs( ctx
->drmFD
,
278 MGA_NUM_BUFFERS
, MGA_BUFFER_SIZE
,
279 DRM_AGP_BUFFER
, pMga
->buffers
.offset
);
282 "[drm] failure adding %d %d byte DMA buffers\n",
283 MGA_NUM_BUFFERS
, MGA_BUFFER_SIZE
);
287 "[drm] Added %d %d byte DMA buffers\n",
288 count
, MGA_BUFFER_SIZE
);
290 i
= mylog2(pMga
->agpTextures
.size
/ MGA_NR_TEX_REGIONS
);
291 if(i
< MGA_LOG_MIN_TEX_REGION_SIZE
)
292 i
= MGA_LOG_MIN_TEX_REGION_SIZE
;
293 pMga
->agpTextures
.size
= (pMga
->agpTextures
.size
>> i
) << i
;
295 if ( drmAddMap( ctx
->drmFD
,
296 pMga
->agpTextures
.offset
,
297 pMga
->agpTextures
.size
,
299 &pMga
->agpTextures
.handle
) < 0 ) {
301 "[agp] Could not add agpTexture mapping\n" );
304 /* should i map it ? */
306 "[agp] agpTexture handle = 0x%08lx\n",
307 pMga
->agpTextures
.handle
);
309 "[agp] agpTexture size: %d kb\n", pMga
->agpTextures
.size
/1024 );
314 static int MGADRIMapInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
316 pMga
->registers
.size
= MGAIOMAPSIZE
;
318 if ( drmAddMap( ctx
->drmFD
,
319 (drmHandle
)pMga
->IOAddress
,
320 pMga
->registers
.size
,
321 DRM_REGISTERS
, DRM_READ_ONLY
,
322 &pMga
->registers
.handle
) < 0 ) {
324 "[drm] Could not add MMIO registers mapping\n" );
328 "[drm] Registers handle = 0x%08lx\n",
329 pMga
->registers
.handle
);
331 pMga
->status
.size
= SAREA_MAX
;
333 if ( drmAddMap( ctx
->drmFD
, 0, pMga
->status
.size
,
334 DRM_SHM
, DRM_READ_ONLY
| DRM_LOCKED
| DRM_KERNEL
,
335 &pMga
->status
.handle
) < 0 ) {
337 "[drm] Could not add status page mapping\n" );
341 "[drm] Status handle = 0x%08lx\n",
342 pMga
->status
.handle
);
344 if ( drmMap( ctx
->drmFD
,
347 &pMga
->status
.map
) < 0 ) {
349 "[agp] Could not map status page\n" );
353 "[agp] Status page mapped at 0x%08lx\n",
354 (unsigned long)pMga
->status
.map
);
359 static int MGADRIKernelInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
364 memset( &init
, 0, sizeof(drmMGAInit
) );
366 init
.func
= MGA_INIT_DMA
;
367 init
.sarea_priv_offset
= sizeof(drm_sarea_t
);
369 switch ( pMga
->Chipset
) {
370 case PCI_CHIP_MGAG550
:
371 case PCI_CHIP_MGAG400
:
372 init
.chipset
= MGA_CARD_TYPE_G400
;
374 case PCI_CHIP_MGAG200
:
375 case PCI_CHIP_MGAG200_PCI
:
376 init
.chipset
= MGA_CARD_TYPE_G200
;
382 init
.sgram
= 0; /* FIXME !pMga->HasSDRAM; */
388 init
.maccess
= MGA_MACCESS_PW16
;
391 init
.maccess
= MGA_MACCESS_PW32
;
394 fprintf( stderr
, "[mga] invalid bpp (%d)\n", ctx
->bpp
);
399 init
.fb_cpp
= ctx
->bpp
/ 8;
400 init
.front_offset
= pMga
->frontOffset
;
401 init
.front_pitch
= pMga
->frontPitch
/ init
.fb_cpp
;
402 init
.back_offset
= pMga
->backOffset
;
403 init
.back_pitch
= pMga
->backPitch
/ init
.fb_cpp
;
405 init
.depth_cpp
= ctx
->bpp
/ 8;
406 init
.depth_offset
= pMga
->depthOffset
;
407 init
.depth_pitch
= pMga
->depthPitch
/ init
.depth_cpp
;
409 init
.texture_offset
[0] = pMga
->textureOffset
;
410 init
.texture_size
[0] = pMga
->textureSize
;
412 init
.fb_offset
= ctx
->shared
.hFrameBuffer
;
413 init
.mmio_offset
= pMga
->registers
.handle
;
414 init
.status_offset
= pMga
->status
.handle
;
416 init
.warp_offset
= pMga
->warp
.handle
;
417 init
.primary_offset
= pMga
->primary
.handle
;
418 init
.buffers_offset
= pMga
->buffers
.handle
;
420 init
.texture_offset
[1] = pMga
->agpTextures
.handle
;
421 init
.texture_size
[1] = pMga
->agpTextures
.size
;
423 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_INIT
, &init
, sizeof(drmMGAInit
));
426 "[drm] Failed to initialize DMA! (%d)\n", ret
);
433 static void MGADRIIrqInit(struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
437 pMga
->irq
= drmGetInterruptFromBusID(ctx
->drmFD
,
442 fprintf(stderr
, "[drm] got IRQ %d\n", pMga
->irq
);
444 if((drmCtlInstHandler(ctx
->drmFD
, pMga
->irq
)) != 0)
447 "[drm] failure adding irq handler, "
448 "there is a device already using that irq\n"
449 "[drm] falling back to irq-free operation\n");
454 pMga
->reg_ien
= INREG( MGAREG_IEN
);
460 "[drm] dma control initialized, using IRQ %d\n",
464 static int MGADRIBuffersInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
466 pMga
->drmBuffers
= drmMapBufs( ctx
->drmFD
);
467 if ( !pMga
->drmBuffers
)
470 "[drm] Failed to map DMA buffers list\n" );
475 "[drm] Mapped %d DMA buffers\n",
476 pMga
->drmBuffers
->count
);
481 static int MGAMemoryInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
483 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
484 int bufferSize
= ((ctx
->shared
.virtualHeight
* width_bytes
486 & ~MGA_BUFFER_ALIGN
);
487 int depthSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
489 & ~MGA_BUFFER_ALIGN
);
492 pMga
->frontOffset
= 0;
493 pMga
->frontPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
496 "Using %d MB AGP aperture\n", pMga
->agpSize
);
498 "Using %d MB for vertex/indirect buffers\n", pMga
->buffers
.size
>>20);
500 "Using %d MB for AGP textures\n", pMga
->agpTextures
.size
>>20);
502 /* Front, back and depth buffers - everything else texture??
504 pMga
->textureSize
= ctx
->shared
.fbSize
- 2 * bufferSize
- depthSize
;
506 if (pMga
->textureSize
< 0)
509 l
= mylog2( pMga
->textureSize
/ MGA_NR_TEX_REGIONS
);
510 if ( l
< MGA_LOG_MIN_TEX_REGION_SIZE
)
511 l
= MGA_LOG_MIN_TEX_REGION_SIZE
;
513 /* Round the texture size up to the nearest whole number of
514 * texture regions. Again, be greedy about this, don't
517 pMga
->logTextureGranularity
= l
;
518 pMga
->textureSize
= (pMga
->textureSize
>> l
) << l
;
520 /* Set a minimum usable local texture heap size. This will fit
521 * two 256x256x32bpp textures.
523 if (pMga
->textureSize
< 512 * 1024) {
524 pMga
->textureOffset
= 0;
525 pMga
->textureSize
= 0;
528 /* Reserve space for textures */
529 pMga
->textureOffset
= ((ctx
->shared
.fbSize
- pMga
->textureSize
+
533 /* Reserve space for the shared depth
536 pMga
->depthOffset
= ((pMga
->textureOffset
- depthSize
+
539 pMga
->depthPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
541 pMga
->backOffset
= ((pMga
->depthOffset
- bufferSize
+
544 pMga
->backPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
548 "Will use back buffer at offset 0x%x\n",
551 "Will use depth buffer at offset 0x%x\n",
554 "Will use %d kb for textures at offset 0x%x\n",
555 pMga
->textureSize
/1024, pMga
->textureOffset
);
560 static int MGACheckDRMVersion( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
562 drmVersionPtr version
;
564 /* Check the MGA DRM version */
565 version
= drmGetVersion(ctx
->drmFD
);
567 if ( version
->version_major
!= 3 ||
568 version
->version_minor
< 0 ) {
569 /* incompatible drm version */
571 "[dri] MGADRIScreenInit failed because of a version mismatch.\n"
572 "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n"
573 "[dri] Disabling DRI.\n",
574 version
->version_major
,
575 version
->version_minor
,
576 version
->version_patchlevel
);
577 drmFreeVersion( version
);
580 drmFreeVersion( version
);
586 static void print_client_msg( MGADRIPtr pMGADRI
)
588 fprintf( stderr
, "chipset: %d\n", pMGADRI
->chipset
);
590 fprintf( stderr
, "width: %d\n", pMGADRI
->width
);
591 fprintf( stderr
, "height: %d\n", pMGADRI
->height
);
592 fprintf( stderr
, "mem: %d\n", pMGADRI
->mem
);
593 fprintf( stderr
, "cpp: %d\n", pMGADRI
->cpp
);
595 fprintf( stderr
, "agpMode: %d\n", pMGADRI
->agpMode
);
597 fprintf( stderr
, "frontOffset: %d\n", pMGADRI
->frontOffset
);
598 fprintf( stderr
, "frontPitch: %d\n", pMGADRI
->frontPitch
);
600 fprintf( stderr
, "backOffset: %d\n", pMGADRI
->backOffset
);
601 fprintf( stderr
, "backPitch: %d\n", pMGADRI
->backPitch
);
603 fprintf( stderr
, "depthOffset: %d\n", pMGADRI
->depthOffset
);
604 fprintf( stderr
, "depthPitch: %d\n", pMGADRI
->depthPitch
);
606 fprintf( stderr
, "textureOffset: %d\n", pMGADRI
->textureOffset
);
607 fprintf( stderr
, "textureSize: %d\n", pMGADRI
->textureSize
);
609 fprintf( stderr
, "logTextureGranularity: %d\n", pMGADRI
->logTextureGranularity
);
610 fprintf( stderr
, "logAgpTextureGranularity: %d\n", pMGADRI
->logAgpTextureGranularity
);
612 fprintf( stderr
, "agpTextureHandle: %u\n", (unsigned int)pMGADRI
->agpTextureOffset
);
613 fprintf( stderr
, "agpTextureSize: %u\n", (unsigned int)pMGADRI
->agpTextureSize
);
616 pMGADRI
->registers
.handle
= pMga
->registers
.handle
;
617 pMGADRI
->registers
.size
= pMga
->registers
.size
;
618 pMGADRI
->status
.handle
= pMga
->status
.handle
;
619 pMGADRI
->status
.size
= pMga
->status
.size
;
620 pMGADRI
->primary
.handle
= pMga
->primary
.handle
;
621 pMGADRI
->primary
.size
= pMga
->primary
.size
;
622 pMGADRI
->buffers
.handle
= pMga
->buffers
.handle
;
623 pMGADRI
->buffers
.size
= pMga
->buffers
.size
;
624 pMGADRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
628 static int MGAScreenInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
635 /*assert(!ctx->IsClient);*/
638 int width_bytes
= (ctx
->shared
.virtualWidth
* ctx
->cpp
);
639 int maxy
= ctx
->shared
.fbSize
/ width_bytes
;
642 if (maxy
<= ctx
->shared
.virtualHeight
* 3) {
644 "Static buffer allocation failed -- "
645 "need at least %d kB video memory (have %d kB)\n",
646 (ctx
->shared
.virtualWidth
* ctx
->shared
.virtualHeight
*
647 ctx
->cpp
* 3 + 1023) / 1024,
648 ctx
->shared
.fbSize
/ 1024);
653 switch(pMga
->Chipset
) {
654 case PCI_CHIP_MGAG550
:
655 case PCI_CHIP_MGAG400
:
656 case PCI_CHIP_MGAG200
:
658 case PCI_CHIP_MGAG200_PCI
:
662 fprintf(stderr
, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n");
667 "[drm] bpp: %d depth: %d\n",
668 ctx
->bpp
, ctx
->bpp
/* FIXME: depth */ );
670 if ( (ctx
->bpp
/ 8) != 2 &&
671 (ctx
->bpp
/ 8) != 4 ) {
673 "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
677 ctx
->shared
.SAREASize
= SAREA_MAX
;
680 /* Note that drmOpen will try to load the kernel module, if needed. */
681 ctx
->drmFD
= drmOpen("mga", NULL
);
682 if (ctx
->drmFD
< 0) {
683 fprintf(stderr
, "[drm] drmOpen failed\n");
687 if ((err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
)) < 0) {
688 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
689 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
694 if (drmAddMap( ctx
->drmFD
,
696 ctx
->shared
.SAREASize
,
699 &ctx
->shared
.hSAREA
) < 0)
701 fprintf(stderr
, "[drm] drmAddMap failed\n");
704 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
705 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
707 if (drmMap( ctx
->drmFD
,
709 ctx
->shared
.SAREASize
,
710 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
712 fprintf(stderr
, "[drm] drmMap failed\n");
715 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
716 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
717 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
719 /* Need to AddMap the framebuffer and mmio regions here:
721 if (drmAddMap( ctx
->drmFD
,
722 (drmHandle
)ctx
->FBStart
,
726 &ctx
->shared
.hFrameBuffer
) < 0)
728 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
731 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
732 ctx
->shared
.hFrameBuffer
);
735 #if 0 /* will be done in MGADRIMapInit */
736 if (drmAddMap(ctx
->drmFD
,
737 ctx
->FixedInfo
.mmio_start
,
738 ctx
->FixedInfo
.mmio_len
,
741 &pMga
->registers
.handle
) < 0) {
742 fprintf(stderr
, "[drm] drmAddMap mmio failed\n");
746 "[drm] register handle = 0x%08lx\n", pMga
->registers
.handle
);
750 /* Check the mga DRM version */
751 if (!MGACheckDRMVersion(ctx
, pMga
)) {
755 if ( !MGADRIAgpInit( ctx
, pMga
) ) {
759 if ( !MGADRIMapInit( ctx
, pMga
) ) {
763 /* Memory manager setup */
764 if (!MGAMemoryInit(ctx
, pMga
)) {
769 /* Create a 'server' context so we can grab the lock for
770 * initialization ioctls.
772 if ((err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
)) != 0) {
773 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
777 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
779 /* Initialize the kernel data structures */
780 if (!MGADRIKernelInit(ctx
, pMga
)) {
781 fprintf(stderr
, "MGADRIKernelInit failed\n");
782 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
786 /* Initialize the vertex buffers list */
787 if (!MGADRIBuffersInit(ctx
, pMga
)) {
788 fprintf(stderr
, "MGADRIBuffersInit failed\n");
789 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
794 MGADRIIrqInit(ctx
, pMga
);
797 /* Initialize the SAREA private data structure */
799 MGASAREAPrivPtr pSAREAPriv
;
800 pSAREAPriv
= (MGASAREAPrivPtr
)(((char*)ctx
->pSAREA
) +
801 sizeof(drm_sarea_t
));
802 memset(pSAREAPriv
, 0, sizeof(*pSAREAPriv
));
805 /* Quick hack to clear the front & back buffers. Could also use
806 * the clear ioctl to do this, but would need to setup hw state
809 memset((char *)ctx
->FBAddress
+ pMga
->frontOffset
,
811 pMga
->frontPitch
* ctx
->shared
.virtualHeight
);
813 memset((char *)ctx
->FBAddress
+ pMga
->backOffset
,
815 pMga
->backPitch
* ctx
->shared
.virtualHeight
);
817 /* Can release the lock now */
818 /* DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/
820 /* This is the struct passed to radeon_dri.so for its initialization */
821 ctx
->driverClientMsg
= malloc(sizeof(MGADRIRec
));
822 ctx
->driverClientMsgSize
= sizeof(MGADRIRec
);
824 pMGADRI
= (MGADRIPtr
)ctx
->driverClientMsg
;
827 switch(pMga
->Chipset
) {
828 case PCI_CHIP_MGAG550
:
829 case PCI_CHIP_MGAG400
:
830 pMGADRI
->chipset
= MGA_CARD_TYPE_G400
;
832 case PCI_CHIP_MGAG200
:
833 case PCI_CHIP_MGAG200_PCI
:
834 pMGADRI
->chipset
= MGA_CARD_TYPE_G200
;
839 pMGADRI
->width
= ctx
->shared
.virtualWidth
;
840 pMGADRI
->height
= ctx
->shared
.virtualHeight
;
841 pMGADRI
->mem
= ctx
->shared
.fbSize
;
842 pMGADRI
->cpp
= ctx
->bpp
/ 8;
844 pMGADRI
->agpMode
= pMga
->agpMode
;
846 pMGADRI
->frontOffset
= pMga
->frontOffset
;
847 pMGADRI
->frontPitch
= pMga
->frontPitch
;
848 pMGADRI
->backOffset
= pMga
->backOffset
;
849 pMGADRI
->backPitch
= pMga
->backPitch
;
850 pMGADRI
->depthOffset
= pMga
->depthOffset
;
851 pMGADRI
->depthPitch
= pMga
->depthPitch
;
852 pMGADRI
->textureOffset
= pMga
->textureOffset
;
853 pMGADRI
->textureSize
= pMga
->textureSize
;
854 pMGADRI
->logTextureGranularity
= pMga
->logTextureGranularity
;
856 i
= mylog2( pMga
->agpTextures
.size
/ MGA_NR_TEX_REGIONS
);
857 if ( i
< MGA_LOG_MIN_TEX_REGION_SIZE
)
858 i
= MGA_LOG_MIN_TEX_REGION_SIZE
;
860 pMGADRI
->logAgpTextureGranularity
= i
;
861 pMGADRI
->agpTextureOffset
= (unsigned int)pMga
->agpTextures
.handle
;
862 pMGADRI
->agpTextureSize
= (unsigned int)pMga
->agpTextures
.size
;
864 pMGADRI
->registers
.handle
= pMga
->registers
.handle
;
865 pMGADRI
->registers
.size
= pMga
->registers
.size
;
866 pMGADRI
->status
.handle
= pMga
->status
.handle
;
867 pMGADRI
->status
.size
= pMga
->status
.size
;
868 pMGADRI
->primary
.handle
= pMga
->primary
.handle
;
869 pMGADRI
->primary
.size
= pMga
->primary
.size
;
870 pMGADRI
->buffers
.handle
= pMga
->buffers
.handle
;
871 pMGADRI
->buffers
.size
= pMga
->buffers
.size
;
872 pMGADRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
874 print_client_msg( pMGADRI
);
881 * \brief Establish the set of modes available for the display.
883 * \param ctx display handle.
884 * \param numModes will receive the number of supported modes.
885 * \param modes will point to the list of supported modes.
887 * \return one on success, or zero on failure.
889 * Allocates a single visual and fills it with information according to the
890 * display bit depth. Supports only 16 and 32 bpp bit depths, aborting
893 const __GLcontextModes __glModes
[] = {
895 /* 32 bit, RGBA Depth=24 Stencil=8 */
896 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
897 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_TRUE
,
898 .redBits
= 8, .greenBits
= 8, .blueBits
= 8, .alphaBits
= 8,
899 .redMask
= 0xff0000, .greenMask
= 0xff00, .blueMask
= 0xff, .alphaMask
= 0xff000000,
900 .rgbBits
= 32, .indexBits
= 0,
901 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
902 .depthBits
= 24, .stencilBits
= 8,
903 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
905 /* 16 bit, RGB Depth=16 */
906 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
907 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_FALSE
,
908 .redBits
= 5, .greenBits
= 6, .blueBits
= 5, .alphaBits
= 0,
909 .redMask
= 0xf800, .greenMask
= 0x07e0, .blueMask
= 0x001f, .alphaMask
= 0x0,
910 .rgbBits
= 16, .indexBits
= 0,
911 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
912 .depthBits
= 16, .stencilBits
= 0,
913 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
915 static int mgaInitContextModes( const DRIDriverContext
*ctx
,
916 int *numModes
, const __GLcontextModes
**modes
)
918 *numModes
= sizeof(__glModes
)/sizeof(__GLcontextModes
*);
919 *modes
= &__glModes
[0];
925 * \brief Validate the fbdev mode.
927 * \param ctx display handle.
929 * \return one on success, or zero on failure.
931 * Saves some registers and returns 1.
933 * \sa mgaValidateMode().
935 static int mgaValidateMode( const DRIDriverContext
*ctx
)
942 * \brief Examine mode returned by fbdev.
944 * \param ctx display handle.
946 * \return one on success, or zero on failure.
948 * Restores registers that fbdev has clobbered and returns 1.
950 * \sa mgaValidateMode().
952 static int mgaPostValidateMode( const DRIDriverContext
*ctx
)
959 * \brief Initialize the framebuffer device mode
961 * \param ctx display handle.
963 * \return one on success, or zero on failure.
965 * Fills in \p info with some default values and some information from \p ctx
966 * and then calls MGAScreenInit() for the screen initialization.
968 * Before exiting clears the framebuffer memomry accessing it directly.
970 static int mgaInitFBDev( struct DRIDriverContextRec
*ctx
)
972 MGAPtr pMga
= calloc(1, sizeof(*pMga
));
975 int dummy
= ctx
->shared
.virtualWidth
;
977 switch (ctx
->bpp
/ 8) {
978 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
979 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 31) & ~31; break;
981 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 15) & ~15; break;
984 ctx
->shared
.virtualWidth
= dummy
;
987 ctx
->driverPrivate
= (void *)pMga
;
989 pMga
->agpMode
= MGA_DEFAULT_AGP_MODE
;
990 pMga
->agpSize
= MGA_DEFAULT_AGP_SIZE
;
992 pMga
->Chipset
= ctx
->chipset
;
994 pMga
->IOAddress
= ctx
->MMIOStart
;
995 pMga
->IOBase
= ctx
->MMIOAddress
;
997 pMga
->frontPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
999 if (!MGAScreenInit( ctx
, pMga
))
1007 * \brief The screen is being closed, so clean up any state and free any
1008 * resources used by the DRI.
1010 * \param ctx display handle.
1012 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1015 static void mgaHaltFBDev( struct DRIDriverContextRec
*ctx
)
1017 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
1018 drmClose(ctx
->drmFD
);
1020 if (ctx
->driverPrivate
) {
1021 free(ctx
->driverPrivate
);
1022 ctx
->driverPrivate
= NULL
;
1027 static int mgaEngineShutdown( const DRIDriverContext
*ctx
)
1029 fprintf(stderr
, "%s() is not yet implemented!\n", __FUNCTION__
);
1034 static int mgaEngineRestore( const DRIDriverContext
*ctx
)
1036 fprintf(stderr
, "%s() is not yet implemented!\n", __FUNCTION__
);
1042 * \brief Exported driver interface for Mini GLX.
1046 struct DRIDriverRec __driDriver
= {
1047 mgaInitContextModes
,
1049 mgaPostValidateMode
,
1061 void MGADRICloseScreen( ScreenPtr pScreen
)
1063 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1064 MGAPtr pMga
= MGAPTR(pScrn
);
1065 MGADRIServerPrivatePtr pMga
= pMga
->DRIServerInfo
;
1068 if ( pMga
->drmBuffers
) {
1069 drmUnmapBufs( pMga
->drmBuffers
);
1070 pMga
->drmBuffers
= NULL
;
1074 drmCtlUninstHandler(ctx
->drmFD
);
1079 memset( &init
, 0, sizeof(drmMGAInit
) );
1080 init
.func
= MGA_CLEANUP_DMA
;
1081 drmCommandWrite( ctx
->drmFD
, DRM_MGA_INIT
, &init
, sizeof(drmMGAInit
) );
1083 if ( pMga
->status
.map
) {
1084 drmUnmap( pMga
->status
.map
, pMga
->status
.size
);
1085 pMga
->status
.map
= NULL
;
1087 if ( pMga
->buffers
.map
) {
1088 drmUnmap( pMga
->buffers
.map
, pMga
->buffers
.size
);
1089 pMga
->buffers
.map
= NULL
;
1091 if ( pMga
->primary
.map
) {
1092 drmUnmap( pMga
->primary
.map
, pMga
->primary
.size
);
1093 pMga
->primary
.map
= NULL
;
1095 if ( pMga
->warp
.map
) {
1096 drmUnmap( pMga
->warp
.map
, pMga
->warp
.size
);
1097 pMga
->warp
.map
= NULL
;
1100 if ( pMga
->agpTextures
.map
) {
1101 drmUnmap( pMga
->agpTextures
.map
, pMga
->agpTextures
.size
);
1102 pMga
->agpTextures
.map
= NULL
;
1105 if ( pMga
->agp
.handle
) {
1106 drmAgpUnbind( ctx
->drmFD
, pMga
->agp
.handle
);
1107 drmAgpFree( ctx
->drmFD
, pMga
->agp
.handle
);
1108 pMga
->agp
.handle
= 0;
1109 drmAgpRelease( ctx
->drmFD
);
1112 DRICloseScreen( pScreen
);
1114 if ( pMga
->pDRIInfo
) {
1115 if ( pMga
->pDRIpMga
->devPrivate
) {
1116 xfree( pMga
->pDRIpMga
->devPrivate
);
1117 pMga
->pDRIpMga
->devPrivate
= 0;
1119 DRIDestroyInfoRec( pMga
->pDRIInfo
);
1122 if ( pMga
->DRIServerInfo
) {
1123 xfree( pMga
->DRIServerInfo
);
1124 pMga
->DRIServerInfo
= 0;
1126 if ( pMga
->pVisualConfigs
) {
1127 xfree( pMga
->pVisualConfigs
);
1129 if ( pMga
->pVisualConfigsPriv
) {
1130 xfree( pMga
->pVisualConfigsPriv
);