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