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"
50 /* Quiescence, locking
52 #define MGA_TIMEOUT 2048
54 static void MGAWaitForIdleDMA( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
60 memset( &lock
, 0, sizeof(drmMGALock
) );
64 /* first ask for quiescent and flush */
65 lock
.flags
= DRM_MGA_LOCK_QUIESCENT
| DRM_MGA_LOCK_FLUSH
;
67 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_FLUSH
,
68 &lock
, sizeof( drmMGALock
) );
69 } while ( ret
== -EBUSY
&& i
++ < DRM_MGA_IDLE_RETRY
);
71 /* if it's still busy just try quiescent */
72 if ( ret
== -EBUSY
) {
73 lock
.flags
= DRM_MGA_LOCK_QUIESCENT
;
75 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_FLUSH
,
76 &lock
, sizeof( drmMGALock
) );
77 } while ( ret
== -EBUSY
&& i
++ < DRM_MGA_IDLE_RETRY
);
79 } while ( ( ret
== -EBUSY
) && ( i
++ < MGA_TIMEOUT
) );
85 "[dri] Idle timed out, resetting engine...\n" );
87 drmCommandNone( ctx
->drmFD
, DRM_MGA_RESET
);
91 static unsigned int mylog2( unsigned int n
)
93 unsigned int log2
= 1;
94 while ( n
> 1 ) n
>>= 1, log2
++;
98 static int MGADRIAgpInit(struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
101 unsigned int vendor
, device
;
104 if(pMga
->agpSize
< 12)pMga
->agpSize
= 12;
105 if(pMga
->agpSize
> 64)pMga
->agpSize
= 64; /* cap */
107 /* FIXME: Make these configurable...
109 pMga
->agp
.size
= pMga
->agpSize
* 1024 * 1024;
111 pMga
->warp
.offset
= 0;
112 pMga
->warp
.size
= MGA_WARP_UCODE_SIZE
;
114 pMga
->primary
.offset
= (pMga
->warp
.offset
+
116 pMga
->primary
.size
= 1024 * 1024;
118 pMga
->buffers
.offset
= (pMga
->primary
.offset
+
120 pMga
->buffers
.size
= MGA_NUM_BUFFERS
* MGA_BUFFER_SIZE
;
123 pMga
->agpTextures
.offset
= (pMga
->buffers
.offset
+
126 pMga
->agpTextures
.size
= pMga
->agp
.size
-
127 pMga
->agpTextures
.offset
;
129 if ( drmAgpAcquire( ctx
->drmFD
) < 0 ) {
130 fprintf( stderr
, "[agp] AGP not available\n" );
134 mode
= drmAgpGetMode( ctx
->drmFD
); /* Default mode */
135 vendor
= drmAgpVendorId( ctx
->drmFD
);
136 device
= drmAgpDeviceId( ctx
->drmFD
);
138 mode
&= ~MGA_AGP_MODE_MASK
;
139 switch ( pMga
->agpMode
) {
141 mode
|= MGA_AGP_4X_MODE
;
143 mode
|= MGA_AGP_2X_MODE
;
146 mode
|= MGA_AGP_1X_MODE
;
151 "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n",
152 mode
, vendor
, device
,
157 if ( drmAgpEnable( ctx
->drmFD
, mode
) < 0 ) {
158 fprintf( stderr
, "[agp] AGP not enabled\n" );
159 drmAgpRelease( ctx
->drmFD
);
163 if ( pMga
->Chipset
== PCI_CHIP_MGAG200
) {
164 switch ( pMga
->agpMode
) {
167 "[drm] Enabling AGP 2x PLL encoding\n" );
168 OUTREG( MGAREG_AGP_PLL
, MGA_AGP2XPLL_ENABLE
);
174 "[drm] Disabling AGP 2x PLL encoding\n" );
175 OUTREG( MGAREG_AGP_PLL
, MGA_AGP2XPLL_DISABLE
);
181 ret
= drmAgpAlloc( ctx
->drmFD
, pMga
->agp
.size
,
182 0, NULL
, &pMga
->agp
.handle
);
184 fprintf( stderr
, "[agp] Out of memory (%d)\n", ret
);
185 drmAgpRelease( ctx
->drmFD
);
189 "[agp] %d kB allocated with handle 0x%08x\n",
190 pMga
->agp
.size
/1024, (unsigned int)pMga
->agp
.handle
);
192 if ( drmAgpBind( ctx
->drmFD
, pMga
->agp
.handle
, 0 ) < 0 ) {
193 fprintf( stderr
, "[agp] Could not bind memory\n" );
194 drmAgpFree( ctx
->drmFD
, pMga
->agp
.handle
);
195 drmAgpRelease( ctx
->drmFD
);
199 /* WARP microcode space
201 if ( drmAddMap( ctx
->drmFD
,
204 DRM_AGP
, DRM_READ_ONLY
,
205 &pMga
->warp
.handle
) < 0 ) {
207 "[agp] Could not add WARP microcode mapping\n" );
211 "[agp] WARP microcode handle = 0x%08lx\n",
214 if ( drmMap( ctx
->drmFD
,
217 &pMga
->warp
.map
) < 0 ) {
219 "[agp] Could not map WARP microcode\n" );
223 "[agp] WARP microcode mapped at 0x%08lx\n",
224 (unsigned long)pMga
->warp
.map
);
228 if ( drmAddMap( ctx
->drmFD
,
229 pMga
->primary
.offset
,
231 DRM_AGP
, DRM_READ_ONLY
,
232 &pMga
->primary
.handle
) < 0 ) {
234 "[agp] Could not add primary DMA mapping\n" );
238 "[agp] Primary DMA handle = 0x%08lx\n",
239 pMga
->primary
.handle
);
241 if ( drmMap( ctx
->drmFD
,
242 pMga
->primary
.handle
,
244 &pMga
->primary
.map
) < 0 ) {
246 "[agp] Could not map primary DMA\n" );
250 "[agp] Primary DMA mapped at 0x%08lx\n",
251 (unsigned long)pMga
->primary
.map
);
255 if ( drmAddMap( ctx
->drmFD
,
256 pMga
->buffers
.offset
,
259 &pMga
->buffers
.handle
) < 0 ) {
261 "[agp] Could not add DMA buffers mapping\n" );
265 "[agp] DMA buffers handle = 0x%08lx\n",
266 pMga
->buffers
.handle
);
268 if ( drmMap( ctx
->drmFD
,
269 pMga
->buffers
.handle
,
271 &pMga
->buffers
.map
) < 0 ) {
273 "[agp] Could not map DMA buffers\n" );
277 "[agp] DMA buffers mapped at 0x%08lx\n",
278 (unsigned long)pMga
->buffers
.map
);
280 count
= drmAddBufs( ctx
->drmFD
,
281 MGA_NUM_BUFFERS
, MGA_BUFFER_SIZE
,
282 DRM_AGP_BUFFER
, pMga
->buffers
.offset
);
285 "[drm] failure adding %d %d byte DMA buffers\n",
286 MGA_NUM_BUFFERS
, MGA_BUFFER_SIZE
);
290 "[drm] Added %d %d byte DMA buffers\n",
291 count
, MGA_BUFFER_SIZE
);
293 i
= mylog2(pMga
->agpTextures
.size
/ MGA_NR_TEX_REGIONS
);
294 if(i
< MGA_LOG_MIN_TEX_REGION_SIZE
)
295 i
= MGA_LOG_MIN_TEX_REGION_SIZE
;
296 pMga
->agpTextures
.size
= (pMga
->agpTextures
.size
>> i
) << i
;
298 if ( drmAddMap( ctx
->drmFD
,
299 pMga
->agpTextures
.offset
,
300 pMga
->agpTextures
.size
,
302 &pMga
->agpTextures
.handle
) < 0 ) {
304 "[agp] Could not add agpTexture mapping\n" );
307 /* should i map it ? */
309 "[agp] agpTexture handle = 0x%08lx\n",
310 pMga
->agpTextures
.handle
);
312 "[agp] agpTexture size: %d kb\n", pMga
->agpTextures
.size
/1024 );
317 static int MGADRIMapInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
319 pMga
->registers
.size
= MGAIOMAPSIZE
;
321 if ( drmAddMap( ctx
->drmFD
,
322 (drmHandle
)pMga
->IOAddress
,
323 pMga
->registers
.size
,
324 DRM_REGISTERS
, DRM_READ_ONLY
,
325 &pMga
->registers
.handle
) < 0 ) {
327 "[drm] Could not add MMIO registers mapping\n" );
331 "[drm] Registers handle = 0x%08lx\n",
332 pMga
->registers
.handle
);
334 pMga
->status
.size
= SAREA_MAX
;
336 if ( drmAddMap( ctx
->drmFD
, 0, pMga
->status
.size
,
337 DRM_SHM
, DRM_READ_ONLY
| DRM_LOCKED
| DRM_KERNEL
,
338 &pMga
->status
.handle
) < 0 ) {
340 "[drm] Could not add status page mapping\n" );
344 "[drm] Status handle = 0x%08lx\n",
345 pMga
->status
.handle
);
347 if ( drmMap( ctx
->drmFD
,
350 &pMga
->status
.map
) < 0 ) {
352 "[agp] Could not map status page\n" );
356 "[agp] Status page mapped at 0x%08lx\n",
357 (unsigned long)pMga
->status
.map
);
362 static int MGADRIKernelInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
367 memset( &init
, 0, sizeof(drmMGAInit
) );
369 init
.func
= MGA_INIT_DMA
;
370 init
.sarea_priv_offset
= sizeof(XF86DRISAREARec
);
372 switch ( pMga
->Chipset
) {
373 case PCI_CHIP_MGAG550
:
374 case PCI_CHIP_MGAG400
:
375 init
.chipset
= MGA_CARD_TYPE_G400
;
377 case PCI_CHIP_MGAG200
:
378 case PCI_CHIP_MGAG200_PCI
:
379 init
.chipset
= MGA_CARD_TYPE_G200
;
385 init
.sgram
= 0; /* FIXME !pMga->HasSDRAM; */
391 init
.maccess
= MGA_MACCESS_PW16
;
394 init
.maccess
= MGA_MACCESS_PW32
;
397 fprintf( stderr
, "[mga] invalid bpp (%d)\n", ctx
->bpp
);
402 init
.fb_cpp
= ctx
->bpp
/ 8;
403 init
.front_offset
= pMga
->frontOffset
;
404 init
.front_pitch
= pMga
->frontPitch
/ init
.fb_cpp
;
405 init
.back_offset
= pMga
->backOffset
;
406 init
.back_pitch
= pMga
->backPitch
/ init
.fb_cpp
;
408 init
.depth_cpp
= ctx
->bpp
/ 8;
409 init
.depth_offset
= pMga
->depthOffset
;
410 init
.depth_pitch
= pMga
->depthPitch
/ init
.depth_cpp
;
412 init
.texture_offset
[0] = pMga
->textureOffset
;
413 init
.texture_size
[0] = pMga
->textureSize
;
415 init
.fb_offset
= ctx
->shared
.hFrameBuffer
;
416 init
.mmio_offset
= pMga
->registers
.handle
;
417 init
.status_offset
= pMga
->status
.handle
;
419 init
.warp_offset
= pMga
->warp
.handle
;
420 init
.primary_offset
= pMga
->primary
.handle
;
421 init
.buffers_offset
= pMga
->buffers
.handle
;
423 init
.texture_offset
[1] = pMga
->agpTextures
.handle
;
424 init
.texture_size
[1] = pMga
->agpTextures
.size
;
426 ret
= drmCommandWrite( ctx
->drmFD
, DRM_MGA_INIT
, &init
, sizeof(drmMGAInit
));
429 "[drm] Failed to initialize DMA! (%d)\n", ret
);
436 static void MGADRIIrqInit(struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
440 pMga
->irq
= drmGetInterruptFromBusID(ctx
->drmFD
,
445 fprintf(stderr
, "[drm] got IRQ %d\n", pMga
->irq
);
447 if((drmCtlInstHandler(ctx
->drmFD
, pMga
->irq
)) != 0)
450 "[drm] failure adding irq handler, "
451 "there is a device already using that irq\n"
452 "[drm] falling back to irq-free operation\n");
457 pMga
->reg_ien
= INREG( MGAREG_IEN
);
463 "[drm] dma control initialized, using IRQ %d\n",
467 static int MGADRIBuffersInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
469 pMga
->drmBuffers
= drmMapBufs( ctx
->drmFD
);
470 if ( !pMga
->drmBuffers
)
473 "[drm] Failed to map DMA buffers list\n" );
478 "[drm] Mapped %d DMA buffers\n",
479 pMga
->drmBuffers
->count
);
484 static int MGAMemoryInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
486 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
487 int bufferSize
= ((ctx
->shared
.virtualHeight
* width_bytes
489 & ~MGA_BUFFER_ALIGN
);
490 int depthSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
492 & ~MGA_BUFFER_ALIGN
);
495 pMga
->frontOffset
= 0;
496 pMga
->frontPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
499 "Using %d MB AGP aperture\n", pMga
->agpSize
);
501 "Using %d MB for vertex/indirect buffers\n", pMga
->buffers
.size
>>20);
503 "Using %d MB for AGP textures\n", pMga
->agpTextures
.size
>>20);
505 /* Front, back and depth buffers - everything else texture??
507 pMga
->textureSize
= ctx
->shared
.fbSize
- 2 * bufferSize
- depthSize
;
509 if (pMga
->textureSize
< 0)
512 l
= mylog2( pMga
->textureSize
/ MGA_NR_TEX_REGIONS
);
513 if ( l
< MGA_LOG_MIN_TEX_REGION_SIZE
)
514 l
= MGA_LOG_MIN_TEX_REGION_SIZE
;
516 /* Round the texture size up to the nearest whole number of
517 * texture regions. Again, be greedy about this, don't
520 pMga
->logTextureGranularity
= l
;
521 pMga
->textureSize
= (pMga
->textureSize
>> l
) << l
;
523 /* Set a minimum usable local texture heap size. This will fit
524 * two 256x256x32bpp textures.
526 if (pMga
->textureSize
< 512 * 1024) {
527 pMga
->textureOffset
= 0;
528 pMga
->textureSize
= 0;
531 /* Reserve space for textures */
532 pMga
->textureOffset
= ((ctx
->shared
.fbSize
- pMga
->textureSize
+
536 /* Reserve space for the shared depth
539 pMga
->depthOffset
= ((pMga
->textureOffset
- depthSize
+
542 pMga
->depthPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
544 pMga
->backOffset
= ((pMga
->depthOffset
- bufferSize
+
547 pMga
->backPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
551 "Will use back buffer at offset 0x%x\n",
554 "Will use depth buffer at offset 0x%x\n",
557 "Will use %d kb for textures at offset 0x%x\n",
558 pMga
->textureSize
/1024, pMga
->textureOffset
);
563 static int MGACheckDRMVersion( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
565 drmVersionPtr version
;
567 /* Check the MGA DRM version */
568 version
= drmGetVersion(ctx
->drmFD
);
570 if ( version
->version_major
!= 3 ||
571 version
->version_minor
< 0 ) {
572 /* incompatible drm version */
574 "[dri] MGADRIScreenInit failed because of a version mismatch.\n"
575 "[dri] mga.o kernel module version is %d.%d.%d but version 3.0.x is needed.\n"
576 "[dri] Disabling DRI.\n",
577 version
->version_major
,
578 version
->version_minor
,
579 version
->version_patchlevel
);
580 drmFreeVersion( version
);
583 drmFreeVersion( version
);
589 static void print_client_msg( MGADRIPtr pMGADRI
)
591 fprintf( stderr
, "chipset: %d\n", pMGADRI
->chipset
);
593 fprintf( stderr
, "width: %d\n", pMGADRI
->width
);
594 fprintf( stderr
, "height: %d\n", pMGADRI
->height
);
595 fprintf( stderr
, "mem: %d\n", pMGADRI
->mem
);
596 fprintf( stderr
, "cpp: %d\n", pMGADRI
->cpp
);
598 fprintf( stderr
, "agpMode: %d\n", pMGADRI
->agpMode
);
600 fprintf( stderr
, "frontOffset: %d\n", pMGADRI
->frontOffset
);
601 fprintf( stderr
, "frontPitch: %d\n", pMGADRI
->frontPitch
);
603 fprintf( stderr
, "backOffset: %d\n", pMGADRI
->backOffset
);
604 fprintf( stderr
, "backPitch: %d\n", pMGADRI
->backPitch
);
606 fprintf( stderr
, "depthOffset: %d\n", pMGADRI
->depthOffset
);
607 fprintf( stderr
, "depthPitch: %d\n", pMGADRI
->depthPitch
);
609 fprintf( stderr
, "textureOffset: %d\n", pMGADRI
->textureOffset
);
610 fprintf( stderr
, "textureSize: %d\n", pMGADRI
->textureSize
);
612 fprintf( stderr
, "logTextureGranularity: %d\n", pMGADRI
->logTextureGranularity
);
613 fprintf( stderr
, "logAgpTextureGranularity: %d\n", pMGADRI
->logAgpTextureGranularity
);
615 fprintf( stderr
, "agpTextureHandle: %u\n", (unsigned int)pMGADRI
->agpTextureOffset
);
616 fprintf( stderr
, "agpTextureSize: %u\n", (unsigned int)pMGADRI
->agpTextureSize
);
619 pMGADRI
->registers
.handle
= pMga
->registers
.handle
;
620 pMGADRI
->registers
.size
= pMga
->registers
.size
;
621 pMGADRI
->status
.handle
= pMga
->status
.handle
;
622 pMGADRI
->status
.size
= pMga
->status
.size
;
623 pMGADRI
->primary
.handle
= pMga
->primary
.handle
;
624 pMGADRI
->primary
.size
= pMga
->primary
.size
;
625 pMGADRI
->buffers
.handle
= pMga
->buffers
.handle
;
626 pMGADRI
->buffers
.size
= pMga
->buffers
.size
;
627 pMGADRI
->sarea_priv_offset
= sizeof(XF86DRISAREARec
);
631 static int MGAScreenInit( struct DRIDriverContextRec
*ctx
, MGAPtr pMga
)
638 /*assert(!ctx->IsClient);*/
641 int width_bytes
= (ctx
->shared
.virtualWidth
* ctx
->cpp
);
642 int maxy
= ctx
->shared
.fbSize
/ width_bytes
;
645 if (maxy
<= ctx
->shared
.virtualHeight
* 3) {
647 "Static buffer allocation failed -- "
648 "need at least %d kB video memory (have %d kB)\n",
649 (ctx
->shared
.virtualWidth
* ctx
->shared
.virtualHeight
*
650 ctx
->cpp
* 3 + 1023) / 1024,
651 ctx
->shared
.fbSize
/ 1024);
656 switch(pMga
->Chipset
) {
657 case PCI_CHIP_MGAG550
:
658 case PCI_CHIP_MGAG400
:
659 case PCI_CHIP_MGAG200
:
661 case PCI_CHIP_MGAG200_PCI
:
665 fprintf(stderr
, "[drm] Direct rendering only supported with G200/G400/G550 AGP\n");
670 "[drm] bpp: %d depth: %d\n",
671 ctx
->bpp
, ctx
->bpp
/* FIXME: depth */ );
673 if ( (ctx
->bpp
/ 8) != 2 &&
674 (ctx
->bpp
/ 8) != 4 ) {
676 "[dri] Direct rendering only supported in 16 and 32 bpp modes\n" );
680 ctx
->shared
.SAREASize
= SAREA_MAX
;
683 /* Note that drmOpen will try to load the kernel module, if needed. */
684 ctx
->drmFD
= drmOpen("mga", NULL
);
685 if (ctx
->drmFD
< 0) {
686 fprintf(stderr
, "[drm] drmOpen failed\n");
690 if ((err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
)) < 0) {
691 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
692 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
697 if (drmAddMap( ctx
->drmFD
,
699 ctx
->shared
.SAREASize
,
702 &ctx
->shared
.hSAREA
) < 0)
704 fprintf(stderr
, "[drm] drmAddMap failed\n");
707 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
708 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
710 if (drmMap( ctx
->drmFD
,
712 ctx
->shared
.SAREASize
,
713 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
715 fprintf(stderr
, "[drm] drmMap failed\n");
718 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
719 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
720 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
722 /* Need to AddMap the framebuffer and mmio regions here:
724 if (drmAddMap( ctx
->drmFD
,
725 (drmHandle
)ctx
->FBStart
,
729 &ctx
->shared
.hFrameBuffer
) < 0)
731 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
734 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
735 ctx
->shared
.hFrameBuffer
);
738 #if 0 /* will be done in MGADRIMapInit */
739 if (drmAddMap(ctx
->drmFD
,
740 ctx
->FixedInfo
.mmio_start
,
741 ctx
->FixedInfo
.mmio_len
,
744 &pMga
->registers
.handle
) < 0) {
745 fprintf(stderr
, "[drm] drmAddMap mmio failed\n");
749 "[drm] register handle = 0x%08lx\n", pMga
->registers
.handle
);
753 /* Check the mga DRM version */
754 if (!MGACheckDRMVersion(ctx
, pMga
)) {
758 if ( !MGADRIAgpInit( ctx
, pMga
) ) {
762 if ( !MGADRIMapInit( ctx
, pMga
) ) {
766 /* Memory manager setup */
767 if (!MGAMemoryInit(ctx
, pMga
)) {
772 /* Create a 'server' context so we can grab the lock for
773 * initialization ioctls.
775 if ((err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
)) != 0) {
776 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
780 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
782 /* Initialize the kernel data structures */
783 if (!MGADRIKernelInit(ctx
, pMga
)) {
784 fprintf(stderr
, "MGADRIKernelInit failed\n");
785 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
789 /* Initialize the vertex buffers list */
790 if (!MGADRIBuffersInit(ctx
, pMga
)) {
791 fprintf(stderr
, "MGADRIBuffersInit failed\n");
792 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
797 MGADRIIrqInit(ctx
, pMga
);
800 /* Initialize the SAREA private data structure */
802 MGASAREAPrivPtr pSAREAPriv
;
803 pSAREAPriv
= (MGASAREAPrivPtr
)(((char*)ctx
->pSAREA
) +
804 sizeof(XF86DRISAREARec
));
805 memset(pSAREAPriv
, 0, sizeof(*pSAREAPriv
));
808 /* Quick hack to clear the front & back buffers. Could also use
809 * the clear ioctl to do this, but would need to setup hw state
812 memset((char *)ctx
->FBAddress
+ pMga
->frontOffset
,
814 pMga
->frontPitch
* ctx
->shared
.virtualHeight
);
816 memset((char *)ctx
->FBAddress
+ pMga
->backOffset
,
818 pMga
->backPitch
* ctx
->shared
.virtualHeight
);
820 /* Can release the lock now */
821 /* DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);*/
823 /* This is the struct passed to radeon_dri.so for its initialization */
824 ctx
->driverClientMsg
= malloc(sizeof(MGADRIRec
));
825 ctx
->driverClientMsgSize
= sizeof(MGADRIRec
);
827 pMGADRI
= (MGADRIPtr
)ctx
->driverClientMsg
;
830 switch(pMga
->Chipset
) {
831 case PCI_CHIP_MGAG550
:
832 case PCI_CHIP_MGAG400
:
833 pMGADRI
->chipset
= MGA_CARD_TYPE_G400
;
835 case PCI_CHIP_MGAG200
:
836 case PCI_CHIP_MGAG200_PCI
:
837 pMGADRI
->chipset
= MGA_CARD_TYPE_G200
;
842 pMGADRI
->width
= ctx
->shared
.virtualWidth
;
843 pMGADRI
->height
= ctx
->shared
.virtualHeight
;
844 pMGADRI
->mem
= ctx
->shared
.fbSize
;
845 pMGADRI
->cpp
= ctx
->bpp
/ 8;
847 pMGADRI
->agpMode
= pMga
->agpMode
;
849 pMGADRI
->frontOffset
= pMga
->frontOffset
;
850 pMGADRI
->frontPitch
= pMga
->frontPitch
;
851 pMGADRI
->backOffset
= pMga
->backOffset
;
852 pMGADRI
->backPitch
= pMga
->backPitch
;
853 pMGADRI
->depthOffset
= pMga
->depthOffset
;
854 pMGADRI
->depthPitch
= pMga
->depthPitch
;
855 pMGADRI
->textureOffset
= pMga
->textureOffset
;
856 pMGADRI
->textureSize
= pMga
->textureSize
;
857 pMGADRI
->logTextureGranularity
= pMga
->logTextureGranularity
;
859 i
= mylog2( pMga
->agpTextures
.size
/ MGA_NR_TEX_REGIONS
);
860 if ( i
< MGA_LOG_MIN_TEX_REGION_SIZE
)
861 i
= MGA_LOG_MIN_TEX_REGION_SIZE
;
863 pMGADRI
->logAgpTextureGranularity
= i
;
864 pMGADRI
->agpTextureOffset
= (unsigned int)pMga
->agpTextures
.handle
;
865 pMGADRI
->agpTextureSize
= (unsigned int)pMga
->agpTextures
.size
;
867 pMGADRI
->registers
.handle
= pMga
->registers
.handle
;
868 pMGADRI
->registers
.size
= pMga
->registers
.size
;
869 pMGADRI
->status
.handle
= pMga
->status
.handle
;
870 pMGADRI
->status
.size
= pMga
->status
.size
;
871 pMGADRI
->primary
.handle
= pMga
->primary
.handle
;
872 pMGADRI
->primary
.size
= pMga
->primary
.size
;
873 pMGADRI
->buffers
.handle
= pMga
->buffers
.handle
;
874 pMGADRI
->buffers
.size
= pMga
->buffers
.size
;
875 pMGADRI
->sarea_priv_offset
= sizeof(XF86DRISAREARec
);
877 print_client_msg( pMGADRI
);
884 * \brief Establish the set of modes available for the display.
886 * \param ctx display handle.
887 * \param numModes will receive the number of supported modes.
888 * \param modes will point to the list of supported modes.
890 * \return one on success, or zero on failure.
892 * Allocates a single visual and fills it with information according to the
893 * display bit depth. Supports only 16 and 32 bpp bit depths, aborting
896 const __GLcontextModes __glModes
[] = {
898 /* 32 bit, RGBA Depth=24 Stencil=8 */
899 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
900 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_TRUE
,
901 .redBits
= 8, .greenBits
= 8, .blueBits
= 8, .alphaBits
= 8,
902 .redMask
= 0xff0000, .greenMask
= 0xff00, .blueMask
= 0xff, .alphaMask
= 0xff000000,
903 .rgbBits
= 32, .indexBits
= 0,
904 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
905 .depthBits
= 24, .stencilBits
= 8,
906 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
908 /* 16 bit, RGB Depth=16 */
909 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
910 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_FALSE
,
911 .redBits
= 5, .greenBits
= 6, .blueBits
= 5, .alphaBits
= 0,
912 .redMask
= 0xf800, .greenMask
= 0x07e0, .blueMask
= 0x001f, .alphaMask
= 0x0,
913 .rgbBits
= 16, .indexBits
= 0,
914 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
915 .depthBits
= 16, .stencilBits
= 0,
916 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
918 static int mgaInitContextModes( const DRIDriverContext
*ctx
,
919 int *numModes
, const __GLcontextModes
**modes
)
921 *numModes
= sizeof(__glModes
)/sizeof(__GLcontextModes
*);
922 *modes
= &__glModes
[0];
928 * \brief Validate the fbdev mode.
930 * \param ctx display handle.
932 * \return one on success, or zero on failure.
934 * Saves some registers and returns 1.
936 * \sa mgaValidateMode().
938 static int mgaValidateMode( const DRIDriverContext
*ctx
)
945 * \brief Examine mode returned by fbdev.
947 * \param ctx display handle.
949 * \return one on success, or zero on failure.
951 * Restores registers that fbdev has clobbered and returns 1.
953 * \sa mgaValidateMode().
955 static int mgaPostValidateMode( const DRIDriverContext
*ctx
)
962 * \brief Initialize the framebuffer device mode
964 * \param ctx display handle.
966 * \return one on success, or zero on failure.
968 * Fills in \p info with some default values and some information from \p ctx
969 * and then calls MGAScreenInit() for the screen initialization.
971 * Before exiting clears the framebuffer memomry accessing it directly.
973 static int mgaInitFBDev( struct DRIDriverContextRec
*ctx
)
975 MGAPtr pMga
= calloc(1, sizeof(*pMga
));
978 int dummy
= ctx
->shared
.virtualWidth
;
980 switch (ctx
->bpp
/ 8) {
981 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
982 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 31) & ~31; break;
984 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 15) & ~15; break;
987 ctx
->shared
.virtualWidth
= dummy
;
990 ctx
->driverPrivate
= (void *)pMga
;
992 pMga
->agpMode
= MGA_DEFAULT_AGP_MODE
;
993 pMga
->agpSize
= MGA_DEFAULT_AGP_SIZE
;
995 pMga
->Chipset
= ctx
->chipset
;
997 pMga
->IOAddress
= ctx
->MMIOStart
;
998 pMga
->IOBase
= ctx
->MMIOAddress
;
1000 pMga
->frontPitch
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
1002 if (!MGAScreenInit( ctx
, pMga
))
1010 * \brief The screen is being closed, so clean up any state and free any
1011 * resources used by the DRI.
1013 * \param ctx display handle.
1015 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1018 static void mgaHaltFBDev( struct DRIDriverContextRec
*ctx
)
1020 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
1021 drmClose(ctx
->drmFD
);
1023 if (ctx
->driverPrivate
) {
1024 free(ctx
->driverPrivate
);
1025 ctx
->driverPrivate
= NULL
;
1030 static int mgaEngineShutdown( const DRIDriverContext
*ctx
)
1032 fprintf(stderr
, "%s() is not yet implemented!\n", __FUNCTION__
);
1037 static int mgaEngineRestore( const DRIDriverContext
*ctx
)
1039 fprintf(stderr
, "%s() is not yet implemented!\n", __FUNCTION__
);
1045 * \brief Exported driver interface for Mini GLX.
1049 struct DRIDriverRec __driDriver
= {
1050 mgaInitContextModes
,
1052 mgaPostValidateMode
,
1064 void MGADRICloseScreen( ScreenPtr pScreen
)
1066 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
1067 MGAPtr pMga
= MGAPTR(pScrn
);
1068 MGADRIServerPrivatePtr pMga
= pMga
->DRIServerInfo
;
1071 if ( pMga
->drmBuffers
) {
1072 drmUnmapBufs( pMga
->drmBuffers
);
1073 pMga
->drmBuffers
= NULL
;
1077 drmCtlUninstHandler(ctx
->drmFD
);
1082 memset( &init
, 0, sizeof(drmMGAInit
) );
1083 init
.func
= MGA_CLEANUP_DMA
;
1084 drmCommandWrite( ctx
->drmFD
, DRM_MGA_INIT
, &init
, sizeof(drmMGAInit
) );
1086 if ( pMga
->status
.map
) {
1087 drmUnmap( pMga
->status
.map
, pMga
->status
.size
);
1088 pMga
->status
.map
= NULL
;
1090 if ( pMga
->buffers
.map
) {
1091 drmUnmap( pMga
->buffers
.map
, pMga
->buffers
.size
);
1092 pMga
->buffers
.map
= NULL
;
1094 if ( pMga
->primary
.map
) {
1095 drmUnmap( pMga
->primary
.map
, pMga
->primary
.size
);
1096 pMga
->primary
.map
= NULL
;
1098 if ( pMga
->warp
.map
) {
1099 drmUnmap( pMga
->warp
.map
, pMga
->warp
.size
);
1100 pMga
->warp
.map
= NULL
;
1103 if ( pMga
->agpTextures
.map
) {
1104 drmUnmap( pMga
->agpTextures
.map
, pMga
->agpTextures
.size
);
1105 pMga
->agpTextures
.map
= NULL
;
1108 if ( pMga
->agp
.handle
) {
1109 drmAgpUnbind( ctx
->drmFD
, pMga
->agp
.handle
);
1110 drmAgpFree( ctx
->drmFD
, pMga
->agp
.handle
);
1111 pMga
->agp
.handle
= 0;
1112 drmAgpRelease( ctx
->drmFD
);
1115 DRICloseScreen( pScreen
);
1117 if ( pMga
->pDRIInfo
) {
1118 if ( pMga
->pDRIpMga
->devPrivate
) {
1119 xfree( pMga
->pDRIpMga
->devPrivate
);
1120 pMga
->pDRIpMga
->devPrivate
= 0;
1122 DRIDestroyInfoRec( pMga
->pDRIInfo
);
1125 if ( pMga
->DRIServerInfo
) {
1126 xfree( pMga
->DRIServerInfo
);
1127 pMga
->DRIServerInfo
= 0;
1129 if ( pMga
->pVisualConfigs
) {
1130 xfree( pMga
->pVisualConfigs
);
1132 if ( pMga
->pVisualConfigsPriv
) {
1133 xfree( pMga
->pVisualConfigsPriv
);