2 * \file server/radeon_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.
21 #include "radeon_dri.h"
22 #include "radeon_macros.h"
23 #include "radeon_reg.h"
24 #include "drm_sarea.h"
27 /* HACK - for now, put this here... */
28 /* Alpha - this may need to be a variable to handle UP1x00 vs TITAN */
29 #if defined(__alpha__)
30 # define DRM_PAGE_SIZE 8192
31 #elif defined(__ia64__)
32 # define DRM_PAGE_SIZE getpagesize()
34 # define DRM_PAGE_SIZE 4096
39 * \brief Wait for free FIFO entries.
41 * \param ctx display handle.
42 * \param entries number of free entries to wait.
44 * It polls the free entries from the chip until it reaches the requested value
45 * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
47 static void RADEONWaitForFifo( const DRIDriverContext
*ctx
,
50 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
53 for (i
= 0; i
< 3000; i
++) {
55 INREG(RADEON_RBBM_STATUS
) & RADEON_RBBM_FIFOCNT_MASK
;
56 if (fifo_slots
>= entries
) return;
59 /* There are recoveries possible, but I haven't seen them work
62 fprintf(stderr
, "FIFO timed out: %d entries, stat=0x%08x\n",
63 INREG(RADEON_RBBM_STATUS
) & RADEON_RBBM_FIFOCNT_MASK
,
64 INREG(RADEON_RBBM_STATUS
));
69 * \brief Read a PLL register.
71 * \param ctx display handle.
72 * \param addr PLL register index.
74 * \return value of the PLL register.
76 static unsigned int RADEONINPLL( const DRIDriverContext
*ctx
, int addr
)
78 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
81 OUTREG8(RADEON_CLOCK_CNTL_INDEX
, addr
& 0x3f);
82 data
= INREG(RADEON_CLOCK_CNTL_DATA
);
88 * \brief Reset graphics card to known state.
90 * \param ctx display handle.
92 * Resets the values of several Radeon registers.
94 static void RADEONEngineReset( const DRIDriverContext
*ctx
)
96 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
97 unsigned int clock_cntl_index
;
98 unsigned int mclk_cntl
;
99 unsigned int rbbm_soft_reset
;
100 unsigned int host_path_cntl
;
103 OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT
,
104 RADEON_RB2D_DC_FLUSH_ALL
,
105 ~RADEON_RB2D_DC_FLUSH_ALL
);
106 for (i
= 0; i
< 512; i
++) {
107 if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT
) & RADEON_RB2D_DC_BUSY
))
111 clock_cntl_index
= INREG(RADEON_CLOCK_CNTL_INDEX
);
113 mclk_cntl
= INPLL(ctx
, RADEON_MCLK_CNTL
);
114 OUTPLL(RADEON_MCLK_CNTL
, (mclk_cntl
|
115 RADEON_FORCEON_MCLKA
|
116 RADEON_FORCEON_MCLKB
|
117 RADEON_FORCEON_YCLKA
|
118 RADEON_FORCEON_YCLKB
|
120 RADEON_FORCEON_AIC
));
122 /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
123 * unexpected behaviour on some machines. Here we use
124 * RADEON_HOST_PATH_CNTL to reset it.
126 host_path_cntl
= INREG(RADEON_HOST_PATH_CNTL
);
127 rbbm_soft_reset
= INREG(RADEON_RBBM_SOFT_RESET
);
129 OUTREG(RADEON_RBBM_SOFT_RESET
, (rbbm_soft_reset
|
130 RADEON_SOFT_RESET_CP
|
131 RADEON_SOFT_RESET_HI
|
132 RADEON_SOFT_RESET_SE
|
133 RADEON_SOFT_RESET_RE
|
134 RADEON_SOFT_RESET_PP
|
135 RADEON_SOFT_RESET_E2
|
136 RADEON_SOFT_RESET_RB
));
137 INREG(RADEON_RBBM_SOFT_RESET
);
138 OUTREG(RADEON_RBBM_SOFT_RESET
, (rbbm_soft_reset
&
139 (unsigned int) ~(RADEON_SOFT_RESET_CP
|
140 RADEON_SOFT_RESET_HI
|
141 RADEON_SOFT_RESET_SE
|
142 RADEON_SOFT_RESET_RE
|
143 RADEON_SOFT_RESET_PP
|
144 RADEON_SOFT_RESET_E2
|
145 RADEON_SOFT_RESET_RB
)));
146 INREG(RADEON_RBBM_SOFT_RESET
);
148 OUTREG(RADEON_HOST_PATH_CNTL
, host_path_cntl
| RADEON_HDP_SOFT_RESET
);
149 INREG(RADEON_HOST_PATH_CNTL
);
150 OUTREG(RADEON_HOST_PATH_CNTL
, host_path_cntl
);
152 OUTREG(RADEON_RBBM_SOFT_RESET
, rbbm_soft_reset
);
154 OUTREG(RADEON_CLOCK_CNTL_INDEX
, clock_cntl_index
);
155 OUTPLL(RADEON_MCLK_CNTL
, mclk_cntl
);
159 * \brief Restore the drawing engine.
161 * \param ctx display handle
163 * Resets the graphics card and sets initial values for several registers of
164 * the card's drawing engine.
166 * Turns on the radeon command processor engine (i.e., the ringbuffer).
168 static int RADEONEngineRestore( const DRIDriverContext
*ctx
)
170 RADEONInfoPtr info
= ctx
->driverPrivate
;
171 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
172 int pitch64
, datatype
, dp_gui_master_cntl
, err
;
174 fprintf(stderr
, "%s\n", __FUNCTION__
);
176 OUTREG(RADEON_RB3D_CNTL
, 0);
177 RADEONEngineReset( ctx
);
180 case 16: datatype
= 4; break;
181 case 32: datatype
= 6; break;
186 ((datatype
<< RADEON_GMC_DST_DATATYPE_SHIFT
)
187 | RADEON_GMC_CLR_CMP_CNTL_DIS
);
189 pitch64
= ((ctx
->shared
.virtualWidth
* (ctx
->bpp
/ 8) + 0x3f)) >> 6;
191 RADEONWaitForFifo(ctx
, 1);
192 OUTREG(RADEON_DEFAULT_OFFSET
, ((INREG(RADEON_DEFAULT_OFFSET
) & 0xC0000000)
195 RADEONWaitForFifo(ctx
, 1);
196 OUTREG(RADEON_SURFACE_CNTL
, RADEON_SURF_TRANSLATION_DIS
);
198 RADEONWaitForFifo(ctx
, 1);
199 OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT
, (RADEON_DEFAULT_SC_RIGHT_MAX
200 | RADEON_DEFAULT_SC_BOTTOM_MAX
));
202 RADEONWaitForFifo(ctx
, 1);
203 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, (dp_gui_master_cntl
204 | RADEON_GMC_BRUSH_SOLID_COLOR
205 | RADEON_GMC_SRC_DATATYPE_COLOR
));
207 RADEONWaitForFifo(ctx
, 7);
208 OUTREG(RADEON_DST_LINE_START
, 0);
209 OUTREG(RADEON_DST_LINE_END
, 0);
210 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, 0xffffffff);
211 OUTREG(RADEON_DP_BRUSH_BKGD_CLR
, 0);
212 OUTREG(RADEON_DP_SRC_FRGD_CLR
, 0xffffffff);
213 OUTREG(RADEON_DP_SRC_BKGD_CLR
, 0);
214 OUTREG(RADEON_DP_WRITE_MASK
, 0xffffffff);
215 OUTREG(RADEON_AUX_SC_CNTL
, 0);
217 /* RADEONWaitForIdleMMIO(ctx); */
221 OUTREG(RADEON_GEN_INT_CNTL
, info
->gen_int_cntl
);
222 OUTREG(RADEON_CRTC_OFFSET_CNTL
, info
->crtc_offset_cntl
);
225 /* Initialize and start the CP if required */
226 if ((err
= drmCommandNone(ctx
->drmFD
, DRM_RADEON_CP_START
)) != 0) {
227 fprintf(stderr
, "%s: CP start %d\n", __FUNCTION__
, err
);
236 * \brief Shutdown the drawing engine.
238 * \param ctx display handle
240 * Turns off the command processor engine & restores the graphics card
241 * to a state that fbdev understands.
243 static int RADEONEngineShutdown( const DRIDriverContext
*ctx
)
245 drm_radeon_cp_stop_t stop
;
251 ret
= drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_STOP
, &stop
,
252 sizeof(drm_radeon_cp_stop_t
));
256 } else if (errno
!= EBUSY
) {
264 ret
= drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_STOP
, &stop
,
265 sizeof(drm_radeon_cp_stop_t
));
266 } while (ret
&& errno
== EBUSY
&& i
++ < 10);
270 } else if (errno
!= EBUSY
) {
276 if (drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_STOP
,
277 &stop
, sizeof(drm_radeon_cp_stop_t
))) {
285 * \brief Compute base 2 logarithm.
289 * \return base 2 logarithm of \p val.
291 static int RADEONMinBits(int val
)
296 for (bits
= 0; val
; val
>>= 1, ++bits
);
301 * \brief Initialize the AGP state
303 * \param ctx display handle.
304 * \param info driver private data.
306 * \return one on success, or zero on failure.
308 * Acquires and enables the AGP device. Reserves memory in the AGP space for
309 * the ring buffer, vertex buffers and textures. Initialize the Radeon
310 * registers to point to that memory and add client mappings.
312 static int RADEONDRIAgpInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
314 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
319 if (drmAgpAcquire(ctx
->drmFD
) < 0) {
320 fprintf(stderr
, "[gart] AGP not available\n");
324 /* Modify the mode if the default mode is not appropriate for this
325 * particular combination of graphics card and AGP chipset.
327 mode
= drmAgpGetMode(ctx
->drmFD
); /* Default mode */
329 /* Disable fast write entirely - too many lockups.
331 mode
&= ~RADEON_AGP_MODE_MASK
;
332 switch (ctx
->agpmode
) {
333 case 4: mode
|= RADEON_AGP_4X_MODE
;
334 case 2: mode
|= RADEON_AGP_2X_MODE
;
335 case 1: default: mode
|= RADEON_AGP_1X_MODE
;
338 if (drmAgpEnable(ctx
->drmFD
, mode
) < 0) {
339 fprintf(stderr
, "[gart] AGP not enabled\n");
340 drmAgpRelease(ctx
->drmFD
);
344 fprintf(stderr
, "[gart] AGP enabled at %dx\n", ctx
->agpmode
);
346 /* Workaround for some hardware bugs */
347 if (info
->ChipFamily
< CHIP_FAMILY_R200
)
348 OUTREG(RADEON_AGP_CNTL
, INREG(RADEON_AGP_CNTL
) | 0x000e0000);
350 info
->gartOffset
= 0;
352 if ((ret
= drmAgpAlloc(ctx
->drmFD
, info
->gartSize
*1024*1024, 0, NULL
,
353 &info
->gartMemHandle
)) < 0) {
354 fprintf(stderr
, "[gart] Out of memory (%d)\n", ret
);
355 drmAgpRelease(ctx
->drmFD
);
359 "[gart] %d kB allocated with handle 0x%08x\n",
360 info
->gartSize
*1024, (unsigned)info
->gartMemHandle
);
362 if (drmAgpBind(ctx
->drmFD
,
363 info
->gartMemHandle
, info
->gartOffset
) < 0) {
364 fprintf(stderr
, "[gart] Could not bind\n");
365 drmAgpFree(ctx
->drmFD
, info
->gartMemHandle
);
366 drmAgpRelease(ctx
->drmFD
);
370 /* Initialize the CP ring buffer data */
371 info
->ringStart
= info
->gartOffset
;
372 info
->ringMapSize
= info
->ringSize
*1024*1024 + DRM_PAGE_SIZE
;
374 info
->ringReadOffset
= info
->ringStart
+ info
->ringMapSize
;
375 info
->ringReadMapSize
= DRM_PAGE_SIZE
;
377 /* Reserve space for vertex/indirect buffers */
378 info
->bufStart
= info
->ringReadOffset
+ info
->ringReadMapSize
;
379 info
->bufMapSize
= info
->bufSize
*1024*1024;
381 /* Reserve the rest for AGP textures */
382 info
->gartTexStart
= info
->bufStart
+ info
->bufMapSize
;
383 s
= (info
->gartSize
*1024*1024 - info
->gartTexStart
);
384 l
= RADEONMinBits((s
-1) / RADEON_NR_TEX_REGIONS
);
385 if (l
< RADEON_LOG_TEX_GRANULARITY
) l
= RADEON_LOG_TEX_GRANULARITY
;
386 info
->gartTexMapSize
= (s
>> l
) << l
;
387 info
->log2GARTTexGran
= l
;
389 if (drmAddMap(ctx
->drmFD
, info
->ringStart
, info
->ringMapSize
,
390 DRM_AGP
, DRM_READ_ONLY
, &info
->ringHandle
) < 0) {
391 fprintf(stderr
, "[gart] Could not add ring mapping\n");
394 fprintf(stderr
, "[gart] ring handle = 0x%08lx\n", info
->ringHandle
);
397 if (drmAddMap(ctx
->drmFD
, info
->ringReadOffset
, info
->ringReadMapSize
,
398 DRM_AGP
, DRM_READ_ONLY
, &info
->ringReadPtrHandle
) < 0) {
400 "[gart] Could not add ring read ptr mapping\n");
405 "[gart] ring read ptr handle = 0x%08lx\n",
406 info
->ringReadPtrHandle
);
408 if (drmAddMap(ctx
->drmFD
, info
->bufStart
, info
->bufMapSize
,
409 DRM_AGP
, 0, &info
->bufHandle
) < 0) {
411 "[gart] Could not add vertex/indirect buffers mapping\n");
415 "[gart] vertex/indirect buffers handle = 0x%08lx\n",
418 if (drmAddMap(ctx
->drmFD
, info
->gartTexStart
, info
->gartTexMapSize
,
419 DRM_AGP
, 0, &info
->gartTexHandle
) < 0) {
421 "[gart] Could not add AGP texture map mapping\n");
425 "[gart] AGP texture map handle = 0x%08lx\n",
426 info
->gartTexHandle
);
428 /* Initialize Radeon's AGP registers */
429 /* Ring buffer is at AGP offset 0 */
430 OUTREG(RADEON_AGP_BASE
, info
->ringHandle
);
437 * \brief Initialize the kernel data structures and enable the CP engine.
439 * \param ctx display handle.
440 * \param info driver private data.
442 * \return non-zero on success, or zero on failure.
444 * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
445 * all the parameters in a drm_radeon_init_t structure.
447 static int RADEONDRIKernelInit( const DRIDriverContext
*ctx
,
450 int cpp
= ctx
->bpp
/ 8;
451 drm_radeon_init_t drmInfo
;
454 memset(&drmInfo
, 0, sizeof(drm_radeon_init_t
));
456 if ( (info
->ChipFamily
== CHIP_FAMILY_R200
) ||
457 (info
->ChipFamily
== CHIP_FAMILY_RV250
) ||
458 (info
->ChipFamily
== CHIP_FAMILY_M9
) ||
459 (info
->ChipFamily
== CHIP_FAMILY_RV280
) )
460 drmInfo
.func
= RADEON_INIT_R200_CP
;
462 drmInfo
.func
= RADEON_INIT_CP
;
464 /* This is the struct passed to the kernel module for its initialization */
465 drmInfo
.sarea_priv_offset
= sizeof(drm_sarea_t
);
467 drmInfo
.cp_mode
= RADEON_DEFAULT_CP_BM_MODE
;
468 drmInfo
.gart_size
= info
->gartSize
*1024*1024;
469 drmInfo
.ring_size
= info
->ringSize
*1024*1024;
470 drmInfo
.usec_timeout
= 1000;
471 drmInfo
.fb_bpp
= ctx
->bpp
;
472 drmInfo
.depth_bpp
= ctx
->bpp
;
473 drmInfo
.front_offset
= info
->frontOffset
;
474 drmInfo
.front_pitch
= info
->frontPitch
* cpp
;
475 drmInfo
.back_offset
= info
->backOffset
;
476 drmInfo
.back_pitch
= info
->backPitch
* cpp
;
477 drmInfo
.depth_offset
= info
->depthOffset
;
478 drmInfo
.depth_pitch
= info
->depthPitch
* cpp
;
479 drmInfo
.fb_offset
= info
->LinearAddr
;
480 drmInfo
.mmio_offset
= info
->registerHandle
;
481 drmInfo
.ring_offset
= info
->ringHandle
;
482 drmInfo
.ring_rptr_offset
= info
->ringReadPtrHandle
;
483 drmInfo
.buffers_offset
= info
->bufHandle
;
484 drmInfo
.gart_textures_offset
= info
->gartTexHandle
;
486 ret
= drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_INIT
, &drmInfo
,
487 sizeof(drm_radeon_init_t
));
494 * \brief Initialize the AGP heap.
496 * \param ctx display handle.
497 * \param info driver private data.
499 * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
500 * all the parameters in a drm_radeon_mem_init_heap structure.
502 static void RADEONDRIAgpHeapInit(const DRIDriverContext
*ctx
,
505 drm_radeon_mem_init_heap_t drmHeap
;
507 /* Start up the simple memory manager for gart space */
508 drmHeap
.region
= RADEON_MEM_REGION_GART
;
510 drmHeap
.size
= info
->gartTexMapSize
;
512 if (drmCommandWrite(ctx
->drmFD
, DRM_RADEON_INIT_HEAP
,
513 &drmHeap
, sizeof(drmHeap
))) {
515 "[drm] Failed to initialized gart heap manager\n");
518 "[drm] Initialized kernel gart heap manager, %d\n",
519 info
->gartTexMapSize
);
524 * \brief Add a map for the vertex buffers that will be accessed by any
527 * \param ctx display handle.
528 * \param info driver private data.
530 * \return one on success, or zero on failure.
532 * Calls drmAddBufs() with the previously allocated vertex buffers.
534 static int RADEONDRIBufInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
536 /* Initialize vertex buffers */
537 info
->bufNumBufs
= drmAddBufs(ctx
->drmFD
,
538 info
->bufMapSize
/ RADEON_BUFFER_SIZE
,
543 if (info
->bufNumBufs
<= 0) {
545 "[drm] Could not create vertex/indirect buffers list\n");
549 "[drm] Added %d %d byte vertex/indirect buffers\n",
550 info
->bufNumBufs
, RADEON_BUFFER_SIZE
);
556 * \brief Install an IRQ handler.
558 * \param ctx display handle.
559 * \param info driver private data.
561 * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
562 * IRQ-free operation on failure.
564 static void RADEONDRIIrqInit(const DRIDriverContext
*ctx
,
568 info
->irq
= drmGetInterruptFromBusID(ctx
->drmFD
,
573 if ((drmCtlInstHandler(ctx
->drmFD
, info
->irq
)) != 0) {
575 "[drm] failure adding irq handler, "
576 "there is a device already using that irq\n"
577 "[drm] falling back to irq-free operation\n");
584 "[drm] dma control initialized, using IRQ %d\n",
588 static int RADEONCheckDRMVersion( const DRIDriverContext
*ctx
,
591 drmVersionPtr version
;
593 version
= drmGetVersion(ctx
->drmFD
);
595 int req_minor
, req_patch
;
597 /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
602 if (version
->version_major
!= 1 ||
603 version
->version_minor
< req_minor
||
604 (version
->version_minor
== req_minor
&&
605 version
->version_patchlevel
< req_patch
)) {
606 /* Incompatible drm version */
608 "[dri] RADEONDRIScreenInit failed because of a version "
610 "[dri] radeon.o kernel module version is %d.%d.%d "
611 "but version 1.%d.%d or newer is needed.\n"
612 "[dri] Disabling DRI.\n",
613 version
->version_major
,
614 version
->version_minor
,
615 version
->version_patchlevel
,
618 drmFreeVersion(version
);
622 info
->drmMinor
= version
->version_minor
;
623 drmFreeVersion(version
);
629 static int RADEONMemoryInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
631 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
633 int bufferSize
= ((ctx
->shared
.virtualHeight
* width_bytes
634 + RADEON_BUFFER_ALIGN
)
635 & ~RADEON_BUFFER_ALIGN
);
636 int depthSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
637 + RADEON_BUFFER_ALIGN
)
638 & ~RADEON_BUFFER_ALIGN
);
641 info
->frontOffset
= 0;
642 info
->frontPitch
= ctx
->shared
.virtualWidth
;
645 "Using %d MB AGP aperture\n", info
->gartSize
);
647 "Using %d MB for the ring buffer\n", info
->ringSize
);
649 "Using %d MB for vertex/indirect buffers\n", info
->bufSize
);
651 "Using %d MB for AGP textures\n", info
->gartTexSize
);
653 /* Front, back and depth buffers - everything else texture??
655 info
->textureSize
= ctx
->shared
.fbSize
- 2 * bufferSize
- depthSize
;
657 if (info
->textureSize
< 0)
660 l
= RADEONMinBits((info
->textureSize
-1) / RADEON_NR_TEX_REGIONS
);
661 if (l
< RADEON_LOG_TEX_GRANULARITY
) l
= RADEON_LOG_TEX_GRANULARITY
;
663 /* Round the texture size up to the nearest whole number of
664 * texture regions. Again, be greedy about this, don't
667 info
->log2TexGran
= l
;
668 info
->textureSize
= (info
->textureSize
>> l
) << l
;
670 /* Set a minimum usable local texture heap size. This will fit
671 * two 256x256x32bpp textures.
673 if (info
->textureSize
< 512 * 1024) {
674 info
->textureOffset
= 0;
675 info
->textureSize
= 0;
678 /* Reserve space for textures */
679 info
->textureOffset
= ((ctx
->shared
.fbSize
- info
->textureSize
+
680 RADEON_BUFFER_ALIGN
) &
681 ~RADEON_BUFFER_ALIGN
);
683 /* Reserve space for the shared depth
686 info
->depthOffset
= ((info
->textureOffset
- depthSize
+
687 RADEON_BUFFER_ALIGN
) &
688 ~RADEON_BUFFER_ALIGN
);
689 info
->depthPitch
= ctx
->shared
.virtualWidth
;
691 info
->backOffset
= ((info
->depthOffset
- bufferSize
+
692 RADEON_BUFFER_ALIGN
) &
693 ~RADEON_BUFFER_ALIGN
);
694 info
->backPitch
= ctx
->shared
.virtualWidth
;
698 "Will use back buffer at offset 0x%x\n",
701 "Will use depth buffer at offset 0x%x\n",
704 "Will use %d kb for textures at offset 0x%x\n",
705 info
->textureSize
/1024, info
->textureOffset
);
707 info
->frontPitchOffset
= (((info
->frontPitch
* cpp
/ 64) << 22) |
708 (info
->frontOffset
>> 10));
710 info
->backPitchOffset
= (((info
->backPitch
* cpp
/ 64) << 22) |
711 (info
->backOffset
>> 10));
713 info
->depthPitchOffset
= (((info
->depthPitch
* cpp
/ 64) << 22) |
714 (info
->depthOffset
>> 10));
722 * Called at the start of each server generation.
724 * \param ctx display handle.
725 * \param info driver private data.
727 * \return non-zero on success, or zero on failure.
729 * Performs static frame buffer allocation. Opens the DRM device and add maps
730 * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
731 * information. Creates a \e server context to grab the lock for the
732 * initialization ioctls and calls the other initilization functions in this
733 * file. Starts the CP engine via the DRM_RADEON_CP_START command.
735 * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
738 static int RADEONScreenInit( DRIDriverContext
*ctx
, RADEONInfoPtr info
)
740 RADEONDRIPtr pRADEONDRI
;
744 /*assert(!ctx->IsClient);*/
747 int width_bytes
= (ctx
->shared
.virtualWidth
* ctx
->cpp
);
748 int maxy
= ctx
->shared
.fbSize
/ width_bytes
;
751 if (maxy
<= ctx
->shared
.virtualHeight
* 3) {
753 "Static buffer allocation failed -- "
754 "need at least %d kB video memory (have %d kB)\n",
755 (ctx
->shared
.virtualWidth
* ctx
->shared
.virtualHeight
*
756 ctx
->cpp
* 3 + 1023) / 1024,
757 ctx
->shared
.fbSize
/ 1024);
763 if (info
->ChipFamily
>= CHIP_FAMILY_R300
) {
765 "Direct rendering not yet supported on "
766 "Radeon 9700 and newer cards\n");
770 info
->registerSize
= ctx
->MMIOSize
;
771 ctx
->shared
.SAREASize
= DRM_PAGE_SIZE
;
773 /* Note that drmOpen will try to load the kernel module, if needed. */
774 ctx
->drmFD
= drmOpen("radeon", NULL
);
775 if (ctx
->drmFD
< 0) {
776 fprintf(stderr
, "[drm] drmOpen failed\n");
780 if ((err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
)) < 0) {
781 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
782 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
786 if (drmAddMap( ctx
->drmFD
,
788 ctx
->shared
.SAREASize
,
791 &ctx
->shared
.hSAREA
) < 0)
793 fprintf(stderr
, "[drm] drmAddMap failed\n");
796 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
797 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
799 if (drmMap( ctx
->drmFD
,
801 ctx
->shared
.SAREASize
,
802 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
804 fprintf(stderr
, "[drm] drmMap failed\n");
807 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
808 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
809 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
811 /* Need to AddMap the framebuffer and mmio regions here:
813 if (drmAddMap( ctx
->drmFD
,
814 (drmHandle
)ctx
->FBStart
,
822 &ctx
->shared
.hFrameBuffer
) < 0)
824 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
828 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
829 ctx
->shared
.hFrameBuffer
);
833 if (drmAddMap(ctx
->drmFD
,
838 &info
->registerHandle
) < 0) {
839 fprintf(stderr
, "[drm] drmAddMap mmio failed\n");
843 "[drm] register handle = 0x%08lx\n", info
->registerHandle
);
845 /* Check the radeon DRM version */
846 if (!RADEONCheckDRMVersion(ctx
, info
)) {
851 if (!RADEONDRIAgpInit(ctx
, info
)) {
856 /* Memory manager setup */
857 if (!RADEONMemoryInit(ctx
, info
)) {
861 /* Create a 'server' context so we can grab the lock for
862 * initialization ioctls.
864 if ((err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
)) != 0) {
865 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
869 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
871 /* Initialize the kernel data structures */
872 if (!RADEONDRIKernelInit(ctx
, info
)) {
873 fprintf(stderr
, "RADEONDRIKernelInit failed\n");
874 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
878 /* Initialize the vertex buffers list */
879 if (!RADEONDRIBufInit(ctx
, info
)) {
880 fprintf(stderr
, "RADEONDRIBufInit failed\n");
881 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
886 RADEONDRIIrqInit(ctx
, info
);
888 /* Initialize kernel gart memory manager */
889 RADEONDRIAgpHeapInit(ctx
, info
);
891 /* Initialize the SAREA private data structure */
893 drm_radeon_sarea_t
*pSAREAPriv
;
894 pSAREAPriv
= (drm_radeon_sarea_t
*)(((char*)ctx
->pSAREA
) +
895 sizeof(drm_sarea_t
));
896 memset(pSAREAPriv
, 0, sizeof(*pSAREAPriv
));
897 pSAREAPriv
->pfState
= 1;
901 /* Quick hack to clear the front & back buffers. Could also use
902 * the clear ioctl to do this, but would need to setup hw state
905 memset((char *)ctx
->FBAddress
+ info
->frontOffset
,
907 info
->frontPitch
* ctx
->cpp
* ctx
->shared
.virtualHeight
);
909 memset((char *)ctx
->FBAddress
+ info
->backOffset
,
911 info
->backPitch
* ctx
->cpp
* ctx
->shared
.virtualHeight
);
914 /* This is the struct passed to radeon_dri.so for its initialization */
915 ctx
->driverClientMsg
= malloc(sizeof(RADEONDRIRec
));
916 ctx
->driverClientMsgSize
= sizeof(RADEONDRIRec
);
917 pRADEONDRI
= (RADEONDRIPtr
)ctx
->driverClientMsg
;
918 pRADEONDRI
->deviceID
= info
->Chipset
;
919 pRADEONDRI
->width
= ctx
->shared
.virtualWidth
;
920 pRADEONDRI
->height
= ctx
->shared
.virtualHeight
;
921 pRADEONDRI
->depth
= ctx
->bpp
; /* XXX: depth */
922 pRADEONDRI
->bpp
= ctx
->bpp
;
923 pRADEONDRI
->IsPCI
= 0;
924 pRADEONDRI
->AGPMode
= ctx
->agpmode
;
925 pRADEONDRI
->frontOffset
= info
->frontOffset
;
926 pRADEONDRI
->frontPitch
= info
->frontPitch
;
927 pRADEONDRI
->backOffset
= info
->backOffset
;
928 pRADEONDRI
->backPitch
= info
->backPitch
;
929 pRADEONDRI
->depthOffset
= info
->depthOffset
;
930 pRADEONDRI
->depthPitch
= info
->depthPitch
;
931 pRADEONDRI
->textureOffset
= info
->textureOffset
;
932 pRADEONDRI
->textureSize
= info
->textureSize
;
933 pRADEONDRI
->log2TexGran
= info
->log2TexGran
;
934 pRADEONDRI
->registerHandle
= info
->registerHandle
;
935 pRADEONDRI
->registerSize
= info
->registerSize
;
936 pRADEONDRI
->statusHandle
= info
->ringReadPtrHandle
;
937 pRADEONDRI
->statusSize
= info
->ringReadMapSize
;
938 pRADEONDRI
->gartTexHandle
= info
->gartTexHandle
;
939 pRADEONDRI
->gartTexMapSize
= info
->gartTexMapSize
;
940 pRADEONDRI
->log2GARTTexGran
= info
->log2GARTTexGran
;
941 pRADEONDRI
->gartTexOffset
= info
->gartTexStart
;
942 pRADEONDRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
944 /* Don't release the lock now - let the VT switch handler do it. */
951 * \brief Get Radeon chip family from chipset number.
953 * \param info driver private data.
955 * \return non-zero on success, or zero on failure.
957 * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily
958 * according to the value of RADEONInfoRec::Chipset. Fails if the
959 * chipset is unrecognized or not appropriate for this driver (i.e., not
960 * an r100 style radeon)
962 static int get_chipfamily_from_chipset( RADEONInfoPtr info
)
964 switch (info
->Chipset
) {
965 case PCI_CHIP_RADEON_LY
:
966 case PCI_CHIP_RADEON_LZ
:
967 info
->ChipFamily
= CHIP_FAMILY_M6
;
970 case PCI_CHIP_RADEON_QY
:
971 case PCI_CHIP_RADEON_QZ
:
972 info
->ChipFamily
= CHIP_FAMILY_VE
;
975 case PCI_CHIP_R200_QL
:
976 case PCI_CHIP_R200_QN
:
977 case PCI_CHIP_R200_QO
:
978 case PCI_CHIP_R200_Ql
:
979 case PCI_CHIP_R200_BB
:
980 info
->ChipFamily
= CHIP_FAMILY_R200
;
983 case PCI_CHIP_RV200_QW
: /* RV200 desktop */
984 case PCI_CHIP_RV200_QX
:
985 info
->ChipFamily
= CHIP_FAMILY_RV200
;
988 case PCI_CHIP_RADEON_LW
:
989 case PCI_CHIP_RADEON_LX
:
990 info
->ChipFamily
= CHIP_FAMILY_M7
;
993 case PCI_CHIP_RV250_Id
:
994 case PCI_CHIP_RV250_Ie
:
995 case PCI_CHIP_RV250_If
:
996 case PCI_CHIP_RV250_Ig
:
997 info
->ChipFamily
= CHIP_FAMILY_RV250
;
1000 case PCI_CHIP_RV250_Ld
:
1001 case PCI_CHIP_RV250_Le
:
1002 case PCI_CHIP_RV250_Lf
:
1003 case PCI_CHIP_RV250_Lg
:
1004 info
->ChipFamily
= CHIP_FAMILY_M9
;
1007 case PCI_CHIP_RV280_Y_
:
1008 case PCI_CHIP_RV280_Ya
:
1009 case PCI_CHIP_RV280_Yb
:
1010 case PCI_CHIP_RV280_Yc
:
1011 info
->ChipFamily
= CHIP_FAMILY_RV280
;
1014 case PCI_CHIP_R300_ND
:
1015 case PCI_CHIP_R300_NE
:
1016 case PCI_CHIP_R300_NF
:
1017 case PCI_CHIP_R300_NG
:
1018 info
->ChipFamily
= CHIP_FAMILY_R300
;
1022 /* Original Radeon/7200 */
1023 info
->ChipFamily
= CHIP_FAMILY_RADEON
;
1031 * \brief Establish the set of modes available for the display.
1033 * \param ctx display handle.
1034 * \param numModes will receive the number of supported modes.
1035 * \param modes will point to the list of supported modes.
1037 * \return one on success, or zero on failure.
1039 * Allocates a single visual and fills it with information according to the
1040 * display bit depth. Supports only 16 and 32 bpp bit depths, aborting
1043 const __GLcontextModes __glModes
[] = {
1045 /* 32 bit, RGBA Depth=24 Stencil=8 */
1046 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
1047 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_TRUE
,
1048 .redBits
= 8, .greenBits
= 8, .blueBits
= 8, .alphaBits
= 8,
1049 .redMask
= 0xff0000, .greenMask
= 0xff00, .blueMask
= 0xff, .alphaMask
= 0xff000000,
1050 .rgbBits
= 32, .indexBits
= 0,
1051 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
1052 .depthBits
= 24, .stencilBits
= 8,
1053 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
1055 /* 16 bit, RGB Depth=16 */
1056 {.rgbMode
= GL_TRUE
, .colorIndexMode
= GL_FALSE
, .doubleBufferMode
= GL_TRUE
, .stereoMode
= GL_FALSE
,
1057 .haveAccumBuffer
= GL_FALSE
, .haveDepthBuffer
= GL_TRUE
, .haveStencilBuffer
= GL_FALSE
,
1058 .redBits
= 5, .greenBits
= 6, .blueBits
= 5, .alphaBits
= 0,
1059 .redMask
= 0xf800, .greenMask
= 0x07e0, .blueMask
= 0x001f, .alphaMask
= 0x0,
1060 .rgbBits
= 16, .indexBits
= 0,
1061 .accumRedBits
= 0, .accumGreenBits
= 0, .accumBlueBits
= 0, .accumAlphaBits
= 0,
1062 .depthBits
= 16, .stencilBits
= 0,
1063 .numAuxBuffers
= 0, .level
= 0, .pixmapMode
= GL_FALSE
, },
1065 static int radeonInitContextModes( const DRIDriverContext
*ctx
,
1066 int *numModes
, const __GLcontextModes
**modes
)
1068 *numModes
= sizeof(__glModes
)/sizeof(__GLcontextModes
*);
1069 *modes
= &__glModes
[0];
1075 * \brief Validate the fbdev mode.
1077 * \param ctx display handle.
1079 * \return one on success, or zero on failure.
1081 * Saves some registers and returns 1.
1083 * \sa radeonValidateMode().
1085 static int radeonValidateMode( const DRIDriverContext
*ctx
)
1087 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
1088 RADEONInfoPtr info
= ctx
->driverPrivate
;
1090 info
->gen_int_cntl
= INREG(RADEON_GEN_INT_CNTL
);
1091 info
->crtc_offset_cntl
= INREG(RADEON_CRTC_OFFSET_CNTL
);
1098 * \brief Examine mode returned by fbdev.
1100 * \param ctx display handle.
1102 * \return one on success, or zero on failure.
1104 * Restores registers that fbdev has clobbered and returns 1.
1106 * \sa radeonValidateMode().
1108 static int radeonPostValidateMode( const DRIDriverContext
*ctx
)
1110 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
1111 RADEONInfoPtr info
= ctx
->driverPrivate
;
1113 OUTREG(RADEON_GEN_INT_CNTL
, info
->gen_int_cntl
);
1114 OUTREG(RADEON_CRTC_OFFSET_CNTL
, info
->crtc_offset_cntl
);
1121 * \brief Initialize the framebuffer device mode
1123 * \param ctx display handle.
1125 * \return one on success, or zero on failure.
1127 * Fills in \p info with some default values and some information from \p ctx
1128 * and then calls RADEONScreenInit() for the screen initialization.
1130 * Before exiting clears the framebuffer memory accessing it directly.
1132 static int radeonInitFBDev( DRIDriverContext
*ctx
)
1134 RADEONInfoPtr info
= calloc(1, sizeof(*info
));
1137 int dummy
= ctx
->shared
.virtualWidth
;
1139 switch (ctx
->bpp
/ 8) {
1140 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
1141 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 31) & ~31; break;
1143 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 15) & ~15; break;
1146 ctx
->shared
.virtualWidth
= dummy
;
1149 ctx
->driverPrivate
= (void *)info
;
1151 info
->gartFastWrite
= RADEON_DEFAULT_AGP_FAST_WRITE
;
1152 info
->gartSize
= RADEON_DEFAULT_AGP_SIZE
;
1153 info
->gartTexSize
= RADEON_DEFAULT_AGP_TEX_SIZE
;
1154 info
->bufSize
= RADEON_DEFAULT_BUFFER_SIZE
;
1155 info
->ringSize
= RADEON_DEFAULT_RING_SIZE
;
1157 info
->Chipset
= ctx
->chipset
;
1159 if (!get_chipfamily_from_chipset( info
)) {
1160 fprintf(stderr
, "Unknown or non-radeon chipset -- cannot continue\n");
1161 fprintf(stderr
, "==> Verify PCI BusID is correct in miniglx.conf\n");
1165 info
->frontPitch
= ctx
->shared
.virtualWidth
;
1166 info
->LinearAddr
= ctx
->FBStart
& 0xfc000000;
1169 if (!RADEONScreenInit( ctx
, info
))
1178 * \brief The screen is being closed, so clean up any state and free any
1179 * resources used by the DRI.
1181 * \param ctx display handle.
1183 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1186 static void radeonHaltFBDev( DRIDriverContext
*ctx
)
1188 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
1189 drmClose(ctx
->drmFD
);
1191 if (ctx
->driverPrivate
) {
1192 free(ctx
->driverPrivate
);
1193 ctx
->driverPrivate
= 0;
1198 extern void radeonNotifyFocus( int );
1201 * \brief Exported driver interface for Mini GLX.
1205 const struct DRIDriverRec __driDriver
= {
1206 radeonInitContextModes
,
1208 radeonPostValidateMode
,
1211 RADEONEngineShutdown
,
1212 RADEONEngineRestore
,