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