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.
22 #include "radeon_dri.h"
23 #include "radeon_macros.h"
24 #include "radeon_reg.h"
25 #include "drm_sarea.h"
27 static size_t radeon_drm_page_size
;
29 static int RadeonSetParam(const DRIDriverContext
*ctx
, int param
, int value
)
31 drm_radeon_setparam_t sp
;
33 memset(&sp
, 0, sizeof(sp
));
37 if (drmCommandWrite(ctx
->drmFD
, DRM_RADEON_SETPARAM
, &sp
, sizeof(sp
))) {
45 * \brief Wait for free FIFO entries.
47 * \param ctx display handle.
48 * \param entries number of free entries to wait.
50 * It polls the free entries from the chip until it reaches the requested value
51 * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
53 static void RADEONWaitForFifo( const DRIDriverContext
*ctx
,
56 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
59 for (i
= 0; i
< 3000; i
++) {
61 INREG(RADEON_RBBM_STATUS
) & RADEON_RBBM_FIFOCNT_MASK
;
62 if (fifo_slots
>= entries
) return;
65 /* There are recoveries possible, but I haven't seen them work
68 fprintf(stderr
, "FIFO timed out: %d entries, stat=0x%08x\n",
69 INREG(RADEON_RBBM_STATUS
) & RADEON_RBBM_FIFOCNT_MASK
,
70 INREG(RADEON_RBBM_STATUS
));
75 * \brief Read a PLL register.
77 * \param ctx display handle.
78 * \param addr PLL register index.
80 * \return value of the PLL register.
82 static unsigned int RADEONINPLL( const DRIDriverContext
*ctx
, int addr
)
84 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
87 OUTREG8(RADEON_CLOCK_CNTL_INDEX
, addr
& 0x3f);
88 data
= INREG(RADEON_CLOCK_CNTL_DATA
);
94 * \brief Reset graphics card to known state.
96 * \param ctx display handle.
98 * Resets the values of several Radeon registers.
100 static void RADEONEngineReset( const DRIDriverContext
*ctx
)
102 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
103 unsigned int clock_cntl_index
;
104 unsigned int mclk_cntl
;
105 unsigned int rbbm_soft_reset
;
106 unsigned int host_path_cntl
;
109 OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT
,
110 RADEON_RB2D_DC_FLUSH_ALL
,
111 ~RADEON_RB2D_DC_FLUSH_ALL
);
112 for (i
= 0; i
< 512; i
++) {
113 if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT
) & RADEON_RB2D_DC_BUSY
))
117 clock_cntl_index
= INREG(RADEON_CLOCK_CNTL_INDEX
);
119 mclk_cntl
= INPLL(ctx
, RADEON_MCLK_CNTL
);
120 OUTPLL(RADEON_MCLK_CNTL
, (mclk_cntl
|
121 RADEON_FORCEON_MCLKA
|
122 RADEON_FORCEON_MCLKB
|
123 RADEON_FORCEON_YCLKA
|
124 RADEON_FORCEON_YCLKB
|
126 RADEON_FORCEON_AIC
));
128 /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
129 * unexpected behaviour on some machines. Here we use
130 * RADEON_HOST_PATH_CNTL to reset it.
132 host_path_cntl
= INREG(RADEON_HOST_PATH_CNTL
);
133 rbbm_soft_reset
= INREG(RADEON_RBBM_SOFT_RESET
);
135 OUTREG(RADEON_RBBM_SOFT_RESET
, (rbbm_soft_reset
|
136 RADEON_SOFT_RESET_CP
|
137 RADEON_SOFT_RESET_HI
|
138 RADEON_SOFT_RESET_SE
|
139 RADEON_SOFT_RESET_RE
|
140 RADEON_SOFT_RESET_PP
|
141 RADEON_SOFT_RESET_E2
|
142 RADEON_SOFT_RESET_RB
));
143 INREG(RADEON_RBBM_SOFT_RESET
);
144 OUTREG(RADEON_RBBM_SOFT_RESET
, (rbbm_soft_reset
&
145 (unsigned int) ~(RADEON_SOFT_RESET_CP
|
146 RADEON_SOFT_RESET_HI
|
147 RADEON_SOFT_RESET_SE
|
148 RADEON_SOFT_RESET_RE
|
149 RADEON_SOFT_RESET_PP
|
150 RADEON_SOFT_RESET_E2
|
151 RADEON_SOFT_RESET_RB
)));
152 INREG(RADEON_RBBM_SOFT_RESET
);
154 OUTREG(RADEON_HOST_PATH_CNTL
, host_path_cntl
| RADEON_HDP_SOFT_RESET
);
155 INREG(RADEON_HOST_PATH_CNTL
);
156 OUTREG(RADEON_HOST_PATH_CNTL
, host_path_cntl
);
158 OUTREG(RADEON_RBBM_SOFT_RESET
, rbbm_soft_reset
);
160 OUTREG(RADEON_CLOCK_CNTL_INDEX
, clock_cntl_index
);
161 OUTPLL(RADEON_MCLK_CNTL
, mclk_cntl
);
165 * \brief Restore the drawing engine.
167 * \param ctx display handle
169 * Resets the graphics card and sets initial values for several registers of
170 * the card's drawing engine.
172 * Turns on the radeon command processor engine (i.e., the ringbuffer).
174 static int RADEONEngineRestore( const DRIDriverContext
*ctx
)
176 RADEONInfoPtr info
= ctx
->driverPrivate
;
177 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
178 int pitch64
, datatype
, dp_gui_master_cntl
, err
;
180 fprintf(stderr
, "%s\n", __FUNCTION__
);
182 OUTREG(RADEON_RB3D_CNTL
, 0);
183 RADEONEngineReset( ctx
);
186 case 16: datatype
= 4; break;
187 case 32: datatype
= 6; break;
192 ((datatype
<< RADEON_GMC_DST_DATATYPE_SHIFT
)
193 | RADEON_GMC_CLR_CMP_CNTL_DIS
);
195 pitch64
= ((ctx
->shared
.virtualWidth
* (ctx
->bpp
/ 8) + 0x3f)) >> 6;
197 RADEONWaitForFifo(ctx
, 1);
198 OUTREG(RADEON_DEFAULT_OFFSET
, ((INREG(RADEON_DEFAULT_OFFSET
) & 0xC0000000)
201 RADEONWaitForFifo(ctx
, 1);
202 OUTREG(RADEON_SURFACE_CNTL
, RADEON_SURF_TRANSLATION_DIS
);
204 RADEONWaitForFifo(ctx
, 1);
205 OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT
, (RADEON_DEFAULT_SC_RIGHT_MAX
206 | RADEON_DEFAULT_SC_BOTTOM_MAX
));
208 RADEONWaitForFifo(ctx
, 1);
209 OUTREG(RADEON_DP_GUI_MASTER_CNTL
, (dp_gui_master_cntl
210 | RADEON_GMC_BRUSH_SOLID_COLOR
211 | RADEON_GMC_SRC_DATATYPE_COLOR
));
213 RADEONWaitForFifo(ctx
, 7);
214 OUTREG(RADEON_DST_LINE_START
, 0);
215 OUTREG(RADEON_DST_LINE_END
, 0);
216 OUTREG(RADEON_DP_BRUSH_FRGD_CLR
, 0xffffffff);
217 OUTREG(RADEON_DP_BRUSH_BKGD_CLR
, 0);
218 OUTREG(RADEON_DP_SRC_FRGD_CLR
, 0xffffffff);
219 OUTREG(RADEON_DP_SRC_BKGD_CLR
, 0);
220 OUTREG(RADEON_DP_WRITE_MASK
, 0xffffffff);
221 OUTREG(RADEON_AUX_SC_CNTL
, 0);
223 /* RADEONWaitForIdleMMIO(ctx); */
227 OUTREG(RADEON_GEN_INT_CNTL
, info
->gen_int_cntl
);
228 if (info
->colorTiling
)
229 info
->crtc_offset_cntl
|= RADEON_CRTC_TILE_EN
;
230 OUTREG(RADEON_CRTC_OFFSET_CNTL
, info
->crtc_offset_cntl
);
232 /* Initialize and start the CP if required */
233 if ((err
= drmCommandNone(ctx
->drmFD
, DRM_RADEON_CP_START
)) != 0) {
234 fprintf(stderr
, "%s: CP start %d\n", __FUNCTION__
, err
);
243 * \brief Shutdown the drawing engine.
245 * \param ctx display handle
247 * Turns off the command processor engine & restores the graphics card
248 * to a state that fbdev understands.
250 static int RADEONEngineShutdown( const DRIDriverContext
*ctx
)
252 drm_radeon_cp_stop_t stop
;
258 ret
= drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_STOP
, &stop
,
259 sizeof(drm_radeon_cp_stop_t
));
263 } else if (errno
!= EBUSY
) {
271 ret
= drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_STOP
, &stop
,
272 sizeof(drm_radeon_cp_stop_t
));
273 } while (ret
&& errno
== EBUSY
&& i
++ < 10);
277 } else if (errno
!= EBUSY
) {
283 if (drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_STOP
,
284 &stop
, sizeof(drm_radeon_cp_stop_t
))) {
292 * \brief Compute base 2 logarithm.
296 * \return base 2 logarithm of \p val.
298 static int RADEONMinBits(int val
)
303 for (bits
= 0; val
; val
>>= 1, ++bits
);
308 * \brief Initialize the AGP state
310 * \param ctx display handle.
311 * \param info driver private data.
313 * \return one on success, or zero on failure.
315 * Acquires and enables the AGP device. Reserves memory in the AGP space for
316 * the ring buffer, vertex buffers and textures. Initialize the Radeon
317 * registers to point to that memory and add client mappings.
319 static int RADEONDRIAgpInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
321 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
326 if (drmAgpAcquire(ctx
->drmFD
) < 0) {
327 fprintf(stderr
, "[gart] AGP not available\n");
331 /* Modify the mode if the default mode is not appropriate for this
332 * particular combination of graphics card and AGP chipset.
334 mode
= drmAgpGetMode(ctx
->drmFD
); /* Default mode */
336 /* Disable fast write entirely - too many lockups.
338 mode
&= ~RADEON_AGP_MODE_MASK
;
339 switch (ctx
->agpmode
) {
340 case 4: mode
|= RADEON_AGP_4X_MODE
;
341 case 2: mode
|= RADEON_AGP_2X_MODE
;
342 case 1: default: mode
|= RADEON_AGP_1X_MODE
;
345 if (drmAgpEnable(ctx
->drmFD
, mode
) < 0) {
346 fprintf(stderr
, "[gart] AGP not enabled\n");
347 drmAgpRelease(ctx
->drmFD
);
351 fprintf(stderr
, "[gart] AGP enabled at %dx\n", ctx
->agpmode
);
353 /* Workaround for some hardware bugs */
354 if (info
->ChipFamily
< CHIP_FAMILY_R200
)
355 OUTREG(RADEON_AGP_CNTL
, INREG(RADEON_AGP_CNTL
) | 0x000e0000);
357 info
->gartOffset
= 0;
359 if ((ret
= drmAgpAlloc(ctx
->drmFD
, info
->gartSize
*1024*1024, 0, NULL
,
360 &info
->gartMemHandle
)) < 0) {
361 fprintf(stderr
, "[gart] Out of memory (%d)\n", ret
);
362 drmAgpRelease(ctx
->drmFD
);
366 "[gart] %d kB allocated with handle 0x%08x\n",
367 info
->gartSize
*1024, (unsigned)info
->gartMemHandle
);
369 if (drmAgpBind(ctx
->drmFD
,
370 info
->gartMemHandle
, info
->gartOffset
) < 0) {
371 fprintf(stderr
, "[gart] Could not bind\n");
372 drmAgpFree(ctx
->drmFD
, info
->gartMemHandle
);
373 drmAgpRelease(ctx
->drmFD
);
377 /* Initialize the CP ring buffer data */
378 info
->ringStart
= info
->gartOffset
;
379 info
->ringMapSize
= info
->ringSize
*1024*1024 + radeon_drm_page_size
;
381 info
->ringReadOffset
= info
->ringStart
+ info
->ringMapSize
;
382 info
->ringReadMapSize
= radeon_drm_page_size
;
384 /* Reserve space for vertex/indirect buffers */
385 info
->bufStart
= info
->ringReadOffset
+ info
->ringReadMapSize
;
386 info
->bufMapSize
= info
->bufSize
*1024*1024;
388 /* Reserve the rest for AGP textures */
389 info
->gartTexStart
= info
->bufStart
+ info
->bufMapSize
;
390 s
= (info
->gartSize
*1024*1024 - info
->gartTexStart
);
391 l
= RADEONMinBits((s
-1) / RADEON_NR_TEX_REGIONS
);
392 if (l
< RADEON_LOG_TEX_GRANULARITY
) l
= RADEON_LOG_TEX_GRANULARITY
;
393 info
->gartTexMapSize
= (s
>> l
) << l
;
394 info
->log2GARTTexGran
= l
;
396 if (drmAddMap(ctx
->drmFD
, info
->ringStart
, info
->ringMapSize
,
397 DRM_AGP
, DRM_READ_ONLY
, &info
->ringHandle
) < 0) {
398 fprintf(stderr
, "[gart] Could not add ring mapping\n");
401 fprintf(stderr
, "[gart] ring handle = 0x%08x\n", info
->ringHandle
);
404 if (drmAddMap(ctx
->drmFD
, info
->ringReadOffset
, info
->ringReadMapSize
,
405 DRM_AGP
, DRM_READ_ONLY
, &info
->ringReadPtrHandle
) < 0) {
407 "[gart] Could not add ring read ptr mapping\n");
412 "[gart] ring read ptr handle = 0x%08lx\n",
413 info
->ringReadPtrHandle
);
415 if (drmAddMap(ctx
->drmFD
, info
->bufStart
, info
->bufMapSize
,
416 DRM_AGP
, 0, &info
->bufHandle
) < 0) {
418 "[gart] Could not add vertex/indirect buffers mapping\n");
422 "[gart] vertex/indirect buffers handle = 0x%08x\n",
425 if (drmAddMap(ctx
->drmFD
, info
->gartTexStart
, info
->gartTexMapSize
,
426 DRM_AGP
, 0, &info
->gartTexHandle
) < 0) {
428 "[gart] Could not add AGP texture map mapping\n");
432 "[gart] AGP texture map handle = 0x%08lx\n",
433 info
->gartTexHandle
);
435 /* Initialize Radeon's AGP registers */
436 /* Ring buffer is at AGP offset 0 */
437 OUTREG(RADEON_AGP_BASE
, info
->ringHandle
);
442 /* Initialize the PCI GART state. Request memory for use in PCI space,
443 * and initialize the Radeon registers to point to that memory.
445 static int RADEONDRIPciInit(const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
448 int flags
= DRM_READ_ONLY
| DRM_LOCKED
| DRM_KERNEL
;
451 ret
= drmScatterGatherAlloc(ctx
->drmFD
, info
->gartSize
*1024*1024,
452 &info
->gartMemHandle
);
454 fprintf(stderr
, "[pci] Out of memory (%d)\n", ret
);
458 "[pci] %d kB allocated with handle 0x%08lx\n",
459 info
->gartSize
*1024, info
->gartMemHandle
);
461 info
->gartOffset
= 0;
463 /* Initialize the CP ring buffer data */
464 info
->ringStart
= info
->gartOffset
;
465 info
->ringMapSize
= info
->ringSize
*1024*1024 + radeon_drm_page_size
;
467 info
->ringReadOffset
= info
->ringStart
+ info
->ringMapSize
;
468 info
->ringReadMapSize
= radeon_drm_page_size
;
470 /* Reserve space for vertex/indirect buffers */
471 info
->bufStart
= info
->ringReadOffset
+ info
->ringReadMapSize
;
472 info
->bufMapSize
= info
->bufSize
*1024*1024;
474 /* Reserve the rest for AGP textures */
475 info
->gartTexStart
= info
->bufStart
+ info
->bufMapSize
;
476 s
= (info
->gartSize
*1024*1024 - info
->gartTexStart
);
477 l
= RADEONMinBits((s
-1) / RADEON_NR_TEX_REGIONS
);
478 if (l
< RADEON_LOG_TEX_GRANULARITY
) l
= RADEON_LOG_TEX_GRANULARITY
;
479 info
->gartTexMapSize
= (s
>> l
) << l
;
480 info
->log2GARTTexGran
= l
;
482 if (drmAddMap(ctx
->drmFD
, info
->ringStart
, info
->ringMapSize
,
483 DRM_SCATTER_GATHER
, flags
, &info
->ringHandle
) < 0) {
485 "[pci] Could not add ring mapping\n");
489 "[pci] ring handle = 0x%08x\n", info
->ringHandle
);
491 if (drmAddMap(ctx
->drmFD
, info
->ringReadOffset
, info
->ringReadMapSize
,
492 DRM_SCATTER_GATHER
, flags
, &info
->ringReadPtrHandle
) < 0) {
494 "[pci] Could not add ring read ptr mapping\n");
498 "[pci] ring read ptr handle = 0x%08lx\n",
499 info
->ringReadPtrHandle
);
501 if (drmAddMap(ctx
->drmFD
, info
->bufStart
, info
->bufMapSize
,
502 DRM_SCATTER_GATHER
, 0, &info
->bufHandle
) < 0) {
504 "[pci] Could not add vertex/indirect buffers mapping\n");
508 "[pci] vertex/indirect buffers handle = 0x%08lx\n",
511 if (drmAddMap(ctx
->drmFD
, info
->gartTexStart
, info
->gartTexMapSize
,
512 DRM_SCATTER_GATHER
, 0, &info
->gartTexHandle
) < 0) {
514 "[pci] Could not add GART texture map mapping\n");
518 "[pci] GART texture map handle = 0x%08x\n",
519 info
->gartTexHandle
);
526 * \brief Initialize the kernel data structures and enable the CP engine.
528 * \param ctx display handle.
529 * \param info driver private data.
531 * \return non-zero on success, or zero on failure.
533 * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
534 * all the parameters in a drm_radeon_init_t structure.
536 static int RADEONDRIKernelInit( const DRIDriverContext
*ctx
,
539 int cpp
= ctx
->bpp
/ 8;
540 drm_radeon_init_t drmInfo
;
543 memset(&drmInfo
, 0, sizeof(drm_radeon_init_t
));
545 if ( (info
->ChipFamily
== CHIP_FAMILY_R200
) ||
546 (info
->ChipFamily
== CHIP_FAMILY_RV250
) ||
547 (info
->ChipFamily
== CHIP_FAMILY_M9
) ||
548 (info
->ChipFamily
== CHIP_FAMILY_RV280
) )
549 drmInfo
.func
= RADEON_INIT_R200_CP
;
551 drmInfo
.func
= RADEON_INIT_CP
;
553 /* This is the struct passed to the kernel module for its initialization */
554 drmInfo
.sarea_priv_offset
= sizeof(drm_sarea_t
);
555 drmInfo
.is_pci
= ctx
->isPCI
;
556 drmInfo
.cp_mode
= RADEON_DEFAULT_CP_BM_MODE
;
557 drmInfo
.gart_size
= info
->gartSize
*1024*1024;
558 drmInfo
.ring_size
= info
->ringSize
*1024*1024;
559 drmInfo
.usec_timeout
= 1000;
560 drmInfo
.fb_bpp
= ctx
->bpp
;
561 drmInfo
.depth_bpp
= ctx
->bpp
;
562 drmInfo
.front_offset
= info
->frontOffset
;
563 drmInfo
.front_pitch
= info
->frontPitch
* cpp
;
564 drmInfo
.back_offset
= info
->backOffset
;
565 drmInfo
.back_pitch
= info
->backPitch
* cpp
;
566 drmInfo
.depth_offset
= info
->depthOffset
;
567 drmInfo
.depth_pitch
= info
->depthPitch
* cpp
;
568 drmInfo
.fb_offset
= info
->LinearAddr
;
569 drmInfo
.mmio_offset
= info
->registerHandle
;
570 drmInfo
.ring_offset
= info
->ringHandle
;
571 drmInfo
.ring_rptr_offset
= info
->ringReadPtrHandle
;
572 drmInfo
.buffers_offset
= info
->bufHandle
;
573 drmInfo
.gart_textures_offset
= info
->gartTexHandle
;
575 ret
= drmCommandWrite(ctx
->drmFD
, DRM_RADEON_CP_INIT
, &drmInfo
,
576 sizeof(drm_radeon_init_t
));
583 * \brief Initialize the AGP heap.
585 * \param ctx display handle.
586 * \param info driver private data.
588 * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
589 * all the parameters in a drm_radeon_mem_init_heap structure.
591 static void RADEONDRIAgpHeapInit(const DRIDriverContext
*ctx
,
594 drm_radeon_mem_init_heap_t drmHeap
;
596 /* Start up the simple memory manager for gart space */
597 drmHeap
.region
= RADEON_MEM_REGION_GART
;
599 drmHeap
.size
= info
->gartTexMapSize
;
601 if (drmCommandWrite(ctx
->drmFD
, DRM_RADEON_INIT_HEAP
,
602 &drmHeap
, sizeof(drmHeap
))) {
604 "[drm] Failed to initialized gart heap manager\n");
607 "[drm] Initialized kernel gart heap manager, %d\n",
608 info
->gartTexMapSize
);
613 * \brief Add a map for the vertex buffers that will be accessed by any
616 * \param ctx display handle.
617 * \param info driver private data.
619 * \return one on success, or zero on failure.
621 * Calls drmAddBufs() with the previously allocated vertex buffers.
623 static int RADEONDRIBufInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
625 /* Initialize vertex buffers */
626 info
->bufNumBufs
= drmAddBufs(ctx
->drmFD
,
627 info
->bufMapSize
/ RADEON_BUFFER_SIZE
,
629 ctx
->isPCI
? DRM_SG_BUFFER
: DRM_AGP_BUFFER
,
632 if (info
->bufNumBufs
<= 0) {
634 "[drm] Could not create vertex/indirect buffers list\n");
638 "[drm] Added %d %d byte vertex/indirect buffers\n",
639 info
->bufNumBufs
, RADEON_BUFFER_SIZE
);
645 * \brief Install an IRQ handler.
647 * \param ctx display handle.
648 * \param info driver private data.
650 * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
651 * IRQ-free operation on failure.
653 static void RADEONDRIIrqInit(const DRIDriverContext
*ctx
,
657 info
->irq
= drmGetInterruptFromBusID(ctx
->drmFD
,
662 if ((drmCtlInstHandler(ctx
->drmFD
, info
->irq
)) != 0) {
664 "[drm] failure adding irq handler, "
665 "there is a device already using that irq\n"
666 "[drm] falling back to irq-free operation\n");
673 "[drm] dma control initialized, using IRQ %d\n",
677 static int RADEONCheckDRMVersion( const DRIDriverContext
*ctx
,
680 drmVersionPtr version
;
682 version
= drmGetVersion(ctx
->drmFD
);
684 int req_minor
, req_patch
;
686 /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
691 if (version
->version_major
!= 1 ||
692 version
->version_minor
< req_minor
||
693 (version
->version_minor
== req_minor
&&
694 version
->version_patchlevel
< req_patch
)) {
695 /* Incompatible drm version */
697 "[dri] RADEONDRIScreenInit failed because of a version "
699 "[dri] radeon.o kernel module version is %d.%d.%d "
700 "but version 1.%d.%d or newer is needed.\n"
701 "[dri] Disabling DRI.\n",
702 version
->version_major
,
703 version
->version_minor
,
704 version
->version_patchlevel
,
707 drmFreeVersion(version
);
711 info
->drmMinor
= version
->version_minor
;
712 drmFreeVersion(version
);
718 static int RADEONMemoryInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
720 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
722 int bufferSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
+ RADEON_BUFFER_ALIGN
) & ~RADEON_BUFFER_ALIGN
);
723 int depthSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
724 + RADEON_BUFFER_ALIGN
) & ~RADEON_BUFFER_ALIGN
);
727 info
->frontOffset
= 0;
728 info
->frontPitch
= ctx
->shared
.virtualWidth
;
731 "Using %d MB AGP aperture\n", info
->gartSize
);
733 "Using %d MB for the ring buffer\n", info
->ringSize
);
735 "Using %d MB for vertex/indirect buffers\n", info
->bufSize
);
737 "Using %d MB for AGP textures\n", info
->gartTexSize
);
739 /* Front, back and depth buffers - everything else texture??
741 info
->textureSize
= ctx
->shared
.fbSize
- 2 * bufferSize
- depthSize
;
743 if (ctx
->colorTiling
==1)
745 info
->textureSize
= ctx
->shared
.fbSize
- ((ctx
->shared
.fbSize
- info
->textureSize
+ width_bytes
* 16 - 1) / (width_bytes
* 16)) * (width_bytes
*16);
748 if (info
->textureSize
< 0)
751 l
= RADEONMinBits((info
->textureSize
-1) / RADEON_NR_TEX_REGIONS
);
752 if (l
< RADEON_LOG_TEX_GRANULARITY
) l
= RADEON_LOG_TEX_GRANULARITY
;
754 /* Round the texture size up to the nearest whole number of
755 * texture regions. Again, be greedy about this, don't
758 info
->log2TexGran
= l
;
759 info
->textureSize
= (info
->textureSize
>> l
) << l
;
761 /* Set a minimum usable local texture heap size. This will fit
762 * two 256x256x32bpp textures.
764 if (info
->textureSize
< 512 * 1024) {
765 info
->textureOffset
= 0;
766 info
->textureSize
= 0;
769 /* Reserve space for textures */
770 if (ctx
->colorTiling
==1)
772 info
->textureOffset
= ((ctx
->shared
.fbSize
- info
->textureSize
) /
773 (width_bytes
* 16)) * (width_bytes
*16);
777 info
->textureOffset
= ((ctx
->shared
.fbSize
- info
->textureSize
+
778 RADEON_BUFFER_ALIGN
) &
779 ~RADEON_BUFFER_ALIGN
);
781 /* Reserve space for the shared depth
784 info
->depthOffset
= ((info
->textureOffset
- depthSize
+
785 RADEON_BUFFER_ALIGN
) &
786 ~RADEON_BUFFER_ALIGN
);
787 info
->depthPitch
= ctx
->shared
.virtualWidth
;
789 info
->backOffset
= ((info
->depthOffset
- bufferSize
+
790 RADEON_BUFFER_ALIGN
) &
791 ~RADEON_BUFFER_ALIGN
);
792 info
->backPitch
= ctx
->shared
.virtualWidth
;
796 "Will use back buffer at offset 0x%x\n",
799 "Will use depth buffer at offset 0x%x\n",
802 "Will use %d kb for textures at offset 0x%x\n",
803 info
->textureSize
/1024, info
->textureOffset
);
805 info
->frontPitchOffset
= (((info
->frontPitch
* cpp
/ 64) << 22) |
806 (info
->frontOffset
>> 10));
808 info
->backPitchOffset
= (((info
->backPitch
* cpp
/ 64) << 22) |
809 (info
->backOffset
>> 10));
811 info
->depthPitchOffset
= (((info
->depthPitch
* cpp
/ 64) << 22) |
812 (info
->depthOffset
>> 10));
817 static int RADEONColorTilingInit( const DRIDriverContext
*ctx
, RADEONInfoPtr info
)
819 int width_bytes
= ctx
->shared
.virtualWidth
* ctx
->cpp
;
820 int bufferSize
= ((((ctx
->shared
.virtualHeight
+15) & ~15) * width_bytes
+ RADEON_BUFFER_ALIGN
)
821 & ~RADEON_BUFFER_ALIGN
);
822 /* Setup color tiling */
823 if (info
->drmMinor
<14)
826 if (info
->colorTiling
)
830 drm_radeon_surface_alloc_t front
,back
;
832 RadeonSetParam(ctx
, RADEON_SETPARAM_SWITCH_TILING
, info
->colorTiling
? 1 : 0);
834 /* Setup the surfaces */
835 if (info
->ChipFamily
< CHIP_FAMILY_R200
)
836 colorTilingFlag
=RADEON_SURF_TILE_COLOR_MACRO
;
838 colorTilingFlag
=R200_SURF_TILE_COLOR_MACRO
;
840 front
.address
= info
->frontOffset
;
841 front
.size
= bufferSize
;
842 front
.flags
= (width_bytes
) | colorTilingFlag
;
843 drmCommandWrite(ctx
->drmFD
, DRM_RADEON_SURF_ALLOC
, &front
,sizeof(front
));
845 back
.address
= info
->backOffset
;
846 back
.size
= bufferSize
;
847 back
.flags
= (width_bytes
) | colorTilingFlag
;
848 drmCommandWrite(ctx
->drmFD
, DRM_RADEON_SURF_ALLOC
, &back
,sizeof(back
));
857 * Called at the start of each server generation.
859 * \param ctx display handle.
860 * \param info driver private data.
862 * \return non-zero on success, or zero on failure.
864 * Performs static frame buffer allocation. Opens the DRM device and add maps
865 * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
866 * information. Creates a \e server context to grab the lock for the
867 * initialization ioctls and calls the other initilization functions in this
868 * file. Starts the CP engine via the DRM_RADEON_CP_START command.
870 * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
873 static int RADEONScreenInit( DRIDriverContext
*ctx
, RADEONInfoPtr info
)
875 RADEONDRIPtr pRADEONDRI
;
879 /*assert(!ctx->IsClient);*/
882 int width_bytes
= (ctx
->shared
.virtualWidth
* ctx
->cpp
);
883 int maxy
= ctx
->shared
.fbSize
/ width_bytes
;
886 if (maxy
<= ctx
->shared
.virtualHeight
* 3) {
888 "Static buffer allocation failed -- "
889 "need at least %d kB video memory (have %d kB)\n",
890 (ctx
->shared
.virtualWidth
* ctx
->shared
.virtualHeight
*
891 ctx
->cpp
* 3 + 1023) / 1024,
892 ctx
->shared
.fbSize
/ 1024);
898 if (info
->ChipFamily
>= CHIP_FAMILY_R300
) {
900 "Direct rendering not yet supported on "
901 "Radeon 9700 and newer cards\n");
905 radeon_drm_page_size
= getpagesize();
907 info
->registerSize
= ctx
->MMIOSize
;
908 ctx
->shared
.SAREASize
= SAREA_MAX
;
910 /* Note that drmOpen will try to load the kernel module, if needed. */
911 ctx
->drmFD
= drmOpen("radeon", NULL
);
912 if (ctx
->drmFD
< 0) {
913 fprintf(stderr
, "[drm] drmOpen failed\n");
917 if ((err
= drmSetBusid(ctx
->drmFD
, ctx
->pciBusID
)) < 0) {
918 fprintf(stderr
, "[drm] drmSetBusid failed (%d, %s), %s\n",
919 ctx
->drmFD
, ctx
->pciBusID
, strerror(-err
));
923 if (drmAddMap( ctx
->drmFD
,
925 ctx
->shared
.SAREASize
,
928 &ctx
->shared
.hSAREA
) < 0)
930 fprintf(stderr
, "[drm] drmAddMap failed\n");
933 fprintf(stderr
, "[drm] added %d byte SAREA at 0x%08lx\n",
934 ctx
->shared
.SAREASize
, ctx
->shared
.hSAREA
);
936 if (drmMap( ctx
->drmFD
,
938 ctx
->shared
.SAREASize
,
939 (drmAddressPtr
)(&ctx
->pSAREA
)) < 0)
941 fprintf(stderr
, "[drm] drmMap failed\n");
944 memset(ctx
->pSAREA
, 0, ctx
->shared
.SAREASize
);
945 fprintf(stderr
, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
946 ctx
->shared
.hSAREA
, ctx
->pSAREA
, ctx
->shared
.SAREASize
);
948 /* Need to AddMap the framebuffer and mmio regions here:
950 if (drmAddMap( ctx
->drmFD
,
951 (drm_handle_t
)ctx
->FBStart
,
959 &ctx
->shared
.hFrameBuffer
) < 0)
961 fprintf(stderr
, "[drm] drmAddMap framebuffer failed\n");
965 fprintf(stderr
, "[drm] framebuffer handle = 0x%08lx\n",
966 ctx
->shared
.hFrameBuffer
);
970 if (drmAddMap(ctx
->drmFD
,
975 &info
->registerHandle
) < 0) {
976 fprintf(stderr
, "[drm] drmAddMap mmio failed\n");
980 "[drm] register handle = 0x%08lx\n", info
->registerHandle
);
982 /* Check the radeon DRM version */
983 if (!RADEONCheckDRMVersion(ctx
, info
)) {
989 if (!RADEONDRIPciInit(ctx
, info
))
994 if (!RADEONDRIAgpInit(ctx
, info
))
998 /* Memory manager setup */
999 if (!RADEONMemoryInit(ctx
, info
)) {
1003 /* Create a 'server' context so we can grab the lock for
1004 * initialization ioctls.
1006 if ((err
= drmCreateContext(ctx
->drmFD
, &ctx
->serverContext
)) != 0) {
1007 fprintf(stderr
, "%s: drmCreateContext failed %d\n", __FUNCTION__
, err
);
1011 DRM_LOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
, 0);
1013 /* Initialize the kernel data structures */
1014 if (!RADEONDRIKernelInit(ctx
, info
)) {
1015 fprintf(stderr
, "RADEONDRIKernelInit failed\n");
1016 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
1020 /* Initialize the vertex buffers list */
1021 if (!RADEONDRIBufInit(ctx
, info
)) {
1022 fprintf(stderr
, "RADEONDRIBufInit failed\n");
1023 DRM_UNLOCK(ctx
->drmFD
, ctx
->pSAREA
, ctx
->serverContext
);
1027 RADEONColorTilingInit(ctx
, info
);
1029 /* Initialize IRQ */
1030 RADEONDRIIrqInit(ctx
, info
);
1032 /* Initialize kernel gart memory manager */
1033 RADEONDRIAgpHeapInit(ctx
, info
);
1035 fprintf(stderr
,"color tiling %sabled\n", info
->colorTiling
?"en":"dis");
1036 fprintf(stderr
,"page flipping %sabled\n", info
->page_flip_enable
?"en":"dis");
1037 /* Initialize the SAREA private data structure */
1039 drm_radeon_sarea_t
*pSAREAPriv
;
1040 pSAREAPriv
= (drm_radeon_sarea_t
*)(((char*)ctx
->pSAREA
) +
1041 sizeof(drm_sarea_t
));
1042 memset(pSAREAPriv
, 0, sizeof(*pSAREAPriv
));
1043 pSAREAPriv
->pfState
= info
->page_flip_enable
;
1047 /* Quick hack to clear the front & back buffers. Could also use
1048 * the clear ioctl to do this, but would need to setup hw state
1051 drimemsetio((char *)ctx
->FBAddress
+ info
->frontOffset
,
1053 info
->frontPitch
* ctx
->cpp
* ctx
->shared
.virtualHeight
);
1055 drimemsetio((char *)ctx
->FBAddress
+ info
->backOffset
,
1057 info
->backPitch
* ctx
->cpp
* ctx
->shared
.virtualHeight
);
1059 /* This is the struct passed to radeon_dri.so for its initialization */
1060 ctx
->driverClientMsg
= malloc(sizeof(RADEONDRIRec
));
1061 ctx
->driverClientMsgSize
= sizeof(RADEONDRIRec
);
1062 pRADEONDRI
= (RADEONDRIPtr
)ctx
->driverClientMsg
;
1063 pRADEONDRI
->deviceID
= info
->Chipset
;
1064 pRADEONDRI
->width
= ctx
->shared
.virtualWidth
;
1065 pRADEONDRI
->height
= ctx
->shared
.virtualHeight
;
1066 pRADEONDRI
->depth
= ctx
->bpp
; /* XXX: depth */
1067 pRADEONDRI
->bpp
= ctx
->bpp
;
1068 pRADEONDRI
->IsPCI
= ctx
->isPCI
;
1069 pRADEONDRI
->AGPMode
= ctx
->agpmode
;
1070 pRADEONDRI
->frontOffset
= info
->frontOffset
;
1071 pRADEONDRI
->frontPitch
= info
->frontPitch
;
1072 pRADEONDRI
->backOffset
= info
->backOffset
;
1073 pRADEONDRI
->backPitch
= info
->backPitch
;
1074 pRADEONDRI
->depthOffset
= info
->depthOffset
;
1075 pRADEONDRI
->depthPitch
= info
->depthPitch
;
1076 pRADEONDRI
->textureOffset
= info
->textureOffset
;
1077 pRADEONDRI
->textureSize
= info
->textureSize
;
1078 pRADEONDRI
->log2TexGran
= info
->log2TexGran
;
1079 pRADEONDRI
->registerHandle
= info
->registerHandle
;
1080 pRADEONDRI
->registerSize
= info
->registerSize
;
1081 pRADEONDRI
->statusHandle
= info
->ringReadPtrHandle
;
1082 pRADEONDRI
->statusSize
= info
->ringReadMapSize
;
1083 pRADEONDRI
->gartTexHandle
= info
->gartTexHandle
;
1084 pRADEONDRI
->gartTexMapSize
= info
->gartTexMapSize
;
1085 pRADEONDRI
->log2GARTTexGran
= info
->log2GARTTexGran
;
1086 pRADEONDRI
->gartTexOffset
= info
->gartTexStart
;
1087 pRADEONDRI
->sarea_priv_offset
= sizeof(drm_sarea_t
);
1089 /* Don't release the lock now - let the VT switch handler do it. */
1096 * \brief Get Radeon chip family from chipset number.
1098 * \param info driver private data.
1100 * \return non-zero on success, or zero on failure.
1102 * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily
1103 * according to the value of RADEONInfoRec::Chipset. Fails if the
1104 * chipset is unrecognized or not appropriate for this driver (i.e., not
1105 * an r100 style radeon)
1107 static int get_chipfamily_from_chipset( RADEONInfoPtr info
)
1109 switch (info
->Chipset
) {
1110 case PCI_CHIP_RADEON_LY
:
1111 case PCI_CHIP_RADEON_LZ
:
1112 info
->ChipFamily
= CHIP_FAMILY_M6
;
1115 case PCI_CHIP_RADEON_QY
:
1116 case PCI_CHIP_RADEON_QZ
:
1117 info
->ChipFamily
= CHIP_FAMILY_VE
;
1120 case PCI_CHIP_R200_QL
:
1121 case PCI_CHIP_R200_QN
:
1122 case PCI_CHIP_R200_QO
:
1123 case PCI_CHIP_R200_Ql
:
1124 case PCI_CHIP_R200_BB
:
1125 info
->ChipFamily
= CHIP_FAMILY_R200
;
1128 case PCI_CHIP_RV200_QW
: /* RV200 desktop */
1129 case PCI_CHIP_RV200_QX
:
1130 info
->ChipFamily
= CHIP_FAMILY_RV200
;
1133 case PCI_CHIP_RADEON_LW
:
1134 case PCI_CHIP_RADEON_LX
:
1135 info
->ChipFamily
= CHIP_FAMILY_M7
;
1138 case PCI_CHIP_RV250_Id
:
1139 case PCI_CHIP_RV250_Ie
:
1140 case PCI_CHIP_RV250_If
:
1141 case PCI_CHIP_RV250_Ig
:
1142 info
->ChipFamily
= CHIP_FAMILY_RV250
;
1145 case PCI_CHIP_RV250_Ld
:
1146 case PCI_CHIP_RV250_Le
:
1147 case PCI_CHIP_RV250_Lf
:
1148 case PCI_CHIP_RV250_Lg
:
1149 info
->ChipFamily
= CHIP_FAMILY_M9
;
1152 case PCI_CHIP_RV280_Y_
:
1153 case PCI_CHIP_RV280_Ya
:
1154 case PCI_CHIP_RV280_Yb
:
1155 case PCI_CHIP_RV280_Yc
:
1156 info
->ChipFamily
= CHIP_FAMILY_RV280
;
1159 case PCI_CHIP_R300_ND
:
1160 case PCI_CHIP_R300_NE
:
1161 case PCI_CHIP_R300_NF
:
1162 case PCI_CHIP_R300_NG
:
1163 info
->ChipFamily
= CHIP_FAMILY_R300
;
1167 /* Original Radeon/7200 */
1168 info
->ChipFamily
= CHIP_FAMILY_RADEON
;
1176 * \brief Validate the fbdev mode.
1178 * \param ctx display handle.
1180 * \return one on success, or zero on failure.
1182 * Saves some registers and returns 1.
1184 * \sa radeonValidateMode().
1186 static int radeonValidateMode( const DRIDriverContext
*ctx
)
1188 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
1189 RADEONInfoPtr info
= ctx
->driverPrivate
;
1191 info
->gen_int_cntl
= INREG(RADEON_GEN_INT_CNTL
);
1192 info
->crtc_offset_cntl
= INREG(RADEON_CRTC_OFFSET_CNTL
);
1194 if (info
->colorTiling
)
1195 info
->crtc_offset_cntl
|= RADEON_CRTC_TILE_EN
;
1201 * \brief Examine mode returned by fbdev.
1203 * \param ctx display handle.
1205 * \return one on success, or zero on failure.
1207 * Restores registers that fbdev has clobbered and returns 1.
1209 * \sa radeonValidateMode().
1211 static int radeonPostValidateMode( const DRIDriverContext
*ctx
)
1213 unsigned char *RADEONMMIO
= ctx
->MMIOAddress
;
1214 RADEONInfoPtr info
= ctx
->driverPrivate
;
1216 RADEONColorTilingInit( ctx
, info
);
1217 OUTREG(RADEON_GEN_INT_CNTL
, info
->gen_int_cntl
);
1218 if (info
->colorTiling
)
1219 info
->crtc_offset_cntl
|= RADEON_CRTC_TILE_EN
;
1220 OUTREG(RADEON_CRTC_OFFSET_CNTL
, info
->crtc_offset_cntl
);
1227 * \brief Initialize the framebuffer device mode
1229 * \param ctx display handle.
1231 * \return one on success, or zero on failure.
1233 * Fills in \p info with some default values and some information from \p ctx
1234 * and then calls RADEONScreenInit() for the screen initialization.
1236 * Before exiting clears the framebuffer memory accessing it directly.
1238 static int radeonInitFBDev( DRIDriverContext
*ctx
)
1240 RADEONInfoPtr info
= calloc(1, sizeof(*info
));
1243 int dummy
= ctx
->shared
.virtualWidth
;
1245 if (ctx
->colorTiling
==1)
1247 switch (ctx
->bpp
/ 8) {
1248 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 255) & ~255; break;
1249 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
1251 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 63) & ~63; break;
1254 switch (ctx
->bpp
/ 8) {
1255 case 1: dummy
= (ctx
->shared
.virtualWidth
+ 127) & ~127; break;
1256 case 2: dummy
= (ctx
->shared
.virtualWidth
+ 31) & ~31; break;
1258 case 4: dummy
= (ctx
->shared
.virtualWidth
+ 15) & ~15; break;
1262 ctx
->shared
.virtualWidth
= dummy
;
1263 ctx
->shared
.Width
= dummy
;
1266 fprintf(stderr
,"shared virtual width is %d\n", ctx
->shared
.virtualWidth
);
1267 ctx
->driverPrivate
= (void *)info
;
1269 info
->gartFastWrite
= RADEON_DEFAULT_AGP_FAST_WRITE
;
1270 info
->gartSize
= RADEON_DEFAULT_AGP_SIZE
;
1271 info
->gartTexSize
= RADEON_DEFAULT_AGP_TEX_SIZE
;
1272 info
->bufSize
= RADEON_DEFAULT_BUFFER_SIZE
;
1273 info
->ringSize
= RADEON_DEFAULT_RING_SIZE
;
1274 info
->page_flip_enable
= RADEON_DEFAULT_PAGE_FLIP
;
1275 info
->colorTiling
= ctx
->colorTiling
;
1277 info
->Chipset
= ctx
->chipset
;
1279 if (!get_chipfamily_from_chipset( info
)) {
1280 fprintf(stderr
, "Unknown or non-radeon chipset -- cannot continue\n");
1281 fprintf(stderr
, "==> Verify PCI BusID is correct in miniglx.conf\n");
1285 info
->frontPitch
= ctx
->shared
.virtualWidth
;
1286 info
->LinearAddr
= ctx
->FBStart
& 0xfc000000;
1289 if (!RADEONScreenInit( ctx
, info
))
1298 * \brief The screen is being closed, so clean up any state and free any
1299 * resources used by the DRI.
1301 * \param ctx display handle.
1303 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1306 static void radeonHaltFBDev( DRIDriverContext
*ctx
)
1308 drmUnmap( ctx
->pSAREA
, ctx
->shared
.SAREASize
);
1309 drmClose(ctx
->drmFD
);
1311 if (ctx
->driverPrivate
) {
1312 free(ctx
->driverPrivate
);
1313 ctx
->driverPrivate
= 0;
1318 extern void radeonNotifyFocus( int );
1321 * \brief Exported driver interface for Mini GLX.
1325 const struct DRIDriverRec __driDriver
= {
1327 radeonPostValidateMode
,
1330 RADEONEngineShutdown
,
1331 RADEONEngineRestore
,