2 * \file server/i810_dri.c
3 * \brief File to perform the device-specific initialization tasks typically
4 * done in the X server.
6 * Here they are converted to run in the client (or perhaps a standalone
7 * process), and to work with the frame buffer device rather than the X
8 * server infrastructure.
10 * Copyright (C) 2004 Dave Airlie (airlied@linux.ie)
27 static int i810_pitches
[] = {
35 static int i810_pitch_flags
[] = {
43 static unsigned int i810_drm_version
= 0;
46 I810AllocLow(I810MemRange
* result
, I810MemRange
* pool
, int size
)
48 if (size
> pool
->Size
)
53 result
->Start
= pool
->Start
;
54 result
->End
= pool
->Start
+= size
;
60 I810AllocHigh(I810MemRange
* result
, I810MemRange
* pool
, int size
)
62 if (size
> pool
->Size
)
67 result
->End
= pool
->End
;
68 result
->Start
= pool
->End
-= size
;
75 * \brief Wait for free FIFO entries.
77 * \param ctx display handle.
78 * \param entries number of free entries to wait.
80 * It polls the free entries from the chip until it reaches the requested value
81 * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
83 static void I810WaitForFifo( const DRIDriverContext
*ctx
,
89 * \brief Reset graphics card to known state.
91 * \param ctx display handle.
93 * Resets the values of several I810 registers.
95 static void I810EngineReset( const DRIDriverContext
*ctx
)
97 unsigned char *I810MMIO
= ctx
->MMIOAddress
;
101 * \brief Restore the drawing engine.
103 * \param ctx display handle
105 * Resets the graphics card and sets initial values for several registers of
106 * the card's drawing engine.
108 * Turns on the i810 command processor engine (i.e., the ringbuffer).
110 static int I810EngineRestore( const DRIDriverContext
*ctx
)
112 I810Ptr info
= ctx
->driverPrivate
;
113 unsigned char *I810MMIO
= ctx
->MMIOAddress
;
115 fprintf(stderr
, "%s\n", __FUNCTION__
);
122 * \brief Shutdown the drawing engine.
124 * \param ctx display handle
126 * Turns off the command processor engine & restores the graphics card
127 * to a state that fbdev understands.
129 static int I810EngineShutdown( const DRIDriverContext
*ctx
)
134 memset(&info
, 0, sizeof(drmI810Init
));
135 info
.func
= I810_CLEANUP_DMA
;
137 ret
= drmCommandWrite(ctx
->drmFD
, DRM_I810_INIT
, &info
, sizeof(drmI810Init
));
140 fprintf(stderr
,"[dri] I810 DMA Cleanup failed\n");
147 * \brief Compute base 2 logarithm.
151 * \return base 2 logarithm of \p val.
153 static int I810MinBits(int val
)
158 for (bits
= 0; val
; val
>>= 1, ++bits
);
162 static int I810DRIAgpPreInit( const DRIDriverContext
*ctx
, I810Ptr info
)
165 if (drmAgpAcquire(ctx
->drmFD
) < 0) {
166 fprintf(stderr
, "[gart] AGP not available\n");
171 if (drmAgpEnable(ctx
->drmFD
, 0) < 0) {
172 fprintf(stderr
, "[gart] AGP not enabled\n");
173 drmAgpRelease(ctx
->drmFD
);
179 * \brief Initialize the AGP state
181 * \param ctx display handle.
182 * \param info driver private data.
184 * \return one on success, or zero on failure.
186 * Acquires and enables the AGP device. Reserves memory in the AGP space for
187 * the ring buffer, vertex buffers and textures. Initialize the I810
188 * registers to point to that memory and add client mappings.
190 static int I810DRIAgpInit( const DRIDriverContext
*ctx
, I810Ptr info
)
192 unsigned char *I810MMIO
= ctx
->MMIOAddress
;
195 unsigned long dcacheHandle
;
196 unsigned long agpHandle
;
200 int width
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
203 info
->backHandle
= DRM_AGP_NO_HANDLE
;
204 info
->zHandle
= DRM_AGP_NO_HANDLE
;
205 info
->sysmemHandle
= DRM_AGP_NO_HANDLE
;
206 info
->dcacheHandle
= DRM_AGP_NO_HANDLE
;
208 memset(&info
->DcacheMem
, 0, sizeof(I810MemRange
));
209 memset(&info
->BackBuffer
, 0, sizeof(I810MemRange
));
210 memset(&info
->DepthBuffer
, 0, sizeof(I810MemRange
));
212 drmAgpAlloc(ctx
->drmFD
, 4096 * 1024, 1, NULL
, &dcacheHandle
);
213 info
->dcacheHandle
= dcacheHandle
;
215 fprintf(stderr
, "[agp] dcacheHandle : 0x%x\n", dcacheHandle
);
217 #define Elements(x) sizeof(x)/sizeof(*x)
218 for (pitch_idx
= 0; pitch_idx
< Elements(i810_pitches
); pitch_idx
++)
219 if (width
<= i810_pitches
[pitch_idx
])
222 if (pitch_idx
== Elements(i810_pitches
)) {
223 fprintf(stderr
,"[dri] Couldn't find depth/back buffer pitch\n");
228 int lines
= (ctx
->shared
.virtualWidth
+ 15) / 16 * 16;
229 back_size
= i810_pitches
[pitch_idx
] * lines
;
230 back_size
= ((back_size
+ 4096 - 1) / 4096) * 4096;
233 sysmem_size
= ctx
->shared
.fbSize
;
234 fprintf(stderr
,"sysmem_size is %lu back_size is %lu\n", sysmem_size
, back_size
);
235 if (dcacheHandle
!= DRM_AGP_NO_HANDLE
) {
236 if (back_size
> 4 * 1024 * 1024) {
237 fprintf(stderr
,"[dri] Backsize is larger then 4 meg\n");
238 sysmem_size
= sysmem_size
- 2 * back_size
;
239 drmAgpFree(ctx
->drmFD
, dcacheHandle
);
240 info
->dcacheHandle
= dcacheHandle
= DRM_AGP_NO_HANDLE
;
242 sysmem_size
= sysmem_size
- back_size
;
245 sysmem_size
= sysmem_size
- 2 * back_size
;
248 info
->SysMem
.Start
=0;
249 info
->SysMem
.Size
= sysmem_size
;
250 info
->SysMem
.End
= sysmem_size
;
252 if (dcacheHandle
!= DRM_AGP_NO_HANDLE
) {
253 if (drmAgpBind(ctx
->drmFD
, dcacheHandle
, info
->DepthOffset
) == 0) {
254 memset(&info
->DcacheMem
, 0, sizeof(I810MemRange
));
255 fprintf(stderr
,"[agp] GART: Found 4096K Z buffer memory\n");
256 info
->DcacheMem
.Start
= info
->DepthOffset
;
257 info
->DcacheMem
.Size
= 1024 * 4096;
258 info
->DcacheMem
.End
= info
->DcacheMem
.Start
+ info
->DcacheMem
.Size
;
260 fprintf(stderr
, "[agp] GART: dcache bind failed\n");
261 drmAgpFree(ctx
->drmFD
, dcacheHandle
);
262 info
->dcacheHandle
= dcacheHandle
= DRM_AGP_NO_HANDLE
;
265 fprintf(stderr
, "[agp] GART: no dcache memory found\n");
268 drmAgpAlloc(ctx
->drmFD
, back_size
, 0, NULL
, &agpHandle
);
269 info
->backHandle
= agpHandle
;
271 if (agpHandle
!= DRM_AGP_NO_HANDLE
) {
272 if (drmAgpBind(ctx
->drmFD
, agpHandle
, info
->BackOffset
) == 0) {
273 fprintf(stderr
, "[agp] Bound backbuffer memory\n");
275 info
->BackBuffer
.Start
= info
->BackOffset
;
276 info
->BackBuffer
.Size
= back_size
;
277 info
->BackBuffer
.End
= (info
->BackBuffer
.Start
+
278 info
->BackBuffer
.Size
);
280 fprintf(stderr
,"[agp] Unable to bind backbuffer. Disabling DRI.\n");
284 fprintf(stderr
, "[dri] Unable to allocate backbuffer memory. Disabling DRI.\n");
288 if (dcacheHandle
== DRM_AGP_NO_HANDLE
) {
289 drmAgpAlloc(ctx
->drmFD
, back_size
, 0, NULL
, &agpHandle
);
291 info
->zHandle
= agpHandle
;
293 if (agpHandle
!= DRM_AGP_NO_HANDLE
) {
294 if (drmAgpBind(ctx
->drmFD
, agpHandle
, info
->DepthOffset
) == 0) {
295 fprintf(stderr
,"[agp] Bound depthbuffer memory\n");
296 info
->DepthBuffer
.Start
= info
->DepthOffset
;
297 info
->DepthBuffer
.Size
= back_size
;
298 info
->DepthBuffer
.End
= (info
->DepthBuffer
.Start
+
299 info
->DepthBuffer
.Size
);
301 fprintf(stderr
,"[agp] Unable to bind depthbuffer. Disabling DRI.\n");
305 fprintf(stderr
,"[agp] Unable to allocate depthbuffer memory. Disabling DRI.\n");
310 /* Now allocate and bind the agp space. This memory will include the
311 * regular framebuffer as well as texture memory.
313 drmAgpAlloc(ctx
->drmFD
, sysmem_size
, 0, NULL
, &agpHandle
);
314 info
->sysmemHandle
= agpHandle
;
316 if (agpHandle
!= DRM_AGP_NO_HANDLE
) {
317 if (drmAgpBind(ctx
->drmFD
, agpHandle
, 0) == 0) {
318 fprintf(stderr
, "[agp] Bound System Texture Memory\n");
320 fprintf(stderr
, "[agp] Unable to bind system texture memory. Disabling DRI.\n");
324 fprintf(stderr
, "[agp] Unable to allocate system texture memory. Disabling DRI.\n");
328 info
->auxPitch
= i810_pitches
[pitch_idx
];
329 info
->auxPitchBits
= i810_pitch_flags
[pitch_idx
];
336 * \brief Initialize the kernel data structures and enable the CP engine.
338 * \param ctx display handle.
339 * \param info driver private data.
341 * \return non-zero on success, or zero on failure.
343 * This function is a wrapper around the DRM_I810_CP_INIT command, passing
344 * all the parameters in a drmI810Init structure.
346 static int I810DRIKernelInit( const DRIDriverContext
*ctx
,
349 int cpp
= ctx
->bpp
/ 8;
352 I810RingBuffer
*ring
= &(info
->LpRing
);
354 /* This is the struct passed to the kernel module for its initialization */
355 memset(&drmInfo
, 0, sizeof(drmI810Init
));
357 /* make sure we have at least 1.4 */
358 drmInfo
.func
= I810_INIT_DMA_1_4
;
360 drmInfo
.ring_start
= ring
->mem
.Start
;
361 drmInfo
.ring_end
= ring
->mem
.End
;
362 drmInfo
.ring_size
= ring
->mem
.Size
;
364 drmInfo
.mmio_offset
= (unsigned int)info
->regs
;
365 drmInfo
.buffers_offset
= (unsigned int)info
->buffer_map
;
366 drmInfo
.sarea_priv_offset
= sizeof(drm_sarea_t
);
368 drmInfo
.front_offset
= 0;
369 drmInfo
.back_offset
= info
->BackBuffer
.Start
;
370 drmInfo
.depth_offset
= info
->DepthBuffer
.Start
;
372 drmInfo
.w
= ctx
->shared
.virtualWidth
;
373 drmInfo
.h
= ctx
->shared
.virtualHeight
;
374 drmInfo
.pitch
= info
->auxPitch
;
375 drmInfo
.pitch_bits
= info
->auxPitchBits
;
378 ret
= drmCommandWrite(ctx
->drmFD
, DRM_I810_INIT
, &drmInfo
,
379 sizeof(drmI810Init
));
386 * \brief Add a map for the vertex buffers that will be accessed by any
389 * \param ctx display handle.
390 * \param info driver private data.
392 * \return one on success, or zero on failure.
394 * Calls drmAddBufs() with the previously allocated vertex buffers.
396 static int I810DRIBufInit( const DRIDriverContext
*ctx
, I810Ptr info
)
398 /* Initialize vertex buffers */
399 info
->bufNumBufs
= drmAddBufs(ctx
->drmFD
,
403 info
->BufferMem
.Start
);
405 if (info
->bufNumBufs
<= 0) {
407 "[drm] Could not create vertex/indirect buffers list\n");
411 "[drm] Added %d %d byte vertex/indirect buffers\n",
412 info
->bufNumBufs
, I810_DMA_BUF_SZ
);
418 * \brief Install an IRQ handler.
420 * \param ctx display handle.
421 * \param info driver private data.
423 * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
424 * IRQ-free operation on failure.
426 static void I810DRIIrqInit(const DRIDriverContext
*ctx
,
430 info
->irq
= drmGetInterruptFromBusID(ctx
->drmFD
,
435 if ((drmCtlInstHandler(ctx
->drmFD
, info
->irq
)) != 0) {
437 "[drm] failure adding irq handler, "
438 "there is a device already using that irq\n"
439 "[drm] falling back to irq-free operation\n");
446 "[drm] dma control initialized, using IRQ %d\n",
450 static int I810CheckDRMVersion( const DRIDriverContext
*ctx
,
453 drmVersionPtr version
;
455 version
= drmGetVersion(ctx
->drmFD
);
457 int req_minor
, req_patch
;
462 i810_drm_version
= (version
->version_major
<<16) | version
->version_minor
;
463 if (version
->version_major
!= 1 ||
464 version
->version_minor
< req_minor
||
465 (version
->version_minor
== req_minor
&&
466 version
->version_patchlevel
< req_patch
)) {
467 /* Incompatible drm version */
469 "[dri] I810DRIScreenInit failed because of a version "
471 "[dri] i810.o kernel module version is %d.%d.%d "
472 "but version 1.%d.%d or newer is needed.\n"
473 "[dri] Disabling DRI.\n",
474 version
->version_major
,
475 version
->version_minor
,
476 version
->version_patchlevel
,
479 drmFreeVersion(version
);
483 info
->drmMinor
= version
->version_minor
;
484 drmFreeVersion(version
);
490 static int I810MemoryInit( const DRIDriverContext
*ctx
, I810Ptr info
)
492 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
494 int bufferSize
= (ctx
->shared
.virtualHeight
* width_bytes
);
495 int depthSize
= (((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
);
498 if (drmAddMap(ctx
->drmFD
, (drm_handle_t
) info
->BackBuffer
.Start
,
499 info
->BackBuffer
.Size
, DRM_AGP
, 0,
500 &info
->backbuffer
) < 0) {
501 fprintf(stderr
, "[drm] drmAddMap(backbuffer) failed. Disabling DRI\n");
505 if (drmAddMap(ctx
->drmFD
, (drm_handle_t
) info
->DepthBuffer
.Start
,
506 info
->DepthBuffer
.Size
, DRM_AGP
, 0,
507 &info
->depthbuffer
) < 0) {
508 fprintf(stderr
, "[drm] drmAddMap(depthbuffer) failed. Disabling DRI.\n");
512 if (!I810AllocLow(&(info
->FrontBuffer
), &(info
->SysMem
), (((ctx
->shared
.virtualHeight
* width_bytes
) + 4095) & ~4095)))
514 fprintf(stderr
,"Framebuffer allocation failed\n");
518 fprintf(stderr
,"Frame buffer at 0x%.8x (%luk, %lu bytes)\n",
519 info
->FrontBuffer
.Start
,
520 info
->FrontBuffer
.Size
/ 1024, info
->FrontBuffer
.Size
);
522 memset(&(info
->LpRing
), 0, sizeof(I810RingBuffer
));
523 if (I810AllocLow(&(info
->LpRing
.mem
), &(info
->SysMem
), 16 * 4096)) {
525 "Ring buffer at 0x%.8x (%luk, %lu bytes)\n",
526 info
->LpRing
.mem
.Start
,
527 info
->LpRing
.mem
.Size
/ 1024, info
->LpRing
.mem
.Size
);
529 info
->LpRing
.tail_mask
= info
->LpRing
.mem
.Size
- 1;
530 info
->LpRing
.virtual_start
= info
->LpRing
.mem
.Start
;
531 info
->LpRing
.head
= 0;
532 info
->LpRing
.tail
= 0;
533 info
->LpRing
.space
= 0;
535 fprintf(stderr
, "Ring buffer allocation failed\n");
539 /* Allocate buffer memory */
540 I810AllocHigh(&(info
->BufferMem
), &(info
->SysMem
),
541 I810_DMA_BUF_NR
* I810_DMA_BUF_SZ
);
544 fprintf(stderr
, "[dri] Buffer map : %lx\n",
545 info
->BufferMem
.Start
);
547 if (info
->BufferMem
.Start
== 0 ||
548 info
->BufferMem
.End
- info
->BufferMem
.Start
>
549 I810_DMA_BUF_NR
* I810_DMA_BUF_SZ
) {
550 fprintf(stderr
,"[dri] Not enough memory for dma buffers. Disabling DRI.\n");
554 if (drmAddMap(ctx
->drmFD
, (drm_handle_t
) info
->BufferMem
.Start
,
555 info
->BufferMem
.Size
, DRM_AGP
, 0, &info
->buffer_map
) < 0) {
556 fprintf(stderr
, "[drm] drmAddMap(buffer_map) failed. Disabling DRI.\n");
560 if (drmAddMap(ctx
->drmFD
, (drm_handle_t
) info
->LpRing
.mem
.Start
,
561 info
->LpRing
.mem
.Size
, DRM_AGP
, 0, &info
->ring_map
) < 0) {
562 fprintf(stderr
, "[drm] drmAddMap(ring_map) failed. Disabling DRI. \n");
566 /* Front, back and depth buffers - everything else texture??
568 info
->textureSize
= info
->SysMem
.Size
;
570 if (info
->textureSize
< 0)
574 l
= I810MinBits((info
->textureSize
-1) / I810_NR_TEX_REGIONS
);
575 if (l
< I810_LOG_MIN_TEX_REGION_SIZE
) l
= I810_LOG_MIN_TEX_REGION_SIZE
;
577 /* Round the texture size up to the nearest whole number of
578 * texture regions. Again, be greedy about this, don't
581 info
->logTextureGranularity
= l
;
582 info
->textureSize
= (info
->textureSize
>> l
) << l
;
584 /* Set a minimum usable local texture heap size. This will fit
585 * two 256x256x32bpp textures.
587 if (info
->textureSize
< 512 * 1024) {
588 info
->textureOffset
= 0;
589 info
->textureSize
= 0;
592 I810AllocLow(&(info
->TexMem
), &(info
->SysMem
), info
->textureSize
);
594 if (drmAddMap(ctx
->drmFD
, (drm_handle_t
) info
->TexMem
.Start
,
595 info
->TexMem
.Size
, DRM_AGP
, 0, &info
->textures
) < 0) {
597 "[drm] drmAddMap(textures) failed. Disabling DRI.\n");
601 /* Reserve space for textures */
603 "Will use back buffer at offset 0x%x\n",
606 "Will use depth buffer at offset 0x%x\n",
609 "Will use %d kb for textures at offset 0x%x\n",
610 info
->TexMem
.Size
/1024, info
->TexMem
.Start
);
618 * Called at the start of each server generation.
620 * \param ctx display handle.
621 * \param info driver private data.
623 * \return non-zero on success, or zero on failure.
625 * Performs static frame buffer allocation. Opens the DRM device and add maps
626 * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
627 * information. Creates a \e server context to grab the lock for the
628 * initialization ioctls and calls the other initilization functions in this
629 * file. Starts the CP engine via the DRM_I810_CP_START command.
631 * Setups a I810DRIRec structure to be passed to i810_dri.so for its
634 static int I810ScreenInit( DRIDriverContext
*ctx
, I810Ptr info
)
640 /*assert(!ctx->IsClient);*/
642 /* from XFree86 driver */
643 info
->DepthOffset
= 0x3000000;
644 info
->BackOffset
= 0x3800000;
646 int width_bytes
= (ctx
->shared
.virtualWidth
* ctx
->cpp
);
647 int maxy
= ctx
->shared
.fbSize
/ width_bytes
;
650 if (maxy
<= ctx
->shared
.virtualHeight
* 3) {
652 "Static buffer allocation failed -- "
653 "need at least %d kB video memory (have %d kB)\n",
654 (ctx
->shared
.virtualWidth
* ctx
->shared
.virtualHeight
*
655 ctx
->cpp
* 3 + 1023) / 1024,
656 ctx
->shared
.fbSize
/ 1024);
662 info
->regsSize
= ctx
->MMIOSize
;
663 ctx
->shared
.SAREASize
= 0x2000;
665 /* Note that drmOpen will try to load the kernel module, if needed. */
666 ctx
->drmFD
= drmOpen("i810", NULL
);
667 if (ctx
->drmFD
< 0) {
668 fprintf(stderr
, "[drm] drmOpen failed\n");
672 if ((err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
)) < 0) {
673 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
674 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
678 if (drmAddMap( ctx
->drmFD
,
680 ctx
->shared
.SAREASize
,
683 &ctx
->shared
.hSAREA
) < 0)
685 fprintf(stderr
, "[drm] drmAddMap failed\n");
688 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
689 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
691 if (drmMap( ctx
->drmFD
,
693 ctx
->shared
.SAREASize
,
694 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
696 fprintf(stderr
, "[drm] drmMap failed\n");
699 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
700 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
701 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
703 if (drmAddMap(ctx
->drmFD
,
709 fprintf(stderr
, "[drm] drmAddMap mmio failed\n");
713 "[drm] register handle = 0x%08x\n", info
->regs
);
715 I810DRIAgpPreInit(ctx
, info
);
716 /* Need to AddMap the framebuffer and mmio regions here:
718 if (drmAddMap( ctx
->drmFD
,
719 (drm_handle_t
)ctx
->FBStart
,
727 &ctx
->shared
.hFrameBuffer
) < 0)
729 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
733 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
734 ctx
->shared
.hFrameBuffer
);
736 /* Check the i810 DRM version */
737 if (!I810CheckDRMVersion(ctx
, info
)) {
742 if (!I810DRIAgpInit(ctx
, info
)) {
747 /* Memory manager setup */
748 if (!I810MemoryInit(ctx
, info
)) {
752 /* Initialize the SAREA private data structure */
754 I810SAREAPtr pSAREAPriv
;
755 pSAREAPriv
= (I810SAREAPtr
)(((char*)ctx
->pSAREA
) +
756 sizeof(drm_sarea_t
));
757 memset(pSAREAPriv
, 0, sizeof(*pSAREAPriv
));
758 // pSAREAPriv->pf_enabled=1;
762 /* Create a 'server' context so we can grab the lock for
763 * initialization ioctls.
765 if ((err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
)) != 0) {
766 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
770 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
772 /* Initialize the vertex buffers list */
773 if (!I810DRIBufInit(ctx
, info
)) {
774 fprintf(stderr
, "I810DRIBufInit failed\n");
775 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
779 /* Initialize the kernel data structures */
780 if (!I810DRIKernelInit(ctx
, info
)) {
781 fprintf(stderr
, "I810DRIKernelInit failed\n");
782 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
787 I810DRIIrqInit(ctx
, info
);
789 /* Quick hack to clear the front & back buffers. Could also use
790 * the clear ioctl to do this, but would need to setup hw state
794 memset((char *)ctx
->FBAddress
,
796 info
->auxPitch
* ctx
->cpp
* ctx
->shared
.virtualHeight
);
798 memset((char *)info
->backbuffer
,
800 info
->auxPitch
* ctx
->cpp
* ctx
->shared
.virtualHeight
);
803 /* This is the struct passed to i810_dri.so for its initialization */
804 ctx
->driverClientMsg
= malloc(sizeof(I810DRIRec
));
805 ctx
->driverClientMsgSize
= sizeof(I810DRIRec
);
806 pI810DRI
= (I810DRIPtr
)ctx
->driverClientMsg
;
808 pI810DRI
->regs
= info
->regs
;
809 pI810DRI
->regsSize
= info
->regsSize
;
812 pI810DRI
->backbufferSize
= info
->BackBuffer
.Size
;
813 pI810DRI
->backbuffer
= info
->backbuffer
;
815 pI810DRI
->depthbufferSize
= info
->DepthBuffer
.Size
;
816 pI810DRI
->depthbuffer
= info
->depthbuffer
;
818 pI810DRI
->textures
= info
->textures
;
819 pI810DRI
->textureSize
= info
->textureSize
;
821 pI810DRI
->agp_buffers
= info
->buffer_map
;
822 pI810DRI
->agp_buf_size
= info
->BufferMem
.Size
;
824 pI810DRI
->deviceID
= info
->Chipset
;
825 pI810DRI
->width
= ctx
->shared
.virtualWidth
;
826 pI810DRI
->height
= ctx
->shared
.virtualHeight
;
827 pI810DRI
->mem
= ctx
->shared
.fbSize
;
828 pI810DRI
->cpp
= ctx
->bpp
/ 8;
829 pI810DRI
->bitsPerPixel
= ctx
->bpp
;
830 pI810DRI
->fbOffset
= info
->FrontBuffer
.Start
;
831 pI810DRI
->fbStride
= info
->auxPitch
;
833 pI810DRI
->backOffset
= info
->BackBuffer
.Start
;
834 pI810DRI
->depthOffset
= info
->DepthBuffer
.Start
;
836 pI810DRI
->auxPitch
= info
->auxPitch
;
837 pI810DRI
->auxPitchBits
= info
->auxPitchBits
;
839 pI810DRI
->logTextureGranularity
= info
->logTextureGranularity
;
840 pI810DRI
->textureOffset
= info
->TexMem
.Start
;
842 pI810DRI
->ringOffset
= info
->LpRing
.mem
.Start
;
843 pI810DRI
->ringSize
= info
->LpRing
.mem
.Size
;
845 // drmBufs looks unused
846 pI810DRI
->irq
= info
->irq
;
847 pI810DRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
849 /* Don't release the lock now - let the VT switch handler do it. */
855 * \brief Validate the fbdev mode.
857 * \param ctx display handle.
859 * \return one on success, or zero on failure.
861 * Saves some registers and returns 1.
863 * \sa i810ValidateMode().
865 static int i810ValidateMode( const DRIDriverContext
*ctx
)
867 unsigned char *I810MMIO
= ctx
->MMIOAddress
;
868 I810Ptr info
= ctx
->driverPrivate
;
875 * \brief Examine mode returned by fbdev.
877 * \param ctx display handle.
879 * \return one on success, or zero on failure.
881 * Restores registers that fbdev has clobbered and returns 1.
883 * \sa i810ValidateMode().
885 static int i810PostValidateMode( const DRIDriverContext
*ctx
)
887 unsigned char *I810MMIO
= ctx
->MMIOAddress
;
888 I810Ptr info
= ctx
->driverPrivate
;
895 * \brief Initialize the framebuffer device mode
897 * \param ctx display handle.
899 * \return one on success, or zero on failure.
901 * Fills in \p info with some default values and some information from \p ctx
902 * and then calls I810ScreenInit() for the screen initialization.
904 * Before exiting clears the framebuffer memory accessing it directly.
906 static int i810InitFBDev( DRIDriverContext
*ctx
)
908 I810Ptr info
= calloc(1, sizeof(*info
));
911 int dummy
= ctx
->shared
.virtualWidth
;
913 switch (ctx
->bpp
/ 8) {
914 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
915 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 31) & ~31; break;
917 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 15) & ~15; break;
920 ctx
->shared
.virtualWidth
= dummy
;
923 ctx
->driverPrivate
= (void *)info
;
925 info
->Chipset
= ctx
->chipset
;
927 if (!I810ScreenInit( ctx
, info
))
936 * \brief The screen is being closed, so clean up any state and free any
937 * resources used by the DRI.
939 * \param ctx display handle.
941 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
944 static void i810HaltFBDev( DRIDriverContext
*ctx
)
946 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
947 drmClose(ctx
->drmFD
);
949 if (ctx
->driverPrivate
) {
950 free(ctx
->driverPrivate
);
951 ctx
->driverPrivate
= 0;
956 extern void i810NotifyFocus( int );
959 * \brief Exported driver interface for Mini GLX.
963 const struct DRIDriverRec __driDriver
= {
965 i810PostValidateMode
,