Make solo radeon/r128 drivers track fix for DRI bug 849
[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
425 /**
426 * \brief Initialize the kernel data structures and enable the CP engine.
427 *
428 * \param ctx display handle.
429 * \param info driver private data.
430 *
431 * \return non-zero on success, or zero on failure.
432 *
433 * This function is a wrapper around the DRM_RADEON_CP_INIT command, passing
434 * all the parameters in a drm_radeon_init_t structure.
435 */
436 static int RADEONDRIKernelInit( const DRIDriverContext *ctx,
437 RADEONInfoPtr info)
438 {
439 int cpp = ctx->bpp / 8;
440 drm_radeon_init_t drmInfo;
441 int ret;
442
443 memset(&drmInfo, 0, sizeof(drm_radeon_init_t));
444
445 if ( (info->ChipFamily == CHIP_FAMILY_R200) ||
446 (info->ChipFamily == CHIP_FAMILY_RV250) ||
447 (info->ChipFamily == CHIP_FAMILY_M9) ||
448 (info->ChipFamily == CHIP_FAMILY_RV280) )
449 drmInfo.func = RADEON_INIT_R200_CP;
450 else
451 drmInfo.func = RADEON_INIT_CP;
452
453 /* This is the struct passed to the kernel module for its initialization */
454 drmInfo.sarea_priv_offset = sizeof(drm_sarea_t);
455 drmInfo.is_pci = 0;
456 drmInfo.cp_mode = RADEON_DEFAULT_CP_BM_MODE;
457 drmInfo.gart_size = info->gartSize*1024*1024;
458 drmInfo.ring_size = info->ringSize*1024*1024;
459 drmInfo.usec_timeout = 1000;
460 drmInfo.fb_bpp = ctx->bpp;
461 drmInfo.depth_bpp = ctx->bpp;
462 drmInfo.front_offset = info->frontOffset;
463 drmInfo.front_pitch = info->frontPitch * cpp;
464 drmInfo.back_offset = info->backOffset;
465 drmInfo.back_pitch = info->backPitch * cpp;
466 drmInfo.depth_offset = info->depthOffset;
467 drmInfo.depth_pitch = info->depthPitch * cpp;
468 drmInfo.fb_offset = info->LinearAddr;
469 drmInfo.mmio_offset = info->registerHandle;
470 drmInfo.ring_offset = info->ringHandle;
471 drmInfo.ring_rptr_offset = info->ringReadPtrHandle;
472 drmInfo.buffers_offset = info->bufHandle;
473 drmInfo.gart_textures_offset = info->gartTexHandle;
474
475 ret = drmCommandWrite(ctx->drmFD, DRM_RADEON_CP_INIT, &drmInfo,
476 sizeof(drm_radeon_init_t));
477
478 return ret >= 0;
479 }
480
481
482 /**
483 * \brief Initialize the AGP heap.
484 *
485 * \param ctx display handle.
486 * \param info driver private data.
487 *
488 * This function is a wrapper around the DRM_RADEON_INIT_HEAP command, passing
489 * all the parameters in a drm_radeon_mem_init_heap structure.
490 */
491 static void RADEONDRIAgpHeapInit(const DRIDriverContext *ctx,
492 RADEONInfoPtr info)
493 {
494 drm_radeon_mem_init_heap_t drmHeap;
495
496 /* Start up the simple memory manager for gart space */
497 drmHeap.region = RADEON_MEM_REGION_GART;
498 drmHeap.start = 0;
499 drmHeap.size = info->gartTexMapSize;
500
501 if (drmCommandWrite(ctx->drmFD, DRM_RADEON_INIT_HEAP,
502 &drmHeap, sizeof(drmHeap))) {
503 fprintf(stderr,
504 "[drm] Failed to initialized gart heap manager\n");
505 } else {
506 fprintf(stderr,
507 "[drm] Initialized kernel gart heap manager, %d\n",
508 info->gartTexMapSize);
509 }
510 }
511
512 /**
513 * \brief Add a map for the vertex buffers that will be accessed by any
514 * DRI-based clients.
515 *
516 * \param ctx display handle.
517 * \param info driver private data.
518 *
519 * \return one on success, or zero on failure.
520 *
521 * Calls drmAddBufs() with the previously allocated vertex buffers.
522 */
523 static int RADEONDRIBufInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
524 {
525 /* Initialize vertex buffers */
526 info->bufNumBufs = drmAddBufs(ctx->drmFD,
527 info->bufMapSize / RADEON_BUFFER_SIZE,
528 RADEON_BUFFER_SIZE,
529 DRM_AGP_BUFFER,
530 info->bufStart);
531
532 if (info->bufNumBufs <= 0) {
533 fprintf(stderr,
534 "[drm] Could not create vertex/indirect buffers list\n");
535 return 0;
536 }
537 fprintf(stderr,
538 "[drm] Added %d %d byte vertex/indirect buffers\n",
539 info->bufNumBufs, RADEON_BUFFER_SIZE);
540
541 return 1;
542 }
543
544 /**
545 * \brief Install an IRQ handler.
546 *
547 * \param ctx display handle.
548 * \param info driver private data.
549 *
550 * Attempts to install an IRQ handler via drmCtlInstHandler(), falling back to
551 * IRQ-free operation on failure.
552 */
553 static void RADEONDRIIrqInit(const DRIDriverContext *ctx,
554 RADEONInfoPtr info)
555 {
556 if (!info->irq) {
557 info->irq = drmGetInterruptFromBusID(ctx->drmFD,
558 ctx->pciBus,
559 ctx->pciDevice,
560 ctx->pciFunc);
561
562 if ((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) {
563 fprintf(stderr,
564 "[drm] failure adding irq handler, "
565 "there is a device already using that irq\n"
566 "[drm] falling back to irq-free operation\n");
567 info->irq = 0;
568 }
569 }
570
571 if (info->irq)
572 fprintf(stderr,
573 "[drm] dma control initialized, using IRQ %d\n",
574 info->irq);
575 }
576
577 static int RADEONCheckDRMVersion( const DRIDriverContext *ctx,
578 RADEONInfoPtr info )
579 {
580 drmVersionPtr version;
581
582 version = drmGetVersion(ctx->drmFD);
583 if (version) {
584 int req_minor, req_patch;
585
586 /* Need 1.8.x for proper cleanup-on-client-exit behaviour.
587 */
588 req_minor = 8;
589 req_patch = 0;
590
591 if (version->version_major != 1 ||
592 version->version_minor < req_minor ||
593 (version->version_minor == req_minor &&
594 version->version_patchlevel < req_patch)) {
595 /* Incompatible drm version */
596 fprintf(stderr,
597 "[dri] RADEONDRIScreenInit failed because of a version "
598 "mismatch.\n"
599 "[dri] radeon.o kernel module version is %d.%d.%d "
600 "but version 1.%d.%d or newer is needed.\n"
601 "[dri] Disabling DRI.\n",
602 version->version_major,
603 version->version_minor,
604 version->version_patchlevel,
605 req_minor,
606 req_patch);
607 drmFreeVersion(version);
608 return 0;
609 }
610
611 info->drmMinor = version->version_minor;
612 drmFreeVersion(version);
613 }
614
615 return 1;
616 }
617
618 static int RADEONMemoryInit( const DRIDriverContext *ctx, RADEONInfoPtr info )
619 {
620 int width_bytes = ctx->shared.virtualWidth * ctx->cpp;
621 int cpp = ctx->cpp;
622 int bufferSize = ((ctx->shared.virtualHeight * width_bytes
623 + RADEON_BUFFER_ALIGN)
624 & ~RADEON_BUFFER_ALIGN);
625 int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes
626 + RADEON_BUFFER_ALIGN)
627 & ~RADEON_BUFFER_ALIGN);
628 int l;
629
630 info->frontOffset = 0;
631 info->frontPitch = ctx->shared.virtualWidth;
632
633 fprintf(stderr,
634 "Using %d MB AGP aperture\n", info->gartSize);
635 fprintf(stderr,
636 "Using %d MB for the ring buffer\n", info->ringSize);
637 fprintf(stderr,
638 "Using %d MB for vertex/indirect buffers\n", info->bufSize);
639 fprintf(stderr,
640 "Using %d MB for AGP textures\n", info->gartTexSize);
641
642 /* Front, back and depth buffers - everything else texture??
643 */
644 info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize;
645
646 if (info->textureSize < 0)
647 return 0;
648
649 l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS);
650 if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY;
651
652 /* Round the texture size up to the nearest whole number of
653 * texture regions. Again, be greedy about this, don't
654 * round down.
655 */
656 info->log2TexGran = l;
657 info->textureSize = (info->textureSize >> l) << l;
658
659 /* Set a minimum usable local texture heap size. This will fit
660 * two 256x256x32bpp textures.
661 */
662 if (info->textureSize < 512 * 1024) {
663 info->textureOffset = 0;
664 info->textureSize = 0;
665 }
666
667 /* Reserve space for textures */
668 info->textureOffset = ((ctx->shared.fbSize - info->textureSize +
669 RADEON_BUFFER_ALIGN) &
670 ~RADEON_BUFFER_ALIGN);
671
672 /* Reserve space for the shared depth
673 * buffer.
674 */
675 info->depthOffset = ((info->textureOffset - depthSize +
676 RADEON_BUFFER_ALIGN) &
677 ~RADEON_BUFFER_ALIGN);
678 info->depthPitch = ctx->shared.virtualWidth;
679
680 info->backOffset = ((info->depthOffset - bufferSize +
681 RADEON_BUFFER_ALIGN) &
682 ~RADEON_BUFFER_ALIGN);
683 info->backPitch = ctx->shared.virtualWidth;
684
685
686 fprintf(stderr,
687 "Will use back buffer at offset 0x%x\n",
688 info->backOffset);
689 fprintf(stderr,
690 "Will use depth buffer at offset 0x%x\n",
691 info->depthOffset);
692 fprintf(stderr,
693 "Will use %d kb for textures at offset 0x%x\n",
694 info->textureSize/1024, info->textureOffset);
695
696 info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
697 (info->frontOffset >> 10));
698
699 info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
700 (info->backOffset >> 10));
701
702 info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
703 (info->depthOffset >> 10));
704
705 return 1;
706 }
707
708
709
710 /**
711 * Called at the start of each server generation.
712 *
713 * \param ctx display handle.
714 * \param info driver private data.
715 *
716 * \return non-zero on success, or zero on failure.
717 *
718 * Performs static frame buffer allocation. Opens the DRM device and add maps
719 * to the SAREA, framebuffer and MMIO regions. Fills in \p info with more
720 * information. Creates a \e server context to grab the lock for the
721 * initialization ioctls and calls the other initilization functions in this
722 * file. Starts the CP engine via the DRM_RADEON_CP_START command.
723 *
724 * Setups a RADEONDRIRec structure to be passed to radeon_dri.so for its
725 * initialization.
726 */
727 static int RADEONScreenInit( DRIDriverContext *ctx, RADEONInfoPtr info )
728 {
729 RADEONDRIPtr pRADEONDRI;
730 int err;
731
732 usleep(100);
733 /*assert(!ctx->IsClient);*/
734
735 {
736 int width_bytes = (ctx->shared.virtualWidth * ctx->cpp);
737 int maxy = ctx->shared.fbSize / width_bytes;
738
739
740 if (maxy <= ctx->shared.virtualHeight * 3) {
741 fprintf(stderr,
742 "Static buffer allocation failed -- "
743 "need at least %d kB video memory (have %d kB)\n",
744 (ctx->shared.virtualWidth * ctx->shared.virtualHeight *
745 ctx->cpp * 3 + 1023) / 1024,
746 ctx->shared.fbSize / 1024);
747 return 0;
748 }
749 }
750
751
752 if (info->ChipFamily >= CHIP_FAMILY_R300) {
753 fprintf(stderr,
754 "Direct rendering not yet supported on "
755 "Radeon 9700 and newer cards\n");
756 return 0;
757 }
758
759 radeon_drm_page_size = getpagesize();
760
761 info->registerSize = ctx->MMIOSize;
762 ctx->shared.SAREASize = SAREA_MAX;
763
764 /* Note that drmOpen will try to load the kernel module, if needed. */
765 ctx->drmFD = drmOpen("radeon", NULL );
766 if (ctx->drmFD < 0) {
767 fprintf(stderr, "[drm] drmOpen failed\n");
768 return 0;
769 }
770
771 if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) {
772 fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
773 ctx->drmFD, ctx->pciBusID, strerror(-err));
774 return 0;
775 }
776
777 if (drmAddMap( ctx->drmFD,
778 0,
779 ctx->shared.SAREASize,
780 DRM_SHM,
781 DRM_CONTAINS_LOCK,
782 &ctx->shared.hSAREA) < 0)
783 {
784 fprintf(stderr, "[drm] drmAddMap failed\n");
785 return 0;
786 }
787 fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
788 ctx->shared.SAREASize, ctx->shared.hSAREA);
789
790 if (drmMap( ctx->drmFD,
791 ctx->shared.hSAREA,
792 ctx->shared.SAREASize,
793 (drmAddressPtr)(&ctx->pSAREA)) < 0)
794 {
795 fprintf(stderr, "[drm] drmMap failed\n");
796 return 0;
797 }
798 memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
799 fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
800 ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
801
802 /* Need to AddMap the framebuffer and mmio regions here:
803 */
804 if (drmAddMap( ctx->drmFD,
805 (drm_handle_t)ctx->FBStart,
806 ctx->FBSize,
807 DRM_FRAME_BUFFER,
808 #ifndef _EMBEDDED
809 0,
810 #else
811 DRM_READ_ONLY,
812 #endif
813 &ctx->shared.hFrameBuffer) < 0)
814 {
815 fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
816 return 0;
817 }
818
819 fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
820 ctx->shared.hFrameBuffer);
821
822
823
824 if (drmAddMap(ctx->drmFD,
825 ctx->MMIOStart,
826 ctx->MMIOSize,
827 DRM_REGISTERS,
828 DRM_READ_ONLY,
829 &info->registerHandle) < 0) {
830 fprintf(stderr, "[drm] drmAddMap mmio failed\n");
831 return 0;
832 }
833 fprintf(stderr,
834 "[drm] register handle = 0x%08lx\n", info->registerHandle);
835
836 /* Check the radeon DRM version */
837 if (!RADEONCheckDRMVersion(ctx, info)) {
838 return 0;
839 }
840
841 /* Initialize AGP */
842 if (!RADEONDRIAgpInit(ctx, info)) {
843 return 0;
844 }
845
846
847 /* Memory manager setup */
848 if (!RADEONMemoryInit(ctx, info)) {
849 return 0;
850 }
851
852 /* Create a 'server' context so we can grab the lock for
853 * initialization ioctls.
854 */
855 if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) {
856 fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
857 return 0;
858 }
859
860 DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
861
862 /* Initialize the kernel data structures */
863 if (!RADEONDRIKernelInit(ctx, info)) {
864 fprintf(stderr, "RADEONDRIKernelInit failed\n");
865 DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
866 return 0;
867 }
868
869 /* Initialize the vertex buffers list */
870 if (!RADEONDRIBufInit(ctx, info)) {
871 fprintf(stderr, "RADEONDRIBufInit failed\n");
872 DRM_UNLOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext);
873 return 0;
874 }
875
876 /* Initialize IRQ */
877 RADEONDRIIrqInit(ctx, info);
878
879 /* Initialize kernel gart memory manager */
880 RADEONDRIAgpHeapInit(ctx, info);
881
882 fprintf(stderr,"page flipping %sabled\n", info->page_flip_enable?"en":"dis");
883 /* Initialize the SAREA private data structure */
884 {
885 drm_radeon_sarea_t *pSAREAPriv;
886 pSAREAPriv = (drm_radeon_sarea_t *)(((char*)ctx->pSAREA) +
887 sizeof(drm_sarea_t));
888 memset(pSAREAPriv, 0, sizeof(*pSAREAPriv));
889 pSAREAPriv->pfState = info->page_flip_enable;
890 }
891
892
893 /* Quick hack to clear the front & back buffers. Could also use
894 * the clear ioctl to do this, but would need to setup hw state
895 * first.
896 */
897 memset((char *)ctx->FBAddress + info->frontOffset,
898 0,
899 info->frontPitch * ctx->cpp * ctx->shared.virtualHeight );
900
901 memset((char *)ctx->FBAddress + info->backOffset,
902 0,
903 info->backPitch * ctx->cpp * ctx->shared.virtualHeight );
904
905
906 /* This is the struct passed to radeon_dri.so for its initialization */
907 ctx->driverClientMsg = malloc(sizeof(RADEONDRIRec));
908 ctx->driverClientMsgSize = sizeof(RADEONDRIRec);
909 pRADEONDRI = (RADEONDRIPtr)ctx->driverClientMsg;
910 pRADEONDRI->deviceID = info->Chipset;
911 pRADEONDRI->width = ctx->shared.virtualWidth;
912 pRADEONDRI->height = ctx->shared.virtualHeight;
913 pRADEONDRI->depth = ctx->bpp; /* XXX: depth */
914 pRADEONDRI->bpp = ctx->bpp;
915 pRADEONDRI->IsPCI = 0;
916 pRADEONDRI->AGPMode = ctx->agpmode;
917 pRADEONDRI->frontOffset = info->frontOffset;
918 pRADEONDRI->frontPitch = info->frontPitch;
919 pRADEONDRI->backOffset = info->backOffset;
920 pRADEONDRI->backPitch = info->backPitch;
921 pRADEONDRI->depthOffset = info->depthOffset;
922 pRADEONDRI->depthPitch = info->depthPitch;
923 pRADEONDRI->textureOffset = info->textureOffset;
924 pRADEONDRI->textureSize = info->textureSize;
925 pRADEONDRI->log2TexGran = info->log2TexGran;
926 pRADEONDRI->registerHandle = info->registerHandle;
927 pRADEONDRI->registerSize = info->registerSize;
928 pRADEONDRI->statusHandle = info->ringReadPtrHandle;
929 pRADEONDRI->statusSize = info->ringReadMapSize;
930 pRADEONDRI->gartTexHandle = info->gartTexHandle;
931 pRADEONDRI->gartTexMapSize = info->gartTexMapSize;
932 pRADEONDRI->log2GARTTexGran = info->log2GARTTexGran;
933 pRADEONDRI->gartTexOffset = info->gartTexStart;
934 pRADEONDRI->sarea_priv_offset = sizeof(drm_sarea_t);
935
936 /* Don't release the lock now - let the VT switch handler do it. */
937
938 return 1;
939 }
940
941
942 /**
943 * \brief Get Radeon chip family from chipset number.
944 *
945 * \param info driver private data.
946 *
947 * \return non-zero on success, or zero on failure.
948 *
949 * Called by radeonInitFBDev() to set RADEONInfoRec::ChipFamily
950 * according to the value of RADEONInfoRec::Chipset. Fails if the
951 * chipset is unrecognized or not appropriate for this driver (i.e., not
952 * an r100 style radeon)
953 */
954 static int get_chipfamily_from_chipset( RADEONInfoPtr info )
955 {
956 switch (info->Chipset) {
957 case PCI_CHIP_RADEON_LY:
958 case PCI_CHIP_RADEON_LZ:
959 info->ChipFamily = CHIP_FAMILY_M6;
960 break;
961
962 case PCI_CHIP_RADEON_QY:
963 case PCI_CHIP_RADEON_QZ:
964 info->ChipFamily = CHIP_FAMILY_VE;
965 break;
966
967 case PCI_CHIP_R200_QL:
968 case PCI_CHIP_R200_QN:
969 case PCI_CHIP_R200_QO:
970 case PCI_CHIP_R200_Ql:
971 case PCI_CHIP_R200_BB:
972 info->ChipFamily = CHIP_FAMILY_R200;
973 break;
974
975 case PCI_CHIP_RV200_QW: /* RV200 desktop */
976 case PCI_CHIP_RV200_QX:
977 info->ChipFamily = CHIP_FAMILY_RV200;
978 break;
979
980 case PCI_CHIP_RADEON_LW:
981 case PCI_CHIP_RADEON_LX:
982 info->ChipFamily = CHIP_FAMILY_M7;
983 break;
984
985 case PCI_CHIP_RV250_Id:
986 case PCI_CHIP_RV250_Ie:
987 case PCI_CHIP_RV250_If:
988 case PCI_CHIP_RV250_Ig:
989 info->ChipFamily = CHIP_FAMILY_RV250;
990 break;
991
992 case PCI_CHIP_RV250_Ld:
993 case PCI_CHIP_RV250_Le:
994 case PCI_CHIP_RV250_Lf:
995 case PCI_CHIP_RV250_Lg:
996 info->ChipFamily = CHIP_FAMILY_M9;
997 break;
998
999 case PCI_CHIP_RV280_Y_:
1000 case PCI_CHIP_RV280_Ya:
1001 case PCI_CHIP_RV280_Yb:
1002 case PCI_CHIP_RV280_Yc:
1003 info->ChipFamily = CHIP_FAMILY_RV280;
1004 break;
1005
1006 case PCI_CHIP_R300_ND:
1007 case PCI_CHIP_R300_NE:
1008 case PCI_CHIP_R300_NF:
1009 case PCI_CHIP_R300_NG:
1010 info->ChipFamily = CHIP_FAMILY_R300;
1011 break;
1012
1013 default:
1014 /* Original Radeon/7200 */
1015 info->ChipFamily = CHIP_FAMILY_RADEON;
1016 }
1017
1018 return 1;
1019 }
1020
1021
1022 /**
1023 * \brief Validate the fbdev mode.
1024 *
1025 * \param ctx display handle.
1026 *
1027 * \return one on success, or zero on failure.
1028 *
1029 * Saves some registers and returns 1.
1030 *
1031 * \sa radeonValidateMode().
1032 */
1033 static int radeonValidateMode( const DRIDriverContext *ctx )
1034 {
1035 unsigned char *RADEONMMIO = ctx->MMIOAddress;
1036 RADEONInfoPtr info = ctx->driverPrivate;
1037
1038 info->gen_int_cntl = INREG(RADEON_GEN_INT_CNTL);
1039 info->crtc_offset_cntl = INREG(RADEON_CRTC_OFFSET_CNTL);
1040
1041 return 1;
1042 }
1043
1044
1045 /**
1046 * \brief Examine mode returned by fbdev.
1047 *
1048 * \param ctx display handle.
1049 *
1050 * \return one on success, or zero on failure.
1051 *
1052 * Restores registers that fbdev has clobbered and returns 1.
1053 *
1054 * \sa radeonValidateMode().
1055 */
1056 static int radeonPostValidateMode( const DRIDriverContext *ctx )
1057 {
1058 unsigned char *RADEONMMIO = ctx->MMIOAddress;
1059 RADEONInfoPtr info = ctx->driverPrivate;
1060
1061 OUTREG(RADEON_GEN_INT_CNTL, info->gen_int_cntl);
1062 OUTREG(RADEON_CRTC_OFFSET_CNTL, info->crtc_offset_cntl);
1063
1064 return 1;
1065 }
1066
1067
1068 /**
1069 * \brief Initialize the framebuffer device mode
1070 *
1071 * \param ctx display handle.
1072 *
1073 * \return one on success, or zero on failure.
1074 *
1075 * Fills in \p info with some default values and some information from \p ctx
1076 * and then calls RADEONScreenInit() for the screen initialization.
1077 *
1078 * Before exiting clears the framebuffer memory accessing it directly.
1079 */
1080 static int radeonInitFBDev( DRIDriverContext *ctx )
1081 {
1082 RADEONInfoPtr info = calloc(1, sizeof(*info));
1083
1084 {
1085 int dummy = ctx->shared.virtualWidth;
1086
1087 switch (ctx->bpp / 8) {
1088 case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break;
1089 case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break;
1090 case 3:
1091 case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break;
1092 }
1093
1094 ctx->shared.virtualWidth = dummy;
1095 }
1096
1097 ctx->driverPrivate = (void *)info;
1098
1099 info->gartFastWrite = RADEON_DEFAULT_AGP_FAST_WRITE;
1100 info->gartSize = RADEON_DEFAULT_AGP_SIZE;
1101 info->gartTexSize = RADEON_DEFAULT_AGP_TEX_SIZE;
1102 info->bufSize = RADEON_DEFAULT_BUFFER_SIZE;
1103 info->ringSize = RADEON_DEFAULT_RING_SIZE;
1104 info->page_flip_enable = RADEON_DEFAULT_PAGE_FLIP;
1105
1106 info->Chipset = ctx->chipset;
1107
1108 if (!get_chipfamily_from_chipset( info )) {
1109 fprintf(stderr, "Unknown or non-radeon chipset -- cannot continue\n");
1110 fprintf(stderr, "==> Verify PCI BusID is correct in miniglx.conf\n");
1111 return 0;
1112 }
1113
1114 info->frontPitch = ctx->shared.virtualWidth;
1115 info->LinearAddr = ctx->FBStart & 0xfc000000;
1116
1117
1118 if (!RADEONScreenInit( ctx, info ))
1119 return 0;
1120
1121
1122 return 1;
1123 }
1124
1125
1126 /**
1127 * \brief The screen is being closed, so clean up any state and free any
1128 * resources used by the DRI.
1129 *
1130 * \param ctx display handle.
1131 *
1132 * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver
1133 * private data.
1134 */
1135 static void radeonHaltFBDev( DRIDriverContext *ctx )
1136 {
1137 drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
1138 drmClose(ctx->drmFD);
1139
1140 if (ctx->driverPrivate) {
1141 free(ctx->driverPrivate);
1142 ctx->driverPrivate = 0;
1143 }
1144 }
1145
1146
1147 extern void radeonNotifyFocus( int );
1148
1149 /**
1150 * \brief Exported driver interface for Mini GLX.
1151 *
1152 * \sa DRIDriverRec.
1153 */
1154 const struct DRIDriverRec __driDriver = {
1155 radeonValidateMode,
1156 radeonPostValidateMode,
1157 radeonInitFBDev,
1158 radeonHaltFBDev,
1159 RADEONEngineShutdown,
1160 RADEONEngineRestore,
1161 #ifndef _EMBEDDED
1162 0,
1163 #else
1164 radeonNotifyFocus,
1165 #endif
1166 };