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