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>
44 #include "mga_macros.h"
48 /* Quiescence, locking
50 #define MGA_TIMEOUT 2048
52 static void MGAWaitForIdleDMA( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
58 memset( &lock
, 0, sizeof(lock
) );
62 /* first ask for quiescent and flush */
63 lock
.flags
= DRM_LOCK_QUIESCENT
| DRM_LOCK_FLUSH
;
65 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_FLUSH
,
66 &lock
, sizeof( lock
) );
67 } while ( ret
== -EBUSY
&& i
++ < DRM_MGA_IDLE_RETRY
);
69 /* if it's still busy just try quiescent */
70 if ( ret
== -EBUSY
) {
71 lock
.flags
= DRM_LOCK_QUIESCENT
;
73 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_FLUSH
,
74 &lock
, sizeof( lock
) );
75 } while ( ret
== -EBUSY
&& i
++ < DRM_MGA_IDLE_RETRY
);
77 } while ( ( ret
== -EBUSY
) && ( i
++ < MGA_TIMEOUT
) );
83 "[dri] Idle timed out, resetting engine...\n" );
85 drmCommandNone( ctx
->drmFD
, DRM_MGA_RESET
);
89 static unsigned int mylog2( unsigned int n
)
91 unsigned int log2
= 1;
92 while ( n
> 1 ) n
>>= 1, log2
++;
96 static int MGADRIAgpInit(struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
99 unsigned int vendor
, device
;
102 if(pMga
->agpSize
< 12)pMga
->agpSize
= 12;
103 if(pMga
->agpSize
> 64)pMga
->agpSize
= 64; /* cap */
105 /* FIXME: Make these configurable...
107 pMga
->agp
.size
= pMga
->agpSize
* 1024 * 1024;
109 pMga
->warp
.offset
= 0;
110 pMga
->warp
.size
= MGA_WARP_UCODE_SIZE
;
112 pMga
->primary
.offset
= (pMga
->warp
.offset
+
114 pMga
->primary
.size
= 1024 * 1024;
116 pMga
->buffers
.offset
= (pMga
->primary
.offset
+
118 pMga
->buffers
.size
= MGA_NUM_BUFFERS
* MGA_BUFFER_SIZE
;
121 pMga
->agpTextures
.offset
= (pMga
->buffers
.offset
+
124 pMga
->agpTextures
.size
= pMga
->agp
.size
-
125 pMga
->agpTextures
.offset
;
127 if ( drmAgpAcquire( ctx
->drmFD
) < 0 ) {
128 fprintf( stderr
, "[agp] AGP not available\n" );
132 mode
= drmAgpGetMode( ctx
->drmFD
); /* Default mode */
133 vendor
= drmAgpVendorId( ctx
->drmFD
);
134 device
= drmAgpDeviceId( ctx
->drmFD
);
136 mode
&= ~MGA_AGP_MODE_MASK
;
137 switch ( pMga
->agpMode
) {
139 mode
|= MGA_AGP_4X_MODE
;
141 mode
|= MGA_AGP_2X_MODE
;
144 mode
|= MGA_AGP_1X_MODE
;
149 "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
150 mode
, vendor
, device
,
155 if ( drmAgpEnable( ctx
->drmFD
, mode
) < 0 ) {
156 fprintf( stderr
, "[agp] AGP not enabled\n" );
157 drmAgpRelease( ctx
->drmFD
);
161 if ( pMga
->Chipset
== PCI_CHIP_MGAG200
) {
162 switch ( pMga
->agpMode
) {
165 "[drm] Enabling AGP 2x PLL encoding\n" );
166 OUTREG( MGAREG_AGP_PLL
, MGA_AGP2XPLL_ENABLE
);
172 "[drm] Disabling AGP 2x PLL encoding\n" );
173 OUTREG( MGAREG_AGP_PLL
, MGA_AGP2XPLL_DISABLE
);
179 ret
= drmAgpAlloc( ctx
->drmFD
, pMga
->agp
.size
,
180 0, NULL
, &pMga
->agp
.handle
);
182 fprintf( stderr
, "[agp] Out of memory (%d)\n", ret
);
183 drmAgpRelease( ctx
->drmFD
);
187 "[agp] %d kB allocated with handle 0x%08x\n",
188 pMga
->agp
.size
/1024, (unsigned int)pMga
->agp
.handle
);
190 if ( drmAgpBind( ctx
->drmFD
, pMga
->agp
.handle
, 0 ) < 0 ) {
191 fprintf( stderr
, "[agp] Could not bind memory\n" );
192 drmAgpFree( ctx
->drmFD
, pMga
->agp
.handle
);
193 drmAgpRelease( ctx
->drmFD
);
197 /* WARP microcode space
199 if ( drmAddMap( ctx
->drmFD
,
202 DRM_AGP
, DRM_READ_ONLY
,
203 &pMga
->warp
.handle
) < 0 ) {
205 "[agp] Could not add WARP microcode mapping\n" );
209 "[agp] WARP microcode handle = 0x%08x\n",
212 if ( drmMap( ctx
->drmFD
,
215 &pMga
->warp
.map
) < 0 ) {
217 "[agp] Could not map WARP microcode\n" );
221 "[agp] WARP microcode mapped at 0x%08lx\n",
222 (unsigned long)pMga
->warp
.map
);
226 if ( drmAddMap( ctx
->drmFD
,
227 pMga
->primary
.offset
,
229 DRM_AGP
, DRM_READ_ONLY
,
230 &pMga
->primary
.handle
) < 0 ) {
232 "[agp] Could not add primary DMA mapping\n" );
236 "[agp] Primary DMA handle = 0x%08x\n",
237 pMga
->primary
.handle
);
239 if ( drmMap( ctx
->drmFD
,
240 pMga
->primary
.handle
,
242 &pMga
->primary
.map
) < 0 ) {
244 "[agp] Could not map primary DMA\n" );
248 "[agp] Primary DMA mapped at 0x%08lx\n",
249 (unsigned long)pMga
->primary
.map
);
253 if ( drmAddMap( ctx
->drmFD
,
254 pMga
->buffers
.offset
,
257 &pMga
->buffers
.handle
) < 0 ) {
259 "[agp] Could not add DMA buffers mapping\n" );
263 "[agp] DMA buffers handle = 0x%08x\n",
264 pMga
->buffers
.handle
);
266 if ( drmMap( ctx
->drmFD
,
267 pMga
->buffers
.handle
,
269 &pMga
->buffers
.map
) < 0 ) {
271 "[agp] Could not map DMA buffers\n" );
275 "[agp] DMA buffers mapped at 0x%08lx\n",
276 (unsigned long)pMga
->buffers
.map
);
278 count
= drmAddBufs( ctx
->drmFD
,
279 MGA_NUM_BUFFERS
, MGA_BUFFER_SIZE
,
280 DRM_AGP_BUFFER
, pMga
->buffers
.offset
);
283 "[drm] failure adding %d %d byte DMA buffers\n",
284 MGA_NUM_BUFFERS
, MGA_BUFFER_SIZE
);
288 "[drm] Added %d %d byte DMA buffers\n",
289 count
, MGA_BUFFER_SIZE
);
291 i
= mylog2(pMga
->agpTextures
.size
/ MGA_NR_TEX_REGIONS
);
292 if(i
< MGA_LOG_MIN_TEX_REGION_SIZE
)
293 i
= MGA_LOG_MIN_TEX_REGION_SIZE
;
294 pMga
->agpTextures
.size
= (pMga
->agpTextures
.size
>> i
) << i
;
296 if ( drmAddMap( ctx
->drmFD
,
297 pMga
->agpTextures
.offset
,
298 pMga
->agpTextures
.size
,
300 &pMga
->agpTextures
.handle
) < 0 ) {
302 "[agp] Could not add agpTexture mapping\n" );
305 /* should i map it ? */
307 "[agp] agpTexture handle = 0x%08x\n",
308 pMga
->agpTextures
.handle
);
310 "[agp] agpTexture size: %d kb\n", pMga
->agpTextures
.size
/1024 );
315 static int MGADRIMapInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
317 pMga
->registers
.size
= MGAIOMAPSIZE
;
319 if ( drmAddMap( ctx
->drmFD
,
320 (drm_handle_t
)pMga
->IOAddress
,
321 pMga
->registers
.size
,
322 DRM_REGISTERS
, DRM_READ_ONLY
,
323 &pMga
->registers
.handle
) < 0 ) {
325 "[drm] Could not add MMIO registers mapping\n" );
329 "[drm] Registers handle = 0x%08lx\n",
330 pMga
->registers
.handle
);
332 pMga
->status
.size
= SAREA_MAX
;
334 if ( drmAddMap( ctx
->drmFD
, 0, pMga
->status
.size
,
335 DRM_SHM
, DRM_READ_ONLY
| DRM_LOCKED
| DRM_KERNEL
,
336 &pMga
->status
.handle
) < 0 ) {
338 "[drm] Could not add status page mapping\n" );
342 "[drm] Status handle = 0x%08x\n",
343 pMga
->status
.handle
);
345 if ( drmMap( ctx
->drmFD
,
348 &pMga
->status
.map
) < 0 ) {
350 "[agp] Could not map status page\n" );
354 "[agp] Status page mapped at 0x%08lx\n",
355 (unsigned long)pMga
->status
.map
);
360 static int MGADRIKernelInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
365 memset( &init
, 0, sizeof(init
) );
367 init
.func
= MGA_INIT_DMA
;
368 init
.sarea_priv_offset
= sizeof(drm_sarea_t
);
370 switch ( pMga
->Chipset
) {
371 case PCI_CHIP_MGAG550
:
372 case PCI_CHIP_MGAG400
:
373 init
.chipset
= MGA_CARD_TYPE_G400
;
375 case PCI_CHIP_MGAG200
:
376 case PCI_CHIP_MGAG200_PCI
:
377 init
.chipset
= MGA_CARD_TYPE_G200
;
383 init
.sgram
= 0; /* FIXME !pMga->HasSDRAM; */
389 init
.maccess
= MGA_MACCESS_PW16
;
392 init
.maccess
= MGA_MACCESS_PW32
;
395 fprintf( stderr
, "[mga] invalid bpp (%d)\n", ctx
->bpp
);
400 init
.fb_cpp
= ctx
->bpp
/ 8;
401 init
.front_offset
= pMga
->frontOffset
;
402 init
.front_pitch
= pMga
->frontPitch
/ init
.fb_cpp
;
403 init
.back_offset
= pMga
->backOffset
;
404 init
.back_pitch
= pMga
->backPitch
/ init
.fb_cpp
;
406 init
.depth_cpp
= ctx
->bpp
/ 8;
407 init
.depth_offset
= pMga
->depthOffset
;
408 init
.depth_pitch
= pMga
->depthPitch
/ init
.depth_cpp
;
410 init
.texture_offset
[0] = pMga
->textureOffset
;
411 init
.texture_size
[0] = pMga
->textureSize
;
413 init
.fb_offset
= ctx
->shared
.hFrameBuffer
;
414 init
.mmio_offset
= pMga
->registers
.handle
;
415 init
.status_offset
= pMga
->status
.handle
;
417 init
.warp_offset
= pMga
->warp
.handle
;
418 init
.primary_offset
= pMga
->primary
.handle
;
419 init
.buffers_offset
= pMga
->buffers
.handle
;
421 init
.texture_offset
[1] = pMga
->agpTextures
.handle
;
422 init
.texture_size
[1] = pMga
->agpTextures
.size
;
424 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_INIT
, &init
, sizeof(init
));
427 "[drm] Failed to initialize DMA! (%d)\n", ret
);
434 static void MGADRIIrqInit(struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
438 pMga
->irq
= drmGetInterruptFromBusID(ctx
->drmFD
,
443 fprintf(stderr
, "[drm] got IRQ %d\n", pMga
->irq
);
445 if((drmCtlInstHandler(ctx
->drmFD
, pMga
->irq
)) != 0)
448 "[drm] failure adding irq handler, "
449 "there is a device already using that irq\n"
450 "[drm] falling back to irq-free operation\n");
455 pMga
->reg_ien
= INREG( MGAREG_IEN
);
461 "[drm] dma control initialized, using IRQ %d\n",
465 static int MGADRIBuffersInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
467 pMga
->drmBuffers
= drmMapBufs( ctx
->drmFD
);
468 if ( !pMga
->drmBuffers
)
471 "[drm] Failed to map DMA buffers list\n" );
476 "[drm] Mapped %d DMA buffers\n",
477 pMga
->drmBuffers
->count
);
482 static int MGAMemoryInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
484 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
485 int bufferSize
= ((ctx
->shared
.virtualHeight
* width_bytes
487 & ~MGA_BUFFER_ALIGN
);
488 int depthSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
490 & ~MGA_BUFFER_ALIGN
);
493 pMga
->frontOffset
= 0;
494 pMga
->frontPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
497 "Using %d MB AGP aperture\n", pMga
->agpSize
);
499 "Using %d MB for vertex/indirect buffers\n", pMga
->buffers
.size
>>20);
501 "Using %d MB for AGP textures\n", pMga
->agpTextures
.size
>>20);
503 /* Front, back and depth buffers - everything else texture??
505 pMga
->textureSize
= ctx
->shared
.fbSize
- 2 * bufferSize
- depthSize
;
507 if (pMga
->textureSize
< 0)
510 l
= mylog2( pMga
->textureSize
/ MGA_NR_TEX_REGIONS
);
511 if ( l
< MGA_LOG_MIN_TEX_REGION_SIZE
)
512 l
= MGA_LOG_MIN_TEX_REGION_SIZE
;
514 /* Round the texture size up to the nearest whole number of
515 * texture regions. Again, be greedy about this, don't
518 pMga
->logTextureGranularity
= l
;
519 pMga
->textureSize
= (pMga
->textureSize
>> l
) << l
;
521 /* Set a minimum usable local texture heap size. This will fit
522 * two 256x256x32bpp textures.
524 if (pMga
->textureSize
< 512 * 1024) {
525 pMga
->textureOffset
= 0;
526 pMga
->textureSize
= 0;
529 /* Reserve space for textures */
530 pMga
->textureOffset
= ((ctx
->shared
.fbSize
- pMga
->textureSize
+
534 /* Reserve space for the shared depth
537 pMga
->depthOffset
= ((pMga
->textureOffset
- depthSize
+
540 pMga
->depthPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
542 pMga
->backOffset
= ((pMga
->depthOffset
- bufferSize
+
545 pMga
->backPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
549 "Will use back buffer at offset 0x%x\n",
552 "Will use depth buffer at offset 0x%x\n",
555 "Will use %d kb for textures at offset 0x%x\n",
556 pMga
->textureSize
/1024, pMga
->textureOffset
);
561 static int MGACheckDRMVersion( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
563 drmVersionPtr version
;
565 /* Check the MGA DRM version */
566 version
= drmGetVersion(ctx
->drmFD
);
568 if ( version
->version_major
!= 3 ||
569 version
->version_minor
< 0 ) {
570 /* incompatible drm version */
572 "[dri] MGADRIScreenInit failed because of a version mismatch.\n"
573 "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n"
574 "[dri] Disabling DRI.\n",
575 version
->version_major
,
576 version
->version_minor
,
577 version
->version_patchlevel
);
578 drmFreeVersion( version
);
581 drmFreeVersion( version
);
587 static void print_client_msg( MGADRIPtr pMGADRI
)
589 fprintf( stderr
, "chipset: %d\n", pMGADRI
->chipset
);
591 fprintf( stderr
, "width: %d\n", pMGADRI
->width
);
592 fprintf( stderr
, "height: %d\n", pMGADRI
->height
);
593 fprintf( stderr
, "mem: %d\n", pMGADRI
->mem
);
594 fprintf( stderr
, "cpp: %d\n", pMGADRI
->cpp
);
596 fprintf( stderr
, "agpMode: %d\n", pMGADRI
->agpMode
);
598 fprintf( stderr
, "frontOffset: %d\n", pMGADRI
->frontOffset
);
599 fprintf( stderr
, "frontPitch: %d\n", pMGADRI
->frontPitch
);
601 fprintf( stderr
, "backOffset: %d\n", pMGADRI
->backOffset
);
602 fprintf( stderr
, "backPitch: %d\n", pMGADRI
->backPitch
);
604 fprintf( stderr
, "depthOffset: %d\n", pMGADRI
->depthOffset
);
605 fprintf( stderr
, "depthPitch: %d\n", pMGADRI
->depthPitch
);
607 fprintf( stderr
, "textureOffset: %d\n", pMGADRI
->textureOffset
);
608 fprintf( stderr
, "textureSize: %d\n", pMGADRI
->textureSize
);
610 fprintf( stderr
, "logTextureGranularity: %d\n", pMGADRI
->logTextureGranularity
);
611 fprintf( stderr
, "logAgpTextureGranularity: %d\n", pMGADRI
->logAgpTextureGranularity
);
613 fprintf( stderr
, "agpTextureHandle: %u\n", (unsigned int)pMGADRI
->agpTextureOffset
);
614 fprintf( stderr
, "agpTextureSize: %u\n", (unsigned int)pMGADRI
->agpTextureSize
);
617 pMGADRI
->registers
.handle
= pMga
->registers
.handle
;
618 pMGADRI
->registers
.size
= pMga
->registers
.size
;
619 pMGADRI
->status
.handle
= pMga
->status
.handle
;
620 pMGADRI
->status
.size
= pMga
->status
.size
;
621 pMGADRI
->primary
.handle
= pMga
->primary
.handle
;
622 pMGADRI
->primary
.size
= pMga
->primary
.size
;
623 pMGADRI
->buffers
.handle
= pMga
->buffers
.handle
;
624 pMGADRI
->buffers
.size
= pMga
->buffers
.size
;
625 pMGADRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
629 static int MGAScreenInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
636 /*assert(!ctx->IsClient);*/
639 int width_bytes
= (ctx
->shared
.virtualWidth
* ctx
->cpp
);
640 int maxy
= ctx
->shared
.fbSize
/ width_bytes
;
643 if (maxy
<= ctx
->shared
.virtualHeight
* 3) {
645 "Static buffer allocation failed -- "
646 "need at least %d kB video memory (have %d kB)\n",
647 (ctx
->shared
.virtualWidth
* ctx
->shared
.virtualHeight
*
648 ctx
->cpp
* 3 + 1023) / 1024,
649 ctx
->shared
.fbSize
/ 1024);
654 switch(pMga
->Chipset
) {
655 case PCI_CHIP_MGAG550
:
656 case PCI_CHIP_MGAG400
:
657 case PCI_CHIP_MGAG200
:
659 case PCI_CHIP_MGAG200_PCI
:
663 fprintf(stderr
, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n");
668 "[drm] bpp: %d depth: %d\n",
669 ctx
->bpp
, ctx
->bpp
/* FIXME: depth */ );
671 if ( (ctx
->bpp
/ 8) != 2 &&
672 (ctx
->bpp
/ 8) != 4 ) {
674 "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
678 ctx
->shared
.SAREASize
= SAREA_MAX
;
681 /* Note that drmOpen will try to load the kernel module, if needed. */
682 ctx
->drmFD
= drmOpen("mga", NULL
);
683 if (ctx
->drmFD
< 0) {
684 fprintf(stderr
, "[drm] drmOpen failed\n");
688 if ((err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
)) < 0) {
689 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
690 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
695 if (drmAddMap( ctx
->drmFD
,
697 ctx
->shared
.SAREASize
,
700 &ctx
->shared
.hSAREA
) < 0)
702 fprintf(stderr
, "[drm] drmAddMap failed\n");
705 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
706 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
708 if (drmMap( ctx
->drmFD
,
710 ctx
->shared
.SAREASize
,
711 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
713 fprintf(stderr
, "[drm] drmMap failed\n");
716 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
717 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
718 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
720 /* Need to AddMap the framebuffer and mmio regions here:
722 if (drmAddMap( ctx
->drmFD
,
723 (drm_handle_t
)ctx
->FBStart
,
727 &ctx
->shared
.hFrameBuffer
) < 0)
729 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
732 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
733 ctx
->shared
.hFrameBuffer
);
736 #if 0 /* will be done in MGADRIMapInit */
737 if (drmAddMap(ctx
->drmFD
,
738 ctx
->FixedInfo
.mmio_start
,
739 ctx
->FixedInfo
.mmio_len
,
742 &pMga
->registers
.handle
) < 0) {
743 fprintf(stderr
, "[drm] drmAddMap mmio failed\n");
747 "[drm] register handle = 0x%08lx\n", pMga
->registers
.handle
);
751 /* Check the mga DRM version */
752 if (!MGACheckDRMVersion(ctx
, pMga
)) {
756 if ( !MGADRIAgpInit( ctx
, pMga
) ) {
760 if ( !MGADRIMapInit( ctx
, pMga
) ) {
764 /* Memory manager setup */
765 if (!MGAMemoryInit(ctx
, pMga
)) {
770 /* Create a 'server' context so we can grab the lock for
771 * initialization ioctls.
773 if ((err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
)) != 0) {
774 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
778 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
780 /* Initialize the kernel data structures */
781 if (!MGADRIKernelInit(ctx
, pMga
)) {
782 fprintf(stderr
, "MGADRIKernelInit failed\n");
783 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
787 /* Initialize the vertex buffers list */
788 if (!MGADRIBuffersInit(ctx
, pMga
)) {
789 fprintf(stderr
, "MGADRIBuffersInit failed\n");
790 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
795 MGADRIIrqInit(ctx
, pMga
);
798 /* Initialize the SAREA private data structure */
800 drm_mga_sarea_t
*pSAREAPriv
;
801 pSAREAPriv
= (drm_mga_sarea_t
*)(((char*)ctx
->pSAREA
) +
802 sizeof(drm_sarea_t
));
803 memset(pSAREAPriv
, 0, sizeof(*pSAREAPriv
));
806 /* Quick hack to clear the front & back buffers. Could also use
807 * the clear ioctl to do this, but would need to setup hw state
810 drimemsetio((char *)ctx
->FBAddress
+ pMga
->frontOffset
,
812 pMga
->frontPitch
* ctx
->shared
.virtualHeight
);
814 drimemsetio((char *)ctx
->FBAddress
+ pMga
->backOffset
,
816 pMga
->backPitch
* ctx
->shared
.virtualHeight
);
818 /* Can release the lock now */
819 /* DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/
821 /* This is the struct passed to radeon_dri.so for its initialization */
822 ctx
->driverClientMsg
= malloc(sizeof(MGADRIRec
));
823 ctx
->driverClientMsgSize
= sizeof(MGADRIRec
);
825 pMGADRI
= (MGADRIPtr
)ctx
->driverClientMsg
;
828 switch(pMga
->Chipset
) {
829 case PCI_CHIP_MGAG550
:
830 case PCI_CHIP_MGAG400
:
831 pMGADRI
->chipset
= MGA_CARD_TYPE_G400
;
833 case PCI_CHIP_MGAG200
:
834 case PCI_CHIP_MGAG200_PCI
:
835 pMGADRI
->chipset
= MGA_CARD_TYPE_G200
;
840 pMGADRI
->width
= ctx
->shared
.virtualWidth
;
841 pMGADRI
->height
= ctx
->shared
.virtualHeight
;
842 pMGADRI
->mem
= ctx
->shared
.fbSize
;
843 pMGADRI
->cpp
= ctx
->bpp
/ 8;
845 pMGADRI
->agpMode
= pMga
->agpMode
;
847 pMGADRI
->frontOffset
= pMga
->frontOffset
;
848 pMGADRI
->frontPitch
= pMga
->frontPitch
;
849 pMGADRI
->backOffset
= pMga
->backOffset
;
850 pMGADRI
->backPitch
= pMga
->backPitch
;
851 pMGADRI
->depthOffset
= pMga
->depthOffset
;
852 pMGADRI
->depthPitch
= pMga
->depthPitch
;
853 pMGADRI
->textureOffset
= pMga
->textureOffset
;
854 pMGADRI
->textureSize
= pMga
->textureSize
;
855 pMGADRI
->logTextureGranularity
= pMga
->logTextureGranularity
;
857 i
= mylog2( pMga
->agpTextures
.size
/ MGA_NR_TEX_REGIONS
);
858 if ( i
< MGA_LOG_MIN_TEX_REGION_SIZE
)
859 i
= MGA_LOG_MIN_TEX_REGION_SIZE
;
861 pMGADRI
->logAgpTextureGranularity
= i
;
862 pMGADRI
->agpTextureOffset
= (unsigned int)pMga
->agpTextures
.handle
;
863 pMGADRI
->agpTextureSize
= (unsigned int)pMga
->agpTextures
.size
;
865 pMGADRI
->registers
.handle
= pMga
->registers
.handle
;
866 pMGADRI
->registers
.size
= pMga
->registers
.size
;
867 pMGADRI
->status
.handle
= pMga
->status
.handle
;
868 pMGADRI
->status
.size
= pMga
->status
.size
;
869 pMGADRI
->primary
.handle
= pMga
->primary
.handle
;
870 pMGADRI
->primary
.size
= pMga
->primary
.size
;
871 pMGADRI
->buffers
.handle
= pMga
->buffers
.handle
;
872 pMGADRI
->buffers
.size
= pMga
->buffers
.size
;
873 pMGADRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
875 print_client_msg( pMGADRI
);
882 * \brief Validate the fbdev mode.
884 * \param ctx display handle.
886 * \return one on success, or zero on failure.
888 * Saves some registers and returns 1.
890 * \sa mgaValidateMode().
892 static int mgaValidateMode( const DRIDriverContext
*ctx
)
899 * \brief Examine mode returned by fbdev.
901 * \param ctx display handle.
903 * \return one on success, or zero on failure.
905 * Restores registers that fbdev has clobbered and returns 1.
907 * \sa mgaValidateMode().
909 static int mgaPostValidateMode( const DRIDriverContext
*ctx
)
916 * \brief Initialize the framebuffer device mode
918 * \param ctx display handle.
920 * \return one on success, or zero on failure.
922 * Fills in \p info with some default values and some information from \p ctx
923 * and then calls MGAScreenInit() for the screen initialization.
925 * Before exiting clears the framebuffer memomry accessing it directly.
927 static int mgaInitFBDev( struct DRIDriverContextRec
*ctx
)
929 MGAPtr pMga
= calloc(1, sizeof(*pMga
));
932 int dummy
= ctx
->shared
.virtualWidth
;
934 switch (ctx
->bpp
/ 8) {
935 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
936 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 31) & ~31; break;
938 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 15) & ~15; break;
941 ctx
->shared
.virtualWidth
= dummy
;
944 ctx
->driverPrivate
= (void *)pMga
;
946 pMga
->agpMode
= MGA_DEFAULT_AGP_MODE
;
947 pMga
->agpSize
= MGA_DEFAULT_AGP_SIZE
;
949 pMga
->Chipset
= ctx
->chipset
;
951 pMga
->IOAddress
= ctx
->MMIOStart
;
952 pMga
->IOBase
= ctx
->MMIOAddress
;
954 pMga
->frontPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
956 if (!MGAScreenInit( ctx
, pMga
))
964 * \brief The screen is being closed, so clean up any state and free any
965 * resources used by the DRI.
967 * \param ctx display handle.
969 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
972 static void mgaHaltFBDev( struct DRIDriverContextRec
*ctx
)
974 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
975 drmClose(ctx
->drmFD
);
977 if (ctx
->driverPrivate
) {
978 free(ctx
->driverPrivate
);
979 ctx
->driverPrivate
= NULL
;
984 static int mgaEngineShutdown( const DRIDriverContext
*ctx
)
986 fprintf(stderr
, "%s() is not yet implemented!\n", __FUNCTION__
);
991 static int mgaEngineRestore( const DRIDriverContext
*ctx
)
993 fprintf(stderr
, "%s() is not yet implemented!\n", __FUNCTION__
);
999 * \brief Exported driver interface for Mini GLX.
1003 struct DRIDriverRec __driDriver
= {
1005 mgaPostValidateMode
,
1017 void MGADRICloseScreen( ScreenPtr pScreen
)
1019 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1020 MGAPtr pMga
= MGAPTR(pScrn
);
1021 MGADRIServerPrivatePtr pMga
= pMga
->DRIServerInfo
;
1024 if ( pMga
->drmBuffers
) {
1025 drmUnmapBufs( pMga
->drmBuffers
);
1026 pMga
->drmBuffers
= NULL
;
1030 drmCtlUninstHandler(ctx
->drmFD
);
1035 memset( &init
, 0, sizeof(drmMGAInit
) );
1036 init
.func
= MGA_CLEANUP_DMA
;
1037 drmCommandWrite( ctx
->drmFD
, DRM_MGA_INIT
, &init
, sizeof(drmMGAInit
) );
1039 if ( pMga
->status
.map
) {
1040 drmUnmap( pMga
->status
.map
, pMga
->status
.size
);
1041 pMga
->status
.map
= NULL
;
1043 if ( pMga
->buffers
.map
) {
1044 drmUnmap( pMga
->buffers
.map
, pMga
->buffers
.size
);
1045 pMga
->buffers
.map
= NULL
;
1047 if ( pMga
->primary
.map
) {
1048 drmUnmap( pMga
->primary
.map
, pMga
->primary
.size
);
1049 pMga
->primary
.map
= NULL
;
1051 if ( pMga
->warp
.map
) {
1052 drmUnmap( pMga
->warp
.map
, pMga
->warp
.size
);
1053 pMga
->warp
.map
= NULL
;
1056 if ( pMga
->agpTextures
.map
) {
1057 drmUnmap( pMga
->agpTextures
.map
, pMga
->agpTextures
.size
);
1058 pMga
->agpTextures
.map
= NULL
;
1061 if ( pMga
->agp
.handle
) {
1062 drmAgpUnbind( ctx
->drmFD
, pMga
->agp
.handle
);
1063 drmAgpFree( ctx
->drmFD
, pMga
->agp
.handle
);
1064 pMga
->agp
.handle
= 0;
1065 drmAgpRelease( ctx
->drmFD
);
1068 DRICloseScreen( pScreen
);
1070 if ( pMga
->pDRIInfo
) {
1071 if ( pMga
->pDRIpMga
->devPrivate
) {
1072 xfree( pMga
->pDRIpMga
->devPrivate
);
1073 pMga
->pDRIpMga
->devPrivate
= 0;
1075 DRIDestroyInfoRec( pMga
->pDRIInfo
);
1078 if ( pMga
->DRIServerInfo
) {
1079 xfree( pMga
->DRIServerInfo
);
1080 pMga
->DRIServerInfo
= 0;
1082 if ( pMga
->pVisualConfigs
) {
1083 xfree( pMga
->pVisualConfigs
);
1085 if ( pMga
->pVisualConfigsPriv
) {
1086 xfree( pMga
->pVisualConfigsPriv
);