From: Stephane Marchesin <marchesin@icps.u-strasbg.fr>
[mesa.git] / src / mesa / drivers / dri / radeon / server / radeon_dri.c
1 /**
2 * \file server/radeon_dri.c
3 * \brief File to perform the device-specific initialization tasks typically
4 * done in the X server.
5 *
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.
9 */
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <errno.h>
15 #include <unistd.h>
16
17 #include "driver.h"
18 #include "drm.h"
19
20 #include "radeon.h"
21 #include "radeon_dri.h"
22 #include "radeon_macros.h"
23 #include "radeon_reg.h"
24 #include "drm_sarea.h"
25
26 static size_t radeon_drm_page_size;
27
28 /**
29 * \brief Wait for free FIFO entries.
30 *
31 * \param ctx display handle.
32 * \param entries number of free entries to wait.
33 *
34 * It polls the free entries from the chip until it reaches the requested value
35 * or a timeout (3000 tries) occurs. Aborts the program if the FIFO times out.
36 */
37 static void RADEONWaitForFifo( const DRIDriverContext *ctx,
38 int entries )
39 {
40 unsigned char *RADEONMMIO = ctx->MMIOAddress;
41 int i;
42
43 for (i = 0; i < 3000; i++) {
44 int fifo_slots =
45 INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
46 if (fifo_slots >= entries) return;
47 }
48
49 /* There are recoveries possible, but I haven't seen them work
50 * in practice:
51 */
52 fprintf(stderr, "FIFO timed out: %d entries, stat=0x%08x\n",
53 INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
54 INREG(RADEON_RBBM_STATUS));
55 exit(1);
56 }
57
58 /**
59 * \brief Read a PLL register.
60 *
61 * \param ctx display handle.
62 * \param addr PLL register index.
63 *
64 * \return value of the PLL register.
65 */
66 static unsigned int RADEONINPLL( const DRIDriverContext *ctx, int addr)
67 {
68 unsigned char *RADEONMMIO = ctx->MMIOAddress;
69 unsigned int data;
70
71 OUTREG8(RADEON_CLOCK_CNTL_INDEX, addr & 0x3f);
72 data = INREG(RADEON_CLOCK_CNTL_DATA);
73
74 return data;
75 }
76
77 /**
78 * \brief Reset graphics card to known state.
79 *
80 * \param ctx display handle.
81 *
82 * Resets the values of several Radeon registers.
83 */
84 static void RADEONEngineReset( const DRIDriverContext *ctx )
85 {
86 unsigned char *RADEONMMIO = ctx->MMIOAddress;
87 unsigned int clock_cntl_index;
88 unsigned int mclk_cntl;
89 unsigned int rbbm_soft_reset;
90 unsigned int host_path_cntl;
91 int i;
92
93 OUTREGP(RADEON_RB2D_DSTCACHE_CTLSTAT,
94 RADEON_RB2D_DC_FLUSH_ALL,
95 ~RADEON_RB2D_DC_FLUSH_ALL);
96 for (i = 0; i < 512; i++) {
97 if (!(INREG(RADEON_RB2D_DSTCACHE_CTLSTAT) & RADEON_RB2D_DC_BUSY))
98 break;
99 }
100
101 clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX);
102
103 mclk_cntl = INPLL(ctx, RADEON_MCLK_CNTL);
104 OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl |
105 RADEON_FORCEON_MCLKA |
106 RADEON_FORCEON_MCLKB |
107 RADEON_FORCEON_YCLKA |
108 RADEON_FORCEON_YCLKB |
109 RADEON_FORCEON_MC |
110 RADEON_FORCEON_AIC));
111
112 /* Soft resetting HDP thru RBBM_SOFT_RESET register can cause some
113 * unexpected behaviour on some machines. Here we use
114 * RADEON_HOST_PATH_CNTL to reset it.
115 */
116 host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
117 rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
118
119 OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
120 RADEON_SOFT_RESET_CP |
121 RADEON_SOFT_RESET_HI |
122 RADEON_SOFT_RESET_SE |
123 RADEON_SOFT_RESET_RE |
124 RADEON_SOFT_RESET_PP |
125 RADEON_SOFT_RESET_E2 |
126 RADEON_SOFT_RESET_RB));
127 INREG(RADEON_RBBM_SOFT_RESET);
128 OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
129 (unsigned int) ~(RADEON_SOFT_RESET_CP |
130 RADEON_SOFT_RESET_HI |
131 RADEON_SOFT_RESET_SE |
132 RADEON_SOFT_RESET_RE |
133 RADEON_SOFT_RESET_PP |
134 RADEON_SOFT_RESET_E2 |
135 RADEON_SOFT_RESET_RB)));
136 INREG(RADEON_RBBM_SOFT_RESET);
137
138 OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl | RADEON_HDP_SOFT_RESET);
139 INREG(RADEON_HOST_PATH_CNTL);
140 OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);
141
142 OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
143
144 OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
145 OUTPLL(RADEON_MCLK_CNTL, mclk_cntl);
146 }
147
148 /**
149 * \brief Restore the drawing engine.
150 *
151 * \param ctx display handle
152 *
153 * Resets the graphics card and sets initial values for several registers of
154 * the card's drawing engine.
155 *
156 * Turns on the radeon command processor engine (i.e., the ringbuffer).
157 */
158 static int RADEONEngineRestore( const DRIDriverContext *ctx )
159 {
160 RADEONInfoPtr info = ctx->driverPrivate;
161 unsigned char *RADEONMMIO = ctx->MMIOAddress;
162 int pitch64, datatype, dp_gui_master_cntl, err;
163
164 fprintf(stderr, "%s\n", __FUNCTION__);
165
166 OUTREG(RADEON_RB3D_CNTL, 0);
167 RADEONEngineReset( ctx );
168
169 switch (ctx->bpp) {
170 case 16: datatype = 4; break;
171 case 32: datatype = 6; break;
172 default: return 0;
173 }
174
175 dp_gui_master_cntl =
176 ((datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
177 | RADEON_GMC_CLR_CMP_CNTL_DIS);
178
179 pitch64 = ((ctx->shared.virtualWidth * (ctx->bpp / 8) + 0x3f)) >> 6;
180
181 RADEONWaitForFifo(ctx, 1);
182 OUTREG(RADEON_DEFAULT_OFFSET, ((INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000)
183 | (pitch64 << 22)));
184
185 RADEONWaitForFifo(ctx, 1);
186 OUTREG(RADEON_SURFACE_CNTL, RADEON_SURF_TRANSLATION_DIS);
187
188 RADEONWaitForFifo(ctx, 1);
189 OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
190 | RADEON_DEFAULT_SC_BOTTOM_MAX));
191
192 RADEONWaitForFifo(ctx, 1);
193 OUTREG(RADEON_DP_GUI_MASTER_CNTL, (dp_gui_master_cntl
194 | RADEON_GMC_BRUSH_SOLID_COLOR
195 | RADEON_GMC_SRC_DATATYPE_COLOR));
196
197 RADEONWaitForFifo(ctx, 7);
198 OUTREG(RADEON_DST_LINE_START, 0);
199 OUTREG(RADEON_DST_LINE_END, 0);
200 OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
201 OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0);
202 OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
203 OUTREG(RADEON_DP_SRC_BKGD_CLR, 0);
204 OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff);
205 OUTREG(RADEON_AUX_SC_CNTL, 0);
206
207 /* RADEONWaitForIdleMMIO(ctx); */
208 usleep(100);
209
210
211 OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
212 OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
213
214 /* Initialize and start the CP if required */
215 if ((err = drmCommandNone(ctx->drmFD, DRM_RADEON_CP_START)) != 0) {
216 fprintf(stderr, "%s: CP start %d\n", __FUNCTION__, err);
217 return 0;
218 }
219
220 return 1;
221 }
222
223
224 /**
225 * \brief Shutdown the drawing engine.
226 *
227 * \param ctx display handle
228 *
229 * Turns off the command processor engine & restores the graphics card
230 * to a state that fbdev understands.
231 */
232 static int RADEONEngineShutdown( const DRIDriverContext *ctx )
233 {
234 drm_radeon_cp_stop_t stop;
235 int ret, i;
236
237 stop.flush = 1;
238 stop.idle = 1;
239
240 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop,
241 sizeof(drm_radeon_cp_stop_t));
242
243 if (ret == 0) {
244 return 0;
245 } else if (errno != EBUSY) {
246 return -errno;
247 }
248
249 stop.flush = 0;
250
251 i = 0;
252 do {
253 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP, &stop,
254 sizeof(drm_radeon_cp_stop_t));
255 } while (ret && errno == EBUSY && i++ < 10);
256
257 if (ret == 0) {
258 return 0;
259 } else if (errno != EBUSY) {
260 return -errno;
261 }
262
263 stop.idle = 0;
264
265 if (drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_STOP,
266 &stop, sizeof(drm_radeon_cp_stop_t))) {
267 return -errno;
268 } else {
269 return 0;
270 }
271 }
272
273 /**
274 * \brief Compute base 2 logarithm.
275 *
276 * \param val value.
277 *
278 * \return base 2 logarithm of \p val.
279 */
280 static int RADEONMinBits(int val)
281 {
282 int bits;
283
284 if (!val) return 1;
285 for (bits = 0; val; val >>= 1, ++bits);
286 return bits;
287 }
288
289 /**
290 * \brief Initialize the AGP state
291 *
292 * \param ctx display handle.
293 * \param info driver private data.
294 *
295 * \return one on success, or zero on failure.
296 *
297 * Acquires and enables the AGP device. Reserves memory in the AGP space for
298 * the ring buffer, vertex buffers and textures. Initialize the Radeon
299 * registers to point to that memory and add client mappings.
300 */
301 static int RADEONDRIAgpInit( const DRIDriverContext *ctx, RADEONInfoPtr info)
302 {
303 unsigned char *RADEONMMIO = ctx->MMIOAddress;
304 unsigned long mode;
305 int ret;
306 int s, l;
307
308 if (drmAgpAcquire(ctx->drmFD) < 0) {
309 fprintf(stderr, "[gart] AGP not available\n");
310 return 0;
311 }
312
313 /* Modify the mode if the default mode is not appropriate for this
314 * particular combination of graphics card and AGP chipset.
315 */
316 mode = drmAgpGetMode(ctx->drmFD); /* Default mode */
317
318 /* Disable fast write entirely - too many lockups.
319 */
320 mode &= ~RADEON_AGP_MODE_MASK;
321 switch (ctx->agpmode) {
322 case 4: mode |= RADEON_AGP_4X_MODE;
323 case 2: mode |= RADEON_AGP_2X_MODE;
324 case 1: default: mode |= RADEON_AGP_1X_MODE;
325 }
326
327 if (drmAgpEnable(ctx->drmFD, mode) < 0) {
328 fprintf(stderr, "[gart] AGP not enabled\n");
329 drmAgpRelease(ctx->drmFD);
330 return 0;
331 }
332 else
333 fprintf(stderr, "[gart] AGP enabled at %dx\n", ctx->agpmode);
334
335 /* Workaround for some hardware bugs */
336 if (info->ChipFamily < CHIP_FAMILY_R200)
337 OUTREG(RADEON_AGP_CNTL, INREG(RADEON_AGP_CNTL) | 0x000e0000);
338
339 info->gartOffset = 0;
340
341 if ((ret = drmAgpAlloc(ctx->drmFD, info->gartSize*1024*1024, 0, NULL,
342 &info->gartMemHandle)) < 0) {
343 fprintf(stderr, "[gart] Out of memory (%d)\n", ret);
344 drmAgpRelease(ctx->drmFD);
345 return 0;
346 }
347 fprintf(stderr,
348 "[gart] %d kB allocated with handle 0x%08x\n",
349 info->gartSize*1024, (unsigned)info->gartMemHandle);
350
351 if (drmAgpBind(ctx->drmFD,
352 info->gartMemHandle, info->gartOffset) < 0) {
353 fprintf(stderr, "[gart] Could not bind\n");
354 drmAgpFree(ctx->drmFD, info->gartMemHandle);
355 drmAgpRelease(ctx->drmFD);
356 return 0;
357 }
358
359 /* Initialize the CP ring buffer data */
360 info->ringStart = info->gartOffset;
361 info->ringMapSize = info->ringSize*1024*1024 + radeon_drm_page_size;
362
363 info->ringReadOffset = info->ringStart + info->ringMapSize;
364 info->ringReadMapSize = radeon_drm_page_size;
365
366 /* Reserve space for vertex/indirect buffers */
367 info->bufStart = info->ringReadOffset + info->ringReadMapSize;
368 info->bufMapSize = info->bufSize*1024*1024;
369
370 /* Reserve the rest for AGP textures */
371 info->gartTexStart = info->bufStart + info->bufMapSize;
372 s = (info->gartSize*1024*1024 - info->gartTexStart);
373 l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
374 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
375 info->gartTexMapSize = (s >> l) << l;
376 info->log2GARTTexGran = l;
377
378 if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
379 DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) {
380 fprintf(stderr, "[gart] Could not add ring mapping\n");
381 return 0;
382 }
383 fprintf(stderr, "[gart] ring handle = 0x%08lx\n", info->ringHandle);
384
385
386 if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
387 DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) {
388 fprintf(stderr,
389 "[gart] Could not add ring read ptr mapping\n");
390 return 0;
391 }
392
393 fprintf(stderr,
394 "[gart] ring read ptr handle = 0x%08lx\n",
395 info->ringReadPtrHandle);
396
397 if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
398 DRM_AGP, 0, &info->bufHandle) < 0) {
399 fprintf(stderr,
400 "[gart] Could not add vertex/indirect buffers mapping\n");
401 return 0;
402 }
403 fprintf(stderr,
404 "[gart] vertex/indirect buffers handle = 0x%08lx\n",
405 info->bufHandle);
406
407 if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize,
408 DRM_AGP, 0, &info->gartTexHandle) < 0) {
409 fprintf(stderr,
410 "[gart] Could not add AGP texture map mapping\n");
411 return 0;
412 }
413 fprintf(stderr,
414 "[gart] AGP texture map handle = 0x%08lx\n",
415 info->gartTexHandle);
416
417 /* Initialize Radeon's AGP registers */
418 /* Ring buffer is at AGP offset 0 */
419 OUTREG(RADEON_AGP_BASE, info->ringHandle);
420
421 return 1;
422 }
423
424 /* Initialize the PCI GART state. Request memory for use in PCI space,
425 * and initialize the Radeon registers to point to that memory.
426 */
427 static int RADEONDRIPciInit(const DRIDriverContext *ctx, RADEONInfoPtr info)
428 {
429 int ret;
430 int flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL;
431 int s, l;
432
433 ret = drmScatterGatherAlloc(ctx->drmFD, info->gartSize*1024*1024,
434 &info->gartMemHandle);
435 if (ret < 0) {
436 fprintf(stderr, "[pci] Out of memory (%d)\n", ret);
437 return 0;
438 }
439 fprintf(stderr,
440 "[pci] %d kB allocated with handle 0x%08x\n",
441 info->gartSize*1024, info->gartMemHandle);
442
443 info->gartOffset = 0;
444
445 /* Initialize the CP ring buffer data */
446 info->ringStart = info->gartOffset;
447 info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE;
448
449 info->ringReadOffset = info->ringStart + info->ringMapSize;
450 info->ringReadMapSize = DRM_PAGE_SIZE;
451
452 /* Reserve space for vertex/indirect buffers */
453 info->bufStart = info->ringReadOffset + info->ringReadMapSize;
454 info->bufMapSize = info->bufSize*1024*1024;
455
456 /* Reserve the rest for AGP textures */
457 info->gartTexStart = info->bufStart + info->bufMapSize;
458 s = (info->gartSize*1024*1024 - info->gartTexStart);
459 l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS);
460 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
461 info->gartTexMapSize = (s >> l) << l;
462 info->log2GARTTexGran = l;
463
464 if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize,
465 DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) {
466 fprintf(stderr,
467 "[pci] Could not add ring mapping\n");
468 return 0;
469 }
470 fprintf(stderr,
471 "[pci] ring handle = 0x%08lx\n", info->ringHandle);
472
473 if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize,
474 DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) {
475 fprintf(stderr,
476 "[pci] Could not add ring read ptr mapping\n");
477 return 0;
478 }
479 fprintf(stderr,
480 "[pci] ring read ptr handle = 0x%08lx\n",
481 info->ringReadPtrHandle);
482
483 if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize,
484 DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) {
485 fprintf(stderr,
486 "[pci] Could not add vertex/indirect buffers mapping\n");
487 return 0;
488 }
489 fprintf(stderr,
490 "[pci] vertex/indirect buffers handle = 0x%08lx\n",
491 info->bufHandle);
492
493 if (drmAddMap(ctx->drmFD, info->gartTexStart, info->gartTexMapSize,
494 DRM_SCATTER_GATHER, 0, &info->gartTexHandle) < 0) {
495 fprintf(stderr,
496 "[pci] Could not add GART texture map mapping\n");
497 return 0;
498 }
499 fprintf(stderr,
500 "[pci] GART texture map handle = 0x%08lx\n",
501 info->gartTexHandle);
502
503 return 1;
504 }
505
506
507 /**
508 * \brief Initialize the kernel data structures and enable the CP engine.
509 *
510 * \param ctx display handle.
511 * \param info driver private data.
512 *
513 * \return non-zero on success, or zero on failure.
514 *
515 * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
516 * all the parameters in a drm_radeon_init_t structure.
517 */
518 static int RADEONDRIKernelInit( const DRIDriverContext *ctx,
519 RADEONInfoPtr info)
520 {
521 int cpp = ctx->bpp / 8;
522 drm_radeon_init_t drmInfo;
523 int ret;
524
525 memset(&drmInfo, 0, sizeof(drm_radeon_init_t));
526
527 if ( (info->ChipFamily == CHIP_FAMILY_R200) ||
528 (info->ChipFamily == CHIP_FAMILY_RV250) ||
529 (info->ChipFamily == CHIP_FAMILY_M9) ||
530 (info->ChipFamily == CHIP_FAMILY_RV280) )
531 drmInfo.func = RADEON_INIT_R200_CP;
532 else
533 drmInfo.func = RADEON_INIT_CP;
534
535 /* This is the struct passed to the kernel module for its initialization */
536 drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
537 drmInfo.is_pci = ctx->isPCI;
538 drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE;
539 drmInfo.gart_size = info->gartSize*1024*1024;
540 drmInfo.ring_size = info->ringSize*1024*1024;
541 drmInfo.usec_timeout = 1000;
542 drmInfo.fb_bpp = ctx->bpp;
543 drmInfo.depth_bpp = ctx->bpp;
544 drmInfo.front_offset = info->frontOffset;
545 drmInfo.front_pitch = info->frontPitch * cpp;
546 drmInfo.back_offset = info->backOffset;
547 drmInfo.back_pitch = info->backPitch * cpp;
548 drmInfo.depth_offset = info->depthOffset;
549 drmInfo.depth_pitch = info->depthPitch * cpp;
550 drmInfo.fb_offset = info->LinearAddr;
551 drmInfo.mmio_offset = info->registerHandle;
552 drmInfo.ring_offset = info->ringHandle;
553 drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
554 drmInfo.buffers_offset = info->bufHandle;
555 drmInfo.gart_textures_offset = info->gartTexHandle;
556
557 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_INIT, &drmInfo,
558 sizeof(drm_radeon_init_t));
559
560 return ret >= 0;
561 }
562
563
564 /**
565 * \brief Initialize the AGP heap.
566 *
567 * \param ctx display handle.
568 * \param info driver private data.
569 *
570 * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
571 * all the parameters in a drm_radeon_mem_init_heap structure.
572 */
573 static void RADEONDRIAgpHeapInit(const DRIDriverContext *ctx,
574 RADEONInfoPtr info)
575 {
576 drm_radeon_mem_init_heap_t drmHeap;
577
578 /* Start up the simple memory manager for gart space */
579 drmHeap.region = RADEON_MEM_REGION_GART;
580 drmHeap.start = 0;
581 drmHeap.size = info->gartTexMapSize;
582
583 if (drmCommandWrite(ctx->drmFD, DRM_RADEON_INIT_HEAP,
584 &drmHeap, sizeof(drmHeap))) {
585 fprintf(stderr,
586 "[drm] Failed to initialized gart heap manager\n");
587 } else {
588 fprintf(stderr,
589 "[drm] Initialized kernel gart heap manager, %d\n",
590 info->gartTexMapSize);
591 }
592 }
593
594 /**
595 * \brief Add a map for the vertex buffers that will be accessed by any
596 * DRI-based clients.
597 *
598 * \param ctx display handle.
599 * \param info driver private data.
600 *
601 * \return one on success, or zero on failure.
602 *
603 * Calls drmAddBufs() with the previously allocated vertex buffers.
604 */
605 static int RADEONDRIBufInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
606 {
607 /* Initialize vertex buffers */
608 info->bufNumBufs = drmAddBufs(ctx->drmFD,
609 info->bufMapSize / RADEON_BUFFER_SIZE,
610 RADEON_BUFFER_SIZE,
611 ctx->isPCI ? DRM_SG_BUFFER : DRM_AGP_BUFFER,
612 info->bufStart);
613
614 if (info->bufNumBufs <= 0) {
615 fprintf(stderr,
616 "[drm] Could not create vertex/indirect buffers list\n");
617 return 0;
618 }
619 fprintf(stderr,
620 "[drm] Added %d %d byte vertex/indirect buffers\n",
621 info->bufNumBufs, RADEON_BUFFER_SIZE);
622
623 return 1;
624 }
625
626 /**
627 * \brief Install an IRQ handler.
628 *
629 * \param ctx display handle.
630 * \param info driver private data.
631 *
632 * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
633 * IRQ-free operation on failure.
634 */
635 static void RADEONDRIIrqInit(const DRIDriverContext *ctx,
636 RADEONInfoPtr info)
637 {
638 if (!info->irq) {
639 info->irq = drmGetInterruptFromBusID(ctx->drmFD,
640 ctx->pciBus,
641 ctx->pciDevice,
642 ctx->pciFunc);
643
644 if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
645 fprintf(stderr,
646 "[drm] failure adding irq handler, "
647 "there is a device already using that irq\n"
648 "[drm] falling back to irq-free operation\n");
649 info->irq = 0;
650 }
651 }
652
653 if (info->irq)
654 fprintf(stderr,
655 "[drm] dma control initialized, using IRQ %d\n",
656 info->irq);
657 }
658
659 static int RADEONCheckDRMVersion( const DRIDriverContext *ctx,
660 RADEONInfoPtr info )
661 {
662 drmVersionPtr version;
663
664 version = drmGetVersion(ctx->drmFD);
665 if (version) {
666 int req_minor, req_patch;
667
668 /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
669 */
670 req_minor = 8;
671 req_patch = 0;
672
673 if (version->version_major != 1 ||
674 version->version_minor < req_minor ||
675 (version->version_minor == req_minor &&
676 version->version_patchlevel < req_patch)) {
677 /* Incompatible drm version */
678 fprintf(stderr,
679 "[dri] RADEONDRIScreenInit failed because of a version "
680 "mismatch.\n"
681 "[dri] radeon.o kernel module version is %d.%d.%d "
682 "but version 1.%d.%d or newer is needed.\n"
683 "[dri] Disabling DRI.\n",
684 version->version_major,
685 version->version_minor,
686 version->version_patchlevel,
687 req_minor,
688 req_patch);
689 drmFreeVersion(version);
690 return 0;
691 }
692
693 info->drmMinor = version->version_minor;
694 drmFreeVersion(version);
695 }
696
697 return 1;
698 }
699
700 static int RADEONMemoryInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
701 {
702 int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
703 int cpp = ctx->cpp;
704 int bufferSize = ((ctx->shared.virtualHeight * width_bytes
705 + RADEON_BUFFER_ALIGN)
706 & ~RADEON_BUFFER_ALIGN);
707 int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
708 + RADEON_BUFFER_ALIGN)
709 & ~RADEON_BUFFER_ALIGN);
710 int l;
711
712 info->frontOffset = 0;
713 info->frontPitch = ctx->shared.virtualWidth;
714
715 fprintf(stderr,
716 "Using %d MB AGP aperture\n", info->gartSize);
717 fprintf(stderr,
718 "Using %d MB for the ring buffer\n", info->ringSize);
719 fprintf(stderr,
720 "Using %d MB for vertex/indirect buffers\n", info->bufSize);
721 fprintf(stderr,
722 "Using %d MB for AGP textures\n", info->gartTexSize);
723
724 /* Front, back and depth buffers - everything else texture??
725 */
726 info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
727
728 if (info->textureSize < 0)
729 return 0;
730
731 l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
732 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
733
734 /* Round the texture size up to the nearest whole number of
735 * texture regions. Again, be greedy about this, don't
736 * round down.
737 */
738 info->log2TexGran = l;
739 info->textureSize = (info->textureSize >> l) << l;
740
741 /* Set a minimum usable local texture heap size. This will fit
742 * two 256x256x32bpp textures.
743 */
744 if (info->textureSize < 512 * 1024) {
745 info->textureOffset = 0;
746 info->textureSize = 0;
747 }
748
749 /* Reserve space for textures */
750 info->textureOffset = ((ctx->shared.fbSize - info->textureSize +
751 RADEON_BUFFER_ALIGN) &
752 ~RADEON_BUFFER_ALIGN);
753
754 /* Reserve space for the shared depth
755 * buffer.
756 */
757 info->depthOffset = ((info->textureOffset - depthSize +
758 RADEON_BUFFER_ALIGN) &
759 ~RADEON_BUFFER_ALIGN);
760 info->depthPitch = ctx->shared.virtualWidth;
761
762 info->backOffset = ((info->depthOffset - bufferSize +
763 RADEON_BUFFER_ALIGN) &
764 ~RADEON_BUFFER_ALIGN);
765 info->backPitch = ctx->shared.virtualWidth;
766
767
768 fprintf(stderr,
769 "Will use back buffer at offset 0x%x\n",
770 info->backOffset);
771 fprintf(stderr,
772 "Will use depth buffer at offset 0x%x\n",
773 info->depthOffset);
774 fprintf(stderr,
775 "Will use %d kb for textures at offset 0x%x\n",
776 info->textureSize/1024, info->textureOffset);
777
778 info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
779 (info->frontOffset >> 10));
780
781 info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
782 (info->backOffset >> 10));
783
784 info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
785 (info->depthOffset >> 10));
786
787 return 1;
788 }
789
790
791
792 /**
793 * Called at the start of each server generation.
794 *
795 * \param ctx display handle.
796 * \param info driver private data.
797 *
798 * \return non-zero on success, or zero on failure.
799 *
800 * Performs static frame buffer allocation. Opens the DRM device and add maps
801 * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
802 * information. Creates a \e server context to grab the lock for the
803 * initialization ioctls and calls the other initilization functions in this
804 * file. Starts the CP engine via the DRM_RADEON_CP_START command.
805 *
806 * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
807 * initialization.
808 */
809 static int RADEONScreenInit( DRIDriverContext *ctx, RADEONInfoPtr info )
810 {
811 RADEONDRIPtr pRADEONDRI;
812 int err;
813
814 usleep(100);
815 /*assert(!ctx->IsClient);*/
816
817 {
818 int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
819 int maxy = ctx->shared.fbSize / width_bytes;
820
821
822 if (maxy <= ctx->shared.virtualHeight * 3) {
823 fprintf(stderr,
824 "Static buffer allocation failed -- "
825 "need at least %d kB video memory (have %d kB)\n",
826 (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
827 ctx->cpp * 3 + 1023) / 1024,
828 ctx->shared.fbSize / 1024);
829 return 0;
830 }
831 }
832
833
834 if (info->ChipFamily >= CHIP_FAMILY_R300) {
835 fprintf(stderr,
836 "Direct rendering not yet supported on "
837 "Radeon 9700 and newer cards\n");
838 return 0;
839 }
840
841 radeon_drm_page_size = getpagesize();
842
843 info->registerSize = ctx->MMIOSize;
844 ctx->shared.SAREASize = SAREA_MAX;
845
846 /* Note that drmOpen will try to load the kernel module, if needed. */
847 ctx->drmFD = drmOpen("radeon", NULL );
848 if (ctx->drmFD < 0) {
849 fprintf(stderr, "[drm] drmOpen failed\n");
850 return 0;
851 }
852
853 if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
854 fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
855 ctx->drmFD, ctx->pciBusID, strerror(-err));
856 return 0;
857 }
858
859 if (drmAddMap( ctx->drmFD,
860 0,
861 ctx->shared.SAREASize,
862 DRM_SHM,
863 DRM_CONTAINS_LOCK,
864 &ctx->shared.hSAREA) < 0)
865 {
866 fprintf(stderr, "[drm] drmAddMap failed\n");
867 return 0;
868 }
869 fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
870 ctx->shared.SAREASize, ctx->shared.hSAREA);
871
872 if (drmMap( ctx->drmFD,
873 ctx->shared.hSAREA,
874 ctx->shared.SAREASize,
875 (drmAddressPtr)(&ctx->pSAREA)) < 0)
876 {
877 fprintf(stderr, "[drm] drmMap failed\n");
878 return 0;
879 }
880 memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
881 fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
882 ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
883
884 /* Need to AddMap the framebuffer and mmio regions here:
885 */
886 if (drmAddMap( ctx->drmFD,
887 (drm_handle_t)ctx->FBStart,
888 ctx->FBSize,
889 DRM_FRAME_BUFFER,
890 #ifndef _EMBEDDED
891 0,
892 #else
893 DRM_READ_ONLY,
894 #endif
895 &ctx->shared.hFrameBuffer) < 0)
896 {
897 fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
898 return 0;
899 }
900
901 fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
902 ctx->shared.hFrameBuffer);
903
904
905
906 if (drmAddMap(ctx->drmFD,
907 ctx->MMIOStart,
908 ctx->MMIOSize,
909 DRM_REGISTERS,
910 DRM_READ_ONLY,
911 &info->registerHandle) < 0) {
912 fprintf(stderr, "[drm] drmAddMap mmio failed\n");
913 return 0;
914 }
915 fprintf(stderr,
916 "[drm] register handle = 0x%08lx\n", info->registerHandle);
917
918 /* Check the radeon DRM version */
919 if (!RADEONCheckDRMVersion(ctx, info)) {
920 return 0;
921 }
922
923 if (ctx->isPCI) {
924 /* Initialize PCI */
925 if (!RADEONDRIPciInit(ctx, info))
926 return 0;
927 }
928 else {
929 /* Initialize AGP */
930 if (!RADEONDRIAgpInit(ctx, info))
931 return 0;
932 }
933
934 /* Memory manager setup */
935 if (!RADEONMemoryInit(ctx, info)) {
936 return 0;
937 }
938
939 /* Create a 'server' context so we can grab the lock for
940 * initialization ioctls.
941 */
942 if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
943 fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
944 return 0;
945 }
946
947 DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
948
949 /* Initialize the kernel data structures */
950 if (!RADEONDRIKernelInit(ctx, info)) {
951 fprintf(stderr, "RADEONDRIKernelInit failed\n");
952 DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
953 return 0;
954 }
955
956 /* Initialize the vertex buffers list */
957 if (!RADEONDRIBufInit(ctx, info)) {
958 fprintf(stderr, "RADEONDRIBufInit failed\n");
959 DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
960 return 0;
961 }
962
963 /* Initialize IRQ */
964 RADEONDRIIrqInit(ctx, info);
965
966 /* Initialize kernel gart memory manager */
967 RADEONDRIAgpHeapInit(ctx, info);
968
969 fprintf(stderr,"page flipping %sabled\n", info->page_flip_enable?"en":"dis");
970 /* Initialize the SAREA private data structure */
971 {
972 drm_radeon_sarea_t *pSAREAPriv;
973 pSAREAPriv = (drm_radeon_sarea_t *)(((char*)ctx->pSAREA) +
974 sizeof(drm_sarea_t));
975 memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
976 pSAREAPriv->pfState = info->page_flip_enable;
977 }
978
979
980 /* Quick hack to clear the front & back buffers. Could also use
981 * the clear ioctl to do this, but would need to setup hw state
982 * first.
983 */
984 memset((char *)ctx->FBAddress + info->frontOffset,
985 0,
986 info->frontPitch * ctx->cpp * ctx->shared.virtualHeight );
987
988 memset((char *)ctx->FBAddress + info->backOffset,
989 0,
990 info->backPitch * ctx->cpp * ctx->shared.virtualHeight );
991
992
993 /* This is the struct passed to radeon_dri.so for its initialization */
994 ctx->driverClientMsg = malloc(sizeof(RADEONDRIRec));
995 ctx->driverClientMsgSize = sizeof(RADEONDRIRec);
996 pRADEONDRI = (RADEONDRIPtr)ctx->driverClientMsg;
997 pRADEONDRI->deviceID = info->Chipset;
998 pRADEONDRI->width = ctx->shared.virtualWidth;
999 pRADEONDRI->height = ctx->shared.virtualHeight;
1000 pRADEONDRI->depth = ctx->bpp; /* XXX: depth */
1001 pRADEONDRI->bpp = ctx->bpp;
1002 pRADEONDRI->IsPCI = ctx->isPCI;
1003 pRADEONDRI->AGPMode = ctx->agpmode;
1004 pRADEONDRI->frontOffset = info->frontOffset;
1005 pRADEONDRI->frontPitch = info->frontPitch;
1006 pRADEONDRI->backOffset = info->backOffset;
1007 pRADEONDRI->backPitch = info->backPitch;
1008 pRADEONDRI->depthOffset = info->depthOffset;
1009 pRADEONDRI->depthPitch = info->depthPitch;
1010 pRADEONDRI->textureOffset = info->textureOffset;
1011 pRADEONDRI->textureSize = info->textureSize;
1012 pRADEONDRI->log2TexGran = info->log2TexGran;
1013 pRADEONDRI->registerHandle = info->registerHandle;
1014 pRADEONDRI->registerSize = info->registerSize;
1015 pRADEONDRI->statusHandle = info->ringReadPtrHandle;
1016 pRADEONDRI->statusSize = info->ringReadMapSize;
1017 pRADEONDRI->gartTexHandle = info->gartTexHandle;
1018 pRADEONDRI->gartTexMapSize = info->gartTexMapSize;
1019 pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran;
1020 pRADEONDRI->gartTexOffset = info->gartTexStart;
1021 pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t);
1022
1023 /* Don't release the lock now - let the VT switch handler do it. */
1024
1025 return 1;
1026 }
1027
1028
1029 /**
1030 * \brief Get Radeon chip family from chipset number.
1031 *
1032 * \param info driver private data.
1033 *
1034 * \return non-zero on success, or zero on failure.
1035 *
1036 * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily
1037 * according to the value of RADEONInfoRec::Chipset. Fails if the
1038 * chipset is unrecognized or not appropriate for this driver (i.e., not
1039 * an r100 style radeon)
1040 */
1041 static int get_chipfamily_from_chipset( RADEONInfoPtr info )
1042 {
1043 switch (info->Chipset) {
1044 case PCI_CHIP_RADEON_LY:
1045 case PCI_CHIP_RADEON_LZ:
1046 info->ChipFamily = CHIP_FAMILY_M6;
1047 break;
1048
1049 case PCI_CHIP_RADEON_QY:
1050 case PCI_CHIP_RADEON_QZ:
1051 info->ChipFamily = CHIP_FAMILY_VE;
1052 break;
1053
1054 case PCI_CHIP_R200_QL:
1055 case PCI_CHIP_R200_QN:
1056 case PCI_CHIP_R200_QO:
1057 case PCI_CHIP_R200_Ql:
1058 case PCI_CHIP_R200_BB:
1059 info->ChipFamily = CHIP_FAMILY_R200;
1060 break;
1061
1062 case PCI_CHIP_RV200_QW: /* RV200 desktop */
1063 case PCI_CHIP_RV200_QX:
1064 info->ChipFamily = CHIP_FAMILY_RV200;
1065 break;
1066
1067 case PCI_CHIP_RADEON_LW:
1068 case PCI_CHIP_RADEON_LX:
1069 info->ChipFamily = CHIP_FAMILY_M7;
1070 break;
1071
1072 case PCI_CHIP_RV250_Id:
1073 case PCI_CHIP_RV250_Ie:
1074 case PCI_CHIP_RV250_If:
1075 case PCI_CHIP_RV250_Ig:
1076 info->ChipFamily = CHIP_FAMILY_RV250;
1077 break;
1078
1079 case PCI_CHIP_RV250_Ld:
1080 case PCI_CHIP_RV250_Le:
1081 case PCI_CHIP_RV250_Lf:
1082 case PCI_CHIP_RV250_Lg:
1083 info->ChipFamily = CHIP_FAMILY_M9;
1084 break;
1085
1086 case PCI_CHIP_RV280_Y_:
1087 case PCI_CHIP_RV280_Ya:
1088 case PCI_CHIP_RV280_Yb:
1089 case PCI_CHIP_RV280_Yc:
1090 info->ChipFamily = CHIP_FAMILY_RV280;
1091 break;
1092
1093 case PCI_CHIP_R300_ND:
1094 case PCI_CHIP_R300_NE:
1095 case PCI_CHIP_R300_NF:
1096 case PCI_CHIP_R300_NG:
1097 info->ChipFamily = CHIP_FAMILY_R300;
1098 break;
1099
1100 default:
1101 /* Original Radeon/7200 */
1102 info->ChipFamily = CHIP_FAMILY_RADEON;
1103 }
1104
1105 return 1;
1106 }
1107
1108
1109 /**
1110 * \brief Validate the fbdev mode.
1111 *
1112 * \param ctx display handle.
1113 *
1114 * \return one on success, or zero on failure.
1115 *
1116 * Saves some registers and returns 1.
1117 *
1118 * \sa radeonValidateMode().
1119 */
1120 static int radeonValidateMode( const DRIDriverContext *ctx )
1121 {
1122 unsigned char *RADEONMMIO = ctx->MMIOAddress;
1123 RADEONInfoPtr info = ctx->driverPrivate;
1124
1125 info->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
1126 info->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
1127
1128 return 1;
1129 }
1130
1131
1132 /**
1133 * \brief Examine mode returned by fbdev.
1134 *
1135 * \param ctx display handle.
1136 *
1137 * \return one on success, or zero on failure.
1138 *
1139 * Restores registers that fbdev has clobbered and returns 1.
1140 *
1141 * \sa radeonValidateMode().
1142 */
1143 static int radeonPostValidateMode( const DRIDriverContext *ctx )
1144 {
1145 unsigned char *RADEONMMIO = ctx->MMIOAddress;
1146 RADEONInfoPtr info = ctx->driverPrivate;
1147
1148 OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
1149 OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
1150
1151 return 1;
1152 }
1153
1154
1155 /**
1156 * \brief Initialize the framebuffer device mode
1157 *
1158 * \param ctx display handle.
1159 *
1160 * \return one on success, or zero on failure.
1161 *
1162 * Fills in \p info with some default values and some information from \p ctx
1163 * and then calls RADEONScreenInit() for the screen initialization.
1164 *
1165 * Before exiting clears the framebuffer memory accessing it directly.
1166 */
1167 static int radeonInitFBDev( DRIDriverContext *ctx )
1168 {
1169 RADEONInfoPtr info = calloc(1, sizeof(*info));
1170
1171 {
1172 int dummy = ctx->shared.virtualWidth;
1173
1174 switch (ctx->bpp / 8) {
1175 case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
1176 case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
1177 case 3:
1178 case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
1179 }
1180
1181 ctx->shared.virtualWidth = dummy;
1182 }
1183
1184 ctx->driverPrivate = (void *)info;
1185
1186 info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE;
1187 info->gartSize = RADEON_DEFAULT_AGP_SIZE;
1188 info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE;
1189 info->bufSize = RADEON_DEFAULT_BUFFER_SIZE;
1190 info->ringSize = RADEON_DEFAULT_RING_SIZE;
1191 info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP;
1192
1193 info->Chipset = ctx->chipset;
1194
1195 if (!get_chipfamily_from_chipset( info )) {
1196 fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n");
1197 fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n");
1198 return 0;
1199 }
1200
1201 info->frontPitch = ctx->shared.virtualWidth;
1202 info->LinearAddr = ctx->FBStart & 0xfc000000;
1203
1204
1205 if (!RADEONScreenInit( ctx, info ))
1206 return 0;
1207
1208
1209 return 1;
1210 }
1211
1212
1213 /**
1214 * \brief The screen is being closed, so clean up any state and free any
1215 * resources used by the DRI.
1216 *
1217 * \param ctx display handle.
1218 *
1219 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1220 * private data.
1221 */
1222 static void radeonHaltFBDev( DRIDriverContext *ctx )
1223 {
1224 drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
1225 drmClose(ctx->drmFD);
1226
1227 if (ctx->driverPrivate) {
1228 free(ctx->driverPrivate);
1229 ctx->driverPrivate = 0;
1230 }
1231 }
1232
1233
1234 extern void radeonNotifyFocus( int );
1235
1236 /**
1237 * \brief Exported driver interface for Mini GLX.
1238 *
1239 * \sa DRIDriverRec.
1240 */
1241 const struct DRIDriverRec __driDriver = {
1242 radeonValidateMode,
1243 radeonPostValidateMode,
1244 radeonInitFBDev,
1245 radeonHaltFBDev,
1246 RADEONEngineShutdown,
1247 RADEONEngineRestore,
1248 #ifndef _EMBEDDED
1249 0,
1250 #else
1251 radeonNotifyFocus,
1252 #endif
1253 };